CellSPU:
authorScott Michel <scottm@aero.org>
Tue, 6 Jan 2009 23:10:38 +0000 (23:10 +0000)
committerScott Michel <scottm@aero.org>
Tue, 6 Jan 2009 23:10:38 +0000 (23:10 +0000)
- Add preliminary support for v2i32; load/store generates the right code but
  there's a lot work to be done to make this vector type operational.

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

lib/Target/CellSPU/SPUCallingConv.td
lib/Target/CellSPU/SPUISelLowering.cpp
lib/Target/CellSPU/SPUISelLowering.h
lib/Target/CellSPU/SPUInstrInfo.td
lib/Target/CellSPU/SPUNodes.td
lib/Target/CellSPU/SPURegisterInfo.td
lib/Target/CellSPU/SPUSubtarget.h

index 5213e424523361a78527d80396088ee17d10e044..10dc837d90b766a4ddbe5b593cb4983c5aa63ca5 100644 (file)
@@ -21,13 +21,14 @@ class CCIfSubtarget<string F, CCAction A>
 
 // Return-value convention for Cell SPU: Everything can be passed back via $3:
 def RetCC_SPU : CallingConv<[
-  CCIfType<[i8],   CCAssignToReg<[R3]>>,
-  CCIfType<[i16],  CCAssignToReg<[R3]>>,
-  CCIfType<[i32],  CCAssignToReg<[R3]>>,
-  CCIfType<[i64],  CCAssignToReg<[R3]>>,
-  CCIfType<[i128], CCAssignToReg<[R3]>>,
+  CCIfType<[i8],       CCAssignToReg<[R3]>>,
+  CCIfType<[i16],      CCAssignToReg<[R3]>>,
+  CCIfType<[i32],      CCAssignToReg<[R3]>>,
+  CCIfType<[i64],      CCAssignToReg<[R3]>>,
+  CCIfType<[i128],     CCAssignToReg<[R3]>>,
   CCIfType<[f32, f64], CCAssignToReg<[R3]>>,
-  CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToReg<[R3]>>
+  CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToReg<[R3]>>,
+  CCIfType<[v2i32],                                    CCAssignToReg<[R3]>>
 ]>;
 
 
index 7e63a87288349d4c214296de2fe21477a34b31e3..9dd98558509b618b82f388aeb7d878028e6e2fd5 100644 (file)
@@ -327,6 +327,9 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
   addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
   addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
 
+  // "Odd size" vector classes that we're willing to support:
+  addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
+
   for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
        i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
     MVT VT = (MVT::SimpleValueType)i;
@@ -417,7 +420,6 @@ SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
     node_names[(unsigned) SPUISD::CARRY_GENERATE] = "SPUISD::CARRY_GENERATE";
     node_names[(unsigned) SPUISD::SUB_EXTENDED] = "SPUISD::SUB_EXTENDED";
     node_names[(unsigned) SPUISD::BORROW_GENERATE] = "SPUISD::BORROW_GENERATE";
-    node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
   }
 
   std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
@@ -1029,8 +1031,7 @@ static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
   return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
 }
 
-static
-SDValue
+static SDValue
 LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
   CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
   SDValue Chain = TheCall->getChain();
@@ -1618,6 +1619,11 @@ static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
     SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
     return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
   }
+  case MVT::v2i32: {
+    unsigned int Value = SplatBits;
+    SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
+    return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T);
+  }
   case MVT::v2i64: {
     uint64_t val = SplatBits;
     uint32_t upper = uint32_t(val >> 32);
@@ -2454,32 +2460,6 @@ static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
   return SDValue();
 }
 
-//! Lower ISD::SETCC
-/*!
- Lower i64 condition code handling.
- */
-
-static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) {
-  MVT VT = Op.getValueType();
-  SDValue lhs = Op.getOperand(0);
-  SDValue rhs = Op.getOperand(1);
-  SDValue condition = Op.getOperand(2);
-
-  if (VT == MVT::i32 && lhs.getValueType() == MVT::i64) {
-    // Expand the i64 comparisons to what Cell can actually support,
-    // which is eq, ugt and sgt:
-#if 0
-    CondCodeSDNode *ccvalue = dyn_cast<CondCodeSDValue>(condition);
-
-    switch (ccvalue->get()) {
-      case
-    }
-#endif
-  }
-
-  return SDValue();
-}
-
 //! Lower ISD::SELECT_CC
 /*!
   ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
@@ -2647,9 +2627,6 @@ SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
 
   case ISD::TRUNCATE:
     return LowerTRUNCATE(Op, DAG);
-
-  case ISD::SETCC:
-    return LowerSETCC(Op, DAG);
   }
 
   return SDValue();
@@ -2971,7 +2948,6 @@ SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
   case SPUISD::ROTBYTES_LEFT:
   case SPUISD::SELECT_MASK:
   case SPUISD::SELB:
-  case SPUISD::SEXT32TO64:
 #endif
   }
 }
index feee6fd55c1c9821b519c241239dcc547ad60245..24b8f82ecbe9b192d5f4382be9ef8a58e526e031 100644 (file)
@@ -52,12 +52,10 @@ namespace llvm {
       ROTBYTES_LEFT_BITS,       ///< Rotate bytes left by bit shift count
       SELECT_MASK,              ///< Select Mask (FSM, FSMB, FSMH, FSMBI)
       SELB,                     ///< Select bits -> (b & mask) | (a & ~mask)
-      GATHER_BITS,              ///< Gather bits from bytes/words/halfwords
       ADD_EXTENDED,             ///< Add extended, with carry
       CARRY_GENERATE,           ///< Carry generate for ADD_EXTENDED
       SUB_EXTENDED,             ///< Subtract extended, with borrow
       BORROW_GENERATE,          ///< Borrow generate for SUB_EXTENDED
-      SEXT32TO64,               ///< Sign-extended 32-bit const -> 64-bits
       LAST_SPUISD               ///< Last user-defined instruction
     };
   }
index 6a0fde398b8a8c0d058ff5caad06b88f1a1021d0..b9956402d95ad6fb8ceeea0678a73a848cb31018 100644 (file)
@@ -71,6 +71,8 @@ let canFoldAsLoad = 1 in {
     def v4f32: LoadDFormVec<v4f32>;
     def v2f64: LoadDFormVec<v2f64>;
 
+    def v2i32: LoadDFormVec<v2i32>;
+
     def r128:  LoadDForm<GPRC>;
     def r64:   LoadDForm<R64C>;
     def r32:   LoadDForm<R32C>;
@@ -103,6 +105,8 @@ let canFoldAsLoad = 1 in {
     def v4f32: LoadAFormVec<v4f32>;
     def v2f64: LoadAFormVec<v2f64>;
 
+    def v2i32: LoadAFormVec<v2i32>;
+
     def r128:  LoadAForm<GPRC>;
     def r64:   LoadAForm<R64C>;
     def r32:   LoadAForm<R32C>;
@@ -135,6 +139,8 @@ let canFoldAsLoad = 1 in {
     def v4f32: LoadXFormVec<v4f32>;
     def v2f64: LoadXFormVec<v2f64>;
 
+    def v2i32: LoadXFormVec<v2i32>;
+
     def r128:  LoadXForm<GPRC>;
     def r64:   LoadXForm<R64C>;
     def r32:   LoadXForm<R32C>;
@@ -183,6 +189,8 @@ multiclass StoreDForms
   def v4f32: StoreDFormVec<v4f32>;
   def v2f64: StoreDFormVec<v2f64>;
 
+  def v2i32: StoreDFormVec<v2i32>;
+
   def r128:  StoreDForm<GPRC>;
   def r64:   StoreDForm<R64C>;
   def r32:   StoreDForm<R32C>;
@@ -213,6 +221,8 @@ multiclass StoreAForms
   def v4f32: StoreAFormVec<v4f32>;
   def v2f64: StoreAFormVec<v2f64>;
 
+  def v2i32: StoreAFormVec<v2i32>;
+
   def r128:  StoreAForm<GPRC>;
   def r64:   StoreAForm<R64C>;
   def r32:   StoreAForm<R32C>;
@@ -245,6 +255,8 @@ multiclass StoreXForms
   def v4f32: StoreXFormVec<v4f32>;
   def v2f64: StoreXFormVec<v2f64>;
 
+  def v2i32: StoreXFormVec<v2i32>;
+
   def r128:  StoreXForm<GPRC>;
   def r64:   StoreXForm<R64C>;
   def r32:   StoreXForm<R32C>;
@@ -1044,11 +1056,11 @@ class GBBInst<dag OOL, dag IOL, list<dag> pattern>:
 
 class GBBRegInst<RegisterClass rclass, ValueType vectype>:
   GBBInst<(outs rclass:$rT), (ins VECREG:$rA),
-          [(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
+          [/* no pattern */]>;
 
 class GBBVecInst<ValueType vectype>:
   GBBInst<(outs VECREG:$rT), (ins VECREG:$rA),
-          [(set (vectype VECREG:$rT), (SPUgatherbits (vectype VECREG:$rA)))]>;
+          [/* no pattern */]>;
 
 multiclass GatherBitsFromBytes {
   def v16i8_r32: GBBRegInst<R32C, v16i8>;
@@ -1070,12 +1082,11 @@ class GBHInst<dag OOL, dag IOL, list<dag> pattern>:
 
 class GBHRegInst<RegisterClass rclass, ValueType vectype>:
     GBHInst<(outs rclass:$rT), (ins VECREG:$rA),
-            [(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
+            [/* no pattern */]>;
 
 class GBHVecInst<ValueType vectype>:
     GBHInst<(outs VECREG:$rT), (ins VECREG:$rA),
-            [(set (vectype VECREG:$rT),
-                  (SPUgatherbits (vectype VECREG:$rA)))]>;
+            [/* no pattern */]>;
 
 multiclass GatherBitsHalfword {
   def v8i16_r32: GBHRegInst<R32C, v8i16>;
@@ -1097,12 +1108,11 @@ class GBInst<dag OOL, dag IOL, list<dag> pattern>:
 
 class GBRegInst<RegisterClass rclass, ValueType vectype>:
     GBInst<(outs rclass:$rT), (ins VECREG:$rA),
-           [(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
+           [/* no pattern */]>;
 
 class GBVecInst<ValueType vectype>:
     GBInst<(outs VECREG:$rT), (ins VECREG:$rA),
-           [(set (vectype VECREG:$rT),
-                 (SPUgatherbits (vectype VECREG:$rA)))]>;
+           [/* no pattern */]>;
 
 multiclass GatherBitsWord {
   def v4i32_r32: GBRegInst<R32C, v4i32>;
index 0725d72e0f38992fd37a156f347bbddec4aefc82..cae6023cd45046931f9a8a27b1196d5b8e36da27 100644 (file)
@@ -61,13 +61,6 @@ def SPUselb_type: SDTypeProfile<1, 3, [
 def SPUvecshift_type: SDTypeProfile<1, 2, [
   SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
 
-// SPU gather bits:
-// This instruction looks at each vector (word|halfword|byte) slot's low bit
-// and forms a mask in the low order bits of the first word's preferred slot.
-def SPUgatherbits_type: SDTypeProfile<1, 1, [
-  /* no type constraints defined */
-]>;
-
 //===----------------------------------------------------------------------===//
 // Synthetic/pseudo-instructions
 //===----------------------------------------------------------------------===//
@@ -115,9 +108,6 @@ def SPUselmask: SDNode<"SPUISD::SELECT_MASK", SPUselmask_type, []>;
 // SPU select bits instruction
 def SPUselb: SDNode<"SPUISD::SELB", SPUselb_type, []>;
 
-// SPU gather bits instruction:
-def SPUgatherbits: SDNode<"SPUISD::GATHER_BITS", SPUgatherbits_type, []>;
-
 def SDTprefslot2vec: SDTypeProfile<1, 1, []>;
 def SPUprefslot2vec: SDNode<"SPUISD::PREFSLOT2VEC", SDTprefslot2vec, []>;
 
index 8ce6bc84e7aa63afaa1c26f6b18f1a316cbd2718..bb88f2bf9a2986b1a7168778d4db585bd76e12fb 100644 (file)
@@ -393,7 +393,9 @@ def R8C : RegisterClass<"SPU", [i8], 128,
 }
 
 // The SPU's registers as vector registers:
-def VECREG : RegisterClass<"SPU", [v16i8,v8i16,v4i32,v4f32,v2i64,v2f64], 128,
+def VECREG : RegisterClass<"SPU",
+                           [v16i8,v8i16,v2i32,v4i32,v4f32,v2i64,v2f64],
+                           128,
  [
    /* volatile register */
    R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, 
index 51dd44c5f9da1b7e262c9789187679a31500a2f3..695ec94fee2a401b28a8dbaad7d843c235c4d587 100644 (file)
@@ -85,7 +85,7 @@ namespace llvm {
     /// properties of this subtarget.
     const char *getTargetDataString() const {
       return "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128"
-             "-i16:16:128-i8:8:128-i1:8:128-a:0:128-v128:128:128"
+             "-i16:16:128-i8:8:128-i1:8:128-a:0:128-v64:128:128-v128:128:128"
              "-s:128:128";
     }
   };