Ejemplo n.º 1
0
TR::Register *IA32LinkageUtils::pushLongArg(
      TR::Node *child,
      TR::CodeGenerator *cg)
   {
   TR::Register *pushRegister;
   if (child->getRegister() == NULL)
      {
      if (child->getOpCode().isLoadConst())
         {
         TR_X86OpCodes pushOp;

         int32_t highValue = child->getLongIntHigh();
         if (highValue >= -128 && highValue <= 127)
            {
            pushOp = PUSHImms;
            }
         else
            {
            pushOp = PUSHImm4;
            }
         generateImmInstruction(pushOp, child, highValue, cg);

         int32_t lowValue = child->getLongIntLow();
         if (lowValue >= -128 && lowValue <= 127)
            {
            pushOp = PUSHImms;
            }
         else
            {
            pushOp = PUSHImm4;
            }
         generateImmInstruction(pushOp, child, lowValue, cg);
         cg->decReferenceCount(child);
         return NULL;
         }
      else if (child->getOpCodeValue() == TR::dbits2l &&
               !child->normalizeNanValues() &&
               child->getReferenceCount() == 1)
         {
         pushRegister = pushDoubleArg(child->getFirstChild(), cg);
         cg->decReferenceCount(child);
         return pushRegister;
         }
      else if (child->getOpCode().isMemoryReference() &&
                child->getReferenceCount() == 1)
         {
         TR::MemoryReference  *lowMR = generateX86MemoryReference(child, cg);
         generateMemInstruction(PUSHMem, child, generateX86MemoryReference(*lowMR,4, cg), cg);
         generateMemInstruction(PUSHMem, child, lowMR, cg);
         lowMR->decNodeReferenceCounts(cg);
         return NULL;
         }
      }

   pushRegister = cg->evaluate(child);
   generateRegInstruction(PUSHReg, child, pushRegister->getHighOrder(), cg);
   generateRegInstruction(PUSHReg, child, pushRegister->getLowOrder(), cg);
   cg->decReferenceCount(child);
   return pushRegister;
   }
Ejemplo n.º 2
0
TR::Register *IA32LinkageUtils::pushFloatArg(
      TR::Node *child,
      TR::CodeGenerator *cg)
   {
   TR::Register *pushRegister;
   if (child->getRegister() == NULL)
      {
      if (child->getOpCodeValue() == TR::fconst)
         {
         int32_t value = child->getFloatBits();
         TR_X86OpCodes pushOp;
         if (value >= -128 && value <= 127)
            {
            pushOp = PUSHImms;
            }
         else
            {
            pushOp = PUSHImm4;
            }
         generateImmInstruction(pushOp, child, value, cg);
         cg->decReferenceCount(child);
         return NULL;
         }
      else if (child->getReferenceCount() == 1)
         {
         if (child->getOpCode().isLoad())
            {
            TR::MemoryReference  *tempMR = generateX86MemoryReference(child, cg);
            generateMemInstruction(PUSHMem, child, tempMR, cg);
            tempMR->decNodeReferenceCounts(cg);
            cg->decReferenceCount(child);
            return NULL;
            }
      else if (child->getOpCodeValue() == TR::ibits2f)
         {
         pushRegister = pushIntegerWordArg(child->getFirstChild(), cg);
         cg->decReferenceCount(child);
         return pushRegister;
         }
      }
   }

   pushRegister = cg->evaluate(child);
   TR::RealRegister *espReal = cg->machine()->getRealRegister(TR::RealRegister::esp);
   generateRegImmInstruction(SUB4RegImms, child, espReal, 4, cg);

   if (cg->useSSEForSinglePrecision() && pushRegister->getKind() == TR_FPR)
      generateMemRegInstruction(MOVSSMemReg, child, generateX86MemoryReference(espReal, 0, cg), pushRegister, cg);
   else
      generateFPMemRegInstruction(FSTMemReg, child, generateX86MemoryReference(espReal, 0, cg), pushRegister, cg);

   cg->decReferenceCount(child);
   return pushRegister;
   }
Ejemplo n.º 3
0
TR::Register *IA32LinkageUtils::pushIntegerWordArg(
      TR::Node *child,
      TR::CodeGenerator *cg)
   {
   TR::Register *pushRegister;
   if (child->getRegister() == NULL)
      {
      if (child->getOpCode().isLoadConst())
         {
         int32_t value = child->getInt();
         TR_X86OpCodes pushOp;
         if (value >= -128 && value <= 127)
            {
            pushOp = PUSHImms;
            }
         else
            {
            pushOp = PUSHImm4;
            }

         generateImmInstruction(pushOp, child, value, cg);
         cg->decReferenceCount(child);
         return NULL;
         }
      else if (child->getOpCodeValue() == TR::loadaddr)
         {
         TR::SymbolReference * symRef = child->getSymbolReference();
         TR::StaticSymbol *sym = symRef->getSymbol()->getStaticSymbol();
         if (sym)
            {
            TR_ASSERT(!symRef->isUnresolved(), "pushIntegerWordArg loadaddr expecting resolved symbol");
            generateImmSymInstruction(PUSHImm4, child, (uintptrj_t)sym->getStaticAddress(), symRef, cg);
            cg->decReferenceCount(child);
            return NULL;
            }
         }
      else if (child->getOpCodeValue() == TR::fbits2i &&
               !child->normalizeNanValues() &&
               child->getReferenceCount() == 1)
         {
         pushRegister = pushFloatArg(child->getFirstChild(), cg);
         cg->decReferenceCount(child);
         return pushRegister;
         }
      else if (child->getOpCode().isMemoryReference() &&
               (child->getReferenceCount() == 1) &&
               (child->getSymbolReference() != cg->comp()->getSymRefTab()->findVftSymbolRef()))
         {
         TR::MemoryReference  *tempMR = generateX86MemoryReference(child, cg);
         generateMemInstruction(PUSHMem, child, tempMR, cg);
         tempMR->decNodeReferenceCounts(cg);
         cg->decReferenceCount(child);
         return NULL;
         }
      }

   pushRegister = cg->evaluate(child);
   generateRegInstruction(PUSHReg, child, pushRegister, cg);
   cg->decReferenceCount(child);
   return pushRegister;
   }
Ejemplo n.º 4
0
TR::Register *IA32LinkageUtils::pushDoubleArg(
      TR::Node *child,
      TR::CodeGenerator *cg)
   {
   TR::Register *pushRegister;
   if (child->getRegister() == NULL)
      {
      if (child->getOpCodeValue() == TR::dconst)
         {
         TR_X86OpCodes pushOp;

         int32_t highValue = child->getLongIntHigh();
         if (highValue >= -128 && highValue <= 127)
            {
            pushOp = PUSHImms;
            }
         else
            {
            pushOp = PUSHImm4;
            }
         generateImmInstruction(pushOp, child, highValue, cg);

         int32_t lowValue = child->getLongIntLow();
         if (lowValue >= -128 && lowValue <= 127)
            {
            pushOp = PUSHImms;
            }
         else
            {
            pushOp = PUSHImm4;
            }
         generateImmInstruction(pushOp, child, lowValue, cg);
         cg->decReferenceCount(child);
         return NULL;
         }
      else if (child->getReferenceCount() == 1)
         {
         if (child->getOpCode().isLoad())
            {
            TR::MemoryReference  *lowMR = generateX86MemoryReference(child, cg);
            generateMemInstruction(PUSHMem, child, generateX86MemoryReference(*lowMR, 4, cg), cg);
            generateMemInstruction(PUSHMem, child, lowMR, cg);
            lowMR->decNodeReferenceCounts(cg);
            cg->decReferenceCount(child);
            return NULL;
            }
         else if (child->getOpCodeValue() == TR::lbits2d)
            {
            pushRegister = pushLongArg(child->getFirstChild(), cg);
            cg->decReferenceCount(child);
            return pushRegister;
            }
         }
      }

   pushRegister = cg->evaluate(child);
   TR::RealRegister *espReal = cg->machine()->getRealRegister(TR::RealRegister::esp);
   generateRegImmInstruction(SUB4RegImms, child, espReal, 8, cg);

   if (cg->useSSEForSinglePrecision() && pushRegister->getKind() == TR_FPR)
      generateMemRegInstruction(MOVSDMemReg, child, generateX86MemoryReference(espReal, 0, cg), pushRegister, cg);
   else
      generateFPMemRegInstruction(DSTMemReg, child, generateX86MemoryReference(espReal, 0, cg), pushRegister, cg);

   cg->decReferenceCount(child);
   return pushRegister;
   }
Ejemplo n.º 5
0
void TR_OutlinedInstructions::generateOutlinedInstructionsDispatch()
   {
   // Switch to cold helper instruction stream.
   //
   TR::Register    *vmThreadReg = _cg->getMethodMetaDataRegister();
   TR::Instruction *savedFirstInstruction = comp()->getFirstInstruction();
   TR::Instruction *savedAppendInstruction = comp()->getAppendInstruction();
   comp()->setFirstInstruction(NULL);
   comp()->setAppendInstruction(NULL);

   new (_cg->trHeapMemory()) TR::X86LabelInstruction(NULL, LABEL, _entryLabel, _cg);

   if (_rematerializeVMThread)
      {
      generateRegInstruction(PUSHReg, _callNode, vmThreadReg, _cg);
      generateRestoreVMThreadInstruction ( _callNode, _cg);
      TR::MemoryReference  *vmThreadMR = generateX86MemoryReference(vmThreadReg, (TR::Compiler->target.is64Bit()) ? 16 : 8, _cg);
      generateRegMemInstruction (LRegMem(), _callNode, vmThreadReg, vmThreadMR, _cg);
      }
   TR::Register *resultReg=NULL;
   if (_callNode->getOpCode().isCallIndirect())
      resultReg = TR::TreeEvaluator::performCall(_callNode, true, false, _cg);
   else
      resultReg = TR::TreeEvaluator::performCall(_callNode, false, false, _cg);

   if (_rematerializeVMThread)
      {
      generateRegInstruction(POPReg, _callNode, vmThreadReg, _cg);
      }

   if (_targetReg)
      {
      TR_ASSERT(resultReg, "assertion failure");
      TR::RegisterPair *targetRegPair = _targetReg->getRegisterPair();
      TR::RegisterPair *resultRegPair =  resultReg->getRegisterPair();
      if (targetRegPair)
         {
         TR_ASSERT(resultRegPair, "OutlinedInstructions: targetReg is a register pair and resultReg is not");
         generateRegRegInstruction(_targetRegMovOpcode, _callNode, targetRegPair->getLowOrder(),  resultRegPair->getLowOrder(),  _cg);
         generateRegRegInstruction(_targetRegMovOpcode, _callNode, targetRegPair->getHighOrder(), resultRegPair->getHighOrder(), _cg);
         }
      else
         {
         TR_ASSERT(!resultRegPair, "OutlinedInstructions: resultReg is a register pair and targetReg is not");
         generateRegRegInstruction(_targetRegMovOpcode, _callNode, _targetReg, resultReg, _cg);
         }
      }

   _cg->decReferenceCount(_callNode);

   if (_restartLabel)
      generateLabelInstruction(JMP4, _callNode, _restartLabel, _cg);
   else
      {
      // Java-specific.
      // No restart label implies we're not coming back from this call,
      // so it's safe to put data after the call.  In the case of calling a throw
      // helper, there's an ancient busted handshake that expects to find a 4-byte
      // offset here, so we have to comply...
      //
      // When the handshake is removed, we can delete this zero.
      //
      generateImmInstruction(DDImm4, _callNode, 0, _cg);
      }

   // Dummy label to delimit the end of the helper call dispatch sequence (for exception ranges).
   //
   generateLabelInstruction(LABEL, _callNode, TR::LabelSymbol::create(_cg->trHeapMemory(),_cg), _cg);

   // Switch from cold helper instruction stream.
   //
   _firstInstruction = comp()->getFirstInstruction();
   _appendInstruction = comp()->getAppendInstruction();
   comp()->setFirstInstruction(savedFirstInstruction);
   comp()->setAppendInstruction(savedAppendInstruction);
   }