diff --git a/decompiler/IR2/FormExpressionAnalysis.cpp b/decompiler/IR2/FormExpressionAnalysis.cpp index bd6fa9c053..c9a5a7ff11 100644 --- a/decompiler/IR2/FormExpressionAnalysis.cpp +++ b/decompiler/IR2/FormExpressionAnalysis.cpp @@ -2371,6 +2371,40 @@ Matcher make_int_uint_cast_matcher(const Matcher& thing) { // ConditionElement /////////////////// +namespace { +/*! + * Try to make a pretty looking constant out of value for comparing to something of type. + * If we can't do anything nice, return nullptr. + */ +Form* try_make_constant_for_compare(Form* value, + const TypeSpec& type, + FormPool& pool, + const Env& env) { + if (get_goal_integer_constant(value, env) && env.dts->ts.try_enum_lookup(type)) { + return cast_form(value, type, pool, env); + } + return nullptr; +} + +Form* try_make_constant_from_int_for_compare(s64 value, + const TypeSpec& type, + FormPool& pool, + const Env& env) { + auto enum_type_info = env.dts->ts.try_enum_lookup(type); + if (enum_type_info) { + if (enum_type_info->is_bitfield()) { + if (value != 0) { + // prefer (zero? x) for bitfield enums. + return cast_to_bitfield_enum(enum_type_info, pool, env, value); + } + } else { + return cast_to_int_enum(enum_type_info, pool, env, value); + } + } + return nullptr; +} +} // namespace + FormElement* ConditionElement::make_zero_check_generic(const Env& env, FormPool& pool, const std::vector