Implemented division by immediates in the IR
This commit is contained in:
@ -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}
|
||||
|
@ -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:
|
||||
|
@ -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]
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
}
|
Reference in New Issue
Block a user