Renamed x64 to x86
This commit is contained in:
parent
37afbde0da
commit
d4f9071ee4
@ -71,7 +71,7 @@
|
||||
|
||||
- [ ] arm64
|
||||
- [ ] riscv
|
||||
- [x] x64
|
||||
- [x] x86
|
||||
|
||||
### Platform
|
||||
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"git.akyoto.dev/cli/q/src/config"
|
||||
"git.akyoto.dev/cli/q/src/dll"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
)
|
||||
|
||||
// Finalize generates the final machine code.
|
||||
@ -27,67 +27,67 @@ func (a Assembler) Finalize(dlls dll.List) ([]byte, []byte) {
|
||||
case ADD:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.AddRegisterNumber(code, operands.Register, operands.Number)
|
||||
code = x86.AddRegisterNumber(code, operands.Register, operands.Number)
|
||||
case *RegisterRegister:
|
||||
code = x64.AddRegisterRegister(code, operands.Destination, operands.Source)
|
||||
code = x86.AddRegisterRegister(code, operands.Destination, operands.Source)
|
||||
}
|
||||
|
||||
case AND:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.AndRegisterNumber(code, operands.Register, operands.Number)
|
||||
code = x86.AndRegisterNumber(code, operands.Register, operands.Number)
|
||||
case *RegisterRegister:
|
||||
code = x64.AndRegisterRegister(code, operands.Destination, operands.Source)
|
||||
code = x86.AndRegisterRegister(code, operands.Destination, operands.Source)
|
||||
}
|
||||
|
||||
case SUB:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.SubRegisterNumber(code, operands.Register, operands.Number)
|
||||
code = x86.SubRegisterNumber(code, operands.Register, operands.Number)
|
||||
case *RegisterRegister:
|
||||
code = x64.SubRegisterRegister(code, operands.Destination, operands.Source)
|
||||
code = x86.SubRegisterRegister(code, operands.Destination, operands.Source)
|
||||
}
|
||||
|
||||
case MUL:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.MulRegisterNumber(code, operands.Register, operands.Number)
|
||||
code = x86.MulRegisterNumber(code, operands.Register, operands.Number)
|
||||
case *RegisterRegister:
|
||||
code = x64.MulRegisterRegister(code, operands.Destination, operands.Source)
|
||||
code = x86.MulRegisterRegister(code, operands.Destination, operands.Source)
|
||||
}
|
||||
|
||||
case DIV:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterRegister:
|
||||
if operands.Destination != x64.RAX {
|
||||
code = x64.MoveRegisterRegister(code, x64.RAX, operands.Destination)
|
||||
if operands.Destination != x86.RAX {
|
||||
code = x86.MoveRegisterRegister(code, x86.RAX, operands.Destination)
|
||||
}
|
||||
|
||||
code = x64.ExtendRAXToRDX(code)
|
||||
code = x64.DivRegister(code, operands.Source)
|
||||
code = x86.ExtendRAXToRDX(code)
|
||||
code = x86.DivRegister(code, operands.Source)
|
||||
|
||||
if operands.Destination != x64.RAX {
|
||||
code = x64.MoveRegisterRegister(code, operands.Destination, x64.RAX)
|
||||
if operands.Destination != x86.RAX {
|
||||
code = x86.MoveRegisterRegister(code, operands.Destination, x86.RAX)
|
||||
}
|
||||
}
|
||||
|
||||
case MODULO:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterRegister:
|
||||
if operands.Destination != x64.RAX {
|
||||
code = x64.MoveRegisterRegister(code, x64.RAX, operands.Destination)
|
||||
if operands.Destination != x86.RAX {
|
||||
code = x86.MoveRegisterRegister(code, x86.RAX, operands.Destination)
|
||||
}
|
||||
|
||||
code = x64.ExtendRAXToRDX(code)
|
||||
code = x64.DivRegister(code, operands.Source)
|
||||
code = x86.ExtendRAXToRDX(code)
|
||||
code = x86.DivRegister(code, operands.Source)
|
||||
|
||||
if operands.Destination != x64.RDX {
|
||||
code = x64.MoveRegisterRegister(code, operands.Destination, x64.RDX)
|
||||
if operands.Destination != x86.RDX {
|
||||
code = x86.MoveRegisterRegister(code, operands.Destination, x86.RDX)
|
||||
}
|
||||
}
|
||||
|
||||
case CALL:
|
||||
code = x64.Call(code, 0x00_00_00_00)
|
||||
code = x86.Call(code, 0x00_00_00_00)
|
||||
size := 4
|
||||
label := x.Data.(*Label)
|
||||
|
||||
@ -116,20 +116,20 @@ func (a Assembler) Finalize(dlls dll.List) ([]byte, []byte) {
|
||||
case COMPARE:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.CompareRegisterNumber(code, operands.Register, operands.Number)
|
||||
code = x86.CompareRegisterNumber(code, operands.Register, operands.Number)
|
||||
case *RegisterRegister:
|
||||
code = x64.CompareRegisterRegister(code, operands.Destination, operands.Source)
|
||||
code = x86.CompareRegisterRegister(code, operands.Destination, operands.Source)
|
||||
}
|
||||
|
||||
case DLLCALL:
|
||||
size := 4
|
||||
// TODO: R15 could be in use.
|
||||
code = x64.MoveRegisterRegister(code, x64.R15, x64.RSP)
|
||||
code = x64.AlignStack(code)
|
||||
code = x64.SubRegisterNumber(code, x64.RSP, 32)
|
||||
code = x64.CallAtAddress(code, 0x00_00_00_00)
|
||||
code = x86.MoveRegisterRegister(code, x86.R15, x86.RSP)
|
||||
code = x86.AlignStack(code)
|
||||
code = x86.SubRegisterNumber(code, x86.RSP, 32)
|
||||
code = x86.CallAtAddress(code, 0x00_00_00_00)
|
||||
position := len(code) - size
|
||||
code = x64.MoveRegisterRegister(code, x64.RSP, x64.R15)
|
||||
code = x86.MoveRegisterRegister(code, x86.RSP, x86.R15)
|
||||
|
||||
label := x.Data.(*Label)
|
||||
pointer := &pointer{
|
||||
@ -156,19 +156,19 @@ func (a Assembler) Finalize(dlls dll.List) ([]byte, []byte) {
|
||||
case JE, JNE, JG, JGE, JL, JLE, JUMP:
|
||||
switch x.Mnemonic {
|
||||
case JE:
|
||||
code = x64.Jump8IfEqual(code, 0x00)
|
||||
code = x86.Jump8IfEqual(code, 0x00)
|
||||
case JNE:
|
||||
code = x64.Jump8IfNotEqual(code, 0x00)
|
||||
code = x86.Jump8IfNotEqual(code, 0x00)
|
||||
case JG:
|
||||
code = x64.Jump8IfGreater(code, 0x00)
|
||||
code = x86.Jump8IfGreater(code, 0x00)
|
||||
case JGE:
|
||||
code = x64.Jump8IfGreaterOrEqual(code, 0x00)
|
||||
code = x86.Jump8IfGreaterOrEqual(code, 0x00)
|
||||
case JL:
|
||||
code = x64.Jump8IfLess(code, 0x00)
|
||||
code = x86.Jump8IfLess(code, 0x00)
|
||||
case JLE:
|
||||
code = x64.Jump8IfLessOrEqual(code, 0x00)
|
||||
code = x86.Jump8IfLessOrEqual(code, 0x00)
|
||||
case JUMP:
|
||||
code = x64.Jump8(code, 0x00)
|
||||
code = x86.Jump8(code, 0x00)
|
||||
}
|
||||
|
||||
size := 1
|
||||
@ -199,20 +199,20 @@ func (a Assembler) Finalize(dlls dll.List) ([]byte, []byte) {
|
||||
case LOAD:
|
||||
switch operands := x.Data.(type) {
|
||||
case *MemoryRegister:
|
||||
code = x64.LoadRegister(code, operands.Register, operands.Address.Offset, operands.Address.Length, operands.Address.Base)
|
||||
code = x86.LoadRegister(code, operands.Register, operands.Address.Offset, operands.Address.Length, operands.Address.Base)
|
||||
}
|
||||
|
||||
case MOVE:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.MoveRegisterNumber(code, operands.Register, operands.Number)
|
||||
code = x86.MoveRegisterNumber(code, operands.Register, operands.Number)
|
||||
|
||||
case *RegisterRegister:
|
||||
code = x64.MoveRegisterRegister(code, operands.Destination, operands.Source)
|
||||
code = x86.MoveRegisterRegister(code, operands.Destination, operands.Source)
|
||||
|
||||
case *RegisterLabel:
|
||||
start := len(code)
|
||||
code = x64.MoveRegisterNumber(code, operands.Register, 0x00_00_00_00)
|
||||
code = x86.MoveRegisterNumber(code, operands.Register, 0x00_00_00_00)
|
||||
size := 4
|
||||
opSize := len(code) - size - start
|
||||
regLabel := x.Data.(*RegisterLabel)
|
||||
@ -253,59 +253,59 @@ func (a Assembler) Finalize(dlls dll.List) ([]byte, []byte) {
|
||||
case NEGATE:
|
||||
switch operands := x.Data.(type) {
|
||||
case *Register:
|
||||
code = x64.NegateRegister(code, operands.Register)
|
||||
code = x86.NegateRegister(code, operands.Register)
|
||||
}
|
||||
|
||||
case OR:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.OrRegisterNumber(code, operands.Register, operands.Number)
|
||||
code = x86.OrRegisterNumber(code, operands.Register, operands.Number)
|
||||
case *RegisterRegister:
|
||||
code = x64.OrRegisterRegister(code, operands.Destination, operands.Source)
|
||||
code = x86.OrRegisterRegister(code, operands.Destination, operands.Source)
|
||||
}
|
||||
|
||||
case POP:
|
||||
switch operands := x.Data.(type) {
|
||||
case *Register:
|
||||
code = x64.PopRegister(code, operands.Register)
|
||||
code = x86.PopRegister(code, operands.Register)
|
||||
}
|
||||
|
||||
case PUSH:
|
||||
switch operands := x.Data.(type) {
|
||||
case *Register:
|
||||
code = x64.PushRegister(code, operands.Register)
|
||||
code = x86.PushRegister(code, operands.Register)
|
||||
}
|
||||
|
||||
case RETURN:
|
||||
code = x64.Return(code)
|
||||
code = x86.Return(code)
|
||||
|
||||
case SHIFTL:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.ShiftLeftNumber(code, operands.Register, byte(operands.Number)&0b111111)
|
||||
code = x86.ShiftLeftNumber(code, operands.Register, byte(operands.Number)&0b111111)
|
||||
}
|
||||
|
||||
case SHIFTRS:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.ShiftRightSignedNumber(code, operands.Register, byte(operands.Number)&0b111111)
|
||||
code = x86.ShiftRightSignedNumber(code, operands.Register, byte(operands.Number)&0b111111)
|
||||
}
|
||||
|
||||
case STORE:
|
||||
switch operands := x.Data.(type) {
|
||||
case *MemoryNumber:
|
||||
if operands.Address.OffsetRegister == math.MaxUint8 {
|
||||
code = x64.StoreNumber(code, operands.Address.Base, operands.Address.Offset, operands.Address.Length, operands.Number)
|
||||
code = x86.StoreNumber(code, operands.Address.Base, operands.Address.Offset, operands.Address.Length, operands.Number)
|
||||
} else {
|
||||
code = x64.StoreDynamicNumber(code, operands.Address.Base, operands.Address.OffsetRegister, operands.Address.Length, operands.Number)
|
||||
code = x86.StoreDynamicNumber(code, operands.Address.Base, operands.Address.OffsetRegister, operands.Address.Length, operands.Number)
|
||||
}
|
||||
case *MemoryLabel:
|
||||
start := len(code)
|
||||
|
||||
if operands.Address.OffsetRegister == math.MaxUint8 {
|
||||
code = x64.StoreNumber(code, operands.Address.Base, operands.Address.Offset, operands.Address.Length, 0b00_00_00_00)
|
||||
code = x86.StoreNumber(code, operands.Address.Base, operands.Address.Offset, operands.Address.Length, 0b00_00_00_00)
|
||||
} else {
|
||||
code = x64.StoreDynamicNumber(code, operands.Address.Base, operands.Address.OffsetRegister, operands.Address.Length, 0b00_00_00_00)
|
||||
code = x86.StoreDynamicNumber(code, operands.Address.Base, operands.Address.OffsetRegister, operands.Address.Length, 0b00_00_00_00)
|
||||
}
|
||||
|
||||
size := 4
|
||||
@ -328,21 +328,21 @@ func (a Assembler) Finalize(dlls dll.List) ([]byte, []byte) {
|
||||
})
|
||||
case *MemoryRegister:
|
||||
if operands.Address.OffsetRegister == math.MaxUint8 {
|
||||
code = x64.StoreRegister(code, operands.Address.Base, operands.Address.Offset, operands.Address.Length, operands.Register)
|
||||
code = x86.StoreRegister(code, operands.Address.Base, operands.Address.Offset, operands.Address.Length, operands.Register)
|
||||
} else {
|
||||
code = x64.StoreDynamicRegister(code, operands.Address.Base, operands.Address.OffsetRegister, operands.Address.Length, operands.Register)
|
||||
code = x86.StoreDynamicRegister(code, operands.Address.Base, operands.Address.OffsetRegister, operands.Address.Length, operands.Register)
|
||||
}
|
||||
}
|
||||
|
||||
case SYSCALL:
|
||||
code = x64.Syscall(code)
|
||||
code = x86.Syscall(code)
|
||||
|
||||
case XOR:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
code = x64.XorRegisterNumber(code, operands.Register, operands.Number)
|
||||
code = x86.XorRegisterNumber(code, operands.Register, operands.Number)
|
||||
case *RegisterRegister:
|
||||
code = x64.XorRegisterRegister(code, operands.Destination, operands.Source)
|
||||
code = x86.XorRegisterRegister(code, operands.Destination, operands.Source)
|
||||
}
|
||||
|
||||
default:
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"git.akyoto.dev/cli/q/src/elf"
|
||||
"git.akyoto.dev/cli/q/src/macho"
|
||||
"git.akyoto.dev/cli/q/src/pe"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/color/ansi"
|
||||
)
|
||||
|
||||
@ -43,15 +43,15 @@ func (r *Result) finalize() {
|
||||
|
||||
switch config.TargetOS {
|
||||
case config.Linux:
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], LinuxExit)
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0)
|
||||
final.RegisterNumber(asm.MOVE, x86.SyscallInputRegisters[0], LinuxExit)
|
||||
final.RegisterNumber(asm.MOVE, x86.SyscallInputRegisters[1], 0)
|
||||
final.Syscall()
|
||||
case config.Mac:
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], MacExit)
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0)
|
||||
final.RegisterNumber(asm.MOVE, x86.SyscallInputRegisters[0], MacExit)
|
||||
final.RegisterNumber(asm.MOVE, x86.SyscallInputRegisters[1], 0)
|
||||
final.Syscall()
|
||||
case config.Windows:
|
||||
final.RegisterNumber(asm.MOVE, x64.WindowsInputRegisters[0], 0)
|
||||
final.RegisterNumber(asm.MOVE, x86.WindowsInputRegisters[0], 0)
|
||||
final.DLLCall("kernel32.ExitProcess")
|
||||
}
|
||||
|
||||
@ -75,15 +75,15 @@ func (r *Result) finalize() {
|
||||
|
||||
switch config.TargetOS {
|
||||
case config.Linux:
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], LinuxExit)
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 1)
|
||||
final.RegisterNumber(asm.MOVE, x86.SyscallInputRegisters[0], LinuxExit)
|
||||
final.RegisterNumber(asm.MOVE, x86.SyscallInputRegisters[1], 1)
|
||||
final.Syscall()
|
||||
case config.Mac:
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], MacExit)
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 1)
|
||||
final.RegisterNumber(asm.MOVE, x86.SyscallInputRegisters[0], MacExit)
|
||||
final.RegisterNumber(asm.MOVE, x86.SyscallInputRegisters[1], 1)
|
||||
final.Syscall()
|
||||
case config.Windows:
|
||||
final.RegisterNumber(asm.MOVE, x64.WindowsInputRegisters[0], 1)
|
||||
final.RegisterNumber(asm.MOVE, x86.WindowsInputRegisters[0], 1)
|
||||
final.DLLCall("kernel32.ExitProcess")
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"git.akyoto.dev/cli/q/src/asm"
|
||||
"git.akyoto.dev/cli/q/src/ast"
|
||||
"git.akyoto.dev/cli/q/src/errors"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
)
|
||||
|
||||
// CompileAssignDivision compiles an assign statement that has quotient and remainder on the left side and division on the right.
|
||||
@ -37,8 +37,8 @@ func (f *Function) CompileAssignDivision(node *ast.Assign) error {
|
||||
|
||||
divisor := right.Children[1]
|
||||
err = f.Execute(right.Token, dividendRegister, divisor)
|
||||
f.RegisterRegister(asm.MOVE, quotientVariable.Register, x64.RAX)
|
||||
f.RegisterRegister(asm.MOVE, remainderVariable.Register, x64.RDX)
|
||||
f.RegisterRegister(asm.MOVE, quotientVariable.Register, x86.RAX)
|
||||
f.RegisterRegister(asm.MOVE, remainderVariable.Register, x86.RDX)
|
||||
|
||||
if isTemporary {
|
||||
f.FreeRegister(dividendRegister)
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"git.akyoto.dev/cli/q/src/errors"
|
||||
"git.akyoto.dev/cli/q/src/expression"
|
||||
"git.akyoto.dev/cli/q/src/types"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
)
|
||||
|
||||
// CompileCall executes a function call.
|
||||
@ -50,7 +50,7 @@ func (f *Function) CompileCall(root *expression.Expression) (*Function, error) {
|
||||
|
||||
if pkg == "kernel32" || pkg == "user32" || pkg == "gdi32" || pkg == "comctl32" {
|
||||
parameters := root.Children[1:]
|
||||
registers := x64.WindowsInputRegisters[:len(parameters)]
|
||||
registers := x86.WindowsInputRegisters[:len(parameters)]
|
||||
|
||||
for i := len(parameters) - 1; i >= 0; i-- {
|
||||
_, err := f.ExpressionToRegister(parameters[i], registers[i])
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/errors"
|
||||
"git.akyoto.dev/cli/q/src/token"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
)
|
||||
|
||||
// ExecuteRegisterNumber performs an operation on a register and a number.
|
||||
@ -25,16 +25,16 @@ func (f *Function) ExecuteRegisterNumber(operation token.Token, register cpu.Reg
|
||||
f.RegisterNumber(asm.MUL, register, number)
|
||||
|
||||
case token.Div, token.DivAssign:
|
||||
f.SaveRegister(x64.RAX)
|
||||
f.SaveRegister(x64.RDX)
|
||||
f.SaveRegister(x86.RAX)
|
||||
f.SaveRegister(x86.RDX)
|
||||
tmp := f.NewRegister()
|
||||
f.RegisterNumber(asm.MOVE, tmp, number)
|
||||
f.RegisterRegister(asm.DIV, register, tmp)
|
||||
f.FreeRegister(tmp)
|
||||
|
||||
case token.Mod, token.ModAssign:
|
||||
f.SaveRegister(x64.RAX)
|
||||
f.SaveRegister(x64.RDX)
|
||||
f.SaveRegister(x86.RAX)
|
||||
f.SaveRegister(x86.RDX)
|
||||
tmp := f.NewRegister()
|
||||
f.RegisterNumber(asm.MOVE, tmp, number)
|
||||
f.RegisterRegister(asm.MODULO, register, tmp)
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/errors"
|
||||
"git.akyoto.dev/cli/q/src/token"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
)
|
||||
|
||||
// ExecuteRegisterRegister performs an operation on two registers.
|
||||
@ -25,13 +25,13 @@ func (f *Function) ExecuteRegisterRegister(operation token.Token, register cpu.R
|
||||
f.RegisterRegister(asm.MUL, register, operand)
|
||||
|
||||
case token.Div, token.DivAssign:
|
||||
f.SaveRegister(x64.RAX)
|
||||
f.SaveRegister(x64.RDX)
|
||||
f.SaveRegister(x86.RAX)
|
||||
f.SaveRegister(x86.RDX)
|
||||
f.RegisterRegister(asm.DIV, register, operand)
|
||||
|
||||
case token.Mod, token.ModAssign:
|
||||
f.SaveRegister(x64.RAX)
|
||||
f.SaveRegister(x64.RDX)
|
||||
f.SaveRegister(x86.RAX)
|
||||
f.SaveRegister(x86.RDX)
|
||||
f.RegisterRegister(asm.MODULO, register, operand)
|
||||
|
||||
case token.And, token.AndAssign:
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"git.akyoto.dev/cli/q/src/register"
|
||||
"git.akyoto.dev/cli/q/src/scope"
|
||||
"git.akyoto.dev/cli/q/src/token"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
)
|
||||
|
||||
// NewFunction creates a new function.
|
||||
@ -26,12 +26,12 @@ func NewFunction(pkg string, name string, file *fs.File, body []token.Token) *Fu
|
||||
Scopes: []*scope.Scope{{}},
|
||||
},
|
||||
CPU: cpu.CPU{
|
||||
All: x64.AllRegisters,
|
||||
General: x64.GeneralRegisters,
|
||||
Input: x64.InputRegisters,
|
||||
Output: x64.OutputRegisters,
|
||||
SyscallInput: x64.SyscallInputRegisters,
|
||||
SyscallOutput: x64.SyscallOutputRegisters,
|
||||
All: x86.AllRegisters,
|
||||
General: x86.GeneralRegisters,
|
||||
Input: x86.InputRegisters,
|
||||
Output: x86.OutputRegisters,
|
||||
SyscallInput: x86.SyscallInputRegisters,
|
||||
SyscallOutput: x86.SyscallOutputRegisters,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"git.akyoto.dev/cli/q/src/errors"
|
||||
"git.akyoto.dev/cli/q/src/scope"
|
||||
"git.akyoto.dev/cli/q/src/token"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
)
|
||||
|
||||
// ResolveTypes parses the input and output types.
|
||||
@ -27,7 +27,7 @@ func (f *Function) ResolveTypes() error {
|
||||
f.AddVariable(&scope.Variable{
|
||||
Name: param.Name,
|
||||
Type: param.Type,
|
||||
Register: x64.InputRegisters[i],
|
||||
Register: x86.InputRegisters[i],
|
||||
Alive: uses,
|
||||
})
|
||||
}
|
||||
|
@ -24,4 +24,4 @@
|
||||
- [sizeof](sizeof) - Calculates the byte size of numbers
|
||||
- [token](token) - Converts a file to tokens with the `Tokenize` function
|
||||
- [types](types) - Type system (w.i.p.)
|
||||
- [x64](x64) - x86-64 implementation
|
||||
- [x86](x86) - x86-64 implementation
|
||||
|
@ -1,88 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestAddRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, 1, []byte{0x48, 0x83, 0xC0, 0x01}},
|
||||
{x64.RCX, 1, []byte{0x48, 0x83, 0xC1, 0x01}},
|
||||
{x64.RDX, 1, []byte{0x48, 0x83, 0xC2, 0x01}},
|
||||
{x64.RBX, 1, []byte{0x48, 0x83, 0xC3, 0x01}},
|
||||
{x64.RSP, 1, []byte{0x48, 0x83, 0xC4, 0x01}},
|
||||
{x64.RBP, 1, []byte{0x48, 0x83, 0xC5, 0x01}},
|
||||
{x64.RSI, 1, []byte{0x48, 0x83, 0xC6, 0x01}},
|
||||
{x64.RDI, 1, []byte{0x48, 0x83, 0xC7, 0x01}},
|
||||
{x64.R8, 1, []byte{0x49, 0x83, 0xC0, 0x01}},
|
||||
{x64.R9, 1, []byte{0x49, 0x83, 0xC1, 0x01}},
|
||||
{x64.R10, 1, []byte{0x49, 0x83, 0xC2, 0x01}},
|
||||
{x64.R11, 1, []byte{0x49, 0x83, 0xC3, 0x01}},
|
||||
{x64.R12, 1, []byte{0x49, 0x83, 0xC4, 0x01}},
|
||||
{x64.R13, 1, []byte{0x49, 0x83, 0xC5, 0x01}},
|
||||
{x64.R14, 1, []byte{0x49, 0x83, 0xC6, 0x01}},
|
||||
{x64.R15, 1, []byte{0x49, 0x83, 0xC7, 0x01}},
|
||||
|
||||
{x64.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("add %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.AddRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, []byte{0x4C, 0x01, 0xF8}},
|
||||
{x64.RCX, x64.R14, []byte{0x4C, 0x01, 0xF1}},
|
||||
{x64.RDX, x64.R13, []byte{0x4C, 0x01, 0xEA}},
|
||||
{x64.RBX, x64.R12, []byte{0x4C, 0x01, 0xE3}},
|
||||
{x64.RSP, x64.R11, []byte{0x4C, 0x01, 0xDC}},
|
||||
{x64.RBP, x64.R10, []byte{0x4C, 0x01, 0xD5}},
|
||||
{x64.RSI, x64.R9, []byte{0x4C, 0x01, 0xCE}},
|
||||
{x64.RDI, x64.R8, []byte{0x4C, 0x01, 0xC7}},
|
||||
{x64.R8, x64.RDI, []byte{0x49, 0x01, 0xF8}},
|
||||
{x64.R9, x64.RSI, []byte{0x49, 0x01, 0xF1}},
|
||||
{x64.R10, x64.RBP, []byte{0x49, 0x01, 0xEA}},
|
||||
{x64.R11, x64.RSP, []byte{0x49, 0x01, 0xE3}},
|
||||
{x64.R12, x64.RBX, []byte{0x49, 0x01, 0xDC}},
|
||||
{x64.R13, x64.RDX, []byte{0x49, 0x01, 0xD5}},
|
||||
{x64.R14, x64.RCX, []byte{0x49, 0x01, 0xCE}},
|
||||
{x64.R15, x64.RAX, []byte{0x49, 0x01, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("add %s, %s", pattern.Left, pattern.Right)
|
||||
code := x64.AddRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestAndRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, 1, []byte{0x48, 0x83, 0xE0, 0x01}},
|
||||
{x64.RCX, 1, []byte{0x48, 0x83, 0xE1, 0x01}},
|
||||
{x64.RDX, 1, []byte{0x48, 0x83, 0xE2, 0x01}},
|
||||
{x64.RBX, 1, []byte{0x48, 0x83, 0xE3, 0x01}},
|
||||
{x64.RSP, 1, []byte{0x48, 0x83, 0xE4, 0x01}},
|
||||
{x64.RBP, 1, []byte{0x48, 0x83, 0xE5, 0x01}},
|
||||
{x64.RSI, 1, []byte{0x48, 0x83, 0xE6, 0x01}},
|
||||
{x64.RDI, 1, []byte{0x48, 0x83, 0xE7, 0x01}},
|
||||
{x64.R8, 1, []byte{0x49, 0x83, 0xE0, 0x01}},
|
||||
{x64.R9, 1, []byte{0x49, 0x83, 0xE1, 0x01}},
|
||||
{x64.R10, 1, []byte{0x49, 0x83, 0xE2, 0x01}},
|
||||
{x64.R11, 1, []byte{0x49, 0x83, 0xE3, 0x01}},
|
||||
{x64.R12, 1, []byte{0x49, 0x83, 0xE4, 0x01}},
|
||||
{x64.R13, 1, []byte{0x49, 0x83, 0xE5, 0x01}},
|
||||
{x64.R14, 1, []byte{0x49, 0x83, 0xE6, 0x01}},
|
||||
{x64.R15, 1, []byte{0x49, 0x83, 0xE7, 0x01}},
|
||||
|
||||
{x64.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("and %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.AndRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAndRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, []byte{0x4C, 0x21, 0xF8}},
|
||||
{x64.RCX, x64.R14, []byte{0x4C, 0x21, 0xF1}},
|
||||
{x64.RDX, x64.R13, []byte{0x4C, 0x21, 0xEA}},
|
||||
{x64.RBX, x64.R12, []byte{0x4C, 0x21, 0xE3}},
|
||||
{x64.RSP, x64.R11, []byte{0x4C, 0x21, 0xDC}},
|
||||
{x64.RBP, x64.R10, []byte{0x4C, 0x21, 0xD5}},
|
||||
{x64.RSI, x64.R9, []byte{0x4C, 0x21, 0xCE}},
|
||||
{x64.RDI, x64.R8, []byte{0x4C, 0x21, 0xC7}},
|
||||
{x64.R8, x64.RDI, []byte{0x49, 0x21, 0xF8}},
|
||||
{x64.R9, x64.RSI, []byte{0x49, 0x21, 0xF1}},
|
||||
{x64.R10, x64.RBP, []byte{0x49, 0x21, 0xEA}},
|
||||
{x64.R11, x64.RSP, []byte{0x49, 0x21, 0xE3}},
|
||||
{x64.R12, x64.RBX, []byte{0x49, 0x21, 0xDC}},
|
||||
{x64.R13, x64.RDX, []byte{0x49, 0x21, 0xD5}},
|
||||
{x64.R14, x64.RCX, []byte{0x49, 0x21, 0xCE}},
|
||||
{x64.R15, x64.RAX, []byte{0x49, 0x21, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("and %s, %s", pattern.Left, pattern.Right)
|
||||
code := x64.AndRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestCompareRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, 1, []byte{0x48, 0x83, 0xF8, 0x01}},
|
||||
{x64.RCX, 1, []byte{0x48, 0x83, 0xF9, 0x01}},
|
||||
{x64.RDX, 1, []byte{0x48, 0x83, 0xFA, 0x01}},
|
||||
{x64.RBX, 1, []byte{0x48, 0x83, 0xFB, 0x01}},
|
||||
{x64.RSP, 1, []byte{0x48, 0x83, 0xFC, 0x01}},
|
||||
{x64.RBP, 1, []byte{0x48, 0x83, 0xFD, 0x01}},
|
||||
{x64.RSI, 1, []byte{0x48, 0x83, 0xFE, 0x01}},
|
||||
{x64.RDI, 1, []byte{0x48, 0x83, 0xFF, 0x01}},
|
||||
{x64.R8, 1, []byte{0x49, 0x83, 0xF8, 0x01}},
|
||||
{x64.R9, 1, []byte{0x49, 0x83, 0xF9, 0x01}},
|
||||
{x64.R10, 1, []byte{0x49, 0x83, 0xFA, 0x01}},
|
||||
{x64.R11, 1, []byte{0x49, 0x83, 0xFB, 0x01}},
|
||||
{x64.R12, 1, []byte{0x49, 0x83, 0xFC, 0x01}},
|
||||
{x64.R13, 1, []byte{0x49, 0x83, 0xFD, 0x01}},
|
||||
{x64.R14, 1, []byte{0x49, 0x83, 0xFE, 0x01}},
|
||||
{x64.R15, 1, []byte{0x49, 0x83, 0xFF, 0x01}},
|
||||
|
||||
{x64.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("cmp %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.CompareRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompareRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, []byte{0x4C, 0x39, 0xF8}},
|
||||
{x64.RCX, x64.R14, []byte{0x4C, 0x39, 0xF1}},
|
||||
{x64.RDX, x64.R13, []byte{0x4C, 0x39, 0xEA}},
|
||||
{x64.RBX, x64.R12, []byte{0x4C, 0x39, 0xE3}},
|
||||
{x64.RSP, x64.R11, []byte{0x4C, 0x39, 0xDC}},
|
||||
{x64.RBP, x64.R10, []byte{0x4C, 0x39, 0xD5}},
|
||||
{x64.RSI, x64.R9, []byte{0x4C, 0x39, 0xCE}},
|
||||
{x64.RDI, x64.R8, []byte{0x4C, 0x39, 0xC7}},
|
||||
{x64.R8, x64.RDI, []byte{0x49, 0x39, 0xF8}},
|
||||
{x64.R9, x64.RSI, []byte{0x49, 0x39, 0xF1}},
|
||||
{x64.R10, x64.RBP, []byte{0x49, 0x39, 0xEA}},
|
||||
{x64.R11, x64.RSP, []byte{0x49, 0x39, 0xE3}},
|
||||
{x64.R12, x64.RBX, []byte{0x49, 0x39, 0xDC}},
|
||||
{x64.R13, x64.RDX, []byte{0x49, 0x39, 0xD5}},
|
||||
{x64.R14, x64.RCX, []byte{0x49, 0x39, 0xCE}},
|
||||
{x64.R15, x64.RAX, []byte{0x49, 0x39, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("cmp %s, %s", pattern.Left, pattern.Right)
|
||||
code := x64.CompareRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestDivRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, []byte{0x48, 0xF7, 0xF8}},
|
||||
{x64.RCX, []byte{0x48, 0xF7, 0xF9}},
|
||||
{x64.RDX, []byte{0x48, 0xF7, 0xFA}},
|
||||
{x64.RBX, []byte{0x48, 0xF7, 0xFB}},
|
||||
{x64.RSP, []byte{0x48, 0xF7, 0xFC}},
|
||||
{x64.RBP, []byte{0x48, 0xF7, 0xFD}},
|
||||
{x64.RSI, []byte{0x48, 0xF7, 0xFE}},
|
||||
{x64.RDI, []byte{0x48, 0xF7, 0xFF}},
|
||||
{x64.R8, []byte{0x49, 0xF7, 0xF8}},
|
||||
{x64.R9, []byte{0x49, 0xF7, 0xF9}},
|
||||
{x64.R10, []byte{0x49, 0xF7, 0xFA}},
|
||||
{x64.R11, []byte{0x49, 0xF7, 0xFB}},
|
||||
{x64.R12, []byte{0x49, 0xF7, 0xFC}},
|
||||
{x64.R13, []byte{0x49, 0xF7, 0xFD}},
|
||||
{x64.R14, []byte{0x49, 0xF7, 0xFE}},
|
||||
{x64.R15, []byte{0x49, 0xF7, 0xFF}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("idiv %s", pattern.Register)
|
||||
code := x64.DivRegister(nil, pattern.Register)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestLoadRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Destination cpu.Register
|
||||
Source cpu.Register
|
||||
Offset byte
|
||||
Length byte
|
||||
Code []byte
|
||||
}{
|
||||
// No offset
|
||||
{x64.RAX, x64.R15, 0, 8, []byte{0x49, 0x8B, 0x07}},
|
||||
{x64.RAX, x64.R15, 0, 4, []byte{0x41, 0x8B, 0x07}},
|
||||
{x64.RAX, x64.R15, 0, 2, []byte{0x66, 0x41, 0x8B, 0x07}},
|
||||
{x64.RAX, x64.R15, 0, 1, []byte{0x41, 0x8A, 0x07}},
|
||||
{x64.RCX, x64.R14, 0, 8, []byte{0x49, 0x8B, 0x0E}},
|
||||
{x64.RCX, x64.R14, 0, 4, []byte{0x41, 0x8B, 0x0E}},
|
||||
{x64.RCX, x64.R14, 0, 2, []byte{0x66, 0x41, 0x8B, 0x0E}},
|
||||
{x64.RCX, x64.R14, 0, 1, []byte{0x41, 0x8A, 0x0E}},
|
||||
{x64.RDX, x64.R13, 0, 8, []byte{0x49, 0x8B, 0x55, 0x00}},
|
||||
{x64.RDX, x64.R13, 0, 4, []byte{0x41, 0x8B, 0x55, 0x00}},
|
||||
{x64.RDX, x64.R13, 0, 2, []byte{0x66, 0x41, 0x8B, 0x55, 0x00}},
|
||||
{x64.RDX, x64.R13, 0, 1, []byte{0x41, 0x8A, 0x55, 0x00}},
|
||||
{x64.RBX, x64.R12, 0, 8, []byte{0x49, 0x8B, 0x1C, 0x24}},
|
||||
{x64.RBX, x64.R12, 0, 4, []byte{0x41, 0x8B, 0x1C, 0x24}},
|
||||
{x64.RBX, x64.R12, 0, 2, []byte{0x66, 0x41, 0x8B, 0x1C, 0x24}},
|
||||
{x64.RBX, x64.R12, 0, 1, []byte{0x41, 0x8A, 0x1C, 0x24}},
|
||||
{x64.RSP, x64.R11, 0, 8, []byte{0x49, 0x8B, 0x23}},
|
||||
{x64.RSP, x64.R11, 0, 4, []byte{0x41, 0x8B, 0x23}},
|
||||
{x64.RSP, x64.R11, 0, 2, []byte{0x66, 0x41, 0x8B, 0x23}},
|
||||
{x64.RSP, x64.R11, 0, 1, []byte{0x41, 0x8A, 0x23}},
|
||||
{x64.RBP, x64.R10, 0, 8, []byte{0x49, 0x8B, 0x2A}},
|
||||
{x64.RBP, x64.R10, 0, 4, []byte{0x41, 0x8B, 0x2A}},
|
||||
{x64.RBP, x64.R10, 0, 2, []byte{0x66, 0x41, 0x8B, 0x2A}},
|
||||
{x64.RBP, x64.R10, 0, 1, []byte{0x41, 0x8A, 0x2A}},
|
||||
{x64.RSI, x64.R9, 0, 8, []byte{0x49, 0x8B, 0x31}},
|
||||
{x64.RSI, x64.R9, 0, 4, []byte{0x41, 0x8B, 0x31}},
|
||||
{x64.RSI, x64.R9, 0, 2, []byte{0x66, 0x41, 0x8B, 0x31}},
|
||||
{x64.RSI, x64.R9, 0, 1, []byte{0x41, 0x8A, 0x31}},
|
||||
{x64.RDI, x64.R8, 0, 8, []byte{0x49, 0x8B, 0x38}},
|
||||
{x64.RDI, x64.R8, 0, 4, []byte{0x41, 0x8B, 0x38}},
|
||||
{x64.RDI, x64.R8, 0, 2, []byte{0x66, 0x41, 0x8B, 0x38}},
|
||||
{x64.RDI, x64.R8, 0, 1, []byte{0x41, 0x8A, 0x38}},
|
||||
{x64.R8, x64.RDI, 0, 8, []byte{0x4C, 0x8B, 0x07}},
|
||||
{x64.R8, x64.RDI, 0, 4, []byte{0x44, 0x8B, 0x07}},
|
||||
{x64.R8, x64.RDI, 0, 2, []byte{0x66, 0x44, 0x8B, 0x07}},
|
||||
{x64.R8, x64.RDI, 0, 1, []byte{0x44, 0x8A, 0x07}},
|
||||
{x64.R9, x64.RSI, 0, 8, []byte{0x4C, 0x8B, 0x0E}},
|
||||
{x64.R9, x64.RSI, 0, 4, []byte{0x44, 0x8B, 0x0E}},
|
||||
{x64.R9, x64.RSI, 0, 2, []byte{0x66, 0x44, 0x8B, 0x0E}},
|
||||
{x64.R9, x64.RSI, 0, 1, []byte{0x44, 0x8A, 0x0E}},
|
||||
{x64.R10, x64.RBP, 0, 8, []byte{0x4C, 0x8B, 0x55, 0x00}},
|
||||
{x64.R10, x64.RBP, 0, 4, []byte{0x44, 0x8B, 0x55, 0x00}},
|
||||
{x64.R10, x64.RBP, 0, 2, []byte{0x66, 0x44, 0x8B, 0x55, 0x00}},
|
||||
{x64.R10, x64.RBP, 0, 1, []byte{0x44, 0x8A, 0x55, 0x00}},
|
||||
{x64.R11, x64.RSP, 0, 8, []byte{0x4C, 0x8B, 0x1C, 0x24}},
|
||||
{x64.R11, x64.RSP, 0, 4, []byte{0x44, 0x8B, 0x1C, 0x24}},
|
||||
{x64.R11, x64.RSP, 0, 2, []byte{0x66, 0x44, 0x8B, 0x1C, 0x24}},
|
||||
{x64.R11, x64.RSP, 0, 1, []byte{0x44, 0x8A, 0x1C, 0x24}},
|
||||
{x64.R12, x64.RBX, 0, 8, []byte{0x4C, 0x8B, 0x23}},
|
||||
{x64.R12, x64.RBX, 0, 4, []byte{0x44, 0x8B, 0x23}},
|
||||
{x64.R12, x64.RBX, 0, 2, []byte{0x66, 0x44, 0x8B, 0x23}},
|
||||
{x64.R12, x64.RBX, 0, 1, []byte{0x44, 0x8A, 0x23}},
|
||||
{x64.R13, x64.RDX, 0, 8, []byte{0x4C, 0x8B, 0x2A}},
|
||||
{x64.R13, x64.RDX, 0, 4, []byte{0x44, 0x8B, 0x2A}},
|
||||
{x64.R13, x64.RDX, 0, 2, []byte{0x66, 0x44, 0x8B, 0x2A}},
|
||||
{x64.R13, x64.RDX, 0, 1, []byte{0x44, 0x8A, 0x2A}},
|
||||
{x64.R14, x64.RCX, 0, 8, []byte{0x4C, 0x8B, 0x31}},
|
||||
{x64.R14, x64.RCX, 0, 4, []byte{0x44, 0x8B, 0x31}},
|
||||
{x64.R14, x64.RCX, 0, 2, []byte{0x66, 0x44, 0x8B, 0x31}},
|
||||
{x64.R14, x64.RCX, 0, 1, []byte{0x44, 0x8A, 0x31}},
|
||||
{x64.R15, x64.RAX, 0, 8, []byte{0x4C, 0x8B, 0x38}},
|
||||
{x64.R15, x64.RAX, 0, 4, []byte{0x44, 0x8B, 0x38}},
|
||||
{x64.R15, x64.RAX, 0, 2, []byte{0x66, 0x44, 0x8B, 0x38}},
|
||||
{x64.R15, x64.RAX, 0, 1, []byte{0x44, 0x8A, 0x38}},
|
||||
|
||||
// Offset of 1
|
||||
{x64.RAX, x64.R15, 1, 8, []byte{0x49, 0x8B, 0x47, 0x01}},
|
||||
{x64.RAX, x64.R15, 1, 4, []byte{0x41, 0x8B, 0x47, 0x01}},
|
||||
{x64.RAX, x64.R15, 1, 2, []byte{0x66, 0x41, 0x8B, 0x47, 0x01}},
|
||||
{x64.RAX, x64.R15, 1, 1, []byte{0x41, 0x8A, 0x47, 0x01}},
|
||||
{x64.RCX, x64.R14, 1, 8, []byte{0x49, 0x8B, 0x4E, 0x01}},
|
||||
{x64.RCX, x64.R14, 1, 4, []byte{0x41, 0x8B, 0x4E, 0x01}},
|
||||
{x64.RCX, x64.R14, 1, 2, []byte{0x66, 0x41, 0x8B, 0x4E, 0x01}},
|
||||
{x64.RCX, x64.R14, 1, 1, []byte{0x41, 0x8A, 0x4E, 0x01}},
|
||||
{x64.RDX, x64.R13, 1, 8, []byte{0x49, 0x8B, 0x55, 0x01}},
|
||||
{x64.RDX, x64.R13, 1, 4, []byte{0x41, 0x8B, 0x55, 0x01}},
|
||||
{x64.RDX, x64.R13, 1, 2, []byte{0x66, 0x41, 0x8B, 0x55, 0x01}},
|
||||
{x64.RDX, x64.R13, 1, 1, []byte{0x41, 0x8A, 0x55, 0x01}},
|
||||
{x64.RBX, x64.R12, 1, 8, []byte{0x49, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x64.RBX, x64.R12, 1, 4, []byte{0x41, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x64.RBX, x64.R12, 1, 2, []byte{0x66, 0x41, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x64.RBX, x64.R12, 1, 1, []byte{0x41, 0x8A, 0x5C, 0x24, 0x01}},
|
||||
{x64.RSP, x64.R11, 1, 8, []byte{0x49, 0x8B, 0x63, 0x01}},
|
||||
{x64.RSP, x64.R11, 1, 4, []byte{0x41, 0x8B, 0x63, 0x01}},
|
||||
{x64.RSP, x64.R11, 1, 2, []byte{0x66, 0x41, 0x8B, 0x63, 0x01}},
|
||||
{x64.RSP, x64.R11, 1, 1, []byte{0x41, 0x8A, 0x63, 0x01}},
|
||||
{x64.RBP, x64.R10, 1, 8, []byte{0x49, 0x8B, 0x6A, 0x01}},
|
||||
{x64.RBP, x64.R10, 1, 4, []byte{0x41, 0x8B, 0x6A, 0x01}},
|
||||
{x64.RBP, x64.R10, 1, 2, []byte{0x66, 0x41, 0x8B, 0x6A, 0x01}},
|
||||
{x64.RBP, x64.R10, 1, 1, []byte{0x41, 0x8A, 0x6A, 0x01}},
|
||||
{x64.RSI, x64.R9, 1, 8, []byte{0x49, 0x8B, 0x71, 0x01}},
|
||||
{x64.RSI, x64.R9, 1, 4, []byte{0x41, 0x8B, 0x71, 0x01}},
|
||||
{x64.RSI, x64.R9, 1, 2, []byte{0x66, 0x41, 0x8B, 0x71, 0x01}},
|
||||
{x64.RSI, x64.R9, 1, 1, []byte{0x41, 0x8A, 0x71, 0x01}},
|
||||
{x64.RDI, x64.R8, 1, 8, []byte{0x49, 0x8B, 0x78, 0x01}},
|
||||
{x64.RDI, x64.R8, 1, 4, []byte{0x41, 0x8B, 0x78, 0x01}},
|
||||
{x64.RDI, x64.R8, 1, 2, []byte{0x66, 0x41, 0x8B, 0x78, 0x01}},
|
||||
{x64.RDI, x64.R8, 1, 1, []byte{0x41, 0x8A, 0x78, 0x01}},
|
||||
{x64.R8, x64.RDI, 1, 8, []byte{0x4C, 0x8B, 0x47, 0x01}},
|
||||
{x64.R8, x64.RDI, 1, 4, []byte{0x44, 0x8B, 0x47, 0x01}},
|
||||
{x64.R8, x64.RDI, 1, 2, []byte{0x66, 0x44, 0x8B, 0x47, 0x01}},
|
||||
{x64.R8, x64.RDI, 1, 1, []byte{0x44, 0x8A, 0x47, 0x01}},
|
||||
{x64.R9, x64.RSI, 1, 8, []byte{0x4C, 0x8B, 0x4E, 0x01}},
|
||||
{x64.R9, x64.RSI, 1, 4, []byte{0x44, 0x8B, 0x4E, 0x01}},
|
||||
{x64.R9, x64.RSI, 1, 2, []byte{0x66, 0x44, 0x8B, 0x4E, 0x01}},
|
||||
{x64.R9, x64.RSI, 1, 1, []byte{0x44, 0x8A, 0x4E, 0x01}},
|
||||
{x64.R10, x64.RBP, 1, 8, []byte{0x4C, 0x8B, 0x55, 0x01}},
|
||||
{x64.R10, x64.RBP, 1, 4, []byte{0x44, 0x8B, 0x55, 0x01}},
|
||||
{x64.R10, x64.RBP, 1, 2, []byte{0x66, 0x44, 0x8B, 0x55, 0x01}},
|
||||
{x64.R10, x64.RBP, 1, 1, []byte{0x44, 0x8A, 0x55, 0x01}},
|
||||
{x64.R11, x64.RSP, 1, 8, []byte{0x4C, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x64.R11, x64.RSP, 1, 4, []byte{0x44, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x64.R11, x64.RSP, 1, 2, []byte{0x66, 0x44, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x64.R11, x64.RSP, 1, 1, []byte{0x44, 0x8A, 0x5C, 0x24, 0x01}},
|
||||
{x64.R12, x64.RBX, 1, 8, []byte{0x4C, 0x8B, 0x63, 0x01}},
|
||||
{x64.R12, x64.RBX, 1, 4, []byte{0x44, 0x8B, 0x63, 0x01}},
|
||||
{x64.R12, x64.RBX, 1, 2, []byte{0x66, 0x44, 0x8B, 0x63, 0x01}},
|
||||
{x64.R12, x64.RBX, 1, 1, []byte{0x44, 0x8A, 0x63, 0x01}},
|
||||
{x64.R13, x64.RDX, 1, 8, []byte{0x4C, 0x8B, 0x6A, 0x01}},
|
||||
{x64.R13, x64.RDX, 1, 4, []byte{0x44, 0x8B, 0x6A, 0x01}},
|
||||
{x64.R13, x64.RDX, 1, 2, []byte{0x66, 0x44, 0x8B, 0x6A, 0x01}},
|
||||
{x64.R13, x64.RDX, 1, 1, []byte{0x44, 0x8A, 0x6A, 0x01}},
|
||||
{x64.R14, x64.RCX, 1, 8, []byte{0x4C, 0x8B, 0x71, 0x01}},
|
||||
{x64.R14, x64.RCX, 1, 4, []byte{0x44, 0x8B, 0x71, 0x01}},
|
||||
{x64.R14, x64.RCX, 1, 2, []byte{0x66, 0x44, 0x8B, 0x71, 0x01}},
|
||||
{x64.R14, x64.RCX, 1, 1, []byte{0x44, 0x8A, 0x71, 0x01}},
|
||||
{x64.R15, x64.RAX, 1, 8, []byte{0x4C, 0x8B, 0x78, 0x01}},
|
||||
{x64.R15, x64.RAX, 1, 4, []byte{0x44, 0x8B, 0x78, 0x01}},
|
||||
{x64.R15, x64.RAX, 1, 2, []byte{0x66, 0x44, 0x8B, 0x78, 0x01}},
|
||||
{x64.R15, x64.RAX, 1, 1, []byte{0x44, 0x8A, 0x78, 0x01}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("load %dB %s, [%s+%d]", pattern.Length, pattern.Destination, pattern.Source, pattern.Offset)
|
||||
code := x64.LoadRegister(nil, pattern.Destination, pattern.Offset, pattern.Length, pattern.Source)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestMoveRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
// 32 bits
|
||||
{x64.RAX, 0x7FFFFFFF, []byte{0xB8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RCX, 0x7FFFFFFF, []byte{0xB9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDX, 0x7FFFFFFF, []byte{0xBA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBX, 0x7FFFFFFF, []byte{0xBB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSP, 0x7FFFFFFF, []byte{0xBC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBP, 0x7FFFFFFF, []byte{0xBD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSI, 0x7FFFFFFF, []byte{0xBE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDI, 0x7FFFFFFF, []byte{0xBF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R8, 0x7FFFFFFF, []byte{0x41, 0xB8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R9, 0x7FFFFFFF, []byte{0x41, 0xB9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R10, 0x7FFFFFFF, []byte{0x41, 0xBA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R11, 0x7FFFFFFF, []byte{0x41, 0xBB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R12, 0x7FFFFFFF, []byte{0x41, 0xBC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R13, 0x7FFFFFFF, []byte{0x41, 0xBD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R14, 0x7FFFFFFF, []byte{0x41, 0xBE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R15, 0x7FFFFFFF, []byte{0x41, 0xBF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
|
||||
// 64 bits
|
||||
{x64.RAX, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RCX, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDX, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBX, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSP, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBP, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSI, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDI, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R8, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R9, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R10, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R11, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R12, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R13, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R14, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R15, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
|
||||
// Negative numbers
|
||||
{x64.RAX, -1, []byte{0x48, 0xC7, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.RCX, -1, []byte{0x48, 0xC7, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.RDX, -1, []byte{0x48, 0xC7, 0xC2, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.RBX, -1, []byte{0x48, 0xC7, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.RSP, -1, []byte{0x48, 0xC7, 0xC4, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.RBP, -1, []byte{0x48, 0xC7, 0xC5, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.RSI, -1, []byte{0x48, 0xC7, 0xC6, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.RDI, -1, []byte{0x48, 0xC7, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.R8, -1, []byte{0x49, 0xC7, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.R9, -1, []byte{0x49, 0xC7, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.R10, -1, []byte{0x49, 0xC7, 0xC2, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.R11, -1, []byte{0x49, 0xC7, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.R12, -1, []byte{0x49, 0xC7, 0xC4, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.R13, -1, []byte{0x49, 0xC7, 0xC5, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.R14, -1, []byte{0x49, 0xC7, 0xC6, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x64.R15, -1, []byte{0x49, 0xC7, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("mov %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.MoveRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMoveRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, []byte{0x4C, 0x89, 0xF8}},
|
||||
{x64.RCX, x64.R14, []byte{0x4C, 0x89, 0xF1}},
|
||||
{x64.RDX, x64.R13, []byte{0x4C, 0x89, 0xEA}},
|
||||
{x64.RBX, x64.R12, []byte{0x4C, 0x89, 0xE3}},
|
||||
{x64.RSP, x64.R11, []byte{0x4C, 0x89, 0xDC}},
|
||||
{x64.RBP, x64.R10, []byte{0x4C, 0x89, 0xD5}},
|
||||
{x64.RSI, x64.R9, []byte{0x4C, 0x89, 0xCE}},
|
||||
{x64.RDI, x64.R8, []byte{0x4C, 0x89, 0xC7}},
|
||||
{x64.R8, x64.RDI, []byte{0x49, 0x89, 0xF8}},
|
||||
{x64.R9, x64.RSI, []byte{0x49, 0x89, 0xF1}},
|
||||
{x64.R10, x64.RBP, []byte{0x49, 0x89, 0xEA}},
|
||||
{x64.R11, x64.RSP, []byte{0x49, 0x89, 0xE3}},
|
||||
{x64.R12, x64.RBX, []byte{0x49, 0x89, 0xDC}},
|
||||
{x64.R13, x64.RDX, []byte{0x49, 0x89, 0xD5}},
|
||||
{x64.R14, x64.RCX, []byte{0x49, 0x89, 0xCE}},
|
||||
{x64.R15, x64.RAX, []byte{0x49, 0x89, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("mov %s, %s", pattern.Left, pattern.Right)
|
||||
code := x64.MoveRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestMulRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, 1, []byte{0x48, 0x6B, 0xC0, 0x01}},
|
||||
{x64.RCX, 1, []byte{0x48, 0x6B, 0xC9, 0x01}},
|
||||
{x64.RDX, 1, []byte{0x48, 0x6B, 0xD2, 0x01}},
|
||||
{x64.RBX, 1, []byte{0x48, 0x6B, 0xDB, 0x01}},
|
||||
{x64.RSP, 1, []byte{0x48, 0x6B, 0xE4, 0x01}},
|
||||
{x64.RBP, 1, []byte{0x48, 0x6B, 0xED, 0x01}},
|
||||
{x64.RSI, 1, []byte{0x48, 0x6B, 0xF6, 0x01}},
|
||||
{x64.RDI, 1, []byte{0x48, 0x6B, 0xFF, 0x01}},
|
||||
{x64.R8, 1, []byte{0x4D, 0x6B, 0xC0, 0x01}},
|
||||
{x64.R9, 1, []byte{0x4D, 0x6B, 0xC9, 0x01}},
|
||||
{x64.R10, 1, []byte{0x4D, 0x6B, 0xD2, 0x01}},
|
||||
{x64.R11, 1, []byte{0x4D, 0x6B, 0xDB, 0x01}},
|
||||
{x64.R12, 1, []byte{0x4D, 0x6B, 0xE4, 0x01}},
|
||||
{x64.R13, 1, []byte{0x4D, 0x6B, 0xED, 0x01}},
|
||||
{x64.R14, 1, []byte{0x4D, 0x6B, 0xF6, 0x01}},
|
||||
{x64.R15, 1, []byte{0x4D, 0x6B, 0xFF, 0x01}},
|
||||
|
||||
{x64.RAX, 0x7FFFFFFF, []byte{0x48, 0x69, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RCX, 0x7FFFFFFF, []byte{0x48, 0x69, 0xC9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDX, 0x7FFFFFFF, []byte{0x48, 0x69, 0xD2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBX, 0x7FFFFFFF, []byte{0x48, 0x69, 0xDB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSP, 0x7FFFFFFF, []byte{0x48, 0x69, 0xE4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBP, 0x7FFFFFFF, []byte{0x48, 0x69, 0xED, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSI, 0x7FFFFFFF, []byte{0x48, 0x69, 0xF6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDI, 0x7FFFFFFF, []byte{0x48, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R8, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R9, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xC9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R10, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xD2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R11, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xDB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R12, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xE4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R13, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xED, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R14, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xF6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R15, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("mul %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.MulRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMulRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, []byte{0x49, 0x0F, 0xAF, 0xC7}},
|
||||
{x64.RCX, x64.R14, []byte{0x49, 0x0F, 0xAF, 0xCE}},
|
||||
{x64.RDX, x64.R13, []byte{0x49, 0x0F, 0xAF, 0xD5}},
|
||||
{x64.RBX, x64.R12, []byte{0x49, 0x0F, 0xAF, 0xDC}},
|
||||
{x64.RSP, x64.R11, []byte{0x49, 0x0F, 0xAF, 0xE3}},
|
||||
{x64.RBP, x64.R10, []byte{0x49, 0x0F, 0xAF, 0xEA}},
|
||||
{x64.RSI, x64.R9, []byte{0x49, 0x0F, 0xAF, 0xF1}},
|
||||
{x64.RDI, x64.R8, []byte{0x49, 0x0F, 0xAF, 0xF8}},
|
||||
{x64.R8, x64.RDI, []byte{0x4C, 0x0F, 0xAF, 0xC7}},
|
||||
{x64.R9, x64.RSI, []byte{0x4C, 0x0F, 0xAF, 0xCE}},
|
||||
{x64.R10, x64.RBP, []byte{0x4C, 0x0F, 0xAF, 0xD5}},
|
||||
{x64.R11, x64.RSP, []byte{0x4C, 0x0F, 0xAF, 0xDC}},
|
||||
{x64.R12, x64.RBX, []byte{0x4C, 0x0F, 0xAF, 0xE3}},
|
||||
{x64.R13, x64.RDX, []byte{0x4C, 0x0F, 0xAF, 0xEA}},
|
||||
{x64.R14, x64.RCX, []byte{0x4C, 0x0F, 0xAF, 0xF1}},
|
||||
{x64.R15, x64.RAX, []byte{0x4C, 0x0F, 0xAF, 0xF8}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("mul %s, %s", pattern.Left, pattern.Right)
|
||||
code := x64.MulRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestNegateRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, []byte{0x48, 0xF7, 0xD8}},
|
||||
{x64.RCX, []byte{0x48, 0xF7, 0xD9}},
|
||||
{x64.RDX, []byte{0x48, 0xF7, 0xDA}},
|
||||
{x64.RBX, []byte{0x48, 0xF7, 0xDB}},
|
||||
{x64.RSP, []byte{0x48, 0xF7, 0xDC}},
|
||||
{x64.RBP, []byte{0x48, 0xF7, 0xDD}},
|
||||
{x64.RSI, []byte{0x48, 0xF7, 0xDE}},
|
||||
{x64.RDI, []byte{0x48, 0xF7, 0xDF}},
|
||||
{x64.R8, []byte{0x49, 0xF7, 0xD8}},
|
||||
{x64.R9, []byte{0x49, 0xF7, 0xD9}},
|
||||
{x64.R10, []byte{0x49, 0xF7, 0xDA}},
|
||||
{x64.R11, []byte{0x49, 0xF7, 0xDB}},
|
||||
{x64.R12, []byte{0x49, 0xF7, 0xDC}},
|
||||
{x64.R13, []byte{0x49, 0xF7, 0xDD}},
|
||||
{x64.R14, []byte{0x49, 0xF7, 0xDE}},
|
||||
{x64.R15, []byte{0x49, 0xF7, 0xDF}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("neg %s", pattern.Register)
|
||||
code := x64.NegateRegister(nil, pattern.Register)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestOrRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, 1, []byte{0x48, 0x83, 0xC8, 0x01}},
|
||||
{x64.RCX, 1, []byte{0x48, 0x83, 0xC9, 0x01}},
|
||||
{x64.RDX, 1, []byte{0x48, 0x83, 0xCA, 0x01}},
|
||||
{x64.RBX, 1, []byte{0x48, 0x83, 0xCB, 0x01}},
|
||||
{x64.RSP, 1, []byte{0x48, 0x83, 0xCC, 0x01}},
|
||||
{x64.RBP, 1, []byte{0x48, 0x83, 0xCD, 0x01}},
|
||||
{x64.RSI, 1, []byte{0x48, 0x83, 0xCE, 0x01}},
|
||||
{x64.RDI, 1, []byte{0x48, 0x83, 0xCF, 0x01}},
|
||||
{x64.R8, 1, []byte{0x49, 0x83, 0xC8, 0x01}},
|
||||
{x64.R9, 1, []byte{0x49, 0x83, 0xC9, 0x01}},
|
||||
{x64.R10, 1, []byte{0x49, 0x83, 0xCA, 0x01}},
|
||||
{x64.R11, 1, []byte{0x49, 0x83, 0xCB, 0x01}},
|
||||
{x64.R12, 1, []byte{0x49, 0x83, 0xCC, 0x01}},
|
||||
{x64.R13, 1, []byte{0x49, 0x83, 0xCD, 0x01}},
|
||||
{x64.R14, 1, []byte{0x49, 0x83, 0xCE, 0x01}},
|
||||
{x64.R15, 1, []byte{0x49, 0x83, 0xCF, 0x01}},
|
||||
|
||||
{x64.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("or %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.OrRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, []byte{0x4C, 0x09, 0xF8}},
|
||||
{x64.RCX, x64.R14, []byte{0x4C, 0x09, 0xF1}},
|
||||
{x64.RDX, x64.R13, []byte{0x4C, 0x09, 0xEA}},
|
||||
{x64.RBX, x64.R12, []byte{0x4C, 0x09, 0xE3}},
|
||||
{x64.RSP, x64.R11, []byte{0x4C, 0x09, 0xDC}},
|
||||
{x64.RBP, x64.R10, []byte{0x4C, 0x09, 0xD5}},
|
||||
{x64.RSI, x64.R9, []byte{0x4C, 0x09, 0xCE}},
|
||||
{x64.RDI, x64.R8, []byte{0x4C, 0x09, 0xC7}},
|
||||
{x64.R8, x64.RDI, []byte{0x49, 0x09, 0xF8}},
|
||||
{x64.R9, x64.RSI, []byte{0x49, 0x09, 0xF1}},
|
||||
{x64.R10, x64.RBP, []byte{0x49, 0x09, 0xEA}},
|
||||
{x64.R11, x64.RSP, []byte{0x49, 0x09, 0xE3}},
|
||||
{x64.R12, x64.RBX, []byte{0x49, 0x09, 0xDC}},
|
||||
{x64.R13, x64.RDX, []byte{0x49, 0x09, 0xD5}},
|
||||
{x64.R14, x64.RCX, []byte{0x49, 0x09, 0xCE}},
|
||||
{x64.R15, x64.RAX, []byte{0x49, 0x09, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("or %s, %s", pattern.Left, pattern.Right)
|
||||
code := x64.OrRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestPopRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, []byte{0x58}},
|
||||
{x64.RCX, []byte{0x59}},
|
||||
{x64.RDX, []byte{0x5A}},
|
||||
{x64.RBX, []byte{0x5B}},
|
||||
{x64.RSP, []byte{0x5C}},
|
||||
{x64.RBP, []byte{0x5D}},
|
||||
{x64.RSI, []byte{0x5E}},
|
||||
{x64.RDI, []byte{0x5F}},
|
||||
{x64.R8, []byte{0x41, 0x58}},
|
||||
{x64.R9, []byte{0x41, 0x59}},
|
||||
{x64.R10, []byte{0x41, 0x5A}},
|
||||
{x64.R11, []byte{0x41, 0x5B}},
|
||||
{x64.R12, []byte{0x41, 0x5C}},
|
||||
{x64.R13, []byte{0x41, 0x5D}},
|
||||
{x64.R14, []byte{0x41, 0x5E}},
|
||||
{x64.R15, []byte{0x41, 0x5F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("pop %s", pattern.Register)
|
||||
code := x64.PopRegister(nil, pattern.Register)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestPushRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, []byte{0x50}},
|
||||
{x64.RCX, []byte{0x51}},
|
||||
{x64.RDX, []byte{0x52}},
|
||||
{x64.RBX, []byte{0x53}},
|
||||
{x64.RSP, []byte{0x54}},
|
||||
{x64.RBP, []byte{0x55}},
|
||||
{x64.RSI, []byte{0x56}},
|
||||
{x64.RDI, []byte{0x57}},
|
||||
{x64.R8, []byte{0x41, 0x50}},
|
||||
{x64.R9, []byte{0x41, 0x51}},
|
||||
{x64.R10, []byte{0x41, 0x52}},
|
||||
{x64.R11, []byte{0x41, 0x53}},
|
||||
{x64.R12, []byte{0x41, 0x54}},
|
||||
{x64.R13, []byte{0x41, 0x55}},
|
||||
{x64.R14, []byte{0x41, 0x56}},
|
||||
{x64.R15, []byte{0x41, 0x57}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("push %s", pattern.Register)
|
||||
code := x64.PushRegister(nil, pattern.Register)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestRegisters(t *testing.T) {
|
||||
assert.NotContains(t, x64.GeneralRegisters, x64.RSP)
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestShiftLeftNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, 1, []byte{0x48, 0xC1, 0xE0, 0x01}},
|
||||
{x64.RCX, 1, []byte{0x48, 0xC1, 0xE1, 0x01}},
|
||||
{x64.RDX, 1, []byte{0x48, 0xC1, 0xE2, 0x01}},
|
||||
{x64.RBX, 1, []byte{0x48, 0xC1, 0xE3, 0x01}},
|
||||
{x64.RSP, 1, []byte{0x48, 0xC1, 0xE4, 0x01}},
|
||||
{x64.RBP, 1, []byte{0x48, 0xC1, 0xE5, 0x01}},
|
||||
{x64.RSI, 1, []byte{0x48, 0xC1, 0xE6, 0x01}},
|
||||
{x64.RDI, 1, []byte{0x48, 0xC1, 0xE7, 0x01}},
|
||||
{x64.R8, 1, []byte{0x49, 0xC1, 0xE0, 0x01}},
|
||||
{x64.R9, 1, []byte{0x49, 0xC1, 0xE1, 0x01}},
|
||||
{x64.R10, 1, []byte{0x49, 0xC1, 0xE2, 0x01}},
|
||||
{x64.R11, 1, []byte{0x49, 0xC1, 0xE3, 0x01}},
|
||||
{x64.R12, 1, []byte{0x49, 0xC1, 0xE4, 0x01}},
|
||||
{x64.R13, 1, []byte{0x49, 0xC1, 0xE5, 0x01}},
|
||||
{x64.R14, 1, []byte{0x49, 0xC1, 0xE6, 0x01}},
|
||||
{x64.R15, 1, []byte{0x49, 0xC1, 0xE7, 0x01}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("shl %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.ShiftLeftNumber(nil, pattern.Register, byte(pattern.Number))
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShiftRightSignedNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, 1, []byte{0x48, 0xC1, 0xF8, 0x01}},
|
||||
{x64.RCX, 1, []byte{0x48, 0xC1, 0xF9, 0x01}},
|
||||
{x64.RDX, 1, []byte{0x48, 0xC1, 0xFA, 0x01}},
|
||||
{x64.RBX, 1, []byte{0x48, 0xC1, 0xFB, 0x01}},
|
||||
{x64.RSP, 1, []byte{0x48, 0xC1, 0xFC, 0x01}},
|
||||
{x64.RBP, 1, []byte{0x48, 0xC1, 0xFD, 0x01}},
|
||||
{x64.RSI, 1, []byte{0x48, 0xC1, 0xFE, 0x01}},
|
||||
{x64.RDI, 1, []byte{0x48, 0xC1, 0xFF, 0x01}},
|
||||
{x64.R8, 1, []byte{0x49, 0xC1, 0xF8, 0x01}},
|
||||
{x64.R9, 1, []byte{0x49, 0xC1, 0xF9, 0x01}},
|
||||
{x64.R10, 1, []byte{0x49, 0xC1, 0xFA, 0x01}},
|
||||
{x64.R11, 1, []byte{0x49, 0xC1, 0xFB, 0x01}},
|
||||
{x64.R12, 1, []byte{0x49, 0xC1, 0xFC, 0x01}},
|
||||
{x64.R13, 1, []byte{0x49, 0xC1, 0xFD, 0x01}},
|
||||
{x64.R14, 1, []byte{0x49, 0xC1, 0xFE, 0x01}},
|
||||
{x64.R15, 1, []byte{0x49, 0xC1, 0xFF, 0x01}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("sar %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.ShiftRightSignedNumber(nil, pattern.Register, byte(pattern.Number))
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestStoreDynamicNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
RegisterTo cpu.Register
|
||||
Offset cpu.Register
|
||||
Length byte
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RAX, x64.R15, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RAX, x64.R15, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x38, 0x7F, 0x00}},
|
||||
{x64.RAX, x64.R15, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x38, 0x7F}},
|
||||
{x64.RCX, x64.R14, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RCX, x64.R14, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RCX, x64.R14, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x31, 0x7F, 0x00}},
|
||||
{x64.RCX, x64.R14, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x31, 0x7F}},
|
||||
{x64.RDX, x64.R13, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDX, x64.R13, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDX, x64.R13, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x2A, 0x7F, 0x00}},
|
||||
{x64.RDX, x64.R13, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x2A, 0x7F}},
|
||||
{x64.RBX, x64.R12, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x23, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBX, x64.R12, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x23, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBX, x64.R12, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x23, 0x7F, 0x00}},
|
||||
{x64.RBX, x64.R12, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x23, 0x7F}},
|
||||
{x64.RSP, x64.R11, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSP, x64.R11, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSP, x64.R11, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00}},
|
||||
{x64.RSP, x64.R11, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x1C, 0x7F}},
|
||||
{x64.RBP, x64.R10, 8, 0x7F, []byte{0x4A, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBP, x64.R10, 4, 0x7F, []byte{0x42, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBP, x64.R10, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00}},
|
||||
{x64.RBP, x64.R10, 1, 0x7F, []byte{0x42, 0xC6, 0x44, 0x15, 0x00, 0x7F}},
|
||||
{x64.RSI, x64.R9, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSI, x64.R9, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSI, x64.R9, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x0E, 0x7F, 0x00}},
|
||||
{x64.RSI, x64.R9, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x0E, 0x7F}},
|
||||
{x64.RDI, x64.R8, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDI, x64.R8, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDI, x64.R8, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x07, 0x7F, 0x00}},
|
||||
{x64.RDI, x64.R8, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x07, 0x7F}},
|
||||
{x64.R8, x64.RDI, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R8, x64.RDI, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R8, x64.RDI, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x38, 0x7F, 0x00}},
|
||||
{x64.R8, x64.RDI, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x38, 0x7F}},
|
||||
{x64.R9, x64.RSI, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R9, x64.RSI, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R9, x64.RSI, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x31, 0x7F, 0x00}},
|
||||
{x64.R9, x64.RSI, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x31, 0x7F}},
|
||||
{x64.R10, x64.RBP, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R10, x64.RBP, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R10, x64.RBP, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x2A, 0x7F, 0x00}},
|
||||
{x64.R10, x64.RBP, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x2A, 0x7F}},
|
||||
{x64.R11, x64.RSP, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R11, x64.RSP, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R11, x64.RSP, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00}},
|
||||
{x64.R11, x64.RSP, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x1C, 0x7F}},
|
||||
{x64.R12, x64.RBX, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R12, x64.RBX, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R12, x64.RBX, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x1C, 0x7F, 0x00}},
|
||||
{x64.R12, x64.RBX, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x1C, 0x7F}},
|
||||
{x64.R13, x64.RDX, 8, 0x7F, []byte{0x49, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R13, x64.RDX, 4, 0x7F, []byte{0x41, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R13, x64.RDX, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00}},
|
||||
{x64.R13, x64.RDX, 1, 0x7F, []byte{0x41, 0xC6, 0x44, 0x15, 0x00, 0x7F}},
|
||||
{x64.R14, x64.RCX, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R14, x64.RCX, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R14, x64.RCX, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x0E, 0x7F, 0x00}},
|
||||
{x64.R14, x64.RCX, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x0E, 0x7F}},
|
||||
{x64.R15, x64.RAX, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R15, x64.RAX, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R15, x64.RAX, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x07, 0x7F, 0x00}},
|
||||
{x64.R15, x64.RAX, 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 := x64.StoreDynamicNumber(nil, pattern.RegisterTo, pattern.Offset, pattern.Length, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreDynamicRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
RegisterTo cpu.Register
|
||||
Offset cpu.Register
|
||||
Length byte
|
||||
RegisterFrom cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, 8, x64.R15, []byte{0x4E, 0x89, 0x3C, 0x38}},
|
||||
{x64.RAX, x64.R15, 4, x64.R15, []byte{0x46, 0x89, 0x3C, 0x38}},
|
||||
{x64.RAX, x64.R15, 2, x64.R15, []byte{0x66, 0x46, 0x89, 0x3C, 0x38}},
|
||||
{x64.RAX, x64.R15, 1, x64.R15, []byte{0x46, 0x88, 0x3C, 0x38}},
|
||||
{x64.RCX, x64.R14, 8, x64.R14, []byte{0x4E, 0x89, 0x34, 0x31}},
|
||||
{x64.RCX, x64.R14, 4, x64.R14, []byte{0x46, 0x89, 0x34, 0x31}},
|
||||
{x64.RCX, x64.R14, 2, x64.R14, []byte{0x66, 0x46, 0x89, 0x34, 0x31}},
|
||||
{x64.RCX, x64.R14, 1, x64.R14, []byte{0x46, 0x88, 0x34, 0x31}},
|
||||
{x64.RDX, x64.R13, 8, x64.R13, []byte{0x4E, 0x89, 0x2C, 0x2A}},
|
||||
{x64.RDX, x64.R13, 4, x64.R13, []byte{0x46, 0x89, 0x2C, 0x2A}},
|
||||
{x64.RDX, x64.R13, 2, x64.R13, []byte{0x66, 0x46, 0x89, 0x2C, 0x2A}},
|
||||
{x64.RDX, x64.R13, 1, x64.R13, []byte{0x46, 0x88, 0x2C, 0x2A}},
|
||||
{x64.RBX, x64.R12, 8, x64.R12, []byte{0x4E, 0x89, 0x24, 0x23}},
|
||||
{x64.RBX, x64.R12, 4, x64.R12, []byte{0x46, 0x89, 0x24, 0x23}},
|
||||
{x64.RBX, x64.R12, 2, x64.R12, []byte{0x66, 0x46, 0x89, 0x24, 0x23}},
|
||||
{x64.RBX, x64.R12, 1, x64.R12, []byte{0x46, 0x88, 0x24, 0x23}},
|
||||
{x64.RSP, x64.R11, 8, x64.R11, []byte{0x4E, 0x89, 0x1C, 0x1C}},
|
||||
{x64.RSP, x64.R11, 4, x64.R11, []byte{0x46, 0x89, 0x1C, 0x1C}},
|
||||
{x64.RSP, x64.R11, 2, x64.R11, []byte{0x66, 0x46, 0x89, 0x1C, 0x1C}},
|
||||
{x64.RSP, x64.R11, 1, x64.R11, []byte{0x46, 0x88, 0x1C, 0x1C}},
|
||||
{x64.RBP, x64.R10, 8, x64.R10, []byte{0x4E, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x64.RBP, x64.R10, 4, x64.R10, []byte{0x46, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x64.RBP, x64.R10, 2, x64.R10, []byte{0x66, 0x46, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x64.RBP, x64.R10, 1, x64.R10, []byte{0x46, 0x88, 0x54, 0x15, 0x00}},
|
||||
{x64.RSI, x64.R9, 8, x64.R9, []byte{0x4E, 0x89, 0x0C, 0x0E}},
|
||||
{x64.RSI, x64.R9, 4, x64.R9, []byte{0x46, 0x89, 0x0C, 0x0E}},
|
||||
{x64.RSI, x64.R9, 2, x64.R9, []byte{0x66, 0x46, 0x89, 0x0C, 0x0E}},
|
||||
{x64.RSI, x64.R9, 1, x64.R9, []byte{0x46, 0x88, 0x0C, 0x0E}},
|
||||
{x64.RDI, x64.R8, 8, x64.R8, []byte{0x4E, 0x89, 0x04, 0x07}},
|
||||
{x64.RDI, x64.R8, 4, x64.R8, []byte{0x46, 0x89, 0x04, 0x07}},
|
||||
{x64.RDI, x64.R8, 2, x64.R8, []byte{0x66, 0x46, 0x89, 0x04, 0x07}},
|
||||
{x64.RDI, x64.R8, 1, x64.R8, []byte{0x46, 0x88, 0x04, 0x07}},
|
||||
{x64.R8, x64.RDI, 8, x64.RDI, []byte{0x49, 0x89, 0x3C, 0x38}},
|
||||
{x64.R8, x64.RDI, 4, x64.RDI, []byte{0x41, 0x89, 0x3C, 0x38}},
|
||||
{x64.R8, x64.RDI, 2, x64.RDI, []byte{0x66, 0x41, 0x89, 0x3C, 0x38}},
|
||||
{x64.R8, x64.RDI, 1, x64.RDI, []byte{0x41, 0x88, 0x3C, 0x38}},
|
||||
{x64.R9, x64.RSI, 8, x64.RSI, []byte{0x49, 0x89, 0x34, 0x31}},
|
||||
{x64.R9, x64.RSI, 4, x64.RSI, []byte{0x41, 0x89, 0x34, 0x31}},
|
||||
{x64.R9, x64.RSI, 2, x64.RSI, []byte{0x66, 0x41, 0x89, 0x34, 0x31}},
|
||||
{x64.R9, x64.RSI, 1, x64.RSI, []byte{0x41, 0x88, 0x34, 0x31}},
|
||||
{x64.R10, x64.RBP, 8, x64.RBP, []byte{0x49, 0x89, 0x2C, 0x2A}},
|
||||
{x64.R10, x64.RBP, 4, x64.RBP, []byte{0x41, 0x89, 0x2C, 0x2A}},
|
||||
{x64.R10, x64.RBP, 2, x64.RBP, []byte{0x66, 0x41, 0x89, 0x2C, 0x2A}},
|
||||
{x64.R10, x64.RBP, 1, x64.RBP, []byte{0x41, 0x88, 0x2C, 0x2A}},
|
||||
{x64.R11, x64.RSP, 8, x64.RSP, []byte{0x4A, 0x89, 0x24, 0x1C}},
|
||||
{x64.R11, x64.RSP, 4, x64.RSP, []byte{0x42, 0x89, 0x24, 0x1C}},
|
||||
{x64.R11, x64.RSP, 2, x64.RSP, []byte{0x66, 0x42, 0x89, 0x24, 0x1C}},
|
||||
{x64.R11, x64.RSP, 1, x64.RSP, []byte{0x42, 0x88, 0x24, 0x1C}},
|
||||
{x64.R12, x64.RBX, 8, x64.RBX, []byte{0x49, 0x89, 0x1C, 0x1C}},
|
||||
{x64.R12, x64.RBX, 4, x64.RBX, []byte{0x41, 0x89, 0x1C, 0x1C}},
|
||||
{x64.R12, x64.RBX, 2, x64.RBX, []byte{0x66, 0x41, 0x89, 0x1C, 0x1C}},
|
||||
{x64.R12, x64.RBX, 1, x64.RBX, []byte{0x41, 0x88, 0x1C, 0x1C}},
|
||||
{x64.R13, x64.RDX, 8, x64.RDX, []byte{0x49, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x64.R13, x64.RDX, 4, x64.RDX, []byte{0x41, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x64.R13, x64.RDX, 2, x64.RDX, []byte{0x66, 0x41, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x64.R13, x64.RDX, 1, x64.RDX, []byte{0x41, 0x88, 0x54, 0x15, 0x00}},
|
||||
{x64.R14, x64.RCX, 8, x64.RCX, []byte{0x49, 0x89, 0x0C, 0x0E}},
|
||||
{x64.R14, x64.RCX, 4, x64.RCX, []byte{0x41, 0x89, 0x0C, 0x0E}},
|
||||
{x64.R14, x64.RCX, 2, x64.RCX, []byte{0x66, 0x41, 0x89, 0x0C, 0x0E}},
|
||||
{x64.R14, x64.RCX, 1, x64.RCX, []byte{0x41, 0x88, 0x0C, 0x0E}},
|
||||
{x64.R15, x64.RAX, 8, x64.RAX, []byte{0x49, 0x89, 0x04, 0x07}},
|
||||
{x64.R15, x64.RAX, 4, x64.RAX, []byte{0x41, 0x89, 0x04, 0x07}},
|
||||
{x64.R15, x64.RAX, 2, x64.RAX, []byte{0x66, 0x41, 0x89, 0x04, 0x07}},
|
||||
{x64.R15, x64.RAX, 1, x64.RAX, []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 := x64.StoreDynamicRegister(nil, pattern.RegisterTo, pattern.Offset, pattern.Length, pattern.RegisterFrom)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,305 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestStoreNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Offset byte
|
||||
Length byte
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
// No offset
|
||||
{x64.RAX, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RAX, 0, 4, 0x7F, []byte{0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RAX, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x00, 0x7F, 0x00}},
|
||||
{x64.RAX, 0, 1, 0x7F, []byte{0xC6, 0x00, 0x7F}},
|
||||
{x64.RCX, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RCX, 0, 4, 0x7F, []byte{0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RCX, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x01, 0x7F, 0x00}},
|
||||
{x64.RCX, 0, 1, 0x7F, []byte{0xC6, 0x01, 0x7F}},
|
||||
{x64.RDX, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDX, 0, 4, 0x7F, []byte{0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDX, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x02, 0x7F, 0x00}},
|
||||
{x64.RDX, 0, 1, 0x7F, []byte{0xC6, 0x02, 0x7F}},
|
||||
{x64.RBX, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBX, 0, 4, 0x7F, []byte{0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBX, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x03, 0x7F, 0x00}},
|
||||
{x64.RBX, 0, 1, 0x7F, []byte{0xC6, 0x03, 0x7F}},
|
||||
{x64.RSP, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSP, 0, 4, 0x7F, []byte{0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSP, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x04, 0x24, 0x7F, 0x00}},
|
||||
{x64.RSP, 0, 1, 0x7F, []byte{0xC6, 0x04, 0x24, 0x7F}},
|
||||
{x64.RBP, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBP, 0, 4, 0x7F, []byte{0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBP, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x45, 0x00, 0x7F, 0x00}},
|
||||
{x64.RBP, 0, 1, 0x7F, []byte{0xC6, 0x45, 0x00, 0x7F}},
|
||||
{x64.RSI, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSI, 0, 4, 0x7F, []byte{0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSI, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x06, 0x7F, 0x00}},
|
||||
{x64.RSI, 0, 1, 0x7F, []byte{0xC6, 0x06, 0x7F}},
|
||||
{x64.RDI, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDI, 0, 4, 0x7F, []byte{0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDI, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x07, 0x7F, 0x00}},
|
||||
{x64.RDI, 0, 1, 0x7F, []byte{0xC6, 0x07, 0x7F}},
|
||||
{x64.R8, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R8, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R8, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x00, 0x7F, 0x00}},
|
||||
{x64.R8, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x00, 0x7F}},
|
||||
{x64.R9, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R9, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R9, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x01, 0x7F, 0x00}},
|
||||
{x64.R9, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x01, 0x7F}},
|
||||
{x64.R10, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R10, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R10, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x02, 0x7F, 0x00}},
|
||||
{x64.R10, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x02, 0x7F}},
|
||||
{x64.R11, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R11, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R11, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x03, 0x7F, 0x00}},
|
||||
{x64.R11, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x03, 0x7F}},
|
||||
{x64.R12, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R12, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R12, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x24, 0x7F, 0x00}},
|
||||
{x64.R12, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x24, 0x7F}},
|
||||
{x64.R13, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R13, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R13, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x45, 0x00, 0x7F, 0x00}},
|
||||
{x64.R13, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x45, 0x00, 0x7F}},
|
||||
{x64.R14, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R14, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R14, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x06, 0x7F, 0x00}},
|
||||
{x64.R14, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x06, 0x7F}},
|
||||
{x64.R15, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R15, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R15, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x07, 0x7F, 0x00}},
|
||||
{x64.R15, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x07, 0x7F}},
|
||||
|
||||
// Offset of 1
|
||||
{x64.RAX, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RAX, 1, 4, 0x7F, []byte{0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RAX, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x40, 0x01, 0x7F, 0x00}},
|
||||
{x64.RAX, 1, 1, 0x7F, []byte{0xC6, 0x40, 0x01, 0x7F}},
|
||||
{x64.RCX, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RCX, 1, 4, 0x7F, []byte{0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RCX, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x41, 0x01, 0x7F, 0x00}},
|
||||
{x64.RCX, 1, 1, 0x7F, []byte{0xC6, 0x41, 0x01, 0x7F}},
|
||||
{x64.RDX, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDX, 1, 4, 0x7F, []byte{0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDX, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x42, 0x01, 0x7F, 0x00}},
|
||||
{x64.RDX, 1, 1, 0x7F, []byte{0xC6, 0x42, 0x01, 0x7F}},
|
||||
{x64.RBX, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBX, 1, 4, 0x7F, []byte{0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBX, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x43, 0x01, 0x7F, 0x00}},
|
||||
{x64.RBX, 1, 1, 0x7F, []byte{0xC6, 0x43, 0x01, 0x7F}},
|
||||
{x64.RSP, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSP, 1, 4, 0x7F, []byte{0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSP, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00}},
|
||||
{x64.RSP, 1, 1, 0x7F, []byte{0xC6, 0x44, 0x24, 0x01, 0x7F}},
|
||||
{x64.RBP, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBP, 1, 4, 0x7F, []byte{0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RBP, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x45, 0x01, 0x7F, 0x00}},
|
||||
{x64.RBP, 1, 1, 0x7F, []byte{0xC6, 0x45, 0x01, 0x7F}},
|
||||
{x64.RSI, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSI, 1, 4, 0x7F, []byte{0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RSI, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x46, 0x01, 0x7F, 0x00}},
|
||||
{x64.RSI, 1, 1, 0x7F, []byte{0xC6, 0x46, 0x01, 0x7F}},
|
||||
{x64.RDI, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDI, 1, 4, 0x7F, []byte{0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.RDI, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x47, 0x01, 0x7F, 0x00}},
|
||||
{x64.RDI, 1, 1, 0x7F, []byte{0xC6, 0x47, 0x01, 0x7F}},
|
||||
{x64.R8, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R8, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R8, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x40, 0x01, 0x7F, 0x00}},
|
||||
{x64.R8, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x40, 0x01, 0x7F}},
|
||||
{x64.R9, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R9, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R9, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x41, 0x01, 0x7F, 0x00}},
|
||||
{x64.R9, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x41, 0x01, 0x7F}},
|
||||
{x64.R10, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R10, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R10, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x42, 0x01, 0x7F, 0x00}},
|
||||
{x64.R10, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x42, 0x01, 0x7F}},
|
||||
{x64.R11, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R11, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R11, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x43, 0x01, 0x7F, 0x00}},
|
||||
{x64.R11, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x43, 0x01, 0x7F}},
|
||||
{x64.R12, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R12, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R12, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00}},
|
||||
{x64.R12, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x44, 0x24, 0x01, 0x7F}},
|
||||
{x64.R13, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R13, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R13, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x45, 0x01, 0x7F, 0x00}},
|
||||
{x64.R13, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x45, 0x01, 0x7F}},
|
||||
{x64.R14, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R14, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R14, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x46, 0x01, 0x7F, 0x00}},
|
||||
{x64.R14, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x46, 0x01, 0x7F}},
|
||||
{x64.R15, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R15, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x64.R15, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x47, 0x01, 0x7F, 0x00}},
|
||||
{x64.R15, 1, 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 := x64.StoreNumber(nil, pattern.Register, pattern.Offset, pattern.Length, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
RegisterTo cpu.Register
|
||||
Offset byte
|
||||
Length byte
|
||||
RegisterFrom cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
// No offset
|
||||
{x64.RAX, 0, 8, x64.R15, []byte{0x4C, 0x89, 0x38}},
|
||||
{x64.RAX, 0, 4, x64.R15, []byte{0x44, 0x89, 0x38}},
|
||||
{x64.RAX, 0, 2, x64.R15, []byte{0x66, 0x44, 0x89, 0x38}},
|
||||
{x64.RAX, 0, 1, x64.R15, []byte{0x44, 0x88, 0x38}},
|
||||
{x64.RCX, 0, 8, x64.R14, []byte{0x4C, 0x89, 0x31}},
|
||||
{x64.RCX, 0, 4, x64.R14, []byte{0x44, 0x89, 0x31}},
|
||||
{x64.RCX, 0, 2, x64.R14, []byte{0x66, 0x44, 0x89, 0x31}},
|
||||
{x64.RCX, 0, 1, x64.R14, []byte{0x44, 0x88, 0x31}},
|
||||
{x64.RDX, 0, 8, x64.R13, []byte{0x4C, 0x89, 0x2A}},
|
||||
{x64.RDX, 0, 4, x64.R13, []byte{0x44, 0x89, 0x2A}},
|
||||
{x64.RDX, 0, 2, x64.R13, []byte{0x66, 0x44, 0x89, 0x2A}},
|
||||
{x64.RDX, 0, 1, x64.R13, []byte{0x44, 0x88, 0x2A}},
|
||||
{x64.RBX, 0, 8, x64.R12, []byte{0x4C, 0x89, 0x23}},
|
||||
{x64.RBX, 0, 4, x64.R12, []byte{0x44, 0x89, 0x23}},
|
||||
{x64.RBX, 0, 2, x64.R12, []byte{0x66, 0x44, 0x89, 0x23}},
|
||||
{x64.RBX, 0, 1, x64.R12, []byte{0x44, 0x88, 0x23}},
|
||||
{x64.RSP, 0, 8, x64.R11, []byte{0x4C, 0x89, 0x1C, 0x24}},
|
||||
{x64.RSP, 0, 4, x64.R11, []byte{0x44, 0x89, 0x1C, 0x24}},
|
||||
{x64.RSP, 0, 2, x64.R11, []byte{0x66, 0x44, 0x89, 0x1C, 0x24}},
|
||||
{x64.RSP, 0, 1, x64.R11, []byte{0x44, 0x88, 0x1C, 0x24}},
|
||||
{x64.RBP, 0, 8, x64.R10, []byte{0x4C, 0x89, 0x55, 0x00}},
|
||||
{x64.RBP, 0, 4, x64.R10, []byte{0x44, 0x89, 0x55, 0x00}},
|
||||
{x64.RBP, 0, 2, x64.R10, []byte{0x66, 0x44, 0x89, 0x55, 0x00}},
|
||||
{x64.RBP, 0, 1, x64.R10, []byte{0x44, 0x88, 0x55, 0x00}},
|
||||
{x64.RSI, 0, 8, x64.R9, []byte{0x4C, 0x89, 0x0E}},
|
||||
{x64.RSI, 0, 4, x64.R9, []byte{0x44, 0x89, 0x0E}},
|
||||
{x64.RSI, 0, 2, x64.R9, []byte{0x66, 0x44, 0x89, 0x0E}},
|
||||
{x64.RSI, 0, 1, x64.R9, []byte{0x44, 0x88, 0x0E}},
|
||||
{x64.RDI, 0, 8, x64.R8, []byte{0x4C, 0x89, 0x07}},
|
||||
{x64.RDI, 0, 4, x64.R8, []byte{0x44, 0x89, 0x07}},
|
||||
{x64.RDI, 0, 2, x64.R8, []byte{0x66, 0x44, 0x89, 0x07}},
|
||||
{x64.RDI, 0, 1, x64.R8, []byte{0x44, 0x88, 0x07}},
|
||||
{x64.R8, 0, 8, x64.RDI, []byte{0x49, 0x89, 0x38}},
|
||||
{x64.R8, 0, 4, x64.RDI, []byte{0x41, 0x89, 0x38}},
|
||||
{x64.R8, 0, 2, x64.RDI, []byte{0x66, 0x41, 0x89, 0x38}},
|
||||
{x64.R8, 0, 1, x64.RDI, []byte{0x41, 0x88, 0x38}},
|
||||
{x64.R9, 0, 8, x64.RSI, []byte{0x49, 0x89, 0x31}},
|
||||
{x64.R9, 0, 4, x64.RSI, []byte{0x41, 0x89, 0x31}},
|
||||
{x64.R9, 0, 2, x64.RSI, []byte{0x66, 0x41, 0x89, 0x31}},
|
||||
{x64.R9, 0, 1, x64.RSI, []byte{0x41, 0x88, 0x31}},
|
||||
{x64.R10, 0, 8, x64.RBP, []byte{0x49, 0x89, 0x2A}},
|
||||
{x64.R10, 0, 4, x64.RBP, []byte{0x41, 0x89, 0x2A}},
|
||||
{x64.R10, 0, 2, x64.RBP, []byte{0x66, 0x41, 0x89, 0x2A}},
|
||||
{x64.R10, 0, 1, x64.RBP, []byte{0x41, 0x88, 0x2A}},
|
||||
{x64.R11, 0, 8, x64.RSP, []byte{0x49, 0x89, 0x23}},
|
||||
{x64.R11, 0, 4, x64.RSP, []byte{0x41, 0x89, 0x23}},
|
||||
{x64.R11, 0, 2, x64.RSP, []byte{0x66, 0x41, 0x89, 0x23}},
|
||||
{x64.R11, 0, 1, x64.RSP, []byte{0x41, 0x88, 0x23}},
|
||||
{x64.R12, 0, 8, x64.RBX, []byte{0x49, 0x89, 0x1C, 0x24}},
|
||||
{x64.R12, 0, 4, x64.RBX, []byte{0x41, 0x89, 0x1C, 0x24}},
|
||||
{x64.R12, 0, 2, x64.RBX, []byte{0x66, 0x41, 0x89, 0x1C, 0x24}},
|
||||
{x64.R12, 0, 1, x64.RBX, []byte{0x41, 0x88, 0x1C, 0x24}},
|
||||
{x64.R13, 0, 8, x64.RDX, []byte{0x49, 0x89, 0x55, 0x00}},
|
||||
{x64.R13, 0, 4, x64.RDX, []byte{0x41, 0x89, 0x55, 0x00}},
|
||||
{x64.R13, 0, 2, x64.RDX, []byte{0x66, 0x41, 0x89, 0x55, 0x00}},
|
||||
{x64.R13, 0, 1, x64.RDX, []byte{0x41, 0x88, 0x55, 0x00}},
|
||||
{x64.R14, 0, 8, x64.RCX, []byte{0x49, 0x89, 0x0E}},
|
||||
{x64.R14, 0, 4, x64.RCX, []byte{0x41, 0x89, 0x0E}},
|
||||
{x64.R14, 0, 2, x64.RCX, []byte{0x66, 0x41, 0x89, 0x0E}},
|
||||
{x64.R14, 0, 1, x64.RCX, []byte{0x41, 0x88, 0x0E}},
|
||||
{x64.R15, 0, 8, x64.RAX, []byte{0x49, 0x89, 0x07}},
|
||||
{x64.R15, 0, 4, x64.RAX, []byte{0x41, 0x89, 0x07}},
|
||||
{x64.R15, 0, 2, x64.RAX, []byte{0x66, 0x41, 0x89, 0x07}},
|
||||
{x64.R15, 0, 1, x64.RAX, []byte{0x41, 0x88, 0x07}},
|
||||
|
||||
// Offset of 1
|
||||
{x64.RAX, 1, 8, x64.R15, []byte{0x4C, 0x89, 0x78, 0x01}},
|
||||
{x64.RAX, 1, 4, x64.R15, []byte{0x44, 0x89, 0x78, 0x01}},
|
||||
{x64.RAX, 1, 2, x64.R15, []byte{0x66, 0x44, 0x89, 0x78, 0x01}},
|
||||
{x64.RAX, 1, 1, x64.R15, []byte{0x44, 0x88, 0x78, 0x01}},
|
||||
{x64.RCX, 1, 8, x64.R14, []byte{0x4C, 0x89, 0x71, 0x01}},
|
||||
{x64.RCX, 1, 4, x64.R14, []byte{0x44, 0x89, 0x71, 0x01}},
|
||||
{x64.RCX, 1, 2, x64.R14, []byte{0x66, 0x44, 0x89, 0x71, 0x01}},
|
||||
{x64.RCX, 1, 1, x64.R14, []byte{0x44, 0x88, 0x71, 0x01}},
|
||||
{x64.RDX, 1, 8, x64.R13, []byte{0x4C, 0x89, 0x6A, 0x01}},
|
||||
{x64.RDX, 1, 4, x64.R13, []byte{0x44, 0x89, 0x6A, 0x01}},
|
||||
{x64.RDX, 1, 2, x64.R13, []byte{0x66, 0x44, 0x89, 0x6A, 0x01}},
|
||||
{x64.RDX, 1, 1, x64.R13, []byte{0x44, 0x88, 0x6A, 0x01}},
|
||||
{x64.RBX, 1, 8, x64.R12, []byte{0x4C, 0x89, 0x63, 0x01}},
|
||||
{x64.RBX, 1, 4, x64.R12, []byte{0x44, 0x89, 0x63, 0x01}},
|
||||
{x64.RBX, 1, 2, x64.R12, []byte{0x66, 0x44, 0x89, 0x63, 0x01}},
|
||||
{x64.RBX, 1, 1, x64.R12, []byte{0x44, 0x88, 0x63, 0x01}},
|
||||
{x64.RSP, 1, 8, x64.R11, []byte{0x4C, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x64.RSP, 1, 4, x64.R11, []byte{0x44, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x64.RSP, 1, 2, x64.R11, []byte{0x66, 0x44, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x64.RSP, 1, 1, x64.R11, []byte{0x44, 0x88, 0x5C, 0x24, 0x01}},
|
||||
{x64.RBP, 1, 8, x64.R10, []byte{0x4C, 0x89, 0x55, 0x01}},
|
||||
{x64.RBP, 1, 4, x64.R10, []byte{0x44, 0x89, 0x55, 0x01}},
|
||||
{x64.RBP, 1, 2, x64.R10, []byte{0x66, 0x44, 0x89, 0x55, 0x01}},
|
||||
{x64.RBP, 1, 1, x64.R10, []byte{0x44, 0x88, 0x55, 0x01}},
|
||||
{x64.RSI, 1, 8, x64.R9, []byte{0x4C, 0x89, 0x4E, 0x01}},
|
||||
{x64.RSI, 1, 4, x64.R9, []byte{0x44, 0x89, 0x4E, 0x01}},
|
||||
{x64.RSI, 1, 2, x64.R9, []byte{0x66, 0x44, 0x89, 0x4E, 0x01}},
|
||||
{x64.RSI, 1, 1, x64.R9, []byte{0x44, 0x88, 0x4E, 0x01}},
|
||||
{x64.RDI, 1, 8, x64.R8, []byte{0x4C, 0x89, 0x47, 0x01}},
|
||||
{x64.RDI, 1, 4, x64.R8, []byte{0x44, 0x89, 0x47, 0x01}},
|
||||
{x64.RDI, 1, 2, x64.R8, []byte{0x66, 0x44, 0x89, 0x47, 0x01}},
|
||||
{x64.RDI, 1, 1, x64.R8, []byte{0x44, 0x88, 0x47, 0x01}},
|
||||
{x64.R8, 1, 8, x64.RDI, []byte{0x49, 0x89, 0x78, 0x01}},
|
||||
{x64.R8, 1, 4, x64.RDI, []byte{0x41, 0x89, 0x78, 0x01}},
|
||||
{x64.R8, 1, 2, x64.RDI, []byte{0x66, 0x41, 0x89, 0x78, 0x01}},
|
||||
{x64.R8, 1, 1, x64.RDI, []byte{0x41, 0x88, 0x78, 0x01}},
|
||||
{x64.R9, 1, 8, x64.RSI, []byte{0x49, 0x89, 0x71, 0x01}},
|
||||
{x64.R9, 1, 4, x64.RSI, []byte{0x41, 0x89, 0x71, 0x01}},
|
||||
{x64.R9, 1, 2, x64.RSI, []byte{0x66, 0x41, 0x89, 0x71, 0x01}},
|
||||
{x64.R9, 1, 1, x64.RSI, []byte{0x41, 0x88, 0x71, 0x01}},
|
||||
{x64.R10, 1, 8, x64.RBP, []byte{0x49, 0x89, 0x6A, 0x01}},
|
||||
{x64.R10, 1, 4, x64.RBP, []byte{0x41, 0x89, 0x6A, 0x01}},
|
||||
{x64.R10, 1, 2, x64.RBP, []byte{0x66, 0x41, 0x89, 0x6A, 0x01}},
|
||||
{x64.R10, 1, 1, x64.RBP, []byte{0x41, 0x88, 0x6A, 0x01}},
|
||||
{x64.R11, 1, 8, x64.RSP, []byte{0x49, 0x89, 0x63, 0x01}},
|
||||
{x64.R11, 1, 4, x64.RSP, []byte{0x41, 0x89, 0x63, 0x01}},
|
||||
{x64.R11, 1, 2, x64.RSP, []byte{0x66, 0x41, 0x89, 0x63, 0x01}},
|
||||
{x64.R11, 1, 1, x64.RSP, []byte{0x41, 0x88, 0x63, 0x01}},
|
||||
{x64.R12, 1, 8, x64.RBX, []byte{0x49, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x64.R12, 1, 4, x64.RBX, []byte{0x41, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x64.R12, 1, 2, x64.RBX, []byte{0x66, 0x41, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x64.R12, 1, 1, x64.RBX, []byte{0x41, 0x88, 0x5C, 0x24, 01}},
|
||||
{x64.R13, 1, 8, x64.RDX, []byte{0x49, 0x89, 0x55, 0x01}},
|
||||
{x64.R13, 1, 4, x64.RDX, []byte{0x41, 0x89, 0x55, 0x01}},
|
||||
{x64.R13, 1, 2, x64.RDX, []byte{0x66, 0x41, 0x89, 0x55, 0x01}},
|
||||
{x64.R13, 1, 1, x64.RDX, []byte{0x41, 0x88, 0x55, 0x01}},
|
||||
{x64.R14, 1, 8, x64.RCX, []byte{0x49, 0x89, 0x4E, 0x01}},
|
||||
{x64.R14, 1, 4, x64.RCX, []byte{0x41, 0x89, 0x4E, 0x01}},
|
||||
{x64.R14, 1, 2, x64.RCX, []byte{0x66, 0x41, 0x89, 0x4E, 0x01}},
|
||||
{x64.R14, 1, 1, x64.RCX, []byte{0x41, 0x88, 0x4E, 0x01}},
|
||||
{x64.R15, 1, 8, x64.RAX, []byte{0x49, 0x89, 0x47, 0x01}},
|
||||
{x64.R15, 1, 4, x64.RAX, []byte{0x41, 0x89, 0x47, 0x01}},
|
||||
{x64.R15, 1, 2, x64.RAX, []byte{0x66, 0x41, 0x89, 0x47, 0x01}},
|
||||
{x64.R15, 1, 1, x64.RAX, []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 := x64.StoreRegister(nil, pattern.RegisterTo, pattern.Offset, pattern.Length, pattern.RegisterFrom)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestSubRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, 1, []byte{0x48, 0x83, 0xE8, 0x01}},
|
||||
{x64.RCX, 1, []byte{0x48, 0x83, 0xE9, 0x01}},
|
||||
{x64.RDX, 1, []byte{0x48, 0x83, 0xEA, 0x01}},
|
||||
{x64.RBX, 1, []byte{0x48, 0x83, 0xEB, 0x01}},
|
||||
{x64.RSP, 1, []byte{0x48, 0x83, 0xEC, 0x01}},
|
||||
{x64.RBP, 1, []byte{0x48, 0x83, 0xED, 0x01}},
|
||||
{x64.RSI, 1, []byte{0x48, 0x83, 0xEE, 0x01}},
|
||||
{x64.RDI, 1, []byte{0x48, 0x83, 0xEF, 0x01}},
|
||||
{x64.R8, 1, []byte{0x49, 0x83, 0xE8, 0x01}},
|
||||
{x64.R9, 1, []byte{0x49, 0x83, 0xE9, 0x01}},
|
||||
{x64.R10, 1, []byte{0x49, 0x83, 0xEA, 0x01}},
|
||||
{x64.R11, 1, []byte{0x49, 0x83, 0xEB, 0x01}},
|
||||
{x64.R12, 1, []byte{0x49, 0x83, 0xEC, 0x01}},
|
||||
{x64.R13, 1, []byte{0x49, 0x83, 0xED, 0x01}},
|
||||
{x64.R14, 1, []byte{0x49, 0x83, 0xEE, 0x01}},
|
||||
{x64.R15, 1, []byte{0x49, 0x83, 0xEF, 0x01}},
|
||||
|
||||
{x64.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xED, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xED, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("sub %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.SubRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, []byte{0x4C, 0x29, 0xF8}},
|
||||
{x64.RCX, x64.R14, []byte{0x4C, 0x29, 0xF1}},
|
||||
{x64.RDX, x64.R13, []byte{0x4C, 0x29, 0xEA}},
|
||||
{x64.RBX, x64.R12, []byte{0x4C, 0x29, 0xE3}},
|
||||
{x64.RSP, x64.R11, []byte{0x4C, 0x29, 0xDC}},
|
||||
{x64.RBP, x64.R10, []byte{0x4C, 0x29, 0xD5}},
|
||||
{x64.RSI, x64.R9, []byte{0x4C, 0x29, 0xCE}},
|
||||
{x64.RDI, x64.R8, []byte{0x4C, 0x29, 0xC7}},
|
||||
{x64.R8, x64.RDI, []byte{0x49, 0x29, 0xF8}},
|
||||
{x64.R9, x64.RSI, []byte{0x49, 0x29, 0xF1}},
|
||||
{x64.R10, x64.RBP, []byte{0x49, 0x29, 0xEA}},
|
||||
{x64.R11, x64.RSP, []byte{0x49, 0x29, 0xE3}},
|
||||
{x64.R12, x64.RBX, []byte{0x49, 0x29, 0xDC}},
|
||||
{x64.R13, x64.RDX, []byte{0x49, 0x29, 0xD5}},
|
||||
{x64.R14, x64.RCX, []byte{0x49, 0x29, 0xCE}},
|
||||
{x64.R15, x64.RAX, []byte{0x49, 0x29, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("sub %s, %s", pattern.Left, pattern.Right)
|
||||
code := x64.SubRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestXorRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, 1, []byte{0x48, 0x83, 0xF0, 0x01}},
|
||||
{x64.RCX, 1, []byte{0x48, 0x83, 0xF1, 0x01}},
|
||||
{x64.RDX, 1, []byte{0x48, 0x83, 0xF2, 0x01}},
|
||||
{x64.RBX, 1, []byte{0x48, 0x83, 0xF3, 0x01}},
|
||||
{x64.RSP, 1, []byte{0x48, 0x83, 0xF4, 0x01}},
|
||||
{x64.RBP, 1, []byte{0x48, 0x83, 0xF5, 0x01}},
|
||||
{x64.RSI, 1, []byte{0x48, 0x83, 0xF6, 0x01}},
|
||||
{x64.RDI, 1, []byte{0x48, 0x83, 0xF7, 0x01}},
|
||||
{x64.R8, 1, []byte{0x49, 0x83, 0xF0, 0x01}},
|
||||
{x64.R9, 1, []byte{0x49, 0x83, 0xF1, 0x01}},
|
||||
{x64.R10, 1, []byte{0x49, 0x83, 0xF2, 0x01}},
|
||||
{x64.R11, 1, []byte{0x49, 0x83, 0xF3, 0x01}},
|
||||
{x64.R12, 1, []byte{0x49, 0x83, 0xF4, 0x01}},
|
||||
{x64.R13, 1, []byte{0x49, 0x83, 0xF5, 0x01}},
|
||||
{x64.R14, 1, []byte{0x49, 0x83, 0xF6, 0x01}},
|
||||
{x64.R15, 1, []byte{0x49, 0x83, 0xF7, 0x01}},
|
||||
|
||||
{x64.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x64.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("xor %s, %x", pattern.Register, pattern.Number)
|
||||
code := x64.XorRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestXorRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x64.RAX, x64.R15, []byte{0x4C, 0x31, 0xF8}},
|
||||
{x64.RCX, x64.R14, []byte{0x4C, 0x31, 0xF1}},
|
||||
{x64.RDX, x64.R13, []byte{0x4C, 0x31, 0xEA}},
|
||||
{x64.RBX, x64.R12, []byte{0x4C, 0x31, 0xE3}},
|
||||
{x64.RSP, x64.R11, []byte{0x4C, 0x31, 0xDC}},
|
||||
{x64.RBP, x64.R10, []byte{0x4C, 0x31, 0xD5}},
|
||||
{x64.RSI, x64.R9, []byte{0x4C, 0x31, 0xCE}},
|
||||
{x64.RDI, x64.R8, []byte{0x4C, 0x31, 0xC7}},
|
||||
{x64.R8, x64.RDI, []byte{0x49, 0x31, 0xF8}},
|
||||
{x64.R9, x64.RSI, []byte{0x49, 0x31, 0xF1}},
|
||||
{x64.R10, x64.RBP, []byte{0x49, 0x31, 0xEA}},
|
||||
{x64.R11, x64.RSP, []byte{0x49, 0x31, 0xE3}},
|
||||
{x64.R12, x64.RBX, []byte{0x49, 0x31, 0xDC}},
|
||||
{x64.R13, x64.RDX, []byte{0x49, 0x31, 0xD5}},
|
||||
{x64.R14, x64.RCX, []byte{0x49, 0x31, 0xCE}},
|
||||
{x64.R15, x64.RAX, []byte{0x49, 0x31, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("xor %s, %s", pattern.Left, pattern.Right)
|
||||
code := x64.XorRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestX64(t *testing.T) {
|
||||
assert.DeepEqual(t, x64.AlignStack(nil), []byte{0x48, 0x83, 0xE4, 0xF0})
|
||||
assert.DeepEqual(t, x64.Call(nil, 1), []byte{0xE8, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x64.CallAtAddress(nil, 1), []byte{0xFF, 0x15, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x64.ExtendRAXToRDX(nil), []byte{0x48, 0x99})
|
||||
assert.DeepEqual(t, x64.MoveRegisterNumber(nil, 0, 1), []byte{0xB8, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x64.MoveRegisterNumber(nil, 1, 1), []byte{0xB9, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x64.Return(nil), []byte{0xC3})
|
||||
assert.DeepEqual(t, x64.Syscall(nil), []byte{0x0F, 0x05})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
88
src/x86/Add_test.go
Normal file
88
src/x86/Add_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestAddRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, 1, []byte{0x48, 0x83, 0xC0, 0x01}},
|
||||
{x86.RCX, 1, []byte{0x48, 0x83, 0xC1, 0x01}},
|
||||
{x86.RDX, 1, []byte{0x48, 0x83, 0xC2, 0x01}},
|
||||
{x86.RBX, 1, []byte{0x48, 0x83, 0xC3, 0x01}},
|
||||
{x86.RSP, 1, []byte{0x48, 0x83, 0xC4, 0x01}},
|
||||
{x86.RBP, 1, []byte{0x48, 0x83, 0xC5, 0x01}},
|
||||
{x86.RSI, 1, []byte{0x48, 0x83, 0xC6, 0x01}},
|
||||
{x86.RDI, 1, []byte{0x48, 0x83, 0xC7, 0x01}},
|
||||
{x86.R8, 1, []byte{0x49, 0x83, 0xC0, 0x01}},
|
||||
{x86.R9, 1, []byte{0x49, 0x83, 0xC1, 0x01}},
|
||||
{x86.R10, 1, []byte{0x49, 0x83, 0xC2, 0x01}},
|
||||
{x86.R11, 1, []byte{0x49, 0x83, 0xC3, 0x01}},
|
||||
{x86.R12, 1, []byte{0x49, 0x83, 0xC4, 0x01}},
|
||||
{x86.R13, 1, []byte{0x49, 0x83, 0xC5, 0x01}},
|
||||
{x86.R14, 1, []byte{0x49, 0x83, 0xC6, 0x01}},
|
||||
{x86.R15, 1, []byte{0x49, 0x83, 0xC7, 0x01}},
|
||||
|
||||
{x86.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("add %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.AddRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, []byte{0x4C, 0x01, 0xF8}},
|
||||
{x86.RCX, x86.R14, []byte{0x4C, 0x01, 0xF1}},
|
||||
{x86.RDX, x86.R13, []byte{0x4C, 0x01, 0xEA}},
|
||||
{x86.RBX, x86.R12, []byte{0x4C, 0x01, 0xE3}},
|
||||
{x86.RSP, x86.R11, []byte{0x4C, 0x01, 0xDC}},
|
||||
{x86.RBP, x86.R10, []byte{0x4C, 0x01, 0xD5}},
|
||||
{x86.RSI, x86.R9, []byte{0x4C, 0x01, 0xCE}},
|
||||
{x86.RDI, x86.R8, []byte{0x4C, 0x01, 0xC7}},
|
||||
{x86.R8, x86.RDI, []byte{0x49, 0x01, 0xF8}},
|
||||
{x86.R9, x86.RSI, []byte{0x49, 0x01, 0xF1}},
|
||||
{x86.R10, x86.RBP, []byte{0x49, 0x01, 0xEA}},
|
||||
{x86.R11, x86.RSP, []byte{0x49, 0x01, 0xE3}},
|
||||
{x86.R12, x86.RBX, []byte{0x49, 0x01, 0xDC}},
|
||||
{x86.R13, x86.RDX, []byte{0x49, 0x01, 0xD5}},
|
||||
{x86.R14, x86.RCX, []byte{0x49, 0x01, 0xCE}},
|
||||
{x86.R15, x86.RAX, []byte{0x49, 0x01, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("add %s, %s", pattern.Left, pattern.Right)
|
||||
code := x86.AddRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
// AlignStack aligns RSP on a 16-byte boundary.
|
||||
func AlignStack(code []byte) []byte {
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
88
src/x86/And_test.go
Normal file
88
src/x86/And_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestAndRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, 1, []byte{0x48, 0x83, 0xE0, 0x01}},
|
||||
{x86.RCX, 1, []byte{0x48, 0x83, 0xE1, 0x01}},
|
||||
{x86.RDX, 1, []byte{0x48, 0x83, 0xE2, 0x01}},
|
||||
{x86.RBX, 1, []byte{0x48, 0x83, 0xE3, 0x01}},
|
||||
{x86.RSP, 1, []byte{0x48, 0x83, 0xE4, 0x01}},
|
||||
{x86.RBP, 1, []byte{0x48, 0x83, 0xE5, 0x01}},
|
||||
{x86.RSI, 1, []byte{0x48, 0x83, 0xE6, 0x01}},
|
||||
{x86.RDI, 1, []byte{0x48, 0x83, 0xE7, 0x01}},
|
||||
{x86.R8, 1, []byte{0x49, 0x83, 0xE0, 0x01}},
|
||||
{x86.R9, 1, []byte{0x49, 0x83, 0xE1, 0x01}},
|
||||
{x86.R10, 1, []byte{0x49, 0x83, 0xE2, 0x01}},
|
||||
{x86.R11, 1, []byte{0x49, 0x83, 0xE3, 0x01}},
|
||||
{x86.R12, 1, []byte{0x49, 0x83, 0xE4, 0x01}},
|
||||
{x86.R13, 1, []byte{0x49, 0x83, 0xE5, 0x01}},
|
||||
{x86.R14, 1, []byte{0x49, 0x83, 0xE6, 0x01}},
|
||||
{x86.R15, 1, []byte{0x49, 0x83, 0xE7, 0x01}},
|
||||
|
||||
{x86.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("and %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.AndRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAndRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, []byte{0x4C, 0x21, 0xF8}},
|
||||
{x86.RCX, x86.R14, []byte{0x4C, 0x21, 0xF1}},
|
||||
{x86.RDX, x86.R13, []byte{0x4C, 0x21, 0xEA}},
|
||||
{x86.RBX, x86.R12, []byte{0x4C, 0x21, 0xE3}},
|
||||
{x86.RSP, x86.R11, []byte{0x4C, 0x21, 0xDC}},
|
||||
{x86.RBP, x86.R10, []byte{0x4C, 0x21, 0xD5}},
|
||||
{x86.RSI, x86.R9, []byte{0x4C, 0x21, 0xCE}},
|
||||
{x86.RDI, x86.R8, []byte{0x4C, 0x21, 0xC7}},
|
||||
{x86.R8, x86.RDI, []byte{0x49, 0x21, 0xF8}},
|
||||
{x86.R9, x86.RSI, []byte{0x49, 0x21, 0xF1}},
|
||||
{x86.R10, x86.RBP, []byte{0x49, 0x21, 0xEA}},
|
||||
{x86.R11, x86.RSP, []byte{0x49, 0x21, 0xE3}},
|
||||
{x86.R12, x86.RBX, []byte{0x49, 0x21, 0xDC}},
|
||||
{x86.R13, x86.RDX, []byte{0x49, 0x21, 0xD5}},
|
||||
{x86.R14, x86.RCX, []byte{0x49, 0x21, 0xCE}},
|
||||
{x86.R15, x86.RAX, []byte{0x49, 0x21, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("and %s, %s", pattern.Left, pattern.Right)
|
||||
code := x86.AndRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
// Call places the return address on the top of the stack and continues
|
||||
// program flow at the new address.
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
88
src/x86/Compare_test.go
Normal file
88
src/x86/Compare_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestCompareRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, 1, []byte{0x48, 0x83, 0xF8, 0x01}},
|
||||
{x86.RCX, 1, []byte{0x48, 0x83, 0xF9, 0x01}},
|
||||
{x86.RDX, 1, []byte{0x48, 0x83, 0xFA, 0x01}},
|
||||
{x86.RBX, 1, []byte{0x48, 0x83, 0xFB, 0x01}},
|
||||
{x86.RSP, 1, []byte{0x48, 0x83, 0xFC, 0x01}},
|
||||
{x86.RBP, 1, []byte{0x48, 0x83, 0xFD, 0x01}},
|
||||
{x86.RSI, 1, []byte{0x48, 0x83, 0xFE, 0x01}},
|
||||
{x86.RDI, 1, []byte{0x48, 0x83, 0xFF, 0x01}},
|
||||
{x86.R8, 1, []byte{0x49, 0x83, 0xF8, 0x01}},
|
||||
{x86.R9, 1, []byte{0x49, 0x83, 0xF9, 0x01}},
|
||||
{x86.R10, 1, []byte{0x49, 0x83, 0xFA, 0x01}},
|
||||
{x86.R11, 1, []byte{0x49, 0x83, 0xFB, 0x01}},
|
||||
{x86.R12, 1, []byte{0x49, 0x83, 0xFC, 0x01}},
|
||||
{x86.R13, 1, []byte{0x49, 0x83, 0xFD, 0x01}},
|
||||
{x86.R14, 1, []byte{0x49, 0x83, 0xFE, 0x01}},
|
||||
{x86.R15, 1, []byte{0x49, 0x83, 0xFF, 0x01}},
|
||||
|
||||
{x86.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("cmp %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.CompareRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompareRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, []byte{0x4C, 0x39, 0xF8}},
|
||||
{x86.RCX, x86.R14, []byte{0x4C, 0x39, 0xF1}},
|
||||
{x86.RDX, x86.R13, []byte{0x4C, 0x39, 0xEA}},
|
||||
{x86.RBX, x86.R12, []byte{0x4C, 0x39, 0xE3}},
|
||||
{x86.RSP, x86.R11, []byte{0x4C, 0x39, 0xDC}},
|
||||
{x86.RBP, x86.R10, []byte{0x4C, 0x39, 0xD5}},
|
||||
{x86.RSI, x86.R9, []byte{0x4C, 0x39, 0xCE}},
|
||||
{x86.RDI, x86.R8, []byte{0x4C, 0x39, 0xC7}},
|
||||
{x86.R8, x86.RDI, []byte{0x49, 0x39, 0xF8}},
|
||||
{x86.R9, x86.RSI, []byte{0x49, 0x39, 0xF1}},
|
||||
{x86.R10, x86.RBP, []byte{0x49, 0x39, 0xEA}},
|
||||
{x86.R11, x86.RSP, []byte{0x49, 0x39, 0xE3}},
|
||||
{x86.R12, x86.RBX, []byte{0x49, 0x39, 0xDC}},
|
||||
{x86.R13, x86.RDX, []byte{0x49, 0x39, 0xD5}},
|
||||
{x86.R14, x86.RCX, []byte{0x49, 0x39, 0xCE}},
|
||||
{x86.R15, x86.RAX, []byte{0x49, 0x39, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("cmp %s, %s", pattern.Left, pattern.Right)
|
||||
code := x86.CompareRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
39
src/x86/Div_test.go
Normal file
39
src/x86/Div_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestDivRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, []byte{0x48, 0xF7, 0xF8}},
|
||||
{x86.RCX, []byte{0x48, 0xF7, 0xF9}},
|
||||
{x86.RDX, []byte{0x48, 0xF7, 0xFA}},
|
||||
{x86.RBX, []byte{0x48, 0xF7, 0xFB}},
|
||||
{x86.RSP, []byte{0x48, 0xF7, 0xFC}},
|
||||
{x86.RBP, []byte{0x48, 0xF7, 0xFD}},
|
||||
{x86.RSI, []byte{0x48, 0xF7, 0xFE}},
|
||||
{x86.RDI, []byte{0x48, 0xF7, 0xFF}},
|
||||
{x86.R8, []byte{0x49, 0xF7, 0xF8}},
|
||||
{x86.R9, []byte{0x49, 0xF7, 0xF9}},
|
||||
{x86.R10, []byte{0x49, 0xF7, 0xFA}},
|
||||
{x86.R11, []byte{0x49, 0xF7, 0xFB}},
|
||||
{x86.R12, []byte{0x49, 0xF7, 0xFC}},
|
||||
{x86.R13, []byte{0x49, 0xF7, 0xFD}},
|
||||
{x86.R14, []byte{0x49, 0xF7, 0xFE}},
|
||||
{x86.R15, []byte{0x49, 0xF7, 0xFF}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("idiv %s", pattern.Register)
|
||||
code := x86.DivRegister(nil, pattern.Register)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
// ExtendRAXToRDX doubles the size of RAX by sign-extending it to RDX.
|
||||
// This is also known as CQO.
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
// Jump continues program flow at the new address.
|
||||
// The address is relative to the next instruction.
|
@ -1,9 +1,9 @@
|
||||
package x64_test
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
@ -25,16 +25,16 @@ func TestJump(t *testing.T) {
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("jmp %x", pattern.Offset)
|
||||
code := x64.Jump8(nil, pattern.Offset)
|
||||
code := x86.Jump8(nil, pattern.Offset)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConditionalJump(t *testing.T) {
|
||||
assert.DeepEqual(t, x64.Jump8IfEqual(nil, 1), []byte{0x74, 0x01})
|
||||
assert.DeepEqual(t, x64.Jump8IfNotEqual(nil, 1), []byte{0x75, 0x01})
|
||||
assert.DeepEqual(t, x64.Jump8IfLess(nil, 1), []byte{0x7C, 0x01})
|
||||
assert.DeepEqual(t, x64.Jump8IfGreaterOrEqual(nil, 1), []byte{0x7D, 0x01})
|
||||
assert.DeepEqual(t, x64.Jump8IfLessOrEqual(nil, 1), []byte{0x7E, 0x01})
|
||||
assert.DeepEqual(t, x64.Jump8IfGreater(nil, 1), []byte{0x7F, 0x01})
|
||||
assert.DeepEqual(t, x86.Jump8IfEqual(nil, 1), []byte{0x74, 0x01})
|
||||
assert.DeepEqual(t, x86.Jump8IfNotEqual(nil, 1), []byte{0x75, 0x01})
|
||||
assert.DeepEqual(t, x86.Jump8IfLess(nil, 1), []byte{0x7C, 0x01})
|
||||
assert.DeepEqual(t, x86.Jump8IfGreaterOrEqual(nil, 1), []byte{0x7D, 0x01})
|
||||
assert.DeepEqual(t, x86.Jump8IfLessOrEqual(nil, 1), []byte{0x7E, 0x01})
|
||||
assert.DeepEqual(t, x86.Jump8IfGreater(nil, 1), []byte{0x7F, 0x01})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
157
src/x86/Load_test.go
Normal file
157
src/x86/Load_test.go
Normal file
@ -0,0 +1,157 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestLoadRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Destination cpu.Register
|
||||
Source cpu.Register
|
||||
Offset byte
|
||||
Length byte
|
||||
Code []byte
|
||||
}{
|
||||
// No offset
|
||||
{x86.RAX, x86.R15, 0, 8, []byte{0x49, 0x8B, 0x07}},
|
||||
{x86.RAX, x86.R15, 0, 4, []byte{0x41, 0x8B, 0x07}},
|
||||
{x86.RAX, x86.R15, 0, 2, []byte{0x66, 0x41, 0x8B, 0x07}},
|
||||
{x86.RAX, x86.R15, 0, 1, []byte{0x41, 0x8A, 0x07}},
|
||||
{x86.RCX, x86.R14, 0, 8, []byte{0x49, 0x8B, 0x0E}},
|
||||
{x86.RCX, x86.R14, 0, 4, []byte{0x41, 0x8B, 0x0E}},
|
||||
{x86.RCX, x86.R14, 0, 2, []byte{0x66, 0x41, 0x8B, 0x0E}},
|
||||
{x86.RCX, x86.R14, 0, 1, []byte{0x41, 0x8A, 0x0E}},
|
||||
{x86.RDX, x86.R13, 0, 8, []byte{0x49, 0x8B, 0x55, 0x00}},
|
||||
{x86.RDX, x86.R13, 0, 4, []byte{0x41, 0x8B, 0x55, 0x00}},
|
||||
{x86.RDX, x86.R13, 0, 2, []byte{0x66, 0x41, 0x8B, 0x55, 0x00}},
|
||||
{x86.RDX, x86.R13, 0, 1, []byte{0x41, 0x8A, 0x55, 0x00}},
|
||||
{x86.RBX, x86.R12, 0, 8, []byte{0x49, 0x8B, 0x1C, 0x24}},
|
||||
{x86.RBX, x86.R12, 0, 4, []byte{0x41, 0x8B, 0x1C, 0x24}},
|
||||
{x86.RBX, x86.R12, 0, 2, []byte{0x66, 0x41, 0x8B, 0x1C, 0x24}},
|
||||
{x86.RBX, x86.R12, 0, 1, []byte{0x41, 0x8A, 0x1C, 0x24}},
|
||||
{x86.RSP, x86.R11, 0, 8, []byte{0x49, 0x8B, 0x23}},
|
||||
{x86.RSP, x86.R11, 0, 4, []byte{0x41, 0x8B, 0x23}},
|
||||
{x86.RSP, x86.R11, 0, 2, []byte{0x66, 0x41, 0x8B, 0x23}},
|
||||
{x86.RSP, x86.R11, 0, 1, []byte{0x41, 0x8A, 0x23}},
|
||||
{x86.RBP, x86.R10, 0, 8, []byte{0x49, 0x8B, 0x2A}},
|
||||
{x86.RBP, x86.R10, 0, 4, []byte{0x41, 0x8B, 0x2A}},
|
||||
{x86.RBP, x86.R10, 0, 2, []byte{0x66, 0x41, 0x8B, 0x2A}},
|
||||
{x86.RBP, x86.R10, 0, 1, []byte{0x41, 0x8A, 0x2A}},
|
||||
{x86.RSI, x86.R9, 0, 8, []byte{0x49, 0x8B, 0x31}},
|
||||
{x86.RSI, x86.R9, 0, 4, []byte{0x41, 0x8B, 0x31}},
|
||||
{x86.RSI, x86.R9, 0, 2, []byte{0x66, 0x41, 0x8B, 0x31}},
|
||||
{x86.RSI, x86.R9, 0, 1, []byte{0x41, 0x8A, 0x31}},
|
||||
{x86.RDI, x86.R8, 0, 8, []byte{0x49, 0x8B, 0x38}},
|
||||
{x86.RDI, x86.R8, 0, 4, []byte{0x41, 0x8B, 0x38}},
|
||||
{x86.RDI, x86.R8, 0, 2, []byte{0x66, 0x41, 0x8B, 0x38}},
|
||||
{x86.RDI, x86.R8, 0, 1, []byte{0x41, 0x8A, 0x38}},
|
||||
{x86.R8, x86.RDI, 0, 8, []byte{0x4C, 0x8B, 0x07}},
|
||||
{x86.R8, x86.RDI, 0, 4, []byte{0x44, 0x8B, 0x07}},
|
||||
{x86.R8, x86.RDI, 0, 2, []byte{0x66, 0x44, 0x8B, 0x07}},
|
||||
{x86.R8, x86.RDI, 0, 1, []byte{0x44, 0x8A, 0x07}},
|
||||
{x86.R9, x86.RSI, 0, 8, []byte{0x4C, 0x8B, 0x0E}},
|
||||
{x86.R9, x86.RSI, 0, 4, []byte{0x44, 0x8B, 0x0E}},
|
||||
{x86.R9, x86.RSI, 0, 2, []byte{0x66, 0x44, 0x8B, 0x0E}},
|
||||
{x86.R9, x86.RSI, 0, 1, []byte{0x44, 0x8A, 0x0E}},
|
||||
{x86.R10, x86.RBP, 0, 8, []byte{0x4C, 0x8B, 0x55, 0x00}},
|
||||
{x86.R10, x86.RBP, 0, 4, []byte{0x44, 0x8B, 0x55, 0x00}},
|
||||
{x86.R10, x86.RBP, 0, 2, []byte{0x66, 0x44, 0x8B, 0x55, 0x00}},
|
||||
{x86.R10, x86.RBP, 0, 1, []byte{0x44, 0x8A, 0x55, 0x00}},
|
||||
{x86.R11, x86.RSP, 0, 8, []byte{0x4C, 0x8B, 0x1C, 0x24}},
|
||||
{x86.R11, x86.RSP, 0, 4, []byte{0x44, 0x8B, 0x1C, 0x24}},
|
||||
{x86.R11, x86.RSP, 0, 2, []byte{0x66, 0x44, 0x8B, 0x1C, 0x24}},
|
||||
{x86.R11, x86.RSP, 0, 1, []byte{0x44, 0x8A, 0x1C, 0x24}},
|
||||
{x86.R12, x86.RBX, 0, 8, []byte{0x4C, 0x8B, 0x23}},
|
||||
{x86.R12, x86.RBX, 0, 4, []byte{0x44, 0x8B, 0x23}},
|
||||
{x86.R12, x86.RBX, 0, 2, []byte{0x66, 0x44, 0x8B, 0x23}},
|
||||
{x86.R12, x86.RBX, 0, 1, []byte{0x44, 0x8A, 0x23}},
|
||||
{x86.R13, x86.RDX, 0, 8, []byte{0x4C, 0x8B, 0x2A}},
|
||||
{x86.R13, x86.RDX, 0, 4, []byte{0x44, 0x8B, 0x2A}},
|
||||
{x86.R13, x86.RDX, 0, 2, []byte{0x66, 0x44, 0x8B, 0x2A}},
|
||||
{x86.R13, x86.RDX, 0, 1, []byte{0x44, 0x8A, 0x2A}},
|
||||
{x86.R14, x86.RCX, 0, 8, []byte{0x4C, 0x8B, 0x31}},
|
||||
{x86.R14, x86.RCX, 0, 4, []byte{0x44, 0x8B, 0x31}},
|
||||
{x86.R14, x86.RCX, 0, 2, []byte{0x66, 0x44, 0x8B, 0x31}},
|
||||
{x86.R14, x86.RCX, 0, 1, []byte{0x44, 0x8A, 0x31}},
|
||||
{x86.R15, x86.RAX, 0, 8, []byte{0x4C, 0x8B, 0x38}},
|
||||
{x86.R15, x86.RAX, 0, 4, []byte{0x44, 0x8B, 0x38}},
|
||||
{x86.R15, x86.RAX, 0, 2, []byte{0x66, 0x44, 0x8B, 0x38}},
|
||||
{x86.R15, x86.RAX, 0, 1, []byte{0x44, 0x8A, 0x38}},
|
||||
|
||||
// Offset of 1
|
||||
{x86.RAX, x86.R15, 1, 8, []byte{0x49, 0x8B, 0x47, 0x01}},
|
||||
{x86.RAX, x86.R15, 1, 4, []byte{0x41, 0x8B, 0x47, 0x01}},
|
||||
{x86.RAX, x86.R15, 1, 2, []byte{0x66, 0x41, 0x8B, 0x47, 0x01}},
|
||||
{x86.RAX, x86.R15, 1, 1, []byte{0x41, 0x8A, 0x47, 0x01}},
|
||||
{x86.RCX, x86.R14, 1, 8, []byte{0x49, 0x8B, 0x4E, 0x01}},
|
||||
{x86.RCX, x86.R14, 1, 4, []byte{0x41, 0x8B, 0x4E, 0x01}},
|
||||
{x86.RCX, x86.R14, 1, 2, []byte{0x66, 0x41, 0x8B, 0x4E, 0x01}},
|
||||
{x86.RCX, x86.R14, 1, 1, []byte{0x41, 0x8A, 0x4E, 0x01}},
|
||||
{x86.RDX, x86.R13, 1, 8, []byte{0x49, 0x8B, 0x55, 0x01}},
|
||||
{x86.RDX, x86.R13, 1, 4, []byte{0x41, 0x8B, 0x55, 0x01}},
|
||||
{x86.RDX, x86.R13, 1, 2, []byte{0x66, 0x41, 0x8B, 0x55, 0x01}},
|
||||
{x86.RDX, x86.R13, 1, 1, []byte{0x41, 0x8A, 0x55, 0x01}},
|
||||
{x86.RBX, x86.R12, 1, 8, []byte{0x49, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x86.RBX, x86.R12, 1, 4, []byte{0x41, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x86.RBX, x86.R12, 1, 2, []byte{0x66, 0x41, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x86.RBX, x86.R12, 1, 1, []byte{0x41, 0x8A, 0x5C, 0x24, 0x01}},
|
||||
{x86.RSP, x86.R11, 1, 8, []byte{0x49, 0x8B, 0x63, 0x01}},
|
||||
{x86.RSP, x86.R11, 1, 4, []byte{0x41, 0x8B, 0x63, 0x01}},
|
||||
{x86.RSP, x86.R11, 1, 2, []byte{0x66, 0x41, 0x8B, 0x63, 0x01}},
|
||||
{x86.RSP, x86.R11, 1, 1, []byte{0x41, 0x8A, 0x63, 0x01}},
|
||||
{x86.RBP, x86.R10, 1, 8, []byte{0x49, 0x8B, 0x6A, 0x01}},
|
||||
{x86.RBP, x86.R10, 1, 4, []byte{0x41, 0x8B, 0x6A, 0x01}},
|
||||
{x86.RBP, x86.R10, 1, 2, []byte{0x66, 0x41, 0x8B, 0x6A, 0x01}},
|
||||
{x86.RBP, x86.R10, 1, 1, []byte{0x41, 0x8A, 0x6A, 0x01}},
|
||||
{x86.RSI, x86.R9, 1, 8, []byte{0x49, 0x8B, 0x71, 0x01}},
|
||||
{x86.RSI, x86.R9, 1, 4, []byte{0x41, 0x8B, 0x71, 0x01}},
|
||||
{x86.RSI, x86.R9, 1, 2, []byte{0x66, 0x41, 0x8B, 0x71, 0x01}},
|
||||
{x86.RSI, x86.R9, 1, 1, []byte{0x41, 0x8A, 0x71, 0x01}},
|
||||
{x86.RDI, x86.R8, 1, 8, []byte{0x49, 0x8B, 0x78, 0x01}},
|
||||
{x86.RDI, x86.R8, 1, 4, []byte{0x41, 0x8B, 0x78, 0x01}},
|
||||
{x86.RDI, x86.R8, 1, 2, []byte{0x66, 0x41, 0x8B, 0x78, 0x01}},
|
||||
{x86.RDI, x86.R8, 1, 1, []byte{0x41, 0x8A, 0x78, 0x01}},
|
||||
{x86.R8, x86.RDI, 1, 8, []byte{0x4C, 0x8B, 0x47, 0x01}},
|
||||
{x86.R8, x86.RDI, 1, 4, []byte{0x44, 0x8B, 0x47, 0x01}},
|
||||
{x86.R8, x86.RDI, 1, 2, []byte{0x66, 0x44, 0x8B, 0x47, 0x01}},
|
||||
{x86.R8, x86.RDI, 1, 1, []byte{0x44, 0x8A, 0x47, 0x01}},
|
||||
{x86.R9, x86.RSI, 1, 8, []byte{0x4C, 0x8B, 0x4E, 0x01}},
|
||||
{x86.R9, x86.RSI, 1, 4, []byte{0x44, 0x8B, 0x4E, 0x01}},
|
||||
{x86.R9, x86.RSI, 1, 2, []byte{0x66, 0x44, 0x8B, 0x4E, 0x01}},
|
||||
{x86.R9, x86.RSI, 1, 1, []byte{0x44, 0x8A, 0x4E, 0x01}},
|
||||
{x86.R10, x86.RBP, 1, 8, []byte{0x4C, 0x8B, 0x55, 0x01}},
|
||||
{x86.R10, x86.RBP, 1, 4, []byte{0x44, 0x8B, 0x55, 0x01}},
|
||||
{x86.R10, x86.RBP, 1, 2, []byte{0x66, 0x44, 0x8B, 0x55, 0x01}},
|
||||
{x86.R10, x86.RBP, 1, 1, []byte{0x44, 0x8A, 0x55, 0x01}},
|
||||
{x86.R11, x86.RSP, 1, 8, []byte{0x4C, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x86.R11, x86.RSP, 1, 4, []byte{0x44, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x86.R11, x86.RSP, 1, 2, []byte{0x66, 0x44, 0x8B, 0x5C, 0x24, 0x01}},
|
||||
{x86.R11, x86.RSP, 1, 1, []byte{0x44, 0x8A, 0x5C, 0x24, 0x01}},
|
||||
{x86.R12, x86.RBX, 1, 8, []byte{0x4C, 0x8B, 0x63, 0x01}},
|
||||
{x86.R12, x86.RBX, 1, 4, []byte{0x44, 0x8B, 0x63, 0x01}},
|
||||
{x86.R12, x86.RBX, 1, 2, []byte{0x66, 0x44, 0x8B, 0x63, 0x01}},
|
||||
{x86.R12, x86.RBX, 1, 1, []byte{0x44, 0x8A, 0x63, 0x01}},
|
||||
{x86.R13, x86.RDX, 1, 8, []byte{0x4C, 0x8B, 0x6A, 0x01}},
|
||||
{x86.R13, x86.RDX, 1, 4, []byte{0x44, 0x8B, 0x6A, 0x01}},
|
||||
{x86.R13, x86.RDX, 1, 2, []byte{0x66, 0x44, 0x8B, 0x6A, 0x01}},
|
||||
{x86.R13, x86.RDX, 1, 1, []byte{0x44, 0x8A, 0x6A, 0x01}},
|
||||
{x86.R14, x86.RCX, 1, 8, []byte{0x4C, 0x8B, 0x71, 0x01}},
|
||||
{x86.R14, x86.RCX, 1, 4, []byte{0x44, 0x8B, 0x71, 0x01}},
|
||||
{x86.R14, x86.RCX, 1, 2, []byte{0x66, 0x44, 0x8B, 0x71, 0x01}},
|
||||
{x86.R14, x86.RCX, 1, 1, []byte{0x44, 0x8A, 0x71, 0x01}},
|
||||
{x86.R15, x86.RAX, 1, 8, []byte{0x4C, 0x8B, 0x78, 0x01}},
|
||||
{x86.R15, x86.RAX, 1, 4, []byte{0x44, 0x8B, 0x78, 0x01}},
|
||||
{x86.R15, x86.RAX, 1, 2, []byte{0x66, 0x44, 0x8B, 0x78, 0x01}},
|
||||
{x86.R15, x86.RAX, 1, 1, []byte{0x44, 0x8A, 0x78, 0x01}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("load %dB %s, [%s+%d]", pattern.Length, pattern.Destination, pattern.Source, pattern.Offset)
|
||||
code := x86.LoadRegister(nil, pattern.Destination, pattern.Offset, pattern.Length, pattern.Source)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
// AddressMode encodes the addressing mode.
|
||||
type AddressMode = byte
|
@ -1,9 +1,9 @@
|
||||
package x64_test
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
@ -28,7 +28,7 @@ func TestModRM(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range testData {
|
||||
modRM := x64.ModRM(test.mod, test.reg, test.rm)
|
||||
modRM := x86.ModRM(test.mod, test.reg, test.rm)
|
||||
assert.Equal(t, modRM, test.expected)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
108
src/x86/Move_test.go
Normal file
108
src/x86/Move_test.go
Normal file
@ -0,0 +1,108 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestMoveRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
// 32 bits
|
||||
{x86.RAX, 0x7FFFFFFF, []byte{0xB8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RCX, 0x7FFFFFFF, []byte{0xB9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDX, 0x7FFFFFFF, []byte{0xBA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBX, 0x7FFFFFFF, []byte{0xBB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSP, 0x7FFFFFFF, []byte{0xBC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBP, 0x7FFFFFFF, []byte{0xBD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSI, 0x7FFFFFFF, []byte{0xBE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDI, 0x7FFFFFFF, []byte{0xBF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R8, 0x7FFFFFFF, []byte{0x41, 0xB8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R9, 0x7FFFFFFF, []byte{0x41, 0xB9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R10, 0x7FFFFFFF, []byte{0x41, 0xBA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R11, 0x7FFFFFFF, []byte{0x41, 0xBB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R12, 0x7FFFFFFF, []byte{0x41, 0xBC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R13, 0x7FFFFFFF, []byte{0x41, 0xBD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R14, 0x7FFFFFFF, []byte{0x41, 0xBE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R15, 0x7FFFFFFF, []byte{0x41, 0xBF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
|
||||
// 64 bits
|
||||
{x86.RAX, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RCX, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDX, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBX, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSP, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBP, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSI, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDI, 0x7FFFFFFFFFFFFFFF, []byte{0x48, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R8, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R9, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R10, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R11, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R12, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R13, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R14, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R15, 0x7FFFFFFFFFFFFFFF, []byte{0x49, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
|
||||
// Negative numbers
|
||||
{x86.RAX, -1, []byte{0x48, 0xC7, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.RCX, -1, []byte{0x48, 0xC7, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.RDX, -1, []byte{0x48, 0xC7, 0xC2, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.RBX, -1, []byte{0x48, 0xC7, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.RSP, -1, []byte{0x48, 0xC7, 0xC4, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.RBP, -1, []byte{0x48, 0xC7, 0xC5, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.RSI, -1, []byte{0x48, 0xC7, 0xC6, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.RDI, -1, []byte{0x48, 0xC7, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.R8, -1, []byte{0x49, 0xC7, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.R9, -1, []byte{0x49, 0xC7, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.R10, -1, []byte{0x49, 0xC7, 0xC2, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.R11, -1, []byte{0x49, 0xC7, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.R12, -1, []byte{0x49, 0xC7, 0xC4, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.R13, -1, []byte{0x49, 0xC7, 0xC5, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.R14, -1, []byte{0x49, 0xC7, 0xC6, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
{x86.R15, -1, []byte{0x49, 0xC7, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("mov %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.MoveRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMoveRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, []byte{0x4C, 0x89, 0xF8}},
|
||||
{x86.RCX, x86.R14, []byte{0x4C, 0x89, 0xF1}},
|
||||
{x86.RDX, x86.R13, []byte{0x4C, 0x89, 0xEA}},
|
||||
{x86.RBX, x86.R12, []byte{0x4C, 0x89, 0xE3}},
|
||||
{x86.RSP, x86.R11, []byte{0x4C, 0x89, 0xDC}},
|
||||
{x86.RBP, x86.R10, []byte{0x4C, 0x89, 0xD5}},
|
||||
{x86.RSI, x86.R9, []byte{0x4C, 0x89, 0xCE}},
|
||||
{x86.RDI, x86.R8, []byte{0x4C, 0x89, 0xC7}},
|
||||
{x86.R8, x86.RDI, []byte{0x49, 0x89, 0xF8}},
|
||||
{x86.R9, x86.RSI, []byte{0x49, 0x89, 0xF1}},
|
||||
{x86.R10, x86.RBP, []byte{0x49, 0x89, 0xEA}},
|
||||
{x86.R11, x86.RSP, []byte{0x49, 0x89, 0xE3}},
|
||||
{x86.R12, x86.RBX, []byte{0x49, 0x89, 0xDC}},
|
||||
{x86.R13, x86.RDX, []byte{0x49, 0x89, 0xD5}},
|
||||
{x86.R14, x86.RCX, []byte{0x49, 0x89, 0xCE}},
|
||||
{x86.R15, x86.RAX, []byte{0x49, 0x89, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("mov %s, %s", pattern.Left, pattern.Right)
|
||||
code := x86.MoveRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
88
src/x86/Mul_test.go
Normal file
88
src/x86/Mul_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestMulRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, 1, []byte{0x48, 0x6B, 0xC0, 0x01}},
|
||||
{x86.RCX, 1, []byte{0x48, 0x6B, 0xC9, 0x01}},
|
||||
{x86.RDX, 1, []byte{0x48, 0x6B, 0xD2, 0x01}},
|
||||
{x86.RBX, 1, []byte{0x48, 0x6B, 0xDB, 0x01}},
|
||||
{x86.RSP, 1, []byte{0x48, 0x6B, 0xE4, 0x01}},
|
||||
{x86.RBP, 1, []byte{0x48, 0x6B, 0xED, 0x01}},
|
||||
{x86.RSI, 1, []byte{0x48, 0x6B, 0xF6, 0x01}},
|
||||
{x86.RDI, 1, []byte{0x48, 0x6B, 0xFF, 0x01}},
|
||||
{x86.R8, 1, []byte{0x4D, 0x6B, 0xC0, 0x01}},
|
||||
{x86.R9, 1, []byte{0x4D, 0x6B, 0xC9, 0x01}},
|
||||
{x86.R10, 1, []byte{0x4D, 0x6B, 0xD2, 0x01}},
|
||||
{x86.R11, 1, []byte{0x4D, 0x6B, 0xDB, 0x01}},
|
||||
{x86.R12, 1, []byte{0x4D, 0x6B, 0xE4, 0x01}},
|
||||
{x86.R13, 1, []byte{0x4D, 0x6B, 0xED, 0x01}},
|
||||
{x86.R14, 1, []byte{0x4D, 0x6B, 0xF6, 0x01}},
|
||||
{x86.R15, 1, []byte{0x4D, 0x6B, 0xFF, 0x01}},
|
||||
|
||||
{x86.RAX, 0x7FFFFFFF, []byte{0x48, 0x69, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RCX, 0x7FFFFFFF, []byte{0x48, 0x69, 0xC9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDX, 0x7FFFFFFF, []byte{0x48, 0x69, 0xD2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBX, 0x7FFFFFFF, []byte{0x48, 0x69, 0xDB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSP, 0x7FFFFFFF, []byte{0x48, 0x69, 0xE4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBP, 0x7FFFFFFF, []byte{0x48, 0x69, 0xED, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSI, 0x7FFFFFFF, []byte{0x48, 0x69, 0xF6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDI, 0x7FFFFFFF, []byte{0x48, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R8, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R9, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xC9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R10, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xD2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R11, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xDB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R12, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xE4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R13, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xED, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R14, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xF6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R15, 0x7FFFFFFF, []byte{0x4D, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("mul %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.MulRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMulRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, []byte{0x49, 0x0F, 0xAF, 0xC7}},
|
||||
{x86.RCX, x86.R14, []byte{0x49, 0x0F, 0xAF, 0xCE}},
|
||||
{x86.RDX, x86.R13, []byte{0x49, 0x0F, 0xAF, 0xD5}},
|
||||
{x86.RBX, x86.R12, []byte{0x49, 0x0F, 0xAF, 0xDC}},
|
||||
{x86.RSP, x86.R11, []byte{0x49, 0x0F, 0xAF, 0xE3}},
|
||||
{x86.RBP, x86.R10, []byte{0x49, 0x0F, 0xAF, 0xEA}},
|
||||
{x86.RSI, x86.R9, []byte{0x49, 0x0F, 0xAF, 0xF1}},
|
||||
{x86.RDI, x86.R8, []byte{0x49, 0x0F, 0xAF, 0xF8}},
|
||||
{x86.R8, x86.RDI, []byte{0x4C, 0x0F, 0xAF, 0xC7}},
|
||||
{x86.R9, x86.RSI, []byte{0x4C, 0x0F, 0xAF, 0xCE}},
|
||||
{x86.R10, x86.RBP, []byte{0x4C, 0x0F, 0xAF, 0xD5}},
|
||||
{x86.R11, x86.RSP, []byte{0x4C, 0x0F, 0xAF, 0xDC}},
|
||||
{x86.R12, x86.RBX, []byte{0x4C, 0x0F, 0xAF, 0xE3}},
|
||||
{x86.R13, x86.RDX, []byte{0x4C, 0x0F, 0xAF, 0xEA}},
|
||||
{x86.R14, x86.RCX, []byte{0x4C, 0x0F, 0xAF, 0xF1}},
|
||||
{x86.R15, x86.RAX, []byte{0x4C, 0x0F, 0xAF, 0xF8}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("mul %s, %s", pattern.Left, pattern.Right)
|
||||
code := x86.MulRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
39
src/x86/Negate_test.go
Normal file
39
src/x86/Negate_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestNegateRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, []byte{0x48, 0xF7, 0xD8}},
|
||||
{x86.RCX, []byte{0x48, 0xF7, 0xD9}},
|
||||
{x86.RDX, []byte{0x48, 0xF7, 0xDA}},
|
||||
{x86.RBX, []byte{0x48, 0xF7, 0xDB}},
|
||||
{x86.RSP, []byte{0x48, 0xF7, 0xDC}},
|
||||
{x86.RBP, []byte{0x48, 0xF7, 0xDD}},
|
||||
{x86.RSI, []byte{0x48, 0xF7, 0xDE}},
|
||||
{x86.RDI, []byte{0x48, 0xF7, 0xDF}},
|
||||
{x86.R8, []byte{0x49, 0xF7, 0xD8}},
|
||||
{x86.R9, []byte{0x49, 0xF7, 0xD9}},
|
||||
{x86.R10, []byte{0x49, 0xF7, 0xDA}},
|
||||
{x86.R11, []byte{0x49, 0xF7, 0xDB}},
|
||||
{x86.R12, []byte{0x49, 0xF7, 0xDC}},
|
||||
{x86.R13, []byte{0x49, 0xF7, 0xDD}},
|
||||
{x86.R14, []byte{0x49, 0xF7, 0xDE}},
|
||||
{x86.R15, []byte{0x49, 0xF7, 0xDF}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("neg %s", pattern.Register)
|
||||
code := x86.NegateRegister(nil, pattern.Register)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
88
src/x86/Or_test.go
Normal file
88
src/x86/Or_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestOrRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, 1, []byte{0x48, 0x83, 0xC8, 0x01}},
|
||||
{x86.RCX, 1, []byte{0x48, 0x83, 0xC9, 0x01}},
|
||||
{x86.RDX, 1, []byte{0x48, 0x83, 0xCA, 0x01}},
|
||||
{x86.RBX, 1, []byte{0x48, 0x83, 0xCB, 0x01}},
|
||||
{x86.RSP, 1, []byte{0x48, 0x83, 0xCC, 0x01}},
|
||||
{x86.RBP, 1, []byte{0x48, 0x83, 0xCD, 0x01}},
|
||||
{x86.RSI, 1, []byte{0x48, 0x83, 0xCE, 0x01}},
|
||||
{x86.RDI, 1, []byte{0x48, 0x83, 0xCF, 0x01}},
|
||||
{x86.R8, 1, []byte{0x49, 0x83, 0xC8, 0x01}},
|
||||
{x86.R9, 1, []byte{0x49, 0x83, 0xC9, 0x01}},
|
||||
{x86.R10, 1, []byte{0x49, 0x83, 0xCA, 0x01}},
|
||||
{x86.R11, 1, []byte{0x49, 0x83, 0xCB, 0x01}},
|
||||
{x86.R12, 1, []byte{0x49, 0x83, 0xCC, 0x01}},
|
||||
{x86.R13, 1, []byte{0x49, 0x83, 0xCD, 0x01}},
|
||||
{x86.R14, 1, []byte{0x49, 0x83, 0xCE, 0x01}},
|
||||
{x86.R15, 1, []byte{0x49, 0x83, 0xCF, 0x01}},
|
||||
|
||||
{x86.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xC9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xCF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xC9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCD, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xCF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("or %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.OrRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, []byte{0x4C, 0x09, 0xF8}},
|
||||
{x86.RCX, x86.R14, []byte{0x4C, 0x09, 0xF1}},
|
||||
{x86.RDX, x86.R13, []byte{0x4C, 0x09, 0xEA}},
|
||||
{x86.RBX, x86.R12, []byte{0x4C, 0x09, 0xE3}},
|
||||
{x86.RSP, x86.R11, []byte{0x4C, 0x09, 0xDC}},
|
||||
{x86.RBP, x86.R10, []byte{0x4C, 0x09, 0xD5}},
|
||||
{x86.RSI, x86.R9, []byte{0x4C, 0x09, 0xCE}},
|
||||
{x86.RDI, x86.R8, []byte{0x4C, 0x09, 0xC7}},
|
||||
{x86.R8, x86.RDI, []byte{0x49, 0x09, 0xF8}},
|
||||
{x86.R9, x86.RSI, []byte{0x49, 0x09, 0xF1}},
|
||||
{x86.R10, x86.RBP, []byte{0x49, 0x09, 0xEA}},
|
||||
{x86.R11, x86.RSP, []byte{0x49, 0x09, 0xE3}},
|
||||
{x86.R12, x86.RBX, []byte{0x49, 0x09, 0xDC}},
|
||||
{x86.R13, x86.RDX, []byte{0x49, 0x09, 0xD5}},
|
||||
{x86.R14, x86.RCX, []byte{0x49, 0x09, 0xCE}},
|
||||
{x86.R15, x86.RAX, []byte{0x49, 0x09, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("or %s, %s", pattern.Left, pattern.Right)
|
||||
code := x86.OrRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
39
src/x86/Pop_test.go
Normal file
39
src/x86/Pop_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestPopRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, []byte{0x58}},
|
||||
{x86.RCX, []byte{0x59}},
|
||||
{x86.RDX, []byte{0x5A}},
|
||||
{x86.RBX, []byte{0x5B}},
|
||||
{x86.RSP, []byte{0x5C}},
|
||||
{x86.RBP, []byte{0x5D}},
|
||||
{x86.RSI, []byte{0x5E}},
|
||||
{x86.RDI, []byte{0x5F}},
|
||||
{x86.R8, []byte{0x41, 0x58}},
|
||||
{x86.R9, []byte{0x41, 0x59}},
|
||||
{x86.R10, []byte{0x41, 0x5A}},
|
||||
{x86.R11, []byte{0x41, 0x5B}},
|
||||
{x86.R12, []byte{0x41, 0x5C}},
|
||||
{x86.R13, []byte{0x41, 0x5D}},
|
||||
{x86.R14, []byte{0x41, 0x5E}},
|
||||
{x86.R15, []byte{0x41, 0x5F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("pop %s", pattern.Register)
|
||||
code := x86.PopRegister(nil, pattern.Register)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
39
src/x86/Push_test.go
Normal file
39
src/x86/Push_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestPushRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, []byte{0x50}},
|
||||
{x86.RCX, []byte{0x51}},
|
||||
{x86.RDX, []byte{0x52}},
|
||||
{x86.RBX, []byte{0x53}},
|
||||
{x86.RSP, []byte{0x54}},
|
||||
{x86.RBP, []byte{0x55}},
|
||||
{x86.RSI, []byte{0x56}},
|
||||
{x86.RDI, []byte{0x57}},
|
||||
{x86.R8, []byte{0x41, 0x50}},
|
||||
{x86.R9, []byte{0x41, 0x51}},
|
||||
{x86.R10, []byte{0x41, 0x52}},
|
||||
{x86.R11, []byte{0x41, 0x53}},
|
||||
{x86.R12, []byte{0x41, 0x54}},
|
||||
{x86.R13, []byte{0x41, 0x55}},
|
||||
{x86.R14, []byte{0x41, 0x56}},
|
||||
{x86.R15, []byte{0x41, 0x57}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("push %s", pattern.Register)
|
||||
code := x86.PushRegister(nil, pattern.Register)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
// REX is used to generate a REX prefix.
|
||||
// w, r, x and b can only be set to either 0 or 1.
|
@ -1,9 +1,9 @@
|
||||
package x64_test
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
@ -28,7 +28,7 @@ func TestREX(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range testData {
|
||||
rex := x64.REX(test.w, test.r, test.x, test.b)
|
||||
rex := x86.REX(test.w, test.r, test.x, test.b)
|
||||
assert.Equal(t, rex, test.expected)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
12
src/x86/Registers_test.go
Normal file
12
src/x86/Registers_test.go
Normal file
@ -0,0 +1,12 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestRegisters(t *testing.T) {
|
||||
assert.NotContains(t, x86.GeneralRegisters, x86.RSP)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
// Return transfers program control to a return address located on the top of the stack.
|
||||
// The address is usually placed on the stack by a Call instruction.
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
// ScaleFactor encodes the scale factor.
|
||||
type ScaleFactor = byte
|
@ -1,9 +1,9 @@
|
||||
package x64_test
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
@ -28,7 +28,7 @@ func TestSIB(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range testData {
|
||||
sib := x64.SIB(test.scale, test.index, test.base)
|
||||
sib := x86.SIB(test.scale, test.index, test.base)
|
||||
assert.Equal(t, sib, test.expected)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
71
src/x86/Shift_test.go
Normal file
71
src/x86/Shift_test.go
Normal file
@ -0,0 +1,71 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestShiftLeftNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, 1, []byte{0x48, 0xC1, 0xE0, 0x01}},
|
||||
{x86.RCX, 1, []byte{0x48, 0xC1, 0xE1, 0x01}},
|
||||
{x86.RDX, 1, []byte{0x48, 0xC1, 0xE2, 0x01}},
|
||||
{x86.RBX, 1, []byte{0x48, 0xC1, 0xE3, 0x01}},
|
||||
{x86.RSP, 1, []byte{0x48, 0xC1, 0xE4, 0x01}},
|
||||
{x86.RBP, 1, []byte{0x48, 0xC1, 0xE5, 0x01}},
|
||||
{x86.RSI, 1, []byte{0x48, 0xC1, 0xE6, 0x01}},
|
||||
{x86.RDI, 1, []byte{0x48, 0xC1, 0xE7, 0x01}},
|
||||
{x86.R8, 1, []byte{0x49, 0xC1, 0xE0, 0x01}},
|
||||
{x86.R9, 1, []byte{0x49, 0xC1, 0xE1, 0x01}},
|
||||
{x86.R10, 1, []byte{0x49, 0xC1, 0xE2, 0x01}},
|
||||
{x86.R11, 1, []byte{0x49, 0xC1, 0xE3, 0x01}},
|
||||
{x86.R12, 1, []byte{0x49, 0xC1, 0xE4, 0x01}},
|
||||
{x86.R13, 1, []byte{0x49, 0xC1, 0xE5, 0x01}},
|
||||
{x86.R14, 1, []byte{0x49, 0xC1, 0xE6, 0x01}},
|
||||
{x86.R15, 1, []byte{0x49, 0xC1, 0xE7, 0x01}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("shl %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.ShiftLeftNumber(nil, pattern.Register, byte(pattern.Number))
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShiftRightSignedNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, 1, []byte{0x48, 0xC1, 0xF8, 0x01}},
|
||||
{x86.RCX, 1, []byte{0x48, 0xC1, 0xF9, 0x01}},
|
||||
{x86.RDX, 1, []byte{0x48, 0xC1, 0xFA, 0x01}},
|
||||
{x86.RBX, 1, []byte{0x48, 0xC1, 0xFB, 0x01}},
|
||||
{x86.RSP, 1, []byte{0x48, 0xC1, 0xFC, 0x01}},
|
||||
{x86.RBP, 1, []byte{0x48, 0xC1, 0xFD, 0x01}},
|
||||
{x86.RSI, 1, []byte{0x48, 0xC1, 0xFE, 0x01}},
|
||||
{x86.RDI, 1, []byte{0x48, 0xC1, 0xFF, 0x01}},
|
||||
{x86.R8, 1, []byte{0x49, 0xC1, 0xF8, 0x01}},
|
||||
{x86.R9, 1, []byte{0x49, 0xC1, 0xF9, 0x01}},
|
||||
{x86.R10, 1, []byte{0x49, 0xC1, 0xFA, 0x01}},
|
||||
{x86.R11, 1, []byte{0x49, 0xC1, 0xFB, 0x01}},
|
||||
{x86.R12, 1, []byte{0x49, 0xC1, 0xFC, 0x01}},
|
||||
{x86.R13, 1, []byte{0x49, 0xC1, 0xFD, 0x01}},
|
||||
{x86.R14, 1, []byte{0x49, 0xC1, 0xFE, 0x01}},
|
||||
{x86.R15, 1, []byte{0x49, 0xC1, 0xFF, 0x01}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("sar %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.ShiftRightSignedNumber(nil, pattern.Register, byte(pattern.Number))
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
171
src/x86/StoreDynamic_test.go
Normal file
171
src/x86/StoreDynamic_test.go
Normal file
@ -0,0 +1,171 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestStoreDynamicNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
RegisterTo cpu.Register
|
||||
Offset cpu.Register
|
||||
Length byte
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RAX, x86.R15, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RAX, x86.R15, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x38, 0x7F, 0x00}},
|
||||
{x86.RAX, x86.R15, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x38, 0x7F}},
|
||||
{x86.RCX, x86.R14, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RCX, x86.R14, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RCX, x86.R14, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x31, 0x7F, 0x00}},
|
||||
{x86.RCX, x86.R14, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x31, 0x7F}},
|
||||
{x86.RDX, x86.R13, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDX, x86.R13, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDX, x86.R13, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x2A, 0x7F, 0x00}},
|
||||
{x86.RDX, x86.R13, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x2A, 0x7F}},
|
||||
{x86.RBX, x86.R12, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x23, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBX, x86.R12, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x23, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBX, x86.R12, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x23, 0x7F, 0x00}},
|
||||
{x86.RBX, x86.R12, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x23, 0x7F}},
|
||||
{x86.RSP, x86.R11, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSP, x86.R11, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSP, x86.R11, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00}},
|
||||
{x86.RSP, x86.R11, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x1C, 0x7F}},
|
||||
{x86.RBP, x86.R10, 8, 0x7F, []byte{0x4A, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBP, x86.R10, 4, 0x7F, []byte{0x42, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBP, x86.R10, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00}},
|
||||
{x86.RBP, x86.R10, 1, 0x7F, []byte{0x42, 0xC6, 0x44, 0x15, 0x00, 0x7F}},
|
||||
{x86.RSI, x86.R9, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSI, x86.R9, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSI, x86.R9, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x0E, 0x7F, 0x00}},
|
||||
{x86.RSI, x86.R9, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x0E, 0x7F}},
|
||||
{x86.RDI, x86.R8, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDI, x86.R8, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDI, x86.R8, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x07, 0x7F, 0x00}},
|
||||
{x86.RDI, x86.R8, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x07, 0x7F}},
|
||||
{x86.R8, x86.RDI, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R8, x86.RDI, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x38, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R8, x86.RDI, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x38, 0x7F, 0x00}},
|
||||
{x86.R8, x86.RDI, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x38, 0x7F}},
|
||||
{x86.R9, x86.RSI, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R9, x86.RSI, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x31, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R9, x86.RSI, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x31, 0x7F, 0x00}},
|
||||
{x86.R9, x86.RSI, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x31, 0x7F}},
|
||||
{x86.R10, x86.RBP, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R10, x86.RBP, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x2A, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R10, x86.RBP, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x2A, 0x7F, 0x00}},
|
||||
{x86.R10, x86.RBP, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x2A, 0x7F}},
|
||||
{x86.R11, x86.RSP, 8, 0x7F, []byte{0x4A, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R11, x86.RSP, 4, 0x7F, []byte{0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R11, x86.RSP, 2, 0x7F, []byte{0x66, 0x42, 0xC7, 0x04, 0x1C, 0x7F, 0x00}},
|
||||
{x86.R11, x86.RSP, 1, 0x7F, []byte{0x42, 0xC6, 0x04, 0x1C, 0x7F}},
|
||||
{x86.R12, x86.RBX, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R12, x86.RBX, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x1C, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R12, x86.RBX, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x1C, 0x7F, 0x00}},
|
||||
{x86.R12, x86.RBX, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x1C, 0x7F}},
|
||||
{x86.R13, x86.RDX, 8, 0x7F, []byte{0x49, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R13, x86.RDX, 4, 0x7F, []byte{0x41, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R13, x86.RDX, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x44, 0x15, 0x00, 0x7F, 0x00}},
|
||||
{x86.R13, x86.RDX, 1, 0x7F, []byte{0x41, 0xC6, 0x44, 0x15, 0x00, 0x7F}},
|
||||
{x86.R14, x86.RCX, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R14, x86.RCX, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x0E, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R14, x86.RCX, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x0E, 0x7F, 0x00}},
|
||||
{x86.R14, x86.RCX, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x0E, 0x7F}},
|
||||
{x86.R15, x86.RAX, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R15, x86.RAX, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R15, x86.RAX, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x07, 0x7F, 0x00}},
|
||||
{x86.R15, x86.RAX, 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.Length, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreDynamicRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
RegisterTo cpu.Register
|
||||
Offset cpu.Register
|
||||
Length byte
|
||||
RegisterFrom cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, 8, x86.R15, []byte{0x4E, 0x89, 0x3C, 0x38}},
|
||||
{x86.RAX, x86.R15, 4, x86.R15, []byte{0x46, 0x89, 0x3C, 0x38}},
|
||||
{x86.RAX, x86.R15, 2, x86.R15, []byte{0x66, 0x46, 0x89, 0x3C, 0x38}},
|
||||
{x86.RAX, x86.R15, 1, x86.R15, []byte{0x46, 0x88, 0x3C, 0x38}},
|
||||
{x86.RCX, x86.R14, 8, x86.R14, []byte{0x4E, 0x89, 0x34, 0x31}},
|
||||
{x86.RCX, x86.R14, 4, x86.R14, []byte{0x46, 0x89, 0x34, 0x31}},
|
||||
{x86.RCX, x86.R14, 2, x86.R14, []byte{0x66, 0x46, 0x89, 0x34, 0x31}},
|
||||
{x86.RCX, x86.R14, 1, x86.R14, []byte{0x46, 0x88, 0x34, 0x31}},
|
||||
{x86.RDX, x86.R13, 8, x86.R13, []byte{0x4E, 0x89, 0x2C, 0x2A}},
|
||||
{x86.RDX, x86.R13, 4, x86.R13, []byte{0x46, 0x89, 0x2C, 0x2A}},
|
||||
{x86.RDX, x86.R13, 2, x86.R13, []byte{0x66, 0x46, 0x89, 0x2C, 0x2A}},
|
||||
{x86.RDX, x86.R13, 1, x86.R13, []byte{0x46, 0x88, 0x2C, 0x2A}},
|
||||
{x86.RBX, x86.R12, 8, x86.R12, []byte{0x4E, 0x89, 0x24, 0x23}},
|
||||
{x86.RBX, x86.R12, 4, x86.R12, []byte{0x46, 0x89, 0x24, 0x23}},
|
||||
{x86.RBX, x86.R12, 2, x86.R12, []byte{0x66, 0x46, 0x89, 0x24, 0x23}},
|
||||
{x86.RBX, x86.R12, 1, x86.R12, []byte{0x46, 0x88, 0x24, 0x23}},
|
||||
{x86.RSP, x86.R11, 8, x86.R11, []byte{0x4E, 0x89, 0x1C, 0x1C}},
|
||||
{x86.RSP, x86.R11, 4, x86.R11, []byte{0x46, 0x89, 0x1C, 0x1C}},
|
||||
{x86.RSP, x86.R11, 2, x86.R11, []byte{0x66, 0x46, 0x89, 0x1C, 0x1C}},
|
||||
{x86.RSP, x86.R11, 1, x86.R11, []byte{0x46, 0x88, 0x1C, 0x1C}},
|
||||
{x86.RBP, x86.R10, 8, x86.R10, []byte{0x4E, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x86.RBP, x86.R10, 4, x86.R10, []byte{0x46, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x86.RBP, x86.R10, 2, x86.R10, []byte{0x66, 0x46, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x86.RBP, x86.R10, 1, x86.R10, []byte{0x46, 0x88, 0x54, 0x15, 0x00}},
|
||||
{x86.RSI, x86.R9, 8, x86.R9, []byte{0x4E, 0x89, 0x0C, 0x0E}},
|
||||
{x86.RSI, x86.R9, 4, x86.R9, []byte{0x46, 0x89, 0x0C, 0x0E}},
|
||||
{x86.RSI, x86.R9, 2, x86.R9, []byte{0x66, 0x46, 0x89, 0x0C, 0x0E}},
|
||||
{x86.RSI, x86.R9, 1, x86.R9, []byte{0x46, 0x88, 0x0C, 0x0E}},
|
||||
{x86.RDI, x86.R8, 8, x86.R8, []byte{0x4E, 0x89, 0x04, 0x07}},
|
||||
{x86.RDI, x86.R8, 4, x86.R8, []byte{0x46, 0x89, 0x04, 0x07}},
|
||||
{x86.RDI, x86.R8, 2, x86.R8, []byte{0x66, 0x46, 0x89, 0x04, 0x07}},
|
||||
{x86.RDI, x86.R8, 1, x86.R8, []byte{0x46, 0x88, 0x04, 0x07}},
|
||||
{x86.R8, x86.RDI, 8, x86.RDI, []byte{0x49, 0x89, 0x3C, 0x38}},
|
||||
{x86.R8, x86.RDI, 4, x86.RDI, []byte{0x41, 0x89, 0x3C, 0x38}},
|
||||
{x86.R8, x86.RDI, 2, x86.RDI, []byte{0x66, 0x41, 0x89, 0x3C, 0x38}},
|
||||
{x86.R8, x86.RDI, 1, x86.RDI, []byte{0x41, 0x88, 0x3C, 0x38}},
|
||||
{x86.R9, x86.RSI, 8, x86.RSI, []byte{0x49, 0x89, 0x34, 0x31}},
|
||||
{x86.R9, x86.RSI, 4, x86.RSI, []byte{0x41, 0x89, 0x34, 0x31}},
|
||||
{x86.R9, x86.RSI, 2, x86.RSI, []byte{0x66, 0x41, 0x89, 0x34, 0x31}},
|
||||
{x86.R9, x86.RSI, 1, x86.RSI, []byte{0x41, 0x88, 0x34, 0x31}},
|
||||
{x86.R10, x86.RBP, 8, x86.RBP, []byte{0x49, 0x89, 0x2C, 0x2A}},
|
||||
{x86.R10, x86.RBP, 4, x86.RBP, []byte{0x41, 0x89, 0x2C, 0x2A}},
|
||||
{x86.R10, x86.RBP, 2, x86.RBP, []byte{0x66, 0x41, 0x89, 0x2C, 0x2A}},
|
||||
{x86.R10, x86.RBP, 1, x86.RBP, []byte{0x41, 0x88, 0x2C, 0x2A}},
|
||||
{x86.R11, x86.RSP, 8, x86.RSP, []byte{0x4A, 0x89, 0x24, 0x1C}},
|
||||
{x86.R11, x86.RSP, 4, x86.RSP, []byte{0x42, 0x89, 0x24, 0x1C}},
|
||||
{x86.R11, x86.RSP, 2, x86.RSP, []byte{0x66, 0x42, 0x89, 0x24, 0x1C}},
|
||||
{x86.R11, x86.RSP, 1, x86.RSP, []byte{0x42, 0x88, 0x24, 0x1C}},
|
||||
{x86.R12, x86.RBX, 8, x86.RBX, []byte{0x49, 0x89, 0x1C, 0x1C}},
|
||||
{x86.R12, x86.RBX, 4, x86.RBX, []byte{0x41, 0x89, 0x1C, 0x1C}},
|
||||
{x86.R12, x86.RBX, 2, x86.RBX, []byte{0x66, 0x41, 0x89, 0x1C, 0x1C}},
|
||||
{x86.R12, x86.RBX, 1, x86.RBX, []byte{0x41, 0x88, 0x1C, 0x1C}},
|
||||
{x86.R13, x86.RDX, 8, x86.RDX, []byte{0x49, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x86.R13, x86.RDX, 4, x86.RDX, []byte{0x41, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x86.R13, x86.RDX, 2, x86.RDX, []byte{0x66, 0x41, 0x89, 0x54, 0x15, 0x00}},
|
||||
{x86.R13, x86.RDX, 1, x86.RDX, []byte{0x41, 0x88, 0x54, 0x15, 0x00}},
|
||||
{x86.R14, x86.RCX, 8, x86.RCX, []byte{0x49, 0x89, 0x0C, 0x0E}},
|
||||
{x86.R14, x86.RCX, 4, x86.RCX, []byte{0x41, 0x89, 0x0C, 0x0E}},
|
||||
{x86.R14, x86.RCX, 2, x86.RCX, []byte{0x66, 0x41, 0x89, 0x0C, 0x0E}},
|
||||
{x86.R14, x86.RCX, 1, x86.RCX, []byte{0x41, 0x88, 0x0C, 0x0E}},
|
||||
{x86.R15, x86.RAX, 8, x86.RAX, []byte{0x49, 0x89, 0x04, 0x07}},
|
||||
{x86.R15, x86.RAX, 4, x86.RAX, []byte{0x41, 0x89, 0x04, 0x07}},
|
||||
{x86.R15, x86.RAX, 2, x86.RAX, []byte{0x66, 0x41, 0x89, 0x04, 0x07}},
|
||||
{x86.R15, x86.RAX, 1, x86.RAX, []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.Length, pattern.RegisterFrom)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
305
src/x86/Store_test.go
Normal file
305
src/x86/Store_test.go
Normal file
@ -0,0 +1,305 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestStoreNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Offset byte
|
||||
Length byte
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
// No offset
|
||||
{x86.RAX, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RAX, 0, 4, 0x7F, []byte{0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RAX, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x00, 0x7F, 0x00}},
|
||||
{x86.RAX, 0, 1, 0x7F, []byte{0xC6, 0x00, 0x7F}},
|
||||
{x86.RCX, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RCX, 0, 4, 0x7F, []byte{0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RCX, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x01, 0x7F, 0x00}},
|
||||
{x86.RCX, 0, 1, 0x7F, []byte{0xC6, 0x01, 0x7F}},
|
||||
{x86.RDX, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDX, 0, 4, 0x7F, []byte{0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDX, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x02, 0x7F, 0x00}},
|
||||
{x86.RDX, 0, 1, 0x7F, []byte{0xC6, 0x02, 0x7F}},
|
||||
{x86.RBX, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBX, 0, 4, 0x7F, []byte{0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBX, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x03, 0x7F, 0x00}},
|
||||
{x86.RBX, 0, 1, 0x7F, []byte{0xC6, 0x03, 0x7F}},
|
||||
{x86.RSP, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSP, 0, 4, 0x7F, []byte{0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSP, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x04, 0x24, 0x7F, 0x00}},
|
||||
{x86.RSP, 0, 1, 0x7F, []byte{0xC6, 0x04, 0x24, 0x7F}},
|
||||
{x86.RBP, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBP, 0, 4, 0x7F, []byte{0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBP, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x45, 0x00, 0x7F, 0x00}},
|
||||
{x86.RBP, 0, 1, 0x7F, []byte{0xC6, 0x45, 0x00, 0x7F}},
|
||||
{x86.RSI, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSI, 0, 4, 0x7F, []byte{0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSI, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x06, 0x7F, 0x00}},
|
||||
{x86.RSI, 0, 1, 0x7F, []byte{0xC6, 0x06, 0x7F}},
|
||||
{x86.RDI, 0, 8, 0x7F, []byte{0x48, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDI, 0, 4, 0x7F, []byte{0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDI, 0, 2, 0x7F, []byte{0x66, 0xC7, 0x07, 0x7F, 0x00}},
|
||||
{x86.RDI, 0, 1, 0x7F, []byte{0xC6, 0x07, 0x7F}},
|
||||
{x86.R8, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R8, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R8, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x00, 0x7F, 0x00}},
|
||||
{x86.R8, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x00, 0x7F}},
|
||||
{x86.R9, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R9, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R9, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x01, 0x7F, 0x00}},
|
||||
{x86.R9, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x01, 0x7F}},
|
||||
{x86.R10, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R10, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x02, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R10, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x02, 0x7F, 0x00}},
|
||||
{x86.R10, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x02, 0x7F}},
|
||||
{x86.R11, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R11, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x03, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R11, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x03, 0x7F, 0x00}},
|
||||
{x86.R11, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x03, 0x7F}},
|
||||
{x86.R12, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R12, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x04, 0x24, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R12, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x04, 0x24, 0x7F, 0x00}},
|
||||
{x86.R12, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x04, 0x24, 0x7F}},
|
||||
{x86.R13, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R13, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x45, 0x00, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R13, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x45, 0x00, 0x7F, 0x00}},
|
||||
{x86.R13, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x45, 0x00, 0x7F}},
|
||||
{x86.R14, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R14, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x06, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R14, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x06, 0x7F, 0x00}},
|
||||
{x86.R14, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x06, 0x7F}},
|
||||
{x86.R15, 0, 8, 0x7F, []byte{0x49, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R15, 0, 4, 0x7F, []byte{0x41, 0xC7, 0x07, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R15, 0, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x07, 0x7F, 0x00}},
|
||||
{x86.R15, 0, 1, 0x7F, []byte{0x41, 0xC6, 0x07, 0x7F}},
|
||||
|
||||
// Offset of 1
|
||||
{x86.RAX, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RAX, 1, 4, 0x7F, []byte{0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RAX, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x40, 0x01, 0x7F, 0x00}},
|
||||
{x86.RAX, 1, 1, 0x7F, []byte{0xC6, 0x40, 0x01, 0x7F}},
|
||||
{x86.RCX, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RCX, 1, 4, 0x7F, []byte{0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RCX, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x41, 0x01, 0x7F, 0x00}},
|
||||
{x86.RCX, 1, 1, 0x7F, []byte{0xC6, 0x41, 0x01, 0x7F}},
|
||||
{x86.RDX, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDX, 1, 4, 0x7F, []byte{0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDX, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x42, 0x01, 0x7F, 0x00}},
|
||||
{x86.RDX, 1, 1, 0x7F, []byte{0xC6, 0x42, 0x01, 0x7F}},
|
||||
{x86.RBX, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBX, 1, 4, 0x7F, []byte{0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBX, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x43, 0x01, 0x7F, 0x00}},
|
||||
{x86.RBX, 1, 1, 0x7F, []byte{0xC6, 0x43, 0x01, 0x7F}},
|
||||
{x86.RSP, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSP, 1, 4, 0x7F, []byte{0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSP, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00}},
|
||||
{x86.RSP, 1, 1, 0x7F, []byte{0xC6, 0x44, 0x24, 0x01, 0x7F}},
|
||||
{x86.RBP, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBP, 1, 4, 0x7F, []byte{0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RBP, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x45, 0x01, 0x7F, 0x00}},
|
||||
{x86.RBP, 1, 1, 0x7F, []byte{0xC6, 0x45, 0x01, 0x7F}},
|
||||
{x86.RSI, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSI, 1, 4, 0x7F, []byte{0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RSI, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x46, 0x01, 0x7F, 0x00}},
|
||||
{x86.RSI, 1, 1, 0x7F, []byte{0xC6, 0x46, 0x01, 0x7F}},
|
||||
{x86.RDI, 1, 8, 0x7F, []byte{0x48, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDI, 1, 4, 0x7F, []byte{0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.RDI, 1, 2, 0x7F, []byte{0x66, 0xC7, 0x47, 0x01, 0x7F, 0x00}},
|
||||
{x86.RDI, 1, 1, 0x7F, []byte{0xC6, 0x47, 0x01, 0x7F}},
|
||||
{x86.R8, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R8, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x40, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R8, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x40, 0x01, 0x7F, 0x00}},
|
||||
{x86.R8, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x40, 0x01, 0x7F}},
|
||||
{x86.R9, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R9, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x41, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R9, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x41, 0x01, 0x7F, 0x00}},
|
||||
{x86.R9, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x41, 0x01, 0x7F}},
|
||||
{x86.R10, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R10, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x42, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R10, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x42, 0x01, 0x7F, 0x00}},
|
||||
{x86.R10, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x42, 0x01, 0x7F}},
|
||||
{x86.R11, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R11, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x43, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R11, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x43, 0x01, 0x7F, 0x00}},
|
||||
{x86.R11, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x43, 0x01, 0x7F}},
|
||||
{x86.R12, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R12, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R12, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x44, 0x24, 0x01, 0x7F, 0x00}},
|
||||
{x86.R12, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x44, 0x24, 0x01, 0x7F}},
|
||||
{x86.R13, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R13, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x45, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R13, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x45, 0x01, 0x7F, 0x00}},
|
||||
{x86.R13, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x45, 0x01, 0x7F}},
|
||||
{x86.R14, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R14, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x46, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R14, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x46, 0x01, 0x7F, 0x00}},
|
||||
{x86.R14, 1, 1, 0x7F, []byte{0x41, 0xC6, 0x46, 0x01, 0x7F}},
|
||||
{x86.R15, 1, 8, 0x7F, []byte{0x49, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R15, 1, 4, 0x7F, []byte{0x41, 0xC7, 0x47, 0x01, 0x7F, 0x00, 0x00, 0x00}},
|
||||
{x86.R15, 1, 2, 0x7F, []byte{0x66, 0x41, 0xC7, 0x47, 0x01, 0x7F, 0x00}},
|
||||
{x86.R15, 1, 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.StoreNumber(nil, pattern.Register, pattern.Offset, pattern.Length, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
RegisterTo cpu.Register
|
||||
Offset byte
|
||||
Length byte
|
||||
RegisterFrom cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
// No offset
|
||||
{x86.RAX, 0, 8, x86.R15, []byte{0x4C, 0x89, 0x38}},
|
||||
{x86.RAX, 0, 4, x86.R15, []byte{0x44, 0x89, 0x38}},
|
||||
{x86.RAX, 0, 2, x86.R15, []byte{0x66, 0x44, 0x89, 0x38}},
|
||||
{x86.RAX, 0, 1, x86.R15, []byte{0x44, 0x88, 0x38}},
|
||||
{x86.RCX, 0, 8, x86.R14, []byte{0x4C, 0x89, 0x31}},
|
||||
{x86.RCX, 0, 4, x86.R14, []byte{0x44, 0x89, 0x31}},
|
||||
{x86.RCX, 0, 2, x86.R14, []byte{0x66, 0x44, 0x89, 0x31}},
|
||||
{x86.RCX, 0, 1, x86.R14, []byte{0x44, 0x88, 0x31}},
|
||||
{x86.RDX, 0, 8, x86.R13, []byte{0x4C, 0x89, 0x2A}},
|
||||
{x86.RDX, 0, 4, x86.R13, []byte{0x44, 0x89, 0x2A}},
|
||||
{x86.RDX, 0, 2, x86.R13, []byte{0x66, 0x44, 0x89, 0x2A}},
|
||||
{x86.RDX, 0, 1, x86.R13, []byte{0x44, 0x88, 0x2A}},
|
||||
{x86.RBX, 0, 8, x86.R12, []byte{0x4C, 0x89, 0x23}},
|
||||
{x86.RBX, 0, 4, x86.R12, []byte{0x44, 0x89, 0x23}},
|
||||
{x86.RBX, 0, 2, x86.R12, []byte{0x66, 0x44, 0x89, 0x23}},
|
||||
{x86.RBX, 0, 1, x86.R12, []byte{0x44, 0x88, 0x23}},
|
||||
{x86.RSP, 0, 8, x86.R11, []byte{0x4C, 0x89, 0x1C, 0x24}},
|
||||
{x86.RSP, 0, 4, x86.R11, []byte{0x44, 0x89, 0x1C, 0x24}},
|
||||
{x86.RSP, 0, 2, x86.R11, []byte{0x66, 0x44, 0x89, 0x1C, 0x24}},
|
||||
{x86.RSP, 0, 1, x86.R11, []byte{0x44, 0x88, 0x1C, 0x24}},
|
||||
{x86.RBP, 0, 8, x86.R10, []byte{0x4C, 0x89, 0x55, 0x00}},
|
||||
{x86.RBP, 0, 4, x86.R10, []byte{0x44, 0x89, 0x55, 0x00}},
|
||||
{x86.RBP, 0, 2, x86.R10, []byte{0x66, 0x44, 0x89, 0x55, 0x00}},
|
||||
{x86.RBP, 0, 1, x86.R10, []byte{0x44, 0x88, 0x55, 0x00}},
|
||||
{x86.RSI, 0, 8, x86.R9, []byte{0x4C, 0x89, 0x0E}},
|
||||
{x86.RSI, 0, 4, x86.R9, []byte{0x44, 0x89, 0x0E}},
|
||||
{x86.RSI, 0, 2, x86.R9, []byte{0x66, 0x44, 0x89, 0x0E}},
|
||||
{x86.RSI, 0, 1, x86.R9, []byte{0x44, 0x88, 0x0E}},
|
||||
{x86.RDI, 0, 8, x86.R8, []byte{0x4C, 0x89, 0x07}},
|
||||
{x86.RDI, 0, 4, x86.R8, []byte{0x44, 0x89, 0x07}},
|
||||
{x86.RDI, 0, 2, x86.R8, []byte{0x66, 0x44, 0x89, 0x07}},
|
||||
{x86.RDI, 0, 1, x86.R8, []byte{0x44, 0x88, 0x07}},
|
||||
{x86.R8, 0, 8, x86.RDI, []byte{0x49, 0x89, 0x38}},
|
||||
{x86.R8, 0, 4, x86.RDI, []byte{0x41, 0x89, 0x38}},
|
||||
{x86.R8, 0, 2, x86.RDI, []byte{0x66, 0x41, 0x89, 0x38}},
|
||||
{x86.R8, 0, 1, x86.RDI, []byte{0x41, 0x88, 0x38}},
|
||||
{x86.R9, 0, 8, x86.RSI, []byte{0x49, 0x89, 0x31}},
|
||||
{x86.R9, 0, 4, x86.RSI, []byte{0x41, 0x89, 0x31}},
|
||||
{x86.R9, 0, 2, x86.RSI, []byte{0x66, 0x41, 0x89, 0x31}},
|
||||
{x86.R9, 0, 1, x86.RSI, []byte{0x41, 0x88, 0x31}},
|
||||
{x86.R10, 0, 8, x86.RBP, []byte{0x49, 0x89, 0x2A}},
|
||||
{x86.R10, 0, 4, x86.RBP, []byte{0x41, 0x89, 0x2A}},
|
||||
{x86.R10, 0, 2, x86.RBP, []byte{0x66, 0x41, 0x89, 0x2A}},
|
||||
{x86.R10, 0, 1, x86.RBP, []byte{0x41, 0x88, 0x2A}},
|
||||
{x86.R11, 0, 8, x86.RSP, []byte{0x49, 0x89, 0x23}},
|
||||
{x86.R11, 0, 4, x86.RSP, []byte{0x41, 0x89, 0x23}},
|
||||
{x86.R11, 0, 2, x86.RSP, []byte{0x66, 0x41, 0x89, 0x23}},
|
||||
{x86.R11, 0, 1, x86.RSP, []byte{0x41, 0x88, 0x23}},
|
||||
{x86.R12, 0, 8, x86.RBX, []byte{0x49, 0x89, 0x1C, 0x24}},
|
||||
{x86.R12, 0, 4, x86.RBX, []byte{0x41, 0x89, 0x1C, 0x24}},
|
||||
{x86.R12, 0, 2, x86.RBX, []byte{0x66, 0x41, 0x89, 0x1C, 0x24}},
|
||||
{x86.R12, 0, 1, x86.RBX, []byte{0x41, 0x88, 0x1C, 0x24}},
|
||||
{x86.R13, 0, 8, x86.RDX, []byte{0x49, 0x89, 0x55, 0x00}},
|
||||
{x86.R13, 0, 4, x86.RDX, []byte{0x41, 0x89, 0x55, 0x00}},
|
||||
{x86.R13, 0, 2, x86.RDX, []byte{0x66, 0x41, 0x89, 0x55, 0x00}},
|
||||
{x86.R13, 0, 1, x86.RDX, []byte{0x41, 0x88, 0x55, 0x00}},
|
||||
{x86.R14, 0, 8, x86.RCX, []byte{0x49, 0x89, 0x0E}},
|
||||
{x86.R14, 0, 4, x86.RCX, []byte{0x41, 0x89, 0x0E}},
|
||||
{x86.R14, 0, 2, x86.RCX, []byte{0x66, 0x41, 0x89, 0x0E}},
|
||||
{x86.R14, 0, 1, x86.RCX, []byte{0x41, 0x88, 0x0E}},
|
||||
{x86.R15, 0, 8, x86.RAX, []byte{0x49, 0x89, 0x07}},
|
||||
{x86.R15, 0, 4, x86.RAX, []byte{0x41, 0x89, 0x07}},
|
||||
{x86.R15, 0, 2, x86.RAX, []byte{0x66, 0x41, 0x89, 0x07}},
|
||||
{x86.R15, 0, 1, x86.RAX, []byte{0x41, 0x88, 0x07}},
|
||||
|
||||
// Offset of 1
|
||||
{x86.RAX, 1, 8, x86.R15, []byte{0x4C, 0x89, 0x78, 0x01}},
|
||||
{x86.RAX, 1, 4, x86.R15, []byte{0x44, 0x89, 0x78, 0x01}},
|
||||
{x86.RAX, 1, 2, x86.R15, []byte{0x66, 0x44, 0x89, 0x78, 0x01}},
|
||||
{x86.RAX, 1, 1, x86.R15, []byte{0x44, 0x88, 0x78, 0x01}},
|
||||
{x86.RCX, 1, 8, x86.R14, []byte{0x4C, 0x89, 0x71, 0x01}},
|
||||
{x86.RCX, 1, 4, x86.R14, []byte{0x44, 0x89, 0x71, 0x01}},
|
||||
{x86.RCX, 1, 2, x86.R14, []byte{0x66, 0x44, 0x89, 0x71, 0x01}},
|
||||
{x86.RCX, 1, 1, x86.R14, []byte{0x44, 0x88, 0x71, 0x01}},
|
||||
{x86.RDX, 1, 8, x86.R13, []byte{0x4C, 0x89, 0x6A, 0x01}},
|
||||
{x86.RDX, 1, 4, x86.R13, []byte{0x44, 0x89, 0x6A, 0x01}},
|
||||
{x86.RDX, 1, 2, x86.R13, []byte{0x66, 0x44, 0x89, 0x6A, 0x01}},
|
||||
{x86.RDX, 1, 1, x86.R13, []byte{0x44, 0x88, 0x6A, 0x01}},
|
||||
{x86.RBX, 1, 8, x86.R12, []byte{0x4C, 0x89, 0x63, 0x01}},
|
||||
{x86.RBX, 1, 4, x86.R12, []byte{0x44, 0x89, 0x63, 0x01}},
|
||||
{x86.RBX, 1, 2, x86.R12, []byte{0x66, 0x44, 0x89, 0x63, 0x01}},
|
||||
{x86.RBX, 1, 1, x86.R12, []byte{0x44, 0x88, 0x63, 0x01}},
|
||||
{x86.RSP, 1, 8, x86.R11, []byte{0x4C, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x86.RSP, 1, 4, x86.R11, []byte{0x44, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x86.RSP, 1, 2, x86.R11, []byte{0x66, 0x44, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x86.RSP, 1, 1, x86.R11, []byte{0x44, 0x88, 0x5C, 0x24, 0x01}},
|
||||
{x86.RBP, 1, 8, x86.R10, []byte{0x4C, 0x89, 0x55, 0x01}},
|
||||
{x86.RBP, 1, 4, x86.R10, []byte{0x44, 0x89, 0x55, 0x01}},
|
||||
{x86.RBP, 1, 2, x86.R10, []byte{0x66, 0x44, 0x89, 0x55, 0x01}},
|
||||
{x86.RBP, 1, 1, x86.R10, []byte{0x44, 0x88, 0x55, 0x01}},
|
||||
{x86.RSI, 1, 8, x86.R9, []byte{0x4C, 0x89, 0x4E, 0x01}},
|
||||
{x86.RSI, 1, 4, x86.R9, []byte{0x44, 0x89, 0x4E, 0x01}},
|
||||
{x86.RSI, 1, 2, x86.R9, []byte{0x66, 0x44, 0x89, 0x4E, 0x01}},
|
||||
{x86.RSI, 1, 1, x86.R9, []byte{0x44, 0x88, 0x4E, 0x01}},
|
||||
{x86.RDI, 1, 8, x86.R8, []byte{0x4C, 0x89, 0x47, 0x01}},
|
||||
{x86.RDI, 1, 4, x86.R8, []byte{0x44, 0x89, 0x47, 0x01}},
|
||||
{x86.RDI, 1, 2, x86.R8, []byte{0x66, 0x44, 0x89, 0x47, 0x01}},
|
||||
{x86.RDI, 1, 1, x86.R8, []byte{0x44, 0x88, 0x47, 0x01}},
|
||||
{x86.R8, 1, 8, x86.RDI, []byte{0x49, 0x89, 0x78, 0x01}},
|
||||
{x86.R8, 1, 4, x86.RDI, []byte{0x41, 0x89, 0x78, 0x01}},
|
||||
{x86.R8, 1, 2, x86.RDI, []byte{0x66, 0x41, 0x89, 0x78, 0x01}},
|
||||
{x86.R8, 1, 1, x86.RDI, []byte{0x41, 0x88, 0x78, 0x01}},
|
||||
{x86.R9, 1, 8, x86.RSI, []byte{0x49, 0x89, 0x71, 0x01}},
|
||||
{x86.R9, 1, 4, x86.RSI, []byte{0x41, 0x89, 0x71, 0x01}},
|
||||
{x86.R9, 1, 2, x86.RSI, []byte{0x66, 0x41, 0x89, 0x71, 0x01}},
|
||||
{x86.R9, 1, 1, x86.RSI, []byte{0x41, 0x88, 0x71, 0x01}},
|
||||
{x86.R10, 1, 8, x86.RBP, []byte{0x49, 0x89, 0x6A, 0x01}},
|
||||
{x86.R10, 1, 4, x86.RBP, []byte{0x41, 0x89, 0x6A, 0x01}},
|
||||
{x86.R10, 1, 2, x86.RBP, []byte{0x66, 0x41, 0x89, 0x6A, 0x01}},
|
||||
{x86.R10, 1, 1, x86.RBP, []byte{0x41, 0x88, 0x6A, 0x01}},
|
||||
{x86.R11, 1, 8, x86.RSP, []byte{0x49, 0x89, 0x63, 0x01}},
|
||||
{x86.R11, 1, 4, x86.RSP, []byte{0x41, 0x89, 0x63, 0x01}},
|
||||
{x86.R11, 1, 2, x86.RSP, []byte{0x66, 0x41, 0x89, 0x63, 0x01}},
|
||||
{x86.R11, 1, 1, x86.RSP, []byte{0x41, 0x88, 0x63, 0x01}},
|
||||
{x86.R12, 1, 8, x86.RBX, []byte{0x49, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x86.R12, 1, 4, x86.RBX, []byte{0x41, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x86.R12, 1, 2, x86.RBX, []byte{0x66, 0x41, 0x89, 0x5C, 0x24, 0x01}},
|
||||
{x86.R12, 1, 1, x86.RBX, []byte{0x41, 0x88, 0x5C, 0x24, 01}},
|
||||
{x86.R13, 1, 8, x86.RDX, []byte{0x49, 0x89, 0x55, 0x01}},
|
||||
{x86.R13, 1, 4, x86.RDX, []byte{0x41, 0x89, 0x55, 0x01}},
|
||||
{x86.R13, 1, 2, x86.RDX, []byte{0x66, 0x41, 0x89, 0x55, 0x01}},
|
||||
{x86.R13, 1, 1, x86.RDX, []byte{0x41, 0x88, 0x55, 0x01}},
|
||||
{x86.R14, 1, 8, x86.RCX, []byte{0x49, 0x89, 0x4E, 0x01}},
|
||||
{x86.R14, 1, 4, x86.RCX, []byte{0x41, 0x89, 0x4E, 0x01}},
|
||||
{x86.R14, 1, 2, x86.RCX, []byte{0x66, 0x41, 0x89, 0x4E, 0x01}},
|
||||
{x86.R14, 1, 1, x86.RCX, []byte{0x41, 0x88, 0x4E, 0x01}},
|
||||
{x86.R15, 1, 8, x86.RAX, []byte{0x49, 0x89, 0x47, 0x01}},
|
||||
{x86.R15, 1, 4, x86.RAX, []byte{0x41, 0x89, 0x47, 0x01}},
|
||||
{x86.R15, 1, 2, x86.RAX, []byte{0x66, 0x41, 0x89, 0x47, 0x01}},
|
||||
{x86.R15, 1, 1, x86.RAX, []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.StoreRegister(nil, pattern.RegisterTo, pattern.Offset, pattern.Length, pattern.RegisterFrom)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
88
src/x86/Sub_test.go
Normal file
88
src/x86/Sub_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestSubRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, 1, []byte{0x48, 0x83, 0xE8, 0x01}},
|
||||
{x86.RCX, 1, []byte{0x48, 0x83, 0xE9, 0x01}},
|
||||
{x86.RDX, 1, []byte{0x48, 0x83, 0xEA, 0x01}},
|
||||
{x86.RBX, 1, []byte{0x48, 0x83, 0xEB, 0x01}},
|
||||
{x86.RSP, 1, []byte{0x48, 0x83, 0xEC, 0x01}},
|
||||
{x86.RBP, 1, []byte{0x48, 0x83, 0xED, 0x01}},
|
||||
{x86.RSI, 1, []byte{0x48, 0x83, 0xEE, 0x01}},
|
||||
{x86.RDI, 1, []byte{0x48, 0x83, 0xEF, 0x01}},
|
||||
{x86.R8, 1, []byte{0x49, 0x83, 0xE8, 0x01}},
|
||||
{x86.R9, 1, []byte{0x49, 0x83, 0xE9, 0x01}},
|
||||
{x86.R10, 1, []byte{0x49, 0x83, 0xEA, 0x01}},
|
||||
{x86.R11, 1, []byte{0x49, 0x83, 0xEB, 0x01}},
|
||||
{x86.R12, 1, []byte{0x49, 0x83, 0xEC, 0x01}},
|
||||
{x86.R13, 1, []byte{0x49, 0x83, 0xED, 0x01}},
|
||||
{x86.R14, 1, []byte{0x49, 0x83, 0xEE, 0x01}},
|
||||
{x86.R15, 1, []byte{0x49, 0x83, 0xEF, 0x01}},
|
||||
|
||||
{x86.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xE9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xED, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xEF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE8, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xE9, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEA, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEB, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEC, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xED, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEE, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xEF, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("sub %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.SubRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, []byte{0x4C, 0x29, 0xF8}},
|
||||
{x86.RCX, x86.R14, []byte{0x4C, 0x29, 0xF1}},
|
||||
{x86.RDX, x86.R13, []byte{0x4C, 0x29, 0xEA}},
|
||||
{x86.RBX, x86.R12, []byte{0x4C, 0x29, 0xE3}},
|
||||
{x86.RSP, x86.R11, []byte{0x4C, 0x29, 0xDC}},
|
||||
{x86.RBP, x86.R10, []byte{0x4C, 0x29, 0xD5}},
|
||||
{x86.RSI, x86.R9, []byte{0x4C, 0x29, 0xCE}},
|
||||
{x86.RDI, x86.R8, []byte{0x4C, 0x29, 0xC7}},
|
||||
{x86.R8, x86.RDI, []byte{0x49, 0x29, 0xF8}},
|
||||
{x86.R9, x86.RSI, []byte{0x49, 0x29, 0xF1}},
|
||||
{x86.R10, x86.RBP, []byte{0x49, 0x29, 0xEA}},
|
||||
{x86.R11, x86.RSP, []byte{0x49, 0x29, 0xE3}},
|
||||
{x86.R12, x86.RBX, []byte{0x49, 0x29, 0xDC}},
|
||||
{x86.R13, x86.RDX, []byte{0x49, 0x29, 0xD5}},
|
||||
{x86.R14, x86.RCX, []byte{0x49, 0x29, 0xCE}},
|
||||
{x86.R15, x86.RAX, []byte{0x49, 0x29, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("sub %s, %s", pattern.Left, pattern.Right)
|
||||
code := x86.SubRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
// Syscall is the primary way to communicate with the OS kernel.
|
||||
func Syscall(code []byte) []byte {
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
88
src/x86/Xor_test.go
Normal file
88
src/x86/Xor_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestXorRegisterNumber(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Register cpu.Register
|
||||
Number int
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, 1, []byte{0x48, 0x83, 0xF0, 0x01}},
|
||||
{x86.RCX, 1, []byte{0x48, 0x83, 0xF1, 0x01}},
|
||||
{x86.RDX, 1, []byte{0x48, 0x83, 0xF2, 0x01}},
|
||||
{x86.RBX, 1, []byte{0x48, 0x83, 0xF3, 0x01}},
|
||||
{x86.RSP, 1, []byte{0x48, 0x83, 0xF4, 0x01}},
|
||||
{x86.RBP, 1, []byte{0x48, 0x83, 0xF5, 0x01}},
|
||||
{x86.RSI, 1, []byte{0x48, 0x83, 0xF6, 0x01}},
|
||||
{x86.RDI, 1, []byte{0x48, 0x83, 0xF7, 0x01}},
|
||||
{x86.R8, 1, []byte{0x49, 0x83, 0xF0, 0x01}},
|
||||
{x86.R9, 1, []byte{0x49, 0x83, 0xF1, 0x01}},
|
||||
{x86.R10, 1, []byte{0x49, 0x83, 0xF2, 0x01}},
|
||||
{x86.R11, 1, []byte{0x49, 0x83, 0xF3, 0x01}},
|
||||
{x86.R12, 1, []byte{0x49, 0x83, 0xF4, 0x01}},
|
||||
{x86.R13, 1, []byte{0x49, 0x83, 0xF5, 0x01}},
|
||||
{x86.R14, 1, []byte{0x49, 0x83, 0xF6, 0x01}},
|
||||
{x86.R15, 1, []byte{0x49, 0x83, 0xF7, 0x01}},
|
||||
|
||||
{x86.RAX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RCX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBX, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RBP, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RSI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.RDI, 0x7FFFFFFF, []byte{0x48, 0x81, 0xF7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R8, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF0, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R9, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF1, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R10, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF2, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R11, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF3, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R12, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF4, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R13, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF5, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R14, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF6, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
{x86.R15, 0x7FFFFFFF, []byte{0x49, 0x81, 0xF7, 0xFF, 0xFF, 0xFF, 0x7F}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("xor %s, %x", pattern.Register, pattern.Number)
|
||||
code := x86.XorRegisterNumber(nil, pattern.Register, pattern.Number)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestXorRegisterRegister(t *testing.T) {
|
||||
usagePatterns := []struct {
|
||||
Left cpu.Register
|
||||
Right cpu.Register
|
||||
Code []byte
|
||||
}{
|
||||
{x86.RAX, x86.R15, []byte{0x4C, 0x31, 0xF8}},
|
||||
{x86.RCX, x86.R14, []byte{0x4C, 0x31, 0xF1}},
|
||||
{x86.RDX, x86.R13, []byte{0x4C, 0x31, 0xEA}},
|
||||
{x86.RBX, x86.R12, []byte{0x4C, 0x31, 0xE3}},
|
||||
{x86.RSP, x86.R11, []byte{0x4C, 0x31, 0xDC}},
|
||||
{x86.RBP, x86.R10, []byte{0x4C, 0x31, 0xD5}},
|
||||
{x86.RSI, x86.R9, []byte{0x4C, 0x31, 0xCE}},
|
||||
{x86.RDI, x86.R8, []byte{0x4C, 0x31, 0xC7}},
|
||||
{x86.R8, x86.RDI, []byte{0x49, 0x31, 0xF8}},
|
||||
{x86.R9, x86.RSI, []byte{0x49, 0x31, 0xF1}},
|
||||
{x86.R10, x86.RBP, []byte{0x49, 0x31, 0xEA}},
|
||||
{x86.R11, x86.RSP, []byte{0x49, 0x31, 0xE3}},
|
||||
{x86.R12, x86.RBX, []byte{0x49, 0x31, 0xDC}},
|
||||
{x86.R13, x86.RDX, []byte{0x49, 0x31, 0xD5}},
|
||||
{x86.R14, x86.RCX, []byte{0x49, 0x31, 0xCE}},
|
||||
{x86.R15, x86.RAX, []byte{0x49, 0x31, 0xC7}},
|
||||
}
|
||||
|
||||
for _, pattern := range usagePatterns {
|
||||
t.Logf("xor %s, %s", pattern.Left, pattern.Right)
|
||||
code := x86.XorRegisterRegister(nil, pattern.Left, pattern.Right)
|
||||
assert.DeepEqual(t, code, pattern.Code)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package x64
|
||||
package x86
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/cpu"
|
||||
|
19
src/x86/x64_test.go
Normal file
19
src/x86/x64_test.go
Normal file
@ -0,0 +1,19 @@
|
||||
package x86_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestX64(t *testing.T) {
|
||||
assert.DeepEqual(t, x86.AlignStack(nil), []byte{0x48, 0x83, 0xE4, 0xF0})
|
||||
assert.DeepEqual(t, x86.Call(nil, 1), []byte{0xE8, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x86.CallAtAddress(nil, 1), []byte{0xFF, 0x15, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x86.ExtendRAXToRDX(nil), []byte{0x48, 0x99})
|
||||
assert.DeepEqual(t, x86.MoveRegisterNumber(nil, 0, 1), []byte{0xB8, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x86.MoveRegisterNumber(nil, 1, 1), []byte{0xB9, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x86.Return(nil), []byte{0xC3})
|
||||
assert.DeepEqual(t, x86.Syscall(nil), []byte{0x0F, 0x05})
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user