SH: Reloc overflow

Andrew Haley aph@cambridge.redhat.com
Mon Jan 21 05:08:00 GMT 2002


Hi there Joern.  Thanks for looking at this.

Joern Rennecke writes:
 > > I had a great deal of fun trying to figure out what had gone wrong.
 > > It turns out that the code that lays out constant tables in
 > > machine_dependent_reorg was underestimating the distance from a load
 > > to its constant in the table due to a freak combination of
 > > circumstances.
 > > 
 > > machine_dependent_reorg assumes a worst case size for a conditional
 > > branch of 12 bytes.  However, this insn
 > > 
 > > (jump_insn 327 326 13320 (set (pc)
 > >         (if_then_else (eq (reg:SI 18 t)
 > >                 (const_int 0 [0x0]))
 > >             (label_ref 13316)
 > >             (pc))) 95 {branch_false} (insn_list:REG_DEP_ANTI 317 (insn_list:REG_DEP_ANTI 319 (insn_list:REG_DEP_ANTI 320 (insn_list 326 (nil)))))
 > >     (expr_list:REG_DEAD (reg:SI 18 t)
 > >         (expr_list:REG_BR_PROB (const_int 6001 [0x1771])
 > >             (nil))))
 > > 
 > > turns into all this
 > >  
 > >  482 00d8 068B                  bf      .L1151  ! 327   branch_false
 > >  483 00da FF79                  add     #-1,r9  ! 331   addsi3
 > >  484 00dc 1549                  cmp/pl  r9      ! 332   cmpgtsi_t/2
 > >  485 00de D62F                  mov.l   r13,@-r15
 > >  486 00e0 019D230D              mov.w   .L1160,r13; braf        r13
 > >  487 00e4 F66D                  mov.l   @r15+,r13
 > >  489 00e6 FA1A                  .word .L250-.L1160
 > >  490                    .L1151:
 > > 
 > > which by my reckoning is 16 bytes.  
 > > 
 > > First, The conditional jump gets turned into a conditional jump around
 > > a far jump.
 > > 
 > > Then the delay slots of both jumps are filled by reorg with insns 331
 > > and 332 from the destinatio of the jump.  (331 is actually an annulled
 > > deal slot insn.)
 > 
 > We don't want either delay slot filling.

True.

 > We calculate the scratch registers for far jumps in
 > machine_dependent_reorg, so we should be able to say that a far
 > jump without a scratch register has no delay slot.

Right.

 > To avoid the senseless filling of condbranch delay slots with
 > anulled insns in the condbranch-around-jump scenario, we can
 > introduce a dummy insn (length zero), the sole purpose of which is
 > to stuff the delay slot if reorg can't find anything better to do
 > with the delay slot.

Okay.  But even if we emit such an insn in md reorg immediately after
the condbranch, can we guarantee that reorg won't ignore it and pull
another insn from the destination?

 > we could introduce a
 > > 
 > > When we come to emit the insns, we would like to fill the delay slot
 > > of the far jump with insn 332.  Unfortunately we don't have a scratch
 > > register available, so we have to save and restore r13, and the insn
 > > to restore r13 goes in the delay slot.  So, insn 332 is emitted before
 > > the jump; the jump itself is expanded into the code you see above.
 > 
 > > I don't know if there are more cases like this in sh.md.
 > 
 > branch-around-32-bit-jump will ahve the same issues.

Right.

 > > 	* config/sh/sh.md: Conditional branches have a worst case length
 > > 	of 16, not 12.	
 > 
 > Actually, condbranches already have a worst case length of 16 even without
 > the suprious delay slot insns.  For the condbranch-around-32-bit-jump
 > case.

Yes, good point.

Andrew.



More information about the Gcc-patches mailing list