7423f38771
Upgrade libcontainer dependency to pick up fix for CVE-2019-19921 .
150 lines
3.2 KiB
Go
150 lines
3.2 KiB
Go
package asm
|
|
|
|
//go:generate stringer -output alu_string.go -type=Source,Endianness,ALUOp
|
|
|
|
// Source of ALU / ALU64 / Branch operations
|
|
//
|
|
// msb lsb
|
|
// +----+-+---+
|
|
// |op |S|cls|
|
|
// +----+-+---+
|
|
type Source uint8
|
|
|
|
const sourceMask OpCode = 0x08
|
|
|
|
// Source bitmask
|
|
const (
|
|
// InvalidSource is returned by getters when invoked
|
|
// on non ALU / branch OpCodes.
|
|
InvalidSource Source = 0xff
|
|
// ImmSource src is from constant
|
|
ImmSource Source = 0x00
|
|
// RegSource src is from register
|
|
RegSource Source = 0x08
|
|
)
|
|
|
|
// The Endianness of a byte swap instruction.
|
|
type Endianness uint8
|
|
|
|
const endianMask = sourceMask
|
|
|
|
// Endian flags
|
|
const (
|
|
InvalidEndian Endianness = 0xff
|
|
// Convert to little endian
|
|
LE Endianness = 0x00
|
|
// Convert to big endian
|
|
BE Endianness = 0x08
|
|
)
|
|
|
|
// ALUOp are ALU / ALU64 operations
|
|
//
|
|
// msb lsb
|
|
// +----+-+---+
|
|
// |OP |s|cls|
|
|
// +----+-+---+
|
|
type ALUOp uint8
|
|
|
|
const aluMask OpCode = 0xf0
|
|
|
|
const (
|
|
// InvalidALUOp is returned by getters when invoked
|
|
// on non ALU OpCodes
|
|
InvalidALUOp ALUOp = 0xff
|
|
// Add - addition
|
|
Add ALUOp = 0x00
|
|
// Sub - subtraction
|
|
Sub ALUOp = 0x10
|
|
// Mul - multiplication
|
|
Mul ALUOp = 0x20
|
|
// Div - division
|
|
Div ALUOp = 0x30
|
|
// Or - bitwise or
|
|
Or ALUOp = 0x40
|
|
// And - bitwise and
|
|
And ALUOp = 0x50
|
|
// LSh - bitwise shift left
|
|
LSh ALUOp = 0x60
|
|
// RSh - bitwise shift right
|
|
RSh ALUOp = 0x70
|
|
// Neg - sign/unsign signing bit
|
|
Neg ALUOp = 0x80
|
|
// Mod - modulo
|
|
Mod ALUOp = 0x90
|
|
// Xor - bitwise xor
|
|
Xor ALUOp = 0xa0
|
|
// Mov - move value from one place to another
|
|
Mov ALUOp = 0xb0
|
|
// ArSh - arithmatic shift
|
|
ArSh ALUOp = 0xc0
|
|
// Swap - endian conversions
|
|
Swap ALUOp = 0xd0
|
|
)
|
|
|
|
// HostTo converts from host to another endianness.
|
|
func HostTo(endian Endianness, dst Register, size Size) Instruction {
|
|
var imm int64
|
|
switch size {
|
|
case Half:
|
|
imm = 16
|
|
case Word:
|
|
imm = 32
|
|
case DWord:
|
|
imm = 64
|
|
default:
|
|
return Instruction{OpCode: InvalidOpCode}
|
|
}
|
|
|
|
return Instruction{
|
|
OpCode: OpCode(ALUClass).SetALUOp(Swap).SetSource(Source(endian)),
|
|
Dst: dst,
|
|
Constant: imm,
|
|
}
|
|
}
|
|
|
|
// Op returns the OpCode for an ALU operation with a given source.
|
|
func (op ALUOp) Op(source Source) OpCode {
|
|
return OpCode(ALU64Class).SetALUOp(op).SetSource(source)
|
|
}
|
|
|
|
// Reg emits `dst (op) src`.
|
|
func (op ALUOp) Reg(dst, src Register) Instruction {
|
|
return Instruction{
|
|
OpCode: op.Op(RegSource),
|
|
Dst: dst,
|
|
Src: src,
|
|
}
|
|
}
|
|
|
|
// Imm emits `dst (op) value`.
|
|
func (op ALUOp) Imm(dst Register, value int32) Instruction {
|
|
return Instruction{
|
|
OpCode: op.Op(ImmSource),
|
|
Dst: dst,
|
|
Constant: int64(value),
|
|
}
|
|
}
|
|
|
|
// Op32 returns the OpCode for a 32-bit ALU operation with a given source.
|
|
func (op ALUOp) Op32(source Source) OpCode {
|
|
return OpCode(ALUClass).SetALUOp(op).SetSource(source)
|
|
}
|
|
|
|
// Reg32 emits `dst (op) src`, zeroing the upper 32 bit of dst.
|
|
func (op ALUOp) Reg32(dst, src Register) Instruction {
|
|
return Instruction{
|
|
OpCode: op.Op32(RegSource),
|
|
Dst: dst,
|
|
Src: src,
|
|
}
|
|
}
|
|
|
|
// Imm32 emits `dst (op) value`, zeroing the upper 32 bit of dst.
|
|
func (op ALUOp) Imm32(dst Register, value int32) Instruction {
|
|
return Instruction{
|
|
OpCode: op.Op32(ImmSource),
|
|
Dst: dst,
|
|
Constant: int64(value),
|
|
}
|
|
}
|