More native code generator

This commit is contained in:
drmortalwombat 2021-09-11 15:01:32 +02:00
parent 07f797e577
commit 93b6aca8a3
20 changed files with 1083 additions and 194 deletions

View File

@ -51,6 +51,7 @@ The first release of the compiler is severely limited considering it is only two
* Missing livetime reduction of intermediates
* No block domination analysis
* No register use for arguments
* Auto variables places on fixed stack for known call sequence
### Intermediate code generation
@ -59,7 +60,8 @@ The first release of the compiler is severely limited considering it is only two
### Native code generation
* Missing
* Calling non native functions missing
* More byte operation optimisation required
## Implementation Details
@ -109,6 +111,15 @@ The intermediate code generator assumes a large number of registers so the zero
* **0x43-0x52** caller saved registers
* **0x53-0x8f** callee saved registers
Routines can be marked to be compiled to 6502 machine code with the native pragma:
void Plot(int x, int y)
{
(*Bitmap)[y >> 3][x >> 3][y & 7] |= 0x80 >> (x & 7);
}
#pragma native(Plot)

View File

@ -39,6 +39,9 @@ if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e testint16cmp.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e floatstringtest.c
if %errorlevel% neq 0 goto :error
exit /b 0
:error
echo Failed with error #%errorlevel%.

94
autotest/bitshifttest.c Normal file
View File

@ -0,0 +1,94 @@
#include <stdio.h>
unsigned shl1b(int n)
{
return 1 << n;
}
unsigned shl1n(int n)
{
return 1 << n;
}
#pragma native(shl1n)
unsigned shr1b(int n)
{
return 0x8000 >> n;
}
unsigned shr1n(int n)
{
return 0x8000 >> n;
}
#pragma native(shr1n)
unsigned shl4b(int n)
{
return 0x0010 << n;
}
unsigned shl4n(int n)
{
return 0x0010 << n;
}
#pragma native(shl4n)
unsigned shr4b(int n)
{
return 0x0800 >> n;
}
unsigned shr4n(int n)
{
return 0x0800 >> n;
}
#pragma native(shr4n)
unsigned shl8b(int n)
{
return 0x0100 << n;
}
unsigned shl8n(int n)
{
return 0x0100 << n;
}
#pragma native(shl8n)
unsigned shr8b(int n)
{
return 0x0080 >> n;
}
unsigned shr8n(int n)
{
return 0x0080 >> n;
}
#pragma native(shr8n)
int main(void)
{
for(int i=0; i<32; i++)
{
printf("1: %.4x : %.4x | %.4x : %.4x\n", shl1b(i), shl1n(i), shr1b(i), shr1n(i));
}
for(int i=0; i<32; i++)
{
printf("4: %.4x : %.4x | %.4x : %.4x\n", shl4b(i), shl4n(i), shr4b(i), shr4n(i));
}
for(int i=0; i<32; i++)
{
printf("8: %.4x : %.4x | %.4x : %.4x\n", shl8b(i), shl8n(i), shr8b(i), shr8n(i));
}
return 0;
}

View File

@ -0,0 +1,25 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
float x = 1.0, y = 1.0;
char xb[20], yb[20];
for(int i=0; i<40; i++)
{
ftoa(x, xb); float xr = atof(xb);
ftoa(y, yb); float yr = atof(yb);
// printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, y, fabs(x - xr) / x, fabs(y - yr) / y);
if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001)
return -1;
x *= 2.5;
y *= 0.8;
}
return 0;
}

View File

@ -295,6 +295,30 @@ P1:
}
#pragma bytecode(BC_JSR, inp_jsr)
__asm inp_native
{
tya
clc
adc ip
sta P1 + 1
lda ip + 1
adc #0
sta P1 + 2
P1:
jsr $0000
ldy #0
lda (sp), y
sta ip
iny
lda (sp), y
sta ip + 1
dey
jmp startup.exec
}
#pragma bytecode(BC_NATIVE, inp_native)
__asm inp_const_p8
{
lda (ip), y
@ -2532,6 +2556,18 @@ __asm inp_op_abs_f32
unsigned char ubitmask[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
unsigned char bitshift[56] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#pragma runtime(bitshift, bitshift)
__asm fround {
ffloor:
bit accu + 3

View File

@ -145,7 +145,9 @@ enum ByteCode
BC_JSR,
BC_COPY,
BC_COPY_LONG
BC_COPY_LONG,
BC_NATIVE = 0x75
};
#pragma compile("crt.c")

View File

@ -176,7 +176,7 @@ float log10(float f)
float pow(float p, float q)
{
return exp(p * log(q));
return exp(q * log(p));
}
float sqrt(float f)

View File

@ -1,6 +1,7 @@
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "math.h"
void itoa(int n, char * s, int radix)
{
@ -164,6 +165,90 @@ int atoi(const char * s)
return v;
}
const float tpow10[7] = {1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0};
float atof(const char * s)
{
char c;
while ((c = *s++) <= ' ')
if (!c) return 0;
bool neg = false;
if (c == '-')
{
neg = true;
c = *s++;
}
else if (c == '+')
c = *s++;
float v = 0;
while (c >= '0' && c <= '9')
{
v = v * 10 + (c - '0');
c = *s++;
}
if (c == '.')
{
float d = 1.0;
c = *s++;
while (c >= '0' && c <= '9')
{
v = v * 10 + (c - '0');
d = d * 10;
c = *s++;
}
v /= d;
}
if (c == 'e' || c == 'E')
{
c = *s++;
bool eneg = false;
if (c == '-')
{
eneg = true;
c = *s++;
}
else if (c == '+')
c = *s++;
int e = 0;
while (c >= '0' && c <= '9')
{
e = e * 10 + (c - '0');
c = *s++;
}
if (eneg)
{
while (e > 6)
{
v /= 1000000.0;
e -= 6;
}
v /= tpow10[e];
}
else
{
while (e > 6)
{
v *= 1000000.0;
e -= 6;
}
v *= tpow10[e];
}
}
if (neg)
v = -v;
return v;
}
void exit(int status)
{
__asm {

View File

@ -9,6 +9,8 @@ void ftoa(float f, char * s);
int atoi(const char * s);
float atof(const char * s);
void exit(int status);
void * malloc(unsigned int size);

View File

@ -1556,6 +1556,7 @@ void ByteCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInst
bins.mRelocate = true;
bins.mVIndex = ins.mVarIndex;
bins.mFunction = ins.mMemory == IM_PROCEDURE;
bins.mValue = ins.mSIntConst[0];
mIns.Push(bins);
}
@ -3546,51 +3547,51 @@ void ByteCodeGenerator::WriteAsmFile(FILE * file, Address & addr)
switch (d.mMode)
{
case ASMIM_IMPLIED:
fprintf(file, "%04x : %02x __ __ %s\n", iip, mMemory[ip], AsmInstructionNames[d.mType]);
fprintf(file, "%04x : %02x __ __ %s\n", iip, mMemory[iip], AsmInstructionNames[d.mType]);
break;
case ASMIM_IMMEDIATE:
addr = mMemory[ip++];
fprintf(file, "%04x : %02x %02x __ %s #$%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x __ %s #$%02x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_ZERO_PAGE:
addr = mMemory[ip++];
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_ZERO_PAGE_X:
addr = mMemory[ip++];
fprintf(file, "%04x : %02x %02x __ %s $%02x,x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x __ %s $%02x,x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_ZERO_PAGE_Y:
addr = mMemory[ip++];
fprintf(file, "%04x : %02x %02x __ %s $%02x,y\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x __ %s $%02x,y\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_ABSOLUTE:
addr = mMemory[ip] + 256 * mMemory[ip + 1];
fprintf(file, "%04x : %02x %02x %02x %s $%04x\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x %02x %s $%04x\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
ip += 2;
break;
case ASMIM_ABSOLUTE_X:
addr = mMemory[ip] + 256 * mMemory[ip + 1];
fprintf(file, "%04x : %02x %02x %02x %s $%04x,x\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x %02x %s $%04x,x\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
ip += 2;
break;
case ASMIM_ABSOLUTE_Y:
addr = mMemory[ip] + 256 * mMemory[ip + 1];
fprintf(file, "%04x : %02x %02x %02x %s $%04x,y\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x %02x %s $%04x,y\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
ip += 2;
break;
case ASMIM_INDIRECT:
addr = mMemory[ip] + 256 * mMemory[ip + 1];
ip += 2;
fprintf(file, "%04x : %02x %02x %02x %s ($%04x)\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x %02x %s ($%04x)\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_INDIRECT_X:
addr = mMemory[ip++];
fprintf(file, "%04x : %02x %02x __ %s ($%02x,x)\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x __ %s ($%02x,x)\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_INDIRECT_Y:
addr = mMemory[ip++];
fprintf(file, "%04x : %02x %02x __ %s ($%02x),y\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x __ %s ($%02x),y\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_RELATIVE:
addr = mMemory[ip++];
@ -3598,7 +3599,7 @@ void ByteCodeGenerator::WriteAsmFile(FILE * file, Address & addr)
addr = addr + ip - 256;
else
addr = addr + ip;
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
}
}

View File

@ -134,7 +134,9 @@ enum ByteCode
BC_JSR,
BC_COPY,
BC_COPY_LONG
BC_COPY_LONG,
BC_NATIVE = 0x75
};
class ByteCodeProcedure;

View File

@ -143,7 +143,13 @@ bool Compiler::GenerateCode(void)
index = bcdec->mBase->mVarIndex;
offset = bcdec->mInteger;
}
else if (bcdec->mType == DT_VARIABLE)
{
if (bcdec->mBase->mVarIndex < 0)
mInterCodeGenerator->InitGlobalVariable(mInterCodeModule, bcdec);
index = bcdec->mVarIndex;
offset = bcdec->mOffset + mByteCodeGenerator->mRelocations[i].mOffset;
}
assert(index > 0);
mInterCodeModule->UseGlobal(index);

View File

@ -1593,6 +1593,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
ins.mMemory = tvalue[ins.mSTemp[0]]->mMemory;
ins.mVarIndex = tvalue[ins.mSTemp[0]]->mVarIndex;
ins.mOperandSize = tvalue[ins.mSTemp[0]]->mOperandSize;
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
ins.mSTemp[0] = -1;
}
@ -2708,6 +2709,9 @@ static bool CanBypassStore(const InterInstruction& sins, const InterInstruction&
return false;
}
if (sins.mMemory == IM_FRAME && (bins.mCode == IC_PUSH_FRAME || bins.mCode == IC_POP_FRAME))
return false;
// Side effects
if (bins.mCode == IC_CALL || bins.mCode == IC_JSR)
return false;

View File

@ -341,9 +341,17 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins.mTType = InterTypeOf(dec->mBase);
ins.mTTemp = proc->AddTemporary(ins.mTType);
if (ins.mTType == IT_SIGNED)
{
if (dec->mInteger < -32768 || dec->mInteger > 32767)
mErrors->Warning(dec->mLocation, "Integer constant truncated");
ins.mIntValue = short(dec->mInteger);
}
else
{
if (dec->mInteger < 0 || dec->mInteger > 65535)
mErrors->Warning(dec->mLocation, "Unsigned integer constant truncated");
ins.mIntValue = unsigned short(dec->mInteger);
}
block->Append(ins);
return ExValue(dec->mBase, ins.mTTemp);
@ -597,32 +605,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
}
else
{
if (vll.mType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
{
InterInstruction cins;
cins.mCode = IC_CONVERSION_OPERATOR;
cins.mOperator = IA_FLOAT2INT;
cins.mSType[0] = InterTypeOf(vr.mType);
cins.mSTemp[0] = vr.mTemp;
cins.mTType = InterTypeOf(vll.mType);
cins.mTTemp = proc->AddTemporary(cins.mTType);
vr.mTemp = cins.mTTemp;
vr.mType = TheSignedIntTypeDeclaration;
block->Append(cins);
}
else if (vll.mType->mType == DT_TYPE_FLOAT && vr.mType->IsIntegerType())
{
InterInstruction cins;
cins.mCode = IC_CONVERSION_OPERATOR;
cins.mOperator = IA_INT2FLOAT;
cins.mSType[0] = InterTypeOf(vr.mType);
cins.mSTemp[0] = vr.mTemp;
cins.mTType = InterTypeOf(vll.mType);;
cins.mTTemp = proc->AddTemporary(cins.mTType);
vr.mTemp = cins.mTTemp;
vr.mType = TheFloatTypeDeclaration;
block->Append(cins);
}
vr = CoerceType(proc, block, vr, vll.mType);
InterInstruction oins;
oins.mCode = IC_BINARY_OPERATOR;
@ -1406,7 +1389,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
mErrors->Error(exp->mLocation, "Not enough arguments for function call");
InterInstruction cins;
if (exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
if (exp->mLeft->mDecValue && exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
cins.mCode = IC_JSR;
else
cins.mCode = IC_CALL;
@ -2139,10 +2122,27 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
__int64 t = cast.i;
for (int i = 0; i < 4; i++)
{
dp[i] = t & 0xff;
dp[offset + i] = t & 0xff;
t >>= 8;
}
}
else if (data->mType == DT_CONST_FUNCTION)
{
if (data->mVarIndex < 0)
{
InterCodeProcedure* cproc = this->TranslateProcedure(mod, data->mValue, data);
cproc->ReduceTemporaries();
}
InterVariable::Reference ref;
ref.mAddr = offset;
ref.mLower = true;
ref.mUpper = true;
ref.mFunction = true;
ref.mIndex = data->mVarIndex;
ref.mOffset = 0;
references.Push(ref);
}
else if (data->mType == DT_CONST_POINTER)
{
Expression* exp = data->mValue;

View File

@ -22,6 +22,7 @@ public:
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
void TranslateAssembler(InterCodeModule* mod, Expression * exp);
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
protected:
Errors* mErrors;
@ -30,7 +31,6 @@ protected:
ExValue CoerceType(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, Declaration * type);
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock);
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp);
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, GrowingArray<InterVariable::Reference> & references);
};

File diff suppressed because it is too large Load Diff

View File

@ -28,19 +28,23 @@ class NativeCodeInstruction
{
public:
NativeCodeInstruction(AsmInsType type = ASMIT_INV, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, int varIndex = -1, bool lower = true, bool upper = true);
NativeCodeInstruction(AsmInsType type, AsmInsMode mode, const char* runtime, int address = 0, bool lower = true, bool upper = true);
NativeCodeInstruction(const char* runtime);
AsmInsType mType;
AsmInsMode mMode;
int mAddress, mVarIndex;
bool mLower, mUpper;
bool mLower, mUpper, mFunction;
const char * mRuntime;
void Assemble(NativeCodeBasicBlock* block);
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
bool IsUsedResultInstructions(NumberSet& requiredTemps);
bool ValueForwarding(NativeRegisterDataSet& data);
bool LoadsAccu(void) const;
bool ChangesAddress(void) const;
};
class NativeCodeBasicBlock
@ -77,6 +81,7 @@ public:
void PutWord(uint16 code);
void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction& ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh);
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction& ins, InterType type, int reg);
void LoadConstant(InterCodeProcedure* proc, const InterInstruction& ins);
void StoreValue(InterCodeProcedure* proc, const InterInstruction& ins);
@ -88,6 +93,12 @@ public:
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins);
void NumericConversion(InterCodeProcedure* proc, const InterInstruction& ins);
void CallAssembler(InterCodeProcedure* proc, const InterInstruction& ins);
void CallFunction(InterCodeProcedure* proc, const InterInstruction& ins);
void ShiftRegisterLeft(InterCodeProcedure* proc, int reg, int shift);
int ShortMultiply(InterCodeProcedure* proc, const InterInstruction& ins, const InterInstruction* sins, int index, int mul);
bool CheckPredAccuStore(int reg);
NumberSet mLocalRequiredRegs, mLocalProvidedRegs;
@ -98,6 +109,8 @@ public:
void BuildGlobalProvidedRegSet(NumberSet fromProvidedTemps);
bool BuildGlobalRequiredRegSet(NumberSet& fromRequiredTemps);
bool RemoveUnusedResultInstructions(void);
bool MoveLoadStoreUp(int at);
};
class NativeCodeProcedure

View File

@ -804,11 +804,11 @@ Expression* Parser::ParseSimpleExpression(void)
break;
case TK_INTEGER:
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
dec->mInteger = mScanner->mTokenInteger;
if (dec->mInteger < 32768)
dec->mBase = TheSignedIntTypeDeclaration;
else
dec->mBase = TheUnsignedIntTypeDeclaration;
dec->mInteger = mScanner->mTokenInteger;
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
exp->mDecValue = dec;
exp->mDecType = dec->mBase;
@ -993,6 +993,8 @@ Expression* Parser::ParsePostfixExpression(void)
else
mErrors->Error(mScanner->mLocation, "']' expected");
nexp->mDecType = exp->mDecType->mBase;
if (!nexp->mDecType)
nexp->mDecType = TheVoidTypeDeclaration;
exp = nexp;
}
else if (mScanner->mToken == TK_OPEN_PARENTHESIS)
@ -2224,9 +2226,13 @@ void Parser::ParsePragma(void)
}
if (rtident)
{
mCompilationUnits->mRuntimeScope->Insert(rtident, dec);
}
else if (dec && dec->mType == DT_VARIABLE && (dec->mFlags & DTF_GLOBAL))
{
if (rtident)
mCompilationUnits->mRuntimeScope->Insert(rtident, dec);
mScanner->NextToken();
}
else
{

View File

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

View File

@ -147,6 +147,14 @@
"PrerequisitesLocation" = "2:1"
"Url" = "8:"
"ComponentsUrl" = "8:"
"Items"
{
"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
{
"Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)"
"ProductCode" = "8:.NETFramework,Version=v4.7.2"
}
}
}
}
}
@ -496,15 +504,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64"
"ProductCode" = "8:{468390A3-2F63-4CA4-9043-3B1AEEA1852F}"
"PackageCode" = "8:{A55AE2BA-C814-4AD7-BBB6-00042C360D73}"
"ProductCode" = "8:{B20D936B-B9E1-4135-B9AA-8C367043CF71}"
"PackageCode" = "8:{63E1E188-3AB3-4767-B84A-CDB7F9FC9E10}"
"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.0.23"
"ProductVersion" = "8:1.0.24"
"Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"