mirror of https://github.com/PCSX2/pcsx2.git
commit
5b74374bb2
|
@ -30,11 +30,7 @@ struct _SimdShiftHelper
|
||||||
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||||
|
|
||||||
void operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const;
|
|
||||||
void operator()( const xRegisterMMX& to, const xIndirectVoid& from ) const;
|
|
||||||
|
|
||||||
void operator()( const xRegisterSSE& to, u8 imm8 ) const;
|
void operator()( const xRegisterSSE& to, u8 imm8 ) const;
|
||||||
void operator()( const xRegisterMMX& to, u8 imm8 ) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -96,12 +96,10 @@ struct xImplSimd_PMinMax
|
||||||
{
|
{
|
||||||
// Compare packed unsigned byte integers in dest to src and store packed min/max
|
// Compare packed unsigned byte integers in dest to src and store packed min/max
|
||||||
// values in dest.
|
// values in dest.
|
||||||
// Operation can be performed on either MMX or SSE operands.
|
|
||||||
const xImplSimd_DestRegEither UB;
|
const xImplSimd_DestRegEither UB;
|
||||||
|
|
||||||
// Compare packed signed word integers in dest to src and store packed min/max
|
// Compare packed signed word integers in dest to src and store packed min/max
|
||||||
// values in dest.
|
// values in dest.
|
||||||
// Operation can be performed on either MMX or SSE operands.
|
|
||||||
const xImplSimd_DestRegEither SW;
|
const xImplSimd_DestRegEither SW;
|
||||||
|
|
||||||
// [SSE-4.1] Compare packed signed byte integers in dest to src and store
|
// [SSE-4.1] Compare packed signed byte integers in dest to src and store
|
||||||
|
|
|
@ -56,17 +56,8 @@ struct xImplSimd_DestSSE_CmpImm
|
||||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm ) const;
|
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xImplSimd_DestRegImmMMX
|
|
||||||
{
|
|
||||||
u8 Prefix;
|
|
||||||
u16 Opcode;
|
|
||||||
|
|
||||||
void operator()( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm ) const;
|
|
||||||
void operator()( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm ) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// For implementing MMX/SSE operations that have reg,reg/rm forms only,
|
// For implementing SSE operations that have reg,reg/rm forms only,
|
||||||
// but accept either MM or XMM destinations (most PADD/PSUB and other P arithmetic ops).
|
// but accept either MM or XMM destinations (most PADD/PSUB and other P arithmetic ops).
|
||||||
//
|
//
|
||||||
struct xImplSimd_DestRegEither
|
struct xImplSimd_DestRegEither
|
||||||
|
@ -76,9 +67,6 @@ struct xImplSimd_DestRegEither
|
||||||
|
|
||||||
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||||
|
|
||||||
void operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const;
|
|
||||||
void operator()( const xRegisterMMX& to, const xIndirectVoid& from ) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace x86Emitter
|
} // end namespace x86Emitter
|
||||||
|
|
|
@ -36,10 +36,6 @@ struct xImplSimd_Shuffle
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
struct xImplSimd_PShuffle
|
struct xImplSimd_PShuffle
|
||||||
{
|
{
|
||||||
// Copies words from src and inserts them into dest at word locations selected with
|
|
||||||
// the order operand (8 bit immediate).
|
|
||||||
const xImplSimd_DestRegImmMMX W;
|
|
||||||
|
|
||||||
// Copies doublewords from src and inserts them into dest at dword locations selected
|
// Copies doublewords from src and inserts them into dest at dword locations selected
|
||||||
// with the order operand (8 bit immediate).
|
// with the order operand (8 bit immediate).
|
||||||
const xImplSimd_DestRegImmSSE D;
|
const xImplSimd_DestRegImmSSE D;
|
||||||
|
@ -61,7 +57,6 @@ struct xImplSimd_PShuffle
|
||||||
// byte in dest. The value of each index is the least significant 4 bits (128-bit
|
// byte in dest. The value of each index is the least significant 4 bits (128-bit
|
||||||
// operation) or 3 bits (64-bit operation) of the shuffle control byte.
|
// operation) or 3 bits (64-bit operation) of the shuffle control byte.
|
||||||
//
|
//
|
||||||
// Operands can be MMX or XMM registers.
|
|
||||||
const xImplSimd_DestRegEither B;
|
const xImplSimd_DestRegEither B;
|
||||||
|
|
||||||
// below is my test bed for a new system, free of subclasses. Was supposed to improve intellisense
|
// below is my test bed for a new system, free of subclasses. Was supposed to improve intellisense
|
||||||
|
@ -70,8 +65,6 @@ struct xImplSimd_PShuffle
|
||||||
#if 0
|
#if 0
|
||||||
// Copies words from src and inserts them into dest at word locations selected with
|
// Copies words from src and inserts them into dest at word locations selected with
|
||||||
// the order operand (8 bit immediate).
|
// the order operand (8 bit immediate).
|
||||||
void W( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm ) const { xOpWrite0F( 0x70, to, from, imm ); }
|
|
||||||
void W( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( 0x70, to, from, imm ); }
|
|
||||||
|
|
||||||
// Copies doublewords from src and inserts them into dest at dword locations selected
|
// Copies doublewords from src and inserts them into dest at dword locations selected
|
||||||
// with the order operand (8 bit immediate).
|
// with the order operand (8 bit immediate).
|
||||||
|
@ -97,11 +90,8 @@ struct xImplSimd_PShuffle
|
||||||
// byte in dest. The value of each index is the least significant 4 bits (128-bit
|
// byte in dest. The value of each index is the least significant 4 bits (128-bit
|
||||||
// operation) or 3 bits (64-bit operation) of the shuffle control byte.
|
// operation) or 3 bits (64-bit operation) of the shuffle control byte.
|
||||||
//
|
//
|
||||||
// Operands can be MMX or XMM registers.
|
|
||||||
void B( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
|
void B( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
|
||||||
void B( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
|
void B( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
|
||||||
void B( const xRegisterMMX& to, const xRegisterMMX& from ) const { OpWriteSSE( 0x00, 0x0038 ); }
|
|
||||||
void B( const xRegisterMMX& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x00, 0x0038 ); }
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,9 +204,6 @@ struct xImplSimd_PInsert
|
||||||
void W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const;
|
void W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const;
|
||||||
void W( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const;
|
void W( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const;
|
||||||
|
|
||||||
void W( const xRegisterMMX& to, const xRegister32& from, u8 imm8 ) const;
|
|
||||||
void W( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm8 ) const;
|
|
||||||
|
|
||||||
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
|
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
|
||||||
xImplSimd_InsertExtractHelper B;
|
xImplSimd_InsertExtractHelper B;
|
||||||
|
|
||||||
|
@ -239,7 +226,6 @@ struct SimdImpl_PExtract
|
||||||
// [SSE-4.1] Note: Indirect memory forms of this instruction are an SSE-4.1 extension!
|
// [SSE-4.1] Note: Indirect memory forms of this instruction are an SSE-4.1 extension!
|
||||||
//
|
//
|
||||||
void W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const;
|
void W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const;
|
||||||
void W( const xRegister32& to, const xRegisterMMX& from, u8 imm8 ) const;
|
|
||||||
void W( const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8 ) const;
|
void W( const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8 ) const;
|
||||||
|
|
||||||
// [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits
|
// [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits
|
||||||
|
|
|
@ -339,22 +339,10 @@ namespace x86Emitter
|
||||||
extern void xMOVDZX( const xRegisterSSE& to, const xRegister32or64& from );
|
extern void xMOVDZX( const xRegisterSSE& to, const xRegister32or64& from );
|
||||||
extern void xMOVDZX( const xRegisterSSE& to, const xIndirectVoid& src );
|
extern void xMOVDZX( const xRegisterSSE& to, const xIndirectVoid& src );
|
||||||
|
|
||||||
extern void xMOVDZX( const xRegisterMMX& to, const xRegister32or64& from );
|
|
||||||
extern void xMOVDZX( const xRegisterMMX& to, const xIndirectVoid& src );
|
|
||||||
|
|
||||||
extern void xMOVD( const xRegister32or64& to, const xRegisterSSE& from );
|
extern void xMOVD( const xRegister32or64& to, const xRegisterSSE& from );
|
||||||
extern void xMOVD( const xIndirectVoid& dest, const xRegisterSSE& from );
|
extern void xMOVD( const xIndirectVoid& dest, const xRegisterSSE& from );
|
||||||
|
|
||||||
extern void xMOVD( const xRegister32or64& to, const xRegisterMMX& from );
|
|
||||||
extern void xMOVD( const xIndirectVoid& dest, const xRegisterMMX& from );
|
|
||||||
|
|
||||||
extern void xMOVQ( const xRegisterMMX& to, const xRegisterMMX& from );
|
|
||||||
extern void xMOVQ( const xRegisterMMX& to, const xRegisterSSE& from );
|
|
||||||
extern void xMOVQ( const xRegisterSSE& to, const xRegisterMMX& from );
|
|
||||||
|
|
||||||
extern void xMOVQ( const xIndirectVoid& dest, const xRegisterSSE& from );
|
extern void xMOVQ( const xIndirectVoid& dest, const xRegisterSSE& from );
|
||||||
extern void xMOVQ( const xIndirectVoid& dest, const xRegisterMMX& from );
|
|
||||||
extern void xMOVQ( const xRegisterMMX& to, const xIndirectVoid& src );
|
|
||||||
|
|
||||||
extern void xMOVQZX( const xRegisterSSE& to, const xIndirectVoid& src );
|
extern void xMOVQZX( const xRegisterSSE& to, const xIndirectVoid& src );
|
||||||
extern void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from );
|
extern void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||||
|
@ -372,17 +360,13 @@ namespace x86Emitter
|
||||||
|
|
||||||
extern void xMOVNTPD( const xIndirectVoid& to, const xRegisterSSE& from );
|
extern void xMOVNTPD( const xIndirectVoid& to, const xRegisterSSE& from );
|
||||||
extern void xMOVNTPS( const xIndirectVoid& to, const xRegisterSSE& from );
|
extern void xMOVNTPS( const xIndirectVoid& to, const xRegisterSSE& from );
|
||||||
extern void xMOVNTQ( const xIndirectVoid& to, const xRegisterMMX& from );
|
|
||||||
|
|
||||||
extern void xMOVMSKPS( const xRegister32or64& to, const xRegisterSSE& from );
|
extern void xMOVMSKPS( const xRegister32or64& to, const xRegisterSSE& from );
|
||||||
extern void xMOVMSKPD( const xRegister32or64& to, const xRegisterSSE& from );
|
extern void xMOVMSKPD( const xRegister32or64& to, const xRegisterSSE& from );
|
||||||
|
|
||||||
extern void xMASKMOV( const xRegisterSSE& to, const xRegisterSSE& from );
|
extern void xMASKMOV( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||||
extern void xMASKMOV( const xRegisterMMX& to, const xRegisterMMX& from );
|
|
||||||
extern void xPMOVMSKB( const xRegister32or64& to, const xRegisterSSE& from );
|
extern void xPMOVMSKB( const xRegister32or64& to, const xRegisterSSE& from );
|
||||||
extern void xPMOVMSKB( const xRegister32or64& to, const xRegisterMMX& from );
|
|
||||||
extern void xPALIGNR( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
|
extern void xPALIGNR( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
|
||||||
extern void xPALIGNR( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm8 );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -455,29 +439,21 @@ namespace x86Emitter
|
||||||
|
|
||||||
extern void xCVTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
extern void xCVTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||||
extern void xCVTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
extern void xCVTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
||||||
extern void xCVTPD2PI( const xRegisterMMX& to, const xRegisterSSE& from );
|
|
||||||
extern void xCVTPD2PI( const xRegisterMMX& to, const xIndirect128& from );
|
|
||||||
extern void xCVTPD2PS( const xRegisterSSE& to, const xRegisterSSE& from );
|
extern void xCVTPD2PS( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||||
extern void xCVTPD2PS( const xRegisterSSE& to, const xIndirect128& from );
|
extern void xCVTPD2PS( const xRegisterSSE& to, const xIndirect128& from );
|
||||||
|
|
||||||
extern void xCVTPI2PD( const xRegisterSSE& to, const xRegisterMMX& from );
|
|
||||||
extern void xCVTPI2PD( const xRegisterSSE& to, const xIndirect64& from );
|
extern void xCVTPI2PD( const xRegisterSSE& to, const xIndirect64& from );
|
||||||
extern void xCVTPI2PS( const xRegisterSSE& to, const xRegisterMMX& from );
|
|
||||||
extern void xCVTPI2PS( const xRegisterSSE& to, const xIndirect64& from );
|
extern void xCVTPI2PS( const xRegisterSSE& to, const xIndirect64& from );
|
||||||
|
|
||||||
extern void xCVTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
extern void xCVTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||||
extern void xCVTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
extern void xCVTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
||||||
extern void xCVTPS2PD( const xRegisterSSE& to, const xRegisterSSE& from );
|
extern void xCVTPS2PD( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||||
extern void xCVTPS2PD( const xRegisterSSE& to, const xIndirect64& from );
|
extern void xCVTPS2PD( const xRegisterSSE& to, const xIndirect64& from );
|
||||||
extern void xCVTPS2PI( const xRegisterMMX& to, const xRegisterSSE& from );
|
|
||||||
extern void xCVTPS2PI( const xRegisterMMX& to, const xIndirect64& from );
|
|
||||||
|
|
||||||
extern void xCVTSD2SI( const xRegister32or64& to, const xRegisterSSE& from );
|
extern void xCVTSD2SI( const xRegister32or64& to, const xRegisterSSE& from );
|
||||||
extern void xCVTSD2SI( const xRegister32or64& to, const xIndirect64& from );
|
extern void xCVTSD2SI( const xRegister32or64& to, const xIndirect64& from );
|
||||||
extern void xCVTSD2SS( const xRegisterSSE& to, const xRegisterSSE& from );
|
extern void xCVTSD2SS( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||||
extern void xCVTSD2SS( const xRegisterSSE& to, const xIndirect64& from );
|
extern void xCVTSD2SS( const xRegisterSSE& to, const xIndirect64& from );
|
||||||
extern void xCVTSI2SD( const xRegisterMMX& to, const xRegister32or64& from );
|
|
||||||
extern void xCVTSI2SD( const xRegisterMMX& to, const xIndirect32& from );
|
|
||||||
extern void xCVTSI2SS( const xRegisterSSE& to, const xRegister32or64& from );
|
extern void xCVTSI2SS( const xRegisterSSE& to, const xRegister32or64& from );
|
||||||
extern void xCVTSI2SS( const xRegisterSSE& to, const xIndirect32& from );
|
extern void xCVTSI2SS( const xRegisterSSE& to, const xIndirect32& from );
|
||||||
|
|
||||||
|
@ -488,12 +464,8 @@ namespace x86Emitter
|
||||||
|
|
||||||
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||||
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
||||||
extern void xCVTTPD2PI( const xRegisterMMX& to, const xRegisterSSE& from );
|
|
||||||
extern void xCVTTPD2PI( const xRegisterMMX& to, const xIndirect128& from );
|
|
||||||
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||||
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
||||||
extern void xCVTTPS2PI( const xRegisterMMX& to, const xRegisterSSE& from );
|
|
||||||
extern void xCVTTPS2PI( const xRegisterMMX& to, const xIndirect64& from );
|
|
||||||
|
|
||||||
extern void xCVTTSD2SI( const xRegister32or64& to, const xRegisterSSE& from );
|
extern void xCVTTSD2SI( const xRegister32or64& to, const xRegisterSSE& from );
|
||||||
extern void xCVTTSD2SI( const xRegister32or64& to, const xIndirect64& from );
|
extern void xCVTTSD2SI( const xRegister32or64& to, const xIndirect64& from );
|
||||||
|
|
|
@ -21,5 +21,4 @@
|
||||||
|
|
||||||
// general types
|
// general types
|
||||||
typedef int x86IntRegType;
|
typedef int x86IntRegType;
|
||||||
typedef int x86MMXRegType;
|
|
||||||
typedef int x86SSERegType;
|
typedef int x86SSERegType;
|
||||||
|
|
|
@ -73,7 +73,6 @@ public:
|
||||||
u32 hasCFLUSHInstruction :1;
|
u32 hasCFLUSHInstruction :1;
|
||||||
u32 hasDebugStore :1;
|
u32 hasDebugStore :1;
|
||||||
u32 hasACPIThermalMonitorAndClockControl :1;
|
u32 hasACPIThermalMonitorAndClockControl :1;
|
||||||
u32 hasMultimediaExtensions :1;
|
|
||||||
u32 hasFastStreamingSIMDExtensionsSaveRestore :1;
|
u32 hasFastStreamingSIMDExtensionsSaveRestore :1;
|
||||||
u32 hasStreamingSIMDExtensions :1;
|
u32 hasStreamingSIMDExtensions :1;
|
||||||
u32 hasStreamingSIMD2Extensions :1;
|
u32 hasStreamingSIMD2Extensions :1;
|
||||||
|
@ -95,10 +94,7 @@ public:
|
||||||
u32 hasFMA :1;
|
u32 hasFMA :1;
|
||||||
|
|
||||||
// AMD-specific CPU Features
|
// AMD-specific CPU Features
|
||||||
u32 hasMultimediaExtensionsExt :1;
|
|
||||||
u32 hasAMD64BitArchitecture :1;
|
u32 hasAMD64BitArchitecture :1;
|
||||||
u32 has3DNOWInstructionExtensionsExt :1;
|
|
||||||
u32 has3DNOWInstructionExtensions :1;
|
|
||||||
u32 hasStreamingSIMD4ExtensionsA :1;
|
u32 hasStreamingSIMD4ExtensionsA :1;
|
||||||
|
|
||||||
// Core Counts!
|
// Core Counts!
|
||||||
|
|
|
@ -18,12 +18,10 @@
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
static const uint iREGCNT_XMM = 16;
|
static const uint iREGCNT_XMM = 16;
|
||||||
static const uint iREGCNT_GPR = 16;
|
static const uint iREGCNT_GPR = 16;
|
||||||
static const uint iREGCNT_MMX = 8; // FIXME: port the code and remove MMX
|
|
||||||
#else
|
#else
|
||||||
// Register counts for x86/32 mode:
|
// Register counts for x86/32 mode:
|
||||||
static const uint iREGCNT_XMM = 8;
|
static const uint iREGCNT_XMM = 8;
|
||||||
static const uint iREGCNT_GPR = 8;
|
static const uint iREGCNT_GPR = 8;
|
||||||
static const uint iREGCNT_MMX = 8;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum XMMSSEType
|
enum XMMSSEType
|
||||||
|
@ -233,7 +231,7 @@ template< typename T > void xWrite( T val );
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// xRegisterBase - type-unsafe x86 register representation.
|
// xRegisterBase - type-unsafe x86 register representation.
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// Unless doing some fundamental stuff, use the friendly xRegister32/16/8 and xRegisterSSE/MMX
|
// Unless doing some fundamental stuff, use the friendly xRegister32/16/8 and xRegisterSSE
|
||||||
// instead, which are built using this class and provide strict register type safety when
|
// instead, which are built using this class and provide strict register type safety when
|
||||||
// passed into emitter instructions.
|
// passed into emitter instructions.
|
||||||
//
|
//
|
||||||
|
@ -264,14 +262,13 @@ template< typename T > void xWrite( T val );
|
||||||
// Returns true if the register is a valid accumulator: Eax, Ax, Al, XMM0.
|
// Returns true if the register is a valid accumulator: Eax, Ax, Al, XMM0.
|
||||||
bool IsAccumulator() const { return Id == 0; }
|
bool IsAccumulator() const { return Id == 0; }
|
||||||
|
|
||||||
// IsSIMD: returns true if the register is a valid MMX or XMM register.
|
// IsSIMD: returns true if the register is a valid XMM register.
|
||||||
|
bool IsSIMD() const { return GetOperandSize() == 16; }
|
||||||
|
|
||||||
// IsWide: return true if the register is 64 bits (requires a wide op on the rex prefix)
|
// IsWide: return true if the register is 64 bits (requires a wide op on the rex prefix)
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
// No MMX on 64 bits, let's directly uses GPR
|
|
||||||
bool IsSIMD() const { return GetOperandSize() == 16; }
|
|
||||||
bool IsWide() const { return GetOperandSize() == 8; }
|
bool IsWide() const { return GetOperandSize() == 8; }
|
||||||
#else
|
#else
|
||||||
bool IsSIMD() const { return GetOperandSize() == 8 || GetOperandSize() == 16; }
|
|
||||||
bool IsWide() const { return false; } // no 64 bits GPR
|
bool IsWide() const { return false; } // no 64 bits GPR
|
||||||
#endif
|
#endif
|
||||||
// return true if the register is a valid YMM register
|
// return true if the register is a valid YMM register
|
||||||
|
@ -359,29 +356,10 @@ template< typename T > void xWrite( T val );
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// xRegisterMMX/SSE - Represents either a 64 bit or 128 bit SIMD register
|
// xRegisterSSE - Represents either a 64 bit or 128 bit SIMD register
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// This register type is provided to allow legal syntax for instructions that accept either
|
// This register type is provided to allow legal syntax for instructions that accept
|
||||||
// an XMM or MMX register as a parameter, but do not allow for a GPR.
|
// an XMM register as a parameter, but do not allow for a GPR.
|
||||||
|
|
||||||
class xRegisterMMX : public xRegisterBase
|
|
||||||
{
|
|
||||||
typedef xRegisterBase _parent;
|
|
||||||
|
|
||||||
public:
|
|
||||||
xRegisterMMX(): _parent() {
|
|
||||||
#ifdef __x86_64__
|
|
||||||
pxAssert(0); // Sorry but code must be ported
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
//xRegisterMMX( const xRegisterBase& src ) : _parent( src ) {}
|
|
||||||
explicit xRegisterMMX( int regId ) : _parent( regId ) {}
|
|
||||||
|
|
||||||
virtual uint GetOperandSize() const { return 8; }
|
|
||||||
|
|
||||||
bool operator==( const xRegisterMMX& src ) const { return this->Id == src.Id; }
|
|
||||||
bool operator!=( const xRegisterMMX& src ) const { return this->Id != src.Id; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class xRegisterSSE : public xRegisterBase
|
class xRegisterSSE : public xRegisterBase
|
||||||
{
|
{
|
||||||
|
@ -473,12 +451,6 @@ template< typename T > void xWrite( T val );
|
||||||
return xRegister16( xRegId_Empty );
|
return xRegister16( xRegId_Empty );
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME remove it in x86 64
|
|
||||||
operator xRegisterMMX() const
|
|
||||||
{
|
|
||||||
return xRegisterMMX( xRegId_Empty );
|
|
||||||
}
|
|
||||||
|
|
||||||
operator xRegisterSSE() const
|
operator xRegisterSSE() const
|
||||||
{
|
{
|
||||||
return xRegisterSSE( xRegId_Empty );
|
return xRegisterSSE( xRegId_Empty );
|
||||||
|
@ -551,10 +523,6 @@ template< typename T > void xWrite( T val );
|
||||||
xmm8, xmm9, xmm10, xmm11,
|
xmm8, xmm9, xmm10, xmm11,
|
||||||
xmm12, xmm13, xmm14, xmm15;
|
xmm12, xmm13, xmm14, xmm15;
|
||||||
|
|
||||||
extern const xRegisterMMX
|
|
||||||
mm0, mm1, mm2, mm3,
|
|
||||||
mm4, mm5, mm6, mm7;
|
|
||||||
|
|
||||||
extern const xAddressReg
|
extern const xAddressReg
|
||||||
rax, rbx, rcx, rdx,
|
rax, rbx, rcx, rdx,
|
||||||
rsi, rdi, rbp, rsp,
|
rsi, rdi, rbp, rsp,
|
||||||
|
@ -943,7 +911,6 @@ template< typename T > void xWrite( T val );
|
||||||
typedef xDirectOrIndirect<xRegister8,xIndirect8> xDirectOrIndirect8;
|
typedef xDirectOrIndirect<xRegister8,xIndirect8> xDirectOrIndirect8;
|
||||||
typedef xDirectOrIndirect<xRegister16,xIndirect16> xDirectOrIndirect16;
|
typedef xDirectOrIndirect<xRegister16,xIndirect16> xDirectOrIndirect16;
|
||||||
typedef xDirectOrIndirect<xRegister32,xIndirect32> xDirectOrIndirect32;
|
typedef xDirectOrIndirect<xRegister32,xIndirect32> xDirectOrIndirect32;
|
||||||
typedef xDirectOrIndirect<xRegisterMMX,xIndirect64> xDirectOrIndirect64;
|
|
||||||
typedef xDirectOrIndirect<xRegisterSSE,xIndirect128> xDirectOrIndirect128;
|
typedef xDirectOrIndirect<xRegisterSSE,xIndirect128> xDirectOrIndirect128;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,6 @@ void x86capabilities::Identify()
|
||||||
hasCFLUSHInstruction = ( Flags >> 19 ) & 1;
|
hasCFLUSHInstruction = ( Flags >> 19 ) & 1;
|
||||||
hasDebugStore = ( Flags >> 21 ) & 1;
|
hasDebugStore = ( Flags >> 21 ) & 1;
|
||||||
hasACPIThermalMonitorAndClockControl = ( Flags >> 22 ) & 1;
|
hasACPIThermalMonitorAndClockControl = ( Flags >> 22 ) & 1;
|
||||||
hasMultimediaExtensions = ( Flags >> 23 ) & 1; //mmx
|
|
||||||
hasFastStreamingSIMDExtensionsSaveRestore = ( Flags >> 24 ) & 1;
|
hasFastStreamingSIMDExtensionsSaveRestore = ( Flags >> 24 ) & 1;
|
||||||
hasStreamingSIMDExtensions = ( Flags >> 25 ) & 1; //sse
|
hasStreamingSIMDExtensions = ( Flags >> 25 ) & 1; //sse
|
||||||
hasStreamingSIMD2Extensions = ( Flags >> 26 ) & 1; //sse2
|
hasStreamingSIMD2Extensions = ( Flags >> 26 ) & 1; //sse2
|
||||||
|
@ -282,10 +281,7 @@ void x86capabilities::Identify()
|
||||||
hasBMI2 = ( SEFlag >> 8 ) & 1;
|
hasBMI2 = ( SEFlag >> 8 ) & 1;
|
||||||
|
|
||||||
// Ones only for AMDs:
|
// Ones only for AMDs:
|
||||||
hasMultimediaExtensionsExt = ( EFlags >> 22 ) & 1; //mmx2
|
|
||||||
hasAMD64BitArchitecture = ( EFlags >> 29 ) & 1; //64bit cpu
|
hasAMD64BitArchitecture = ( EFlags >> 29 ) & 1; //64bit cpu
|
||||||
has3DNOWInstructionExtensionsExt = ( EFlags >> 30 ) & 1; //3dnow+
|
|
||||||
has3DNOWInstructionExtensions = ( EFlags >> 31 ) & 1; //3dnow
|
|
||||||
hasStreamingSIMD4ExtensionsA = ( EFlags2 >> 6 ) & 1; //INSERTQ / EXTRQ / MOVNT
|
hasStreamingSIMD4ExtensionsA = ( EFlags2 >> 6 ) & 1; //INSERTQ / EXTRQ / MOVNT
|
||||||
|
|
||||||
isIdentified = true;
|
isIdentified = true;
|
||||||
|
|
|
@ -145,29 +145,21 @@ __fi void xCVTDQ2PS( const xRegisterSSE& to, const xIndirect128& from ) { OpWri
|
||||||
|
|
||||||
__fi void xCVTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0xe6 ); }
|
__fi void xCVTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0xe6 ); }
|
||||||
__fi void xCVTPD2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0xf2, 0xe6 ); }
|
__fi void xCVTPD2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0xf2, 0xe6 ); }
|
||||||
__fi void xCVTPD2PI( const xRegisterMMX& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x2d ); }
|
|
||||||
__fi void xCVTPD2PI( const xRegisterMMX& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x2d ); }
|
|
||||||
__fi void xCVTPD2PS( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x5a ); }
|
__fi void xCVTPD2PS( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x5a ); }
|
||||||
__fi void xCVTPD2PS( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x5a ); }
|
__fi void xCVTPD2PS( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x5a ); }
|
||||||
|
|
||||||
__fi void xCVTPI2PD( const xRegisterSSE& to, const xRegisterMMX& from ) { OpWriteSSE( 0x66, 0x2a ); }
|
|
||||||
__fi void xCVTPI2PD( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0x66, 0x2a ); }
|
__fi void xCVTPI2PD( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0x66, 0x2a ); }
|
||||||
__fi void xCVTPI2PS( const xRegisterSSE& to, const xRegisterMMX& from ) { OpWriteSSE( 0x00, 0x2a ); }
|
|
||||||
__fi void xCVTPI2PS( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x2a ); }
|
__fi void xCVTPI2PS( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x2a ); }
|
||||||
|
|
||||||
__fi void xCVTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x5b ); }
|
__fi void xCVTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x5b ); }
|
||||||
__fi void xCVTPS2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x5b ); }
|
__fi void xCVTPS2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x5b ); }
|
||||||
__fi void xCVTPS2PD( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x00, 0x5a ); }
|
__fi void xCVTPS2PD( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x00, 0x5a ); }
|
||||||
__fi void xCVTPS2PD( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x5a ); }
|
__fi void xCVTPS2PD( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x5a ); }
|
||||||
__fi void xCVTPS2PI( const xRegisterMMX& to, const xRegisterSSE& from ) { OpWriteSSE( 0x00, 0x2d ); }
|
|
||||||
__fi void xCVTPS2PI( const xRegisterMMX& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x2d ); }
|
|
||||||
|
|
||||||
__fi void xCVTSD2SI( const xRegister32or64& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0x2d ); }
|
__fi void xCVTSD2SI( const xRegister32or64& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0x2d ); }
|
||||||
__fi void xCVTSD2SI( const xRegister32or64& to, const xIndirect64& from ) { OpWriteSSE( 0xf2, 0x2d ); }
|
__fi void xCVTSD2SI( const xRegister32or64& to, const xIndirect64& from ) { OpWriteSSE( 0xf2, 0x2d ); }
|
||||||
__fi void xCVTSD2SS( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0x5a ); }
|
__fi void xCVTSD2SS( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0x5a ); }
|
||||||
__fi void xCVTSD2SS( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0xf2, 0x5a ); }
|
__fi void xCVTSD2SS( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0xf2, 0x5a ); }
|
||||||
__fi void xCVTSI2SD( const xRegisterMMX& to, const xRegister32or64& from ) { OpWriteSSE( 0xf2, 0x2a ); }
|
|
||||||
__fi void xCVTSI2SD( const xRegisterMMX& to, const xIndirect32& from ) { OpWriteSSE( 0xf2, 0x2a ); }
|
|
||||||
__fi void xCVTSI2SS( const xRegisterSSE& to, const xRegister32or64& from ) { OpWriteSSE( 0xf3, 0x2a ); }
|
__fi void xCVTSI2SS( const xRegisterSSE& to, const xRegister32or64& from ) { OpWriteSSE( 0xf3, 0x2a ); }
|
||||||
__fi void xCVTSI2SS( const xRegisterSSE& to, const xIndirect32& from ) { OpWriteSSE( 0xf3, 0x2a ); }
|
__fi void xCVTSI2SS( const xRegisterSSE& to, const xIndirect32& from ) { OpWriteSSE( 0xf3, 0x2a ); }
|
||||||
|
|
||||||
|
@ -178,12 +170,8 @@ __fi void xCVTSS2SI( const xRegister32or64& to, const xIndirect32& from ) { Op
|
||||||
|
|
||||||
__fi void xCVTTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0xe6 ); }
|
__fi void xCVTTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0xe6 ); }
|
||||||
__fi void xCVTTPD2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0xe6 ); }
|
__fi void xCVTTPD2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0xe6 ); }
|
||||||
__fi void xCVTTPD2PI( const xRegisterMMX& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x2c ); }
|
|
||||||
__fi void xCVTTPD2PI( const xRegisterMMX& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x2c ); }
|
|
||||||
__fi void xCVTTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf3, 0x5b ); }
|
__fi void xCVTTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf3, 0x5b ); }
|
||||||
__fi void xCVTTPS2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0xf3, 0x5b ); }
|
__fi void xCVTTPS2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0xf3, 0x5b ); }
|
||||||
__fi void xCVTTPS2PI( const xRegisterMMX& to, const xRegisterSSE& from ) { OpWriteSSE( 0x00, 0x2c ); }
|
|
||||||
__fi void xCVTTPS2PI( const xRegisterMMX& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x2c ); }
|
|
||||||
|
|
||||||
__fi void xCVTTSD2SI( const xRegister32or64& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0x2c ); }
|
__fi void xCVTTSD2SI( const xRegister32or64& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0x2c ); }
|
||||||
__fi void xCVTTSD2SI( const xRegister32or64& to, const xIndirect64& from ) { OpWriteSSE( 0xf2, 0x2c ); }
|
__fi void xCVTTSD2SI( const xRegister32or64& to, const xIndirect64& from ) { OpWriteSSE( 0xf2, 0x2c ); }
|
||||||
|
@ -199,14 +187,10 @@ void xImplSimd_DestRegSSE::operator()( const xRegisterSSE& to, const xIndirectVo
|
||||||
void xImplSimd_DestRegImmSSE::operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
void xImplSimd_DestRegImmSSE::operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||||
void xImplSimd_DestRegImmSSE::operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
void xImplSimd_DestRegImmSSE::operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||||
|
|
||||||
void xImplSimd_DestRegImmMMX::operator()( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); }
|
|
||||||
void xImplSimd_DestRegImmMMX::operator()( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); }
|
|
||||||
|
|
||||||
void xImplSimd_DestRegEither::operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
void xImplSimd_DestRegEither::operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||||
void xImplSimd_DestRegEither::operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
void xImplSimd_DestRegEither::operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||||
|
|
||||||
void xImplSimd_DestRegEither::operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
|
||||||
void xImplSimd_DestRegEither::operator()( const xRegisterMMX& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
|
||||||
|
|
||||||
void xImplSimd_DestSSE_CmpImm::operator()( const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
void xImplSimd_DestSSE_CmpImm::operator()( const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||||
void xImplSimd_DestSSE_CmpImm::operator()( const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
void xImplSimd_DestSSE_CmpImm::operator()( const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||||
|
@ -218,8 +202,6 @@ void xImplSimd_DestSSE_CmpImm::operator()( const xRegisterSSE& to, const xIndire
|
||||||
void _SimdShiftHelper::operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
void _SimdShiftHelper::operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||||
void _SimdShiftHelper::operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
void _SimdShiftHelper::operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||||
|
|
||||||
void _SimdShiftHelper::operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
|
||||||
void _SimdShiftHelper::operator()( const xRegisterMMX& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
|
||||||
|
|
||||||
void _SimdShiftHelper::operator()( const xRegisterSSE& to, u8 imm8 ) const
|
void _SimdShiftHelper::operator()( const xRegisterSSE& to, u8 imm8 ) const
|
||||||
{
|
{
|
||||||
|
@ -227,12 +209,6 @@ void _SimdShiftHelper::operator()( const xRegisterSSE& to, u8 imm8 ) const
|
||||||
xWrite8( imm8 );
|
xWrite8( imm8 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void _SimdShiftHelper::operator()( const xRegisterMMX& to, u8 imm8 ) const
|
|
||||||
{
|
|
||||||
xOpWrite0F( 0x00, OpcodeImm, (int)Modcode, to );
|
|
||||||
xWrite8( imm8 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void xImplSimd_Shift::DQ( const xRegisterSSE& to, u8 imm8 ) const
|
void xImplSimd_Shift::DQ( const xRegisterSSE& to, u8 imm8 ) const
|
||||||
{
|
{
|
||||||
xOpWrite0F( 0x66, 0x73, (int)Q.Modcode+1, to, imm8 );
|
xOpWrite0F( 0x66, 0x73, (int)Q.Modcode+1, to, imm8 );
|
||||||
|
@ -495,18 +471,14 @@ void xImplSimd_InsertExtractHelper::operator()( const xRegisterSSE& to, const xI
|
||||||
|
|
||||||
void xImplSimd_PInsert::W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
void xImplSimd_PInsert::W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
||||||
void xImplSimd_PInsert::W( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
void xImplSimd_PInsert::W( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
||||||
void xImplSimd_PInsert::W( const xRegisterMMX& to, const xRegister32& from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); }
|
|
||||||
void xImplSimd_PInsert::W( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); }
|
|
||||||
|
|
||||||
void SimdImpl_PExtract::W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc5, to, from, imm8 ); }
|
void SimdImpl_PExtract::W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc5, to, from, imm8 ); }
|
||||||
void SimdImpl_PExtract::W( const xRegister32& to, const xRegisterMMX& from, u8 imm8 ) const { xOpWrite0F( 0xc5, to, from, imm8 ); }
|
|
||||||
void SimdImpl_PExtract::W( const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0x153a, from, dest, imm8 ); }
|
void SimdImpl_PExtract::W( const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0x153a, from, dest, imm8 ); }
|
||||||
|
|
||||||
const xImplSimd_Shuffle xSHUF = { };
|
const xImplSimd_Shuffle xSHUF = { };
|
||||||
|
|
||||||
const xImplSimd_PShuffle xPSHUF =
|
const xImplSimd_PShuffle xPSHUF =
|
||||||
{
|
{
|
||||||
{ 0x00, 0x70 }, // W
|
|
||||||
{ 0x66, 0x70 }, // D
|
{ 0x66, 0x70 }, // D
|
||||||
{ 0xf2, 0x70 }, // LW
|
{ 0xf2, 0x70 }, // LW
|
||||||
{ 0xf3, 0x70 }, // HW
|
{ 0xf3, 0x70 }, // HW
|
||||||
|
@ -689,16 +661,9 @@ const xImplSimd_DestRegSSE xMOVSHDUP = { 0xf3,0x16 };
|
||||||
__fi void xMOVDZX( const xRegisterSSE& to, const xRegister32or64& from ) { xOpWrite0F( 0x66, 0x6e, to, from ); }
|
__fi void xMOVDZX( const xRegisterSSE& to, const xRegister32or64& from ) { xOpWrite0F( 0x66, 0x6e, to, from ); }
|
||||||
__fi void xMOVDZX( const xRegisterSSE& to, const xIndirectVoid& src ) { xOpWrite0F( 0x66, 0x6e, to, src ); }
|
__fi void xMOVDZX( const xRegisterSSE& to, const xIndirectVoid& src ) { xOpWrite0F( 0x66, 0x6e, to, src ); }
|
||||||
|
|
||||||
__fi void xMOVDZX( const xRegisterMMX& to, const xRegister32or64& from ) { xOpWrite0F( 0x6e, to, from ); }
|
|
||||||
__fi void xMOVDZX( const xRegisterMMX& to, const xIndirectVoid& src ) { xOpWrite0F( 0x6e, to, src ); }
|
|
||||||
|
|
||||||
__fi void xMOVD( const xRegister32or64& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, to ); }
|
__fi void xMOVD( const xRegister32or64& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, to ); }
|
||||||
__fi void xMOVD( const xIndirectVoid& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, dest ); }
|
__fi void xMOVD( const xIndirectVoid& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, dest ); }
|
||||||
|
|
||||||
__fi void xMOVD( const xRegister32or64& to, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, to ); }
|
|
||||||
__fi void xMOVD( const xIndirectVoid& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, dest ); }
|
|
||||||
|
|
||||||
|
|
||||||
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
||||||
// being cleared to zero.
|
// being cleared to zero.
|
||||||
__fi void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from ) { xOpWrite0F( 0xf3, 0x7e, to, from ); }
|
__fi void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from ) { xOpWrite0F( 0xf3, 0x7e, to, from ); }
|
||||||
|
@ -714,23 +679,6 @@ __fi void xMOVQZX( const xRegisterSSE& to, const void* src ) { xOpWrite0F( 0xf
|
||||||
// Moves lower quad of XMM to ptr64 (no bits are cleared)
|
// Moves lower quad of XMM to ptr64 (no bits are cleared)
|
||||||
__fi void xMOVQ( const xIndirectVoid& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd6, from, dest ); }
|
__fi void xMOVQ( const xIndirectVoid& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd6, from, dest ); }
|
||||||
|
|
||||||
__fi void xMOVQ( const xRegisterMMX& to, const xRegisterMMX& from ) { if( to != from ) xOpWrite0F( 0x6f, to, from ); }
|
|
||||||
__fi void xMOVQ( const xRegisterMMX& to, const xIndirectVoid& src ) { xOpWrite0F( 0x6f, to, src ); }
|
|
||||||
__fi void xMOVQ( const xIndirectVoid& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7f, from, dest ); }
|
|
||||||
|
|
||||||
// This form of xMOVQ is Intel's adeptly named 'MOVQ2DQ'
|
|
||||||
__fi void xMOVQ( const xRegisterSSE& to, const xRegisterMMX& from ) { xOpWrite0F( 0xf3, 0xd6, to, from ); }
|
|
||||||
|
|
||||||
// This form of xMOVQ is Intel's adeptly named 'MOVDQ2Q'
|
|
||||||
__fi void xMOVQ( const xRegisterMMX& to, const xRegisterSSE& from )
|
|
||||||
{
|
|
||||||
// Manual implementation of this form of MOVQ, since its parameters are unique in a way
|
|
||||||
// that breaks the template inference of writeXMMop();
|
|
||||||
|
|
||||||
SimdPrefix( 0xf2, 0xd6 );
|
|
||||||
EmitSibMagic( to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -756,8 +704,6 @@ __fi void xMOVNTDQA( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWr
|
||||||
__fi void xMOVNTPD( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x2b, from, to ); }
|
__fi void xMOVNTPD( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x2b, from, to ); }
|
||||||
__fi void xMOVNTPS( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWrite0F( 0x2b, from, to ); }
|
__fi void xMOVNTPS( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWrite0F( 0x2b, from, to ); }
|
||||||
|
|
||||||
__fi void xMOVNTQ( const xIndirectVoid& to, const xRegisterMMX& from ) { xOpWrite0F( 0xe7, from, to ); }
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
__fi void xMOVMSKPS( const xRegister32or64& to, const xRegisterSSE& from) { xOpWrite0F( 0x50, to, from ); }
|
__fi void xMOVMSKPS( const xRegister32or64& to, const xRegisterSSE& from) { xOpWrite0F( 0x50, to, from ); }
|
||||||
|
@ -769,7 +715,6 @@ __fi void xMOVMSKPD( const xRegister32or64& to, const xRegisterSSE& from) { xOpW
|
||||||
// of the mask operand determines whether the corresponding byte in the source operand is
|
// of the mask operand determines whether the corresponding byte in the source operand is
|
||||||
// written to the corresponding byte location in memory.
|
// written to the corresponding byte location in memory.
|
||||||
__fi void xMASKMOV( const xRegisterSSE& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xf7, to, from ); }
|
__fi void xMASKMOV( const xRegisterSSE& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xf7, to, from ); }
|
||||||
__fi void xMASKMOV( const xRegisterMMX& to, const xRegisterMMX& from ) { xOpWrite0F( 0xf7, to, from ); }
|
|
||||||
|
|
||||||
// xPMOVMSKB:
|
// xPMOVMSKB:
|
||||||
// Creates a mask made up of the most significant bit of each byte of the source
|
// Creates a mask made up of the most significant bit of each byte of the source
|
||||||
|
@ -780,14 +725,12 @@ __fi void xMASKMOV( const xRegisterMMX& to, const xRegisterMMX& from ) { xOpWri
|
||||||
// 128-bit (SSE) source, the byte mask is 16-bits.
|
// 128-bit (SSE) source, the byte mask is 16-bits.
|
||||||
//
|
//
|
||||||
__fi void xPMOVMSKB( const xRegister32or64& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd7, to, from ); }
|
__fi void xPMOVMSKB( const xRegister32or64& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd7, to, from ); }
|
||||||
__fi void xPMOVMSKB( const xRegister32or64& to, const xRegisterMMX& from ) { xOpWrite0F( 0xd7, to, from ); }
|
|
||||||
|
|
||||||
// [sSSE-3] Concatenates dest and source operands into an intermediate composite,
|
// [sSSE-3] Concatenates dest and source operands into an intermediate composite,
|
||||||
// shifts the composite at byte granularity to the right by a constant immediate,
|
// shifts the composite at byte granularity to the right by a constant immediate,
|
||||||
// and extracts the right-aligned result into the destination.
|
// and extracts the right-aligned result into the destination.
|
||||||
//
|
//
|
||||||
__fi void xPALIGNR( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x0f3a, to, from, imm8 ); }
|
__fi void xPALIGNR( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x0f3a, to, from, imm8 ); }
|
||||||
__fi void xPALIGNR( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm8 ) { xOpWrite0F( 0x0f3a, to, from, imm8 ); }
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -824,11 +767,6 @@ __emitinline void xEXTRACTPS( const xIndirect32& dest, const xRegisterSSE& from,
|
||||||
// Ungrouped Instructions!
|
// Ungrouped Instructions!
|
||||||
// =====================================================================================================
|
// =====================================================================================================
|
||||||
|
|
||||||
// Converts from MMX register mode to FPU register mode. The cpu enters MMX register mode
|
|
||||||
// when ever MMX instructions are run, and if FPU instructions are run without using EMMS,
|
|
||||||
// the FPU results will be invalid.
|
|
||||||
__fi void xEMMS() { xWrite16( 0x770F ); }
|
|
||||||
|
|
||||||
|
|
||||||
// Store Streaming SIMD Extension Control/Status to Mem32.
|
// Store Streaming SIMD Extension Control/Status to Mem32.
|
||||||
__emitinline void xSTMXCSR( const xIndirect32& dest )
|
__emitinline void xSTMXCSR( const xIndirect32& dest )
|
||||||
|
|
|
@ -116,12 +116,6 @@ const xRegisterSSE
|
||||||
xmm12( 12 ), xmm13( 13 ),
|
xmm12( 12 ), xmm13( 13 ),
|
||||||
xmm14( 14 ), xmm15( 15 );
|
xmm14( 14 ), xmm15( 15 );
|
||||||
|
|
||||||
const xRegisterMMX
|
|
||||||
mm0( 0 ), mm1( 1 ),
|
|
||||||
mm2( 2 ), mm3( 3 ),
|
|
||||||
mm4( 4 ), mm5( 5 ),
|
|
||||||
mm6( 6 ), mm7( 7 );
|
|
||||||
|
|
||||||
const xAddressReg
|
const xAddressReg
|
||||||
rax( 0 ), rbx( 3 ),
|
rax( 0 ), rbx( 3 ),
|
||||||
rcx( 1 ), rdx( 2 ),
|
rcx( 1 ), rdx( 2 ),
|
||||||
|
@ -192,12 +186,6 @@ const char *const x86_regnames_sse[] =
|
||||||
"xmm12", "xmm13", "xmm14", "xmm15"
|
"xmm12", "xmm13", "xmm14", "xmm15"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const x86_regnames_mmx[] =
|
|
||||||
{
|
|
||||||
"mm0", "mm1", "mm2", "mm3",
|
|
||||||
"mm4", "mm5", "mm6", "mm7"
|
|
||||||
};
|
|
||||||
|
|
||||||
const char* xRegisterBase::GetName()
|
const char* xRegisterBase::GetName()
|
||||||
{
|
{
|
||||||
if( Id == xRegId_Invalid ) return "invalid";
|
if( Id == xRegId_Invalid ) return "invalid";
|
||||||
|
@ -214,8 +202,6 @@ const char* xRegisterBase::GetName()
|
||||||
case 4: return x86_regnames_gpr32[ Id ];
|
case 4: return x86_regnames_gpr32[ Id ];
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
case 8: return x86_regnames_gpr64[ Id ];
|
case 8: return x86_regnames_gpr64[ Id ];
|
||||||
#else
|
|
||||||
case 8: return x86_regnames_mmx[ Id ];
|
|
||||||
#endif
|
#endif
|
||||||
case 16: return x86_regnames_sse[ Id ];
|
case 16: return x86_regnames_sse[ Id ];
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,9 +274,6 @@ void SysLogMachineCaps()
|
||||||
if( x86caps.hasAVX2 ) features[0].Add( L"AVX2" );
|
if( x86caps.hasAVX2 ) features[0].Add( L"AVX2" );
|
||||||
if( x86caps.hasFMA) features[0].Add( L"FMA" );
|
if( x86caps.hasFMA) features[0].Add( L"FMA" );
|
||||||
|
|
||||||
if( x86caps.hasMultimediaExtensionsExt ) features[1].Add( L"MMX2 " );
|
|
||||||
if( x86caps.has3DNOWInstructionExtensions ) features[1].Add( L"3DNOW " );
|
|
||||||
if( x86caps.has3DNOWInstructionExtensionsExt ) features[1].Add( L"3DNOW2" );
|
|
||||||
if( x86caps.hasStreamingSIMD4ExtensionsA ) features[1].Add( L"SSE4a " );
|
if( x86caps.hasStreamingSIMD4ExtensionsA ) features[1].Add( L"SSE4a " );
|
||||||
|
|
||||||
const wxString result[2] =
|
const wxString result[2] =
|
||||||
|
|
|
@ -33,7 +33,7 @@ u16 g_xmmAllocCounter = 0;
|
||||||
EEINST* g_pCurInstInfo = NULL;
|
EEINST* g_pCurInstInfo = NULL;
|
||||||
|
|
||||||
// used to make sure regs don't get changed while in recompiler
|
// used to make sure regs don't get changed while in recompiler
|
||||||
// use FreezeMMXRegs, FreezeXMMRegs
|
// use FreezeXMMRegs
|
||||||
u32 g_recWriteback = 0;
|
u32 g_recWriteback = 0;
|
||||||
|
|
||||||
_xmmregs xmmregs[iREGCNT_XMM], s_saveXMMregs[iREGCNT_XMM];
|
_xmmregs xmmregs[iREGCNT_XMM], s_saveXMMregs[iREGCNT_XMM];
|
||||||
|
@ -373,8 +373,6 @@ int _allocGPRtoXMMreg(int xmmreg, int gprreg, int mode)
|
||||||
if (xmmregs[i].type != XMMTYPE_GPRREG) continue;
|
if (xmmregs[i].type != XMMTYPE_GPRREG) continue;
|
||||||
if (xmmregs[i].reg != gprreg) continue;
|
if (xmmregs[i].reg != gprreg) continue;
|
||||||
|
|
||||||
pxAssert( _checkMMXreg(MMX_GPR|gprreg, mode) == -1 );
|
|
||||||
|
|
||||||
g_xmmtypes[i] = XMMT_INT;
|
g_xmmtypes[i] = XMMT_INT;
|
||||||
|
|
||||||
if (!(xmmregs[i].mode & MODE_READ) && (mode & MODE_READ))
|
if (!(xmmregs[i].mode & MODE_READ) && (mode & MODE_READ))
|
||||||
|
@ -432,40 +430,11 @@ int _allocGPRtoXMMreg(int xmmreg, int gprreg, int mode)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// DOX86
|
// DOX86
|
||||||
int mmxreg;
|
|
||||||
|
|
||||||
if (mode & MODE_READ) _flushConstReg(gprreg);
|
if (mode & MODE_READ) _flushConstReg(gprreg);
|
||||||
|
|
||||||
mmxreg = _checkMMXreg(MMX_GPR+gprreg, 0);
|
|
||||||
|
|
||||||
if (mmxreg >= 0 )
|
|
||||||
{
|
|
||||||
// transfer
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(xRegisterSSE(xmmreg), xRegisterMMX(mmxreg));
|
|
||||||
xPUNPCK.LQDQ(xRegisterSSE(xmmreg), xRegisterSSE(xmmreg));
|
|
||||||
xPUNPCK.HQDQ(xRegisterSSE(xmmreg), ptr[&cpuRegs.GPR.r[gprreg].UL[0]]);
|
|
||||||
|
|
||||||
if (mmxregs[mmxreg].mode & MODE_WRITE )
|
|
||||||
{
|
|
||||||
// instead of setting to write, just flush to mem
|
|
||||||
if (!(mode & MODE_WRITE))
|
|
||||||
{
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[gprreg].UL[0]], xRegisterMMX(mmxreg));
|
|
||||||
}
|
|
||||||
//xmmregs[xmmreg].mode |= MODE_WRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't flush
|
|
||||||
mmxregs[mmxreg].inuse = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
xMOVDQA(xRegisterSSE(xmmreg), ptr[&cpuRegs.GPR.r[gprreg].UL[0]]);
|
xMOVDQA(xRegisterSSE(xmmreg), ptr[&cpuRegs.GPR.r[gprreg].UL[0]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
_deleteMMXreg(MMX_GPR+gprreg, 0);
|
|
||||||
|
|
||||||
return xmmreg;
|
return xmmreg;
|
||||||
}
|
}
|
||||||
|
@ -1169,7 +1138,3 @@ void _recFillRegister(EEINST& pinst, int type, int reg, int write)
|
||||||
pxAssume( false );
|
pxAssume( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMMXstate() {
|
|
||||||
x86FpuState = MMX_STATE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -268,77 +268,6 @@ int _allocCheckFPUtoXMM(EEINST* pinst, int fpureg, int mode);
|
||||||
// allocates only if later insts use this register
|
// allocates only if later insts use this register
|
||||||
int _allocCheckGPRtoX86(EEINST* pinst, int gprreg, int mode);
|
int _allocCheckGPRtoX86(EEINST* pinst, int gprreg, int mode);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// MMX (64-bit) Register Allocation Tools
|
|
||||||
|
|
||||||
#define FPU_STATE 0
|
|
||||||
#define MMX_STATE 1
|
|
||||||
|
|
||||||
void SetMMXstate();
|
|
||||||
void SetFPUstate();
|
|
||||||
|
|
||||||
// max is 0x7f, when 0x80 is set, need to flush reg
|
|
||||||
//#define MMX_GET_CACHE(ptr, index) ((u8*)ptr)[index]
|
|
||||||
//#define MMX_SET_CACHE(ptr, ind3, ind2, ind1, ind0) ((u32*)ptr)[0] = (ind3<<24)|(ind2<<16)|(ind1<<8)|ind0;
|
|
||||||
#define MMX_GPR 0
|
|
||||||
#define MMX_HI XMMGPR_HI
|
|
||||||
#define MMX_LO XMMGPR_LO
|
|
||||||
#define MMX_FPUACC 34
|
|
||||||
#define MMX_FPU 64
|
|
||||||
#define MMX_COP0 96
|
|
||||||
#define MMX_TEMP 0x7f
|
|
||||||
|
|
||||||
static __fi bool MMX_IS32BITS(s32 x)
|
|
||||||
{
|
|
||||||
return (((x >= MMX_FPU) && (x < MMX_COP0 + 32)) || (x == MMX_FPUACC));
|
|
||||||
}
|
|
||||||
|
|
||||||
static __fi bool MMX_ISGPR(s32 x)
|
|
||||||
{
|
|
||||||
return ((x >= MMX_GPR) && (x < MMX_GPR + 34));
|
|
||||||
}
|
|
||||||
|
|
||||||
static __fi bool MMX_ISGPR(u32 x)
|
|
||||||
{
|
|
||||||
return (x < MMX_GPR + 34);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct _mmxregs {
|
|
||||||
u8 inuse;
|
|
||||||
u8 reg; // value of 0 - not used
|
|
||||||
u8 mode;
|
|
||||||
u8 needed;
|
|
||||||
u16 counter;
|
|
||||||
};
|
|
||||||
|
|
||||||
void _initMMXregs();
|
|
||||||
int _getFreeMMXreg();
|
|
||||||
int _allocMMXreg(int MMXreg, int reg, int mode);
|
|
||||||
void _addNeededMMXreg(int reg);
|
|
||||||
int _checkMMXreg(int reg, int mode);
|
|
||||||
void _clearNeededMMXregs();
|
|
||||||
void _deleteMMXreg(int reg, int flush);
|
|
||||||
void _freeMMXreg(u32 mmxreg);
|
|
||||||
void _moveMMXreg(int mmxreg); // instead of freeing, moves it to a diff location
|
|
||||||
void _flushMMXregs();
|
|
||||||
u8 _hasFreeMMXreg();
|
|
||||||
void _freeMMXregs();
|
|
||||||
int _getNumMMXwrite();
|
|
||||||
|
|
||||||
int _signExtendMtoMMX(x86MMXRegType to, uptr mem);
|
|
||||||
int _signExtendGPRMMXtoMMX(x86MMXRegType to, u32 gprreg, x86MMXRegType from, u32 gprfromreg);
|
|
||||||
int _allocCheckGPRtoMMX(EEINST* pinst, int reg, int mode);
|
|
||||||
|
|
||||||
// returns new index of reg, lower 32 bits already in mmx
|
|
||||||
// shift is used when the data is in the top bits of the mmx reg to begin with
|
|
||||||
// a negative shift is for sign extension
|
|
||||||
extern int _signExtendGPRtoMMX(x86MMXRegType to, u32 gprreg, int shift);
|
|
||||||
|
|
||||||
extern _mmxregs mmxregs[iREGCNT_MMX], s_saveMMXregs[iREGCNT_MMX];
|
|
||||||
extern u16 x86FpuState;
|
|
||||||
|
|
||||||
// extern void iDumpRegisters(u32 startpc, u32 temp);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// iFlushCall / _psxFlushCall Parameters
|
// iFlushCall / _psxFlushCall Parameters
|
||||||
|
|
||||||
|
@ -357,8 +286,6 @@ extern u16 x86FpuState;
|
||||||
#define FLUSH_CACHED_REGS 0x001
|
#define FLUSH_CACHED_REGS 0x001
|
||||||
#define FLUSH_FLUSH_XMM 0x002
|
#define FLUSH_FLUSH_XMM 0x002
|
||||||
#define FLUSH_FREE_XMM 0x004 // both flushes and frees
|
#define FLUSH_FREE_XMM 0x004 // both flushes and frees
|
||||||
#define FLUSH_FLUSH_MMX 0x008
|
|
||||||
#define FLUSH_FREE_MMX 0x010 // both flushes and frees
|
|
||||||
#define FLUSH_FLUSH_ALLX86 0x020 // flush x86
|
#define FLUSH_FLUSH_ALLX86 0x020 // flush x86
|
||||||
#define FLUSH_FREE_TEMPX86 0x040 // flush and free temporary x86 regs
|
#define FLUSH_FREE_TEMPX86 0x040 // flush and free temporary x86 regs
|
||||||
#define FLUSH_FREE_ALLX86 0x080 // free all x86 regs
|
#define FLUSH_FREE_ALLX86 0x080 // free all x86 regs
|
||||||
|
@ -372,9 +299,9 @@ extern u16 x86FpuState;
|
||||||
#define FLUSH_INTERPRETER 0xfff
|
#define FLUSH_INTERPRETER 0xfff
|
||||||
#define FLUSH_FULLVTLB FLUSH_NOCONST
|
#define FLUSH_FULLVTLB FLUSH_NOCONST
|
||||||
|
|
||||||
// no freeing, used when callee won't destroy mmx/xmm regs
|
// no freeing, used when callee won't destroy xmm regs
|
||||||
#define FLUSH_NODESTROY (FLUSH_CACHED_REGS|FLUSH_FLUSH_XMM|FLUSH_FLUSH_MMX|FLUSH_FLUSH_ALLX86)
|
#define FLUSH_NODESTROY (FLUSH_CACHED_REGS|FLUSH_FLUSH_XMM|FLUSH_FLUSH_ALLX86)
|
||||||
// used when regs aren't going to be changed be callee
|
// used when regs aren't going to be changed be callee
|
||||||
#define FLUSH_NOCONST (FLUSH_FREE_XMM|FLUSH_FREE_MMX|FLUSH_FREE_TEMPX86)
|
#define FLUSH_NOCONST (FLUSH_FREE_XMM|FLUSH_FREE_TEMPX86)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -154,26 +154,15 @@ void recCTC1()
|
||||||
xMOVSS(ptr[&fpuRegs.fprc[ _Fs_ ]], xRegisterSSE(mmreg));
|
xMOVSS(ptr[&fpuRegs.fprc[ _Fs_ ]], xRegisterSSE(mmreg));
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_READ);
|
|
||||||
|
|
||||||
if ( mmreg >= 0 )
|
|
||||||
{
|
|
||||||
xMOVD(ptr[&fpuRegs.fprc[ _Fs_ ]], xRegisterMMX(mmreg));
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
|
||||||
|
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ]);
|
||||||
xMOV(ptr[&fpuRegs.fprc[ _Fs_ ]], eax);
|
xMOV(ptr[&fpuRegs.fprc[ _Fs_ ]], eax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,29 +183,8 @@ void recMFC1()
|
||||||
if( regs >= 0 )
|
if( regs >= 0 )
|
||||||
{
|
{
|
||||||
_deleteGPRtoXMMreg(_Rt_, 2);
|
_deleteGPRtoXMMreg(_Rt_, 2);
|
||||||
regt = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rt_, MODE_WRITE);
|
|
||||||
|
|
||||||
if( regt >= 0 )
|
|
||||||
{
|
|
||||||
xMOVQ(xRegisterMMX(regt), xRegisterSSE(regs));
|
|
||||||
_signExtendGPRtoMMX(regt, _Rt_, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_signExtendXMMtoM((uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], regs, 0);
|
_signExtendXMMtoM((uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], regs, 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
regs = _checkMMXreg(MMX_FPU+_Fs_, MODE_READ);
|
|
||||||
|
|
||||||
if( regs >= 0 )
|
|
||||||
{
|
|
||||||
// convert to mmx reg
|
|
||||||
mmxregs[regs].reg = MMX_GPR+_Rt_;
|
|
||||||
mmxregs[regs].mode |= MODE_READ|MODE_WRITE;
|
|
||||||
_signExtendGPRtoMMX(regs, _Rt_, 0);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
regt = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ);
|
regt = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ);
|
||||||
|
@ -238,7 +206,6 @@ void recMFC1()
|
||||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ]], edx);
|
xMOV(ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ]], edx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -279,26 +246,8 @@ void recMTC1()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int mmreg2;
|
int mmreg2 = _allocCheckFPUtoXMM(g_pCurInstInfo, _Fs_, MODE_WRITE);
|
||||||
|
|
||||||
mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_READ);
|
|
||||||
mmreg2 = _allocCheckFPUtoXMM(g_pCurInstInfo, _Fs_, MODE_WRITE);
|
|
||||||
|
|
||||||
if( mmreg >= 0 )
|
|
||||||
{
|
|
||||||
if( mmreg2 >= 0 )
|
|
||||||
{
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(xRegisterSSE(mmreg2), xRegisterMMX(mmreg));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVD(ptr[&fpuRegs.fpr[ _Fs_ ].UL], xRegisterMMX(mmreg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( mmreg2 >= 0 )
|
if( mmreg2 >= 0 )
|
||||||
{
|
{
|
||||||
xMOVSSZX(xRegisterSSE(mmreg2), ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]]);
|
xMOVSSZX(xRegisterSSE(mmreg2), ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]]);
|
||||||
|
@ -311,7 +260,6 @@ void recMTC1()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,6 @@ REC_FUNC_DEL( PSLLW, _Rd_ );
|
||||||
|
|
||||||
void recPLZCW()
|
void recPLZCW()
|
||||||
{
|
{
|
||||||
bool isXMMreg = false;
|
|
||||||
int regs = -1;
|
int regs = -1;
|
||||||
|
|
||||||
if ( ! _Rd_ ) return;
|
if ( ! _Rd_ ) return;
|
||||||
|
@ -80,11 +79,6 @@ void recPLZCW()
|
||||||
|
|
||||||
if( (regs = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
|
if( (regs = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
|
||||||
xMOVD(eax, xRegisterSSE(regs));
|
xMOVD(eax, xRegisterSSE(regs));
|
||||||
isXMMreg = true;
|
|
||||||
}
|
|
||||||
else if( (regs = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) {
|
|
||||||
xMOVD(eax, xRegisterMMX(regs));
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||||
|
@ -119,17 +113,9 @@ void recPLZCW()
|
||||||
// second word
|
// second word
|
||||||
|
|
||||||
if( regs >= 0) {
|
if( regs >= 0) {
|
||||||
// Check if it was an XMM reg or MMX reg
|
|
||||||
if (isXMMreg) {
|
|
||||||
xPSHUF.D(xRegisterSSE(regs&0xf), xRegisterSSE(regs&0xf), 0xe1);
|
xPSHUF.D(xRegisterSSE(regs&0xf), xRegisterSSE(regs&0xf), 0xe1);
|
||||||
xMOVD(eax, xRegisterSSE(regs&0xf));
|
xMOVD(eax, xRegisterSSE(regs&0xf));
|
||||||
xPSHUF.D(xRegisterSSE(regs&0xf), xRegisterSSE(regs&0xf), 0xe1);
|
xPSHUF.D(xRegisterSSE(regs&0xf), xRegisterSSE(regs&0xf), 0xe1);
|
||||||
} else {
|
|
||||||
xPSHUF.W(xRegisterMMX(regs&0xf), xRegisterMMX(regs&0xf), 0x4e);
|
|
||||||
xMOVD(eax, xRegisterMMX(regs&0xf));
|
|
||||||
xPSHUF.W(xRegisterMMX(regs&0xf), xRegisterMMX(regs&0xf), 0x4e);
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||||
|
@ -244,47 +230,6 @@ void recPMTHL()
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
}
|
}
|
||||||
|
|
||||||
// MMX helper routines
|
|
||||||
/*#define MMX_ALLOC_TEMP1(code) { \
|
|
||||||
int t0reg; \
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
code; \
|
|
||||||
_freeMMXreg(t0reg); \
|
|
||||||
} \
|
|
||||||
|
|
||||||
#define MMX_ALLOC_TEMP2(code) { \
|
|
||||||
int t0reg, t1reg; \
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
t1reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
code; \
|
|
||||||
_freeMMXreg(t0reg); \
|
|
||||||
_freeMMXreg(t1reg); \
|
|
||||||
} \
|
|
||||||
|
|
||||||
#define MMX_ALLOC_TEMP3(code) { \
|
|
||||||
int t0reg, t1reg, t2reg; \
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
t1reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
t2reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
code; \
|
|
||||||
_freeMMXreg(t0reg); \
|
|
||||||
_freeMMXreg(t1reg); \
|
|
||||||
_freeMMXreg(t2reg); \
|
|
||||||
} \
|
|
||||||
|
|
||||||
#define MMX_ALLOC_TEMP4(code) { \
|
|
||||||
int t0reg, t1reg, t2reg, t3reg; \
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
t1reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
t2reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
t3reg = _allocMMXreg(-1, MMX_TEMP, 0); \
|
|
||||||
code; \
|
|
||||||
_freeMMXreg(t0reg); \
|
|
||||||
_freeMMXreg(t1reg); \
|
|
||||||
_freeMMXreg(t2reg); \
|
|
||||||
_freeMMXreg(t3reg); \
|
|
||||||
} \*/
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void recPSRLH()
|
void recPSRLH()
|
||||||
{
|
{
|
||||||
|
|
|
@ -98,10 +98,6 @@ void recMFSA()
|
||||||
if( mmreg >= 0 ) {
|
if( mmreg >= 0 ) {
|
||||||
xMOVL.PS(xRegisterSSE(mmreg), ptr[&cpuRegs.sa]);
|
xMOVL.PS(xRegisterSSE(mmreg), ptr[&cpuRegs.sa]);
|
||||||
}
|
}
|
||||||
else if( (mmreg = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE)) >= 0 ) {
|
|
||||||
xMOVDZX(xRegisterMMX(mmreg), ptr[&cpuRegs.sa]);
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
xMOV(eax, ptr[&cpuRegs.sa]);
|
xMOV(eax, ptr[&cpuRegs.sa]);
|
||||||
_deleteEEreg(_Rd_, 0);
|
_deleteEEreg(_Rd_, 0);
|
||||||
|
@ -122,10 +118,6 @@ void recMTSA()
|
||||||
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
|
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
|
||||||
xMOVSS(ptr[&cpuRegs.sa], xRegisterSSE(mmreg));
|
xMOVSS(ptr[&cpuRegs.sa], xRegisterSSE(mmreg));
|
||||||
}
|
}
|
||||||
else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) {
|
|
||||||
xMOVD(ptr[&cpuRegs.sa], xRegisterMMX(mmreg));
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
|
||||||
xMOV(ptr[&cpuRegs.sa], eax);
|
xMOV(ptr[&cpuRegs.sa], eax);
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace VU1micro
|
||||||
void recAlloc() { SuperVUAlloc(1); initVUrec(&VU1, 1); }
|
void recAlloc() { SuperVUAlloc(1); initVUrec(&VU1, 1); }
|
||||||
void __fastcall recClear(u32 Addr, u32 Size) { SuperVUClear(Addr, Size, 1); clearVUrec(Addr, Size, 1); }
|
void __fastcall recClear(u32 Addr, u32 Size) { SuperVUClear(Addr, Size, 1); clearVUrec(Addr, Size, 1); }
|
||||||
void recShutdown() { SuperVUDestroy(1); closeVUrec(1); }
|
void recShutdown() { SuperVUDestroy(1); closeVUrec(1); }
|
||||||
static void recReset() { SuperVUReset(1); resetVUrec(1); x86FpuState = FPU_STATE; }
|
static void recReset() { SuperVUReset(1); resetVUrec(1); }
|
||||||
static void recStep() {}
|
static void recStep() {}
|
||||||
|
|
||||||
static void recExecuteBlock(void)
|
static void recExecuteBlock(void)
|
||||||
|
@ -257,7 +257,6 @@ namespace VU1micro
|
||||||
static void recReset() {
|
static void recReset() {
|
||||||
if (useMVU1) resetVUrec(1);
|
if (useMVU1) resetVUrec(1);
|
||||||
else SuperVUReset(1);
|
else SuperVUReset(1);
|
||||||
x86FpuState = FPU_STATE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void recStep() {}
|
static void recStep() {}
|
||||||
|
|
|
@ -28,9 +28,6 @@ using namespace x86Emitter;
|
||||||
// landmass of shared code. (air)
|
// landmass of shared code. (air)
|
||||||
extern u32 g_psxConstRegs[32];
|
extern u32 g_psxConstRegs[32];
|
||||||
|
|
||||||
u16 x86FpuState;
|
|
||||||
static u16 g_mmxAllocCounter = 0;
|
|
||||||
|
|
||||||
// X86 caching
|
// X86 caching
|
||||||
static int g_x86checknext;
|
static int g_x86checknext;
|
||||||
|
|
||||||
|
@ -162,7 +159,6 @@ int _getFreeX86reg(int mode)
|
||||||
void _flushCachedRegs()
|
void _flushCachedRegs()
|
||||||
{
|
{
|
||||||
_flushConstRegs();
|
_flushConstRegs();
|
||||||
_flushMMXregs();
|
|
||||||
_flushXMMregs();
|
_flushXMMregs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,12 +333,10 @@ int _allocX86reg(xRegisterLong x86reg, int type, int reg, int mode)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_flushConstReg(reg);
|
_flushConstReg(reg);
|
||||||
_deleteMMXreg(MMX_GPR+reg, 1);
|
|
||||||
_deleteGPRtoXMMreg(reg, 1);
|
_deleteGPRtoXMMreg(reg, 1);
|
||||||
|
|
||||||
_eeMoveGPRtoR(x86reg, reg);
|
_eeMoveGPRtoR(x86reg, reg);
|
||||||
|
|
||||||
_deleteMMXreg(MMX_GPR+reg, 0);
|
|
||||||
_deleteGPRtoXMMreg(reg, 0);
|
_deleteGPRtoXMMreg(reg, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -473,404 +467,7 @@ void _freeX86regs()
|
||||||
_freeX86reg(i);
|
_freeX86reg(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MMX Caching
|
// Misc
|
||||||
_mmxregs mmxregs[8], s_saveMMXregs[8];
|
|
||||||
static int s_mmxchecknext = 0;
|
|
||||||
|
|
||||||
void _initMMXregs()
|
|
||||||
{
|
|
||||||
memzero(mmxregs);
|
|
||||||
g_mmxAllocCounter = 0;
|
|
||||||
s_mmxchecknext = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__fi void* _MMXGetAddr(int reg)
|
|
||||||
{
|
|
||||||
pxAssert( reg != MMX_TEMP );
|
|
||||||
|
|
||||||
if( reg == MMX_LO ) return &cpuRegs.LO;
|
|
||||||
if( reg == MMX_HI ) return &cpuRegs.HI;
|
|
||||||
if( reg == MMX_FPUACC ) return &fpuRegs.ACC;
|
|
||||||
|
|
||||||
if( reg >= MMX_GPR && reg < MMX_GPR+32 ) return &cpuRegs.GPR.r[reg&31];
|
|
||||||
if( reg >= MMX_FPU && reg < MMX_FPU+32 ) return &fpuRegs.fpr[reg&31];
|
|
||||||
if( reg >= MMX_COP0 && reg < MMX_COP0+32 ) return &cpuRegs.CP0.r[reg&31];
|
|
||||||
|
|
||||||
pxAssume( false );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _getFreeMMXreg()
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
int tempi = -1;
|
|
||||||
u32 bestcount = 0x10000;
|
|
||||||
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[(s_mmxchecknext+i)%iREGCNT_MMX].inuse == 0) {
|
|
||||||
int ret = (s_mmxchecknext+i)%iREGCNT_MMX;
|
|
||||||
s_mmxchecknext = (s_mmxchecknext+i+1)%iREGCNT_MMX;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for dead regs
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].needed) continue;
|
|
||||||
if (MMX_ISGPR(mmxregs[i].reg)) {
|
|
||||||
if( !(g_pCurInstInfo->regs[mmxregs[i].reg-MMX_GPR] & (EEINST_LIVE0)) ) {
|
|
||||||
_freeMMXreg(i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
if( !(g_pCurInstInfo->regs[mmxregs[i].reg-MMX_GPR]&EEINST_USED) ) {
|
|
||||||
_freeMMXreg(i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for future xmm usage
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].needed) continue;
|
|
||||||
if (MMX_ISGPR(mmxregs[i].reg)) {
|
|
||||||
_freeMMXreg(i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].needed) continue;
|
|
||||||
if (mmxregs[i].reg != MMX_TEMP) {
|
|
||||||
|
|
||||||
if( mmxregs[i].counter < bestcount ) {
|
|
||||||
tempi = i;
|
|
||||||
bestcount = mmxregs[i].counter;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_freeMMXreg(i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( tempi != -1 ) {
|
|
||||||
_freeMMXreg(tempi);
|
|
||||||
return tempi;
|
|
||||||
}
|
|
||||||
|
|
||||||
pxFailDev( "mmx register allocation error" );
|
|
||||||
throw Exception::FailedToAllocateRegister();
|
|
||||||
}
|
|
||||||
|
|
||||||
int _allocMMXreg(int mmxreg, int reg, int mode)
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
|
|
||||||
if( reg != MMX_TEMP ) {
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].inuse == 0 || mmxregs[i].reg != reg ) continue;
|
|
||||||
|
|
||||||
if( MMX_ISGPR(reg)) {
|
|
||||||
pxAssert( _checkXMMreg(XMMTYPE_GPRREG, reg-MMX_GPR, 0) == -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
mmxregs[i].needed = 1;
|
|
||||||
|
|
||||||
if( !(mmxregs[i].mode & MODE_READ) && (mode&MODE_READ) && reg != MMX_TEMP ) {
|
|
||||||
|
|
||||||
SetMMXstate();
|
|
||||||
if( reg == MMX_GPR ) {
|
|
||||||
// moving in 0s
|
|
||||||
xPXOR(xRegisterMMX(i), xRegisterMMX(i));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( MMX_ISGPR(reg) ) _flushConstReg(reg-MMX_GPR);
|
|
||||||
if( (mode & MODE_READHALF) || (MMX_IS32BITS(reg)&&(mode&MODE_READ)) )
|
|
||||||
xMOVDZX(xRegisterMMX(i), ptr[(_MMXGetAddr(reg))]);
|
|
||||||
else
|
|
||||||
xMOVQ(xRegisterMMX(i), ptr[(_MMXGetAddr(reg))]);
|
|
||||||
}
|
|
||||||
|
|
||||||
mmxregs[i].mode |= MODE_READ;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmxregs[i].counter = g_mmxAllocCounter++;
|
|
||||||
mmxregs[i].mode|= mode;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mmxreg == -1)
|
|
||||||
mmxreg = _getFreeMMXreg();
|
|
||||||
|
|
||||||
mmxregs[mmxreg].inuse = 1;
|
|
||||||
mmxregs[mmxreg].reg = reg;
|
|
||||||
mmxregs[mmxreg].mode = mode&~MODE_READHALF;
|
|
||||||
mmxregs[mmxreg].needed = 1;
|
|
||||||
mmxregs[mmxreg].counter = g_mmxAllocCounter++;
|
|
||||||
|
|
||||||
SetMMXstate();
|
|
||||||
if( reg == MMX_GPR ) {
|
|
||||||
// moving in 0s
|
|
||||||
xPXOR(xRegisterMMX(mmxreg), xRegisterMMX(mmxreg));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int xmmreg;
|
|
||||||
if( MMX_ISGPR(reg) && (xmmreg = _checkXMMreg(XMMTYPE_GPRREG, reg-MMX_GPR, 0)) >= 0 ) {
|
|
||||||
xMOVH.PS(ptr[(void*)((uptr)_MMXGetAddr(reg)+8)], xRegisterSSE(xmmreg));
|
|
||||||
if( mode & MODE_READ )
|
|
||||||
xMOVQ(xRegisterMMX(mmxreg), xRegisterSSE(xmmreg));
|
|
||||||
|
|
||||||
if( xmmregs[xmmreg].mode & MODE_WRITE )
|
|
||||||
mmxregs[mmxreg].mode |= MODE_WRITE;
|
|
||||||
|
|
||||||
// don't flush
|
|
||||||
xmmregs[xmmreg].inuse = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( MMX_ISGPR(reg) ) {
|
|
||||||
if(mode&(MODE_READHALF|MODE_READ)) _flushConstReg(reg-MMX_GPR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( (mode & MODE_READHALF) || (MMX_IS32BITS(reg)&&(mode&MODE_READ)) ) {
|
|
||||||
xMOVDZX(xRegisterMMX(mmxreg), ptr[(_MMXGetAddr(reg))]);
|
|
||||||
}
|
|
||||||
else if( mode & MODE_READ ) {
|
|
||||||
xMOVQ(xRegisterMMX(mmxreg), ptr[(_MMXGetAddr(reg))]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mmxreg;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _checkMMXreg(int reg, int mode)
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].inuse && mmxregs[i].reg == reg ) {
|
|
||||||
|
|
||||||
if( !(mmxregs[i].mode & MODE_READ) && (mode&MODE_READ) ) {
|
|
||||||
|
|
||||||
if( reg == MMX_GPR ) {
|
|
||||||
// moving in 0s
|
|
||||||
xPXOR(xRegisterMMX(i), xRegisterMMX(i));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (MMX_ISGPR(reg) && (mode&(MODE_READHALF|MODE_READ))) _flushConstReg(reg-MMX_GPR);
|
|
||||||
if( (mode & MODE_READHALF) || (MMX_IS32BITS(reg)&&(mode&MODE_READ)) )
|
|
||||||
xMOVDZX(xRegisterMMX(i), ptr[(_MMXGetAddr(reg))]);
|
|
||||||
else
|
|
||||||
xMOVQ(xRegisterMMX(i), ptr[(_MMXGetAddr(reg))]);
|
|
||||||
}
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
|
||||||
|
|
||||||
mmxregs[i].mode |= mode;
|
|
||||||
mmxregs[i].counter = g_mmxAllocCounter++;
|
|
||||||
mmxregs[i].needed = 1;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _addNeededMMXreg(int reg)
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].inuse == 0) continue;
|
|
||||||
if (mmxregs[i].reg != reg) continue;
|
|
||||||
|
|
||||||
mmxregs[i].counter = g_mmxAllocCounter++;
|
|
||||||
mmxregs[i].needed = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _clearNeededMMXregs()
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if( mmxregs[i].needed ) {
|
|
||||||
// setup read to any just written regs
|
|
||||||
if( mmxregs[i].inuse && (mmxregs[i].mode&MODE_WRITE) )
|
|
||||||
mmxregs[i].mode |= MODE_READ;
|
|
||||||
mmxregs[i].needed = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _deleteMMXreg(int reg, int flush)
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
|
|
||||||
if (mmxregs[i].inuse && mmxregs[i].reg == reg ) {
|
|
||||||
|
|
||||||
switch(flush) {
|
|
||||||
case 0: // frees all of the reg
|
|
||||||
_freeMMXreg(i);
|
|
||||||
break;
|
|
||||||
case 1: // flushes all of the reg
|
|
||||||
if( mmxregs[i].mode & MODE_WRITE) {
|
|
||||||
pxAssert( mmxregs[i].reg != MMX_GPR );
|
|
||||||
|
|
||||||
if( MMX_IS32BITS(reg) )
|
|
||||||
xMOVD(ptr[(_MMXGetAddr(mmxregs[i].reg))], xRegisterMMX(i));
|
|
||||||
else
|
|
||||||
xMOVQ(ptr[(_MMXGetAddr(mmxregs[i].reg))], xRegisterMMX(i));
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
// get rid of MODE_WRITE since don't want to flush again
|
|
||||||
mmxregs[i].mode &= ~MODE_WRITE;
|
|
||||||
mmxregs[i].mode |= MODE_READ;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case 2: // just stops using the reg (no flushing)
|
|
||||||
mmxregs[i].inuse = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int _getNumMMXwrite()
|
|
||||||
{
|
|
||||||
uint num = 0, i;
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if( mmxregs[i].inuse && (mmxregs[i].mode&MODE_WRITE) ) ++num;
|
|
||||||
}
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 _hasFreeMMXreg()
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (!mmxregs[i].inuse) return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for dead regs
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].needed) continue;
|
|
||||||
if (MMX_ISGPR(mmxregs[i].reg)) {
|
|
||||||
if( !EEINST_ISLIVE64(mmxregs[i].reg-MMX_GPR) ) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for dead regs
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].needed) continue;
|
|
||||||
if (MMX_ISGPR(mmxregs[i].reg)) {
|
|
||||||
if( !(g_pCurInstInfo->regs[mmxregs[i].reg-MMX_GPR]&EEINST_USED) ) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _freeMMXreg(u32 mmxreg)
|
|
||||||
{
|
|
||||||
pxAssert( mmxreg < iREGCNT_MMX );
|
|
||||||
if (!mmxregs[mmxreg].inuse) return;
|
|
||||||
|
|
||||||
if (mmxregs[mmxreg].mode & MODE_WRITE ) {
|
|
||||||
// Not sure if this line is accurate, since if the 32 was 34, it would be MMX_ISGPR.
|
|
||||||
if ( /*mmxregs[mmxreg].reg >= MMX_GPR &&*/ mmxregs[mmxreg].reg < MMX_GPR+32 ) // Checking if a u32 is >=0 is pointless.
|
|
||||||
pxAssert( !(g_cpuHasConstReg & (1<<(mmxregs[mmxreg].reg-MMX_GPR))) );
|
|
||||||
|
|
||||||
pxAssert( mmxregs[mmxreg].reg != MMX_GPR );
|
|
||||||
|
|
||||||
if( MMX_IS32BITS(mmxregs[mmxreg].reg) )
|
|
||||||
xMOVD(ptr[(_MMXGetAddr(mmxregs[mmxreg].reg))], xRegisterMMX(mmxreg));
|
|
||||||
else
|
|
||||||
xMOVQ(ptr[(_MMXGetAddr(mmxregs[mmxreg].reg))], xRegisterMMX(mmxreg));
|
|
||||||
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
|
||||||
|
|
||||||
mmxregs[mmxreg].mode &= ~MODE_WRITE;
|
|
||||||
mmxregs[mmxreg].inuse = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _moveMMXreg(int mmxreg)
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
if( !mmxregs[mmxreg].inuse ) return;
|
|
||||||
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].inuse) continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( i == iREGCNT_MMX ) {
|
|
||||||
_freeMMXreg(mmxreg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// move
|
|
||||||
mmxregs[i] = mmxregs[mmxreg];
|
|
||||||
mmxregs[mmxreg].inuse = 0;
|
|
||||||
xMOVQ(xRegisterMMX(i), xRegisterMMX(mmxreg));
|
|
||||||
}
|
|
||||||
|
|
||||||
// write all active regs
|
|
||||||
void _flushMMXregs()
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].inuse == 0) continue;
|
|
||||||
|
|
||||||
if( mmxregs[i].mode & MODE_WRITE ) {
|
|
||||||
pxAssert( !(g_cpuHasConstReg & (1<<mmxregs[i].reg)) );
|
|
||||||
pxAssert( mmxregs[i].reg != MMX_TEMP );
|
|
||||||
pxAssert( mmxregs[i].mode & MODE_READ );
|
|
||||||
pxAssert( mmxregs[i].reg != MMX_GPR );
|
|
||||||
|
|
||||||
if( MMX_IS32BITS(mmxregs[i].reg) )
|
|
||||||
xMOVD(ptr[(_MMXGetAddr(mmxregs[i].reg))], xRegisterMMX(i));
|
|
||||||
else
|
|
||||||
xMOVQ(ptr[(_MMXGetAddr(mmxregs[i].reg))], xRegisterMMX(i));
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
mmxregs[i].mode &= ~MODE_WRITE;
|
|
||||||
mmxregs[i].mode |= MODE_READ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _freeMMXregs()
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (mmxregs[i].inuse == 0) continue;
|
|
||||||
|
|
||||||
pxAssert( mmxregs[i].reg != MMX_TEMP );
|
|
||||||
pxAssert( mmxregs[i].mode & MODE_READ );
|
|
||||||
|
|
||||||
_freeMMXreg(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetFPUstate() {
|
|
||||||
_freeMMXreg(6);
|
|
||||||
_freeMMXreg(7);
|
|
||||||
|
|
||||||
if (x86FpuState == MMX_STATE) {
|
|
||||||
xEMMS();
|
|
||||||
x86FpuState = FPU_STATE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _signExtendSFtoM(uptr mem)
|
void _signExtendSFtoM(uptr mem)
|
||||||
{
|
{
|
||||||
|
@ -879,60 +476,3 @@ void _signExtendSFtoM(uptr mem)
|
||||||
xCWDE();
|
xCWDE();
|
||||||
xMOV(ptr[(void*)(mem)], eax);
|
xMOV(ptr[(void*)(mem)], eax);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _signExtendMtoMMX(x86MMXRegType to, uptr mem)
|
|
||||||
{
|
|
||||||
int t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
|
|
||||||
xMOVDZX(xRegisterMMX(t0reg), ptr[(void*)(mem)]);
|
|
||||||
xMOVQ(xRegisterMMX(to), xRegisterMMX(t0reg));
|
|
||||||
xPSRA.D(xRegisterMMX(t0reg), 31);
|
|
||||||
xPUNPCK.LDQ(xRegisterMMX(to), xRegisterMMX(t0reg));
|
|
||||||
_freeMMXreg(t0reg);
|
|
||||||
|
|
||||||
return to;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _signExtendGPRMMXtoMMX(x86MMXRegType to, u32 gprreg, x86MMXRegType from, u32 gprfromreg)
|
|
||||||
{
|
|
||||||
pxAssert( to >= 0 && from >= 0 );
|
|
||||||
|
|
||||||
if( to == from ) return _signExtendGPRtoMMX(to, gprreg, 0);
|
|
||||||
if( !(g_pCurInstInfo->regs[gprfromreg]&EEINST_LASTUSE) ) {
|
|
||||||
if( EEINST_ISLIVE64(gprfromreg) ) {
|
|
||||||
xMOVQ(xRegisterMMX(to), xRegisterMMX(from));
|
|
||||||
return _signExtendGPRtoMMX(to, gprreg, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// from is free for use
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
xMOVQ(xRegisterMMX(to), xRegisterMMX(from));
|
|
||||||
xMOVD(ptr[&cpuRegs.GPR.r[gprreg].UL[0]], xRegisterMMX(from));
|
|
||||||
xPSRA.D(xRegisterMMX(from), 31);
|
|
||||||
xMOVD(ptr[&cpuRegs.GPR.r[gprreg].UL[1]], xRegisterMMX(from));
|
|
||||||
mmxregs[to].inuse = 0;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _signExtendGPRtoMMX(x86MMXRegType to, u32 gprreg, int shift)
|
|
||||||
{
|
|
||||||
pxAssert( to >= 0 && shift >= 0 );
|
|
||||||
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
if( shift > 0 ) xPSRA.D(xRegisterMMX(to), shift);
|
|
||||||
xMOVD(ptr[&cpuRegs.GPR.r[gprreg].UL[0]], xRegisterMMX(to));
|
|
||||||
xPSRA.D(xRegisterMMX(to), 31);
|
|
||||||
xMOVD(ptr[&cpuRegs.GPR.r[gprreg].UL[1]], xRegisterMMX(to));
|
|
||||||
mmxregs[to].inuse = 0;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _allocCheckGPRtoMMX(EEINST* pinst, int reg, int mode)
|
|
||||||
{
|
|
||||||
return _checkMMXreg(MMX_GPR+reg, mode);
|
|
||||||
}
|
|
||||||
|
|
|
@ -98,7 +98,6 @@ static bool s_nBlockFF;
|
||||||
|
|
||||||
// save states for branches
|
// save states for branches
|
||||||
GPR_reg64 s_saveConstRegs[32];
|
GPR_reg64 s_saveConstRegs[32];
|
||||||
static u16 s_savex86FpuState;
|
|
||||||
static u32 s_saveHasConstReg = 0, s_saveFlushedConstReg = 0;
|
static u32 s_saveHasConstReg = 0, s_saveFlushedConstReg = 0;
|
||||||
static EEINST* s_psaveInstInfo = NULL;
|
static EEINST* s_psaveInstInfo = NULL;
|
||||||
|
|
||||||
|
@ -127,7 +126,6 @@ void _eeFlushAllUnused()
|
||||||
|
|
||||||
if( i < 32 && GPR_IS_CONST1(i) ) _flushConstReg(i);
|
if( i < 32 && GPR_IS_CONST1(i) ) _flushConstReg(i);
|
||||||
else {
|
else {
|
||||||
_deleteMMXreg(MMX_GPR+i, 1);
|
|
||||||
_deleteGPRtoXMMreg(i, 1);
|
_deleteGPRtoXMMreg(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,10 +164,6 @@ void _eeMoveGPRtoR(const xRegisterLong& to, int fromgpr)
|
||||||
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, fromgpr, MODE_READ)) >= 0 && (xmmregs[mmreg].mode&MODE_WRITE)) {
|
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, fromgpr, MODE_READ)) >= 0 && (xmmregs[mmreg].mode&MODE_WRITE)) {
|
||||||
xMOVD(to, xRegisterSSE(mmreg));
|
xMOVD(to, xRegisterSSE(mmreg));
|
||||||
}
|
}
|
||||||
else if( (mmreg = _checkMMXreg(MMX_GPR+fromgpr, MODE_READ)) >= 0 && (mmxregs[mmreg].mode&MODE_WRITE) ) {
|
|
||||||
xMOVD(to, xRegisterMMX(mmreg));
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
xMOV(to, ptr[&cpuRegs.GPR.r[ fromgpr ].UL[ 0 ] ]);
|
xMOV(to, ptr[&cpuRegs.GPR.r[ fromgpr ].UL[ 0 ] ]);
|
||||||
}
|
}
|
||||||
|
@ -186,10 +180,6 @@ void _eeMoveGPRtoM(uptr to, int fromgpr)
|
||||||
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, fromgpr, MODE_READ)) >= 0 ) {
|
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, fromgpr, MODE_READ)) >= 0 ) {
|
||||||
xMOVSS(ptr[(void*)(to)], xRegisterSSE(mmreg));
|
xMOVSS(ptr[(void*)(to)], xRegisterSSE(mmreg));
|
||||||
}
|
}
|
||||||
else if( (mmreg = _checkMMXreg(MMX_GPR+fromgpr, MODE_READ)) >= 0 ) {
|
|
||||||
xMOVD(ptr[(void*)(to)], xRegisterMMX(mmreg));
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ fromgpr ].UL[ 0 ] ]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ fromgpr ].UL[ 0 ] ]);
|
||||||
xMOV(ptr[(void*)(to)], eax);
|
xMOV(ptr[(void*)(to)], eax);
|
||||||
|
@ -207,10 +197,6 @@ void _eeMoveGPRtoRm(x86IntRegType to, int fromgpr)
|
||||||
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, fromgpr, MODE_READ)) >= 0 ) {
|
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, fromgpr, MODE_READ)) >= 0 ) {
|
||||||
xMOVSS(ptr[xAddressReg(to)], xRegisterSSE(mmreg));
|
xMOVSS(ptr[xAddressReg(to)], xRegisterSSE(mmreg));
|
||||||
}
|
}
|
||||||
else if( (mmreg = _checkMMXreg(MMX_GPR+fromgpr, MODE_READ)) >= 0 ) {
|
|
||||||
xMOVD(ptr[xAddressReg(to)], xRegisterMMX(mmreg));
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ fromgpr ].UL[ 0 ] ]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ fromgpr ].UL[ 0 ] ]);
|
||||||
xMOV(ptr[xAddressReg(to)], eax);
|
xMOV(ptr[xAddressReg(to)], eax);
|
||||||
|
@ -245,25 +231,6 @@ int _flushXMMunused()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _flushMMXunused()
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
for (i=0; i<iREGCNT_MMX; i++) {
|
|
||||||
if (!mmxregs[i].inuse || mmxregs[i].needed || !(mmxregs[i].mode&MODE_WRITE) ) continue;
|
|
||||||
|
|
||||||
if( MMX_ISGPR(mmxregs[i].reg) ) {
|
|
||||||
//if( !(g_pCurInstInfo->regs[mmxregs[i].reg-MMX_GPR]&EEINST_USED) ) {
|
|
||||||
if( !_recIsRegWritten(g_pCurInstInfo+1, (s_nEndBlock-pc)/4, XMMTYPE_GPRREG, mmxregs[i].reg-MMX_GPR) ) {
|
|
||||||
_freeMMXreg(i);
|
|
||||||
mmxregs[i].inuse = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _flushUnusedConstReg()
|
int _flushUnusedConstReg()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -444,7 +411,6 @@ static DynGenFunc* _DynGen_EnterRecompiledCode()
|
||||||
static DynGenFunc* _DynGen_DispatchBlockDiscard()
|
static DynGenFunc* _DynGen_DispatchBlockDiscard()
|
||||||
{
|
{
|
||||||
u8* retval = xGetPtr();
|
u8* retval = xGetPtr();
|
||||||
xEMMS();
|
|
||||||
xFastCall(dyna_block_discard);
|
xFastCall(dyna_block_discard);
|
||||||
xJMP(ExitRecompiledCode);
|
xJMP(ExitRecompiledCode);
|
||||||
return (DynGenFunc*)retval;
|
return (DynGenFunc*)retval;
|
||||||
|
@ -453,7 +419,6 @@ static DynGenFunc* _DynGen_DispatchBlockDiscard()
|
||||||
static DynGenFunc* _DynGen_DispatchPageReset()
|
static DynGenFunc* _DynGen_DispatchPageReset()
|
||||||
{
|
{
|
||||||
u8* retval = xGetPtr();
|
u8* retval = xGetPtr();
|
||||||
xEMMS();
|
|
||||||
xFastCall(dyna_page_reset);
|
xFastCall(dyna_page_reset);
|
||||||
xJMP(ExitRecompiledCode);
|
xJMP(ExitRecompiledCode);
|
||||||
return (DynGenFunc*)retval;
|
return (DynGenFunc*)retval;
|
||||||
|
@ -596,8 +561,6 @@ static void recAlloc()
|
||||||
// No errors.. Proceed with initialization:
|
// No errors.. Proceed with initialization:
|
||||||
|
|
||||||
_DynGen_Dispatchers();
|
_DynGen_Dispatchers();
|
||||||
|
|
||||||
x86FpuState = FPU_STATE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __aligned16 u16 manual_page[Ps2MemSize::MainRam >> 12];
|
static __aligned16 u16 manual_page[Ps2MemSize::MainRam >> 12];
|
||||||
|
@ -639,7 +602,6 @@ static void recResetRaw()
|
||||||
|
|
||||||
recPtr = *recMem;
|
recPtr = *recMem;
|
||||||
recConstBufPtr = recConstBuf;
|
recConstBufPtr = recConstBuf;
|
||||||
x86FpuState = FPU_STATE;
|
|
||||||
|
|
||||||
g_branch = 0;
|
g_branch = 0;
|
||||||
}
|
}
|
||||||
|
@ -882,10 +844,6 @@ void SetBranchReg( u32 reg )
|
||||||
// if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, reg, MODE_READ)) >= 0 ) {
|
// if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, reg, MODE_READ)) >= 0 ) {
|
||||||
// xMOVSS(ptr[&cpuRegs.pc], xRegisterSSE(mmreg));
|
// xMOVSS(ptr[&cpuRegs.pc], xRegisterSSE(mmreg));
|
||||||
// }
|
// }
|
||||||
// else if( (mmreg = _checkMMXreg(MMX_GPR+reg, MODE_READ)) >= 0 ) {
|
|
||||||
// xMOVD(ptr[&cpuRegs.pc], xRegisterMMX(mmreg));
|
|
||||||
// SetMMXstate();
|
|
||||||
// }
|
|
||||||
// else {
|
// else {
|
||||||
// xMOV(eax, ptr[(void*)((int)&cpuRegs.GPR.r[ reg ].UL[ 0 ] )]);
|
// xMOV(eax, ptr[(void*)((int)&cpuRegs.GPR.r[ reg ].UL[ 0 ] )]);
|
||||||
// xMOV(ptr[&cpuRegs.pc], eax);
|
// xMOV(ptr[&cpuRegs.pc], eax);
|
||||||
|
@ -937,21 +895,17 @@ void SetBranchImm( u32 imm )
|
||||||
|
|
||||||
void SaveBranchState()
|
void SaveBranchState()
|
||||||
{
|
{
|
||||||
s_savex86FpuState = x86FpuState;
|
|
||||||
s_savenBlockCycles = s_nBlockCycles;
|
s_savenBlockCycles = s_nBlockCycles;
|
||||||
memcpy(s_saveConstRegs, g_cpuConstRegs, sizeof(g_cpuConstRegs));
|
memcpy(s_saveConstRegs, g_cpuConstRegs, sizeof(g_cpuConstRegs));
|
||||||
s_saveHasConstReg = g_cpuHasConstReg;
|
s_saveHasConstReg = g_cpuHasConstReg;
|
||||||
s_saveFlushedConstReg = g_cpuFlushedConstReg;
|
s_saveFlushedConstReg = g_cpuFlushedConstReg;
|
||||||
s_psaveInstInfo = g_pCurInstInfo;
|
s_psaveInstInfo = g_pCurInstInfo;
|
||||||
|
|
||||||
// save all mmx regs
|
|
||||||
memcpy(s_saveMMXregs, mmxregs, sizeof(mmxregs));
|
|
||||||
memcpy(s_saveXMMregs, xmmregs, sizeof(xmmregs));
|
memcpy(s_saveXMMregs, xmmregs, sizeof(xmmregs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadBranchState()
|
void LoadBranchState()
|
||||||
{
|
{
|
||||||
x86FpuState = s_savex86FpuState;
|
|
||||||
s_nBlockCycles = s_savenBlockCycles;
|
s_nBlockCycles = s_savenBlockCycles;
|
||||||
|
|
||||||
memcpy(g_cpuConstRegs, s_saveConstRegs, sizeof(g_cpuConstRegs));
|
memcpy(g_cpuConstRegs, s_saveConstRegs, sizeof(g_cpuConstRegs));
|
||||||
|
@ -959,8 +913,6 @@ void LoadBranchState()
|
||||||
g_cpuFlushedConstReg = s_saveFlushedConstReg;
|
g_cpuFlushedConstReg = s_saveFlushedConstReg;
|
||||||
g_pCurInstInfo = s_psaveInstInfo;
|
g_pCurInstInfo = s_psaveInstInfo;
|
||||||
|
|
||||||
// restore all mmx regs
|
|
||||||
memcpy(mmxregs, s_saveMMXregs, sizeof(mmxregs));
|
|
||||||
memcpy(xmmregs, s_saveXMMregs, sizeof(xmmregs));
|
memcpy(xmmregs, s_saveXMMregs, sizeof(xmmregs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -992,18 +944,8 @@ void iFlushCall(int flushtype)
|
||||||
else if( flushtype & FLUSH_FLUSH_XMM)
|
else if( flushtype & FLUSH_FLUSH_XMM)
|
||||||
_flushXMMregs();
|
_flushXMMregs();
|
||||||
|
|
||||||
if( flushtype & FLUSH_FREE_MMX )
|
|
||||||
_freeMMXregs();
|
|
||||||
else if( flushtype & FLUSH_FLUSH_MMX)
|
|
||||||
_flushMMXregs();
|
|
||||||
|
|
||||||
if( flushtype & FLUSH_CACHED_REGS )
|
if( flushtype & FLUSH_CACHED_REGS )
|
||||||
_flushConstRegs();
|
_flushConstRegs();
|
||||||
|
|
||||||
if (x86FpuState==MMX_STATE) {
|
|
||||||
xEMMS();
|
|
||||||
x86FpuState=FPU_STATE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: scaleblockcycles() scales s_nBlockCycles respective to the EECycleRate value for manipulating the cycles of current block recompiling.
|
// Note: scaleblockcycles() scales s_nBlockCycles respective to the EECycleRate value for manipulating the cycles of current block recompiling.
|
||||||
|
@ -1301,15 +1243,6 @@ void recompileNextInstruction(int delayslot)
|
||||||
|
|
||||||
g_pCurInstInfo++;
|
g_pCurInstInfo++;
|
||||||
|
|
||||||
for(i = 0; i < iREGCNT_MMX; ++i) {
|
|
||||||
if( mmxregs[i].inuse ) {
|
|
||||||
pxAssert( MMX_ISGPR(mmxregs[i].reg) );
|
|
||||||
count = _recIsRegWritten(g_pCurInstInfo, (s_nEndBlock-pc)/4 + 1, XMMTYPE_GPRREG, mmxregs[i].reg-MMX_GPR);
|
|
||||||
if( count > 0 ) mmxregs[i].counter = 1000-count;
|
|
||||||
else mmxregs[i].counter = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < iREGCNT_XMM; ++i) {
|
for(i = 0; i < iREGCNT_XMM; ++i) {
|
||||||
if( xmmregs[i].inuse ) {
|
if( xmmregs[i].inuse ) {
|
||||||
count = _recIsRegWritten(g_pCurInstInfo, (s_nEndBlock-pc)/4 + 1, xmmregs[i].type, xmmregs[i].reg);
|
count = _recIsRegWritten(g_pCurInstInfo, (s_nEndBlock-pc)/4 + 1, xmmregs[i].type, xmmregs[i].reg);
|
||||||
|
@ -1330,7 +1263,6 @@ void recompileNextInstruction(int delayslot)
|
||||||
case 0: case 1: case 2: case 3: case 0x10: case 0x11: case 0x12: case 0x13:
|
case 0: case 1: case 2: case 3: case 0x10: case 0x11: case 0x12: case 0x13:
|
||||||
Console.Warning("branch %x in delay slot!", cpuRegs.code);
|
Console.Warning("branch %x in delay slot!", cpuRegs.code);
|
||||||
_clearNeededX86regs();
|
_clearNeededX86regs();
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1339,7 +1271,6 @@ void recompileNextInstruction(int delayslot)
|
||||||
case 2: case 3: case 4: case 5: case 6: case 7: case 0x14: case 0x15: case 0x16: case 0x17:
|
case 2: case 3: case 4: case 5: case 6: case 7: case 0x14: case 0x15: case 0x16: case 0x17:
|
||||||
Console.Warning("branch %x in delay slot!", cpuRegs.code);
|
Console.Warning("branch %x in delay slot!", cpuRegs.code);
|
||||||
_clearNeededX86regs();
|
_clearNeededX86regs();
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1360,7 +1291,6 @@ void recompileNextInstruction(int delayslot)
|
||||||
#if 0
|
#if 0
|
||||||
// TODO: Free register ?
|
// TODO: Free register ?
|
||||||
// _freeXMMregs();
|
// _freeXMMregs();
|
||||||
// _freeMMXregs();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1369,7 +1299,7 @@ void recompileNextInstruction(int delayslot)
|
||||||
if( s_bFlushReg ) {
|
if( s_bFlushReg ) {
|
||||||
//if( !_flushUnusedConstReg() ) {
|
//if( !_flushUnusedConstReg() ) {
|
||||||
int flushed = 0;
|
int flushed = 0;
|
||||||
if( _getNumMMXwrite() > 3 ) flushed = _flushMMXunused();
|
if( false ) flushed = 0; // old mmx path. I don't understand why flushed isn't set in the line below
|
||||||
if( !flushed && _getNumXMMwrite() > 2 ) _flushXMMunused();
|
if( !flushed && _getNumXMMwrite() > 2 ) _flushXMMunused();
|
||||||
s_bFlushReg = !flushed;
|
s_bFlushReg = !flushed;
|
||||||
// }
|
// }
|
||||||
|
@ -1381,11 +1311,9 @@ void recompileNextInstruction(int delayslot)
|
||||||
|
|
||||||
//CHECK_XMMCHANGED();
|
//CHECK_XMMCHANGED();
|
||||||
_clearNeededX86regs();
|
_clearNeededX86regs();
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
|
|
||||||
// _freeXMMregs();
|
// _freeXMMregs();
|
||||||
// _freeMMXregs();
|
|
||||||
// _flushCachedRegs();
|
// _flushCachedRegs();
|
||||||
// g_cpuHasConstReg = 1;
|
// g_cpuHasConstReg = 1;
|
||||||
|
|
||||||
|
@ -1684,13 +1612,11 @@ static void __fastcall recRecompile( const u32 startpc )
|
||||||
// reset recomp state variables
|
// reset recomp state variables
|
||||||
s_nBlockCycles = 0;
|
s_nBlockCycles = 0;
|
||||||
pc = startpc;
|
pc = startpc;
|
||||||
x86FpuState = FPU_STATE;
|
|
||||||
g_cpuHasConstReg = g_cpuFlushedConstReg = 1;
|
g_cpuHasConstReg = g_cpuFlushedConstReg = 1;
|
||||||
pxAssert( g_cpuConstRegs[0].UD[0] == 0 );
|
pxAssert( g_cpuConstRegs[0].UD[0] == 0 );
|
||||||
|
|
||||||
_initX86regs();
|
_initX86regs();
|
||||||
_initXMMregs();
|
_initXMMregs();
|
||||||
_initMMXregs();
|
|
||||||
|
|
||||||
if( EmuConfig.Cpu.Recompiler.PreBlockCheckEE )
|
if( EmuConfig.Cpu.Recompiler.PreBlockCheckEE )
|
||||||
{
|
{
|
||||||
|
@ -2090,7 +2016,6 @@ StartRecomp:
|
||||||
|
|
||||||
pxAssert( xGetPtr() < recMem->GetPtrEnd() );
|
pxAssert( xGetPtr() < recMem->GetPtrEnd() );
|
||||||
pxAssert( recConstBufPtr < recConstBuf + RECCONSTBUF_SIZE );
|
pxAssert( recConstBufPtr < recConstBuf + RECCONSTBUF_SIZE );
|
||||||
pxAssert( x86FpuState == 0 );
|
|
||||||
|
|
||||||
pxAssert(xGetPtr() - recPtr < _64kb);
|
pxAssert(xGetPtr() - recPtr < _64kb);
|
||||||
s_pCurBlockEx->x86size = xGetPtr() - recPtr;
|
s_pCurBlockEx->x86size = xGetPtr() - recPtr;
|
||||||
|
|
|
@ -186,7 +186,6 @@ void recSetBranchEQ(int info, int bne, int process)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +210,6 @@ void recSetBranchL(int ltz)
|
||||||
if( ltz ) j32Ptr[ 0 ] = JGE32( 0 );
|
if( ltz ) j32Ptr[ 0 ] = JGE32( 0 );
|
||||||
else j32Ptr[ 0 ] = JL32( 0 );
|
else j32Ptr[ 0 ] = JL32( 0 );
|
||||||
|
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,7 +584,6 @@ void recBLEZ()
|
||||||
|
|
||||||
x86SetJ8( j8Ptr[ 0 ] );
|
x86SetJ8( j8Ptr[ 0 ] );
|
||||||
|
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
|
|
||||||
SaveBranchState();
|
SaveBranchState();
|
||||||
|
@ -634,7 +631,6 @@ void recBGTZ()
|
||||||
|
|
||||||
x86SetJ8( j8Ptr[ 0 ] );
|
x86SetJ8( j8Ptr[ 0 ] );
|
||||||
|
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
|
|
||||||
SaveBranchState();
|
SaveBranchState();
|
||||||
|
@ -807,7 +803,6 @@ void recBLEZL()
|
||||||
if( !(g_cpuConstRegs[_Rs_].SD[0] <= 0) )
|
if( !(g_cpuConstRegs[_Rs_].SD[0] <= 0) )
|
||||||
SetBranchImm( pc + 4);
|
SetBranchImm( pc + 4);
|
||||||
else {
|
else {
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
recompileNextInstruction(1);
|
recompileNextInstruction(1);
|
||||||
SetBranchImm( branchTo );
|
SetBranchImm( branchTo );
|
||||||
|
@ -826,7 +821,6 @@ void recBLEZL()
|
||||||
|
|
||||||
x86SetJ32( j32Ptr[ 0 ] );
|
x86SetJ32( j32Ptr[ 0 ] );
|
||||||
|
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
|
|
||||||
SaveBranchState();
|
SaveBranchState();
|
||||||
|
@ -853,7 +847,6 @@ void recBGTZL()
|
||||||
if( !(g_cpuConstRegs[_Rs_].SD[0] > 0) )
|
if( !(g_cpuConstRegs[_Rs_].SD[0] > 0) )
|
||||||
SetBranchImm( pc + 4);
|
SetBranchImm( pc + 4);
|
||||||
else {
|
else {
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
recompileNextInstruction(1);
|
recompileNextInstruction(1);
|
||||||
SetBranchImm( branchTo );
|
SetBranchImm( branchTo );
|
||||||
|
@ -872,7 +865,6 @@ void recBGTZL()
|
||||||
|
|
||||||
x86SetJ32( j32Ptr[ 0 ] );
|
x86SetJ32( j32Ptr[ 0 ] );
|
||||||
|
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
|
|
||||||
SaveBranchState();
|
SaveBranchState();
|
||||||
|
|
|
@ -121,10 +121,6 @@ void recJALR()
|
||||||
// if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
|
// if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
|
||||||
// xMOVSS(ptr[&cpuRegs.pc], xRegisterSSE(mmreg));
|
// xMOVSS(ptr[&cpuRegs.pc], xRegisterSSE(mmreg));
|
||||||
// }
|
// }
|
||||||
// else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) {
|
|
||||||
// xMOVD(ptr[&cpuRegs.pc], xRegisterMMX(mmreg));
|
|
||||||
// SetMMXstate();
|
|
||||||
// }
|
|
||||||
// else {
|
// else {
|
||||||
// xMOV(eax, ptr[(void*)((int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] )]);
|
// xMOV(eax, ptr[(void*)((int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] )]);
|
||||||
// xMOV(ptr[&cpuRegs.pc], eax);
|
// xMOV(ptr[&cpuRegs.pc], eax);
|
||||||
|
@ -148,7 +144,6 @@ void recJALR()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_clearNeededMMXregs();
|
|
||||||
_clearNeededXMMregs();
|
_clearNeededXMMregs();
|
||||||
recompileNextInstruction(1);
|
recompileNextInstruction(1);
|
||||||
|
|
||||||
|
|
|
@ -115,62 +115,16 @@ void recMFHILO(int hi)
|
||||||
xMOVH.PS(ptr[&cpuRegs.GPR.r[_Rd_].UL[2]], xRegisterSSE(regd));
|
xMOVH.PS(ptr[&cpuRegs.GPR.r[_Rd_].UL[2]], xRegisterSSE(regd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
regd = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rd_, MODE_WRITE);
|
|
||||||
|
|
||||||
if( regd >= 0 ) {
|
|
||||||
xMOVQ(xRegisterMMX(regd), xRegisterSSE(reghi));
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
_deleteEEreg(_Rd_, 0);
|
_deleteEEreg(_Rd_, 0);
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]], xRegisterSSE(reghi));
|
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]], xRegisterSSE(reghi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
reghi = _checkMMXreg(MMX_GPR+xmmhilo, MODE_READ);
|
|
||||||
|
|
||||||
if( reghi >= 0 ) {
|
|
||||||
|
|
||||||
if( regd >= 0 ) {
|
|
||||||
if( EEINST_ISLIVE2(_Rd_) ) {
|
|
||||||
if( xmmregs[regd].mode & MODE_WRITE ) {
|
|
||||||
xMOVH.PS(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 2 ]], xRegisterSSE(regd));
|
|
||||||
}
|
|
||||||
xmmregs[regd].inuse = 0;
|
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]], xRegisterMMX(reghi));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(xRegisterSSE(regd), xRegisterMMX(reghi));
|
|
||||||
xmmregs[regd].mode |= MODE_WRITE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
regd = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rd_, MODE_WRITE);
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
if( regd >= 0 ) {
|
|
||||||
xMOVQ(xRegisterMMX(regd), xRegisterMMX(reghi));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_deleteEEreg(_Rd_, 0);
|
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]], xRegisterMMX(reghi));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
if( regd >= 0 ) {
|
if( regd >= 0 ) {
|
||||||
if( EEINST_ISLIVE2(_Rd_) ) xMOVL.PS(xRegisterSSE(regd), ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UD[ 0 ] : (uptr)&cpuRegs.LO.UD[ 0 ])]);
|
if( EEINST_ISLIVE2(_Rd_) ) xMOVL.PS(xRegisterSSE(regd), ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UD[ 0 ] : (uptr)&cpuRegs.LO.UD[ 0 ])]);
|
||||||
else xMOVQZX(xRegisterSSE(regd), ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UD[ 0 ] : (uptr)&cpuRegs.LO.UD[ 0 ])]);
|
else xMOVQZX(xRegisterSSE(regd), ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UD[ 0 ] : (uptr)&cpuRegs.LO.UD[ 0 ])]);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
regd = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rd_, MODE_WRITE);
|
|
||||||
|
|
||||||
if( regd >= 0 ) {
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(xRegisterMMX(regd), ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UD[ 0 ] : (uptr)&cpuRegs.LO.UD[ 0 ])]);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
_deleteEEreg(_Rd_, 0);
|
_deleteEEreg(_Rd_, 0);
|
||||||
xMOV(eax, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 0 ] : (uptr)&cpuRegs.LO.UL[ 0 ])]);
|
xMOV(eax, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 0 ] : (uptr)&cpuRegs.LO.UL[ 0 ])]);
|
||||||
|
@ -180,8 +134,6 @@ void recMFHILO(int hi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void recMTHILO(int hi)
|
void recMTHILO(int hi)
|
||||||
{
|
{
|
||||||
|
@ -208,63 +160,16 @@ void recMTHILO(int hi)
|
||||||
xmmregs[regs].mode |= MODE_WRITE;
|
xmmregs[regs].mode |= MODE_WRITE;
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
regs = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ);
|
|
||||||
|
|
||||||
if( regs >= 0 ) {
|
|
||||||
|
|
||||||
if( EEINST_ISLIVE2(xmmhilo) ) {
|
|
||||||
if( xmmregs[reghi].mode & MODE_WRITE ) {
|
|
||||||
xMOVH.PS(ptr[(void*)(addrhilo+8)], xRegisterSSE(reghi));
|
|
||||||
}
|
|
||||||
xmmregs[reghi].inuse = 0;
|
|
||||||
xMOVQ(ptr[(void*)(addrhilo)], xRegisterMMX(regs));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(xRegisterSSE(reghi), xRegisterMMX(regs));
|
|
||||||
xmmregs[reghi].mode |= MODE_WRITE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
_flushConstReg(_Rs_);
|
_flushConstReg(_Rs_);
|
||||||
xMOVL.PS(xRegisterSSE(reghi), ptr[&cpuRegs.GPR.r[ _Rs_ ].UD[ 0 ]]);
|
xMOVL.PS(xRegisterSSE(reghi), ptr[&cpuRegs.GPR.r[ _Rs_ ].UD[ 0 ]]);
|
||||||
xmmregs[reghi].mode |= MODE_WRITE;
|
xmmregs[reghi].mode |= MODE_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
reghi = _allocCheckGPRtoMMX(g_pCurInstInfo, xmmhilo, MODE_WRITE);
|
|
||||||
|
|
||||||
if( reghi >= 0 ) {
|
|
||||||
if( regs >= 0 ) {
|
|
||||||
//SetMMXstate();
|
|
||||||
xMOVQ(xRegisterMMX(reghi), xRegisterSSE(regs));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
regs = _checkMMXreg(MMX_GPR+_Rs_, MODE_WRITE);
|
|
||||||
|
|
||||||
if( regs >= 0 ) {
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(xRegisterMMX(reghi), xRegisterMMX(regs));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_flushConstReg(_Rs_);
|
|
||||||
xMOVQ(xRegisterMMX(reghi), ptr[&cpuRegs.GPR.r[ _Rs_ ].UD[ 0 ]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
if( regs >= 0 ) {
|
if( regs >= 0 ) {
|
||||||
xMOVQ(ptr[(void*)(addrhilo)], xRegisterSSE(regs));
|
xMOVQ(ptr[(void*)(addrhilo)], xRegisterSSE(regs));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
regs = _checkMMXreg(MMX_GPR+_Rs_, MODE_WRITE);
|
|
||||||
|
|
||||||
if( regs >= 0 ) {
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(ptr[(void*)(addrhilo)], xRegisterMMX(regs));
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
if( GPR_IS_CONST1(_Rs_) ) {
|
if( GPR_IS_CONST1(_Rs_) ) {
|
||||||
xMOV(ptr32[(u32*)(addrhilo)], g_cpuConstRegs[_Rs_].UL[0] );
|
xMOV(ptr32[(u32*)(addrhilo)], g_cpuConstRegs[_Rs_].UL[0] );
|
||||||
|
@ -281,8 +186,6 @@ void recMTHILO(int hi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void recMFHI()
|
void recMFHI()
|
||||||
{
|
{
|
||||||
|
@ -344,13 +247,6 @@ void recMFHILO1(int hi)
|
||||||
|
|
||||||
xmmregs[regd].mode |= MODE_WRITE;
|
xmmregs[regd].mode |= MODE_WRITE;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
regd = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rd_, MODE_WRITE);
|
|
||||||
|
|
||||||
if( regd >= 0 ) {
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(xRegisterMMX(regd), ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UD[ 1 ] : (uptr)&cpuRegs.LO.UD[ 1 ])]);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
_deleteEEreg(_Rd_, 0);
|
_deleteEEreg(_Rd_, 0);
|
||||||
xMOV(eax, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 2 ] : (uptr)&cpuRegs.LO.UL[ 2 ])]);
|
xMOV(eax, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 2 ] : (uptr)&cpuRegs.LO.UL[ 2 ])]);
|
||||||
|
@ -360,7 +256,6 @@ void recMFHILO1(int hi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void recMTHILO1(int hi)
|
void recMTHILO1(int hi)
|
||||||
{
|
{
|
||||||
|
@ -386,13 +281,6 @@ void recMTHILO1(int hi)
|
||||||
if( regs >= 0 ) {
|
if( regs >= 0 ) {
|
||||||
xMOVQ(ptr[(void*)(addrhilo+8)], xRegisterSSE(regs));
|
xMOVQ(ptr[(void*)(addrhilo+8)], xRegisterSSE(regs));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
regs = _checkMMXreg(MMX_GPR+_Rs_, MODE_WRITE);
|
|
||||||
|
|
||||||
if( regs >= 0 ) {
|
|
||||||
SetMMXstate();
|
|
||||||
xMOVQ(ptr[(void*)(addrhilo+8)], xRegisterMMX(regs));
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
if( GPR_IS_CONST1(_Rs_) ) {
|
if( GPR_IS_CONST1(_Rs_) ) {
|
||||||
xMOV(ptr32[(u32*)(addrhilo+8)], g_cpuConstRegs[_Rs_].UL[0] );
|
xMOV(ptr32[(u32*)(addrhilo+8)], g_cpuConstRegs[_Rs_].UL[0] );
|
||||||
|
@ -408,7 +296,6 @@ void recMTHILO1(int hi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void recMFHI1()
|
void recMFHI1()
|
||||||
{
|
{
|
||||||
|
@ -456,47 +343,24 @@ void recMOVZtemp_consts(int info)
|
||||||
|
|
||||||
void recMOVZtemp_constt(int info)
|
void recMOVZtemp_constt(int info)
|
||||||
{
|
{
|
||||||
// Fixme: MMX problem
|
|
||||||
if(0/* _hasFreeXMMreg() */) {
|
|
||||||
int t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
xMOVQ(xRegisterMMX(t0reg), ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], xRegisterMMX(t0reg));
|
|
||||||
_freeMMXreg(t0reg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||||
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void recMOVZtemp_(int info)
|
void recMOVZtemp_(int info)
|
||||||
{
|
{
|
||||||
int t0reg = -1;
|
|
||||||
|
|
||||||
// Fixme: MMX problem
|
|
||||||
if(0/* _hasFreeXMMreg() */)
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
|
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ]);
|
||||||
xOR(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ] ]);
|
xOR(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ] ]);
|
||||||
j8Ptr[ 0 ] = JNZ8( 0 );
|
j8Ptr[ 0 ] = JNZ8( 0 );
|
||||||
|
|
||||||
if( t0reg >= 0 ) {
|
|
||||||
xMOVQ(xRegisterMMX(t0reg), ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], xRegisterMMX(t0reg));
|
|
||||||
_freeMMXreg(t0reg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||||
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||||
}
|
|
||||||
|
|
||||||
x86SetJ8( j8Ptr[ 0 ] );
|
x86SetJ8( j8Ptr[ 0 ] );
|
||||||
SetMMXstate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EERECOMPILE_CODE0(MOVZtemp, XMMINFO_READS|XMMINFO_READD|XMMINFO_READD|XMMINFO_WRITED);
|
EERECOMPILE_CODE0(MOVZtemp, XMMINFO_READS|XMMINFO_READD|XMMINFO_READD|XMMINFO_WRITED);
|
||||||
|
@ -535,48 +399,24 @@ void recMOVNtemp_consts(int info)
|
||||||
|
|
||||||
void recMOVNtemp_constt(int info)
|
void recMOVNtemp_constt(int info)
|
||||||
{
|
{
|
||||||
// Fixme: MMX problem
|
|
||||||
if(0/* _hasFreeXMMreg() */) {
|
|
||||||
int t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
xMOVQ(xRegisterMMX(t0reg), ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], xRegisterMMX(t0reg));
|
|
||||||
_freeMMXreg(t0reg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||||
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void recMOVNtemp_(int info)
|
void recMOVNtemp_(int info)
|
||||||
{
|
{
|
||||||
int t0reg=-1;
|
|
||||||
|
|
||||||
// Fixme: MMX problem
|
|
||||||
if(0/* _hasFreeXMMreg() */)
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
|
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ]);
|
||||||
xOR(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ] ]);
|
xOR(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ] ]);
|
||||||
j8Ptr[ 0 ] = JZ8( 0 );
|
j8Ptr[ 0 ] = JZ8( 0 );
|
||||||
|
|
||||||
if( t0reg >= 0 ) {
|
|
||||||
xMOVQ(xRegisterMMX(t0reg), ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], xRegisterMMX(t0reg));
|
|
||||||
_freeMMXreg(t0reg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||||
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||||
}
|
|
||||||
|
|
||||||
x86SetJ8( j8Ptr[ 0 ] );
|
x86SetJ8( j8Ptr[ 0 ] );
|
||||||
|
|
||||||
SetMMXstate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EERECOMPILE_CODE0(MOVNtemp, XMMINFO_READS|XMMINFO_READD|XMMINFO_READD|XMMINFO_WRITED);
|
EERECOMPILE_CODE0(MOVNtemp, XMMINFO_READS|XMMINFO_READD|XMMINFO_READD|XMMINFO_WRITED);
|
||||||
|
|
|
@ -65,8 +65,6 @@ void recWritebackHILO(int info, int writed, int upper)
|
||||||
|
|
||||||
if( g_pCurInstInfo->regs[XMMGPR_LO] & testlive ) {
|
if( g_pCurInstInfo->regs[XMMGPR_LO] & testlive ) {
|
||||||
|
|
||||||
_deleteMMXreg(XMMGPR_LO, 2);
|
|
||||||
|
|
||||||
if( (reglo = _checkXMMreg(XMMTYPE_GPRREG, XMMGPR_LO, MODE_READ)) >= 0 ) {
|
if( (reglo = _checkXMMreg(XMMTYPE_GPRREG, XMMGPR_LO, MODE_READ)) >= 0 ) {
|
||||||
if( xmmregs[reglo].mode & MODE_WRITE ) {
|
if( xmmregs[reglo].mode & MODE_WRITE ) {
|
||||||
if( upper ) xMOVQ(ptr[(void*)(loaddr-8)], xRegisterSSE(reglo));
|
if( upper ) xMOVQ(ptr[(void*)(loaddr-8)], xRegisterSSE(reglo));
|
||||||
|
@ -107,8 +105,6 @@ void recWritebackHILO(int info, int writed, int upper)
|
||||||
}
|
}
|
||||||
|
|
||||||
if( g_pCurInstInfo->regs[XMMGPR_HI] & testlive ) {
|
if( g_pCurInstInfo->regs[XMMGPR_HI] & testlive ) {
|
||||||
_deleteMMXreg(XMMGPR_HI, 2);
|
|
||||||
|
|
||||||
if( (reghi = _checkXMMreg(XMMTYPE_GPRREG, XMMGPR_HI, MODE_READ)) >= 0 ) {
|
if( (reghi = _checkXMMreg(XMMTYPE_GPRREG, XMMGPR_HI, MODE_READ)) >= 0 ) {
|
||||||
if( xmmregs[reghi].mode & MODE_WRITE ) {
|
if( xmmregs[reghi].mode & MODE_WRITE ) {
|
||||||
if( upper ) xMOVQ(ptr[(void*)(hiaddr-8)], xRegisterSSE(reghi));
|
if( upper ) xMOVQ(ptr[(void*)(hiaddr-8)], xRegisterSSE(reghi));
|
||||||
|
@ -125,126 +121,6 @@ void recWritebackHILO(int info, int writed, int upper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void recWritebackHILOMMX(int info, int regsource, int writed, int upper)
|
|
||||||
{
|
|
||||||
int regd, t0reg, t1reg = -1;
|
|
||||||
uptr loaddr = (uptr)&cpuRegs.LO.UL[ upper ? 2 : 0 ];
|
|
||||||
uptr hiaddr = (uptr)&cpuRegs.HI.UL[ upper ? 2 : 0 ];
|
|
||||||
u8 testlive = upper?EEINST_LIVE2:EEINST_LIVE0;
|
|
||||||
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
xMOVQ(xRegisterMMX(t0reg), xRegisterMMX(regsource));
|
|
||||||
xPSRA.D(xRegisterMMX(t0reg), 31); // shift in 0s
|
|
||||||
|
|
||||||
if( (g_pCurInstInfo->regs[XMMGPR_LO] & testlive) || (writed && _Rd_) ) {
|
|
||||||
if( (g_pCurInstInfo->regs[XMMGPR_HI] & testlive) )
|
|
||||||
{
|
|
||||||
if( !_hasFreeMMXreg() ) {
|
|
||||||
if( g_pCurInstInfo->regs[XMMGPR_HI] & testlive )
|
|
||||||
_deleteMMXreg(MMX_GPR+MMX_HI, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
t1reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
xMOVQ(xRegisterMMX(t1reg), xRegisterMMX(regsource));
|
|
||||||
}
|
|
||||||
|
|
||||||
xPUNPCK.LDQ(xRegisterMMX(regsource), xRegisterMMX(t0reg));
|
|
||||||
}
|
|
||||||
|
|
||||||
if( g_pCurInstInfo->regs[XMMGPR_LO] & testlive ) {
|
|
||||||
int reglo;
|
|
||||||
if( !upper && (reglo = _allocCheckGPRtoMMX(g_pCurInstInfo, XMMGPR_LO, MODE_WRITE)) >= 0 ) {
|
|
||||||
xMOVQ(xRegisterMMX(reglo), xRegisterMMX(regsource));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reglo = _checkXMMreg(XMMTYPE_GPRREG, XMMGPR_LO, MODE_READ);
|
|
||||||
|
|
||||||
xMOVQ(ptr[(void*)(loaddr)], xRegisterMMX(regsource));
|
|
||||||
|
|
||||||
if( reglo >= 0 ) {
|
|
||||||
if( xmmregs[reglo].mode & MODE_WRITE ) {
|
|
||||||
if( upper ) xMOVQ(ptr[(void*)(loaddr-8)], xRegisterSSE(reglo));
|
|
||||||
else xMOVH.PS(ptr[(void*)(loaddr+8)], xRegisterSSE(reglo));
|
|
||||||
}
|
|
||||||
xmmregs[reglo].inuse = 0;
|
|
||||||
reglo = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( writed && _Rd_ )
|
|
||||||
{
|
|
||||||
regd = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rd_, MODE_WRITE);
|
|
||||||
|
|
||||||
if( regd >= 0 ) {
|
|
||||||
if( regd != regsource ) xMOVQ(xRegisterMMX(regd), xRegisterMMX(regsource));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
regd = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_READ);
|
|
||||||
|
|
||||||
if( regd >= 0 ) {
|
|
||||||
if( g_pCurInstInfo->regs[XMMGPR_LO] & testlive ) {
|
|
||||||
// lo written
|
|
||||||
xMOVL.PS(xRegisterSSE(regd), ptr[(void*)(loaddr)]);
|
|
||||||
xmmregs[regd].mode |= MODE_WRITE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], xRegisterMMX(regsource));
|
|
||||||
|
|
||||||
if( xmmregs[regd].mode & MODE_WRITE ) {
|
|
||||||
xMOVH.PS(ptr[&cpuRegs.GPR.r[_Rd_].UL[2]], xRegisterSSE(regd));
|
|
||||||
}
|
|
||||||
|
|
||||||
xmmregs[regd].inuse = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], xRegisterMMX(regsource));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( g_pCurInstInfo->regs[XMMGPR_HI] & testlive ) {
|
|
||||||
|
|
||||||
int mmreg = -1, reghi;
|
|
||||||
|
|
||||||
if( t1reg >= 0 ) {
|
|
||||||
xPUNPCK.HDQ(xRegisterMMX(t1reg), xRegisterMMX(t0reg));
|
|
||||||
mmreg = t1reg;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// can't modify regsource
|
|
||||||
xPUNPCK.HDQ(xRegisterMMX(t0reg), xRegisterMMX(regsource));
|
|
||||||
mmreg = t0reg;
|
|
||||||
xPSHUF.W(xRegisterMMX(t0reg), xRegisterMMX(t0reg), 0x4e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( upper ) {
|
|
||||||
reghi = _checkXMMreg(XMMTYPE_GPRREG, XMMGPR_HI, MODE_READ);
|
|
||||||
if( reghi >= 0 ) {
|
|
||||||
if( xmmregs[reghi].mode & MODE_WRITE ) xMOVQ(ptr[(void*)(hiaddr-8)], xRegisterSSE(reghi));
|
|
||||||
xmmregs[reghi].inuse = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
xMOVQ(ptr[(void*)(hiaddr)], xRegisterMMX(mmreg));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_deleteGPRtoXMMreg(XMMGPR_HI, 2);
|
|
||||||
_deleteMMXreg(MMX_GPR+MMX_HI, 2);
|
|
||||||
mmxregs[mmreg].mode = MODE_WRITE;
|
|
||||||
mmxregs[mmreg].reg = MMX_GPR+MMX_HI;
|
|
||||||
|
|
||||||
if( t1reg >= 0 ) t1reg = -1;
|
|
||||||
else t0reg = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( t0reg >= 0 ) _freeMMXreg(t0reg&0xf);
|
|
||||||
if( t1reg >= 0 ) _freeMMXreg(t1reg&0xf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void recWritebackConstHILO(u64 res, int writed, int upper)
|
void recWritebackConstHILO(u64 res, int writed, int upper)
|
||||||
{
|
{
|
||||||
int reglo, reghi;
|
int reglo, reghi;
|
||||||
|
@ -253,10 +129,6 @@ void recWritebackConstHILO(u64 res, int writed, int upper)
|
||||||
u8 testlive = upper?EEINST_LIVE2:EEINST_LIVE0;
|
u8 testlive = upper?EEINST_LIVE2:EEINST_LIVE0;
|
||||||
|
|
||||||
if( g_pCurInstInfo->regs[XMMGPR_LO] & testlive ) {
|
if( g_pCurInstInfo->regs[XMMGPR_LO] & testlive ) {
|
||||||
if( !upper && (reglo = _allocCheckGPRtoMMX(g_pCurInstInfo, XMMGPR_LO, MODE_WRITE)) >= 0 ) {
|
|
||||||
xMOVQ(xRegisterMMX(reglo), ptr[recGetImm64(res & 0x80000000 ? -1 : 0, (u32)res)]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reglo = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_LO, MODE_WRITE|MODE_READ);
|
reglo = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_LO, MODE_WRITE|MODE_READ);
|
||||||
|
|
||||||
if( reglo >= 0 ) {
|
if( reglo >= 0 ) {
|
||||||
|
@ -269,14 +141,9 @@ void recWritebackConstHILO(u64 res, int writed, int upper)
|
||||||
xMOV(ptr32[(u32*)(loaddr+4)], (res&0x80000000)?0xffffffff:0);
|
xMOV(ptr32[(u32*)(loaddr+4)], (res&0x80000000)?0xffffffff:0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if( g_pCurInstInfo->regs[XMMGPR_HI] & testlive ) {
|
if( g_pCurInstInfo->regs[XMMGPR_HI] & testlive ) {
|
||||||
|
|
||||||
if( !upper && (reghi = _allocCheckGPRtoMMX(g_pCurInstInfo, XMMGPR_HI, MODE_WRITE)) >= 0 ) {
|
|
||||||
xMOVQ(xRegisterMMX(reghi), ptr[recGetImm64((res >> 63) ? -1 : 0, res >> 32)]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reghi = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_HI, MODE_WRITE|MODE_READ);
|
reghi = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_HI, MODE_WRITE|MODE_READ);
|
||||||
|
|
||||||
if( reghi >= 0 ) {
|
if( reghi >= 0 ) {
|
||||||
|
@ -290,7 +157,6 @@ void recWritebackConstHILO(u64 res, int writed, int upper)
|
||||||
xMOV(ptr32[(u32*)(hiaddr+4)], (res>>63)?0xffffffff:0);
|
xMOV(ptr32[(u32*)(hiaddr+4)], (res>>63)?0xffffffff:0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!writed || !_Rd_) return;
|
if (!writed || !_Rd_) return;
|
||||||
g_cpuConstRegs[_Rd_].UD[0] = (s32)(res & 0xffffffff); //that is the difference
|
g_cpuConstRegs[_Rd_].UD[0] = (s32)(res & 0xffffffff); //that is the difference
|
||||||
|
@ -323,63 +189,18 @@ void recMULTsuper(int info, int upper, int process)
|
||||||
recWritebackHILO(info, 1, upper);
|
recWritebackHILO(info, 1, upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void recMULT_process(int info, int process)
|
|
||||||
//{
|
|
||||||
// if( EEINST_ISLIVE64(XMMGPR_HI) ) {
|
|
||||||
// recMULTsuper(info, 0, process);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// // EEREC_D isn't set
|
|
||||||
// int mmregd;
|
|
||||||
//
|
|
||||||
// if( _Rd_ ) {
|
|
||||||
// assert(EEREC_D == 0);
|
|
||||||
// mmregd = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE);
|
|
||||||
//
|
|
||||||
// if( mmregd < 0 ) {
|
|
||||||
// if( !(process&PROCESS_CONSTS) && ((g_pCurInstInfo->regs[_Rs_]&EEINST_LASTUSE)||!EEINST_ISLIVE64(_Rs_)) ) {
|
|
||||||
// _freeMMXreg(EEREC_S);
|
|
||||||
// _deleteGPRtoXMMreg(_Rd_, 2);
|
|
||||||
// mmxregs[EEREC_S].inuse = 1;
|
|
||||||
// mmxregs[EEREC_S].reg = _Rd_;
|
|
||||||
// mmxregs[EEREC_S].mode = MODE_WRITE;
|
|
||||||
// mmregd = EEREC_S;
|
|
||||||
// }
|
|
||||||
// else if( !(process&PROCESS_CONSTT) && ((g_pCurInstInfo->regs[_Rt_]&EEINST_LASTUSE)||!EEINST_ISLIVE64(_Rt_)) ) {
|
|
||||||
// _freeMMXreg(EEREC_T);
|
|
||||||
// _deleteGPRtoXMMreg(_Rd_, 2);
|
|
||||||
// mmxregs[EEREC_T].inuse = 1;
|
|
||||||
// mmxregs[EEREC_T].reg = _Rd_;
|
|
||||||
// mmxregs[EEREC_T].mode = MODE_WRITE;
|
|
||||||
// mmregd = EEREC_T;
|
|
||||||
// }
|
|
||||||
// else mmregd = _allocMMXreg(-1, MMX_GPR+_Rd_, MODE_WRITE);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// info |= PROCESS_EE_SET_D(mmregd);
|
|
||||||
// }
|
|
||||||
// recMULTUsuper(info, 0, process);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // sometimes _Rd_ can be const
|
|
||||||
// if( _Rd_ ) _eeOnWriteReg(_Rd_, 1);
|
|
||||||
//}
|
|
||||||
|
|
||||||
void recMULT_(int info)
|
void recMULT_(int info)
|
||||||
{
|
{
|
||||||
//recMULT_process(info, 0);
|
|
||||||
recMULTsuper(info, 0, 0);
|
recMULTsuper(info, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recMULT_consts(int info)
|
void recMULT_consts(int info)
|
||||||
{
|
{
|
||||||
//recMULT_process(info, PROCESS_CONSTS);
|
|
||||||
recMULTsuper(info, 0, PROCESS_CONSTS);
|
recMULTsuper(info, 0, PROCESS_CONSTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recMULT_constt(int info)
|
void recMULT_constt(int info)
|
||||||
{
|
{
|
||||||
//recMULT_process(info, PROCESS_CONSTT);
|
|
||||||
recMULTsuper(info, 0, PROCESS_CONSTT);
|
recMULTsuper(info, 0, PROCESS_CONSTT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,8 +521,6 @@ void recMADD()
|
||||||
_deleteEEreg(XMMGPR_HI, 1);
|
_deleteEEreg(XMMGPR_HI, 1);
|
||||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
|
||||||
|
|
||||||
if( GPR_IS_CONST1(_Rs_) ) {
|
if( GPR_IS_CONST1(_Rs_) ) {
|
||||||
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
||||||
|
@ -772,8 +591,6 @@ void recMADDU()
|
||||||
_deleteEEreg(XMMGPR_HI, 1);
|
_deleteEEreg(XMMGPR_HI, 1);
|
||||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
|
||||||
|
|
||||||
if( GPR_IS_CONST1(_Rs_) ) {
|
if( GPR_IS_CONST1(_Rs_) ) {
|
||||||
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
||||||
|
@ -842,8 +659,6 @@ void recMADD1()
|
||||||
_deleteEEreg(XMMGPR_HI, 1);
|
_deleteEEreg(XMMGPR_HI, 1);
|
||||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
|
||||||
|
|
||||||
if( GPR_IS_CONST1(_Rs_) ) {
|
if( GPR_IS_CONST1(_Rs_) ) {
|
||||||
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
||||||
|
@ -914,8 +729,6 @@ void recMADDU1()
|
||||||
_deleteEEreg(XMMGPR_HI, 1);
|
_deleteEEreg(XMMGPR_HI, 1);
|
||||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
|
||||||
|
|
||||||
if( GPR_IS_CONST1(_Rs_) ) {
|
if( GPR_IS_CONST1(_Rs_) ) {
|
||||||
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#include "R5900OpcodeTables.h"
|
#include "R5900OpcodeTables.h"
|
||||||
#include "iR5900.h"
|
#include "iR5900.h"
|
||||||
|
|
||||||
#define NO_MMX 1
|
|
||||||
|
|
||||||
using namespace x86Emitter;
|
using namespace x86Emitter;
|
||||||
|
|
||||||
namespace R5900 {
|
namespace R5900 {
|
||||||
|
@ -145,7 +143,6 @@ void recDSLLs_(int info, int sa)
|
||||||
int rtreg, rdreg;
|
int rtreg, rdreg;
|
||||||
pxAssert( !(info & PROCESS_EE_XMM) );
|
pxAssert( !(info & PROCESS_EE_XMM) );
|
||||||
|
|
||||||
#if NO_MMX
|
|
||||||
_addNeededGPRtoXMMreg(_Rt_);
|
_addNeededGPRtoXMMreg(_Rt_);
|
||||||
_addNeededGPRtoXMMreg(_Rd_);
|
_addNeededGPRtoXMMreg(_Rd_);
|
||||||
rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ);
|
rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ);
|
||||||
|
@ -160,16 +157,6 @@ void recDSLLs_(int info, int sa)
|
||||||
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
||||||
_deleteGPRtoXMMreg(_Rt_, 3);
|
_deleteGPRtoXMMreg(_Rt_, 3);
|
||||||
_deleteGPRtoXMMreg(_Rd_, 3);
|
_deleteGPRtoXMMreg(_Rd_, 3);
|
||||||
#else
|
|
||||||
_addNeededMMXreg(MMX_GPR+_Rt_);
|
|
||||||
_addNeededMMXreg(MMX_GPR+_Rd_);
|
|
||||||
rtreg = _allocMMXreg(-1, MMX_GPR+_Rt_, MODE_READ);
|
|
||||||
rdreg = _allocMMXreg(-1, MMX_GPR+_Rd_, MODE_WRITE);
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
if( rtreg != rdreg ) xMOVQ(xRegisterMMX(rdreg), xRegisterMMX(rtreg));
|
|
||||||
xPSLL.Q(xRegisterMMX(rdreg), sa);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recDSLL_(int info)
|
void recDSLL_(int info)
|
||||||
|
@ -190,7 +177,6 @@ void recDSRLs_(int info, int sa)
|
||||||
int rtreg, rdreg;
|
int rtreg, rdreg;
|
||||||
pxAssert( !(info & PROCESS_EE_XMM) );
|
pxAssert( !(info & PROCESS_EE_XMM) );
|
||||||
|
|
||||||
#if NO_MMX
|
|
||||||
_addNeededGPRtoXMMreg(_Rt_);
|
_addNeededGPRtoXMMreg(_Rt_);
|
||||||
_addNeededGPRtoXMMreg(_Rd_);
|
_addNeededGPRtoXMMreg(_Rd_);
|
||||||
rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ);
|
rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ);
|
||||||
|
@ -205,16 +191,6 @@ void recDSRLs_(int info, int sa)
|
||||||
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
||||||
_deleteGPRtoXMMreg(_Rt_, 3);
|
_deleteGPRtoXMMreg(_Rt_, 3);
|
||||||
_deleteGPRtoXMMreg(_Rd_, 3);
|
_deleteGPRtoXMMreg(_Rd_, 3);
|
||||||
#else
|
|
||||||
_addNeededMMXreg(MMX_GPR+_Rt_);
|
|
||||||
_addNeededMMXreg(MMX_GPR+_Rd_);
|
|
||||||
rtreg = _allocMMXreg(-1, MMX_GPR+_Rt_, MODE_READ);
|
|
||||||
rdreg = _allocMMXreg(-1, MMX_GPR+_Rd_, MODE_WRITE);
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
if( rtreg != rdreg ) xMOVQ(xRegisterMMX(rdreg), xRegisterMMX(rtreg));
|
|
||||||
xPSRL.Q(xRegisterMMX(rdreg), sa);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recDSRL_(int info)
|
void recDSRL_(int info)
|
||||||
|
@ -235,7 +211,6 @@ void recDSRAs_(int info, int sa)
|
||||||
int rtreg, rdreg, t0reg;
|
int rtreg, rdreg, t0reg;
|
||||||
pxAssert( !(info & PROCESS_EE_XMM) );
|
pxAssert( !(info & PROCESS_EE_XMM) );
|
||||||
|
|
||||||
#if NO_MMX
|
|
||||||
_addNeededGPRtoXMMreg(_Rt_);
|
_addNeededGPRtoXMMreg(_Rt_);
|
||||||
_addNeededGPRtoXMMreg(_Rd_);
|
_addNeededGPRtoXMMreg(_Rd_);
|
||||||
rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ);
|
rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ);
|
||||||
|
@ -270,30 +245,6 @@ void recDSRAs_(int info, int sa)
|
||||||
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
||||||
_deleteGPRtoXMMreg(_Rt_, 3);
|
_deleteGPRtoXMMreg(_Rt_, 3);
|
||||||
_deleteGPRtoXMMreg(_Rd_, 3);
|
_deleteGPRtoXMMreg(_Rd_, 3);
|
||||||
#else
|
|
||||||
_addNeededMMXreg(MMX_GPR+_Rt_);
|
|
||||||
_addNeededMMXreg(MMX_GPR+_Rd_);
|
|
||||||
rtreg = _allocMMXreg(-1, MMX_GPR+_Rt_, MODE_READ);
|
|
||||||
rdreg = _allocMMXreg(-1, MMX_GPR+_Rd_, MODE_WRITE);
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
if( rtreg != rdreg ) xMOVQ(xRegisterMMX(rdreg), xRegisterMMX(rtreg));
|
|
||||||
|
|
||||||
if ( sa != 0 ) {
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
xMOVQ(xRegisterMMX(t0reg), xRegisterMMX(rtreg));
|
|
||||||
|
|
||||||
// it is a signed shift
|
|
||||||
xPSRA.D(xRegisterMMX(t0reg), sa);
|
|
||||||
xPSRL.Q(xRegisterMMX(rdreg), sa);
|
|
||||||
|
|
||||||
xPUNPCK.HDQ(xRegisterMMX(t0reg), xRegisterMMX(t0reg)); // shift to lower
|
|
||||||
// take lower dword of rdreg and lower dword of t0reg
|
|
||||||
xPUNPCK.LDQ(xRegisterMMX(rdreg), xRegisterMMX(t0reg));
|
|
||||||
|
|
||||||
_freeMMXreg(t0reg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recDSRA_(int info)
|
void recDSRA_(int info)
|
||||||
|
@ -391,7 +342,6 @@ void recSetShiftV(int info, int* rsreg, int* rtreg, int* rdreg, int* rstemp)
|
||||||
{
|
{
|
||||||
pxAssert( !(info & PROCESS_EE_XMM) );
|
pxAssert( !(info & PROCESS_EE_XMM) );
|
||||||
|
|
||||||
#if NO_MMX
|
|
||||||
_addNeededGPRtoXMMreg(_Rt_);
|
_addNeededGPRtoXMMreg(_Rt_);
|
||||||
_addNeededGPRtoXMMreg(_Rd_);
|
_addNeededGPRtoXMMreg(_Rd_);
|
||||||
*rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ);
|
*rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ);
|
||||||
|
@ -405,21 +355,6 @@ void recSetShiftV(int info, int* rsreg, int* rtreg, int* rdreg, int* rstemp)
|
||||||
*rsreg = *rstemp;
|
*rsreg = *rstemp;
|
||||||
|
|
||||||
if( *rtreg != *rdreg ) xMOVDQA(xRegisterSSE(*rdreg), xRegisterSSE(*rtreg));
|
if( *rtreg != *rdreg ) xMOVDQA(xRegisterSSE(*rdreg), xRegisterSSE(*rtreg));
|
||||||
#else
|
|
||||||
_addNeededMMXreg(MMX_GPR+_Rt_);
|
|
||||||
_addNeededMMXreg(MMX_GPR+_Rd_);
|
|
||||||
*rtreg = _allocMMXreg(-1, MMX_GPR+_Rt_, MODE_READ);
|
|
||||||
*rdreg = _allocMMXreg(-1, MMX_GPR+_Rd_, MODE_WRITE);
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
*rstemp = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
|
|
||||||
xAND(eax, 0x3f);
|
|
||||||
xMOVDZX(xRegisterMMX(*rstemp), eax);
|
|
||||||
*rsreg = *rstemp;
|
|
||||||
|
|
||||||
if( *rtreg != *rdreg ) xMOVQ(xRegisterMMX(*rdreg), xRegisterMMX(*rtreg));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recSetConstShiftV(int info, int* rsreg, int* rdreg, int* rstemp)
|
void recSetConstShiftV(int info, int* rsreg, int* rdreg, int* rstemp)
|
||||||
|
@ -430,7 +365,6 @@ void recSetConstShiftV(int info, int* rsreg, int* rdreg, int* rstemp)
|
||||||
// 2/ CPU has minimum cycle delay between read/write
|
// 2/ CPU has minimum cycle delay between read/write
|
||||||
_flushConstReg(_Rt_);
|
_flushConstReg(_Rt_);
|
||||||
|
|
||||||
#if NO_MMX
|
|
||||||
_addNeededGPRtoXMMreg(_Rd_);
|
_addNeededGPRtoXMMreg(_Rd_);
|
||||||
*rdreg = _allocGPRtoXMMreg(-1, _Rd_, MODE_WRITE);
|
*rdreg = _allocGPRtoXMMreg(-1, _Rd_, MODE_WRITE);
|
||||||
|
|
||||||
|
@ -439,16 +373,6 @@ void recSetConstShiftV(int info, int* rsreg, int* rdreg, int* rstemp)
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
|
xMOV(eax, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
|
||||||
xAND(eax, 0x3f);
|
xAND(eax, 0x3f);
|
||||||
xMOVDZX(xRegisterSSE(*rstemp), eax);
|
xMOVDZX(xRegisterSSE(*rstemp), eax);
|
||||||
#else
|
|
||||||
_addNeededMMXreg(MMX_GPR+_Rd_);
|
|
||||||
*rdreg = _allocMMXreg(-1, MMX_GPR+_Rd_, MODE_WRITE);
|
|
||||||
SetMMXstate();
|
|
||||||
|
|
||||||
*rstemp = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
xMOV(eax, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
|
|
||||||
xAND(eax, 0x3f);
|
|
||||||
xMOVDZX(xRegisterMMX(*rstemp), eax);
|
|
||||||
#endif
|
|
||||||
*rsreg = *rstemp;
|
*rsreg = *rstemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,7 +507,6 @@ void recDSLLV_constt(int info)
|
||||||
{
|
{
|
||||||
int rsreg, rdreg, rstemp = -1;
|
int rsreg, rdreg, rstemp = -1;
|
||||||
recSetConstShiftV(info, &rsreg, &rdreg, &rstemp);
|
recSetConstShiftV(info, &rsreg, &rdreg, &rstemp);
|
||||||
#if NO_MMX
|
|
||||||
xMOVDQA(xRegisterSSE(rdreg), ptr[&cpuRegs.GPR.r[_Rt_]]);
|
xMOVDQA(xRegisterSSE(rdreg), ptr[&cpuRegs.GPR.r[_Rt_]]);
|
||||||
xPSLL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
xPSLL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
||||||
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
||||||
|
@ -594,12 +517,6 @@ void recDSLLV_constt(int info)
|
||||||
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
||||||
//_deleteGPRtoXMMreg(_Rt_, 3);
|
//_deleteGPRtoXMMreg(_Rt_, 3);
|
||||||
_deleteGPRtoXMMreg(_Rd_, 3);
|
_deleteGPRtoXMMreg(_Rd_, 3);
|
||||||
#else
|
|
||||||
|
|
||||||
xMOVQ(xRegisterMMX(rdreg), ptr[&cpuRegs.GPR.r[_Rt_]]);
|
|
||||||
xPSLL.Q(xRegisterMMX(rdreg), xRegisterMMX(rsreg));
|
|
||||||
if( rstemp != -1 ) _freeMMXreg(rstemp);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recDSLLV_(int info)
|
void recDSLLV_(int info)
|
||||||
|
@ -607,7 +524,6 @@ void recDSLLV_(int info)
|
||||||
int rsreg, rtreg, rdreg, rstemp = -1;
|
int rsreg, rtreg, rdreg, rstemp = -1;
|
||||||
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
||||||
|
|
||||||
#if NO_MMX
|
|
||||||
xPSLL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
xPSLL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
||||||
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
||||||
|
|
||||||
|
@ -617,10 +533,6 @@ void recDSLLV_(int info)
|
||||||
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
||||||
_deleteGPRtoXMMreg(_Rt_, 3);
|
_deleteGPRtoXMMreg(_Rt_, 3);
|
||||||
_deleteGPRtoXMMreg(_Rd_, 3);
|
_deleteGPRtoXMMreg(_Rd_, 3);
|
||||||
#else
|
|
||||||
xPSLL.Q(xRegisterMMX(rdreg), xRegisterMMX(rsreg));
|
|
||||||
if( rstemp != -1 ) _freeMMXreg(rstemp);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EERECOMPILE_CODE0(DSLLV, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
|
EERECOMPILE_CODE0(DSLLV, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
|
||||||
|
@ -643,7 +555,6 @@ void recDSRLV_constt(int info)
|
||||||
int rsreg, rdreg, rstemp = -1;
|
int rsreg, rdreg, rstemp = -1;
|
||||||
recSetConstShiftV(info, &rsreg, &rdreg, &rstemp);
|
recSetConstShiftV(info, &rsreg, &rdreg, &rstemp);
|
||||||
|
|
||||||
#if NO_MMX
|
|
||||||
xMOVDQA(xRegisterSSE(rdreg), ptr[&cpuRegs.GPR.r[_Rt_]]);
|
xMOVDQA(xRegisterSSE(rdreg), ptr[&cpuRegs.GPR.r[_Rt_]]);
|
||||||
xPSRL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
xPSRL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
||||||
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
||||||
|
@ -654,11 +565,6 @@ void recDSRLV_constt(int info)
|
||||||
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
||||||
//_deleteGPRtoXMMreg(_Rt_, 3);
|
//_deleteGPRtoXMMreg(_Rt_, 3);
|
||||||
_deleteGPRtoXMMreg(_Rd_, 3);
|
_deleteGPRtoXMMreg(_Rd_, 3);
|
||||||
#else
|
|
||||||
xMOVQ(xRegisterMMX(rdreg), ptr[&cpuRegs.GPR.r[_Rt_]]);
|
|
||||||
xPSRL.Q(xRegisterMMX(rdreg), xRegisterMMX(rsreg));
|
|
||||||
if( rstemp != -1 ) _freeMMXreg(rstemp);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recDSRLV_(int info)
|
void recDSRLV_(int info)
|
||||||
|
@ -666,7 +572,6 @@ void recDSRLV_(int info)
|
||||||
int rsreg, rtreg, rdreg, rstemp = -1;
|
int rsreg, rtreg, rdreg, rstemp = -1;
|
||||||
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
||||||
|
|
||||||
#if NO_MMX
|
|
||||||
xPSRL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
xPSRL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
||||||
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
||||||
|
|
||||||
|
@ -676,10 +581,6 @@ void recDSRLV_(int info)
|
||||||
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
||||||
_deleteGPRtoXMMreg(_Rt_, 3);
|
_deleteGPRtoXMMreg(_Rt_, 3);
|
||||||
_deleteGPRtoXMMreg(_Rd_, 3);
|
_deleteGPRtoXMMreg(_Rd_, 3);
|
||||||
#else
|
|
||||||
xPSRL.Q(xRegisterMMX(rdreg), xRegisterMMX(rsreg));
|
|
||||||
if( rstemp != -1 ) _freeMMXreg(rstemp);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EERECOMPILE_CODE0(DSRLV, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
|
EERECOMPILE_CODE0(DSRLV, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
|
||||||
|
@ -700,7 +601,6 @@ void recDSRAV_consts(int info)
|
||||||
void recDSRAV_constt(int info)
|
void recDSRAV_constt(int info)
|
||||||
{
|
{
|
||||||
int rsreg, rdreg, rstemp = -1, t0reg, t1reg;
|
int rsreg, rdreg, rstemp = -1, t0reg, t1reg;
|
||||||
#if NO_MMX
|
|
||||||
t0reg = _allocTempXMMreg(XMMT_INT, -1);
|
t0reg = _allocTempXMMreg(XMMT_INT, -1);
|
||||||
t1reg = _allocTempXMMreg(XMMT_INT, -1);
|
t1reg = _allocTempXMMreg(XMMT_INT, -1);
|
||||||
|
|
||||||
|
@ -734,41 +634,11 @@ void recDSRAV_constt(int info)
|
||||||
_freeXMMreg(t0reg);
|
_freeXMMreg(t0reg);
|
||||||
_freeXMMreg(t1reg);
|
_freeXMMreg(t1reg);
|
||||||
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
||||||
#else
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
t1reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
|
|
||||||
recSetConstShiftV(info, &rsreg, &rdreg, &rstemp);
|
|
||||||
|
|
||||||
xMOVQ(xRegisterMMX(rdreg), ptr[&cpuRegs.GPR.r[_Rt_]]);
|
|
||||||
xPXOR(xRegisterMMX(t0reg), xRegisterMMX(t0reg));
|
|
||||||
|
|
||||||
// calc high bit
|
|
||||||
xMOVQ(xRegisterMMX(t1reg), xRegisterMMX(rdreg));
|
|
||||||
xPCMP.GTD(xRegisterMMX(t0reg), xRegisterMMX(rdreg));
|
|
||||||
xPUNPCK.HDQ(xRegisterMMX(t0reg), xRegisterMMX(t0reg)); // shift to lower
|
|
||||||
|
|
||||||
// shift highest bit, 64 - eax
|
|
||||||
xMOV(eax, 64);
|
|
||||||
xMOVDZX(xRegisterMMX(t1reg), eax);
|
|
||||||
xPSUB.D(xRegisterMMX(t1reg), xRegisterMMX(rsreg));
|
|
||||||
|
|
||||||
// right logical shift
|
|
||||||
xPSRL.Q(xRegisterMMX(rdreg), xRegisterMMX(rsreg));
|
|
||||||
xPSLL.Q(xRegisterMMX(t0reg), xRegisterMMX(t1reg)); // highest bits
|
|
||||||
|
|
||||||
xPOR(xRegisterMMX(rdreg), xRegisterMMX(t0reg));
|
|
||||||
|
|
||||||
_freeMMXreg(t0reg);
|
|
||||||
_freeMMXreg(t1reg);
|
|
||||||
if( rstemp != -1 ) _freeMMXreg(rstemp);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recDSRAV_(int info)
|
void recDSRAV_(int info)
|
||||||
{
|
{
|
||||||
int rsreg, rtreg, rdreg, rstemp = -1, t0reg, t1reg;
|
int rsreg, rtreg, rdreg, rstemp = -1, t0reg, t1reg;
|
||||||
#if NO_MMX
|
|
||||||
t0reg = _allocTempXMMreg(XMMT_INT, -1);
|
t0reg = _allocTempXMMreg(XMMT_INT, -1);
|
||||||
t1reg = _allocTempXMMreg(XMMT_INT, -1);
|
t1reg = _allocTempXMMreg(XMMT_INT, -1);
|
||||||
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
||||||
|
@ -801,33 +671,6 @@ void recDSRAV_(int info)
|
||||||
_freeXMMreg(t0reg);
|
_freeXMMreg(t0reg);
|
||||||
_freeXMMreg(t1reg);
|
_freeXMMreg(t1reg);
|
||||||
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
||||||
#else
|
|
||||||
t0reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
t1reg = _allocMMXreg(-1, MMX_TEMP, 0);
|
|
||||||
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
|
||||||
|
|
||||||
xPXOR(xRegisterMMX(t0reg), xRegisterMMX(t0reg));
|
|
||||||
|
|
||||||
// calc high bit
|
|
||||||
xMOVQ(xRegisterMMX(t1reg), xRegisterMMX(rdreg));
|
|
||||||
xPCMP.GTD(xRegisterMMX(t0reg), xRegisterMMX(rdreg));
|
|
||||||
xPUNPCK.HDQ(xRegisterMMX(t0reg), xRegisterMMX(t0reg)); // shift to lower
|
|
||||||
|
|
||||||
// shift highest bit, 64 - eax
|
|
||||||
xMOV(eax, 64);
|
|
||||||
xMOVDZX(xRegisterMMX(t1reg), eax);
|
|
||||||
xPSUB.D(xRegisterMMX(t1reg), xRegisterMMX(rsreg));
|
|
||||||
|
|
||||||
// right logical shift
|
|
||||||
xPSRL.Q(xRegisterMMX(rdreg), xRegisterMMX(rsreg));
|
|
||||||
xPSLL.Q(xRegisterMMX(t0reg), xRegisterMMX(t1reg)); // highest bits
|
|
||||||
|
|
||||||
xPOR(xRegisterMMX(rdreg), xRegisterMMX(t0reg));
|
|
||||||
|
|
||||||
_freeMMXreg(t0reg);
|
|
||||||
_freeMMXreg(t1reg);
|
|
||||||
if( rstemp != -1 ) _freeMMXreg(rstemp);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EERECOMPILE_CODE0(DSRAV, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
|
EERECOMPILE_CODE0(DSRAV, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
|
||||||
|
|
|
@ -51,7 +51,6 @@ void _deleteEEreg(int reg, int flush)
|
||||||
}
|
}
|
||||||
GPR_DEL_CONST(reg);
|
GPR_DEL_CONST(reg);
|
||||||
_deleteGPRtoXMMreg(reg, flush ? 0 : 2);
|
_deleteGPRtoXMMreg(reg, flush ? 0 : 2);
|
||||||
_deleteMMXreg(MMX_GPR+reg, flush ? 0 : 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _flushEEreg(int reg)
|
void _flushEEreg(int reg)
|
||||||
|
@ -62,24 +61,23 @@ void _flushEEreg(int reg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_deleteGPRtoXMMreg(reg, 1);
|
_deleteGPRtoXMMreg(reg, 1);
|
||||||
_deleteMMXreg(MMX_GPR + reg, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not mmx, then xmm
|
// if not mmx, then xmm
|
||||||
int eeProcessHILO(int reg, int mode, int mmx)
|
int eeProcessHILO(int reg, int mode, int mmx)
|
||||||
{
|
{
|
||||||
// Fixme: MMX problem
|
// Fixme: MMX problem
|
||||||
int usemmx = 0/*mmx && _hasFreeMMXreg()*/;
|
int usemmx = 0;
|
||||||
if( (usemmx || _hasFreeXMMreg()) || !(g_pCurInstInfo->regs[reg]&EEINST_LASTUSE) ) {
|
if( (usemmx || _hasFreeXMMreg()) || !(g_pCurInstInfo->regs[reg]&EEINST_LASTUSE) ) {
|
||||||
//if( usemmx ) return _allocMMXreg(-1, MMX_GPR+reg, mode);
|
|
||||||
return _allocGPRtoXMMreg(-1, reg, mode);
|
return _allocGPRtoXMMreg(-1, reg, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROCESS_EE_SETMODES(mmreg) ((mmxregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITES:0)
|
// Strangely this code is used on NOT-MMX path ...
|
||||||
#define PROCESS_EE_SETMODET(mmreg) ((mmxregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITET:0)
|
#define PROCESS_EE_SETMODES(mmreg) (/*(mmxregs[mmreg].mode&MODE_WRITE)*/ false ?PROCESS_EE_MODEWRITES:0)
|
||||||
|
#define PROCESS_EE_SETMODET(mmreg) (/*(mmxregs[mmreg].mode&MODE_WRITE)*/ false ?PROCESS_EE_MODEWRITET:0)
|
||||||
|
|
||||||
// ignores XMMINFO_READS, XMMINFO_READT, and XMMINFO_READD_LO from xmminfo
|
// ignores XMMINFO_READS, XMMINFO_READT, and XMMINFO_READD_LO from xmminfo
|
||||||
// core of reg caching
|
// core of reg caching
|
||||||
|
@ -91,7 +89,6 @@ void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNP
|
||||||
|
|
||||||
if( GPR_IS_CONST2(_Rs_, _Rt_) ) {
|
if( GPR_IS_CONST2(_Rs_, _Rt_) ) {
|
||||||
if( xmminfo & XMMINFO_WRITED ) {
|
if( xmminfo & XMMINFO_WRITED ) {
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
|
||||||
_deleteGPRtoXMMreg(_Rd_, 2);
|
_deleteGPRtoXMMreg(_Rd_, 2);
|
||||||
}
|
}
|
||||||
if( xmminfo&XMMINFO_WRITED ) GPR_SET_CONST(_Rd_);
|
if( xmminfo&XMMINFO_WRITED ) GPR_SET_CONST(_Rd_);
|
||||||
|
@ -135,7 +132,6 @@ void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNP
|
||||||
_freeXMMreg(mmreg1);
|
_freeXMMreg(mmreg1);
|
||||||
if( GPR_IS_CONST1(_Rs_) ) info &= ~PROCESS_EE_MODEWRITET;
|
if( GPR_IS_CONST1(_Rs_) ) info &= ~PROCESS_EE_MODEWRITET;
|
||||||
else info &= ~PROCESS_EE_MODEWRITES;
|
else info &= ~PROCESS_EE_MODEWRITES;
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
|
||||||
xmmregs[mmreg1].inuse = 1;
|
xmmregs[mmreg1].inuse = 1;
|
||||||
xmmregs[mmreg1].reg = _Rd_;
|
xmmregs[mmreg1].reg = _Rd_;
|
||||||
xmmregs[mmreg1].mode = moded;
|
xmmregs[mmreg1].mode = moded;
|
||||||
|
@ -185,7 +181,6 @@ void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNP
|
||||||
if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rt_)) ) {
|
if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rt_)) ) {
|
||||||
_freeXMMreg(mmreg2);
|
_freeXMMreg(mmreg2);
|
||||||
info &= ~PROCESS_EE_MODEWRITET;
|
info &= ~PROCESS_EE_MODEWRITET;
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
|
||||||
xmmregs[mmreg2].inuse = 1;
|
xmmregs[mmreg2].inuse = 1;
|
||||||
xmmregs[mmreg2].reg = _Rd_;
|
xmmregs[mmreg2].reg = _Rd_;
|
||||||
xmmregs[mmreg2].mode = moded;
|
xmmregs[mmreg2].mode = moded;
|
||||||
|
@ -194,7 +189,6 @@ void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNP
|
||||||
else if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_)) ) {
|
else if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_)) ) {
|
||||||
_freeXMMreg(mmreg1);
|
_freeXMMreg(mmreg1);
|
||||||
info &= ~PROCESS_EE_MODEWRITES;
|
info &= ~PROCESS_EE_MODEWRITES;
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
|
||||||
xmmregs[mmreg1].inuse = 1;
|
xmmregs[mmreg1].inuse = 1;
|
||||||
xmmregs[mmreg1].reg = _Rd_;
|
xmmregs[mmreg1].reg = _Rd_;
|
||||||
xmmregs[mmreg1].mode = moded;
|
xmmregs[mmreg1].mode = moded;
|
||||||
|
@ -230,19 +224,13 @@ void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNP
|
||||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||||
if( xmminfo&XMMINFO_WRITED )
|
if( xmminfo&XMMINFO_WRITED )
|
||||||
_deleteGPRtoXMMreg(_Rd_, (xmminfo&XMMINFO_READD)?0:2);
|
_deleteGPRtoXMMreg(_Rd_, (xmminfo&XMMINFO_READD)?0:2);
|
||||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
|
||||||
if( xmminfo&XMMINFO_WRITED )
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, (xmminfo&XMMINFO_READD)?0:2);
|
|
||||||
|
|
||||||
// don't delete, fn will take care of them
|
// don't delete, fn will take care of them
|
||||||
// if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) {
|
// if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) {
|
||||||
// _deleteGPRtoXMMreg(XMMGPR_LO, (xmminfo&XMMINFO_READLO)?1:0);
|
// _deleteGPRtoXMMreg(XMMGPR_LO, (xmminfo&XMMINFO_READLO)?1:0);
|
||||||
// _deleteMMXreg(MMX_GPR+MMX_LO, (xmminfo&XMMINFO_READLO)?1:0);
|
|
||||||
// }
|
// }
|
||||||
// if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) {
|
// if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) {
|
||||||
// _deleteGPRtoXMMreg(XMMGPR_HI, (xmminfo&XMMINFO_READHI)?1:0);
|
// _deleteGPRtoXMMreg(XMMGPR_HI, (xmminfo&XMMINFO_READHI)?1:0);
|
||||||
// _deleteMMXreg(MMX_GPR+MMX_HI, (xmminfo&XMMINFO_READHI)?1:0);
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if( GPR_IS_CONST1(_Rs_) ) {
|
if( GPR_IS_CONST1(_Rs_) ) {
|
||||||
|
@ -268,7 +256,6 @@ void eeRecompileCode1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
||||||
if ( ! _Rt_ ) return;
|
if ( ! _Rt_ ) return;
|
||||||
|
|
||||||
if( GPR_IS_CONST1(_Rs_) ) {
|
if( GPR_IS_CONST1(_Rs_) ) {
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 2);
|
|
||||||
_deleteGPRtoXMMreg(_Rt_, 2);
|
_deleteGPRtoXMMreg(_Rt_, 2);
|
||||||
GPR_SET_CONST(_Rt_);
|
GPR_SET_CONST(_Rt_);
|
||||||
constcode();
|
constcode();
|
||||||
|
@ -293,7 +280,6 @@ void eeRecompileCode1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
||||||
if( (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_) ) {
|
if( (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_) ) {
|
||||||
_freeXMMreg(mmreg1);
|
_freeXMMreg(mmreg1);
|
||||||
info &= ~PROCESS_EE_MODEWRITES;
|
info &= ~PROCESS_EE_MODEWRITES;
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 2);
|
|
||||||
xmmregs[mmreg1].inuse = 1;
|
xmmregs[mmreg1].inuse = 1;
|
||||||
xmmregs[mmreg1].reg = _Rt_;
|
xmmregs[mmreg1].reg = _Rt_;
|
||||||
xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ;
|
xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ;
|
||||||
|
@ -314,8 +300,6 @@ void eeRecompileCode1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
||||||
// regular x86
|
// regular x86
|
||||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||||
_deleteGPRtoXMMreg(_Rt_, 2);
|
_deleteGPRtoXMMreg(_Rt_, 2);
|
||||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 2);
|
|
||||||
|
|
||||||
noconstcode(0);
|
noconstcode(0);
|
||||||
GPR_DEL_CONST(_Rt_);
|
GPR_DEL_CONST(_Rt_);
|
||||||
|
@ -328,7 +312,6 @@ void eeRecompileCode2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
||||||
if ( ! _Rd_ ) return;
|
if ( ! _Rd_ ) return;
|
||||||
|
|
||||||
if( GPR_IS_CONST1(_Rt_) ) {
|
if( GPR_IS_CONST1(_Rt_) ) {
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
|
||||||
_deleteGPRtoXMMreg(_Rd_, 2);
|
_deleteGPRtoXMMreg(_Rd_, 2);
|
||||||
GPR_SET_CONST(_Rd_);
|
GPR_SET_CONST(_Rd_);
|
||||||
constcode();
|
constcode();
|
||||||
|
@ -353,7 +336,6 @@ void eeRecompileCode2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
||||||
if( (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rt_) ) {
|
if( (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rt_) ) {
|
||||||
_freeXMMreg(mmreg1);
|
_freeXMMreg(mmreg1);
|
||||||
info &= ~PROCESS_EE_MODEWRITET;
|
info &= ~PROCESS_EE_MODEWRITET;
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
|
||||||
xmmregs[mmreg1].inuse = 1;
|
xmmregs[mmreg1].inuse = 1;
|
||||||
xmmregs[mmreg1].reg = _Rd_;
|
xmmregs[mmreg1].reg = _Rd_;
|
||||||
xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ;
|
xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ;
|
||||||
|
@ -374,8 +356,6 @@ void eeRecompileCode2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
||||||
// regular x86
|
// regular x86
|
||||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||||
_deleteGPRtoXMMreg(_Rd_, 2);
|
_deleteGPRtoXMMreg(_Rd_, 2);
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
|
||||||
|
|
||||||
noconstcode(0);
|
noconstcode(0);
|
||||||
GPR_DEL_CONST(_Rd_);
|
GPR_DEL_CONST(_Rd_);
|
||||||
|
@ -420,9 +400,6 @@ void eeRecompileCodeConst0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R59
|
||||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||||
_deleteGPRtoXMMreg(_Rd_, 0);
|
_deleteGPRtoXMMreg(_Rd_, 0);
|
||||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 0);
|
|
||||||
|
|
||||||
if( GPR_IS_CONST2(_Rs_, _Rt_) ) {
|
if( GPR_IS_CONST2(_Rs_, _Rt_) ) {
|
||||||
GPR_SET_CONST(_Rd_);
|
GPR_SET_CONST(_Rd_);
|
||||||
|
@ -576,7 +553,6 @@ int eeRecompileCodeXMM(int xmminfo)
|
||||||
if( regd < 0 ) {
|
if( regd < 0 ) {
|
||||||
if( !(xmminfo&XMMINFO_READD) && (xmminfo & XMMINFO_READT) && (_Rt_ == 0 || (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rt_)) ) {
|
if( !(xmminfo&XMMINFO_READD) && (xmminfo & XMMINFO_READT) && (_Rt_ == 0 || (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rt_)) ) {
|
||||||
_freeXMMreg(EEREC_T);
|
_freeXMMreg(EEREC_T);
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
|
||||||
xmmregs[EEREC_T].inuse = 1;
|
xmmregs[EEREC_T].inuse = 1;
|
||||||
xmmregs[EEREC_T].reg = _Rd_;
|
xmmregs[EEREC_T].reg = _Rd_;
|
||||||
xmmregs[EEREC_T].mode = readd;
|
xmmregs[EEREC_T].mode = readd;
|
||||||
|
@ -584,7 +560,6 @@ int eeRecompileCodeXMM(int xmminfo)
|
||||||
}
|
}
|
||||||
else if( !(xmminfo&XMMINFO_READD) && (xmminfo & XMMINFO_READS) && (_Rs_ == 0 || (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_)) ) {
|
else if( !(xmminfo&XMMINFO_READD) && (xmminfo & XMMINFO_READS) && (_Rs_ == 0 || (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_)) ) {
|
||||||
_freeXMMreg(EEREC_S);
|
_freeXMMreg(EEREC_S);
|
||||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
|
||||||
xmmregs[EEREC_S].inuse = 1;
|
xmmregs[EEREC_S].inuse = 1;
|
||||||
xmmregs[EEREC_S].reg = _Rd_;
|
xmmregs[EEREC_S].reg = _Rd_;
|
||||||
xmmregs[EEREC_S].mode = readd;
|
xmmregs[EEREC_S].mode = readd;
|
||||||
|
@ -664,7 +639,6 @@ void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo
|
||||||
_freeXMMreg(mmregt);
|
_freeXMMreg(mmregt);
|
||||||
info &= ~PROCESS_EE_MODEWRITET;
|
info &= ~PROCESS_EE_MODEWRITET;
|
||||||
}
|
}
|
||||||
_deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2);
|
|
||||||
xmmregs[mmregt].inuse = 1;
|
xmmregs[mmregt].inuse = 1;
|
||||||
xmmregs[mmregt].reg = 0;
|
xmmregs[mmregt].reg = 0;
|
||||||
xmmregs[mmregt].mode = readacc;
|
xmmregs[mmregt].mode = readacc;
|
||||||
|
@ -676,7 +650,6 @@ void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo
|
||||||
_freeXMMreg(mmregs);
|
_freeXMMreg(mmregs);
|
||||||
info &= ~PROCESS_EE_MODEWRITES;
|
info &= ~PROCESS_EE_MODEWRITES;
|
||||||
}
|
}
|
||||||
_deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2);
|
|
||||||
xmmregs[mmregs].inuse = 1;
|
xmmregs[mmregs].inuse = 1;
|
||||||
xmmregs[mmregs].reg = 0;
|
xmmregs[mmregs].reg = 0;
|
||||||
xmmregs[mmregs].mode = readacc;
|
xmmregs[mmregs].mode = readacc;
|
||||||
|
@ -700,7 +673,6 @@ void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo
|
||||||
_freeXMMreg(mmregt);
|
_freeXMMreg(mmregt);
|
||||||
info &= ~PROCESS_EE_MODEWRITET;
|
info &= ~PROCESS_EE_MODEWRITET;
|
||||||
}
|
}
|
||||||
_deleteMMXreg(MMX_FPU+_Fd_, 2);
|
|
||||||
xmmregs[mmregt].inuse = 1;
|
xmmregs[mmregt].inuse = 1;
|
||||||
xmmregs[mmregt].reg = _Fd_;
|
xmmregs[mmregt].reg = _Fd_;
|
||||||
xmmregs[mmregt].mode = readd;
|
xmmregs[mmregt].mode = readd;
|
||||||
|
@ -711,7 +683,6 @@ void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo
|
||||||
_freeXMMreg(mmregs);
|
_freeXMMreg(mmregs);
|
||||||
info &= ~PROCESS_EE_MODEWRITES;
|
info &= ~PROCESS_EE_MODEWRITES;
|
||||||
}
|
}
|
||||||
_deleteMMXreg(MMX_FPU+_Fd_, 2);
|
|
||||||
xmmregs[mmregs].inuse = 1;
|
xmmregs[mmregs].inuse = 1;
|
||||||
xmmregs[mmregs].reg = _Fd_;
|
xmmregs[mmregs].reg = _Fd_;
|
||||||
xmmregs[mmregs].mode = readd;
|
xmmregs[mmregs].mode = readd;
|
||||||
|
@ -720,7 +691,6 @@ void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo
|
||||||
else if( (xmminfo&XMMINFO_READACC) && mmregacc >= 0 && (FPUINST_LASTUSE(XMMFPU_ACC) || !FPUINST_ISLIVE(XMMFPU_ACC)) ) {
|
else if( (xmminfo&XMMINFO_READACC) && mmregacc >= 0 && (FPUINST_LASTUSE(XMMFPU_ACC) || !FPUINST_ISLIVE(XMMFPU_ACC)) ) {
|
||||||
if( FPUINST_ISLIVE(XMMFPU_ACC) )
|
if( FPUINST_ISLIVE(XMMFPU_ACC) )
|
||||||
_freeXMMreg(mmregacc);
|
_freeXMMreg(mmregacc);
|
||||||
_deleteMMXreg(MMX_FPU+_Fd_, 2);
|
|
||||||
xmmregs[mmregacc].inuse = 1;
|
xmmregs[mmregacc].inuse = 1;
|
||||||
xmmregs[mmregacc].reg = _Fd_;
|
xmmregs[mmregacc].reg = _Fd_;
|
||||||
xmmregs[mmregacc].mode = readd;
|
xmmregs[mmregacc].mode = readd;
|
||||||
|
|
|
@ -68,15 +68,11 @@ static void iMOV128_SSE( const xIndirectVoid& destRm, const xIndirectVoid& srcRm
|
||||||
xMOVDQA( destRm, reg );
|
xMOVDQA( destRm, reg );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves 64 bits of data from point B to point A, using either MMX, SSE, or x86 registers
|
// Moves 64 bits of data from point B to point A, using either SSE, or x86 registers
|
||||||
// if neither MMX nor SSE is available to the task.
|
|
||||||
//
|
|
||||||
// Optimizations: This method uses MMX is the cpu is in MMX mode, or SSE if it's in FPU
|
|
||||||
// mode (saving on potential xEMMS uses).
|
|
||||||
//
|
//
|
||||||
static void iMOV64_Smart( const xIndirectVoid& destRm, const xIndirectVoid& srcRm )
|
static void iMOV64_Smart( const xIndirectVoid& destRm, const xIndirectVoid& srcRm )
|
||||||
{
|
{
|
||||||
if( (x86FpuState == FPU_STATE) && _hasFreeXMMreg() )
|
if( _hasFreeXMMreg() )
|
||||||
{
|
{
|
||||||
// Move things using MOVLPS:
|
// Move things using MOVLPS:
|
||||||
xRegisterSSE reg( _allocTempXMMreg( XMMT_INT, -1 ) );
|
xRegisterSSE reg( _allocTempXMMreg( XMMT_INT, -1 ) );
|
||||||
|
@ -86,21 +82,11 @@ static void iMOV64_Smart( const xIndirectVoid& destRm, const xIndirectVoid& srcR
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _hasFreeMMXreg() )
|
|
||||||
{
|
|
||||||
xRegisterMMX reg( _allocMMXreg(-1, MMX_TEMP, 0) );
|
|
||||||
xMOVQ( reg, srcRm );
|
|
||||||
xMOVQ( destRm, reg );
|
|
||||||
_freeMMXreg( reg.Id );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xMOV( eax, srcRm );
|
xMOV( eax, srcRm );
|
||||||
xMOV( destRm, eax );
|
xMOV( destRm, eax );
|
||||||
xMOV( eax, srcRm+4 );
|
xMOV( eax, srcRm+4 );
|
||||||
xMOV( destRm+4, eax );
|
xMOV( destRm+4, eax );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Pseudo-Code For the following Dynarec Implementations -->
|
// Pseudo-Code For the following Dynarec Implementations -->
|
||||||
|
|
|
@ -17,16 +17,12 @@
|
||||||
|
|
||||||
#define REC_VUOP(VU, f) { \
|
#define REC_VUOP(VU, f) { \
|
||||||
_freeXMMregs(/*&VU*/); \
|
_freeXMMregs(/*&VU*/); \
|
||||||
_freeMMXregs(); \
|
|
||||||
SetFPUstate();) \
|
|
||||||
xMOV(ptr32[&VU.code], (u32)VU.code); \
|
xMOV(ptr32[&VU.code], (u32)VU.code); \
|
||||||
xCALL((void*)(uptr)VU##MI_##f); \
|
xCALL((void*)(uptr)VU##MI_##f); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REC_VUOPs(VU, f) { \
|
#define REC_VUOPs(VU, f) { \
|
||||||
_freeXMMregs(); \
|
_freeXMMregs(); \
|
||||||
_freeMMXregs(); \
|
|
||||||
SetFPUstate();) \
|
|
||||||
if (VU==&VU1) { \
|
if (VU==&VU1) { \
|
||||||
xMOV(ptr32[&VU1.code], (u32)VU1.code); \
|
xMOV(ptr32[&VU1.code], (u32)VU1.code); \
|
||||||
xCALL((void*)(uptr)VU1MI_##f); \
|
xCALL((void*)(uptr)VU1MI_##f); \
|
||||||
|
@ -39,16 +35,12 @@
|
||||||
|
|
||||||
#define REC_VUOPFLAGS(VU, f) { \
|
#define REC_VUOPFLAGS(VU, f) { \
|
||||||
_freeXMMregs(/*&VU*/); \
|
_freeXMMregs(/*&VU*/); \
|
||||||
_freeMMXregs(); \
|
|
||||||
SetFPUstate(); \
|
|
||||||
xMOV(ptr32[&VU.code], (u32)VU.code); \
|
xMOV(ptr32[&VU.code], (u32)VU.code); \
|
||||||
xCALL((void*)(uptr)VU##MI_##f); \
|
xCALL((void*)(uptr)VU##MI_##f); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REC_VUBRANCH(VU, f) { \
|
#define REC_VUBRANCH(VU, f) { \
|
||||||
_freeXMMregs(/*&VU*/); \
|
_freeXMMregs(/*&VU*/); \
|
||||||
_freeMMXregs(); \
|
|
||||||
SetFPUstate(); \
|
|
||||||
xMOV(ptr32[&VU.code], (u32)VU.code); \
|
xMOV(ptr32[&VU.code], (u32)VU.code); \
|
||||||
xMOV(ptr32[&VU.VI[REG_TPC].UL], (u32)pc); \
|
xMOV(ptr32[&VU.VI[REG_TPC].UL], (u32)pc); \
|
||||||
xCALL((void*)(uptr)VU##MI_##f); \
|
xCALL((void*)(uptr)VU##MI_##f); \
|
||||||
|
|
|
@ -2545,7 +2545,6 @@ void SuperVUCleanupProgram(u32 startpc, int vuindex)
|
||||||
// Could clear allocation info to prevent possibly bad data being used in other parts of pcsx2;
|
// Could clear allocation info to prevent possibly bad data being used in other parts of pcsx2;
|
||||||
// not doing this because it's slow and not needed (rama)
|
// not doing this because it's slow and not needed (rama)
|
||||||
// _initXMMregs();
|
// _initXMMregs();
|
||||||
// _initMMXregs();
|
|
||||||
// _initX86regs();
|
// _initX86regs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue