CodeGen updates

git-svn-id: http://svn.purei.org/purei/trunk@673 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
jpd002 2010-06-23 23:48:01 +00:00
parent 69fa0dc6ad
commit a7f5ee55da
8 changed files with 174 additions and 33 deletions

View File

@ -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)

View File

@ -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)
{

View File

@ -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&);

View File

@ -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;
}
}

View File

@ -14,6 +14,7 @@ namespace Jitter
OP_ADD,
OP_SUB,
OP_CMP,
OP_AND,
OP_OR,

View File

@ -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

View File

@ -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();

View File

@ -18,6 +18,9 @@ private:
{
uint32 number1;
uint32 number2;
uint32 number3;
uint32 number4;
uint32 number5;
};
CONTEXT m_context;