Fixe unsigned byte signed const comparison

This commit is contained in:
drmortalwombat 2021-11-02 17:18:24 +01:00
parent dcbd51e75e
commit 099f3b8a26
3 changed files with 417 additions and 40 deletions

View File

@ -235,6 +235,118 @@ void cmp1(int8 a)
assert(bgef == ngef); 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) int main(void)
{ {
cmp( 0, 1); cmp( 0, 1);
@ -311,6 +423,44 @@ int main(void)
cmp1(-3); cmp1(-3);
cmp1(-128); 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;
} }

View File

@ -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 && 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) 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; bool toconst = false;
ins->mSrc[1].mType = tvalue[ins->mSrc[1].mTemp]->mSrc[0].mType; int cvalue = 0;
ins->mSrc[1].mTemp = tvalue[ins->mSrc[1].mTemp]->mSrc[0].mTemp;
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); 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 && 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) 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; bool toconst = false;
ins->mSrc[0].mType = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mType; int cvalue = 0;
ins->mSrc[0].mTemp = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mTemp;
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); UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
} }

View File

@ -286,7 +286,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
if (!aexp) if (!aexp)
mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand"); mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand");
else if (aexp->mType == DT_CONST_INTEGER) 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) else if (aexp->mType == DT_LABEL_REF)
{ {
if (aexp->mBase->mBase) if (aexp->mBase->mBase)
@ -308,8 +308,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
} }
else else
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined immediate operand", aexp->mBase->mIdent->mString); mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined immediate operand", aexp->mBase->mIdent->mString);
offset += 1;
} }
else if (aexp->mType == DT_VARIABLE_REF) else if (aexp->mType == DT_VARIABLE_REF)
{ {
@ -328,8 +326,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
ref.mRefOffset = aexp->mOffset; ref.mRefOffset = aexp->mOffset;
ref.mRefObject->mFlags |= LOBJF_RELEVANT; ref.mRefObject->mFlags |= LOBJF_RELEVANT;
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
offset += 1;
} }
else else
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Invalid immediate operand"); 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.mRefOffset = aexp->mOffset;
ref.mRefObject->mFlags |= LOBJF_RELEVANT; ref.mRefObject->mFlags |= LOBJF_RELEVANT;
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
offset += 1;
} }
else else
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Invalid immediate operand"); mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Invalid immediate operand");
offset += 1;
break; break;
case ASMIM_ZERO_PAGE: case ASMIM_ZERO_PAGE:
case ASMIM_ZERO_PAGE_X: case ASMIM_ZERO_PAGE_X:
@ -383,13 +379,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
ref.mRefObject->mFlags |= LOBJF_RELEVANT; ref.mRefObject->mFlags |= LOBJF_RELEVANT;
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
d[offset++] = aexp->mOffset; d[offset] = aexp->mOffset;
} }
else else
{
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Local variable outside scope"); mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Local variable outside scope");
offset += 1;
}
} }
else if (aexp->mType == DT_ARGUMENT || aexp->mType == DT_VARIABLE) 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; ref.mRefObject->mFlags |= LOBJF_RELEVANT;
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
d[offset++] = 0; d[offset] = 0;
} }
else else
{
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Local variable outside scope"); mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Local variable outside scope");
offset += 1;
}
} }
else else
d[offset++] = aexp->mInteger; d[offset] = aexp->mInteger;
offset += 1;
break; break;
case ASMIM_ABSOLUTE: case ASMIM_ABSOLUTE:
case ASMIM_INDIRECT: 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"); mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand");
else if (aexp->mType == DT_CONST_INTEGER) else if (aexp->mType == DT_CONST_INTEGER)
{ {
d[offset++] = cexp->mLeft->mDecValue->mInteger & 255; d[offset + 0] = cexp->mLeft->mDecValue->mInteger & 255;
d[offset++] = cexp->mLeft->mDecValue->mInteger >> 8; d[offset + 1] = cexp->mLeft->mDecValue->mInteger >> 8;
} }
else if (aexp->mType == DT_LABEL) else if (aexp->mType == DT_LABEL)
{ {
@ -450,8 +441,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
} }
else else
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined label"); mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined label");
offset += 2;
} }
else if (aexp->mType == DT_LABEL_REF) else if (aexp->mType == DT_LABEL_REF)
{ {
@ -471,8 +460,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
} }
else else
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined label"); mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined label");
offset += 2;
} }
else if (aexp->mType == DT_CONST_ASSEMBLER) else if (aexp->mType == DT_CONST_ASSEMBLER)
{ {
@ -487,8 +474,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
ref.mRefOffset = 0; ref.mRefOffset = 0;
ref.mRefObject->mFlags |= LOBJF_RELEVANT; ref.mRefObject->mFlags |= LOBJF_RELEVANT;
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
offset += 2;
} }
else if (aexp->mType == DT_VARIABLE) else if (aexp->mType == DT_VARIABLE)
{ {
@ -504,8 +489,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
ref.mRefOffset = 0; ref.mRefOffset = 0;
ref.mRefObject->mFlags |= LOBJF_RELEVANT; ref.mRefObject->mFlags |= LOBJF_RELEVANT;
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
offset += 2;
} }
} }
else if (aexp->mType == DT_VARIABLE_REF) else if (aexp->mType == DT_VARIABLE_REF)
@ -522,8 +505,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
ref.mRefOffset = aexp->mOffset; ref.mRefOffset = aexp->mOffset;
ref.mRefObject->mFlags |= LOBJF_RELEVANT; ref.mRefObject->mFlags |= LOBJF_RELEVANT;
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
offset += 2;
} }
} }
else if (aexp->mType == DT_CONST_FUNCTION) else if (aexp->mType == DT_CONST_FUNCTION)
@ -541,8 +522,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
ref.mRefOffset = 0; ref.mRefOffset = 0;
ref.mRefObject->mFlags |= LOBJF_RELEVANT; ref.mRefObject->mFlags |= LOBJF_RELEVANT;
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
offset += 2;
} }
else if (aexp->mType == DT_FUNCTION_REF) else if (aexp->mType == DT_FUNCTION_REF)
{ {
@ -559,9 +538,9 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
ref.mRefOffset = aexp->mOffset; ref.mRefOffset = aexp->mOffset;
ref.mRefObject->mFlags |= LOBJF_RELEVANT; ref.mRefObject->mFlags |= LOBJF_RELEVANT;
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
offset += 2;
} }
offset += 2;
break; break;
case ASMIM_RELATIVE: case ASMIM_RELATIVE:
if (!aexp) if (!aexp)