Implemented division by immediates in the IR

This commit is contained in:
2025-03-31 15:51:04 +02:00
parent 008f097186
commit 9302eaef2f
7 changed files with 61 additions and 20 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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