Yup, my registers are smaller than Pmode. This is what I ended up with...
Some notes: I lie to gcc and tell it that $fp (reg 22) is two bytes when it's really one. None of the register classes have reg 23 (used for the upper half of $fp) in them. Reg 23 is also listed as being two bytes, to keep the register pairing logic in reload in sync for registers above $fp (otherwise it only checks odd registers afer $fp). Does this all make sense? Index: reload.c =================================================================== --- reload.c (revision 203733) +++ reload.c (working copy) @@ -723,13 +723,15 @@ find_valid_class_1 (enum machine_mode ou unsigned int best_size = 0; int cost; for (rclass = 1; rclass < N_REG_CLASSES; rclass++) { int bad = 0; - for (regno = 0; regno < FIRST_PSEUDO_REGISTER && !bad; regno++) + for (regno = 0; + regno < FIRST_PSEUDO_REGISTER && !bad; + regno += HARD_REGNO_NREGS (regno, mode)) { if (in_hard_reg_set_p (reg_class_contents[rclass], mode, regno) && !HARD_REGNO_MODE_OK (regno, mode)) bad = 1; } Index: config/rl78/rl78.h =================================================================== --- config/rl78/rl78.h (revision 203733) +++ config/rl78/rl78.h (working copy) @@ -242,12 +242,14 @@ enum reg_class "V_REGS", \ "GR_REGS", \ "PSWREG", \ "ALL_REGS" \ } +/* Note that no class may include the second register in $fp, because + we treat $fp as a single HImode register. */ #define REG_CLASS_CONTENTS \ { \ { 0x00000000, 0x00000000 }, /* No registers, */ \ { 0x00000001, 0x00000000 }, \ { 0x00000002, 0x00000000 }, \ { 0x00000003, 0x00000000 }, \ Index: config/rl78/rl78.c =================================================================== --- config/rl78/rl78.c (revision 203733) +++ config/rl78/rl78.c (working copy) @@ -321,19 +321,21 @@ rl78_option_override (void) for (i = 24; i < 32; i++) fixed_regs[i] = 0; } } /* Most registers are 8 bits. Some are 16 bits because, for example, - gcc doesn't like dealing with $FP as a register pair. This table - maps register numbers to size in bytes. */ + gcc doesn't like dealing with $FP as a register pair (the second + half of $fp is also 2 to keep reload happy wrt register pairs, but + no register class includes it). This table maps register numbers + to size in bytes. */ static const int register_sizes[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1 }; /* Predicates used in the MD patterns. This one is true when virtual insns may be matched, which typically means before (or during) the