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