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