gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

alu.go (3238B)


      1 package asm
      2 
      3 //go:generate stringer -output alu_string.go -type=Source,Endianness,ALUOp
      4 
      5 // Source of ALU / ALU64 / Branch operations
      6 //
      7 //    msb      lsb
      8 //    +----+-+---+
      9 //    |op  |S|cls|
     10 //    +----+-+---+
     11 type Source uint8
     12 
     13 const sourceMask OpCode = 0x08
     14 
     15 // Source bitmask
     16 const (
     17 	// InvalidSource is returned by getters when invoked
     18 	// on non ALU / branch OpCodes.
     19 	InvalidSource Source = 0xff
     20 	// ImmSource src is from constant
     21 	ImmSource Source = 0x00
     22 	// RegSource src is from register
     23 	RegSource Source = 0x08
     24 )
     25 
     26 // The Endianness of a byte swap instruction.
     27 type Endianness uint8
     28 
     29 const endianMask = sourceMask
     30 
     31 // Endian flags
     32 const (
     33 	InvalidEndian Endianness = 0xff
     34 	// Convert to little endian
     35 	LE Endianness = 0x00
     36 	// Convert to big endian
     37 	BE Endianness = 0x08
     38 )
     39 
     40 // ALUOp are ALU / ALU64 operations
     41 //
     42 //    msb      lsb
     43 //    +----+-+---+
     44 //    |OP  |s|cls|
     45 //    +----+-+---+
     46 type ALUOp uint8
     47 
     48 const aluMask OpCode = 0xf0
     49 
     50 const (
     51 	// InvalidALUOp is returned by getters when invoked
     52 	// on non ALU OpCodes
     53 	InvalidALUOp ALUOp = 0xff
     54 	// Add - addition
     55 	Add ALUOp = 0x00
     56 	// Sub - subtraction
     57 	Sub ALUOp = 0x10
     58 	// Mul - multiplication
     59 	Mul ALUOp = 0x20
     60 	// Div - division
     61 	Div ALUOp = 0x30
     62 	// Or - bitwise or
     63 	Or ALUOp = 0x40
     64 	// And - bitwise and
     65 	And ALUOp = 0x50
     66 	// LSh - bitwise shift left
     67 	LSh ALUOp = 0x60
     68 	// RSh - bitwise shift right
     69 	RSh ALUOp = 0x70
     70 	// Neg - sign/unsign signing bit
     71 	Neg ALUOp = 0x80
     72 	// Mod - modulo
     73 	Mod ALUOp = 0x90
     74 	// Xor - bitwise xor
     75 	Xor ALUOp = 0xa0
     76 	// Mov - move value from one place to another
     77 	Mov ALUOp = 0xb0
     78 	// ArSh - arithmatic shift
     79 	ArSh ALUOp = 0xc0
     80 	// Swap - endian conversions
     81 	Swap ALUOp = 0xd0
     82 )
     83 
     84 // HostTo converts from host to another endianness.
     85 func HostTo(endian Endianness, dst Register, size Size) Instruction {
     86 	var imm int64
     87 	switch size {
     88 	case Half:
     89 		imm = 16
     90 	case Word:
     91 		imm = 32
     92 	case DWord:
     93 		imm = 64
     94 	default:
     95 		return Instruction{OpCode: InvalidOpCode}
     96 	}
     97 
     98 	return Instruction{
     99 		OpCode:   OpCode(ALUClass).SetALUOp(Swap).SetSource(Source(endian)),
    100 		Dst:      dst,
    101 		Constant: imm,
    102 	}
    103 }
    104 
    105 // Op returns the OpCode for an ALU operation with a given source.
    106 func (op ALUOp) Op(source Source) OpCode {
    107 	return OpCode(ALU64Class).SetALUOp(op).SetSource(source)
    108 }
    109 
    110 // Reg emits `dst (op) src`.
    111 func (op ALUOp) Reg(dst, src Register) Instruction {
    112 	return Instruction{
    113 		OpCode: op.Op(RegSource),
    114 		Dst:    dst,
    115 		Src:    src,
    116 	}
    117 }
    118 
    119 // Imm emits `dst (op) value`.
    120 func (op ALUOp) Imm(dst Register, value int32) Instruction {
    121 	return Instruction{
    122 		OpCode:   op.Op(ImmSource),
    123 		Dst:      dst,
    124 		Constant: int64(value),
    125 	}
    126 }
    127 
    128 // Op32 returns the OpCode for a 32-bit ALU operation with a given source.
    129 func (op ALUOp) Op32(source Source) OpCode {
    130 	return OpCode(ALUClass).SetALUOp(op).SetSource(source)
    131 }
    132 
    133 // Reg32 emits `dst (op) src`, zeroing the upper 32 bit of dst.
    134 func (op ALUOp) Reg32(dst, src Register) Instruction {
    135 	return Instruction{
    136 		OpCode: op.Op32(RegSource),
    137 		Dst:    dst,
    138 		Src:    src,
    139 	}
    140 }
    141 
    142 // Imm32 emits `dst (op) value`, zeroing the upper 32 bit of dst.
    143 func (op ALUOp) Imm32(dst Register, value int32) Instruction {
    144 	return Instruction{
    145 		OpCode:   op.Op32(ImmSource),
    146 		Dst:      dst,
    147 		Constant: int64(value),
    148 	}
    149 }