3 ms·
AArch64 uses adrp in almost exactly the same way that RISC-V uses auipc to access literal pools. It isn't a strongly distinguishing feature between those archi
by brandmeyer 8y ago
AArch64 uses adrp in almost exactly the same way that RISC-V uses auipc to access literal pools. It isn't a strongly distinguishing feature between those architectures.
The difference between them is that ADRP computes a 4 kB page-aligned pc-relative address, which complements the 12-bit unsigned address offsets in its base+disp addressing mode to get a uniform +(2 GB -1) to -2GB reach. RISC-V doesn't compute a page-aligned address, in order to partially compensate for the use of signed offsets in its base+disp12 addressing mode. I say partially because RISC-V's PC-relative reach remains asymmetric +(2 GB - 2k - 1) to -(2 GB + 2k), but that probably doesn't matter much as long as you establish an appropriate red zone.
ARM distinguishes immediate operands used for data processing and immediate operands used for address generation. The alternative formats I was referring to are mostly just available for the logical operations (although Thumb2 sometimes also uses them for arithmetic). I was thinking that they might make pointer tagging a smidge easier to deal with.
*edit: Whoops, 12-bit signed, not 10-bit signed on the asymmetry of the RISC-V reach.
- brucehoult 8y agoYour figures seem a little off there. Yes, RISC-V is a little asymmetric, with the AUIPC being able to subtract exactly 2 GB from the PC or add 2GB-4KB to it, and then a jalr/lb/sb can subtract an additional 2 KB or add 2KB-1. But the AArch64 adrp is also asymmetric because the relative reach depends on where in the 4 KB page the original PC is. It's only symmetric if the PC is 4 KB aligned. If you're part way through the page then there is more -ve reach and less +ve reach. A couple of KB fuzziness in what is basically a 32 bit reach in a 64 bit address space is pretty much completely irrelevant in both cases.
- brandmeyer 8y agoADRP operates on the 4kB page of the pc (by truncation), not the entire pc. RISC-V could have implicitly added 2k in auipc and balanced out the bias. But they didn't.
- brucehoult 8y agoI know how ADRP operates. It's symmetric about the truncated PC. It's not symmetric about the actual PC. As I said in the last post.
- brandmeyer 8y agoI think you are misunderstanding the benefit of having symmetric reach by the page. On AArch64, you can define a 2 GB contiguous slice of address space, built up out of whatever page size you find convenient for your system and plant a relocatable binary into it, up to 2 GB of size. Any instruction anywhere in the last page can reach any address in the first page, and vice versa. In RISC-V, if you try to do the same thing, you'd find that while any instructions in the last page can reach any address in the first page with room to spare. But some instructions in the first page cannot reach portions of the last page. Sure, it doesn't matter most of the time. It isn't ever really an obstacle in practice for the feller writing application code for the platform. But the linker has to be aware of it in the 'medium' code model as a special case for just this particular platform. Somebody had to write that special case to work around the hardware.
- brucehoult 8y agoThe linker code to calculate the necessary auipc and remaining offset for a relocation and do something else when out of bounds, was written years ago, is two lines of code, and no doubt took less time than this conversation. I don't even know of any application that has 1 GB of code, let alone 2 GB minus 2 KB (2,147,481,600 bytes).
- microcolonel 8y ago> AArch64 uses adrp in almost exactly the same way that RISC-V uses auipc to access literal pools. I meant that you could forego the constant pool (ARM calls them literal pools?) for branch targets in some use cases due to the added range of RISC-V U immediates, and in more cases than you can with ARMv8 (which only now offers 16-bit immediates in some cases, AFAIK [ARM's infocenter timed out, and I couldn't find it in the manual with search, so I'm basing this on some forum post by some dude]). With auipc you can compute an address 1GiB two ways from the pc, to the byte, and with no base register to be set in your JIT entry frames and allocated around. In the V8 "arm64" port, it seems they manage 128MB as a practical matter: https://github.com/v8/v8/blob/master/src/arm64/constants-arm64.h#L29 https://github.com/v8/v8/blob/master/src/arm64/constants-arm...
- brandmeyer 8y agoFor the most part, ARMv8 immediates are 12 bits for [base + displacement] addressing. However, most of the modes also allow you to use natural scaling of the displacement (or index in [base + index] modes). So you can reach the 4096th byte, or the 4096th pointer in a struct (and other sizes in between). That 128 MB limit is interesting. Its the limit for direct pc-relative calls in ARMv8 without resorting to adrp.