Esempio n. 1
0
bool Dialog::setRemoteParameter(const char* pname, const UtlString& pvalue)
{
   UtlBoolean found = FALSE;

   UtlDListIterator paramIterator(mRemoteParameters);
   NameValuePairInsensitive* param= NULL;

   UtlString paramName;

   while (!found && (param = dynamic_cast<NameValuePairInsensitive*>(paramIterator())))
   {
      paramName = param->data();
      if (paramName.compareTo(pname, UtlString::ignoreCase) == 0)
      {
         found = TRUE;
         param->setValue(pvalue);
      }
   }
   return(found);
}
Esempio n. 2
0
// Copies parameters from where they enter the method (either on stack or in a
// linkage register) to their "home location" where the method body will expect
// to find them (either on stack or in a global register).
//
TR::Instruction *
TR::X86SystemLinkage::copyParametersToHomeLocation(TR::Instruction *cursor)
   {
   TR::Machine *machine = cg()->machine();
   TR::RealRegister *framePointer = machine->getX86RealRegister(TR::RealRegister::vfp);

   TR::ResolvedMethodSymbol             *bodySymbol = comp()->getJittedMethodSymbol();
   ListIterator<TR::ParameterSymbol>  paramIterator(&(bodySymbol->getParameterList()));
   TR::ParameterSymbol               *paramCursor;

   const TR::RealRegister::RegNum noReg = TR::RealRegister::NoReg;
   TR_ASSERT(noReg == 0, "noReg must be zero so zero-initializing movStatus will work");

   TR::MovStatus movStatus[TR::RealRegister::NumRegisters] = {{(TR::RealRegister::RegNum)0,(TR::RealRegister::RegNum)0,(TR_MovDataTypes)0}};

   // We must always do the stores first, then the reg-reg copies, then the
   // loads, so that we never clobber a register we will need later.  However,
   // the logic is simpler if we do the loads and stores in the same loop.
   // Therefore, we maintain a separate instruction cursor for the loads.
   //
   // We defer the initialization of loadCursor until we generate the first
   // load.  Otherwise, if we happen to generate some stores first, then the
   // store cursor would get ahead of the loadCursor, and the instructions
   // would end up in the wrong order despite our efforts.
   //
   TR::Instruction *loadCursor = NULL;

   // Phase 1: generate RegMem and MemReg movs, and collect information about
   // the required RegReg movs.
   //
   for (paramCursor = paramIterator.getFirst();
       paramCursor != NULL;
       paramCursor = paramIterator.getNext())
      {
      int8_t lri = paramCursor->getLinkageRegisterIndex();     // How the parameter enters the method
      TR::RealRegister::RegNum ai                              // Where method body expects to find it
         = (TR::RealRegister::RegNum)paramCursor->getAllocatedIndex();
      int32_t offset = paramCursor->getParameterOffset();      // Location of the parameter's stack slot
      TR_MovDataTypes movDataType = paramMovType(paramCursor); // What sort of MOV instruction does it need?

      // Copy the parameter to wherever it should be
      //
      if (lri == NOT_LINKAGE) // It's on the stack
         {
         if (ai == NOT_ASSIGNED) // It only needs to be on the stack
            {
            // Nothing to do
            }
         else // Method body expects it to be in the ai register
            {
            if (loadCursor == NULL)
               loadCursor = cursor;

            if (debug("traceCopyParametersToHomeLocation"))
               diagnostic("copyParametersToHomeLocation: Loading %d\n", ai);
            // ai := stack
            loadCursor = generateRegMemInstruction(
               loadCursor,
               TR::Linkage::movOpcodes(RegMem, movDataType),
               machine->getX86RealRegister(ai),
               generateX86MemoryReference(framePointer, offset, cg()),
               cg()
               );
            }
         }
      else // It's in a linkage register
         {
         TR::RealRegister::RegNum sourceIndex = getProperties().getArgumentRegister(lri, isFloat(movDataType));

         // Copy to the stack if necessary
         //
         if (ai == NOT_ASSIGNED || hasToBeOnStack(paramCursor))
            {
            if (comp()->getOption(TR_TraceCG))
              traceMsg(comp(), "copyToHomeLocation param %p, linkage reg index %d, allocated index %d, parameter offset %d, hasToBeOnStack %d, parm->isParmHasToBeOnStack() %d.\n", paramCursor, lri, ai, offset, hasToBeOnStack(paramCursor), paramCursor->isParmHasToBeOnStack());
            if (debug("traceCopyParametersToHomeLocation"))
               diagnostic("copyParametersToHomeLocation: Storing %d\n", sourceIndex);
            // stack := lri
            cursor = generateMemRegInstruction(
               cursor,
               TR::Linkage::movOpcodes(MemReg, movDataType),
               generateX86MemoryReference(framePointer, offset, cg()),
               machine->getX86RealRegister(sourceIndex),
               cg()
               );
            }

         // Copy to the ai register if necessary
         //
         if (ai != NOT_ASSIGNED && ai != sourceIndex)
            {
            // This parameter needs a RegReg move.  We don't know yet whether
            // we need the value in the target register, so for now we just
            // remember that we need to do this and keep going.
            //
            TR_ASSERT(movStatus[ai         ].sourceReg == noReg, "Each target reg must have only one source");
            TR_ASSERT(movStatus[sourceIndex].targetReg == noReg, "Each source reg must have only one target");
            if (debug("traceCopyParametersToHomeLocation"))
               diagnostic("copyParametersToHomeLocation: Planning to move %d to %d\n", sourceIndex, ai);
            movStatus[ai].sourceReg                  = sourceIndex;
            movStatus[sourceIndex].targetReg         = ai;
            movStatus[sourceIndex].outgoingDataType  = movDataType;
            }

         if (debug("traceCopyParametersToHomeLocation") && ai == sourceIndex)
            {
            diagnostic("copyParametersToHomeLocation: Parameter #%d already in register %d\n", lri, ai);
            }
         }
      }

   // Phase 2: Iterate through the parameters again to insert the RegReg moves.
   //
   for (paramCursor = paramIterator.getFirst();
       paramCursor != NULL;
       paramCursor = paramIterator.getNext())
      {
      if (paramCursor->getLinkageRegisterIndex() == NOT_LINKAGE)
         continue;

      const TR::RealRegister::RegNum paramReg =
         getProperties().getArgumentRegister(paramCursor->getLinkageRegisterIndex(), isFloat(paramMovType(paramCursor)));

      if (movStatus[paramReg].targetReg == 0)
         {
         // This parameter does not need to be copied anywhere
         if (debug("traceCopyParametersToHomeLocation"))
            diagnostic("copyParametersToHomeLocation: Not moving %d\n", paramReg);
         }
      else
         {
         if (debug("traceCopyParametersToHomeLocation"))
            diagnostic("copyParametersToHomeLocation: Preparing to move %d\n", paramReg);

         // If a mov's target register is the source for another mov, we need
         // to do that other mov first.  The idea is to find the end point of
         // the chain of movs starting with paramReg and ending with a
         // register whose current value is not needed; then do that chain of
         // movs in reverse order.
         //
         TR_ASSERT(noReg == 0, "noReg must be zero (not %d) for zero-filled initialization to work", noReg);

         TR::RealRegister::RegNum regCursor;

         // Find the last target in the chain
         //
         regCursor = movStatus[paramReg].targetReg;
         while(movStatus[regCursor].targetReg != noReg)
            {
            // Haven't found the end yet
            regCursor = movStatus[regCursor].targetReg;
            TR_ASSERT(regCursor != paramReg, "Can't yet handle cyclic dependencies");

            // TODO:AMD64 Use scratch register to break cycles
            // A properly-written pickRegister should never
            // cause cycles to occur in the first place.  However, we may want
            // to consider adding cycle-breaking logic so that (1) pickRegister
            // has more flexibility, and (2) we're more robust against
            // otherwise harmless bugs in pickRegister.
            }

         // Work our way backward along the chain, generating all the necessary movs
         //
         while(movStatus[regCursor].sourceReg != noReg)
            {
            TR::RealRegister::RegNum source = movStatus[regCursor].sourceReg;
            if (debug("traceCopyParametersToHomeLocation"))
               diagnostic("copyParametersToHomeLocation: Moving %d to %d\n", source, regCursor);
            // regCursor := regCursor.sourceReg
            cursor = generateRegRegInstruction(
               cursor,
               TR::Linkage::movOpcodes(RegReg, movStatus[source].outgoingDataType),
               machine->getX86RealRegister(regCursor),
               machine->getX86RealRegister(source),
               cg()
               );
            // Update movStatus as we go so we don't generate redundant movs
            movStatus[regCursor].sourceReg = noReg;
            movStatus[source   ].targetReg = noReg;
            // Continue with the next register in the chain
            regCursor = source;
            }
         }
      }

   // Return the last instruction we inserted, whether or not it was a load.
   //
   return loadCursor? loadCursor : cursor;
   }
Esempio n. 3
0
TR::Instruction *OMR::Power::Linkage::flushArguments(TR::Instruction *cursor)
   {
   TR::Machine *machine = self()->machine();
   TR::RealRegister      *stackPtr   = self()->cg()->getStackPointerRegister();
   TR::ResolvedMethodSymbol      *bodySymbol = self()->comp()->getJittedMethodSymbol();
   ListIterator<TR::ParameterSymbol>   paramIterator(&(bodySymbol->getParameterList()));
   TR::ParameterSymbol      *paramCursor = paramIterator.getFirst();
   TR::Node                 *firstNode = self()->comp()->getStartTree()->getNode();
   int32_t                  numIntArgs = 0, numFloatArgs = 0;
   const TR::PPCLinkageProperties& properties = self()->getProperties();

   while ( (paramCursor!=NULL) &&
           ( (numIntArgs < properties.getNumIntArgRegs()) ||
             (numFloatArgs < properties.getNumFloatArgRegs()) ) )
      {
      TR::RealRegister     *argRegister;
      int32_t                 offset = paramCursor->getParameterOffset();

      // If parm is referenced or required to be on stack (i.e. FSD), we have to flush.
      bool hasToStoreToStack = paramCursor->isReferencedParameter() || paramCursor->isParmHasToBeOnStack();

      switch (paramCursor->getDataType())
         {
         case TR::Int8:
         case TR::Int16:
         case TR::Int32:
            if (hasToStoreToStack &&
                  numIntArgs<properties.getNumIntArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getIntegerArgumentRegister(numIntArgs));
               cursor = generateMemSrc1Instruction(self()->cg(), TR::InstOpCode::stw, firstNode,
                     new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()),
                     argRegister, cursor);
               }
            numIntArgs++;
            break;
         case TR::Address:
            if (numIntArgs<properties.getNumIntArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getIntegerArgumentRegister(numIntArgs));
               cursor = generateMemSrc1Instruction(self()->cg(),TR::InstOpCode::Op_st, firstNode,
                     new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, TR::Compiler->om.sizeofReferenceAddress(), self()->cg()),
                     argRegister, cursor);
               }
            numIntArgs++;
            break;
         case TR::Int64:
            if (hasToStoreToStack &&
                  numIntArgs<properties.getNumIntArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getIntegerArgumentRegister(numIntArgs));
               if (TR::Compiler->target.is64Bit())
                  cursor = generateMemSrc1Instruction(self()->cg(),TR::InstOpCode::Op_st, firstNode,
                        new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 8, self()->cg()),
                        argRegister, cursor);
               else
                  {
                  cursor = generateMemSrc1Instruction(self()->cg(), TR::InstOpCode::stw, firstNode,
                        new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()),
                        argRegister, cursor);
                  if (numIntArgs < properties.getNumIntArgRegs()-1)
                     {
                     argRegister = machine->getRealRegister(properties.getIntegerArgumentRegister(numIntArgs+1));
                     cursor = generateMemSrc1Instruction(self()->cg(), TR::InstOpCode::stw, firstNode,
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset+4, 4, self()->cg()),
                           argRegister, cursor);
                     }
                  }
               }
            if (TR::Compiler->target.is64Bit())
               numIntArgs++;
            else
               numIntArgs+=2;
            break;
         case TR::Float:
            if (hasToStoreToStack &&
                  numFloatArgs<properties.getNumFloatArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getFloatArgumentRegister(numFloatArgs));
               cursor = generateMemSrc1Instruction(self()->cg(), TR::InstOpCode::stfs, firstNode,
                     new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()),
                     argRegister, cursor);
               }
            numFloatArgs++;
            break;
         case TR::Double:
            if (hasToStoreToStack &&
                  numFloatArgs<properties.getNumFloatArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getFloatArgumentRegister(numFloatArgs));
               cursor = generateMemSrc1Instruction(self()->cg(), TR::InstOpCode::stfd, firstNode,
                     new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 8, self()->cg()),
                     argRegister, cursor);
               }
            numFloatArgs++;
            break;
         }
      paramCursor = paramIterator.getNext();
      }
   return(cursor);
   }
Esempio n. 4
0
TR::Instruction *OMR::Power::Linkage::loadUpArguments(TR::Instruction *cursor)
   {
   if (!self()->cg()->buildInterpreterEntryPoint())
      // would be better to use a different linkage for this purpose
      return cursor;

   TR::Machine *machine = self()->machine();
   TR::RealRegister      *stackPtr   = self()->cg()->getStackPointerRegister();
   TR::ResolvedMethodSymbol      *bodySymbol = self()->comp()->getJittedMethodSymbol();
   ListIterator<TR::ParameterSymbol>   paramIterator(&(bodySymbol->getParameterList()));
   TR::ParameterSymbol      *paramCursor = paramIterator.getFirst();
   TR::Node                 *firstNode = self()->comp()->getStartTree()->getNode();
   int32_t                  numIntArgs = 0, numFloatArgs = 0;
   const TR::PPCLinkageProperties& properties = self()->getProperties();

   while ( (paramCursor!=NULL) &&
           ( (numIntArgs < properties.getNumIntArgRegs()) ||
             (numFloatArgs < properties.getNumFloatArgRegs()) ) )
      {
      TR::RealRegister     *argRegister;
      int32_t                 offset = paramCursor->getParameterOffset();

      bool hasToLoadFromStack = paramCursor->isReferencedParameter() || paramCursor->isParmHasToBeOnStack();

      switch (paramCursor->getDataType())
         {
         case TR::Int8:
         case TR::Int16:
         case TR::Int32:
            if (hasToLoadFromStack &&
                  numIntArgs<properties.getNumIntArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getIntegerArgumentRegister(numIntArgs));
               cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lwz, firstNode, argRegister,
                     new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()), cursor);
               }
            numIntArgs++;
            break;
         case TR::Address:
            if (numIntArgs<properties.getNumIntArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getIntegerArgumentRegister(numIntArgs));
               cursor = generateTrg1MemInstruction(self()->cg(),TR::InstOpCode::Op_load, firstNode, argRegister,
                     new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, TR::Compiler->om.sizeofReferenceAddress(), self()->cg()), cursor);
               }
            numIntArgs++;
            break;
         case TR::Int64:
            if (hasToLoadFromStack &&
                  numIntArgs<properties.getNumIntArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getIntegerArgumentRegister(numIntArgs));
               if (TR::Compiler->target.is64Bit())
                  cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::ld, firstNode, argRegister,
                        new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 8, self()->cg()), cursor);
               else
                  {
                  cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lwz, firstNode, argRegister,
                        new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()), cursor);
                  if (numIntArgs < properties.getNumIntArgRegs()-1)
                     {
                     argRegister = machine->getRealRegister(properties.getIntegerArgumentRegister(numIntArgs+1));
                     cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lwz, firstNode, argRegister,
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset+4, 4, self()->cg()), cursor);
                     }
                  }
               }
            if (TR::Compiler->target.is64Bit())
               numIntArgs++;
            else
               numIntArgs+=2;
            break;
         case TR::Float:
            if (hasToLoadFromStack &&
                  numFloatArgs<properties.getNumFloatArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getFloatArgumentRegister(numFloatArgs));
               cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lfs, firstNode, argRegister,
                     new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()), cursor);
               }
            numFloatArgs++;
            break;
         case TR::Double:
            if (hasToLoadFromStack &&
                  numFloatArgs<properties.getNumFloatArgRegs())
               {
               argRegister = machine->getRealRegister(properties.getFloatArgumentRegister(numFloatArgs));
               cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lfd, firstNode, argRegister,
                     new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 8, self()->cg()), cursor);
               }
            numFloatArgs++;
            break;
         }
      paramCursor = paramIterator.getNext();
      }
   return(cursor);
   }
Esempio n. 5
0
TR::Instruction *OMR::Power::Linkage::saveArguments(TR::Instruction *cursor, bool fsd, bool saveOnly,
                                             List<TR::ParameterSymbol> &parmList)
   {
   #define  REAL_REGISTER(ri)  machine->getRealRegister(ri)
   #define  REGNUM(ri)         ((TR::RealRegister::RegNum)(ri))
   const TR::PPCLinkageProperties& properties = self()->getProperties();
   TR::Machine *machine = self()->machine();
   TR::RealRegister      *stackPtr   = self()->cg()->getStackPointerRegister();
   TR::ResolvedMethodSymbol    *bodySymbol = self()->comp()->getJittedMethodSymbol();
   ListIterator<TR::ParameterSymbol>   paramIterator(&parmList);
   TR::ParameterSymbol      *paramCursor;
   TR::Node                 *firstNode = self()->comp()->getStartTree()->getNode();
   TR_BitVector             freeScratchable;
   int32_t                  busyMoves[3][64];
   int32_t                  busyIndex = 0, i1;


   bool all_saved  = false;

   // the freeScratchable structure will not be used when saveOnly == true
   // no additional conditions were added with the intention of keeping the code easier to read
   // and not full of if conditions

   freeScratchable.init(TR::RealRegister::LastFPR + 1, self()->trMemory());

   // first, consider all argument registers free
   for (i1=TR::RealRegister::FirstGPR; i1<=TR::RealRegister::LastFPR; i1++)
      {
      if (!properties.getReserved(REGNUM(i1)))
         {
         freeScratchable.set(i1);
         }
      }
   // second, go through all parameters and reset registers that are actually used
   for (paramCursor=paramIterator.getFirst(); paramCursor!=NULL; paramCursor=paramIterator.getNext())
      {
      int32_t lri = paramCursor->getLinkageRegisterIndex();
      TR::DataType type = paramCursor->getType();

      if (lri >= 0)
         {
         TR::RealRegister::RegNum regNum;
         bool twoRegs = (TR::Compiler->target.is32Bit() && type.isInt64() && lri < properties.getNumIntArgRegs()-1);

         if (!type.isFloatingPoint())
            {
            regNum = properties.getIntegerArgumentRegister(lri);
            if (paramCursor->isReferencedParameter()) freeScratchable.reset(regNum);
            if (twoRegs)
               if (paramCursor->isReferencedParameter()) freeScratchable.reset(regNum+1);
            }
         else
            {
            regNum = properties.getFloatArgumentRegister(lri);
            if (paramCursor->isReferencedParameter()) freeScratchable.reset(regNum);
            if (twoRegs)
               if (paramCursor->isReferencedParameter()) freeScratchable.reset(regNum+1);
            }
         }
      }

   for (paramCursor=paramIterator.getFirst(); paramCursor!=NULL; paramCursor=paramIterator.getNext())
      {
      int32_t lri = paramCursor->getLinkageRegisterIndex();
      int32_t ai  = paramCursor->getAllocatedIndex();
      int32_t offset = self()->calculateParameterRegisterOffset(paramCursor->getParameterOffset(), *paramCursor);
      TR::DataType type = paramCursor->getType();
      int32_t dtype = type.getDataType();


      // TODO: Is there an accurate assume to insert here ?
      if (lri >= 0)
         {
         if (!paramCursor->isReferencedParameter() && !paramCursor->isParmHasToBeOnStack()) continue;

         TR::RealRegister::RegNum regNum;
         bool twoRegs = (TR::Compiler->target.is32Bit() && type.isInt64() && lri < properties.getNumIntArgRegs()-1);

         if (type.isFloatingPoint())
            regNum = properties.getFloatArgumentRegister(lri);
         else
            regNum = properties.getIntegerArgumentRegister(lri);

         // Do not save arguments to the stack if in Full Speed Debug and saveOnly is not set.
         // If not in Full Speed Debug, the arguments will be saved.
         if (((ai<0 || self()->hasToBeOnStack(paramCursor)) && !fsd) || (fsd && saveOnly))
            {
            switch (dtype)
               {
               case TR::Int8:
               case TR::Int16:
               case TR::Int32:
                  {
                  TR::InstOpCode::Mnemonic op = TR::InstOpCode::stw;
                  if (!all_saved) cursor = generateMemSrc1Instruction(self()->cg(), op, firstNode,
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()), REAL_REGISTER(regNum), cursor);
                  }
                  break;
               case TR::Address:
                  if (!all_saved) cursor = generateMemSrc1Instruction(self()->cg(),TR::InstOpCode::Op_st, firstNode,
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, TR::Compiler->om.sizeofReferenceAddress(), self()->cg()), REAL_REGISTER(regNum), cursor);
                  break;
               case TR::Int64:
                  if (!all_saved) cursor = generateMemSrc1Instruction(self()->cg(),TR::InstOpCode::Op_st, firstNode,
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, TR::Compiler->om.sizeofReferenceAddress(), self()->cg()), REAL_REGISTER(regNum), cursor);
                  if (twoRegs)
                     {
                     if (!all_saved) cursor = generateMemSrc1Instruction(self()->cg(), TR::InstOpCode::stw, firstNode,
                              new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset+4, 4, self()->cg()),
                              REAL_REGISTER(REGNUM(regNum+1)), cursor);
                     if (ai<0)
                        freeScratchable.set(regNum+1);
                     }
                  break;
               case TR::Float:
                  cursor = generateMemSrc1Instruction(self()->cg(), TR::InstOpCode::stfs, firstNode,
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()),
                           REAL_REGISTER(regNum), cursor);
                  break;
               case TR::Double:
                  cursor = generateMemSrc1Instruction(self()->cg(), TR::InstOpCode::stfd, firstNode,
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 8, self()->cg()),
                           REAL_REGISTER(regNum), cursor);
                  break;
               default:
                  TR_ASSERT(false, "assertion failure");
                  break;
               }

               if (ai<0)
                  freeScratchable.set(regNum);
            }

         // Global register is allocated to this argument.

         // Don't process if in Full Speed Debug and saveOnly is set
         if (ai>=0 && (!fsd || !saveOnly))
            {
            if (regNum != ai)      // Equal assignment: do nothing
               {
               if (freeScratchable.isSet(ai))
                  {
                  cursor = generateTrg1Src1Instruction(self()->cg(),
                              (type.isFloatingPoint()) ? TR::InstOpCode::fmr:TR::InstOpCode::mr,
                              firstNode, REAL_REGISTER(REGNUM(ai)), REAL_REGISTER(regNum), cursor);
                  freeScratchable.reset(ai);
                  freeScratchable.set(regNum);
                  }
               else    // The status of target global register is unclear (i.e. it is a arg reg)
                  {
                  busyMoves[0][busyIndex] = regNum;
                  busyMoves[1][busyIndex] = ai;
                  busyMoves[2][busyIndex] = 0;
                  busyIndex++;
                  }
               }

            if (TR::Compiler->target.is32Bit() && type.isInt64())
               {
               int32_t aiLow = paramCursor->getAllocatedLow();

               if (!twoRegs)    // Low part needs to come from memory
                  {
                  offset += 4;   // We are dealing with the low part

                  if (freeScratchable.isSet(aiLow))
                     {
                     cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lwz, firstNode, REAL_REGISTER(REGNUM(aiLow)),
                                 new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()), cursor);
                     freeScratchable.reset(aiLow);
                     }
                  else
                     {
                     busyMoves[0][busyIndex] = offset;
                     busyMoves[1][busyIndex] = aiLow;
                     busyMoves[2][busyIndex] = 1;
                     busyIndex++;
                     }
                  }
               else if (regNum+1 != aiLow)  // Low part needs to be moved
                  {
                  if (freeScratchable.isSet(aiLow))
                     {
                     cursor = generateTrg1Src1Instruction(self()->cg(), TR::InstOpCode::mr,
                              firstNode, REAL_REGISTER(REGNUM(aiLow)),
                              REAL_REGISTER(REGNUM(regNum+1)), cursor);
                     freeScratchable.reset(aiLow);
                     freeScratchable.set(regNum+1);
                     }
                  else
                     {
                     busyMoves[0][busyIndex] = regNum+1;
                     busyMoves[1][busyIndex] = aiLow;
                     busyMoves[2][busyIndex] = 0;
                     busyIndex++;
                     }
                  }
               }
            }
         }

      // Don't process if in Full Speed Debug and saveOnly is set
      else if (ai >= 0 && (!fsd || !saveOnly))     // lri<0: arg needs to come from memory
         {
         switch (dtype)
            {
            case TR::Int8:
            case TR::Int16:
            case TR::Int32:
               if (freeScratchable.isSet(ai))
                  {
                  cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lwz, firstNode, REAL_REGISTER(REGNUM(ai)),
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()), cursor);
                  freeScratchable.reset(ai);
                  }
               else
                  {
                  busyMoves[0][busyIndex] = offset;
                  busyMoves[1][busyIndex] = ai;
                  busyMoves[2][busyIndex] = 1;
                  busyIndex++;
                  }
               break;
            case TR::Address:
               if (freeScratchable.isSet(ai))
                  {
                  cursor = generateTrg1MemInstruction(self()->cg(),TR::InstOpCode::Op_load, firstNode, REAL_REGISTER(REGNUM(ai)),
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, TR::Compiler->om.sizeofReferenceAddress(), self()->cg()), cursor);
                  freeScratchable.reset(ai);
                  }
               else
                  {
                  busyMoves[0][busyIndex] = offset;
                  busyMoves[1][busyIndex] = ai;
                  if (TR::Compiler->target.is64Bit())
                     busyMoves[2][busyIndex] = 2;
                  else
                     busyMoves[2][busyIndex] = 1;
                  busyIndex++;
                  }
               break;
            case TR::Int64:
               if (TR::Compiler->target.is64Bit())
                  {
                  if (freeScratchable.isSet(ai))
                     {
                     cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::ld, firstNode, REAL_REGISTER(REGNUM(ai)),
                              new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 8, self()->cg()), cursor);
                     freeScratchable.reset(ai);
                     }
                  else
                     {
                     busyMoves[0][busyIndex] = offset;
                     busyMoves[1][busyIndex] = ai;
                     busyMoves[2][busyIndex] = 2;
                     busyIndex++;
                     }
                  }
               else // 32-bit
                  {
                  if (freeScratchable.isSet(ai))
                     {
                     cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lwz, firstNode, REAL_REGISTER(REGNUM(ai)),
                              new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()), cursor);
                     freeScratchable.reset(ai);
                     }
                  else
                     {
                     busyMoves[0][busyIndex] = offset;
                     busyMoves[1][busyIndex] = ai;
                     busyMoves[2][busyIndex] = 1;
                     busyIndex++;
                     }

                  ai = paramCursor->getAllocatedLow();
                  if (freeScratchable.isSet(ai))
                     {
                     cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lwz, firstNode, REAL_REGISTER(REGNUM(ai)),
                              new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset+4, 4, self()->cg()), cursor);
                     freeScratchable.reset(ai);
                     }
                  else
                     {
                     busyMoves[0][busyIndex] = offset+4;
                     busyMoves[1][busyIndex] = ai;
                     busyMoves[2][busyIndex] = 1;
                     busyIndex++;
                     }
                  }
               break;
            case TR::Float:
               if (freeScratchable.isSet(ai))
                  {
                  cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lfs, firstNode, REAL_REGISTER(REGNUM(ai)),
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 4, self()->cg()), cursor);
                  freeScratchable.reset(ai);
                  }
               else
                  {
                  busyMoves[0][busyIndex] = offset;
                  busyMoves[1][busyIndex] = ai;
                  busyMoves[2][busyIndex] = 3;
                  busyIndex++;
                  }
               break;
            case TR::Double:
               if (freeScratchable.isSet(ai))
                  {
                  cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lfd, firstNode, REAL_REGISTER(REGNUM(ai)),
                           new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, offset, 8, self()->cg()), cursor);
                  freeScratchable.reset(ai);
                  }
               else
                  {
                  busyMoves[0][busyIndex] = offset;
                  busyMoves[1][busyIndex] = ai;
                  busyMoves[2][busyIndex] = 4;
                  busyIndex++;
                  }
               break;
            default:
               break;
            }
         }
      }

   if (!fsd || !saveOnly)
      {
      bool     freeMore = true;
      int32_t  numMoves = busyIndex;

      while (freeMore && numMoves>0)
         {
         freeMore = false;
         for (i1=0; i1<busyIndex; i1++)
            {
            int32_t source = busyMoves[0][i1];
            int32_t target = busyMoves[1][i1];
            if (!(target<0) && freeScratchable.isSet(target))
               {
               switch(busyMoves[2][i1])
                  {
                  case 0:
                     cursor = generateTrg1Src1Instruction(self()->cg(), (source<=TR::RealRegister::LastGPR)?TR::InstOpCode::mr:TR::InstOpCode::fmr,
                              firstNode, REAL_REGISTER(REGNUM(target)), REAL_REGISTER(REGNUM(source)), cursor);
                     freeScratchable.set(source);
                     break;
                  case 1:
                     cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lwz, firstNode, REAL_REGISTER(REGNUM(target)),
                              new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, source, 4, self()->cg()), cursor);
                     break;
                  case 2:
                     cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::ld, firstNode, REAL_REGISTER(REGNUM(target)),
                              new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, source, 8, self()->cg()), cursor);
                     break;
                  case 3:
                     cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lfs, firstNode, REAL_REGISTER(REGNUM(target)),
                              new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, source, 4, self()->cg()), cursor);
                     break;
                  case 4:
                     cursor = generateTrg1MemInstruction(self()->cg(), TR::InstOpCode::lfd, firstNode, REAL_REGISTER(REGNUM(target)),
                              new (self()->trHeapMemory()) TR::MemoryReference(stackPtr, source, 8, self()->cg()), cursor);
                     break;
                  }

               freeScratchable.reset(target);
               freeMore = true;
               busyMoves[0][i1] = busyMoves[1][i1] = -1;
               numMoves--;
               }
            }
         }

      TR_ASSERT(numMoves<=0, "Circular argument register dependency can and should be avoided.");
      }

   return(cursor);
   }
Esempio n. 6
0
// Assignment operator
Url&
Url::operator=(const Url& rhs)
{
   if (this != &rhs) // handle the assignment to self case
   {
      reset();

      // Copy the members
      mScheme = rhs.mScheme;
      mDisplayName = rhs.mDisplayName;
      mUserId = rhs.mUserId;
      mPassword = rhs.mPassword;
      mPasswordSet = rhs.mPasswordSet;
      mHostAddress = rhs.mHostAddress;
      mHostPort = rhs.mHostPort;
      mPath = rhs.mPath;
      mAngleBracketsIncluded = rhs.mAngleBracketsIncluded;

      if (rhs.mpUrlParameters)
      {
         mpUrlParameters = new UtlDList;
         
         UtlDListIterator paramIterator(*rhs.mpUrlParameters);
         NameValuePair* rhsParam;
         while ((rhsParam = (NameValuePair*) paramIterator()))
         {
            mpUrlParameters->append(new NameValuePair(*rhsParam));
         }
      }
      else
      {
         mRawUrlParameters = rhs.mRawUrlParameters;
      }

      if (rhs.mpHeaderOrQueryParameters)
      {
         mpHeaderOrQueryParameters = new UtlDList;
         
         UtlDListIterator paramIterator(*rhs.mpHeaderOrQueryParameters);
         NameValuePair* rhsParam;
         while ((rhsParam = (NameValuePair*) paramIterator()))
         {
            mpHeaderOrQueryParameters->append(new NameValuePair(*rhsParam));
         }
      }
      else
      {
         mRawHeaderOrQueryParameters = rhs.mRawHeaderOrQueryParameters;
      }

      if (rhs.mpFieldParameters)
      {
         mpFieldParameters = new UtlDList;
         
         UtlDListIterator paramIterator(*rhs.mpFieldParameters);
         NameValuePair* rhsParam;
         while ((rhsParam = (NameValuePair*) paramIterator()))
         {
            mpFieldParameters->append(new NameValuePair(*rhsParam));
         }         
      }
      else
      {
         mRawFieldParameters = rhs.mRawFieldParameters;
      }
   }

   return *this;
}