mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-06-12 11:29:29 +00:00
ppcfpopcodes: Fix fctiw/fctiwz.
This commit is contained in:
parent
bd419912b5
commit
0100e67ebf
|
@ -420,6 +420,7 @@ void update_fpscr(uint32_t new_fpscr);
|
||||||
/* Exception handlers. */
|
/* Exception handlers. */
|
||||||
void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits);
|
void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits);
|
||||||
[[noreturn]] void dbg_exception_handler(Except_Type exception_type, uint32_t srr1_bits);
|
[[noreturn]] void dbg_exception_handler(Except_Type exception_type, uint32_t srr1_bits);
|
||||||
|
void ppc_floating_point_exception();
|
||||||
|
|
||||||
// MEMORY DECLARATIONS
|
// MEMORY DECLARATIONS
|
||||||
extern MemCtrlBase* mem_ctrl_instance;
|
extern MemCtrlBase* mem_ctrl_instance;
|
||||||
|
|
|
@ -194,3 +194,9 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
|
||||||
|
|
||||||
throw std::invalid_argument(exc_descriptor);
|
throw std::invalid_argument(exc_descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ppc_floating_point_exception() {
|
||||||
|
LOG_F(ERROR, "Floating point exception at 0x%08x for instruction 0x%08x",
|
||||||
|
ppc_state.pc, ppc_cur_instruction);
|
||||||
|
// mmu_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::FPU_EXCEPTION);
|
||||||
|
}
|
||||||
|
|
|
@ -631,16 +631,38 @@ void dppc_interpreter::ppc_fctiw() {
|
||||||
double val_reg_b = GET_FPR(reg_b);
|
double val_reg_b = GET_FPR(reg_b);
|
||||||
|
|
||||||
if (std::isnan(val_reg_b)) {
|
if (std::isnan(val_reg_b)) {
|
||||||
ppc_state.fpr[reg_d].int64_r = 0x80000000;
|
if (ppc_state.fpr[reg_b].int64_r & 0x0008000000000000) {
|
||||||
ppc_state.fpscr |= FPSCR::VXSNAN | FPSCR::VXCVI;
|
// isqnan
|
||||||
|
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FR | FPSCR::FI)) | FPSCR::VXCVI;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// issnan
|
||||||
|
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FR | FPSCR::FI)) | FPSCR::VXCVI | FPSCR::VXSNAN;
|
||||||
|
}
|
||||||
|
if (ppc_state.fpscr & FPSCR::VE) {
|
||||||
|
ppc_floating_point_exception();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ppc_state.fpr[reg_d].int64_r = 0xfff8000080000000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (val_reg_b > static_cast<double>(0x7fffffff)) {
|
else if (val_reg_b > static_cast<double>(0x7fffffff)) {
|
||||||
ppc_state.fpr[reg_d].int64_r = 0x7fffffff;
|
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FR | FPSCR::FI)) | FPSCR::VXCVI;
|
||||||
ppc_state.fpscr |= FPSCR::VXCVI;
|
if (ppc_state.fpscr & FPSCR::VE) {
|
||||||
|
ppc_floating_point_exception();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ppc_state.fpr[reg_d].int64_r = 0xfff800007fffffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (val_reg_b < -static_cast<double>(0x80000000)) {
|
else if (val_reg_b < -static_cast<double>(0x80000000)) {
|
||||||
ppc_state.fpr[reg_d].int64_r = 0x80000000;
|
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FR | FPSCR::FI)) | FPSCR::VXCVI;
|
||||||
ppc_state.fpscr |= FPSCR::VXCVI;
|
if (ppc_state.fpscr & FPSCR::VE) {
|
||||||
|
ppc_floating_point_exception();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ppc_state.fpr[reg_d].int64_r = 0xfff8000080000000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
switch (ppc_state.fpscr & 0x3) {
|
switch (ppc_state.fpscr & 0x3) {
|
||||||
|
@ -659,7 +681,6 @@ void dppc_interpreter::ppc_fctiw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ppc_store_dfpresult_int(reg_d);
|
ppc_store_dfpresult_int(reg_d);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc_flag)
|
if (rc_flag)
|
||||||
|
@ -671,20 +692,41 @@ void dppc_interpreter::ppc_fctiwz() {
|
||||||
double val_reg_b = GET_FPR(reg_b);
|
double val_reg_b = GET_FPR(reg_b);
|
||||||
|
|
||||||
if (std::isnan(val_reg_b)) {
|
if (std::isnan(val_reg_b)) {
|
||||||
ppc_state.fpr[reg_d].int64_r = 0x80000000;
|
if (ppc_state.fpr[reg_b].int64_r & 0x0008000000000000) {
|
||||||
ppc_state.fpscr |= FPSCR::VXSNAN | FPSCR::VXCVI;
|
// isqnan
|
||||||
|
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FR | FPSCR::FI)) | FPSCR::VXCVI;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// issnan
|
||||||
|
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FR | FPSCR::FI)) | FPSCR::VXCVI | FPSCR::VXSNAN;
|
||||||
|
}
|
||||||
|
if (ppc_state.fpscr & FPSCR::VE) {
|
||||||
|
ppc_floating_point_exception();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ppc_state.fpr[reg_d].int64_r = 0xfff8000080000000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (val_reg_b > static_cast<double>(0x7fffffff)) {
|
else if (val_reg_b > static_cast<double>(0x7fffffff)) {
|
||||||
ppc_state.fpr[reg_d].int64_r = 0x7fffffff;
|
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FR | FPSCR::FI)) | FPSCR::VXCVI;
|
||||||
ppc_state.fpscr |= FPSCR::VXCVI;
|
if (ppc_state.fpscr & FPSCR::VE) {
|
||||||
|
ppc_floating_point_exception();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ppc_state.fpr[reg_d].int64_r = 0xfff800007fffffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (val_reg_b < -static_cast<double>(0x80000000)) {
|
else if (val_reg_b < -static_cast<double>(0x80000000)) {
|
||||||
ppc_state.fpr[reg_d].int64_r = 0x80000000;
|
ppc_state.fpscr = (ppc_state.fpscr & ~(FPSCR::FR | FPSCR::FI)) | FPSCR::VXCVI;
|
||||||
ppc_state.fpscr |= FPSCR::VXCVI;
|
if (ppc_state.fpscr & FPSCR::VE) {
|
||||||
|
ppc_floating_point_exception();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ppc_state.fpr[reg_d].int64_r = 0xfff8000080000000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ppc_result64_d = round_to_zero(val_reg_b);
|
uint64_t ppc_result64_d = round_to_zero(val_reg_b);
|
||||||
|
|
||||||
ppc_store_dfpresult_int(reg_d);
|
ppc_store_dfpresult_int(reg_d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user