0
0
forked from toolshed/abra

chore: go mod vendor / tidy

This commit is contained in:
2025-01-03 20:21:06 +01:00
parent a379b31a19
commit b9f2d1f568
182 changed files with 184390 additions and 209 deletions

282
vendor/github.com/mmcloughlin/avo/operand/checks.go generated vendored Normal file
View File

@ -0,0 +1,282 @@
package operand
import "github.com/mmcloughlin/avo/reg"
// Pure type assertion checks:
// IsRegister returns whether op has type reg.Register.
func IsRegister(op Op) bool { _, ok := op.(reg.Register); return ok }
// IsMem returns whether op has type Mem.
func IsMem(op Op) bool { _, ok := op.(Mem); return ok }
// IsRel returns whether op has type Rel.
func IsRel(op Op) bool { _, ok := op.(Rel); return ok }
// Checks corresponding to specific operand types in the Intel Manual:
// Is1 returns true if op is the immediate constant 1.
func Is1(op Op) bool {
i, ok := op.(U8)
return ok && i == 1
}
// Is3 returns true if op is the immediate constant 3.
func Is3(op Op) bool {
i, ok := op.(U8)
return ok && i == 3
}
// IsIMM2U returns true if op is a 2-bit unsigned immediate (less than 4).
func IsIMM2U(op Op) bool {
i, ok := op.(U8)
return ok && i < 4
}
// IsIMM8 returns true is op is an 8-bit immediate.
func IsIMM8(op Op) bool {
_, uok := op.(U8)
_, iok := op.(I8)
return uok || iok
}
// IsIMM16 returns true is op is a 16-bit immediate.
func IsIMM16(op Op) bool {
_, uok := op.(U16)
_, iok := op.(I16)
return uok || iok
}
// IsIMM32 returns true is op is a 32-bit immediate.
func IsIMM32(op Op) bool {
_, uok := op.(U32)
_, iok := op.(I32)
return uok || iok
}
// IsIMM64 returns true is op is a 64-bit immediate.
func IsIMM64(op Op) bool {
_, uok := op.(U64)
_, iok := op.(I64)
return uok || iok
}
// IsAL returns true if op is the AL register.
func IsAL(op Op) bool {
return op == reg.AL
}
// IsCL returns true if op is the CL register.
func IsCL(op Op) bool {
return op == reg.CL
}
// IsAX returns true if op is the 16-bit AX register.
func IsAX(op Op) bool {
return op == reg.AX
}
// IsEAX returns true if op is the 32-bit EAX register.
func IsEAX(op Op) bool {
return op == reg.EAX
}
// IsRAX returns true if op is the 64-bit RAX register.
func IsRAX(op Op) bool {
return op == reg.RAX
}
// IsR8 returns true if op is an 8-bit general-purpose register.
func IsR8(op Op) bool {
return IsGP(op, 1)
}
// IsR16 returns true if op is a 16-bit general-purpose register.
func IsR16(op Op) bool {
return IsGP(op, 2)
}
// IsR32 returns true if op is a 32-bit general-purpose register.
func IsR32(op Op) bool {
return IsGP(op, 4)
}
// IsR64 returns true if op is a 64-bit general-purpose register.
func IsR64(op Op) bool {
return IsGP(op, 8)
}
// IsPseudo returns true if op is a pseudo register.
func IsPseudo(op Op) bool {
return IsRegisterKind(op, reg.KindPseudo)
}
// IsGP returns true if op is a general-purpose register of size n bytes.
func IsGP(op Op, n uint) bool {
return IsRegisterKindSize(op, reg.KindGP, n)
}
// IsXMM0 returns true if op is the X0 register.
func IsXMM0(op Op) bool {
return op == reg.X0
}
// IsXMM returns true if op is a 128-bit XMM register.
func IsXMM(op Op) bool {
return IsRegisterKindSize(op, reg.KindVector, 16)
}
// IsYMM returns true if op is a 256-bit YMM register.
func IsYMM(op Op) bool {
return IsRegisterKindSize(op, reg.KindVector, 32)
}
// IsZMM returns true if op is a 512-bit ZMM register.
func IsZMM(op Op) bool {
return IsRegisterKindSize(op, reg.KindVector, 64)
}
// IsK returns true if op is an Opmask register.
func IsK(op Op) bool {
return IsRegisterKind(op, reg.KindOpmask)
}
// IsRegisterKindSize returns true if op is a register of the given kind and size in bytes.
func IsRegisterKindSize(op Op, k reg.Kind, n uint) bool {
r, ok := op.(reg.Register)
return ok && r.Kind() == k && r.Size() == n
}
// IsRegisterKind returns true if op is a register of the given kind.
func IsRegisterKind(op Op, k reg.Kind) bool {
r, ok := op.(reg.Register)
return ok && r.Kind() == k
}
// IsM returns true if op is a 16-, 32- or 64-bit memory operand.
func IsM(op Op) bool {
// TODO(mbm): confirm "m" check is defined correctly
// Intel manual: "A 16-, 32- or 64-bit operand in memory."
return IsM16(op) || IsM32(op) || IsM64(op)
}
// IsM8 returns true if op is an 8-bit memory operand.
func IsM8(op Op) bool {
// TODO(mbm): confirm "m8" check is defined correctly
// Intel manual: "A byte operand in memory, usually expressed as a variable or
// array name, but pointed to by the DS:(E)SI or ES:(E)DI registers. In 64-bit
// mode, it is pointed to by the RSI or RDI registers."
return IsMSize(op, 1)
}
// IsM16 returns true if op is a 16-bit memory operand.
func IsM16(op Op) bool {
return IsMSize(op, 2)
}
// IsM32 returns true if op is a 16-bit memory operand.
func IsM32(op Op) bool {
return IsMSize(op, 4)
}
// IsM64 returns true if op is a 64-bit memory operand.
func IsM64(op Op) bool {
return IsMSize(op, 8)
}
// IsMSize returns true if op is a memory operand using general-purpose address
// registers of the given size in bytes.
func IsMSize(op Op, n uint) bool {
// TODO(mbm): should memory operands have a size attribute as well?
// TODO(mbm): m8,m16,m32,m64 checks do not actually check size
m, ok := op.(Mem)
return ok && IsMReg(m.Base) && (m.Index == nil || IsMReg(m.Index))
}
// IsMReg returns true if op is a register that can be used in a memory operand.
func IsMReg(op Op) bool {
return IsPseudo(op) || IsRegisterKind(op, reg.KindGP)
}
// IsM128 returns true if op is a 128-bit memory operand.
func IsM128(op Op) bool {
// TODO(mbm): should "m128" be the same as "m64"?
return IsM64(op)
}
// IsM256 returns true if op is a 256-bit memory operand.
func IsM256(op Op) bool {
// TODO(mbm): should "m256" be the same as "m64"?
return IsM64(op)
}
// IsM512 returns true if op is a 512-bit memory operand.
func IsM512(op Op) bool {
// TODO(mbm): should "m512" be the same as "m64"?
return IsM64(op)
}
// IsVM32X returns true if op is a vector memory operand with 32-bit XMM index.
func IsVM32X(op Op) bool {
return IsVmx(op)
}
// IsVM64X returns true if op is a vector memory operand with 64-bit XMM index.
func IsVM64X(op Op) bool {
return IsVmx(op)
}
// IsVmx returns true if op is a vector memory operand with XMM index.
func IsVmx(op Op) bool {
return isvm(op, IsXMM)
}
// IsVM32Y returns true if op is a vector memory operand with 32-bit YMM index.
func IsVM32Y(op Op) bool {
return IsVmy(op)
}
// IsVM64Y returns true if op is a vector memory operand with 64-bit YMM index.
func IsVM64Y(op Op) bool {
return IsVmy(op)
}
// IsVmy returns true if op is a vector memory operand with YMM index.
func IsVmy(op Op) bool {
return isvm(op, IsYMM)
}
// IsVM32Z returns true if op is a vector memory operand with 32-bit ZMM index.
func IsVM32Z(op Op) bool {
return IsVmz(op)
}
// IsVM64Z returns true if op is a vector memory operand with 64-bit ZMM index.
func IsVM64Z(op Op) bool {
return IsVmz(op)
}
// IsVmz returns true if op is a vector memory operand with ZMM index.
func IsVmz(op Op) bool {
return isvm(op, IsZMM)
}
func isvm(op Op, idx func(Op) bool) bool {
m, ok := op.(Mem)
return ok && IsR64(m.Base) && idx(m.Index)
}
// IsREL8 returns true if op is an 8-bit offset relative to instruction pointer.
func IsREL8(op Op) bool {
r, ok := op.(Rel)
return ok && r == Rel(int8(r))
}
// IsREL32 returns true if op is an offset relative to instruction pointer, or a
// label reference.
func IsREL32(op Op) bool {
// TODO(mbm): should labels be considered separately?
_, rel := op.(Rel)
_, label := op.(LabelRef)
return rel || label
}

64
vendor/github.com/mmcloughlin/avo/operand/const.go generated vendored Normal file
View File

@ -0,0 +1,64 @@
package operand
import (
"fmt"
"strconv"
"strings"
)
// Constant represents a constant literal.
type Constant interface {
Op
Bytes() int
constant()
}
//go:generate go run make_const.go -output zconst.go
// Special cases for floating point string representation.
//
// Issue 387 pointed out that floating point values that happen to be integers
// need to have a decimal point to be parsed correctly.
// String returns a representation the 32-bit float which is guaranteed to be
// parsed as a floating point constant by the Go assembler.
func (f F32) String() string { return asmfloat(float64(f), 32) }
// String returns a representation the 64-bit float which is guaranteed to be
// parsed as a floating point constant by the Go assembler.
func (f F64) String() string { return asmfloat(float64(f), 64) }
// asmfloat represents x as a string such that the assembler scanner will always
// recognize it as a float. Specifically, ensure that when x is an integral
// value, the result will still have a decimal point.
func asmfloat(x float64, bits int) string {
s := strconv.FormatFloat(x, 'f', -1, bits)
if !strings.ContainsRune(s, '.') {
s += ".0"
}
return s
}
// String is a string constant.
type String string
// Asm returns an assembly syntax representation of the string s.
func (s String) Asm() string { return fmt.Sprintf("$%q", s) }
// Bytes returns the length of s.
func (s String) Bytes() int { return len(s) }
func (s String) constant() {}
// Imm returns an unsigned integer constant with size guessed from x.
func Imm(x uint64) Constant {
switch {
case uint64(uint8(x)) == x:
return U8(x)
case uint64(uint16(x)) == x:
return U16(x)
case uint64(uint32(x)) == x:
return U32(x)
}
return U64(x)
}

2
vendor/github.com/mmcloughlin/avo/operand/doc.go generated vendored Normal file
View File

@ -0,0 +1,2 @@
// Package operand provides types for instruction operands.
package operand

151
vendor/github.com/mmcloughlin/avo/operand/types.go generated vendored Normal file
View File

@ -0,0 +1,151 @@
package operand
import (
"fmt"
"github.com/mmcloughlin/avo/reg"
)
// Op is an operand.
type Op interface {
Asm() string
}
// Symbol represents a symbol name.
type Symbol struct {
Name string
Static bool // only visible in current source file
}
// NewStaticSymbol builds a static Symbol. Static symbols are only visible in the current source file.
func NewStaticSymbol(name string) Symbol {
return Symbol{Name: name, Static: true}
}
func (s Symbol) String() string {
n := s.Name
if s.Static {
n += "<>"
}
return n
}
// Mem represents a memory reference.
type Mem struct {
Symbol Symbol
Disp int
Base reg.Register
Index reg.Register
Scale uint8
}
// NewParamAddr is a convenience to build a Mem operand pointing to a function
// parameter, which is a named offset from the frame pointer pseudo register.
func NewParamAddr(name string, offset int) Mem {
return Mem{
Symbol: Symbol{
Name: name,
Static: false,
},
Disp: offset,
Base: reg.FramePointer,
}
}
// NewStackAddr returns a memory reference relative to the stack pointer.
func NewStackAddr(offset int) Mem {
return Mem{
Disp: offset,
Base: reg.StackPointer,
}
}
// NewDataAddr returns a memory reference relative to the named data symbol.
func NewDataAddr(sym Symbol, offset int) Mem {
return Mem{
Symbol: sym,
Disp: offset,
Base: reg.StaticBase,
}
}
// Offset returns a reference to m plus idx bytes.
func (m Mem) Offset(idx int) Mem {
a := m
a.Disp += idx
return a
}
// Idx returns a new memory reference with (Index, Scale) set to (r, s).
func (m Mem) Idx(r reg.Register, s uint8) Mem {
a := m
a.Index = r
a.Scale = s
return a
}
// Asm returns an assembly syntax representation of m.
func (m Mem) Asm() string {
a := m.Symbol.String()
if a != "" {
a += fmt.Sprintf("%+d", m.Disp)
} else if m.Disp != 0 {
a += fmt.Sprintf("%d", m.Disp)
}
if m.Base != nil {
a += fmt.Sprintf("(%s)", m.Base.Asm())
}
if m.Index != nil && m.Scale != 0 {
a += fmt.Sprintf("(%s*%d)", m.Index.Asm(), m.Scale)
}
return a
}
// Rel is an offset relative to the instruction pointer.
type Rel int32
// Asm returns an assembly syntax representation of r.
func (r Rel) Asm() string {
return fmt.Sprintf(".%+d", r)
}
// LabelRef is a reference to a label.
type LabelRef string
// Asm returns an assembly syntax representation of l.
func (l LabelRef) Asm() string {
return string(l)
}
// Registers returns the list of all operands involved in the given operand.
func Registers(op Op) []reg.Register {
switch op := op.(type) {
case reg.Register:
return []reg.Register{op}
case Mem:
var r []reg.Register
if op.Base != nil {
r = append(r, op.Base)
}
if op.Index != nil {
r = append(r, op.Index)
}
return r
case Constant, Rel, LabelRef:
return nil
}
panic("unknown operand type")
}
// ApplyAllocation returns an operand with allocated registers replaced. Registers missing from the allocation are left alone.
func ApplyAllocation(op Op, a reg.Allocation) Op {
switch op := op.(type) {
case reg.Register:
return a.LookupRegisterDefault(op)
case Mem:
op.Base = a.LookupRegisterDefault(op.Base)
op.Index = a.LookupRegisterDefault(op.Index)
return op
}
return op
}

75
vendor/github.com/mmcloughlin/avo/operand/zconst.go generated vendored Normal file
View File

@ -0,0 +1,75 @@
// Code generated by make_const.go. DO NOT EDIT.
package operand
import "fmt"
// I8 is a 8-bit signed integer constant.
type I8 int8
func (i I8) Asm() string { return fmt.Sprintf("$%+d", i) }
func (i I8) Bytes() int { return 1 }
func (i I8) constant() {}
// U8 is a 8-bit unsigned integer constant.
type U8 uint8
func (u U8) Asm() string { return fmt.Sprintf("$%#02x", u) }
func (u U8) Bytes() int { return 1 }
func (u U8) constant() {}
// I16 is a 16-bit signed integer constant.
type I16 int16
func (i I16) Asm() string { return fmt.Sprintf("$%+d", i) }
func (i I16) Bytes() int { return 2 }
func (i I16) constant() {}
// U16 is a 16-bit unsigned integer constant.
type U16 uint16
func (u U16) Asm() string { return fmt.Sprintf("$%#04x", u) }
func (u U16) Bytes() int { return 2 }
func (u U16) constant() {}
// F32 is a 32-bit floating point constant.
type F32 float32
func (f F32) Asm() string { return fmt.Sprintf("$(%s)", f) }
func (f F32) Bytes() int { return 4 }
func (f F32) constant() {}
// I32 is a 32-bit signed integer constant.
type I32 int32
func (i I32) Asm() string { return fmt.Sprintf("$%+d", i) }
func (i I32) Bytes() int { return 4 }
func (i I32) constant() {}
// U32 is a 32-bit unsigned integer constant.
type U32 uint32
func (u U32) Asm() string { return fmt.Sprintf("$%#08x", u) }
func (u U32) Bytes() int { return 4 }
func (u U32) constant() {}
// F64 is a 64-bit floating point constant.
type F64 float64
func (f F64) Asm() string { return fmt.Sprintf("$(%s)", f) }
func (f F64) Bytes() int { return 8 }
func (f F64) constant() {}
// I64 is a 64-bit signed integer constant.
type I64 int64
func (i I64) Asm() string { return fmt.Sprintf("$%+d", i) }
func (i I64) Bytes() int { return 8 }
func (i I64) constant() {}
// U64 is a 64-bit unsigned integer constant.
type U64 uint64
func (u U64) Asm() string { return fmt.Sprintf("$%#016x", u) }
func (u U64) Bytes() int { return 8 }
func (u U64) constant() {}