mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-30 12:44:10 +08:00
gas/
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:
parent
b41e175056
commit
539e75adb5
@ -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 '-'.
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
15
gas/testsuite/gas/i386/addr16.d
Normal file
15
gas/testsuite/gas/i386/addr16.d
Normal 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
|
7
gas/testsuite/gas/i386/addr16.s
Normal file
7
gas/testsuite/gas/i386/addr16.s
Normal 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
|
15
gas/testsuite/gas/i386/addr32.d
Normal file
15
gas/testsuite/gas/i386/addr32.d
Normal 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
|
8
gas/testsuite/gas/i386/addr32.s
Normal file
8
gas/testsuite/gas/i386/addr32.s
Normal 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
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user