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

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

unix.superglobalmegacorp.com

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