Fixed volatile registers on external calls
This commit is contained in:
parent
49afa5d800
commit
c10395eddc
@ -2,7 +2,10 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/asm"
|
||||
"git.akyoto.dev/cli/q/src/cpu"
|
||||
"git.akyoto.dev/cli/q/src/expression"
|
||||
"git.akyoto.dev/cli/q/src/types"
|
||||
"git.akyoto.dev/cli/q/src/x86"
|
||||
@ -11,6 +14,17 @@ import (
|
||||
// CallExtern calls an external function.
|
||||
func (f *Function) CallExtern(fn *Function, parameters []*expression.Expression) ([]types.Type, error) {
|
||||
f.DLLs = f.DLLs.Append(fn.Package, fn.Name)
|
||||
|
||||
var pushedRegisters []cpu.Register
|
||||
|
||||
for _, register := range x86.WindowsVolatileRegisters {
|
||||
if f.RegisterIsUsed(register) {
|
||||
f.Register(asm.PUSH, register)
|
||||
f.FreeRegister(register)
|
||||
pushedRegisters = append(pushedRegisters, register)
|
||||
}
|
||||
}
|
||||
|
||||
registers := x86.WindowsInputRegisters[:len(parameters)]
|
||||
err := f.BeforeCall(fn, parameters, registers)
|
||||
|
||||
@ -19,5 +33,14 @@ func (f *Function) CallExtern(fn *Function, parameters []*expression.Expression)
|
||||
}
|
||||
|
||||
f.DLLCall(fmt.Sprintf("%s.%s", fn.Package, fn.Name))
|
||||
|
||||
for _, register := range registers {
|
||||
f.FreeRegister(register)
|
||||
}
|
||||
|
||||
for _, register := range slices.Backward(pushedRegisters) {
|
||||
f.Register(asm.POP, register)
|
||||
}
|
||||
|
||||
return fn.OutputTypes, nil
|
||||
}
|
||||
|
@ -22,12 +22,13 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
AllRegisters = []cpu.Register{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15}
|
||||
SyscallInputRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9}
|
||||
SyscallOutputRegisters = []cpu.Register{RAX, RCX, R11}
|
||||
GeneralRegisters = []cpu.Register{RCX, RBX, R11, R12, R13, R14, R15, RBP}
|
||||
InputRegisters = SyscallInputRegisters
|
||||
OutputRegisters = SyscallInputRegisters
|
||||
WindowsInputRegisters = []cpu.Register{RCX, RDX, R8, R9}
|
||||
WindowsOutputRegisters = []cpu.Register{RAX}
|
||||
AllRegisters = []cpu.Register{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15}
|
||||
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, RBP}
|
||||
InputRegisters = SyscallInputRegisters
|
||||
OutputRegisters = SyscallInputRegisters
|
||||
WindowsInputRegisters = []cpu.Register{RCX, RDX, R8, R9}
|
||||
WindowsOutputRegisters = []cpu.Register{RAX}
|
||||
WindowsVolatileRegisters = []cpu.Register{RCX, RDX, R8, R9, R10, R11}
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user