Added Windows support for the hello example
All checks were successful
/ test (push) Successful in 16s
All checks were successful
/ test (push) Successful in 16s
This commit is contained in:
parent
e833268061
commit
47b4b1f1dd
7 changed files with 92 additions and 55 deletions
|
@ -1,10 +1,12 @@
|
|||
write(_ string) -> (written int) {
|
||||
return 0
|
||||
write(buffer string) -> (written int) {
|
||||
stdout := kernel32.GetStdHandle(-11)
|
||||
kernel32.WriteConsoleA(stdout, buffer.ptr, buffer.len, 0)
|
||||
return buffer.len
|
||||
}
|
||||
|
||||
extern {
|
||||
kernel32 {
|
||||
GetStdHandle(handle int64) -> int64
|
||||
WriteConsoleA(fd int64, buffer *byte, length uint32, written *uint32) -> bool
|
||||
GetStdHandle(device int64) -> (handle int64)
|
||||
WriteConsoleA(fd int64, buffer *byte, length uint32, written *uint32) -> (success bool)
|
||||
}
|
||||
}
|
|
@ -42,8 +42,9 @@ const (
|
|||
)
|
||||
|
||||
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},
|
||||
Return: []cpu.Register{X0, X1, X2},
|
||||
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},
|
||||
}
|
|
@ -122,6 +122,21 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
|||
|
||||
for i, param := range slices.Backward(parameters) {
|
||||
if !types.Is(param.Type(), fn.Input[i].Typ) {
|
||||
_, isPointer := fn.Input[i].Typ.(*types.Pointer)
|
||||
|
||||
if isPointer {
|
||||
number, isInt := param.(*ssa.Int)
|
||||
|
||||
if isInt && number.Int == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Temporary hack to allow int64 -> uint32 conversion
|
||||
if types.Is(param.Type(), types.AnyInt) && types.Is(fn.Input[i].Typ, types.AnyInt) {
|
||||
continue
|
||||
}
|
||||
|
||||
return nil, errors.New(&TypeMismatch{
|
||||
Encountered: param.Type().Name(),
|
||||
Expected: fn.Input[i].Typ.Name(),
|
||||
|
|
|
@ -2,8 +2,9 @@ package cpu
|
|||
|
||||
// CPU represents the processor.
|
||||
type CPU struct {
|
||||
Call []Register
|
||||
Syscall []Register
|
||||
ExternCall []Register
|
||||
Return []Register
|
||||
Call []Register
|
||||
Syscall []Register
|
||||
ExternCall []Register
|
||||
ExternCallVolatile []Register
|
||||
Return []Register
|
||||
}
|
|
@ -2,7 +2,6 @@ package ssa2asm
|
|||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"git.urbach.dev/cli/q/src/asm"
|
||||
"git.urbach.dev/cli/q/src/ssa"
|
||||
|
@ -17,38 +16,13 @@ func (f *Compiler) GenerateAssembly(ir ssa.IR, isLeaf bool) {
|
|||
}
|
||||
|
||||
for instr := range ir.Values {
|
||||
if instr.CountUsers() != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
switch instr := instr.(type) {
|
||||
case *ssa.Call:
|
||||
fn := instr.Arguments[0].(*ssa.Function)
|
||||
args := instr.Arguments[1:]
|
||||
|
||||
if fn.IsExtern {
|
||||
for i := range slices.Backward(args) {
|
||||
f.ValueToRegister(args[i], f.CPU.ExternCall[i])
|
||||
}
|
||||
|
||||
dot := strings.IndexByte(fn.UniqueName, '.')
|
||||
library := fn.UniqueName[:dot]
|
||||
function := fn.UniqueName[dot+1:]
|
||||
f.Assembler.Append(&asm.CallExtern{Library: library, Function: function})
|
||||
} else {
|
||||
offset := 0
|
||||
|
||||
for i := range slices.Backward(args) {
|
||||
structure, isStruct := args[i].(*ssa.Struct)
|
||||
|
||||
if isStruct {
|
||||
for _, field := range structure.Arguments {
|
||||
f.ValueToRegister(field, f.CPU.Call[offset+i])
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
f.ValueToRegister(args[i], f.CPU.Call[offset+i])
|
||||
}
|
||||
}
|
||||
|
||||
f.Assembler.Append(&asm.Call{Label: fn.UniqueName})
|
||||
}
|
||||
case *ssa.Call, *ssa.Syscall:
|
||||
f.ValueToRegister(instr, f.CPU.Return[0])
|
||||
|
||||
case *ssa.Return:
|
||||
for i := range slices.Backward(instr.Arguments) {
|
||||
|
@ -56,13 +30,6 @@ func (f *Compiler) GenerateAssembly(ir ssa.IR, isLeaf bool) {
|
|||
}
|
||||
|
||||
f.Assembler.Append(&asm.Return{})
|
||||
|
||||
case *ssa.Syscall:
|
||||
for i := range slices.Backward(instr.Arguments) {
|
||||
f.ValueToRegister(instr.Arguments[i], f.CPU.Syscall[i])
|
||||
}
|
||||
|
||||
f.Assembler.Append(&asm.Syscall{})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package ssa2asm
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"git.urbach.dev/cli/q/src/asm"
|
||||
"git.urbach.dev/cli/q/src/cpu"
|
||||
"git.urbach.dev/cli/q/src/ssa"
|
||||
|
@ -19,6 +22,47 @@ func (f *Compiler) ValueToRegister(instr ssa.Value, destination cpu.Register) {
|
|||
Label: label.Name,
|
||||
})
|
||||
|
||||
case *ssa.Call:
|
||||
fn := instr.Arguments[0].(*ssa.Function)
|
||||
args := instr.Arguments[1:]
|
||||
|
||||
if fn.IsExtern {
|
||||
for i := range slices.Backward(args) {
|
||||
f.ValueToRegister(args[i], f.CPU.ExternCall[i])
|
||||
}
|
||||
|
||||
dot := strings.IndexByte(fn.UniqueName, '.')
|
||||
library := fn.UniqueName[:dot]
|
||||
function := fn.UniqueName[dot+1:]
|
||||
f.Assembler.Append(&asm.CallExtern{Library: library, Function: function})
|
||||
} else {
|
||||
offset := 0
|
||||
|
||||
for i := range slices.Backward(args) {
|
||||
structure, isStruct := args[i].(*ssa.Struct)
|
||||
|
||||
if isStruct {
|
||||
for _, field := range structure.Arguments {
|
||||
f.ValueToRegister(field, f.CPU.Call[offset+i])
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
f.ValueToRegister(args[i], f.CPU.Call[offset+i])
|
||||
}
|
||||
}
|
||||
|
||||
f.Assembler.Append(&asm.Call{Label: fn.UniqueName})
|
||||
}
|
||||
|
||||
if destination == f.CPU.Return[0] {
|
||||
return
|
||||
}
|
||||
|
||||
f.Assembler.Append(&asm.MoveRegisterRegister{
|
||||
Destination: destination,
|
||||
Source: f.CPU.Return[0],
|
||||
})
|
||||
|
||||
case *ssa.Int:
|
||||
f.Assembler.Append(&asm.MoveRegisterNumber{
|
||||
Destination: destination,
|
||||
|
@ -52,6 +96,12 @@ func (f *Compiler) ValueToRegister(instr ssa.Value, destination cpu.Register) {
|
|||
})
|
||||
|
||||
case *ssa.Syscall:
|
||||
for i := range slices.Backward(instr.Arguments) {
|
||||
f.ValueToRegister(instr.Arguments[i], f.CPU.Syscall[i])
|
||||
}
|
||||
|
||||
f.Assembler.Append(&asm.Syscall{})
|
||||
|
||||
if destination == f.CPU.Return[0] {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -22,8 +22,9 @@ const (
|
|||
)
|
||||
|
||||
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},
|
||||
Return: []cpu.Register{R0, R7, R6},
|
||||
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},
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue