sh4: build fix. rounding mode refactoring

This commit is contained in:
Flyinghead 2024-11-08 21:34:24 +01:00
parent db846ca933
commit 2b28e819e5
11 changed files with 39 additions and 40 deletions

View File

@ -21,7 +21,7 @@
#include "emulator.h" #include "emulator.h"
#include "hw/sh4/sh4_if.h" #include "hw/sh4/sh4_if.h"
#include "hw/sh4/sh4_mem.h" #include "hw/sh4/sh4_mem.h"
#include "hw/sh4/sh4_interpreter.h" #include "hw/sh4/dyna/shil.h"
#include "cfg/option.h" #include "cfg/option.h"
#include <array> #include <array>
#include <signal.h> #include <signal.h>

View File

@ -9,7 +9,6 @@
#include "hw/holly/holly_intc.h" #include "hw/holly/holly_intc.h"
#include "hw/holly/sb.h" #include "hw/holly/sb.h"
#include "hw/sh4/modules/dmac.h" #include "hw/sh4/modules/dmac.h"
#include "hw/sh4/sh4_interpreter.h"
#include "hw/sh4/sh4_mem.h" #include "hw/sh4/sh4_mem.h"
#include "hw/sh4/sh4_mmr.h" #include "hw/sh4/sh4_mmr.h"
#include "hw/sh4/sh4_sched.h" #include "hw/sh4/sh4_sched.h"

View File

@ -15,14 +15,22 @@ void AnalyseBlock(RuntimeBlockInfo* blk)
u32 getRegOffset(Sh4RegType reg) u32 getRegOffset(Sh4RegType reg)
{ {
if (reg >= reg_r0 && reg <= reg_r15) if (reg >= reg_r0 && reg <= reg_r15) {
return offsetof(Sh4Context, r[reg - reg_r0]); const size_t regofs = (reg - reg_r0) * sizeof(u32);
if (reg >= reg_r0_Bank && reg <= reg_r7_Bank) return offsetof(Sh4Context, r[0]) + regofs;
return offsetof(Sh4Context, r_bank[reg - reg_r0_Bank]); }
if (reg >= reg_fr_0 && reg <= reg_fr_15) if (reg >= reg_r0_Bank && reg <= reg_r7_Bank) {
return offsetof(Sh4Context, xffr[reg - reg_fr_0 + 16]); const size_t regofs = (reg - reg_r0_Bank) * sizeof(u32);
if (reg >= reg_xf_0 && reg <= reg_xf_15) return offsetof(Sh4Context, r_bank[0]) + regofs;
return offsetof(Sh4Context, xffr[reg - reg_xf_0]); }
if (reg >= reg_fr_0 && reg <= reg_fr_15) {
const size_t regofs = (reg - reg_fr_0) * sizeof(float);
return offsetof(Sh4Context, xffr[16]) + regofs;
}
if (reg >= reg_xf_0 && reg <= reg_xf_15) {
const size_t regofs = (reg - reg_xf_0) * sizeof(float);
return offsetof(Sh4Context, xffr[0]) + regofs;
}
switch (reg) switch (reg)
{ {
case reg_gbr: return offsetof(Sh4Context, gbr); case reg_gbr: return offsetof(Sh4Context, gbr);

View File

@ -3,7 +3,6 @@
*/ */
#include "types.h" #include "types.h"
#include "hw/sh4/sh4_interpreter.h"
#include "hw/sh4/sh4_mem.h" #include "hw/sh4/sh4_mem.h"
#include "hw/sh4/sh4_mmr.h" #include "hw/sh4/sh4_mmr.h"
#include "hw/sh4/sh4_core.h" #include "hw/sh4/sh4_core.h"
@ -1123,7 +1122,7 @@ sh4op(i0000_0000_0011_1000)
sh4op(i0000_nnnn_1001_0011) sh4op(i0000_nnnn_1001_0011)
{ {
#ifdef STRICT_MODE #ifdef STRICT_MODE
ocache.WriteBack(r[GetN(op)], false, true); ocache.WriteBack(ctx->r[GetN(op)], false, true);
#endif #endif
} }
@ -1131,7 +1130,7 @@ sh4op(i0000_nnnn_1001_0011)
sh4op(i0000_nnnn_1010_0011) sh4op(i0000_nnnn_1010_0011)
{ {
#ifdef STRICT_MODE #ifdef STRICT_MODE
ocache.WriteBack(r[GetN(op)], true, true); ocache.WriteBack(ctx->r[GetN(op)], true, true);
#endif #endif
} }
@ -1139,7 +1138,7 @@ sh4op(i0000_nnnn_1010_0011)
sh4op(i0000_nnnn_1011_0011) sh4op(i0000_nnnn_1011_0011)
{ {
#ifdef STRICT_MODE #ifdef STRICT_MODE
ocache.WriteBack(r[GetN(op)], true, false); ocache.WriteBack(ctx->r[GetN(op)], true, false);
#endif #endif
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "types.h" #include "types.h"
#include "../sh4_interpreter.h" #include "hw/sh4/sh4_opcode_list.h"
/* Opcodes :) */ /* Opcodes :) */

View File

@ -1,7 +1,9 @@
#pragma once #pragma once
#include "types.h" #include "types.h"
#include "sh4_if.h" #include "sh4_if.h"
#include <cmath>
int UpdateSystem_INTC();
void UpdateFPSCR(); void UpdateFPSCR();
bool UpdateSR(); bool UpdateSR();
void RestoreHostRoundingMode(); void RestoreHostRoundingMode();

View File

@ -46,21 +46,21 @@ bool UpdateSR()
static u32 old_rm = 0xFF; static u32 old_rm = 0xFF;
static u32 old_dn = 0xFF; static u32 old_dn = 0xFF;
static void setHostRoundingMode() static void setHostRoundingMode(u32 roundingMode, u32 denorm2zero)
{ {
if (old_rm != Sh4cntx.fpscr.RM || old_dn != Sh4cntx.fpscr.DN) if (old_rm != roundingMode || old_dn != denorm2zero)
{ {
old_rm = Sh4cntx.fpscr.RM; old_rm = roundingMode;
old_dn = Sh4cntx.fpscr.DN; old_dn = denorm2zero;
//Correct rounding is required by some games (SOTB, etc) //Correct rounding is required by some games (SOTB, etc)
#ifdef _MSC_VER #ifdef _MSC_VER
if (Sh4cntx.fpscr.RM == 1) //if round to 0 , set the flag if (roundingMode == 1) // if round to 0 , set the flag
_controlfp(_RC_CHOP, _MCW_RC); _controlfp(_RC_CHOP, _MCW_RC);
else else
_controlfp(_RC_NEAR, _MCW_RC); _controlfp(_RC_NEAR, _MCW_RC);
if (Sh4cntx.fpscr.DN) //denormals are considered 0 if (denorm2zero == 1) // denormals are considered 0
_controlfp(_DN_FLUSH, _MCW_DN); _controlfp(_DN_FLUSH, _MCW_DN);
else else
_controlfp(_DN_SAVE, _MCW_DN); _controlfp(_DN_SAVE, _MCW_DN);
@ -70,20 +70,20 @@ static void setHostRoundingMode()
u32 temp=0x1f80; //no flush to zero && round to nearest u32 temp=0x1f80; //no flush to zero && round to nearest
if (Sh4cntx.fpscr.RM==1) //if round to 0 , set the flag if (roundingMode==1) // if round to 0 , set the flag
temp|=(3<<13); temp|=(3<<13);
if (Sh4cntx.fpscr.DN) //denormals are considered 0 if (denorm2zero == 1) // denormals are considered 0
temp|=(1<<15); temp|=(1<<15);
asm("ldmxcsr %0" : : "m"(temp)); asm("ldmxcsr %0" : : "m"(temp));
#elif HOST_CPU==CPU_ARM #elif HOST_CPU==CPU_ARM
static const unsigned int offMask = 0x04086060; static const unsigned int offMask = 0x04086060;
unsigned int onMask = 0x02000000; unsigned int onMask = 0x02000000;
if (Sh4cntx.fpscr.RM == 1) //if round to 0 , set the flag if (roundingMode == 1)
onMask |= 3 << 22; onMask |= 3 << 22;
if (Sh4cntx.fpscr.DN) if (denorm2zero == 1)
onMask |= 1 << 24; onMask |= 1 << 24;
#ifdef __ANDROID__ #ifdef __ANDROID__
@ -109,10 +109,10 @@ static void setHostRoundingMode()
static const unsigned long off_mask = 0x04080000; static const unsigned long off_mask = 0x04080000;
unsigned long on_mask = 0x02000000; // DN=1 Any operation involving one or more NaNs returns the Default NaN unsigned long on_mask = 0x02000000; // DN=1 Any operation involving one or more NaNs returns the Default NaN
if (Sh4cntx.fpscr.RM == 1) // if round to 0, set the flag if (roundingMode == 1)
on_mask |= 3 << 22; on_mask |= 3 << 22;
if (Sh4cntx.fpscr.DN) if (denorm2zero == 1)
on_mask |= 1 << 24; // flush denormalized numbers to zero on_mask |= 1 << 24; // flush denormalized numbers to zero
asm volatile asm volatile
@ -140,23 +140,17 @@ void UpdateFPSCR()
ChangeFP(); // FPU bank change ChangeFP(); // FPU bank change
Sh4cntx.old_fpscr = Sh4cntx.fpscr; Sh4cntx.old_fpscr = Sh4cntx.fpscr;
setHostRoundingMode(); setHostRoundingMode(p_sh4rcb->cntx.fpscr.RM, p_sh4rcb->cntx.fpscr.DN);
} }
void RestoreHostRoundingMode() void RestoreHostRoundingMode()
{ {
old_rm = 0xFF; old_rm = 0xFF;
old_dn = 0xFF; old_dn = 0xFF;
setHostRoundingMode(); setHostRoundingMode(p_sh4rcb->cntx.fpscr.RM, p_sh4rcb->cntx.fpscr.DN);
} }
void setDefaultRoundingMode() void setDefaultRoundingMode()
{ {
u32 savedRM = Sh4cntx.fpscr.RM; setHostRoundingMode(0, 0);
u32 savedDN = Sh4cntx.fpscr.DN;
Sh4cntx.fpscr.RM = 0;
Sh4cntx.fpscr.DN = 0;
setHostRoundingMode();
Sh4cntx.fpscr.RM = savedRM;
Sh4cntx.fpscr.DN = savedDN;
} }

View File

@ -35,5 +35,3 @@ private:
static constexpr int CPU_RATIO = 8; static constexpr int CPU_RATIO = 8;
#endif #endif
}; };
int UpdateSystem_INTC();

View File

@ -11,6 +11,7 @@
#include "hw/pvr/pvr_mem.h" #include "hw/pvr/pvr_mem.h"
#include "hw/mem/addrspace.h" #include "hw/mem/addrspace.h"
#include "hw/sh4/modules/mmu.h" #include "hw/sh4/modules/mmu.h"
#include "cfg/option.h"
#ifdef STRICT_MODE #ifdef STRICT_MODE
#include "sh4_cache.h" #include "sh4_cache.h"

View File

@ -12,7 +12,6 @@
#include "serialize.h" #include "serialize.h"
#include "sh4_interrupts.h" #include "sh4_interrupts.h"
#include "sh4_sched.h" #include "sh4_sched.h"
#include "sh4_interpreter.h"
#include <array> #include <array>
#include <map> #include <map>

View File

@ -22,7 +22,6 @@
#include "rec_x86.h" #include "rec_x86.h"
#include "hw/sh4/sh4_core.h" #include "hw/sh4/sh4_core.h"
#include "hw/sh4/sh4_interpreter.h"
#include "hw/sh4/sh4_interrupts.h" #include "hw/sh4/sh4_interrupts.h"
#include "hw/sh4/sh4_mem.h" #include "hw/sh4/sh4_mem.h"
#include "hw/mem/addrspace.h" #include "hw/mem/addrspace.h"