Annotation of cci/d/fpevent/chk_event.c, revision 1.1.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.