1
1
/* ----------------------------------------------------------------------- *
2
2
*
3
- * Copyright 1996-2023 The NASM Authors - All Rights Reserved
3
+ * Copyright 1996-2024 The NASM Authors - All Rights Reserved
4
4
* See the file AUTHORS included with the NASM distribution for
5
5
* the specific copyright holders.
6
6
*
@@ -109,9 +109,18 @@ static void add_asp(insn *, int);
109
109
static int process_ea (operand * , ea * , int , int , opflags_t ,
110
110
insn * , enum ea_type , const char * * );
111
111
112
+ /* Get the pointer to an operand if it exits */
113
+ static inline struct operand * get_operand (insn * ins , unsigned int n )
114
+ {
115
+ if (n >= (unsigned int )ins -> operands )
116
+ return NULL ;
117
+ else
118
+ return & ins -> oprs [n ];
119
+ }
120
+
112
121
static inline bool absolute_op (const struct operand * o )
113
122
{
114
- return o -> segment == NO_SEG && o -> wrt == NO_SEG &&
123
+ return o && o -> segment == NO_SEG && o -> wrt == NO_SEG &&
115
124
!(o -> opflags & OPFLAG_RELATIVE );
116
125
}
117
126
@@ -537,8 +546,9 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits,
537
546
const uint8_t * code = temp -> code ;
538
547
uint8_t c = code [0 ];
539
548
bool is_byte ;
549
+ const struct operand * const op0 = get_operand (ins , 0 );
540
550
541
- if (((c & ~1 ) != 0370 ) || (ins -> oprs [ 0 ]. type & STRICT ))
551
+ if (((c & ~1 ) != 0370 ) || (op0 -> type & STRICT ))
542
552
return false;
543
553
if (!optimizing .level || (optimizing .flag & OPTIM_DISABLE_JMP_MATCH ))
544
554
return false;
@@ -547,14 +557,14 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits,
547
557
548
558
isize = calcsize (segment , offset , bits , ins , temp );
549
559
550
- if (ins -> oprs [ 0 ]. opflags & OPFLAG_UNKNOWN )
560
+ if (op0 -> opflags & OPFLAG_UNKNOWN )
551
561
/* Be optimistic in pass 1 */
552
562
return true;
553
563
554
- if (ins -> oprs [ 0 ]. segment != segment )
564
+ if (op0 -> segment != segment )
555
565
return false;
556
566
557
- isize = ins -> oprs [ 0 ]. offset - offset - isize ; /* isize is delta */
567
+ isize = op0 -> offset - offset - isize ; /* isize is delta */
558
568
is_byte = (isize >= -128 && isize <= 127 ); /* is it byte size? */
559
569
560
570
if (is_byte && c == 0371 && ins -> prefixes [PPS_REP ] == P_BND ) {
@@ -1211,7 +1221,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
1211
1221
uint8_t c ;
1212
1222
int rex_mask = ~0 ;
1213
1223
int op1 , op2 ;
1214
- struct operand * opx ;
1224
+ struct operand * opx , * opy ;
1215
1225
uint8_t opex = 0 ;
1216
1226
enum ea_type eat ;
1217
1227
uint8_t hleok = 0 ;
@@ -1232,8 +1242,9 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
1232
1242
while (* codes ) {
1233
1243
c = * codes ++ ;
1234
1244
op1 = (c & 3 ) + ((opex & 1 ) << 2 );
1245
+ opx = get_operand (ins , op1 );
1235
1246
op2 = ((c >> 3 ) & 3 ) + ((opex & 2 ) << 1 );
1236
- opx = & ins -> oprs [ op1 ] ;
1247
+ opy = NULL ;
1237
1248
opex = 0 ; /* For the next iteration */
1238
1249
1239
1250
switch (c ) {
@@ -1310,8 +1321,8 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
1310
1321
case 0171 :
1311
1322
c = * codes ++ ;
1312
1323
op2 = (op2 & ~3 ) | ((c >> 3 ) & 3 );
1313
- opx = & ins -> oprs [ op2 ] ;
1314
- ins -> rex |= op_rexflags (opx , REX_R |REX_H |REX_P |REX_W );
1324
+ opy = get_operand ( ins , op2 ) ;
1325
+ ins -> rex |= op_rexflags (opy , REX_R |REX_H |REX_P |REX_W );
1315
1326
length ++ ;
1316
1327
break ;
1317
1328
@@ -1479,14 +1490,15 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
1479
1490
*! severe programming error as the code could break at
1480
1491
*! any time for any number of reasons.
1481
1492
*/
1482
- if (!absolute_op (& ins -> oprs [0 ]))
1493
+ /* The bytecode ends in 0, so opx points to operand 0 */
1494
+ if (!absolute_op (opx ))
1483
1495
nasm_nonfatal ("attempt to reserve non-constant"
1484
1496
" quantity of BSS space" );
1485
- else if (ins -> oprs [ 0 ]. opflags & OPFLAG_FORWARD )
1497
+ else if (opx -> opflags & OPFLAG_FORWARD )
1486
1498
nasm_warn (WARN_FORWARD , "forward reference in RESx "
1487
1499
"can have unpredictable results" );
1488
1500
else
1489
- length += ins -> oprs [ 0 ]. offset * resb_bytes (ins -> opcode );
1501
+ length += opx -> offset * resb_bytes (ins -> opcode );
1490
1502
break ;
1491
1503
1492
1504
case 0341 :
@@ -1546,8 +1558,9 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
1546
1558
ea ea_data ;
1547
1559
int rfield ;
1548
1560
opflags_t rflags ;
1549
- struct operand * opy = & ins -> oprs [op2 ];
1550
- struct operand * op_er_sae ;
1561
+ const struct operand * op_er_sae ;
1562
+
1563
+ opy = get_operand (ins , op2 );
1551
1564
1552
1565
ea_data .rex = 0 ; /* Ensure ea.REX is initially 0 */
1553
1566
@@ -1558,11 +1571,11 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
1558
1571
} else {
1559
1572
rflags = 0 ;
1560
1573
rfield = c & 7 ;
1574
+ opx = NULL ;
1561
1575
}
1562
1576
1563
1577
/* EVEX.b1 : evex_brerop contains the operand position */
1564
- op_er_sae = (ins -> evex_brerop >= 0 ?
1565
- & ins -> oprs [ins -> evex_brerop ] : NULL );
1578
+ op_er_sae = ins -> evex_brerop ;
1566
1579
1567
1580
if (op_er_sae && (op_er_sae -> decoflags & (ER | SAE ))) {
1568
1581
/* set EVEX.b */
@@ -1888,7 +1901,7 @@ static void gencode(struct out_data *data, insn *ins)
1888
1901
uint8_t bytes [4 ];
1889
1902
int64_t size ;
1890
1903
int op1 , op2 ;
1891
- struct operand * opx ;
1904
+ struct operand * opx , * opy ;
1892
1905
const uint8_t * codes = data -> itemp -> code ;
1893
1906
uint8_t opex = 0 ;
1894
1907
enum ea_type eat = EA_SCALAR ;
@@ -1903,8 +1916,9 @@ static void gencode(struct out_data *data, insn *ins)
1903
1916
while (* codes ) {
1904
1917
c = * codes ++ ;
1905
1918
op1 = (c & 3 ) + ((opex & 1 ) << 2 );
1919
+ opx = get_operand (ins , op1 );
1906
1920
op2 = ((c >> 3 ) & 3 ) + ((opex & 2 ) << 1 );
1907
- opx = & ins -> oprs [ op1 ] ;
1921
+ opy = NULL ;
1908
1922
opex = 0 ; /* For the next iteration */
1909
1923
1910
1924
@@ -2013,11 +2027,11 @@ static void gencode(struct out_data *data, insn *ins)
2013
2027
const struct operand * opy ;
2014
2028
2015
2029
c = * codes ++ ;
2016
- opx = & ins -> oprs [ c >> 3 ] ;
2017
- opy = & ins -> oprs [ c & 7 ] ;
2030
+ opx = get_operand ( ins , op1 = ( c >> 3 ) & 7 ) ;
2031
+ opy = get_operand ( ins , op2 = c & 7 ) ;
2018
2032
if (!absolute_op (opy ))
2019
2033
nasm_nonfatal ("non-absolute expression not permitted "
2020
- "as argument %d" , c & 7 );
2034
+ "as argument %d" , op2 );
2021
2035
else if (opy -> offset & ~mask )
2022
2036
nasm_warn (ERR_PASS2 |WARN_NUMBER_OVERFLOW ,
2023
2037
"is4 argument exceeds bounds" );
@@ -2027,7 +2041,7 @@ static void gencode(struct out_data *data, insn *ins)
2027
2041
2028
2042
case 0173 :
2029
2043
c = * codes ++ ;
2030
- opx = & ins -> oprs [ c >> 4 ] ;
2044
+ opx = get_operand ( ins , op1 = c >> 4 ) ;
2031
2045
c &= 15 ;
2032
2046
goto emit_is4 ;
2033
2047
@@ -2250,7 +2264,8 @@ static void gencode(struct out_data *data, insn *ins)
2250
2264
int rfield ;
2251
2265
opflags_t rflags ;
2252
2266
uint8_t * p ;
2253
- struct operand * opy = & ins -> oprs [op2 ];
2267
+
2268
+ opy = get_operand (ins , op2 );
2254
2269
2255
2270
if (c <= 0177 ) {
2256
2271
/* pick rfield from operand b (opx) */
@@ -2260,6 +2275,7 @@ static void gencode(struct out_data *data, insn *ins)
2260
2275
/* rfield is constant */
2261
2276
rflags = 0 ;
2262
2277
rfield = c & 7 ;
2278
+ opx = NULL ;
2263
2279
}
2264
2280
2265
2281
if (process_ea (opy , & ea_data , bits ,
@@ -2390,16 +2406,10 @@ static enum match_result find_match(const struct itemplate **tempp,
2390
2406
enum match_result m , merr ;
2391
2407
opflags_t xsizeflags [MAX_OPERANDS ];
2392
2408
bool opsizemissing = false;
2393
- int8_t broadcast = instruction -> evex_brerop ;
2394
2409
int i ;
2395
2410
2396
- /* broadcasting uses a different data element size */
2397
- for (i = 0 ; i < instruction -> operands ; i ++ ) {
2398
- if (i == broadcast )
2399
- xsizeflags [i ] = instruction -> oprs [i ].decoflags & BRSIZE_MASK ;
2400
- else
2401
- xsizeflags [i ] = instruction -> oprs [i ].type & SIZE_MASK ;
2402
- }
2411
+ for (i = 0 ; i < instruction -> operands ; i ++ )
2412
+ xsizeflags [i ] = instruction -> oprs [i ].xsize ;
2403
2413
2404
2414
merr = MERR_INVALOP ;
2405
2415
@@ -2415,11 +2425,12 @@ static enum match_result find_match(const struct itemplate **tempp,
2415
2425
/*
2416
2426
* Missing operand size and a candidate for fuzzy matching...
2417
2427
*/
2418
- for (i = 0 ; i < temp -> operands ; i ++ )
2419
- if (i == broadcast )
2428
+ for (i = 0 ; i < temp -> operands ; i ++ ) {
2429
+ if (instruction -> oprs [ i ]. bcast )
2420
2430
xsizeflags [i ] |= temp -> deco [i ] & BRSIZE_MASK ;
2421
2431
else
2422
2432
xsizeflags [i ] |= temp -> opd [i ] & SIZE_MASK ;
2433
+ }
2423
2434
opsizemissing = true;
2424
2435
}
2425
2436
if (m > merr )
@@ -2433,23 +2444,24 @@ static enum match_result find_match(const struct itemplate **tempp,
2433
2444
goto done ;
2434
2445
2435
2446
for (i = 0 ; i < instruction -> operands ; i ++ ) {
2447
+ struct operand * op = & instruction -> oprs [i ];
2436
2448
/*
2437
2449
* We ignore extrinsic operand sizes on registers, so we should
2438
2450
* never try to fuzzy-match on them. This also resolves the case
2439
2451
* when we have e.g. "xmmrm128" in two different positions.
2440
2452
*/
2441
- if (is_class (REGISTER , instruction -> oprs [ i ]. type ))
2453
+ if (is_class (REGISTER , op -> type ))
2442
2454
continue ;
2443
2455
2444
2456
/* This tests if xsizeflags[i] has more than one bit set */
2445
2457
if ((xsizeflags [i ] & (xsizeflags [i ]- 1 )))
2446
2458
goto done ; /* No luck */
2447
2459
2448
- if (i == broadcast ) {
2449
- instruction -> oprs [ i ]. decoflags |= xsizeflags [i ];
2450
- instruction -> oprs [ i ]. type |= brsize_to_size (xsizeflags [i ]);
2460
+ if (op -> bcast ) {
2461
+ op -> decoflags |= xsizeflags [i ];
2462
+ op -> type |= brsize_to_size (xsizeflags [i ]);
2451
2463
} else {
2452
- instruction -> oprs [ i ]. type |= xsizeflags [i ]; /* Set the size */
2464
+ op -> type |= xsizeflags [i ]; /* Set the size */
2453
2465
}
2454
2466
}
2455
2467
0 commit comments