Jay K via llvm-dev
2019-Jul-15 07:14 UTC
[llvm-dev] Having trouble getting started on writing a WDC 65816 backend
>> As I recall the big one is that LLVM isn't well adapted to instruction>> sets without fungible registers.>What does this mean exactly? How does the WDC 65816 not have fungible registers, while other processors do?>> One idea is to use some of bank 0 as>> a source of registers, maybe with a custom pass to promote things to>> real registers where possible after the fact.>How would I end up doing this? Do you mean bank 0 of the actual SNES ROM?Probably meant page 0, from a 6502 nomenclature, or "direct page" in 65816. Ah, so the 6502 and 65816. As I recall... These processors have one general purpose register "accumulator" and two limited-use index registers "x" and "y". So basically no registers. Therefore there is a reported style of programming the 6502 where the first 256 bytes of memory -- "page 0" -- are used as general purpose registers instead. The stack pointer "S" btw is an 8 bit register, implicitly referencing the second 256 bytes of memory -- "page 1". And silently wrapping around. Instructions referencing page 0 are smaller and faster than instructions referencing the rest of the 16bit address space. The 65816 is slightly less bad. It has a 24 bit address space (24 MB). It's stack pointer is widened to 16 bits, referencing anywhere in the first 64K. It also renames "page 0" to be "direct page", based via a new 16 bit "direct page" "D" register. If you assume a pushy/poppy ABI (like NT/x86, unlike NT/amd64), then these two registers combine to give you a semblance of a modern call sequence. D is like ebp. When it was said "bank 0" it was probably meant "page 0". Though 64K in 65816 might be a "bank" and the first 64K "bank 0". There is also a bank "K" register that implies the high 8 bits of most 16bit addresses (unless S- or D-relative). I'm still not sure what you'd do with this. I guess you can try picking a small number of general purpose registers. No more than 8, since x86 does "ok" with that. Model them as all volatile. ? Despite their historical high usefuless and that I programmed both of these, they are difficult for me to imagine using today. For the morbidly curious: The compare instruction only yields status bits useful for a conditional compare if the inputs are considered unsigned. To do a "compare" of signed integers, requires a destructive subtract. (but if accumulator does not count as a register, maybe you have not destroyed anything..) The interrupt enable/disable flag has a reversed meaning but same instruction mnemonics compared to x86. So people write the code backwards. sei/cli, but interrupt flag enabling vs. inhibiting interrupts. There is no add without carry instruction. You have to clear carry first, like always (unless doing multi-precision math). The subtract/borrow meaning I believe is also same mnemonic but reversed meaning from x86. You set carry before sbc, or such. It made sense to me at the time based on elementary school math at least. - Jay
Jay K via llvm-dev
2019-Jul-15 16:28 UTC
[llvm-dev] Having trouble getting started on writing a WDC 65816 backend
> The subtract/borrow meaning I believe is also same mnemonic > but reversed meaning from x86. > You set carry before sbc, or such. > It made sense to me at the time based on elementary school math at least. Actually it sense in college EE learning to implement an ALU. 🙂 Subtract is adding the negative. Two's complement negative is inverting and adding 1. The reversed carry is that added 1. And I guess the cleared carry is also correct then for extended precision. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190715/7388532e/attachment.html>