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