From e69d695f6bf94d23544821b77f0bfec17e78ec50 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Tue, 25 Jun 2024 23:37:14 +0200 Subject: [PATCH] Improved function names --- src/build/arch/x64/Add.go | 37 ++----------- src/build/arch/x64/Add_test.go | 4 +- src/build/arch/x64/Div.go | 4 +- src/build/arch/x64/Div_test.go | 2 +- src/build/arch/x64/Move.go | 8 +-- src/build/arch/x64/Mul.go | 10 ++-- src/build/arch/x64/Mul_test.go | 4 +- src/build/arch/x64/Pop.go | 4 +- src/build/arch/x64/Pop_test.go | 2 +- src/build/arch/x64/Push.go | 4 +- src/build/arch/x64/Push_test.go | 2 +- src/build/arch/x64/Sub.go | 10 ++-- src/build/arch/x64/Sub_test.go | 2 +- src/build/arch/x64/Syscall.go | 2 +- src/build/arch/x64/regReg.go | 29 ++++++++++ .../arch/x64/{numRegReg.go => regRegNum.go} | 4 +- src/build/arch/x64/x64_test.go | 4 +- src/build/asm/Assembler.go | 54 +++++++++---------- src/build/expression/Expression.go | 22 -------- 19 files changed, 94 insertions(+), 114 deletions(-) create mode 100644 src/build/arch/x64/regReg.go rename src/build/arch/x64/{numRegReg.go => regRegNum.go} (71%) diff --git a/src/build/arch/x64/Add.go b/src/build/arch/x64/Add.go index 5e28c0b..b92cc60 100644 --- a/src/build/arch/x64/Add.go +++ b/src/build/arch/x64/Add.go @@ -4,39 +4,12 @@ import ( "git.akyoto.dev/cli/q/src/build/cpu" ) -// AddRegNum adds a number to the given register. -func AddRegNum(code []byte, destination cpu.Register, number int) []byte { - return numRegReg(code, 0, byte(destination), number, 0x83, 0x81) +// AddRegisterNumber adds a number to the given register. +func AddRegisterNumber(code []byte, destination cpu.Register, number int) []byte { + return regRegNum(code, 0, byte(destination), number, 0x83, 0x81) } -// AddRegReg adds a number to the given register. -func AddRegReg(code []byte, destination cpu.Register, operand cpu.Register) []byte { +// AddRegisterRegister adds a register value into another register. +func AddRegisterRegister(code []byte, destination cpu.Register, operand cpu.Register) []byte { return regReg(code, byte(operand), byte(destination), 0x01) } - -func regReg(code []byte, reg byte, rm byte, opCodes ...byte) []byte { - w := byte(1) // Indicates a 64-bit register. - r := byte(0) // Extension to the "reg" field in ModRM. - x := byte(0) // Extension to the SIB index field. - b := byte(0) // Extension to the "rm" field in ModRM or the SIB base (r8 up to r15 use this). - mod := byte(0b11) // Direct addressing mode, no register offsets. - - if reg > 0b111 { - r = 1 - reg &= 0b111 - } - - if rm > 0b111 { - b = 1 - rm &= 0b111 - } - - rex := REX(w, r, x, b) - modRM := ModRM(mod, reg, rm) - - code = append(code, rex) - code = append(code, opCodes...) - code = append(code, modRM) - - return code -} diff --git a/src/build/arch/x64/Add_test.go b/src/build/arch/x64/Add_test.go index ca21dc7..607b467 100644 --- a/src/build/arch/x64/Add_test.go +++ b/src/build/arch/x64/Add_test.go @@ -51,7 +51,7 @@ func TestAddRegisterNumber(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("add %s, %x", pattern.Register, pattern.Number) - code := x64.AddRegNum(nil, pattern.Register, pattern.Number) + code := x64.AddRegisterNumber(nil, pattern.Register, pattern.Number) assert.DeepEqual(t, code, pattern.Code) } } @@ -82,7 +82,7 @@ func TestAddRegisterRegister(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("add %s, %s", pattern.Left, pattern.Right) - code := x64.AddRegReg(nil, pattern.Left, pattern.Right) + code := x64.AddRegisterRegister(nil, pattern.Left, pattern.Right) assert.DeepEqual(t, code, pattern.Code) } } diff --git a/src/build/arch/x64/Div.go b/src/build/arch/x64/Div.go index 0ed4a56..5c567bd 100644 --- a/src/build/arch/x64/Div.go +++ b/src/build/arch/x64/Div.go @@ -2,8 +2,8 @@ package x64 import "git.akyoto.dev/cli/q/src/build/cpu" -// DivReg divides RDX:RAX by the value in the register. -func DivReg(code []byte, divisor cpu.Register) []byte { +// DivRegister divides RDX:RAX by the value in the register. +func DivRegister(code []byte, divisor cpu.Register) []byte { rex := byte(0x48) if divisor >= 8 { diff --git a/src/build/arch/x64/Div_test.go b/src/build/arch/x64/Div_test.go index 04ed063..267250e 100644 --- a/src/build/arch/x64/Div_test.go +++ b/src/build/arch/x64/Div_test.go @@ -33,7 +33,7 @@ func TestDivRegister(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("idiv %s", pattern.Register) - code := x64.DivReg(nil, pattern.Register) + code := x64.DivRegister(nil, pattern.Register) assert.DeepEqual(t, code, pattern.Code) } } diff --git a/src/build/arch/x64/Move.go b/src/build/arch/x64/Move.go index 63ffaf0..9f57728 100644 --- a/src/build/arch/x64/Move.go +++ b/src/build/arch/x64/Move.go @@ -2,8 +2,8 @@ package x64 import "git.akyoto.dev/cli/q/src/build/cpu" -// MoveRegNum32 moves a 32 bit integer into the given register. -func MoveRegNum32(code []byte, destination cpu.Register, number uint32) []byte { +// MoveRegisterNumber32 moves a 32 bit integer into the given register. +func MoveRegisterNumber32(code []byte, destination cpu.Register, number uint32) []byte { if destination >= 8 { code = append(code, REX(0, 0, 0, 1)) destination -= 8 @@ -19,8 +19,8 @@ func MoveRegNum32(code []byte, destination cpu.Register, number uint32) []byte { ) } -// MoveRegReg64 moves a register value into another register. -func MoveRegReg64(code []byte, destination cpu.Register, source cpu.Register) []byte { +// MoveRegisterRegister64 moves a register value into another register. +func MoveRegisterRegister64(code []byte, destination cpu.Register, source cpu.Register) []byte { r := byte(0) // Extension to the "reg" field in ModRM. b := byte(0) // Extension to the "rm" field in ModRM or the SIB base (r8 up to r15 use this). diff --git a/src/build/arch/x64/Mul.go b/src/build/arch/x64/Mul.go index 45254b2..a041799 100644 --- a/src/build/arch/x64/Mul.go +++ b/src/build/arch/x64/Mul.go @@ -2,12 +2,12 @@ package x64 import "git.akyoto.dev/cli/q/src/build/cpu" -// MulRegNum multiplies a register with a number. -func MulRegNum(code []byte, destination cpu.Register, number int) []byte { - return numRegReg(code, byte(destination), byte(destination), number, 0x6B, 0x69) +// MulRegisterNumber multiplies a register with a number. +func MulRegisterNumber(code []byte, destination cpu.Register, number int) []byte { + return regRegNum(code, byte(destination), byte(destination), number, 0x6B, 0x69) } -// MulRegReg multiplies a register with another register. -func MulRegReg(code []byte, destination cpu.Register, operand cpu.Register) []byte { +// MulRegisterRegister multiplies a register with another register. +func MulRegisterRegister(code []byte, destination cpu.Register, operand cpu.Register) []byte { return regReg(code, byte(destination), byte(operand), 0x0F, 0xAF) } diff --git a/src/build/arch/x64/Mul_test.go b/src/build/arch/x64/Mul_test.go index ffea393..5c029dd 100644 --- a/src/build/arch/x64/Mul_test.go +++ b/src/build/arch/x64/Mul_test.go @@ -51,7 +51,7 @@ func TestMulRegisterNumber(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("mul %s, %x", pattern.Register, pattern.Number) - code := x64.MulRegNum(nil, pattern.Register, pattern.Number) + code := x64.MulRegisterNumber(nil, pattern.Register, pattern.Number) assert.DeepEqual(t, code, pattern.Code) } } @@ -82,7 +82,7 @@ func TestMulRegisterRegister(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("mul %s, %s", pattern.Left, pattern.Right) - code := x64.MulRegReg(nil, pattern.Left, pattern.Right) + code := x64.MulRegisterRegister(nil, pattern.Left, pattern.Right) assert.DeepEqual(t, code, pattern.Code) } } diff --git a/src/build/arch/x64/Pop.go b/src/build/arch/x64/Pop.go index 746f3a0..4ce82ec 100644 --- a/src/build/arch/x64/Pop.go +++ b/src/build/arch/x64/Pop.go @@ -2,8 +2,8 @@ package x64 import "git.akyoto.dev/cli/q/src/build/cpu" -// PopReg pops a value from the stack and saves it into the register. -func PopReg(code []byte, register cpu.Register) []byte { +// PopRegister pops a value from the stack and saves it into the register. +func PopRegister(code []byte, register cpu.Register) []byte { if register >= 8 { code = append(code, REX(0, 0, 0, 1)) register -= 8 diff --git a/src/build/arch/x64/Pop_test.go b/src/build/arch/x64/Pop_test.go index 64acf13..5375bde 100644 --- a/src/build/arch/x64/Pop_test.go +++ b/src/build/arch/x64/Pop_test.go @@ -33,7 +33,7 @@ func TestPopRegister(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("pop %s", pattern.Register) - code := x64.PopReg(nil, pattern.Register) + code := x64.PopRegister(nil, pattern.Register) assert.DeepEqual(t, code, pattern.Code) } } diff --git a/src/build/arch/x64/Push.go b/src/build/arch/x64/Push.go index 48bed9d..944d1e4 100644 --- a/src/build/arch/x64/Push.go +++ b/src/build/arch/x64/Push.go @@ -2,8 +2,8 @@ package x64 import "git.akyoto.dev/cli/q/src/build/cpu" -// PushReg pushes the value inside the register onto the stack. -func PushReg(code []byte, register cpu.Register) []byte { +// PushRegister pushes the value inside the register onto the stack. +func PushRegister(code []byte, register cpu.Register) []byte { if register >= 8 { code = append(code, REX(0, 0, 0, 1)) register -= 8 diff --git a/src/build/arch/x64/Push_test.go b/src/build/arch/x64/Push_test.go index 22994bb..9177532 100644 --- a/src/build/arch/x64/Push_test.go +++ b/src/build/arch/x64/Push_test.go @@ -33,7 +33,7 @@ func TestPushRegister(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("push %s", pattern.Register) - code := x64.PushReg(nil, pattern.Register) + code := x64.PushRegister(nil, pattern.Register) assert.DeepEqual(t, code, pattern.Code) } } diff --git a/src/build/arch/x64/Sub.go b/src/build/arch/x64/Sub.go index 60fc81d..4dd9b23 100644 --- a/src/build/arch/x64/Sub.go +++ b/src/build/arch/x64/Sub.go @@ -4,12 +4,12 @@ import ( "git.akyoto.dev/cli/q/src/build/cpu" ) -// SubRegNum subtracts a number from the given register. -func SubRegNum(code []byte, destination cpu.Register, number int) []byte { - return numRegReg(code, 0b101, byte(destination), number, 0x83, 0x81) +// SubRegisterNumber subtracts a number from the given register. +func SubRegisterNumber(code []byte, destination cpu.Register, number int) []byte { + return regRegNum(code, 0b101, byte(destination), number, 0x83, 0x81) } -// SubRegReg subtracts a register value from another register. -func SubRegReg(code []byte, destination cpu.Register, operand cpu.Register) []byte { +// SubRegisterRegister subtracts a register value from another register. +func SubRegisterRegister(code []byte, destination cpu.Register, operand cpu.Register) []byte { return regReg(code, byte(operand), byte(destination), 0x29) } diff --git a/src/build/arch/x64/Sub_test.go b/src/build/arch/x64/Sub_test.go index 5dcf691..2380098 100644 --- a/src/build/arch/x64/Sub_test.go +++ b/src/build/arch/x64/Sub_test.go @@ -51,7 +51,7 @@ func TestSubRegisterNumber(t *testing.T) { for _, pattern := range usagePatterns { t.Logf("sub %s, %x", pattern.Register, pattern.Number) - code := x64.SubRegNum(nil, pattern.Register, pattern.Number) + code := x64.SubRegisterNumber(nil, pattern.Register, pattern.Number) assert.DeepEqual(t, code, pattern.Code) } } diff --git a/src/build/arch/x64/Syscall.go b/src/build/arch/x64/Syscall.go index 94b07d2..31e2b96 100644 --- a/src/build/arch/x64/Syscall.go +++ b/src/build/arch/x64/Syscall.go @@ -2,5 +2,5 @@ package x64 // Syscall is the primary way to communicate with the OS kernel. func Syscall(code []byte) []byte { - return append(code, 0x0f, 0x05) + return append(code, 0x0F, 0x05) } diff --git a/src/build/arch/x64/regReg.go b/src/build/arch/x64/regReg.go new file mode 100644 index 0000000..57b0f00 --- /dev/null +++ b/src/build/arch/x64/regReg.go @@ -0,0 +1,29 @@ +package x64 + +// regReg encodes an operation using 2 registers. +func regReg(code []byte, reg byte, rm byte, opCodes ...byte) []byte { + w := byte(1) // Indicates a 64-bit register. + r := byte(0) // Extension to the "reg" field in ModRM. + x := byte(0) // Extension to the SIB index field. + b := byte(0) // Extension to the "rm" field in ModRM or the SIB base (r8 up to r15 use this). + mod := byte(0b11) // Direct addressing mode, no register offsets. + + if reg > 0b111 { + r = 1 + reg &= 0b111 + } + + if rm > 0b111 { + b = 1 + rm &= 0b111 + } + + rex := REX(w, r, x, b) + modRM := ModRM(mod, reg, rm) + + code = append(code, rex) + code = append(code, opCodes...) + code = append(code, modRM) + + return code +} diff --git a/src/build/arch/x64/numRegReg.go b/src/build/arch/x64/regRegNum.go similarity index 71% rename from src/build/arch/x64/numRegReg.go rename to src/build/arch/x64/regRegNum.go index bb7fa96..8a04be4 100644 --- a/src/build/arch/x64/numRegReg.go +++ b/src/build/arch/x64/regRegNum.go @@ -1,7 +1,7 @@ package x64 -// numRegReg encodes an instruction with up to two registers and a number parameter. -func numRegReg(code []byte, reg byte, rm byte, number int, opCode8 byte, opCode32 byte) []byte { +// regRegNum encodes an instruction with up to two registers and a number parameter. +func regRegNum(code []byte, reg byte, rm byte, number int, opCode8 byte, opCode32 byte) []byte { if sizeOf(number) == 1 { code = regReg(code, reg, rm, opCode8) return append(code, byte(number)) diff --git a/src/build/arch/x64/x64_test.go b/src/build/arch/x64/x64_test.go index b39570d..8369738 100644 --- a/src/build/arch/x64/x64_test.go +++ b/src/build/arch/x64/x64_test.go @@ -9,8 +9,8 @@ import ( func TestX64(t *testing.T) { assert.DeepEqual(t, x64.Call([]byte{}, 1), []byte{0xe8, 0x01, 0x00, 0x00, 0x00}) - assert.DeepEqual(t, x64.MoveRegNum32([]byte{}, 0, 1), []byte{0xb8, 0x01, 0x00, 0x00, 0x00}) - assert.DeepEqual(t, x64.MoveRegNum32([]byte{}, 1, 1), []byte{0xb9, 0x01, 0x00, 0x00, 0x00}) + assert.DeepEqual(t, x64.MoveRegisterNumber32([]byte{}, 0, 1), []byte{0xb8, 0x01, 0x00, 0x00, 0x00}) + assert.DeepEqual(t, x64.MoveRegisterNumber32([]byte{}, 1, 1), []byte{0xb9, 0x01, 0x00, 0x00, 0x00}) assert.DeepEqual(t, x64.Return([]byte{}), []byte{0xc3}) assert.DeepEqual(t, x64.Syscall([]byte{}), []byte{0x0f, 0x05}) } diff --git a/src/build/asm/Assembler.go b/src/build/asm/Assembler.go index f3529ec..e2e1483 100644 --- a/src/build/asm/Assembler.go +++ b/src/build/asm/Assembler.go @@ -30,57 +30,57 @@ func (a *Assembler) Finalize() ([]byte, []byte) { case ADD: switch operands := x.Data.(type) { case *RegisterNumber: - code = x64.AddRegNum(code, operands.Register, operands.Number) + code = x64.AddRegisterNumber(code, operands.Register, operands.Number) case *RegisterRegister: - code = x64.AddRegReg(code, operands.Destination, operands.Source) + code = x64.AddRegisterRegister(code, operands.Destination, operands.Source) } case SUB: switch operands := x.Data.(type) { case *RegisterNumber: - code = x64.SubRegNum(code, operands.Register, operands.Number) + code = x64.SubRegisterNumber(code, operands.Register, operands.Number) case *RegisterRegister: - code = x64.SubRegReg(code, operands.Destination, operands.Source) + code = x64.SubRegisterRegister(code, operands.Destination, operands.Source) } case MUL: switch operands := x.Data.(type) { case *RegisterNumber: - code = x64.MulRegNum(code, operands.Register, operands.Number) + code = x64.MulRegisterNumber(code, operands.Register, operands.Number) case *RegisterRegister: - code = x64.MulRegReg(code, operands.Destination, operands.Source) + code = x64.MulRegisterRegister(code, operands.Destination, operands.Source) } case DIV: switch operands := x.Data.(type) { case *RegisterNumber: if operands.Register == x64.RAX { - code = x64.PushReg(code, x64.RCX) - code = x64.MoveRegNum32(code, x64.RCX, uint32(operands.Number)) + code = x64.PushRegister(code, x64.RCX) + code = x64.MoveRegisterNumber32(code, x64.RCX, uint32(operands.Number)) code = x64.ExtendRAXToRDX(code) - code = x64.DivReg(code, x64.RCX) - code = x64.PopReg(code, x64.RCX) + code = x64.DivRegister(code, x64.RCX) + code = x64.PopRegister(code, x64.RCX) } else { - code = x64.PushReg(code, x64.RAX) - code = x64.PushReg(code, x64.RDX) - code = x64.MoveRegReg64(code, x64.RAX, operands.Register) - code = x64.MoveRegNum32(code, operands.Register, uint32(operands.Number)) + code = x64.PushRegister(code, x64.RAX) + code = x64.PushRegister(code, x64.RDX) + code = x64.MoveRegisterRegister64(code, x64.RAX, operands.Register) + code = x64.MoveRegisterNumber32(code, operands.Register, uint32(operands.Number)) code = x64.ExtendRAXToRDX(code) - code = x64.DivReg(code, operands.Register) - code = x64.MoveRegReg64(code, operands.Register, x64.RAX) - code = x64.PopReg(code, x64.RDX) - code = x64.PopReg(code, x64.RAX) + code = x64.DivRegister(code, operands.Register) + code = x64.MoveRegisterRegister64(code, operands.Register, x64.RAX) + code = x64.PopRegister(code, x64.RDX) + code = x64.PopRegister(code, x64.RAX) } case *RegisterRegister: - code = x64.PushReg(code, x64.RAX) - code = x64.PushReg(code, x64.RDX) - code = x64.MoveRegReg64(code, x64.RAX, operands.Destination) + code = x64.PushRegister(code, x64.RAX) + code = x64.PushRegister(code, x64.RDX) + code = x64.MoveRegisterRegister64(code, x64.RAX, operands.Destination) code = x64.ExtendRAXToRDX(code) - code = x64.DivReg(code, operands.Source) - code = x64.MoveRegReg64(code, operands.Destination, x64.RAX) - code = x64.PopReg(code, x64.RDX) - code = x64.PopReg(code, x64.RAX) + code = x64.DivRegister(code, operands.Source) + code = x64.MoveRegisterRegister64(code, operands.Destination, x64.RAX) + code = x64.PopRegister(code, x64.RDX) + code = x64.PopRegister(code, x64.RAX) } case CALL: @@ -121,10 +121,10 @@ func (a *Assembler) Finalize() ([]byte, []byte) { case MOVE: switch operands := x.Data.(type) { case *RegisterNumber: - code = x64.MoveRegNum32(code, operands.Register, uint32(operands.Number)) + code = x64.MoveRegisterNumber32(code, operands.Register, uint32(operands.Number)) case *RegisterRegister: - code = x64.MoveRegReg64(code, operands.Destination, operands.Source) + code = x64.MoveRegisterRegister64(code, operands.Destination, operands.Source) } case RETURN: diff --git a/src/build/expression/Expression.go b/src/build/expression/Expression.go index dc5a206..84b9249 100644 --- a/src/build/expression/Expression.go +++ b/src/build/expression/Expression.go @@ -71,28 +71,6 @@ func (expr *Expression) EachLeaf(call func(*Expression) error) error { return nil } -// EachOperation iterates through all the operations in the tree. -func (expr *Expression) EachOperation(call func(*Expression) error) error { - if expr.IsLeaf() { - return nil - } - - // Don't descend into the parameters of function calls - if expr.Token.Text() == "λ" { - return call(expr) - } - - for _, child := range expr.Children { - err := child.EachOperation(call) - - if err != nil { - return err - } - } - - return call(expr) -} - // RemoveChild removes a child from the expression. func (expr *Expression) RemoveChild(child *Expression) { for i, c := range expr.Children {