diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def index c3852fbb4232f6c6c5d28ca129bd9fec3aa02004..8c6daa9146f5ecba44f078eea65e2579a5c45e77 100644 --- a/include/clang/Basic/BuiltinsAArch64.def +++ b/include/clang/Basic/BuiltinsAArch64.def @@ -27,6 +27,13 @@ BUILTIN(__builtin_arm_clrex, "v", "") BUILTIN(__builtin_arm_rbit, "UiUi", "nc") BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc") +// HINT +BUILTIN(__builtin_arm_yield, "v", "") +BUILTIN(__builtin_arm_wfe, "v", "") +BUILTIN(__builtin_arm_wfi, "v", "") +BUILTIN(__builtin_arm_sev, "v", "") +BUILTIN(__builtin_arm_sevl, "v", "") + // CRC32 BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc") BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc") diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 9d1ad673c20a21b8f3d41edd0d4322a1d65aa23c..4fd98bc1fd10eb9486632cf807a5e322d6a4e844 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -3801,6 +3801,31 @@ emitVectorWrappedScalar16Intrinsic(unsigned Int, SmallVectorImpl<Value*> &Ops, Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E) { + unsigned HintID = static_cast<unsigned>(-1); + switch (BuiltinID) { + default: break; + case AArch64::BI__builtin_arm_yield: + HintID = 1; + break; + case AArch64::BI__builtin_arm_wfe: + HintID = 2; + break; + case AArch64::BI__builtin_arm_wfi: + HintID = 3; + break; + case AArch64::BI__builtin_arm_sev: + HintID = 4; + break; + case AArch64::BI__builtin_arm_sevl: + HintID = 5; + break; + } + + if (HintID != static_cast<unsigned>(-1)) { + Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint); + return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID)); + } + if (BuiltinID == AArch64::BI__builtin_arm_rbit) { assert((getContext().getTypeSize(E->getType()) == 32) && "rbit of unusual size!"); diff --git a/test/CodeGen/arm_acle.c b/test/CodeGen/arm_acle.c index a2f24d3fbf4f78343ca1c6bc947dab291887be1e..a7c37f5f8a0cd7a37196fc0692fdf6e41237b286 100644 --- a/test/CodeGen/arm_acle.c +++ b/test/CodeGen/arm_acle.c @@ -3,6 +3,43 @@ #include <arm_acle.h> +/* Hints */ + +// ARM-LABEL: test_yield +// AArch32: call void @llvm.arm.hint(i32 1) +// AArch64: call void @llvm.aarch64.hint(i32 1) +void test_yield(void) { + __yield(); +} + +// ARM-LABEL: test_wfe +// AArch32: call void @llvm.arm.hint(i32 2) +// AArch64: call void @llvm.aarch64.hint(i32 2) +void test_wfe(void) { + __wfe(); +} + +// ARM-LABEL: test_wfi +// AArch32: call void @llvm.arm.hint(i32 3) +// AArch64: call void @llvm.aarch64.hint(i32 3) +void test_wfi(void) { + __wfi(); +} + +// ARM-LABEL: test_sev +// AArch32: call void @llvm.arm.hint(i32 4) +// AArch64: call void @llvm.aarch64.hint(i32 4) +void test_sev(void) { + __sev(); +} + +// ARM-LABEL: test_sevl +// AArch32: call void @llvm.arm.hint(i32 5) +// AArch64: call void @llvm.aarch64.hint(i32 5) +void test_sevl(void) { + __sevl(); +} + /* 9 DATA-PROCESSING INTRINSICS */ /* 9.2 Miscellaneous data-processing intrinsics */ // ARM-LABEL: test_rev