diff --git a/decompiler/analysis/atomic_op_builder.cpp b/decompiler/analysis/atomic_op_builder.cpp index 775f90adde..4c8250743a 100644 --- a/decompiler/analysis/atomic_op_builder.cpp +++ b/decompiler/analysis/atomic_op_builder.cpp @@ -156,8 +156,7 @@ std::unique_ptr make_standard_load(const Instruction& i0, if (i0.get_src(0).is_label() && i0.get_src(1).is_reg(rfp())) { // it's an FP relative load. src = SimpleAtom::make_static_address(i0.get_src(0).get_label()).as_expr(); - } else if (i0.get_src(0).is_imm() && i0.get_src(1).is_reg(rsp()) && - (kind == LoadVarOp::Kind::SIGNED || kind == LoadVarOp::Kind::UNSIGNED)) { + } else if (i0.get_src(0).is_imm() && i0.get_src(1).is_reg(rsp())) { // it's a stack spill. return std::make_unique(make_dst_var(i0, idx), load_size, i0.get_src(0).get_imm(), @@ -178,7 +177,7 @@ std::unique_ptr make_standard_store(const Instruction& i0, int idx, int store_size, StoreOp::Kind kind) { - if (i0.get_src(2).is_reg(Register(Reg::GPR, Reg::SP)) && kind == StoreOp::Kind::INTEGER) { + if (i0.get_src(2).is_reg(Register(Reg::GPR, Reg::SP))) { if (kind == StoreOp::Kind::INTEGER && store_size == 4 && i0.get_src(1).get_imm() == 0) { // this is a bit of a hack. enter-state does a sw onto the stack that's not a spill, but // instead manipulates the stores "ra" register that will later be restored. diff --git a/decompiler/analysis/expression_build.cpp b/decompiler/analysis/expression_build.cpp index 242dd2c0d2..55bbd935f4 100644 --- a/decompiler/analysis/expression_build.cpp +++ b/decompiler/analysis/expression_build.cpp @@ -101,6 +101,26 @@ bool convert_to_expressions( assert(x->parent_form == top_level_form); } + // if we were don't return, make sure we didn't find a return form. + if (f.type.last_arg() == TypeSpec("none")) { + bool found_return = false; + top_level_form->apply([&](FormElement* elt) { + if (dynamic_cast(elt)) { + found_return = true; + } + }); + + if (found_return) { + auto warn = fmt::format( + "Function {} has a return type of none, but the expression builder found a return " + "statement.", + f.guessed_name.to_string()); + f.warnings.expression_build_warning(warn); + lg::warn(warn); + return false; + } + } + } catch (std::exception& e) { f.warnings.expression_build_warning("In {}: {}", f.guessed_name.to_string(), e.what()); lg::warn("In {}: {}", f.guessed_name.to_string(), e.what()); diff --git a/decompiler/analysis/stack_spill.cpp b/decompiler/analysis/stack_spill.cpp index 98a4b74c20..b54ace866d 100644 --- a/decompiler/analysis/stack_spill.cpp +++ b/decompiler/analysis/stack_spill.cpp @@ -69,7 +69,9 @@ constexpr StackInstrInfo stack_instrs[] = {{InstructionKind::SQ, false, 16, fals {InstructionKind::LQ, true, 16, false}, {InstructionKind::SW, false, 4, false}, //{InstructionKind::LWU, true, 4, false} - {InstructionKind::SD, false, 8, false}}; + {InstructionKind::SD, false, 8, false}, + {InstructionKind::SWC1, false, 4, false}, + {InstructionKind::LWC1, true, 4, false}}; } // namespace StackSpillMap build_spill_map(const std::vector& instructions, Range range) {