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