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 "hw/sh4/sh4_if.h"
#include "hw/sh4/sh4_mem.h"
#include "hw/sh4/sh4_interpreter.h"
#include "hw/sh4/dyna/shil.h"
#include "cfg/option.h"
#include <array>
#include <signal.h>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,21 +46,21 @@ bool UpdateSR()
static u32 old_rm = 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_dn = Sh4cntx.fpscr.DN;
old_rm = roundingMode;
old_dn = denorm2zero;
//Correct rounding is required by some games (SOTB, etc)
#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);
else
_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);
else
_controlfp(_DN_SAVE, _MCW_DN);
@ -70,20 +70,20 @@ static void setHostRoundingMode()
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);
if (Sh4cntx.fpscr.DN) //denormals are considered 0
if (denorm2zero == 1) // denormals are considered 0
temp|=(1<<15);
asm("ldmxcsr %0" : : "m"(temp));
#elif HOST_CPU==CPU_ARM
static const unsigned int offMask = 0x04086060;
unsigned int onMask = 0x02000000;
if (Sh4cntx.fpscr.RM == 1) //if round to 0 , set the flag
if (roundingMode == 1)
onMask |= 3 << 22;
if (Sh4cntx.fpscr.DN)
if (denorm2zero == 1)
onMask |= 1 << 24;
#ifdef __ANDROID__
@ -109,10 +109,10 @@ static void setHostRoundingMode()
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
if (Sh4cntx.fpscr.RM == 1) // if round to 0, set the flag
if (roundingMode == 1)
on_mask |= 3 << 22;
if (Sh4cntx.fpscr.DN)
if (denorm2zero == 1)
on_mask |= 1 << 24; // flush denormalized numbers to zero
asm volatile
@ -140,23 +140,17 @@ void UpdateFPSCR()
ChangeFP(); // FPU bank change
Sh4cntx.old_fpscr = Sh4cntx.fpscr;
setHostRoundingMode();
setHostRoundingMode(p_sh4rcb->cntx.fpscr.RM, p_sh4rcb->cntx.fpscr.DN);
}
void RestoreHostRoundingMode()
{
old_rm = 0xFF;
old_dn = 0xFF;
setHostRoundingMode();
setHostRoundingMode(p_sh4rcb->cntx.fpscr.RM, p_sh4rcb->cntx.fpscr.DN);
}
void setDefaultRoundingMode()
{
u32 savedRM = Sh4cntx.fpscr.RM;
u32 savedDN = Sh4cntx.fpscr.DN;
Sh4cntx.fpscr.RM = 0;
Sh4cntx.fpscr.DN = 0;
setHostRoundingMode();
Sh4cntx.fpscr.RM = savedRM;
Sh4cntx.fpscr.DN = savedDN;
setHostRoundingMode(0, 0);
}

View File

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

View File

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

View File

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

View File

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