void InterruptedContext::set_continuation_address(char *addr, bool mustWork, bool setSema) { InterruptedContext::the_interrupted_context->must_be_in_self_thread(); assert(!continuePC, "continuePC already set"); if (setSema) processSemaphore = true; if (the_interrupted_context->next_pc() == the_interrupted_context->pc() + 4) { // normal case continuePC = the_interrupted_context->pc(); the_interrupted_context->set_pc(addr); the_interrupted_context->set_next_pc(addr + 4); } else { // Instruction at pc is in delay slot; next instr. is non-sequential // Execute delay slot instruction before jumping to continuation int32* instp = (int32*)the_interrupted_context->pc(); if (isCall(instp) || isJump(instp)) { // back-to-back CTI - shouldn't happen for Self code warning("setContinuationAddress: can't handle back-to-back CTI;\n"); warning4("pc=%#lx (%lx), npc=%#lx (%lx)", the_interrupted_context->pc(), *(int*)the_interrupted_context->pc(), the_interrupted_context->next_pc(), *(int*)the_interrupted_context->next_pc()); if (mustWork) fatal("couldn't set continuation address"); } else { continuePC = the_interrupted_context->next_pc(); the_interrupted_context->set_next_pc(addr); } } }
int32 getJumpImm(int32* instp) { assert(isJump(instp), "expecting a jmpl"); assert(isImmed(instp), "expecting an offset"); assert(isSetHi(instp - 1), "expecting a sethi before the jmpl"); int32 val = getSetHiImm(instp - 1); val += getArithImm(instp); return val; }
void ComparingStub::set_recompile_addr(pc_t addr) { CountCodePattern* patt = CountStub::pattern[Comparing]; int32* p = (int32*)insts() + patt->recompile_offset; assert(isSetHi(p), "wrong pattern"); assert(isJump(p + 1), "strange instruction after setHi"); setSetHiImm(p , int32(addr)); setArithImm(p + 1, int32(addr)); }
pc_t ComparingStub::get_recompile_addr() { CountCodePattern* patt = CountStub::pattern[Comparing]; int32* p = (int32*)insts() + patt->recompile_offset; assert(isSetHi(p), "wrong pattern"); assert(isJump(p + 1), "strange instruction after setHi"); int32 val = getSetHiImm(p) + getArithImm(p + 1); return (pc_t)val; }
void setJumpImm(int32* instp, int32 val) { assert(isJump(instp), "expecting a jmpl"); assert(isImmed(instp), "expecting an offset"); assert(isSetHi(instp - 1), "expecting a sethi before the jmpl"); setSetHiImm(instp - 1, val); setArithImm(instp, val); MachineCache::flush_instruction_cache_word(instp - 1); MachineCache::flush_instruction_cache_word(instp); }
pc_t CountStub::jump_addr() { CountCodePattern* patt = CountStub::pattern[countType()]; int32* p = (int32*)insts(); assert(isSetHi(p + patt->nm_sethi_offset), "wrong pattern"); assert(isJump (p + patt->nm_jmp_offset), "wrong pattern"); pc_t n = (pc_t)getSetHiImm(p + patt->nm_sethi_offset); n += getArithImm(p + patt->nm_jmp_offset); return n; }