|
|
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.