asm_amd64

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

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

Go to latest
Published: Apr 20, 2022 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ConditionalRegisterStateE  = asm.ConditionalRegisterStateUnset + 1 + iota // ZF equal to zero
	ConditionalRegisterStateNE                                                //˜ZF not equal to zero
	ConditionalRegisterStateS                                                 // SF negative
	ConditionalRegisterStateNS                                                // ˜SF non-negative
	ConditionalRegisterStateG                                                 // ˜(SF xor OF) & ˜ ZF greater (signed >)
	ConditionalRegisterStateGE                                                // ˜(SF xor OF) greater or equal (signed >=)
	ConditionalRegisterStateL                                                 // SF xor OF less (signed <)
	ConditionalRegisterStateLE                                                // (SF xor OF) | ZF less or equal (signed <=)
	ConditionalRegisterStateA                                                 // ˜CF & ˜ZF above (unsigned >)
	ConditionalRegisterStateAE                                                // ˜CF above or equal (unsigned >=)
	ConditionalRegisterStateB                                                 // CF below (unsigned <)
	ConditionalRegisterStateBE                                                // CF | ZF below or equal (unsigned <=)
)

AMD64-specific conditional register states.

See https://www.lri.fr/~filliatr/ens/compil/x86-64.pdf See https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf

View Source
const (
	NONE asm.Instruction = iota
	ADDL
	ADDQ
	ADDSD
	ADDSS
	ANDL
	ANDPD
	ANDPS
	ANDQ
	BSRL
	BSRQ
	CDQ
	CMOVQCS
	CMPL
	CMPQ
	COMISD
	COMISS
	CQO
	CVTSD2SS
	CVTSL2SD
	CVTSL2SS
	CVTSQ2SD
	CVTSQ2SS
	CVTSS2SD
	CVTTSD2SL
	CVTTSD2SQ
	CVTTSS2SL
	CVTTSS2SQ
	DECQ
	DIVL
	DIVQ
	DIVSD
	DIVSS
	IDIVL
	IDIVQ
	INCQ
	JCC
	JCS
	JEQ
	JGE
	JGT
	JHI
	JLE
	JLS
	JLT
	JMI
	JNE
	JPC
	JPL
	JPS
	LEAQ
	LZCNTL
	LZCNTQ
	MAXSD
	MAXSS
	MINSD
	MINSS
	MOVB
	MOVBLSX
	MOVBLZX
	MOVBQSX
	MOVBQZX
	MOVL
	MOVLQSX
	MOVLQZX
	MOVQ
	MOVW
	MOVWLSX
	MOVWLZX
	MOVWQSX
	MOVWQZX
	MULL
	MULQ
	MULSD
	MULSS
	ORL
	ORPD
	ORPS
	ORQ
	POPCNTL
	POPCNTQ
	PSLLL
	PSLLQ
	PSRLL
	PSRLQ
	ROLL
	ROLQ
	RORL
	RORQ
	ROUNDSD
	ROUNDSS
	SARL
	SARQ
	SETCC
	SETCS
	SETEQ
	SETGE
	SETGT
	SETHI
	SETLE
	SETLS
	SETLT
	SETMI
	SETNE
	SETPC
	SETPL
	SETPS
	SHLL
	SHLQ
	SHRL
	SHRQ
	SQRTSD
	SQRTSS
	SUBL
	SUBQ
	SUBSD
	SUBSS
	TESTL
	TESTQ
	TZCNTL
	TZCNTQ
	UCOMISD
	UCOMISS
	XORL
	XORPD
	XORPS
	XORQ
	RET
	JMP
	NOP
	UD2
)

AMD64-specific instructions.

Note: This only defines amd64 instructions used by wazero's JIT compiler. Note: Naming conventions intentionally match the Go assembler: https://go.dev/doc/asm See https://www.felixcloutier.com/x86/index.html

View Source
const (
	REG_AX asm.Register = asm.NilRegister + 1 + iota
	REG_CX
	REG_DX
	REG_BX
	REG_SP
	REG_BP
	REG_SI
	REG_DI
	REG_R8
	REG_R9
	REG_R10
	REG_R11
	REG_R12
	REG_R13
	REG_R14
	REG_R15
	REG_X0
	REG_X1
	REG_X2
	REG_X3
	REG_X4
	REG_X5
	REG_X6
	REG_X7
	REG_X8
	REG_X9
	REG_X10
	REG_X11
	REG_X12
	REG_X13
	REG_X14
	REG_X15
)

Arm64-specific registers.

Note: naming convention intentionally matches the Go assembler: https://go.dev/doc/asm See https://www.lri.fr/~filliatr/ens/compil/x86-64.pdf See https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf

Variables

View Source
var (
	OperandTypesNoneToNone         = OperandTypes{OperandTypeNone, OperandTypeNone}
	OperandTypesNoneToRegister     = OperandTypes{OperandTypeNone, OperandTypeRegister}
	OperandTypesNoneToMemory       = OperandTypes{OperandTypeNone, OperandTypeMemory}
	OperandTypesNoneToBranch       = OperandTypes{OperandTypeNone, OperandTypeBranch}
	OperandTypesRegisterToNone     = OperandTypes{OperandTypeRegister, OperandTypeNone}
	OperandTypesRegisterToRegister = OperandTypes{OperandTypeRegister, OperandTypeRegister}
	OperandTypesRegisterToMemory   = OperandTypes{OperandTypeRegister, OperandTypeMemory}
	OperandTypesRegisterToConst    = OperandTypes{OperandTypeRegister, OperandTypeConst}
	OperandTypesMemoryToRegister   = OperandTypes{OperandTypeMemory, OperandTypeRegister}
	OperandTypesMemoryToConst      = OperandTypes{OperandTypeMemory, OperandTypeConst}
	OperandTypesConstToRegister    = OperandTypes{OperandTypeConst, OperandTypeRegister}
	OperandTypesConstToMemory      = OperandTypes{OperandTypeConst, OperandTypeMemory}
)
View Source
var RegisterToRegisterShiftOpcode = map[asm.Instruction]struct {
	opcode         []byte
	rPrefix        RexPrefix
	modRMExtension byte
}{

	ROLL: {/* contains filtered or unexported fields */},
	ROLQ: {/* contains filtered or unexported fields */},
	RORL: {/* contains filtered or unexported fields */},
	RORQ: {/* contains filtered or unexported fields */},

	SARL: {/* contains filtered or unexported fields */},
	SARQ: {/* contains filtered or unexported fields */},
	SHLL: {/* contains filtered or unexported fields */},
	SHLQ: {/* contains filtered or unexported fields */},
	SHRL: {/* contains filtered or unexported fields */},
	SHRQ: {/* contains filtered or unexported fields */},
}

Functions

func FitIn32bit

func FitIn32bit(v int64) bool

func InstructionName

func InstructionName(instruction asm.Instruction) string

func IsFloatRegister

func IsFloatRegister(r asm.Register) bool

func RegisterName

func RegisterName(reg asm.Register) string

Types

type Assembler

type Assembler interface {
	asm.AssemblerBase

	// CompileJumpToMemory adds jump-type instruction whose destination is stored in the memory address specified by `baseReg+offset`,
	// and returns the corresponding Node in the assembled linked list.
	CompileJumpToMemory(jmpInstruction asm.Instruction, baseReg asm.Register, offset asm.ConstantValue)

	// CompileRegisterToRegisterWithMode adds an instruction where source and destination
	// are `from` and `to` registers and the instruction's "Mode" is specified by `Mode`.
	CompileRegisterToRegisterWithMode(instruction asm.Instruction, from, to asm.Register, mode Mode)

	// CompileMemoryWithIndexToRegister adds an instruction where source operand is the memory address
	// specified as `srcBaseReg + srcOffsetConst + srcIndex*srcScale` and destination is the register `DstReg`.
	// Note: sourceScale must be one of 1, 2, 4, 8.
	CompileMemoryWithIndexToRegister(
		instruction asm.Instruction,
		srcBaseReg asm.Register,
		srcOffsetConst int64,
		srcIndex asm.Register,
		srcScale int16,
		dstReg asm.Register,
	)

	// CompileRegisterToMemoryWithIndex adds an instruction where source operand is the register `SrcReg`,
	// and the destination is the memory address specified as `dstBaseReg + dstOffsetConst + dstIndex*dstScale`
	// Note: dstScale must be one of 1, 2, 4, 8.
	CompileRegisterToMemoryWithIndex(
		instruction asm.Instruction,
		srcReg asm.Register,
		dstBaseReg asm.Register,
		dstOffsetConst int64,
		dstIndex asm.Register,
		dstScale int16,
	)

	// CompileRegisterToConst adds an instruction where source operand is the register `srcRegister`,
	// and the destination is the const `value`.
	CompileRegisterToConst(instruction asm.Instruction, srcRegister asm.Register, value int64) asm.Node

	// CompileRegisterToNone adds an instruction where source operand is the register `register`,
	// and there's no destination operand.
	CompileRegisterToNone(instruction asm.Instruction, register asm.Register)

	// CompileNoneToRegister adds an instruction where destination operand is the register `register`,
	// and there's no source operand.
	CompileNoneToRegister(instruction asm.Instruction, register asm.Register)

	// CompileNoneToMemory adds an instruction where destination operand is the memory address specified
	// as `baseReg+offset`. and there's no source operand.
	CompileNoneToMemory(instruction asm.Instruction, baseReg asm.Register, offset int64)

	// CompileConstToMemory adds an instruction where source operand is the constant `value` and
	// the destination is the memory address specified as `dstbaseReg+dstOffset`.
	CompileConstToMemory(instruction asm.Instruction, value int64, dstbaseReg asm.Register, dstOffset int64) asm.Node

	// CompileMemoryToConst adds an instruction where source operand is the memory address, and
	// the destination is the constant `value`.
	CompileMemoryToConst(instruction asm.Instruction, srcBaseReg asm.Register, srcOffset int64, value int64) asm.Node
}

Assembler is the interface used by amd64 JIT compiler.

type AssemblerImpl

type AssemblerImpl struct {
	asm.BaseAssemblerImpl
	EnablePadding   bool
	Root, Current   *NodeImpl
	Buf             *bytes.Buffer
	ForceReAssemble bool
}

AssemblerImpl implements Assembler.

func NewAssemblerImpl

func NewAssemblerImpl() *AssemblerImpl

func (*AssemblerImpl) Assemble

func (a *AssemblerImpl) Assemble() ([]byte, error)

Assemble implements asm.AssemblerBase

func (*AssemblerImpl) CompileConstToMemory

func (a *AssemblerImpl) CompileConstToMemory(
	instruction asm.Instruction,
	value asm.ConstantValue,
	dstbaseReg asm.Register,
	dstOffset asm.ConstantValue,
) asm.Node

CompileConstToMemory implements the same method as documented on asm_arm64.Assembler.

func (*AssemblerImpl) CompileConstToRegister

func (a *AssemblerImpl) CompileConstToRegister(
	instruction asm.Instruction,
	value asm.ConstantValue,
	destinationReg asm.Register,
) (inst asm.Node)

CompileConstToRegister implements the same method as documented on asm.AssemblerBase.

func (*AssemblerImpl) CompileJump

func (a *AssemblerImpl) CompileJump(jmpInstruction asm.Instruction) asm.Node

CompileJump implements the same method as documented on asm.AssemblerBase.

func (*AssemblerImpl) CompileJumpToMemory

func (a *AssemblerImpl) CompileJumpToMemory(
	jmpInstruction asm.Instruction,
	baseReg asm.Register,
	offset asm.ConstantValue,
)

CompileJumpToMemory implements the same method as documented on asm.AssemblerBase.

func (*AssemblerImpl) CompileJumpToRegister

func (a *AssemblerImpl) CompileJumpToRegister(jmpInstruction asm.Instruction, reg asm.Register)

CompileJumpToRegister implements the same method as documented on asm.AssemblerBase.

func (*AssemblerImpl) CompileMemoryToConst

func (a *AssemblerImpl) CompileMemoryToConst(
	instruction asm.Instruction,
	srcBaseReg asm.Register,
	srcOffset, value asm.ConstantValue,
) asm.Node

CompileMemoryToConst implements the same method as documented on asm_arm64.Assembler.

func (*AssemblerImpl) CompileMemoryToRegister

func (a *AssemblerImpl) CompileMemoryToRegister(
	instruction asm.Instruction,
	sourceBaseReg asm.Register,
	sourceOffsetConst asm.ConstantValue,
	destinationReg asm.Register,
)

CompileMemoryToRegister implements the same method as documented on asm.AssemblerBase.

func (*AssemblerImpl) CompileMemoryWithIndexToRegister

func (a *AssemblerImpl) CompileMemoryWithIndexToRegister(
	instruction asm.Instruction,
	srcBaseReg asm.Register,
	srcOffsetConst asm.ConstantValue,
	srcIndex asm.Register,
	srcScale int16,
	dstReg asm.Register,
)

CompileMemoryWithIndexToRegister implements the same method as documented on asm_arm64.Assembler.

func (*AssemblerImpl) CompileNoneToMemory

func (a *AssemblerImpl) CompileNoneToMemory(
	instruction asm.Instruction,
	baseReg asm.Register,
	offset asm.ConstantValue,
)

CompileNoneToMemory implements the same method as documented on asm_arm64.Assembler.

func (*AssemblerImpl) CompileNoneToRegister

func (a *AssemblerImpl) CompileNoneToRegister(instruction asm.Instruction, register asm.Register)

CompileNoneToRegister implements the same method as documented on asm_arm64.Assembler.

func (*AssemblerImpl) CompileReadInstructionAddress

func (a *AssemblerImpl) CompileReadInstructionAddress(
	destinationRegister asm.Register,
	beforeAcquisitionTargetInstruction asm.Instruction,
)

CompileReadInstructionAddress implements the same method as documented on asm.AssemblerBase.

func (*AssemblerImpl) CompileRegisterToConst

func (a *AssemblerImpl) CompileRegisterToConst(
	instruction asm.Instruction,
	srcRegister asm.Register,
	value asm.ConstantValue,
) asm.Node

CompileRegisterToConst implements the same method as documented on asm_arm64.Assembler.

func (*AssemblerImpl) CompileRegisterToMemory

func (a *AssemblerImpl) CompileRegisterToMemory(
	instruction asm.Instruction,
	sourceRegister, destinationBaseRegister asm.Register,
	destinationOffsetConst asm.ConstantValue,
)

CompileRegisterToMemory implements the same method as documented on asm.AssemblerBase.

func (*AssemblerImpl) CompileRegisterToMemoryWithIndex

func (a *AssemblerImpl) CompileRegisterToMemoryWithIndex(
	instruction asm.Instruction,
	srcReg, dstBaseReg asm.Register,
	dstOffsetConst asm.ConstantValue,
	dstIndex asm.Register,
	dstScale int16,
)

CompileRegisterToMemoryWithIndex implements the same method as documented on asm_arm64.Assembler.

func (*AssemblerImpl) CompileRegisterToNone

func (a *AssemblerImpl) CompileRegisterToNone(instruction asm.Instruction, register asm.Register)

CompileRegisterToNone implements the same method as documented on asm_arm64.Assembler.

func (*AssemblerImpl) CompileRegisterToRegister

func (a *AssemblerImpl) CompileRegisterToRegister(instruction asm.Instruction, from, to asm.Register)

CompileRegisterToRegister implements the same method as documented on asm.AssemblerBase.

func (*AssemblerImpl) CompileRegisterToRegisterWithMode

func (a *AssemblerImpl) CompileRegisterToRegisterWithMode(
	instruction asm.Instruction,
	from, to asm.Register,
	mode Mode,
)

CompileRegisterToRegisterWithMode implements the same method as documented on asm_arm64.Assembler.

func (*AssemblerImpl) CompileStandAlone

func (a *AssemblerImpl) CompileStandAlone(instruction asm.Instruction) asm.Node

CompileStandAlone implements the same method as documented on asm.AssemblerBase.

func (*AssemblerImpl) Encode

func (a *AssemblerImpl) Encode() (err error)

func (*AssemblerImpl) EncodeConstToMemory

func (a *AssemblerImpl) EncodeConstToMemory(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeConstToRegister

func (a *AssemblerImpl) EncodeConstToRegister(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeMemoryToConst

func (a *AssemblerImpl) EncodeMemoryToConst(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeMemoryToRegister

func (a *AssemblerImpl) EncodeMemoryToRegister(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeNode

func (a *AssemblerImpl) EncodeNode(n *NodeImpl) (err error)

EncodeNode encodes the given node into writer.

func (*AssemblerImpl) EncodeNoneToMemory

func (a *AssemblerImpl) EncodeNoneToMemory(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeNoneToRegister

func (a *AssemblerImpl) EncodeNoneToRegister(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeRegisterToConst

func (a *AssemblerImpl) EncodeRegisterToConst(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeRegisterToMemory

func (a *AssemblerImpl) EncodeRegisterToMemory(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeRegisterToNone

func (a *AssemblerImpl) EncodeRegisterToNone(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeRegisterToRegister

func (a *AssemblerImpl) EncodeRegisterToRegister(n *NodeImpl) (err error)

func (*AssemblerImpl) EncodeRelativeJump

func (a *AssemblerImpl) EncodeRelativeJump(n *NodeImpl) (err error)

func (*AssemblerImpl) InitializeNodesForEncoding

func (a *AssemblerImpl) InitializeNodesForEncoding()

InitializeNodesForEncoding initializes NodeImpl.Flag and determine all the jumps are forward or backward jump.

func (*AssemblerImpl) ResolveForwardRelativeJumps

func (a *AssemblerImpl) ResolveForwardRelativeJumps(target *NodeImpl) (err error)

func (*AssemblerImpl) WriteConst

func (a *AssemblerImpl) WriteConst(v int64, length byte)

type Mode

type Mode = byte

Mode represents a Mode for specific instruction. For example, ROUND** instructions' behavior can be modified "Mode" constant. See https://www.felixcloutier.com/x86/roundss for ROUNDSS as an example.

type NodeFlag

type NodeFlag byte
const (
	// NodeFlagInitializedForEncoding is always set to indicate that node is already initialized. Notably, this is used to judge
	// whether a jump is backward or forward before encoding.
	NodeFlagInitializedForEncoding NodeFlag = (1 << iota)
	NodeFlagBackwardJump
	// NodeFlagShortForwardJump is set to false by default and only used by forward branch jumps, which means .JumpTarget != nil and
	// the target node is encoded afoter this node. False by default means that that we Encode all the jumps with JumpTarget
	// as short jump (i.e. relative signed 8-bit integer offset jump) and try to Encode as small as possible.
	NodeFlagShortForwardJump
)

type NodeImpl

type NodeImpl struct {
	Instruction asm.Instruction

	OffsetInBinaryField asm.NodeOffsetInBinary // Field suffix to dodge conflict with OffsetInBinary

	// JumpTarget holds the target node in the linked for the jump-kind instruction.
	JumpTarget *NodeImpl
	Flag       NodeFlag
	// next holds the next node from this node in the assembled linked list.
	Next *NodeImpl

	Types                    OperandTypes
	SrcReg, DstReg           asm.Register
	SrcConst, DstConst       asm.ConstantValue
	SrcMemIndex, DstMemIndex asm.Register
	SrcMemScale, DstMemScale byte

	Mode byte

	// JumpOrigins hold all the nodes trying to jump into this node. In other words, all the nodes with .JumpTarget == this.
	JumpOrigins map[*NodeImpl]struct{}
	// contains filtered or unexported fields
}

NodeImpl implements asm.Node for amd64.

func (*NodeImpl) AssignDestinationConstant

func (n *NodeImpl) AssignDestinationConstant(value asm.ConstantValue)

AssignDestinationConstant implements asm.Node.AssignDestinationConstant.

func (*NodeImpl) AssignJumpTarget

func (n *NodeImpl) AssignJumpTarget(target asm.Node)

AssignJumpTarget implements asm.Node.AssignJumpTarget.

func (*NodeImpl) AssignSourceConstant

func (n *NodeImpl) AssignSourceConstant(value asm.ConstantValue)

AssignSourceConstant implements asm.Node.AssignSourceConstant.

func (*NodeImpl) GetMemoryLocation

func (n *NodeImpl) GetMemoryLocation() (p RexPrefix, modRM byte, sbi *byte, displacementWidth byte, err error)

func (*NodeImpl) GetRegisterToRegisterModRM

func (n *NodeImpl) GetRegisterToRegisterModRM(srcOnModRMReg bool) (RexPrefix, modRM byte, err error)

GetRegisterToRegisterModRM does XXXX

TODO: srcOnModRMReg can be deleted after golang-asm removal. This is necessary to match our implementation with golang-asm, but in practice, there are equivalent opcodes to always have src on ModRM:reg without ambiguity.

func (*NodeImpl) OffsetInBinary

func (n *NodeImpl) OffsetInBinary() asm.NodeOffsetInBinary

OffsetInBinary implements asm.Node.OffsetInBinary.

func (*NodeImpl) String

func (n *NodeImpl) String() (ret string)

String implements fmt.Stringer.

This is for debugging purpose, and the format is almost same as the AT&T assembly syntax, meaning that this should look like "INSTRUCTION ${from}, ${to}" where each operand might be embraced by '[]' to represent the memory location.

type OperandType

type OperandType byte

OperandType represents where an operand is placed for an instruction. Note: this is almost the same as obj.AddrType in GO assembler.

const (
	OperandTypeNone OperandType = iota
	OperandTypeRegister
	OperandTypeMemory
	OperandTypeConst
	OperandTypeBranch
)

func (OperandType) String

func (o OperandType) String() (ret string)

type OperandTypes

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

OperandTypes represents the only combinations of two OperandTypes used by wazero

func (OperandTypes) String

func (o OperandTypes) String() string

String implements fmt.Stringer

type RexPrefix

type RexPrefix = byte

RexPrefix represents REX prefix https://wiki.osdev.org/X86-64_Instruction_Encoding#REX_prefix

const (
	RexPrefixNone    RexPrefix = 0x0000_0000 // Indicates that the instruction doesn't need RexPrefix.
	RexPrefixDefault RexPrefix = 0b0100_0000
	RexPrefixW       RexPrefix = 0b0000_1000 | RexPrefixDefault
	RexPrefixR       RexPrefix = 0b0000_0100 | RexPrefixDefault
	RexPrefixX       RexPrefix = 0b0000_0010 | RexPrefixDefault
	RexPrefixB       RexPrefix = 0b0000_0001 | RexPrefixDefault
)

REX prefixes are independent of each other and can be combined with OR.

Jump to

Keyboard shortcuts

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