maddsidi4 detection

BELBACHIR Selim selim.belbachir@fr.thalesgroup.com
Tue Nov 22 19:34:00 GMT 2011


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






More information about the Gcc mailing list