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