ack/util/ego/share/show.c
1984-11-26 15:04:22 +00:00

416 lines
6.9 KiB
C

/* S H O W . C */
/* This program can be used to make the output of the 'cf' pass
* human readable. It will display either the procedure table,
* the datablock table, the basic block table or the EM text,
* depending on the flag that is passed as first argument.
*/
#include <stdio.h>
#include "../../../h/em_spec.h"
#include "../../../h/em_flag.h"
#include "../../../h/em_pseu.h"
#include "../share/types.h"
#include "../share/def.h"
#include "../share/global.h"
#define BMASK 0377
extern byte em_flag[];
#define space1() printf(" ")
char format[] = " %-11s%d\n";
char lformat[] = " %-11s%D\n";
char sformat[] = " %-10s%s\n";
char dformat[] = " %-11s%d\n";
char oformat[] = " %-11s%D\n";
FILE *f; /* input file */
#define getbyte() getc(f)
short getshort()
{
register n;
n = getbyte();
n |= getbyte() << 8;
return n;
}
int getint()
{
/* Read an integer from the input file. This routine is
* only used when reading a bitvector-set. We expect an
* integer to be either a short or a long.
*/
if (sizeof(int) == sizeof(short)) {
return getshort();
} else {
return getoff();
}
}
offset getoff()
{
register offset n;
n = (unsigned) getshort();
n |= ((offset) getshort() ) << 16;
return n;
}
/* VARARGS 1 */
error(s,a) char *s,*a; {
fprintf(stderr,"error");
fprintf(stderr,": ");
fprintf(stderr,s,a);
fprintf(stderr,"\n");
abort();
exit(-1);
}
main(argc, argv)
int argc;
char *argv[];
{
if (argc != 3 || argv[1][0] != '-') {
error("usage: %s -[ldpbc] filename",argv[0]);
}
if ((f = fopen(argv[2], "r")) == NULL) {
error("cannot open %s", argv[2]);
}
switch(argv[1][1]) {
case 'l':
showl();
break;
case 'd':
showd();
break;
case 'p':
showp();
break;
case 'b':
showb();
break;
case 'c':
showc();
break;
default:
error("bad flag");
}
fclose(f);
}
showcset()
{
/* print a compact (bitvector) set */
short size;
register short i,j;
int w, mask;
size = getshort();
/* # significant bits in bitvector */
i = 1;
printf(" { ");
if (size == 0) {
printf("}\n");
return;
}
for (;;) {
w = getint();
mask = 1 ;
for (j = 1; j <= WORDLENGTH; j++) {
if (w & mask) {
printf("%d ",i);
}
if (i++ == size) {
printf ("}\n");
return;
}
mask <<= 1;
}
}
}
showp()
{
byte b;
short n;
short all;
printf("total number of procs: %d\n\n",getshort());
all = getshort();
while (TRUE) {
n = getshort();
if (feof(f)) break;
printf("PROC\n");
printf(format,"id =",n);
printf(format,"flags1 =",b = getbyte());
if (b & PF_BODYSEEN) {
printf(format,"# labels =",getshort());
printf(lformat,"# locals =",getoff());
printf(lformat,"# formals =",getoff());
if (all == 1) {
printf(" changed ="); showcset();
printf(format,"c_flags =",getshort());
printf(" used ="); showcset();
printf(format,"u_flags =",getshort());
printf(" calling ="); showcset();
}
} else {
printf(" body not available\n");
}
}
}
char *pseudo[] = {"hol", "bss", "rom", "con", "unknown" };
showd()
{
short n;
printf("total number of objects: %d\n\n",getshort());
while (TRUE) {
n = getbyte();
if (feof(f)) break;
switch(n) {
case MARK_DBLOCK:
printf("DBLOCK\n");
printf(format,"id =",getshort());
printf(sformat,"pseudo =",
pseudo[(short) getbyte()]);
printf(lformat,"size =",getoff());
printf(format,"fragment =",getshort());
printf(format,"flags1 =",
(short) getbyte());
break;
case MARK_OBJ:
printf(" OBJ\n");
space1();
printf(format,"id =",getshort());
space1();
printf(lformat,"size =",getoff());
space1();
printf(lformat,"offset =",getoff());
break;
case MARK_ARG:
printf(" VALUE\n");
space1();
printf(lformat,"offset =",getoff());
break;
}
}
}
/* The mnemonics of the EM instructions and pseudos */
extern char em_mnem[];
extern char em_pseu[];
char lab_mnem[] = "instrlab";
char sym_mnem[] = "datalab";
showinstr()
{
short instr;
char *s;
instr = (short) getbyte();
if (feof(f)) return FALSE;
if (instr >= sp_fmnem && instr <= sp_lmnem) {
s = &(em_mnem[(instr-sp_fmnem) *4]);
} else {
if (instr == op_lab) {
s = lab_mnem;
} else {
if (instr == ps_sym) {
s = sym_mnem;
} else {
s = &(em_pseu[(instr-sp_fpseu)*4]);
}
}
}
printf("%s",s);
switch((short) getbyte()) {
case OPSHORT:
case OPOBJECT:
printf(" %d", getshort());
break;
case OPPROC:
printf(" $%d",getshort());
break;
case OPINSTRLAB:
printf(" *%d",getshort());
break;
case OPOFFSET:
printf(" %D", getoff());
break;
case OPLIST:
arglist();
break;
}
printf("\n");
return TRUE;
}
showl()
{
while (showinstr());
}
arglist()
{
short length;
for (;;) {
switch((short) getbyte()) {
case ARGOBJECT:
printf(" %d", getshort());
break;
case ARGPROC:
printf(" $%d",getshort());
break;
case ARGINSTRLAB:
printf(" *%d",getshort());
break;
case ARGOFF:
printf(" %D", getoff());
break;
case ARGICN:
case ARGUCN:
case ARGFCN:
printf(" %d",getshort());
/* Fall through !! */
case ARGSTRING:
length = getshort();
putchar(' ');
putchar('"');
while (length--) {
putchar(getbyte());
}
putchar('"');
break;
case ARGCEND:
return;
}
}
}
showlset()
{
register short x;
printf("{ ");
while (x = getshort()) {
printf("%d ",x);
}
printf("}\n");
}
showb()
{
/* basic block file */
short n,m;
while (TRUE) {
n = getshort();
if (feof(f)) break;
if (n == 0) {
printf("Declaration Unit:\n");
printf(dformat,"#instrs =",getshort());
printf("\n");
continue;
}
printf("Control Flow Graph:\n");
printf("number of basic blocks: %d\n",n);
m = getshort(); /* #loops */
while (n--) {
printf(" BASIC BLOCK\n");
printf(dformat,"id =",getshort());
printf(dformat,"# instrs =",getshort());
printf(" succ =");
showlset();
printf(" pred =");
showlset();
printf(dformat,"idom =",getshort());
printf(" loops =");
showlset();
printf(dformat,"flags =",getshort());
}
printf("number of loops: %d\n",m);
while (m--) {
printf(" LOOP\n");
printf(dformat,"id =",getshort());
printf(dformat,"level =",getshort());
printf(dformat,"entry =",getshort());
printf(dformat,"end =",getshort());
}
printf("\n");
}
}
showc()
{
int n,m,cnt,t;
cnt = 1;
while(TRUE) {
t = getshort();
if (feof(f)) break;
printf("CALL %d\n",cnt++);
printf(format,"nestlevel =",t);
printf(format,"calling p. =",getshort());
printf(format,"call_id =",getshort());
printf(format,"called p. =",getshort());
printf(format,"looplevel =",getbyte());
printf(format,"flags =",getbyte());
printf(format,"ratio =",getshort());
printf(" actuals:");
n = getshort();
if (n == 0) {
printf(" ---\n");
} else {
while (n--) {
printf("\n");
m = getshort();
printf(oformat,"size =",getoff());
printf(dformat,"inl =",getbyte());
while (m--) {
printf(" ");
showinstr();
}
}
}
}
}