Skip to content

Commit

Permalink
PPCRec: Implement MFCR and MTCRF
Browse files Browse the repository at this point in the history
  • Loading branch information
Exzap committed Mar 13, 2023
1 parent 97e39e3 commit 3590ad9
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 921 deletions.
33 changes: 0 additions & 33 deletions src/Cafe/HW/Espresso/Recompiler/BackendX64/BackendX64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,31 +680,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_s32(PPCRecFunction_t* PPCRecFunction,
cemu_assert_debug((imlInstruction->op_r_immS32.immS32 & 0x80) == 0);
x64Gen_rol_reg64Low32_imm8(x64GenContext, regR, (uint8)imlInstruction->op_r_immS32.immS32);
}
else if( imlInstruction->operation == PPCREC_IML_OP_MFCR )
{
DEBUG_BREAK;
//uint32 destRegister = imlInstruction->op_r_immS32.registerIndex;
//x64Gen_xor_reg64Low32_reg64Low32(x64GenContext, destRegister, destRegister);
//for(sint32 f=0; f<32; f++)
//{
// x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+f, 0);
// x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, destRegister, destRegister);
//}
}
else if (imlInstruction->operation == PPCREC_IML_OP_MTCRF)
{
DEBUG_BREAK;
//uint32 srcRegister = imlInstruction->op_r_immS32.registerIndex;
//uint32 crBitMask = ppc_MTCRFMaskToCRBitMask((uint32)imlInstruction->op_r_immS32.immS32);
//for (sint32 f = 0; f < 32; f++)
//{
// if(((crBitMask >> f) & 1) == 0)
// continue;
// x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_ESP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8) * (f), 0);
// x64Gen_test_reg64Low32_imm32(x64GenContext, srcRegister, 0x80000000>>f);
// x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_NOT_EQUAL, X86_REG_ESP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8) * (f));
//}
}
else
{
debug_printf("PPCRecompilerX64Gen_imlInstruction_r_s32(): Unsupported operation 0x%x\n", imlInstruction->operation);
Expand Down Expand Up @@ -1582,14 +1557,6 @@ bool PPCRecompiler_generateX64Code(PPCRecFunction_t* PPCRecFunction, ppcImlGenCo
{
// no op
}
else if( imlInstruction->type == PPCREC_IML_TYPE_FPR_R_NAME )
{
PPCRecompilerX64Gen_imlInstruction_fpr_r_name(PPCRecFunction, ppcImlGenContext, &x64GenContext, imlInstruction);
}
else if( imlInstruction->type == PPCREC_IML_TYPE_FPR_NAME_R )
{
PPCRecompilerX64Gen_imlInstruction_fpr_name_r(PPCRecFunction, ppcImlGenContext, &x64GenContext, imlInstruction);
}
else if( imlInstruction->type == PPCREC_IML_TYPE_FPR_LOAD )
{
if( PPCRecompilerX64Gen_imlInstruction_fpr_load(PPCRecFunction, ppcImlGenContext, &x64GenContext, imlInstruction, false) == false )
Expand Down
36 changes: 0 additions & 36 deletions src/Cafe/HW/Espresso/Recompiler/BackendX64/BackendX64FPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,42 +34,6 @@ static x86Assembler64::GPR8_REX _reg8_from_reg32(x86Assembler64::GPR32 regId)
return (x86Assembler64::GPR8_REX)regId;
}

void PPCRecompilerX64Gen_imlInstruction_fpr_r_name(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
{
uint32 name = imlInstruction->op_r_name.name;
uint32 fprReg = _regF64(imlInstruction->op_r_name.regR);
if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) )
{
x64Gen_movupd_xmmReg_memReg128(x64GenContext, fprReg, X86_REG_ESP, offsetof(PPCInterpreter_t, fpr)+sizeof(FPR_t)*(name-PPCREC_NAME_FPR0));
}
else if( name >= PPCREC_NAME_TEMPORARY_FPR0 || name < (PPCREC_NAME_TEMPORARY_FPR0+8) )
{
x64Gen_movupd_xmmReg_memReg128(x64GenContext, fprReg, X86_REG_ESP, offsetof(PPCInterpreter_t, temporaryFPR)+sizeof(FPR_t)*(name-PPCREC_NAME_TEMPORARY_FPR0));
}
else
{
cemu_assert_debug(false);
}
}

void PPCRecompilerX64Gen_imlInstruction_fpr_name_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
{
uint32 name = imlInstruction->op_r_name.name;
uint32 fprReg = _regF64(imlInstruction->op_r_name.regR);
if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) )
{
x64Gen_movupd_memReg128_xmmReg(x64GenContext, fprReg, X86_REG_ESP, offsetof(PPCInterpreter_t, fpr)+sizeof(FPR_t)*(name-PPCREC_NAME_FPR0));
}
else if( name >= PPCREC_NAME_TEMPORARY_FPR0 && name < (PPCREC_NAME_TEMPORARY_FPR0+8) )
{
x64Gen_movupd_memReg128_xmmReg(x64GenContext, fprReg, X86_REG_ESP, offsetof(PPCInterpreter_t, temporaryFPR)+sizeof(FPR_t)*(name-PPCREC_NAME_TEMPORARY_FPR0));
}
else
{
cemu_assert_debug(false);
}
}

void PPCRecompilerX64Gen_imlInstr_gqr_generateScaleCode(ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, sint32 registerXMM, bool isLoad, bool scalePS1, IMLReg registerGQR)
{
// load GQR
Expand Down
17 changes: 3 additions & 14 deletions src/Cafe/HW/Espresso/Recompiler/IML/IML.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,13 @@
#include "IMLSegment.h"

// analyzer
struct PPCRecCRTracking_t
{
uint32 readCRBits;
uint32 writtenCRBits;
};

bool IMLAnalyzer_IsTightFiniteLoop(IMLSegment* imlSegment);
bool IMLAnalyzer_CanTypeWriteCR(IMLInstruction* imlInstruction);

// optimizer passes
// todo - rename
//bool PPCRecompiler_reduceNumberOfFPRRegisters(struct ppcImlGenContext_t* ppcImlGenContext);
//bool PPCRecompiler_manageFPRRegisters(struct ppcImlGenContext_t* ppcImlGenContext);
void PPCRecompiler_optimizeDirectFloatCopies(struct ppcImlGenContext_t* ppcImlGenContext);
void PPCRecompiler_optimizeDirectIntegerCopies(struct ppcImlGenContext_t* ppcImlGenContext);
void IMLOptimizer_OptimizeDirectFloatCopies(struct ppcImlGenContext_t* ppcImlGenContext);
void IMLOptimizer_OptimizeDirectIntegerCopies(struct ppcImlGenContext_t* ppcImlGenContext);
void PPCRecompiler_optimizePSQLoadAndStore(struct ppcImlGenContext_t* ppcImlGenContext);
void PPCRecompiler_reorderConditionModifyInstructions(struct ppcImlGenContext_t* ppcImlGenContext);

// debug
void IMLDebug_DumpSegment(struct ppcImlGenContext_t* ctx, struct IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo = false);
void IMLDebug_DumpSegment(struct ppcImlGenContext_t* ctx, IMLSegment* imlSegment, bool printLivenessRangeInfo = false);
void IMLDebug_Dump(struct ppcImlGenContext_t* ppcImlGenContext, bool printLivenessRangeInfo = false);
38 changes: 1 addition & 37 deletions src/Cafe/HW/Espresso/Recompiler/IML/IMLAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,40 +52,4 @@ bool IMLAnalyzer_IsTightFiniteLoop(IMLSegment* imlSegment)
}
}
return false;
}

/*
* Returns true if the instruction can overwrite CR (depending on value of ->crRegister)
*/
bool IMLAnalyzer_CanTypeWriteCR(IMLInstruction* imlInstruction)
{
if (imlInstruction->type == PPCREC_IML_TYPE_R_R)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_R_R_R)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_R_R_S32)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_R_S32)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_FPR_R_R)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_FPR_R_R_R)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_FPR_R_R_R_R)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_FPR_R)
return true;

// new instructions
if (imlInstruction->type == PPCREC_IML_TYPE_COMPARE || imlInstruction->type == PPCREC_IML_TYPE_COMPARE_S32)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_CONDITIONAL_JUMP)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_R_R_R_CARRY)
return true;
if (imlInstruction->type == PPCREC_IML_TYPE_R_R_S32_CARRY)
return true;


return false;
}
}
32 changes: 1 addition & 31 deletions src/Cafe/HW/Espresso/Recompiler/IML/IMLDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ std::string IMLDebug_GetRegName(IMLReg r)
regName.append("r");
break;
default:
__debugbreak();
DEBUG_BREAK;
}
regName.append(fmt::format("{}", regId));
return regName;
Expand Down Expand Up @@ -417,36 +417,6 @@ void IMLDebug_DumpSegment(ppcImlGenContext_t* ctx, IMLSegment* imlSegment, bool
strOutput.addFmt("MACRO ukn operation {}", inst.operation);
}
}
else if (inst.type == PPCREC_IML_TYPE_FPR_R_NAME)
{
strOutput.addFmt("fpr_t{} = name_{} (", inst.op_r_name.regR.GetRegID(), inst.op_r_name.name);
if (inst.op_r_name.name >= PPCREC_NAME_FPR0 && inst.op_r_name.name < (PPCREC_NAME_FPR0 + 999))
{
strOutput.addFmt("fpr{}", inst.op_r_name.name - PPCREC_NAME_FPR0);
}
else if (inst.op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && inst.op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0 + 999))
{
strOutput.addFmt("tempFpr{}", inst.op_r_name.name - PPCREC_NAME_TEMPORARY_FPR0);
}
else
strOutput.add("ukn");
strOutput.add(")");
}
else if (inst.type == PPCREC_IML_TYPE_FPR_NAME_R)
{
strOutput.addFmt("name_{} (", inst.op_r_name.name);
if (inst.op_r_name.name >= PPCREC_NAME_FPR0 && inst.op_r_name.name < (PPCREC_NAME_FPR0 + 999))
{
strOutput.addFmt("fpr{}", inst.op_r_name.name - PPCREC_NAME_FPR0);
}
else if (inst.op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && inst.op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0 + 999))
{
strOutput.addFmt("tempFpr{}", inst.op_r_name.name - PPCREC_NAME_TEMPORARY_FPR0);
}
else
strOutput.add("ukn");
strOutput.addFmt(") = {}", IMLDebug_GetRegName(inst.op_r_name.regR));
}
else if (inst.type == PPCREC_IML_TYPE_FPR_LOAD)
{
strOutput.addFmt("{} = ", IMLDebug_GetRegName(inst.op_storeLoad.registerData));
Expand Down
41 changes: 1 addition & 40 deletions src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ void IMLInstruction::CheckRegisterUsage(IMLUsedRegisters* registersUsed) const
operation != PPCREC_IML_OP_OR &&
operation != PPCREC_IML_OP_XOR); // deprecated, use r_r_s32 for these

if (operation == PPCREC_IML_OP_MTCRF)
{
// operand register is read only
registersUsed->readGPR1 = op_r_immS32.regR;
}
else if (operation == PPCREC_IML_OP_LEFT_ROTATE)
if (operation == PPCREC_IML_OP_LEFT_ROTATE)
{
// operand register is read and write
registersUsed->readGPR1 = op_r_immS32.regR;
Expand Down Expand Up @@ -221,16 +216,6 @@ void IMLInstruction::CheckRegisterUsage(IMLUsedRegisters* registersUsed) const
registersUsed->readGPR3 = op_atomic_compare_store.regWriteValue;
registersUsed->writtenGPR1 = op_atomic_compare_store.regBoolOut;
}
else if (type == PPCREC_IML_TYPE_FPR_R_NAME)
{
// fpr operation
registersUsed->writtenFPR1 = op_r_name.regR;
}
else if (type == PPCREC_IML_TYPE_FPR_NAME_R)
{
// fpr operation
registersUsed->readFPR1 = op_r_name.regR;
}
else if (type == PPCREC_IML_TYPE_FPR_LOAD)
{
// fpr load operation
Expand Down Expand Up @@ -636,14 +621,6 @@ void IMLInstruction::RewriteGPR(const std::unordered_map<IMLRegID, IMLRegID>& tr
op_atomic_compare_store.regWriteValue = replaceRegisterIdMultiple(op_atomic_compare_store.regWriteValue, translationTable);
op_atomic_compare_store.regBoolOut = replaceRegisterIdMultiple(op_atomic_compare_store.regBoolOut, translationTable);
}
else if (type == PPCREC_IML_TYPE_FPR_R_NAME)
{
op_r_name.regR = replaceRegisterIdMultiple(op_r_name.regR, translationTable);
}
else if (type == PPCREC_IML_TYPE_FPR_NAME_R)
{
op_r_name.regR = replaceRegisterIdMultiple(op_r_name.regR, translationTable);
}
else if (type == PPCREC_IML_TYPE_FPR_LOAD)
{
op_storeLoad.registerData = replaceRegisterIdMultiple(op_storeLoad.registerData, translationTable);
Expand Down Expand Up @@ -766,14 +743,6 @@ void IMLInstruction::ReplaceFPRs(IMLReg fprRegisterSearched[4], IMLReg fprRegist
{
;
}
else if (type == PPCREC_IML_TYPE_FPR_R_NAME)
{
op_r_name.regR = replaceRegisterIdMultiple(op_r_name.regR, fprRegisterSearched, fprRegisterReplaced);
}
else if (type == PPCREC_IML_TYPE_FPR_NAME_R)
{
op_r_name.regR = replaceRegisterIdMultiple(op_r_name.regR, fprRegisterSearched, fprRegisterReplaced);
}
else if (type == PPCREC_IML_TYPE_FPR_LOAD)
{
op_storeLoad.registerData = replaceRegisterIdMultiple(op_storeLoad.registerData, fprRegisterSearched, fprRegisterReplaced);
Expand Down Expand Up @@ -885,14 +854,6 @@ void IMLInstruction::ReplaceFPR(IMLRegID fprRegisterSearched, IMLRegID fprRegist
{
;
}
else if (type == PPCREC_IML_TYPE_FPR_R_NAME)
{
op_r_name.regR = replaceRegisterId(op_r_name.regR, fprRegisterSearched, fprRegisterReplaced);
}
else if (type == PPCREC_IML_TYPE_FPR_NAME_R)
{
op_r_name.regR = replaceRegisterId(op_r_name.regR, fprRegisterSearched, fprRegisterReplaced);
}
else if (type == PPCREC_IML_TYPE_FPR_LOAD)
{
op_storeLoad.registerData = replaceRegisterId(op_storeLoad.registerData, fprRegisterSearched, fprRegisterReplaced);
Expand Down
18 changes: 0 additions & 18 deletions src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,6 @@ enum
PPCREC_IML_OP_SRW, // SRW (shift based on register by up to 63 bits)
PPCREC_IML_OP_CNTLZW,
PPCREC_IML_OP_DCBZ, // clear 32 bytes aligned to 0x20
PPCREC_IML_OP_MFCR, // copy cr to gpr
PPCREC_IML_OP_MTCRF, // copy gpr to cr (with mask)
// FPU
PPCREC_IML_OP_FPR_ADD_BOTTOM,
PPCREC_IML_OP_FPR_ADD_PAIR,
Expand Down Expand Up @@ -253,8 +251,6 @@ enum
PPCREC_IML_TYPE_CONDITIONAL_R_S32,

// FPR
PPCREC_IML_TYPE_FPR_R_NAME, // name = f*
PPCREC_IML_TYPE_FPR_NAME_R, // f* = name
PPCREC_IML_TYPE_FPR_LOAD, // r* = (bitdepth) [r*+s32*] (single or paired single mode)
PPCREC_IML_TYPE_FPR_LOAD_INDEXED, // r* = (bitdepth) [r*+r*] (single or paired single mode)
PPCREC_IML_TYPE_FPR_STORE, // (bitdepth) [r*+s32*] = r* (single or paired single mode)
Expand Down Expand Up @@ -412,20 +408,6 @@ struct IMLUsedRegisters
F(writtenFPR1, true);
}

//bool HasSameBaseFPRRegId(IMLRegID regId) const
//{
// if (readFPR1.IsValid() && readFPR1.GetRegID() == regId)
// return true;
// if (readFPR2.IsValid() && readFPR2.GetRegID() == regId)
// return true;
// if (readFPR3.IsValid() && readFPR3.GetRegID() == regId)
// return true;
// if (readFPR4.IsValid() && readFPR4.GetRegID() == regId)
// return true;
// if (writtenFPR1.IsValid() && writtenFPR1.GetRegID() == regId)
// return true;
// return false;
//}
};

struct IMLInstruction
Expand Down
Loading

0 comments on commit 3590ad9

Please sign in to comment.