diff --git a/src/Cafe/HW/Espresso/Recompiler/BackendX64/BackendX64.cpp b/src/Cafe/HW/Espresso/Recompiler/BackendX64/BackendX64.cpp index 5ef713b9..f60ac2b8 100644 --- a/src/Cafe/HW/Espresso/Recompiler/BackendX64/BackendX64.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/BackendX64/BackendX64.cpp @@ -1073,26 +1073,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction else // XOR x64Gen_xor_reg64Low32_imm32(x64GenContext, regR, immS32); } - else if( imlInstruction->operation == PPCREC_IML_OP_RLWIMI ) - { - // registerResult = ((registerResult<<op_r_r_s32.immS32; - uint32 mb = (vImm>>0)&0xFF; - uint32 me = (vImm>>8)&0xFF; - uint32 sh = (vImm>>16)&0xFF; - uint32 mask = ppc_mask(mb, me); - // copy rS to temporary register - x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, regA); - // rotate destination register - if( sh ) - x64Gen_rol_reg64Low32_imm8(x64GenContext, REG_RESV_TEMP, (uint8)sh&0x1F); - // AND destination register with inverted mask - x64Gen_and_reg64Low32_imm32(x64GenContext, regR, ~mask); - // AND temporary rS register with mask - x64Gen_and_reg64Low32_imm32(x64GenContext, REG_RESV_TEMP, mask); - // OR result with temporary - x64Gen_or_reg64Low32_reg64Low32(x64GenContext, regR, REG_RESV_TEMP); - } else if( imlInstruction->operation == PPCREC_IML_OP_MULTIPLY_SIGNED ) { // registerResult = registerOperand * immS32 diff --git a/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.cpp b/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.cpp index 66548027..480b0d8d 100644 --- a/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.cpp @@ -93,19 +93,8 @@ void IMLInstruction::CheckRegisterUsage(IMLUsedRegisters* registersUsed) const } else if (type == PPCREC_IML_TYPE_R_R_S32) { - if (operation == PPCREC_IML_OP_RLWIMI) - { - // result and operand register are both read, result is written - registersUsed->writtenGPR1 = op_r_r_s32.regR; - registersUsed->readGPR1 = op_r_r_s32.regR; - registersUsed->readGPR2 = op_r_r_s32.regA; - } - else - { - // result is write only and operand is read only - registersUsed->writtenGPR1 = op_r_r_s32.regR; - registersUsed->readGPR1 = op_r_r_s32.regA; - } + registersUsed->writtenGPR1 = op_r_r_s32.regR; + registersUsed->readGPR1 = op_r_r_s32.regA; } else if (type == PPCREC_IML_TYPE_R_R_S32_CARRY) { diff --git a/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h b/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h index e58511c1..2cd1d642 100644 --- a/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h +++ b/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h @@ -122,7 +122,6 @@ enum PPCREC_IML_OP_RIGHT_SHIFT_U, // right shift operator (unsigned) PPCREC_IML_OP_RIGHT_SHIFT_S, // right shift operator (signed) // ppc - PPCREC_IML_OP_RLWIMI, // RLWIMI instruction (rotate, merge based on mask) PPCREC_IML_OP_SLW, // SLW (shift based on register by up to 63 bits) PPCREC_IML_OP_SRW, // SRW (shift based on register by up to 63 bits) PPCREC_IML_OP_CNTLZW, diff --git a/src/Cafe/HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp b/src/Cafe/HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp index 1ac884cd..583d5905 100644 --- a/src/Cafe/HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp @@ -290,7 +290,7 @@ void IMLRA_MergeSubranges(ppcImlGenContext_t* ppcImlGenContext, raLivenessRange* PPCRecRA_debugValidateSubrange(absorbedSubrange); if (subrange->imlSegment != absorbedSubrange->imlSegment) assert_dbg(); - cemu_assert_debug(subrange->interval2.end == absorbedSubrange->interval2.start); + cemu_assert_debug(subrange->interval.end == absorbedSubrange->interval.start); if (subrange->subrangeBranchTaken || subrange->subrangeBranchNotTaken) assert_dbg(); @@ -375,23 +375,23 @@ void PPCRecRA_debugValidateSubrange(raLivenessRange* range) if(range->subrangeBranchTaken || range->subrangeBranchNotTaken) { - cemu_assert_debug(range->interval2.end.ConnectsToNextSegment()); + cemu_assert_debug(range->interval.end.ConnectsToNextSegment()); } if(!range->previousRanges.empty()) { - cemu_assert_debug(range->interval2.start.ConnectsToPreviousSegment()); + cemu_assert_debug(range->interval.start.ConnectsToPreviousSegment()); } // validate locations if (!range->list_accessLocations.empty()) { - cemu_assert_debug(range->list_accessLocations.front().pos >= range->interval2.start); - cemu_assert_debug(range->list_accessLocations.back().pos <= range->interval2.end); + cemu_assert_debug(range->list_accessLocations.front().pos >= range->interval.start); + cemu_assert_debug(range->list_accessLocations.back().pos <= range->interval.end); } // validate fixed reg requirements if (!range->list_fixedRegRequirements.empty()) { - cemu_assert_debug(range->list_fixedRegRequirements.front().pos >= range->interval2.start); - cemu_assert_debug(range->list_fixedRegRequirements.back().pos <= range->interval2.end); + cemu_assert_debug(range->list_fixedRegRequirements.front().pos >= range->interval.start); + cemu_assert_debug(range->list_fixedRegRequirements.back().pos <= range->interval.end); for(sint32 i = 0; i < (sint32)range->list_fixedRegRequirements.size()-1; i++) cemu_assert_debug(range->list_fixedRegRequirements[i].pos < range->list_fixedRegRequirements[i+1].pos); } @@ -423,12 +423,12 @@ void IMLRA_TrimRangeToUse(raLivenessRange* range) range->interval.end = range->list_accessLocations.back().pos; // extra checks #ifdef CEMU_DEBUG_ASSERT - cemu_assert_debug(range->interval2.start <= range->interval2.end); + cemu_assert_debug(range->interval.start <= range->interval.end); for(auto& loc : range->list_accessLocations) { - cemu_assert_debug(range->interval2.ContainsEdge(loc.pos)); + cemu_assert_debug(range->interval.ContainsEdge(loc.pos)); } - cemu_assert_debug(prevInterval.ContainsWholeInterval(range->interval2)); + cemu_assert_debug(prevInterval.ContainsWholeInterval(range->interval)); #endif } @@ -580,7 +580,7 @@ sint32 IMLRA_CalculateAdditionalCostAfterSplit(raLivenessRange* subrange, raInst { // validation #ifdef CEMU_DEBUG_ASSERT - if (subrange->interval2.ExtendsIntoNextSegment()) + if (subrange->interval.ExtendsIntoNextSegment()) assert_dbg(); #endif cemu_assert_debug(splitPosition.IsInstructionIndex()); diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp index 9b74e45b..55d4a94b 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp @@ -982,12 +982,12 @@ bool PPCRecompilerImlGen_DIVWU(ppcImlGenContext_t* ppcImlGenContext, uint32 opco bool PPCRecompilerImlGen_RLWINM(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode) { - int rS, rA, SH, MB, ME; + sint32 rS, rA, SH, MB, ME; PPC_OPC_TEMPL_M(opcode, rS, rA, SH, MB, ME); uint32 mask = ppc_mask(MB, ME); IMLReg regS = _GetRegGPR(ppcImlGenContext, rS); - IMLReg regA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA); + IMLReg regA = _GetRegGPR(ppcImlGenContext, rA); if( ME == (31-SH) && MB == 0 ) { // SLWI @@ -1015,16 +1015,22 @@ bool PPCRecompilerImlGen_RLWINM(ppcImlGenContext_t* ppcImlGenContext, uint32 opc bool PPCRecompilerImlGen_RLWIMI(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode) { - int rS, rA, SH, MB, ME; + sint32 rS, rA, SH, MB, ME; PPC_OPC_TEMPL_M(opcode, rS, rA, SH, MB, ME); - - IMLReg regS = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rS); - IMLReg regA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA); - // pack RLWIMI parameters into single integer - uint32 vImm = MB|(ME<<8)|(SH<<16); - ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_RLWIMI, regA, regS, (sint32)vImm); + IMLReg regS = _GetRegGPR(ppcImlGenContext, rS); + IMLReg regR = _GetRegGPR(ppcImlGenContext, rA); + IMLReg regTmp = _GetRegTemporary(ppcImlGenContext, 0); + uint32 mask = ppc_mask(MB, ME); + ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ASSIGN, regTmp, regS); + if (SH) + ppcImlGenContext->emitInst().make_r_s32(PPCREC_IML_OP_LEFT_ROTATE, regTmp, SH); + if (mask != 0) + ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_AND, regR, regR, (sint32)~mask); + if (mask != 0xFFFFFFFF) + ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_AND, regTmp, regTmp, (sint32)mask); + ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_OR, regR, regR, regTmp); if (opcode & PPC_OPC_RC) - PPCImlGen_UpdateCR0(ppcImlGenContext, regA); + PPCImlGen_UpdateCR0(ppcImlGenContext, regR); return true; }