This commit is contained in:
parent
7d2eb95c83
commit
6d15ff3a35
9 changed files with 116 additions and 43 deletions
3
lib/os/os_mac_arm.q
Normal file
3
lib/os/os_mac_arm.q
Normal file
|
@ -0,0 +1,3 @@
|
|||
exit(code int) {
|
||||
syscall(0x1, code)
|
||||
}
|
|
@ -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},
|
||||
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,
|
||||
}
|
||||
)
|
8
src/cpu/ABI.go
Normal file
8
src/cpu/ABI.go
Normal file
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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]
|
||||
|
|
|
@ -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] {
|
||||
|
|
|
@ -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],
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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},
|
||||
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},
|
||||
},
|
||||
}
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue