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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits