This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: general_operand() not accepting CONCAT?


On Thu, Apr 26, 2007 at 01:52:37PM -0700, Richard Henderson wrote:
> On Thu, Apr 26, 2007 at 09:49:16PM +0200, Rask Ingemann Lambertsen wrote:
> >    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
> 
> It's not supposed to.  Please debug emit_move_complex_push
> and find out why.  I suspect PUSH_ROUNDING is larger than
> it's supposed to be.

#define PUSH_ROUNDING(BYTES)    (((BYTES) + 1) & ~1)

   I don't see how emit_move_complex_push() can ever generate a push
instruction. Here's a backtrace:

(gdb) fin
Run till exit from #0  push_operand (op=0xb7f7b118, mode=SFmode) at ../../../cvssrc/gcc/gcc/recog.c:1299
0x0828f941 in emit_move_multi_word (mode=SFmode, x=0xb7f78bc4, y=0xb7f793d0) at ../../../cvssrc/gcc/gcc/expr.c:3182
Value returned is $44 = 1
(gdb) bt
#0  0x0828f941 in emit_move_multi_word (mode=SFmode, x=0xb7f78bc4, y=0xb7f793d0) at ../../../cvssrc/gcc/gcc/expr.c:3182
#1  0x0829016e in emit_move_insn_1 (x=0xb7f78bc4, y=0xb7f793d0) at ../../../cvssrc/gcc/gcc/expr.c:3291
#2  0x0829074d in emit_move_insn (x=0xb7f78bc4, y=0xb7f793d0) at ../../../cvssrc/gcc/gcc/expr.c:3351
#3  0x0828f236 in emit_move_complex_push (mode=SCmode, x=0xb7f78bb8, y=0xb7f78078) at ../../../cvssrc/gcc/gcc/expr.c:3025
#4  0x0828f45d in emit_move_complex (mode=SCmode, x=0xb7f78bb8, y=0xb7f78078) at ../../../cvssrc/gcc/gcc/expr.c:3061
#5  0x0829003f in emit_move_insn_1 (x=0xb7f78bb8, y=0xb7f78078) at ../../../cvssrc/gcc/gcc/expr.c:3264
#6  0x0829074d in emit_move_insn (x=0xb7f78bb8, y=0xb7f78078) at ../../../cvssrc/gcc/gcc/expr.c:3351
#7  0x0829120e in emit_single_push_insn (mode=SCmode, x=0xb7f78078, type=0xb7edcbd0) at ../../../cvssrc/gcc/gcc/expr.c:3582
#8  0x08291d43 in emit_push_insn (x=0xb7f78078, mode=SCmode, type=0xb7edcbd0, size=0x0, align=16, partial=0, reg=0x0, extra=0, args_addr=0x0,
    args_so_far=0xb7ecb210, reg_parm_stack_space=0, alignment_pad=0xb7ecb210) at ../../../cvssrc/gcc/gcc/expr.c:3852

(gdb) call debug_rtx(x)
(mem:SF (pre_dec:HI (reg/f:HI 12 sp)) [0 S4 A8])
(gdb) call debug_rtx(y)
(reg/v:SF 27 [ i+4 ])

   The only place where push_optab is consulted is at the beginning of
emit_single_push_insn(), which is only called from move_by_pieces() and
emit_push_insn(). emit_push_insn() isn't called from anywhere in expr.c.
I don't see how move_by_pieces() can be called by emit_move_insn(). There
seems to be no way that it could ever work.

> > (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")))]
> 
> This is horrible.  At minimum you should expand this to
> two separate pushed immediately.

   Usually, doing so will fool reload's frame pointer elimination if the
operand is a pseudo which ends up on the stack. Diffing the output between
the two implementations confirms it:

--- /tmp/complex-3.s_expand	2007-04-27 15:50:49.000000000 +0200
+++ /tmp/complex-3.s_postsplit	2007-04-27 15:50:26.000000000 +0200
@@ -53,8 +53,8 @@
 	movw	16(%di),	%ax	
 	pushw	%cx	
 	pushw	%ax	
-	pushw	14(%di)	
-	pushw	12(%di)	
+	pushw	10(%di)	
+	pushw	8(%di)	
 	call	g	
 	movw	24(%di),	%dx	
 	movw	%dx,	32(%di)	

-- 
Rask Ingemann Lambertsen


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]