mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-01 15:00:00 +00:00
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),
|
||
|
}
|
||
|
}
|