|
|
1.1 root 1: /*
2: * instruction decoding
3: * VAX instructions; works only on a VAX for now
4: */
5:
6: #include "defs.h"
7: #include "space.h"
8:
9: #define LOBYTE 0377
10:
11: /* instruction printing */
12:
13: /*
14: * Argument access types
15: */
16: #define ACCA (8<<3) /* address only */
17: #define ACCR (1<<3) /* read */
18: #define ACCW (2<<3) /* write */
19: #define ACCM (3<<3) /* modify */
20: #define ACCB (4<<3) /* branch displacement */
21: #define ACCI (5<<3) /* XFC code */
22:
23: /*
24: * Argument data types
25: */
26: #define TYPB 0 /* byte */
27: #define TYPW 1 /* word */
28: #define TYPL 2 /* long */
29: #define TYPQ 3 /* quad */
30: #define TYPF 4 /* floating */
31: #define TYPD 5 /* double floating */
32:
33: typedef struct optab *OPTAB;
34: struct optab {
35: char *iname;
36: char val;
37: char nargs;
38: char argtype[6];
39: } optab[];
40: struct optab junkoptab = {"???"};
41: char *regname[];
42: char *fltimm[];
43: static ADDR incp;
44:
45: short ioptab[256]; /* index by opcode to optab */
46:
47: mkioptab() {/* set up ioptab */
48: register OPTAB p=optab;
49: register int i;
50:
51: for (i = 0; i < 256; i++)
52: ioptab[i] = -1; /* flag invalid */
53: while (p->iname){
54: ioptab[p->val&LOBYTE]=p-optab;
55: p++;
56: }
57: }
58:
59: printins(idsp)
60: {
61: register short argno; /* argument index */
62: register short mode; /* mode */
63: register char **r; /* register name */
64: register unsigned char ins;
65: long d; /* assembled byte, word, long or float */
66: long snarf();
67: register char * ap;
68: register OPTAB ip;
69:
70: ins = cget(dot, idsp);
71: chkerr();
72: if (ioptab[ins] == -1)
73: ip = &junkoptab;
74: else
75: ip = &optab[ioptab[ins]];
76: printf("%s%8t",ip->iname);
77: incp = 1;
78: ap = ip->argtype;
79: for (argno=0; argno<ip->nargs; argno++,ap++) {
80: var[argno] = 0x80000000;
81: if (argno!=0) printc(',');
82: top:
83: if (*ap&ACCB)
84: mode = 0xAF + ((*ap&7)<<5); /* branch displacement */
85: else{
86: mode = cget(inkdot((WORD)incp), idsp);
87: chkerr();
88: ++incp;
89: }
90: if (mode & 0300) {/* not short literal */
91: r = ®name[mode&0xF];
92: mode >>= 4;
93: switch ((int)mode) {
94: case 4: /* [r] */
95: printf("[%s]",*r);
96: goto top;
97: case 5: /* r */
98: printf("%s",*r);
99: break;
100: case 6: /* (r) */
101: printf("(%s)",*r);
102: break;
103: case 7: /* -(r) */
104: printf("-(%s)",*r);
105: break;
106: case 9: /* *(r)+ */
107: printc('*');
108: case 8: /* (r)+ */
109: if (r==(regname+0xF)) {
110: printc('$');
111: if (mode==9){ /* PC absolute, always 4 bytes*/
112: d = snarf(4, idsp);
113: goto disp;
114: }
115: switch(*ap&7){
116: case TYPB:
117: d = snarf(1, idsp);
118: goto disp;
119: case TYPW:
120: d = snarf(2, idsp);
121: goto disp;
122: case TYPL:
123: d = snarf(4, idsp);
124: goto disp;
125: case TYPQ:
126: d = snarf(4, idsp);
127: printquad(d, snarf(4, idsp));
128: break;
129: case TYPF:
130: printfloating(snarf(4, idsp), 0L);
131: break;
132: case TYPD:
133: d = snarf(4, idsp);
134: printfloating(d, snarf(4, idsp));
135: break;
136: } /*end of type switch */
137: /*
138: * here only for TYPQ, TYPf, TYPD
139: * others went to disp
140: */
141: } else { /*it's not PC immediate or abs*/
142: printf("(%s)+",*r);
143: }
144: break;
145: case 0xB: /* byte displacement defferred*/
146: printc('*');
147: case 0xA: /* byte displacement */
148: d = snarf(1, idsp);
149: goto disp;
150: case 0xD: /* word displacement deferred */
151: printc('*');
152: case 0xC: /* word displacement */
153: d = snarf(2, idsp);
154: goto disp;
155: case 0xF: /* long displacement deferred */
156: printc('*');
157: case 0xE: /* long displacement */
158: d = snarf(4, idsp);
159: goto disp;
160: disp:
161: var[argno]=d;
162: if (r==(regname+0xF) && mode>=0xA){
163: /* PC offset addressing */
164: var[argno] += dot+incp;
165: }
166: psymoff(var[argno],ANYSP,"");
167: if (r != regname+0xF)
168: printf("(%s)",*r);
169: break;
170: } /* end of the mode switch */
171: } else { /* short literal */
172: var[argno]=mode;
173: if((*ap&7)==TYPF || (*ap&7)==TYPD)
174: printf("$%s",fltimm[mode]);
175: else
176: printf("$%r",mode);
177: }
178: }
179: if (ins==0xCF || ins==0xAF || ins==0x8F) {/* CASEx instr */
180: for (argno=0; argno<=var[2]; ++argno) {
181: printc(EOR);
182: printf(" %R: ",argno+var[1]);
183: d=sget(inkdot((WORD)incp+argno+argno),idsp);
184: if (d&0x8000) d -= 0x10000;
185: psymoff((WORD)(inkdot((WORD)incp)+d),ANYSP,"");
186: }
187: incp += var[2]+var[2]+2;
188: }
189: dotinc=incp;
190: }
191:
192: /*
193: * magic values to mung an offset to a register into
194: * something that psymoff can understand.. all magic
195: */
196: /* 0 1 2 3 4 */
197: static long magic_masks[5] = {
198: 0, 0x80, 0x8000, 0, 0};
199: static long magic_compl[5] = {
200: 0, 0x100, 0x10000,0, 0};
201:
202: static
203: long
204: snarf(nbytes, idsp)
205: int nbytes;
206: {
207: register int byteindex;
208: union Long{
209: char long_bytes[4];
210: long long_value;
211: } d;
212:
213: d.long_value = 0;
214: for (byteindex = 0; byteindex < nbytes; byteindex++){
215: d.long_bytes[byteindex] = cget(inkdot((WORD)incp), idsp);
216: chkerr();
217: ++incp;
218: }
219: if (d.long_value & magic_masks[nbytes])
220: d.long_value -= magic_compl[nbytes];
221: return(d.long_value);
222: }
223:
224: static
225: printfloating(word_first, word_last)
226: long word_first;
227: long word_last;
228: {
229: union Double{
230: struct {
231: long word_first;
232: long word_last;
233: } composite;
234: double dvalue;
235: } reconstructed;
236:
237: reconstructed.composite.word_first = word_first;
238: reconstructed.composite.word_last = word_last;
239: fpout('F', (char *)&reconstructed.dvalue);
240: }
241:
242: static
243: printquad(word_first, word_last)
244: long word_first;
245: long word_last;
246: {
247: union Quad {
248: char quad_bytes[8];
249: long quad_long[2];
250: } reconstructed;
251: int leading_zero = 1;
252: int byteindex;
253: int nibbleindex;
254: register int ch;
255:
256: reconstructed.quad_long[0] = word_first;
257: reconstructed.quad_long[1] = word_last;
258: for (byteindex = 7; byteindex >= 0; --byteindex){
259: for (nibbleindex = 4; nibbleindex >= 0; nibbleindex -= 4){
260: ch = (reconstructed.quad_bytes[byteindex]
261: >> nibbleindex) & 0x0F;
262: if ( ! (leading_zero &= (ch == 0) ) ){
263: if (ch <= 0x09)
264: printc(ch + '0');
265: else
266: printc(ch - 0x0A + 'a');
267: }
268: }
269: }
270: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.