Annotation of previous/src/dimension/i860dis.cpp, revision 1.1

1.1     ! root        1: /***************************************************************************
        !             2: 
        !             3:     i860dis.c
        !             4: 
        !             5:     Disassembler for the Intel i860 emulator.
        !             6: 
        !             7:     Copyright (C) 1995-present Jason Eckhardt ([email protected])
        !             8:     Released for general non-commercial use under the MAME license
        !             9:     with the additional requirement that you are free to use and
        !            10:     redistribute this code in modified or unmodified form, provided
        !            11:     you list me in the credits.
        !            12:     Visit http://mamedev.org for licensing and usage restrictions.
        !            13: 
        !            14:     Changes for previous/NeXTdimension by Simon Schubiger (SC)
        !            15: 
        !            16: ***************************************************************************/
        !            17: 
        !            18: #include <string.h>
        !            19: #include <stdio.h>
        !            20: #include "i860.hpp"
        !            21: 
        !            22: /* Macros for accessing register fields in instruction word.  */
        !            23: #define get_isrc1(bits) (((bits) >> 11) & 0x1f)
        !            24: #define get_isrc2(bits) (((bits) >> 21) & 0x1f)
        !            25: #define get_idest(bits) (((bits) >> 16) & 0x1f)
        !            26: #define get_fsrc1(bits) (((bits) >> 11) & 0x1f)
        !            27: #define get_fsrc2(bits) (((bits) >> 21) & 0x1f)
        !            28: #define get_fdest(bits) (((bits) >> 16) & 0x1f)
        !            29: #define get_creg(bits)  (((bits) >> 21) & 0x7)
        !            30: 
        !            31: /* Macros for accessing immediate fields.  */
        !            32: /* 16-bit immediate.  */
        !            33: #define get_imm16(insn) ((insn) & 0xffff)
        !            34: 
        !            35: 
        !            36: /* Control register names.  */
        !            37: static const char *const cr2str[] =
        !            38:        {"fir", "psr", "dirbase", "db", "fsr", "epsr", "!", "!"};
        !            39: 
        !            40: 
        !            41: /* Sign extend N-bit number.  */
        !            42: static INT32 sign_ext(UINT32 x, int n)
        !            43: {
        !            44:        INT32 t;
        !            45:        t = x >> (n - 1);
        !            46:        t = ((-t) << n) | x;
        !            47:        return t;
        !            48: }
        !            49: 
        !            50: 
        !            51: /* Basic integer 3-address register format:
        !            52:  *   mnemonic %rs1,%rs2,%rd  */
        !            53: static void int_12d(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !            54: {
        !            55:        /* Possibly prefix shrd with 'd.' */
        !            56:        if (((insn & 0xfc000000) == 0xb0000000) && (insn & 0x200))
        !            57:                sprintf(buf, "d.%s\t%%r%d,%%r%d,%%r%d", mnemonic,
        !            58:                        get_isrc1 (insn), get_isrc2 (insn), get_idest (insn));
        !            59:        else
        !            60:                sprintf(buf, "  %s\t%%r%d,%%r%d,%%r%d", mnemonic,
        !            61:                        get_isrc1 (insn), get_isrc2 (insn), get_idest (insn));
        !            62: }
        !            63: 
        !            64: 
        !            65: /* Basic integer 3-address imm16 format:
        !            66:  *   mnemonic #imm16,%rs2,%rd  */
        !            67: static void int_i2d(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !            68: {
        !            69:        /* Sign extend the 16-bit immediate.
        !            70:           Print as hex for the bitwise operations.  */
        !            71:        int upper_6bits = (insn >> 26) & 0x3f;
        !            72:        if (upper_6bits >= 0x30 && upper_6bits <= 0x3f)
        !            73:                sprintf(buf, "  %s\t0x%04x,%%r%d,%%r%d", mnemonic,
        !            74:                        (UINT32)(get_imm16 (insn)), get_isrc2 (insn), get_idest (insn));
        !            75:        else
        !            76:                sprintf(buf, "  %s\t%d,%%r%d,%%r%d", mnemonic,
        !            77:                        sign_ext(get_imm16 (insn), 16), get_isrc2 (insn), get_idest (insn));
        !            78: }
        !            79: 
        !            80: 
        !            81: /* Integer (mixed) 2-address  isrc1ni,fdest.  */
        !            82: static void int_1d(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !            83: {
        !            84:        sprintf(buf, "  %s\t%%r%d,%%f%d", mnemonic, get_isrc1 (insn), get_fdest (insn));
        !            85: }
        !            86: 
        !            87: 
        !            88: /* Integer (mixed) 2-address  csrc2,idest.  */
        !            89: static void int_cd(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !            90: {
        !            91:        sprintf(buf, "  %s\t%%%s,%%r%d", mnemonic, cr2str[get_creg (insn)], get_idest (insn));
        !            92: }
        !            93: 
        !            94: 
        !            95: /* Integer (mixed) 2-address  isrc1,csrc2.  */
        !            96: static void int_1c(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !            97: {
        !            98:        sprintf(buf, "  %s\t%%r%d,%%%s", mnemonic, get_isrc1(insn), cr2str[get_creg (insn)]);
        !            99: }
        !           100: 
        !           101: 
        !           102: /* Integer 1-address register format:
        !           103:  *   mnemonic %rs1  */
        !           104: static void int_1(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           105: {
        !           106:        sprintf(buf, "  %s\t%%r%d", mnemonic, get_isrc1 (insn));
        !           107: }
        !           108: 
        !           109: 
        !           110: /* Integer no-address register format:
        !           111:  *   mnemonic  */
        !           112: static void int_0(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           113: {
        !           114:        sprintf(buf, "  %s", mnemonic);
        !           115: }
        !           116: 
        !           117: 
        !           118: /* Basic floating-point 3-address register format:
        !           119:  *   mnemonic %fs1,%fs2,%fd  */
        !           120: static void flop_12d(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           121: {
        !           122:        const char *const suffix[4] = { "ss", "sd", "ds", "dd" };
        !           123:        const char *prefix_d, *prefix_p;
        !           124:        prefix_p = (insn & 0x400) ? "p" : "";
        !           125:        prefix_d = (insn & 0x200) ? "d." : "  ";
        !           126: 
        !           127:        /* Special case: pf[m]am and pf[m]sm families are always pipelined, so they
        !           128:           do not have a prefix.  Also, for the pfmam and pfmsm families, replace
        !           129:           any 'a' in the mnemonic with 'm' and prepend an 'm'.  */
        !           130:        if ((insn & 0x7f) < 0x20)
        !           131:        {
        !           132:                int is_pfam = insn & 0x400;
        !           133:                if (!is_pfam)
        !           134:                {
        !           135:                        char newname[256];
        !           136:                        char *op = mnemonic;
        !           137:                        char *np = newname + 1;
        !           138:                        newname[0] = 'm';
        !           139:                        while (*op)
        !           140:                        {
        !           141:                                if (*op == 'a')
        !           142:                                        *np = 'm';
        !           143:                                else
        !           144:                                        *np = *op;
        !           145:                                np++;
        !           146:                                op++;
        !           147:                        }
        !           148:                        *np = 0;
        !           149:                        mnemonic = newname;
        !           150:                }
        !           151:                prefix_p = "";
        !           152:        }
        !           153: 
        !           154:        /* Special case: pfgt/pfle-- R-bit distinguishes the two.  */
        !           155:        if ((insn & 0x7f) == 0x34)
        !           156:        {
        !           157:                const char *const mn[2] = { "fgt.", "fle." };
        !           158:                int r = (insn & 0x080) >> 7;
        !           159:                int s = (insn & 0x100) ? 3 : 0;
        !           160:                sprintf(buf, "%s%s%s%s\t%%f%d,%%f%d,%%f%d", prefix_d, prefix_p, mn[r],
        !           161:                        suffix[s], get_fsrc1 (insn), get_fsrc2 (insn), get_fdest (insn));
        !           162:        }
        !           163:        else
        !           164:        {
        !           165:                int s = (insn & 0x180) >> 7;
        !           166:                sprintf(buf, "%s%s%s%s\t%%f%d,%%f%d,%%f%d", prefix_d, prefix_p, mnemonic,
        !           167:                        suffix[s], get_fsrc1 (insn), get_fsrc2 (insn), get_fdest (insn));
        !           168:        }
        !           169: }
        !           170: 
        !           171: 
        !           172: /* Floating-point 2-address register format:
        !           173:  *   mnemonic %fs1,%fd  */
        !           174: static void flop_1d(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           175: {
        !           176:        const char *const suffix[4] = { "ss", "sd", "ds", "dd" };
        !           177:        const char *prefix_d, *prefix_p;
        !           178:        int s = (insn & 0x180) >> 7;
        !           179:        prefix_p = (insn & 0x400) ? "p" : "";
        !           180:        prefix_d = (insn & 0x200) ? "d." : "  ";
        !           181:        sprintf(buf, "%s%s%s%s\t%%f%d,%%f%d", prefix_d, prefix_p, mnemonic,
        !           182:                suffix[s], get_fsrc1 (insn), get_fdest (insn));
        !           183: }
        !           184: 
        !           185: 
        !           186: /* Floating-point 2-address register format:
        !           187:  *   mnemonic %fs2,%fd  */
        !           188: static void flop_2d(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           189: {
        !           190:        const char *const suffix[4] = { "ss", "sd", "ds", "dd" };
        !           191:        const char *prefix_d;
        !           192:        int s = (insn & 0x180) >> 7;
        !           193:        prefix_d = (insn & 0x200) ? "d." : "  ";
        !           194:        sprintf(buf, "%s%s%s\t%%f%d,%%f%d", prefix_d, mnemonic, suffix[s],
        !           195:                get_fsrc2 (insn), get_fdest (insn));
        !           196: }
        !           197: 
        !           198: 
        !           199: /* Floating-point (mixed) 2-address register format:
        !           200:  *  fxfr fsrc1,idest.  */
        !           201: static void flop_fxfr(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           202: {
        !           203:        const char *prefix_d = (insn & 0x200) ? "d." : "  ";
        !           204:        sprintf(buf, "%s%s\t%%f%d,%%r%d", prefix_d, mnemonic, get_fsrc1 (insn),
        !           205:                get_idest (insn));
        !           206: }
        !           207: 
        !           208: 
        !           209: /* Branch with reg,reg,sbroff format:
        !           210:  *   mnemonic %rs1,%rs2,sbroff  */
        !           211: static void int_12S(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           212: {
        !           213:        INT32 sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
        !           214:        INT32 rel = (INT32)pc + (sbroff << 2) + 4;
        !           215: 
        !           216:        sprintf(buf, "  %s\t%%r%d,%%r%d,0x%08x", mnemonic, get_isrc1 (insn),
        !           217:                get_isrc2 (insn), (UINT32)rel);
        !           218: }
        !           219: 
        !           220: 
        !           221: /* Branch with #const5,reg,sbroff format:
        !           222:  *   mnemonic #const5,%rs2,sbroff  */
        !           223: static void int_i2S(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           224: {
        !           225:        INT32 sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
        !           226:        INT32 rel = (INT32)pc + (sbroff << 2) + 4;
        !           227: 
        !           228:        sprintf(buf, "  %s\t%d,%%r%d,0x%08x", mnemonic, ((insn >> 11) & 0x1f),
        !           229:                get_isrc2 (insn), (UINT32)rel);
        !           230: }
        !           231: 
        !           232: 
        !           233: /* Branch with lbroff format:
        !           234:  *   mnemonic lbroff  */
        !           235: static void int_L(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           236: {
        !           237:        INT32 lbroff =  sign_ext ((insn & 0x03ffffff), 26);
        !           238:        INT32 rel = (INT32)pc + (lbroff << 2) + 4;
        !           239: 
        !           240:        sprintf(buf, "  %s\t0x%08x", mnemonic, (UINT32)rel);
        !           241: }
        !           242: 
        !           243: 
        !           244: /* Integer load.
        !           245:  *  ld.{b,s,l} isrc1(isrc2),idest
        !           246:  *  ld.{b,s,l} #const(isrc2),idest  */
        !           247: static void int_ldx(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           248: {
        !           249:        /* Operand size, in bytes.  */
        !           250:        int sizes[4] = { 1, 1, 2, 4 };
        !           251:        const char *const suffix[4] = { "b", "b", "s", "l" };
        !           252:        UINT32 idx = 0;
        !           253: 
        !           254:        /* Bits 28 and 0 determine the operand size.  */
        !           255:        idx = ((insn >> 27) & 2) | (insn & 1);
        !           256: 
        !           257:        /* Bit 26 determines the addressing mode (reg+reg or disp+reg).  */
        !           258:        if (insn & 0x04000000)
        !           259:        {
        !           260:                /* Chop off lower bits of displacement.  */
        !           261:                INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
        !           262:                int size = sizes[idx];
        !           263:                immsrc1 &= ~(size - 1);
        !           264:                sprintf(buf, "  %s%s\t%d(%%r%d),%%r%d", mnemonic, suffix[idx],
        !           265:                        immsrc1, get_isrc2 (insn), get_idest (insn));
        !           266:        }
        !           267:        else
        !           268:                sprintf(buf, "  %s%s\t%%r%d(%%r%d),%%r%d", mnemonic, suffix[idx],
        !           269:                        get_isrc1 (insn), get_isrc2 (insn), get_idest (insn));
        !           270: }
        !           271: 
        !           272: 
        !           273: /* Integer store: st.b isrc1ni,#const(isrc2)  */
        !           274: static void int_stx(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           275: {
        !           276:        /* Operand size, in bytes.  */
        !           277:        int sizes[4] = { 1, 1, 2, 4 };
        !           278:        const char *const suffix[4] = { "b", "b", "s", "l" };
        !           279:        int idx = 0;
        !           280:        int size;
        !           281:        INT32 immsrc = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
        !           282: 
        !           283:        /* Bits 28 and 0 determine the operand size.  */
        !           284:        idx = ((insn >> 27) & 2) | (insn & 1);
        !           285: 
        !           286:        /* Chop off lower bits of displacement.  */
        !           287:        size = sizes[idx];
        !           288:        immsrc &= ~(size - 1);
        !           289:        sprintf(buf, "  %s%s\t%%r%d,%d(%%r%d)", mnemonic, suffix[idx],
        !           290:                get_isrc1 (insn), immsrc, get_isrc2 (insn));
        !           291: }
        !           292: 
        !           293: 
        !           294: /* Disassemble:
        !           295:  *  "[p]fld.y isrc1(isrc2),fdest", "[p]fld.y isrc1(isrc2)++,idest",
        !           296:  *  "[p]fld.y #const(isrc2),fdest" or "[p]fld.y #const(isrc2)++,idest".
        !           297:  *  "fst.y fdest,isrc1(isrc2)", "fst.y fdest,isrc1(isrc2)++",
        !           298:  *  "fst.y fdest,#const(isrc2)" or "fst.y fdest,#const(isrc2)++"
        !           299:  *  Where y = {l,d,q}.  Note, there is no pfld.q, though.  */
        !           300: static void int_fldst(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           301: {
        !           302:        INT32 immsrc1 = sign_ext (get_imm16 (insn), 16);
        !           303:        /* Operand size, in bytes.  */
        !           304:        int sizes[4] = { 8, 4, 16, 4 };
        !           305:        const char *const suffix[4] = { "d", "l", "q", "l" };
        !           306:        int idx = 0;
        !           307:        int size = 0;
        !           308:        int auto_inc = (insn & 1);
        !           309:        const char *const auto_suff[2] = { "", "++" };
        !           310:        int piped = (insn & 0x40000000) >> 30;
        !           311:        const char *const piped_suff[2] = { "", "p" };
        !           312:        int upper_6bits = (insn >> 26) & 0x3f;
        !           313:        int is_load = (upper_6bits == 8 || upper_6bits == 9 || upper_6bits == 24
        !           314:                                        || upper_6bits == 25);
        !           315: 
        !           316:        /* Bits 2 and 1 determine the operand size.  */
        !           317:        idx = ((insn >> 1) & 3);
        !           318:        size = sizes[idx];
        !           319: 
        !           320:        /* There is no pipelined load quad on XR.  */
        !           321:        if (piped && size == 16)
        !           322:        {
        !           323:                sprintf (buf, ".long\t%#08x; *", insn);
        !           324:                return;
        !           325:        }
        !           326: 
        !           327:        /* There is only a 64-bit pixel store.  */
        !           328:        if ((upper_6bits == 15) && size != 8)
        !           329:        {
        !           330:                sprintf (buf, ".long\t%#08x", insn);
        !           331:                return;
        !           332:        }
        !           333: 
        !           334:        /* Bit 26 determines the addressing mode (reg+reg or disp+reg).  */
        !           335:        if (insn & 0x04000000)
        !           336:        {
        !           337:                /* Chop off lower bits of displacement.  */
        !           338:                immsrc1 &= ~(size - 1);
        !           339:                if (is_load)
        !           340:                        sprintf(buf, "  %s%s%s\t%d(%%r%d)%s,%%f%d", piped_suff[piped], mnemonic,
        !           341:                                suffix[idx], immsrc1, get_isrc2 (insn), auto_suff[auto_inc],
        !           342:                                get_fdest (insn));
        !           343:                else
        !           344:                        sprintf(buf, "  %s%s\t%%f%d,%d(%%r%d)%s", mnemonic, suffix[idx],
        !           345:                                get_fdest (insn), immsrc1, get_isrc2 (insn), auto_suff[auto_inc]);
        !           346:        }
        !           347:        else
        !           348:        {
        !           349:                if (is_load)
        !           350:                        sprintf(buf, "  %s%s%s\t%%r%d(%%r%d)%s,%%f%d", piped_suff[piped],
        !           351:                                mnemonic, suffix[idx], get_isrc1 (insn), get_isrc2 (insn),
        !           352:                                auto_suff[auto_inc], get_fdest (insn));
        !           353:                else
        !           354:                        sprintf(buf, "  %s%s\t%%f%d,%%r%d(%%r%d)%s", mnemonic, suffix[idx],
        !           355:                                get_fdest (insn), get_isrc1 (insn), get_isrc2 (insn),
        !           356:                                auto_suff[auto_inc]);
        !           357:        }
        !           358: }
        !           359: 
        !           360: 
        !           361: /* flush #const(isrc2)[++].  */
        !           362: static void int_flush(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
        !           363: {
        !           364:        const char *const auto_suff[2] = { "", "++" };
        !           365:        INT32 immsrc = sign_ext (get_imm16 (insn), 16);
        !           366:        immsrc &= ~(16-1);
        !           367:        sprintf(buf, "  %s\t%d(%%r%d)%s", mnemonic, immsrc, get_isrc2 (insn),
        !           368:                auto_suff[(insn & 1)]);
        !           369: }
        !           370: 
        !           371: 
        !           372: /* Flags for the decode table.  */
        !           373: enum
        !           374: {
        !           375:        DEC_MORE    = 1,    /* More decoding necessary.  */
        !           376:        DEC_DECODED = 2     /* Fully decoded, go.  */
        !           377: };
        !           378: 
        !           379: 
        !           380: struct decode_tbl_t
        !           381: {
        !           382:        /* Disassembly function for this opcode.
        !           383:           Call with buffer, mnemonic, pc, insn.  */
        !           384:        void (*insn_dis)(char *, char *, UINT32, UINT32);
        !           385: 
        !           386:        /* Flags for this opcode.  */
        !           387:        char flags;
        !           388: 
        !           389:        /* Mnemonic of this opcode (sometimes partial when more decode is
        !           390:           done in disassembly routines-- e.g., loads and stores).  */
        !           391:        const char *mnemonic;
        !           392: };
        !           393: 
        !           394: 
        !           395: /* First-level decode table (i.e., for the 6 primary opcode bits).  */
        !           396: static const decode_tbl_t decode_tbl[64] =
        !           397: {
        !           398:        /* A slight bit of decoding for loads and stores is done in the
        !           399:           execution routines (operand size and addressing mode), which
        !           400:           is why their respective entries are identical.  */
        !           401:        { int_ldx,   DEC_DECODED, "ld."        }, /* ld.b isrc1(isrc2),idest.  */
        !           402:        { int_ldx,   DEC_DECODED, "ld."        }, /* ld.b #const(isrc2),idest.  */
        !           403:        { int_1d,    DEC_DECODED, "ixfr"       }, /* ixfr isrc1ni,fdest.        */
        !           404:        { int_stx,   DEC_DECODED, "st."        }, /* st.b isrc1ni,#const(isrc2).  */
        !           405:        { int_ldx,   DEC_DECODED, "ld."        }, /* ld.{s,l} isrc1(isrc2),idest.  */
        !           406:        { int_ldx,   DEC_DECODED, "ld."        }, /* ld.{s,l} #const(isrc2),idest.  */
        !           407:        { 0,         0           , 0           },
        !           408:        { int_stx,   DEC_DECODED, "st."        }, /* st.{s,l} isrc1ni,#const(isrc2),idest.*/
        !           409:        { int_fldst, DEC_DECODED, "fld."       }, /* fld.{l,d,q} isrc1(isrc2)[++],fdest.  */
        !           410:        { int_fldst, DEC_DECODED, "fld."       }, /* fld.{l,d,q} #const(isrc2)[++],fdest. */
        !           411:        { int_fldst, DEC_DECODED, "fst."       }, /* fst.{l,d,q} fdest,isrc1(isrc2)[++]   */
        !           412:        { int_fldst, DEC_DECODED, "fst."       }, /* fst.{l,d,q} fdest,#const(isrc2)[++]  */
        !           413:        { int_cd,    DEC_DECODED, "ld.c"       }, /* ld.c csrc2,idest.                    */
        !           414:        { int_flush, DEC_DECODED, "flush"      }, /* flush #const(isrc2) (or autoinc).    */
        !           415:        { int_1c,    DEC_DECODED, "st.c"       }, /* st.c isrc1,csrc2.                    */
        !           416:        { int_fldst, DEC_DECODED, "pstd."      }, /* pst.d fdest,#const(isrc2)[++].       */
        !           417:        { int_1,     DEC_DECODED, "bri"        }, /* bri isrc1ni.                         */
        !           418:        { int_12d,   DEC_DECODED, "trap"       }, /* trap isrc1ni,isrc2,idest.            */
        !           419:        { 0,         DEC_MORE,    0            }, /* FP ESCAPE FORMAT, more decode.       */
        !           420:        { 0,         DEC_MORE,    0            }, /* CORE ESCAPE FORMAT, more decode.     */
        !           421:        { int_12S,   DEC_DECODED, "btne"       }, /* btne isrc1,isrc2,sbroff.             */
        !           422:        { int_i2S,   DEC_DECODED, "btne"       }, /* btne #const,isrc2,sbroff.            */
        !           423:        { int_12S,   DEC_DECODED, "bte"        }, /* bte isrc1,isrc2,sbroff.              */
        !           424:        { int_i2S,   DEC_DECODED, "bte"        }, /* bte #const5,isrc2,idest.             */
        !           425:        { int_fldst, DEC_DECODED, "pfld."      }, /* pfld.{l,d,q} isrc1(isrc2)[++],fdest. */
        !           426:        { int_fldst, DEC_DECODED, "pfld."      }, /* pfld.{l,d,q} #const(isrc2)[++],fdest.*/
        !           427:        { int_L,     DEC_DECODED, "br"         }, /* br lbroff.    */
        !           428:        { int_L,     DEC_DECODED, "call"       }, /* call lbroff . */
        !           429:        { int_L,     DEC_DECODED, "bc"         }, /* bc lbroff.    */
        !           430:        { int_L,     DEC_DECODED, "bc.t"       }, /* bc.t lbroff.  */
        !           431:        { int_L,     DEC_DECODED, "bnc"        }, /* bnc lbroff.   */
        !           432:        { int_L,     DEC_DECODED, "bnc.t"      }, /* bnc.t lbroff. */
        !           433:        { int_12d,   DEC_DECODED, "addu"       }, /* addu isrc1,isrc2,idest.    */
        !           434:        { int_i2d,   DEC_DECODED, "addu"       }, /* addu #const,isrc2,idest.   */
        !           435:        { int_12d,   DEC_DECODED, "subu"       }, /* subu isrc1,isrc2,idest.    */
        !           436:        { int_i2d,   DEC_DECODED, "subu"       }, /* subu #const,isrc2,idest.   */
        !           437:        { int_12d,   DEC_DECODED, "adds"       }, /* adds isrc1,isrc2,idest.    */
        !           438:        { int_i2d,   DEC_DECODED, "adds"       }, /* adds #const,isrc2,idest.   */
        !           439:        { int_12d,   DEC_DECODED, "subs"       }, /* subs isrc1,isrc2,idest.    */
        !           440:        { int_i2d,   DEC_DECODED, "subs"       }, /* subs #const,isrc2,idest.   */
        !           441:        { int_12d,   DEC_DECODED, "shl"        }, /* shl isrc1,isrc2,idest.     */
        !           442:        { int_i2d,   DEC_DECODED, "shl"        }, /* shl #const,isrc2,idest.    */
        !           443:        { int_12d,   DEC_DECODED, "shr"        }, /* shr isrc1,isrc2,idest.     */
        !           444:        { int_i2d,   DEC_DECODED, "shr"        }, /* shr #const,isrc2,idest.    */
        !           445:        { int_12d,   DEC_DECODED, "shrd"       }, /* shrd isrc1ni,isrc2,idest.  */
        !           446:        { int_12S,   DEC_DECODED, "bla"        }, /* bla isrc1ni,isrc2,sbroff.  */
        !           447:        { int_12d,   DEC_DECODED, "shra"       }, /* shra isrc1,isrc2,idest.    */
        !           448:        { int_i2d,   DEC_DECODED, "shra"       }, /* shra #const,isrc2,idest.   */
        !           449:        { int_12d,   DEC_DECODED, "and"        }, /* and isrc1,isrc2,idest.     */
        !           450:        { int_i2d,   DEC_DECODED, "and"        }, /* and #const,isrc2,idest.    */
        !           451:        { 0,         0           , 0           },
        !           452:        { int_i2d,   DEC_DECODED, "andh"       }, /* andh #const,isrc2,idest.   */
        !           453:        { int_12d,   DEC_DECODED, "andnot"     }, /* andnot isrc1,isrc2,idest.  */
        !           454:        { int_i2d,   DEC_DECODED, "andnot"     }, /* andnot #const,isrc2,idest. */
        !           455:        { 0,         0           , 0           },
        !           456:        { int_i2d,   DEC_DECODED, "andnoth"    }, /* andnoth #const,isrc2,idest.*/
        !           457:        { int_12d,   DEC_DECODED, "or"         }, /* or isrc1,isrc2,idest.      */
        !           458:        { int_i2d,   DEC_DECODED, "or"         }, /* or #const,isrc2,idest.     */
        !           459:        { 0,         0           , 0           },
        !           460:        { int_i2d,   DEC_DECODED, "orh"        }, /* orh #const,isrc2,idest.    */
        !           461:        { int_12d,   DEC_DECODED, "xor"        }, /* xor isrc1,isrc2,idest.     */
        !           462:        { int_i2d,   DEC_DECODED, "xor"        }, /* xor #const,isrc2,idest.    */
        !           463:        { 0,         0           , 0           },
        !           464:        { int_i2d,   DEC_DECODED, "xorh"       }, /* xorh #const,isrc2,idest.   */
        !           465: };
        !           466: 
        !           467: 
        !           468: /* Second-level decode table (i.e., for the 3 core escape opcode bits).  */
        !           469: static const decode_tbl_t core_esc_decode_tbl[8] =
        !           470: {
        !           471:        { 0,         0          , 0           },
        !           472:        { int_0,     DEC_DECODED, "lock"      }, /* lock.           */
        !           473:        { int_1,     DEC_DECODED, "calli"     }, /* calli isrc1ni.  */
        !           474:        { 0,         0          , 0           },
        !           475:        { int_0,     DEC_DECODED, "intovr"    }, /* intovr.         */
        !           476:        { 0,         0          , 0           },
        !           477:        { 0,         0          , 0           },
        !           478:        { int_0,     DEC_DECODED, "unlock"    }, /* unlock.         */
        !           479: };
        !           480: 
        !           481: 
        !           482: /* Second-level decode table (i.e., for the 7 FP extended opcode bits).  */
        !           483: static const decode_tbl_t fp_decode_tbl[128] =
        !           484: {
        !           485:        /* Floating point instructions.  The least significant 7 bits are
        !           486:           the (extended) opcode and bits 10:7 are P,D,S,R respectively
        !           487:           ([p]ipelined, [d]ual, [s]ource prec., [r]esult prec.).
        !           488:           For some operations, I defer decoding the P,S,R bits to the
        !           489:           emulation routine for them.  */
        !           490:        { flop_12d,  DEC_DECODED, "r2p1."     }, /* 0x00 pf[m]am */
        !           491:        { flop_12d,  DEC_DECODED, "r2pt."     }, /* 0x01 pf[m]am */
        !           492:        { flop_12d,  DEC_DECODED, "r2ap1."    }, /* 0x02 pf[m]am */
        !           493:        { flop_12d,  DEC_DECODED, "r2apt."    }, /* 0x03 pf[m]am */
        !           494:        { flop_12d,  DEC_DECODED, "i2p1."     }, /* 0x04 pf[m]am */
        !           495:        { flop_12d,  DEC_DECODED, "i2pt."     }, /* 0x05 pf[m]am */
        !           496:        { flop_12d,  DEC_DECODED, "i2ap1."    }, /* 0x06 pf[m]am */
        !           497:        { flop_12d,  DEC_DECODED, "i2apt."    }, /* 0x07 pf[m]am */
        !           498:        { flop_12d,  DEC_DECODED, "rat1p2."   }, /* 0x08 pf[m]am */
        !           499:        { flop_12d,  DEC_DECODED, "m12apm."   }, /* 0x09 pf[m]am */
        !           500:        { flop_12d,  DEC_DECODED, "ra1p2."    }, /* 0x0A pf[m]am */
        !           501:        { flop_12d,  DEC_DECODED, "m12ttpa."  }, /* 0x0B pf[m]am */
        !           502:        { flop_12d,  DEC_DECODED, "iat1p2."   }, /* 0x0C pf[m]am */
        !           503:        { flop_12d,  DEC_DECODED, "m12tpm."   }, /* 0x0D pf[m]am */
        !           504:        { flop_12d,  DEC_DECODED, "ia1p2."    }, /* 0x0E pf[m]am */
        !           505:        { flop_12d,  DEC_DECODED, "m12tpa."   }, /* 0x0F pf[m]am */
        !           506:        { flop_12d,  DEC_DECODED, "r2s1."     }, /* 0x10 pf[m]sm */
        !           507:        { flop_12d,  DEC_DECODED, "r2st."     }, /* 0x11 pf[m]sm */
        !           508:        { flop_12d,  DEC_DECODED, "r2as1."    }, /* 0x12 pf[m]sm */
        !           509:        { flop_12d,  DEC_DECODED, "r2ast."    }, /* 0x13 pf[m]sm */
        !           510:        { flop_12d,  DEC_DECODED, "i2s1."     }, /* 0x14 pf[m]sm */
        !           511:        { flop_12d,  DEC_DECODED, "i2st."     }, /* 0x15 pf[m]sm */
        !           512:        { flop_12d,  DEC_DECODED, "i2as1."    }, /* 0x16 pf[m]sm */
        !           513:        { flop_12d,  DEC_DECODED, "i2ast."    }, /* 0x17 pf[m]sm */
        !           514:        { flop_12d,  DEC_DECODED, "rat1s2."   }, /* 0x18 pf[m]sm */
        !           515:        { flop_12d,  DEC_DECODED, "m12asm."   }, /* 0x19 pf[m]sm */
        !           516:        { flop_12d,  DEC_DECODED, "ra1s2."    }, /* 0x1A pf[m]sm */
        !           517:        { flop_12d,  DEC_DECODED, "m12ttsa."  }, /* 0x1B pf[m]sm */
        !           518:        { flop_12d,  DEC_DECODED, "iat1s2."   }, /* 0x1C pf[m]sm */
        !           519:        { flop_12d,  DEC_DECODED, "m12tsm."   }, /* 0x1D pf[m]sm */
        !           520:        { flop_12d,  DEC_DECODED, "ia1s2."    }, /* 0x1E pf[m]sm */
        !           521:        { flop_12d,  DEC_DECODED, "m12tsa."   }, /* 0x1F pf[m]sm */
        !           522:        { flop_12d,  DEC_DECODED, "fmul."     }, /* 0x20 [p]fmul */
        !           523:        { flop_12d,  DEC_DECODED, "fmlow."    }, /* 0x21 fmlow.dd */
        !           524:        { flop_2d,   DEC_DECODED, "frcp."     }, /* 0x22 frcp.{ss,sd,dd} */
        !           525:        { flop_2d,   DEC_DECODED, "frsqr."    }, /* 0x23 frsqr.{ss,sd,dd} */
        !           526:        { flop_12d,  DEC_DECODED, "pfmul3.dd" }, /* 0x24 pfmul3.dd */
        !           527:        { 0,         0          , 0           }, /* 0x25 */
        !           528:        { 0,         0          , 0           }, /* 0x26 */
        !           529:        { 0,         0          , 0           }, /* 0x27 */
        !           530:        { 0,         0          , 0           }, /* 0x28 */
        !           531:        { 0,         0          , 0           }, /* 0x29 */
        !           532:        { 0,         0          , 0           }, /* 0x2A */
        !           533:        { 0,         0          , 0           }, /* 0x2B */
        !           534:        { 0,         0          , 0           }, /* 0x2C */
        !           535:        { 0,         0          , 0           }, /* 0x2D */
        !           536:        { 0,         0          , 0           }, /* 0x2E */
        !           537:        { 0,         0          , 0           }, /* 0x2F */
        !           538:        { flop_12d,  DEC_DECODED, "fadd."     }, /* 0x30, [p]fadd.{ss,sd,dd} */
        !           539:        { flop_12d,  DEC_DECODED, "fsub."     }, /* 0x31, [p]fsub.{ss,sd,dd} */
        !           540:        { flop_1d,   DEC_DECODED, "fix."      }, /* 0x32, [p]fix.{ss,sd,dd} */
        !           541:        { flop_1d,   DEC_DECODED, "famov."    }, /* 0x33, [p]famov.{ss,sd,ds,dd} */
        !           542:        { flop_12d,  DEC_DECODED, "f{gt,le}"  }, /* 0x34, pf{gt,le}.{ss,dd} */
        !           543:        { flop_12d,  DEC_DECODED, "feq."      }, /* 0x35, pfeq.{ss,dd} */
        !           544:        { 0,         0          , 0           }, /* 0x36 */
        !           545:        { 0,         0          , 0           }, /* 0x37 */
        !           546:        { 0,         0          , 0           }, /* 0x38 */
        !           547:        { 0,         0          , 0           }, /* 0x39 */
        !           548:        { flop_1d,   DEC_DECODED, "ftrunc."   }, /* 0x3A, [p]ftrunc.{ss,sd,dd} */
        !           549:        { 0,         0          , 0           }, /* 0x3B */
        !           550:        { 0,         0          , 0           }, /* 0x3C */
        !           551:        { 0,         0          , 0           }, /* 0x3D */
        !           552:        { 0,         0          , 0           }, /* 0x3E */
        !           553:        { 0,         0          , 0           }, /* 0x3F */
        !           554:        { flop_fxfr, DEC_DECODED, "fxfr"      }, /* 0x40, fxfr fsrc1,idest. */
        !           555:        { 0,         0          , 0           }, /* 0x41 */
        !           556:        { 0,         0          , 0           }, /* 0x42 */
        !           557:        { 0,         0          , 0           }, /* 0x43 */
        !           558:        { 0,         0          , 0           }, /* 0x44 */
        !           559:        { 0,         0          , 0           }, /* 0x45 */
        !           560:        { 0,         0          , 0           }, /* 0x46 */
        !           561:        { 0,         0          , 0           }, /* 0x47 */
        !           562:        { 0,         0          , 0           }, /* 0x48 */
        !           563:        { flop_12d,  DEC_DECODED, "fiadd."    }, /* 0x49, [p]fiadd.{ss,dd} */
        !           564:        { 0,         0          , 0           }, /* 0x4A */
        !           565:        { 0,         0          , 0           }, /* 0x4B */
        !           566:        { 0,         0          , 0           }, /* 0x4C */
        !           567:        { flop_12d,  DEC_DECODED, "fisub."    }, /* 0x4D, [p]fisub.{ss,dd} */
        !           568:        { 0,         0          , 0           }, /* 0x4E */
        !           569:        { 0,         0          , 0           }, /* 0x4F */
        !           570:        { flop_12d,  DEC_DECODED, "faddp"     }, /* 0x50, [p]faddp */
        !           571:        { flop_12d,  DEC_DECODED, "faddz"     }, /* 0x51, [p]faddz */
        !           572:        { 0,         0          , 0           }, /* 0x52 */
        !           573:        { 0,         0          , 0           }, /* 0x53 */
        !           574:        { 0,         0          , 0           }, /* 0x54 */
        !           575:        { 0,         0          , 0           }, /* 0x55 */
        !           576:        { 0,         0          , 0           }, /* 0x56 */
        !           577:        { flop_12d,  DEC_DECODED, "fzchkl"    }, /* 0x57, [p]fzchkl */
        !           578:        { 0,         0          , 0           }, /* 0x58 */
        !           579:        { 0,         0          , 0           }, /* 0x59 */
        !           580:        { flop_1d,   DEC_DECODED, "form"      }, /* 0x5A, [p]form.dd */
        !           581:        { 0,         0          , 0           }, /* 0x5B */
        !           582:        { 0,         0          , 0           }, /* 0x5C */
        !           583:        { 0,         0          , 0           }, /* 0x5D */
        !           584:        { 0,         0          , 0           }, /* 0x5E */
        !           585:        { flop_12d,  DEC_DECODED, "fzchks"    }, /* 0x5F, [p]fzchks */
        !           586:        { 0,         0          , 0           }, /* 0x60 */
        !           587:        { 0,         0          , 0           }, /* 0x61 */
        !           588:        { 0,         0          , 0           }, /* 0x62 */
        !           589:        { 0,         0          , 0           }, /* 0x63 */
        !           590:        { 0,         0          , 0           }, /* 0x64 */
        !           591:        { 0,         0          , 0           }, /* 0x65 */
        !           592:        { 0,         0          , 0           }, /* 0x66 */
        !           593:        { 0,         0          , 0           }, /* 0x67 */
        !           594:        { 0,         0          , 0           }, /* 0x68 */
        !           595:        { 0,         0          , 0           }, /* 0x69 */
        !           596:        { 0,         0          , 0           }, /* 0x6A */
        !           597:        { 0,         0          , 0           }, /* 0x6B */
        !           598:        { 0,         0          , 0           }, /* 0x6C */
        !           599:        { 0,         0          , 0           }, /* 0x6D */
        !           600:        { 0,         0          , 0           }, /* 0x6E */
        !           601:        { 0,         0          , 0           }, /* 0x6F */
        !           602:        { 0,         0          , 0           }, /* 0x70 */
        !           603:        { 0,         0          , 0           }, /* 0x71 */
        !           604:        { 0,         0          , 0           }, /* 0x72 */
        !           605:        { 0,         0          , 0           }, /* 0x73 */
        !           606:        { 0,         0          , 0           }, /* 0x74 */
        !           607:        { 0,         0          , 0           }, /* 0x75 */
        !           608:        { 0,         0          , 0           }, /* 0x76 */
        !           609:        { 0,         0          , 0           }, /* 0x77 */
        !           610:        { 0,         0          , 0           }, /* 0x78 */
        !           611:        { 0,         0          , 0           }, /* 0x79 */
        !           612:        { 0,         0          , 0           }, /* 0x7A */
        !           613:        { 0,         0          , 0           }, /* 0x7B */
        !           614:        { 0,         0          , 0           }, /* 0x7C */
        !           615:        { 0,         0          , 0           }, /* 0x7D */
        !           616:        { 0,         0          , 0           }, /* 0x7E */
        !           617:        { 0,         0          , 0           }, /* 0x7F */
        !           618: };
        !           619: 
        !           620: 
        !           621: /* Replaces tabs with spaces.  */
        !           622: static void i860_dasm_tab_replacer(char* buf, int tab_size)
        !           623: {
        !           624:        int i = 0;
        !           625:        int tab_count = 0;
        !           626:        char tab_buf[1024];
        !           627:        memset(tab_buf, 0, 1024);
        !           628: 
        !           629:        while (i != strlen(buf))
        !           630:        {
        !           631:                if (buf[i] != '\t')
        !           632:                {
        !           633:                        tab_buf[tab_count] = buf[i];
        !           634:                        tab_count++;
        !           635:                }
        !           636:                else
        !           637:                {
        !           638:                        while (tab_count % tab_size != 0)
        !           639:                        {
        !           640:                                strcat(tab_buf, " ");
        !           641:                                tab_count++;
        !           642:                        }
        !           643:                }
        !           644:                i++;
        !           645:        }
        !           646: 
        !           647:        tab_buf[tab_count] = 0x00;
        !           648:        strcpy(buf, tab_buf);
        !           649: }
        !           650: 
        !           651: 
        !           652: int i860_disassembler(UINT32 pc, UINT32 insn, char* buffer) {
        !           653:        int unrecognized_op = 1;
        !           654:     
        !           655:        int upper_6bits = (insn >> 26) & 0x3f;
        !           656:        char flags = decode_tbl[upper_6bits].flags;
        !           657:     if(insn == INSN_NOP) {
        !           658:         strcpy(buffer, "  nop");
        !           659:         unrecognized_op = 0;
        !           660:     } else if(insn == INSN_FNOP) {
        !           661:         strcpy(buffer, "  fnop");
        !           662:         unrecognized_op = 0;
        !           663:     } else if(insn == INSN_FNOP_DIM) {
        !           664:         strcpy(buffer, "d.fnop");
        !           665:         unrecognized_op = 0;
        !           666:     } else if (flags & DEC_DECODED) {
        !           667:                const char *s = decode_tbl[upper_6bits].mnemonic;
        !           668:                decode_tbl[upper_6bits].insn_dis (buffer, (char *)s, pc, insn);
        !           669:                unrecognized_op = 0;
        !           670:        } else if (flags & DEC_MORE) {
        !           671:                if (upper_6bits == 0x12) {
        !           672:                        /* FP instruction format handled here.  */
        !           673:                        char fp_flags = fp_decode_tbl[insn & 0x7f].flags;
        !           674:                        const char *s = fp_decode_tbl[insn & 0x7f].mnemonic;
        !           675:                        if (fp_flags & DEC_DECODED) {
        !           676:                                fp_decode_tbl[insn & 0x7f].insn_dis (buffer, (char *)s, pc, insn);
        !           677:                                unrecognized_op = 0;
        !           678:                        }
        !           679:                }
        !           680:                else if (upper_6bits == 0x13) {
        !           681:                        /* Core escape instruction format handled here.  */
        !           682:                        char esc_flags = core_esc_decode_tbl[insn & 0x3].flags;
        !           683:                        const char *s = core_esc_decode_tbl[insn & 0x3].mnemonic;
        !           684:                        if (esc_flags & DEC_DECODED)
        !           685:                        {
        !           686:                                core_esc_decode_tbl[insn & 0x3].insn_dis (buffer, (char *)s, pc, insn);
        !           687:                                unrecognized_op = 0;
        !           688:                        }
        !           689:                }
        !           690:        }
        !           691: 
        !           692:        if (unrecognized_op)
        !           693:                sprintf (buffer, "  .long\t%#08x", insn);
        !           694: 
        !           695:        /* Replace tabs with spaces */
        !           696:        i860_dasm_tab_replacer(buffer, 10);
        !           697: 
        !           698:        /* Return number of bytes disassembled.  */
        !           699:        /* MAME dasm flags haven't been added yet */
        !           700:        return (4);
        !           701: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.