1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)printinst.c 1.2 02/10/82";
4 
5 /*
6  * decode and print the instructions
7  */
8 
9 #include "defs.h"
10 #include "machine.h"
11 #include "process.h"
12 #include "pxops.h"
13 #include "optab.h"
14 #include "object.h"
15 
16 LOCAL ADDRESS printop(), docase();
17 
18 /*
19  * print instructions within the given address range
20  */
21 
22 printinst(lowaddr, highaddr)
23 ADDRESS lowaddr;
24 ADDRESS highaddr;
25 {
26     register ADDRESS addr;
27 
28     for (addr = lowaddr; addr <= highaddr; ) {
29 	addr = printop(addr);
30     }
31 }
32 
33 /*
34  * print count instructions from given address
35  */
36 
37 printninst(count, addr)
38 int count;
39 ADDRESS addr;
40 {
41     int i;
42 
43     for (i = 0; i < count; i++) {
44 	addr = printop(addr);
45     }
46 }
47 
48 /*
49  * print the opcode at the given address, return the address
50  * of the next instruction
51  */
52 
53 LOCAL ADDRESS printop(addr)
54 register ADDRESS addr;
55 {
56     int i;
57     PXOP op;
58     OPTAB *o;
59     char subop;
60     short arg;
61     long longarg;
62     union {
63 	short i;
64 	struct { char c1, c2; } opword;
65     } u;
66 
67     iread(&u.i, addr, sizeof(u.i));
68     op = (PXOP) u.opword.c1;
69     subop = u.opword.c2;
70     o = &optab[op];
71     printf("%5d   %s", addr, o->opname);
72     addr += sizeof(u);
73     for (i = 0; o->argtype[i] != 0; i++) {
74 	if (i == 0) {
75 	    putchar('\t');
76 	} else {
77 	    putchar(',');
78 	}
79 	switch(o->argtype[i]) {
80 	    case ADDR4:
81 	    case LWORD:
82 		iread(&longarg, addr, sizeof(longarg));
83 		printf("%d", longarg);
84 		addr += sizeof(long);
85 		break;
86 
87 	    case SUBOP:
88 		printf("%d", subop);
89 		break;
90 
91 	    case ADDR2:
92 	    case DISP:
93 	    case PSUBOP:
94 	    case VLEN:
95 	    case HWORD:
96 		if (i != 0 || subop == 0) {
97 		    iread(&arg, addr, sizeof(arg));
98 		    addr += sizeof(short);
99 		} else {
100 		    arg = subop;
101 		}
102 		printf("%d", arg);
103 		break;
104 
105 	    case STRING: {
106 		char c;
107 
108 		putchar('\'');
109 		while (subop > 0) {
110 		    iread(&c, addr, sizeof(c));
111 		    if (c == '\0') {
112 			break;
113 		    }
114 		    putchar(c);
115 		    subop--;
116 		    addr++;
117 		}
118 		addr++;
119 		putchar('\'');
120 		if ((addr&1) != 0) {
121 		    addr++;
122 		}
123 		break;
124 	    }
125 
126 	    default:
127 		panic("bad argtype %d", o->argtype[i]);
128 		/*NOTREACHED*/
129 	}
130     }
131     switch(op) {
132 	case O_CON:
133 	    addr += arg;
134 	    break;
135 
136 	case O_CASE1OP:
137 	    addr = docase(addr, 1, subop);
138 	    break;
139 
140 	case O_CASE2OP:
141 	    addr = docase(addr, 2, subop);
142 	    break;
143 
144 	case O_CASE4OP:
145 	    addr = docase(addr, 4, subop);
146 	    break;
147     }
148     putchar('\n');
149     return(addr);
150 }
151 
152 /*
153  * print out the destinations and cases
154  */
155 
156 LOCAL ADDRESS docase(addr, size, n)
157 ADDRESS addr;
158 int size;
159 int n;
160 {
161     register int i;
162     char c;
163     short arg;
164     long longarg;
165 
166     iread(&arg, addr, sizeof(arg));
167     printf("\n\t%5d", arg);
168     addr += 2;
169     for (i = 1; i < n; i++) {
170 	iread(&arg, addr, sizeof(arg));
171 	printf(", %5d", arg);
172 	addr += 2;
173     }
174     printf("\n\t");
175     for (i = 0; i < n; i++) {
176 	switch(size) {
177 	    case 1:
178 		iread(&c, addr, sizeof(c));
179 		printf("%5d", c);
180 		break;
181 
182 	    case 2:
183 		iread(&arg, addr, sizeof(arg));
184 		printf("%5d", arg);
185 		break;
186 
187 	    case 4:
188 		iread(&longarg, addr, sizeof(longarg));
189 		printf("%5d", longarg);
190 		break;
191 	}
192 	addr += size;
193 	if (i < n - 1) {
194 	    printf(", ");
195 	}
196     }
197     if ((addr&01) == 01) {
198 	addr++;
199     }
200     return(addr);
201 }
202