// Inferno utils/6l/pass.c
// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/pass.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package x86

import (
	"cmd/internal/obj"
	"cmd/internal/objabi"
	"cmd/internal/src"
	"cmd/internal/sys"
	"internal/abi"
	"log"
	"math"
	"path"
	"strings"
)

func CanUse1InsnTLS(ctxt *obj.Link) bool {
	if isAndroid {
		// Android uses a global variable for the tls offset.
		return false
	}

	if ctxt.Arch.Family == sys.I386 {
		switch ctxt.Headtype {
		case objabi.Hlinux,
			objabi.Hplan9,
			objabi.Hwindows:
			return false
		}

		return true
	}

	switch ctxt.Headtype {
	case objabi.Hplan9, objabi.Hwindows:
		return false
	case objabi.Hlinux, objabi.Hfreebsd:
		return !ctxt.Flag_shared
	}

	return true
}

func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
	// Thread-local storage references use the TLS pseudo-register.
	// As a register, TLS refers to the thread-local storage base, and it
	// can only be loaded into another register:
	//
	//         MOVQ TLS, AX
	//
	// An offset from the thread-local storage base is written off(reg)(TLS*1).
	// Semantically it is off(reg), but the (TLS*1) annotation marks this as
	// indexing from the loaded TLS base. This emits a relocation so that
	// if the linker needs to adjust the offset, it can. For example:
	//
	//         MOVQ TLS, AX
	//         MOVQ 0(AX)(TLS*1), CX // load g into CX
	//
	// On systems that support direct access to the TLS memory, this
	// pair of instructions can be reduced to a direct TLS memory reference:
	//
	//         MOVQ 0(TLS), CX // load g into CX
	//
	// The 2-instruction and 1-instruction forms correspond to the two code
	// sequences for loading a TLS variable in the local exec model given in "ELF
	// Handling For Thread-Local Storage".
	//
	// We apply this rewrite on systems that support the 1-instruction form.
	// The decision is made using only the operating system and the -shared flag,
	// not the link mode. If some link modes on a particular operating system
	// require the 2-instruction form, then all builds for that operating system
	// will use the 2-instruction form, so that the link mode decision can be
	// delayed to link time.
	//
	// In this way, all supported systems use identical instructions to
	// access TLS, and they are rewritten appropriately first here in
	// liblink and then finally using relocations in the linker.
	//
	// When -shared is passed, we leave the code in the 2-instruction form but
	// assemble (and relocate) them in different ways to generate the initial
	// exec code sequence. It's a bit of a fluke that this is possible without
	// rewriting the instructions more comprehensively, and it only does because
	// we only support a single TLS variable (g).

	if CanUse1InsnTLS(ctxt) {
		// Reduce 2-instruction sequence to 1-instruction sequence.
		// Sequences like
		//	MOVQ TLS, BX
		//	... off(BX)(TLS*1) ...
		// become
		//	NOP
		//	... off(TLS) ...
		//
		// TODO(rsc): Remove the Hsolaris special case. It exists only to
		// guarantee we are producing byte-identical binaries as before this code.
		// But it should be unnecessary.
		if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 && ctxt.Headtype != objabi.Hsolaris {
			obj.Nopout(p)
		}
		if p.From.Type == obj.TYPE_MEM && p.From.Index == REG_TLS && REG_AX <= p.From.Reg && p.From.Reg <= REG_R15 {
			p.From.Reg = REG_TLS
			p.From.Scale = 0
			p.From.Index = REG_NONE
		}

		if p.To.Type == obj.TYPE_MEM && p.To.Index == REG_TLS && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
			p.To.Reg = REG_TLS
			p.To.Scale = 0
			p.To.Index = REG_NONE
		}
	} else {
		// load_g, below, always inserts the 1-instruction sequence. Rewrite it
		// as the 2-instruction sequence if necessary.
		//	MOVQ 0(TLS), BX
		// becomes
		//	MOVQ TLS, BX
		//	MOVQ 0(BX)(TLS*1), BX
		if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
			q := obj.Appendp(p, newprog)
			q.As = p.As
			q.From = p.From
			q.From.Type = obj.TYPE_MEM
			q.From.Reg = p.To.Reg
			q.From.Index = REG_TLS
			q.From.Scale = 2 // TODO: use 1
			q.To = p.To
			p.From.Type = obj.TYPE_REG
			p.From.Reg = REG_TLS
			p.From.Index = REG_NONE
			p.From.Offset = 0
		}
	}

	// Android and Windows use a tls offset determined at runtime. Rewrite
	//	MOVQ TLS, BX
	// to
	//	MOVQ runtime.tls_g(SB), BX
	if (isAndroid || ctxt.Headtype == objabi.Hwindows) &&
		(p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
		p.From.Type = obj.TYPE_MEM
		p.From.Name = obj.NAME_EXTERN
		p.From.Reg = REG_NONE
		p.From.Sym = ctxt.Lookup("runtime.tls_g")
		p.From.Index = REG_NONE
		if ctxt.Headtype == objabi.Hwindows {
			// Windows requires an additional indirection
			// to retrieve the TLS pointer,
			// as runtime.tls_g contains the TLS offset from GS or FS.
			// on AMD64 add
			//	MOVQ 0(BX)(GS*1), BX
			// on 386 add
			//	MOVQ 0(BX)(FS*1), BX4
			q := obj.Appendp(p, newprog)
			q.As = p.As
			q.From = obj.Addr{}
			q.From.Type = obj.TYPE_MEM
			q.From.Reg = p.To.Reg
			if ctxt.Arch.Family == sys.AMD64 {
				q.From.Index = REG_GS
			} else {
				q.From.Index = REG_FS
			}
			q.From.Scale = 1
			q.From.Offset = 0
			q.To = p.To
		}
	}

	// TODO: Remove.
	if ctxt.Headtype == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64 || ctxt.Headtype == objabi.Hplan9 {
		if p.From.Scale == 1 && p.From.Index == REG_TLS {
			p.From.Scale = 2
		}
		if p.To.Scale == 1 && p.To.Index == REG_TLS {
			p.To.Scale = 2
		}
	}

	// Rewrite 0 to $0 in 3rd argument to CMPPS etc.
	// That's what the tables expect.
	switch p.As {
	case ACMPPD, ACMPPS, ACMPSD, ACMPSS:
		if p.To.Type == obj.TYPE_MEM && p.To.Name == obj.NAME_NONE && p.To.Reg == REG_NONE && p.To.Index == REG_NONE && p.To.Sym == nil {
			p.To.Type = obj.TYPE_CONST
		}
	}

	// Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH.
	switch p.As {
	case obj.ACALL, obj.AJMP, obj.ARET:
		if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil {
			p.To.Type = obj.TYPE_BRANCH
		}
	}

	// Rewrite MOVL/MOVQ $XXX(FP/SP) as LEAL/LEAQ.
	if p.From.Type == obj.TYPE_ADDR && (ctxt.Arch.Family == sys.AMD64 || p.From.Name != obj.NAME_EXTERN && p.From.Name != obj.NAME_STATIC) {
		switch p.As {
		case AMOVL:
			p.As = ALEAL
			p.From.Type = obj.TYPE_MEM
		case AMOVQ:
			p.As = ALEAQ
			p.From.Type = obj.TYPE_MEM
		}
	}

	// Rewrite float constants to values stored in memory.
	switch p.As {
	// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
	case AMOVSS, AVMOVSS:
		if p.From.Type == obj.TYPE_FCONST {
			//  f == 0 can't be used here due to -0, so use Float64bits
			if f := p.From.Val.(float64); math.Float64bits(f) == 0 {
				if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X15 {
					p.As = AXORPS
					p.From = p.To
					break
				}
			}
		}
		fallthrough

	case AFMOVF,
		AFADDF,
		AFSUBF,
		AFSUBRF,
		AFMULF,
		AFDIVF,
		AFDIVRF,
		AFCOMF,
		AFCOMFP,
		AADDSS,
		ASUBSS,
		AMULSS,
		ADIVSS,
		ACOMISS,
		AUCOMISS:
		if p.From.Type == obj.TYPE_FCONST {
			f32 := float32(p.From.Val.(float64))
			p.From.Type = obj.TYPE_MEM
			p.From.Name = obj.NAME_EXTERN
			p.From.Sym = ctxt.Float32Sym(f32)
			p.From.Offset = 0
		}

	case AMOVSD, AVMOVSD:
		// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
		if p.From.Type == obj.TYPE_FCONST {
			//  f == 0 can't be used here due to -0, so use Float64bits
			if f := p.From.Val.(float64); math.Float64bits(f) == 0 {
				if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X15 {
					p.As = AXORPS
					p.From = p.To
					break
				}
			}
		}
		fallthrough

	case AFMOVD,
		AFADDD,
		AFSUBD,
		AFSUBRD,
		AFMULD,
		AFDIVD,
		AFDIVRD,
		AFCOMD,
		AFCOMDP,
		AADDSD,
		ASUBSD,
		AMULSD,
		ADIVSD,
		ACOMISD,
		AUCOMISD:
		if p.From.Type == obj.TYPE_FCONST {
			f64 := p.From.Val.(float64)
			p.From.Type = obj.TYPE_MEM
			p.From.Name = obj.NAME_EXTERN
			p.From.Sym = ctxt.Float64Sym(f64)
			p.From.Offset = 0
		}
	}

	if ctxt.Flag_dynlink {
		rewriteToUseGot(ctxt, p, newprog)
	}

	if ctxt.Flag_shared && ctxt.Arch.Family == sys.I386 {
		rewriteToPcrel(ctxt, p, newprog)
	}
}

// Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
	var lea, mov obj.As
	var reg int16
	if ctxt.Arch.Family == sys.AMD64 {
		lea = ALEAQ
		mov = AMOVQ
		reg = REG_R15
	} else {
		lea = ALEAL
		mov = AMOVL
		reg = REG_CX
		if p.As == ALEAL && p.To.Reg != p.From.Reg && p.To.Reg != p.From.Index {
			// Special case: clobber the destination register with
			// the PC so we don't have to clobber CX.
			// The SSA backend depends on CX not being clobbered across LEAL.
			// See cmd/compile/internal/ssa/gen/386.rules (search for Flag_shared).
			reg = p.To.Reg
		}
	}

	if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
		//     ADUFFxxx $offset
		// becomes
		//     $MOV runtime.duffxxx@GOT, $reg
		//     $LEA $offset($reg), $reg
		//     CALL $reg
		// (we use LEAx rather than ADDx because ADDx clobbers
		// flags and duffzero on 386 does not otherwise do so).
		var sym *obj.LSym
		if p.As == obj.ADUFFZERO {
			sym = ctxt.LookupABI("runtime.duffzero", obj.ABIInternal)
		} else {
			sym = ctxt.LookupABI("runtime.duffcopy", obj.ABIInternal)
		}
		offset := p.To.Offset
		p.As = mov
		p.From.Type = obj.TYPE_MEM
		p.From.Name = obj.NAME_GOTREF
		p.From.Sym = sym
		p.To.Type = obj.TYPE_REG
		p.To.Reg = reg
		p.To.Offset = 0
		p.To.Sym = nil
		p1 := obj.Appendp(p, newprog)
		p1.As = lea
		p1.From.Type = obj.TYPE_MEM
		p1.From.Offset = offset
		p1.From.Reg = reg
		p1.To.Type = obj.TYPE_REG
		p1.To.Reg = reg
		p2 := obj.Appendp(p1, newprog)
		p2.As = obj.ACALL
		p2.To.Type = obj.TYPE_REG
		p2.To.Reg = reg
	}

	// We only care about global data: NAME_EXTERN means a global
	// symbol in the Go sense, and p.Sym.Local is true for a few
	// internally defined symbols.
	if p.As == lea && p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
		// $LEA sym, Rx becomes $MOV $sym, Rx which will be rewritten below
		p.As = mov
		p.From.Type = obj.TYPE_ADDR
	}
	if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
		// $MOV $sym, Rx becomes $MOV sym@GOT, Rx
		// $MOV $sym+<off>, Rx becomes $MOV sym@GOT, Rx; $LEA <off>(Rx), Rx
		// On 386 only, more complicated things like PUSHL $sym become $MOV sym@GOT, CX; PUSHL CX
		cmplxdest := false
		pAs := p.As
		var dest obj.Addr
		if p.To.Type != obj.TYPE_REG || pAs != mov {
			if ctxt.Arch.Family == sys.AMD64 {
				ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p)
			}
			cmplxdest = true
			dest = p.To
			p.As = mov
			p.To.Type = obj.TYPE_REG
			p.To.Reg = reg
			p.To.Sym = nil
			p.To.Name = obj.NAME_NONE
		}
		p.From.Type = obj.TYPE_MEM
		p.From.Name = obj.NAME_GOTREF
		q := p
		if p.From.Offset != 0 {
			q = obj.Appendp(p, newprog)
			q.As = lea
			q.From.Type = obj.TYPE_MEM
			q.From.Reg = p.To.Reg
			q.From.Offset = p.From.Offset
			q.To = p.To
			p.From.Offset = 0
		}
		if cmplxdest {
			q = obj.Appendp(q, newprog)
			q.As = pAs
			q.To = dest
			q.From.Type = obj.TYPE_REG
			q.From.Reg = reg
		}
	}
	from3 := p.GetFrom3()
	for i := range p.RestArgs {
		a := &p.RestArgs[i].Addr
		if a != from3 && a.Name == obj.NAME_EXTERN && !a.Sym.Local() {
			ctxt.Diag("don't know how to handle %v with -dynlink", p)
		}
	}
	var source *obj.Addr
	// MOVx sym, Ry becomes $MOV sym@GOT, R15; MOVx (R15), Ry
	// MOVx Ry, sym becomes $MOV sym@GOT, R15; MOVx Ry, (R15)
	// An addition may be inserted between the two MOVs if there is an offset.
	if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
		if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
			ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
		}
		if from3 != nil && from3.Name == obj.NAME_EXTERN && !from3.Sym.Local() {
			ctxt.Diag("cannot handle NAME_EXTERN on multiple operands in %v with -dynlink", p)
		}
		source = &p.From
	} else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
		if from3 != nil && from3.Name == obj.NAME_EXTERN && !from3.Sym.Local() {
			ctxt.Diag("cannot handle NAME_EXTERN on multiple operands in %v with -dynlink", p)
		}
		source = &p.To
	} else if from3 != nil && from3.Name == obj.NAME_EXTERN && !from3.Sym.Local() {
		source = from3
	} else {
		return
	}
	if p.As == obj.ACALL {
		// When dynlinking on 386, almost any call might end up being a call
		// to a PLT, so make sure the GOT pointer is loaded into BX.
		// RegTo2 is set on the replacement call insn to stop it being
		// processed when it is in turn passed to progedit.
		//
		// We disable open-coded defers in buildssa() on 386 ONLY with shared
		// libraries because of this extra code added before deferreturn calls.
		//
		// computeDeferReturn in cmd/link/internal/ld/pcln.go depends
		// on the size of these instructions.
		if ctxt.Arch.Family == sys.AMD64 || (p.To.Sym != nil && p.To.Sym.Local()) || p.RegTo2 != 0 {
			return
		}
		p1 := obj.Appendp(p, newprog)
		p2 := obj.Appendp(p1, newprog)

		p1.As = ALEAL
		p1.From.Type = obj.TYPE_MEM
		p1.From.Name = obj.NAME_STATIC
		p1.From.Sym = ctxt.Lookup("_GLOBAL_OFFSET_TABLE_")
		p1.To.Type = obj.TYPE_REG
		p1.To.Reg = REG_BX

		p2.As = p.As
		p2.Scond = p.Scond
		p2.From = p.From
		if p.RestArgs != nil {
			p2.RestArgs = append(p2.RestArgs, p.RestArgs...)
		}
		p2.Reg = p.Reg
		p2.To = p.To
		// p.To.Type was set to TYPE_BRANCH above, but that makes checkaddr
		// in ../pass.go complain, so set it back to TYPE_MEM here, until p2
		// itself gets passed to progedit.
		p2.To.Type = obj.TYPE_MEM
		p2.RegTo2 = 1

		obj.Nopout(p)
		return

	}
	if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ARET || p.As == obj.AJMP {
		return
	}
	if source.Type != obj.TYPE_MEM {
		ctxt.Diag("don't know how to handle %v with -dynlink", p)
	}
	p1 := obj.Appendp(p, newprog)
	p2 := obj.Appendp(p1, newprog)

	p1.As = mov
	p1.From.Type = obj.TYPE_MEM
	p1.From.Sym = source.Sym
	p1.From.Name = obj.NAME_GOTREF
	p1.To.Type = obj.TYPE_REG
	p1.To.Reg = reg

	p2.As = p.As
	p2.From = p.From
	p2.To = p.To
	p2.RestArgs = p.RestArgs
	if p.From.Name == obj.NAME_EXTERN {
		p2.From.Reg = reg
		p2.From.Name = obj.NAME_NONE
		p2.From.Sym = nil
	} else if p.To.Name == obj.NAME_EXTERN {
		p2.To.Reg = reg
		p2.To.Name = obj.NAME_NONE
		p2.To.Sym = nil
	} else if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
		from3 = p2.GetFrom3()
		from3.Reg = reg
		from3.Name = obj.NAME_NONE
		from3.Sym = nil
	} else {
		return
	}
	obj.Nopout(p)
}

func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
	// RegTo2 is set on the instructions we insert here so they don't get
	// processed twice.
	if p.RegTo2 != 0 {
		return
	}
	if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP {
		return
	}
	// Any Prog (aside from the above special cases) with an Addr with Name ==
	// NAME_EXTERN, NAME_STATIC or NAME_GOTREF has a CALL __x86.get_pc_thunk.XX
	// inserted before it.
	isName := func(a *obj.Addr) bool {
		if a.Sym == nil || (a.Type != obj.TYPE_MEM && a.Type != obj.TYPE_ADDR) || a.Reg != 0 {
			return false
		}
		if a.Sym.Type == objabi.STLSBSS {
			return false
		}
		return a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_STATIC || a.Name == obj.NAME_GOTREF
	}

	if isName(&p.From) && p.From.Type == obj.TYPE_ADDR {
		// Handle things like "MOVL $sym, (SP)" or "PUSHL $sym" by rewriting
		// to "MOVL $sym, CX; MOVL CX, (SP)" or "MOVL $sym, CX; PUSHL CX"
		// respectively.
		if p.To.Type != obj.TYPE_REG {
			q := obj.Appendp(p, newprog)
			q.As = p.As
			q.From.Type = obj.TYPE_REG
			q.From.Reg = REG_CX
			q.To = p.To
			p.As = AMOVL
			p.To.Type = obj.TYPE_REG
			p.To.Reg = REG_CX
			p.To.Sym = nil
			p.To.Name = obj.NAME_NONE
		}
	}

	if !isName(&p.From) && !isName(&p.To) && (p.GetFrom3() == nil || !isName(p.GetFrom3())) {
		return
	}
	var dst int16 = REG_CX
	if (p.As == ALEAL || p.As == AMOVL) && p.To.Reg != p.From.Reg && p.To.Reg != p.From.Index {
		dst = p.To.Reg
		// Why? See the comment near the top of rewriteToUseGot above.
		// AMOVLs might be introduced by the GOT rewrites.
	}
	q := obj.Appendp(p, newprog)
	q.RegTo2 = 1
	r := obj.Appendp(q, newprog)
	r.RegTo2 = 1
	q.As = obj.ACALL
	thunkname := "__x86.get_pc_thunk." + strings.ToLower(rconv(int(dst)))
	q.To.Sym = ctxt.LookupInit(thunkname, func(s *obj.LSym) { s.Set(obj.AttrLocal, true) })
	q.To.Type = obj.TYPE_MEM
	q.To.Name = obj.NAME_EXTERN
	r.As = p.As
	r.Scond = p.Scond
	r.From = p.From
	r.RestArgs = p.RestArgs
	r.Reg = p.Reg
	r.To = p.To
	if isName(&p.From) {
		r.From.Reg = dst
	}
	if isName(&p.To) {
		r.To.Reg = dst
	}
	if p.GetFrom3() != nil && isName(p.GetFrom3()) {
		r.GetFrom3().Reg = dst
	}
	obj.Nopout(p)
}

// Prog.mark
const (
	markBit = 1 << 0 // used in errorCheck to avoid duplicate work
)

func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
	if cursym.Func().Text == nil || cursym.Func().Text.Link == nil {
		return
	}

	p := cursym.Func().Text
	autoffset := int32(p.To.Offset)
	if autoffset < 0 {
		autoffset = 0
	}

	hasCall := false
	for q := p; q != nil; q = q.Link {
		if q.As == obj.ACALL || q.As == obj.ADUFFCOPY || q.As == obj.ADUFFZERO {
			hasCall = true
			break
		}
	}

	var bpsize int
	if ctxt.Arch.Family == sys.AMD64 &&
		!p.From.Sym.NoFrame() && // (1) below
		!(autoffset == 0 && !hasCall) { // (2) below
		// Make room to save a base pointer.
		// There are 2 cases we must avoid:
		// 1) If noframe is set (which we do for functions which tail call).
		// For performance, we also want to avoid:
		// 2) Frameless leaf functions
		bpsize = ctxt.Arch.PtrSize
		autoffset += int32(bpsize)
		p.To.Offset += int64(bpsize)
	} else {
		bpsize = 0
		p.From.Sym.Set(obj.AttrNoFrame, true)
	}

	textarg := int64(p.To.Val.(int32))
	cursym.Func().Args = int32(textarg)
	cursym.Func().Locals = int32(p.To.Offset)

	// TODO(rsc): Remove.
	if ctxt.Arch.Family == sys.I386 && cursym.Func().Locals < 0 {
		cursym.Func().Locals = 0
	}

	// TODO(rsc): Remove 'ctxt.Arch.Family == sys.AMD64 &&'.
	if ctxt.Arch.Family == sys.AMD64 && autoffset < abi.StackSmall && !p.From.Sym.NoSplit() {
		leaf := true
	LeafSearch:
		for q := p; q != nil; q = q.Link {
			switch q.As {
			case obj.ACALL:
				// Treat common runtime calls that take no arguments
				// the same as duffcopy and duffzero.

				// Note that of these functions, panicBounds does
				// use some stack, but its stack together with the
				// < StackSmall used by this function is still
				// less than stackNosplit. See issue 31219.
				if !isZeroArgRuntimeCall(q.To.Sym) {
					leaf = false
					break LeafSearch
				}
				fallthrough
			case obj.ADUFFCOPY, obj.ADUFFZERO:
				if autoffset >= abi.StackSmall-8 {
					leaf = false
					break LeafSearch
				}
			}
		}

		if leaf {
			p.From.Sym.Set(obj.AttrNoSplit, true)
		}
	}

	if !p.From.Sym.NoSplit() {
		// Emit split check.
		p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg))
	}

	if bpsize > 0 {
		// Save caller's BP
		p = obj.Appendp(p, newprog)

		p.As = APUSHQ
		p.From.Type = obj.TYPE_REG
		p.From.Reg = REG_BP

		// Move current frame to BP
		p = obj.Appendp(p, newprog)

		p.As = AMOVQ
		p.From.Type = obj.TYPE_REG
		p.From.Reg = REG_SP
		p.To.Type = obj.TYPE_REG
		p.To.Reg = REG_BP
	}

	if autoffset%int32(ctxt.Arch.RegSize) != 0 {
		ctxt.Diag("unaligned stack size %d", autoffset)
	}

	// localoffset is autoffset discounting the frame pointer,
	// which has already been allocated in the stack.
	localoffset := autoffset - int32(bpsize)
	if localoffset != 0 {
		p = obj.Appendp(p, newprog)
		p.As = AADJSP
		p.From.Type = obj.TYPE_CONST
		p.From.Offset = int64(localoffset)
		p.Spadj = localoffset
	}

	// Delve debugger would like the next instruction to be noted as the end of the function prologue.
	// TODO: are there other cases (e.g., wrapper functions) that need marking?
	if autoffset != 0 {
		p.Pos = p.Pos.WithXlogue(src.PosPrologueEnd)
	}

	var deltasp int32
	for p = cursym.Func().Text; p != nil; p = p.Link {
		pcsize := ctxt.Arch.RegSize
		switch p.From.Name {
		case obj.NAME_AUTO:
			p.From.Offset += int64(deltasp) - int64(bpsize)
		case obj.NAME_PARAM:
			p.From.Offset += int64(deltasp) + int64(pcsize)
		}
		if p.GetFrom3() != nil {
			switch p.GetFrom3().Name {
			case obj.NAME_AUTO:
				p.GetFrom3().Offset += int64(deltasp) - int64(bpsize)
			case obj.NAME_PARAM:
				p.GetFrom3().Offset += int64(deltasp) + int64(pcsize)
			}
		}
		switch p.To.Name {
		case obj.NAME_AUTO:
			p.To.Offset += int64(deltasp) - int64(bpsize)
		case obj.NAME_PARAM:
			p.To.Offset += int64(deltasp) + int64(pcsize)
		}

		switch p.As {
		default:
			if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_SP && p.As != ACMPL && p.As != ACMPQ {
				f := cursym.Func()
				if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
					f.FuncFlag |= abi.FuncFlagSPWrite
					if ctxt.Debugvlog || !ctxt.IsAsm {
						ctxt.Logf("auto-SPWRITE: %s %v\n", cursym.Name, p)
						if !ctxt.IsAsm {
							ctxt.Diag("invalid auto-SPWRITE in non-assembly")
							ctxt.DiagFlush()
							log.Fatalf("bad SPWRITE")
						}
					}
				}
			}
			continue

		case APUSHL, APUSHFL:
			deltasp += 4
			p.Spadj = 4
			continue

		case APUSHQ, APUSHFQ:
			deltasp += 8
			p.Spadj = 8
			continue

		case APUSHW, APUSHFW:
			deltasp += 2
			p.Spadj = 2
			continue

		case APOPL, APOPFL:
			deltasp -= 4
			p.Spadj = -4
			continue

		case APOPQ, APOPFQ:
			deltasp -= 8
			p.Spadj = -8
			continue

		case APOPW, APOPFW:
			deltasp -= 2
			p.Spadj = -2
			continue

		case AADJSP:
			p.Spadj = int32(p.From.Offset)
			deltasp += int32(p.From.Offset)
			continue

		case obj.ARET:
			// do nothing
		}

		if autoffset != deltasp {
			ctxt.Diag("%s: unbalanced PUSH/POP", cursym)
		}

		if autoffset != 0 {
			to := p.To // Keep To attached to RET for retjmp below
			p.To = obj.Addr{}
			if localoffset != 0 {
				p.As = AADJSP
				p.From.Type = obj.TYPE_CONST
				p.From.Offset = int64(-localoffset)
				p.Spadj = -localoffset
				p = obj.Appendp(p, newprog)
			}

			if bpsize > 0 {
				// Restore caller's BP
				p.As = APOPQ
				p.To.Type = obj.TYPE_REG
				p.To.Reg = REG_BP
				p.Spadj = -int32(bpsize)
				p = obj.Appendp(p, newprog)
			}

			p.As = obj.ARET
			p.To = to

			// If there are instructions following
			// this ARET, they come from a branch
			// with the same stackframe, so undo
			// the cleanup.
			p.Spadj = +autoffset
		}

		if p.As == obj.ARET && (p.To.Sym != nil || p.To.Type == obj.TYPE_REG) { // retjmp
			p.As = obj.AJMP
		}
	}
}

func isZeroArgRuntimeCall(s *obj.LSym) bool {
	if s == nil {
		return false
	}
	switch s.Name {
	case "runtime.panicdivide", "runtime.panicwrap", "runtime.panicshift", "runtime.panicBounds", "runtime.panicExtend":
		return true
	}
	return false
}

// loadG ensures the G is loaded into a register (either CX or REGG),
// appending instructions to p if necessary. It returns the new last
// instruction and the G register.
func loadG(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc) (*obj.Prog, int16) {
	if ctxt.Arch.Family == sys.AMD64 && cursym.ABI() == obj.ABIInternal {
		// Use the G register directly in ABIInternal
		return p, REGG
	}

	var regg int16 = REG_CX
	if ctxt.Arch.Family == sys.AMD64 {
		regg = REGG // == REG_R14
	}

	p = obj.Appendp(p, newprog)
	p.As = AMOVQ
	if ctxt.Arch.PtrSize == 4 {
		p.As = AMOVL
	}
	p.From.Type = obj.TYPE_MEM
	p.From.Reg = REG_TLS
	p.From.Offset = 0
	p.To.Type = obj.TYPE_REG
	p.To.Reg = regg

	// Rewrite TLS instruction if necessary.
	next := p.Link
	progedit(ctxt, p, newprog)
	for p.Link != next {
		p = p.Link
		progedit(ctxt, p, newprog)
	}

	if p.From.Index == REG_TLS {
		p.From.Scale = 2
	}

	return p, regg
}

// Append code to p to check for stack split.
// Appends to (does not overwrite) p.
// Assumes g is in rg.
// Returns last new instruction.
func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32) *obj.Prog {
	cmp := ACMPQ
	lea := ALEAQ
	mov := AMOVQ
	sub := ASUBQ
	push, pop := APUSHQ, APOPQ

	if ctxt.Arch.Family == sys.I386 {
		cmp = ACMPL
		lea = ALEAL
		mov = AMOVL
		sub = ASUBL
		push, pop = APUSHL, APOPL
	}

	tmp := int16(REG_AX) // use AX for 32-bit
	if ctxt.Arch.Family == sys.AMD64 {
		// Avoid register parameters.
		tmp = int16(REGENTRYTMP0)
	}

	if ctxt.Flag_maymorestack != "" {
		p = cursym.Func().SpillRegisterArgs(p, newprog)

		if cursym.Func().Text.From.Sym.NeedCtxt() {
			p = obj.Appendp(p, newprog)
			p.As = push
			p.From.Type = obj.TYPE_REG
			p.From.Reg = REGCTXT
		}

		// We call maymorestack with an ABI matching the
		// caller's ABI. Since this is the first thing that
		// happens in the function, we have to be consistent
		// with the caller about CPU state (notably,
		// fixed-meaning registers).

		p = obj.Appendp(p, newprog)
		p.As = obj.ACALL
		p.To.Type = obj.TYPE_BRANCH
		p.To.Name = obj.NAME_EXTERN
		p.To.Sym = ctxt.LookupABI(ctxt.Flag_maymorestack, cursym.ABI())

		if cursym.Func().Text.From.Sym.NeedCtxt() {
			p = obj.Appendp(p, newprog)
			p.As = pop
			p.To.Type = obj.TYPE_REG
			p.To.Reg = REGCTXT
		}

		p = cursym.Func().UnspillRegisterArgs(p, newprog)
	}

	// Jump back to here after morestack returns.
	startPred := p

	// Load G register
	var rg int16
	p, rg = loadG(ctxt, cursym, p, newprog)

	var q1 *obj.Prog
	if framesize <= abi.StackSmall {
		// small stack: SP <= stackguard
		//	CMPQ SP, stackguard
		p = obj.Appendp(p, newprog)

		p.As = cmp
		p.From.Type = obj.TYPE_REG
		p.From.Reg = REG_SP
		p.To.Type = obj.TYPE_MEM
		p.To.Reg = rg
		p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
		if cursym.CFunc() {
			p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
		}

		// Mark the stack bound check and morestack call async nonpreemptible.
		// If we get preempted here, when resumed the preemption request is
		// cleared, but we'll still call morestack, which will double the stack
		// unnecessarily. See issue #35470.
		p = ctxt.StartUnsafePoint(p, newprog)
	} else if framesize <= abi.StackBig {
		// large stack: SP-framesize <= stackguard-StackSmall
		//	LEAQ -xxx(SP), tmp
		//	CMPQ tmp, stackguard
		p = obj.Appendp(p, newprog)

		p.As = lea
		p.From.Type = obj.TYPE_MEM
		p.From.Reg = REG_SP
		p.From.Offset = -(int64(framesize) - abi.StackSmall)
		p.To.Type = obj.TYPE_REG
		p.To.Reg = tmp

		p = obj.Appendp(p, newprog)
		p.As = cmp
		p.From.Type = obj.TYPE_REG
		p.From.Reg = tmp
		p.To.Type = obj.TYPE_MEM
		p.To.Reg = rg
		p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
		if cursym.CFunc() {
			p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
		}

		p = ctxt.StartUnsafePoint(p, newprog) // see the comment above
	} else {
		// Such a large stack we need to protect against underflow.
		// The runtime guarantees SP > objabi.StackBig, but
		// framesize is large enough that SP-framesize may
		// underflow, causing a direct comparison with the
		// stack guard to incorrectly succeed. We explicitly
		// guard against underflow.
		//
		//	MOVQ	SP, tmp
		//	SUBQ	$(framesize - StackSmall), tmp
		//	// If subtraction wrapped (carry set), morestack.
		//	JCS	label-of-call-to-morestack
		//	CMPQ	tmp, stackguard

		p = obj.Appendp(p, newprog)

		p.As = mov
		p.From.Type = obj.TYPE_REG
		p.From.Reg = REG_SP
		p.To.Type = obj.TYPE_REG
		p.To.Reg = tmp

		p = ctxt.StartUnsafePoint(p, newprog) // see the comment above

		p = obj.Appendp(p, newprog)
		p.As = sub
		p.From.Type = obj.TYPE_CONST
		p.From.Offset = int64(framesize) - abi.StackSmall
		p.To.Type = obj.TYPE_REG
		p.To.Reg = tmp

		p = obj.Appendp(p, newprog)
		p.As = AJCS
		p.To.Type = obj.TYPE_BRANCH
		q1 = p

		p = obj.Appendp(p, newprog)
		p.As = cmp
		p.From.Type = obj.TYPE_REG
		p.From.Reg = tmp
		p.To.Type = obj.TYPE_MEM
		p.To.Reg = rg
		p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
		if cursym.CFunc() {
			p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
		}
	}

	// common
	jls := obj.Appendp(p, newprog)
	jls.As = AJLS
	jls.To.Type = obj.TYPE_BRANCH

	end := ctxt.EndUnsafePoint(jls, newprog, -1)

	var last *obj.Prog
	for last = cursym.Func().Text; last.Link != nil; last = last.Link {
	}

	// Now we are at the end of the function, but logically
	// we are still in function prologue. We need to fix the
	// SP data and PCDATA.
	spfix := obj.Appendp(last, newprog)
	spfix.As = obj.ANOP
	spfix.Spadj = -framesize

	pcdata := ctxt.EmitEntryStackMap(cursym, spfix, newprog)
	spill := ctxt.StartUnsafePoint(pcdata, newprog)
	pcdata = cursym.Func().SpillRegisterArgs(spill, newprog)

	call := obj.Appendp(pcdata, newprog)
	call.Pos = cursym.Func().Text.Pos
	call.As = obj.ACALL
	call.To.Type = obj.TYPE_BRANCH
	call.To.Name = obj.NAME_EXTERN
	morestack := "runtime.morestack"
	switch {
	case cursym.CFunc():
		morestack = "runtime.morestackc"
	case !cursym.Func().Text.From.Sym.NeedCtxt():
		morestack = "runtime.morestack_noctxt"
	}
	call.To.Sym = ctxt.Lookup(morestack)
	// When compiling 386 code for dynamic linking, the call needs to be adjusted
	// to follow PIC rules. This in turn can insert more instructions, so we need
	// to keep track of the start of the call (where the jump will be to) and the
	// end (which following instructions are appended to).
	callend := call
	progedit(ctxt, callend, newprog)
	for ; callend.Link != nil; callend = callend.Link {
		progedit(ctxt, callend.Link, newprog)
	}

	// The instructions which unspill regs should be preemptible.
	pcdata = ctxt.EndUnsafePoint(callend, newprog, -1)
	unspill := cursym.Func().UnspillRegisterArgs(pcdata, newprog)

	jmp := obj.Appendp(unspill, newprog)
	jmp.As = obj.AJMP
	jmp.To.Type = obj.TYPE_BRANCH
	jmp.To.SetTarget(startPred.Link)
	jmp.Spadj = +framesize

	jls.To.SetTarget(spill)
	if q1 != nil {
		q1.To.SetTarget(spill)
	}

	return end
}

func isR15(r int16) bool {
	return r == REG_R15 || r == REG_R15B
}
func addrMentionsR15(a *obj.Addr) bool {
	if a == nil {
		return false
	}
	return isR15(a.Reg) || isR15(a.Index)
}
func progMentionsR15(p *obj.Prog) bool {
	return addrMentionsR15(&p.From) || addrMentionsR15(&p.To) || isR15(p.Reg) || addrMentionsR15(p.GetFrom3())
}

func addrUsesGlobal(a *obj.Addr) bool {
	if a == nil {
		return false
	}
	return a.Name == obj.NAME_EXTERN && !a.Sym.Local()
}
func progUsesGlobal(p *obj.Prog) bool {
	if p.As == obj.ACALL || p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ARET || p.As == obj.AJMP {
		// These opcodes don't use a GOT to access their argument (see rewriteToUseGot),
		// or R15 would be dead at them anyway.
		return false
	}
	if p.As == ALEAQ {
		// The GOT entry is placed directly in the destination register; R15 is not used.
		return false
	}
	return addrUsesGlobal(&p.From) || addrUsesGlobal(&p.To) || addrUsesGlobal(p.GetFrom3())
}

type rwMask int

const (
	readFrom rwMask = 1 << iota
	readTo
	readReg
	readFrom3
	writeFrom
	writeTo
	writeReg
	writeFrom3
)

// progRW returns a mask describing the effects of the instruction p.
// Note: this isn't exhaustively accurate. It is only currently used for detecting
// reads/writes to R15, so SSE register behavior isn't fully correct, and
// other weird cases (e.g. writes to DX by CLD) also aren't captured.
func progRW(p *obj.Prog) rwMask {
	var m rwMask
	// Default for most instructions
	if p.From.Type != obj.TYPE_NONE {
		m |= readFrom
	}
	if p.To.Type != obj.TYPE_NONE {
		// Most x86 instructions update the To value
		m |= readTo | writeTo
	}
	if p.Reg != 0 {
		m |= readReg
	}
	if p.GetFrom3() != nil {
		m |= readFrom3
	}

	// Lots of exceptions to the above defaults.
	name := p.As.String()
	if strings.HasPrefix(name, "MOV") || strings.HasPrefix(name, "PMOV") {
		// MOV instructions don't read To.
		m &^= readTo
	}
	switch p.As {
	case APOPW, APOPL, APOPQ,
		ALEAL, ALEAQ,
		AIMUL3W, AIMUL3L, AIMUL3Q,
		APEXTRB, APEXTRW, APEXTRD, APEXTRQ, AVPEXTRB, AVPEXTRW, AVPEXTRD, AVPEXTRQ, AEXTRACTPS,
		ABSFW, ABSFL, ABSFQ, ABSRW, ABSRL, ABSRQ, APOPCNTW, APOPCNTL, APOPCNTQ, ALZCNTW, ALZCNTL, ALZCNTQ,
		ASHLXL, ASHLXQ, ASHRXL, ASHRXQ, ASARXL, ASARXQ:
		// These instructions are pure writes to To. They don't use its old value.
		m &^= readTo
	case AXORL, AXORQ:
		// Register-clearing idiom doesn't read previous value.
		if p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_REG && p.From.Reg == p.To.Reg {
			m &^= readFrom | readTo
		}
	case AMULXL, AMULXQ:
		// These are write-only to both To and From3.
		m &^= readTo | readFrom3
		m |= writeFrom3
	}
	return m
}

// progReadsR15 reports whether p reads the register R15.
func progReadsR15(p *obj.Prog) bool {
	m := progRW(p)
	if m&readFrom != 0 && p.From.Type == obj.TYPE_REG && isR15(p.From.Reg) {
		return true
	}
	if m&readTo != 0 && p.To.Type == obj.TYPE_REG && isR15(p.To.Reg) {
		return true
	}
	if m&readReg != 0 && isR15(p.Reg) {
		return true
	}
	if m&readFrom3 != 0 && p.GetFrom3().Type == obj.TYPE_REG && isR15(p.GetFrom3().Reg) {
		return true
	}
	// reads of the index registers
	if p.From.Type == obj.TYPE_MEM && (isR15(p.From.Reg) || isR15(p.From.Index)) {
		return true
	}
	if p.To.Type == obj.TYPE_MEM && (isR15(p.To.Reg) || isR15(p.To.Index)) {
		return true
	}
	if f3 := p.GetFrom3(); f3 != nil && f3.Type == obj.TYPE_MEM && (isR15(f3.Reg) || isR15(f3.Index)) {
		return true
	}
	return false
}

// progWritesR15 reports whether p writes the register R15.
func progWritesR15(p *obj.Prog) bool {
	m := progRW(p)
	if m&writeFrom != 0 && p.From.Type == obj.TYPE_REG && isR15(p.From.Reg) {
		return true
	}
	if m&writeTo != 0 && p.To.Type == obj.TYPE_REG && isR15(p.To.Reg) {
		return true
	}
	if m&writeReg != 0 && isR15(p.Reg) {
		return true
	}
	if m&writeFrom3 != 0 && p.GetFrom3().Type == obj.TYPE_REG && isR15(p.GetFrom3().Reg) {
		return true
	}
	return false
}

func errorCheck(ctxt *obj.Link, s *obj.LSym) {
	// When dynamic linking, R15 is used to access globals. Reject code that
	// uses R15 after a global variable access.
	if !ctxt.Flag_dynlink {
		return
	}

	// Flood fill all the instructions where R15's value is junk.
	// If there are any uses of R15 in that set, report an error.
	var work []*obj.Prog
	var mentionsR15 bool
	for p := s.Func().Text; p != nil; p = p.Link {
		if progUsesGlobal(p) {
			work = append(work, p)
			p.Mark |= markBit
		}
		if progMentionsR15(p) {
			mentionsR15 = true
		}
	}
	if mentionsR15 {
		for len(work) > 0 {
			p := work[len(work)-1]
			work = work[:len(work)-1]
			if progReadsR15(p) {
				pos := ctxt.PosTable.Pos(p.Pos)
				ctxt.Diag("%s:%s: when dynamic linking, R15 is clobbered by a global variable access and is used here: %v", path.Base(pos.Filename()), pos.LineNumber(), p)
				break // only report one error
			}
			if progWritesR15(p) {
				// R15 is overwritten by this instruction. Its value is not junk any more.
				continue
			}
			if q := p.To.Target(); q != nil && q.Mark&markBit == 0 {
				q.Mark |= markBit
				work = append(work, q)
			}
			if p.As == obj.AJMP || p.As == obj.ARET {
				continue // no fallthrough
			}
			if q := p.Link; q != nil && q.Mark&markBit == 0 {
				q.Mark |= markBit
				work = append(work, q)
			}
		}
	}

	// Clean up.
	for p := s.Func().Text; p != nil; p = p.Link {
		p.Mark &^= markBit
	}
}

var unaryDst = map[obj.As]bool{
	ABSWAPL:     true,
	ABSWAPQ:     true,
	ACLDEMOTE:   true,
	ACLFLUSH:    true,
	ACLFLUSHOPT: true,
	ACLWB:       true,
	ACMPXCHG16B: true,
	ACMPXCHG8B:  true,
	ADECB:       true,
	ADECL:       true,
	ADECQ:       true,
	ADECW:       true,
	AFBSTP:      true,
	AFFREE:      true,
	AFLDENV:     true,
	AFSAVE:      true,
	AFSTCW:      true,
	AFSTENV:     true,
	AFSTSW:      true,
	AFXSAVE64:   true,
	AFXSAVE:     true,
	AINCB:       true,
	AINCL:       true,
	AINCQ:       true,
	AINCW:       true,
	ANEGB:       true,
	ANEGL:       true,
	ANEGQ:       true,
	ANEGW:       true,
	ANOTB:       true,
	ANOTL:       true,
	ANOTQ:       true,
	ANOTW:       true,
	APOPL:       true,
	APOPQ:       true,
	APOPW:       true,
	ARDFSBASEL:  true,
	ARDFSBASEQ:  true,
	ARDGSBASEL:  true,
	ARDGSBASEQ:  true,
	ARDPID:      true,
	ARDRANDL:    true,
	ARDRANDQ:    true,
	ARDRANDW:    true,
	ARDSEEDL:    true,
	ARDSEEDQ:    true,
	ARDSEEDW:    true,
	ASETCC:      true,
	ASETCS:      true,
	ASETEQ:      true,
	ASETGE:      true,
	ASETGT:      true,
	ASETHI:      true,
	ASETLE:      true,
	ASETLS:      true,
	ASETLT:      true,
	ASETMI:      true,
	ASETNE:      true,
	ASETOC:      true,
	ASETOS:      true,
	ASETPC:      true,
	ASETPL:      true,
	ASETPS:      true,
	ASGDT:       true,
	ASIDT:       true,
	ASLDTL:      true,
	ASLDTQ:      true,
	ASLDTW:      true,
	ASMSWL:      true,
	ASMSWQ:      true,
	ASMSWW:      true,
	ASTMXCSR:    true,
	ASTRL:       true,
	ASTRQ:       true,
	ASTRW:       true,
	AXSAVE64:    true,
	AXSAVE:      true,
	AXSAVEC64:   true,
	AXSAVEC:     true,
	AXSAVEOPT64: true,
	AXSAVEOPT:   true,
	AXSAVES64:   true,
	AXSAVES:     true,
}

var Linkamd64 = obj.LinkArch{
	Arch:           sys.ArchAMD64,
	Init:           instinit,
	ErrorCheck:     errorCheck,
	Preprocess:     preprocess,
	Assemble:       span6,
	Progedit:       progedit,
	SEH:            populateSeh,
	UnaryDst:       unaryDst,
	DWARFRegisters: AMD64DWARFRegisters,
}

var Link386 = obj.LinkArch{
	Arch:           sys.Arch386,
	Init:           instinit,
	Preprocess:     preprocess,
	Assemble:       span6,
	Progedit:       progedit,
	UnaryDst:       unaryDst,
	DWARFRegisters: X86DWARFRegisters,
}
