15485Slinton /* Copyright (c) 1982 Regents of the University of California */
25485Slinton 
3*5743Slinton static char sccsid[] = "@(#)printinst.c 1.2 02/10/82";
45485Slinton 
55485Slinton /*
65485Slinton  * decode and print the instructions
75485Slinton  */
85485Slinton 
95485Slinton #include "defs.h"
105485Slinton #include "machine.h"
115485Slinton #include "process.h"
125485Slinton #include "pxops.h"
135485Slinton #include "optab.h"
145485Slinton #include "object.h"
155485Slinton 
165485Slinton LOCAL ADDRESS printop(), docase();
175485Slinton 
185485Slinton /*
195485Slinton  * print instructions within the given address range
205485Slinton  */
215485Slinton 
225485Slinton printinst(lowaddr, highaddr)
235485Slinton ADDRESS lowaddr;
245485Slinton ADDRESS highaddr;
255485Slinton {
26*5743Slinton     register ADDRESS addr;
275485Slinton 
28*5743Slinton     for (addr = lowaddr; addr <= highaddr; ) {
29*5743Slinton 	addr = printop(addr);
30*5743Slinton     }
315485Slinton }
325485Slinton 
335485Slinton /*
345485Slinton  * print count instructions from given address
355485Slinton  */
365485Slinton 
375485Slinton printninst(count, addr)
385485Slinton int count;
395485Slinton ADDRESS addr;
405485Slinton {
41*5743Slinton     int i;
425485Slinton 
43*5743Slinton     for (i = 0; i < count; i++) {
44*5743Slinton 	addr = printop(addr);
45*5743Slinton     }
465485Slinton }
475485Slinton 
485485Slinton /*
495485Slinton  * print the opcode at the given address, return the address
505485Slinton  * of the next instruction
515485Slinton  */
525485Slinton 
535485Slinton LOCAL ADDRESS printop(addr)
545485Slinton register ADDRESS addr;
555485Slinton {
56*5743Slinton     int i;
57*5743Slinton     PXOP op;
58*5743Slinton     OPTAB *o;
59*5743Slinton     char subop;
60*5743Slinton     short arg;
61*5743Slinton     long longarg;
62*5743Slinton     union {
63*5743Slinton 	short i;
64*5743Slinton 	struct { char c1, c2; } opword;
65*5743Slinton     } u;
665485Slinton 
67*5743Slinton     iread(&u.i, addr, sizeof(u.i));
68*5743Slinton     op = (PXOP) u.opword.c1;
69*5743Slinton     subop = u.opword.c2;
70*5743Slinton     o = &optab[op];
71*5743Slinton     printf("%5d   %s", addr, o->opname);
72*5743Slinton     addr += sizeof(u);
73*5743Slinton     for (i = 0; o->argtype[i] != 0; i++) {
74*5743Slinton 	if (i == 0) {
75*5743Slinton 	    putchar('\t');
76*5743Slinton 	} else {
77*5743Slinton 	    putchar(',');
78*5743Slinton 	}
79*5743Slinton 	switch(o->argtype[i]) {
80*5743Slinton 	    case ADDR4:
81*5743Slinton 	    case LWORD:
82*5743Slinton 		iread(&longarg, addr, sizeof(longarg));
83*5743Slinton 		printf("%d", longarg);
84*5743Slinton 		addr += sizeof(long);
85*5743Slinton 		break;
86*5743Slinton 
87*5743Slinton 	    case SUBOP:
88*5743Slinton 		printf("%d", subop);
89*5743Slinton 		break;
90*5743Slinton 
91*5743Slinton 	    case ADDR2:
92*5743Slinton 	    case DISP:
93*5743Slinton 	    case PSUBOP:
94*5743Slinton 	    case VLEN:
95*5743Slinton 	    case HWORD:
96*5743Slinton 		if (i != 0 || subop == 0) {
97*5743Slinton 		    iread(&arg, addr, sizeof(arg));
98*5743Slinton 		    addr += sizeof(short);
995485Slinton 		} else {
100*5743Slinton 		    arg = subop;
1015485Slinton 		}
102*5743Slinton 		printf("%d", arg);
103*5743Slinton 		break;
1045485Slinton 
105*5743Slinton 	    case STRING: {
106*5743Slinton 		char c;
1075485Slinton 
108*5743Slinton 		putchar('\'');
109*5743Slinton 		while (subop > 0) {
110*5743Slinton 		    iread(&c, addr, sizeof(c));
111*5743Slinton 		    if (c == '\0') {
112*5743Slinton 			break;
113*5743Slinton 		    }
114*5743Slinton 		    putchar(c);
115*5743Slinton 		    subop--;
116*5743Slinton 		    addr++;
117*5743Slinton 		}
118*5743Slinton 		addr++;
119*5743Slinton 		putchar('\'');
120*5743Slinton 		if ((addr&1) != 0) {
121*5743Slinton 		    addr++;
122*5743Slinton 		}
123*5743Slinton 		break;
124*5743Slinton 	    }
1255485Slinton 
126*5743Slinton 	    default:
127*5743Slinton 		panic("bad argtype %d", o->argtype[i]);
128*5743Slinton 		/*NOTREACHED*/
129*5743Slinton 	}
130*5743Slinton     }
131*5743Slinton     switch(op) {
132*5743Slinton 	case O_CON:
133*5743Slinton 	    addr += arg;
134*5743Slinton 	    break;
1355485Slinton 
136*5743Slinton 	case O_CASE1OP:
137*5743Slinton 	    addr = docase(addr, 1, subop);
138*5743Slinton 	    break;
1395485Slinton 
140*5743Slinton 	case O_CASE2OP:
141*5743Slinton 	    addr = docase(addr, 2, subop);
142*5743Slinton 	    break;
1435485Slinton 
144*5743Slinton 	case O_CASE4OP:
145*5743Slinton 	    addr = docase(addr, 4, subop);
146*5743Slinton 	    break;
147*5743Slinton     }
148*5743Slinton     putchar('\n');
149*5743Slinton     return(addr);
1505485Slinton }
1515485Slinton 
1525485Slinton /*
1535485Slinton  * print out the destinations and cases
1545485Slinton  */
1555485Slinton 
1565485Slinton LOCAL ADDRESS docase(addr, size, n)
1575485Slinton ADDRESS addr;
1585485Slinton int size;
1595485Slinton int n;
1605485Slinton {
161*5743Slinton     register int i;
162*5743Slinton     char c;
163*5743Slinton     short arg;
164*5743Slinton     long longarg;
1655485Slinton 
166*5743Slinton     iread(&arg, addr, sizeof(arg));
167*5743Slinton     printf("\n\t%5d", arg);
168*5743Slinton     addr += 2;
169*5743Slinton     for (i = 1; i < n; i++) {
1705485Slinton 	iread(&arg, addr, sizeof(arg));
171*5743Slinton 	printf(", %5d", arg);
1725485Slinton 	addr += 2;
173*5743Slinton     }
174*5743Slinton     printf("\n\t");
175*5743Slinton     for (i = 0; i < n; i++) {
176*5743Slinton 	switch(size) {
177*5743Slinton 	    case 1:
178*5743Slinton 		iread(&c, addr, sizeof(c));
179*5743Slinton 		printf("%5d", c);
180*5743Slinton 		break;
181*5743Slinton 
182*5743Slinton 	    case 2:
1835485Slinton 		iread(&arg, addr, sizeof(arg));
184*5743Slinton 		printf("%5d", arg);
185*5743Slinton 		break;
1865485Slinton 
187*5743Slinton 	    case 4:
188*5743Slinton 		iread(&longarg, addr, sizeof(longarg));
189*5743Slinton 		printf("%5d", longarg);
190*5743Slinton 		break;
1915485Slinton 	}
192*5743Slinton 	addr += size;
193*5743Slinton 	if (i < n - 1) {
194*5743Slinton 	    printf(", ");
1955485Slinton 	}
196*5743Slinton     }
197*5743Slinton     if ((addr&01) == 01) {
198*5743Slinton 	addr++;
199*5743Slinton     }
200*5743Slinton     return(addr);
2015485Slinton }
202