mirror of
https://github.com/open-goal/jak-project
synced 2026-07-11 07:25:37 -04:00
more fixes
This commit is contained in:
@@ -62,7 +62,8 @@ FormElement* SetVarOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||
m_dst,
|
||||
pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::ADDRESS_OF),
|
||||
pool.alloc_single_element_form<StackSpillValueElement>(nullptr, -1, offset, false)),
|
||||
pool.alloc_single_element_form<StackSpillValueElement>(
|
||||
nullptr, -1, offset, make_stack_slot_access(offset), false)),
|
||||
true, env.stack_slot_entries.at(offset).typespec);
|
||||
}
|
||||
} else {
|
||||
@@ -847,10 +848,12 @@ FormElement* StackSpillLoadOp::get_as_form(FormPool& pool, const Env& env) const
|
||||
if (env.has_type_analysis()) {
|
||||
read_type = env.get_types_before_op(m_my_idx).get_slot(m_offset).typespec();
|
||||
}
|
||||
return pool.alloc_element<SetVarElement>(m_dst,
|
||||
pool.alloc_single_element_form<StackSpillValueElement>(
|
||||
nullptr, m_size, m_offset, m_is_signed, read_type),
|
||||
true, type);
|
||||
return pool.alloc_element<SetVarElement>(
|
||||
m_dst,
|
||||
pool.alloc_single_element_form<StackSpillValueElement>(
|
||||
nullptr, m_size, m_offset, env.get_stack_slot_access_for_op(m_my_idx, m_offset),
|
||||
m_is_signed, read_type),
|
||||
true, type);
|
||||
}
|
||||
|
||||
FormElement* StackSpillStoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||
@@ -870,6 +873,7 @@ FormElement* StackSpillStoreOp::get_as_form(FormPool& pool, const Env& env) cons
|
||||
}
|
||||
}
|
||||
|
||||
return pool.alloc_element<StackSpillStoreElement>(m_value, m_size, m_offset, cast_type);
|
||||
return pool.alloc_element<StackSpillStoreElement>(
|
||||
m_value, m_size, m_offset, env.get_stack_slot_access_for_op(m_my_idx, m_offset), cast_type);
|
||||
}
|
||||
} // namespace decompiler
|
||||
|
||||
+127
-32
@@ -623,7 +623,7 @@ std::unordered_set<RegId, RegId::hash> Env::get_ssa_var(const RegAccessSet& vars
|
||||
|
||||
RegId Env::get_program_var_id(const RegisterAccess& var) const {
|
||||
if (is_stack_slot_access(var)) {
|
||||
return RegId(Register(Reg::GPR, Reg::SP), get_stack_slot_offset_from_access(var));
|
||||
return RegId(Register(Reg::GPR, Reg::SP), get_stack_slot_var_id_from_access(var));
|
||||
}
|
||||
return m_var_names.lookup(var.reg(), var.idx(), var.mode()).reg_id;
|
||||
}
|
||||
@@ -637,17 +637,20 @@ const UseDefInfo& Env::get_use_def_info(const RegisterAccess& ra) const {
|
||||
return m_var_names.use_def_info.at(var_id);
|
||||
}
|
||||
|
||||
RegisterAccess Env::get_stack_slot_access_for_op(int op_id, int offset) const {
|
||||
auto it = m_stack_slot_var_by_op.find(op_id);
|
||||
if (it == m_stack_slot_var_by_op.end()) {
|
||||
return make_stack_slot_access(offset);
|
||||
}
|
||||
return make_stack_slot_access(offset, it->second);
|
||||
}
|
||||
|
||||
void Env::disable_def(const RegisterAccess& access, DecompWarnings& warnings) {
|
||||
if (is_stack_slot_access(access)) {
|
||||
auto& info = m_stack_slot_use_def_info.at(get_program_var_id(access));
|
||||
for (auto& def : info.defs) {
|
||||
if (!def.disabled) {
|
||||
def.disabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
warnings.warning("disable stack def twice: {}",
|
||||
get_spill_slot_var_name(get_stack_slot_offset_from_access(access)));
|
||||
// Stack-slot use/def info is intentionally immutable during expression building.
|
||||
// Unlike registers, the stack-slot analysis models value lifetimes through merged control flow
|
||||
// with synthetic phi-like vars, and mutating counts here would desynchronize later accesses
|
||||
// from that analysis.
|
||||
return;
|
||||
}
|
||||
if (has_local_vars()) {
|
||||
@@ -657,16 +660,7 @@ void Env::disable_def(const RegisterAccess& access, DecompWarnings& warnings) {
|
||||
|
||||
void Env::disable_use(const RegisterAccess& access) {
|
||||
if (is_stack_slot_access(access)) {
|
||||
auto& info = m_stack_slot_use_def_info.at(get_program_var_id(access));
|
||||
for (auto& use : info.uses) {
|
||||
if (!use.disabled) {
|
||||
use.disabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error(
|
||||
fmt::format("Invalid disable use on stack slot {}",
|
||||
get_spill_slot_var_name(get_stack_slot_offset_from_access(access))));
|
||||
// See disable_def above.
|
||||
return;
|
||||
}
|
||||
if (has_local_vars()) {
|
||||
@@ -676,33 +670,134 @@ void Env::disable_use(const RegisterAccess& access) {
|
||||
|
||||
void Env::rebuild_stack_slot_use_def_info() {
|
||||
m_stack_slot_use_def_info.clear();
|
||||
m_stack_slot_var_by_op.clear();
|
||||
|
||||
if (!func || !func->ir2.atomic_ops) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& ops = *func->ir2.atomic_ops;
|
||||
const int block_count = (int)ops.block_id_to_first_atomic_op.size();
|
||||
std::vector<int> op_to_block(ops.ops.size(), -1);
|
||||
for (int block_id = 0; block_id < (int)ops.block_id_to_first_atomic_op.size(); block_id++) {
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
for (int op_id = ops.block_id_to_first_atomic_op.at(block_id);
|
||||
op_id < ops.block_id_to_end_atomic_op.at(block_id); op_id++) {
|
||||
op_to_block.at(op_id) = block_id;
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_set<int> offsets;
|
||||
for (int op_id = 0; op_id < (int)ops.ops.size(); op_id++) {
|
||||
const auto* op = ops.ops.at(op_id).get();
|
||||
if (auto* store = dynamic_cast<const StackSpillStoreOp*>(op)) {
|
||||
auto var_id = RegId(Register(Reg::GPR, Reg::SP), store->offset());
|
||||
auto& info = m_stack_slot_use_def_info[var_id];
|
||||
info.defs.push_back({op_id, op_to_block.at(op_id), AccessMode::WRITE, false});
|
||||
info.ssa_vars.insert(store->offset());
|
||||
if (auto* store = dynamic_cast<const StackSpillStoreOp*>(ops.ops.at(op_id).get())) {
|
||||
offsets.insert(store->offset());
|
||||
} else if (auto* load = dynamic_cast<const StackSpillLoadOp*>(ops.ops.at(op_id).get())) {
|
||||
offsets.insert(load->offset());
|
||||
}
|
||||
if (auto* load = dynamic_cast<const StackSpillLoadOp*>(op)) {
|
||||
auto var_id = RegId(Register(Reg::GPR, Reg::SP), load->offset());
|
||||
auto& info = m_stack_slot_use_def_info[var_id];
|
||||
info.uses.push_back({op_id, op_to_block.at(op_id), AccessMode::READ, false});
|
||||
info.ssa_vars.insert(load->offset());
|
||||
}
|
||||
|
||||
int next_var_id = 1;
|
||||
for (int offset : offsets) {
|
||||
std::vector<bool> reads_before_write(block_count, false);
|
||||
std::vector<bool> writes(block_count, false);
|
||||
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
bool seen_write = false;
|
||||
for (int op_id = ops.block_id_to_first_atomic_op.at(block_id);
|
||||
op_id < ops.block_id_to_end_atomic_op.at(block_id); op_id++) {
|
||||
const auto* op = ops.ops.at(op_id).get();
|
||||
if (auto* load = dynamic_cast<const StackSpillLoadOp*>(op)) {
|
||||
if (load->offset() == offset && !seen_write) {
|
||||
reads_before_write.at(block_id) = true;
|
||||
}
|
||||
} else if (auto* store = dynamic_cast<const StackSpillStoreOp*>(op)) {
|
||||
if (store->offset() == offset) {
|
||||
writes.at(block_id) = true;
|
||||
seen_write = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<bool> live_in(block_count, false);
|
||||
std::vector<bool> live_out(block_count, false);
|
||||
bool changed = true;
|
||||
while (changed) {
|
||||
changed = false;
|
||||
for (int block_id = block_count - 1; block_id >= 0; block_id--) {
|
||||
bool new_live_out = false;
|
||||
for (int succ : {func->basic_blocks.at(block_id).succ_branch,
|
||||
func->basic_blocks.at(block_id).succ_ft}) {
|
||||
if (succ != -1 && live_in.at(succ)) {
|
||||
new_live_out = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool new_live_in =
|
||||
reads_before_write.at(block_id) || (new_live_out && !writes.at(block_id));
|
||||
if (new_live_in != live_in.at(block_id) || new_live_out != live_out.at(block_id)) {
|
||||
live_in.at(block_id) = new_live_in;
|
||||
live_out.at(block_id) = new_live_out;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> phi_var(block_count, -1);
|
||||
std::vector<std::vector<int>> phi_sources(block_count);
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
if (live_in.at(block_id)) {
|
||||
phi_var.at(block_id) = next_var_id++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
int current_var = live_in.at(block_id) ? phi_var.at(block_id) : -1;
|
||||
for (int op_id = ops.block_id_to_first_atomic_op.at(block_id);
|
||||
op_id < ops.block_id_to_end_atomic_op.at(block_id); op_id++) {
|
||||
const auto* op = ops.ops.at(op_id).get();
|
||||
if (auto* load = dynamic_cast<const StackSpillLoadOp*>(op)) {
|
||||
if (load->offset() != offset) {
|
||||
continue;
|
||||
}
|
||||
ASSERT(current_var != -1);
|
||||
m_stack_slot_var_by_op[op_id] = current_var;
|
||||
auto& info = m_stack_slot_use_def_info[RegId(Register(Reg::GPR, Reg::SP), current_var)];
|
||||
info.uses.push_back({op_id, block_id, AccessMode::READ, false});
|
||||
info.ssa_vars.insert(current_var);
|
||||
} else if (auto* store = dynamic_cast<const StackSpillStoreOp*>(op)) {
|
||||
if (store->offset() != offset) {
|
||||
continue;
|
||||
}
|
||||
current_var = next_var_id++;
|
||||
m_stack_slot_var_by_op[op_id] = current_var;
|
||||
auto& info = m_stack_slot_use_def_info[RegId(Register(Reg::GPR, Reg::SP), current_var)];
|
||||
info.defs.push_back({op_id, block_id, AccessMode::WRITE, false});
|
||||
info.ssa_vars.insert(current_var);
|
||||
}
|
||||
}
|
||||
|
||||
if (!live_out.at(block_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSERT(current_var != -1);
|
||||
for (int succ :
|
||||
{func->basic_blocks.at(block_id).succ_branch, func->basic_blocks.at(block_id).succ_ft}) {
|
||||
if (succ != -1 && live_in.at(succ)) {
|
||||
phi_sources.at(succ).push_back(current_var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
if (phi_var.at(block_id) == -1) {
|
||||
continue;
|
||||
}
|
||||
int first_op = ops.block_id_to_first_atomic_op.at(block_id);
|
||||
for (int src_var : phi_sources.at(block_id)) {
|
||||
auto& info = m_stack_slot_use_def_info[RegId(Register(Reg::GPR, Reg::SP), src_var)];
|
||||
info.uses.push_back({first_op, block_id, AccessMode::READ, false});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-3
@@ -44,17 +44,27 @@ struct StackSpillEntry {
|
||||
}
|
||||
};
|
||||
|
||||
constexpr int STACK_SLOT_VAR_STRIDE = 1 << 16;
|
||||
|
||||
inline bool is_stack_slot_access(const RegisterAccess& access) {
|
||||
return access.reg() == Register(Reg::GPR, Reg::SP) && access.idx() < 0;
|
||||
}
|
||||
|
||||
inline int get_stack_slot_offset_from_access(const RegisterAccess& access) {
|
||||
ASSERT(is_stack_slot_access(access));
|
||||
return -access.idx() - 1;
|
||||
return (-access.idx() - 1) / STACK_SLOT_VAR_STRIDE;
|
||||
}
|
||||
|
||||
inline RegisterAccess make_stack_slot_access(int offset) {
|
||||
return RegisterAccess(AccessMode::READ, Register(Reg::GPR, Reg::SP), -offset - 1, true);
|
||||
inline int get_stack_slot_var_id_from_access(const RegisterAccess& access) {
|
||||
ASSERT(is_stack_slot_access(access));
|
||||
return (-access.idx() - 1) % STACK_SLOT_VAR_STRIDE;
|
||||
}
|
||||
|
||||
inline RegisterAccess make_stack_slot_access(int offset, int var_id = 0) {
|
||||
ASSERT(var_id >= 0);
|
||||
ASSERT(var_id < STACK_SLOT_VAR_STRIDE);
|
||||
return RegisterAccess(AccessMode::READ, Register(Reg::GPR, Reg::SP),
|
||||
-1 - (offset * STACK_SLOT_VAR_STRIDE + var_id), true);
|
||||
}
|
||||
|
||||
inline bool same_expression_var(const RegisterAccess& a, const RegisterAccess& b) {
|
||||
@@ -214,6 +224,7 @@ class Env {
|
||||
}
|
||||
|
||||
const UseDefInfo& get_use_def_info(const RegisterAccess& ra) const;
|
||||
RegisterAccess get_stack_slot_access_for_op(int op_id, int offset) const;
|
||||
void disable_use(const RegisterAccess& access);
|
||||
|
||||
void disable_def(const RegisterAccess& access, DecompWarnings& warnings);
|
||||
@@ -259,6 +270,7 @@ class Env {
|
||||
bool m_has_local_vars = false;
|
||||
VariableNames m_var_names;
|
||||
std::unordered_map<RegId, UseDefInfo, RegId::hash> m_stack_slot_use_def_info;
|
||||
std::unordered_map<int, int> m_stack_slot_var_by_op;
|
||||
|
||||
bool m_has_types = false;
|
||||
bool m_pp_mapped_by_behavior = false;
|
||||
|
||||
+10
-3
@@ -2776,8 +2776,13 @@ void VectorFloatLoadStoreElement::collect_vf_regs(RegSet& regs) const {
|
||||
StackSpillStoreElement::StackSpillStoreElement(SimpleAtom value,
|
||||
int size,
|
||||
int stack_offset,
|
||||
RegisterAccess access,
|
||||
const std::optional<TypeSpec>& cast_type)
|
||||
: m_value(value), m_size(size), m_stack_offset(stack_offset), m_cast_type(cast_type) {}
|
||||
: m_value(value),
|
||||
m_size(size),
|
||||
m_stack_offset(stack_offset),
|
||||
m_access(access),
|
||||
m_cast_type(cast_type) {}
|
||||
|
||||
goos::Object StackSpillStoreElement::to_form_internal(const Env& env) const {
|
||||
return pretty_print::build_list(
|
||||
@@ -2804,15 +2809,17 @@ void StackSpillStoreElement::get_modified_regs(RegSet&) const {}
|
||||
|
||||
StackSpillValueElement::StackSpillValueElement(int size,
|
||||
int stack_offset,
|
||||
RegisterAccess access,
|
||||
bool is_signed,
|
||||
std::optional<TypeSpec> read_type)
|
||||
: m_size(size),
|
||||
m_stack_offset(stack_offset),
|
||||
m_access(access),
|
||||
m_is_signed(is_signed),
|
||||
m_read_type(std::move(read_type)) {}
|
||||
|
||||
goos::Object StackSpillValueElement::to_form_internal(const Env& env) const {
|
||||
auto var = make_stack_slot_access(m_stack_offset);
|
||||
auto var = m_access;
|
||||
auto base = pretty_print::to_symbol(env.get_spill_slot_var_name(m_stack_offset));
|
||||
if (m_read_type && env.get_variable_type(var, true) != *m_read_type) {
|
||||
return pretty_print::build_list("the-as", m_read_type->print(), base);
|
||||
@@ -2826,7 +2833,7 @@ void StackSpillValueElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void StackSpillValueElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
void StackSpillValueElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
vars.insert(make_stack_slot_access(m_stack_offset));
|
||||
vars.insert(m_access);
|
||||
}
|
||||
void StackSpillValueElement::get_modified_regs(RegSet&) const {}
|
||||
|
||||
|
||||
@@ -1545,6 +1545,7 @@ class StackSpillStoreElement : public FormElement {
|
||||
StackSpillStoreElement(SimpleAtom value,
|
||||
int size,
|
||||
int stack_offset,
|
||||
RegisterAccess access,
|
||||
const std::optional<TypeSpec>& cast_type);
|
||||
goos::Object to_form_internal(const Env& env) const override;
|
||||
void apply(const std::function<void(FormElement*)>& f) override;
|
||||
@@ -1553,11 +1554,14 @@ class StackSpillStoreElement : public FormElement {
|
||||
void get_modified_regs(RegSet& regs) const override;
|
||||
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
||||
const std::optional<TypeSpec>& cast_type() const { return m_cast_type; }
|
||||
const RegisterAccess& access() const { return m_access; }
|
||||
int stack_offset() const { return m_stack_offset; }
|
||||
|
||||
private:
|
||||
SimpleAtom m_value;
|
||||
int m_size = -1;
|
||||
int m_stack_offset = -1;
|
||||
RegisterAccess m_access;
|
||||
std::optional<TypeSpec> m_cast_type;
|
||||
};
|
||||
|
||||
@@ -1566,9 +1570,11 @@ class StackSpillValueElement : public FormElement {
|
||||
public:
|
||||
StackSpillValueElement(int size,
|
||||
int stack_offset,
|
||||
RegisterAccess access,
|
||||
bool is_signed,
|
||||
std::optional<TypeSpec> read_type = std::nullopt);
|
||||
int stack_offset() const { return m_stack_offset; }
|
||||
const RegisterAccess& access() const { return m_access; }
|
||||
goos::Object to_form_internal(const Env& env) const override;
|
||||
void apply(const std::function<void(FormElement*)>& f) override;
|
||||
void apply_form(const std::function<void(Form*)>& f) override;
|
||||
@@ -1583,6 +1589,7 @@ class StackSpillValueElement : public FormElement {
|
||||
private:
|
||||
int m_size = -1;
|
||||
int m_stack_offset = -1;
|
||||
RegisterAccess m_access;
|
||||
bool m_is_signed = false;
|
||||
std::optional<TypeSpec> m_read_type;
|
||||
};
|
||||
|
||||
@@ -2738,8 +2738,7 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
if (m_src->is_single_element()) {
|
||||
auto spill_value = dynamic_cast<StackSpillValueElement*>(m_src->back());
|
||||
if (spill_value) {
|
||||
stack.push_non_seq_reg_to_reg(m_dst, make_stack_slot_access(spill_value->stack_offset()),
|
||||
m_src, m_src_type, m_var_info);
|
||||
stack.push_non_seq_reg_to_reg(m_dst, spill_value->access(), m_src, m_src_type, m_var_info);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7076,7 +7075,7 @@ void StackSpillStoreElement::push_to_stack(const Env& env, FormPool& pool, FormS
|
||||
InplaceOpInfo{FixedOperatorKind::LOGXOR, FixedOperatorKind::LOGXOR_IN_PLACE},
|
||||
};
|
||||
|
||||
auto dst_var = make_stack_slot_access(m_stack_offset);
|
||||
auto dst_var = m_access;
|
||||
auto dst_form = pool.form<SimpleAtomElement>(SimpleAtom::make_var(dst_var))->to_form(env);
|
||||
for (const auto& [kind, inplace_kind] : in_place_ops) {
|
||||
if (!src_as_generic->op().is_fixed(kind)) {
|
||||
@@ -7098,7 +7097,7 @@ void StackSpillStoreElement::push_to_stack(const Env& env, FormPool& pool, FormS
|
||||
}
|
||||
}
|
||||
|
||||
stack.push_value_to_reg(make_stack_slot_access(m_stack_offset), src, true, stack_type);
|
||||
stack.push_value_to_reg(m_access, src, true, stack_type);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -7358,7 +7357,7 @@ void StackSpillValueElement::update_from_stack(const Env& env,
|
||||
std::vector<FormElement*>* result,
|
||||
bool) {
|
||||
mark_popped();
|
||||
auto var = make_stack_slot_access(m_stack_offset);
|
||||
auto var = m_access;
|
||||
Form* form =
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, SimpleAtom::make_var(var));
|
||||
if (m_read_type && env.get_variable_type(var, true) != *m_read_type) {
|
||||
|
||||
@@ -18,6 +18,15 @@ bool nonempty_intersection(const RegSet& a, const RegSet& b) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool can_inline_non_seq_source(const RegisterAccess& src, const Env& env) {
|
||||
if (!is_stack_slot_access(src)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto& use_def = env.get_use_def_info(src);
|
||||
return use_def.use_count() == 1 && use_def.def_count() == 1;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string FormStack::StackEntry::print(const Env& env) const {
|
||||
@@ -147,9 +156,11 @@ Form* FormStack::pop_reg(const RegisterAccess& var,
|
||||
ASSERT(entry.source);
|
||||
if (entry.non_seq_source.has_value()) {
|
||||
ASSERT(entry.sequence_point == false);
|
||||
auto result = pop_reg(*entry.non_seq_source, barrier, env, allow_side_effects, i);
|
||||
if (result) {
|
||||
return result;
|
||||
if (can_inline_non_seq_source(*entry.non_seq_source, env)) {
|
||||
auto result = pop_reg(*entry.non_seq_source, barrier, env, allow_side_effects, i);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,13 +226,15 @@ Form* FormStack::pop_reg(Register reg,
|
||||
ASSERT(entry.source);
|
||||
if (entry.non_seq_source.has_value()) {
|
||||
ASSERT(entry.sequence_point == false);
|
||||
auto result = pop_reg(entry.non_seq_source->reg(), barrier, env, allow_side_effects, i);
|
||||
if (result) {
|
||||
if (found_orig_out) {
|
||||
*found_orig_out = true;
|
||||
*orig_out = *entry.destination;
|
||||
if (can_inline_non_seq_source(*entry.non_seq_source, env)) {
|
||||
auto result = pop_reg(entry.non_seq_source->reg(), barrier, env, allow_side_effects, i);
|
||||
if (result) {
|
||||
if (found_orig_out) {
|
||||
*found_orig_out = true;
|
||||
*orig_out = *entry.destination;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out, const Env* cons
|
||||
dynamic_cast<StackSpillValueElement*>(input->try_as_single_active_element());
|
||||
if (as_stack_spill) {
|
||||
got = true;
|
||||
result = make_stack_slot_access(as_stack_spill->stack_offset());
|
||||
result = as_stack_spill->access();
|
||||
}
|
||||
|
||||
if (got) {
|
||||
|
||||
@@ -153,6 +153,8 @@ with open(decomp_file_path) as f:
|
||||
decomp_form_paren_stack = []
|
||||
i = i + 1
|
||||
break
|
||||
if i + 1 == len(lines):
|
||||
break
|
||||
else:
|
||||
decomp_lines.append(line)
|
||||
i = i + 1
|
||||
|
||||
+4
@@ -1729,6 +1729,10 @@
|
||||
)
|
||||
)
|
||||
|
||||
(defmacro square (x)
|
||||
`(* ,x ,x)
|
||||
)
|
||||
|
||||
|
||||
(import "goal_src/jak1/engine/data/tpages.gc")
|
||||
(import "goal_src/jak1/engine/data/textures.gc")
|
||||
Generated
Vendored
+116
-115
@@ -114,7 +114,6 @@
|
||||
;; definition for method 9 of type lod-set
|
||||
;; INFO: Used lq/sq
|
||||
(defmethod setup-lods! ((this lod-set) (arg0 skeleton-group) (arg1 art-group) (arg2 entity))
|
||||
(local-vars (sv-16 res-tag))
|
||||
(let ((s4-0 arg0)
|
||||
(s5-0 arg1)
|
||||
)
|
||||
@@ -138,13 +137,13 @@
|
||||
(set! (-> this lod s3-0 dist) (res-lump-float arg2 'vis-dist :default 4095996000.0))
|
||||
)
|
||||
)
|
||||
(let ((v1-13 (-> s5-0 data (-> s4-0 jgeo))))
|
||||
(set! sv-16 (new 'static 'res-tag))
|
||||
(let ((v1-14 (res-lump-data (-> v1-13 extra) 'lod-dist pointer :tag-ptr (& sv-16))))
|
||||
(when v1-14
|
||||
(dotimes (a0-6 (the-as int (-> sv-16 elt-count)))
|
||||
(set! (-> this lod a0-6 dist) (-> (the-as (pointer float) (&+ v1-14 (* a0-6 4)))))
|
||||
)
|
||||
(let* ((v1-13 (-> s5-0 data (-> s4-0 jgeo)))
|
||||
(sv-16 (new 'static 'res-tag))
|
||||
(v1-14 (res-lump-data (-> v1-13 extra) 'lod-dist pointer :tag-ptr (& sv-16)))
|
||||
)
|
||||
(when v1-14
|
||||
(dotimes (a0-6 (the-as int (-> sv-16 elt-count)))
|
||||
(set! (-> this lod a0-6 dist) (-> (the-as (pointer float) (&+ v1-14 (* a0-6 4)))))
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -428,7 +427,7 @@
|
||||
;; WARN: Stack slot offset 20 signed mismatch
|
||||
;; INFO: Return type mismatch draw-control vs none.
|
||||
(defmethod initialize-skeleton ((this process-drawable) (arg0 skeleton-group) (arg1 pair))
|
||||
(local-vars (s3-0 draw-control) (sv-16 art-element) (sv-20 int))
|
||||
(local-vars (s3-0 draw-control))
|
||||
(let ((s1-0 (cond
|
||||
((= (-> arg0 texture-level) 2)
|
||||
(-> *level* level-default)
|
||||
@@ -448,122 +447,124 @@
|
||||
(set! s3-0 (the-as draw-control #f))
|
||||
(goto cfg-59)
|
||||
)
|
||||
(set! sv-16 (-> s4-0 data (-> arg0 jgeo)))
|
||||
(set! sv-20 (-> s4-0 length))
|
||||
(when (or (>= (-> arg0 jgeo) sv-20) (!= (-> sv-16 type) art-joint-geo))
|
||||
(go process-drawable-art-error "joint-geo")
|
||||
(set! s3-0 (the-as draw-control #f))
|
||||
(goto cfg-59)
|
||||
)
|
||||
(let ((v0-3 (new 'process 'draw-control this (the-as art-joint-geo sv-16))))
|
||||
(set! (-> this draw) v0-3)
|
||||
(set! s3-0 v0-3)
|
||||
)
|
||||
(let ((v1-26 s3-0))
|
||||
(set! (-> v1-26 status) (draw-status no-skeleton-update))
|
||||
(set! (-> v1-26 art-group) s4-0)
|
||||
(set! (-> v1-26 jgeo) (the-as art-joint-geo sv-16))
|
||||
(set! (-> v1-26 force-lod) -1)
|
||||
(set! (-> v1-26 cur-lod) -1)
|
||||
(set! (-> v1-26 shadow) #f)
|
||||
(set! (-> v1-26 shadow-ctrl) #f)
|
||||
(set! (-> v1-26 data-format) (the-as uint 1))
|
||||
(set! (-> v1-26 color-mult quad) (-> (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) quad))
|
||||
(set! (-> v1-26 color-emissive quad) (-> (new 'static 'vector) quad))
|
||||
(set! (-> v1-26 level-index) (the-as uint (-> (if (-> this entity)
|
||||
(-> this entity extra level)
|
||||
(-> *level* level-default)
|
||||
)
|
||||
index
|
||||
)
|
||||
)
|
||||
(let ((sv-16 (-> s4-0 data (-> arg0 jgeo)))
|
||||
(sv-20 (-> s4-0 length))
|
||||
)
|
||||
(when (or (>= (-> arg0 jgeo) sv-20) (!= (-> sv-16 type) art-joint-geo))
|
||||
(go process-drawable-art-error "joint-geo")
|
||||
(set! s3-0 (the-as draw-control #f))
|
||||
(goto cfg-59)
|
||||
)
|
||||
(let ((v0-3 (new 'process 'draw-control this (the-as art-joint-geo sv-16))))
|
||||
(set! (-> this draw) v0-3)
|
||||
(set! s3-0 v0-3)
|
||||
)
|
||||
(let ((v1-26 s3-0))
|
||||
(set! (-> v1-26 status) (draw-status no-skeleton-update))
|
||||
(set! (-> v1-26 art-group) s4-0)
|
||||
(set! (-> v1-26 jgeo) (the-as art-joint-geo sv-16))
|
||||
(set! (-> v1-26 force-lod) -1)
|
||||
(set! (-> v1-26 cur-lod) -1)
|
||||
(set! (-> v1-26 shadow) #f)
|
||||
(set! (-> v1-26 shadow-ctrl) #f)
|
||||
(set! (-> v1-26 data-format) (the-as uint 1))
|
||||
(set! (-> v1-26 color-mult quad) (-> (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) quad))
|
||||
(set! (-> v1-26 color-emissive quad) (-> (new 'static 'vector) quad))
|
||||
(set! (-> v1-26 level-index) (the-as uint (-> (if (-> this entity)
|
||||
(-> this entity extra level)
|
||||
(-> *level* level-default)
|
||||
)
|
||||
index
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> v1-26 longest-edge) (-> arg0 longest-edge))
|
||||
(set! (-> v1-26 ripple) #f)
|
||||
)
|
||||
(set! (-> s3-0 bounds quad) (-> arg0 bounds quad))
|
||||
(let ((v1-28 (-> arg0 shadow)))
|
||||
(when (and (> v1-28 0) (< v1-28 sv-20))
|
||||
(let ((s0-0 (-> s4-0 data v1-28))
|
||||
(v1-32 (res-lump-value (-> this entity) 'options uint128))
|
||||
)
|
||||
(if (and (not (logtest? #x20000 v1-32)) (= (-> s0-0 type) shadow-geo))
|
||||
(set! (-> s3-0 shadow) (the-as shadow-geo s0-0))
|
||||
)
|
||||
)
|
||||
(set! (-> v1-26 longest-edge) (-> arg0 longest-edge))
|
||||
(set! (-> v1-26 ripple) #f)
|
||||
)
|
||||
(set! (-> s3-0 bounds quad) (-> arg0 bounds quad))
|
||||
(let ((v1-28 (-> arg0 shadow)))
|
||||
(when (and (> v1-28 0) (< v1-28 sv-20))
|
||||
(let ((s0-0 (-> s4-0 data v1-28))
|
||||
(v1-32 (res-lump-value (-> this entity) 'options uint128))
|
||||
)
|
||||
(if (and (not (logtest? #x20000 v1-32)) (= (-> s0-0 type) shadow-geo))
|
||||
(set! (-> s3-0 shadow) (the-as shadow-geo s0-0))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (not (setup-lods! (-> s3-0 lod-set) arg0 s4-0 (-> this entity)))
|
||||
(go process-drawable-art-error "mesh")
|
||||
(if (not (setup-lods! (-> s3-0 lod-set) arg0 s4-0 (-> this entity)))
|
||||
(go process-drawable-art-error "mesh")
|
||||
)
|
||||
(let ((v1-43 (res-lump-value (-> sv-16 extra) 'texture-bucket int :default (the-as uint128 1))))
|
||||
(let ((a0-39 (if (= (-> arg0 texture-level) 2)
|
||||
2
|
||||
(-> s1-0 index)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (= (the-as uint v1-43) 4)
|
||||
(set! v1-43 2)
|
||||
)
|
||||
(if (= a0-39 2)
|
||||
(set! v1-43 (-> arg0 sort))
|
||||
)
|
||||
)
|
||||
(set! (-> s3-0 sink-group) (-> s1-0 foreground-sink-group v1-43))
|
||||
)
|
||||
(let ((v1-43 (res-lump-value (-> sv-16 extra) 'texture-bucket int :default (the-as uint128 1))))
|
||||
(let ((a0-39 (if (= (-> arg0 texture-level) 2)
|
||||
2
|
||||
(-> s1-0 index)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (= (the-as uint v1-43) 4)
|
||||
(set! v1-43 2)
|
||||
)
|
||||
(if (= a0-39 2)
|
||||
(set! v1-43 (-> arg0 sort))
|
||||
)
|
||||
)
|
||||
(set! (-> s3-0 sink-group) (-> s1-0 foreground-sink-group v1-43))
|
||||
)
|
||||
(set! (-> s3-0 dma-add-func) (the-as (function process-drawable draw-control symbol object none) nothing))
|
||||
(set! (-> this node-list) (make-nodes-from-jg (the-as art-joint-geo sv-16) arg1 'process))
|
||||
(set! (-> s3-0 dma-add-func) dma-add-process-drawable)
|
||||
(set! (-> s3-0 shadow-mask) (res-lump-value (-> this entity) 'shadow-mask uint))
|
||||
(set! (-> s3-0 light-index) (res-lump-value (-> this entity) 'light-index uint))
|
||||
(lod-set! s3-0 0)
|
||||
(let ((a2-10 (res-lump-value (-> sv-16 extra) 'joint-channel int :default (the-as uint128 6))))
|
||||
(cond
|
||||
((> a2-10 0)
|
||||
(logior! (-> s3-0 status) (draw-status has-joint-channels))
|
||||
(let ((v0-13 (new 'process 'joint-control a2-10)))
|
||||
(set! (-> this skel) v0-13)
|
||||
(let ((s2-1 v0-13))
|
||||
(cond
|
||||
((>= (-> arg0 janim) 0)
|
||||
(when (or (>= (-> arg0 janim) sv-20) (!= (-> s4-0 data (-> arg0 janim) type) art-joint-anim))
|
||||
(go process-drawable-art-error "initial joint-anim")
|
||||
(set! s3-0 (the-as draw-control #f))
|
||||
(goto cfg-59)
|
||||
)
|
||||
(ja-channel-set! 1)
|
||||
(let ((s1-1 (-> this skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
s1-1
|
||||
(the-as art-joint-anim (-> s4-0 data (-> arg0 janim)))
|
||||
num-func-identity
|
||||
(set! (-> s3-0 dma-add-func) (the-as (function process-drawable draw-control symbol object none) nothing))
|
||||
(set! (-> this node-list) (make-nodes-from-jg (the-as art-joint-geo sv-16) arg1 'process))
|
||||
(set! (-> s3-0 dma-add-func) dma-add-process-drawable)
|
||||
(set! (-> s3-0 shadow-mask) (res-lump-value (-> this entity) 'shadow-mask uint))
|
||||
(set! (-> s3-0 light-index) (res-lump-value (-> this entity) 'light-index uint))
|
||||
(lod-set! s3-0 0)
|
||||
(let ((a2-10 (res-lump-value (-> sv-16 extra) 'joint-channel int :default (the-as uint128 6))))
|
||||
(cond
|
||||
((> a2-10 0)
|
||||
(logior! (-> s3-0 status) (draw-status has-joint-channels))
|
||||
(let ((v0-13 (new 'process 'joint-control a2-10)))
|
||||
(set! (-> this skel) v0-13)
|
||||
(let ((s2-1 v0-13))
|
||||
(cond
|
||||
((>= (-> arg0 janim) 0)
|
||||
(when (or (>= (-> arg0 janim) sv-20) (!= (-> s4-0 data (-> arg0 janim) type) art-joint-anim))
|
||||
(go process-drawable-art-error "initial joint-anim")
|
||||
(set! s3-0 (the-as draw-control #f))
|
||||
(goto cfg-59)
|
||||
)
|
||||
(ja-channel-set! 1)
|
||||
(let ((s1-1 (-> this skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
s1-1
|
||||
(the-as art-joint-anim (-> s4-0 data (-> arg0 janim)))
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> s1-1 frame-num) 0.0)
|
||||
)
|
||||
(set! (-> s1-1 frame-num) 0.0)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(ja-channel-set! 0)
|
||||
(else
|
||||
(ja-channel-set! 0)
|
||||
)
|
||||
)
|
||||
(set! (-> s2-1 effect) (new 'process 'effect-control this))
|
||||
)
|
||||
(set! (-> s2-1 effect) (new 'process 'effect-control this))
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set! (-> s3-0 skeleton bones 0 transform vector 3 quad) (-> (the-as vector (get-property-struct
|
||||
(-> sv-16 extra)
|
||||
'trans-offset
|
||||
'interp
|
||||
-1000000000.0
|
||||
*null-vector*
|
||||
(the-as (pointer res-tag) #f)
|
||||
*res-static-buf*
|
||||
)
|
||||
)
|
||||
quad
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set! (-> s3-0 skeleton bones 0 transform vector 3 quad) (-> (the-as vector (get-property-struct
|
||||
(-> sv-16 extra)
|
||||
'trans-offset
|
||||
'interp
|
||||
-1000000000.0
|
||||
*null-vector*
|
||||
(the-as (pointer res-tag) #f)
|
||||
*res-static-buf*
|
||||
)
|
||||
)
|
||||
quad
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
Generated
Vendored
+1
-2
@@ -63,7 +63,6 @@
|
||||
;; WARN: Stack slot offset 16 signed mismatch
|
||||
;; INFO: Return type mismatch vector4w vs pointer.
|
||||
(defun render-eyes ((arg0 dma-buffer) (arg1 eye-control) (arg2 int))
|
||||
(local-vars (sv-16 float))
|
||||
(let ((s4-0 32)
|
||||
(s3-0 (+ (* arg2 32) 32))
|
||||
(s2-0 (* arg2 32))
|
||||
@@ -71,8 +70,8 @@
|
||||
(let ((f28-0 (* 16.0 (+ (the float (+ s4-0 16)) (* 32.0 (-> arg1 left data 0 x)))))
|
||||
(f26-0 (* 16.0 (+ (the float (+ s3-0 16)) (* 32.0 (-> arg1 left data 0 y)))))
|
||||
(f30-0 (* 16.0 (+ (the float (+ s4-0 48)) (* 32.0 (-> arg1 right data 0 x)))))
|
||||
(sv-16 (* 16.0 (+ (the float (+ s3-0 16)) (* 32.0 (-> arg1 right data 0 y)))))
|
||||
)
|
||||
(set! sv-16 (* 16.0 (+ (the float (+ s3-0 16)) (* 32.0 (-> arg1 right data 0 y)))))
|
||||
(let ((s1-0 (-> arg1 shaders 0)))
|
||||
(let ((v1-6 (the-as object (-> arg0 base))))
|
||||
(set! (-> (the-as dma-gif-packet v1-6) dma-vif quad) (-> *eye-work* adgif-tmpl dma-vif quad))
|
||||
Reference in New Issue
Block a user