diff --git a/decompiler/IR2/AtomicOp.cpp b/decompiler/IR2/AtomicOp.cpp index 4c49f6e9e9..2e50275f94 100644 --- a/decompiler/IR2/AtomicOp.cpp +++ b/decompiler/IR2/AtomicOp.cpp @@ -1121,6 +1121,21 @@ void StoreOp::collect_vars(RegAccessSet& vars) const { // LoadVarOp ///////////////////////////// +std::string load_kind_to_string(LoadVarOp::Kind kind) { + switch (kind) { + case LoadVarOp::Kind::FLOAT: + return "float"; + case LoadVarOp::Kind::VECTOR_FLOAT: + return "vector-float"; + case LoadVarOp::Kind::SIGNED: + return "signed"; + case LoadVarOp::Kind::UNSIGNED: + return "unsigned"; + default: + assert(false); + } +} + LoadVarOp::LoadVarOp(Kind kind, int size, RegisterAccess dst, SimpleExpression src, int my_idx) : AtomicOp(my_idx), m_kind(kind), m_size(size), m_dst(dst), m_src(std::move(src)) {} diff --git a/decompiler/IR2/AtomicOp.h b/decompiler/IR2/AtomicOp.h index cd1303f199..56d2760152 100644 --- a/decompiler/IR2/AtomicOp.h +++ b/decompiler/IR2/AtomicOp.h @@ -467,7 +467,7 @@ class StoreOp : public AtomicOp { */ class LoadVarOp : public AtomicOp { public: - enum class Kind { UNSIGNED, SIGNED, FLOAT, VECTOR_FLOAT }; + enum class Kind { UNSIGNED, SIGNED, FLOAT, VECTOR_FLOAT, INVALID }; LoadVarOp(Kind kind, int size, RegisterAccess dst, SimpleExpression src, int my_idx); goos::Object to_form(const std::vector& labels, const Env& env) const override; bool operator==(const AtomicOp& other) const override; @@ -490,6 +490,13 @@ class LoadVarOp : public AtomicOp { std::optional m_type; }; +std::string load_kind_to_string(LoadVarOp::Kind kind); +FormElement* make_label_load(int label_idx, + const Env& env, + FormPool& pool, + int load_size, + LoadVarOp::Kind load_kind); + /*! * This represents one of the possible instructions that can go in a branch delay slot. * These will be "absorbed" into higher level structures, but for the purpose of printing AtomicOps, diff --git a/decompiler/IR2/AtomicOpForm.cpp b/decompiler/IR2/AtomicOpForm.cpp index dd441d6255..48a402346c 100644 --- a/decompiler/IR2/AtomicOpForm.cpp +++ b/decompiler/IR2/AtomicOpForm.cpp @@ -476,6 +476,82 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const { return pool.alloc_element(this); } +FormElement* make_label_load(int label_idx, + const Env& env, + FormPool& pool, + int load_size, + LoadVarOp::Kind load_kind) { + auto label = env.file->labels.at(label_idx); + auto label_name = label.name; + auto hint = env.label_types().find(label_name); + if (hint != env.label_types().end()) { + if (hint->second.is_const) { + if ((load_kind == LoadVarOp::Kind::FLOAT || load_kind == LoadVarOp::Kind::SIGNED) && + load_size == 4 && hint->second.type_name == "float") { + assert((label.offset % 4) == 0); + auto word = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4); + assert(word.kind == LinkedWord::PLAIN_DATA); + float value; + memcpy(&value, &word.data, 4); + return pool.alloc_element(value); + } else if (hint->second.type_name == "uint64" && load_kind != LoadVarOp::Kind::FLOAT && + load_size == 8) { + assert((label.offset % 8) == 0); + auto word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4); + auto word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4)); + assert(word0.kind == LinkedWord::PLAIN_DATA); + assert(word1.kind == LinkedWord::PLAIN_DATA); + u64 value; + memcpy(&value, &word0.data, 4); + memcpy(((u8*)&value) + 4, &word1.data, 4); + return pool.alloc_element(TypeSpec("uint"), + pool.alloc_single_element_form( + nullptr, SimpleAtom::make_int_constant(value))); + } + + // is it a constant bitfield? + auto& ts = env.dts->ts; + auto as_bitfield = dynamic_cast(ts.lookup_type(hint->second.type_name)); + if (as_bitfield && load_kind != LoadVarOp::Kind::FLOAT && load_size == 8) { + // get the data + assert((label.offset % 8) == 0); + auto word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4); + auto word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4)); + assert(word0.kind == LinkedWord::PLAIN_DATA); + assert(word1.kind == LinkedWord::PLAIN_DATA); + u64 value; + memcpy(&value, &word0.data, 4); + memcpy(((u8*)&value) + 4, &word1.data, 4); + // for some reason, GOAL would use a 64-bit constant for all bitfields, even if they are + // smaller. We should check that the higher bits are all zero. + int bits = as_bitfield->get_size_in_memory() * 8; + assert(bits <= 64); + if (bits < 64) { + assert((value >> bits) == 0); + // technically ub if bits == 64. + } + TypeSpec typespec(hint->second.type_name); + auto defs = decompile_bitfield_from_int(typespec, ts, value); + return pool.alloc_element(typespec, defs, pool); + } + } + } + + if (load_kind == LoadVarOp::Kind::FLOAT && load_size == 4) { + assert((label.offset % 4) == 0); + const auto& words = env.file->words_by_seg.at(label.target_segment); + if ((int)words.size() > label.offset / 4) { + auto word = words.at(label.offset / 4); + assert(word.kind == LinkedWord::PLAIN_DATA); + float value; + memcpy(&value, &word.data, 4); + return pool.alloc_element(value); + } + } + + return nullptr; +} + Form* LoadVarOp::get_load_src(FormPool& pool, const Env& env) const { if (env.has_type_analysis()) { IR2_RegOffset ro; @@ -584,6 +660,12 @@ Form* LoadVarOp::get_load_src(FormPool& pool, const Env& env) const { return pool.alloc_single_element_form(nullptr, source, rd.addr_of, tokens); } + if (ro.offset == 0 && input_type.kind == TP_Type::Kind::LABEL_ADDR) { + // we no longer resolve label stuff here because sometimes we need expressions for this + return pool.alloc_single_element_form(nullptr, input_type.label_id(), + m_size, m_kind, ro.var); + } + if (ro.offset == 0 && (input_type.typespec() == TypeSpec("pointer") || input_type.kind == TP_Type::Kind::OBJECT_PLUS_PRODUCT_WITH_CONSTANT)) { std::string cast_type; @@ -623,74 +705,9 @@ Form* LoadVarOp::get_load_src(FormPool& pool, const Env& env) const { } if (m_src.is_identity() && m_src.get_arg(0).is_label()) { - // try to see if we're loading a constant - auto label = env.file->labels.at(m_src.get_arg(0).label()); - auto label_name = label.name; - auto hint = env.label_types().find(label_name); - if (hint != env.label_types().end()) { - if (hint->second.is_const) { - if ((m_kind == Kind::FLOAT || m_kind == Kind::SIGNED) && m_size == 4 && - hint->second.type_name == "float") { - assert((label.offset % 4) == 0); - auto word = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4); - assert(word.kind == LinkedWord::PLAIN_DATA); - float value; - memcpy(&value, &word.data, 4); - return pool.alloc_single_element_form(nullptr, value); - } else if (hint->second.type_name == "uint64" && m_kind != Kind::FLOAT && m_size == 8) { - assert((label.offset % 8) == 0); - auto word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4); - auto word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4)); - assert(word0.kind == LinkedWord::PLAIN_DATA); - assert(word1.kind == LinkedWord::PLAIN_DATA); - u64 value; - memcpy(&value, &word0.data, 4); - memcpy(((u8*)&value) + 4, &word1.data, 4); - return pool.alloc_single_element_form( - nullptr, TypeSpec("uint"), - pool.alloc_single_element_form( - nullptr, SimpleAtom::make_int_constant(value))); - } - - // is it a constant bitfield? - auto& ts = env.dts->ts; - auto as_bitfield = dynamic_cast(ts.lookup_type(hint->second.type_name)); - if (as_bitfield && m_kind != Kind::FLOAT && m_size == 8) { - // get the data - assert((label.offset % 8) == 0); - auto word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4); - auto word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4)); - assert(word0.kind == LinkedWord::PLAIN_DATA); - assert(word1.kind == LinkedWord::PLAIN_DATA); - u64 value; - memcpy(&value, &word0.data, 4); - memcpy(((u8*)&value) + 4, &word1.data, 4); - // for some reason, GOAL would use a 64-bit constant for all bitfields, even if they are - // smaller. We should check that the higher bits are all zero. - int bits = as_bitfield->get_size_in_memory() * 8; - assert(bits <= 64); - if (bits < 64) { - assert((value >> bits) == 0); - // technically ub if bits == 64. - } - TypeSpec typespec(hint->second.type_name); - auto defs = decompile_bitfield_from_int(typespec, ts, value); - return pool.alloc_single_element_form(nullptr, typespec, defs, - pool); - } - } - } - - if (m_kind == Kind::FLOAT && m_size == 4) { - assert((label.offset % 4) == 0); - const auto& words = env.file->words_by_seg.at(label.target_segment); - if ((int)words.size() > label.offset / 4) { - auto word = words.at(label.offset / 4); - assert(word.kind == LinkedWord::PLAIN_DATA); - float value; - memcpy(&value, &word.data, 4); - return pool.alloc_single_element_form(nullptr, value); - } + auto label_load_element = make_label_load(m_src.get_arg(0).label(), env, pool, m_size, m_kind); + if (label_load_element) { + return pool.alloc_single_form(nullptr, label_load_element); } } diff --git a/decompiler/IR2/AtomicOpTypeAnalysis.cpp b/decompiler/IR2/AtomicOpTypeAnalysis.cpp index 482b311403..ec6a2e2771 100644 --- a/decompiler/IR2/AtomicOpTypeAnalysis.cpp +++ b/decompiler/IR2/AtomicOpTypeAnalysis.cpp @@ -137,7 +137,7 @@ TP_Type SimpleAtom::get_type(const TypeState& input, } // todo: should we take out this warning? lg::warn("IR_StaticAddress does not know the type of {}", label.name); - return TP_Type::make_label_addr(); + return TP_Type::make_label_addr(m_int); } case Kind::INVALID: default: diff --git a/decompiler/IR2/Form.cpp b/decompiler/IR2/Form.cpp index e97c334fe4..f12c180d46 100644 --- a/decompiler/IR2/Form.cpp +++ b/decompiler/IR2/Form.cpp @@ -2776,6 +2776,32 @@ void LabelElement::apply_form(const std::function&) {} void LabelElement::collect_vars(RegAccessSet&, bool) const {} void LabelElement::get_modified_regs(RegSet&) const {} +//////////////////////////////// +// LabelDerefElement +/////////////////////////////// + +LabelDerefElement::LabelDerefElement(int lid, + int size, + LoadVarOp::Kind load_kind, + RegisterAccess var) + : m_lid(lid), m_size(size), m_load_kind(load_kind), m_var(var) {} + +goos::Object LabelDerefElement::to_form_internal(const Env& env) const { + return pretty_print::build_list(fmt::format("label-deref {} :label {} :size {} :kind {}", + m_var.to_string(env), env.file->labels.at(m_lid).name, + m_size, load_kind_to_string(m_load_kind))); +} + +void LabelDerefElement::apply(const std::function& f) { + f(this); +} + +void LabelDerefElement::apply_form(const std::function&) {} +void LabelDerefElement::collect_vars(RegAccessSet& regs, bool) const { + regs.insert(m_var); +} +void LabelDerefElement::get_modified_regs(RegSet&) const {} + //////////////////////////////// // GetSymbolStringPointer ////////////////////////////// diff --git a/decompiler/IR2/Form.h b/decompiler/IR2/Form.h index 702595787b..5f47ba13ce 100644 --- a/decompiler/IR2/Form.h +++ b/decompiler/IR2/Form.h @@ -632,6 +632,7 @@ class ReturnElement : public FormElement { void collect_vars(RegAccessSet& vars, bool recursive) const override; void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override; void get_modified_regs(RegSet& regs) const override; + std::optional return_type; }; /*! @@ -1549,6 +1550,27 @@ class LabelElement : public FormElement { int m_lid = -1; }; +class LabelDerefElement : public FormElement { + public: + LabelDerefElement(int lid, int size, LoadVarOp::Kind load_kind, RegisterAccess var); + goos::Object to_form_internal(const Env& env) const override; + void apply(const std::function& f) override; + void apply_form(const std::function& f) override; + void collect_vars(RegAccessSet& vars, bool recursive) const override; + void get_modified_regs(RegSet& regs) const override; + void update_from_stack(const Env& env, + FormPool& pool, + FormStack& stack, + std::vector* result, + bool allow_side_effects) override; + + private: + int m_lid = -1; + int m_size = -1; + LoadVarOp::Kind m_load_kind = LoadVarOp::Kind::INVALID; + RegisterAccess m_var; +}; + class GetSymbolStringPointer : public FormElement { public: GetSymbolStringPointer(Form* src); diff --git a/decompiler/IR2/FormExpressionAnalysis.cpp b/decompiler/IR2/FormExpressionAnalysis.cpp index c8ada84beb..c76c1ef0a0 100644 --- a/decompiler/IR2/FormExpressionAnalysis.cpp +++ b/decompiler/IR2/FormExpressionAnalysis.cpp @@ -3549,6 +3549,24 @@ FormElement* ConditionElement::make_zero_check_generic(const Env& env, return pool.alloc_element(GenericOperator::make_compare(m_kind), source_forms); } +FormElement* try_make_nonzero_logtest(Form* in, FormPool& pool) { + /* + (defmacro logtest? (a b) + "does a have any of the bits in b?" + `(nonzero? (logand ,a ,b)) + ) + */ + auto logand_matcher = Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::LOGAND), + {Matcher::any(0), Matcher::any(1)}); + auto mr_logand = match(logand_matcher, in); + if (mr_logand.matched) { + return pool.alloc_element( + GenericOperator::make_fixed(FixedOperatorKind::LOGTEST), mr_logand.maps.forms.at(0), + mr_logand.maps.forms.at(1)); + } + return nullptr; +} + FormElement* ConditionElement::make_nonzero_check_generic(const Env& env, FormPool& pool, const std::vector& source_forms, @@ -3578,19 +3596,9 @@ FormElement* ConditionElement::make_nonzero_check_generic(const Env& env, std::vector{mr.maps.forms.at(0), value_form}); } - /* - (defmacro logtest? (a b) - "does a have any of the bits in b?" - `(nonzero? (logand ,a ,b)) - ) - */ - auto logand_matcher = Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::LOGAND), - {Matcher::any(0), Matcher::any(1)}); - auto mr_logand = match(logand_matcher, source_forms.at(0)); - if (mr_logand.matched) { - return pool.alloc_element( - GenericOperator::make_fixed(FixedOperatorKind::LOGTEST), mr_logand.maps.forms.at(0), - mr_logand.maps.forms.at(1)); + auto as_logand = try_make_nonzero_logtest(source_forms.at(0), pool); + if (as_logand) { + return as_logand; } return pool.alloc_element(GenericOperator::make_compare(m_kind), source_forms); @@ -3967,7 +3975,8 @@ void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta return_code->push_back(new_entries.back()); if (var) { const auto& func_type = env.func->type.last_arg(); - if (!env.dts->ts.tc(func_type, env.get_variable_type(*var, false))) { + return_type = env.get_variable_type(*var, false); + if (func_type != return_type) { auto as_cast = return_code->try_as_element(); if (as_cast) { return_code->clear(); @@ -4643,13 +4652,25 @@ void ConditionalMoveFalseElement::push_to_stack(const Env& env, FormPool& pool, stack.push_form_element(this, true); return; } - stack.push_value_to_reg(dest, - pool.alloc_single_element_form( - nullptr, - GenericOperator::make_compare(on_zero ? IR2_Condition::Kind::NONZERO - : IR2_Condition::Kind::ZERO), - std::vector{popped.at(1)}), - true, TypeSpec("symbol")); + + Form* val = nullptr; + + if (!val && on_zero) { + auto as_logtest = try_make_nonzero_logtest(popped.at(1), pool); + if (as_logtest) { + val = pool.alloc_single_form(nullptr, as_logtest); + } + } + + if (!val) { + val = pool.alloc_single_element_form( + nullptr, + GenericOperator::make_compare(on_zero ? IR2_Condition::Kind::NONZERO + : IR2_Condition::Kind::ZERO), + std::vector{popped.at(1)}); + } + + stack.push_value_to_reg(dest, val, true, TypeSpec("symbol")); } /////////////////////////// @@ -4951,6 +4972,32 @@ void DefstateElement::update_from_stack(const Env&, result->push_back(this); } +void LabelDerefElement::update_from_stack(const Env& env, + FormPool& pool, + FormStack& stack, + std::vector* result, + bool allow_side_effects) { + mark_popped(); + auto label_var = pop_to_forms({m_var}, env, pool, stack, allow_side_effects).at(0); + auto atom = form_as_atom(label_var); + if (!atom || !atom->is_label()) { + throw std::runtime_error(fmt::format("LabelDerefElement didn't get a label, got {} instead", + label_var->to_string(env))); + } + + if (atom->label() != m_lid) { + throw std::runtime_error( + fmt::format("Label ID error in LabelDerefElement: {} vs {}", atom->label(), m_lid)); + } + + auto as_label = make_label_load(m_lid, env, pool, m_size, m_load_kind); + if (!as_label) { + throw std::runtime_error( + fmt::format("Unable to figure out label load for {}\n", env.file->labels.at(m_lid).name)); + } + result->push_back(as_label); +} + void LabelElement::push_to_stack(const Env&, FormPool&, FormStack& stack) { mark_popped(); stack.push_form_element(this, true); diff --git a/decompiler/ObjectFile/ObjectFileDB.h b/decompiler/ObjectFile/ObjectFileDB.h index b2f3917ffc..da1627cd30 100644 --- a/decompiler/ObjectFile/ObjectFileDB.h +++ b/decompiler/ObjectFile/ObjectFileDB.h @@ -158,9 +158,11 @@ class ObjectFileDB { void for_each_function_in_seg(int seg, Func f) { for_each_obj([&](ObjectFileData& data) { int fn = 0; - for (size_t j = data.linked_data.functions_by_seg.at(seg).size(); j-- > 0;) { - f(data.linked_data.functions_by_seg.at(seg).at(j), data); - fn++; + if (data.linked_data.segments == 3) { + for (size_t j = data.linked_data.functions_by_seg.at(seg).size(); j-- > 0;) { + f(data.linked_data.functions_by_seg.at(seg).at(j), data); + fn++; + } } }); } diff --git a/decompiler/analysis/expression_build.cpp b/decompiler/analysis/expression_build.cpp index aa5a04c105..a1661fd130 100644 --- a/decompiler/analysis/expression_build.cpp +++ b/decompiler/analysis/expression_build.cpp @@ -84,8 +84,31 @@ bool convert_to_expressions( } } + bool needs_cast = false; if (!dts.ts.tc(f.type.last_arg(), return_type)) { // we need to cast the final value. + needs_cast = true; + + } else { + bool found_early_return = false; + for (auto e : new_entries) { + e->apply([&](FormElement* elt) { + auto as_ret = dynamic_cast(elt); + if (as_ret) { + found_early_return = true; + } + }); + if (found_early_return) { + break; + } + } + + if (!found_early_return && f.type.last_arg() != return_type) { + needs_cast = true; + } + } + + if (needs_cast) { auto to_cast = new_entries.back(); auto as_cast = dynamic_cast(to_cast); if (as_cast) { diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index e36eeca8da..cd5ba54523 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -640,7 +640,6 @@ :bitfield #t :type uint32 (display-marks 0) - (bit0 0) ;; TODO - nav-enemy::45 (bit1 1) (bit2 2) (bit3 3) ;; TODO - nav-enemy::45 @@ -14752,7 +14751,7 @@ (define-extern show-iop-info (function dma-buffer int)) (define-extern show-iop-memory (function dma-buffer int)) (define-extern make-sqrt-table (function int)) -(define-extern flava-lookup (function symbol int integer)) +(define-extern flava-lookup (function symbol int int)) ;; - Symbols diff --git a/decompiler/util/TP_Type.cpp b/decompiler/util/TP_Type.cpp index ffbe5f8909..167ff5e98a 100644 --- a/decompiler/util/TP_Type.cpp +++ b/decompiler/util/TP_Type.cpp @@ -70,7 +70,7 @@ std::string TP_Type::print() const { case Kind::PCPYUD_BITFIELD_AND: return fmt::format("", m_ts.print()); case Kind::LABEL_ADDR: - return ""; + return fmt::format("", m_int); case Kind::ENTER_STATE_FUNCTION: return ""; case Kind::INVALID: diff --git a/decompiler/util/TP_Type.h b/decompiler/util/TP_Type.h index ce076cdb56..14c234ff0b 100644 --- a/decompiler/util/TP_Type.h +++ b/decompiler/util/TP_Type.h @@ -262,9 +262,10 @@ class TP_Type { return result; } - static TP_Type make_label_addr() { + static TP_Type make_label_addr(int label_id) { TP_Type result; result.kind = Kind::LABEL_ADDR; + result.m_int = label_id; return result; } @@ -342,6 +343,11 @@ class TP_Type { return m_flipped_order; } + int label_id() const { + assert(kind == Kind::LABEL_ADDR); + return m_int; + } + private: TypeSpec m_ts; TypeSpec m_method_from_type; diff --git a/decompiler/util/data_decompile.cpp b/decompiler/util/data_decompile.cpp index fe0d535f63..21ac31535c 100644 --- a/decompiler/util/data_decompile.cpp +++ b/decompiler/util/data_decompile.cpp @@ -1255,11 +1255,22 @@ std::vector decompile_bitfield_enum_from_int(const TypeSpec& type, return type_info->entries().at(a) < type_info->entries().at(b); }); - for (auto& field_name : bit_sorted_names) { - u64 mask = ((u64)1) << type_info->entries().at(field_name); + for (auto& kv : type_info->entries()) { + u64 mask = ((u64)1) << kv.second; if (value & mask) { reconstructed |= mask; - result.push_back(field_name); + result.push_back(kv.first); + } + } + + int bit_count = 0; + { + u64 x = value; + while (x) { + if (x & 1) { + bit_count++; + } + x >>= 1; } } @@ -1270,10 +1281,18 @@ std::vector decompile_bitfield_enum_from_int(const TypeSpec& type, type.print(), value, reconstructed)); } - // unordered map will give us these fields in a weird order, let's order them explicitly. - std::sort(result.begin(), result.end(), [&](const std::string& a, const std::string& b) { - return type_info->entries().at(a) < type_info->entries().at(b); - }); + if (bit_count == (int)result.size()) { + // unordered map will give us these fields in a weird order, let's order them explicitly. + // because we have exactly one name per bit, we can just order them in bit order. + std::sort(result.begin(), result.end(), [&](const std::string& a, const std::string& b) { + return type_info->entries().at(a) < type_info->entries().at(b); + }); + } else { + // we have multiple. Just sort alphabetically and complain. + lg::warn("Enum type {} has multiple entries with the same value.", type_info->get_name()); + std::sort(result.begin(), result.end()); + } + return result; } diff --git a/goal_src/engine/camera/cam-combiner.gc b/goal_src/engine/camera/cam-combiner.gc index 77070a5330..3c6c1b65d7 100644 --- a/goal_src/engine/camera/cam-combiner.gc +++ b/goal_src/engine/camera/cam-combiner.gc @@ -561,7 +561,7 @@ (when (and (< 8192.0 f28-1) - (nonzero? (logand (-> *camera* master-options) 2)) + (logtest? (-> *camera* master-options) 2) ) (vector-! (the-as vector (-> s1-0 vector)) diff --git a/goal_src/engine/geometry/vol-h.gc b/goal_src/engine/geometry/vol-h.gc index d6684f194e..e2cc921518 100644 --- a/goal_src/engine/geometry/vol-h.gc +++ b/goal_src/engine/geometry/vol-h.gc @@ -141,5 +141,5 @@ ;; definition for method 11 of type vol-control (defmethod TODO-RENAME-11 vol-control ((obj vol-control)) - (and *display-vol-marks* (nonzero? (logand (-> obj flags) 1))) + (and *display-vol-marks* (logtest? (-> obj flags) 1)) ) diff --git a/goal_src/engine/gfx/texture.gc b/goal_src/engine/gfx/texture.gc index f3d9efa4a7..4f513130a8 100644 --- a/goal_src/engine/gfx/texture.gc +++ b/goal_src/engine/gfx/texture.gc @@ -1004,9 +1004,7 @@ (+ tex-dest-base-chunk (the-as uint upload-chunk-idx)) ) ;; can we possibly use existing data in VRAM? - (set! need-tex - (nonzero? (logand needed-mask (ash 1 upload-chunk-idx))) - ) + (set! need-tex (logtest? needed-mask (ash 1 upload-chunk-idx))) ;; look for the start of a run of uploads. (if (zero? chunks-to-upload-count) (when (and (!= (-> pool ids current-dest-chunk) page-id) need-tex) @@ -1579,7 +1577,7 @@ (dotimes (v1-0 32) (let ((a2-0 (-> obj common-page v1-0))) (when (and (nonzero? a2-0) ;; known common texture page - (nonzero? (logand (-> obj common-page-mask) (ash 1 v1-0))) ;; in the mask. + (and (nonzero? a2-0) (logtest? (-> obj common-page-mask) (ash 1 v1-0))) ;; in the mask. ) ;; upload it! (upload-vram-pages obj (-> obj segment-common) a2-0 -2 (bucket-id bucket-65)) diff --git a/goal_src/engine/gfx/water/water-h.gc b/goal_src/engine/gfx/water/water-h.gc index 5d0849b51a..19a0ee502d 100644 --- a/goal_src/engine/gfx/water/water-h.gc +++ b/goal_src/engine/gfx/water/water-h.gc @@ -58,7 +58,7 @@ ) (defmethod display-water-marks? water-control ((obj water-control)) - (and *display-water-marks* (nonzero? (logand (-> obj flags) 1))) + (and *display-water-marks* (logtest? (-> obj flags) 1)) ) (defmethod new water-control ((allocation symbol) (type-to-make type) (arg0 process) (arg1 int) (arg2 float) (arg3 float) (arg4 float)) diff --git a/goal_src/engine/math/vector-h.gc b/goal_src/engine/math/vector-h.gc index a07c9d864e..3f9a00d5d6 100644 --- a/goal_src/engine/math/vector-h.gc +++ b/goal_src/engine/math/vector-h.gc @@ -69,7 +69,7 @@ (defmethod get-bit bit-array ((obj bit-array) (idx int)) "Is the bit at idx set or not?" (let ((v1-2 (-> obj bytes (/ idx 8)))) - (nonzero? (logand v1-2 (ash 1 (logand idx 7)))) + (logtest? v1-2 (ash 1 (logand idx 7))) ) ) diff --git a/goal_src/engine/nav/navigate-h.gc b/goal_src/engine/nav/navigate-h.gc index 5fdf657ef4..fd7885bf75 100644 --- a/goal_src/engine/nav/navigate-h.gc +++ b/goal_src/engine/nav/navigate-h.gc @@ -9,7 +9,6 @@ :bitfield #t :type uint32 (display-marks 0) - (bit0 0) ;; TODO - nav-enemy::45 (bit1 1) (bit2 2) (bit3 3) ;; TODO - nav-enemy::45 @@ -402,7 +401,7 @@ (defmethod should-display? nav-control ((obj nav-control)) (and *display-nav-marks* - (nonzero? (logand (-> obj flags) (nav-control-flags bit0 display-marks))) + (logtest? (-> obj flags) (nav-control-flags display-marks)) ) ) diff --git a/goal_src/engine/nav/path-h.gc b/goal_src/engine/nav/path-h.gc index 7b0d817147..0fd853c432 100644 --- a/goal_src/engine/nav/path-h.gc +++ b/goal_src/engine/nav/path-h.gc @@ -115,7 +115,7 @@ (defmethod should-display? path-control ((obj path-control)) "Should we display path marks?" (and *display-path-marks* - (nonzero? (logand (-> obj flags) (path-control-flag display))) + (logtest? (-> obj flags) (path-control-flag display)) ) ) diff --git a/goal_src/engine/nav/path.gc b/goal_src/engine/nav/path.gc index c456ef50f3..4fc13e5cb2 100644 --- a/goal_src/engine/nav/path.gc +++ b/goal_src/engine/nav/path.gc @@ -38,7 +38,7 @@ ((let ((a0-5 obj)) (and *display-path-marks* - (nonzero? (logand (-> a0-5 flags) (path-control-flag display))) + (logtest? (-> a0-5 flags) (path-control-flag display)) ) ) (dotimes (s5-1 (-> obj curve num-cverts)) @@ -412,12 +412,12 @@ ((let ((a0-5 obj)) (and *display-path-marks* - (nonzero? (logand (-> a0-5 flags) (path-control-flag display))) + (logtest? (-> a0-5 flags) (path-control-flag display)) ) ) (if (and - (nonzero? (logand (-> obj flags) (path-control-flag draw-line))) + (logtest? (-> obj flags) (path-control-flag draw-line)) (> (-> obj curve num-cverts) 0) ) (add-debug-curve2 diff --git a/goal_src/engine/sound/gsound.gc b/goal_src/engine/sound/gsound.gc index 56d90b212b..5b4d03acbf 100644 --- a/goal_src/engine/sound/gsound.gc +++ b/goal_src/engine/sound/gsound.gc @@ -826,7 +826,7 @@ (dotimes (i (-> *flava-table* count)) (if (= (-> *flava-table* row i music) music) - (return (-> *flava-table* row i flava n)) + (return (the-as int (-> *flava-table* row i flava n))) ) ) 0 diff --git a/goal_src/levels/common/nav-enemy.gc b/goal_src/levels/common/nav-enemy.gc index 319be8837d..162abafbe2 100644 --- a/goal_src/levels/common/nav-enemy.gc +++ b/goal_src/levels/common/nav-enemy.gc @@ -107,50 +107,46 @@ ;; INFO: Return type mismatch int vs none. (defmethod TODO-RENAME-39 nav-enemy ((obj nav-enemy)) (when - (and - (logtest? (-> obj nav-enemy-flags) 256) - (or - (not *target*) - (and - (zero? (logand (-> *target* state-flags) #x80f8)) - (>= - (the-as int (- (-> *display* base-frame-counter) (-> obj touch-time))) - 15 - ) + (and + (logtest? (-> obj nav-enemy-flags) 256) + (or + (not *target*) + (and + (zero? (logand (-> *target* state-flags) #x80f8)) + (>= + (the-as int (- (-> *display* base-frame-counter) (-> obj touch-time))) + 15 + ) + ) + ) ) - ) + (dummy-54 (-> obj collide-info) 2 1) + (set! (-> obj nav-enemy-flags) (logand -257 (-> obj nav-enemy-flags))) ) - (dummy-54 (-> obj collide-info) 2 1) - (set! (-> obj nav-enemy-flags) (logand -257 (-> obj nav-enemy-flags))) - ) ((method-of-object (-> obj draw shadow-ctrl) dummy-14)) (when *target* - (if *target* - (look-at-enemy! - (-> *target* neck) - (the-as vector (-> obj collide-info root-prim prim-core)) - (if (logtest? (-> obj nav-enemy-flags) 4) - 'attacking - ) - obj - ) + (if *target* + (look-at-enemy! + (-> *target* neck) + (the-as vector (-> obj collide-info root-prim prim-core)) + (if (logtest? (-> obj nav-enemy-flags) 4) + 'attacking + ) + obj + ) + ) + (if (and (nonzero? (-> obj neck)) (logtest? (-> obj nav-enemy-flags) #x4000)) + (set-target! + (-> obj neck) + (target-pos (-> obj nav-info player-look-at-joint)) + ) + ) ) - (if - (and - (nonzero? (-> obj neck)) - (nonzero? (logand (-> obj nav-enemy-flags) #x4000)) - ) - (set-target! - (-> obj neck) - (target-pos (-> obj nav-info player-look-at-joint)) - ) - ) - ) (when (-> obj nav-info debug-draw-neck) - (if (nonzero? (-> obj neck)) - (joint-mod-debug-draw (-> obj neck)) + (if (nonzero? (-> obj neck)) + (joint-mod-debug-draw (-> obj neck)) + ) ) - ) (ja-post) 0 (none) @@ -3168,7 +3164,7 @@ nav-enemy-default-event-handler ) (logior! (-> obj nav flags) - (nav-control-flags bit0 display-marks bit3 bit5 bit6 bit7) + (nav-control-flags display-marks bit3 bit5 bit6 bit7) ) (set! (-> obj nav gap-event) 'jump) (dummy-26 (-> obj nav)) diff --git a/test/decompiler/reference/engine/camera/cam-combiner_REF.gc b/test/decompiler/reference/engine/camera/cam-combiner_REF.gc index 0bd0dd591f..578ecb88ae 100644 --- a/test/decompiler/reference/engine/camera/cam-combiner_REF.gc +++ b/test/decompiler/reference/engine/camera/cam-combiner_REF.gc @@ -557,7 +557,7 @@ (when (and (< 8192.0 f28-1) - (nonzero? (logand (-> *camera* master-options) 2)) + (logtest? (-> *camera* master-options) 2) ) (vector-! (the-as vector (-> s1-0 vector)) diff --git a/test/decompiler/reference/engine/camera/cam-update_REF.gc b/test/decompiler/reference/engine/camera/cam-update_REF.gc index 2a32604ffa..2b1346c926 100644 --- a/test/decompiler/reference/engine/camera/cam-update_REF.gc +++ b/test/decompiler/reference/engine/camera/cam-update_REF.gc @@ -166,13 +166,13 @@ (let ((v1-32 #f)) (set! a0-16 #f) (when s4-0 - (set! v1-32 (nonzero? (logand (shl #x8000 16) (-> s4-0 flags)))) + (set! v1-32 (logtest? (shl #x8000 16) (-> s4-0 flags))) (if (< (-> s4-0 length) (-> s4-0 from-bsp current-leaf-idx)) (set! v1-32 #f) ) ) (when s3-0 - (set! a0-16 (nonzero? (logand (shl #x8000 16) (-> s3-0 flags)))) + (set! a0-16 (logtest? (shl #x8000 16) (-> s3-0 flags))) (if (< (-> s3-0 length) (-> s3-0 from-bsp current-leaf-idx)) (set! a0-16 #f) ) diff --git a/test/decompiler/reference/engine/debug/menu_REF.gc b/test/decompiler/reference/engine/debug/menu_REF.gc index 35b59e3c16..1bbbf10fdd 100644 --- a/test/decompiler/reference/engine/debug/menu_REF.gc +++ b/test/decompiler/reference/engine/debug/menu_REF.gc @@ -1686,7 +1686,7 @@ (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons right)) (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons left)) (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons down)) - (nonzero? (logand (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons up))) + (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons up)) ) (let ((v1-39 (cond ((logtest? diff --git a/test/decompiler/reference/engine/game/task/task-control_REF.gc b/test/decompiler/reference/engine/game/task/task-control_REF.gc index 2f81fce552..c9c1d888c4 100644 --- a/test/decompiler/reference/engine/game/task/task-control_REF.gc +++ b/test/decompiler/reference/engine/game/task/task-control_REF.gc @@ -46,19 +46,19 @@ ;; definition for method 12 of type task-cstage (defmethod closed? task-cstage ((obj task-cstage)) - (nonzero? (logand (-> obj flags) (task-flags closed))) + (logtest? (-> obj flags) (task-flags closed)) ) ;; definition for method 13 of type task-cstage (defmethod closed-by-default? task-cstage ((obj task-cstage)) - (nonzero? (logand (-> obj flags) (task-flags closed-by-default))) + (logtest? (-> obj flags) (task-flags closed-by-default)) ) ;; definition for method 11 of type task-cstage (defmethod task-available? task-cstage ((obj task-cstage) (arg0 task-control)) (let ((a0-1 obj)) (cond - ((nonzero? (logand (-> a0-1 flags) (task-flags closed))) + ((logtest? (-> a0-1 flags) (task-flags closed)) #f ) ((>= @@ -227,11 +227,9 @@ (dotimes (s4-0 (-> obj stage length)) (if (or (= arg0 'game) (let ((a0-4 (-> obj stage s4-0))) (not - (nonzero? - (logand - (-> a0-4 flags) - (task-flags closed-by-default) - ) + (logtest? + (-> a0-4 flags) + (task-flags closed-by-default) ) ) ) @@ -239,7 +237,7 @@ (open-task! (-> obj stage s4-0)) ) (let ((a0-10 (-> obj stage s4-0))) - (if (nonzero? (logand (-> a0-10 flags) (task-flags closed))) + (if (logtest? (-> a0-10 flags) (task-flags closed)) (close-task! (-> obj stage s4-0)) ) ) @@ -263,7 +261,7 @@ (= arg1 (-> obj stage v1-3 status)) ) (let ((a0-3 (-> obj stage v1-3))) - (return (nonzero? (logand (-> a0-3 flags) (task-flags closed)))) + (return (logtest? (-> a0-3 flags) (task-flags closed))) ) ) ) diff --git a/test/decompiler/reference/engine/geometry/vol-h_REF.gc b/test/decompiler/reference/engine/geometry/vol-h_REF.gc index 0425525679..28205a9bd0 100644 --- a/test/decompiler/reference/engine/geometry/vol-h_REF.gc +++ b/test/decompiler/reference/engine/geometry/vol-h_REF.gc @@ -173,5 +173,5 @@ ;; definition for method 11 of type vol-control (defmethod TODO-RENAME-11 vol-control ((obj vol-control)) - (and *display-vol-marks* (nonzero? (logand (-> obj flags) 1))) + (and *display-vol-marks* (logtest? (-> obj flags) 1)) ) diff --git a/test/decompiler/reference/engine/gfx/ocean/ocean-transition_REF.gc b/test/decompiler/reference/engine/gfx/ocean/ocean-transition_REF.gc index 39997751e5..d43acf3e38 100644 --- a/test/decompiler/reference/engine/gfx/ocean/ocean-transition_REF.gc +++ b/test/decompiler/reference/engine/gfx/ocean/ocean-transition_REF.gc @@ -22,11 +22,9 @@ (v1-4 (logand a0-4 3)) (a0-6 (+ (* a3-0 4) a2-3)) ) - (nonzero? - (logand - (-> *ocean-work* trans-camera-masks 0 mask (+ a1-2 (* a0-6 8))) - (ash 1 v1-4) - ) + (logtest? + (-> *ocean-work* trans-camera-masks 0 mask (+ a1-2 (* a0-6 8))) + (ash 1 v1-4) ) ) ) @@ -62,7 +60,7 @@ ) ) (if a0-11 - (nonzero? (logand (-> a0-11 1) (ash 1 v1-4))) + (logtest? (-> a0-11 1) (ash 1 v1-4)) #f ) ) diff --git a/test/decompiler/reference/engine/gfx/texture_REF.gc b/test/decompiler/reference/engine/gfx/texture_REF.gc index 45e920a202..74ba519546 100644 --- a/test/decompiler/reference/engine/gfx/texture_REF.gc +++ b/test/decompiler/reference/engine/gfx/texture_REF.gc @@ -1213,10 +1213,7 @@ ) (dotimes (upload-chunk-idx chunk-count) (set! current-dest-chunk (+ tex-dest-base-chunk upload-chunk-idx)) - (set! - need-tex - (nonzero? (logand allow-cache-mask (ash 1 upload-chunk-idx))) - ) + (set! need-tex (logtest? allow-cache-mask (ash 1 upload-chunk-idx))) (cond ((zero? chunks-to-upload-count) (when (and (!= (-> pool ids current-dest-chunk) page-id) need-tex) @@ -1856,10 +1853,7 @@ (dotimes (v1-0 32) (let ((a2-0 (-> obj common-page v1-0))) (when - (and - (nonzero? a2-0) - (nonzero? (logand (-> obj common-page-mask) (ash 1 v1-0))) - ) + (and (nonzero? a2-0) (logtest? (-> obj common-page-mask) (ash 1 v1-0))) (upload-vram-pages obj (-> obj segment-common) diff --git a/test/decompiler/reference/engine/gfx/water/water-h_REF.gc b/test/decompiler/reference/engine/gfx/water/water-h_REF.gc index 1878e33a49..b1e7734f0b 100644 --- a/test/decompiler/reference/engine/gfx/water/water-h_REF.gc +++ b/test/decompiler/reference/engine/gfx/water/water-h_REF.gc @@ -96,7 +96,7 @@ ;; definition for method 14 of type water-control (defmethod display-water-marks? water-control ((obj water-control)) - (and *display-water-marks* (nonzero? (logand (-> obj flags) 1))) + (and *display-water-marks* (logtest? (-> obj flags) 1)) ) ;; definition for method 0 of type water-control diff --git a/test/decompiler/reference/engine/math/vector-h_REF.gc b/test/decompiler/reference/engine/math/vector-h_REF.gc index 37aa746421..f2f75da579 100644 --- a/test/decompiler/reference/engine/math/vector-h_REF.gc +++ b/test/decompiler/reference/engine/math/vector-h_REF.gc @@ -62,7 +62,7 @@ ;; definition for method 9 of type bit-array (defmethod get-bit bit-array ((obj bit-array) (arg0 int)) (let ((v1-2 (-> obj bytes (/ arg0 8)))) - (nonzero? (logand v1-2 (ash 1 (logand arg0 7)))) + (logtest? v1-2 (ash 1 (logand arg0 7))) ) ) diff --git a/test/decompiler/reference/engine/nav/navigate-h_REF.gc b/test/decompiler/reference/engine/nav/navigate-h_REF.gc index 59f91c16e5..8272e4b0b9 100644 --- a/test/decompiler/reference/engine/nav/navigate-h_REF.gc +++ b/test/decompiler/reference/engine/nav/navigate-h_REF.gc @@ -591,7 +591,7 @@ (defmethod should-display? nav-control ((obj nav-control)) (and *display-nav-marks* - (nonzero? (logand (-> obj flags) (nav-control-flags display-marks bit0))) + (logtest? (-> obj flags) (nav-control-flags display-marks)) ) ) diff --git a/test/decompiler/reference/engine/nav/path-h_REF.gc b/test/decompiler/reference/engine/nav/path-h_REF.gc index 8d90f987e1..417fd61239 100644 --- a/test/decompiler/reference/engine/nav/path-h_REF.gc +++ b/test/decompiler/reference/engine/nav/path-h_REF.gc @@ -135,7 +135,7 @@ (defmethod should-display? path-control ((obj path-control)) (and *display-path-marks* - (nonzero? (logand (-> obj flags) (path-control-flag display))) + (logtest? (-> obj flags) (path-control-flag display)) ) ) diff --git a/test/decompiler/reference/engine/nav/path_REF.gc b/test/decompiler/reference/engine/nav/path_REF.gc index 52ed8ede33..4bf49ad6e3 100644 --- a/test/decompiler/reference/engine/nav/path_REF.gc +++ b/test/decompiler/reference/engine/nav/path_REF.gc @@ -34,7 +34,7 @@ ((let ((a0-5 obj)) (and *display-path-marks* - (nonzero? (logand (-> a0-5 flags) (path-control-flag display))) + (logtest? (-> a0-5 flags) (path-control-flag display)) ) ) (dotimes (s5-1 (-> obj curve num-cverts)) @@ -404,7 +404,7 @@ ((let ((a0-5 obj)) (and *display-path-marks* - (nonzero? (logand (-> a0-5 flags) (path-control-flag display))) + (logtest? (-> a0-5 flags) (path-control-flag display)) ) ) (if diff --git a/test/decompiler/reference/engine/sound/gsound_REF.gc b/test/decompiler/reference/engine/sound/gsound_REF.gc index 070eb688cc..14cb178e7d 100644 --- a/test/decompiler/reference/engine/sound/gsound_REF.gc +++ b/test/decompiler/reference/engine/sound/gsound_REF.gc @@ -1135,7 +1135,6 @@ (set! (-> *flava-table* count) 0) ;; definition for function flava-lookup -;; INFO: Return type mismatch int vs integer. (defun flava-lookup ((arg0 symbol) (arg1 int)) (dotimes (v1-0 (-> *flava-table* count)) (if (= (-> *flava-table* row v1-0 music) arg0) diff --git a/test/decompiler/reference/kernel/gkernel_REF.gc b/test/decompiler/reference/kernel/gkernel_REF.gc index b91841574e..d969b8f819 100644 --- a/test/decompiler/reference/kernel/gkernel_REF.gc +++ b/test/decompiler/reference/kernel/gkernel_REF.gc @@ -1508,11 +1508,11 @@ (when parent (let ((child (-> parent 0 child))) (if (= child proc) - (return (the-as (pointer process-tree) #f)) + (return (the-as object #f)) ) (while child (if (= (-> child 0 brother) proc) - (return child) + (return (the-as object child)) ) (set! child (-> child 0 brother)) ) diff --git a/test/decompiler/reference/levels/beach/bird-lady_REF.gc b/test/decompiler/reference/levels/beach/bird-lady_REF.gc index 6800a771ca..c3e8695c29 100644 --- a/test/decompiler/reference/levels/beach/bird-lady_REF.gc +++ b/test/decompiler/reference/levels/beach/bird-lady_REF.gc @@ -65,7 +65,7 @@ ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) - (nonzero? (logand (-> obj draw status) 8)) + (logtest? (-> obj draw status) 8) ) (let ((v1-9 (-> obj draw shadow-ctrl))) (set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags))) diff --git a/test/decompiler/reference/levels/beach/mayor_REF.gc b/test/decompiler/reference/levels/beach/mayor_REF.gc index 79ec438bc5..80624805ed 100644 --- a/test/decompiler/reference/levels/beach/mayor_REF.gc +++ b/test/decompiler/reference/levels/beach/mayor_REF.gc @@ -62,7 +62,7 @@ ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) - (nonzero? (logand (-> obj draw status) 8)) + (logtest? (-> obj draw status) 8) ) (let ((v1-9 (-> obj draw shadow-ctrl))) (set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags))) diff --git a/test/decompiler/reference/levels/beach/sculptor_REF.gc b/test/decompiler/reference/levels/beach/sculptor_REF.gc index cbff330297..fb7d8e24c6 100644 --- a/test/decompiler/reference/levels/beach/sculptor_REF.gc +++ b/test/decompiler/reference/levels/beach/sculptor_REF.gc @@ -80,7 +80,7 @@ ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) - (nonzero? (logand (-> obj draw status) 8)) + (logtest? (-> obj draw status) 8) ) (let ((v1-9 (-> obj draw shadow-ctrl))) (set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags))) diff --git a/test/decompiler/reference/levels/common/nav-enemy_REF.gc b/test/decompiler/reference/levels/common/nav-enemy_REF.gc index 4baf38cfbc..d61bad8f7e 100644 --- a/test/decompiler/reference/levels/common/nav-enemy_REF.gc +++ b/test/decompiler/reference/levels/common/nav-enemy_REF.gc @@ -131,11 +131,7 @@ obj ) ) - (if - (and - (nonzero? (-> obj neck)) - (nonzero? (logand (-> obj nav-enemy-flags) #x4000)) - ) + (if (and (nonzero? (-> obj neck)) (logtest? (-> obj nav-enemy-flags) #x4000)) (set-target! (-> obj neck) (target-pos (-> obj nav-info player-look-at-joint)) @@ -259,10 +255,11 @@ (set! (-> a1-1 mode) arg2) (set! (-> v1-0 param 1) (the-as uint a1-1)) ) - (when (send-event-function arg0 v1-0) - (dummy-54 (-> self collide-info) 2 0) - (logior! (-> self nav-enemy-flags) 256) - #t + (the-as object (when (send-event-function arg0 v1-0) + (dummy-54 (-> self collide-info) 2 0) + (logior! (-> self nav-enemy-flags) 256) + #t + ) ) ) ) @@ -456,7 +453,7 @@ nav-enemy-default-event-handler (if (or (logtest? (-> obj nav-enemy-flags) 128) - (nonzero? (logand #x80000 (-> obj nav flags))) + (logtest? #x80000 (-> obj nav flags)) ) (seek-to-point-toward-point! (-> obj collide-info) @@ -487,7 +484,7 @@ nav-enemy-default-event-handler 8192.0 #f (-> obj nav-info hover-if-no-ground) - (nonzero? (logand (-> obj nav-enemy-flags) #x8000)) + (logtest? (-> obj nav-enemy-flags) #x8000) ) (dummy-58 (-> obj collide-info) (-> obj collide-info transv)) ) @@ -600,7 +597,7 @@ nav-enemy-default-event-handler ;; definition for function nav-enemy-face-player-post ;; INFO: Return type mismatch int vs none. (defbehavior nav-enemy-face-player-post nav-enemy () - (if (and *target* (nonzero? (logand (-> self nav-enemy-flags) 16))) + (if (and *target* (logtest? (-> self nav-enemy-flags) 16)) (seek-to-point-toward-point! (-> self collide-info) (target-pos 0) @@ -660,10 +657,7 @@ nav-enemy-default-event-handler ;; INFO: Return type mismatch int vs none. (defbehavior nav-enemy-neck-control-inactive nav-enemy () (when - (and - (nonzero? (-> self neck)) - (nonzero? (logand (-> self nav-enemy-flags) #x4000)) - ) + (and (nonzero? (-> self neck)) (logtest? (-> self nav-enemy-flags) #x4000)) (set! (-> self nav-enemy-flags) (logand -16385 (-> self nav-enemy-flags))) (shut-down! (-> self neck)) ) @@ -1087,7 +1081,7 @@ nav-enemy-default-event-handler (nonzero? (-> obj skel)) (!= (-> obj skel root-channel 0) (-> obj skel channel)) ) - (and (nonzero? (-> obj draw)) (nonzero? (logand (-> obj draw status) 16))) + (and (nonzero? (-> obj draw)) (logtest? (-> obj draw status) 16)) ) ) ) @@ -1139,7 +1133,7 @@ nav-enemy-default-event-handler (the-as int (-> self state-timeout)) ) (nonzero? (-> self draw)) - (nonzero? (logand (-> self draw status) 8)) + (logtest? (-> self draw status) 8) ) (go-virtual nav-enemy-patrol) ) @@ -1227,11 +1221,7 @@ nav-enemy-default-event-handler ) (the-as int (-> self state-timeout)) ) - (if - (and - (nonzero? (-> self draw)) - (nonzero? (logand (-> self draw status) 8)) - ) + (if (and (nonzero? (-> self draw)) (logtest? (-> self draw status) 8)) (set! (-> self free-time) (-> *display* base-frame-counter)) ) (if @@ -1903,7 +1893,7 @@ nav-enemy-default-event-handler (if (or (not (TODO-RENAME-46 self (-> self nav-info stop-chase-distance))) - (nonzero? (logand (-> self nav-enemy-flags) 8192)) + (logtest? (-> self nav-enemy-flags) 8192) ) (go-virtual nav-enemy-stop-chase) ) @@ -2198,7 +2188,7 @@ nav-enemy-default-event-handler ) ) ) - (nonzero? (logand #x20000 (-> self nav flags))) + (logtest? #x20000 (-> self nav flags)) ) (go-virtual nav-enemy-give-up) ) @@ -2529,7 +2519,7 @@ nav-enemy-default-event-handler (logior! (-> self nav-enemy-flags) 1024) ) ) - (when (and arg1 (nonzero? (logand (-> self nav-enemy-flags) 1024))) + (when (and arg1 (logtest? (-> self nav-enemy-flags) 1024)) (set! (-> self nav-enemy-flags) (logand -513 (-> self nav-enemy-flags))) (set! f30-0 2048.0) ) @@ -2850,7 +2840,7 @@ nav-enemy-default-event-handler (if (or (logtest? (-> self nav-enemy-flags) 128) - (nonzero? (logand #x80000 (-> self nav flags))) + (logtest? #x80000 (-> self nav flags)) ) (seek-to-point-toward-point! (-> self collide-info) @@ -2915,7 +2905,7 @@ nav-enemy-default-event-handler ) 150 ) - (nonzero? (logand #x80000 (-> self nav flags))) + (logtest? #x80000 (-> self nav flags)) ) (go-virtual nav-enemy-chase) ) @@ -3164,7 +3154,7 @@ nav-enemy-default-event-handler ) (logior! (-> obj nav flags) - (nav-control-flags display-marks bit0 bit3 bit5 bit6 bit7) + (nav-control-flags display-marks bit3 bit5 bit6 bit7) ) (set! (-> obj nav gap-event) 'jump) (dummy-26 (-> obj nav)) diff --git a/test/decompiler/reference/levels/common/water-anim_REF.gc b/test/decompiler/reference/levels/common/water-anim_REF.gc index 67eeacf8e7..5dd170a0b2 100644 --- a/test/decompiler/reference/levels/common/water-anim_REF.gc +++ b/test/decompiler/reference/levels/common/water-anim_REF.gc @@ -1786,21 +1786,24 @@ :virtual #t :event (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) - (case arg2 - (('move-to) - (set! - (-> self root trans quad) - (-> (the-as vector (-> arg3 param 0)) quad) - ) - (set! (-> self water-height) (-> self root trans y)) - (if (nonzero? (-> self sound)) - (update-trans! (-> self sound) (-> self root trans)) - ) - (let ((v0-0 (logclear (-> self mask) (process-mask sleep-code)))) - (set! (-> self mask) v0-0) - v0-0 - ) - ) + (let ((v1-0 arg2)) + (the-as object (when (= v1-0 'move-to) + (set! + (-> self root trans quad) + (-> (the-as vector (-> arg3 param 0)) quad) + ) + (set! (-> self water-height) (-> self root trans y)) + (if (nonzero? (-> self sound)) + (update-trans! (-> self sound) (-> self root trans)) + ) + (let + ((v0-0 (logclear (-> self mask) (process-mask sleep-code))) + ) + (set! (-> self mask) v0-0) + v0-0 + ) + ) + ) ) ) :trans diff --git a/test/decompiler/reference/levels/misty/misty-teetertotter_REF.gc b/test/decompiler/reference/levels/misty/misty-teetertotter_REF.gc index 61a2199aa3..28b55edad6 100644 --- a/test/decompiler/reference/levels/misty/misty-teetertotter_REF.gc +++ b/test/decompiler/reference/levels/misty/misty-teetertotter_REF.gc @@ -129,59 +129,60 @@ (defstate teetertotter-launch (teetertotter) :event (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) - (when (= arg2 'touch) - (when - (and - ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg3 param 0)) - (the-as collide-shape-moving (-> self root)) - (the-as uint 1) - ) - (-> self rock-is-dangerous) - ) - (let ((a1-2 (new 'stack-no-clear 'event-message-block))) - (set! (-> a1-2 from) self) - (set! (-> a1-2 num-params) 2) - (set! (-> a1-2 message) 'attack) - (set! (-> a1-2 param 0) (-> arg3 param 0)) - (let ((a0-2 (new 'static 'attack-info :mask #x20))) - (set! (-> a0-2 mode) 'deadly) - (set! (-> a1-2 param 1) (the-as uint a0-2)) - ) - (send-event-function arg0 a1-2) - ) - ) - (when - (and - ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg3 param 0)) - (the-as collide-shape-moving (-> self root)) - (the-as uint 2) - ) - (target-on-end-of-teetertotter? self) - (not (-> self launched-player)) - (-> self in-launch-window) - ) - (let ((a1-4 (new 'stack-no-clear 'event-message-block))) - (set! (-> a1-4 from) self) - (set! (-> a1-4 num-params) 2) - (set! (-> a1-4 message) 'shove) - (set! (-> a1-4 param 0) (the-as uint #f)) - (let ((v1-16 (new 'static 'attack-info :mask #xcc0))) - (set! (-> v1-16 shove-back) 0.0) - (set! (-> v1-16 shove-up) 53248.0) - (set! (-> v1-16 angle) 'jump) - (set! (-> v1-16 control) 1.0) - (set! (-> a1-4 param 1) (the-as uint v1-16)) - ) - (when (send-event-function arg0 a1-4) - (let ((v0-0 #t)) - (set! (-> self launched-player) v0-0) - v0-0 - ) - ) - ) - ) + (the-as object (when (= arg2 'touch) + (when + (and + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg3 param 0)) + (the-as collide-shape-moving (-> self root)) + (the-as uint 1) + ) + (-> self rock-is-dangerous) + ) + (let ((a1-2 (new 'stack-no-clear 'event-message-block))) + (set! (-> a1-2 from) self) + (set! (-> a1-2 num-params) 2) + (set! (-> a1-2 message) 'attack) + (set! (-> a1-2 param 0) (-> arg3 param 0)) + (let ((a0-2 (new 'static 'attack-info :mask #x20))) + (set! (-> a0-2 mode) 'deadly) + (set! (-> a1-2 param 1) (the-as uint a0-2)) + ) + (send-event-function arg0 a1-2) + ) + ) + (when + (and + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg3 param 0)) + (the-as collide-shape-moving (-> self root)) + (the-as uint 2) + ) + (target-on-end-of-teetertotter? self) + (not (-> self launched-player)) + (-> self in-launch-window) + ) + (let ((a1-4 (new 'stack-no-clear 'event-message-block))) + (set! (-> a1-4 from) self) + (set! (-> a1-4 num-params) 2) + (set! (-> a1-4 message) 'shove) + (set! (-> a1-4 param 0) (the-as uint #f)) + (let ((v1-16 (new 'static 'attack-info :mask #xcc0))) + (set! (-> v1-16 shove-back) 0.0) + (set! (-> v1-16 shove-up) 53248.0) + (set! (-> v1-16 angle) 'jump) + (set! (-> v1-16 control) 1.0) + (set! (-> a1-4 param 1) (the-as uint v1-16)) + ) + (when (send-event-function arg0 a1-4) + (let ((v0-0 #t)) + (set! (-> self launched-player) v0-0) + v0-0 + ) + ) + ) + ) + ) ) ) :code diff --git a/test/decompiler/reference/levels/misty/misty-warehouse_REF.gc b/test/decompiler/reference/levels/misty/misty-warehouse_REF.gc index b9f6d29621..52dcef9bc4 100644 --- a/test/decompiler/reference/levels/misty/misty-warehouse_REF.gc +++ b/test/decompiler/reference/levels/misty/misty-warehouse_REF.gc @@ -283,9 +283,7 @@ (if (and (-> obj entity) - (nonzero? - (logand (-> obj entity extra perm status) (entity-perm-status complete)) - ) + (logtest? (-> obj entity extra perm status) (entity-perm-status complete)) ) (go silostep-rise #t) (go silostep-idle) diff --git a/test/decompiler/reference/levels/village1/explorer_REF.gc b/test/decompiler/reference/levels/village1/explorer_REF.gc index 93dcab36fd..d6f6334cf8 100644 --- a/test/decompiler/reference/levels/village1/explorer_REF.gc +++ b/test/decompiler/reference/levels/village1/explorer_REF.gc @@ -64,7 +64,7 @@ ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) - (nonzero? (logand (-> obj draw status) 8)) + (logtest? (-> obj draw status) 8) ) (let ((v1-9 (-> obj draw shadow-ctrl))) (set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags))) diff --git a/test/decompiler/reference/levels/village2/warrior_REF.gc b/test/decompiler/reference/levels/village2/warrior_REF.gc index e9c892ca69..4f7fd212a8 100644 --- a/test/decompiler/reference/levels/village2/warrior_REF.gc +++ b/test/decompiler/reference/levels/village2/warrior_REF.gc @@ -66,7 +66,7 @@ ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) - (nonzero? (logand (-> obj draw status) 8)) + (logtest? (-> obj draw status) 8) ) (let ((v1-9 (-> obj draw shadow-ctrl))) (set! (-> v1-9 settings flags) (logand -33 (-> v1-9 settings flags))) diff --git a/test/decompiler/test_FormExpressionBuild.cpp b/test/decompiler/test_FormExpressionBuild.cpp index 0e07b611c2..df70274926 100644 --- a/test/decompiler/test_FormExpressionBuild.cpp +++ b/test/decompiler/test_FormExpressionBuild.cpp @@ -2564,7 +2564,7 @@ TEST_F(FormRegressionTest, MoveFalse) { " daddiu sp, sp, 16\n"; std::string type = "(function int symbol)"; - std::string expected = "(nonzero? (logand (+ arg0 12) 1))"; + std::string expected = "(logtest? (+ arg0 12) 1)"; test_with_expr(func, type, expected, false, "", {{"L17", "A ~A"}}); } @@ -2934,7 +2934,7 @@ TEST_F(FormRegressionTest, AshPropagation2) { std::string type = "(function bit-array int symbol)"; std::string expected = "(let ((v1-2 (-> arg0 bytes (/ arg1 8))))\n" - " (nonzero? (logand v1-2 (ash 1 (logand arg1 7))))\n" + " (logtest? v1-2 (ash 1 (logand arg1 7)))\n" " )"; test_with_expr(func, type, expected); } \ No newline at end of file diff --git a/test/decompiler/test_FormExpressionBuild3.cpp b/test/decompiler/test_FormExpressionBuild3.cpp index dac6dcf805..a7ff033c6b 100644 --- a/test/decompiler/test_FormExpressionBuild3.cpp +++ b/test/decompiler/test_FormExpressionBuild3.cpp @@ -160,6 +160,6 @@ TEST_F(FormRegressionTest, WeirdShortCircuit2) { " jr ra\n" " daddu sp, sp, r0"; std::string type = "(function actor-link-info object)"; - std::string expected = "(and (-> arg0 prev) (-> arg0 prev extra process))"; + std::string expected = "(the-as object (and (-> arg0 prev) (-> arg0 prev extra process)))"; test_with_stack_structures(func, type, expected, "[[16, \"event-message-block\"]]"); } \ No newline at end of file