Propagation of unsigend attribute accross function arguments

This commit is contained in:
drmortalwombat 2023-01-13 20:14:16 +01:00
parent fdb051bd2b
commit 761206d009
7 changed files with 181 additions and 50 deletions

View File

@ -87,6 +87,9 @@ static const byte rmask[8] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
void bm_scan_fill(int left, int right, char * lp, int x0, int x1, char pat)
{
__assume(left >= 0);
__assume(right >= 0);
if (x0 < left)
x0 = left;
if (x1 > right)
@ -95,7 +98,7 @@ void bm_scan_fill(int left, int right, char * lp, int x0, int x1, char pat)
if (x1 > x0)
{
char * dp = lp + (x0 & ~7);
char l = (x1 >> 3) - (x0 >> 3);
unsigned l = (x1 & ~7) - (x0 & ~7);
char lm = lmask[x0 & 7], rm = rmask[x1 & 7];
char o = 0;
@ -105,17 +108,19 @@ void bm_scan_fill(int left, int right, char * lp, int x0, int x1, char pat)
{
*dp = (*dp & ~lm) | (pat & lm);
o = 8;
if (l >= 32)
if (l >= 256)
{
#pragma unroll(full)
for(char i=0; i<31; i++)
{
dp[o] = pat;
o += 8;
}
dp += 256;
l -= 31;
l -= 248;
}
for(char i=1; i<l; i++)
while (o < (char)l)
{
dp[o] = pat;
o += 8;

View File

@ -2570,6 +2570,11 @@ bool InterOperand::IsSByte(void) const
mRange.mMaxState == IntegerValueRange::S_BOUND && mRange.mMaxValue < 128;
}
bool InterOperand::IsPositive(void) const
{
return mRange.mMinState == IntegerValueRange::S_BOUND && mRange.mMinValue >= 0;
}
bool InterOperand::IsUnsigned(void) const
{
if (mRange.mMinState == IntegerValueRange::S_BOUND && mRange.mMinValue >= 0 && mRange.mMaxState == IntegerValueRange::S_BOUND)
@ -3898,6 +3903,7 @@ void InterInstruction::Disassemble(FILE* file)
InterCodeBasicBlock::InterCodeBasicBlock(void)
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mMergeAValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr),
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()),
mEntryParamValueRange(IntegerValueRange()), mTrueParamValueRange(IntegerValueRange()), mFalseParamValueRange(IntegerValueRange()), mLocalParamValueRange(IntegerValueRange()),
mReverseValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr), mLoopPathBlocks(nullptr), mMemoryValueSize(0), mEntryMemoryValueSize(0)
{
mVisited = false;
@ -5430,7 +5436,7 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
}
bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars)
bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars)
{
bool changed = false;
@ -5439,8 +5445,10 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const Growin
return false;
mLocalValueRange.Clear();
mLocalParamValueRange.Clear();
assert(mLocalValueRange.Size() == mExitRequiredTemps.Size());
assert(mLocalParamValueRange.Size() == paramVars.Size());
bool firstEntry = true;
@ -5448,6 +5456,7 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const Growin
{
InterCodeBasicBlock* from = mEntryBlocks[j];
GrowingIntegerValueRangeArray& range(this == from->mTrueJump ? from->mTrueValueRange : from->mFalseValueRange);
GrowingIntegerValueRangeArray& prange(this == from->mTrueJump ? from->mTrueParamValueRange : from->mFalseParamValueRange);
if (range.Size())
{
@ -5455,21 +5464,29 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const Growin
{
firstEntry = false;
mLocalValueRange = range;
mLocalParamValueRange = prange;
}
else
{
for (int i = 0; i < mLocalValueRange.Size(); i++)
mLocalValueRange[i].Merge(range[i], mLoopHead, initial);
for (int i = 0; i < mLocalParamValueRange.Size(); i++)
mLocalParamValueRange[i].Merge(prange[i], mLoopHead, initial);
}
}
}
assert(mLocalValueRange.Size() == mExitRequiredTemps.Size());
assert(mLocalParamValueRange.Size() == paramVars.Size());
for (int i = 0; i < mLocalValueRange.Size(); i++)
if (!mLocalValueRange[i].Same(mEntryValueRange[i]))
changed = true;
for (int i = 0; i < mLocalParamValueRange.Size(); i++)
if (!mLocalParamValueRange[i].Same(mEntryParamValueRange[i]))
changed = true;
if (mVisited && mNumEntered >= 2 * mEntryBlocks.Size())
return changed;
@ -5489,14 +5506,15 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const Growin
if (changed)
{
mEntryValueRange = mLocalValueRange;
mEntryParamValueRange = mLocalParamValueRange;
UpdateLocalIntegerRangeSets(localVars);
UpdateLocalIntegerRangeSets(localVars, paramVars);
}
if (mTrueJump && mTrueJump->BuildGlobalIntegerRangeSets(initial, localVars))
if (mTrueJump && mTrueJump->BuildGlobalIntegerRangeSets(initial, localVars, paramVars))
changed = true;
if (mFalseJump && mFalseJump->BuildGlobalIntegerRangeSets(initial, localVars))
if (mFalseJump && mFalseJump->BuildGlobalIntegerRangeSets(initial, localVars, paramVars))
changed = true;
}
@ -5540,7 +5558,7 @@ static int64 BuildLowerBitsMask(int64 v)
return v;
}
void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars)
void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars)
{
mLocalValueRange = mEntryValueRange;
@ -5585,6 +5603,9 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
{
case IC_LOAD:
vr = ins->mDst.mRange;
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_FPARAM)
vr.Limit(mLocalParamValueRange[ins->mSrc[0].mVarIndex]);
#if 1
if (ins->mDst.mType == IT_INT8)
{
@ -6132,6 +6153,11 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
}
#endif
}
else if (ins->mCode == IC_STORE)
{
if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_FPARAM)
mLocalParamValueRange[ins->mSrc[1].mVarIndex] = ins->mSrc[0].mRange;
}
assert(mLocalValueRange.Size() == mExitRequiredTemps.Size());
}
@ -6307,6 +6333,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
mTrueValueRange = mLocalValueRange;
mFalseValueRange = mLocalValueRange;
mTrueParamValueRange = mLocalParamValueRange;
mFalseParamValueRange = mLocalParamValueRange;
if (sz >= 1)
{
@ -6437,12 +6465,33 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst);
mFalseValueRange[s1].LimitMinWeak(SignedTypeMin(mInstructions[sz - 2]->mSrc[1].mType));
}
else if (s1 < 0)
{
mTrueValueRange[s0].LimitMax(mInstructions[sz - 2]->mSrc[1].mIntConst - 1);
mTrueValueRange[s0].LimitMinWeak(SignedTypeMax(mInstructions[sz - 2]->mSrc[0].mType));
mFalseValueRange[s0].LimitMin(mInstructions[sz - 2]->mSrc[1].mIntConst);
mFalseValueRange[s0].LimitMaxWeak(SignedTypeMin(mInstructions[sz - 2]->mSrc[0].mType));
}
else
{
if (mLocalValueRange[s0].mMaxState == IntegerValueRange::S_BOUND)
mTrueValueRange[s1].LimitMin(mLocalValueRange[s0].mMinValue + 1);
if (mLocalValueRange[s0].mMinState == IntegerValueRange::S_BOUND)
mFalseValueRange[s1].LimitMax(mLocalValueRange[s0].mMaxValue);
if (mLocalValueRange[s1].mMaxState == IntegerValueRange::S_BOUND)
mTrueValueRange[s0].LimitMax(mLocalValueRange[s1].mMaxValue - 1);
if (mLocalValueRange[s1].mMinState == IntegerValueRange::S_BOUND)
mFalseValueRange[s0].LimitMin(mLocalValueRange[s1].mMinValue);
}
break;
case IA_CMPGES:
if (s0 < 0)
{
mTrueValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst);
mTrueValueRange[s1].LimitMaxWeak(SignedTypeMax(mInstructions[sz - 2]->mSrc[1].mType));
mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1);
mFalseValueRange[s1].LimitMinWeak(SignedTypeMin(mInstructions[sz - 2]->mSrc[1].mType));
}
break;
@ -6512,6 +6561,17 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
mTrueValueRange[mInstructions[sz - 3]->mDst.mTemp] = mTrueValueRange[s1];
mFalseValueRange[mInstructions[sz - 3]->mDst.mTemp] = mFalseValueRange[s1];
}
if (sz >= 3 && mInstructions[sz - 3]->mCode == IC_LOAD)
{
InterInstruction* ins = mInstructions[sz - 3];
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_FPARAM)
{
mTrueParamValueRange[ins->mSrc[0].mVarIndex].Limit(mTrueValueRange[ins->mDst.mTemp]);
mFalseParamValueRange[ins->mSrc[0].mVarIndex].Limit(mFalseValueRange[ins->mDst.mTemp]);
}
}
}
}
@ -6527,7 +6587,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
void InterCodeBasicBlock::RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars)
void InterCodeBasicBlock::RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars)
{
if (!mVisited)
{
@ -6549,14 +6609,24 @@ void InterCodeBasicBlock::RestartLocalIntegerRangeSets(int num, const GrowingVar
vr.mMaxState = IntegerValueRange::S_UNKNOWN;
}
UpdateLocalIntegerRangeSets(localVars);
for (int i = 0; i < mEntryParamValueRange.Size(); i++)
{
IntegerValueRange& vr(mEntryParamValueRange[i]);
if (vr.mMinState == IntegerValueRange::S_UNBOUND)
vr.mMinState = IntegerValueRange::S_UNKNOWN;
if (vr.mMaxState == IntegerValueRange::S_UNBOUND)
vr.mMaxState = IntegerValueRange::S_UNKNOWN;
}
if (mTrueJump) mTrueJump->RestartLocalIntegerRangeSets(num, localVars);
if (mFalseJump) mFalseJump->RestartLocalIntegerRangeSets(num, localVars);
UpdateLocalIntegerRangeSets(localVars, paramVars);
if (mTrueJump) mTrueJump->RestartLocalIntegerRangeSets(num, localVars, paramVars);
if (mFalseJump) mFalseJump->RestartLocalIntegerRangeSets(num, localVars, paramVars);
}
}
void InterCodeBasicBlock::BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars)
void InterCodeBasicBlock::BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars)
{
if (!mVisited)
{
@ -6569,10 +6639,15 @@ void InterCodeBasicBlock::BuildLocalIntegerRangeSets(int num, const GrowingVaria
mMemoryValueSize.SetSize(num, true);
mEntryMemoryValueSize.SetSize(num, true);
UpdateLocalIntegerRangeSets(localVars);
mEntryParamValueRange.SetSize(paramVars.Size(), true);
mTrueParamValueRange.SetSize(paramVars.Size(), true);
mFalseParamValueRange.SetSize(paramVars.Size(), true);
mLocalParamValueRange.SetSize(paramVars.Size(), true);
if (mTrueJump) mTrueJump->BuildLocalIntegerRangeSets(num, localVars);
if (mFalseJump) mFalseJump->BuildLocalIntegerRangeSets(num, localVars);
UpdateLocalIntegerRangeSets(localVars, paramVars);
if (mTrueJump) mTrueJump->BuildLocalIntegerRangeSets(num, localVars, paramVars);
if (mFalseJump) mFalseJump->BuildLocalIntegerRangeSets(num, localVars, paramVars);
}
}
@ -13072,19 +13147,19 @@ void InterCodeProcedure::DisassembleDebug(const char* name)
void InterCodeProcedure::RebuildIntegerRangeSet(void)
{
ResetVisited();
mEntryBlock->RestartLocalIntegerRangeSets(mTemporaries.Size(), mLocalVars);
mEntryBlock->RestartLocalIntegerRangeSets(mTemporaries.Size(), mLocalVars, mParamVars);
do {
DisassembleDebug("tr");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true, mLocalVars));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true, mLocalVars, mParamVars));
do {
DisassembleDebug("tr");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false, mLocalVars));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false, mLocalVars, mParamVars));
assert(mTemporaries.Size() == mEntryBlock->mLocalValueRange.Size());
@ -13992,19 +14067,19 @@ void InterCodeProcedure::Close(void)
#if 1
ResetVisited();
mEntryBlock->BuildLocalIntegerRangeSets(mTemporaries.Size(), mLocalVars);
mEntryBlock->BuildLocalIntegerRangeSets(mTemporaries.Size(), mLocalVars, mParamVars);
do {
DisassembleDebug("tt");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true, mLocalVars));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(true, mLocalVars, mParamVars));
do {
DisassembleDebug("tq");
ResetVisited();
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false, mLocalVars));
} while (mEntryBlock->BuildGlobalIntegerRangeSets(false, mLocalVars, mParamVars));
DisassembleDebug("Estimated value range");

View File

@ -269,6 +269,7 @@ public:
bool IsUByte(void) const;
bool IsSByte(void) const;
bool IsUnsigned(void) const;
bool IsPositive(void) const;
bool IsNotUByte(void) const;
@ -362,6 +363,8 @@ public:
GrowingInstructionArray mLoadStoreInstructions;
GrowingIntegerValueRangeArray mEntryValueRange, mTrueValueRange, mFalseValueRange, mLocalValueRange, mReverseValueRange;
GrowingIntegerValueRangeArray mEntryParamValueRange, mTrueParamValueRange, mFalseParamValueRange, mLocalParamValueRange;
GrowingArray<int64> mMemoryValueSize, mEntryMemoryValueSize;
GrowingArray<InterCodeBasicBlock*> mEntryBlocks, mLoopPathBlocks;
@ -415,10 +418,10 @@ public:
bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars);
bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars);
void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars);
void BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars);
void UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars);
bool BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars);
void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
void BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
void UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
bool BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
void SimplifyIntegerRangeRelops(void);
GrowingIntArray mEntryRenameTable;

View File

@ -10686,6 +10686,7 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
NativeCodeBasicBlock* nblock = nproc->AllocateBlock();
NativeCodeBasicBlock* cblock = this;
int li = 1, ri = 0;
if (op == IA_CMPLEU || op == IA_CMPGU || op == IA_CMPLES || op == IA_CMPGS)
@ -10719,6 +10720,52 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
}
if (op >= IA_CMPGES && ins->mOperator <= IA_CMPLS)
{
if (ins->mSrc[li].mTemp >= 0 && ins->mSrc[ri].mTemp >= 0 && ins->mSrc[li].IsPositive() && (op == IA_CMPGS || op == IA_CMPLS))
{
cblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[ri].mTemp] + 1));
this->Close(falseJump, cblock, ASMIT_BMI);
cblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 1));
cblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[ri].mTemp] + 1));
}
else if (ins->mSrc[li].mTemp >= 0 && ins->mSrc[ri].mTemp >= 0 && ins->mSrc[ri].IsPositive() && (op == IA_CMPGES || op == IA_CMPLES))
{
cblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 1));
this->Close(falseJump, cblock, ASMIT_BMI);
cblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 1));
cblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[ri].mTemp] + 1));
}
else if (ins->mSrc[li].mTemp >= 0 && ins->mSrc[ri].mTemp >= 0 && ins->mSrc[ri].IsPositive() && (op == IA_CMPGS || op == IA_CMPLS))
{
cblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 1));
this->Close(trueJump, cblock, ASMIT_BMI);
cblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 1));
cblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[ri].mTemp] + 1));
}
else if (ins->mSrc[li].mTemp >= 0 && ins->mSrc[ri].mTemp >= 0 && ins->mSrc[li].IsPositive() && (op == IA_CMPGES || op == IA_CMPLES))
{
cblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[ri].mTemp] + 1));
this->Close(trueJump, cblock, ASMIT_BMI);
cblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 1));
cblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[ri].mTemp] + 1));
}
else
{
if (!rconst)
{
@ -10740,6 +10787,7 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
else
mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_WORK));
}
}
else
{
if (ins->mSrc[li].mTemp < 0)
@ -10752,7 +10800,7 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[ri].mTemp] + 1));
}
this->Close(nblock, eblock, ASMIT_BNE);
cblock->Close(nblock, eblock, ASMIT_BNE);
if (ins->mSrc[li].mTemp < 0)
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[li].mIntConst & 0xff));

View File

@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
#else
strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.13.177");
strcpy(strProductVersion, "1.13.178");
#ifdef __APPLE__
uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,13,177,0
PRODUCTVERSION 1,13,177,0
FILEVERSION 1,13,178,0
PRODUCTVERSION 1,13,178,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.13.177.0"
VALUE "FileVersion", "1.13.178.0"
VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.13.177.0"
VALUE "ProductVersion", "1.13.178.0"
END
END
BLOCK "VarFileInfo"

View File

@ -4450,15 +4450,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64"
"ProductCode" = "8:{F395B181-BC67-45F0-ABC6-A1DD8AF53FD3}"
"PackageCode" = "8:{9D340FCF-C068-44AE-91FF-DA164F68B9FB}"
"ProductCode" = "8:{9F4E2BAD-97D8-4D1A-981F-D6B719A704C0}"
"PackageCode" = "8:{9749B605-800D-406D-A8C7-759AA28CA93D}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.13.177"
"ProductVersion" = "8:1.13.178"
"Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"