|
|
1.1 ! root 1: #include "evt_defs.h" ! 2: ! 3: /************************************************************************** ! 4: * ! 5: * Test the current instruction ! 6: * ! 7: * 10-Apr-85 - changed the test to just check a couple of addr. modes ! 8: * 30-May-85 - added pipeline tests for A-loaded and B-loaded entries. ! 9: * 20-Jul-85 - added 3 operands for MULL3 integer overflow ! 10: **************************************************************************/ ! 11: test_inst() ! 12: { ! 13: *adr_op1_ptr = (int) adr_op1; /* set word offset ptr #1 */ ! 14: *adr_op2_ptr = (int) adr_op2; /* set word offset ptr #2 */ ! 15: *adr_op3_ptr = (int) adr_op3; /* set word offset ptr #3 */ ! 16: asm("moval (sp),_monitor_sp"); /* save the stack pointer */ ! 17: asm("moval (fp),_monitor_fp"); /* save the frame pointer */ ! 18: asm("movab _test_inst_ret,_unexp_event_ret"); ! 19: error = FALSE; /* clear error flag */ ! 20: set_load_flag(); /* set the LOAD ACC. flag */ ! 21: if( !no_ops ) ! 22: test_0_ops(); /* test inst w/ no operands */ ! 23: else { ! 24: tst_l(); /* longword displacement relative */ ! 25: tst_r(); /* direct register */ ! 26: tst_r_d(); /* register deferred */ ! 27: tst_r_ld(); /* register + longword displacement */ ! 28: tst_x_fpd(); /* FP deferred + longword index */ ! 29: tst_p1(); /* pipeline test #1, LDx <op.> */ ! 30: if( (!load_type_inst) && (!no_fpp_wcs) ) ! 31: tst_p2(); /* pipeline test #2, ADDx <op.> */ ! 32: } ! 33: asm(".globl _test_inst_ret"); ! 34: asm("_test_inst_ret:"); ! 35: asm("movl _monitor_sp,sp"); /* restore the stack ptr. */ ! 36: asm("movl _monitor_fp,fp"); /* restore the frame ptr. */ ! 37: } ! 38: ! 39: ! 40: ! 41: ! 42: ! 43: ! 44: /******************************************************************* ! 45: * LONGWORD DISPLACEMENT RELATIVE ADDRESSING: ! 46: * instruction = <op-code> <ef> <offset to dmp_op_1> ! 47: * { <ef> <offset to dmp_op_2> } ! 48: * { <ef> <offset to dmp_op_3> } ! 49: *******************************************************************/ ! 50: tst_l() ! 51: { ! 52: pipe_test = FALSE; ! 53: fill_reg_buf( load_regs ); /* set data for registers */ ! 54: fill_reg_buf( exp_regs ); /* set data for registers */ ! 55: addr_mode = ADR_L_DSP; ! 56: addr_code = addr_code2 = addr_code3 = 0xef; ! 57: addr_size = 4; /* longword (4 byte) ops. */ ! 58: addr_1 = os_op1 + 14; /* offset to the data */ ! 59: addr_2 = os_op2 + 9; ! 60: addr_3 = os_op3 + 4; ! 61: pack_inst(); /* pack the instr. code */ ! 62: for( index = 0; index <= max_index; index++ ) { ! 63: get_current_data( adr_op1, adr_op2 ); ! 64: run_code(); /* execute the instruction */ ! 65: } ! 66: } ! 67: ! 68: ! 69: ! 70: /******************************************************************* ! 71: * DIRECT REGISTER ADDRESSING: ! 72: * instruction = <op-code> <50> { <54> <56> } ! 73: *******************************************************************/ ! 74: tst_r() ! 75: { ! 76: pipe_test = FALSE; ! 77: fill_reg_buf( load_regs ); /* set data for registers */ ! 78: fill_reg_buf( exp_regs ); /* set data for registers */ ! 79: if( op_code == MULL3_OP_CODE ) ! 80: exp_regs[6] = 0; /* final op #3 should = 0 */ ! 81: addr_mode = ADR_REG; ! 82: addr_code = 0x50; /* 1st op in registers 0/1 */ ! 83: addr_code2 = 0x54; /* 2nd op in registers 4/5 */ ! 84: addr_code3 = 0x56; /* 3rd op in registers 6 */ ! 85: addr_size = 0; /* no addressing bytes */ ! 86: pack_inst(); /* pack the instr. code */ ! 87: for( index = 0; index <= max_index; index++ ) { ! 88: get_current_data( adr_op1, adr_op2 ); /* addr's not used */ ! 89: load_regs[0] = dbl_value_1.m; /* set the data */ ! 90: load_regs[1] = dbl_value_1.l; ! 91: load_regs[4] = dbl_value_2.m; ! 92: load_regs[5] = dbl_value_2.l; ! 93: if( op_code == MULL2_OP_CODE ) ! 94: exp_regs[4] = 0; /* final op #2 should = 0 */ ! 95: else /* op #2 shouldn't change */ ! 96: exp_regs[4] = dbl_value_2.m; ! 97: exp_regs[5] = dbl_value_2.l; ! 98: exp_regs[1] = dbl_value_1.l; /* op #1's LSW won't change */ ! 99: if( (op_code == CVFL_OP_CODE) || /* correct for sgl store */ ! 100: (op_code == CVDL_OP_CODE) ) ! 101: exp_regs[0] = 0; /* ovfl results are cleared */ ! 102: else ! 103: exp_regs[0] = dbl_value_1.m; ! 104: run_code(); /* execute the instruction */ ! 105: } ! 106: } ! 107: ! 108: ! 109: ! 110: /******************************************************************* ! 111: * REGISTER DEFERRED ADDRESSING: ! 112: * instruction = <op-code> <60> { <61> <62> } ! 113: *******************************************************************/ ! 114: tst_r_d() ! 115: { ! 116: pipe_test = FALSE; ! 117: fill_reg_buf( load_regs ); /* set data for registers */ ! 118: fill_reg_buf( exp_regs ); /* set data for registers */ ! 119: addr_mode = ADR_REG_DEF; ! 120: addr_code = 0x60; ! 121: addr_code2 = 0x61; ! 122: addr_code3 = 0x62; ! 123: addr_size = 0; /* no address byte(s) */ ! 124: load_regs[0] = (int) adr_op1; /* get addr of op. 1 */ ! 125: load_regs[1] = (int) adr_op2; /* get addr of op. 2 */ ! 126: load_regs[2] = (int) adr_op3; /* get addr of op. 3 */ ! 127: exp_regs[0] = load_regs[0]; ! 128: exp_regs[1] = load_regs[1]; ! 129: exp_regs[2] = load_regs[2]; ! 130: pack_inst(); /* pack the instr. code */ ! 131: for( index = 0; index <= max_index; index++ ) { ! 132: get_current_data( adr_op1, adr_op2 ); ! 133: run_code(); /* execute the instruction */ ! 134: } ! 135: } ! 136: ! 137: ! 138: ! 139: ! 140: /******************************************************************* ! 141: * REGISTER + LONGWORD DISPLACEMENT DEFERRED ADDRESSING: ! 142: * instruction = <op-code> <f4> <(longword &ptr_to_op_1 -r4)> ! 143: * { <f5> <(longword &ptr_to_op_2 -r5)> } ! 144: * { <f6> <(longword &ptr_to_op_3 -r6)> } ! 145: *******************************************************************/ ! 146: tst_r_ld() ! 147: { ! 148: pipe_test = FALSE; ! 149: fill_reg_buf( load_regs ); /* set data for registers */ ! 150: fill_reg_buf( exp_regs ); /* set data for registers */ ! 151: addr_mode = ADR_REG_L_DEF; ! 152: addr_code = 0xf4; /* addr 1 is offset by r4 */ ! 153: addr_code2 = 0xf5; /* addr 2 is offset by r5 */ ! 154: addr_code3 = 0xf6; /* addr 3 is offset by r6 */ ! 155: addr_size = 4; /* longword (4 byte) op. */ ! 156: addr_1 = (int) adr_op1_ptr - 123; /* set the 1st offset */ ! 157: addr_2 = (int) adr_op2_ptr - 212; /* set the 2nd offset */ ! 158: addr_3 = (int) adr_op3_ptr - 256; /* set the 3rd offset */ ! 159: pack_inst(); /* pack the instr. code */ ! 160: load_regs[4] = 123; /* reg 4 = 123 */ ! 161: load_regs[5] = 212; /* reg 5 = 212 */ ! 162: load_regs[6] = 256; /* reg 5 = 212 */ ! 163: exp_regs[4] = load_regs[4]; ! 164: exp_regs[5] = load_regs[5]; ! 165: exp_regs[6] = load_regs[6]; ! 166: for( index = 0; index <= max_index; index++ ) { ! 167: get_current_data( adr_op1, adr_op2 ); ! 168: run_code(); /* execute the instruction */ ! 169: } ! 170: } ! 171: ! 172: ! 173: ! 174: /******************************************************************* ! 175: * FRAME POINTER DEFERRED + LONGWORD INDEX ADDRESSING: ! 176: * instruction = <op-code> <44> <6d> { <45> <6d> <46> <6d> } ! 177: * ! 178: * The indeces used will be either quadword indeces ( for DBL operands ) ! 179: * of longword indeces ( for SGL operands ). ! 180: * ! 181: * NOTE: ! 182: * dmp_op_2 is exactly 4 pages away from dmp_op_1. (200 hex quadwords) ! 183: * IF THIS RELATIVE DISPLACEMENT IS CHANGED THEN THE R5 INDEX MUST ! 184: * BE CHANGED IN THIS CODE!!! ( used by CMPF2, CMPD2, MULL2, MULL3 ) ! 185: * dmp_op_3 is exactly 5 pages and 4 bytes away from dmp_op_1 (501 hex ! 186: * longwords). This is needed for MULL3. ! 187: *******************************************************************/ ! 188: tst_x_fpd() ! 189: { ! 190: pipe_test = FALSE; ! 191: fill_reg_buf( load_regs ); /* set data for registers */ ! 192: fill_reg_buf( exp_regs ); /* set data for registers */ ! 193: addr_mode = ADR_I_FP_DEF; ! 194: addr_code = 0x44; /* code for reg. 4 index */ ! 195: addr_code2 = 0x45; /* code for reg. 5 index */ ! 196: addr_code3 = 0x46; /* code for reg. 6 index */ ! 197: addr_codeB = 0x6d; /* code for FP deferred */ ! 198: addr_size = 0; /* no addr. field per se */ ! 199: pack_inst(); /* pack the instr. code */ ! 200: /* ! 201: * set the frame pointer to '&operand_1 - 16 bytes' (2 quad-words) ! 202: */ ! 203: sgl_dummy1 = (int) adr_op1; /* get the addr of op #1 */ ! 204: load_regs[13] = sgl_dummy1-16; /* FP = op 1's addr - 16 */ ! 205: exp_regs[13] = load_regs[13]; ! 206: if( (sgl_op) || /* Should we use a longword */ ! 207: (op_code == LDFD_OP_CODE) || /* or a quadword index? */ ! 208: (op_code == CVLD_OP_CODE) ) { ! 209: load_regs[4] = 4; /* FP to op_1 (longwords) */ ! 210: load_regs[5] = 0x404; /* FP to op_2 (longwords) */ ! 211: load_regs[6] = 0x505; /* FP to op_3 (longwords) */ ! 212: } else { ! 213: load_regs[4] = 2; /* FP to op_1 (quadwords) */ ! 214: load_regs[5] = 0x202; /* FP to op_2 (quadwords) */ ! 215: } ! 216: exp_regs[4] = load_regs[4]; ! 217: exp_regs[5] = load_regs[5]; ! 218: exp_regs[6] = load_regs[6]; ! 219: for( index = 0; index <= max_index; index++ ) { ! 220: get_current_data( adr_op1, adr_op2 ); ! 221: run_code(); /* execute the instruction */ ! 222: } ! 223: } ! 224: ! 225: ! 226: ! 227: ! 228: /******************************************************************* ! 229: * PIPELINE TEST #1 -LOAD THE ACCUMULATOR JUST BEFORE THE OPERATION ! 230: * instruction = <ldx> <62> <op-code> <50> { <54> <56> } ! 231: *******************************************************************/ ! 232: tst_p1() ! 233: { ! 234: pipe_test = 1; /* pipeline test #1 */ ! 235: if( acc_ld_size == DBL ) ! 236: pipe_inst1 = LDD_OP_CODE; ! 237: else ! 238: pipe_inst1 = LDF_OP_CODE; ! 239: fill_reg_buf( load_regs ); /* set data for registers */ ! 240: fill_reg_buf( exp_regs ); /* set data for registers */ ! 241: if( op_code == MULL3_OP_CODE ) ! 242: exp_regs[6] = 0; /* op 3 s/b = 0 if MULL3 */ ! 243: addr_code_p1 = 0x62; /* piped load is via reg 2 */ ! 244: load_regs[2] = (int)&dbl_ld_acc; /* point R2 to the load data */ ! 245: exp_regs[2] = (int)&dbl_ld_acc; ! 246: addr_mode = ADR_REG; ! 247: addr_code = 0x50; /* 1st op in registers 0/1 */ ! 248: addr_code2 = 0x54; /* 2nd op in registers 4/5 */ ! 249: addr_code3 = 0x56; /* 3rd op in register 6 */ ! 250: addr_size = 0; /* no addressing bytes */ ! 251: pack_inst(); /* pack the instr. code */ ! 252: for( index = 0; index <= max_index; index++ ) { ! 253: get_current_data( adr_op1, adr_op2 ); /* addr's not used */ ! 254: load_regs[0] = dbl_value_1.m; /* set the data */ ! 255: load_regs[1] = dbl_value_1.l; ! 256: load_regs[4] = dbl_value_2.m; ! 257: load_regs[5] = dbl_value_2.l; ! 258: if( op_code == MULL2_OP_CODE ) ! 259: exp_regs[4] = 0; /* op 2 s/b = 0 if MULL2 */ ! 260: else ! 261: exp_regs[4] = dbl_value_2.m; ! 262: exp_regs[5] = dbl_value_2.l; ! 263: exp_regs[1] = dbl_value_1.l; /* op #1's LSW won't change */ ! 264: if( (op_code == CVFL_OP_CODE) || /* correct for sgl store */ ! 265: (op_code == CVDL_OP_CODE) ) ! 266: exp_regs[0] = 0; /* fault results are cleared */ ! 267: else ! 268: exp_regs[0] = dbl_value_1.m; ! 269: run_code(); /* execute the instruction */ ! 270: } ! 271: pipe_test = FALSE; ! 272: } ! 273: ! 274: ! 275: ! 276: ! 277: ! 278: /******************************************************************* ! 279: * PIPELINE TEST #2 -ADD TO THE ACCUMULATOR JUST BEFORE THE OPERATION ! 280: * instruction = <addx> <62> <op-code> <50> { <54> <56> } ! 281: *******************************************************************/ ! 282: tst_p2() ! 283: { ! 284: pipe_test = 2; /* pipeline test #2 */ ! 285: if( acc_ld_size == DBL ) ! 286: pipe_inst1 = ADDD_OP_CODE; ! 287: else ! 288: pipe_inst1 = ADDF_OP_CODE; ! 289: fill_reg_buf( load_regs ); /* set data for registers */ ! 290: fill_reg_buf( exp_regs ); /* set data for registers */ ! 291: addr_code_p1 = 0x62; /* piped load is via reg 2 */ ! 292: load_regs[2] = (int)&dbl_ld_acc; /* point R2 to the load data */ ! 293: exp_regs[2] = (int)&dbl_ld_acc; ! 294: if( op_code == MULL3_OP_CODE ) ! 295: exp_regs[6] = 0; /* op 3 s/b = 0 */ ! 296: addr_mode = ADR_REG; ! 297: addr_code = 0x50; /* 1st op in registers 0/1 */ ! 298: addr_code2 = 0x54; /* 2nd op in registers 4/5 */ ! 299: addr_code3 = 0x56; /* 3rd op in register 6 */ ! 300: addr_size = 0; /* no addressing bytes */ ! 301: pack_inst(); /* pack the instr. code */ ! 302: for( index = 0; index <= max_index; index++ ) { ! 303: get_current_data( adr_op1, adr_op2 ); /* addr's not used */ ! 304: load_regs[0] = dbl_value_1.m; /* set the data */ ! 305: load_regs[1] = dbl_value_1.l; ! 306: load_regs[4] = dbl_value_2.m; ! 307: load_regs[5] = dbl_value_2.l; ! 308: if( op_code == MULL2_OP_CODE ) ! 309: exp_regs[4] = 0; /* op 2 s/b = 0 */ ! 310: else ! 311: exp_regs[4] = dbl_value_2.m; /* op #2 s/n change */ ! 312: exp_regs[5] = dbl_value_2.l; ! 313: exp_regs[1] = dbl_value_1.l; /* op #1's LSW won't change */ ! 314: if( (op_code == CVFL_OP_CODE) || /* correct for sgl store */ ! 315: (op_code == CVDL_OP_CODE) ) ! 316: exp_regs[0] = 0; /* fault results are cleared */ ! 317: else ! 318: exp_regs[0] = dbl_value_1.m; ! 319: run_code(); /* execute the instruction */ ! 320: } ! 321: pipe_test = FALSE; ! 322: } ! 323: ! 324: ! 325: ! 326: ! 327: ! 328: ! 329: ! 330: /*************************************************************************** ! 331: * Get the Current Data Values ! 332: * ! 333: * In most cases the first operand is loaded into the accumulator. ! 334: * If we're testing Reserved Operands then, unless it's LOGF, we'd better not ! 335: * load the Accumulator with the Resop before executing the instruction. ! 336: * Ergo and towit, we'll use a dummy Acc. for those cases. ! 337: * The 4 instructions currently tested that have 2 or more operands are: ! 338: * CMPF2, CMPD2, MULL2, MULL3. None of these accesses the accumulator so we'll ! 339: * use dummy accumulator data for these too. ! 340: ***************************************************************************/ ! 341: get_current_data( dptr_1, dptr_2 ) ! 342: struct u64 *dptr_1; /* pointer to 1st operand */ ! 343: struct u64 *dptr_2; /* pointer to 2nd operand */ ! 344: { ! 345: if( (no_ops >= 2) || ! 346: ((test_event == RESOP_CODE) && (op_code != LOGF_OP_CODE)) ) { ! 347: dbl_ld_acc = acc_data[ index ]; ! 348: dbl_value_1 = data_ptr[ index ].op_1; ! 349: dbl_value_2 = data_ptr[ index ].op_2; ! 350: } else { ! 351: dbl_ld_acc = data_ptr[ index ].op_1; ! 352: dbl_value_1 = data_ptr[ index ].op_2; ! 353: dbl_value_2 = dbl_value_1; ! 354: } ! 355: *dptr_1 = dbl_value_1; /* set 1st operand */ ! 356: *dptr_2 = dbl_value_2; /* set 2nd operand */ ! 357: } ! 358: ! 359: ! 360: ! 361: ! 362: /* ! 363: *************************************************************************** ! 364: * ! 365: * Set or reset the LOAD_ACCUMULATOR flag ! 366: * ! 367: * If the current instruction loads the accumulator then set the flag. ! 368: *************************************************************************** ! 369: */ ! 370: set_load_flag() ! 371: { ! 372: if( (op_code == LDF_OP_CODE) || /* load SGL Acc. */ ! 373: (op_code == LNF_OP_CODE) || /* load / negate SGL Acc. */ ! 374: (op_code == LDD_OP_CODE) || /* load SGL Acc. */ ! 375: (op_code == LND_OP_CODE) || /* load / negate SGL Acc. */ ! 376: (op_code == LDFD_OP_CODE) ) /* load SGL to DBL Acc. */ ! 377: load_type_inst = TRUE; ! 378: else ! 379: load_type_inst = FALSE; ! 380: } ! 381:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.