Hi,
I'm trying to define the standard pattern maddsidi4. To do this I wrote this in
my backend (gcc4.5.2) :
(define_insn "maddsidi4"
[(set (match_operand:DI 0 "register_operand" "=a")
(plus:DI
(mult:DI
(sign_extend:DI (match_operand:SI 1 "general_operand" "%g"))
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
(match_operand:DI 3 "register_operand" " 0")))]
""
"mulacc %2,%1,%0";
)
('a' constraints is for accumulator registers)
(the movdi standard pattern defines the moves from and to accumulator registers)
When I compile the following code, mulacc is properly emitted :
void test_maddsidi4(int a, int b, long long * c)
{
*c += (long long)a*(long long)b;
}
But when I write the following code, (mulsidi3 + adddi3) is chosen instead of
maddsi4:
void maddsidi4_alt(int a, int b, long long * c)
{
*c = (long long)a*(long long)b + (*c);
}
I tried in debug mode to figure out why maddsi4 is ignore in the last case. I
found in expr.c file, in 'expand_expr_real_2' function and in 'PLUS_EXPR'
switch case that instead of encountering a MULT_EXPR following the PLUS_EXPR,
an INDIRECT_REF is encountered. This seems quite logical given the '+(*c)' in
my test.
I'm quite surprised that the multiplication/addition detection is so
restrictive. Is there a way to enhance the mul/add detection without patching
expr.c ? Someone else has certainly met the same problem :) Feel free to send
me the trick or patch :)
Regards,
Selim