Skip to content

Commit 0246fe8

Browse files
committed
__ptr32 support for z/OS
1 parent 8bfa089 commit 0246fe8

17 files changed

+785
-10
lines changed

clang/include/clang/Basic/LangOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ LANGOPT(C2y , 1, 0, "C2y")
9191
LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode")
9292
LANGOPT(Kernel , 1, 0, "Kernel mode")
9393
LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions")
94+
LANGOPT(ZOSExt , 1, 0, "z/OS extensions")
9495
LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
9596
LANGOPT(Borland , 1, 0, "Borland extensions")
9697
LANGOPT(CPlusPlus , 1, 0, "C++")

clang/include/clang/Basic/TokenKinds.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ PUNCTUATOR(caretcaret, "^^")
292292
// CHAR8SUPPORT - This is a keyword if 'char8_t' is a built-in type
293293
// KEYFIXEDPOINT - This is a keyword according to the N1169 fixed point
294294
// extension.
295+
// KEYZOS - This is a keyword in C/C++ on z/OS
295296
//
296297
KEYWORD(auto , KEYALL)
297298
KEYWORD(break , KEYALL)
@@ -722,7 +723,7 @@ KEYWORD(__funcref , KEYALL)
722723

723724
// Microsoft extensions which should be disabled in strict conformance mode
724725
KEYWORD(__ptr64 , KEYMS)
725-
KEYWORD(__ptr32 , KEYMS)
726+
KEYWORD(__ptr32 , KEYMS | KEYZOS)
726727
KEYWORD(__sptr , KEYMS)
727728
KEYWORD(__uptr , KEYMS)
728729
KEYWORD(__w64 , KEYMS)

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3065,6 +3065,10 @@ dll version.}]>;
30653065
def fms_omit_default_lib : Joined<["-"], "fms-omit-default-lib">,
30663066
Group<f_Group>, Flags<[]>,
30673067
Visibility<[ClangOption, CLOption]>;
3068+
def fzos_extensions : Flag<["-"], "fzos-extensions">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
3069+
HelpText<"Accept some non-standard constructs supported by the z/OS compiler">;
3070+
def fno_zos_extensions : Flag<["-"], "fno-zos-extensions">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
3071+
HelpText<"Do not accept non-standard constructs supported by the z/OS compiler">;
30683072
defm delayed_template_parsing : BoolFOption<"delayed-template-parsing",
30693073
LangOpts<"DelayedTemplateParsing">, DefaultFalse,
30703074
PosFlag<SetTrue, [], [ClangOption, CC1Option],

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2727,6 +2727,8 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
27272727
// <type> ::= U <OpenCL-addrspace>
27282728
// <type> ::= U <CUDA-addrspace>
27292729

2730+
llvm::Triple Triple = getASTContext().getTargetInfo().getTriple();
2731+
27302732
SmallString<64> ASString;
27312733
LangAS AS = Quals.getAddressSpace();
27322734

@@ -2795,7 +2797,11 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
27952797
ASString = "ptr32_sptr";
27962798
break;
27972799
case LangAS::ptr32_uptr:
2798-
ASString = "ptr32_uptr";
2800+
// For z/OS, there are no special mangling rules applied to the ptr32
2801+
// qualifier. Ex: void foo(int * __ptr32 p) -> _Z3f2Pi. The mangling for
2802+
// "p" is treated the same as a regular integer pointer.
2803+
if (!Triple.isOSzOS())
2804+
ASString = "ptr32_uptr";
27992805
break;
28002806
case LangAS::ptr64:
28012807
ASString = "ptr64";

clang/lib/Basic/IdentifierTable.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,14 @@ namespace {
107107
KEYMSCOMPAT = 0x400000,
108108
KEYSYCL = 0x800000,
109109
KEYCUDA = 0x1000000,
110-
KEYHLSL = 0x2000000,
111-
KEYFIXEDPOINT = 0x4000000,
110+
KEYZOS = 0x2000000,
111+
KEYNOZOS = 0x4000000,
112+
KEYHLSL = 0x8000000,
113+
KEYFIXEDPOINT = 0x10000000,
112114
KEYMAX = KEYFIXEDPOINT, // The maximum key
113115
KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20,
114-
KEYALL = (KEYMAX | (KEYMAX-1)) & ~KEYNOMS18 &
115-
~KEYNOOPENCL // KEYNOMS18 and KEYNOOPENCL are used to exclude.
116+
KEYALL = (KEYMAX | (KEYMAX-1)) & ~KEYNOMS18 & ~KEYNOOPENCL &
117+
~KEYNOZOS // KEYNOMS18, KEYNOOPENCL, KEYNOZOS are excluded.
116118
};
117119

118120
/// How a keyword is treated in the selected standard. This enum is ordered
@@ -199,6 +201,8 @@ static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts,
199201
return LangOpts.isSYCL() ? KS_Enabled : KS_Unknown;
200202
case KEYCUDA:
201203
return LangOpts.CUDA ? KS_Enabled : KS_Unknown;
204+
case KEYZOS:
205+
return LangOpts.ZOSExt ? KS_Enabled : KS_Unknown;
202206
case KEYHLSL:
203207
return LangOpts.HLSL ? KS_Enabled : KS_Unknown;
204208
case KEYNOCXX:
@@ -211,6 +215,9 @@ static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts,
211215
case KEYNOMS18:
212216
// The disable behavior for this is handled in getKeywordStatus.
213217
return KS_Unknown;
218+
case KEYNOZOS:
219+
// The disable behavior for this is handled in getKeywordStatus.
220+
return KS_Unknown;
214221
case KEYFIXEDPOINT:
215222
return LangOpts.FixedPoint ? KS_Enabled : KS_Disabled;
216223
default:
@@ -230,7 +237,8 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts,
230237
if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
231238
!LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015))
232239
return KS_Disabled;
233-
240+
if (LangOpts.ZOSExt && (Flags & KEYNOZOS))
241+
return KS_Disabled;
234242
KeywordStatus CurStatus = KS_Unknown;
235243

236244
while (Flags != 0) {

clang/lib/Basic/Targets/SystemZ.h

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,30 @@
2121
namespace clang {
2222
namespace targets {
2323

24+
static const unsigned ZOSAddressMap[] = {
25+
0, // Default
26+
0, // opencl_global
27+
0, // opencl_local
28+
0, // opencl_constant
29+
0, // opencl_private
30+
0, // opencl_generic
31+
0, // opencl_global_device
32+
0, // opencl_global_host
33+
0, // cuda_device
34+
0, // cuda_constant
35+
0, // cuda_shared
36+
0, // sycl_global
37+
0, // sycl_global_device
38+
0, // sycl_global_host
39+
0, // sycl_local
40+
0, // sycl_private
41+
0, // ptr32_sptr
42+
1, // ptr32_uptr
43+
0, // ptr64
44+
0, // hlsl_groupshared
45+
0 // wasm_funcref
46+
};
47+
2448
class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
2549

2650
static const char *const GCCRegNames[];
@@ -30,6 +54,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
3054
bool HasVector;
3155
bool SoftFloat;
3256
bool UnalignedSymbols;
57+
enum AddrSpace { ptr32 = 1 };
3358

3459
public:
3560
SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
@@ -49,14 +74,17 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
4974
MinGlobalAlign = 16;
5075
HasUnalignedAccess = true;
5176
if (Triple.isOSzOS()) {
77+
if (Triple.isArch64Bit()) {
78+
AddrSpaceMap = &ZOSAddressMap;
79+
}
5280
TLSSupported = false;
5381
// All vector types are default aligned on an 8-byte boundary, even if the
5482
// vector facility is not available. That is different from Linux.
5583
MaxVectorAlign = 64;
5684
// Compared to Linux/ELF, the data layout differs only in some details:
5785
// - name mangling is GOFF.
5886
// - 32 bit pointers, either as default or special address space
59-
resetDataLayout("E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"
87+
resetDataLayout("E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"
6088
"a:8:16-n32:64");
6189
} else {
6290
TLSSupported = true;
@@ -224,6 +252,16 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
224252
std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
225253
return std::make_pair(256, 256);
226254
}
255+
uint64_t getPointerWidthV(LangAS AddrSpace) const override {
256+
return (getTriple().isOSzOS() && getTriple().isArch64Bit() &&
257+
getTargetAddressSpace(AddrSpace) == ptr32)
258+
? 32
259+
: PointerWidth;
260+
}
261+
262+
uint64_t getPointerAlignV(LangAS AddrSpace) const override {
263+
return getPointerWidthV(AddrSpace);
264+
}
227265
};
228266
} // namespace targets
229267
} // namespace clang

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,6 +3642,14 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
36423642
GenerateArg(Consumer, OPT_ftrigraphs);
36433643
}
36443644

3645+
if (T.isOSzOS()) {
3646+
if (!Opts.ZOSExt)
3647+
GenerateArg(Consumer, OPT_fno_zos_extensions);
3648+
} else {
3649+
if (Opts.ZOSExt)
3650+
GenerateArg(Consumer, OPT_fzos_extensions);
3651+
}
3652+
36453653
if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
36463654
GenerateArg(Consumer, OPT_fblocks);
36473655

@@ -4043,6 +4051,9 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
40434051
Opts.Trigraphs =
40444052
Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
40454053

4054+
Opts.ZOSExt =
4055+
Args.hasFlag(OPT_fzos_extensions, OPT_fno_zos_extensions, T.isOSzOS());
4056+
40464057
Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
40474058
&& Opts.OpenCLVersion == 200);
40484059

clang/lib/Sema/SemaType.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7051,6 +7051,7 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
70517051

70527052
// Add address space to type based on its attributes.
70537053
LangAS ASIdx = LangAS::Default;
7054+
llvm::Triple Triple = S.Context.getTargetInfo().getTriple();
70547055
uint64_t PtrWidth =
70557056
S.Context.getTargetInfo().getPointerWidth(LangAS::Default);
70567057
if (PtrWidth == 32) {
@@ -7059,7 +7060,7 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
70597060
else if (Attrs[attr::UPtr])
70607061
ASIdx = LangAS::ptr32_uptr;
70617062
} else if (PtrWidth == 64 && Attrs[attr::Ptr32]) {
7062-
if (Attrs[attr::UPtr])
7063+
if (Triple.isOSzOS() || Attrs[attr::UPtr])
70637064
ASIdx = LangAS::ptr32_uptr;
70647065
else
70657066
ASIdx = LangAS::ptr32_sptr;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
2+
// RUN: %clang_cc1 -triple s390x-ibm-zos -fzos-extensions -emit-llvm < %s | FileCheck %s --check-prefix=PTR32-ZOS
3+
// RUN: %clang_cc1 -triple s390x-ibm-linux -fzos-extensions -emit-llvm < %s | FileCheck %s --check-prefix=PTR32-LINUX
4+
// RUN: %clang_cc1 -triple s390x-linux-gnu -fzos-extensions -emit-llvm < %s | FileCheck %s --check-prefix=PTR32-LINUX
5+
6+
void ptr32_declarations() {
7+
// PTR32-ZOS-LABEL: @ptr32_declarations()
8+
// PTR32-LINUX-LABEL: @ptr32_declarations()
9+
10+
// PTR32-ZOS: %p1 = alloca ptr addrspace(1), align 4
11+
// PTR32-LINUX-NOT: %p1 = alloca i8 addrspace(1)*, align 4
12+
// PTR32-LINUX: %p1 = alloca ptr, align 8
13+
char * __ptr32 p1;
14+
15+
// PTR32-ZOS: %p2 = alloca ptr, align 8
16+
// PTR32-LINUX-NOT: %p2 = alloca ptr addrspace(1), align 8
17+
// PTR32-LINUX: %p2 = alloca ptr, align 8
18+
char * __ptr32 *p2;
19+
20+
// PTR32-ZOS: %p3 = alloca ptr addrspace(1), align 4
21+
// PTR32-LINUX-NOT: %p3 = alloca i8* addrspace(1)*, align 4
22+
// PTR32-LINUX: %p3 = alloca ptr, align 8
23+
char ** __ptr32 p3;
24+
25+
// PTR32-ZOS: %p4 = alloca ptr, align 8
26+
// PTR32-LINUX-NOT: %p4 = alloca ptr addrspace(1), align 8
27+
// PTR32-LINUX: %p4 = alloca ptr, align 8
28+
char ** __ptr32 *p4;
29+
30+
// PTR32-ZOS: %p5 = alloca ptr, align 8
31+
// PTR32-LINUX-NOT: %p5 = alloca ptr addrspace(1), align 8
32+
// PTR32-LINUX: %p5 = alloca ptr, align 8
33+
char *** __ptr32 *p5;
34+
35+
// PTR32-ZOS: %p6 = alloca ptr, align 8
36+
// PTR32-LINUX: %p6 = alloca ptr, align 8
37+
char **p6;
38+
39+
// PTR32-ZOS: %p7 = alloca ptr addrspace(1), align 4
40+
// PTR32-LINUX-NOT: %p7 = alloca i8 addrspace(1)* addrspace(1)*, align 4
41+
// PTR32-LINUX: %p7 = alloca ptr, align 8
42+
char * __ptr32 * __ptr32 p7;
43+
44+
// PTR32-ZOS: %p8 = alloca ptr addrspace(1), align 4
45+
// PTR32-LINUX-NOT: %p8 = alloca i8* addrspace(1)* addrspace(1)*, align 4
46+
// PTR32-LINUX: %p8 = alloca ptr, align 8
47+
char ** __ptr32 * __ptr32 p8;
48+
49+
// PTR32-ZOS: %p9 = alloca ptr, align 8
50+
// PTR32-LINUX-NOT: %p9 = alloca i8* addrspace(1)* addrspace(1)**, align 8
51+
// PTR32-LINUX: %p9 = alloca ptr, align 8
52+
char ** __ptr32 * __ptr32 *p9;
53+
54+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// RUN: %clang_cc1 -triple s390x-ibm-zos -fzos-extensions -emit-llvm -O2 < %s | FileCheck %s --check-prefix=X64
2+
#include <stddef.h>
3+
void *__malloc31(size_t);
4+
5+
int test_1() {
6+
// X64-LABEL: define {{.*}} i32 @test_1()
7+
// X64: ret i32 135
8+
int *__ptr32 a;
9+
int *b;
10+
int i;
11+
int sum1, sum2, sum3;
12+
13+
a = (int *__ptr32)__malloc31(sizeof(int) * 10);
14+
15+
b = a;
16+
sum1 = 0;
17+
for (i = 0; i < 10; ++i) {
18+
a[i] = i;
19+
sum1 += i;
20+
}
21+
22+
sum2 = 0;
23+
for (i = 0; i < 10; ++i) {
24+
sum2 += a[i];
25+
}
26+
sum3 = 0;
27+
for (i = 0; i < 10; ++i) {
28+
sum3 += b[i];
29+
}
30+
31+
return (sum1 + sum2 + sum3);
32+
}
33+
34+
int test_2() {
35+
// X64-LABEL: define {{.*}} i32 @test_2()
36+
// X64: ret i32 4
37+
int *a = (int *)__malloc31(sizeof(int));
38+
int *__ptr32 b;
39+
40+
*a = 99;
41+
b = a;
42+
*b = 44;
43+
44+
// Test should return 4
45+
return (*b - 40);
46+
}
47+
48+
int test_3() {
49+
// X64-LABEL: define {{.*}} i32 @test_3()
50+
// X64: ret i32 4
51+
int *a = (int *)__malloc31(sizeof(int));
52+
int *__ptr32 b;
53+
54+
*a = 99;
55+
b = a;
56+
57+
// Test should return 4
58+
return (*b - 95);
59+
}
60+
61+
int test_4() {
62+
// X64-LABEL: define {{.*}} i32 @test_4()
63+
// X64: ret i32 1
64+
int *a = (int *)__malloc31(sizeof(int));
65+
float *d = (float *)__malloc31(sizeof(float));
66+
67+
int *__ptr32 b;
68+
int *c;
69+
70+
float *__ptr32 e;
71+
float *f;
72+
73+
*a = 0;
74+
*d = 0.0;
75+
76+
b = a;
77+
c = a;
78+
e = d;
79+
f = d;
80+
81+
// Test should return 1
82+
return (b == c && e == f);
83+
}
84+

0 commit comments

Comments
 (0)