diff --git a/assemble.c b/assemble.c index f06cee82..bdf9a10c 100644 --- a/assemble.c +++ b/assemble.c @@ -196,6 +196,7 @@ enum match_result { MERR_BADHLE, MERR_ENCMISMATCH, MERR_BADBND, + MERR_BADREPNE, /* * Matching success; the conditional ones first */ @@ -647,6 +648,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, iflag_t cp, case P_EVEX: case P_VEX3: case P_VEX2: + case P_NOBND: case P_none: break; default: @@ -700,6 +702,11 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, iflag_t cp, case MERR_BADBND: error(ERR_NONFATAL, "bnd prefix is not allowed"); break; + case MERR_BADREPNE: + error(ERR_NONFATAL, "%s prefix is not allowed", + (has_prefix(instruction, PPS_REP, P_REPNE) ? + "repne" : "repnz")); + break; default: error(ERR_NONFATAL, "invalid combination of opcode and operands"); @@ -814,6 +821,7 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, iflag_t cp, case P_EVEX: case P_VEX3: case P_VEX2: + case P_NOBND: case P_none: break; default: @@ -1351,6 +1359,15 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, bad_hle_warn(ins, hleok); + /* + * when BND prefix is set by DEFAULT directive, + * BND prefix is added to every appropriate instruction line + * unless it is overridden by NOBND prefix. + */ + if (globalbnd && + (itemp_has(temp, IF_BND) && !has_prefix(ins, PPS_REP, P_NOBND))) + ins->prefixes[PPS_REP] = P_BND; + return length; } @@ -2328,11 +2345,17 @@ static enum match_result matches(const struct itemplate *itemp, return MOK_JUMP; /* - * Check if BND prefix is allowed + * Check if BND prefix is allowed. + * Other 0xF2 (REPNE/REPNZ) prefix is prohibited. */ if (!itemp_has(itemp, IF_BND) && - has_prefix(instruction, PPS_REP, P_BND)) + (has_prefix(instruction, PPS_REP, P_BND) || + has_prefix(instruction, PPS_REP, P_NOBND))) return MERR_BADBND; + else if (itemp_has(itemp, IF_BND) && + (has_prefix(instruction, PPS_REP, P_REPNE) || + has_prefix(instruction, PPS_REP, P_REPNZ))) + return MERR_BADREPNE; return MOK_GOOD; } diff --git a/nasm.c b/nasm.c index d10ddbcb..2bb30292 100644 --- a/nasm.c +++ b/nasm.c @@ -89,6 +89,7 @@ bool tasm_compatible_mode = false; int pass0, passn; int maxbits = 0; int globalrel = 0; +int globalbnd = 0; static time_t official_compile_time; @@ -1525,7 +1526,7 @@ static void assemble_file(char *fname, StrList **depend_ptr) stdscan_reset(); stdscan_set(value); tokval.t_type = TOKEN_INVALID; - if (stdscan(NULL, &tokval) == TOKEN_SPECIAL) { + if (stdscan(NULL, &tokval) != TOKEN_INVALID) { switch ((int)tokval.t_integer) { case S_REL: globalrel = 1; @@ -1533,6 +1534,12 @@ static void assemble_file(char *fname, StrList **depend_ptr) case S_ABS: globalrel = 0; break; + case P_BND: + globalbnd = 1; + break; + case P_NOBND: + globalbnd = 0; + break; default: err = 1; break; diff --git a/nasm.h b/nasm.h index f499c49a..736c290e 100644 --- a/nasm.h +++ b/nasm.h @@ -564,6 +564,7 @@ enum prefixes { /* instruction prefixes */ P_XACQUIRE, P_XRELEASE, P_BND, + P_NOBND, P_EVEX, P_VEX3, P_VEX2, @@ -1172,6 +1173,7 @@ extern bool tasm_compatible_mode; extern int optimizing; extern int globalbits; /* 16, 32 or 64-bit mode */ extern int globalrel; /* default to relative addressing? */ +extern int globalbnd; /* default to using bnd prefix? */ extern int maxbits; /* max bits supported by output */ /* diff --git a/parser.c b/parser.c index 4f0898c2..2d8d4ff8 100644 --- a/parser.c +++ b/parser.c @@ -90,6 +90,7 @@ static int prefix_slot(int prefix) case P_XACQUIRE: case P_XRELEASE: case P_BND: + case P_NOBND: return PPS_REP; case P_O16: case P_O32: diff --git a/standard.mac b/standard.mac index b2dff8d6..60c0387c 100644 --- a/standard.mac +++ b/standard.mac @@ -205,6 +205,19 @@ [default %1] %endmacro +%imacro userel 0.nolist + [default rel] +%endmacro +%imacro useabs 0.nolist + [default abs] +%endmacro +%imacro usebnd 0.nolist + [default bnd] +%endmacro +%imacro usenobnd 0.nolist + [default nobnd] +%endmacro + %imacro incbin 1-2+.nolist 0 %push %pathsearch %$dep %1 diff --git a/tokens.dat b/tokens.dat index 09d4b9fb..0e446417 100644 --- a/tokens.dat +++ b/tokens.dat @@ -55,6 +55,7 @@ wait xacquire xrelease bnd +nobnd % TOKEN_SPECIAL, 0, 0, S_* abs