improve constant loading. Still sucks, but oh well
authorAndrew Lenharth <andrewl@lenharth.org>
Fri, 30 Dec 2005 02:30:02 +0000 (02:30 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Fri, 30 Dec 2005 02:30:02 +0000 (02:30 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25047 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Alpha/AlphaISelDAGToDAG.cpp
lib/Target/Alpha/AlphaInstrInfo.td

index e51db4127de1ff9b8e2687ae7bc33d5bc4abc32f..dd29e912529bc67bf98c434986236b9d7396b8fb 100644 (file)
@@ -38,13 +38,14 @@ namespace {
   class AlphaDAGToDAGISel : public SelectionDAGISel {
     AlphaTargetLowering AlphaLowering;
 
-    static const int IMM_LOW  = -32768;
-    static const int IMM_HIGH = 32767;
-    static const int IMM_MULT = 65536;
+    static const int64_t IMM_LOW  = -32768;
+    static const int64_t IMM_HIGH = 32767;
+    static const int64_t IMM_MULT = 65536;
     
   public:
     AlphaDAGToDAGISel(TargetMachine &TM)
-      : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {}
+      : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) 
+    {}
 
     /// getI64Imm - Return a target constant with the specified value, of type
     /// i64.
@@ -240,17 +241,24 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
     return CurDAG->SelectNodeTo(N, Alpha::RETDAG, MVT::Other, Chain, InFlag);
   }
   case ISD::Constant: {
-    int64_t val = (int64_t)cast<ConstantSDNode>(N)->getValue();
-    if (val > (int64_t)IMM_HIGH +(int64_t)IMM_HIGH* (int64_t)IMM_MULT ||
-        val < (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT) {
-      MachineConstantPool *CP = BB->getParent()->getConstantPool();
-      ConstantUInt *C =
-        ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
-      SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
-      Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg());
-      return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, CPI, Tmp);
-    }
-    break;
+    uint64_t uval = cast<ConstantSDNode>(N)->getValue();
+    int64_t val = (int64_t)uval;
+    int32_t val32 = (int32_t)val;
+    if (val <= IMM_HIGH + IMM_HIGH * IMM_MULT &&
+       val >= IMM_LOW  + IMM_LOW  * IMM_MULT)
+      break; //(LDAH (LDA))
+    if ((uval >> 32) == 0 && //empty upper bits
+       val32 <= IMM_HIGH + IMM_HIGH * IMM_MULT &&
+       val32 >= IMM_LOW  + IMM_LOW  * IMM_MULT)
+      break; //(zext (LDAH (LDA)))
+    //Else use the constant pool
+    MachineConstantPool *CP = BB->getParent()->getConstantPool();
+    ConstantUInt *C =
+      ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , uval);
+    SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
+    Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg());
+    return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other, 
+                               CPI, Tmp, CurDAG->getEntryNode());
   }
   case ISD::ConstantFP:
     if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
index 13aab77c82359b069e92b7cc066f81a486b97c21..20a0350d3a90c8180a36ac6cbebc9eeaebcf8507 100644 (file)
@@ -57,6 +57,20 @@ def immSExt16  : PatLeaf<(imm), [{
   return (int64_t)N->getValue() == (int16_t)N->getValue();
 }]>;
 
+def SExtInt : SDNodeXForm<imm, [{
+  return getI64Imm(((int64_t)N->getValue() << 32) >> 32);
+}]>;
+
+def immSExt16int  : PatLeaf<(imm), [{
+  // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended
+  // field.  Used by instructions like 'lda'.
+  int64_t val = (int64_t)N->getValue();
+  uint32_t uval32 = (uint32_t)val;
+  int32_t val32 = (int32_t)val;
+  return (int64_t)uval32 == val && val32 == (int16_t)val32;
+}], SExtInt>;
+
+
 def iZAPX : SDNodeXForm<imm, [{
   // Transformation function: get the imm to ZAPi
   uint64_t UImm = (uint64_t)N->getValue();
@@ -778,12 +792,19 @@ def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
 //Constant handling
 
 def immConst2Part  : PatLeaf<(imm), [{
-  // immZAP predicate - True if the immediate fits is suitable for use in a
-  // ZAP instruction
+  //true if imm fits in a LDAH LDA pair
   int64_t val = (int64_t)N->getValue();
   return (val <= (int64_t)IMM_HIGH +(int64_t)IMM_HIGH* (int64_t)IMM_MULT &
                val >= (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT);
 }]>;
+def immConst2PartInt  : PatLeaf<(imm), [{
+  //true if imm fits in a LDAH LDA pair with zeroext
+  uint64_t uval = N->getValue();
+  int32_t val32 = (int32_t)uval;
+  return ((uval >> 32) == 0 && //empty upper bits
+          val32 <= IMM_HIGH + IMM_HIGH * IMM_MULT &&
+          val32 >= IMM_LOW  + IMM_LOW  * IMM_MULT);
+}], SExtInt>;
 
 //TODO: factor this out
 def LL16 : SDNodeXForm<imm, [{
@@ -808,6 +829,13 @@ def : Pat<(i64 immConst2Part:$imm),
 def : Pat<(i64 immSExt16:$imm),
           (LDA immSExt16:$imm, R31)>;
 
+def : Pat<(i64 immSExt16int:$imm),
+          (ZAPNOTi (LDA (SExtInt immSExt16int:$imm), R31), 15)>;
+def : Pat<(i64 immConst2PartInt:$imm),
+          (ZAPNOTi (LDA (LL16 (SExtInt immConst2PartInt:$imm)), 
+                        (LDAH (LH16 (SExtInt immConst2PartInt:$imm)), R31)), 15)>;
+
+
 //TODO: I want to just define these like this!
 //def : Pat<(i64 0),
 //          (R31)>;