More autoinline optimizations

This commit is contained in:
drmortalwombat 2021-10-10 17:14:12 +02:00
parent 5e02e48c5a
commit 11af372509
31 changed files with 1084 additions and 109 deletions

View File

@ -18,6 +18,13 @@ if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint32.c ..\release\oscar64 -e -n testint32.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -e testint16mul.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint16mul.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e recursiontest.c ..\release\oscar64 -e recursiontest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error

23
autotest/testint16mul.c Normal file
View File

@ -0,0 +1,23 @@
#include <assert.h>
int mul[32][32];
int main(void)
{
for(int i=0; i<32; i++)
for(int j=0; j<32; j++)
mul[i][j] = i * j;
#assign xi 0
#repeat
for(int j=0; j<32; j++)
{
assert(mul[xi][j] == xi * j);
assert(mul[j][xi] == j * xi);
}
#assign xi xi + 1
#until xi == 32
return 0;
}

25
include/c64/joystick.c Normal file
View File

@ -0,0 +1,25 @@
#include "joystick.h"
signed char joyx[2], joyy[2];
bool joyb[2];
void joy_poll(char n)
{
char b = ((char *)0xdc00)[n];
if (!(b & 1))
joyy[n] = -1;
else if (!(b & 2))
joyy[n] = 1;
else
joyy[n] = 0;
if (!(b & 4))
joyx[n] = -1;
else if (!(b & 8))
joyx[n] = 1;
else
joyx[n] = 0;
joyb[n] = (b & 0x10) == 0;
}

11
include/c64/joystick.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef C64_JOYSTICK_H
#define C64_JOYSTICK_H
extern signed char joyx[2], joyy[2];
extern bool joyb[2];
void joy_poll(char n);
#pragma compile("joystick.c")
#endif

View File

@ -6,6 +6,8 @@ void StackStart, StackEnd, BSSStart, BSSEnd;
#pragma section(stack, 0x0000, StackStart, StackEnd) #pragma section(stack, 0x0000, StackStart, StackEnd)
#pragma section(bss, 0x0000, BSSStart, BSSEnd) #pragma section(bss, 0x0000, BSSStart, BSSEnd)
char spentry;
int main(void); int main(void);
__asm startup __asm startup
@ -25,6 +27,9 @@ __asm startup
// Clear BSS Segment // Clear BSS Segment
tsx
stx spentry
lda #<BSSStart lda #<BSSStart
sta ip sta ip
lda #>BSSStart lda #>BSSStart
@ -202,13 +207,18 @@ __asm divmod
// byte / byte // byte / byte
BB: BB:
lda #0 lda #0
ldx #8 ldx #4
asl accu asl accu
LBB1: rol LBB1: rol
cmp tmp cmp tmp
bcc WBB1 bcc WBB1
sbc tmp sbc tmp
WBB1: rol accu WBB1: rol accu
rol
cmp tmp
bcc WBB2
sbc tmp
WBB2: rol accu
dex dex
bne LBB1 bne LBB1
sta tmp + 2 sta tmp + 2
@ -330,26 +340,55 @@ W1: dey
__asm mul16 __asm mul16
{ {
lda #0 ldy #0
sta tmp + 2 sty tmp + 3
sta tmp + 3
ldx #16 lda tmp
L1: lsr tmp + 1 ldx tmp + 1
ror tmp beq W1
bcc W1
sec
ror
bcc L2
L1:
tax
clc clc
lda tmp + 2 tya
adc accu adc accu
sta tmp + 2 tay
lda tmp + 3 lda tmp + 3
adc accu + 1 adc accu + 1
sta tmp + 3 sta tmp + 3
W1: asl accu txa
L2:
asl accu + 0
rol accu + 1 rol accu + 1
dex lsr
bcc L2
bne L1 bne L1
rts
lda tmp + 1
W1:
lsr
bcc L4
L3:
tax
clc
tya
adc accu
tay
lda tmp + 3
adc accu + 1
sta tmp + 3
txa
L4:
asl accu + 0
rol accu + 1
lsr
bcs L3
bne L4
sty tmp + 2
} }
__asm mul32 __asm mul32
@ -1010,6 +1049,25 @@ __asm inp_lea_abs
#pragma bytecode(BC_LEA_ABS, inp_lea_abs) #pragma bytecode(BC_LEA_ABS, inp_lea_abs)
__asm inp_lea_abs_index
{
lda (ip), y
tax
iny
clc
lda $00, x
adc (ip), y
sta addr
iny
lda $01, x
adc (ip), y
sta addr + 1
iny
jmp startup.exec
}
#pragma bytecode(BC_LEA_ABS_INDEX, inp_lea_abs_index)
__asm inp_load_local_16 __asm inp_load_local_16
{ {
lda (ip), y lda (ip), y

View File

@ -13,6 +13,7 @@
#define sregs 0x43 #define sregs 0x43
#define regs 0x53 #define regs 0x53
extern char spentry;
enum ByteCode enum ByteCode
{ {
@ -42,6 +43,7 @@ enum ByteCode
BC_STORE_ABS_32, BC_STORE_ABS_32,
BC_LEA_ABS, BC_LEA_ABS,
BC_LEA_ABS_INDEX,
BC_LOAD_LOCAL_8, BC_LOAD_LOCAL_8,
BC_LOAD_LOCAL_16, BC_LOAD_LOCAL_16,

View File

@ -92,7 +92,7 @@ struct sinfo
bool sign, left, prefix; bool sign, left, prefix;
}; };
int nformi(const sinfo * si, char * str, int v, bool s) inline int nformi(const sinfo * si, char * str, int v, bool s)
{ {
char * sp = str; char * sp = str;

View File

@ -2,6 +2,7 @@
#include "string.h" #include "string.h"
#include "stdio.h" #include "stdio.h"
#include "math.h" #include "math.h"
#include "crt.h"
void itoa(int n, char * s, unsigned radix) void itoa(int n, char * s, unsigned radix)
{ {
@ -312,8 +313,12 @@ void exit(int status)
sta accu + 0 sta accu + 0
lda status + 1 lda status + 1
sta accu + 1 sta accu + 1
pla ldx spentry
pla txs
lda #$4c
sta $54
lda #0
sta $13
} }
} }

View File

@ -13,6 +13,10 @@ char * strcpy(char * dst, const char * src)
ldy #0 ldy #0
L1: lda (src), y L1: lda (src), y
sta (dst), y
beq W1
iny
lda (src), y
sta (dst), y sta (dst), y
beq W1 beq W1
iny iny
@ -21,7 +25,6 @@ char * strcpy(char * dst, const char * src)
inc dst + 1 inc dst + 1
bne L1 bne L1
W1: W1:
rts
} }
} }
@ -57,17 +60,18 @@ int strcmp(const char * ptr1, const char * ptr2)
W2: bcs gt W2: bcs gt
lda #$ff lda #$ff
sta accu sta accu
sta accu + 1 bmi E
rts
gt: lda #$01 gt: lda #$01
sta accu sta accu
lda #$00 lda #$00
sta accu + 1 beq E
rts
W1: cmp (ptr2), y W1: cmp (ptr2), y
bne W2 bne W2
lda #$00 lda #$00
sta accu sta accu
E:
sta accu + 1 sta accu + 1
} }
} }

View File

@ -1,9 +1,9 @@
#ifndef STRING_H #ifndef STRING_H
#define STRING_H #define STRING_H
__fastcall char * strcpy(char * dst, const char * src); char * strcpy(char * dst, const char * src);
__fastcall int strcmp(const char * ptr1, const char * ptr2); int strcmp(const char * ptr1, const char * ptr2);
int strlen(const char * str); int strlen(const char * str);

View File

@ -267,4 +267,12 @@ public:
{ {
Grow(size, true); Grow(size, true);
} }
int IndexOf(const T& t)
{
for (int i = 0; i < size; i++)
if (array[i] == t)
return i;
return -1;
}
}; };

View File

@ -206,6 +206,8 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
return true; return true;
if (mCode == BC_JSR || mCode == BC_CALL) if (mCode == BC_JSR || mCode == BC_CALL)
return true; return true;
if (mCode == BC_LEA_ABS_INDEX)
return true;
} }
return false; return false;
@ -293,6 +295,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
break; break;
case BC_LEA_ABS: case BC_LEA_ABS:
case BC_LEA_ABS_INDEX:
block->PutCode(generator, mCode); block->PutByte(mRegister); block->PutCode(generator, mCode); block->PutByte(mRegister);
if (mRelocate) if (mRelocate)
{ {
@ -3261,6 +3264,23 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
{ {
if (i + 3 < mIns.Size())
{
if (
mIns[i + 0].mCode == BC_LEA_ABS && mIns[i + 0].mRegister == BC_REG_ACCU &&
mIns[i + 1].mCode == BC_BINOP_ADDR_16 &&
mIns[i + 2].mCode == BC_ADDR_REG && mIns[i + 2].mRegister == BC_REG_ACCU &&
mIns[i + 3].ChangesAccu())
{
mIns[i + 0].mCode = BC_LEA_ABS_INDEX;
mIns[i + 0].mRegister = mIns[i + 1].mRegister;
mIns[i + 0].mRegisterFinal = mIns[i + 1].mRegisterFinal;
mIns[i + 1].mCode = BC_NOP;
mIns[i + 2].mCode = BC_NOP;
progress = true;
}
}
if (i + 2 < mIns.Size()) if (i + 2 < mIns.Size())
{ {
if (mIns[i].mCode == BC_LOAD_LOCAL_16 && if (mIns[i].mCode == BC_LOAD_LOCAL_16 &&
@ -3403,6 +3423,15 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 1].mRegister = mIns[i + 0].mRegister; mIns[i + 1].mRegister = mIns[i + 0].mRegister;
progress = true; progress = true;
} }
else if (
mIns[i + 0].mCode == BC_LOAD_REG_8 &&
mIns[i + 1].mCode == BC_STORE_REG_8 &&
mIns[i + 2].mCode == BC_LOAD_REG_8 && mIns[i + 1].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal)
{
mIns[i + 1].mCode = BC_NOP;
mIns[i + 2].mCode = BC_NOP;
progress = true;
}
} }
if (i + 1 < mIns.Size()) if (i + 1 < mIns.Size())

View File

@ -32,6 +32,7 @@ enum ByteCode
BC_STORE_ABS_32, BC_STORE_ABS_32,
BC_LEA_ABS, BC_LEA_ABS,
BC_LEA_ABS_INDEX,
BC_LOAD_LOCAL_8, BC_LOAD_LOCAL_8,
BC_LOAD_LOCAL_16, BC_LOAD_LOCAL_16,

View File

@ -19,6 +19,7 @@ Compiler::Compiler(void)
mInterCodeGenerator = new InterCodeGenerator(mErrors, mLinker); mInterCodeGenerator = new InterCodeGenerator(mErrors, mLinker);
mNativeCodeGenerator = new NativeCodeGenerator(mErrors, mLinker); mNativeCodeGenerator = new NativeCodeGenerator(mErrors, mLinker);
mInterCodeModule = new InterCodeModule(); mInterCodeModule = new InterCodeModule();
mGlobalAnalyzer = new GlobalAnalyzer(mErrors, mLinker);
mCompilationUnits->mLinker = mLinker; mCompilationUnits->mLinker = mLinker;
@ -156,6 +157,11 @@ bool Compiler::GenerateCode(void)
dcrtstart->mSection = sectionStartup; dcrtstart->mSection = sectionStartup;
mGlobalAnalyzer->AnalyzeAssembler(dcrtstart->mValue, nullptr);
mGlobalAnalyzer->DumpCallGraph();
mGlobalAnalyzer->AutoInline();
mGlobalAnalyzer->DumpCallGraph();
mInterCodeGenerator->mForceNativeCode = mNativeCode; mInterCodeGenerator->mForceNativeCode = mNativeCode;
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr);

View File

@ -6,6 +6,7 @@
#include "ByteCodeGenerator.h" #include "ByteCodeGenerator.h"
#include "NativeCodeGenerator.h" #include "NativeCodeGenerator.h"
#include "InterCodeGenerator.h" #include "InterCodeGenerator.h"
#include "GlobalAnalyzer.h"
#include "Linker.h" #include "Linker.h"
class Compiler class Compiler
@ -22,6 +23,7 @@ public:
NativeCodeGenerator* mNativeCodeGenerator; NativeCodeGenerator* mNativeCodeGenerator;
InterCodeGenerator* mInterCodeGenerator; InterCodeGenerator* mInterCodeGenerator;
InterCodeModule* mInterCodeModule; InterCodeModule* mInterCodeModule;
GlobalAnalyzer* mGlobalAnalyzer;
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions; GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;

View File

@ -337,7 +337,7 @@ Expression* Expression::ConstantFold(void)
} }
Declaration::Declaration(const Location& loc, DecType type) Declaration::Declaration(const Location& loc, DecType type)
: mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr) : mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr)
{} {}
Declaration::~Declaration(void) Declaration::~Declaration(void)

View File

@ -4,6 +4,7 @@
#include "Scanner.h" #include "Scanner.h"
#include "MachineTypes.h" #include "MachineTypes.h"
#include "Assembler.h" #include "Assembler.h"
#include "Array.h"
class LinkerObject; class LinkerObject;
class LinkerSection; class LinkerSection;
@ -63,6 +64,14 @@ static const uint32 DTF_SECTION_START = 0x00001000;
static const uint32 DTF_SECTION_END = 0x00002000; static const uint32 DTF_SECTION_END = 0x00002000;
static const uint32 DTF_FASTCALL = 0x00004000; static const uint32 DTF_FASTCALL = 0x00004000;
static const uint32 DTF_INLINE = 0x00008000; static const uint32 DTF_INLINE = 0x00008000;
static const uint32 DTF_ANALYZED = 0x00010000;
static const uint32 DTF_REQUEST_INLINE = 0x00020000;
static const uint32 DTF_FUNC_VARIABLE = 0x00040000;
static const uint32 DTF_FUNC_ASSEMBLER = 0x00080000;
static const uint32 DTF_FUNC_RECURSIVE = 0x00100000;
static const uint32 DTF_FUNC_ANALYZING = 0x00200000;
class Declaration; class Declaration;
@ -156,7 +165,7 @@ public:
Declaration* mBase, *mParams, * mNext; Declaration* mBase, *mParams, * mNext;
Expression* mValue; Expression* mValue;
DeclarationScope* mScope; DeclarationScope* mScope;
int mOffset, mSize, mVarIndex, mNumVars; int mOffset, mSize, mVarIndex, mNumVars, mComplexity;
int64 mInteger; int64 mInteger;
double mNumber; double mNumber;
uint32 mFlags; uint32 mFlags;
@ -165,6 +174,8 @@ public:
const uint8 * mData; const uint8 * mData;
LinkerObject * mLinkerObject; LinkerObject * mLinkerObject;
GrowingArray<Declaration*> mCallers, mCalled;
bool CanAssign(const Declaration* fromType) const; bool CanAssign(const Declaration* fromType) const;
bool IsSame(const Declaration* dec) const; bool IsSame(const Declaration* dec) const;
bool IsSubType(const Declaration* dec) const; bool IsSubType(const Declaration* dec) const;

View File

@ -20,6 +20,11 @@ const char* ByteCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodePro
return "ADDR"; return "ADDR";
else if (tmp == BC_REG_ACCU) else if (tmp == BC_REG_ACCU)
return "ACCU"; return "ACCU";
else if (tmp >= BC_REG_FPARAMS && tmp <= BC_REG_FPARAMS + 7)
{
sprintf_s(buffer, 10, "P%d", tmp - BC_REG_FPARAMS);
return buffer;
}
else if (proc && tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize) else if (proc && tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize)
{ {
int i = 0; int i = 0;
@ -152,6 +157,11 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
i += 3; i += 3;
break; break;
case BC_LEA_ABS_INDEX:
fprintf(file, "LEAX\tADDR, %s + %s", AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker), TempName(memory[start + i + 0], tbuffer, proc));
i += 3;
break;
case BC_STORE_ABS_8: case BC_STORE_ABS_8:
fprintf(file, "MOVB\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc)); fprintf(file, "MOVB\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc));
i += 3; i += 3;
@ -639,7 +649,7 @@ const char* NativeCodeDisassembler::AddrName(int addr, char* buffer, Linker* lin
LinkerObject* obj = linker->FindObjectByAddr(addr); LinkerObject* obj = linker->FindObjectByAddr(addr);
if (obj && obj->mIdent) if (obj && obj->mIdent)
{ {
sprintf_s(buffer, 40, "%s + %d", obj->mIdent->mString, addr - obj->mAddress); sprintf_s(buffer, 40, "$%04x ; (%s + %d)", addr, obj->mIdent->mString, addr - obj->mAddress);
return buffer; return buffer;
} }
} }
@ -671,6 +681,11 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP
sprintf_s(buffer, 10, "IP + %d", tmp - BC_REG_IP); sprintf_s(buffer, 10, "IP + %d", tmp - BC_REG_IP);
return buffer; return buffer;
} }
else if (tmp >= BC_REG_FPARAMS && tmp <= BC_REG_FPARAMS + 7)
{
sprintf_s(buffer, 10, "P%d", tmp - BC_REG_FPARAMS);
return buffer;
}
else if (tmp >= BC_REG_LOCALS && tmp <= BC_REG_LOCALS + 3) else if (tmp >= BC_REG_LOCALS && tmp <= BC_REG_LOCALS + 3)
{ {
sprintf_s(buffer, 10, "FP + %d", tmp - BC_REG_LOCALS); sprintf_s(buffer, 10, "FP + %d", tmp - BC_REG_LOCALS);

View File

@ -633,7 +633,7 @@ int Emulator::Emulate(int startIP)
break; break;
} }
if ((trace & 1) && ip == 0x081f) if ((trace & 1) && ip == 0x0850)
{ {
int accu = mMemory[BC_REG_ACCU] + 256 * mMemory[BC_REG_ACCU + 1]; int accu = mMemory[BC_REG_ACCU] + 256 * mMemory[BC_REG_ACCU + 1];
int ptr = mMemory[BC_REG_ADDR] + 256 * mMemory[BC_REG_ADDR + 1]; int ptr = mMemory[BC_REG_ADDR] + 256 * mMemory[BC_REG_ADDR + 1];

400
oscar64/GlobalAnalyzer.cpp Normal file
View File

@ -0,0 +1,400 @@
#include "GlobalAnalyzer.h"
GlobalAnalyzer::GlobalAnalyzer(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker), mCalledFunctions(nullptr), mCallingFunctions(nullptr), mVariableFunctions(nullptr), mFunctions(nullptr)
{
}
GlobalAnalyzer::~GlobalAnalyzer(void)
{
}
void GlobalAnalyzer::DumpCallGraph(void)
{
printf("------------------------------\n");
for (int i = 0; i < mFunctions.Size(); i++)
{
GrowingArray<Declaration*> decs(nullptr);
GrowingArray<int> calls(0);
Declaration* from = mFunctions[i];
for (int j = 0; j < from->mCalled.Size(); j++)
{
Declaration* to = from->mCalled[j];
int k = decs.IndexOf(to);
if (k == -1)
{
decs.Push(to);
calls.Push(1);
}
else
calls[k]++;
}
if (decs.Size() > 0)
{
for (int j = 0; j < decs.Size(); j++)
{
printf("CALL %s[%d] -> %d -> %s[%d]\n", from->mIdent->mString, from->mComplexity, calls[j], decs[j]->mIdent->mString, decs[j]->mComplexity);
}
}
else
{
printf("LEAF %d -> %s[%d]\n", from->mCallers.Size(), from->mIdent->mString, from->mComplexity );
}
}
}
void GlobalAnalyzer::AutoInline(void)
{
bool changed = false;
do
{
changed = false;
for (int i = 0; i < mFunctions.Size(); i++)
{
Declaration* f = mFunctions[i];
if (!(f->mFlags & DTF_INLINE) && !(f->mBase->mFlags & DTF_VARIADIC) && !(f->mFlags & DTF_FUNC_VARIABLE) && !(f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_INTRINSIC) && !(f->mFlags & DTF_FUNC_RECURSIVE))
{
int nparams = 0;
Declaration* dec = f->mParams;
while (dec)
{
nparams++;
dec = dec->mNext;
}
int cost = (f->mComplexity - 20 * nparams);
if (cost * (f->mCallers.Size() - 1) <= 0 || (f->mFlags & DTF_REQUEST_INLINE))
//if (cost * (f->mCallers.Size() - 1) <= 1000 || (f->mFlags & DTF_REQUEST_INLINE))
{
printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size());
f->mFlags |= DTF_INLINE;
for (int j = 0; j < f->mCallers.Size(); j++)
{
Declaration* cf = f->mCallers[j];
int sk = 0, dk = 0;
while (sk < cf->mCalled.Size())
{
if (cf->mCalled[sk] == f)
{
cf->mComplexity += cost;
for (int m = 0; m < f->mCalled.Size(); m++)
{
cf->mCalled.Push(f->mCalled[m]);
f->mCalled[m]->mCallers.Push(cf);
}
}
else
cf->mCalled[dk++] = cf->mCalled[sk];
sk++;
}
cf->mCalled.SetSize(dk);
}
changed = true;
}
}
}
} while (changed);
for (int i = 0; i < mFunctions.Size(); i++)
{
Declaration* f = mFunctions[i];
if (!(f->mFlags & DTF_INLINE) && !(f->mBase->mFlags & DTF_VARIADIC) && !(f->mFlags & DTF_FUNC_VARIABLE) && !(f->mFlags & DTF_INTRINSIC) && f->mCalled.Size() == 0)
{
int nparams = 0;
Declaration* dec = f->mParams;
while (dec)
{
nparams += dec->mSize;
dec = dec->mNext;
}
if (nparams <= 8)
{
f->mBase->mFlags |= DTF_FASTCALL;
printf("FASTCALL %s\n", f->mIdent->mString);
}
}
}
}
void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
{
if (dec->mFlags & DTF_FUNC_ANALYZING)
dec->mFlags |= DTF_FUNC_RECURSIVE;
if (!(dec->mFlags & DTF_ANALYZED))
{
dec->mFlags |= DTF_FUNC_ANALYZING;
mFunctions.Push(dec);
dec->mFlags |= DTF_ANALYZED;
if (dec->mFlags & DTF_INTRINSIC)
;
else if (dec->mFlags & DTF_DEFINED)
Analyze(exp, dec);
else
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mIdent->mString);
dec->mFlags &= ~DTF_FUNC_ANALYZING;
}
}
void GlobalAnalyzer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
{
while (exp)
{
if (procDec)
procDec->mComplexity += 2;
if (exp->mLeft)
{
Declaration* adec = exp->mLeft->mDecValue;
if (adec->mType == DT_LABEL_REF)
{
}
else if (adec->mType == DT_VARIABLE_REF)
{
if (adec->mBase->mFlags & DTF_GLOBAL)
AnalyzeGlobalVariable(adec->mBase);
}
else if (adec->mType == DT_LABEL)
{
}
else if (adec->mType == DT_VARIABLE)
{
if (adec->mFlags & DTF_GLOBAL)
AnalyzeGlobalVariable(adec);
}
else if (adec->mType == DT_FUNCTION_REF)
{
AnalyzeProcedure(adec->mBase->mValue, adec->mBase);
RegisterProc(adec->mBase);
}
else if (adec->mType == DT_CONST_FUNCTION)
{
AnalyzeProcedure(adec->mValue, adec);
RegisterCall(adec, procDec);
}
}
exp = exp->mRight;
}
}
void GlobalAnalyzer::AnalyzeGlobalVariable(Declaration* dec)
{
if (!(dec->mFlags & DTF_ANALYZED))
{
dec->mFlags |= DTF_ANALYZED;
if (dec->mValue)
{
Analyze(dec->mValue, dec);
}
}
}
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
{
Declaration* ldec, * rdec;
procDec->mComplexity += 10;
switch (exp->mType)
{
case EX_ERROR:
case EX_VOID:
break;
case EX_CONSTANT:
if (exp->mDecValue->mType == DT_CONST_FUNCTION)
AnalyzeProcedure(exp->mDecValue->mValue, exp->mDecValue);
else if (exp->mDecValue->mType == DT_CONST_STRUCT)
{
Declaration* mdec = exp->mDecValue->mParams;
while (mdec)
{
if (mdec->mValue)
RegisterProc(Analyze(mdec->mValue, mdec));
mdec = mdec->mNext;
}
}
else if (exp->mDecValue->mType == DT_CONST_POINTER)
{
RegisterProc(Analyze(exp->mDecValue->mValue, procDec));
}
else if (exp->mDecValue->mType == DT_CONST_ASSEMBLER)
{
AnalyzeAssembler(exp->mDecValue->mValue, procDec);
}
return exp->mDecValue;
case EX_VARIABLE:
return exp->mDecValue;
case EX_ASSIGNMENT:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
RegisterProc(rdec);
break;
case EX_BINARY:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
break;
case EX_RELATIONAL:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
return TheBoolTypeDeclaration;
case EX_PREINCDEC:
return Analyze(exp->mLeft, procDec);
case EX_PREFIX:
break;
case EX_POSTFIX:
break;
case EX_POSTINCDEC:
return Analyze(exp->mLeft, procDec);
case EX_INDEX:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
return ldec->mBase;
case EX_QUALIFY:
Analyze(exp->mLeft, procDec);
return exp->mDecValue->mBase;
case EX_CALL:
ldec = Analyze(exp->mLeft, procDec);
RegisterCall(procDec, ldec);
if (exp->mRight)
RegisterProc(Analyze(exp->mRight, procDec));
break;
case EX_LIST:
RegisterProc(Analyze(exp->mLeft, procDec));
return Analyze(exp->mRight, procDec);
case EX_RETURN:
if (exp->mLeft)
RegisterProc(Analyze(exp->mLeft, procDec));
break;
case EX_SEQUENCE:
do
{
ldec = Analyze(exp->mLeft, procDec);
exp = exp->mRight;
} while (exp);
break;
case EX_WHILE:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
break;
case EX_IF:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight->mLeft, procDec);
if (exp->mRight->mRight)
rdec = Analyze(exp->mRight->mRight, procDec);
break;
case EX_ELSE:
break;
case EX_FOR:
if (exp->mLeft->mRight)
ldec = Analyze(exp->mLeft->mRight, procDec);
if (exp->mLeft->mLeft->mLeft)
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
if (exp->mLeft->mLeft->mRight)
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec);
break;
case EX_DO:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
break;
case EX_BREAK:
case EX_CONTINUE:
break;
case EX_TYPE:
break;
case EX_TYPECAST:
rdec = Analyze(exp->mRight, procDec);
break;
case EX_LOGICAL_AND:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
break;
case EX_LOGICAL_OR:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);
break;
case EX_LOGICAL_NOT:
ldec = Analyze(exp->mLeft, procDec);
break;
case EX_ASSEMBLER:
procDec->mFlags |= DTF_FUNC_ASSEMBLER;
AnalyzeAssembler(exp, procDec);
break;
case EX_UNDEFINED:
break;
case EX_SWITCH:
ldec = Analyze(exp->mLeft, procDec);
exp = exp->mRight;
while (exp)
{
if (exp->mLeft->mRight)
rdec = Analyze(exp->mLeft->mRight, procDec);
exp = exp->mRight;
}
break;
case EX_CASE:
break;
case EX_DEFAULT:
break;
case EX_CONDITIONAL:
ldec = Analyze(exp->mLeft, procDec);
RegisterProc(Analyze(exp->mRight->mLeft, procDec));
RegisterProc(Analyze(exp->mRight->mRight, procDec));
break;
}
return TheVoidTypeDeclaration;
}
void GlobalAnalyzer::RegisterCall(Declaration* from, Declaration* to)
{
if (from)
{
if (to->mType == DT_CONST_FUNCTION)
{
if (to->mCallers.Size() == 0)
mCalledFunctions.Push(to);
to->mCallers.Push(from);
if (from->mCalled.Size() == 0)
mCallingFunctions.Push(from);
from->mCalled.Push(to);
}
else if (to->mType == DT_TYPE_FUNCTION)
{
if (from->mCalled.Size() == 0)
mCallingFunctions.Push(from);
from->mCalled.Push(to);
}
}
}
void GlobalAnalyzer::RegisterProc(Declaration* to)
{
if (to->mType == DT_CONST_FUNCTION)
{
to->mFlags |= DTF_FUNC_VARIABLE;
mVariableFunctions.Push(to);
}
}

30
oscar64/GlobalAnalyzer.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include "Declaration.h"
#include "Linker.h"
class GlobalAnalyzer
{
public:
GlobalAnalyzer(Errors* errors, Linker* linker);
~GlobalAnalyzer(void);
void DumpCallGraph(void);
void AutoInline(void);
void AnalyzeProcedure(Expression* exp, Declaration* procDec);
void AnalyzeAssembler(Expression* exp, Declaration* procDec);
void AnalyzeGlobalVariable(Declaration* dec);
protected:
Errors* mErrors;
Linker* mLinker;
GrowingArray<Declaration*> mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions;
Declaration* Analyze(Expression* exp, Declaration* procDec);
void RegisterCall(Declaration* from, Declaration* to);
void RegisterProc(Declaration* to);
};

View File

@ -673,6 +673,8 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
case IT_POINTER: case IT_POINTER:
break; break;
default: default:
assert(ins->mSrc[1].mType == IT_INT8 || ins->mSrc[1].mType == IT_INT16 || ins->mSrc[1].mType == IT_INT32);
if (ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONSTANT && if (ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONSTANT &&
ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
{ {
@ -1199,10 +1201,12 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
switch (mCode) switch (mCode)
{ {
case IC_LOAD: case IC_LOAD:
case IC_CALL:
case IC_CALL_NATIVE:
if (mSrc[0].mTemp >= 0 && ctemps[mSrc[0].mTemp]) if (mSrc[0].mTemp >= 0 && ctemps[mSrc[0].mTemp])
{ {
InterInstruction* ains = ctemps[mSrc[0].mTemp]; InterInstruction* ains = ctemps[mSrc[0].mTemp];
mSrc[0].mIntConst = ains->mConst.mIntConst; mSrc[0].mIntConst += ains->mConst.mIntConst;
mSrc[0].mLinkerObject = ains->mConst.mLinkerObject; mSrc[0].mLinkerObject = ains->mConst.mLinkerObject;
mSrc[0].mVarIndex = ains->mConst.mVarIndex; mSrc[0].mVarIndex = ains->mConst.mVarIndex;
mSrc[0].mMemory = ains->mConst.mMemory; mSrc[0].mMemory = ains->mConst.mMemory;
@ -1214,7 +1218,7 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
if (mSrc[1].mTemp >= 0 && ctemps[mSrc[1].mTemp]) if (mSrc[1].mTemp >= 0 && ctemps[mSrc[1].mTemp])
{ {
InterInstruction* ains = ctemps[mSrc[1].mTemp]; InterInstruction* ains = ctemps[mSrc[1].mTemp];
mSrc[1].mIntConst = ains->mConst.mIntConst; mSrc[1].mIntConst += ains->mConst.mIntConst;
mSrc[1].mLinkerObject = ains->mConst.mLinkerObject; mSrc[1].mLinkerObject = ains->mConst.mLinkerObject;
mSrc[1].mVarIndex = ains->mConst.mVarIndex; mSrc[1].mVarIndex = ains->mConst.mVarIndex;
mSrc[1].mMemory = ains->mConst.mMemory; mSrc[1].mMemory = ains->mConst.mMemory;
@ -1732,6 +1736,11 @@ InterCodeBasicBlock::~InterCodeBasicBlock(void)
void InterCodeBasicBlock::Append(InterInstruction * code) void InterCodeBasicBlock::Append(InterInstruction * code)
{ {
if (code->mCode == IC_BINARY_OPERATOR)
{
assert(code->mSrc[1].mType != IT_POINTER);
}
assert(!(code->mInUse)); assert(!(code->mInUse));
code->mInUse = true; code->mInUse = true;
this->mInstructions.Push(code); this->mInstructions.Push(code);
@ -1843,7 +1852,7 @@ static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrA
if (ains->mCode == IC_CONSTANT) if (ains->mCode == IC_CONSTANT)
{ {
ins->mSrc[offset].mIntConst = ains->mConst.mIntConst; ins->mSrc[offset].mIntConst += ains->mConst.mIntConst;
ins->mSrc[offset].mLinkerObject = ains->mConst.mLinkerObject; ins->mSrc[offset].mLinkerObject = ains->mConst.mLinkerObject;
ins->mSrc[offset].mVarIndex = ains->mConst.mVarIndex; ins->mSrc[offset].mVarIndex = ains->mConst.mVarIndex;
ins->mSrc[offset].mMemory = ains->mConst.mMemory; ins->mSrc[offset].mMemory = ains->mConst.mMemory;
@ -1851,16 +1860,18 @@ static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrA
} }
else if (ains->mCode == IC_LEA && ains->mSrc[0].mTemp < 0 && ains->mSrc[1].mTemp >= 0 && tvalue[ains->mSrc[1].mTemp]) else if (ains->mCode == IC_LEA && ains->mSrc[0].mTemp < 0 && ains->mSrc[1].mTemp >= 0 && tvalue[ains->mSrc[1].mTemp])
{ {
ins->mSrc[offset].mIntConst = ains->mSrc[0].mIntConst; ins->mSrc[offset].mIntConst += ains->mSrc[0].mIntConst;
ins->mSrc[offset].mTemp = ains->mSrc[1].mTemp; ins->mSrc[offset].mTemp = ains->mSrc[1].mTemp;
} }
else if (ains->mCode == IC_BINARY_OPERATOR && ains->mOperator == IA_ADD && ains->mSrc[0].mTemp < 0 && ains->mSrc[1].mTemp >= 0 && tvalue[ains->mSrc[1].mTemp] && ains->mSrc[0].mIntConst >= 0) else if (ains->mCode == IC_BINARY_OPERATOR && ains->mOperator == IA_ADD && ains->mSrc[0].mTemp < 0 && ains->mSrc[1].mTemp >= 0 && tvalue[ains->mSrc[1].mTemp] && ains->mSrc[0].mIntConst >= 0)
{ {
assert(false);
ins->mSrc[offset].mIntConst = ains->mSrc[0].mIntConst; ins->mSrc[offset].mIntConst = ains->mSrc[0].mIntConst;
ins->mSrc[offset].mTemp = ains->mSrc[1].mTemp; ins->mSrc[offset].mTemp = ains->mSrc[1].mTemp;
} }
else if (ains->mCode == IC_BINARY_OPERATOR && ains->mOperator == IA_ADD && ains->mSrc[1].mTemp < 0 && ains->mSrc[0].mTemp >= 0 && tvalue[ains->mSrc[0].mTemp] && ains->mSrc[1].mIntConst >= 0) else if (ains->mCode == IC_BINARY_OPERATOR && ains->mOperator == IA_ADD && ains->mSrc[1].mTemp < 0 && ains->mSrc[0].mTemp >= 0 && tvalue[ains->mSrc[0].mTemp] && ains->mSrc[1].mIntConst >= 0)
{ {
assert(false);
ins->mSrc[offset].mIntConst = ains->mSrc[1].mIntConst; ins->mSrc[offset].mIntConst = ains->mSrc[1].mIntConst;
ins->mSrc[offset].mTemp = ains->mSrc[0].mTemp; ins->mSrc[offset].mTemp = ains->mSrc[0].mTemp;
} }
@ -3263,7 +3274,7 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
} }
} }
void InterCodeBasicBlock::CollectOuterFrame(int level, int& size, bool &inner, bool &inlineAssembler) void InterCodeBasicBlock::CollectOuterFrame(int level, int& size, bool &inner, bool &inlineAssembler, bool &byteCodeCall)
{ {
int i; int i;
@ -3295,10 +3306,12 @@ void InterCodeBasicBlock::CollectOuterFrame(int level, int& size, bool &inner, b
} }
else if (mInstructions[i]->mCode == IC_ASSEMBLER) else if (mInstructions[i]->mCode == IC_ASSEMBLER)
inlineAssembler = true; inlineAssembler = true;
else if (mInstructions[i]->mCode == IC_CALL)
byteCodeCall = true;
} }
if (mTrueJump) mTrueJump->CollectOuterFrame(level, size, inner, inlineAssembler); if (mTrueJump) mTrueJump->CollectOuterFrame(level, size, inner, inlineAssembler, byteCodeCall);
if (mFalseJump) mFalseJump->CollectOuterFrame(level, size, inner, inlineAssembler); if (mFalseJump) mFalseJump->CollectOuterFrame(level, size, inner, inlineAssembler, byteCodeCall);
} }
} }
@ -3450,6 +3463,14 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
if (mLoopHead && mNumEntries == 2 && (mTrueJump == this || mFalseJump == this)) if (mLoopHead && mNumEntries == 2 && (mTrueJump == this || mFalseJump == this))
{ {
bool hasCall = false;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins = mInstructions[i];
if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE)
hasCall = true;
}
for (int i = 0; i < mInstructions.Size(); i++) for (int i = 0; i < mInstructions.Size(); i++)
{ {
InterInstruction* ins = mInstructions[i]; InterInstruction* ins = mInstructions[i];
@ -3463,6 +3484,10 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
{ {
ins->mInvariant = false; ins->mInvariant = false;
} }
else if (ins->mSrc[0].mMemory == IM_GLOBAL && hasCall)
{
ins->mInvariant = false;
}
else else
{ {
for (int j = 0; j < mInstructions.Size(); j++) for (int j = 0; j < mInstructions.Size(); j++)
@ -4159,12 +4184,13 @@ void InterCodeProcedure::Close(void)
mHasDynamicStack = false; mHasDynamicStack = false;
mHasInlineAssembler = false; mHasInlineAssembler = false;
mCallsByteCode = false;
if (!mLeafProcedure) if (!mLeafProcedure)
{ {
int size = 0; int size = 0;
ResetVisited(); ResetVisited();
mEntryBlock->CollectOuterFrame(0, size, mHasDynamicStack, mHasInlineAssembler); mEntryBlock->CollectOuterFrame(0, size, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode);
mCommonFrameSize = size; mCommonFrameSize = size;
} }
else else
@ -4458,6 +4484,20 @@ bool InterCodeProcedure::GlobalConstantPropagation(void)
ResetVisited(); ResetVisited();
mEntryBlock->CollectConstTemps(ctemps, assignedTemps); mEntryBlock->CollectConstTemps(ctemps, assignedTemps);
FILE* file;
fopen_s(&file, "r:\\cldiss.txt", "a");
for (int i = 0; i < assignedTemps.Size(); i++)
{
if (assignedTemps[i])
{
if (ctemps[i])
fprintf(file, "%d, ", i);
}
}
fprintf(file, "\n");
fclose(file);
ResetVisited(); ResetVisited();
return mEntryBlock->PropagateConstTemps(ctemps); return mEntryBlock->PropagateConstTemps(ctemps);
} }

View File

@ -483,7 +483,7 @@ public:
void CollectVariables(GrowingVariableArray & globalVars, GrowingVariableArray & localVars); void CollectVariables(GrowingVariableArray & globalVars, GrowingVariableArray & localVars);
void MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars); void MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars);
void CollectOuterFrame(int level, int& size, bool& inner, bool& inlineAssembler); void CollectOuterFrame(int level, int& size, bool& inner, bool& inlineAssembler, bool& byteCodeCall);
bool IsLeafProcedure(void); bool IsLeafProcedure(void);
@ -511,7 +511,7 @@ public:
GrowingTypeArray mTemporaries; GrowingTypeArray mTemporaries;
GrowingIntArray mTempOffset, mTempSizes; GrowingIntArray mTempOffset, mTempSizes;
int mTempSize, mCommonFrameSize, mCallerSavedTemps; int mTempSize, mCommonFrameSize, mCallerSavedTemps;
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler; bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode;
GrowingInterCodeProcedurePtrArray mCalledFunctions; GrowingInterCodeProcedurePtrArray mCalledFunctions;
InterCodeModule * mModule; InterCodeModule * mModule;

View File

@ -756,7 +756,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (inlineMapper) if (inlineMapper)
{ {
ins->mConst.mMemory = IM_LOCAL; ins->mConst.mMemory = IM_LOCAL;
ins->mConst.mVarIndex = inlineMapper->mParams[dec->mOffset]; ins->mConst.mVarIndex = inlineMapper->mParams[dec->mVarIndex];
} }
else if (procType->mFlags & DTF_FASTCALL) else if (procType->mFlags & DTF_FASTCALL)
ins->mConst.mMemory = IM_FPARAM; ins->mConst.mMemory = IM_FPARAM;
@ -1298,13 +1298,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block->Append(cins); block->Append(cins);
ains->mCode = IC_BINARY_OPERATOR; InterType ttype = InterTypeOf(vdl.mType);
ains->mOperator = IA_ADD; if (ttype == IT_POINTER)
{
ains->mCode = IC_LEA;
}
else
{
ains->mCode = IC_BINARY_OPERATOR;
ains->mOperator = IA_ADD;
}
ains->mSrc[0].mType = cins->mDst.mType; ains->mSrc[0].mType = cins->mDst.mType;
ains->mSrc[0].mTemp = cins->mDst.mTemp; ains->mSrc[0].mTemp = cins->mDst.mTemp;
ains->mSrc[1].mType = InterTypeOf(vdl.mType); ains->mSrc[1].mType = ttype;
ains->mSrc[1].mTemp = vdl.mTemp; ains->mSrc[1].mTemp = vdl.mTemp;
ains->mDst.mType = ains->mSrc[1].mType; ains->mDst.mType = ttype;
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType); ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
block->Append(ains); block->Append(ains);
@ -1349,14 +1357,22 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a numeric value or pointer"); mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a numeric value or pointer");
block->Append(cins); block->Append(cins);
ains->mCode = IC_BINARY_OPERATOR; InterType ttype = InterTypeOf(vdl.mType);
ains->mOperator = IA_ADD; if (ttype == IT_POINTER)
{
ains->mCode = IC_LEA;
}
else
{
ains->mCode = IC_BINARY_OPERATOR;
ains->mOperator = IA_ADD;
}
ains->mSrc[0].mType = cins->mDst.mType; ains->mSrc[0].mType = cins->mDst.mType;
ains->mSrc[0].mTemp = cins->mDst.mTemp; ains->mSrc[0].mTemp = cins->mDst.mTemp;
ains->mSrc[1].mType = InterTypeOf(vdl.mType); ains->mSrc[1].mType = ttype;
ains->mSrc[1].mTemp = vdl.mTemp; ains->mSrc[1].mTemp = vdl.mTemp;
ains->mDst.mType = ains->mSrc[1].mType; ains->mDst.mType = ttype;
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType); ains->mDst.mTemp = proc->AddTemporary(ttype);
block->Append(ains); block->Append(ains);
sins->mCode = IC_STORE; sins->mCode = IC_STORE;
@ -1588,7 +1604,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
} }
else if (exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION && (exp->mLeft->mDecValue->mFlags & DTF_INLINE) && !(inlineMapper && inlineMapper->mDepth > 3)) else if (exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION && (exp->mLeft->mDecValue->mFlags & DTF_INLINE) && !(inlineMapper && inlineMapper->mDepth > 10))
{ {
Declaration* fdec = exp->mLeft->mDecValue; Declaration* fdec = exp->mLeft->mDecValue;
Expression* fexp = fdec->mValue; Expression* fexp = fdec->mValue;
@ -1965,13 +1981,18 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
Declaration* vdec = refvars[i]; Declaration* vdec = refvars[i];
if (vdec->mType == DT_ARGUMENT) if (vdec->mType == DT_ARGUMENT)
{ {
if (procType->mFlags & DTF_FASTCALL) vins->mConst.mVarIndex = vdec->mVarIndex;
if (inlineMapper)
{
vins->mConst.mMemory = IM_LOCAL;
vins->mConst.mVarIndex = inlineMapper->mParams[vdec->mVarIndex];
}
else if (procType->mFlags & DTF_FASTCALL)
vins->mConst.mMemory = IM_FPARAM; vins->mConst.mMemory = IM_FPARAM;
else else
vins->mConst.mMemory = IM_PARAM; vins->mConst.mMemory = IM_PARAM;
vins->mConst.mOperandSize = vdec->mSize; vins->mConst.mOperandSize = vdec->mSize;
vins->mConst.mIntConst = vdec->mOffset; vins->mConst.mIntConst = vdec->mOffset;
vins->mConst.mVarIndex = vdec->mVarIndex;
} }
block->Append(vins); block->Append(vins);

View File

@ -15,9 +15,10 @@ static const uint32 LIVE_CPU_REG_C = 0x00000008;
static const uint32 LIVE_CPU_REG_Z = 0x00000010; static const uint32 LIVE_CPU_REG_Z = 0x00000010;
static const uint32 LIVE_MEM = 0x00000020; static const uint32 LIVE_MEM = 0x00000020;
static int GlobalValueNumber = 0;
NativeRegisterData::NativeRegisterData(void) NativeRegisterData::NativeRegisterData(void)
: mMode(NRDM_UNKNOWN) : mMode(NRDM_UNKNOWN), mValue(GlobalValueNumber++)
{ {
} }
@ -25,6 +26,7 @@ NativeRegisterData::NativeRegisterData(void)
void NativeRegisterData::Reset(void) void NativeRegisterData::Reset(void)
{ {
mMode = NRDM_UNKNOWN; mMode = NRDM_UNKNOWN;
mValue = GlobalValueNumber++;
} }
void NativeRegisterDataSet::Reset(void) void NativeRegisterDataSet::Reset(void)
@ -39,10 +41,57 @@ void NativeRegisterDataSet::ResetZeroPage(int addr)
for (int i = 0; i < NUM_REGS; i++) for (int i = 0; i < NUM_REGS; i++)
{ {
if (mRegs[i].mMode == NRDM_ZERO_PAGE && mRegs[i].mValue == addr) if (mRegs[i].mMode == NRDM_ZERO_PAGE && mRegs[i].mValue == addr)
mRegs[i].mMode = NRDM_UNKNOWN; mRegs[i].Reset();
} }
} }
void NativeRegisterDataSet::Intersect(const NativeRegisterDataSet& set)
{
for (int i = 0; i < NUM_REGS; i++)
{
if (mRegs[i].mMode == NRDM_UNKNOWN)
{
if (set.mRegs[i].mMode != NRDM_UNKNOWN || mRegs[i].mValue != set.mRegs[i].mValue)
mRegs[i].Reset();
}
else if (mRegs[i].mMode == NRDM_IMMEDIATE)
{
if (set.mRegs[i].mMode != NRDM_IMMEDIATE || mRegs[i].mValue != set.mRegs[i].mValue)
mRegs[i].Reset();
}
else if (mRegs[i].mMode == NRDM_IMMEDIATE_ADDRESS)
{
if (set.mRegs[i].mMode != NRDM_IMMEDIATE_ADDRESS || mRegs[i].mValue != set.mRegs[i].mValue || mRegs[i].mLinkerObject != set.mRegs[i].mLinkerObject || mRegs[i].mFlags != set.mRegs[i].mFlags)
mRegs[i].Reset();
}
}
bool changed;
do
{
changed = false;
for (int i = 0; i < NUM_REGS; i++)
{
if (mRegs[i].mMode == NRDM_ZERO_PAGE)
{
if (set.mRegs[i].mMode != NRDM_ZERO_PAGE || mRegs[i].mValue != set.mRegs[i].mValue)
{
mRegs[i].Reset();
changed = true;
}
else if (mRegs[mRegs[i].mValue].mValue != set.mRegs[set.mRegs[i].mValue].mValue)
{
mRegs[i].Reset();
changed = true;
}
}
}
} while (changed);
}
NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, AsmInsMode mode, int address, LinkerObject* linkerObject, uint32 flags) NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, AsmInsMode mode, int address, LinkerObject* linkerObject, uint32 flags)
: mType(type), mMode(mode), mAddress(address), mLinkerObject(linkerObject), mFlags(flags) : mType(type), mMode(mode), mAddress(address), mLinkerObject(linkerObject), mFlags(flags)
{} {}
@ -448,7 +497,7 @@ bool NativeCodeInstruction::ChangesAccuAndFlag(void) const
return return
mType == ASMIT_LDA || mType == ASMIT_TXA || mType == ASMIT_TYA || mType == ASMIT_LDA || mType == ASMIT_TXA || mType == ASMIT_TYA ||
mType == ASMIT_ORA || mType == ASMIT_AND || mType == ASMIT_EOR || mType == ASMIT_ORA || mType == ASMIT_AND || mType == ASMIT_EOR ||
mType == ASMIT_SBC || mType == ASMIT_ADC; mType == ASMIT_SBC || mType == ASMIT_ADC || mType == ASMIT_JSR;
} }
bool NativeCodeInstruction::RequiresYReg(void) const bool NativeCodeInstruction::RequiresYReg(void) const
@ -463,9 +512,26 @@ bool NativeCodeInstruction::RequiresYReg(void) const
bool NativeCodeInstruction::ChangesYReg(void) const bool NativeCodeInstruction::ChangesYReg(void) const
{ {
return mType == ASMIT_TAY || mType == ASMIT_LDY || mType == ASMIT_INY || mType == ASMIT_DEY; return mType == ASMIT_TAY || mType == ASMIT_LDY || mType == ASMIT_INY || mType == ASMIT_DEY || mType == ASMIT_JSR;
} }
bool NativeCodeInstruction::ChangesZeroPage(int address) const
{
if (mMode == ASMIM_ZERO_PAGE && mAddress == address)
return mType == ASMIT_INC || mType == ASMIT_DEC || mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR || mType == ASMIT_STA || mType == ASMIT_STX || mType == ASMIT_STY;
else
return false;
}
bool NativeCodeInstruction::ChangesGlobalMemory(void) const
{
if (mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_ABSOLUTE || mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_ABSOLUTE_Y)
return mType == ASMIT_INC || mType == ASMIT_DEC || mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR || mType == ASMIT_STA || mType == ASMIT_STX || mType == ASMIT_STY || mType == ASMIT_JSR;
else
return false;
}
bool NativeCodeInstruction::RequiresAccu(void) const bool NativeCodeInstruction::RequiresAccu(void) const
{ {
if (mMode == ASMIM_IMPLIED) if (mMode == ASMIM_IMPLIED)
@ -578,6 +644,11 @@ bool NativeCodeInstruction::ApplySimulation(const NativeRegisterDataSet& data)
case ASMIT_CMP: case ASMIT_CMP:
case ASMIT_CPX: case ASMIT_CPX:
case ASMIT_CPY: case ASMIT_CPY:
case ASMIT_ADC:
case ASMIT_SBC:
case ASMIT_AND:
case ASMIT_ORA:
case ASMIT_EOR:
if (mMode == ASMIM_ZERO_PAGE && data.mRegs[mAddress].mMode == NRDM_IMMEDIATE) if (mMode == ASMIM_ZERO_PAGE && data.mRegs[mAddress].mMode == NRDM_IMMEDIATE)
{ {
mMode = ASMIM_IMMEDIATE; mMode = ASMIM_IMMEDIATE;
@ -1314,6 +1385,25 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
break; break;
case ASMIT_ADC: case ASMIT_ADC:
if (data.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_C].mValue == 0)
{
if (mMode == ASMIM_IMMEDIATE && mAddress == 0)
{
mType = ASMIT_ORA;
changed = true;
}
else if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mValue == 0)
{
mType = ASMIT_LDA;
changed = true;
}
}
data.mRegs[CPU_REG_A].Reset();
data.mRegs[CPU_REG_C].Reset();
data.mRegs[CPU_REG_Z].Reset();
break;
case ASMIT_SBC: case ASMIT_SBC:
data.mRegs[CPU_REG_A].Reset(); data.mRegs[CPU_REG_A].Reset();
data.mRegs[CPU_REG_C].Reset(); data.mRegs[CPU_REG_C].Reset();
@ -1377,6 +1467,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
data.mRegs[CPU_REG_A].mValue = mAddress; data.mRegs[CPU_REG_A].mValue = mAddress;
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
data.mRegs[CPU_REG_Z].mValue = mAddress; data.mRegs[CPU_REG_Z].mValue = mAddress;
changed = true;
} }
else if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mValue == 0) else if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mValue == 0)
{ {
@ -1391,6 +1482,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
mMode = ASMIM_IMMEDIATE; mMode = ASMIM_IMMEDIATE;
mAddress = 0; mAddress = 0;
} }
changed = true;
} }
else else
{ {
@ -1715,6 +1807,13 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
break; break;
} }
} }
else if (mMode == ASMIM_INDIRECT_Y)
{
if (data.mRegs[mAddress].mMode == NRDM_ZERO_PAGE && data.mRegs[mAddress + 1].mMode == NRDM_ZERO_PAGE && data.mRegs[mAddress].mValue + 1 == data.mRegs[mAddress + 1].mValue)
{
mAddress = data.mRegs[mAddress].mValue;
}
}
return changed; return changed;
} }
@ -1968,7 +2067,7 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
{ {
if (mType == ASMIT_BYTE) if (mType == ASMIT_BYTE)
block->PutByte(mAddress); block->PutByte(mAddress);
else if (mType == ASMIT_JSR && (mLinkerObject->mFlags & LOBJF_INLINE)) else if (mType == ASMIT_JSR && mLinkerObject && (mLinkerObject->mFlags & LOBJF_INLINE))
{ {
int pos = block->mCode.Size(); int pos = block->mCode.Size();
for (int i = 0; i < mLinkerObject->mSize - 1; i++) for (int i = 0; i < mLinkerObject->mSize - 1; i++)
@ -3769,6 +3868,7 @@ int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, NativeCodeProc
switch (lmul) switch (lmul)
{ {
#if 1
case 1: case 1:
ShiftRegisterLeft(proc, BC_REG_ACCU, lshift); ShiftRegisterLeft(proc, BC_REG_ACCU, lshift);
return BC_REG_ACCU; return BC_REG_ACCU;
@ -3806,7 +3906,47 @@ int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, NativeCodeProc
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
ShiftRegisterLeft(proc, BC_REG_ACCU, lshift); ShiftRegisterLeft(proc, BC_REG_ACCU, lshift);
return BC_REG_ACCU; return BC_REG_ACCU;
#if 0 case 7:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_TXA, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
ShiftRegisterLeft(proc, BC_REG_ACCU, lshift);
return BC_REG_ACCU;
case 9:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_TXA, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
ShiftRegisterLeft(proc, BC_REG_ACCU, lshift);
return BC_REG_ACCU;
#if 1
case 25: case 25:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
@ -3836,6 +3976,7 @@ int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, NativeCodeProc
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
ShiftRegisterLeft(proc, BC_REG_ACCU, lshift); ShiftRegisterLeft(proc, BC_REG_ACCU, lshift);
return BC_REG_ACCU; return BC_REG_ACCU;
#endif
#endif #endif
default: default:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, mul)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, mul));
@ -6320,6 +6461,9 @@ bool NativeCodeBasicBlock::RemoveUnusedResultInstructions(void)
void NativeCodeBasicBlock::CountEntries(NativeCodeBasicBlock * fromJump) void NativeCodeBasicBlock::CountEntries(NativeCodeBasicBlock * fromJump)
{ {
if (mVisiting)
mLoopHead = true;
if (mNumEntries == 0) if (mNumEntries == 0)
mFromJump = fromJump; mFromJump = fromJump;
else else
@ -6329,11 +6473,14 @@ void NativeCodeBasicBlock::CountEntries(NativeCodeBasicBlock * fromJump)
if (!mVisited) if (!mVisited)
{ {
mVisited = true; mVisited = true;
mVisiting = true;
if (mTrueJump) if (mTrueJump)
mTrueJump->CountEntries(this); mTrueJump->CountEntries(this);
if (mFalseJump) if (mFalseJump)
mFalseJump->CountEntries(this); mFalseJump->CountEntries(this);
mVisiting = false;
} }
} }
@ -6408,15 +6555,15 @@ void NativeCodeBasicBlock::BuildEntryDataSet(const NativeRegisterDataSet& set)
{ {
mVisited = true; mVisited = true;
NativeRegisterDataSet nset = mEntryRegisterDataSet; mNDataSet = mEntryRegisterDataSet;
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
mIns[i].Simulate(nset); mIns[i].Simulate(mNDataSet);
if (mTrueJump) if (mTrueJump)
mTrueJump->BuildEntryDataSet(nset); mTrueJump->BuildEntryDataSet(mNDataSet);
if (mFalseJump) if (mFalseJump)
mFalseJump->BuildEntryDataSet(nset); mFalseJump->BuildEntryDataSet(mNDataSet);
} }
} }
@ -6428,13 +6575,13 @@ bool NativeCodeBasicBlock::ApplyEntryDataSet(void)
{ {
mVisited = true; mVisited = true;
NativeRegisterDataSet nset = mEntryRegisterDataSet; mNDataSet = mEntryRegisterDataSet;
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
{ {
if (mIns[i].ApplySimulation(nset)) if (mIns[i].ApplySimulation(mNDataSet))
changed = true; changed = true;
mIns[i].Simulate(nset); mIns[i].Simulate(mNDataSet);
} }
if (mTrueJump && mTrueJump->ApplyEntryDataSet()) if (mTrueJump && mTrueJump->ApplyEntryDataSet())
@ -6627,6 +6774,35 @@ bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& bre
return false; return false;
} }
bool NativeCodeBasicBlock::MoveIndirectLoadStoreUp(int at)
{
int j = at - 1;
while (j > 0)
{
if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress)
{
mIns.Insert(j + 1, mIns[at + 1]);
mIns.Insert(j + 2, mIns[at + 3]);
mIns[at + 4].mType = ASMIT_NOP;
mIns[at + 4].mMode = ASMIM_IMPLIED;
return true;
}
if (mIns[j].ChangesYReg())
return false;
if (mIns[j].ChangesZeroPage(mIns[at].mAddress))
return false;
if (mIns[j].ChangesZeroPage(mIns[at + 2].mAddress))
return false;
if (mIns[j].ChangesZeroPage(mIns[at + 2].mAddress + 1))
return false;
j--;
}
return false;
}
bool NativeCodeBasicBlock::MoveLoadStoreUp(int at) bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
{ {
int j = at; int j = at;
@ -6664,16 +6840,37 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data)
if (!mVisited) if (!mVisited)
{ {
mVisited = true; mNDataSet = data;
NativeRegisterDataSet ndata(data); if (mLoopHead)
{
if (mNumEntries != 1) mNDataSet.Reset();
}
#if 0
else if (mNumEntries != 1)
{
ndata.Reset(); ndata.Reset();
}
#endif
else if (mNumEntries > 0)
{
if (mNumEntered > 0)
mNDataSet.Intersect(mDataSet);
mNumEntered++;
if (mNumEntered < mNumEntries)
{
mDataSet = mNDataSet;
return false;
}
}
mVisited = true;
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
{ {
if (mIns[i].ValueForwarding(ndata)) if (mIns[i].ValueForwarding(mNDataSet))
changed = true; changed = true;
} }
@ -6682,60 +6879,60 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data)
switch (mBranch) switch (mBranch)
{ {
case ASMIT_BCS: case ASMIT_BCS:
if (ndata.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE) if (mNDataSet.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE)
{ {
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
if (!ndata.mRegs[CPU_REG_C].mValue) if (!mNDataSet.mRegs[CPU_REG_C].mValue)
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
mFalseJump = nullptr; mFalseJump = nullptr;
changed = true; changed = true;
} }
break; break;
case ASMIT_BCC: case ASMIT_BCC:
if (ndata.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE) if (mNDataSet.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE)
{ {
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
if (ndata.mRegs[CPU_REG_C].mValue) if (mNDataSet.mRegs[CPU_REG_C].mValue)
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
mFalseJump = nullptr; mFalseJump = nullptr;
changed = true; changed = true;
} }
break; break;
case ASMIT_BNE: case ASMIT_BNE:
if (ndata.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE) if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
{ {
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
if (!ndata.mRegs[CPU_REG_Z].mValue) if (!mNDataSet.mRegs[CPU_REG_Z].mValue)
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
mFalseJump = nullptr; mFalseJump = nullptr;
changed = true; changed = true;
} }
break; break;
case ASMIT_BEQ: case ASMIT_BEQ:
if (ndata.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE) if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
{ {
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
if (ndata.mRegs[CPU_REG_Z].mValue) if (mNDataSet.mRegs[CPU_REG_Z].mValue)
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
mFalseJump = nullptr; mFalseJump = nullptr;
changed = true; changed = true;
} }
break; break;
case ASMIT_BPL: case ASMIT_BPL:
if (ndata.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE) if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
{ {
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
if ((ndata.mRegs[CPU_REG_Z].mValue & 0x80)) if ((mNDataSet.mRegs[CPU_REG_Z].mValue & 0x80))
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
mFalseJump = nullptr; mFalseJump = nullptr;
changed = true; changed = true;
} }
break; break;
case ASMIT_BMI: case ASMIT_BMI:
if (ndata.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE) if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
{ {
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
if (!(ndata.mRegs[CPU_REG_Z].mValue & 0x80)) if (!(mNDataSet.mRegs[CPU_REG_Z].mValue & 0x80))
mTrueJump = mFalseJump; mTrueJump = mFalseJump;
mFalseJump = nullptr; mFalseJump = nullptr;
changed = true; changed = true;
@ -6744,9 +6941,9 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data)
} }
} }
if (this->mTrueJump && this->mTrueJump->ValueForwarding(ndata)) if (this->mTrueJump && this->mTrueJump->ValueForwarding(mNDataSet))
changed = true; changed = true;
if (this->mFalseJump && this->mFalseJump->ValueForwarding(ndata)) if (this->mFalseJump && this->mFalseJump->ValueForwarding(mNDataSet))
changed = true; changed = true;
} }
@ -7074,6 +7271,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
} }
} }
#endif #endif
#if 1
// move load - store (),y up to initial store
//
for (int i = 2; i + 2 < mIns.Size(); i++)
{
if (mIns[i].mType == ASMIT_LDA && mIns[i].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)
{
if (MoveIndirectLoadStoreUp(i))
changed = true;
}
}
#endif
//
// shorten x/y register livetime // shorten x/y register livetime
#if 1 #if 1
@ -7267,6 +7480,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mMode = ASMIM_IMPLIED;
progress = true; progress = true;
} }
else if (mIns[i + 1].mType == ASMIT_ORA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 && mIns[i].ChangesAccuAndFlag())
{
mIns[i + 0].mLive |= (mIns[i + 1].mLive & LIVE_CPU_REG_Z);
mIns[i + 1].mType = ASMIT_NOP;
progress = true;
}
else if (mIns[i + 1].mType == ASMIT_CMP && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 && mIns[i].ChangesAccuAndFlag() && !(mIns[i + 1].mLive & LIVE_CPU_REG_C))
{
mIns[i + 0].mLive |= (mIns[i + 1].mLive & LIVE_CPU_REG_Z);
mIns[i + 1].mType = ASMIT_NOP;
progress = true;
}
else if ( else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress && mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress &&
(mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR)) (mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR))
@ -7376,6 +7601,16 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 1].mLive |= mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z); mIns[i + 1].mLive |= mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z);
progress = true; progress = true;
} }
else if (
mIns[i + 0].ChangesAccuAndFlag() &&
mIns[i + 1].mType == ASMIT_STA &&
mIns[i + 2].mType == ASMIT_CMP && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0 && !(mIns[i + 2].mLive & LIVE_CPU_REG_C))
{
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
mIns[i + 0].mLive |= mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z);
mIns[i + 1].mLive |= mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z);
progress = true;
}
else if ( else if (
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
(mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR) && (mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR) &&
@ -7879,6 +8114,10 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
int tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0; int tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0;
int stackExpand = tempSave + proc->mLocalSize; int stackExpand = tempSave + proc->mLocalSize;
int commonFrameSize = proc->mCommonFrameSize;
if (proc->mCallsByteCode || commonFrameSize > 0)
commonFrameSize += 2;
mFrameOffset = 0; mFrameOffset = 0;
mNoFrame = (stackExpand + proc->mCommonFrameSize) < 64 && !proc->mHasDynamicStack && !(proc->mHasInlineAssembler && !proc->mLeafProcedure); mNoFrame = (stackExpand + proc->mCommonFrameSize) < 64 && !proc->mHasDynamicStack && !(proc->mHasInlineAssembler && !proc->mLeafProcedure);
@ -7966,16 +8205,19 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
if (!proc->mLeafProcedure) if (!proc->mLeafProcedure)
{ {
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); if (commonFrameSize > 0)
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); {
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (proc->mCommonFrameSize + 2) & 0xff)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, ((proc->mCommonFrameSize + 2) >> 8) & 0xff)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
}
if (mNoFrame) if (mNoFrame)
mFrameOffset = proc->mCommonFrameSize + tempSave + 2; mFrameOffset = commonFrameSize + tempSave;
} }
entryBlock->mFrameOffset = mFrameOffset; entryBlock->mFrameOffset = mFrameOffset;
@ -7985,14 +8227,14 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
exitBlock = AllocateBlock(); exitBlock = AllocateBlock();
mBlocks.Push(exitBlock); mBlocks.Push(exitBlock);
if (!proc->mLeafProcedure) if (!proc->mLeafProcedure && commonFrameSize > 0)
{ {
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (proc->mCommonFrameSize + 2) & 0xff)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, ((proc->mCommonFrameSize + 2) >> 8) & 0xff)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
} }
@ -8060,6 +8302,8 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
CompileInterBlock(proc, proc->mBlocks[0], entryBlock); CompileInterBlock(proc, proc->mBlocks[0], entryBlock);
#if 1 #if 1
int step = 0;
bool changed; bool changed;
do do
{ {
@ -8067,6 +8311,8 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
for (int i = 0; i < mBlocks.Size(); i++) for (int i = 0; i < mBlocks.Size(); i++)
{ {
mBlocks[i]->mNumEntries = 0; mBlocks[i]->mNumEntries = 0;
mBlocks[i]->mVisiting = false;
mBlocks[i]->mLoopHead = false;
mBlocks[i]->mFromJump = nullptr; mBlocks[i]->mFromJump = nullptr;
} }
entryBlock->CountEntries(nullptr); entryBlock->CountEntries(nullptr);
@ -8101,9 +8347,12 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mBlocks[i]->mEntryBlocks.SetSize(0); mBlocks[i]->mEntryBlocks.SetSize(0);
entryBlock->CollectEntryBlocks(nullptr); entryBlock->CollectEntryBlocks(nullptr);
ResetVisited(); if (step > 2)
if (entryBlock->JoinTailCodeSequences()) {
changed = true; ResetVisited();
if (entryBlock->JoinTailCodeSequences())
changed = true;
}
ResetVisited(); ResetVisited();
NativeRegisterDataSet data; NativeRegisterDataSet data;
@ -8113,6 +8362,11 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
if (entryBlock->ApplyEntryDataSet()) if (entryBlock->ApplyEntryDataSet())
changed = true; changed = true;
if (!changed && step < 4)
{
step++;
changed = true;
}
} while (changed); } while (changed);
#endif #endif
@ -8198,7 +8452,10 @@ void NativeCodeProcedure::ResetVisited(void)
int i; int i;
for (i = 0; i < mBlocks.Size(); i++) for (i = 0; i < mBlocks.Size(); i++)
{
mBlocks[i]->mVisited = false; mBlocks[i]->mVisited = false;
mBlocks[i]->mNumEntered = 0;
}
} }
@ -8517,6 +8774,9 @@ NativeCodeGenerator::Runtime& NativeCodeGenerator::ResolveRuntime(const Ident* i
int i = 0; int i = 0;
while (i < mRuntime.Size() && mRuntime[i].mIdent != ident) while (i < mRuntime.Size() && mRuntime[i].mIdent != ident)
i++; i++;
Location loc;
if (i == mRuntime.Size() || !mRuntime[i].mLinkerObject)
mErrors->Error(loc, EERR_RUNTIME_CODE, "Undefied runtime function", ident->mString);
return mRuntime[i]; return mRuntime[i];
} }

View File

@ -34,6 +34,7 @@ struct NativeRegisterDataSet
void Reset(void); void Reset(void);
void ResetZeroPage(int addr); void ResetZeroPage(int addr);
void Intersect(const NativeRegisterDataSet& set);
}; };
@ -70,6 +71,8 @@ public:
bool RequiresAccu(void) const; bool RequiresAccu(void) const;
bool RequiresYReg(void) const; bool RequiresYReg(void) const;
bool ChangesYReg(void) const; bool ChangesYReg(void) const;
bool ChangesZeroPage(int address) const;
bool ChangesGlobalMemory(void) const;
bool SameEffectiveAddress(const NativeCodeInstruction& ins) const; bool SameEffectiveAddress(const NativeCodeInstruction& ins) const;
bool IsSame(const NativeCodeInstruction& ins) const; bool IsSame(const NativeCodeInstruction& ins) const;
bool IsCommutative(void) const; bool IsCommutative(void) const;
@ -92,8 +95,10 @@ public:
GrowingArray<NativeCodeBasicBlock*> mEntryBlocks; GrowingArray<NativeCodeBasicBlock*> mEntryBlocks;
int mOffset, mSize, mNumEntries, mFrameOffset; int mOffset, mSize, mNumEntries, mNumEntered, mFrameOffset;
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited; bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting;
NativeRegisterDataSet mDataSet, mNDataSet;
int PutBranch(NativeCodeProcedure* proc, AsmInsType code, int offset); int PutBranch(NativeCodeProcedure* proc, AsmInsType code, int offset);
int PutJump(NativeCodeProcedure* proc, int offset); int PutJump(NativeCodeProcedure* proc, int offset);
@ -147,8 +152,10 @@ public:
void CountEntries(NativeCodeBasicBlock* fromJump); void CountEntries(NativeCodeBasicBlock* fromJump);
bool MergeBasicBlocks(void); bool MergeBasicBlocks(void);
void MarkLoopHead(void);
bool MoveLoadStoreUp(int at); bool MoveLoadStoreUp(int at);
bool MoveIndirectLoadStoreUp(int at);
bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg); bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg);
bool FindGlobalAddress(int at, int reg, int& apos); bool FindGlobalAddress(int at, int reg, int& apos);
bool FindGlobalAddressSumY(int at, int reg, const NativeCodeInstruction * & ains, int& ireg); bool FindGlobalAddressSumY(int at, int reg, const NativeCodeInstruction * & ains, int& ireg);

View File

@ -704,13 +704,7 @@ Declaration* Parser::ParseDeclaration(bool variable)
if (mScanner->mToken == TK_INLINE) if (mScanner->mToken == TK_INLINE)
{ {
storageFlags |= DTF_INLINE; storageFlags |= DTF_REQUEST_INLINE;
mScanner->NextToken();
}
if (mScanner->mToken == TK_FASTCALL)
{
typeFlags |= DTF_FASTCALL;
mScanner->NextToken(); mScanner->NextToken();
} }
} }
@ -785,6 +779,18 @@ Declaration* Parser::ParseDeclaration(bool variable)
ndec = pdec; ndec = pdec;
} }
else if ((ndec->mFlags & DTF_EXTERN) || (pdec->mFlags & DTF_EXTERN))
{
if (!ndec->mBase->IsSame(pdec->mBase))
{
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs");
}
if (!(ndec->mFlags & DTF_EXTERN))
pdec->mFlags &= ~DTF_EXTERN;
ndec = pdec;
}
else else
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate variable declaration", ndec->mIdent->mString); mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate variable declaration", ndec->mIdent->mString);
} }

View File

@ -46,7 +46,6 @@ const char* TokenNames[] = {
"'static'", "'static'",
"'extern'", "'extern'",
"'inline'", "'inline'",
"'__fastcall'",
"__asm", "__asm",
@ -1152,8 +1151,6 @@ void Scanner::NextRawToken(void)
mToken = TK_EXTERN; mToken = TK_EXTERN;
else if (!strcmp(tkident, "inline")) else if (!strcmp(tkident, "inline"))
mToken = TK_INLINE; mToken = TK_INLINE;
else if (!strcmp(tkident, "__fastcall"))
mToken = TK_FASTCALL;
else if (!strcmp(tkident, "__asm")) else if (!strcmp(tkident, "__asm"))
mToken = TK_ASM; mToken = TK_ASM;
else else

View File

@ -45,7 +45,6 @@ enum Token
TK_STATIC, TK_STATIC,
TK_EXTERN, TK_EXTERN,
TK_INLINE, TK_INLINE,
TK_FASTCALL,
TK_ASM, TK_ASM,

View File

@ -149,6 +149,7 @@
<ClCompile Include="Disassembler.cpp" /> <ClCompile Include="Disassembler.cpp" />
<ClCompile Include="Emulator.cpp" /> <ClCompile Include="Emulator.cpp" />
<ClCompile Include="Errors.cpp" /> <ClCompile Include="Errors.cpp" />
<ClCompile Include="GlobalAnalyzer.cpp" />
<ClCompile Include="Ident.cpp" /> <ClCompile Include="Ident.cpp" />
<ClCompile Include="InterCode.cpp" /> <ClCompile Include="InterCode.cpp" />
<ClCompile Include="InterCodeGenerator.cpp" /> <ClCompile Include="InterCodeGenerator.cpp" />
@ -171,6 +172,7 @@
<ClInclude Include="Disassembler.h" /> <ClInclude Include="Disassembler.h" />
<ClInclude Include="Emulator.h" /> <ClInclude Include="Emulator.h" />
<ClInclude Include="Errors.h" /> <ClInclude Include="Errors.h" />
<ClInclude Include="GlobalAnalyzer.h" />
<ClInclude Include="Ident.h" /> <ClInclude Include="Ident.h" />
<ClInclude Include="InterCode.h" /> <ClInclude Include="InterCode.h" />
<ClInclude Include="InterCodeGenerator.h" /> <ClInclude Include="InterCodeGenerator.h" />

View File

@ -69,6 +69,9 @@
<ClCompile Include="Disassembler.cpp"> <ClCompile Include="Disassembler.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="GlobalAnalyzer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Array.h"> <ClInclude Include="Array.h">
@ -137,6 +140,9 @@
<ClInclude Include="Disassembler.h"> <ClInclude Include="Disassembler.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GlobalAnalyzer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="oscar64.rc"> <ResourceCompile Include="oscar64.rc">