Improved branch code generation
This commit is contained in:
parent
403e78f655
commit
23b4e6442d
@ -10,41 +10,39 @@ import (
|
|||||||
// CompileIf compiles a branch instruction.
|
// CompileIf compiles a branch instruction.
|
||||||
func (f *Function) CompileIf(branch *ast.If) error {
|
func (f *Function) CompileIf(branch *ast.If) error {
|
||||||
condition := branch.Condition
|
condition := branch.Condition
|
||||||
tmpRight := f.cpu.MustFindFree(f.cpu.General)
|
tmp := f.cpu.MustFindFree(f.cpu.General)
|
||||||
err := f.ExpressionToRegister(condition.Children[1], tmpRight)
|
err := f.ExpressionToRegister(condition.Children[0], tmp)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
f.cpu.Use(tmpRight)
|
f.cpu.Use(tmp)
|
||||||
tmpLeft := f.cpu.Input[0]
|
err = f.Execute(condition.Token, tmp, condition.Children[1])
|
||||||
err = f.ExpressionToRegister(condition.Children[0], tmpLeft)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
f.assembler.RegisterRegister(asm.COMPARE, tmpLeft, tmpRight)
|
f.cpu.Free(tmp)
|
||||||
f.cpu.Free(tmpRight)
|
endLabel := fmt.Sprintf("%s_end_if_%d", f.Name, f.count.branch)
|
||||||
elseLabel := fmt.Sprintf("%s_if_%d_else", f.Name, f.count.branch)
|
|
||||||
|
|
||||||
switch condition.Token.Text() {
|
switch condition.Token.Text() {
|
||||||
case "==":
|
case "==":
|
||||||
f.assembler.Label(asm.JNE, elseLabel)
|
f.assembler.Label(asm.JNE, endLabel)
|
||||||
case "!=":
|
case "!=":
|
||||||
f.assembler.Label(asm.JE, elseLabel)
|
f.assembler.Label(asm.JE, endLabel)
|
||||||
case ">":
|
case ">":
|
||||||
f.assembler.Label(asm.JLE, elseLabel)
|
f.assembler.Label(asm.JLE, endLabel)
|
||||||
case "<":
|
case "<":
|
||||||
f.assembler.Label(asm.JGE, elseLabel)
|
f.assembler.Label(asm.JGE, endLabel)
|
||||||
case ">=":
|
case ">=":
|
||||||
f.assembler.Label(asm.JL, elseLabel)
|
f.assembler.Label(asm.JL, endLabel)
|
||||||
case "<=":
|
case "<=":
|
||||||
f.assembler.Label(asm.JG, elseLabel)
|
f.assembler.Label(asm.JG, endLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer f.assembler.Label(asm.LABEL, elseLabel)
|
defer f.assembler.Label(asm.LABEL, endLabel)
|
||||||
f.count.branch++
|
f.count.branch++
|
||||||
return f.CompileAST(branch.Body)
|
return f.CompileAST(branch.Body)
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,9 @@ func (f *Function) ExecuteRegisterNumber(operation token.Token, register cpu.Reg
|
|||||||
case "/", "/=":
|
case "/", "/=":
|
||||||
f.assembler.RegisterNumber(asm.DIV, register, number)
|
f.assembler.RegisterNumber(asm.DIV, register, number)
|
||||||
|
|
||||||
|
case "==", "!=", "<", "<=", ">", ">=":
|
||||||
|
f.assembler.RegisterNumber(asm.COMPARE, register, number)
|
||||||
|
|
||||||
case "=":
|
case "=":
|
||||||
f.assembler.RegisterNumber(asm.MOVE, register, number)
|
f.assembler.RegisterNumber(asm.MOVE, register, number)
|
||||||
|
|
||||||
|
@ -22,6 +22,9 @@ func (f *Function) ExecuteRegisterRegister(operation token.Token, destination cp
|
|||||||
case "/", "/=":
|
case "/", "/=":
|
||||||
f.assembler.RegisterRegister(asm.DIV, destination, source)
|
f.assembler.RegisterRegister(asm.DIV, destination, source)
|
||||||
|
|
||||||
|
case "==", "!=", "<", "<=", ">", ">=":
|
||||||
|
f.assembler.RegisterRegister(asm.COMPARE, destination, source)
|
||||||
|
|
||||||
case "=":
|
case "=":
|
||||||
if destination != source {
|
if destination != source {
|
||||||
f.assembler.RegisterRegister(asm.MOVE, destination, source)
|
f.assembler.RegisterRegister(asm.MOVE, destination, source)
|
||||||
|
Loading…
Reference in New Issue
Block a user