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