Sunil_Srivastava created this revision.
Sunil_Srivastava added reviewers: rjmccall, DmitryPolukhin, rsmith, probinson.
Sunil_Srivastava added a subscriber: cfe-commits.

This is the round 2 of the PS4 ABI. In this round:

1) A new value PS4 has been added to TargetCXXABI::Kind. It is being used for 
x86_64-scei-ps4 triple only.
2) RecordLayoutBuilder.cpp has been logically reverted back to pre r257462 
behavior for PS4 abi.
3) The test Sema/bitfield-layout.c has been enhanced by adding the PS4 triple, 
and few test entries that differ between PS4 and other triples, have been put 
under '#ifdef PS4'. Logically, the test has not changed for triples other than 
x86_64-scei-ps4. For x86_64-scei-ps4 triple, the test matches pre r257462 
behavior.

The test passes on all listed triples on x86 Linux and windows hosts.

http://reviews.llvm.org/D16788

Files:
  include/clang/Basic/TargetCXXABI.h
  lib/AST/ASTContext.cpp
  lib/AST/RecordLayoutBuilder.cpp
  lib/Basic/Targets.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  test/Sema/bitfield-layout.c

Index: test/Sema/bitfield-layout.c
===================================================================
--- test/Sema/bitfield-layout.c
+++ test/Sema/bitfield-layout.c
@@ -2,6 +2,7 @@
 // RUN: %clang_cc1 %s -fsyntax-only -verify -triple=arm-linux-gnueabihf
 // RUN: %clang_cc1 %s -fsyntax-only -verify -triple=aarch64-linux-gnu
 // RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-pc-linux-gnu
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-scei-ps4
 // expected-no-diagnostics
 #include <stddef.h>
 
@@ -96,9 +97,15 @@
   char c;
 };
 
+#if defined(__PS4__)
+CHECK_SIZE(struct, g0, 16);
+CHECK_ALIGN(struct, g0, 16);
+CHECK_OFFSET(struct, g0, c, 2);
+#else
 CHECK_SIZE(struct, g0, 32);
 CHECK_ALIGN(struct, g0, 16);
 CHECK_OFFSET(struct, g0, c, 17);
+#endif
 
 // Bit-field with explicit align smaller than normal.
 struct g1 {
@@ -109,7 +116,11 @@
 
 CHECK_SIZE(struct, g1, 4);
 CHECK_ALIGN(struct, g1, 4);
+#if defined(__PS4__)
+CHECK_OFFSET(struct, g1, c, 2);
+#else
 CHECK_OFFSET(struct, g1, c, 3);
+#endif
 
 // Same as above but without explicit align.
 struct g2 {
@@ -130,9 +141,14 @@
   char c;
 };
 
-CHECK_SIZE(struct, g3, 32);
 CHECK_ALIGN(struct, g3, 16);
+#if defined(__PS4__)
+CHECK_SIZE(struct, g3, 16);
+CHECK_OFFSET(struct, g3, c, 2);
+#else
+CHECK_SIZE(struct, g3, 32);
 CHECK_OFFSET(struct, g3, c, 17);
+#endif
 
 struct __attribute__((packed)) g4 {
   char a;
@@ -142,7 +158,11 @@
 
 CHECK_SIZE(struct, g4, 4);
 CHECK_ALIGN(struct, g4, 2);
+#if defined(__PS4__)
+CHECK_OFFSET(struct, g4, c, 2);
+#else
 CHECK_OFFSET(struct, g4, c, 3);
+#endif
 
 struct g5 {
   char : 1;
@@ -162,28 +182,44 @@
   char : 1;
   __attribute__((aligned(1))) int n : 25;
 };
+#if defined(__PS4__)
+CHECK_SIZE(struct, g7, 4);
+#else
 CHECK_SIZE(struct, g7, 8);
+#endif
 CHECK_ALIGN(struct, g7, 4);
 
 struct __attribute__((packed)) g8 {
   char : 1;
   __attribute__((aligned(1))) int n : 25;
 };
+#if defined(__PS4__)
+CHECK_SIZE(struct, g8, 4);
+#else
 CHECK_SIZE(struct, g8, 5);
+#endif
 CHECK_ALIGN(struct, g8, 1);
 
 struct g9 {
   __attribute__((aligned(1))) char a : 2, b : 2, c : 2, d : 2, e : 2;
   int i;
 };
+#if defined(__PS4__)
+CHECK_SIZE(struct, g9, 8);
+#else
 CHECK_SIZE(struct, g9, 12);
+#endif
 CHECK_ALIGN(struct, g9, 4);
 
 struct __attribute__((packed)) g10 {
   __attribute__((aligned(1))) char a : 2, b : 2, c : 2, d : 2, e : 2;
   int i;
 };
+#if defined(__PS4__)
+CHECK_SIZE(struct, g10, 6);
+#else
 CHECK_SIZE(struct, g10, 9);
+#endif
 CHECK_ALIGN(struct, g10, 1);
 
 struct g11 {
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -480,6 +480,7 @@
     return new WebAssemblyCXXABI(CGM);
 
   case TargetCXXABI::GenericItanium:
+  case TargetCXXABI::PS4:
     if (CGM.getContext().getTargetInfo().getTriple().getArch()
         == llvm::Triple::le32) {
       // For PNaCl, use ARM-style method pointers so that PNaCl code
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -69,6 +69,7 @@
   case TargetCXXABI::WatchOS:
   case TargetCXXABI::GenericMIPS:
   case TargetCXXABI::GenericItanium:
+  case TargetCXXABI::PS4:
   case TargetCXXABI::WebAssembly:
     return CreateItaniumCXXABI(CGM);
   case TargetCXXABI::Microsoft:
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -602,6 +602,9 @@
   PS4OSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
     this->WCharType = this->UnsignedShort;
 
+    // PS4 uses a variant of the C++11 ABI.
+    this->TheCXXABI.set(TargetCXXABI::PS4);
+
     // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits).
     this->MaxTLSAlign = 256;
     this->UserLabelPrefix = "";
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1595,12 +1595,15 @@
     // #pragma pack, with any value, suppresses the insertion of padding.
     bool AllowPadding = MaxFieldAlignment.isZero();
 
+    // PS4 remains compatible to pre r257462 behavior.
+    bool isPS4ABI = (Context.getTargetInfo().getCXXABI().getKind() == TargetCXXABI::PS4);
+
     // Compute the real offset.
     if (FieldSize == 0 || 
         (AllowPadding &&
          (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)) {
       FieldOffset = llvm::alignTo(FieldOffset, FieldAlign);
-    } else if (ExplicitFieldAlign) {
+    } else if (ExplicitFieldAlign && !isPS4ABI) {
       // TODO: figure it out what needs to be done on targets that don't honor
       // bit-field type alignment like ARM APCS ABI.
       FieldOffset = llvm::alignTo(FieldOffset, ExplicitFieldAlign);
@@ -1612,7 +1615,7 @@
          (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize))
       UnpackedFieldOffset =
           llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign);
-    else if (ExplicitFieldAlign)
+    else if (ExplicitFieldAlign && !isPS4ABI)
       UnpackedFieldOffset =
           llvm::alignTo(UnpackedFieldOffset, ExplicitFieldAlign);
   }
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -686,6 +686,7 @@
   case TargetCXXABI::GenericAArch64:
   case TargetCXXABI::GenericMIPS:
   case TargetCXXABI::GenericItanium:
+  case TargetCXXABI::PS4:
   case TargetCXXABI::WebAssembly:
     return CreateItaniumCXXABI(*this);
   case TargetCXXABI::Microsoft:
@@ -8573,6 +8574,7 @@
   case TargetCXXABI::GenericMIPS:
   case TargetCXXABI::iOS:
   case TargetCXXABI::iOS64:
+  case TargetCXXABI::PS4:
   case TargetCXXABI::WebAssembly:
   case TargetCXXABI::WatchOS:
     return ItaniumMangleContext::create(*this, getDiagnostics());
Index: include/clang/Basic/TargetCXXABI.h
===================================================================
--- include/clang/Basic/TargetCXXABI.h
+++ include/clang/Basic/TargetCXXABI.h
@@ -111,7 +111,11 @@
     /// FIXME: should this be split into Win32 and Win64 variants?
     ///
     /// Only scattered and incomplete official documentation exists.
-    Microsoft
+    Microsoft,
+
+    /// The PS4 ABI is basically GenericItaniumABI, as it was implemented
+    /// in LLVM 3.2.
+    PS4
   };
 
 private:
@@ -143,6 +147,7 @@
     case WatchOS:
     case GenericMIPS:
     case WebAssembly:
+    case PS4:
       return true;
 
     case Microsoft:
@@ -162,6 +167,7 @@
     case WatchOS:
     case GenericMIPS:
     case WebAssembly:
+    case PS4:
       return false;
 
     case Microsoft:
@@ -195,6 +201,7 @@
     case iOS64:
     case WatchOS:
     case Microsoft:
+    case PS4:
       return true;
     }
     llvm_unreachable("bad ABI kind");
@@ -277,6 +284,7 @@
     case iOS:   // old iOS compilers did not follow this rule
     case Microsoft:
     case GenericMIPS:
+    case PS4:
       return true;
     }
     llvm_unreachable("bad ABI kind");
@@ -323,6 +331,7 @@
     case GenericARM:
     case iOS:
     case GenericMIPS:
+    case PS4:
       return UseTailPaddingUnlessPOD03;
 
     // iOS on ARM64 and WebAssembly use the C++11 POD rules.  They do not honor
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to