Index: include/clang/Basic/BuiltinsAArch64.def =================================================================== --- include/clang/Basic/BuiltinsAArch64.def +++ include/clang/Basic/BuiltinsAArch64.def @@ -61,4 +61,7 @@ BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc") BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") +// Special registers +BUILTIN(__builtin_arm_current_sp, "LUi", "nc") + #undef BUILTIN Index: include/clang/Basic/BuiltinsARM.def =================================================================== --- include/clang/Basic/BuiltinsARM.def +++ include/clang/Basic/BuiltinsARM.def @@ -103,6 +103,10 @@ BUILTIN(__builtin_arm_wsr64, "vcC*LLUi", "nc") BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") +// Special registers +BUILTIN(__builtin_arm_current_sp, "Ui", "nc") +BUILTIN(__builtin_arm_current_pc, "Ui", "nc") + // MSVC LANGBUILTIN(__emit, "vIUiC", "", ALL_MS_LANGUAGES) Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -4224,11 +4224,15 @@ BuiltinID == ARM::BI__builtin_arm_rsrp || BuiltinID == ARM::BI__builtin_arm_wsr || BuiltinID == ARM::BI__builtin_arm_wsr64 || - BuiltinID == ARM::BI__builtin_arm_wsrp) { + BuiltinID == ARM::BI__builtin_arm_wsrp || + BuiltinID == ARM::BI__builtin_arm_current_sp || + BuiltinID == ARM::BI__builtin_arm_current_pc) { bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr || BuiltinID == ARM::BI__builtin_arm_rsr64 || - BuiltinID == ARM::BI__builtin_arm_rsrp; + BuiltinID == ARM::BI__builtin_arm_rsrp || + BuiltinID == ARM::BI__builtin_arm_current_sp || + BuiltinID == ARM::BI__builtin_arm_current_pc; bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp || BuiltinID == ARM::BI__builtin_arm_wsrp; @@ -4246,8 +4250,13 @@ } else { ValueType = RegisterType = Int32Ty; } - - return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); + std::string SysReg = ""; + if (BuiltinID == ARM::BI__builtin_arm_current_sp) + SysReg = "sp"; + else if (BuiltinID == ARM::BI__builtin_arm_current_pc) + SysReg = "pc"; + return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead, + SysReg); } // Find out if any arguments are required to be integer constant @@ -4980,11 +4989,13 @@ BuiltinID == AArch64::BI__builtin_arm_rsrp || BuiltinID == AArch64::BI__builtin_arm_wsr || BuiltinID == AArch64::BI__builtin_arm_wsr64 || - BuiltinID == AArch64::BI__builtin_arm_wsrp) { + BuiltinID == AArch64::BI__builtin_arm_wsrp || + BuiltinID == AArch64::BI__builtin_arm_current_sp) { bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr || BuiltinID == AArch64::BI__builtin_arm_rsr64 || - BuiltinID == AArch64::BI__builtin_arm_rsrp; + BuiltinID == AArch64::BI__builtin_arm_rsrp || + BuiltinID == AArch64::BI__builtin_arm_current_sp; bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp || BuiltinID == AArch64::BI__builtin_arm_wsrp; @@ -5001,8 +5012,11 @@ } else { ValueType = Int32Ty; } - - return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); + std::string SysReg = ""; + if (BuiltinID == AArch64::BI__builtin_arm_current_sp) + SysReg = "sp"; + return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead, + SysReg); } // Find out if any arguments are required to be integer constant Index: test/CodeGen/builtins-arm.c =================================================================== --- test/CodeGen/builtins-arm.c +++ test/CodeGen/builtins-arm.c @@ -225,6 +225,18 @@ return __builtin_arm_rsrp("sysreg"); } +unsigned __current_sp() { + // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i32 @llvm.read_register.i32(metadata ![[M3:.*]]) + // CHECK-NEXT: ret i32 [[V0]] + return __builtin_arm_current_sp(); +} + +unsigned __current_pc() { + // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i32 @llvm.read_register.i32(metadata ![[M4:.*]]) + // CHECK-NEXT: ret i32 [[V0]] + return __builtin_arm_current_pc(); +} + void wsr(unsigned v) { // CHECK: call void @llvm.write_register.i32(metadata ![[M0]], i32 %v) __builtin_arm_wsr("cp1:2:c3:c4:5", v); @@ -244,3 +256,5 @@ // CHECK: ![[M0]] = !{!"cp1:2:c3:c4:5"} // CHECK: ![[M1]] = !{!"cp1:2:c3"} // CHECK: ![[M2]] = !{!"sysreg"} +// CHECK: ![[M3]] = !{!"sp"} +// CHECK: ![[M4]] = !{!"pc"} Index: test/CodeGen/builtins-arm64.c =================================================================== --- test/CodeGen/builtins-arm64.c +++ test/CodeGen/builtins-arm64.c @@ -83,4 +83,10 @@ __builtin_arm_wsrp("1:2:3:4:5", v); } +unsigned long __current_sp() { + // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i64 @llvm.read_register.i64(metadata ![[M1:.*]]) + // CHECK-NEXT: ret i64 [[V0]] + return __builtin_arm_current_sp(); +} // CHECK: ![[M0]] = !{!"1:2:3:4:5"} +// CHECK: ![[M1]] = !{!"sp"}