Improved assembler
This commit is contained in:
@ -52,36 +52,7 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
|
||||
}
|
||||
|
||||
case DIV:
|
||||
switch operands := x.Data.(type) {
|
||||
case *RegisterNumber:
|
||||
if operands.Register == x64.RAX {
|
||||
code = x64.PushRegister(code, x64.RCX)
|
||||
code = x64.MoveRegisterNumber32(code, x64.RCX, uint32(operands.Number))
|
||||
code = x64.ExtendRAXToRDX(code)
|
||||
code = x64.DivRegister(code, x64.RCX)
|
||||
code = x64.PopRegister(code, x64.RCX)
|
||||
} else {
|
||||
code = x64.PushRegister(code, x64.RAX)
|
||||
code = x64.PushRegister(code, x64.RDX)
|
||||
code = x64.MoveRegisterRegister64(code, x64.RAX, operands.Register)
|
||||
code = x64.MoveRegisterNumber32(code, operands.Register, uint32(operands.Number))
|
||||
code = x64.ExtendRAXToRDX(code)
|
||||
code = x64.DivRegister(code, operands.Register)
|
||||
code = x64.MoveRegisterRegister64(code, operands.Register, x64.RAX)
|
||||
code = x64.PopRegister(code, x64.RDX)
|
||||
code = x64.PopRegister(code, x64.RAX)
|
||||
}
|
||||
|
||||
case *RegisterRegister:
|
||||
code = x64.PushRegister(code, x64.RAX)
|
||||
code = x64.PushRegister(code, x64.RDX)
|
||||
code = x64.MoveRegisterRegister64(code, x64.RAX, operands.Destination)
|
||||
code = x64.ExtendRAXToRDX(code)
|
||||
code = x64.DivRegister(code, operands.Source)
|
||||
code = x64.MoveRegisterRegister64(code, operands.Destination, x64.RAX)
|
||||
code = x64.PopRegister(code, x64.RDX)
|
||||
code = x64.PopRegister(code, x64.RAX)
|
||||
}
|
||||
code = divide(code, x.Data)
|
||||
|
||||
case CALL:
|
||||
code = x64.Call(code, 0x00_00_00_00)
|
||||
@ -166,3 +137,43 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
|
||||
func (a *Assembler) Merge(b *Assembler) {
|
||||
a.Instructions = append(a.Instructions, b.Instructions...)
|
||||
}
|
||||
|
||||
// divide implements the division on x64 machines.
|
||||
func divide(code []byte, data any) []byte {
|
||||
code = x64.PushRegister(code, x64.RDX)
|
||||
|
||||
switch operands := data.(type) {
|
||||
case *RegisterNumber:
|
||||
if operands.Register == x64.RAX {
|
||||
code = x64.PushRegister(code, x64.RCX)
|
||||
code = x64.MoveRegisterNumber32(code, x64.RCX, uint32(operands.Number))
|
||||
code = x64.ExtendRAXToRDX(code)
|
||||
code = x64.DivRegister(code, x64.RCX)
|
||||
code = x64.PopRegister(code, x64.RCX)
|
||||
} else {
|
||||
code = x64.PushRegister(code, x64.RAX)
|
||||
code = x64.MoveRegisterRegister64(code, x64.RAX, operands.Register)
|
||||
code = x64.MoveRegisterNumber32(code, operands.Register, uint32(operands.Number))
|
||||
code = x64.ExtendRAXToRDX(code)
|
||||
code = x64.DivRegister(code, operands.Register)
|
||||
code = x64.MoveRegisterRegister64(code, operands.Register, x64.RAX)
|
||||
code = x64.PopRegister(code, x64.RAX)
|
||||
}
|
||||
|
||||
case *RegisterRegister:
|
||||
if operands.Destination == x64.RAX {
|
||||
code = x64.ExtendRAXToRDX(code)
|
||||
code = x64.DivRegister(code, operands.Source)
|
||||
} else {
|
||||
code = x64.PushRegister(code, x64.RAX)
|
||||
code = x64.MoveRegisterRegister64(code, x64.RAX, operands.Destination)
|
||||
code = x64.ExtendRAXToRDX(code)
|
||||
code = x64.DivRegister(code, operands.Source)
|
||||
code = x64.MoveRegisterRegister64(code, operands.Destination, x64.RAX)
|
||||
code = x64.PopRegister(code, x64.RAX)
|
||||
}
|
||||
}
|
||||
|
||||
code = x64.PopRegister(code, x64.RDX)
|
||||
return code
|
||||
}
|
||||
|
Reference in New Issue
Block a user