From 85df217c50ed88dc06129f9b8983b6cb9f87d15a Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 9 Apr 2023 09:45:13 +0200 Subject: [PATCH] Add warning for const integer truncation --- include/cx16/vera.c | 32 ++++++++++++++++++++++- include/cx16/vera.h | 10 ++++++++ oscar64/InterCode.cpp | 11 ++++++++ oscar64/InterCode.h | 1 + oscar64/InterCodeGenerator.cpp | 47 ++++++++++++++++++++++++++++++++-- oscar64/InterCodeGenerator.h | 2 +- 6 files changed, 99 insertions(+), 4 deletions(-) diff --git a/include/cx16/vera.c b/include/cx16/vera.c index 5e0762f..bbc3b07 100644 --- a/include/cx16/vera.c +++ b/include/cx16/vera.c @@ -3,7 +3,7 @@ void vram_addr(unsigned long addr) { vera.ctrl &= ~VERA_CTRL_ADDRSEL; - vera.addr = addr; + vera.addr = (unsigned)addr; vera.addrh = (char)((addr >> 16) & 1) | 0x10; } @@ -23,6 +23,14 @@ char vram_get(void) return vera.data0; } +unsigned vram_getw(void) +{ + unsigned l = vera.data0; + unsigned h = vera.data0; + return (h << 8) | l; +} + + void vram_put_at(unsigned long addr, char data) { vram_addr(addr); @@ -99,3 +107,25 @@ void vera_spr_image(char spr, unsigned addr32) char b = vram_get() & 0x80; vram_put((addr32 >> 8) | b); } + +void vera_pal_put(char index, unsigned color) +{ + vram_addr(0x1fa00ul + 2 * index); + vram_putw(color); +} + +unsigned vera_pal_get(char index) +{ + vram_addr(0x1fa00ul + 2 * index); + return vram_getw(); +} + +void vera_pal_putn(char index, const unsigned * color, unsigned size) +{ + vram_addr(0x1fa00ul + 2 * index); + while (size > 0) + { + vram_putw(*color++); + size--; + } +} diff --git a/include/cx16/vera.h b/include/cx16/vera.h index 138eab9..b1d8810 100644 --- a/include/cx16/vera.h +++ b/include/cx16/vera.h @@ -108,6 +108,8 @@ enum VERASpritePriority VSPRPRI_FRONT }; +#define VERA_COLOR(r, g, b) (((unsigned)(r) << 8) | ((unsigned)(g) << 4) | (unsigned)(b)) + #define vera (*(VERA *)0x9f20) inline void vram_addr(unsigned long addr); @@ -118,6 +120,8 @@ inline void vram_putw(unsigned data); inline char vram_get(void); +inline unsigned vram_getw(void); + inline void vram_put_at(unsigned long addr, char data); inline char vram_get_at(unsigned long addr); @@ -134,6 +138,12 @@ void vera_spr_move(char spr, int x, int y); void vera_spr_image(char spr, unsigned addr32); +void vera_pal_put(char index, unsigned color); + +unsigned vera_pal_get(char index); + +void vera_pal_putn(char index, const unsigned * color, unsigned size); + #pragma compile("vera.c") #endif diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 589379c..97df976 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -4167,6 +4167,17 @@ void InterCodeBasicBlock::Append(InterInstruction * code) this->mInstructions.Push(code); } +const InterInstruction* InterCodeBasicBlock::FindByDst(int dst) const +{ + int n = mInstructions.Size() - 1; + while (n >= 0 && mInstructions[n]->mDst.mTemp != dst) + n--; + if (n >= 0) + return mInstructions[n]; + else + return nullptr; +} + void InterCodeBasicBlock::Close(InterCodeBasicBlock* trueJump, InterCodeBasicBlock* falseJump) { this->mTrueJump = trueJump; diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 059187a..0528964 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -384,6 +384,7 @@ public: ~InterCodeBasicBlock(void); void Append(InterInstruction * code); + const InterInstruction* FindByDst(int dst) const; void Close(InterCodeBasicBlock* trueJump, InterCodeBasicBlock* falseJump); void CollectEntries(void); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 90ec560..479d1c7 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -65,7 +65,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure* return v; } -InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration* type) +InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration* type, bool checkTrunc) { int stemp = v.mTemp; @@ -204,7 +204,50 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p else { // ignore size reduction + if (checkTrunc && v.mType->mSize > type->mSize) + { + const InterInstruction* ins = block->FindByDst(stemp); + if (ins && ins->mCode == IC_CONSTANT) + { + int64 min = 0, max = 0; + if (type->mFlags & DTF_SIGNED) + { + switch (type->mSize) + { + case 1: + min = -128; max = 127; + break; + case 2: + min = -32768; max = 32767; + break; + case 4: + min = -2147483648LL; max = 2147483647LL; + break; + } + } + else + { + switch (type->mSize) + { + case 1: + max = 255; + break; + case 2: + max = 65535; + break; + case 4: + max = 429467295LL; + break; + } + } + + if (ins->mConst.mIntConst < min || ins->mConst.mIntConst > max) + { + mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated"); + } + } + } v.mType = type; } @@ -1402,7 +1445,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vll = CoerceType(proc, exp, block, vll, otype); } - vr = CoerceType(proc, exp, block, vr, otype); + vr = CoerceType(proc, exp, block, vr, otype, exp->mToken != TK_ASSIGN_AND); InterInstruction * oins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR); oins->mSrc[0].mType = InterTypeOf(otype); diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 7637326..870633c 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -56,7 +56,7 @@ protected: void BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, ExValue v, const SwitchNodeArray& nodes, int left, int right, InterCodeBasicBlock* dblock); ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, int level = 0); - ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration * type); + ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration * type, bool checkTrunc = true); ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr); void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, InlineMapper* inlineMapper); ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr);