package core import ( "slices" "git.urbach.dev/cli/q/src/asm" "git.urbach.dev/cli/q/src/cpu" ) // CallSafe pushes used registers to the stack, executes the call and restores the original register value. func (f *Function) CallSafe(fn *Function, registers []cpu.Register) { for _, register := range f.CPU.Output { f.SaveRegister(register) } for _, register := range f.CPU.General { if f.RegisterIsUsed(register) { f.Register(asm.PUSH, register) } } f.Label(asm.CALL, fn.UniqueName) for _, register := range slices.Backward(f.CPU.General) { if f.RegisterIsUsed(register) { f.Register(asm.POP, register) } } for _, register := range registers { f.FreeRegister(register) } }