@@ -20,7 +20,7 @@
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
static bool IsExpensiveVehicleVariable(uint16 variable)
|
||||
static bool IsExpensiveVehicleVariable(uint16_t variable)
|
||||
{
|
||||
switch (variable) {
|
||||
case 0x45:
|
||||
@@ -38,7 +38,7 @@ static bool IsExpensiveVehicleVariable(uint16 variable)
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsExpensiveStationVariable(uint16 variable)
|
||||
static bool IsExpensiveStationVariable(uint16_t variable)
|
||||
{
|
||||
switch (variable) {
|
||||
case 0x66:
|
||||
@@ -53,7 +53,7 @@ static bool IsExpensiveStationVariable(uint16 variable)
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsExpensiveIndustryTileVariable(uint16 variable)
|
||||
static bool IsExpensiveIndustryTileVariable(uint16_t variable)
|
||||
{
|
||||
switch (variable) {
|
||||
case 0x60:
|
||||
@@ -66,7 +66,7 @@ static bool IsExpensiveIndustryTileVariable(uint16 variable)
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsExpensiveObjectVariable(uint16 variable)
|
||||
static bool IsExpensiveObjectVariable(uint16_t variable)
|
||||
{
|
||||
switch (variable) {
|
||||
case 0x41:
|
||||
@@ -85,7 +85,7 @@ static bool IsExpensiveObjectVariable(uint16 variable)
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsExpensiveRoadStopsVariable(uint16 variable)
|
||||
static bool IsExpensiveRoadStopsVariable(uint16_t variable)
|
||||
{
|
||||
switch (variable) {
|
||||
case 0x45:
|
||||
@@ -104,7 +104,7 @@ static bool IsExpensiveRoadStopsVariable(uint16 variable)
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsExpensiveRailtypeVariable(uint16 variable)
|
||||
static bool IsExpensiveRailtypeVariable(uint16_t variable)
|
||||
{
|
||||
switch (variable) {
|
||||
case A2VRI_RAILTYPE_SIGNAL_VERTICAL_CLEARANCE:
|
||||
@@ -116,7 +116,7 @@ static bool IsExpensiveRailtypeVariable(uint16 variable)
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsExpensiveSignalVariable(uint16 variable)
|
||||
static bool IsExpensiveSignalVariable(uint16_t variable)
|
||||
{
|
||||
switch (variable) {
|
||||
case A2VRI_SIGNALS_SIGNAL_VERTICAL_CLEARANCE:
|
||||
@@ -127,7 +127,7 @@ static bool IsExpensiveSignalVariable(uint16 variable)
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsExpensiveVariable(uint16 variable, GrfSpecFeature scope_feature)
|
||||
static bool IsExpensiveVariable(uint16_t variable, GrfSpecFeature scope_feature)
|
||||
{
|
||||
switch (scope_feature) {
|
||||
case GSF_TRAINS:
|
||||
@@ -159,7 +159,7 @@ static bool IsExpensiveVariable(uint16 variable, GrfSpecFeature scope_feature)
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsVariableVeryCheap(uint16 variable, GrfSpecFeature scope_feature)
|
||||
static bool IsVariableVeryCheap(uint16_t variable, GrfSpecFeature scope_feature)
|
||||
{
|
||||
switch (variable) {
|
||||
case 0x0C:
|
||||
@@ -269,7 +269,7 @@ static const DeterministicSpriteGroupAdjust *GetVarAction2PreviousSingleStoreAdj
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static int GetVarAction2AdjustOfPreviousTempStoreSource(const DeterministicSpriteGroupAdjust *adjusts, int start_index, uint8 store_var)
|
||||
static int GetVarAction2AdjustOfPreviousTempStoreSource(const DeterministicSpriteGroupAdjust *adjusts, int start_index, uint8_t store_var)
|
||||
{
|
||||
for (int i = start_index - 1; i >= 0; i--) {
|
||||
const DeterministicSpriteGroupAdjust &prev = adjusts[i];
|
||||
@@ -802,15 +802,15 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const VarAction2Ad
|
||||
const VarAction2AdjustInferenceFlags prev_inference = state.inference;
|
||||
state.inference = VA2AIF_NONE;
|
||||
|
||||
auto get_sign_bit = [&]() -> uint32 {
|
||||
auto get_sign_bit = [&]() -> uint32_t {
|
||||
return (1 << ((info.varsize * 8) - 1));
|
||||
};
|
||||
|
||||
auto get_full_mask = [&]() -> uint32 {
|
||||
auto get_full_mask = [&]() -> uint32_t {
|
||||
return UINT_MAX >> ((4 - info.varsize) * 8);
|
||||
};
|
||||
|
||||
auto add_inferences_from_mask = [&](uint32 mask) {
|
||||
auto add_inferences_from_mask = [&](uint32_t mask) {
|
||||
if (mask == 1) {
|
||||
state.inference |= VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO;
|
||||
} else if ((mask & get_sign_bit()) == 0) {
|
||||
@@ -818,7 +818,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const VarAction2Ad
|
||||
}
|
||||
};
|
||||
|
||||
auto replace_with_constant_load = [&](uint32 constant) {
|
||||
auto replace_with_constant_load = [&](uint32_t constant) {
|
||||
group->adjusts.pop_back();
|
||||
if ((prev_inference & VA2AIF_HAVE_CONSTANT) && constant == state.current_constant) {
|
||||
/* Don't create a new constant load for the same constant as was there previously */
|
||||
@@ -899,7 +899,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const VarAction2Ad
|
||||
if (proc == nullptr) return false;
|
||||
|
||||
byte shift_num = adjust.shift_num;
|
||||
uint32 and_mask = adjust.and_mask;
|
||||
uint32_t and_mask = adjust.and_mask;
|
||||
|
||||
// Initial value state is 0
|
||||
replace_with_constant_load(0);
|
||||
@@ -1112,7 +1112,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const VarAction2Ad
|
||||
std::bitset<256> seen_stores;
|
||||
bool seen_unpredictable_store = false;
|
||||
bool seen_special_store = false;
|
||||
uint16 seen_special_store_mask = 0;
|
||||
uint16_t seen_special_store_mask = 0;
|
||||
bool seen_perm_store = false;
|
||||
auto handle_proc_stores = y_combinator([&](auto handle_proc_stores, const SpriteGroup *sg) -> void {
|
||||
if (sg == nullptr) return;
|
||||
@@ -1230,7 +1230,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const VarAction2Ad
|
||||
}
|
||||
if (adjust.operation == DSGA_OP_RST && adjust.type == DSGA_TYPE_MOD && adjust.divmod_val == 2) {
|
||||
/* Non-negative value % 2 implies VA2AIF_ONE_OR_ZERO */
|
||||
if ((uint64)adjust.and_mask + (uint64)adjust.add_val < (uint64)get_sign_bit()) {
|
||||
if ((uint64_t)adjust.and_mask + (uint64_t)adjust.add_val < (uint64_t)get_sign_bit()) {
|
||||
state.inference |= VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO;
|
||||
}
|
||||
}
|
||||
@@ -1574,7 +1574,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const VarAction2Ad
|
||||
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 {
|
||||
auto is_expected_op = [](const DeterministicSpriteGroupAdjust &adj, DeterministicSpriteGroupAdjustOperation op, uint32_t 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)) &&
|
||||
@@ -1587,10 +1587,10 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const VarAction2Ad
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint32 sign_bit = (1 << ((info.varsize * 8) - 1));
|
||||
uint32_t sign_bit = (1 << ((info.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 */
|
||||
if (((uint64)group->adjusts[group->adjusts.size() - 2].and_mask) * ((uint64)adjust.and_mask) < ((uint64)sign_bit)) {
|
||||
if (((uint64_t)group->adjusts[group->adjusts.size() - 2].and_mask) * ((uint64_t)adjust.and_mask) < ((uint64_t)sign_bit)) {
|
||||
state.inference |= VA2AIF_SIGNED_NON_NEGATIVE;
|
||||
}
|
||||
}
|
||||
@@ -1871,15 +1871,15 @@ static bool CheckDeterministicSpriteGroupOutputVarBits(const DeterministicSprite
|
||||
|
||||
static bool OptimiseVarAction2DeterministicSpriteGroupExpensiveVarsInner(DeterministicSpriteGroup *group, const GrfSpecFeature scope_feature, VarAction2GroupVariableTracking *var_tracking)
|
||||
{
|
||||
btree::btree_map<uint64, uint32> seen_expensive_variables;
|
||||
btree::btree_map<uint64_t, uint32_t> seen_expensive_variables;
|
||||
std::bitset<256> usable_vars;
|
||||
if (var_tracking != nullptr) {
|
||||
usable_vars = ~(var_tracking->out | var_tracking->proc_call_out);
|
||||
} else {
|
||||
usable_vars.set();
|
||||
}
|
||||
uint16 target_var = 0;
|
||||
uint32 target_param = 0;
|
||||
uint16_t target_var = 0;
|
||||
uint32_t target_param = 0;
|
||||
auto found_target = [&]() -> bool {
|
||||
for (auto &iter : seen_expensive_variables) {
|
||||
if (iter.second >= 2) {
|
||||
@@ -1893,9 +1893,9 @@ static bool OptimiseVarAction2DeterministicSpriteGroupExpensiveVarsInner(Determi
|
||||
auto do_replacements = [&](int start, int end) {
|
||||
std::bitset<256> mask(UINT64_MAX);
|
||||
std::bitset<256> cur = usable_vars;
|
||||
uint8 bit = 0;
|
||||
uint8_t bit = 0;
|
||||
while (true) {
|
||||
uint64 t = (cur & mask).to_ullong();
|
||||
uint64_t t = (cur & mask).to_ullong();
|
||||
if (t != 0) {
|
||||
bit += FindFirstBit(t);
|
||||
break;
|
||||
@@ -1904,7 +1904,7 @@ static bool OptimiseVarAction2DeterministicSpriteGroupExpensiveVarsInner(Determi
|
||||
bit += 64;
|
||||
}
|
||||
int insert_pos = start;
|
||||
uint32 and_mask = 0;
|
||||
uint32_t and_mask = 0;
|
||||
uint condition_depth = 0;
|
||||
bool seen_first = false;
|
||||
int last_unused_jump = -1;
|
||||
@@ -1963,7 +1963,7 @@ static bool OptimiseVarAction2DeterministicSpriteGroupExpensiveVarsInner(Determi
|
||||
} else if (adjust.variable == 0x7D) {
|
||||
if (adjust.parameter < 0x100) usable_vars.set(adjust.parameter, false);
|
||||
} else if (IsExpensiveVariable(adjust.variable, scope_feature)) {
|
||||
seen_expensive_variables[(((uint64)adjust.variable) << 32) | adjust.parameter]++;
|
||||
seen_expensive_variables[(((uint64_t)adjust.variable) << 32) | adjust.parameter]++;
|
||||
}
|
||||
if (adjust.variable == 0x7E || (adjust.operation == DSGA_OP_STO && adjust.and_mask >= 0x100) || (adjust.operation == DSGA_OP_STO_NC && adjust.divmod_val >= 0x100)) {
|
||||
/* Can't cross this barrier, stop here */
|
||||
@@ -2076,11 +2076,11 @@ static void OptimiseVarAction2DeterministicSpriteGroupAdjustOrdering(Determinist
|
||||
{
|
||||
if (HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2_ADJUST_ORDERING)) return;
|
||||
|
||||
auto acceptable_variable = [](uint16 variable) -> bool {
|
||||
auto acceptable_variable = [](uint16_t variable) -> bool {
|
||||
return variable != 0x7E && variable != 0x7B;
|
||||
};
|
||||
|
||||
auto get_variable_expense = [&](uint16 variable) -> int {
|
||||
auto get_variable_expense = [&](uint16_t variable) -> int {
|
||||
if (variable == 0x1A) return -15;
|
||||
if (IsVariableVeryCheap(variable, scope_feature)) return -10;
|
||||
if (variable == 0x7D || variable == 0x7C) return -5;
|
||||
@@ -2230,10 +2230,10 @@ static VarAction2ProcedureAnnotation *OptimiseVarAction2GetFilledProcedureAnnota
|
||||
return anno;
|
||||
}
|
||||
|
||||
static uint OptimiseVarAction2InsertSpecialStoreOps(DeterministicSpriteGroup *group, uint offset, uint32 values[16], uint16 mask)
|
||||
static uint OptimiseVarAction2InsertSpecialStoreOps(DeterministicSpriteGroup *group, uint offset, uint32_t values[16], uint16_t mask)
|
||||
{
|
||||
uint added = 0;
|
||||
for (uint8 bit : SetBitIterator(mask)) {
|
||||
for (uint8_t bit : SetBitIterator(mask)) {
|
||||
bool skip = false;
|
||||
for (size_t i = offset; i < group->adjusts.size(); i++) {
|
||||
const DeterministicSpriteGroupAdjust &next = group->adjusts[i];
|
||||
@@ -2381,8 +2381,8 @@ static void OptimiseVarAction2DeterministicSpriteGroupInsertJumps(DeterministicS
|
||||
|
||||
if (adjust.adjust_flags & DSGAF_JUMP_INS_HINT) {
|
||||
std::bitset<256> ok_stores;
|
||||
uint32 special_stores[16];
|
||||
uint16 special_stores_mask = 0;
|
||||
uint32_t special_stores[16];
|
||||
uint16_t special_stores_mask = 0;
|
||||
int j = i - 1;
|
||||
int skip_count = 0;
|
||||
const DeterministicSpriteGroupAdjustFlags skip_mask = adjust.adjust_flags & (DSGAF_SKIP_ON_ZERO | DSGAF_SKIP_ON_LSB_SET);
|
||||
@@ -2410,8 +2410,8 @@ static void OptimiseVarAction2DeterministicSpriteGroupInsertJumps(DeterministicS
|
||||
if ((anno.relevant_stores & ~ok_stores).any()) break;
|
||||
ok_stores |= anno.last_reads;
|
||||
|
||||
uint16 new_stores = anno.anno->special_register_mask & ~special_stores_mask;
|
||||
for (uint8 bit : SetBitIterator(new_stores)) {
|
||||
uint16_t new_stores = anno.anno->special_register_mask & ~special_stores_mask;
|
||||
for (uint8_t bit : SetBitIterator(new_stores)) {
|
||||
special_stores[bit] = anno.anno->special_register_values[bit];
|
||||
}
|
||||
special_stores_mask |= new_stores;
|
||||
@@ -2549,7 +2549,7 @@ static void OptimiseVarAction2DeterministicSpriteResolveJumps(DeterministicSprit
|
||||
|
||||
static const size_t MAX_PROC_INLINE_ADJUST_COUNT = 8;
|
||||
|
||||
static bool IsVariableInlinable(uint16 variable, GrfSpecFeature feature)
|
||||
static bool IsVariableInlinable(uint16_t variable, GrfSpecFeature feature)
|
||||
{
|
||||
/* Always available global variables */
|
||||
if (variable <= 0x03) return true;
|
||||
@@ -2751,7 +2751,7 @@ void OptimiseVarAction2DeterministicSpriteGroup(VarAction2OptimiseState &state,
|
||||
}
|
||||
if (!found_zero_value && !found_random_cb_value) {
|
||||
group->ranges.insert(group->ranges.begin(), { group->default_group, 0, 1 });
|
||||
extern const CallbackResultSpriteGroup *NewCallbackResultSpriteGroupNoTransform(uint16 result);
|
||||
extern const CallbackResultSpriteGroup *NewCallbackResultSpriteGroupNoTransform(uint16_t result);
|
||||
group->default_group = NewCallbackResultSpriteGroupNoTransform(CALLBACK_FAILED);
|
||||
}
|
||||
}
|
||||
@@ -2862,7 +2862,7 @@ static std::bitset<256> HandleVarAction2DeadStoreElimination(DeterministicSprite
|
||||
i++;
|
||||
}
|
||||
};
|
||||
auto try_variable_substitution = [&](DeterministicSpriteGroupAdjust &target, int prev_load_index, uint8 idx) -> bool {
|
||||
auto try_variable_substitution = [&](DeterministicSpriteGroupAdjust &target, int prev_load_index, uint8_t idx) -> bool {
|
||||
assert(target.variable == 0x7D && target.parameter == idx);
|
||||
|
||||
bool inverted = false;
|
||||
@@ -2891,7 +2891,7 @@ static std::bitset<256> HandleVarAction2DeadStoreElimination(DeterministicSprite
|
||||
const DeterministicSpriteGroupAdjust &adjust = group->adjusts[i];
|
||||
if (adjust.operation == DSGA_OP_STO) {
|
||||
if (adjust.type == DSGA_TYPE_NONE && adjust.variable == 0x1A && adjust.shift_num == 0 && adjust.and_mask < 0x100) {
|
||||
uint8 idx = adjust.and_mask;
|
||||
uint8_t idx = adjust.and_mask;
|
||||
/* Predictable store */
|
||||
|
||||
for (size_t j = 0; j < substitution_candidates.size(); j++) {
|
||||
@@ -3115,7 +3115,7 @@ static std::bitset<256> HandleVarAction2DeadStoreElimination(DeterministicSprite
|
||||
} else {
|
||||
/* Flush any substitution candidates which reference stores made in the procedure */
|
||||
for (size_t j = 0; j < substitution_candidates.size();) {
|
||||
uint8 idx = substitution_candidates[j] & 0xFF;
|
||||
uint8_t idx = substitution_candidates[j] & 0xFF;
|
||||
if (anno->stores[idx]) {
|
||||
all_bits.set(idx, true);
|
||||
propagate_bits.set(idx, true);
|
||||
@@ -3230,7 +3230,7 @@ const SpriteGroup *PruneTargetSpriteGroup(const SpriteGroup *result)
|
||||
const DeterministicSpriteGroup *sg = static_cast<const DeterministicSpriteGroup *>(result);
|
||||
if (sg->GroupMayBeBypassed()) {
|
||||
/* Deterministic sprite group can be trivially resolved, skip it */
|
||||
uint32 value = (sg->adjusts.size() == 1) ? EvaluateDeterministicSpriteGroupAdjust(sg->size, sg->adjusts[0], nullptr, 0, UINT_MAX) : 0;
|
||||
uint32_t value = (sg->adjusts.size() == 1) ? EvaluateDeterministicSpriteGroupAdjust(sg->size, sg->adjusts[0], nullptr, 0, UINT_MAX) : 0;
|
||||
const SpriteGroup *candidate = sg->default_group;
|
||||
for (const auto &range : sg->ranges) {
|
||||
if (range.low <= value && value <= range.high) {
|
||||
|
Reference in New Issue
Block a user