Added immediate constant stuff in ARM CodeGen.

git-svn-id: http://svn.purei.org/purei/trunk@522 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
jpd002 2009-05-13 00:03:11 +00:00
parent 7b7c69d8b0
commit b51b5facfd
4 changed files with 63 additions and 18 deletions

View file

@ -218,6 +218,11 @@ void CArmAssembler::Mov(REGISTER rd, const RegisterAluOperand& operand)
WriteWord(opcode);
}
void CArmAssembler::Mov(REGISTER rd, const ImmediateAluOperand& operand)
{
MovCc(CONDITION_AL, rd, operand);
}
void CArmAssembler::MovCc(CONDITION condition, REGISTER rd, const ImmediateAluOperand& operand)
{
InstructionAlu instruction;

View file

@ -177,6 +177,7 @@ public:
void Ldr(REGISTER, REGISTER, const LdrAddress&);
void Mov(REGISTER, REGISTER);
void Mov(REGISTER, const RegisterAluOperand&);
void Mov(REGISTER, const ImmediateAluOperand&);
void MovCc(CONDITION, REGISTER, const ImmediateAluOperand&);
void Mvn(REGISTER, REGISTER);
void Or(REGISTER, REGISTER, REGISTER);

View file

@ -964,33 +964,69 @@ void CCodeGen::LoadRelativeInRegister(CArmAssembler::REGISTER registerId, uint32
m_assembler.Ldr(registerId, g_baseRegister, CArmAssembler::MakeImmediateLdrAddress(relative));
}
uint32 CCodeGen::RotateRight(uint32 value)
{
uint32 carry = value & 1;
value >>= 1;
value |= carry << 31;
return value;
}
uint32 CCodeGen::RotateLeft(uint32 value)
{
uint32 carry = value >> 31;
value <<= 1;
value |= carry;
return value;
}
void CCodeGen::LoadConstantInRegister(CArmAssembler::REGISTER registerId, uint32 constant)
{
//Search for an existing literal
unsigned int literalPtr = -1;
for(unsigned int i = 0; i < m_lastLiteralPtr; i++)
uint32 shadowConstant = constant;
int shiftAmount = -1;
for(unsigned int i = 0; i < 16; i++)
{
if(m_literalPool[i] == constant)
if((shadowConstant & 0xFF) == shadowConstant)
{
literalPtr = i;
shiftAmount = i;
break;
}
shadowConstant = RotateLeft(shadowConstant);
shadowConstant = RotateLeft(shadowConstant);
}
if(literalPtr == -1)
if(shiftAmount != -1)
{
assert(m_lastLiteralPtr != LITERAL_POOL_SIZE);
literalPtr = m_lastLiteralPtr++;
m_literalPool[literalPtr] = constant;
m_assembler.Mov(registerId, CArmAssembler::MakeImmediateAluOperand(shadowConstant, shiftAmount));
}
else
{
//Search for an existing literal
unsigned int literalPtr = -1;
for(unsigned int i = 0; i < m_lastLiteralPtr; i++)
{
if(m_literalPool[i] == constant)
{
literalPtr = i;
break;
}
}
if(literalPtr == -1)
{
assert(m_lastLiteralPtr != LITERAL_POOL_SIZE);
literalPtr = m_lastLiteralPtr++;
m_literalPool[literalPtr] = constant;
}
LITERAL_POOL_REF reference;
reference.poolPtr = literalPtr;
reference.dstRegister = registerId;
reference.offset = m_stream->Tell();
m_literalPoolRefs.push_back(reference);
//Write a blank instruction
m_stream->Write32(0);
}
LITERAL_POOL_REF reference;
reference.poolPtr = literalPtr;
reference.dstRegister = registerId;
reference.offset = m_stream->Tell();
m_literalPoolRefs.push_back(reference);
//Write a blank instruction
m_stream->Write32(0);
}
void CCodeGen::DumpLiteralPool()

View file

@ -161,6 +161,9 @@ private:
void PushReg(CArmAssembler::REGISTER);
uint32 RotateRight(uint32);
uint32 RotateLeft(uint32);
void LoadRelativeInRegister(CArmAssembler::REGISTER, uint32);
void LoadConstantInRegister(CArmAssembler::REGISTER, uint32);