@@ -1219,6 +1219,48 @@ static bool interp__builtin_ia32_tzcnt(InterpState &S, CodePtr OpPC,
12191219 return true ;
12201220}
12211221
1222+ static bool interp__builtin_ia32_pdep (InterpState &S, CodePtr OpPC,
1223+ const InterpFrame *Frame,
1224+ const Function *Func,
1225+ const CallExpr *Call) {
1226+ PrimType ValT = *S.Ctx .classify (Call->getArg (0 ));
1227+ PrimType MaskT = *S.Ctx .classify (Call->getArg (1 ));
1228+
1229+ APSInt Val =
1230+ peekToAPSInt (S.Stk , ValT, align (primSize (ValT)) + align (primSize (MaskT)));
1231+ APSInt Mask = peekToAPSInt (S.Stk , MaskT);
1232+
1233+ unsigned BitWidth = Val.getBitWidth ();
1234+ APInt Result = APInt::getZero (BitWidth);
1235+ for (unsigned I = 0 , P = 0 ; I != BitWidth; ++I) {
1236+ if (Mask[I])
1237+ Result.setBitVal (I, Val[P++]);
1238+ }
1239+ pushInteger (S, Result, Call->getType ());
1240+ return true ;
1241+ }
1242+
1243+ static bool interp__builtin_ia32_pext (InterpState &S, CodePtr OpPC,
1244+ const InterpFrame *Frame,
1245+ const Function *Func,
1246+ const CallExpr *Call) {
1247+ PrimType ValT = *S.Ctx .classify (Call->getArg (0 ));
1248+ PrimType MaskT = *S.Ctx .classify (Call->getArg (1 ));
1249+
1250+ APSInt Val =
1251+ peekToAPSInt (S.Stk , ValT, align (primSize (ValT)) + align (primSize (MaskT)));
1252+ APSInt Mask = peekToAPSInt (S.Stk , MaskT);
1253+
1254+ unsigned BitWidth = Val.getBitWidth ();
1255+ APInt Result = APInt::getZero (BitWidth);
1256+ for (unsigned I = 0 , P = 0 ; I != BitWidth; ++I) {
1257+ if (Mask[I])
1258+ Result.setBitVal (P++, Val[I]);
1259+ }
1260+ pushInteger (S, Result, Call->getType ());
1261+ return true ;
1262+ }
1263+
12221264static bool interp__builtin_os_log_format_buffer_size (InterpState &S,
12231265 CodePtr OpPC,
12241266 const InterpFrame *Frame,
@@ -1832,6 +1874,18 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
18321874 return false ;
18331875 break ;
18341876
1877+ case clang::X86::BI__builtin_ia32_pdep_si:
1878+ case clang::X86::BI__builtin_ia32_pdep_di:
1879+ if (!interp__builtin_ia32_pdep (S, OpPC, Frame, F, Call))
1880+ return false ;
1881+ break ;
1882+
1883+ case clang::X86::BI__builtin_ia32_pext_si:
1884+ case clang::X86::BI__builtin_ia32_pext_di:
1885+ if (!interp__builtin_ia32_pext (S, OpPC, Frame, F, Call))
1886+ return false ;
1887+ break ;
1888+
18351889 case Builtin::BI__builtin_os_log_format_buffer_size:
18361890 if (!interp__builtin_os_log_format_buffer_size (S, OpPC, Frame, F, Call))
18371891 return false ;
0 commit comments