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