Improved division
This commit is contained in:
parent
f9ff83136a
commit
c8045cb4fb
@ -58,7 +58,34 @@ func (a Assembler) Finalize() ([]byte, []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case DIV:
|
case DIV:
|
||||||
code = divide(code, x.Data)
|
switch operands := x.Data.(type) {
|
||||||
|
case *RegisterRegister:
|
||||||
|
if operands.Destination != x64.RAX {
|
||||||
|
code = x64.MoveRegisterRegister(code, x64.RAX, operands.Destination)
|
||||||
|
}
|
||||||
|
|
||||||
|
code = x64.ExtendRAXToRDX(code)
|
||||||
|
code = x64.DivRegister(code, operands.Source)
|
||||||
|
|
||||||
|
if operands.Destination != x64.RAX {
|
||||||
|
code = x64.MoveRegisterRegister(code, operands.Destination, x64.RAX)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case MODULO:
|
||||||
|
switch operands := x.Data.(type) {
|
||||||
|
case *RegisterRegister:
|
||||||
|
if operands.Destination != x64.RAX {
|
||||||
|
code = x64.MoveRegisterRegister(code, x64.RAX, operands.Destination)
|
||||||
|
}
|
||||||
|
|
||||||
|
code = x64.ExtendRAXToRDX(code)
|
||||||
|
code = x64.DivRegister(code, operands.Source)
|
||||||
|
|
||||||
|
if operands.Destination != x64.RDX {
|
||||||
|
code = x64.MoveRegisterRegister(code, operands.Destination, x64.RDX)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case CALL:
|
case CALL:
|
||||||
code = x64.Call(code, 0x00_00_00_00)
|
code = x64.Call(code, 0x00_00_00_00)
|
||||||
@ -144,9 +171,6 @@ func (a Assembler) Finalize() ([]byte, []byte) {
|
|||||||
code = x64.LoadRegister(code, operands.Register, operands.Address.Offset, operands.Address.Length, operands.Address.Base)
|
code = x64.LoadRegister(code, operands.Register, operands.Address.Offset, operands.Address.Length, operands.Address.Base)
|
||||||
}
|
}
|
||||||
|
|
||||||
case MODULO:
|
|
||||||
code = modulo(code, x.Data)
|
|
||||||
|
|
||||||
case MOVE:
|
case MOVE:
|
||||||
switch operands := x.Data.(type) {
|
switch operands := x.Data.(type) {
|
||||||
case *RegisterNumber:
|
case *RegisterNumber:
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
package asm
|
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/arch/x64"
|
|
||||||
|
|
||||||
// divide implements the division on x64 machines.
|
|
||||||
func divide(code []byte, data any) []byte {
|
|
||||||
switch operands := data.(type) {
|
|
||||||
case *RegisterNumber:
|
|
||||||
if operands.Register == x64.RAX {
|
|
||||||
code = x64.MoveRegisterNumber(code, x64.RCX, operands.Number)
|
|
||||||
code = x64.ExtendRAXToRDX(code)
|
|
||||||
code = x64.DivRegister(code, x64.RCX)
|
|
||||||
} else {
|
|
||||||
code = x64.MoveRegisterRegister(code, x64.RAX, operands.Register)
|
|
||||||
code = x64.MoveRegisterNumber(code, operands.Register, operands.Number)
|
|
||||||
code = x64.ExtendRAXToRDX(code)
|
|
||||||
code = x64.DivRegister(code, operands.Register)
|
|
||||||
code = x64.MoveRegisterRegister(code, operands.Register, x64.RAX)
|
|
||||||
}
|
|
||||||
|
|
||||||
case *RegisterRegister:
|
|
||||||
if operands.Destination == x64.RAX {
|
|
||||||
code = x64.ExtendRAXToRDX(code)
|
|
||||||
code = x64.DivRegister(code, operands.Source)
|
|
||||||
} else {
|
|
||||||
code = x64.MoveRegisterRegister(code, x64.RAX, operands.Destination)
|
|
||||||
code = x64.ExtendRAXToRDX(code)
|
|
||||||
|
|
||||||
code = x64.DivRegister(code, operands.Source)
|
|
||||||
code = x64.MoveRegisterRegister(code, operands.Destination, x64.RAX)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
|
|
||||||
// modulo calculates the division remainder on x64 machines.
|
|
||||||
func modulo(code []byte, data any) []byte {
|
|
||||||
switch operands := data.(type) {
|
|
||||||
case *RegisterNumber:
|
|
||||||
code = x64.MoveRegisterRegister(code, x64.RAX, operands.Register)
|
|
||||||
code = x64.MoveRegisterNumber(code, operands.Register, operands.Number)
|
|
||||||
code = x64.ExtendRAXToRDX(code)
|
|
||||||
code = x64.DivRegister(code, operands.Register)
|
|
||||||
code = x64.MoveRegisterRegister(code, operands.Register, x64.RDX)
|
|
||||||
|
|
||||||
case *RegisterRegister:
|
|
||||||
code = x64.MoveRegisterRegister(code, x64.RAX, operands.Destination)
|
|
||||||
code = x64.ExtendRAXToRDX(code)
|
|
||||||
code = x64.DivRegister(code, operands.Source)
|
|
||||||
code = x64.MoveRegisterRegister(code, operands.Destination, x64.RDX)
|
|
||||||
}
|
|
||||||
|
|
||||||
return code
|
|
||||||
}
|
|
@ -24,10 +24,16 @@ 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:
|
||||||
f.RegisterNumber(asm.DIV, register, number)
|
tmp := f.NewRegister()
|
||||||
|
f.RegisterNumber(asm.MOVE, tmp, number)
|
||||||
|
f.RegisterRegister(asm.DIV, register, tmp)
|
||||||
|
f.FreeRegister(tmp)
|
||||||
|
|
||||||
case token.Mod, token.ModAssign:
|
case token.Mod, token.ModAssign:
|
||||||
f.RegisterNumber(asm.MODULO, register, number)
|
tmp := f.NewRegister()
|
||||||
|
f.RegisterNumber(asm.MOVE, tmp, number)
|
||||||
|
f.RegisterRegister(asm.MODULO, register, tmp)
|
||||||
|
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user