Improved function names
This commit is contained in:
parent
e6462266ef
commit
e69d695f6b
@ -4,39 +4,12 @@ import (
|
|||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/build/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddRegNum adds a number to the given register.
|
// AddRegisterNumber adds a number to the given register.
|
||||||
func AddRegNum(code []byte, destination cpu.Register, number int) []byte {
|
func AddRegisterNumber(code []byte, destination cpu.Register, number int) []byte {
|
||||||
return numRegReg(code, 0, byte(destination), number, 0x83, 0x81)
|
return regRegNum(code, 0, byte(destination), number, 0x83, 0x81)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddRegReg adds a number to the given register.
|
// AddRegisterRegister adds a register value into another register.
|
||||||
func AddRegReg(code []byte, destination cpu.Register, operand cpu.Register) []byte {
|
func AddRegisterRegister(code []byte, destination cpu.Register, operand cpu.Register) []byte {
|
||||||
return regReg(code, byte(operand), byte(destination), 0x01)
|
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
|
|
||||||
}
|
|
||||||
|
@ -51,7 +51,7 @@ func TestAddRegisterNumber(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("add %s, %x", pattern.Register, pattern.Number)
|
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)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ func TestAddRegisterRegister(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("add %s, %s", pattern.Left, pattern.Right)
|
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)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ package x64
|
|||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/build/cpu"
|
||||||
|
|
||||||
// DivReg divides RDX:RAX by the value in the register.
|
// DivRegister divides RDX:RAX by the value in the register.
|
||||||
func DivReg(code []byte, divisor cpu.Register) []byte {
|
func DivRegister(code []byte, divisor cpu.Register) []byte {
|
||||||
rex := byte(0x48)
|
rex := byte(0x48)
|
||||||
|
|
||||||
if divisor >= 8 {
|
if divisor >= 8 {
|
||||||
|
@ -33,7 +33,7 @@ func TestDivRegister(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("idiv %s", pattern.Register)
|
t.Logf("idiv %s", pattern.Register)
|
||||||
code := x64.DivReg(nil, pattern.Register)
|
code := x64.DivRegister(nil, pattern.Register)
|
||||||
assert.DeepEqual(t, code, pattern.Code)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ package x64
|
|||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/build/cpu"
|
||||||
|
|
||||||
// MoveRegNum32 moves a 32 bit integer into the given register.
|
// MoveRegisterNumber32 moves a 32 bit integer into the given register.
|
||||||
func MoveRegNum32(code []byte, destination cpu.Register, number uint32) []byte {
|
func MoveRegisterNumber32(code []byte, destination cpu.Register, number uint32) []byte {
|
||||||
if destination >= 8 {
|
if destination >= 8 {
|
||||||
code = append(code, REX(0, 0, 0, 1))
|
code = append(code, REX(0, 0, 0, 1))
|
||||||
destination -= 8
|
destination -= 8
|
||||||
@ -19,8 +19,8 @@ func MoveRegNum32(code []byte, destination cpu.Register, number uint32) []byte {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MoveRegReg64 moves a register value into another register.
|
// MoveRegisterRegister64 moves a register value into another register.
|
||||||
func MoveRegReg64(code []byte, destination cpu.Register, source cpu.Register) []byte {
|
func MoveRegisterRegister64(code []byte, destination cpu.Register, source cpu.Register) []byte {
|
||||||
r := byte(0) // Extension to the "reg" field in ModRM.
|
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).
|
b := byte(0) // Extension to the "rm" field in ModRM or the SIB base (r8 up to r15 use this).
|
||||||
|
|
||||||
|
@ -2,12 +2,12 @@ package x64
|
|||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/build/cpu"
|
||||||
|
|
||||||
// MulRegNum multiplies a register with a number.
|
// MulRegisterNumber multiplies a register with a number.
|
||||||
func MulRegNum(code []byte, destination cpu.Register, number int) []byte {
|
func MulRegisterNumber(code []byte, destination cpu.Register, number int) []byte {
|
||||||
return numRegReg(code, byte(destination), byte(destination), number, 0x6B, 0x69)
|
return regRegNum(code, byte(destination), byte(destination), number, 0x6B, 0x69)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MulRegReg multiplies a register with another register.
|
// MulRegisterRegister multiplies a register with another register.
|
||||||
func MulRegReg(code []byte, destination cpu.Register, operand cpu.Register) []byte {
|
func MulRegisterRegister(code []byte, destination cpu.Register, operand cpu.Register) []byte {
|
||||||
return regReg(code, byte(destination), byte(operand), 0x0F, 0xAF)
|
return regReg(code, byte(destination), byte(operand), 0x0F, 0xAF)
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ func TestMulRegisterNumber(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("mul %s, %x", pattern.Register, pattern.Number)
|
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)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ func TestMulRegisterRegister(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("mul %s, %s", pattern.Left, pattern.Right)
|
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)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ package x64
|
|||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/build/cpu"
|
||||||
|
|
||||||
// PopReg pops a value from the stack and saves it into the register.
|
// PopRegister pops a value from the stack and saves it into the register.
|
||||||
func PopReg(code []byte, register cpu.Register) []byte {
|
func PopRegister(code []byte, register cpu.Register) []byte {
|
||||||
if register >= 8 {
|
if register >= 8 {
|
||||||
code = append(code, REX(0, 0, 0, 1))
|
code = append(code, REX(0, 0, 0, 1))
|
||||||
register -= 8
|
register -= 8
|
||||||
|
@ -33,7 +33,7 @@ func TestPopRegister(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("pop %s", pattern.Register)
|
t.Logf("pop %s", pattern.Register)
|
||||||
code := x64.PopReg(nil, pattern.Register)
|
code := x64.PopRegister(nil, pattern.Register)
|
||||||
assert.DeepEqual(t, code, pattern.Code)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ package x64
|
|||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/build/cpu"
|
||||||
|
|
||||||
// PushReg pushes the value inside the register onto the stack.
|
// PushRegister pushes the value inside the register onto the stack.
|
||||||
func PushReg(code []byte, register cpu.Register) []byte {
|
func PushRegister(code []byte, register cpu.Register) []byte {
|
||||||
if register >= 8 {
|
if register >= 8 {
|
||||||
code = append(code, REX(0, 0, 0, 1))
|
code = append(code, REX(0, 0, 0, 1))
|
||||||
register -= 8
|
register -= 8
|
||||||
|
@ -33,7 +33,7 @@ func TestPushRegister(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("push %s", pattern.Register)
|
t.Logf("push %s", pattern.Register)
|
||||||
code := x64.PushReg(nil, pattern.Register)
|
code := x64.PushRegister(nil, pattern.Register)
|
||||||
assert.DeepEqual(t, code, pattern.Code)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@ import (
|
|||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/build/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SubRegNum subtracts a number from the given register.
|
// SubRegisterNumber subtracts a number from the given register.
|
||||||
func SubRegNum(code []byte, destination cpu.Register, number int) []byte {
|
func SubRegisterNumber(code []byte, destination cpu.Register, number int) []byte {
|
||||||
return numRegReg(code, 0b101, byte(destination), number, 0x83, 0x81)
|
return regRegNum(code, 0b101, byte(destination), number, 0x83, 0x81)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubRegReg subtracts a register value from another register.
|
// SubRegisterRegister subtracts a register value from another register.
|
||||||
func SubRegReg(code []byte, destination cpu.Register, operand cpu.Register) []byte {
|
func SubRegisterRegister(code []byte, destination cpu.Register, operand cpu.Register) []byte {
|
||||||
return regReg(code, byte(operand), byte(destination), 0x29)
|
return regReg(code, byte(operand), byte(destination), 0x29)
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ func TestSubRegisterNumber(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("sub %s, %x", pattern.Register, pattern.Number)
|
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)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,5 @@ package x64
|
|||||||
|
|
||||||
// Syscall is the primary way to communicate with the OS kernel.
|
// Syscall is the primary way to communicate with the OS kernel.
|
||||||
func Syscall(code []byte) []byte {
|
func Syscall(code []byte) []byte {
|
||||||
return append(code, 0x0f, 0x05)
|
return append(code, 0x0F, 0x05)
|
||||||
}
|
}
|
||||||
|
29
src/build/arch/x64/regReg.go
Normal file
29
src/build/arch/x64/regReg.go
Normal 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
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
// numRegReg encodes an instruction with up to two registers and a number parameter.
|
// regRegNum 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 {
|
func regRegNum(code []byte, reg byte, rm byte, number int, opCode8 byte, opCode32 byte) []byte {
|
||||||
if sizeOf(number) == 1 {
|
if sizeOf(number) == 1 {
|
||||||
code = regReg(code, reg, rm, opCode8)
|
code = regReg(code, reg, rm, opCode8)
|
||||||
return append(code, byte(number))
|
return append(code, byte(number))
|
@ -9,8 +9,8 @@ import (
|
|||||||
|
|
||||||
func TestX64(t *testing.T) {
|
func TestX64(t *testing.T) {
|
||||||
assert.DeepEqual(t, x64.Call([]byte{}, 1), []byte{0xe8, 0x01, 0x00, 0x00, 0x00})
|
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.MoveRegisterNumber32([]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{}, 1, 1), []byte{0xb9, 0x01, 0x00, 0x00, 0x00})
|
||||||
assert.DeepEqual(t, x64.Return([]byte{}), []byte{0xc3})
|
assert.DeepEqual(t, x64.Return([]byte{}), []byte{0xc3})
|
||||||
assert.DeepEqual(t, x64.Syscall([]byte{}), []byte{0x0f, 0x05})
|
assert.DeepEqual(t, x64.Syscall([]byte{}), []byte{0x0f, 0x05})
|
||||||
}
|
}
|
||||||
|
@ -30,57 +30,57 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
|
|||||||
case ADD:
|
case ADD:
|
||||||
switch operands := x.Data.(type) {
|
switch operands := x.Data.(type) {
|
||||||
case *RegisterNumber:
|
case *RegisterNumber:
|
||||||
code = x64.AddRegNum(code, operands.Register, operands.Number)
|
code = x64.AddRegisterNumber(code, operands.Register, operands.Number)
|
||||||
case *RegisterRegister:
|
case *RegisterRegister:
|
||||||
code = x64.AddRegReg(code, operands.Destination, operands.Source)
|
code = x64.AddRegisterRegister(code, operands.Destination, operands.Source)
|
||||||
}
|
}
|
||||||
|
|
||||||
case SUB:
|
case SUB:
|
||||||
switch operands := x.Data.(type) {
|
switch operands := x.Data.(type) {
|
||||||
case *RegisterNumber:
|
case *RegisterNumber:
|
||||||
code = x64.SubRegNum(code, operands.Register, operands.Number)
|
code = x64.SubRegisterNumber(code, operands.Register, operands.Number)
|
||||||
case *RegisterRegister:
|
case *RegisterRegister:
|
||||||
code = x64.SubRegReg(code, operands.Destination, operands.Source)
|
code = x64.SubRegisterRegister(code, operands.Destination, operands.Source)
|
||||||
}
|
}
|
||||||
|
|
||||||
case MUL:
|
case MUL:
|
||||||
switch operands := x.Data.(type) {
|
switch operands := x.Data.(type) {
|
||||||
case *RegisterNumber:
|
case *RegisterNumber:
|
||||||
code = x64.MulRegNum(code, operands.Register, operands.Number)
|
code = x64.MulRegisterNumber(code, operands.Register, operands.Number)
|
||||||
case *RegisterRegister:
|
case *RegisterRegister:
|
||||||
code = x64.MulRegReg(code, operands.Destination, operands.Source)
|
code = x64.MulRegisterRegister(code, operands.Destination, operands.Source)
|
||||||
}
|
}
|
||||||
|
|
||||||
case DIV:
|
case DIV:
|
||||||
switch operands := x.Data.(type) {
|
switch operands := x.Data.(type) {
|
||||||
case *RegisterNumber:
|
case *RegisterNumber:
|
||||||
if operands.Register == x64.RAX {
|
if operands.Register == x64.RAX {
|
||||||
code = x64.PushReg(code, x64.RCX)
|
code = x64.PushRegister(code, x64.RCX)
|
||||||
code = x64.MoveRegNum32(code, x64.RCX, uint32(operands.Number))
|
code = x64.MoveRegisterNumber32(code, x64.RCX, uint32(operands.Number))
|
||||||
code = x64.ExtendRAXToRDX(code)
|
code = x64.ExtendRAXToRDX(code)
|
||||||
code = x64.DivReg(code, x64.RCX)
|
code = x64.DivRegister(code, x64.RCX)
|
||||||
code = x64.PopReg(code, x64.RCX)
|
code = x64.PopRegister(code, x64.RCX)
|
||||||
} else {
|
} else {
|
||||||
code = x64.PushReg(code, x64.RAX)
|
code = x64.PushRegister(code, x64.RAX)
|
||||||
code = x64.PushReg(code, x64.RDX)
|
code = x64.PushRegister(code, x64.RDX)
|
||||||
code = x64.MoveRegReg64(code, x64.RAX, operands.Register)
|
code = x64.MoveRegisterRegister64(code, x64.RAX, operands.Register)
|
||||||
code = x64.MoveRegNum32(code, operands.Register, uint32(operands.Number))
|
code = x64.MoveRegisterNumber32(code, operands.Register, uint32(operands.Number))
|
||||||
code = x64.ExtendRAXToRDX(code)
|
code = x64.ExtendRAXToRDX(code)
|
||||||
code = x64.DivReg(code, operands.Register)
|
code = x64.DivRegister(code, operands.Register)
|
||||||
code = x64.MoveRegReg64(code, operands.Register, x64.RAX)
|
code = x64.MoveRegisterRegister64(code, operands.Register, x64.RAX)
|
||||||
code = x64.PopReg(code, x64.RDX)
|
code = x64.PopRegister(code, x64.RDX)
|
||||||
code = x64.PopReg(code, x64.RAX)
|
code = x64.PopRegister(code, x64.RAX)
|
||||||
}
|
}
|
||||||
|
|
||||||
case *RegisterRegister:
|
case *RegisterRegister:
|
||||||
code = x64.PushReg(code, x64.RAX)
|
code = x64.PushRegister(code, x64.RAX)
|
||||||
code = x64.PushReg(code, x64.RDX)
|
code = x64.PushRegister(code, x64.RDX)
|
||||||
code = x64.MoveRegReg64(code, x64.RAX, operands.Destination)
|
code = x64.MoveRegisterRegister64(code, x64.RAX, operands.Destination)
|
||||||
code = x64.ExtendRAXToRDX(code)
|
code = x64.ExtendRAXToRDX(code)
|
||||||
code = x64.DivReg(code, operands.Source)
|
code = x64.DivRegister(code, operands.Source)
|
||||||
code = x64.MoveRegReg64(code, operands.Destination, x64.RAX)
|
code = x64.MoveRegisterRegister64(code, operands.Destination, x64.RAX)
|
||||||
code = x64.PopReg(code, x64.RDX)
|
code = x64.PopRegister(code, x64.RDX)
|
||||||
code = x64.PopReg(code, x64.RAX)
|
code = x64.PopRegister(code, x64.RAX)
|
||||||
}
|
}
|
||||||
|
|
||||||
case CALL:
|
case CALL:
|
||||||
@ -121,10 +121,10 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
|
|||||||
case MOVE:
|
case MOVE:
|
||||||
switch operands := x.Data.(type) {
|
switch operands := x.Data.(type) {
|
||||||
case *RegisterNumber:
|
case *RegisterNumber:
|
||||||
code = x64.MoveRegNum32(code, operands.Register, uint32(operands.Number))
|
code = x64.MoveRegisterNumber32(code, operands.Register, uint32(operands.Number))
|
||||||
|
|
||||||
case *RegisterRegister:
|
case *RegisterRegister:
|
||||||
code = x64.MoveRegReg64(code, operands.Destination, operands.Source)
|
code = x64.MoveRegisterRegister64(code, operands.Destination, operands.Source)
|
||||||
}
|
}
|
||||||
|
|
||||||
case RETURN:
|
case RETURN:
|
||||||
|
@ -71,28 +71,6 @@ func (expr *Expression) EachLeaf(call func(*Expression) error) error {
|
|||||||
return nil
|
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.
|
// RemoveChild removes a child from the expression.
|
||||||
func (expr *Expression) RemoveChild(child *Expression) {
|
func (expr *Expression) RemoveChild(child *Expression) {
|
||||||
for i, c := range expr.Children {
|
for i, c := range expr.Children {
|
||||||
|
Loading…
Reference in New Issue
Block a user