From d3d1d516f8446748912ef932942f417b0f84ef3b Mon Sep 17 00:00:00 2001 From: Richard Patel Date: Sat, 3 Sep 2022 06:31:41 +0200 Subject: [PATCH] sbf: add opcodes --- pkg/sbf/opcode.go | 179 +++++++++++++++++++++++++++++++++++++++++ pkg/sbf/opcode_test.go | 121 ++++++++++++++++++++++++++++ 2 files changed, 300 insertions(+) create mode 100644 pkg/sbf/opcode.go create mode 100644 pkg/sbf/opcode_test.go diff --git a/pkg/sbf/opcode.go b/pkg/sbf/opcode.go new file mode 100644 index 0000000..e10b39a --- /dev/null +++ b/pkg/sbf/opcode.go @@ -0,0 +1,179 @@ +package sbf + +// Op classes +const ( + ClassLd = uint8(iota) + ClassLdx + ClassSt + ClassStx + ClassAlu + ClassJmp + Class0x06 // reserved + ClassAlu64 +) + +// Size modes +const ( + SizeW = uint8(iota * 0x08) + SizeH + SizeB + SizeDw +) + +// Addressing modes +const ( + AddrImm = uint8(iota * 0x20) + AddrAbs + AddrInd + AddrMem + Addr0x80 // reserved + Addr0xa0 // reserved + AddrXadd +) + +// Source modes +const ( + SrcK = uint8(iota * 0x08) + SrcX +) + +// ALU operations +const ( + AluAdd = uint8(iota * 0x10) + AluSub + AluMul + AluDiv + AluOr + AluAnd + AluLsh + AluRsh + AluNeg + AluMod + AluXor + AluMov + AluArsh + AluEnd + AluSdiv +) + +// Jump operations +const ( + JumpAlways = uint8(iota * 0x10) + JumpEq + JumpGt + JumpGe + JumpSet + JumpNe + JumpSgt + JumpSge + JumpCall + JumpExit + JumpLt + JumpLe + JumpSlt + JumpSle +) + +// Opcodes +const ( + OpLddw = ClassLd | AddrImm | SizeDw + + OpLdxb = ClassLdx | AddrMem | SizeB + OpLdxh = ClassLdx | AddrMem | SizeH + OpLdxw = ClassLdx | AddrMem | SizeW + OpLdxdw = ClassLdx | AddrMem | SizeDw + OpStb = ClassSt | AddrMem | SizeB + OpSth = ClassSt | AddrMem | SizeH + OpStw = ClassSt | AddrMem | SizeW + OpStdw = ClassSt | AddrMem | SizeDw + OpStxb = ClassStx | AddrMem | SizeB + OpStxh = ClassStx | AddrMem | SizeH + OpStxw = ClassStx | AddrMem | SizeW + OpStxdw = ClassStx | AddrMem | SizeDw + + OpAdd32Imm = ClassAlu | SrcK | AluAdd + OpAdd32Reg = ClassAlu | SrcX | AluAdd + OpSub32Imm = ClassAlu | SrcK | AluSub + OpSub32Reg = ClassAlu | SrcX | AluSub + OpMul32Imm = ClassAlu | SrcK | AluMul + OpMul32Reg = ClassAlu | SrcX | AluMul + OpDiv32Imm = ClassAlu | SrcK | AluDiv + OpDiv32Reg = ClassAlu | SrcX | AluDiv + OpOr32Imm = ClassAlu | SrcK | AluOr + OpOr32Reg = ClassAlu | SrcX | AluOr + OpAnd32Imm = ClassAlu | SrcK | AluAnd + OpAnd32Reg = ClassAlu | SrcX | AluAnd + OpLsh32Imm = ClassAlu | SrcK | AluLsh + OpLsh32Reg = ClassAlu | SrcX | AluLsh + OpRsh32Imm = ClassAlu | SrcK | AluRsh + OpRsh32Reg = ClassAlu | SrcX | AluRsh + OpNeg32 = ClassAlu | AluNeg + OpMod32Imm = ClassAlu | SrcK | AluMod + OpMod32Reg = ClassAlu | SrcX | AluMod + OpXor32Imm = ClassAlu | SrcK | AluXor + OpXor32Reg = ClassAlu | SrcX | AluXor + OpMov32Imm = ClassAlu | SrcK | AluMov + OpMov32Reg = ClassAlu | SrcX | AluMov + OpArsh32Imm = ClassAlu | SrcK | AluArsh + OpArsh32Reg = ClassAlu | SrcX | AluArsh + OpSdiv32Imm = ClassAlu | SrcK | AluSdiv + OpSdiv32Reg = ClassAlu | SrcX | AluSdiv + OpLe = ClassAlu | SrcK | AluEnd + OpBe = ClassAlu | SrcX | AluEnd + + OpAdd64Imm = ClassAlu64 | SrcK | AluAdd + OpAdd64Reg = ClassAlu64 | SrcX | AluAdd + OpSub64Imm = ClassAlu64 | SrcK | AluSub + OpSub64Reg = ClassAlu64 | SrcX | AluSub + OpMul64Imm = ClassAlu64 | SrcK | AluMul + OpMul64Reg = ClassAlu64 | SrcX | AluMul + OpDiv64Imm = ClassAlu64 | SrcK | AluDiv + OpDiv64Reg = ClassAlu64 | SrcX | AluDiv + OpOr64Imm = ClassAlu64 | SrcK | AluOr + OpOr64Reg = ClassAlu64 | SrcX | AluOr + OpAnd64Imm = ClassAlu64 | SrcK | AluAnd + OpAnd64Reg = ClassAlu64 | SrcX | AluAnd + OpLsh64Imm = ClassAlu64 | SrcK | AluLsh + OpLsh64Reg = ClassAlu64 | SrcX | AluLsh + OpRsh64Imm = ClassAlu64 | SrcK | AluRsh + OpRsh64Reg = ClassAlu64 | SrcX | AluRsh + OpNeg64 = ClassAlu64 | AluNeg + OpMod64Imm = ClassAlu64 | SrcK | AluMod + OpMod64Reg = ClassAlu64 | SrcX | AluMod + OpXor64Imm = ClassAlu64 | SrcK | AluXor + OpXor64Reg = ClassAlu64 | SrcX | AluXor + OpMov64Imm = ClassAlu64 | SrcK | AluMov + OpMov64Reg = ClassAlu64 | SrcX | AluMov + OpArsh64Imm = ClassAlu64 | SrcK | AluArsh + OpArsh64Reg = ClassAlu64 | SrcX | AluArsh + OpSdiv64Imm = ClassAlu64 | SrcK | AluSdiv + OpSdiv64Reg = ClassAlu64 | SrcX | AluSdiv + + OpJa = ClassJmp | JumpAlways + OpJeqImm = ClassJmp | SrcK | JumpEq + OpJeqReg = ClassJmp | SrcX | JumpEq + OpJgtImm = ClassJmp | SrcK | JumpGt + OpJgtReg = ClassJmp | SrcX | JumpGt + OpJgeImm = ClassJmp | SrcK | JumpGe + OpJgeReg = ClassJmp | SrcX | JumpGe + OpJltImm = ClassJmp | SrcK | JumpLt + OpJltReg = ClassJmp | SrcX | JumpLt + OpJleImm = ClassJmp | SrcK | JumpLe + OpJleReg = ClassJmp | SrcX | JumpLe + OpJsetImm = ClassJmp | SrcK | JumpSet + OpJsetReg = ClassJmp | SrcX | JumpSet + OpJneImm = ClassJmp | SrcK | JumpNe + OpJneReg = ClassJmp | SrcX | JumpNe + OpJsgtImm = ClassJmp | SrcK | JumpSgt + OpJsgtReg = ClassJmp | SrcX | JumpSgt + OpJsgeImm = ClassJmp | SrcK | JumpSge + OpJsgeReg = ClassJmp | SrcX | JumpSge + OpJsltImm = ClassJmp | SrcK | JumpSlt + OpJsltReg = ClassJmp | SrcX | JumpSlt + OpJsleImm = ClassJmp | SrcK | JumpSle + OpJsleReg = ClassJmp | SrcX | JumpSle + + OpCall = ClassJmp | SrcK | JumpCall + OpCallx = ClassJmp | SrcX | JumpCall + OpExit = ClassJmp | JumpExit +) diff --git a/pkg/sbf/opcode_test.go b/pkg/sbf/opcode_test.go new file mode 100644 index 0000000..a4dd1e4 --- /dev/null +++ b/pkg/sbf/opcode_test.go @@ -0,0 +1,121 @@ +package sbf + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestOpcodes(t *testing.T) { + type testCase struct { + want uint8 + have uint8 + } + cases := []testCase{ + {0x18, OpLddw}, + + {0x71, OpLdxb}, + {0x69, OpLdxh}, + {0x61, OpLdxw}, + {0x79, OpLdxdw}, + {0x72, OpStb}, + {0x6a, OpSth}, + {0x62, OpStw}, + {0x7a, OpStdw}, + {0x73, OpStxb}, + {0x6b, OpStxh}, + {0x63, OpStxw}, + {0x7b, OpStxdw}, + + {0x04, OpAdd32Imm}, + {0x07, OpAdd64Imm}, + {0x0c, OpAdd32Reg}, + {0x0f, OpAdd64Reg}, + {0x14, OpSub32Imm}, + {0x17, OpSub64Imm}, + {0x1c, OpSub32Reg}, + {0x1f, OpSub64Reg}, + {0x24, OpMul32Imm}, + {0x27, OpMul64Imm}, + {0x2c, OpMul32Reg}, + {0x2f, OpMul64Reg}, + {0x34, OpDiv32Imm}, + {0x37, OpDiv64Imm}, + {0x3c, OpDiv32Reg}, + {0x3f, OpDiv64Reg}, + {0x44, OpOr32Imm}, + {0x47, OpOr64Imm}, + {0x4c, OpOr32Reg}, + {0x4f, OpOr64Reg}, + {0x54, OpAnd32Imm}, + {0x57, OpAnd64Imm}, + {0x5c, OpAnd32Reg}, + {0x5f, OpAnd64Reg}, + {0x64, OpLsh32Imm}, + {0x67, OpLsh64Imm}, + {0x6c, OpLsh32Reg}, + {0x6f, OpLsh64Reg}, + {0x74, OpRsh32Imm}, + {0x77, OpRsh64Imm}, + {0x7c, OpRsh32Reg}, + {0x7f, OpRsh64Reg}, + {0x84, OpNeg32}, + {0x87, OpNeg64}, + {0x94, OpMod32Imm}, + {0x97, OpMod64Imm}, + {0x9c, OpMod32Reg}, + {0x9f, OpMod64Reg}, + {0xa4, OpXor32Imm}, + {0xa7, OpXor64Imm}, + {0xac, OpXor32Reg}, + {0xaf, OpXor64Reg}, + {0xb4, OpMov32Imm}, + {0xb7, OpMov64Imm}, + {0xbc, OpMov32Reg}, + {0xbf, OpMov64Reg}, + {0xc4, OpArsh32Imm}, + {0xc7, OpArsh64Imm}, + {0xcc, OpArsh32Reg}, + {0xcf, OpArsh64Reg}, + {0xd4, OpLe}, + {0xdc, OpBe}, + {0xe4, OpSdiv32Imm}, + {0xe7, OpSdiv64Imm}, + {0xec, OpSdiv32Reg}, + {0xef, OpSdiv64Reg}, + + {0x05, OpJa}, + {0x15, OpJeqImm}, + {0x1d, OpJeqReg}, + {0x25, OpJgtImm}, + {0x2d, OpJgtReg}, + {0x35, OpJgeImm}, + {0x3d, OpJgeReg}, + {0x45, OpJsetImm}, + {0x4d, OpJsetReg}, + {0x55, OpJneImm}, + {0x5d, OpJneReg}, + {0x65, OpJsgtImm}, + {0x6d, OpJsgtReg}, + {0x75, OpJsgeImm}, + {0x7d, OpJsgeReg}, + {0xa5, OpJltImm}, + {0xad, OpJltReg}, + {0xb5, OpJleImm}, + {0xbd, OpJleReg}, + {0xc5, OpJsltImm}, + {0xcd, OpJsltReg}, + {0xd5, OpJsleImm}, + {0xdd, OpJsleReg}, + + {0x85, OpCall}, + {0x8d, OpCallx}, + {0x95, OpExit}, + } + for _, c := range cases { + t.Run(fmt.Sprintf("Op_%#02x", c.want), func(t *testing.T) { + require.Equal(t, c.want, c.have) + }) + } +}