void IRBuilder::startBlock(Block* block) { assert(block); assert(m_savedBlocks.empty()); // No bytecode control flow in exits. if (block->empty()) { if (block != m_curBlock) { if (m_state.compatible(block)) { m_state.pauseBlock(block); } else { m_state.clearCse(); } assert(m_curBlock); auto& prev = m_curBlock->back(); if (!prev.hasEdges()) { gen(Jmp, block); } else if (!prev.isTerminal()) { prev.setNext(block); } m_curBlock = block; m_state.startBlock(m_curBlock); FTRACE(2, "IRBuilder switching to block B{}: {}\n", block->id(), show(m_state)); } } if (sp() == nullptr) { gen(DefSP, StackOffset(spOffset() + evalStack().size() - stackDeficit()), fp()); } }
void ArithRCNode::gen() { BasicNode::gen(); Location src = genHelper->moveToReg(_src, Temp1); Location dest = isRegister(_dest->loc) ? _dest->loc : Temp2; switch (op) { case AddArithOp: theAssembler->AddI(src, oper, dest); break; case SubArithOp: theAssembler->SubI(src, oper, dest); break; case AndArithOp: theAssembler->AndI(src, oper, dest); break; case OrArithOp: theAssembler->OrI (src, oper, dest); break; case XOrArithOp: theAssembler->XorI(src, oper, dest); break; case ArithmeticLeftShiftArithOp: case LogicalLeftShiftArithOp: theAssembler->SllI(src, oper, dest); break; case ArithmeticRightShiftArithOp: theAssembler->SraI(src, oper, dest); break; case LogicalRightShiftArithOp: theAssembler->SrlI(src, oper, dest); break; case AddCCArithOp: theAssembler->AddCCI(src, oper, dest); break; case SubCCArithOp: theAssembler->SubCCI(src, oper, dest); break; case AndCCArithOp: theAssembler->AndCCI(src, oper, dest); break; case OrCCArithOp: theAssembler->OrCCI (src, oper, dest); break; default: ShouldNotReachHere(); // unexpected arith type } if (dest != _dest->loc) { theAssembler->StoreI(SP, spOffset(_dest->loc), dest); } }
void BlockCloneNode::genCall() { Location dest = block()->loc; genHelper->loadImmediateOop(block()->block, CReceiverReg); // load block Oop theAssembler->CallP(first_inst_addr(blockClone->fn())); theAssembler->OrR(SP, G0, Arg1); // load home frame assert(!blockClone->canScavenge() && !blockClone->needsNLRCode(), "need to rewrite this"); genHelper->moveRegToLoc(ResultReg, dest); if (block()->uplevelR && isRegister(dest)) { // flush to stack theAssembler->StoreI(SP, spOffset(dest), dest); } }
void LoadIntNode::gen() { BasicNode::gen(); if (isRegister(_dest->loc) && isImmediate(smiOop(value))) { theAssembler->OrI(G0, value, _dest->loc); // common case } else if (isRegister(_dest->loc)) { theAssembler->SetHiI(value, _dest->loc); theAssembler->AddI(_dest->loc, value, _dest->loc); } else { theAssembler->SetHiI(value, Temp1); theAssembler->AddI(Temp1, value, Temp1); theAssembler->StoreI(SP, spOffset(_dest->loc), Temp1); } }
void AssignNode::genOop() { ConstPReg* value = (ConstPReg*)_src; Location src = value->loc; if (src != UnAllocated) { // value is already in src register genHelper->moveRegToLoc(src, _dest->loc); } else if (isRegister(_dest->loc)) { genHelper->loadImmediateOop(value->constant, _dest->loc); } else { Location t = Temp1; oop c = value->constant; if (c) { genHelper->loadImmediateOop(c, t); } else { t = G0; } theAssembler->StoreI(SP, spOffset(_dest->loc), t); } }
void TArithRRNode::gen() { BasicNode::gen(); if (constResult) { Location dest = isRegister(_dest->loc) ? _dest->loc : Temp2; Location l_ = genHelper->moveToReg(constResult, dest); if (l_ != _dest->loc) genHelper->moveRegToLoc(dest, _dest->loc); } else { Location t1, t2; bool reversed; if (SICCountIntTagTests) theAssembler->markTagTest(arg1IsInt ? 1 : 2); Location dest = arith_genHelper(_src, oper, _dest, op, t1, t2, reversed); Node* n= next1(); if (n) { Label* l_= theAssembler->BvsForward(false); n->l= l_->unify(n->l); } // fill delay slot with tag test // caution: code below depends on temp reg assignments in arith_genHelper // also, the code in sicPrimline.c depends on Temp1 being set correctly if (arg1IsInt) { // only need to check arg2 Location t = reversed ? t1 : t2; if (t == G0) { theAssembler->Nop(); } else { theAssembler->AndCCI(t, Tag_Mask, Temp1); } } else { theAssembler->OrR(t1, t2, Temp1); } if (dest != _dest->loc) { // store result on stack (success case) theAssembler->StoreI(SP, spOffset(_dest->loc), dest); } } }
void StoreOffsetNode::gen() { BasicNode::gen(); Location b = genHelper->moveToReg(base, Temp1); Location t = Temp2; if (_src->isConstPReg()) { // store constant ConstPReg* value = (ConstPReg*)_src; oop p = value->constant; // don't need to check-store if oop is old - old objs will never become // new again needCheckStore = needCheckStore && p->is_new(); // ints/floats aren't new if (p == 0) { theAssembler->StoreI(b, offset, G0); } else { assert(b != t, "must be different"); t = genHelper->loadImmediateOop(value, t, false); theAssembler->StoreI(b, offset, t); } } else { if (isRegister(_src->loc)) { theAssembler->StoreI(b, offset, _src->loc); } else { theAssembler->LoadI(SP, spOffset(_src->loc), t); theAssembler->StoreI(b, offset, t); } } if (needCheckStore) { // do a check-store assert(isRegister(b), "base reg of check_store must be in a register"); if (offset > card_size || !AllowOffsetCheckStores) { // use slow check-store sequence // (marked card may be off by one, but not more) theAssembler->AddI(b, offset, Temp1); b = Temp1; } theAssembler->SrlI(b, card_shift, Temp1); // shift target addr theAssembler->StoreBR(Temp1, ByteMapBaseReg, G0); // set byte in map } }
int32 compiled_vframe::register_offset(Location r) { return spOffset(r, fr->frame_size()) / oopSize; }
oop frame::get_lookup_arg(fint index) { frame* f = sendee(); fint offset = spOffset(IArgLocation(index), f->frame_size()) / oopSize; return callees_sp()->as_oops()[offset]; }
void FlushNode::flushRegister(PReg* pr) { Location l = pr->loc; assert(l >= L0 && l <= I7, "not a local register"); theAssembler->StoreI(SP, spOffset(l), l); }