Add makefile for linux

This commit is contained in:
drmortalwombat 2021-09-24 16:17:20 +02:00
parent 5c3ff47690
commit fd10525780
26 changed files with 524 additions and 128 deletions

4
.gitignore vendored
View File

@ -335,3 +335,7 @@ ASALocalRun/
*.asm
*.map
*.prg
*.d
*.d.*
*.o
make/oscar64

View File

@ -90,6 +90,12 @@ if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n qsorttest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e loopdomtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n loopdomtest.c
if %errorlevel% neq 0 goto :error
exit /b 0
:error
echo Failed with error #%errorlevel%.

13
autotest/floortest.c Normal file
View File

@ -0,0 +1,13 @@
#include <stdio.h>
#include <math.h>
int main(void)
{
for(int y=1; y<100; y++)
{
float fz = 100.0 / (float)y;
printf("%d %f %f\n", y, floor(fz * 100.0), fz * 100.0);
}
return 0;
}

28
autotest/loopdomtest.c Normal file
View File

@ -0,0 +1,28 @@
#include <stdio.h>
#include <assert.h>
int main(void)
{
int a[10][10];
for(int i=0; i<10; i++)
{
for(int j=0; j<10; j++)
{
a[i][j] = i + j;
}
}
int s = 0;
for(int i=0; i<10; i++)
{
s += a[i][i];
}
assert(s == 90);
return 0;
}

39
make/makefile Normal file
View File

@ -0,0 +1,39 @@
sources = $(wildcard ../oscar64/*.cpp)
objects = $(patsubst ../oscar64/%.cpp,%.o,$(sources))
CXX = g++
CPPFLAGS = -g -O -march=athlon64 -mfpmath=sse
ifdef WINDIR
linklibs = -lpthread
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Darwin)
linklibs = -lpthread
else
linklibs = -lrt -lpthread
endif
endif
%.o: ../oscar64/%.cpp
g++ -c $(CPPFLAGS) $< -o $@
%.d: ../oscar64/%.cpp
@set -e; rm -f $@; \
$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
oscar64 : $(objects)
g++ $(CPPFLAGS) $(linklibs) $(objects) -o oscar64
.PHONY : clean
clean :
-rm *.o *.d
include $(objects:.o=.d)

View File

@ -212,26 +212,26 @@ public:
delete[] array;
}
__forceinline T& operator[](int n)
T& operator[](int n)
{
assert(n >= 0);
if (n >= size) Grow(n + 1, false);
return array[n];
}
__forceinline T operator[](int n) const
T operator[](int n) const
{
assert(n >= 0);
if (n >= size) return empty;
else return array[n];
}
__forceinline void Push(T t)
void Push(T t)
{
(*this)[size] = t;
}
__forceinline T Pop(void)
T Pop(void)
{
assert(size > 0);
return array[--size];
@ -249,21 +249,21 @@ public:
array[at] = t;
}
__forceinline T Top(void) const
T Top(void) const
{
return array[size - 1];
}
__forceinline bool IsEmpty(void) const { return size == 0; }
bool IsEmpty(void) const { return size == 0; }
__forceinline int Size(void) const { return size; }
int Size(void) const { return size; }
__forceinline void SetSize(int size, bool clear = false)
void SetSize(int size, bool clear = false)
{
Grow(size, clear);
}
__forceinline void Clear(void)
void Clear(void)
{
Grow(size, true);
}

View File

@ -1,5 +1,3 @@
#pragma once
#include "Assembler.h"
#include <assert.h>

View File

@ -232,8 +232,7 @@ inline BitVector BitVector::operator*(const int n) const
if (dw < vv.dwsize)
vv.bits[dw++] = merge;
if (dw > vv.dwsize)
__asm int 3
assert(dw <= vv.dwsize);
}
return vv;

View File

@ -532,11 +532,12 @@ ByteCodeBasicBlock::ByteCodeBasicBlock(void)
mTrueLink = mFalseLink = NULL;
mOffset = 0x7fffffff;
mCopied = false;
mAssembled = false;
mKnownShortBranch = false;
mBypassed = false;
}
void ByteCodeBasicBlock::IntConstToAccu(__int64 val)
void ByteCodeBasicBlock::IntConstToAccu(int64 val)
{
ByteCodeInstruction ins(BC_CONST_16);
ins.mRegister = BC_REG_ACCU;
@ -565,7 +566,7 @@ void ByteCodeBasicBlock::FloatConstToWork(double val)
}
void ByteCodeBasicBlock::IntConstToAddr(__int64 val)
void ByteCodeBasicBlock::IntConstToAddr(int64 val)
{
ByteCodeInstruction ins(BC_CONST_16);
ins.mRegister = BC_REG_ADDR;
@ -2769,7 +2770,9 @@ void ByteCodeBasicBlock::Assemble(ByteCodeGenerator* generator)
mAssembled = true;
for (int i = 0; i < mIns.Size(); i++)
{
mIns[i].Assemble(generator, this);
}
if (this->mTrueJump)
this->mTrueJump->Assemble(generator);

View File

@ -214,8 +214,8 @@ public:
void CalculateOffset(int& total);
void CopyCode(ByteCodeGenerator* generator, LinkerObject * linkerObject, uint8* target);
void IntConstToAccu(__int64 val);
void IntConstToAddr(__int64 val);
void IntConstToAccu(int64 val);
void IntConstToAddr(int64 val);
void FloatConstToAccu(double val);
void FloatConstToWork(double val);
void CopyValue(InterCodeProcedure* proc, const InterInstruction * ins);

View File

@ -1,5 +1,9 @@
#include "CompilationUnits.h"
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <string.h>

View File

@ -150,6 +150,7 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("mul16by8"));
RegisterRuntime(loc, Ident::Unique("fsplitt"));
RegisterRuntime(loc, Ident::Unique("fsplita"));
RegisterRuntime(loc, Ident::Unique("faddsub"));
RegisterRuntime(loc, Ident::Unique("fmul"));
RegisterRuntime(loc, Ident::Unique("fdiv"));

View File

@ -246,7 +246,7 @@ Expression* Expression::ConstantFold(void)
{
if (mLeft->mDecValue->mType == DT_CONST_INTEGER && mRight->mDecValue->mType == DT_CONST_INTEGER)
{
__int64 ival, ileft = mLeft->mDecValue->mInteger, iright = mRight->mDecValue->mInteger;
int64 ival, ileft = mLeft->mDecValue->mInteger, iright = mRight->mDecValue->mInteger;
switch (mToken)
{

View File

@ -154,7 +154,7 @@ public:
Expression* mValue;
DeclarationScope* mScope;
int mOffset, mSize, mVarIndex;
__int64 mInteger;
int64 mInteger;
double mNumber;
uint32 mFlags;
const Ident * mIdent;

View File

@ -1,4 +1,5 @@
#include "Ident.h"
#include "MachineTypes.h"
#include <string.h>
Ident::~Ident()
@ -21,7 +22,7 @@ unsigned int IHash(const char* str)
Ident::Ident(const char* str, unsigned int hash)
{
ptrdiff_t ssize = strlen(str);
int ssize = strlen(str);
mString = new char[ssize + 1];
strcpy_s(mString, ssize + 1, str);

View File

@ -3,7 +3,6 @@
#include "InterCode.h"
#include <stdio.h>
#include <math.h>
#include <crtdbg.h>
int InterTypeSize[] = {
0,
@ -86,7 +85,7 @@ void ValueSet::FlushCallAliases(void)
}
}
static __int64 ConstantFolding(InterOperator oper, __int64 val1, __int64 val2)
static int64 ConstantFolding(InterOperator oper, int64 val1, int64 val2)
{
switch (oper)
{
@ -100,13 +99,13 @@ static __int64 ConstantFolding(InterOperator oper, __int64 val1, __int64 val2)
return val1 * val2;
break;
case IA_DIVU:
return (unsigned __int64)val1 / (unsigned __int64)val2;
return (uint64)val1 / (uint64)val2;
break;
case IA_DIVS:
return val1 / val2;
break;
case IA_MODU:
return (unsigned __int64)val1 % (unsigned __int64)val2;
return (uint64)val1 % (uint64)val2;
break;
case IA_MODS:
return val1 % val2;
@ -130,7 +129,7 @@ static __int64 ConstantFolding(InterOperator oper, __int64 val1, __int64 val2)
return val1 << val2;
break;
case IA_SHR:
return (unsigned __int64)val1 >> (unsigned __int64)val2;
return (uint64)val1 >> (uint64)val2;
break;
case IA_SAR:
return val1 >> val2;
@ -154,23 +153,23 @@ static __int64 ConstantFolding(InterOperator oper, __int64 val1, __int64 val2)
return val1 < val2 ? 1 : 0;
break;
case IA_CMPGEU:
return (unsigned __int64)val1 >= (unsigned __int64)val2 ? 1 : 0;
return (uint64)val1 >= (uint64)val2 ? 1 : 0;
break;
case IA_CMPLEU:
return (unsigned __int64)val1 <= (unsigned __int64)val2 ? 1 : 0;
return (uint64)val1 <= (uint64)val2 ? 1 : 0;
break;
case IA_CMPGU:
return (unsigned __int64)val1 > (unsigned __int64)val2 ? 1 : 0;
return (uint64)val1 > (uint64)val2 ? 1 : 0;
break;
case IA_CMPLU:
return (unsigned __int64)val1 < (unsigned __int64)val2 ? 1 : 0;
return (uint64)val1 < (uint64)val2 ? 1 : 0;
break;
default:
return 0;
}
}
static __int64 ConstantRelationalFolding(InterOperator oper, double val1, double val2)
static int64 ConstantRelationalFolding(InterOperator oper, double val1, double val2)
{
switch (oper)
{
@ -1652,7 +1651,13 @@ void InterInstruction::Disassemble(FILE* file)
else if (mTType == IT_FLOAT)
fprintf(file, "C%f", mFloatValue);
else
{
#ifdef _WIN32
fprintf(file, "C%I64d", mIntValue);
#else
fprintf(file, "C%lld", mIntValue);
#endif
}
}
fprintf(file, "\n");
@ -1660,7 +1665,7 @@ void InterInstruction::Disassemble(FILE* file)
}
InterCodeBasicBlock::InterCodeBasicBlock(void)
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr)
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mDominator(nullptr)
{
mInPath = false;
mLoopHead = false;
@ -2476,13 +2481,16 @@ bool InterCodeBasicBlock::RemoveUnusedResultInstructions(int numStaticTemps)
for (i = 0; i < numStaticTemps; i++)
requiredTemps += i;
for (i = mInstructions.Size() - 1; i > 0; i--)
if (mInstructions.Size() > 0)
{
if (mInstructions[i]->RemoveUnusedResultInstructions(mInstructions[i - 1], requiredTemps, numStaticTemps))
for (i = mInstructions.Size() - 1; i > 0; i--)
{
if (mInstructions[i]->RemoveUnusedResultInstructions(mInstructions[i - 1], requiredTemps, numStaticTemps))
changed = true;
}
if (mInstructions[0]->RemoveUnusedResultInstructions(NULL, requiredTemps, numStaticTemps))
changed = true;
}
if (mInstructions[0]->RemoveUnusedResultInstructions(NULL, requiredTemps, numStaticTemps))
changed = true;
if (mTrueJump)
{
@ -3058,6 +3066,173 @@ static bool CanBypassStore(const InterInstruction * sins, const InterInstruction
return true;
}
InterCodeBasicBlock* InterCodeBasicBlock::PropagateDominator(InterCodeProcedure* proc)
{
if (!mVisited)
{
mVisited = true;
if (mTrueJump)
mTrueJump = mTrueJump->PropagateDominator(proc);
if (mFalseJump)
mFalseJump = mFalseJump->PropagateDominator(proc);
if (mLoopHead)
{
mDominator = new InterCodeBasicBlock();
proc->Append(mDominator);
mDominator->Close(this, nullptr);
}
}
return mDominator ? mDominator : this;
}
bool IsMoveable(InterCode code)
{
if (HasSideEffect(code) || code == IC_COPY || code == IC_STORE || code == IC_BRANCH || code == IC_POP_FRAME || code == IC_PUSH_FRAME)
return false;
if (code == IC_RETURN || code == IC_RETURN_STRUCT || code == IC_RETURN_VALUE)
return false;
return true;
}
void InterCodeBasicBlock::SingleBlockLoopOptimisation(void)
{
if (!mVisited)
{
mVisited = true;
if (mLoopHead && mNumEntries == 2 && (mTrueJump == this || mFalseJump == this))
{
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins = mInstructions[i];
ins->mInvariant = true;
if (!IsMoveable(ins->mCode))
ins->mInvariant = false;
else if (ins->mCode == IC_LOAD)
{
if (ins->mSTemp[0] >= 0)
{
ins->mInvariant = false;
}
else
{
for (int j = 0; j < mInstructions.Size(); j++)
{
InterInstruction* sins = mInstructions[j];
if (sins->mCode == IC_STORE)
{
if (sins->mSTemp[1] >= 0)
{
ins->mInvariant = false;
}
else if (ins->mMemory == sins->mMemory && ins->mVarIndex == sins->mVarIndex && ins->mLinkerObject == sins->mLinkerObject)
{
ins->mInvariant = false;
}
}
}
}
}
}
enum Dependency
{
DEP_UNKNOWN,
DEP_DEFINED,
DEP_ITERATED,
DEP_VARIABLE
};
GrowingArray<Dependency> dep(DEP_UNKNOWN);
GrowingArray<InterInstructionPtr> tvalues(nullptr);
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins = mInstructions[i];
int t = ins->mTTemp;
if (t >= 0)
{
if (HasSideEffect(ins->mCode) || !ins->mInvariant)
dep[t] = DEP_VARIABLE;
else if (dep[t] == DEP_UNKNOWN)
dep[t] = DEP_DEFINED;
else if (dep[t] == DEP_DEFINED)
{
dep[t] = DEP_VARIABLE;
ins->mInvariant = false;
}
}
}
for (int i = 0; i < dep.Size(); i++)
{
if (dep[i] == DEP_DEFINED)
dep[i] = DEP_ITERATED;
}
bool changed;
do
{
changed = false;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins = mInstructions[i];
int t = ins->mTTemp;
if (t >= 0)
{
if (dep[t] < DEP_VARIABLE)
{
if (ins->mSTemp[0] >= 0 && dep[ins->mSTemp[0]] >= DEP_ITERATED ||
ins->mSTemp[1] >= 0 && dep[ins->mSTemp[1]] >= DEP_ITERATED ||
ins->mSTemp[2] >= 0 && dep[ins->mSTemp[2]] >= DEP_ITERATED)
{
dep[t] = DEP_VARIABLE;
ins->mInvariant = false;
changed = true;
}
else
{
dep[t] = DEP_DEFINED;
}
}
}
}
} while (changed);
#if 1
int j = 0;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins = mInstructions[i];
if (ins->mInvariant)
{
mDominator->mInstructions.Push(ins);
}
else
{
mInstructions[j++] = ins;
}
}
if (j != mInstructions.Size())
printf("Moved %d %d\n", mIndex, mInstructions.Size() - j);
mInstructions.SetSize(j);
#endif
}
if (mTrueJump)
mTrueJump->SingleBlockLoopOptimisation();
if (mFalseJump)
mFalseJump->SingleBlockLoopOptimisation();
}
}
void InterCodeBasicBlock::PeepholeOptimization(void)
{
int i;
@ -3358,7 +3533,7 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets)
for (i = 0; i < mInstructions.Size(); i++)
{
if (mInstructions[i]->mCode != IT_NONE)
if (mInstructions[i]->mCode != IC_NONE)
{
fprintf(file, "%04x\t", i);
mInstructions[i]->Disassemble(file);
@ -3425,18 +3600,18 @@ void InterCodeProcedure::BuildTraces(void)
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0;
mBlocks[0]->CollectEntries();
mEntryBlock->CollectEntries();
//
// Build traces
//
ResetVisited();
mBlocks[0]->GenerateTraces();
mEntryBlock->GenerateTraces();
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0;
mBlocks[0]->CollectEntries();
mEntryBlock->CollectEntries();
DisassembleDebug("BuildTraces");
}
@ -3449,13 +3624,13 @@ void InterCodeProcedure::BuildDataFlowSets(void)
// Build set with local provided/required temporaries
//
ResetVisited();
mBlocks[0]->BuildLocalTempSets(numTemps, numFixedTemporaries);
mEntryBlock->BuildLocalTempSets(numTemps, numFixedTemporaries);
//
// Build set of globaly provided temporaries
//
ResetVisited();
mBlocks[0]->BuildGlobalProvidedTempSet(NumberSet(numTemps));
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps));
//
// Build set of globaly required temporaries, might need
@ -3465,7 +3640,7 @@ void InterCodeProcedure::BuildDataFlowSets(void)
do {
ResetVisited();
} while (mBlocks[0]->BuildGlobalRequiredTempSet(totalRequired));
} while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired));
}
void InterCodeProcedure::RenameTemporaries(void)
@ -3487,7 +3662,7 @@ void InterCodeProcedure::RenameTemporaries(void)
// First localy rename all temporaries
//
ResetVisited();
mBlocks[0]->LocalRenameRegister(mRenameTable, numRename, numFixedTemporaries);
mEntryBlock->LocalRenameRegister(mRenameTable, numRename, numFixedTemporaries);
DisassembleDebug("local renamed temps");
@ -3506,7 +3681,7 @@ void InterCodeProcedure::RenameTemporaries(void)
mRenameTable.SetSize(numTemps, true);
ResetVisited();
mBlocks[0]->BuildGlobalRenameRegisterTable(mRenameTable, mRenameUnionTable);
mEntryBlock->BuildGlobalRenameRegisterTable(mRenameTable, mRenameUnionTable);
//
// Now calculate the global temporary IDs for all local ids
@ -3536,7 +3711,7 @@ void InterCodeProcedure::RenameTemporaries(void)
// Set global temporary IDs
//
ResetVisited();
mBlocks[0]->GlobalRenameRegister(mGlobalRenameTable, mTemporaries);
mEntryBlock->GlobalRenameRegister(mGlobalRenameTable, mTemporaries);
numTemps = numRenamedTemps;
@ -3558,7 +3733,7 @@ void InterCodeProcedure::TempForwarding(void)
mTempForwardingTable.Reset();
ResetVisited();
mBlocks[0]->PerformTempForwarding(mTempForwardingTable);
mEntryBlock->PerformTempForwarding(mTempForwardingTable);
DisassembleDebug("temp forwarding");
}
@ -3569,19 +3744,19 @@ void InterCodeProcedure::RemoveUnusedInstructions(void)
do {
ResetVisited();
mBlocks[0]->BuildLocalTempSets(numTemps, numFixedTemporaries);
mEntryBlock->BuildLocalTempSets(numTemps, numFixedTemporaries);
ResetVisited();
mBlocks[0]->BuildGlobalProvidedTempSet(NumberSet(numTemps));
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps));
NumberSet totalRequired2(numTemps);
do {
ResetVisited();
} while (mBlocks[0]->BuildGlobalRequiredTempSet(totalRequired2));
} while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired2));
ResetVisited();
} while (mBlocks[0]->RemoveUnusedResultInstructions(numFixedTemporaries));
} while (mEntryBlock->RemoveUnusedResultInstructions(numFixedTemporaries));
}
void InterCodeProcedure::Close(void)
@ -3589,23 +3764,22 @@ void InterCodeProcedure::Close(void)
int i, j, k, start;
GrowingTypeArray tstack(IT_NONE);
_CrtCheckMemory();
numFixedTemporaries = 0;
mEntryBlock = mBlocks[0];
DisassembleDebug("start");
BuildTraces();
ResetVisited();
mLeafProcedure = mBlocks[0]->IsLeafProcedure();
mLeafProcedure = mEntryBlock->IsLeafProcedure();
if (!mLeafProcedure)
{
int size = 0;
ResetVisited();
mBlocks[0]->CollectOuterFrame(0, size);
mEntryBlock->CollectOuterFrame(0, size);
mCommonFrameSize = size;
}
else
@ -3624,7 +3798,7 @@ void InterCodeProcedure::Close(void)
//
GrowingIntArray localTable(-1), paramTable(-1);
ResetVisited();
mBlocks[0]->CollectLocalAddressTemps(localTable, paramTable);
mEntryBlock->CollectLocalAddressTemps(localTable, paramTable);
int nlocals = 0, nparams = 0;
for (int i = 0; i < localTable.Size(); i++)
@ -3637,7 +3811,7 @@ void InterCodeProcedure::Close(void)
mLocalAliasedSet.Reset(nlocals);
mParamAliasedSet.Reset(nparams);
ResetVisited();
mBlocks[0]->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet);
mEntryBlock->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet);
//
// Now forward constant values
@ -3648,14 +3822,14 @@ void InterCodeProcedure::Close(void)
mValueForwardingTable.SetSize(numTemps, true);
ResetVisited();
mBlocks[0]->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet);
mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet);
DisassembleDebug("value forwarding");
mValueForwardingTable.Clear();
ResetVisited();
mBlocks[0]->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet);
mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet);
GlobalConstantPropagation();
@ -3669,7 +3843,7 @@ void InterCodeProcedure::Close(void)
mTempForwardingTable.SetSize(numTemps);
ResetVisited();
mBlocks[0]->PerformTempForwarding(mTempForwardingTable);
mEntryBlock->PerformTempForwarding(mTempForwardingTable);
DisassembleDebug("temp forwarding 2");
@ -3680,24 +3854,24 @@ void InterCodeProcedure::Close(void)
do {
ResetVisited();
mBlocks[0]->BuildLocalTempSets(numTemps, numFixedTemporaries);
mEntryBlock->BuildLocalTempSets(numTemps, numFixedTemporaries);
ResetVisited();
mBlocks[0]->BuildGlobalProvidedTempSet(NumberSet(numTemps));
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps));
NumberSet totalRequired2(numTemps);
do {
ResetVisited();
} while (mBlocks[0]->BuildGlobalRequiredTempSet(totalRequired2));
} while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired2));
ResetVisited();
} while (mBlocks[0]->RemoveUnusedResultInstructions(numFixedTemporaries));
} while (mEntryBlock->RemoveUnusedResultInstructions(numFixedTemporaries));
DisassembleDebug("removed unused instructions");
ResetVisited();
mBlocks[0]->CollectVariables(mModule->mGlobalVars, mLocalVars);
mEntryBlock->CollectVariables(mModule->mGlobalVars, mLocalVars);
if (mLocalVars.Size() > 0)
@ -3714,19 +3888,19 @@ void InterCodeProcedure::Close(void)
do {
ResetVisited();
mBlocks[0]->BuildLocalVariableSets(mLocalVars);
mEntryBlock->BuildLocalVariableSets(mLocalVars);
ResetVisited();
mBlocks[0]->BuildGlobalProvidedVariableSet(mLocalVars, NumberSet(mLocalVars.Size()));
mEntryBlock->BuildGlobalProvidedVariableSet(mLocalVars, NumberSet(mLocalVars.Size()));
NumberSet totalRequired2(mLocalVars.Size());
do {
ResetVisited();
} while (mBlocks[0]->BuildGlobalRequiredVariableSet(mLocalVars, totalRequired2));
} while (mEntryBlock->BuildGlobalRequiredVariableSet(mLocalVars, totalRequired2));
ResetVisited();
} while (mBlocks[0]->RemoveUnusedStoreInstructions(mLocalVars));
} while (mEntryBlock->RemoveUnusedStoreInstructions(mLocalVars));
DisassembleDebug("removed unused local stores");
}
@ -3742,7 +3916,7 @@ void InterCodeProcedure::Close(void)
GrowingTypeArray paramTypes(IT_NONE);
ResetVisited();
mBlocks[0]->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
mEntryBlock->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
for (int i = 0; i < simpleLocals.Num(); i++)
{
@ -3750,7 +3924,7 @@ void InterCodeProcedure::Close(void)
if (!complexLocals[vi])
{
ResetVisited();
mBlocks[0]->SimpleLocalToTemp(vi, AddTemporary(localTypes[vi]));
mEntryBlock->SimpleLocalToTemp(vi, AddTemporary(localTypes[vi]));
}
}
@ -3774,9 +3948,30 @@ void InterCodeProcedure::Close(void)
DisassembleDebug("removed unused instructions 2");
TempForwarding();
BuildDominators();
DisassembleDebug("added dominators");
BuildDataFlowSets();
ResetVisited();
mBlocks[0]->PeepholeOptimization();
mEntryBlock->PeepholeOptimization();
TempForwarding();
RemoveUnusedInstructions();
DisassembleDebug("Peephole optimized");
ResetVisited();
mEntryBlock->SingleBlockLoopOptimisation();
DisassembleDebug("single block loop opt");
BuildDataFlowSets();
ResetVisited();
mEntryBlock->PeepholeOptimization();
TempForwarding();
RemoveUnusedInstructions();
@ -3792,7 +3987,7 @@ void InterCodeProcedure::Close(void)
activeSet += i;
ResetVisited();
mBlocks[0]->CollectActiveTemporaries(activeSet);
mEntryBlock->CollectActiveTemporaries(activeSet);
mTemporaries.SetSize(activeSet.Num(), true);
@ -3800,19 +3995,17 @@ void InterCodeProcedure::Close(void)
ResetVisited();
mBlocks[0]->ShrinkActiveTemporaries(activeSet, mTemporaries);
mEntryBlock->ShrinkActiveTemporaries(activeSet, mTemporaries);
MapVariables();
DisassembleDebug("mapped variabled");
_CrtCheckMemory();
}
void InterCodeProcedure::MapVariables(void)
{
ResetVisited();
mBlocks[0]->MapVariables(mModule->mGlobalVars, mLocalVars);
mEntryBlock->MapVariables(mModule->mGlobalVars, mLocalVars);
mLocalSize = 0;
for (int i = 0; i < mLocalVars.Size(); i++)
{
@ -3824,6 +4017,17 @@ void InterCodeProcedure::MapVariables(void)
}
}
void InterCodeProcedure::BuildDominators(void)
{
ResetVisited();
mEntryBlock = mEntryBlock->PropagateDominator(this);
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0;
mEntryBlock->CollectEntries();
}
bool InterCodeProcedure::GlobalConstantPropagation(void)
{
@ -3832,10 +4036,10 @@ bool InterCodeProcedure::GlobalConstantPropagation(void)
ResetVisited();
mBlocks[0]->CollectConstTemps(ctemps, assignedTemps);
mEntryBlock->CollectConstTemps(ctemps, assignedTemps);
ResetVisited();
return mBlocks[0]->PropagateConstTemps(ctemps);
return mEntryBlock->PropagateConstTemps(ctemps);
}
void InterCodeProcedure::ReduceTemporaries(void)
@ -3845,16 +4049,16 @@ void InterCodeProcedure::ReduceTemporaries(void)
int numTemps = mTemporaries.Size();
ResetVisited();
mBlocks[0]->BuildLocalTempSets(numTemps, numFixedTemporaries);
mEntryBlock->BuildLocalTempSets(numTemps, numFixedTemporaries);
ResetVisited();
mBlocks[0]->BuildGlobalProvidedTempSet(NumberSet(numTemps));
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps));
NumberSet totalRequired2(numTemps);
do {
ResetVisited();
} while (mBlocks[0]->BuildGlobalRequiredTempSet(totalRequired2));
} while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired2));
collisionSet = new NumberSet[numTemps];
@ -3862,7 +4066,7 @@ void InterCodeProcedure::ReduceTemporaries(void)
collisionSet[i].Reset(numTemps);
ResetVisited();
mBlocks[0]->BuildCollisionTable(collisionSet);
mEntryBlock->BuildCollisionTable(collisionSet);
mRenameTable.SetSize(numTemps, true);
@ -3896,26 +4100,26 @@ void InterCodeProcedure::ReduceTemporaries(void)
mTemporaries.SetSize(numRenamedTemps, true);
ResetVisited();
mBlocks[0]->GlobalRenameRegister(mRenameTable, mTemporaries);
mEntryBlock->GlobalRenameRegister(mRenameTable, mTemporaries);
delete[] collisionSet;
ResetVisited();
mBlocks[0]->BuildLocalTempSets(numRenamedTemps, numFixedTemporaries);
mEntryBlock->BuildLocalTempSets(numRenamedTemps, numFixedTemporaries);
ResetVisited();
mBlocks[0]->BuildGlobalProvidedTempSet(NumberSet(numRenamedTemps));
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numRenamedTemps));
NumberSet totalRequired3(numRenamedTemps);
do {
ResetVisited();
} while (mBlocks[0]->BuildGlobalRequiredTempSet(totalRequired3));
} while (mEntryBlock->BuildGlobalRequiredTempSet(totalRequired3));
NumberSet callerSaved(numRenamedTemps);
ResetVisited();
mBlocks[0]->BuildCallerSaveTempSet(callerSaved);
mEntryBlock->BuildCallerSaveTempSet(callerSaved);
int callerSavedTemps = 0, calleeSavedTemps = 16;
@ -3972,7 +4176,7 @@ void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
fprintf(file, "\n");
ResetVisited();
mBlocks[0]->Disassemble(file, dumpSets);
mEntryBlock->Disassemble(file, dumpSets);
fclose(file);
}

View File

@ -291,18 +291,18 @@ public:
InterType mTType, mSType[3];
int mTTemp, mSTemp[3];
bool mSFinal[3];
__int64 mSIntConst[3];
int64 mSIntConst[3];
double mSFloatConst[3];
InterMemory mMemory;
InterOperator mOperator;
int mOperandSize;
int mVarIndex;
__int64 mIntValue;
int64 mIntValue;
double mFloatValue;
Location mLocation;
LinkerObject * mLinkerObject;
bool mInUse;
bool mInUse, mInvariant;
InterInstruction(void);
@ -385,10 +385,10 @@ class InterCodeBasicBlock
{
public:
int mIndex, mNumEntries, mNumEntered;
InterCodeBasicBlock* mTrueJump, * mFalseJump;
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mDominator;
GrowingInstructionArray mInstructions;
bool mVisited, mInPath, mLoopHead;
bool mVisited, mInPath, mLoopHead;
NumberSet mLocalRequiredTemps, mLocalProvidedTemps;
NumberSet mEntryRequiredTemps, mEntryProvidedTemps;
@ -463,6 +463,9 @@ public:
bool IsLeafProcedure(void);
void PeepholeOptimization(void);
void SingleBlockLoopOptimisation(void);
InterCodeBasicBlock* PropagateDominator(InterCodeProcedure * proc);
};
class InterCodeModule;
@ -478,6 +481,7 @@ protected:
void ResetVisited(void);
public:
InterCodeBasicBlock * mEntryBlock;
GrowingInterCodeBasicBlockPtrArray mBlocks;
GrowingTypeArray mTemporaries;
GrowingIntArray mTempOffset, mTempSizes;
@ -515,6 +519,7 @@ protected:
void TempForwarding(void);
void RemoveUnusedInstructions(void);
bool GlobalConstantPropagation(void);
void BuildDominators(void);
void DisassembleDebug(const char* name);
};

View File

@ -1,5 +1,4 @@
#include "InterCodeGenerator.h"
#include <crtdbg.h>
InterCodeGenerator::InterCodeGenerator(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker), mForceNativeCode(false)
@ -648,7 +647,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock);
vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock);
if (exp->mToken == TK_ASSIGN || !(vl.mType->mType == IT_POINTER && vr.mType->IsIntegerType() && (exp->mToken == TK_ASSIGN_ADD || exp->mToken == TK_ASSIGN_SUB)))
if (exp->mToken == TK_ASSIGN || !(vl.mType->mType == DT_TYPE_POINTER && vr.mType->IsIntegerType() && (exp->mToken == TK_ASSIGN_ADD || exp->mToken == TK_ASSIGN_SUB)))
{
if (!vl.mType->CanAssign(vr.mType))
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
@ -2094,7 +2093,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
}
else if (data->mType == DT_CONST_INTEGER)
{
__int64 t = data->mInteger;
int64 t = data->mInteger;
for (int i = 0; i < data->mBase->mSize; i++)
{
dp[offset + i] = uint8(t & 0xff);
@ -2103,7 +2102,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
}
else if (data->mType == DT_CONST_ADDRESS)
{
__int64 t = data->mInteger;
int64 t = data->mInteger;
dp[offset + 0] = uint8(t & 0xff);
dp[offset + 1] = t >> 8;
}
@ -2111,7 +2110,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
{
union { float f; uint32 i; } cast;
cast.f = data->mNumber;
__int64 t = cast.i;
int64 t = cast.i;
for (int i = 0; i < 4; i++)
{
dp[offset + i] = t & 0xff;
@ -2255,8 +2254,6 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
exitBlock->Append(ins);
exitBlock->Close(nullptr, nullptr);
_CrtCheckMemory();
proc->Close();
return proc;

View File

@ -1,11 +1,81 @@
#pragma once
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef signed char int8;
typedef signed short int16;
typedef signed short int32;
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef signed char int8;
typedef signed short int16;
typedef signed short int32;
#ifdef _WIN32
typedef __int64 int64;
typedef unsigned __int64 uint64;
#define MAXPATHLEN _MAX_PATH
#else
#include "linux/limits.h"
typedef long long int64;
typedef unsigned long long uint64;
#define _access access
#define _strdup strdup
#define MAXPATHLEN PATH_MAX
inline char* strcat_s(char* c, const char* d)
{
return strcat(c, d);
}
inline char* strcat_s(char* c, int n, const char* d)
{
return strcat(c, d);
}
inline char* strcpy_s(char* c, const char* d)
{
return strcpy(c, d);
}
inline char* strcpy_s(char* c, int n, const char* d)
{
return strcpy(c, d);
}
inline int fopen_s(FILE** f, const char* fname, const char* mode)
{
*f = fopen(fname, mode);
return *f ? 0 : -1;
}
inline char* _fullpath(char* absPath, const char* relPath, size_t maxLength)
{
return realpath(relPath, absPath);
}
inline int sprintf_s(char* buffer, const char* format, ...)
{
va_list args;
va_start(args, format);
int n = vsprintf(buffer, format, args);
va_end(args);
return n;
}
inline int sprintf_s(char* buffer, int size, const char* format, ...)
{
va_list args;
va_start(args, format);
int n = vsprintf(buffer, format, args);
va_end(args);
return n;
}
#endif
static const uint8 BC_REG_WORK = 0x03;
static const uint8 BC_REG_IP = 0x19;

View File

@ -2800,8 +2800,16 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
insl = NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, treg);
insh = NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, treg + 1);
LoadValueToReg(proc, sins1, treg, nullptr, nullptr);
LoadValueToReg(proc, sins0, treg, &insl, &insh);
if (sins1->mTTemp == ins->mTTemp)
{
LoadValueToReg(proc, sins1, treg, nullptr, nullptr);
LoadValueToReg(proc, sins0, treg, &insl, &insh);
}
else
{
LoadValueToReg(proc, sins0, treg, nullptr, nullptr);
LoadValueToReg(proc, sins1, treg, &insl, &insh);
}
}
else if (sins1)
{
@ -3385,6 +3393,9 @@ void NativeCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, NativeCodePro
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
NativeCodeGenerator::Runtime& frx(nproc->mGenerator->ResolveRuntime(Ident::Unique("fsplita")));
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frx.mOffset, frx.mLinkerObject, NCIF_RUNTIME));
if (ins->mOperator == IA_FLOOR)
{
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ffloor")));
@ -4813,6 +4824,7 @@ NativeCodeBasicBlock::NativeCodeBasicBlock(void)
mCopied = false;
mKnownShortBranch = false;
mBypassed = false;
mAssembled = false;
}
NativeCodeBasicBlock::~NativeCodeBasicBlock(void)
@ -4906,8 +4918,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
tblocks[0] = entryBlock;
exitBlock = new NativeCodeBasicBlock();
exitBlock->mNoFrame = mNoFrame;
exitBlock = AllocateBlock();
mBlocks.Push(exitBlock);
if (!proc->mLeafProcedure)
@ -4960,7 +4971,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
CompileInterBlock(proc, proc->mBlocks[0], entryBlock);
#if 1
#if 0
bool changed;
do
{
@ -5119,6 +5130,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
else if (i + 2 < iblock->mInstructions.Size() &&
ins->mOperandSize >= 2 &&
iblock->mInstructions[i + 1]->mCode == IC_LOAD && iblock->mInstructions[i + 1]->mOperandSize == 2 &&
iblock->mInstructions[i + 1]->mTTemp != ins->mTTemp &&
iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR &&
iblock->mInstructions[i + 2]->mSTemp[0] == iblock->mInstructions[i + 1]->mTTemp && iblock->mInstructions[i + 2]->mSFinal[0] &&
iblock->mInstructions[i + 2]->mSTemp[1] == ins->mTTemp && iblock->mInstructions[i + 2]->mSFinal[1])
@ -5129,6 +5141,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
else if (i + 2 < iblock->mInstructions.Size() &&
ins->mOperandSize >= 2 &&
iblock->mInstructions[i + 1]->mCode == IC_LOAD && iblock->mInstructions[i + 1]->mOperandSize == 2 &&
iblock->mInstructions[i + 1]->mTTemp != ins->mTTemp &&
iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR &&
iblock->mInstructions[i + 2]->mSTemp[1] == iblock->mInstructions[i + 1]->mTTemp && iblock->mInstructions[i + 2]->mSFinal[1] &&
iblock->mInstructions[i + 2]->mSTemp[0] == ins->mTTemp && iblock->mInstructions[i + 2]->mSFinal[0])

View File

@ -2,7 +2,7 @@
#include <assert.h>
typedef unsigned __int32 uint32;
#include "MachineTypes.h"
class NumberSet
{
@ -35,7 +35,7 @@ public:
int Size(void) { return size; }
};
__forceinline NumberSet& NumberSet::operator+=(int elem)
inline NumberSet& NumberSet::operator+=(int elem)
{
assert(elem >= 0 && elem < size);
bits[elem >> 5] |= (1UL << (elem & 31));
@ -43,7 +43,7 @@ __forceinline NumberSet& NumberSet::operator+=(int elem)
return *this;
}
__forceinline NumberSet& NumberSet::operator-=(int elem)
inline NumberSet& NumberSet::operator-=(int elem)
{
assert(elem >= 0 && elem < size);
bits[elem >> 5] &= ~(1UL << (elem & 31));
@ -51,7 +51,7 @@ __forceinline NumberSet& NumberSet::operator-=(int elem)
return *this;
}
__forceinline bool NumberSet::operator[](int elem) const
inline bool NumberSet::operator[](int elem) const
{
assert(elem >= 0 && elem < size);
return (bits[elem >> 5] & (1UL << (elem & 31))) != 0;
@ -88,14 +88,14 @@ public:
int Index(int elem);
};
__forceinline bool FastNumberSet::operator[](int elem)
inline bool FastNumberSet::operator[](int elem)
{
uint32 dw = buffer[size + elem];
return (dw < uint32(num) && buffer[dw] == elem);
}
__forceinline FastNumberSet& FastNumberSet::operator+=(int elem)
inline FastNumberSet& FastNumberSet::operator+=(int elem)
{
uint32 dw = buffer[size + elem];
@ -109,7 +109,7 @@ __forceinline FastNumberSet& FastNumberSet::operator+=(int elem)
return *this;
}
__forceinline FastNumberSet& FastNumberSet::operator-=(int elem)
inline FastNumberSet& FastNumberSet::operator-=(int elem)
{
uint32 dw = buffer[size + elem];
@ -123,7 +123,7 @@ __forceinline FastNumberSet& FastNumberSet::operator-=(int elem)
return *this;
}
__forceinline int FastNumberSet::Element(int i)
inline int FastNumberSet::Element(int i)
{
if (i < num)
return buffer[i];

View File

@ -650,7 +650,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
else
{
exp = ParseRExpression();
if (dtype->mType == DT_TYPE_POINTER && exp->mDecType && exp->mDecType->mType == DT_TYPE_ARRAY)
if (dtype->mType == DT_TYPE_POINTER && exp->mDecType && exp->mDecType->mType == DT_TYPE_ARRAY && exp->mType == EX_CONSTANT)
{
Declaration* ndec = new Declaration(exp->mDecValue->mLocation, DT_CONST_POINTER);
ndec->mValue = exp;

View File

@ -65,6 +65,8 @@ bool SourceFile::Open(const char* name, const char* path)
if (!fopen_s(&mFile, fname, "r"))
{
printf("<%s>\n", fname);
_fullpath(mFileName, fname, sizeof(mFileName));
char* p = mFileName;
while (*p)

View File

@ -2,11 +2,12 @@
#include "Errors.h"
#include <stdio.h>
#include "MachineTypes.h"
class SourceFile
{
public:
char mFileName[200];
char mFileName[MAXPATHLEN];
SourceFile * mUp, * mNext;
Location mLocation;
@ -25,7 +26,7 @@ protected:
class SourcePath
{
public:
char mPathName[200];
char mPathName[MAXPATHLEN];
SourcePath* mNext;

View File

@ -3,6 +3,7 @@
#include <math.h>
#include <string.h>
#include <assert.h>
#include "MachineTypes.h"
const char* TokenNames[] = {
@ -649,7 +650,7 @@ void Scanner::NextRawToken(void)
if (mAssemblerMode)
{
int n = 0;
__int64 mant = 0;
int64 mant = 0;
while (NextChar())
{
if (mTokenChar >= '0' && mTokenChar <= '9')
@ -888,7 +889,7 @@ void Scanner::NextRawToken(void)
if (mAssemblerMode)
{
int n = 0;
__int64 mant = 0;
int64 mant = 0;
while (NextChar())
{
if (mTokenChar >= '0' && mTokenChar <= '9')
@ -1203,7 +1204,7 @@ bool Scanner::NextChar(void)
void Scanner::ParseNumberToken(void)
{
unsigned __int64 mant = (int)mTokenChar - (int)'0';
uint64 mant = (int)mTokenChar - (int)'0';
NextChar();

View File

@ -1,7 +1,10 @@
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#endif
#include "Compiler.h"
#ifdef _WIN32
bool GetProductAndVersion(char* strProductName, char* strProductVersion)
{
// get the filename of the executable containing the version resource
@ -46,7 +49,7 @@ bool GetProductAndVersion(char* strProductName, char* strProductVersion)
return true;
}
#endif
int main(int argc, const char** argv)
{
@ -58,13 +61,17 @@ int main(int argc, const char** argv)
char basePath[200], crtPath[200], includePath[200], targetPath[200];
char strProductName[100], strProductVersion[200];
#ifdef _WIN32
if (GetProductAndVersion(strProductName, strProductVersion))
{
printf("Starting %s %s\n", strProductName, strProductVersion);
}
DWORD length = ::GetModuleFileNameA(NULL, basePath, sizeof(basePath));
#else
strcpy(basePath, argv[0]);
int length = strlen(basePath);
#endif
while (length > 0 && basePath[length - 1] != '/' && basePath[length - 1] != '\\')
length--;