@@ -1294,95 +1294,6 @@ static bool interp__builtin_assume_aligned(InterpState &S, CodePtr OpPC,
1294
1294
return true ;
1295
1295
}
1296
1296
1297
- static bool interp__builtin_ia32_bextr (InterpState &S, CodePtr OpPC,
1298
- const InterpFrame *Frame,
1299
- const CallExpr *Call) {
1300
- if (Call->getNumArgs () != 2 || !Call->getArg (0 )->getType ()->isIntegerType () ||
1301
- !Call->getArg (1 )->getType ()->isIntegerType ())
1302
- return false ;
1303
-
1304
- APSInt Index = popToAPSInt (S, Call->getArg (1 ));
1305
- APSInt Val = popToAPSInt (S, Call->getArg (0 ));
1306
-
1307
- unsigned BitWidth = Val.getBitWidth ();
1308
- uint64_t Shift = Index.extractBitsAsZExtValue (8 , 0 );
1309
- uint64_t Length = Index.extractBitsAsZExtValue (8 , 8 );
1310
- Length = Length > BitWidth ? BitWidth : Length;
1311
-
1312
- // Handle out of bounds cases.
1313
- if (Length == 0 || Shift >= BitWidth) {
1314
- pushInteger (S, 0 , Call->getType ());
1315
- return true ;
1316
- }
1317
-
1318
- uint64_t Result = Val.getZExtValue () >> Shift;
1319
- Result &= llvm::maskTrailingOnes<uint64_t >(Length);
1320
- pushInteger (S, Result, Call->getType ());
1321
- return true ;
1322
- }
1323
-
1324
- static bool interp__builtin_ia32_bzhi (InterpState &S, CodePtr OpPC,
1325
- const InterpFrame *Frame,
1326
- const CallExpr *Call) {
1327
- QualType CallType = Call->getType ();
1328
- if (Call->getNumArgs () != 2 || !Call->getArg (0 )->getType ()->isIntegerType () ||
1329
- !Call->getArg (1 )->getType ()->isIntegerType () ||
1330
- !CallType->isIntegerType ())
1331
- return false ;
1332
-
1333
- APSInt Idx = popToAPSInt (S, Call->getArg (1 ));
1334
- APSInt Val = popToAPSInt (S, Call->getArg (0 ));
1335
-
1336
- unsigned BitWidth = Val.getBitWidth ();
1337
- uint64_t Index = Idx.extractBitsAsZExtValue (8 , 0 );
1338
-
1339
- if (Index < BitWidth)
1340
- Val.clearHighBits (BitWidth - Index);
1341
-
1342
- pushInteger (S, Val, CallType);
1343
- return true ;
1344
- }
1345
-
1346
- static bool interp__builtin_ia32_pdep (InterpState &S, CodePtr OpPC,
1347
- const InterpFrame *Frame,
1348
- const CallExpr *Call) {
1349
- if (Call->getNumArgs () != 2 || !Call->getArg (0 )->getType ()->isIntegerType () ||
1350
- !Call->getArg (1 )->getType ()->isIntegerType ())
1351
- return false ;
1352
-
1353
- APSInt Mask = popToAPSInt (S, Call->getArg (1 ));
1354
- APSInt Val = popToAPSInt (S, Call->getArg (0 ));
1355
-
1356
- unsigned BitWidth = Val.getBitWidth ();
1357
- APInt Result = APInt::getZero (BitWidth);
1358
- for (unsigned I = 0 , P = 0 ; I != BitWidth; ++I) {
1359
- if (Mask[I])
1360
- Result.setBitVal (I, Val[P++]);
1361
- }
1362
- pushInteger (S, std::move (Result), Call->getType ());
1363
- return true ;
1364
- }
1365
-
1366
- static bool interp__builtin_ia32_pext (InterpState &S, CodePtr OpPC,
1367
- const InterpFrame *Frame,
1368
- const CallExpr *Call) {
1369
- if (Call->getNumArgs () != 2 || !Call->getArg (0 )->getType ()->isIntegerType () ||
1370
- !Call->getArg (1 )->getType ()->isIntegerType ())
1371
- return false ;
1372
-
1373
- APSInt Mask = popToAPSInt (S, Call->getArg (1 ));
1374
- APSInt Val = popToAPSInt (S, Call->getArg (0 ));
1375
-
1376
- unsigned BitWidth = Val.getBitWidth ();
1377
- APInt Result = APInt::getZero (BitWidth);
1378
- for (unsigned I = 0 , P = 0 ; I != BitWidth; ++I) {
1379
- if (Mask[I])
1380
- Result.setBitVal (P++, Val[I]);
1381
- }
1382
- pushInteger (S, std::move (Result), Call->getType ());
1383
- return true ;
1384
- }
1385
-
1386
1297
// / (CarryIn, LHS, RHS, Result)
1387
1298
static bool interp__builtin_ia32_addcarry_subborrow (InterpState &S,
1388
1299
CodePtr OpPC,
@@ -3275,11 +3186,37 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
3275
3186
case clang::X86::BI__builtin_ia32_bextr_u64:
3276
3187
case clang::X86::BI__builtin_ia32_bextri_u32:
3277
3188
case clang::X86::BI__builtin_ia32_bextri_u64:
3278
- return interp__builtin_ia32_bextr (S, OpPC, Frame, Call);
3189
+ return interp__builtin_elementwise_int_binop (
3190
+ S, OpPC, Call, [](const APSInt &Val, const APSInt &Idx) {
3191
+ unsigned BitWidth = Val.getBitWidth ();
3192
+ uint64_t Shift = Idx.extractBitsAsZExtValue (8 , 0 );
3193
+ uint64_t Length = Idx.extractBitsAsZExtValue (8 , 8 );
3194
+ if (Length > BitWidth) {
3195
+ Length = BitWidth;
3196
+ }
3197
+
3198
+ // Handle out of bounds cases.
3199
+ if (Length == 0 || Shift >= BitWidth)
3200
+ return APInt (BitWidth, 0 );
3201
+
3202
+ uint64_t Result = Val.getZExtValue () >> Shift;
3203
+ Result &= llvm::maskTrailingOnes<uint64_t >(Length);
3204
+ return APInt (BitWidth, Result);
3205
+ });
3279
3206
3280
3207
case clang::X86::BI__builtin_ia32_bzhi_si:
3281
3208
case clang::X86::BI__builtin_ia32_bzhi_di:
3282
- return interp__builtin_ia32_bzhi (S, OpPC, Frame, Call);
3209
+ return interp__builtin_elementwise_int_binop (
3210
+ S, OpPC, Call, [](const APSInt &Val, const APSInt &Idx) {
3211
+ unsigned BitWidth = Val.getBitWidth ();
3212
+ uint64_t Index = Idx.extractBitsAsZExtValue (8 , 0 );
3213
+ APSInt Result = Val;
3214
+
3215
+ if (Index < BitWidth)
3216
+ Result.clearHighBits (BitWidth - Index);
3217
+
3218
+ return Result;
3219
+ });
3283
3220
3284
3221
case clang::X86::BI__builtin_ia32_lzcnt_u16:
3285
3222
case clang::X86::BI__builtin_ia32_lzcnt_u32:
@@ -3299,11 +3236,33 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
3299
3236
3300
3237
case clang::X86::BI__builtin_ia32_pdep_si:
3301
3238
case clang::X86::BI__builtin_ia32_pdep_di:
3302
- return interp__builtin_ia32_pdep (S, OpPC, Frame, Call);
3239
+ return interp__builtin_elementwise_int_binop (
3240
+ S, OpPC, Call, [](const APSInt &Val, const APSInt &Mask) {
3241
+ unsigned BitWidth = Val.getBitWidth ();
3242
+ APInt Result = APInt::getZero (BitWidth);
3243
+
3244
+ for (unsigned I = 0 , P = 0 ; I != BitWidth; ++I) {
3245
+ if (Mask[I])
3246
+ Result.setBitVal (I, Val[P++]);
3247
+ }
3248
+
3249
+ return Result;
3250
+ });
3303
3251
3304
3252
case clang::X86::BI__builtin_ia32_pext_si:
3305
3253
case clang::X86::BI__builtin_ia32_pext_di:
3306
- return interp__builtin_ia32_pext (S, OpPC, Frame, Call);
3254
+ return interp__builtin_elementwise_int_binop (
3255
+ S, OpPC, Call, [](const APSInt &Val, const APSInt &Mask) {
3256
+ unsigned BitWidth = Val.getBitWidth ();
3257
+ APInt Result = APInt::getZero (BitWidth);
3258
+
3259
+ for (unsigned I = 0 , P = 0 ; I != BitWidth; ++I) {
3260
+ if (Mask[I])
3261
+ Result.setBitVal (P++, Val[I]);
3262
+ }
3263
+
3264
+ return Result;
3265
+ });
3307
3266
3308
3267
case clang::X86::BI__builtin_ia32_addcarryx_u32:
3309
3268
case clang::X86::BI__builtin_ia32_addcarryx_u64:
0 commit comments