Exemplo n.º 1
0
   S390HelperCallSnippet(TR::CodeGenerator        *cg,
                         TR::Node                 *node,
                         TR::LabelSymbol           *snippetlab,
                         TR::SymbolReference      *helper,
                         TR::LabelSymbol           *restartlab = NULL,
                         int32_t                  s = 0)
      : TR::Snippet(cg, node, snippetlab, (restartlab == NULL)),
        _reStartLabel(restartlab),
        _helperSymRef(helper),
	    sizeOfArguments(s)
      {
      // If we don't have a restart label, then we must not be returning to the mainline code -
      // hence, always except.
      TR_ASSERT(restartlab || (!restartlab && helper->canCauseGC()),
                 "An exception snippet is marked as cannot cause GC");

      // Set up appropriate GC Map
      if (!restartlab)
        gcMap().setGCRegisterMask((uint32_t)0x00000000);  // everything gets clobbered if we're taking an exception.
      }
Exemplo n.º 2
0
uint8_t *TR::X86FPConversionSnippet::emitCallToConversionHelper(uint8_t *buffer)
   {
   intptrj_t callInstructionAddress = (intptrj_t)buffer;
   intptrj_t nextInstructionAddress = callInstructionAddress+5;

   *buffer++ = 0xe8;      // CallImm4

   intptrj_t helperAddress = (intptrj_t)getHelperSymRef()->getMethodAddress();
   if (cg()->directCallRequiresTrampoline(helperAddress, callInstructionAddress))
      {
      helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(getHelperSymRef()->getReferenceNumber(), (void *)buffer);

      TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinRIPRange(helperAddress, nextInstructionAddress),
                      "Local helper trampoline must be reachable directly");
      }
   *(int32_t *)buffer = (int32_t)(helperAddress - nextInstructionAddress);
   cg()->addProjectSpecializedRelocation(buffer, (uint8_t *)getHelperSymRef(), NULL, TR_HelperAddress,
                                                         __FILE__, __LINE__, getNode());
   buffer += 4;
   gcMap().registerStackMap(buffer, cg());
   return buffer;
   }
Exemplo n.º 3
0
uint8_t *TR::PPCHelperCallSnippet::genHelperCall(uint8_t *buffer)
   {
   intptrj_t helperAddress = (intptrj_t)getDestination()->getSymbol()->castToMethodSymbol()->getMethodAddress();

   if (cg()->directCallRequiresTrampoline(helperAddress, (intptrj_t)buffer))
      {
      helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(getDestination()->getReferenceNumber(), (void *)buffer);

      TR_ASSERT_FATAL(TR::Compiler->target.cpu.isTargetWithinIFormBranchRange(helperAddress, (intptrj_t)buffer),
                      "Helper address is out of range");
      }

   intptrj_t distance = helperAddress - (intptrj_t)buffer;

   // b|bl distance
   *(int32_t *)buffer = 0x48000000 | (distance & 0x03fffffc);
   if (_restartLabel != NULL)
      {
      *(int32_t *)buffer |= 0x00000001;
      }

   cg()->addProjectSpecializedRelocation(buffer,(uint8_t *)getDestination(), NULL, TR_HelperAddress,
                          __FILE__, __LINE__, getNode());
   buffer += 4;

   gcMap().registerStackMap(buffer, cg());

   if (_restartLabel != NULL)
      {
      int32_t returnDistance = _restartLabel->getCodeLocation() - buffer;
      *(int32_t *)buffer = 0x48000000 | (returnDistance & 0x03fffffc);
      buffer += 4;
      }

   return buffer;
   }
Exemplo n.º 4
0
uint8_t *
TR::S390HelperCallSnippet::emitSnippetBody()
   {
   uint8_t * cursor = cg()->getBinaryBufferCursor();
   getSnippetLabel()->setCodeLocation(cursor);

   TR::Node * callNode = getNode();
   TR::SymbolReference * helperSymRef = getHelperSymRef();
   bool jitInduceOSR = helperSymRef == cg()->symRefTab()->element(TR_induceOSRAtCurrentPC);
   if (jitInduceOSR)
      {
      // Flush in-register arguments back to the stack for interpreter
      cursor = TR::S390CallSnippet::S390flushArgumentsToStack(cursor, callNode, getSizeOfArguments(), cg());
      }


   uint32_t rEP = (uint32_t) cg()->getEntryPointRegister() - 1;

   //load vm thread into gpr13
   cursor = generateLoadVMThreadInstruction(cg(), cursor);

   // Generate RIOFF if RI is supported.
   cursor = generateRuntimeInstrumentationOnOffInstruction(cg(), cursor, TR::InstOpCode::RIOFF);

   if (                                                                               // Methods that require
             alwaysExcept())                                                          // R14 to point to snippet:
      {
      // For trace method entry/exit, we need to set up R14 to point to the
      // beginning of the data segment.  We will use BRASL to automatically
      // set R14 correctly.

      // For methods that lead to exceptions, and never return to the
      // main code, we set up R14, so that if GC occurs, the stackwalker
      // will see R14 is pointing to this snippet, and pick up the correct
      // stack map.

      *(int16_t *) cursor = 0xC0E5;                                                   // BRASL  R14, <Helper Addr>
      cursor += sizeof(int16_t);
      }
   else                                                                               // Otherwise:
      {
      // We're not sure if the helper will return.  So, we need to provide
      // the return addr of the main line code, so that when helper call
      // completes, it can jump back properly.

      // Load Return Address into R14.
      intptrj_t returnAddr = (intptrj_t)getReStartLabel()->getCodeLocation();         // LARL   R14, <Return Addr>
      *(int16_t *) cursor = 0xC0E0;
      cursor += sizeof(int16_t);
      *(int32_t *) cursor = (int32_t)((returnAddr - (intptrj_t)(cursor - 2)) / 2);
      cursor += sizeof(int32_t);

      *(int16_t *) cursor = 0xC0F4;                                                   // BRCL   <Helper Addr>
      cursor += sizeof(int16_t);
      }

   // Calculate the relative offset to get to helper method.
   // If MCC is not supported, everything should be reachable.
   // If MCC is supported, we will look up the appropriate trampoline, if
   //     necessary.
   intptrj_t destAddr = (intptrj_t)(helperSymRef->getSymbol()->castToMethodSymbol()->getMethodAddress());

#if defined(TR_TARGET_64BIT)
#if defined(J9ZOS390)
   if (cg()->comp()->getOption(TR_EnableRMODE64))
#endif
      {
      if (NEEDS_TRAMPOLINE(destAddr, cursor, cg()))
         {
         destAddr = cg()->fe()->indexedTrampolineLookup(helperSymRef->getReferenceNumber(), (void *)cursor);
         this->setUsedTrampoline(true);

         // We clobber rEP if we take a trampoline. Update our register map if necessary.
         if (gcMap().getStackMap() != NULL)
            {
            gcMap().getStackMap()->maskRegisters(~(0x1 << (rEP)));
            }
         }
      }
#endif

   TR_ASSERT(CHECK_32BIT_TRAMPOLINE_RANGE(destAddr, cursor), "Helper Call is not reachable.");
   this->setSnippetDestAddr(destAddr);

   *(int32_t *) cursor = (int32_t)((destAddr - (intptrj_t)(cursor - 2)) / 2);
   AOTcgDiag1(cg()->comp(), "add TR_HelperAddress cursor=%x\n", cursor);
   cg()->addProjectSpecializedRelocation(cursor, (uint8_t*) helperSymRef, NULL, TR_HelperAddress,
                             __FILE__, __LINE__, getNode());
   cursor += sizeof(int32_t);

   gcMap().registerStackMap(cursor, cg());

   return cursor;
   }