2003-03-21  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/4218
	* config/tc-i386.c (match_template): Properly handle 64bit mode
	"xchg %eax, %eax".

gas/testsuite/

2003-03-21  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/4218
	* gas/i386/nops.s: Add testcases for nop r/m.
	* gas/i386/x86-64-nops.s: Likewise.

	* gas/i386/x86-64-opcode.s: Add testcases for xchg with %ax,
	%eax and %rax.

	* gas/i386/nops.d: Updated.
	* gas/i386/x86-64-nops.d: Likewise.
	* gas/i386/x86-64-opcode.d: Likewise.

opcodes/

2003-03-21  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/4218
	* i386-dis.c (PREGRP38): New.
	(dis386): Use PREGRP38 for 0x90.
	(prefix_user_table): Add PREGRP38.
	(print_insn): Set uses_REPZ_prefix to 1 for pause.
	(NOP_Fixup1): Properly handle REX bits.
	(NOP_Fixup2): Likewise.

	* i386-opc.c (i386_optab): Allow %eax with xchg in 64bit.
	Allow register with nop.
This commit is contained in:
H.J. Lu 2007-03-21 20:45:14 +00:00
parent ffa8bd48e3
commit 8b38ad713b
12 changed files with 143 additions and 18 deletions

View File

@ -1,3 +1,9 @@
2003-03-21 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/4218
* config/tc-i386.c (match_template): Properly handle 64bit mode
"xchg %eax, %eax".
2007-03-21 Anton Ertl <anton@mips.complang.tuw> 2007-03-21 Anton Ertl <anton@mips.complang.tuw>
PR gas/4124 PR gas/4124

View File

@ -2621,6 +2621,15 @@ match_template (void)
continue; continue;
break; break;
case 2: case 2:
/* xchg %eax, %eax is a special case. It is an aliase for nop
only in 32bit mode and we can use opcode 0x90. In 64bit
mode, we can't use 0x90 for xchg %eax, %eax since it should
zero-extend %eax to %rax. */
if (flag_code == CODE_64BIT
&& t->base_opcode == 0x90
&& i.types [0] == (Acc | Reg32)
&& i.types [1] == (Acc | Reg32))
continue;
case 3: case 3:
case 4: case 4:
overlap1 = i.types[1] & operand_types[1]; overlap1 = i.types[1] & operand_types[1];

View File

@ -1,3 +1,16 @@
2003-03-21 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/4218
* gas/i386/nops.s: Add testcases for nop r/m.
* gas/i386/x86-64-nops.s: Likewise.
* gas/i386/x86-64-opcode.s: Add testcases for xchg with %ax,
%eax and %rax.
* gas/i386/nops.d: Updated.
* gas/i386/x86-64-nops.d: Likewise.
* gas/i386/x86-64-opcode.d: Likewise.
2003-03-21 H.J. Lu <hongjiu.lu@intel.com> 2003-03-21 H.J. Lu <hongjiu.lu@intel.com>
* gas/i386/i386.exp: Run nops-3. * gas/i386/i386.exp: Run nops-3.

View File

@ -14,4 +14,11 @@ Disassembly of section .text:
[ ]*19:[ ]+0f 1f 84 00 00 00 00 00[ ]+nopl[ ]+0x0\(%eax,%eax,1\) [ ]*19:[ ]+0f 1f 84 00 00 00 00 00[ ]+nopl[ ]+0x0\(%eax,%eax,1\)
[ ]*21:[ ]+66 0f 1f 84 00 00 00 00 00[ ]+nopw[ ]+0x0\(%eax,%eax,1\) [ ]*21:[ ]+66 0f 1f 84 00 00 00 00 00[ ]+nopw[ ]+0x0\(%eax,%eax,1\)
[ ]*2a:[ ]+66 2e 0f 1f 84 00 00 00 00 00[ ]+nopw[ ]+%cs:0x0\(%eax,%eax,1\) [ ]*2a:[ ]+66 2e 0f 1f 84 00 00 00 00 00[ ]+nopw[ ]+%cs:0x0\(%eax,%eax,1\)
[ ]*34:[ ]+0f 1f 00[ ]+nopl[ ]+\(%eax\)
[ ]*37:[ ]+0f 1f c0[ ]+nop[ ]+%eax
[ ]*3a:[ ]+66 0f 1f c0[ ]+nop[ ]+%ax
[ ]*3e:[ ]+0f 1f 00[ ]+nopl[ ]+\(%eax\)
[ ]*41:[ ]+66 0f 1f 00[ ]+nopw[ ]+\(%eax\)
[ ]*45:[ ]+0f 1f c0[ ]+nop[ ]+%eax
[ ]*48:[ ]+66 0f 1f c0[ ]+nop[ ]+%ax
#pass #pass

View File

@ -9,4 +9,12 @@
.byte 0x66, 0x0f, 0x1f, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0 .byte 0x66, 0x0f, 0x1f, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0 .byte 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0
nop (%eax)
nop %eax
nop %ax
nopl (%eax)
nopw (%eax)
nopl %eax
nopw %ax
.p2align 4 .p2align 4

View File

@ -14,4 +14,24 @@ Disassembly of section .text:
[ ]*19:[ ]+0f 1f 84 00 00 00 00 00[ ]+nopl[ ]+0x0\(%rax,%rax,1\) [ ]*19:[ ]+0f 1f 84 00 00 00 00 00[ ]+nopl[ ]+0x0\(%rax,%rax,1\)
[ ]*21:[ ]+66 0f 1f 84 00 00 00 00 00[ ]+nopw[ ]+0x0\(%rax,%rax,1\) [ ]*21:[ ]+66 0f 1f 84 00 00 00 00 00[ ]+nopw[ ]+0x0\(%rax,%rax,1\)
[ ]*2a:[ ]+66 2e 0f 1f 84 00 00 00 00 00[ ]+nopw[ ]+%cs:0x0\(%rax,%rax,1\) [ ]*2a:[ ]+66 2e 0f 1f 84 00 00 00 00 00[ ]+nopw[ ]+%cs:0x0\(%rax,%rax,1\)
[ ]*34:[ ]+0f 1f 00[ ]+nopl[ ]+\(%rax\)
[ ]*37:[ ]+48 0f 1f c0[ ]+nop[ ]+%rax
[ ]*3b:[ ]+0f 1f c0[ ]+nop[ ]+%eax
[ ]*3e:[ ]+66 0f 1f c0[ ]+nop[ ]+%ax
[ ]*42:[ ]+48 0f 1f 00[ ]+nopq[ ]+\(%rax\)
[ ]*46:[ ]+0f 1f 00[ ]+nopl[ ]+\(%rax\)
[ ]*49:[ ]+66 0f 1f 00[ ]+nopw[ ]+\(%rax\)
[ ]*4d:[ ]+48 0f 1f c0[ ]+nop[ ]+%rax
[ ]*51:[ ]+0f 1f c0[ ]+nop[ ]+%eax
[ ]*54:[ ]+66 0f 1f c0[ ]+nop[ ]+%ax
[ ]*58:[ ]+41 0f 1f 02[ ]+nopl[ ]+\(%r10\)
[ ]*5c:[ ]+49 0f 1f c2[ ]+nop[ ]+%r10
[ ]*60:[ ]+41 0f 1f c2[ ]+nop[ ]+%r10d
[ ]*64:[ ]+66 41 0f 1f c2[ ]+nop[ ]+%r10w
[ ]*69:[ ]+49 0f 1f 02[ ]+nopq[ ]+\(%r10\)
[ ]*6d:[ ]+41 0f 1f 02[ ]+nopl[ ]+\(%r10\)
[ ]*71:[ ]+66 41 0f 1f 02[ ]+nopw[ ]+\(%r10\)
[ ]*76:[ ]+49 0f 1f c2[ ]+nop[ ]+%r10
[ ]*7a:[ ]+41 0f 1f c2[ ]+nop[ ]+%r10d
[ ]*7e:[ ]+66 41 0f 1f c2[ ]+nop[ ]+%r10w
#pass #pass

View File

@ -9,4 +9,25 @@
.byte 0x66, 0x0f, 0x1f, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0 .byte 0x66, 0x0f, 0x1f, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0
.byte 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0 .byte 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0
nop (%rax)
nop %rax
nop %eax
nop %ax
nopq (%rax)
nopl (%rax)
nopw (%rax)
nopq %rax
nopl %eax
nopw %ax
nop (%r10)
nop %r10
nop %r10d
nop %r10w
nopq (%r10)
nopl (%r10)
nopw (%r10)
nopq %r10
nopl %r10d
nopw %r10w
.p2align 4 .p2align 4

View File

@ -274,6 +274,16 @@ Disassembly of section .text:
[ ]*[0-9a-f]+:[ ]+90[ ]+nop[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+90[ ]+nop[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+48 90[ ]+rex64 nop[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+48 90[ ]+rex64 nop[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+49 90[ ]+xchg[ ]+%rax,%r8[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+49 90[ ]+xchg[ ]+%rax,%r8[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+41 90[ ]+xchg[ ]+%eax,%r8d[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+41 90[ ]+xchg[ ]+%eax,%r8d[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+41 91[ ]+xchg[ ]+%eax,%r9d[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+41 91[ ]+xchg[ ]+%eax,%r9d[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+93[ ]+xchg[ ]+%eax,%ebx[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+93[ ]+xchg[ ]+%eax,%ebx[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+66 41 90[ ]+xchg[ ]+%ax,%r8w[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+66 41 90[ ]+xchg[ ]+%ax,%r8w[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+66 41 91[ ]+xchg[ ]+%ax,%r9w[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+66 41 91[ ]+xchg[ ]+%ax,%r9w[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+48 0f 01 e0[ ]+smsw[ ]+%rax[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+48 0f 01 e0[ ]+smsw[ ]+%rax[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+0f 01 e0[ ]+smsw[ ]+%eax[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+0f 01 e0[ ]+smsw[ ]+%eax[ ]*(#.*)*
[ ]*[0-9a-f]+:[ ]+66 0f 01 e0[ ]+smsw[ ]+%ax[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+66 0f 01 e0[ ]+smsw[ ]+%ax[ ]*(#.*)*

View File

@ -397,6 +397,16 @@
xchg %rax,%rax # -- -- -- -- 90 xchg %rax,%rax # -- -- -- -- 90
rex64 xchg %rax,%rax # -- -- -- 48 90 rex64 xchg %rax,%rax # -- -- -- 48 90
xchg %rax,%r8 # -- -- -- 49 90 xchg %rax,%r8 # -- -- -- 49 90
xchg %eax,%r8d # -- -- -- 41 90
xchg %r8d,%eax # -- -- -- 41 90
xchg %eax,%r9d # -- -- -- 41 91
xchg %r9d,%eax # -- -- -- 41 91
xchg %ebx,%eax # -- -- -- 93
xchg %eax,%ebx # -- -- -- 93
xchg %ax,%r8w # -- -- -- 66 41 90
xchg %r8w,%ax # -- -- -- 66 41 90
xchg %ax,%r9w # -- -- -- 66 41 91
xchg %r9w,%ax # -- -- -- 66 41 91
smsw %rax # -- -- -- 48 0F 01 e0 smsw %rax # -- -- -- 48 0F 01 e0
smsw %eax # -- -- -- -- 0F 01 e0 smsw %eax # -- -- -- -- 0F 01 e0

View File

@ -1,3 +1,16 @@
2003-03-21 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/4218
* i386-dis.c (PREGRP38): New.
(dis386): Use PREGRP38 for 0x90.
(prefix_user_table): Add PREGRP38.
(print_insn): Set uses_REPZ_prefix to 1 for pause.
(NOP_Fixup1): Properly handle REX bits.
(NOP_Fixup2): Likewise.
* i386-opc.c (i386_optab): Allow %eax with xchg in 64bit.
Allow register with nop.
2007-03-20 DJ Delorie <dj@redhat.com> 2007-03-20 DJ Delorie <dj@redhat.com>
* m32c-asm.c: Regenerate. * m32c-asm.c: Regenerate.

View File

@ -467,6 +467,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
#define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } } #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
#define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } } #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
#define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } } #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
#define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } } #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
@ -692,7 +693,7 @@ static const struct dis386 dis386[] = {
{ "movD", { Sw, Sv } }, { "movD", { Sw, Sv } },
{ "popU", { stackEv } }, { "popU", { stackEv } },
/* 90 */ /* 90 */
{ "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } }, { PREGRP38 },
{ "xchgS", { RMeCX, eAX } }, { "xchgS", { RMeCX, eAX } },
{ "xchgS", { RMeDX, eAX } }, { "xchgS", { RMeDX, eAX } },
{ "xchgS", { RMeBX, eAX } }, { "xchgS", { RMeBX, eAX } },
@ -2017,6 +2018,14 @@ static const struct dis386 prefix_user_table[][4] = {
{ "(bad)", { XX } }, { "(bad)", { XX } },
{ "(bad)", { XX } }, { "(bad)", { XX } },
}, },
/* PREGRP38 */
{
{ "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
{ "pause", { XX } },
{ "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
{ "(bad)", { XX } },
},
}; };
static const struct dis386 x86_64_table[][2] = { static const struct dis386 x86_64_table[][2] = {
@ -3091,7 +3100,8 @@ print_insn (bfd_vma pc, disassemble_info *info)
need_modrm = onebyte_has_modrm[*codep]; need_modrm = onebyte_has_modrm[*codep];
uses_DATA_prefix = 0; uses_DATA_prefix = 0;
uses_REPNZ_prefix = 0; uses_REPNZ_prefix = 0;
uses_REPZ_prefix = 0; /* pause is 0xf3 0x90. */
uses_REPZ_prefix = *codep == 0x90;
uses_LOCK_prefix = 0; uses_LOCK_prefix = 0;
codep++; codep++;
} }
@ -5284,17 +5294,15 @@ OP_0fae (int bytemode, int sizeflag)
} }
/* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix 32bit mode and "xchg %rax,%rax" in 64bit mode. */
is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
*/
static void static void
NOP_Fixup1 (int bytemode, int sizeflag) NOP_Fixup1 (int bytemode, int sizeflag)
{ {
if (prefixes == PREFIX_REPZ) if ((prefixes & PREFIX_DATA) != 0
strcpy (obuf, "pause"); || (rex != 0
else if (prefixes == PREFIX_DATA && rex != 0x48
|| ((rex & REX_MODE64) && rex != 0x48)) && address_mode == mode_64bit))
OP_REG (bytemode, sizeflag); OP_REG (bytemode, sizeflag);
else else
strcpy (obuf, "nop"); strcpy (obuf, "nop");
@ -5303,8 +5311,10 @@ NOP_Fixup1 (int bytemode, int sizeflag)
static void static void
NOP_Fixup2 (int bytemode, int sizeflag) NOP_Fixup2 (int bytemode, int sizeflag)
{ {
if (prefixes == PREFIX_DATA if ((prefixes & PREFIX_DATA) != 0
|| ((rex & REX_MODE64) && rex != 0x48)) || (rex != 0
&& rex != 0x48
&& address_mode == mode_64bit))
OP_IMREG (bytemode, sizeflag); OP_IMREG (bytemode, sizeflag);
} }

View File

@ -144,12 +144,10 @@ const template i386_optab[] =
xchg commutes: we allow both operand orders. xchg commutes: we allow both operand orders.
In the 64bit code, xchg rax, rax is reused for new nop instruction. */ In the 64bit code, xchg rax, rax is reused for new nop instruction. */
{"xchg", 2, 0x90, X, CpuNo64, wl_Suf|ShortForm, { WordReg, Acc, 0 } }, {"xchg", 2, 0x90, X, 0, wlq_Suf|ShortForm, { WordReg, Acc, 0 } },
{"xchg", 2, 0x90, X, CpuNo64, wl_Suf|ShortForm, { Acc, WordReg, 0 } }, {"xchg", 2, 0x90, X, 0, wlq_Suf|ShortForm, { Acc, WordReg, 0 } },
{"xchg", 2, 0x90, X, Cpu64, wq_Suf|ShortForm, { Reg16|Reg64, Acc, 0 } }, {"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } },
{"xchg", 2, 0x90, X, Cpu64, wq_Suf|ShortForm, { Acc, Reg16|Reg64, 0 } }, {"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, Reg, 0 } },
{"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } },
{"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, Reg, 0 } },
/* In/out from ports. */ /* In/out from ports. */
/* XXX should reject %rax */ /* XXX should reject %rax */
@ -517,7 +515,7 @@ const template i386_optab[] =
{"hlt", 0, 0xf4, X, 0, NoSuf, { 0, 0, 0} }, {"hlt", 0, 0xf4, X, 0, NoSuf, { 0, 0, 0} },
{"nop", 1, 0x0f1f, X, Cpu686, wl_Suf|Modrm, { WordMem, 0, 0} }, {"nop", 1, 0x0f1f, 0, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, 0, 0} },
/* nop is actually "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in /* nop is actually "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
32bit mode and "xchg %rax,%rax" in 64bit mode. */ 32bit mode and "xchg %rax,%rax" in 64bit mode. */