Hi,

I am working on a 32bit private target which has the following restriction

1. store/load can happen only through a general purpose register (GP_REGS)
2. base register should be an address register (AD_REGS)
3. moves between GP_REGS and AD_REGS can happen only through PT_REGS

In a PRE_MODIFY instruction when both the base register and the output
register gets spilled the reloading is going wrong.

befor IRA pass
~~~~~~~~~~~
(insn 259 336 317 2 ../rld_bug.c:94 (set (reg:QI 234 [+1 ])
        (mem/s/j/c:QI (pre_modify:PQI (reg/f:PQI 233)
                (plus:PQI (reg/f:PQI 233)
                    (const_int 1 [0x1]))) [0+1 S1 A32])) 7 {movqi_op}
(expr_list:REG_INC (reg/f:PQI 233)
        (nil)))

after IRA pass
~~~~~~~~~~~
Reloads for insn # 259
Reload 0: GP_REGS, RELOAD_FOR_OPADDR_ADDR (opnum = 1), can't combine,
secondary_reload_p
        reload_reg_rtx: (reg:PQI 11 g11)
Reload 1: PT_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1), can't
combine, secondary_reload_p
        reload_reg_rtx: (reg:PQI 12 as0)
        secondary_in_reload = 0
Reload 2: GP_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1), can't
combine, secondary_reload_p
        reload_reg_rtx: (reg:PQI 11 g11)
Reload 3: PT_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1), can't
combine, secondary_reload_p
        reload_reg_rtx: (reg:PQI 13 as1)
        secondary_out_reload = 2

Reload 4: reload_in (PQI) = (reg/f:PQI 233)
        reload_out (PQI) = (reg/f:PQI 233)
        AD_REGS, RELOAD_OTHER (opnum = 1)
        reload_in_reg: (reg/f:PQI 233)
        reload_out_reg: (reg/f:PQI 233)
        reload_reg_rtx: (reg:PQI 31 a3)
        secondary_in_reload = 1, secondary_out_reload = 3

Reload 5: reload_out (QI) = (reg:QI 234 [+1 ])
        GP_REGS, RELOAD_FOR_OUTPUT (opnum = 0)
        reload_out_reg: (reg:QI 234 [+1 ])
        reload_reg_rtx: (reg:QI 11 g11)


(insn 744 336 745 2 ../rld_bug.c:94 (set (reg:PQI 11 g11)
        (mem/c:PQI (plus:PQI (reg/f:PQI 32 sp)
                (const_int -24 [0xffffffffffffffe8])) [99 %sfp+8 S1
A32])) 9 {movpqi_op} (nil))

(insn 745 744 746 2 ../rld_bug.c:94 (set (reg:PQI 12 as0)
        (reg:PQI 11 g11)) 9 {movpqi_op} (nil))

(insn 746 745 259 2 ../rld_bug.c:94 (set (reg:PQI 31 a3)
        (reg:PQI 12 as0)) 9 {movpqi_op} (nil))

(insn 259 746 747 2 ../rld_bug.c:94 (set (reg:QI 11 g11)
        (mem/s/j/c:QI (pre_modify:PQI (reg:PQI 31 a3)
                (plus:PQI (reg:PQI 31 a3)
                    (const_int 1 [0x1]))) [0+1 S1 A32])) 7 {movqi_op}
(expr_list:REG_INC (reg:PQI 31 a3)
        (nil)))

(insn 747 259 748 2 ../rld_bug.c:94 (set (reg:PQI 13 as1)
        (reg:PQI 31 a3)) 9 {movpqi_op} (nil))

(insn 748 747 749 2 ../rld_bug.c:94 (set (reg:PQI 11 g11)
        (reg:PQI 13 as1)) 9 {movpqi_op} (nil))

(insn 749 748 750 2 ../rld_bug.c:94 (set (mem/c:PQI (plus:PQI (reg/f:PQI 32 sp)
                (const_int -24 [0xffffffffffffffe8])) [99 %sfp+8 S1 A32])
        (reg:PQI 11 g11)) 9 {movpqi_op} (nil))

(insn 750 749 751 2 ../rld_bug.c:94 (set (mem/c:QI (plus:PQI (reg/f:PQI 32 sp)
                (const_int -29 [0xffffffffffffffe3])) [99 %sfp+3 S1 A32])
        (reg:QI 11 g11)) 7 {movqi_op} (nil))


After IRA pass for insn 259 1st the modified address is stored into
its spilled location and then the modified value is stored. As you can
see from the instructions same register (g11) is used for Reload 5 and
2, and hence the modified value is getting corrupted and hence the
modified address gets stored instead of modified value (insn 749 and
insn 750). I am not able to figure out where this is going wrong in
the reload phase. I suspect that this is a GCC issue.

Can some one give me some pointers to resolve this issue?

Regards,
Shafi

Reply via email to