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 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 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
|
||||
// values in dest.
|
||||
// Operation can be performed on either MMX or SSE operands.
|
||||
const xImplSimd_DestRegEither UB;
|
||||
|
||||
// Compare packed signed word integers in dest to src and store packed min/max
|
||||
// values in dest.
|
||||
// Operation can be performed on either MMX or SSE operands.
|
||||
const xImplSimd_DestRegEither SW;
|
||||
|
||||
// [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;
|
||||
};
|
||||
|
||||
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).
|
||||
//
|
||||
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 xIndirectVoid& from ) const;
|
||||
|
||||
void operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const;
|
||||
void operator()( const xRegisterMMX& to, const xIndirectVoid& from ) const;
|
||||
};
|
||||
|
||||
} // end namespace x86Emitter
|
||||
|
|
|
@ -36,10 +36,6 @@ struct xImplSimd_Shuffle
|
|||
// --------------------------------------------------------------------------------------
|
||||
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
|
||||
// with the order operand (8 bit immediate).
|
||||
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
|
||||
// operation) or 3 bits (64-bit operation) of the shuffle control byte.
|
||||
//
|
||||
// Operands can be MMX or XMM registers.
|
||||
const xImplSimd_DestRegEither B;
|
||||
|
||||
// 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
|
||||
// Copies words from src and inserts them into dest at word locations selected with
|
||||
// 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
|
||||
// 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
|
||||
// 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 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
|
||||
};
|
||||
|
||||
|
@ -214,9 +204,6 @@ struct xImplSimd_PInsert
|
|||
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 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)
|
||||
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!
|
||||
//
|
||||
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;
|
||||
|
||||
// [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 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 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 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 xRegisterSSE& from );
|
||||
|
@ -372,17 +360,13 @@ namespace x86Emitter
|
|||
|
||||
extern void xMOVNTPD( 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 xMOVMSKPD( const xRegister32or64& 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 xRegisterMMX& from );
|
||||
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 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 xIndirect128& from );
|
||||
|
||||
extern void xCVTPI2PD( const xRegisterSSE& to, const xRegisterMMX& 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 xCVTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& 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 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 xIndirect64& from );
|
||||
extern void xCVTSD2SS( const xRegisterSSE& to, const xRegisterSSE& 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 xIndirect32& from );
|
||||
|
||||
|
@ -488,12 +464,8 @@ namespace x86Emitter
|
|||
|
||||
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& 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 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 xIndirect64& from );
|
||||
|
|
|
@ -21,5 +21,4 @@
|
|||
|
||||
// general types
|
||||
typedef int x86IntRegType;
|
||||
typedef int x86MMXRegType;
|
||||
typedef int x86SSERegType;
|
||||
|
|
|
@ -73,7 +73,6 @@ public:
|
|||
u32 hasCFLUSHInstruction :1;
|
||||
u32 hasDebugStore :1;
|
||||
u32 hasACPIThermalMonitorAndClockControl :1;
|
||||
u32 hasMultimediaExtensions :1;
|
||||
u32 hasFastStreamingSIMDExtensionsSaveRestore :1;
|
||||
u32 hasStreamingSIMDExtensions :1;
|
||||
u32 hasStreamingSIMD2Extensions :1;
|
||||
|
@ -95,10 +94,7 @@ public:
|
|||
u32 hasFMA :1;
|
||||
|
||||
// AMD-specific CPU Features
|
||||
u32 hasMultimediaExtensionsExt :1;
|
||||
u32 hasAMD64BitArchitecture :1;
|
||||
u32 has3DNOWInstructionExtensionsExt :1;
|
||||
u32 has3DNOWInstructionExtensions :1;
|
||||
u32 hasStreamingSIMD4ExtensionsA :1;
|
||||
|
||||
// Core Counts!
|
||||
|
|
|
@ -18,12 +18,10 @@
|
|||
#ifdef __x86_64__
|
||||
static const uint iREGCNT_XMM = 16;
|
||||
static const uint iREGCNT_GPR = 16;
|
||||
static const uint iREGCNT_MMX = 8; // FIXME: port the code and remove MMX
|
||||
#else
|
||||
// Register counts for x86/32 mode:
|
||||
static const uint iREGCNT_XMM = 8;
|
||||
static const uint iREGCNT_GPR = 8;
|
||||
static const uint iREGCNT_MMX = 8;
|
||||
#endif
|
||||
|
||||
enum XMMSSEType
|
||||
|
@ -233,7 +231,7 @@ template< typename T > void xWrite( T val );
|
|||
// --------------------------------------------------------------------------------------
|
||||
// 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
|
||||
// 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.
|
||||
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)
|
||||
#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; }
|
||||
#else
|
||||
bool IsSIMD() const { return GetOperandSize() == 8 || GetOperandSize() == 16; }
|
||||
bool IsWide() const { return false; } // no 64 bits GPR
|
||||
#endif
|
||||
// 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
|
||||
// an XMM or MMX 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; }
|
||||
};
|
||||
// This register type is provided to allow legal syntax for instructions that accept
|
||||
// an XMM register as a parameter, but do not allow for a GPR.
|
||||
|
||||
class xRegisterSSE : public xRegisterBase
|
||||
{
|
||||
|
@ -473,12 +451,6 @@ template< typename T > void xWrite( T val );
|
|||
return xRegister16( xRegId_Empty );
|
||||
}
|
||||
|
||||
// FIXME remove it in x86 64
|
||||
operator xRegisterMMX() const
|
||||
{
|
||||
return xRegisterMMX( xRegId_Empty );
|
||||
}
|
||||
|
||||
operator xRegisterSSE() const
|
||||
{
|
||||
return xRegisterSSE( xRegId_Empty );
|
||||
|
@ -551,10 +523,6 @@ template< typename T > void xWrite( T val );
|
|||
xmm8, xmm9, xmm10, xmm11,
|
||||
xmm12, xmm13, xmm14, xmm15;
|
||||
|
||||
extern const xRegisterMMX
|
||||
mm0, mm1, mm2, mm3,
|
||||
mm4, mm5, mm6, mm7;
|
||||
|
||||
extern const xAddressReg
|
||||
rax, rbx, rcx, rdx,
|
||||
rsi, rdi, rbp, rsp,
|
||||
|
@ -943,7 +911,6 @@ template< typename T > void xWrite( T val );
|
|||
typedef xDirectOrIndirect<xRegister8,xIndirect8> xDirectOrIndirect8;
|
||||
typedef xDirectOrIndirect<xRegister16,xIndirect16> xDirectOrIndirect16;
|
||||
typedef xDirectOrIndirect<xRegister32,xIndirect32> xDirectOrIndirect32;
|
||||
typedef xDirectOrIndirect<xRegisterMMX,xIndirect64> xDirectOrIndirect64;
|
||||
typedef xDirectOrIndirect<xRegisterSSE,xIndirect128> xDirectOrIndirect128;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -250,7 +250,6 @@ void x86capabilities::Identify()
|
|||
hasCFLUSHInstruction = ( Flags >> 19 ) & 1;
|
||||
hasDebugStore = ( Flags >> 21 ) & 1;
|
||||
hasACPIThermalMonitorAndClockControl = ( Flags >> 22 ) & 1;
|
||||
hasMultimediaExtensions = ( Flags >> 23 ) & 1; //mmx
|
||||
hasFastStreamingSIMDExtensionsSaveRestore = ( Flags >> 24 ) & 1;
|
||||
hasStreamingSIMDExtensions = ( Flags >> 25 ) & 1; //sse
|
||||
hasStreamingSIMD2Extensions = ( Flags >> 26 ) & 1; //sse2
|
||||
|
@ -282,10 +281,7 @@ void x86capabilities::Identify()
|
|||
hasBMI2 = ( SEFlag >> 8 ) & 1;
|
||||
|
||||
// Ones only for AMDs:
|
||||
hasMultimediaExtensionsExt = ( EFlags >> 22 ) & 1; //mmx2
|
||||
hasAMD64BitArchitecture = ( EFlags >> 29 ) & 1; //64bit cpu
|
||||
has3DNOWInstructionExtensionsExt = ( EFlags >> 30 ) & 1; //3dnow+
|
||||
has3DNOWInstructionExtensions = ( EFlags >> 31 ) & 1; //3dnow
|
||||
hasStreamingSIMD4ExtensionsA = ( EFlags2 >> 6 ) & 1; //INSERTQ / EXTRQ / MOVNT
|
||||
|
||||
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 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 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 xCVTPI2PS( const xRegisterSSE& to, const xRegisterMMX& 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 xIndirect128& from ) { OpWriteSSE( 0x66, 0x5b ); }
|
||||
__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 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 xIndirect64& from ) { OpWriteSSE( 0xf2, 0x2d ); }
|
||||
__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 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 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 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 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 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 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 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 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 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
|
||||
{
|
||||
|
@ -227,12 +209,6 @@ void _SimdShiftHelper::operator()( const xRegisterSSE& to, u8 imm8 ) const
|
|||
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
|
||||
{
|
||||
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 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 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 ); }
|
||||
|
||||
const xImplSimd_Shuffle xSHUF = { };
|
||||
|
||||
const xImplSimd_PShuffle xPSHUF =
|
||||
{
|
||||
{ 0x00, 0x70 }, // W
|
||||
{ 0x66, 0x70 }, // D
|
||||
{ 0xf2, 0x70 }, // LW
|
||||
{ 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 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 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
|
||||
// being cleared to zero.
|
||||
__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)
|
||||
__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 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 ); }
|
||||
|
@ -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
|
||||
// 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 xRegisterMMX& to, const xRegisterMMX& from ) { xOpWrite0F( 0xf7, to, from ); }
|
||||
|
||||
// xPMOVMSKB:
|
||||
// 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.
|
||||
//
|
||||
__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,
|
||||
// shifts the composite at byte granularity to the right by a constant immediate,
|
||||
// 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 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!
|
||||
// =====================================================================================================
|
||||
|
||||
// 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.
|
||||
__emitinline void xSTMXCSR( const xIndirect32& dest )
|
||||
|
|
|
@ -116,12 +116,6 @@ const xRegisterSSE
|
|||
xmm12( 12 ), xmm13( 13 ),
|
||||
xmm14( 14 ), xmm15( 15 );
|
||||
|
||||
const xRegisterMMX
|
||||
mm0( 0 ), mm1( 1 ),
|
||||
mm2( 2 ), mm3( 3 ),
|
||||
mm4( 4 ), mm5( 5 ),
|
||||
mm6( 6 ), mm7( 7 );
|
||||
|
||||
const xAddressReg
|
||||
rax( 0 ), rbx( 3 ),
|
||||
rcx( 1 ), rdx( 2 ),
|
||||
|
@ -192,12 +186,6 @@ const char *const x86_regnames_sse[] =
|
|||
"xmm12", "xmm13", "xmm14", "xmm15"
|
||||
};
|
||||
|
||||
const char *const x86_regnames_mmx[] =
|
||||
{
|
||||
"mm0", "mm1", "mm2", "mm3",
|
||||
"mm4", "mm5", "mm6", "mm7"
|
||||
};
|
||||
|
||||
const char* xRegisterBase::GetName()
|
||||
{
|
||||
if( Id == xRegId_Invalid ) return "invalid";
|
||||
|
@ -214,8 +202,6 @@ const char* xRegisterBase::GetName()
|
|||
case 4: return x86_regnames_gpr32[ Id ];
|
||||
#ifdef __x86_64__
|
||||
case 8: return x86_regnames_gpr64[ Id ];
|
||||
#else
|
||||
case 8: return x86_regnames_mmx[ Id ];
|
||||
#endif
|
||||
case 16: return x86_regnames_sse[ Id ];
|
||||
}
|
||||
|
|
|
@ -274,9 +274,6 @@ void SysLogMachineCaps()
|
|||
if( x86caps.hasAVX2 ) features[0].Add( L"AVX2" );
|
||||
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 " );
|
||||
|
||||
const wxString result[2] =
|
||||
|
|
|
@ -33,7 +33,7 @@ u16 g_xmmAllocCounter = 0;
|
|||
EEINST* g_pCurInstInfo = NULL;
|
||||
|
||||
// used to make sure regs don't get changed while in recompiler
|
||||
// use FreezeMMXRegs, FreezeXMMRegs
|
||||
// use FreezeXMMRegs
|
||||
u32 g_recWriteback = 0;
|
||||
|
||||
_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].reg != gprreg) continue;
|
||||
|
||||
pxAssert( _checkMMXreg(MMX_GPR|gprreg, mode) == -1 );
|
||||
|
||||
g_xmmtypes[i] = XMMT_INT;
|
||||
|
||||
if (!(xmmregs[i].mode & MODE_READ) && (mode & MODE_READ))
|
||||
|
@ -432,40 +430,11 @@ int _allocGPRtoXMMreg(int xmmreg, int gprreg, int mode)
|
|||
else
|
||||
{
|
||||
// DOX86
|
||||
int mmxreg;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -1169,7 +1138,3 @@ void _recFillRegister(EEINST& pinst, int type, int reg, int write)
|
|||
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
|
||||
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
|
||||
|
||||
|
@ -357,8 +286,6 @@ extern u16 x86FpuState;
|
|||
#define FLUSH_CACHED_REGS 0x001
|
||||
#define FLUSH_FLUSH_XMM 0x002
|
||||
#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_FREE_TEMPX86 0x040 // flush and free temporary x86 regs
|
||||
#define FLUSH_FREE_ALLX86 0x080 // free all x86 regs
|
||||
|
@ -372,9 +299,9 @@ extern u16 x86FpuState;
|
|||
#define FLUSH_INTERPRETER 0xfff
|
||||
#define FLUSH_FULLVTLB FLUSH_NOCONST
|
||||
|
||||
// no freeing, used when callee won't destroy mmx/xmm regs
|
||||
#define FLUSH_NODESTROY (FLUSH_CACHED_REGS|FLUSH_FLUSH_XMM|FLUSH_FLUSH_MMX|FLUSH_FLUSH_ALLX86)
|
||||
// no freeing, used when callee won't destroy xmm regs
|
||||
#define FLUSH_NODESTROY (FLUSH_CACHED_REGS|FLUSH_FLUSH_XMM|FLUSH_FLUSH_ALLX86)
|
||||
// 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
|
||||
|
|
|
@ -156,21 +156,10 @@ void recCTC1()
|
|||
|
||||
else
|
||||
{
|
||||
mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_READ);
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
|
||||
if ( mmreg >= 0 )
|
||||
{
|
||||
xMOVD(ptr[&fpuRegs.fprc[ _Fs_ ]], xRegisterMMX(mmreg));
|
||||
SetMMXstate();
|
||||
}
|
||||
else
|
||||
{
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ]);
|
||||
xMOV(ptr[&fpuRegs.fprc[ _Fs_ ]], eax);
|
||||
}
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ]);
|
||||
xMOV(ptr[&fpuRegs.fprc[ _Fs_ ]], eax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,49 +183,27 @@ void recMFC1()
|
|||
if( regs >= 0 )
|
||||
{
|
||||
_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);
|
||||
regt = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ);
|
||||
|
||||
if( regs >= 0 )
|
||||
if( regt >= 0 )
|
||||
{
|
||||
// convert to mmx reg
|
||||
mmxregs[regs].reg = MMX_GPR+_Rt_;
|
||||
mmxregs[regs].mode |= MODE_READ|MODE_WRITE;
|
||||
_signExtendGPRtoMMX(regs, _Rt_, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
regt = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ);
|
||||
|
||||
if( regt >= 0 )
|
||||
if( xmmregs[regt].mode & MODE_WRITE )
|
||||
{
|
||||
if( xmmregs[regt].mode & MODE_WRITE )
|
||||
{
|
||||
xMOVH.PS(ptr[&cpuRegs.GPR.r[_Rt_].UL[2]], xRegisterSSE(regt));
|
||||
}
|
||||
xmmregs[regt].inuse = 0;
|
||||
xMOVH.PS(ptr[&cpuRegs.GPR.r[_Rt_].UL[2]], xRegisterSSE(regt));
|
||||
}
|
||||
|
||||
_deleteEEreg(_Rt_, 0);
|
||||
xMOV(eax, ptr[&fpuRegs.fpr[ _Fs_ ].UL ]);
|
||||
|
||||
xCDQ( );
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ]], edx);
|
||||
xmmregs[regt].inuse = 0;
|
||||
}
|
||||
|
||||
_deleteEEreg(_Rt_, 0);
|
||||
xMOV(eax, ptr[&fpuRegs.fpr[ _Fs_ ].UL ]);
|
||||
|
||||
xCDQ( );
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ]], edx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,35 +246,16 @@ void recMTC1()
|
|||
}
|
||||
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 )
|
||||
{
|
||||
if( mmreg2 >= 0 )
|
||||
{
|
||||
SetMMXstate();
|
||||
xMOVQ(xRegisterSSE(mmreg2), xRegisterMMX(mmreg));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMMXstate();
|
||||
xMOVD(ptr[&fpuRegs.fpr[ _Fs_ ].UL], xRegisterMMX(mmreg));
|
||||
}
|
||||
xMOVSSZX(xRegisterSSE(mmreg2), ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( mmreg2 >= 0 )
|
||||
{
|
||||
xMOVSSZX(xRegisterSSE(mmreg2), ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]]);
|
||||
xMOV(ptr[&fpuRegs.fpr[ _Fs_ ].UL], eax);
|
||||
}
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]]);
|
||||
xMOV(ptr[&fpuRegs.fpr[ _Fs_ ].UL], eax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ REC_FUNC_DEL( PSLLW, _Rd_ );
|
|||
|
||||
void recPLZCW()
|
||||
{
|
||||
bool isXMMreg = false;
|
||||
int regs = -1;
|
||||
|
||||
if ( ! _Rd_ ) return;
|
||||
|
@ -80,11 +79,6 @@ void recPLZCW()
|
|||
|
||||
if( (regs = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
|
||||
xMOVD(eax, xRegisterSSE(regs));
|
||||
isXMMreg = true;
|
||||
}
|
||||
else if( (regs = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) {
|
||||
xMOVD(eax, xRegisterMMX(regs));
|
||||
SetMMXstate();
|
||||
}
|
||||
else {
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||
|
@ -119,17 +113,9 @@ void recPLZCW()
|
|||
// second word
|
||||
|
||||
if( regs >= 0) {
|
||||
// Check if it was an XMM reg or MMX reg
|
||||
if (isXMMreg) {
|
||||
xPSHUF.D(xRegisterSSE(regs&0xf), xRegisterSSE(regs&0xf), 0xe1);
|
||||
xMOVD(eax, xRegisterSSE(regs&0xf));
|
||||
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();
|
||||
}
|
||||
xPSHUF.D(xRegisterSSE(regs&0xf), xRegisterSSE(regs&0xf), 0xe1);
|
||||
xMOVD(eax, xRegisterSSE(regs&0xf));
|
||||
xPSHUF.D(xRegisterSSE(regs&0xf), xRegisterSSE(regs&0xf), 0xe1);
|
||||
}
|
||||
else {
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||
|
@ -244,47 +230,6 @@ void recPMTHL()
|
|||
_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()
|
||||
{
|
||||
|
|
|
@ -98,10 +98,6 @@ void recMFSA()
|
|||
if( mmreg >= 0 ) {
|
||||
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 {
|
||||
xMOV(eax, ptr[&cpuRegs.sa]);
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
|
@ -122,10 +118,6 @@ void recMTSA()
|
|||
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
|
||||
xMOVSS(ptr[&cpuRegs.sa], xRegisterSSE(mmreg));
|
||||
}
|
||||
else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) {
|
||||
xMOVD(ptr[&cpuRegs.sa], xRegisterMMX(mmreg));
|
||||
SetMMXstate();
|
||||
}
|
||||
else {
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[_Rs_].UL[0]]);
|
||||
xMOV(ptr[&cpuRegs.sa], eax);
|
||||
|
|
|
@ -112,7 +112,7 @@ namespace VU1micro
|
|||
void recAlloc() { SuperVUAlloc(1); initVUrec(&VU1, 1); }
|
||||
void __fastcall recClear(u32 Addr, u32 Size) { SuperVUClear(Addr, Size, 1); clearVUrec(Addr, Size, 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 recExecuteBlock(void)
|
||||
|
@ -257,7 +257,6 @@ namespace VU1micro
|
|||
static void recReset() {
|
||||
if (useMVU1) resetVUrec(1);
|
||||
else SuperVUReset(1);
|
||||
x86FpuState = FPU_STATE;
|
||||
}
|
||||
|
||||
static void recStep() {}
|
||||
|
@ -284,4 +283,4 @@ namespace VU1micro
|
|||
}*/
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -28,9 +28,6 @@ using namespace x86Emitter;
|
|||
// landmass of shared code. (air)
|
||||
extern u32 g_psxConstRegs[32];
|
||||
|
||||
u16 x86FpuState;
|
||||
static u16 g_mmxAllocCounter = 0;
|
||||
|
||||
// X86 caching
|
||||
static int g_x86checknext;
|
||||
|
||||
|
@ -162,7 +159,6 @@ int _getFreeX86reg(int mode)
|
|||
void _flushCachedRegs()
|
||||
{
|
||||
_flushConstRegs();
|
||||
_flushMMXregs();
|
||||
_flushXMMregs();
|
||||
}
|
||||
|
||||
|
@ -337,12 +333,10 @@ int _allocX86reg(xRegisterLong x86reg, int type, int reg, int mode)
|
|||
}
|
||||
else {
|
||||
_flushConstReg(reg);
|
||||
_deleteMMXreg(MMX_GPR+reg, 1);
|
||||
_deleteGPRtoXMMreg(reg, 1);
|
||||
|
||||
_eeMoveGPRtoR(x86reg, reg);
|
||||
|
||||
_deleteMMXreg(MMX_GPR+reg, 0);
|
||||
_deleteGPRtoXMMreg(reg, 0);
|
||||
}
|
||||
}
|
||||
|
@ -473,404 +467,7 @@ void _freeX86regs()
|
|||
_freeX86reg(i);
|
||||
}
|
||||
|
||||
// MMX Caching
|
||||
_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;
|
||||
}
|
||||
}
|
||||
// Misc
|
||||
|
||||
void _signExtendSFtoM(uptr mem)
|
||||
{
|
||||
|
@ -879,60 +476,3 @@ void _signExtendSFtoM(uptr mem)
|
|||
xCWDE();
|
||||
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
|
||||
GPR_reg64 s_saveConstRegs[32];
|
||||
static u16 s_savex86FpuState;
|
||||
static u32 s_saveHasConstReg = 0, s_saveFlushedConstReg = 0;
|
||||
static EEINST* s_psaveInstInfo = NULL;
|
||||
|
||||
|
@ -127,7 +126,6 @@ void _eeFlushAllUnused()
|
|||
|
||||
if( i < 32 && GPR_IS_CONST1(i) ) _flushConstReg(i);
|
||||
else {
|
||||
_deleteMMXreg(MMX_GPR+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)) {
|
||||
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 {
|
||||
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 ) {
|
||||
xMOVSS(ptr[(void*)(to)], xRegisterSSE(mmreg));
|
||||
}
|
||||
else if( (mmreg = _checkMMXreg(MMX_GPR+fromgpr, MODE_READ)) >= 0 ) {
|
||||
xMOVD(ptr[(void*)(to)], xRegisterMMX(mmreg));
|
||||
SetMMXstate();
|
||||
}
|
||||
else {
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ fromgpr ].UL[ 0 ] ]);
|
||||
xMOV(ptr[(void*)(to)], eax);
|
||||
|
@ -207,10 +197,6 @@ void _eeMoveGPRtoRm(x86IntRegType to, int fromgpr)
|
|||
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, fromgpr, MODE_READ)) >= 0 ) {
|
||||
xMOVSS(ptr[xAddressReg(to)], xRegisterSSE(mmreg));
|
||||
}
|
||||
else if( (mmreg = _checkMMXreg(MMX_GPR+fromgpr, MODE_READ)) >= 0 ) {
|
||||
xMOVD(ptr[xAddressReg(to)], xRegisterMMX(mmreg));
|
||||
SetMMXstate();
|
||||
}
|
||||
else {
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ fromgpr ].UL[ 0 ] ]);
|
||||
xMOV(ptr[xAddressReg(to)], eax);
|
||||
|
@ -245,25 +231,6 @@ int _flushXMMunused()
|
|||
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 i;
|
||||
|
@ -444,7 +411,6 @@ static DynGenFunc* _DynGen_EnterRecompiledCode()
|
|||
static DynGenFunc* _DynGen_DispatchBlockDiscard()
|
||||
{
|
||||
u8* retval = xGetPtr();
|
||||
xEMMS();
|
||||
xFastCall(dyna_block_discard);
|
||||
xJMP(ExitRecompiledCode);
|
||||
return (DynGenFunc*)retval;
|
||||
|
@ -453,7 +419,6 @@ static DynGenFunc* _DynGen_DispatchBlockDiscard()
|
|||
static DynGenFunc* _DynGen_DispatchPageReset()
|
||||
{
|
||||
u8* retval = xGetPtr();
|
||||
xEMMS();
|
||||
xFastCall(dyna_page_reset);
|
||||
xJMP(ExitRecompiledCode);
|
||||
return (DynGenFunc*)retval;
|
||||
|
@ -596,8 +561,6 @@ static void recAlloc()
|
|||
// No errors.. Proceed with initialization:
|
||||
|
||||
_DynGen_Dispatchers();
|
||||
|
||||
x86FpuState = FPU_STATE;
|
||||
}
|
||||
|
||||
static __aligned16 u16 manual_page[Ps2MemSize::MainRam >> 12];
|
||||
|
@ -639,7 +602,6 @@ static void recResetRaw()
|
|||
|
||||
recPtr = *recMem;
|
||||
recConstBufPtr = recConstBuf;
|
||||
x86FpuState = FPU_STATE;
|
||||
|
||||
g_branch = 0;
|
||||
}
|
||||
|
@ -882,10 +844,6 @@ void SetBranchReg( u32 reg )
|
|||
// if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, reg, MODE_READ)) >= 0 ) {
|
||||
// xMOVSS(ptr[&cpuRegs.pc], xRegisterSSE(mmreg));
|
||||
// }
|
||||
// else if( (mmreg = _checkMMXreg(MMX_GPR+reg, MODE_READ)) >= 0 ) {
|
||||
// xMOVD(ptr[&cpuRegs.pc], xRegisterMMX(mmreg));
|
||||
// SetMMXstate();
|
||||
// }
|
||||
// else {
|
||||
// xMOV(eax, ptr[(void*)((int)&cpuRegs.GPR.r[ reg ].UL[ 0 ] )]);
|
||||
// xMOV(ptr[&cpuRegs.pc], eax);
|
||||
|
@ -937,21 +895,17 @@ void SetBranchImm( u32 imm )
|
|||
|
||||
void SaveBranchState()
|
||||
{
|
||||
s_savex86FpuState = x86FpuState;
|
||||
s_savenBlockCycles = s_nBlockCycles;
|
||||
memcpy(s_saveConstRegs, g_cpuConstRegs, sizeof(g_cpuConstRegs));
|
||||
s_saveHasConstReg = g_cpuHasConstReg;
|
||||
s_saveFlushedConstReg = g_cpuFlushedConstReg;
|
||||
s_psaveInstInfo = g_pCurInstInfo;
|
||||
|
||||
// save all mmx regs
|
||||
memcpy(s_saveMMXregs, mmxregs, sizeof(mmxregs));
|
||||
memcpy(s_saveXMMregs, xmmregs, sizeof(xmmregs));
|
||||
}
|
||||
|
||||
void LoadBranchState()
|
||||
{
|
||||
x86FpuState = s_savex86FpuState;
|
||||
s_nBlockCycles = s_savenBlockCycles;
|
||||
|
||||
memcpy(g_cpuConstRegs, s_saveConstRegs, sizeof(g_cpuConstRegs));
|
||||
|
@ -959,8 +913,6 @@ void LoadBranchState()
|
|||
g_cpuFlushedConstReg = s_saveFlushedConstReg;
|
||||
g_pCurInstInfo = s_psaveInstInfo;
|
||||
|
||||
// restore all mmx regs
|
||||
memcpy(mmxregs, s_saveMMXregs, sizeof(mmxregs));
|
||||
memcpy(xmmregs, s_saveXMMregs, sizeof(xmmregs));
|
||||
}
|
||||
|
||||
|
@ -992,18 +944,8 @@ void iFlushCall(int flushtype)
|
|||
else if( flushtype & FLUSH_FLUSH_XMM)
|
||||
_flushXMMregs();
|
||||
|
||||
if( flushtype & FLUSH_FREE_MMX )
|
||||
_freeMMXregs();
|
||||
else if( flushtype & FLUSH_FLUSH_MMX)
|
||||
_flushMMXregs();
|
||||
|
||||
if( flushtype & FLUSH_CACHED_REGS )
|
||||
_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.
|
||||
|
@ -1301,15 +1243,6 @@ void recompileNextInstruction(int delayslot)
|
|||
|
||||
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) {
|
||||
if( xmmregs[i].inuse ) {
|
||||
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:
|
||||
Console.Warning("branch %x in delay slot!", cpuRegs.code);
|
||||
_clearNeededX86regs();
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
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:
|
||||
Console.Warning("branch %x in delay slot!", cpuRegs.code);
|
||||
_clearNeededX86regs();
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
return;
|
||||
}
|
||||
|
@ -1360,7 +1291,6 @@ void recompileNextInstruction(int delayslot)
|
|||
#if 0
|
||||
// TODO: Free register ?
|
||||
// _freeXMMregs();
|
||||
// _freeMMXregs();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1369,7 +1299,7 @@ void recompileNextInstruction(int delayslot)
|
|||
if( s_bFlushReg ) {
|
||||
//if( !_flushUnusedConstReg() ) {
|
||||
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();
|
||||
s_bFlushReg = !flushed;
|
||||
// }
|
||||
|
@ -1381,11 +1311,9 @@ void recompileNextInstruction(int delayslot)
|
|||
|
||||
//CHECK_XMMCHANGED();
|
||||
_clearNeededX86regs();
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
|
||||
// _freeXMMregs();
|
||||
// _freeMMXregs();
|
||||
// _flushCachedRegs();
|
||||
// g_cpuHasConstReg = 1;
|
||||
|
||||
|
@ -1684,13 +1612,11 @@ static void __fastcall recRecompile( const u32 startpc )
|
|||
// reset recomp state variables
|
||||
s_nBlockCycles = 0;
|
||||
pc = startpc;
|
||||
x86FpuState = FPU_STATE;
|
||||
g_cpuHasConstReg = g_cpuFlushedConstReg = 1;
|
||||
pxAssert( g_cpuConstRegs[0].UD[0] == 0 );
|
||||
|
||||
_initX86regs();
|
||||
_initXMMregs();
|
||||
_initMMXregs();
|
||||
|
||||
if( EmuConfig.Cpu.Recompiler.PreBlockCheckEE )
|
||||
{
|
||||
|
@ -2090,7 +2016,6 @@ StartRecomp:
|
|||
|
||||
pxAssert( xGetPtr() < recMem->GetPtrEnd() );
|
||||
pxAssert( recConstBufPtr < recConstBuf + RECCONSTBUF_SIZE );
|
||||
pxAssert( x86FpuState == 0 );
|
||||
|
||||
pxAssert(xGetPtr() - recPtr < _64kb);
|
||||
s_pCurBlockEx->x86size = xGetPtr() - recPtr;
|
||||
|
|
|
@ -186,7 +186,6 @@ void recSetBranchEQ(int info, int bne, int process)
|
|||
}
|
||||
}
|
||||
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
}
|
||||
|
||||
|
@ -211,7 +210,6 @@ void recSetBranchL(int ltz)
|
|||
if( ltz ) j32Ptr[ 0 ] = JGE32( 0 );
|
||||
else j32Ptr[ 0 ] = JL32( 0 );
|
||||
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
}
|
||||
|
||||
|
@ -586,7 +584,6 @@ void recBLEZ()
|
|||
|
||||
x86SetJ8( j8Ptr[ 0 ] );
|
||||
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
|
||||
SaveBranchState();
|
||||
|
@ -634,7 +631,6 @@ void recBGTZ()
|
|||
|
||||
x86SetJ8( j8Ptr[ 0 ] );
|
||||
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
|
||||
SaveBranchState();
|
||||
|
@ -807,7 +803,6 @@ void recBLEZL()
|
|||
if( !(g_cpuConstRegs[_Rs_].SD[0] <= 0) )
|
||||
SetBranchImm( pc + 4);
|
||||
else {
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
recompileNextInstruction(1);
|
||||
SetBranchImm( branchTo );
|
||||
|
@ -826,7 +821,6 @@ void recBLEZL()
|
|||
|
||||
x86SetJ32( j32Ptr[ 0 ] );
|
||||
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
|
||||
SaveBranchState();
|
||||
|
@ -853,7 +847,6 @@ void recBGTZL()
|
|||
if( !(g_cpuConstRegs[_Rs_].SD[0] > 0) )
|
||||
SetBranchImm( pc + 4);
|
||||
else {
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
recompileNextInstruction(1);
|
||||
SetBranchImm( branchTo );
|
||||
|
@ -872,7 +865,6 @@ void recBGTZL()
|
|||
|
||||
x86SetJ32( j32Ptr[ 0 ] );
|
||||
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
|
||||
SaveBranchState();
|
||||
|
|
|
@ -121,10 +121,6 @@ void recJALR()
|
|||
// if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
|
||||
// xMOVSS(ptr[&cpuRegs.pc], xRegisterSSE(mmreg));
|
||||
// }
|
||||
// else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) {
|
||||
// xMOVD(ptr[&cpuRegs.pc], xRegisterMMX(mmreg));
|
||||
// SetMMXstate();
|
||||
// }
|
||||
// else {
|
||||
// xMOV(eax, ptr[(void*)((int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] )]);
|
||||
// xMOV(ptr[&cpuRegs.pc], eax);
|
||||
|
@ -148,7 +144,6 @@ void recJALR()
|
|||
}
|
||||
}
|
||||
|
||||
_clearNeededMMXregs();
|
||||
_clearNeededXMMregs();
|
||||
recompileNextInstruction(1);
|
||||
|
||||
|
|
|
@ -116,69 +116,21 @@ void recMFHILO(int hi)
|
|||
}
|
||||
}
|
||||
else {
|
||||
regd = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rd_, MODE_WRITE);
|
||||
|
||||
if( regd >= 0 ) {
|
||||
xMOVQ(xRegisterMMX(regd), xRegisterSSE(reghi));
|
||||
}
|
||||
else {
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
xMOVQ(ptr[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]], xRegisterSSE(reghi));
|
||||
}
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
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));
|
||||
}
|
||||
}
|
||||
if( regd >= 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 {
|
||||
if( regd >= 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 {
|
||||
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 {
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
xMOV(eax, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 0 ] : (uptr)&cpuRegs.LO.UL[ 0 ])]);
|
||||
xMOV(edx, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 1 ] : (uptr)&cpuRegs.LO.UL[ 1 ])]);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||
}
|
||||
}
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
xMOV(eax, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 0 ] : (uptr)&cpuRegs.LO.UL[ 0 ])]);
|
||||
xMOV(edx, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 1 ] : (uptr)&cpuRegs.LO.UL[ 1 ])]);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,76 +161,27 @@ void recMTHILO(int hi)
|
|||
|
||||
}
|
||||
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 {
|
||||
_flushConstReg(_Rs_);
|
||||
xMOVL.PS(xRegisterSSE(reghi), ptr[&cpuRegs.GPR.r[ _Rs_ ].UD[ 0 ]]);
|
||||
xmmregs[reghi].mode |= MODE_WRITE;
|
||||
}
|
||||
_flushConstReg(_Rs_);
|
||||
xMOVL.PS(xRegisterSSE(reghi), ptr[&cpuRegs.GPR.r[ _Rs_ ].UD[ 0 ]]);
|
||||
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 ]]);
|
||||
}
|
||||
}
|
||||
if( regs >= 0 ) {
|
||||
xMOVQ(ptr[(void*)(addrhilo)], xRegisterSSE(regs));
|
||||
}
|
||||
else {
|
||||
if( regs >= 0 ) {
|
||||
xMOVQ(ptr[(void*)(addrhilo)], xRegisterSSE(regs));
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
xMOV(ptr32[(u32*)(addrhilo)], g_cpuConstRegs[_Rs_].UL[0] );
|
||||
xMOV(ptr32[(u32*)(addrhilo+4)], g_cpuConstRegs[_Rs_].UL[1] );
|
||||
}
|
||||
else {
|
||||
regs = _checkMMXreg(MMX_GPR+_Rs_, MODE_WRITE);
|
||||
|
||||
if( regs >= 0 ) {
|
||||
SetMMXstate();
|
||||
xMOVQ(ptr[(void*)(addrhilo)], xRegisterMMX(regs));
|
||||
}
|
||||
else {
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
xMOV(ptr32[(u32*)(addrhilo)], g_cpuConstRegs[_Rs_].UL[0] );
|
||||
xMOV(ptr32[(u32*)(addrhilo+4)], g_cpuConstRegs[_Rs_].UL[1] );
|
||||
}
|
||||
else {
|
||||
_eeMoveGPRtoR(ecx, _Rs_);
|
||||
_flushEEreg(_Rs_);
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||
xMOV(ptr[(void*)(addrhilo)], eax);
|
||||
xMOV(ptr[(void*)(addrhilo+4)], edx);
|
||||
}
|
||||
}
|
||||
_eeMoveGPRtoR(ecx, _Rs_);
|
||||
_flushEEreg(_Rs_);
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||
xMOV(ptr[(void*)(addrhilo)], eax);
|
||||
xMOV(ptr[(void*)(addrhilo+4)], edx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -345,19 +248,11 @@ void recMFHILO1(int hi)
|
|||
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 {
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
xMOV(eax, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 2 ] : (uptr)&cpuRegs.LO.UL[ 2 ])]);
|
||||
xMOV(edx, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 3 ] : (uptr)&cpuRegs.LO.UL[ 3 ])]);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||
}
|
||||
_deleteEEreg(_Rd_, 0);
|
||||
xMOV(eax, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 2 ] : (uptr)&cpuRegs.LO.UL[ 2 ])]);
|
||||
xMOV(edx, ptr[(void*)(hi ? (uptr)&cpuRegs.HI.UL[ 3 ] : (uptr)&cpuRegs.LO.UL[ 3 ])]);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -387,24 +282,16 @@ void recMTHILO1(int hi)
|
|||
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));
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
xMOV(ptr32[(u32*)(addrhilo+8)], g_cpuConstRegs[_Rs_].UL[0] );
|
||||
xMOV(ptr32[(u32*)(addrhilo+12)], g_cpuConstRegs[_Rs_].UL[1] );
|
||||
}
|
||||
else {
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
xMOV(ptr32[(u32*)(addrhilo+8)], g_cpuConstRegs[_Rs_].UL[0] );
|
||||
xMOV(ptr32[(u32*)(addrhilo+12)], g_cpuConstRegs[_Rs_].UL[1] );
|
||||
}
|
||||
else {
|
||||
_flushEEreg(_Rs_);
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||
xMOV(ptr[(void*)(addrhilo+8)], eax);
|
||||
xMOV(ptr[(void*)(addrhilo+12)], edx);
|
||||
}
|
||||
_flushEEreg(_Rs_);
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||
xMOV(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||
xMOV(ptr[(void*)(addrhilo+8)], eax);
|
||||
xMOV(ptr[(void*)(addrhilo+12)], edx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -456,47 +343,24 @@ void recMOVZtemp_consts(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(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||
}
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||
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[ 1 ]], edx);
|
||||
}
|
||||
|
||||
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 ] ]);
|
||||
xOR(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ] ]);
|
||||
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(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||
}
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||
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[ 1 ]], edx);
|
||||
|
||||
x86SetJ8( j8Ptr[ 0 ] );
|
||||
SetMMXstate();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// 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(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||
}
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||
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[ 1 ]], edx);
|
||||
}
|
||||
|
||||
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 ] ]);
|
||||
xOR(eax, ptr[&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ] ]);
|
||||
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(edx, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]]);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ]], eax);
|
||||
xMOV(ptr[&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ]], edx);
|
||||
}
|
||||
xMOV(eax, ptr[&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]]);
|
||||
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[ 1 ]], edx);
|
||||
|
||||
x86SetJ8( j8Ptr[ 0 ] );
|
||||
|
||||
SetMMXstate();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
_deleteMMXreg(XMMGPR_LO, 2);
|
||||
|
||||
if( (reglo = _checkXMMreg(XMMTYPE_GPRREG, XMMGPR_LO, MODE_READ)) >= 0 ) {
|
||||
if( xmmregs[reglo].mode & MODE_WRITE ) {
|
||||
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 ) {
|
||||
_deleteMMXreg(XMMGPR_HI, 2);
|
||||
|
||||
if( (reghi = _checkXMMreg(XMMTYPE_GPRREG, XMMGPR_HI, MODE_READ)) >= 0 ) {
|
||||
if( xmmregs[reghi].mode & MODE_WRITE ) {
|
||||
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)
|
||||
{
|
||||
int reglo, reghi;
|
||||
|
@ -253,42 +129,32 @@ void recWritebackConstHILO(u64 res, int writed, int upper)
|
|||
u8 testlive = upper?EEINST_LIVE2:EEINST_LIVE0;
|
||||
|
||||
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)]);
|
||||
reglo = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_LO, MODE_WRITE|MODE_READ);
|
||||
|
||||
if( reglo >= 0 ) {
|
||||
u32* mem_ptr = recGetImm64(res & 0x80000000 ? -1 : 0, (u32)res);
|
||||
if( upper ) xMOVH.PS(xRegisterSSE(reglo), ptr[mem_ptr]);
|
||||
else xMOVL.PS(xRegisterSSE(reglo), ptr[mem_ptr]);
|
||||
}
|
||||
else {
|
||||
reglo = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_LO, MODE_WRITE|MODE_READ);
|
||||
|
||||
if( reglo >= 0 ) {
|
||||
u32* mem_ptr = recGetImm64(res & 0x80000000 ? -1 : 0, (u32)res);
|
||||
if( upper ) xMOVH.PS(xRegisterSSE(reglo), ptr[mem_ptr]);
|
||||
else xMOVL.PS(xRegisterSSE(reglo), ptr[mem_ptr]);
|
||||
}
|
||||
else {
|
||||
xMOV(ptr32[(u32*)(loaddr)], res & 0xffffffff);
|
||||
xMOV(ptr32[(u32*)(loaddr+4)], (res&0x80000000)?0xffffffff:0);
|
||||
}
|
||||
xMOV(ptr32[(u32*)(loaddr)], res & 0xffffffff);
|
||||
xMOV(ptr32[(u32*)(loaddr+4)], (res&0x80000000)?0xffffffff:0);
|
||||
}
|
||||
}
|
||||
|
||||
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)]);
|
||||
reghi = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_HI, MODE_WRITE|MODE_READ);
|
||||
|
||||
if( reghi >= 0 ) {
|
||||
u32* mem_ptr = recGetImm64((res >> 63) ? -1 : 0, res >> 32);
|
||||
if( upper ) xMOVH.PS(xRegisterSSE(reghi), ptr[mem_ptr]);
|
||||
else xMOVL.PS(xRegisterSSE(reghi), ptr[mem_ptr]);
|
||||
}
|
||||
else {
|
||||
reghi = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_HI, MODE_WRITE|MODE_READ);
|
||||
|
||||
if( reghi >= 0 ) {
|
||||
u32* mem_ptr = recGetImm64((res >> 63) ? -1 : 0, res >> 32);
|
||||
if( upper ) xMOVH.PS(xRegisterSSE(reghi), ptr[mem_ptr]);
|
||||
else xMOVL.PS(xRegisterSSE(reghi), ptr[mem_ptr]);
|
||||
}
|
||||
else {
|
||||
_deleteEEreg(XMMGPR_HI, 0);
|
||||
xMOV(ptr32[(u32*)(hiaddr)], res >> 32);
|
||||
xMOV(ptr32[(u32*)(hiaddr+4)], (res>>63)?0xffffffff:0);
|
||||
}
|
||||
_deleteEEreg(XMMGPR_HI, 0);
|
||||
xMOV(ptr32[(u32*)(hiaddr)], res >> 32);
|
||||
xMOV(ptr32[(u32*)(hiaddr+4)], (res>>63)?0xffffffff:0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,63 +189,18 @@ void recMULTsuper(int info, int upper, int process)
|
|||
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)
|
||||
{
|
||||
//recMULT_process(info, 0);
|
||||
recMULTsuper(info, 0, 0);
|
||||
}
|
||||
|
||||
void recMULT_consts(int info)
|
||||
{
|
||||
//recMULT_process(info, PROCESS_CONSTS);
|
||||
recMULTsuper(info, 0, PROCESS_CONSTS);
|
||||
}
|
||||
|
||||
void recMULT_constt(int info)
|
||||
{
|
||||
//recMULT_process(info, PROCESS_CONSTT);
|
||||
recMULTsuper(info, 0, PROCESS_CONSTT);
|
||||
}
|
||||
|
||||
|
@ -700,8 +521,6 @@ void recMADD()
|
|||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
||||
|
@ -772,8 +591,6 @@ void recMADDU()
|
|||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
||||
|
@ -842,8 +659,6 @@ void recMADD1()
|
|||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
||||
|
@ -914,8 +729,6 @@ void recMADDU1()
|
|||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
xMOV(eax, g_cpuConstRegs[_Rs_].UL[0] );
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include "R5900OpcodeTables.h"
|
||||
#include "iR5900.h"
|
||||
|
||||
#define NO_MMX 1
|
||||
|
||||
using namespace x86Emitter;
|
||||
|
||||
namespace R5900 {
|
||||
|
@ -145,7 +143,6 @@ void recDSLLs_(int info, int sa)
|
|||
int rtreg, rdreg;
|
||||
pxAssert( !(info & PROCESS_EE_XMM) );
|
||||
|
||||
#if NO_MMX
|
||||
_addNeededGPRtoXMMreg(_Rt_);
|
||||
_addNeededGPRtoXMMreg(_Rd_);
|
||||
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));
|
||||
_deleteGPRtoXMMreg(_Rt_, 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)
|
||||
|
@ -190,7 +177,6 @@ void recDSRLs_(int info, int sa)
|
|||
int rtreg, rdreg;
|
||||
pxAssert( !(info & PROCESS_EE_XMM) );
|
||||
|
||||
#if NO_MMX
|
||||
_addNeededGPRtoXMMreg(_Rt_);
|
||||
_addNeededGPRtoXMMreg(_Rd_);
|
||||
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));
|
||||
_deleteGPRtoXMMreg(_Rt_, 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)
|
||||
|
@ -235,7 +211,6 @@ void recDSRAs_(int info, int sa)
|
|||
int rtreg, rdreg, t0reg;
|
||||
pxAssert( !(info & PROCESS_EE_XMM) );
|
||||
|
||||
#if NO_MMX
|
||||
_addNeededGPRtoXMMreg(_Rt_);
|
||||
_addNeededGPRtoXMMreg(_Rd_);
|
||||
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));
|
||||
_deleteGPRtoXMMreg(_Rt_, 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)
|
||||
|
@ -391,7 +342,6 @@ void recSetShiftV(int info, int* rsreg, int* rtreg, int* rdreg, int* rstemp)
|
|||
{
|
||||
pxAssert( !(info & PROCESS_EE_XMM) );
|
||||
|
||||
#if NO_MMX
|
||||
_addNeededGPRtoXMMreg(_Rt_);
|
||||
_addNeededGPRtoXMMreg(_Rd_);
|
||||
*rtreg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ);
|
||||
|
@ -405,21 +355,6 @@ void recSetShiftV(int info, int* rsreg, int* rtreg, int* rdreg, int* rstemp)
|
|||
*rsreg = *rstemp;
|
||||
|
||||
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)
|
||||
|
@ -430,7 +365,6 @@ void recSetConstShiftV(int info, int* rsreg, int* rdreg, int* rstemp)
|
|||
// 2/ CPU has minimum cycle delay between read/write
|
||||
_flushConstReg(_Rt_);
|
||||
|
||||
#if NO_MMX
|
||||
_addNeededGPRtoXMMreg(_Rd_);
|
||||
*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]]);
|
||||
xAND(eax, 0x3f);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -583,7 +507,6 @@ void recDSLLV_constt(int info)
|
|||
{
|
||||
int rsreg, rdreg, rstemp = -1;
|
||||
recSetConstShiftV(info, &rsreg, &rdreg, &rstemp);
|
||||
#if NO_MMX
|
||||
xMOVDQA(xRegisterSSE(rdreg), ptr[&cpuRegs.GPR.r[_Rt_]]);
|
||||
xPSLL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
||||
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));
|
||||
//_deleteGPRtoXMMreg(_Rt_, 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)
|
||||
|
@ -607,7 +524,6 @@ void recDSLLV_(int info)
|
|||
int rsreg, rtreg, rdreg, rstemp = -1;
|
||||
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
||||
|
||||
#if NO_MMX
|
||||
xPSLL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
||||
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
||||
|
||||
|
@ -617,10 +533,6 @@ void recDSLLV_(int info)
|
|||
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
||||
_deleteGPRtoXMMreg(_Rt_, 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);
|
||||
|
@ -643,7 +555,6 @@ void recDSRLV_constt(int info)
|
|||
int rsreg, rdreg, rstemp = -1;
|
||||
recSetConstShiftV(info, &rsreg, &rdreg, &rstemp);
|
||||
|
||||
#if NO_MMX
|
||||
xMOVDQA(xRegisterSSE(rdreg), ptr[&cpuRegs.GPR.r[_Rt_]]);
|
||||
xPSRL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
||||
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));
|
||||
//_deleteGPRtoXMMreg(_Rt_, 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)
|
||||
|
@ -666,7 +572,6 @@ void recDSRLV_(int info)
|
|||
int rsreg, rtreg, rdreg, rstemp = -1;
|
||||
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
||||
|
||||
#if NO_MMX
|
||||
xPSRL.Q(xRegisterSSE(rdreg), xRegisterSSE(rsreg));
|
||||
if( rstemp != -1 ) _freeXMMreg(rstemp);
|
||||
|
||||
|
@ -676,10 +581,6 @@ void recDSRLV_(int info)
|
|||
xMOVL.PD(ptr64[&cpuRegs.GPR.r[ _Rd_ ].UD[ 0 ]] , xRegisterSSE(rdreg));
|
||||
_deleteGPRtoXMMreg(_Rt_, 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);
|
||||
|
@ -700,7 +601,6 @@ void recDSRAV_consts(int info)
|
|||
void recDSRAV_constt(int info)
|
||||
{
|
||||
int rsreg, rdreg, rstemp = -1, t0reg, t1reg;
|
||||
#if NO_MMX
|
||||
t0reg = _allocTempXMMreg(XMMT_INT, -1);
|
||||
t1reg = _allocTempXMMreg(XMMT_INT, -1);
|
||||
|
||||
|
@ -734,41 +634,11 @@ void recDSRAV_constt(int info)
|
|||
_freeXMMreg(t0reg);
|
||||
_freeXMMreg(t1reg);
|
||||
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)
|
||||
{
|
||||
int rsreg, rtreg, rdreg, rstemp = -1, t0reg, t1reg;
|
||||
#if NO_MMX
|
||||
t0reg = _allocTempXMMreg(XMMT_INT, -1);
|
||||
t1reg = _allocTempXMMreg(XMMT_INT, -1);
|
||||
recSetShiftV(info, &rsreg, &rtreg, &rdreg, &rstemp);
|
||||
|
@ -801,33 +671,6 @@ void recDSRAV_(int info)
|
|||
_freeXMMreg(t0reg);
|
||||
_freeXMMreg(t1reg);
|
||||
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);
|
||||
|
|
|
@ -51,7 +51,6 @@ void _deleteEEreg(int reg, int flush)
|
|||
}
|
||||
GPR_DEL_CONST(reg);
|
||||
_deleteGPRtoXMMreg(reg, flush ? 0 : 2);
|
||||
_deleteMMXreg(MMX_GPR+reg, flush ? 0 : 2);
|
||||
}
|
||||
|
||||
void _flushEEreg(int reg)
|
||||
|
@ -62,24 +61,23 @@ void _flushEEreg(int reg)
|
|||
return;
|
||||
}
|
||||
_deleteGPRtoXMMreg(reg, 1);
|
||||
_deleteMMXreg(MMX_GPR + reg, 1);
|
||||
}
|
||||
|
||||
// if not mmx, then xmm
|
||||
int eeProcessHILO(int reg, int mode, int mmx)
|
||||
{
|
||||
// Fixme: MMX problem
|
||||
int usemmx = 0/*mmx && _hasFreeMMXreg()*/;
|
||||
int usemmx = 0;
|
||||
if( (usemmx || _hasFreeXMMreg()) || !(g_pCurInstInfo->regs[reg]&EEINST_LASTUSE) ) {
|
||||
//if( usemmx ) return _allocMMXreg(-1, MMX_GPR+reg, mode);
|
||||
return _allocGPRtoXMMreg(-1, reg, mode);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define PROCESS_EE_SETMODES(mmreg) ((mmxregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITES:0)
|
||||
#define PROCESS_EE_SETMODET(mmreg) ((mmxregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITET:0)
|
||||
// Strangely this code is used on NOT-MMX path ...
|
||||
#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
|
||||
// core of reg caching
|
||||
|
@ -91,7 +89,6 @@ void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNP
|
|||
|
||||
if( GPR_IS_CONST2(_Rs_, _Rt_) ) {
|
||||
if( xmminfo & XMMINFO_WRITED ) {
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
||||
_deleteGPRtoXMMreg(_Rd_, 2);
|
||||
}
|
||||
if( xmminfo&XMMINFO_WRITED ) GPR_SET_CONST(_Rd_);
|
||||
|
@ -135,7 +132,6 @@ void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNP
|
|||
_freeXMMreg(mmreg1);
|
||||
if( GPR_IS_CONST1(_Rs_) ) info &= ~PROCESS_EE_MODEWRITET;
|
||||
else info &= ~PROCESS_EE_MODEWRITES;
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
||||
xmmregs[mmreg1].inuse = 1;
|
||||
xmmregs[mmreg1].reg = _Rd_;
|
||||
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_)) ) {
|
||||
_freeXMMreg(mmreg2);
|
||||
info &= ~PROCESS_EE_MODEWRITET;
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
||||
xmmregs[mmreg2].inuse = 1;
|
||||
xmmregs[mmreg2].reg = _Rd_;
|
||||
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_)) ) {
|
||||
_freeXMMreg(mmreg1);
|
||||
info &= ~PROCESS_EE_MODEWRITES;
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
||||
xmmregs[mmreg1].inuse = 1;
|
||||
xmmregs[mmreg1].reg = _Rd_;
|
||||
xmmregs[mmreg1].mode = moded;
|
||||
|
@ -230,19 +224,13 @@ void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNP
|
|||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
if( xmminfo&XMMINFO_WRITED )
|
||||
_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
|
||||
// if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) {
|
||||
// _deleteGPRtoXMMreg(XMMGPR_LO, (xmminfo&XMMINFO_READLO)?1:0);
|
||||
// _deleteMMXreg(MMX_GPR+MMX_LO, (xmminfo&XMMINFO_READLO)?1:0);
|
||||
// }
|
||||
// if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) {
|
||||
// _deleteGPRtoXMMreg(XMMGPR_HI, (xmminfo&XMMINFO_READHI)?1:0);
|
||||
// _deleteMMXreg(MMX_GPR+MMX_HI, (xmminfo&XMMINFO_READHI)?1:0);
|
||||
// }
|
||||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
|
@ -268,7 +256,6 @@ void eeRecompileCode1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
|||
if ( ! _Rt_ ) return;
|
||||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 2);
|
||||
_deleteGPRtoXMMreg(_Rt_, 2);
|
||||
GPR_SET_CONST(_Rt_);
|
||||
constcode();
|
||||
|
@ -293,7 +280,6 @@ void eeRecompileCode1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
|||
if( (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_) ) {
|
||||
_freeXMMreg(mmreg1);
|
||||
info &= ~PROCESS_EE_MODEWRITES;
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 2);
|
||||
xmmregs[mmreg1].inuse = 1;
|
||||
xmmregs[mmreg1].reg = _Rt_;
|
||||
xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ;
|
||||
|
@ -314,8 +300,6 @@ void eeRecompileCode1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
|||
// regular x86
|
||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
_deleteGPRtoXMMreg(_Rt_, 2);
|
||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 2);
|
||||
|
||||
noconstcode(0);
|
||||
GPR_DEL_CONST(_Rt_);
|
||||
|
@ -328,7 +312,6 @@ void eeRecompileCode2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
|||
if ( ! _Rd_ ) return;
|
||||
|
||||
if( GPR_IS_CONST1(_Rt_) ) {
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
||||
_deleteGPRtoXMMreg(_Rd_, 2);
|
||||
GPR_SET_CONST(_Rd_);
|
||||
constcode();
|
||||
|
@ -353,7 +336,6 @@ void eeRecompileCode2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
|||
if( (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rt_) ) {
|
||||
_freeXMMreg(mmreg1);
|
||||
info &= ~PROCESS_EE_MODEWRITET;
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
||||
xmmregs[mmreg1].inuse = 1;
|
||||
xmmregs[mmreg1].reg = _Rd_;
|
||||
xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ;
|
||||
|
@ -374,8 +356,6 @@ void eeRecompileCode2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode)
|
|||
// regular x86
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteGPRtoXMMreg(_Rd_, 2);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
||||
|
||||
noconstcode(0);
|
||||
GPR_DEL_CONST(_Rd_);
|
||||
|
@ -420,9 +400,6 @@ void eeRecompileCodeConst0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R59
|
|||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
_deleteGPRtoXMMreg(_Rt_, 1);
|
||||
_deleteGPRtoXMMreg(_Rd_, 0);
|
||||
_deleteMMXreg(MMX_GPR+_Rs_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rt_, 1);
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 0);
|
||||
|
||||
if( GPR_IS_CONST2(_Rs_, _Rt_) ) {
|
||||
GPR_SET_CONST(_Rd_);
|
||||
|
@ -576,7 +553,6 @@ int eeRecompileCodeXMM(int xmminfo)
|
|||
if( regd < 0 ) {
|
||||
if( !(xmminfo&XMMINFO_READD) && (xmminfo & XMMINFO_READT) && (_Rt_ == 0 || (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rt_)) ) {
|
||||
_freeXMMreg(EEREC_T);
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
||||
xmmregs[EEREC_T].inuse = 1;
|
||||
xmmregs[EEREC_T].reg = _Rd_;
|
||||
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_)) ) {
|
||||
_freeXMMreg(EEREC_S);
|
||||
_deleteMMXreg(MMX_GPR+_Rd_, 2);
|
||||
xmmregs[EEREC_S].inuse = 1;
|
||||
xmmregs[EEREC_S].reg = _Rd_;
|
||||
xmmregs[EEREC_S].mode = readd;
|
||||
|
@ -664,7 +639,6 @@ void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo
|
|||
_freeXMMreg(mmregt);
|
||||
info &= ~PROCESS_EE_MODEWRITET;
|
||||
}
|
||||
_deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2);
|
||||
xmmregs[mmregt].inuse = 1;
|
||||
xmmregs[mmregt].reg = 0;
|
||||
xmmregs[mmregt].mode = readacc;
|
||||
|
@ -676,7 +650,6 @@ void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo
|
|||
_freeXMMreg(mmregs);
|
||||
info &= ~PROCESS_EE_MODEWRITES;
|
||||
}
|
||||
_deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2);
|
||||
xmmregs[mmregs].inuse = 1;
|
||||
xmmregs[mmregs].reg = 0;
|
||||
xmmregs[mmregs].mode = readacc;
|
||||
|
@ -700,7 +673,6 @@ void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo
|
|||
_freeXMMreg(mmregt);
|
||||
info &= ~PROCESS_EE_MODEWRITET;
|
||||
}
|
||||
_deleteMMXreg(MMX_FPU+_Fd_, 2);
|
||||
xmmregs[mmregt].inuse = 1;
|
||||
xmmregs[mmregt].reg = _Fd_;
|
||||
xmmregs[mmregt].mode = readd;
|
||||
|
@ -711,7 +683,6 @@ void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo
|
|||
_freeXMMreg(mmregs);
|
||||
info &= ~PROCESS_EE_MODEWRITES;
|
||||
}
|
||||
_deleteMMXreg(MMX_FPU+_Fd_, 2);
|
||||
xmmregs[mmregs].inuse = 1;
|
||||
xmmregs[mmregs].reg = _Fd_;
|
||||
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)) ) {
|
||||
if( FPUINST_ISLIVE(XMMFPU_ACC) )
|
||||
_freeXMMreg(mmregacc);
|
||||
_deleteMMXreg(MMX_FPU+_Fd_, 2);
|
||||
xmmregs[mmregacc].inuse = 1;
|
||||
xmmregs[mmregacc].reg = _Fd_;
|
||||
xmmregs[mmregacc].mode = readd;
|
||||
|
|
|
@ -68,15 +68,11 @@ static void iMOV128_SSE( const xIndirectVoid& destRm, const xIndirectVoid& srcRm
|
|||
xMOVDQA( destRm, reg );
|
||||
}
|
||||
|
||||
// Moves 64 bits of data from point B to point A, using either MMX, 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).
|
||||
// Moves 64 bits of data from point B to point A, using either SSE, or x86 registers
|
||||
//
|
||||
static void iMOV64_Smart( const xIndirectVoid& destRm, const xIndirectVoid& srcRm )
|
||||
{
|
||||
if( (x86FpuState == FPU_STATE) && _hasFreeXMMreg() )
|
||||
if( _hasFreeXMMreg() )
|
||||
{
|
||||
// Move things using MOVLPS:
|
||||
xRegisterSSE reg( _allocTempXMMreg( XMMT_INT, -1 ) );
|
||||
|
@ -86,20 +82,10 @@ static void iMOV64_Smart( const xIndirectVoid& destRm, const xIndirectVoid& srcR
|
|||
return;
|
||||
}
|
||||
|
||||
if( _hasFreeMMXreg() )
|
||||
{
|
||||
xRegisterMMX reg( _allocMMXreg(-1, MMX_TEMP, 0) );
|
||||
xMOVQ( reg, srcRm );
|
||||
xMOVQ( destRm, reg );
|
||||
_freeMMXreg( reg.Id );
|
||||
}
|
||||
else
|
||||
{
|
||||
xMOV( eax, srcRm );
|
||||
xMOV( destRm, eax );
|
||||
xMOV( eax, srcRm+4 );
|
||||
xMOV( destRm+4, eax );
|
||||
}
|
||||
xMOV( eax, srcRm );
|
||||
xMOV( destRm, eax );
|
||||
xMOV( eax, srcRm+4 );
|
||||
xMOV( destRm+4, eax );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -17,16 +17,12 @@
|
|||
|
||||
#define REC_VUOP(VU, f) { \
|
||||
_freeXMMregs(/*&VU*/); \
|
||||
_freeMMXregs(); \
|
||||
SetFPUstate();) \
|
||||
xMOV(ptr32[&VU.code], (u32)VU.code); \
|
||||
xCALL((void*)(uptr)VU##MI_##f); \
|
||||
}
|
||||
|
||||
#define REC_VUOPs(VU, f) { \
|
||||
_freeXMMregs(); \
|
||||
_freeMMXregs(); \
|
||||
SetFPUstate();) \
|
||||
if (VU==&VU1) { \
|
||||
xMOV(ptr32[&VU1.code], (u32)VU1.code); \
|
||||
xCALL((void*)(uptr)VU1MI_##f); \
|
||||
|
@ -39,16 +35,12 @@
|
|||
|
||||
#define REC_VUOPFLAGS(VU, f) { \
|
||||
_freeXMMregs(/*&VU*/); \
|
||||
_freeMMXregs(); \
|
||||
SetFPUstate(); \
|
||||
xMOV(ptr32[&VU.code], (u32)VU.code); \
|
||||
xCALL((void*)(uptr)VU##MI_##f); \
|
||||
}
|
||||
|
||||
#define REC_VUBRANCH(VU, f) { \
|
||||
_freeXMMregs(/*&VU*/); \
|
||||
_freeMMXregs(); \
|
||||
SetFPUstate(); \
|
||||
xMOV(ptr32[&VU.code], (u32)VU.code); \
|
||||
xMOV(ptr32[&VU.VI[REG_TPC].UL], (u32)pc); \
|
||||
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;
|
||||
// not doing this because it's slow and not needed (rama)
|
||||
// _initXMMregs();
|
||||
// _initMMXregs();
|
||||
// _initX86regs();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue