VarAction2: Add an ABS opcode

pull/397/head^2
Jonathan G Rennison 2 years ago
parent 3ca95a63d2
commit 6214d0d20d

@ -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,
};

Loading…
Cancel
Save