Floating point test fixes

This commit is contained in:
dingusdev 2021-10-19 07:16:15 -07:00
parent 331b93d4d6
commit fb277945c2
5 changed files with 474 additions and 466 deletions

View File

@ -231,10 +231,10 @@ enum FPSCR : uint32_t {
VXSQRT = 0x200,
VXSOFT = 0x400,
FPRF = 0x1F000,
FPCC_FUNAN = 0x10000,
FPCC_ZERO = 0x8000,
FPCC_POS = 0x4000,
FPCC_NEG = 0x2000,
FPCC_FUNAN = 0x10000,
FPCC_NEG = 0x8000,
FPCC_POS = 0x4000,
FPCC_ZERO = 0x2000,
FPCC_FPRCD = 0x1000,
FI = 0x20000,
FR = 0x40000,

View File

@ -151,15 +151,6 @@ void ppc_fp_changecrf1() {
ppc_state.fpscr |= 0xf0000000;
}
void ppc_divbyzero(uint64_t input_a, uint64_t input_b, bool is_single) {
if (input_b == 0) {
ppc_state.fpscr |= 0x84000000;
if (input_a == 0) {
ppc_state.fpscr |= 0x200000;
}
}
}
int64_t round_to_nearest(double f) {
if (f >= 0.0) {
return static_cast<int32_t>(static_cast<int64_t> (ceil(f)));
@ -186,7 +177,7 @@ void update_fex() {
}
template <typename T, const FPOP fpop>
void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, int chosen_reg_3) {
void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, int chosen_reg_3, bool rc_flag = false) {
T input_a = T(ppc_state.fpr[chosen_reg_1].int64_r);
T input_b = T(ppc_state.fpr[chosen_reg_2].int64_r);
T input_c = T(ppc_state.fpr[chosen_reg_3].int64_r);
@ -238,7 +229,7 @@ void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, int chosen_reg_3) {
case FPOP::FMADD:
case FPOP::FNMADD:
if (isnan(input_a) || isnan(input_b) || isnan(input_c)) {
ppc_state.fpscr |= FPSCR::VXSNAN;
ppc_state.fpscr |= (FPSCR::VXSNAN | FPSCR::FPCC_FUNAN);
}
update_fex();
break;
@ -248,26 +239,26 @@ void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, int chosen_reg_3) {
void fpresult_update(double set_result, bool confirm_arc) {
bool confirm_ov = (bool)std::fetestexcept(FE_OVERFLOW);
if (ppc_state.fpscr & 0x3)
ppc_state.cr |= 0x2;
if (set_result > 0.0) {
ppc_state.fpscr |= FPSCR::FPCC_POS;
} else if (set_result < 0.0) {
ppc_state.fpscr |= FPSCR::FPCC_NEG;
} else if (set_result == 0.0) {
ppc_state.fpscr |= FPSCR::FPCC_ZERO;
} else {
ppc_state.fpscr |= FPSCR::FPCC_FPRCD;
}
if (confirm_ov) {
ppc_state.fpscr |= (FPSCR::FX | (FPSCR::FPRF & FPSCR::FPCC_FUNAN));
}
if (confirm_arc) {
ppc_state.fpscr |= (FPSCR::FX | (FPSCR::FPRF & FPSCR::FPCC_FUNAN));
ppc_state.fpscr &= 0xFFFF0FFF;
if (set_result == 0.0) {
ppc_state.fpscr |= FPSCR::FPCC_NEG;
} else {
if (set_result < 0.0) {
ppc_state.fpscr |= FPSCR::FPCC_ZERO;
} else if (set_result > 0.0) {
ppc_state.fpscr |= FPSCR::FPCC_POS;
} else {
ppc_state.fpscr |= FPSCR::FPCC_FPRCD;
}
}
//ppc_state.fpscr &= 0xFFFF0FFF;
}
}
@ -284,8 +275,9 @@ void dppc_interpreter::ppc_fadd() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_dfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<double, ADD>(reg_a, reg_b, 0);
ppc_confirm_inf_nan<double, ADD>(reg_a, reg_b, 0, rc_flag);
}
if (rc_flag)
@ -299,8 +291,9 @@ void dppc_interpreter::ppc_fsub() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_dfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<double, SUB>(reg_a, reg_b, 0);
ppc_confirm_inf_nan<double, SUB>(reg_a, reg_b, 0, rc_flag);
}
if (rc_flag)
@ -314,8 +307,9 @@ void dppc_interpreter::ppc_fdiv() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_dfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<double, DIV>(reg_a, reg_b, 0);
ppc_confirm_inf_nan<double, DIV>(reg_a, reg_b, 0, rc_flag);
}
if (rc_flag)
@ -329,8 +323,9 @@ void dppc_interpreter::ppc_fmul() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_dfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_b, 0);
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_b, 0, rc_flag);
}
if (rc_flag)
@ -344,6 +339,7 @@ void dppc_interpreter::ppc_fmadd() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_dfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<double, FMADD>(reg_a, reg_b, reg_c);
}
@ -360,6 +356,7 @@ void dppc_interpreter::ppc_fmsub() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_dfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<double, FMSUB>(reg_a, reg_b, reg_c);
}
@ -373,10 +370,10 @@ void dppc_interpreter::ppc_fnmadd() {
ppc_dblresult64_d = (val_reg_a * val_reg_c);
ppc_dblresult64_d += val_reg_b;
ppc_dblresult64_d = -ppc_dblresult64_d;
if (!isnan(ppc_dblresult64_d)) {
ppc_store_dfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
}
else {
ppc_confirm_inf_nan<double, FNMADD>(reg_a, reg_b, reg_c);
@ -391,9 +388,11 @@ void dppc_interpreter::ppc_fnmsub() {
ppc_dblresult64_d = (val_reg_a * val_reg_c);
ppc_dblresult64_d -= val_reg_b;
ppc_dblresult64_d = -ppc_dblresult64_d;
if (!isnan(ppc_dblresult64_d)) {
ppc_store_dfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<double, FNMSUB>(reg_a, reg_b, reg_c);
}
@ -410,6 +409,7 @@ void dppc_interpreter::ppc_fadds() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, ADD>(reg_a, reg_b, 0);
}
@ -426,6 +426,7 @@ void dppc_interpreter::ppc_fsubs() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, SUB>(reg_a, reg_b, 0);
}
@ -442,6 +443,7 @@ void dppc_interpreter::ppc_fdivs() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, DIV>(reg_a, reg_b, 0);
}
@ -458,6 +460,7 @@ void dppc_interpreter::ppc_fmuls() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, MUL>(reg_a, 0, reg_c);
}
@ -474,6 +477,7 @@ void dppc_interpreter::ppc_fmadds() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, FMADD>(reg_a, reg_b, reg_c);
}
@ -491,6 +495,7 @@ void dppc_interpreter::ppc_fmsubs() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, FMSUB>(reg_a, reg_b, reg_c);
}
@ -509,6 +514,7 @@ void dppc_interpreter::ppc_fnmadds() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, FNMADD>(reg_a, reg_b, reg_c);
}
@ -528,6 +534,7 @@ void dppc_interpreter::ppc_fnmsubs() {
if (!isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, FNMSUB>(reg_a, reg_b, reg_c);
}

View File

@ -416,31 +416,31 @@ if __name__ == "__main__":
while pos < len(line):
if (line[pos].isalnum()):
checkstring += line[pos]
if ("RTN" in checkstring):
out_file.write(",round=RTN")
checkstring = ''
if (line[pos+1:pos+2] == "I"):
out_file.write(",round=RNI")
checkstring = ''
else:
out_file.write(",round=RTN")
checkstring = ''
pos += 1
if ("RTZ" in checkstring):
elif ("RTZ" in checkstring):
out_file.write(",round=RTZ")
checkstring = ''
pos += 1
if ("RTPI" in checkstring):
elif ("RTPI" in checkstring):
out_file.write(",round=RPI")
checkstring = ''
pos += 1
if ("RTNI" in checkstring):
out_file.write(",round=RNI")
checkstring = ''
pos += 1
if ("VE" in checkstring):
elif ("VE" in checkstring):
out_file.write(",round=VEN")
checkstring = ''
pos += 1
if ("frD" in checkstring):
elif ("frD" in checkstring):
out_file.write(",frD=0x" + line[pos+4:pos+20])
checkstring = ''
if ("frA" in checkstring): #sloppy temp code
elif ("frA" in checkstring): #sloppy temp code
check2 = line[pos+1:pos+10]
if ("-inf" in check2):
out_file.write(",frA=-inf")
@ -463,7 +463,7 @@ if __name__ == "__main__":
get_pos = line[pos+2:pos+15]
out_file.write(",frA=" + get_pos.strip())
checkstring = ''
if ("frB" in checkstring): #sloppy temp code
elif ("frB" in checkstring): #sloppy temp code
check2 = line[pos+1:pos+10]
if ("-inf" in check2):
out_file.write(",frB=-inf")
@ -486,7 +486,7 @@ if __name__ == "__main__":
get_pos = line[pos+2:pos+15]
out_file.write(",frB=" + get_pos.strip())
checkstring = ''
if ("frC" in checkstring): #sloppy temp code
elif ("frC" in checkstring): #sloppy temp code
check2 = line[pos+1:pos+10]
if ("-inf" in check2):
out_file.write(",frC=-inf")
@ -509,10 +509,10 @@ if __name__ == "__main__":
get_pos = line[pos+2:pos+15]
out_file.write(",frC=" + get_pos.strip())
checkstring = ''
if ("FPSCR" in checkstring):
elif ("FPSCR" in checkstring):
out_file.write(",FPSCR=" + line[pos+3:pos+13])
checkstring = ''
if ("CR" in checkstring):
elif ("CR" in checkstring):
out_file.write(",CR=0x0" + line[pos+6:pos+14])
checkstring = ''
pos += 1

File diff suppressed because it is too large Load Diff

View File

@ -148,7 +148,7 @@ static void read_test_float_data() {
int i, lineno;
uint32_t opcode, dest, src1, src2, check_xer, check_cr, check_fpscr;
//uint64_t dest_64, src1_64, src2_64;
uint64_t dest_64, src1_64, src2_64;
//float sfp_dest, sfp_src1, sfp_src2, sfp_src3;
double dfp_dest, dfp_src1, dfp_src2, dfp_src3;
string rounding_mode;
@ -195,10 +195,11 @@ static void read_test_float_data() {
dfp_src1 = 0.0;
dfp_src2 = 0.0;
dfp_src3 = 0.0;
dest_64 = 0;
for (i = 2; i < tokens.size(); i++) {
if (tokens[i].rfind("frD=", 0) == 0) {
dfp_dest = stoull(tokens[i].substr(4), NULL, 16);
dest_64 = stoull(tokens[i].substr(4), NULL, 16);
} else if (tokens[i].rfind("frA=", 0) == 0) {
dfp_src1 = stod(tokens[i].substr(4), NULL);
} else if (tokens[i].rfind("frB=", 0) == 0) {
@ -209,15 +210,15 @@ static void read_test_float_data() {
rounding_mode = tokens[i].substr(6, 3);
ppc_state.fpscr &= 0xFFFFFFFC;
if (rounding_mode.compare("RTN") == 0) {
ppc_state.fpscr |= 0x0;
ppc_state.fpscr = 0x0;
} else if (rounding_mode.compare("RTZ") == 0) {
ppc_state.fpscr |= 0x1;
ppc_state.fpscr = 0x1;
} else if (rounding_mode.compare("RPI") == 0) {
ppc_state.fpscr |= 0x2;
ppc_state.fpscr = 0x2;
} else if (rounding_mode.compare("RNI") == 0) {
ppc_state.fpscr |= 0x3;
ppc_state.fpscr = 0x3;
} else if (rounding_mode.compare("VEN") == 0) {
ppc_state.fpscr |= FPSCR::VE;
ppc_state.fpscr = FPSCR::VE;
} else {
cout << "ILLEGAL ROUNDING METHOD: " << tokens[i] << " in line " << lineno
<< ". Exiting..." << endl;
@ -249,14 +250,14 @@ static void read_test_float_data() {
ntested++;
if ((tokens[0].rfind("FCMP") && (ppc_state.fpr[3].dbl64_r != dfp_dest)) ||
if ((tokens[0].rfind("FCMP") && (ppc_state.fpr[3].int64_r != dest_64)) ||
(ppc_state.fpscr != check_fpscr) ||
(ppc_state.cr != check_cr)) {
cout << "Mismatch: instr=" << tokens[0] << ", src1=" << scientific << dfp_src1 << ", src2=" << scientific << dfp_src2 << ", src3=" << scientific << dfp_src3 << endl;
cout << "expected: dest=0x" << hex << dfp_dest << ", FPSCR=0x" << hex << check_fpscr
cout << "expected: dest=0x" << hex << dest_64 << ", FPSCR=0x" << hex << check_fpscr
<< ", CR=0x"
<< hex << check_cr << endl;
cout << "got: dest=0x" << hex << ppc_state.fpr[3].dbl64_r << ", FPSCR=0x" << hex
cout << "got: dest=0x" << hex << ppc_state.fpr[3].int64_r << ", FPSCR=0x" << hex
<< ppc_state.fpscr << ", CR=0x" << hex << ppc_state.cr << endl;
cout << "Test file line #: " << dec << lineno << endl << endl;