Added MIN.S and MAX.S and some missing CodeGen cases.

git-svn-id: http://svn.purei.org/purei/trunk@512 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
jpd002 2009-05-02 02:11:55 +00:00
parent 965705ad39
commit d0fef1d64a
9 changed files with 93 additions and 3 deletions

View File

@ -314,6 +314,24 @@ void CCOP_FPU::CVT_W_S()
m_codeGen->FP_PullWordTruncate(offsetof(CMIPS, m_State.nCOP10[m_nFD * 2]));
}
//28
void CCOP_FPU::MAX_S()
{
m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP10[m_nFS * 2]));
m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP10[m_nFT * 2]));
m_codeGen->FP_Max();
m_codeGen->FP_PullSingle(offsetof(CMIPS, m_State.nCOP10[m_nFD * 2]));
}
//29
void CCOP_FPU::MIN_S()
{
m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP10[m_nFS * 2]));
m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP10[m_nFT * 2]));
m_codeGen->FP_Min();
m_codeGen->FP_PullSingle(offsetof(CMIPS, m_State.nCOP10[m_nFD * 2]));
}
//32
void CCOP_FPU::C_EQ_S()
{
@ -418,7 +436,7 @@ CCOP_FPU::InstructionFuncConstant CCOP_FPU::m_pOpSingle[0x40] =
//0x20
&Illegal, &Illegal, &Illegal, &Illegal, &CVT_W_S, &Illegal, &Illegal, &Illegal,
//0x28
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
&MAX_S, &MIN_S, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x30
&Illegal, &Illegal, &C_EQ_S, &Illegal, &C_LT_S, &Illegal, &C_LE_S, &Illegal,
//0x38

View File

@ -85,6 +85,8 @@ private:
void MADD_S();
void MSUB_S();
void CVT_W_S();
void MAX_S();
void MIN_S();
void C_EQ_S();
void C_LT_S();
void C_LE_S();

View File

@ -284,8 +284,8 @@ INSTRUCTION CCOP_FPU::m_cReflS[64] =
{ NULL, NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL },
//0x28
{ NULL, NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL },
{ "MAX.S", NULL, CopyMnemonic, ReflOpFdFsFt, NULL, NULL },
{ "MIN.S", NULL, CopyMnemonic, ReflOpFdFsFt, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL },

View File

@ -1247,6 +1247,19 @@ void CCodeGen::Cmp(CONDITION nCondition)
Cmp(nCondition);
}
else if(FitsPattern<ConstantRegister>())
{
RegisterConstant::PatternValue ops = GetPattern<ConstantRegister>();
unsigned int register1 = AllocateRegister();
unsigned int register2 = ops.second;
LoadConstantInRegister(register1, ops.first);
PushReg(register1);
PushReg(register2);
Cmp(nCondition);
}
else if(FitsPattern<RegisterConstant>())
{
RegisterConstant::PatternValue ops = GetPattern<RegisterConstant>();
@ -2035,6 +2048,34 @@ void CCodeGen::Shl64(uint8 nAmount)
ops.q <<= nAmount;
PushCst(ops.d0);
PushCst(ops.d1);
}
else if(FitsPattern<ConstantRelative>())
{
//Upper = Relative
//Lower = Constant
ConstantRelative::PatternValue ops(GetPattern<ConstantRelative>());
if(nAmount < 32)
{
unsigned int register1 = AllocateRegister();
unsigned int register2 = AllocateRegister();
LoadConstantInRegister(register1, ops.first);
LoadRelativeInRegister(register2, ops.second);
m_Assembler.ShldEd(
CX86Assembler::MakeRegisterAddress(m_nRegisterLookupEx[register2]),
m_nRegisterLookupEx[register1], nAmount);
m_Assembler.ShlEd(CX86Assembler::MakeRegisterAddress(m_nRegisterLookupEx[register1]), nAmount);
PushReg(register1);
PushReg(register2);
}
else
{
assert(0);
}
}
else
{

View File

@ -152,6 +152,8 @@ public:
void FP_Add();
void FP_Abs();
void FP_Sub();
void FP_Max();
void FP_Min();
void FP_Mul();
void FP_Div();
void FP_Cmp(CONDITION);

View File

@ -254,6 +254,16 @@ void CCodeGen::FP_Sub()
FP_GenericTwoOperand(bind(&CX86Assembler::SubssEd, m_Assembler, PLACEHOLDER_1, PLACEHOLDER_2));
}
void CCodeGen::FP_Max()
{
FP_GenericTwoOperand(bind(&CX86Assembler::MaxssEd, m_Assembler, PLACEHOLDER_1, PLACEHOLDER_2));
}
void CCodeGen::FP_Min()
{
FP_GenericTwoOperand(bind(&CX86Assembler::MinssEd, m_Assembler, PLACEHOLDER_1, PLACEHOLDER_2));
}
void CCodeGen::FP_Mul()
{
FP_GenericTwoOperand(bind(&CX86Assembler::MulssEd, m_Assembler, PLACEHOLDER_1, PLACEHOLDER_2));

View File

@ -289,6 +289,7 @@ typedef GenericOneArgument<CCodeGen::REGISTER128> SingleRegister128;
typedef GenericTwoArguments<CCodeGen::RELATIVE, CCodeGen::CONSTANT> RelativeConstant;
typedef GenericTwoArguments<CCodeGen::REGISTER, CCodeGen::CONSTANT> RegisterConstant;
typedef GenericTwoArguments<CCodeGen::CONSTANT, CCodeGen::RELATIVE> ConstantRelative;
typedef GenericTwoArguments<CCodeGen::CONSTANT, CCodeGen::REGISTER> ConstantRegister;
typedef GenericTwoArguments<CCodeGen::CONSTANT, CCodeGen::CONSTANT> ConstantConstant;
typedef GenericTwoArguments<CCodeGen::RELATIVE, CCodeGen::RELATIVE> RelativeRelative;
typedef GenericTwoArguments<CCodeGen::REGISTER, CCodeGen::REGISTER> RegisterRegister;

View File

@ -246,6 +246,8 @@ public:
void MovssEd(XMMREGISTER, const CAddress&);
void AddssEd(XMMREGISTER, const CAddress&);
void SubssEd(XMMREGISTER, const CAddress&);
void MaxssEd(XMMREGISTER, const CAddress&);
void MinssEd(XMMREGISTER, const CAddress&);
void MulssEd(XMMREGISTER, const CAddress&);
void DivssEd(XMMREGISTER, const CAddress&);
void RcpssEd(XMMREGISTER, const CAddress&);

View File

@ -32,6 +32,20 @@ void CX86Assembler::SubssEd(XMMREGISTER registerId, const CAddress& address)
WriteEdVdOp(0x5C, address, registerId);
}
void CX86Assembler::MaxssEd(XMMREGISTER registerId, const CAddress& address)
{
WriteByte(0xF3);
WriteByte(0x0F);
WriteEdVdOp(0x5F, address, registerId);
}
void CX86Assembler::MinssEd(XMMREGISTER registerId, const CAddress& address)
{
WriteByte(0xF3);
WriteByte(0x0F);
WriteEdVdOp(0x5D, address, registerId);
}
void CX86Assembler::MulssEd(XMMREGISTER registerId, const CAddress& address)
{
WriteByte(0xF3);