aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2024-09-30 20:07:28 +0200
committerGitHub <noreply@github.com>2024-09-30 20:07:28 +0200
commit85181788576151cc4b52d38d9b52d04f26179530 (patch)
treebd0721d0b687c882b40e85935f850de18186c1ac
parent5d45815473496db4b041a008e60be17bd78c06ae (diff)
downloadllvm-85181788576151cc4b52d38d9b52d04f26179530.zip
llvm-85181788576151cc4b52d38d9b52d04f26179530.tar.gz
llvm-85181788576151cc4b52d38d9b52d04f26179530.tar.bz2
[clang][bytecode] Implement ia32_bextr builitns (#110513)
-rw-r--r--clang/lib/AST/ByteCode/InterpBuiltin.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 82ed6d9..eb59cf3 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -14,6 +14,7 @@
#include "clang/AST/OSLog.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/Builtins.h"
+#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/Support/SipHash.h"
@@ -1152,6 +1153,33 @@ static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC,
return false;
}
+static bool interp__builtin_ia32_bextr(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const Function *Func,
+ const CallExpr *Call) {
+ PrimType ValT = *S.Ctx.classify(Call->getArg(0));
+ PrimType IndexT = *S.Ctx.classify(Call->getArg(1));
+ APSInt Val = peekToAPSInt(S.Stk, ValT,
+ align(primSize(ValT)) + align(primSize(IndexT)));
+ APSInt Index = peekToAPSInt(S.Stk, IndexT);
+
+ unsigned BitWidth = Val.getBitWidth();
+ uint64_t Shift = Index.extractBitsAsZExtValue(8, 0);
+ uint64_t Length = Index.extractBitsAsZExtValue(8, 8);
+ Length = Length > BitWidth ? BitWidth : Length;
+
+ // Handle out of bounds cases.
+ if (Length == 0 || Shift >= BitWidth) {
+ pushInteger(S, 0, Call->getType());
+ return true;
+ }
+
+ uint64_t Result = Val.getZExtValue() >> Shift;
+ Result &= llvm::maskTrailingOnes<uint64_t>(Length);
+ pushInteger(S, Result, Call->getType());
+ return true;
+}
+
static bool interp__builtin_os_log_format_buffer_size(InterpState &S,
CodePtr OpPC,
const InterpFrame *Frame,
@@ -1737,6 +1765,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
return false;
break;
+ case clang::X86::BI__builtin_ia32_bextr_u32:
+ case clang::X86::BI__builtin_ia32_bextr_u64:
+ case clang::X86::BI__builtin_ia32_bextri_u32:
+ case clang::X86::BI__builtin_ia32_bextri_u64:
+ if (!interp__builtin_ia32_bextr(S, OpPC, Frame, F, Call))
+ return false;
+ break;
+
case Builtin::BI__builtin_os_log_format_buffer_size:
if (!interp__builtin_os_log_format_buffer_size(S, OpPC, Frame, F, Call))
return false;