Added call registers
This commit is contained in:
parent
735057ac74
commit
dc497ba4fb
@ -1,8 +1,4 @@
|
|||||||
main() {
|
main() {
|
||||||
hello()
|
|
||||||
}
|
|
||||||
|
|
||||||
hello() {
|
|
||||||
address := 0
|
address := 0
|
||||||
length := 0
|
length := 0
|
||||||
|
|
||||||
@ -15,6 +11,7 @@ hello() {
|
|||||||
length *= 10
|
length *= 10
|
||||||
length /= 100
|
length /= 100
|
||||||
length = (0 + 50 - 20) * 10 / 100
|
length = (0 + 50 - 20) * 10 / 100
|
||||||
|
length = 1
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
print(address, length)
|
print(address, length)
|
||||||
@ -22,7 +19,7 @@ hello() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print(address, length) {
|
print(address, length) {
|
||||||
write(1, address, length)
|
write(length, address, length+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
write(fd, address, length) {
|
write(fd, address, length) {
|
||||||
|
@ -33,6 +33,32 @@ func (f *Function) Execute(operation token.Token, register cpu.Register, value *
|
|||||||
return f.ExecuteRegisterRegister(operation, register, temporary)
|
return f.ExecuteRegisterRegister(operation, register, temporary)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteFunctionCall executes a function call.
|
||||||
|
func (f *Function) ExecuteFunctionCall(expr *expression.Expression) error {
|
||||||
|
funcName := expr.Children[0].Token.Text()
|
||||||
|
parameters := expr.Children[1:]
|
||||||
|
|
||||||
|
if funcName == "syscall" {
|
||||||
|
err := f.ExpressionsToRegisters(parameters, f.CPU.Syscall)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Assembler.Syscall()
|
||||||
|
} else {
|
||||||
|
err := f.ExpressionsToRegisters(parameters, f.CPU.Call)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Assembler.Call(funcName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ExecuteLeaf performs an operation on a register with the given leaf operand.
|
// ExecuteLeaf performs an operation on a register with the given leaf operand.
|
||||||
func (f *Function) ExecuteLeaf(operation token.Token, register cpu.Register, operand token.Token) error {
|
func (f *Function) ExecuteLeaf(operation token.Token, register cpu.Register, operand token.Token) error {
|
||||||
switch operand.Kind {
|
switch operand.Kind {
|
||||||
|
@ -113,7 +113,7 @@ func (f *Function) CompileInstruction(line token.List) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isFunctionCall(expr) {
|
if isFunctionCall(expr) {
|
||||||
return f.CompileFunctionCall(expr)
|
return f.ExecuteFunctionCall(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.New(&errors.InvalidInstruction{Instruction: expr.Token.Text()}, f.File, expr.Token.Position)
|
return errors.New(&errors.InvalidInstruction{Instruction: expr.Token.Text()}, f.File, expr.Token.Position)
|
||||||
@ -139,6 +139,19 @@ func (f *Function) ExpressionToRegister(root *expression.Expression, register cp
|
|||||||
return f.Execute(operation, register, right)
|
return f.Execute(operation, register, right)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExpressionsToRegisters moves multiple expressions into the specified registers.
|
||||||
|
func (f *Function) ExpressionsToRegisters(expressions []*expression.Expression, registers []cpu.Register) error {
|
||||||
|
for i := len(expressions) - 1; i >= 0; i-- {
|
||||||
|
err := f.ExpressionToRegister(expressions[i], registers[i])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// TokenToRegister moves a token into a register.
|
// TokenToRegister moves a token into a register.
|
||||||
// It only works with identifiers, numbers and strings.
|
// It only works with identifiers, numbers and strings.
|
||||||
func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
|
func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CompileFunctionCall compiles a top-level function call.
|
|
||||||
func (f *Function) CompileFunctionCall(expr *expression.Expression) error {
|
|
||||||
funcName := expr.Children[0].Token.Text()
|
|
||||||
parameters := expr.Children[1:]
|
|
||||||
registers := f.CPU.Syscall
|
|
||||||
|
|
||||||
if funcName != "syscall" {
|
|
||||||
registers = registers[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := len(parameters) - 1; i >= 0; i-- {
|
|
||||||
err := f.ExpressionToRegister(parameters[i], registers[i])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if funcName == "syscall" {
|
|
||||||
f.Assembler.Syscall()
|
|
||||||
} else {
|
|
||||||
f.Assembler.Call(funcName)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -29,12 +29,12 @@ func (f *Function) CompileVariableDefinition(expr *expression.Expression) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
f.CPU.Use(reg)
|
variable := &Variable{
|
||||||
|
|
||||||
f.Variables[name] = &Variable{
|
|
||||||
Name: name,
|
Name: name,
|
||||||
Register: reg,
|
Register: reg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.Variables[name] = variable
|
||||||
|
f.CPU.Use(reg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,9 @@ const (
|
|||||||
R15
|
R15
|
||||||
)
|
)
|
||||||
|
|
||||||
var GeneralRegisters = []cpu.Register{RBX, RBP, R12, R13, R14, R15}
|
var (
|
||||||
var SyscallRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9}
|
CallRegisters = []cpu.Register{RDI, RSI, RDX, RCX, R8, R9}
|
||||||
var ReturnValueRegisters = []cpu.Register{RAX, RCX, R11}
|
GeneralRegisters = []cpu.Register{RBX, RBP, R12, R13, R14, R15}
|
||||||
|
SyscallRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9}
|
||||||
|
ReturnValueRegisters = []cpu.Register{RAX, RCX, R11}
|
||||||
|
)
|
||||||
|
@ -2,6 +2,7 @@ package cpu
|
|||||||
|
|
||||||
// CPU represents the processor.
|
// CPU represents the processor.
|
||||||
type CPU struct {
|
type CPU struct {
|
||||||
|
Call []Register
|
||||||
General []Register
|
General []Register
|
||||||
Syscall []Register
|
Syscall []Register
|
||||||
Return []Register
|
Return []Register
|
||||||
|
@ -225,6 +225,7 @@ func scanFile(path string, functions chan<- *Function) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpu := cpu.CPU{
|
cpu := cpu.CPU{
|
||||||
|
Call: x64.CallRegisters,
|
||||||
General: x64.GeneralRegisters,
|
General: x64.GeneralRegisters,
|
||||||
Syscall: x64.SyscallRegisters,
|
Syscall: x64.SyscallRegisters,
|
||||||
Return: x64.ReturnValueRegisters,
|
Return: x64.ReturnValueRegisters,
|
||||||
|
Loading…
Reference in New Issue
Block a user