[AArch64] Make function processLogicalImmediate more efficient. NFC.
authorAkira Hatanaka <ahatanaka@apple.com>
Mon, 3 Nov 2014 23:06:31 +0000 (23:06 +0000)
committerAkira Hatanaka <ahatanaka@apple.com>
Mon, 3 Nov 2014 23:06:31 +0000 (23:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221199 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h

index 832b2db5a7332bc49f09b0659edb04c8acb85b83..43f551724c772260d685b9e972050175a4dc03c8 100644 (file)
@@ -216,61 +216,56 @@ static inline bool processLogicalImmediate(uint64_t imm, unsigned regSize,
       (regSize != 64 && (imm >> regSize != 0 || imm == ~0U)))
     return false;
 
-  unsigned size = 2;
-  uint64_t eltVal = imm;
-
   // First, determine the element size.
-  while (size < regSize) {
-    unsigned numElts = regSize / size;
-    unsigned mask = (1ULL << size) - 1;
-    uint64_t lowestEltVal = imm & mask;
-
-    bool allMatched = true;
-    for (unsigned i = 1; i < numElts; ++i) {
-     uint64_t currEltVal = (imm >> (i*size)) & mask;
-      if (currEltVal != lowestEltVal) {
-        allMatched = false;
-        break;
-      }
-    }
+  unsigned size = regSize;
+
+  do {
+    size /= 2;
+    uint64_t mask = (1ULL << size) - 1;
 
-    if (allMatched) {
-      eltVal = lowestEltVal;
+    if ((imm & mask) != ((imm >> size) & mask)) {
+      size *= 2;
       break;
     }
-
-    size *= 2;
-  }
+  } while (size > 2);
 
   // Second, determine the rotation to make the element be: 0^m 1^n.
-  for (unsigned i = 0; i < size; ++i) {
-    eltVal = ror(eltVal, size);
-    uint32_t clz = countLeadingZeros(eltVal) - (64 - size);
-    uint32_t cto = CountTrailingOnes_64(eltVal);
-
-    if (clz + cto == size) {
-      // Encode in immr the number of RORs it would take to get *from* this
-      // element value to our target value, where i+1 is the number of RORs
-      // to go the opposite direction.
-      unsigned immr = size - (i + 1);
-
-      // If size has a 1 in the n'th bit, create a value that has zeroes in
-      // bits [0, n] and ones above that.
-      uint64_t nimms = ~(size-1) << 1;
-
-      // Or the CTO value into the low bits, which must be below the Nth bit
-      // bit mentioned above.
-      nimms |= (cto-1);
-
-      // Extract the seventh bit and toggle it to create the N field.
-      unsigned N = ((nimms >> 6) & 1) ^ 1;
-
-      encoding = (N << 12) | (immr << 6) | (nimms & 0x3f);
-      return true;
-    }
+  uint32_t cto, i;
+  uint64_t mask = ((uint64_t)-1LL) >> (64 - size);
+  imm &= mask;
+
+  if (isShiftedMask_64(imm)) {
+    i = countTrailingZeros(imm);
+    cto = CountTrailingOnes_64(imm >> i);
+  } else {
+    imm |= ~mask;
+    if (!isShiftedMask_64(~imm))
+      return false;
+
+    unsigned clo = CountLeadingOnes_64(imm);
+    i = 64 - clo;
+    cto = clo + CountTrailingOnes_64(imm) - (64 - size);
   }
 
-  return false;
+  // Encode in immr the number of RORs it would take to get *from* 0^m 1^n
+  // to our target value, where i is the number of RORs to go the opposite
+  // direction.
+  assert(size > i && "i should be smaller than element size");
+  unsigned immr = (size - i) & (size - 1);
+
+  // If size has a 1 in the n'th bit, create a value that has zeroes in
+  // bits [0, n] and ones above that.
+  uint64_t nimms = ~(size-1) << 1;
+
+  // Or the CTO value into the low bits, which must be below the Nth bit
+  // bit mentioned above.
+  nimms |= (cto-1);
+
+  // Extract the seventh bit and toggle it to create the N field.
+  unsigned N = ((nimms >> 6) & 1) ^ 1;
+
+  encoding = (N << 12) | (immr << 6) | (nimms & 0x3f);
+  return true;
 }
 
 /// isLogicalImmediate - Return true if the immediate is valid for a logical