|
14 | 14 | #include "clang/AST/OSLog.h"
|
15 | 15 | #include "clang/AST/RecordLayout.h"
|
16 | 16 | #include "clang/Basic/Builtins.h"
|
| 17 | +#include "clang/Basic/TargetBuiltins.h" |
17 | 18 | #include "clang/Basic/TargetInfo.h"
|
18 | 19 | #include "llvm/Support/SipHash.h"
|
19 | 20 |
|
@@ -1152,6 +1153,33 @@ static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC,
|
1152 | 1153 | return false;
|
1153 | 1154 | }
|
1154 | 1155 |
|
| 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 | + |
1155 | 1183 | static bool interp__builtin_os_log_format_buffer_size(InterpState &S,
|
1156 | 1184 | CodePtr OpPC,
|
1157 | 1185 | const InterpFrame *Frame,
|
@@ -1737,6 +1765,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
|
1737 | 1765 | return false;
|
1738 | 1766 | break;
|
1739 | 1767 |
|
| 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 | + |
1740 | 1776 | case Builtin::BI__builtin_os_log_format_buffer_size:
|
1741 | 1777 | if (!interp__builtin_os_log_format_buffer_size(S, OpPC, Frame, F, Call))
|
1742 | 1778 | return false;
|
|
0 commit comments