aboutsummaryrefslogtreecommitdiff
path: root/opcodes/i386-dis.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2005-12-06 12:40:57 +0000
committerH.J. Lu <hjl.tools@gmail.com>2005-12-06 12:40:57 +0000
commitcb712a9ecdc5784b3790aef71852e3bd329a976a (patch)
tree12879fe3450d70e0acb093eec52c1ea26c07ddde /opcodes/i386-dis.c
parent1ca81d7218066519c88fcdaffe2a82da423a1519 (diff)
downloadgdb-cb712a9ecdc5784b3790aef71852e3bd329a976a.zip
gdb-cb712a9ecdc5784b3790aef71852e3bd329a976a.tar.gz
gdb-cb712a9ecdc5784b3790aef71852e3bd329a976a.tar.bz2
gas/
2005-12-06 H.J. Lu <hongjiu.lu@intel.com> PR gas/1874 * config/tc-i386.c (match_template): Handle monitor. (process_suffix): Likewise. gas/testsuite/ 2005-12-06 H.J. Lu <hongjiu.lu@intel.com> PR gas/1874 * gas/i386/i386.exp: Add x86-64-prescott for 64bit. * gas/i386/prescott.s: Test address size override for monitor. * gas/i386/prescott.d: Updated. * gas/i386/x86-64-prescott.d: New file. * gas/i386/x86-64-prescott.s: Likewise. include/opcode/ 2005-12-06 H.J. Lu <hongjiu.lu@intel.com> PR gas/1874 * i386.h (i386_optab): Add 64bit support for monitor and mwait. opcodes/ 2005-12-06 H.J. Lu <hongjiu.lu@intel.com> PR gas/1874 * i386-dis.c (address_mode): New enum type. (address_mode): New variable. (mode_64bit): Removed. (ckprefix): Updated to check address_mode instead of mode_64bit. (prefix_name): Likewise. (print_insn): Likewise. (putop): Likewise. (print_operand_value): Likewise. (intel_operand_size): Likewise. (OP_E): Likewise. (OP_G): Likewise. (set_op): Likewise. (OP_REG): Likewise. (OP_I): Likewise. (OP_I64): Likewise. (OP_OFF): Likewise. (OP_OFF64): Likewise. (ptr_reg): Likewise. (OP_C): Likewise. (SVME_Fixup): Likewise. (print_insn): Set address_mode. (PNI_Fixup): Add 64bit and address size override support for monitor and mwait.
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r--opcodes/i386-dis.c119
1 files changed, 72 insertions, 47 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 47455e3..5adf4af 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -115,8 +115,14 @@ struct dis_private {
when we can. */
#define FWAIT_OPCODE (0x9b)
-/* Set to 1 for 64bit mode disassembly. */
-static int mode_64bit;
+enum address_mode
+{
+ mode_16bit,
+ mode_32bit,
+ mode_64bit
+};
+
+enum address_mode address_mode;
/* Flags for the prefixes for the current instruction. See below. */
static int prefixes;
@@ -1772,7 +1778,7 @@ ckprefix (void)
case 0x4d:
case 0x4e:
case 0x4f:
- if (mode_64bit)
+ if (address_mode == mode_64bit)
newrex = *codep;
else
return;
@@ -1898,7 +1904,7 @@ prefix_name (int pref, int sizeflag)
case 0x66:
return (sizeflag & DFLAG) ? "data16" : "data32";
case 0x67:
- if (mode_64bit)
+ if (address_mode == mode_64bit)
return (sizeflag & AFLAG) ? "addr32" : "addr64";
else
return (sizeflag & AFLAG) ? "addr16" : "addr32";
@@ -1970,8 +1976,11 @@ print_insn (bfd_vma pc, disassemble_info *info)
const char *p;
struct dis_private priv;
- mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
- || info->mach == bfd_mach_x86_64);
+ if (info->mach == bfd_mach_x86_64_intel_syntax
+ || info->mach == bfd_mach_x86_64)
+ address_mode = mode_64bit;
+ else
+ address_mode = mode_32bit;
if (intel_syntax == (char) -1)
intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
@@ -1991,17 +2000,17 @@ print_insn (bfd_vma pc, disassemble_info *info)
{
if (strncmp (p, "x86-64", 6) == 0)
{
- mode_64bit = 1;
+ address_mode = mode_64bit;
priv.orig_sizeflag = AFLAG | DFLAG;
}
else if (strncmp (p, "i386", 4) == 0)
{
- mode_64bit = 0;
+ address_mode = mode_32bit;
priv.orig_sizeflag = AFLAG | DFLAG;
}
else if (strncmp (p, "i8086", 5) == 0)
{
- mode_64bit = 0;
+ address_mode = mode_16bit;
priv.orig_sizeflag = 0;
}
else if (strncmp (p, "intel", 5) == 0)
@@ -2170,7 +2179,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
sizeflag ^= AFLAG;
if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
{
- if ((sizeflag & AFLAG) || mode_64bit)
+ if ((sizeflag & AFLAG) || address_mode == mode_64bit)
oappend ("addr32 ");
else
oappend ("addr16 ");
@@ -2237,7 +2246,8 @@ print_insn (bfd_vma pc, disassemble_info *info)
break;
case X86_64_SPECIAL:
- dp = &x86_64_table[dp->bytemode2][mode_64bit];
+ index = address_mode == mode_64bit ? 1 : 0;
+ dp = &x86_64_table[dp->bytemode2][index];
break;
default:
@@ -2739,7 +2749,7 @@ putop (const char *template, int sizeflag)
alt = 0;
if (intel_syntax)
alt += 1;
- if (mode_64bit)
+ if (address_mode == mode_64bit)
alt += 2;
while (alt != 0)
{
@@ -2795,7 +2805,7 @@ putop (const char *template, int sizeflag)
}
break;
case 'E': /* For jcxz/jecxz */
- if (mode_64bit)
+ if (address_mode == mode_64bit)
{
if (sizeflag & AFLAG)
*obufp++ = 'r';
@@ -2813,9 +2823,9 @@ putop (const char *template, int sizeflag)
if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
{
if (sizeflag & AFLAG)
- *obufp++ = mode_64bit ? 'q' : 'l';
+ *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
else
- *obufp++ = mode_64bit ? 'l' : 'w';
+ *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
used_prefixes |= (prefixes & PREFIX_ADDR);
}
break;
@@ -2861,7 +2871,7 @@ putop (const char *template, int sizeflag)
case 'T':
if (intel_syntax)
break;
- if (mode_64bit && (sizeflag & DFLAG))
+ if (address_mode == mode_64bit && (sizeflag & DFLAG))
{
*obufp++ = 'q';
break;
@@ -2890,7 +2900,7 @@ putop (const char *template, int sizeflag)
case 'U':
if (intel_syntax)
break;
- if (mode_64bit && (sizeflag & DFLAG))
+ if (address_mode == mode_64bit && (sizeflag & DFLAG))
{
if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
*obufp++ = 'q';
@@ -2950,7 +2960,7 @@ putop (const char *template, int sizeflag)
case 'V':
if (intel_syntax)
break;
- if (mode_64bit && (sizeflag & DFLAG))
+ if (address_mode == mode_64bit && (sizeflag & DFLAG))
{
if (sizeflag & SUFFIX_ALWAYS)
*obufp++ = 'q';
@@ -3080,7 +3090,7 @@ OP_indirE (int bytemode, int sizeflag)
static void
print_operand_value (char *buf, int hex, bfd_vma disp)
{
- if (mode_64bit)
+ if (address_mode == mode_64bit)
{
if (hex)
{
@@ -3147,7 +3157,7 @@ intel_operand_size (int bytemode, int sizeflag)
oappend ("WORD PTR ");
break;
case stack_v_mode:
- if (mode_64bit && (sizeflag & DFLAG))
+ if (address_mode == mode_64bit && (sizeflag & DFLAG))
{
oappend ("QWORD PTR ");
used_prefixes |= (prefixes & PREFIX_DATA);
@@ -3172,7 +3182,7 @@ intel_operand_size (int bytemode, int sizeflag)
oappend ("QWORD PTR ");
break;
case m_mode:
- if (mode_64bit)
+ if (address_mode == mode_64bit)
oappend ("QWORD PTR ");
else
oappend ("DWORD PTR ");
@@ -3230,13 +3240,13 @@ OP_E (int bytemode, int sizeflag)
oappend (names64[rm + add]);
break;
case m_mode:
- if (mode_64bit)
+ if (address_mode == mode_64bit)
oappend (names64[rm + add]);
else
oappend (names32[rm + add]);
break;
case stack_v_mode:
- if (mode_64bit && (sizeflag & DFLAG))
+ if (address_mode == mode_64bit && (sizeflag & DFLAG))
{
oappend (names64[rm + add]);
used_prefixes |= (prefixes & PREFIX_DATA);
@@ -3270,7 +3280,7 @@ OP_E (int bytemode, int sizeflag)
intel_operand_size (bytemode, sizeflag);
append_seg ();
- if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
+ if ((sizeflag & AFLAG) || address_mode == mode_64bit) /* 32 bit address mode */
{
int havesib;
int havebase;
@@ -3287,7 +3297,7 @@ OP_E (int bytemode, int sizeflag)
havesib = 1;
FETCH_DATA (the_info, codep + 1);
index = (*codep >> 3) & 7;
- if (mode_64bit || index != 0x4)
+ if (address_mode == mode_64bit || index != 0x4)
/* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
scale = (*codep >> 6) & 3;
base = *codep & 7;
@@ -3304,7 +3314,7 @@ OP_E (int bytemode, int sizeflag)
if ((base & 7) == 5)
{
havebase = 0;
- if (mode_64bit && !havesib)
+ if (address_mode == mode_64bit && !havesib)
riprel = 1;
disp = get32s ();
}
@@ -3339,7 +3349,7 @@ OP_E (int bytemode, int sizeflag)
oappend ("rip + ");
*obufp = '\0';
if (havebase)
- oappend (mode_64bit && (sizeflag & AFLAG)
+ oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
? names64[base] : names32[base]);
if (havesib)
{
@@ -3350,7 +3360,7 @@ OP_E (int bytemode, int sizeflag)
*obufp++ = separator_char;
*obufp = '\0';
}
- oappend (mode_64bit && (sizeflag & AFLAG)
+ oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
? names64[index] : names32[index]);
}
if (scale != 0 || (!intel_syntax && index != 4))
@@ -3511,7 +3521,7 @@ OP_G (int bytemode, int sizeflag)
used_prefixes |= (prefixes & PREFIX_DATA);
break;
case m_mode:
- if (mode_64bit)
+ if (address_mode == mode_64bit)
oappend (names64[reg + add]);
else
oappend (names32[reg + add]);
@@ -3591,7 +3601,7 @@ static void
set_op (bfd_vma op, int riprel)
{
op_index[op_ad] = op_ad;
- if (mode_64bit)
+ if (address_mode == mode_64bit)
{
op_address[op_ad] = op;
op_riprel[op_ad] = riprel;
@@ -3639,7 +3649,7 @@ OP_REG (int code, int sizeflag)
break;
case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
- if (mode_64bit && (sizeflag & DFLAG))
+ if (address_mode == mode_64bit && (sizeflag & DFLAG))
{
s = names64[code - rAX_reg + add];
break;
@@ -3725,7 +3735,7 @@ OP_I (int bytemode, int sizeflag)
mask = 0xff;
break;
case q_mode:
- if (mode_64bit)
+ if (address_mode == mode_64bit)
{
op = get32s ();
break;
@@ -3773,7 +3783,7 @@ OP_I64 (int bytemode, int sizeflag)
bfd_signed_vma op;
bfd_signed_vma mask = -1;
- if (!mode_64bit)
+ if (address_mode != mode_64bit)
{
OP_I (bytemode, sizeflag);
return;
@@ -3941,7 +3951,7 @@ OP_OFF (int bytemode, int sizeflag)
intel_operand_size (bytemode, sizeflag);
append_seg ();
- if ((sizeflag & AFLAG) || mode_64bit)
+ if ((sizeflag & AFLAG) || address_mode == mode_64bit)
off = get32 ();
else
off = get16 ();
@@ -3964,7 +3974,7 @@ OP_OFF64 (int bytemode, int sizeflag)
{
bfd_vma off;
- if (!mode_64bit)
+ if (address_mode != mode_64bit)
{
OP_OFF (bytemode, sizeflag);
return;
@@ -3996,7 +4006,7 @@ ptr_reg (int code, int sizeflag)
*obufp++ = open_char;
used_prefixes |= (prefixes & PREFIX_ADDR);
- if (mode_64bit)
+ if (address_mode == mode_64bit)
{
if (!(sizeflag & AFLAG))
s = names32[code - eAX_reg];
@@ -4050,7 +4060,7 @@ OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
USED_REX (REX_EXTX);
add = 8;
}
- else if (!mode_64bit && (prefixes & PREFIX_LOCK))
+ else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
{
used_prefixes |= PREFIX_LOCK;
add = 8;
@@ -4412,18 +4422,31 @@ PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
if (mod == 3 && reg == 1 && rm <= 1)
{
/* Override "sidt". */
- char *p = obuf + strlen (obuf) - 4;
+ size_t olen = strlen (obuf);
+ char *p = obuf + olen - 4;
+ const char **names = (address_mode == mode_64bit
+ ? names64 : names32);
/* We might have a suffix when disassembling with -Msuffix. */
if (*p == 'i')
--p;
+ /* Remove "addr16/addr32" if we aren't in Intel mode. */
+ if (!intel_syntax
+ && (prefixes & PREFIX_ADDR)
+ && olen >= (4 + 7)
+ && *(p - 1) == ' '
+ && strncmp (p - 7, "addr", 4) == 0
+ && (strncmp (p - 3, "16", 2) == 0
+ || strncmp (p - 3, "32", 2) == 0))
+ p -= 7;
+
if (rm)
{
/* mwait %eax,%ecx */
strcpy (p, "mwait");
if (!intel_syntax)
- strcpy (op1out, names32[0]);
+ strcpy (op1out, names[0]);
}
else
{
@@ -4431,21 +4454,23 @@ PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
strcpy (p, "monitor");
if (!intel_syntax)
{
- if (!mode_64bit)
- strcpy (op1out, names32[0]);
- else if (!(prefixes & PREFIX_ADDR))
- strcpy (op1out, names64[0]);
+ const char **op1_names;
+ if (!(prefixes & PREFIX_ADDR))
+ op1_names = (address_mode == mode_16bit
+ ? names16 : names);
else
{
- strcpy (op1out, names32[0]);
+ op1_names = (address_mode != mode_32bit
+ ? names32 : names16);
used_prefixes |= PREFIX_ADDR;
}
- strcpy (op3out, names32[2]);
+ strcpy (op1out, op1_names[0]);
+ strcpy (op3out, names[2]);
}
}
if (!intel_syntax)
{
- strcpy (op2out, names32[1]);
+ strcpy (op2out, names[1]);
two_source_ops = 1;
}
@@ -4513,7 +4538,7 @@ SVME_Fixup (int bytemode, int sizeflag)
case 0xda:
case 0xdb:
*obufp++ = open_char;
- if (mode_64bit || (sizeflag & AFLAG))
+ if (address_mode == mode_64bit || (sizeflag & AFLAG))
alt = names32[0];
else
alt = names16[0];