[llvm-commits] [llvm] r45851 - in /llvm/trunk: include/llvm/ include/llvm/CodeGen/ lib/Target/CellSPU/ test/CodeGen/CellSPU/

Scott Michel scottm at aero.org
Thu Jan 10 18:53:16 PST 2008


Author: pingbak
Date: Thu Jan 10 20:53:15 2008
New Revision: 45851

URL: http://llvm.org/viewvc/llvm-project?rev=45851&view=rev
Log:
More CellSPU refinement and progress:

- Cleaned up custom load/store logic, common code is now shared [see note
  below], cleaned up address modes

- More test cases: various intrinsics, structure element access (load/store
  test), updated target data strings, indirect function calls.

Note: This patch contains a refactoring of the LoadSDNode and StoreSDNode
structures: they now share a common base class, LSBaseSDNode, that
provides an interface to their common functionality. There is some hackery
to access the proper operand depending on the derived class; otherwise,
to do a proper job would require finding and rearranging the SDOperands
sent to StoreSDNode's constructor. The current refactor errs on the
side of being conservatively and backwardly compatible while providing
functionality that reduces redundant code for targets where loads and
stores are custom-lowered.

Added:
    llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll
    llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll
    llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll
    llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll
    llvm/trunk/test/CodeGen/CellSPU/struct_1.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
    llvm/trunk/include/llvm/IntrinsicsCellSPU.td
    llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td
    llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
    llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp
    llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h
    llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td
    llvm/trunk/lib/Target/CellSPU/SPUNodes.td
    llvm/trunk/lib/Target/CellSPU/SPUOperands.td
    llvm/trunk/test/CodeGen/CellSPU/and_ops.ll
    llvm/trunk/test/CodeGen/CellSPU/ctpop.ll
    llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll
    llvm/trunk/test/CodeGen/CellSPU/eqv.ll
    llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll
    llvm/trunk/test/CodeGen/CellSPU/fcmp.ll
    llvm/trunk/test/CodeGen/CellSPU/fdiv.ll
    llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll
    llvm/trunk/test/CodeGen/CellSPU/immed16.ll
    llvm/trunk/test/CodeGen/CellSPU/immed32.ll
    llvm/trunk/test/CodeGen/CellSPU/immed64.ll
    llvm/trunk/test/CodeGen/CellSPU/int2fp.ll
    llvm/trunk/test/CodeGen/CellSPU/nand.ll
    llvm/trunk/test/CodeGen/CellSPU/or_ops.ll
    llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll
    llvm/trunk/test/CodeGen/CellSPU/select_bits.ll
    llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll
    llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Jan 10 20:53:15 2008
@@ -1454,11 +1454,63 @@
   }
 };
 
+/// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode
+///
+class LSBaseSDNode : public SDNode {
+private:
+  //! SrcValue - Memory location for alias analysis.
+  const Value *SrcValue;
+
+  //! SVOffset - Memory location offset.
+  int SVOffset;
+
+  //! Alignment - Alignment of memory location in bytes.
+  unsigned Alignment;
+
+  //! IsVolatile - True if the store is volatile.
+  bool IsVolatile;
+protected:
+  //! Operand array for load and store
+  /*!
+    \note Moving this array to the base class captures more
+    common functionality shared between LoadSDNode and
+    StoreSDNode
+   */
+  SDOperand Ops[4];
+public:
+  LSBaseSDNode(ISD::NodeType NodeTy, SDVTList VTs, const Value *SV, int SVO,
+               unsigned Align, bool Vol)
+    : SDNode(NodeTy, VTs),
+      SrcValue(SV), SVOffset(SVO), Alignment(Align), IsVolatile(Vol)
+  { }
+
+  const SDOperand getChain() const {
+    return getOperand(0);
+  }
+  const SDOperand getBasePtr() const {
+    return getOperand(getOpcode() == ISD::LOAD ? 1 : 2);
+  }
+  const SDOperand getOffset() const {
+    return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
+  }
+  const SDOperand getValue() const {
+    assert(getOpcode() == ISD::STORE);
+    return getOperand(1);
+  }
+
+  const Value *getSrcValue() const { return SrcValue; }
+  int getSrcValueOffset() const { return SVOffset; }
+  unsigned getAlignment() const { return Alignment; }
+  bool isVolatile() const { return IsVolatile; }
+
+  static bool classof(const LSBaseSDNode *N) { return true; }
+  static bool classof(const SDNode *N) { return true; }
+};
+
 /// LoadSDNode - This class is used to represent ISD::LOAD nodes.
 ///
-class LoadSDNode : public SDNode {
+class LoadSDNode : public LSBaseSDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
-  SDOperand Ops[3];
   
   // AddrMode - unindexed, pre-indexed, post-indexed.
   ISD::MemIndexedMode AddrMode;
@@ -1468,26 +1520,13 @@
 
   // LoadedVT - VT of loaded value before extension.
   MVT::ValueType LoadedVT;
-
-  // SrcValue - Memory location for alias analysis.
-  const Value *SrcValue;
-
-  // SVOffset - Memory location offset.
-  int SVOffset;
-
-  // Alignment - Alignment of memory location in bytes.
-  unsigned Alignment;
-
-  // IsVolatile - True if the load is volatile.
-  bool IsVolatile;
 protected:
   friend class SelectionDAG;
   LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs,
              ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT,
              const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
-    : SDNode(ISD::LOAD, VTs),
-      AddrMode(AM), ExtType(ETy), LoadedVT(LVT), SrcValue(SV), SVOffset(O),
-      Alignment(Align), IsVolatile(Vol) {
+    : LSBaseSDNode(ISD::LOAD, VTs, SV, O, Align, Vol),
+      AddrMode(AM), ExtType(ETy), LoadedVT(LVT) {
     Ops[0] = ChainPtrOff[0]; // Chain
     Ops[1] = ChainPtrOff[1]; // Ptr
     Ops[2] = ChainPtrOff[2]; // Off
@@ -1499,18 +1538,12 @@
   }
 public:
 
-  const SDOperand getChain() const { return getOperand(0); }
-  const SDOperand getBasePtr() const { return getOperand(1); }
-  const SDOperand getOffset() const { return getOperand(2); }
   ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
   ISD::LoadExtType getExtensionType() const { return ExtType; }
   MVT::ValueType getLoadedVT() const { return LoadedVT; }
-  const Value *getSrcValue() const { return SrcValue; }
-  int getSrcValueOffset() const { return SVOffset; }
-  unsigned getAlignment() const { return Alignment; }
-  bool isVolatile() const { return IsVolatile; }
 
   static bool classof(const LoadSDNode *) { return true; }
+  static bool classof(const LSBaseSDNode *N) { return true; }
   static bool classof(const SDNode *N) {
     return N->getOpcode() == ISD::LOAD;
   }
@@ -1518,9 +1551,8 @@
 
 /// StoreSDNode - This class is used to represent ISD::STORE nodes.
 ///
-class StoreSDNode : public SDNode {
+class StoreSDNode : public LSBaseSDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
-  SDOperand Ops[4];
     
   // AddrMode - unindexed, pre-indexed, post-indexed.
   ISD::MemIndexedMode AddrMode;
@@ -1530,26 +1562,13 @@
 
   // StoredVT - VT of the value after truncation.
   MVT::ValueType StoredVT;
-
-  // SrcValue - Memory location for alias analysis.
-  const Value *SrcValue;
-
-  // SVOffset - Memory location offset.
-  int SVOffset;
-
-  // Alignment - Alignment of memory location in bytes.
-  unsigned Alignment;
-
-  // IsVolatile - True if the store is volatile.
-  bool IsVolatile;
 protected:
   friend class SelectionDAG;
   StoreSDNode(SDOperand *ChainValuePtrOff, SDVTList VTs,
               ISD::MemIndexedMode AM, bool isTrunc, MVT::ValueType SVT,
               const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
-    : SDNode(ISD::STORE, VTs),
-      AddrMode(AM), IsTruncStore(isTrunc), StoredVT(SVT), SrcValue(SV),
-      SVOffset(O), Alignment(Align), IsVolatile(Vol) {
+    : LSBaseSDNode(ISD::STORE, VTs, SV, O, Align, Vol),
+      AddrMode(AM), IsTruncStore(isTrunc), StoredVT(SVT) {
     Ops[0] = ChainValuePtrOff[0]; // Chain
     Ops[1] = ChainValuePtrOff[1]; // Value
     Ops[2] = ChainValuePtrOff[2]; // Ptr
@@ -1562,19 +1581,12 @@
   }
 public:
 
-  const SDOperand getChain() const { return getOperand(0); }
-  const SDOperand getValue() const { return getOperand(1); }
-  const SDOperand getBasePtr() const { return getOperand(2); }
-  const SDOperand getOffset() const { return getOperand(3); }
   ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
   bool isTruncatingStore() const { return IsTruncStore; }
   MVT::ValueType getStoredVT() const { return StoredVT; }
-  const Value *getSrcValue() const { return SrcValue; }
-  int getSrcValueOffset() const { return SVOffset; }
-  unsigned getAlignment() const { return Alignment; }
-  bool isVolatile() const { return IsVolatile; }
 
   static bool classof(const StoreSDNode *) { return true; }
+  static bool classof(const LSBaseSDNode *N) { return true; }
   static bool classof(const SDNode *N) {
     return N->getOpcode() == ISD::STORE;
   }

Modified: llvm/trunk/include/llvm/IntrinsicsCellSPU.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsCellSPU.td?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/include/llvm/IntrinsicsCellSPU.td (original)
+++ llvm/trunk/include/llvm/IntrinsicsCellSPU.td Thu Jan 10 20:53:15 2008
@@ -17,8 +17,8 @@
 //===----------------------------------------------------------------------===//
 
 // 7-bit integer type, used as an immediate:
-def cell_i7_ty: LLVMType<i16>;   // Note: This was i8
-def cell_i8_ty: LLVMType<i16>;   // Note: This was i8
+def cell_i7_ty: LLVMType<i8>;
+def cell_i8_ty: LLVMType<i8>;
 
 class v16i8_u7imm<string builtin_suffix> :
   GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
@@ -27,7 +27,7 @@
 
 class v16i8_u8imm<string builtin_suffix> :
   GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
-  Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty],
+  Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
             [IntrNoMem]>;
 
 class v16i8_s10imm<string builtin_suffix> :

Modified: llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td (original)
+++ llvm/trunk/lib/Target/CellSPU/CellSDKIntrinsics.td Thu Jan 10 20:53:15 2008
@@ -108,18 +108,18 @@
 
 def CellSDKand:
         RRForm<0b1000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
-          "add\t $rT, $rA, $rB", IntegerOp,
+          "and\t $rT, $rA, $rB", IntegerOp,
           [(set (v4i32 VECREG:$rT),
                 (int_spu_si_and (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
 
 def CellSDKandc:
         RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
-          "addc\t $rT, $rA, $rB", IntegerOp,
+          "andc\t $rT, $rA, $rB", IntegerOp,
           [(set (v4i32 VECREG:$rT),
                 (int_spu_si_andc (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
 
 def CellSDKandbi:
-     RI10Form<0b01101000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val),
+     RI10Form<0b01101000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
        "andbi\t $rT, $rA, $val", BranchResolv,
        [(set (v16i8 VECREG:$rT),
              (int_spu_si_andbi (v16i8 VECREG:$rA), immU8:$val))]>;
@@ -149,7 +149,7 @@
                 (int_spu_si_orc (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
 
 def CellSDKorbi:
-     RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val),
+     RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
        "orbi\t $rT, $rA, $val", BranchResolv,
        [(set (v16i8 VECREG:$rT),
              (int_spu_si_orbi (v16i8 VECREG:$rA), immU8:$val))]>;
@@ -173,7 +173,7 @@
                 (int_spu_si_xor (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
 
 def CellSDKxorbi:
-     RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val),
+     RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
        "xorbi\t $rT, $rA, $val", BranchResolv,
        [(set (v16i8 VECREG:$rT), (int_spu_si_xorbi (v16i8 VECREG:$rA), immU8:$val))]>;
 
@@ -248,7 +248,7 @@
               (int_spu_si_ceqb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>;
 
 def CellSDKceqbi:
-  RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val),
+  RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
         "ceqbi\t $rT, $rA, $val", BranchResolv,
     [(set (v16i8 VECREG:$rT), (int_spu_si_ceqbi (v16i8 VECREG:$rA), immU8:$val))]>;
 
@@ -294,7 +294,7 @@
               (int_spu_si_cgtb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>;
 
 def CellSDKcgtbi:
-  RI10Form<0b01110010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val),
+  RI10Form<0b01110010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
     "cgtbi\t $rT, $rA, $val", BranchResolv,
         [(set (v16i8 VECREG:$rT), (int_spu_si_cgtbi (v16i8 VECREG:$rA), immU8:$val))]>;
 
@@ -329,7 +329,7 @@
           (int_spu_si_clgtb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>;
 
 def CellSDKclgtbi:
-  RI10Form<0b01111010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val),
+  RI10Form<0b01111010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
     "clgtbi\t $rT, $rA, $val", BranchResolv,
     [(set (v16i8 VECREG:$rT),
           (int_spu_si_clgtbi (v16i8 VECREG:$rA), immU8:$val))]>;

Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Thu Jan 10 20:53:15 2008
@@ -384,11 +384,17 @@
 SPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
 		    SDOperand &Index) {
   // These match the addr256k operand type:
-  MVT::ValueType PtrVT = SPUtli.getPointerTy();
   MVT::ValueType OffsVT = MVT::i16;
+  MVT::ValueType PtrVT = SPUtli.getPointerTy();
 
   switch (N.getOpcode()) {
   case ISD::Constant:
+  case ISD::ConstantPool:
+  case ISD::GlobalAddress:
+    cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n";
+    abort();
+    /*NOTREACHED*/
+
   case ISD::TargetConstant: {
     // Loading from a constant address.
     ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
@@ -400,23 +406,15 @@
       return true;
     }
   }
-  case ISD::ConstantPool:
-  case ISD::TargetConstantPool: {
-    // The constant pool address is N. Base is a dummy that will be ignored by
+  case ISD::TargetGlobalAddress:
+  case ISD::TargetConstantPool:
+  case SPUISD::AFormAddr: {
+    // The address is in Base. N is a dummy that will be ignored by
     // the assembly printer.
     Base = N;
     Index = CurDAG->getTargetConstant(0, OffsVT);
     return true;
   }
-
-  case ISD::GlobalAddress:
-  case ISD::TargetGlobalAddress: {
-    // The global address is N. Base is a dummy that is ignored by the
-    // assembly printer.
-    Base = N;
-    Index = CurDAG->getTargetConstant(0, OffsVT);
-    return true;
-  }
   }
 
   return false;
@@ -445,10 +443,9 @@
     Index = CurDAG->getTargetConstant(0, PtrTy);
     return true;
   } else if (Opc == ISD::FrameIndex) {
-    // Stack frame index must be less than 512 (divided by 16):
     FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N);
     DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
-	  << FI->getIndex() << "\n");
+	       << FI->getIndex() << "\n");
     if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
       Base = CurDAG->getTargetConstant(0, PtrTy);
       Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
@@ -458,45 +455,49 @@
     // Generated by getelementptr
     const SDOperand Op0 = N.getOperand(0); // Frame index/base
     const SDOperand Op1 = N.getOperand(1); // Offset within base
-    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
-
-    // Not a constant?
-    if (CN == 0)
-      return false;
-
-    int32_t offset = (int32_t) CN->getSignExtended();
-    unsigned Opc0 = Op0.getOpcode();
 
-    if ((offset & 0xf) != 0) {
-      cerr << "SelectDFormAddr: unaligned offset = " << offset << "\n";
-      abort();
-      /*NOTREACHED*/
-    }
-
-    if (Opc0 == ISD::FrameIndex) {
-      FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0);
-      DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
-	    << " frame index = " << FI->getIndex() << "\n");
-
-      if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
-	Base = CurDAG->getTargetConstant(offset, PtrTy);
-	Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
-	return true;
+    if (Op1.getOpcode() == ISD::Constant
+        || Op1.getOpcode() == ISD::TargetConstant) {
+      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
+      assert(CN != 0 && "SelectDFormAddr: Expected a constant");
+
+      int32_t offset = (int32_t) CN->getSignExtended();
+      unsigned Opc0 = Op0.getOpcode();
+
+      if ((offset & 0xf) != 0) {
+        // Unaligned offset: punt and let X-form address handle it.
+        // NOTE: This really doesn't have to be strictly 16-byte aligned,
+        // since the load/store quadword instructions will implicitly
+        // zero the lower 4 bits of the resulting address.
+        return false;
       }
-    } else if (offset > SPUFrameInfo::minFrameOffset()
-	       && offset < SPUFrameInfo::maxFrameOffset()) {
-      Base = CurDAG->getTargetConstant(offset, PtrTy);
-      if (Opc0 == ISD::GlobalAddress) {
-	// Convert global address to target global address
-	GlobalAddressSDNode *GV = dyn_cast<GlobalAddressSDNode>(Op0);
-	Index = CurDAG->getTargetGlobalAddress(GV->getGlobal(), PtrTy);
-	return true;
-      } else {
-	// Otherwise, just take operand 0
-	Index = Op0;
-	return true;
+
+      if (Opc0 == ISD::FrameIndex) {
+        FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0);
+        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
+              << " frame index = " << FI->getIndex() << "\n");
+
+        if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
+          Base = CurDAG->getTargetConstant(offset, PtrTy);
+          Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
+          return true;
+        }
+      } else if (offset > SPUFrameInfo::minFrameOffset()
+                 && offset < SPUFrameInfo::maxFrameOffset()) {
+        Base = CurDAG->getTargetConstant(offset, PtrTy);
+        if (Opc0 == ISD::GlobalAddress) {
+          // Convert global address to target global address
+          GlobalAddressSDNode *GV = dyn_cast<GlobalAddressSDNode>(Op0);
+          Index = CurDAG->getTargetGlobalAddress(GV->getGlobal(), PtrTy);
+          return true;
+        } else {
+          // Otherwise, just take operand 0
+          Index = Op0;
+          return true;
+        }
       }
-    }
+    } else
+      return false;
   } else if (Opc == SPUISD::DFormAddr) {
     // D-Form address: This is pretty straightforward, naturally...
     ConstantSDNode *CN = cast<ConstantSDNode>(N.getOperand(1));
@@ -504,6 +505,16 @@
     Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy);
     Index = N.getOperand(0);
     return true;
+  } else if (Opc == ISD::FrameIndex) {
+    // Stack frame index must be less than 512 (divided by 16):
+    FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N);
+    DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
+	  << FI->getIndex() << "\n");
+    if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
+      Base = CurDAG->getTargetConstant(0, PtrTy);
+      Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
+      return true;
+    }
   }
 
   return false;
@@ -535,7 +546,8 @@
     unsigned N2Opc = N2.getOpcode();
 
     if ((N1Opc == SPUISD::Hi && N2Opc == SPUISD::Lo)
-	 || (N1Opc == SPUISD::Lo && N2Opc == SPUISD::Hi)) {
+	 || (N1Opc == SPUISD::Lo && N2Opc == SPUISD::Hi)
+        || (N1Opc == SPUISD::XFormAddr)) {
       Base = N.getOperand(0);
       Index = N.getOperand(1);
       return true;
@@ -548,6 +560,10 @@
       abort();
       /*UNREACHED*/
     }
+  } else if (Opc == SPUISD::XFormAddr) {
+    Base = N;
+    Index = N.getOperand(1);
+    return true;
   } else if (N.getNumOperands() == 2) {
     SDOperand N1 = N.getOperand(0);
     SDOperand N2 = N.getOperand(1);
@@ -591,11 +607,14 @@
   } else if (Opc == ISD::FrameIndex) {
     // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm.
     int FI = cast<FrameIndexSDNode>(N)->getIndex();
-    SDOperand TFI = CurDAG->getTargetFrameIndex(FI, SPUtli.getPointerTy());
+    MVT::ValueType PtrVT = SPUtli.getPointerTy();
+    SDOperand Zero = CurDAG->getTargetConstant(0, PtrVT);
+    SDOperand TFI = CurDAG->getTargetFrameIndex(FI, PtrVT);
 
     DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 <FI>, 0\n");
-    return CurDAG->SelectNodeTo(N, SPU::AIr32, Op.getValueType(), TFI,
-				CurDAG->getTargetConstant(0, MVT::i32));
+    if (N->hasOneUse())
+      return CurDAG->SelectNodeTo(N, SPU::AIr32, Op.getValueType(), TFI, Zero);
+    CurDAG->getTargetNode(SPU::AIr32, Op.getValueType(), TFI, Zero);
   } else if (Opc == SPUISD::LDRESULT) {
     // Custom select instructions for LDRESULT
     unsigned VT = N->getValueType(0);

Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Thu Jan 10 20:53:15 2008
@@ -82,7 +82,7 @@
   /*!
     \arg Op Operand to test
     \return true if the operand is a memory target (i.e., global
-    address, external symbol, constant pool) or an existing D-Form
+    address, external symbol, constant pool) or an A-form
     address.
    */
   bool isMemoryOperand(const SDOperand &Op)
@@ -90,17 +90,17 @@
     const unsigned Opc = Op.getOpcode();
     return (Opc == ISD::GlobalAddress
             || Opc == ISD::GlobalTLSAddress
-            || Opc ==  ISD::FrameIndex
+            /* || Opc ==  ISD::FrameIndex */
             || Opc == ISD::JumpTable
             || Opc == ISD::ConstantPool
             || Opc == ISD::ExternalSymbol
             || Opc == ISD::TargetGlobalAddress
             || Opc == ISD::TargetGlobalTLSAddress
-            || Opc == ISD::TargetFrameIndex
+            /* || Opc == ISD::TargetFrameIndex */
             || Opc == ISD::TargetJumpTable
             || Opc == ISD::TargetConstantPool
             || Opc == ISD::TargetExternalSymbol
-	    || Opc == SPUISD::DFormAddr);
+            || Opc == SPUISD::AFormAddr);
   }
 }
 
@@ -356,7 +356,7 @@
   setOperationAction(ISD::OR,  MVT::v16i8, Custom);
   setOperationAction(ISD::XOR, MVT::v16i8, Custom);
   setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
-  
+
   setSetCCResultType(MVT::i32);
   setShiftAmountType(MVT::i32);
   setSetCCResultContents(ZeroOrOneSetCCResult);
@@ -377,6 +377,7 @@
     node_names[(unsigned) SPUISD::Hi] = "SPUISD::Hi";
     node_names[(unsigned) SPUISD::Lo] = "SPUISD::Lo";
     node_names[(unsigned) SPUISD::PCRelAddr] = "SPUISD::PCRelAddr";
+    node_names[(unsigned) SPUISD::AFormAddr] = "SPUISD::AFormAddr";
     node_names[(unsigned) SPUISD::DFormAddr] = "SPUISD::DFormAddr";
     node_names[(unsigned) SPUISD::XFormAddr] = "SPUISD::XFormAddr";
     node_names[(unsigned) SPUISD::LDRESULT] = "SPUISD::LDRESULT";
@@ -430,6 +431,105 @@
 //  LowerOperation implementation
 //===----------------------------------------------------------------------===//
 
+/// Aligned load common code for CellSPU
+/*!
+  \param[in] Op The SelectionDAG load or store operand
+  \param[in] DAG The selection DAG
+  \param[in] ST CellSPU subtarget information structure
+  \param[in,out] alignment Caller initializes this to the load or store node's
+  value from getAlignment(), may be updated while generating the aligned load
+  \param[in,out] alignOffs Aligned offset; set by AlignedLoad to the aligned
+  offset (divisible by 16, modulo 16 == 0)
+  \param[in,out] prefSlotOffs Preferred slot offset; set by AlignedLoad to the
+  offset of the preferred slot (modulo 16 != 0)
+  \param[in,out] VT Caller initializes this value type to the the load or store
+  node's loaded or stored value type; may be updated if an i1-extended load or
+  store.
+  \param[out] was16aligned true if the base pointer had 16-byte alignment,
+  otherwise false. Can help to determine if the chunk needs to be rotated.
+
+ Both load and store lowering load a block of data aligned on a 16-byte
+ boundary. This is the common aligned load code shared between both.
+ */
+static SDOperand
+AlignedLoad(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST,
+            LSBaseSDNode *LSN,
+            unsigned &alignment, int &alignOffs, int &prefSlotOffs,
+            unsigned &VT, bool &was16aligned)
+{
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  const valtype_map_s *vtm = getValueTypeMapEntry(VT);
+  SDOperand basePtr = LSN->getBasePtr();
+  SDOperand chain = LSN->getChain();
+
+  if (basePtr.getOpcode() == ISD::ADD) {
+    SDOperand Op1 = basePtr.Val->getOperand(1);
+
+    if (Op1.getOpcode() == ISD::Constant || Op1.getOpcode() == ISD::TargetConstant) {
+      const ConstantSDNode *CN = cast<ConstantSDNode>(basePtr.Val->getOperand(1));
+
+      alignOffs = (int) CN->getValue();
+      prefSlotOffs = (int) (alignOffs & 0xf);
+
+      // Adjust the rotation amount to ensure that the final result ends up in
+      // the preferred slot:
+      prefSlotOffs -= vtm->prefslot_byte;
+      basePtr = basePtr.getOperand(0);
+
+      // Modify alignment, since the ADD is likely from getElementPtr:
+      switch (basePtr.getOpcode()) {
+      case ISD::GlobalAddress:
+      case ISD::TargetGlobalAddress: {
+        GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(basePtr.Val);
+        const GlobalValue *GV = GN->getGlobal();
+        alignment = GV->getAlignment();
+        break;
+      }
+      }
+    } else {
+      alignOffs = 0;
+      prefSlotOffs = -vtm->prefslot_byte;
+    }
+  } else {
+    alignOffs = 0;
+    prefSlotOffs = -vtm->prefslot_byte;
+  }
+
+  if (alignment == 16) {
+    // Realign the base pointer as a D-Form address:
+    if (!isMemoryOperand(basePtr) || (alignOffs & ~0xf) != 0) {
+      if (isMemoryOperand(basePtr)) {
+        SDOperand Zero = DAG.getConstant(0, PtrVT);
+        unsigned Opc = (!ST->usingLargeMem()
+                        ? SPUISD::AFormAddr
+                        : SPUISD::XFormAddr);
+        basePtr = DAG.getNode(Opc, PtrVT, basePtr, Zero);
+      }
+      basePtr = DAG.getNode(SPUISD::DFormAddr, PtrVT,
+                          basePtr, DAG.getConstant((alignOffs & ~0xf), PtrVT));
+    }
+
+    // Emit the vector load:
+    was16aligned = true;
+    return DAG.getLoad(MVT::v16i8, chain, basePtr,
+                       LSN->getSrcValue(), LSN->getSrcValueOffset(),
+                       LSN->isVolatile(), 16);
+  }
+
+  // Unaligned load or we're using the "large memory" model, which means that
+  // we have to be very pessimistic:
+  if (isMemoryOperand(basePtr)) {
+    basePtr = DAG.getNode(SPUISD::XFormAddr, PtrVT, basePtr, DAG.getConstant(0, PtrVT));
+  }
+
+  // Add the offset
+  basePtr = DAG.getNode(ISD::ADD, PtrVT, basePtr, DAG.getConstant(alignOffs, PtrVT));
+  was16aligned = false;
+  return DAG.getLoad(MVT::v16i8, chain, basePtr,
+                     LSN->getSrcValue(), LSN->getSrcValueOffset(),
+                     LSN->isVolatile(), 16);
+}
+
 /// Custom lower loads for CellSPU
 /*!
  All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements
@@ -438,22 +538,13 @@
 static SDOperand
 LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
   LoadSDNode *LN = cast<LoadSDNode>(Op);
-  SDOperand basep = LN->getBasePtr();
   SDOperand the_chain = LN->getChain();
-  MVT::ValueType BasepOpc = basep.Val->getOpcode();
   MVT::ValueType VT = LN->getLoadedVT();
   MVT::ValueType OpVT = Op.Val->getValueType(0);
-  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
   ISD::LoadExtType ExtType = LN->getExtensionType();
   unsigned alignment = LN->getAlignment();
-  const valtype_map_s *vtm = getValueTypeMapEntry(VT);
   SDOperand Ops[8];
 
-  if (BasepOpc == ISD::FrameIndex) {
-    // Loading from a frame index is always properly aligned. Always.
-    return SDOperand();
-  }
-
   // For an extending load of an i1 variable, just call it i8 (or whatever we
   // were passed) and make it zero-extended:
   if (VT == MVT::i1) {
@@ -463,178 +554,76 @@
 
   switch (LN->getAddressingMode()) {
   case ISD::UNINDEXED: {
-    SDOperand result;
-    SDOperand rot_op, rotamt;
-    SDOperand ptrp;
-    int c_offset;
-    int c_rotamt;
+    int offset, rotamt;
+    bool was16aligned;
+    SDOperand result =
+      AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned);
 
-    // The vector type we really want to be when we load the 16-byte chunk
-    MVT::ValueType vecVT, opVecVT;
-    
-    vecVT = MVT::v16i8;
-    if (VT != MVT::i1)
-      vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
-    opVecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
-
-    if (basep.getOpcode() == ISD::ADD) {
-      const ConstantSDNode *CN = cast<ConstantSDNode>(basep.Val->getOperand(1));
-
-      assert(CN != NULL
-             && "LowerLOAD: ISD::ADD operand 1 is not constant");
-
-      c_offset = (int) CN->getValue();
-      c_rotamt = (int) (c_offset & 0xf);
+    if (result.Val == 0)
+      return result;
 
-      // Adjust the rotation amount to ensure that the final result ends up in
-      // the preferred slot:
-      c_rotamt -= vtm->prefslot_byte;
-      ptrp = basep.getOperand(0);
-    } else {
-      c_offset = 0;
-      c_rotamt = -vtm->prefslot_byte;
-      ptrp = basep;
-    }
-
-    if (alignment == 16) {
-      // 16-byte aligned load into preferred slot, no rotation
-      if (c_rotamt == 0) {
-	if (isMemoryOperand(ptrp))
-	  // Return unchanged
-	  return SDOperand();
-	else {
-	  // Return modified D-Form address for pointer:
-	  ptrp = DAG.getNode(SPUISD::DFormAddr, PtrVT,
-			     ptrp, DAG.getConstant((c_offset & ~0xf), PtrVT));
-	  if (VT == OpVT)
-	    return DAG.getLoad(VT, LN->getChain(), ptrp,
-			       LN->getSrcValue(), LN->getSrcValueOffset(),
-			       LN->isVolatile(), 16);
-	  else
-	    return DAG.getExtLoad(ExtType, VT, LN->getChain(), ptrp, LN->getSrcValue(),
-				  LN->getSrcValueOffset(), OpVT,
-				  LN->isVolatile(), 16);
-	}
+    the_chain = result.getValue(1);
+    // Rotate the chunk if necessary
+    if (rotamt < 0)
+      rotamt += 16;
+    if (rotamt != 0) {
+      SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
+
+      if (was16aligned) {
+        Ops[0] = the_chain;
+        Ops[1] = result;
+        Ops[2] = DAG.getConstant(rotamt, MVT::i16);
       } else {
-	// Need to rotate...
-	if (c_rotamt < 0)
-	  c_rotamt += 16;
-	// Realign the base pointer, with a D-Form address
-	if ((c_offset & ~0xf) != 0 || !isMemoryOperand(ptrp))
-	  basep = DAG.getNode(SPUISD::DFormAddr, PtrVT,
-			      ptrp, DAG.getConstant((c_offset & ~0xf), MVT::i32));
-	else
-	  basep = ptrp;
-
-	// Rotate the load:
-	rot_op = DAG.getLoad(MVT::v16i8, the_chain, basep,
-			     LN->getSrcValue(), LN->getSrcValueOffset(),
-			     LN->isVolatile(), 16);
-	the_chain = rot_op.getValue(1);
-	rotamt = DAG.getConstant(c_rotamt, MVT::i16);
-
-	SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other);
-	Ops[0] = the_chain;
-	Ops[1] = rot_op;
-	Ops[2] = rotamt;
-
-	result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
-	the_chain = result.getValue(1);
-
-	if (VT == OpVT || ExtType == ISD::EXTLOAD) {
-	  SDVTList scalarvts;
-	  Ops[0] = the_chain;
-	  Ops[1] = result;
-	  if (OpVT == VT) {
-	    scalarvts = DAG.getVTList(VT, MVT::Other);
-	  } else {
-	    scalarvts = DAG.getVTList(OpVT, MVT::Other);
-	  }
-
-	  result = DAG.getNode(ISD::BIT_CONVERT, (OpVT == VT ? vecVT : opVecVT),
-	                       result);
-	  Ops[0] = the_chain;
-	  Ops[1] = result;
-	  result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
-	  the_chain = result.getValue(1);
-	} else {
-	  // Handle the sign and zero-extending loads for i1 and i8:
-	  unsigned NewOpC;
-
-	  if (ExtType == ISD::SEXTLOAD) {
-	    NewOpC = (OpVT == MVT::i1
-		      ? SPUISD::EXTRACT_I1_SEXT
-		      : SPUISD::EXTRACT_I8_SEXT);
-	  } else {
-      assert(ExtType == ISD::ZEXTLOAD);
-	    NewOpC = (OpVT == MVT::i1
-		      ? SPUISD::EXTRACT_I1_ZEXT
-		      : SPUISD::EXTRACT_I8_ZEXT);
-	  }
-
-	  result = DAG.getNode(NewOpC, OpVT, result);
-	}
-
-	SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
-	SDOperand retops[2] = { result, the_chain };
-
-	result = DAG.getNode(SPUISD::LDRESULT, retvts, retops, 2);
-	return result;
-	/*UNREACHED*/
-      }
-    } else {
-      // Misaligned 16-byte load:
-      if (basep.getOpcode() == ISD::LOAD) {
-	LN = cast<LoadSDNode>(basep);
-	if (LN->getAlignment() == 16) {
-	  // We can verify that we're really loading from a 16-byte aligned
-	  // chunk. Encapsulate basep as a D-Form address and return a new
-	  // load:
-	  basep = DAG.getNode(SPUISD::DFormAddr, PtrVT, basep,
-			      DAG.getConstant(0, PtrVT));
-	  if (OpVT == VT)
-	    return DAG.getLoad(VT, LN->getChain(), basep,
-			       LN->getSrcValue(), LN->getSrcValueOffset(),
-			       LN->isVolatile(), 16);
-	  else
-	    return DAG.getExtLoad(ExtType, VT, LN->getChain(), basep,
-				  LN->getSrcValue(), LN->getSrcValueOffset(),
-				  OpVT, LN->isVolatile(), 16);
-	}
+        LoadSDNode *LN1 = cast<LoadSDNode>(result);
+        Ops[0] = the_chain;
+        Ops[1] = result;
+        Ops[2] = LN1->getBasePtr();
       }
 
-      // Catch all other cases where we can't guarantee that we have a
-      // 16-byte aligned entity, which means resorting to an X-form
-      // address scheme:
-
-      SDOperand ZeroOffs = DAG.getConstant(0, PtrVT);
-      SDOperand loOp = DAG.getNode(SPUISD::Lo, PtrVT, basep, ZeroOffs);
-      SDOperand hiOp = DAG.getNode(SPUISD::Hi, PtrVT, basep, ZeroOffs);
-
-      ptrp = DAG.getNode(ISD::ADD, PtrVT, loOp, hiOp);
-
-      SDOperand alignLoad =
-	DAG.getLoad(opVecVT, LN->getChain(), ptrp,
-		    LN->getSrcValue(), LN->getSrcValueOffset(),
-		    LN->isVolatile(), 16);
+      result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3);
+      the_chain = result.getValue(1);
+    }
 
-      SDOperand insertEltOp =
-	DAG.getNode(SPUISD::INSERT_MASK, vecVT, ptrp);
+    if (VT == OpVT || ExtType == ISD::EXTLOAD) {
+      SDVTList scalarvts;
+      MVT::ValueType vecVT = MVT::v16i8;
+    
+      // Convert the loaded v16i8 vector to the appropriate vector type
+      // specified by the operand:
+      if (OpVT == VT) {
+        if (VT != MVT::i1)
+          vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
+      } else
+        vecVT = MVT::getVectorType(OpVT, (128 / MVT::getSizeInBits(OpVT)));
+
+      Ops[0] = the_chain;
+      Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result);
+      scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other);
+      result = DAG.getNode(SPUISD::EXTRACT_ELT0_CHAINED, scalarvts, Ops, 2);
+      the_chain = result.getValue(1);
+    } else {
+      // Handle the sign and zero-extending loads for i1 and i8:
+      unsigned NewOpC;
 
-      result = DAG.getNode(SPUISD::SHUFB, opVecVT,
-			   alignLoad,
-			   alignLoad,
-			   DAG.getNode(ISD::BIT_CONVERT, opVecVT, insertEltOp));
+      if (ExtType == ISD::SEXTLOAD) {
+        NewOpC = (OpVT == MVT::i1
+                  ? SPUISD::EXTRACT_I1_SEXT
+                  : SPUISD::EXTRACT_I8_SEXT);
+      } else {
+        assert(ExtType == ISD::ZEXTLOAD);
+        NewOpC = (OpVT == MVT::i1
+                  ? SPUISD::EXTRACT_I1_ZEXT
+                  : SPUISD::EXTRACT_I8_ZEXT);
+      }
 
-      result = DAG.getNode(SPUISD::EXTRACT_ELT0, OpVT, result);
+      result = DAG.getNode(NewOpC, OpVT, result);
+    }
 
-      SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
-      SDOperand retops[2] = { result, the_chain };
+    SDVTList retvts = DAG.getVTList(OpVT, MVT::Other);
+    SDOperand retops[2] = { result, the_chain };
 
-      result = DAG.getNode(SPUISD::LDRESULT, retvts, retops, 2);
-      return result;
-    }
-    break;
+    result = DAG.getNode(SPUISD::LDRESULT, retvts, retops, 2);
+    return result;
   }
   case ISD::PRE_INC:
   case ISD::PRE_DEC:
@@ -664,58 +653,31 @@
   MVT::ValueType VT = Value.getValueType();
   MVT::ValueType StVT = (!SN->isTruncatingStore() ? VT : SN->getStoredVT());
   MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
-  SDOperand the_chain = SN->getChain();
-  //unsigned alignment = SN->getAlignment();
-  //const valtype_map_s *vtm = getValueTypeMapEntry(VT);
+  unsigned alignment = SN->getAlignment();
 
   switch (SN->getAddressingMode()) {
   case ISD::UNINDEXED: {
-    SDOperand basep = SN->getBasePtr();
-    SDOperand ptrOp;
-    int offset;
-
-    if (basep.getOpcode() == ISD::FrameIndex) {
-      // FrameIndex nodes are always properly aligned. Really.
-      return SDOperand();
-    }
-
-    if (basep.getOpcode() == ISD::ADD) {
-      const ConstantSDNode *CN = cast<ConstantSDNode>(basep.Val->getOperand(1));
-      assert(CN != NULL
-             && "LowerSTORE: ISD::ADD operand 1 is not constant");
-      offset = unsigned(CN->getValue());
-      ptrOp = basep.getOperand(0);
-      DEBUG(cerr << "LowerSTORE: StoreSDNode ISD:ADD offset = "
-	         << offset
-		 << "\n");
-    } else {
-      ptrOp = basep;
-      offset = 0;
-    }
+    int chunk_offset, slot_offset;
+    bool was16aligned;
 
     // The vector type we really want to load from the 16-byte chunk, except
     // in the case of MVT::i1, which has to be v16i8.
-    unsigned vecVT, stVecVT;
-
+    unsigned vecVT, stVecVT = MVT::v16i8;
+ 
     if (StVT != MVT::i1)
       stVecVT = MVT::getVectorType(StVT, (128 / MVT::getSizeInBits(StVT)));
-    else
-      stVecVT = MVT::v16i8;
     vecVT = MVT::getVectorType(VT, (128 / MVT::getSizeInBits(VT)));
 
-    // Realign the pointer as a D-Form address (ptrOp is the pointer, basep is
-    // the actual dform addr offs($reg).
-    basep = DAG.getNode(SPUISD::DFormAddr, PtrVT, ptrOp,
-                        DAG.getConstant((offset & ~0xf), PtrVT));
-
-    // Create the 16-byte aligned vector load
-    SDOperand alignLoad =
-      DAG.getLoad(vecVT, the_chain, basep,
-                  SN->getSrcValue(), SN->getSrcValueOffset(),
-                  SN->isVolatile(), 16);
-    the_chain = alignLoad.getValue(1);
-
-    LoadSDNode *LN = cast<LoadSDNode>(alignLoad);
+    SDOperand alignLoadVec =
+      AlignedLoad(Op, DAG, ST, SN, alignment,
+                  chunk_offset, slot_offset, VT, was16aligned);
+
+    if (alignLoadVec.Val == 0)
+      return alignLoadVec;
+
+    LoadSDNode *LN = cast<LoadSDNode>(alignLoadVec);
+    SDOperand basePtr = LN->getBasePtr();
+    SDOperand the_chain = alignLoadVec.getValue(1);
     SDOperand theValue = SN->getValue();
     SDOperand result;
 
@@ -727,18 +689,34 @@
       theValue = theValue.getOperand(0); 
     }
 
-    SDOperand insertEltOp =
-      DAG.getNode(SPUISD::INSERT_MASK, stVecVT,
-		  DAG.getNode(SPUISD::DFormAddr, PtrVT,
-			      ptrOp,
-			      DAG.getConstant((offset & 0xf), PtrVT)));
+    chunk_offset &= 0xf;
+    chunk_offset /= (MVT::getSizeInBits(StVT == MVT::i1 ? (unsigned) MVT::i8 : StVT) / 8);
 
+    SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT);
+    SDOperand insertEltPtr;
+    SDOperand insertEltOp;
+
+    // If the base pointer is already a D-form address, then just create
+    // a new D-form address with a slot offset and the orignal base pointer.
+    // Otherwise generate a D-form address with the slot offset relative
+    // to the stack pointer, which is always aligned.
+    if (basePtr.getOpcode() == SPUISD::DFormAddr) {
+      insertEltPtr = DAG.getNode(SPUISD::DFormAddr, PtrVT,
+				 basePtr.getOperand(0),
+				 insertEltOffs);
+    } else {
+      insertEltPtr = DAG.getNode(SPUISD::DFormAddr, PtrVT,
+				 DAG.getRegister(SPU::R1, PtrVT),
+				 insertEltOffs);
+    }
+
+    insertEltOp = DAG.getNode(SPUISD::INSERT_MASK, stVecVT, insertEltPtr);
     result = DAG.getNode(SPUISD::SHUFB, vecVT,
 			 DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue),
-			 alignLoad,
+			 alignLoadVec,
 			 DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp));
 
-    result = DAG.getStore(the_chain, result, basep,
+    result = DAG.getStore(the_chain, result, basePtr,
                           LN->getSrcValue(), LN->getSrcValueOffset(),
                           LN->isVolatile(), LN->getAlignment());
 
@@ -767,19 +745,23 @@
   ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
   Constant *C = CP->getConstVal();
   SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
-  const TargetMachine &TM = DAG.getTarget();
   SDOperand Zero = DAG.getConstant(0, PtrVT);
+  const TargetMachine &TM = DAG.getTarget();
 
   if (TM.getRelocationModel() == Reloc::Static) {
     if (!ST->usingLargeMem()) {
       // Just return the SDOperand with the constant pool address in it.
       return CPI;
     } else {
+#if 1
       // Generate hi/lo address pair
       SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, CPI, Zero);
       SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, CPI, Zero);
 
       return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi);
+#else
+      return DAG.getNode(SPUISD::XFormAddr, PtrVT, CPI, Zero);
+#endif
     }
   }
 
@@ -797,16 +779,9 @@
   const TargetMachine &TM = DAG.getTarget();
 
   if (TM.getRelocationModel() == Reloc::Static) {
-    if (!ST->usingLargeMem()) {
-      // Just return the SDOperand with the jump table address in it.
-      return JTI;
-    } else {
-      // Generate hi/lo address pair
-      SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, JTI, Zero);
-      SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, JTI, Zero);
-
-      return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi);
-    }
+    return (!ST->usingLargeMem()
+            ? JTI
+            : DAG.getNode(SPUISD::XFormAddr, PtrVT, JTI, Zero));
   }
 
   assert(0 &&
@@ -820,20 +795,13 @@
   GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
   GlobalValue *GV = GSDN->getGlobal();
   SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
-  SDOperand Zero = DAG.getConstant(0, PtrVT);
   const TargetMachine &TM = DAG.getTarget();
+  SDOperand Zero = DAG.getConstant(0, PtrVT);
   
   if (TM.getRelocationModel() == Reloc::Static) {
-    if (!ST->usingLargeMem()) {
-      // Generate a local store address
-      return GA;
-    } else {
-      // Generate hi/lo address pair
-      SDOperand Hi = DAG.getNode(SPUISD::Hi, PtrVT, GA, Zero);
-      SDOperand Lo = DAG.getNode(SPUISD::Lo, PtrVT, GA, Zero);
-
-      return DAG.getNode(ISD::ADD, PtrVT, Lo, Hi);
-    }
+    return (!ST->usingLargeMem()
+            ? GA
+            : DAG.getNode(SPUISD::XFormAddr, PtrVT, GA, Zero));
   } else {
     cerr << "LowerGlobalAddress: Relocation model other than static not "
 	 << "supported.\n";
@@ -1074,7 +1042,7 @@
 
 static
 SDOperand
-LowerCALL(SDOperand Op, SelectionDAG &DAG) {
+LowerCALL(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
   SDOperand Chain = Op.getOperand(0);
 #if 0
   bool isVarArg       = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
@@ -1184,25 +1152,35 @@
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
     GlobalValue *GV = G->getGlobal();
     unsigned CalleeVT = Callee.getValueType();
+    SDOperand Zero = DAG.getConstant(0, PtrVT);
+    SDOperand GA = DAG.getTargetGlobalAddress(GV, CalleeVT);
 
-    // Turn calls to targets that are defined (i.e., have bodies) into BRSL
-    // style calls, otherwise, external symbols are BRASL calls.
-    // NOTE:
-    // This may be an unsafe assumption for JIT and really large compilation
-    // units.
-    if (GV->isDeclaration()) {
-      Callee = DAG.getGlobalAddress(GV, CalleeVT);
+    if (!ST->usingLargeMem()) {
+      // Turn calls to targets that are defined (i.e., have bodies) into BRSL
+      // style calls, otherwise, external symbols are BRASL calls. This assumes
+      // that declared/defined symbols are in the same compilation unit and can
+      // be reached through PC-relative jumps.
+      //
+      // NOTE:
+      // This may be an unsafe assumption for JIT and really large compilation
+      // units.
+      if (GV->isDeclaration()) {
+        Callee = DAG.getNode(SPUISD::AFormAddr, CalleeVT, GA, Zero);
+      } else {
+        Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT, GA, Zero);
+      }
     } else {
-      Callee = DAG.getNode(SPUISD::PCRelAddr, CalleeVT,
-                           DAG.getTargetGlobalAddress(GV, CalleeVT),
-                           DAG.getConstant(0, PtrVT));
+      // "Large memory" mode: Turn all calls into indirect calls with a X-form
+      // address pairs:
+      Callee = DAG.getNode(SPUISD::XFormAddr, PtrVT, GA, Zero);
     }
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
     Callee = DAG.getExternalSymbol(S->getSymbol(), Callee.getValueType());
-  else if (SDNode *Dest = isLSAAddress(Callee, DAG))
+  else if (SDNode *Dest = isLSAAddress(Callee, DAG)) {
     // If this is an absolute destination address that appears to be a legal
     // local store address, use the munged value.
     Callee = SDOperand(Dest, 0);
+  }
 
   Ops.push_back(Chain);
   Ops.push_back(Callee);
@@ -2468,7 +2446,7 @@
   case ISD::FORMAL_ARGUMENTS:
       return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
   case ISD::CALL:
-    return LowerCALL(Op, DAG);
+    return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl());
   case ISD::RET:
     return LowerRET(Op, DAG, getTargetMachine());
 

Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h Thu Jan 10 20:53:15 2008
@@ -31,8 +31,9 @@
       Hi,                       ///< High address component (upper 16)
       Lo,                       ///< Low address component (lower 16)
       PCRelAddr,                ///< Program counter relative address
+      AFormAddr,                ///< A-form address (local store)
       DFormAddr,                ///< D-Form address "imm($r)"
-      XFormAddr,		///< X-Form address "$r1($r2)"
+      XFormAddr,                ///< X-Form address "$r($r)"
 
       LDRESULT,                 ///< Load result (value, chain)
       CALL,                     ///< CALL instruction

Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Thu Jan 10 20:53:15 2008
@@ -158,7 +158,7 @@
   def LQAr32:
       RI16Form<0b100001100, (outs R32C:$rT), (ins addr256k:$src),
         "lqa\t$rT, $src", LoadStore,
-        [(set R32C:$rT, (load aform_addr:$src))]>;
+        [(set R32C:$rT, (load  aform_addr:$src))]>;
 
   def LQAf32:
       RI16Form<0b100001100, (outs R32FP:$rT), (ins addr256k:$src),
@@ -610,6 +610,13 @@
       RegConstraint<"$rS = $rT">,
       NoEncode<"$rS">;
 
+def IOHLlo:
+    RI16Form<0b100000110, (outs R32C:$rT), (ins R32C:$rS, symbolLo:$val),
+      "iohl\t$rT, $val", ImmLoad,
+      [/* no pattern */]>,
+      RegConstraint<"$rS = $rT">,
+      NoEncode<"$rS">;
+
 // Form select mask for bytes using immediate, used in conjunction with the
 // SELB instruction:
 
@@ -2367,12 +2374,12 @@
 // are used here for type checking (instances where ROTQBI is used actually
 // use vector registers)
 def ROTQBYvec:
-    RRForm<0b00111011100, (outs VECREG:$rT), (ins VECREG:$rA, R16C:$rB),
+    RRForm<0b00111011100, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
       "rotqby\t$rT, $rA, $rB", RotateShift,
-      [(set (v16i8 VECREG:$rT), (SPUrotbytes_left (v16i8 VECREG:$rA), R16C:$rB))]>;
+      [(set (v16i8 VECREG:$rT), (SPUrotbytes_left (v16i8 VECREG:$rA), R32C:$rB))]>;
 
-def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), R16C:$rB),
-          (ROTQBYvec VECREG:$rA, R16C:$rB)>;
+def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), R32C:$rB),
+          (ROTQBYvec VECREG:$rA, R32C:$rB)>;
 
 // See ROTQBY note above.
 def ROTQBYIvec:
@@ -2720,12 +2727,12 @@
     [/* no pattern to match: intrinsic */]>;
 
 def CEQBIr8:
-  RI10Form<0b01111110, (outs R8C:$rT), (ins R8C:$rA, s7imm:$val),
+  RI10Form<0b01111110, (outs R8C:$rT), (ins R8C:$rA, s7imm_i8:$val),
     "ceqbi\t$rT, $rA, $val", ByteOp,
     [/* no pattern to match: intrinsic */]>;
 
 def CEQBIv16i8:
-  RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, s7imm:$val),
+  RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, s7imm_i8:$val),
     "ceqbi\t$rT, $rA, $val", ByteOp,
     [/* no pattern to match: intrinsic */]>;
 
@@ -2793,7 +2800,7 @@
   def BRASL:
     BranchSetLink<0b011001100, (outs), (ins calltarget:$func, variable_ops),
       "brasl\t$$lr, $func",
-      [(SPUcall tglobaladdr:$func)]>;
+      [(SPUcall (SPUaform tglobaladdr:$func, 0))]>;
 
   // Branch indirect and set link if external data. These instructions are not
   // actually generated, matched by an intrinsic:
@@ -3468,20 +3475,21 @@
 // low parts in order to load them into a register.
 //===----------------------------------------------------------------------===//
 
-def : Pat<(SPUhi    tglobaladdr:$in, 0), (ILHUhi tglobaladdr:$in)>;
-def : Pat<(SPUlo    tglobaladdr:$in, 0), (ILAlo  tglobaladdr:$in)>;
-def : Pat<(SPUdform tglobaladdr:$in, imm:$imm), (ILAlsa tglobaladdr:$in)>;
-def : Pat<(SPUhi    tconstpool:$in , 0), (ILHUhi tconstpool:$in)>;
-def : Pat<(SPUlo    tconstpool:$in , 0), (ILAlo  tconstpool:$in)>;
-def : Pat<(SPUdform tconstpool:$in, imm:$imm), (ILAlsa tconstpool:$in)>;
-def : Pat<(SPUhi    tjumptable:$in, 0),  (ILHUhi tjumptable:$in)>;
-def : Pat<(SPUlo    tjumptable:$in, 0),  (ILAlo tjumptable:$in)>;
-def : Pat<(SPUdform tjumptable:$in, imm:$imm),  (ILAlsa tjumptable:$in)>;
-
-// Force load of global address to a register. These forms show up in
-// SPUISD::DFormAddr pseudo instructions:
-def : Pat<(add tglobaladdr:$in, 0), (ILAlsa tglobaladdr:$in)>;
-def : Pat<(add tconstpool:$in, 0),  (ILAlsa tglobaladdr:$in)>;
-def : Pat<(add tjumptable:$in, 0),  (ILAlsa tglobaladdr:$in)>;
+def : Pat<(SPUhi    tglobaladdr:$in, 0),        (ILHUhi tglobaladdr:$in)>;
+def : Pat<(SPUlo    tglobaladdr:$in, 0),        (ILAlo  tglobaladdr:$in)>;
+def : Pat<(SPUaform tglobaladdr:$in, 0),        (ILAlsa tglobaladdr:$in)>;
+def : Pat<(SPUxform tglobaladdr:$in, 0),
+          (IOHLlo (ILHUhi tglobaladdr:$in), tglobaladdr:$in)>;
+def : Pat<(SPUhi    tjumptable:$in, 0),         (ILHUhi tjumptable:$in)>;
+def : Pat<(SPUlo    tjumptable:$in, 0),         (ILAlo  tjumptable:$in)>;
+def : Pat<(SPUaform tjumptable:$in, 0),         (ILAlsa tjumptable:$in)>;
+def : Pat<(SPUxform tjumptable:$in, 0),
+          (IOHLlo (ILHUhi tjumptable:$in), tjumptable:$in)>;
+def : Pat<(SPUhi    tconstpool:$in , 0),        (ILHUhi tconstpool:$in)>;
+def : Pat<(SPUlo    tconstpool:$in , 0),        (ILAlo  tconstpool:$in)>;
+def : Pat<(SPUaform tconstpool:$in, 0),         (ILAlsa tconstpool:$in)>;
+/* def : Pat<(SPUxform tconstpool:$in, 0),
+          (IOHLlo (ILHUhi tconstpool:$in), tconstpool:$in)>; */
+
 // Instrinsics:
 include "CellSDKIntrinsics.td"

Modified: llvm/trunk/lib/Target/CellSPU/SPUNodes.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUNodes.td?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUNodes.td (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUNodes.td Thu Jan 10 20:53:15 2008
@@ -186,9 +186,15 @@
 // PC-relative address
 def SPUpcrel : SDNode<"SPUISD::PCRelAddr", SDTIntBinOp, []>;
 
+// A-Form local store addresses
+def SPUaform : SDNode<"SPUISD::AFormAddr", SDTIntBinOp, []>;
+
 // D-Form "imm($reg)" addresses
 def SPUdform : SDNode<"SPUISD::DFormAddr", SDTIntBinOp, []>;
 
+// X-Form "$reg($reg)" addresses
+def SPUxform : SDNode<"SPUISD::XFormAddr", SDTIntBinOp, []>;
+
 // SPU 32-bit sign-extension to 64-bits
 def SPUsext32_to_64: SDNode<"SPUISD::SEXT32TO64", SDTIntExtendOp, []>;
 

Modified: llvm/trunk/lib/Target/CellSPU/SPUOperands.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUOperands.td?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUOperands.td (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUOperands.td Thu Jan 10 20:53:15 2008
@@ -140,6 +140,17 @@
   return ((Value & ((1 << 19) - 1)) == Value);
 }]>;
 
+def lo16 : PatLeaf<(imm), [{
+  // hi16 predicate - returns true if the immediate has all zeros in the
+  // low order bits and is a 32-bit constant:
+  if (N->getValueType(0) == MVT::i32) {
+    uint32_t val = N->getValue();
+    return ((val & 0x0000ffff) == val);
+  }
+
+  return false;
+}], LO16>;
+
 def hi16 : PatLeaf<(imm), [{
   // hi16 predicate - returns true if the immediate has all zeros in the
   // low order bits and is a 32-bit constant:
@@ -411,7 +422,11 @@
 //===----------------------------------------------------------------------===//
 // Operand Definitions.
 
-def s7imm: Operand<i16> {
+def s7imm: Operand<i8> {
+  let PrintMethod = "printS7ImmOperand";
+}
+
+def s7imm_i8: Operand<i8> {
   let PrintMethod = "printS7ImmOperand";
 }
 

Modified: llvm/trunk/test/CodeGen/CellSPU/and_ops.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/and_ops.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/and_ops.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/and_ops.ll Thu Jan 10 20:53:15 2008
@@ -4,6 +4,8 @@
 ; RUN: grep andi   %t1.s | count 36
 ; RUN: grep andhi  %t1.s | count 30
 ; RUN: grep andbi  %t1.s | count 4
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 ; AND instruction generation:
 define <4 x i32> @and_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {

Added: llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll?rev=45851&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll (added)
+++ llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll Thu Jan 10 20:53:15 2008
@@ -0,0 +1,29 @@
+; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
+; RUN: grep bisl    %t1.s | count 6 &&
+; RUN: grep ila     %t1.s | count 1 &&
+; RUN: grep rotqbyi %t1.s | count 4 &&
+; RUN: grep lqa     %t1.s | count 4 &&
+; RUN: grep lqd     %t1.s | count 6 &&
+; RUN: grep dispatch_tab %t1.s | count 10
+; ModuleID = 'call_indirect.bc'
+target datalayout = "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-a0:0:128-v128:128:128"
+target triple = "spu-unknown-elf"
+
+ at dispatch_tab = global [6 x void (i32, float)*] zeroinitializer, align 16
+
+define void @dispatcher(i32 %i_arg, float %f_arg) {
+entry:
+	%tmp2 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 0), align 16
+	tail call void %tmp2( i32 %i_arg, float %f_arg )
+	%tmp2.1 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 1), align 4
+	tail call void %tmp2.1( i32 %i_arg, float %f_arg )
+	%tmp2.2 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 2), align 4
+	tail call void %tmp2.2( i32 %i_arg, float %f_arg )
+	%tmp2.3 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 3), align 4
+	tail call void %tmp2.3( i32 %i_arg, float %f_arg )
+	%tmp2.4 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 4), align 4
+	tail call void %tmp2.4( i32 %i_arg, float %f_arg )
+	%tmp2.5 = load void (i32, float)** getelementptr ([6 x void (i32, float)*]* @dispatch_tab, i32 0, i32 5), align 4
+	tail call void %tmp2.5( i32 %i_arg, float %f_arg )
+	ret void
+}

Modified: llvm/trunk/test/CodeGen/CellSPU/ctpop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/ctpop.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/ctpop.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/ctpop.ll Thu Jan 10 20:53:15 2008
@@ -3,6 +3,8 @@
 ; RUN: grep andi    %t1.s | count 3 &&
 ; RUN: grep rotmi   %t1.s | count 2 &&
 ; RUN: grep rothmi  %t1.s | count 1
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 declare i32 @llvm.ctpop.i8(i8)
 declare i32 @llvm.ctpop.i16(i16)

Modified: llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/dp_farith.ll Thu Jan 10 20:53:15 2008
@@ -7,6 +7,8 @@
 ; RUN: grep dfnms  %t1.s | count 4
 ;
 ; This file includes double precision floating point arithmetic instructions
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define double @fadd(double %arg1, double %arg2) {
 	%A = add double %arg1, %arg2

Modified: llvm/trunk/test/CodeGen/CellSPU/eqv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/eqv.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/eqv.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/eqv.ll Thu Jan 10 20:53:15 2008
@@ -10,6 +10,8 @@
 ; Alternatively, a ^ ~b, which the compiler will also match.
 
 ; ModuleID = 'eqv.bc'
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define <4 x i32> @equiv_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {
 	%A = and <4 x i32> %arg1, %arg2		; <<4 x i32>> [#uses=1]

Modified: llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/extract_elt.ll Thu Jan 10 20:53:15 2008
@@ -5,6 +5,8 @@
 ; RUN: grep   lqx %t2.s | count 27 &&
 ; RUN: grep space %t1.s | count 8 &&
 ; RUN: grep  byte %t1.s | count 424
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define i32 @i32_extract_0(<4 x i32> %v) {
 entry:

Modified: llvm/trunk/test/CodeGen/CellSPU/fcmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/fcmp.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/fcmp.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/fcmp.ll Thu Jan 10 20:53:15 2008
@@ -3,6 +3,8 @@
 ; RUN: grep fcmeq %t1.s | count 1
 ;
 ; This file includes standard floating point arithmetic instructions
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 declare double @fabs(double)
 declare float @fabsf(float)

Modified: llvm/trunk/test/CodeGen/CellSPU/fdiv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/fdiv.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/fdiv.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/fdiv.ll Thu Jan 10 20:53:15 2008
@@ -6,6 +6,8 @@
 ; RUN: grep fnms     %t1.s | count 2
 ;
 ; This file includes standard floating point arithmetic instructions
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define float @fdiv32(float %arg1, float %arg2) {
 	%A = fdiv float %arg1,  %arg2

Modified: llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/fneg-fabs.ll Thu Jan 10 20:53:15 2008
@@ -4,6 +4,8 @@
 ; RUN: grep xor     %t1.s | count 4 &&
 ; RUN: grep and     %t1.s | count 5 &&
 ; RUN: grep andbi   %t1.s | count 3
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define double @fneg_dp(double %X) {
 	%Y = sub double -0.000000e+00, %X

Modified: llvm/trunk/test/CodeGen/CellSPU/immed16.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/immed16.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/immed16.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/immed16.ll Thu Jan 10 20:53:15 2008
@@ -1,5 +1,7 @@
 ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
 ; RUN: grep "ilh" %t1.s | count 5
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define i16 @test_1() {
   %x = alloca i16, align 16

Modified: llvm/trunk/test/CodeGen/CellSPU/immed32.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/immed32.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/immed32.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/immed32.ll Thu Jan 10 20:53:15 2008
@@ -12,6 +12,8 @@
 ; RUN: grep 49077 %t1.s | count 1 &&
 ; RUN: grep  1267 %t1.s | count 2 &&
 ; RUN: grep 16309 %t1.s | count 1
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define i32 @test_1() {
   ret i32 4784128		;; ILHU via pattern (0x49000)

Modified: llvm/trunk/test/CodeGen/CellSPU/immed64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/immed64.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/immed64.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/immed64.ll Thu Jan 10 20:53:15 2008
@@ -11,6 +11,9 @@
 ; RUN: grep      128 %t1.s | count 30 &&
 ; RUN: grep      224 %t1.s | count 2
 
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
+
 ;  1311768467750121234 => 0x 12345678 abcdef12 (4660,22136/43981,61202)
 ; 18446744073709551591 => 0x ffffffff ffffffe7 (-25)
 ; 18446744073708516742 => 0x ffffffff fff03586 (-1034874)

Modified: llvm/trunk/test/CodeGen/CellSPU/int2fp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/int2fp.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/int2fp.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/int2fp.ll Thu Jan 10 20:53:15 2008
@@ -7,6 +7,9 @@
 ; RUN: grep andi  %t1.s | count 1 &&
 ; RUN: grep ila   %t1.s | count 1
 
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
+
 define float @sitofp_i32(i32 %arg1) {
 	%A = sitofp i32 %arg1 to float		; <float> [#uses=1]
 	ret float %A

Added: llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll?rev=45851&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll (added)
+++ llvm/trunk/test/CodeGen/CellSPU/intrinsics_branch.ll Thu Jan 10 20:53:15 2008
@@ -0,0 +1,150 @@
+; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
+; RUN: grep ceq     %t1.s | count 30 &&
+; RUN: grep ceqb    %t1.s | count 10 &&
+; RUN: grep ceqhi   %t1.s | count 5 &&
+; RUN: grep ceqi    %t1.s | count 5 &&
+; RUN: grep cgt     %t1.s | count 30 &&
+; RUN: grep cgtb    %t1.s | count 10 &&
+; RUN: grep cgthi   %t1.s | count 5 &&
+; RUN: grep cgti    %t1.s | count 5
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
+
+declare <4 x i32> @llvm.spu.si.shli(<4 x i32>, i8)
+
+declare <4 x i32> @llvm.spu.si.ceq(<4 x i32>, <4 x i32>)
+declare <16 x i8> @llvm.spu.si.ceqb(<16 x i8>, <16 x i8>)
+declare <8 x i16> @llvm.spu.si.ceqh(<8 x i16>, <8 x i16>)
+declare <4 x i32> @llvm.spu.si.ceqi(<4 x i32>, i16)
+declare <8 x i16> @llvm.spu.si.ceqhi(<8 x i16>, i16)
+declare <16 x i8> @llvm.spu.si.ceqbi(<16 x i8>, i8)
+
+declare <4 x i32> @llvm.spu.si.cgt(<4 x i32>, <4 x i32>)
+declare <16 x i8> @llvm.spu.si.cgtb(<16 x i8>, <16 x i8>)
+declare <8 x i16> @llvm.spu.si.cgth(<8 x i16>, <8 x i16>)
+declare <4 x i32> @llvm.spu.si.cgti(<4 x i32>, i16)
+declare <8 x i16> @llvm.spu.si.cgthi(<8 x i16>, i16)
+declare <16 x i8> @llvm.spu.si.cgtbi(<16 x i8>, i8)
+
+declare <4 x i32> @llvm.spu.si.clgt(<4 x i32>, <4 x i32>)
+declare <16 x i8> @llvm.spu.si.clgtb(<16 x i8>, <16 x i8>)
+declare <8 x i16> @llvm.spu.si.clgth(<8 x i16>, <8 x i16>)
+declare <4 x i32> @llvm.spu.si.clgti(<4 x i32>, i16)
+declare <8 x i16> @llvm.spu.si.clgthi(<8 x i16>, i16)
+declare <16 x i8> @llvm.spu.si.clgtbi(<16 x i8>, i8)
+
+
+
+define <4 x i32> @test(<4 x i32> %A) {
+	call <4 x i32> @llvm.spu.si.shli(<4 x i32> %A, i8 3)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <4 x i32> @ceqtest(<4 x i32> %A, <4 x i32> %B) {
+	call <4 x i32> @llvm.spu.si.ceq(<4 x i32> %A, <4 x i32> %B)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <8 x i16> @ceqhtest(<8 x i16> %A, <8 x i16> %B) {
+	call <8 x i16> @llvm.spu.si.ceqh(<8 x i16> %A, <8 x i16> %B)
+	%Y = bitcast <8 x i16> %1 to <8 x i16>
+	ret <8 x i16> %Y
+}
+
+define <16 x i8> @ceqbtest(<16 x i8> %A, <16 x i8> %B) {
+	call <16 x i8> @llvm.spu.si.ceqb(<16 x i8> %A, <16 x i8> %B)
+	%Y = bitcast <16 x i8> %1 to <16 x i8>
+	ret <16 x i8> %Y
+}
+
+define <4 x i32> @ceqitest(<4 x i32> %A) {
+	call <4 x i32> @llvm.spu.si.ceqi(<4 x i32> %A, i16 65)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <8 x i16> @ceqhitest(<8 x i16> %A) {
+	call <8 x i16> @llvm.spu.si.ceqhi(<8 x i16> %A, i16 65)
+	%Y = bitcast <8 x i16> %1 to <8 x i16>
+	ret <8 x i16> %Y
+}
+
+define <16 x i8> @ceqbitest(<16 x i8> %A) {
+	call <16 x i8> @llvm.spu.si.ceqbi(<16 x i8> %A, i8 65)
+	%Y = bitcast <16 x i8> %1 to <16 x i8>
+	ret <16 x i8> %Y
+}
+
+define <4 x i32> @cgttest(<4 x i32> %A, <4 x i32> %B) {
+	call <4 x i32> @llvm.spu.si.cgt(<4 x i32> %A, <4 x i32> %B)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <8 x i16> @cgthtest(<8 x i16> %A, <8 x i16> %B) {
+	call <8 x i16> @llvm.spu.si.cgth(<8 x i16> %A, <8 x i16> %B)
+	%Y = bitcast <8 x i16> %1 to <8 x i16>
+	ret <8 x i16> %Y
+}
+
+define <16 x i8> @cgtbtest(<16 x i8> %A, <16 x i8> %B) {
+	call <16 x i8> @llvm.spu.si.cgtb(<16 x i8> %A, <16 x i8> %B)
+	%Y = bitcast <16 x i8> %1 to <16 x i8>
+	ret <16 x i8> %Y
+}
+
+define <4 x i32> @cgtitest(<4 x i32> %A) {
+	call <4 x i32> @llvm.spu.si.cgti(<4 x i32> %A, i16 65)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <8 x i16> @cgthitest(<8 x i16> %A) {
+	call <8 x i16> @llvm.spu.si.cgthi(<8 x i16> %A, i16 65)
+	%Y = bitcast <8 x i16> %1 to <8 x i16>
+	ret <8 x i16> %Y
+}
+
+define <16 x i8> @cgtbitest(<16 x i8> %A) {
+	call <16 x i8> @llvm.spu.si.cgtbi(<16 x i8> %A, i8 65)
+	%Y = bitcast <16 x i8> %1 to <16 x i8>
+	ret <16 x i8> %Y
+}
+
+define <4 x i32> @clgttest(<4 x i32> %A, <4 x i32> %B) {
+	call <4 x i32> @llvm.spu.si.clgt(<4 x i32> %A, <4 x i32> %B)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <8 x i16> @clgthtest(<8 x i16> %A, <8 x i16> %B) {
+	call <8 x i16> @llvm.spu.si.clgth(<8 x i16> %A, <8 x i16> %B)
+	%Y = bitcast <8 x i16> %1 to <8 x i16>
+	ret <8 x i16> %Y
+}
+
+define <16 x i8> @clgtbtest(<16 x i8> %A, <16 x i8> %B) {
+	call <16 x i8> @llvm.spu.si.clgtb(<16 x i8> %A, <16 x i8> %B)
+	%Y = bitcast <16 x i8> %1 to <16 x i8>
+	ret <16 x i8> %Y
+}
+
+define <4 x i32> @clgtitest(<4 x i32> %A) {
+	call <4 x i32> @llvm.spu.si.clgti(<4 x i32> %A, i16 65)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <8 x i16> @clgthitest(<8 x i16> %A) {
+	call <8 x i16> @llvm.spu.si.clgthi(<8 x i16> %A, i16 65)
+	%Y = bitcast <8 x i16> %1 to <8 x i16>
+	ret <8 x i16> %Y
+}
+
+define <16 x i8> @clgtbitest(<16 x i8> %A) {
+	call <16 x i8> @llvm.spu.si.clgtbi(<16 x i8> %A, i8 65)
+	%Y = bitcast <16 x i8> %1 to <16 x i8>
+	ret <16 x i8> %Y
+}

Added: llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll?rev=45851&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll (added)
+++ llvm/trunk/test/CodeGen/CellSPU/intrinsics_float.ll Thu Jan 10 20:53:15 2008
@@ -0,0 +1,94 @@
+; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
+; RUN: grep fa      %t1.s | count 5 &&
+; RUN: grep fs      %t1.s | count 5 &&
+; RUN: grep fm      %t1.s | count 15 &&
+; RUN: grep fceq    %t1.s | count 5 &&
+; RUN: grep fcmeq   %t1.s | count 5 &&
+; RUN: grep fcgt    %t1.s | count 5 &&
+; RUN: grep fcmgt   %t1.s | count 5 &&
+; RUN: grep fma     %t1.s | count 5 &&
+; RUN: grep fnms    %t1.s | count 5 &&
+; RUN: grep fms     %t1.s | count 5
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
+
+declare <4 x i32> @llvm.spu.si.shli(<4 x i32>, i8)
+
+declare <4 x float> @llvm.spu.si.fa(<4 x float>, <4 x float>)
+declare <4 x float> @llvm.spu.si.fs(<4 x float>, <4 x float>)
+declare <4 x float> @llvm.spu.si.fm(<4 x float>, <4 x float>)
+
+declare <4 x float> @llvm.spu.si.fceq(<4 x float>, <4 x float>)
+declare <4 x float> @llvm.spu.si.fcmeq(<4 x float>, <4 x float>)
+declare <4 x float> @llvm.spu.si.fcgt(<4 x float>, <4 x float>)
+declare <4 x float> @llvm.spu.si.fcmgt(<4 x float>, <4 x float>)
+
+declare <4 x float> @llvm.spu.si.fma(<4 x float>, <4 x float>, <4 x float>)
+declare <4 x float> @llvm.spu.si.fnms(<4 x float>, <4 x float>, <4 x float>)
+declare <4 x float> @llvm.spu.si.fms(<4 x float>, <4 x float>, <4 x float>)
+
+define <4 x i32> @test(<4 x i32> %A) {
+	call <4 x i32> @llvm.spu.si.shli(<4 x i32> %A, i8 3)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <4 x float> @fatest(<4 x float> %A, <4 x float> %B) {
+	call <4 x float> @llvm.spu.si.fa(<4 x float> %A, <4 x float> %B)
+	%Y = bitcast <4 x float> %1 to <4 x float>
+	ret <4 x float> %Y
+}
+
+define <4 x float> @fstest(<4 x float> %A, <4 x float> %B) {
+        call <4 x float> @llvm.spu.si.fs(<4 x float> %A, <4 x float> %B)
+        %Y = bitcast <4 x float> %1 to <4 x float>
+        ret <4 x float> %Y
+}
+
+define <4 x float> @fmtest(<4 x float> %A, <4 x float> %B) {
+	call <4 x float> @llvm.spu.si.fm(<4 x float> %A, <4 x float> %B)
+	%Y = bitcast <4 x float> %1 to <4 x float>
+	ret <4 x float> %Y
+}
+
+define <4 x float> @fceqtest(<4 x float> %A, <4 x float> %B) {
+	call <4 x float> @llvm.spu.si.fceq(<4 x float> %A, <4 x float> %B)
+	%Y = bitcast <4 x float> %1 to <4 x float>
+	ret <4 x float> %Y
+}
+
+define <4 x float> @fcmeqtest(<4 x float> %A, <4 x float> %B) {
+	call <4 x float> @llvm.spu.si.fcmeq(<4 x float> %A, <4 x float> %B)
+	%Y = bitcast <4 x float> %1 to <4 x float>
+	ret <4 x float> %Y
+}
+
+define <4 x float> @fcgttest(<4 x float> %A, <4 x float> %B) {
+	call <4 x float> @llvm.spu.si.fcgt(<4 x float> %A, <4 x float> %B)
+	%Y = bitcast <4 x float> %1 to <4 x float>
+	ret <4 x float> %Y
+}
+
+define <4 x float> @fcmgttest(<4 x float> %A, <4 x float> %B) {
+	call <4 x float> @llvm.spu.si.fcmgt(<4 x float> %A, <4 x float> %B)
+	%Y = bitcast <4 x float> %1 to <4 x float>
+	ret <4 x float> %Y
+}
+
+define <4 x float> @fmatest(<4 x float> %A, <4 x float> %B, <4 x float> %C) {
+	call <4 x float> @llvm.spu.si.fma(<4 x float> %A, <4 x float> %B, <4 x float> %C)
+	%Y = bitcast <4 x float> %1 to <4 x float>
+	ret <4 x float> %Y
+}
+
+define <4 x float> @fnmstest(<4 x float> %A, <4 x float> %B, <4 x float> %C) {
+	call <4 x float> @llvm.spu.si.fnms(<4 x float> %A, <4 x float> %B, <4 x float> %C)
+	%Y = bitcast <4 x float> %1 to <4 x float>
+	ret <4 x float> %Y
+}
+
+define <4 x float> @fmstest(<4 x float> %A, <4 x float> %B, <4 x float> %C) {
+	call <4 x float> @llvm.spu.si.fms(<4 x float> %A, <4 x float> %B, <4 x float> %C)
+	%Y = bitcast <4 x float> %1 to <4 x float>
+	ret <4 x float> %Y
+}
\ No newline at end of file

Added: llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll?rev=45851&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll (added)
+++ llvm/trunk/test/CodeGen/CellSPU/intrinsics_logical.ll Thu Jan 10 20:53:15 2008
@@ -0,0 +1,49 @@
+; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
+; RUN: grep and       %t1.s | count 20 &&
+; RUN: grep andc      %t1.s | count 5
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
+
+declare <4 x i32> @llvm.spu.si.and(<4 x i32>, <4 x i32>)
+declare <4 x i32> @llvm.spu.si.andc(<4 x i32>, <4 x i32>)
+declare <4 x i32> @llvm.spu.si.andi(<4 x i32>, i16)
+declare <8 x i16> @llvm.spu.si.andhi(<8 x i16>, i16)
+declare <16 x i8> @llvm.spu.si.andbi(<16 x i8>, i8)
+
+declare <4 x i32> @llvm.spu.si.or(<4 x i32>, <4 x i32>)
+declare <4 x i32> @llvm.spu.si.orc(<4 x i32>, <4 x i32>)
+declare <4 x i32> @llvm.spu.si.ori(<4 x i32>, i16)
+declare <8 x i16> @llvm.spu.si.orhi(<8 x i16>, i16)
+declare <16 x i8> @llvm.spu.si.orbi(<16 x i8>, i8)
+
+declare <4 x i32> @llvm.spu.si.xor(<4 x i32>, <4 x i32>)
+declare <4 x i32> @llvm.spu.si.xori(<4 x i32>, i16)
+declare <8 x i16> @llvm.spu.si.xorhi(<8 x i16>, i16)
+declare <16 x i8> @llvm.spu.si.xorbi(<16 x i8>, i8)
+
+declare <4 x i32> @llvm.spu.si.nand(<4 x i32>, <4 x i32>)
+declare <4 x i32> @llvm.spu.si.nor(<4 x i32>, <4 x i32>)
+
+define <4 x i32> @andtest(<4 x i32> %A, <4 x i32> %B) {
+	call <4 x i32> @llvm.spu.si.and(<4 x i32> %A, <4 x i32> %B)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <4 x i32> @andctest(<4 x i32> %A, <4 x i32> %B) {
+        call <4 x i32> @llvm.spu.si.andc(<4 x i32> %A, <4 x i32> %B)
+        %Y = bitcast <4 x i32> %1 to <4 x i32>
+        ret <4 x i32> %Y
+}
+
+define <4 x i32> @anditest(<4 x i32> %A) {
+	call <4 x i32> @llvm.spu.si.andi(<4 x i32> %A, i16 65)
+	%Y = bitcast <4 x i32> %1 to <4 x i32>
+	ret <4 x i32> %Y
+}
+
+define <8 x i16> @andhitest(<8 x i16> %A) {
+	call <8 x i16> @llvm.spu.si.andhi(<8 x i16> %A, i16 65)
+	%Y = bitcast <8 x i16> %1 to <8 x i16>
+	ret <8 x i16> %Y
+}

Modified: llvm/trunk/test/CodeGen/CellSPU/nand.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/nand.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/nand.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/nand.ll Thu Jan 10 20:53:15 2008
@@ -3,6 +3,8 @@
 ; RUN: grep and    %t1.s | count 94
 ; RUN: grep xsbh   %t1.s | count 2
 ; RUN: grep xshw   %t1.s | count 4
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define <4 x i32> @nand_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {
         %A = and <4 x i32> %arg2, %arg1      ; <<4 x i32>> [#uses=1]

Modified: llvm/trunk/test/CodeGen/CellSPU/or_ops.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/or_ops.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/or_ops.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/or_ops.ll Thu Jan 10 20:53:15 2008
@@ -4,6 +4,8 @@
 ; RUN: grep ori    %t1.s | count 30
 ; RUN: grep orhi   %t1.s | count 30
 ; RUN: grep orbi   %t1.s | count 15
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 ; OR instruction generation:
 define <4 x i32> @or_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {

Modified: llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/rotate_ops.ll Thu Jan 10 20:53:15 2008
@@ -8,6 +8,8 @@
 ; RUN grep rothi.*,.3    %t1.s | count 1
 ; RUN: grep andhi        %t1.s | count 4
 ; RUN: grep shlhi        %t1.s | count 4
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 ; Vector rotates are not currently supported in gcc or llvm assembly. These are
 ; not tested.

Modified: llvm/trunk/test/CodeGen/CellSPU/select_bits.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/select_bits.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/select_bits.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/select_bits.ll Thu Jan 10 20:53:15 2008
@@ -3,6 +3,8 @@
 ; RUN: grep and    %t1.s | count 2
 ; RUN: grep xsbh   %t1.s | count 1
 ; RUN: grep xshw   %t1.s | count 2
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define <16 x i8> @selb_v16i8_1(<16 x i8> %arg1, <16 x i8> %arg2, <16 x i8> %arg3) {
 	%A = xor <16 x i8> %arg3, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,

Modified: llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/shift_ops.ll Thu Jan 10 20:53:15 2008
@@ -5,6 +5,8 @@
 ; RUN: grep shli   %t1.s | count 51
 ; RUN: grep xshw   %t1.s | count 5
 ; RUN: grep and    %t1.s | count 5
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 ; Vector shifts are not currently supported in gcc or llvm assembly. These are
 ; not tested.

Modified: llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll?rev=45851&r1=45850&r2=45851&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/sp_farith.ll Thu Jan 10 20:53:15 2008
@@ -8,6 +8,8 @@
 ;
 ; This file includes standard floating point arithmetic instructions
 ; NOTE fdiv is tested separately since it is a compound operation
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
 
 define float @fp_add(float %arg1, float %arg2) {
 	%A = add float %arg1, %arg2 	; <float> [#uses=1]

Added: llvm/trunk/test/CodeGen/CellSPU/struct_1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/struct_1.ll?rev=45851&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/struct_1.ll (added)
+++ llvm/trunk/test/CodeGen/CellSPU/struct_1.ll Thu Jan 10 20:53:15 2008
@@ -0,0 +1,107 @@
+; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
+; RUN: grep lqa     %t1.s | count 10 &&
+; RUN: grep lqd     %t1.s | count 2 &&
+; RUN: grep rotqbyi %t1.s | count 5 &&
+; RUN: grep xshw    %t1.s | count 1 &&
+; RUN: grep andi    %t1.s | count 4 &&
+; RUN: grep cbd     %t1.s | count 3 &&
+; RUN: grep chd     %t1.s | count 1 &&
+; RUN: grep cwd     %t1.s | count 1 &&
+; RUN: grep shufb   %t1.s | count 5 &&
+; RUN: grep stqa    %t1.s | count 5
+; ModuleID = 'struct_1.bc'
+target datalayout = "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-a0:0:128-v128:128:128-s0:128:128"
+target triple = "spu"
+
+; struct hackstate {
+;   unsigned char c1;   // offset 0 (rotate left by 13 bytes to byte 3)
+;   unsigned char c2;   // offset 1 (rotate left by 14 bytes to byte 3)
+;   unsigned char c3;   // offset 2 (rotate left by 15 bytes to byte 3)
+;   int           i1;   // offset 4 (rotate left by 4 bytes to byte 0)
+;   short         s1;   // offset 8 (rotate left by 6 bytes to byte 2)
+;   int           i2;   // offset 12 [ignored]
+;   unsigned char c4;   // offset 16 [ignored]
+;   unsigned char c5;   // offset 17 [ignored]
+;   unsigned char c6;   // offset 18 [ignored]
+;   unsigned char c7;   // offset 19 (no rotate, in preferred slot)
+;   int           i3;   // offset 20 [ignored]
+;   int           i4;   // offset 24 [ignored]
+;   int           i5;   // offset 28 [ignored]
+;   int           i6;   // offset 32 (no rotate, in preferred slot)
+; }
+%struct.hackstate = type { i8, i8, i8, i32, i16, i32, i8, i8, i8, i8, i32, i32, i32, i32 }
+
+; struct hackstate state = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ at state = global %struct.hackstate zeroinitializer, align 16
+
+define i8 @get_hackstate_c1() zeroext  {
+entry:
+        %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 0), align 16
+        ret i8 %tmp2
+}
+
+define i8 @get_hackstate_c2() zeroext  {
+entry:
+        %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 1), align 16
+        ret i8 %tmp2
+}
+
+define i8 @get_hackstate_c3() zeroext  {
+entry:
+        %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 2), align 16
+        ret i8 %tmp2
+}
+
+define i32 @get_hackstate_i1() {
+entry:
+        %tmp2 = load i32* getelementptr (%struct.hackstate* @state, i32 0, i32 3), align 16
+        ret i32 %tmp2
+}
+
+define i16 @get_hackstate_s1() signext  {
+entry:
+        %tmp2 = load i16* getelementptr (%struct.hackstate* @state, i32 0, i32 4), align 16
+        ret i16 %tmp2
+}
+
+define i8 @get_hackstate_c7() zeroext  {
+entry:
+        %tmp2 = load i8* getelementptr (%struct.hackstate* @state, i32 0, i32 9), align 16
+        ret i8 %tmp2
+}
+
+define i32 @get_hackstate_i6() zeroext  {
+entry:
+        %tmp2 = load i32* getelementptr (%struct.hackstate* @state, i32 0, i32 13), align 16
+        ret i32 %tmp2
+}
+
+define void @set_hackstate_c1(i8 zeroext  %c) {
+entry:
+        store i8 %c, i8* getelementptr (%struct.hackstate* @state, i32 0, i32 0), align 16
+        ret void
+}
+
+define void @set_hackstate_c2(i8 zeroext  %c) {
+entry:
+        store i8 %c, i8* getelementptr (%struct.hackstate* @state, i32 0, i32 1), align 16
+        ret void
+}
+
+define void @set_hackstate_c3(i8 zeroext  %c) {
+entry:
+        store i8 %c, i8* getelementptr (%struct.hackstate* @state, i32 0, i32 2), align 16
+        ret void
+}
+
+define void @set_hackstate_i1(i32 %i) {
+entry:
+        store i32 %i, i32* getelementptr (%struct.hackstate* @state, i32 0, i32 3), align 16
+        ret void
+}
+
+define void @set_hackstate_s1(i16 signext  %s) {
+entry:
+        store i16 %s, i16* getelementptr (%struct.hackstate* @state, i32 0, i32 4), align 16
+        ret void
+}





More information about the llvm-commits mailing list