Example #1
0
static void insertMaskField(uint32_t *instruction, TR::InstOpCode::Mnemonic op, int64_t lmask)
   {
   int32_t encoding;
   // A mask is is a string of 1 bits surrounded by a string of 0 bits.
   // For word instructions it is specified through its start and stop bit
   // numbers.  Note - the mask is considered circular so the start bit
   // number may be greater than the stop bit number.
   // Examples:     input     start   stop
   //              00FFFF00      8     23
   //              00000001     31     31
   //              80000001     31      0
   //              FFFFFFFF      0     31  (somewhat arbitrary)
   //              00000000      ?      ?  (illegal)
   //
   // For doubleword instructions only one of the start bit or stop bit is
   // specified and the other is implicit in the instruction.  The bit
   // number is strangely encoded in that the low order bit 5 comes first
   // and the high order bits after.  The field is in bit positions 21-26.

   // For these instructions the immediate is not a mask but a 1-bit immediate operand
   if (op == TR::InstOpCode::cmprb)
      {
      // populate 1-bit L field
      encoding = (((uint32_t)lmask) & 0x1) << 21;
      *instruction |= encoding;
      return;
      }

   // For these instructions the immediate is not a mask but a 2-bit immediate operand
   if (op == TR::InstOpCode::xxpermdi ||
       op == TR::InstOpCode::xxsldwi)
      {
      encoding = (((uint32_t)lmask) & 0x3) << 8;
      *instruction |= encoding;
      return;
      }

   if (op == TR::InstOpCode::addex ||
       op == TR::InstOpCode::addex_r)
      {
      encoding = (((uint32_t)lmask) & 0x3) << 9;
      *instruction |= encoding;
      return;
      }

   // For these instructions the immediate is not a mask but a 4-bit immediate operand
   if (op == TR::InstOpCode::vsldoi)
      {
      encoding = (((uint32_t)lmask) & 0xf)<< 6;
      *instruction |= encoding;
      return;
      }

   TR::InstOpCode       opCode(op);

   if (opCode.isCRLogical())
      {
      encoding = (((uint32_t) lmask) & 0xffffffff);
      *instruction |= encoding;
      return;
      }

   TR_ASSERT(lmask, "A mask of 0 cannot be encoded");   

   if (opCode.isDoubleWord())
      {
      int bitnum;

      if (opCode.useMaskEnd())
	 {
         TR_ASSERT(contiguousBits(lmask) &&
		((lmask & CONSTANT64(0x8000000000000000)) != 0) &&
		((lmask == -1) || ((lmask & 0x1) == 0)),
		"Bad doubleword mask for ME encoding");
         bitnum = leadingOnes(lmask) - 1;
	 }
      else
	 {
         bitnum = leadingZeroes(lmask);
	 // assert on cases like 0xffffff00000000ff
         TR_ASSERT((bitnum != 0) || (lmask == -1) || ((lmask & 0x1) == 0) ||
                             (op!=TR::InstOpCode::rldic   &&
                              op!=TR::InstOpCode::rldimi  &&
                              op!=TR::InstOpCode::rldic_r &&
                              op!=TR::InstOpCode::rldimi_r),
                "Cannot handle wrap-around, check mask for correctness");
	 }
      encoding = ((bitnum&0x1f)<<6) | ((bitnum&0x20));

      }
   else // single word
      {
      // special case the 3-bit rounding mode fields
      if (op == TR::InstOpCode::drrnd || op == TR::InstOpCode::dqua)
         {
         encoding = (lmask << 9) & 0x600;
         }
      else
         {
         int32_t mask = lmask&0xffffffff;
         int32_t maskBegin;
         int32_t maskEnd;

         maskBegin = leadingZeroes(~mask & (2*mask));
         maskBegin = (maskBegin + (maskBegin != 32)) & 0x1f;
         maskEnd  = leadingZeroes(mask & ~(2*mask));
         encoding = 32*maskBegin + maskEnd << 1; // shift encrypted mask into position
         }
      }
   *instruction |= encoding;
   }
Example #2
0
const char *TR::DebugCounter::debugCounterBucketName(TR::Compilation *comp, int32_t value, const char *format, ...)
   {

   if (!comp->getOptions()->enableDebugCounters())
      {
      return NULL;
      }

   TR::StackMemoryRegion stackMemoryRegion(*comp->trMemory());
   char *bucketFormat = (char*)comp->trMemory()->allocateStackMemory(strlen(format) + 40); // appending "=%d..%d" where each %d could be 11 characters

   int32_t low  = value;
   int32_t high = value;

   if (value != 0 && comp->getOptions()->getDebugCounterBucketGranularity() >= 1)
      {
      const int32_t magnitude = abs(value);
      low = high = magnitude;
      const int32_t granularity = comp->getOptions()->getDebugCounterBucketGranularity();
      const double  bucketRatio = pow(2.0, 1.0 / granularity); // TODO: calculate once
      const int32_t logLow  = (int)(log((double)magnitude)/log(bucketRatio));

      // Figure out which bucket sizing algorithm to use
      //
      const int32_t log2magnitude = 31-leadingZeroes(magnitude); // floor
      const int32_t doublingInterval = 1 << log2magnitude;
      if (doublingInterval <= granularity)
         {
         // Tiny buckets degenerate to one value per bucket
         high = low;
         }
      else
         {
         // We do this with some buckets of size smallBucketSize, plus
         // some that are 1 larger.
         // We'd like to make sure make sure the smaller ones come
         // before bigger ones (eg. we want to see 8-9, 10-12, 13-15
         // rather than 8-10, 11-12, 13-15)
         //
         low = 1 << log2magnitude; // power-of-two starting point
         int32_t smallBucketSize      = doublingInterval / granularity;
         int32_t numBigBuckets        = doublingInterval - smallBucketSize * granularity;
         int32_t numSmallBuckets      = granularity - numBigBuckets;
         int32_t totalSmallBucketSize = numSmallBuckets * smallBucketSize;
         int32_t offset               = magnitude-low;
         if (offset < totalSmallBucketSize)
            {
            low += offset - offset % smallBucketSize;
            high = low + smallBucketSize - 1;
            }
         else
            {
            offset -= totalSmallBucketSize;
            low += totalSmallBucketSize + offset - offset % (smallBucketSize+1);
            high = low + smallBucketSize;
            }
         }

      TR_ASSERT(low <= magnitude && magnitude <= high, "Range (%d..%d) must contain %d\n", low, high, magnitude);

      if (value < 0)
         {
         low  = -low;
         high = -high;
         }
      }

   if (low == high)
      sprintf(bucketFormat, "%s=%d", format, low);
   else
      sprintf(bucketFormat, "%s=%d..%d", format, low, high);

   va_list args;
   va_start(args, format);
   const char *result = comp->getPersistentInfo()->getStaticCounters()->counterName(comp, bucketFormat, args);
   va_end(args);

   return result;
   }