|
|
Power 6/32 Unix version 1.21
#include "dmp_defs.h"
/**************************************************************************
*
* Test the current instruction
*
* If the current instruction accesses any operands, then test it with
* all major applicable addressing modes.
*
* NOTE: Pipline tests 3 & 4 are not run with the "no-fpp" firmware because
* the ADDs would cause traps. They are not run with certain "load
* type instructions because of a hardware restriction (an ADDF
* followed by an LDF will cause a floating overflow event).
*
* 30-Apr-85 added pipelined instruction tests
* 17-May-85 don't run pre-piped stuff w/ LDF, LNF (ovfl errors)
* 21-Jun-85 added 3rd operand for MULL3
**************************************************************************/
test_inst()
{
/*
* Set the values for the indirect pointers
*/
*adr_op1_ptr = (int) adr_op1; /* set word offset ptr #1 */
*adr_op2_ptr = (int) adr_op2; /* set word offset ptr #2 */
*adr_op3_ptr = (int) adr_op3; /* set word offset ptr #3 */
error = FALSE; /* clear the error flag */
set_load_flag(); /* set/reset load Acc flag */
if( !no_ops )
test_0_ops(); /* test inst w/ no operands */
else {
tst_abs(); /* absolute addressing */
if( s_to_d ||
( (precision == SGL) && (op_type == LOAD) ) )
tst_i_l(); /* immediate longword */
tst_b(); /* byte displacement relative */
tst_w(); /* word displacement relative */
tst_l(); /* longword displacement relative */
tst_b_d(); /* byte disp. relative deferred */
tst_w_d(); /* word disp. relative deferred */
tst_l_d(); /* longword disp. rel. deferred */
tst_r(); /* direct register */
tst_r_d(); /* register deferred */
if( user_mode ) { /* do stack stuff in user mode only */
if( (op_code == MULL2_OP_CODE) ||
(op_code == MULL3_OP_CODE) ) {
tst_mull_stack(); /* POP, POP, PUSH */
tst_pop_d(); /* deferred POP */
}
else if( d_to_s ||
( (precision == SGL) && (op_type == STORE) ) ) {
tst_push(); /* PUSH ( auto-decremented SP ) */
tst_pop_d(); /* deferred POP */
}
else if( s_to_d ||
( (precision == SGL) && (op_type == LOAD) ) ) {
tst_pop(); /* POP ( auto-incremented SP ) */
tst_pop_d(); /* deferred POP */
}
}
tst_r_b(); /* register + byte displacement */
tst_r_w(); /* register + word displacement */
tst_r_l(); /* register + longword disp. */
tst_r_bd(); /* reg. + byte disp. deferred */
tst_r_wd(); /* reg. + word disp. deferred */
tst_r_ld(); /* reg. + longword disp. deferred */
tst_x_fpd(); /* FP deferred + longword index */
tst_x_l(); /* longword disp. + longword index */
if( !no_fpp_wcs ) {
tst_p1(); /* pipe 1 - load w/ register data */
tst_p2(); /* pipe 2 - load w/ lw addressing */
if( ( op_code != LDF_OP_CODE ) &&
( op_code != LNF_OP_CODE ) &&
( op_code != CVLF_OP_CODE ) ) {
tst_p3(); /* pipe 3 - mulx w/ register data */
tst_p4(); /* pipe 4 - mulx w/ lw addressing */
}
} /* end IF not no-fpp */
} /* end IF one or more operands */
}
/*******************************************************************
* ABSOLUTE ADDRESSING:
* instr = <op-code> <9f> <&dmp_op_1> {<9f> <&dmp_op_2> <9f> <&dmp_op_3>}
*******************************************************************/
tst_abs()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_ABSOLUTE;
addr_code = addr_code2 = addr_code3 = 0x9f;
addr_size = 4; /* longword (4 byte) ops. */
addr_1 = DMP_OP_1; /* abs. address of data */
addr_2 = DMP_OP_2;
addr_3 = DMP_OP_3;
if( no_ops == 1 )
min_shift = 15;
else if( no_ops == 2 )
min_shift = 10;
else
min_shift = 5;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault cnt */
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* IMMEDIATE LONGWORD ADDRESSING: ( sgl and sgl_to_dbl only )
* instr = <op-code> <8f> <data> { <8f> <data> <8f> <data> }
*
* NOTE: If the instruction is MULL2, op #2 will use absolute addressing.
* If the instruction is MULL3, op #3 will use absolute addressing.
*******************************************************************/
tst_i_l()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_IM_L;
addr_code = addr_code2 = 0x8f;
addr_code3 = 0x9f; /* MULL3 uses ABS for op #3 */
addr_3 = DMP_OP_3; /* addr_3 points to DMP_OP3 */
if( op_code == MULL2_OP_CODE ) {
addr_code2 = 0x9f; /* MULL2 uses ABS for op #2 */
addr_2 = DMP_OP_2; /* addr_2 points to DMP_OP2 */
}
addr_size = 4; /* longword (4 byte) data */
if( (op_code == MULL2_OP_CODE) || (op_code == MULL3_OP_CODE) )
exp_page_faults = 3; /* 3 pages are used */
else
exp_page_faults = 2; /* 2 pages are used */
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
addr_1 = dbl_value_1.m; /* set the 1st operand */
if( op_code != MULL2_OP_CODE )
addr_2 = dbl_value_2.m; /* set the 2nd operand */
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* BYTE DISPLACEMENT RELATIVE ADDRESSING:
* instr = <op-code> <af> <offset to dmp_byte_op_1>
* { <af> <offset to dmp_byte_op_2> }
* { <af> <offset to dmp_byte_op_3> }
*******************************************************************/
tst_b()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_B_DSP;
addr_code = addr_code2 = addr_code3 = 0xaf;
addr_size = 1; /* 1 byte operand */
exp_page_faults = 2; /* 2 pages are used */
if( no_ops == 1 )
min_shift = 17;
else if( no_ops == 2 )
min_shift = 15;
else
min_shift = 13;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_b_op1, adr_b_op2 );
addr_1 = os_b_op1 + 17 - shift_count; /* data's offset */
addr_2 = os_b_op2 + 15 - shift_count;
addr_3 = os_b_op3 + 13 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* WORD DISPLACEMENT RELATIVE ADDRESSING:
* instruction = <op-code> <cf> <offset to dmp_op_1>
* { <cf> <offset to dmp_op_2> }
* { <cf> <offset to dmp_op_3> }
*******************************************************************/
tst_w()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_W_DSP;
addr_code = addr_code2 = addr_code3 = 0xcf;
addr_size = 2; /* word (2 byte) operand */
if( no_ops == 1 )
min_shift = 17;
else if( no_ops == 2 )
min_shift = 14;
else
min_shift = 11;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault cnt */
addr_1 = os_op1 + 16 - shift_count; /* data's offset */
addr_2 = os_op2 + 13 - shift_count;
addr_3 = os_op3 + 10 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* LONGWORD DISPLACEMENT RELATIVE ADDRESSING:
* instruction = <op-code> <ef> <offset to dmp_op_1>
* { <ef> <offset to dmp_op_2> }
* { <ef> <offset to dmp_op_3> }
*******************************************************************/
tst_l()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_L_DSP;
addr_code = addr_code2 = addr_code3 = 0xef;
addr_size = 4; /* longword (4 byte) ops. */
if( no_ops == 1 )
min_shift = 15;
else if( no_ops == 2 )
min_shift = 10;
else
min_shift = 5;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
addr_1 = os_op1 + 14 - shift_count; /* data's offset */
addr_2 = os_op2 + 9 - shift_count;
addr_3 = os_op3 + 4 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* BYTE DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
* instruction = <op-code> <bf> <offset to dmp_byte_op_1>
* { <bf> <offset to dmp_byte_op_2> }
* { <bf> <offset to dmp_byte_op_3> }
*******************************************************************/
tst_b_d()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_B_DSP_DEF;
addr_code = addr_code2 = addr_code3 = 0xbf;
addr_size = 1; /* 1 byte operand */
adr_b_op1->m = (int) adr_op1; /* set byte offset ptr #1 */
adr_b_op2->m = (int) adr_op2; /* set byte offset ptr #2 */
adr_b_op3->m = (int) adr_op3; /* set byte offset ptr #3 */
if( no_ops == 1 )
min_shift = 17;
else if( no_ops == 2 )
min_shift = 15;
else
min_shift = 13;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
addr_1 = os_b_op1 + 17 - shift_count; /* data's offset */
addr_2 = os_b_op2 + 15 - shift_count;
addr_3 = os_b_op3 + 13 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* WORD DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
* instruction = <op-code> <df> <offset to dmp_op_1_ptr>
* { <df> <offset to dmp_op_2_ptr> }
* { <df> <offset to dmp_op_3_ptr> }
*******************************************************************/
tst_w_d()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_W_DSP_DEF;
addr_code = addr_code2 = addr_code3 = 0xdf;
addr_size = 2; /* word (2 byte) operand */
if( no_ops == 1 )
min_shift = 17;
else if( no_ops == 2 )
min_shift = 14;
else
min_shift = 11;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
addr_1 = os_ad_op1 + 16 - shift_count; /* operand offset */
addr_2 = os_ad_op2 + 13 - shift_count;
addr_3 = os_ad_op3 + 10 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* LONGWORD DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
* instruction = <op-code> <ff> <offset to dmp_op_1_ptr>
* { <ff> <offset to dmp_op_2_ptr> }
* { <ff> <offset to dmp_op_3_ptr> }
*******************************************************************/
tst_l_d()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_L_DSP_DEF;
addr_code = addr_code2 = addr_code3 = 0xff;
addr_size = 4; /* longword (4 byte) op. */
if( no_ops == 1 )
min_shift = 15;
else if( no_ops == 2 )
min_shift = 10;
else
min_shift = 5;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
addr_1 = os_ad_op1 + 14 - shift_count; /* operand offset */
addr_2 = os_ad_op2 + 9 - shift_count;
addr_3 = os_ad_op3 + 4 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* DIRECT REGISTER ADDRESSING:
* instruction = <op-code> <50> { <54> } { <56> }
*
* If the instruction = MULL2 the store will be to R4,
* If the instruction = MULL3 the store will be to R6,
* If the instruction is any other store it will be to R0/R1.
*******************************************************************/
tst_r()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_REG;
addr_code = 0x50; /* 1st op in registers 0/1 */
addr_code2 = 0x54; /* 2nd op in registers 4/5 */
addr_code3 = 0x56; /* 3rd op in register 6 */
addr_size = 0; /* no addressing bytes */
pack_inst(); /* pack the instr. code */
exp_page_faults = 2; /* 2 pages are used */
if( no_ops == 1 )
min_shift = 19;
else if( no_ops == 2 )
min_shift = 18;
else
min_shift = 17;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
load_regs[0] = dbl_value_1.m; /* set the data for the regs*/
load_regs[1] = dbl_value_1.l;
load_regs[4] = dbl_value_2.m;
load_regs[5] = dbl_value_2.l;
exp_regs[0] = load_regs[0]; /* set exp final reg values */
exp_regs[1] = load_regs[1];
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
if( op_code == MULL2_OP_CODE )
exp_regs[4] = dbl_expected.m;
else if( op_code == MULL3_OP_CODE )
exp_regs[6] = dbl_expected.m;
else if( op_type == STORE ) {
exp_regs[0] = dbl_expected.m;
exp_regs[1] = dbl_expected.l;
}
if( op_code == CVDL_OP_CODE ) /* correct for sgl store */
exp_regs[1] = dbl_value_1.l; /* r1 shouldn't change */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* REGISTER DEFERRED ADDRESSING:
* instruction = <op-code> <60> { <61> <62> }
*******************************************************************/
tst_r_d()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_REG_DEF;
addr_code = 0x60;
addr_code2 = 0x61;
addr_code3 = 0x62;
addr_size = 0; /* no address byte(s) */
load_regs[0] = (int) adr_op1; /* get addr of op. 1 */
load_regs[1] = (int) adr_op2; /* get addr of op. 2 */
load_regs[2] = (int) adr_op3; /* get addr of op. 3 */
exp_regs[0] = load_regs[0];
exp_regs[1] = load_regs[1];
exp_regs[2] = load_regs[2];
pack_inst(); /* pack the instr. code */
if( no_ops == 1 )
min_shift = 19;
else if( no_ops == 2 )
min_shift = 18;
else
min_shift = 17;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* AUTO-DECREMENTED STACK POINTER ADDRESSING ( PUSH ):
* instruction = <op-code> <7e>
*
* The final result will be popped by "run_code".
* Push will be run with SGL instructions only.
* "DBL_VALUE_4", the final result, will be set by RUN_CODE.
*******************************************************************/
tst_push()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_PUSH;
addr_code = 0x7e;
addr_size = 0; /* no addressing bytes */
exp_page_faults = 3; /* 3 pages are used */
shift_count = 19;
pack_inst(); /* pack the instr. code */
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
run_code(); /* execute the instruction */
if( force_loop )
run_code(); /* start the error loop */
}
}
/*******************************************************************
* AUTO-INCREMENTED STACK POINTER ADDRESSING ( POP ): ( sgl ops only )
* instruction = <op-code> <8e>
*
* The data will be pushed by "run_code"
* Pop will be run with SGL floating point instructions only. A different
* routine will be used for the integer multiply instructions.
*******************************************************************/
tst_pop()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_POP;
addr_code = addr_code2 = 0x8e;
addr_size = 0; /* no addressing bytes */
pack_inst(); /* pack the instr. code */
if( no_ops == 1 ) {
min_shift = 19;
exp_page_faults = 3; /* 3 pages are used */
} else { /* 2 operands */
min_shift = 18;
exp_page_faults = 4; /* 4 pages are used */
}
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
sgl_value_8 = dbl_value_1.m; /* data to be pushed */
sgl_value_9 = dbl_value_2.m; /* data to be pushed */
run_code(); /* execute the instruction */
if( force_loop )
run_code(); /* start the error loop */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* STACK ADDRESSING TEST FOR THE MULL2 AND MULL3 INTEGER MULTIPLY INSTRUCTIONS
*
* For MULL2, operand 1 will be popped from the stack and
* operand 2 will be in memory
*
* For MULL3, operands 1 and 2 will be popped from the stack and
* operand 3 will be in pushed back onto the stack.
*
* The stack data will be pushed by "run_code"
*******************************************************************/
tst_mull_stack()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_size = 0; /* no addressing bytes */
addr_mode = ADR_POP;
addr_code = 0x8e; /* auto increment SP (POP) */
if( op_code == MULL2_OP_CODE )
addr_code2 = 0x60; /* R0 (deferred) addressing */
else
addr_code2 = 0x8e; /* auto increment SP (POP) */
addr_code3 = 0x7e; /* auto decrement SP (PUSH) */
load_regs[0] = (int) adr_op2; /* set R0 to addr of op #2 */
exp_regs[0] = load_regs[0];
pack_inst(); /* pack the instr. code */
exp_page_faults = 4; /* 4 pages are used */
if( no_ops == 2 )
min_shift = 18; /* MULL2 */
else
min_shift = 17; /* MULL3 */
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
if( op_code == MULL2_OP_CODE )
sgl_value_8 = dbl_value_1.m; /* push operand 1 only */
else {
sgl_value_8 = dbl_value_1.m; /* push both of */
sgl_value_9 = dbl_value_2.m; /* the operands */
}
run_code(); /* execute the instruction */
if( force_loop )
run_code(); /* start the error loop */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* AUTO-INCREMENTED STACK POINTER DEFERRED ADDRESSING:
* instruction = <op-code> <9e> { <9e> <9e> }
*
* The address(es) of the data will be pushed by "run_code"
*******************************************************************/
tst_pop_d()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_POP_DEF;
addr_code = addr_code2 = addr_code3 = 0x9e;
addr_size = 0; /* no addressing bytes */
pack_inst(); /* pack the instr. code */
sgl_value_8 = (int) adr_op1; /* get 1st op's address */
sgl_value_9 = (int) adr_op2; /* get 2nd op's address */
sgl_value_10 = (int) adr_op3; /* get 3rd op's address */
if( no_ops == 1 )
min_shift = 19;
else if( no_ops == 2 )
min_shift = 18;
else
min_shift = 17;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 4, 5, 6, 7, 7 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* REGISTER + BYTE DISPLACEMENT ADDRESSING:
* instruction = <op-code> <a4> <(&op_1 -r4)>
* { <a5> <(&op_2- r5)> }
* { <a6> <(&op_3- r6)> }
*******************************************************************/
tst_r_b()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_REG_B;
addr_code = 0xa4; /* addr 1 is offset by r4 */
addr_code2 = 0xa5; /* addr 2 is offset by r5 */
addr_code3 = 0xa6; /* addr 3 is offset by r6 */
addr_size = 1; /* 1 byte operand */
addr_1 = 20; /* set the 1st byte offset */
addr_2 = 4; /* set the 2nd byte offset */
addr_3 = 16; /* set the 3rd byte offset */
pack_inst(); /* pack the instr. code */
load_regs[4] = (int) adr_op1 - 20; /* get the reg value */
load_regs[5] = (int) adr_op2 - 4;
load_regs[6] = (int) adr_op3 - 16;
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
exp_regs[6] = load_regs[6];
if( no_ops == 1 )
min_shift = 18;
else if( no_ops == 2 )
min_shift = 16;
else
min_shift = 14;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* REGISTER + WORD DISPLACEMENT ADDRESSING:
* instruction = <op-code> <c4> <(&op_1 -r4)>
* { <c5> <(&op_2 -r5)> }
* { <c6> <(&op_3 -r6)> }
*******************************************************************/
tst_r_w()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_REG_W;
addr_code = 0xc4; /* addr 1 is offset by r4 */
addr_code2 = 0xc5; /* addr 2 is offset by r5 */
addr_code3 = 0xc6; /* addr 3 is offset by r6 */
addr_size = 2; /* word (2 byte) operand */
addr_1 = 511; /* set the 1st word offset */
addr_2 = 513; /* set the 2nd word offset */
addr_3 = 600; /* set the 3rd word offset */
pack_inst(); /* pack the instr. code */
load_regs[4] = (int) adr_op1 - 511; /* get the reg value */
load_regs[5] = (int) adr_op2 - 513;
load_regs[6] = (int) adr_op3 - 600;
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
exp_regs[6] = load_regs[6];
if( no_ops == 1 )
min_shift = 17;
else if( no_ops == 2 )
min_shift = 14;
else
min_shift = 11;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* REGISTER + LONGWORD DISPLACEMENT ADDRESSING:
* instruction = <op-code> <e4> <(&op_1 -r4)>
* { <e5> <(&op_2 -r5)> }
* { <e6> <(&op_3 -r6)> }
*******************************************************************/
tst_r_l()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_REG_L;
addr_code = 0xe4; /* addr 1 is offset by r4 */
addr_code2 = 0xe5; /* addr 2 is offset by r5 */
addr_code3 = 0xe6; /* addr 3 is offset by r6 */
addr_size = 4; /* longword (4 byte) op. */
addr_1 = (int) adr_op1 - 123; /* get the 1st addr base */
addr_2 = (int) adr_op2 - 130; /* get the 2nd addr base */
addr_3 = (int) adr_op3 - 255; /* get the 3rd addr base */
load_regs[4] = 123; /* reg 4 = 123 */
exp_regs[4] = 123;
load_regs[5] = 130; /* reg 5 = 130 */
exp_regs[5] = 130;
load_regs[6] = 255; /* reg 5 = 255 */
exp_regs[6] = 255;
pack_inst(); /* pack the instr. code */
if( no_ops == 1 )
min_shift = 15;
else if( no_ops == 2 )
min_shift = 10;
else
min_shift = 5;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* REGISTER + BYTE DISPLACEMENT DEFERRED ADDRESSING:
* instruction = <op-code> <b4> <(&ptr_to_op_3 -r4)>
* { <b5> <(&ptr_to_op_3 -r5)> }
* { <b6> <(&ptr_to_op_3 -r6)> }
*******************************************************************/
tst_r_bd()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_REG_B_DEF;
addr_code = 0xb4; /* addr 1 is offset by r4 */
addr_code2 = 0xb5; /* addr 2 is offset by r5 */
addr_code3 = 0xb6; /* addr 3 is offset by r6 */
addr_size = 1; /* 1 byte operand */
addr_1 = 20; /* set the 1st byte offset */
addr_2 = 4; /* set the 2nd byte offset */
addr_3 = 16; /* set the 3rd byte offset */
pack_inst(); /* pack the instr. code */
load_regs[4] = (int) adr_op1_ptr - 20; /* get the reg value */
load_regs[5] = (int) adr_op2_ptr - 4;
load_regs[6] = (int) adr_op3_ptr - 16;
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
exp_regs[6] = load_regs[6];
if( no_ops == 1 )
min_shift = 18;
else if( no_ops == 2 )
min_shift = 16;
else
min_shift = 14;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* REGISTER + WORD DISPLACEMENT DEFERRED ADDRESSING:
* instruction = <op-code> <d4> <(&ptr_to_op_1 -r4)>
* { <d5> <(&ptr_to_op_2 -r5)> }
* { <d6> <(&ptr_to_op_3 -r6)> }
*******************************************************************/
tst_r_wd()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_REG_W_DEF;
addr_code = 0xd4; /* addr 1 is offset by r4 */
addr_code2 = 0xd5; /* addr 2 is offset by r5 */
addr_code3 = 0xd6; /* addr 3 is offset by r6 */
addr_size = 2; /* word (2 byte) operand */
addr_1 = 511; /* set the 1st word offset */
addr_2 = 601; /* set the 2nd word offset */
addr_3 = 1027; /* set the 3rd word offset */
pack_inst(); /* pack the instr. code */
load_regs[4] = (int) adr_op1_ptr - 511; /* get the reg value */
load_regs[5] = (int) adr_op2_ptr - 601;
load_regs[6] = (int) adr_op3_ptr - 1027;
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
exp_regs[6] = load_regs[6];
if( no_ops == 1 )
min_shift = 17;
else if( no_ops == 2 )
min_shift = 14;
else
min_shift = 11;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* REGISTER + LONGWORD DISPLACEMENT DEFERRED ADDRESSING:
* instruction = <op-code> <f4> <(longword &ptr_to_op_1 -r4)>
* { <f5> <(longword &ptr_to_op_2 -r5)> }
* { <f6> <(longword &ptr_to_op_3 -r6)> }
*******************************************************************/
tst_r_ld()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_REG_L_DEF;
addr_code = 0xf4; /* addr 1 is offset by r4 */
addr_code2 = 0xf5; /* addr 2 is offset by r5 */
addr_code3 = 0xf6; /* addr 3 is offset by r6 */
addr_size = 4; /* longword (4 byte) op. */
addr_1 = (int) adr_op1_ptr - 123; /* set the 1st offset */
addr_2 = (int) adr_op2_ptr - 212; /* set the 2nd offset */
addr_3 = (int) adr_op3_ptr - 510; /* set the 3rd offset */
pack_inst(); /* pack the instr. code */
load_regs[4] = 123; /* reg 4 = 123 */
load_regs[5] = 212; /* reg 5 = 212 */
load_regs[6] = 510; /* reg 6 = 510 */
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
exp_regs[6] = load_regs[6];
if( no_ops == 1 )
min_shift = 15;
else if( no_ops == 2 )
min_shift = 10;
else
min_shift = 5;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 4, 5, 6, 8, 8 ); /* set exp fault count */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* FRAME POINTER DEFERRED + LONGWORD INDEX ADDRESSING:
* instruction = <op-code> <44> <6d> { <45> <6d> } { <46> <6d> }
*
* The indeces used will be either quadword indeces ( for DBL operands )
* of longword indeces ( for SGL operands ).
*
* NOTE:
* dmp_op_2 is 4 pages away from dmp_op_1. (200 hex quadwords)
* dmp_op_3 is 5 pages & 4 bytes from dmp_op_1. (501 hex longwords)
* IF THIS RELATIVE DISPLACEMENT IS CHANGED THEN THE R5 AND/OR R6 INDICES
* MUST BE CHANGED IN THIS CODE!!!
* ( The R5 index is used by CMPF2, CMPD2, MULL2, & MULL3.
* The R6 index is used by MULL3. )
*******************************************************************/
tst_x_fpd()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_I_FP_DEF;
addr_code = 0x44; /* code for reg. 4 index */
addr_code2 = 0x45; /* code for reg. 5 index */
addr_code3 = 0x46; /* code for reg. 6 index */
addr_codeB = 0x6d; /* code for FP deferred */
addr_size = 0; /* no addr. field per se */
pack_inst(); /* pack the instr. code */
/*
* set the frame pointer to '&operand_1 - 16 bytes' (2 quad-words)
*/
sgl_dummy1 = (int) adr_op1; /* get the addr of op #1 */
load_regs[13] = sgl_dummy1-16; /* FP = op 1's addr - 16 */
exp_regs[13] = load_regs[13];
if( sgl_op ) {
load_regs[4] = 4; /* FP to op_1 (longwords) */
load_regs[5] = 0x404; /* FP to op_2 (longwords) */
load_regs[6] = 0x505; /* FP to op_2 (longwords) */
} else {
load_regs[4] = 2; /* FP to op_1 (quadwords) */
load_regs[5] = 0x202; /* FP to op_2 (quadwords) */
}
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
exp_regs[6] = load_regs[6];
if( no_ops == 1 )
min_shift = 18;
else if( no_ops == 2 )
min_shift = 16;
else
min_shift = 14;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* INDEXED LONGWORD DISPLACEMENT ADDRESSING:
* instruction = <op-code> <44> <ef> <longword offset>
* { <45> <ef> <longword offset> }
* { <46> <ef> <longword offset> }
*
* NOTE: The index to operand 3 (R6) is only used with MULL3.
*******************************************************************/
tst_x_l()
{
pipe_test = FALSE; /* clear the pipe test flag */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_I_L;
addr_code = 0x44; /* code for reg. 4 index */
addr_code2 = 0x45; /* code for reg. 5 index */
addr_code3 = 0x46; /* code for reg. 6 index */
addr_codeB = 0xef; /* code for longword disp */
addr_size = 4; /* longword (4 byte) op. */
if( sgl_op ) {
load_regs[4] = 4; /* reg 4 = 4 (longwords) */
load_regs[5] = 6; /* reg 5 = 6 (longwords) */
load_regs[6] = 5; /* reg 6 = 5 (longwords) */
} else {
load_regs[4] = 2; /* reg 4 = 2 (quadwords) */
load_regs[5] = 3; /* reg 5 = 3 (quadwords) */
}
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
exp_regs[6] = load_regs[6];
if( no_ops == 1 )
min_shift = 14;
else if( no_ops == 2 )
min_shift = 8;
else
min_shift = 2;
shift_count = 19;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
addr_1 = os_op1 + 13 - shift_count; /* data's offset */
addr_1 -=16; /* -16 bytes (2 Q-words) */
addr_2 = os_op2 + 7 - shift_count; /* data's offset */
addr_2 -=24; /* -24 bytes (3 Q-words) */
addr_3 = os_op3 + 1 - shift_count; /* data's offset */
addr_3 -=20; /* -20 bytes (5 L-words) */
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 19;
}
}
/*******************************************************************
* PIPELINE TEST #1 -DIRECT REGISTER ADDRESSING WITH AN INITIAL LOAD
*
* This test will put a LOAD instruction immediately in front of the
* test instruction and a MULTIPLY instruction immediately behind it.
* The instruction buffer will look like:
*
* <ldf/ldd> <instruction> <mulf/muld> where:
* instruction = <op-code> <50> { <54> } { <58> }
*
* The load will be done through register R6 deferred.
* The multiply addressing mode will be through register R2 deferred.
*******************************************************************/
tst_p1()
{
pipe_test = 1; /* set pipelined test flag to test #3 */
if( acc_ld_size == DBL )
pipe_inst1 = LDD_OP_CODE;
else
pipe_inst1 = LDF_OP_CODE;
if( acc_st_size == DBL )
pipe_inst2 = MULD_OP_CODE;
else
pipe_inst2 = MULF_OP_CODE;
addr_code_p1 = 0x66; /* set the 1st piped addr mode */
addr_code_p2 = 0x62; /* set the 2nd piped addr mode */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
load_regs[2] = (int) adr_op4; /* the MULx is w/ op. #4 */
exp_regs[2] = load_regs[2];
load_regs[6] = (int) adr_op5; /* the LDx is w/ op. #5 */
exp_regs[6] = load_regs[6];
adr_op4->m = 0x40800000; /* set the MULx instr's */
adr_op4->l = 0; /* operand = '1.0' */
addr_mode = ADR_REG;
addr_code = 0x50; /* 1st op in registers 0/1 */
addr_code2 = 0x54; /* 2nd op in registers 4/5 */
addr_code3 = 0x58; /* 3rd op goes to reg. 8 */
addr_size = 0; /* no addressing bytes */
pack_inst(); /* pack the instr. code */
exp_page_faults = 4; /* 4 pages are used */
if( no_ops == 1 )
min_shift = 16;
else if( no_ops == 2 )
min_shift = 15;
else
min_shift = 14;
shift_count = 18;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
adr_op5->m = dbl_ld_acc.m; /* get the data for the */
adr_op5->l = dbl_ld_acc.l; /* load instruction */
load_regs[0] = dbl_value_1.m; /* set the test data */
load_regs[1] = dbl_value_1.l;
load_regs[4] = dbl_value_2.m;
load_regs[5] = dbl_value_2.l;
exp_regs[4] = load_regs[4]; /* set exp final reg value */
exp_regs[5] = load_regs[5];
if( op_type == STORE ) {
exp_regs[0] = dbl_expected.m;
exp_regs[1] = dbl_expected.l;
} else {
exp_regs[0] = dbl_value_1.m;
exp_regs[1] = dbl_value_1.l;
if( op_code == MULL3_OP_CODE )
exp_regs[8] = dbl_expected.m;
if( op_code == MULL2_OP_CODE )
exp_regs[4] = dbl_expected.m;
}
if( op_code == CVDL_OP_CODE ) /* correct for sgl store */
exp_regs[1] = dbl_value_1.l; /* r1 shouldn't change */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 18;
}
pipe_test = FALSE; /* clear the pipe test flag */
}
/*******************************************************************
* PIPELINE TEST #2 -LONGWORD DISP REL ADDRESSING WITH AN INITIAL LOAD
*
* This test will put a LOAD instruction immediately in front of the
* test instruction and a MULTIPLY instruction immediately behind it.
* The instruction buffer will look like:
*
* <ldf/ldd> <instruction> <mulf/muld> where:
* instruction = <op-code> <ef> <offset to dmp_op_1>
* { <ef> <offset to dmp_op_2> }
* { <ef> <offset to dmp_op_3> }
*
* The load's addressing mode will be through register R6 deferred.
* The multiply's addressing mode will be through register R2 deferred.
*******************************************************************/
tst_p2()
{
pipe_test = 2; /* set the piplined test flag to test #4 */
if( acc_ld_size == DBL )
pipe_inst1 = LDD_OP_CODE;
else
pipe_inst1 = LDF_OP_CODE;
if( acc_st_size == DBL )
pipe_inst2 = MULD_OP_CODE;
else
pipe_inst2 = MULF_OP_CODE;
addr_code_p1 = 0x66; /* set the 1st piped addr mode */
addr_code_p2 = 0x62; /* set the 2nd piped addr mode */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
load_regs[2] = (int) adr_op4; /* MULx is via op. #4 */
exp_regs[2] = load_regs[2];
load_regs[6] = (int) adr_op5; /* LDx is via op. #5 */
exp_regs[6] = load_regs[6];
adr_op4->m = 0x40800000; /* set the piped mult's */
adr_op4->l = 0; /* operand = '1.0' */
addr_mode = ADR_L_DSP;
addr_code = addr_code2 = addr_code3 = 0xef;
addr_size = 4; /* longword (4 byte) ops. */
if( no_ops == 1 )
min_shift = 12;
else if( no_ops == 2 )
min_shift = 7;
else
min_shift = 2;
shift_count = 18;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 5, 6, 6, 8, 7 ); /* set exp fault count */
adr_op5->m = dbl_ld_acc.m; /* get the data for the */
adr_op5->l = dbl_ld_acc.l; /* load instruction */
addr_1 = os_op1 + 12 - shift_count;
addr_2 = os_op2 + 7 - shift_count;
addr_3 = os_op3 + 2 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 18;
}
pipe_test = FALSE; /* clear the pipe test flag */
}
/*******************************************************************
* PIPELINE TEST #3 -DIRECT REGISTER ADDRESSING WITH AN INITIAL MULTIPLY
*
* This test will put a MULTIPLY instruction immediately in front of the
* test instruction and a MULTIPLY instruction immediately behind it.
* Both multiplys will be times "1.0".
*
* The instruction buffer will look like:
* <mulf/muld> <instruction> <mulf/muld> where:
* instruction = <op-code> <50> { <54> } { <58> }
*
* The 1st multiply will be done through register R6 deferred.
* The 2nd multiply will be done through register R2 deferred.
*******************************************************************/
tst_p3()
{
pipe_test = 3; /* set pipelined test flag to pipe test #1 */
if( acc_ld_size == DBL )
pipe_inst1 = MULD_OP_CODE;
else
pipe_inst1 = MULF_OP_CODE;
if( acc_st_size == DBL )
pipe_inst2 = MULD_OP_CODE;
else
pipe_inst2 = MULF_OP_CODE;
addr_code_p1 = 0x66; /* set the 1st piped addr mode */
addr_code_p2 = 0x62; /* set the 2nd piped addr mode */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
load_regs[2] = (int) adr_op4; /* 2nd MULx is via op. #4 */
exp_regs[2] = load_regs[2];
load_regs[6] = (int) adr_op5; /* 1st MULx is via op. #5 */
exp_regs[6] = load_regs[6];
adr_op4->m = 0x40800000; /* set the MULx instr's */
adr_op4->l = 0; /* operand = '1.0' */
adr_op5->m = 0x40800000;
adr_op5->l = 0;
addr_mode = ADR_REG;
addr_code = 0x50; /* 1st op in registers 0/1 */
addr_code2 = 0x54; /* 2nd op in registers 4/5 */
addr_code3 = 0x58; /* 3rd op goes to reg. 8 */
addr_size = 0; /* no addressing bytes */
pack_inst(); /* pack the instr. code */
exp_page_faults = 4; /* 4 pages are used */
if( no_ops == 1 )
min_shift = 16;
else if( no_ops == 2 )
min_shift = 15;
else
min_shift = 14;
shift_count = 18;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
load_regs[0] = dbl_value_1.m; /* set the test data */
load_regs[1] = dbl_value_1.l;
load_regs[4] = dbl_value_2.m;
load_regs[5] = dbl_value_2.l;
if( op_code == MULL2_OP_CODE )
exp_regs[4] = dbl_expected.m; /* store to reg #4 */
else
exp_regs[4] = load_regs[4]; /* reg 4 s/n change */
exp_regs[5] = load_regs[5];
if( op_code == MULL3_OP_CODE )
exp_regs[8] = dbl_expected.m; /* store to reg #8 */
if( op_type == LOAD ) {
exp_regs[0] = dbl_value_1.m;
exp_regs[1] = dbl_value_1.l;
} else {
exp_regs[0] = dbl_expected.m;
exp_regs[1] = dbl_expected.l;
}
if( op_code == CVDL_OP_CODE ) /* correct for sgl store */
exp_regs[1] = dbl_value_1.l; /* r1 shouldn't change */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 18;
}
pipe_test = FALSE; /* clear the pipe test flag */
}
/*******************************************************************
* PIPELINE TEST #4 -LONGWORD DISP REL ADDR. WITH AN INITIAL MULTIPLY
*
* This test will put MULTIPLY instructions immediately in front of and
* behind the test instruction.
* The instruction buffer will look like:
*
* <mulf/muld> <instruction> <mulf/muld> where:
* instruction = <op-code> <ef> <offset to dmp_op_1>
* { <ef> <offset to dmp_op_2> }
* { <ef> <offset to dmp_op_3> }
*
* The 1st multiply's addressing will be through register R6 deferred.
* The 2nd multiply's addressing will be through register R2 deferred.
*******************************************************************/
tst_p4()
{
pipe_test = 4; /* set the piplined flag to test # 2 */
if( acc_ld_size == DBL )
pipe_inst1 = MULD_OP_CODE;
else
pipe_inst1 = MULF_OP_CODE;
if( acc_st_size == DBL )
pipe_inst2 = MULD_OP_CODE;
else
pipe_inst2 = MULF_OP_CODE;
addr_code_p1 = 0x66; /* set the 1st piped addr mode */
addr_code_p2 = 0x62; /* set the 2nd piped addr mode */
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
load_regs[2] = (int) adr_op4; /* 2nd MULx is w/ op. #4 */
exp_regs[2] = load_regs[2];
load_regs[6] = (int) adr_op5; /* 1st MULx is w/ op. #5 */
exp_regs[6] = load_regs[6];
adr_op4->m = 0x40800000; /* set the piped mult's */
adr_op4->l = 0; /* operand = '1.0' */
adr_op5->m = 0x40800000;
adr_op5->l = 0;
addr_mode = ADR_L_DSP;
addr_code = addr_code2 = addr_code3 = 0xef;
addr_size = 4; /* longword (4 byte) ops. */
if( no_ops == 1 )
min_shift = 12;
else if( no_ops == 2 )
min_shift = 7;
else
min_shift = 2;
shift_count = 18;
for( index = 0; index <= max_index; index++ ) {
get_current_data( adr_op1, adr_op2 );
get_exp_faults( 5, 6, 6, 8, 7 ); /* set exp fault count */
addr_1 = os_op1 + 12 - shift_count; /* data's offset */
addr_2 = os_op2 + 7 - shift_count;
addr_3 = os_op3 + 2 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
if( --shift_count < min_shift )
shift_count = 18;
}
pipe_test = FALSE; /* clear the pipe test flag */
}
/*
***************************************************************************
*
* GET DATA FOR DOUBLE PRECISION INSTRUCTIONS
*
***************************************************************************
*/
get_current_data( dptr_1, dptr_2 )
struct u64 *dptr_1; /* pointer to 1st operand */
struct u64 *dptr_2; /* pointer to 2nd operand */
{
if( no_ops == 1 ) {
dbl_ld_acc = data_ptr[index].op_1;
dbl_value_1 = data_ptr[index].op_2;
dbl_expected = data_ptr[index].exp;
*dptr_1 = dbl_value_1; /* set the operand */
} else if( no_ops == 2 ) {
if( index < (ldf_cnt -1) )
dbl_ld_acc = ldd_data[index+1].op_1;
else
dbl_ld_acc = ldd_data[index & 0xf].op_1;
dbl_value_1 = data_ptr[index].op_1;
dbl_value_2 = data_ptr[index].op_2;
dbl_expected = data_ptr[index].exp;
*dptr_1 = dbl_value_1; /* set 1st operand */
*dptr_2 = dbl_value_2; /* set 2nd operand */
} else { /* 3 operands */
if( index < (ldf_cnt -1) )
dbl_ld_acc = ldd_data[index +1].op_1;
else
dbl_ld_acc = ldd_data[index & 0xf].op_1;
dbl_value_1 = data_ptr[index].op_1;
dbl_value_2 = data_ptr[index].op_2;
dbl_expected = data_ptr[index].exp;
*dptr_1 = dbl_value_1; /* set 1st operand */
*dptr_2 = dbl_value_2; /* set 2nd operand */
}
}
/*
***************************************************************************
* Set the number of translation faults expected
*
* The entry parameters are the number of faults expected with an instruction
* cache miss and with varying data types. The correct fault count is
* selected and put into "exp_page_faults".
* In double precision compare (CMPD, CMPD2) operations, the system won't
* fetch the least significant half of the operand(s) if the most significant
* halves are different. The # of faults expected will be adjusted for this.
* When using the "no-fpp" version of firmware the least significant longword
* will always be fetched for CMPD. CMPD2 acts the same with either WCS.
*
***************************************************************************
*/
get_exp_faults( sgl_1, dbl_1, sgl_2, dbl_2, sgl_3 )
int sgl_1; /* exp # faults for 1 sgl operand */
int dbl_1; /* exp # faults for 1 dbl operand */
int sgl_2; /* exp # faults for 2 sgl operands */
int dbl_2; /* exp # faults for 2 dbl operands */
int sgl_3; /* exp # faults for 3 sgl operands */
{
if( no_ops == 1 ) {
if( sgl_op )
exp_page_faults = sgl_1; /* 1 sgl operand */
else
exp_page_faults = dbl_1; /* 1 dbl operand */
} else if( no_ops == 2 ) {
if( sgl_op )
exp_page_faults = sgl_2; /* 2 sgl operands */
else
exp_page_faults = dbl_2; /* 2 dbl operands */
} else /* 3 sgl operands */
exp_page_faults = sgl_3; /* 3 sgl operands */
if( (op_code == CMPD2_OP_CODE) && (dbl_value_1.m != dbl_value_2.m) )
exp_page_faults--;
if( (op_code == CMPD_OP_CODE) && (dbl_value_1.m != dbl_ld_acc.m) &&
(!no_fpp_wcs) )
exp_page_faults--;
}
/*
***************************************************************************
*
* Set or reset the LOAD_ACCUMULATOR flag
*
* If the current instruction loads the accumulator then set the flag.
* This flag is used by the page fault handler.
***************************************************************************
*/
set_load_flag()
{
if( (op_code == LDF_OP_CODE) || /* load SGL Acc. */
(op_code == LNF_OP_CODE) || /* load / negate SGL Acc. */
(op_code == LDD_OP_CODE) || /* load SGL Acc. */
(op_code == LND_OP_CODE) || /* load / negate SGL Acc. */
(op_code == LDFD_OP_CODE) ) /* load SGL to DBL Acc. */
load_type_inst = TRUE;
else
load_type_inst = FALSE;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.