123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- 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),
- }
- }
|