2006-09-23  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/3235
	* config/tc-i386.c (match_template): Check address size prefix
	to turn Disp64/Disp32/Disp16 operand into Disp32/Disp16/Disp32
	operand.

gas/testsuite/

2006-09-23  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/3235
	* gas/i386/addr16.d: New file.
	* gas/i386/addr16.s: Likewise.
	* gas/i386/addr32.d: Likewise.
	* gas/i386/addr32.s: Likewise.

	* gas/i386/i386.exp: Add "addr16" and "addr32".

	* gas/i386/x86-64-addr32.s: Add tests for "add32 mov".
	* gas/i386/x86-64-addr32.d: Updated.

opcodes/

2006-09-23  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/3235
	* i386-dis.c (OP_OFF64): Get 32bit offset if there is an
	address size prefix.
This commit is contained in:
H.J. Lu 2006-09-23 23:10:14 +00:00
parent b41e175056
commit 539e75adb5
12 changed files with 165 additions and 23 deletions

View File

@ -1,3 +1,10 @@
2006-09-23 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/3235
* config/tc-i386.c (match_template): Check address size prefix
to turn Disp64/Disp32/Disp16 operand into Disp32/Disp16/Disp32
operand.
2006-09-22 Alan Modra <amodra@bigpond.net.au>
* config/tc-ppc.c (ppc_symbol_chars): Remove '+' and '-'.

View File

@ -2563,6 +2563,8 @@ match_template ()
unsigned int overlap0, overlap1, overlap2;
unsigned int found_reverse_match;
int suffix_check;
unsigned int operand_types [3];
int addr_prefix_disp;
#define MATCH(overlap, given, template) \
((overlap & ~JumpAbsolute) \
@ -2581,6 +2583,10 @@ match_template ()
overlap1 = 0;
overlap2 = 0;
found_reverse_match = 0;
operand_types [0] = 0;
operand_types [1] = 0;
operand_types [2] = 0;
addr_prefix_disp = -1;
suffix_check = (i.suffix == BYTE_MNEM_SUFFIX
? No_bSuf
: (i.suffix == WORD_MNEM_SUFFIX
@ -2596,6 +2602,8 @@ match_template ()
for (t = current_templates->start; t < current_templates->end; t++)
{
addr_prefix_disp = -1;
/* Must have right number of operands. */
if (i.operands != t->operands)
continue;
@ -2606,6 +2614,10 @@ match_template ()
&& (t->opcode_modifier & IgnoreSize)))
continue;
operand_types [0] = t->operand_types [0];
operand_types [1] = t->operand_types [1];
operand_types [2] = t->operand_types [2];
/* In general, don't allow 64-bit operands in 32-bit mode. */
if (i.suffix == QWORD_MNEM_SUFFIX
&& flag_code != CODE_64BIT
@ -2613,8 +2625,8 @@ match_template ()
? (!(t->opcode_modifier & IgnoreSize)
&& !intel_float_operand (t->name))
: intel_float_operand (t->name) != 2)
&& (!(t->operand_types[0] & (RegMMX | RegXMM))
|| !(t->operand_types[t->operands > 1] & (RegMMX | RegXMM)))
&& (!(operand_types[0] & (RegMMX | RegXMM))
|| !(operand_types[t->operands > 1] & (RegMMX | RegXMM)))
&& (t->base_opcode != 0x0fc7
|| t->extension_opcode != 1 /* cmpxchg8b */))
continue;
@ -2628,41 +2640,76 @@ match_template ()
break;
}
overlap0 = i.types[0] & t->operand_types[0];
/* Address size prefix will turn Disp64/Disp32/Disp16 operand
into Disp32/Disp16/Disp32 operand. */
if (i.prefix[ADDR_PREFIX] != 0)
{
unsigned int j, DispOn = 0, DispOff = 0;
switch (flag_code)
{
case CODE_16BIT:
DispOn = Disp32;
DispOff = Disp16;
break;
case CODE_32BIT:
DispOn = Disp16;
DispOff = Disp32;
break;
case CODE_64BIT:
DispOn = Disp32;
DispOff = Disp64;
break;
}
for (j = 0; j < 3; j++)
{
/* There should be only one Disp operand. */
if ((operand_types[j] & DispOff))
{
addr_prefix_disp = j;
operand_types[j] |= DispOn;
operand_types[j] &= ~DispOff;
break;
}
}
}
overlap0 = i.types[0] & operand_types[0];
switch (t->operands)
{
case 1:
if (!MATCH (overlap0, i.types[0], t->operand_types[0]))
if (!MATCH (overlap0, i.types[0], operand_types[0]))
continue;
break;
case 2:
case 3:
overlap1 = i.types[1] & t->operand_types[1];
if (!MATCH (overlap0, i.types[0], t->operand_types[0])
|| !MATCH (overlap1, i.types[1], t->operand_types[1])
overlap1 = i.types[1] & operand_types[1];
if (!MATCH (overlap0, i.types[0], operand_types[0])
|| !MATCH (overlap1, i.types[1], operand_types[1])
/* monitor in SSE3 is a very special case. The first
register and the second register may have different
sizes. */
|| !((t->base_opcode == 0x0f01
&& t->extension_opcode == 0xc8)
|| CONSISTENT_REGISTER_MATCH (overlap0, i.types[0],
t->operand_types[0],
operand_types[0],
overlap1, i.types[1],
t->operand_types[1])))
operand_types[1])))
{
/* Check if other direction is valid ... */
if ((t->opcode_modifier & (D | FloatD)) == 0)
continue;
/* Try reversing direction of operands. */
overlap0 = i.types[0] & t->operand_types[1];
overlap1 = i.types[1] & t->operand_types[0];
if (!MATCH (overlap0, i.types[0], t->operand_types[1])
|| !MATCH (overlap1, i.types[1], t->operand_types[0])
overlap0 = i.types[0] & operand_types[1];
overlap1 = i.types[1] & operand_types[0];
if (!MATCH (overlap0, i.types[0], operand_types[1])
|| !MATCH (overlap1, i.types[1], operand_types[0])
|| !CONSISTENT_REGISTER_MATCH (overlap0, i.types[0],
t->operand_types[1],
operand_types[1],
overlap1, i.types[1],
t->operand_types[0]))
operand_types[0]))
{
/* Does not match either direction. */
continue;
@ -2678,12 +2725,12 @@ match_template ()
reverse match 3 operand instructions, and all 3
operand instructions only need to be checked for
register consistency between operands 2 and 3. */
overlap2 = i.types[2] & t->operand_types[2];
if (!MATCH (overlap2, i.types[2], t->operand_types[2])
overlap2 = i.types[2] & operand_types[2];
if (!MATCH (overlap2, i.types[2], operand_types[2])
|| !CONSISTENT_REGISTER_MATCH (overlap1, i.types[1],
t->operand_types[1],
operand_types[1],
overlap2, i.types[2],
t->operand_types[2]))
operand_types[2]))
continue;
}
@ -2711,7 +2758,7 @@ match_template ()
{
if (!intel_syntax
&& ((i.types[0] & JumpAbsolute)
!= (t->operand_types[0] & JumpAbsolute)))
!= (operand_types[0] & JumpAbsolute)))
{
as_warn (_("indirect %s without `*'"), t->name);
}
@ -2727,6 +2774,11 @@ match_template ()
/* Copy the template we found. */
i.tm = *t;
if (addr_prefix_disp != -1)
i.tm.operand_types[addr_prefix_disp]
= operand_types[addr_prefix_disp];
if (found_reverse_match)
{
/* If we found a reverse match we must alter the opcode
@ -2735,8 +2787,8 @@ match_template ()
i.tm.base_opcode ^= found_reverse_match;
i.tm.operand_types[0] = t->operand_types[1];
i.tm.operand_types[1] = t->operand_types[0];
i.tm.operand_types[0] = operand_types[1];
i.tm.operand_types[1] = operand_types[0];
}
return 1;

View File

@ -1,3 +1,16 @@
2006-09-23 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/3235
* gas/i386/addr16.d: New file.
* gas/i386/addr16.s: Likewise.
* gas/i386/addr32.d: Likewise.
* gas/i386/addr32.s: Likewise.
* gas/i386/i386.exp: Add "addr16" and "addr32".
* gas/i386/x86-64-addr32.s: Add tests for "add32 mov".
* gas/i386/x86-64-addr32.d: Updated.
2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
* gas/all/gas.exp: Add support for x86_64-*-mingw64.

View File

@ -0,0 +1,15 @@
#objdump: -drw
#name: i386 16-bit addressing in 32-bit mode.
.*: +file format .*
Disassembly of section .text:
0+000 <.text>:
[ ]*0:[ ]+67 a0 98 08 [ ]+addr16[ ]+mov[ ]+0x898,%al
[ ]*4:[ ]+67 66 a1 98 08 [ ]+addr16[ ]+mov[ ]+0x898,%ax
[ ]*9:[ ]+67 a1 98 08 [ ]+addr16[ ]+mov[ ]+0x898,%eax
[ ]*d:[ ]+67 a2 98 08 [ ]+addr16[ ]+mov[ ]+%al,0x898
[ ]*11:[ ]+67 66 a3 98 08 [ ]+addr16[ ]+mov[ ]+%ax,0x898
[ ]*16:[ ]+67 a3 98 08[ ]+addr16[ ]+mov[ ]+%eax,0x898
#pass

View File

@ -0,0 +1,7 @@
.text
addr16 mov 0x0898,%al
addr16 mov 0x0898,%ax
addr16 mov 0x0898,%eax
addr16 mov %al,0x0898
addr16 mov %ax,0x0898
addr16 mov %eax,0x0898

View File

@ -0,0 +1,15 @@
#objdump: -drw -mi8086
#name: i386 32-bit addressing in 16-bit mode.
.*: +file format .*
Disassembly of section .text:
0+000 <.text>:
[ ]*0:[ ]+67 a0 98 08 60 00[ ]+addr32[ ]+mov[ ]+0x600898,%al
[ ]*6:[ ]+67 a1 98 08 60 00[ ]+addr32[ ]+mov[ ]+0x600898,%ax
[ ]*c:[ ]+67 66 a1 98 08 60 00[ ]+addr32[ ]+mov[ ]+0x600898,%eax
[ ]*13:[ ]+67 a2 98 08 60 00[ ]+addr32[ ]+mov[ ]+%al,0x600898
[ ]*19:[ ]+67 a3 98 08 60 00[ ]+addr32[ ]+mov[ ]+%ax,0x600898
[ ]*1f:[ ]+67 66 a3 98 08 60 00[ ]+addr32[ ]+mov[ ]+%eax,0x600898
#pass

View File

@ -0,0 +1,8 @@
.text
.code16
addr32 mov 0x600898,%al
addr32 mov 0x600898,%ax
addr32 mov 0x600898,%eax
addr32 mov %al,0x600898
addr32 mov %ax,0x600898
addr32 mov %eax,0x600898

View File

@ -81,6 +81,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
run_dump_test "nops-2"
run_dump_test "nops-2-i386"
run_dump_test "nops-2-merom"
run_dump_test "addr16"
run_dump_test "addr32"
# These tests require support for 8 and 16 bit relocs,
# so we only run them for ELF and COFF targets.

View File

@ -11,4 +11,12 @@ Disassembly of section .text:
[ ]*8:[ ]+67 49 8d 80 00 00 00 00[ ]+addr32[ ]+lea[ ]+0x0\(%r8d?\),%rax.*
[ ]*10:[ ]+67 48 8d 05 00 00 00 00[ ]+addr32[ ]+lea[ ]+0\(%[re]ip\),%rax.*
[ ]*18:[ ]+67 48 8d 04 25 00 00 00 00[ ]+addr32[ ]+lea[ ]+0x0,%rax.*
[ ]*21:[ ]+67 a0 98 08 60 00[ ]+addr32[ ]+mov[ ]+0x600898,%al
[ ]*27:[ ]+67 66 a1 98 08 60 00[ ]+addr32[ ]+mov[ ]+0x600898,%ax
[ ]*2e:[ ]+67 a1 98 08 60 00[ ]+addr32[ ]+mov[ ]+0x600898,%eax
[ ]*34:[ ]+67 48 a1 98 08 60 00[ ]+addr32[ ]+mov[ ]+0x600898,%rax
[ ]*3b:[ ]+67 a2 98 08 60 00[ ]+addr32[ ]+mov[ ]+%al,0x600898
[ ]*41:[ ]+67 66 a3 98 08 60 00[ ]+addr32[ ]+mov[ ]+%ax,0x600898
[ ]*48:[ ]+67 a3 98 08 60 00[ ]+addr32[ ]+mov[ ]+%eax,0x600898
[ ]*4e:[ ]+67 48 a3 98 08 60 00[ ]+addr32[ ]+mov[ ]+%rax,0x600898
#pass

View File

@ -3,3 +3,11 @@
lea symbol(%r8d), %rax
addr32 lea symbol(%rip), %rax
addr32 lea symbol, %rax
addr32 mov 0x600898,%al
addr32 mov 0x600898,%ax
addr32 mov 0x600898,%eax
addr32 mov 0x600898,%rax
addr32 mov %al,0x600898
addr32 mov %ax,0x600898
addr32 mov %eax,0x600898
addr32 mov %rax,0x600898

View File

@ -1,3 +1,9 @@
2006-09-23 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/3235
* i386-dis.c (OP_OFF64): Get 32bit offset if there is an
address size prefix.
2006-09-17 Mei Ligang <ligang@sunnorth.com.cn>
* score-dis.c: New file.

View File

@ -4693,7 +4693,8 @@ OP_OFF64 (int bytemode, int sizeflag)
{
bfd_vma off;
if (address_mode != mode_64bit)
if (address_mode != mode_64bit
|| (prefixes & PREFIX_ADDR))
{
OP_OFF (bytemode, sizeflag);
return;