[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp

Nate Begeman natebegeman at mac.com
Thu Oct 7 19:49:35 PDT 2004



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelSimple.cpp updated: 1.89 -> 1.90
---
Log message:

Implement logical and with an immediate that consists of a contiguous block
of one or more 1 bits (may wrap from least significant bit to most
significant bit) as the rlwinm rather than andi., andis., or some longer
instructons sequence.

int andn4(int z) { return z & -4; }
int clearhi(int z) { return z & 0x0000FFFF; }
int clearlo(int z) { return z & 0xFFFF0000; }
int clearmid(int z) { return z & 0x00FFFF00; }
int clearwrap(int z) { return z & 0xFF0000FF; }

_andn4:
        rlwinm r3, r3, 0, 0, 29
        blr

_clearhi:
        rlwinm r3, r3, 0, 16, 31
        blr

_clearlo:
        rlwinm r3, r3, 0, 0, 15
        blr

_clearmid:
        rlwinm r3, r3, 0, 8, 23
        blr

_clearwrap:
        rlwinm r3, r3, 0, 24, 7
        blr


---
Diffs of the changes:  (+69 -5)

Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.89 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.90
--- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.89	Thu Oct  7 17:30:03 2004
+++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp	Thu Oct  7 21:49:24 2004
@@ -32,7 +32,7 @@
 using namespace llvm;
 
 namespace {
-  Statistic<> ShiftedImm("ppc-codegen", "Number of shifted immediates used");
+  Statistic<> NumClear("ppc-codegen", "Number of AND turned into mask");
 
   /// TypeClass - Used by the PowerPC backend to group LLVM types by their basic
   /// PPC Representation.
@@ -499,11 +499,10 @@
 
   // For shifted immediates, any value with the low halfword cleared may be used
   if (Shifted) {
-    if (((int32_t)CI->getRawValue() & 0x0000FFFF) == 0) {
-      ++ShiftedImm;
+    if (((int32_t)CI->getRawValue() & 0x0000FFFF) == 0)
       return true;
-    }
-    return false;
+    else
+      return false;
   }
       
   // ADDI, Compare, and non-indexed Load take SIMM
@@ -2038,6 +2037,61 @@
   return Count;
 }
 
+// isRunOfOnes - returns true if Val consists of one contiguous run of 1's with
+// any number of 0's on either side.  the 1's are allowed to wrap from LSB to
+// MSB.  so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs.  0x0F0F0000 is
+// not, since all 1's are not contiguous.
+static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
+  bool isRun = true;
+  MB = 0; 
+  ME = 0;
+
+  // look for first set bit
+  int i = 0;
+  for (; i < 32; i++) {
+    if ((Val & (1 << (31 - i))) != 0) {
+      MB = i;
+      ME = i;
+      break;
+    }
+  }
+  
+  // look for last set bit
+  for (; i < 32; i++) {
+    if ((Val & (1 << (31 - i))) == 0)
+      break;
+    ME = i;
+  }
+
+  // look for next set bit
+  for (; i < 32; i++) {
+    if ((Val & (1 << (31 - i))) != 0)
+      break;
+  }
+  
+  // if we exhausted all the bits, we found a match at this point for 0*1*0*
+  if (i == 32)
+    return true;
+
+  // since we just encountered more 1's, if it doesn't wrap around to the
+  // most significant bit of the word, then we did not find a match to 1*0*1* so
+  // exit.
+  if (MB != 0)
+    return false;
+
+  // look for last set bit
+  for (MB = i; i < 32; i++) {
+    if ((Val & (1 << (31 - i))) == 0)
+      break;
+  }
+  
+  // if we exhausted all the bits, then we found a match for 1*0*1*, otherwise,
+  // the value is not a run of ones.
+  if (i == 32)
+    return true;
+  return false;
+}
+
 /// emitBinaryConstOperation - Implement simple binary operators for integral
 /// types with a constant operand.  Opcode is one of: 0 for Add, 1 for Sub, 
 /// 2 for And, 3 for Or, 4 for Xor, and 5 for Subtract-From.
@@ -2070,6 +2124,16 @@
       return;
     }
   }
+  
+  if (Opcode == 2) {
+    unsigned MB, ME, mask = CI->getRawValue();
+    if (isRunOfOnes(mask, MB, ME)) {
+      ++NumClear;
+      BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(Op0Reg).addImm(0)
+        .addImm(MB).addImm(ME);
+      return;
+    }
+  }
 
   // For Add, Sub, and SubF the instruction takes a signed immediate.  For And,
   // Or, and Xor, the instruction takes an unsigned immediate.  There is no 






More information about the llvm-commits mailing list