@@ -1180,6 +1180,45 @@ static bool interp__builtin_ia32_bextr(InterpState &S, CodePtr OpPC,
11801180 return true ;
11811181}
11821182
1183+ static bool interp__builtin_ia32_bzhi (InterpState &S, CodePtr OpPC,
1184+ const InterpFrame *Frame,
1185+ const Function *Func,
1186+ const CallExpr *Call) {
1187+ PrimType ValT = *S.Ctx .classify (Call->getArg (0 ));
1188+ PrimType IndexT = *S.Ctx .classify (Call->getArg (1 ));
1189+
1190+ APSInt Val = peekToAPSInt (S.Stk , ValT,
1191+ align (primSize (ValT)) + align (primSize (IndexT)));
1192+ APSInt Idx = peekToAPSInt (S.Stk , IndexT);
1193+
1194+ unsigned BitWidth = Val.getBitWidth ();
1195+ uint64_t Index = Idx.extractBitsAsZExtValue (8 , 0 );
1196+
1197+ if (Index < BitWidth)
1198+ Val.clearHighBits (BitWidth - Index);
1199+
1200+ pushInteger (S, Val, Call->getType ());
1201+ return true ;
1202+ }
1203+
1204+ static bool interp__builtin_ia32_lzcnt (InterpState &S, CodePtr OpPC,
1205+ const InterpFrame *Frame,
1206+ const Function *Func,
1207+ const CallExpr *Call) {
1208+ APSInt Val = peekToAPSInt (S.Stk , *S.Ctx .classify (Call->getArg (0 )));
1209+ pushInteger (S, Val.countLeadingZeros (), Call->getType ());
1210+ return true ;
1211+ }
1212+
1213+ static bool interp__builtin_ia32_tzcnt (InterpState &S, CodePtr OpPC,
1214+ const InterpFrame *Frame,
1215+ const Function *Func,
1216+ const CallExpr *Call) {
1217+ APSInt Val = peekToAPSInt (S.Stk , *S.Ctx .classify (Call->getArg (0 )));
1218+ pushInteger (S, Val.countTrailingZeros (), Call->getType ());
1219+ return true ;
1220+ }
1221+
11831222static bool interp__builtin_os_log_format_buffer_size (InterpState &S,
11841223 CodePtr OpPC,
11851224 const InterpFrame *Frame,
@@ -1773,6 +1812,26 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
17731812 return false ;
17741813 break ;
17751814
1815+ case clang::X86::BI__builtin_ia32_bzhi_si:
1816+ case clang::X86::BI__builtin_ia32_bzhi_di:
1817+ if (!interp__builtin_ia32_bzhi (S, OpPC, Frame, F, Call))
1818+ return false ;
1819+ break ;
1820+
1821+ case clang::X86::BI__builtin_ia32_lzcnt_u16:
1822+ case clang::X86::BI__builtin_ia32_lzcnt_u32:
1823+ case clang::X86::BI__builtin_ia32_lzcnt_u64:
1824+ if (!interp__builtin_ia32_lzcnt (S, OpPC, Frame, F, Call))
1825+ return false ;
1826+ break ;
1827+
1828+ case clang::X86::BI__builtin_ia32_tzcnt_u16:
1829+ case clang::X86::BI__builtin_ia32_tzcnt_u32:
1830+ case clang::X86::BI__builtin_ia32_tzcnt_u64:
1831+ if (!interp__builtin_ia32_tzcnt (S, OpPC, Frame, F, Call))
1832+ return false ;
1833+ break ;
1834+
17761835 case Builtin::BI__builtin_os_log_format_buffer_size:
17771836 if (!interp__builtin_os_log_format_buffer_size (S, OpPC, Frame, F, Call))
17781837 return false ;
0 commit comments