Make a new reg class for 64 bit regs that aliases the 32 bit regs. This
authorNate Begeman <natebegeman@mac.com>
Wed, 19 Oct 2005 00:05:37 +0000 (00:05 +0000)
committerNate Begeman <natebegeman@mac.com>
Wed, 19 Oct 2005 00:05:37 +0000 (00:05 +0000)
will have to tide us over until we get real subreg support, but it prevents
the PrologEpilogInserter from spilling 8 byte GPRs on a G4 processor.

Add some initial support for TRUNCATE and ANY_EXTEND, but they don't
currently work due to issues with ScheduleDAG.  Something wll have to be
figured out.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23803 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelDAGToDAG.cpp
lib/Target/PowerPC/PPCInstrInfo.td
lib/Target/PowerPC/PPCRegisterInfo.td

index 754809303112fc6be9f22accbd8a7424c884b826..39f380acfae0d4f89a6c0270376dbf21e13cf4d1 100644 (file)
@@ -219,6 +219,11 @@ static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
 // and mask opcode and mask operation.
 static bool isRotateAndMask(SDNode *N, unsigned Mask, bool IsShiftMask,
                             unsigned &SH, unsigned &MB, unsigned &ME) {
+  // Don't even go down this path for i64, since different logic will be
+  // necessary for rldicl/rldicr/rldimi.
+  if (N->getValueType(0) != MVT::i32)
+    return false;
+
   unsigned Shift  = 32;
   unsigned Indeterminant = ~0;  // bit mask marking indeterminant results
   unsigned Opcode = N->getOpcode();
@@ -1206,14 +1211,27 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
       
     // Other cases are autogenerated.
     break;
+  case ISD::TRUNCATE: {
+    assert(N->getValueType(0) == MVT::i32 && 
+           N->getOperand(0).getValueType() == MVT::i64 &&
+           "TRUNCATE only supported for i64 -> i32");
+    // FIXME: this code breaks ScheduleDAG since Op0 is an i64 and OR4
+    // takes i32s.
+    SDOperand Op0 = Select(N->getOperand(0));
+    CurDAG->SelectNodeTo(N, PPC::OR4, MVT::i32, Op0, Op0);
+    break;
+  }
   case ISD::ANY_EXTEND:
     switch(N->getValueType(0)) {
     default: assert(0 && "Unhandled type in ANY_EXTEND");
-    case MVT::i64:
-      CurDAG->SelectNodeTo(N, PPC::OR8, MVT::i64, Select(N->getOperand(0)), 
-                           Select(N->getOperand(0)));
+    case MVT::i64: {
+      // FIXME: this code breaks ScheduleDAG since Op0 is an i32 and OR8
+      // takes i64s.
+      SDOperand Op0 = Select(N->getOperand(0));
+      CurDAG->SelectNodeTo(N, PPC::OR8, MVT::i64, Op0, Op0);
       break;
     }
+    }
     return SDOperand(N, 0);
   case ISD::ZERO_EXTEND:
     assert(N->getValueType(0) == MVT::i64 && 
index ad4444bc02ccd25f951b31e8620f6dcfae042ab8..7cd35344ede101057666c095a203d972f2ac168f 100644 (file)
@@ -703,7 +703,6 @@ def : Pat<(xor GPRC:$in, imm:$imm),
           (XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>;
 
 
-
 // Same as above, but using a temporary. FIXME: implement temporaries :)
 /*
 def : Pattern<(xor GPRC:$in, imm:$imm),
index 5cecf50f56037d795b0a63188c44be945fc91a96..bbc6a4c0bcff3fff4c2212a749357dc405176ead 100644 (file)
@@ -21,6 +21,12 @@ class GPR<bits<5> num, string n> : PPCReg<n> {
   field bits<5> Num = num;
 }
 
+// GP8 - One of the 32 64-bit general-purpose registers
+class GP8<bits<5> num, string n, Register Alias> : PPCReg<n> {
+  field bits<5> Num = num;
+  let Aliases = [Alias];
+}   
+
 // SPR - One of the 32-bit special-purpose registers
 class SPR<bits<5> num, string n> : PPCReg<n> {
   field bits<5> Num = num;
@@ -54,6 +60,24 @@ def R26 : GPR<26, "r26">;  def R27 : GPR<27, "r27">;
 def R28 : GPR<28, "r28">;  def R29 : GPR<29, "r29">;
 def R30 : GPR<30, "r30">;  def R31 : GPR<31, "r31">;
 
+// 64-bit General-purpose registers
+def X0  : GP8< 0,  "r0",  R0>;  def X1  : GP8< 1,  "r1",  R1>;
+def X2  : GP8< 2,  "r2",  R2>;  def X3  : GP8< 3,  "r3",  R3>;
+def X4  : GP8< 4,  "r4",  R4>;  def X5  : GP8< 5,  "r5",  R5>;
+def X6  : GP8< 6,  "r6",  R6>;  def X7  : GP8< 7,  "r7",  R7>;
+def X8  : GP8< 8,  "r8",  R8>;  def X9  : GP8< 9,  "r9",  R9>;
+def X10 : GP8<10, "r10", R10>;  def X11 : GP8<11, "r11", R11>;
+def X12 : GP8<12, "r12", R12>;  def X13 : GP8<13, "r13", R13>;
+def X14 : GP8<14, "r14", R14>;  def X15 : GP8<15, "r15", R15>;
+def X16 : GP8<16, "r16", R16>;  def X17 : GP8<17, "r17", R17>;
+def X18 : GP8<18, "r18", R18>;  def X19 : GP8<19, "r19", R19>;
+def X20 : GP8<20, "r20", R20>;  def X21 : GP8<21, "r21", R21>;
+def X22 : GP8<22, "r22", R22>;  def X23 : GP8<23, "r23", R23>;
+def X24 : GP8<24, "r24", R24>;  def X25 : GP8<25, "r25", R25>;
+def X26 : GP8<26, "r26", R26>;  def X27 : GP8<27, "r27", R27>;
+def X28 : GP8<28, "r28", R28>;  def X29 : GP8<29, "r29", R29>;
+def X30 : GP8<30, "r30", R30>;  def X31 : GP8<31, "r31", R31>;
+
 // Floating-point registers
 def F0  : FPR< 0,  "f0">;  def F1  : FPR< 1,  "f1">;
 def F2  : FPR< 2,  "f2">;  def F3  : FPR< 3,  "f3">;
@@ -111,9 +135,9 @@ def GPRC : RegisterClass<"PPC", i32, 32,
   }];
 }
 def G8RC : RegisterClass<"PPC", i64, 64,
-     [R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12,
-      R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17,
-      R16, R15, R14, R13, R31, R0, R1, LR]>
+     [X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12,
+      X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17,
+      X16, X15, X14, X13, X31, X0, X1]>
 {
   let MethodProtos = [{
     iterator allocation_order_begin(MachineFunction &MF) const;
@@ -127,9 +151,9 @@ def G8RC : RegisterClass<"PPC", i64, 64,
     G8RCClass::iterator
     G8RCClass::allocation_order_end(MachineFunction &MF) const {
       if (hasFP(MF))
-        return end()-4;
-      else
         return end()-3;
+      else
+        return end()-2;
     }
   }];
 }