> Gosh, we got one of those too, though, I don't know how much worse > your machine is than mine, in at all.
In the RL78 case, it's basically a modern Z80 clone. It has eight 8-bit registers (er, four banks of those, one active at a time) which can be combined into four 16-bit registers, but for each addressing mode there's specific register pairs that can be used as base registers, and sometimes the "base register" is 8-bits and sometimes it's 16, and sometimes you can combine them (i.e. [HL+B]) in weird ways. Worse, most of the MOV operations and all of the math/logic operations *only* use the A/AX register, and the ones that use other registers are often asymmetrical. For example, you can move data from memory to BC, but not from BC to memory. It's the weird addressing modes that confuse gcc. (I had similar problems with the m32c port, although it was "clean" enough to eventually force it to work right. Er, "right enough". There's still one double-indirect addressing mode that I can't tell gcc about because it makes reload vomit.) Fortunately, there's an addressing mode that covers a small range of RAM with relatively flexible addressing, and that range happens to overlap the memory-mapped registers. So, we tell GCC to use some of that memory as "virtual registers" and after reload the devirtualization pass shuffles data in and out of real registers to do whatever operations are required, based on what addressing modes are used and what operations need be done. The post-reload optimizations then clean up unneeded moves etc. I.e. we built a micro-interpreter with a compile-time JIT :-) To do this, we have separate "virtual" and "real" *.md files and patterns, and the devirtualizer has some standard rules for copying data, which it applies until the pattern's predicates and constraints match. There are some hints in the patterns to tell it which rules to use, too. We do a recog on the virtual pattern to get the hints and operands, then recog on the real one until it works. > As we move to C++, I'd love for port maintainers to be able to get > together and hoist _up_ code from the port so other ports can use it > and thus, have more sharing. The one bit of code I seem to need more often than usual is an "unneeded move elimination" pass or helper. I'd like to be able to call that at arbitrary times after (or before, or during) other passes to clean up unneeded moves. My implementations are fairly trivial because they cater to my ports, but a generic one that covers all ports generically would be much more appropriate.