|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.