@@ -31,7 +31,79 @@ using namespace clang;
3131using namespace clang ::CIRGen;
3232using namespace cir ;
3333
34+ static std::optional<CIRGenFunction::MSVCIntrin>
35+ translateX86ToMsvcIntrin (unsigned BuiltinID) {
36+ using MSVCIntrin = CIRGenFunction::MSVCIntrin;
37+ switch (BuiltinID) {
38+ default :
39+ return std::nullopt ;
40+ case clang::X86::BI_BitScanForward:
41+ case clang::X86::BI_BitScanForward64:
42+ return MSVCIntrin::_BitScanForward;
43+ case clang::X86::BI_BitScanReverse:
44+ case clang::X86::BI_BitScanReverse64:
45+ return MSVCIntrin::_BitScanReverse;
46+ case clang::X86::BI_InterlockedAnd64:
47+ return MSVCIntrin::_InterlockedAnd;
48+ case clang::X86::BI_InterlockedCompareExchange128:
49+ return MSVCIntrin::_InterlockedCompareExchange128;
50+ case clang::X86::BI_InterlockedExchange64:
51+ return MSVCIntrin::_InterlockedExchange;
52+ case clang::X86::BI_InterlockedExchangeAdd64:
53+ return MSVCIntrin::_InterlockedExchangeAdd;
54+ case clang::X86::BI_InterlockedExchangeSub64:
55+ return MSVCIntrin::_InterlockedExchangeSub;
56+ case clang::X86::BI_InterlockedOr64:
57+ return MSVCIntrin::_InterlockedOr;
58+ case clang::X86::BI_InterlockedXor64:
59+ return MSVCIntrin::_InterlockedXor;
60+ case clang::X86::BI_InterlockedDecrement64:
61+ return MSVCIntrin::_InterlockedDecrement;
62+ case clang::X86::BI_InterlockedIncrement64:
63+ return MSVCIntrin::_InterlockedIncrement;
64+ }
65+ llvm_unreachable (" must return from switch" );
66+ }
67+
3468mlir::Value CIRGenFunction::emitX86BuiltinExpr (unsigned BuiltinID,
3569 const CallExpr *E) {
36- llvm_unreachable (" NYI" );
70+ if (BuiltinID == Builtin::BI__builtin_cpu_is)
71+ llvm_unreachable (" __builtin_cpu_is NYI" );
72+ if (BuiltinID == Builtin::BI__builtin_cpu_supports)
73+ llvm_unreachable (" __builtin_cpu_supports NYI" );
74+ if (BuiltinID == Builtin::BI__builtin_cpu_init)
75+ llvm_unreachable (" __builtin_cpu_init NYI" );
76+
77+ // Handle MSVC intrinsics before argument evaluation to prevent double
78+ // evaluation.
79+ if (std::optional<MSVCIntrin> MsvcIntId = translateX86ToMsvcIntrin (BuiltinID))
80+ llvm_unreachable (" translateX86ToMsvcIntrin NYI" );
81+
82+ llvm::SmallVector<mlir::Value, 4 > Ops;
83+
84+ // Find out if any arguments are required to be integer constant expressions.
85+ unsigned ICEArguments = 0 ;
86+ ASTContext::GetBuiltinTypeError Error;
87+ getContext ().GetBuiltinType (BuiltinID, Error, &ICEArguments);
88+ assert (Error == ASTContext::GE_None && " Should not codegen an error" );
89+
90+ for (unsigned i = 0 , e = E->getNumArgs (); i != e; i++) {
91+ Ops.push_back (emitScalarOrConstFoldImmArg (ICEArguments, i, E));
92+ }
93+
94+ switch (BuiltinID) {
95+ default :
96+ return nullptr ;
97+ case X86::BI_mm_prefetch: {
98+ llvm_unreachable (" _mm_prefetch NYI" );
99+ }
100+ case X86::BI_mm_clflush: {
101+ mlir::Type voidTy = cir::VoidType::get (&getMLIRContext ());
102+ return builder
103+ .create <cir::LLVMIntrinsicCallOp>(
104+ getLoc (E->getExprLoc ()), builder.getStringAttr (" x86.sse2.clflush" ),
105+ voidTy, Ops[0 ])
106+ .getResult ();
107+ }
108+ }
37109}
0 commit comments