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