Added bitfields
This commit is contained in:
parent
3374544ced
commit
c1ecf1c281
|
@ -1,5 +1,8 @@
|
|||
rem @echo off
|
||||
|
||||
@call :test bitfields.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test opp_string.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
#include <assert.h>
|
||||
|
||||
struct A
|
||||
{
|
||||
char x : 4;
|
||||
char y : 1;
|
||||
char z : 3;
|
||||
};
|
||||
|
||||
A a = {7, 1, 2};
|
||||
|
||||
void test_char_fit(void)
|
||||
{
|
||||
assert(a.x == 7);
|
||||
assert(a.y == 1);
|
||||
assert(a.z == 2);
|
||||
assert(sizeof(A) == 1);
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
a.x = i;
|
||||
a.y = 0;
|
||||
a.z = 3;
|
||||
assert(a.x == i);
|
||||
assert(a.y == 0);
|
||||
assert(a.z == 3);
|
||||
}
|
||||
}
|
||||
|
||||
struct B
|
||||
{
|
||||
char x : 6;
|
||||
char y : 6;
|
||||
char z : 6;
|
||||
char w : 6;
|
||||
};
|
||||
|
||||
B b = {11, 22, 33, 44};
|
||||
|
||||
void test_char_cross(void)
|
||||
{
|
||||
assert(b.x == 11);
|
||||
assert(b.y == 22);
|
||||
assert(b.z == 33);
|
||||
assert(b.w == 44);
|
||||
assert(sizeof(B) == 3);
|
||||
|
||||
for(int i=0; i<64; i++)
|
||||
{
|
||||
b.x = i * 1;
|
||||
b.y = i * 3;
|
||||
b.z = i * 5;
|
||||
b.w = i * 7;
|
||||
assert(b.x == ((i * 1) & 0x3f));
|
||||
assert(b.y == ((i * 3) & 0x3f));
|
||||
assert(b.z == ((i * 5) & 0x3f));
|
||||
assert(b.w == ((i * 7) & 0x3f));
|
||||
}
|
||||
}
|
||||
|
||||
struct C
|
||||
{
|
||||
unsigned x : 4;
|
||||
unsigned y : 1;
|
||||
unsigned z : 3;
|
||||
};
|
||||
|
||||
C c = {7, 1, 2};
|
||||
|
||||
void test_word_fit(void)
|
||||
{
|
||||
assert(c.x == 7);
|
||||
assert(c.y == 1);
|
||||
assert(c.z == 2);
|
||||
assert(sizeof(C) == 1);
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
c.x = i;
|
||||
c.y = 0;
|
||||
c.z = 3;
|
||||
assert(c.x == i);
|
||||
assert(c.y == 0);
|
||||
assert(c.z == 3);
|
||||
}
|
||||
}
|
||||
|
||||
struct D
|
||||
{
|
||||
unsigned x : 10;
|
||||
unsigned y : 10;
|
||||
unsigned z : 10;
|
||||
unsigned w : 10;
|
||||
};
|
||||
|
||||
D d = {111, 222, 333, 444};
|
||||
|
||||
void test_word_cross(void)
|
||||
{
|
||||
assert(d.x == 111);
|
||||
assert(d.y == 222);
|
||||
assert(d.z == 333);
|
||||
assert(d.w == 444);
|
||||
assert(sizeof(D) == 5);
|
||||
|
||||
for(int i=0; i<1024; i++)
|
||||
{
|
||||
d.x = i * 1;
|
||||
d.y = i * 3;
|
||||
d.z = i * 5;
|
||||
d.w = i * 7;
|
||||
assert(d.x == ((i * 1) & 0x3ff));
|
||||
assert(d.y == ((i * 3) & 0x3ff));
|
||||
assert(d.z == ((i * 5) & 0x3ff));
|
||||
assert(d.w == ((i * 7) & 0x3ff));
|
||||
}
|
||||
}
|
||||
|
||||
struct E
|
||||
{
|
||||
unsigned long x : 4;
|
||||
unsigned long y : 1;
|
||||
unsigned long z : 3;
|
||||
};
|
||||
|
||||
E e = {7, 1, 2};
|
||||
|
||||
void test_dword_fit(void)
|
||||
{
|
||||
assert(e.x == 7);
|
||||
assert(e.y == 1);
|
||||
assert(e.z == 2);
|
||||
assert(sizeof(E) == 1);
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
e.x = i;
|
||||
e.y = 0;
|
||||
e.z = 3;
|
||||
assert(e.x == i);
|
||||
assert(e.y == 0);
|
||||
assert(e.z == 3);
|
||||
}
|
||||
}
|
||||
|
||||
struct F
|
||||
{
|
||||
unsigned long x : 20;
|
||||
unsigned long y : 20;
|
||||
unsigned long z : 20;
|
||||
unsigned long w : 20;
|
||||
};
|
||||
|
||||
F f = {111111UL, 222222UL, 333333UL, 444444UL};
|
||||
|
||||
void test_dword_cross(void)
|
||||
{
|
||||
assert(f.x == 111111UL);
|
||||
assert(f.y == 222222UL);
|
||||
assert(f.z == 333333UL);
|
||||
assert(f.w == 444444UL);
|
||||
assert(sizeof(F) == 10);
|
||||
|
||||
for(int i=0; i<1024; i++)
|
||||
{
|
||||
f.x = i * 11UL;
|
||||
f.y = i * 33UL;
|
||||
f.z = i * 55UL;
|
||||
f.w = i * 77UL;
|
||||
assert(f.x == ((i * 11UL) & 0xfffffUL));
|
||||
assert(f.y == ((i * 33UL) & 0xfffffUL));
|
||||
assert(f.z == ((i * 55UL) & 0xfffffUL));
|
||||
assert(f.w == ((i * 77UL) & 0xfffffUL));
|
||||
}
|
||||
}
|
||||
|
||||
struct G
|
||||
{
|
||||
signed char x : 1;
|
||||
signed char y : 5;
|
||||
signed char z : 2;
|
||||
};
|
||||
|
||||
G g = {0, -1, -2};
|
||||
|
||||
void test_char_signed(void)
|
||||
{
|
||||
assert(g.x == 0);
|
||||
assert(g.y == -1);
|
||||
assert(g.z == -2);
|
||||
assert(sizeof(G) == 1);
|
||||
|
||||
for(int i=-16; i<16; i++)
|
||||
{
|
||||
g.x = -1;
|
||||
g.y = i;
|
||||
g.z = 1;
|
||||
assert(g.x == -1);
|
||||
assert(g.y == i);
|
||||
assert(g.z == 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct H
|
||||
{
|
||||
int x : 10;
|
||||
int y : 10;
|
||||
int z : 10;
|
||||
int w : 10;
|
||||
};
|
||||
|
||||
H h = {111, -222, -333, 444};
|
||||
|
||||
void test_word_signed(void)
|
||||
{
|
||||
assert(h.x == 111);
|
||||
assert(h.y == -222);
|
||||
assert(h.z == -333);
|
||||
assert(h.w == 444);
|
||||
assert(sizeof(H) == 5);
|
||||
|
||||
for(int i=-32; i<32; i++)
|
||||
{
|
||||
h.x = i * 1;
|
||||
h.y = i * 3;
|
||||
h.z = i * 5;
|
||||
h.w = i * 7;
|
||||
assert(h.x == i * 1);
|
||||
assert(h.y == i * 3);
|
||||
assert(h.z == i * 5);
|
||||
assert(h.w == i * 7);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_char_fit();
|
||||
test_char_cross();
|
||||
test_word_fit();
|
||||
test_word_cross();
|
||||
test_dword_fit();
|
||||
test_dword_cross();
|
||||
test_char_signed();
|
||||
test_word_signed();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -4246,8 +4246,8 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns
|
|||
case IA_SAR:
|
||||
{
|
||||
ByteCode rbc = ByteCodeBinRegOperator(ins);
|
||||
|
||||
ByteCode ibc = ByteCodeBinImmOperator(ins);
|
||||
|
||||
if (ins->mSrc[1].mTemp < 0)
|
||||
{
|
||||
IntConstToAccu(ins->mSrc[1].mIntConst);
|
||||
|
@ -4259,18 +4259,25 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns
|
|||
}
|
||||
else if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
ByteCodeInstruction lins(InterTypeSize[ins->mSrc[1].mType] == 1 ? BC_LOAD_REG_8 : BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
if (ins->mOperator == IA_SAR && InterTypeSize[ins->mSrc[1].mType] == 1)
|
||||
{
|
||||
ByteCodeInstruction xins(BC_CONV_I8_I16);
|
||||
xins.mRegister = BC_REG_ACCU;
|
||||
mIns.Push(xins);
|
||||
}
|
||||
|
||||
ByteCodeInstruction bins(ibc);
|
||||
bins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(bins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
ByteCodeInstruction lins(InterTypeSize[ins->mSrc[1].mType] == 1 ? BC_LOAD_REG_8 : BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal && (ins->mSrc[1].mTemp != ins->mSrc[0].mTemp);;
|
||||
mIns.Push(lins);
|
||||
|
|
|
@ -1236,7 +1236,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
return true;
|
||||
}
|
||||
|
||||
int Compiler::ExecuteCode(bool profile, bool trace)
|
||||
int Compiler::ExecuteCode(bool profile, int trace)
|
||||
{
|
||||
Location loc;
|
||||
|
||||
|
@ -1249,12 +1249,12 @@ int Compiler::ExecuteCode(bool profile, bool trace)
|
|||
memcpy(emu->mMemory + mLinker->mProgramStart, mLinker->mMemory + mLinker->mProgramStart, mLinker->mProgramEnd - mLinker->mProgramStart);
|
||||
emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff;
|
||||
emu->mMemory[0x2e] = mLinker->mProgramEnd >> 8;
|
||||
ecode = emu->Emulate(2061, trace ? 2 : 0);
|
||||
ecode = emu->Emulate(2061, trace);
|
||||
}
|
||||
else if (mCompilerOptions & COPT_TARGET_CRT)
|
||||
{
|
||||
memcpy(emu->mMemory + 0x8000, mLinker->mMemory + 0x0800, 0x4000);
|
||||
ecode = emu->Emulate(0x8009, trace ? 2 : 0);
|
||||
ecode = emu->Emulate(0x8009, trace);
|
||||
}
|
||||
|
||||
printf("Emulation result %d\n", ecode);
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
bool ParseSource(void);
|
||||
bool GenerateCode(void);
|
||||
bool WriteOutputFile(const char* targetPath, DiskImage * d64);
|
||||
int ExecuteCode(bool profile, bool trace);
|
||||
int ExecuteCode(bool profile, int trace);
|
||||
|
||||
void AddDefine(const Ident* ident, const char* value);
|
||||
|
||||
|
|
|
@ -819,6 +819,8 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
dec->mBase = mLeft->mDecValue;
|
||||
dec->mOffset = mDecValue->mOffset;
|
||||
dec->mSize = mDecValue->mSize;
|
||||
dec->mBits = mDecValue->mBits;
|
||||
dec->mShift = mDecValue->mShift;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = mDecType;
|
||||
return ex;
|
||||
|
@ -831,6 +833,8 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
dec->mBase = mLeft->mDecValue->mBase;
|
||||
dec->mOffset = mLeft->mDecValue->mOffset + mDecValue->mOffset;
|
||||
dec->mSize = mDecValue->mSize;
|
||||
dec->mBits = mDecValue->mBits;
|
||||
dec->mShift = mDecValue->mShift;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = mDecType;
|
||||
return ex;
|
||||
|
@ -887,7 +891,8 @@ Declaration::Declaration(const Location& loc, DecType type)
|
|||
mVTable(nullptr), mTemplate(nullptr),
|
||||
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mFriends(nullptr),
|
||||
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
||||
mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr)
|
||||
mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr),
|
||||
mShift(0), mBits(0)
|
||||
{}
|
||||
|
||||
Declaration::~Declaration(void)
|
||||
|
|
|
@ -29,9 +29,6 @@ enum DecType
|
|||
DT_TYPE_ASSEMBLER,
|
||||
DT_TYPE_AUTO,
|
||||
|
||||
DT_TYPE_CONST,
|
||||
DT_TYPE_VOLATILE,
|
||||
|
||||
DT_CONST_INTEGER,
|
||||
DT_CONST_FLOAT,
|
||||
DT_CONST_FUNCTION,
|
||||
|
@ -264,6 +261,7 @@ public:
|
|||
Expression* mValue;
|
||||
DeclarationScope* mScope;
|
||||
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe;
|
||||
uint8 mShift, mBits;
|
||||
int64 mInteger, mMinValue, mMaxValue;
|
||||
double mNumber;
|
||||
uint64 mFlags, mCompilerOptions;
|
||||
|
|
|
@ -649,7 +649,7 @@ int Emulator::Emulate(int startIP, int trace)
|
|||
break;
|
||||
}
|
||||
|
||||
if ((trace & 1) && ip == 0x0855)
|
||||
if ((trace & 1) && ip == 0x0862)
|
||||
{
|
||||
unsigned accu = mMemory[BC_REG_ACCU] + (mMemory[BC_REG_ACCU + 1] << 8) + (mMemory[BC_REG_ACCU + 2] << 16) + (mMemory[BC_REG_ACCU + 3] << 24);
|
||||
int ptr = mMemory[BC_REG_ADDR] + 256 * mMemory[BC_REG_ADDR + 1];
|
||||
|
|
|
@ -83,6 +83,7 @@ enum ErrorID
|
|||
EERR_NON_STATIC_MEMBER,
|
||||
EERR_TEMPLATE_PARAMS,
|
||||
EERR_FUNCTION_TEMPLATE,
|
||||
EERR_INVALID_BITFIELD,
|
||||
|
||||
EERR_INVALID_CONSTEXPR,
|
||||
EERR_DOUBLE_FREE,
|
||||
|
|
|
@ -643,6 +643,16 @@ static bool SameMem(const InterOperand& op, const InterInstruction* ins)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool SameMemAndSize(const InterOperand& op, const InterInstruction* ins)
|
||||
{
|
||||
if (ins->mCode == IC_LOAD)
|
||||
return SameMemAndSize(op, ins->mSrc[0]);
|
||||
else if (ins->mCode == IC_STORE)
|
||||
return SameMemAndSize(op, ins->mSrc[1]);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool SameInstruction(const InterInstruction* ins1, const InterInstruction* ins2)
|
||||
{
|
||||
if (ins1->mCode == ins2->mCode && ins1->mNumOperands == ins2->mNumOperands)
|
||||
|
@ -7252,11 +7262,36 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
case IA_SHL:
|
||||
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[1].mTemp >= 0)
|
||||
{
|
||||
if (vr.mMinState == IntegerValueRange::S_BOUND)
|
||||
ins->mSrc[1].mRange.LimitMin(vr.mMinValue >> ins->mSrc[0].mIntConst);
|
||||
if (vr.mMaxState == IntegerValueRange::S_BOUND)
|
||||
ins->mSrc[1].mRange.LimitMax(vr.mMaxValue >> ins->mSrc[0].mIntConst);
|
||||
mReverseValueRange[ins->mSrc[1].mTemp].Limit(ins->mSrc[1].mRange);
|
||||
if (ins->mDst.mType == IT_INT16)
|
||||
{
|
||||
if (vr.mMinState == IntegerValueRange::S_BOUND && vr.mMinValue >= -0x4000 &&
|
||||
vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMaxValue < 0x4000)
|
||||
{
|
||||
ins->mSrc[1].mRange.LimitMin(vr.mMinValue >> ins->mSrc[0].mIntConst);
|
||||
ins->mSrc[1].mRange.LimitMax(vr.mMaxValue >> ins->mSrc[0].mIntConst);
|
||||
mReverseValueRange[ins->mSrc[1].mTemp].Limit(ins->mSrc[1].mRange);
|
||||
}
|
||||
}
|
||||
else if (ins->mDst.mType == IT_INT8)
|
||||
{
|
||||
if (vr.mMinState == IntegerValueRange::S_BOUND && vr.mMinValue >= -0x40 &&
|
||||
vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMaxValue < 0x40)
|
||||
{
|
||||
ins->mSrc[1].mRange.LimitMin(vr.mMinValue >> ins->mSrc[0].mIntConst);
|
||||
ins->mSrc[1].mRange.LimitMax(vr.mMaxValue >> ins->mSrc[0].mIntConst);
|
||||
mReverseValueRange[ins->mSrc[1].mTemp].Limit(ins->mSrc[1].mRange);
|
||||
}
|
||||
}
|
||||
else if (ins->mDst.mType == IT_INT32)
|
||||
{
|
||||
if (vr.mMinState == IntegerValueRange::S_BOUND && vr.mMinValue >= -0x40000000 &&
|
||||
vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMaxValue < 0x40000000)
|
||||
{
|
||||
ins->mSrc[1].mRange.LimitMin(vr.mMinValue >> ins->mSrc[0].mIntConst);
|
||||
ins->mSrc[1].mRange.LimitMax(vr.mMaxValue >> ins->mSrc[0].mIntConst);
|
||||
mReverseValueRange[ins->mSrc[1].mTemp].Limit(ins->mSrc[1].mRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IA_SUB:
|
||||
|
@ -8559,6 +8594,72 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr
|
|||
|
||||
}
|
||||
|
||||
bool InterCodeBasicBlock::RemoveUnusedIndirectStoreInstructions(void)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
ExpandingArray<InterInstructionPtr> stores;
|
||||
|
||||
for (int i = mInstructions.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
InterInstruction* ins = mInstructions[i];
|
||||
|
||||
if (ins->mCode == IC_STORE)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < stores.Size() && !SameMemAndSize(ins->mSrc[1], stores[j]->mSrc[1]))
|
||||
j++;
|
||||
|
||||
if (j < stores.Size())
|
||||
{
|
||||
if (ins->mVolatile)
|
||||
stores[j] = ins;
|
||||
else
|
||||
{
|
||||
ins->mCode = IC_NONE;
|
||||
ins->mNumOperands = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
j = 0;
|
||||
while (j < stores.Size())
|
||||
{
|
||||
if (CollidingMem(ins, stores[j]))
|
||||
stores.Remove(j);
|
||||
else
|
||||
j++;
|
||||
}
|
||||
stores.Push(ins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int j = 0;
|
||||
while (j < stores.Size())
|
||||
{
|
||||
if (CollidingMem(ins, stores[j]) || ins->mDst.mTemp >= 0 && ins->mDst.mTemp == stores[j]->mSrc[1].mTemp)
|
||||
stores.Remove(j);
|
||||
else
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->RemoveUnusedIndirectStoreInstructions())
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->RemoveUnusedIndirectStoreInstructions())
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
bool InterCodeBasicBlock::EliminateAliasValues(const GrowingInstructionPtrArray& tvalue, const GrowingInstructionPtrArray& avalue)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -9867,7 +9968,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
if (ins->mCode == IC_LOAD)
|
||||
{
|
||||
j = 0;
|
||||
while (j < tvalue.Size() && !SameMem(ins->mSrc[0], tvalue[j]))
|
||||
while (j < tvalue.Size() && !SameMemAndSize(ins->mSrc[0], tvalue[j]))
|
||||
j++;
|
||||
if (j < tvalue.Size())
|
||||
{
|
||||
|
@ -9880,7 +9981,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
else if (ins->mCode == IC_STORE)
|
||||
{
|
||||
j = 0;
|
||||
while (j < tvalue.Size() && !SameMem(ins->mSrc[1], tvalue[j]))
|
||||
while (j < tvalue.Size() && !SameMemAndSize(ins->mSrc[1], tvalue[j]))
|
||||
j++;
|
||||
if (j < tvalue.Size())
|
||||
{
|
||||
|
@ -9945,7 +10046,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
if (!ins->mVolatile)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < mLoadStoreInstructions.Size() && !SameMem(ins->mSrc[0], mLoadStoreInstructions[j]))
|
||||
while (j < mLoadStoreInstructions.Size() && !SameMemAndSize(ins->mSrc[0], mLoadStoreInstructions[j]))
|
||||
j++;
|
||||
if (j < mLoadStoreInstructions.Size())
|
||||
{
|
||||
|
@ -9986,7 +10087,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
{
|
||||
int j = 0, k = 0;
|
||||
|
||||
while (j < mLoadStoreInstructions.Size() && !SameMem(ins->mSrc[1], mLoadStoreInstructions[j]))
|
||||
while (j < mLoadStoreInstructions.Size() && !SameMemAndSize(ins->mSrc[1], mLoadStoreInstructions[j]))
|
||||
j++;
|
||||
|
||||
if (!ins->mVolatile && j < mLoadStoreInstructions.Size() && mLoadStoreInstructions[j]->mCode == IC_LOAD && ins->mSrc[0].mTemp == mLoadStoreInstructions[j]->mDst.mTemp)
|
||||
|
@ -14541,7 +14642,6 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
|
|||
int64 mshift = mInstructions[i + 1]->mSrc[0].mIntConst;
|
||||
|
||||
mInstructions[i + 0]->mOperator = IA_AND;
|
||||
mInstructions[i + 0]->mSrc[0].mType = IT_INT16;
|
||||
mInstructions[i + 0]->mSrc[0].mType = mInstructions[i + 1]->mSrc[0].mType;
|
||||
|
||||
switch (mInstructions[i + 0]->mSrc[1].mType)
|
||||
|
@ -14584,6 +14684,61 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
else if (
|
||||
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SHL && mInstructions[i + 0]->mSrc[0].mTemp < 0 &&
|
||||
mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 1]->mOperator == IA_SHR && mInstructions[i + 1]->mSrc[0].mTemp < 0 &&
|
||||
mInstructions[i + 1]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[1].mFinal)
|
||||
{
|
||||
|
||||
int64 shift = mInstructions[i + 0]->mSrc[0].mIntConst;
|
||||
if (shift & 7)
|
||||
{
|
||||
int64 mshift = mInstructions[i + 1]->mSrc[0].mIntConst;
|
||||
|
||||
mInstructions[i + 0]->mOperator = IA_AND;
|
||||
mInstructions[i + 0]->mSrc[0].mType = mInstructions[i + 1]->mSrc[0].mType;
|
||||
|
||||
switch (mInstructions[i + 0]->mSrc[1].mType)
|
||||
{
|
||||
case IT_INT8:
|
||||
mInstructions[i + 0]->mSrc[0].mIntConst = 0xffu >> shift;
|
||||
break;
|
||||
case IT_INT16:
|
||||
mInstructions[i + 0]->mSrc[0].mIntConst = 0xffffu >> shift;
|
||||
break;
|
||||
case IT_INT32:
|
||||
mInstructions[i + 0]->mSrc[0].mIntConst = 0xffffffffu >> shift;
|
||||
break;
|
||||
}
|
||||
|
||||
if (shift > mshift && mInstructions[i + 0]->mDst.mType > mInstructions[i + 1]->mSrc[1].mType)
|
||||
{
|
||||
mInstructions[i + 1]->mSrc[1].mType = mInstructions[i + 0]->mDst.mType;
|
||||
mInstructions[i + 1]->mDst.mType = mInstructions[i + 0]->mDst.mType;
|
||||
}
|
||||
|
||||
if (shift > mshift)
|
||||
{
|
||||
mInstructions[i + 1]->mOperator = IA_SHL;
|
||||
mInstructions[i + 1]->mSrc[0].mIntConst = shift - mshift;
|
||||
}
|
||||
else if (shift < mshift)
|
||||
{
|
||||
mInstructions[i + 1]->mOperator = IA_SHR;
|
||||
mInstructions[i + 1]->mSrc[0].mIntConst = mshift - shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
mInstructions[i + 0]->mDst = mInstructions[i + 1]->mDst;
|
||||
mInstructions[i + 1]->mCode = IC_NONE;
|
||||
mInstructions[i + 1]->mNumOperands = 0;
|
||||
}
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
else if (
|
||||
mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY &&
|
||||
|
@ -16507,6 +16662,11 @@ void InterCodeProcedure::RemoveUnusedStoreInstructions(InterMemory paramMemory)
|
|||
|
||||
DisassembleDebug("removed unused static stores");
|
||||
}
|
||||
|
||||
// Remove unused indirect stores
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->RemoveUnusedIndirectStoreInstructions();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16921,7 +17081,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||
CheckFunc = !strcmp(mIdent->mString, "test");
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
||||
|
|
|
@ -428,6 +428,7 @@ public:
|
|||
void BuildGlobalProvidedVariableSet(const GrowingVariableArray& localVars, NumberSet fromProvidedVars, const GrowingVariableArray& params, NumberSet fromProvidedParams, InterMemory paramMemory);
|
||||
bool BuildGlobalRequiredVariableSet(const GrowingVariableArray& localVars, NumberSet& fromRequiredVars, const GrowingVariableArray& params, NumberSet& fromRequiredParams, InterMemory paramMemory);
|
||||
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory);
|
||||
bool RemoveUnusedIndirectStoreInstructions(void);
|
||||
|
||||
void BuildStaticVariableSet(const GrowingVariableArray& staticVars);
|
||||
void BuildGlobalProvidedStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet fromProvidedVars);
|
||||
|
|
|
@ -68,16 +68,220 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
|
|||
ins->mDst.mRange.LimitMin(v.mType->mMinValue);
|
||||
ins->mDst.mRange.LimitMax(v.mType->mMaxValue);
|
||||
}
|
||||
|
||||
if (v.mType->mFlags & DTF_VOLATILE)
|
||||
ins->mVolatile = true;
|
||||
block->Append(ins);
|
||||
|
||||
v = ExValue(v.mType, ins->mDst.mTemp, v.mReference - 1);
|
||||
if (v.mReference == 1 && v.mBits)
|
||||
{
|
||||
if (v.mBits + v.mShift <= 8)
|
||||
ins->mDst.mType = IT_INT8;
|
||||
else if (v.mBits + v.mShift <= 16)
|
||||
ins->mDst.mType = IT_INT16;
|
||||
else
|
||||
ins->mDst.mType = IT_INT32;
|
||||
|
||||
ins->mSrc[0].mOperandSize = InterTypeSize[ins->mDst.mType];
|
||||
int nbits = ins->mSrc[0].mOperandSize * 8;
|
||||
|
||||
InterInstruction* clsins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
clsins->mDst.mType = IT_INT8;
|
||||
clsins->mDst.mTemp = proc->AddTemporary(clsins->mDst.mType);
|
||||
clsins->mConst.mType = IT_INT8;
|
||||
clsins->mConst.mIntConst = nbits - v.mShift - v.mBits;
|
||||
clsins->mNumOperands = 0;
|
||||
block->Append(clsins);
|
||||
|
||||
InterInstruction* crsins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
crsins->mDst.mType = IT_INT8;
|
||||
crsins->mDst.mTemp = proc->AddTemporary(crsins->mDst.mType);
|
||||
crsins->mConst.mType = IT_INT8;
|
||||
crsins->mConst.mIntConst = nbits - v.mBits;
|
||||
crsins->mNumOperands = 0;
|
||||
block->Append(crsins);
|
||||
|
||||
InterInstruction* slins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);
|
||||
slins->mOperator = IA_SHL;
|
||||
slins->mDst.mType = ins->mDst.mType;
|
||||
slins->mDst.mTemp = proc->AddTemporary(slins->mDst.mType);
|
||||
slins->mSrc[1] = ins->mDst;
|
||||
slins->mSrc[0] = clsins->mDst;
|
||||
slins->mNumOperands = 2;
|
||||
block->Append(slins);
|
||||
|
||||
InterInstruction* srins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);
|
||||
srins->mOperator = (v.mType->mFlags & DTF_SIGNED) ? IA_SAR : IA_SHR;
|
||||
srins->mDst.mType = ins->mDst.mType;
|
||||
srins->mDst.mTemp = proc->AddTemporary(slins->mDst.mType);
|
||||
srins->mSrc[1] = slins->mDst;
|
||||
srins->mSrc[0] = crsins->mDst;
|
||||
srins->mNumOperands = 2;
|
||||
block->Append(srins);
|
||||
|
||||
if (InterTypeSize[ins->mDst.mType] < v.mType->mSize)
|
||||
{
|
||||
InterInstruction* crins = new InterInstruction(exp->mLocation, IC_CONVERSION_OPERATOR);
|
||||
crins->mDst.mType = InterTypeOf(v.mType);
|
||||
crins->mDst.mTemp = proc->AddTemporary(crins->mDst.mType);
|
||||
crins->mSrc[0] = srins->mDst;
|
||||
crins->mNumOperands = 1;
|
||||
if (ins->mDst.mType == IT_INT16)
|
||||
crins->mOperator = (v.mType->mFlags & DTF_SIGNED) ? IA_EXT16TO32S : IA_EXT16TO32U;
|
||||
else if (v.mType->mSize == 2)
|
||||
crins->mOperator = (v.mType->mFlags & DTF_SIGNED) ? IA_EXT8TO16S : IA_EXT8TO16U;
|
||||
else
|
||||
crins->mOperator = (v.mType->mFlags & DTF_SIGNED) ? IA_EXT8TO32S : IA_EXT8TO32U;
|
||||
block->Append(crins);
|
||||
v = ExValue(v.mType, crins->mDst.mTemp, v.mReference - 1);
|
||||
}
|
||||
else
|
||||
v = ExValue(v.mType, srins->mDst.mTemp, v.mReference - 1);
|
||||
}
|
||||
else
|
||||
v = ExValue(v.mType, ins->mDst.mTemp, v.mReference - 1, v.mBits, v.mShift);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void InterCodeGenerator::StoreValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr)
|
||||
{
|
||||
// Bitfield assignment
|
||||
if (vl.mBits)
|
||||
{
|
||||
InterType itype;
|
||||
|
||||
if (vl.mBits + vl.mShift <= 8)
|
||||
itype = IT_INT8;
|
||||
else if (vl.mBits + vl.mShift <= 16)
|
||||
itype = IT_INT16;
|
||||
else
|
||||
itype = IT_INT32;
|
||||
|
||||
int nbits = InterTypeSize[itype] * 8;
|
||||
|
||||
InterInstruction* lins = new InterInstruction(exp->mLocation, IC_LOAD);
|
||||
lins->mDst.mType = itype;
|
||||
lins->mDst.mTemp = proc->AddTemporary(lins->mDst.mType);
|
||||
lins->mSrc[0].mMemory = IM_INDIRECT;
|
||||
lins->mSrc[0].mType = IT_POINTER;
|
||||
lins->mSrc[0].mTemp = vl.mTemp;
|
||||
lins->mSrc[0].mOperandSize = InterTypeSize[itype];
|
||||
lins->mVolatile = vl.mType->mFlags & DTF_VOLATILE;
|
||||
lins->mNumOperands = 1;
|
||||
block->Append(lins);
|
||||
|
||||
InterInstruction* csins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
csins->mDst.mType = IT_INT8;
|
||||
csins->mDst.mTemp = proc->AddTemporary(csins->mDst.mType);
|
||||
csins->mConst.mType = IT_INT8;
|
||||
csins->mConst.mIntConst = vl.mShift;
|
||||
csins->mNumOperands = 0;
|
||||
block->Append(csins);
|
||||
|
||||
InterInstruction* cmsins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
cmsins->mDst.mType = itype;
|
||||
cmsins->mDst.mTemp = proc->AddTemporary(cmsins->mDst.mType);
|
||||
cmsins->mConst.mType = itype;
|
||||
cmsins->mConst.mIntConst = ((1 << vl.mBits) - 1) << vl.mShift;
|
||||
cmsins->mNumOperands = 0;
|
||||
block->Append(cmsins);
|
||||
|
||||
InterInstruction* cmlins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
cmlins->mDst.mType = itype;
|
||||
cmlins->mDst.mTemp = proc->AddTemporary(cmlins->mDst.mType);
|
||||
cmlins->mConst.mType = itype;
|
||||
cmlins->mConst.mIntConst = ~cmsins->mConst.mIntConst;
|
||||
cmlins->mNumOperands = 0;
|
||||
block->Append(cmlins);
|
||||
|
||||
int rtemp = vr.mTemp;
|
||||
|
||||
if (InterTypeSize[itype] > vr.mType->mSize)
|
||||
{
|
||||
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_CONVERSION_OPERATOR);
|
||||
|
||||
if (InterTypeSize[itype] == 2)
|
||||
cins->mOperator = IA_EXT8TO16U;
|
||||
else if (vr.mType->mSize == 1)
|
||||
cins->mOperator = IA_EXT8TO32U;
|
||||
else
|
||||
cins->mOperator = IA_EXT8TO16U;
|
||||
|
||||
cins->mDst.mType = itype;
|
||||
cins->mDst.mTemp = proc->AddTemporary(itype);
|
||||
cins->mSrc[0].mTemp = rtemp;
|
||||
cins->mSrc[0].mType = InterTypeOf(vr.mType);
|
||||
block->Append(cins);
|
||||
|
||||
rtemp = cins->mDst.mTemp;
|
||||
}
|
||||
|
||||
InterInstruction* sins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);
|
||||
sins->mOperator = IA_SHL;
|
||||
sins->mDst.mType = itype;
|
||||
sins->mDst.mTemp = proc->AddTemporary(sins->mDst.mType);
|
||||
sins->mSrc[1].mTemp = rtemp;
|
||||
sins->mSrc[1].mType = itype;
|
||||
sins->mSrc[0] = csins->mDst;
|
||||
sins->mNumOperands = 2;
|
||||
block->Append(sins);
|
||||
|
||||
InterInstruction* msins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);
|
||||
msins->mOperator = IA_AND;
|
||||
msins->mDst.mType = itype;
|
||||
msins->mDst.mTemp = proc->AddTemporary(msins->mDst.mType);
|
||||
msins->mSrc[0] = sins->mDst;
|
||||
msins->mSrc[1] = cmsins->mDst;
|
||||
msins->mNumOperands = 2;
|
||||
block->Append(msins);
|
||||
|
||||
InterInstruction* mlins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);
|
||||
mlins->mOperator = IA_AND;
|
||||
mlins->mDst.mType = itype;
|
||||
mlins->mDst.mTemp = proc->AddTemporary(mlins->mDst.mType);
|
||||
mlins->mSrc[0] = lins->mDst;
|
||||
mlins->mSrc[1] = cmlins->mDst;
|
||||
mlins->mNumOperands = 2;
|
||||
block->Append(mlins);
|
||||
|
||||
InterInstruction* oins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);
|
||||
oins->mOperator = IA_OR;
|
||||
oins->mDst.mType = itype;
|
||||
oins->mDst.mTemp = proc->AddTemporary(oins->mDst.mType);
|
||||
oins->mSrc[0] = msins->mDst;
|
||||
oins->mSrc[1] = mlins->mDst;
|
||||
oins->mNumOperands = 2;
|
||||
block->Append(oins);
|
||||
|
||||
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
ins->mSrc[0] = oins->mDst;
|
||||
ins->mSrc[1].mType = IT_POINTER;
|
||||
ins->mSrc[1].mTemp = vl.mTemp;
|
||||
ins->mSrc[1].mOperandSize = InterTypeSize[itype];
|
||||
ins->mVolatile = vl.mType->mFlags & DTF_VOLATILE;
|
||||
ins->mNumOperands = 2;
|
||||
block->Append(ins);
|
||||
}
|
||||
else
|
||||
{
|
||||
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||
|
||||
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
ins->mSrc[0].mType = InterTypeOf(vr.mType);
|
||||
ins->mSrc[0].mTemp = vr.mTemp;
|
||||
ins->mSrc[1].mType = IT_POINTER;
|
||||
ins->mSrc[1].mTemp = vl.mTemp;
|
||||
ins->mSrc[1].mOperandSize = vl.mType->mSize;
|
||||
ins->mSrc[1].mStride = vl.mType->mStripe;
|
||||
ins->mVolatile = vl.mType->mFlags & DTF_VOLATILE;
|
||||
ins->mNumOperands = 2;
|
||||
block->Append(ins);
|
||||
}
|
||||
}
|
||||
|
||||
InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration* type, bool checkTrunc)
|
||||
{
|
||||
int stemp = v.mTemp;
|
||||
|
@ -1713,6 +1917,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mConst.mOperandSize = dec->mSize;
|
||||
ins->mConst.mIntConst = dec->mOffset;
|
||||
|
||||
int lbits = dec->mBits, lshift = dec->mShift;
|
||||
|
||||
if (dec->mType == DT_VARIABLE_REF)
|
||||
dec = dec->mBase;
|
||||
|
||||
|
@ -1779,13 +1985,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (exp->mDecType->IsReference())
|
||||
return ExValue(exp->mDecType->mBase, ins->mDst.mTemp, ref + 1);
|
||||
else
|
||||
return ExValue(exp->mDecType, ins->mDst.mTemp, ref);
|
||||
return ExValue(exp->mDecType, ins->mDst.mTemp, ref, lbits, lshift);
|
||||
}
|
||||
|
||||
|
||||
case EX_ASSIGNMENT:
|
||||
case EX_INITIALIZATION:
|
||||
{
|
||||
{
|
||||
if (exp->mLeft->mDecType && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||
|
@ -1902,8 +2108,6 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (vl.mReference != 1)
|
||||
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not a left hand expression");
|
||||
|
||||
InterInstruction * ins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||
|
||||
if (exp->mToken != TK_ASSIGN)
|
||||
{
|
||||
ExValue vll = Dereference(proc, exp, block, vl);
|
||||
|
@ -2043,17 +2247,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
vr = CoerceType(proc, exp, block, vr, vl.mType);
|
||||
}
|
||||
|
||||
ins->mCode = IC_STORE;
|
||||
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
ins->mSrc[0].mType = InterTypeOf(vr.mType);
|
||||
ins->mSrc[0].mTemp = vr.mTemp;
|
||||
ins->mSrc[1].mType = IT_POINTER;
|
||||
ins->mSrc[1].mTemp = vl.mTemp;
|
||||
ins->mSrc[1].mOperandSize = vl.mType->mSize;
|
||||
ins->mSrc[1].mStride = vl.mType->mStripe;
|
||||
ins->mVolatile = vl.mType->mFlags & DTF_VOLATILE;
|
||||
ins->mNumOperands = 2;
|
||||
block->Append(ins);
|
||||
StoreValue(proc, exp, block, vl, vr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2151,7 +2345,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
||||
block->Append(ains);
|
||||
|
||||
return ExValue(exp->mDecValue->mBase, ains->mDst.mTemp, 1);
|
||||
return ExValue(exp->mDecValue->mBase, ains->mDst.mTemp, 1, exp->mDecValue->mBits, exp->mDecValue->mShift);
|
||||
}
|
||||
|
||||
case EX_BINARY:
|
||||
|
@ -2483,7 +2677,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (vl.mType->mFlags & DTF_CONST)
|
||||
mErrors->Error(exp->mLocation, EERR_CONST_ASSIGN, "Cannot change const value");
|
||||
|
||||
InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CONSTANT), * ains = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR), * sins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_CONSTANT), * ains = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);// , * sins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||
|
||||
ExValue vdl = Dereference(proc, exp, block, vl);
|
||||
|
||||
|
@ -2524,6 +2718,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
||||
block->Append(ains);
|
||||
|
||||
StoreValue(proc, exp, block, vl, ExValue(vl.mType, ains->mDst.mTemp));
|
||||
#if 0
|
||||
sins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
sins->mSrc[0].mType = ains->mDst.mType;
|
||||
sins->mSrc[0].mTemp = ains->mDst.mTemp;
|
||||
|
@ -2532,6 +2728,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
sins->mSrc[1].mOperandSize = vl.mType->mSize;
|
||||
sins->mVolatile = vl.mType->mFlags & DTF_VOLATILE;
|
||||
block->Append(sins);
|
||||
#endif
|
||||
|
||||
// Return reference to value
|
||||
return ExValue(vl.mType, vl.mTemp, 1);
|
||||
|
@ -2550,7 +2747,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (vl.mType->mFlags & DTF_CONST)
|
||||
mErrors->Error(exp->mLocation, EERR_CONST_ASSIGN, "Cannot change const value");
|
||||
|
||||
InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CONSTANT), * ains = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR), * sins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_CONSTANT), * ains = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);// , * sins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||
|
||||
ExValue vdl = Dereference(proc, exp, block, vl);
|
||||
|
||||
|
@ -2590,6 +2787,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ains->mDst.mTemp = proc->AddTemporary(ttype);
|
||||
block->Append(ains);
|
||||
|
||||
StoreValue(proc, exp, block, vl, ExValue(vl.mType, ains->mDst.mTemp));
|
||||
#if 0
|
||||
sins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
sins->mSrc[0].mType = ains->mDst.mType;
|
||||
sins->mSrc[0].mTemp = ains->mDst.mTemp;
|
||||
|
@ -2598,7 +2797,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
sins->mSrc[1].mOperandSize = vl.mType->mSize;
|
||||
sins->mVolatile = vl.mType->mFlags & DTF_VOLATILE;
|
||||
block->Append(sins);
|
||||
|
||||
#endif
|
||||
return ExValue(vdl.mType, vdl.mTemp);
|
||||
}
|
||||
break;
|
||||
|
@ -2642,7 +2841,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
return ExValue(vl.mType->mBase, vl.mTemp, vl.mReference + 1);
|
||||
case TK_BINARY_AND:
|
||||
{
|
||||
if (vl.mReference < 1)
|
||||
if (vl.mReference < 1 || vl.mBits)
|
||||
mErrors->Error(exp->mLocation, EERR_NOT_AN_LVALUE, "Not an addressable value");
|
||||
|
||||
Declaration* dec = new Declaration(exp->mLocation, DT_TYPE_POINTER);
|
||||
|
@ -4582,10 +4781,38 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
|
|||
else if (data->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
int64 t = data->mInteger;
|
||||
for (int i = 0; i < data->mBase->mSize; i++)
|
||||
if (data->mBits)
|
||||
{
|
||||
dp[offset + i * data->mBase->mStripe] = uint8(t & 0xff);
|
||||
t >>= 8;
|
||||
if (data->mBits + data->mShift <= 8)
|
||||
{
|
||||
uint8 mask = uint8(((1 << data->mBits) - 1) << data->mShift);
|
||||
dp[offset] = (dp[offset] & ~mask) | (uint8(t << data->mShift) & mask);
|
||||
}
|
||||
else if (data->mBits + data->mShift <= 16)
|
||||
{
|
||||
uint16 mask = uint16(((1 << data->mBits) - 1) << data->mShift);
|
||||
|
||||
dp[offset + 0] = (dp[offset + 0] & ~(mask & 0xff)) | (uint8(t << data->mShift) & (mask & 0xff));
|
||||
dp[offset + 1] = (dp[offset + 1] & ~(mask >> 8)) | (uint8(t >> (8 - data->mShift)) & (mask >> 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 mask = uint32(((1 << data->mBits) - 1) << data->mShift);
|
||||
t = (t << data->mShift) & mask;
|
||||
|
||||
dp[offset + 0] = (dp[offset + 0] & ~(mask & 0xff)) | (uint8(t ));
|
||||
dp[offset + 1] = (dp[offset + 1] & ~(mask >> 8)) | (uint8(t >> 8));
|
||||
dp[offset + 2] = (dp[offset + 2] & ~(mask >> 16)) | (uint8(t >> 16));
|
||||
dp[offset + 3] = (dp[offset + 3] & ~(mask >> 24)) | (uint8(t >> 24));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < data->mBase->mSize; i++)
|
||||
{
|
||||
dp[offset + i * data->mBase->mStripe] = uint8(t & 0xff);
|
||||
t >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data->mType == DT_CONST_ADDRESS)
|
||||
|
|
|
@ -21,9 +21,10 @@ public:
|
|||
{
|
||||
Declaration* mType;
|
||||
int mTemp, mReference;
|
||||
int mBits, mShift;
|
||||
|
||||
ExValue(Declaration* type = nullptr, int temp = -1, int reference = 0)
|
||||
: mType(type), mTemp(temp), mReference(reference)
|
||||
ExValue(Declaration* type = nullptr, int temp = -1, int reference = 0, int bits = 0, int shift = 0)
|
||||
: mType(type), mTemp(temp), mReference(reference), mBits(bits), mShift(shift)
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -86,6 +87,7 @@ protected:
|
|||
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, InlineMapper* inlineMapper);
|
||||
ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr, ExValue* lrexp);
|
||||
void CopyStruct(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper, bool moving);
|
||||
void StoreValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr);
|
||||
|
||||
void UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack * bottom, InlineMapper* inlineMapper);
|
||||
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable);
|
||||
|
|
|
@ -9788,7 +9788,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
|
||||
int shift = ins->mSrc[0].mIntConst & 15;
|
||||
if (ins->mDst.IsUByte())
|
||||
if (ins->mDst.IsUByte() || InterTypeSize[ins->mDst.mType] == 1)
|
||||
{
|
||||
if (shift == 0)
|
||||
{
|
||||
|
@ -9834,8 +9834,11 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||
}
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10045,7 +10048,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
{
|
||||
int shift = ins->mSrc[0].mIntConst & 15;
|
||||
#if 1
|
||||
if (ins->mSrc[1].IsUByte())
|
||||
if (ins->mSrc[1].IsUByte() || InterTypeSize[ins->mSrc[1].mType] == 1)
|
||||
{
|
||||
if (shift == 0)
|
||||
{
|
||||
|
@ -10053,8 +10056,11 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (shift == 7)
|
||||
|
@ -10062,7 +10068,8 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ASL, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROL, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||
}
|
||||
|
@ -10074,14 +10081,18 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROL, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_AND, ASMIM_IMMEDIATE, 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
}
|
||||
else if (shift >= 8)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10089,8 +10100,11 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
for (int i = 0; i < shift; i++)
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LSR, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
if (InterTypeSize[ins->mDst.mType] > 1)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -10377,6 +10391,33 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
}
|
||||
else if (InterTypeSize[ins->mDst.mType] == 1)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||
|
||||
if (shift > 5)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ASL, ASMIM_IMPLIED));
|
||||
for (int i = shift; i < 8; i++)
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROL, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_AND, ASMIM_IMMEDIATE, 0xff >> shift));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_EOR, ASMIM_IMMEDIATE, 0x80 >> shift));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_SEC, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_SBC, ASMIM_IMMEDIATE, 0x80 >> shift));
|
||||
}
|
||||
else if (shift > 0)
|
||||
{
|
||||
for (int i = 0; i < shift; i++)
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LSR, ASMIM_IMPLIED));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_EOR, ASMIM_IMMEDIATE, 0x80 >> shift));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_SEC, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_SBC, ASMIM_IMMEDIATE, 0x80 >> shift));
|
||||
}
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||
}
|
||||
else if (ins->mSrc[1].IsSByte() && shift != 0 && shift < 5)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
|
||||
|
@ -18939,6 +18980,148 @@ bool NativeCodeBasicBlock::ShortcutPointerAddForward(void)
|
|||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::MoveIndirectLoadZeroStoreDown(int at)
|
||||
{
|
||||
int yval = mIns[at].mAddress;
|
||||
|
||||
for (int i = at + 3; i < mIns.Size(); i++)
|
||||
{
|
||||
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[at + 2].mAddress)
|
||||
{
|
||||
if (mIns[i].mLive & LIVE_CPU_REG_Y)
|
||||
return false;
|
||||
mIns.Insert(i, mIns[at]);
|
||||
mIns.Insert(i + 1, mIns[at + 1]);
|
||||
mIns[i + 2].mType = ASMIT_STA;
|
||||
mIns[i].mLive |= mIns[i + 2].mLive;
|
||||
mIns[i + 1].mLive |= mIns[i + 2].mLive;
|
||||
mIns.Remove(at + 1, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mIns[i].ChangesZeroPage(mIns[at + 1].mAddress) || mIns[i].ChangesZeroPage(mIns[at + 1].mAddress + 1) || mIns[i].ReferencesZeroPage(mIns[at + 2].mAddress))
|
||||
return false;
|
||||
|
||||
if (mIns[i].mType == ASMIT_JSR)
|
||||
return false;
|
||||
|
||||
if (mIns[i].ChangesAddress())
|
||||
{
|
||||
if (mIns[i].mMode == ASMIM_INDIRECT_Y && mIns[i].mAddress == mIns[at + 1].mAddress)
|
||||
{
|
||||
if (yval == -1 || yval == mIns[at].mAddress)
|
||||
return false;
|
||||
}
|
||||
else if (mIns[at + 1].MayBeChangedOnAddress(mIns[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mIns[i].ChangesYReg())
|
||||
{
|
||||
if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE)
|
||||
yval = mIns[i].mAddress;
|
||||
else if (mIns[i].mType == ASMIT_INY && yval >= 0)
|
||||
yval = (yval + 1) & 255;
|
||||
else if (mIns[i].mType == ASMIT_DEY && yval >= 0)
|
||||
yval = (yval - 1) & 255;
|
||||
else
|
||||
yval = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::MoveLoadZeroStoreIndirectUp(int at)
|
||||
{
|
||||
int i = at - 1;
|
||||
while (i >= 0 && !(mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[at].mAddress))
|
||||
i--;
|
||||
|
||||
if (i >= 0 && mIns[i].mType == ASMIT_STA && !(mIns[i].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_Y)))
|
||||
{
|
||||
int yval = -1;
|
||||
for (int j = i + 1; j < at; j++)
|
||||
{
|
||||
if (mIns[j].mType == ASMIT_JSR)
|
||||
return false;
|
||||
if (mIns[j].ChangesZeroPage(mIns[at + 2].mAddress) || mIns[j].ChangesZeroPage(mIns[at + 2].mAddress + 1))
|
||||
return false;
|
||||
|
||||
if (mIns[j].mMode == ASMIM_INDIRECT_Y && mIns[j].mAddress == mIns[at + 2].mAddress)
|
||||
{
|
||||
if (yval == -1 || yval == mIns[at].mAddress)
|
||||
return false;
|
||||
}
|
||||
else if (mIns[j].MayBeSameAddress(mIns[at + 2]))
|
||||
return false;
|
||||
|
||||
if (mIns[j].ChangesYReg())
|
||||
{
|
||||
if (mIns[j].mType == ASMIT_LDY && mIns[j].mMode == ASMIM_IMMEDIATE)
|
||||
yval = mIns[j].mAddress;
|
||||
else if (mIns[j].mType == ASMIT_INY && yval >= 0)
|
||||
yval = (yval + 1) & 255;
|
||||
else if (mIns[j].mType == ASMIT_DEY && yval >= 0)
|
||||
yval = (yval - 1) & 255;
|
||||
else
|
||||
yval = -1;
|
||||
}
|
||||
}
|
||||
|
||||
NativeCodeInstruction i0 = mIns[at + 1], i1 = mIns[at + 2];
|
||||
mIns.Remove(at + 1, 2);
|
||||
|
||||
mIns.Insert(i + 1, i0);
|
||||
mIns.Insert(i + 2, i1);
|
||||
mIns[i].mLive |= LIVE_CPU_REG_A;
|
||||
mIns[i + 1].mLive |= mIns[i].mLive;
|
||||
mIns[i + 2].mLive |= mIns[i].mLive;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NativeCodeBasicBlock::ShortcutIndirectLoadStore(void)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
for (int i = 0; i + 2 < mIns.Size(); i++)
|
||||
{
|
||||
if (mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y &&
|
||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) &&
|
||||
mIns[i + 2].mAddress != mIns[i + 1].mAddress && mIns[i + 2].mAddress != mIns[i + 1].mAddress + 1)
|
||||
{
|
||||
if (MoveIndirectLoadZeroStoreDown(i))
|
||||
changed = true;
|
||||
}
|
||||
else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||
{
|
||||
if (MoveLoadZeroStoreIndirectUp(i))
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->ShortcutIndirectLoadStore())
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->ShortcutIndirectLoadStore())
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int NativeCodeExpressionID;
|
||||
|
||||
|
@ -34683,6 +34866,39 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
for (int i = 0; i + 1 < mIns.Size(); i++)
|
||||
{
|
||||
if (mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_IMPLIED &&
|
||||
mIns[i + 1].mType == ASMIT_LSR && mIns[i + 1].mMode == ASMIM_IMPLIED && !(mIns[i + 1].mLive & (LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
||||
{
|
||||
int j = 1;
|
||||
while (i >= j && i + j + 1 < mIns.Size() &&
|
||||
mIns[i - j].mType == ASMIT_ASL && mIns[i - j].mMode == ASMIM_IMPLIED &&
|
||||
mIns[i + 1 + j].mType == ASMIT_LSR && mIns[i + 1 + j].mMode == ASMIM_IMPLIED && !(mIns[i + 1 + j].mLive & (LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
||||
j++;
|
||||
mIns[i + 1 - j].mType = ASMIT_AND;
|
||||
mIns[i + 1 - j].mMode = ASMIM_IMMEDIATE;
|
||||
mIns[i + 1 - j].mAddress = 0xff >> j;
|
||||
|
||||
while (j > 1)
|
||||
{
|
||||
mIns[i + j].mType = ASMIT_NOP;
|
||||
mIns[i + j].mMode = ASMIM_IMPLIED;
|
||||
j--;
|
||||
mIns[i + 1 - j].mType = ASMIT_NOP;
|
||||
mIns[i + 1 - j].mMode = ASMIM_IMPLIED;
|
||||
}
|
||||
mIns[i + 1].mType = ASMIT_NOP;
|
||||
mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
CheckLive();
|
||||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
bool progress = false;
|
||||
do {
|
||||
|
@ -36740,6 +36956,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
progress = true;
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LSR && mIns[i + 0].mMode == ASMIM_IMPLIED &&
|
||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 &&
|
||||
mIns[i + 2].mType == ASMIT_ROL && mIns[i + 2].mMode == ASMIM_IMPLIED && !(mIns[i + 2].mLive & LIVE_CPU_REG_C))
|
||||
{
|
||||
mIns[i + 1].mType = ASMIT_AND; mIns[i + 1].mAddress = 1;
|
||||
mIns[i + 0].mAddress &= (mIns[i + 2].mAddress << 1) | 1;
|
||||
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
progress = true;
|
||||
}
|
||||
#endif
|
||||
else if (
|
||||
mIns[i + 0].IsShift() && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
|
@ -36984,6 +37213,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns.Remove(i + 2);
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LDA &&
|
||||
mIns[i + 1].mType == ASMIT_STA &&
|
||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) &&
|
||||
!(mIns[i + 0].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && (mIns[i + 1].mAddress == mIns[i + 0].mAddress || mIns[i + 1].mAddress + 1 == mIns[i + 0].mAddress)))
|
||||
{
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
progress = true;
|
||||
}
|
||||
|
||||
if (
|
||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 &&
|
||||
|
@ -40915,7 +41153,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
{
|
||||
mInterProc = proc;
|
||||
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "main");
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test");
|
||||
|
||||
int nblocks = proc->mBlocks.Size();
|
||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||
|
@ -41688,6 +41926,14 @@ void NativeCodeProcedure::Optimize(void)
|
|||
changed = true;
|
||||
#endif
|
||||
|
||||
|
||||
if (step == 2)
|
||||
{
|
||||
ResetVisited();
|
||||
if (mEntryBlock->ShortcutIndirectLoadStore())
|
||||
changed = true;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (step >= 3)
|
||||
{
|
||||
|
|
|
@ -604,6 +604,10 @@ public:
|
|||
bool CheckShortcutPointerAddForward(int at);
|
||||
bool ShortcutPointerAddForward(void);
|
||||
|
||||
bool ShortcutIndirectLoadStore(void);
|
||||
bool MoveIndirectLoadZeroStoreDown(int at);
|
||||
bool MoveLoadZeroStoreIndirectUp(int at);
|
||||
|
||||
bool CommonSubExpressionElimination(void);
|
||||
|
||||
bool CheckPatchFailReg(const NativeCodeBasicBlock* block, int reg);
|
||||
|
|
|
@ -231,6 +231,8 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
|||
}
|
||||
else
|
||||
{
|
||||
int bitsleft = 0;
|
||||
|
||||
Declaration* mlast = nullptr;
|
||||
for (;;)
|
||||
{
|
||||
|
@ -334,7 +336,103 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
|||
mdec->mType = DT_ELEMENT;
|
||||
mdec->mOffset = offset;
|
||||
|
||||
offset += mdec->mBase->mSize;
|
||||
if (mdec->mBits)
|
||||
{
|
||||
if (mdec->mBits <= 8)
|
||||
{
|
||||
if (bitsleft == 0)
|
||||
{
|
||||
bitsleft = 8 - mdec->mBits;
|
||||
offset++;
|
||||
}
|
||||
else if (bitsleft >= mdec->mBits)
|
||||
{
|
||||
mdec->mOffset--;
|
||||
mdec->mShift = 8 - bitsleft;
|
||||
bitsleft -= mdec->mBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
mdec->mOffset--;
|
||||
mdec->mShift = 8 - bitsleft;
|
||||
bitsleft = 8 + bitsleft - mdec->mBits;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
else if (mdec->mBits <= 16)
|
||||
{
|
||||
if (bitsleft == 0)
|
||||
{
|
||||
bitsleft = 16 - mdec->mBits;
|
||||
offset += 2;
|
||||
}
|
||||
else if (bitsleft + 8 >= mdec->mBits)
|
||||
{
|
||||
mdec->mOffset--;
|
||||
mdec->mShift = 8 - bitsleft;
|
||||
bitsleft = bitsleft + 8 - mdec->mBits;
|
||||
offset++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mdec->mOffset -= 3;
|
||||
mdec->mShift = 24 - bitsleft;
|
||||
bitsleft = bitsleft + 16 - mdec->mBits;
|
||||
offset += 2;
|
||||
}
|
||||
}
|
||||
else if (mdec->mBits <= 24)
|
||||
{
|
||||
if (bitsleft == 0)
|
||||
{
|
||||
bitsleft = 24 - mdec->mBits;
|
||||
offset += 3;
|
||||
}
|
||||
else if (bitsleft + 16 >= mdec->mBits)
|
||||
{
|
||||
mdec->mOffset -= 2;
|
||||
mdec->mShift = 16 - bitsleft;
|
||||
bitsleft = bitsleft + 16 - mdec->mBits;
|
||||
offset += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
mdec->mOffset -= 1;
|
||||
mdec->mShift = 8 - bitsleft;
|
||||
bitsleft = bitsleft + 24 - mdec->mBits;
|
||||
offset += 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bitsleft == 0)
|
||||
{
|
||||
bitsleft = 32 - mdec->mBits;
|
||||
offset += 4;
|
||||
}
|
||||
else if (bitsleft + 24 >= mdec->mBits)
|
||||
{
|
||||
mdec->mOffset--;
|
||||
mdec->mShift = 8 - bitsleft;
|
||||
bitsleft = bitsleft + 24 - mdec->mBits;
|
||||
offset+=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitsleft = 32 - mdec->mBits;
|
||||
offset += mdec->mBase->mSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (mdec->mShift == 0 && mdec->mBits == 8 * mdec->mSize)
|
||||
mdec->mBits = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitsleft = 0;
|
||||
offset += mdec->mBase->mSize;
|
||||
}
|
||||
|
||||
if (offset > dec->mSize)
|
||||
dec->mSize = offset;
|
||||
|
||||
|
@ -1409,6 +1507,8 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
|||
Expression* texp = ParseInitExpression(mdec->mBase);
|
||||
|
||||
Declaration* cdec = CopyConstantInitializer(mdec->mOffset, mdec->mBase, texp);
|
||||
cdec->mBits = mdec->mBits;
|
||||
cdec->mShift = mdec->mShift;
|
||||
|
||||
if (last)
|
||||
last->mNext = cdec;
|
||||
|
@ -4043,9 +4143,19 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
ldec = ndec;
|
||||
// ndec->mNext = nullptr;
|
||||
|
||||
if (mScanner->mToken == TK_ASSIGN)
|
||||
if (ConsumeTokenIf(TK_COLON))
|
||||
{
|
||||
Expression* exp = ParseRExpression();
|
||||
if (!ndec->mBase->IsIntegerType())
|
||||
mErrors->Error(exp->mLocation, EERR_INVALID_BITFIELD, "Invalid bitfíeld for non integer type");
|
||||
else if (exp->mType == EX_CONSTANT && exp->mDecType->IsIntegerType() && exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||
ndec->mBits = uint8(exp->mDecValue->mInteger);
|
||||
else
|
||||
mErrors->Error(exp->mLocation, EERR_CONSTANT_TYPE, "Constant integer expression expected");
|
||||
}
|
||||
|
||||
if (ConsumeTokenIf(TK_ASSIGN))
|
||||
{
|
||||
mScanner->NextToken();
|
||||
ndec->mValue = ParseInitExpression(ndec->mBase);
|
||||
if (ndec->mBase->mType == DT_TYPE_AUTO)
|
||||
{
|
||||
|
|
|
@ -116,7 +116,8 @@ int main2(int argc, const char** argv)
|
|||
strcpy_s(crtPath, includePath);
|
||||
strcat_s(crtPath, "crt.c");
|
||||
|
||||
bool emulate = false, profile = false, trace = false;
|
||||
bool emulate = false, profile = false;
|
||||
int trace = 0;
|
||||
|
||||
targetPath[0] = 0;
|
||||
diskPath[0] = 0;
|
||||
|
@ -211,7 +212,9 @@ int main2(int argc, const char** argv)
|
|||
if (arg[2] == 'p')
|
||||
profile = true;
|
||||
else if (arg[2] == 't')
|
||||
trace = true;
|
||||
trace = 2;
|
||||
else if (arg[2] == 'b')
|
||||
trace = 1;
|
||||
}
|
||||
else if (arg[1] == 'd')
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue