mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-04-29 14:59:26 -04:00
PPCRec: Rename IML structs for better clarity
This commit is contained in:
parent
4abd5127c0
commit
faf6c17438
16 changed files with 396 additions and 424 deletions
|
@ -236,7 +236,7 @@ enum
|
||||||
PPCREC_FPR_ST_MODE_PSQ_S16_PS0_PS1,
|
PPCREC_FPR_ST_MODE_PSQ_S16_PS0_PS1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PPCRecImlInstruction_t
|
struct IMLInstruction
|
||||||
{
|
{
|
||||||
uint8 type;
|
uint8 type;
|
||||||
uint8 operation;
|
uint8 operation;
|
||||||
|
@ -274,9 +274,7 @@ struct PPCRecImlInstruction_t
|
||||||
{
|
{
|
||||||
// R/F = NAME or NAME = R/F
|
// R/F = NAME or NAME = R/F
|
||||||
uint8 registerIndex;
|
uint8 registerIndex;
|
||||||
uint8 copyWidth;
|
|
||||||
uint32 name;
|
uint32 name;
|
||||||
uint8 flags;
|
|
||||||
}op_r_name;
|
}op_r_name;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -298,7 +296,7 @@ struct PPCRecImlInstruction_t
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 jumpmarkAddress;
|
uint32 jumpmarkAddress;
|
||||||
bool jumpAccordingToSegment; //PPCRecImlSegment_t* destinationSegment; // if set, this replaces jumpmarkAddress
|
bool jumpAccordingToSegment; //IMLSegment* destinationSegment; // if set, this replaces jumpmarkAddress
|
||||||
uint8 condition; // only used when crRegisterIndex is 8 or above (update: Apparently only used to mark jumps without a condition? -> Cleanup)
|
uint8 condition; // only used when crRegisterIndex is 8 or above (update: Apparently only used to mark jumps without a condition? -> Cleanup)
|
||||||
uint8 crRegisterIndex;
|
uint8 crRegisterIndex;
|
||||||
uint8 crBitIndex;
|
uint8 crBitIndex;
|
||||||
|
@ -311,7 +309,6 @@ struct PPCRecImlInstruction_t
|
||||||
uint8 registerMem2;
|
uint8 registerMem2;
|
||||||
uint8 registerGQR;
|
uint8 registerGQR;
|
||||||
uint8 copyWidth;
|
uint8 copyWidth;
|
||||||
//uint8 flags;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool swapEndian : 1;
|
bool swapEndian : 1;
|
||||||
|
@ -322,20 +319,6 @@ struct PPCRecImlInstruction_t
|
||||||
sint32 immS32;
|
sint32 immS32;
|
||||||
}op_storeLoad;
|
}op_storeLoad;
|
||||||
struct
|
struct
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint8 registerMem;
|
|
||||||
sint32 immS32;
|
|
||||||
}src;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint8 registerMem;
|
|
||||||
sint32 immS32;
|
|
||||||
}dst;
|
|
||||||
uint8 copyWidth;
|
|
||||||
}op_mem2mem;
|
|
||||||
struct
|
|
||||||
{
|
{
|
||||||
uint8 registerResult;
|
uint8 registerResult;
|
||||||
uint8 registerOperand;
|
uint8 registerOperand;
|
||||||
|
@ -359,7 +342,6 @@ struct PPCRecImlInstruction_t
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8 registerResult;
|
uint8 registerResult;
|
||||||
//uint8 flags;
|
|
||||||
}op_fpr_r;
|
}op_fpr_r;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -384,4 +366,30 @@ struct PPCRecImlInstruction_t
|
||||||
bool bitMustBeSet;
|
bool bitMustBeSet;
|
||||||
}op_conditional_r_s32;
|
}op_conditional_r_s32;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// instruction setters
|
||||||
|
void make_jumpmark(uint32 address)
|
||||||
|
{
|
||||||
|
type = PPCREC_IML_TYPE_JUMPMARK;
|
||||||
|
op_jumpmark.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
void make_macro(uint32 macroId, uint32 param, uint32 param2, uint16 paramU16)
|
||||||
|
{
|
||||||
|
type = PPCREC_IML_TYPE_MACRO;
|
||||||
|
operation = macroId;
|
||||||
|
op_macro.param = param;
|
||||||
|
op_macro.param2 = param2;
|
||||||
|
op_macro.paramU16 = paramU16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void make_ppcEnter(uint32 ppcAddress)
|
||||||
|
{
|
||||||
|
type = PPCREC_IML_TYPE_PPC_ENTER;
|
||||||
|
operation = 0;
|
||||||
|
op_ppcEnter.ppcAddress = ppcAddress;
|
||||||
|
op_ppcEnter.x64Offset = 0;
|
||||||
|
associatedPPCAddress = 0;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct PPCRecImlSegment_t
|
struct IMLSegment
|
||||||
{
|
{
|
||||||
sint32 momentaryIndex{}; // index in segment list, generally not kept up to date except if needed (necessary for loop detection)
|
sint32 momentaryIndex{}; // index in segment list, generally not kept up to date except if needed (necessary for loop detection)
|
||||||
sint32 startOffset{}; // offset to first instruction in iml instruction list
|
sint32 startOffset{}; // offset to first instruction in iml instruction list
|
||||||
|
@ -9,13 +9,13 @@ struct PPCRecImlSegment_t
|
||||||
uint32 x64Offset{}; // x64 code offset of segment start
|
uint32 x64Offset{}; // x64 code offset of segment start
|
||||||
uint32 cycleCount{}; // number of PPC cycles required to execute this segment (roughly)
|
uint32 cycleCount{}; // number of PPC cycles required to execute this segment (roughly)
|
||||||
// list of intermediate instructions in this segment
|
// list of intermediate instructions in this segment
|
||||||
std::vector<PPCRecImlInstruction_t> imlList;
|
std::vector<IMLInstruction> imlList;
|
||||||
// segment link
|
// segment link
|
||||||
PPCRecImlSegment_t* nextSegmentBranchNotTaken{}; // this is also the default for segments where there is no branch
|
IMLSegment* nextSegmentBranchNotTaken{}; // this is also the default for segments where there is no branch
|
||||||
PPCRecImlSegment_t* nextSegmentBranchTaken{};
|
IMLSegment* nextSegmentBranchTaken{};
|
||||||
bool nextSegmentIsUncertain{};
|
bool nextSegmentIsUncertain{};
|
||||||
sint32 loopDepth{};
|
sint32 loopDepth{};
|
||||||
std::vector<PPCRecImlSegment_t*> list_prevSegments{};
|
std::vector<IMLSegment*> list_prevSegments{};
|
||||||
// PPC range of segment
|
// PPC range of segment
|
||||||
uint32 ppcAddrMin{};
|
uint32 ppcAddrMin{};
|
||||||
uint32 ppcAddrMax{};
|
uint32 ppcAddrMax{};
|
||||||
|
|
|
@ -173,7 +173,7 @@ PPCRecFunction_t* PPCRecompiler_recompileFunction(PPCFunctionBoundaryTracker::PP
|
||||||
|
|
||||||
// collect list of PPC-->x64 entry points
|
// collect list of PPC-->x64 entry points
|
||||||
entryPointsOut.clear();
|
entryPointsOut.clear();
|
||||||
for(PPCRecImlSegment_t* imlSegment : ppcImlGenContext.segmentList2)
|
for(IMLSegment* imlSegment : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
if (imlSegment->isEnterable == false)
|
if (imlSegment->isEnterable == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -31,7 +31,7 @@ typedef struct
|
||||||
typedef struct _ppcRecompilerSegmentPoint_t
|
typedef struct _ppcRecompilerSegmentPoint_t
|
||||||
{
|
{
|
||||||
sint32 index;
|
sint32 index;
|
||||||
struct PPCRecImlSegment_t* imlSegment;
|
struct IMLSegment* imlSegment;
|
||||||
_ppcRecompilerSegmentPoint_t* next;
|
_ppcRecompilerSegmentPoint_t* next;
|
||||||
_ppcRecompilerSegmentPoint_t* prev;
|
_ppcRecompilerSegmentPoint_t* prev;
|
||||||
}ppcRecompilerSegmentPoint_t;
|
}ppcRecompilerSegmentPoint_t;
|
||||||
|
@ -57,7 +57,7 @@ struct raLivenessSubrangeLink_t
|
||||||
struct raLivenessSubrange_t
|
struct raLivenessSubrange_t
|
||||||
{
|
{
|
||||||
struct raLivenessRange_t* range;
|
struct raLivenessRange_t* range;
|
||||||
PPCRecImlSegment_t* imlSegment;
|
IMLSegment* imlSegment;
|
||||||
ppcRecompilerSegmentPoint_t start;
|
ppcRecompilerSegmentPoint_t start;
|
||||||
ppcRecompilerSegmentPoint_t end;
|
ppcRecompilerSegmentPoint_t end;
|
||||||
// dirty state tracking
|
// dirty state tracking
|
||||||
|
@ -107,6 +107,8 @@ struct PPCRecVGPRDistances_t
|
||||||
|
|
||||||
#include "Cafe/HW/Espresso/Recompiler/IML/IMLSegment.h"
|
#include "Cafe/HW/Espresso/Recompiler/IML/IMLSegment.h"
|
||||||
|
|
||||||
|
struct IMLInstruction* PPCRecompilerImlGen_generateNewEmptyInstruction(struct ppcImlGenContext_t* ppcImlGenContext);
|
||||||
|
|
||||||
struct ppcImlGenContext_t
|
struct ppcImlGenContext_t
|
||||||
{
|
{
|
||||||
PPCRecFunction_t* functionRef;
|
PPCRecFunction_t* functionRef;
|
||||||
|
@ -122,14 +124,11 @@ struct ppcImlGenContext_t
|
||||||
// temporary floating point registers (single and double precision)
|
// temporary floating point registers (single and double precision)
|
||||||
uint32 mappedFPRRegister[256];
|
uint32 mappedFPRRegister[256];
|
||||||
// list of intermediate instructions
|
// list of intermediate instructions
|
||||||
PPCRecImlInstruction_t* imlList;
|
IMLInstruction* imlList;
|
||||||
sint32 imlListSize;
|
sint32 imlListSize;
|
||||||
sint32 imlListCount;
|
sint32 imlListCount;
|
||||||
// list of segments
|
// list of segments
|
||||||
//PPCRecImlSegment_t** segmentList;
|
std::vector<IMLSegment*> segmentList2;
|
||||||
//sint32 segmentListSize;
|
|
||||||
//sint32 segmentListCount;
|
|
||||||
std::vector<PPCRecImlSegment_t*> segmentList2;
|
|
||||||
// code generation control
|
// code generation control
|
||||||
bool hasFPUInstruction; // if true, PPCEnter macro will create FP_UNAVAIL checks -> Not needed in user mode
|
bool hasFPUInstruction; // if true, PPCEnter macro will create FP_UNAVAIL checks -> Not needed in user mode
|
||||||
// register allocator info
|
// register allocator info
|
||||||
|
@ -142,6 +141,12 @@ struct ppcImlGenContext_t
|
||||||
{
|
{
|
||||||
bool modifiesGQR[8];
|
bool modifiesGQR[8];
|
||||||
}tracking;
|
}tracking;
|
||||||
|
|
||||||
|
// append raw instruction
|
||||||
|
IMLInstruction& emitInst()
|
||||||
|
{
|
||||||
|
return *PPCRecompilerImlGen_generateNewEmptyInstruction(this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void ATTR_MS_ABI (*PPCREC_JUMP_ENTRY)();
|
typedef void ATTR_MS_ABI (*PPCREC_JUMP_ENTRY)();
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext, PPCRecFunction_t* PPCRecFunction, std::set<uint32>& entryAddresses);
|
bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext, PPCRecFunction_t* PPCRecFunction, std::set<uint32>& entryAddresses);
|
||||||
void PPCRecompiler_freeContext(ppcImlGenContext_t* ppcImlGenContext); // todo - move to destructor
|
void PPCRecompiler_freeContext(ppcImlGenContext_t* ppcImlGenContext); // todo - move to destructor
|
||||||
|
|
||||||
PPCRecImlInstruction_t* PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext_t* ppcImlGenContext);
|
IMLInstruction* PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
void PPCRecompiler_pushBackIMLInstructions(PPCRecImlSegment_t* imlSegment, sint32 index, sint32 shiftBackCount);
|
void PPCRecompiler_pushBackIMLInstructions(IMLSegment* imlSegment, sint32 index, sint32 shiftBackCount);
|
||||||
PPCRecImlInstruction_t* PPCRecompiler_insertInstruction(PPCRecImlSegment_t* imlSegment, sint32 index);
|
IMLInstruction* PPCRecompiler_insertInstruction(IMLSegment* imlSegment, sint32 index);
|
||||||
|
|
||||||
void PPCRecompilerIml_insertSegments(ppcImlGenContext_t* ppcImlGenContext, sint32 index, sint32 count);
|
void PPCRecompilerIml_insertSegments(ppcImlGenContext_t* ppcImlGenContext, sint32 index, sint32 count);
|
||||||
|
|
||||||
void PPCRecompilerIml_setSegmentPoint(ppcRecompilerSegmentPoint_t* segmentPoint, PPCRecImlSegment_t* imlSegment, sint32 index);
|
void PPCRecompilerIml_setSegmentPoint(ppcRecompilerSegmentPoint_t* segmentPoint, IMLSegment* imlSegment, sint32 index);
|
||||||
void PPCRecompilerIml_removeSegmentPoint(ppcRecompilerSegmentPoint_t* segmentPoint);
|
void PPCRecompilerIml_removeSegmentPoint(ppcRecompilerSegmentPoint_t* segmentPoint);
|
||||||
|
|
||||||
// GPR register management
|
// GPR register management
|
||||||
|
@ -22,20 +22,20 @@ uint32 PPCRecompilerImlGen_loadFPRRegister(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
uint32 PPCRecompilerImlGen_loadOverwriteFPRRegister(ppcImlGenContext_t* ppcImlGenContext, uint32 mappedName);
|
uint32 PPCRecompilerImlGen_loadOverwriteFPRRegister(ppcImlGenContext_t* ppcImlGenContext, uint32 mappedName);
|
||||||
|
|
||||||
// IML instruction generation
|
// IML instruction generation
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_jump(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, uint32 jumpmarkAddress);
|
void PPCRecompilerImlGen_generateNewInstruction_jump(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, uint32 jumpmarkAddress);
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_jumpSegment(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction);
|
void PPCRecompilerImlGen_generateNewInstruction_jumpSegment(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction);
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_r_s32(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerIndex, sint32 immS32, uint32 copyWidth, bool signExtend, bool bigEndian, uint8 crRegister, uint32 crMode);
|
void PPCRecompilerImlGen_generateNewInstruction_r_s32(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerIndex, sint32 immS32, uint32 copyWidth, bool signExtend, bool bigEndian, uint8 crRegister, uint32 crMode);
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_conditional_r_s32(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, uint32 operation, uint8 registerIndex, sint32 immS32, uint32 crRegisterIndex, uint32 crBitIndex, bool bitMustBeSet);
|
void PPCRecompilerImlGen_generateNewInstruction_conditional_r_s32(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, uint32 operation, uint8 registerIndex, sint32 immS32, uint32 crRegisterIndex, uint32 crBitIndex, bool bitMustBeSet);
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_r_r(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, uint32 operation, uint8 registerResult, uint8 registerA, uint8 crRegister = PPC_REC_INVALID_REGISTER, uint8 crMode = 0);
|
void PPCRecompilerImlGen_generateNewInstruction_r_r(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, uint32 operation, uint8 registerResult, uint8 registerA, uint8 crRegister = PPC_REC_INVALID_REGISTER, uint8 crMode = 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// IML instruction generation (new style, can generate new instructions but also overwrite existing ones)
|
// IML instruction generation (new style, can generate new instructions but also overwrite existing ones)
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_noOp(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction);
|
void PPCRecompilerImlGen_generateNewInstruction_noOp(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction);
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_r(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, sint32 operation, uint8 registerResult, sint32 crRegister = PPC_REC_INVALID_REGISTER);
|
void PPCRecompilerImlGen_generateNewInstruction_fpr_r(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, sint32 operation, uint8 registerResult, sint32 crRegister = PPC_REC_INVALID_REGISTER);
|
||||||
|
|
||||||
// IML generation - FPU
|
// IML generation - FPU
|
||||||
bool PPCRecompilerImlGen_LFS(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode);
|
bool PPCRecompilerImlGen_LFS(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode);
|
||||||
|
@ -113,15 +113,15 @@ bool PPCRecompilerImlGen_PS_CMPU1(ppcImlGenContext_t* ppcImlGenContext, uint32 o
|
||||||
|
|
||||||
// IML general
|
// IML general
|
||||||
|
|
||||||
bool PPCRecompiler_isSuffixInstruction(PPCRecImlInstruction_t* iml);
|
bool PPCRecompiler_isSuffixInstruction(IMLInstruction* iml);
|
||||||
void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext);
|
void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
void PPCRecompilerIml_setLinkBranchNotTaken(PPCRecImlSegment_t* imlSegmentSrc, PPCRecImlSegment_t* imlSegmentDst);
|
void PPCRecompilerIml_setLinkBranchNotTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst);
|
||||||
void PPCRecompilerIml_setLinkBranchTaken(PPCRecImlSegment_t* imlSegmentSrc, PPCRecImlSegment_t* imlSegmentDst);
|
void PPCRecompilerIml_setLinkBranchTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst);
|
||||||
void PPCRecompilerIML_relinkInputSegment(PPCRecImlSegment_t* imlSegmentOrig, PPCRecImlSegment_t* imlSegmentNew);
|
void PPCRecompilerIML_relinkInputSegment(IMLSegment* imlSegmentOrig, IMLSegment* imlSegmentNew);
|
||||||
void PPCRecompilerIML_removeLink(PPCRecImlSegment_t* imlSegmentSrc, PPCRecImlSegment_t* imlSegmentDst);
|
void PPCRecompilerIML_removeLink(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst);
|
||||||
void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenContext);
|
void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
|
|
||||||
PPCRecImlInstruction_t* PPCRecompilerIML_getLastInstruction(PPCRecImlSegment_t* imlSegment);
|
IMLInstruction* PPCRecompilerIML_getLastInstruction(IMLSegment* imlSegment);
|
||||||
|
|
||||||
// IML analyzer
|
// IML analyzer
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -130,9 +130,9 @@ typedef struct
|
||||||
uint32 writtenCRBits;
|
uint32 writtenCRBits;
|
||||||
}PPCRecCRTracking_t;
|
}PPCRecCRTracking_t;
|
||||||
|
|
||||||
bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(PPCRecImlSegment_t* imlSegment);
|
bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(IMLSegment* imlSegment);
|
||||||
bool PPCRecompilerImlAnalyzer_canTypeWriteCR(PPCRecImlInstruction_t* imlInstruction);
|
bool PPCRecompilerImlAnalyzer_canTypeWriteCR(IMLInstruction* imlInstruction);
|
||||||
void PPCRecompilerImlAnalyzer_getCRTracking(PPCRecImlInstruction_t* imlInstruction, PPCRecCRTracking_t* crTracking);
|
void PPCRecompilerImlAnalyzer_getCRTracking(IMLInstruction* imlInstruction, PPCRecCRTracking_t* crTracking);
|
||||||
|
|
||||||
// IML optimizer
|
// IML optimizer
|
||||||
bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenContext);
|
bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
|
@ -153,7 +153,7 @@ void PPCRecompiler_reorderConditionModifyInstructions(ppcImlGenContext_t* ppcIml
|
||||||
|
|
||||||
// debug
|
// debug
|
||||||
|
|
||||||
void PPCRecompiler_dumpIMLSegment(PPCRecImlSegment_t* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo = false);
|
void PPCRecompiler_dumpIMLSegment(IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo = false);
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -185,4 +185,4 @@ typedef struct
|
||||||
};
|
};
|
||||||
}PPCImlOptimizerUsedRegisters_t;
|
}PPCImlOptimizerUsedRegisters_t;
|
||||||
|
|
||||||
void PPCRecompiler_checkRegisterUsage(ppcImlGenContext_t* ppcImlGenContext, const PPCRecImlInstruction_t* imlInstruction, PPCImlOptimizerUsedRegisters_t* registersUsed);
|
void PPCRecompiler_checkRegisterUsage(ppcImlGenContext_t* ppcImlGenContext, const IMLInstruction* imlInstruction, PPCImlOptimizerUsedRegisters_t* registersUsed);
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
/*
|
/*
|
||||||
* Initializes a single segment and returns true if it is a finite loop
|
* Initializes a single segment and returns true if it is a finite loop
|
||||||
*/
|
*/
|
||||||
bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(PPCRecImlSegment_t* imlSegment)
|
bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
bool isTightFiniteLoop = false;
|
bool isTightFiniteLoop = false;
|
||||||
// base criteria, must jump to beginning of same segment
|
// base criteria, must jump to beginning of same segment
|
||||||
if (imlSegment->nextSegmentBranchTaken != imlSegment)
|
if (imlSegment->nextSegmentBranchTaken != imlSegment)
|
||||||
return false;
|
return false;
|
||||||
// loops using BDNZ are assumed to always be finite
|
// loops using BDNZ are assumed to always be finite
|
||||||
for(const PPCRecImlInstruction_t& instIt : imlSegment->imlList)
|
for(const IMLInstruction& instIt : imlSegment->imlList)
|
||||||
{
|
{
|
||||||
if (instIt.type == PPCREC_IML_TYPE_R_S32 && instIt.operation == PPCREC_IML_OP_SUB && instIt.crRegister == 8)
|
if (instIt.type == PPCREC_IML_TYPE_R_S32 && instIt.operation == PPCREC_IML_OP_SUB && instIt.crRegister == 8)
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,7 @@ bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(PPCRecImlSegment_t* imlSegment)
|
||||||
// risky approach, look for ADD/SUB operations and assume that potential overflow means finite (does not include r_r_s32 ADD/SUB)
|
// risky approach, look for ADD/SUB operations and assume that potential overflow means finite (does not include r_r_s32 ADD/SUB)
|
||||||
// this catches most loops with load-update and store-update instructions, but also those with decrementing counters
|
// this catches most loops with load-update and store-update instructions, but also those with decrementing counters
|
||||||
FixedSizeList<sint32, 64, true> list_modifiedRegisters;
|
FixedSizeList<sint32, 64, true> list_modifiedRegisters;
|
||||||
for (const PPCRecImlInstruction_t& instIt : imlSegment->imlList)
|
for (const IMLInstruction& instIt : imlSegment->imlList)
|
||||||
{
|
{
|
||||||
if (instIt.type == PPCREC_IML_TYPE_R_S32 && (instIt.operation == PPCREC_IML_OP_ADD || instIt.operation == PPCREC_IML_OP_SUB) )
|
if (instIt.type == PPCREC_IML_TYPE_R_S32 && (instIt.operation == PPCREC_IML_OP_ADD || instIt.operation == PPCREC_IML_OP_SUB) )
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(PPCRecImlSegment_t* imlSegment)
|
||||||
// remove all registers from the list that are modified by non-ADD/SUB instructions
|
// remove all registers from the list that are modified by non-ADD/SUB instructions
|
||||||
// todo: We should also cover the case where ADD+SUB on the same register cancel the effect out
|
// todo: We should also cover the case where ADD+SUB on the same register cancel the effect out
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
for (const PPCRecImlInstruction_t& instIt : imlSegment->imlList)
|
for (const IMLInstruction& instIt : imlSegment->imlList)
|
||||||
{
|
{
|
||||||
if (instIt.type == PPCREC_IML_TYPE_R_S32 && (instIt.operation == PPCREC_IML_OP_ADD || instIt.operation == PPCREC_IML_OP_SUB))
|
if (instIt.type == PPCREC_IML_TYPE_R_S32 && (instIt.operation == PPCREC_IML_OP_ADD || instIt.operation == PPCREC_IML_OP_SUB))
|
||||||
continue;
|
continue;
|
||||||
|
@ -56,7 +56,7 @@ bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(PPCRecImlSegment_t* imlSegment)
|
||||||
/*
|
/*
|
||||||
* Returns true if the imlInstruction can overwrite CR (depending on value of ->crRegister)
|
* Returns true if the imlInstruction can overwrite CR (depending on value of ->crRegister)
|
||||||
*/
|
*/
|
||||||
bool PPCRecompilerImlAnalyzer_canTypeWriteCR(PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerImlAnalyzer_canTypeWriteCR(IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
if (imlInstruction->type == PPCREC_IML_TYPE_R_R)
|
if (imlInstruction->type == PPCREC_IML_TYPE_R_R)
|
||||||
return true;
|
return true;
|
||||||
|
@ -77,7 +77,7 @@ bool PPCRecompilerImlAnalyzer_canTypeWriteCR(PPCRecImlInstruction_t* imlInstruct
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerImlAnalyzer_getCRTracking(PPCRecImlInstruction_t* imlInstruction, PPCRecCRTracking_t* crTracking)
|
void PPCRecompilerImlAnalyzer_getCRTracking(IMLInstruction* imlInstruction, PPCRecCRTracking_t* crTracking)
|
||||||
{
|
{
|
||||||
crTracking->readCRBits = 0;
|
crTracking->readCRBits = 0;
|
||||||
crTracking->writtenCRBits = 0;
|
crTracking->writtenCRBits = 0;
|
||||||
|
|
|
@ -10,57 +10,57 @@ bool PPCRecompiler_decodePPCInstruction(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
uint32 PPCRecompiler_iterateCurrentInstruction(ppcImlGenContext_t* ppcImlGenContext);
|
uint32 PPCRecompiler_iterateCurrentInstruction(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
uint32 PPCRecompiler_getInstructionByOffset(ppcImlGenContext_t* ppcImlGenContext, uint32 offset);
|
uint32 PPCRecompiler_getInstructionByOffset(ppcImlGenContext_t* ppcImlGenContext, uint32 offset);
|
||||||
|
|
||||||
PPCRecImlInstruction_t* PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext_t* ppcImlGenContext)
|
IMLInstruction* PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
if( ppcImlGenContext->imlListCount+1 > ppcImlGenContext->imlListSize )
|
if( ppcImlGenContext->imlListCount+1 > ppcImlGenContext->imlListSize )
|
||||||
{
|
{
|
||||||
sint32 newSize = ppcImlGenContext->imlListCount*2 + 2;
|
sint32 newSize = ppcImlGenContext->imlListCount*2 + 2;
|
||||||
ppcImlGenContext->imlList = (PPCRecImlInstruction_t*)realloc(ppcImlGenContext->imlList, sizeof(PPCRecImlInstruction_t)*newSize);
|
ppcImlGenContext->imlList = (IMLInstruction*)realloc(ppcImlGenContext->imlList, sizeof(IMLInstruction)*newSize);
|
||||||
ppcImlGenContext->imlListSize = newSize;
|
ppcImlGenContext->imlListSize = newSize;
|
||||||
}
|
}
|
||||||
PPCRecImlInstruction_t* imlInstruction = ppcImlGenContext->imlList+ppcImlGenContext->imlListCount;
|
IMLInstruction* imlInstruction = ppcImlGenContext->imlList+ppcImlGenContext->imlListCount;
|
||||||
memset(imlInstruction, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstruction, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER; // dont update any cr register by default
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER; // dont update any cr register by default
|
||||||
imlInstruction->associatedPPCAddress = ppcImlGenContext->ppcAddressOfCurrentInstruction;
|
imlInstruction->associatedPPCAddress = ppcImlGenContext->ppcAddressOfCurrentInstruction;
|
||||||
ppcImlGenContext->imlListCount++;
|
ppcImlGenContext->imlListCount++;
|
||||||
return imlInstruction;
|
return imlInstruction;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
//void PPCRecompilerImlGen_generateNewInstruction_jumpmark(ppcImlGenContext_t* ppcImlGenContext, uint32 address)
|
||||||
|
//{
|
||||||
|
// // no-op that indicates possible destination of a jump
|
||||||
|
// IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
|
// imlInstruction->type = PPCREC_IML_TYPE_JUMPMARK;
|
||||||
|
// imlInstruction->op_jumpmark.address = address;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext_t* ppcImlGenContext, uint32 macroId, uint32 param, uint32 param2, uint16 paramU16)
|
||||||
|
//{
|
||||||
|
// // no-op that indicates possible destination of a jump
|
||||||
|
// IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
|
// imlInstruction->type = PPCREC_IML_TYPE_MACRO;
|
||||||
|
// imlInstruction->operation = macroId;
|
||||||
|
// imlInstruction->op_macro.param = param;
|
||||||
|
// imlInstruction->op_macro.param2 = param2;
|
||||||
|
// imlInstruction->op_macro.paramU16 = paramU16;
|
||||||
|
//}
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_jumpmark(ppcImlGenContext_t* ppcImlGenContext, uint32 address)
|
///*
|
||||||
{
|
// * Generates a marker for Interpreter -> Recompiler entrypoints
|
||||||
// no-op that indicates possible destination of a jump
|
// * PPC_ENTER iml instructions have no associated PPC address but the instruction itself has one
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
// */
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_JUMPMARK;
|
//void PPCRecompilerImlGen_generateNewInstruction_ppcEnter(ppcImlGenContext_t* ppcImlGenContext, uint32 ppcAddress)
|
||||||
imlInstruction->op_jumpmark.address = address;
|
//{
|
||||||
}
|
// // no-op that indicates possible destination of a jump
|
||||||
|
// IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
|
// imlInstruction->type = PPCREC_IML_TYPE_PPC_ENTER;
|
||||||
|
// imlInstruction->operation = 0;
|
||||||
|
// imlInstruction->op_ppcEnter.ppcAddress = ppcAddress;
|
||||||
|
// imlInstruction->op_ppcEnter.x64Offset = 0;
|
||||||
|
// imlInstruction->associatedPPCAddress = 0;
|
||||||
|
//}
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext_t* ppcImlGenContext, uint32 macroId, uint32 param, uint32 param2, uint16 paramU16)
|
void PPCRecompilerImlGen_generateNewInstruction_r_r(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, uint32 operation, uint8 registerResult, uint8 registerA, uint8 crRegister, uint8 crMode)
|
||||||
{
|
|
||||||
// no-op that indicates possible destination of a jump
|
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_MACRO;
|
|
||||||
imlInstruction->operation = macroId;
|
|
||||||
imlInstruction->op_macro.param = param;
|
|
||||||
imlInstruction->op_macro.param2 = param2;
|
|
||||||
imlInstruction->op_macro.paramU16 = paramU16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generates a marker for Interpreter -> Recompiler entrypoints
|
|
||||||
* PPC_ENTER iml instructions have no associated PPC address but the instruction itself has one
|
|
||||||
*/
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_ppcEnter(ppcImlGenContext_t* ppcImlGenContext, uint32 ppcAddress)
|
|
||||||
{
|
|
||||||
// no-op that indicates possible destination of a jump
|
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_PPC_ENTER;
|
|
||||||
imlInstruction->operation = 0;
|
|
||||||
imlInstruction->op_ppcEnter.ppcAddress = ppcAddress;
|
|
||||||
imlInstruction->op_ppcEnter.x64Offset = 0;
|
|
||||||
imlInstruction->associatedPPCAddress = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_r_r(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, uint32 operation, uint8 registerResult, uint8 registerA, uint8 crRegister, uint8 crMode)
|
|
||||||
{
|
{
|
||||||
// operation with two register operands (e.g. "t0 = t1")
|
// operation with two register operands (e.g. "t0 = t1")
|
||||||
if(imlInstruction == NULL)
|
if(imlInstruction == NULL)
|
||||||
|
@ -76,7 +76,7 @@ void PPCRecompilerImlGen_generateNewInstruction_r_r(ppcImlGenContext_t* ppcImlGe
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_r_r_r(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerResult, uint8 registerA, uint8 registerB, uint8 crRegister=PPC_REC_INVALID_REGISTER, uint8 crMode=0)
|
void PPCRecompilerImlGen_generateNewInstruction_r_r_r(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerResult, uint8 registerA, uint8 registerB, uint8 crRegister=PPC_REC_INVALID_REGISTER, uint8 crMode=0)
|
||||||
{
|
{
|
||||||
// operation with three register operands (e.g. "t0 = t1 + t4")
|
// operation with three register operands (e.g. "t0 = t1 + t4")
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_R_R_R;
|
imlInstruction->type = PPCREC_IML_TYPE_R_R_R;
|
||||||
imlInstruction->operation = operation;
|
imlInstruction->operation = operation;
|
||||||
imlInstruction->crRegister = crRegister;
|
imlInstruction->crRegister = crRegister;
|
||||||
|
@ -89,7 +89,7 @@ void PPCRecompilerImlGen_generateNewInstruction_r_r_r(ppcImlGenContext_t* ppcIml
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_r_r_s32(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerResult, uint8 registerA, sint32 immS32, uint8 crRegister=PPC_REC_INVALID_REGISTER, uint8 crMode=0)
|
void PPCRecompilerImlGen_generateNewInstruction_r_r_s32(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerResult, uint8 registerA, sint32 immS32, uint8 crRegister=PPC_REC_INVALID_REGISTER, uint8 crMode=0)
|
||||||
{
|
{
|
||||||
// operation with two register operands and one signed immediate (e.g. "t0 = t1 + 1234")
|
// operation with two register operands and one signed immediate (e.g. "t0 = t1 + 1234")
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_R_R_S32;
|
imlInstruction->type = PPCREC_IML_TYPE_R_R_S32;
|
||||||
imlInstruction->operation = operation;
|
imlInstruction->operation = operation;
|
||||||
imlInstruction->crRegister = crRegister;
|
imlInstruction->crRegister = crRegister;
|
||||||
|
@ -99,16 +99,14 @@ void PPCRecompilerImlGen_generateNewInstruction_r_r_s32(ppcImlGenContext_t* ppcI
|
||||||
imlInstruction->op_r_r_s32.immS32 = immS32;
|
imlInstruction->op_r_r_s32.immS32 = immS32;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_name_r(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerIndex, uint32 name, uint32 copyWidth, bool signExtend, bool bigEndian)
|
void PPCRecompilerImlGen_generateNewInstruction_name_r(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerIndex, uint32 name)
|
||||||
{
|
{
|
||||||
// Store name (e.g. "'r3' = t0" which translates to MOV [ESP+offset_r3], reg32)
|
// Store name (e.g. "'r3' = t0" which translates to MOV [ESP+offset_r3], reg32)
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_NAME_R;
|
imlInstruction->type = PPCREC_IML_TYPE_NAME_R;
|
||||||
imlInstruction->operation = operation;
|
imlInstruction->operation = operation;
|
||||||
imlInstruction->op_r_name.registerIndex = registerIndex;
|
imlInstruction->op_r_name.registerIndex = registerIndex;
|
||||||
imlInstruction->op_r_name.name = name;
|
imlInstruction->op_r_name.name = name;
|
||||||
imlInstruction->op_r_name.copyWidth = copyWidth;
|
|
||||||
imlInstruction->op_r_name.flags = (signExtend?PPCREC_IML_OP_FLAG_SIGNEXTEND:0)|(bigEndian?PPCREC_IML_OP_FLAG_SWITCHENDIAN:0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_r_s32(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerIndex, sint32 immS32, uint32 copyWidth, bool signExtend, bool bigEndian, uint8 crRegister, uint32 crMode)
|
void PPCRecompilerImlGen_generateNewInstruction_r_s32(ppcImlGenContext_t* ppcImlGenContext, uint32 operation, uint8 registerIndex, sint32 immS32, uint32 copyWidth, bool signExtend, bool bigEndian, uint8 crRegister, uint32 crMode)
|
||||||
|
@ -116,7 +114,7 @@ void PPCRecompilerImlGen_generateNewInstruction_r_s32(ppcImlGenContext_t* ppcIml
|
||||||
// two variations:
|
// two variations:
|
||||||
// operation without store (e.g. "'r3' < 123" which has no effect other than updating a condition flags register)
|
// operation without store (e.g. "'r3' < 123" which has no effect other than updating a condition flags register)
|
||||||
// operation with store (e.g. "'r3' = 123")
|
// operation with store (e.g. "'r3' = 123")
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_R_S32;
|
imlInstruction->type = PPCREC_IML_TYPE_R_S32;
|
||||||
imlInstruction->operation = operation;
|
imlInstruction->operation = operation;
|
||||||
imlInstruction->crRegister = crRegister;
|
imlInstruction->crRegister = crRegister;
|
||||||
|
@ -125,12 +123,12 @@ void PPCRecompilerImlGen_generateNewInstruction_r_s32(ppcImlGenContext_t* ppcIml
|
||||||
imlInstruction->op_r_immS32.immS32 = immS32;
|
imlInstruction->op_r_immS32.immS32 = immS32;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_conditional_r_s32(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, uint32 operation, uint8 registerIndex, sint32 immS32, uint32 crRegisterIndex, uint32 crBitIndex, bool bitMustBeSet)
|
void PPCRecompilerImlGen_generateNewInstruction_conditional_r_s32(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, uint32 operation, uint8 registerIndex, sint32 immS32, uint32 crRegisterIndex, uint32 crBitIndex, bool bitMustBeSet)
|
||||||
{
|
{
|
||||||
if(imlInstruction == NULL)
|
if(imlInstruction == NULL)
|
||||||
imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
else
|
else
|
||||||
memset(imlInstruction, 0, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstruction, 0, sizeof(IMLInstruction));
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_CONDITIONAL_R_S32;
|
imlInstruction->type = PPCREC_IML_TYPE_CONDITIONAL_R_S32;
|
||||||
imlInstruction->operation = operation;
|
imlInstruction->operation = operation;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
|
@ -144,13 +142,13 @@ void PPCRecompilerImlGen_generateNewInstruction_conditional_r_s32(ppcImlGenConte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_jump(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, uint32 jumpmarkAddress)
|
void PPCRecompilerImlGen_generateNewInstruction_jump(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, uint32 jumpmarkAddress)
|
||||||
{
|
{
|
||||||
// jump
|
// jump
|
||||||
if (imlInstruction == NULL)
|
if (imlInstruction == NULL)
|
||||||
imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
else
|
else
|
||||||
memset(imlInstruction, 0, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstruction, 0, sizeof(IMLInstruction));
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_CJUMP;
|
imlInstruction->type = PPCREC_IML_TYPE_CJUMP;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstruction->op_conditionalJump.jumpmarkAddress = jumpmarkAddress;
|
imlInstruction->op_conditionalJump.jumpmarkAddress = jumpmarkAddress;
|
||||||
|
@ -162,7 +160,7 @@ void PPCRecompilerImlGen_generateNewInstruction_jump(ppcImlGenContext_t* ppcImlG
|
||||||
}
|
}
|
||||||
|
|
||||||
// jump based on segment branches
|
// jump based on segment branches
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_jumpSegment(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerImlGen_generateNewInstruction_jumpSegment(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
// jump
|
// jump
|
||||||
if (imlInstruction == NULL)
|
if (imlInstruction == NULL)
|
||||||
|
@ -178,7 +176,7 @@ void PPCRecompilerImlGen_generateNewInstruction_jumpSegment(ppcImlGenContext_t*
|
||||||
imlInstruction->op_conditionalJump.bitMustBeSet = false;
|
imlInstruction->op_conditionalJump.bitMustBeSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_noOp(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerImlGen_generateNewInstruction_noOp(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
if (imlInstruction == NULL)
|
if (imlInstruction == NULL)
|
||||||
imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
|
@ -193,7 +191,7 @@ void PPCRecompilerImlGen_generateNewInstruction_cr(ppcImlGenContext_t* ppcImlGen
|
||||||
// multiple variations:
|
// multiple variations:
|
||||||
// operation involving only one cr bit (like clear crD bit)
|
// operation involving only one cr bit (like clear crD bit)
|
||||||
// operation involving three cr bits (like crD = crA or crB)
|
// operation involving three cr bits (like crD = crA or crB)
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_CR;
|
imlInstruction->type = PPCREC_IML_TYPE_CR;
|
||||||
imlInstruction->operation = operation;
|
imlInstruction->operation = operation;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
|
@ -206,7 +204,7 @@ void PPCRecompilerImlGen_generateNewInstruction_cr(ppcImlGenContext_t* ppcImlGen
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext_t* ppcImlGenContext, uint32 jumpmarkAddress, uint32 jumpCondition, uint32 crRegisterIndex, uint32 crBitIndex, bool bitMustBeSet)
|
void PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext_t* ppcImlGenContext, uint32 jumpmarkAddress, uint32 jumpCondition, uint32 crRegisterIndex, uint32 crBitIndex, bool bitMustBeSet)
|
||||||
{
|
{
|
||||||
// conditional jump
|
// conditional jump
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_CJUMP;
|
imlInstruction->type = PPCREC_IML_TYPE_CJUMP;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstruction->op_conditionalJump.jumpmarkAddress = jumpmarkAddress;
|
imlInstruction->op_conditionalJump.jumpmarkAddress = jumpmarkAddress;
|
||||||
|
@ -219,7 +217,7 @@ void PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_r_memory(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory, sint32 immS32, uint32 copyWidth, bool signExtend, bool switchEndian)
|
void PPCRecompilerImlGen_generateNewInstruction_r_memory(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory, sint32 immS32, uint32 copyWidth, bool signExtend, bool switchEndian)
|
||||||
{
|
{
|
||||||
// load from memory
|
// load from memory
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_LOAD;
|
imlInstruction->type = PPCREC_IML_TYPE_LOAD;
|
||||||
imlInstruction->operation = 0;
|
imlInstruction->operation = 0;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
|
@ -235,7 +233,7 @@ void PPCRecompilerImlGen_generateNewInstruction_r_memory(ppcImlGenContext_t* ppc
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_r_memory_indexed(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory1, uint8 registerMemory2, uint32 copyWidth, bool signExtend, bool switchEndian)
|
void PPCRecompilerImlGen_generateNewInstruction_r_memory_indexed(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory1, uint8 registerMemory2, uint32 copyWidth, bool signExtend, bool switchEndian)
|
||||||
{
|
{
|
||||||
// load from memory
|
// load from memory
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_LOAD_INDEXED;
|
imlInstruction->type = PPCREC_IML_TYPE_LOAD_INDEXED;
|
||||||
imlInstruction->operation = 0;
|
imlInstruction->operation = 0;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
|
@ -251,7 +249,7 @@ void PPCRecompilerImlGen_generateNewInstruction_r_memory_indexed(ppcImlGenContex
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_memory_r(ppcImlGenContext_t* ppcImlGenContext, uint8 registerSource, uint8 registerMemory, sint32 immS32, uint32 copyWidth, bool switchEndian)
|
void PPCRecompilerImlGen_generateNewInstruction_memory_r(ppcImlGenContext_t* ppcImlGenContext, uint8 registerSource, uint8 registerMemory, sint32 immS32, uint32 copyWidth, bool switchEndian)
|
||||||
{
|
{
|
||||||
// load from memory
|
// load from memory
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_STORE;
|
imlInstruction->type = PPCREC_IML_TYPE_STORE;
|
||||||
imlInstruction->operation = 0;
|
imlInstruction->operation = 0;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
|
@ -267,7 +265,7 @@ void PPCRecompilerImlGen_generateNewInstruction_memory_r(ppcImlGenContext_t* ppc
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_memory_r_indexed(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory1, uint8 registerMemory2, uint32 copyWidth, bool signExtend, bool switchEndian)
|
void PPCRecompilerImlGen_generateNewInstruction_memory_r_indexed(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory1, uint8 registerMemory2, uint32 copyWidth, bool signExtend, bool switchEndian)
|
||||||
{
|
{
|
||||||
// load from memory
|
// load from memory
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_STORE_INDEXED;
|
imlInstruction->type = PPCREC_IML_TYPE_STORE_INDEXED;
|
||||||
imlInstruction->operation = 0;
|
imlInstruction->operation = 0;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
|
@ -400,10 +398,7 @@ uint32 PPCRecompilerImlGen_loadOverwriteFPRRegister(ppcImlGenContext_t* ppcImlGe
|
||||||
|
|
||||||
void PPCRecompilerImlGen_TW(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
void PPCRecompilerImlGen_TW(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||||
{
|
{
|
||||||
//#ifdef CEMU_DEBUG_ASSERT
|
PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext)->make_macro(PPCREC_IML_MACRO_LEAVE, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, 0);
|
||||||
// PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, 0);
|
|
||||||
//#endif
|
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_LEAVE, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompilerImlGen_MTSPR(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
bool PPCRecompilerImlGen_MTSPR(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||||
|
@ -465,7 +460,7 @@ bool PPCRecompilerImlGen_MFTB(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
{
|
{
|
||||||
// TBL / TBU
|
// TBL / TBU
|
||||||
uint32 param2 = spr | (rD << 16);
|
uint32 param2 = spr | (rD << 16);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_MFTB, ppcImlGenContext->ppcAddressOfCurrentInstruction, param2, 0);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_MFTB, ppcImlGenContext->ppcAddressOfCurrentInstruction, param2, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -636,8 +631,8 @@ bool PPCRecompilerImlGen_B(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// generate funtion call instructions
|
// generate funtion call instructions
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_BL, ppcImlGenContext->ppcAddressOfCurrentInstruction, jumpAddressDest, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_BL, ppcImlGenContext->ppcAddressOfCurrentInstruction, jumpAddressDest, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_ppcEnter(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4);
|
ppcImlGenContext->emitInst().make_ppcEnter(ppcImlGenContext->ppcAddressOfCurrentInstruction+4);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// is jump destination within recompiled function?
|
// is jump destination within recompiled function?
|
||||||
|
@ -649,7 +644,7 @@ bool PPCRecompilerImlGen_B(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// todo: Inline this jump destination if possible (in many cases it's a bunch of GPR/FPR store instructions + BLR)
|
// todo: Inline this jump destination if possible (in many cases it's a bunch of GPR/FPR store instructions + BLR)
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_B_FAR, ppcImlGenContext->ppcAddressOfCurrentInstruction, jumpAddressDest, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_B_FAR, ppcImlGenContext->ppcAddressOfCurrentInstruction, jumpAddressDest, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -702,10 +697,10 @@ bool PPCRecompilerImlGen_BC(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||||
jumpCondition = PPCREC_JUMP_CONDITION_SUMMARYOVERFLOW;
|
jumpCondition = PPCREC_JUMP_CONDITION_SUMMARYOVERFLOW;
|
||||||
}
|
}
|
||||||
// generate instruction
|
// generate instruction
|
||||||
//PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, 0);
|
//ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, 0);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4, jumpCondition, crRegister, crBit, !conditionMustBeTrue);
|
PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4, jumpCondition, crRegister, crBit, !conditionMustBeTrue);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_BL, ppcImlGenContext->ppcAddressOfCurrentInstruction, jumpAddressDest, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_BL, ppcImlGenContext->ppcAddressOfCurrentInstruction, jumpAddressDest, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_ppcEnter(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4);
|
ppcImlGenContext->emitInst().make_ppcEnter(ppcImlGenContext->ppcAddressOfCurrentInstruction+4);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -766,8 +761,8 @@ bool PPCRecompilerImlGen_BC(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||||
{
|
{
|
||||||
// far jump
|
// far jump
|
||||||
PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction + 4, jumpCondition, crRegister, crBit, !conditionMustBeTrue);
|
PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction + 4, jumpCondition, crRegister, crBit, !conditionMustBeTrue);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_B_FAR, ppcImlGenContext->ppcAddressOfCurrentInstruction, jumpAddressDest, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_B_FAR, ppcImlGenContext->ppcAddressOfCurrentInstruction, jumpAddressDest, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_ppcEnter(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction + 4);
|
ppcImlGenContext->emitInst().make_ppcEnter(ppcImlGenContext->ppcAddressOfCurrentInstruction + 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -803,13 +798,13 @@ bool PPCRecompilerImlGen_BCLR(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
// store LR
|
// store LR
|
||||||
if( saveLR )
|
if( saveLR )
|
||||||
{
|
{
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_BLRL, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_BLRL, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_ppcEnter(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4);
|
ppcImlGenContext->emitInst().make_ppcEnter(ppcImlGenContext->ppcAddressOfCurrentInstruction+4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// branch always, no condition and no decrementer
|
// branch always, no condition and no decrementer
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_BLR, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_BLR, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -845,7 +840,7 @@ bool PPCRecompilerImlGen_BCLR(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
}
|
}
|
||||||
// jump if BCLR condition NOT met (jump to jumpmark of next instruction, essentially skipping current instruction)
|
// jump if BCLR condition NOT met (jump to jumpmark of next instruction, essentially skipping current instruction)
|
||||||
PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4, jumpCondition, crRegister, crBit, invertedConditionMustBeTrue);
|
PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4, jumpCondition, crRegister, crBit, invertedConditionMustBeTrue);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_BLR, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_BLR, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -884,13 +879,13 @@ bool PPCRecompilerImlGen_BCCTR(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||||
{
|
{
|
||||||
uint32 registerLR = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_SPR0+SPR_LR);
|
uint32 registerLR = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_SPR0+SPR_LR);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_r_s32(ppcImlGenContext, PPCREC_IML_OP_ASSIGN, registerLR, (ppcImlGenContext->ppcAddressOfCurrentInstruction+4)&0x7FFFFFFF, 0, false, false, PPC_REC_INVALID_REGISTER, 0);
|
PPCRecompilerImlGen_generateNewInstruction_r_s32(ppcImlGenContext, PPCREC_IML_OP_ASSIGN, registerLR, (ppcImlGenContext->ppcAddressOfCurrentInstruction+4)&0x7FFFFFFF, 0, false, false, PPC_REC_INVALID_REGISTER, 0);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_BCTRL, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_BCTRL, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_ppcEnter(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4);
|
ppcImlGenContext->emitInst().make_ppcEnter(ppcImlGenContext->ppcAddressOfCurrentInstruction+4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// branch always, no condition and no decrementer
|
// branch always, no condition and no decrementer
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_BCTR, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_BCTR, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -926,7 +921,7 @@ bool PPCRecompilerImlGen_BCCTR(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||||
}
|
}
|
||||||
// jump if BCLR condition NOT met (jump to jumpmark of next instruction, essentially skipping current instruction)
|
// jump if BCLR condition NOT met (jump to jumpmark of next instruction, essentially skipping current instruction)
|
||||||
PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4, jumpCondition, crRegister, crBit, invertedConditionMustBeTrue);
|
PPCRecompilerImlGen_generateNewInstruction_conditionalJump(ppcImlGenContext, ppcImlGenContext->ppcAddressOfCurrentInstruction+4, jumpCondition, crRegister, crBit, invertedConditionMustBeTrue);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_BCTR, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_BCTR, ppcImlGenContext->ppcAddressOfCurrentInstruction, 0, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1575,7 +1570,7 @@ void PPCRecompilerImlGen_LWZ(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -1596,7 +1591,7 @@ void PPCRecompilerImlGen_LWZU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -1619,7 +1614,7 @@ void PPCRecompilerImlGen_LHA(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -1640,7 +1635,7 @@ void PPCRecompilerImlGen_LHAU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -1664,7 +1659,7 @@ void PPCRecompilerImlGen_LHZ(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
// note: Darksiders 2 has this instruction form but it is never executed.
|
// note: Darksiders 2 has this instruction form but it is never executed.
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -1685,7 +1680,7 @@ void PPCRecompilerImlGen_LHZU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -1708,7 +1703,7 @@ void PPCRecompilerImlGen_LBZ(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -1729,7 +1724,7 @@ void PPCRecompilerImlGen_LBZU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -1815,7 +1810,7 @@ bool PPCRecompilerImlGen_LHAX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// load memory rA and rB into register
|
// load memory rA and rB into register
|
||||||
|
@ -1837,7 +1832,7 @@ bool PPCRecompilerImlGen_LHAUX(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// load memory rA and rB into register
|
// load memory rA and rB into register
|
||||||
|
@ -1861,7 +1856,7 @@ bool PPCRecompilerImlGen_LHZX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// load memory rA and rB into register
|
// load memory rA and rB into register
|
||||||
|
@ -1883,7 +1878,7 @@ bool PPCRecompilerImlGen_LHZUX(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// load memory rA and rB into register
|
// load memory rA and rB into register
|
||||||
|
@ -1947,7 +1942,7 @@ bool PPCRecompilerImlGen_LBZUX(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||||
if (rA == 0)
|
if (rA == 0)
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// load memory rA and rB into register
|
// load memory rA and rB into register
|
||||||
|
@ -2015,7 +2010,7 @@ void PPCRecompilerImlGen_STW(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
// note: Darksiders 2 has this instruction form but it is never executed.
|
// note: Darksiders 2 has this instruction form but it is never executed.
|
||||||
//PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
//ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -2034,7 +2029,7 @@ void PPCRecompilerImlGen_STWU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// store&update instructions where rD==rA store the register contents without added imm, therefore we need to handle it differently
|
// store&update instructions where rD==rA store the register contents without added imm, therefore we need to handle it differently
|
||||||
|
@ -2060,7 +2055,7 @@ void PPCRecompilerImlGen_STH(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -2079,7 +2074,7 @@ void PPCRecompilerImlGen_STHU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// get memory gpr register
|
// get memory gpr register
|
||||||
|
@ -2104,7 +2099,7 @@ void PPCRecompilerImlGen_STB(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// load memory gpr into register
|
// load memory gpr into register
|
||||||
|
@ -2123,7 +2118,7 @@ void PPCRecompilerImlGen_STBU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||||
if( rA == 0 )
|
if( rA == 0 )
|
||||||
{
|
{
|
||||||
// special form where gpr is ignored and only imm is used
|
// special form where gpr is ignored and only imm is used
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->ppcAddressOfCurrentInstruction, ppcImlGenContext->cyclesSinceLastBranch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// get memory gpr register
|
// get memory gpr register
|
||||||
|
@ -2944,7 +2939,7 @@ bool PPCRecompilerImlGen_CREQV(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||||
bool PPCRecompilerImlGen_HLE(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
bool PPCRecompilerImlGen_HLE(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||||
{
|
{
|
||||||
uint32 hleFuncId = opcode&0xFFFF;
|
uint32 hleFuncId = opcode&0xFFFF;
|
||||||
PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext, PPCREC_IML_MACRO_HLE, ppcImlGenContext->ppcAddressOfCurrentInstruction, hleFuncId, 0);
|
ppcImlGenContext->emitInst().make_macro(PPCREC_IML_MACRO_HLE, ppcImlGenContext->ppcAddressOfCurrentInstruction, hleFuncId, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2975,7 +2970,7 @@ uint32 PPCRecompiler_getPreviousInstruction(ppcImlGenContext_t* ppcImlGenContext
|
||||||
|
|
||||||
char _tempOpcodename[32];
|
char _tempOpcodename[32];
|
||||||
|
|
||||||
const char* PPCRecompiler_getOpcodeDebugName(const PPCRecImlInstruction_t* iml)
|
const char* PPCRecompiler_getOpcodeDebugName(const IMLInstruction* iml)
|
||||||
{
|
{
|
||||||
uint32 op = iml->operation;
|
uint32 op = iml->operation;
|
||||||
if (op == PPCREC_IML_OP_ASSIGN)
|
if (op == PPCREC_IML_OP_ASSIGN)
|
||||||
|
@ -3031,7 +3026,7 @@ void PPCRecDebug_addS32Param(StringBuf& strOutput, sint32 val, bool isLast = fal
|
||||||
strOutput.addFmt("0x{:08x}, ", val);
|
strOutput.addFmt("0x{:08x}, ", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerDebug_printLivenessRangeInfo(StringBuf& currentLineText, PPCRecImlSegment_t* imlSegment, sint32 offset)
|
void PPCRecompilerDebug_printLivenessRangeInfo(StringBuf& currentLineText, IMLSegment* imlSegment, sint32 offset)
|
||||||
{
|
{
|
||||||
// pad to 70 characters
|
// pad to 70 characters
|
||||||
sint32 index = currentLineText.getLen();
|
sint32 index = currentLineText.getLen();
|
||||||
|
@ -3072,7 +3067,7 @@ void PPCRecompilerDebug_printLivenessRangeInfo(StringBuf& currentLineText, PPCRe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompiler_dumpIMLSegment(PPCRecImlSegment_t* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo)
|
void PPCRecompiler_dumpIMLSegment(IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo)
|
||||||
{
|
{
|
||||||
StringBuf strOutput(1024);
|
StringBuf strOutput(1024);
|
||||||
|
|
||||||
|
@ -3102,7 +3097,7 @@ void PPCRecompiler_dumpIMLSegment(PPCRecImlSegment_t* imlSegment, sint32 segment
|
||||||
|
|
||||||
for(sint32 i=0; i<imlSegment->imlList.size(); i++)
|
for(sint32 i=0; i<imlSegment->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
const PPCRecImlInstruction_t& inst = imlSegment->imlList[i];
|
const IMLInstruction& inst = imlSegment->imlList[i];
|
||||||
// don't log NOP instructions unless they have an associated PPC address
|
// don't log NOP instructions unless they have an associated PPC address
|
||||||
if(inst.type == PPCREC_IML_TYPE_NO_OP && inst.associatedPPCAddress == MPTR_NULL)
|
if(inst.type == PPCREC_IML_TYPE_NO_OP && inst.associatedPPCAddress == MPTR_NULL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -3439,7 +3434,7 @@ void PPCRecompiler_dumpIML(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerIml_setSegmentPoint(ppcRecompilerSegmentPoint_t* segmentPoint, PPCRecImlSegment_t* imlSegment, sint32 index)
|
void PPCRecompilerIml_setSegmentPoint(ppcRecompilerSegmentPoint_t* segmentPoint, IMLSegment* imlSegment, sint32 index)
|
||||||
{
|
{
|
||||||
segmentPoint->imlSegment = imlSegment;
|
segmentPoint->imlSegment = imlSegment;
|
||||||
segmentPoint->index = index;
|
segmentPoint->index = index;
|
||||||
|
@ -3464,13 +3459,13 @@ void PPCRecompilerIml_removeSegmentPoint(ppcRecompilerSegmentPoint_t* segmentPoi
|
||||||
* Insert multiple no-op instructions
|
* Insert multiple no-op instructions
|
||||||
* Warning: Can invalidate any previous instruction structs from the same segment
|
* Warning: Can invalidate any previous instruction structs from the same segment
|
||||||
*/
|
*/
|
||||||
void PPCRecompiler_pushBackIMLInstructions(PPCRecImlSegment_t* imlSegment, sint32 index, sint32 shiftBackCount)
|
void PPCRecompiler_pushBackIMLInstructions(IMLSegment* imlSegment, sint32 index, sint32 shiftBackCount)
|
||||||
{
|
{
|
||||||
cemu_assert_debug(index >= 0 && index <= imlSegment->imlList.size());
|
cemu_assert_debug(index >= 0 && index <= imlSegment->imlList.size());
|
||||||
|
|
||||||
imlSegment->imlList.insert(imlSegment->imlList.begin() + index, shiftBackCount, {});
|
imlSegment->imlList.insert(imlSegment->imlList.begin() + index, shiftBackCount, {});
|
||||||
|
|
||||||
memset(imlSegment->imlList.data() + index, 0, sizeof(PPCRecImlInstruction_t) * shiftBackCount);
|
memset(imlSegment->imlList.data() + index, 0, sizeof(IMLInstruction) * shiftBackCount);
|
||||||
|
|
||||||
// fill empty space with NOP instructions
|
// fill empty space with NOP instructions
|
||||||
for (sint32 i = 0; i < shiftBackCount; i++)
|
for (sint32 i = 0; i < shiftBackCount; i++)
|
||||||
|
@ -3495,23 +3490,23 @@ void PPCRecompiler_pushBackIMLInstructions(PPCRecImlSegment_t* imlSegment, sint3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCRecImlInstruction_t* PPCRecompiler_insertInstruction(PPCRecImlSegment_t* imlSegment, sint32 index)
|
IMLInstruction* PPCRecompiler_insertInstruction(IMLSegment* imlSegment, sint32 index)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, index, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, index, 1);
|
||||||
return imlSegment->imlList.data() + index;
|
return imlSegment->imlList.data() + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCRecImlInstruction_t* PPCRecompiler_appendInstruction(PPCRecImlSegment_t* imlSegment)
|
IMLInstruction* PPCRecompiler_appendInstruction(IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
size_t index = imlSegment->imlList.size();
|
size_t index = imlSegment->imlList.size();
|
||||||
imlSegment->imlList.emplace_back();
|
imlSegment->imlList.emplace_back();
|
||||||
memset(imlSegment->imlList.data() + index, 0, sizeof(PPCRecImlInstruction_t));
|
memset(imlSegment->imlList.data() + index, 0, sizeof(IMLInstruction));
|
||||||
return imlSegment->imlList.data() + index;
|
return imlSegment->imlList.data() + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCRecImlSegment_t* PPCRecompilerIml_appendSegment(ppcImlGenContext_t* ppcImlGenContext)
|
IMLSegment* PPCRecompilerIml_appendSegment(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* segment = new PPCRecImlSegment_t();
|
IMLSegment* segment = new IMLSegment();
|
||||||
ppcImlGenContext->segmentList2.emplace_back(segment);
|
ppcImlGenContext->segmentList2.emplace_back(segment);
|
||||||
return segment;
|
return segment;
|
||||||
}
|
}
|
||||||
|
@ -3520,7 +3515,7 @@ void PPCRecompilerIml_insertSegments(ppcImlGenContext_t* ppcImlGenContext, sint3
|
||||||
{
|
{
|
||||||
ppcImlGenContext->segmentList2.insert(ppcImlGenContext->segmentList2.begin() + index, count, nullptr);
|
ppcImlGenContext->segmentList2.insert(ppcImlGenContext->segmentList2.begin() + index, count, nullptr);
|
||||||
for (sint32 i = 0; i < count; i++)
|
for (sint32 i = 0; i < count; i++)
|
||||||
ppcImlGenContext->segmentList2[index + i] = new PPCRecImlSegment_t();
|
ppcImlGenContext->segmentList2[index + i] = new IMLSegment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompiler_freeContext(ppcImlGenContext_t* ppcImlGenContext)
|
void PPCRecompiler_freeContext(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
|
@ -3531,7 +3526,7 @@ void PPCRecompiler_freeContext(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
ppcImlGenContext->imlList = nullptr;
|
ppcImlGenContext->imlList = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PPCRecImlSegment_t* imlSegment : ppcImlGenContext->segmentList2)
|
for (IMLSegment* imlSegment : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
//free(imlSegment->imlList);
|
//free(imlSegment->imlList);
|
||||||
delete imlSegment;
|
delete imlSegment;
|
||||||
|
@ -3551,7 +3546,7 @@ void PPCRecompiler_freeContext(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompiler_isSuffixInstruction(PPCRecImlInstruction_t* iml)
|
bool PPCRecompiler_isSuffixInstruction(IMLInstruction* iml)
|
||||||
{
|
{
|
||||||
if (iml->type == PPCREC_IML_TYPE_MACRO && (iml->operation == PPCREC_IML_MACRO_BLR || iml->operation == PPCREC_IML_MACRO_BCTR) ||
|
if (iml->type == PPCREC_IML_TYPE_MACRO && (iml->operation == PPCREC_IML_MACRO_BLR || iml->operation == PPCREC_IML_MACRO_BCTR) ||
|
||||||
iml->type == PPCREC_IML_TYPE_MACRO && iml->operation == PPCREC_IML_MACRO_BL ||
|
iml->type == PPCREC_IML_TYPE_MACRO && iml->operation == PPCREC_IML_MACRO_BL ||
|
||||||
|
@ -4438,12 +4433,11 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
uint32 addressOfCurrentInstruction = (uint32)((uint8*)ppcImlGenContext.currentInstruction - memory_base);
|
uint32 addressOfCurrentInstruction = (uint32)((uint8*)ppcImlGenContext.currentInstruction - memory_base);
|
||||||
ppcImlGenContext.ppcAddressOfCurrentInstruction = addressOfCurrentInstruction;
|
ppcImlGenContext.ppcAddressOfCurrentInstruction = addressOfCurrentInstruction;
|
||||||
ppcImlGenContext.cyclesSinceLastBranch++;
|
ppcImlGenContext.cyclesSinceLastBranch++;
|
||||||
PPCRecompilerImlGen_generateNewInstruction_jumpmark(&ppcImlGenContext, addressOfCurrentInstruction);
|
ppcImlGenContext.emitInst().make_jumpmark(addressOfCurrentInstruction);
|
||||||
|
|
||||||
if (entryAddresses.find(addressOfCurrentInstruction) != entryAddresses.end())
|
if (entryAddresses.find(addressOfCurrentInstruction) != entryAddresses.end())
|
||||||
{
|
{
|
||||||
// add PPCEnter for addresses that are in entryAddresses
|
// add PPCEnter for addresses that are in entryAddresses
|
||||||
PPCRecompilerImlGen_generateNewInstruction_ppcEnter(&ppcImlGenContext, addressOfCurrentInstruction);
|
ppcImlGenContext.emitInst().make_ppcEnter(addressOfCurrentInstruction);
|
||||||
}
|
}
|
||||||
else if(ppcImlGenContext.currentInstruction != firstCurrentInstruction)
|
else if(ppcImlGenContext.currentInstruction != firstCurrentInstruction)
|
||||||
{
|
{
|
||||||
|
@ -4465,7 +4459,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
canInlineFunction = true;
|
canInlineFunction = true;
|
||||||
}
|
}
|
||||||
if( canInlineFunction == false && (opcodePrevious & PPC_OPC_LK) == false)
|
if( canInlineFunction == false && (opcodePrevious & PPC_OPC_LK) == false)
|
||||||
PPCRecompilerImlGen_generateNewInstruction_ppcEnter(&ppcImlGenContext, addressOfCurrentInstruction);
|
ppcImlGenContext.emitInst().make_ppcEnter(addressOfCurrentInstruction);
|
||||||
}
|
}
|
||||||
if( ((opcodePrevious>>26) == 19) && PPC_getBits(opcodePrevious, 30, 10) == 528 )
|
if( ((opcodePrevious>>26) == 19) && PPC_getBits(opcodePrevious, 30, 10) == 528 )
|
||||||
{
|
{
|
||||||
|
@ -4474,7 +4468,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
if( (BO & 16) && (opcodePrevious&PPC_OPC_LK) == 0 )
|
if( (BO & 16) && (opcodePrevious&PPC_OPC_LK) == 0 )
|
||||||
{
|
{
|
||||||
// after unconditional BCTR instruction
|
// after unconditional BCTR instruction
|
||||||
PPCRecompilerImlGen_generateNewInstruction_ppcEnter(&ppcImlGenContext, addressOfCurrentInstruction);
|
ppcImlGenContext.emitInst().make_ppcEnter(addressOfCurrentInstruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4498,7 +4492,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
}
|
}
|
||||||
// optimize unused jumpmarks away
|
// optimize unused jumpmarks away
|
||||||
// first, flag all jumpmarks as unused
|
// first, flag all jumpmarks as unused
|
||||||
std::map<uint32, PPCRecImlInstruction_t*> map_jumpMarks;
|
std::map<uint32, IMLInstruction*> map_jumpMarks;
|
||||||
for(sint32 i=0; i<ppcImlGenContext.imlListCount; i++)
|
for(sint32 i=0; i<ppcImlGenContext.imlListCount; i++)
|
||||||
{
|
{
|
||||||
if( ppcImlGenContext.imlList[i].type == PPCREC_IML_TYPE_JUMPMARK )
|
if( ppcImlGenContext.imlList[i].type == PPCREC_IML_TYPE_JUMPMARK )
|
||||||
|
@ -4533,7 +4527,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
// move back instruction
|
// move back instruction
|
||||||
if( currentImlIndex < i )
|
if( currentImlIndex < i )
|
||||||
{
|
{
|
||||||
memcpy(ppcImlGenContext.imlList+currentImlIndex, ppcImlGenContext.imlList+i, sizeof(PPCRecImlInstruction_t));
|
memcpy(ppcImlGenContext.imlList+currentImlIndex, ppcImlGenContext.imlList+i, sizeof(IMLInstruction));
|
||||||
}
|
}
|
||||||
currentImlIndex++;
|
currentImlIndex++;
|
||||||
}
|
}
|
||||||
|
@ -4562,7 +4556,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
(ppcImlGenContext.imlList[segmentImlIndex].type == PPCREC_IML_TYPE_MACRO && (ppcImlGenContext.imlList[segmentImlIndex].operation == PPCREC_IML_MACRO_MFTB)) )
|
(ppcImlGenContext.imlList[segmentImlIndex].type == PPCREC_IML_TYPE_MACRO && (ppcImlGenContext.imlList[segmentImlIndex].operation == PPCREC_IML_MACRO_MFTB)) )
|
||||||
{
|
{
|
||||||
// segment ends after current instruction
|
// segment ends after current instruction
|
||||||
PPCRecImlSegment_t* ppcRecSegment = PPCRecompilerIml_appendSegment(&ppcImlGenContext);
|
IMLSegment* ppcRecSegment = PPCRecompilerIml_appendSegment(&ppcImlGenContext);
|
||||||
ppcRecSegment->startOffset = segmentStart;
|
ppcRecSegment->startOffset = segmentStart;
|
||||||
ppcRecSegment->count = segmentImlIndex-segmentStart+1;
|
ppcRecSegment->count = segmentImlIndex-segmentStart+1;
|
||||||
ppcRecSegment->ppcAddress = 0xFFFFFFFF;
|
ppcRecSegment->ppcAddress = 0xFFFFFFFF;
|
||||||
|
@ -4574,7 +4568,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
// segment ends before current instruction
|
// segment ends before current instruction
|
||||||
if( segmentImlIndex > segmentStart )
|
if( segmentImlIndex > segmentStart )
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* ppcRecSegment = PPCRecompilerIml_appendSegment(&ppcImlGenContext);
|
IMLSegment* ppcRecSegment = PPCRecompilerIml_appendSegment(&ppcImlGenContext);
|
||||||
ppcRecSegment->startOffset = segmentStart;
|
ppcRecSegment->startOffset = segmentStart;
|
||||||
ppcRecSegment->count = segmentImlIndex-segmentStart;
|
ppcRecSegment->count = segmentImlIndex-segmentStart;
|
||||||
ppcRecSegment->ppcAddress = 0xFFFFFFFF;
|
ppcRecSegment->ppcAddress = 0xFFFFFFFF;
|
||||||
|
@ -4586,26 +4580,20 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
if( segmentImlIndex != segmentStart )
|
if( segmentImlIndex != segmentStart )
|
||||||
{
|
{
|
||||||
// final segment
|
// final segment
|
||||||
PPCRecImlSegment_t* ppcRecSegment = PPCRecompilerIml_appendSegment(&ppcImlGenContext);
|
IMLSegment* ppcRecSegment = PPCRecompilerIml_appendSegment(&ppcImlGenContext);
|
||||||
ppcRecSegment->startOffset = segmentStart;
|
ppcRecSegment->startOffset = segmentStart;
|
||||||
ppcRecSegment->count = segmentImlIndex-segmentStart;
|
ppcRecSegment->count = segmentImlIndex-segmentStart;
|
||||||
ppcRecSegment->ppcAddress = 0xFFFFFFFF;
|
ppcRecSegment->ppcAddress = 0xFFFFFFFF;
|
||||||
segmentStart = segmentImlIndex;
|
segmentStart = segmentImlIndex;
|
||||||
}
|
}
|
||||||
// move iml instructions into the segments
|
// move iml instructions into the segments
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
uint32 imlStartIndex = segIt->startOffset;
|
uint32 imlStartIndex = segIt->startOffset;
|
||||||
uint32 imlCount = segIt->count;
|
uint32 imlCount = segIt->count;
|
||||||
if( imlCount > 0 )
|
if( imlCount > 0 )
|
||||||
{
|
{
|
||||||
//segIt->imlListSize = imlCount + 4;
|
|
||||||
//segIt->imlList = (PPCRecImlInstruction_t*)malloc(sizeof(PPCRecImlInstruction_t) * segIt->imlListSize);
|
|
||||||
//segIt->imlListCount = imlCount;
|
|
||||||
//memcpy(segIt->imlList, ppcImlGenContext.imlList+imlStartIndex, sizeof(PPCRecImlInstruction_t)*imlCount);
|
|
||||||
cemu_assert_debug(segIt->imlList.empty());
|
cemu_assert_debug(segIt->imlList.empty());
|
||||||
//segIt->imlList.resize(imlCount);
|
|
||||||
//segIt->imlList.insert(segIt->imlList.begin() + imlStartIndex, );
|
|
||||||
segIt->imlList.insert(segIt->imlList.begin(), ppcImlGenContext.imlList + imlStartIndex, ppcImlGenContext.imlList + imlStartIndex + imlCount);
|
segIt->imlList.insert(segIt->imlList.begin(), ppcImlGenContext.imlList + imlStartIndex, ppcImlGenContext.imlList + imlStartIndex + imlCount);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4613,9 +4601,6 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
{
|
{
|
||||||
// empty segments are allowed so we can handle multiple PPC entry addresses pointing to the same code
|
// empty segments are allowed so we can handle multiple PPC entry addresses pointing to the same code
|
||||||
cemu_assert_debug(segIt->imlList.empty());
|
cemu_assert_debug(segIt->imlList.empty());
|
||||||
//segIt->imlList = nullptr;
|
|
||||||
//segIt->imlListSize = 0;
|
|
||||||
//segIt->imlListCount = 0;
|
|
||||||
}
|
}
|
||||||
segIt->startOffset = 9999999;
|
segIt->startOffset = 9999999;
|
||||||
segIt->count = 9999999;
|
segIt->count = 9999999;
|
||||||
|
@ -4625,7 +4610,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
ppcImlGenContext.imlList = nullptr;
|
ppcImlGenContext.imlList = nullptr;
|
||||||
ppcImlGenContext.imlListCount = 999999; // set to high number to force crash in case old code still uses ppcImlGenContext.imlList
|
ppcImlGenContext.imlListCount = 999999; // set to high number to force crash in case old code still uses ppcImlGenContext.imlList
|
||||||
// calculate PPC address of each segment based on iml instructions inside that segment (we need this info to calculate how many cpu cycles each segment takes)
|
// calculate PPC address of each segment based on iml instructions inside that segment (we need this info to calculate how many cpu cycles each segment takes)
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
uint32 segmentPPCAddrMin = 0xFFFFFFFF;
|
uint32 segmentPPCAddrMin = 0xFFFFFFFF;
|
||||||
uint32 segmentPPCAddrMax = 0x00000000;
|
uint32 segmentPPCAddrMax = 0x00000000;
|
||||||
|
@ -4652,7 +4637,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
// certain instructions can change the segment state
|
// certain instructions can change the segment state
|
||||||
// ppcEnter instruction marks a segment as enterable (BL, BCTR, etc. instructions can enter at this location from outside)
|
// ppcEnter instruction marks a segment as enterable (BL, BCTR, etc. instructions can enter at this location from outside)
|
||||||
// jumpmarks mark the segment as a jump destination (within the same function)
|
// jumpmarks mark the segment as a jump destination (within the same function)
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
while (segIt->imlList.size() > 0)
|
while (segIt->imlList.size() > 0)
|
||||||
{
|
{
|
||||||
|
@ -4692,15 +4677,15 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
PPCRecompilerIML_linkSegments(&ppcImlGenContext);
|
PPCRecompilerIML_linkSegments(&ppcImlGenContext);
|
||||||
|
|
||||||
// optimization pass - replace segments with conditional MOVs if possible
|
// optimization pass - replace segments with conditional MOVs if possible
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
if (segIt->nextSegmentBranchNotTaken == nullptr || segIt->nextSegmentBranchTaken == nullptr)
|
if (segIt->nextSegmentBranchNotTaken == nullptr || segIt->nextSegmentBranchTaken == nullptr)
|
||||||
continue; // not a branching segment
|
continue; // not a branching segment
|
||||||
PPCRecImlInstruction_t* lastInstruction = PPCRecompilerIML_getLastInstruction(segIt);
|
IMLInstruction* lastInstruction = PPCRecompilerIML_getLastInstruction(segIt);
|
||||||
if (lastInstruction->type != PPCREC_IML_TYPE_CJUMP || lastInstruction->op_conditionalJump.crRegisterIndex != 0)
|
if (lastInstruction->type != PPCREC_IML_TYPE_CJUMP || lastInstruction->op_conditionalJump.crRegisterIndex != 0)
|
||||||
continue;
|
continue;
|
||||||
PPCRecImlSegment_t* conditionalSegment = segIt->nextSegmentBranchNotTaken;
|
IMLSegment* conditionalSegment = segIt->nextSegmentBranchNotTaken;
|
||||||
PPCRecImlSegment_t* finalSegment = segIt->nextSegmentBranchTaken;
|
IMLSegment* finalSegment = segIt->nextSegmentBranchTaken;
|
||||||
if (segIt->nextSegmentBranchTaken != segIt->nextSegmentBranchNotTaken->nextSegmentBranchNotTaken)
|
if (segIt->nextSegmentBranchTaken != segIt->nextSegmentBranchNotTaken->nextSegmentBranchNotTaken)
|
||||||
continue;
|
continue;
|
||||||
if (segIt->nextSegmentBranchNotTaken->imlList.size() > 4)
|
if (segIt->nextSegmentBranchNotTaken->imlList.size() > 4)
|
||||||
|
@ -4713,7 +4698,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
bool canReduceSegment = true;
|
bool canReduceSegment = true;
|
||||||
for (sint32 f = 0; f < conditionalSegment->imlList.size(); f++)
|
for (sint32 f = 0; f < conditionalSegment->imlList.size(); f++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = conditionalSegment->imlList.data() + f;
|
IMLInstruction* imlInstruction = conditionalSegment->imlList.data() + f;
|
||||||
if( imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
if( imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
||||||
continue;
|
continue;
|
||||||
// todo: Register to register copy
|
// todo: Register to register copy
|
||||||
|
@ -4734,7 +4719,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
// append conditional moves based on branch condition
|
// append conditional moves based on branch condition
|
||||||
for (sint32 f = 0; f < conditionalSegment->imlList.size(); f++)
|
for (sint32 f = 0; f < conditionalSegment->imlList.size(); f++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = conditionalSegment->imlList.data() + f;
|
IMLInstruction* imlInstruction = conditionalSegment->imlList.data() + f;
|
||||||
if (imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
if (imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
||||||
PPCRecompilerImlGen_generateNewInstruction_conditional_r_s32(&ppcImlGenContext, PPCRecompiler_appendInstruction(segIt), PPCREC_IML_OP_ASSIGN, imlInstruction->op_r_immS32.registerIndex, imlInstruction->op_r_immS32.immS32, branchCond_crRegisterIndex, branchCond_crBitIndex, !branchCond_bitMustBeSet);
|
PPCRecompilerImlGen_generateNewInstruction_conditional_r_s32(&ppcImlGenContext, PPCRecompiler_appendInstruction(segIt), PPCREC_IML_OP_ASSIGN, imlInstruction->op_r_immS32.registerIndex, imlInstruction->op_r_immS32.immS32, branchCond_crRegisterIndex, branchCond_crBitIndex, !branchCond_bitMustBeSet);
|
||||||
else
|
else
|
||||||
|
@ -4756,13 +4741,13 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
PPCRecompilerIML_removeLink(segIt, finalSegment);
|
PPCRecompilerIML_removeLink(segIt, finalSegment);
|
||||||
if (finalSegment->nextSegmentBranchNotTaken)
|
if (finalSegment->nextSegmentBranchNotTaken)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* tempSegment = finalSegment->nextSegmentBranchNotTaken;
|
IMLSegment* tempSegment = finalSegment->nextSegmentBranchNotTaken;
|
||||||
PPCRecompilerIML_removeLink(finalSegment, tempSegment);
|
PPCRecompilerIML_removeLink(finalSegment, tempSegment);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(segIt, tempSegment);
|
PPCRecompilerIml_setLinkBranchNotTaken(segIt, tempSegment);
|
||||||
}
|
}
|
||||||
if (finalSegment->nextSegmentBranchTaken)
|
if (finalSegment->nextSegmentBranchTaken)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* tempSegment = finalSegment->nextSegmentBranchTaken;
|
IMLSegment* tempSegment = finalSegment->nextSegmentBranchTaken;
|
||||||
PPCRecompilerIML_removeLink(finalSegment, tempSegment);
|
PPCRecompilerIML_removeLink(finalSegment, tempSegment);
|
||||||
PPCRecompilerIml_setLinkBranchTaken(segIt, tempSegment);
|
PPCRecompilerIml_setLinkBranchTaken(segIt, tempSegment);
|
||||||
}
|
}
|
||||||
|
@ -4770,7 +4755,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
cemu_assert_debug(segIt != finalSegment);
|
cemu_assert_debug(segIt != finalSegment);
|
||||||
for (sint32 f = 0; f < finalSegment->imlList.size(); f++)
|
for (sint32 f = 0; f < finalSegment->imlList.size(); f++)
|
||||||
{
|
{
|
||||||
memcpy(PPCRecompiler_appendInstruction(segIt), finalSegment->imlList.data() + f, sizeof(PPCRecImlInstruction_t));
|
memcpy(PPCRecompiler_appendInstruction(segIt), finalSegment->imlList.data() + f, sizeof(IMLInstruction));
|
||||||
}
|
}
|
||||||
finalSegment->imlList.clear();
|
finalSegment->imlList.clear();
|
||||||
|
|
||||||
|
@ -4781,7 +4766,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert cycle counter instruction in every segment that has a cycle count greater zero
|
// insert cycle counter instruction in every segment that has a cycle count greater zero
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
if( segIt->ppcAddrMin == 0 )
|
if( segIt->ppcAddrMin == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
@ -4817,7 +4802,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
for(size_t s=0; s<ppcImlGenContext.segmentList2.size(); s++)
|
for(size_t s=0; s<ppcImlGenContext.segmentList2.size(); s++)
|
||||||
{
|
{
|
||||||
// todo: This currently uses segment->ppcAddrMin which isn't really reliable. (We already had a problem where function inlining would generate falsified segment ranges by omitting the branch instruction). Find a better solution (use jumpmark/enterable offsets?)
|
// todo: This currently uses segment->ppcAddrMin which isn't really reliable. (We already had a problem where function inlining would generate falsified segment ranges by omitting the branch instruction). Find a better solution (use jumpmark/enterable offsets?)
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext.segmentList2[s];
|
IMLSegment* imlSegment = ppcImlGenContext.segmentList2[s];
|
||||||
if( imlSegment->imlList.empty() )
|
if( imlSegment->imlList.empty() )
|
||||||
continue;
|
continue;
|
||||||
if (imlSegment->imlList[imlSegment->imlList.size() - 1].type != PPCREC_IML_TYPE_CJUMP || imlSegment->imlList[imlSegment->imlList.size() - 1].op_conditionalJump.jumpmarkAddress > imlSegment->ppcAddrMin)
|
if (imlSegment->imlList[imlSegment->imlList.size() - 1].type != PPCREC_IML_TYPE_CJUMP || imlSegment->imlList[imlSegment->imlList.size() - 1].op_conditionalJump.jumpmarkAddress > imlSegment->ppcAddrMin)
|
||||||
|
@ -4839,12 +4824,12 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
|
|
||||||
PPCRecompilerIml_insertSegments(&ppcImlGenContext, s, 2);
|
PPCRecompilerIml_insertSegments(&ppcImlGenContext, s, 2);
|
||||||
imlSegment = NULL;
|
imlSegment = NULL;
|
||||||
PPCRecImlSegment_t* imlSegmentP0 = ppcImlGenContext.segmentList2[s+0];
|
IMLSegment* imlSegmentP0 = ppcImlGenContext.segmentList2[s+0];
|
||||||
PPCRecImlSegment_t* imlSegmentP1 = ppcImlGenContext.segmentList2[s+1];
|
IMLSegment* imlSegmentP1 = ppcImlGenContext.segmentList2[s+1];
|
||||||
PPCRecImlSegment_t* imlSegmentP2 = ppcImlGenContext.segmentList2[s+2];
|
IMLSegment* imlSegmentP2 = ppcImlGenContext.segmentList2[s+2];
|
||||||
// create entry point segment
|
// create entry point segment
|
||||||
PPCRecompilerIml_insertSegments(&ppcImlGenContext, ppcImlGenContext.segmentList2.size(), 1);
|
PPCRecompilerIml_insertSegments(&ppcImlGenContext, ppcImlGenContext.segmentList2.size(), 1);
|
||||||
PPCRecImlSegment_t* imlSegmentPEntry = ppcImlGenContext.segmentList2[ppcImlGenContext.segmentList2.size()-1];
|
IMLSegment* imlSegmentPEntry = ppcImlGenContext.segmentList2[ppcImlGenContext.segmentList2.size()-1];
|
||||||
// relink segments
|
// relink segments
|
||||||
PPCRecompilerIML_relinkInputSegment(imlSegmentP2, imlSegmentP0);
|
PPCRecompilerIML_relinkInputSegment(imlSegmentP2, imlSegmentP0);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegmentP0, imlSegmentP1);
|
PPCRecompilerIml_setLinkBranchNotTaken(imlSegmentP0, imlSegmentP1);
|
||||||
|
@ -4920,7 +4905,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert name store instructions at the end of each segment but before branch instructions
|
// insert name store instructions at the end of each segment but before branch instructions
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
if(segIt->imlList.size() == 0 )
|
if(segIt->imlList.size() == 0 )
|
||||||
continue; // ignore empty segments
|
continue; // ignore empty segments
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_memory(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory, sint32 immS32, uint32 mode, bool switchEndian, uint8 registerGQR = PPC_REC_INVALID_REGISTER)
|
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_memory(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory, sint32 immS32, uint32 mode, bool switchEndian, uint8 registerGQR = PPC_REC_INVALID_REGISTER)
|
||||||
{
|
{
|
||||||
// load from memory
|
// load from memory
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_FPR_LOAD;
|
imlInstruction->type = PPCREC_IML_TYPE_FPR_LOAD;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstruction->operation = 0;
|
imlInstruction->operation = 0;
|
||||||
|
@ -21,7 +21,7 @@ void PPCRecompilerImlGen_generateNewInstruction_fpr_r_memory(ppcImlGenContext_t*
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_memory_indexed(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory1, uint8 registerMemory2, uint32 mode, bool switchEndian, uint8 registerGQR = PPC_REC_INVALID_REGISTER)
|
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_memory_indexed(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory1, uint8 registerMemory2, uint32 mode, bool switchEndian, uint8 registerGQR = PPC_REC_INVALID_REGISTER)
|
||||||
{
|
{
|
||||||
// load from memory
|
// load from memory
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_FPR_LOAD_INDEXED;
|
imlInstruction->type = PPCREC_IML_TYPE_FPR_LOAD_INDEXED;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstruction->operation = 0;
|
imlInstruction->operation = 0;
|
||||||
|
@ -37,7 +37,7 @@ void PPCRecompilerImlGen_generateNewInstruction_fpr_r_memory_indexed(ppcImlGenCo
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_memory_r(ppcImlGenContext_t* ppcImlGenContext, uint8 registerSource, uint8 registerMemory, sint32 immS32, uint32 mode, bool switchEndian, uint8 registerGQR = PPC_REC_INVALID_REGISTER)
|
void PPCRecompilerImlGen_generateNewInstruction_fpr_memory_r(ppcImlGenContext_t* ppcImlGenContext, uint8 registerSource, uint8 registerMemory, sint32 immS32, uint32 mode, bool switchEndian, uint8 registerGQR = PPC_REC_INVALID_REGISTER)
|
||||||
{
|
{
|
||||||
// store to memory
|
// store to memory
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_FPR_STORE;
|
imlInstruction->type = PPCREC_IML_TYPE_FPR_STORE;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstruction->operation = 0;
|
imlInstruction->operation = 0;
|
||||||
|
@ -52,7 +52,7 @@ void PPCRecompilerImlGen_generateNewInstruction_fpr_memory_r(ppcImlGenContext_t*
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_memory_r_indexed(ppcImlGenContext_t* ppcImlGenContext, uint8 registerSource, uint8 registerMemory1, uint8 registerMemory2, sint32 immS32, uint32 mode, bool switchEndian, uint8 registerGQR = 0)
|
void PPCRecompilerImlGen_generateNewInstruction_fpr_memory_r_indexed(ppcImlGenContext_t* ppcImlGenContext, uint8 registerSource, uint8 registerMemory1, uint8 registerMemory2, sint32 immS32, uint32 mode, bool switchEndian, uint8 registerGQR = 0)
|
||||||
{
|
{
|
||||||
// store to memory
|
// store to memory
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_FPR_STORE_INDEXED;
|
imlInstruction->type = PPCREC_IML_TYPE_FPR_STORE_INDEXED;
|
||||||
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstruction->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstruction->operation = 0;
|
imlInstruction->operation = 0;
|
||||||
|
@ -68,7 +68,7 @@ void PPCRecompilerImlGen_generateNewInstruction_fpr_memory_r_indexed(ppcImlGenCo
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_r(ppcImlGenContext_t* ppcImlGenContext, sint32 operation, uint8 registerResult, uint8 registerOperand, sint32 crRegister=PPC_REC_INVALID_REGISTER)
|
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_r(ppcImlGenContext_t* ppcImlGenContext, sint32 operation, uint8 registerResult, uint8 registerOperand, sint32 crRegister=PPC_REC_INVALID_REGISTER)
|
||||||
{
|
{
|
||||||
// fpr OP fpr
|
// fpr OP fpr
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_FPR_R_R;
|
imlInstruction->type = PPCREC_IML_TYPE_FPR_R_R;
|
||||||
imlInstruction->operation = operation;
|
imlInstruction->operation = operation;
|
||||||
imlInstruction->op_fpr_r_r.registerResult = registerResult;
|
imlInstruction->op_fpr_r_r.registerResult = registerResult;
|
||||||
|
@ -80,7 +80,7 @@ void PPCRecompilerImlGen_generateNewInstruction_fpr_r_r(ppcImlGenContext_t* ppcI
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_r_r(ppcImlGenContext_t* ppcImlGenContext, sint32 operation, uint8 registerResult, uint8 registerOperand1, uint8 registerOperand2, sint32 crRegister=PPC_REC_INVALID_REGISTER)
|
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_r_r(ppcImlGenContext_t* ppcImlGenContext, sint32 operation, uint8 registerResult, uint8 registerOperand1, uint8 registerOperand2, sint32 crRegister=PPC_REC_INVALID_REGISTER)
|
||||||
{
|
{
|
||||||
// fpr = OP (fpr,fpr)
|
// fpr = OP (fpr,fpr)
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_FPR_R_R_R;
|
imlInstruction->type = PPCREC_IML_TYPE_FPR_R_R_R;
|
||||||
imlInstruction->operation = operation;
|
imlInstruction->operation = operation;
|
||||||
imlInstruction->op_fpr_r_r_r.registerResult = registerResult;
|
imlInstruction->op_fpr_r_r_r.registerResult = registerResult;
|
||||||
|
@ -93,7 +93,7 @@ void PPCRecompilerImlGen_generateNewInstruction_fpr_r_r_r(ppcImlGenContext_t* pp
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_r_r_r(ppcImlGenContext_t* ppcImlGenContext, sint32 operation, uint8 registerResult, uint8 registerOperandA, uint8 registerOperandB, uint8 registerOperandC, sint32 crRegister=PPC_REC_INVALID_REGISTER)
|
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_r_r_r(ppcImlGenContext_t* ppcImlGenContext, sint32 operation, uint8 registerResult, uint8 registerOperandA, uint8 registerOperandB, uint8 registerOperandC, sint32 crRegister=PPC_REC_INVALID_REGISTER)
|
||||||
{
|
{
|
||||||
// fpr = OP (fpr,fpr,fpr)
|
// fpr = OP (fpr,fpr,fpr)
|
||||||
PPCRecImlInstruction_t* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext);
|
||||||
imlInstruction->type = PPCREC_IML_TYPE_FPR_R_R_R_R;
|
imlInstruction->type = PPCREC_IML_TYPE_FPR_R_R_R_R;
|
||||||
imlInstruction->operation = operation;
|
imlInstruction->operation = operation;
|
||||||
imlInstruction->op_fpr_r_r_r_r.registerResult = registerResult;
|
imlInstruction->op_fpr_r_r_r_r.registerResult = registerResult;
|
||||||
|
@ -104,7 +104,7 @@ void PPCRecompilerImlGen_generateNewInstruction_fpr_r_r_r_r(ppcImlGenContext_t*
|
||||||
imlInstruction->op_fpr_r_r_r_r.flags = 0;
|
imlInstruction->op_fpr_r_r_r_r.flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_r(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, sint32 operation, uint8 registerResult, sint32 crRegister)
|
void PPCRecompilerImlGen_generateNewInstruction_fpr_r(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, sint32 operation, uint8 registerResult, sint32 crRegister)
|
||||||
{
|
{
|
||||||
// OP (fpr)
|
// OP (fpr)
|
||||||
if(imlInstruction == NULL)
|
if(imlInstruction == NULL)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "PPCRecompilerIml.h"
|
#include "PPCRecompilerIml.h"
|
||||||
#include "PPCRecompilerX64.h"
|
#include "PPCRecompilerX64.h"
|
||||||
|
|
||||||
void PPCRecompiler_checkRegisterUsage(ppcImlGenContext_t* ppcImlGenContext, const PPCRecImlInstruction_t* imlInstruction, PPCImlOptimizerUsedRegisters_t* registersUsed)
|
void PPCRecompiler_checkRegisterUsage(ppcImlGenContext_t* ppcImlGenContext, const IMLInstruction* imlInstruction, PPCImlOptimizerUsedRegisters_t* registersUsed)
|
||||||
{
|
{
|
||||||
registersUsed->readNamedReg1 = -1;
|
registersUsed->readNamedReg1 = -1;
|
||||||
registersUsed->readNamedReg2 = -1;
|
registersUsed->readNamedReg2 = -1;
|
||||||
|
@ -433,7 +433,7 @@ sint32 replaceRegisterMultiple(sint32 reg, sint32 match[4], sint32 replaced[4])
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, sint32 gprRegisterSearched[4], sint32 gprRegisterReplaced[4])
|
void PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, sint32 gprRegisterSearched[4], sint32 gprRegisterReplaced[4])
|
||||||
{
|
{
|
||||||
if (imlInstruction->type == PPCREC_IML_TYPE_R_NAME)
|
if (imlInstruction->type == PPCREC_IML_TYPE_R_NAME)
|
||||||
{
|
{
|
||||||
|
@ -608,7 +608,7 @@ void PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompiler_replaceFPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, sint32 fprRegisterSearched[4], sint32 fprRegisterReplaced[4])
|
void PPCRecompiler_replaceFPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, sint32 fprRegisterSearched[4], sint32 fprRegisterReplaced[4])
|
||||||
{
|
{
|
||||||
if (imlInstruction->type == PPCREC_IML_TYPE_R_NAME)
|
if (imlInstruction->type == PPCREC_IML_TYPE_R_NAME)
|
||||||
{
|
{
|
||||||
|
@ -726,7 +726,7 @@ void PPCRecompiler_replaceFPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompiler_replaceFPRRegisterUsage(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, sint32 fprRegisterSearched, sint32 fprRegisterReplaced)
|
void PPCRecompiler_replaceFPRRegisterUsage(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, sint32 fprRegisterSearched, sint32 fprRegisterReplaced)
|
||||||
{
|
{
|
||||||
if( imlInstruction->type == PPCREC_IML_TYPE_R_NAME )
|
if( imlInstruction->type == PPCREC_IML_TYPE_R_NAME )
|
||||||
{
|
{
|
||||||
|
@ -891,7 +891,7 @@ sint32 PPCRecompiler_getNextRegisterToReplace(PPCImlOptimizerUsedRegisters_t* re
|
||||||
return gprToReplace;
|
return gprToReplace;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompiler_findAvailableRegisterDepr(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 imlIndexStart, replacedRegisterTracker_t* replacedRegisterTracker, sint32* registerIndex, sint32* registerName, bool* isUsed)
|
bool PPCRecompiler_findAvailableRegisterDepr(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 imlIndexStart, replacedRegisterTracker_t* replacedRegisterTracker, sint32* registerIndex, sint32* registerName, bool* isUsed)
|
||||||
{
|
{
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &imlSegment->imlList[imlIndexStart], ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &imlSegment->imlList[imlIndexStart], ®istersUsed);
|
||||||
|
@ -942,11 +942,11 @@ bool PPCRecompiler_findAvailableRegisterDepr(ppcImlGenContext_t* ppcImlGenContex
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompiler_hasSuffixInstruction(PPCRecImlSegment_t* imlSegment)
|
bool PPCRecompiler_hasSuffixInstruction(IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
if (imlSegment->imlList.empty())
|
if (imlSegment->imlList.empty())
|
||||||
return false;
|
return false;
|
||||||
const PPCRecImlInstruction_t& imlInstruction = imlSegment->imlList.back();
|
const IMLInstruction& imlInstruction = imlSegment->imlList.back();
|
||||||
if( imlInstruction.type == PPCREC_IML_TYPE_MACRO && (imlInstruction.operation == PPCREC_IML_MACRO_BLR || imlInstruction.operation == PPCREC_IML_MACRO_BCTR) ||
|
if( imlInstruction.type == PPCREC_IML_TYPE_MACRO && (imlInstruction.operation == PPCREC_IML_MACRO_BLR || imlInstruction.operation == PPCREC_IML_MACRO_BCTR) ||
|
||||||
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_BL ||
|
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_BL ||
|
||||||
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_B_FAR ||
|
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_B_FAR ||
|
||||||
|
@ -962,35 +962,31 @@ bool PPCRecompiler_hasSuffixInstruction(PPCRecImlSegment_t* imlSegment)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompiler_storeReplacedRegister(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, replacedRegisterTracker_t* replacedRegisterTracker, sint32 registerTrackerIndex, sint32* imlIndex)
|
void PPCRecompiler_storeReplacedRegister(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, replacedRegisterTracker_t* replacedRegisterTracker, sint32 registerTrackerIndex, sint32* imlIndex)
|
||||||
{
|
{
|
||||||
// store register
|
// store register
|
||||||
sint32 imlIndexEdit = *imlIndex;
|
sint32 imlIndexEdit = *imlIndex;
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
||||||
// name_unusedRegister = unusedRegister
|
// name_unusedRegister = unusedRegister
|
||||||
PPCRecImlInstruction_t& imlInstructionItr = imlSegment->imlList[imlIndexEdit + 0];
|
IMLInstruction& imlInstructionItr = imlSegment->imlList[imlIndexEdit + 0];
|
||||||
memset(&imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(&imlInstructionItr, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionItr.type = PPCREC_IML_TYPE_NAME_R;
|
imlInstructionItr.type = PPCREC_IML_TYPE_NAME_R;
|
||||||
imlInstructionItr.crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstructionItr.crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstructionItr.operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr.operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr.op_r_name.registerIndex = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].index;
|
imlInstructionItr.op_r_name.registerIndex = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].index;
|
||||||
imlInstructionItr.op_r_name.name = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].registerNewName;
|
imlInstructionItr.op_r_name.name = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].registerNewName;
|
||||||
imlInstructionItr.op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr.op_r_name.flags = 0;
|
|
||||||
imlIndexEdit++;
|
imlIndexEdit++;
|
||||||
// load new register if required
|
// load new register if required
|
||||||
if( replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].nameMustBeMaintained )
|
if( replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].nameMustBeMaintained )
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
||||||
PPCRecImlInstruction_t& imlInstructionItr = imlSegment->imlList[imlIndexEdit];
|
IMLInstruction& imlInstructionItr = imlSegment->imlList[imlIndexEdit];
|
||||||
memset(&imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(&imlInstructionItr, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionItr.type = PPCREC_IML_TYPE_R_NAME;
|
imlInstructionItr.type = PPCREC_IML_TYPE_R_NAME;
|
||||||
imlInstructionItr.crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstructionItr.crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstructionItr.operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr.operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr.op_r_name.registerIndex = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].index;
|
imlInstructionItr.op_r_name.registerIndex = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].index;
|
||||||
imlInstructionItr.op_r_name.name = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].registerPreviousName;//ppcImlGenContext->mappedRegister[replacedRegisterTracker.replacedRegisterEntry[i].index];
|
imlInstructionItr.op_r_name.name = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].registerPreviousName;//ppcImlGenContext->mappedRegister[replacedRegisterTracker.replacedRegisterEntry[i].index];
|
||||||
imlInstructionItr.op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr.op_r_name.flags = 0;
|
|
||||||
imlIndexEdit += 1;
|
imlIndexEdit += 1;
|
||||||
}
|
}
|
||||||
// move last entry to current one
|
// move last entry to current one
|
||||||
|
@ -1006,12 +1002,12 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
||||||
// inefficient algorithm for optimizing away excess registers
|
// inefficient algorithm for optimizing away excess registers
|
||||||
// we simply load, use and store excess registers into other unused registers when we need to
|
// we simply load, use and store excess registers into other unused registers when we need to
|
||||||
// first we remove all name load and store instructions that involve out-of-bounds registers
|
// first we remove all name load and store instructions that involve out-of-bounds registers
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
size_t imlIndex = 0;
|
size_t imlIndex = 0;
|
||||||
while( imlIndex < segIt->imlList.size() )
|
while( imlIndex < segIt->imlList.size() )
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t& imlInstructionItr = segIt->imlList[imlIndex];
|
IMLInstruction& imlInstructionItr = segIt->imlList[imlIndex];
|
||||||
if( imlInstructionItr.type == PPCREC_IML_TYPE_FPR_R_NAME || imlInstructionItr.type == PPCREC_IML_TYPE_FPR_NAME_R )
|
if( imlInstructionItr.type == PPCREC_IML_TYPE_FPR_R_NAME || imlInstructionItr.type == PPCREC_IML_TYPE_FPR_NAME_R )
|
||||||
{
|
{
|
||||||
if( imlInstructionItr.op_r_name.registerIndex >= PPC_X64_FPR_USABLE_REGISTERS )
|
if( imlInstructionItr.op_r_name.registerIndex >= PPC_X64_FPR_USABLE_REGISTERS )
|
||||||
|
@ -1025,7 +1021,7 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// replace registers
|
// replace registers
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
size_t imlIndex = 0;
|
size_t imlIndex = 0;
|
||||||
while( imlIndex < segIt->imlList.size() )
|
while( imlIndex < segIt->imlList.size() )
|
||||||
|
@ -1085,47 +1081,39 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
||||||
// add load/store before current instruction
|
// add load/store before current instruction
|
||||||
PPCRecompiler_pushBackIMLInstructions(segIt, imlIndex, 2);
|
PPCRecompiler_pushBackIMLInstructions(segIt, imlIndex, 2);
|
||||||
// name_unusedRegister = unusedRegister
|
// name_unusedRegister = unusedRegister
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = segIt->imlList.data() + (imlIndex + 0);
|
IMLInstruction* imlInstructionItr = segIt->imlList.data() + (imlIndex + 0);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(IMLInstruction));
|
||||||
if( replacedRegisterIsUsed )
|
if( replacedRegisterIsUsed )
|
||||||
{
|
{
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = unusedRegisterIndex;
|
imlInstructionItr->op_r_name.registerIndex = unusedRegisterIndex;
|
||||||
imlInstructionItr->op_r_name.name = ppcImlGenContext->mappedFPRRegister[unusedRegisterIndex];
|
imlInstructionItr->op_r_name.name = ppcImlGenContext->mappedFPRRegister[unusedRegisterIndex];
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_NO_OP;
|
imlInstructionItr->type = PPCREC_IML_TYPE_NO_OP;
|
||||||
imlInstructionItr = segIt->imlList.data() + (imlIndex + 1);
|
imlInstructionItr = segIt->imlList.data() + (imlIndex + 1);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = unusedRegisterIndex;
|
imlInstructionItr->op_r_name.registerIndex = unusedRegisterIndex;
|
||||||
imlInstructionItr->op_r_name.name = ppcImlGenContext->mappedFPRRegister[fprToReplace];
|
imlInstructionItr->op_r_name.name = ppcImlGenContext->mappedFPRRegister[fprToReplace];
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
|
||||||
// name_gprToReplace = unusedRegister
|
// name_gprToReplace = unusedRegister
|
||||||
imlInstructionItr = segIt->imlList.data() + (imlIndex + 3);
|
imlInstructionItr = segIt->imlList.data() + (imlIndex + 3);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = unusedRegisterIndex;
|
imlInstructionItr->op_r_name.registerIndex = unusedRegisterIndex;
|
||||||
imlInstructionItr->op_r_name.name = ppcImlGenContext->mappedFPRRegister[fprToReplace];
|
imlInstructionItr->op_r_name.name = ppcImlGenContext->mappedFPRRegister[fprToReplace];
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
|
||||||
// unusedRegister = name_unusedRegister
|
// unusedRegister = name_unusedRegister
|
||||||
imlInstructionItr = segIt->imlList.data() + (imlIndex + 4);
|
imlInstructionItr = segIt->imlList.data() + (imlIndex + 4);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(IMLInstruction));
|
||||||
if( replacedRegisterIsUsed )
|
if( replacedRegisterIsUsed )
|
||||||
{
|
{
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = unusedRegisterIndex;
|
imlInstructionItr->op_r_name.registerIndex = unusedRegisterIndex;
|
||||||
imlInstructionItr->op_r_name.name = ppcImlGenContext->mappedFPRRegister[unusedRegisterIndex];
|
imlInstructionItr->op_r_name.name = ppcImlGenContext->mappedFPRRegister[unusedRegisterIndex];
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_NO_OP;
|
imlInstructionItr->type = PPCREC_IML_TYPE_NO_OP;
|
||||||
|
@ -1208,13 +1196,13 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
||||||
ppcRecManageRegisters_t rCtx = { 0 };
|
ppcRecManageRegisters_t rCtx = { 0 };
|
||||||
for (sint32 i = 0; i < 64; i++)
|
for (sint32 i = 0; i < 64; i++)
|
||||||
rCtx.ppcRegToMapping[i] = -1;
|
rCtx.ppcRegToMapping[i] = -1;
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[segmentIndex];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[segmentIndex];
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
sint32 currentUseIndex = 0;
|
sint32 currentUseIndex = 0;
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
while (idx < imlSegment->imlList.size())
|
while (idx < imlSegment->imlList.size())
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t& idxInst = imlSegment->imlList[idx];
|
IMLInstruction& idxInst = imlSegment->imlList[idx];
|
||||||
if ( PPCRecompiler_isSuffixInstruction(&idxInst) )
|
if ( PPCRecompiler_isSuffixInstruction(&idxInst) )
|
||||||
break;
|
break;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &idxInst, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &idxInst, ®istersUsed);
|
||||||
|
@ -1264,14 +1252,12 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
||||||
unloadLockedMask |= (1<<(unloadRegMapping- rCtx.currentMapping));
|
unloadLockedMask |= (1<<(unloadRegMapping- rCtx.currentMapping));
|
||||||
// create unload instruction
|
// create unload instruction
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
||||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
IMLInstruction* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
||||||
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionTemp, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||||
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionTemp->op_r_name.registerIndex = (uint8)(unloadRegMapping - rCtx.currentMapping);
|
imlInstructionTemp->op_r_name.registerIndex = (uint8)(unloadRegMapping - rCtx.currentMapping);
|
||||||
imlInstructionTemp->op_r_name.name = ppcImlGenContext->mappedFPRRegister[unloadRegMapping->virtualReg];
|
imlInstructionTemp->op_r_name.name = ppcImlGenContext->mappedFPRRegister[unloadRegMapping->virtualReg];
|
||||||
imlInstructionTemp->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionTemp->op_r_name.flags = 0;
|
|
||||||
idx++;
|
idx++;
|
||||||
// update mapping
|
// update mapping
|
||||||
unloadRegMapping->isActive = false;
|
unloadRegMapping->isActive = false;
|
||||||
|
@ -1282,14 +1268,12 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
||||||
}
|
}
|
||||||
// create load instruction
|
// create load instruction
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
||||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
IMLInstruction* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
||||||
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionTemp, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
||||||
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionTemp->op_r_name.registerIndex = (uint8)(regMapping-rCtx.currentMapping);
|
imlInstructionTemp->op_r_name.registerIndex = (uint8)(regMapping-rCtx.currentMapping);
|
||||||
imlInstructionTemp->op_r_name.name = ppcImlGenContext->mappedFPRRegister[virtualFpr];
|
imlInstructionTemp->op_r_name.name = ppcImlGenContext->mappedFPRRegister[virtualFpr];
|
||||||
imlInstructionTemp->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionTemp->op_r_name.flags = 0;
|
|
||||||
idx++;
|
idx++;
|
||||||
// update mapping
|
// update mapping
|
||||||
regMapping->virtualReg = virtualFpr;
|
regMapping->virtualReg = virtualFpr;
|
||||||
|
@ -1344,14 +1328,12 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
||||||
{
|
{
|
||||||
if (rCtx.currentMapping[i].isActive == false)
|
if (rCtx.currentMapping[i].isActive == false)
|
||||||
continue;
|
continue;
|
||||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
IMLInstruction* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
||||||
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionTemp, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||||
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionTemp->op_r_name.registerIndex = i;
|
imlInstructionTemp->op_r_name.registerIndex = i;
|
||||||
imlInstructionTemp->op_r_name.name = ppcImlGenContext->mappedFPRRegister[rCtx.currentMapping[i].virtualReg];
|
imlInstructionTemp->op_r_name.name = ppcImlGenContext->mappedFPRRegister[rCtx.currentMapping[i].virtualReg];
|
||||||
imlInstructionTemp->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionTemp->op_r_name.flags = 0;
|
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1372,12 +1354,12 @@ bool PPCRecompiler_manageFPRRegisters(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
/*
|
/*
|
||||||
* Returns true if the loaded value is guaranteed to be overwritten
|
* Returns true if the loaded value is guaranteed to be overwritten
|
||||||
*/
|
*/
|
||||||
bool PPCRecompiler_trackRedundantNameLoadInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
bool PPCRecompiler_trackRedundantNameLoadInstruction(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 startIndex, IMLInstruction* nameStoreInstruction, sint32 scanDepth)
|
||||||
{
|
{
|
||||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||||
for(size_t i=startIndex; i<imlSegment->imlList.size(); i++)
|
for(size_t i=startIndex; i<imlSegment->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
IMLInstruction* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
//nameStoreInstruction->op_r_name.registerIndex
|
//nameStoreInstruction->op_r_name.registerIndex
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||||
|
@ -1393,12 +1375,12 @@ bool PPCRecompiler_trackRedundantNameLoadInstruction(ppcImlGenContext_t* ppcImlG
|
||||||
/*
|
/*
|
||||||
* Returns true if the loaded value is guaranteed to be overwritten
|
* Returns true if the loaded value is guaranteed to be overwritten
|
||||||
*/
|
*/
|
||||||
bool PPCRecompiler_trackRedundantFPRNameLoadInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
bool PPCRecompiler_trackRedundantFPRNameLoadInstruction(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 startIndex, IMLInstruction* nameStoreInstruction, sint32 scanDepth)
|
||||||
{
|
{
|
||||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||||
for(size_t i=startIndex; i<imlSegment->imlList.size(); i++)
|
for(size_t i=startIndex; i<imlSegment->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
IMLInstruction* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||||
if( registersUsed.readFPR1 == registerIndex || registersUsed.readFPR2 == registerIndex || registersUsed.readFPR3 == registerIndex || registersUsed.readFPR4 == registerIndex)
|
if( registersUsed.readFPR1 == registerIndex || registersUsed.readFPR2 == registerIndex || registersUsed.readFPR3 == registerIndex || registersUsed.readFPR4 == registerIndex)
|
||||||
|
@ -1413,12 +1395,12 @@ bool PPCRecompiler_trackRedundantFPRNameLoadInstruction(ppcImlGenContext_t* ppcI
|
||||||
/*
|
/*
|
||||||
* Returns true if the loaded name is never changed
|
* Returns true if the loaded name is never changed
|
||||||
*/
|
*/
|
||||||
bool PPCRecompiler_trackRedundantNameStoreInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
bool PPCRecompiler_trackRedundantNameStoreInstruction(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 startIndex, IMLInstruction* nameStoreInstruction, sint32 scanDepth)
|
||||||
{
|
{
|
||||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||||
for(sint32 i=startIndex; i>=0; i--)
|
for(sint32 i=startIndex; i>=0; i--)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
IMLInstruction* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||||
if( registersUsed.writtenNamedReg1 == registerIndex )
|
if( registersUsed.writtenNamedReg1 == registerIndex )
|
||||||
|
@ -1436,12 +1418,12 @@ sint32 debugCallCounter1 = 0;
|
||||||
/*
|
/*
|
||||||
* Returns true if the name is overwritten in the current or any following segments
|
* Returns true if the name is overwritten in the current or any following segments
|
||||||
*/
|
*/
|
||||||
bool PPCRecompiler_trackOverwrittenNameStoreInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
bool PPCRecompiler_trackOverwrittenNameStoreInstruction(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 startIndex, IMLInstruction* nameStoreInstruction, sint32 scanDepth)
|
||||||
{
|
{
|
||||||
uint32 name = nameStoreInstruction->op_r_name.name;
|
uint32 name = nameStoreInstruction->op_r_name.name;
|
||||||
for(size_t i=startIndex; i<imlSegment->imlList.size(); i++)
|
for(size_t i=startIndex; i<imlSegment->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
const PPCRecImlInstruction_t& imlInstruction = imlSegment->imlList[i];
|
const IMLInstruction& imlInstruction = imlSegment->imlList[i];
|
||||||
if(imlInstruction.type == PPCREC_IML_TYPE_R_NAME )
|
if(imlInstruction.type == PPCREC_IML_TYPE_R_NAME )
|
||||||
{
|
{
|
||||||
// name is loaded before being written
|
// name is loaded before being written
|
||||||
|
@ -1472,12 +1454,12 @@ bool PPCRecompiler_trackOverwrittenNameStoreInstruction(ppcImlGenContext_t* ppcI
|
||||||
/*
|
/*
|
||||||
* Returns true if the loaded FPR name is never changed
|
* Returns true if the loaded FPR name is never changed
|
||||||
*/
|
*/
|
||||||
bool PPCRecompiler_trackRedundantFPRNameStoreInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
bool PPCRecompiler_trackRedundantFPRNameStoreInstruction(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 startIndex, IMLInstruction* nameStoreInstruction, sint32 scanDepth)
|
||||||
{
|
{
|
||||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||||
for(sint32 i=startIndex; i>=0; i--)
|
for(sint32 i=startIndex; i>=0; i--)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
IMLInstruction* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||||
if( registersUsed.writtenFPR1 == registerIndex )
|
if( registersUsed.writtenFPR1 == registerIndex )
|
||||||
|
@ -1491,7 +1473,7 @@ bool PPCRecompiler_trackRedundantFPRNameStoreInstruction(ppcImlGenContext_t* ppc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 _PPCRecompiler_getCROverwriteMask(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, uint32 currentOverwriteMask, uint32 currentReadMask, uint32 scanDepth)
|
uint32 _PPCRecompiler_getCROverwriteMask(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, uint32 currentOverwriteMask, uint32 currentReadMask, uint32 scanDepth)
|
||||||
{
|
{
|
||||||
// is any bit overwritten but not read?
|
// is any bit overwritten but not read?
|
||||||
uint32 overwriteMask = imlSegment->crBitsWritten&~imlSegment->crBitsInput;
|
uint32 overwriteMask = imlSegment->crBitsWritten&~imlSegment->crBitsInput;
|
||||||
|
@ -1527,7 +1509,7 @@ uint32 _PPCRecompiler_getCROverwriteMask(ppcImlGenContext_t* ppcImlGenContext, P
|
||||||
* Returns a mask of all CR bits that are overwritten (written but not read) in the segment and all it's following segments
|
* Returns a mask of all CR bits that are overwritten (written but not read) in the segment and all it's following segments
|
||||||
* If the write state of a CR bit cannot be determined, it is returned as 0 (not overwritten)
|
* If the write state of a CR bit cannot be determined, it is returned as 0 (not overwritten)
|
||||||
*/
|
*/
|
||||||
uint32 PPCRecompiler_getCROverwriteMask(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment)
|
uint32 PPCRecompiler_getCROverwriteMask(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
if (imlSegment->nextSegmentIsUncertain)
|
if (imlSegment->nextSegmentIsUncertain)
|
||||||
{
|
{
|
||||||
|
@ -1553,9 +1535,9 @@ uint32 PPCRecompiler_getCROverwriteMask(ppcImlGenContext_t* ppcImlGenContext, PP
|
||||||
|
|
||||||
void PPCRecompiler_removeRedundantCRUpdates(ppcImlGenContext_t* ppcImlGenContext)
|
void PPCRecompiler_removeRedundantCRUpdates(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
for(PPCRecImlInstruction_t& instIt : segIt->imlList)
|
for(IMLInstruction& instIt : segIt->imlList)
|
||||||
{
|
{
|
||||||
if (instIt.type == PPCREC_IML_TYPE_CJUMP)
|
if (instIt.type == PPCREC_IML_TYPE_CJUMP)
|
||||||
{
|
{
|
||||||
|
@ -1615,9 +1597,9 @@ void PPCRecompiler_removeRedundantCRUpdates(ppcImlGenContext_t* ppcImlGenContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// flag instructions that write to CR where we can ignore individual CR bits
|
// flag instructions that write to CR where we can ignore individual CR bits
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
for (PPCRecImlInstruction_t& instIt : segIt->imlList)
|
for (IMLInstruction& instIt : segIt->imlList)
|
||||||
{
|
{
|
||||||
if( PPCRecompilerImlAnalyzer_canTypeWriteCR(&instIt) && instIt.crRegister >= 0 && instIt.crRegister <= 7 )
|
if( PPCRecompilerImlAnalyzer_canTypeWriteCR(&instIt) && instIt.crRegister >= 0 && instIt.crRegister <= 7 )
|
||||||
{
|
{
|
||||||
|
@ -1630,12 +1612,12 @@ void PPCRecompiler_removeRedundantCRUpdates(ppcImlGenContext_t* ppcImlGenContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompiler_checkIfGPRIsModifiedInRange(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, sint32 endIndex, sint32 vreg)
|
bool PPCRecompiler_checkIfGPRIsModifiedInRange(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 startIndex, sint32 endIndex, sint32 vreg)
|
||||||
{
|
{
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
for (sint32 i = startIndex; i <= endIndex; i++)
|
for (sint32 i = startIndex; i <= endIndex; i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
IMLInstruction* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||||
if (registersUsed.writtenNamedReg1 == vreg)
|
if (registersUsed.writtenNamedReg1 == vreg)
|
||||||
return true;
|
return true;
|
||||||
|
@ -1643,11 +1625,11 @@ bool PPCRecompiler_checkIfGPRIsModifiedInRange(ppcImlGenContext_t* ppcImlGenCont
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* startSegment, sint32 startIndex, sint32 name)
|
sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* startSegment, sint32 startIndex, sint32 name)
|
||||||
{
|
{
|
||||||
// current segment
|
// current segment
|
||||||
sint32 currentIndex = startIndex;
|
sint32 currentIndex = startIndex;
|
||||||
PPCRecImlSegment_t* currentSegment = startSegment;
|
IMLSegment* currentSegment = startSegment;
|
||||||
sint32 segmentIterateCount = 0;
|
sint32 segmentIterateCount = 0;
|
||||||
sint32 foundRegister = -1;
|
sint32 foundRegister = -1;
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -1709,9 +1691,9 @@ sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcIml
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 imlIndexLoad, sint32 fprIndex)
|
void PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 imlIndexLoad, sint32 fprIndex)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstructionLoad = imlSegment->imlList.data() + imlIndexLoad;
|
IMLInstruction* imlInstructionLoad = imlSegment->imlList.data() + imlIndexLoad;
|
||||||
if (imlInstructionLoad->op_storeLoad.flags2.notExpanded)
|
if (imlInstructionLoad->op_storeLoad.flags2.notExpanded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1721,7 +1703,7 @@ void PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext_t* ppcI
|
||||||
sint32 lastStore = -1;
|
sint32 lastStore = -1;
|
||||||
for (sint32 i = imlIndexLoad + 1; i < scanRangeEnd; i++)
|
for (sint32 i = imlIndexLoad + 1; i < scanRangeEnd; i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
IMLInstruction* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
if (PPCRecompiler_isSuffixInstruction(imlInstruction))
|
if (PPCRecompiler_isSuffixInstruction(imlInstruction))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -1739,7 +1721,7 @@ void PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext_t* ppcI
|
||||||
imlInstructionLoad->op_storeLoad.flags2.notExpanded = true;
|
imlInstructionLoad->op_storeLoad.flags2.notExpanded = true;
|
||||||
}
|
}
|
||||||
// also set the flag for the store instruction
|
// also set the flag for the store instruction
|
||||||
PPCRecImlInstruction_t* imlInstructionStore = imlInstruction;
|
IMLInstruction* imlInstructionStore = imlInstruction;
|
||||||
imlInstructionStore->op_storeLoad.flags2.notExpanded = true;
|
imlInstructionStore->op_storeLoad.flags2.notExpanded = true;
|
||||||
|
|
||||||
foundMatch = true;
|
foundMatch = true;
|
||||||
|
@ -1766,7 +1748,7 @@ void PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext_t* ppcI
|
||||||
if (foundMatch)
|
if (foundMatch)
|
||||||
{
|
{
|
||||||
// insert expand instruction after store
|
// insert expand instruction after store
|
||||||
PPCRecImlInstruction_t* newExpand = PPCRecompiler_insertInstruction(imlSegment, lastStore);
|
IMLInstruction* newExpand = PPCRecompiler_insertInstruction(imlSegment, lastStore);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_fpr_r(ppcImlGenContext, newExpand, PPCREC_IML_OP_FPR_EXPAND_BOTTOM32_TO_BOTTOM64_AND_TOP64, fprIndex);
|
PPCRecompilerImlGen_generateNewInstruction_fpr_r(ppcImlGenContext, newExpand, PPCREC_IML_OP_FPR_EXPAND_BOTTOM32_TO_BOTTOM64_AND_TOP64, fprIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1784,11 +1766,11 @@ void PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext_t* ppcI
|
||||||
*/
|
*/
|
||||||
void PPCRecompiler_optimizeDirectFloatCopies(ppcImlGenContext_t* ppcImlGenContext)
|
void PPCRecompiler_optimizeDirectFloatCopies(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
for (sint32 i = 0; i < segIt->imlList.size(); i++)
|
for (sint32 i = 0; i < segIt->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList.data() + i;
|
IMLInstruction* imlInstruction = segIt->imlList.data() + i;
|
||||||
if (imlInstruction->type == PPCREC_IML_TYPE_FPR_LOAD && imlInstruction->op_storeLoad.mode == PPCREC_FPR_LD_MODE_SINGLE_INTO_PS0_PS1)
|
if (imlInstruction->type == PPCREC_IML_TYPE_FPR_LOAD && imlInstruction->op_storeLoad.mode == PPCREC_FPR_LD_MODE_SINGLE_INTO_PS0_PS1)
|
||||||
{
|
{
|
||||||
PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext, segIt, i, imlInstruction->op_storeLoad.registerData);
|
PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext, segIt, i, imlInstruction->op_storeLoad.registerData);
|
||||||
|
@ -1801,9 +1783,9 @@ void PPCRecompiler_optimizeDirectFloatCopies(ppcImlGenContext_t* ppcImlGenContex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 imlIndexLoad, sint32 gprIndex)
|
void PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 imlIndexLoad, sint32 gprIndex)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstructionLoad = imlSegment->imlList.data() + imlIndexLoad;
|
IMLInstruction* imlInstructionLoad = imlSegment->imlList.data() + imlIndexLoad;
|
||||||
if ( imlInstructionLoad->op_storeLoad.flags2.swapEndian == false )
|
if ( imlInstructionLoad->op_storeLoad.flags2.swapEndian == false )
|
||||||
return;
|
return;
|
||||||
bool foundMatch = false;
|
bool foundMatch = false;
|
||||||
|
@ -1812,7 +1794,7 @@ void PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext_t* pp
|
||||||
sint32 i = imlIndexLoad + 1;
|
sint32 i = imlIndexLoad + 1;
|
||||||
for (; i < scanRangeEnd; i++)
|
for (; i < scanRangeEnd; i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
IMLInstruction* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
if (PPCRecompiler_isSuffixInstruction(imlInstruction))
|
if (PPCRecompiler_isSuffixInstruction(imlInstruction))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -1824,7 +1806,7 @@ void PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext_t* pp
|
||||||
break;
|
break;
|
||||||
if (imlInstruction->op_storeLoad.registerData == gprIndex)
|
if (imlInstruction->op_storeLoad.registerData == gprIndex)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstructionStore = imlInstruction;
|
IMLInstruction* imlInstructionStore = imlInstruction;
|
||||||
if (foundMatch == false)
|
if (foundMatch == false)
|
||||||
{
|
{
|
||||||
// switch the endian swap flag for the load instruction
|
// switch the endian swap flag for the load instruction
|
||||||
|
@ -1851,7 +1833,7 @@ void PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext_t* pp
|
||||||
if (foundMatch)
|
if (foundMatch)
|
||||||
{
|
{
|
||||||
// insert expand instruction
|
// insert expand instruction
|
||||||
PPCRecImlInstruction_t* newExpand = PPCRecompiler_insertInstruction(imlSegment, i);
|
IMLInstruction* newExpand = PPCRecompiler_insertInstruction(imlSegment, i);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_r_r(ppcImlGenContext, newExpand, PPCREC_IML_OP_ENDIAN_SWAP, gprIndex, gprIndex);
|
PPCRecompilerImlGen_generateNewInstruction_r_r(ppcImlGenContext, newExpand, PPCREC_IML_OP_ENDIAN_SWAP, gprIndex, gprIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1868,11 +1850,11 @@ void PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext_t* pp
|
||||||
*/
|
*/
|
||||||
void PPCRecompiler_optimizeDirectIntegerCopies(ppcImlGenContext_t* ppcImlGenContext)
|
void PPCRecompiler_optimizeDirectIntegerCopies(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
for (sint32 i = 0; i < segIt->imlList.size(); i++)
|
for (sint32 i = 0; i < segIt->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList.data() + i;
|
IMLInstruction* imlInstruction = segIt->imlList.data() + i;
|
||||||
if (imlInstruction->type == PPCREC_IML_TYPE_LOAD && imlInstruction->op_storeLoad.copyWidth == 32 && imlInstruction->op_storeLoad.flags2.swapEndian )
|
if (imlInstruction->type == PPCREC_IML_TYPE_LOAD && imlInstruction->op_storeLoad.copyWidth == 32 && imlInstruction->op_storeLoad.flags2.swapEndian )
|
||||||
{
|
{
|
||||||
PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext, segIt, i, imlInstruction->op_storeLoad.registerData);
|
PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext, segIt, i, imlInstruction->op_storeLoad.registerData);
|
||||||
|
@ -1915,9 +1897,9 @@ bool PPCRecompiler_isUGQRValueKnown(ppcImlGenContext_t* ppcImlGenContext, sint32
|
||||||
*/
|
*/
|
||||||
void PPCRecompiler_optimizePSQLoadAndStore(ppcImlGenContext_t* ppcImlGenContext)
|
void PPCRecompiler_optimizePSQLoadAndStore(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
for(PPCRecImlInstruction_t& instIt : segIt->imlList)
|
for(IMLInstruction& instIt : segIt->imlList)
|
||||||
{
|
{
|
||||||
if (instIt.type == PPCREC_IML_TYPE_FPR_LOAD || instIt.type == PPCREC_IML_TYPE_FPR_LOAD_INDEXED)
|
if (instIt.type == PPCREC_IML_TYPE_FPR_LOAD || instIt.type == PPCREC_IML_TYPE_FPR_LOAD_INDEXED)
|
||||||
{
|
{
|
||||||
|
@ -2031,9 +2013,9 @@ bool PPCRecompilerAnalyzer_checkForGPROverwrite(PPCImlOptimizerUsedRegisters_t*
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
void _reorderConditionModifyInstructions(IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* lastInstruction = PPCRecompilerIML_getLastInstruction(imlSegment);
|
IMLInstruction* lastInstruction = PPCRecompilerIML_getLastInstruction(imlSegment);
|
||||||
// last instruction a conditional branch?
|
// last instruction a conditional branch?
|
||||||
if (lastInstruction == nullptr || lastInstruction->type != PPCREC_IML_TYPE_CJUMP)
|
if (lastInstruction == nullptr || lastInstruction->type != PPCREC_IML_TYPE_CJUMP)
|
||||||
return;
|
return;
|
||||||
|
@ -2049,7 +2031,7 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
||||||
sint32 unsafeInstructionIndex = -1;
|
sint32 unsafeInstructionIndex = -1;
|
||||||
for (sint32 i = imlSegment->imlList.size() - 2; i >= 0; i--)
|
for (sint32 i = imlSegment->imlList.size() - 2; i >= 0; i--)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
IMLInstruction* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
PPCRecompilerImlAnalyzer_getCRTracking(imlInstruction, &crTracking);
|
PPCRecompilerImlAnalyzer_getCRTracking(imlInstruction, &crTracking);
|
||||||
if (crTracking.readCRBits != 0)
|
if (crTracking.readCRBits != 0)
|
||||||
return; // dont handle complex cases for now
|
return; // dont handle complex cases for now
|
||||||
|
@ -2127,8 +2109,8 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
||||||
if ((unsafeInstructionIndex + 1) <= crSetterInstructionIndex)
|
if ((unsafeInstructionIndex + 1) <= crSetterInstructionIndex)
|
||||||
assert_dbg();
|
assert_dbg();
|
||||||
#endif
|
#endif
|
||||||
PPCRecImlInstruction_t* newCRSetterInstruction = PPCRecompiler_insertInstruction(imlSegment, unsafeInstructionIndex+1);
|
IMLInstruction* newCRSetterInstruction = PPCRecompiler_insertInstruction(imlSegment, unsafeInstructionIndex+1);
|
||||||
memcpy(newCRSetterInstruction, imlSegment->imlList.data() + crSetterInstructionIndex, sizeof(PPCRecImlInstruction_t));
|
memcpy(newCRSetterInstruction, imlSegment->imlList.data() + crSetterInstructionIndex, sizeof(IMLInstruction));
|
||||||
PPCRecompilerImlGen_generateNewInstruction_noOp(nullptr, imlSegment->imlList.data() + crSetterInstructionIndex);
|
PPCRecompilerImlGen_generateNewInstruction_noOp(nullptr, imlSegment->imlList.data() + crSetterInstructionIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2139,7 +2121,7 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
||||||
void PPCRecompiler_reorderConditionModifyInstructions(ppcImlGenContext_t* ppcImlGenContext)
|
void PPCRecompiler_reorderConditionModifyInstructions(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
// check if this segment has a conditional branch
|
// check if this segment has a conditional branch
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
_reorderConditionModifyInstructions(segIt);
|
_reorderConditionModifyInstructions(segIt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ raLivenessRange_t* PPCRecRA_createRangeBase(ppcImlGenContext_t* ppcImlGenContext
|
||||||
return livenessRange;
|
return livenessRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
raLivenessSubrange_t* PPCRecRA_createSubrange(ppcImlGenContext_t* ppcImlGenContext, raLivenessRange_t* range, PPCRecImlSegment_t* imlSegment, sint32 startIndex, sint32 endIndex)
|
raLivenessSubrange_t* PPCRecRA_createSubrange(ppcImlGenContext_t* ppcImlGenContext, raLivenessRange_t* range, IMLSegment* imlSegment, sint32 startIndex, sint32 endIndex)
|
||||||
{
|
{
|
||||||
raLivenessSubrange_t* livenessSubrange = memPool_livenessSubrange.acquireObj();
|
raLivenessSubrange_t* livenessSubrange = memPool_livenessSubrange.acquireObj();
|
||||||
livenessSubrange->list_locations.resize(0);
|
livenessSubrange->list_locations.resize(0);
|
||||||
|
@ -95,7 +95,7 @@ raLivenessSubrange_t* PPCRecRA_createSubrange(ppcImlGenContext_t* ppcImlGenConte
|
||||||
|
|
||||||
void _unlinkSubrange(raLivenessSubrange_t* subrange)
|
void _unlinkSubrange(raLivenessSubrange_t* subrange)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = subrange->imlSegment;
|
IMLSegment* imlSegment = subrange->imlSegment;
|
||||||
PPCRecRARange_removeLink_perVirtualGPR(&imlSegment->raInfo.linkedList_perVirtualGPR[subrange->range->virtualRegister], subrange);
|
PPCRecRARange_removeLink_perVirtualGPR(&imlSegment->raInfo.linkedList_perVirtualGPR[subrange->range->virtualRegister], subrange);
|
||||||
PPCRecRARange_removeLink_allSubrangesGPR(&imlSegment->raInfo.linkedList_allSubranges, subrange);
|
PPCRecRARange_removeLink_allSubrangesGPR(&imlSegment->raInfo.linkedList_allSubranges, subrange);
|
||||||
}
|
}
|
||||||
|
@ -306,7 +306,7 @@ void PPCRecRA_updateOrAddSubrangeLocation(raLivenessSubrange_t* subrange, sint32
|
||||||
subrange->list_locations.emplace_back(index, isRead, isWrite);
|
subrange->list_locations.emplace_back(index, isRead, isWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
sint32 PPCRecRARange_getReadWriteCost(PPCRecImlSegment_t* imlSegment)
|
sint32 PPCRecRARange_getReadWriteCost(IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
sint32 v = imlSegment->loopDepth + 1;
|
sint32 v = imlSegment->loopDepth + 1;
|
||||||
v *= 5;
|
v *= 5;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
raLivenessRange_t* PPCRecRA_createRangeBase(ppcImlGenContext_t* ppcImlGenContext, uint32 virtualRegister, uint32 name);
|
raLivenessRange_t* PPCRecRA_createRangeBase(ppcImlGenContext_t* ppcImlGenContext, uint32 virtualRegister, uint32 name);
|
||||||
raLivenessSubrange_t* PPCRecRA_createSubrange(ppcImlGenContext_t* ppcImlGenContext, raLivenessRange_t* range, PPCRecImlSegment_t* imlSegment, sint32 startIndex, sint32 endIndex);
|
raLivenessSubrange_t* PPCRecRA_createSubrange(ppcImlGenContext_t* ppcImlGenContext, raLivenessRange_t* range, IMLSegment* imlSegment, sint32 startIndex, sint32 endIndex);
|
||||||
void PPCRecRA_deleteSubrange(ppcImlGenContext_t* ppcImlGenContext, raLivenessSubrange_t* subrange);
|
void PPCRecRA_deleteSubrange(ppcImlGenContext_t* ppcImlGenContext, raLivenessSubrange_t* subrange);
|
||||||
void PPCRecRA_deleteRange(ppcImlGenContext_t* ppcImlGenContext, raLivenessRange_t* range);
|
void PPCRecRA_deleteRange(ppcImlGenContext_t* ppcImlGenContext, raLivenessRange_t* range);
|
||||||
void PPCRecRA_deleteAllRanges(ppcImlGenContext_t* ppcImlGenContext);
|
void PPCRecRA_deleteAllRanges(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
|
@ -17,7 +17,7 @@ void PPCRecRA_updateOrAddSubrangeLocation(raLivenessSubrange_t* subrange, sint32
|
||||||
void PPCRecRA_debugValidateSubrange(raLivenessSubrange_t* subrange);
|
void PPCRecRA_debugValidateSubrange(raLivenessSubrange_t* subrange);
|
||||||
|
|
||||||
// cost estimation
|
// cost estimation
|
||||||
sint32 PPCRecRARange_getReadWriteCost(PPCRecImlSegment_t* imlSegment);
|
sint32 PPCRecRARange_getReadWriteCost(IMLSegment* imlSegment);
|
||||||
sint32 PPCRecRARange_estimateCost(raLivenessRange_t* range);
|
sint32 PPCRecRARange_estimateCost(raLivenessRange_t* range);
|
||||||
sint32 PPCRecRARange_estimateAdditionalCostAfterRangeExplode(raLivenessRange_t* range);
|
sint32 PPCRecRARange_estimateAdditionalCostAfterRangeExplode(raLivenessRange_t* range);
|
||||||
sint32 PPCRecRARange_estimateAdditionalCostAfterSplit(raLivenessSubrange_t* subrange, sint32 splitIndex);
|
sint32 PPCRecRARange_estimateAdditionalCostAfterSplit(raLivenessSubrange_t* subrange, sint32 splitIndex);
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
#include "PPCRecompilerX64.h"
|
#include "PPCRecompilerX64.h"
|
||||||
#include "PPCRecompilerImlRanges.h"
|
#include "PPCRecompilerImlRanges.h"
|
||||||
|
|
||||||
void PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, sint32 gprRegisterSearched[4], sint32 gprRegisterReplaced[4]);
|
void PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, sint32 gprRegisterSearched[4], sint32 gprRegisterReplaced[4]);
|
||||||
|
|
||||||
bool PPCRecompiler_isSuffixInstruction(PPCRecImlInstruction_t* iml);
|
bool PPCRecompiler_isSuffixInstruction(IMLInstruction* iml);
|
||||||
|
|
||||||
uint32 recRACurrentIterationIndex = 0;
|
uint32 recRACurrentIterationIndex = 0;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ uint32 PPCRecRA_getNextIterationIndex()
|
||||||
return recRACurrentIterationIndex;
|
return recRACurrentIterationIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _detectLoop(PPCRecImlSegment_t* currentSegment, sint32 depth, uint32 iterationIndex, PPCRecImlSegment_t* imlSegmentLoopBase)
|
bool _detectLoop(IMLSegment* currentSegment, sint32 depth, uint32 iterationIndex, IMLSegment* imlSegmentLoopBase)
|
||||||
{
|
{
|
||||||
if (currentSegment == imlSegmentLoopBase)
|
if (currentSegment == imlSegmentLoopBase)
|
||||||
return true;
|
return true;
|
||||||
|
@ -47,7 +47,7 @@ bool _detectLoop(PPCRecImlSegment_t* currentSegment, sint32 depth, uint32 iterat
|
||||||
return currentSegment->raInfo.isPartOfProcessedLoop;
|
return currentSegment->raInfo.isPartOfProcessedLoop;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_detectLoop(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegmentLoopBase)
|
void PPCRecRA_detectLoop(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegmentLoopBase)
|
||||||
{
|
{
|
||||||
uint32 iterationIndex = PPCRecRA_getNextIterationIndex();
|
uint32 iterationIndex = PPCRecRA_getNextIterationIndex();
|
||||||
imlSegmentLoopBase->raInfo.lastIterationIndex = iterationIndex;
|
imlSegmentLoopBase->raInfo.lastIterationIndex = iterationIndex;
|
||||||
|
@ -57,7 +57,7 @@ void PPCRecRA_detectLoop(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_identifyLoop(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment)
|
void PPCRecRA_identifyLoop(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
if (imlSegment->nextSegmentIsUncertain)
|
if (imlSegment->nextSegmentIsUncertain)
|
||||||
return;
|
return;
|
||||||
|
@ -120,62 +120,54 @@ typedef struct
|
||||||
uint16 registerName;
|
uint16 registerName;
|
||||||
}raLoadStoreInfo_t;
|
}raLoadStoreInfo_t;
|
||||||
|
|
||||||
void PPCRecRA_insertGPRLoadInstruction(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, sint32 registerIndex, sint32 registerName)
|
void PPCRecRA_insertGPRLoadInstruction(IMLSegment* imlSegment, sint32 insertIndex, sint32 registerIndex, sint32 registerName)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, 1);
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + 0);
|
IMLInstruction* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + 0);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_R_NAME;
|
imlInstructionItr->type = PPCREC_IML_TYPE_R_NAME;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = registerIndex;
|
imlInstructionItr->op_r_name.registerIndex = registerIndex;
|
||||||
imlInstructionItr->op_r_name.name = registerName;
|
imlInstructionItr->op_r_name.name = registerName;
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_insertGPRLoadInstructions(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, raLoadStoreInfo_t* loadList, sint32 loadCount)
|
void PPCRecRA_insertGPRLoadInstructions(IMLSegment* imlSegment, sint32 insertIndex, raLoadStoreInfo_t* loadList, sint32 loadCount)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, loadCount);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, loadCount);
|
||||||
memset(imlSegment->imlList.data() + (insertIndex + 0), 0x00, sizeof(PPCRecImlInstruction_t)*loadCount);
|
memset(imlSegment->imlList.data() + (insertIndex + 0), 0x00, sizeof(IMLInstruction)*loadCount);
|
||||||
for (sint32 i = 0; i < loadCount; i++)
|
for (sint32 i = 0; i < loadCount; i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + i);
|
IMLInstruction* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + i);
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_R_NAME;
|
imlInstructionItr->type = PPCREC_IML_TYPE_R_NAME;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = (uint8)loadList[i].registerIndex;
|
imlInstructionItr->op_r_name.registerIndex = (uint8)loadList[i].registerIndex;
|
||||||
imlInstructionItr->op_r_name.name = (uint32)loadList[i].registerName;
|
imlInstructionItr->op_r_name.name = (uint32)loadList[i].registerName;
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_insertGPRStoreInstruction(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, sint32 registerIndex, sint32 registerName)
|
void PPCRecRA_insertGPRStoreInstruction(IMLSegment* imlSegment, sint32 insertIndex, sint32 registerIndex, sint32 registerName)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, 1);
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + 0);
|
IMLInstruction* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + 0);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_NAME_R;
|
imlInstructionItr->type = PPCREC_IML_TYPE_NAME_R;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = registerIndex;
|
imlInstructionItr->op_r_name.registerIndex = registerIndex;
|
||||||
imlInstructionItr->op_r_name.name = registerName;
|
imlInstructionItr->op_r_name.name = registerName;
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_insertGPRStoreInstructions(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, raLoadStoreInfo_t* storeList, sint32 storeCount)
|
void PPCRecRA_insertGPRStoreInstructions(IMLSegment* imlSegment, sint32 insertIndex, raLoadStoreInfo_t* storeList, sint32 storeCount)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, storeCount);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, storeCount);
|
||||||
memset(imlSegment->imlList.data() + (insertIndex + 0), 0x00, sizeof(PPCRecImlInstruction_t)*storeCount);
|
memset(imlSegment->imlList.data() + (insertIndex + 0), 0x00, sizeof(IMLInstruction)*storeCount);
|
||||||
for (sint32 i = 0; i < storeCount; i++)
|
for (sint32 i = 0; i < storeCount; i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + i);
|
IMLInstruction* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + i);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(IMLInstruction));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_NAME_R;
|
imlInstructionItr->type = PPCREC_IML_TYPE_NAME_R;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = (uint8)storeList[i].registerIndex;
|
imlInstructionItr->op_r_name.registerIndex = (uint8)storeList[i].registerIndex;
|
||||||
imlInstructionItr->op_r_name.name = (uint32)storeList[i].registerName;
|
imlInstructionItr->op_r_name.name = (uint32)storeList[i].registerName;
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +184,7 @@ sint32 PPCRecRA_countInstructionsUntilNextUse(raLivenessSubrange_t* subrange, si
|
||||||
}
|
}
|
||||||
|
|
||||||
// count how many instructions there are until physRegister is used by any subrange (returns 0 if register is in use at startIndex, and INT_MAX if not used for the remainder of the segment)
|
// count how many instructions there are until physRegister is used by any subrange (returns 0 if register is in use at startIndex, and INT_MAX if not used for the remainder of the segment)
|
||||||
sint32 PPCRecRA_countInstructionsUntilNextLocalPhysRegisterUse(PPCRecImlSegment_t* imlSegment, sint32 startIndex, sint32 physRegister)
|
sint32 PPCRecRA_countInstructionsUntilNextLocalPhysRegisterUse(IMLSegment* imlSegment, sint32 startIndex, sint32 physRegister)
|
||||||
{
|
{
|
||||||
sint32 minDistance = INT_MAX;
|
sint32 minDistance = INT_MAX;
|
||||||
// next
|
// next
|
||||||
|
@ -227,7 +219,7 @@ uint32 PPCRecRA_getAllowedRegisterMaskForFullRange(raLivenessRange_t* range)
|
||||||
uint32 physRegisterMask = (1 << PPC_X64_GPR_USABLE_REGISTERS) - 1;
|
uint32 physRegisterMask = (1 << PPC_X64_GPR_USABLE_REGISTERS) - 1;
|
||||||
for (auto& subrange : range->list_subranges)
|
for (auto& subrange : range->list_subranges)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = subrange->imlSegment;
|
IMLSegment* imlSegment = subrange->imlSegment;
|
||||||
raLivenessSubrange_t* subrangeItr = imlSegment->raInfo.linkedList_allSubranges;
|
raLivenessSubrange_t* subrangeItr = imlSegment->raInfo.linkedList_allSubranges;
|
||||||
while(subrangeItr)
|
while(subrangeItr)
|
||||||
{
|
{
|
||||||
|
@ -254,7 +246,7 @@ uint32 PPCRecRA_getAllowedRegisterMaskForFullRange(raLivenessRange_t* range)
|
||||||
|
|
||||||
bool _livenessRangeStartCompare(raLivenessSubrange_t* lhs, raLivenessSubrange_t* rhs) { return lhs->start.index < rhs->start.index; }
|
bool _livenessRangeStartCompare(raLivenessSubrange_t* lhs, raLivenessSubrange_t* rhs) { return lhs->start.index < rhs->start.index; }
|
||||||
|
|
||||||
void _sortSegmentAllSubrangesLinkedList(PPCRecImlSegment_t* imlSegment)
|
void _sortSegmentAllSubrangesLinkedList(IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
raLivenessSubrange_t* subrangeList[4096+1];
|
raLivenessSubrange_t* subrangeList[4096+1];
|
||||||
sint32 count = 0;
|
sint32 count = 0;
|
||||||
|
@ -318,7 +310,7 @@ void _sortSegmentAllSubrangesLinkedList(PPCRecImlSegment_t* imlSegment)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecRA_assignSegmentRegisters(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment)
|
bool PPCRecRA_assignSegmentRegisters(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
|
|
||||||
// sort subranges ascending by start index
|
// sort subranges ascending by start index
|
||||||
|
@ -628,7 +620,7 @@ void PPCRecRA_assignRegisters(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
// start with frequently executed segments first
|
// start with frequently executed segments first
|
||||||
sint32 maxLoopDepth = 0;
|
sint32 maxLoopDepth = 0;
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
maxLoopDepth = std::max(maxLoopDepth, segIt->loopDepth);
|
maxLoopDepth = std::max(maxLoopDepth, segIt->loopDepth);
|
||||||
}
|
}
|
||||||
|
@ -637,7 +629,7 @@ void PPCRecRA_assignRegisters(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
bool done = false;
|
bool done = false;
|
||||||
for (sint32 d = maxLoopDepth; d >= 0; d--)
|
for (sint32 d = maxLoopDepth; d >= 0; d--)
|
||||||
{
|
{
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
if (segIt->loopDepth != d)
|
if (segIt->loopDepth != d)
|
||||||
continue;
|
continue;
|
||||||
|
@ -672,7 +664,7 @@ void _findSubrangeWriteEndings(raLivenessSubrange_t* subrange, uint32 iterationI
|
||||||
subrange->lastIterationIndex = iterationIndex;
|
subrange->lastIterationIndex = iterationIndex;
|
||||||
if (subrange->hasStoreDelayed)
|
if (subrange->hasStoreDelayed)
|
||||||
return; // no need to traverse this subrange
|
return; // no need to traverse this subrange
|
||||||
PPCRecImlSegment_t* imlSegment = subrange->imlSegment;
|
IMLSegment* imlSegment = subrange->imlSegment;
|
||||||
if (subrange->end.index != RA_INTER_RANGE_END)
|
if (subrange->end.index != RA_INTER_RANGE_END)
|
||||||
{
|
{
|
||||||
// ending segment
|
// ending segment
|
||||||
|
@ -758,7 +750,7 @@ void _analyzeRangeDataFlow(raLivenessSubrange_t* subrange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment)
|
void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
sint16 virtualReg2PhysReg[PPC_REC_MAX_VIRTUAL_GPR];
|
sint16 virtualReg2PhysReg[PPC_REC_MAX_VIRTUAL_GPR];
|
||||||
for (sint32 i = 0; i < PPC_REC_MAX_VIRTUAL_GPR; i++)
|
for (sint32 i = 0; i < PPC_REC_MAX_VIRTUAL_GPR; i++)
|
||||||
|
@ -933,7 +925,7 @@ void PPCRecRA_generateMoveInstructions(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[s];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[s];
|
||||||
PPCRecRA_generateSegmentInstructions(ppcImlGenContext, imlSegment);
|
PPCRecRA_generateSegmentInstructions(ppcImlGenContext, imlSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -949,7 +941,7 @@ void PPCRecompilerImm_prepareForRegisterAllocation(ppcImlGenContext_t* ppcImlGen
|
||||||
size_t segmentIndex = 0;
|
size_t segmentIndex = 0;
|
||||||
while (segmentIndex < ppcImlGenContext->segmentList2.size())
|
while (segmentIndex < ppcImlGenContext->segmentList2.size())
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[segmentIndex];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[segmentIndex];
|
||||||
if (imlSegment->nextSegmentIsUncertain)
|
if (imlSegment->nextSegmentIsUncertain)
|
||||||
{
|
{
|
||||||
segmentIndex++;
|
segmentIndex++;
|
||||||
|
@ -971,9 +963,9 @@ void PPCRecompilerImm_prepareForRegisterAllocation(ppcImlGenContext_t* ppcImlGen
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PPCRecompilerIml_insertSegments(ppcImlGenContext, segmentIndex + 1, 1);
|
PPCRecompilerIml_insertSegments(ppcImlGenContext, segmentIndex + 1, 1);
|
||||||
PPCRecImlSegment_t* imlSegmentP0 = ppcImlGenContext->segmentList2[segmentIndex + 0];
|
IMLSegment* imlSegmentP0 = ppcImlGenContext->segmentList2[segmentIndex + 0];
|
||||||
PPCRecImlSegment_t* imlSegmentP1 = ppcImlGenContext->segmentList2[segmentIndex + 1];
|
IMLSegment* imlSegmentP1 = ppcImlGenContext->segmentList2[segmentIndex + 1];
|
||||||
PPCRecImlSegment_t* nextSegment = imlSegment->nextSegmentBranchNotTaken;
|
IMLSegment* nextSegment = imlSegment->nextSegmentBranchNotTaken;
|
||||||
PPCRecompilerIML_removeLink(imlSegmentP0, nextSegment);
|
PPCRecompilerIML_removeLink(imlSegmentP0, nextSegment);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegmentP1, nextSegment);
|
PPCRecompilerIml_setLinkBranchNotTaken(imlSegmentP1, nextSegment);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegmentP0, imlSegmentP1);
|
PPCRecompilerIml_setLinkBranchNotTaken(imlSegmentP0, imlSegmentP1);
|
||||||
|
@ -982,12 +974,12 @@ void PPCRecompilerImm_prepareForRegisterAllocation(ppcImlGenContext_t* ppcImlGen
|
||||||
// detect loops
|
// detect loops
|
||||||
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[s];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[s];
|
||||||
imlSegment->momentaryIndex = s;
|
imlSegment->momentaryIndex = s;
|
||||||
}
|
}
|
||||||
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[s];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[s];
|
||||||
PPCRecRA_identifyLoop(ppcImlGenContext, imlSegment);
|
PPCRecRA_identifyLoop(ppcImlGenContext, imlSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1010,12 +1002,12 @@ void PPCRecompilerImm_allocateRegisters(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool _isRangeDefined(PPCRecImlSegment_t* imlSegment, sint32 vGPR)
|
bool _isRangeDefined(IMLSegment* imlSegment, sint32 vGPR)
|
||||||
{
|
{
|
||||||
return (imlSegment->raDistances.reg[vGPR].usageStart != INT_MAX);
|
return (imlSegment->raDistances.reg[vGPR].usageStart != INT_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_calculateSegmentMinMaxRanges(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment)
|
void PPCRecRA_calculateSegmentMinMaxRanges(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
for (sint32 i = 0; i < PPC_REC_MAX_VIRTUAL_GPR; i++)
|
for (sint32 i = 0; i < PPC_REC_MAX_VIRTUAL_GPR; i++)
|
||||||
{
|
{
|
||||||
|
@ -1049,13 +1041,13 @@ void PPCRecRA_calculateSegmentMinMaxRanges(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
void PPCRecRA_calculateLivenessRangesV2(ppcImlGenContext_t* ppcImlGenContext)
|
void PPCRecRA_calculateLivenessRangesV2(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
// for each register calculate min/max index of usage range within each segment
|
// for each register calculate min/max index of usage range within each segment
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
PPCRecRA_calculateSegmentMinMaxRanges(ppcImlGenContext, segIt);
|
PPCRecRA_calculateSegmentMinMaxRanges(ppcImlGenContext, segIt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
raLivenessSubrange_t* PPCRecRA_convertToMappedRanges(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 vGPR, raLivenessRange_t* range)
|
raLivenessSubrange_t* PPCRecRA_convertToMappedRanges(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 vGPR, raLivenessRange_t* range)
|
||||||
{
|
{
|
||||||
if (imlSegment->raDistances.isProcessed[vGPR])
|
if (imlSegment->raDistances.isProcessed[vGPR])
|
||||||
{
|
{
|
||||||
|
@ -1094,7 +1086,7 @@ raLivenessSubrange_t* PPCRecRA_convertToMappedRanges(ppcImlGenContext_t* ppcImlG
|
||||||
return subrange;
|
return subrange;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_createSegmentLivenessRanges(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment)
|
void PPCRecRA_createSegmentLivenessRanges(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
for (sint32 i = 0; i < PPC_REC_MAX_VIRTUAL_GPR; i++)
|
for (sint32 i = 0; i < PPC_REC_MAX_VIRTUAL_GPR; i++)
|
||||||
{
|
{
|
||||||
|
@ -1146,7 +1138,7 @@ void PPCRecRA_createSegmentLivenessRanges(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_extendRangeToEndOfSegment(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 vGPR)
|
void PPCRecRA_extendRangeToEndOfSegment(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 vGPR)
|
||||||
{
|
{
|
||||||
if (_isRangeDefined(imlSegment, vGPR) == false)
|
if (_isRangeDefined(imlSegment, vGPR) == false)
|
||||||
{
|
{
|
||||||
|
@ -1157,7 +1149,7 @@ void PPCRecRA_extendRangeToEndOfSegment(ppcImlGenContext_t* ppcImlGenContext, PP
|
||||||
imlSegment->raDistances.reg[vGPR].usageEnd = RA_INTER_RANGE_END;
|
imlSegment->raDistances.reg[vGPR].usageEnd = RA_INTER_RANGE_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_extendRangeToBeginningOfSegment(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 vGPR)
|
void PPCRecRA_extendRangeToBeginningOfSegment(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 vGPR)
|
||||||
{
|
{
|
||||||
if (_isRangeDefined(imlSegment, vGPR) == false)
|
if (_isRangeDefined(imlSegment, vGPR) == false)
|
||||||
{
|
{
|
||||||
|
@ -1175,7 +1167,7 @@ void PPCRecRA_extendRangeToBeginningOfSegment(ppcImlGenContext_t* ppcImlGenConte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _PPCRecRA_connectRanges(ppcImlGenContext_t* ppcImlGenContext, sint32 vGPR, PPCRecImlSegment_t** route, sint32 routeDepth)
|
void _PPCRecRA_connectRanges(ppcImlGenContext_t* ppcImlGenContext, sint32 vGPR, IMLSegment** route, sint32 routeDepth)
|
||||||
{
|
{
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
if (routeDepth < 2)
|
if (routeDepth < 2)
|
||||||
|
@ -1193,7 +1185,7 @@ void _PPCRecRA_connectRanges(ppcImlGenContext_t* ppcImlGenContext, sint32 vGPR,
|
||||||
PPCRecRA_extendRangeToBeginningOfSegment(ppcImlGenContext, route[routeDepth - 1], vGPR);
|
PPCRecRA_extendRangeToBeginningOfSegment(ppcImlGenContext, route[routeDepth - 1], vGPR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* currentSegment, sint32 vGPR, sint32 distanceLeft, PPCRecImlSegment_t** route, sint32 routeDepth)
|
void _PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* currentSegment, sint32 vGPR, sint32 distanceLeft, IMLSegment** route, sint32 routeDepth)
|
||||||
{
|
{
|
||||||
if (routeDepth >= 64)
|
if (routeDepth >= 64)
|
||||||
{
|
{
|
||||||
|
@ -1229,7 +1221,7 @@ void _PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, PPCR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* currentSegment, sint32 vGPR)
|
void PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* currentSegment, sint32 vGPR)
|
||||||
{
|
{
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
if (currentSegment->raDistances.reg[vGPR].usageEnd < 0)
|
if (currentSegment->raDistances.reg[vGPR].usageEnd < 0)
|
||||||
|
@ -1253,7 +1245,7 @@ void PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, PPCRe
|
||||||
return; // can't reach end
|
return; // can't reach end
|
||||||
|
|
||||||
// also dont forget: Extending is easier if we allow 'non symmetric' branches. E.g. register range one enters one branch
|
// also dont forget: Extending is easier if we allow 'non symmetric' branches. E.g. register range one enters one branch
|
||||||
PPCRecImlSegment_t* route[64];
|
IMLSegment* route[64];
|
||||||
route[0] = currentSegment;
|
route[0] = currentSegment;
|
||||||
if (currentSegment->nextSegmentBranchNotTaken)
|
if (currentSegment->nextSegmentBranchNotTaken)
|
||||||
{
|
{
|
||||||
|
@ -1265,7 +1257,7 @@ void PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, PPCRe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_mergeCloseRangesForSegmentV2(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment)
|
void PPCRecRA_mergeCloseRangesForSegmentV2(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
for (sint32 i = 0; i < PPC_REC_MAX_VIRTUAL_GPR; i++) // todo: Use dynamic maximum or list of used vGPRs so we can avoid parsing empty entries
|
for (sint32 i = 0; i < PPC_REC_MAX_VIRTUAL_GPR; i++) // todo: Use dynamic maximum or list of used vGPRs so we can avoid parsing empty entries
|
||||||
{
|
{
|
||||||
|
@ -1282,16 +1274,16 @@ void PPCRecRA_mergeCloseRangesForSegmentV2(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecRA_followFlowAndExtendRanges(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment)
|
void PPCRecRA_followFlowAndExtendRanges(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
std::vector<PPCRecImlSegment_t*> list_segments;
|
std::vector<IMLSegment*> list_segments;
|
||||||
list_segments.reserve(1000);
|
list_segments.reserve(1000);
|
||||||
sint32 index = 0;
|
sint32 index = 0;
|
||||||
imlSegment->raRangeExtendProcessed = true;
|
imlSegment->raRangeExtendProcessed = true;
|
||||||
list_segments.push_back(imlSegment);
|
list_segments.push_back(imlSegment);
|
||||||
while (index < list_segments.size())
|
while (index < list_segments.size())
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* currentSegment = list_segments[index];
|
IMLSegment* currentSegment = list_segments[index];
|
||||||
PPCRecRA_mergeCloseRangesForSegmentV2(ppcImlGenContext, currentSegment);
|
PPCRecRA_mergeCloseRangesForSegmentV2(ppcImlGenContext, currentSegment);
|
||||||
// follow flow
|
// follow flow
|
||||||
if (currentSegment->nextSegmentBranchNotTaken && currentSegment->nextSegmentBranchNotTaken->raRangeExtendProcessed == false)
|
if (currentSegment->nextSegmentBranchNotTaken && currentSegment->nextSegmentBranchNotTaken->raRangeExtendProcessed == false)
|
||||||
|
@ -1312,7 +1304,7 @@ void PPCRecRA_mergeCloseRangesV2(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[s];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[s];
|
||||||
if (imlSegment->list_prevSegments.empty())
|
if (imlSegment->list_prevSegments.empty())
|
||||||
{
|
{
|
||||||
if (imlSegment->raRangeExtendProcessed)
|
if (imlSegment->raRangeExtendProcessed)
|
||||||
|
@ -1326,7 +1318,7 @@ void PPCRecRA_extendRangesOutOfLoopsV2(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[s];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[s];
|
||||||
auto localLoopDepth = imlSegment->loopDepth;
|
auto localLoopDepth = imlSegment->loopDepth;
|
||||||
if (localLoopDepth <= 0)
|
if (localLoopDepth <= 0)
|
||||||
continue; // not inside a loop
|
continue; // not inside a loop
|
||||||
|
@ -1365,7 +1357,7 @@ void PPCRecRA_processFlowAndCalculateLivenessRangesV2(ppcImlGenContext_t* ppcIml
|
||||||
// calculate liveness ranges
|
// calculate liveness ranges
|
||||||
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
for (size_t s = 0; s < ppcImlGenContext->segmentList2.size(); s++)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[s];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[s];
|
||||||
PPCRecRA_createSegmentLivenessRanges(ppcImlGenContext, imlSegment);
|
PPCRecRA_createSegmentLivenessRanges(ppcImlGenContext, imlSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "PPCRecompiler.h"
|
#include "PPCRecompiler.h"
|
||||||
#include "PPCRecompilerIml.h"
|
#include "PPCRecompilerIml.h"
|
||||||
|
|
||||||
PPCRecImlSegment_t* PPCRecompiler_getSegmentByPPCJumpAddress(ppcImlGenContext_t* ppcImlGenContext, uint32 ppcOffset)
|
IMLSegment* PPCRecompiler_getSegmentByPPCJumpAddress(ppcImlGenContext_t* ppcImlGenContext, uint32 ppcOffset)
|
||||||
{
|
{
|
||||||
for(PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for(IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
if(segIt->isJumpDestination && segIt->jumpDestinationPPCAddress == ppcOffset )
|
if(segIt->isJumpDestination && segIt->jumpDestinationPPCAddress == ppcOffset )
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@ PPCRecImlSegment_t* PPCRecompiler_getSegmentByPPCJumpAddress(ppcImlGenContext_t*
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerIml_setLinkBranchNotTaken(PPCRecImlSegment_t* imlSegmentSrc, PPCRecImlSegment_t* imlSegmentDst)
|
void PPCRecompilerIml_setLinkBranchNotTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst)
|
||||||
{
|
{
|
||||||
// make sure segments aren't already linked
|
// make sure segments aren't already linked
|
||||||
if (imlSegmentSrc->nextSegmentBranchNotTaken == imlSegmentDst)
|
if (imlSegmentSrc->nextSegmentBranchNotTaken == imlSegmentDst)
|
||||||
|
@ -27,7 +27,7 @@ void PPCRecompilerIml_setLinkBranchNotTaken(PPCRecImlSegment_t* imlSegmentSrc, P
|
||||||
imlSegmentDst->list_prevSegments.push_back(imlSegmentSrc);
|
imlSegmentDst->list_prevSegments.push_back(imlSegmentSrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerIml_setLinkBranchTaken(PPCRecImlSegment_t* imlSegmentSrc, PPCRecImlSegment_t* imlSegmentDst)
|
void PPCRecompilerIml_setLinkBranchTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst)
|
||||||
{
|
{
|
||||||
// make sure segments aren't already linked
|
// make sure segments aren't already linked
|
||||||
if (imlSegmentSrc->nextSegmentBranchTaken == imlSegmentDst)
|
if (imlSegmentSrc->nextSegmentBranchTaken == imlSegmentDst)
|
||||||
|
@ -40,7 +40,7 @@ void PPCRecompilerIml_setLinkBranchTaken(PPCRecImlSegment_t* imlSegmentSrc, PPCR
|
||||||
imlSegmentDst->list_prevSegments.push_back(imlSegmentSrc);
|
imlSegmentDst->list_prevSegments.push_back(imlSegmentSrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerIML_removeLink(PPCRecImlSegment_t* imlSegmentSrc, PPCRecImlSegment_t* imlSegmentDst)
|
void PPCRecompilerIML_removeLink(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst)
|
||||||
{
|
{
|
||||||
if (imlSegmentSrc->nextSegmentBranchNotTaken == imlSegmentDst)
|
if (imlSegmentSrc->nextSegmentBranchNotTaken == imlSegmentDst)
|
||||||
{
|
{
|
||||||
|
@ -70,11 +70,11 @@ void PPCRecompilerIML_removeLink(PPCRecImlSegment_t* imlSegmentSrc, PPCRecImlSeg
|
||||||
/*
|
/*
|
||||||
* Replaces all links to segment orig with linkts to segment new
|
* Replaces all links to segment orig with linkts to segment new
|
||||||
*/
|
*/
|
||||||
void PPCRecompilerIML_relinkInputSegment(PPCRecImlSegment_t* imlSegmentOrig, PPCRecImlSegment_t* imlSegmentNew)
|
void PPCRecompilerIML_relinkInputSegment(IMLSegment* imlSegmentOrig, IMLSegment* imlSegmentNew)
|
||||||
{
|
{
|
||||||
while (imlSegmentOrig->list_prevSegments.size() != 0)
|
while (imlSegmentOrig->list_prevSegments.size() != 0)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* prevSegment = imlSegmentOrig->list_prevSegments[0];
|
IMLSegment* prevSegment = imlSegmentOrig->list_prevSegments[0];
|
||||||
if (prevSegment->nextSegmentBranchNotTaken == imlSegmentOrig)
|
if (prevSegment->nextSegmentBranchNotTaken == imlSegmentOrig)
|
||||||
{
|
{
|
||||||
PPCRecompilerIML_removeLink(prevSegment, imlSegmentOrig);
|
PPCRecompilerIML_removeLink(prevSegment, imlSegmentOrig);
|
||||||
|
@ -97,10 +97,10 @@ void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
size_t segCount = ppcImlGenContext->segmentList2.size();
|
size_t segCount = ppcImlGenContext->segmentList2.size();
|
||||||
for(size_t s=0; s<segCount; s++)
|
for(size_t s=0; s<segCount; s++)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[s];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[s];
|
||||||
|
|
||||||
bool isLastSegment = (s+1)>=ppcImlGenContext->segmentList2.size();
|
bool isLastSegment = (s+1)>=ppcImlGenContext->segmentList2.size();
|
||||||
PPCRecImlSegment_t* nextSegment = isLastSegment?nullptr:ppcImlGenContext->segmentList2[s+1];
|
IMLSegment* nextSegment = isLastSegment?nullptr:ppcImlGenContext->segmentList2[s+1];
|
||||||
// handle empty segment
|
// handle empty segment
|
||||||
if( imlSegment->imlList.empty())
|
if( imlSegment->imlList.empty())
|
||||||
{
|
{
|
||||||
|
@ -111,11 +111,11 @@ void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// check last instruction of segment
|
// check last instruction of segment
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + (imlSegment->imlList.size() - 1);
|
IMLInstruction* imlInstruction = imlSegment->imlList.data() + (imlSegment->imlList.size() - 1);
|
||||||
if( imlInstruction->type == PPCREC_IML_TYPE_CJUMP || imlInstruction->type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK )
|
if( imlInstruction->type == PPCREC_IML_TYPE_CJUMP || imlInstruction->type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK )
|
||||||
{
|
{
|
||||||
// find destination segment by ppc jump address
|
// find destination segment by ppc jump address
|
||||||
PPCRecImlSegment_t* jumpDestSegment = PPCRecompiler_getSegmentByPPCJumpAddress(ppcImlGenContext, imlInstruction->op_conditionalJump.jumpmarkAddress);
|
IMLSegment* jumpDestSegment = PPCRecompiler_getSegmentByPPCJumpAddress(ppcImlGenContext, imlInstruction->op_conditionalJump.jumpmarkAddress);
|
||||||
if( jumpDestSegment )
|
if( jumpDestSegment )
|
||||||
{
|
{
|
||||||
if (imlInstruction->op_conditionalJump.condition != PPCREC_JUMP_CONDITION_NONE)
|
if (imlInstruction->op_conditionalJump.condition != PPCREC_JUMP_CONDITION_NONE)
|
||||||
|
@ -145,12 +145,12 @@ void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenCont
|
||||||
size_t initialSegmentCount = ppcImlGenContext->segmentList2.size();
|
size_t initialSegmentCount = ppcImlGenContext->segmentList2.size();
|
||||||
for (size_t i = 0; i < initialSegmentCount; i++)
|
for (size_t i = 0; i < initialSegmentCount; i++)
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[i];
|
IMLSegment* imlSegment = ppcImlGenContext->segmentList2[i];
|
||||||
if (imlSegment->list_prevSegments.empty() == false && imlSegment->isEnterable)
|
if (imlSegment->list_prevSegments.empty() == false && imlSegment->isEnterable)
|
||||||
{
|
{
|
||||||
// spawn new segment at end
|
// spawn new segment at end
|
||||||
PPCRecompilerIml_insertSegments(ppcImlGenContext, ppcImlGenContext->segmentList2.size(), 1);
|
PPCRecompilerIml_insertSegments(ppcImlGenContext, ppcImlGenContext->segmentList2.size(), 1);
|
||||||
PPCRecImlSegment_t* entrySegment = ppcImlGenContext->segmentList2[ppcImlGenContext->segmentList2.size()-1];
|
IMLSegment* entrySegment = ppcImlGenContext->segmentList2[ppcImlGenContext->segmentList2.size()-1];
|
||||||
entrySegment->isEnterable = true;
|
entrySegment->isEnterable = true;
|
||||||
entrySegment->enterPPCAddress = imlSegment->enterPPCAddress;
|
entrySegment->enterPPCAddress = imlSegment->enterPPCAddress;
|
||||||
// create jump instruction
|
// create jump instruction
|
||||||
|
@ -164,7 +164,7 @@ void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenCont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCRecImlInstruction_t* PPCRecompilerIML_getLastInstruction(PPCRecImlSegment_t* imlSegment)
|
IMLInstruction* PPCRecompilerIML_getLastInstruction(IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
if (imlSegment->imlList.empty())
|
if (imlSegment->imlList.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -79,7 +79,7 @@ void PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext_t* x64GenContext, si
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
sint32 crRegister = imlInstruction->crRegister;
|
sint32 crRegister = imlInstruction->crRegister;
|
||||||
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 )
|
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 )
|
||||||
|
@ -124,7 +124,7 @@ void ATTR_MS_ABI PPCRecompiler_getTBU(PPCInterpreter_t* hCPU, uint32 gprIndex)
|
||||||
hCPU->gpr[gprIndex] = (uint32)((coreTime>>32)&0xFFFFFFFF);
|
hCPU->gpr[gprIndex] = (uint32)((coreTime>>32)&0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||||
if( imlInstruction->operation == PPCREC_IML_MACRO_BLR || imlInstruction->operation == PPCREC_IML_MACRO_BLRL )
|
if( imlInstruction->operation == PPCREC_IML_MACRO_BLR || imlInstruction->operation == PPCREC_IML_MACRO_BLRL )
|
||||||
|
@ -344,7 +344,7 @@ bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction,
|
||||||
/*
|
/*
|
||||||
* Load from memory
|
* Load from memory
|
||||||
*/
|
*/
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction, bool indexed)
|
bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction, bool indexed)
|
||||||
{
|
{
|
||||||
sint32 realRegisterData = tempToRealRegister(imlInstruction->op_storeLoad.registerData);
|
sint32 realRegisterData = tempToRealRegister(imlInstruction->op_storeLoad.registerData);
|
||||||
sint32 realRegisterMem = tempToRealRegister(imlInstruction->op_storeLoad.registerMem);
|
sint32 realRegisterMem = tempToRealRegister(imlInstruction->op_storeLoad.registerMem);
|
||||||
|
@ -502,7 +502,7 @@ bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, p
|
||||||
/*
|
/*
|
||||||
* Write to memory
|
* Write to memory
|
||||||
*/
|
*/
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction, bool indexed)
|
bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction, bool indexed)
|
||||||
{
|
{
|
||||||
sint32 realRegisterData = tempToRealRegister(imlInstruction->op_storeLoad.registerData);
|
sint32 realRegisterData = tempToRealRegister(imlInstruction->op_storeLoad.registerData);
|
||||||
sint32 realRegisterMem = tempToRealRegister(imlInstruction->op_storeLoad.registerMem);
|
sint32 realRegisterMem = tempToRealRegister(imlInstruction->op_storeLoad.registerMem);
|
||||||
|
@ -675,7 +675,7 @@ bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
if (imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
if (imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
||||||
{
|
{
|
||||||
|
@ -989,7 +989,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_r_s32(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerX64Gen_imlInstruction_r_s32(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
if( imlInstruction->operation == PPCREC_IML_OP_ASSIGN )
|
if( imlInstruction->operation == PPCREC_IML_OP_ASSIGN )
|
||||||
{
|
{
|
||||||
|
@ -1140,7 +1140,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_s32(PPCRecFunction_t* PPCRecFunction,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_conditional_r_s32(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerX64Gen_imlInstruction_conditional_r_s32(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
if (imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
if (imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
||||||
{
|
{
|
||||||
|
@ -1221,7 +1221,7 @@ bool PPCRecompilerX64Gen_imlInstruction_conditional_r_s32(PPCRecFunction_t* PPCR
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
if( imlInstruction->operation == PPCREC_IML_OP_ADD || imlInstruction->operation == PPCREC_IML_OP_ADD_UPDATE_CARRY || imlInstruction->operation == PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY )
|
if( imlInstruction->operation == PPCREC_IML_OP_ADD || imlInstruction->operation == PPCREC_IML_OP_ADD_UPDATE_CARRY || imlInstruction->operation == PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY )
|
||||||
{
|
{
|
||||||
|
@ -1791,7 +1791,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
if( imlInstruction->operation == PPCREC_IML_OP_ADD )
|
if( imlInstruction->operation == PPCREC_IML_OP_ADD )
|
||||||
{
|
{
|
||||||
|
@ -1981,7 +1981,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_conditionalJump(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlSegment_t* imlSegment, PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerX64Gen_imlInstruction_conditionalJump(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLSegment* imlSegment, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
if( imlInstruction->op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NONE )
|
if( imlInstruction->op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NONE )
|
||||||
{
|
{
|
||||||
|
@ -2102,7 +2102,7 @@ bool PPCRecompilerX64Gen_imlInstruction_conditionalJump(PPCRecFunction_t* PPCRec
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_conditionalJumpCycleCheck(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerX64Gen_imlInstruction_conditionalJumpCycleCheck(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||||
// some tests (all performed on a i7-4790K)
|
// some tests (all performed on a i7-4790K)
|
||||||
|
@ -2119,7 +2119,7 @@ bool PPCRecompilerX64Gen_imlInstruction_conditionalJumpCycleCheck(PPCRecFunction
|
||||||
/*
|
/*
|
||||||
* PPC condition register operation
|
* PPC condition register operation
|
||||||
*/
|
*/
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_cr(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
bool PPCRecompilerX64Gen_imlInstruction_cr(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext); // while these instruction do not directly affect eflags, they change the CR bit
|
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext); // while these instruction do not directly affect eflags, they change the CR bit
|
||||||
if (imlInstruction->operation == PPCREC_IML_OP_CR_CLEAR)
|
if (imlInstruction->operation == PPCREC_IML_OP_CR_CLEAR)
|
||||||
|
@ -2161,7 +2161,7 @@ bool PPCRecompilerX64Gen_imlInstruction_cr(PPCRecFunction_t* PPCRecFunction, ppc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PPCRecompilerX64Gen_imlInstruction_ppcEnter(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerX64Gen_imlInstruction_ppcEnter(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
imlInstruction->op_ppcEnter.x64Offset = x64GenContext->codeBufferIndex;
|
imlInstruction->op_ppcEnter.x64Offset = x64GenContext->codeBufferIndex;
|
||||||
// generate code
|
// generate code
|
||||||
|
@ -2182,7 +2182,7 @@ void PPCRecompilerX64Gen_imlInstruction_ppcEnter(PPCRecFunction_t* PPCRecFunctio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerX64Gen_imlInstruction_r_name(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerX64Gen_imlInstruction_r_name(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
uint32 name = imlInstruction->op_r_name.name;
|
uint32 name = imlInstruction->op_r_name.name;
|
||||||
if( name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0+32 )
|
if( name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0+32 )
|
||||||
|
@ -2211,7 +2211,7 @@ void PPCRecompilerX64Gen_imlInstruction_r_name(PPCRecFunction_t* PPCRecFunction,
|
||||||
assert_dbg();
|
assert_dbg();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerX64Gen_imlInstruction_name_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerX64Gen_imlInstruction_name_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
uint32 name = imlInstruction->op_r_name.name;
|
uint32 name = imlInstruction->op_r_name.name;
|
||||||
if( name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0+32 )
|
if( name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0+32 )
|
||||||
|
@ -2278,12 +2278,12 @@ bool PPCRecompiler_generateX64Code(PPCRecFunction_t* PPCRecFunction, ppcImlGenCo
|
||||||
|
|
||||||
// generate iml instruction code
|
// generate iml instruction code
|
||||||
bool codeGenerationFailed = false;
|
bool codeGenerationFailed = false;
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
segIt->x64Offset = x64GenContext.codeBufferIndex;
|
segIt->x64Offset = x64GenContext.codeBufferIndex;
|
||||||
for(size_t i=0; i<segIt->imlList.size(); i++)
|
for(size_t i=0; i<segIt->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList.data() + i;
|
IMLInstruction* imlInstruction = segIt->imlList.data() + i;
|
||||||
|
|
||||||
if( imlInstruction->type == PPCREC_IML_TYPE_R_NAME )
|
if( imlInstruction->type == PPCREC_IML_TYPE_R_NAME )
|
||||||
{
|
{
|
||||||
|
@ -2477,7 +2477,7 @@ bool PPCRecompiler_generateX64Code(PPCRecFunction_t* PPCRecFunction, ppcImlGenCo
|
||||||
uint32 x64Offset = 0xFFFFFFFF;
|
uint32 x64Offset = 0xFFFFFFFF;
|
||||||
if (x64GenContext.relocateOffsetTable[i].type == X64_RELOC_LINK_TO_PPC)
|
if (x64GenContext.relocateOffsetTable[i].type == X64_RELOC_LINK_TO_PPC)
|
||||||
{
|
{
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (IMLSegment* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
if (segIt->isJumpDestination && segIt->jumpDestinationPPCAddress == ppcOffset)
|
if (segIt->isJumpDestination && segIt->jumpDestinationPPCAddress == ppcOffset)
|
||||||
{
|
{
|
||||||
|
@ -2494,7 +2494,7 @@ bool PPCRecompiler_generateX64Code(PPCRecFunction_t* PPCRecFunction, ppcImlGenCo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PPCRecImlSegment_t* destSegment = (PPCRecImlSegment_t*)x64GenContext.relocateOffsetTable[i].extraInfo;
|
IMLSegment* destSegment = (IMLSegment*)x64GenContext.relocateOffsetTable[i].extraInfo;
|
||||||
x64Offset = destSegment->x64Offset;
|
x64Offset = destSegment->x64Offset;
|
||||||
}
|
}
|
||||||
uint32 relocBase = x64GenContext.relocateOffsetTable[i].offset;
|
uint32 relocBase = x64GenContext.relocateOffsetTable[i].offset;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
|
||||||
typedef struct
|
struct x64RelocEntry_t
|
||||||
{
|
{
|
||||||
uint32 offset;
|
uint32 offset;
|
||||||
uint8 type;
|
uint8 type;
|
||||||
void* extraInfo;
|
void* extraInfo;
|
||||||
}x64RelocEntry_t;
|
};
|
||||||
|
|
||||||
typedef struct
|
struct x64GenContext_t
|
||||||
{
|
{
|
||||||
uint8* codeBuffer;
|
uint8* codeBuffer;
|
||||||
sint32 codeBufferIndex;
|
sint32 codeBufferIndex;
|
||||||
|
@ -18,7 +18,7 @@ typedef struct
|
||||||
x64RelocEntry_t* relocateOffsetTable;
|
x64RelocEntry_t* relocateOffsetTable;
|
||||||
sint32 relocateOffsetTableSize;
|
sint32 relocateOffsetTableSize;
|
||||||
sint32 relocateOffsetTableCount;
|
sint32 relocateOffsetTableCount;
|
||||||
}x64GenContext_t;
|
};
|
||||||
|
|
||||||
// Some of these are defined by winnt.h and gnu headers
|
// Some of these are defined by winnt.h and gnu headers
|
||||||
#undef REG_EAX
|
#undef REG_EAX
|
||||||
|
@ -140,15 +140,15 @@ void PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext_t* x64GenContext, si
|
||||||
|
|
||||||
void PPCRecompilerX64Gen_generateRecompilerInterfaceFunctions();
|
void PPCRecompilerX64Gen_generateRecompilerInterfaceFunctions();
|
||||||
|
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r_name(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction);
|
void PPCRecompilerX64Gen_imlInstruction_fpr_r_name(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction);
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_name_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction);
|
void PPCRecompilerX64Gen_imlInstruction_fpr_name_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction);
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_fpr_load(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction, bool indexed);
|
bool PPCRecompilerX64Gen_imlInstruction_fpr_load(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction, bool indexed);
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction, bool indexed);
|
bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction, bool indexed);
|
||||||
|
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction);
|
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction);
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction);
|
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction);
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction);
|
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction);
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction);
|
void PPCRecompilerX64Gen_imlInstruction_fpr_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction);
|
||||||
|
|
||||||
// ASM gen
|
// ASM gen
|
||||||
void x64Gen_writeU8(x64GenContext_t* x64GenContext, uint8 v);
|
void x64Gen_writeU8(x64GenContext_t* x64GenContext, uint8 v);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "asm/x64util.h"
|
#include "asm/x64util.h"
|
||||||
#include "Common/cpu_features.h"
|
#include "Common/cpu_features.h"
|
||||||
|
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r_name(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
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 name = imlInstruction->op_r_name.name;
|
||||||
if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) )
|
if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) )
|
||||||
|
@ -21,7 +21,7 @@ void PPCRecompilerX64Gen_imlInstruction_fpr_r_name(PPCRecFunction_t* PPCRecFunct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_name_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
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 name = imlInstruction->op_r_name.name;
|
||||||
if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) )
|
if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) )
|
||||||
|
@ -264,7 +264,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_load_generic(ppcImlGenContext_t* ppcImlGen
|
||||||
}
|
}
|
||||||
|
|
||||||
// load from memory
|
// load from memory
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_fpr_load(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction, bool indexed)
|
bool PPCRecompilerX64Gen_imlInstruction_fpr_load(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction, bool indexed)
|
||||||
{
|
{
|
||||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||||
sint32 realRegisterXMM = tempToRealFPRRegister(imlInstruction->op_storeLoad.registerData);
|
sint32 realRegisterXMM = tempToRealFPRRegister(imlInstruction->op_storeLoad.registerData);
|
||||||
|
@ -591,7 +591,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_store_generic(ppcImlGenContext_t* ppcImlGe
|
||||||
}
|
}
|
||||||
|
|
||||||
// store to memory
|
// store to memory
|
||||||
bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction, bool indexed)
|
bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction, bool indexed)
|
||||||
{
|
{
|
||||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||||
sint32 realRegisterXMM = tempToRealFPRRegister(imlInstruction->op_storeLoad.registerData);
|
sint32 realRegisterXMM = tempToRealFPRRegister(imlInstruction->op_storeLoad.registerData);
|
||||||
|
@ -727,7 +727,7 @@ void _swapPS0PS1(x64GenContext_t* x64GenContext, sint32 xmmReg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FPR op FPR
|
// FPR op FPR
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||||
if( imlInstruction->operation == PPCREC_IML_OP_FPR_COPY_BOTTOM_TO_BOTTOM_AND_TOP )
|
if( imlInstruction->operation == PPCREC_IML_OP_FPR_COPY_BOTTOM_TO_BOTTOM_AND_TOP )
|
||||||
|
@ -1006,7 +1006,7 @@ void PPCRecompilerX64Gen_imlInstruction_fpr_r_r(PPCRecFunction_t* PPCRecFunction
|
||||||
/*
|
/*
|
||||||
* FPR = op (fprA, fprB)
|
* FPR = op (fprA, fprB)
|
||||||
*/
|
*/
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||||
|
|
||||||
|
@ -1099,7 +1099,7 @@ void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r(PPCRecFunction_t* PPCRecFuncti
|
||||||
/*
|
/*
|
||||||
* FPR = op (fprA, fprB, fprC)
|
* FPR = op (fprA, fprB, fprC)
|
||||||
*/
|
*/
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||||
if( imlInstruction->operation == PPCREC_IML_OP_FPR_SUM0 )
|
if( imlInstruction->operation == PPCREC_IML_OP_FPR_SUM0 )
|
||||||
|
@ -1193,7 +1193,7 @@ void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r_r(PPCRecFunction_t* PPCRecFunc
|
||||||
/*
|
/*
|
||||||
* Single FPR operation
|
* Single FPR operation
|
||||||
*/
|
*/
|
||||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
void PPCRecompilerX64Gen_imlInstruction_fpr_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||||
if( imlInstruction->operation == PPCREC_IML_OP_FPR_NEGATE_BOTTOM )
|
if( imlInstruction->operation == PPCREC_IML_OP_FPR_NEGATE_BOTTOM )
|
||||||
|
|
Loading…
Add table
Reference in a new issue