diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -46,7 +46,17 @@ LongDoubleFormat = &llvm::APFloat::IEEEquad(); DefaultAlignForAttributeAligned = 64; MinGlobalAlign = 16; - resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); + if (Triple.isOSzOS()) { + // All vector types are default aligned on an 8-byte boundary, even if the + // vector facility is not available. That is different from Linux. + MaxVectorAlign = 64; + // Compared to Linux/ELF, the data layout differs only in some details: + // - name mangling is GOFF + // - 128 bit vector types are 64 bit aligned + resetDataLayout( + "E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"); + } else + resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; HasStrictFP = true; } @@ -129,7 +139,7 @@ HasVector &= !SoftFloat; // If we use the vector ABI, vector types are 64-bit aligned. - if (HasVector) { + if (HasVector && !getTriple().isOSzOS()) { MaxVectorAlign = 64; resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" "-v128:64-a:8:16-n32:64"); diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c --- a/clang/test/CodeGen/target-data.c +++ b/clang/test/CodeGen/target-data.c @@ -253,6 +253,40 @@ // RUN: FileCheck %s -check-prefix=SYSTEMZ-VECTOR // SYSTEMZ-VECTOR: target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64" +// RUN: %clang_cc1 -triple s390x-none-zos -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu z10 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu arch8 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu z196 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu arch9 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu zEC12 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu arch10 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu z13 -target-feature +soft-float -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS +// ZOS: target datalayout = "E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64" + +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu z13 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS-VECTOR +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu arch11 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS-VECTOR +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu z14 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS-VECTOR +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu arch12 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS-VECTOR +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu z15 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS-VECTOR +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu arch13 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS-VECTOR +// RUN: %clang_cc1 -triple s390x-none-zos -target-cpu arch14 -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=ZOS +// ZOS-VECTOR: target datalayout = "E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64" + // RUN: %clang_cc1 -triple msp430-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=MSP430 // MSP430: target datalayout = "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16" diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -2593,6 +2593,7 @@ options are * ``e``: ELF mangling: Private symbols get a ``.L`` prefix. + * ``l``: GOFF mangling: Private symbols get a ``.L`` prefix. * ``m``: Mips mangling: Private symbols get a ``$`` prefix. * ``o``: Mach-O mangling: Private symbols get ``L`` prefix. Other symbols get a ``_`` prefix. diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -135,6 +135,7 @@ MM_MachO, MM_WinCOFF, MM_WinCOFFX86, + MM_GOFF, MM_Mips, MM_XCOFF }; @@ -316,6 +317,7 @@ switch (ManglingMode) { case MM_None: case MM_ELF: + case MM_GOFF: case MM_Mips: case MM_WinCOFF: case MM_XCOFF: @@ -332,6 +334,7 @@ case MM_None: return ""; case MM_ELF: + case MM_GOFF: case MM_WinCOFF: return ".L"; case MM_Mips: diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -151,6 +151,8 @@ //===----------------------------------------------------------------------===// const char *DataLayout::getManglingComponent(const Triple &T) { + if (T.isOSBinFormatGOFF()) + return "-m:l"; if (T.isOSBinFormatMachO()) return "-m:o"; if (T.isOSWindows() && T.isOSBinFormatCOFF()) @@ -500,6 +502,9 @@ case 'e': ManglingMode = MM_ELF; break; + case 'l': + ManglingMode = MM_GOFF; + break; case 'o': ManglingMode = MM_MachO; break; diff --git a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp --- a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp +++ b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -84,8 +84,9 @@ // 128-bit floats are aligned only to 64 bits. Ret += "-f128:64"; - // When using the vector ABI, 128-bit vectors are also aligned to 64 bits. - if (VectorABI) + // When using the vector ABI on Linux, 128-bit vectors are also aligned to 64 + // bits. On z/OS, vector types are always aligned to 64 bits. + if (VectorABI || TT.isOSzOS()) Ret += "-v128:64"; // We prefer 16 bits of aligned for all globals; see above. diff --git a/llvm/unittests/IR/ManglerTest.cpp b/llvm/unittests/IR/ManglerTest.cpp --- a/llvm/unittests/IR/ManglerTest.cpp +++ b/llvm/unittests/IR/ManglerTest.cpp @@ -156,4 +156,22 @@ "L..foo"); } +TEST(ManglerTest, GOFF) { + LLVMContext Ctx; + DataLayout DL("m:l"); // GOFF + Module Mod("test", Ctx); + Mod.setDataLayout(DL); + Mangler Mang; + + EXPECT_EQ(mangleStr("foo", Mang, DL), "foo"); + EXPECT_EQ(mangleStr("\01foo", Mang, DL), "foo"); + EXPECT_EQ(mangleStr("?foo", Mang, DL), "?foo"); + EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::ExternalLinkage, + llvm::CallingConv::C, Mod, Mang), + "foo"); + EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage, + llvm::CallingConv::C, Mod, Mang), + ".Lfoo"); +} + } // end anonymous namespace