This commit is contained in:
parent
8ea491bb92
commit
8d13f1ece8
6 changed files with 38 additions and 7 deletions
|
@ -1,12 +1,12 @@
|
||||||
write(buffer string) -> (written int) {
|
write(buffer string) -> (written int) {
|
||||||
stdout := kernel32.GetStdHandle(-11)
|
stdout := kernel32.GetStdHandle(-11)
|
||||||
kernel32.WriteConsoleA(stdout, buffer.ptr, buffer.len, 0)
|
kernel32.WriteFile(stdout, buffer.ptr, buffer.len, 0, 0)
|
||||||
return buffer.len
|
return buffer.len
|
||||||
}
|
}
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
kernel32 {
|
kernel32 {
|
||||||
GetStdHandle(device int64) -> (handle int64)
|
GetStdHandle(device int64) -> (handle int64)
|
||||||
WriteConsoleA(fd int64, buffer *byte, length uint32, written *uint32) -> (success bool)
|
WriteFile(fd int64, buffer *byte, length uint32, written *uint32, overlapped *any) -> (success bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,6 +25,9 @@ type CallExtern struct {
|
||||||
Function string
|
Function string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CallExternStart struct{}
|
||||||
|
type CallExternEnd struct{}
|
||||||
|
|
||||||
type FunctionStart struct{}
|
type FunctionStart struct{}
|
||||||
type FunctionEnd struct{}
|
type FunctionEnd struct{}
|
||||||
|
|
||||||
|
@ -51,6 +54,10 @@ type MoveRegisterRegister struct {
|
||||||
Source cpu.Register
|
Source cpu.Register
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PushRegister struct {
|
||||||
|
Register cpu.Register
|
||||||
|
}
|
||||||
|
|
||||||
type Return struct{}
|
type Return struct{}
|
||||||
|
|
||||||
type SubRegisterNumber struct {
|
type SubRegisterNumber struct {
|
||||||
|
|
|
@ -32,6 +32,12 @@ func (c *compilerARM) Compile(instr Instruction) {
|
||||||
offset := (address - start) / 4
|
offset := (address - start) / 4
|
||||||
binary.LittleEndian.PutUint32(c.code[start:start+4], arm.Call(offset))
|
binary.LittleEndian.PutUint32(c.code[start:start+4], arm.Call(offset))
|
||||||
})
|
})
|
||||||
|
case *CallExtern:
|
||||||
|
panic("not implemented")
|
||||||
|
case *CallExternStart:
|
||||||
|
panic("not implemented")
|
||||||
|
case *CallExternEnd:
|
||||||
|
panic("not implemented")
|
||||||
case *Jump:
|
case *Jump:
|
||||||
start := len(c.code)
|
start := len(c.code)
|
||||||
c.append(arm.Jump(0))
|
c.append(arm.Jump(0))
|
||||||
|
@ -76,6 +82,8 @@ func (c *compilerARM) Compile(instr Instruction) {
|
||||||
c.code = arm.MoveRegisterNumber(c.code, instr.Destination, instr.Number)
|
c.code = arm.MoveRegisterNumber(c.code, instr.Destination, instr.Number)
|
||||||
case *MoveRegisterRegister:
|
case *MoveRegisterRegister:
|
||||||
c.append(arm.MoveRegisterRegister(instr.Destination, instr.Source))
|
c.append(arm.MoveRegisterRegister(instr.Destination, instr.Source))
|
||||||
|
case *PushRegister:
|
||||||
|
panic("not implemented")
|
||||||
case *Return:
|
case *Return:
|
||||||
c.append(arm.Return())
|
c.append(arm.Return())
|
||||||
case *Syscall:
|
case *Syscall:
|
||||||
|
|
|
@ -41,12 +41,8 @@ func (c *compilerX86) Compile(instr Instruction) {
|
||||||
binary.LittleEndian.PutUint32(c.code[end-4:end], uint32(offset))
|
binary.LittleEndian.PutUint32(c.code[end-4:end], uint32(offset))
|
||||||
})
|
})
|
||||||
case *CallExtern:
|
case *CallExtern:
|
||||||
c.code = x86.MoveRegisterRegister(c.code, x86.R5, x86.SP)
|
|
||||||
c.code = x86.AndRegisterNumber(c.code, x86.SP, -16)
|
|
||||||
c.code = x86.SubRegisterNumber(c.code, x86.SP, 32)
|
|
||||||
c.code = x86.CallAt(c.code, 0)
|
c.code = x86.CallAt(c.code, 0)
|
||||||
end := len(c.code)
|
end := len(c.code)
|
||||||
c.code = x86.MoveRegisterRegister(c.code, x86.SP, x86.R5)
|
|
||||||
|
|
||||||
c.Defer(func() {
|
c.Defer(func() {
|
||||||
index := c.libraries.Index(instr.Library, instr.Function)
|
index := c.libraries.Index(instr.Library, instr.Function)
|
||||||
|
@ -59,6 +55,12 @@ func (c *compilerX86) Compile(instr Instruction) {
|
||||||
offset := address - end
|
offset := address - end
|
||||||
binary.LittleEndian.PutUint32(c.code[end-4:end], uint32(offset))
|
binary.LittleEndian.PutUint32(c.code[end-4:end], uint32(offset))
|
||||||
})
|
})
|
||||||
|
case *CallExternStart:
|
||||||
|
c.code = x86.MoveRegisterRegister(c.code, x86.R5, x86.SP)
|
||||||
|
c.code = x86.AndRegisterNumber(c.code, x86.SP, -16)
|
||||||
|
c.code = x86.SubRegisterNumber(c.code, x86.SP, 32)
|
||||||
|
case *CallExternEnd:
|
||||||
|
c.code = x86.MoveRegisterRegister(c.code, x86.SP, x86.R5)
|
||||||
case *FunctionStart:
|
case *FunctionStart:
|
||||||
case *FunctionEnd:
|
case *FunctionEnd:
|
||||||
case *Jump:
|
case *Jump:
|
||||||
|
@ -100,6 +102,8 @@ func (c *compilerX86) Compile(instr Instruction) {
|
||||||
c.code = x86.MoveRegisterNumber(c.code, instr.Destination, instr.Number)
|
c.code = x86.MoveRegisterNumber(c.code, instr.Destination, instr.Number)
|
||||||
case *MoveRegisterRegister:
|
case *MoveRegisterRegister:
|
||||||
c.code = x86.MoveRegisterRegister(c.code, instr.Destination, instr.Source)
|
c.code = x86.MoveRegisterRegister(c.code, instr.Destination, instr.Source)
|
||||||
|
case *PushRegister:
|
||||||
|
c.code = x86.PushRegister(c.code, instr.Register)
|
||||||
case *Return:
|
case *Return:
|
||||||
c.code = x86.Return(c.code)
|
c.code = x86.Return(c.code)
|
||||||
case *SubRegisterNumber:
|
case *SubRegisterNumber:
|
||||||
|
|
|
@ -41,6 +41,12 @@ func (f *Compiler) CreateSteps(ir ssa.IR) []Step {
|
||||||
|
|
||||||
case *ssa.CallExtern:
|
case *ssa.CallExtern:
|
||||||
for r, param := range instr.Arguments[1:] {
|
for r, param := range instr.Arguments[1:] {
|
||||||
|
if r >= len(f.CPU.ExternCall.In) {
|
||||||
|
// Temporary hack to allow arguments 5 and 6 to be hinted as r10 and r11, then pushed later.
|
||||||
|
f.ValueToStep[param].Hint(f.CPU.ExternCall.Volatile[1+r])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
f.ValueToStep[param].Hint(f.CPU.ExternCall.In[r])
|
f.ValueToStep[param].Hint(f.CPU.ExternCall.In[r])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,10 +69,15 @@ func (f *Compiler) Exec(step *Step) {
|
||||||
})
|
})
|
||||||
|
|
||||||
case *ssa.CallExtern:
|
case *ssa.CallExtern:
|
||||||
|
f.Assembler.Append(&asm.CallExternStart{})
|
||||||
args := instr.Arguments[1:]
|
args := instr.Arguments[1:]
|
||||||
|
|
||||||
for i, arg := range args {
|
for i, arg := range args {
|
||||||
if f.ValueToStep[arg].Register != f.CPU.ExternCall.In[i] {
|
if i >= len(f.CPU.ExternCall.In) {
|
||||||
|
f.Assembler.Append(&asm.PushRegister{
|
||||||
|
Register: f.ValueToStep[arg].Register,
|
||||||
|
})
|
||||||
|
} else if f.ValueToStep[arg].Register != f.CPU.ExternCall.In[i] {
|
||||||
f.Assembler.Append(&asm.MoveRegisterRegister{
|
f.Assembler.Append(&asm.MoveRegisterRegister{
|
||||||
Destination: f.CPU.ExternCall.In[i],
|
Destination: f.CPU.ExternCall.In[i],
|
||||||
Source: f.ValueToStep[arg].Register,
|
Source: f.ValueToStep[arg].Register,
|
||||||
|
@ -85,6 +90,7 @@ func (f *Compiler) Exec(step *Step) {
|
||||||
library := fn.UniqueName[:dot]
|
library := fn.UniqueName[:dot]
|
||||||
function := fn.UniqueName[dot+1:]
|
function := fn.UniqueName[dot+1:]
|
||||||
f.Assembler.Append(&asm.CallExtern{Library: library, Function: function})
|
f.Assembler.Append(&asm.CallExtern{Library: library, Function: function})
|
||||||
|
f.Assembler.Append(&asm.CallExternEnd{})
|
||||||
|
|
||||||
if step.Register == -1 || step.Register == f.CPU.ExternCall.Out[0] {
|
if step.Register == -1 || step.Register == f.CPU.ExternCall.Out[0] {
|
||||||
return
|
return
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue