Skip to content

Commit cd5afb9

Browse files
committed
__sys builtin support
1 parent 4f991cc commit cd5afb9

File tree

6 files changed

+96
-10
lines changed

6 files changed

+96
-10
lines changed

clang/include/clang/Basic/BuiltinsAArch64.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", INTRIN_H, ALL_MS_LANGUAGES,
267267
TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
268268
TARGET_HEADER_BUILTIN(_ReadStatusReg, "LLii", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
269269
TARGET_HEADER_BUILTIN(_WriteStatusReg, "viLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
270+
TARGET_HEADER_BUILTIN(__sys, "UiiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
270271
TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
271272

272273
TARGET_HEADER_BUILTIN(__mulh, "SLLiSLLiSLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")

clang/lib/CodeGen/TargetBuiltins/ARM.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5471,19 +5471,21 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
54715471
}
54725472

54735473
if (BuiltinID == clang::AArch64::BI_ReadStatusReg ||
5474-
BuiltinID == clang::AArch64::BI_WriteStatusReg) {
5474+
BuiltinID == clang::AArch64::BI_WriteStatusReg ||
5475+
BuiltinID == clang::AArch64::BI__sys) {
54755476
LLVMContext &Context = CGM.getLLVMContext();
54765477

54775478
unsigned SysReg =
54785479
E->getArg(0)->EvaluateKnownConstInt(getContext()).getZExtValue();
54795480

54805481
std::string SysRegStr;
5481-
llvm::raw_string_ostream(SysRegStr) <<
5482-
((1 << 1) | ((SysReg >> 14) & 1)) << ":" <<
5483-
((SysReg >> 11) & 7) << ":" <<
5484-
((SysReg >> 7) & 15) << ":" <<
5485-
((SysReg >> 3) & 15) << ":" <<
5486-
( SysReg & 7);
5482+
unsigned SysRegOp0 = (BuiltinID != clang::AArch64::BI__sys)
5483+
? ((1 << 1) | ((SysReg >> 14) & 1))
5484+
: 1;
5485+
llvm::raw_string_ostream(SysRegStr)
5486+
<< SysRegOp0 << ":" << ((SysReg >> 11) & 7) << ":"
5487+
<< ((SysReg >> 7) & 15) << ":" << ((SysReg >> 3) & 15) << ":"
5488+
<< (SysReg & 7);
54875489

54885490
llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysRegStr) };
54895491
llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
@@ -5500,8 +5502,13 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
55005502

55015503
llvm::Function *F = CGM.getIntrinsic(Intrinsic::write_register, Types);
55025504
llvm::Value *ArgValue = EmitScalarExpr(E->getArg(1));
5503-
5504-
return Builder.CreateCall(F, { Metadata, ArgValue });
5505+
llvm::Value *Result = Builder.CreateCall(F, {Metadata, ArgValue});
5506+
if (BuiltinID == clang::AArch64::BI__sys) {
5507+
// Return 0 for convenience, even though MSVC returns some other undefined
5508+
// value.
5509+
Result = ConstantInt::get(Builder.getInt32Ty(), 0);
5510+
}
5511+
return Result;
55055512
}
55065513

55075514
if (BuiltinID == clang::AArch64::BI_AddressOfReturnAddress) {

clang/lib/Headers/intrin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ long _InterlockedAdd(long volatile *Addend, long Value);
374374
__int64 _InterlockedAdd64(__int64 volatile *Addend, __int64 Value);
375375
__int64 _ReadStatusReg(int);
376376
void _WriteStatusReg(int, __int64);
377+
unsigned int __sys(int, __int64);
377378

378379
unsigned short __cdecl _byteswap_ushort(unsigned short val);
379380
unsigned long __cdecl _byteswap_ulong (unsigned long val);

clang/lib/Sema/SemaARM.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,7 @@ bool SemaARM::CheckAArch64BuiltinFunctionCall(const TargetInfo &TI,
10841084
// converted to a register of the form S1_2_C3_C4_5. Let the hardware throw
10851085
// an exception for incorrect registers. This matches MSVC behavior.
10861086
if (BuiltinID == AArch64::BI_ReadStatusReg ||
1087-
BuiltinID == AArch64::BI_WriteStatusReg)
1087+
BuiltinID == AArch64::BI_WriteStatusReg || BuiltinID == AArch64::BI__sys)
10881088
return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0x7fff);
10891089

10901090
if (BuiltinID == AArch64::BI__getReg)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// REQUIRES: aarch64-registered-target
2+
3+
// RUN: %clang_cc1 -triple arm64-windows -fms-compatibility -S \
4+
// RUN: -o - %s | FileCheck %s -check-prefix CHECK-ASM
5+
6+
// RUN: %clang_cc1 -triple arm64-darwin -fms-compatibility -S \
7+
// RUN: -o - %s | FileCheck %s -check-prefix CHECK-ASM
8+
9+
// RUN: %clang_cc1 -triple arm64-windows -fms-compatibility -emit-llvm \
10+
// RUN: -o - %s | FileCheck %s -check-prefix CHECK-IR
11+
12+
// RUN: %clang_cc1 -triple arm64-darwin -fms-compatibility -emit-llvm \
13+
// RUN: -o - %s | FileCheck %s -check-prefix CHECK-IR
14+
15+
// From winnt.h
16+
// op0=1 encodings, use with __sys
17+
#define ARM64_SYSINSTR(op0, op1, crn, crm, op2) \
18+
( ((op1 & 7) << 11) | \
19+
((crn & 15) << 7) | \
20+
((crm & 15) << 3) | \
21+
((op2 & 7) << 0) )
22+
23+
//
24+
// Sampling of instructions
25+
//
26+
#define ARM64_DC_CGDSW_EL1 ARM64_SYSINSTR(1,0, 7,10,6) // Clean of Data and Allocation Tags by Set/Way
27+
#define ARM64_IC_IALLU_EL1 ARM64_SYSINSTR(1,0, 7, 5,0) // Instruction Cache Invalidate All to PoU
28+
#define ARM64_AT_S1E2W ARM64_SYSINSTR(1,4, 7, 8,1) // Translate Stage1, EL2, write
29+
#define ARM64_TLBI_VMALLE1 ARM64_SYSINSTR(1,0, 8, 7,0) // Invalidate stage 1 TLB [CP15_TLBIALL]
30+
#define ARM64_CFP_RCTX ARM64_SYSINSTR(1,3, 7, 3,4) // Control Flow Prediction Restriction by Context
31+
32+
// From intrin.h
33+
unsigned int __sys(int, __int64);
34+
35+
void check__sys(__int64 v) {
36+
__int64 ret;
37+
38+
__sys(ARM64_DC_CGDSW_EL1, v);
39+
// CHECK-ASM: msr S1_0_C7_C10_6, x8
40+
// CHECK-IR: %[[VAR:.*]] = load i64,
41+
// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD2:.*]], i64 %[[VAR]])
42+
43+
__sys(ARM64_IC_IALLU_EL1, v);
44+
// CHECK-ASM: msr S1_0_C7_C5_0, x8
45+
// CHECK-IR: %[[VAR:.*]] = load i64,
46+
// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD3:.*]], i64 %[[VAR]])
47+
48+
__sys(ARM64_AT_S1E2W, v);
49+
// CHECK-ASM: msr S1_4_C7_C8_1, x8
50+
// CHECK-IR: %[[VAR:.*]] = load i64,
51+
// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD4:.*]], i64 %[[VAR]])
52+
53+
__sys(ARM64_TLBI_VMALLE1, v);
54+
// CHECK-ASM: msr S1_0_C8_C7_0, x8
55+
// CHECK-IR: %[[VAR:.*]] = load i64,
56+
// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD5:.*]], i64 %[[VAR]])
57+
58+
__sys(ARM64_CFP_RCTX, v);
59+
// CHECK-ASM: msr S1_3_C7_C3_4, x8
60+
// CHECK-IR: %[[VAR:.*]] = load i64,
61+
// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD6:.*]], i64 %[[VAR]])
62+
}
63+
64+
// CHECK-IR: ![[MD2]] = !{!"1:0:7:10:6"}
65+
// CHECK-IR: ![[MD3]] = !{!"1:0:7:5:0"}
66+
// CHECK-IR: ![[MD4]] = !{!"1:4:7:8:1"}
67+
// CHECK-IR: ![[MD5]] = !{!"1:0:8:7:0"}
68+
// CHECK-IR: ![[MD6]] = !{!"1:3:7:3:4"}

clang/test/Sema/builtins-microsoft-arm64.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,12 @@ void check_ReadWriteStatusReg(int v) {
2424
_ReadStatusReg(x); // expected-error {{argument to '_ReadStatusReg' must be a constant integer}}
2525
_WriteStatusReg(x, v); // expected-error {{argument to '_WriteStatusReg' must be a constant integer}}
2626
}
27+
28+
void check__sys(int v) {
29+
int x;
30+
__sys(x, v); // expected-error {{argument to '__sys' must be a constant integer}}
31+
}
32+
33+
unsigned int check__sys_retval() {
34+
return __sys(0, 1); // builtin has superfluous return value for MSVC compatibility
35+
}

0 commit comments

Comments
 (0)