BR 3392279: Fix duplicated REX prefixes

The fix for BR 3392278:

aa29b1d93f 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>
This commit is contained in:
H. Peter Anvin 2014-05-21 08:19:16 -07:00
parent 13558c1e7c
commit 0a9250c2ab
3 changed files with 17 additions and 3 deletions

View 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);

3
nasm.h
View 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.
*
@ -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 */

8
test/times.asm Normal file
View file

@ -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