R600: Use the GPU type to determine the correct DataLayout v2

v2:
  - Add R600_DOUBLE_OPS for RV670
  - s/CPU/GPU/

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176440 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 24a69ee..c63ccce 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -1373,16 +1373,50 @@
   3     // cuda_shared
 };
 
+static const char *DescriptionStringR600 =
+  "e"
+  "-p:32:32:32"
+  "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32"
+  "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
+  "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
+  "-n32:64";
+
+static const char *DescriptionStringR600DoubleOps =
+  "e"
+  "-p:32:32:32"
+  "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64"
+  "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
+  "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
+  "-n32:64";
+
+static const char *DescriptionStringSI =
+  "e"
+  "-p:64:64:64"
+  "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64"
+  "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
+  "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
+  "-n32:64";
+
 class R600TargetInfo : public TargetInfo {
+  /// \brief The GPU profiles supported by the R600 target.
+  enum GPUKind {
+    GK_NONE,
+    GK_R600,
+    GK_R600_DOUBLE_OPS,
+    GK_R700,
+    GK_R700_DOUBLE_OPS,
+    GK_EVERGREEN,
+    GK_EVERGREEN_DOUBLE_OPS,
+    GK_NORTHERN_ISLANDS,
+    GK_CAYMAN,
+    GK_SOUTHERN_ISLANDS
+  } GPU;
+
 public:
-  R600TargetInfo(const std::string& triple) : TargetInfo(triple) {
-    DescriptionString =
-          "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16"
-          "-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:32:32"
-          "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64"
-          "-v96:128:128-v128:128:128-v192:256:256-v256:256:256"
-          "-v512:512:512-v1024:1024:1024-v2048:2048:2048"
-          "-n8:16:32:64";
+  R600TargetInfo(const std::string& triple)
+    : TargetInfo(triple),
+      GPU(GK_R600) {
+    DescriptionString = DescriptionStringR600;
     AddrSpaceMap = &R600AddrSpaceMap;
   }
 
@@ -1423,6 +1457,65 @@
     return TargetInfo::CharPtrBuiltinVaList;
   }
 
+  virtual bool setCPU(const std::string &Name) {
+    GPU = llvm::StringSwitch<GPUKind>(Name)
+      .Case("r600" ,    GK_R600)
+      .Case("rv610",    GK_R600)
+      .Case("rv620",    GK_R600)
+      .Case("rv630",    GK_R600)
+      .Case("rv635",    GK_R600)
+      .Case("rs780",    GK_R600)
+      .Case("rs880",    GK_R600)
+      .Case("rv670",    GK_R600_DOUBLE_OPS)
+      .Case("rv710",    GK_R700)
+      .Case("rv730",    GK_R700)
+      .Case("rv740",    GK_R700_DOUBLE_OPS)
+      .Case("rv770",    GK_R700_DOUBLE_OPS)
+      .Case("palm",     GK_EVERGREEN)
+      .Case("cedar",    GK_EVERGREEN)
+      .Case("sumo",     GK_EVERGREEN)
+      .Case("sumo2",    GK_EVERGREEN)
+      .Case("redwood",  GK_EVERGREEN)
+      .Case("juniper",  GK_EVERGREEN)
+      .Case("hemlock",  GK_EVERGREEN_DOUBLE_OPS)
+      .Case("cypress",  GK_EVERGREEN_DOUBLE_OPS)
+      .Case("barts",    GK_NORTHERN_ISLANDS)
+      .Case("turks",    GK_NORTHERN_ISLANDS)
+      .Case("caicos",   GK_NORTHERN_ISLANDS)
+      .Case("cayman",   GK_CAYMAN)
+      .Case("aruba",    GK_CAYMAN)
+      .Case("SI",       GK_SOUTHERN_ISLANDS)
+      .Case("pitcairn", GK_SOUTHERN_ISLANDS)
+      .Case("verde",    GK_SOUTHERN_ISLANDS)
+      .Case("oland",    GK_SOUTHERN_ISLANDS)
+      .Default(GK_NONE);
+
+    if (GPU == GK_NONE) {
+      return false;
+    }
+
+    // Set the correct data layout
+    switch (GPU) {
+    case GK_NONE:
+    case GK_R600:
+    case GK_R700:
+    case GK_EVERGREEN:
+    case GK_NORTHERN_ISLANDS:
+      DescriptionString = DescriptionStringR600;
+      break;
+    case GK_R600_DOUBLE_OPS:
+    case GK_R700_DOUBLE_OPS:
+    case GK_EVERGREEN_DOUBLE_OPS:
+    case GK_CAYMAN:
+      DescriptionString = DescriptionStringR600DoubleOps;
+      break;
+    case GK_SOUTHERN_ISLANDS:
+      DescriptionString = DescriptionStringSI;
+      break;
+    }
+
+    return true;
+  }
 };
 
 } // end anonymous namespace