> From: Jamie Prescott <[email protected]>
> To: [email protected]
> Sent: Friday, May 15, 2009 3:28:18 PM
> Subject: Different reload behavior from 4.3.3 to 4.4
>
>
> In my VM, the X_REGS class is a generic 64bit regsiter class that can hold
> both 64bit DImode and 64bit DFmode.
> Such class does not allow direct constant loading, so in 4.3.3 I had:
>
> enum reg_class
> xxx_preferred_reload_class(rtx x, enum reg_class regclass)
> {
> enum machine_mode mode = GET_MODE(x);
>
> if (regclass == NO_REGS ||
> ((GET_CODE(x) == CONST_INT ||
> GET_CODE(x) == CONST_DOUBLE) && regclass == X_REGS))
> return NO_REGS;
> switch (mode) {
> case DImode:
> case SFmode:
> case DFmode:
> return X_REGS;
> default:
> break;
> }
>
> return regclass;
> }
>
> This was working fine with 4.3.3, while with 4.4 I get an error like if GCC
> was
> trying
> to load a const_int directly anyway:
>
> ./csrc/test_sha512.c:294: error: insn does not satisfy its constraints:
> (insn 870 869 43 2 ./csrc/test_sha512.c:200 (set (reg:DI 55 x0)
> (const_int 7640891576956012808 [0x6a09e667f3bcc908])) 31 {movdi}
> (nil))
> ./csrc/test_sha512.c:294: internal compiler error: in
> reload_cse_simplify_operands, at postreload.c:396
Found it.
The reload function were called with X0_REG, that is a class containing only
X0, and is
in turn a subclass of X_REGS.
So the test had to be changed to a REG_CLASS_X(rcls), to account all the classes
storing 64bit registers.
This was a bitch to diagnose.
enum reg_class
xxx_preferred_reload_class(rtx x, enum reg_class regclass)
{
enum machine_mode mode = GET_MODE(x);
if (regclass == NO_REGS ||
((GET_CODE(x) == CONST_INT ||
GET_CODE(x) == CONST_DOUBLE) && REG_CLASS_X(regclass)))
return NO_REGS;
switch (mode) {
case DImode:
case SFmode:
case DFmode:
return REG_CLASS_X(regclass) ? regclass: X_REGS;
default:
break;
}
return regclass;
}
- Jamie