Skip to main content

far

Function far 

Source
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.