github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/asm/alu.go (about) 1 package asm 2 3 //go:generate go run golang.org/x/tools/cmd/stringer@latest -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 uint16 12 13 const sourceMask OpCode = 0x0008 14 15 // Source bitmask 16 const ( 17 // InvalidSource is returned by getters when invoked 18 // on non ALU / branch OpCodes. 19 InvalidSource Source = 0xffff 20 // ImmSource src is from constant 21 ImmSource Source = 0x0000 22 // RegSource src is from register 23 RegSource Source = 0x0008 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 // | EXT | OP |s|cls| 45 // +-------+----+-+---+ 46 type ALUOp uint16 47 48 const aluMask OpCode = 0x3ff0 49 50 const ( 51 // InvalidALUOp is returned by getters when invoked 52 // on non ALU OpCodes 53 InvalidALUOp ALUOp = 0xffff 54 // Add - addition 55 Add ALUOp = 0x0000 56 // Sub - subtraction 57 Sub ALUOp = 0x0010 58 // Mul - multiplication 59 Mul ALUOp = 0x0020 60 // Div - division 61 Div ALUOp = 0x0030 62 // SDiv - signed division 63 SDiv ALUOp = Div + 0x0100 64 // Or - bitwise or 65 Or ALUOp = 0x0040 66 // And - bitwise and 67 And ALUOp = 0x0050 68 // LSh - bitwise shift left 69 LSh ALUOp = 0x0060 70 // RSh - bitwise shift right 71 RSh ALUOp = 0x0070 72 // Neg - sign/unsign signing bit 73 Neg ALUOp = 0x0080 74 // Mod - modulo 75 Mod ALUOp = 0x0090 76 // SMod - signed modulo 77 SMod ALUOp = Mod + 0x0100 78 // Xor - bitwise xor 79 Xor ALUOp = 0x00a0 80 // Mov - move value from one place to another 81 Mov ALUOp = 0x00b0 82 // MovSX8 - move lower 8 bits, sign extended upper bits of target 83 MovSX8 ALUOp = Mov + 0x0100 84 // MovSX16 - move lower 16 bits, sign extended upper bits of target 85 MovSX16 ALUOp = Mov + 0x0200 86 // MovSX32 - move lower 32 bits, sign extended upper bits of target 87 MovSX32 ALUOp = Mov + 0x0300 88 // ArSh - arithmetic shift 89 ArSh ALUOp = 0x00c0 90 // Swap - endian conversions 91 Swap ALUOp = 0x00d0 92 ) 93 94 // HostTo converts from host to another endianness. 95 func HostTo(endian Endianness, dst Register, size Size) Instruction { 96 var imm int64 97 switch size { 98 case Half: 99 imm = 16 100 case Word: 101 imm = 32 102 case DWord: 103 imm = 64 104 default: 105 return Instruction{OpCode: InvalidOpCode} 106 } 107 108 return Instruction{ 109 OpCode: OpCode(ALUClass).SetALUOp(Swap).SetSource(Source(endian)), 110 Dst: dst, 111 Constant: imm, 112 } 113 } 114 115 // BSwap unconditionally reverses the order of bytes in a register. 116 func BSwap(dst Register, size Size) Instruction { 117 var imm int64 118 switch size { 119 case Half: 120 imm = 16 121 case Word: 122 imm = 32 123 case DWord: 124 imm = 64 125 default: 126 return Instruction{OpCode: InvalidOpCode} 127 } 128 129 return Instruction{ 130 OpCode: OpCode(ALU64Class).SetALUOp(Swap), 131 Dst: dst, 132 Constant: imm, 133 } 134 } 135 136 // Op returns the OpCode for an ALU operation with a given source. 137 func (op ALUOp) Op(source Source) OpCode { 138 return OpCode(ALU64Class).SetALUOp(op).SetSource(source) 139 } 140 141 // Reg emits `dst (op) src`. 142 func (op ALUOp) Reg(dst, src Register) Instruction { 143 return Instruction{ 144 OpCode: op.Op(RegSource), 145 Dst: dst, 146 Src: src, 147 } 148 } 149 150 // Imm emits `dst (op) value`. 151 func (op ALUOp) Imm(dst Register, value int32) Instruction { 152 return Instruction{ 153 OpCode: op.Op(ImmSource), 154 Dst: dst, 155 Constant: int64(value), 156 } 157 } 158 159 // Op32 returns the OpCode for a 32-bit ALU operation with a given source. 160 func (op ALUOp) Op32(source Source) OpCode { 161 return OpCode(ALUClass).SetALUOp(op).SetSource(source) 162 } 163 164 // Reg32 emits `dst (op) src`, zeroing the upper 32 bit of dst. 165 func (op ALUOp) Reg32(dst, src Register) Instruction { 166 return Instruction{ 167 OpCode: op.Op32(RegSource), 168 Dst: dst, 169 Src: src, 170 } 171 } 172 173 // Imm32 emits `dst (op) value`, zeroing the upper 32 bit of dst. 174 func (op ALUOp) Imm32(dst Register, value int32) Instruction { 175 return Instruction{ 176 OpCode: op.Op32(ImmSource), 177 Dst: dst, 178 Constant: int64(value), 179 } 180 }