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

@ -39,11 +39,12 @@ const (
const ( const (
ZR = SP // Zero register uses the same numerical value as SP ZR = SP // Zero register uses the same numerical value as SP
TMP = X28 // Temporary register for the assembler TMP = X27 // Temporary register for the assembler
TMP2 = X28 // Temporary register for the assembler
) )
var ( 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} InputRegisters = []cpu.Register{X0, X1, X2, X3, X4, X5}
OutputRegisters = InputRegisters OutputRegisters = InputRegisters
SyscallInputRegisters = []cpu.Register{X8, X0, X1, X2, X3, X4, X5} 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] operand := c.assembler.Param.RegisterRegister[x.Index]
c.append(arm.DivSigned(operand.Destination, operand.Destination, operand.Source)) c.append(arm.DivSigned(operand.Destination, operand.Destination, operand.Source))
case asm.TypeRegisterNumber: 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: 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.DivSigned(arm.TMP, operand.Destination, operand.Source))
c.append(arm.MultiplySubtract(operand.Destination, arm.TMP, operand.Source, operand.Destination)) c.append(arm.MultiplySubtract(operand.Destination, arm.TMP, operand.Source, operand.Destination))
case asm.TypeRegisterNumber: 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: 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: case asm.DIV:
switch x.Type { 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: case asm.TypeRegisterRegister:
operands := c.assembler.Param.RegisterRegister[x.Index] operands := c.assembler.Param.RegisterRegister[x.Index]
@ -88,6 +102,20 @@ func (c *compiler) X86(x asm.Instruction) {
case asm.MODULO: case asm.MODULO:
switch x.Type { 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: case asm.TypeRegisterRegister:
operands := c.assembler.Param.RegisterRegister[x.Index] operands := c.assembler.Param.RegisterRegister[x.Index]

View File

@ -2,6 +2,7 @@ package core
import ( import (
"git.urbach.dev/cli/q/src/asm" "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/cpu"
"git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/errors"
"git.urbach.dev/cli/q/src/token" "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) f.RegisterNumber(asm.MUL, register, number)
case token.Div, token.DivAssign: case token.Div, token.DivAssign:
if config.TargetArch == config.X86 {
f.SaveRegister(x86.RDX) f.SaveRegister(x86.RDX)
tmp := f.NewRegister() }
f.RegisterNumber(asm.MOVE, tmp, number)
f.RegisterRegister(asm.DIV, register, tmp) f.RegisterNumber(asm.DIV, register, number)
f.FreeRegister(tmp)
case token.Mod, token.ModAssign: case token.Mod, token.ModAssign:
if config.TargetArch == config.X86 {
f.SaveRegister(x86.RDX) f.SaveRegister(x86.RDX)
tmp := f.NewRegister() }
f.RegisterNumber(asm.MOVE, tmp, number)
f.RegisterRegister(asm.MODULO, register, tmp) f.RegisterNumber(asm.MODULO, register, number)
f.FreeRegister(tmp)
case token.And, token.AndAssign: case token.And, token.AndAssign:
f.RegisterNumber(asm.AND, register, number) f.RegisterNumber(asm.AND, register, number)

View File

@ -2,6 +2,7 @@ package core
import ( import (
"git.urbach.dev/cli/q/src/asm" "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/cpu"
"git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/errors"
"git.urbach.dev/cli/q/src/token" "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) f.RegisterRegister(asm.MUL, register, operand)
case token.Div, token.DivAssign: case token.Div, token.DivAssign:
if config.TargetArch == config.X86 {
f.SaveRegister(x86.RDX) f.SaveRegister(x86.RDX)
}
f.RegisterRegister(asm.DIV, register, operand) f.RegisterRegister(asm.DIV, register, operand)
case token.Mod, token.ModAssign: case token.Mod, token.ModAssign:
if config.TargetArch == config.X86 {
f.SaveRegister(x86.RDX) f.SaveRegister(x86.RDX)
}
f.RegisterRegister(asm.MODULO, register, operand) f.RegisterRegister(asm.MODULO, register, operand)
case token.And, token.AndAssign: case token.And, token.AndAssign:

View File

@ -19,12 +19,13 @@ const (
R13 R13
R14 R14
R15 R15
TMP = RCX
) )
var ( var (
SyscallInputRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9} SyscallInputRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9}
SyscallOutputRegisters = []cpu.Register{RAX, RCX, R11} 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 InputRegisters = SyscallInputRegisters
OutputRegisters = SyscallInputRegisters OutputRegisters = SyscallInputRegisters
WindowsInputRegisters = []cpu.Register{RCX, RDX, R8, R9} WindowsInputRegisters = []cpu.Register{RCX, RDX, R8, R9}

View File

@ -5,7 +5,6 @@ main() {
d := 4 d := 4
e := 5 e := 5
f := 6 f := 6
g := 7
assert a == 1 assert a == 1
assert b == 2 assert b == 2
@ -13,5 +12,4 @@ main() {
assert d == 4 assert d == 4
assert e == 5 assert e == 5
assert f == 6 assert f == 6
assert g == 7
} }