caps, mosfets, and the happiest thoughts in the universe
https://dram.page
https://github.com/dramforever
https://cohost.org/dram
https://ko-fi.com/dramforever
caps, mosfets, and the happiest thoughts in the universe
https://dram.page
https://github.com/dramforever
https://cohost.org/dram
https://ko-fi.com/dramforever
Fun thing I've learned about RISC-V recently:
There is no easy way of writing a 32-bit nop in RISC-V assembly.
RISC-V tries to make the C extension transparent. You don't need to write compressed variants of instructions, you just write as if you're targeting the 32-bit encoding and the assembler transparently shrinks some things for you. The C extension is entirely duplicated instructions: every 16-bit instruction in the C extension can also be written as a 32-bit instruction and this leaves it to the assembler to figure out which.
The exact same logic is applied to NOPs (which aren't really nops, they're add 0 to 0 and store the result in the zero register). There is a NOP and a C.NOP variant, but because NOP is an alias for ADDI x0, x0, 0 and C.NOP is an alias for C.ADDI x0, 0 (which is equivalent), the assembler will always emit C.NOP (a.k.a. C.ADDI x0, 0) if you write NOP. You can generate a non-canonical nop by doing something like ADDI x0, x15, 0x200, which can't be compressed (currently), but that's fragile.
This is an issue if you want to guarantee padding space in the instruction stream for later patching or linker relaxations.
As far as I am aware, RISC-V is the only variable-length architecture whose assembler makes this mistake. x86 and Thumb-2, for example, both have explicit mnemonics for longer nops. Thumb-2 has NOP and NOP.W. x86 has a baroque list of arguments you add to NOP to make it 2-15 bytes (it's one byte with no operands).
Well this is ✨interesting✨!
Turns out, macOS already supports what it needs to run Intel binaries with a non-Rosetta emulator, after Rosetta dies.
It's behind a private entitlement for now, but still!
Wine+FEX+ARM64EC anyone? ^^