// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package obj

import (
	"bytes"
	"cmd/internal/objabi"
	"fmt"
	"internal/abi"
	"internal/buildcfg"
	"io"
	"strings"
)

const REG_NONE = 0

// Line returns a string containing the filename and line number for p
func (p *Prog) Line() string {
	return p.Ctxt.OutermostPos(p.Pos).Format(false, true)
}
func (p *Prog) InnermostLine(w io.Writer) {
	p.Ctxt.InnermostPos(p.Pos).WriteTo(w, false, true)
}

// InnermostLineNumber returns a string containing the line number for the
// innermost inlined function (if any inlining) at p's position
func (p *Prog) InnermostLineNumber() string {
	return p.Ctxt.InnermostPos(p.Pos).LineNumber()
}

// InnermostLineNumberHTML returns a string containing the line number for the
// innermost inlined function (if any inlining) at p's position
func (p *Prog) InnermostLineNumberHTML() string {
	return p.Ctxt.InnermostPos(p.Pos).LineNumberHTML()
}

// InnermostFilename returns a string containing the innermost
// (in inlining) filename at p's position
func (p *Prog) InnermostFilename() string {
	// TODO For now, this is only used for debugging output, and if we need more/better information, it might change.
	// An example of what we might want to see is the full stack of positions for inlined code, so we get some visibility into what is recorded there.
	pos := p.Ctxt.InnermostPos(p.Pos)
	if !pos.IsKnown() {
		return "<unknown file name>"
	}
	return pos.Filename()
}

var armCondCode = []string{
	".EQ",
	".NE",
	".CS",
	".CC",
	".MI",
	".PL",
	".VS",
	".VC",
	".HI",
	".LS",
	".GE",
	".LT",
	".GT",
	".LE",
	"",
	".NV",
}

/* ARM scond byte */
const (
	C_SCOND     = (1 << 4) - 1
	C_SBIT      = 1 << 4
	C_PBIT      = 1 << 5
	C_WBIT      = 1 << 6
	C_FBIT      = 1 << 7
	C_UBIT      = 1 << 7
	C_SCOND_XOR = 14
)

// CConv formats opcode suffix bits (Prog.Scond).
func CConv(s uint8) string {
	if s == 0 {
		return ""
	}
	for i := range opSuffixSpace {
		sset := &opSuffixSpace[i]
		if sset.arch == buildcfg.GOARCH {
			return sset.cconv(s)
		}
	}
	return fmt.Sprintf("SC???%d", s)
}

// CConvARM formats ARM opcode suffix bits (mostly condition codes).
func CConvARM(s uint8) string {
	// TODO: could be great to move suffix-related things into
	// ARM asm backends some day.
	// obj/x86 can be used as an example.

	sc := armCondCode[(s&C_SCOND)^C_SCOND_XOR]
	if s&C_SBIT != 0 {
		sc += ".S"
	}
	if s&C_PBIT != 0 {
		sc += ".P"
	}
	if s&C_WBIT != 0 {
		sc += ".W"
	}
	if s&C_UBIT != 0 { /* ambiguous with FBIT */
		sc += ".U"
	}
	return sc
}

func (p *Prog) String() string {
	if p == nil {
		return "<nil Prog>"
	}
	if p.Ctxt == nil {
		return "<Prog without ctxt>"
	}
	return fmt.Sprintf("%.5d (%v)\t%s", p.Pc, p.Line(), p.InstructionString())
}

func (p *Prog) InnermostString(w io.Writer) {
	if p == nil {
		io.WriteString(w, "<nil Prog>")
		return
	}
	if p.Ctxt == nil {
		io.WriteString(w, "<Prog without ctxt>")
		return
	}
	fmt.Fprintf(w, "%.5d (", p.Pc)
	p.InnermostLine(w)
	io.WriteString(w, ")\t")
	p.WriteInstructionString(w)
}

// InstructionString returns a string representation of the instruction without preceding
// program counter or file and line number.
func (p *Prog) InstructionString() string {
	buf := new(bytes.Buffer)
	p.WriteInstructionString(buf)
	return buf.String()
}

// WriteInstructionString writes a string representation of the instruction without preceding
// program counter or file and line number.
func (p *Prog) WriteInstructionString(w io.Writer) {
	if p == nil {
		io.WriteString(w, "<nil Prog>")
		return
	}

	if p.Ctxt == nil {
		io.WriteString(w, "<Prog without ctxt>")
		return
	}

	sc := CConv(p.Scond)

	io.WriteString(w, p.As.String())
	io.WriteString(w, sc)
	sep := "\t"

	if p.From.Type != TYPE_NONE {
		io.WriteString(w, sep)
		WriteDconv(w, p, &p.From)
		sep = ", "
	}
	if p.Reg != REG_NONE {
		// Should not happen but might as well show it if it does.
		fmt.Fprintf(w, "%s%v", sep, Rconv(int(p.Reg)))
		sep = ", "
	}
	for i := range p.RestArgs {
		if p.RestArgs[i].Pos == Source {
			io.WriteString(w, sep)
			WriteDconv(w, p, &p.RestArgs[i].Addr)
			sep = ", "
		}
	}

	if p.As == ATEXT {
		// If there are attributes, print them. Otherwise, skip the comma.
		// In short, print one of these two:
		// TEXT	foo(SB), DUPOK|NOSPLIT, $0
		// TEXT	foo(SB), $0
		s := p.From.Sym.TextAttrString()
		if s != "" {
			fmt.Fprintf(w, "%s%s", sep, s)
			sep = ", "
		}
	}
	if p.To.Type != TYPE_NONE {
		io.WriteString(w, sep)
		WriteDconv(w, p, &p.To)
		sep = ", "
	}
	if p.RegTo2 != REG_NONE {
		fmt.Fprintf(w, "%s%v", sep, Rconv(int(p.RegTo2)))
	}
	for i := range p.RestArgs {
		if p.RestArgs[i].Pos == Destination {
			io.WriteString(w, sep)
			WriteDconv(w, p, &p.RestArgs[i].Addr)
			sep = ", "
		}
	}
}

func (ctxt *Link) NewProg() *Prog {
	p := new(Prog)
	p.Ctxt = ctxt
	return p
}

func (ctxt *Link) CanReuseProgs() bool {
	return ctxt.Debugasm == 0
}

func isZReg(r int) bool {
	return (r >= RBaseARM64+96 && r <= RBaseARM64+127) ||
		(r >= RBaseARM64+2048 && r < RBaseARM64+3072)
}

// Dconv accepts an argument 'a' within a prog 'p' and returns a string
// with a formatted version of the argument.
func Dconv(p *Prog, a *Addr) string {
	buf := new(bytes.Buffer)
	writeDconv(buf, p, a, false)
	return buf.String()
}

// DconvWithABIDetail accepts an argument 'a' within a prog 'p'
// and returns a string with a formatted version of the argument, in
// which text symbols are rendered with explicit ABI selectors.
func DconvWithABIDetail(p *Prog, a *Addr) string {
	buf := new(bytes.Buffer)
	writeDconv(buf, p, a, true)
	return buf.String()
}

// WriteDconv accepts an argument 'a' within a prog 'p'
// and writes a formatted version of the arg to the writer.
func WriteDconv(w io.Writer, p *Prog, a *Addr) {
	writeDconv(w, p, a, false)
}

func writeDconv(w io.Writer, p *Prog, a *Addr, abiDetail bool) {
	switch a.Type {
	default:
		fmt.Fprintf(w, "type=%d", a.Type)

	case TYPE_NONE:
		if a.Name != NAME_NONE || a.Reg != 0 || a.Sym != nil {
			a.WriteNameTo(w)
			fmt.Fprintf(w, "(%v)(NONE)", Rconv(int(a.Reg)))
		}

	case TYPE_REG:
		if buildcfg.GOARCH == "arm64" && a.Offset&(int64(1)<<62) != 0 {
			preg := int((a.Offset)&31) + RBaseARM64 + 128
			arng2 := (a.Offset >> 5) & 15
			selreg := int((a.Offset>>9)&31) + RBaseARM64
			idximm := (a.Offset >> 14) & 63

			arngStr := ""
			switch arng2 {
			case 9:
				arngStr = ".B"
			case 10:
				arngStr = ".H"
			case 11:
				arngStr = ".S"
			case 12:
				arngStr = ".D"
			case 13:
				arngStr = ".Q"
			}

			fmt.Fprintf(w, "[%s,$%d](%s%s)", Rconv(selreg), idximm, Rconv(preg), arngStr)
			return
		}

		// TODO(rsc): This special case is for x86 instructions like
		//	PINSRQ	CX,$1,X6
		// where the $1 is included in the p->to Addr.
		// Move into a new field.
		if a.Offset != 0 && (a.Reg < RBaseARM64 || a.Reg >= RBaseMIPS) {
			fmt.Fprintf(w, "$%d,%v", a.Offset, Rconv(int(a.Reg)))
			return
		}

		if a.Name != NAME_NONE || a.Sym != nil {
			a.WriteNameTo(w)
			fmt.Fprintf(w, "(%v)(REG)", Rconv(int(a.Reg)))
		} else {
			io.WriteString(w, Rconv(int(a.Reg)))
		}

		if ((RBaseARM64+1<<10+1<<9) /* arm64.REG_ELEM */ <= a.Reg && a.Reg < (RBaseARM64+1<<11) /* arm64.REG_ZARNG */) ||
			((RBaseARM64+1<<11+1<<9) /* arm64.REG_ZARNGELEM */ <= a.Reg && a.Reg < (RBaseARM64+1<<11+1<<10+1<<9) /* arm64.REG_PARNGZM */) {
			fmt.Fprintf(w, "[%d]", a.Index)
		}

		if (RBaseLOONG64+(1<<10)+(1<<11)) /* loong64.REG_ELEM */ <= a.Reg &&
			a.Reg < (RBaseLOONG64+(1<<10)+(2<<11)) /* loong64.REG_ELEM_END */ {
			fmt.Fprintf(w, "[%d]", a.Index)
		}

	case TYPE_BRANCH:
		if a.Sym != nil {
			fmt.Fprintf(w, "%s%s(SB)", a.Sym.Name, abiDecorate(a, abiDetail))
		} else if a.Target() != nil {
			fmt.Fprint(w, a.Target().Pc)
		} else {
			fmt.Fprintf(w, "%d(PC)", a.Offset)
		}

	case TYPE_INDIR:
		io.WriteString(w, "*")
		a.writeNameTo(w, abiDetail)

	case TYPE_MEM:
		if buildcfg.GOARCH == "arm64" && (a.Scale < 0 || (a.Index != REG_NONE && (isZReg(int(a.Reg)) || isZReg(int(a.Index))))) {
			// SVE extended addressing pattern
			if a.Index == REG_NONE {
				if a.Offset < 0 {
					fmt.Fprintf(w, "(-VL*%d)(%v)", -a.Offset, Rconv(int(a.Reg)))
				} else {
					fmt.Fprintf(w, "(VL*%d)(%v)", a.Offset, Rconv(int(a.Reg)))
				}
			} else {
				amount := 0
				mod := 0
				if a.Scale < 0 {
					amount = int((a.Scale >> 12) & 0x7)
					mod = int((a.Scale >> 9) & 0x7)
				}
				modStr := ""
				switch mod {
				case 1:
					modStr = ".UXTW"
				case 2:
					modStr = ".SXTW"
				}
				amountStr := ""
				if amount != 0 {
					amountStr = fmt.Sprintf("<<%d", amount)
				}
				fmt.Fprintf(w, "(%v%s%s)(%v)", Rconv(int(a.Reg)), modStr, amountStr, Rconv(int(a.Index)))
			}
		} else {
			a.WriteNameTo(w)
			if a.Index != REG_NONE {
				if a.Scale == 0 {
					// arm64 shifted or extended register offset, scale = 0.
					fmt.Fprintf(w, "(%v)", Rconv(int(a.Index)))
				} else {
					fmt.Fprintf(w, "(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
				}
			}
		}

	case TYPE_CONST:
		io.WriteString(w, "$")
		a.WriteNameTo(w)
		if a.Reg != 0 {
			fmt.Fprintf(w, "(%v)", Rconv(int(a.Reg)))
		}

	case TYPE_TEXTSIZE:
		if a.Val.(int32) == abi.ArgsSizeUnknown {
			fmt.Fprintf(w, "$%d", a.Offset)
		} else {
			fmt.Fprintf(w, "$%d-%d", a.Offset, a.Val.(int32))
		}

	case TYPE_FCONST:
		str := fmt.Sprintf("%.17g", a.Val.(float64))
		// Make sure 1 prints as 1.0
		if !strings.ContainsAny(str, ".e") {
			str += ".0"
		}
		fmt.Fprintf(w, "$(%s)", str)

	case TYPE_SCONST:
		fmt.Fprintf(w, "$%q", a.Val.(string))

	case TYPE_ADDR:
		io.WriteString(w, "$")
		a.writeNameTo(w, abiDetail)

	case TYPE_SHIFT:
		v := int(a.Offset)
		ops := "<<>>->@>"
		switch buildcfg.GOARCH {
		case "arm":
			op := ops[((v>>5)&3)<<1:]
			if v&(1<<4) != 0 {
				fmt.Fprintf(w, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15)
			} else {
				fmt.Fprintf(w, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31)
			}
			if a.Reg != 0 {
				fmt.Fprintf(w, "(%v)", Rconv(int(a.Reg)))
			}
		case "arm64":
			op := ops[((v>>22)&3)<<1:]
			r := (v >> 16) & 31
			fmt.Fprintf(w, "%s%c%c%d", Rconv(r+RBaseARM64), op[0], op[1], (v>>10)&63)
		default:
			panic("TYPE_SHIFT is not supported on " + buildcfg.GOARCH)
		}

	case TYPE_REGREG:
		fmt.Fprintf(w, "(%v, %v)", Rconv(int(a.Reg)), Rconv(int(a.Offset)))

	case TYPE_REGREG2:
		fmt.Fprintf(w, "%v, %v", Rconv(int(a.Offset)), Rconv(int(a.Reg)))

	case TYPE_REGLIST:
		io.WriteString(w, RLconv(a.Offset))

	case TYPE_SPECIAL:
		io.WriteString(w, SPCconv(a.Offset))
	}
}

func (a *Addr) WriteNameTo(w io.Writer) {
	a.writeNameTo(w, false)
}

func (a *Addr) writeNameTo(w io.Writer, abiDetail bool) {

	switch a.Name {
	default:
		fmt.Fprintf(w, "name=%d", a.Name)

	case NAME_NONE:
		switch {
		case a.Reg == REG_NONE:
			fmt.Fprint(w, a.Offset)
		case a.Offset == 0:
			fmt.Fprintf(w, "(%v)", Rconv(int(a.Reg)))
		case a.Offset != 0:
			fmt.Fprintf(w, "%d(%v)", a.Offset, Rconv(int(a.Reg)))
		}

		// Note: a.Reg == REG_NONE encodes the default base register for the NAME_ type.
	case NAME_EXTERN:
		reg := "SB"
		if a.Reg != REG_NONE {
			reg = Rconv(int(a.Reg))
		}
		if a.Sym != nil {
			fmt.Fprintf(w, "%s%s%s(%s)", a.Sym.Name, abiDecorate(a, abiDetail), offConv(a.Offset), reg)
		} else {
			fmt.Fprintf(w, "%s(%s)", offConv(a.Offset), reg)
		}

	case NAME_GOTREF:
		reg := "SB"
		if a.Reg != REG_NONE {
			reg = Rconv(int(a.Reg))
		}
		if a.Sym != nil {
			fmt.Fprintf(w, "%s%s@GOT(%s)", a.Sym.Name, offConv(a.Offset), reg)
		} else {
			fmt.Fprintf(w, "%s@GOT(%s)", offConv(a.Offset), reg)
		}

	case NAME_STATIC:
		reg := "SB"
		if a.Reg != REG_NONE {
			reg = Rconv(int(a.Reg))
		}
		if a.Sym != nil {
			fmt.Fprintf(w, "%s<>%s(%s)", a.Sym.Name, offConv(a.Offset), reg)
		} else {
			fmt.Fprintf(w, "<>%s(%s)", offConv(a.Offset), reg)
		}

	case NAME_AUTO:
		reg := "SP"
		if a.Reg != REG_NONE {
			reg = Rconv(int(a.Reg))
		}
		if a.Sym != nil {
			fmt.Fprintf(w, "%s%s(%s)", a.Sym.Name, offConv(a.Offset), reg)
		} else {
			fmt.Fprintf(w, "%s(%s)", offConv(a.Offset), reg)
		}

	case NAME_PARAM:
		reg := "FP"
		if a.Reg != REG_NONE {
			reg = Rconv(int(a.Reg))
		}
		if a.Sym != nil {
			fmt.Fprintf(w, "%s%s(%s)", a.Sym.Name, offConv(a.Offset), reg)
		} else {
			fmt.Fprintf(w, "%s(%s)", offConv(a.Offset), reg)
		}
	case NAME_TOCREF:
		reg := "SB"
		if a.Reg != REG_NONE {
			reg = Rconv(int(a.Reg))
		}
		if a.Sym != nil {
			fmt.Fprintf(w, "%s%s(%s)", a.Sym.Name, offConv(a.Offset), reg)
		} else {
			fmt.Fprintf(w, "%s(%s)", offConv(a.Offset), reg)
		}
	}
}

func offConv(off int64) string {
	if off == 0 {
		return ""
	}
	return fmt.Sprintf("%+d", off)
}

// opSuffixSet is like regListSet, but for opcode suffixes.
//
// Unlike some other similar structures, uint8 space is not
// divided by its own values set (because there are only 256 of them).
// Instead, every arch may interpret/format all 8 bits as they like,
// as long as they register proper cconv function for it.
type opSuffixSet struct {
	arch  string
	cconv func(suffix uint8) string
}

var opSuffixSpace []opSuffixSet

// RegisterOpSuffix assigns cconv function for formatting opcode suffixes
// when compiling for GOARCH=arch.
//
// cconv is never called with 0 argument.
func RegisterOpSuffix(arch string, cconv func(uint8) string) {
	opSuffixSpace = append(opSuffixSpace, opSuffixSet{
		arch:  arch,
		cconv: cconv,
	})
}

type regSet struct {
	lo    int
	hi    int
	Rconv func(int) string
}

// Few enough architectures that a linear scan is fastest.
// Not even worth sorting.
var regSpace []regSet

/*
	Each architecture defines a register space as a unique
	integer range.
	Here is the list of architectures and the base of their register spaces.
*/

const (
	// Because of masking operations in the encodings, each register
	// space should start at 0 modulo some power of 2.
	RBase386     = 1 * 1024
	RBaseAMD64   = 2 * 1024
	RBaseARM     = 3 * 1024
	RBasePPC64   = 4 * 1024  // range [4k, 8k)
	RBaseARM64   = 8 * 1024  // range [8k, 18k)
	RBaseMIPS    = 18 * 1024 // range [18k, 19k)
	RBaseS390X   = 19 * 1024 // range [19k, 20k)
	RBaseRISCV   = 20 * 1024 // range [20k, 21k)
	RBaseWasm    = 21 * 1024
	RBaseLOONG64 = 22 * 1024 // range [22K, 25k)
)

// RegisterRegister binds a pretty-printer (Rconv) for register
// numbers to a given register number range. Lo is inclusive,
// hi exclusive (valid registers are lo through hi-1).
func RegisterRegister(lo, hi int, Rconv func(int) string) {
	regSpace = append(regSpace, regSet{lo, hi, Rconv})
}

func Rconv(reg int) string {
	if reg == REG_NONE {
		return "NONE"
	}
	for i := range regSpace {
		rs := &regSpace[i]
		if rs.lo <= reg && reg < rs.hi {
			return rs.Rconv(reg)
		}
	}
	return fmt.Sprintf("R???%d", reg)
}

type regListSet struct {
	lo     int64
	hi     int64
	RLconv func(int64) string
}

var regListSpace []regListSet

// Each architecture is allotted a distinct subspace: [Lo, Hi) for declaring its
// arch-specific register list numbers.
const (
	RegListARMLo = 0
	RegListARMHi = 1 << 16

	// arm64 uses the 60th bit to differentiate from other archs
	RegListARM64Lo = 1 << 60
	RegListARM64Hi = 1<<61 - 1

	// x86 uses the 61th bit to differentiate from other archs
	RegListX86Lo = 1 << 61
	RegListX86Hi = 1<<62 - 1
)

// RegisterRegisterList binds a pretty-printer (RLconv) for register list
// numbers to a given register list number range. Lo is inclusive,
// hi exclusive (valid register list are lo through hi-1).
func RegisterRegisterList(lo, hi int64, rlconv func(int64) string) {
	regListSpace = append(regListSpace, regListSet{lo, hi, rlconv})
}

func RLconv(list int64) string {
	for i := range regListSpace {
		rls := &regListSpace[i]
		if rls.lo <= list && list < rls.hi {
			return rls.RLconv(list)
		}
	}
	return fmt.Sprintf("RL???%d", list)
}

// Special operands
type spcSet struct {
	lo      int64
	hi      int64
	SPCconv func(int64) string
}

var spcSpace []spcSet

// Each architecture is allotted a distinct subspace: [Lo, Hi) for declaring its
// arch-specific special operands.
const (
	SpecialOperandARM64Base = 0 << 16
	SpecialOperandRISCVBase = 1 << 16
)

// RegisterSpecialOperands binds a pretty-printer (SPCconv) for special
// operand numbers to a given special operand number range. Lo is inclusive,
// hi is exclusive (valid special operands are lo through hi-1).
func RegisterSpecialOperands(lo, hi int64, rlconv func(int64) string) {
	spcSpace = append(spcSpace, spcSet{lo, hi, rlconv})
}

// SPCconv returns the string representation of the special operand spc.
func SPCconv(spc int64) string {
	for i := range spcSpace {
		spcs := &spcSpace[i]
		if spcs.lo <= spc && spc < spcs.hi {
			return spcs.SPCconv(spc)
		}
	}
	return fmt.Sprintf("SPC???%d", spc)
}

type opSet struct {
	lo    As
	names []string
}

// Not even worth sorting
var aSpace []opSet

// RegisterOpcode binds a list of instruction names
// to a given instruction number range.
func RegisterOpcode(lo As, Anames []string) {
	if len(Anames) > AllowedOpCodes {
		panic(fmt.Sprintf("too many instructions, have %d max %d", len(Anames), AllowedOpCodes))
	}
	aSpace = append(aSpace, opSet{lo, Anames})
}

func (a As) String() string {
	if 0 <= a && int(a) < len(Anames) {
		return Anames[a]
	}
	for i := range aSpace {
		as := &aSpace[i]
		if as.lo <= a && int(a-as.lo) < len(as.names) {
			return as.names[a-as.lo]
		}
	}
	return fmt.Sprintf("A???%d", a)
}

var Anames = []string{
	"XXX",
	"CALL",
	"DUFFCOPY",
	"DUFFZERO",
	"END",
	"FUNCDATA",
	"JMP",
	"NOP",
	"PCALIGN",
	"PCALIGNMAX",
	"PCDATA",
	"RET",
	"GETCALLERPC",
	"TEXT",
	"UNDEF",
}

func Bool2int(b bool) int {
	// The compiler currently only optimizes this form.
	// See issue 6011.
	var i int
	if b {
		i = 1
	} else {
		i = 0
	}
	return i
}

func abiDecorate(a *Addr, abiDetail bool) string {
	if !abiDetail || a.Sym == nil {
		return ""
	}
	return fmt.Sprintf("<%s>", a.Sym.ABI())
}

// AlignmentPadding bytes to add to align code as requested.
// Alignment is restricted to powers of 2 between 8 and 2048 inclusive.
//
// pc_: current offset in function, in bytes
// p:  a PCALIGN or PCALIGNMAX prog
// ctxt: the context, for current function
// cursym: current function being assembled
// returns number of bytes of padding needed,
// updates minimum alignment for the function.
func AlignmentPadding(pc int32, p *Prog, ctxt *Link, cursym *LSym) int {
	v := AlignmentPaddingLength(pc, p, ctxt)
	requireAlignment(p.From.Offset, ctxt, cursym)
	return v
}

// AlignmentPaddingLength is the number of bytes to add to align code as requested.
// Alignment is restricted to powers of 2 between 8 and 2048 inclusive.
// This only computes the length and does not update the (missing parameter)
// current function's own required alignment.
//
// pc: current offset in function, in bytes
// p:  a PCALIGN or PCALIGNMAX prog
// ctxt: the context, for current function
// returns number of bytes of padding needed,
func AlignmentPaddingLength(pc int32, p *Prog, ctxt *Link) int {
	a := p.From.Offset
	if !((a&(a-1) == 0) && 8 <= a && a <= 2048) {
		ctxt.Diag("alignment value of an instruction must be a power of two and in the range [8, 2048], got %d\n", a)
		return 0
	}
	pc64 := int64(pc)
	lob := pc64 & (a - 1) // Low Order Bits -- if not zero, then not aligned
	if p.As == APCALIGN {
		if lob != 0 {
			return int(a - lob)
		}
		return 0
	}
	// emit as many as s bytes of padding to obtain alignment
	s := p.To.Offset
	if s < 0 || s >= a {
		ctxt.Diag("PCALIGNMAX 'amount' %d must be non-negative and smaller than the alignment %d\n", s, a)
		return 0
	}
	if s >= a-lob {
		return int(a - lob)
	}
	return 0
}

// requireAlignment ensures that the function is aligned enough to support
// the required code alignment
func requireAlignment(a int64, ctxt *Link, cursym *LSym) {
	// TODO remove explicit knowledge about AIX.
	if ctxt.Headtype != objabi.Haix && cursym.Align < int16(a) {
		cursym.Align = int16(a)
	}
}
