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

emit_rex is supposed to write REX prefix into output stream
if needed, but we happen to drop it off on a first write
which breaks REX required instructions if TIMES directive
is used.

For example the code like

	| times 4		movq	xmm11, xmm11

compiles into

	| 0000000000000000 <.text>:
	|   0:	f3 45 0f 7e db       	movq   %xmm11,%xmm11
	|   5:	f3 0f 7e db          	movq   %xmm3,%xmm3
	|   9:	f3 0f 7e db          	movq   %xmm3,%xmm3
	|   d:	f3 0f 7e db          	movq   %xmm3,%xmm3

instead of proper

	| 0000000000000000 <.text>:
	|   0:	f3 45 0f 7e db       	movq   %xmm11,%xmm11
	|   5:	f3 45 0f 7e db       	movq   %xmm11,%xmm11
	|   a:	f3 45 0f 7e db       	movq   %xmm11,%xmm11
	|   f:	f3 45 0f 7e db       	movq   %xmm11,%xmm11

http://bugzilla.nasm.us/show_bug.cgi?id=3392278

Reported-by: Javier <elpochodelagente@gmail.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
Cyrill Gorcunov 2014-05-05 00:30:58 +04:00 committed by H. Peter Anvin
parent 429beab924
commit aa29b1d93f

View File

@ -1366,9 +1366,8 @@ static inline unsigned int emit_rex(insn *ins, int32_t segment, int64_t offset,
{
if (bits == 64) {
if ((ins->rex & REX_REAL) && !(ins->rex & (REX_V | REX_EV))) {
ins->rex = (ins->rex & REX_REAL) | REX_P;
out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
ins->rex = 0;
int rex = (ins->rex & REX_REAL) | REX_P;
out(offset, segment, &rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
return 1;
}
}