summaryrefslogtreecommitdiff
path: root/assemble.c
diff options
context:
space:
mode:
authorJin Kyu Song <jin.kyu.song@intel.com>2013-12-04 20:05:55 -0800
committerJin Kyu Song <jin.kyu.song@intel.com>2013-12-04 20:10:08 -0800
commitb287ff0ddbfb997663ca9432ca3456e3d15ae9ed (patch)
tree2b5e8c2f5830eedc53b61458137a1f69a296bb0f /assemble.c
parentbb8cf3fa77e63f7c6a02d23bbfe3426beff26358 (diff)
downloadnasm-b287ff0ddbfb997663ca9432ca3456e3d15ae9ed.tar.gz
nasm-b287ff0ddbfb997663ca9432ca3456e3d15ae9ed.tar.bz2
nasm-b287ff0ddbfb997663ca9432ca3456e3d15ae9ed.zip
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 <jin.kyu.song@intel.com>
Diffstat (limited to 'assemble.c')
-rw-r--r--assemble.c27
1 files changed, 25 insertions, 2 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;
}