|
|
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.
**************************************************************************/
test_inst()
{
/*
* Set the values for the indirect pointers
*/
asm("movl _adr_op1,*_adr_op1_ptr"); /* word offset ptr #1 */
asm("movl _adr_op2,*_adr_op2_ptr"); /* word offset ptr #2 */
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( d_to_s || ( (precision == SGL) && (op_type == STORE) ) )
/* tst_push(); /* PUSH ( auto-decremented SP ) */
/* if( s_to_d || ( (precision == SGL) && (op_type == LOAD) ) )
/* tst_pop(); /* POP ( auto-incremented SP ) */
/* tst_pop_d(); /* auto-incremented SP deferred */
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 */
}
}
/*******************************************************************
* ABSOLUTE ADDRESSING:
* instruction = <op-code> <9f> <&dmp_op_1> {<9f> <&dmp_op_2>}
*******************************************************************/
tst_abs()
{
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_ABSOLUTE;
addr_code = 0x9f;
addr_code2 = 0x9f;
addr_size = 4; /* longword (4 byte) ops. */
addr_1 = DMP_OP_1; /* abs. address of data */
addr_2 = DMP_OP_2;
if( no_ops == 2 )
min_shift = 6;
else
min_shift = 11;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* IMMEDIATE LONGWORD ADDRESSING: ( sgl and sgl_to_dbl only )
* instruction = <op-code> <8f> <data>
*******************************************************************/
tst_i_l()
{
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; /* immediate lword = 0x8f */
addr_size = 4; /* longword (4 byte) data */
exp_page_faults = 2; /* 2 pages used */
index = 0;
for( shift_count = 15; shift_count >= 11; shift_count-- )
{
get_current_data();
addr_1 = dbl_value_1.m; /* set the 1st operand */
addr_2 = dbl_value_2.m; /* set the 2nd operand */
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* BYTE DISPLACEMENT RELATIVE ADDRESSING:
* instruction = <op-code> <af> <offset to dmp_byte_op_1>
* { <af> <offset to dmp_byte_op_2> }
*******************************************************************/
tst_b()
{
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 = 0xaf;
addr_size = 1; /* 1 byte operand */
exp_page_faults = 2; /* 2 pages used */
if( no_ops == 2 )
min_shift = 11;
else
min_shift = 13;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_b_op1 = dbl_value_1.m; /* set the operand */
*adr_bop1_lsw = dbl_value_1.l;
*adr_b_op2 = dbl_value_2.m; /* set the operand */
*adr_bop2_lsw = dbl_value_2.l;
addr_1 = os_b_op1 + 13 - shift_count; /* data's offset */
addr_2 = os_b_op2 + 11 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_b_op1; /* get the final operand */
dbl_value_3.l = *adr_bop1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* WORD DISPLACEMENT RELATIVE ADDRESSING:
* instruction = <op-code> <cf> <offset to dmp_op_1>
* { <cf> <offset to dmp_op_2> }
*******************************************************************/
tst_w()
{
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 = 0xcf;
addr_size = 2; /* word (2 byte) operand */
if( no_ops == 2 )
min_shift = 10;
else
min_shift = 13;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m;
*adr_op2_lsw = dbl_value_2.l;
addr_1 = os_op1 + 12 - shift_count; /* data's offset */
addr_2 = os_op2 + 9 - shift_count;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* LONGWORD DISPLACEMENT RELATIVE ADDRESSING:
* instruction = <op-code> <ef> <offset to dmp_op_1>
* { <ef> <offset to dmp_op_2> }
*******************************************************************/
tst_l()
{
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 = 0xef;
addr_size = 4; /* longword (4 byte) ops. */
if( no_ops == 2 )
min_shift = 6;
else
min_shift = 11;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m;
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
addr_1 = os_op1 + 10 - shift_count; /* data's offset */
addr_2 = os_op2 + 5 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* BYTE DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
* instruction = <op-code> <bf> <offset to dmp_byte_op_1>
* { <bf> <offset to dmp_byte_op_2> }
*******************************************************************/
tst_b_d()
{
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 = 0xbf;
addr_size = 1; /* 1 byte operand */
*adr_b_op1 = (int) adr_op1; /* set byte offset ptr #1 */
*adr_b_op2 = (int) adr_op2; /* set byte offset ptr #2 */
if( no_ops == 2 )
min_shift = 11;
else
min_shift = 13;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m;
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
addr_1 = os_b_op1 + 13 - shift_count; /* data's offset */
addr_2 = os_b_op2 + 11 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* WORD DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
* instruction = <op-code> <df> <offset to dmp_op_1>
* { <df> <offset to dmp_op_2> }
*******************************************************************/
tst_w_d()
{
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 = 0xdf;
addr_size = 2; /* word (2 byte) operand */
if( no_ops == 2 )
min_shift = 10;
else
min_shift = 13;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m;
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 4, 5, 6, 8 ); /* set exp fault cnt */
addr_1 = os_ad_op1 + 12 - shift_count; /* operand offset */
addr_2 = os_ad_op2 + 9 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* LONGWORD DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
* instruction = <op-code> <ff> <offset to dmp_op_1>
* { <ff> <offset to dmp_op_1> }
*******************************************************************/
tst_l_d()
{
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 = 0xff;
addr_size = 4; /* longword (4 byte) op. */
if( no_ops == 2 )
min_shift = 6;
else
min_shift = 11;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 4, 5, 6, 8 ); /* set exp fault cnt */
addr_1 = os_ad_op1 + 10 - shift_count; /* operand offset */
addr_2 = os_ad_op2 + 5 - shift_count;
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* DIRECT REGISTER ADDRESSING:
* instruction = <op-code> <50> { <54> }
*******************************************************************/
tst_r()
{
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_size = 0; /* no addressing bytes */
pack_inst(); /* pack the instr. code */
exp_page_faults = 2; /* 2 pages used */
if( no_ops == 2 )
min_shift = 14;
else
min_shift = 15;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
for( index = 0; index < 3; index++ )
{
get_current_data();
load_regs[0] = dbl_value_1.m; /* get the 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 == 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 */
dbl_value_3.m = store_regs[0]; /* get final r0, r1 values */
dbl_value_3.l = store_regs[1];
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
}
}
}
/*******************************************************************
* REGISTER DEFERRED ADDRESSING:
* instruction = <op-code> <60> {<61>}
*******************************************************************/
tst_r_d()
{
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_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 */
exp_regs[0] = load_regs[0];
exp_regs[1] = load_regs[1];
pack_inst(); /* pack the instr. code */
if( no_ops == 2 )
min_shift = 14;
else
min_shift = 15;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
for( index = 0; index < 3; index++ )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st data */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd data */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get op's final value */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
}
}
}
/*******************************************************************
* AUTO-DECREMENTED STACK POINTER ADDRESSING ( PUSH ):
* instruction = <op-code> <7e>
*
* The final result will be popped by "run_code"
*******************************************************************/
tst_push()
{
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 used */
shift_count = 15;
pack_inst(); /* pack the instr. code */
for( index = 0; index < 3; index++ )
{
get_current_data();
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get op's final value */
(*test_ptr)(); /* verify the results */
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"
*******************************************************************/
tst_pop()
{
fill_reg_buf( load_regs ); /* set data for registers */
fill_reg_buf( exp_regs ); /* set data for registers */
addr_mode = ADR_POP;
addr_code = 0x8e;
addr_size = 0; /* no addressing bytes */
pack_inst(); /* pack the instr. code */
exp_page_faults = 3; /* 3 pages used */
shift_count = 15;
for( index = 0; index < 3; index++ )
{
get_current_data();
sgl_value_9 = dbl_value_1.m; /* data to be pushed */
if( no_ops == 2 )
sgl_value_10 = dbl_value_2.m;
run_code(); /* execute the instruction */
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
}
}
/*******************************************************************
* AUTO-INCREMENTED STACK POINTER DEFERRED ADDRESSING:
* instruction = <op-code> <9e> { <9e> }
*
* The address of the data will be pushed by "run_code"
*******************************************************************/
tst_pop_d()
{
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 = 0x9e;
addr_size = 0; /* no addressing bytes */
pack_inst(); /* pack the instr. code */
sgl_value_9 = (int) adr_op1; /* get 1st op to be popped */
sgl_value_10 = (int) adr_op2; /* get 2nd op to be popped */
if( no_ops == 2 )
min_shift = 14;
else
min_shift = 15;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
for( index = 0; index < 3; index++ )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st op's data */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd op's data */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 4, 5, 5, 7 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get op's final value */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
}
}
}
/*******************************************************************
* REGISTER + BYTE DISPLACEMENT ADDRESSING:
* instruction = <op-code> <a4> <(&op_1 -r4)>
* { <a5> <(&op_2- r5)> }
*******************************************************************/
tst_r_b()
{
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_size = 1; /* 1 byte operand */
addr_1 = 20; /* set the 1st byte offset */
addr_2 = 4; /* set the 2nd 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;
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
if( no_ops == 2 )
min_shift = 12;
else
min_shift = 14;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* REGISTER + WORD DISPLACEMENT ADDRESSING:
* instruction = <op-code> <c4> <(&op_1 -r4)>
* { <c5> <(&op_2 -r5)> }
*******************************************************************/
tst_r_w()
{
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_size = 2; /* word (2 byte) operand */
addr_1 = 511; /* set the 1st word offset */
addr_2 = 513; /* set the 2nd 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;
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
if( no_ops == 2 )
min_shift = 10;
else
min_shift = 13;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* REGISTER + LONGWORD DISPLACEMENT ADDRESSING:
* instruction = <op-code> <e4> <(op_1 -r4)>
* { <e5> <(op_2 -r5)> }
*******************************************************************/
tst_r_l()
{
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 = 0xe4; /* addr 1 is offset by r4 */
addr_code2 = 0xe5; /* addr 2 is offset by r5 */
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 */
load_regs[4] = 123; /* reg 4 = 123 */
exp_regs[4] = 123;
load_regs[5] = 130; /* reg 5 = 130 */
exp_regs[5] = 130;
pack_inst(); /* pack the instr. code */
if( no_ops == 2 )
min_shift = 6;
else
min_shift = 11;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* REGISTER + BYTE DISPLACEMENT DEFERRED ADDRESSING:
* instruction = <op-code> <b4> <(&ptr_to_op_1 -r4)>
* { <b5> <(&ptr_to_op_1 -r5)>}
*******************************************************************/
tst_r_bd()
{
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_size = 1; /* 1 byte operand */
addr_1 = 20; /* set the 1st byte offset */
addr_2 = 4; /* set the 2nd 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;
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
if( no_ops == 2 )
min_shift = 12;
else
min_shift = 14;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 4, 5, 6, 8 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* REGISTER + WORD DISPLACEMENT DEFERRED ADDRESSING:
* instruction = <op-code> <d4> <(word &ptr_to_op_1 -r4)>
* { <d5> <(word &ptr_to_op_1 -r5)> }
*******************************************************************/
tst_r_wd()
{
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_size = 2; /* word (2 byte) operand */
addr_1 = 511; /* set the 1st word offset */
addr_2 = 601; /* set the 2nd 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;
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
if( no_ops == 2 )
min_shift = 10;
else
min_shift = 13;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 4, 5, 6, 8 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* REGISTER + LONGWORD DISPLACEMENT DEFERRED ADDRESSING:
* instruction = <op-code> <f4> <(longword &ptr_to_op_1 -r4)>
* { <f5> <(longword &ptr_to_op_1 -r5)> }
*******************************************************************/
tst_r_ld()
{
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_size = 4; /* longword (4 byte) op. */
addr_1 = (int) adr_op1_ptr - 123; /* set the 1st byte offset */
addr_2 = (int) adr_op2_ptr - 212; /* set the 2nd byte offset */
pack_inst(); /* pack the instr. code */
load_regs[4] = 123; /* reg 4 = 123 */
load_regs[5] = 212; /* reg 5 = 212 */
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
if( no_ops == 2 )
min_shift = 6;
else
min_shift = 11;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 4, 5, 6, 8 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* FRAME POINTER DEFERRED + LONGWORD INDEX ADDRESSING:
* instruction = <op-code> <44> <6d> { <45> <6d> }
*
* The indeces used will be either quadword indeces ( for DBL operands )
* of longword indeces ( for SGL operands ).
*
* NOTE:
* dmp_op_2 is exactly 4 pages away from dmp_op_1. (200 hex quadwords)
* IF THIS RELATIVE DISPLACEMENT IS CHANGED THEN THE R5 INDEX MUST
* BE CHANGED IN THIS CODE!!! ( used by CMPF2 & CMPD2 )
*******************************************************************/
tst_x_fpd()
{
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_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)
*/
asm("movl _adr_op1,_sgl_dummy1"); /* get the addr of op 1 */
load_regs[13] = sgl_dummy1-16; /* SP = op 1's addr - 16 */
exp_regs[13] = load_regs[13];
if( sgl_op )
{
load_regs[4] = 4; /* SP to op_1 (longwords) */
load_regs[5] = 0x404; /* SP to op_2 (longwords) */
} else {
load_regs[4] = 2; /* SP to op_1 (quadwords) */
load_regs[5] = 0x202; /* SP to op_2 (quadwords) */
}
exp_regs[4] = load_regs[4];
exp_regs[5] = load_regs[5];
if( no_ops == 2 )
min_shift = 12;
else
min_shift = 14;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/*******************************************************************
* INDEXED LONGWORD DISPLACEMENT ADDRESSING:
* instruction = <op-code> <44> <ef> <longword offset>
* { <45> <ef> <longword offset> }
*******************************************************************/
tst_x_l()
{
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_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) */
} 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];
if( no_ops == 2 )
min_shift = 4;
else
min_shift = 10;
index = 0;
for( shift_count = 15; shift_count >= min_shift; shift_count-- )
{
get_current_data();
*adr_op1 = dbl_value_1.m; /* set the 1st operand */
*adr_op1_lsw = dbl_value_1.l;
*adr_op2 = dbl_value_2.m; /* set the 2nd operand */
*adr_op2_lsw = dbl_value_2.l;
get_exp_faults( 3, 4, 4, 6 ); /* set exp fault cnt */
addr_1 = os_op1 + 9 - shift_count; /* data's offset */
addr_1 -=16; /* -16 bytes (2 Q-words) */
addr_2 = os_op2 + 3 - shift_count; /* data's offset */
addr_2 -=24; /* -24 bytes (3 Q-words) */
pack_inst(); /* pack the instr. code */
run_code(); /* execute the instruction */
dbl_value_3.m = *adr_op1; /* get the final operand */
dbl_value_3.l = *adr_op1_lsw;
(*test_ptr)(); /* verify the results */
if( force_loop )
run_code(); /* start the error loop */
index++; /* bump the data index */
}
}
/**************************************************************************
* Get data for double precision instructions
**************************************************************************/
get_current_data()
{
if( no_ops == 2 )
{
dbl_ld_acc = ldd_data[ index +1 ].op_1;
dbl_value_1 = data_ptr[ index ].op_1;
dbl_value_2 = data_ptr[ index ].op_2;
dbl_expected = data_ptr[ index ].exp;
}
else
{
dbl_ld_acc = data_ptr[ index ].op_1;
dbl_value_1 = data_ptr[ index ].op_2;
dbl_expected = data_ptr[ index ].exp;
}
}
/****************************************************************************
* Get the expected number of translation faults
****************************************************************************/
get_exp_faults( sgl_1, dbl_1, sgl_2, dbl_2 )
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 */
{
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( sgl_op )
exp_page_faults = sgl_2; /* 2 sgl operands */
else
exp_page_faults = dbl_2; /* 2 dbl operands */
}
/*
* In DBL compare instructions, the system won't fetch the least significant
* half of the operand(s) if the most significant halves are different.
*/
if( (op_code == CMPD_OP_CODE) && (dbl_value_1.m != dbl_ld_acc.m) ||
(op_code == CMPD2_OP_CODE) && (dbl_value_1.m != dbl_value_2.m) )
exp_page_faults--;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.