You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw-tes3mp/components/compiler/generator.cpp

144 lines
3.6 KiB
C++

#include "generator.hpp"
#include <cassert>
#include <algorithm>
#include <iterator>
#include "literals.hpp"
namespace
{
Interpreter::Type_Code segment0 (unsigned int c, unsigned int arg0)
{
assert (c<64);
return (c<<24) | (arg0 & 0xffffff);
}
Interpreter::Type_Code segment1 (unsigned int c, unsigned int arg0, unsigned int arg1)
{
assert (c<64);
return 0x40000000 | (c<<24) | ((arg0 & 0xfff)<<12) | (arg1 & 0xfff);
}
Interpreter::Type_Code segment2 (unsigned int c, unsigned int arg0)
{
assert (c<1024);
return 0x80000000 | (c<<20) | (arg0 & 0xfffff);
}
Interpreter::Type_Code segment3 (unsigned int c, unsigned int arg0)
{
assert (c<1024);
return 0xc0000000 | (c<<20) | (arg0 & 0xffff);
}
Interpreter::Type_Code segment4 (unsigned int c, unsigned int arg0, unsigned int arg1)
{
assert (c<1024);
return 0xc4000000 | (c<<16) | ((arg0 & 0xff)<<8) | (arg1 & 0xff);
}
Interpreter::Type_Code segment5 (unsigned int c)
{
assert (c<67108864);
return 0xc8000000 | c;
}
void opPushInt (Compiler::Generator::CodeContainer& code, int value)
{
code.push_back (segment0 (0, value));
}
void opFetchIntLiteral (Compiler::Generator::CodeContainer& code)
{
code.push_back (segment5 (4));
}
void opFetchFloatLiteral (Compiler::Generator::CodeContainer& code)
{
code.push_back (segment5 (5));
}
void opIntToFloat (Compiler::Generator::CodeContainer& code)
{
code.push_back (segment5 (3));
}
void opFloatToInt (Compiler::Generator::CodeContainer& code)
{
assert (0); // not implemented
}
void opStoreLocalShort (Compiler::Generator::CodeContainer& code)
{
code.push_back (segment5 (0));
}
void opStoreLocalLong (Compiler::Generator::CodeContainer& code)
{
code.push_back (segment5 (1));
}
void opStoreLocalFloat (Compiler::Generator::CodeContainer& code)
{
code.push_back (segment5 (2));
}
}
namespace Compiler
{
namespace Generator
{
void pushInt (CodeContainer& code, Literals& literals, int value)
{
int index = literals.addInteger (value);
opPushInt (code, index);
opFetchIntLiteral (code);
}
void assignToLocal (CodeContainer& code, char localType,
int localIndex, const CodeContainer& value, char valueType)
{
opPushInt (code, localIndex);
std::copy (value.begin(), value.end(), std::back_inserter (code));
if (localType!=valueType)
{
if (localType=='f' && valueType=='l')
{
opIntToFloat (code);
}
else if ((localType=='l' || localType=='s') && valueType=='f')
{
opFloatToInt (code);
}
}
switch (localType)
{
case 'f':
opStoreLocalFloat (code);
break;
case 's':
opStoreLocalShort (code);
break;
case 'l':
opStoreLocalLong (code);
break;
default:
assert (0);
}
}
}
}