mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-23 21:29:28 +00:00
Merge pull request #21 from dingusdev/floating-point
Floating point fixes. Rehauled floating-point emulation code. Fixed a test suite for floating points.
This commit is contained in:
commit
7919cd0590
@ -169,6 +169,7 @@ if (DPPC_BUILD_PPC_TESTS)
|
||||
TARGET testppc POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${PROJECT_SOURCE_DIR}/cpu/ppc/test/ppcinttests.csv"
|
||||
"${PROJECT_SOURCE_DIR}/cpu/ppc/test/ppcfloattests.csv"
|
||||
"${PROJECT_SOURCE_DIR}/cpu/ppc/test/ppcdisasmtest.csv"
|
||||
$<TARGET_FILE_DIR:${PROJECT_NAME}>)
|
||||
endif()
|
||||
|
@ -200,6 +200,71 @@ enum class BB_end_kind {
|
||||
BB_RFI /* the rfi instruction is encountered */
|
||||
};
|
||||
|
||||
enum CR_select : int32_t {
|
||||
CR0_field = (0xF << 28),
|
||||
CR1_field = (0xF << 24),
|
||||
};
|
||||
|
||||
enum CRx_bit : uint32_t {
|
||||
CR_SO = 0,
|
||||
CR_EQ,
|
||||
CR_GT,
|
||||
CR_LT
|
||||
};
|
||||
|
||||
enum CR1_bit : uint32_t {
|
||||
CR1_OX = 24,
|
||||
CR1_VX,
|
||||
CR1_FEX,
|
||||
CR1_FX,
|
||||
};
|
||||
|
||||
enum FPSCR : uint32_t {
|
||||
RN = 0x3,
|
||||
NI = 0x4,
|
||||
XE = 0x8,
|
||||
ZE = 0x10,
|
||||
UE = 0x20,
|
||||
OE = 0x40,
|
||||
VE = 0x80,
|
||||
VXCVI = 0x100,
|
||||
VXSQRT = 0x200,
|
||||
VXSOFT = 0x400,
|
||||
FPRF = 0x1F000,
|
||||
FPCC_FUNAN = 0x10000,
|
||||
FPCC_NEG = 0x8000,
|
||||
FPCC_POS = 0x4000,
|
||||
FPCC_ZERO = 0x2000,
|
||||
FPCC_FPRCD = 0x1000,
|
||||
FI = 0x20000,
|
||||
FR = 0x40000,
|
||||
VXVC = 0x80000,
|
||||
VXIMZ = 0x100000,
|
||||
VXZDZ = 0x200000,
|
||||
VXIDI = 0x400000,
|
||||
VXISI = 0x800000,
|
||||
VXSNAN = 0x1000000,
|
||||
XX = 0x2000000,
|
||||
ZX = 0x4000000,
|
||||
UX = 0x8000000,
|
||||
OX = 0x10000000,
|
||||
VX = 0x20000000,
|
||||
FEX = 0x40000000,
|
||||
FX = 0x80000000
|
||||
};
|
||||
|
||||
//for inf and nan checks
|
||||
enum FPOP : int {
|
||||
DIV = 0x12,
|
||||
SUB = 0x14,
|
||||
ADD = 0x15,
|
||||
MUL = 0x19,
|
||||
FMSUB = 0x1C,
|
||||
FMADD = 0x1D,
|
||||
FNMSUB = 0x1E,
|
||||
FNMADD = 0x1F,
|
||||
};
|
||||
|
||||
/** PowerPC exception types. */
|
||||
enum class Except_Type {
|
||||
EXC_SYSTEM_RESET = 1,
|
||||
@ -271,7 +336,6 @@ void ppc_opcode63();
|
||||
|
||||
void initialize_ppc_opcode_tables();
|
||||
|
||||
extern bool ppc_confirm_inf_nan(uint64_t input_a, uint64_t input_b, bool is_single, uint32_t op);
|
||||
extern double fp_return_double(uint32_t reg);
|
||||
extern uint64_t fp_return_uint64(uint32_t reg);
|
||||
|
||||
@ -416,15 +480,10 @@ extern void ppc_mtspr();
|
||||
extern void ppc_mtfsb0();
|
||||
extern void ppc_mtfsb1();
|
||||
extern void ppc_mcrfs();
|
||||
extern void ppc_mtfsb0dot();
|
||||
extern void ppc_mtfsb1dot();
|
||||
extern void ppc_fmr();
|
||||
extern void ppc_mffs();
|
||||
extern void ppc_mffsdot();
|
||||
extern void ppc_mtfsf();
|
||||
extern void ppc_mtfsfdot();
|
||||
extern void ppc_mtfsfi();
|
||||
extern void ppc_mtfsfidot();
|
||||
|
||||
extern void ppc_addi();
|
||||
extern void ppc_addic();
|
||||
|
@ -253,8 +253,7 @@ void ppc_opcode31() {
|
||||
oe_flag = ppc_cur_instruction & 0x400;
|
||||
|
||||
#ifdef EXHAUSTIVE_DEBUG
|
||||
uint32_t regrab = (uint32_t)subop_grab;
|
||||
LOG_F(INFO, "Executing Opcode 63 table subopcode entry \n", regrab);
|
||||
LOG_F(INFO, "Executing Opcode 31 table subopcode entry %n \n", (uint32_t)subop_grab);
|
||||
#endif // EXHAUSTIVE_DEBUG
|
||||
|
||||
SubOpcode31Grabber[subop_grab]();
|
||||
@ -264,8 +263,7 @@ void ppc_opcode59() {
|
||||
uint16_t subop_grab = (ppc_cur_instruction >> 1) & 0x1F;
|
||||
rc_flag = ppc_cur_instruction & 1;
|
||||
#ifdef EXHAUSTIVE_DEBUG
|
||||
uint32_t regrab = (uint32_t)subop_grab;
|
||||
LOG_F(INFO, "Executing Opcode 59 table subopcode entry \n", regrab);
|
||||
LOG_F(INFO, "Executing Opcode 59 table subopcode entry %n \n", (uint32_t)subop_grab);
|
||||
#endif // EXHAUSTIVE_DEBUG
|
||||
SubOpcode59Grabber[subop_grab]();
|
||||
}
|
||||
@ -274,8 +272,7 @@ void ppc_opcode63() {
|
||||
uint16_t subop_grab = (ppc_cur_instruction >> 1) & 0x3FF;
|
||||
rc_flag = ppc_cur_instruction & 1;
|
||||
#ifdef EXHAUSTIVE_DEBUG
|
||||
uint32_t regrab = (uint32_t)subop_grab;
|
||||
LOG_F(INFO, "Executing Opcode 63 table subopcode entry \n", regrab);
|
||||
LOG_F(INFO, "Executing Opcode 63 table subopcode entry %n \n", (uint32_t)subop_grab);
|
||||
#endif // EXHAUSTIVE_DEBUG
|
||||
SubOpcode63Grabber[subop_grab]();
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include "ppcmmu.h"
|
||||
#include <array>
|
||||
#include <cfenv>
|
||||
#include <cfloat>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
@ -150,20 +151,11 @@ 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> (f + 0.5));
|
||||
return static_cast<int32_t>(static_cast<int64_t> (ceil(f)));
|
||||
} else {
|
||||
return static_cast<int32_t>(static_cast<int64_t> (-f + 0.5));
|
||||
return static_cast<int32_t>(static_cast<int64_t> (floor(f)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,153 +171,113 @@ int64_t round_to_neg_inf(double f) {
|
||||
return static_cast<int32_t>(floor(f));
|
||||
}
|
||||
|
||||
void ppc_toggle_fpscr_fex() {
|
||||
bool fex_result = ((ppc_state.fpscr & 0x20000000) & (ppc_state.fpscr & 0x80));
|
||||
fex_result |= ((ppc_state.fpscr & 0x10000000) & (ppc_state.fpscr & 0x40));
|
||||
fex_result |= ((ppc_state.fpscr & 0x8000000) & (ppc_state.fpscr & 0x20));
|
||||
fex_result |= ((ppc_state.fpscr & 0x4000000) & (ppc_state.fpscr & 0x10));
|
||||
fex_result |= ((ppc_state.fpscr & 0x2000000) & (ppc_state.fpscr & 0x8));
|
||||
ppc_state.fpscr |= (fex_result << 30);
|
||||
void update_fex() {
|
||||
int fex_result = !!((ppc_state.fpscr & (ppc_state.fpscr << 22)) & 0x3E000000);
|
||||
ppc_state.fpscr = (ppc_state.fpscr & ~0x40000000) | (fex_result << 30);
|
||||
}
|
||||
|
||||
bool ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, bool is_single, uint32_t op) {
|
||||
uint64_t input_a = ppc_state.fpr[chosen_reg_1].int64_r;
|
||||
uint64_t input_b = ppc_state.fpr[chosen_reg_2].int64_r;
|
||||
template <typename T, const FPOP fpop>
|
||||
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);
|
||||
|
||||
if (is_single) {
|
||||
uint32_t exp_a = (input_a >> 23) & 0xff;
|
||||
uint32_t exp_b = (input_b >> 23) & 0xff;
|
||||
ppc_state.fpscr &= 0x7fbfffff;
|
||||
|
||||
ppc_state.fpscr &= 0x7fbfffff;
|
||||
switch (fpop) {
|
||||
case FPOP::DIV:
|
||||
if (isnan(input_a) && isnan(input_b)) {
|
||||
ppc_state.fpscr |= (FPSCR::FX | FPSCR::VXIDI);
|
||||
} else if ((input_a == FP_ZERO) && (input_b == FP_ZERO)) {
|
||||
ppc_state.fpscr |= (FPSCR::FX | FPSCR::VXZDZ);
|
||||
}
|
||||
update_fex();
|
||||
break;
|
||||
case FPOP::SUB:
|
||||
if (isnan(input_a) && isnan(input_b)) {
|
||||
ppc_state.fpscr |= (FPSCR::FX | FPSCR::VXISI);
|
||||
}
|
||||
update_fex();
|
||||
break;
|
||||
case FPOP::ADD:
|
||||
if (isnan(input_a) && isnan(input_b)) {
|
||||
ppc_state.fpscr |= (FPSCR::FX | FPSCR::VXISI);
|
||||
}
|
||||
update_fex();
|
||||
break;
|
||||
case FPOP::MUL:
|
||||
if (((input_a == FP_ZERO) && (input_c == FP_INFINITE)) ||
|
||||
((input_c == FP_ZERO) && (input_a == FP_INFINITE))) {
|
||||
ppc_state.fpscr |=
|
||||
(FPSCR::FX | FPSCR::VXSNAN |
|
||||
FPSCR::VXIMZ);
|
||||
}
|
||||
update_fex();
|
||||
break;
|
||||
case FPOP::FMSUB:
|
||||
case FPOP::FNMSUB:
|
||||
if (isnan(input_a) || isnan(input_b) || isnan(input_c)) {
|
||||
ppc_state.fpscr |= FPSCR::VXSNAN;
|
||||
if (((input_a == FP_ZERO) && (input_c == FP_INFINITE)) ||
|
||||
((input_c == FP_ZERO) && (input_a == FP_INFINITE))) {
|
||||
ppc_state.fpscr |= FPSCR::VXIMZ;
|
||||
}
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case 36:
|
||||
if ((exp_a == 0xff) && (exp_b == 0xff)) {
|
||||
ppc_state.fpscr |= 0x80400000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
} else if ((input_a == 0) && (input_b == 0)) {
|
||||
ppc_state.fpscr |= 0x80200000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
}
|
||||
update_fex();
|
||||
break;
|
||||
case 40:
|
||||
if ((exp_a == 0xff) && (exp_b == 0xff)) {
|
||||
ppc_state.fpscr |= 0x80800000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
case FPOP::FMADD:
|
||||
case FPOP::FNMADD:
|
||||
if (isnan(input_a) || isnan(input_b) || isnan(input_c)) {
|
||||
ppc_state.fpscr |= (FPSCR::VXSNAN | FPSCR::FPCC_FUNAN);
|
||||
}
|
||||
update_fex();
|
||||
break;
|
||||
case 50:
|
||||
if (((exp_a == 0xff) & (input_b == 0)) | ((exp_b == 0xff) & (input_a == 0))) {
|
||||
ppc_state.fpscr |= 0x80100000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 56:
|
||||
case 58:
|
||||
if ((exp_a == 0xff) && (exp_b == 0xff)) {
|
||||
ppc_state.fpscr |= 0x80800000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
uint32_t exp_a = (input_a >> 52) & 0x7ff;
|
||||
uint32_t exp_b = (input_b >> 52) & 0x7ff;
|
||||
|
||||
ppc_state.fpscr &= 0x7fbfffff;
|
||||
|
||||
switch (op) {
|
||||
case 36:
|
||||
if ((exp_a == 0x7ff) && (exp_b == 0x7ff)) {
|
||||
ppc_state.fpscr |= 0x80400000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
} else if ((input_a == 0) && (input_b == 0)) {
|
||||
ppc_state.fpscr |= 0x80200000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 40:
|
||||
if ((exp_a == 0x7ff) && (exp_b == 0x7ff)) {
|
||||
ppc_state.fpscr |= 0x80800000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 50:
|
||||
if (((exp_a == 0x7ff) & (input_b == 0)) | ((exp_b == 0x7ff) & (input_a == 0))) {
|
||||
ppc_state.fpscr |= 0x80100000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 56:
|
||||
case 58:
|
||||
if ((exp_a == 0xff) && (exp_b == 0xff)) {
|
||||
ppc_state.fpscr |= 0x80800000;
|
||||
ppc_toggle_fpscr_fex();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void fpresult_update(uint64_t set_result, bool confirm_arc) {
|
||||
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 |= 0x80001000;
|
||||
ppc_state.fpscr |= (FPSCR::FX | (FPSCR::FPRF & FPSCR::FPCC_FUNAN));
|
||||
}
|
||||
|
||||
if (confirm_arc) {
|
||||
ppc_state.fpscr |= 0x80010000;
|
||||
ppc_state.fpscr &= 0xFFFF0FFF;
|
||||
|
||||
|
||||
if (set_result == 0) {
|
||||
ppc_state.fpscr |= 0x2000;
|
||||
} else {
|
||||
if (set_result < 0) {
|
||||
ppc_state.fpscr |= 0x8000;
|
||||
} else if (set_result > 0) {
|
||||
ppc_state.fpscr |= 0x4000;
|
||||
} else {
|
||||
ppc_state.fpscr |= 0x1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ppc_frsqrte_result() {
|
||||
if (ppc_result64_d & 0x007FF000000000000UL) {
|
||||
ppc_state.fpscr |= (FPSCR::FX | (FPSCR::FPRF & FPSCR::FPCC_FUNAN));
|
||||
//ppc_state.fpscr &= 0xFFFF0FFF;
|
||||
}
|
||||
}
|
||||
|
||||
void ppc_changecrf1() {
|
||||
ppc_state.cr &= 0xF0FFFFFF;
|
||||
ppc_state.cr |= (ppc_state.fpscr & 0xF0000000) >> 4;
|
||||
ppc_state.cr &= ~((uint32_t)CR_select::CR1_field);
|
||||
ppc_state.cr |= (ppc_state.fpscr & (uint32_t)CR_select::CR0_field) >> 4;
|
||||
}
|
||||
|
||||
// Floating Point Arithmetic
|
||||
void dppc_interpreter::ppc_fadd() {
|
||||
ppc_grab_regsfpdab();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
|
||||
ppc_dblresult64_d = val_reg_a + val_reg_b;
|
||||
ppc_dblresult64_d = val_reg_a + val_reg_b;
|
||||
|
||||
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, rc_flag);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -335,9 +287,13 @@ void dppc_interpreter::ppc_fadd() {
|
||||
void dppc_interpreter::ppc_fsub() {
|
||||
ppc_grab_regsfpdab();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 56)) {
|
||||
ppc_dblresult64_d = val_reg_a - val_reg_b;
|
||||
ppc_dblresult64_d = val_reg_a - val_reg_b;
|
||||
|
||||
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, rc_flag);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -347,9 +303,13 @@ void dppc_interpreter::ppc_fsub() {
|
||||
void dppc_interpreter::ppc_fdiv() {
|
||||
ppc_grab_regsfpdab();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 36)) {
|
||||
ppc_dblresult64_d = val_reg_a / val_reg_b;
|
||||
ppc_dblresult64_d = val_reg_a / val_reg_b;
|
||||
|
||||
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, rc_flag);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -359,9 +319,13 @@ void dppc_interpreter::ppc_fdiv() {
|
||||
void dppc_interpreter::ppc_fmul() {
|
||||
ppc_grab_regsfpdac();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
|
||||
ppc_dblresult64_d = val_reg_a * val_reg_c;
|
||||
ppc_dblresult64_d = val_reg_a * val_reg_c;
|
||||
|
||||
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, rc_flag);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -371,14 +335,14 @@ void dppc_interpreter::ppc_fmul() {
|
||||
void dppc_interpreter::ppc_fmadd() {
|
||||
ppc_grab_regsfpdabc();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
|
||||
ppc_dblresult64_d = (val_reg_a * val_reg_c);
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
|
||||
ppc_dblresult64_d += val_reg_b;
|
||||
}
|
||||
}
|
||||
ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, val_reg_b);
|
||||
|
||||
ppc_store_dfpresult_flt(reg_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, FMADD>(reg_a, reg_b, reg_c);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
ppc_changecrf1();
|
||||
@ -387,14 +351,15 @@ void dppc_interpreter::ppc_fmadd() {
|
||||
void dppc_interpreter::ppc_fmsub() {
|
||||
ppc_grab_regsfpdabc();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
|
||||
ppc_dblresult64_d = (val_reg_a * val_reg_c);
|
||||
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
|
||||
ppc_dblresult64_d -= val_reg_b;
|
||||
}
|
||||
}
|
||||
ppc_dblresult64_d = (val_reg_a * val_reg_c);
|
||||
ppc_dblresult64_d -= val_reg_b;
|
||||
|
||||
ppc_store_dfpresult_flt(reg_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, FMSUB>(reg_a, reg_b, reg_c);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
ppc_changecrf1();
|
||||
@ -403,15 +368,16 @@ void dppc_interpreter::ppc_fmsub() {
|
||||
void dppc_interpreter::ppc_fnmadd() {
|
||||
ppc_grab_regsfpdabc();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
|
||||
ppc_dblresult64_d = (val_reg_a * val_reg_c);
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
|
||||
ppc_dblresult64_d += val_reg_b;
|
||||
}
|
||||
}
|
||||
ppc_dblresult64_d = (val_reg_a * val_reg_c);
|
||||
ppc_dblresult64_d += val_reg_b;
|
||||
|
||||
ppc_dblresult64_d = -ppc_dblresult64_d;
|
||||
ppc_store_dfpresult_flt(reg_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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
ppc_changecrf1();
|
||||
@ -420,15 +386,16 @@ void dppc_interpreter::ppc_fnmadd() {
|
||||
void dppc_interpreter::ppc_fnmsub() {
|
||||
ppc_grab_regsfpdabc();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
|
||||
ppc_dblresult64_d = (val_reg_a * val_reg_c);
|
||||
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
|
||||
ppc_dblresult64_d -= val_reg_b;
|
||||
}
|
||||
}
|
||||
ppc_dblresult64_d = (val_reg_a * val_reg_c);
|
||||
ppc_dblresult64_d -= val_reg_b;
|
||||
ppc_dblresult64_d = -ppc_dblresult64_d;
|
||||
|
||||
ppc_store_dfpresult_flt(reg_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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
ppc_changecrf1();
|
||||
@ -437,10 +404,14 @@ void dppc_interpreter::ppc_fnmsub() {
|
||||
void dppc_interpreter::ppc_fadds() {
|
||||
ppc_grab_regsfpdab();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
|
||||
float intermediate = (float)val_reg_a + (float)val_reg_b;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
float intermediate = (float)val_reg_a + (float)val_reg_b;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -450,23 +421,14 @@ void dppc_interpreter::ppc_fadds() {
|
||||
void dppc_interpreter::ppc_fsubs() {
|
||||
ppc_grab_regsfpdab();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 56)) {
|
||||
float intermediate = (float)val_reg_a - (float)val_reg_b;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
ppc_store_sfpresult_flt(reg_d);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
ppc_changecrf1();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_fmuls() {
|
||||
ppc_grab_regsfpdac();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_c, true, 50)) {
|
||||
float intermediate = (float)val_reg_a * (float)val_reg_c;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
float intermediate = (float)val_reg_a - (float)val_reg_b;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -476,10 +438,31 @@ void dppc_interpreter::ppc_fmuls() {
|
||||
void dppc_interpreter::ppc_fdivs() {
|
||||
ppc_grab_regsfpdab();
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 36)) {
|
||||
float intermediate = (float)val_reg_a / (float)val_reg_b;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
float intermediate = (float)val_reg_a / (float)val_reg_b;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
ppc_changecrf1();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_fmuls() {
|
||||
ppc_grab_regsfpdac();
|
||||
|
||||
float intermediate = (float)val_reg_a * (float)val_reg_c;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -489,16 +472,14 @@ void dppc_interpreter::ppc_fdivs() {
|
||||
void dppc_interpreter::ppc_fmadds() {
|
||||
ppc_grab_regsfpdabc();
|
||||
|
||||
float intermediate;
|
||||
ppc_dblresult64_d = static_cast<double>(
|
||||
std::fma((float)val_reg_a, (float)val_reg_c, (float)val_reg_b));
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
|
||||
intermediate = (float)val_reg_a * (float)val_reg_c;
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
|
||||
intermediate += (float)val_reg_b;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
ppc_store_sfpresult_flt(reg_d);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -508,16 +489,15 @@ void dppc_interpreter::ppc_fmadds() {
|
||||
void dppc_interpreter::ppc_fmsubs() {
|
||||
ppc_grab_regsfpdabc();
|
||||
|
||||
float intermediate;
|
||||
float intermediate = (float)val_reg_a * (float)val_reg_c;
|
||||
intermediate -= (float)val_reg_b;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
|
||||
intermediate = (float)val_reg_a * (float)val_reg_c;
|
||||
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
|
||||
intermediate -= (float)val_reg_b;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
ppc_store_sfpresult_flt(reg_d);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -527,18 +507,16 @@ void dppc_interpreter::ppc_fmsubs() {
|
||||
void dppc_interpreter::ppc_fnmadds() {
|
||||
ppc_grab_regsfpdabc();
|
||||
|
||||
float intermediate;
|
||||
float intermediate = (float)val_reg_a * (float)val_reg_c;
|
||||
intermediate += (float)val_reg_b;
|
||||
intermediate = -intermediate;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
|
||||
intermediate = (float)val_reg_a * (float)val_reg_c;
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
|
||||
intermediate += (float)val_reg_b;
|
||||
intermediate = -intermediate;
|
||||
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
ppc_store_sfpresult_flt(reg_d);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -548,18 +526,17 @@ void dppc_interpreter::ppc_fnmadds() {
|
||||
void dppc_interpreter::ppc_fnmsubs() {
|
||||
ppc_grab_regsfpdabc();
|
||||
|
||||
float intermediate;
|
||||
float intermediate = (float)val_reg_a * (float)val_reg_c;
|
||||
intermediate -= (float)val_reg_b;
|
||||
intermediate = -intermediate;
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
|
||||
intermediate = (float)val_reg_a * (float)val_reg_c;
|
||||
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
|
||||
intermediate -= (float)val_reg_b;
|
||||
intermediate = -intermediate;
|
||||
|
||||
ppc_dblresult64_d = static_cast<double>(intermediate);
|
||||
|
||||
ppc_store_sfpresult_flt(reg_d);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
@ -603,7 +580,7 @@ void dppc_interpreter::ppc_fneg() {
|
||||
void dppc_interpreter::ppc_fsel() {
|
||||
ppc_grab_regsfpdabc();
|
||||
|
||||
ppc_dblresult64_d = (val_reg_a >= 0.0) ? val_reg_c : val_reg_b;
|
||||
ppc_dblresult64_d = (val_reg_a >= -0.0) ? val_reg_c : val_reg_b;
|
||||
|
||||
ppc_store_dfpresult_flt(reg_d);
|
||||
|
||||
@ -658,11 +635,23 @@ void dppc_interpreter::ppc_frsp() {
|
||||
|
||||
void dppc_interpreter::ppc_fres() {
|
||||
ppc_grab_regsfpdb();
|
||||
float testf2 = (float)GET_FPR(reg_b);
|
||||
double start_num = GET_FPR(reg_b);
|
||||
float testf2 = (float)start_num;
|
||||
testf2 = 1 / testf2;
|
||||
ppc_dblresult64_d = (double)testf2;
|
||||
ppc_store_dfpresult_flt(reg_d);
|
||||
|
||||
if (start_num == 0.0) {
|
||||
ppc_state.fpscr |= FPSCR::ZX;
|
||||
}
|
||||
else if (std::isnan(start_num)) {
|
||||
ppc_state.fpscr |= FPSCR::VXSNAN;
|
||||
}
|
||||
else if (std::isinf(start_num)){
|
||||
ppc_state.fpscr |= FPSCR::VXSNAN;
|
||||
ppc_state.fpscr &= 0xFFF9FFFF;
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
ppc_changecrf1();
|
||||
}
|
||||
@ -673,26 +662,30 @@ void dppc_interpreter::ppc_fctiw() {
|
||||
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_state.fpr[reg_d].int64_r = 0x80000000;
|
||||
ppc_state.fpscr |= 0x1000100;
|
||||
ppc_state.fpscr |= FPSCR::VXSNAN | FPSCR::VXCVI;
|
||||
}
|
||||
else if (val_reg_b > static_cast<double>(0x7fffffff)) {
|
||||
ppc_state.fpr[reg_d].int64_r = 0x7fffffff;
|
||||
ppc_state.fpscr |= 0x100;
|
||||
ppc_state.fpscr |= FPSCR::VXCVI;
|
||||
}
|
||||
else if (val_reg_b < -static_cast<double>(0x80000000)) {
|
||||
ppc_state.fpr[reg_d].int64_r = 0x80000000;
|
||||
ppc_state.fpscr |= 0x100;
|
||||
ppc_state.fpscr |= FPSCR::VXCVI;
|
||||
}
|
||||
else {
|
||||
switch (ppc_state.fpscr & 0x3) {
|
||||
case 0:
|
||||
ppc_result64_d = round_to_nearest(val_reg_b);
|
||||
break;
|
||||
case 1:
|
||||
ppc_result64_d = round_to_zero(val_reg_b);
|
||||
break;
|
||||
case 2:
|
||||
ppc_result64_d = round_to_pos_inf(val_reg_b);
|
||||
break;
|
||||
case 3:
|
||||
ppc_result64_d = round_to_neg_inf(val_reg_b);
|
||||
break;
|
||||
}
|
||||
|
||||
ppc_store_dfpresult_int(reg_d);
|
||||
@ -709,15 +702,15 @@ void dppc_interpreter::ppc_fctiwz() {
|
||||
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_state.fpr[reg_d].int64_r = 0x80000000;
|
||||
ppc_state.fpscr |= 0x1000100;
|
||||
ppc_state.fpscr |= FPSCR::VXSNAN | FPSCR::VXCVI;
|
||||
}
|
||||
else if (val_reg_b > static_cast<double>(0x7fffffff)) {
|
||||
ppc_state.fpr[reg_d].int64_r = 0x7fffffff;
|
||||
ppc_state.fpscr |= 0x100;
|
||||
ppc_state.fpscr |= FPSCR::VXCVI;
|
||||
}
|
||||
else if (val_reg_b < -static_cast<double>(0x80000000)) {
|
||||
ppc_state.fpr[reg_d].int64_r = 0x80000000;
|
||||
ppc_state.fpscr |= 0x100;
|
||||
ppc_state.fpscr |= FPSCR::VXCVI;
|
||||
}
|
||||
else {
|
||||
ppc_result64_d = round_to_zero(val_reg_b);
|
||||
@ -914,22 +907,14 @@ void dppc_interpreter::ppc_fmr() {
|
||||
ppc_state.fpr[reg_d].dbl64_r = ppc_state.fpr[reg_b].dbl64_r;
|
||||
}
|
||||
|
||||
|
||||
void dppc_interpreter::ppc_mffs() {
|
||||
ppc_grab_regsda();
|
||||
uint64_t fpstore1 = ppc_state.fpr[reg_d].int64_r & 0xFFFFFFFF00000000;
|
||||
uint64_t fpstore2 = ppc_state.fpscr & 0x00000000FFFFFFFF;
|
||||
fpstore1 |= fpstore2;
|
||||
uint64_t fpstore1 = ppc_state.fpr[reg_d].int64_r & ((uint64_t)0xFFF80000 << 32);
|
||||
fpstore1 |= (uint64_t)ppc_state.fpscr;
|
||||
fp_save_uint64(fpstore1);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mffsdot() {
|
||||
ppc_grab_regsda();
|
||||
uint64_t fpstore1 = ppc_state.fpr[reg_d].int64_r & 0xFFFFFFFF00000000;
|
||||
uint64_t fpstore2 = ppc_state.fpscr & 0x00000000FFFFFFFF;
|
||||
fpstore1 |= fpstore2;
|
||||
fp_save_uint64(fpstore1);
|
||||
ppc_fp_changecrf1();
|
||||
if (rc_flag)
|
||||
ppc_fp_changecrf1();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mtfsf() {
|
||||
@ -945,22 +930,9 @@ void dppc_interpreter::ppc_mtfsf() {
|
||||
crm += (((fm_mask >> 7) & 1) == 1) ? 0x0000000F : 0x00000000;
|
||||
uint32_t quickfprval = (uint32_t)ppc_state.fpr[reg_b].int64_r;
|
||||
ppc_state.fpscr = (quickfprval & crm) | (quickfprval & ~(crm));
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mtfsfdot() {
|
||||
reg_b = (ppc_cur_instruction >> 11) & 31;
|
||||
uint32_t fm_mask = (ppc_cur_instruction >> 17) & 255;
|
||||
crm += ((fm_mask & 1) == 1) ? 0xF0000000 : 0x00000000;
|
||||
crm += (((fm_mask >> 1) & 1) == 1) ? 0x0F000000 : 0x00000000;
|
||||
crm += (((fm_mask >> 2) & 1) == 1) ? 0x00F00000 : 0x00000000;
|
||||
crm += (((fm_mask >> 3) & 1) == 1) ? 0x000F0000 : 0x00000000;
|
||||
crm += (((fm_mask >> 4) & 1) == 1) ? 0x0000F000 : 0x00000000;
|
||||
crm += (((fm_mask >> 5) & 1) == 1) ? 0x00000F00 : 0x00000000;
|
||||
crm += (((fm_mask >> 6) & 1) == 1) ? 0x000000F0 : 0x00000000;
|
||||
crm += (((fm_mask >> 7) & 1) == 1) ? 0x0000000F : 0x00000000;
|
||||
uint32_t quickfprval = (uint32_t)ppc_state.fpr[reg_b].int64_r;
|
||||
ppc_state.fpscr = (quickfprval & crm) | (quickfprval & ~(crm));
|
||||
ppc_fp_changecrf1();
|
||||
if (rc_flag)
|
||||
ppc_fp_changecrf1();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mtfsfi() {
|
||||
@ -969,15 +941,9 @@ void dppc_interpreter::ppc_mtfsfi() {
|
||||
crf_d = crf_d << 2;
|
||||
ppc_state.fpscr = (ppc_state.cr & ~(0xF0000000UL >> crf_d)) |
|
||||
((ppc_state.spr[SPR::XER] & 0xF0000000UL) >> crf_d);
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mtfsfidot() {
|
||||
ppc_result_b = (ppc_cur_instruction >> 11) & 15;
|
||||
crf_d = (ppc_cur_instruction >> 23) & 7;
|
||||
crf_d = crf_d << 2;
|
||||
ppc_state.fpscr = (ppc_state.cr & ~(0xF0000000UL >> crf_d)) |
|
||||
((ppc_state.spr[SPR::XER] & 0xF0000000UL) >> crf_d);
|
||||
ppc_fp_changecrf1();
|
||||
if (rc_flag)
|
||||
ppc_fp_changecrf1();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mtfsb0() {
|
||||
@ -985,14 +951,9 @@ void dppc_interpreter::ppc_mtfsb0() {
|
||||
if ((crf_d == 0) || (crf_d > 2)) {
|
||||
ppc_state.fpscr &= ~(0x80000000UL >> crf_d);
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mtfsb0dot() {
|
||||
crf_d = (ppc_cur_instruction >> 21) & 0x1F;
|
||||
if ((crf_d == 0) || (crf_d > 2)) {
|
||||
ppc_state.fpscr &= ~(0x80000000UL >> crf_d);
|
||||
}
|
||||
ppc_fp_changecrf1();
|
||||
if (rc_flag)
|
||||
ppc_fp_changecrf1();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mtfsb1() {
|
||||
@ -1000,14 +961,9 @@ void dppc_interpreter::ppc_mtfsb1() {
|
||||
if ((crf_d == 0) || (crf_d > 2)) {
|
||||
ppc_state.fpscr |= (0x80000000UL >> crf_d);
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mtfsb1dot() {
|
||||
crf_d = (ppc_cur_instruction >> 21) & 0x1F;
|
||||
if ((crf_d == 0) || (crf_d > 2)) {
|
||||
ppc_state.fpscr |= (0x80000000UL >> crf_d);
|
||||
}
|
||||
ppc_fp_changecrf1();
|
||||
if (rc_flag)
|
||||
ppc_fp_changecrf1();
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mcrfs() {
|
||||
@ -1027,25 +983,28 @@ void dppc_interpreter::ppc_fcmpo() {
|
||||
ppc_state.fpscr &= 0xFFFF0FFF;
|
||||
|
||||
if (std::isnan(db_test_a) || std::isnan(db_test_b)) {
|
||||
cmp_c |= 0x01;
|
||||
cmp_c |= (1 << (uint32_t)CRx_bit::CR_SO);
|
||||
} else if (db_test_a < db_test_b) {
|
||||
cmp_c |= 0x08;
|
||||
cmp_c |= (1 << (uint32_t)CRx_bit::CR_LT);
|
||||
} else if (db_test_a > db_test_b) {
|
||||
cmp_c |= 0x04;
|
||||
cmp_c |= (1 << (uint32_t)CRx_bit::CR_GT);
|
||||
} else {
|
||||
cmp_c |= 0x02;
|
||||
cmp_c |= (1 << (uint32_t)CRx_bit::CR_EQ);
|
||||
}
|
||||
|
||||
ppc_state.fpscr |= (cmp_c << 12);
|
||||
ppc_state.cr = ((ppc_state.cr & ~(0xf0000000 >> crf_d)) | ((cmp_c + xercon) >> crf_d));
|
||||
fpresult_update(db_test_a, true);
|
||||
|
||||
if ((db_test_a == snan) || (db_test_b == snan)) {
|
||||
ppc_state.fpscr |= 0x1000000;
|
||||
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FPRF)) | (cmp_c << 12);
|
||||
ppc_state.cr =
|
||||
((ppc_state.cr & ~((uint32_t)CR_select::CR0_field >> crf_d)) | ((cmp_c + xercon) >> crf_d));
|
||||
|
||||
if (std::isnan(db_test_a) || std::isnan(db_test_b)) {
|
||||
ppc_state.fpscr |= FPSCR::VXSNAN;
|
||||
if (ppc_state.fpscr & 0x80) {
|
||||
ppc_state.fpscr |= 0x80000;
|
||||
ppc_state.fpscr |= FPSCR::VXVC;
|
||||
}
|
||||
} else if ((db_test_a == qnan) || (db_test_b == qnan)) {
|
||||
ppc_state.fpscr |= 0x80000;
|
||||
ppc_state.fpscr |= FPSCR::VXVC;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1055,19 +1014,22 @@ void dppc_interpreter::ppc_fcmpu() {
|
||||
ppc_state.fpscr &= 0xFFFF0FFF;
|
||||
|
||||
if (std::isnan(db_test_a) || std::isnan(db_test_b)) {
|
||||
cmp_c |= 0x01;
|
||||
cmp_c |= (1 << (uint32_t)CRx_bit::CR_SO);
|
||||
} else if (db_test_a < db_test_b) {
|
||||
cmp_c |= 0x08;
|
||||
cmp_c |= (1 << (uint32_t)CRx_bit::CR_LT);
|
||||
} else if (db_test_a > db_test_b) {
|
||||
cmp_c |= 0x04;
|
||||
cmp_c |= (1 << (uint32_t)CRx_bit::CR_GT);
|
||||
} else {
|
||||
cmp_c |= 0x02;
|
||||
cmp_c |= (1 << (uint32_t)CRx_bit::CR_EQ);
|
||||
}
|
||||
|
||||
ppc_state.fpscr |= (cmp_c << 12);
|
||||
ppc_state.cr = ((ppc_state.cr & ~(0xf0000000 >> crf_d)) | ((cmp_c + xercon) >> crf_d));
|
||||
fpresult_update(db_test_a, true);
|
||||
|
||||
if ((db_test_a == snan) || (db_test_b == snan)) {
|
||||
ppc_state.fpscr |= 0x1000000;
|
||||
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FPRF)) | (cmp_c << 12);
|
||||
ppc_state.cr =
|
||||
((ppc_state.cr & ~((uint32_t)CR_select::CR0_field >> crf_d)) | ((cmp_c + xercon) >> crf_d));
|
||||
|
||||
if (std::isnan(db_test_a) || std::isnan(db_test_b)) {
|
||||
ppc_state.fpscr |= FPSCR::VXSNAN;
|
||||
}
|
||||
}
|
||||
|
@ -127,14 +127,18 @@ def gen_ppc_opcode(opc_str, imm):
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x12 << 1)
|
||||
elif opc_str == "FDIV.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x12 << 1) + 1
|
||||
elif opc_str == "FDIVS":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x12 << 1)
|
||||
elif opc_str == "FDIVS.":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x12 << 1) + 1
|
||||
elif opc_str == "FMADD":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1D << 1)
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1D << 1)
|
||||
elif opc_str == "FMADD.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1D << 1) + 1
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1D << 1) + 1
|
||||
elif opc_str == "FMADDS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1D << 1)
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1D << 1)
|
||||
elif opc_str == "FMADDS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1D << 1) + 1
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1D << 1) + 1
|
||||
elif opc_str == "FMUL":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x19 << 1)
|
||||
elif opc_str == "FMUL.":
|
||||
@ -152,29 +156,29 @@ def gen_ppc_opcode(opc_str, imm):
|
||||
elif opc_str == "FMULS.":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x28 << 1) + 1
|
||||
elif opc_str == "FMSUB":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1)
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1C << 1)
|
||||
elif opc_str == "FMSUB.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1) + 1
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1C << 1) + 1
|
||||
elif opc_str == "FMSUBS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1)
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1C << 1)
|
||||
elif opc_str == "FMSUBS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1) + 1
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1C << 1) + 1
|
||||
elif opc_str == "FNMADD":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1F << 1)
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1F << 1)
|
||||
elif opc_str == "FNMADD.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1F << 1) + 1
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1F << 1) + 1
|
||||
elif opc_str == "FNMADDS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1F << 1)
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1F << 1)
|
||||
elif opc_str == "FNMADDS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1F << 1) + 1
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1F << 1) + 1
|
||||
elif opc_str == "FNMSUB":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1)
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1C << 1)
|
||||
elif opc_str == "FNMSUB.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1) + 1
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1C << 1) + 1
|
||||
elif opc_str == "FNMSUBS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1)
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1C << 1)
|
||||
elif opc_str == "FNMSUBS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1) + 1
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (5 << 6) + (0x1C << 1) + 1
|
||||
elif opc_str == "FSUB":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x15 << 1)
|
||||
elif opc_str == "FSUB.":
|
||||
@ -346,7 +350,6 @@ def extract_rot_params(line):
|
||||
pos += 16
|
||||
return (sh, mb, me)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("ppcinttest.txt", "r") as in_file:
|
||||
with open("ppcinttests.csv", "w") as out_file:
|
||||
@ -404,41 +407,152 @@ if __name__ == "__main__":
|
||||
|
||||
line = line.strip()
|
||||
opcode = (line[0:8]).rstrip().upper()
|
||||
out_file.write(opcode + ",")
|
||||
out_file.write(opcode+ ",")
|
||||
out_file.write("0x{:X}".format(gen_ppc_opcode(opcode, 0)))
|
||||
|
||||
if opcode.startswith("RLWI"):
|
||||
sh, mb, me = extract_rot_params(line)
|
||||
out_file.write("0x{:X}".format(gen_rot_opcode(opcode, sh, mb, me)))
|
||||
else:
|
||||
imm = extract_imm(line)
|
||||
out_file.write("0x{:X}".format(gen_ppc_opcode(opcode, imm)))
|
||||
|
||||
pos = 12
|
||||
pos = 10
|
||||
checkstring = ''
|
||||
|
||||
while pos < len(line):
|
||||
reg_id = line[pos:pos+4]
|
||||
if reg_id.startswith("frD"):
|
||||
out_file.write(",frD=" + line[pos+4:pos+14])
|
||||
pos += 16
|
||||
elif reg_id.startswith("frA"):
|
||||
out_file.write(",frA=" + line[pos+4:pos+14])
|
||||
pos += 16
|
||||
elif reg_id.startswith("frB"):
|
||||
out_file.write(",frB=" + line[pos+4:pos+14])
|
||||
pos += 16
|
||||
elif reg_id.startswith("frC"):
|
||||
out_file.write(",frC=" + line[pos+4:pos+14])
|
||||
pos += 16
|
||||
elif reg_id.startswith("FPSCR:"):
|
||||
out_file.write(",FPSCR=" + line[pos+7:pos+17])
|
||||
pos += 19
|
||||
elif reg_id.startswith("CR:"):
|
||||
out_file.write(",CR=" + line[pos+4:pos+14])
|
||||
pos += 17
|
||||
elif reg_id.startswith("imm"):
|
||||
pos += 17 # ignore immediate operands
|
||||
else:
|
||||
out_file.write("Unknown reg ID" + reg_id)
|
||||
break
|
||||
if (line[pos].isalnum()):
|
||||
checkstring += line[pos]
|
||||
|
||||
if ("RTN" in checkstring):
|
||||
if (line[pos+1:pos+2] == "I"):
|
||||
out_file.write(",round=RNI")
|
||||
checkstring = ''
|
||||
else:
|
||||
out_file.write(",round=RTN")
|
||||
checkstring = ''
|
||||
pos += 1
|
||||
elif ("RTZ" in checkstring):
|
||||
out_file.write(",round=RTZ")
|
||||
checkstring = ''
|
||||
pos += 1
|
||||
elif ("RTPI" in checkstring):
|
||||
out_file.write(",round=RPI")
|
||||
checkstring = ''
|
||||
pos += 1
|
||||
elif ("VE" in checkstring):
|
||||
out_file.write(",round=VEN")
|
||||
checkstring = ''
|
||||
pos += 1
|
||||
elif ("frD" in checkstring):
|
||||
out_file.write(",frD=0x" + line[pos+4:pos+20])
|
||||
checkstring = ''
|
||||
elif ("frA" in checkstring): #sloppy temp code
|
||||
check2 = line[pos+1:pos+10]
|
||||
if ("-inf" in check2):
|
||||
out_file.write(",frA=-inf")
|
||||
elif ("inf" in check2):
|
||||
out_file.write(",frA=inf")
|
||||
pos += 1
|
||||
elif ("nan" in check2):
|
||||
out_file.write(",frA=nan")
|
||||
pos += 1
|
||||
elif ("-0." or "-2." or "-4." or \
|
||||
"-6." or "-8." or "-7." or\
|
||||
"-5." or "-3." or "-1." or \
|
||||
"-9." in check2):
|
||||
get_pos = line[pos+2:pos+16].strip("|")
|
||||
out_file.write(",frA=" + get_pos.strip())
|
||||
elif ("0." or "2." or "4." or \
|
||||
"6." or "8." or "7." or\
|
||||
"5." or "3." or "1." or \
|
||||
"9." in check2):
|
||||
get_pos = line[pos+2:pos+15]
|
||||
out_file.write(",frA=" + get_pos.strip())
|
||||
checkstring = ''
|
||||
elif ("frB" in checkstring): #sloppy temp code
|
||||
check2 = line[pos+1:pos+10]
|
||||
if ("-inf" in check2):
|
||||
out_file.write(",frB=-inf")
|
||||
elif ("inf" in check2):
|
||||
out_file.write(",frB=inf")
|
||||
pos += 1
|
||||
elif ("nan" in check2):
|
||||
out_file.write(",frB=nan")
|
||||
pos += 1
|
||||
elif ("-0." or "-2." or "-4." or \
|
||||
"-6." or "-8." or "-7." or\
|
||||
"-5." or "-3." or "-1." or \
|
||||
"-9." in check2):
|
||||
get_pos = line[pos+2:pos+16].strip("|")
|
||||
out_file.write(",frB=" + get_pos.strip())
|
||||
elif ("0." or "2." or "4." or \
|
||||
"6." or "8." or "7." or\
|
||||
"5." or "3." or "1." or \
|
||||
"9." in check2):
|
||||
get_pos = line[pos+2:pos+15]
|
||||
out_file.write(",frB=" + get_pos.strip())
|
||||
checkstring = ''
|
||||
elif ("frC" in checkstring): #sloppy temp code
|
||||
check2 = line[pos+1:pos+10]
|
||||
if ("-inf" in check2):
|
||||
out_file.write(",frC=-inf")
|
||||
elif ("inf" in check2):
|
||||
out_file.write(",frC=inf")
|
||||
pos += 1
|
||||
elif ("nan" in check2):
|
||||
out_file.write(",frC=nan")
|
||||
pos += 1
|
||||
elif ("-0." or "-2." or "-4." or \
|
||||
"-6." or "-8." or "-7." or\
|
||||
"-5." or "-3." or "-1." or \
|
||||
"-9." in check2):
|
||||
get_pos = line[pos+2:pos+16].strip("|")
|
||||
out_file.write(",frC=" + get_pos.strip())
|
||||
elif ("0." or "2." or "4." or \
|
||||
"6." or "8." or "7." or\
|
||||
"5." or "3." or "1." or \
|
||||
"9." in check2):
|
||||
get_pos = line[pos+2:pos+15]
|
||||
out_file.write(",frC=" + get_pos.strip())
|
||||
checkstring = ''
|
||||
elif ("FPSCR" in checkstring):
|
||||
out_file.write(",FPSCR=" + line[pos+3:pos+13])
|
||||
checkstring = ''
|
||||
elif ("CR" in checkstring):
|
||||
out_file.write(",CR=0x0" + line[pos+6:pos+14])
|
||||
checkstring = ''
|
||||
pos += 1
|
||||
|
||||
out_file.write("\n")
|
||||
# reg_id = line[pos:pos+4]
|
||||
# if reg_id.startswith("frD"):
|
||||
# out_file.write(",frD=" + line[pos+4:pos+22])
|
||||
# pos += 24
|
||||
# elif reg_id.startswith("frA"):
|
||||
# out_file.write(",frA=" + line[pos+4:pos+14])
|
||||
# pos += 16
|
||||
# elif reg_id.startswith("frB"):
|
||||
# out_file.write(",frB=" + line[pos+4:pos+14])
|
||||
# pos += 16
|
||||
# elif reg_id.startswith("frC"):
|
||||
# out_file.write(",frC=" + line[pos+4:pos+14])
|
||||
# pos += 16
|
||||
# elif reg_id.startswith("FPSCR:"):
|
||||
# out_file.write(",FPSCR=" + line[pos+7:pos+17])
|
||||
# pos += 19
|
||||
# elif reg_id.startswith("CR:"):
|
||||
# out_file.write(",CR=" + line[pos+4:pos+14])
|
||||
# pos += 17
|
||||
# elif reg_id.startswith("VE)"):
|
||||
# out_file.write("round=VEN" + line[pos+4:pos+20])
|
||||
# pos += 17
|
||||
# elif reg_id.startswith("TN)"):
|
||||
# out_file.write("round=RTN" + line[pos+4:pos+20])
|
||||
# pos += 17
|
||||
# elif reg_id.startswith("TZ)"):
|
||||
# out_file.write("round=RTZ" + line[pos+4:pos+20])
|
||||
# pos += 17
|
||||
# elif reg_id.startswith("NI)"):
|
||||
# out_file.write("round=RNI" + line[pos+4:pos+20])
|
||||
# pos += 17
|
||||
# elif reg_id.startswith("PI)"):
|
||||
# out_file.write("round=RPI" + line[pos+4:pos+20])
|
||||
# pos += 17
|
||||
# else:
|
||||
# out_file.write("Unknown reg ID" + reg_id)
|
||||
# break
|
||||
|
||||
out_file.write("\n")
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
#include "../ppcdisasm.h"
|
||||
#include "../ppcemu.h"
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
@ -148,7 +149,7 @@ static void read_test_float_data() {
|
||||
|
||||
uint32_t opcode, dest, src1, src2, check_xer, check_cr, check_fpscr;
|
||||
uint64_t dest_64, src1_64, src2_64;
|
||||
float sfp_dest, sfp_src1, sfp_src2, sfp_src3;
|
||||
//float sfp_dest, sfp_src1, sfp_src2, sfp_src3;
|
||||
double dfp_dest, dfp_src1, dfp_src2, dfp_src3;
|
||||
string rounding_mode;
|
||||
|
||||
@ -181,48 +182,50 @@ static void read_test_float_data() {
|
||||
|
||||
opcode = stoul(tokens[1], NULL, 16);
|
||||
|
||||
dest = 0;
|
||||
src1 = 0;
|
||||
src2 = 0;
|
||||
check_xer = 0;
|
||||
check_cr = 0;
|
||||
check_fpscr = 0;
|
||||
sfp_dest = 0.0;
|
||||
sfp_src1 = 0.0;
|
||||
sfp_src2 = 0.0;
|
||||
sfp_src3 = 0.0;
|
||||
//sfp_dest = 0.0;
|
||||
//sfp_src1 = 0.0;
|
||||
//sfp_src2 = 0.0;
|
||||
//sfp_src3 = 0.0;
|
||||
dfp_dest = 0.0;
|
||||
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 = stoul(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 = stoul(tokens[i].substr(4), NULL, 16);
|
||||
dfp_src1 = stod(tokens[i].substr(4), NULL);
|
||||
} else if (tokens[i].rfind("frB=", 0) == 0) {
|
||||
dfp_src2 = stoul(tokens[i].substr(4), NULL, 16);
|
||||
dfp_src2 = stod(tokens[i].substr(4), NULL);
|
||||
} else if (tokens[i].rfind("frC=", 0) == 0) {
|
||||
dfp_src3 = stoul(tokens[i].substr(4), NULL, 16);
|
||||
dfp_src3 = stod(tokens[i].substr(4), NULL);
|
||||
} else if (tokens[i].rfind("round=", 0) == 0) {
|
||||
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;
|
||||
} else {
|
||||
cout << "ILLEGAL ROUNDING METHOD: " << tokens[i] << " in line " << lineno
|
||||
<< ". Exiting..." << endl;
|
||||
exit(0);
|
||||
}
|
||||
} else if (tokens[i].rfind("FPSCR=", 0) == 0) {
|
||||
check_cr = stoul(tokens[i].substr(6), NULL, 16);
|
||||
check_fpscr = stoul(tokens[i].substr(6), NULL, 16);
|
||||
} else if (tokens[i].rfind("CR=", 0) == 0) {
|
||||
check_cr = stoul(tokens[i].substr(3), NULL, 16);
|
||||
} else {
|
||||
@ -239,7 +242,6 @@ static void read_test_float_data() {
|
||||
ppc_state.fpr[4].dbl64_r = dfp_src2;
|
||||
ppc_state.fpr[5].dbl64_r = dfp_src3;
|
||||
|
||||
ppc_state.spr[SPR::XER] = 0;
|
||||
ppc_state.cr = 0;
|
||||
|
||||
ppc_cur_instruction = opcode;
|
||||
@ -248,13 +250,14 @@ static void read_test_float_data() {
|
||||
|
||||
ntested++;
|
||||
|
||||
if ((tokens[0].rfind("FCMP") && (ppc_state.gpr[3] != dest)) || (ppc_state.fpscr != check_fpscr) ||
|
||||
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=0x" << hex << src1 << ", src2=0x" << hex
|
||||
<< src2 << endl;
|
||||
cout << "expected: dest=0x" << hex << dest << ", FPSCR=0x" << hex << check_xer << ", CR=0x"
|
||||
cout << "Mismatch: instr=" << tokens[0] << ", src1=" << scientific << dfp_src1 << ", src2=" << scientific << dfp_src2 << ", src3=" << scientific << dfp_src3 << endl;
|
||||
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.gpr[3] << ", 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…
Reference in New Issue
Block a user