VarAction2: Add a JNZ op analogous to JZ for OR ops
This commit is contained in:
@@ -6915,7 +6915,13 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp
|
|||||||
}
|
}
|
||||||
if (adjust.and_mask <= 1) state.inference = prev_inference & (VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO);
|
if (adjust.and_mask <= 1) state.inference = prev_inference & (VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO);
|
||||||
state.inference |= prev_inference & (VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO) & non_const_var_inference;
|
state.inference |= prev_inference & (VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO) & non_const_var_inference;
|
||||||
if ((non_const_var_inference & VA2AIF_ONE_OR_ZERO) || (adjust.and_mask <= 1)) adjust.adjust_flags |= DSGAF_SKIP_ON_LSB_SET;
|
if ((non_const_var_inference & VA2AIF_ONE_OR_ZERO) || (adjust.and_mask <= 1)) {
|
||||||
|
adjust.adjust_flags |= DSGAF_SKIP_ON_LSB_SET;
|
||||||
|
if (prev_inference & VA2AIF_ONE_OR_ZERO) {
|
||||||
|
adjust.adjust_flags |= DSGAF_JUMP_INS_HINT;
|
||||||
|
group->dsg_flags |= DSGF_CHECK_INSERT_JUMP;
|
||||||
|
}
|
||||||
|
}
|
||||||
try_merge_with_previous();
|
try_merge_with_previous();
|
||||||
break;
|
break;
|
||||||
case DSGA_OP_XOR:
|
case DSGA_OP_XOR:
|
||||||
@@ -7332,7 +7338,7 @@ static bool OptimiseVarAction2DeterministicSpriteGroupExpensiveVarsInner(Determi
|
|||||||
bool seen_first = false;
|
bool seen_first = false;
|
||||||
for (int j = end; j >= start; j--) {
|
for (int j = end; j >= start; j--) {
|
||||||
DeterministicSpriteGroupAdjust &adjust = group->adjusts[j];
|
DeterministicSpriteGroupAdjust &adjust = group->adjusts[j];
|
||||||
if (seen_first && adjust.operation == DSGA_OP_JZ && condition_depth > 0) {
|
if (seen_first && IsEvalAdjustJumpOperation(adjust.operation) && condition_depth > 0) {
|
||||||
/* Do not insert the STO_NC inside a conditional block when it is also needed outside the block */
|
/* Do not insert the STO_NC inside a conditional block when it is also needed outside the block */
|
||||||
condition_depth--;
|
condition_depth--;
|
||||||
insert_pos = j;
|
insert_pos = j;
|
||||||
@@ -7645,7 +7651,7 @@ static void OptimiseVarAction2DeterministicSpriteGroupInsertJumps(DeterministicS
|
|||||||
if (prev.operation == DSGA_OP_STO && (prev.type != DSGA_TYPE_NONE || prev.variable != 0x1A || prev.shift_num != 0 || prev.and_mask >= 0x100)) break;
|
if (prev.operation == DSGA_OP_STO && (prev.type != DSGA_TYPE_NONE || prev.variable != 0x1A || prev.shift_num != 0 || prev.and_mask >= 0x100)) break;
|
||||||
if (prev.operation == DSGA_OP_STO_NC && prev.divmod_val >= 0x100) break;
|
if (prev.operation == DSGA_OP_STO_NC && prev.divmod_val >= 0x100) break;
|
||||||
if (prev.operation == DSGA_OP_STOP) break;
|
if (prev.operation == DSGA_OP_STOP) break;
|
||||||
if (prev.operation == DSGA_OP_JZ) break;
|
if (IsEvalAdjustJumpOperation(prev.operation)) break;
|
||||||
if (prev.variable == 0x7E) break;
|
if (prev.variable == 0x7E) break;
|
||||||
|
|
||||||
/* Reached a store which can't be skipped over because the value is needed later */
|
/* Reached a store which can't be skipped over because the value is needed later */
|
||||||
@@ -7676,8 +7682,8 @@ static void OptimiseVarAction2DeterministicSpriteGroupInsertJumps(DeterministicS
|
|||||||
current.adjust_flags &= ~DSGAF_END_BLOCK;
|
current.adjust_flags &= ~DSGAF_END_BLOCK;
|
||||||
current.jump = 0;
|
current.jump = 0;
|
||||||
}
|
}
|
||||||
current.operation = DSGA_OP_JZ;
|
current.operation = (current.adjust_flags & DSGAF_SKIP_ON_LSB_SET) ? DSGA_OP_JNZ : DSGA_OP_JZ;
|
||||||
current.adjust_flags &= ~(DSGAF_JUMP_INS_HINT | DSGAF_SKIP_ON_ZERO);
|
current.adjust_flags &= ~(DSGAF_JUMP_INS_HINT | DSGAF_SKIP_ON_ZERO | DSGAF_SKIP_ON_LSB_SET);
|
||||||
mark_end_block(group->adjusts[i - 1], 1);
|
mark_end_block(group->adjusts[i - 1], 1);
|
||||||
group->adjusts.erase(group->adjusts.begin() + i);
|
group->adjusts.erase(group->adjusts.begin() + i);
|
||||||
if (j >= 0 && current.variable == 0x7D && (current.adjust_flags & DSGAF_LAST_VAR_READ)) {
|
if (j >= 0 && current.variable == 0x7D && (current.adjust_flags & DSGAF_LAST_VAR_READ)) {
|
||||||
@@ -7706,7 +7712,7 @@ struct ResolveJumpInnerResult {
|
|||||||
static ResolveJumpInnerResult OptimiseVarAction2DeterministicSpriteResolveJumpsInner(DeterministicSpriteGroup *group, const uint start)
|
static ResolveJumpInnerResult OptimiseVarAction2DeterministicSpriteResolveJumpsInner(DeterministicSpriteGroup *group, const uint start)
|
||||||
{
|
{
|
||||||
for (uint i = start + 1; i < (uint)group->adjusts.size(); i++) {
|
for (uint i = start + 1; i < (uint)group->adjusts.size(); i++) {
|
||||||
if (group->adjusts[i].operation == DSGA_OP_JZ) {
|
if (IsEvalAdjustJumpOperation(group->adjusts[i].operation)) {
|
||||||
ResolveJumpInnerResult result = OptimiseVarAction2DeterministicSpriteResolveJumpsInner(group, i);
|
ResolveJumpInnerResult result = OptimiseVarAction2DeterministicSpriteResolveJumpsInner(group, i);
|
||||||
i = result.end_index;
|
i = result.end_index;
|
||||||
if (result.end_block_remaining > 0) {
|
if (result.end_block_remaining > 0) {
|
||||||
@@ -7727,7 +7733,7 @@ static void OptimiseVarAction2DeterministicSpriteResolveJumps(DeterministicSprit
|
|||||||
if (HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2_INSERT_JUMPS)) return;
|
if (HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2_INSERT_JUMPS)) return;
|
||||||
|
|
||||||
for (uint i = 0; i < (uint)group->adjusts.size(); i++) {
|
for (uint i = 0; i < (uint)group->adjusts.size(); i++) {
|
||||||
if (group->adjusts[i].operation == DSGA_OP_JZ) {
|
if (IsEvalAdjustJumpOperation(group->adjusts[i].operation)) {
|
||||||
ResolveJumpInnerResult result = OptimiseVarAction2DeterministicSpriteResolveJumpsInner(group, i);
|
ResolveJumpInnerResult result = OptimiseVarAction2DeterministicSpriteResolveJumpsInner(group, i);
|
||||||
i = result.end_index;
|
i = result.end_index;
|
||||||
assert(result.end_block_remaining == 0);
|
assert(result.end_block_remaining == 0);
|
||||||
|
@@ -212,6 +212,16 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust &adjust, ScopeResolver
|
|||||||
return last_value;
|
return last_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case DSGA_OP_JNZ: {
|
||||||
|
if (value != 0 && adjust_iter != nullptr) {
|
||||||
|
/* Jump */
|
||||||
|
(*adjust_iter) += adjust.jump;
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
/* Don't jump */
|
||||||
|
return last_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
default: return value;
|
default: return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -700,6 +710,7 @@ static const char *_dsg_op_special_names[] {
|
|||||||
"STO_NC",
|
"STO_NC",
|
||||||
"ABS",
|
"ABS",
|
||||||
"JZ",
|
"JZ",
|
||||||
|
"JNZ",
|
||||||
};
|
};
|
||||||
static_assert(lengthof(_dsg_op_special_names) == DSGA_OP_SPECIAL_END - DSGA_OP_TERNARY);
|
static_assert(lengthof(_dsg_op_special_names) == DSGA_OP_SPECIAL_END - DSGA_OP_TERNARY);
|
||||||
|
|
||||||
@@ -753,7 +764,7 @@ static char *DumpSpriteGroupAdjust(char *p, const char *last, const Deterministi
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (adjust.operation == DSGA_OP_JZ) {
|
if (IsEvalAdjustJumpOperation(adjust.operation)) {
|
||||||
conditional_indent++;
|
conditional_indent++;
|
||||||
}
|
}
|
||||||
if (adjust.adjust_flags & DSGAF_END_BLOCK) {
|
if (adjust.adjust_flags & DSGAF_END_BLOCK) {
|
||||||
@@ -801,7 +812,7 @@ static char *DumpSpriteGroupAdjust(char *p, const char *last, const Deterministi
|
|||||||
}
|
}
|
||||||
p += seprintf(p, last, ", op: ");
|
p += seprintf(p, last, ", op: ");
|
||||||
p = GetAdjustOperationName(p, last, adjust.operation);
|
p = GetAdjustOperationName(p, last, adjust.operation);
|
||||||
if (adjust.operation == DSGA_OP_JZ) {
|
if (IsEvalAdjustJumpOperation(adjust.operation)) {
|
||||||
p += seprintf(p, last, " +%u", adjust.jump);
|
p += seprintf(p, last, " +%u", adjust.jump);
|
||||||
}
|
}
|
||||||
append_flags();
|
append_flags();
|
||||||
|
@@ -207,6 +207,7 @@ enum DeterministicSpriteGroupAdjustOperation : uint8 {
|
|||||||
DSGA_OP_STO_NC, ///< store b into temporary storage, indexed by c. return a
|
DSGA_OP_STO_NC, ///< store b into temporary storage, indexed by c. return a
|
||||||
DSGA_OP_ABS, ///< abs(a)
|
DSGA_OP_ABS, ///< abs(a)
|
||||||
DSGA_OP_JZ, ///< jump forward fixed number of adjusts (to adjust after DSGAF_END_BLOCK marker (taking into account nesting)) if b is zero. return 0 if jumped, return a if not jumped
|
DSGA_OP_JZ, ///< jump forward fixed number of adjusts (to adjust after DSGAF_END_BLOCK marker (taking into account nesting)) if b is zero. return 0 if jumped, return a if not jumped
|
||||||
|
DSGA_OP_JNZ, ///< jump forward fixed number of adjusts (to adjust after DSGAF_END_BLOCK marker (taking into account nesting)) if b is non-zero. return b if jumped, return a if not jumped
|
||||||
|
|
||||||
DSGA_OP_SPECIAL_END,
|
DSGA_OP_SPECIAL_END,
|
||||||
};
|
};
|
||||||
@@ -402,6 +403,18 @@ inline bool IsEvalAdjustWithZeroLastValueAlwaysZero(DeterministicSpriteGroupAdju
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool IsEvalAdjustJumpOperation(DeterministicSpriteGroupAdjustOperation op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case DSGA_OP_JZ:
|
||||||
|
case DSGA_OP_JNZ:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline bool IsConstantComparisonAdjustType(DeterministicSpriteGroupAdjustType adjust_type)
|
inline bool IsConstantComparisonAdjustType(DeterministicSpriteGroupAdjustType adjust_type)
|
||||||
{
|
{
|
||||||
switch (adjust_type) {
|
switch (adjust_type) {
|
||||||
|
Reference in New Issue
Block a user