mirror of
https://github.com/libretro/Play-.git
synced 2025-01-09 18:10:57 +00:00
CodeGen updates
git-svn-id: http://svn.purei.org/purei/trunk@673 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
69fa0dc6ad
commit
a7f5ee55da
@ -241,9 +241,19 @@ void CJitter::Call(void* pFunc, unsigned int nParamCount, bool nKeepRet)
|
||||
}
|
||||
}
|
||||
|
||||
void CJitter::Cmp(CONDITION nCondition)
|
||||
void CJitter::Cmp(CONDITION condition)
|
||||
{
|
||||
throw std::exception();
|
||||
SymbolPtr tempSym = MakeSymbol(SYM_TEMPORARY, m_nextTemporary++);
|
||||
|
||||
STATEMENT statement;
|
||||
statement.op = OP_CMP;
|
||||
statement.src2 = MakeSymbolRef(m_Shadow.Pull());
|
||||
statement.src1 = MakeSymbolRef(m_Shadow.Pull());
|
||||
statement.jmpCondition = condition;
|
||||
statement.dst = MakeSymbolRef(tempSym);
|
||||
InsertStatement(statement);
|
||||
|
||||
m_Shadow.Push(tempSym);
|
||||
}
|
||||
|
||||
void CJitter::Div()
|
||||
@ -349,7 +359,16 @@ void CJitter::SignExt16()
|
||||
|
||||
void CJitter::Shl()
|
||||
{
|
||||
throw std::exception();
|
||||
SymbolPtr tempSym = MakeSymbol(SYM_TEMPORARY, m_nextTemporary++);
|
||||
|
||||
STATEMENT statement;
|
||||
statement.op = OP_SLL;
|
||||
statement.src2 = MakeSymbolRef(m_Shadow.Pull());
|
||||
statement.src1 = MakeSymbolRef(m_Shadow.Pull());
|
||||
statement.dst = MakeSymbolRef(tempSym);
|
||||
InsertStatement(statement);
|
||||
|
||||
m_Shadow.Push(tempSym);
|
||||
}
|
||||
|
||||
void CJitter::Shl(uint8 nAmount)
|
||||
|
@ -206,6 +206,17 @@ void CCodeGen_x86::Emit_Shift_RegRegCst(const STATEMENT& statement)
|
||||
((m_assembler).*(SHIFTOP::OpCst()))(CX86Assembler::MakeRegisterAddress(m_registers[dst->m_valueLow]), static_cast<uint8>(src2->m_valueLow));
|
||||
}
|
||||
|
||||
template <typename SHIFTOP>
|
||||
void CCodeGen_x86::Emit_Shift_RegRelCst(const STATEMENT& statement)
|
||||
{
|
||||
CSymbol* dst = statement.dst->GetSymbol().get();
|
||||
CSymbol* src1 = statement.src1->GetSymbol().get();
|
||||
CSymbol* src2 = statement.src2->GetSymbol().get();
|
||||
|
||||
m_assembler.MovEd(m_registers[dst->m_valueLow], CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, src1->m_valueLow));
|
||||
((m_assembler).*(SHIFTOP::OpCst()))(CX86Assembler::MakeRegisterAddress(m_registers[dst->m_valueLow]), static_cast<uint8>(src2->m_valueLow));
|
||||
}
|
||||
|
||||
template <typename SHIFTOP>
|
||||
void CCodeGen_x86::Emit_Shift_RegRegReg(const STATEMENT& statement)
|
||||
{
|
||||
@ -224,16 +235,55 @@ void CCodeGen_x86::Emit_Shift_RegRegReg(const STATEMENT& statement)
|
||||
}
|
||||
|
||||
template <typename SHIFTOP>
|
||||
void CCodeGen_x86::Emit_Shift_RegRelCst(const STATEMENT& statement)
|
||||
void CCodeGen_x86::Emit_Shift_RegRelReg(const STATEMENT& statement)
|
||||
{
|
||||
CSymbol* dst = statement.dst->GetSymbol().get();
|
||||
CSymbol* src1 = statement.src1->GetSymbol().get();
|
||||
CSymbol* src2 = statement.src2->GetSymbol().get();
|
||||
|
||||
m_assembler.MovEd(CX86Assembler::rCX, CX86Assembler::MakeRegisterAddress(m_registers[src2->m_valueLow]));
|
||||
|
||||
m_assembler.MovEd(m_registers[dst->m_valueLow], CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, src1->m_valueLow));
|
||||
((m_assembler).*(SHIFTOP::OpCst()))(CX86Assembler::MakeRegisterAddress(m_registers[dst->m_valueLow]), static_cast<uint8>(src2->m_valueLow));
|
||||
((m_assembler).*(SHIFTOP::OpVar()))(CX86Assembler::MakeRegisterAddress(m_registers[dst->m_valueLow]));
|
||||
}
|
||||
|
||||
template <typename SHIFTOP>
|
||||
void CCodeGen_x86::Emit_Shift_RelRegReg(const STATEMENT& statement)
|
||||
{
|
||||
CSymbol* dst = statement.dst->GetSymbol().get();
|
||||
CSymbol* src1 = statement.src1->GetSymbol().get();
|
||||
CSymbol* src2 = statement.src2->GetSymbol().get();
|
||||
|
||||
m_assembler.MovEd(CX86Assembler::rCX, CX86Assembler::MakeRegisterAddress(m_registers[src2->m_valueLow]));
|
||||
m_assembler.MovEd(CX86Assembler::rAX, CX86Assembler::MakeRegisterAddress(m_registers[src1->m_valueLow]));
|
||||
((m_assembler).*(SHIFTOP::OpVar()))(CX86Assembler::MakeRegisterAddress(CX86Assembler::rAX));
|
||||
m_assembler.MovGd(CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, dst->m_valueLow), CX86Assembler::rAX);
|
||||
}
|
||||
|
||||
template <typename SHIFTOP>
|
||||
void CCodeGen_x86::Emit_Shift_RegRegRel(const STATEMENT& statement)
|
||||
{
|
||||
CSymbol* dst = statement.dst->GetSymbol().get();
|
||||
CSymbol* src1 = statement.src1->GetSymbol().get();
|
||||
CSymbol* src2 = statement.src2->GetSymbol().get();
|
||||
|
||||
m_assembler.MovEd(CX86Assembler::rCX, CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, src2->m_valueLow));
|
||||
|
||||
if(!dst->Equals(src1))
|
||||
{
|
||||
m_assembler.MovEd(m_registers[dst->m_valueLow], CX86Assembler::MakeRegisterAddress(m_registers[src1->m_valueLow]));
|
||||
}
|
||||
|
||||
((m_assembler).*(SHIFTOP::OpVar()))(CX86Assembler::MakeRegisterAddress(m_registers[dst->m_valueLow]));
|
||||
}
|
||||
|
||||
#define SHIFT_CONST_MATCHERS(SHIFTOP_CST, SHIFTOP) \
|
||||
{ SHIFTOP_CST, MATCH_REGISTER, MATCH_REGISTER, MATCH_CONSTANT, &CCodeGen_x86::Emit_Shift_RegRegCst<SHIFTOP> }, \
|
||||
{ SHIFTOP_CST, MATCH_REGISTER, MATCH_RELATIVE, MATCH_CONSTANT, &CCodeGen_x86::Emit_Shift_RegRelCst<SHIFTOP> }, \
|
||||
{ SHIFTOP_CST, MATCH_REGISTER, MATCH_REGISTER, MATCH_REGISTER, &CCodeGen_x86::Emit_Shift_RegRegReg<SHIFTOP> }, \
|
||||
{ SHIFTOP_CST, MATCH_RELATIVE, MATCH_REGISTER, MATCH_REGISTER, &CCodeGen_x86::Emit_Shift_RelRegReg<SHIFTOP> }, \
|
||||
{ SHIFTOP_CST, MATCH_REGISTER, MATCH_REGISTER, MATCH_RELATIVE, &CCodeGen_x86::Emit_Shift_RegRegRel<SHIFTOP> },
|
||||
|
||||
CCodeGen_x86::CONSTMATCHER CCodeGen_x86::g_constMatchers[] =
|
||||
{
|
||||
{ OP_LABEL, MATCH_NIL, MATCH_NIL, MATCH_NIL, &CCodeGen_x86::MarkLabel },
|
||||
@ -249,6 +299,9 @@ CCodeGen_x86::CONSTMATCHER CCodeGen_x86::g_constMatchers[] =
|
||||
{ OP_SUB, MATCH_TEMPORARY, MATCH_TEMPORARY, MATCH_CONSTANT, &CCodeGen_x86::Emit_Alu_TmpTmpCst<ALUOP_SUB> },
|
||||
{ OP_SUB, MATCH_REGISTER, MATCH_CONSTANT, MATCH_REGISTER, &CCodeGen_x86::Emit_Alu_RegCstReg<ALUOP_SUB> },
|
||||
|
||||
{ OP_CMP, MATCH_REGISTER, MATCH_REGISTER, MATCH_CONSTANT, &CCodeGen_x86::Emit_Cmp_RegRegCst },
|
||||
{ OP_CMP, MATCH_REGISTER, MATCH_REGISTER, MATCH_REGISTER, &CCodeGen_x86::Emit_Cmp_RegRegReg },
|
||||
|
||||
{ OP_AND, MATCH_REGISTER, MATCH_REGISTER, MATCH_CONSTANT, &CCodeGen_x86::Emit_Alu_RegRegCst<ALUOP_AND> },
|
||||
|
||||
{ OP_OR, MATCH_REGISTER, MATCH_TEMPORARY, MATCH_CONSTANT, &CCodeGen_x86::Emit_Alu_RegTmpCst<ALUOP_OR> },
|
||||
@ -262,15 +315,9 @@ CCodeGen_x86::CONSTMATCHER CCodeGen_x86::g_constMatchers[] =
|
||||
{ OP_NOT, MATCH_REGISTER, MATCH_REGISTER, MATCH_NIL, &CCodeGen_x86::Emit_Not_RegReg },
|
||||
{ OP_NOT, MATCH_REGISTER, MATCH_RELATIVE, MATCH_NIL, &CCodeGen_x86::Emit_Not_RegRel },
|
||||
|
||||
{ OP_SRL, MATCH_TEMPORARY, MATCH_REGISTER, MATCH_CONSTANT, &CCodeGen_x86::Emit_Shift_TmpRegCst<SHIFTOP_SRL> },
|
||||
{ OP_SRL, MATCH_REGISTER, MATCH_REGISTER, MATCH_CONSTANT, &CCodeGen_x86::Emit_Shift_RegRegCst<SHIFTOP_SRL> },
|
||||
{ OP_SRL, MATCH_REGISTER, MATCH_REGISTER, MATCH_REGISTER, &CCodeGen_x86::Emit_Shift_RegRegReg<SHIFTOP_SRL> },
|
||||
|
||||
{ OP_SRA, MATCH_REGISTER, MATCH_REGISTER, MATCH_CONSTANT, &CCodeGen_x86::Emit_Shift_RegRegCst<SHIFTOP_SRA> },
|
||||
{ OP_SRA, MATCH_REGISTER, MATCH_REGISTER, MATCH_REGISTER, &CCodeGen_x86::Emit_Shift_RegRegReg<SHIFTOP_SRA> },
|
||||
|
||||
{ OP_SLL, MATCH_REGISTER, MATCH_REGISTER, MATCH_CONSTANT, &CCodeGen_x86::Emit_Shift_RegRegCst<SHIFTOP_SLL> },
|
||||
{ OP_SLL, MATCH_REGISTER, MATCH_RELATIVE, MATCH_CONSTANT, &CCodeGen_x86::Emit_Shift_RegRelCst<SHIFTOP_SLL> },
|
||||
SHIFT_CONST_MATCHERS(OP_SRL, SHIFTOP_SRL)
|
||||
SHIFT_CONST_MATCHERS(OP_SRA, SHIFTOP_SRA)
|
||||
SHIFT_CONST_MATCHERS(OP_SLL, SHIFTOP_SLL)
|
||||
|
||||
{ OP_MOV, MATCH_REGISTER, MATCH_RELATIVE, MATCH_NIL, &CCodeGen_x86::Emit_Mov_RegRel },
|
||||
{ OP_MOV, MATCH_REGISTER, MATCH_REGISTER, MATCH_NIL, &CCodeGen_x86::Emit_Mov_RegReg },
|
||||
@ -537,25 +584,43 @@ void CCodeGen_x86::Emit_ExtHigh64RelTmp64(const STATEMENT& statement)
|
||||
m_assembler.MovGd(CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, dst->m_valueLow), CX86Assembler::rAX);
|
||||
}
|
||||
|
||||
//void CCodeGen_x86::Emit_CondJmp_RelCst(const STATEMENT& statement)
|
||||
//{
|
||||
// CRelativeSymbol* src1 = dynamic_symbolref_cast<CRelativeSymbol>(statement.src1);
|
||||
// CConstantSymbol* src2 = dynamic_symbolref_cast<CConstantSymbol>(statement.src2);
|
||||
//
|
||||
// cout << "cmp dword ptr[ebp + " << src1->m_valueLow << "], " << src2->m_valueLow << endl;
|
||||
//
|
||||
// switch(statement.jmpCondition)
|
||||
// {
|
||||
// case CONDITION_NE:
|
||||
// cout << "jne ";
|
||||
// break;
|
||||
// default:
|
||||
// assert(0);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// cout << "$LABEL_" << statement.jmpBlock << endl;
|
||||
//}
|
||||
void CCodeGen_x86::Cmp_GetFlag(const CX86Assembler::CAddress& dst, CONDITION flag)
|
||||
{
|
||||
switch(flag)
|
||||
{
|
||||
case CONDITION_LT:
|
||||
m_assembler.SetlEb(dst);
|
||||
break;
|
||||
case CONDITION_NE:
|
||||
m_assembler.SetneEb(dst);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CCodeGen_x86::Emit_Cmp_RegRegCst(const STATEMENT& statement)
|
||||
{
|
||||
CSymbol* dst = statement.dst->GetSymbol().get();
|
||||
CSymbol* src1 = statement.src1->GetSymbol().get();
|
||||
CSymbol* src2 = statement.src2->GetSymbol().get();
|
||||
|
||||
m_assembler.CmpId(CX86Assembler::MakeRegisterAddress(m_registers[src1->m_valueLow]), src2->m_valueLow);
|
||||
Cmp_GetFlag(CX86Assembler::MakeRegisterAddress(CX86Assembler::rAX), statement.jmpCondition);
|
||||
m_assembler.MovzxEb(m_registers[dst->m_valueLow], CX86Assembler::MakeRegisterAddress(CX86Assembler::rAX));
|
||||
}
|
||||
|
||||
void CCodeGen_x86::Emit_Cmp_RegRegReg(const STATEMENT& statement)
|
||||
{
|
||||
CSymbol* dst = statement.dst->GetSymbol().get();
|
||||
CSymbol* src1 = statement.src1->GetSymbol().get();
|
||||
CSymbol* src2 = statement.src2->GetSymbol().get();
|
||||
|
||||
m_assembler.CmpEd(m_registers[src1->m_valueLow], CX86Assembler::MakeRegisterAddress(m_registers[src2->m_valueLow]));
|
||||
Cmp_GetFlag(CX86Assembler::MakeRegisterAddress(CX86Assembler::rAX), statement.jmpCondition);
|
||||
m_assembler.MovzxEb(m_registers[dst->m_valueLow], CX86Assembler::MakeRegisterAddress(CX86Assembler::rAX));
|
||||
}
|
||||
|
||||
void CCodeGen_x86::Emit_CondJmp_RegCst(const STATEMENT& statement)
|
||||
{
|
||||
|
@ -137,11 +137,19 @@ namespace Jitter
|
||||
template <typename> void Emit_Shift_RegRegCst(const STATEMENT&);
|
||||
template <typename> void Emit_Shift_RegRelCst(const STATEMENT&);
|
||||
template <typename> void Emit_Shift_RegRegReg(const STATEMENT&);
|
||||
template <typename> void Emit_Shift_RegRelReg(const STATEMENT&);
|
||||
template <typename> void Emit_Shift_RelRegReg(const STATEMENT&);
|
||||
template <typename> void Emit_Shift_RegRegRel(const STATEMENT&);
|
||||
|
||||
//NOT
|
||||
void Emit_Not_RegReg(const STATEMENT&);
|
||||
void Emit_Not_RegRel(const STATEMENT&);
|
||||
|
||||
//CMP
|
||||
void Cmp_GetFlag(const CX86Assembler::CAddress&, CONDITION);
|
||||
void Emit_Cmp_RegRegCst(const STATEMENT&);
|
||||
void Emit_Cmp_RegRegReg(const STATEMENT&);
|
||||
|
||||
//ADD64
|
||||
void Emit_Add64_RelRelRel(const STATEMENT&);
|
||||
|
||||
|
@ -218,6 +218,22 @@ void CJitter::DumpStatementList(const StatementList& statements)
|
||||
case OP_SUB:
|
||||
cout << " - ";
|
||||
break;
|
||||
case OP_CMP:
|
||||
cout << " CMP(";
|
||||
switch(statement.jmpCondition)
|
||||
{
|
||||
case CONDITION_LT:
|
||||
cout << "LT";
|
||||
break;
|
||||
case CONDITION_NE:
|
||||
cout << "NE";
|
||||
break;
|
||||
default:
|
||||
cout << "??";
|
||||
break;
|
||||
}
|
||||
cout << ") ";
|
||||
break;
|
||||
case OP_MUL:
|
||||
case OP_MULS:
|
||||
case OP_FP_MUL:
|
||||
@ -849,6 +865,7 @@ bool CJitter::CopyPropagation(StatementList& statements)
|
||||
innerStatement.op = outerStatement.op;
|
||||
innerStatement.src1 = outerStatement.src1;
|
||||
innerStatement.src2 = outerStatement.src2;
|
||||
innerStatement.jmpCondition = outerStatement.jmpCondition;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace Jitter
|
||||
|
||||
OP_ADD,
|
||||
OP_SUB,
|
||||
OP_CMP,
|
||||
|
||||
OP_AND,
|
||||
OP_OR,
|
||||
|
@ -118,6 +118,11 @@ namespace Jitter
|
||||
return (m_type == SYM_RELATIVE) || (m_type == SYM_RELATIVE64) || (m_type == SYM_FP_REL_SINGLE);
|
||||
}
|
||||
|
||||
bool IsTemporary() const
|
||||
{
|
||||
return (m_type == SYM_TEMPORARY) || (m_type == SYM_TEMPORARY64) || (m_type == SYM_FP_TMP_SINGLE);
|
||||
}
|
||||
|
||||
bool Equals(CSymbol* symbol) const
|
||||
{
|
||||
return
|
||||
|
@ -17,8 +17,12 @@ void CCompareTest::Run()
|
||||
memset(&m_context, 0, sizeof(m_context));
|
||||
m_context.number1 = 0x80000000;
|
||||
m_context.number2 = 0x10;
|
||||
m_context.number3 = 0x10000;
|
||||
|
||||
(*m_function)(&m_context);
|
||||
|
||||
TEST_VERIFY(m_context.number1 == 0x10000);
|
||||
TEST_VERIFY(m_context.number3 == 0);
|
||||
}
|
||||
|
||||
void CCompareTest::Compile(Jitter::CJitter& jitter)
|
||||
@ -30,10 +34,29 @@ void CCompareTest::Compile(Jitter::CJitter& jitter)
|
||||
|
||||
jitter.Begin();
|
||||
{
|
||||
//number1 = ((number1 >> number2) < -1) << number2
|
||||
|
||||
jitter.PushRel(offsetof(CONTEXT, number1));
|
||||
jitter.PushRel(offsetof(CONTEXT, number2));
|
||||
jitter.Sra();
|
||||
|
||||
jitter.PushCst(0xFFFFFFFF);
|
||||
jitter.Cmp(Jitter::CONDITION_LT);
|
||||
|
||||
//jitter.PushTop();
|
||||
//jitter.PullRel(offsetof(CONTEXT, number4));
|
||||
|
||||
jitter.PushRel(offsetof(CONTEXT, number2));
|
||||
jitter.Shl();
|
||||
jitter.PullRel(offsetof(CONTEXT, number1));
|
||||
|
||||
//number3 = number1 != number3
|
||||
|
||||
jitter.PushRel(offsetof(CONTEXT, number1));
|
||||
jitter.PushRel(offsetof(CONTEXT, number3));
|
||||
jitter.Cmp(Jitter::CONDITION_NE);
|
||||
|
||||
jitter.PullRel(offsetof(CONTEXT, number3));
|
||||
}
|
||||
jitter.End();
|
||||
|
||||
|
@ -18,6 +18,9 @@ private:
|
||||
{
|
||||
uint32 number1;
|
||||
uint32 number2;
|
||||
uint32 number3;
|
||||
uint32 number4;
|
||||
uint32 number5;
|
||||
};
|
||||
|
||||
CONTEXT m_context;
|
||||
|
Loading…
Reference in New Issue
Block a user