ptr.insertBefore(Empty.create(IR_ENDPROLOGUE));
  final void insertExceptionalPrologue () {    if (frameSize >= 0x7ff0) {      throw new OPT_OptimizingCompilerException("Stackframe size exceeded!");    }    OPT_PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();    OPT_Register FP = phys.getFP();    OPT_Register PR = phys.getPR();    OPT_Register TSR= phys.getTSR();    OPT_Register R0 = phys.getTemp();    OPT_Register S1 = phys.getGPR(LAST_SCRATCH_GPR);    boolean interruptible = ir.method.isInterruptible();    boolean stackOverflow = interruptible;    boolean yp = hasPrologueYieldpoint();    OPT_Instruction ptr = ir.firstInstructionInCodeOrder().nextInstructionInCodeOrder();    if (VM.VerifyAssertions) VM._assert(ptr.getOpcode() == IR_PROLOGUE_opcode);    // Stack overflow check    if (stackOverflow) {      // R0 is fairly useless (can't be operand 1 of an addi or the base ptr      // of a load) so, free up S1 for use by briefly saving its contents in the      // return address slot of my caller's frame      ptr.insertBefore(MIR_Store.create(PPC_STAddr, A(S1), A(FP),                                         IC(STACKFRAME_NEXT_INSTRUCTION_OFFSET)));      Offset offset = VM_Entrypoints.activeThreadStackLimitField.getOffset();      if (VM.VerifyAssertions) VM._assert(OPT_Bits.fits(offset, 16));      ptr.insertBefore(MIR_Load.create(PPC_LAddr, A(S1), A(phys.getPR()),                                        IC(OPT_Bits.PPCMaskLower16(offset))));       ptr.insertBefore(MIR_Binary.create(PPC_ADDI, A(R0), A(S1),                         IC(frameSize)));      ptr.insertBefore(MIR_Load.create(PPC_LAddr, A(S1), A(FP),                                        IC(STACKFRAME_NEXT_INSTRUCTION_OFFSET)));      // Mutate the Prologue holder instruction into the trap      MIR_Trap.mutate(ptr, PPC_TAddr, OPT_PowerPCTrapOperand.LESS(), A(FP), A(R0),                      OPT_TrapCodeOperand.StackOverflow());       // advance ptr because we want the remaining instructions to come after      // the trap      ptr = ptr.nextInstructionInCodeOrder();    } else {      // no stack overflow test, so we must remove the IR_Prologue instruction      OPT_Instruction next = ptr.nextInstructionInCodeOrder();      ptr.remove();      ptr = next;    }        // Buy stack frame, save LR, caller's FP     ptr.insertBefore(MIR_Move.create(PPC_MFSPR, A(R0),                                     A(phys.getLR())));    ptr.insertBefore(MIR_StoreUpdate.create(PPC_STAddrU, A(FP), A(FP),                                            IC(-frameSize)));    ptr.insertBefore(MIR_Store.create(PPC_STAddr, A(R0), A(FP),                                      IC(frameSize+STACKFRAME_NEXT_INSTRUCTION_OFFSET)));        // Store cmid    int cmid = ir.compiledMethod.getId();    if (cmid <= 0x7fff) {      ptr.insertBefore(MIR_Unary.create(PPC_LDI, I(R0), IC(cmid)));    } else {      ptr.insertBefore(MIR_Unary.create(PPC_LDIS, I(R0),IC(cmid>>>16)));      ptr.insertBefore(MIR_Binary.create(PPC_ORI, I(R0), I(R0),IC(cmid&0xffff)));    }    ptr.insertBefore(MIR_Store.create(PPC_STW, I(R0), A(FP),                                       IC(STACKFRAME_METHOD_ID_OFFSET)));    // Now save the volatile/nonvolatile registers    if (ir.compiledMethod.isSaveVolatile()) {      saveVolatiles(ptr);    }    saveNonVolatiles(ptr);        // Threadswitch    if (yp) {      Offset offset = VM_Entrypoints.takeYieldpointField.getOffset();      if (VM.VerifyAssertions) VM._assert(OPT_Bits.fits(offset, 16));      ptr.insertBefore(MIR_Load.create(PPC_LInt, I(R0), A(PR),                                        IC(OPT_Bits.PPCMaskLower16(offset))));       ptr.insertBefore(MIR_Binary.create(PPC_CMPI, I(TSR), I(R0), IC(0)));    }    ptr.insertBefore(Empty.create(IR_ENDPROLOGUE));  }