Annotation of cci/d/fpevent/chk_event.c, revision 1.1

1.1     ! root        1: #include "evt_defs.h"
        !             2: 
        !             3: /*
        !             4:  ********************************************************************
        !             5:  *
        !             6:  *     Check the Results of a Floating Point Event
        !             7:  *
        !             8:  * This code will verify the following:
        !             9:  *   - the PSL saved after the event
        !            10:  *   - the # of operands pushed during the event.
        !            11:  *   - the PSL pushed on the stack
        !            12:  *   - the register values
        !            13:  *   - the final accumulator value
        !            14:  *
        !            15:  * If it was an FPP Emulation (FPM) Trap then this code will verify
        !            16:  *   - the data pushed onto the stack by the trap 
        !            17:  *   - the PSL saved after the event
        !            18:  *   - the register values 
        !            19:  *   - the final accumulator value
        !            20:  *
        !            21:  *  17-Jul-85 : added the FPM checks
        !            22:  *  26-Jul-85 : don't check stack's PSL w/ no-fpp. The no-fpp firmware may
        !            23:  *              update the PSL before pushing it. 
        !            24:  ********************************************************************
        !            25: */
        !            26: chk_event()
        !            27: {
        !            28:        error = FALSE;
        !            29:        if( test_event == FPM_CODE ) {     /* FPP EMULATION TRAP */
        !            30:             chk_fpm_trap();                    /* check FPM trap data    */
        !            31:             if( !error )
        !            32:                  chk_final_acc();              /* check final Acc value  */
        !            33:             if( !error )
        !            34:                  chk_final_psl();              /* check final PSL value  */
        !            35:             if( !error )
        !            36:                  chk_registers();              /* check final REG values */
        !            37:        } else {                           /* other event type */
        !            38:             chk_final_psl();                   /* check final PSL value  */
        !            39:             if( !error )
        !            40:                  chk_push_cnt();               /* check # ops pushed     */
        !            41:             if( (!error) && (!no_fpp_wcs) )
        !            42:                  chk_stack_psl();              /* check PSL on the stack */
        !            43:             if( !error )
        !            44:                  chk_registers();              /* check final REG values */
        !            45:             if( !error )
        !            46:                  chk_final_acc();              /* check final Acc value  */
        !            47:        }
        !            48:  }
        !            49: 
        !            50: 
        !            51: 
        !            52: 
        !            53: 
        !            54: /*
        !            55:  ***************************************************************************
        !            56:  *
        !            57:  *     Check the final PSL value
        !            58:  *
        !            59:  ***************************************************************************
        !            60: */
        !            61: chk_final_psl()
        !            62: {
        !            63:        if( bad_final_psl() ) {
        !            64:             error = TRUE;
        !            65:             errcnt++;
        !            66:             if( prt_error ) {
        !            67:                   prt_evt_er_msg( bad_psl_msg );
        !            68:                  writes("final PSL = ");
        !            69:                  write32h( psl_val );
        !            70:                  writes(",   expected PSL = ");
        !            71:                  write32h( exp_psl );
        !            72:                  writec('\n');
        !            73:              }
        !            74:             if( halt_flg )
        !            75:                  event_halt( BAD_PSL_HLT );    /* halt on the error */
        !            76:             if( loop_on_err )
        !            77:                  force_loop = TRUE;            /* set loop flag */
        !            78:        }
        !            79: }
        !            80: 
        !            81: 
        !            82: 
        !            83: /*
        !            84:  ***************************************************************************
        !            85:  *
        !            86:  *     Is the final PSL correct?
        !            87:  *
        !            88:  *   2-May-85   -stopped looking for 'V' set if the event was enabled.
        !            89:  *
        !            90:  ***************************************************************************
        !            91: */
        !            92: bad_final_psl()
        !            93: {
        !            94:        exp_psl = psl_val;
        !            95:        if( (test_event == ARITH_CODE) &&    /* the PSL overflow bit should */
        !            96:            (exp_code == INT_OVFL_CODE) &&   /* be set for int. overflow's  */
        !            97:            ( evt_disabled ) )               /* when the event is disabled  */
        !            98:             exp_psl |= PSL_V;          /* expect the INTEGER OVERFLOW set  */
        !            99:        else
        !           100:             exp_psl &= ~PSL_V;         /* expect INTEGER OVERFLOW reset    */
        !           101:        if( psl_val == exp_psl )
        !           102:             return( FALSE );
        !           103:        else 
        !           104:             return( TRUE );
        !           105: }
        !           106: 
        !           107: 
        !           108: 
        !           109: 
        !           110: /*
        !           111:  ***************************************************************************
        !           112:  *
        !           113:  *     Check the # of operands pushed onto the stack
        !           114:  *
        !           115:  ***************************************************************************
        !           116: */
        !           117: chk_push_cnt()
        !           118: {
        !           119:         if( bad_push_count() ) {
        !           120:             error = TRUE;
        !           121:             errcnt++;
        !           122:             if( prt_error ) {
        !           123:                  prt_evt_er_msg( push_cnt_msg );
        !           124:                  writed( push_cnt );
        !           125:                  writes(" longwords pushed,   ");
        !           126:                  writed( exp_push_cnt );
        !           127:                  writes(" longwords expected\n");
        !           128:             }
        !           129:             if( halt_flg )
        !           130:                  event_halt( PUSH_CNT_HLT );   /* halt on the error */
        !           131:             if( loop_on_err )
        !           132:                  force_loop = TRUE;            /* set loop flag */
        !           133:        }
        !           134: }
        !           135: 
        !           136: 
        !           137: 
        !           138: /*
        !           139:  ***************************************************************************
        !           140:  *
        !           141:  *     Were the right number of longwords pushed onto the stack?
        !           142:  *
        !           143:  * Get the number of longwords pushed by the change in stack pointer.
        !           144:  * The only special case is with CMPF2: If the addressing mode is POP
        !           145:  * and a Reserved Operand fault happens with the 2nd operand then the
        !           146:  * CMPF2 will pop 2 operands and then the fault will push 2.
        !           147:  ***************************************************************************
        !           148: */
        !           149: bad_push_count()
        !           150: {
        !           151:        push_cnt =  (int) pre_event_sp - (int) post_event_sp;
        !           152:        push_cnt /= 4;                  /* get # longwords pushed */
        !           153:        if( test_event == ARITH_CODE )
        !           154:             exp_push_cnt = 3;  /* ARITHMETIC faults push 3 longwords */
        !           155:         else if( test_event == RESOP_CODE ) {
        !           156:             if( (op_code == CMPF2_OP_CODE) &&
        !           157:                 ( (addr_code == 0x8e) || (addr_code == 0x9e) ) &&
        !           158:                 ( (dbl_value_1.m & 0xff800000) != 0x80000000 ) )
        !           159:                exp_push_cnt = 0;       /* special case with POPs */
        !           160:             else
        !           161:                exp_push_cnt = 2;       /* reserved ops push 2 longwords */
        !           162:        } else
        !           163:             exp_push_cnt = 2;
        !           164:        if( push_cnt != exp_push_cnt )
        !           165:             return( TRUE );
        !           166:        else
        !           167:             return( FALSE );
        !           168: }
        !           169: 
        !           170: 
        !           171: 
        !           172: 
        !           173: /*
        !           174:  ***************************************************************************
        !           175:  *
        !           176:  *     Check the PSL pushed onto the stack
        !           177:  *
        !           178:  *  22-Jul-85 : don't worry about the N or Z bits in the PSL. The interrupt
        !           179:  *              handler can store a Zero and update the status.
        !           180:  *  23-Jul-85 : don't expect the DBL bit set after a CVDF instruction.
        !           181:  ***************************************************************************
        !           182: */
        !           183: chk_stack_psl()
        !           184: {
        !           185: int mask;
        !           186:         if( op_code == CVDF_OP_CODE )
        !           187:             mask = 0xffffff73;                 /* don't look at the DBL bit */
        !           188:         else
        !           189:             mask = 0xfffffff3;                 /* look at the DBL bit */
        !           190:         if( (event_psl & mask) != (init_psl & mask) ) { 
        !           191:             error = TRUE;
        !           192:             errcnt++;
        !           193:             if( prt_error ) {
        !           194:                  prt_evt_er_msg( psl_pushed_msg );
        !           195:                  writes("PSL on stack = ");
        !           196:                  write32h( event_psl );
        !           197:                  writes(",  expected = ");
        !           198:                  write32h( init_psl );
        !           199:                  writec('\n');
        !           200:             }
        !           201:             if( halt_flg )
        !           202:                  event_halt( PUSH_PSL_HLT );   /* halt on the error */
        !           203:             if( loop_on_err )
        !           204:                  force_loop = TRUE;            /* set loop flag */
        !           205:        }
        !           206: }
        !           207: 
        !           208: 
        !           209: 
        !           210: /*
        !           211:  ***************************************************************************
        !           212:  *
        !           213:  *     Check the final register values
        !           214:  *
        !           215:  *  23-Jul-85 : If we are running MULL2 or MULL3 with register addressing 
        !           216:  *              then don't check the final operand's register. 
        !           217:  ***************************************************************************
        !           218: */
        !           219: chk_registers()
        !           220: {
        !           221:         if( (op_code == MULL2_OP_CODE) && (addr_mode == ADR_REG) ) {
        !           222:              reg_no = addr_code2 & 0xf;        /* get operand 2's reg # */
        !           223:              exp_regs[reg_no] = store_regs[reg_no];
        !           224:         }
        !           225:         if( (op_code == MULL3_OP_CODE) && (addr_mode == ADR_REG) ) {
        !           226:              reg_no = addr_code3 & 0xf;        /* get operand 3's reg # */
        !           227:              exp_regs[reg_no] = store_regs[reg_no];
        !           228:         }
        !           229:         reg_no = 0;                    /* check regs 0 - 12 */
        !           230:         regs_ok = TRUE;
        !           231:         while( (reg_no < 13) && (regs_ok) )  
        !           232:              if( store_regs[reg_no] == exp_regs[reg_no] )
        !           233:                   reg_no++;
        !           234:              else
        !           235:                   regs_ok = FALSE;
        !           236:         if( !regs_ok ) {
        !           237:              error = TRUE;
        !           238:              errcnt++;
        !           239:              if( prt_error ) {
        !           240:                   prt_evt_er_msg( reg_modified_msg );
        !           241:                   writes("Register ");
        !           242:                   writeh( reg_no );
        !           243:                   writes(" = ");
        !           244:                   write32h( store_regs[reg_no] );
        !           245:                   writes(",  expected = ");
        !           246:                   write32h( exp_regs[reg_no] );
        !           247:                   writec('\n');
        !           248:              }
        !           249:              if( halt_flg )
        !           250:                   event_halt( BAD_REG_HLT );   /* halt on the error */
        !           251:              if( loop_on_err )
        !           252:                   force_loop = TRUE;           /* set loop flag */
        !           253:        }
        !           254: }
        !           255: 
        !           256: 
        !           257: 
        !           258: 
        !           259: /*
        !           260:  ***************************************************************************
        !           261:  *
        !           262:  *     Check the final Accumulator value
        !           263:  *
        !           264:  ***************************************************************************
        !           265: */
        !           266: chk_final_acc()
        !           267: {
        !           268:        if( acc_trashed() ) {
        !           269:             error = TRUE;
        !           270:             errcnt++;
        !           271:             if( prt_error ) {
        !           272:                  prt_evt_er_msg( bad_acc_msg );
        !           273:                  writes("    expected = ");
        !           274:                  write32h( dbl_expected.m );
        !           275:                  if( precision == DBL ) {
        !           276:                       writec(' ');
        !           277:                       write32h( dbl_expected.l );
        !           278:                  }
        !           279:                  writec('\n');
        !           280:             }
        !           281:             if( halt_flg ) {
        !           282:                  if( test_event == FPM_CODE )
        !           283:                       fpm_halt( BAD_ACC_HLT );         /* use the FPM halt */
        !           284:                  else
        !           285:                       event_halt( BAD_ACC_HLT );       /* use normal halt */
        !           286:             } 
        !           287:             if( loop_on_err )
        !           288:                  force_loop = TRUE;                    /* set loop flag */
        !           289:        } 
        !           290: }
        !           291: 
        !           292: 
        !           293: 
        !           294: /*
        !           295:  ***************************************************************************
        !           296:  *
        !           297:  *     Check to see if the accumulator has the correct value in it
        !           298:  *
        !           299:  * The final accumulator should either be the original value loaded or '0'.
        !           300:  *
        !           301:  * Bad 0's are numbers with a exponent of zero and a non-zero fraction. These
        !           302:  * are any hex number between 00000001 and 007fffff. Bad 0's are changed to
        !           303:  * good 0's by the store instruction unless we are using the "no-fpp" WCS
        !           304:  * and the most significant longword of a double precision accumulator isn't
        !           305:  * all 0's. If the most significant longword of the accumulator is '0' then 
        !           306:  * the least significant longword will get cleared anyway. (I didn't write 
        !           307:  * the micro-code folks - I just test it).
        !           308:  *
        !           309:  * The accumulator will be cleared to '0' by the firmware if there is
        !           310:  * a floating Underflow fault, if there is a floating Overflow fault, or 
        !           311:  * if there is a floating Reserved Operand fault (except for the compare
        !           312:  * instructions -CMPF, CMPF2, CMPD, CMPD2). If we are using the "no-fpp" WCS 
        !           313:  * then the accumulator will not be changed for any Reserved Operands.
        !           314:  *
        !           315:  * The accumulator should not be changed by either the Integer Overflow or
        !           316:  * the Divide By Zero faults.
        !           317:  *
        !           318:  * SUMMARY: the final accumulator will be zero if:
        !           319:  *   A: the most significant accumulator longword is '0'.
        !           320:  *   B: the accumulator's exponent was zero AND either:
        !           321:  *      b1: the accumulator is single precision OR 
        !           322:  *      b2: we're using the FPP WCS
        !           323:  *   C: We are using the fpp-hardware wcs  AND either:
        !           324:  *     c1: the event was either floating Overflow or floating Underflow  OR
        !           325:  *     c2: the event was Reserved Operand and the instruction was not 
        !           326:  *          one of the 'compare' instructions.
        !           327:  *
        !           328:  ***************************************************************************
        !           329: */
        !           330: acc_trashed()
        !           331: {
        !           332: int clear_acc;
        !           333:        clear_acc = FALSE;                      /* initialize the clear flag */
        !           334:        if( !dbl_ld_acc.m )                             /* case A: */
        !           335:             clear_acc = TRUE;  
        !           336:        else
        !           337:         if( (!(dbl_ld_acc.m & 0x7f800000)) &&          /* case B: */
        !           338:             ( (precision == SGL) || (!no_fpp_wcs)) )   /* case b1, b2 */
        !           339:             clear_acc = TRUE;  
        !           340:        else
        !           341:         if( (!no_fpp_wcs) &&                           /* case C: */
        !           342:             ( ( (test_event == ARITH_CODE) &&          /* case c1 */
        !           343:                 ( (exp_code == FLT_OVFL_CODE) ||
        !           344:                   (exp_code == FLT_UNDFL_CODE) ) ) ||
        !           345:               ( (test_event == RESOP_CODE) &&          /* case c2 */
        !           346:                 ( (op_code != CMPF_OP_CODE)  &&        
        !           347:                   (op_code != CMPF2_OP_CODE) &&
        !           348:                   (op_code != CMPD_OP_CODE)  &&
        !           349:                   (op_code != CMPD2_OP_CODE) ) ) ) )
        !           350:             clear_acc = TRUE;  
        !           351:        if( clear_acc ) {
        !           352:             dbl_expected.m = 0;                /* the Acc. s/b cleared */
        !           353:             dbl_expected.l = 0;
        !           354:        } else {
        !           355:             dbl_expected.m = dbl_ld_acc.m;     /* the Acc. s/b unchanged */
        !           356:             dbl_expected.l = dbl_ld_acc.l;
        !           357:        }
        !           358:        if( (dbl_expected.m != dbl_st_acc.m) || 
        !           359:            ( (precision == DBL) && (dbl_expected.l != dbl_st_acc.l) ) )
        !           360:             return( TRUE );
        !           361:        else
        !           362:             return( FALSE );   
        !           363: }
        !           364: 
        !           365: 
        !           366: 
        !           367: /*
        !           368:  ***************************************************************************
        !           369:  *
        !           370:  *     Check the results of an FPP Emulation Trap.
        !           371:  *
        !           372:  *  Check the stack data, the final accumulator, and the registers. The data
        !           373:  *  was saved by the FPM trap handler.
        !           374:  *  The stack data is:
        !           375:  *   - the PSL
        !           376:  *   - the PC of the next instruction
        !           377:  *   - the op-code
        !           378:  *   - the operand's LS longword  { for double precision instructions }
        !           379:  *   - the operand's MS longword
        !           380:  *
        !           381:  ***************************************************************************
        !           382: */
        !           383: chk_fpm_trap()
        !           384: {
        !           385:        exp_pc = code_addr + inst_size;         /* expected PC on stack */
        !           386: /*
        !           387:  * check the FPM variables pushed onto the stack
        !           388: */
        !           389:        if( !no_ops )                           /* if no operands then    */
        !           390:            dbl_value_1.m = fpm_ms_op;          /*   expect whatever was  */
        !           391:            dbl_value_1.l = fpm_ls_op;          /*     put on the stack   */
        !           392:        if( precision != DBL )                  /* if single operand then */
        !           393:            dbl_value_1.l = fpm_ls_op;          /*   no LS op. errors     */
        !           394:        if((fpm_ms_op != dbl_value_1.m) ||      /* check stack's MS op   */
        !           395:           (fpm_ls_op != dbl_value_1.l) ||      /* check stack's LS op   */
        !           396:           (fpm_op_code != op_code) ||          /* check stack's op-code */
        !           397:           (fpm_pc != exp_pc) ||                /* check stack's PC      */
        !           398:           (fpm_psl != init_psl) ) {            /* check stack's PSL     */
        !           399:             error = TRUE;
        !           400:             errcnt++;
        !           401:             if( prt_error ) {
        !           402:                   prt_evt_er_msg( bad_fpm_stack_msg );
        !           403:                  writes("  data on the stack       expected\n");
        !           404:                  writes("  MS operand = ");
        !           405:                  write32h( fpm_ms_op );                /* MS operand */
        !           406:                  writes(",  ");
        !           407:                  write32h( dbl_value_1.m );
        !           408:                  writes("\n  LS operand = ");
        !           409:                  write32h( fpm_ls_op );                /* LS operand */
        !           410:                  writes(",  ");
        !           411:                  write32h( dbl_value_1.l );
        !           412:                  writes("\n     op-code = ");
        !           413:                  write32h( fpm_op_code );              /* op-code */
        !           414:                  writes(",  ");
        !           415:                  write32h( op_code );
        !           416:                  writes("\n         PC  = ");
        !           417:                  write32h( fpm_pc );                   /* PC */
        !           418:                  writes(",  ");
        !           419:                  write32h( exp_pc );
        !           420:                  writes("\n         PSL = ");
        !           421:                  write32h( fpm_psl );                  /* PSL */
        !           422:                  writes(",  ");
        !           423:                  write32h( init_psl );
        !           424:                  writec('\n');
        !           425:              }
        !           426:             if( halt_flg ) 
        !           427:                  fpm_halt( BAD_FPM_STK_HLT );  /* halt on the error */
        !           428:             if( loop_on_err )
        !           429:                  force_loop = TRUE;            /* set loop flag */
        !           430:        }
        !           431: }

unix.superglobalmegacorp.com

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