Exemplo n.º 1
0
void OMR::X86::Instruction::assignRegisters(TR_RegisterKinds kindsToBeAssigned)
   {
   if (!self()->getDependencyConditions())
      {
      // Fast path when there are no dependency conditions.
      //
      return;
      }

   if (self()->getOpCodeValue() != ASSOCREGS)
      {
      self()->aboutToAssignRegDeps();

      if ((self()->cg()->getAssignmentDirection() == self()->cg()->Backward))
         {
         self()->getDependencyConditions()->assignPostConditionRegisters(self(), kindsToBeAssigned, self()->cg());
         self()->getDependencyConditions()->assignPreConditionRegisters(self(), kindsToBeAssigned, self()->cg());
         }
      else
         {
         self()->getDependencyConditions()->assignPreConditionRegisters(self()->getPrev(), kindsToBeAssigned, self()->cg());
         self()->getDependencyConditions()->assignPostConditionRegisters(self(), kindsToBeAssigned, self()->cg());
         }
      }
   else if ((self()->getOpCodeValue() == ASSOCREGS) && self()->cg()->enableRegisterAssociations())
      {
      if (kindsToBeAssigned & TR_GPR_Mask)
         {
         TR::Machine *machine = self()->cg()->machine();

         // First traverse the existing associations and remove them
         // so that they don't interfere with the new ones
         //
         for (int i = TR::RealRegister::FirstGPR;
              i <= TR::RealRegister::LastAssignableGPR;
              ++i)
            {
            // Skip non-assignable registers
            //
            if (machine->getX86RealRegister((TR::RealRegister::RegNum)i)->getState() == TR::RealRegister::Locked)
               continue;

            TR::Register *virtReg = machine->getVirtualAssociatedWithReal((TR::RealRegister::RegNum)i);
            if (virtReg)
               {
               virtReg->setAssociation(TR::RealRegister::NoReg);
               }
            }

         // Next loop through and set up the new associations (both on the machine
         // and by associating the virtual registers with their real dependencies)
         //
         TR_X86RegisterDependencyGroup *depGroup = self()->getDependencyConditions()->getPostConditions();
         for (int j = 0; j < self()->getDependencyConditions()->getNumPostConditions(); ++j)
            {
            TR::RegisterDependency  *dep = depGroup->getRegisterDependency(j);
            machine->setVirtualAssociatedWithReal(dep->getRealRegister(), dep->getRegister());
            }

         machine->setGPRWeightsFromAssociations();
         }
      }
   }
Exemplo n.º 2
0
OMR::ARM::RegisterDependencyConditions::RegisterDependencyConditions( TR::Node          *node,
                                                                       uint32_t           extranum,
                                                                       TR::Instruction   **cursorPtr,
                                                                       TR::CodeGenerator  *cg)
   {

   List<TR::Register>  regList(cg->trMemory());
   TR::Instruction    *cursor = (cursorPtr == NULL ? NULL : *cursorPtr);
   int32_t totalNum = node->getNumChildren() + extranum;
   int32_t i;


   cg->comp()->incVisitCount();

   int32_t numLongs = 0;
   //
   // Pre-compute how many longs are global register candidates
   //
   for (i = 0; i < node->getNumChildren(); ++i)
      {
      TR::Node     *child = node->getChild(i);
      TR::Register *reg   = child->getRegister();

      if (reg!=NULL /* && reg->getKind()==TR_GPR */)
         {
         if (child->getHighGlobalRegisterNumber() > -1)
            numLongs++;
         }
      }

   totalNum = totalNum + numLongs;

   _preConditions = TR_ARMRegisterDependencyGroup::create(totalNum, cg->trMemory());
   _postConditions = TR_ARMRegisterDependencyGroup::create(totalNum, cg->trMemory());
   _numPreConditions = totalNum;
   _addCursorForPre = 0;
   _numPostConditions = totalNum;
   _addCursorForPost = 0;

   // First, handle dependencies that match current association
   for (i=0; i<node->getNumChildren(); i++)
      {
      TR::Node *child = node->getChild(i);
      TR::Register *reg = child->getRegister();
      TR::Register *highReg = NULL;
      TR::RealRegister::RegNum regNum = (TR::RealRegister::RegNum)cg->getGlobalRegister(child->getGlobalRegisterNumber());

      TR::RealRegister::RegNum highRegNum;

      if (child->getHighGlobalRegisterNumber() > -1)
         {
         highRegNum = (TR::RealRegister::RegNum)cg->getGlobalRegister(child->getHighGlobalRegisterNumber());

         TR::RegisterPair *regPair = reg->getRegisterPair();
         TR_ASSERT(regPair, "assertion failure");
         highReg = regPair->getHighOrder();
         reg = regPair->getLowOrder();

         if (highReg->getAssociation() != highRegNum ||
            reg->getAssociation() != regNum)
            continue;
         }
      else if (reg->getAssociation() != regNum)
         continue;

      TR_ASSERT(!regList.find(reg) && (!highReg || !regList.find(highReg)), "Should not happen\n");

      addPreCondition(reg, regNum);
      addPostCondition(reg, regNum);
      regList.add(reg);

      if (highReg)
         {
         addPreCondition(highReg, highRegNum);
         addPostCondition(highReg, highRegNum);
         regList.add(highReg);
         }
      }


   // Second pass to handle dependencies for which association does not exist
   // or does not match
   for (i=0; i<node->getNumChildren(); i++)
      {
      TR::Node *child = node->getChild(i);
      TR::Register *reg = child->getRegister();
      TR::Register *highReg = NULL;
      TR::Register *copyReg = NULL;
      TR::Register *highCopyReg = NULL;
      TR::RealRegister::RegNum regNum = (TR::RealRegister::RegNum)cg->getGlobalRegister(child->getGlobalRegisterNumber());

      TR::RealRegister::RegNum highRegNum;

      if (child->getHighGlobalRegisterNumber() > -1)
         {
         highRegNum = (TR::RealRegister::RegNum)cg->getGlobalRegister(child->getHighGlobalRegisterNumber());
         TR::RegisterPair *regPair = reg->getRegisterPair();
         TR_ASSERT(regPair, "assertion failure");
         highReg = regPair->getHighOrder();
         reg = regPair->getLowOrder();

         if (highReg->getAssociation() == highRegNum &&
            reg->getAssociation() == regNum)
            continue;
         }
      else if (reg->getAssociation() == regNum)
         continue;

      if (regList.find(reg) || (highReg && regList.find(highReg)))
         {
         TR_ARMOpCodes    opCode;
         TR_RegisterKinds kind = reg->getKind();

         switch (kind)
            {
            case TR_GPR:
               opCode = ARMOp_mov;
               break;
            case TR_FPR:
               opCode = ARMOp_fmrs;
               break;
            default:
               TR_ASSERT(0, "Invalid register kind.");
            }

         if (regList.find(reg))
            {
            bool containsInternalPointer = false;
            if (reg->getPinningArrayPointer())
               containsInternalPointer = true;

            copyReg = (reg->containsCollectedReference() && !containsInternalPointer) ?
               cg->allocateCollectedReferenceRegister() : cg->allocateRegister(kind);

            if (containsInternalPointer)
               {
               copyReg->setContainsInternalPointer();
               copyReg->setPinningArrayPointer(reg->getPinningArrayPointer());
               }

            cursor = generateTrg1Src1Instruction(cg, opCode, node, copyReg, reg, cursor);
            reg = copyReg;
            }

         if (highReg && regList.find(highReg))
            {
            bool containsInternalPointer = false;
            if (highReg->getPinningArrayPointer())
               containsInternalPointer = true;

            highCopyReg = (highReg->containsCollectedReference() && !containsInternalPointer) ?
               cg->allocateCollectedReferenceRegister() : cg->allocateRegister(kind);

            if (containsInternalPointer)
               {
               highCopyReg->setContainsInternalPointer();
               highCopyReg->setPinningArrayPointer(highReg->getPinningArrayPointer());
               }

            cursor = generateTrg1Src1Instruction(cg, opCode, node, highCopyReg, highReg, cursor);
            highReg = highCopyReg;
            }
         }

      reg->setAssociation(regNum);
      addPreCondition(reg, regNum);
      addPostCondition(reg, regNum);
      if (copyReg != NULL)
         cg->stopUsingRegister(copyReg);
      else
         regList.add(reg);

      if (highReg)
         {
         highReg->setAssociation(highRegNum);
         addPreCondition(highReg, highRegNum);
         addPostCondition(highReg, highRegNum);
         if (highCopyReg != NULL)
            cg->stopUsingRegister(highCopyReg);
         else
            regList.add(highReg);
         }
      }

   if (cursor != NULL && cursorPtr != NULL)
      *cursorPtr = cursor;
   }