@Override public InstructionsAndTiming<T> generate( final InstanceOfExprSymbol op, final Platform<T, E> platform) { final InstructionsAndTiming<T> instructions = new InstructionsAndTiming<T>(); final SizeHelper<T, E> sizeHelper = platform.getSizeHelper(); final TileHelper<T, E> tileHelper = platform.getTileHelper(); instructions.addAll(platform.getBest(op.getLeftOperand())); // eax should have reference to object final String nullObjectLbl = "nullObject" + CodeGenVisitor.getNewLblNum(); tileHelper.setupJmpNull(nullObjectLbl, sizeHelper, instructions); instructions.addAll( platform.getObjectLayout().subtypeCheckCode((TypeSymbol) op.getRightOperand(), platform)); final String endLbl = "instanceOfEnd" + CodeGenVisitor.getNewLblNum(); tileHelper.setupJump(endLbl, sizeHelper, instructions); tileHelper.setupLbl(nullObjectLbl, instructions); tileHelper.setupComment("set to false", instructions); tileHelper.loadBool(false, instructions, sizeHelper); tileHelper.setupLbl(endLbl, instructions); return instructions; }
@Override public InstructionsAndTiming<ArmInstruction> generate( SimpleNameSymbol name, Platform<ArmInstruction, Size> platform) { final SizeHelper<ArmInstruction, Size> sizeHelper = platform.getSizeHelper(); final InstructionsAndTiming<ArmInstruction> instructions = new InstructionsAndTiming<>(); final DclSymbol dcl = name.dcl; final String staticFieldLbl = PkgClassResolver.getUniqueNameFor(dcl); instructions.add(new Comment("Moving " + staticFieldLbl + " into R0")); instructions.add( new Movw(Register.R0, new ImmediateStr(":lower16:" + staticFieldLbl), sizeHelper)); instructions.add( new Movt(Register.R0, new ImmediateStr(":upper16:" + staticFieldLbl), sizeHelper)); instructions.add(new Ldr(Register.R0, Register.R0, sizeHelper)); return instructions; }
@Override public InstructionsAndTiming<ArmInstruction> generate( final CastExpressionSymbol symbol, final Platform<ArmInstruction, Size> platform) { final TypeSymbol type = symbol.getType(); final InstructionsAndTiming<ArmInstruction> instructions = new InstructionsAndTiming<ArmInstruction>(); final String castExprEnd = "CastExprEnd" + CodeGenVisitor.getNewLblNum(); final SizeHelper<ArmInstruction, Size> sizeHelper = platform.getSizeHelper(); instructions.addAll(platform.getBest(symbol.getOperandExpression())); platform.getTileHelper().setupJmpNull(castExprEnd, sizeHelper, instructions); instructions.add(new Push(Register.R0)); instructions.addAll(platform.getObjectLayout().subtypeCheckCode(type, platform)); platform.getTileHelper().setupJumpNe(IRuntime.EXCEPTION_LBL, sizeHelper, instructions); instructions.add(new Pop(Register.R0)); instructions.add(platform.makeLabel(castExprEnd)); return instructions; }
@Override public InstructionsAndTiming<ArmInstruction> generate( final ArrayAccessExprSymbol arrayAccess, final Platform<ArmInstruction, Size> platform) { final InstructionsAndTiming<ArmInstruction> instructions = new InstructionsAndTiming<ArmInstruction>(); final SizeHelper<ArmInstruction, Size> sizeHelper = platform.getSizeHelper(); final ObjectLayout<ArmInstruction, Size> objectLayout = platform.getObjectLayout(); final IRuntime<ArmInstruction> runtime = platform.getRunime(); instructions.add(new Comment("Accessing array")); instructions.addAll(platform.getBest(arrayAccess.children.get(0))); platform.getTileHelper().setupJmpNull(IRuntime.EXCEPTION_LBL, sizeHelper, instructions); instructions.add(new Push(Register.R8)); instructions.add(new Mov(Register.R8, Register.R0, sizeHelper)); instructions.addAll(platform.getBest(arrayAccess.children.get(1))); instructions.add(new Comment("Checking element >= 0")); final long myVal = CodeGenVisitor.getNewLblNum(); String ok = "arrayAccessP1Ok" + myVal; instructions.add(new Eor(Register.R1, Register.R1, Register.R1, sizeHelper)); instructions.add(new Cmp(Register.R0, Register.R1, sizeHelper)); instructions.add(new B(Condition.GE, ok)); runtime.throwException(instructions, "Invalid array access"); instructions.add(new Label(ok)); ok = "arrayAccessOk" + myVal; instructions.add( new Ldr( Register.R3, Register.R8, new Immediate12((short) platform.getObjectLayout().objSize()), sizeHelper)); instructions.add(new Cmp(Register.R3, Register.R0, sizeHelper)); instructions.add(new B(Condition.GT, ok)); runtime.throwException(instructions, "Invalid array access"); instructions.add(new Label(ok)); final Size elementSize = sizeHelper.getPushSize(sizeHelper.getSizeOfType(arrayAccess.getType().value)); if (elementSize != Size.B && elementSize != Size.SB) { instructions.add( new Mov( Register.R0, new ConstantShift(Register.R0, ArmSizeHelper.getPowerSizeImd(elementSize), Shift.LSL), sizeHelper)); } final Immediate8 offset = new Immediate8((char) (objectLayout.objSize() + sizeHelper.getDefaultStackSize())); instructions.add(new Add(Register.R0, Register.R0, offset, sizeHelper)); return instructions; }