1818#include " clang/CIR/MissingFeatures.h"
1919#include " llvm/IR/IntrinsicsX86.h"
2020
21+ #define UNIMPLEMENTED_BUILTIN () \
22+ do { \
23+ cgm.errorNYI (e->getSourceRange (), \
24+ std::string (" unimplemented X86 builtin call: " ) + \
25+ getContext ().BuiltinInfo .getName (builtinID)); \
26+ return {}; \
27+ } while (0 )
28+
2129using namespace clang ;
2230using namespace clang ::CIRGen;
2331
32+ // / Get integer from a mlir::Value that is an int constant or a constant op.
33+ static int64_t getIntValueFromConstOp (mlir::Value val) {
34+ return val.getDefiningOp <cir::ConstantOp>().getIntValue ().getSExtValue ();
35+ }
36+
2437mlir::Value CIRGenFunction::emitX86BuiltinExpr (unsigned builtinID,
2538 const CallExpr *e) {
2639 if (builtinID == Builtin::BI__builtin_cpu_is) {
@@ -43,15 +56,76 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
4356 // Find out if any arguments are required to be integer constant expressions.
4457 assert (!cir::MissingFeatures::handleBuiltinICEArguments ());
4558
59+ llvm::SmallVector<mlir::Value, 4 > ops;
60+
61+ // Find out if any arguments are required to be integer constant expressions.
62+ unsigned ICEArguments = 0 ;
63+ ASTContext::GetBuiltinTypeError error;
64+ getContext ().GetBuiltinType (builtinID, error, &ICEArguments);
65+ assert (error == ASTContext::GE_None && " Should not codegen an error" );
66+
67+ for (auto [idx, _] : llvm::enumerate (e->arguments ())) {
68+ ops.push_back (emitScalarOrConstFoldImmArg (ICEArguments, idx, e));
69+ }
70+
4671 switch (builtinID) {
4772 default :
4873 return {};
49- case X86::BI_mm_prefetch:
50- case X86::BI_mm_clflush:
51- case X86::BI_mm_lfence:
52- case X86::BI_mm_pause:
53- case X86::BI_mm_mfence:
54- case X86::BI_mm_sfence:
74+ case X86::BI_mm_prefetch: {
75+ mlir::Value address = builder.createPtrBitcast (ops[0 ], voidTy);
76+
77+ int64_t hint = getIntValueFromConstOp (ops[1 ]);
78+ mlir::Value rw =
79+ cir::ConstantOp::create (builder, getLoc (e->getExprLoc ()),
80+ cir::IntAttr::get (sInt32Ty , (hint >> 2 ) & 0x1 ));
81+ mlir::Value locality =
82+ cir::ConstantOp::create (builder, getLoc (e->getExprLoc ()),
83+ cir::IntAttr::get (sInt32Ty , hint & 0x3 ));
84+ mlir::Value data = cir::ConstantOp::create (builder, getLoc (e->getExprLoc ()),
85+ cir::IntAttr::get (sInt32Ty , 1 ));
86+ mlir::Type voidTy = cir::VoidType::get (&getMLIRContext ());
87+
88+ return cir::LLVMIntrinsicCallOp::create (
89+ builder, getLoc (e->getExprLoc ()),
90+ builder.getStringAttr (" prefetch" ), voidTy,
91+ mlir::ValueRange{address, rw, locality, data})
92+ .getResult ();
93+ }
94+ case X86::BI_mm_clflush: {
95+ mlir::Type voidTy = cir::VoidType::get (&getMLIRContext ());
96+ return cir::LLVMIntrinsicCallOp::create (
97+ builder, getLoc (e->getExprLoc ()),
98+ builder.getStringAttr (" x86.sse2.clflush" ), voidTy, ops[0 ])
99+ .getResult ();
100+ }
101+ case X86::BI_mm_lfence: {
102+ mlir::Type voidTy = cir::VoidType::get (&getMLIRContext ());
103+ return cir::LLVMIntrinsicCallOp::create (
104+ builder, getLoc (e->getExprLoc ()),
105+ builder.getStringAttr (" x86.sse2.lfence" ), voidTy)
106+ .getResult ();
107+ }
108+ case X86::BI_mm_pause: {
109+ mlir::Type voidTy = cir::VoidType::get (&getMLIRContext ());
110+ return cir::LLVMIntrinsicCallOp::create (
111+ builder, getLoc (e->getExprLoc ()),
112+ builder.getStringAttr (" x86.sse2.pause" ), voidTy)
113+ .getResult ();
114+ }
115+ case X86::BI_mm_mfence: {
116+ mlir::Type voidTy = cir::VoidType::get (&getMLIRContext ());
117+ return cir::LLVMIntrinsicCallOp::create (
118+ builder, getLoc (e->getExprLoc ()),
119+ builder.getStringAttr (" x86.sse2.mfence" ), voidTy)
120+ .getResult ();
121+ }
122+ case X86::BI_mm_sfence: {
123+ mlir::Type voidTy = cir::VoidType::get (&getMLIRContext ());
124+ return cir::LLVMIntrinsicCallOp::create (
125+ builder, getLoc (e->getExprLoc ()),
126+ builder.getStringAttr (" x86.sse.sfence" ), voidTy)
127+ .getResult ();
128+ }
55129 case X86::BI__rdtsc:
56130 case X86::BI__builtin_ia32_rdtscp:
57131 case X86::BI__builtin_ia32_lzcnt_u16:
@@ -82,10 +156,27 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
82156 case X86::BI__builtin_ia32_vec_set_v16hi:
83157 case X86::BI__builtin_ia32_vec_set_v8si:
84158 case X86::BI__builtin_ia32_vec_set_v4di:
159+ UNIMPLEMENTED_BUILTIN ();
85160 case X86::BI_mm_setcsr:
86- case X86::BI__builtin_ia32_ldmxcsr:
161+ case X86::BI__builtin_ia32_ldmxcsr: {
162+ Address tmp =
163+ createMemTemp (e->getArg (0 )->getType (), getLoc (e->getExprLoc ()));
164+ builder.createStore (getLoc (e->getExprLoc ()), ops[0 ], tmp);
165+ return cir::LLVMIntrinsicCallOp::create (
166+ builder, getLoc (e->getExprLoc ()),
167+ builder.getStringAttr (" x86.sse.ldmxcsr" ), builder.getVoidTy (),
168+ tmp.getPointer ())
169+ .getResult ();
170+ }
87171 case X86::BI_mm_getcsr:
88- case X86::BI__builtin_ia32_stmxcsr:
172+ case X86::BI__builtin_ia32_stmxcsr: {
173+ Address tmp = createMemTemp (e->getType (), getLoc (e->getExprLoc ()));
174+ cir::LLVMIntrinsicCallOp::create (builder, getLoc (e->getExprLoc ()),
175+ builder.getStringAttr (" x86.sse.stmxcsr" ),
176+ builder.getVoidTy (), tmp.getPointer ())
177+ .getResult ();
178+ return builder.createLoad (getLoc (e->getExprLoc ()), tmp);
179+ }
89180 case X86::BI__builtin_ia32_xsave:
90181 case X86::BI__builtin_ia32_xsave64:
91182 case X86::BI__builtin_ia32_xrstor:
@@ -798,9 +889,6 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
798889 case X86::BI__builtin_ia32_vfcmaddcsh_round_mask3:
799890 case X86::BI__builtin_ia32_vfmaddcsh_round_mask3:
800891 case X86::BI__builtin_ia32_prefetchi:
801- cgm.errorNYI (e->getSourceRange (),
802- std::string (" unimplemented X86 builtin call: " ) +
803- getContext ().BuiltinInfo .getName (builtinID));
804- return {};
892+ UNIMPLEMENTED_BUILTIN ();
805893 }
806894}
0 commit comments