|
Message
From: pthomas@o...<pthomas@o...>
Date: Wed Jul 14 22:11:21 CEST 2004
Subject: [openrisc] GCC: support for l.cmov
I have, after some struggles, managed to add support for the l.cmov instruction into GCC. There were a couple of problems:
1) Having if-then-else branch instructions based on the value of (reg:CC 32), causes canonicalize_condition to return RTX_NULL because it can't find the actual condition that was set into (reg:CC 32) earlier (it balks at the operand of the condition being a CCmode register). This prevents a bunch of if-optimizations in ifcvt.c from being attempted (like conditional move).
This was fixed by representing SR.F as a BImode register, rather than a CCmode register. The canonicalize_condition function still can't find the real condition, but it will take the (eq (const_int 0) (reg:BI 32)) or (ne (const_int 0) (reg:BI 32)) instead. I suspect that this still prevents some if-optimizations from being recognized (like converting <= i into < i+1, etc...), but its better than not recognizing any.
2) Once the compiler recognizes an oppertunity to try the conditional move pattern, it has to be able to emit a "cmpsi" pattern before the "movsicc" pattern (unfortunately, the compiler does not appear to try to emit the "cmovsi6" pattern). However, once the "cmpsi" pattern is supported, all of the "bcond" patterns must also be supported, so the "cbranchsi4" pattern is no longer used.
The solution was to drop the "cbranchsi4" pattern, and go back to using "cmpsi" and "bcond".
After all that, I was able to add a (define-insn) that recognized the l.cmov pattern.
I have a patch, but it includes fixes for some other things I found along the way:
___modsi3 did not zero r10, so it would randomly negate the result
Added support for l.extbs, l.extbz, l.exths, l.exthz. This eliminates the two instruction left/right shift for sign-extension.
Removed subtract constant pattern because the compiler favored the add pattern anyway, and because negating the 'I' constraint would have caused the result to be out-of-range for the -32768 case (can't represent +32768 in 16-bit signed int).
Made r9 a fixed register so that it did not need to be saved/restored in leaf functions that used many registers.
Added support for l.ror and l.rori instructions.
Changed TARGET_DEFAULT flags to used MASK_HARD_MUL instead of hard-coded 0x00000004.
|
 |