VarAction2: Add last_value variants of JZ/JNZ ops

This commit is contained in:
Jonathan G Rennison
2022-07-30 23:32:23 +01:00
parent cbc6199542
commit 9a4c31b0da
3 changed files with 37 additions and 20 deletions

View File

@@ -7694,6 +7694,16 @@ static void OptimiseVarAction2DeterministicSpriteGroupInsertJumps(DeterministicS
group->adjusts.erase(group->adjusts.begin() + j);
j--;
i--;
} else if (current.type == DSGA_TYPE_NONE && current.shift_num == 0 && current.and_mask == 0xFFFFFFFF &&
prev.operation == DSGA_OP_STO && prev.variable == 0x1A && prev.shift_num == 0 && prev.and_mask == (current.parameter & 0xFF)) {
/* Reading from immediately prior store, which can now be removed */
current.operation = (current.operation == DSGA_OP_JNZ) ? DSGA_OP_JNZ_LV : DSGA_OP_JZ_LV;
current.adjust_flags &= ~DSGAF_LAST_VAR_READ;
current.and_mask = 0;
current.variable = 0x1A;
group->adjusts.erase(group->adjusts.begin() + j);
j--;
i--;
}
}
group->adjusts.insert(group->adjusts.begin() + j + 1, current);

View File

@@ -169,6 +169,17 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust &adjust, ScopeResolver
case DSGA_TYPE_NONE: break;
}
auto handle_jump = [&](bool jump, U jump_return_value) -> U {
if (jump && adjust_iter != nullptr) {
/* Jump */
(*adjust_iter) += adjust.jump;
return jump_return_value;
} else {
/* Don't jump */
return last_value;
}
};
switch (adjust.operation) {
case DSGA_OP_ADD: return last_value + value;
case DSGA_OP_SUB: return last_value - value;
@@ -202,26 +213,10 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust &adjust, ScopeResolver
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;
case DSGA_OP_JZ: {
if (value == 0 && adjust_iter != nullptr) {
/* Jump */
(*adjust_iter) += adjust.jump;
return 0;
} else {
/* Don't jump */
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;
}
}
case DSGA_OP_JZ: return handle_jump(value == 0, value);
case DSGA_OP_JNZ: return handle_jump(value != 0, value);
case DSGA_OP_JZ_LV: return handle_jump(last_value == 0, last_value);
case DSGA_OP_JNZ_LV: return handle_jump(last_value != 0, last_value);
default: return value;
}
}
@@ -711,6 +706,8 @@ static const char *_dsg_op_special_names[] {
"ABS",
"JZ",
"JNZ",
"JZ_LV",
"JNZ_LV",
};
static_assert(lengthof(_dsg_op_special_names) == DSGA_OP_SPECIAL_END - DSGA_OP_TERNARY);
@@ -781,6 +778,12 @@ static char *DumpSpriteGroupAdjust(char *p, const char *last, const Deterministi
append_flags();
return p;
}
if (adjust.operation == DSGA_OP_JZ_LV || adjust.operation == DSGA_OP_JNZ_LV) {
p = GetAdjustOperationName(p, last, adjust.operation);
p += seprintf(p, last, " +%u", adjust.jump);
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);

View File

@@ -208,6 +208,8 @@ enum DeterministicSpriteGroupAdjustOperation : uint8 {
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_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_JZ_LV, ///< jump forward fixed number of adjusts (to adjust after DSGAF_END_BLOCK marker (taking into account nesting)) if a is zero. return a
DSGA_OP_JNZ_LV, ///< jump forward fixed number of adjusts (to adjust after DSGAF_END_BLOCK marker (taking into account nesting)) if a is non-zero. return a
DSGA_OP_SPECIAL_END,
};
@@ -408,6 +410,8 @@ inline bool IsEvalAdjustJumpOperation(DeterministicSpriteGroupAdjustOperation op
switch (op) {
case DSGA_OP_JZ:
case DSGA_OP_JNZ:
case DSGA_OP_JZ_LV:
case DSGA_OP_JNZ_LV:
return true;
default: