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