예제 #1
0
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());
  }

}
예제 #2
0
  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);
    }
  }
예제 #3
0
 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);
   }
 }
예제 #4
0
 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);
   }
 }
예제 #5
0
 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);
   }
 }
예제 #6
0
  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);
      }
    }
  }
예제 #7
0
 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
   }
 }
예제 #8
0
int32 compiled_vframe::register_offset(Location r) {
  return spOffset(r, fr->frame_size()) / oopSize; 
}
예제 #9
0
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];
}
예제 #10
0
 void FlushNode::flushRegister(PReg* pr) {
   Location l = pr->loc;
   assert(l >= L0 && l <= I7, "not a local register");
   theAssembler->StoreI(SP, spOffset(l), l);
 }