Line 795... |
Line 795... |
/******* Floating point instructions *******/
|
/******* Floating point instructions *******/
|
/* Do calculation, and update FPCSR as required */
|
/* Do calculation, and update FPCSR as required */
|
/* Single precision */
|
/* Single precision */
|
INSTRUCTION (lf_add_s) {
|
INSTRUCTION (lf_add_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1, param2;
|
float_set_rm();
|
param1.hval = (uorreg_t)PARAM1;
|
SET_PARAM0(float32_add((unsigned int)PARAM1,(unsigned int)PARAM2));
|
param2.hval = (uorreg_t)PARAM2;
|
float_set_flags();
|
fp_set_or1k_rm();
|
|
param0.fval = param1.fval + param2.fval;
|
|
SET_PARAM0(param0.hval);
|
|
fp_set_flags_restore_host_rm();
|
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_div_s) {
|
INSTRUCTION (lf_div_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1, param2;
|
float_set_rm();
|
param1.hval = (uorreg_t)PARAM1;
|
SET_PARAM0(float32_div((unsigned int)PARAM1,(unsigned int)PARAM2));
|
param2.hval = (uorreg_t)PARAM2;
|
float_set_flags();
|
fp_set_or1k_rm();
|
|
param0.fval = param1.fval / param2.fval;
|
|
SET_PARAM0(param0.hval);
|
|
fp_set_flags_restore_host_rm();
|
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_ftoi_s) {
|
INSTRUCTION (lf_ftoi_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
fp_set_or1k_rm();
|
float_set_rm();
|
// no other way appeared to work --jb
|
SET_PARAM0(float32_to_int32((unsigned int)PARAM1));
|
float tmp_f; memcpy((void*)&tmp_f, (void*)&PARAM1, sizeof(float));
|
float_set_flags();
|
SET_PARAM0((int)tmp_f);
|
|
fp_set_flags_restore_host_rm();
|
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_itof_s) {
|
INSTRUCTION (lf_itof_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0;
|
float_set_rm();
|
fp_set_or1k_rm();
|
SET_PARAM0(int32_to_float32((unsigned int)PARAM1));
|
param0.fval = (float)((int)PARAM1);
|
float_set_flags();
|
SET_PARAM0(param0.hval);
|
|
fp_set_flags_restore_host_rm();
|
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_madd_s) {
|
INSTRUCTION (lf_madd_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0,param1, param2;
|
float_set_rm();
|
param0.hval = (uorreg_t)PARAM0;
|
SET_PARAM0(float32_add((unsigned int)PARAM0, float32_mul((unsigned int)PARAM1,(unsigned int)PARAM2)));
|
param1.hval = (uorreg_t)PARAM1;
|
// Note: this ignores flags from the multiply!
|
fp_set_or1k_rm();
|
float_set_flags();
|
param2.hval = PARAM2;
|
|
param0.fval += param1.fval * param2.fval;
|
|
SET_PARAM0(param0.hval);
|
|
fp_set_flags_restore_host_rm();
|
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_mul_s) {
|
INSTRUCTION (lf_mul_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1, param2;
|
float_set_rm();
|
param1.hval = (uorreg_t)PARAM1;
|
SET_PARAM0(float32_mul((unsigned int)PARAM1,(unsigned int)PARAM2));
|
param2.hval = (uorreg_t)PARAM2;
|
float_set_flags();
|
fp_set_or1k_rm();
|
|
param0.fval = param1.fval * param2.fval;
|
|
SET_PARAM0(param0.hval);
|
|
fp_set_flags_restore_host_rm();
|
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_rem_s) {
|
INSTRUCTION (lf_rem_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1, param2;
|
float_set_rm();
|
param1.hval = PARAM1;
|
SET_PARAM0(float32_rem((unsigned int)PARAM1,(unsigned int)PARAM2));
|
param2.hval = PARAM2;
|
float_set_flags();
|
fp_set_or1k_rm();
|
|
param0.fval = fmodf (param1.fval, param2.fval);
|
|
SET_PARAM0(param0.hval);
|
|
fp_set_flags_restore_host_rm();
|
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_sfeq_s) {
|
INSTRUCTION (lf_sfeq_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1;
|
float_set_rm();
|
param0.hval = PARAM0;
|
if(float32_eq((unsigned int)PARAM0, (unsigned int)PARAM1))
|
param1.hval = PARAM1;
|
|
fp_set_or1k_rm();
|
|
if(param0.fval == param1.fval)
|
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
else
|
else
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
fp_set_flags_restore_host_rm();
|
float_set_flags();
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_sfge_s) {
|
INSTRUCTION (lf_sfge_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1;
|
float_set_rm();
|
param0.hval = PARAM0;
|
if((!float32_lt((unsigned int)PARAM0, (unsigned int)PARAM1) &
|
param1.hval = PARAM1;
|
!float32_is_nan( (unsigned int)PARAM0) &
|
fp_set_or1k_rm();
|
!float32_is_nan( (unsigned int)PARAM1) ) )
|
if(param0.fval >= param1.fval)
|
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
else
|
else
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
fp_set_flags_restore_host_rm();
|
float_set_flags();
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_sfgt_s) {
|
INSTRUCTION (lf_sfgt_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1;
|
float_set_rm();
|
param0.hval = PARAM0;
|
if((!float32_le((unsigned int)PARAM0, (unsigned int)PARAM1) &
|
param1.hval = PARAM1;
|
!float32_is_nan( (unsigned int)PARAM0) &
|
fp_set_or1k_rm();
|
!float32_is_nan( (unsigned int)PARAM1) ) )
|
if(param0.fval > param1.fval)
|
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
else
|
else
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
fp_set_flags_restore_host_rm();
|
float_set_flags();
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_sfle_s) {
|
INSTRUCTION (lf_sfle_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1;
|
float_set_rm();
|
param0.hval = PARAM0;
|
if((float32_le((unsigned int)PARAM0, (unsigned int)PARAM1) &
|
param1.hval = PARAM1;
|
!float32_is_nan( (unsigned int)PARAM0) &
|
fp_set_or1k_rm();
|
!float32_is_nan( (unsigned int)PARAM1) ) )
|
if(param0.fval <= param1.fval)
|
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
else
|
else
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
fp_set_flags_restore_host_rm();
|
float_set_flags();
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_sflt_s) {
|
INSTRUCTION (lf_sflt_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1;
|
float_set_rm();
|
param0.hval = PARAM0;
|
if(( float32_lt((unsigned int)PARAM0, (unsigned int)PARAM1) &
|
param1.hval = PARAM1;
|
!float32_is_nan( (unsigned int)PARAM0) &
|
fp_set_or1k_rm();
|
!float32_is_nan( (unsigned int)PARAM1) ) )
|
if(param0.fval < param1.fval)
|
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
else
|
else
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
fp_set_flags_restore_host_rm();
|
float_set_flags();
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_sfne_s) {
|
INSTRUCTION (lf_sfne_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1;
|
float_set_rm();
|
param0.hval = PARAM0;
|
if(!float32_eq((unsigned int)PARAM0, (unsigned int)PARAM1))
|
param1.hval = PARAM1;
|
|
fp_set_or1k_rm();
|
|
if(param0.fval != param1.fval)
|
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
cpu_state.sprs[SPR_SR] |= SPR_SR_F;
|
else
|
else
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
|
|
float_set_flags();
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
INSTRUCTION (lf_sub_s) {
|
INSTRUCTION (lf_sub_s) {
|
if (config.cpu.hardfloat) {
|
if (config.cpu.hardfloat) {
|
FLOAT param0, param1, param2;
|
float_set_rm();
|
param1.hval = PARAM1;
|
SET_PARAM0(float32_sub((unsigned int)PARAM1,(unsigned int)PARAM2));
|
param2.hval = PARAM2;
|
float_set_flags();
|
fp_set_or1k_rm();
|
|
param0.fval = param1.fval - param2.fval;
|
|
SET_PARAM0(param0.hval);
|
|
fp_set_flags_restore_host_rm();
|
|
} else l_invalid();
|
} else l_invalid();
|
}
|
}
|
|
|
/******* Custom instructions *******/
|
/******* Custom instructions *******/
|
INSTRUCTION (l_cust1) {
|
INSTRUCTION (l_cust1) {
|