Exemplo n.º 1
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.º 2
0
uint32_t
TR::S390HelperCallSnippet::getLength(int32_t)
   {
   uint32_t length;
   TR::SymbolReference * helperSymRef = getHelperSymRef();

   // LARL + BRASL/BRCL
   length = 12;

   if (helperSymRef == cg()->symRefTab()->element(TR_induceOSRAtCurrentPC))
      {
      length += TR::S390CallSnippet::instructionCountForArguments(getNode(), cg());
      }

   length += getLoadVMThreadInstructionLength(cg());

   length += getRuntimeInstrumentationOnOffInstructionLength(cg());

   return length;
   }
Exemplo n.º 3
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;
   }