Skip to content

Commit 8518178

Browse files
authored
[clang][bytecode] Implement ia32_bextr builitns (#110513)
1 parent 5d45815 commit 8518178

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "clang/AST/OSLog.h"
1515
#include "clang/AST/RecordLayout.h"
1616
#include "clang/Basic/Builtins.h"
17+
#include "clang/Basic/TargetBuiltins.h"
1718
#include "clang/Basic/TargetInfo.h"
1819
#include "llvm/Support/SipHash.h"
1920

@@ -1152,6 +1153,33 @@ static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC,
11521153
return false;
11531154
}
11541155

1156+
static bool interp__builtin_ia32_bextr(InterpState &S, CodePtr OpPC,
1157+
const InterpFrame *Frame,
1158+
const Function *Func,
1159+
const CallExpr *Call) {
1160+
PrimType ValT = *S.Ctx.classify(Call->getArg(0));
1161+
PrimType IndexT = *S.Ctx.classify(Call->getArg(1));
1162+
APSInt Val = peekToAPSInt(S.Stk, ValT,
1163+
align(primSize(ValT)) + align(primSize(IndexT)));
1164+
APSInt Index = peekToAPSInt(S.Stk, IndexT);
1165+
1166+
unsigned BitWidth = Val.getBitWidth();
1167+
uint64_t Shift = Index.extractBitsAsZExtValue(8, 0);
1168+
uint64_t Length = Index.extractBitsAsZExtValue(8, 8);
1169+
Length = Length > BitWidth ? BitWidth : Length;
1170+
1171+
// Handle out of bounds cases.
1172+
if (Length == 0 || Shift >= BitWidth) {
1173+
pushInteger(S, 0, Call->getType());
1174+
return true;
1175+
}
1176+
1177+
uint64_t Result = Val.getZExtValue() >> Shift;
1178+
Result &= llvm::maskTrailingOnes<uint64_t>(Length);
1179+
pushInteger(S, Result, Call->getType());
1180+
return true;
1181+
}
1182+
11551183
static bool interp__builtin_os_log_format_buffer_size(InterpState &S,
11561184
CodePtr OpPC,
11571185
const InterpFrame *Frame,
@@ -1737,6 +1765,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
17371765
return false;
17381766
break;
17391767

1768+
case clang::X86::BI__builtin_ia32_bextr_u32:
1769+
case clang::X86::BI__builtin_ia32_bextr_u64:
1770+
case clang::X86::BI__builtin_ia32_bextri_u32:
1771+
case clang::X86::BI__builtin_ia32_bextri_u64:
1772+
if (!interp__builtin_ia32_bextr(S, OpPC, Frame, F, Call))
1773+
return false;
1774+
break;
1775+
17401776
case Builtin::BI__builtin_os_log_format_buffer_size:
17411777
if (!interp__builtin_os_log_format_buffer_size(S, OpPC, Frame, F, Call))
17421778
return false;

0 commit comments

Comments
 (0)