From 1b00da2f3a167b320e9fbf4ccd78e9b60969b5c0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 31 Jan 2021 01:25:52 -0800 Subject: [PATCH] Common: Sign extend w/func not chained casts. Should be clearer to read and easier to get right. --- Common/ColorConv.cpp | 5 +++-- Common/Data/Convert/SmallDataConvert.h | 13 +++++++++++++ Core/ELF/ElfReader.cpp | 2 +- Core/HLE/sceKernelModule.cpp | 3 ++- Core/MIPS/ARM/ArmCompALU.cpp | 15 ++++++++------- Core/MIPS/ARM/ArmCompBranch.cpp | 4 ++-- Core/MIPS/ARM/ArmCompVFPU.cpp | 5 +++-- Core/MIPS/ARM/ArmCompVFPUNEON.cpp | 3 ++- Core/MIPS/ARM64/Arm64CompALU.cpp | 11 ++++++----- Core/MIPS/ARM64/Arm64CompBranch.cpp | 4 ++-- Core/MIPS/ARM64/Arm64CompVFPU.cpp | 7 ++++--- Core/MIPS/IR/IRCompALU.cpp | 2 +- Core/MIPS/IR/IRCompBranch.cpp | 4 ++-- Core/MIPS/IR/IRCompVFPU.cpp | 6 +++--- Core/MIPS/IR/IRInterpreter.cpp | 13 +++++++------ Core/MIPS/IR/IRPassSimplify.cpp | 5 +++-- Core/MIPS/MIPSCodeUtils.h | 8 ++++++++ Core/MIPS/MIPSDis.cpp | 7 ++++--- Core/MIPS/MIPSInt.cpp | 17 +++++++++-------- Core/MIPS/x86/CompALU.cpp | 8 ++++---- Core/MIPS/x86/CompBranch.cpp | 4 ++-- Core/MIPS/x86/CompLoadStore.cpp | 4 ++-- Core/MIPS/x86/CompVFPU.cpp | 2 +- 23 files changed, 92 insertions(+), 60 deletions(-) diff --git a/Common/ColorConv.cpp b/Common/ColorConv.cpp index 0146967e99..a9628207e4 100644 --- a/Common/ColorConv.cpp +++ b/Common/ColorConv.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/Data/Convert/SmallDataConvert.h" #include "ColorConv.h" // NEON is in a separate file so that it can be compiled with a runtime check. #include "ColorConvNEON.h" @@ -487,8 +488,8 @@ void ConvertRGBA5551ToBGRA8888(u32 *dst, const u16 *src, u32 numPixels) { u32 r = Convert5To8(c & 0x001f); u32 g = Convert5To8((c >> 5) & 0x001f); u32 b = Convert5To8((c >> 10) & 0x001f); - // We force an arithmetic shift to get the sign bits/ - u32 a = ((s32)(s16)c) & 0xff000000; + // We force an arithmetic shift to get the sign bits. + u32 a = SignExtend16To32(c) & 0xff000000; dst[x] = a | (r << 16) | (g << 8) | b; } diff --git a/Common/Data/Convert/SmallDataConvert.h b/Common/Data/Convert/SmallDataConvert.h index 502cb9a0a6..953f596f53 100644 --- a/Common/Data/Convert/SmallDataConvert.h +++ b/Common/Data/Convert/SmallDataConvert.h @@ -180,3 +180,16 @@ inline void ExpandFloat24x3ToFloat4(float dest[4], const uint32_t src[3]) { inline uint32_t BytesToUint32(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { return (a) | (b << 8) | (c << 16) | (d << 24); } + +constexpr uint32_t SignExtend8To32(uint32_t value) { + // This extends this sign at the 8th bit to the other 24 bits. + int32_t signedValue = (int8_t)(value & 0xFF); + // We return as unsigned because we're likely just interested in the bits. + return (uint32_t)signedValue; +} + +constexpr uint32_t SignExtend16To32(uint32_t value) { + // Same as SignExtend8to32, but from the 16th bit. + int32_t signedValue = (int16_t)(value & 0xFFFF); + return (uint32_t)signedValue; +} diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index 93863d7c6d..eec53a3c2f 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -136,7 +136,7 @@ bool ElfReader::LoadRelocations(const Elf32_Rel *rels, int numRelocs) DEBUG_LOG(LOADER,"Corresponding lo found at %08x", corrLoAddr); } if (Memory::IsValidAddress(corrLoAddr)) { - s16 lo = (s32)(s16)(u16)(Memory::ReadUnchecked_U32(corrLoAddr) & 0xFFFF); //signed?? + s16 lo = (s16)Memory::ReadUnchecked_U16(corrLoAddr); cur += lo; cur += relocateTo; addrToHiLo(cur, hi, lo); diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index a60b07e71f..46f64d23ce 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -21,6 +21,7 @@ #include "zlib.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeSet.h" @@ -625,7 +626,7 @@ static void WriteVarSymbol(WriteVarSymbolState &state, u32 exportAddress, u32 re case R_MIPS_LO16: { // Sign extend the existing low value (e.g. from addiu.) - const u32 offsetLo = (s32)(s16)(u16)(relocData & 0xFFFF); + const u32 offsetLo = SignExtend16To32(relocData); u32 full = exportAddress; // This is only used in the error case (no hi/wrong hi.) if (!reverse) { diff --git a/Core/MIPS/ARM/ArmCompALU.cpp b/Core/MIPS/ARM/ArmCompALU.cpp index 6088454fad..18ea66a6d6 100644 --- a/Core/MIPS/ARM/ArmCompALU.cpp +++ b/Core/MIPS/ARM/ArmCompALU.cpp @@ -20,12 +20,13 @@ #include +#include "Common/BitSet.h" +#include "Common/CPUDetect.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/ARM/ArmJit.h" #include "Core/MIPS/ARM/ArmRegCache.h" -#include "Common/CPUDetect.h" -#include "Common/BitSet.h" using namespace MIPSAnalyst; @@ -75,9 +76,9 @@ namespace MIPSComp void ArmJit::Comp_IType(MIPSOpcode op) { CONDITIONAL_DISABLE(ALU_IMM); - s32 simm = (s32)(s16)(op & 0xFFFF); // sign extension u32 uimm = op & 0xFFFF; - u32 suimm = (u32)(s32)simm; + u32 suimm = SignExtend16To32(op); + s32 simm = (s32)suimm; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; @@ -601,9 +602,9 @@ namespace MIPSComp return; switch ((op >> 6) & 31) { - case 16: // seb // R(rd) = (u32)(s32)(s8)(u8)R(rt); + case 16: // seb // R(rd) = SignExtend8To32(R(rt)); if (gpr.IsImm(rt)) { - gpr.SetImm(rd, (s32)(s8)(u8)gpr.GetImm(rt)); + gpr.SetImm(rd, SignExtend8To32(gpr.GetImm(rt))); return; } gpr.MapDirtyIn(rd, rt); @@ -612,7 +613,7 @@ namespace MIPSComp case 24: // seh if (gpr.IsImm(rt)) { - gpr.SetImm(rd, (s32)(s16)(u16)gpr.GetImm(rt)); + gpr.SetImm(rd, SignExtend16To32(gpr.GetImm(rt))); return; } gpr.MapDirtyIn(rd, rt); diff --git a/Core/MIPS/ARM/ArmCompBranch.cpp b/Core/MIPS/ARM/ArmCompBranch.cpp index 25151c1729..da2300d5f7 100644 --- a/Core/MIPS/ARM/ArmCompBranch.cpp +++ b/Core/MIPS/ARM/ArmCompBranch.cpp @@ -18,6 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM) +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Profiler/Profiler.h" #include "Core/Config.h" @@ -47,9 +48,8 @@ #define _SA MIPS_GET_SA(op) #define _POS ((op>> 6) & 0x1F) #define _SIZE ((op>>11) & 0x1F) -#define _IMM16 (signed short)(op & 0xFFFF) #define _IMM26 (op & 0x03FFFFFF) -#define TARGET16 ((int)((uint32_t)(int)_IMM16 << 2)) +#define TARGET16 ((int)(SignExtend16To32(op) << 2)) #define TARGET26 (_IMM26 << 2) #define LOOPOPTIMIZATION 0 diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index 4291f694f2..46a9e3c075 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -19,6 +19,8 @@ #if PPSSPP_ARCH(ARM) #include +#include "Common/CPUDetect.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Math/math_util.h" #include "Core/Compatibility.h" @@ -30,7 +32,6 @@ #include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/MIPSAnalyst.h" #include "Core/MIPS/MIPSCodeUtils.h" -#include "Common/CPUDetect.h" #include "Core/MIPS/ARM/ArmJit.h" #include "Core/MIPS/ARM/ArmRegCache.h" @@ -2087,7 +2088,7 @@ namespace MIPSComp u8 dreg; GetVectorRegs(&dreg, V_Single, _VT); - s32 imm = (s32)(s16)(u16)(op & 0xFFFF); + s32 imm = (s32)SignExtend16To32(op); fpr.MapRegV(dreg, MAP_DIRTY | MAP_NOINIT); MOVI2F(fpr.V(dreg), (float)imm, SCRATCHREG1); diff --git a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp index 34bd76f055..bd680b0a2a 100644 --- a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp +++ b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp @@ -30,6 +30,7 @@ #include +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Math/math_util.h" #include "Common/CPUDetect.h" @@ -1347,7 +1348,7 @@ void ArmJit::CompNEON_Viim(MIPSOpcode op) { DestARMReg vt = NEONMapPrefixD(_VT, V_Single, MAP_NOINIT | MAP_DIRTY); - s32 imm = (s32)(s16)(u16)(op & 0xFFFF); + s32 imm = (s32)SignExtend16To32(op); // TODO: Optimize for low registers. MOVI2F(S0, (float)imm, R0); VMOV_neon(vt.rd, D0); diff --git a/Core/MIPS/ARM64/Arm64CompALU.cpp b/Core/MIPS/ARM64/Arm64CompALU.cpp index a4e5ea25e9..3ac0e9f6ac 100644 --- a/Core/MIPS/ARM64/Arm64CompALU.cpp +++ b/Core/MIPS/ARM64/Arm64CompALU.cpp @@ -22,6 +22,7 @@ #include "Common/BitSet.h" #include "Common/CPUDetect.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/ARM64/Arm64Jit.h" @@ -72,9 +73,9 @@ void Arm64Jit::CompImmLogic(MIPSGPReg rs, MIPSGPReg rt, u32 uimm, void (ARM64XEm void Arm64Jit::Comp_IType(MIPSOpcode op) { CONDITIONAL_DISABLE(ALU_IMM); - s32 simm = (s32)(s16)(op & 0xFFFF); // sign extension u32 uimm = op & 0xFFFF; - u32 suimm = (u32)(s32)simm; + u32 suimm = SignExtend16To32(op); + s32 simm = (s32)suimm; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; @@ -488,9 +489,9 @@ void Arm64Jit::Comp_Allegrex(MIPSOpcode op) { return; switch ((op >> 6) & 31) { - case 16: // seb // R(rd) = (u32)(s32)(s8)(u8)R(rt); + case 16: // seb // R(rd) = SignExtend8To32(R(rt)); if (gpr.IsImm(rt)) { - gpr.SetImm(rd, (s32)(s8)(u8)gpr.GetImm(rt)); + gpr.SetImm(rd, SignExtend8To32(gpr.GetImm(rt))); return; } gpr.MapDirtyIn(rd, rt); @@ -499,7 +500,7 @@ void Arm64Jit::Comp_Allegrex(MIPSOpcode op) { case 24: // seh if (gpr.IsImm(rt)) { - gpr.SetImm(rd, (s32)(s16)(u16)gpr.GetImm(rt)); + gpr.SetImm(rd, SignExtend16To32(gpr.GetImm(rt))); return; } gpr.MapDirtyIn(rd, rt); diff --git a/Core/MIPS/ARM64/Arm64CompBranch.cpp b/Core/MIPS/ARM64/Arm64CompBranch.cpp index e3914ee1a6..42ca60750a 100644 --- a/Core/MIPS/ARM64/Arm64CompBranch.cpp +++ b/Core/MIPS/ARM64/Arm64CompBranch.cpp @@ -18,6 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM64) +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Profiler/Profiler.h" #include "Core/Config.h" @@ -47,9 +48,8 @@ #define _SA MIPS_GET_SA(op) #define _POS ((op>> 6) & 0x1F) #define _SIZE ((op>>11) & 0x1F) -#define _IMM16 (signed short)(op & 0xFFFF) #define _IMM26 (op & 0x03FFFFFF) -#define TARGET16 ((int)((uint32_t)(int)_IMM16 << 2)) +#define TARGET16 ((int)(SignExtend16To32(op) << 2)) #define TARGET26 (_IMM26 << 2) #define LOOPOPTIMIZATION 0 diff --git a/Core/MIPS/ARM64/Arm64CompVFPU.cpp b/Core/MIPS/ARM64/Arm64CompVFPU.cpp index d90ed9bce8..4bc27fce91 100644 --- a/Core/MIPS/ARM64/Arm64CompVFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompVFPU.cpp @@ -19,6 +19,9 @@ #if PPSSPP_ARCH(ARM64) #include +#include "Common/Arm64Emitter.h" +#include "Common/CPUDetect.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Math/math_util.h" #include "Core/Compatibility.h" @@ -30,8 +33,6 @@ #include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/MIPSAnalyst.h" #include "Core/MIPS/MIPSCodeUtils.h" -#include "Common/CPUDetect.h" -#include "Common/Arm64Emitter.h" #include "Core/MIPS/ARM64/Arm64Jit.h" #include "Core/MIPS/ARM64/Arm64RegCache.h" @@ -1811,7 +1812,7 @@ namespace MIPSComp { u8 dreg; GetVectorRegs(&dreg, V_Single, _VT); - s32 imm = (s32)(s16)(u16)(op & 0xFFFF); + s32 imm = (s32)SignExtend16To32(op); fpr.MapRegV(dreg, MAP_DIRTY | MAP_NOINIT); fp.MOVI2F(fpr.V(dreg), (float)imm, SCRATCH1); diff --git a/Core/MIPS/IR/IRCompALU.cpp b/Core/MIPS/IR/IRCompALU.cpp index 72f9a1ff42..6a987cc374 100644 --- a/Core/MIPS/IR/IRCompALU.cpp +++ b/Core/MIPS/IR/IRCompALU.cpp @@ -274,7 +274,7 @@ void IRFrontend::Comp_Allegrex(MIPSOpcode op) { return; switch ((op >> 6) & 31) { - case 16: // seb // R(rd) = (u32)(s32)(s8)(u8)R(rt); + case 16: // seb // R(rd) = SignExtend8To32(R(rt)); ir.Write(IROp::Ext8to32, rd, rt); break; diff --git a/Core/MIPS/IR/IRCompBranch.cpp b/Core/MIPS/IR/IRCompBranch.cpp index 16a158b9fe..c60cf549b0 100644 --- a/Core/MIPS/IR/IRCompBranch.cpp +++ b/Core/MIPS/IR/IRCompBranch.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Profiler/Profiler.h" #include "Core/Reporting.h" @@ -40,9 +41,8 @@ #define _SA MIPS_GET_SA(op) #define _POS ((op>> 6) & 0x1F) #define _SIZE ((op>>11) & 0x1F) -#define _IMM16 (signed short)(op & 0xFFFF) #define _IMM26 (op & 0x03FFFFFF) -#define TARGET16 ((int)((uint32_t)(int)_IMM16 << 2)) +#define TARGET16 ((int)(SignExtend16To32(op) << 2)) #define TARGET26 (_IMM26 << 2) #define LOOPOPTIMIZATION 0 diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index 5226e57fd1..ddccf33e1b 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -17,9 +17,9 @@ #include -#include "Common/Math/math_util.h" - #include "Common/CPUDetect.h" +#include "Common/Data/Convert/SmallDataConvert.h" +#include "Common/Math/math_util.h" #include "Core/Compatibility.h" #include "Core/Config.h" #include "Core/MemMap.h" @@ -1778,7 +1778,7 @@ namespace MIPSComp { // Vector integer immediate // d[0] = float(imm) - s32 imm = (s32)(s16)(u16)(op & 0xFFFF); + s32 imm = (s32)SignExtend16To32(op); u8 dreg; GetVectorRegsPrefixD(&dreg, V_Single, _VT); ir.Write(IROp::SetConstF, dreg, ir.AddConstantFloat((float)imm)); diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index aa962dbb5e..bf01b2d80d 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -2,9 +2,10 @@ #include #include "ppsspp_config.h" -#include "Common/Math/math_util.h" -#include "Common/Common.h" #include "Common/BitScan.h" +#include "Common/Common.h" +#include "Common/Data/Convert/SmallDataConvert.h" +#include "Common/Math/math_util.h" #ifdef _M_SSE #include @@ -126,10 +127,10 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) { mips->r[inst->dest] = ~mips->r[inst->src1]; break; case IROp::Ext8to32: - mips->r[inst->dest] = (s32)(s8)mips->r[inst->src1]; + mips->r[inst->dest] = SignExtend8To32(mips->r[inst->src1]); break; case IROp::Ext16to32: - mips->r[inst->dest] = (s32)(s16)mips->r[inst->src1]; + mips->r[inst->dest] = SignExtend16To32(mips->r[inst->src1]); break; case IROp::ReverseBits: mips->r[inst->dest] = ReverseBits32(mips->r[inst->src1]); @@ -139,13 +140,13 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) { mips->r[inst->dest] = Memory::ReadUnchecked_U8(mips->r[inst->src1] + inst->constant); break; case IROp::Load8Ext: - mips->r[inst->dest] = (s32)(s8)Memory::ReadUnchecked_U8(mips->r[inst->src1] + inst->constant); + mips->r[inst->dest] = SignExtend8To32(Memory::ReadUnchecked_U8(mips->r[inst->src1] + inst->constant)); break; case IROp::Load16: mips->r[inst->dest] = Memory::ReadUnchecked_U16(mips->r[inst->src1] + inst->constant); break; case IROp::Load16Ext: - mips->r[inst->dest] = (s32)(s16)Memory::ReadUnchecked_U16(mips->r[inst->src1] + inst->constant); + mips->r[inst->dest] = SignExtend16To32(Memory::ReadUnchecked_U16(mips->r[inst->src1] + inst->constant)); break; case IROp::Load32: mips->r[inst->dest] = Memory::ReadUnchecked_U32(mips->r[inst->src1] + inst->constant); diff --git a/Core/MIPS/IR/IRPassSimplify.cpp b/Core/MIPS/IR/IRPassSimplify.cpp index ee65084a60..92dd6691d4 100644 --- a/Core/MIPS/IR/IRPassSimplify.cpp +++ b/Core/MIPS/IR/IRPassSimplify.cpp @@ -3,6 +3,7 @@ #include #include "Common/BitSet.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Log.h" #include "Core/MIPS/IR/IRInterpreter.h" #include "Core/MIPS/IR/IRPassSimplify.h" @@ -36,8 +37,8 @@ u32 Evaluate(u32 a, IROp op) { case IROp::Neg: return -(s32)a; case IROp::BSwap16: return ((a & 0xFF00FF00) >> 8) | ((a & 0x00FF00FF) << 8); case IROp::BSwap32: return swap32(a); - case IROp::Ext8to32: return (u32)(s32)(s8)(u8)a; - case IROp::Ext16to32: return (u32)(s32)(s16)(u16)a; + case IROp::Ext8to32: return SignExtend8To32(a); + case IROp::Ext16to32: return SignExtend16To32(a); case IROp::ReverseBits: return ReverseBits32(a); case IROp::Clz: { int x = 31; diff --git a/Core/MIPS/MIPSCodeUtils.h b/Core/MIPS/MIPSCodeUtils.h index b6c0a3642e..fab9aaa7b9 100644 --- a/Core/MIPS/MIPSCodeUtils.h +++ b/Core/MIPS/MIPSCodeUtils.h @@ -18,6 +18,7 @@ #pragma once #include "Common/CommonTypes.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Core/MIPS/MIPS.h" // Invalid branch target address @@ -52,6 +53,13 @@ #define MIPS_GET_VS(op) ((op>>8) & 0x7F) #define MIPS_GET_VT(op) ((op>>16) & 0x7F) +inline uint32_t SignExtend8To32(MIPSOpcode op) { + return SignExtend8To32(op.encoding); +} + +inline uint32_t SignExtend16To32(MIPSOpcode op) { + return SignExtend16To32(op.encoding); +} namespace MIPSCodeUtils { diff --git a/Core/MIPS/MIPSDis.cpp b/Core/MIPS/MIPSDis.cpp index 9cc169e588..3750bc15c8 100644 --- a/Core/MIPS/MIPSDis.cpp +++ b/Core/MIPS/MIPSDis.cpp @@ -19,6 +19,7 @@ #include "Core/HLE/HLE.h" #include "Core/MemMap.h" #include "Core/MIPS/MIPS.h" +#include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/MIPSDis.h" #include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/MIPSDebugInterface.h" @@ -171,9 +172,9 @@ namespace MIPSDis void Dis_IType(MIPSOpcode op, char *out) { - s32 simm = (s32)(s16)(op & 0xFFFF); - u32 uimm = (u32)(u16)(op & 0xFFFF); - u32 suimm = (u32)simm; + u32 uimm = op & 0xFFFF; + u32 suimm = SignExtend16To32(op); + s32 simm = (s32)suimm; int rt = _RT; int rs = _RS; diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index be67cc915d..6c60ddbff3 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -17,6 +17,7 @@ #include +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Math/math_util.h" #include "Common/BitSet.h" @@ -27,6 +28,7 @@ #include "Core/Host.h" #include "Core/MemMap.h" #include "Core/MIPS/MIPS.h" +#include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/MIPSInt.h" #include "Core/MIPS/MIPSTables.h" #include "Core/Reporting.h" @@ -295,10 +297,9 @@ namespace MIPSInt void Int_IType(MIPSOpcode op) { - s32 simm = (s32)(s16)(op & 0xFFFF); - u32 uimm = (u32)(u16)(op & 0xFFFF); - - u32 suimm = (u32)simm; + u32 uimm = op & 0xFFFF; + u32 suimm = SignExtend16To32(op); + s32 simm = (s32)suimm; int rt = _RT; int rs = _RS; @@ -411,8 +412,8 @@ namespace MIPSInt switch (op >> 26) { - case 32: R(rt) = (u32)(s32)(s8) Memory::Read_U8(addr); break; //lb - case 33: R(rt) = (u32)(s32)(s16)Memory::Read_U16(addr); break; //lh + case 32: R(rt) = SignExtend8To32(Memory::Read_U8(addr)); break; //lb + case 33: R(rt) = SignExtend16To32(Memory::Read_U16(addr)); break; //lh case 35: R(rt) = Memory::Read_U32(addr); break; //lw case 36: R(rt) = Memory::Read_U8 (addr); break; //lbu case 37: R(rt) = Memory::Read_U16(addr); break; //lhu @@ -738,7 +739,7 @@ namespace MIPSInt switch((op>>6)&31) { case 16: // seb - R(rd) = (u32)(s32)(s8)(u8)R(rt); + R(rd) = SignExtend8To32(R(rt)); break; case 20: // bitrev @@ -756,7 +757,7 @@ namespace MIPSInt break; case 24: // seh - R(rd) = (u32)(s32)(s16)(u16)R(rt); + R(rd) = SignExtend16To32(R(rt)); break; default: diff --git a/Core/MIPS/x86/CompALU.cpp b/Core/MIPS/x86/CompALU.cpp index 4c262cf1a4..61995792ba 100644 --- a/Core/MIPS/x86/CompALU.cpp +++ b/Core/MIPS/x86/CompALU.cpp @@ -798,10 +798,10 @@ namespace MIPSComp switch ((op >> 6) & 31) { - case 16: // seb // R(rd) = (u32)(s32)(s8)(u8)R(rt); + case 16: // seb // R(rd) = SignExtend8To32(R(rt)); if (gpr.IsImm(rt)) { - gpr.SetImm(rd, (u32)(s32)(s8)(u8)gpr.GetImm(rt)); + gpr.SetImm(rd, SignExtend8To32(gpr.GetImm(rt))); break; } @@ -876,10 +876,10 @@ namespace MIPSComp gpr.UnlockAll(); break; - case 24: // seh // R(rd) = (u32)(s32)(s16)(u16)R(rt); + case 24: // seh // R(rd) = SignExtend16To32(R(rt)); if (gpr.IsImm(rt)) { - gpr.SetImm(rd, (u32)(s32)(s16)(u16)gpr.GetImm(rt)); + gpr.SetImm(rd, SignExtend16To32(gpr.GetImm(rt))); break; } diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index 4910e29655..7c3cdf326e 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -18,6 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Profiler/Profiler.h" #include "Core/Config.h" @@ -46,9 +47,8 @@ #define _SA MIPS_GET_SA(op) #define _POS ((op>> 6) & 0x1F) #define _SIZE ((op>>11) & 0x1F) -#define _IMM16 (signed short)(op & 0xFFFF) #define _IMM26 (op & 0x03FFFFFF) -#define TARGET16 ((int)((uint32_t)(int)_IMM16 << 2)) +#define TARGET16 ((int)(SignExtend16To32(op) << 2)) #define TARGET26 (_IMM26 << 2) #define LOOPOPTIMIZATION 0 diff --git a/Core/MIPS/x86/CompLoadStore.cpp b/Core/MIPS/x86/CompLoadStore.cpp index 403f613f33..215e75797f 100644 --- a/Core/MIPS/x86/CompLoadStore.cpp +++ b/Core/MIPS/x86/CompLoadStore.cpp @@ -309,11 +309,11 @@ namespace MIPSComp { CompITypeMemRead(op, 32, &XEmitter::MOVZX, safeMemFuncs.readU32); break; - case 32: //R(rt) = (u32)(s32)(s8) ReadMem8 (addr); break; //lb + case 32: //R(rt) = SignExtend8To32 (ReadMem8 (addr)); break; //lb CompITypeMemRead(op, 8, &XEmitter::MOVSX, safeMemFuncs.readU8); break; - case 33: //R(rt) = (u32)(s32)(s16)ReadMem16(addr); break; //lh + case 33: //R(rt) = SignExtend16To32(ReadMem16(addr)); break; //lh CompITypeMemRead(op, 16, &XEmitter::MOVSX, safeMemFuncs.readU16); break; diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index f2cd64fd45..143d3f5a87 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -3452,7 +3452,7 @@ void Jit::Comp_Viim(MIPSOpcode op) { // Flush SIMD. fpr.SimpleRegsV(&dreg, V_Single, MAP_NOINIT | MAP_DIRTY); - s32 imm = (s32)(s16)(u16)(op & 0xFFFF); + s32 imm = (s32)SignExtend16To32(op); FP32 fp; fp.f = (float)imm; MOV(32, R(TEMPREG), Imm32(fp.u));