From b287ff0ddbfb997663ca9432ca3456e3d15ae9ed Mon Sep 17 00:00:00 2001 From: Jin Kyu Song Date: Wed, 4 Dec 2013 20:05:55 -0800 Subject: [PATCH] bnd: Add a new nobnd prefix bnd and nobnd prifixes can be used for each instruction line to direct whether bnd registers should be preserved or not. And those are also added as options for DEFAULT directive. Once bnd is set with default, DEFAULT BND, all bnd-prefix available instructions are prefixed with bnd. To override it, nobnd prefix can be used. In the other way, DEFAULT NOBND can disable DEFAULT BND and have nasm encode in the normal way. Signed-off-by: Jin Kyu Song --- assemble.c | 27 +++++++++++++++++++++++++-- nasm.c | 9 ++++++++- nasm.h | 2 ++ parser.c | 1 + standard.mac | 13 +++++++++++++ tokens.dat | 1 + 6 files changed, 50 insertions(+), 3 deletions(-) diff --git a/assemble.c b/assemble.c index f06cee8..bdf9a10 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 d10ddbc..2bb3029 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 f499c49..736c290 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 4f0898c..2d8d4ff 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 b2dff8d..60c0387 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 09d4b9f..0e44641 100644 --- a/tokens.dat +++ b/tokens.dat @@ -55,6 +55,7 @@ wait xacquire xrelease bnd +nobnd % TOKEN_SPECIAL, 0, 0, S_* abs -- 2.7.4