Skip to content

Commit 7147e88

Browse files
authored
[clang][bytecode] Implement lzcnt/tzcnt/bzhi builtins (#110639)
1 parent a5f3a2a commit 7147e88

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
11831222
static 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

Comments
 (0)