More Read_U32 cleanup

This commit is contained in:
Henrik Rydgård committed 2026-08-11 09:08:52 +02:00
1 parent 3c7a323e99
commit 9396030f02
9 files changed
+57 -39

No files matched your search

+10 -7
View File
@@ -746,6 +746,9 @@ void PGF::SetFontPixel(u32 base, int bpl, int bufWidth, int bufHeight, int x, in
}
int framebufferAddr = base + (y * bpl) + (pixelBytes == 0 ? x / 2 : x * pixelBytes);
if (!Memory::IsValidAddress(framebufferAddr)) {
return;
}
switch (pixelformat) {
case PSP_FONT_PIXELFORMAT_4:
@@ -753,29 +756,29 @@ void PGF::SetFontPixel(u32 base, int bpl, int bufWidth, int bufHeight, int x, in
{
// The two pixels share a byte, so the neighbour's nibble is left alone.
const int shift = ((x & 1) != pixelformat) ? 4 : 0;
const int oldColor = Memory::Read_U8(framebufferAddr);
const int oldColor = Memory::ReadUnchecked_U8(framebufferAddr);
const int newPix = std::min(((oldColor >> shift) & 0xF) + pixelColor, 15);
Memory::Write_U8((u8)((oldColor & ~(0xF << shift)) | (newPix << shift)), framebufferAddr);
Memory::WriteUnchecked_U8((u8)((oldColor & ~(0xF << shift)) | (newPix << shift)), framebufferAddr);
break;
}
case PSP_FONT_PIXELFORMAT_8:
{
const int newPix = std::min((int)Memory::Read_U8(framebufferAddr) + pixelColor, 255);
Memory::Write_U8((u8)newPix, framebufferAddr);
const int newPix = std::min((int)Memory::ReadUnchecked_U8(framebufferAddr) + pixelColor, 255);
Memory::WriteUnchecked_U8((u8)newPix, framebufferAddr);
break;
}
case PSP_FONT_PIXELFORMAT_24:
{
// Each channel gets the same value.
for (int i = 0; i < 3; ++i) {
const int newPix = std::min((int)Memory::Read_U8(framebufferAddr + i) + pixelColor, 255);
Memory::Write_U8((u8)newPix, framebufferAddr + i);
const int newPix = std::min((int)Memory::ReadUnchecked_U8(framebufferAddr + i) + pixelColor, 255);
Memory::WriteUnchecked_U8((u8)newPix, framebufferAddr + i);
}
break;
}
case PSP_FONT_PIXELFORMAT_32:
{
const u32 oldColor = Memory::Read_U32(framebufferAddr);
const u32 oldColor = Memory::ReadUnchecked_U32(framebufferAddr);
u32 pix32 = 0;
for (int i = 0; i < 4; ++i) {
const int newPix = std::min((int)((oldColor >> (i * 8)) & 0xFF) + pixelColor, 255);
+2 -1
View File
@@ -721,7 +721,8 @@ void HLEReturnFromMipsCall() {
currentMIPS->pc = stackData->func;
currentMIPS->r[MIPS_REG_RA] = HLEMipsCallReturnAddress();
for (int i = 0; i < (int)stackData->argc; i++) {
currentMIPS->r[MIPS_REG_A0 + i] = Memory::Read_U32(sp + sizeof(HLEMipsCallStack) + i * sizeof(u32));
// The check at the start of the function should be enough to use an unchecked read (well, kinda..)
currentMIPS->r[MIPS_REG_A0 + i] = Memory::ReadUnchecked_U32(sp + sizeof(HLEMipsCallStack) + i * sizeof(u32));
}
DEBUG_LOG(Log::HLE, "Executing next HLE mips call at %08x, sp=%08x", currentMIPS->pc, sp);
hleNoLogVoid();
+3
View File
@@ -1846,6 +1846,9 @@ void RestoreReplacedInstructions(u32 startAddr, u32 endAddr) {
std::map<u32, u32> SaveAndClearReplacements() {
std::map<u32, u32> saved;
for (const auto &[addr, instr] : replacedInstructions) {
if (!Memory::IsValid4AlignedAddress(addr)) {
continue;
}
// This will not retain jit blocks.
const u32 curInstr = Memory::Read_Opcode_JIT(addr).encoding;
if (MIPS_IS_REPLACEMENT(curInstr)) {
+27 -20
View File
@@ -238,7 +238,7 @@ static MpegContext *getMpegCtx(u32 mpegAddr) {
if (!Memory::IsValidAddress(mpegAddr))
return nullptr;
u32 mpeg = Memory::Read_U32(mpegAddr);
u32 mpeg = Memory::ReadUnchecked_U32(mpegAddr);
auto found = g_mpegCtxs.find(mpeg);
if (found == g_mpegCtxs.end())
return nullptr;
@@ -560,7 +560,7 @@ static int sceMpegDelete(u32 mpeg) {
}
delete ctx;
g_mpegCtxs.erase(Memory::Read_U32(mpeg));
g_mpegCtxs.erase(Memory::ReadUnchecked_U32(mpeg));
return hleDelayResult(hleLogDebug(Log::Mpeg, 0), "mpeg delete", 40000);
}
@@ -568,7 +568,7 @@ static int sceMpegDelete(u32 mpeg) {
static int sceMpegAvcDecodeMode(u32 mpeg, u32 modeAddr)
{
if (!Memory::IsValidAddress(modeAddr)) {
if (!Memory::IsValidRange(modeAddr, 8)) {
return hleLogWarning(Log::Mpeg, -1, "invalid addresses");
}
@@ -579,8 +579,8 @@ static int sceMpegAvcDecodeMode(u32 mpeg, u32 modeAddr)
DEBUG_LOG(Log::Mpeg, "sceMpegAvcDecodeMode(%08x, %08x)", mpeg, modeAddr);
int mode = Memory::Read_U32(modeAddr);
int pixelMode = Memory::Read_U32(modeAddr + 4);
int mode = Memory::ReadUnchecked_U32(modeAddr);
int pixelMode = Memory::ReadUnchecked_U32(modeAddr + 4);
if (pixelMode >= GE_CMODE_16BIT_BGR5650 && pixelMode <= GE_CMODE_32BIT_ABGR8888) {
ctx->videoPixelMode = pixelMode;
} else {
@@ -1071,8 +1071,7 @@ void __VideoPmpDoState(PointerWrap &p){
}
}
static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr, u32 initAddr)
{
static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr, u32 initAddr) {
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
return hleLogWarning(Log::Mpeg, -1, "bad mpeg handle");
@@ -1094,8 +1093,12 @@ static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr
return hleLogError(Log::Mpeg, -1, "Bogus mpegringbufferaddr");
}
u32 buffer = Memory::Read_U32(bufferAddr);
u32 init = Memory::Read_U32(initAddr);
if (!Memory::IsValidRange(bufferAddr, 4) || !Memory::IsValidRange(initAddr, 4)) {
return hleLogError(Log::Mpeg, -1, "invalid addresses");
}
u32 buffer = Memory::ReadUnchecked_U32(bufferAddr);
u32 init = Memory::ReadUnchecked_U32(initAddr);
DEBUG_LOG(Log::Mpeg, "video: bufferAddr = %08x, *buffer = %08x, *init = %08x", bufferAddr, buffer, init);
// check and decode pmp video
@@ -1244,7 +1247,7 @@ static int sceMpegAvcDecodeDetail(u32 mpeg, u32 detailAddr) {
}
static u32 sceMpegAvcDecodeStopYCbCr(u32 mpeg, u32 bufferAddr, u32 statusAddr) {
if (!Memory::IsValidAddress(bufferAddr) || !Memory::IsValidAddress(statusAddr)) {
if (!Memory::IsValidAddress(bufferAddr) || !Memory::IsValid4AlignedAddress(statusAddr)) {
return hleLogError(Log::Mpeg, -1, "UNIMPL + invalid addresses");
}
@@ -1254,7 +1257,7 @@ static u32 sceMpegAvcDecodeStopYCbCr(u32 mpeg, u32 bufferAddr, u32 statusAddr) {
}
ERROR_LOG(Log::Mpeg, "UNIMPL sceMpegAvcDecodeStopYCbCr(%08x, %08x, %08x)", mpeg, bufferAddr, statusAddr);
Memory::Write_U32(0, statusAddr);
Memory::WriteUnchecked_U32(0, statusAddr);
return hleNoLog(0);
}
@@ -1282,8 +1285,12 @@ static int sceMpegAvcDecodeYCbCr(u32 mpeg, u32 auAddr, u32 bufferAddr, u32 initA
// We stored the video stream id here in sceMpegGetAvcAu().
ctx->mediaengine->setVideoStream(avcAu.esBuffer);
u32 buffer = Memory::Read_U32(bufferAddr);
u32 init = Memory::Read_U32(initAddr);
if (!Memory::IsValidRange(bufferAddr, 4) || !Memory::IsValidRange(initAddr, 4)) {
return hleLogError(Log::Mpeg, -1, "invalid addresses");
}
u32 buffer = Memory::ReadUnchecked_U32(bufferAddr);
u32 init = Memory::ReadUnchecked_U32(initAddr);
DEBUG_LOG(Log::Mpeg, "*buffer = %08x, *init = %08x", buffer, init);
if (ctx->mediaengine->stepVideo(ctx->videoPixelMode)) {
@@ -1309,10 +1316,10 @@ static int sceMpegAvcDecodeYCbCr(u32 mpeg, u32 auAddr, u32 bufferAddr, u32 initA
if (mpegLibVersion >= 0x010A) {
// Sunday Vs Magazine Shuuketsu! Choujou Daikessen expect, issue #11060
Memory::Write_U32(1, initAddr);
Memory::WriteUnchecked_U32(1, initAddr);
} else {
// Save the current frame's status to initAddr
Memory::Write_U32(ctx->avc.avcFrameStatus, initAddr);
Memory::WriteUnchecked_U32(ctx->avc.avcFrameStatus, initAddr);
}
ctx->avc.avcDecodeResult = MPEG_AVC_DECODE_SUCCESS;
@@ -1928,7 +1935,7 @@ static u32 sceMpegAtracDecode(u32 mpeg, u32 auAddr, u32 bufferAddr, int init)
// YCbCr -> RGB color space conversion
static u32 sceMpegAvcCsc(u32 mpeg, u32 sourceAddr, u32 rangeAddr, int frameWidth, u32 destAddr)
{
if (!Memory::IsValidAddress(sourceAddr) || !Memory::IsValidAddress(rangeAddr) || !Memory::IsValidAddress(destAddr)) {
if (!Memory::IsValidAddress(sourceAddr) || !Memory::IsValidRange(rangeAddr, 16) || !Memory::IsValidAddress(destAddr)) {
return hleLogError(Log::Mpeg, -1, "invalid addresses");
}
@@ -1945,10 +1952,10 @@ static u32 sceMpegAvcCsc(u32 mpeg, u32 sourceAddr, u32 rangeAddr, int frameWidth
}
}
int x = Memory::Read_U32(rangeAddr);
int y = Memory::Read_U32(rangeAddr + 4);
int width = Memory::Read_U32(rangeAddr + 8);
int height = Memory::Read_U32(rangeAddr + 12);
int x = Memory::ReadUnchecked_U32(rangeAddr);
int y = Memory::ReadUnchecked_U32(rangeAddr + 4);
int width = Memory::ReadUnchecked_U32(rangeAddr + 8);
int height = Memory::ReadUnchecked_U32(rangeAddr + 12);
if (x < 0 || y < 0 || width < 0 || height < 0) {
WARN_LOG(Log::Mpeg, "sceMpegAvcCsc(%08x, %08x, %08x, %i, %08x) returning ERROR_INVALID_VALUE", mpeg, sourceAddr, rangeAddr, frameWidth, destAddr);
+2 -2
View File
@@ -1552,10 +1552,10 @@ int NetApctl_GetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) {
const int userInfoSize = 8; // 8 bytes per entry (next address + entry id)
// Faking 4 entries, games like MGS:PW Recruit will need to have a different AP for each entry
int entries = 4;
if (!Memory::IsValidAddress(sizeAddr) || !Memory::IsValidAddress(bufAddr))
if (!Memory::IsValid4AlignedAddress(sizeAddr) || !Memory::IsValidAddress(bufAddr))
return hleLogError(Log::sceNet, -1, "apctl invalid arg"); // 0x8002013A or ERROR_NET_WLAN_INVALID_ARG ?
int size = Memory::Read_U32(sizeAddr);
int size = Memory::ReadUnchecked_U32(sizeAddr);
// Return size required
Memory::Write_U32(entries * userInfoSize, sizeAddr);
+2 -2
View File
@@ -547,7 +547,7 @@ bool IRBlock::RestoreOriginalFirstOp(int cookie) {
void IRBlock::Finalize(int cookie) {
// Check it wasn't invalidated, in case this is after preload.
// TODO: Allow reusing blocks when the code matches hash_ again, instead.
if (origAddr_) {
if (origAddr_ && Memory::IsValid4AlignedAddress(origAddr_)) {
origFirstOpcode_ = Memory::Read_Opcode_JIT(origAddr_);
MIPSOpcode opcode = MIPSOpcode(MIPS_EMUHACK_OPCODE | cookie);
Memory::Write_Opcode_JIT(origAddr_, opcode);
@@ -557,7 +557,7 @@ void IRBlock::Finalize(int cookie) {
}
void IRBlock::Destroy(int cookie) {
if (origAddr_) {
if (origAddr_ && Memory::IsValid4AlignedAddress(origAddr_)) {
MIPSOpcode opcode = MIPSOpcode(MIPS_EMUHACK_OPCODE | cookie);
u32 memOp = Memory::ReadUnchecked_U32(origAddr_);
if (memOp == opcode.encoding) {
+1 -1
View File
@@ -293,7 +293,7 @@ bool parseExpression(const DebugInterface *debug, PostfixExpression& exp, u32& d
}
void DisAsm(u32 pc, char *out, size_t outSize) {
if (Memory::IsValidAddress(pc))
if (Memory::IsValid4AlignedAddress(pc))
MIPSDisAsm(Memory::Read_Opcode_JIT(pc), pc, out, outSize);
else
truncate_cpy(out, outSize, "-");
+6 -3
View File
@@ -75,9 +75,12 @@ static inline void SkipLikely() {
}
}
int MIPS_SingleStep()
{
MIPSOpcode op = Memory::Read_Opcode_JIT(mipsr4k.pc);
int MIPS_SingleStep() {
if (!Memory::IsValid4AlignedAddress(mipsr4k.pc)) {
Core_ExecException(mipsr4k.pc, mipsr4k.pc, ExecExceptionType::JUMP);
return 0;
}
MIPSOpcode op = Memory::Read_Opcode_JIT(mipsr4k.pc); // now unchecked
if (mipsr4k.inDelaySlot) {
MIPSInterpret(op);
if (mipsr4k.inDelaySlot) {
+4 -3
View File
@@ -490,9 +490,10 @@ Opcode ReadUnchecked_Instruction(u32 address, bool resolveReplacements) {
return Read_Instruction(address, resolveReplacements, inst);
}
Opcode Read_Opcode_JIT(u32 address)
{
Opcode inst = Opcode(Read_U32(address));
// WARNING! Caller checks that address is valid!
Opcode Read_Opcode_JIT(u32 address) {
_dbg_assert_(Memory::IsValid4AlignedAddress(address));
Opcode inst = Opcode(ReadUnchecked_U32(address));
// No mutex around jit access here, but we assume caller has if necessary.
if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) {
return MIPSComp::jit->GetOriginalOp(inst);