Add __bankof operator
This commit is contained in:
parent
ac7e1d5867
commit
b1fc2e3736
|
@ -23,7 +23,7 @@ After extensive optimizations it turns out, that the interpreted code is not sig
|
||||||
|
|
||||||
## Limits and Errors
|
## Limits and Errors
|
||||||
|
|
||||||
There are still several open areas, but most targets have been reached. The current Dhrystone performance is 82 iterations per second with byte code (11831) and 365 iterations with native code (11372 Bytes). This clearly shows that Dhrystone is not a valid benchmark for optimizing compilers, because it puts the 6502 on par with a 4MHz 8088 or 68k, which it clearly is not.
|
There are still several open areas, but most targets have been reached. The current Dhrystone performance is 94 iterations per second with byte code (11696) and 395 iterations with native code (10425 Bytes). This clearly shows that Dhrystone is not a valid benchmark for optimizing compilers, because it puts the 6502 on par with a 4MHz 8088 or 68k, which it clearly is not.
|
||||||
|
|
||||||
### Language
|
### Language
|
||||||
|
|
||||||
|
@ -516,6 +516,8 @@ the start of the stack section. The size of the stack and the minimum size of t
|
||||||
|
|
||||||
The linker will throw an error if the heap or stack cannot be placed without collision.
|
The linker will throw an error if the heap or stack cannot be placed without collision.
|
||||||
|
|
||||||
|
The __bankof operator returns the bank id of a function or constant placed into a ROM bank.
|
||||||
|
|
||||||
|
|
||||||
#### Overlays
|
#### Overlays
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,20 @@ void vram_addr(unsigned long addr)
|
||||||
vera.addrh = (char)((addr >> 16) & 1) | 0x10;
|
vera.addrh = (char)((addr >> 16) & 1) | 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vram_addr0(unsigned long addr)
|
||||||
|
{
|
||||||
|
vera.ctrl &= ~VERA_CTRL_ADDRSEL;
|
||||||
|
vera.addr = (unsigned)addr;
|
||||||
|
vera.addrh = (char)((addr >> 16) & 1) | 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vram_addr2(unsigned long addr)
|
||||||
|
{
|
||||||
|
vera.ctrl &= ~VERA_CTRL_ADDRSEL;
|
||||||
|
vera.addr = (unsigned)addr;
|
||||||
|
vera.addrh = (char)((addr >> 16) & 1) | 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
void vram_put(char data)
|
void vram_put(char data)
|
||||||
{
|
{
|
||||||
vera.data0 = data;
|
vera.data0 = data;
|
||||||
|
@ -88,6 +102,17 @@ void vera_spr_set(char spr, unsigned addr32, VERASpriteMode mode8, VERASpriteSiz
|
||||||
vram_put((h << 6) | (w << 4) | pal);
|
vram_put((h << 6) | (w << 4) | pal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vera_spr_flip(char spr, bool fliph, bool flipv)
|
||||||
|
{
|
||||||
|
__assume(spr < 128);
|
||||||
|
|
||||||
|
vram_addr0(0x1fc00UL + spr * 8 + 6);
|
||||||
|
char b = vram_get() & 0xfc;
|
||||||
|
if (fliph) b |= 0x01;
|
||||||
|
if (flipv) b |= 0x02;
|
||||||
|
vram_put(b);
|
||||||
|
}
|
||||||
|
|
||||||
void vera_spr_move(char spr, int x, int y)
|
void vera_spr_move(char spr, int x, int y)
|
||||||
{
|
{
|
||||||
__assume(spr < 128);
|
__assume(spr < 128);
|
||||||
|
@ -129,3 +154,13 @@ void vera_pal_putn(char index, const unsigned * color, unsigned size)
|
||||||
size--;
|
size--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vera_pal_getn(char index, unsigned * color, unsigned size)
|
||||||
|
{
|
||||||
|
vram_addr(0x1fa00ul + 2 * index);
|
||||||
|
while (size > 0)
|
||||||
|
{
|
||||||
|
*color++ = vram_getw();
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -114,6 +114,10 @@ enum VERASpritePriority
|
||||||
|
|
||||||
inline void vram_addr(unsigned long addr);
|
inline void vram_addr(unsigned long addr);
|
||||||
|
|
||||||
|
inline void vram_addr0(unsigned long addr);
|
||||||
|
|
||||||
|
inline void vram_addr2(unsigned long addr);
|
||||||
|
|
||||||
inline void vram_put(char data);
|
inline void vram_put(char data);
|
||||||
|
|
||||||
inline void vram_putw(unsigned data);
|
inline void vram_putw(unsigned data);
|
||||||
|
@ -134,6 +138,8 @@ void vram_fill(unsigned long addr, char data, unsigned size);
|
||||||
|
|
||||||
void vera_spr_set(char spr, unsigned addr32, VERASpriteMode mode8, VERASpriteSize w, VERASpriteSize h, VERASpritePriority z, char pal);
|
void vera_spr_set(char spr, unsigned addr32, VERASpriteMode mode8, VERASpriteSize w, VERASpriteSize h, VERASpritePriority z, char pal);
|
||||||
|
|
||||||
|
void vera_spr_flip(char spr, bool fliph, bool flipv);
|
||||||
|
|
||||||
void vera_spr_move(char spr, int x, int y);
|
void vera_spr_move(char spr, int x, int y);
|
||||||
|
|
||||||
void vera_spr_image(char spr, unsigned addr32);
|
void vera_spr_image(char spr, unsigned addr32);
|
||||||
|
@ -144,6 +150,8 @@ unsigned vera_pal_get(char index);
|
||||||
|
|
||||||
void vera_pal_putn(char index, const unsigned * color, unsigned size);
|
void vera_pal_putn(char index, const unsigned * color, unsigned size);
|
||||||
|
|
||||||
|
void vera_pal_getn(char index, unsigned * color, unsigned size);
|
||||||
|
|
||||||
#pragma compile("vera.c")
|
#pragma compile("vera.c")
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -150,7 +150,8 @@ enum ExpressionType
|
||||||
EX_CASE,
|
EX_CASE,
|
||||||
EX_DEFAULT,
|
EX_DEFAULT,
|
||||||
EX_CONDITIONAL,
|
EX_CONDITIONAL,
|
||||||
EX_ASSUME
|
EX_ASSUME,
|
||||||
|
EX_BANKOF
|
||||||
};
|
};
|
||||||
|
|
||||||
class Expression
|
class Expression
|
||||||
|
|
|
@ -67,6 +67,7 @@ enum ErrorID
|
||||||
ERRR_SEMICOLON_EXPECTED,
|
ERRR_SEMICOLON_EXPECTED,
|
||||||
ERRR_USE_OF_UNINITIALIZED_VARIABLE,
|
ERRR_USE_OF_UNINITIALIZED_VARIABLE,
|
||||||
ERRR_STRIPE_REQUIRES_FIXED_SIZE_ARRAY,
|
ERRR_STRIPE_REQUIRES_FIXED_SIZE_ARRAY,
|
||||||
|
ERRR_CANNOT_FIND_BANK_OF_EXPRESSION,
|
||||||
|
|
||||||
ERRR_STACK_OVERFLOW,
|
ERRR_STACK_OVERFLOW,
|
||||||
ERRR_INVALID_NUMBER,
|
ERRR_INVALID_NUMBER,
|
||||||
|
|
|
@ -2081,6 +2081,28 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
dec->mFlags = DTF_DEFINED;
|
dec->mFlags = DTF_DEFINED;
|
||||||
return ExValue(dec, vl.mTemp, vl.mReference - 1);
|
return ExValue(dec, vl.mTemp, vl.mReference - 1);
|
||||||
}
|
}
|
||||||
|
case TK_BANKOF:
|
||||||
|
{
|
||||||
|
LinkerRegion* rgn;
|
||||||
|
if (exp->mLeft->mDecValue->mSection && (rgn = mLinker->FindRegionOfSection(exp->mLeft->mDecValue->mSection)))
|
||||||
|
{
|
||||||
|
uint64 i = 0;
|
||||||
|
while (i < 64 && rgn->mCartridgeBanks != (1ULL << i))
|
||||||
|
i++;
|
||||||
|
if (i < 64)
|
||||||
|
{
|
||||||
|
ins->mCode = IC_CONSTANT;
|
||||||
|
ins->mNumOperands = 0;
|
||||||
|
ins->mConst.mType = IT_INT8;
|
||||||
|
ins->mConst.mIntConst = i;
|
||||||
|
ins->mDst.mType = IT_INT8;
|
||||||
|
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||||
|
block->Append(ins);
|
||||||
|
return ExValue(TheUnsignedCharTypeDeclaration, ins->mDst.mTemp, vl.mReference - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mErrors->Error(exp->mLocation, ERRR_CANNOT_FIND_BANK_OF_EXPRESSION, "Cannot find bank of expressiohn");
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ins->mSrc[0].mType = InterTypeOf(vl.mType);
|
ins->mSrc[0].mType = InterTypeOf(vl.mType);
|
||||||
|
|
|
@ -172,6 +172,23 @@ LinkerSection* Linker::AddSection(const Ident* section, LinkerSectionType type)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinkerRegion* Linker::FindRegionOfSection(LinkerSection* section)
|
||||||
|
{
|
||||||
|
LinkerRegion* srgn = nullptr;
|
||||||
|
for (int i = 0; i < mRegions.Size(); i++)
|
||||||
|
{
|
||||||
|
LinkerRegion* rgn = mRegions[i];
|
||||||
|
if (rgn->mSections.Contains(section))
|
||||||
|
{
|
||||||
|
if (srgn)
|
||||||
|
return nullptr;
|
||||||
|
srgn = rgn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return srgn;
|
||||||
|
}
|
||||||
|
|
||||||
LinkerSection* Linker::FindSection(const Ident* section)
|
LinkerSection* Linker::FindSection(const Ident* section)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mSections.Size(); i++)
|
for (int i = 0; i < mSections.Size(); i++)
|
||||||
|
|
|
@ -231,6 +231,8 @@ public:
|
||||||
LinkerSection * AddSection(const Ident* section, LinkerSectionType type);
|
LinkerSection * AddSection(const Ident* section, LinkerSectionType type);
|
||||||
LinkerSection* FindSection(const Ident* section);
|
LinkerSection* FindSection(const Ident* section);
|
||||||
|
|
||||||
|
LinkerRegion* FindRegionOfSection(LinkerSection* section);
|
||||||
|
|
||||||
LinkerObject* FindObjectByAddr(int addr);
|
LinkerObject* FindObjectByAddr(int addr);
|
||||||
|
|
||||||
bool IsSectionPlaced(LinkerSection* section);
|
bool IsSectionPlaced(LinkerSection* section);
|
||||||
|
|
|
@ -27443,6 +27443,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
prevBlock->mIns.Push(mIns[0]);
|
prevBlock->mIns.Push(mIns[0]);
|
||||||
mIns.Remove(0);
|
mIns.Remove(0);
|
||||||
|
|
||||||
|
mEntryRequiredRegs += CPU_REG_A;
|
||||||
|
mExitRequiredRegs += CPU_REG_A;
|
||||||
|
prevBlock->mExitRequiredRegs += CPU_REG_A;
|
||||||
|
|
||||||
CheckLive();
|
CheckLive();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -27747,6 +27751,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
prevBlock->mIns.Push(mIns[si]);
|
prevBlock->mIns.Push(mIns[si]);
|
||||||
mIns.Remove(si);
|
mIns.Remove(si);
|
||||||
|
|
||||||
|
mEntryRequiredRegs += CPU_REG_A;
|
||||||
|
mExitRequiredRegs += CPU_REG_A;
|
||||||
|
prevBlock->mExitRequiredRegs += CPU_REG_A;
|
||||||
|
|
||||||
CheckLive();
|
CheckLive();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -27791,6 +27799,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
prevBlock->mIns.Push(mIns[si]);
|
prevBlock->mIns.Push(mIns[si]);
|
||||||
mIns.Remove(si);
|
mIns.Remove(si);
|
||||||
|
|
||||||
|
mEntryRequiredRegs += CPU_REG_A;
|
||||||
|
mExitRequiredRegs += CPU_REG_A;
|
||||||
|
prevBlock->mExitRequiredRegs += CPU_REG_A;
|
||||||
|
|
||||||
CheckLive();
|
CheckLive();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -27844,6 +27856,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
prevBlock->mIns.Push(mIns[si]);
|
prevBlock->mIns.Push(mIns[si]);
|
||||||
mIns.Remove(si);
|
mIns.Remove(si);
|
||||||
|
|
||||||
|
mEntryRequiredRegs += CPU_REG_A;
|
||||||
|
mExitRequiredRegs += CPU_REG_A;
|
||||||
|
prevBlock->mExitRequiredRegs += CPU_REG_A;
|
||||||
|
|
||||||
CheckLive();
|
CheckLive();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -27893,6 +27909,9 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
prevBlock->mIns.Push(mIns[0]);
|
prevBlock->mIns.Push(mIns[0]);
|
||||||
mIns.Remove(0);
|
mIns.Remove(0);
|
||||||
|
|
||||||
|
mEntryRequiredRegs += CPU_REG_Y;
|
||||||
|
mExitRequiredRegs += CPU_REG_Y;
|
||||||
|
|
||||||
CheckLive();
|
CheckLive();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -27920,6 +27939,9 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
prevBlock->mIns.Push(mIns[0]);
|
prevBlock->mIns.Push(mIns[0]);
|
||||||
mIns.Remove(0);
|
mIns.Remove(0);
|
||||||
|
|
||||||
|
mEntryRequiredRegs += CPU_REG_X;
|
||||||
|
mExitRequiredRegs += CPU_REG_X;
|
||||||
|
|
||||||
CheckLive();
|
CheckLive();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -27996,6 +28018,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
prevBlock->mIns.Push(mIns[ai]);
|
prevBlock->mIns.Push(mIns[ai]);
|
||||||
mIns.Remove(ai);
|
mIns.Remove(ai);
|
||||||
|
|
||||||
|
mEntryRequiredRegs += CPU_REG_A;
|
||||||
|
mExitRequiredRegs += CPU_REG_A;
|
||||||
|
prevBlock->mExitRequiredRegs += CPU_REG_A;
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28010,6 +28036,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
prevBlock->mIns.Push(mIns[ai]);
|
prevBlock->mIns.Push(mIns[ai]);
|
||||||
mIns.Remove(ai);
|
mIns.Remove(ai);
|
||||||
|
|
||||||
|
mEntryRequiredRegs += CPU_REG_A;
|
||||||
|
mExitRequiredRegs += CPU_REG_A;
|
||||||
|
prevBlock->mExitRequiredRegs += CPU_REG_A;
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28156,6 +28186,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
if (mEntryRequiredRegs.Size() && (!mEntryRequiredRegs[CPU_REG_A] || !mEntryRequiredRegs[CPU_REG_X]))
|
if (mEntryRequiredRegs.Size() && (!mEntryRequiredRegs[CPU_REG_A] || !mEntryRequiredRegs[CPU_REG_X]))
|
||||||
{
|
{
|
||||||
for (int i = 0; i + 1 < mIns.Size(); i++)
|
for (int i = 0; i + 1 < mIns.Size(); i++)
|
||||||
|
@ -28174,6 +28205,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
return OptimizeSimpleLoopInvariant(proc, full);
|
return OptimizeSimpleLoopInvariant(proc, full);
|
||||||
if (!mEntryRequiredRegs[CPU_REG_A])
|
if (!mEntryRequiredRegs[CPU_REG_A])
|
||||||
{
|
{
|
||||||
|
assert(mIns[0].mType != ASMIT_STA);
|
||||||
prevBlock->mIns.Push(NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
|
prevBlock->mIns.Push(NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
|
||||||
prevBlock->mIns.Push(NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
|
prevBlock->mIns.Push(NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
|
||||||
}
|
}
|
||||||
|
@ -28200,6 +28232,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
|
|
||||||
if (!mEntryRequiredRegs[CPU_REG_A])
|
if (!mEntryRequiredRegs[CPU_REG_A])
|
||||||
{
|
{
|
||||||
|
assert(mIns[0].mType != ASMIT_STA);
|
||||||
prevBlock->mIns.Push(NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
|
prevBlock->mIns.Push(NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
|
||||||
prevBlock->mIns.Push(NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
|
prevBlock->mIns.Push(NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
|
||||||
}
|
}
|
||||||
|
@ -28237,6 +28270,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
|
|
||||||
if (!mEntryRequiredRegs[CPU_REG_A])
|
if (!mEntryRequiredRegs[CPU_REG_A])
|
||||||
{
|
{
|
||||||
|
assert(mIns[0].mType != ASMIT_STA);
|
||||||
prevBlock->mIns.Insert(k, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, mIns[i + 0].mAddress));
|
prevBlock->mIns.Insert(k, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, mIns[i + 0].mAddress));
|
||||||
prevBlock->mIns.Insert(k + 1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
|
prevBlock->mIns.Insert(k + 1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
|
||||||
}
|
}
|
||||||
|
@ -28250,6 +28284,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
for (int i = 0; i < mIns.Size(); i++)
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
@ -39543,6 +39578,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
else
|
else
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
|
|
@ -1768,7 +1768,9 @@ Expression* Parser::ParsePostfixExpression(void)
|
||||||
|
|
||||||
Expression* Parser::ParsePrefixExpression(void)
|
Expression* Parser::ParsePrefixExpression(void)
|
||||||
{
|
{
|
||||||
if (mScanner->mToken == TK_SUB || mScanner->mToken == TK_BINARY_NOT || mScanner->mToken == TK_LOGICAL_NOT || mScanner->mToken == TK_MUL || mScanner->mToken == TK_INC || mScanner->mToken == TK_DEC || mScanner->mToken == TK_BINARY_AND)
|
if (mScanner->mToken == TK_SUB || mScanner->mToken == TK_BINARY_NOT || mScanner->mToken == TK_LOGICAL_NOT ||
|
||||||
|
mScanner->mToken == TK_MUL || mScanner->mToken == TK_INC || mScanner->mToken == TK_DEC || mScanner->mToken == TK_BINARY_AND ||
|
||||||
|
mScanner->mToken == TK_BANKOF)
|
||||||
{
|
{
|
||||||
Expression* nexp;
|
Expression* nexp;
|
||||||
if (mScanner->mToken == TK_LOGICAL_NOT)
|
if (mScanner->mToken == TK_LOGICAL_NOT)
|
||||||
|
@ -1814,6 +1816,10 @@ Expression* Parser::ParsePrefixExpression(void)
|
||||||
pdec->mFlags |= DTF_DEFINED;
|
pdec->mFlags |= DTF_DEFINED;
|
||||||
nexp->mDecType = pdec;
|
nexp->mDecType = pdec;
|
||||||
}
|
}
|
||||||
|
else if (nexp->mToken == TK_BANKOF)
|
||||||
|
{
|
||||||
|
nexp->mDecType == TheUnsignedCharTypeDeclaration;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
nexp->mDecType = nexp->mLeft->mDecType;
|
nexp->mDecType = nexp->mLeft->mDecType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ const char* TokenNames[] =
|
||||||
"'union'",
|
"'union'",
|
||||||
"'enum'",
|
"'enum'",
|
||||||
"'sizeof'",
|
"'sizeof'",
|
||||||
|
"'__bankof'",
|
||||||
"'static'",
|
"'static'",
|
||||||
"'auto'",
|
"'auto'",
|
||||||
"'extern'",
|
"'extern'",
|
||||||
|
@ -1342,6 +1343,8 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_ENUM;
|
mToken = TK_ENUM;
|
||||||
else if (!strcmp(tkident, "sizeof"))
|
else if (!strcmp(tkident, "sizeof"))
|
||||||
mToken = TK_SIZEOF;
|
mToken = TK_SIZEOF;
|
||||||
|
else if (!strcmp(tkident, "__bankof"))
|
||||||
|
mToken = TK_BANKOF;
|
||||||
else if (!strcmp(tkident, "typedef"))
|
else if (!strcmp(tkident, "typedef"))
|
||||||
mToken = TK_TYPEDEF;
|
mToken = TK_TYPEDEF;
|
||||||
else if (!strcmp(tkident, "static"))
|
else if (!strcmp(tkident, "static"))
|
||||||
|
|
|
@ -42,6 +42,7 @@ enum Token
|
||||||
TK_UNION,
|
TK_UNION,
|
||||||
TK_ENUM,
|
TK_ENUM,
|
||||||
TK_SIZEOF,
|
TK_SIZEOF,
|
||||||
|
TK_BANKOF,
|
||||||
TK_STATIC,
|
TK_STATIC,
|
||||||
TK_AUTO,
|
TK_AUTO,
|
||||||
TK_EXTERN,
|
TK_EXTERN,
|
||||||
|
|
|
@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.19.198");
|
strcpy(strProductVersion, "1.19.199");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
uint32_t length = sizeof(basePath);
|
uint32_t length = sizeof(basePath);
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,19,198,0
|
FILEVERSION 1,19,199,0
|
||||||
PRODUCTVERSION 1,19,198,0
|
PRODUCTVERSION 1,19,199,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,12 +43,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "oscar64"
|
VALUE "CompanyName", "oscar64"
|
||||||
VALUE "FileDescription", "oscar64 compiler"
|
VALUE "FileDescription", "oscar64 compiler"
|
||||||
VALUE "FileVersion", "1.19.198.0"
|
VALUE "FileVersion", "1.19.199.0"
|
||||||
VALUE "InternalName", "oscar64.exe"
|
VALUE "InternalName", "oscar64.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "oscar64.exe"
|
VALUE "OriginalFilename", "oscar64.exe"
|
||||||
VALUE "ProductName", "oscar64"
|
VALUE "ProductName", "oscar64"
|
||||||
VALUE "ProductVersion", "1.19.198.0"
|
VALUE "ProductVersion", "1.19.199.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -5155,15 +5155,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{1E7DBEE1-2479-49F8-9F5B-1DA786C469FD}"
|
"ProductCode" = "8:{A34D0747-EA76-43D6-AB25-7A788C4ECAE2}"
|
||||||
"PackageCode" = "8:{F178C72F-3E89-41CE-8310-E30ADA97F214}"
|
"PackageCode" = "8:{A35E0D83-FD72-41CF-85BC-8E74BB5E9888}"
|
||||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||||
"AspNetVersion" = "8:2.0.50727.0"
|
"AspNetVersion" = "8:2.0.50727.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:TRUE"
|
"RemovePreviousVersions" = "11:TRUE"
|
||||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||||
"InstallAllUsers" = "11:FALSE"
|
"InstallAllUsers" = "11:FALSE"
|
||||||
"ProductVersion" = "8:1.19.198"
|
"ProductVersion" = "8:1.19.199"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
|
@ -106,6 +106,16 @@ void print6(void)
|
||||||
#pragma data ( data )
|
#pragma data ( data )
|
||||||
|
|
||||||
|
|
||||||
|
// Function for indirect cross bank call
|
||||||
|
void fcall(char bank, void (* func)())
|
||||||
|
{
|
||||||
|
eflash.bank = bank;
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Macro for indirect cross bank call
|
||||||
|
#define FCALL(f) fcall(__bankof(f), f)
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
// Enable ROM
|
// Enable ROM
|
||||||
|
@ -136,14 +146,15 @@ int main(void)
|
||||||
eflash.bank = 3;
|
eflash.bank = 3;
|
||||||
print3();
|
print3();
|
||||||
|
|
||||||
eflash.bank = 4;
|
// Get bank of function using __bankof operator
|
||||||
|
eflash.bank = __bankof print4;
|
||||||
print4();
|
print4();
|
||||||
|
|
||||||
eflash.bank = 5;
|
// Indirect call
|
||||||
print5();
|
fcall(__bankof print5, print5);
|
||||||
|
|
||||||
eflash.bank = 6;
|
// Macro call
|
||||||
print6();
|
FCALL(print6);
|
||||||
|
|
||||||
// Loop forever
|
// Loop forever
|
||||||
while (true)
|
while (true)
|
||||||
|
|
Loading…
Reference in New Issue