private Rvalue compileImpl(IntermediateCompiler ic, Scope scope, CType leftType, CType rightType) throws SyntaxException { // Compile operands. Rvalue rhs = right.compileWithConversion(ic, scope, rightType); Lvalue lhs = left.compileAsLvalue(ic, scope, false); // Load LHS to register. Rvalue lhsVal = new Rvalue(new VirtualRegister()); ic.emit("load", lhsVal.getRegister(), "0", lhs.getRegister()); lhsVal = left.getType(scope).compileConversion(ic, scope, lhsVal, leftType); // Compile the binary operator. String binOp = operator.binaryOperator; Rvalue retVal; if (leftType.isPointer()) { // Scale integer operand if necessary. int leftIncrSize = left.getType(scope).decay().getIncrementSize(); if (leftIncrSize > 1) ic.emit("mul", rhs.getRegister(), "=" + leftIncrSize); ic.emit(operator.mnemonic, lhsVal.getRegister(), rhs.getRegister()); retVal = lhsVal; } else if (operator.type == BinaryExpression.Type.BITWISE) retVal = leftType.compileBinaryBitwiseOperator(ic, scope, lhsVal, rhs, binOp); else if (operator.type == BinaryExpression.Type.SHIFT) retVal = leftType.compileBinaryShiftOperator(ic, scope, lhsVal, rhs, binOp); else // if (operator.type == BinaryExpression.Type.ARITHMETIC) retVal = leftType.compileBinaryArithmeticOperator(ic, scope, lhsVal, rhs, binOp); // Convert to the original type of the left operand. retVal = leftType.compileConversion(ic, scope, retVal, left.getType(scope)); // Assign result back to lvalue. ic.emit("store", retVal.getRegister(), "0", lhs.getRegister()); return retVal; }
@Override public Rvalue compile(IntermediateCompiler ic, Scope scope) throws SyntaxException { FunctionType funcType = getFunctionType(scope); // Reserve space for return value. if (!funcType.getReturnType().equals(CType.VOID)) ic.emit("add", VirtualRegister.SP, "=" + funcType.getReturnType().getSize()); // Push arguments to stack. argumentList.compile(ic, scope, funcType.getParameterTypes()); // Evaluate the function pointer. Rvalue funcPtrVal = functionPointer.compile(ic, scope); // Make the call. ic.emit("call", VirtualRegister.SP, funcPtrVal.getRegister()); // Read the return value. VirtualRegister retReg = null; if (!funcType.getReturnType().equals(CType.VOID)) { retReg = new VirtualRegister(); ic.emit("pop", VirtualRegister.SP, retReg); } return new Rvalue(retReg); }
private Rvalue compileSimpleAssignment(IntermediateCompiler ic, Scope scope) throws SyntaxException { Rvalue rhs = right.compileWithConversion(ic, scope, left.getType(scope).decay()); Lvalue lhs = left.compileAsLvalue(ic, scope, false); ic.emit("store", rhs.getRegister(), "0", lhs.getRegister()); return rhs; }
@Override public void compile(IntermediateCompiler ic, Scope scope, StackAllocator stack) throws SyntaxException { Symbol jumpPosition = scope.find("__Brk"); if (jumpPosition == null) throw new SyntaxException("Break used outside loop or switch.", getPosition()); // Jump to end of the loop/switch ic.emit("jump", VirtualRegister.NONE, jumpPosition.getReference()); }