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




Reply via email to