mirror of
https://github.com/libretro/Play-.git
synced 2024-11-27 18:50:28 +00:00
95 lines
2.0 KiB
C++
95 lines
2.0 KiB
C++
#include <assert.h>
|
|
#include "MipsJitter.h"
|
|
|
|
CMipsJitter::CMipsJitter(Jitter::CCodeGen* codeGen)
|
|
: CJitter(codeGen)
|
|
, m_lastBlockLabel(-1)
|
|
{
|
|
}
|
|
|
|
void CMipsJitter::Begin()
|
|
{
|
|
CJitter::Begin();
|
|
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::GetFinalBlockLabel()
|
|
{
|
|
if(m_lastBlockLabel == -1)
|
|
{
|
|
m_lastBlockLabel = CreateLabel();
|
|
}
|
|
return m_lastBlockLabel;
|
|
}
|
|
|
|
void CMipsJitter::MarkFinalBlockLabel()
|
|
{
|
|
if(m_lastBlockLabel != -1)
|
|
{
|
|
MarkLabel(m_lastBlockLabel);
|
|
}
|
|
}
|
|
|
|
void CMipsJitter::SetVariableAsConstant(size_t variableId, uint32 value)
|
|
{
|
|
VARIABLESTATUS status;
|
|
status.operandType = Jitter::SYM_CONSTANT;
|
|
status.operandValue = value;
|
|
SetVariableStatus(variableId, status);
|
|
}
|
|
|
|
CMipsJitter::VARIABLESTATUS* CMipsJitter::GetVariableStatus(size_t variableId)
|
|
{
|
|
auto statusIterator(m_variableStatus.find(variableId));
|
|
return statusIterator == m_variableStatus.end() ? nullptr : &statusIterator->second;
|
|
}
|
|
|
|
void CMipsJitter::SetVariableStatus(size_t variableId, const VARIABLESTATUS& status)
|
|
{
|
|
assert(GetVariableStatus(variableId) == NULL);
|
|
m_variableStatus[variableId] = status;
|
|
}
|