> > Some notes: I lie to gcc and tell it that $fp (reg 22) is two bytes > > when it's really one. > > Well, it's not really a lie if you map hardware registers 22 and 23 to > a single register for the purposes of gcc internals.
Yeah, I'm basically making those two registers into a permanent bigger register. > Although it does make some other things more awkward, e.g. when you > copy fp, and this gets split so you have an insn that copies the > highpart of fp to another register. Not a problem, the chip can copy the whole $fp in one insn. Registers are only 8 bits on this chip. > Seeing the patched code in its entirety like this, I notice that we > would use HARD_REGNO_NREGS for a regno that's not ok for the mode. The core problem is that gcc has no way of dealing with register pairs as real registers - the second halves are still registers, still need to be in the reg class, still need _NREGS() values, etc. There's no way to tell gcc that a "register" is a set of (for example) N registers starting at 3, 5, 9, 12, or 14. > That can be avoided if we put a break into the if. And then the > !bad term in the loop condition becomes redundant. The problem I had to solve was to re-synchronize the counter with the even-numbered register. The naive patch counted even registers up to $fp, then checked odd (invalid) registers after that. The only other way I can think to "solve" this problem is to add a VALID_STARTING_REG(reg,mode) macro, but that would require changes all over the core code.