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