Documentation ¶
Index ¶
- Constants
- Variables
- func Log2Uint(n uint64) (uint8, bool)
- type Arch
- type ArchId
- type Arg
- type Asm
- func (asm *Asm) AddJump(dst uintptr) *Asm
- func (asm *Asm) Alloc(s SoftReg) Arg
- func (asm *Asm) Arch() Arch
- func (asm *Asm) ArchId() ArchId
- func (asm *Asm) Arg(x AsmCode) Arg
- func (asm *Asm) Assemble(args ...AsmCode) *Asm
- func (asm *Asm) Byte(b byte) *Asm
- func (asm *Asm) Bytes(bytes ...byte) *Asm
- func (asm *Asm) Cast(src Arg, dst Arg) *Asm
- func (asm *Asm) ClearCode() *Asm
- func (asm *Asm) ClearRegs() *Asm
- func (asm *Asm) Code() MachineCode
- func (asm *Asm) Epilogue() *Asm
- func (asm *Asm) Free(s SoftReg)
- func (asm *Asm) Func(funcaddr interface{})
- func (asm *Asm) InitArch(arch Arch) *Asm
- func (asm *Asm) InitArch2(arch Arch, saveStart SaveSlot, saveEnd SaveSlot) *Asm
- func (asm *Asm) InitArchId(archId ArchId) *Asm
- func (asm *Asm) InitArchId2(archId ArchId, saveStart SaveSlot, saveEnd SaveSlot) *Asm
- func (asm *Asm) Int16(val int16) *Asm
- func (asm *Asm) Int32(val int32) *Asm
- func (asm *Asm) Int64(val int64) *Asm
- func (asm *Asm) Int8(val int8) *Asm
- func (asm *Asm) Link(address uintptr)
- func (asm *Asm) Load(src Mem, dst Reg) *Asm
- func (asm *Asm) MemToFunc(funcaddr interface{}, mem MemArea)
- func (asm *Asm) Mmap() MemArea
- func (asm *Asm) Mov(src Arg, dst Arg) *Asm
- func (asm *Asm) Op(args ...AsmCode) int
- func (asm *Asm) Op0(op Op0) *Asm
- func (asm *Asm) Op1(op Op1, dst Arg) *Asm
- func (asm *Asm) Op1Misc(op Op1Misc, arg1 AsmCode) *Asm
- func (asm *Asm) Op2(op Op2, src Arg, dst Arg) *Asm
- func (asm *Asm) Op2Misc(op Op2Misc, arg1 AsmCode, arg2 AsmCode) *Asm
- func (asm *Asm) Op3(op Op3, a Arg, b Arg, dst Arg) *Asm
- func (asm *Asm) Op4(op Op4, a Arg, b Arg, c Arg, dst Arg) *Asm
- func (asm *Asm) Optimize2(op Op2, src Arg, dst Arg) bool
- func (asm *Asm) Optimize3(op Op3, a Arg, b Arg, dst Arg) bool
- func (asm *Asm) Pop(r Reg, index *SaveSlot) *Asm
- func (asm *Asm) Prologue() *Asm
- func (asm *Asm) Push(r Reg, index *SaveSlot) *Asm
- func (asm *Asm) RegAlloc(kind Kind) Reg
- func (asm *Asm) RegDecUse(id RegId) uint32
- func (asm *Asm) RegFree(r Reg) *Asm
- func (asm *Asm) RegIdConfig() RegIdConfig
- func (asm *Asm) RegIncUse(id RegId) uint32
- func (asm *Asm) RegIsUsed(id RegId) bool
- func (asm *Asm) Store(src Reg, dst Mem) *Asm
- func (asm *Asm) TryRegAlloc(kind Kind) Reg
- func (asm *Asm) Uint16(val uint16) *Asm
- func (asm *Asm) Uint32(val uint32) *Asm
- func (asm *Asm) Uint64(val uint64) *Asm
- func (asm *Asm) Uint8(val uint8) *Asm
- func (asm *Asm) Zero(dst Arg) *Asm
- type AsmCode
- type Cache
- type Const
- func ConstInt(val int) Const
- func ConstInt16(val int16) Const
- func ConstInt32(val int32) Const
- func ConstInt64(val int64) Const
- func ConstInt8(val int8) Const
- func ConstInterface(ival interface{}, t reflect.Type) (Const, error)
- func ConstPointer(val *uint8) Const
- func ConstUint(val uint) Const
- func ConstUint16(val uint16) Const
- func ConstUint32(val uint32) Const
- func ConstUint64(val uint64) Const
- func ConstUint8(val uint8) Const
- func ConstUintptr(val uintptr) Const
- func MakeConst(val int64, kind Kind) Const
- type Expr
- type Kind
- type MachineCode
- type Mem
- type MemArea
- type MemPool
- type Op0
- type Op1
- type Op1Misc
- type Op2
- type Op2Misc
- type Op3
- type Op4
- type Reg
- type RegId
- type RegIdConfig
- type RegIds
- type Save
- type SaveSlot
- type Size
- type SoftReg
- type SoftRegId
- type SoftRegs
Constants ¶
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 )
const ( BAD = Op0(token.ILLEGAL) // invalid instruction, guaranteed to signal exception NOP = Op0(token.SEMICOLON) // somewhat arbitrary choice RET = Op0(token.RETURN) )
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) )
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) )
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 )
const ( ALLOC Op1Misc = 0x01 // allocate soft register FREE Op1Misc = 0x02 // free soft register PUSH Op2Misc = 0x20 POP Op2Misc = 0x21 )
const ( FirstSoftRegId = 0x000000 LastSoftRegId = 0x7FFFFF FirstTempRegId = 0x800000 LastTempRegId = 0xFFFFFF )
const (
InvalidSlot = ^SaveSlot(0)
)
const (
LEA4 = Op4(LEA2) // amd64 only
)
const (
MMAP_SUPPORTED = true
)
const MMAP_VERBOSE = false
Variables ¶
var Archs = make(map[ArchId]Arch) // {ARM64:Arm64{}, AMD64:Amd64{}}
Functions ¶
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 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 (*Asm) AddJump ¶
mark the last assembled 32 bits as a relative jump destination to be set to 'dst'
func (*Asm) Code ¶
func (asm *Asm) Code() MachineCode
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) InitArchId ¶
func (*Asm) InitArchId2 ¶
func (*Asm) Link ¶
now that final destination of machine code is known, fill jumps to absolute destinations
func (*Asm) MemToFunc ¶
*
- 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 ¶
return a MemArea with executable machine code equal to asm.Code(). Also calls asm.link()
func (*Asm) RegIdConfig ¶
func (asm *Asm) RegIdConfig() RegIdConfig
func (*Asm) TryRegAlloc ¶
type AsmCode ¶
type AsmCode interface {
// contains filtered or unexported methods
}
symbolic assembly code: instruction or its arguments
type Const ¶
type Const struct {
// contains filtered or unexported fields
}
func ConstInt16 ¶
func ConstInt32 ¶
func ConstInt64 ¶
func ConstPointer ¶
guaranteed to work only if val points to non-Go memory, as for example C/C++ memory
func ConstUint16 ¶
func ConstUint32 ¶
func ConstUint64 ¶
func ConstUint8 ¶
func ConstUintptr ¶
type MachineCode ¶
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 MemPool ¶
type MemPool struct {
// contains filtered or unexported fields
}
func NewMemPool ¶
func (*MemPool) SetReadWrite ¶
func (pool *MemPool) SetReadWrite()
func (*MemPool) SetReadonly ¶
func (pool *MemPool) SetReadonly()
type Op0 ¶
type Op0 uint8
============================================================================ no-arg instruction
type Op1 ¶
type Op1 uint8
============================================================================ one-arg instruction
type Op2 ¶
type Op2 uint8
============================================================================ two-arg instruction
type Op3 ¶
type Op3 uint8
============================================================================ three-arg instruction
func (Op3) IsCommutative ¶
type Op4 ¶
type Op4 uint8
============================================================================ four-arg instruction
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
}
type Save ¶
type Save struct {
// contains filtered or unexported fields
}
memory area where spill registers can be saved
type SoftReg ¶
type SoftReg uint32
soft register. may be mapped by assembler to an actual machine register or to a memory location