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