BR 3392279: Fix duplicated REX prefixes
authorH. Peter Anvin <hpa@zytor.com>
Wed, 21 May 2014 15:19:16 +0000 (08:19 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Wed, 21 May 2014 15:24:21 +0000 (08:24 -0700)
The fix for BR 3392278:

aa29b1d93f5a assemble.c: Don't drop rex prefix from instruction itself

... would cause multiple REX prefixes to be emitted for some
instructions.  Create a new flag to indicate that REX has already been
emitted, which can be cleared for each instance of an instruction.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
assemble.c
nasm.h
test/times.asm [new file with mode: 0644]

index e9cd70f..ff3cea7 100644 (file)
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 1996-2013 The NASM Authors - All Rights Reserved
+ *   Copyright 1996-2014 The NASM Authors - All Rights Reserved
  *   See the file AUTHORS included with the NASM distribution for
  *   the specific copyright holders.
  *
@@ -1365,9 +1365,12 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
 static inline unsigned int emit_rex(insn *ins, int32_t segment, int64_t offset, int bits)
 {
     if (bits == 64) {
-        if ((ins->rex & REX_REAL) && !(ins->rex & (REX_V | REX_EV))) {
+        if ((ins->rex & REX_REAL) &&
+            !(ins->rex & (REX_V | REX_EV)) &&
+            !ins->rex_done) {
             int rex = (ins->rex & REX_REAL) | REX_P;
             out(offset, segment, &rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
+            ins->rex_done = true;
             return 1;
         }
     }
@@ -1389,6 +1392,8 @@ static void gencode(int32_t segment, int64_t offset, int bits,
     uint8_t opex = 0;
     enum ea_type eat = EA_SCALAR;
 
+    ins->rex_done = false;
+
     while (*codes) {
         c = *codes++;
         op1 = (c & 3) + ((opex & 1) << 2);
diff --git a/nasm.h b/nasm.h
index 18de37c..666d749 100644 (file)
--- a/nasm.h
+++ b/nasm.h
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *   
- *   Copyright 1996-2013 The NASM Authors - All Rights Reserved
+ *   Copyright 1996-2014 The NASM Authors - All Rights Reserved
  *   See the file AUTHORS included with the NASM distribution for
  *   the specific copyright holders.
  *
@@ -702,6 +702,7 @@ typedef struct insn { /* an instruction itself */
     int             eops_float;             /* true if DD and floating */
     int32_t         times;                  /* repeat count (TIMES prefix) */
     bool            forw_ref;               /* is there a forward reference? */
+    bool            rex_done;               /* REX prefix emitted? */
     int             rex;                    /* Special REX Prefix */
     int             vexreg;                 /* Register encoded in VEX prefix */
     int             vex_cm;                 /* Class and M field for VEX prefix */
diff --git a/test/times.asm b/test/times.asm
new file mode 100644 (file)
index 0000000..a8e3d58
--- /dev/null
@@ -0,0 +1,8 @@
+       bits 64
+
+; Broken per BR 3392278
+       times 4 paddd xmm8, xmm11
+
+; Broken per BR 3392279
+       bswap r12d
+       times 4 bswap r12d