Corrections for x86_64 assembly.
This commit is contained in:
parent
93a6423143
commit
20f0a1fc7d
11 changed files with 167 additions and 109 deletions
|
@ -1,3 +1,21 @@
|
||||||
|
2004-07-21 Jan Beulich <jbeulich@novell.com>
|
||||||
|
|
||||||
|
* config/tc-i386.c (optimize_imm): Adjust immediates to only those
|
||||||
|
permissible for the selected instruction suffix.
|
||||||
|
(match_template): Don't permit 64-bit general purpose operands in
|
||||||
|
32-bit mode.
|
||||||
|
(finalize_imm): Permit 64-bit immediates.
|
||||||
|
(build_modrm_byte): Don't treat 32-bit addressing in 64-bit mode
|
||||||
|
specially except for the width of the used base and/or index
|
||||||
|
registers. For 32-bit displacements, use sign-extended
|
||||||
|
relocations only when using 64-bit addressing.
|
||||||
|
Force zero displacement on rip-relative addressing when there is
|
||||||
|
no other displacement.
|
||||||
|
(i386_index_check): Don't treat 32-bit addressing in 64-bit mode
|
||||||
|
specially except for the width of the used base and/or index
|
||||||
|
registers.
|
||||||
|
(parse_register): Disallow Reg64 registers in 32-bit mode.
|
||||||
|
|
||||||
2004-07-20 Maciej W. Rozycki <macro@linux-mips.org>
|
2004-07-20 Maciej W. Rozycki <macro@linux-mips.org>
|
||||||
|
|
||||||
* config/tc-mips.c (append_insn): Handle constant expressions with
|
* config/tc-mips.c (append_insn): Handle constant expressions with
|
||||||
|
|
|
@ -1922,15 +1922,13 @@ optimize_imm ()
|
||||||
i.types[op] = Imm64 | Imm32S;
|
i.types[op] = Imm64 | Imm32S;
|
||||||
break;
|
break;
|
||||||
case LONG_MNEM_SUFFIX:
|
case LONG_MNEM_SUFFIX:
|
||||||
i.types[op] = Imm32 | Imm64;
|
i.types[op] = Imm32;
|
||||||
break;
|
break;
|
||||||
case WORD_MNEM_SUFFIX:
|
case WORD_MNEM_SUFFIX:
|
||||||
i.types[op] = Imm16 | Imm32 | Imm64;
|
i.types[op] = Imm16;
|
||||||
break;
|
|
||||||
break;
|
break;
|
||||||
case BYTE_MNEM_SUFFIX:
|
case BYTE_MNEM_SUFFIX:
|
||||||
i.types[op] = Imm8 | Imm8S | Imm16 | Imm32S | Imm32;
|
i.types[op] = Imm8 | Imm8S;
|
||||||
break;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2018,9 +2016,18 @@ match_template ()
|
||||||
: (i.suffix == LONG_DOUBLE_MNEM_SUFFIX
|
: (i.suffix == LONG_DOUBLE_MNEM_SUFFIX
|
||||||
? No_xSuf : 0))))));
|
? No_xSuf : 0))))));
|
||||||
|
|
||||||
for (t = current_templates->start;
|
t = current_templates->start;
|
||||||
t < current_templates->end;
|
if (i.suffix == QWORD_MNEM_SUFFIX
|
||||||
t++)
|
&& flag_code != CODE_64BIT
|
||||||
|
&& (!intel_syntax
|
||||||
|
|| (!(t->opcode_modifier & IgnoreSize)
|
||||||
|
&& ! intel_float_operand (t->name)))
|
||||||
|
&& (!(t->operand_types[0] & (RegMMX | RegXMM))
|
||||||
|
|| !(t->operand_types[t->operands > 1] & (RegMMX | RegXMM)))
|
||||||
|
&& (t->base_opcode != 0x0fc7
|
||||||
|
|| t->extension_opcode != 1 /* cmpxchg8b */))
|
||||||
|
t = current_templates->end;
|
||||||
|
for (; t < current_templates->end; t++)
|
||||||
{
|
{
|
||||||
/* Must have right number of operands. */
|
/* Must have right number of operands. */
|
||||||
if (i.operands != t->operands)
|
if (i.operands != t->operands)
|
||||||
|
@ -2504,7 +2511,7 @@ finalize_imm ()
|
||||||
unsigned int overlap0, overlap1, overlap2;
|
unsigned int overlap0, overlap1, overlap2;
|
||||||
|
|
||||||
overlap0 = i.types[0] & i.tm.operand_types[0];
|
overlap0 = i.types[0] & i.tm.operand_types[0];
|
||||||
if ((overlap0 & (Imm8 | Imm8S | Imm16 | Imm32 | Imm32S))
|
if ((overlap0 & (Imm8 | Imm8S | Imm16 | Imm32 | Imm32S | Imm64))
|
||||||
&& overlap0 != Imm8 && overlap0 != Imm8S
|
&& overlap0 != Imm8 && overlap0 != Imm8S
|
||||||
&& overlap0 != Imm16 && overlap0 != Imm32S
|
&& overlap0 != Imm16 && overlap0 != Imm32S
|
||||||
&& overlap0 != Imm32 && overlap0 != Imm64)
|
&& overlap0 != Imm32 && overlap0 != Imm64)
|
||||||
|
@ -2733,21 +2740,7 @@ build_modrm_byte ()
|
||||||
if (i.index_reg == 0)
|
if (i.index_reg == 0)
|
||||||
{
|
{
|
||||||
/* Operand is just <disp> */
|
/* Operand is just <disp> */
|
||||||
if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0)
|
if (flag_code == CODE_64BIT)
|
||||||
&& (flag_code != CODE_64BIT))
|
|
||||||
{
|
|
||||||
i.rm.regmem = NO_BASE_REGISTER_16;
|
|
||||||
i.types[op] &= ~Disp;
|
|
||||||
i.types[op] |= Disp16;
|
|
||||||
}
|
|
||||||
else if (flag_code != CODE_64BIT
|
|
||||||
|| (i.prefix[ADDR_PREFIX] != 0))
|
|
||||||
{
|
|
||||||
i.rm.regmem = NO_BASE_REGISTER;
|
|
||||||
i.types[op] &= ~Disp;
|
|
||||||
i.types[op] |= Disp32;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* 64bit mode overwrites the 32bit absolute
|
/* 64bit mode overwrites the 32bit absolute
|
||||||
addressing by RIP relative addressing and
|
addressing by RIP relative addressing and
|
||||||
|
@ -2756,8 +2749,17 @@ build_modrm_byte ()
|
||||||
i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
|
i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
|
||||||
i.sib.base = NO_BASE_REGISTER;
|
i.sib.base = NO_BASE_REGISTER;
|
||||||
i.sib.index = NO_INDEX_REGISTER;
|
i.sib.index = NO_INDEX_REGISTER;
|
||||||
i.types[op] &= ~Disp;
|
i.types[op] = ((i.prefix[ADDR_PREFIX] == 0) ? Disp32S : Disp32);
|
||||||
i.types[op] |= Disp32S;
|
}
|
||||||
|
else if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
|
||||||
|
{
|
||||||
|
i.rm.regmem = NO_BASE_REGISTER_16;
|
||||||
|
i.types[op] = Disp16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i.rm.regmem = NO_BASE_REGISTER;
|
||||||
|
i.types[op] = Disp32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* !i.base_reg && i.index_reg */
|
else /* !i.base_reg && i.index_reg */
|
||||||
|
@ -2779,9 +2781,11 @@ build_modrm_byte ()
|
||||||
else if (i.base_reg->reg_type == BaseIndex)
|
else if (i.base_reg->reg_type == BaseIndex)
|
||||||
{
|
{
|
||||||
i.rm.regmem = NO_BASE_REGISTER;
|
i.rm.regmem = NO_BASE_REGISTER;
|
||||||
i.types[op] &= ~Disp;
|
i.types[op] &= ~ Disp;
|
||||||
i.types[op] |= Disp32S;
|
i.types[op] |= Disp32S;
|
||||||
i.flags[op] = Operand_PCrel;
|
i.flags[op] = Operand_PCrel;
|
||||||
|
if (! i.disp_operands)
|
||||||
|
fake_zero_displacement = 1;
|
||||||
}
|
}
|
||||||
else if (i.base_reg->reg_type & Reg16)
|
else if (i.base_reg->reg_type & Reg16)
|
||||||
{
|
{
|
||||||
|
@ -2817,12 +2821,8 @@ build_modrm_byte ()
|
||||||
{
|
{
|
||||||
if (flag_code == CODE_64BIT
|
if (flag_code == CODE_64BIT
|
||||||
&& (i.types[op] & Disp))
|
&& (i.types[op] & Disp))
|
||||||
{
|
i.types[op] = (i.types[op] & Disp8) | (i.prefix[ADDR_PREFIX] == 0 ? Disp32S : Disp32);
|
||||||
if (i.types[op] & Disp8)
|
|
||||||
i.types[op] = Disp8 | Disp32S;
|
|
||||||
else
|
|
||||||
i.types[op] = Disp32S;
|
|
||||||
}
|
|
||||||
i.rm.regmem = i.base_reg->reg_num;
|
i.rm.regmem = i.base_reg->reg_num;
|
||||||
if ((i.base_reg->reg_flags & RegRex) != 0)
|
if ((i.base_reg->reg_flags & RegRex) != 0)
|
||||||
i.rex |= REX_EXTZ;
|
i.rex |= REX_EXTZ;
|
||||||
|
@ -3999,30 +3999,18 @@ i386_index_check (operand_string)
|
||||||
tryprefix:
|
tryprefix:
|
||||||
#endif
|
#endif
|
||||||
ok = 1;
|
ok = 1;
|
||||||
if (flag_code == CODE_64BIT)
|
if (flag_code == CODE_64BIT)
|
||||||
{
|
{
|
||||||
if (i.prefix[ADDR_PREFIX] == 0)
|
unsigned RegXX = (i.prefix[ADDR_PREFIX] == 0 ? Reg64 : Reg32);
|
||||||
{
|
|
||||||
/* 64bit checks. */
|
if ((i.base_reg
|
||||||
if ((i.base_reg
|
&& ((i.base_reg->reg_type & RegXX) == 0)
|
||||||
&& ((i.base_reg->reg_type & Reg64) == 0)
|
&& (i.base_reg->reg_type != BaseIndex
|
||||||
&& (i.base_reg->reg_type != BaseIndex
|
|| i.index_reg))
|
||||||
|| i.index_reg))
|
|| (i.index_reg
|
||||||
|| (i.index_reg
|
&& ((i.index_reg->reg_type & (RegXX | BaseIndex))
|
||||||
&& ((i.index_reg->reg_type & (Reg64 | BaseIndex))
|
!= (RegXX | BaseIndex))))
|
||||||
!= (Reg64 | BaseIndex))))
|
ok = 0;
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 32bit checks. */
|
|
||||||
if ((i.base_reg
|
|
||||||
&& (i.base_reg->reg_type & (Reg32 | RegRex)) != Reg32)
|
|
||||||
|| (i.index_reg
|
|
||||||
&& ((i.index_reg->reg_type & (Reg32 | BaseIndex | RegRex))
|
|
||||||
!= (Reg32 | BaseIndex))))
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4055,8 +4043,7 @@ i386_index_check (operand_string)
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
#if INFER_ADDR_PREFIX
|
#if INFER_ADDR_PREFIX
|
||||||
if (flag_code != CODE_64BIT
|
if (i.prefix[ADDR_PREFIX] == 0)
|
||||||
&& i.prefix[ADDR_PREFIX] == 0 && stackop_size != '\0')
|
|
||||||
{
|
{
|
||||||
i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
|
i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
|
||||||
i.prefixes += 1;
|
i.prefixes += 1;
|
||||||
|
@ -4065,7 +4052,7 @@ i386_index_check (operand_string)
|
||||||
FIXME. There doesn't seem to be any real need for separate
|
FIXME. There doesn't seem to be any real need for separate
|
||||||
Disp16 and Disp32 flags. The same goes for Imm16 and Imm32.
|
Disp16 and Disp32 flags. The same goes for Imm16 and Imm32.
|
||||||
Removing them would probably clean up the code quite a lot. */
|
Removing them would probably clean up the code quite a lot. */
|
||||||
if (i.types[this_operand] & (Disp16 | Disp32))
|
if (flag_code != CODE_64BIT && (i.types[this_operand] & (Disp16 | Disp32)))
|
||||||
i.types[this_operand] ^= (Disp16 | Disp32);
|
i.types[this_operand] ^= (Disp16 | Disp32);
|
||||||
fudged = 1;
|
fudged = 1;
|
||||||
goto tryprefix;
|
goto tryprefix;
|
||||||
|
@ -4078,9 +4065,8 @@ i386_index_check (operand_string)
|
||||||
as_bad (_("`%s' is not a valid %s bit base/index expression"),
|
as_bad (_("`%s' is not a valid %s bit base/index expression"),
|
||||||
operand_string,
|
operand_string,
|
||||||
flag_code_names[flag_code]);
|
flag_code_names[flag_code]);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse OPERAND_STRING into the i386_insn structure I. Returns non-zero
|
/* Parse OPERAND_STRING into the i386_insn structure I. Returns non-zero
|
||||||
|
@ -4904,11 +4890,9 @@ parse_register (reg_string, end_op)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r != NULL
|
if (r != NULL
|
||||||
&& (r->reg_flags & (RegRex64 | RegRex)) != 0
|
&& ((r->reg_flags & (RegRex64 | RegRex)) | (r->reg_type & Reg64)) != 0
|
||||||
&& flag_code != CODE_64BIT)
|
&& flag_code != CODE_64BIT)
|
||||||
{
|
return (const reg_entry *) NULL;
|
||||||
return (const reg_entry *) NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
2004-07-21 Jan Beulich <jbeulich@novell.com>
|
||||||
|
|
||||||
|
* testsuite/gas/i386/x86-64-addr32.[ds]: New test for x86-64
|
||||||
|
32-bit addressing in 64-bit mode.
|
||||||
|
* testsuite/gas/i386/x86-64-rip.[ds]: New test for x86-64
|
||||||
|
rip-relative addressing.
|
||||||
|
* testsuite/gas/i386/i386.exp: Run the two new tests.
|
||||||
|
|
||||||
2004-07-20 Maciej W. Rozycki <macro@linux-mips.org>
|
2004-07-20 Maciej W. Rozycki <macro@linux-mips.org>
|
||||||
|
|
||||||
* gas/mips/elf-rel19.d: Pass -march=mips1 to gas as the test
|
* gas/mips/elf-rel19.d: Pass -march=mips1 to gas as the test
|
||||||
|
|
|
@ -105,7 +105,9 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
|
||||||
set ASFLAGS "$ASFLAGS --64"
|
set ASFLAGS "$ASFLAGS --64"
|
||||||
|
|
||||||
run_dump_test "x86_64"
|
run_dump_test "x86_64"
|
||||||
|
run_dump_test "x86-64-addr32"
|
||||||
run_dump_test "x86-64-opcode"
|
run_dump_test "x86-64-opcode"
|
||||||
|
run_dump_test "x86-64-rip"
|
||||||
run_list_test "x86-64-inval" "-al"
|
run_list_test "x86-64-inval" "-al"
|
||||||
|
|
||||||
set ASFLAGS "$old_ASFLAGS"
|
set ASFLAGS "$old_ASFLAGS"
|
||||||
|
|
13
gas/testsuite/gas/i386/x86-64-addr32.d
Normal file
13
gas/testsuite/gas/i386/x86-64-addr32.d
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#as: -J
|
||||||
|
#objdump: -drw
|
||||||
|
#name: x86-64 32-bit addressing
|
||||||
|
|
||||||
|
.*: +file format elf64-x86-64
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
0+000 <.text>:
|
||||||
|
[ ]*0:[ ]+67 48 8d 80 00 00 00 00[ ]+addr32[ ]+lea[ ]+0x0\(%[re]ax\),%rax.*
|
||||||
|
[ ]*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.*
|
5
gas/testsuite/gas/i386/x86-64-addr32.s
Normal file
5
gas/testsuite/gas/i386/x86-64-addr32.s
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.text
|
||||||
|
lea symbol(%eax), %rax
|
||||||
|
lea symbol(%r8d), %rax
|
||||||
|
addr32 lea symbol(%rip), %rax
|
||||||
|
addr32 lea symbol, %rax
|
13
gas/testsuite/gas/i386/x86-64-rip.d
Normal file
13
gas/testsuite/gas/i386/x86-64-rip.d
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#as: -J
|
||||||
|
#objdump: -drw
|
||||||
|
#name: x86-64 rip addressing
|
||||||
|
|
||||||
|
.*: +file format elf64-x86-64
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
0+000 <.text>:
|
||||||
|
[ ]*0:[ ]+8d 05 00 00 00 00[ ]+lea[ ]+0\(%rip\),%eax[ ]*(#.*)?
|
||||||
|
[ ]*6:[ ]+8d 05 11 11 11 11[ ]+lea[ ]+286331153\(%rip\),%eax[ ]*(#.*)?
|
||||||
|
[ ]*c:[ ]+8d 05 01 00 00 00[ ]+lea[ ]+1\(%rip\),%eax[ ]*(#.*)?
|
||||||
|
[ ]*12:[ ]+8d 05 00 00 00 00[ ]+lea[ ]+0\(%rip\),%eax[ ]*(#.*)?
|
5
gas/testsuite/gas/i386/x86-64-rip.s
Normal file
5
gas/testsuite/gas/i386/x86-64-rip.s
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.text
|
||||||
|
leal symbol(%rip), %eax
|
||||||
|
leal 0x11111111(%rip), %eax
|
||||||
|
leal 1(%rip), %eax
|
||||||
|
leal (%rip), %eax
|
|
@ -37,7 +37,7 @@ Disassembly of section .text:
|
||||||
[ ]+5a: 44 0f 20 c0[ ]+mov[ ]+%cr8,%rax
|
[ ]+5a: 44 0f 20 c0[ ]+mov[ ]+%cr8,%rax
|
||||||
[ ]+5e: 44 0f 22 c0[ ]+mov[ ]+%rax,%cr8
|
[ ]+5e: 44 0f 22 c0[ ]+mov[ ]+%rax,%cr8
|
||||||
[ ]+62: f3 48 a5[ ]+repz movsq %ds:\(%rsi\),%es:\(%rdi\)
|
[ ]+62: f3 48 a5[ ]+repz movsq %ds:\(%rsi\),%es:\(%rdi\)
|
||||||
[ ]+65: f3 66 a5[ ]+repz movsw %ds:\(%esi\),%es:\(%edi\)
|
[ ]+65: f3 66 a5[ ]+repz movsw %ds:\(%rsi\),%es:\(%rdi\)
|
||||||
[ ]+68: f3 48 a5[ ]+repz movsq %ds:\(%rsi\),%es:\(%rdi\)
|
[ ]+68: f3 48 a5[ ]+repz movsq %ds:\(%rsi\),%es:\(%rdi\)
|
||||||
[ ]+6b: b0 11[ ]+mov[ ]+\$0x11,%al
|
[ ]+6b: b0 11[ ]+mov[ ]+\$0x11,%al
|
||||||
[ ]+6d: b4 11[ ]+mov[ ]+\$0x11,%ah
|
[ ]+6d: b4 11[ ]+mov[ ]+\$0x11,%ah
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
2004-07-21 Jan Beulich <jbeulich@novell.com>
|
||||||
|
|
||||||
|
* i386-dis.c (OP_E): Show rip-relative addressing in 64-bit mode
|
||||||
|
regardless of address size prefix in effect.
|
||||||
|
(ptr_reg): Size or address registers does not depend on rex64, but
|
||||||
|
on the presence of an address size override.
|
||||||
|
(OP_MMX): Use rex.x only for xmm registers.
|
||||||
|
(OP_EM): Use rex.z only for xmm registers.
|
||||||
|
|
||||||
2004-07-20 Maciej W. Rozycki <macro@linux-mips.org>
|
2004-07-20 Maciej W. Rozycki <macro@linux-mips.org>
|
||||||
|
|
||||||
* mips-opc.c (mips_builtin_opcodes): Move coprocessor 2
|
* mips-opc.c (mips_builtin_opcodes): Move coprocessor 2
|
||||||
|
|
|
@ -2,38 +2,34 @@
|
||||||
Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||||
2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
/*
|
/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
|
||||||
* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
|
July 1988
|
||||||
* July 1988
|
modified by John Hassey (hassey@dg-rtp.dg.com)
|
||||||
* modified by John Hassey (hassey@dg-rtp.dg.com)
|
x86-64 support added by Jan Hubicka (jh@suse.cz)
|
||||||
* x86-64 support added by Jan Hubicka (jh@suse.cz)
|
VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
|
||||||
* VIA PadLock support by Michal Ludvig (mludvig@suse.cz)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/* The main tables describing the instructions is essentially a copy
|
||||||
* The main tables describing the instructions is essentially a copy
|
of the "Opcode Map" chapter (Appendix A) of the Intel 80386
|
||||||
* of the "Opcode Map" chapter (Appendix A) of the Intel 80386
|
Programmers Manual. Usually, there is a capital letter, followed
|
||||||
* Programmers Manual. Usually, there is a capital letter, followed
|
by a small letter. The capital letter tell the addressing mode,
|
||||||
* by a small letter. The capital letter tell the addressing mode,
|
and the small letter tells about the operand size. Refer to
|
||||||
* and the small letter tells about the operand size. Refer to
|
the Intel manual for details. */
|
||||||
* the Intel manual for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dis-asm.h"
|
#include "dis-asm.h"
|
||||||
#include "sysdep.h"
|
#include "sysdep.h"
|
||||||
|
@ -3166,7 +3162,7 @@ OP_E (int bytemode, int sizeflag)
|
||||||
if ((base & 7) == 5)
|
if ((base & 7) == 5)
|
||||||
{
|
{
|
||||||
havebase = 0;
|
havebase = 0;
|
||||||
if (mode_64bit && !havesib && (sizeflag & AFLAG))
|
if (mode_64bit && !havesib)
|
||||||
riprel = 1;
|
riprel = 1;
|
||||||
disp = get32s ();
|
disp = get32s ();
|
||||||
}
|
}
|
||||||
|
@ -3856,8 +3852,8 @@ ptr_reg (int code, int sizeflag)
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
*obufp++ = open_char;
|
*obufp++ = open_char;
|
||||||
USED_REX (REX_MODE64);
|
used_prefixes |= (prefixes & PREFIX_ADDR);
|
||||||
if (rex & REX_MODE64)
|
if (mode_64bit)
|
||||||
{
|
{
|
||||||
if (!(sizeflag & AFLAG))
|
if (!(sizeflag & AFLAG))
|
||||||
s = names32[code - eAX_reg];
|
s = names32[code - eAX_reg];
|
||||||
|
@ -3939,15 +3935,17 @@ OP_Rd (int bytemode, int sizeflag)
|
||||||
static void
|
static void
|
||||||
OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
int add = 0;
|
|
||||||
USED_REX (REX_EXTX);
|
|
||||||
if (rex & REX_EXTX)
|
|
||||||
add = 8;
|
|
||||||
used_prefixes |= (prefixes & PREFIX_DATA);
|
used_prefixes |= (prefixes & PREFIX_DATA);
|
||||||
if (prefixes & PREFIX_DATA)
|
if (prefixes & PREFIX_DATA)
|
||||||
sprintf (scratchbuf, "%%xmm%d", reg + add);
|
{
|
||||||
|
int add = 0;
|
||||||
|
USED_REX (REX_EXTX);
|
||||||
|
if (rex & REX_EXTX)
|
||||||
|
add = 8;
|
||||||
|
sprintf (scratchbuf, "%%xmm%d", reg + add);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
sprintf (scratchbuf, "%%mm%d", reg + add);
|
sprintf (scratchbuf, "%%mm%d", reg);
|
||||||
oappend (scratchbuf + intel_syntax);
|
oappend (scratchbuf + intel_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3965,24 +3963,27 @@ OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||||||
static void
|
static void
|
||||||
OP_EM (int bytemode, int sizeflag)
|
OP_EM (int bytemode, int sizeflag)
|
||||||
{
|
{
|
||||||
int add = 0;
|
|
||||||
if (mod != 3)
|
if (mod != 3)
|
||||||
{
|
{
|
||||||
OP_E (bytemode, sizeflag);
|
OP_E (bytemode, sizeflag);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
USED_REX (REX_EXTZ);
|
|
||||||
if (rex & REX_EXTZ)
|
|
||||||
add = 8;
|
|
||||||
|
|
||||||
/* Skip mod/rm byte. */
|
/* Skip mod/rm byte. */
|
||||||
MODRM_CHECK;
|
MODRM_CHECK;
|
||||||
codep++;
|
codep++;
|
||||||
used_prefixes |= (prefixes & PREFIX_DATA);
|
used_prefixes |= (prefixes & PREFIX_DATA);
|
||||||
if (prefixes & PREFIX_DATA)
|
if (prefixes & PREFIX_DATA)
|
||||||
sprintf (scratchbuf, "%%xmm%d", rm + add);
|
{
|
||||||
|
int add = 0;
|
||||||
|
|
||||||
|
USED_REX (REX_EXTZ);
|
||||||
|
if (rex & REX_EXTZ)
|
||||||
|
add = 8;
|
||||||
|
sprintf (scratchbuf, "%%xmm%d", rm + add);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
sprintf (scratchbuf, "%%mm%d", rm + add);
|
sprintf (scratchbuf, "%%mm%d", rm);
|
||||||
oappend (scratchbuf + intel_syntax);
|
oappend (scratchbuf + intel_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue