aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2006-09-23 23:10:14 +0000
committerH.J. Lu <hjl.tools@gmail.com>2006-09-23 23:10:14 +0000
commit539e75adb5c6632bd7e601a03185b865d751e23f (patch)
tree38a6bade71978aa8c5d8d0130de53bc214ec8fc6 /gas
parentb41e175056364479595c15b3bba30970dfc9fffc (diff)
downloadgdb-539e75adb5c6632bd7e601a03185b865d751e23f.zip
gdb-539e75adb5c6632bd7e601a03185b865d751e23f.tar.gz
gdb-539e75adb5c6632bd7e601a03185b865d751e23f.tar.bz2
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.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-i386.c96
-rw-r--r--gas/testsuite/ChangeLog13
-rw-r--r--gas/testsuite/gas/i386/addr16.d15
-rw-r--r--gas/testsuite/gas/i386/addr16.s7
-rw-r--r--gas/testsuite/gas/i386/addr32.d15
-rw-r--r--gas/testsuite/gas/i386/addr32.s8
-rw-r--r--gas/testsuite/gas/i386/i386.exp2
-rw-r--r--gas/testsuite/gas/i386/x86-64-addr32.d8
-rw-r--r--gas/testsuite/gas/i386/x86-64-addr32.s8
10 files changed, 157 insertions, 22 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 9fe98d4..8648384 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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 '-'.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 1e8534a..7cf514b 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -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;
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 89892f7..fe1f119 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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.
diff --git a/gas/testsuite/gas/i386/addr16.d b/gas/testsuite/gas/i386/addr16.d
new file mode 100644
index 0000000..910d725
--- /dev/null
+++ b/gas/testsuite/gas/i386/addr16.d
@@ -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
diff --git a/gas/testsuite/gas/i386/addr16.s b/gas/testsuite/gas/i386/addr16.s
new file mode 100644
index 0000000..b1510e7
--- /dev/null
+++ b/gas/testsuite/gas/i386/addr16.s
@@ -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
diff --git a/gas/testsuite/gas/i386/addr32.d b/gas/testsuite/gas/i386/addr32.d
new file mode 100644
index 0000000..5866a30
--- /dev/null
+++ b/gas/testsuite/gas/i386/addr32.d
@@ -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
diff --git a/gas/testsuite/gas/i386/addr32.s b/gas/testsuite/gas/i386/addr32.s
new file mode 100644
index 0000000..3dab339
--- /dev/null
+++ b/gas/testsuite/gas/i386/addr32.s
@@ -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
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 096b58a..aa2558e 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -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.
diff --git a/gas/testsuite/gas/i386/x86-64-addr32.d b/gas/testsuite/gas/i386/x86-64-addr32.d
index d22cff9..6cb20dc 100644
--- a/gas/testsuite/gas/i386/x86-64-addr32.d
+++ b/gas/testsuite/gas/i386/x86-64-addr32.d
@@ -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
diff --git a/gas/testsuite/gas/i386/x86-64-addr32.s b/gas/testsuite/gas/i386/x86-64-addr32.s
index d18cbb9..c32525f 100644
--- a/gas/testsuite/gas/i386/x86-64-addr32.s
+++ b/gas/testsuite/gas/i386/x86-64-addr32.s
@@ -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