[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC32ISelSimple.cpp PPC64ISelPattern.cpp PowerPCAsmPrinter.cpp
Chris Lattner
lattner at cs.uiuc.edu
Tue Aug 2 12:25:17 PDT 2005
Changes in directory llvm/lib/Target/PowerPC:
PPC32ISelPattern.cpp updated: 1.110 -> 1.111
PPC32ISelSimple.cpp updated: 1.143 -> 1.144
PPC64ISelPattern.cpp updated: 1.26 -> 1.27
PowerPCAsmPrinter.cpp updated: 1.83 -> 1.84
---
Log message:
Update to use the new MathExtras.h support for log2 computation.
Patch contributed by Jim Laskey!
---
Diffs of the changes: (+78 -106)
PPC32ISelPattern.cpp | 46 ++++++++++++++++-----
PPC32ISelSimple.cpp | 105 +++++++++++++++-----------------------------------
PPC64ISelPattern.cpp | 31 ++++----------
PowerPCAsmPrinter.cpp | 2
4 files changed, 78 insertions(+), 106 deletions(-)
Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.110 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.111
--- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.110 Tue Aug 2 14:07:49 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Tue Aug 2 14:25:03 2005
@@ -35,6 +35,29 @@
#include <algorithm>
using namespace llvm;
+
+// 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) {
+ if (isShiftedMask_32(Val)) {
+ // look for the first non-zero bit
+ MB = CountLeadingZeros_32(Val);
+ // look for the first zero bit after the run of ones
+ ME = CountLeadingZeros_32((Val - 1) ^ Val);
+ return true;
+ } else if (isShiftedMask_32(Val = ~Val)) { // invert mask
+ // effectively look for the first zero bit
+ ME = CountLeadingZeros_32(Val) - 1;
+ // effectively look for the first one bit after the run of zeros
+ MB = CountLeadingZeros_32((Val - 1) ^ Val) + 1;
+ return true;
+ }
+ // no run present
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// PPC32TargetLowering - PPC32 Implementation of the TargetLowering interface
namespace {
@@ -321,6 +344,7 @@
// Just to be safe, we'll always reserve the full 24 bytes of linkage area
// plus 32 bytes of argument space in case any called code gets funky on us.
+ // (Required by ABI to support var arg)
if (NumBytes < 56) NumBytes = 56;
// Adjust the stack pointer for the new arguments...
@@ -664,36 +688,36 @@
switch(Opcode) {
default: return 0;
case ISD::ADD:
- if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
+ if (isInt16(v)) { Imm = v & 0xFFFF; return 1; }
if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
break;
case ISD::AND: {
unsigned MB, ME;
if (IsRunOfOnes(v, MB, ME)) { Imm = MB << 16 | ME & 0xFFFF; return 5; }
- if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; }
+ if (isUInt16(v)) { Imm = v & 0xFFFF; return 1; }
if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
break;
}
case ISD::XOR:
case ISD::OR:
- if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; }
+ if (isUInt16(v)) { Imm = v & 0xFFFF; return 1; }
if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
break;
case ISD::MUL:
- if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
+ if (isInt16(v)) { Imm = v & 0xFFFF; return 1; }
break;
case ISD::SUB:
// handle subtract-from separately from subtract, since subi is really addi
- if (U && v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
- if (!U && v <= 32768 && v >= -32767) { Imm = (-v) & 0xFFFF; return 1; }
+ if (U && isInt16(v)) { Imm = v & 0xFFFF; return 1; }
+ if (!U && isInt16(-v)) { Imm = (-v) & 0xFFFF; return 1; }
break;
case ISD::SETCC:
- if (U && (v >= 0 && v <= 65535)) { Imm = v & 0xFFFF; return 1; }
- if (!U && (v <= 32767 && v >= -32768)) { Imm = v & 0xFFFF; return 1; }
+ if (U && isUInt16(v)) { Imm = v & 0xFFFF; return 1; }
+ if (!U && isInt16(v)) { Imm = v & 0xFFFF; return 1; }
break;
case ISD::SDIV:
- if ((Imm = ExactLog2(v))) { return 3; }
- if ((Imm = ExactLog2(-v))) { Imm = -Imm; return 3; }
+ if (isPowerOf2_32(v)) { Imm = Log2_32(v); return 3; }
+ if (isPowerOf2_32(-v)) { Imm = Log2_32(-v); return 3; }
if (v <= -2 || v >= 2) { return 4; }
break;
case ISD::UDIV:
@@ -807,7 +831,7 @@
static struct ms magic(int d) {
int p;
unsigned int ad, anc, delta, q1, r1, q2, r2, t;
- const unsigned int two31 = 2147483648U; // 2^31
+ const unsigned int two31 = 0x80000000U;
struct ms mag;
ad = abs(d);
Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.143 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.144
--- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.143 Thu Jul 21 15:44:42 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Tue Aug 2 14:25:03 2005
@@ -26,11 +26,35 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include <vector>
using namespace llvm;
+
+// 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) {
+ if (isShiftedMask_32(Val)) {
+ // look for the first non-zero bit
+ MB = CountLeadingZeros_32(Val);
+ // look for the first zero bit after the run of ones
+ ME = CountLeadingZeros_32((Val - 1) ^ Val);
+ return true;
+ } else if (isShiftedMask_32(Val = ~Val)) { // invert mask
+ // effectively look for the first zero bit
+ ME = CountLeadingZeros_32(Val) - 1;
+ // effectively look for the first one bit after the run of zeros
+ MB = CountLeadingZeros_32((Val - 1) ^ Val) + 1;
+ return true;
+ }
+ // no run present
+ return false;
+}
+
namespace {
/// TypeClass - Used by the PowerPC backend to group LLVM types by their basic
/// PPC Representation.
@@ -2085,73 +2109,6 @@
BuildMI(*BB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r);
}
-// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It
-// returns zero when the input is not exactly a power of two.
-static unsigned ExactLog2(unsigned Val) {
- if (Val == 0 || (Val & (Val-1))) return 0;
- unsigned Count = 0;
- while (Val != 1) {
- Val >>= 1;
- ++Count;
- }
- 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;
-}
-
/// isInsertAndHalf - Helper function for emitBitfieldInsert. Returns true if
/// OpUser has one use, is used by an or instruction, and is itself an and whose
/// second operand is a constant int. Optionally, set OrI to the Or instruction
@@ -2281,7 +2238,7 @@
// succeeded in matching one of the cases for generating rlwimi. Update the
// skip lists and users of the Instruction::Or.
unsigned MB, ME;
- if (((TgtMask ^ InsMask) == 0xFFFFFFFF) && isRunOfOnes(InsMask, MB, ME)) {
+ if (((TgtMask ^ InsMask) == 0xFFFFFFFF) && IsRunOfOnes(InsMask, MB, ME)) {
SkipList.push_back(Op0User);
SkipList.push_back(Op1User);
SkipList.push_back(OptAndI);
@@ -2320,7 +2277,7 @@
if (matched == false)
return false;
- if (isRunOfOnes(Imm, MB, ME)) {
+ if (IsRunOfOnes(Imm, MB, ME)) {
unsigned SrcReg = getReg(Op, MBB, IP);
BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(SrcReg).addImm(Rotate)
.addImm(MB).addImm(ME);
@@ -2361,7 +2318,7 @@
if (Opcode == 2 && !Op1->isNullValue()) {
unsigned MB, ME, mask = Op1->getRawValue();
- if (isRunOfOnes(mask, MB, ME)) {
+ if (IsRunOfOnes(mask, MB, ME)) {
BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(Op0Reg).addImm(0)
.addImm(MB).addImm(ME);
return;
@@ -2582,7 +2539,9 @@
}
// If the element size is exactly a power of 2, use a shift to get it.
- if (unsigned Shift = ExactLog2(CI->getRawValue())) {
+ uint64_t C = CI->getRawValue();
+ if (isPowerOf2_64(C)) {
+ unsigned Shift = Log2_64(C);
ConstantUInt *ShiftCI = ConstantUInt::get(Type::UByteTy, Shift);
emitShiftOperation(MBB, IP, Op0, ShiftCI, true, Op0->getType(), 0, DestReg);
return;
@@ -2729,8 +2688,8 @@
return;
}
- unsigned log2V = ExactLog2(V);
- if (log2V != 0 && Ty->isSigned()) {
+ if (isPowerOf2_32(V) && Ty->isSigned()) {
+ unsigned log2V = Log2_32(V);
unsigned Op0Reg = getReg(Op0, MBB, IP);
unsigned TmpReg = makeAnotherReg(Op0->getType());
Index: llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.26 llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.27
--- llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp:1.26 Thu Jul 21 15:44:42 2005
+++ llvm/lib/Target/PowerPC/PPC64ISelPattern.cpp Tue Aug 2 14:25:03 2005
@@ -34,7 +34,7 @@
using namespace llvm;
//===----------------------------------------------------------------------===//
-// PPC32TargetLowering - PPC32 Implementation of the TargetLowering interface
+// PPC64TargetLowering - PPC64 Implementation of the TargetLowering interface
namespace {
class PPC64TargetLowering : public TargetLowering {
int VarArgsFrameIndex; // FrameIndex for start of varargs area.
@@ -258,6 +258,7 @@
// Just to be safe, we'll always reserve the full 48 bytes of linkage area
// plus 64 bytes of argument space in case any called code gets funky on us.
+ // (Required by ABI to support var arg)
if (NumBytes < 112) NumBytes = 112;
// Adjust the stack pointer for the new arguments...
@@ -397,7 +398,7 @@
Statistic<>NotLogic("ppc-codegen", "Number of inverted logical ops");
Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations");
//===--------------------------------------------------------------------===//
-/// ISel - PPC32 specific code to select PPC32 machine instructions for
+/// ISel - PPC64 specific code to select PPC64 machine instructions for
/// SelectionDAG operations.
//===--------------------------------------------------------------------===//
class ISel : public SelectionDAGISel {
@@ -447,18 +448,6 @@
void SelectBranchCC(SDOperand N);
};
-/// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It
-/// returns zero when the input is not exactly a power of two.
-static unsigned ExactLog2(unsigned Val) {
- if (Val == 0 || (Val & (Val-1))) return 0;
- unsigned Count = 0;
- while (Val != 1) {
- Val >>= 1;
- ++Count;
- }
- return Count;
-}
-
/// getImmediateForOpcode - This method returns a value indicating whether
/// the ConstantSDNode N can be used as an immediate to Opcode. The return
/// values are either 0, 1 or 2. 0 indicates that either N is not a
@@ -477,25 +466,25 @@
switch(Opcode) {
default: return 0;
case ISD::ADD:
- if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
+ if (isInt16(v)) { Imm = v & 0xFFFF; return 1; }
if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
break;
case ISD::AND:
case ISD::XOR:
case ISD::OR:
- if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; }
+ if (isUInt16(v)) { Imm = v & 0xFFFF; return 1; }
if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
break;
case ISD::MUL:
case ISD::SUB:
- if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
+ if (isInt16(v)) { Imm = v & 0xFFFF; return 1; }
break;
case ISD::SETCC:
- if (U && (v >= 0 && v <= 65535)) { Imm = v & 0xFFFF; return 1; }
- if (!U && (v <= 32767 && v >= -32768)) { Imm = v & 0xFFFF; return 1; }
+ if (U && isUInt16(v)) { Imm = v & 0xFFFF; return 1; }
+ if (!U && isInt16(v)) { Imm = v & 0xFFFF; return 1; }
break;
case ISD::SDIV:
- if ((Imm = ExactLog2(v))) { return 3; }
+ if (isPowerOf2_32(v)) { Imm = Log2_32(v); return 3; }
break;
}
return 0;
@@ -1636,7 +1625,7 @@
}
-/// createPPC32PatternInstructionSelector - This pass converts an LLVM function
+/// createPPC64PatternInstructionSelector - This pass converts an LLVM function
/// into a machine code representation using pattern matching and a machine
/// description file.
///
Index: llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp
diff -u llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.83 llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.84
--- llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp:1.83 Tue Jul 26 14:03:27 2005
+++ llvm/lib/Target/PowerPC/PowerPCAsmPrinter.cpp Tue Aug 2 14:25:03 2005
@@ -698,7 +698,7 @@
O << "\t.lcomm " << Name << ",16,_global.bss_c";
} else {
O << "\t.comm " << Name << "," << TD.getTypeSize(I->getType())
- << "," << log2((unsigned)TD.getTypeAlignment(I->getType()));
+ << "," << Log2_32((unsigned)TD.getTypeAlignment(I->getType()));
}
O << "\t\t# ";
WriteAsOperand(O, I, true, true, &M);
More information about the llvm-commits
mailing list