• Keith Randall's avatar
    [dev.ssa] cmd/compile: fix PIC for SSA-generated code · 2cbdd55d
    Keith Randall authored
    Access to globals requires a 2-instruction sequence on PIC 386.
    
        MOVL foo(SB), AX
    
    is translated by the obj package into:
    
        CALL getPCofNextInstructionInTempRegister(SB)
        MOVL (&foo-&thisInstruction)(tmpReg), AX
    
    The call returns the PC of the next instruction in a register.
    The next instruction then offsets from that register to get the
    address required.  The tricky part is the allocation of the
    temp register.  The legacy compiler always used CX, and forbid
    the register allocator from allocating CX when in PIC mode.
    We can't easily do that in SSA because CX is actually a required
    register for shift instructions. (I think the old backend got away
    with this because the register allocator never uses CX, only
    codegen knows that shifts must use CX.)
    
    Instead, we allow the temp register to be anything.  When the
    destination of the MOV (or LEA) is an integer register, we can
    use that register.  Otherwise, we make sure to compile the
    operation using an LEA to reference the global.  So
    
        MOVL AX, foo(SB)
    
    is never generated directly.  Instead, SSA generates:
    
        LEAL foo(SB), DX
        MOVL AX, (DX)
    
    which is then rewritten by the obj package to:
    
        CALL getPcInDX(SB)
        LEAL (&foo-&thisInstruction)(DX), AX
        MOVL AX, (DX)
    
    So this CL modifies the obj package to use different thunks
    to materialize the pc into different registers.  We use the
    registers that regalloc chose so that SSA can still allocate
    the full set of registers.
    
    Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
    Reviewed-on: https://go-review.googlesource.com/25442
    Run-TryBot: Keith Randall <khr@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: 's avatarDavid Chase <drchase@google.com>
    2cbdd55d
asm.go 18.1 KB