On Fri, Aug 04, 2006 at 11:21:05AM +0200, Bernd Schmidt wrote:
> Probably the compiler doesn't in general like a paradoxical subreg that
> can take more hard regs than its SUBREG_REG. I think this is probably
> something that can be worked around with a proper combination of
> MODES_TIEABLE_P, CANNOT_CHANGE_MODE_CLASS, and maybe
> REG_CANNOT_CHANGE_MODE_P.
This should be documented! It is not obvious that this may be the case.
I backed out the patch I put in and changed my definition of
CANNOT_CHANGE_MODE_CLASS() to this:
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
(GET_MODE_SIZE(TO) > GET_MODE_SIZE(FROM) \
|| (((TO) == QImode || (FROM) == QImode) \
&& reg_classes_intersect_p (HI_REGS, (CLASS))))
This disallows any mode change which will require more hard regs. Now, the
insn still looks the same before reload:
(insn:HI 2485 2483 2486 39 libgcc2.c:1825 (set (subreg:HI (reg:QI 178) 0)
(ashiftrt:HI (reg:HI 641)
(const_int 15 [0xf]))) 31 {*ashrhi3_const15}
(insn_list:REG_DEP_TRUE 2480 (nil))
(expr_list:REG_DEAD (reg:HI 641)
(nil)))
But reload now reloads the whole subreg instead of just the inner reg:
Reloads for insn # 2485
Reload 0: reload_out (HI) = (subreg:HI (reg:QI 178) 0)
DX_REGS, RELOAD_FOR_OUTPUT (opnum = 0)
reload_out_reg: (subreg:HI (reg:QI 178) 0)
reload_reg_rtx: (reg:HI 4 d)
Reload 1: reload_in (HI) = (reg:HI 0 c [641])
AX_REGS, RELOAD_FOR_INPUT (opnum = 1)
reload_in_reg: (reg:HI 0 c [641])
reload_reg_rtx: (reg:HI 2 a)
The resulting insns are correct:
(insn:HI 2485 2606 2605 39 libgcc2.c:1825 (set (reg:HI 4 d)
(ashiftrt:HI (reg:HI 2 a)
(const_int 15 [0xf]))) 31 {*ashrhi3_const15}
(insn_list:REG_DEP_TRUE 2480 (nil))
(nil))
(insn 2605 2485 2486 39 libgcc2.c:1825 (set (mem/c:QI (plus:HI (reg/f:HI 10 bp)
(const_int -42 [0xffffffd6])) [10 S1 A8])
(reg:QI 4 d)) 34 {movqi} (nil)
(nil))
--
Rask Ingemann Lambertsen
"If you leave out a few minor details, gcc is simply a translator of text
files from C/C++/whatever text to assembly text." - Ian Lance Taylor