brucee@runx.ips.oz (Bruce Evans) (11/26/88)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 7 (of 7)." # Contents: kernel/db/unasm.c # Wrapped by sys@besplex on Sat Nov 26 06:00:33 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'kernel/db/unasm.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'kernel/db/unasm.c'\" else echo shar: Extracting \"'kernel/db/unasm.c'\" \(24851 characters\) sed "s/^X//" >'kernel/db/unasm.c' <<'END_OF_FILE' X/* unasm.c */ X X#define Ib() outget8() X#define Iw() outget16() X Xtypedef int su8_pt; Xtypedef int su16_t; X X#include "const.h" X#include "type.h" X#include "var.h" X#include "/usr/include/a.out.h" /* full pathname to get right one! */ X X#define LINDIRECT '[' X#define RINDIRECT ']' X X#define BASE_MASK 0x07 X#define INDEX_MASK 0x38 X#define INDEX_SHIFT 3 X#define MOD_MASK 0xC0 /* mod reg r/m is mmrrr/// */ X# define REG_MOD 0xC0 X# define MEM0_MOD 0x00 X# define MEM1_MOD 0x40 X# define MEM2_MOD 0x80 X#define REG_MASK 0x38 X#define REG_SHIFT 3 X#define RM_MASK 0x07 X#define SREG_MASK 0x38 X#define SREG_SHIFT 3 X#define SS_MASK 0xC0 X#define SS_SHIFT 6 X X#define SIGNBIT 0x02 /* opcode bits xxxxxxsw for immediates */ X#define WORDBIT 0x01 X#define TOREGBIT 0x02 /* opcode bit for non-immediates */ X X#define MAX_SIGNED_CHAR 0x7F /* will assume 2's complement */ X#define MAX_UNSIGNED_CHAR 0xFF X XFORWARD void i_00_to_3f(); XFORWARD void i_40_to_5f(); XFORWARD void i_60_to_6f(); XFORWARD void i_70_to_7f(); XFORWARD void i_80(); XFORWARD void i_88(); XFORWARD void i_90(); XFORWARD void i_98(); XFORWARD void i_a0();; XFORWARD void i_a8(); XFORWARD void i_b0(); XFORWARD void i_b8(); XFORWARD void i_c0(); XFORWARD void i_c8();; XFORWARD void i_d0(); XFORWARD void i_d8();; XFORWARD void i_e0(); XFORWARD void i_e8(); XFORWARD void i_f0(); XFORWARD void i_f8(); X XPRIVATE pfv_t optable[] = X{ X i_00_to_3f, X i_00_to_3f, X i_00_to_3f, X i_00_to_3f, X i_00_to_3f, X i_00_to_3f, X i_00_to_3f, X i_00_to_3f, X i_40_to_5f, X i_40_to_5f, X i_40_to_5f, X i_40_to_5f, X i_60_to_6f, X i_60_to_6f, X i_70_to_7f, X i_70_to_7f, X i_80, X i_88, X i_90, X i_98, X i_a0, X i_a8, X i_b0, X i_b8, X i_c0, X i_c8, X i_d0, X i_d8, X i_e0, X i_e8, X i_f0, X i_f8 X}; X XPRIVATE char bttab[] = "bt\t"; XPRIVATE char btctab[] = "btc\t"; XPRIVATE char btrtab[] = "btr\t"; XPRIVATE char btstab[] = "bts\t"; XPRIVATE char calltab[] = "call\t"; XPRIVATE char dectab[] = "dec\t"; XPRIVATE char empty[] = ""; X XPRIVATE char f2xm1[] = "f2xm1"; XPRIVATE char fabs[] = "fabs"; XPRIVATE char fadd[] = "fadd"; XPRIVATE char faddp[] = "faddp"; XPRIVATE char fbld[] = "fbld"; XPRIVATE char fbstp[] = "fbstp"; XPRIVATE char fchs[] = "fchs"; XPRIVATE char fclex[] = "fclex"; XPRIVATE char fcom[] = "fcom"; XPRIVATE char fcomp[] = "fcomp"; XPRIVATE char fdecstp[] = "fdecstp"; XPRIVATE char fdisi[] = "fdisi"; XPRIVATE char fdiv[] = "fdiv"; XPRIVATE char fdivp[] = "fdivp"; XPRIVATE char fdivr[] = "fdivr"; XPRIVATE char fdivrp[] = "fdivrp"; XPRIVATE char feni[] = "feni"; XPRIVATE char ffree[] = "ffree"; XPRIVATE char fiadd[] = "fiadd"; XPRIVATE char ficom[] = "ficom"; XPRIVATE char ficomp[] = "ficomp"; XPRIVATE char fidiv[] = "fidiv"; XPRIVATE char fidivr[] = "fidivr"; XPRIVATE char fild[] = "fild"; XPRIVATE char fimul[] = "fimul"; XPRIVATE char fincstp[] = "fincstp"; XPRIVATE char finit[] = "finit"; XPRIVATE char fist[] = "fist"; XPRIVATE char fistp[] = "fistp"; XPRIVATE char fisub[] = "fisub"; XPRIVATE char fisubr[] = "fisubr"; XPRIVATE char fld[] = "fld"; XPRIVATE char fld1[] = "fld1"; XPRIVATE char fldcw[] = "fldcw"; XPRIVATE char fldenv[] = "fldenv"; XPRIVATE char fldl2e[] = "fldl2e"; XPRIVATE char fldl2t[] = "fldl2t"; XPRIVATE char fldlg2[] = "fldlg2"; XPRIVATE char fldln2[] = "fldln2"; XPRIVATE char fldpi[] = "fldpi"; XPRIVATE char fldz[] = "fldz"; XPRIVATE char fmul[] = "fmul"; XPRIVATE char fmulp[] = "fmulp"; XPRIVATE char fnop[] = "fnop"; XPRIVATE char fpatan[] = "fpatan"; XPRIVATE char fprem[] = "fprem"; XPRIVATE char fptan[] = "fptan"; XPRIVATE char frndint[] = "frndint"; XPRIVATE char frstor[] = "frstor"; XPRIVATE char fsave[] = "fsave"; XPRIVATE char fscale[] = "fscale"; XPRIVATE char fsqrt[] = "fsqrt"; XPRIVATE char fst[] = "fst"; XPRIVATE char fstcw[] = "fstcw"; XPRIVATE char fstenv[] = "fstenv"; XPRIVATE char fstp[] = "fstp"; XPRIVATE char fstsw[] = "fstsw"; XPRIVATE char fsub[] = "fsub"; XPRIVATE char fsubp[] = "fsubp"; XPRIVATE char fsubr[] = "fsubr"; XPRIVATE char fsubrp[] = "fsubrp"; XPRIVATE char ftst[] = "ftst"; XPRIVATE char fxam[] = "fxam"; XPRIVATE char fxch[] = "fxch"; XPRIVATE char fxtract[] = "fxtract"; XPRIVATE char fyl2x[] = "fyl2x"; XPRIVATE char fyl2xp1[] = "fyl2xp1"; X XPRIVATE char fishy[] = "???"; XPRIVATE char fishytab[] = "???\t"; XPRIVATE char imultab[] = "imul\t"; XPRIVATE char intab[] = "in\t"; XPRIVATE char inctab[] = "inc\t"; XPRIVATE char jmptab[] = "jmp\t"; XPRIVATE char movtab[] = "mov\t"; XPRIVATE char movsxtab[] = "movsx\t"; XPRIVATE char movzxtab[] = "movzx\t"; XPRIVATE char pushtab[] = "push\t"; XPRIVATE char s_outtab[] = "out\t"; XPRIVATE char shldtab[] = "shld\t"; XPRIVATE char shrdtab[] = "shrd\t"; XPRIVATE char testtab[] = "test\t"; XPRIVATE char xchgtab[] = "xchg\t"; X XPRIVATE char *genreg[] = X{ X "al", "cl", "dl", "bl", X "ah", "ch", "dh", "bh", X "ax", "cx", "dx", "bx", X "sp", "bp", "si", "di", X "eax", "ecx", "edx", "ebx", X "esp", "ebp", "esi", "edi" X}; XPRIVATE char *segreg[] = X{ X "es", "cs", "ss", "ds", X "fs", "gs", "?s", "?s", X}; XPRIVATE char *indreg[] = X{ X "bx+si", "bx+di", "bp+si", "bp+di", X "si", "di", "bp", "bx", X}; X XPRIVATE char *str_00_to_3f[] = X{ X /* index by (opcode >> 3) & 7 */ X "add", "or", "adc", "sbb", X "and", "sub", "xor", "cmp" X}; XPRIVATE char *sstr_00_to_3f[] = X{ X /* index ((opc>>2) & 0xE) + (opc & 7) - 6 */ X "push\tes", "pop\tes", "push\tcs", "pop\tcs", X "push\tss", "pop\tss", "push\tds", "pop\tds", X "es:", "daa", "cs:", "das", X "ss:", "aaa", "ds:", "aas" X}; XPRIVATE char *sstr_0f[] = X{ X "push\tfs", "pop\tfs", fishy, bttab, X shldtab, shldtab, fishy, fishy, X "push\tgs", "pop\tgs", fishy, btstab, X shrdtab, shrdtab, fishy, imultab, X fishy, fishy, "lss\t", btrtab, X "lfs\t", "lgs\t", movzxtab, movzxtab, X fishy, fishy, empty, btctab, X "bsf\t", "bsr\t", movsxtab, movsxtab X}; XPRIVATE char *ssstr_0f[] = X{ X "sldt\t", "str\t", "lldt\t", "ltr\t", X "verr\t", "verw\t", fishy, fishy, X "sgdt\t", "sidt\t", "lgdt\t", "lidt\t", X "smsw\t", fishy, "lmsw\t", fishy, X fishy, fishy, fishy, fishy, X bttab, btstab, btrtab, btctab X}; XPRIVATE char *str_40_to_5f[] = X{ X /* index by (opcode >> 3) & 3 */ X inctab, dectab, pushtab, "pop\t" X}; XPRIVATE char *str_60_to_6f[] = X{ X "pusha", "popa", "bound\t", "arpl\t", X "fs:", "gs:", "os:", "as:", X pushtab, imultab, pushtab, imultab, X "insb", "insw", "outsb", "outsw" X}; XPRIVATE char *str_flags[] = X{ X /* opcodes 0x70 to 0x7F, and 0x0F80 to 0x0F9F */ X "o", "no", "b", "nb", X "z", "nz", "be", "a", X "s", "ns", "pe", "po", X "l", "ge", "le", "g" X}; XPRIVATE char *str_98[] = X{ X "cbw", "cwd", calltab, "wait", X "pushf", "popf", "sahf", "lahf" X}; XPRIVATE char *str_a0[] = X{ X movtab, movtab, movtab, movtab, X "movsb", "movsw", "cmpsb", "cmpsw" X}; XPRIVATE char *str_a8[] = X{ X testtab, testtab, "stosb", "stosw", X "lodsb", "lodsw", "scasb", "scasw" X}; XPRIVATE char *str_c0[] = X{ X empty, empty, "ret\t", "ret", X "les\t", "lds\t", movtab, movtab X}; XPRIVATE char *str_c8[] = X{ X "enter\t", "leave", "retf\t", "retf", X "int\t3", "int\t", "into", "iret" X}; XPRIVATE char *str_d0[] = X{ X "aam", "aad", "db\td6", "xlat" X}; XPRIVATE char *sstr_d0[] = X{ X "rol", "ror", "rcl", "rcr", X "shl", "shr", fishy, "sar" X}; XPRIVATE char *str_d8[] = X{ X fadd, fmul, fcom, fcomp, X fsub, fsubr, fdiv, fdivr, X fld, NULL, fst, fstp, X fldenv, fldcw, fstenv, fstcw, X fiadd, fimul, ficom, ficomp, X fisub, fisubr, fidiv, fidivr, X fild, NULL, fist, fistp, X NULL, fld, NULL, fstp, X fadd, fmul, fcom, fcomp, X fsub, fsubr, fdiv, fdivr, X fld, NULL, fst, fstp, X frstor, NULL, fsave, fstsw, X fiadd, fimul, ficom, ficomp, X fisub, fisubr, fidiv, fidivr, X fild, NULL, fist, fistp, X fbld, fild, fbstp, fistp X}; XPRIVATE char *str1_d8[] = X{ X fadd, fmul, fcom, fcomp, X fsub, fsubr, fdiv, fdivr, X fld, fxch, empty, fstp, X empty, empty, empty, empty, X NULL, NULL, NULL, NULL, X NULL, NULL, NULL, NULL, X NULL, NULL, NULL, NULL, X empty, NULL, NULL, NULL, X fadd, fmul, fcom, fcomp, X fsubr, fsub, fdivr, fdiv, X ffree, fxch, fst, fstp, X NULL, NULL, NULL, NULL, X faddp, fmulp, fcomp, empty, X fsubrp, fsubp, fdivrp, fdivp, X ffree, fxch, fst, fstp, X NULL, NULL, NULL, NULL, X}; XPRIVATE char *sstr1_d8[] = X{ X fnop, NULL, NULL, NULL, X NULL, NULL, NULL, NULL, X}; XPRIVATE char *sstr2_d8[] = X{ X fchs, fabs, empty, empty, X ftst, fxam, empty, empty, X fld1, fldl2t, fldl2e, fldpi, X fldlg2, fldln2, fldz, empty, X f2xm1, fyl2x, fptan, fpatan, X fxtract, empty, fdecstp, fincstp, X fprem, fyl2xp1, fsqrt, empty, X frndint, fscale, empty, empty, X}; XPRIVATE char *sstr3_d8[] = X{ X feni, fdisi, fclex, finit, X NULL, NULL, NULL, NULL, X}; XPRIVATE char *str_e0[] = X{ X "loopnz\t", "loopz\t", "loop\t", "jcxz\t", X intab, intab, s_outtab, s_outtab X}; XPRIVATE char *str_e8[] = X{ X calltab, jmptab, jmptab, jmptab, X intab, intab, s_outtab, s_outtab X}; XPRIVATE char *str_f0[] = X{ X "lock\t", "db\tf1", "repnz\t", "repz\t", X "hlt", "cmc", X /* other 2 from sstr_f0 */ X}; XPRIVATE char *sstr_f0[] = X{ X testtab, fishy, "not\t", "neg\t", X "mul\t", imultab, "div\t", "idiv\t" X}; XPRIVATE char *str_f8[] = X{ X "clc", "stc", "cli", "sti", X "cld", "std", X /* other 2 from sstr_f8 */ X}; XPRIVATE char *sstr_f8[] = X{ X inctab, dectab, calltab, "call\tfar ", X jmptab, "jmp\tfar ", pushtab, fishytab X}; X XPRIVATE int data_seg; /* data segment (munged name for asld) */ XPRIVATE count_t hasize; /* half address size in bits */ XPRIVATE count_t hdefsize; XPRIVATE count_t hosize; /* half operand size in bits */ X /* for easy index into reg tables */ XPRIVATE opcode_pt modregrm; XPRIVATE offset_t offtable[2]; XPRIVATE offset_t *offptr; XPRIVATE offset_t *off1ptr; X XPRIVATE su8_pt get8s() X{ X u8_pt got; X X if ( (got = get8()) > MAX_SIGNED_CHAR ) X got -= (MAX_UNSIGNED_CHAR + 1); X return got; X} X XPRIVATE offset_t getasize() X{ X if ( hasize == 16 ) X return get32(); X return get16(); X} X XPRIVATE void getmodregrm() X{ X modregrm = get8(); X} X XPRIVATE void i_00_to_3f( opc ) Xopcode_pt opc; X{ X opcode_pt sub; X X if ( opc == 15 ) X pagef(); X else if ( (sub = opc & 7) >= 6 ) X { X outustr( (sstr_00_to_3f - 6)[((opc >> 2) & 0xE) + sub] ); X if ( !(opc & 1) ) X data_seg = opc; X } X else X { X oututstr( str_00_to_3f[(opc >> 3) & 7] ); X if ( sub == 4 ) X { X outustr( genreg[0] ); X outcomma(); X Ib(); X } X else if ( sub == 5 ) X { X outax(); X outcomma(); X Iv(); X } X else X outad( sub ); X } X} X XPRIVATE void i_40_to_5f( opc ) Xopcode_pt opc; X{ X outustr( str_40_to_5f[(opc >> 3) & 3] ); X outustr( genreg[hosize + (opc & 7)] ); X} X XPRIVATE void i_60_to_6f( opc ) Xopcode_pt opc; X{ X /* for 386, some for 286 */ X X outustr( (str_60_to_6f - 0x60)[opc] ); X switch( opc ) X { X case 0x62: GvMa(); break; X case 0x63: EwRw(); break; X case 0x64: X case 0x65: data_seg = opc; break; X case 0x66: hosize = (16 + 8) - hdefsize; break; X case 0x67: hasize = (16 + 8) - hdefsize; break; X case 0x68: outword();Iv(); break; X case 0x6A: outword(); outimmed( SIGNBIT | WORDBIT ); break; X case 0x69: X /* IMUL /r iw-id like MOV iw */ X case 0x6B: X /* IMUL /r ib like MOV ib but target is w not b */ X getmodregrm(); X outbwptr( opc ); /* like C6, C7 but this differs */ X outea( opc ); X outcomma(); X if ( opc == 0x69 ) X /* also differs from C6, C7 */ X Iv(); X else X outimmed( SIGNBIT | WORDBIT ); X if ( modregrm & REG_MASK ) X /* not completely decoded (like DEBUG) */ X outfishy(); X break; X } X} X XPRIVATE void i_70_to_7f( opc ) Xopcode_pt opc; X{ X outustr( "j" ); X oututstr( (str_flags - 0x70)[opc] ); X Jb(); X} X XPRIVATE void i_80( opc ) Xopcode_pt opc; X{ X opcode_pt sub; X X if ( opc >= 4 ) X { X outustr( opc >=6 ? xchgtab : testtab ); X outad( opc ); X } X else X { X getmodregrm(); X oututstr( str_00_to_3f[sub = (modregrm & REG_MASK) >> REG_SHIFT] ); X outbwptr( opc ); X outea( opc ); X outcomma(); X outimmed( opc ); X if ( opc & SIGNBIT && (sub == 1 || sub == 4 || sub == 6) ) X /* X and, or and xor are technically illegal with sign extension X but make sense and are produced by MASM! X */ X outfishy(); X } X} X XPRIVATE void i_88( opc ) Xopcode_pt opc; X{ X if ( opc < 4 ) X { X outustr( movtab ); X outad( opc ); X } X else if ( opc == 5 ) X { X oututstr( "lea" ); X GvM(); X } X else if ( opc == 7 ) X { X oututstr( "pop" ); X getmodregrm(); X outwptr(); X Ev(); X if ( modregrm & REG_MASK ) X outfishy(); X } X else X { X getmodregrm(); X outustr( movtab ); X if ( !(opc & TOREGBIT) ) X { X Ev(); X outcomma(); X } X outustr( segreg[(modregrm & SREG_MASK) >> SREG_SHIFT] ); X if ( opc & TOREGBIT ) X { X outcomma(); X Ev(); X } X } X} X XPRIVATE void i_90( opc ) Xopcode_pt opc; X{ X if ( opc == 0 ) X outustr("nop"); X else X { X outustr( xchgtab ); X outax(); X outcomma(); X outustr( genreg[hosize + opc] ); X } X} X XPRIVATE void i_98( opc ) Xopcode_pt opc; X{ X outustr( str_98[opc] ); X if ( opc == 2 ) X outsegpc(); X} X XPRIVATE void i_a0( opc ) Xopcode_pt opc; X{ X outustr( str_a0[opc] ); X if ( opc < 4 ) X { X /* fake mod == MEM0_MOD, reg = 0 (ax) and rm == 6 or 5 ([d32] or [d16]) */ X if ( hasize == 16 ) X modregrm = 5; X else X modregrm = 6; X outad1( opc ^ TOREGBIT ); X } X} X XPRIVATE void i_a8( opc ) Xopcode_pt opc; X{ X outustr( str_a8[opc] ); X if ( opc < 2 ) X { X outalorx( opc ); X outcomma(); X outimmed( opc ); X } X} X XPRIVATE void i_b0( opc ) Xopcode_pt opc; X{ X outustr( movtab ); X outustr( genreg[opc] ); X outcomma(); X Ib(); X} X XPRIVATE void i_b8( opc ) Xopcode_pt opc; X{ X outustr( movtab ); X outustr( genreg[hosize + opc] ); X outcomma(); X Iv(); X} X XPRIVATE void i_c0( opc ) Xopcode_pt opc; X{ X outustr( str_c0[opc] ); X if ( opc >= 6 ) X { X getmodregrm(); X outbwptr( opc ); X outea( opc ); X outcomma(); X outimmed( opc & WORDBIT ); X if ( modregrm & REG_MASK ) X /* not completely decoded (like DEBUG) */ X outfishy(); X } X else if ( opc >= 4 ) X GvMp(); X else if ( opc == 2 ) X Iv(); X else if ( opc < 2 ) X shift( opc ); X} X XPRIVATE void i_c8( opc ) Xopcode_pt opc; X{ X outustr( str_c8[opc] ); X if ( opc == 0 ) X { X Iw(); X outcomma(); X Ib(); X } X if ( opc == 2 ) X Iv(); X else if ( opc == 5 ) X Ib(); X} X XPRIVATE void i_d0( opc ) Xopcode_pt opc; X{ X opcode_pt aabyte; X X if ( opc < 4 ) X shift( opc | 0xD0 ); X else X { X outustr( (str_d0 - 4)[opc] ); X if ( opc < 6 && (aabyte = get8()) != 0xA ) X { X outtab(); X outh8( aabyte ); X outfishy(); X } X } X} X XPRIVATE void i_d8( opc ) Xopcode_pt opc; X{ X opcode_pt esc; X char *str; X opcode_pt sub; X X getmodregrm(); X sub = (modregrm & REG_MASK) >> REG_SHIFT; X esc = (opc << 3) | sub; X if ( (str = ((modregrm & MOD_MASK) == REG_MOD ? str1_d8 : str_d8)[esc]) X == NULL ) X { Xescape: X oututstr( "esc" ); X outh8( esc ); X outcomma(); X outea( opc ); X return; X } X outustr( str ); X if ( (modregrm & MOD_MASK) == REG_MOD ) X { X if ( opc == 0 ) X { X if ( sub == 2 || sub == 3 ) X outtab(); X else X outustr( "\tst," ); X outf1(); X } X else if ( opc == 1 ) X { X if ( *str == 0 ) X { X if ( sub == 2 ) X { X str = sstr1_d8[modregrm & 7]; X if ( str == NULL ) X goto escape; X } X else X str = sstr2_d8[modregrm & 0x1F]; X outustr( str ); X } X else X { X outtab(); X outf1(); X } X } X else if ( opc < 4 ) X { X if ( *str == 0 ) X { X str = sstr3_d8[modregrm & 7]; X if ( str == NULL ) X goto escape; X outustr( str ); X } X else X outea( opc ); X } X else if ( !(opc & 1) ) X { X if ( *str == 0 ) X { X /* fcompp only */ X if ( (modregrm & RM_MASK) != 1 ) X goto escape; X outustr( "fcompp\tst(1)" ); X } X else X { X outtab(); X outf1(); X if ( sub != 2 && sub != 3 ) X outustr( ",st" ); X } X } X else X { X if ( sub < 4 ) X { X outtab(); X outf1(); X } X else X outea( opc ); X } X } X else X { X outtab(); X if ( (esc & 0xC) == 0xC ) X { X if ( esc & 0x10 ) X { X if ( esc == 0x3D || esc == 0x3F ) X { X outustr( "q" ); X outwptr(); X } X else X { X outustr( "t" ); X outbptr(); X } X } X /* else environment stuff */ X } X else X { X if ( opc < 4 ) X outustr( "d" ); X else if ( opc < 6 ) X outustr( "q" ); X outwptr(); X } X outea( opc ); X } X} X XPRIVATE void i_e0( opc ) Xopcode_pt opc; X{ X outustr( str_e0[opc] ); X if ( opc < 4 ) X Jb(); X else if ( opc < 6 ) X { X outalorx( opc ); X outcomma(); X Ib(); X } X else X { X Ib(); X outcomma(); X outalorx( opc ); X } X} X XPRIVATE void i_e8( opc ) Xopcode_pt opc; X{ X outustr( str_e8[opc] ); X if ( opc < 2 ) X Jv(); X else if ( opc == 2 ) X outsegpc(); X else if ( opc == 3 ) X Jb(); X else X { X if ( opc & TOREGBIT ) X { X outustr( genreg[10] ); X outcomma(); X outalorx( opc ); X } X else X { X outalorx( opc ); X outcomma(); X outustr( genreg[10] ); X } X } X} X XPRIVATE void i_f0( opc ) Xopcode_pt opc; X{ X opcode_pt sub; X X if ( opc < 6 ) X outustr( str_f0[opc] ); X else X { X getmodregrm(); X sub = (modregrm & REG_MASK) >> REG_SHIFT; X outustr( sstr_f0[sub] ); X outbwptr( opc ); X outea( opc ); X if ( sub == 0 ) X { X outcomma(); X outimmed( opc & WORDBIT ); X } X } X} X XPRIVATE void i_f8( opc ) Xopcode_pt opc; X{ X opcode_pt sub; X X if ( opc < 6 ) X outustr( str_f8[opc] ); X else X { X getmodregrm(); X sub = (modregrm & REG_MASK) >> REG_SHIFT; X if ( opc == 6 && sub >= 2 ) X outustr( fishytab ); X else X outustr( sstr_f8[sub] ); X outbwptr( opc ); X outea( opc ); X } X} X XPRIVATE void outad( opc ) Xopcode_pt opc; X{ X getmodregrm(); X outad1( opc ); X} X XPRIVATE void outad1( opc ) Xopcode_pt opc; X{ X if ( !(opc & TOREGBIT) ) X { X outea( opc ); X outcomma(); X } X if ( opc & WORDBIT ) X Gv1(); X else X outustr( genreg[(modregrm & REG_MASK) >> REG_SHIFT] ); X if ( opc & TOREGBIT ) X { X outcomma(); X outea( opc ); X } X} X XPRIVATE void outasize( off ) Xoffset_t off; X{ X if ( hasize == 16 ) X outh32( off ); X else X outh16( (u16_t) off ); X} X XPRIVATE void outalorx( opc ) Xopcode_pt opc; X{ X if ( opc & WORDBIT ) X outax(); X else X outustr( genreg[0] ); X} X XPRIVATE void outax() X{ X outustr( genreg[hosize] ); X} X XPRIVATE void outbptr() X{ X outustr( "byte ptr " ); X} X XPRIVATE void outbwptr( opc ) Xopcode_pt opc; X{ X if ( (modregrm & MOD_MASK) != REG_MOD ) X { X if ( opc & WORDBIT ) X outwptr(); X else X outbptr(); X } X} X XPRIVATE void outea( wordflags ) Xopcode_pt wordflags; X{ X reg_pt base; X reg_pt index; X opcode_pt mod; X reg_pt reg; X opcode_pt ss; X opcode_pt ssindexbase; X X reg = modregrm & RM_MASK; X if ( (mod = modregrm & MOD_MASK) == REG_MOD ) X outustr( genreg[hosize * (wordflags & WORDBIT) + reg] ); X else X { X outbyte( LINDIRECT ); X if ( hasize == 16 ) X { X if ( reg == 4 ) X { X base = (ssindexbase = get8()) & BASE_MASK; X if ( mod == MEM0_MOD && base == 5 ) X outgetadr(); X else X outustr( (genreg + 16)[base] ); X ss = (ssindexbase & SS_MASK) >> SS_SHIFT; X if ( (index = (ssindexbase & INDEX_MASK) >> INDEX_SHIFT) != 4 ) X { X outbyte( '+' ); X outustr( (genreg + 16)[index] ); X outstr( "\0\0\0*2\0*4\0*8\0" + (3 * ss) ); X } X } X else if ( mod == MEM0_MOD && reg == 5 ) X outgetadr(); X else X outustr( (genreg + 16)[reg] ); X } X else if ( mod == MEM0_MOD && reg == 6 ) X outgetadr(); X else X outustr( indreg[reg] ); X if ( mod == MEM1_MOD ) X /* fake sign extension to get +- */ X outimmed( SIGNBIT | WORDBIT ); X else if ( mod == MEM2_MOD ) X { X outbyte( '+' ); X outgetadr(); X } X outbyte( RINDIRECT ); X if ( hasize == 16 && reg == 4 && index == 4 && ss != 0 ) X outfishy(); X } X} X XPRIVATE void outf1() X{ X outustr( "st(" ); X outbyte( (int) ((modregrm & RM_MASK) + '0') ); X outbyte( ')' ); X} X XPRIVATE void outfishy() X{ X outustr( "\t???" ); X} X XPRIVATE void outgetadr() X{ X offset_t off; X struct nlist *sp; X X off = getasize(); X if ( (sp = findsval( off, data_seg )) != NULL ) X { X outsym( sp, off ); X *offptr++ = off; X } X else X outasize( off ); X} X XPRIVATE void outimmed( signwordflag ) Xopcode_pt signwordflag; X{ X su8_pt byte; X X if ( signwordflag & WORDBIT ) X { X if ( signwordflag & SIGNBIT ) X { X if ( (byte = get8s()) < 0 ) X { X outbyte( '-' ); X byte = -byte; X } X else X outbyte( '+' ); X outh8( (u8_pt) byte ); X } X else X Iv(); X } X else X Ib(); X} X XPRIVATE void outpc( pc ) Xoffset_t pc; X{ X struct nlist *sp; X X if ( hasize == 8 ) X pc = (u16_t) pc; X if ( (sp = findsval( pc, CSEG )) != NULL ) X { X outsym( sp, pc ); X *offptr++ = pc; X } X else if ( hasize == 16 ) X outh32( pc ); X else X outh16( (u16_t) pc ); X} X XPRIVATE void outsegpc() X{ X segment_t oldseg; X offset_t pc; X X pc = getasize(); X oldseg = uptr.seg; X outh16( uptr.seg = get16() ); /* fake segment for lookup of pc */ X outcolon(); X outpc( pc ); X uptr.seg = oldseg; X} X XPRIVATE void oututstr( s ) Xchar *s; X{ X outustr( s ); X outtab(); X} X XPRIVATE void outword() X{ X outustr( "dword " + ((16 - hosize) >> 3) ); X} X XPRIVATE void outwptr() X{ X outword(); X outustr( "ptr " ); X} X XPRIVATE bool_pt pagef() X{ X opcode_pt opc; X opcode_pt reg; X bool_t regbad; X X if ( (opc = get8()) <= 1 || opc == 0xBA ) X { X if ( opc == 0xBA ) X opc = 16; X else X opc *= 8; X getmodregrm(); X outustr( ssstr_0f[opc += (modregrm & REG_MASK) >> REG_SHIFT] ); X if ( opc < 6 || opc == 12 || opc == 14 ) X Ew(); X else if ( opc >= 8 && opc < 13 ) X Ms(); X else if ( opc >= 20 ) X { X outbwptr( WORDBIT ); X EvIb(); X } X } X else if ( opc < 4 ) X { X oututstr( "lar\0lsl" + 4 * (opc - 2) ); X GvEw(); X } X else if ( opc == 6 ) X outustr( "clts" ); X else if ( opc < 0x20 ) X outstr( fishy ); X else if ( opc < 0x27 && opc != 0x25 ) X { X outustr( movtab ); X getmodregrm(); X reg = (modregrm & REG_MASK) >> REG_SHIFT; X hosize = 16; X if ( !(opc & TOREGBIT) ) X { X Ev(); /* Rd() since hosize is 16 */ X outcomma(); X } X regbad = FALSE; X if ( opc & 1 ) X { X outustr( "dr" ); X if ( reg == 4 || reg == 5 ) X regbad = TRUE; X } X else if ( opc < 0x24 ) X { X outustr( "cr" ); X if ( reg >= 4 || reg == 1 ) X regbad = TRUE; X } X else X { X outustr( "tr" ); X if ( reg < 6 ) X regbad = TRUE; X } X outbyte( (int) (reg + '0') ); X if ( opc & TOREGBIT ) X { X outcomma(); X Ev(); X } X if ( regbad || (modregrm & MOD_MASK) != REG_MOD ) X outfishy(); X } X else if ( opc < 0x80 ) X outstr( fishy ); X else if ( opc < 0x90 ) X { X outustr( "j" ); X oututstr( (str_flags - 0x80)[opc] ); X Jv(); X } X else if ( opc < 0xA0 ) X { X outustr( "set" ); X oututstr( (str_flags - 0x90)[opc] ); X getmodregrm(); X outbwptr( 0 ); X Eb(); X } X else if ( opc < 0xC0 ) X { X outustr( (sstr_0f - 0xA0)[opc] ); X switch( opc ) X { X case 0xA3: case 0xAB: case 0xB3: case 0xBB: X EvGv(); X break; X case 0xA4: case 0xAC: X EvGv(); X outcomma(); X Ib(); X break; X case 0xA5: case 0xAD: X EvGv(); X outcomma(); X CL(); X break; X case 0xAF: case 0xBC: case 0xBD: X GvEv(); X break; X case 0xB2: case 0xB4: case 0xB5: X GvMp(); X break; X case 0xB6: case 0xBE: X Gv(); X outcomma(); X outbwptr( opc ); X Eb(); X break; X case 0xB7: case 0xBF: X Gv(); X outcomma(); X hosize = 8; /* done in Ew(), but too late */ X outbwptr( opc ); X Ew(); X break; X } X } X else X outstr( fishy ); X} X XPUBLIC bool_pt puti() X{ X static bool_t hadprefix; X opcode_pt opcode; X X offptr = offtable; X opcode = get8(); X if ( !hadprefix ) X { X data_seg = DSEG; X hdefsize = 8; X if ( bits32 ) X hdefsize = 16; X hosize = X hasize = hdefsize; X } X (*optable[opcode >> 3]) ( opcode < 0x80 ? opcode: opcode & 7 ); X if ( offptr > offtable ) X { X if ( stringtab() >= 31 ) X out2space(); X else X while ( stringtab() < 32 ) X outtab(); X outbyte( ';' ); X for ( off1ptr = offtable; off1ptr < offptr; ++off1ptr ) X { X outspace(); X outh32( *off1ptr ); X } X offptr = offtable; X } X if ( (opcode & 0xE7) == 0x26 || X opcode >= 0x64 && opcode < 0x68 || X opcode == 0xF0 || opcode == 0xF2 || opcode == 0xF3 ) X /* X not finished instruction for 0x26, 0x2E, 0x36, 0x3E seg overrides X and 0x64, 0x65 386 seg overrides X and 0x66, 0x67 386 size prefixes X and 0xF0 lock, 0xF2 repne, 0xF3 rep X */ X { X hadprefix = TRUE; X return FALSE; X } X hadprefix = FALSE; X return TRUE; X} X XPRIVATE void shift( opc ) Xopcode_pt opc; X{ X reg_pt reg; X X getmodregrm(); X reg = (modregrm & REG_MASK) >> REG_SHIFT; X oututstr( sstr_d0[reg] ); X outbwptr( opc ); X outea( opc ); X outcomma(); X if ( opc < 0xD0 ) X Ib(); X else if ( opc & 2 ) X CL(); X else X outbyte( '1' ); X} X XPRIVATE void checkmemory() X{ X if ( (modregrm & MOD_MASK) == REG_MOD ) X outfishy(); X} X XPRIVATE void CL() X{ X outustr( genreg[1] ); X} X XPRIVATE void Eb() X{ X outea( 0 ); X} X XPRIVATE void Ev() X{ X outea( WORDBIT ); X} X XPRIVATE void EvGv() X{ X getmodregrm(); X Ev(); X outcomma(); X Gv1(); X} X XPRIVATE void EvIb() X{ X Ev(); X outcomma(); X Ib(); X} X XPRIVATE void Ew() X{ X hosize = 8; X Ev(); X} X XPRIVATE void EwRw() X{ X hosize = 8; X EvGv(); X} X XPRIVATE void Gv() X{ X getmodregrm(); X Gv1(); X} X XPRIVATE void Gv1() X{ X outustr( genreg[hosize + ((modregrm & REG_MASK) >> REG_SHIFT)] ); X} X XPRIVATE void GvEv() X{ X Gv(); X outcomma(); X Ev(); X} X XPRIVATE void GvEw() X{ X Gv(); X outcomma(); X Ew(); X} X XPRIVATE void GvM() X{ X GvEv(); X checkmemory(); X} X XPRIVATE void GvMa() X{ X GvM(); X} X XPRIVATE void GvMp() X{ X GvM(); X} X XPRIVATE void Iv() X{ X if ( hosize == 16 ) X outh32( get32() ); X else X Iw(); X} X XPRIVATE void Jb() X{ X offset_t pcjump; X X pcjump = get8s(); X outpc( pcjump + uptr.off ); X} X XPRIVATE void Jv() X{ X offset_t pcjump; X X if ( hasize == 16 ) X pcjump = get32(); X else X pcjump = (su16_t) get16(); X outpc( pcjump + uptr.off ); X} X XPRIVATE void Ms() X{ X Ev(); X checkmemory(); X} END_OF_FILE if test 24851 -ne `wc -c <'kernel/db/unasm.c'`; then echo shar: \"'kernel/db/unasm.c'\" unpacked with wrong size! fi # end of 'kernel/db/unasm.c' fi echo shar: End of archive 7 \(of 7\). cp /dev/null ark7isdone MISSING="" for I in 1 2 3 4 5 6 7 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 7 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 Bruce Evans Internet: brucee@runx.ips.oz.au UUCP: uunet!runx.ips.oz.au!brucee