/** * Rewrites a move instruction if it has 2 memory operands. One of the 2 memory operands must be a * stack location operand. Move the SP to the appropriate location and use a push or pop * instruction. * * @param s the instruction to rewrite */ private void rewriteMoveInstruction(Instruction s) { // first attempt to mutate the move into a noop if (mutateMoveToNop(s)) return; Operand result = MIR_Move.getResult(s); Operand val = MIR_Move.getValue(s); if (result instanceof StackLocationOperand) { if (val instanceof MemoryOperand || val instanceof StackLocationOperand) { int offset = ((StackLocationOperand) result).getOffset(); byte size = ((StackLocationOperand) result).getSize(); offset = FPOffset2SPOffset(offset) + size; moveESPBefore(s, offset); MIR_UnaryNoRes.mutate(s, IA32_PUSH, val); } } else { if (result instanceof MemoryOperand) { if (val instanceof StackLocationOperand) { int offset = ((StackLocationOperand) val).getOffset(); offset = FPOffset2SPOffset(offset); moveESPBefore(s, offset); MIR_Nullary.mutate(s, IA32_POP, result); } } } }
/** * expand an FCLEAR pseudo-insruction using FFREEs. * * @param s the instruction to expand * @param ir the containing IR */ private static void expandFClear(Instruction s, IR ir) { int nSave = MIR_UnaryNoRes.getVal(s).asIntConstant().value; int fpStackHeight = ir.MIRInfo.fpStackHeight; PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asIA32(); for (int i = nSave; i < fpStackHeight; i++) { Register f = phys.getFPR(i); s.insertBefore(MIR_Nullary.create(IA32_FFREE, D(f))); } // Remove the FCLEAR. s.remove(); }
/** * Insert the epilogue before a particular return instruction. * * @param ret the return instruction. */ private void insertEpilogue(Instruction ret) { // 1. Restore any saved registers if (ir.compiledMethod.isSaveVolatile()) { restoreVolatileRegisters(ret); restoreFloatingPointState(ret); } restoreNonVolatiles(ret); // 2. Restore caller's stackpointer and framepointer int frameSize = getFrameFixedSize(); ret.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP, IC(frameSize))); MemoryOperand fpHome = MemoryOperand.BD( ir.regpool.makeTROp(), ArchEntrypoints.framePointerField.getOffset(), (byte) WORDSIZE, null, null); ret.insertBefore(MIR_Nullary.create(IA32_POP, fpHome)); }