Added CPU type
This commit is contained in:
parent
1058970be3
commit
4faa1641c6
@ -18,8 +18,8 @@ func TestErrors(t *testing.T) {
|
||||
{"ExpectedFunctionDefinition.q", errors.ExpectedFunctionDefinition},
|
||||
{"ExpectedFunctionName.q", errors.ExpectedFunctionName},
|
||||
{"ExpectedFunctionParameters.q", errors.ExpectedFunctionParameters},
|
||||
{"InvalidInstruction-Identifier.q", &errors.InvalidInstruction{Instruction: "abc"}},
|
||||
{"InvalidInstruction-Number.q", &errors.InvalidInstruction{Instruction: "123"}},
|
||||
{"InvalidInstructionIdentifier.q", &errors.InvalidInstruction{Instruction: "abc"}},
|
||||
{"InvalidInstructionNumber.q", &errors.InvalidInstruction{Instruction: "123"}},
|
||||
{"MissingAssignValue.q", errors.MissingAssignValue},
|
||||
{"MissingBlockEnd.q", errors.MissingBlockEnd},
|
||||
{"MissingBlockStart.q", errors.MissingBlockStart},
|
||||
|
@ -29,8 +29,8 @@ func Finalize(functions map[string]*Function) ([]byte, []byte) {
|
||||
func entry() *asm.Assembler {
|
||||
entry := asm.New()
|
||||
entry.Call("main")
|
||||
entry.MoveRegisterNumber(x64.SyscallArgs[0], linux.Exit)
|
||||
entry.MoveRegisterNumber(x64.SyscallArgs[1], 0)
|
||||
entry.MoveRegisterNumber(x64.SyscallRegisters[0], linux.Exit)
|
||||
entry.MoveRegisterNumber(x64.SyscallRegisters[1], 0)
|
||||
entry.Syscall()
|
||||
return entry
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
||||
"git.akyoto.dev/cli/q/src/build/asm"
|
||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
||||
"git.akyoto.dev/cli/q/src/build/expression"
|
||||
"git.akyoto.dev/cli/q/src/build/fs"
|
||||
"git.akyoto.dev/cli/q/src/build/token"
|
||||
@ -21,6 +21,7 @@ type Function struct {
|
||||
Body token.List
|
||||
Variables map[string]*Variable
|
||||
Assembler asm.Assembler
|
||||
CPU cpu.CPU
|
||||
Error error
|
||||
}
|
||||
|
||||
@ -169,12 +170,12 @@ func (f *Function) CompileFunctionCall(expr *expression.Expression) error {
|
||||
}
|
||||
|
||||
n, _ := strconv.Atoi(variable.Value.Token.Text())
|
||||
f.Assembler.MoveRegisterNumber(x64.SyscallArgs[i], uint64(n))
|
||||
f.Assembler.MoveRegisterNumber(f.CPU.Syscall[i], uint64(n))
|
||||
|
||||
case token.Number:
|
||||
value := parameter.Token.Text()
|
||||
n, _ := strconv.Atoi(value)
|
||||
f.Assembler.MoveRegisterNumber(x64.SyscallArgs[i], uint64(n))
|
||||
f.Assembler.MoveRegisterNumber(f.CPU.Syscall[i], uint64(n))
|
||||
|
||||
default:
|
||||
panic("Unknown expression")
|
||||
|
28
src/build/arch/x64/Registers.go
Normal file
28
src/build/arch/x64/Registers.go
Normal file
@ -0,0 +1,28 @@
|
||||
package x64
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
||||
|
||||
const (
|
||||
rax = iota
|
||||
rcx
|
||||
rdx
|
||||
rbx
|
||||
rsp
|
||||
rbp
|
||||
rsi
|
||||
rdi
|
||||
r8
|
||||
r9
|
||||
r10
|
||||
r11
|
||||
r12
|
||||
r13
|
||||
r14
|
||||
r15
|
||||
)
|
||||
|
||||
const SyscallReturn = rax
|
||||
|
||||
var GeneralRegisters = []cpu.Register{rbx, rbp, r12, r13, r14, r15}
|
||||
var SyscallRegisters = []cpu.Register{rax, rdi, rsi, rdx, r10, r8, r9}
|
||||
var ReturnValueRegisters = []cpu.Register{rax, rcx, r11}
|
@ -1,13 +1,5 @@
|
||||
package x64
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
||||
|
||||
const (
|
||||
SyscallReturn = 0 // rax
|
||||
)
|
||||
|
||||
var SyscallArgs = []cpu.Register{0, 7, 6, 2, 10, 8, 9}
|
||||
|
||||
// Syscall is the primary way to communicate with the OS kernel.
|
||||
func Syscall(code []byte) []byte {
|
||||
return append(code, 0x0f, 0x05)
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// compile waits for all functions to finish compilation.
|
||||
// compile waits for the scan to finish and compiles all functions.
|
||||
func compile(functions <-chan *Function, errors <-chan error) (map[string]*Function, error) {
|
||||
allFunctions := map[string]*Function{}
|
||||
|
||||
@ -28,18 +28,7 @@ func compile(functions <-chan *Function, errors <-chan error) (map[string]*Funct
|
||||
}
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
for _, function := range allFunctions {
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
function.Compile()
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
compileFunctions(allFunctions)
|
||||
|
||||
for _, function := range allFunctions {
|
||||
if function.Error != nil {
|
||||
@ -49,3 +38,19 @@ func compile(functions <-chan *Function, errors <-chan error) (map[string]*Funct
|
||||
|
||||
return allFunctions, nil
|
||||
}
|
||||
|
||||
// compileFunctions starts a goroutine for each function compilation and waits for completion.
|
||||
func compileFunctions(functions map[string]*Function) {
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
for _, function := range functions {
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
function.Compile()
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
31
src/build/cpu/CPU.go
Normal file
31
src/build/cpu/CPU.go
Normal file
@ -0,0 +1,31 @@
|
||||
package cpu
|
||||
|
||||
// CPU represents the processor.
|
||||
type CPU struct {
|
||||
General []Register
|
||||
Syscall []Register
|
||||
Return []Register
|
||||
usage uint64
|
||||
}
|
||||
|
||||
func (c *CPU) Use(reg Register) {
|
||||
c.usage |= (1 << reg)
|
||||
}
|
||||
|
||||
func (c *CPU) Free(reg Register) {
|
||||
c.usage &= ^(1 << reg)
|
||||
}
|
||||
|
||||
func (c *CPU) IsFree(reg Register) bool {
|
||||
return c.usage&(1<<reg) == 0
|
||||
}
|
||||
|
||||
func (c *CPU) FindFree() (Register, bool) {
|
||||
for _, reg := range c.General {
|
||||
if c.IsFree(reg) {
|
||||
return reg, true
|
||||
}
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
@ -6,6 +6,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
||||
"git.akyoto.dev/cli/q/src/build/fs"
|
||||
"git.akyoto.dev/cli/q/src/build/token"
|
||||
"git.akyoto.dev/cli/q/src/errors"
|
||||
@ -225,6 +227,11 @@ func scanFile(path string, functions chan<- *Function) error {
|
||||
Head: tokens[paramsStart:bodyStart],
|
||||
Body: tokens[bodyStart : i+1],
|
||||
Variables: map[string]*Variable{},
|
||||
CPU: cpu.CPU{
|
||||
General: x64.GeneralRegisters,
|
||||
Syscall: x64.SyscallRegisters,
|
||||
Return: x64.ReturnValueRegisters,
|
||||
},
|
||||
}
|
||||
|
||||
nameStart = -1
|
||||
|
Loading…
Reference in New Issue
Block a user