pub fn far(
func: &mut Func,
insts: &FrameInsts,
conv: &CallRegs,
scratch: &[PhysReg],
names: &mut Interner,
)Expand description
Points every access to the frame that its instruction cannot carry the offset of at a scratch register holding most of the address.
Nothing to do on x86, where every offset a frame has fits in the instruction. An AArch64 load
reaches a few kilobytes up from the stack pointer and add reaches four, so a local deep in a
large frame is written as add x16, sp, #4096 and then the access four thousand and some bytes
closer, which is what gcc writes. The part left in the instruction is the low bits when the
instruction can carry those and nothing when it cannot, which is the unaligned offset a scaled
load refuses.
After the allocator’s moves have been cleaned up rather than here in finish, because that
pass reads what each scratch register holds between one move and the next and an address
written into one in the middle is not a move it knows about. The scratch register is one the
instruction does not read, and one of the two always is, since an access through the stack
pointer has no base register of its own to have been reloaded into a scratch.