diff --git a/lib/os/os_mac_arm.q b/lib/os/os_mac_arm.q new file mode 100644 index 0000000..1d288b5 --- /dev/null +++ b/lib/os/os_mac_arm.q @@ -0,0 +1,3 @@ +exit(code int) { + syscall(0x1, code) +} \ No newline at end of file diff --git a/lib/os/os_mac.q b/lib/os/os_mac_x86.q similarity index 100% rename from lib/os/os_mac.q rename to lib/os/os_mac_x86.q diff --git a/src/arm/Registers.go b/src/arm/Registers.go index ec53bd7..a23e618 100644 --- a/src/arm/Registers.go +++ b/src/arm/Registers.go @@ -41,10 +41,37 @@ const ( ZR = SP // Zero register uses the same numerical value as SP ) -var CPU = cpu.CPU{ - Call: []cpu.Register{X0, X1, X2, X3, X4, X5, X6}, - Syscall: []cpu.Register{X8, X0, X1, X2, X3, X4, X5}, - ExternCall: []cpu.Register{X0, X1, X2, X3, X4, X5, X6, X7}, - ExternCallVolatile: []cpu.Register{X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17}, - Return: []cpu.Register{X0, X1, X2}, -} \ No newline at end of file +var ( + LinuxCPU = cpu.CPU{ + Call: cpu.ABI{ + In: []cpu.Register{X0, X1, X2, X3, X4, X5, X6}, + Out: []cpu.Register{X0, X1, X2}, + Volatile: []cpu.Register{X0, X1, X2, X3, X4, X5, X6}, + }, + ExternCall: cpu.ABI{ + In: []cpu.Register{X0, X1, X2, X3, X4, X5, X6, X7}, + Out: []cpu.Register{X0, X1}, + Volatile: []cpu.Register{X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17}, + }, + Syscall: cpu.ABI{ + In: []cpu.Register{X8, X0, X1, X2, X3, X4, X5}, + Out: []cpu.Register{X0}, + Volatile: []cpu.Register{X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17}, + }, + } + + MacCPU = cpu.CPU{ + Call: LinuxCPU.Call, + ExternCall: LinuxCPU.ExternCall, + Syscall: cpu.ABI{ + In: []cpu.Register{X16, X0, X1, X2, X3, X4, X5, X6, X7}, + Out: LinuxCPU.Syscall.Out, + Volatile: LinuxCPU.Syscall.Volatile, + }, + } + + WindowsCPU = cpu.CPU{ + Call: LinuxCPU.Call, + ExternCall: LinuxCPU.ExternCall, + } +) \ No newline at end of file diff --git a/src/cpu/ABI.go b/src/cpu/ABI.go new file mode 100644 index 0000000..0d43568 --- /dev/null +++ b/src/cpu/ABI.go @@ -0,0 +1,8 @@ +package cpu + +// ABI is the Application Binary Interface which defines the registers used in function calls. +type ABI struct { + In []Register + Out []Register + Volatile []Register +} \ No newline at end of file diff --git a/src/cpu/CPU.go b/src/cpu/CPU.go index 68b41ee..16c9b76 100644 --- a/src/cpu/CPU.go +++ b/src/cpu/CPU.go @@ -2,9 +2,7 @@ package cpu // CPU represents the processor. type CPU struct { - Call []Register - Syscall []Register - ExternCall []Register - ExternCallVolatile []Register - Return []Register + Call ABI + ExternCall ABI + Syscall ABI } \ No newline at end of file diff --git a/src/scanner/scanFunction.go b/src/scanner/scanFunction.go index 259c011..403a617 100644 --- a/src/scanner/scanFunction.go +++ b/src/scanner/scanFunction.go @@ -72,9 +72,23 @@ func (s *scanner) scanFunction(file *fs.File, tokens token.List, i int) (int, er switch s.build.Arch { case build.ARM: - function.CPU = &arm.CPU + switch s.build.OS { + case build.Linux: + function.CPU = &arm.LinuxCPU + case build.Mac: + function.CPU = &arm.MacCPU + case build.Windows: + function.CPU = &arm.WindowsCPU + } case build.X86: - function.CPU = &x86.CPU + switch s.build.OS { + case build.Linux: + function.CPU = &x86.LinuxCPU + case build.Mac: + function.CPU = &x86.MacCPU + case build.Windows: + function.CPU = &x86.WindowsCPU + } } function.Body = tokens[bodyStart:i] diff --git a/src/ssa2asm/CreateSteps.go b/src/ssa2asm/CreateSteps.go index 8aaaa22..13fcd2b 100644 --- a/src/ssa2asm/CreateSteps.go +++ b/src/ssa2asm/CreateSteps.go @@ -29,32 +29,32 @@ func (f *Compiler) CreateSteps(ir ssa.IR) []Step { if isStruct { for _, field := range structure.Arguments { - f.ValueToStep[field].Hint(f.CPU.Call[offset+r]) + f.ValueToStep[field].Hint(f.CPU.Call.In[offset+r]) offset++ } offset-- } else { - f.ValueToStep[param].Hint(f.CPU.Call[offset+r]) + f.ValueToStep[param].Hint(f.CPU.Call.In[offset+r]) } } case *ssa.CallExtern: for r, param := range instr.Arguments[1:] { - f.ValueToStep[param].Hint(f.CPU.ExternCall[r]) + f.ValueToStep[param].Hint(f.CPU.ExternCall.In[r]) } case *ssa.Parameter: - f.ValueToStep[instr].Register = f.CPU.Call[instr.Index] + f.ValueToStep[instr].Register = f.CPU.Call.In[instr.Index] case *ssa.Return: for r, param := range instr.Arguments { - f.ValueToStep[param].Hint(f.CPU.Return[r]) + f.ValueToStep[param].Hint(f.CPU.Call.Out[r]) } case *ssa.Syscall: for r, param := range slices.Backward(instr.Arguments) { - f.ValueToStep[param].Hint(f.CPU.Syscall[r]) + f.ValueToStep[param].Hint(f.CPU.Syscall.In[r]) } } @@ -89,7 +89,7 @@ func (f *Compiler) CreateSteps(ir ssa.IR) []Step { liveParam, isParam := live.Value.(*ssa.Parameter) if isParam { - oldRegister = f.CPU.Call[liveParam.Index] + oldRegister = f.CPU.Call.In[liveParam.Index] } for _, existing := range step.Live[:liveIndex] { diff --git a/src/ssa2asm/Exec.go b/src/ssa2asm/Exec.go index 66f24ab..e65aeac 100644 --- a/src/ssa2asm/Exec.go +++ b/src/ssa2asm/Exec.go @@ -35,9 +35,9 @@ func (f *Compiler) Exec(step *Step) { if isStruct { for _, field := range structure.Arguments { - if f.ValueToStep[field].Register != f.CPU.Call[offset+i] { + if f.ValueToStep[field].Register != f.CPU.Call.In[offset+i] { f.Assembler.Append(&asm.MoveRegisterRegister{ - Destination: f.CPU.Call[offset+i], + Destination: f.CPU.Call.In[offset+i], Source: f.ValueToStep[field].Register, }) } @@ -47,9 +47,9 @@ func (f *Compiler) Exec(step *Step) { offset-- } else { - if f.ValueToStep[arg].Register != f.CPU.Call[offset+i] { + if f.ValueToStep[arg].Register != f.CPU.Call.In[offset+i] { f.Assembler.Append(&asm.MoveRegisterRegister{ - Destination: f.CPU.Call[offset+i], + Destination: f.CPU.Call.In[offset+i], Source: f.ValueToStep[arg].Register, }) } @@ -59,22 +59,22 @@ func (f *Compiler) Exec(step *Step) { fn := instr.Arguments[0].(*ssa.Function) f.Assembler.Append(&asm.Call{Label: fn.UniqueName}) - if step.Register == -1 || step.Register == f.CPU.Return[0] { + if step.Register == -1 || step.Register == f.CPU.Call.Out[0] { return } f.Assembler.Append(&asm.MoveRegisterRegister{ Destination: step.Register, - Source: f.CPU.Return[0], + Source: f.CPU.Call.Out[0], }) case *ssa.CallExtern: args := instr.Arguments[1:] for i, arg := range args { - if f.ValueToStep[arg].Register != f.CPU.ExternCall[i] { + if f.ValueToStep[arg].Register != f.CPU.ExternCall.In[i] { f.Assembler.Append(&asm.MoveRegisterRegister{ - Destination: f.CPU.ExternCall[i], + Destination: f.CPU.ExternCall.In[i], Source: f.ValueToStep[arg].Register, }) } @@ -86,13 +86,13 @@ func (f *Compiler) Exec(step *Step) { function := fn.UniqueName[dot+1:] f.Assembler.Append(&asm.CallExtern{Library: library, Function: function}) - if step.Register == -1 || step.Register == f.CPU.Return[0] { + if step.Register == -1 || step.Register == f.CPU.ExternCall.Out[0] { return } f.Assembler.Append(&asm.MoveRegisterRegister{ Destination: step.Register, - Source: f.CPU.Return[0], + Source: f.CPU.ExternCall.Out[0], }) case *ssa.Int: @@ -102,7 +102,7 @@ func (f *Compiler) Exec(step *Step) { }) case *ssa.Parameter: - source := f.CPU.Call[instr.Index] + source := f.CPU.Call.In[instr.Index] if step.Register == -1 || step.Register == source { return @@ -129,9 +129,9 @@ func (f *Compiler) Exec(step *Step) { case *ssa.Syscall: for i, arg := range instr.Arguments { - if f.ValueToStep[arg].Register != f.CPU.Syscall[i] { + if f.ValueToStep[arg].Register != f.CPU.Syscall.In[i] { f.Assembler.Append(&asm.MoveRegisterRegister{ - Destination: f.CPU.Syscall[i], + Destination: f.CPU.Syscall.In[i], Source: f.ValueToStep[arg].Register, }) } @@ -139,13 +139,13 @@ func (f *Compiler) Exec(step *Step) { f.Assembler.Append(&asm.Syscall{}) - if step.Register == -1 || step.Register == f.CPU.Return[0] { + if step.Register == -1 || step.Register == f.CPU.Syscall.Out[0] { return } f.Assembler.Append(&asm.MoveRegisterRegister{ Destination: step.Register, - Source: f.CPU.Return[0], + Source: f.CPU.Syscall.Out[0], }) } } \ No newline at end of file diff --git a/src/x86/Registers.go b/src/x86/Registers.go index f939b5f..1de949f 100644 --- a/src/x86/Registers.go +++ b/src/x86/Registers.go @@ -21,10 +21,33 @@ const ( R15 ) -var CPU = cpu.CPU{ - Call: []cpu.Register{R0, R7, R6, R2, R10, R8, R9}, - Syscall: []cpu.Register{R0, R7, R6, R2, R10, R8, R9}, - ExternCall: []cpu.Register{R1, R2, R8, R9}, - ExternCallVolatile: []cpu.Register{R0, R1, R2, R8, R9, R10, R11}, - Return: []cpu.Register{R0, R7, R6}, -} \ No newline at end of file +var ( + LinuxCPU = cpu.CPU{ + Call: cpu.ABI{ + In: []cpu.Register{R0, R7, R6, R2, R10, R8, R9}, + Out: []cpu.Register{R0, R7, R6}, + Volatile: []cpu.Register{R0, R1, R2, R6, R7, R8, R9, R10, R11}, + }, + ExternCall: cpu.ABI{ + In: []cpu.Register{R7, R6, R2, R1, R8, R9}, + Out: []cpu.Register{R0, R2}, + Volatile: []cpu.Register{R0, R1, R2, R6, R7, R8, R9, R10, R11}, + }, + Syscall: cpu.ABI{ + In: []cpu.Register{R0, R7, R6, R2, R10, R8, R9}, + Out: []cpu.Register{R0}, + Volatile: []cpu.Register{R0, R7, R6}, + }, + } + + MacCPU = LinuxCPU + + WindowsCPU = cpu.CPU{ + Call: LinuxCPU.Call, + ExternCall: cpu.ABI{ + In: []cpu.Register{R1, R2, R8, R9}, + Out: []cpu.Register{R0}, + Volatile: []cpu.Register{R0, R1, R2, R8, R9, R10, R11}, + }, + } +) \ No newline at end of file