This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: general_operand() not accepting CONCAT?
On Wed, Apr 25, 2007 at 09:11:52AM -0700, Richard Henderson wrote:
> On Wed, Apr 25, 2007 at 01:51:34PM +0200, Rask Ingemann Lambertsen wrote:
> > (define_mode_macro GT16 [SI DI TI SF DF XF SC DC XC SD DD TD CHI CSI CDI
> > CTI])
> >
> > (define_insn_and_split "*push<mode>1"
>
> You almost certainly do not want to handle complex yourself,
> and instead rely on the fallback code in expr.c.
Unfortunately, the fallback code isn't exactly optimum, as it produces
something like
addw $-N*2, %sp
movw %sp, %basereg
movw %wordN, N*2(%basereg)
...
movw %word0, (%basereg)
which compared with
pushw %wordN
...
pushw %word0
needs two more instructions, an extra register and longer instructions. It
becomes even worse when the complex value is on the stack:
addw $-N*2, %sp
movw %sp, %basereg
movw wordN(%basereg),%tmpreg
movw %tmpreg, N*2(%basereg)
...
movw word0(%basereg),%tmpreg
movw %tmpreg, (%basereg)
vs.
movw %sp, %basereg
pushw wordN(%basereg)
...
pushw word0(%basereg)
which is 1+N extra instructions, possibly only 1+(N+1)/2 extra instructions
after peephole optimization.
I ended up with this, which seems to work as intended:
; Complex modes.
(define_mode_macro COMPLEX [SC DC XC CQI CHI CSI CDI CTI])
; Inner mode of a complex value (concat ...).
(define_mode_attr INNER [(SC "SF") (DC "DF") (XC "XF")
(CQI "QI") (CHI "HI") (CSI "SI") (CDI "DI") (CTI "TI")])
; Reload can't handle a (concat ...) operand.
(define_insn_and_split "*push<mode>1_concat"
[(set (mem:COMPLEX (pre_dec:HI (reg:HI SP_REG)))
(concat:COMPLEX (match_operand:<INNER> 0 "general_operand" "RmIpu")
(match_operand:<INNER> 1 "general_operand" "RmIpu")))]
"TARGET_PUSH_IMM
|| (!CONSTANT_P (operands[0]) && !CONSTANT_P (operands[1]))"
"#"
"reload_completed"
...
--
Rask Ingemann Lambertsen