|
|
1.1 root 1: /*
2: * The routines in this file are
3: * the machine dependent parts of the intermediate
4: * file printer. They handle reading and printing
5: * encoded machine instructions and operands.
6: * Included are tables of opcodes, of register names,
7: * etc.
8: */
9: #ifdef vax
10: #include "INC$LIB:cc3.h"
11: #else
12: #include "cc3.h"
13: #endif
14:
15: /*
16: * Instruction names, sizes, and flags.
17: * This table is ordered according to h/i8086/opcode.h
18: * and thus parallel to n2/i8086/opcode.c; modifications
19: * to any of these require modifications to all of them.
20: */
21: static struct ins {
22: char *i_name;
23: char i_size;
24: char i_flag;
25: } ins[] = {
26: "aaa", 0, 0,
27: "aad", 0, 0,
28: "aam", 0, 0,
29: "aas", 0, 0,
30: "adc", 2, 0,
31: "adcb", 2, OP_BYTE,
32: "add", 2, 0,
33: "addb", 2, OP_BYTE,
34: "and", 2, 0,
35: "andb", 2, OP_BYTE,
36: "call", 1, OP_NPTR,
37: "cbw", 0, 0,
38: "clc", 0, 0,
39: "cld", 0, 0,
40: "cli", 0, 0,
41: "cmc", 0, 0,
42: "cmp", 2, 0,
43: "cmpb", 2, OP_BYTE,
44: "cmpsw", 0, 0,
45: "cmpsb", 0, 0,
46: "cwd", 0, 0,
47: "daa", 0, 0,
48: "das", 0, 0,
49: "dec", 1, 0,
50: "decb", 1, OP_BYTE,
51: "div", 1, 0,
52: "divb", 1, OP_BYTE,
53: "hlt", 0, 0,
54: #if AS_FORMAT
55: "icall", 1, 0,
56: #else
57: "call", 1, 0,
58: #endif
59: "idiv", 1, 0,
60: "idivb", 1, OP_BYTE,
61: #if AS_FORMAT
62: "ijmp", 1, 0,
63: #else
64: "jmp", 1, 0,
65: #endif
66: "imul", 1, 0,
67: "imulb", 1, OP_BYTE,
68: "in", 1, 0,
69: "inb", 1, OP_BYTE,
70: "inc", 1, 0,
71: "incb", 1, OP_BYTE,
72: "int", 1, OP_NPTR,
73: "into", 0, 0,
74: "iret", 0, 0,
75: #if AS_FORMAT
76: "xicall", 1, OP_DWORD,
77: "xijmp", 1, OP_NPTR,
78: #else
79: "call", 1, OP_DWORD,
80: "jmp", 1, OP_NPTR,
81: #endif
82: "ja", 1, OP_JUMP,
83: "jae", 1, OP_JUMP,
84: "jb", 1, OP_JUMP,
85: "jbe", 1, OP_JUMP,
86: "jcxz", 1, OP_JUMP,
87: "je", 1, OP_JUMP,
88: "jg", 1, OP_JUMP,
89: "jge", 1, OP_JUMP,
90: "jl", 1, OP_JUMP,
91: "jle", 1, OP_JUMP,
92: "jmp", 1, OP_JUMP,
93: "jne", 1, OP_JUMP,
94: "jno", 1, OP_JUMP,
95: "jns", 1, OP_JUMP,
96: "jo", 1, OP_JUMP,
97: "jpe", 1, OP_JUMP,
98: "jpo", 1, OP_JUMP,
99: "js", 1, OP_JUMP,
100: "lahf", 0, 0,
101: "lds", 2, OP_DWORD,
102: "lea", 2, 0,
103: "les", 2, OP_DWORD,
104: "lock", 0, 0,
105: "lodsw", 0, 0,
106: "lodsb", 0, 0,
107: "loop", 1, OP_JUMP,
108: "loope", 1, OP_JUMP,
109: "loopne", 1, OP_JUMP,
110: "mov", 2, 0,
111: "movb", 2, OP_BYTE,
112: "movsw", 0, 0,
113: "movsb", 0, 0,
114: "mul", 1, 0,
115: "mulb", 1, OP_BYTE,
116: "neg", 1, 0,
117: "negb", 1, OP_BYTE,
118: "not", 1, 0,
119: "notb", 1, OP_BYTE,
120: "ret", 1, OP_NPTR,
121: "ret", 1, OP_NPTR,
122: "or", 2, 0,
123: "orb", 2, OP_BYTE,
124: "out", 1, 0,
125: "outb", 1, OP_BYTE,
126: "pop", 1, 0,
127: "popf", 0, 0,
128: "push", 1, 0,
129: "pushf", 0, 0,
130: "rcl", 2, 0,
131: "rclb", 2, OP_BYTE,
132: "rcr", 2, 0,
133: "rcrb", 2, OP_BYTE,
134: "repe", 0, 0,
135: "repne", 0, 0,
136: "ret", 0, 0,
137: "rol", 2, 0,
138: "rolb", 2, OP_BYTE,
139: "ror", 2, 0,
140: "rorb", 2, OP_BYTE,
141: "sahf", 0, 0,
142: "sal", 2, 0,
143: "salb", 2, OP_BYTE,
144: "sar", 2, 0,
145: "sarb", 2, OP_BYTE,
146: "sbb", 2, 0,
147: "sbbb", 2, OP_BYTE,
148: "scasw", 0, 0,
149: "scasb", 0, 0,
150: "shl", 2, 0,
151: "shlb", 2, OP_BYTE,
152: "shr", 2, 0,
153: "shrb", 2, OP_BYTE,
154: "stc", 0, 0,
155: "std", 0, 0,
156: "sti", 0, 0,
157: "stosw", 0, 0,
158: "stosb", 0, 0,
159: "sub", 2, 0,
160: "subb", 2, OP_BYTE,
161: "test", 2, 0,
162: "testb", 2, OP_BYTE,
163: "wait", 0, 0,
164: #if AS_FORMAT
165: "xcall", 1, OP_NPTR,
166: #else
167: "call", 1, OP_NPTR,
168: #endif
169: "xchg", 2, 0,
170: "xchgb", 2, OP_BYTE,
171: #if AS_FORMAT
172: "xjmp", 1, OP_NPTR,
173: #else
174: "jmp", 1, OP_NPTR,
175: #endif
176: "xlat", 0, 0,
177: "xor", 2, 0,
178: "xorb", 2, OP_BYTE,
179: #if AS_FORMAT
180: "xret", 0, 0,
181: #else
182: "ret", 0, 0,
183: #endif
184:
185: #if AS_FORMAT
186: ".byte", 1, OP_DD|OP_NPTR,
187: ".word", 1, OP_DD|OP_NPTR,
188: ".word", 1, OP_DD|OP_NPTR,
189: ".long", 1, OP_DD|OP_NPTR,
190: #else
191: "db", 1, OP_DD|OP_NPTR,
192: "dw", 1, OP_DD|OP_NPTR,
193: "dw", 1, OP_DD|OP_NPTR,
194: "dd", 1, OP_DD|OP_NPTR,
195: #endif
196:
197: "fadd", 0, 0,
198: "faddf", 1, 0,
199: "faddd", 1, 0,
200: "faddi", 1, 0,
201: "faddl", 1, 0,
202: "fsub", 0, 0,
203: "fsubf", 1, 0,
204: "fsubd", 1, 0,
205: "fsubi", 1, 0,
206: "fsubl", 1, 0,
207: "frsub", 0, 0,
208: "frsubf", 1, 0,
209: "frsubd", 1, 0,
210: "frsubi", 1, 0,
211: "frsubl", 1, 0,
212: "fcompp", 0, 0,
213: "fcompf", 1, 0,
214: "fcompd", 1, 0,
215: "fcompi", 1, 0,
216: "fcompl", 1, 0,
217: "fmul", 0, 0,
218: "fmulf", 1, 0,
219: "fmuld", 1, 0,
220: "fmuli", 1, 0,
221: "fmull", 1, 0,
222: "fdiv", 0, 0,
223: "fdivf", 1, 0,
224: "fdivd", 1, 0,
225: "fdivi", 1, 0,
226: "fdivl", 1, 0,
227: "frdiv", 0, 0,
228: "frdivf", 1, 0,
229: "frdivd", 1, 0,
230: "frdivi", 1, 0,
231: "frdivl", 1, 0,
232: "fchs", 0, 0,
233: "ftst", 0, 0,
234: "fldz", 0, 0,
235: "fld1", 0, 0,
236: "fstsw", 1, 0,
237: "fldf", 1, 0,
238: "fldd", 1, 0,
239: "fldi", 1, 0,
240: "fldl", 1, 0,
241: "fldt", 1, 0,
242: "fstf", 1, 0,
243: "fstd", 1, 0,
244: "fsti", 1, 0,
245: "fstl", 1, 0,
246: "fstpf", 1, 0,
247: "fstpd", 1, 0,
248: "fstpi", 1, 0,
249: "fstpl", 1, 0,
250: "fstpt", 1, 0,
251: "fwait", 0, 0,
252: "fdrop", 0, 0,
253: "fsqrt", 0, 0,
254: "fabs", 0, 0,
255: "fprem", 0, 0,
256: "frnd", 0, 0,
257: "ldes", 0, 0,
258: "imul", 3, 0,
259: "enter", 2, 0,
260: "leave", 0, 0
261: };
262:
263: /*
264: * Handle code nodes.
265: */
266: icode()
267: {
268: register int op, i, n;
269: register struct ins *ip;
270:
271: bput('\t');
272: op = bget();
273: ip = &ins[op];
274: fprintf(ofp, "%s", ip->i_name);
275: n = ip->i_size;
276: for (i=0; i < n; i += 1) {
277: if (i == 0)
278: bput('\t');
279: else
280: fprintf(ofp, ", ");
281: iafield(ip);
282: }
283: bput('\n');
284: }
285:
286: /*
287: * These tables are indexed by the
288: * regm field of a mode. They contain the ascii
289: * strings used to print things in VASM mode.
290: */
291: static char *wregs[] = {
292: "ax", "cx", "dx", "bx", "sp", "bp", "si", "di"
293: };
294:
295: static char *bregs[] = {
296: "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
297: };
298:
299: static char *sregs[] = {
300: "es", "cs", "ss", "ds"
301: };
302:
303: static char *xregs[] = {
304: "bx, si", "bx, di", "bp, si", "bp, di",
305: "si", "di", "bp", "bx"
306: };
307:
308: /*
309: * Read and print an address field. The style
310: * of the address is determined by flag bits that
311: * hide in the address mode. These bits are cleared away
312: * when the mode is actually stored in the afield.
313: */
314: iafield(ip)
315: register struct ins *ip;
316: {
317: register int imode;
318: register int mode;
319: register int regm;
320: register int offs;
321: register int prefix;
322:
323: imode = iget();
324: if ((imode&A_OFFS) != 0)
325: offs = iget();
326: else
327: offs = 0;
328: if ((imode&A_LID) != 0)
329: sprintf(id, "L%d", iget());
330: else if ((imode&A_GID) != 0)
331: sget(id, NCSYMB);
332: mode = imode&A_AMOD;
333: regm = imode&A_REGM;
334: switch (mode) {
335:
336: case A_IMM:
337: #if AS_FORMAT
338: bput('$');
339: #else
340: if ((imode&(A_LID|A_GID)) != 0)
341: fprintf(ofp, "offset ");
342: #endif
343: case A_DIR:
344: case A_X:
345: if (mode!=A_IMM && (ip->i_flag&OP_NPTR)==0) {
346: if ((imode&A_PREFX) != 0) {
347: prefix = ((imode&A_PREFX)>>8)-1;
348: fprintf(ofp, "%s:", sregs[prefix]);
349: }
350: #if !AS_FORMAT
351: if ((ip->i_flag&OP_BYTE) != 0)
352: fprintf(ofp, "byte");
353: else if ((ip->i_flag&OP_DWORD) != 0)
354: fprintf(ofp, "dword");
355: else
356: fprintf(ofp, "word");
357: fprintf(ofp, " ptr ");
358: #endif
359: }
360: #if !AS_FORMAT
361: if (mode == A_X)
362: fprintf(ofp, "[%s", xregs[regm]);
363: #endif
364: if ((imode&(A_LID|A_GID)) != 0) {
365: #if !AS_FORMAT
366: if (mode == A_X)
367: bput('+');
368: #endif
369: fprintf(ofp, "%s", id);
370: if ((SIGNEDADDRESS)offs > 0)
371: bput('+');
372: }
373: #if !AS_FORMAT
374: else if (mode==A_X && (SIGNEDADDRESS)offs>0)
375: bput('+');
376: #endif
377: if (offs!=0 || ((imode&(A_LID|A_GID))==0 && mode!=A_X)) {
378: #if !AS_FORMAT
379: if ((SIGNEDADDRESS)offs<0) {
380: bput('-');
381: offs = -(SIGNEDADDRESS)offs;
382: }
383: fprintf(ofp, "0%xh", offs);
384: #else
385: fprintf(ofp, "%d", offs);
386: #endif
387: }
388: if (mode == A_X)
389: #if AS_FORMAT
390: fprintf(ofp, "(%s)", xregs[regm]);
391: #else
392: bput(']');
393: #endif
394: break;
395:
396: case A_WR:
397: fprintf(ofp, wregs[regm]);
398: break;
399:
400: case A_BR:
401: fprintf(ofp, bregs[regm]);
402: break;
403:
404: case A_SR:
405: fprintf(ofp, sregs[regm]);
406: break;
407:
408: default:
409: cbotch("ifield, mode=%d", mode);
410: }
411: }
412:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.