From 6c05013c6a790b94fa213a9fae6f4965394d2dfd Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Mon, 6 Oct 2025 13:49:58 +0200 Subject: [PATCH] Refactored names of load and store operations --- src/arm/Load.go | 12 +- src/arm/Load_test.go | 8 +- src/arm/Store.go | 8 +- src/arm/Store_test.go | 8 +- src/asm/compilerARM.go | 14 +- src/asm/compilerX86.go | 8 +- src/x86/Load.go | 57 ++++- src/x86/LoadDynamic.go | 59 ----- src/x86/LoadDynamic_test.go | 142 ----------- src/x86/LoadFixedOffset.go | 8 + src/x86/LoadFixedOffset_test.go | 158 ++++++++++++ src/x86/Load_test.go | 262 ++++++++++---------- src/x86/Store.go | 12 +- src/x86/StoreDynamic.go | 27 -- src/x86/StoreDynamic_test.go | 173 ------------- src/x86/StoreFixedOffset.go | 27 ++ src/x86/StoreFixedOffset_test.go | 307 +++++++++++++++++++++++ src/x86/Store_test.go | 410 +++++++++++-------------------- 18 files changed, 850 insertions(+), 850 deletions(-) delete mode 100644 src/x86/LoadDynamic.go delete mode 100644 src/x86/LoadDynamic_test.go create mode 100644 src/x86/LoadFixedOffset.go create mode 100644 src/x86/LoadFixedOffset_test.go delete mode 100644 src/x86/StoreDynamic.go delete mode 100644 src/x86/StoreDynamic_test.go create mode 100644 src/x86/StoreFixedOffset.go create mode 100644 src/x86/StoreFixedOffset_test.go diff --git a/src/arm/Load.go b/src/arm/Load.go index aaeff0c..10dc221 100644 --- a/src/arm/Load.go +++ b/src/arm/Load.go @@ -2,12 +2,12 @@ package arm import "git.urbach.dev/cli/q/src/cpu" -// LoadDynamicRegister loads from memory into a register with a register offset. -func LoadDynamicRegister(destination cpu.Register, base cpu.Register, offset cpu.Register, scale Scale, length byte) uint32 { - return 1<<22 | StoreDynamicRegister(destination, base, offset, scale, length) +// Load loads from memory into a register with a register offset. +func Load(destination cpu.Register, base cpu.Register, offset cpu.Register, scale Scale, length byte) uint32 { + return 1<<22 | StoreRegister(destination, base, offset, scale, length) } -// LoadRegister loads from memory with a signed offset from -256 to 255 into a register. -func LoadRegister(destination cpu.Register, base cpu.Register, mode AddressMode, offset int, length byte) uint32 { - return 1<<22 | StoreRegister(destination, base, mode, offset, length) +// LoadFixedOffset loads from memory with a signed offset from -256 to 255 into a register. +func LoadFixedOffset(destination cpu.Register, base cpu.Register, mode AddressMode, offset int, length byte) uint32 { + return 1<<22 | StoreFixedOffsetRegister(destination, base, mode, offset, length) } \ No newline at end of file diff --git a/src/arm/Load_test.go b/src/arm/Load_test.go index fff5eef..80d4c85 100644 --- a/src/arm/Load_test.go +++ b/src/arm/Load_test.go @@ -8,7 +8,7 @@ import ( "git.urbach.dev/go/assert" ) -func TestLoadDynamicRegister(t *testing.T) { +func TestLoad(t *testing.T) { usagePatterns := []struct { Destination cpu.Register Base cpu.Register @@ -26,12 +26,12 @@ func TestLoadDynamicRegister(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("ldr %s, [%s, #%s] %db", pattern.Destination, pattern.Base, pattern.Offset, pattern.Length) - code := arm.LoadDynamicRegister(pattern.Destination, pattern.Base, pattern.Offset, pattern.Scale, pattern.Length) + code := arm.Load(pattern.Destination, pattern.Base, pattern.Offset, pattern.Scale, pattern.Length) assert.Equal(t, code, pattern.Code) } } -func TestLoadRegister(t *testing.T) { +func TestLoadFixedOffset(t *testing.T) { usagePatterns := []struct { Destination cpu.Register Base cpu.Register @@ -61,7 +61,7 @@ func TestLoadRegister(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("ldur %s, [%s, %d] %db", pattern.Destination, pattern.Base, pattern.Offset, pattern.Length) - code := arm.LoadRegister(pattern.Destination, pattern.Base, pattern.Mode, pattern.Offset, pattern.Length) + code := arm.LoadFixedOffset(pattern.Destination, pattern.Base, pattern.Mode, pattern.Offset, pattern.Length) assert.Equal(t, code, pattern.Code) } } \ No newline at end of file diff --git a/src/arm/Store.go b/src/arm/Store.go index d28f19d..f47ad9c 100644 --- a/src/arm/Store.go +++ b/src/arm/Store.go @@ -4,12 +4,12 @@ import ( "git.urbach.dev/cli/q/src/cpu" ) -// StoreDynamicRegister writes the contents of the register to a memory address with a register offset. -func StoreDynamicRegister(source cpu.Register, base cpu.Register, offset cpu.Register, scale Scale, length byte) uint32 { +// StoreRegister writes the contents of the register to a memory address with a register offset. +func StoreRegister(source cpu.Register, base cpu.Register, offset cpu.Register, scale Scale, length byte) uint32 { return size(length)<<30 | 0b111<<27 | 1<<21 | (LSL << 13) | uint32(scale&1)<<12 | uint32(RegisterOffset)<<10 | reg3(source, base, offset) } -// StoreRegister writes the contents of the register to a memory address with a signed offset from -256 to 255. -func StoreRegister(source cpu.Register, base cpu.Register, mode AddressMode, offset int, length byte) uint32 { +// StoreFixedOffsetRegister writes the contents of the register to a memory address with a signed offset from -256 to 255. +func StoreFixedOffsetRegister(source cpu.Register, base cpu.Register, mode AddressMode, offset int, length byte) uint32 { return size(length)<<30 | 0b111<<27 | memory(source, base, mode, offset) } \ No newline at end of file diff --git a/src/arm/Store_test.go b/src/arm/Store_test.go index 28dc17e..785503d 100644 --- a/src/arm/Store_test.go +++ b/src/arm/Store_test.go @@ -8,7 +8,7 @@ import ( "git.urbach.dev/go/assert" ) -func TestStoreDynamicRegister(t *testing.T) { +func TestStoreRegister(t *testing.T) { usagePatterns := []struct { Source cpu.Register Base cpu.Register @@ -26,12 +26,12 @@ func TestStoreDynamicRegister(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("str %s, [%s, #%s] %db", pattern.Source, pattern.Base, pattern.Offset, pattern.Length) - code := arm.StoreDynamicRegister(pattern.Source, pattern.Base, pattern.Offset, pattern.Scale, pattern.Length) + code := arm.StoreRegister(pattern.Source, pattern.Base, pattern.Offset, pattern.Scale, pattern.Length) assert.Equal(t, code, pattern.Code) } } -func TestStoreRegister(t *testing.T) { +func TestStoreFixedOffsetRegister(t *testing.T) { usagePatterns := []struct { Source cpu.Register Base cpu.Register @@ -59,7 +59,7 @@ func TestStoreRegister(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("stur %s, [%s, #%d] %db", pattern.Source, pattern.Base, pattern.Offset, pattern.Length) - code := arm.StoreRegister(pattern.Source, pattern.Base, pattern.Mode, pattern.Offset, pattern.Length) + code := arm.StoreFixedOffsetRegister(pattern.Source, pattern.Base, pattern.Mode, pattern.Offset, pattern.Length) assert.Equal(t, code, pattern.Code) } } \ No newline at end of file diff --git a/src/asm/compilerARM.go b/src/asm/compilerARM.go index d8b4c8c..2e0a12b 100644 --- a/src/asm/compilerARM.go +++ b/src/asm/compilerARM.go @@ -47,7 +47,7 @@ func (c *compilerARM) Compile(instr Instruction) { case *CallExtern: c.append(arm.LoadAddress(arm.X16, 0)) patch := c.PatchLast4Bytes() - c.append(arm.LoadRegister(arm.X16, arm.X16, arm.UnscaledImmediate, 0, 8)) + c.append(arm.LoadFixedOffset(arm.X16, arm.X16, arm.UnscaledImmediate, 0, 8)) c.append(arm.CallRegister(arm.X16)) patch.apply = func(code []byte) []byte { @@ -131,7 +131,7 @@ func (c *compilerARM) Compile(instr Instruction) { scale = arm.ScaleLength } - c.append(arm.LoadDynamicRegister(instr.Destination, instr.Base, instr.Index, scale, instr.Length)) + c.append(arm.Load(instr.Destination, instr.Base, instr.Index, scale, instr.Length)) case *Modulo: if instr.Destination == instr.Source || instr.Destination == instr.Operand { panic("modulo destination register cannot be equal to the source or operand register") @@ -173,7 +173,7 @@ func (c *compilerARM) Compile(instr Instruction) { if count&1 != 0 { count-- - c.append(arm.LoadRegister(registers[count], arm.SP, arm.PostIndex, 16, 8)) + c.append(arm.LoadFixedOffset(registers[count], arm.SP, arm.PostIndex, 16, 8)) } for i := count - 2; i >= 0; i -= 2 { @@ -186,7 +186,7 @@ func (c *compilerARM) Compile(instr Instruction) { if i+1 < len(registers) { c.append(arm.StorePair(registers[i], registers[i+1], arm.SP, -16)) } else { - c.append(arm.StoreRegister(registers[i], arm.SP, arm.PreIndex, -16, 8)) + c.append(arm.StoreFixedOffsetRegister(registers[i], arm.SP, arm.PreIndex, -16, 8)) } } case *Return: @@ -210,7 +210,7 @@ func (c *compilerARM) Compile(instr Instruction) { scale = arm.ScaleLength } - c.append(arm.StoreDynamicRegister(instr.Source, instr.Base, instr.Index, scale, instr.Length)) + c.append(arm.StoreRegister(instr.Source, instr.Base, instr.Index, scale, instr.Length)) case *StoreNumber: panic("arm64 does not support memory stores of immediates") case *Subtract: @@ -219,9 +219,9 @@ func (c *compilerARM) Compile(instr Instruction) { code, _ := arm.SubRegisterNumber(instr.Destination, instr.Source, instr.Number) c.append(code) case *StackFrameStart: - c.append(arm.StoreRegister(arm.LR, arm.SP, arm.PreIndex, -16, 8)) + c.append(arm.StoreFixedOffsetRegister(arm.LR, arm.SP, arm.PreIndex, -16, 8)) case *StackFrameEnd: - c.append(arm.LoadRegister(arm.LR, arm.SP, arm.PostIndex, 16, 8)) + c.append(arm.LoadFixedOffset(arm.LR, arm.SP, arm.PostIndex, 16, 8)) case *Syscall: switch c.build.OS { case config.Mac: diff --git a/src/asm/compilerX86.go b/src/asm/compilerX86.go index e5e17af..3b82056 100644 --- a/src/asm/compilerX86.go +++ b/src/asm/compilerX86.go @@ -190,9 +190,9 @@ func (c *compilerX86) Compile(instr Instruction) { scale := toX86Scale(instr.Scale, instr.Length) if instr.Length <= 2 { - c.code = x86.LoadDynamicRegisterZeroExtend(c.code, instr.Destination, instr.Base, instr.Index, scale, instr.Length) + c.code = x86.LoadZeroExtend(c.code, instr.Destination, instr.Base, instr.Index, scale, instr.Length) } else { - c.code = x86.LoadDynamicRegister(c.code, instr.Destination, instr.Base, instr.Index, scale, instr.Length) + c.code = x86.Load(c.code, instr.Destination, instr.Base, instr.Index, scale, instr.Length) } case *Modulo: if instr.Operand == x86.R0 { @@ -309,10 +309,10 @@ func (c *compilerX86) Compile(instr Instruction) { } case *Store: scale := toX86Scale(instr.Scale, instr.Length) - c.code = x86.StoreDynamicRegister(c.code, instr.Base, instr.Index, scale, instr.Length, instr.Source) + c.code = x86.StoreRegister(c.code, instr.Base, instr.Index, scale, instr.Length, instr.Source) case *StoreNumber: scale := toX86Scale(instr.Scale, instr.Length) - c.code = x86.StoreDynamicNumber(c.code, instr.Base, instr.Index, scale, instr.Length, instr.Number) + c.code = x86.StoreNumber(c.code, instr.Base, instr.Index, scale, instr.Length, instr.Number) case *Subtract: if instr.Destination == instr.Operand { panic("subtract destination register cannot be equal to the operand register") diff --git a/src/x86/Load.go b/src/x86/Load.go index e80cf33..394c3e0 100644 --- a/src/x86/Load.go +++ b/src/x86/Load.go @@ -2,7 +2,58 @@ package x86 import "git.urbach.dev/cli/q/src/cpu" -// LoadRegister loads from memory into a register. -func LoadRegister(code []byte, destination cpu.Register, base cpu.Register, offset int8, scale Scale, length byte) []byte { - return memAccess(code, 0x8A, 0x8B, destination, base, offset, scale, length) +// Load loads from memory with a register offset into a register. +func Load(code []byte, destination cpu.Register, base cpu.Register, offset cpu.Register, scale Scale, length byte) []byte { + return memAccessDynamic(code, 0x8A, 0x8B, destination, base, offset, scale, length) +} + +// LoadZeroExtend loads from memory with a register offset into a register and zero-extends it. +func LoadZeroExtend(code []byte, destination cpu.Register, base cpu.Register, offset cpu.Register, scale Scale, length byte) []byte { + var ( + w = byte(1) + r = byte(0) + x = byte(0) + b = byte(0) + opCode = byte(0xB7) + mod = AddressMemory + ) + + if length == 1 { + opCode = 0xB6 + } + + if offset == SP { + offset, base = base, offset + } + + if destination > 0b111 { + r = 1 + destination &= 0b111 + } + + if offset > 0b111 { + x = 1 + offset &= 0b111 + } + + if base > 0b111 { + b = 1 + base &= 0b111 + } + + if base == R5 || base == R13 { + mod = AddressMemoryOffset8 + } + + code = append(code, REX(w, r, x, b)) + code = append(code, 0x0F) + code = append(code, opCode) + code = append(code, ModRM(mod, byte(destination), 0b100)) + code = append(code, SIB(scale, byte(offset), byte(base))) + + if mod == AddressMemoryOffset8 { + code = append(code, 0x00) + } + + return code } \ No newline at end of file diff --git a/src/x86/LoadDynamic.go b/src/x86/LoadDynamic.go deleted file mode 100644 index ecb482a..0000000 --- a/src/x86/LoadDynamic.go +++ /dev/null @@ -1,59 +0,0 @@ -package x86 - -import "git.urbach.dev/cli/q/src/cpu" - -// LoadDynamicRegister loads from memory with a register offset into a register. -func LoadDynamicRegister(code []byte, destination cpu.Register, base cpu.Register, offset cpu.Register, scale Scale, length byte) []byte { - return memAccessDynamic(code, 0x8A, 0x8B, destination, base, offset, scale, length) -} - -// LoadDynamicRegisterZeroExtend loads from memory with a register offset into a register and zero-extends it. -func LoadDynamicRegisterZeroExtend(code []byte, destination cpu.Register, base cpu.Register, offset cpu.Register, scale Scale, length byte) []byte { - var ( - w = byte(1) - r = byte(0) - x = byte(0) - b = byte(0) - opCode = byte(0xB7) - mod = AddressMemory - ) - - if length == 1 { - opCode = 0xB6 - } - - if offset == SP { - offset, base = base, offset - } - - if destination > 0b111 { - r = 1 - destination &= 0b111 - } - - if offset > 0b111 { - x = 1 - offset &= 0b111 - } - - if base > 0b111 { - b = 1 - base &= 0b111 - } - - if base == R5 || base == R13 { - mod = AddressMemoryOffset8 - } - - code = append(code, REX(w, r, x, b)) - code = append(code, 0x0F) - code = append(code, opCode) - code = append(code, ModRM(mod, byte(destination), 0b100)) - code = append(code, SIB(scale, byte(offset), byte(base))) - - if mod == AddressMemoryOffset8 { - code = append(code, 0x00) - } - - return code -} \ No newline at end of file diff --git a/src/x86/LoadDynamic_test.go b/src/x86/LoadDynamic_test.go deleted file mode 100644 index b9977f7..0000000 --- a/src/x86/LoadDynamic_test.go +++ /dev/null @@ -1,142 +0,0 @@ -package x86_test - -import ( - "testing" - - "git.urbach.dev/cli/q/src/cpu" - "git.urbach.dev/cli/q/src/x86" - "git.urbach.dev/go/assert" -) - -func TestLoadDynamicRegister(t *testing.T) { - usagePatterns := []struct { - Destination cpu.Register - Length byte - Base cpu.Register - OffsetRegister cpu.Register - Scale x86.Scale - Code []byte - }{ - {x86.R15, 8, x86.R0, x86.R15, x86.Scale1, []byte{0x4E, 0x8B, 0x3C, 0x38}}, - {x86.R15, 4, x86.R0, x86.R15, x86.Scale1, []byte{0x46, 0x8B, 0x3C, 0x38}}, - {x86.R15, 2, x86.R0, x86.R15, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x3C, 0x38}}, - {x86.R15, 1, x86.R0, x86.R15, x86.Scale1, []byte{0x46, 0x8A, 0x3C, 0x38}}, - {x86.R14, 8, x86.R1, x86.R14, x86.Scale1, []byte{0x4E, 0x8B, 0x34, 0x31}}, - {x86.R14, 4, x86.R1, x86.R14, x86.Scale1, []byte{0x46, 0x8B, 0x34, 0x31}}, - {x86.R14, 2, x86.R1, x86.R14, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x34, 0x31}}, - {x86.R14, 1, x86.R1, x86.R14, x86.Scale1, []byte{0x46, 0x8A, 0x34, 0x31}}, - {x86.R13, 8, x86.R2, x86.R13, x86.Scale1, []byte{0x4E, 0x8B, 0x2C, 0x2A}}, - {x86.R13, 4, x86.R2, x86.R13, x86.Scale1, []byte{0x46, 0x8B, 0x2C, 0x2A}}, - {x86.R13, 2, x86.R2, x86.R13, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x2C, 0x2A}}, - {x86.R13, 1, x86.R2, x86.R13, x86.Scale1, []byte{0x46, 0x8A, 0x2C, 0x2A}}, - {x86.R12, 8, x86.R3, x86.R12, x86.Scale1, []byte{0x4E, 0x8B, 0x24, 0x23}}, - {x86.R12, 4, x86.R3, x86.R12, x86.Scale1, []byte{0x46, 0x8B, 0x24, 0x23}}, - {x86.R12, 2, x86.R3, x86.R12, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x24, 0x23}}, - {x86.R12, 1, x86.R3, x86.R12, x86.Scale1, []byte{0x46, 0x8A, 0x24, 0x23}}, - {x86.R11, 8, x86.SP, x86.R11, x86.Scale1, []byte{0x4E, 0x8B, 0x1C, 0x1C}}, - {x86.R11, 4, x86.SP, x86.R11, x86.Scale1, []byte{0x46, 0x8B, 0x1C, 0x1C}}, - {x86.R11, 2, x86.SP, x86.R11, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x1C, 0x1C}}, - {x86.R11, 1, x86.SP, x86.R11, x86.Scale1, []byte{0x46, 0x8A, 0x1C, 0x1C}}, - {x86.R10, 8, x86.R5, x86.R10, x86.Scale1, []byte{0x4E, 0x8B, 0x54, 0x15, 0x00}}, - {x86.R10, 4, x86.R5, x86.R10, x86.Scale1, []byte{0x46, 0x8B, 0x54, 0x15, 0x00}}, - {x86.R10, 2, x86.R5, x86.R10, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x54, 0x15, 0x00}}, - {x86.R10, 1, x86.R5, x86.R10, x86.Scale1, []byte{0x46, 0x8A, 0x54, 0x15, 0x00}}, - {x86.R9, 8, x86.R6, x86.R9, x86.Scale1, []byte{0x4E, 0x8B, 0x0C, 0x0E}}, - {x86.R9, 4, x86.R6, x86.R9, x86.Scale1, []byte{0x46, 0x8B, 0x0C, 0x0E}}, - {x86.R9, 2, x86.R6, x86.R9, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x0C, 0x0E}}, - {x86.R9, 1, x86.R6, x86.R9, x86.Scale1, []byte{0x46, 0x8A, 0x0C, 0x0E}}, - {x86.R8, 8, x86.R7, x86.R8, x86.Scale1, []byte{0x4E, 0x8B, 0x04, 0x07}}, - {x86.R8, 4, x86.R7, x86.R8, x86.Scale1, []byte{0x46, 0x8B, 0x04, 0x07}}, - {x86.R8, 2, x86.R7, x86.R8, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x04, 0x07}}, - {x86.R8, 1, x86.R7, x86.R8, x86.Scale1, []byte{0x46, 0x8A, 0x04, 0x07}}, - {x86.R7, 8, x86.R8, x86.R7, x86.Scale1, []byte{0x49, 0x8B, 0x3C, 0x38}}, - {x86.R7, 4, x86.R8, x86.R7, x86.Scale1, []byte{0x41, 0x8B, 0x3C, 0x38}}, - {x86.R7, 2, x86.R8, x86.R7, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x3C, 0x38}}, - {x86.R7, 1, x86.R8, x86.R7, x86.Scale1, []byte{0x41, 0x8A, 0x3C, 0x38}}, - {x86.R6, 8, x86.R9, x86.R6, x86.Scale1, []byte{0x49, 0x8B, 0x34, 0x31}}, - {x86.R6, 4, x86.R9, x86.R6, x86.Scale1, []byte{0x41, 0x8B, 0x34, 0x31}}, - {x86.R6, 2, x86.R9, x86.R6, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x34, 0x31}}, - {x86.R6, 1, x86.R9, x86.R6, x86.Scale1, []byte{0x41, 0x8A, 0x34, 0x31}}, - {x86.R5, 8, x86.R10, x86.R5, x86.Scale1, []byte{0x49, 0x8B, 0x2C, 0x2A}}, - {x86.R5, 4, x86.R10, x86.R5, x86.Scale1, []byte{0x41, 0x8B, 0x2C, 0x2A}}, - {x86.R5, 2, x86.R10, x86.R5, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x2C, 0x2A}}, - {x86.R5, 1, x86.R10, x86.R5, x86.Scale1, []byte{0x41, 0x8A, 0x2C, 0x2A}}, - {x86.SP, 8, x86.R11, x86.SP, x86.Scale1, []byte{0x4A, 0x8B, 0x24, 0x1C}}, - {x86.SP, 4, x86.R11, x86.SP, x86.Scale1, []byte{0x42, 0x8B, 0x24, 0x1C}}, - {x86.SP, 2, x86.R11, x86.SP, x86.Scale1, []byte{0x66, 0x42, 0x8B, 0x24, 0x1C}}, - {x86.SP, 1, x86.R11, x86.SP, x86.Scale1, []byte{0x42, 0x8A, 0x24, 0x1C}}, - {x86.R3, 8, x86.R12, x86.R3, x86.Scale1, []byte{0x49, 0x8B, 0x1C, 0x1C}}, - {x86.R3, 4, x86.R12, x86.R3, x86.Scale1, []byte{0x41, 0x8B, 0x1C, 0x1C}}, - {x86.R3, 2, x86.R12, x86.R3, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x1C, 0x1C}}, - {x86.R3, 1, x86.R12, x86.R3, x86.Scale1, []byte{0x41, 0x8A, 0x1C, 0x1C}}, - {x86.R2, 8, x86.R13, x86.R2, x86.Scale1, []byte{0x49, 0x8B, 0x54, 0x15, 0x00}}, - {x86.R2, 4, x86.R13, x86.R2, x86.Scale1, []byte{0x41, 0x8B, 0x54, 0x15, 0x00}}, - {x86.R2, 2, x86.R13, x86.R2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x54, 0x15, 0x00}}, - {x86.R2, 1, x86.R13, x86.R2, x86.Scale1, []byte{0x41, 0x8A, 0x54, 0x15, 0x00}}, - {x86.R1, 8, x86.R14, x86.R1, x86.Scale1, []byte{0x49, 0x8B, 0x0C, 0x0E}}, - {x86.R1, 4, x86.R14, x86.R1, x86.Scale1, []byte{0x41, 0x8B, 0x0C, 0x0E}}, - {x86.R1, 2, x86.R14, x86.R1, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x0C, 0x0E}}, - {x86.R1, 1, x86.R14, x86.R1, x86.Scale1, []byte{0x41, 0x8A, 0x0C, 0x0E}}, - {x86.R0, 8, x86.R15, x86.R0, x86.Scale1, []byte{0x49, 0x8B, 0x04, 0x07}}, - {x86.R0, 4, x86.R15, x86.R0, x86.Scale1, []byte{0x41, 0x8B, 0x04, 0x07}}, - {x86.R0, 2, x86.R15, x86.R0, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x04, 0x07}}, - {x86.R0, 1, x86.R15, x86.R0, x86.Scale1, []byte{0x41, 0x8A, 0x04, 0x07}}, - } - - for _, pattern := range usagePatterns { - t.Logf("load %dB %s, [%s+%s]", pattern.Length, pattern.Destination, pattern.Base, pattern.OffsetRegister) - code := x86.LoadDynamicRegister(nil, pattern.Destination, pattern.Base, pattern.OffsetRegister, pattern.Scale, pattern.Length) - assert.DeepEqual(t, code, pattern.Code) - } -} - -func TestLoadDynamicRegisterZeroExtend(t *testing.T) { - usagePatterns := []struct { - Destination cpu.Register - Length byte - Base cpu.Register - OffsetRegister cpu.Register - Scale x86.Scale - Code []byte - }{ - - {x86.R15, 2, x86.R0, x86.R15, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x3C, 0x38}}, - {x86.R15, 1, x86.R0, x86.R15, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x3C, 0x38}}, - {x86.R14, 2, x86.R1, x86.R14, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x34, 0x31}}, - {x86.R14, 1, x86.R1, x86.R14, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x34, 0x31}}, - {x86.R13, 2, x86.R2, x86.R13, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x2C, 0x2A}}, - {x86.R13, 1, x86.R2, x86.R13, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x2C, 0x2A}}, - {x86.R12, 2, x86.R3, x86.R12, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x24, 0x23}}, - {x86.R12, 1, x86.R3, x86.R12, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x24, 0x23}}, - {x86.R11, 2, x86.SP, x86.R11, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x1C, 0x1C}}, - {x86.R11, 1, x86.SP, x86.R11, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x1C, 0x1C}}, - {x86.R10, 2, x86.R5, x86.R10, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x54, 0x15, 0x00}}, - {x86.R10, 1, x86.R5, x86.R10, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x54, 0x15, 0x00}}, - {x86.R9, 2, x86.R6, x86.R9, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x0C, 0x0E}}, - {x86.R9, 1, x86.R6, x86.R9, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x0C, 0x0E}}, - {x86.R8, 2, x86.R7, x86.R8, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x04, 0x07}}, - {x86.R8, 1, x86.R7, x86.R8, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x04, 0x07}}, - {x86.R7, 2, x86.R8, x86.R7, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x3C, 0x38}}, - {x86.R7, 1, x86.R8, x86.R7, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x3C, 0x38}}, - {x86.R6, 2, x86.R9, x86.R6, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x34, 0x31}}, - {x86.R6, 1, x86.R9, x86.R6, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x34, 0x31}}, - {x86.R5, 2, x86.R10, x86.R5, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x2C, 0x2A}}, - {x86.R5, 1, x86.R10, x86.R5, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x2C, 0x2A}}, - {x86.SP, 2, x86.R11, x86.SP, x86.Scale1, []byte{0x4A, 0x0F, 0xB7, 0x24, 0x1C}}, - {x86.SP, 1, x86.R11, x86.SP, x86.Scale1, []byte{0x4A, 0x0F, 0xB6, 0x24, 0x1C}}, - {x86.R3, 2, x86.R12, x86.R3, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x1C, 0x1C}}, - {x86.R3, 1, x86.R12, x86.R3, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x1C, 0x1C}}, - {x86.R2, 2, x86.R13, x86.R2, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x54, 0x15, 0x00}}, - {x86.R2, 1, x86.R13, x86.R2, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x54, 0x15, 0x00}}, - {x86.R1, 2, x86.R14, x86.R1, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x0C, 0x0E}}, - {x86.R1, 1, x86.R14, x86.R1, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x0C, 0x0E}}, - {x86.R0, 2, x86.R15, x86.R0, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x04, 0x07}}, - {x86.R0, 1, x86.R15, x86.R0, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x04, 0x07}}, - } - - for _, pattern := range usagePatterns { - t.Logf("loadzx %dB %s, [%s+%s]", pattern.Length, pattern.Destination, pattern.Base, pattern.OffsetRegister) - code := x86.LoadDynamicRegisterZeroExtend(nil, pattern.Destination, pattern.Base, pattern.OffsetRegister, pattern.Scale, pattern.Length) - assert.DeepEqual(t, code, pattern.Code) - } -} \ No newline at end of file diff --git a/src/x86/LoadFixedOffset.go b/src/x86/LoadFixedOffset.go new file mode 100644 index 0000000..b0d0354 --- /dev/null +++ b/src/x86/LoadFixedOffset.go @@ -0,0 +1,8 @@ +package x86 + +import "git.urbach.dev/cli/q/src/cpu" + +// LoadFixedOffset loads from memory with a signed offset from -128 to 127 into a register. +func LoadFixedOffset(code []byte, destination cpu.Register, base cpu.Register, offset int8, scale Scale, length byte) []byte { + return memAccess(code, 0x8A, 0x8B, destination, base, offset, scale, length) +} \ No newline at end of file diff --git a/src/x86/LoadFixedOffset_test.go b/src/x86/LoadFixedOffset_test.go new file mode 100644 index 0000000..0efe108 --- /dev/null +++ b/src/x86/LoadFixedOffset_test.go @@ -0,0 +1,158 @@ +package x86_test + +import ( + "testing" + + "git.urbach.dev/cli/q/src/cpu" + "git.urbach.dev/cli/q/src/x86" + "git.urbach.dev/go/assert" +) + +func TestLoadFixedOffset(t *testing.T) { + usagePatterns := []struct { + Destination cpu.Register + Base cpu.Register + Offset int8 + Length byte + Scale x86.Scale + Code []byte + }{ + // No offset + {x86.R0, x86.R15, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x07}}, + {x86.R0, x86.R15, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x07}}, + {x86.R0, x86.R15, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x07}}, + {x86.R0, x86.R15, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x07}}, + {x86.R1, x86.R14, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x0E}}, + {x86.R1, x86.R14, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x0E}}, + {x86.R1, x86.R14, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x0E}}, + {x86.R1, x86.R14, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x0E}}, + {x86.R2, x86.R13, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x55, 0x00}}, + {x86.R2, x86.R13, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x55, 0x00}}, + {x86.R2, x86.R13, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x55, 0x00}}, + {x86.R2, x86.R13, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x55, 0x00}}, + {x86.R3, x86.R12, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x1C, 0x24}}, + {x86.R3, x86.R12, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x1C, 0x24}}, + {x86.R3, x86.R12, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x1C, 0x24}}, + {x86.R3, x86.R12, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x1C, 0x24}}, + {x86.SP, x86.R11, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x23}}, + {x86.SP, x86.R11, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x23}}, + {x86.SP, x86.R11, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x23}}, + {x86.SP, x86.R11, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x23}}, + {x86.R5, x86.R10, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x2A}}, + {x86.R5, x86.R10, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x2A}}, + {x86.R5, x86.R10, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x2A}}, + {x86.R5, x86.R10, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x2A}}, + {x86.R6, x86.R9, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x31}}, + {x86.R6, x86.R9, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x31}}, + {x86.R6, x86.R9, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x31}}, + {x86.R6, x86.R9, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x31}}, + {x86.R7, x86.R8, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x38}}, + {x86.R7, x86.R8, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x38}}, + {x86.R7, x86.R8, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x38}}, + {x86.R7, x86.R8, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x38}}, + {x86.R8, x86.R7, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x07}}, + {x86.R8, x86.R7, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x07}}, + {x86.R8, x86.R7, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x07}}, + {x86.R8, x86.R7, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x07}}, + {x86.R9, x86.R6, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x0E}}, + {x86.R9, x86.R6, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x0E}}, + {x86.R9, x86.R6, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x0E}}, + {x86.R9, x86.R6, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x0E}}, + {x86.R10, x86.R5, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x55, 0x00}}, + {x86.R10, x86.R5, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x55, 0x00}}, + {x86.R10, x86.R5, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x55, 0x00}}, + {x86.R10, x86.R5, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x55, 0x00}}, + {x86.R11, x86.SP, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x1C, 0x24}}, + {x86.R11, x86.SP, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x1C, 0x24}}, + {x86.R11, x86.SP, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x1C, 0x24}}, + {x86.R11, x86.SP, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x1C, 0x24}}, + {x86.R12, x86.R3, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x23}}, + {x86.R12, x86.R3, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x23}}, + {x86.R12, x86.R3, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x23}}, + {x86.R12, x86.R3, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x23}}, + {x86.R13, x86.R2, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x2A}}, + {x86.R13, x86.R2, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x2A}}, + {x86.R13, x86.R2, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x2A}}, + {x86.R13, x86.R2, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x2A}}, + {x86.R14, x86.R1, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x31}}, + {x86.R14, x86.R1, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x31}}, + {x86.R14, x86.R1, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x31}}, + {x86.R14, x86.R1, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x31}}, + {x86.R15, x86.R0, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x38}}, + {x86.R15, x86.R0, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x38}}, + {x86.R15, x86.R0, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x38}}, + {x86.R15, x86.R0, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x38}}, + + // Offset of 1 + {x86.R0, x86.R15, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x47, 0x01}}, + {x86.R0, x86.R15, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x47, 0x01}}, + {x86.R0, x86.R15, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x47, 0x01}}, + {x86.R0, x86.R15, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x47, 0x01}}, + {x86.R1, x86.R14, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x4E, 0x01}}, + {x86.R1, x86.R14, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x4E, 0x01}}, + {x86.R1, x86.R14, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x4E, 0x01}}, + {x86.R1, x86.R14, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x4E, 0x01}}, + {x86.R2, x86.R13, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x55, 0x01}}, + {x86.R2, x86.R13, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x55, 0x01}}, + {x86.R2, x86.R13, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x55, 0x01}}, + {x86.R2, x86.R13, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x55, 0x01}}, + {x86.R3, x86.R12, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x5C, 0x24, 0x01}}, + {x86.R3, x86.R12, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x5C, 0x24, 0x01}}, + {x86.R3, x86.R12, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x5C, 0x24, 0x01}}, + {x86.R3, x86.R12, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x5C, 0x24, 0x01}}, + {x86.SP, x86.R11, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x63, 0x01}}, + {x86.SP, x86.R11, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x63, 0x01}}, + {x86.SP, x86.R11, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x63, 0x01}}, + {x86.SP, x86.R11, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x63, 0x01}}, + {x86.R5, x86.R10, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x6A, 0x01}}, + {x86.R5, x86.R10, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x6A, 0x01}}, + {x86.R5, x86.R10, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x6A, 0x01}}, + {x86.R5, x86.R10, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x6A, 0x01}}, + {x86.R6, x86.R9, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x71, 0x01}}, + {x86.R6, x86.R9, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x71, 0x01}}, + {x86.R6, x86.R9, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x71, 0x01}}, + {x86.R6, x86.R9, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x71, 0x01}}, + {x86.R7, x86.R8, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x78, 0x01}}, + {x86.R7, x86.R8, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x78, 0x01}}, + {x86.R7, x86.R8, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x78, 0x01}}, + {x86.R7, x86.R8, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x78, 0x01}}, + {x86.R8, x86.R7, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x47, 0x01}}, + {x86.R8, x86.R7, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x47, 0x01}}, + {x86.R8, x86.R7, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x47, 0x01}}, + {x86.R8, x86.R7, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x47, 0x01}}, + {x86.R9, x86.R6, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x4E, 0x01}}, + {x86.R9, x86.R6, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x4E, 0x01}}, + {x86.R9, x86.R6, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x4E, 0x01}}, + {x86.R9, x86.R6, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x4E, 0x01}}, + {x86.R10, x86.R5, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x55, 0x01}}, + {x86.R10, x86.R5, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x55, 0x01}}, + {x86.R10, x86.R5, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x55, 0x01}}, + {x86.R10, x86.R5, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x55, 0x01}}, + {x86.R11, x86.SP, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x5C, 0x24, 0x01}}, + {x86.R11, x86.SP, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x5C, 0x24, 0x01}}, + {x86.R11, x86.SP, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x5C, 0x24, 0x01}}, + {x86.R11, x86.SP, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x5C, 0x24, 0x01}}, + {x86.R12, x86.R3, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x63, 0x01}}, + {x86.R12, x86.R3, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x63, 0x01}}, + {x86.R12, x86.R3, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x63, 0x01}}, + {x86.R12, x86.R3, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x63, 0x01}}, + {x86.R13, x86.R2, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x6A, 0x01}}, + {x86.R13, x86.R2, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x6A, 0x01}}, + {x86.R13, x86.R2, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x6A, 0x01}}, + {x86.R13, x86.R2, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x6A, 0x01}}, + {x86.R14, x86.R1, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x71, 0x01}}, + {x86.R14, x86.R1, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x71, 0x01}}, + {x86.R14, x86.R1, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x71, 0x01}}, + {x86.R14, x86.R1, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x71, 0x01}}, + {x86.R15, x86.R0, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x78, 0x01}}, + {x86.R15, x86.R0, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x78, 0x01}}, + {x86.R15, x86.R0, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x78, 0x01}}, + {x86.R15, x86.R0, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x78, 0x01}}, + } + + for _, pattern := range usagePatterns { + t.Logf("load %dB %s, [%s+%d]", pattern.Length, pattern.Destination, pattern.Base, pattern.Offset) + code := x86.LoadFixedOffset(nil, pattern.Destination, pattern.Base, pattern.Offset, pattern.Scale, pattern.Length) + assert.DeepEqual(t, code, pattern.Code) + } +} \ No newline at end of file diff --git a/src/x86/Load_test.go b/src/x86/Load_test.go index 1ea57ec..16b2f8d 100644 --- a/src/x86/Load_test.go +++ b/src/x86/Load_test.go @@ -8,151 +8,135 @@ import ( "git.urbach.dev/go/assert" ) -func TestLoadRegister(t *testing.T) { +func TestLoad(t *testing.T) { usagePatterns := []struct { - Destination cpu.Register - Base cpu.Register - Offset int8 - Length byte - Scale x86.Scale - Code []byte + Destination cpu.Register + Length byte + Base cpu.Register + OffsetRegister cpu.Register + Scale x86.Scale + Code []byte + }{ + {x86.R15, 8, x86.R0, x86.R15, x86.Scale1, []byte{0x4E, 0x8B, 0x3C, 0x38}}, + {x86.R15, 4, x86.R0, x86.R15, x86.Scale1, []byte{0x46, 0x8B, 0x3C, 0x38}}, + {x86.R15, 2, x86.R0, x86.R15, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x3C, 0x38}}, + {x86.R15, 1, x86.R0, x86.R15, x86.Scale1, []byte{0x46, 0x8A, 0x3C, 0x38}}, + {x86.R14, 8, x86.R1, x86.R14, x86.Scale1, []byte{0x4E, 0x8B, 0x34, 0x31}}, + {x86.R14, 4, x86.R1, x86.R14, x86.Scale1, []byte{0x46, 0x8B, 0x34, 0x31}}, + {x86.R14, 2, x86.R1, x86.R14, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x34, 0x31}}, + {x86.R14, 1, x86.R1, x86.R14, x86.Scale1, []byte{0x46, 0x8A, 0x34, 0x31}}, + {x86.R13, 8, x86.R2, x86.R13, x86.Scale1, []byte{0x4E, 0x8B, 0x2C, 0x2A}}, + {x86.R13, 4, x86.R2, x86.R13, x86.Scale1, []byte{0x46, 0x8B, 0x2C, 0x2A}}, + {x86.R13, 2, x86.R2, x86.R13, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x2C, 0x2A}}, + {x86.R13, 1, x86.R2, x86.R13, x86.Scale1, []byte{0x46, 0x8A, 0x2C, 0x2A}}, + {x86.R12, 8, x86.R3, x86.R12, x86.Scale1, []byte{0x4E, 0x8B, 0x24, 0x23}}, + {x86.R12, 4, x86.R3, x86.R12, x86.Scale1, []byte{0x46, 0x8B, 0x24, 0x23}}, + {x86.R12, 2, x86.R3, x86.R12, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x24, 0x23}}, + {x86.R12, 1, x86.R3, x86.R12, x86.Scale1, []byte{0x46, 0x8A, 0x24, 0x23}}, + {x86.R11, 8, x86.SP, x86.R11, x86.Scale1, []byte{0x4E, 0x8B, 0x1C, 0x1C}}, + {x86.R11, 4, x86.SP, x86.R11, x86.Scale1, []byte{0x46, 0x8B, 0x1C, 0x1C}}, + {x86.R11, 2, x86.SP, x86.R11, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x1C, 0x1C}}, + {x86.R11, 1, x86.SP, x86.R11, x86.Scale1, []byte{0x46, 0x8A, 0x1C, 0x1C}}, + {x86.R10, 8, x86.R5, x86.R10, x86.Scale1, []byte{0x4E, 0x8B, 0x54, 0x15, 0x00}}, + {x86.R10, 4, x86.R5, x86.R10, x86.Scale1, []byte{0x46, 0x8B, 0x54, 0x15, 0x00}}, + {x86.R10, 2, x86.R5, x86.R10, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x54, 0x15, 0x00}}, + {x86.R10, 1, x86.R5, x86.R10, x86.Scale1, []byte{0x46, 0x8A, 0x54, 0x15, 0x00}}, + {x86.R9, 8, x86.R6, x86.R9, x86.Scale1, []byte{0x4E, 0x8B, 0x0C, 0x0E}}, + {x86.R9, 4, x86.R6, x86.R9, x86.Scale1, []byte{0x46, 0x8B, 0x0C, 0x0E}}, + {x86.R9, 2, x86.R6, x86.R9, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x0C, 0x0E}}, + {x86.R9, 1, x86.R6, x86.R9, x86.Scale1, []byte{0x46, 0x8A, 0x0C, 0x0E}}, + {x86.R8, 8, x86.R7, x86.R8, x86.Scale1, []byte{0x4E, 0x8B, 0x04, 0x07}}, + {x86.R8, 4, x86.R7, x86.R8, x86.Scale1, []byte{0x46, 0x8B, 0x04, 0x07}}, + {x86.R8, 2, x86.R7, x86.R8, x86.Scale1, []byte{0x66, 0x46, 0x8B, 0x04, 0x07}}, + {x86.R8, 1, x86.R7, x86.R8, x86.Scale1, []byte{0x46, 0x8A, 0x04, 0x07}}, + {x86.R7, 8, x86.R8, x86.R7, x86.Scale1, []byte{0x49, 0x8B, 0x3C, 0x38}}, + {x86.R7, 4, x86.R8, x86.R7, x86.Scale1, []byte{0x41, 0x8B, 0x3C, 0x38}}, + {x86.R7, 2, x86.R8, x86.R7, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x3C, 0x38}}, + {x86.R7, 1, x86.R8, x86.R7, x86.Scale1, []byte{0x41, 0x8A, 0x3C, 0x38}}, + {x86.R6, 8, x86.R9, x86.R6, x86.Scale1, []byte{0x49, 0x8B, 0x34, 0x31}}, + {x86.R6, 4, x86.R9, x86.R6, x86.Scale1, []byte{0x41, 0x8B, 0x34, 0x31}}, + {x86.R6, 2, x86.R9, x86.R6, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x34, 0x31}}, + {x86.R6, 1, x86.R9, x86.R6, x86.Scale1, []byte{0x41, 0x8A, 0x34, 0x31}}, + {x86.R5, 8, x86.R10, x86.R5, x86.Scale1, []byte{0x49, 0x8B, 0x2C, 0x2A}}, + {x86.R5, 4, x86.R10, x86.R5, x86.Scale1, []byte{0x41, 0x8B, 0x2C, 0x2A}}, + {x86.R5, 2, x86.R10, x86.R5, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x2C, 0x2A}}, + {x86.R5, 1, x86.R10, x86.R5, x86.Scale1, []byte{0x41, 0x8A, 0x2C, 0x2A}}, + {x86.SP, 8, x86.R11, x86.SP, x86.Scale1, []byte{0x4A, 0x8B, 0x24, 0x1C}}, + {x86.SP, 4, x86.R11, x86.SP, x86.Scale1, []byte{0x42, 0x8B, 0x24, 0x1C}}, + {x86.SP, 2, x86.R11, x86.SP, x86.Scale1, []byte{0x66, 0x42, 0x8B, 0x24, 0x1C}}, + {x86.SP, 1, x86.R11, x86.SP, x86.Scale1, []byte{0x42, 0x8A, 0x24, 0x1C}}, + {x86.R3, 8, x86.R12, x86.R3, x86.Scale1, []byte{0x49, 0x8B, 0x1C, 0x1C}}, + {x86.R3, 4, x86.R12, x86.R3, x86.Scale1, []byte{0x41, 0x8B, 0x1C, 0x1C}}, + {x86.R3, 2, x86.R12, x86.R3, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x1C, 0x1C}}, + {x86.R3, 1, x86.R12, x86.R3, x86.Scale1, []byte{0x41, 0x8A, 0x1C, 0x1C}}, + {x86.R2, 8, x86.R13, x86.R2, x86.Scale1, []byte{0x49, 0x8B, 0x54, 0x15, 0x00}}, + {x86.R2, 4, x86.R13, x86.R2, x86.Scale1, []byte{0x41, 0x8B, 0x54, 0x15, 0x00}}, + {x86.R2, 2, x86.R13, x86.R2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x54, 0x15, 0x00}}, + {x86.R2, 1, x86.R13, x86.R2, x86.Scale1, []byte{0x41, 0x8A, 0x54, 0x15, 0x00}}, + {x86.R1, 8, x86.R14, x86.R1, x86.Scale1, []byte{0x49, 0x8B, 0x0C, 0x0E}}, + {x86.R1, 4, x86.R14, x86.R1, x86.Scale1, []byte{0x41, 0x8B, 0x0C, 0x0E}}, + {x86.R1, 2, x86.R14, x86.R1, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x0C, 0x0E}}, + {x86.R1, 1, x86.R14, x86.R1, x86.Scale1, []byte{0x41, 0x8A, 0x0C, 0x0E}}, + {x86.R0, 8, x86.R15, x86.R0, x86.Scale1, []byte{0x49, 0x8B, 0x04, 0x07}}, + {x86.R0, 4, x86.R15, x86.R0, x86.Scale1, []byte{0x41, 0x8B, 0x04, 0x07}}, + {x86.R0, 2, x86.R15, x86.R0, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x04, 0x07}}, + {x86.R0, 1, x86.R15, x86.R0, x86.Scale1, []byte{0x41, 0x8A, 0x04, 0x07}}, + } + + for _, pattern := range usagePatterns { + t.Logf("load %dB %s, [%s+%s]", pattern.Length, pattern.Destination, pattern.Base, pattern.OffsetRegister) + code := x86.Load(nil, pattern.Destination, pattern.Base, pattern.OffsetRegister, pattern.Scale, pattern.Length) + assert.DeepEqual(t, code, pattern.Code) + } +} + +func TestLoadZeroExtend(t *testing.T) { + usagePatterns := []struct { + Destination cpu.Register + Length byte + Base cpu.Register + OffsetRegister cpu.Register + Scale x86.Scale + Code []byte }{ - // No offset - {x86.R0, x86.R15, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x07}}, - {x86.R0, x86.R15, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x07}}, - {x86.R0, x86.R15, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x07}}, - {x86.R0, x86.R15, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x07}}, - {x86.R1, x86.R14, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x0E}}, - {x86.R1, x86.R14, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x0E}}, - {x86.R1, x86.R14, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x0E}}, - {x86.R1, x86.R14, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x0E}}, - {x86.R2, x86.R13, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x55, 0x00}}, - {x86.R2, x86.R13, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x55, 0x00}}, - {x86.R2, x86.R13, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x55, 0x00}}, - {x86.R2, x86.R13, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x55, 0x00}}, - {x86.R3, x86.R12, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x1C, 0x24}}, - {x86.R3, x86.R12, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x1C, 0x24}}, - {x86.R3, x86.R12, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x1C, 0x24}}, - {x86.R3, x86.R12, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x1C, 0x24}}, - {x86.SP, x86.R11, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x23}}, - {x86.SP, x86.R11, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x23}}, - {x86.SP, x86.R11, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x23}}, - {x86.SP, x86.R11, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x23}}, - {x86.R5, x86.R10, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x2A}}, - {x86.R5, x86.R10, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x2A}}, - {x86.R5, x86.R10, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x2A}}, - {x86.R5, x86.R10, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x2A}}, - {x86.R6, x86.R9, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x31}}, - {x86.R6, x86.R9, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x31}}, - {x86.R6, x86.R9, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x31}}, - {x86.R6, x86.R9, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x31}}, - {x86.R7, x86.R8, 0, 8, x86.Scale1, []byte{0x49, 0x8B, 0x38}}, - {x86.R7, x86.R8, 0, 4, x86.Scale1, []byte{0x41, 0x8B, 0x38}}, - {x86.R7, x86.R8, 0, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x38}}, - {x86.R7, x86.R8, 0, 1, x86.Scale1, []byte{0x41, 0x8A, 0x38}}, - {x86.R8, x86.R7, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x07}}, - {x86.R8, x86.R7, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x07}}, - {x86.R8, x86.R7, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x07}}, - {x86.R8, x86.R7, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x07}}, - {x86.R9, x86.R6, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x0E}}, - {x86.R9, x86.R6, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x0E}}, - {x86.R9, x86.R6, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x0E}}, - {x86.R9, x86.R6, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x0E}}, - {x86.R10, x86.R5, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x55, 0x00}}, - {x86.R10, x86.R5, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x55, 0x00}}, - {x86.R10, x86.R5, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x55, 0x00}}, - {x86.R10, x86.R5, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x55, 0x00}}, - {x86.R11, x86.SP, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x1C, 0x24}}, - {x86.R11, x86.SP, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x1C, 0x24}}, - {x86.R11, x86.SP, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x1C, 0x24}}, - {x86.R11, x86.SP, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x1C, 0x24}}, - {x86.R12, x86.R3, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x23}}, - {x86.R12, x86.R3, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x23}}, - {x86.R12, x86.R3, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x23}}, - {x86.R12, x86.R3, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x23}}, - {x86.R13, x86.R2, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x2A}}, - {x86.R13, x86.R2, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x2A}}, - {x86.R13, x86.R2, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x2A}}, - {x86.R13, x86.R2, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x2A}}, - {x86.R14, x86.R1, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x31}}, - {x86.R14, x86.R1, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x31}}, - {x86.R14, x86.R1, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x31}}, - {x86.R14, x86.R1, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x31}}, - {x86.R15, x86.R0, 0, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x38}}, - {x86.R15, x86.R0, 0, 4, x86.Scale1, []byte{0x44, 0x8B, 0x38}}, - {x86.R15, x86.R0, 0, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x38}}, - {x86.R15, x86.R0, 0, 1, x86.Scale1, []byte{0x44, 0x8A, 0x38}}, - // Offset of 1 - {x86.R0, x86.R15, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x47, 0x01}}, - {x86.R0, x86.R15, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x47, 0x01}}, - {x86.R0, x86.R15, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x47, 0x01}}, - {x86.R0, x86.R15, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x47, 0x01}}, - {x86.R1, x86.R14, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x4E, 0x01}}, - {x86.R1, x86.R14, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x4E, 0x01}}, - {x86.R1, x86.R14, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x4E, 0x01}}, - {x86.R1, x86.R14, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x4E, 0x01}}, - {x86.R2, x86.R13, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x55, 0x01}}, - {x86.R2, x86.R13, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x55, 0x01}}, - {x86.R2, x86.R13, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x55, 0x01}}, - {x86.R2, x86.R13, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x55, 0x01}}, - {x86.R3, x86.R12, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x5C, 0x24, 0x01}}, - {x86.R3, x86.R12, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x5C, 0x24, 0x01}}, - {x86.R3, x86.R12, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x5C, 0x24, 0x01}}, - {x86.R3, x86.R12, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x5C, 0x24, 0x01}}, - {x86.SP, x86.R11, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x63, 0x01}}, - {x86.SP, x86.R11, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x63, 0x01}}, - {x86.SP, x86.R11, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x63, 0x01}}, - {x86.SP, x86.R11, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x63, 0x01}}, - {x86.R5, x86.R10, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x6A, 0x01}}, - {x86.R5, x86.R10, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x6A, 0x01}}, - {x86.R5, x86.R10, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x6A, 0x01}}, - {x86.R5, x86.R10, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x6A, 0x01}}, - {x86.R6, x86.R9, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x71, 0x01}}, - {x86.R6, x86.R9, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x71, 0x01}}, - {x86.R6, x86.R9, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x71, 0x01}}, - {x86.R6, x86.R9, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x71, 0x01}}, - {x86.R7, x86.R8, 1, 8, x86.Scale1, []byte{0x49, 0x8B, 0x78, 0x01}}, - {x86.R7, x86.R8, 1, 4, x86.Scale1, []byte{0x41, 0x8B, 0x78, 0x01}}, - {x86.R7, x86.R8, 1, 2, x86.Scale1, []byte{0x66, 0x41, 0x8B, 0x78, 0x01}}, - {x86.R7, x86.R8, 1, 1, x86.Scale1, []byte{0x41, 0x8A, 0x78, 0x01}}, - {x86.R8, x86.R7, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x47, 0x01}}, - {x86.R8, x86.R7, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x47, 0x01}}, - {x86.R8, x86.R7, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x47, 0x01}}, - {x86.R8, x86.R7, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x47, 0x01}}, - {x86.R9, x86.R6, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x4E, 0x01}}, - {x86.R9, x86.R6, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x4E, 0x01}}, - {x86.R9, x86.R6, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x4E, 0x01}}, - {x86.R9, x86.R6, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x4E, 0x01}}, - {x86.R10, x86.R5, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x55, 0x01}}, - {x86.R10, x86.R5, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x55, 0x01}}, - {x86.R10, x86.R5, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x55, 0x01}}, - {x86.R10, x86.R5, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x55, 0x01}}, - {x86.R11, x86.SP, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x5C, 0x24, 0x01}}, - {x86.R11, x86.SP, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x5C, 0x24, 0x01}}, - {x86.R11, x86.SP, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x5C, 0x24, 0x01}}, - {x86.R11, x86.SP, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x5C, 0x24, 0x01}}, - {x86.R12, x86.R3, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x63, 0x01}}, - {x86.R12, x86.R3, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x63, 0x01}}, - {x86.R12, x86.R3, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x63, 0x01}}, - {x86.R12, x86.R3, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x63, 0x01}}, - {x86.R13, x86.R2, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x6A, 0x01}}, - {x86.R13, x86.R2, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x6A, 0x01}}, - {x86.R13, x86.R2, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x6A, 0x01}}, - {x86.R13, x86.R2, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x6A, 0x01}}, - {x86.R14, x86.R1, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x71, 0x01}}, - {x86.R14, x86.R1, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x71, 0x01}}, - {x86.R14, x86.R1, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x71, 0x01}}, - {x86.R14, x86.R1, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x71, 0x01}}, - {x86.R15, x86.R0, 1, 8, x86.Scale1, []byte{0x4C, 0x8B, 0x78, 0x01}}, - {x86.R15, x86.R0, 1, 4, x86.Scale1, []byte{0x44, 0x8B, 0x78, 0x01}}, - {x86.R15, x86.R0, 1, 2, x86.Scale1, []byte{0x66, 0x44, 0x8B, 0x78, 0x01}}, - {x86.R15, x86.R0, 1, 1, x86.Scale1, []byte{0x44, 0x8A, 0x78, 0x01}}, + {x86.R15, 2, x86.R0, x86.R15, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x3C, 0x38}}, + {x86.R15, 1, x86.R0, x86.R15, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x3C, 0x38}}, + {x86.R14, 2, x86.R1, x86.R14, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x34, 0x31}}, + {x86.R14, 1, x86.R1, x86.R14, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x34, 0x31}}, + {x86.R13, 2, x86.R2, x86.R13, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x2C, 0x2A}}, + {x86.R13, 1, x86.R2, x86.R13, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x2C, 0x2A}}, + {x86.R12, 2, x86.R3, x86.R12, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x24, 0x23}}, + {x86.R12, 1, x86.R3, x86.R12, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x24, 0x23}}, + {x86.R11, 2, x86.SP, x86.R11, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x1C, 0x1C}}, + {x86.R11, 1, x86.SP, x86.R11, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x1C, 0x1C}}, + {x86.R10, 2, x86.R5, x86.R10, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x54, 0x15, 0x00}}, + {x86.R10, 1, x86.R5, x86.R10, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x54, 0x15, 0x00}}, + {x86.R9, 2, x86.R6, x86.R9, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x0C, 0x0E}}, + {x86.R9, 1, x86.R6, x86.R9, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x0C, 0x0E}}, + {x86.R8, 2, x86.R7, x86.R8, x86.Scale1, []byte{0x4E, 0x0F, 0xB7, 0x04, 0x07}}, + {x86.R8, 1, x86.R7, x86.R8, x86.Scale1, []byte{0x4E, 0x0F, 0xB6, 0x04, 0x07}}, + {x86.R7, 2, x86.R8, x86.R7, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x3C, 0x38}}, + {x86.R7, 1, x86.R8, x86.R7, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x3C, 0x38}}, + {x86.R6, 2, x86.R9, x86.R6, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x34, 0x31}}, + {x86.R6, 1, x86.R9, x86.R6, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x34, 0x31}}, + {x86.R5, 2, x86.R10, x86.R5, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x2C, 0x2A}}, + {x86.R5, 1, x86.R10, x86.R5, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x2C, 0x2A}}, + {x86.SP, 2, x86.R11, x86.SP, x86.Scale1, []byte{0x4A, 0x0F, 0xB7, 0x24, 0x1C}}, + {x86.SP, 1, x86.R11, x86.SP, x86.Scale1, []byte{0x4A, 0x0F, 0xB6, 0x24, 0x1C}}, + {x86.R3, 2, x86.R12, x86.R3, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x1C, 0x1C}}, + {x86.R3, 1, x86.R12, x86.R3, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x1C, 0x1C}}, + {x86.R2, 2, x86.R13, x86.R2, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x54, 0x15, 0x00}}, + {x86.R2, 1, x86.R13, x86.R2, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x54, 0x15, 0x00}}, + {x86.R1, 2, x86.R14, x86.R1, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x0C, 0x0E}}, + {x86.R1, 1, x86.R14, x86.R1, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x0C, 0x0E}}, + {x86.R0, 2, x86.R15, x86.R0, x86.Scale1, []byte{0x49, 0x0F, 0xB7, 0x04, 0x07}}, + {x86.R0, 1, x86.R15, x86.R0, x86.Scale1, []byte{0x49, 0x0F, 0xB6, 0x04, 0x07}}, } for _, pattern := range usagePatterns { - t.Logf("load %dB %s, [%s+%d]", pattern.Length, pattern.Destination, pattern.Base, pattern.Offset) - code := x86.LoadRegister(nil, pattern.Destination, pattern.Base, pattern.Offset, pattern.Scale, pattern.Length) + t.Logf("loadzx %dB %s, [%s+%s]", pattern.Length, pattern.Destination, pattern.Base, pattern.OffsetRegister) + code := x86.LoadZeroExtend(nil, pattern.Destination, pattern.Base, pattern.OffsetRegister, pattern.Scale, pattern.Length) assert.DeepEqual(t, code, pattern.Code) } } \ No newline at end of file diff --git a/src/x86/Store.go b/src/x86/Store.go index 59d8a4b..2c8cfec 100644 --- a/src/x86/Store.go +++ b/src/x86/Store.go @@ -6,9 +6,9 @@ import ( "git.urbach.dev/cli/q/src/cpu" ) -// StoreNumber writes a number to a memory address. -func StoreNumber(code []byte, base cpu.Register, offset int8, scale Scale, length byte, number int) []byte { - code = memAccess(code, 0xC6, 0xC7, 0b000, base, offset, scale, length) +// StoreNumber writes a number to a memory address with a register offset. +func StoreNumber(code []byte, base cpu.Register, offset cpu.Register, scale Scale, length byte, number int) []byte { + code = memAccessDynamic(code, 0xC6, 0xC7, 0b000, base, offset, scale, length) switch length { case 8, 4: @@ -21,7 +21,7 @@ func StoreNumber(code []byte, base cpu.Register, offset int8, scale Scale, lengt return append(code, byte(number)) } -// StoreRegister writes the contents of the register to a memory address. -func StoreRegister(code []byte, base cpu.Register, offset int8, scale Scale, length byte, register cpu.Register) []byte { - return memAccess(code, 0x88, 0x89, register, base, offset, scale, length) +// StoreRegister writes the contents of a register to a memory address with a register offset. +func StoreRegister(code []byte, base cpu.Register, offset cpu.Register, scale Scale, length byte, source cpu.Register) []byte { + return memAccessDynamic(code, 0x88, 0x89, source, base, offset, scale, length) } \ No newline at end of file diff --git a/src/x86/StoreDynamic.go b/src/x86/StoreDynamic.go deleted file mode 100644 index fb093b3..0000000 --- a/src/x86/StoreDynamic.go +++ /dev/null @@ -1,27 +0,0 @@ -package x86 - -import ( - "encoding/binary" - - "git.urbach.dev/cli/q/src/cpu" -) - -// StoreDynamicNumber writes a number to a memory address with a register offset. -func StoreDynamicNumber(code []byte, base cpu.Register, offset cpu.Register, scale Scale, length byte, number int) []byte { - code = memAccessDynamic(code, 0xC6, 0xC7, 0b000, base, offset, scale, length) - - switch length { - case 8, 4: - return binary.LittleEndian.AppendUint32(code, uint32(number)) - - case 2: - return binary.LittleEndian.AppendUint16(code, uint16(number)) - } - - return append(code, byte(number)) -} - -// StoreDynamicRegister writes the contents of a register to a memory address with a register offset. -func StoreDynamicRegister(code []byte, base cpu.Register, offset cpu.Register, scale Scale, length byte, source cpu.Register) []byte { - return memAccessDynamic(code, 0x88, 0x89, source, base, offset, scale, length) -} \ No newline at end of file diff --git a/src/x86/StoreDynamic_test.go b/src/x86/StoreDynamic_test.go deleted file mode 100644 index a9ad415..0000000 --- a/src/x86/StoreDynamic_test.go +++ /dev/null @@ -1,173 +0,0 @@ -package x86_test - -import ( - "testing" - - "git.urbach.dev/cli/q/src/cpu" - "git.urbach.dev/cli/q/src/x86" - "git.urbach.dev/go/assert" -) - -func TestStoreDynamicNumber(t *testing.T) { - usagePatterns := []struct { - RegisterTo cpu.Register - Offset cpu.Register - Scale x86.Scale - Length byte - Number int - Code []byte - }{ - {x86.R0, x86.R15, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R0, x86.R15, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R0, x86.R15, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x38, 0x7F, 0x00}}, - {x86.R0, x86.R15, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x38, 0x7F}}, - {x86.R1, x86.R14, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R1, x86.R14, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R1, x86.R14, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x31, 0x7F, 0x00}}, - {x86.R1, x86.R14, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x31, 0x7F}}, - {x86.R2, x86.R13, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R2, x86.R13, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R2, x86.R13, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x2A, 0x7F, 0x00}}, - {x86.R2, x86.R13, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x2A, 0x7F}}, - {x86.R3, x86.R12, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x23, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R3, x86.R12, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x23, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R3, x86.R12, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x23, 0x7F, 0x00}}, - {x86.R3, x86.R12, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x23, 0x7F}}, - {x86.SP, x86.R11, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, - {x86.SP, x86.R11, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, - {x86.SP, x86.R11, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00}}, - {x86.SP, x86.R11, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x1C, 0x7F}}, - {x86.R5, x86.R10, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R5, x86.R10, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R5, x86.R10, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00}}, - {x86.R5, x86.R10, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x44, 0x15, 0x00, 0x7F}}, - {x86.R6, x86.R9, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R6, x86.R9, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R6, x86.R9, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x0E, 0x7F, 0x00}}, - {x86.R6, x86.R9, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x0E, 0x7F}}, - {x86.R7, x86.R8, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R7, x86.R8, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R7, x86.R8, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x07, 0x7F, 0x00}}, - {x86.R7, x86.R8, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x07, 0x7F}}, - {x86.R8, x86.R7, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R8, x86.R7, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R8, x86.R7, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x38, 0x7F, 0x00}}, - {x86.R8, x86.R7, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x38, 0x7F}}, - {x86.R9, x86.R6, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R9, x86.R6, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R9, x86.R6, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x31, 0x7F, 0x00}}, - {x86.R9, x86.R6, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x31, 0x7F}}, - {x86.R10, x86.R5, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R10, x86.R5, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R10, x86.R5, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x2A, 0x7F, 0x00}}, - {x86.R10, x86.R5, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x2A, 0x7F}}, - {x86.R11, x86.SP, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R11, x86.SP, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R11, x86.SP, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00}}, - {x86.R11, x86.SP, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x1C, 0x7F}}, - {x86.R12, x86.R3, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R12, x86.R3, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R12, x86.R3, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x1C, 0x7F, 0x00}}, - {x86.R12, x86.R3, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x1C, 0x7F}}, - {x86.R13, x86.R2, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R13, x86.R2, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R13, x86.R2, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00}}, - {x86.R13, x86.R2, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x44, 0x15, 0x00, 0x7F}}, - {x86.R14, x86.R1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R14, x86.R1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R14, x86.R1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x0E, 0x7F, 0x00}}, - {x86.R14, x86.R1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x0E, 0x7F}}, - {x86.R15, x86.R0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R15, x86.R0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R15, x86.R0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x07, 0x7F, 0x00}}, - {x86.R15, x86.R0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x07, 0x7F}}, - } - - for _, pattern := range usagePatterns { - t.Logf("store %dB [%s+%s], %d", pattern.Length, pattern.RegisterTo, pattern.Offset, pattern.Number) - code := x86.StoreDynamicNumber(nil, pattern.RegisterTo, pattern.Offset, pattern.Scale, pattern.Length, pattern.Number) - assert.DeepEqual(t, code, pattern.Code) - } -} - -func TestStoreDynamicRegister(t *testing.T) { - usagePatterns := []struct { - RegisterTo cpu.Register - Offset cpu.Register - Scale x86.Scale - Length byte - RegisterFrom cpu.Register - Code []byte - }{ - {x86.R0, x86.R15, x86.Scale1, 8, x86.R15, []byte{0x4E, 0x89, 0x3C, 0x38}}, - {x86.R0, x86.R15, x86.Scale1, 4, x86.R15, []byte{0x46, 0x89, 0x3C, 0x38}}, - {x86.R0, x86.R15, x86.Scale1, 2, x86.R15, []byte{0x66, 0x46, 0x89, 0x3C, 0x38}}, - {x86.R0, x86.R15, x86.Scale1, 1, x86.R15, []byte{0x46, 0x88, 0x3C, 0x38}}, - {x86.R1, x86.R14, x86.Scale1, 8, x86.R14, []byte{0x4E, 0x89, 0x34, 0x31}}, - {x86.R1, x86.R14, x86.Scale1, 4, x86.R14, []byte{0x46, 0x89, 0x34, 0x31}}, - {x86.R1, x86.R14, x86.Scale1, 2, x86.R14, []byte{0x66, 0x46, 0x89, 0x34, 0x31}}, - {x86.R1, x86.R14, x86.Scale1, 1, x86.R14, []byte{0x46, 0x88, 0x34, 0x31}}, - {x86.R2, x86.R13, x86.Scale1, 8, x86.R13, []byte{0x4E, 0x89, 0x2C, 0x2A}}, - {x86.R2, x86.R13, x86.Scale1, 4, x86.R13, []byte{0x46, 0x89, 0x2C, 0x2A}}, - {x86.R2, x86.R13, x86.Scale1, 2, x86.R13, []byte{0x66, 0x46, 0x89, 0x2C, 0x2A}}, - {x86.R2, x86.R13, x86.Scale1, 1, x86.R13, []byte{0x46, 0x88, 0x2C, 0x2A}}, - {x86.R3, x86.R12, x86.Scale1, 8, x86.R12, []byte{0x4E, 0x89, 0x24, 0x23}}, - {x86.R3, x86.R12, x86.Scale1, 4, x86.R12, []byte{0x46, 0x89, 0x24, 0x23}}, - {x86.R3, x86.R12, x86.Scale1, 2, x86.R12, []byte{0x66, 0x46, 0x89, 0x24, 0x23}}, - {x86.R3, x86.R12, x86.Scale1, 1, x86.R12, []byte{0x46, 0x88, 0x24, 0x23}}, - {x86.SP, x86.R11, x86.Scale1, 8, x86.R11, []byte{0x4E, 0x89, 0x1C, 0x1C}}, - {x86.SP, x86.R11, x86.Scale1, 4, x86.R11, []byte{0x46, 0x89, 0x1C, 0x1C}}, - {x86.SP, x86.R11, x86.Scale1, 2, x86.R11, []byte{0x66, 0x46, 0x89, 0x1C, 0x1C}}, - {x86.SP, x86.R11, x86.Scale1, 1, x86.R11, []byte{0x46, 0x88, 0x1C, 0x1C}}, - {x86.R5, x86.R10, x86.Scale1, 8, x86.R10, []byte{0x4E, 0x89, 0x54, 0x15, 0x00}}, - {x86.R5, x86.R10, x86.Scale1, 4, x86.R10, []byte{0x46, 0x89, 0x54, 0x15, 0x00}}, - {x86.R5, x86.R10, x86.Scale1, 2, x86.R10, []byte{0x66, 0x46, 0x89, 0x54, 0x15, 0x00}}, - {x86.R5, x86.R10, x86.Scale1, 1, x86.R10, []byte{0x46, 0x88, 0x54, 0x15, 0x00}}, - {x86.R6, x86.R9, x86.Scale1, 8, x86.R9, []byte{0x4E, 0x89, 0x0C, 0x0E}}, - {x86.R6, x86.R9, x86.Scale1, 4, x86.R9, []byte{0x46, 0x89, 0x0C, 0x0E}}, - {x86.R6, x86.R9, x86.Scale1, 2, x86.R9, []byte{0x66, 0x46, 0x89, 0x0C, 0x0E}}, - {x86.R6, x86.R9, x86.Scale1, 1, x86.R9, []byte{0x46, 0x88, 0x0C, 0x0E}}, - {x86.R7, x86.R8, x86.Scale1, 8, x86.R8, []byte{0x4E, 0x89, 0x04, 0x07}}, - {x86.R7, x86.R8, x86.Scale1, 4, x86.R8, []byte{0x46, 0x89, 0x04, 0x07}}, - {x86.R7, x86.R8, x86.Scale1, 2, x86.R8, []byte{0x66, 0x46, 0x89, 0x04, 0x07}}, - {x86.R7, x86.R8, x86.Scale1, 1, x86.R8, []byte{0x46, 0x88, 0x04, 0x07}}, - {x86.R8, x86.R7, x86.Scale1, 8, x86.R7, []byte{0x49, 0x89, 0x3C, 0x38}}, - {x86.R8, x86.R7, x86.Scale1, 4, x86.R7, []byte{0x41, 0x89, 0x3C, 0x38}}, - {x86.R8, x86.R7, x86.Scale1, 2, x86.R7, []byte{0x66, 0x41, 0x89, 0x3C, 0x38}}, - {x86.R8, x86.R7, x86.Scale1, 1, x86.R7, []byte{0x41, 0x88, 0x3C, 0x38}}, - {x86.R9, x86.R6, x86.Scale1, 8, x86.R6, []byte{0x49, 0x89, 0x34, 0x31}}, - {x86.R9, x86.R6, x86.Scale1, 4, x86.R6, []byte{0x41, 0x89, 0x34, 0x31}}, - {x86.R9, x86.R6, x86.Scale1, 2, x86.R6, []byte{0x66, 0x41, 0x89, 0x34, 0x31}}, - {x86.R9, x86.R6, x86.Scale1, 1, x86.R6, []byte{0x41, 0x88, 0x34, 0x31}}, - {x86.R10, x86.R5, x86.Scale1, 8, x86.R5, []byte{0x49, 0x89, 0x2C, 0x2A}}, - {x86.R10, x86.R5, x86.Scale1, 4, x86.R5, []byte{0x41, 0x89, 0x2C, 0x2A}}, - {x86.R10, x86.R5, x86.Scale1, 2, x86.R5, []byte{0x66, 0x41, 0x89, 0x2C, 0x2A}}, - {x86.R10, x86.R5, x86.Scale1, 1, x86.R5, []byte{0x41, 0x88, 0x2C, 0x2A}}, - {x86.R11, x86.SP, x86.Scale1, 8, x86.SP, []byte{0x4A, 0x89, 0x24, 0x1C}}, - {x86.R11, x86.SP, x86.Scale1, 4, x86.SP, []byte{0x42, 0x89, 0x24, 0x1C}}, - {x86.R11, x86.SP, x86.Scale1, 2, x86.SP, []byte{0x66, 0x42, 0x89, 0x24, 0x1C}}, - {x86.R11, x86.SP, x86.Scale1, 1, x86.SP, []byte{0x42, 0x88, 0x24, 0x1C}}, - {x86.R12, x86.R3, x86.Scale1, 8, x86.R3, []byte{0x49, 0x89, 0x1C, 0x1C}}, - {x86.R12, x86.R3, x86.Scale1, 4, x86.R3, []byte{0x41, 0x89, 0x1C, 0x1C}}, - {x86.R12, x86.R3, x86.Scale1, 2, x86.R3, []byte{0x66, 0x41, 0x89, 0x1C, 0x1C}}, - {x86.R12, x86.R3, x86.Scale1, 1, x86.R3, []byte{0x41, 0x88, 0x1C, 0x1C}}, - {x86.R13, x86.R2, x86.Scale1, 8, x86.R2, []byte{0x49, 0x89, 0x54, 0x15, 0x00}}, - {x86.R13, x86.R2, x86.Scale1, 4, x86.R2, []byte{0x41, 0x89, 0x54, 0x15, 0x00}}, - {x86.R13, x86.R2, x86.Scale1, 2, x86.R2, []byte{0x66, 0x41, 0x89, 0x54, 0x15, 0x00}}, - {x86.R13, x86.R2, x86.Scale1, 1, x86.R2, []byte{0x41, 0x88, 0x54, 0x15, 0x00}}, - {x86.R14, x86.R1, x86.Scale1, 8, x86.R1, []byte{0x49, 0x89, 0x0C, 0x0E}}, - {x86.R14, x86.R1, x86.Scale1, 4, x86.R1, []byte{0x41, 0x89, 0x0C, 0x0E}}, - {x86.R14, x86.R1, x86.Scale1, 2, x86.R1, []byte{0x66, 0x41, 0x89, 0x0C, 0x0E}}, - {x86.R14, x86.R1, x86.Scale1, 1, x86.R1, []byte{0x41, 0x88, 0x0C, 0x0E}}, - {x86.R15, x86.R0, x86.Scale1, 8, x86.R0, []byte{0x49, 0x89, 0x04, 0x07}}, - {x86.R15, x86.R0, x86.Scale1, 4, x86.R0, []byte{0x41, 0x89, 0x04, 0x07}}, - {x86.R15, x86.R0, x86.Scale1, 2, x86.R0, []byte{0x66, 0x41, 0x89, 0x04, 0x07}}, - {x86.R15, x86.R0, x86.Scale1, 1, x86.R0, []byte{0x41, 0x88, 0x04, 0x07}}, - } - - for _, pattern := range usagePatterns { - t.Logf("store %dB [%s+%s], %s", pattern.Length, pattern.RegisterTo, pattern.Offset, pattern.RegisterFrom) - code := x86.StoreDynamicRegister(nil, pattern.RegisterTo, pattern.Offset, pattern.Scale, pattern.Length, pattern.RegisterFrom) - assert.DeepEqual(t, code, pattern.Code) - } -} \ No newline at end of file diff --git a/src/x86/StoreFixedOffset.go b/src/x86/StoreFixedOffset.go new file mode 100644 index 0000000..464413f --- /dev/null +++ b/src/x86/StoreFixedOffset.go @@ -0,0 +1,27 @@ +package x86 + +import ( + "encoding/binary" + + "git.urbach.dev/cli/q/src/cpu" +) + +// StoreFixedOffsetNumber writes a number to a memory address. +func StoreFixedOffsetNumber(code []byte, base cpu.Register, offset int8, scale Scale, length byte, number int) []byte { + code = memAccess(code, 0xC6, 0xC7, 0b000, base, offset, scale, length) + + switch length { + case 8, 4: + return binary.LittleEndian.AppendUint32(code, uint32(number)) + + case 2: + return binary.LittleEndian.AppendUint16(code, uint16(number)) + } + + return append(code, byte(number)) +} + +// StoreFixedOffsetRegister writes the contents of the register to a memory address. +func StoreFixedOffsetRegister(code []byte, base cpu.Register, offset int8, scale Scale, length byte, register cpu.Register) []byte { + return memAccess(code, 0x88, 0x89, register, base, offset, scale, length) +} \ No newline at end of file diff --git a/src/x86/StoreFixedOffset_test.go b/src/x86/StoreFixedOffset_test.go new file mode 100644 index 0000000..bd6faab --- /dev/null +++ b/src/x86/StoreFixedOffset_test.go @@ -0,0 +1,307 @@ +package x86_test + +import ( + "testing" + + "git.urbach.dev/cli/q/src/cpu" + "git.urbach.dev/cli/q/src/x86" + "git.urbach.dev/go/assert" +) + +func TestStoreFixedOffsetNumber(t *testing.T) { + usagePatterns := []struct { + Register cpu.Register + Offset int8 + Scale x86.Scale + Length byte + Number int + Code []byte + }{ + // No offset + {x86.R0, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R0, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R0, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x00, 0x7F, 0x00}}, + {x86.R0, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x00, 0x7F}}, + {x86.R1, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R1, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R1, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x01, 0x7F, 0x00}}, + {x86.R1, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x01, 0x7F}}, + {x86.R2, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R2, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R2, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x02, 0x7F, 0x00}}, + {x86.R2, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x02, 0x7F}}, + {x86.R3, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R3, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R3, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x03, 0x7F, 0x00}}, + {x86.R3, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x03, 0x7F}}, + {x86.SP, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}}, + {x86.SP, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}}, + {x86.SP, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x04, 0x24, 0x7F, 0x00}}, + {x86.SP, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x04, 0x24, 0x7F}}, + {x86.R5, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R5, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R5, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x45, 0x00, 0x7F, 0x00}}, + {x86.R5, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x45, 0x00, 0x7F}}, + {x86.R6, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R6, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R6, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x06, 0x7F, 0x00}}, + {x86.R6, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x06, 0x7F}}, + {x86.R7, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R7, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R7, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x07, 0x7F, 0x00}}, + {x86.R7, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x07, 0x7F}}, + {x86.R8, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R8, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R8, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x00, 0x7F, 0x00}}, + {x86.R8, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x00, 0x7F}}, + {x86.R9, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R9, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R9, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x01, 0x7F, 0x00}}, + {x86.R9, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x01, 0x7F}}, + {x86.R10, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R10, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R10, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x02, 0x7F, 0x00}}, + {x86.R10, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x02, 0x7F}}, + {x86.R11, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R11, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R11, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x03, 0x7F, 0x00}}, + {x86.R11, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x03, 0x7F}}, + {x86.R12, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R12, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R12, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x24, 0x7F, 0x00}}, + {x86.R12, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x24, 0x7F}}, + {x86.R13, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R13, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R13, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x45, 0x00, 0x7F, 0x00}}, + {x86.R13, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x45, 0x00, 0x7F}}, + {x86.R14, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R14, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R14, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x06, 0x7F, 0x00}}, + {x86.R14, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x06, 0x7F}}, + {x86.R15, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R15, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R15, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x07, 0x7F, 0x00}}, + {x86.R15, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x07, 0x7F}}, + + // Offset of 1 + {x86.R0, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R0, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R0, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x40, 0x01, 0x7F, 0x00}}, + {x86.R0, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x40, 0x01, 0x7F}}, + {x86.R1, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R1, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R1, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x41, 0x01, 0x7F, 0x00}}, + {x86.R1, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x41, 0x01, 0x7F}}, + {x86.R2, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R2, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R2, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x42, 0x01, 0x7F, 0x00}}, + {x86.R2, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x42, 0x01, 0x7F}}, + {x86.R3, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R3, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R3, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x43, 0x01, 0x7F, 0x00}}, + {x86.R3, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x43, 0x01, 0x7F}}, + {x86.SP, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.SP, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.SP, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00}}, + {x86.SP, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x44, 0x24, 0x01, 0x7F}}, + {x86.R5, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R5, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R5, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x45, 0x01, 0x7F, 0x00}}, + {x86.R5, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x45, 0x01, 0x7F}}, + {x86.R6, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R6, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R6, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x46, 0x01, 0x7F, 0x00}}, + {x86.R6, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x46, 0x01, 0x7F}}, + {x86.R7, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R7, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R7, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x47, 0x01, 0x7F, 0x00}}, + {x86.R7, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x47, 0x01, 0x7F}}, + {x86.R8, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R8, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R8, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x40, 0x01, 0x7F, 0x00}}, + {x86.R8, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x40, 0x01, 0x7F}}, + {x86.R9, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R9, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R9, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x41, 0x01, 0x7F, 0x00}}, + {x86.R9, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x41, 0x01, 0x7F}}, + {x86.R10, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R10, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R10, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x42, 0x01, 0x7F, 0x00}}, + {x86.R10, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x42, 0x01, 0x7F}}, + {x86.R11, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R11, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R11, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x43, 0x01, 0x7F, 0x00}}, + {x86.R11, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x43, 0x01, 0x7F}}, + {x86.R12, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R12, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R12, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00}}, + {x86.R12, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x44, 0x24, 0x01, 0x7F}}, + {x86.R13, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R13, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R13, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x45, 0x01, 0x7F, 0x00}}, + {x86.R13, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x45, 0x01, 0x7F}}, + {x86.R14, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R14, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R14, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x46, 0x01, 0x7F, 0x00}}, + {x86.R14, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x46, 0x01, 0x7F}}, + {x86.R15, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R15, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R15, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x47, 0x01, 0x7F, 0x00}}, + {x86.R15, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x47, 0x01, 0x7F}}, + } + + for _, pattern := range usagePatterns { + t.Logf("store %dB [%s+%d], %d", pattern.Length, pattern.Register, pattern.Offset, pattern.Number) + code := x86.StoreFixedOffsetNumber(nil, pattern.Register, pattern.Offset, pattern.Scale, pattern.Length, pattern.Number) + assert.DeepEqual(t, code, pattern.Code) + } +} + +func TestStoreFixedOffsetRegister(t *testing.T) { + usagePatterns := []struct { + RegisterTo cpu.Register + Offset int8 + Scale x86.Scale + Length byte + RegisterFrom cpu.Register + Code []byte + }{ + // No offset + {x86.R0, 0, x86.Scale1, 8, x86.R15, []byte{0x4C, 0x89, 0x38}}, + {x86.R0, 0, x86.Scale1, 4, x86.R15, []byte{0x44, 0x89, 0x38}}, + {x86.R0, 0, x86.Scale1, 2, x86.R15, []byte{0x66, 0x44, 0x89, 0x38}}, + {x86.R0, 0, x86.Scale1, 1, x86.R15, []byte{0x44, 0x88, 0x38}}, + {x86.R1, 0, x86.Scale1, 8, x86.R14, []byte{0x4C, 0x89, 0x31}}, + {x86.R1, 0, x86.Scale1, 4, x86.R14, []byte{0x44, 0x89, 0x31}}, + {x86.R1, 0, x86.Scale1, 2, x86.R14, []byte{0x66, 0x44, 0x89, 0x31}}, + {x86.R1, 0, x86.Scale1, 1, x86.R14, []byte{0x44, 0x88, 0x31}}, + {x86.R2, 0, x86.Scale1, 8, x86.R13, []byte{0x4C, 0x89, 0x2A}}, + {x86.R2, 0, x86.Scale1, 4, x86.R13, []byte{0x44, 0x89, 0x2A}}, + {x86.R2, 0, x86.Scale1, 2, x86.R13, []byte{0x66, 0x44, 0x89, 0x2A}}, + {x86.R2, 0, x86.Scale1, 1, x86.R13, []byte{0x44, 0x88, 0x2A}}, + {x86.R3, 0, x86.Scale1, 8, x86.R12, []byte{0x4C, 0x89, 0x23}}, + {x86.R3, 0, x86.Scale1, 4, x86.R12, []byte{0x44, 0x89, 0x23}}, + {x86.R3, 0, x86.Scale1, 2, x86.R12, []byte{0x66, 0x44, 0x89, 0x23}}, + {x86.R3, 0, x86.Scale1, 1, x86.R12, []byte{0x44, 0x88, 0x23}}, + {x86.SP, 0, x86.Scale1, 8, x86.R11, []byte{0x4C, 0x89, 0x1C, 0x24}}, + {x86.SP, 0, x86.Scale1, 4, x86.R11, []byte{0x44, 0x89, 0x1C, 0x24}}, + {x86.SP, 0, x86.Scale1, 2, x86.R11, []byte{0x66, 0x44, 0x89, 0x1C, 0x24}}, + {x86.SP, 0, x86.Scale1, 1, x86.R11, []byte{0x44, 0x88, 0x1C, 0x24}}, + {x86.R5, 0, x86.Scale1, 8, x86.R10, []byte{0x4C, 0x89, 0x55, 0x00}}, + {x86.R5, 0, x86.Scale1, 4, x86.R10, []byte{0x44, 0x89, 0x55, 0x00}}, + {x86.R5, 0, x86.Scale1, 2, x86.R10, []byte{0x66, 0x44, 0x89, 0x55, 0x00}}, + {x86.R5, 0, x86.Scale1, 1, x86.R10, []byte{0x44, 0x88, 0x55, 0x00}}, + {x86.R6, 0, x86.Scale1, 8, x86.R9, []byte{0x4C, 0x89, 0x0E}}, + {x86.R6, 0, x86.Scale1, 4, x86.R9, []byte{0x44, 0x89, 0x0E}}, + {x86.R6, 0, x86.Scale1, 2, x86.R9, []byte{0x66, 0x44, 0x89, 0x0E}}, + {x86.R6, 0, x86.Scale1, 1, x86.R9, []byte{0x44, 0x88, 0x0E}}, + {x86.R7, 0, x86.Scale1, 8, x86.R8, []byte{0x4C, 0x89, 0x07}}, + {x86.R7, 0, x86.Scale1, 4, x86.R8, []byte{0x44, 0x89, 0x07}}, + {x86.R7, 0, x86.Scale1, 2, x86.R8, []byte{0x66, 0x44, 0x89, 0x07}}, + {x86.R7, 0, x86.Scale1, 1, x86.R8, []byte{0x44, 0x88, 0x07}}, + {x86.R8, 0, x86.Scale1, 8, x86.R7, []byte{0x49, 0x89, 0x38}}, + {x86.R8, 0, x86.Scale1, 4, x86.R7, []byte{0x41, 0x89, 0x38}}, + {x86.R8, 0, x86.Scale1, 2, x86.R7, []byte{0x66, 0x41, 0x89, 0x38}}, + {x86.R8, 0, x86.Scale1, 1, x86.R7, []byte{0x41, 0x88, 0x38}}, + {x86.R9, 0, x86.Scale1, 8, x86.R6, []byte{0x49, 0x89, 0x31}}, + {x86.R9, 0, x86.Scale1, 4, x86.R6, []byte{0x41, 0x89, 0x31}}, + {x86.R9, 0, x86.Scale1, 2, x86.R6, []byte{0x66, 0x41, 0x89, 0x31}}, + {x86.R9, 0, x86.Scale1, 1, x86.R6, []byte{0x41, 0x88, 0x31}}, + {x86.R10, 0, x86.Scale1, 8, x86.R5, []byte{0x49, 0x89, 0x2A}}, + {x86.R10, 0, x86.Scale1, 4, x86.R5, []byte{0x41, 0x89, 0x2A}}, + {x86.R10, 0, x86.Scale1, 2, x86.R5, []byte{0x66, 0x41, 0x89, 0x2A}}, + {x86.R10, 0, x86.Scale1, 1, x86.R5, []byte{0x41, 0x88, 0x2A}}, + {x86.R11, 0, x86.Scale1, 8, x86.SP, []byte{0x49, 0x89, 0x23}}, + {x86.R11, 0, x86.Scale1, 4, x86.SP, []byte{0x41, 0x89, 0x23}}, + {x86.R11, 0, x86.Scale1, 2, x86.SP, []byte{0x66, 0x41, 0x89, 0x23}}, + {x86.R11, 0, x86.Scale1, 1, x86.SP, []byte{0x41, 0x88, 0x23}}, + {x86.R12, 0, x86.Scale1, 8, x86.R3, []byte{0x49, 0x89, 0x1C, 0x24}}, + {x86.R12, 0, x86.Scale1, 4, x86.R3, []byte{0x41, 0x89, 0x1C, 0x24}}, + {x86.R12, 0, x86.Scale1, 2, x86.R3, []byte{0x66, 0x41, 0x89, 0x1C, 0x24}}, + {x86.R12, 0, x86.Scale1, 1, x86.R3, []byte{0x41, 0x88, 0x1C, 0x24}}, + {x86.R13, 0, x86.Scale1, 8, x86.R2, []byte{0x49, 0x89, 0x55, 0x00}}, + {x86.R13, 0, x86.Scale1, 4, x86.R2, []byte{0x41, 0x89, 0x55, 0x00}}, + {x86.R13, 0, x86.Scale1, 2, x86.R2, []byte{0x66, 0x41, 0x89, 0x55, 0x00}}, + {x86.R13, 0, x86.Scale1, 1, x86.R2, []byte{0x41, 0x88, 0x55, 0x00}}, + {x86.R14, 0, x86.Scale1, 8, x86.R1, []byte{0x49, 0x89, 0x0E}}, + {x86.R14, 0, x86.Scale1, 4, x86.R1, []byte{0x41, 0x89, 0x0E}}, + {x86.R14, 0, x86.Scale1, 2, x86.R1, []byte{0x66, 0x41, 0x89, 0x0E}}, + {x86.R14, 0, x86.Scale1, 1, x86.R1, []byte{0x41, 0x88, 0x0E}}, + {x86.R15, 0, x86.Scale1, 8, x86.R0, []byte{0x49, 0x89, 0x07}}, + {x86.R15, 0, x86.Scale1, 4, x86.R0, []byte{0x41, 0x89, 0x07}}, + {x86.R15, 0, x86.Scale1, 2, x86.R0, []byte{0x66, 0x41, 0x89, 0x07}}, + {x86.R15, 0, x86.Scale1, 1, x86.R0, []byte{0x41, 0x88, 0x07}}, + + // Offset of 1 + {x86.R0, 1, x86.Scale1, 8, x86.R15, []byte{0x4C, 0x89, 0x78, 0x01}}, + {x86.R0, 1, x86.Scale1, 4, x86.R15, []byte{0x44, 0x89, 0x78, 0x01}}, + {x86.R0, 1, x86.Scale1, 2, x86.R15, []byte{0x66, 0x44, 0x89, 0x78, 0x01}}, + {x86.R0, 1, x86.Scale1, 1, x86.R15, []byte{0x44, 0x88, 0x78, 0x01}}, + {x86.R1, 1, x86.Scale1, 8, x86.R14, []byte{0x4C, 0x89, 0x71, 0x01}}, + {x86.R1, 1, x86.Scale1, 4, x86.R14, []byte{0x44, 0x89, 0x71, 0x01}}, + {x86.R1, 1, x86.Scale1, 2, x86.R14, []byte{0x66, 0x44, 0x89, 0x71, 0x01}}, + {x86.R1, 1, x86.Scale1, 1, x86.R14, []byte{0x44, 0x88, 0x71, 0x01}}, + {x86.R2, 1, x86.Scale1, 8, x86.R13, []byte{0x4C, 0x89, 0x6A, 0x01}}, + {x86.R2, 1, x86.Scale1, 4, x86.R13, []byte{0x44, 0x89, 0x6A, 0x01}}, + {x86.R2, 1, x86.Scale1, 2, x86.R13, []byte{0x66, 0x44, 0x89, 0x6A, 0x01}}, + {x86.R2, 1, x86.Scale1, 1, x86.R13, []byte{0x44, 0x88, 0x6A, 0x01}}, + {x86.R3, 1, x86.Scale1, 8, x86.R12, []byte{0x4C, 0x89, 0x63, 0x01}}, + {x86.R3, 1, x86.Scale1, 4, x86.R12, []byte{0x44, 0x89, 0x63, 0x01}}, + {x86.R3, 1, x86.Scale1, 2, x86.R12, []byte{0x66, 0x44, 0x89, 0x63, 0x01}}, + {x86.R3, 1, x86.Scale1, 1, x86.R12, []byte{0x44, 0x88, 0x63, 0x01}}, + {x86.SP, 1, x86.Scale1, 8, x86.R11, []byte{0x4C, 0x89, 0x5C, 0x24, 0x01}}, + {x86.SP, 1, x86.Scale1, 4, x86.R11, []byte{0x44, 0x89, 0x5C, 0x24, 0x01}}, + {x86.SP, 1, x86.Scale1, 2, x86.R11, []byte{0x66, 0x44, 0x89, 0x5C, 0x24, 0x01}}, + {x86.SP, 1, x86.Scale1, 1, x86.R11, []byte{0x44, 0x88, 0x5C, 0x24, 0x01}}, + {x86.R5, 1, x86.Scale1, 8, x86.R10, []byte{0x4C, 0x89, 0x55, 0x01}}, + {x86.R5, 1, x86.Scale1, 4, x86.R10, []byte{0x44, 0x89, 0x55, 0x01}}, + {x86.R5, 1, x86.Scale1, 2, x86.R10, []byte{0x66, 0x44, 0x89, 0x55, 0x01}}, + {x86.R5, 1, x86.Scale1, 1, x86.R10, []byte{0x44, 0x88, 0x55, 0x01}}, + {x86.R6, 1, x86.Scale1, 8, x86.R9, []byte{0x4C, 0x89, 0x4E, 0x01}}, + {x86.R6, 1, x86.Scale1, 4, x86.R9, []byte{0x44, 0x89, 0x4E, 0x01}}, + {x86.R6, 1, x86.Scale1, 2, x86.R9, []byte{0x66, 0x44, 0x89, 0x4E, 0x01}}, + {x86.R6, 1, x86.Scale1, 1, x86.R9, []byte{0x44, 0x88, 0x4E, 0x01}}, + {x86.R7, 1, x86.Scale1, 8, x86.R8, []byte{0x4C, 0x89, 0x47, 0x01}}, + {x86.R7, 1, x86.Scale1, 4, x86.R8, []byte{0x44, 0x89, 0x47, 0x01}}, + {x86.R7, 1, x86.Scale1, 2, x86.R8, []byte{0x66, 0x44, 0x89, 0x47, 0x01}}, + {x86.R7, 1, x86.Scale1, 1, x86.R8, []byte{0x44, 0x88, 0x47, 0x01}}, + {x86.R8, 1, x86.Scale1, 8, x86.R7, []byte{0x49, 0x89, 0x78, 0x01}}, + {x86.R8, 1, x86.Scale1, 4, x86.R7, []byte{0x41, 0x89, 0x78, 0x01}}, + {x86.R8, 1, x86.Scale1, 2, x86.R7, []byte{0x66, 0x41, 0x89, 0x78, 0x01}}, + {x86.R8, 1, x86.Scale1, 1, x86.R7, []byte{0x41, 0x88, 0x78, 0x01}}, + {x86.R9, 1, x86.Scale1, 8, x86.R6, []byte{0x49, 0x89, 0x71, 0x01}}, + {x86.R9, 1, x86.Scale1, 4, x86.R6, []byte{0x41, 0x89, 0x71, 0x01}}, + {x86.R9, 1, x86.Scale1, 2, x86.R6, []byte{0x66, 0x41, 0x89, 0x71, 0x01}}, + {x86.R9, 1, x86.Scale1, 1, x86.R6, []byte{0x41, 0x88, 0x71, 0x01}}, + {x86.R10, 1, x86.Scale1, 8, x86.R5, []byte{0x49, 0x89, 0x6A, 0x01}}, + {x86.R10, 1, x86.Scale1, 4, x86.R5, []byte{0x41, 0x89, 0x6A, 0x01}}, + {x86.R10, 1, x86.Scale1, 2, x86.R5, []byte{0x66, 0x41, 0x89, 0x6A, 0x01}}, + {x86.R10, 1, x86.Scale1, 1, x86.R5, []byte{0x41, 0x88, 0x6A, 0x01}}, + {x86.R11, 1, x86.Scale1, 8, x86.SP, []byte{0x49, 0x89, 0x63, 0x01}}, + {x86.R11, 1, x86.Scale1, 4, x86.SP, []byte{0x41, 0x89, 0x63, 0x01}}, + {x86.R11, 1, x86.Scale1, 2, x86.SP, []byte{0x66, 0x41, 0x89, 0x63, 0x01}}, + {x86.R11, 1, x86.Scale1, 1, x86.SP, []byte{0x41, 0x88, 0x63, 0x01}}, + {x86.R12, 1, x86.Scale1, 8, x86.R3, []byte{0x49, 0x89, 0x5C, 0x24, 0x01}}, + {x86.R12, 1, x86.Scale1, 4, x86.R3, []byte{0x41, 0x89, 0x5C, 0x24, 0x01}}, + {x86.R12, 1, x86.Scale1, 2, x86.R3, []byte{0x66, 0x41, 0x89, 0x5C, 0x24, 0x01}}, + {x86.R12, 1, x86.Scale1, 1, x86.R3, []byte{0x41, 0x88, 0x5C, 0x24, 0x01}}, + {x86.R13, 1, x86.Scale1, 8, x86.R2, []byte{0x49, 0x89, 0x55, 0x01}}, + {x86.R13, 1, x86.Scale1, 4, x86.R2, []byte{0x41, 0x89, 0x55, 0x01}}, + {x86.R13, 1, x86.Scale1, 2, x86.R2, []byte{0x66, 0x41, 0x89, 0x55, 0x01}}, + {x86.R13, 1, x86.Scale1, 1, x86.R2, []byte{0x41, 0x88, 0x55, 0x01}}, + {x86.R14, 1, x86.Scale1, 8, x86.R1, []byte{0x49, 0x89, 0x4E, 0x01}}, + {x86.R14, 1, x86.Scale1, 4, x86.R1, []byte{0x41, 0x89, 0x4E, 0x01}}, + {x86.R14, 1, x86.Scale1, 2, x86.R1, []byte{0x66, 0x41, 0x89, 0x4E, 0x01}}, + {x86.R14, 1, x86.Scale1, 1, x86.R1, []byte{0x41, 0x88, 0x4E, 0x01}}, + {x86.R15, 1, x86.Scale1, 8, x86.R0, []byte{0x49, 0x89, 0x47, 0x01}}, + {x86.R15, 1, x86.Scale1, 4, x86.R0, []byte{0x41, 0x89, 0x47, 0x01}}, + {x86.R15, 1, x86.Scale1, 2, x86.R0, []byte{0x66, 0x41, 0x89, 0x47, 0x01}}, + {x86.R15, 1, x86.Scale1, 1, x86.R0, []byte{0x41, 0x88, 0x47, 0x01}}, + } + + for _, pattern := range usagePatterns { + t.Logf("store %dB [%s+%d], %s", pattern.Length, pattern.RegisterTo, pattern.Offset, pattern.RegisterFrom) + code := x86.StoreFixedOffsetRegister(nil, pattern.RegisterTo, pattern.Offset, pattern.Scale, pattern.Length, pattern.RegisterFrom) + assert.DeepEqual(t, code, pattern.Code) + } +} \ No newline at end of file diff --git a/src/x86/Store_test.go b/src/x86/Store_test.go index 5cf4132..354ea7d 100644 --- a/src/x86/Store_test.go +++ b/src/x86/Store_test.go @@ -10,149 +10,82 @@ import ( func TestStoreNumber(t *testing.T) { usagePatterns := []struct { - Register cpu.Register - Offset int8 - Scale x86.Scale - Length byte - Number int - Code []byte + RegisterTo cpu.Register + Offset cpu.Register + Scale x86.Scale + Length byte + Number int + Code []byte }{ - // No offset - {x86.R0, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R0, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R0, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x00, 0x7F, 0x00}}, - {x86.R0, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x00, 0x7F}}, - {x86.R1, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R1, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R1, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x01, 0x7F, 0x00}}, - {x86.R1, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x01, 0x7F}}, - {x86.R2, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R2, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R2, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x02, 0x7F, 0x00}}, - {x86.R2, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x02, 0x7F}}, - {x86.R3, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R3, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R3, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x03, 0x7F, 0x00}}, - {x86.R3, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x03, 0x7F}}, - {x86.SP, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}}, - {x86.SP, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}}, - {x86.SP, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x04, 0x24, 0x7F, 0x00}}, - {x86.SP, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x04, 0x24, 0x7F}}, - {x86.R5, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R5, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R5, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x45, 0x00, 0x7F, 0x00}}, - {x86.R5, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x45, 0x00, 0x7F}}, - {x86.R6, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R6, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R6, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x06, 0x7F, 0x00}}, - {x86.R6, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x06, 0x7F}}, - {x86.R7, 0, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R7, 0, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R7, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x07, 0x7F, 0x00}}, - {x86.R7, 0, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x07, 0x7F}}, - {x86.R8, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R8, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R8, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x00, 0x7F, 0x00}}, - {x86.R8, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x00, 0x7F}}, - {x86.R9, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R9, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R9, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x01, 0x7F, 0x00}}, - {x86.R9, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x01, 0x7F}}, - {x86.R10, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R10, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R10, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x02, 0x7F, 0x00}}, - {x86.R10, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x02, 0x7F}}, - {x86.R11, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R11, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R11, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x03, 0x7F, 0x00}}, - {x86.R11, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x03, 0x7F}}, - {x86.R12, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R12, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R12, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x24, 0x7F, 0x00}}, - {x86.R12, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x24, 0x7F}}, - {x86.R13, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R13, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R13, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x45, 0x00, 0x7F, 0x00}}, - {x86.R13, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x45, 0x00, 0x7F}}, - {x86.R14, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R14, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R14, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x06, 0x7F, 0x00}}, - {x86.R14, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x06, 0x7F}}, - {x86.R15, 0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R15, 0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R15, 0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x07, 0x7F, 0x00}}, - {x86.R15, 0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x07, 0x7F}}, - - // Offset of 1 - {x86.R0, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R0, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R0, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x40, 0x01, 0x7F, 0x00}}, - {x86.R0, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x40, 0x01, 0x7F}}, - {x86.R1, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R1, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R1, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x41, 0x01, 0x7F, 0x00}}, - {x86.R1, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x41, 0x01, 0x7F}}, - {x86.R2, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R2, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R2, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x42, 0x01, 0x7F, 0x00}}, - {x86.R2, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x42, 0x01, 0x7F}}, - {x86.R3, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R3, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R3, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x43, 0x01, 0x7F, 0x00}}, - {x86.R3, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x43, 0x01, 0x7F}}, - {x86.SP, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.SP, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.SP, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00}}, - {x86.SP, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x44, 0x24, 0x01, 0x7F}}, - {x86.R5, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R5, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R5, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x45, 0x01, 0x7F, 0x00}}, - {x86.R5, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x45, 0x01, 0x7F}}, - {x86.R6, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R6, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R6, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x46, 0x01, 0x7F, 0x00}}, - {x86.R6, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x46, 0x01, 0x7F}}, - {x86.R7, 1, x86.Scale1, 8, 0x7F, []byte{0x48, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R7, 1, x86.Scale1, 4, 0x7F, []byte{0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R7, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0xC7, 0x47, 0x01, 0x7F, 0x00}}, - {x86.R7, 1, x86.Scale1, 1, 0x7F, []byte{0xC6, 0x47, 0x01, 0x7F}}, - {x86.R8, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R8, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R8, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x40, 0x01, 0x7F, 0x00}}, - {x86.R8, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x40, 0x01, 0x7F}}, - {x86.R9, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R9, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R9, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x41, 0x01, 0x7F, 0x00}}, - {x86.R9, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x41, 0x01, 0x7F}}, - {x86.R10, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R10, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R10, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x42, 0x01, 0x7F, 0x00}}, - {x86.R10, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x42, 0x01, 0x7F}}, - {x86.R11, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R11, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R11, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x43, 0x01, 0x7F, 0x00}}, - {x86.R11, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x43, 0x01, 0x7F}}, - {x86.R12, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R12, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R12, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00}}, - {x86.R12, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x44, 0x24, 0x01, 0x7F}}, - {x86.R13, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R13, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R13, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x45, 0x01, 0x7F, 0x00}}, - {x86.R13, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x45, 0x01, 0x7F}}, - {x86.R14, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R14, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R14, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x46, 0x01, 0x7F, 0x00}}, - {x86.R14, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x46, 0x01, 0x7F}}, - {x86.R15, 1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R15, 1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}}, - {x86.R15, 1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x47, 0x01, 0x7F, 0x00}}, - {x86.R15, 1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x47, 0x01, 0x7F}}, + {x86.R0, x86.R15, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R0, x86.R15, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R0, x86.R15, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x38, 0x7F, 0x00}}, + {x86.R0, x86.R15, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x38, 0x7F}}, + {x86.R1, x86.R14, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R1, x86.R14, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R1, x86.R14, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x31, 0x7F, 0x00}}, + {x86.R1, x86.R14, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x31, 0x7F}}, + {x86.R2, x86.R13, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R2, x86.R13, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R2, x86.R13, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x2A, 0x7F, 0x00}}, + {x86.R2, x86.R13, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x2A, 0x7F}}, + {x86.R3, x86.R12, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x23, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R3, x86.R12, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x23, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R3, x86.R12, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x23, 0x7F, 0x00}}, + {x86.R3, x86.R12, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x23, 0x7F}}, + {x86.SP, x86.R11, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, + {x86.SP, x86.R11, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, + {x86.SP, x86.R11, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00}}, + {x86.SP, x86.R11, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x1C, 0x7F}}, + {x86.R5, x86.R10, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R5, x86.R10, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R5, x86.R10, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00}}, + {x86.R5, x86.R10, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x44, 0x15, 0x00, 0x7F}}, + {x86.R6, x86.R9, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R6, x86.R9, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R6, x86.R9, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x0E, 0x7F, 0x00}}, + {x86.R6, x86.R9, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x0E, 0x7F}}, + {x86.R7, x86.R8, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R7, x86.R8, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R7, x86.R8, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x07, 0x7F, 0x00}}, + {x86.R7, x86.R8, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x07, 0x7F}}, + {x86.R8, x86.R7, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R8, x86.R7, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R8, x86.R7, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x38, 0x7F, 0x00}}, + {x86.R8, x86.R7, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x38, 0x7F}}, + {x86.R9, x86.R6, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R9, x86.R6, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R9, x86.R6, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x31, 0x7F, 0x00}}, + {x86.R9, x86.R6, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x31, 0x7F}}, + {x86.R10, x86.R5, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R10, x86.R5, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R10, x86.R5, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x2A, 0x7F, 0x00}}, + {x86.R10, x86.R5, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x2A, 0x7F}}, + {x86.R11, x86.SP, x86.Scale1, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R11, x86.SP, x86.Scale1, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R11, x86.SP, x86.Scale1, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00}}, + {x86.R11, x86.SP, x86.Scale1, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x1C, 0x7F}}, + {x86.R12, x86.R3, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R12, x86.R3, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R12, x86.R3, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x1C, 0x7F, 0x00}}, + {x86.R12, x86.R3, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x1C, 0x7F}}, + {x86.R13, x86.R2, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R13, x86.R2, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R13, x86.R2, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00}}, + {x86.R13, x86.R2, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x44, 0x15, 0x00, 0x7F}}, + {x86.R14, x86.R1, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R14, x86.R1, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R14, x86.R1, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x0E, 0x7F, 0x00}}, + {x86.R14, x86.R1, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x0E, 0x7F}}, + {x86.R15, x86.R0, x86.Scale1, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R15, x86.R0, x86.Scale1, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}}, + {x86.R15, x86.R0, x86.Scale1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x07, 0x7F, 0x00}}, + {x86.R15, x86.R0, x86.Scale1, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x07, 0x7F}}, } for _, pattern := range usagePatterns { - t.Logf("store %dB [%s+%d], %d", pattern.Length, pattern.Register, pattern.Offset, pattern.Number) - code := x86.StoreNumber(nil, pattern.Register, pattern.Offset, pattern.Scale, pattern.Length, pattern.Number) + t.Logf("store %dB [%s+%s], %d", pattern.Length, pattern.RegisterTo, pattern.Offset, pattern.Number) + code := x86.StoreNumber(nil, pattern.RegisterTo, pattern.Offset, pattern.Scale, pattern.Length, pattern.Number) assert.DeepEqual(t, code, pattern.Code) } } @@ -160,147 +93,80 @@ func TestStoreNumber(t *testing.T) { func TestStoreRegister(t *testing.T) { usagePatterns := []struct { RegisterTo cpu.Register - Offset int8 + Offset cpu.Register Scale x86.Scale Length byte RegisterFrom cpu.Register Code []byte }{ - // No offset - {x86.R0, 0, x86.Scale1, 8, x86.R15, []byte{0x4C, 0x89, 0x38}}, - {x86.R0, 0, x86.Scale1, 4, x86.R15, []byte{0x44, 0x89, 0x38}}, - {x86.R0, 0, x86.Scale1, 2, x86.R15, []byte{0x66, 0x44, 0x89, 0x38}}, - {x86.R0, 0, x86.Scale1, 1, x86.R15, []byte{0x44, 0x88, 0x38}}, - {x86.R1, 0, x86.Scale1, 8, x86.R14, []byte{0x4C, 0x89, 0x31}}, - {x86.R1, 0, x86.Scale1, 4, x86.R14, []byte{0x44, 0x89, 0x31}}, - {x86.R1, 0, x86.Scale1, 2, x86.R14, []byte{0x66, 0x44, 0x89, 0x31}}, - {x86.R1, 0, x86.Scale1, 1, x86.R14, []byte{0x44, 0x88, 0x31}}, - {x86.R2, 0, x86.Scale1, 8, x86.R13, []byte{0x4C, 0x89, 0x2A}}, - {x86.R2, 0, x86.Scale1, 4, x86.R13, []byte{0x44, 0x89, 0x2A}}, - {x86.R2, 0, x86.Scale1, 2, x86.R13, []byte{0x66, 0x44, 0x89, 0x2A}}, - {x86.R2, 0, x86.Scale1, 1, x86.R13, []byte{0x44, 0x88, 0x2A}}, - {x86.R3, 0, x86.Scale1, 8, x86.R12, []byte{0x4C, 0x89, 0x23}}, - {x86.R3, 0, x86.Scale1, 4, x86.R12, []byte{0x44, 0x89, 0x23}}, - {x86.R3, 0, x86.Scale1, 2, x86.R12, []byte{0x66, 0x44, 0x89, 0x23}}, - {x86.R3, 0, x86.Scale1, 1, x86.R12, []byte{0x44, 0x88, 0x23}}, - {x86.SP, 0, x86.Scale1, 8, x86.R11, []byte{0x4C, 0x89, 0x1C, 0x24}}, - {x86.SP, 0, x86.Scale1, 4, x86.R11, []byte{0x44, 0x89, 0x1C, 0x24}}, - {x86.SP, 0, x86.Scale1, 2, x86.R11, []byte{0x66, 0x44, 0x89, 0x1C, 0x24}}, - {x86.SP, 0, x86.Scale1, 1, x86.R11, []byte{0x44, 0x88, 0x1C, 0x24}}, - {x86.R5, 0, x86.Scale1, 8, x86.R10, []byte{0x4C, 0x89, 0x55, 0x00}}, - {x86.R5, 0, x86.Scale1, 4, x86.R10, []byte{0x44, 0x89, 0x55, 0x00}}, - {x86.R5, 0, x86.Scale1, 2, x86.R10, []byte{0x66, 0x44, 0x89, 0x55, 0x00}}, - {x86.R5, 0, x86.Scale1, 1, x86.R10, []byte{0x44, 0x88, 0x55, 0x00}}, - {x86.R6, 0, x86.Scale1, 8, x86.R9, []byte{0x4C, 0x89, 0x0E}}, - {x86.R6, 0, x86.Scale1, 4, x86.R9, []byte{0x44, 0x89, 0x0E}}, - {x86.R6, 0, x86.Scale1, 2, x86.R9, []byte{0x66, 0x44, 0x89, 0x0E}}, - {x86.R6, 0, x86.Scale1, 1, x86.R9, []byte{0x44, 0x88, 0x0E}}, - {x86.R7, 0, x86.Scale1, 8, x86.R8, []byte{0x4C, 0x89, 0x07}}, - {x86.R7, 0, x86.Scale1, 4, x86.R8, []byte{0x44, 0x89, 0x07}}, - {x86.R7, 0, x86.Scale1, 2, x86.R8, []byte{0x66, 0x44, 0x89, 0x07}}, - {x86.R7, 0, x86.Scale1, 1, x86.R8, []byte{0x44, 0x88, 0x07}}, - {x86.R8, 0, x86.Scale1, 8, x86.R7, []byte{0x49, 0x89, 0x38}}, - {x86.R8, 0, x86.Scale1, 4, x86.R7, []byte{0x41, 0x89, 0x38}}, - {x86.R8, 0, x86.Scale1, 2, x86.R7, []byte{0x66, 0x41, 0x89, 0x38}}, - {x86.R8, 0, x86.Scale1, 1, x86.R7, []byte{0x41, 0x88, 0x38}}, - {x86.R9, 0, x86.Scale1, 8, x86.R6, []byte{0x49, 0x89, 0x31}}, - {x86.R9, 0, x86.Scale1, 4, x86.R6, []byte{0x41, 0x89, 0x31}}, - {x86.R9, 0, x86.Scale1, 2, x86.R6, []byte{0x66, 0x41, 0x89, 0x31}}, - {x86.R9, 0, x86.Scale1, 1, x86.R6, []byte{0x41, 0x88, 0x31}}, - {x86.R10, 0, x86.Scale1, 8, x86.R5, []byte{0x49, 0x89, 0x2A}}, - {x86.R10, 0, x86.Scale1, 4, x86.R5, []byte{0x41, 0x89, 0x2A}}, - {x86.R10, 0, x86.Scale1, 2, x86.R5, []byte{0x66, 0x41, 0x89, 0x2A}}, - {x86.R10, 0, x86.Scale1, 1, x86.R5, []byte{0x41, 0x88, 0x2A}}, - {x86.R11, 0, x86.Scale1, 8, x86.SP, []byte{0x49, 0x89, 0x23}}, - {x86.R11, 0, x86.Scale1, 4, x86.SP, []byte{0x41, 0x89, 0x23}}, - {x86.R11, 0, x86.Scale1, 2, x86.SP, []byte{0x66, 0x41, 0x89, 0x23}}, - {x86.R11, 0, x86.Scale1, 1, x86.SP, []byte{0x41, 0x88, 0x23}}, - {x86.R12, 0, x86.Scale1, 8, x86.R3, []byte{0x49, 0x89, 0x1C, 0x24}}, - {x86.R12, 0, x86.Scale1, 4, x86.R3, []byte{0x41, 0x89, 0x1C, 0x24}}, - {x86.R12, 0, x86.Scale1, 2, x86.R3, []byte{0x66, 0x41, 0x89, 0x1C, 0x24}}, - {x86.R12, 0, x86.Scale1, 1, x86.R3, []byte{0x41, 0x88, 0x1C, 0x24}}, - {x86.R13, 0, x86.Scale1, 8, x86.R2, []byte{0x49, 0x89, 0x55, 0x00}}, - {x86.R13, 0, x86.Scale1, 4, x86.R2, []byte{0x41, 0x89, 0x55, 0x00}}, - {x86.R13, 0, x86.Scale1, 2, x86.R2, []byte{0x66, 0x41, 0x89, 0x55, 0x00}}, - {x86.R13, 0, x86.Scale1, 1, x86.R2, []byte{0x41, 0x88, 0x55, 0x00}}, - {x86.R14, 0, x86.Scale1, 8, x86.R1, []byte{0x49, 0x89, 0x0E}}, - {x86.R14, 0, x86.Scale1, 4, x86.R1, []byte{0x41, 0x89, 0x0E}}, - {x86.R14, 0, x86.Scale1, 2, x86.R1, []byte{0x66, 0x41, 0x89, 0x0E}}, - {x86.R14, 0, x86.Scale1, 1, x86.R1, []byte{0x41, 0x88, 0x0E}}, - {x86.R15, 0, x86.Scale1, 8, x86.R0, []byte{0x49, 0x89, 0x07}}, - {x86.R15, 0, x86.Scale1, 4, x86.R0, []byte{0x41, 0x89, 0x07}}, - {x86.R15, 0, x86.Scale1, 2, x86.R0, []byte{0x66, 0x41, 0x89, 0x07}}, - {x86.R15, 0, x86.Scale1, 1, x86.R0, []byte{0x41, 0x88, 0x07}}, - - // Offset of 1 - {x86.R0, 1, x86.Scale1, 8, x86.R15, []byte{0x4C, 0x89, 0x78, 0x01}}, - {x86.R0, 1, x86.Scale1, 4, x86.R15, []byte{0x44, 0x89, 0x78, 0x01}}, - {x86.R0, 1, x86.Scale1, 2, x86.R15, []byte{0x66, 0x44, 0x89, 0x78, 0x01}}, - {x86.R0, 1, x86.Scale1, 1, x86.R15, []byte{0x44, 0x88, 0x78, 0x01}}, - {x86.R1, 1, x86.Scale1, 8, x86.R14, []byte{0x4C, 0x89, 0x71, 0x01}}, - {x86.R1, 1, x86.Scale1, 4, x86.R14, []byte{0x44, 0x89, 0x71, 0x01}}, - {x86.R1, 1, x86.Scale1, 2, x86.R14, []byte{0x66, 0x44, 0x89, 0x71, 0x01}}, - {x86.R1, 1, x86.Scale1, 1, x86.R14, []byte{0x44, 0x88, 0x71, 0x01}}, - {x86.R2, 1, x86.Scale1, 8, x86.R13, []byte{0x4C, 0x89, 0x6A, 0x01}}, - {x86.R2, 1, x86.Scale1, 4, x86.R13, []byte{0x44, 0x89, 0x6A, 0x01}}, - {x86.R2, 1, x86.Scale1, 2, x86.R13, []byte{0x66, 0x44, 0x89, 0x6A, 0x01}}, - {x86.R2, 1, x86.Scale1, 1, x86.R13, []byte{0x44, 0x88, 0x6A, 0x01}}, - {x86.R3, 1, x86.Scale1, 8, x86.R12, []byte{0x4C, 0x89, 0x63, 0x01}}, - {x86.R3, 1, x86.Scale1, 4, x86.R12, []byte{0x44, 0x89, 0x63, 0x01}}, - {x86.R3, 1, x86.Scale1, 2, x86.R12, []byte{0x66, 0x44, 0x89, 0x63, 0x01}}, - {x86.R3, 1, x86.Scale1, 1, x86.R12, []byte{0x44, 0x88, 0x63, 0x01}}, - {x86.SP, 1, x86.Scale1, 8, x86.R11, []byte{0x4C, 0x89, 0x5C, 0x24, 0x01}}, - {x86.SP, 1, x86.Scale1, 4, x86.R11, []byte{0x44, 0x89, 0x5C, 0x24, 0x01}}, - {x86.SP, 1, x86.Scale1, 2, x86.R11, []byte{0x66, 0x44, 0x89, 0x5C, 0x24, 0x01}}, - {x86.SP, 1, x86.Scale1, 1, x86.R11, []byte{0x44, 0x88, 0x5C, 0x24, 0x01}}, - {x86.R5, 1, x86.Scale1, 8, x86.R10, []byte{0x4C, 0x89, 0x55, 0x01}}, - {x86.R5, 1, x86.Scale1, 4, x86.R10, []byte{0x44, 0x89, 0x55, 0x01}}, - {x86.R5, 1, x86.Scale1, 2, x86.R10, []byte{0x66, 0x44, 0x89, 0x55, 0x01}}, - {x86.R5, 1, x86.Scale1, 1, x86.R10, []byte{0x44, 0x88, 0x55, 0x01}}, - {x86.R6, 1, x86.Scale1, 8, x86.R9, []byte{0x4C, 0x89, 0x4E, 0x01}}, - {x86.R6, 1, x86.Scale1, 4, x86.R9, []byte{0x44, 0x89, 0x4E, 0x01}}, - {x86.R6, 1, x86.Scale1, 2, x86.R9, []byte{0x66, 0x44, 0x89, 0x4E, 0x01}}, - {x86.R6, 1, x86.Scale1, 1, x86.R9, []byte{0x44, 0x88, 0x4E, 0x01}}, - {x86.R7, 1, x86.Scale1, 8, x86.R8, []byte{0x4C, 0x89, 0x47, 0x01}}, - {x86.R7, 1, x86.Scale1, 4, x86.R8, []byte{0x44, 0x89, 0x47, 0x01}}, - {x86.R7, 1, x86.Scale1, 2, x86.R8, []byte{0x66, 0x44, 0x89, 0x47, 0x01}}, - {x86.R7, 1, x86.Scale1, 1, x86.R8, []byte{0x44, 0x88, 0x47, 0x01}}, - {x86.R8, 1, x86.Scale1, 8, x86.R7, []byte{0x49, 0x89, 0x78, 0x01}}, - {x86.R8, 1, x86.Scale1, 4, x86.R7, []byte{0x41, 0x89, 0x78, 0x01}}, - {x86.R8, 1, x86.Scale1, 2, x86.R7, []byte{0x66, 0x41, 0x89, 0x78, 0x01}}, - {x86.R8, 1, x86.Scale1, 1, x86.R7, []byte{0x41, 0x88, 0x78, 0x01}}, - {x86.R9, 1, x86.Scale1, 8, x86.R6, []byte{0x49, 0x89, 0x71, 0x01}}, - {x86.R9, 1, x86.Scale1, 4, x86.R6, []byte{0x41, 0x89, 0x71, 0x01}}, - {x86.R9, 1, x86.Scale1, 2, x86.R6, []byte{0x66, 0x41, 0x89, 0x71, 0x01}}, - {x86.R9, 1, x86.Scale1, 1, x86.R6, []byte{0x41, 0x88, 0x71, 0x01}}, - {x86.R10, 1, x86.Scale1, 8, x86.R5, []byte{0x49, 0x89, 0x6A, 0x01}}, - {x86.R10, 1, x86.Scale1, 4, x86.R5, []byte{0x41, 0x89, 0x6A, 0x01}}, - {x86.R10, 1, x86.Scale1, 2, x86.R5, []byte{0x66, 0x41, 0x89, 0x6A, 0x01}}, - {x86.R10, 1, x86.Scale1, 1, x86.R5, []byte{0x41, 0x88, 0x6A, 0x01}}, - {x86.R11, 1, x86.Scale1, 8, x86.SP, []byte{0x49, 0x89, 0x63, 0x01}}, - {x86.R11, 1, x86.Scale1, 4, x86.SP, []byte{0x41, 0x89, 0x63, 0x01}}, - {x86.R11, 1, x86.Scale1, 2, x86.SP, []byte{0x66, 0x41, 0x89, 0x63, 0x01}}, - {x86.R11, 1, x86.Scale1, 1, x86.SP, []byte{0x41, 0x88, 0x63, 0x01}}, - {x86.R12, 1, x86.Scale1, 8, x86.R3, []byte{0x49, 0x89, 0x5C, 0x24, 0x01}}, - {x86.R12, 1, x86.Scale1, 4, x86.R3, []byte{0x41, 0x89, 0x5C, 0x24, 0x01}}, - {x86.R12, 1, x86.Scale1, 2, x86.R3, []byte{0x66, 0x41, 0x89, 0x5C, 0x24, 0x01}}, - {x86.R12, 1, x86.Scale1, 1, x86.R3, []byte{0x41, 0x88, 0x5C, 0x24, 0x01}}, - {x86.R13, 1, x86.Scale1, 8, x86.R2, []byte{0x49, 0x89, 0x55, 0x01}}, - {x86.R13, 1, x86.Scale1, 4, x86.R2, []byte{0x41, 0x89, 0x55, 0x01}}, - {x86.R13, 1, x86.Scale1, 2, x86.R2, []byte{0x66, 0x41, 0x89, 0x55, 0x01}}, - {x86.R13, 1, x86.Scale1, 1, x86.R2, []byte{0x41, 0x88, 0x55, 0x01}}, - {x86.R14, 1, x86.Scale1, 8, x86.R1, []byte{0x49, 0x89, 0x4E, 0x01}}, - {x86.R14, 1, x86.Scale1, 4, x86.R1, []byte{0x41, 0x89, 0x4E, 0x01}}, - {x86.R14, 1, x86.Scale1, 2, x86.R1, []byte{0x66, 0x41, 0x89, 0x4E, 0x01}}, - {x86.R14, 1, x86.Scale1, 1, x86.R1, []byte{0x41, 0x88, 0x4E, 0x01}}, - {x86.R15, 1, x86.Scale1, 8, x86.R0, []byte{0x49, 0x89, 0x47, 0x01}}, - {x86.R15, 1, x86.Scale1, 4, x86.R0, []byte{0x41, 0x89, 0x47, 0x01}}, - {x86.R15, 1, x86.Scale1, 2, x86.R0, []byte{0x66, 0x41, 0x89, 0x47, 0x01}}, - {x86.R15, 1, x86.Scale1, 1, x86.R0, []byte{0x41, 0x88, 0x47, 0x01}}, + {x86.R0, x86.R15, x86.Scale1, 8, x86.R15, []byte{0x4E, 0x89, 0x3C, 0x38}}, + {x86.R0, x86.R15, x86.Scale1, 4, x86.R15, []byte{0x46, 0x89, 0x3C, 0x38}}, + {x86.R0, x86.R15, x86.Scale1, 2, x86.R15, []byte{0x66, 0x46, 0x89, 0x3C, 0x38}}, + {x86.R0, x86.R15, x86.Scale1, 1, x86.R15, []byte{0x46, 0x88, 0x3C, 0x38}}, + {x86.R1, x86.R14, x86.Scale1, 8, x86.R14, []byte{0x4E, 0x89, 0x34, 0x31}}, + {x86.R1, x86.R14, x86.Scale1, 4, x86.R14, []byte{0x46, 0x89, 0x34, 0x31}}, + {x86.R1, x86.R14, x86.Scale1, 2, x86.R14, []byte{0x66, 0x46, 0x89, 0x34, 0x31}}, + {x86.R1, x86.R14, x86.Scale1, 1, x86.R14, []byte{0x46, 0x88, 0x34, 0x31}}, + {x86.R2, x86.R13, x86.Scale1, 8, x86.R13, []byte{0x4E, 0x89, 0x2C, 0x2A}}, + {x86.R2, x86.R13, x86.Scale1, 4, x86.R13, []byte{0x46, 0x89, 0x2C, 0x2A}}, + {x86.R2, x86.R13, x86.Scale1, 2, x86.R13, []byte{0x66, 0x46, 0x89, 0x2C, 0x2A}}, + {x86.R2, x86.R13, x86.Scale1, 1, x86.R13, []byte{0x46, 0x88, 0x2C, 0x2A}}, + {x86.R3, x86.R12, x86.Scale1, 8, x86.R12, []byte{0x4E, 0x89, 0x24, 0x23}}, + {x86.R3, x86.R12, x86.Scale1, 4, x86.R12, []byte{0x46, 0x89, 0x24, 0x23}}, + {x86.R3, x86.R12, x86.Scale1, 2, x86.R12, []byte{0x66, 0x46, 0x89, 0x24, 0x23}}, + {x86.R3, x86.R12, x86.Scale1, 1, x86.R12, []byte{0x46, 0x88, 0x24, 0x23}}, + {x86.SP, x86.R11, x86.Scale1, 8, x86.R11, []byte{0x4E, 0x89, 0x1C, 0x1C}}, + {x86.SP, x86.R11, x86.Scale1, 4, x86.R11, []byte{0x46, 0x89, 0x1C, 0x1C}}, + {x86.SP, x86.R11, x86.Scale1, 2, x86.R11, []byte{0x66, 0x46, 0x89, 0x1C, 0x1C}}, + {x86.SP, x86.R11, x86.Scale1, 1, x86.R11, []byte{0x46, 0x88, 0x1C, 0x1C}}, + {x86.R5, x86.R10, x86.Scale1, 8, x86.R10, []byte{0x4E, 0x89, 0x54, 0x15, 0x00}}, + {x86.R5, x86.R10, x86.Scale1, 4, x86.R10, []byte{0x46, 0x89, 0x54, 0x15, 0x00}}, + {x86.R5, x86.R10, x86.Scale1, 2, x86.R10, []byte{0x66, 0x46, 0x89, 0x54, 0x15, 0x00}}, + {x86.R5, x86.R10, x86.Scale1, 1, x86.R10, []byte{0x46, 0x88, 0x54, 0x15, 0x00}}, + {x86.R6, x86.R9, x86.Scale1, 8, x86.R9, []byte{0x4E, 0x89, 0x0C, 0x0E}}, + {x86.R6, x86.R9, x86.Scale1, 4, x86.R9, []byte{0x46, 0x89, 0x0C, 0x0E}}, + {x86.R6, x86.R9, x86.Scale1, 2, x86.R9, []byte{0x66, 0x46, 0x89, 0x0C, 0x0E}}, + {x86.R6, x86.R9, x86.Scale1, 1, x86.R9, []byte{0x46, 0x88, 0x0C, 0x0E}}, + {x86.R7, x86.R8, x86.Scale1, 8, x86.R8, []byte{0x4E, 0x89, 0x04, 0x07}}, + {x86.R7, x86.R8, x86.Scale1, 4, x86.R8, []byte{0x46, 0x89, 0x04, 0x07}}, + {x86.R7, x86.R8, x86.Scale1, 2, x86.R8, []byte{0x66, 0x46, 0x89, 0x04, 0x07}}, + {x86.R7, x86.R8, x86.Scale1, 1, x86.R8, []byte{0x46, 0x88, 0x04, 0x07}}, + {x86.R8, x86.R7, x86.Scale1, 8, x86.R7, []byte{0x49, 0x89, 0x3C, 0x38}}, + {x86.R8, x86.R7, x86.Scale1, 4, x86.R7, []byte{0x41, 0x89, 0x3C, 0x38}}, + {x86.R8, x86.R7, x86.Scale1, 2, x86.R7, []byte{0x66, 0x41, 0x89, 0x3C, 0x38}}, + {x86.R8, x86.R7, x86.Scale1, 1, x86.R7, []byte{0x41, 0x88, 0x3C, 0x38}}, + {x86.R9, x86.R6, x86.Scale1, 8, x86.R6, []byte{0x49, 0x89, 0x34, 0x31}}, + {x86.R9, x86.R6, x86.Scale1, 4, x86.R6, []byte{0x41, 0x89, 0x34, 0x31}}, + {x86.R9, x86.R6, x86.Scale1, 2, x86.R6, []byte{0x66, 0x41, 0x89, 0x34, 0x31}}, + {x86.R9, x86.R6, x86.Scale1, 1, x86.R6, []byte{0x41, 0x88, 0x34, 0x31}}, + {x86.R10, x86.R5, x86.Scale1, 8, x86.R5, []byte{0x49, 0x89, 0x2C, 0x2A}}, + {x86.R10, x86.R5, x86.Scale1, 4, x86.R5, []byte{0x41, 0x89, 0x2C, 0x2A}}, + {x86.R10, x86.R5, x86.Scale1, 2, x86.R5, []byte{0x66, 0x41, 0x89, 0x2C, 0x2A}}, + {x86.R10, x86.R5, x86.Scale1, 1, x86.R5, []byte{0x41, 0x88, 0x2C, 0x2A}}, + {x86.R11, x86.SP, x86.Scale1, 8, x86.SP, []byte{0x4A, 0x89, 0x24, 0x1C}}, + {x86.R11, x86.SP, x86.Scale1, 4, x86.SP, []byte{0x42, 0x89, 0x24, 0x1C}}, + {x86.R11, x86.SP, x86.Scale1, 2, x86.SP, []byte{0x66, 0x42, 0x89, 0x24, 0x1C}}, + {x86.R11, x86.SP, x86.Scale1, 1, x86.SP, []byte{0x42, 0x88, 0x24, 0x1C}}, + {x86.R12, x86.R3, x86.Scale1, 8, x86.R3, []byte{0x49, 0x89, 0x1C, 0x1C}}, + {x86.R12, x86.R3, x86.Scale1, 4, x86.R3, []byte{0x41, 0x89, 0x1C, 0x1C}}, + {x86.R12, x86.R3, x86.Scale1, 2, x86.R3, []byte{0x66, 0x41, 0x89, 0x1C, 0x1C}}, + {x86.R12, x86.R3, x86.Scale1, 1, x86.R3, []byte{0x41, 0x88, 0x1C, 0x1C}}, + {x86.R13, x86.R2, x86.Scale1, 8, x86.R2, []byte{0x49, 0x89, 0x54, 0x15, 0x00}}, + {x86.R13, x86.R2, x86.Scale1, 4, x86.R2, []byte{0x41, 0x89, 0x54, 0x15, 0x00}}, + {x86.R13, x86.R2, x86.Scale1, 2, x86.R2, []byte{0x66, 0x41, 0x89, 0x54, 0x15, 0x00}}, + {x86.R13, x86.R2, x86.Scale1, 1, x86.R2, []byte{0x41, 0x88, 0x54, 0x15, 0x00}}, + {x86.R14, x86.R1, x86.Scale1, 8, x86.R1, []byte{0x49, 0x89, 0x0C, 0x0E}}, + {x86.R14, x86.R1, x86.Scale1, 4, x86.R1, []byte{0x41, 0x89, 0x0C, 0x0E}}, + {x86.R14, x86.R1, x86.Scale1, 2, x86.R1, []byte{0x66, 0x41, 0x89, 0x0C, 0x0E}}, + {x86.R14, x86.R1, x86.Scale1, 1, x86.R1, []byte{0x41, 0x88, 0x0C, 0x0E}}, + {x86.R15, x86.R0, x86.Scale1, 8, x86.R0, []byte{0x49, 0x89, 0x04, 0x07}}, + {x86.R15, x86.R0, x86.Scale1, 4, x86.R0, []byte{0x41, 0x89, 0x04, 0x07}}, + {x86.R15, x86.R0, x86.Scale1, 2, x86.R0, []byte{0x66, 0x41, 0x89, 0x04, 0x07}}, + {x86.R15, x86.R0, x86.Scale1, 1, x86.R0, []byte{0x41, 0x88, 0x04, 0x07}}, } for _, pattern := range usagePatterns { - t.Logf("store %dB [%s+%d], %s", pattern.Length, pattern.RegisterTo, pattern.Offset, pattern.RegisterFrom) + t.Logf("store %dB [%s+%s], %s", pattern.Length, pattern.RegisterTo, pattern.Offset, pattern.RegisterFrom) code := x86.StoreRegister(nil, pattern.RegisterTo, pattern.Offset, pattern.Scale, pattern.Length, pattern.RegisterFrom) assert.DeepEqual(t, code, pattern.Code) } -- 2.51.2