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