Esempio n. 1
0
int32_t TR::PPCAlignedLabelInstruction::estimateBinaryLength(int32_t currentEstimate)
   {
   TR_ASSERT((getAlignment() % PPC_INSTRUCTION_LENGTH) == 0, "label alignment must be a multiple of the instruction length, alignment = %d", getAlignment());
   TR_ASSERT(getOpCodeValue() == TR::InstOpCode::label, "AlignedLabel only supported for TR::InstOpCode::Label opcodes");
   setEstimatedBinaryLength(getAlignment() - PPC_INSTRUCTION_LENGTH);
   return currentEstimate + getEstimatedBinaryLength();
   }
Esempio n. 2
0
void TR::ValidateChildTypes::validate(TR::Node *node)
   {
   auto opcode = node->getOpCode();
   if (opcode.expectedChildCount() != ILChildProp::UnspecifiedChildCount)
      {
      const auto expChildCount = opcode.expectedChildCount();
      const auto actChildCount = node->getNumChildren();
      /* Validate child types. */
      for (auto i = 0; i < actChildCount; ++i)
         {
         auto childOpcode = node->getChild(i)->getOpCode();
         if (childOpcode.getOpCodeValue() != TR::GlRegDeps)
            {
            const auto expChildType = opcode.expectedChildType(i);
            const auto actChildType = childOpcode.getDataType().getDataType();
            const auto expChildTypeName = (expChildType >= TR::NumTypes) ?
                                           "UnspecifiedChildType" :
                                           TR::DataType::getName(expChildType);
            const auto actChildTypeName = TR::DataType::getName(actChildType);
            TR::checkILCondition(node, (expChildType >= TR::NumTypes || actChildType == expChildType),
                                 comp(), "Child %d has unexpected type %s (expected %s)",
                                 i, actChildTypeName, expChildTypeName);
            }
         else
            {
            /**
             * Make sure the node is allowed to have a GlRegDeps child
             * and check that it is the last child.
             */
            TR::checkILCondition(node, opcode.canHaveGlRegDeps() && (i == actChildCount - 1),
                                 comp(), "Unexpected GlRegDeps child %d", i);
            }
         }
      }
   }
Esempio n. 3
0
int32_t TR::PPCControlFlowInstruction::estimateBinaryLength(int32_t currentEstimate)
   {
   switch(getOpCodeValue())
      {
      case TR::InstOpCode::iflong:
      case TR::InstOpCode::setbool:
      case TR::InstOpCode::idiv:
      case TR::InstOpCode::ldiv:
      case TR::InstOpCode::ifx:
      case TR::InstOpCode::iternary:
         if (useRegPairForResult())
            {
            if (!useRegPairForCond())
               setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 6);
            else
               setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 8);
            }
         else
            {
            if (!useRegPairForCond())
               setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 4);
            else
               setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 6);
            }
         break;
      case TR::InstOpCode::setbflt:
         setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 5);
         break;
      case TR::InstOpCode::setblong:
      case TR::InstOpCode::flcmpg:
      case TR::InstOpCode::flcmpl:
      case TR::InstOpCode::irem:
      case TR::InstOpCode::lrem:
      case TR::InstOpCode::d2i:
      case TR::InstOpCode::setbx:
         setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 6);
         break;
      case TR::InstOpCode::d2l:
         if (TR::Compiler->target.is64Bit())
            setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 6);
       else
            setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 8);
         break;
      case TR::InstOpCode::lcmp:
         setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 11);
         break;
      case TR::InstOpCode::cfnan:
         setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 2);
         break;
      case TR::InstOpCode::cdnan:
         setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 3);
         break;
      default:
         TR_ASSERT(false,"unknown control flow instruction (estimateBinaryLength)");
      }
   return currentEstimate + getEstimatedBinaryLength();
   }
Esempio n. 4
0
uint8_t *TR::PPCTrg1Src1ImmInstruction::generateBinaryEncoding()
   {

   uint8_t *instructionStart = cg()->getBinaryBufferCursor();
   uint8_t *cursor           = instructionStart;
   cursor = getOpCode().copyBinaryToBuffer(instructionStart);
   insertTargetRegister(toPPCCursor(cursor));
   insertSource1Register(toPPCCursor(cursor));
   if (getOpCodeValue() == TR::InstOpCode::srawi || getOpCodeValue() == TR::InstOpCode::srawi_r ||
       getOpCodeValue() == TR::InstOpCode::sradi || getOpCodeValue() == TR::InstOpCode::sradi_r ||
       getOpCodeValue() == TR::InstOpCode::extswsli)
      {
      insertShiftAmount(toPPCCursor(cursor));
      }
   else if (getOpCodeValue() == TR::InstOpCode::dtstdg)
      {
      setSourceImmediate(getSourceImmediate() << 10);
      insertImmediateField(toPPCCursor(cursor));
      }
   else
      {
      insertImmediateField(toPPCCursor(cursor));
      }

   addMetaDataForCodeAddress(cursor);

   cursor += PPC_INSTRUCTION_LENGTH;
   setBinaryLength(PPC_INSTRUCTION_LENGTH);
   setBinaryEncoding(instructionStart);
   return cursor;
   }
Esempio n. 5
0
uint8_t *TR::PPCSrc1Instruction::generateBinaryEncoding()
   {
   uint8_t *instructionStart = cg()->getBinaryBufferCursor();
   uint8_t *cursor           = instructionStart;
   cursor = getOpCode().copyBinaryToBuffer(instructionStart);
   insertSource1Register(toPPCCursor(cursor));
   if (getOpCodeValue() == TR::InstOpCode::mtfsf |
       getOpCodeValue() == TR::InstOpCode::mtfsfl ||
       getOpCodeValue() == TR::InstOpCode::mtfsfw)
      {
      insertMaskField(toPPCCursor(cursor));
      }
   else
      {
      insertImmediateField(toPPCCursor(cursor));
      }
   cursor += PPC_INSTRUCTION_LENGTH;
   setBinaryLength(PPC_INSTRUCTION_LENGTH);
   setBinaryEncoding(instructionStart);
   cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()) ;
   return cursor;
   }
Esempio n. 6
0
uint8_t *TR::PPCTrg1ImmInstruction::generateBinaryEncoding()
   {

   uint8_t *instructionStart = cg()->getBinaryBufferCursor();
   uint8_t *cursor           = instructionStart;
   cursor = getOpCode().copyBinaryToBuffer(instructionStart);
   insertTargetRegister(toPPCCursor(cursor));

   if (getOpCodeValue() == TR::InstOpCode::mtcrf ||
       getOpCodeValue() == TR::InstOpCode::mfocrf)
      {
      *((int32_t *)cursor) |= (getSourceImmediate()<<12);
      if ((TR::Compiler->target.cpu.id() >= TR_PPCgp) &&
          ((getSourceImmediate() & (getSourceImmediate() - 1)) == 0))
         // convert to PPC AS single field form
         *((int32_t *)cursor) |= 0x00100000;
      }
   else if (getOpCodeValue() == TR::InstOpCode::mfcr)
      {
      if ((TR::Compiler->target.cpu.id() >= TR_PPCgp) &&
          ((getSourceImmediate() & (getSourceImmediate() - 1)) == 0))
         // convert to PPC AS single field form
         *((int32_t *)cursor) |= (getSourceImmediate()<<12) | 0x00100000;
      else
         TR_ASSERT(getSourceImmediate() == 0xFF, "Bad field mask on mfcr");
      }
   else
      {
      insertImmediateField(toPPCCursor(cursor));
      }

   addMetaDataForCodeAddress(cursor);

   cursor += PPC_INSTRUCTION_LENGTH;
   setBinaryLength(PPC_INSTRUCTION_LENGTH);
   setBinaryEncoding(instructionStart);
   return cursor;
   }
Esempio n. 7
0
uint8_t *TR::PPCTrg1Src1Imm2Instruction::generateBinaryEncoding()
   {
   uint8_t *instructionStart = cg()->getBinaryBufferCursor();
   uint8_t *cursor           = instructionStart;
   cursor = getOpCode().copyBinaryToBuffer(instructionStart);
   insertTargetRegister(toPPCCursor(cursor));
   insertSource1Register(toPPCCursor(cursor));
   insertShiftAmount(toPPCCursor(cursor));
   insertMaskField(toPPCCursor(cursor), getOpCodeValue(), getLongMask());
   cursor += PPC_INSTRUCTION_LENGTH;
   setBinaryLength(PPC_INSTRUCTION_LENGTH);
   setBinaryEncoding(instructionStart);
   return cursor;
   }
Esempio n. 8
0
void TR::Validate_ireturnReturnType::validate(TR::Node *node)
   {
   auto opcode = node->getOpCode();
   if (opcode.getOpCodeValue() == TR::ireturn)
      {
      const auto childCount = node->getNumChildren();
      for (auto i = 0; i < childCount; ++i)
         {
         auto childOpcode = node->getChild(i)->getOpCode();
         const auto actChildType = childOpcode.getDataType().getDataType();
         const auto childTypeName = TR::DataType::getName(actChildType);
         TR::checkILCondition(node, (actChildType == TR::Int32 ||
                                     actChildType == TR::Int16 ||
                                     actChildType == TR::Int8),
                              comp(),"ireturn has an invalid child type %s (expected Int{8,16,32})",
                              childTypeName);
         }
      }
   }
Esempio n. 9
0
uint8_t *TR::PPCConditionalBranchInstruction::generateBinaryEncoding()
   {
   uint8_t        *instructionStart = cg()->getBinaryBufferCursor();
   TR::LabelSymbol *label            = getLabelSymbol();
   uint8_t        *cursor           = instructionStart;
   TR::Compilation *comp = cg()->comp();
   cursor = getOpCode().copyBinaryToBuffer(instructionStart);
   // bclr doesn't have a label
   if (label)
      {
      if (label->getCodeLocation() != NULL)
         {
         if (!getFarRelocation())
            {
            insertConditionRegister((uint32_t *)cursor);
            *(int32_t *)cursor |= ((label->getCodeLocation()-cursor) & 0xffff);
            }
         else // too far - need fix up
            {
            TR::InstOpCode::Mnemonic reversedOp;
            bool  linkForm = reversedConditionalBranchOpCode(getOpCodeValue(), &reversedOp);
            TR::InstOpCode reversedOpCode(reversedOp);
            TR::InstOpCode extraOpCode(linkForm?TR::InstOpCode::bl:TR::InstOpCode::b);

            cursor = reversedOpCode.copyBinaryToBuffer(cursor);
            insertConditionRegister((uint32_t *)cursor);
            *(int32_t *)cursor |= 0x0008;
            cursor += 4;

            cursor = extraOpCode.copyBinaryToBuffer(cursor);
            *(int32_t *)cursor |= ((label->getCodeLocation() - cursor) & 0x03fffffc);
            }
         }
      else
         {
         if (!getFarRelocation())
            {
            insertConditionRegister((uint32_t *)cursor);
            cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative16BitRelocation(cursor, label));
            }
         else // too far - need fix up
            {
            TR::InstOpCode::Mnemonic reversedOp;
            bool  linkForm = reversedConditionalBranchOpCode(getOpCodeValue(), &reversedOp);
            TR::InstOpCode reversedOpCode(reversedOp);
            TR::InstOpCode extraOpCode(linkForm?TR::InstOpCode::bl:TR::InstOpCode::b);

            cursor = reversedOpCode.copyBinaryToBuffer(cursor);
            insertConditionRegister((uint32_t *)cursor);
            *(int32_t *)cursor |= 0x0008;
            cursor += 4;

            cursor = extraOpCode.copyBinaryToBuffer(cursor);
            cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative24BitRelocation(cursor, label));
            }
         }
      }
   else
      insertConditionRegister((uint32_t *)cursor);

   // set up prediction bits if there is any.
   if (haveHint())
      {
      if (getFarRelocation())
         reverseLikeliness();
      if (getOpCode().setsCTR())
         *(int32_t *)instructionStart |= (getLikeliness() ? PPCOpProp_BranchLikelyMaskCtr : PPCOpProp_BranchUnlikelyMaskCtr);
      else
         *(int32_t *)instructionStart |= (getLikeliness() ? PPCOpProp_BranchLikelyMask : PPCOpProp_BranchUnlikelyMask) ;
      }

   cursor += 4;
   setBinaryLength(cursor - instructionStart);
   cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength());
   setBinaryEncoding(instructionStart);
   return cursor;
   }
Esempio n. 10
0
bool TR::ILValidator::treesAreValid(TR::TreeTop *start, TR::TreeTop *stop)
   {
   checkSoundness(start, stop);

   for (PostorderNodeOccurrenceIterator iter(start, _comp, "VALIDATOR"); iter != stop; ++iter)
      {
      updateNodeState(iter);

      // General node validation
      //
      validateNode(iter);

      //
      // Additional specific kinds of validation
      //

      TR::Node *node = iter.currentNode();
      if (node->getOpCodeValue() == TR::BBEnd)
         {
         // Determine whether this is the end of an extended block
         //
         bool isEndOfExtendedBlock = false;
         TR::TreeTop *nextTree = iter.currentTree()->getNextTreeTop();
         if (nextTree)
            {
            validityRule(iter, nextTree->getNode()->getOpCodeValue() == TR::BBStart, "Expected BBStart after BBEnd");
            isEndOfExtendedBlock = ! nextTree->getNode()->getBlock()->isExtensionOfPreviousBlock();
            }
         else
            {
            isEndOfExtendedBlock = true;
            }

         if (isEndOfExtendedBlock)
            validateEndOfExtendedBlock(iter);
         }

      auto opcode = node->getOpCode();
      if (opcode.expectedChildCount() != ILChildProp::UnspecifiedChildCount)
         {
         // Validate child expectations
         //

         const auto expChildCount = opcode.expectedChildCount();
         const auto actChildCount = node->getNumChildren();

         // validate child count
         if (!opcode.canHaveGlRegDeps())
            {
            // in the common case, no GlRegDeps child is expect nor present
            validityRule(iter, actChildCount == expChildCount,
                         "Child count %d does not match expected value of %d", actChildCount, expChildCount);
            }
         else if (actChildCount == (expChildCount + 1))
            {
            // adjust expected child number to account for a possible extra GlRegDeps
            // child and make sure the last child is actually a GlRegDeps
            validityRule(iter, node->getChild(actChildCount - 1)->getOpCodeValue() == TR::GlRegDeps,
                         "Child count %d does not match expected value of %d (%d without GlRegDeps) and last child is not a GlRegDeps",
                         actChildCount, expChildCount + 1, expChildCount);
            }
         else
            {
            // if expected and actual child counts don't match, then the child
            // count is just wrong, even with an expected GlRegDeps
            validityRule(iter, actChildCount == expChildCount,
                         "Child count %d matches neither expected values of %d (without GlRegDeps) nor %d (with GlRegDeps)",
                         actChildCount, expChildCount, expChildCount + 1);
            }

         // validate child types
         for (auto i = 0; i < actChildCount; ++i)
            {
            auto childOpcode = node->getChild(i)->getOpCode();
            if (childOpcode.getOpCodeValue() != TR::GlRegDeps)
               {
               const auto expChildType = opcode.expectedChildType(i);
               const auto actChildType = childOpcode.getDataType().getDataType();
               const auto expChildTypeName = expChildType == ILChildProp::UnspecifiedChildType ? "UnspecifiedChildType" : TR::DataType::getName(expChildType);
               const auto actChildTypeName = TR::DataType::getName(actChildType);
               validityRule(iter, expChildType == ILChildProp::UnspecifiedChildType || actChildType == expChildType,
                            "Child %d has unexpected type %s (expected %s)" , i, actChildTypeName, expChildTypeName);
               }
            else
               {
               // make sure the node is allowed to have a GlRegDeps child
               // and make sure that it is the last child
               validityRule(iter, opcode.canHaveGlRegDeps() && (i == actChildCount - 1), "Unexpected GlRegDeps child %d", i);
               }
            }
         }
      }

   return _isValidSoFar;
   }