bnd: Add a new nobnd prefix
authorJin Kyu Song <jin.kyu.song@intel.com>
Thu, 5 Dec 2013 04:05:55 +0000 (20:05 -0800)
committerJin Kyu Song <jin.kyu.song@intel.com>
Thu, 5 Dec 2013 04:10:08 +0000 (20:10 -0800)
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>
assemble.c
nasm.c
nasm.h
parser.c
standard.mac
tokens.dat

index f06cee8..bdf9a10 100644 (file)
@@ -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 (file)
--- 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 (file)
--- 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 */
 
 /*
index 4f0898c..2d8d4ff 100644 (file)
--- 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:
index b2dff8d..60c0387 100644 (file)
     [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
index 09d4b9f..0e44641 100644 (file)
@@ -55,6 +55,7 @@ wait
 xacquire
 xrelease
 bnd
+nobnd
 
 % TOKEN_SPECIAL, 0, 0, S_*
 abs