* i386-dis.c (print_insn_i8086): New routine to disassemble using

the 8086 instruction set.
	* i386-dis.c:  General cleanups.  Make most things static.  Add
	prototypes.  Get rid of static variables aflags and dflags.  Pass
	them as args (to almost everything).
This commit is contained in:
Stu Grossman 1996-07-12 17:15:38 +00:00
parent 59d3634c87
commit be0c8b0508
2 changed files with 245 additions and 162 deletions

View File

@ -1,3 +1,11 @@
Fri Jul 12 10:12:01 1996 Stu Grossman (grossman@critters.cygnus.com)
* i386-dis.c (print_insn_i8086): New routine to disassemble using
the 8086 instruction set.
* i386-dis.c: General cleanups. Make most things static. Add
prototypes. Get rid of static variables aflags and dflags. Pass
them as args (to almost everything).
Thu Jul 11 11:58:44 1996 Jeffrey A Law (law@cygnus.com) Thu Jul 11 11:58:44 1996 Jeffrey A Law (law@cygnus.com)
* h8300-dis.c (bfd_h8_disassemble): Handle macregs in ldmac insns. * h8300-dis.c (bfd_h8_disassemble): Handle macregs in ldmac insns.

View File

@ -1,5 +1,5 @@
/* Print i386 instructions for GDB, the GNU debugger. /* Print i386 instructions for GDB, the GNU debugger.
Copyright (C) 1988, 1989, 1991, 1993, 1994, 1995 Free Software Foundation, Inc. Copyright (C) 1988, 89, 91, 93, 94, 95, 1996 Free Software Foundation, Inc.
This file is part of GDB. This file is part of GDB.
@ -139,13 +139,19 @@ fetch_data (info, addr)
#define fs OP_REG, fs_reg #define fs OP_REG, fs_reg
#define gs OP_REG, gs_reg #define gs OP_REG, gs_reg
int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG(); typedef int op_rtn PARAMS ((int bytemode, int aflag, int dflag));
int OP_J(), OP_SEG();
int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
int OP_D(), OP_T(), OP_rm();
static void dofloat (), putop (), append_prefix (), set_op (); static op_rtn OP_E, OP_G, OP_I, OP_indirE, OP_sI, OP_REG, OP_J, OP_DIR, OP_OFF;
static int get16 (), get32 (); static op_rtn OP_ESDI, OP_DSSI, OP_SEG, OP_ONE, OP_C, OP_D, OP_T, OP_rm, OP_ST;
static op_rtn OP_STi;
static void append_prefix PARAMS ((void));
static void set_op PARAMS ((int op));
static void putop PARAMS ((char *template, int aflag, int dflag));
static void dofloat PARAMS ((int aflag, int dflag));
static int get16 PARAMS ((void));
static int get32 PARAMS ((void));
static void ckprefix PARAMS ((void));
#define b_mode 1 #define b_mode 1
#define v_mode 2 #define v_mode 2
@ -212,15 +218,15 @@ static int get16 (), get32 ();
struct dis386 { struct dis386 {
char *name; char *name;
int (*op1)(); op_rtn *op1;
int bytemode1; int bytemode1;
int (*op2)(); op_rtn *op2;
int bytemode2; int bytemode2;
int (*op3)(); op_rtn *op3;
int bytemode3; int bytemode3;
}; };
struct dis386 dis386[] = { static struct dis386 dis386[] = {
/* 00 */ /* 00 */
{ "addb", Eb, Gb }, { "addb", Eb, Gb },
{ "addS", Ev, Gv }, { "addS", Ev, Gv },
@ -511,7 +517,7 @@ struct dis386 dis386[] = {
{ GRP5 }, { GRP5 },
}; };
struct dis386 dis386_twobyte[] = { static struct dis386 dis386_twobyte[] = {
/* 00 */ /* 00 */
{ GRP6 }, { GRP6 },
{ GRP7 }, { GRP7 },
@ -732,7 +738,7 @@ static disassemble_info *the_info;
static int mod; static int mod;
static int rm; static int rm;
static int reg; static int reg;
static void oappend (); static void oappend PARAMS ((char *s));
static char *names32[]={ static char *names32[]={
"%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi", "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
@ -746,8 +752,11 @@ static char *names8[] = {
static char *names_seg[] = { static char *names_seg[] = {
"%es","%cs","%ss","%ds","%fs","%gs","%?","%?", "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
}; };
static char *index16[] = {
"bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
};
struct dis386 grps[][8] = { static struct dis386 grps[][8] = {
/* GRP1b */ /* GRP1b */
{ {
{ "addb", Eb, Ib }, { "addb", Eb, Ib },
@ -1004,9 +1013,6 @@ ckprefix ()
} }
} }
static int dflag;
static int aflag;
static char op1out[100], op2out[100], op3out[100]; static char op1out[100], op2out[100], op3out[100];
static int op_address[3], op_ad, op_index[3]; static int op_address[3], op_ad, op_index[3];
static int start_pc; static int start_pc;
@ -1021,10 +1027,28 @@ static int start_pc;
* The function returns the length of this instruction in bytes. * The function returns the length of this instruction in bytes.
*/ */
int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int aflag,
int dflag));
int int
print_insn_i386 (pc, info) print_insn_i386 (pc, info)
bfd_vma pc; bfd_vma pc;
disassemble_info *info; disassemble_info *info;
{
print_insn_x86 (pc, info, 1, 1);
}
int
print_insn_i8086 (pc, info)
bfd_vma pc;
disassemble_info *info;
{
print_insn_x86 (pc, info, 0, 0);
}
int
print_insn_x86 (pc, info, aflag, dflag)
bfd_vma pc;
disassemble_info *info;
{ {
struct dis386 *dp; struct dis386 *dp;
int i; int i;
@ -1080,10 +1104,6 @@ print_insn_i386 (pc, info)
return (1); return (1);
} }
/* these would be initialized to 0 if disassembling for 8086 or 286 */
dflag = 1;
aflag = 1;
if (prefixes & PREFIX_DATA) if (prefixes & PREFIX_DATA)
dflag ^= 1; dflag ^= 1;
@ -1116,29 +1136,29 @@ print_insn_i386 (pc, info)
if (dp->name == NULL && dp->bytemode1 == FLOATCODE) if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
{ {
dofloat (); dofloat (aflag, dflag);
} }
else else
{ {
if (dp->name == NULL) if (dp->name == NULL)
dp = &grps[dp->bytemode1][reg]; dp = &grps[dp->bytemode1][reg];
putop (dp->name); putop (dp->name, aflag, dflag);
obufp = op1out; obufp = op1out;
op_ad = 2; op_ad = 2;
if (dp->op1) if (dp->op1)
(*dp->op1)(dp->bytemode1); (*dp->op1)(dp->bytemode1, aflag, dflag);
obufp = op2out; obufp = op2out;
op_ad = 1; op_ad = 1;
if (dp->op2) if (dp->op2)
(*dp->op2)(dp->bytemode2); (*dp->op2)(dp->bytemode2, aflag, dflag);
obufp = op3out; obufp = op3out;
op_ad = 0; op_ad = 0;
if (dp->op3) if (dp->op3)
(*dp->op3)(dp->bytemode3); (*dp->op3)(dp->bytemode3, aflag, dflag);
} }
obufp = obuf + strlen (obuf); obufp = obuf + strlen (obuf);
@ -1197,7 +1217,7 @@ print_insn_i386 (pc, info)
return (codep - inbuf); return (codep - inbuf);
} }
char *float_mem[] = { static char *float_mem[] = {
/* d8 */ /* d8 */
"fadds", "fadds",
"fmuls", "fmuls",
@ -1274,7 +1294,6 @@ char *float_mem[] = {
#define ST OP_ST, 0 #define ST OP_ST, 0
#define STi OP_STi, 0 #define STi OP_STi, 0
int OP_ST(), OP_STi();
#define FGRPd9_2 NULL, NULL, 0 #define FGRPd9_2 NULL, NULL, 0
#define FGRPd9_4 NULL, NULL, 1 #define FGRPd9_4 NULL, NULL, 1
@ -1286,7 +1305,7 @@ int OP_ST(), OP_STi();
#define FGRPde_3 NULL, NULL, 7 #define FGRPde_3 NULL, NULL, 7
#define FGRPdf_4 NULL, NULL, 8 #define FGRPdf_4 NULL, NULL, 8
struct dis386 float_reg[][8] = { static struct dis386 float_reg[][8] = {
/* d8 */ /* d8 */
{ {
{ "fadd", ST, STi }, { "fadd", ST, STi },
@ -1378,7 +1397,7 @@ struct dis386 float_reg[][8] = {
}; };
char *fgrps[][8] = { static char *fgrps[][8] = {
/* d9_2 0 */ /* d9_2 0 */
{ {
"fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
@ -1427,7 +1446,9 @@ char *fgrps[][8] = {
}; };
static void static void
dofloat () dofloat (aflag, dflag)
int aflag;
int dflag;
{ {
struct dis386 *dp; struct dis386 *dp;
unsigned char floatop; unsigned char floatop;
@ -1436,9 +1457,9 @@ dofloat ()
if (mod != 3) if (mod != 3)
{ {
putop (float_mem[(floatop - 0xd8) * 8 + reg]); putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag);
obufp = op1out; obufp = op1out;
OP_E (v_mode); OP_E (v_mode, aflag, dflag);
return; return;
} }
codep++; codep++;
@ -1446,7 +1467,7 @@ dofloat ()
dp = &float_reg[floatop - 0xd8][reg]; dp = &float_reg[floatop - 0xd8][reg];
if (dp->name == NULL) if (dp->name == NULL)
{ {
putop (fgrps[dp->bytemode1][rm]); putop (fgrps[dp->bytemode1][rm], aflag, dflag);
/* instruction fnstsw is only one with strange arg */ /* instruction fnstsw is only one with strange arg */
if (floatop == 0xdf if (floatop == 0xdf
&& FETCH_DATA (the_info, codep + 1) && FETCH_DATA (the_info, codep + 1)
@ -1455,29 +1476,33 @@ dofloat ()
} }
else else
{ {
putop (dp->name); putop (dp->name, aflag, dflag);
obufp = op1out; obufp = op1out;
if (dp->op1) if (dp->op1)
(*dp->op1)(dp->bytemode1); (*dp->op1)(dp->bytemode1, aflag, dflag);
obufp = op2out; obufp = op2out;
if (dp->op2) if (dp->op2)
(*dp->op2)(dp->bytemode2); (*dp->op2)(dp->bytemode2, aflag, dflag);
} }
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_ST (ignore) OP_ST (ignore, aflag, dflag)
int ignore; int ignore;
int aflag;
int dflag;
{ {
oappend ("%st"); oappend ("%st");
return (0); return (0);
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_STi (ignore) OP_STi (ignore, aflag, dflag)
int ignore; int ignore;
int aflag;
int dflag;
{ {
sprintf (scratchbuf, "%%st(%d)", rm); sprintf (scratchbuf, "%%st(%d)", rm);
oappend (scratchbuf); oappend (scratchbuf);
@ -1487,8 +1512,10 @@ OP_STi (ignore)
/* capital letters in template are macros */ /* capital letters in template are macros */
static void static void
putop (template) putop (template, aflag, dflag)
char *template; char *template;
int aflag;
int dflag;
{ {
char *p; char *p;
@ -1500,7 +1527,7 @@ putop (template)
*obufp++ = *p; *obufp++ = *p;
break; break;
case 'C': /* For jcxz/jecxz */ case 'C': /* For jcxz/jecxz */
if (aflag == 0) if (aflag)
*obufp++ = 'e'; *obufp++ = 'e';
break; break;
case 'N': case 'N':
@ -1545,33 +1572,27 @@ append_prefix ()
oappend ("%gs:"); oappend ("%gs:");
} }
int static int
OP_indirE (bytemode) OP_indirE (bytemode, aflag, dflag)
int bytemode; int bytemode;
int aflag;
int dflag;
{ {
oappend ("*"); oappend ("*");
OP_E (bytemode); return OP_E (bytemode, aflag, dflag);
return (0);
} }
int static int
OP_E (bytemode) OP_E (bytemode, aflag, dflag)
int bytemode; int bytemode;
int aflag;
int dflag;
{ {
int disp; int disp;
int havesib;
int base;
int index;
int scale;
int havebase;
/* skip mod/rm byte */ /* skip mod/rm byte */
codep++; codep++;
havesib = 0;
havebase = 0;
disp = 0;
if (mod == 3) if (mod == 3)
{ {
switch (bytemode) switch (bytemode)
@ -1592,90 +1613,114 @@ OP_E (bytemode)
oappend ("<bad dis table>"); oappend ("<bad dis table>");
break; break;
} }
return (0); return 0;
} }
disp = 0;
append_prefix (); append_prefix ();
if (rm == 4)
if (aflag) /* 32 bit address mode */
{ {
havesib = 1; int havesib;
int havebase;
int base;
int index;
int scale;
havesib = 0;
havebase = 1; havebase = 1;
FETCH_DATA (the_info, codep + 1); base = rm;
scale = (*codep >> 6) & 3;
index = (*codep >> 3) & 7; if (base == 4)
base = *codep & 7;
codep++;
}
switch (mod)
{
case 0:
switch (rm)
{ {
case 4: havesib = 1;
/* implies havesib and havebase */ FETCH_DATA (the_info, codep + 1);
if (base == 5) { scale = (*codep >> 6) & 3;
havebase = 0; index = (*codep >> 3) & 7;
disp = get32 (); base = *codep & 7;
} codep++;
}
switch (mod)
{
case 0:
if (base == 5)
{
havebase = 0;
disp = get32 ();
}
break; break;
case 5: case 1:
FETCH_DATA (the_info, codep + 1);
disp = *(char *)codep++;
break;
case 2:
disp = get32 (); disp = get32 ();
break; break;
default:
havebase = 1;
base = rm;
break;
} }
break;
case 1: if (mod != 0 || base == 5)
FETCH_DATA (the_info, codep + 1);
disp = *(char *)codep++;
if (rm != 4)
{ {
havebase = 1; sprintf (scratchbuf, "0x%x", disp);
base = rm;
}
break;
case 2:
disp = get32 ();
if (rm != 4)
{
havebase = 1;
base = rm;
}
break;
}
if (mod != 0 || rm == 5 || (havesib && base == 5))
{
sprintf (scratchbuf, "0x%x", disp);
oappend (scratchbuf);
}
if (havebase || havesib)
{
oappend ("(");
if (havebase)
oappend (names32[base]);
if (havesib)
{
if (index != 4)
{
sprintf (scratchbuf, ",%s", names32[index]);
oappend (scratchbuf);
}
sprintf (scratchbuf, ",%d", 1 << scale);
oappend (scratchbuf); oappend (scratchbuf);
} }
oappend (")");
if (havebase || (havesib && (index != 4 || scale != 0)))
{
oappend ("(");
if (havebase)
oappend (names32[base]);
if (havesib)
{
if (index != 4)
{
sprintf (scratchbuf, ",%s", names32[index]);
oappend (scratchbuf);
}
sprintf (scratchbuf, ",%d", 1 << scale);
oappend (scratchbuf);
}
oappend (")");
}
} }
return (0); else
{ /* 16 bit address mode */
switch (mod)
{
case 0:
if (rm == 6)
disp = (short) get16 ();
break;
case 1:
FETCH_DATA (the_info, codep + 1);
disp = *(char *)codep++;
break;
case 2:
disp = (short) get16 ();
break;
}
if (mod != 0 || rm == 6)
{
sprintf (scratchbuf, "0x%x", disp);
oappend (scratchbuf);
}
if (mod != 0 || rm != 6)
{
oappend ("(");
oappend (index16[rm]);
oappend (")");
}
}
return 0;
} }
int static int
OP_G (bytemode) OP_G (bytemode, aflag, dflag)
int bytemode; int bytemode;
int aflag;
int dflag;
{ {
switch (bytemode) switch (bytemode)
{ {
@ -1733,9 +1778,11 @@ set_op (op)
op_address[op_ad] = op; op_address[op_ad] = op;
} }
int static int
OP_REG (code) OP_REG (code, aflag, dflag)
int code; int code;
int aflag;
int dflag;
{ {
char *s; char *s;
@ -1769,9 +1816,11 @@ OP_REG (code)
return (0); return (0);
} }
int static int
OP_I (bytemode) OP_I (bytemode, aflag, dflag)
int bytemode; int bytemode;
int aflag;
int dflag;
{ {
int op; int op;
@ -1799,9 +1848,11 @@ OP_I (bytemode)
return (0); return (0);
} }
int static int
OP_sI (bytemode) OP_sI (bytemode, aflag, dflag)
int bytemode; int bytemode;
int aflag;
int dflag;
{ {
int op; int op;
@ -1829,9 +1880,11 @@ OP_sI (bytemode)
return (0); return (0);
} }
int static int
OP_J (bytemode) OP_J (bytemode, aflag, dflag)
int bytemode; int bytemode;
int aflag;
int dflag;
{ {
int disp; int disp;
int mask = -1; int mask = -1;
@ -1866,9 +1919,11 @@ OP_J (bytemode)
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_SEG (dummy) OP_SEG (dummy, aflag, dflag)
int dummy; int dummy;
int aflag;
int dflag;
{ {
static char *sreg[] = { static char *sreg[] = {
"%es","%cs","%ss","%ds","%fs","%gs","%?","%?", "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
@ -1878,9 +1933,11 @@ OP_SEG (dummy)
return (0); return (0);
} }
int static int
OP_DIR (size) OP_DIR (size, aflag, dflag)
int size; int size;
int aflag;
int dflag;
{ {
int seg, offset; int seg, offset;
@ -1919,12 +1976,16 @@ OP_DIR (size)
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_OFF (bytemode) OP_OFF (bytemode, aflag, dflag)
int bytemode; int bytemode;
int aflag;
int dflag;
{ {
int off; int off;
append_prefix ();
if (aflag) if (aflag)
off = get32 (); off = get32 ();
else else
@ -1936,9 +1997,11 @@ OP_OFF (bytemode)
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_ESDI (dummy) OP_ESDI (dummy, aflag, dflag)
int dummy; int dummy;
int aflag;
int dflag;
{ {
oappend ("%es:("); oappend ("%es:(");
oappend (aflag ? "%edi" : "%di"); oappend (aflag ? "%edi" : "%di");
@ -1947,9 +2010,11 @@ OP_ESDI (dummy)
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_DSSI (dummy) OP_DSSI (dummy, aflag, dflag)
int dummy; int dummy;
int aflag;
int dflag;
{ {
oappend ("%ds:("); oappend ("%ds:(");
oappend (aflag ? "%esi" : "%si"); oappend (aflag ? "%esi" : "%si");
@ -1958,18 +2023,22 @@ OP_DSSI (dummy)
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_ONE (dummy) OP_ONE (dummy, aflag, dflag)
int dummy; int dummy;
int aflag;
int dflag;
{ {
oappend ("1"); oappend ("1");
return (0); return (0);
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_C (dummy) OP_C (dummy, aflag, dflag)
int dummy; int dummy;
int aflag;
int dflag;
{ {
codep++; /* skip mod/rm */ codep++; /* skip mod/rm */
sprintf (scratchbuf, "%%cr%d", reg); sprintf (scratchbuf, "%%cr%d", reg);
@ -1978,9 +2047,11 @@ OP_C (dummy)
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_D (dummy) OP_D (dummy, aflag, dflag)
int dummy; int dummy;
int aflag;
int dflag;
{ {
codep++; /* skip mod/rm */ codep++; /* skip mod/rm */
sprintf (scratchbuf, "%%db%d", reg); sprintf (scratchbuf, "%%db%d", reg);
@ -1989,9 +2060,11 @@ OP_D (dummy)
} }
/* ARGSUSED */ /* ARGSUSED */
int static int
OP_T (dummy) OP_T (dummy, aflag, dflag)
int dummy; int dummy;
int aflag;
int dflag;
{ {
codep++; /* skip mod/rm */ codep++; /* skip mod/rm */
sprintf (scratchbuf, "%%tr%d", reg); sprintf (scratchbuf, "%%tr%d", reg);
@ -1999,9 +2072,11 @@ OP_T (dummy)
return (0); return (0);
} }
int static int
OP_rm (bytemode) OP_rm (bytemode, aflag, dflag)
int bytemode; int bytemode;
int aflag;
int dflag;
{ {
switch (bytemode) switch (bytemode)
{ {