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) {
|
write(buffer string) -> (written int) {
|
||||||
return 0
|
stdout := kernel32.GetStdHandle(-11)
|
||||||
|
kernel32.WriteConsoleA(stdout, buffer.ptr, buffer.len, 0)
|
||||||
|
return buffer.len
|
||||||
}
|
}
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
kernel32 {
|
kernel32 {
|
||||||
GetStdHandle(handle int64) -> int64
|
GetStdHandle(device int64) -> (handle int64)
|
||||||
WriteConsoleA(fd int64, buffer *byte, length uint32, written *uint32) -> bool
|
WriteConsoleA(fd int64, buffer *byte, length uint32, written *uint32) -> (success bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -45,5 +45,6 @@ var CPU = cpu.CPU{
|
||||||
Call: []cpu.Register{X0, X1, X2, X3, X4, X5, X6},
|
Call: []cpu.Register{X0, X1, X2, X3, X4, X5, X6},
|
||||||
Syscall: []cpu.Register{X8, X0, X1, X2, X3, X4, X5},
|
Syscall: []cpu.Register{X8, X0, X1, X2, X3, X4, X5},
|
||||||
ExternCall: []cpu.Register{X0, X1, X2, X3, X4, X5, X6, X7},
|
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},
|
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) {
|
for i, param := range slices.Backward(parameters) {
|
||||||
if !types.Is(param.Type(), fn.Input[i].Typ) {
|
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{
|
return nil, errors.New(&TypeMismatch{
|
||||||
Encountered: param.Type().Name(),
|
Encountered: param.Type().Name(),
|
||||||
Expected: fn.Input[i].Typ.Name(),
|
Expected: fn.Input[i].Typ.Name(),
|
||||||
|
|
|
@ -5,5 +5,6 @@ type CPU struct {
|
||||||
Call []Register
|
Call []Register
|
||||||
Syscall []Register
|
Syscall []Register
|
||||||
ExternCall []Register
|
ExternCall []Register
|
||||||
|
ExternCallVolatile []Register
|
||||||
Return []Register
|
Return []Register
|
||||||
}
|
}
|
|
@ -2,7 +2,6 @@ package ssa2asm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.urbach.dev/cli/q/src/asm"
|
"git.urbach.dev/cli/q/src/asm"
|
||||||
"git.urbach.dev/cli/q/src/ssa"
|
"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 {
|
for instr := range ir.Values {
|
||||||
|
if instr.CountUsers() != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
switch instr := instr.(type) {
|
switch instr := instr.(type) {
|
||||||
case *ssa.Call:
|
case *ssa.Call, *ssa.Syscall:
|
||||||
fn := instr.Arguments[0].(*ssa.Function)
|
f.ValueToRegister(instr, f.CPU.Return[0])
|
||||||
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.Return:
|
case *ssa.Return:
|
||||||
for i := range slices.Backward(instr.Arguments) {
|
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{})
|
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
|
package ssa2asm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"git.urbach.dev/cli/q/src/asm"
|
"git.urbach.dev/cli/q/src/asm"
|
||||||
"git.urbach.dev/cli/q/src/cpu"
|
"git.urbach.dev/cli/q/src/cpu"
|
||||||
"git.urbach.dev/cli/q/src/ssa"
|
"git.urbach.dev/cli/q/src/ssa"
|
||||||
|
@ -19,6 +22,47 @@ func (f *Compiler) ValueToRegister(instr ssa.Value, destination cpu.Register) {
|
||||||
Label: label.Name,
|
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:
|
case *ssa.Int:
|
||||||
f.Assembler.Append(&asm.MoveRegisterNumber{
|
f.Assembler.Append(&asm.MoveRegisterNumber{
|
||||||
Destination: destination,
|
Destination: destination,
|
||||||
|
@ -52,6 +96,12 @@ func (f *Compiler) ValueToRegister(instr ssa.Value, destination cpu.Register) {
|
||||||
})
|
})
|
||||||
|
|
||||||
case *ssa.Syscall:
|
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] {
|
if destination == f.CPU.Return[0] {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,5 +25,6 @@ var CPU = cpu.CPU{
|
||||||
Call: []cpu.Register{R0, R7, R6, R2, R10, R8, R9},
|
Call: []cpu.Register{R0, R7, R6, R2, R10, R8, R9},
|
||||||
Syscall: []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},
|
ExternCall: []cpu.Register{R1, R2, R8, R9},
|
||||||
|
ExternCallVolatile: []cpu.Register{R0, R1, R2, R8, R9, R10, R11},
|
||||||
Return: []cpu.Register{R0, R7, R6},
|
Return: []cpu.Register{R0, R7, R6},
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue