diff --git a/src/arm/Registers.go b/src/arm/Registers.go index 6277134..9e54156 100644 --- a/src/arm/Registers.go +++ b/src/arm/Registers.go @@ -38,12 +38,13 @@ const ( ) const ( - ZR = SP // Zero register uses the same numerical value as SP - TMP = X28 // Temporary register for the assembler + ZR = SP // Zero register uses the same numerical value as SP + TMP = X27 // Temporary register for the assembler + TMP2 = X28 // Temporary register for the assembler ) var ( - GeneralRegisters = []cpu.Register{X9, X10, X11, X12, X13, X14, X15, X16, X17, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28} + GeneralRegisters = []cpu.Register{X9, X10, X11, X12, X13, X14, X15, X16, X17, X19, X20, X21, X22, X23, X24, X25, X26} InputRegisters = []cpu.Register{X0, X1, X2, X3, X4, X5} OutputRegisters = InputRegisters SyscallInputRegisters = []cpu.Register{X8, X0, X1, X2, X3, X4, X5} diff --git a/src/asmc/ARM.go b/src/asmc/ARM.go index a4d2347..42ff3a6 100644 --- a/src/asmc/ARM.go +++ b/src/asmc/ARM.go @@ -253,7 +253,9 @@ func (c *compiler) ARM(x asm.Instruction) { operand := c.assembler.Param.RegisterRegister[x.Index] c.append(arm.DivSigned(operand.Destination, operand.Destination, operand.Source)) case asm.TypeRegisterNumber: - panic("not implemented") + operand := c.assembler.Param.RegisterNumber[x.Index] + c.code = arm.MoveRegisterNumber(c.code, arm.TMP, operand.Number) + c.append(arm.DivSigned(operand.Register, operand.Register, arm.TMP)) } case asm.MUL: @@ -274,7 +276,10 @@ func (c *compiler) ARM(x asm.Instruction) { c.append(arm.DivSigned(arm.TMP, operand.Destination, operand.Source)) c.append(arm.MultiplySubtract(operand.Destination, arm.TMP, operand.Source, operand.Destination)) case asm.TypeRegisterNumber: - panic("not implemented") + operand := c.assembler.Param.RegisterNumber[x.Index] + c.code = arm.MoveRegisterNumber(c.code, arm.TMP, operand.Number) + c.append(arm.DivSigned(arm.TMP2, operand.Register, arm.TMP)) + c.append(arm.MultiplySubtract(operand.Register, arm.TMP2, arm.TMP, operand.Register)) } case asm.JE, asm.JNE, asm.JG, asm.JGE, asm.JL, asm.JLE, asm.JUMP: diff --git a/src/asmc/X86.go b/src/asmc/X86.go index 448ec41..5cdf60f 100644 --- a/src/asmc/X86.go +++ b/src/asmc/X86.go @@ -71,6 +71,20 @@ func (c *compiler) X86(x asm.Instruction) { case asm.DIV: switch x.Type { + case asm.TypeRegisterNumber: + operands := c.assembler.Param.RegisterNumber[x.Index] + + if operands.Register != x86.RAX { + c.code = x86.MoveRegisterRegister(c.code, x86.RAX, operands.Register) + } + + c.code = x86.MoveRegisterNumber(c.code, x86.TMP, operands.Number) + c.code = x86.ExtendRAXToRDX(c.code) + c.code = x86.DivRegister(c.code, x86.TMP) + + if operands.Register != x86.RAX { + c.code = x86.MoveRegisterRegister(c.code, operands.Register, x86.RAX) + } case asm.TypeRegisterRegister: operands := c.assembler.Param.RegisterRegister[x.Index] @@ -88,6 +102,20 @@ func (c *compiler) X86(x asm.Instruction) { case asm.MODULO: switch x.Type { + case asm.TypeRegisterNumber: + operands := c.assembler.Param.RegisterNumber[x.Index] + + if operands.Register != x86.RAX { + c.code = x86.MoveRegisterRegister(c.code, x86.RAX, operands.Register) + } + + c.code = x86.MoveRegisterNumber(c.code, x86.TMP, operands.Number) + c.code = x86.ExtendRAXToRDX(c.code) + c.code = x86.DivRegister(c.code, x86.TMP) + + if operands.Register != x86.RDX { + c.code = x86.MoveRegisterRegister(c.code, operands.Register, x86.RDX) + } case asm.TypeRegisterRegister: operands := c.assembler.Param.RegisterRegister[x.Index] diff --git a/src/core/ExecuteRegisterNumber.go b/src/core/ExecuteRegisterNumber.go index a3acbb5..bd79684 100644 --- a/src/core/ExecuteRegisterNumber.go +++ b/src/core/ExecuteRegisterNumber.go @@ -2,6 +2,7 @@ package core import ( "git.urbach.dev/cli/q/src/asm" + "git.urbach.dev/cli/q/src/config" "git.urbach.dev/cli/q/src/cpu" "git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/token" @@ -25,18 +26,18 @@ func (f *Function) ExecuteRegisterNumber(operation token.Token, register cpu.Reg f.RegisterNumber(asm.MUL, register, number) case token.Div, token.DivAssign: - f.SaveRegister(x86.RDX) - tmp := f.NewRegister() - f.RegisterNumber(asm.MOVE, tmp, number) - f.RegisterRegister(asm.DIV, register, tmp) - f.FreeRegister(tmp) + if config.TargetArch == config.X86 { + f.SaveRegister(x86.RDX) + } + + f.RegisterNumber(asm.DIV, register, number) case token.Mod, token.ModAssign: - f.SaveRegister(x86.RDX) - tmp := f.NewRegister() - f.RegisterNumber(asm.MOVE, tmp, number) - f.RegisterRegister(asm.MODULO, register, tmp) - f.FreeRegister(tmp) + if config.TargetArch == config.X86 { + f.SaveRegister(x86.RDX) + } + + f.RegisterNumber(asm.MODULO, register, number) case token.And, token.AndAssign: f.RegisterNumber(asm.AND, register, number) diff --git a/src/core/ExecuteRegisterRegister.go b/src/core/ExecuteRegisterRegister.go index 5b59667..bcb19de 100644 --- a/src/core/ExecuteRegisterRegister.go +++ b/src/core/ExecuteRegisterRegister.go @@ -2,6 +2,7 @@ package core import ( "git.urbach.dev/cli/q/src/asm" + "git.urbach.dev/cli/q/src/config" "git.urbach.dev/cli/q/src/cpu" "git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/token" @@ -25,11 +26,17 @@ func (f *Function) ExecuteRegisterRegister(operation token.Token, register cpu.R f.RegisterRegister(asm.MUL, register, operand) case token.Div, token.DivAssign: - f.SaveRegister(x86.RDX) + if config.TargetArch == config.X86 { + f.SaveRegister(x86.RDX) + } + f.RegisterRegister(asm.DIV, register, operand) case token.Mod, token.ModAssign: - f.SaveRegister(x86.RDX) + if config.TargetArch == config.X86 { + f.SaveRegister(x86.RDX) + } + f.RegisterRegister(asm.MODULO, register, operand) case token.And, token.AndAssign: diff --git a/src/x86/Registers.go b/src/x86/Registers.go index 793be1c..ab31583 100644 --- a/src/x86/Registers.go +++ b/src/x86/Registers.go @@ -19,12 +19,13 @@ const ( R13 R14 R15 + TMP = RCX ) var ( SyscallInputRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9} SyscallOutputRegisters = []cpu.Register{RAX, RCX, R11} - GeneralRegisters = []cpu.Register{RBX, R12, R13, R14, R15, RCX, R11} + GeneralRegisters = []cpu.Register{RBX, R12, R13, R14, R15, R11} InputRegisters = SyscallInputRegisters OutputRegisters = SyscallInputRegisters WindowsInputRegisters = []cpu.Register{RCX, RDX, R8, R9} diff --git a/tests/programs/variables.q b/tests/programs/variables.q index 554f438..b82b974 100644 --- a/tests/programs/variables.q +++ b/tests/programs/variables.q @@ -5,7 +5,6 @@ main() { d := 4 e := 5 f := 6 - g := 7 assert a == 1 assert b == 2 @@ -13,5 +12,4 @@ main() { assert d == 4 assert e == 5 assert f == 6 - assert g == 7 } \ No newline at end of file