diff options
Diffstat (limited to 'submit/ast/BinaryOperator.java')
-rw-r--r-- | submit/ast/BinaryOperator.java | 89 |
1 files changed, 88 insertions, 1 deletions
diff --git a/submit/ast/BinaryOperator.java b/submit/ast/BinaryOperator.java index d18766b..2545dd0 100644 --- a/submit/ast/BinaryOperator.java +++ b/submit/ast/BinaryOperator.java @@ -4,6 +4,10 @@ */ package submit.ast; +import submit.MIPSResult; +import submit.RegisterAllocator; +import submit.SymbolTable; + /** * * @author edwajohn @@ -13,7 +17,8 @@ public class BinaryOperator extends AbstractNode implements Expression { private final Expression lhs, rhs; private final BinaryOperatorType type; - public BinaryOperator(Expression lhs, BinaryOperatorType type, Expression rhs) { + public BinaryOperator(Expression lhs, BinaryOperatorType type, + Expression rhs) { this.lhs = lhs; this.type = type; this.rhs = rhs; @@ -32,4 +37,86 @@ public class BinaryOperator extends AbstractNode implements Expression { rhs.toCminus(builder, prefix); } + @Override + public MIPSResult toMIPS(StringBuilder code, StringBuilder data, + SymbolTable symbolTable, + RegisterAllocator regAllocator) { + MIPSResult left = lhs.toMIPS(code, data, symbolTable, regAllocator); + String leftRegister = + regAllocator.getRegisterOrLoadIntoRegister(left, code); + + MIPSResult right = rhs.toMIPS(code, data, symbolTable, regAllocator); + String rightRegister = + regAllocator.getRegisterOrLoadIntoRegister(right, code); + String resultRegister = regAllocator.getAny(); + + switch (type) { + case PLUS: + code.append(String.format("add %s %s %s\n", resultRegister, leftRegister, + rightRegister)); + break; + case MINUS: + code.append(String.format("sub %s %s %s\n", resultRegister, leftRegister, + rightRegister)); + break; + case TIMES: + code.append(String.format("mult %s %s\n", leftRegister, rightRegister)) + .append(String.format("mflo %s\n", resultRegister)); + break; + case DIVIDE: + code.append(String.format("div %s %s\n", leftRegister, rightRegister)) + .append(String.format("mflo %s\n", resultRegister)); + break; + case MOD: + code.append(String.format("div %s %s\n", leftRegister, rightRegister)) + .append(String.format("mfhi %s\n", resultRegister)); + break; + case LT: + code.append(String.format("slt %s %s %s\n", resultRegister, leftRegister, + rightRegister)) + .append( + String.format("subi %s %s 1\n", resultRegister, resultRegister)); + break; + case GT: + code.append(String.format("slt %s %s %s\n", resultRegister, rightRegister, + leftRegister)) + .append( + String.format("subi %s %s 1\n", resultRegister, resultRegister)); + break; + case LE: + code.append(String.format("slt %s %s %s\n", resultRegister, rightRegister, + leftRegister)); + break; + case GE: + code.append(String.format("slt %s %s %s\n", resultRegister, leftRegister, + rightRegister)); + break; + case EQ: + code.append(String.format("sub %s %s %s\n", resultRegister, leftRegister, + rightRegister)); + break; + case OR: + code.append(String.format("or %s %s %s\n", resultRegister, leftRegister, + rightRegister)); + break; + case AND: + code.append(String.format("abs %s %s\n", leftRegister, leftRegister)) + .append(String.format("abs %s %s\n", rightRegister, rightRegister)) + .append(String.format("add %s %s %s\n", resultRegister, leftRegister, + rightRegister)); + break; + case NE: + code.append(String.format("xor %s %s %s\n", resultRegister, leftRegister, + rightRegister)) + .append( + String.format("sltiu %s %s 1\n", resultRegister, resultRegister)); + default: + break; + } + + regAllocator.clear(leftRegister); + regAllocator.clear(rightRegister); + + return MIPSResult.createRegisterResult(resultRegister, VarType.INT); + } } |