Improved function names

This commit is contained in:
Eduard Urbach 2024-06-25 23:37:14 +02:00
parent e6462266ef
commit e69d695f6b
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
19 changed files with 94 additions and 114 deletions

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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).

View File

@ -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)
}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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)
}
}

View File

@ -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

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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))

View File

@ -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})
}

View File

@ -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:

View File

@ -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 {