VarAction2: Detect equality comparisons
Remove redundant equality with 0 comparison before ternary
This commit is contained in:
@@ -5666,6 +5666,15 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
if (adjust.and_mask <= 1) inference = VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO;
|
||||
break;
|
||||
case DSGA_OP_AND:
|
||||
if ((prev_inference & VA2AIF_SIGNED_NON_NEGATIVE) && adjust.variable == 0x1A && adjust.shift_num == 0 && adjust.and_mask == 1) {
|
||||
DeterministicSpriteGroupAdjust &prev = group->adjusts[group->adjusts.size() - 2];
|
||||
if (prev.operation == DSGA_OP_SCMP || prev.operation == DSGA_OP_UCMP) {
|
||||
prev.operation = DSGA_OP_EQ;
|
||||
group->adjusts.pop_back();
|
||||
inference = VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (adjust.and_mask <= 1) {
|
||||
inference = VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO;
|
||||
} else if ((adjust.and_mask & (1 << ((varsize * 8) - 1))) == 0) {
|
||||
@@ -5700,6 +5709,17 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (group->adjusts.size() > 1) {
|
||||
/* Remove redundant comparison with 0 if applicable */
|
||||
const DeterministicSpriteGroupAdjust &prev = group->adjusts[group->adjusts.size() - 2];
|
||||
if (prev.type == DSGA_TYPE_NONE && prev.operation == DSGA_OP_EQ && prev.variable == 0x1A && prev.shift_num == 0 && prev.and_mask == 0) {
|
||||
DeterministicSpriteGroupAdjust current = group->adjusts.back();
|
||||
group->adjusts.pop_back();
|
||||
group->adjusts.pop_back();
|
||||
std::swap(current.and_mask, current.add_val);
|
||||
group->adjusts.push_back(current);
|
||||
}
|
||||
}
|
||||
inference = VA2AIF_PREV_TERNARY;
|
||||
}
|
||||
break;
|
||||
|
@@ -183,6 +183,7 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust &adjust, ScopeResolver
|
||||
case DSGA_OP_SHR: return (uint32)(U)last_value >> ((U)value & 0x1F);
|
||||
case DSGA_OP_SAR: return (int32)(S)last_value >> ((U)value & 0x1F);
|
||||
case DSGA_OP_TERNARY: return (last_value != 0) ? value : adjust.add_val;
|
||||
case DSGA_OP_EQ: return (last_value == value) ? 1 : 0;
|
||||
default: return value;
|
||||
}
|
||||
}
|
||||
@@ -562,6 +563,14 @@ static const char *_sg_size_names[] {
|
||||
"DWORD",
|
||||
};
|
||||
|
||||
static const char *GetAdjustOperationName(DeterministicSpriteGroupAdjustOperation operation)
|
||||
{
|
||||
if (operation < DSGA_OP_END) return _dsg_op_names[operation];
|
||||
if (operation == DSGA_OP_TERNARY) return "TERNARY";
|
||||
if (operation == DSGA_OP_EQ) return "EQ";
|
||||
return "???";
|
||||
}
|
||||
|
||||
void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint flags)
|
||||
{
|
||||
if (sg == nullptr) {
|
||||
@@ -634,7 +643,7 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint
|
||||
case DSGA_TYPE_MOD: p += seprintf(p, lastof(this->buffer), ", add: %X, mod: %X", adjust.add_val, adjust.divmod_val); break;
|
||||
case DSGA_TYPE_NONE: break;
|
||||
}
|
||||
p += seprintf(p, lastof(this->buffer), ", op: %X (%s)", adjust.operation, adjust.operation < DSGA_OP_END ? _dsg_op_names[adjust.operation] : "???");
|
||||
p += seprintf(p, lastof(this->buffer), ", op: %X (%s)", adjust.operation, GetAdjustOperationName(adjust.operation));
|
||||
this->print();
|
||||
}
|
||||
if (dsg->calculated_result) {
|
||||
|
@@ -163,6 +163,7 @@ enum DeterministicSpriteGroupAdjustOperation {
|
||||
DSGA_OP_END,
|
||||
|
||||
DSGA_OP_TERNARY = 0x80, ///< a == 0 ? b : c,
|
||||
DSGA_OP_EQ, ///< a == b ? 1 : 0,
|
||||
|
||||
DSGA_OP_SPECIAL_END,
|
||||
};
|
||||
|
Reference in New Issue
Block a user