mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 05:29:43 +00:00
Floating point test fixes
This commit is contained in:
parent
331b93d4d6
commit
fb277945c2
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user