summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/TargetBuiltins/ARM.cpp')
-rw-r--r--clang/lib/CodeGen/TargetBuiltins/ARM.cpp84
1 files changed, 59 insertions, 25 deletions
diff --git a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
index 6738d4be6dd2..7e6a47fd7c10 100644
--- a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
@@ -838,20 +838,20 @@ static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = {
NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType),
NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
- NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType),
- NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType),
- NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType),
+ NEONMAP1(vrnd_v, trunc, Add1ArgType),
+ NEONMAP1(vrnda_v, round, Add1ArgType),
+ NEONMAP1(vrndaq_v, round, Add1ArgType),
NEONMAP0(vrndi_v),
NEONMAP0(vrndiq_v),
- NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType),
- NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType),
- NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType),
- NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType),
- NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType),
- NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType),
- NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType),
- NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType),
- NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType),
+ NEONMAP1(vrndm_v, floor, Add1ArgType),
+ NEONMAP1(vrndmq_v, floor, Add1ArgType),
+ NEONMAP1(vrndn_v, roundeven, Add1ArgType),
+ NEONMAP1(vrndnq_v, roundeven, Add1ArgType),
+ NEONMAP1(vrndp_v, ceil, Add1ArgType),
+ NEONMAP1(vrndpq_v, ceil, Add1ArgType),
+ NEONMAP1(vrndq_v, trunc, Add1ArgType),
+ NEONMAP1(vrndx_v, rint, Add1ArgType),
+ NEONMAP1(vrndxq_v, rint, Add1ArgType),
NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts),
@@ -3132,7 +3132,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
case NEON::BI__builtin_neon_vrndns_f32: {
Value *Arg = EmitScalarExpr(E->getArg(0));
llvm::Type *Tys[] = {Arg->getType()};
- Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vrintn, Tys);
+ Function *F = CGM.getIntrinsic(Intrinsic::roundeven, Tys);
return Builder.CreateCall(F, {Arg}, "vrndn"); }
case NEON::BI__builtin_neon_vset_lane_i8:
@@ -5471,19 +5471,22 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
}
if (BuiltinID == clang::AArch64::BI_ReadStatusReg ||
- BuiltinID == clang::AArch64::BI_WriteStatusReg) {
+ BuiltinID == clang::AArch64::BI_WriteStatusReg ||
+ BuiltinID == clang::AArch64::BI__sys) {
LLVMContext &Context = CGM.getLLVMContext();
unsigned SysReg =
E->getArg(0)->EvaluateKnownConstInt(getContext()).getZExtValue();
std::string SysRegStr;
- llvm::raw_string_ostream(SysRegStr) <<
- ((1 << 1) | ((SysReg >> 14) & 1)) << ":" <<
- ((SysReg >> 11) & 7) << ":" <<
- ((SysReg >> 7) & 15) << ":" <<
- ((SysReg >> 3) & 15) << ":" <<
- ( SysReg & 7);
+ unsigned SysRegOp0 = (BuiltinID == clang::AArch64::BI_ReadStatusReg ||
+ BuiltinID == clang::AArch64::BI_WriteStatusReg)
+ ? ((1 << 1) | ((SysReg >> 14) & 1))
+ : 1;
+ llvm::raw_string_ostream(SysRegStr)
+ << SysRegOp0 << ":" << ((SysReg >> 11) & 7) << ":"
+ << ((SysReg >> 7) & 15) << ":" << ((SysReg >> 3) & 15) << ":"
+ << (SysReg & 7);
llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysRegStr) };
llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
@@ -5500,8 +5503,13 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
llvm::Function *F = CGM.getIntrinsic(Intrinsic::write_register, Types);
llvm::Value *ArgValue = EmitScalarExpr(E->getArg(1));
-
- return Builder.CreateCall(F, { Metadata, ArgValue });
+ llvm::Value *Result = Builder.CreateCall(F, {Metadata, ArgValue});
+ if (BuiltinID == clang::AArch64::BI__sys) {
+ // Return 0 for convenience, even though MSVC returns some other undefined
+ // value.
+ Result = ConstantInt::get(Builder.getInt32Ty(), 0);
+ }
+ return Result;
}
if (BuiltinID == clang::AArch64::BI_AddressOfReturnAddress) {
@@ -6499,12 +6507,38 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
}
case clang::AArch64::BI_InterlockedAdd:
- case clang::AArch64::BI_InterlockedAdd64: {
+ case clang::AArch64::BI_InterlockedAdd_acq:
+ case clang::AArch64::BI_InterlockedAdd_rel:
+ case clang::AArch64::BI_InterlockedAdd_nf:
+ case clang::AArch64::BI_InterlockedAdd64:
+ case clang::AArch64::BI_InterlockedAdd64_acq:
+ case clang::AArch64::BI_InterlockedAdd64_rel:
+ case clang::AArch64::BI_InterlockedAdd64_nf: {
Address DestAddr = CheckAtomicAlignment(*this, E);
Value *Val = EmitScalarExpr(E->getArg(1));
+ llvm::AtomicOrdering Ordering;
+ switch (BuiltinID) {
+ case clang::AArch64::BI_InterlockedAdd:
+ case clang::AArch64::BI_InterlockedAdd64:
+ Ordering = llvm::AtomicOrdering::SequentiallyConsistent;
+ break;
+ case clang::AArch64::BI_InterlockedAdd_acq:
+ case clang::AArch64::BI_InterlockedAdd64_acq:
+ Ordering = llvm::AtomicOrdering::Acquire;
+ break;
+ case clang::AArch64::BI_InterlockedAdd_rel:
+ case clang::AArch64::BI_InterlockedAdd64_rel:
+ Ordering = llvm::AtomicOrdering::Release;
+ break;
+ case clang::AArch64::BI_InterlockedAdd_nf:
+ case clang::AArch64::BI_InterlockedAdd64_nf:
+ Ordering = llvm::AtomicOrdering::Monotonic;
+ break;
+ default:
+ llvm_unreachable("missing builtin ID in switch!");
+ }
AtomicRMWInst *RMWI =
- Builder.CreateAtomicRMW(AtomicRMWInst::Add, DestAddr, Val,
- llvm::AtomicOrdering::SequentiallyConsistent);
+ Builder.CreateAtomicRMW(AtomicRMWInst::Add, DestAddr, Val, Ordering);
return Builder.CreateAdd(RMWI, Val);
}
}