Annotation of mstools/samples/sdktools/image/drwatson/alpha/disasm.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1993  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     regs.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This file provides disassembly  ( alpha )
        !            12: 
        !            13: Author:
        !            14: 
        !            15:     Miche Baker-Harvey (v-michbh) 1-May-1993  (ported from ntsd)
        !            16: 
        !            17: Environment:
        !            18: 
        !            19:     User Mode
        !            20: 
        !            21: --*/
        !            22: 
        !            23: 
        !            24: #include <windows.h>
        !            25: #include <stddef.h>
        !            26: #include <string.h>
        !            27: 
        !            28: #include <alphaops.h>
        !            29: #include "disasm.h"
        !            30: #include "regs.h"
        !            31: #include "optable.h"
        !            32: 
        !            33: #include "drwatson.h"
        !            34: #include "proto.h"
        !            35: 
        !            36: void BlankFill(ULONG);
        !            37: void OutputHex(ULONG, ULONG, BOOLEAN);
        !            38: 
        !            39: void OutputEffectiveAddress(PDEBUGPACKET, ULONG);
        !            40: void OutputString(char *);
        !            41: void OutputReg(ULONG);
        !            42: void OutputFReg(ULONG);
        !            43: void GetNextOffset(PDEBUGPACKET, PULONG, BOOLEAN);
        !            44: 
        !            45: 
        !            46: ALPHA_INSTRUCTION disinstr;
        !            47: 
        !            48: extern PUCHAR pszReg[];
        !            49: 
        !            50: BOOLEAN disasm(PDEBUGPACKET, PDWORD, char *, BOOLEAN);
        !            51: 
        !            52: 
        !            53: static char *pBufStart;
        !            54: static char *pBuf;
        !            55: 
        !            56: 
        !            57: #define OPRNDCOL  27            // Column for first operand
        !            58: #define EACOL     40            // column for effective address
        !            59: #define FPTYPECOL 40            // .. for the type of FP instruction
        !            60: 
        !            61: 
        !            62: BOOLEAN
        !            63: disasm (PDEBUGPACKET dp, PDWORD poffset, char *bufptr, BOOLEAN fEAout)
        !            64: {
        !            65:     static      initialized = 0;
        !            66:     ULONG       opcode;
        !            67:     ULONG       Ea;                     // Effective Address
        !            68:     POPTBLENTRY pEntry;
        !            69:     LONG        displacement;
        !            70: 
        !            71:     if (!initialized) {
        !            72:         opTableInit();
        !            73:         initialized = 1;
        !            74:     }
        !            75:     pBufStart = pBuf = bufptr;          // Initialize pointers to buffer that
        !            76:                                         //  will receive the disassembly text
        !            77:     OutputHex(*poffset, 8, FALSE);// Output Hex address of instruction
        !            78:     *pBuf++ = ':';
        !            79:     *pBuf++ = ' ';
        !            80: 
        !            81:     if (!ReadProcessMemory (dp->hProcess,
        !            82:                            (LPVOID)*poffset,
        !            83:                            (LPVOID)&disinstr.Long,
        !            84:                            sizeof(DWORD),
        !            85:                            NULL
        !            86:                            )) {
        !            87:         OutputString("???????? ????");
        !            88:         *pBuf = '\0';
        !            89:         return(FALSE);
        !            90:     }
        !            91: 
        !            92:     OutputHex(disinstr.Long, 8, FALSE); // Output instruction in Hex
        !            93:     *pBuf++ = ' ';
        !            94: 
        !            95:     opcode = disinstr.Memory.Opcode;    // Select disassembly procedure from
        !            96: 
        !            97:     pEntry = findOpCodeEntry(opcode);   // Get non-func entry for this code
        !            98:     if (pEntry == (POPTBLENTRY)-1) {
        !            99:         OutputString("??????? ????");
        !           100:         *pBuf = '\0';
        !           101:         return (FALSE);
        !           102:     }
        !           103: 
        !           104: 
        !           105:     switch (pEntry->iType) {
        !           106:     case ALPHA_UNKNOWN:
        !           107:         OutputString(pEntry->pszAlphaName);
        !           108:         break;
        !           109: 
        !           110:     case ALPHA_MEMORY:
        !           111:         OutputString(pEntry->pszAlphaName);
        !           112:         BlankFill(OPRNDCOL);
        !           113:         OutputReg(disinstr.Memory.Ra);
        !           114:         *pBuf++ = ',';
        !           115:         OutputHex(disinstr.Memory.MemDisp, (WIDTH_MEM_DISP + 3)/4, TRUE );
        !           116:         *pBuf++ = '(';
        !           117:         OutputReg(disinstr.Memory.Rb);
        !           118:         *pBuf++ = ')';
        !           119: 
        !           120:         break;
        !           121: 
        !           122:     case ALPHA_FP_MEMORY:
        !           123:         OutputString(pEntry->pszAlphaName);
        !           124:         BlankFill(OPRNDCOL);
        !           125:         OutputFReg(disinstr.Memory.Ra);
        !           126:         *pBuf++ = ',';
        !           127:         OutputHex(disinstr.Memory.MemDisp, (WIDTH_MEM_DISP + 3)/4, TRUE );
        !           128:         *pBuf++ = '(';
        !           129:         OutputReg(disinstr.Memory.Rb);
        !           130:         *pBuf++ = ')';
        !           131: 
        !           132:         break;
        !           133: 
        !           134:     case ALPHA_MEMSPC:
        !           135:         OutputString(findFuncName(pEntry, disinstr.Memory.MemDisp & BITS_MEM_DISP));
        !           136:         //
        !           137:         // Some memory special instructions have an operand
        !           138:         //
        !           139: 
        !           140:         switch (disinstr.Memory.MemDisp & BITS_MEM_DISP) {
        !           141:         case FETCH_FUNC:
        !           142:         case FETCH_M_FUNC:
        !           143:              // one operand, in Rb
        !           144:              BlankFill(OPRNDCOL);
        !           145:              *pBuf++ = '0';
        !           146:              *pBuf++ = '(';
        !           147:              OutputReg(disinstr.Memory.Rb);
        !           148:              *pBuf++ = ')';
        !           149:              break;
        !           150: 
        !           151:         case RS_FUNC:
        !           152:         case RC_FUNC:
        !           153:         case RPCC_FUNC:
        !           154:              // one operand, in Ra
        !           155:              BlankFill(OPRNDCOL);
        !           156:              OutputReg(disinstr.Memory.Ra);
        !           157:              break;
        !           158: 
        !           159:         case MB_FUNC:
        !           160:         case WMB_FUNC:
        !           161:         case MB2_FUNC:
        !           162:         case MB3_FUNC:
        !           163:         case TRAPB_FUNC:
        !           164:         case EXCB_FUNC:
        !           165:              // no operands
        !           166:              break;
        !           167: 
        !           168:         default:
        !           169:              printf("we shouldn't get here \n");
        !           170:              break;
        !           171:         }
        !           172: 
        !           173:        break;
        !           174: 
        !           175: 
        !           176:     case ALPHA_JUMP:
        !           177:         OutputString(findFuncName(pEntry, disinstr.Jump.Function));
        !           178:         BlankFill(OPRNDCOL);
        !           179:         OutputReg(disinstr.Jump.Ra);
        !           180:         *pBuf++ = ',';
        !           181:         *pBuf++ = '(';
        !           182:         OutputReg(disinstr.Jump.Rb);
        !           183:         *pBuf++ = ')';
        !           184:         *pBuf++ = ',';
        !           185:         OutputHex(disinstr.Jump.Hint, (WIDTH_HINT + 3)/4, TRUE);
        !           186: 
        !           187:         Ea = GetRegValue(dp, GetIntRegNumber(disinstr.Jump.Rb)) & (~3);
        !           188:         OutputEffectiveAddress(dp, Ea);
        !           189:         break;
        !           190: 
        !           191:     case ALPHA_BRANCH:
        !           192:         OutputString(pEntry->pszAlphaName);
        !           193:         BlankFill(OPRNDCOL);
        !           194:         OutputReg(disinstr.Branch.Ra);
        !           195:         *pBuf++ = ',';
        !           196: 
        !           197:         //
        !           198:         // The next line might be a call to GetNextOffset, but
        !           199:         // GetNextOffset assumes that it should work from REGFIR.
        !           200:         //
        !           201: 
        !           202:         Ea = *poffset +
        !           203:              sizeof(DWORD) +
        !           204:              (disinstr.Branch.BranchDisp << 2);
        !           205:         OutputHex(Ea, 8, FALSE);
        !           206:         OutputEffectiveAddress(dp, Ea);
        !           207: 
        !           208:         break;
        !           209: 
        !           210:     case ALPHA_FP_BRANCH:
        !           211:         OutputString(pEntry->pszAlphaName);
        !           212:         BlankFill(OPRNDCOL);
        !           213:         OutputFReg(disinstr.Branch.Ra);
        !           214:         *pBuf++ = ',';
        !           215: 
        !           216:         //
        !           217:         // The next line might be a call to GetNextOffset, but
        !           218:         // GetNextOffset assumes that it should work from REGFIR.
        !           219:         //
        !           220: 
        !           221:         Ea = *poffset +
        !           222:              sizeof(DWORD) +
        !           223:              (disinstr.Branch.BranchDisp << 2);
        !           224:         OutputHex(Ea, 8, FALSE);
        !           225:         OutputEffectiveAddress(dp, Ea);
        !           226: 
        !           227:         break;
        !           228: 
        !           229:     case ALPHA_OPERATE:
        !           230:         OutputString(findFuncName(pEntry, disinstr.OpReg.Function));
        !           231:         BlankFill(OPRNDCOL);
        !           232:         OutputReg(disinstr.OpReg.Ra);
        !           233:         *pBuf++ = ',';
        !           234:         if (disinstr.OpReg.RbvType) {
        !           235:             *pBuf++ = '#';
        !           236:             OutputHex(disinstr.OpLit.Literal, (WIDTH_LIT + 3)/4, TRUE);
        !           237:         } else
        !           238:             OutputReg(disinstr.OpReg.Rb);
        !           239:         *pBuf++ = ',';
        !           240:         OutputReg(disinstr.OpReg.Rc);
        !           241:         break;
        !           242: 
        !           243:     case ALPHA_FP_OPERATE:
        !           244: 
        !           245:       {
        !           246:         ULONG Function;
        !           247:         ULONG Flags;
        !           248: 
        !           249:         Flags = disinstr.FpOp.Function & MSK_FP_FLAGS;
        !           250:         Function = disinstr.FpOp.Function & MSK_FP_OP;
        !           251: 
        !           252: //        if (fVerboseOutput) {
        !           253: //           dprintf("In FP_OPERATE: Flags %08x Function %08x\n",
        !           254: //                    Flags, Function);
        !           255: //           dprintf("opcode %d \n", opcode);
        !           256: //        }
        !           257: 
        !           258:         //
        !           259:         // CVTST and CVTST/S are different: they look like
        !           260:         // CVTTS with some flags set
        !           261:         //
        !           262:         if (Function == CVTTS_FUNC) { 
        !           263:             if (disinstr.FpOp.Function == CVTST_S_FUNC) {
        !           264:                 Function = CVTST_S_FUNC;
        !           265:                 Flags = NONE_FLAGS;
        !           266:             } 
        !           267:             if (disinstr.FpOp.Function == CVTST_FUNC) {
        !           268:                 Function = CVTST_FUNC;
        !           269:                 Flags = NONE_FLAGS;
        !           270:             } 
        !           271:         }
        !           272: 
        !           273:         OutputString(findFuncName(pEntry, Function));
        !           274: 
        !           275:         //
        !           276:         // Append the opcode qualifier, if any, to the opcode name.
        !           277:         //
        !           278: 
        !           279:         if ( (opcode == IEEEFP_OP) || (opcode == VAXFP_OP)
        !           280:                                    || (Function == CVTQL_FUNC) ) {
        !           281:             OutputString(findFlagName(Flags, Function));
        !           282:         }
        !           283: 
        !           284:         BlankFill(OPRNDCOL);
        !           285:         //
        !           286:         // If this is a convert instruction, only Rb and Rc are used
        !           287:         //
        !           288:         if (strncmp("cvt", findFuncName(pEntry, Function), 3) != 0) {
        !           289:             OutputFReg(disinstr.FpOp.Fa);
        !           290:             *pBuf++ = ',';
        !           291:         }
        !           292:         OutputFReg(disinstr.FpOp.Fb);
        !           293:         *pBuf++ = ',';
        !           294:         OutputFReg(disinstr.FpOp.Fc);
        !           295: 
        !           296:         break;
        !           297:       }
        !           298: 
        !           299:     case ALPHA_FP_CONVERT:
        !           300:         OutputString(pEntry->pszAlphaName);
        !           301:         BlankFill(OPRNDCOL);
        !           302:         OutputFReg(disinstr.FpOp.Fa);
        !           303:         *pBuf++ = ',';
        !           304:         OutputFReg(disinstr.FpOp.Fb);
        !           305:         break;
        !           306: 
        !           307:     case ALPHA_CALLPAL:
        !           308:         OutputString(findFuncName(pEntry, disinstr.Pal.Function));
        !           309:         break;
        !           310: 
        !           311:     case ALPHA_EV4_PR:
        !           312:         if ((disinstr.Long & MSK_EV4_PR) == 0)
        !           313:                 OutputString("NOP");
        !           314:         else {
        !           315:             OutputString(pEntry->pszAlphaName);
        !           316:             BlankFill(OPRNDCOL);
        !           317:             OutputReg(disinstr.EV4_PR.Ra);
        !           318:             *pBuf++ = ',';
        !           319:             if(disinstr.EV4_PR.Ra != disinstr.EV4_PR.Rb) {
        !           320:                 OutputReg(disinstr.EV4_PR.Rb);
        !           321:                 *pBuf++ = ',';
        !           322:             };
        !           323:             OutputString(findFuncName(pEntry, (disinstr.Long & MSK_EV4_PR)));
        !           324:         };
        !           325:         break;
        !           326:     case ALPHA_EV4_MEM:
        !           327:         OutputString(pEntry->pszAlphaName);
        !           328:         BlankFill(OPRNDCOL);
        !           329:         OutputReg(disinstr.EV4_MEM.Ra);
        !           330:         *pBuf++ = ',';
        !           331:         OutputReg(disinstr.EV4_MEM.Rb);
        !           332:         break;
        !           333:     case ALPHA_EV4_REI:
        !           334:         OutputString(pEntry->pszAlphaName);
        !           335:         break;
        !           336:     default:
        !           337:         OutputString("Invalid type");
        !           338:         break;
        !           339:     };
        !           340: 
        !           341: 
        !           342:     *poffset += sizeof(ULONG);
        !           343:     *pBuf = '\0';
        !           344:     return(TRUE);
        !           345: }
        !           346: 
        !           347: /* BlankFill - blank-fill buffer
        !           348: *
        !           349: *   Purpose:
        !           350: *       To fill the buffer at *pBuf with blanks until
        !           351: *       position count is reached.
        !           352: *
        !           353: *   Input:
        !           354: *       None.
        !           355: *
        !           356: *   Output:
        !           357: *       None.
        !           358: *
        !           359: ***********************************************************************/
        !           360: 
        !           361: void BlankFill(ULONG count)
        !           362: {
        !           363:     do
        !           364:         *pBuf++ = ' ';
        !           365:     while (pBuf < pBufStart + count);
        !           366: }
        !           367: 
        !           368: /* OutputHex - output hex value
        !           369: *
        !           370: *   Purpose:
        !           371: *       Output the value in outvalue into the buffer
        !           372: *       pointed by *pBuf.  The value may be signed
        !           373: *       or unsigned depending on the value fSigned.
        !           374: *
        !           375: *   Input:
        !           376: *       outvalue - value to output
        !           377: *       length - length in digits
        !           378: *       fSigned - TRUE if signed else FALSE
        !           379: *
        !           380: *   Output:
        !           381: *       None.
        !           382: *
        !           383: ***********************************************************************/
        !           384: 
        !           385: UCHAR HexDigit[16] = {
        !           386:     '0', '1', '2', '3', '4', '5', '6', '7',
        !           387:     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
        !           388:     };
        !           389: 
        !           390: void OutputHex (ULONG outvalue, ULONG length, BOOLEAN fSigned)
        !           391: {
        !           392:     UCHAR   digit[8];
        !           393:     LONG    index = 0;
        !           394: 
        !           395:     if (fSigned && (LONG)outvalue < 0) {
        !           396:         *pBuf++ = '-';
        !           397:         outvalue = - (LONG)outvalue;
        !           398:     }
        !           399:     do {
        !           400:         digit[index++] = HexDigit[outvalue & 0xf];
        !           401:         outvalue >>= 4;
        !           402:     }
        !           403: 
        !           404:     while ((fSigned && outvalue) || (!fSigned && index < (LONG)length))
        !           405:         ;
        !           406:     while (--index >= 0)
        !           407:         *pBuf++ = digit[index];
        !           408: }
        !           409: 
        !           410: /* OutputString - output string
        !           411: *
        !           412: *   Purpose:
        !           413: *       Copy the string into the buffer pointed by pBuf.
        !           414: *
        !           415: *   Input:
        !           416: *       *pStr - pointer to string
        !           417: *
        !           418: *   Output:
        !           419: *       None.
        !           420: *
        !           421: ***********************************************************************/
        !           422: 
        !           423: void OutputString (char *pStr)
        !           424: {
        !           425:     while (*pStr)
        !           426:         *pBuf++ = *pStr++;
        !           427: }
        !           428: 
        !           429: void OutputReg (ULONG regnum)
        !           430: {
        !           431:     OutputString(pszReg[GetIntRegNumber(regnum)]);
        !           432: }
        !           433: 
        !           434: void OutputFReg (ULONG regnum)
        !           435: {
        !           436:     *pBuf++ = 'f';
        !           437:     if (regnum > 9)
        !           438:         *pBuf++ = (UCHAR)('0' + regnum / 10);
        !           439:     *pBuf++ = (UCHAR)('0' + regnum % 10);
        !           440: }
        !           441: 
        !           442: 
        !           443: /*** OutputEffectiveAddress - Print EA symbolically
        !           444: *
        !           445: *   Purpose:
        !           446: *       Given the effective address (for a branch, jump or
        !           447: *       memory instruction, print it symbolically, if
        !           448: *       symbols are available.
        !           449: *
        !           450: *   Input:
        !           451: *       offset - computed by the caller as
        !           452: *               for jumps, the value in Rb
        !           453: *               for branches, func(PC, displacement)
        !           454: *               for memory, func(PC, displacement)
        !           455: *
        !           456: *   Returns:
        !           457: *       None
        !           458: *
        !           459: *************************************************************************/
        !           460: void OutputEffectiveAddress(PDEBUGPACKET dp, ULONG offset)
        !           461: {
        !           462:     ULONG   displacement;
        !           463:     PUCHAR  pszTemp;
        !           464:     UCHAR   ch;
        !           465: 
        !           466:     PSYMBOL sym;
        !           467: 
        !           468:     BlankFill(EACOL);
        !           469: 
        !           470:     sym = GetSymFromAddrAllContexts( offset, &displacement, dp);
        !           471: 
        !           472:     if (sym) {
        !           473:         pszTemp = UnDName( &sym->szName[1] );
        !           474:         while (ch = *pszTemp++)
        !           475:             *pBuf++ = ch;
        !           476:         if (displacement) {
        !           477:             *pBuf++ = '+';
        !           478:             OutputHex(displacement, 8, TRUE);
        !           479:             }
        !           480:     }
        !           481:     else {
        !           482:         OutputHex(offset, 8, FALSE);
        !           483:     }
        !           484: }
        !           485: 
        !           486: 
        !           487: /*** GetNextOffset - compute offset for trace or step
        !           488: *
        !           489: *   Purpose:
        !           490: *       From a limited disassembly of the instruction pointed
        !           491: *       by the FIR register, compute the offset of the next
        !           492: *       instruction for either a trace or step operation.
        !           493: *
        !           494: *       trace -> the next instruction to execute
        !           495: *       step -> the instruction in the next memory location or the
        !           496: *               next instruction executed due to a branch (step over
        !           497: *               subroutine calls).
        !           498: *
        !           499: *   Input:
        !           500: *       result - where to put the next offset
        !           501: *       fStep - TRUE for step offset; FALSE for trace offset
        !           502: *
        !           503: *   Returns:
        !           504: *       step or trace offset if input is TRUE or FALSE, respectively
        !           505: *       in result
        !           506: *
        !           507: *************************************************************************/
        !           508: /*
        !           509: void
        !           510: GetNextOffset (PDEBUGPACKET dp, PULONG result, BOOLEAN fStep)
        !           511: {
        !           512:     ULONG   rv;
        !           513:     ULONG   opcode;
        !           514:     ULONG   firaddr;
        !           515:     ULONG   updatedpc;
        !           516:     ULONG   branchTarget;
        !           517:     DWORD   fir;
        !           518: 
        !           519:     // Canonical form to shorten tests; Abs is absolute value
        !           520: 
        !           521:     LONG    Can, Abs;
        !           522: 
        !           523:     CONVERTED_DOUBLE    Rav;
        !           524:     CONVERTED_DOUBLE    Fav;
        !           525:     CONVERTED_DOUBLE    Rbv;
        !           526: 
        !           527:     //
        !           528:     // Get current address
        !           529:     //
        !           530: 
        !           531:     firaddr = GetRegValue(dp, REGFIR);
        !           532: 
        !           533:     //
        !           534:     // relative addressing updates PC first
        !           535:     // Assume next sequential instruction is next offset
        !           536:     //
        !           537: 
        !           538:     updatedpc = firaddr + sizeof(ULONG);
        !           539:     rv = updatedpc;
        !           540: 
        !           541:     ReadProcessMemory (dp->hProcess,
        !           542:                        (LPVOID)firaddr,
        !           543:                        (LPVOID)&disinstr.Long,
        !           544:                        sizeof(ULONG),
        !           545:                        NULL
        !           546:                        );
        !           547: 
        !           548:     opcode = disinstr.Memory.Opcode;
        !           549: 
        !           550:     switch(findOpCodeEntry(opcode)->iType) {
        !           551: 
        !           552:     case ALPHA_JUMP:
        !           553: 
        !           554:         switch(disinstr.Jump.Function) {
        !           555: 
        !           556:         case JSR_FUNC:
        !           557:         case JSR_CO_FUNC:
        !           558: 
        !           559:             if (fStep) {
        !           560: 
        !           561:                 //
        !           562:                 // Step over the subroutine call;
        !           563:                 //
        !           564: 
        !           565:                 break;
        !           566:             }
        !           567: 
        !           568:             //
        !           569:             // fall through
        !           570:             //
        !           571: 
        !           572:         case JMP_FUNC:
        !           573:         case RET_FUNC:
        !           574: 
        !           575:             GetQuadRegValue(dp, GetIntRegNumber(disinstr.Jump.Rb), &Rbv);
        !           576:             rv = (Rbv.li.LowPart & (~3));
        !           577:             break;
        !           578: 
        !           579:         }
        !           580: 
        !           581:         break;
        !           582: 
        !           583:         case ALPHA_BRANCH:
        !           584: 
        !           585:         branchTarget = (updatedpc + (disinstr.Branch.BranchDisp * 4));
        !           586: 
        !           587:         GetQuadRegValue(dp, GetIntRegNumber(disinstr.Branch.Ra), &Rav.li);
        !           588: 
        !           589:         //
        !           590:         // set up a canonical value for computing the branch test
        !           591:         // - works with ALPHA, MIPS and 386 hosts
        !           592:         //
        !           593: 
        !           594:         Can = Rav.li.LowPart & 1;
        !           595: 
        !           596:         if ((LONG)Rav.li.HighPart < 0) {
        !           597:             Can |= 0x80000000;
        !           598:         }
        !           599: 
        !           600:         if ((Rav.li.LowPart & 0xfffffffe) || (Rav.li.HighPart & 0x7fffffff)) {
        !           601:             Can |= 2;
        !           602:         }
        !           603: 
        !           604: //        if (fVerboseOutput) {
        !           605: //           dprintf("Rav High %08lx Low %08lx Canonical %08lx\n",
        !           606: //                    Rav.li.HighPart, Rav.li.LowPart, Can);
        !           607: //           dprintf("returnvalue %08lx branchTarget %08lx\n",
        !           608: //                    rv, branchTarget);
        !           609: //        }
        !           610: 
        !           611:         switch(opcode) {
        !           612:         case BR_OP:                         rv = branchTarget; break;
        !           613:         case BSR_OP:  if (!fStep)           rv = branchTarget; break;
        !           614:         case BEQ_OP:  if (Can == 0)         rv = branchTarget; break;
        !           615:         case BLT_OP:  if (Can <  0)         rv = branchTarget; break;
        !           616:         case BLE_OP:  if (Can <= 0)         rv = branchTarget; break;
        !           617:         case BNE_OP:  if (Can != 0)         rv = branchTarget; break;
        !           618:         case BGE_OP:  if (Can >= 0)         rv = branchTarget; break;
        !           619:         case BGT_OP:  if (Can >  0)         rv = branchTarget; break;
        !           620:         case BLBC_OP: if ((Can & 0x1) == 0) rv = branchTarget; break;
        !           621:         case BLBS_OP: if ((Can & 0x1) == 1) rv = branchTarget; break;
        !           622:         };
        !           623: 
        !           624:         break;
        !           625: 
        !           626: 
        !           627:     case ALPHA_FP_BRANCH:
        !           628: 
        !           629:         branchTarget = (updatedpc + (disinstr.Branch.BranchDisp * 4));
        !           630: 
        !           631:         GetFloatingPointRegValue(dp, disinstr.Branch.Ra, &Fav);
        !           632: 
        !           633:         //
        !           634:         // Set up a canonical value for computing the branch test
        !           635:         //
        !           636: 
        !           637:         Can = Fav.li.HighPart & 0x80000000;
        !           638: 
        !           639:         //
        !           640:         // The absolute value is needed -0 and non-zero computation
        !           641:         //
        !           642: 
        !           643:         Abs = Fav.li.LowPart || (Fav.li.HighPart & 0x7fffffff);
        !           644: 
        !           645:         if (Can && (Abs == 0x0)) {
        !           646: 
        !           647:             //
        !           648:             // negative 0 should be considered as zero
        !           649:             //
        !           650: 
        !           651:             Can = 0x0;
        !           652: 
        !           653:         } else {
        !           654: 
        !           655:             Can |= Abs;
        !           656: 
        !           657:         }
        !           658: 
        !           659: //        if (fVerboseOutput) {
        !           660: //           dprintf("Fav High %08lx Low %08lx Canonical %08lx Absolute %08lx\n",
        !           661: //                    Fav.li.HighPart, Fav.li.LowPart, Can, Abs);
        !           662: //           dprintf("returnvalue %08lx branchTarget %08lx\n",
        !           663: //                    rv, branchTarget);
        !           664: //        }
        !           665: 
        !           666:         switch(opcode) {
        !           667:         case FBEQ_OP: if (Can == 0)  rv =  branchTarget; break;
        !           668:         case FBLT_OP: if (Can <  0)  rv =  branchTarget; break;
        !           669:         case FBNE_OP: if (Can != 0)  rv =  branchTarget; break;
        !           670:         case FBLE_OP: if (Can <= 0)  rv =  branchTarget; break;
        !           671:         case FBGE_OP: if (Can >= 0)  rv =  branchTarget; break;
        !           672:         case FBGT_OP: if (Can >  0)  rv =  branchTarget; break;
        !           673:         };
        !           674: 
        !           675:         break;
        !           676:     };
        !           677: 
        !           678: //    if (fVerboseOutput) {
        !           679: //        dprintf("GetNextOffset returning %08lx\n", rv);
        !           680: //    }
        !           681: 
        !           682:     *result = rv;
        !           683: }
        !           684: 
        !           685: 
        !           686: */

unix.superglobalmegacorp.com

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