Play-/Source/MipsJitter.cpp

117 lines
2.5 KiB
C++
Raw Normal View History

#include <assert.h>
#include "MipsJitter.h"
2022-11-30 17:09:32 -05:00
#include "MIPS.h"
2022-12-01 16:40:25 -05:00
#include "offsetof_def.h"
CMipsJitter::CMipsJitter(Jitter::CCodeGen* codeGen)
2018-04-30 21:01:23 +01:00
: CJitter(codeGen)
, m_firstBlockLabel(-1)
2018-04-30 21:01:23 +01:00
, m_lastBlockLabel(-1)
{
2022-11-30 17:09:32 -05:00
for(unsigned int i = 0; i < 4; i++)
{
SetVariableAsConstant(
offsetof(CMIPS, m_State.nGPR[CMIPS::R0].nV[i]),
0);
}
}
void CMipsJitter::Begin()
{
CJitter::Begin();
m_firstBlockLabel = -1;
m_lastBlockLabel = -1;
}
void CMipsJitter::PushRel(size_t offset)
{
VARIABLESTATUS* status = GetVariableStatus(offset);
if(status == NULL)
{
CJitter::PushRel(offset);
}
else
{
switch(status->operandType)
{
case Jitter::SYM_CONSTANT:
CJitter::PushCst(status->operandValue);
break;
default:
throw std::runtime_error("Unsupported operand type.");
break;
}
}
}
void CMipsJitter::PushRel64(size_t offset)
{
VARIABLESTATUS* statusLo = GetVariableStatus(offset + 0);
VARIABLESTATUS* statusHi = GetVariableStatus(offset + 4);
if(statusLo == NULL || statusHi == NULL)
{
CJitter::PushRel64(offset);
}
else
{
if((statusLo->operandType == Jitter::SYM_CONSTANT) && (statusHi->operandType == Jitter::SYM_CONSTANT))
{
uint64 result = static_cast<uint64>(statusLo->operandValue) | (static_cast<uint64>(statusHi->operandValue) << 32);
CJitter::PushCst64(result);
}
else
{
throw std::runtime_error("Unsupported operand type.");
}
}
}
Jitter::CJitter::LABEL CMipsJitter::GetFirstBlockLabel()
{
assert(m_firstBlockLabel != -1);
return m_firstBlockLabel;
}
Jitter::CJitter::LABEL CMipsJitter::GetLastBlockLabel()
{
if(m_lastBlockLabel == -1)
{
m_lastBlockLabel = CreateLabel();
}
return m_lastBlockLabel;
}
void CMipsJitter::MarkFirstBlockLabel()
{
m_firstBlockLabel = CreateLabel();
MarkLabel(m_firstBlockLabel);
}
void CMipsJitter::MarkLastBlockLabel()
2018-07-03 19:06:25 -04:00
{
if(m_lastBlockLabel != -1)
{
MarkLabel(m_lastBlockLabel);
}
}
void CMipsJitter::SetVariableAsConstant(size_t variableId, uint32 value)
{
2015-04-23 02:04:12 -04:00
VARIABLESTATUS status;
status.operandType = Jitter::SYM_CONSTANT;
2015-04-23 02:04:12 -04:00
status.operandValue = value;
SetVariableStatus(variableId, status);
}
CMipsJitter::VARIABLESTATUS* CMipsJitter::GetVariableStatus(size_t variableId)
{
2015-04-23 02:04:12 -04:00
auto statusIterator(m_variableStatus.find(variableId));
return statusIterator == m_variableStatus.end() ? nullptr : &statusIterator->second;
}
void CMipsJitter::SetVariableStatus(size_t variableId, const VARIABLESTATUS& status)
{
2015-04-23 02:04:12 -04:00
assert(GetVariableStatus(variableId) == NULL);
m_variableStatus[variableId] = status;
}