|
|
1.1 root 1: /* $Header: /src386/bin/db/RCS/i8086d.c,v 1.4 93/03/11 07:45:48 bin Exp Locker: bin $
2: *
3: * The information contained herein is a trade secret of Mark Williams
4: * Company, and is confidential information. It is provided under a
5: * license agreement, and may be copied or disclosed only under the
6: * terms of that agreement. Any reproduction or disclosure of this
7: * material without the express written authorization of Mark Williams
8: * Company or persuant to the license agreement is unlawful.
9: *
10: * COHERENT Version 2.3.35
11: * Copyright (c) 1982, 1983, 1984.
12: * An unpublished work by Mark Williams Company, Chicago.
13: * All rights reserved.
14: */
15:
16: #include <stdio.h>
17: #include <sys/param.h>
18: #include <l.out.h>
19: #include "trace.h"
20: #include "i8086.h"
21:
22:
23: /*
24: * Legend to characters following "%" tokens in strings - Taken from intel
25: * 386 "Programmer's Reference Manual".
26: */
27:
28: /* First char after '%'; see also 2nd char, general case below:
29: A - direct address
30: C - reg of r/m selects control register
31: D - reg of r/m selects debug register
32: E - modR/M selects operand
33: F - flags register
34: G - reg field of modR/M selects general register
35: I - immediate data
36: J - relative offset added to IP
37: K - as J, except find symbol, if possible
38: M - modR/M selects memory only
39: O - no modR/M byte; offset only
40: R - mod field of modR/M selects register only
41: S - reg field of modR/M selects segment register
42: T - reg feild of modR/M selects test register
43: X - memory addressed by DS:ESI
44: Y - memory addressed by ES:EDI
45: Z - assembler instruction mneumonic size qualifier
46: 2 - prefix of two-byte opcode
47:
48: For the following first characters after the %, the second after the %
49: has a special meaning associated with it:
50: e - put in 'e' if address size attribute = 32
51: - second char is part of reg name
52: f - floating point
53: - second char is esc value
54: g - REG/OPCODE field of the modR/M byte is interpreted as
55: additional opcode; it is used as an index to a
56: column in the 2-d group array (grp[][])
57: - second character yields the group number, i.e., it
58: is used as an index to a row in grp[][]
59: r - read next n bytes, but don't do anything with them; n is
60: given by 2nd char and meaning conforms with general case
61: s - size override:
62: - second char has following meanings:
63: "a" - address size override
64: "o" - operand size override
65:
66: Second char after '%', the general case:
67: a - two words or dwords in memory (BOUND)
68: b - byte
69: d - dword
70: f - 32 bit pointer
71: l - 48 bit pointer
72: p - 32 or 48 bit pointer
73: s - six byte pseudo-descriptor
74: v - word or dword
75: w - word
76: z - r/m16: append 'w' to assem. nmeumonic
77: - r/m32: append 'w' to assem. nmeumonic if operand size = 16,
78: append 'l' to assem. nmeumonic if operand size = 32
79: !!!!!!!!!!!
80: F - use floating regs in mod/rm
81: 1-8 - group number
82: */
83:
84: char *opStrMap1[] = {
85: /* 0 */
86: "add%Zb %Eb,%Gb", "add%Zv %Ev,%Gv", "add%Zb %Gb,%Eb", "add%Zv %Gv,%Ev",
87: "add%Zb al,%Ib", "add%Zv %eax,%Iv", "pushw es", "popw es",
88: "or%Zb %Eb,%Gb", "or%Zv %Ev,%Gv", "or%Zb %Gb,%Eb", "or%Zv %Gv,%Ev",
89: "or%Zb al,%Ib", "or%Zv %eax,%Iv", "pushw cs", "%2 ",
90:
91: /* 1 */
92: "adc%Zb %Eb,%Gb", "adc%Zv %Ev,%Gv", "adc%Zb %Gb,%Eb", "adc%Zv %Gv,%Ev",
93: "adc%Zb al,%Ib", "adc%Zv %eax,%Iv", "pushw ss", "popw ss",
94: "sbb%Zb %Eb,%Gb", "sbb%Zv %Ev,%Gv", "sbb%Zb %Gb,%Eb", "sbb%Zv %Gv,%Ev",
95: "sbb%Zb al,%Ib", "sbb%Zv %eax,%Iv", "pushw ds", "popw ds",
96:
97: /* 2 */
98: "and%Zb %Eb,%Gb", "and%Zv %Ev,%Gv", "and%Zb %Gb,%Eb", "and%Zv %Gv,%Ev",
99: "and%Zb al,%Ib", "and%Zv %eax,%Iv", "es:", "daa",
100: "sub%Zb %Eb,%Gb", "sub%Zv %Ev,%Gv", "sub%Zb %Gb,%Eb", "sub%Zv %Gv,%Ev",
101: "sub%Zb al,%Ib", "sub%Zv %eax,%Iv", "cs:", "das",
102:
103: /* 3 */
104: "xor%Zb %Eb,%Gb", "xor%Zv %Ev,%Gv", "xor%Zb %Gb,%Eb", "xor%Zv %Gv,%Ev",
105: "xor%Zb al,%Ib", "xor%Zv %eax,%Iv", "ss:", "aaa",
106: "cmp%Zb %Eb,%Gb", "cmp%Zv %Ev,%Gv", "cmp%Zb %Gb,%Eb", "cmp%Zv %Gv,%Ev",
107: "cmp%Zb al,%Ib", "cmp%Zv %eax,%Iv", "ds:", "aas",
108:
109: /* 4 */
110: "inc%Zv %eax", "inc%Zv %ecx", "inc%Zv %edx", "inc%Zv %ebx",
111: "inc%Zv %esp", "inc%Zv %ebp", "inc%Zv %esi", "inc%Zv %edi",
112: "dec%Zv %eax", "dec%Zv %ecx", "dec%Zv %edx", "dec%Zv %ebx",
113: "dec%Zv %esp", "dec%Zv %ebp", "dec%Zv %esi", "dec%Zv %edi",
114:
115: /* 5 */
116: "push%Zv %eax", "push%Zv %ecx", "push%Zv %edx", "push%Zv %ebx",
117: "push%Zv %esp", "push%Zv %ebp", "push%Zv %esi", "push%Zv %edi",
118: "pop%Zv %eax", "pop%Zv %ecx", "pop%Zv %edx", "pop%Zv %ebx",
119: "pop%Zv %esp", "pop%Zv %ebp", "pop%Zv %esi", "pop%Zv %edi",
120:
121: /* 6 */
122: "pusha%Zv", "popa%Zv", "bound%Zv %Gv,%Ma", "arpl %Ew,%Gw",
123: "fs:", "gs:", "%so", "%sa",
124: "push%Zv %Iv", "imul%Zv %Gv=%Ev*%Iv", "push%Zb %Ib", "imul%Zv %Gv=%Ev*%Ib",
125: "ins%Zb %Yb", "ins%Zv %Yv", "outs%Zb %Xb", "outs%Zv %Xv",
126:
127: /* 7 */
128: "jo %Jb", "jno %Jb", "jb %Jb", "jae %Jb",
129: "je %Jb", "jne %Jb", "jbe %Jb", "ja %Jb",
130: "js %Jb", "jns %Jb", "jp %Jb", "jnp %Jb",
131: "jl %Jb", "jge %Jb", "jle %Jb", "jg %Jb",
132:
133: /* 8 */
134: "%g1%Zb %Eb,%Ib", "%g1%Zv %Ev,%Iv", "mov%Zb al,%Ib", "%g1%Zv %Ev,%Ib",
135: "test%Zb %Eb,%Gb", "test%Zv %Ev,%Gv", "xchg%Zb %Eb,%Gb", "xchg%Zv %Ev,%Gv",
136: "mov%Zb %Eb,%Gb", "mov%Zv %Ev,%Gv", "mov%Zb %Gb,%Eb", "mov%Zv %Gv,%Ev",
137: "mov%Zw %Ew,%Sw", "lea%Zv %Gv,%M ", "mov%Zw %Sw,%Ew", "pop%Zv %Ev",
138:
139: /* 9 */
140: "nop", "xchg%Zv %eax,%ecx", "xchg%Zv %eax,%edx", "xchg%Zv %eax,%ebx",
141: "xchg%Zv %eax,%esp", "xchg%Zv %eax,%ebp",
142: "xchg%Zv %eax,%esi", "xchg%Zv %eax,%edi",
143: "cbw", "cwd", "lcall %Ap", "fwait",
144: "pushf%Zv", "popf%Zv", "sahf", "lahf",
145:
146: /* A */
147: "mov%Zb al,%Ob", "mov%Zv %eax,%Ov", "mov%Zb %Ob,al", "mov%Zv %Ov,%eax",
148: "movs%Zb %Xb%Yb", "movs%Zz %Xv%Yv", "cmps%Zb %Xb%Yb", "cmps%Zz %Xv%Yv",
149: "test%Zb al,%Ib", "test%Zv %eax,%Iv", "stos%Zb %Yb", "stos%Zz %Yv",
150: "lods%Zb %Xb", "lods%Zz %Xv", "scas%Zb %Xb", "scas%Zv %Xv",
151:
152: /* B */
153: "mov%Zb al,%Ib", "mov%Zb cl,%Ib", "mov%Zb dl,%Ib", "mov%Zb bl,%Ib",
154: "mov%Zb ah,%Ib", "mov%Zb ch,%Ib", "mov%Zb dh,%Ib", "mov%Zb bh,%Ib",
155: "mov%Zv %eax,%Iv", "mov%Zv %ecx,%Iv", "mov%Zv %edx,%Iv", "mov%Zv %ebx,%Iv",
156: "mov%Zv %esp,%Iv", "mov%Zv %ebp,%Iv", "mov%Zv %esi,%Iv", "mov%Zv %edi,%Iv",
157:
158: /* C */
159: "%g2%Zb %Eb,%Ib", "%g2%Zv %Ev,%Ib", "ret %Iw", "ret",
160: "les%Zv %Gv,%Mp", "lds%Zv %Gv,%Mp", "mov%Zb %Eb,%Ib", "mov%Zv %Ev,%Iv",
161: "enter %Iw,%Ib", "leave", "lret %Iw", "lret",
162: "int 3", "int %Ib", "into", "iret",
163:
164: /* D */
165: "%g2%Zb %Eb,$1", "%g2%Zv %Ev,$1", "%g2%Zb %Eb,cl", "%g2%Zv %Ev,cl",
166: "aam %rb", "aad %rb", NULL, "xlat",
167: #if 0
168: "esc 0,%Ib", "esc 1,%Ib", "esc 2,%Ib", "esc 3,%Ib",
169: "esc 4,%Ib", "esc 5,%Ib", "esc 6,%Ib", "esc 7,%Ib",
170: #else
171: "%f0", "%f1", "%f2", "%f3",
172: "%f4", "%f5", "%f6", "%f7",
173: #endif
174:
175: /* E */
176: "loopne %Jb", "loope %Jb", "loop %Jb", "jcxz %Jb",
177: "in%Zb %Ib", "in%Zv %Ib", "out%Zb %Ib,al", "out%Zv %Ib,%eax",
178: "call %Kv", "jmp %Jv", "ljmp %Ap", "jmp %Jb",
179: "in%Zb ", "in%Zv ", "out%Zb dx,al", "out%Zv dx,%eax",
180:
181: /* F */
182: "lock", NULL, "repne", "rep",
183: "hlt", "cmc", "%g3", "%g0",
184: "clc", "stc", "cli", "sti",
185: "cld", "std", "%g4", "%g5"
186: };
187:
188: /******************************************************************************/
189: char *opStrMap2[] = {
190: /* 0 */
191: "%g6", "%g7", "lar%Zv %Gv,%Ew", "lsl%Zv %Gv,%Ew",
192: NULL, NULL, "clts", NULL,
193: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
194:
195: /* 1 */
196: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
197: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
198:
199: /* 2 */
200: "mov%Zd %Rd,%Cd", "mov%Zd %Rd,%Dd", "mov%Zd %Cd,%Rd", "mov%Zd %Dd,%Rd",
201: "mov%Zd %Rd,%Td", NULL, "mov%Zd %Td,%Rd", NULL,
202: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
203:
204: /* 3 */
205: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
206: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
207:
208: /* 4 */
209: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
210: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
211:
212: /* 5 */
213: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
214: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
215:
216: /* 6 */
217: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
218: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
219:
220: /* 7 */
221: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
222: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
223:
224: /* 8 */
225: "jo %Jv", "jno %Jv", "jb %Jv", "jae %Jv",
226: "je %Jv", "jne %Jv", "jbe %Jv", "ja %Jv",
227: "js %Jv", "jns %Jv", "jp %Jv", "jnp %Jv",
228: "jl %Jv", "jge %Jv", "jle %Jv", "jg %Jv",
229:
230: /* 9 */
231: "seto %Eb", "setno %Eb", "setb %Eb", "setae %Eb",
232: "sete %Eb", "setne %Eb", "setbe %Eb", "seta %Eb",
233: "sets %Eb", "setns %Eb", "setp %Eb", "setnp %Eb",
234: "setl %Eb", "setge %Eb", "setle %Eb", "setg %Eb",
235:
236: /* A */
237: "pushw fs", "popw fs", NULL, "bt%Zv %Ev,%Gv",
238: "shld%Zv %Ev,%Gv,%Ib", "shld%Zv %Ev,%Gv,cl", NULL, NULL,
239: "pushw gs", "popw gs", NULL, "bts%Zv %Ev,%Gv",
240: "shrd%Zv %Ev,%Gv,%Ib", "shrd%Zv %Ev,%Gv,cl", NULL, "imul%Zv %Gv,%Ev",
241:
242: /* B */
243: NULL, NULL, "lss%Zv %Mp", "btr%Zv %Ev,%Gv",
244: "lfs%Zv %Mp", "lgs%Zv %Mp", "movzx%Zb %Gv,%Eb", "movzx%Zw %Gv,%Ew",
245: NULL, NULL, "%g8%Zv %Ev,%Ib", "btc%Zv %Ev,%Gv",
246: "bsf%Zv %Gv,%Ev", "bsr%Zv %Gv,%Ev", "movsx%Zb %Gv,%Eb", "movsx%Zw %Gv,%Ew",
247:
248: /* C */
249: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
250: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
251:
252: /* D */
253: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
254: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
255:
256: /* E */
257: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
258: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
259:
260: /* F */
261: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
262: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
263: };
264:
265:
266: /******************************************************************************/
267: /*
268: * Intel groups 1 to 8: grpStrMap0[] is the %Ev case for grpStrMap3[]
269: */
270:
271: char *grpStrMap0[] =
272: { "test%Zv %Ev,%Iv", "test%Zv %Ev,%Iv,", "not%Zv %Ev", "neg%Zv %Ev",
273: "mul%Zv %eax,%Ev", "imul%Zv %eax,%Ev", "div%Zv %eax,%Ev", "idiv%Zv %eax,%Ev" };
274:
275: /* grp[1][] */
276: char *grpStrMap1[] =
277: { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" };
278:
279: /* grp[2][] */
280: char *grpStrMap2[] =
281: { "rol", "ror", "rcl", "rcr", "shl", "shr", "shl", "sar" };
282:
283: /* grp[3][] */
284: char *grpStrMap3[] =
285: { "test%Zb %Eb,%Ib", "test%Zb %Eb,%Ib,", "not%Zb %Eb", "neg%Zb %Eb",
286: "mul%Zb al,%Eb", "imul%Zb al,%Eb", "div%Zb al,%Eb", "idiv%Zb al,%Eb" };
287:
288: /* grp[4][] */
289: char *grpStrMap4[] =
290: { "inc%Zb %Eb", "dec%Zb %Eb", NULL, NULL, NULL, NULL, NULL, NULL };
291:
292: /* grp[5][] */
293: char *grpStrMap5[] =
294: { "inc%Zv %Ev", "dec%Zv %Ev", "icall %Ev", "ilcall %Ep",
295: "ijmp %Ev", "iljmp %Ep", "push%Zv %Ev", NULL };
296:
297: /* grp[6][] */
298: char *grpStrMap6[] =
299: { "sldt %Ew", "str %Ew", "lldt %Ew", "ltr %Ew",
300: "verr %Ew", "verw %Ew", NULL, NULL };
301:
302: /* grp[7][] */
303: char *grpStrMap7[] =
304: { "sgdt %Ms", "sidt %Ms", "lgdt%Zv %Ms", "lidt%Zv %Ms",
305: "smsw %Ew", NULL, "lmsw %Ew", NULL };
306:
307: /* grp[8][] */
308: char *grpStrMap8[] =
309: { NULL, NULL, NULL, NULL, "bt", "bts", "btr", "btc" };
310:
311: char **grpStrMap[] = { grpStrMap0, grpStrMap1, grpStrMap2, grpStrMap3,
312: grpStrMap4, grpStrMap5, grpStrMap6, grpStrMap7,
313: grpStrMap8 };
314:
315:
316: /******************************************************************************/
317: /*
318: * Define arrays of the various 80386 registers
319: */
320:
321: /* segment registers */
322: char *segReg[NSEGREGS] = {"es", "cs", "ss", "ds", "fs", "gs"};
323:
324: /* general registers */
325: char *genReg8[] = {"%al", "%cl", "%dl", "%bl"
326: , "%ah", "%ch", "%dh", "%bh"};
327: char *genReg16[] = {"%ax", "%cx", "%dx", "%bx"
328: , "%sp", "%bp", "%si", "%di"};
329: char *genReg32[] = {"%eax", "%ecx", "%edx", "%ebx"
330: , "%esp", "%ebp", "%esi", "%edi"};
331: char **genReg[] = {genReg8, genReg16, genReg32};
332:
333: /* control registers */
334: char *ctrlReg[NCTRLREGS] = {
335: "%cr0", "%cr1", "%cr2", "%cr3"
336: };
337:
338: /* debug registers */
339: char *dbgReg[NDBGREGS] = {
340: "%dr0", "%dr1", "%dr2", "%dr3", "%dr4", "%dr5", "%dr6", "%dr7"
341: };
342:
343: /* test registers */
344: char *tstReg[NTSTREGS] = {
345: NULL, NULL, NULL, NULL, NULL, NULL, "%tr6", "%tr7"
346: };
347:
348:
349: /******************************************************************************/
350: /*
351: * Indirect mode tables (including indexing for the 16 bit addressing form)
352: */
353:
354: /* 16 bit indirect addressing forms with the ModR/M byte */
355: char *modRMtab16[] = {
356: "(%bx)(%si)", "(%bx)(%di)", "(%bp)(%si)", "(%bp)(%di)",
357: "(%si)", "(%di)", "(%bp)", "(%bx)"
358: };
359:
360: /* 32 bit indirect addressing forms with the ModR/M byte
361: or indirect base addressing with the SIB byte */
362: char *modRMtab32[] = {
363: "(%eax)", "(%ecx)", "(%edx)", "(%ebx)",
364: "(%esp)", "(%ebp)", "(%esi)", "(%edi)"
365: };
366:
367: char **modRMtab[] = { modRMtab16, modRMtab32 };
368:
369: /******************************************************************************/
370: /*
371: * 32 bit indirect indexed addressing forms with the SIB byte
372: */
373:
374: /* index multiplied by 1 */
375: char *sibtab0[] = {
376: "(%eax)", "(%ecx)", "(%edx)", "(%ebx)",
377: NULL , "(%ebp)", "(%esi)", "(%edi)"
378: };
379:
380: /* index multiplied by 2 */
381: char *sibtab1[] = {
382: "(%eax*2)", "(%ecx*2)", "(%edx*2)", "(%ebx*2)",
383: NULL , "(%ebp*2)", "(%esi*2)", "(%edi*2)"
384: };
385:
386: /* index multiplied by 4 */
387: char *sibtab2[] = {
388: "(%eax*4)", "(%ecx*4)", "(%edx*4)", "(%ebx*4)",
389: NULL , "(%ebp*4)", "(%esi*4)", "(%edi*4)"
390: };
391:
392: /* index multiplied by 8 */
393: char *sibtab3[] = {
394: "(%eax*8)", "(%ecx*8)", "(%edx*8)", "(%ebx*8)",
395: NULL , "(%ebp*8)", "(%esi*8)", "(%edi*8)"
396: };
397:
398: char **sibtab[] = { sibtab0, sibtab1, sibtab2, sibtab3 };
399:
400: /*
401: * 8087 Instruction table.
402: * The bits considered are the last 3 bits of the ESC
403: * instruction and the next instruction byte.
404: */
405: INS fpinstab[] = {
406: 0x000, 0x138, "fadd?",
407: 0x0C0, 0x1F8, "fadd\tST(i)?",
408: 0x020, 0x130, "fsubb?",
409: 0x0E0, 0x1F0, "fsub\tST(i)?",
410: 0x008, 0x138, "fmul?",
411: 0x0C8, 0x1F8, "fmul\tST(i)?",
412: 0x030, 0x130, "fdiv?",
413: 0x0F0, 0x1F0, "fdiv\tST(i)?",
414: 0x1FA, 0x7FF, "fsqrt",
415: 0x1FD, 0x7FF, "fscale",
416: 0x1F8, 0x7FF, "fprem",
417: 0x1FC, 0x7FF, "frndint",
418: 0x1F4, 0x7FF, "fxtract",
419: 0x1E1, 0x7FF, "fabs",
420: 0x1E0, 0x7FF, "fchs",
421: 0x1F2, 0x7FF, "fptan",
422: 0x1F3, 0x7FF, "fpatan",
423: 0x1F0, 0x7FF, "f2xm1",
424: 0x1F1, 0x7FF, "fyl2x",
425: 0x1F9, 0x7FF, "fyl2p1",
426: 0x1EE, 0x7FF, "fldz",
427: 0x1E8, 0x7FF, "fld1",
428: 0x1EB, 0x7FF, "fldpi",
429: 0x1E9, 0x7FF, "fldl2t",
430: 0x1EA, 0x7FF, "fldl2e",
431: 0x1EC, 0x7FF, "fldlg2",
432: 0x1ED, 0x7FF, "fldln2",
433: 0x3E3, 0x7FF, "finit",
434: 0x3E0, 0x77FF, "feni",
435: 0x3E1, 0x7FF, "fdisi",
436: 0x128, 0x738, "fldcw?",
437: 0x138, 0x738, "fstcw?",
438: 0x538, 0x738, "fstsw?",
439: 0x3E2, 0x7FF, "fclex",
440: 0x130, 0x738, "fstenv?",
441: 0x120, 0x738, "fldenv?",
442: 0x530, 0x738, "fsave?",
443: 0x520, 0x738, "frstor?",
444: 0x1F7, 0x7FF, "fincstp",
445: 0x1F6, 0x7FF, "fdecstp",
446: 0x5C0, 0x7F8, "ffree\tST(i)?",
447: 0x1D0, 0x7FF, "fnop",
448: 0x00, 0x00, NULL
449: };
450:
451: /* end of i8086d1.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.