VarAction2: Add an ABS opcode
This commit is contained in:
@@ -5633,8 +5633,9 @@ enum VarAction2AdjustInferenceFlags {
|
||||
VA2AIF_HAVE_CONSTANT = 0x20,
|
||||
VA2AIF_SINGLE_LOAD = 0x40,
|
||||
VA2AIF_MUL_BOOL = 0x80,
|
||||
VA2AIF_PREV_SCMP_DEC = 0x100,
|
||||
|
||||
VA2AIF_PREV_MASK = VA2AIF_PREV_TERNARY | VA2AIF_PREV_MASK_ADJUST | VA2AIF_PREV_STORE_TMP,
|
||||
VA2AIF_PREV_MASK = VA2AIF_PREV_TERNARY | VA2AIF_PREV_MASK_ADJUST | VA2AIF_PREV_STORE_TMP | VA2AIF_PREV_SCMP_DEC,
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(VarAction2AdjustInferenceFlags)
|
||||
|
||||
@@ -6322,6 +6323,12 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp
|
||||
}
|
||||
}
|
||||
}
|
||||
if (adjust.variable == 0x1A && adjust.shift_num == 0 && adjust.and_mask == 1 && group->adjusts.size() >= 2) {
|
||||
DeterministicSpriteGroupAdjust &prev = group->adjusts[group->adjusts.size() - 2];
|
||||
if (prev.operation == DSGA_OP_SCMP) {
|
||||
state.inference |= VA2AIF_PREV_SCMP_DEC;
|
||||
}
|
||||
}
|
||||
try_merge_with_previous();
|
||||
break;
|
||||
case DSGA_OP_SMIN:
|
||||
@@ -6543,6 +6550,23 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp
|
||||
state.inference = VA2AIF_PREV_TERNARY;
|
||||
break;
|
||||
}
|
||||
if ((prev_inference & VA2AIF_PREV_SCMP_DEC) && group->adjusts.size() >= 4 && adjust.variable == 0x7D && adjust.shift_num == 0 && adjust.and_mask == 0xFFFFFFFF) {
|
||||
const DeterministicSpriteGroupAdjust &adj1 = group->adjusts[group->adjusts.size() - 4];
|
||||
const DeterministicSpriteGroupAdjust &adj2 = group->adjusts[group->adjusts.size() - 3];
|
||||
const DeterministicSpriteGroupAdjust &adj3 = group->adjusts[group->adjusts.size() - 2];
|
||||
auto is_expected_op = [](const DeterministicSpriteGroupAdjust &adj, DeterministicSpriteGroupAdjustOperation op, uint32 value) -> bool {
|
||||
return adj.operation == op && adj.type == DSGA_TYPE_NONE && adj.variable == 0x1A && adj.shift_num == 0 && adj.and_mask == value;
|
||||
};
|
||||
if (is_expected_op(adj1, DSGA_OP_STO, (adjust.parameter & 0xFF)) &&
|
||||
is_expected_op(adj2, DSGA_OP_SCMP, 0) &&
|
||||
is_expected_op(adj3, DSGA_OP_SUB, 1)) {
|
||||
group->adjusts.pop_back();
|
||||
group->adjusts.pop_back();
|
||||
group->adjusts.back().operation = DSGA_OP_ABS;
|
||||
state.inference |= VA2AIF_SIGNED_NON_NEGATIVE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint32 sign_bit = (1 << ((varsize * 8) - 1));
|
||||
if ((prev_inference & VA2AIF_PREV_MASK_ADJUST) && (prev_inference & VA2AIF_SIGNED_NON_NEGATIVE) && adjust.variable == 0x1A && adjust.shift_num == 0 && (adjust.and_mask & sign_bit) == 0) {
|
||||
/* Determine whether the result will be always non-negative */
|
||||
|
@@ -200,6 +200,7 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust &adjust, ScopeResolver
|
||||
case DSGA_OP_SGT: return ((S)last_value > (S)value) ? 1 : 0;
|
||||
case DSGA_OP_RSUB: return value - last_value;
|
||||
case DSGA_OP_STO_NC: _temp_store.StoreValue(adjust.divmod_val, (S)value); return last_value;
|
||||
case DSGA_OP_ABS: return ((S)last_value < 0) ? -((S)last_value) : (S)last_value;
|
||||
default: return value;
|
||||
}
|
||||
}
|
||||
@@ -683,6 +684,7 @@ static const char *_dsg_op_special_names[] {
|
||||
"SGT",
|
||||
"RSUB",
|
||||
"STO_NC",
|
||||
"ABS",
|
||||
};
|
||||
static_assert(lengthof(_dsg_op_special_names) == DSGA_OP_SPECIAL_END - DSGA_OP_TERNARY);
|
||||
|
||||
@@ -727,6 +729,11 @@ static char *DumpSpriteGroupAdjust(char *p, const char *last, const Deterministi
|
||||
append_flags();
|
||||
return p;
|
||||
}
|
||||
if (adjust.operation == DSGA_OP_ABS) {
|
||||
p += seprintf(p, last, "%*sABS", padding, "");
|
||||
append_flags();
|
||||
return p;
|
||||
}
|
||||
if (adjust.operation == DSGA_OP_STO && adjust.type == DSGA_TYPE_NONE && adjust.variable == 0x1A && adjust.shift_num == 0) {
|
||||
/* Temp storage store */
|
||||
highlight_tag = (1 << 16) | (adjust.and_mask & 0xFFFF);
|
||||
|
@@ -198,6 +198,7 @@ enum DeterministicSpriteGroupAdjustOperation : uint8 {
|
||||
DSGA_OP_SGT, ///< (signed) a > b ? 1 : 0,
|
||||
DSGA_OP_RSUB, ///< b - a
|
||||
DSGA_OP_STO_NC, ///< store b into temporary storage, indexed by c. return a
|
||||
DSGA_OP_ABS, ///< abs(a)
|
||||
|
||||
DSGA_OP_SPECIAL_END,
|
||||
};
|
||||
|
Reference in New Issue
Block a user