From 099f3b8a2633815dcc74cf10d92186367365dc1e Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Tue, 2 Nov 2021 17:18:24 +0100 Subject: [PATCH] Fixe unsigned byte signed const comparison --- autotest/testint8cmp.c | 154 ++++++++++++++++++- oscar64/InterCode.cpp | 260 ++++++++++++++++++++++++++++++++- oscar64/InterCodeGenerator.cpp | 43 ++---- 3 files changed, 417 insertions(+), 40 deletions(-) diff --git a/autotest/testint8cmp.c b/autotest/testint8cmp.c index 60416bc..f12d45d 100644 --- a/autotest/testint8cmp.c +++ b/autotest/testint8cmp.c @@ -235,6 +235,118 @@ void cmp1(int8 a) assert(bgef == ngef); } +void cmpu(char a, char b, bool lt, bool gt, bool eq) +{ + bool clt = a < b, cgt = a > b, ceq = a == b; + bool nlt = a >= b, ngt = a <= b, neq = a != b; + + printf("CPMPU %d, %d LT %d%d%d GT %d%d%d EQ %d%d%d\n", a, b, lt, clt, nlt, gt, cgt, ngt, eq, ceq, neq); + + assert(clt == lt); + assert(cgt == gt); + assert(ceq == eq); + + assert(nlt != lt); + assert(ngt != gt); + assert(neq != eq); +} + +void cmpu100(char a, bool lt, bool gt, bool eq) +{ + bool clt = a < 100, cgt = a > 100, ceq = a == 100; + bool nlt = a >= 100, ngt = a <= 100, neq = a != 100; + + printf("CPMPU %d, %d LT %d%d%d GT %d%d%d EQ %d%d%d\n", a, 100, lt, clt, nlt, gt, cgt, ngt, eq, ceq, neq); + + assert(clt == lt); + assert(cgt == gt); + assert(ceq == eq); + + assert(nlt != lt); + assert(ngt != gt); + assert(neq != eq); +} + +void cmpu100r(char b, bool lt, bool gt, bool eq) +{ + bool clt = 100 < b, cgt = 100 > b, ceq = 100 == b; + bool nlt = 100 >= b, ngt = 100 <= b, neq = 100 != b; + + printf("CPMPU %d, %d LT %d%d%d GT %d%d%d EQ %d%d%d\n", 100, b, lt, clt, nlt, gt, cgt, ngt, eq, ceq, neq); + + assert(clt == lt); + assert(cgt == gt); + assert(ceq == eq); + + assert(nlt != lt); + assert(ngt != gt); + assert(neq != eq); +} + +void cmpu1000(char a, bool lt, bool gt, bool eq) +{ + bool clt = a < 1000, cgt = a > 1000, ceq = a == 1000; + bool nlt = a >= 1000, ngt = a <= 1000, neq = a != 1000; + + printf("CPMPU %d, %d LT %d%d%d GT %d%d%d EQ %d%d%d\n", a, 1000, lt, clt, nlt, gt, cgt, ngt, eq, ceq, neq); + + assert(clt == lt); + assert(cgt == gt); + assert(ceq == eq); + + assert(nlt != lt); + assert(ngt != gt); + assert(neq != eq); +} + +void cmpu1000r(char b, bool lt, bool gt, bool eq) +{ + bool clt = 1000< b, cgt = 1000 > b, ceq = 1000 == b; + bool nlt = 1000 >= b, ngt = 1000 <= b, neq = 1000 != b; + + printf("CPMPU %d, %d LT %d%d%d GT %d%d%d EQ %d%d%d\n", 1000, b, lt, clt, nlt, gt, cgt, ngt, eq, ceq, neq); + + assert(clt == lt); + assert(cgt == gt); + assert(ceq == eq); + + assert(nlt != lt); + assert(ngt != gt); + assert(neq != eq); +} + +void cmpum100(char a, bool lt, bool gt, bool eq) +{ + bool clt = a < -100, cgt = a > -100, ceq = a == -100; + bool nlt = a >= -100, ngt = a <= -100, neq = a != -100; + + printf("CPMPU %d, %d LT %d%d%d GT %d%d%d EQ %d%d%d\n", a, -100, lt, clt, nlt, gt, cgt, ngt, eq, ceq, neq); + + assert(clt == lt); + assert(cgt == gt); + assert(ceq == eq); + + assert(nlt != lt); + assert(ngt != gt); + assert(neq != eq); +} + +void cmpum100r(char b, bool lt, bool gt, bool eq) +{ + bool clt = -100 < b, cgt = -100 > b, ceq = -100 == b; + bool nlt = -100 >= b, ngt = -100 <= b, neq = -100 != b; + + printf("CPMPU %d, %d LT %d%d%d GT %d%d%d EQ %d%d%d\n", -100, b, lt, clt, nlt, gt, cgt, ngt, eq, ceq, neq); + + assert(clt == lt); + assert(cgt == gt); + assert(ceq == eq); + + assert(nlt != lt); + assert(ngt != gt); + assert(neq != eq); +} + int main(void) { cmp( 0, 1); @@ -311,6 +423,44 @@ int main(void) cmp1(-3); cmp1(-128); - return 0; - + cmpu(0, 0, false, false, true); + cmpu(0, 1, true, false, false); + cmpu(1, 0, false ,true, false); + + cmpu(128, 128, false, false, true); + cmpu( 0, 128, true, false, false); + cmpu(128, 0, false ,true, false); + + cmpu(255, 255, false, false, true); + cmpu( 0, 255, true, false, false); + cmpu(255, 0, false ,true, false); + + cmpu(127, 127, false, false, true); + cmpu(128, 255, true, false, false); + cmpu(255, 128, false ,true, false); + + cmpu100(100, false, false, true); + cmpu100( 0, true, false, false); + cmpu100(130, false, true, false); + + cmpu100r(100, false, false, true); + cmpu100r(130, true, false, false); + cmpu100r( 0, false, true, false); + + cmpum100( 0, false, true, false); + cmpum100(130, false, true, false); + + cmpum100r(130, true, false, false); + cmpum100r( 0, true, false, false); + + cmpu1000(100, true, false, false); + cmpu1000( 0, true, false, false); + cmpu1000(130, true, false, false); + + cmpu1000r(100, false, true, false); + cmpu1000r(130, false, true, false); + cmpu1000r( 0, false, true, false); + + + return 0; } diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index bba64f2..bf5425c 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -1127,9 +1127,133 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_INT2FLOAT) { - ins->mSrc[0].mType = tvalue[ins->mSrc[1].mTemp]->mSrc[0].mType; - ins->mSrc[1].mType = tvalue[ins->mSrc[1].mTemp]->mSrc[0].mType; - ins->mSrc[1].mTemp = tvalue[ins->mSrc[1].mTemp]->mSrc[0].mTemp; + bool toconst = false; + int cvalue = 0; + + if (tvalue[ins->mSrc[1].mTemp]->mOperator == IA_EXT8TO16S || tvalue[ins->mSrc[1].mTemp]->mOperator == IA_EXT8TO32S) + { + int ivalue = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst; + if (ivalue < -128) + { + toconst = true; + switch (ins->mOperator) + { + case IA_CMPEQ: + case IA_CMPLES: + case IA_CMPLS: + case IA_CMPLEU: + case IA_CMPLU: + cvalue = 0; + break; + case IA_CMPNE: + case IA_CMPGES: + case IA_CMPGS: + case IA_CMPGEU: + case IA_CMPGU: + cvalue = 1; + break; + } + } + else if (ivalue > 127) + { + toconst = true; + switch (ins->mOperator) + { + case IA_CMPEQ: + case IA_CMPGES: + case IA_CMPGS: + case IA_CMPGEU: + case IA_CMPGU: + cvalue = 0; + break; + case IA_CMPNE: + case IA_CMPLES: + case IA_CMPLS: + case IA_CMPLEU: + case IA_CMPLU: + cvalue = 1; + break; + } + } + } + else if (tvalue[ins->mSrc[1].mTemp]->mOperator == IA_EXT8TO16U || tvalue[ins->mSrc[1].mTemp]->mOperator == IA_EXT8TO32U) + { + int ivalue = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst; + if (ivalue < 0) + { + toconst = true; + switch (ins->mOperator) + { + case IA_CMPEQ: + case IA_CMPLES: + case IA_CMPLS: + case IA_CMPLEU: + case IA_CMPLU: + cvalue = 0; + break; + case IA_CMPNE: + case IA_CMPGES: + case IA_CMPGS: + case IA_CMPGEU: + case IA_CMPGU: + cvalue = 1; + break; + } + } + else if (ivalue > 255) + { + toconst = true; + switch (ins->mOperator) + { + case IA_CMPEQ: + case IA_CMPGES: + case IA_CMPGS: + case IA_CMPGEU: + case IA_CMPGU: + cvalue = 0; + break; + case IA_CMPNE: + case IA_CMPLES: + case IA_CMPLS: + case IA_CMPLEU: + case IA_CMPLU: + cvalue = 1; + break; + } + } + else + { + switch (ins->mOperator) + { + case IA_CMPGES: + ins->mOperator = IA_CMPGEU; + break; + case IA_CMPLES: + ins->mOperator = IA_CMPLEU; + break; + case IA_CMPGS: + ins->mOperator = IA_CMPGU; + break; + case IA_CMPLS: + ins->mOperator = IA_CMPLU; + break; + } + } + } + + if (toconst) + { + ins->mCode = IC_CONSTANT; + ins->mConst.mIntConst = cvalue; + ins->mSrc[0].mTemp = -1; + ins->mSrc[1].mTemp = -1; + } + else + { + ins->mSrc[0].mType = tvalue[ins->mSrc[1].mTemp]->mSrc[0].mType; + ins->mSrc[1].mType = tvalue[ins->mSrc[1].mTemp]->mSrc[0].mType; + ins->mSrc[1].mTemp = tvalue[ins->mSrc[1].mTemp]->mSrc[0].mTemp; + } UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); } @@ -1137,9 +1261,133 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONSTANT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_INT2FLOAT) { - ins->mSrc[1].mType = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mType; - ins->mSrc[0].mType = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mType; - ins->mSrc[0].mTemp = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mTemp; + bool toconst = false; + int cvalue = 0; + + if (tvalue[ins->mSrc[0].mTemp]->mOperator == IA_EXT8TO16S || tvalue[ins->mSrc[0].mTemp]->mOperator == IA_EXT8TO32S) + { + int ivalue = tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst; + if (ivalue > 127) + { + toconst = true; + switch (ins->mOperator) + { + case IA_CMPEQ: + case IA_CMPLES: + case IA_CMPLS: + case IA_CMPLEU: + case IA_CMPLU: + cvalue = 0; + break; + case IA_CMPNE: + case IA_CMPGES: + case IA_CMPGS: + case IA_CMPGEU: + case IA_CMPGU: + cvalue = 1; + break; + } + } + else if (ivalue < -128) + { + toconst = true; + switch (ins->mOperator) + { + case IA_CMPEQ: + case IA_CMPGES: + case IA_CMPGS: + case IA_CMPGEU: + case IA_CMPGU: + cvalue = 0; + break; + case IA_CMPNE: + case IA_CMPLES: + case IA_CMPLS: + case IA_CMPLEU: + case IA_CMPLU: + cvalue = 1; + break; + } + } + } + else if (tvalue[ins->mSrc[0].mTemp]->mOperator == IA_EXT8TO16U || tvalue[ins->mSrc[0].mTemp]->mOperator == IA_EXT8TO32U) + { + int ivalue = tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst; + if (ivalue > 255) + { + toconst = true; + switch (ins->mOperator) + { + case IA_CMPEQ: + case IA_CMPLES: + case IA_CMPLS: + case IA_CMPLEU: + case IA_CMPLU: + cvalue = 0; + break; + case IA_CMPNE: + case IA_CMPGES: + case IA_CMPGS: + case IA_CMPGEU: + case IA_CMPGU: + cvalue = 1; + break; + } + } + else if (ivalue < 0) + { + toconst = true; + switch (ins->mOperator) + { + case IA_CMPEQ: + case IA_CMPGES: + case IA_CMPGS: + case IA_CMPGEU: + case IA_CMPGU: + cvalue = 0; + break; + case IA_CMPNE: + case IA_CMPLES: + case IA_CMPLS: + case IA_CMPLEU: + case IA_CMPLU: + cvalue = 1; + break; + } + } + else + { + switch (ins->mOperator) + { + case IA_CMPGES: + ins->mOperator = IA_CMPGEU; + break; + case IA_CMPLES: + ins->mOperator = IA_CMPLEU; + break; + case IA_CMPGS: + ins->mOperator = IA_CMPGU; + break; + case IA_CMPLS: + ins->mOperator = IA_CMPLU; + break; + } + } + } + + if (toconst) + { + ins->mCode = IC_CONSTANT; + ins->mConst.mIntConst = cvalue; + ins->mSrc[0].mTemp = -1; + ins->mSrc[1].mTemp = -1; + } + else + { + ins->mSrc[1].mType = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mType; + ins->mSrc[0].mType = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mType; + ins->mSrc[0].mTemp = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mTemp; + } UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); } diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index f2d6d67..7e45e8f 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -286,7 +286,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex if (!aexp) mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand"); else if (aexp->mType == DT_CONST_INTEGER) - d[offset++] = cexp->mLeft->mDecValue->mInteger & 255; + d[offset] = cexp->mLeft->mDecValue->mInteger & 255; else if (aexp->mType == DT_LABEL_REF) { if (aexp->mBase->mBase) @@ -308,8 +308,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex } else mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined immediate operand", aexp->mBase->mIdent->mString); - - offset += 1; } else if (aexp->mType == DT_VARIABLE_REF) { @@ -328,8 +326,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex ref.mRefOffset = aexp->mOffset; ref.mRefObject->mFlags |= LOBJF_RELEVANT; dec->mLinkerObject->AddReference(ref); - - offset += 1; } else mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Invalid immediate operand"); @@ -352,11 +348,11 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex ref.mRefOffset = aexp->mOffset; ref.mRefObject->mFlags |= LOBJF_RELEVANT; dec->mLinkerObject->AddReference(ref); - - offset += 1; } else mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Invalid immediate operand"); + + offset += 1; break; case ASMIM_ZERO_PAGE: case ASMIM_ZERO_PAGE_X: @@ -383,13 +379,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex ref.mRefObject->mFlags |= LOBJF_RELEVANT; dec->mLinkerObject->AddReference(ref); - d[offset++] = aexp->mOffset; + d[offset] = aexp->mOffset; } else - { mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Local variable outside scope"); - offset += 1; - } } else if (aexp->mType == DT_ARGUMENT || aexp->mType == DT_VARIABLE) { @@ -410,16 +403,14 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex ref.mRefObject->mFlags |= LOBJF_RELEVANT; dec->mLinkerObject->AddReference(ref); - d[offset++] = 0; + d[offset] = 0; } else - { mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Local variable outside scope"); - offset += 1; - } } else - d[offset++] = aexp->mInteger; + d[offset] = aexp->mInteger; + offset += 1; break; case ASMIM_ABSOLUTE: case ASMIM_INDIRECT: @@ -429,8 +420,8 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand"); else if (aexp->mType == DT_CONST_INTEGER) { - d[offset++] = cexp->mLeft->mDecValue->mInteger & 255; - d[offset++] = cexp->mLeft->mDecValue->mInteger >> 8; + d[offset + 0] = cexp->mLeft->mDecValue->mInteger & 255; + d[offset + 1] = cexp->mLeft->mDecValue->mInteger >> 8; } else if (aexp->mType == DT_LABEL) { @@ -450,8 +441,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex } else mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined label"); - - offset += 2; } else if (aexp->mType == DT_LABEL_REF) { @@ -471,8 +460,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex } else mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined label"); - - offset += 2; } else if (aexp->mType == DT_CONST_ASSEMBLER) { @@ -487,8 +474,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex ref.mRefOffset = 0; ref.mRefObject->mFlags |= LOBJF_RELEVANT; dec->mLinkerObject->AddReference(ref); - - offset += 2; } else if (aexp->mType == DT_VARIABLE) { @@ -504,8 +489,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex ref.mRefOffset = 0; ref.mRefObject->mFlags |= LOBJF_RELEVANT; dec->mLinkerObject->AddReference(ref); - - offset += 2; } } else if (aexp->mType == DT_VARIABLE_REF) @@ -522,8 +505,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex ref.mRefOffset = aexp->mOffset; ref.mRefObject->mFlags |= LOBJF_RELEVANT; dec->mLinkerObject->AddReference(ref); - - offset += 2; } } else if (aexp->mType == DT_CONST_FUNCTION) @@ -541,8 +522,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex ref.mRefOffset = 0; ref.mRefObject->mFlags |= LOBJF_RELEVANT; dec->mLinkerObject->AddReference(ref); - - offset += 2; } else if (aexp->mType == DT_FUNCTION_REF) { @@ -559,9 +538,9 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex ref.mRefOffset = aexp->mOffset; ref.mRefObject->mFlags |= LOBJF_RELEVANT; dec->mLinkerObject->AddReference(ref); - - offset += 2; } + + offset += 2; break; case ASMIM_RELATIVE: if (!aexp)