[llvm] r221199 - [AArch64] Make function processLogicalImmediate more efficient. NFC.
Akira Hatanaka
ahatanaka at apple.com
Mon Nov 3 15:06:31 PST 2014
Author: ahatanak
Date: Mon Nov 3 17:06:31 2014
New Revision: 221199
URL: http://llvm.org/viewvc/llvm-project?rev=221199&view=rev
Log:
[AArch64] Make function processLogicalImmediate more efficient. NFC.
Modified:
llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h?rev=221199&r1=221198&r2=221199&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h Mon Nov 3 17:06:31 2014
@@ -216,61 +216,56 @@ static inline bool processLogicalImmedia
(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;
- if (allMatched) {
- eltVal = lowestEltVal;
+ do {
+ size /= 2;
+ uint64_t mask = (1ULL << size) - 1;
+
+ 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);
+ 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);
+ }
- // Extract the seventh bit and toggle it to create the N field.
- unsigned N = ((nimms >> 6) & 1) ^ 1;
+ // 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);
- encoding = (N << 12) | (immr << 6) | (nimms & 0x3f);
- return true;
- }
- }
+ // Extract the seventh bit and toggle it to create the N field.
+ unsigned N = ((nimms >> 6) & 1) ^ 1;
- return false;
+ encoding = (N << 12) | (immr << 6) | (nimms & 0x3f);
+ return true;
}
/// isLogicalImmediate - Return true if the immediate is valid for a logical
More information about the llvm-commits
mailing list