|
|
1.1 root 1:
2: #include "dmp_defs.h"
3:
4: /**************************************************************************
5: *
6: * Test the current instruction
7: *
8: * If the current instruction accesses any operands, then test it with
9: * all major applicable addressing modes.
10: *
11: * NOTE: Pipline tests 3 & 4 are not run with the "no-fpp" firmware because
12: * the ADDs would cause traps. They are not run with certain "load
13: * type instructions because of a hardware restriction (an ADDF
14: * followed by an LDF will cause a floating overflow event).
15: *
16: * 30-Apr-85 added pipelined instruction tests
17: * 17-May-85 don't run pre-piped stuff w/ LDF, LNF (ovfl errors)
18: * 21-Jun-85 added 3rd operand for MULL3
19: **************************************************************************/
20: test_inst()
21: {
22: /*
23: * Set the values for the indirect pointers
24: */
25: *adr_op1_ptr = (int) adr_op1; /* set word offset ptr #1 */
26: *adr_op2_ptr = (int) adr_op2; /* set word offset ptr #2 */
27: *adr_op3_ptr = (int) adr_op3; /* set word offset ptr #3 */
28: error = FALSE; /* clear the error flag */
29: set_load_flag(); /* set/reset load Acc flag */
30: if( !no_ops )
31: test_0_ops(); /* test inst w/ no operands */
32: else {
33: tst_abs(); /* absolute addressing */
34: if( s_to_d ||
35: ( (precision == SGL) && (op_type == LOAD) ) )
36: tst_i_l(); /* immediate longword */
37: tst_b(); /* byte displacement relative */
38: tst_w(); /* word displacement relative */
39: tst_l(); /* longword displacement relative */
40: tst_b_d(); /* byte disp. relative deferred */
41: tst_w_d(); /* word disp. relative deferred */
42: tst_l_d(); /* longword disp. rel. deferred */
43: tst_r(); /* direct register */
44: tst_r_d(); /* register deferred */
45: if( user_mode ) { /* do stack stuff in user mode only */
46: if( (op_code == MULL2_OP_CODE) ||
47: (op_code == MULL3_OP_CODE) ) {
48: tst_mull_stack(); /* POP, POP, PUSH */
49: tst_pop_d(); /* deferred POP */
50: }
51: else if( d_to_s ||
52: ( (precision == SGL) && (op_type == STORE) ) ) {
53: tst_push(); /* PUSH ( auto-decremented SP ) */
54: tst_pop_d(); /* deferred POP */
55: }
56: else if( s_to_d ||
57: ( (precision == SGL) && (op_type == LOAD) ) ) {
58: tst_pop(); /* POP ( auto-incremented SP ) */
59: tst_pop_d(); /* deferred POP */
60: }
61: }
62: tst_r_b(); /* register + byte displacement */
63: tst_r_w(); /* register + word displacement */
64: tst_r_l(); /* register + longword disp. */
65: tst_r_bd(); /* reg. + byte disp. deferred */
66: tst_r_wd(); /* reg. + word disp. deferred */
67: tst_r_ld(); /* reg. + longword disp. deferred */
68: tst_x_fpd(); /* FP deferred + longword index */
69: tst_x_l(); /* longword disp. + longword index */
70: if( !no_fpp_wcs ) {
71: tst_p1(); /* pipe 1 - load w/ register data */
72: tst_p2(); /* pipe 2 - load w/ lw addressing */
73: if( ( op_code != LDF_OP_CODE ) &&
74: ( op_code != LNF_OP_CODE ) &&
75: ( op_code != CVLF_OP_CODE ) ) {
76: tst_p3(); /* pipe 3 - mulx w/ register data */
77: tst_p4(); /* pipe 4 - mulx w/ lw addressing */
78: }
79: } /* end IF not no-fpp */
80: } /* end IF one or more operands */
81: }
82:
83:
84:
85:
86:
87: /*******************************************************************
88: * ABSOLUTE ADDRESSING:
89: * instr = <op-code> <9f> <&dmp_op_1> {<9f> <&dmp_op_2> <9f> <&dmp_op_3>}
90: *******************************************************************/
91: tst_abs()
92: {
93: pipe_test = FALSE; /* clear the pipe test flag */
94: fill_reg_buf( load_regs ); /* set data for registers */
95: fill_reg_buf( exp_regs ); /* set data for registers */
96: addr_mode = ADR_ABSOLUTE;
97: addr_code = addr_code2 = addr_code3 = 0x9f;
98: addr_size = 4; /* longword (4 byte) ops. */
99: addr_1 = DMP_OP_1; /* abs. address of data */
100: addr_2 = DMP_OP_2;
101: addr_3 = DMP_OP_3;
102: if( no_ops == 1 )
103: min_shift = 15;
104: else if( no_ops == 2 )
105: min_shift = 10;
106: else
107: min_shift = 5;
108: shift_count = 19;
109: for( index = 0; index <= max_index; index++ ) {
110: get_current_data( adr_op1, adr_op2 );
111: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault cnt */
112: pack_inst(); /* pack the instr. code */
113: run_code(); /* execute the instruction */
114: if( --shift_count < min_shift )
115: shift_count = 19;
116: }
117: }
118:
119:
120:
121:
122:
123: /*******************************************************************
124: * IMMEDIATE LONGWORD ADDRESSING: ( sgl and sgl_to_dbl only )
125: * instr = <op-code> <8f> <data> { <8f> <data> <8f> <data> }
126: *
127: * NOTE: If the instruction is MULL2, op #2 will use absolute addressing.
128: * If the instruction is MULL3, op #3 will use absolute addressing.
129: *******************************************************************/
130: tst_i_l()
131: {
132: pipe_test = FALSE; /* clear the pipe test flag */
133: fill_reg_buf( load_regs ); /* set data for registers */
134: fill_reg_buf( exp_regs ); /* set data for registers */
135: addr_mode = ADR_IM_L;
136: addr_code = addr_code2 = 0x8f;
137: addr_code3 = 0x9f; /* MULL3 uses ABS for op #3 */
138: addr_3 = DMP_OP_3; /* addr_3 points to DMP_OP3 */
139: if( op_code == MULL2_OP_CODE ) {
140: addr_code2 = 0x9f; /* MULL2 uses ABS for op #2 */
141: addr_2 = DMP_OP_2; /* addr_2 points to DMP_OP2 */
142: }
143: addr_size = 4; /* longword (4 byte) data */
144: if( (op_code == MULL2_OP_CODE) || (op_code == MULL3_OP_CODE) )
145: exp_page_faults = 3; /* 3 pages are used */
146: else
147: exp_page_faults = 2; /* 2 pages are used */
148: shift_count = 19;
149: for( index = 0; index <= max_index; index++ ) {
150: get_current_data( adr_op1, adr_op2 );
151: addr_1 = dbl_value_1.m; /* set the 1st operand */
152: if( op_code != MULL2_OP_CODE )
153: addr_2 = dbl_value_2.m; /* set the 2nd operand */
154: pack_inst(); /* pack the instr. code */
155: run_code(); /* execute the instruction */
156: if( --shift_count < min_shift )
157: shift_count = 19;
158: }
159: }
160:
161:
162:
163: /*******************************************************************
164: * BYTE DISPLACEMENT RELATIVE ADDRESSING:
165: * instr = <op-code> <af> <offset to dmp_byte_op_1>
166: * { <af> <offset to dmp_byte_op_2> }
167: * { <af> <offset to dmp_byte_op_3> }
168: *******************************************************************/
169: tst_b()
170: {
171: pipe_test = FALSE; /* clear the pipe test flag */
172: fill_reg_buf( load_regs ); /* set data for registers */
173: fill_reg_buf( exp_regs ); /* set data for registers */
174: addr_mode = ADR_B_DSP;
175: addr_code = addr_code2 = addr_code3 = 0xaf;
176: addr_size = 1; /* 1 byte operand */
177: exp_page_faults = 2; /* 2 pages are used */
178: if( no_ops == 1 )
179: min_shift = 17;
180: else if( no_ops == 2 )
181: min_shift = 15;
182: else
183: min_shift = 13;
184: shift_count = 19;
185: for( index = 0; index <= max_index; index++ ) {
186: get_current_data( adr_b_op1, adr_b_op2 );
187: addr_1 = os_b_op1 + 17 - shift_count; /* data's offset */
188: addr_2 = os_b_op2 + 15 - shift_count;
189: addr_3 = os_b_op3 + 13 - shift_count;
190: pack_inst(); /* pack the instr. code */
191: run_code(); /* execute the instruction */
192: if( --shift_count < min_shift )
193: shift_count = 19;
194: }
195: }
196:
197:
198:
199: /*******************************************************************
200: * WORD DISPLACEMENT RELATIVE ADDRESSING:
201: * instruction = <op-code> <cf> <offset to dmp_op_1>
202: * { <cf> <offset to dmp_op_2> }
203: * { <cf> <offset to dmp_op_3> }
204: *******************************************************************/
205: tst_w()
206: {
207: pipe_test = FALSE; /* clear the pipe test flag */
208: fill_reg_buf( load_regs ); /* set data for registers */
209: fill_reg_buf( exp_regs ); /* set data for registers */
210: addr_mode = ADR_W_DSP;
211: addr_code = addr_code2 = addr_code3 = 0xcf;
212: addr_size = 2; /* word (2 byte) operand */
213: if( no_ops == 1 )
214: min_shift = 17;
215: else if( no_ops == 2 )
216: min_shift = 14;
217: else
218: min_shift = 11;
219: shift_count = 19;
220: for( index = 0; index <= max_index; index++ ) {
221: get_current_data( adr_op1, adr_op2 );
222: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault cnt */
223: addr_1 = os_op1 + 16 - shift_count; /* data's offset */
224: addr_2 = os_op2 + 13 - shift_count;
225: addr_3 = os_op3 + 10 - shift_count;
226: pack_inst(); /* pack the instr. code */
227: run_code(); /* execute the instruction */
228: if( --shift_count < min_shift )
229: shift_count = 19;
230: }
231: }
232:
233:
234:
235: /*******************************************************************
236: * LONGWORD DISPLACEMENT RELATIVE ADDRESSING:
237: * instruction = <op-code> <ef> <offset to dmp_op_1>
238: * { <ef> <offset to dmp_op_2> }
239: * { <ef> <offset to dmp_op_3> }
240: *******************************************************************/
241: tst_l()
242: {
243: pipe_test = FALSE; /* clear the pipe test flag */
244: fill_reg_buf( load_regs ); /* set data for registers */
245: fill_reg_buf( exp_regs ); /* set data for registers */
246: addr_mode = ADR_L_DSP;
247: addr_code = addr_code2 = addr_code3 = 0xef;
248: addr_size = 4; /* longword (4 byte) ops. */
249: if( no_ops == 1 )
250: min_shift = 15;
251: else if( no_ops == 2 )
252: min_shift = 10;
253: else
254: min_shift = 5;
255: shift_count = 19;
256: for( index = 0; index <= max_index; index++ ) {
257: get_current_data( adr_op1, adr_op2 );
258: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
259: addr_1 = os_op1 + 14 - shift_count; /* data's offset */
260: addr_2 = os_op2 + 9 - shift_count;
261: addr_3 = os_op3 + 4 - shift_count;
262: pack_inst(); /* pack the instr. code */
263: run_code(); /* execute the instruction */
264: if( --shift_count < min_shift )
265: shift_count = 19;
266: }
267: }
268:
269:
270:
271: /*******************************************************************
272: * BYTE DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
273: * instruction = <op-code> <bf> <offset to dmp_byte_op_1>
274: * { <bf> <offset to dmp_byte_op_2> }
275: * { <bf> <offset to dmp_byte_op_3> }
276: *******************************************************************/
277: tst_b_d()
278: {
279: pipe_test = FALSE; /* clear the pipe test flag */
280: fill_reg_buf( load_regs ); /* set data for registers */
281: fill_reg_buf( exp_regs ); /* set data for registers */
282: addr_mode = ADR_B_DSP_DEF;
283: addr_code = addr_code2 = addr_code3 = 0xbf;
284: addr_size = 1; /* 1 byte operand */
285: adr_b_op1->m = (int) adr_op1; /* set byte offset ptr #1 */
286: adr_b_op2->m = (int) adr_op2; /* set byte offset ptr #2 */
287: adr_b_op3->m = (int) adr_op3; /* set byte offset ptr #3 */
288: if( no_ops == 1 )
289: min_shift = 17;
290: else if( no_ops == 2 )
291: min_shift = 15;
292: else
293: min_shift = 13;
294: shift_count = 19;
295: for( index = 0; index <= max_index; index++ ) {
296: get_current_data( adr_op1, adr_op2 );
297: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
298: addr_1 = os_b_op1 + 17 - shift_count; /* data's offset */
299: addr_2 = os_b_op2 + 15 - shift_count;
300: addr_3 = os_b_op3 + 13 - shift_count;
301: pack_inst(); /* pack the instr. code */
302: run_code(); /* execute the instruction */
303: if( --shift_count < min_shift )
304: shift_count = 19;
305: }
306: }
307:
308:
309:
310:
311: /*******************************************************************
312: * WORD DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
313: * instruction = <op-code> <df> <offset to dmp_op_1_ptr>
314: * { <df> <offset to dmp_op_2_ptr> }
315: * { <df> <offset to dmp_op_3_ptr> }
316: *******************************************************************/
317: tst_w_d()
318: {
319: pipe_test = FALSE; /* clear the pipe test flag */
320: fill_reg_buf( load_regs ); /* set data for registers */
321: fill_reg_buf( exp_regs ); /* set data for registers */
322: addr_mode = ADR_W_DSP_DEF;
323: addr_code = addr_code2 = addr_code3 = 0xdf;
324: addr_size = 2; /* word (2 byte) operand */
325: if( no_ops == 1 )
326: min_shift = 17;
327: else if( no_ops == 2 )
328: min_shift = 14;
329: else
330: min_shift = 11;
331: shift_count = 19;
332: for( index = 0; index <= max_index; index++ ) {
333: get_current_data( adr_op1, adr_op2 );
334: get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
335: addr_1 = os_ad_op1 + 16 - shift_count; /* operand offset */
336: addr_2 = os_ad_op2 + 13 - shift_count;
337: addr_3 = os_ad_op3 + 10 - shift_count;
338: pack_inst(); /* pack the instr. code */
339: run_code(); /* execute the instruction */
340: if( --shift_count < min_shift )
341: shift_count = 19;
342: }
343: }
344:
345:
346:
347: /*******************************************************************
348: * LONGWORD DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
349: * instruction = <op-code> <ff> <offset to dmp_op_1_ptr>
350: * { <ff> <offset to dmp_op_2_ptr> }
351: * { <ff> <offset to dmp_op_3_ptr> }
352: *******************************************************************/
353: tst_l_d()
354: {
355: pipe_test = FALSE; /* clear the pipe test flag */
356: fill_reg_buf( load_regs ); /* set data for registers */
357: fill_reg_buf( exp_regs ); /* set data for registers */
358: addr_mode = ADR_L_DSP_DEF;
359: addr_code = addr_code2 = addr_code3 = 0xff;
360: addr_size = 4; /* longword (4 byte) op. */
361: if( no_ops == 1 )
362: min_shift = 15;
363: else if( no_ops == 2 )
364: min_shift = 10;
365: else
366: min_shift = 5;
367: shift_count = 19;
368: for( index = 0; index <= max_index; index++ ) {
369: get_current_data( adr_op1, adr_op2 );
370: get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
371: addr_1 = os_ad_op1 + 14 - shift_count; /* operand offset */
372: addr_2 = os_ad_op2 + 9 - shift_count;
373: addr_3 = os_ad_op3 + 4 - shift_count;
374: pack_inst(); /* pack the instr. code */
375: run_code(); /* execute the instruction */
376: if( --shift_count < min_shift )
377: shift_count = 19;
378: }
379: }
380:
381:
382:
383: /*******************************************************************
384: * DIRECT REGISTER ADDRESSING:
385: * instruction = <op-code> <50> { <54> } { <56> }
386: *
387: * If the instruction = MULL2 the store will be to R4,
388: * If the instruction = MULL3 the store will be to R6,
389: * If the instruction is any other store it will be to R0/R1.
390: *******************************************************************/
391: tst_r()
392: {
393: pipe_test = FALSE; /* clear the pipe test flag */
394: fill_reg_buf( load_regs ); /* set data for registers */
395: fill_reg_buf( exp_regs ); /* set data for registers */
396: addr_mode = ADR_REG;
397: addr_code = 0x50; /* 1st op in registers 0/1 */
398: addr_code2 = 0x54; /* 2nd op in registers 4/5 */
399: addr_code3 = 0x56; /* 3rd op in register 6 */
400: addr_size = 0; /* no addressing bytes */
401: pack_inst(); /* pack the instr. code */
402: exp_page_faults = 2; /* 2 pages are used */
403: if( no_ops == 1 )
404: min_shift = 19;
405: else if( no_ops == 2 )
406: min_shift = 18;
407: else
408: min_shift = 17;
409: shift_count = 19;
410: for( index = 0; index <= max_index; index++ ) {
411: get_current_data( adr_op1, adr_op2 );
412: load_regs[0] = dbl_value_1.m; /* set the data for the regs*/
413: load_regs[1] = dbl_value_1.l;
414: load_regs[4] = dbl_value_2.m;
415: load_regs[5] = dbl_value_2.l;
416: exp_regs[0] = load_regs[0]; /* set exp final reg values */
417: exp_regs[1] = load_regs[1];
418: exp_regs[4] = load_regs[4];
419: exp_regs[5] = load_regs[5];
420: if( op_code == MULL2_OP_CODE )
421: exp_regs[4] = dbl_expected.m;
422: else if( op_code == MULL3_OP_CODE )
423: exp_regs[6] = dbl_expected.m;
424: else if( op_type == STORE ) {
425: exp_regs[0] = dbl_expected.m;
426: exp_regs[1] = dbl_expected.l;
427: }
428: if( op_code == CVDL_OP_CODE ) /* correct for sgl store */
429: exp_regs[1] = dbl_value_1.l; /* r1 shouldn't change */
430: run_code(); /* execute the instruction */
431: if( --shift_count < min_shift )
432: shift_count = 19;
433: }
434: }
435:
436:
437:
438:
439: /*******************************************************************
440: * REGISTER DEFERRED ADDRESSING:
441: * instruction = <op-code> <60> { <61> <62> }
442: *******************************************************************/
443: tst_r_d()
444: {
445: pipe_test = FALSE; /* clear the pipe test flag */
446: fill_reg_buf( load_regs ); /* set data for registers */
447: fill_reg_buf( exp_regs ); /* set data for registers */
448: addr_mode = ADR_REG_DEF;
449: addr_code = 0x60;
450: addr_code2 = 0x61;
451: addr_code3 = 0x62;
452: addr_size = 0; /* no address byte(s) */
453: load_regs[0] = (int) adr_op1; /* get addr of op. 1 */
454: load_regs[1] = (int) adr_op2; /* get addr of op. 2 */
455: load_regs[2] = (int) adr_op3; /* get addr of op. 3 */
456: exp_regs[0] = load_regs[0];
457: exp_regs[1] = load_regs[1];
458: exp_regs[2] = load_regs[2];
459: pack_inst(); /* pack the instr. code */
460: if( no_ops == 1 )
461: min_shift = 19;
462: else if( no_ops == 2 )
463: min_shift = 18;
464: else
465: min_shift = 17;
466: shift_count = 19;
467: for( index = 0; index <= max_index; index++ ) {
468: get_current_data( adr_op1, adr_op2 );
469: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
470: run_code(); /* execute the instruction */
471: if( --shift_count < min_shift )
472: shift_count = 19;
473: }
474: }
475:
476:
477:
478:
479: /*******************************************************************
480: * AUTO-DECREMENTED STACK POINTER ADDRESSING ( PUSH ):
481: * instruction = <op-code> <7e>
482: *
483: * The final result will be popped by "run_code".
484: * Push will be run with SGL instructions only.
485: * "DBL_VALUE_4", the final result, will be set by RUN_CODE.
486: *******************************************************************/
487: tst_push()
488: {
489: pipe_test = FALSE; /* clear the pipe test flag */
490: fill_reg_buf( load_regs ); /* set data for registers */
491: fill_reg_buf( exp_regs ); /* set data for registers */
492: addr_mode = ADR_PUSH;
493: addr_code = 0x7e;
494: addr_size = 0; /* no addressing bytes */
495: exp_page_faults = 3; /* 3 pages are used */
496: shift_count = 19;
497: pack_inst(); /* pack the instr. code */
498: for( index = 0; index <= max_index; index++ ) {
499: get_current_data( adr_op1, adr_op2 );
500: run_code(); /* execute the instruction */
501: if( force_loop )
502: run_code(); /* start the error loop */
503: }
504: }
505:
506:
507:
508:
509: /*******************************************************************
510: * AUTO-INCREMENTED STACK POINTER ADDRESSING ( POP ): ( sgl ops only )
511: * instruction = <op-code> <8e>
512: *
513: * The data will be pushed by "run_code"
514: * Pop will be run with SGL floating point instructions only. A different
515: * routine will be used for the integer multiply instructions.
516: *******************************************************************/
517: tst_pop()
518: {
519: pipe_test = FALSE; /* clear the pipe test flag */
520: fill_reg_buf( load_regs ); /* set data for registers */
521: fill_reg_buf( exp_regs ); /* set data for registers */
522: addr_mode = ADR_POP;
523: addr_code = addr_code2 = 0x8e;
524: addr_size = 0; /* no addressing bytes */
525: pack_inst(); /* pack the instr. code */
526: if( no_ops == 1 ) {
527: min_shift = 19;
528: exp_page_faults = 3; /* 3 pages are used */
529: } else { /* 2 operands */
530: min_shift = 18;
531: exp_page_faults = 4; /* 4 pages are used */
532: }
533: shift_count = 19;
534: for( index = 0; index <= max_index; index++ ) {
535: get_current_data( adr_op1, adr_op2 );
536: sgl_value_8 = dbl_value_1.m; /* data to be pushed */
537: sgl_value_9 = dbl_value_2.m; /* data to be pushed */
538: run_code(); /* execute the instruction */
539: if( force_loop )
540: run_code(); /* start the error loop */
541: if( --shift_count < min_shift )
542: shift_count = 19;
543: }
544: }
545:
546:
547:
548:
549:
550:
551: /*******************************************************************
552: * STACK ADDRESSING TEST FOR THE MULL2 AND MULL3 INTEGER MULTIPLY INSTRUCTIONS
553: *
554: * For MULL2, operand 1 will be popped from the stack and
555: * operand 2 will be in memory
556: *
557: * For MULL3, operands 1 and 2 will be popped from the stack and
558: * operand 3 will be in pushed back onto the stack.
559: *
560: * The stack data will be pushed by "run_code"
561: *******************************************************************/
562: tst_mull_stack()
563: {
564: pipe_test = FALSE; /* clear the pipe test flag */
565: fill_reg_buf( load_regs ); /* set data for registers */
566: fill_reg_buf( exp_regs ); /* set data for registers */
567: addr_size = 0; /* no addressing bytes */
568: addr_mode = ADR_POP;
569: addr_code = 0x8e; /* auto increment SP (POP) */
570: if( op_code == MULL2_OP_CODE )
571: addr_code2 = 0x60; /* R0 (deferred) addressing */
572: else
573: addr_code2 = 0x8e; /* auto increment SP (POP) */
574: addr_code3 = 0x7e; /* auto decrement SP (PUSH) */
575: load_regs[0] = (int) adr_op2; /* set R0 to addr of op #2 */
576: exp_regs[0] = load_regs[0];
577: pack_inst(); /* pack the instr. code */
578: exp_page_faults = 4; /* 4 pages are used */
579: if( no_ops == 2 )
580: min_shift = 18; /* MULL2 */
581: else
582: min_shift = 17; /* MULL3 */
583: shift_count = 19;
584: for( index = 0; index <= max_index; index++ ) {
585: get_current_data( adr_op1, adr_op2 );
586: if( op_code == MULL2_OP_CODE )
587: sgl_value_8 = dbl_value_1.m; /* push operand 1 only */
588: else {
589: sgl_value_8 = dbl_value_1.m; /* push both of */
590: sgl_value_9 = dbl_value_2.m; /* the operands */
591: }
592: run_code(); /* execute the instruction */
593: if( force_loop )
594: run_code(); /* start the error loop */
595: if( --shift_count < min_shift )
596: shift_count = 19;
597: }
598: }
599:
600:
601:
602:
603:
604: /*******************************************************************
605: * AUTO-INCREMENTED STACK POINTER DEFERRED ADDRESSING:
606: * instruction = <op-code> <9e> { <9e> <9e> }
607: *
608: * The address(es) of the data will be pushed by "run_code"
609: *******************************************************************/
610: tst_pop_d()
611: {
612: pipe_test = FALSE; /* clear the pipe test flag */
613: fill_reg_buf( load_regs ); /* set data for registers */
614: fill_reg_buf( exp_regs ); /* set data for registers */
615: addr_mode = ADR_POP_DEF;
616: addr_code = addr_code2 = addr_code3 = 0x9e;
617: addr_size = 0; /* no addressing bytes */
618: pack_inst(); /* pack the instr. code */
619: sgl_value_8 = (int) adr_op1; /* get 1st op's address */
620: sgl_value_9 = (int) adr_op2; /* get 2nd op's address */
621: sgl_value_10 = (int) adr_op3; /* get 3rd op's address */
622: if( no_ops == 1 )
623: min_shift = 19;
624: else if( no_ops == 2 )
625: min_shift = 18;
626: else
627: min_shift = 17;
628: shift_count = 19;
629: for( index = 0; index <= max_index; index++ ) {
630: get_current_data( adr_op1, adr_op2 );
631: get_exp_faults( 4, 5, 6, 7, 7 ); /* set exp fault cnt */
632: run_code(); /* execute the instruction */
633: if( --shift_count < min_shift )
634: shift_count = 19;
635: }
636: }
637:
638:
639:
640:
641: /*******************************************************************
642: * REGISTER + BYTE DISPLACEMENT ADDRESSING:
643: * instruction = <op-code> <a4> <(&op_1 -r4)>
644: * { <a5> <(&op_2- r5)> }
645: * { <a6> <(&op_3- r6)> }
646: *******************************************************************/
647: tst_r_b()
648: {
649: pipe_test = FALSE; /* clear the pipe test flag */
650: fill_reg_buf( load_regs ); /* set data for registers */
651: fill_reg_buf( exp_regs ); /* set data for registers */
652: addr_mode = ADR_REG_B;
653: addr_code = 0xa4; /* addr 1 is offset by r4 */
654: addr_code2 = 0xa5; /* addr 2 is offset by r5 */
655: addr_code3 = 0xa6; /* addr 3 is offset by r6 */
656: addr_size = 1; /* 1 byte operand */
657: addr_1 = 20; /* set the 1st byte offset */
658: addr_2 = 4; /* set the 2nd byte offset */
659: addr_3 = 16; /* set the 3rd byte offset */
660: pack_inst(); /* pack the instr. code */
661: load_regs[4] = (int) adr_op1 - 20; /* get the reg value */
662: load_regs[5] = (int) adr_op2 - 4;
663: load_regs[6] = (int) adr_op3 - 16;
664: exp_regs[4] = load_regs[4];
665: exp_regs[5] = load_regs[5];
666: exp_regs[6] = load_regs[6];
667: if( no_ops == 1 )
668: min_shift = 18;
669: else if( no_ops == 2 )
670: min_shift = 16;
671: else
672: min_shift = 14;
673: shift_count = 19;
674: for( index = 0; index <= max_index; index++ ) {
675: get_current_data( adr_op1, adr_op2 );
676: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
677: run_code(); /* execute the instruction */
678: if( --shift_count < min_shift )
679: shift_count = 19;
680: }
681: }
682:
683:
684:
685: /*******************************************************************
686: * REGISTER + WORD DISPLACEMENT ADDRESSING:
687: * instruction = <op-code> <c4> <(&op_1 -r4)>
688: * { <c5> <(&op_2 -r5)> }
689: * { <c6> <(&op_3 -r6)> }
690: *******************************************************************/
691: tst_r_w()
692: {
693: pipe_test = FALSE; /* clear the pipe test flag */
694: fill_reg_buf( load_regs ); /* set data for registers */
695: fill_reg_buf( exp_regs ); /* set data for registers */
696: addr_mode = ADR_REG_W;
697: addr_code = 0xc4; /* addr 1 is offset by r4 */
698: addr_code2 = 0xc5; /* addr 2 is offset by r5 */
699: addr_code3 = 0xc6; /* addr 3 is offset by r6 */
700: addr_size = 2; /* word (2 byte) operand */
701: addr_1 = 511; /* set the 1st word offset */
702: addr_2 = 513; /* set the 2nd word offset */
703: addr_3 = 600; /* set the 3rd word offset */
704: pack_inst(); /* pack the instr. code */
705: load_regs[4] = (int) adr_op1 - 511; /* get the reg value */
706: load_regs[5] = (int) adr_op2 - 513;
707: load_regs[6] = (int) adr_op3 - 600;
708: exp_regs[4] = load_regs[4];
709: exp_regs[5] = load_regs[5];
710: exp_regs[6] = load_regs[6];
711: if( no_ops == 1 )
712: min_shift = 17;
713: else if( no_ops == 2 )
714: min_shift = 14;
715: else
716: min_shift = 11;
717: shift_count = 19;
718: for( index = 0; index <= max_index; index++ ) {
719: get_current_data( adr_op1, adr_op2 );
720: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
721: run_code(); /* execute the instruction */
722: if( --shift_count < min_shift )
723: shift_count = 19;
724: }
725: }
726:
727:
728:
729:
730: /*******************************************************************
731: * REGISTER + LONGWORD DISPLACEMENT ADDRESSING:
732: * instruction = <op-code> <e4> <(&op_1 -r4)>
733: * { <e5> <(&op_2 -r5)> }
734: * { <e6> <(&op_3 -r6)> }
735: *******************************************************************/
736: tst_r_l()
737: {
738: pipe_test = FALSE; /* clear the pipe test flag */
739: fill_reg_buf( load_regs ); /* set data for registers */
740: fill_reg_buf( exp_regs ); /* set data for registers */
741: addr_mode = ADR_REG_L;
742: addr_code = 0xe4; /* addr 1 is offset by r4 */
743: addr_code2 = 0xe5; /* addr 2 is offset by r5 */
744: addr_code3 = 0xe6; /* addr 3 is offset by r6 */
745: addr_size = 4; /* longword (4 byte) op. */
746: addr_1 = (int) adr_op1 - 123; /* get the 1st addr base */
747: addr_2 = (int) adr_op2 - 130; /* get the 2nd addr base */
748: addr_3 = (int) adr_op3 - 255; /* get the 3rd addr base */
749: load_regs[4] = 123; /* reg 4 = 123 */
750: exp_regs[4] = 123;
751: load_regs[5] = 130; /* reg 5 = 130 */
752: exp_regs[5] = 130;
753: load_regs[6] = 255; /* reg 5 = 255 */
754: exp_regs[6] = 255;
755: pack_inst(); /* pack the instr. code */
756: if( no_ops == 1 )
757: min_shift = 15;
758: else if( no_ops == 2 )
759: min_shift = 10;
760: else
761: min_shift = 5;
762: shift_count = 19;
763: for( index = 0; index <= max_index; index++ ) {
764: get_current_data( adr_op1, adr_op2 );
765: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
766: run_code(); /* execute the instruction */
767: if( --shift_count < min_shift )
768: shift_count = 19;
769: }
770: }
771:
772:
773:
774:
775: /*******************************************************************
776: * REGISTER + BYTE DISPLACEMENT DEFERRED ADDRESSING:
777: * instruction = <op-code> <b4> <(&ptr_to_op_3 -r4)>
778: * { <b5> <(&ptr_to_op_3 -r5)> }
779: * { <b6> <(&ptr_to_op_3 -r6)> }
780: *******************************************************************/
781: tst_r_bd()
782: {
783: pipe_test = FALSE; /* clear the pipe test flag */
784: fill_reg_buf( load_regs ); /* set data for registers */
785: fill_reg_buf( exp_regs ); /* set data for registers */
786: addr_mode = ADR_REG_B_DEF;
787: addr_code = 0xb4; /* addr 1 is offset by r4 */
788: addr_code2 = 0xb5; /* addr 2 is offset by r5 */
789: addr_code3 = 0xb6; /* addr 3 is offset by r6 */
790: addr_size = 1; /* 1 byte operand */
791: addr_1 = 20; /* set the 1st byte offset */
792: addr_2 = 4; /* set the 2nd byte offset */
793: addr_3 = 16; /* set the 3rd byte offset */
794: pack_inst(); /* pack the instr. code */
795: load_regs[4] = (int) adr_op1_ptr - 20; /* get the reg value */
796: load_regs[5] = (int) adr_op2_ptr - 4;
797: load_regs[6] = (int) adr_op3_ptr - 16;
798: exp_regs[4] = load_regs[4];
799: exp_regs[5] = load_regs[5];
800: exp_regs[6] = load_regs[6];
801: if( no_ops == 1 )
802: min_shift = 18;
803: else if( no_ops == 2 )
804: min_shift = 16;
805: else
806: min_shift = 14;
807: shift_count = 19;
808: for( index = 0; index <= max_index; index++ ) {
809: get_current_data( adr_op1, adr_op2 );
810: get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
811: run_code(); /* execute the instruction */
812: if( --shift_count < min_shift )
813: shift_count = 19;
814: }
815: }
816:
817:
818:
819: /*******************************************************************
820: * REGISTER + WORD DISPLACEMENT DEFERRED ADDRESSING:
821: * instruction = <op-code> <d4> <(&ptr_to_op_1 -r4)>
822: * { <d5> <(&ptr_to_op_2 -r5)> }
823: * { <d6> <(&ptr_to_op_3 -r6)> }
824: *******************************************************************/
825: tst_r_wd()
826: {
827: pipe_test = FALSE; /* clear the pipe test flag */
828: fill_reg_buf( load_regs ); /* set data for registers */
829: fill_reg_buf( exp_regs ); /* set data for registers */
830: addr_mode = ADR_REG_W_DEF;
831: addr_code = 0xd4; /* addr 1 is offset by r4 */
832: addr_code2 = 0xd5; /* addr 2 is offset by r5 */
833: addr_code3 = 0xd6; /* addr 3 is offset by r6 */
834: addr_size = 2; /* word (2 byte) operand */
835: addr_1 = 511; /* set the 1st word offset */
836: addr_2 = 601; /* set the 2nd word offset */
837: addr_3 = 1027; /* set the 3rd word offset */
838: pack_inst(); /* pack the instr. code */
839: load_regs[4] = (int) adr_op1_ptr - 511; /* get the reg value */
840: load_regs[5] = (int) adr_op2_ptr - 601;
841: load_regs[6] = (int) adr_op3_ptr - 1027;
842: exp_regs[4] = load_regs[4];
843: exp_regs[5] = load_regs[5];
844: exp_regs[6] = load_regs[6];
845: if( no_ops == 1 )
846: min_shift = 17;
847: else if( no_ops == 2 )
848: min_shift = 14;
849: else
850: min_shift = 11;
851: shift_count = 19;
852: for( index = 0; index <= max_index; index++ ) {
853: get_current_data( adr_op1, adr_op2 );
854: get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
855: run_code(); /* execute the instruction */
856: if( --shift_count < min_shift )
857: shift_count = 19;
858: }
859: }
860:
861:
862:
863:
864: /*******************************************************************
865: * REGISTER + LONGWORD DISPLACEMENT DEFERRED ADDRESSING:
866: * instruction = <op-code> <f4> <(longword &ptr_to_op_1 -r4)>
867: * { <f5> <(longword &ptr_to_op_2 -r5)> }
868: * { <f6> <(longword &ptr_to_op_3 -r6)> }
869: *******************************************************************/
870: tst_r_ld()
871: {
872: pipe_test = FALSE; /* clear the pipe test flag */
873: fill_reg_buf( load_regs ); /* set data for registers */
874: fill_reg_buf( exp_regs ); /* set data for registers */
875: addr_mode = ADR_REG_L_DEF;
876: addr_code = 0xf4; /* addr 1 is offset by r4 */
877: addr_code2 = 0xf5; /* addr 2 is offset by r5 */
878: addr_code3 = 0xf6; /* addr 3 is offset by r6 */
879: addr_size = 4; /* longword (4 byte) op. */
880: addr_1 = (int) adr_op1_ptr - 123; /* set the 1st offset */
881: addr_2 = (int) adr_op2_ptr - 212; /* set the 2nd offset */
882: addr_3 = (int) adr_op3_ptr - 510; /* set the 3rd offset */
883: pack_inst(); /* pack the instr. code */
884: load_regs[4] = 123; /* reg 4 = 123 */
885: load_regs[5] = 212; /* reg 5 = 212 */
886: load_regs[6] = 510; /* reg 6 = 510 */
887: exp_regs[4] = load_regs[4];
888: exp_regs[5] = load_regs[5];
889: exp_regs[6] = load_regs[6];
890: if( no_ops == 1 )
891: min_shift = 15;
892: else if( no_ops == 2 )
893: min_shift = 10;
894: else
895: min_shift = 5;
896: shift_count = 19;
897: for( index = 0; index <= max_index; index++ ) {
898: get_current_data( adr_op1, adr_op2 );
899: get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
900: run_code(); /* execute the instruction */
901: if( --shift_count < min_shift )
902: shift_count = 19;
903: }
904: }
905:
906:
907:
908: /*******************************************************************
909: * FRAME POINTER DEFERRED + LONGWORD INDEX ADDRESSING:
910: * instruction = <op-code> <44> <6d> { <45> <6d> } { <46> <6d> }
911: *
912: * The indeces used will be either quadword indeces ( for DBL operands )
913: * of longword indeces ( for SGL operands ).
914: *
915: * NOTE:
916: * dmp_op_2 is 4 pages away from dmp_op_1. (200 hex quadwords)
917: * dmp_op_3 is 5 pages & 4 bytes from dmp_op_1. (501 hex longwords)
918: * IF THIS RELATIVE DISPLACEMENT IS CHANGED THEN THE R5 AND/OR R6 INDICES
919: * MUST BE CHANGED IN THIS CODE!!!
920: * ( The R5 index is used by CMPF2, CMPD2, MULL2, & MULL3.
921: * The R6 index is used by MULL3. )
922: *******************************************************************/
923: tst_x_fpd()
924: {
925: pipe_test = FALSE; /* clear the pipe test flag */
926: fill_reg_buf( load_regs ); /* set data for registers */
927: fill_reg_buf( exp_regs ); /* set data for registers */
928: addr_mode = ADR_I_FP_DEF;
929: addr_code = 0x44; /* code for reg. 4 index */
930: addr_code2 = 0x45; /* code for reg. 5 index */
931: addr_code3 = 0x46; /* code for reg. 6 index */
932: addr_codeB = 0x6d; /* code for FP deferred */
933: addr_size = 0; /* no addr. field per se */
934: pack_inst(); /* pack the instr. code */
935: /*
936: * set the frame pointer to '&operand_1 - 16 bytes' (2 quad-words)
937: */
938: sgl_dummy1 = (int) adr_op1; /* get the addr of op #1 */
939: load_regs[13] = sgl_dummy1-16; /* FP = op 1's addr - 16 */
940: exp_regs[13] = load_regs[13];
941: if( sgl_op ) {
942: load_regs[4] = 4; /* FP to op_1 (longwords) */
943: load_regs[5] = 0x404; /* FP to op_2 (longwords) */
944: load_regs[6] = 0x505; /* FP to op_2 (longwords) */
945: } else {
946: load_regs[4] = 2; /* FP to op_1 (quadwords) */
947: load_regs[5] = 0x202; /* FP to op_2 (quadwords) */
948: }
949: exp_regs[4] = load_regs[4];
950: exp_regs[5] = load_regs[5];
951: exp_regs[6] = load_regs[6];
952: if( no_ops == 1 )
953: min_shift = 18;
954: else if( no_ops == 2 )
955: min_shift = 16;
956: else
957: min_shift = 14;
958: shift_count = 19;
959: for( index = 0; index <= max_index; index++ ) {
960: get_current_data( adr_op1, adr_op2 );
961: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
962: run_code(); /* execute the instruction */
963: if( --shift_count < min_shift )
964: shift_count = 19;
965: }
966: }
967:
968:
969:
970: /*******************************************************************
971: * INDEXED LONGWORD DISPLACEMENT ADDRESSING:
972: * instruction = <op-code> <44> <ef> <longword offset>
973: * { <45> <ef> <longword offset> }
974: * { <46> <ef> <longword offset> }
975: *
976: * NOTE: The index to operand 3 (R6) is only used with MULL3.
977: *******************************************************************/
978: tst_x_l()
979: {
980: pipe_test = FALSE; /* clear the pipe test flag */
981: fill_reg_buf( load_regs ); /* set data for registers */
982: fill_reg_buf( exp_regs ); /* set data for registers */
983: addr_mode = ADR_I_L;
984: addr_code = 0x44; /* code for reg. 4 index */
985: addr_code2 = 0x45; /* code for reg. 5 index */
986: addr_code3 = 0x46; /* code for reg. 6 index */
987: addr_codeB = 0xef; /* code for longword disp */
988: addr_size = 4; /* longword (4 byte) op. */
989: if( sgl_op ) {
990: load_regs[4] = 4; /* reg 4 = 4 (longwords) */
991: load_regs[5] = 6; /* reg 5 = 6 (longwords) */
992: load_regs[6] = 5; /* reg 6 = 5 (longwords) */
993: } else {
994: load_regs[4] = 2; /* reg 4 = 2 (quadwords) */
995: load_regs[5] = 3; /* reg 5 = 3 (quadwords) */
996: }
997: exp_regs[4] = load_regs[4];
998: exp_regs[5] = load_regs[5];
999: exp_regs[6] = load_regs[6];
1000: if( no_ops == 1 )
1001: min_shift = 14;
1002: else if( no_ops == 2 )
1003: min_shift = 8;
1004: else
1005: min_shift = 2;
1006: shift_count = 19;
1007: for( index = 0; index <= max_index; index++ ) {
1008: get_current_data( adr_op1, adr_op2 );
1009: get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
1010: addr_1 = os_op1 + 13 - shift_count; /* data's offset */
1011: addr_1 -=16; /* -16 bytes (2 Q-words) */
1012: addr_2 = os_op2 + 7 - shift_count; /* data's offset */
1013: addr_2 -=24; /* -24 bytes (3 Q-words) */
1014: addr_3 = os_op3 + 1 - shift_count; /* data's offset */
1015: addr_3 -=20; /* -20 bytes (5 L-words) */
1016: pack_inst(); /* pack the instr. code */
1017: run_code(); /* execute the instruction */
1018: if( --shift_count < min_shift )
1019: shift_count = 19;
1020: }
1021: }
1022:
1023:
1024:
1025:
1026:
1027: /*******************************************************************
1028: * PIPELINE TEST #1 -DIRECT REGISTER ADDRESSING WITH AN INITIAL LOAD
1029: *
1030: * This test will put a LOAD instruction immediately in front of the
1031: * test instruction and a MULTIPLY instruction immediately behind it.
1032: * The instruction buffer will look like:
1033: *
1034: * <ldf/ldd> <instruction> <mulf/muld> where:
1035: * instruction = <op-code> <50> { <54> } { <58> }
1036: *
1037: * The load will be done through register R6 deferred.
1038: * The multiply addressing mode will be through register R2 deferred.
1039: *******************************************************************/
1040: tst_p1()
1041: {
1042: pipe_test = 1; /* set pipelined test flag to test #3 */
1043: if( acc_ld_size == DBL )
1044: pipe_inst1 = LDD_OP_CODE;
1045: else
1046: pipe_inst1 = LDF_OP_CODE;
1047: if( acc_st_size == DBL )
1048: pipe_inst2 = MULD_OP_CODE;
1049: else
1050: pipe_inst2 = MULF_OP_CODE;
1051: addr_code_p1 = 0x66; /* set the 1st piped addr mode */
1052: addr_code_p2 = 0x62; /* set the 2nd piped addr mode */
1053: fill_reg_buf( load_regs ); /* set data for registers */
1054: fill_reg_buf( exp_regs ); /* set data for registers */
1055: load_regs[2] = (int) adr_op4; /* the MULx is w/ op. #4 */
1056: exp_regs[2] = load_regs[2];
1057: load_regs[6] = (int) adr_op5; /* the LDx is w/ op. #5 */
1058: exp_regs[6] = load_regs[6];
1059: adr_op4->m = 0x40800000; /* set the MULx instr's */
1060: adr_op4->l = 0; /* operand = '1.0' */
1061: addr_mode = ADR_REG;
1062: addr_code = 0x50; /* 1st op in registers 0/1 */
1063: addr_code2 = 0x54; /* 2nd op in registers 4/5 */
1064: addr_code3 = 0x58; /* 3rd op goes to reg. 8 */
1065: addr_size = 0; /* no addressing bytes */
1066: pack_inst(); /* pack the instr. code */
1067: exp_page_faults = 4; /* 4 pages are used */
1068: if( no_ops == 1 )
1069: min_shift = 16;
1070: else if( no_ops == 2 )
1071: min_shift = 15;
1072: else
1073: min_shift = 14;
1074: shift_count = 18;
1075: for( index = 0; index <= max_index; index++ ) {
1076: get_current_data( adr_op1, adr_op2 );
1077: adr_op5->m = dbl_ld_acc.m; /* get the data for the */
1078: adr_op5->l = dbl_ld_acc.l; /* load instruction */
1079: load_regs[0] = dbl_value_1.m; /* set the test data */
1080: load_regs[1] = dbl_value_1.l;
1081: load_regs[4] = dbl_value_2.m;
1082: load_regs[5] = dbl_value_2.l;
1083: exp_regs[4] = load_regs[4]; /* set exp final reg value */
1084: exp_regs[5] = load_regs[5];
1085: if( op_type == STORE ) {
1086: exp_regs[0] = dbl_expected.m;
1087: exp_regs[1] = dbl_expected.l;
1088: } else {
1089: exp_regs[0] = dbl_value_1.m;
1090: exp_regs[1] = dbl_value_1.l;
1091: if( op_code == MULL3_OP_CODE )
1092: exp_regs[8] = dbl_expected.m;
1093: if( op_code == MULL2_OP_CODE )
1094: exp_regs[4] = dbl_expected.m;
1095: }
1096: if( op_code == CVDL_OP_CODE ) /* correct for sgl store */
1097: exp_regs[1] = dbl_value_1.l; /* r1 shouldn't change */
1098: run_code(); /* execute the instruction */
1099: if( --shift_count < min_shift )
1100: shift_count = 18;
1101: }
1102: pipe_test = FALSE; /* clear the pipe test flag */
1103: }
1104:
1105:
1106:
1107: /*******************************************************************
1108: * PIPELINE TEST #2 -LONGWORD DISP REL ADDRESSING WITH AN INITIAL LOAD
1109: *
1110: * This test will put a LOAD instruction immediately in front of the
1111: * test instruction and a MULTIPLY instruction immediately behind it.
1112: * The instruction buffer will look like:
1113: *
1114: * <ldf/ldd> <instruction> <mulf/muld> where:
1115: * instruction = <op-code> <ef> <offset to dmp_op_1>
1116: * { <ef> <offset to dmp_op_2> }
1117: * { <ef> <offset to dmp_op_3> }
1118: *
1119: * The load's addressing mode will be through register R6 deferred.
1120: * The multiply's addressing mode will be through register R2 deferred.
1121: *******************************************************************/
1122: tst_p2()
1123: {
1124: pipe_test = 2; /* set the piplined test flag to test #4 */
1125: if( acc_ld_size == DBL )
1126: pipe_inst1 = LDD_OP_CODE;
1127: else
1128: pipe_inst1 = LDF_OP_CODE;
1129: if( acc_st_size == DBL )
1130: pipe_inst2 = MULD_OP_CODE;
1131: else
1132: pipe_inst2 = MULF_OP_CODE;
1133: addr_code_p1 = 0x66; /* set the 1st piped addr mode */
1134: addr_code_p2 = 0x62; /* set the 2nd piped addr mode */
1135: fill_reg_buf( load_regs ); /* set data for registers */
1136: fill_reg_buf( exp_regs ); /* set data for registers */
1137: load_regs[2] = (int) adr_op4; /* MULx is via op. #4 */
1138: exp_regs[2] = load_regs[2];
1139: load_regs[6] = (int) adr_op5; /* LDx is via op. #5 */
1140: exp_regs[6] = load_regs[6];
1141: adr_op4->m = 0x40800000; /* set the piped mult's */
1142: adr_op4->l = 0; /* operand = '1.0' */
1143: addr_mode = ADR_L_DSP;
1144: addr_code = addr_code2 = addr_code3 = 0xef;
1145: addr_size = 4; /* longword (4 byte) ops. */
1146: if( no_ops == 1 )
1147: min_shift = 12;
1148: else if( no_ops == 2 )
1149: min_shift = 7;
1150: else
1151: min_shift = 2;
1152: shift_count = 18;
1153: for( index = 0; index <= max_index; index++ ) {
1154: get_current_data( adr_op1, adr_op2 );
1155: get_exp_faults( 5, 6, 6, 8, 7 ); /* set exp fault count */
1156: adr_op5->m = dbl_ld_acc.m; /* get the data for the */
1157: adr_op5->l = dbl_ld_acc.l; /* load instruction */
1158: addr_1 = os_op1 + 12 - shift_count;
1159: addr_2 = os_op2 + 7 - shift_count;
1160: addr_3 = os_op3 + 2 - shift_count;
1161: pack_inst(); /* pack the instr. code */
1162: run_code(); /* execute the instruction */
1163: if( --shift_count < min_shift )
1164: shift_count = 18;
1165: }
1166: pipe_test = FALSE; /* clear the pipe test flag */
1167: }
1168:
1169:
1170:
1171:
1172:
1173: /*******************************************************************
1174: * PIPELINE TEST #3 -DIRECT REGISTER ADDRESSING WITH AN INITIAL MULTIPLY
1175: *
1176: * This test will put a MULTIPLY instruction immediately in front of the
1177: * test instruction and a MULTIPLY instruction immediately behind it.
1178: * Both multiplys will be times "1.0".
1179: *
1180: * The instruction buffer will look like:
1181: * <mulf/muld> <instruction> <mulf/muld> where:
1182: * instruction = <op-code> <50> { <54> } { <58> }
1183: *
1184: * The 1st multiply will be done through register R6 deferred.
1185: * The 2nd multiply will be done through register R2 deferred.
1186: *******************************************************************/
1187: tst_p3()
1188: {
1189: pipe_test = 3; /* set pipelined test flag to pipe test #1 */
1190: if( acc_ld_size == DBL )
1191: pipe_inst1 = MULD_OP_CODE;
1192: else
1193: pipe_inst1 = MULF_OP_CODE;
1194: if( acc_st_size == DBL )
1195: pipe_inst2 = MULD_OP_CODE;
1196: else
1197: pipe_inst2 = MULF_OP_CODE;
1198: addr_code_p1 = 0x66; /* set the 1st piped addr mode */
1199: addr_code_p2 = 0x62; /* set the 2nd piped addr mode */
1200: fill_reg_buf( load_regs ); /* set data for registers */
1201: fill_reg_buf( exp_regs ); /* set data for registers */
1202: load_regs[2] = (int) adr_op4; /* 2nd MULx is via op. #4 */
1203: exp_regs[2] = load_regs[2];
1204: load_regs[6] = (int) adr_op5; /* 1st MULx is via op. #5 */
1205: exp_regs[6] = load_regs[6];
1206: adr_op4->m = 0x40800000; /* set the MULx instr's */
1207: adr_op4->l = 0; /* operand = '1.0' */
1208: adr_op5->m = 0x40800000;
1209: adr_op5->l = 0;
1210: addr_mode = ADR_REG;
1211: addr_code = 0x50; /* 1st op in registers 0/1 */
1212: addr_code2 = 0x54; /* 2nd op in registers 4/5 */
1213: addr_code3 = 0x58; /* 3rd op goes to reg. 8 */
1214: addr_size = 0; /* no addressing bytes */
1215: pack_inst(); /* pack the instr. code */
1216: exp_page_faults = 4; /* 4 pages are used */
1217: if( no_ops == 1 )
1218: min_shift = 16;
1219: else if( no_ops == 2 )
1220: min_shift = 15;
1221: else
1222: min_shift = 14;
1223: shift_count = 18;
1224: for( index = 0; index <= max_index; index++ ) {
1225: get_current_data( adr_op1, adr_op2 );
1226: load_regs[0] = dbl_value_1.m; /* set the test data */
1227: load_regs[1] = dbl_value_1.l;
1228: load_regs[4] = dbl_value_2.m;
1229: load_regs[5] = dbl_value_2.l;
1230: if( op_code == MULL2_OP_CODE )
1231: exp_regs[4] = dbl_expected.m; /* store to reg #4 */
1232: else
1233: exp_regs[4] = load_regs[4]; /* reg 4 s/n change */
1234: exp_regs[5] = load_regs[5];
1235: if( op_code == MULL3_OP_CODE )
1236: exp_regs[8] = dbl_expected.m; /* store to reg #8 */
1237: if( op_type == LOAD ) {
1238: exp_regs[0] = dbl_value_1.m;
1239: exp_regs[1] = dbl_value_1.l;
1240: } else {
1241: exp_regs[0] = dbl_expected.m;
1242: exp_regs[1] = dbl_expected.l;
1243: }
1244: if( op_code == CVDL_OP_CODE ) /* correct for sgl store */
1245: exp_regs[1] = dbl_value_1.l; /* r1 shouldn't change */
1246: run_code(); /* execute the instruction */
1247: if( --shift_count < min_shift )
1248: shift_count = 18;
1249: }
1250: pipe_test = FALSE; /* clear the pipe test flag */
1251: }
1252:
1253:
1254:
1255:
1256: /*******************************************************************
1257: * PIPELINE TEST #4 -LONGWORD DISP REL ADDR. WITH AN INITIAL MULTIPLY
1258: *
1259: * This test will put MULTIPLY instructions immediately in front of and
1260: * behind the test instruction.
1261: * The instruction buffer will look like:
1262: *
1263: * <mulf/muld> <instruction> <mulf/muld> where:
1264: * instruction = <op-code> <ef> <offset to dmp_op_1>
1265: * { <ef> <offset to dmp_op_2> }
1266: * { <ef> <offset to dmp_op_3> }
1267: *
1268: * The 1st multiply's addressing will be through register R6 deferred.
1269: * The 2nd multiply's addressing will be through register R2 deferred.
1270: *******************************************************************/
1271: tst_p4()
1272: {
1273: pipe_test = 4; /* set the piplined flag to test # 2 */
1274: if( acc_ld_size == DBL )
1275: pipe_inst1 = MULD_OP_CODE;
1276: else
1277: pipe_inst1 = MULF_OP_CODE;
1278: if( acc_st_size == DBL )
1279: pipe_inst2 = MULD_OP_CODE;
1280: else
1281: pipe_inst2 = MULF_OP_CODE;
1282: addr_code_p1 = 0x66; /* set the 1st piped addr mode */
1283: addr_code_p2 = 0x62; /* set the 2nd piped addr mode */
1284: fill_reg_buf( load_regs ); /* set data for registers */
1285: fill_reg_buf( exp_regs ); /* set data for registers */
1286: load_regs[2] = (int) adr_op4; /* 2nd MULx is w/ op. #4 */
1287: exp_regs[2] = load_regs[2];
1288: load_regs[6] = (int) adr_op5; /* 1st MULx is w/ op. #5 */
1289: exp_regs[6] = load_regs[6];
1290: adr_op4->m = 0x40800000; /* set the piped mult's */
1291: adr_op4->l = 0; /* operand = '1.0' */
1292: adr_op5->m = 0x40800000;
1293: adr_op5->l = 0;
1294: addr_mode = ADR_L_DSP;
1295: addr_code = addr_code2 = addr_code3 = 0xef;
1296: addr_size = 4; /* longword (4 byte) ops. */
1297: if( no_ops == 1 )
1298: min_shift = 12;
1299: else if( no_ops == 2 )
1300: min_shift = 7;
1301: else
1302: min_shift = 2;
1303: shift_count = 18;
1304: for( index = 0; index <= max_index; index++ ) {
1305: get_current_data( adr_op1, adr_op2 );
1306: get_exp_faults( 5, 6, 6, 8, 7 ); /* set exp fault count */
1307: addr_1 = os_op1 + 12 - shift_count; /* data's offset */
1308: addr_2 = os_op2 + 7 - shift_count;
1309: addr_3 = os_op3 + 2 - shift_count;
1310: pack_inst(); /* pack the instr. code */
1311: run_code(); /* execute the instruction */
1312: if( --shift_count < min_shift )
1313: shift_count = 18;
1314: }
1315: pipe_test = FALSE; /* clear the pipe test flag */
1316: }
1317:
1318:
1319:
1320:
1321:
1322: /*
1323: ***************************************************************************
1324: *
1325: * GET DATA FOR DOUBLE PRECISION INSTRUCTIONS
1326: *
1327: ***************************************************************************
1328: */
1329: get_current_data( dptr_1, dptr_2 )
1330: struct u64 *dptr_1; /* pointer to 1st operand */
1331: struct u64 *dptr_2; /* pointer to 2nd operand */
1332: {
1333: if( no_ops == 1 ) {
1334: dbl_ld_acc = data_ptr[index].op_1;
1335: dbl_value_1 = data_ptr[index].op_2;
1336: dbl_expected = data_ptr[index].exp;
1337: *dptr_1 = dbl_value_1; /* set the operand */
1338: } else if( no_ops == 2 ) {
1339: if( index < (ldf_cnt -1) )
1340: dbl_ld_acc = ldd_data[index+1].op_1;
1341: else
1342: dbl_ld_acc = ldd_data[index & 0xf].op_1;
1343: dbl_value_1 = data_ptr[index].op_1;
1344: dbl_value_2 = data_ptr[index].op_2;
1345: dbl_expected = data_ptr[index].exp;
1346: *dptr_1 = dbl_value_1; /* set 1st operand */
1347: *dptr_2 = dbl_value_2; /* set 2nd operand */
1348: } else { /* 3 operands */
1349: if( index < (ldf_cnt -1) )
1350: dbl_ld_acc = ldd_data[index +1].op_1;
1351: else
1352: dbl_ld_acc = ldd_data[index & 0xf].op_1;
1353: dbl_value_1 = data_ptr[index].op_1;
1354: dbl_value_2 = data_ptr[index].op_2;
1355: dbl_expected = data_ptr[index].exp;
1356: *dptr_1 = dbl_value_1; /* set 1st operand */
1357: *dptr_2 = dbl_value_2; /* set 2nd operand */
1358: }
1359: }
1360:
1361:
1362:
1363: /*
1364: ***************************************************************************
1365: * Set the number of translation faults expected
1366: *
1367: * The entry parameters are the number of faults expected with an instruction
1368: * cache miss and with varying data types. The correct fault count is
1369: * selected and put into "exp_page_faults".
1370: * In double precision compare (CMPD, CMPD2) operations, the system won't
1371: * fetch the least significant half of the operand(s) if the most significant
1372: * halves are different. The # of faults expected will be adjusted for this.
1373: * When using the "no-fpp" version of firmware the least significant longword
1374: * will always be fetched for CMPD. CMPD2 acts the same with either WCS.
1375: *
1376: ***************************************************************************
1377: */
1378: get_exp_faults( sgl_1, dbl_1, sgl_2, dbl_2, sgl_3 )
1379: int sgl_1; /* exp # faults for 1 sgl operand */
1380: int dbl_1; /* exp # faults for 1 dbl operand */
1381: int sgl_2; /* exp # faults for 2 sgl operands */
1382: int dbl_2; /* exp # faults for 2 dbl operands */
1383: int sgl_3; /* exp # faults for 3 sgl operands */
1384: {
1385: if( no_ops == 1 ) {
1386: if( sgl_op )
1387: exp_page_faults = sgl_1; /* 1 sgl operand */
1388: else
1389: exp_page_faults = dbl_1; /* 1 dbl operand */
1390: } else if( no_ops == 2 ) {
1391: if( sgl_op )
1392: exp_page_faults = sgl_2; /* 2 sgl operands */
1393: else
1394: exp_page_faults = dbl_2; /* 2 dbl operands */
1395: } else /* 3 sgl operands */
1396: exp_page_faults = sgl_3; /* 3 sgl operands */
1397: if( (op_code == CMPD2_OP_CODE) && (dbl_value_1.m != dbl_value_2.m) )
1398: exp_page_faults--;
1399: if( (op_code == CMPD_OP_CODE) && (dbl_value_1.m != dbl_ld_acc.m) &&
1400: (!no_fpp_wcs) )
1401: exp_page_faults--;
1402: }
1403:
1404:
1405: /*
1406: ***************************************************************************
1407: *
1408: * Set or reset the LOAD_ACCUMULATOR flag
1409: *
1410: * If the current instruction loads the accumulator then set the flag.
1411: * This flag is used by the page fault handler.
1412: ***************************************************************************
1413: */
1414: set_load_flag()
1415: {
1416: if( (op_code == LDF_OP_CODE) || /* load SGL Acc. */
1417: (op_code == LNF_OP_CODE) || /* load / negate SGL Acc. */
1418: (op_code == LDD_OP_CODE) || /* load SGL Acc. */
1419: (op_code == LND_OP_CODE) || /* load / negate SGL Acc. */
1420: (op_code == LDFD_OP_CODE) ) /* load SGL to DBL Acc. */
1421: load_type_inst = TRUE;
1422: else
1423: load_type_inst = FALSE;
1424: }
1425:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.