diff options
Diffstat (limited to 'clang/lib/CodeGen/TargetBuiltins/ARM.cpp')
| -rw-r--r-- | clang/lib/CodeGen/TargetBuiltins/ARM.cpp | 84 |
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); } } |
