aboutsummaryrefslogtreecommitdiff
path: root/opcodes/i386-dis.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2001-06-06 10:24:18 +0000
committerAlan Modra <amodra@gmail.com>2001-06-06 10:24:18 +0000
commit3ffd33cf59cb308d57b1778cd6ec8ed27cdf2f51 (patch)
tree312c7acf96da22d744ba7802ccd218c333f6d6f7 /opcodes/i386-dis.c
parentcb9401fc47194d97851787942c77aa61c3a6dd46 (diff)
downloadgdb-3ffd33cf59cb308d57b1778cd6ec8ed27cdf2f51.zip
gdb-3ffd33cf59cb308d57b1778cd6ec8ed27cdf2f51.tar.gz
gdb-3ffd33cf59cb308d57b1778cd6ec8ed27cdf2f51.tar.bz2
* i386-dis.c (cond_jump_flag, loop_jcxz_flag): Define.
(cond_jump_mode, loop_jcxz_mode): Define. (dis386_att): Add cond_jump_flag and loop_jcxz_flag as appropriate, and 'F' suffix to loop insns. (disx86_64_att): Likewise. (dis386_twobyte_att): Likewise. (print_insn_i386): Don't output addr prefix for loop, jcxz insns. Output data size prefix for long conditional jumps. Output cs and ds branch hints. (putop): Handle 'F', and mark PREFIX_ADDR used for case 'E'. (OP_J): Don't make PREFIX_DATA used.
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r--opcodes/i386-dis.c177
1 files changed, 112 insertions, 65 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 4818a7b..3b93839 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -250,6 +250,9 @@ fetch_data (info, addr)
#define OPSUF OP_3DNowSuffix, 0
#define OPSIMD OP_SIMD_Suffix, 0
+#define cond_jump_flag NULL, cond_jump_mode
+#define loop_jcxz_flag NULL, loop_jcxz_mode
+
/* bits in sizeflag */
#if 0 /* leave undefined until someone adds the extra flag to objdump */
#define SUFFIX_ALWAYS 4
@@ -312,6 +315,8 @@ static void BadOp PARAMS ((void));
#define q_mode 5 /* quad word operand */
#define x_mode 6
#define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
+#define cond_jump_mode 8
+#define loop_jcxz_mode 9
#define es_reg 100
#define cs_reg 101
@@ -430,6 +435,7 @@ struct dis386 {
'A' => print 'b' if no register operands or suffix_always is true
'B' => print 'b' if suffix_always is true
'E' => print 'e' if 32-bit form of jcxz
+ 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
'L' => print 'l' if suffix_always is true
'N' => print 'n' if instruction has no wait "prefix"
'O' => print 'd', or 'o'
@@ -574,23 +580,23 @@ static const struct dis386 dis386_att[] = {
{ "outsb", indirDX, Xb, XX },
{ "outsR", indirDX, Xv, XX },
/* 70 */
- { "jo", Jb, XX, XX },
- { "jno", Jb, XX, XX },
- { "jb", Jb, XX, XX },
- { "jae", Jb, XX, XX },
- { "je", Jb, XX, XX },
- { "jne", Jb, XX, XX },
- { "jbe", Jb, XX, XX },
- { "ja", Jb, XX, XX },
+ { "jo", Jb, cond_jump_flag, XX },
+ { "jno", Jb, cond_jump_flag, XX },
+ { "jb", Jb, cond_jump_flag, XX },
+ { "jae", Jb, cond_jump_flag, XX },
+ { "je", Jb, cond_jump_flag, XX },
+ { "jne", Jb, cond_jump_flag, XX },
+ { "jbe", Jb, cond_jump_flag, XX },
+ { "ja", Jb, cond_jump_flag, XX },
/* 78 */
- { "js", Jb, XX, XX },
- { "jns", Jb, XX, XX },
- { "jp", Jb, XX, XX },
- { "jnp", Jb, XX, XX },
- { "jl", Jb, XX, XX },
- { "jge", Jb, XX, XX },
- { "jle", Jb, XX, XX },
- { "jg", Jb, XX, XX },
+ { "js", Jb, cond_jump_flag, XX },
+ { "jns", Jb, cond_jump_flag, XX },
+ { "jp", Jb, cond_jump_flag, XX },
+ { "jnp", Jb, cond_jump_flag, XX },
+ { "jl", Jb, cond_jump_flag, XX },
+ { "jge", Jb, cond_jump_flag, XX },
+ { "jle", Jb, cond_jump_flag, XX },
+ { "jg", Jb, cond_jump_flag, XX },
/* 80 */
{ GRP1b },
{ GRP1S },
@@ -701,10 +707,10 @@ static const struct dis386 dis386_att[] = {
{ FLOAT },
{ FLOAT },
/* e0 */
- { "loopne", Jb, XX, XX },
- { "loope", Jb, XX, XX },
- { "loop", Jb, XX, XX },
- { "jEcxz", Jb, XX, XX },
+ { "loopneF", Jb, loop_jcxz_flag, XX },
+ { "loopeF", Jb, loop_jcxz_flag, XX },
+ { "loopF", Jb, loop_jcxz_flag, XX },
+ { "jEcxz", Jb, loop_jcxz_flag, XX },
{ "inB", AL, Ib, XX },
{ "inS", eAX, Ib, XX },
{ "outB", Ib, AL, XX },
@@ -1160,23 +1166,23 @@ static const struct dis386 disx86_64_att[] = {
{ "outsb", indirDX, Xb, XX },
{ "outsR", indirDX, Xv, XX },
/* 70 */
- { "jo", Jb, XX, XX },
- { "jno", Jb, XX, XX },
- { "jb", Jb, XX, XX },
- { "jae", Jb, XX, XX },
- { "je", Jb, XX, XX },
- { "jne", Jb, XX, XX },
- { "jbe", Jb, XX, XX },
- { "ja", Jb, XX, XX },
+ { "jo", Jb, cond_jump_flag, XX },
+ { "jno", Jb, cond_jump_flag, XX },
+ { "jb", Jb, cond_jump_flag, XX },
+ { "jae", Jb, cond_jump_flag, XX },
+ { "je", Jb, cond_jump_flag, XX },
+ { "jne", Jb, cond_jump_flag, XX },
+ { "jbe", Jb, cond_jump_flag, XX },
+ { "ja", Jb, cond_jump_flag, XX },
/* 78 */
- { "js", Jb, XX, XX },
- { "jns", Jb, XX, XX },
- { "jp", Jb, XX, XX },
- { "jnp", Jb, XX, XX },
- { "jl", Jb, XX, XX },
- { "jge", Jb, XX, XX },
- { "jle", Jb, XX, XX },
- { "jg", Jb, XX, XX },
+ { "js", Jb, cond_jump_flag, XX },
+ { "jns", Jb, cond_jump_flag, XX },
+ { "jp", Jb, cond_jump_flag, XX },
+ { "jnp", Jb, cond_jump_flag, XX },
+ { "jl", Jb, cond_jump_flag, XX },
+ { "jge", Jb, cond_jump_flag, XX },
+ { "jle", Jb, cond_jump_flag, XX },
+ { "jg", Jb, cond_jump_flag, XX },
/* 80 */
{ GRP1b },
{ GRP1S },
@@ -1287,10 +1293,10 @@ static const struct dis386 disx86_64_att[] = {
{ FLOAT },
{ FLOAT },
/* e0 */
- { "loopne", Jb, XX, XX },
- { "loope", Jb, XX, XX },
- { "loop", Jb, XX, XX },
- { "jEcxz", Jb, XX, XX },
+ { "loopneF", Jb, loop_jcxz_flag, XX },
+ { "loopeF", Jb, loop_jcxz_flag, XX },
+ { "loopF", Jb, loop_jcxz_flag, XX },
+ { "jEcxz", Jb, loop_jcxz_flag, XX },
{ "inB", AL, Ib, XX },
{ "inS", eAX, Ib, XX },
{ "outB", Ib, AL, XX },
@@ -1763,23 +1769,23 @@ static const struct dis386 dis386_twobyte_att[] = {
{ PREGRP23 },
{ PREGRP20 },
/* 80 */
- { "jo", Jv, XX, XX },
- { "jno", Jv, XX, XX },
- { "jb", Jv, XX, XX },
- { "jae", Jv, XX, XX },
- { "je", Jv, XX, XX },
- { "jne", Jv, XX, XX },
- { "jbe", Jv, XX, XX },
- { "ja", Jv, XX, XX },
+ { "jo", Jv, cond_jump_flag, XX },
+ { "jno", Jv, cond_jump_flag, XX },
+ { "jb", Jv, cond_jump_flag, XX },
+ { "jae", Jv, cond_jump_flag, XX },
+ { "je", Jv, cond_jump_flag, XX },
+ { "jne", Jv, cond_jump_flag, XX },
+ { "jbe", Jv, cond_jump_flag, XX },
+ { "ja", Jv, cond_jump_flag, XX },
/* 88 */
- { "js", Jv, XX, XX },
- { "jns", Jv, XX, XX },
- { "jp", Jv, XX, XX },
- { "jnp", Jv, XX, XX },
- { "jl", Jv, XX, XX },
- { "jge", Jv, XX, XX },
- { "jle", Jv, XX, XX },
- { "jg", Jv, XX, XX },
+ { "js", Jv, cond_jump_flag, XX },
+ { "jns", Jv, cond_jump_flag, XX },
+ { "jp", Jv, cond_jump_flag, XX },
+ { "jnp", Jv, cond_jump_flag, XX },
+ { "jl", Jv, cond_jump_flag, XX },
+ { "jge", Jv, cond_jump_flag, XX },
+ { "jle", Jv, cond_jump_flag, XX },
+ { "jg", Jv, cond_jump_flag, XX },
/* 90 */
{ "seto", Eb, XX, XX },
{ "setno", Eb, XX, XX },
@@ -3126,17 +3132,44 @@ print_insn_i386 (pc, info)
used_prefixes |= PREFIX_LOCK;
}
- if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
- sizeflag ^= DFLAG;
-
if (prefixes & PREFIX_ADDR)
{
sizeflag ^= AFLAG;
- if (sizeflag & AFLAG)
- oappend ("addr32 ");
- else
- oappend ("addr16 ");
- used_prefixes |= PREFIX_ADDR;
+ if (dp->bytemode2 != loop_jcxz_mode)
+ {
+ if (sizeflag & AFLAG)
+ oappend ("addr32 ");
+ else
+ oappend ("addr16 ");
+ used_prefixes |= PREFIX_ADDR;
+ }
+ }
+
+ if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
+ {
+ sizeflag ^= DFLAG;
+ if (dp->bytemode2 == cond_jump_mode && dp->bytemode1 == v_mode)
+ {
+ if (sizeflag & DFLAG)
+ oappend ("data32 ");
+ else
+ oappend ("data16 ");
+ used_prefixes |= PREFIX_DATA;
+ }
+ }
+
+ if (dp->bytemode2 == cond_jump_mode || dp->bytemode2 == loop_jcxz_mode)
+ {
+ if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS)
+ {
+ oappend ("cs ");
+ used_prefixes |= PREFIX_CS;
+ }
+ if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
+ {
+ oappend ("ds ");
+ used_prefixes |= PREFIX_DS;
+ }
}
if (need_modrm)
@@ -3717,6 +3750,21 @@ putop (template, sizeflag)
case 'E': /* For jcxz/jecxz */
if (sizeflag & AFLAG)
*obufp++ = 'e';
+ used_prefixes |= (prefixes & PREFIX_ADDR);
+ break;
+ case 'F':
+ if ((prefixes & PREFIX_ADDR)
+#ifdef SUFFIX_ALWAYS
+ || (sizeflag & SUFFIX_ALWAYS)
+#endif
+ )
+ {
+ if (sizeflag & AFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_ADDR);
+ }
break;
case 'I':
if (intel_syntax)
@@ -4703,7 +4751,6 @@ OP_J (bytemode, sizeflag)
displacement is added! */
mask = 0xffff;
}
- used_prefixes |= (prefixes & PREFIX_DATA);
break;
default:
oappend (INTERNAL_DISASSEMBLER_ERROR);