Annotation of mstools/samples/sdktools/image/drwatson/mips/disasm.c, revision 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.