Annotation of mstools/samples/sdktools/image/drwatson/mips/disasm.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     disasm.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This file provides support disassembly ( mips ).
                     12: 
                     13: Author:
                     14: 
                     15:     Gerd Immeyer       19-Oct-1989
                     16:     Wesley Witt (wesw) 1-May-1993    ( ported from ntsd to drwatson)
                     17: 
                     18: Environment:
                     19: 
                     20:     User Mode
                     21: 
                     22: --*/
                     23: 
                     24: #include <windows.h>
                     25: #include <stddef.h>
                     26: #include <string.h>
                     27: #include "regs.h"
                     28: #include "disasm.h"
                     29: #include "drwatson.h"
                     30: #include "proto.h"
                     31: 
                     32: 
                     33: #define OPCODE  18
                     34: #define OPSTART 26
                     35: 
                     36: typedef struct optabentry {
                     37:     PUCHAR   pszOpcode;
                     38:     ULONG    fInstruction;
                     39:     } OPTABENTRY, *POPTABENTRY;
                     40: 
                     41: 
                     42: static ULONG   ProcessorType = 0;
                     43: INSTR   disinstr;
                     44: ULONG   EAaddr = 0;
                     45: DWORD   EA;
                     46: 
                     47: UCHAR   pszUndef[]    = "????";
                     48: UCHAR   pszNull[]     = "";
                     49: 
                     50: UCHAR   pszAbs_s[]    = "abs.s";
                     51: UCHAR   pszAdd[]      = "add";
                     52: UCHAR   pszAdd_s[]    = "add.s";
                     53: UCHAR   pszAddi[]     = "addi";
                     54: UCHAR   pszAddiu[]    = "addiu";
                     55: UCHAR   pszAddu[]     = "addu";
                     56: UCHAR   pszAnd[]      = "and";
                     57: UCHAR   pszAndi[]     = "andi";
                     58: UCHAR   pszBc0f[]     = "bc0f";
                     59: UCHAR   pszBc0fl[]    = "bc0fl";
                     60: UCHAR   pszBc0t[]     = "bc0t";
                     61: UCHAR   pszBc0tl[]    = "bc0tl";
                     62: UCHAR   pszBc1f[]     = "bc1f";
                     63: UCHAR   pszBc1fl[]    = "bc1fl";
                     64: UCHAR   pszBc1t[]     = "bc1t";
                     65: UCHAR   pszBc1tl[]    = "bc1tl";
                     66: UCHAR   pszBc2f[]     = "bc2f";
                     67: UCHAR   pszBc2fl[]    = "bc2fl";
                     68: UCHAR   pszBc2t[]     = "bc2t";
                     69: UCHAR   pszBc2tl[]    = "bc2tl";
                     70: UCHAR   pszBc3f[]     = "bc3f";
                     71: UCHAR   pszBc3fl[]    = "bc3fl";
                     72: UCHAR   pszBc3t[]     = "bc3t";
                     73: UCHAR   pszBc3tl[]    = "bc3tl";
                     74: UCHAR   pszBgez[]     = "bgez";
                     75: UCHAR   pszBgezal[]   = "bgezal";
                     76: UCHAR   pszBgezall[]  = "bgezall";
                     77: UCHAR   pszBgezl[]    = "bgezl";
                     78: UCHAR   pszBgtz[]     = "bgtz";
                     79: UCHAR   pszBgtzl[]    = "bgtzl";
                     80: UCHAR   pszBeq[]      = "beq";
                     81: UCHAR   pszBeql[]     = "beql";
                     82: UCHAR   pszBlez[]     = "blez";
                     83: UCHAR   pszBlezl[]    = "blezl";
                     84: UCHAR   pszBltz[]     = "bltz";
                     85: UCHAR   pszBltzal[]   = "bltzal";
                     86: UCHAR   pszBltzall[]  = "bltzall";
                     87: UCHAR   pszBltzl[]    = "bltzl";
                     88: UCHAR   pszBne[]      = "bne";
                     89: UCHAR   pszBnel[]     = "bnel";
                     90: UCHAR   pszBreak[]    = "break";
                     91: UCHAR   pszCache[]    = "cache";
                     92: UCHAR   pszCeil_w_s[] = "ceil.w.s";
                     93: UCHAR   pszCfc0[]     = "cfc0";
                     94: UCHAR   pszCfc1[]     = "cfc1";
                     95: UCHAR   pszCfc2[]     = "cfc2";
                     96: UCHAR   pszCfc3[]     = "cfc3";
                     97: UCHAR   pszCtc0[]     = "ctc0";
                     98: UCHAR   pszCtc1[]     = "ctc1";
                     99: UCHAR   pszCtc2[]     = "ctc2";
                    100: UCHAR   pszCtc3[]     = "ctc3";
                    101: UCHAR   pszCop0[]     = "cop0";
                    102: UCHAR   pszCop1[]     = "cop1";
                    103: UCHAR   pszCop2[]     = "cop2";
                    104: UCHAR   pszCop3[]     = "cop3";
                    105: UCHAR   pszCvt_d_s[]  = "cvt.d.s";
                    106: UCHAR   pszCvt_e_s[]  = "cvt.e.s";
                    107: UCHAR   pszCvt_q_s[]  = "cvt.q.s";
                    108: UCHAR   pszCvt_s_s[]  = "cvt.s.s";
                    109: UCHAR   pszCvt_w_s[]  = "cvt.w.s";
                    110: UCHAR   pszC_eq_s[]   = "c.eq.s";
                    111: UCHAR   pszC_f_s[]    = "c.f.s";
                    112: UCHAR   pszC_le_s[]   = "c.le.s";
                    113: UCHAR   pszC_lt_s[]   = "c.lt.s";
                    114: UCHAR   pszC_nge_s[]  = "c.nge.s";
                    115: UCHAR   pszC_ngl_s[]  = "c.ngl.s";
                    116: UCHAR   pszC_ngle_s[] = "c.ngle.s";
                    117: UCHAR   pszC_ngt_s[]  = "c.ngt.s";
                    118: UCHAR   pszC_ole_s[]  = "c.ole.s";
                    119: UCHAR   pszC_olt_s[]  = "c.olt.s";
                    120: UCHAR   pszC_seq_s[]  = "c.seq.s";
                    121: UCHAR   pszC_sf_s[]   = "c.sf.s";
                    122: UCHAR   pszC_ueq_s[]  = "c.ueq.s";
                    123: UCHAR   pszC_ule_s[]  = "c.ule.s";
                    124: UCHAR   pszC_ult_s[]  = "c.ult.s";
                    125: UCHAR   pszC_un_s[]   = "c.un.s";
                    126: UCHAR   pszDiv[]      = "div";
                    127: UCHAR   pszDivu[]     = "divu";
                    128: UCHAR   pszDiv_s[]    = "div.s";
                    129: UCHAR   pszEret[]     = "eret";
                    130: UCHAR   pszFloor_w_s[] = "floor.w.s";
                    131: UCHAR   pszJ[]        = "j";
                    132: UCHAR   pszJal[]      = "jal";
                    133: UCHAR   pszJalr[]     = "jalr";
                    134: UCHAR   pszJr[]       = "jr";
                    135: UCHAR   pszLb[]       = "lb";
                    136: UCHAR   pszLbu[]      = "lbu";
                    137: UCHAR   pszLdc1[]     = "ldc1";
                    138: UCHAR   pszLdc2[]     = "ldc2";
                    139: UCHAR   pszLdc3[]     = "ldc3";
                    140: UCHAR   pszLh[]       = "lh";
                    141: UCHAR   pszLhu[]      = "lhu";
                    142: UCHAR   pszLui[]      = "lui";
                    143: UCHAR   pszLw[]       = "lw";
                    144: UCHAR   pszLwc0[]     = "lwc0";
                    145: UCHAR   pszLwc1[]     = "lwc1";
                    146: UCHAR   pszLwc2[]     = "lwc2";
                    147: UCHAR   pszLwc3[]     = "lwc3";
                    148: UCHAR   pszLwl[]      = "lwl";
                    149: UCHAR   pszLwr[]      = "lwr";
                    150: UCHAR   pszMfc0[]     = "mfc0";
                    151: UCHAR   pszMfc1[]     = "mfc1";
                    152: UCHAR   pszMfc2[]     = "mfc2";
                    153: UCHAR   pszMfc3[]     = "mfc3";
                    154: UCHAR   pszMfhi[]     = "mfhi";
                    155: UCHAR   pszMflo[]     = "mflo";
                    156: UCHAR   pszMov_s[]    = "mov.s";
                    157: UCHAR   pszMtc0[]     = "mtc0";
                    158: UCHAR   pszMtc1[]     = "mtc1";
                    159: UCHAR   pszMtc2[]     = "mtc2";
                    160: UCHAR   pszMtc3[]     = "mtc3";
                    161: UCHAR   pszMthi[]     = "mthi";
                    162: UCHAR   pszMtlo[]     = "mtlo";
                    163: UCHAR   pszMul_s[]    = "mul.s";
                    164: UCHAR   pszMult[]     = "mult";
                    165: UCHAR   pszMultu[]    = "multu";
                    166: UCHAR   pszNeg_s[]    = "neg.s";
                    167: UCHAR   pszNop[]      = "nop";
                    168: UCHAR   pszNor[]      = "nor";
                    169: UCHAR   pszOr[]       = "or";
                    170: UCHAR   pszOri[]      = "ori";
                    171: UCHAR   pszRfe[]      = "rfe";
                    172: UCHAR   pszRound_w_s[] = "round.w.s";
                    173: UCHAR   pszSb[]       = "sb";
                    174: UCHAR   pszSdc1[]     = "sdc1";
                    175: UCHAR   pszSdc2[]     = "sdc2";
                    176: UCHAR   pszSdc3[]     = "sdc3";
                    177: UCHAR   pszSh[]       = "sh";
                    178: UCHAR   pszSll[]      = "sll";
                    179: UCHAR   pszSllv[]     = "sllv";
                    180: UCHAR   pszSlt[]      = "slt";
                    181: UCHAR   pszSlti[]     = "slti";
                    182: UCHAR   pszSltiu[]    = "sltiu";
                    183: UCHAR   pszSltu[]     = "sltu";
                    184: UCHAR   pszSqrt_s[]   = "sqrt.s";
                    185: UCHAR   pszSra[]      = "sra";
                    186: UCHAR   pszSrav[]     = "srav";
                    187: UCHAR   pszSrl[]      = "srl";
                    188: UCHAR   pszSrlv[]     = "srlv";
                    189: UCHAR   pszSub[]      = "sub";
                    190: UCHAR   pszSub_s[]    = "sub.s";
                    191: UCHAR   pszSubu[]     = "subu";
                    192: UCHAR   pszSw[]       = "sw";
                    193: UCHAR   pszSwc0[]     = "swc0";
                    194: UCHAR   pszSwc1[]     = "swc1";
                    195: UCHAR   pszSwc2[]     = "swc2";
                    196: UCHAR   pszSwc3[]     = "swc3";
                    197: UCHAR   pszSwl[]      = "swl";
                    198: UCHAR   pszSwr[]      = "swr";
                    199: UCHAR   pszSync[]     = "sync";
                    200: UCHAR   pszSyscall[]  = "syscall";
                    201: UCHAR   pszTeq[]      = "teq";
                    202: UCHAR   pszTeqi[]     = "teqi";
                    203: UCHAR   pszTge[]      = "tge";
                    204: UCHAR   pszTgei[]     = "tgei";
                    205: UCHAR   pszTgeiu[]    = "tgeiu";
                    206: UCHAR   pszTgeu[]     = "tgeu";
                    207: UCHAR   pszTlbp[]     = "tlbp";
                    208: UCHAR   pszTlbr[]     = "tlbr";
                    209: UCHAR   pszTlbwi[]    = "tlbwi";
                    210: UCHAR   pszTlbwr[]    = "tlbwr";
                    211: UCHAR   pszTlt[]      = "tlt";
                    212: UCHAR   pszTlti[]     = "tlti";
                    213: UCHAR   pszTltiu[]    = "tltiu";
                    214: UCHAR   pszTltu[]     = "tltu";
                    215: UCHAR   pszTne[]      = "tne";
                    216: UCHAR   pszTnei[]     = "tnei";
                    217: UCHAR   pszTrunc_w_s[] = "trunc.w.s";
                    218: UCHAR   pszXor[]      = "xor";
                    219: UCHAR   pszXori[]     = "xori";
                    220: 
                    221: OPTABENTRY opTable[] = {
                    222:     { pszNull, 0 },                             //  00
                    223:     { pszNull, 0 },                             //  01
                    224:     { pszJ, opnAddr26 },                        //  02
                    225:     { pszJal, opnAddr26 },                      //  03
                    226:     { pszBeq, opnRsRtRel16 },                   //  04
                    227:     { pszBne, opnRsRtRel16 },                   //  05
                    228:     { pszBlez, opnRsRel16 },                    //  06
                    229:     { pszBgtz, opnRsRel16 },                    //  07
                    230:     { pszAddi, opnRtRsImm16 },                  //  08
                    231:     { pszAddiu, opnRtRsImm16 },                 //  09
                    232:     { pszSlti, opnRtRsImm16 },                  //  0a
                    233:     { pszSltiu, opnRtRsImm16 },                 //  0b
                    234:     { pszAndi, opnRtRsImm16 },                  //  0c
                    235:     { pszOri, opnRtRsImm16 },                   //  0d
                    236:     { pszXori, opnRtRsImm16 },                  //  0e
                    237:     { pszLui, opnRtImm16 },                     //  0f
                    238:     { pszCop0, opnImm26 },                      //  10
                    239:     { pszCop1, opnImm26 },                      //  11
                    240:     { pszCop2, opnImm26 },                      //  12
                    241:     { pszCop3, opnImm26 },                      //  13
                    242:     { pszBeql, opnRsRtRel16 + opnR4000 },       //  14
                    243:     { pszBnel, opnRsRtRel16 + opnR4000 },       //  15
                    244:     { pszBlezl, opnRsRel16 + opnR4000 },        //  16
                    245:     { pszBgtzl, opnRsRel16 + opnR4000 },        //  17
                    246:     { pszUndef, 0 },                            //  18
                    247:     { pszUndef, 0 },                            //  19
                    248:     { pszUndef, 0 },                            //  1a
                    249:     { pszUndef, 0 },                            //  1b
                    250:     { pszUndef, 0 },                            //  1c
                    251:     { pszUndef, 0 },                            //  1d
                    252:     { pszUndef, 0 },                            //  1e
                    253:     { pszUndef, 0 },                            //  1f
                    254:     { pszLb, opnRtByteIndex },                  //  20
                    255:     { pszLh, opnRtWordIndex },                  //  21
                    256:     { pszLwl, opnRtLeftIndex },                 //  22
                    257:     { pszLw, opnRtDwordIndex },                 //  23
                    258:     { pszLbu, opnRtByteIndex },                 //  24
                    259:     { pszLhu, opnRtWordIndex },                 //  25
                    260:     { pszLwr, opnRtRightIndex },                //  26
                    261:     { pszUndef, 0 },                            //  27
                    262:     { pszSb, opnRtByteIndex },                  //  28
                    263:     { pszSh, opnRtWordIndex },                  //  29
                    264:     { pszSwl, opnRtLeftIndex },                 //  2a
                    265:     { pszSw, opnRtDwordIndex },                 //  2b
                    266:     { pszUndef, 0 },                            //  2c
                    267:     { pszUndef, 0 },                            //  2d
                    268:     { pszSwr, opnRtRightIndex },                //  2e
                    269:     { pszCache, opnCacheRightIndex + opnR4000 }, //  2f
                    270:     { pszLwc0, opnRtDwordIndex },               //  30
                    271:     { pszLwc1, opnFtDwordIndex },               //  31
                    272:     { pszLwc2, opnRtDwordIndex },               //  32
                    273:     { pszLwc3, opnRtDwordIndex },               //  33
                    274:     { pszUndef, 0 },                            //  34
                    275:     { pszLdc1, opnFtDwordIndex + opnR4000 },    //  35  Qword?
                    276:     { pszLdc2, opnRtDwordIndex + opnR4000 },    //  36  Qword?
                    277:     { pszLdc3, opnRtDwordIndex + opnR4000 },    //  37  Qword?
                    278:     { pszSwc0, opnRtDwordIndex },               //  38
                    279:     { pszSwc1, opnFtDwordIndex },               //  39
                    280:     { pszSwc2, opnRtDwordIndex },               //  3a
                    281:     { pszSwc3, opnRtDwordIndex },               //  3b
                    282:     { pszUndef, 0 },                            //  3c
                    283:     { pszSdc1, opnFtDwordIndex + opnR4000 },    //  3d  Qword?
                    284:     { pszSdc2, opnRtDwordIndex + opnR4000 },    //  3e  Qword?
                    285:     { pszSdc3, opnRtDwordIndex + opnR4000 },    //  3f  Qword?
                    286:     };
                    287: 
                    288: OPTABENTRY opSpecialTable[] = {
                    289:     { pszSll, opnRdRtShift },                   //  00
                    290:     { pszUndef, 0 },                            //  01
                    291:     { pszSrl, opnRdRtShift },                   //  02
                    292:     { pszSra, opnRdRtShift },                   //  03
                    293:     { pszSllv, opnRdRtRs },                     //  04
                    294:     { pszUndef, 0 },                            //  05
                    295:     { pszSrlv, opnRdRtRs },                     //  06
                    296:     { pszSrav, opnRdRtRs },                     //  07
                    297:     { pszJr, opnRs },                           //  08
                    298:     { pszJalr, opnRdOptRs },                    //  09
                    299:     { pszUndef, 0 },                            //  0a
                    300:     { pszUndef, 0 },                            //  0b
                    301:     { pszSyscall, opnNone },                    //  0c
                    302:     { pszBreak, opnImm20 },                     //  0d
                    303:     { pszUndef, 0 },                            //  0e
                    304:     { pszSync, opnNone + opnR4000 },            //  0f
                    305:     { pszMfhi, opnRd },                         //  10
                    306:     { pszMthi, opnRs },                         //  11
                    307:     { pszMflo, opnRd },                         //  12
                    308:     { pszMtlo, opnRs },                         //  13
                    309:     { pszUndef, 0 },                            //  14
                    310:     { pszUndef, 0 },                            //  15
                    311:     { pszUndef, 0 },                            //  16
                    312:     { pszUndef, 0 },                            //  17
                    313:     { pszMult, opnRsRt },                       //  18
                    314:     { pszMultu, opnRsRt },                      //  19
                    315:     { pszDiv, opnRsRt },                        //  1a
                    316:     { pszDivu, opnRsRt },                       //  1b
                    317:     { pszUndef, 0 },                            //  1c
                    318:     { pszUndef, 0 },                            //  1d
                    319:     { pszUndef, 0 },                            //  1e
                    320:     { pszUndef, 0 },                            //  1f
                    321:     { pszAdd, opnRdRsRt },                      //  20
                    322:     { pszAddu, opnRdRsRt },                     //  21
                    323:     { pszSub, opnRdRsRt },                      //  22
                    324:     { pszSubu, opnRdRsRt },                     //  23
                    325:     { pszAnd, opnRdRsRt },                      //  24
                    326:     { pszOr, opnRdRsRt },                       //  25
                    327:     { pszXor, opnRdRsRt },                      //  26
                    328:     { pszNor, opnRdRsRt },                      //  27
                    329:     { pszUndef, 0 },                            //  28
                    330:     { pszUndef, 0 },                            //  29
                    331:     { pszSlt, opnRdRsRt },                      //  2a
                    332:     { pszSltu, opnRdRsRt },                     //  2b
                    333:     { pszUndef, 0 },                            //  2c
                    334:     { pszUndef, 0 },                            //  2d
                    335:     { pszUndef, 0 },                            //  2e
                    336:     { pszUndef, 0 },                            //  2f
                    337:     { pszTge, opnRsRtImm10 + opnR4000 },        //  30
                    338:     { pszTgeu, opnRsRtImm10 + opnR4000 },       //  31
                    339:     { pszTlt, opnRsRtImm10 + opnR4000 },        //  32
                    340:     { pszTltu, opnRsRtImm10 + opnR4000 },       //  33
                    341:     { pszTeq, opnRsRtImm10 + opnR4000 },        //  34
                    342:     { pszUndef, 0 },                            //  35
                    343:     { pszTne, opnRsRtImm10 + opnR4000 },        //  36
                    344:     { pszUndef, 0 },                            //  37
                    345:     { pszUndef, 0 },                            //  38
                    346:     { pszUndef, 0 },                            //  39
                    347:     { pszUndef, 0 },                            //  3a
                    348:     { pszUndef, 0 },                            //  3b
                    349:     { pszUndef, 0 },                            //  3c
                    350:     { pszUndef, 0 },                            //  3d
                    351:     { pszUndef, 0 },                            //  3e
                    352:     { pszUndef, 0 }                             //  3f
                    353:     };
                    354: 
                    355: OPTABENTRY opBcondTable[] = {
                    356:     { pszBltz, opnRsRel16 },                    //  00
                    357:     { pszBgez, opnRsRel16 },                    //  01
                    358:     { pszBltzl, opnRsRel16 + opnR4000 },        //  02
                    359:     { pszBgezl, opnRsRel16 + opnR4000 },        //  03
                    360:     { pszUndef, 0 },                            //  04
                    361:     { pszUndef, 0 },                            //  05
                    362:     { pszUndef, 0 },                            //  06
                    363:     { pszUndef, 0 },                            //  07
                    364:     { pszTgei, opnRsImm16 + opnR4000 },         //  08
                    365:     { pszTgeiu, opnRsImm16 + opnR4000 },        //  09
                    366:     { pszTlti, opnRsImm16 + opnR4000 },         //  0a
                    367:     { pszTltiu, opnRsImm16 + opnR4000 },        //  0b
                    368:     { pszTeqi, opnRsImm16 + opnR4000 },         //  0c
                    369:     { pszUndef, 0 },                            //  0d
                    370:     { pszTnei, opnRsImm16 + opnR4000 },         //  0e
                    371:     { pszUndef, 0 },                            //  0f
                    372:     { pszBltzal, opnRsRel16 },                  //  10
                    373:     { pszBgezal, opnRsRel16 },                  //  11
                    374:     { pszBltzall, opnRsRel16 + opnR4000 },      //  12
                    375:     { pszBgezall, opnRsRel16 + opnR4000 }       //  13
                    376:     };
                    377: 
                    378: OPTABENTRY opCopnTable[] = {
                    379:     { pszMfc0, opnRtRd },                       //  00
                    380:     { pszMfc1, opnRtFs },                       //  01
                    381:     { pszMfc2, opnRtRd },                       //  02
                    382:     { pszMfc3, opnRtRd },                       //  03
                    383:     { pszCfc0, opnRtRd },                       //  04
                    384:     { pszCfc1, opnRtFs },                       //  05
                    385:     { pszCfc2, opnRtRd },                       //  06
                    386:     { pszCfc3, opnRtRd },                       //  07
                    387:     { pszMtc0, opnRtRd },                       //  08
                    388:     { pszMtc1, opnRtFs },                       //  09
                    389:     { pszMtc2, opnRtRd },                       //  0a
                    390:     { pszMtc3, opnRtRd },                       //  0b
                    391:     { pszCtc0, opnRtRd },                       //  0c
                    392:     { pszCtc1, opnRtFs },                       //  0d
                    393:     { pszCtc2, opnRtRd },                       //  0e
                    394:     { pszCtc3, opnRtRd },                       //  0f
                    395:     { pszBc0f, opnRel16 },                      //  10
                    396:     { pszBc1f, opnRel16 },                      //  11
                    397:     { pszBc2f, opnRel16 },                      //  12
                    398:     { pszBc3f, opnRel16 },                      //  13
                    399:     { pszBc0t, opnRel16 },                      //  14
                    400:     { pszBc1t, opnRel16 },                      //  15
                    401:     { pszBc2t, opnRel16 },                      //  16
                    402:     { pszBc3t, opnRel16 },                      //  17
                    403:     { pszBc0fl, opnRel16 + opnR4000 },          //  18
                    404:     { pszBc1fl, opnRel16 + opnR4000 },          //  19
                    405:     { pszBc2fl, opnRel16 + opnR4000 },          //  1a
                    406:     { pszBc3fl, opnRel16 + opnR4000 },          //  1b
                    407:     { pszBc0tl, opnRel16 + opnR4000 },          //  1c
                    408:     { pszBc1tl, opnRel16 + opnR4000 },          //  1d
                    409:     { pszBc2tl, opnRel16 + opnR4000 },          //  1e
                    410:     { pszBc3tl, opnRel16 + opnR4000 }           //  1f
                    411:     };
                    412: 
                    413: OPTABENTRY opFloatTable[] = {
                    414:     { pszAdd_s, opnFdFsFt },                    //  00
                    415:     { pszSub_s, opnFdFsFt },                    //  01
                    416:     { pszMul_s, opnFdFsFt },                    //  02
                    417:     { pszDiv_s, opnFdFsFt },                    //  03
                    418:     { pszSqrt_s, opnFdFs + opnR4000 },          //  04
                    419:     { pszAbs_s, opnFdFs },                      //  05
                    420:     { pszMov_s, opnFdFs },                      //  06
                    421:     { pszNeg_s, opnFdFs },                      //  07
                    422:     { pszUndef, 0 },                            //  08
                    423:     { pszUndef, 0 },                            //  09
                    424:     { pszUndef, 0 },                            //  0a
                    425:     { pszUndef, 0 },                            //  0b
                    426:     { pszRound_w_s, opnFdFs + opnR4000 },       //  0c
                    427:     { pszTrunc_w_s, opnFdFs + opnR4000 },       //  0d
                    428:     { pszCeil_w_s, opnFdFs + opnR4000 },        //  0e
                    429:     { pszFloor_w_s, opnFdFs + opnR4000 },       //  0f
                    430:     { pszUndef, 0 },                            //  10
                    431:     { pszUndef, 0 },                            //  11
                    432:     { pszUndef, 0 },                            //  12
                    433:     { pszUndef, 0 },                            //  13
                    434:     { pszUndef, 0 },                            //  14
                    435:     { pszUndef, 0 },                            //  15
                    436:     { pszUndef, 0 },                            //  16
                    437:     { pszUndef, 0 },                            //  17
                    438:     { pszUndef, 0 },                            //  18
                    439:     { pszUndef, 0 },                            //  19
                    440:     { pszUndef, 0 },                            //  1a
                    441:     { pszUndef, 0 },                            //  1b
                    442:     { pszUndef, 0 },                            //  1c
                    443:     { pszUndef, 0 },                            //  1d
                    444:     { pszUndef, 0 },                            //  1e
                    445:     { pszUndef, 0 },                            //  1f
                    446:     { pszCvt_s_s, opnFdFs },                    //  20
                    447:     { pszCvt_d_s, opnFdFs },                    //  21
                    448:     { pszCvt_e_s, opnFdFs + opnR4000 },         //  22
                    449:     { pszCvt_q_s, opnFdFs + opnR4000 },         //  23
                    450:     { pszCvt_w_s, opnFdFs },                    //  24
                    451:     { pszUndef, 0 },                            //  25
                    452:     { pszUndef, 0 },                            //  26
                    453:     { pszUndef, 0 },                            //  27
                    454:     { pszUndef, 0 },                            //  28
                    455:     { pszUndef, 0 },                            //  29
                    456:     { pszUndef, 0 },                            //  2a
                    457:     { pszUndef, 0 },                            //  2b
                    458:     { pszUndef, 0 },                            //  2c
                    459:     { pszUndef, 0 },                            //  2d
                    460:     { pszUndef, 0 },                            //  2e
                    461:     { pszUndef, 0 },                            //  2f
                    462:     { pszC_f_s, opnFsFt },                      //  30
                    463:     { pszC_un_s, opnFsFt },                     //  31
                    464:     { pszC_eq_s, opnFsFt },                     //  32
                    465:     { pszC_ueq_s, opnFsFt },                    //  33
                    466:     { pszC_olt_s, opnFsFt },                    //  34
                    467:     { pszC_ult_s, opnFsFt },                    //  35
                    468:     { pszC_ole_s, opnFsFt },                    //  36
                    469:     { pszC_ule_s, opnFsFt },                    //  37
                    470:     { pszC_sf_s, opnFsFt },                     //  38
                    471:     { pszC_ngle_s, opnFsFt },                   //  39
                    472:     { pszC_seq_s, opnFsFt },                    //  3a
                    473:     { pszC_ngl_s, opnFsFt },                    //  3b
                    474:     { pszC_lt_s, opnFsFt },                     //  3c
                    475:     { pszC_nge_s, opnFsFt },                    //  3d
                    476:     { pszC_le_s, opnFsFt },                     //  3e
                    477:     { pszC_ngt_s, opnFsFt }                     //  3f
                    478:     };
                    479: 
                    480: OPTABENTRY TlbrEntry  = { pszTlbr, opnNone };
                    481: OPTABENTRY TlbwiEntry = { pszTlbwi, opnNone };
                    482: OPTABENTRY TlbwrEntry = { pszTlbwr, opnNone };
                    483: OPTABENTRY TlbpEntry  = { pszTlbp, opnNone };
                    484: OPTABENTRY RfeEntry   = { pszRfe, opnNone };
                    485: OPTABENTRY EretEntry  = { pszEret, opnNone };
                    486: OPTABENTRY UndefEntry = { pszUndef, 0 };
                    487: OPTABENTRY NopEntry   = { pszNop, opnNone };
                    488: 
                    489: static PUCHAR   pBufStart;
                    490: static PUCHAR   pBuf;
                    491: static ULONG    InstrOffset;
                    492: 
                    493: UCHAR HexDigit[16] = {
                    494:     '0', '1', '2', '3', '4', '5', '6', '7',
                    495:     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
                    496:     };
                    497: 
                    498: //
                    499: // prototypes
                    500: //
                    501: 
                    502: void BlankFill(ULONG count);
                    503: void OutputHex (ULONG outvalue, ULONG length, BOOLEAN fSigned);
                    504: void OutputDisSymbol (PDEBUGPACKET dp, ULONG offset);
                    505: void OutputString (PUCHAR pStr);
                    506: void OutputReg (ULONG regnum);
                    507: void OutputFReg (ULONG regnum);
                    508: void GetNextOffset (PDEBUGPACKET dp, PULONG result, BOOLEAN fStep);
                    509: BOOLEAN fDelayInstruction (PDEBUGPACKET dp);
                    510: PUCHAR RegNameFromIndex (ULONG index);
                    511: 
                    512: 
                    513: 
                    514: BOOLEAN
                    515: disasm (PDEBUGPACKET dp, PDWORD poffset, PUCHAR bufptr, BOOLEAN fEAout)
                    516: {
                    517:     ULONG       opcode;
                    518:     ULONG       temp;
                    519:     POPTABENTRY pEntry;
                    520:     UCHAR       chSuffix = '\0';
                    521:     UCHAR       EAsize = 0;
                    522: 
                    523:     pBufStart = pBuf = bufptr;
                    524:     OutputHex(*poffset, 8, 0);       //  output hex offset
                    525:     *pBuf++ = ' ';
                    526: 
                    527:     if (!ReadProcessMemory( dp->hProcess,
                    528:                             (LPVOID)*poffset,
                    529:                             (LPVOID)&disinstr.instruction,
                    530:                             sizeof(DWORD),
                    531:                             NULL
                    532:                            )) {
                    533:         OutputString("???????? ????");
                    534:         *pBuf = '\0';
                    535:         return FALSE;
                    536:     }
                    537: 
                    538:     OutputHex(disinstr.instruction, 8, 0);  //  output hex contents
                    539:     *pBuf++ = ' ';
                    540: 
                    541:     //  output the opcode in the table entry
                    542: 
                    543:     opcode = disinstr.jump_instr.Opcode;
                    544:     pEntry = &opTable[opcode];          //  default value
                    545: 
                    546:     if (opcode == 0x00)                 //  special opcodes
                    547:         if (disinstr.instruction)
                    548:             pEntry = &opSpecialTable[disinstr.special_instr.Funct];
                    549:         else
                    550:             pEntry = &NopEntry;         //  special opcode for no-op
                    551: 
                    552:     else if (opcode == 0x01) {          //  bcond opcodes
                    553:         opcode = disinstr.immed_instr.RT;
                    554:         if (opcode < 0x14)
                    555:             pEntry = &opBcondTable[opcode];
                    556:         else
                    557:             pEntry = &UndefEntry;
                    558:         }
                    559: 
                    560:     else if ((opcode & ~0x3) == 0x10) {  // coprocessor opcodes
                    561:         temp = disinstr.immed_instr.RS;
                    562:         if (temp & 0x10) {              //  test for CO bit
                    563:             if (opcode == 0x10) {       //  test if COP0
                    564:                 temp = disinstr.special_instr.Funct;
                    565:                 if (temp == 0x01)
                    566:                     pEntry = &TlbrEntry;
                    567:                 else if (temp == 0x02)
                    568:                     pEntry = &TlbwiEntry;
                    569:                 else if (temp == 0x06)
                    570:                     pEntry = &TlbwrEntry;
                    571:                 else if (temp == 0x08)
                    572:                     pEntry = &TlbpEntry;
                    573:                 else if (temp == 0x10)
                    574:                     pEntry = &RfeEntry;
                    575:                 else if (temp == 0x18)
                    576:                     pEntry = &EretEntry;
                    577:                 }
                    578:             else if (opcode == 0x11) { //  coprocessor operations
                    579:                 opcode = disinstr.float_instr.Funct;
                    580:                 pEntry = &opFloatTable[opcode];  //  get opcode
                    581:                 if (temp == 0x11)
                    582:                     chSuffix = 'd';
                    583:                 else if (temp == 0x12) {
                    584:                     chSuffix = 'e';
                    585:                     pEntry->fInstruction |= opnR4000;
                    586:                     }
                    587:                 else if (temp == 0x13) {
                    588:                     chSuffix = 'q';
                    589:                     pEntry->fInstruction |= opnR4000;
                    590:                     }
                    591:                 else if (temp == 0x14)
                    592:                     chSuffix = 'w';
                    593:                 else if (temp != 0x10)
                    594:                     pEntry = &UndefEntry;
                    595:                 }
                    596:             }
                    597:         else {                          //  no CO bit, general COPz ops
                    598:             if (!(temp & ~0x06))        //  rs = 0, 2, 4, 6
                    599:                 pEntry = &opCopnTable[temp * 2 + (opcode - 0x10)];
                    600:             else if ((temp & ~0x04) == 0x08) //  rs = 8 or 0xc, rt = 0 to 3
                    601:                 pEntry = &opCopnTable[(4 + (disinstr.immed_instr.RT & 3)) * 4
                    602:                                                         + (opcode - 0x10)];
                    603:             }
                    604:         }
                    605: 
                    606:     //  pEntry has the opcode string and operand template needed to
                    607:     //  output the instruction.
                    608: 
                    609:     OutputString(pEntry->pszOpcode);
                    610:     if (*(pBuf - 1) != '?' && chSuffix)
                    611:             *(pBuf - 1) = chSuffix;  //  change xxx.s to xxx.d, xxx.w,
                    612:                                      //  xxx.e, or xxx.q  (R4000 for e, q)
                    613: 
                    614:     BlankFill(OPSTART);
                    615: 
                    616:     //  cache instruction has special codes for RT field value:
                    617:     //      0 = 'i'; 1 = 'd'; 2 = 'si'; 3 = 'sd'
                    618: 
                    619:     if (pEntry->fInstruction & opnCache) {
                    620:         temp = disinstr.special_instr.RT;
                    621:         if (temp > 3)
                    622:             *pBuf++ = '?';
                    623:         else {
                    624:             if (temp > 1) {
                    625:                 *pBuf++ = 's';
                    626:                 temp -= 2;
                    627:                 }
                    628:             if (temp == 0)
                    629:                 *pBuf++ = 'i';
                    630:             else
                    631:                 *pBuf++ = 'd';
                    632:             }
                    633:         *pBuf++ = ',';
                    634:         }
                    635: 
                    636:     if (pEntry->fInstruction & opnPreRt) {
                    637:         OutputReg(disinstr.special_instr.RT);
                    638:         *pBuf++ = ',';
                    639:         }
                    640: 
                    641:     if (pEntry->fInstruction & opnRd)
                    642:         OutputReg(disinstr.special_instr.RD);
                    643: 
                    644:     if (pEntry->fInstruction & opnFd)
                    645:         OutputFReg(disinstr.float_instr.FD);
                    646: 
                    647:     if (pEntry->fInstruction & opnRdOptRs) {
                    648:         if (disinstr.special_instr.RD != 0x1f) {
                    649:             OutputReg(disinstr.special_instr.RD);
                    650:             *pBuf++ = ',';
                    651:             }
                    652:         OutputReg(disinstr.immed_instr.RS);
                    653:         }
                    654: 
                    655:     if (pEntry->fInstruction & opnRdComma)
                    656:         *pBuf++ = ',';
                    657: 
                    658:     if (pEntry->fInstruction & opnRs)
                    659:         OutputReg(disinstr.immed_instr.RS);
                    660: 
                    661:     if (pEntry->fInstruction & opnFs)
                    662:         OutputFReg(disinstr.float_instr.FS);
                    663: 
                    664:     if (pEntry->fInstruction & opnRsComma)
                    665:         *pBuf++ = ',';
                    666: 
                    667:     if (pEntry->fInstruction & opnRt)
                    668:         OutputReg(disinstr.immed_instr.RT);
                    669: 
                    670:     if (pEntry->fInstruction & opnFt)
                    671:         OutputFReg(disinstr.float_instr.FT);
                    672: 
                    673:     if (pEntry->fInstruction & opnRtComma)
                    674:         *pBuf++ = ',';
                    675: 
                    676:     if (pEntry->fInstruction & opnPostRs)
                    677:         OutputReg(disinstr.immed_instr.RS);
                    678: 
                    679:     if (pEntry->fInstruction & opnImm10)
                    680:         OutputHex((long)(short)disinstr.trap_instr.Value, 0, TRUE);
                    681: 
                    682:     if (pEntry->fInstruction & opnImm16)
                    683:         OutputHex((long)(short)disinstr.immed_instr.Value, 0, TRUE);
                    684: 
                    685:     if (pEntry->fInstruction & opnRel16)
                    686:         OutputDisSymbol(dp,((long)(short)disinstr.immed_instr.Value << 2)
                    687:                                                 + *poffset + sizeof(ULONG));
                    688: 
                    689:     if (pEntry->fInstruction & opnImm20)
                    690:         OutputHex(disinstr.break_instr.Value, 0, TRUE);
                    691: 
                    692:     if (pEntry->fInstruction & opnImm26)
                    693:         OutputHex(disinstr.jump_instr.Target, 0, TRUE);
                    694: 
                    695:     if (pEntry->fInstruction & opnAddr26)
                    696:         OutputDisSymbol(dp,(disinstr.jump_instr.Target << 2)
                    697:                                                 + (*poffset & 0xf0000000));
                    698: 
                    699:     if (pEntry->fInstruction & opnAnyIndex) {
                    700:         OutputHex((long)(short)disinstr.immed_instr.Value, 0, TRUE);
                    701:         *pBuf++ = '(';
                    702:         OutputReg(disinstr.immed_instr.RS);
                    703:         *pBuf++ = ')';
                    704: 
                    705:         //  if instruction is for R4000 only, output " (4) "
                    706: 
                    707:         if (ProcessorType == 0 && (pEntry->fInstruction & opnR4000))
                    708:             OutputString(" (R4000!) ");
                    709: 
                    710:         if (fEAout) {
                    711:             EAaddr = GetRegValue(dp, disinstr.immed_instr.RS + REGBASE)
                    712:                                 + (long)(short)disinstr.immed_instr.Value;
                    713:             if (pEntry->fInstruction & opnByteIndex)
                    714:                 EAsize = 1;
                    715:             else if (pEntry->fInstruction & opnWordIndex)
                    716:                 EAsize = 2;
                    717:             else if (pEntry->fInstruction & opnDwordIndex)
                    718:                 EAsize = 4;
                    719:             else if (pEntry->fInstruction & opnLeftIndex)
                    720:                 EAsize = (UCHAR)(4 - (EAaddr & 3));
                    721:             else // if (pEntry->fInstruction & opnRightIndex)
                    722:                 EAsize = (UCHAR)((EAaddr & 3) + 1);
                    723:             BlankFill(79 - 12 - (EAsize * 2));
                    724:             OutputString("EA:");
                    725:             OutputHex(EAaddr, 8, FALSE);
                    726:             *pBuf++ = '=';
                    727: 
                    728:             if (!ReadProcessMemory( dp->hProcess,
                    729:                                     (LPVOID)EAaddr,
                    730:                                     (LPVOID)&temp,
                    731:                                     EAsize,
                    732:                                     NULL
                    733:                                    )) {
                    734:                 while (EAsize--) {
                    735:                     *pBuf++ = '?';
                    736:                     *pBuf++ = '?';
                    737:                     }
                    738:                 }
                    739:             }
                    740:             else {
                    741:                 OutputHex(temp, (ULONG)(EAsize * 2), FALSE);
                    742:             }
                    743:         }
                    744: 
                    745:     if (pEntry->fInstruction & opnShift)
                    746:         OutputHex(disinstr.special_instr.RE, 2, FALSE);
                    747: 
                    748:     *poffset += sizeof(ULONG);
                    749:     *pBuf = '\0';
                    750:     return TRUE;
                    751: }
                    752: 
                    753: /*** BlankFill - blank-fill buffer
                    754: *
                    755: *   Purpose:
                    756: *       To fill the buffer at *pBuf with blanks until
                    757: *       position count is reached.
                    758: *
                    759: *   Input:
                    760: *       None.
                    761: *
                    762: *   Output:
                    763: *       None.
                    764: *
                    765: *************************************************************************/
                    766: 
                    767: void
                    768: BlankFill(ULONG count)
                    769: {
                    770:     do
                    771:         *pBuf++ = ' ';
                    772:     while (pBuf < pBufStart + count);
                    773: }
                    774: 
                    775: /*** OutputHex - output hex value
                    776: *
                    777: *   Purpose:
                    778: *       Output the value in outvalue into the buffer
                    779: *       pointed by *pBuf.  The value may be signed
                    780: *       or unsigned depending on the value fSigned.
                    781: *
                    782: *   Input:
                    783: *       outvalue - value to output
                    784: *       length - length in digits
                    785: *       fSigned - TRUE if signed else FALSE
                    786: *
                    787: *   Output:
                    788: *       None.
                    789: *
                    790: *************************************************************************/
                    791: 
                    792: void
                    793: OutputHex (ULONG outvalue, ULONG length, BOOLEAN fSigned)
                    794: {
                    795:     UCHAR   digit[8];
                    796:     LONG    index = 0;
                    797: 
                    798:     if (fSigned && (long)outvalue < 0) {
                    799:         *pBuf++ = '-';
                    800:         outvalue = (ULONG)(-(long)outvalue);
                    801:         }
                    802:     if (fSigned) {
                    803:         *pBuf++ = '0';
                    804:         *pBuf++ = 'x';
                    805:         }
                    806:     do {
                    807:         digit[index++] = HexDigit[outvalue & 0xf];
                    808:         outvalue >>= 4;
                    809:         }
                    810:     while ((fSigned && outvalue) || (!fSigned && index < (LONG)length));
                    811:     while (--index >= 0)
                    812:         *pBuf++ = digit[index];
                    813: }
                    814: 
                    815: /*** OutputDisSymbol - output symbol for disassembly
                    816: *
                    817: *   Purpose:
                    818: *       Access symbol table with given offset and put string into buffer.
                    819: *
                    820: *   Input:
                    821: *       offset - offset of address to output
                    822: *
                    823: *   Output:
                    824: *       buffer pointed by pBuf updated with string:
                    825: *               if symbol, no disp:     <symbol>(<offset>)
                    826: *               if symbol, disp:        <symbol>+<disp>(<offset>)
                    827: *               if no symbol, no disp:  <offset>
                    828: *
                    829: *************************************************************************/
                    830: 
                    831: void
                    832: OutputDisSymbol (PDEBUGPACKET dp, ULONG offset)
                    833: {
                    834:     ULONG   displacement;
                    835:     PUCHAR  pszTemp;
                    836:     UCHAR   ch;
                    837:     PSYMBOL sym;
                    838: 
                    839:     sym = GetSymFromAddrAllContexts( offset, &displacement, dp );
                    840:     if (sym) {
                    841:         pszTemp = UnDName( &sym->szName[1] );
                    842:         while (ch = *pszTemp++) {
                    843:             *pBuf++ = ch;
                    844:         }
                    845:         if (displacement) {
                    846:             *pBuf++ = '+';
                    847:             OutputHex(displacement, 8, TRUE);
                    848:         }
                    849:         *pBuf++ = '(';
                    850:         OutputHex(offset, 8, FALSE);
                    851:         *pBuf++ = ')';
                    852:     }
                    853:     else {
                    854:         OutputHex(offset, 8, FALSE);
                    855:     }
                    856: }
                    857: 
                    858: /*** OutputString - output string
                    859: *
                    860: *   Purpose:
                    861: *       Copy the string into the buffer pointed by pBuf.
                    862: *
                    863: *   Input:
                    864: *       *pStr - pointer to string
                    865: *
                    866: *   Output:
                    867: *       None.
                    868: *
                    869: *************************************************************************/
                    870: 
                    871: void
                    872: OutputString (PUCHAR pStr)
                    873: {
                    874:     while (*pStr)
                    875:         *pBuf++ = *pStr++;
                    876: }
                    877: 
                    878: void
                    879: OutputReg (ULONG regnum)
                    880: {
                    881:     OutputString(RegNameFromIndex(regnum + REGBASE));
                    882: }
                    883: 
                    884: void
                    885: OutputFReg (ULONG regnum)
                    886: {
                    887:     *pBuf++ = 'f';
                    888:     if (regnum > 9)
                    889:         *pBuf++ = (UCHAR)('0' + regnum / 10);
                    890:     *pBuf++ = (UCHAR)('0' + regnum % 10);
                    891: }
                    892: 
                    893: /*** GetNextOffset - compute offset for trace or step
                    894: *
                    895: *   Purpose:
                    896: *       From a limited disassembly of the instruction pointed
                    897: *       by the FIR register, compute the offset of the next
                    898: *       instruction for either a trace or step operation.
                    899: *
                    900: *   Input:
                    901: *       fStep - TRUE for step offset; FALSE for trace offset
                    902: *
                    903: *   Returns:
                    904: *       step or trace offset if input is TRUE or FALSE, respectively
                    905: *
                    906: *************************************************************************/
                    907: 
                    908: void
                    909: GetNextOffset (PDEBUGPACKET dp, PULONG result, BOOLEAN fStep)
                    910: {
                    911:     ULONG   returnvalue;
                    912:     ULONG   opcode;
                    913:     ULONG   firaddr;
                    914: 
                    915:     firaddr = GetRegValue(dp,REGFIR);
                    916: 
                    917:     ReadProcessMemory( dp->hProcess,
                    918:                        (LPVOID)firaddr,
                    919:                        (LPVOID)&disinstr.instruction,
                    920:                        sizeof(ULONG),
                    921:                        NULL
                    922:                      );
                    923: 
                    924:     opcode = disinstr.jump_instr.Opcode;
                    925:     returnvalue = firaddr + sizeof(ULONG) * 2;  //  assume delay slot
                    926: 
                    927:     if (disinstr.instruction == 0x0000000c) {
                    928:         // stepping over a syscall instruction must set the breakpoint
                    929:         // at the caller's return address, not the inst after the syscall
                    930:         returnvalue = GetRegValue(dp,REGRA);
                    931:     }
                    932:     else
                    933:     if (opcode == 0x00L                                    //  SPECIAL
                    934:                 && (disinstr.special_instr.Funct & ~0x01L) == 0x08L) {
                    935:                                                            //  jr/jalr only
                    936:         if (disinstr.special_instr.Funct == 0x08L || !fStep)  //  jr or trace
                    937:             returnvalue = GetRegValue(dp,disinstr.special_instr.RS + REGBASE);
                    938:         }
                    939:     else if (opcode == 0x01L) {
                    940:         //  For BCOND opcode, RT values 0x00 - 0x03, 0x10 - 0x13
                    941:         //  are defined as conditional jumps.  A 16-bit relative
                    942:         //  offset is taken if:
                    943:         //
                    944:         //    (RT is even and (RS) < 0  (0x00 = BLTZ,   0x02 = BLTZL,
                    945:         //                               0x10 = BLTZAL, 0x12 = BLTZALL)
                    946:         //     OR
                    947:         //     RT is odd and (RS) >= 0  (0x01 = BGEZ,   0x03 = BGEZL
                    948:         //                               0x11 = BGEZAL, 0x13 = BGEZALL))
                    949:         //  AND
                    950:         //    (RT is 0x00 to 0x03       (BLTZ BGEZ BLTZL BGEZL non-linking)
                    951:         //     OR
                    952:         //     fStep is FALSE           (linking and not stepping over))
                    953:         //
                    954:         if (((disinstr.immed_instr.RT & ~0x13) == 0x00) &&
                    955:               (((LONG)GetRegValue(dp,disinstr.immed_instr.RS + REGBASE) >= 0) ==
                    956:                   (BOOLEAN)(disinstr.immed_instr.RT & 0x01)) &&
                    957:               (((disinstr.immed_instr.RT & 0x10) == 0x00) || !fStep))
                    958:             returnvalue = ((LONG)(SHORT)disinstr.immed_instr.Value << 2)
                    959:                                                 + firaddr + sizeof(ULONG);
                    960:         }
                    961:     else if ((opcode & ~0x01L) == 0x02) {
                    962:         //  J and JAL opcodes (0x02 and 0x03).  Target is
                    963:         //  26-bit absolute offset using high four bits of the
                    964:         //  instruction location.  Return target if J opcode or
                    965:         //  not stepping over JAL.
                    966:         //
                    967:         if (opcode == 0x02 || !fStep)
                    968:             returnvalue = (disinstr.jump_instr.Target << 2)
                    969:                                                 + (firaddr & 0xf0000000);
                    970:         }
                    971:     else if ((opcode & ~0x11L) == 0x04) {
                    972:         //  BEQ, BNE, BEQL, BNEL opcodes (0x04, 0x05, 0x14, 0x15).
                    973:         //  Target is 16-bit relative offset to next instruction.
                    974:         //  Return target if (BEQ or BEQL) and (RS) == (RT),
                    975:         //  or (BNE or BNEL) and (RS) != (RT).
                    976:         //
                    977:         if ((BOOLEAN)(opcode & 0x01) ==
                    978:                 (BOOLEAN)(GetRegValue(dp,disinstr.immed_instr.RS + REGBASE)
                    979:                         != GetRegValue(dp,disinstr.immed_instr.RT + REGBASE)))
                    980:             returnvalue = ((long)(short)disinstr.immed_instr.Value << 2)
                    981:                                                 + firaddr + sizeof(ULONG);
                    982:         }
                    983:     else if ((opcode & ~0x11L) == 0x06) {
                    984:         //  BLEZ, BGTZ, BLEZL, BGTZL opcodes (0x06, 0x07, 0x16, 0x17).
                    985:         //  Target is 16-bit relative offset to next instruction.
                    986:         //  Return target if (BLEZ or BLEZL) and (RS) <= 0,
                    987:         //  or (BGTZ or BGTZL) and (RS) > 0.
                    988:         //
                    989:         if ((BOOLEAN)(opcode & 0x01) ==
                    990:                 (BOOLEAN)((long)GetRegValue(dp,disinstr.immed_instr.RS
                    991:                                                         + REGBASE) > 0))
                    992:             returnvalue = ((long)(short)disinstr.immed_instr.Value << 2)
                    993:                                                 + firaddr + sizeof(ULONG);
                    994:         }
                    995:     else if (opcode == 0x11L
                    996:                         && (disinstr.immed_instr.RS & ~0x04L) == 0x08L
                    997:                         && (disinstr.immed_instr.RT & ~0x03L) == 0x00L) {
                    998:         //  COP1 opcode (0x11) with (RS) == 0x08 or (RS) == 0x0c and
                    999:         //  (RT) == 0x00 to 0x03, producing BC1F, BC1T, BC1FL, BC1TL
                   1000:         //  instructions.  Return target if (BC1F or BC1FL) and floating
                   1001:         //  point condition is FALSE or if (BC1T or BC1TL) and condition TRUE.
                   1002:         //
                   1003:         if ((disinstr.immed_instr.RT & 0x01) == GetRegFlagValue(dp,FLAGFPC))
                   1004:             returnvalue = ((long)(short)disinstr.immed_instr.Value << 2)
                   1005:                                                 + firaddr + sizeof(ULONG);
                   1006:         }
                   1007:     else if ((opcode == 0x38) && (fStep)) {
                   1008:         //
                   1009:         // stepping over an SC instruction, so skip the immediately following
                   1010:         // BEQ instruction.  The SC will fail because we are tracing over it,
                   1011:         // the branch will be taken, and we will run through the LL/SC again
                   1012:         // until the SC succeeds.  Then the branch won't be taken, and we
                   1013:         // will hit our breakpoint.
                   1014:         //
                   1015: 
                   1016:         returnvalue += sizeof(ULONG);   //  skip BEQ and BEQ's delay slot
                   1017:     }
                   1018:     else
                   1019:         returnvalue -= sizeof(ULONG);   //  remove delay slot
                   1020: 
                   1021:     *result = returnvalue;
                   1022: }
                   1023: 
                   1024: /*** fDelayInstruction - returns flag TRUE if delayed instruction
                   1025: *
                   1026: *   Purpose:
                   1027: *       From a limited disassembly of the instruction pointed
                   1028: *       by the FIR register, return TRUE if delayed, else FALSE.
                   1029: *
                   1030: *   Input:
                   1031: *       None.
                   1032: *
                   1033: *   Returns:
                   1034: *       set if instruction is delayed execution
                   1035: *
                   1036: *************************************************************************/
                   1037: 
                   1038: BOOLEAN
                   1039: fDelayInstruction (PDEBUGPACKET dp)
                   1040: {
                   1041:     BOOLEAN returnvalue;
                   1042:     ULONG   opcode;
                   1043:     ULONG   firaddr = GetRegValue(dp,REGFIR);
                   1044: 
                   1045: 
                   1046:     ReadProcessMemory( dp->hProcess,
                   1047:                        (LPVOID)firaddr,
                   1048:                        (LPVOID)&disinstr.instruction,
                   1049:                        sizeof(ULONG),
                   1050:                        NULL
                   1051:                      );
                   1052: 
                   1053:     opcode = disinstr.jump_instr.Opcode;
                   1054: 
                   1055:     if (opcode == 0x00)
                   1056:         //  for SPECIAL opcode, JR and JALR use a delay slot
                   1057:         //
                   1058:         returnvalue = (BOOLEAN)((disinstr.special_instr.Funct & ~1L)
                   1059:                                                                 == 0x08);
                   1060:     else if (opcode == 0x01)
                   1061:         //  for BCOND opcode, RT == 0x00 to 0x03 or 0x10 to 0x13 have slot
                   1062:         //  BLTZ, BGEZ, BLTZL, BGEZL, BLTZAL, BGEZAL, BLTZALL, BGEZALL
                   1063:         //
                   1064:         returnvalue = (BOOLEAN)((disinstr.special_instr.RT & ~0x13L)
                   1065:                                                                 == 0x00);
                   1066:     else if ((opcode & ~0x07L) == 0x00)
                   1067:         //  opcodes 0x02 to 0x07 have delay slot (0x00 and 0x01 tested above)
                   1068:         //  J, JAL, BEQ, BNE, BLEZ, BGTZ
                   1069:         //
                   1070:         returnvalue = TRUE;
                   1071:     else if ((opcode & ~0x03L) == 0x14)
                   1072:         //  opcodes 0x14 to 0x17 have delay slot - BEQL, BNEL, BLEZL, BGTZL
                   1073:         //
                   1074:         returnvalue = TRUE;
                   1075:     else
                   1076:         //  opcodes 0x10 to 0x13 - COPn - BCxF, BCxT, BCxFL, BCxTL
                   1077:         //
                   1078:         returnvalue = (BOOLEAN)((opcode & ~0x03L) == 0x10
                   1079:                         && (disinstr.special_instr.RS & ~0x04L) == 0x08
                   1080:                         && (disinstr.special_instr.RT & ~0x03L) == 0x00);
                   1081: 
                   1082:     return returnvalue;
                   1083: }

unix.superglobalmegacorp.com

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