This commit is contained in:
parent
0ece1b092e
commit
59363e2ed3
7 changed files with 75 additions and 38 deletions
|
@ -12,13 +12,10 @@ func showSSA(root *core.Function) {
|
|||
root.EachDependency(make(map[*core.Function]bool), func(f *core.Function) {
|
||||
ansi.Yellow.Println(f.UniqueName + ":")
|
||||
|
||||
for _, block := range f.Blocks {
|
||||
for i, instr := range block.Instructions {
|
||||
ansi.Dim.Printf("%%%-1d = ", i)
|
||||
fmt.Printf("%-30s ", instr.String())
|
||||
ansi.Dim.Printf(" %-30s", instr.Type().Name())
|
||||
fmt.Println()
|
||||
}
|
||||
for i, step := range f.Steps {
|
||||
ansi.Dim.Printf("%%%d = ", i)
|
||||
fmt.Print(step.Value.String())
|
||||
ansi.Dim.Printf(" %s %s %s\n", step.Value.Type().Name(), step.Register, step.Live)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
package core
|
||||
|
||||
import "git.urbach.dev/cli/q/src/types"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.urbach.dev/cli/q/src/ssa"
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
// Compile turns a function into machine code.
|
||||
func (f *Function) Compile() {
|
||||
|
@ -11,14 +16,29 @@ func (f *Function) Compile() {
|
|||
continue
|
||||
}
|
||||
|
||||
input.Index = uint8(offset + i)
|
||||
f.Append(input)
|
||||
f.Identifiers[input.Name] = input
|
||||
structure, isStruct := input.Typ.(*types.Struct)
|
||||
structType, isStructType := input.Typ.(*types.Struct)
|
||||
|
||||
if isStruct {
|
||||
offset += len(structure.Fields) - 1
|
||||
if isStructType {
|
||||
for _, field := range structType.Fields {
|
||||
param := &ssa.Parameter{
|
||||
Index: uint8(offset + i),
|
||||
Name: fmt.Sprintf("%s.%s", input.Name, field.Name),
|
||||
Typ: field.Type,
|
||||
Source: input.Source,
|
||||
}
|
||||
|
||||
f.Identifiers[param.Name] = param
|
||||
f.Append(param)
|
||||
offset++
|
||||
}
|
||||
|
||||
offset--
|
||||
continue
|
||||
}
|
||||
|
||||
input.Index = uint8(offset + i)
|
||||
f.Identifiers[input.Name] = input
|
||||
f.Append(input)
|
||||
}
|
||||
|
||||
for instr := range f.Body.Instructions {
|
||||
|
|
|
@ -169,27 +169,33 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
|||
right := expr.Children[1]
|
||||
leftText := left.String(f.File.Bytes)
|
||||
rightText := right.String(f.File.Bytes)
|
||||
identifier, exists := f.Identifiers[leftText]
|
||||
fullName := fmt.Sprintf("%s.%s", leftText, rightText)
|
||||
identifier, exists := f.Identifiers[fullName]
|
||||
|
||||
if exists {
|
||||
structure := identifier.Type().(*types.Struct)
|
||||
field := structure.FieldByName(rightText)
|
||||
|
||||
if field == nil {
|
||||
return nil, errors.New(&UnknownStructField{StructName: structure.Name(), FieldName: rightText}, f.File, right.Token.Position)
|
||||
return identifier, nil
|
||||
}
|
||||
|
||||
v := f.Append(&ssa.Field{
|
||||
Object: identifier,
|
||||
Field: field,
|
||||
Source: ssa.Source(expr.Source),
|
||||
})
|
||||
// identifier, exists := f.Identifiers[leftText]
|
||||
|
||||
return v, nil
|
||||
}
|
||||
// if exists {
|
||||
// structType := identifier.Type().(*types.Struct)
|
||||
// field := structType.FieldByName(rightText)
|
||||
|
||||
label := fmt.Sprintf("%s.%s", leftText, rightText)
|
||||
function, exists := f.All.Functions[label]
|
||||
// if field == nil {
|
||||
// return nil, errors.New(&UnknownStructField{StructName: structType.Name(), FieldName: rightText}, f.File, right.Token.Position)
|
||||
// }
|
||||
|
||||
// v := f.Append(&ssa.Field{
|
||||
// Object: identifier,
|
||||
// Field: field,
|
||||
// Source: ssa.Source(expr.Source),
|
||||
// })
|
||||
|
||||
// return v, nil
|
||||
// }
|
||||
|
||||
function, exists := f.All.Functions[fullName]
|
||||
|
||||
if exists {
|
||||
if function.IsExtern() {
|
||||
|
@ -208,7 +214,7 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
|||
return v, nil
|
||||
}
|
||||
|
||||
return nil, errors.New(&UnknownIdentifier{Name: label}, f.File, left.Token.Position)
|
||||
return nil, errors.New(&UnknownIdentifier{Name: fullName}, f.File, left.Token.Position)
|
||||
|
||||
default:
|
||||
if expr.Token.IsOperator() {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
type Compiler struct {
|
||||
UniqueName string
|
||||
Assembler asm.Assembler
|
||||
Steps []Step
|
||||
ValueToStep map[ssa.Value]*Step
|
||||
CPU *cpu.CPU
|
||||
Count Count
|
||||
|
|
|
@ -65,6 +65,12 @@ func (f *Compiler) CreateSteps(ir ssa.IR) []Step {
|
|||
}
|
||||
|
||||
liveStart := i
|
||||
_, isParam := instr.(*ssa.Parameter)
|
||||
|
||||
if isParam {
|
||||
liveStart = 0
|
||||
}
|
||||
|
||||
liveEnd := f.ValueToStep[users[len(users)-1]].Index
|
||||
instrStep := f.ValueToStep[instr]
|
||||
|
||||
|
@ -79,12 +85,19 @@ func (f *Compiler) CreateSteps(ir ssa.IR) []Step {
|
|||
continue
|
||||
}
|
||||
|
||||
oldRegister := cpu.Register(-1)
|
||||
liveParam, isParam := live.Value.(*ssa.Parameter)
|
||||
|
||||
if isParam {
|
||||
oldRegister = f.CPU.Call[liveParam.Index]
|
||||
}
|
||||
|
||||
for _, existing := range step.Live[:liveIndex] {
|
||||
if existing.Register == -1 {
|
||||
continue
|
||||
}
|
||||
|
||||
if existing.Register == live.Register {
|
||||
if existing.Register == live.Register || existing.Register == oldRegister {
|
||||
a := existing.Index
|
||||
b := live.Index
|
||||
freeRegister := cpu.Register(15)
|
||||
|
|
|
@ -114,9 +114,9 @@ func (f *Compiler) Exec(step *Step) {
|
|||
})
|
||||
|
||||
case *ssa.Field:
|
||||
parameter := instr.Object.(*ssa.Parameter)
|
||||
field := instr.Field
|
||||
source := f.CPU.Call[parameter.Index+field.Index]
|
||||
structure := instr.Object.(*ssa.Struct)
|
||||
field := structure.Arguments[instr.Field.Index]
|
||||
source := f.ValueToStep[field].Register
|
||||
|
||||
if step.Register == -1 || step.Register == source {
|
||||
return
|
||||
|
|
|
@ -13,9 +13,9 @@ func (f *Compiler) GenerateAssembly(ir ssa.IR, isLeaf bool) {
|
|||
f.Assembler.Append(&asm.FunctionStart{})
|
||||
}
|
||||
|
||||
steps := f.CreateSteps(ir)
|
||||
f.Steps = f.CreateSteps(ir)
|
||||
|
||||
for _, step := range steps {
|
||||
for _, step := range f.Steps {
|
||||
f.Exec(&step)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue