This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
define_insn : order of matching patterns
- From: jeroen dobbelaere <jeroen dot dobbelaere at acunia dot com>
- To: gcc at gcc dot gnu dot org
- Date: Tue, 04 Dec 2001 14:44:03 +0100
- Subject: define_insn : order of matching patterns
- Organization: ACUNIA
Hi,
I'm trying to let 'arm-linux-gcc -mcpu=xscale' produce 'smlabb' instructions.
(using gcc-3.0.2)
In 'arm.md', we have following description :
(define_insn "*mulhisi3addsi"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(plus:SI (match_operand:SI 1 "s_register_operand" "r")
(mult:SI (sign_extend:SI
(match_operand:HI 2 "s_register_operand" "%r"))
(sign_extend:SI
(match_operand:HI 3 "s_register_operand" "r")))))]
"TARGET_ARM && arm_is_xscale"
"smlabb%?\\t%0, %2, %3, %1"
[(set_attr "type" "mult")]
)
But with this, I don't succeed in producing 'smlabb' for a simple example
int test(volatile short a, volatile short b, int length)
{
int result=0;
while(length >0)
{
result += (int)a*(int)b;
}
return result;
}
After duplicating the pattern into :
(define_insn "*mulhisi3addsi_left"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(plus:SI (match_operand:SI 1 "s_register_operand" "r")
(mult:SI (sign_extend:SI
(match_operand:HI 2 "'ts_register_operand" "%r"))
(sign_extend:SI
(match_operand:HI 3 "s_register_operand" "r")))))]
"TARGET_ARM && arm_is_xscale"
"smlabb%?\\t%0, %2, %3, %1"
[(set_attr "type" "mult")]
)
(define_insn "*mulhisi3addsi_right"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(plus:SI (mult:SI (sign_extend:SI
(match_operand:HI 1 "s_register_operand" "%r"))
(sign_extend:SI
(match_operand:HI 2 "s_register_operand" "r")))
(match_operand:SI 3 "s_register_operand" "r")
))]
"TARGET_ARM && arm_is_xscale"
"smlabb%?\\t%0, %1, %2, %3"
[(set_attr "type" "mult")]
)
I finally succeed in producing 'smlabb' instructions. It seems that
only '*mulhisi3addsi_right' is used for this.
Now my questions :
1. Why doesn't the original pattern ('*mulhisi3addsi_left') get a match ?
Looking at the instructions in 14.life, it seems that '*mulhisi3addsi_left'
should match, as reg38, generated in insn 37, is the right operand of 'plus:SI'.
But, it instead, '*mulhisi3addsi_right' is matched, which uses the 'mult' pattern
in the left operand of 'plus:SI'
<From 14.life>
(insn 37 36 39 (set (reg:SI 38)
(mult:SI (sign_extend:SI (reg:HI 36))
(sign_extend:SI (reg:HI 37)))) 56 {mulhisi3} (insn_list 34 (insn_list 36 (nil)))
(expr_list:REG_DEAD (reg:HI 36)
(expr_list:REG_DEAD (reg:HI 37)
(nil))))
(insn 39 37 40 (set (reg/v:SI 35)
(plus:SI (reg/v:SI 35)
(reg:SI 38))) 4 {*arm_addsi3} (insn_list 37 (nil))
(expr_list:REG_DEAD (reg:SI 38)
(nil)))
<From 15.combine>
(note 37 36 39 NOTE_INSN_DELETED 0)
(insn 39 37 40 (set (reg/v:SI 35)
(plus:SI (mult:SI (sign_extend:SI (reg:HI 36))
(sign_extend:SI (reg:HI 37)))
(reg/v:SI 35))) 58 {*mulhisi3addsi_right} (insn_list 36 (insn_list 34 (nil)))
(expr_list:REG_DEAD (reg:HI 37)
(expr_list:REG_DEAD (reg:HI 36)
(nil))))
2. Can I savely remove the '*mulhisi3addsi_left' part, or should I provide
both cases ?
Greetings,
--
Jeroen Dobbelaere
Embedded Software Engineer
ACUNIA Embedded Solutions
http://www.acunia.com