@@ -53,6 +53,21 @@ static constexpr uint32_t kWX = InstDB::kWX;
53
53
static const uint8_t armShiftOpToLdStOptMap[] = { ASMJIT_LOOKUP_TABLE_16 (VALUE, 0 ) };
54
54
#undef VALUE
55
55
56
+ // a64::Assembler - ExtendOpToRegType
57
+ // ==================================
58
+
59
+ static inline RegType extendOptionToRegType (uint32_t option) noexcept {
60
+ uint32_t pred = (uint32_t (RegType::kARM_GpW ) << (0x0 * 4 )) | // 0b000 - UXTB.
61
+ (uint32_t (RegType::kARM_GpW ) << (0x1 * 4 )) | // 0b001 - UXTH.
62
+ (uint32_t (RegType::kARM_GpW ) << (0x2 * 4 )) | // 0b010 - UXTW.
63
+ (uint32_t (RegType::kARM_GpX ) << (0x3 * 4 )) | // 0b011 - UXTX|LSL.
64
+ (uint32_t (RegType::kARM_GpW ) << (0x4 * 4 )) | // 0b100 - SXTB.
65
+ (uint32_t (RegType::kARM_GpW ) << (0x5 * 4 )) | // 0b101 - SXTH.
66
+ (uint32_t (RegType::kARM_GpW ) << (0x6 * 4 )) | // 0b110 - SXTW.
67
+ (uint32_t (RegType::kARM_GpX ) << (0x7 * 4 )) ; // 0b111 - SXTX.
68
+ return RegType ((pred >> (option * 4u )) & 0xFu );
69
+ }
70
+
56
71
// asmjit::a64::Assembler - SizeOp
57
72
// ===============================
58
73
@@ -1228,9 +1243,6 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
1228
1243
}
1229
1244
1230
1245
if (isign4 == ENC_OPS3 (Reg, Reg, Reg) || isign4 == ENC_OPS4 (Reg, Reg, Reg, Imm)) {
1231
- if (!checkSignature (o1, o2))
1232
- goto InvalidInstruction;
1233
-
1234
1246
uint32_t opSize = x ? 64 : 32 ;
1235
1247
uint64_t shift = 0 ;
1236
1248
uint32_t sType = uint32_t (ShiftOp::kLSL );
@@ -1247,11 +1259,17 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
1247
1259
if (sType <= uint32_t (ShiftOp::kASR )) {
1248
1260
bool hasSP = o0.as <Gp>().isSP () || o1.as <Gp>().isSP ();
1249
1261
if (!hasSP) {
1250
- if (!checkGpId (o0, o1, kZR ))
1262
+ if (!checkSignature (o1, o2)) {
1263
+ goto InvalidInstruction;
1264
+ }
1265
+
1266
+ if (!checkGpId (o0, o1, kZR )) {
1251
1267
goto InvalidPhysId;
1268
+ }
1252
1269
1253
- if (shift >= opSize)
1270
+ if (shift >= opSize) {
1254
1271
goto InvalidImmediate;
1272
+ }
1255
1273
1256
1274
opcode.reset (uint32_t (opData.shiftedOp ) << 21 );
1257
1275
opcode.addImm (x, 31 );
@@ -1264,17 +1282,20 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
1264
1282
}
1265
1283
1266
1284
// SP register can only be used with LSL or Extend.
1267
- if (sType != uint32_t (ShiftOp::kLSL ))
1285
+ if (sType != uint32_t (ShiftOp::kLSL )) {
1268
1286
goto InvalidImmediate;
1287
+ }
1288
+
1269
1289
sType = x ? uint32_t (ShiftOp::kUXTX ) : uint32_t (ShiftOp::kUXTW );
1270
1290
}
1271
1291
1272
1292
// Extend operation - UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX.
1273
1293
opcode.reset (uint32_t (opData.extendedOp ) << 21 );
1274
1294
sType -= uint32_t (ShiftOp::kUXTB );
1275
1295
1276
- if (sType > 7 || shift > 4 )
1296
+ if (sType > 7 || shift > 4 ) {
1277
1297
goto InvalidImmediate;
1298
+ }
1278
1299
1279
1300
if (!(opcode.get () & B (29 ))) {
1280
1301
// ADD|SUB (extend) - ZR is not allowed.
@@ -1287,6 +1308,11 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
1287
1308
goto InvalidPhysId;
1288
1309
}
1289
1310
1311
+ // Validate whether the register operands match extend option.
1312
+ if (o2.as <Reg>().type () != extendOptionToRegType (sType ) || o1.as <Reg>().type () < o2.as <Reg>().type ()) {
1313
+ goto InvalidInstruction;
1314
+ }
1315
+
1290
1316
opcode.addImm (x, 31 );
1291
1317
opcode.addReg (o2, 16 );
1292
1318
opcode.addImm (sType , 13 );
@@ -1412,9 +1438,6 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
1412
1438
}
1413
1439
1414
1440
if (isign4 == ENC_OPS2 (Reg, Reg) || isign4 == ENC_OPS3 (Reg, Reg, Imm)) {
1415
- if (!checkSignature (o0, o1))
1416
- goto InvalidInstruction;
1417
-
1418
1441
uint32_t opSize = x ? 64 : 32 ;
1419
1442
uint32_t sType = 0 ;
1420
1443
uint64_t shift = 0 ;
@@ -1429,8 +1452,13 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
1429
1452
// Shift operation - LSL, LSR, ASR.
1430
1453
if (sType <= uint32_t (ShiftOp::kASR )) {
1431
1454
if (!hasSP) {
1432
- if (shift >= opSize)
1455
+ if (!checkSignature (o0, o1)) {
1456
+ goto InvalidInstruction;
1457
+ }
1458
+
1459
+ if (shift >= opSize) {
1433
1460
goto InvalidImmediate;
1461
+ }
1434
1462
1435
1463
opcode.reset (uint32_t (opData.shiftedOp ) << 21 );
1436
1464
opcode.addImm (x, 31 );
@@ -1451,8 +1479,14 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
1451
1479
1452
1480
// Extend operation - UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX.
1453
1481
sType -= uint32_t (ShiftOp::kUXTB );
1454
- if (sType > 7 || shift > 4 )
1482
+ if (sType > 7 || shift > 4 ) {
1455
1483
goto InvalidImmediate;
1484
+ }
1485
+
1486
+ // Validate whether the register operands match extend option.
1487
+ if (o1.as <Reg>().type () != extendOptionToRegType (sType ) || o0.as <Reg>().type () < o1.as <Reg>().type ()) {
1488
+ goto InvalidInstruction;
1489
+ }
1456
1490
1457
1491
opcode.reset (uint32_t (opData.extendedOp ) << 21 );
1458
1492
opcode.addImm (x, 31 );
0 commit comments