Reduce number of instructions to load 64-bit constants.
authorJim Laskey <jlaskey@mac.com>
Tue, 12 Dec 2006 13:23:43 +0000 (13:23 +0000)
committerJim Laskey <jlaskey@mac.com>
Tue, 12 Dec 2006 13:23:43 +0000 (13:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32481 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelDAGToDAG.cpp
lib/Target/PowerPC/PPCInstr64Bit.td

index d45c255d660fef2788fa6614636491715aac9c34..08cceecb5b0f0e8aad4526ca69015ba36349d32b 100644 (file)
@@ -766,6 +766,81 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) {
 
   switch (N->getOpcode()) {
   default: break;
+  
+  case ISD::Constant: {
+    if (N->getValueType(0) == MVT::i64) {
+      // Get 64 bit value.
+      int64_t Imm = cast<ConstantSDNode>(N)->getValue();
+      // Assume no remaining bits.
+      unsigned Remainder = 0;
+      // Assume no shift required.
+      unsigned Shift = 0;
+      
+      // If it can't be represented as a 32 bit value.
+      if (!isInt32(Imm)) {
+        Shift = CountTrailingZeros_64(Imm);
+        int64_t ImmSh = static_cast<uint64_t>(Imm) >> Shift;
+        
+        // If the shifted value fits 32 bits.
+        if (isInt32(ImmSh)) {
+          // Go with the shifted value.
+          Imm = ImmSh;
+        } else {
+          // Still stuck with a 64 bit value.
+          Remainder = Imm;
+          Shift = 32;
+          Imm >>= 32;
+        }
+      }
+      
+      // Intermediate operand.
+      SDNode *Result;
+
+      // Handle first 32 bits.
+      unsigned Lo = Imm & 0xFFFF;
+      unsigned Hi = (Imm >> 16) & 0xFFFF;
+      
+      // Simple value.
+      if (isInt16(Imm)) {
+       // Just the Lo bits.
+        Result = CurDAG->getTargetNode(PPC::LI8, MVT::i64, getI32Imm(Lo));
+      } else if (Lo) {
+        // Handle the Hi bits.
+        unsigned OpC = Hi ? PPC::LIS8 : PPC::LI8;
+        Result = CurDAG->getTargetNode(OpC, MVT::i64, getI32Imm(Hi));
+        // And Lo bits.
+        Result = CurDAG->getTargetNode(PPC::ORI8, MVT::i64,
+                                       SDOperand(Result, 0), getI32Imm(Lo));
+      } else {
+       // Just the Hi bits.
+        Result = CurDAG->getTargetNode(PPC::LIS8, MVT::i64, getI32Imm(Hi));
+      }
+      
+      // If no shift, we're done.
+      if (!Shift) return Result;
+
+      // Shift for next step if the upper 32-bits were not zero.
+      if (Imm) {
+        Result = CurDAG->getTargetNode(PPC::RLDICR, MVT::i64,
+                                       SDOperand(Result, 0),
+                                       getI32Imm(Shift), getI32Imm(63 - Shift));
+      }
+
+      // Add in the last bits as required.
+      if ((Hi = (Remainder >> 16) & 0xFFFF)) {
+        Result = CurDAG->getTargetNode(PPC::ORIS8, MVT::i64,
+                                       SDOperand(Result, 0), getI32Imm(Hi));
+      } 
+      if ((Lo = Remainder & 0xFFFF)) {
+        Result = CurDAG->getTargetNode(PPC::ORI8, MVT::i64,
+                                       SDOperand(Result, 0), getI32Imm(Lo));
+      }
+      
+      return Result;
+    }
+    break;
+  }
+  
   case ISD::SETCC:
     return SelectSETCC(Op);
   case PPCISD::GlobalBaseReg:
index f47e92f3dcd464c5fdd780bf62d2909a0763552c..56d02cc146cfc5214d0f7aa7a8d8e5cf603c6e01 100644 (file)
@@ -474,48 +474,6 @@ def FCTIDZ : XForm_26<63, 815, (ops F8RC:$frD, F8RC:$frB),
 // Instruction Patterns
 //
 
-// Immediate support.
-// Handled above:
-//   sext(0x0000_0000_0000_FFFF,  i8) -> li imm
-//   sext(0x0000_0000_FFFF_0000, i16) -> lis imm>>16
-
-// sext(0x0000_0000_FFFF_FFFF,  i16)  -> lis + ori
-def sext_0x0000_0000_FFFF_FFFF_i16 : PatLeaf<(imm), [{
-  return N->getValue() == (uint64_t)(int32_t)N->getValue();
-}]>;
-def : Pat<(i64 sext_0x0000_0000_FFFF_FFFF_i16:$imm),
-          (ORI8 (LIS8 (HI16 imm:$imm)), (LO16 imm:$imm))>;
-
-// zext(0x0000_0000_FFFF_7FFF, i16) -> oris (li lo16(imm)), imm>>16
-def zext_0x0000_0000_FFFF_7FFF_i16 : PatLeaf<(imm), [{
-  return (N->getValue() & 0xFFFFFFFF00008000ULL) == 0;
-}]>;
-def : Pat<(i64 zext_0x0000_0000_FFFF_7FFF_i16:$imm),
-          (ORIS8 (LI8 (LO16 imm:$imm)), (HI16 imm:$imm))>;
-
-// zext(0x0000_0000_FFFF_FFFF, i16) -> oris (ori (li 0), lo16(imm)), imm>>16
-def zext_0x0000_0000_FFFF_FFFF_i16 : PatLeaf<(imm), [{
-  return (N->getValue() & 0xFFFFFFFF00000000ULL) == 0;
-}]>;
-def : Pat<(i64 zext_0x0000_0000_FFFF_FFFF_i16:$imm),
-          (ORIS8 (ORI8 (LI8 0), (LO16 imm:$imm)), (HI16 imm:$imm))>;
-
-// FIXME: Handle smart forms where the top 32-bits are set.  Right now, stuff
-// like 0xABCD0123BCDE0000 hits the case below, which produces ORI R, R, 0's! 
-
-// Fully general (and most expensive: 6 instructions!) immediate pattern.
-def : Pat<(i64 imm:$imm),
-          (ORI8 
-             (ORIS8 
-                (RLDICR
-                   (ORI8
-                      (LIS8 (HI48_64 imm:$imm)),
-                      (HI32_48 imm:$imm)),
-                   32, 31),
-                (HI16 imm:$imm)),
-             (LO16 imm:$imm))>;
-
-
 // Extensions and truncates to/from 32-bit regs.
 def : Pat<(i64 (zext GPRC:$in)),
           (RLDICL (OR4To8 GPRC:$in, GPRC:$in), 0, 32)>;