common

package
v0.0.0-...-4cc5765 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2022 License: MPL-2.0 Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	Invalid = Kind(reflect.Invalid)
	Bool    = Kind(reflect.Bool)
	Int     = Kind(reflect.Int)
	Int8    = Kind(reflect.Int8)
	Int16   = Kind(reflect.Int16)
	Int32   = Kind(reflect.Int32)
	Int64   = Kind(reflect.Int64)
	Uint    = Kind(reflect.Uint)
	Uint8   = Kind(reflect.Uint8)
	Uint16  = Kind(reflect.Uint16)
	Uint32  = Kind(reflect.Uint32)
	Uint64  = Kind(reflect.Uint64)
	Uintptr = Kind(reflect.Uintptr)
	Float32 = Kind(reflect.Float32)
	Float64 = Kind(reflect.Float64)
	Ptr     = Kind(reflect.Ptr)
	KLo     = Bool
	KHi     = Ptr
)
View Source
const (
	BAD = Op0(token.ILLEGAL)   // invalid instruction, guaranteed to signal exception
	NOP = Op0(token.SEMICOLON) // somewhat arbitrary choice
	RET = Op0(token.RETURN)
)
View Source
const (
	ZERO = Op1(token.DEFAULT) // somewhat arbitrary choice
	INC  = Op1(token.INC)     // ++
	DEC  = Op1(token.DEC)     // --
	NEG1 = Op1(token.VAR + 1) // - // avoid conflict between NEG2 and SUB2
	NOT1 = Op1(token.VAR + 2) // ^ // avoid conflict between NOT2 and XOR2
	JMP  = Op1(token.GOTO)
)
View Source
const (
	ADD2 = Op2(token.ADD)
	SUB2 = Op2(token.SUB)
	ADC2 = Op2(token.ADD + token.VAR) // add with carry
	SBB2 = Op2(token.SUB + token.VAR) // subtract with borrow
	MUL2 = Op2(token.MUL)
	DIV2 = Op2(token.QUO) // divide
	QUO2 = DIV2           // alias for DIV
	REM2 = Op2(token.REM) // remainder

	AND2     = Op2(token.AND)
	OR2      = Op2(token.OR)
	XOR2     = Op2(token.XOR)
	SHL2     = Op2(token.SHL)
	SHR2     = Op2(token.SHR)
	AND_NOT2 = Op2(token.AND_NOT)
	LAND2    = Op2(token.LAND) // &&
	LOR2     = Op2(token.LOR)  // ||

	MOV  = Op2(token.ASSIGN) // =
	CAST = Op2(token.TYPE)   // somewhat arbitrary choice

	LEA2 = Op2(token.ARROW) // amd64 only. somewhat arbitrary choice
	// XCHG = ??
	// two-arg versions of NOT1, NEG1 above
	NEG2  = Op2(NEG1)
	NOT2  = Op2(NOT1)
	JMPIF = Op2(JMP)
)
View Source
const (
	ADD3 = Op3(ADD2)
	SUB3 = Op3(SUB2)
	ADC3 = Op3(ADC2)
	SBB3 = Op3(SBB2)
	MUL3 = Op3(MUL2)
	DIV3 = Op3(DIV2)
	REM3 = Op3(REM2)

	AND3     = Op3(AND2)
	OR3      = Op3(OR2)
	XOR3     = Op3(XOR2)
	SHL3     = Op3(SHL2)
	SHR3     = Op3(SHR2)
	AND_NOT3 = Op3(AND_NOT2)
	LAND3    = Op3(LAND2)
	LOR3     = Op3(LOR2)

	GETIDX = Op3(token.LBRACK) // a[b] -> val
	SETIDX = Op3(token.RBRACK) // a[b] <- val
)
View Source
const (
	ALLOC Op1Misc = 0x01 // allocate soft register
	FREE  Op1Misc = 0x02 // free soft register

	PUSH Op2Misc = 0x20
	POP  Op2Misc = 0x21
)
View Source
const (
	FirstSoftRegId = 0x000000
	LastSoftRegId  = 0x7FFFFF
	FirstTempRegId = 0x800000
	LastTempRegId  = 0xFFFFFF
)
View Source
const (
	InvalidSlot = ^SaveSlot(0)
)
View Source
const (
	LEA4 = Op4(LEA2) // amd64 only
)
View Source
const (
	MMAP_SUPPORTED = true
)
View Source
const MMAP_VERBOSE = false

Variables

View Source
var Archs = make(map[ArchId]Arch) // {ARM64:Arm64{}, AMD64:Amd64{}}

Functions

func Log2Uint

func Log2Uint(n uint64) (uint8, bool)

compute base-2 logarithm of integer n. return 0, false if argument is not a power of 2 used to optimize multiplication by a constant power of two.

Types

type Arch

type Arch interface {
	Id() ArchId
	String() string
	RegIdConfig() RegIdConfig
	RegIdValid(id RegId) bool
	RegIdKind(id RegId) Kind     // uint64 or float64
	RegIdString(id RegId) string // RegId -> string
	RegValid(r Reg) bool
	RegString(r Reg) string          // Reg -> string
	MemString(m Mem) string          // Mem -> string
	CodeString(c MachineCode) string // Code -> string

	Init(asm *Asm, saveStart, saveEnd SaveSlot) *Asm
	Prologue(asm *Asm) *Asm
	Epilogue(asm *Asm) *Asm

	Op0(asm *Asm, op Op0) *Asm
	Op1(asm *Asm, op Op1, dst Arg) *Asm
	Op2(asm *Asm, op Op2, src Arg, dst Arg) *Asm
	Op3(asm *Asm, op Op3, a Arg, b Arg, dst Arg) *Asm
	Op4(asm *Asm, op Op4, a Arg, b Arg, c Arg, dst Arg) *Asm
}

type ArchId

type ArchId uint8
const (
	NOARCH ArchId = iota
	ARM64
	AMD64
)

func (ArchId) String

func (archId ArchId) String() string

type Arg

type Arg interface {
	RegId() RegId // register used by Arg, or NoReg if Arg is Const
	Kind() Kind
	Const() bool
	// contains filtered or unexported methods
}

argument of assembly instructions

type Asm

type Asm struct {
	// contains filtered or unexported fields
}

func New

func New(id ArchId) *Asm

func NewArch

func NewArch(arch Arch) *Asm

func (*Asm) AddJump

func (asm *Asm) AddJump(dst uintptr) *Asm

mark the last assembled 32 bits as a relative jump destination to be set to 'dst'

func (*Asm) Alloc

func (asm *Asm) Alloc(s SoftReg) Arg

allocate a SoftRegId

func (*Asm) Arch

func (asm *Asm) Arch() Arch

func (*Asm) ArchId

func (asm *Asm) ArchId() ArchId

func (*Asm) Arg

func (asm *Asm) Arg(x AsmCode) Arg

convert AsmCode to Arg

func (*Asm) Assemble

func (asm *Asm) Assemble(args ...AsmCode) *Asm

func (*Asm) Byte

func (asm *Asm) Byte(b byte) *Asm

func (*Asm) Bytes

func (asm *Asm) Bytes(bytes ...byte) *Asm

func (*Asm) Cast

func (asm *Asm) Cast(src Arg, dst Arg) *Asm

func (*Asm) ClearCode

func (asm *Asm) ClearCode() *Asm

func (*Asm) ClearRegs

func (asm *Asm) ClearRegs() *Asm

forget all allocated registers

func (*Asm) Code

func (asm *Asm) Code() MachineCode

func (*Asm) Epilogue

func (asm *Asm) Epilogue() *Asm

func (*Asm) Free

func (asm *Asm) Free(s SoftReg)

func (*Asm) Func

func (asm *Asm) Func(funcaddr interface{})

*

  • convert code created by the programmer to a callable function.
  • funcaddr must be a non-nil pointer to function. *
  • function type MUST match the code created by the programmer,
  • or BAD things will happen: crash, memory corruption, undefined behaviour... *
  • Obviously, code created by the programmer must be for the same architecture
  • the program is currently running on... *
  • implemented as Asm.Mmap() + Asm.MemToFunc()

func (*Asm) InitArch

func (asm *Asm) InitArch(arch Arch) *Asm

func (*Asm) InitArch2

func (asm *Asm) InitArch2(arch Arch, saveStart SaveSlot, saveEnd SaveSlot) *Asm

func (*Asm) InitArchId

func (asm *Asm) InitArchId(archId ArchId) *Asm

func (*Asm) InitArchId2

func (asm *Asm) InitArchId2(archId ArchId, saveStart SaveSlot, saveEnd SaveSlot) *Asm

func (*Asm) Int16

func (asm *Asm) Int16(val int16) *Asm

func (*Asm) Int32

func (asm *Asm) Int32(val int32) *Asm

func (*Asm) Int64

func (asm *Asm) Int64(val int64) *Asm

func (*Asm) Int8

func (asm *Asm) Int8(val int8) *Asm
func (asm *Asm) Link(address uintptr)

now that final destination of machine code is known, fill jumps to absolute destinations

func (*Asm) Load

func (asm *Asm) Load(src Mem, dst Reg) *Asm

func (*Asm) MemToFunc

func (asm *Asm) MemToFunc(funcaddr interface{}, mem MemArea)

*

  • convert code created by the programmer to a callable function. *
  • funcaddr must be a non-nil pointer to function,
  • and area must have been returned by Asm.Mmap() *
  • function type MUST match the code created by the programmer,
  • or BAD things will happen: crash, memory corruption, undefined behaviour... *
  • Obviously, code created by the programmer must be for the same architecture
  • the program is currently running on... *
  • used to implement Asm.Func()

func (*Asm) Mmap

func (asm *Asm) Mmap() MemArea

return a MemArea with executable machine code equal to asm.Code(). Also calls asm.link()

func (*Asm) Mov

func (asm *Asm) Mov(src Arg, dst Arg) *Asm

func (*Asm) Op

func (asm *Asm) Op(args ...AsmCode) int

func (*Asm) Op0

func (asm *Asm) Op0(op Op0) *Asm

func (*Asm) Op1

func (asm *Asm) Op1(op Op1, dst Arg) *Asm

func (*Asm) Op1Misc

func (asm *Asm) Op1Misc(op Op1Misc, arg1 AsmCode) *Asm

func (*Asm) Op2

func (asm *Asm) Op2(op Op2, src Arg, dst Arg) *Asm

func (*Asm) Op2Misc

func (asm *Asm) Op2Misc(op Op2Misc, arg1 AsmCode, arg2 AsmCode) *Asm

func (*Asm) Op3

func (asm *Asm) Op3(op Op3, a Arg, b Arg, dst Arg) *Asm

func (*Asm) Op4

func (asm *Asm) Op4(op Op4, a Arg, b Arg, c Arg, dst Arg) *Asm

func (*Asm) Optimize2

func (asm *Asm) Optimize2(op Op2, src Arg, dst Arg) bool

func (*Asm) Optimize3

func (asm *Asm) Optimize3(op Op3, a Arg, b Arg, dst Arg) bool

func (*Asm) Pop

func (asm *Asm) Pop(r Reg, index *SaveSlot) *Asm

func (*Asm) Prologue

func (asm *Asm) Prologue() *Asm

func (*Asm) Push

func (asm *Asm) Push(r Reg, index *SaveSlot) *Asm

func (*Asm) RegAlloc

func (asm *Asm) RegAlloc(kind Kind) Reg

func (*Asm) RegDecUse

func (asm *Asm) RegDecUse(id RegId) uint32

return new use count

func (*Asm) RegFree

func (asm *Asm) RegFree(r Reg) *Asm

func (*Asm) RegIdConfig

func (asm *Asm) RegIdConfig() RegIdConfig

func (*Asm) RegIncUse

func (asm *Asm) RegIncUse(id RegId) uint32

return new use count

func (*Asm) RegIsUsed

func (asm *Asm) RegIsUsed(id RegId) bool

func (*Asm) Store

func (asm *Asm) Store(src Reg, dst Mem) *Asm

func (*Asm) TryRegAlloc

func (asm *Asm) TryRegAlloc(kind Kind) Reg

func (*Asm) Uint16

func (asm *Asm) Uint16(val uint16) *Asm

func (*Asm) Uint32

func (asm *Asm) Uint32(val uint32) *Asm

func (*Asm) Uint64

func (asm *Asm) Uint64(val uint64) *Asm

func (*Asm) Uint8

func (asm *Asm) Uint8(val uint8) *Asm

func (*Asm) Zero

func (asm *Asm) Zero(dst Arg) *Asm

type AsmCode

type AsmCode interface {
	// contains filtered or unexported methods
}

symbolic assembly code: instruction or its arguments

type Cache

type Cache map[int]map[uint32][]MemArea

map[len][crc32c][array of]executable machine code

func (Cache) Add

func (cache Cache) Add(area MemArea)

func (Cache) Lookup

func (cache Cache) Lookup(area MemArea) MemArea

type Const

type Const struct {
	// contains filtered or unexported fields
}

func ConstInt

func ConstInt(val int) Const

func ConstInt16

func ConstInt16(val int16) Const

func ConstInt32

func ConstInt32(val int32) Const

func ConstInt64

func ConstInt64(val int64) Const

func ConstInt8

func ConstInt8(val int8) Const

func ConstInterface

func ConstInterface(ival interface{}, t reflect.Type) (Const, error)

func ConstPointer

func ConstPointer(val *uint8) Const

guaranteed to work only if val points to non-Go memory, as for example C/C++ memory

func ConstUint

func ConstUint(val uint) Const

func ConstUint16

func ConstUint16(val uint16) Const

func ConstUint32

func ConstUint32(val uint32) Const

func ConstUint64

func ConstUint64(val uint64) Const

func ConstUint8

func ConstUint8(val uint8) Const

func ConstUintptr

func ConstUintptr(val uintptr) Const

func MakeConst

func MakeConst(val int64, kind Kind) Const

func (Const) Cast

func (c Const) Cast(to Kind) Const

convert Const to a different kind

func (Const) Const

func (c Const) Const() bool

func (Const) Kind

func (c Const) Kind() Kind

func (Const) RegId

func (c Const) RegId() RegId

implement Arg interface

func (Const) String

func (c Const) String() string

func (Const) Val

func (c Const) Val() int64

type Expr

type Expr interface {
	Kind() Kind
	Const() bool
}

subset of Arg interface

type Kind

type Kind uint8 // narrow version of reflect.Kind

func (Kind) IsFloat

func (k Kind) IsFloat() bool

func (Kind) Signed

func (k Kind) Signed() bool

func (Kind) Size

func (k Kind) Size() Size

func (Kind) String

func (k Kind) String() string

type MachineCode

type MachineCode struct {
	ArchId ArchId
	Bytes  []uint8
}

assembled machine code. Executable if compiled for the same architecture the program is running on - see Asm.Func()

func (MachineCode) Equal

func (code MachineCode) Equal(other MachineCode) bool

func (MachineCode) MemArea

func (code MachineCode) MemArea() MemArea

convert MachineCode to MemArea

func (MachineCode) String

func (code MachineCode) String() string

type Mem

type Mem struct {
	// contains filtered or unexported fields
}

hardware memory location.

func MakeMem

func MakeMem(off int32, id RegId, kind Kind) Mem

func (Mem) Const

func (m Mem) Const() bool

func (Mem) Kind

func (m Mem) Kind() Kind

func (Mem) Offset

func (m Mem) Offset() int32

func (Mem) RegId

func (m Mem) RegId() RegId

implement Arg interface

func (Mem) String

func (m Mem) String() string

type MemArea

type MemArea []byte

func (MemArea) Checksum

func (area MemArea) Checksum() uint32

func (MemArea) Equal

func (area MemArea) Equal(other MemArea) bool

func (MemArea) Size

func (area MemArea) Size() int

type MemPool

type MemPool struct {
	// contains filtered or unexported fields
}

func NewMemPool

func NewMemPool(size int) *MemPool

func (*MemPool) Addr

func (pool *MemPool) Addr() *uint8

func (*MemPool) Copy

func (pool *MemPool) Copy(area MemArea) MemArea

func (*MemPool) SetReadWrite

func (pool *MemPool) SetReadWrite()

func (*MemPool) SetReadonly

func (pool *MemPool) SetReadonly()

func (*MemPool) Size

func (pool *MemPool) Size() int

type Op0

type Op0 uint8

============================================================================ no-arg instruction

func (Op0) String

func (op Op0) String() string

type Op1

type Op1 uint8

============================================================================ one-arg instruction

func (Op1) String

func (op Op1) String() string

type Op1Misc

type Op1Misc uint8

func (Op1Misc) String

func (op Op1Misc) String() string

type Op2

type Op2 uint8

============================================================================ two-arg instruction

func (Op2) String

func (op Op2) String() string

type Op2Misc

type Op2Misc uint8

func (Op2Misc) String

func (op Op2Misc) String() string

type Op3

type Op3 uint8

============================================================================ three-arg instruction

func (Op3) IsCommutative

func (op Op3) IsCommutative() bool

func (Op3) String

func (op Op3) String() string

type Op4

type Op4 uint8

============================================================================ four-arg instruction

func (Op4) String

func (op Op4) String() string

type Reg

type Reg struct {
	// contains filtered or unexported fields
}

register + kind

func MakeReg

func MakeReg(id RegId, kind Kind) Reg

func (Reg) Const

func (r Reg) Const() bool

func (Reg) Kind

func (r Reg) Kind() Kind

func (Reg) RegId

func (r Reg) RegId() RegId

implement Arg interface

func (Reg) String

func (r Reg) String() string

func (Reg) Valid

func (r Reg) Valid() bool

func (Reg) Validate

func (r Reg) Validate()

type RegId

type RegId uint16

machine register

const (
	NoRegId RegId = 0
)

func (RegId) Arch

func (id RegId) Arch() Arch

func (RegId) ArchId

func (id RegId) ArchId() ArchId

func (RegId) Kind

func (id RegId) Kind() Kind

func (RegId) String

func (id RegId) String() string

func (RegId) Valid

func (id RegId) Valid() bool

func (RegId) Validate

func (id RegId) Validate()

type RegIdConfig

type RegIdConfig struct {
	RLo, RHi, RSP, RVAR RegId
	/**
	 * first RegId to allocate.
	 * subsequent allocations will return progressively higher registers,
	 * eventually reach RHi, wrap around to RLo, and finally reach
	 * RAllocFirst again when all registers are allocated.
	 *
	 * used on amd64 to allocate RAX, RCX and RBX as last
	 * because some assembly instructions (shift, division)
	 * are hardcoded to use them
	 */
	RAllocFirst RegId
}

type RegIds

type RegIds struct {
	// contains filtered or unexported fields
}

func (*RegIds) Copy

func (rs *RegIds) Copy(other *RegIds)

func (*RegIds) DecUse

func (rs *RegIds) DecUse(id RegId) uint32

return new use count

func (*RegIds) Free

func (rs *RegIds) Free(id RegId)

func (*RegIds) IncUse

func (rs *RegIds) IncUse(id RegId) uint32

return new use count

func (*RegIds) IsUsed

func (rs *RegIds) IsUsed(id RegId) bool

func (*RegIds) Next

func (rs *RegIds) Next(id RegId) RegId

return the RegId immediately after id, wrapping around after RHi. returned RegId may be used or not valid: it is caller's responsibility to check for valid and unused registers

func (*RegIds) TryAlloc

func (rs *RegIds) TryAlloc(kind Kind) RegId

type Save

type Save struct {
	// contains filtered or unexported fields
}

memory area where spill registers can be saved

func (*Save) Alloc

func (s *Save) Alloc() SaveSlot

find a free slot and return it. return InvalidIndex on failure

func (*Save) Free

func (s *Save) Free(idx SaveSlot)

free a slot.

func (*Save) Valid

func (s *Save) Valid(idx SaveSlot) bool

validate a slot

func (*Save) Validate

func (s *Save) Validate(idx SaveSlot)

validate a slot

type SaveSlot

type SaveSlot uint16

type Size

type Size uint8 // 1, 2, 4 or 8

func SizeOf

func SizeOf(e Expr) Size

type SoftReg

type SoftReg uint32

soft register. may be mapped by assembler to an actual machine register or to a memory location

func MakeSoftReg

func MakeSoftReg(id SoftRegId, kind Kind) SoftReg

func (SoftReg) Arg

func (s SoftReg) Arg(asm *Asm) Arg

use Asm to convert softreg to Reg or Mem

func (SoftReg) Const

func (s SoftReg) Const() bool

implement jit.Expr interface

func (SoftReg) Id

func (s SoftReg) Id() SoftRegId

func (SoftReg) IsTemp

func (s SoftReg) IsTemp() bool

func (SoftReg) Kind

func (s SoftReg) Kind() Kind

func (SoftReg) RegId

func (s SoftReg) RegId(asm *Asm) RegId

func (SoftReg) String

func (s SoftReg) String() string

func (SoftReg) Valid

func (s SoftReg) Valid() bool

func (SoftReg) Validate

func (s SoftReg) Validate()

type SoftRegId

type SoftRegId uint32

soft register id. 24 bits wide.

func (SoftRegId) String

func (s SoftRegId) String() string

func (SoftRegId) Validate

func (s SoftRegId) Validate()

type SoftRegs

type SoftRegs map[SoftRegId]regIdOrMem

func (SoftRegs) Arg

func (softRegs SoftRegs) Arg(s SoftReg) Arg

func (SoftRegs) RegId

func (softRegs SoftRegs) RegId(s SoftReg) RegId

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL