diff --git a/common/dma/dma.cpp b/common/dma/dma.cpp index d2d52b2719..4e8ed3f62c 100644 --- a/common/dma/dma.cpp +++ b/common/dma/dma.cpp @@ -26,10 +26,10 @@ std::string VifCode::print() { result = fmt::format("STCYCL cl: {} wl: {}", stcycl.cl, stcycl.wl); } break; case Kind::OFFSET: - result = "OFFSET"; + result = fmt::format("OFFSET 0x{:x}", immediate); break; case Kind::BASE: - result = "BASE"; + result = fmt::format("BASE 0x{:x}", immediate); break; case Kind::ITOP: result = "ITOP"; @@ -59,7 +59,7 @@ std::string VifCode::print() { result = "MSCNT"; break; case Kind::MSCALF: - result = "MSCALF"; + result = fmt::format("MSCALF 0x{:x}", immediate); break; case Kind::STMASK: result = "STMASK"; @@ -107,6 +107,13 @@ std::string VifCode::print() { break; } + case Kind::UNPACK_V2_16: { + VifCodeUnpack up(*this); + result = fmt::format("UNPACK-V2-16: {} addr: {} us: {} tops: {}", num, up.addr_qw, + up.is_unsigned, up.use_tops_flag); + break; + } + default: fmt::print("Unhandled vif code {}\n", (int)kind); diff --git a/common/dma/dma.h b/common/dma/dma.h index 128f86d401..984b890e11 100644 --- a/common/dma/dma.h +++ b/common/dma/dma.h @@ -87,6 +87,9 @@ inline void emulate_dma(const void* source_base, void* dest_base, u32 tadr, u32 tadr += 16; return; } break; + case DmaTag::Kind::END: + // does this transfer anything in TTE??? + return; default: printf("bad tag: %d\n", (int)tag.kind); ASSERT(false); @@ -122,6 +125,7 @@ struct VifCode { UNPACK_V4_16 = 0b1101101, UNPACK_V3_32 = 0b1101000, UNPACK_V4_8 = 0b1101110, + UNPACK_V2_16 = 0b1100101, }; VifCode(u32 value) { diff --git a/common/util/FontUtils.cpp b/common/util/FontUtils.cpp index c63a1be7b3..dc046fe059 100644 --- a/common/util/FontUtils.cpp +++ b/common/util/FontUtils.cpp @@ -25,6 +25,7 @@ GameTextFontBank::GameTextFontBank(GameTextVersion version, std::sort( m_replace_info->begin(), m_replace_info->end(), [](const ReplaceInfo& a, const ReplaceInfo& b) { return a.from.size() > b.from.size(); }); + (void)m_version; } /*! diff --git a/decompiler/IR2/FormExpressionAnalysis.cpp b/decompiler/IR2/FormExpressionAnalysis.cpp index 4a8ad2ad47..c1c83df59c 100644 --- a/decompiler/IR2/FormExpressionAnalysis.cpp +++ b/decompiler/IR2/FormExpressionAnalysis.cpp @@ -1225,8 +1225,8 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env, as_generic->op().func()->try_as_single_element()); if (as_func_head && as_func_head->expr().is_identity() && as_func_head->expr().get_arg(0).is_sym_val()) { - auto& name = as_func_head->expr().get_arg(0).get_str(); - if (name == "rand-vu-int-range") { + auto& func_name = as_func_head->expr().get_arg(0).get_str(); + if (func_name == "rand-vu-int-range") { arg1_cast = TypeSpec("time-frame"); } } @@ -1277,7 +1277,7 @@ void SimpleExpressionElement::update_from_stack_force_si_2(const Env& env, if (arg1_reg) { auto arg1_type = env.get_types_before_op(m_my_idx).get(m_expr.get_arg(1).var().reg()).typespec(); - bool is_timeframe = arg1_type == TypeSpec("time-frame"); + // bool is_timeframe = arg1_type == TypeSpec("time-frame"); arg1_i = is_int_type(arg1_type); } else { ASSERT(m_expr.get_arg(1).is_int()); diff --git a/decompiler/VuDisasm/VuDisassembler.cpp b/decompiler/VuDisasm/VuDisassembler.cpp index e4c2197ba7..a6fdfaa279 100644 --- a/decompiler/VuDisasm/VuDisassembler.cpp +++ b/decompiler/VuDisasm/VuDisassembler.cpp @@ -592,10 +592,35 @@ std::string mask_to_string(u8 val) { } return result; } + +std::string vf_src(const std::string& name, bool mips2c_format) { + if (mips2c_format) { + return fmt::format("c->vf_src({}).vf", name); + } else { + return fmt::format("vu.{}", name); + } +} + +std::string vf_dst(const std::string& name, bool mips2c_format) { + if (mips2c_format) { + return fmt::format("c->vfs[{}].vf", name); + } else { + return fmt::format("vu.{}", name); + } +} + +std::string vi_src(const std::string& name, bool mips2c_format) { + if (mips2c_format) { + return fmt::format("vis[{}]", name); + } else { + return fmt::format("vu.{}", name); + } +} + } // namespace int unk = 0; -std::string VuDisassembler::to_cpp(const VuInstruction& instr) const { +std::string VuDisassembler::to_cpp(const VuInstruction& instr, bool mips2c_format) const { switch (instr.kind) { case VuInstrK::NOP: case VuInstrK::LOWER_NOP: @@ -606,36 +631,50 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const { instr.dst->to_string(m_label_names), instr.src.at(0).to_string(m_label_names)); } else if (instr.src.at(0).value() == 0) { - return fmt::format("lq_buffer(Mask::{}, vu.{}, vu.{});", mask_to_string(*instr.mask), - instr.dst->to_string(m_label_names), + return fmt::format(mips2c_format ? "lq_buffer(Mask::{}, c->vfs[{}].vf, vis[{}]);" + : "lq_buffer(Mask::{}, vu.{}, vu.{});", + mask_to_string(*instr.mask), instr.dst->to_string(m_label_names), instr.src.at(1).to_string(m_label_names)); } else { - return fmt::format("lq_buffer(Mask::{}, vu.{}, vu.{} + {});", mask_to_string(*instr.mask), - instr.dst->to_string(m_label_names), + return fmt::format(mips2c_format ? "lq_buffer(Mask::{}, c->vfs[{}].vf, vis[{}] + {});" + : "lq_buffer(Mask::{}, vu.{}, vu.{} + {});", + mask_to_string(*instr.mask), instr.dst->to_string(m_label_names), instr.src.at(1).to_string(m_label_names), instr.src.at(0).to_string(m_label_names)); } goto unknown; case VuInstrK::LQI: - return fmt::format("lq_buffer(Mask::{}, vu.{}, vu.{}++);", mask_to_string(*instr.mask), - instr.dst->to_string(m_label_names), + ASSERT(!instr.src.at(0).is_int_reg(0)); + return fmt::format(mips2c_format ? "lq_buffer(Mask::{}, c->vfs[{}].vf, vis[{}]++);" + : "lq_buffer(Mask::{}, vu.{}, vu.{}++);", + mask_to_string(*instr.mask), instr.dst->to_string(m_label_names), instr.src.at(0).to_string(m_label_names)); case VuInstrK::SQI: - return fmt::format("sq_buffer(Mask::{}, vu.{}, vu.{}++);", mask_to_string(*instr.mask), - instr.dst->to_string(m_label_names), - instr.src.at(0).to_string(m_label_names)); + ASSERT(!instr.src.at(0).is_int_reg(0)); + if (mips2c_format) { + return fmt::format("sq_buffer(Mask::{}, {}, vis[{}]++);", mask_to_string(*instr.mask), + vf_src(instr.dst->to_string(m_label_names), mips2c_format), + instr.src.at(0).to_string(m_label_names)); + } else { + return fmt::format("sq_buffer(Mask::{}, vu.{}, vu.{}++);", mask_to_string(*instr.mask), + instr.dst->to_string(m_label_names), + instr.src.at(0).to_string(m_label_names)); + } + case VuInstrK::SQ: if (instr.src.at(1).is_int_reg(0)) { return fmt::format("sq_buffer(Mask::{}, vu.{}, {});", mask_to_string(*instr.mask), instr.dst->to_string(m_label_names), instr.src.at(0).to_string(m_label_names)); } else if (instr.src.at(0).value() == 0) { - return fmt::format("sq_buffer(Mask::{}, vu.{}, vu.{});", mask_to_string(*instr.mask), - instr.dst->to_string(m_label_names), + return fmt::format(mips2c_format ? "sq_buffer(Mask::{}, c->vf_src({}).vf, vis[{}]);" + : "sq_buffer(Mask::{}, vu.{}, vu.{});", + mask_to_string(*instr.mask), instr.dst->to_string(m_label_names), instr.src.at(1).to_string(m_label_names)); } else { - return fmt::format("sq_buffer(Mask::{}, vu.{}, vu.{} + {});", mask_to_string(*instr.mask), - instr.dst->to_string(m_label_names), + return fmt::format(mips2c_format ? "sq_buffer(Mask::{}, c->vf_src({}).vf, vis[{}] + {});" + : "sq_buffer(Mask::{}, vu.{}, vu.{} + {});", + mask_to_string(*instr.mask), instr.dst->to_string(m_label_names), instr.src.at(1).to_string(m_label_names), instr.src.at(0).to_string(m_label_names)); } @@ -650,13 +689,28 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const { } case VuInstrK::IADDIU: + ASSERT(!instr.dst->is_int_reg(0)); if (instr.src.at(0).is_int_reg(0)) { - return fmt::format("vu.{} = 0x{:x}; /* {} */\n", instr.dst->to_string(m_label_names), - (u16)instr.src.at(1).value(), instr.src.at(1).value()); + if (mips2c_format) { + return fmt::format("vis[{}] = 0x{:x}; /* {} */", instr.dst->to_string(m_label_names), + (u16)instr.src.at(1).value(), instr.src.at(1).value()); + } else { + return fmt::format("vu.{} = 0x{:x}; /* {} */", instr.dst->to_string(m_label_names), + (u16)instr.src.at(1).value(), instr.src.at(1).value()); + } + } else { - return fmt::format("vu.{} = vu.{} + 0x{:x}; /* {} */", instr.dst->to_string(m_label_names), - instr.src.at(0).to_string(m_label_names), (u16)instr.src.at(1).value(), - instr.src.at(1).value()); + if (mips2c_format) { + return fmt::format("vis[{}] = vis[{}] + 0x{:x}; /* {} */", + instr.dst->to_string(m_label_names), + instr.src.at(0).to_string(m_label_names), (u16)instr.src.at(1).value(), + instr.src.at(1).value()); + } else { + return fmt::format("vu.{} = vu.{} + 0x{:x}; /* {} */", + instr.dst->to_string(m_label_names), + instr.src.at(0).to_string(m_label_names), (u16)instr.src.at(1).value(), + instr.src.at(1).value()); + } } case VuInstrK::ISW: @@ -696,7 +750,7 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const { case VuInstrK::ISUBIU: if (instr.src.at(0).is_int_reg(0)) { - return fmt::format("vu.{} = -{};\n", instr.dst->to_string(m_label_names), + return fmt::format("vu.{} = -{};", instr.dst->to_string(m_label_names), instr.src.at(1).value()); } else { return fmt::format("vu.{} = vu.{} - 0x{:x}; /* {} */", instr.dst->to_string(m_label_names), @@ -705,9 +759,10 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const { } case VuInstrK::MTIR: - return fmt::format("vu.{} = vu.{}.{}_as_u16();", instr.dst->to_string(m_label_names), - instr.src.at(0).to_string(m_label_names), - bc_to_part(*instr.first_src_field)); + return fmt::format( + mips2c_format ? "vis[{}] = c->vf_src({}).vf.{}_as_u16();" : "vu.{} = vu.{}.{}_as_u16();", + instr.dst->to_string(m_label_names), instr.src.at(0).to_string(m_label_names), + bc_to_part(*instr.first_src_field)); case VuInstrK::MFIR: return fmt::format("vu.{}.mfir(Mask::{}, vu.{});", instr.dst->to_string(m_label_names), @@ -718,28 +773,41 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const { case VuInstrK::IBGTZ: return fmt::format("bc = ((s16)vu.{}) > 0;", instr.src.at(0).to_string(m_label_names)); - + case VuInstrK::IBLTZ: + return fmt::format("bc = ((s16)vu.{}) < 0;", instr.src.at(0).to_string(m_label_names)); + case VuInstrK::IBLEZ: + return fmt::format("bc = ((s16)vu.{}) <= 0;", instr.src.at(0).to_string(m_label_names)); case VuInstrK::IBGEZ: return fmt::format("bc = ((s16)vu.{}) >= 0;", instr.src.at(0).to_string(m_label_names)); case VuInstrK::IBEQ: + ASSERT(!instr.src.at(1).is_int_reg(0)); if (instr.src.at(0).is_int_reg(0)) { - return fmt::format("bc = (vu.{} == 0);", instr.src.at(1).to_string(m_label_names)); + return fmt::format("bc = ({} == 0);", + vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format)); } else { - return fmt::format("bc = (vu.{} == vu.{});", instr.src.at(0).to_string(m_label_names), - instr.src.at(1).to_string(m_label_names)); + return fmt::format("bc = ({} == {});", + vi_src(instr.src.at(0).to_string(m_label_names), mips2c_format), + vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format)); } case VuInstrK::IBNE: + ASSERT(!instr.src.at(1).is_int_reg(0)); if (instr.src.at(0).is_int_reg(0)) { - return fmt::format("bc = (vu.{} != 0);", instr.src.at(1).to_string(m_label_names)); + return fmt::format("bc = ({} != 0);", + vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format)); } else { - return fmt::format("bc = (vu.{} != vu.{});", instr.src.at(0).to_string(m_label_names), - instr.src.at(1).to_string(m_label_names)); + return fmt::format("bc = ({} != {});", + vi_src(instr.src.at(0).to_string(m_label_names), mips2c_format), + vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format)); } case VuInstrK::IADD: - return fmt::format("vu.{} = vu.{} + vu.{};", instr.dst->to_string(m_label_names), + ASSERT(!instr.src.at(1).is_int_reg(0)); + ASSERT(!instr.src.at(0).is_int_reg(0)); + ASSERT(!instr.dst->is_int_reg(0)); + return fmt::format(mips2c_format ? "vis[{}] = vis[{}] + vis[{}];" : "vu.{} = vu.{} + vu.{};", + instr.dst->to_string(m_label_names), instr.src.at(0).to_string(m_label_names), instr.src.at(1).to_string(m_label_names)); case VuInstrK::ISUB: @@ -747,13 +815,25 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const { instr.src.at(0).to_string(m_label_names), instr.src.at(1).to_string(m_label_names)); case VuInstrK::IAND: - return fmt::format("vu.{} = vu.{} & vu.{};", instr.dst->to_string(m_label_names), - instr.src.at(0).to_string(m_label_names), - instr.src.at(1).to_string(m_label_names)); + ASSERT(!instr.src.at(1).is_int_reg(0)); + ASSERT(!instr.src.at(0).is_int_reg(0)); + ASSERT(!instr.dst->is_int_reg(0)); + return fmt::format("{} = {} & {};", + vi_src(instr.dst->to_string(m_label_names), mips2c_format), + vi_src(instr.src.at(0).to_string(m_label_names), mips2c_format), + vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format)); case VuInstrK::IOR: if (instr.src.at(1).is_int_reg(0)) { - return fmt::format("vu.{} = vu.{};", instr.dst->to_string(m_label_names), - instr.src.at(0).to_string(m_label_names)); + ASSERT(!instr.dst->is_int_reg(0)); + ASSERT(!instr.src.at(0).is_int_reg(0)); + if (mips2c_format) { + return fmt::format("vis[{}] = vis[{}];", instr.dst->to_string(m_label_names), + instr.src.at(0).to_string(m_label_names)); + } else { + return fmt::format("vu.{} = vu.{};", instr.dst->to_string(m_label_names), + instr.src.at(0).to_string(m_label_names)); + } + } else { goto unknown; } @@ -763,80 +843,133 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const { mask_to_string(*instr.mask)); case VuInstrK::MULq: - return fmt::format("vu.{}.mul(Mask::{}, vu.{}, vu.Q); /* TODO mulq */", + return fmt::format(mips2c_format ? "c->vfs[{}].vf.mul(Mask::{}, c->vf_src({}).vf, c->Q);" + : "vu.{}.mul(Mask::{}, vu.{}, vu.Q);", + instr.dst->to_string(m_label_names), mask_to_string(*instr.mask), + instr.src.at(0).to_string(m_label_names)); + case VuInstrK::MULi: + return fmt::format(mips2c_format ? "c->vfs[{}].vf.mul(Mask::{}, c->vf_src({}).vf, c->I);" + : "vu.{}.mul(Mask::{}, vu.{}, vu.I);", instr.dst->to_string(m_label_names), mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names)); case VuInstrK::DIV: return fmt::format( - "vu.Q = vu.{}.{}() / vu.{}.{}();\n", instr.src.at(0).to_string(m_label_names), + "vu.Q = vu.{}.{}() / vu.{}.{}();", instr.src.at(0).to_string(m_label_names), bc_to_part(*instr.first_src_field), instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.second_src_field)); case VuInstrK::ERLENG: return fmt::format("vu.P = erleng(Mask::{}, vu.{}); /* TODO erleng */", mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names)); + case VuInstrK::RSQRT: + return fmt::format( + "c->Q = c->vf_src({}).vf.{}() / std::sqrt(c->vf_src({}).vf.{}());", + instr.src.at(0).to_string(m_label_names), bc_to_part(*instr.first_src_field), + instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.second_src_field)); case VuInstrK::MR32: case VuInstrK::MOVE: case VuInstrK::ITOF0: + case VuInstrK::ITOF12: case VuInstrK::ITOF15: case VuInstrK::FTOI0: case VuInstrK::FTOI4: - return fmt::format("vu.{}.{}(Mask::{}, vu.{});", instr.dst->to_string(m_label_names), + case VuInstrK::FTOI12: + return fmt::format("{}.{}(Mask::{}, {});", + vf_dst(instr.dst->to_string(m_label_names), mips2c_format), info(instr.kind).name, mask_to_string(*instr.mask), - instr.src.at(0).to_string(m_label_names)); + vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format)); + + case VuInstrK::CLIP: + return fmt::format("ASSERT(false); cf = clip({}, {}.w(), cf);", + vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format), + vf_src(instr.src.at(1).to_string(m_label_names), mips2c_format)); + case VuInstrK::FCAND: + return fmt::format("ASSERT(false); vu.vi01 = cf & 0x{:x};\n", instr.src.at(0).value()); case VuInstrK::ADDbc: + case VuInstrK::SUBbc: case VuInstrK::MULbc: case VuInstrK::MINIbc: case VuInstrK::MAXbc: - return fmt::format("vu.{}.{}(Mask::{}, vu.{}, vu.{}.{}());", - instr.dst->to_string(m_label_names), info(instr.kind).name, - mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names), - instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.bc)); + return fmt::format("{}.{}(Mask::{}, {}, {}.{}());", + vf_dst(instr.dst->to_string(m_label_names), mips2c_format), + info(instr.kind).name, mask_to_string(*instr.mask), + vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format), + vf_src(instr.src.at(1).to_string(m_label_names), mips2c_format), + bc_to_part(*instr.bc)); case VuInstrK::FP_CONSTANT: - return fmt::format("vu.I = {};", float_to_string(instr.fp)); + if (mips2c_format) { + return fmt::format("c->I = {};", float_to_string(instr.fp)); + + } else { + return fmt::format("vu.I = {};", float_to_string(instr.fp)); + } case VuInstrK::MINIi: case VuInstrK::MAXi: - return fmt::format("vu.{}.{}(Mask::{}, vu.{}, vu.I);", instr.dst->to_string(m_label_names), + return fmt::format("{}.{}(Mask::{}, {}, {});", + vf_dst(instr.dst->to_string(m_label_names), mips2c_format), info(instr.kind).name, mask_to_string(*instr.mask), - instr.src.at(0).to_string(m_label_names)); + vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format), + mips2c_format ? "c->I" : "vu.I"); + case VuInstrK::SUB: + if (instr.dst.value().value() == instr.src.at(0).value() && + instr.src.at(0).value() == instr.src.at(1).value() && instr.mask.value() == 0b1111) { + return fmt::format("vu.{}.set_zero();", instr.src.at(0).to_string(m_label_names)); + } else { + return fmt::format("{}.{}(Mask::{}, {}, {});", + vf_dst(instr.dst->to_string(m_label_names), mips2c_format), + info(instr.kind).name, mask_to_string(*instr.mask), + vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format), + vf_src(instr.src.at(1).to_string(m_label_names), mips2c_format)); + } + break; case VuInstrK::MUL: case VuInstrK::ADD: case VuInstrK::MAX: case VuInstrK::MINI: - return fmt::format("vu.{}.{}(Mask::{}, vu.{}, vu.{});", instr.dst->to_string(m_label_names), + return fmt::format("{}.{}(Mask::{}, {}, {});", + vf_dst(instr.dst->to_string(m_label_names), mips2c_format), info(instr.kind).name, mask_to_string(*instr.mask), - instr.src.at(0).to_string(m_label_names), - instr.src.at(1).to_string(m_label_names)); + vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format), + vf_src(instr.src.at(1).to_string(m_label_names), mips2c_format)); case VuInstrK::ADDAbc: - return fmt::format("vu.acc.adda(Mask::{}, vu.{}, vu.{}.{}());", mask_to_string(*instr.mask), - instr.dst->to_string(m_label_names), + return fmt::format(mips2c_format + ? "c->acc.vf.adda(Mask::{}, c->vfs[{}].vf, c->vfs[{}].vf.{}());" + : "vu.acc.adda(Mask::{}, vu.{}, vu.{}.{}());", + mask_to_string(*instr.mask), instr.dst->to_string(m_label_names), instr.src.at(0).to_string(m_label_names), bc_to_part(*instr.bc)); case VuInstrK::MADDA: return fmt::format("vu.acc.madda(Mask::{}, vu.{}, vu.{});", mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names), instr.src.at(1).to_string(m_label_names)); case VuInstrK::MADDAbc: - return fmt::format("vu.acc.madda(Mask::{}, vu.{}, vu.{}.{}());", mask_to_string(*instr.mask), - instr.src.at(0).to_string(m_label_names), + return fmt::format(mips2c_format + ? "c->acc.vf.madda(Mask::{}, c->vfs[{}].vf, c->vfs[{}].vf.{}());" + : "vu.acc.madda(Mask::{}, vu.{}, vu.{}.{}());", + mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names), instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.bc)); case VuInstrK::MADDbc: - return fmt::format("vu.acc.madd(Mask::{}, vu.{}, vu.{}, vu.{}.{}());", - mask_to_string(*instr.mask), instr.dst->to_string(m_label_names), - instr.src.at(0).to_string(m_label_names), - instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.bc)); + return fmt::format( + mips2c_format + ? "c->acc.vf.madd(Mask::{}, c->vfs[{}].vf, c->vf_src({}).vf, c->vf_src({}).vf.{}());" + : "vu.acc.madd(Mask::{}, vu.{}, vu.{}, vu.{}.{}());", + mask_to_string(*instr.mask), instr.dst->to_string(m_label_names), + instr.src.at(0).to_string(m_label_names), instr.src.at(1).to_string(m_label_names), + bc_to_part(*instr.bc)); case VuInstrK::MULA: return fmt::format("vu.acc.mula(Mask::{}, vu.{}, vu.{});", mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names), instr.src.at(1).to_string(m_label_names)); case VuInstrK::MULAbc: - return fmt::format("vu.acc.mula(Mask::{}, vu.{}, vu.{}.{}());", mask_to_string(*instr.mask), - instr.src.at(0).to_string(m_label_names), + return fmt::format(mips2c_format + ? "c->acc.vf.mula(Mask::{}, c->vf_src({}).vf, c->vf_src({}).vf.{}());" + : "vu.acc.mula(Mask::{}, vu.{}, vu.{}.{}());", + mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names), instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.bc)); case VuInstrK::XGKICK: @@ -846,7 +979,7 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const { return fmt::format("vu.{} = xtop();", instr.src.at(0).to_string(m_label_names)); default: unk++; - return "???"; + return "ASSERT(false);"; //"???"; } unknown: @@ -1049,7 +1182,7 @@ std::string get_label_name(const VuInstructionPair& pair, ASSERT(false); } -std::string VuDisassembler::to_string_with_cpp(const VuProgram& prog) const { +std::string VuDisassembler::to_string_with_cpp(const VuProgram& prog, bool mips2c_format) const { std::string result; for (int i = 0; i < (int)prog.instructions().size(); i++) { auto lab = m_labels.find(i); @@ -1059,20 +1192,36 @@ std::string VuDisassembler::to_string_with_cpp(const VuProgram& prog) const { result += '\n'; } auto& pair = prog.instructions().at(i); - if (has_branch_delay(pair)) { - result += "// BRANCH!\n"; + if (has_branch_delay(pair) && pair.lower.kind != VuInstrK::JALR) { + result += " // BRANCH!\n"; // set bc - result += to_string_with_cpp(prog.instructions().at(i)); + result += to_string_with_cpp(prog.instructions().at(i), mips2c_format, i); result += "\n"; - result += to_string_with_cpp(prog.instructions().at(i + 1)); + result += to_string_with_cpp(prog.instructions().at(i + 1), mips2c_format, i + 1); result += "\n"; - result += fmt::format("if (bc) {{ goto {}; }}\n", get_label_name(pair, m_label_names)); + result += fmt::format(" if (bc) {{ goto {}; }}", get_label_name(pair, m_label_names)); result += "\n\n"; i++; } else { - result += to_string_with_cpp(prog.instructions().at(i)); + result += to_string_with_cpp(prog.instructions().at(i), mips2c_format, i); result += '\n'; } + + if (i > 0) { + const auto& prev = prog.instructions().at(i - 1); + bool has_ebit = false; + if (prev.lower.iemdt && (*prev.lower.iemdt & 0b100000)) { + has_ebit = true; + } + + if (prev.upper.iemdt && (*prev.upper.iemdt & 0b100000)) { + has_ebit = true; + } + + if (has_ebit) { + result += "return;\n\n"; + } + } } fmt::print("TOTAL unk: {}\n", unk); return result; @@ -1083,20 +1232,23 @@ bool is_nop(const VuInstruction& i) { return i.kind == VuInstrK::NOP || i.kind == VuInstrK::LOWER_NOP; } } // namespace -std::string VuDisassembler::to_string_with_cpp(const VuInstructionPair& pair) const { +std::string VuDisassembler::to_string_with_cpp(const VuInstructionPair& pair, + bool mips2c_format, + int idx) const { std::string result; - result += fmt::format(" // {:25s} | {:30s}\n", to_string(pair.lower), to_string(pair.upper)); + result += + fmt::format(" // {:25s} | {:30s} {}\n", to_string(pair.lower), to_string(pair.upper), idx); if (!is_nop(pair.lower) && !is_nop(pair.upper) && pair.lower.kind == VuInstrK::FP_CONSTANT) { - result += fmt::format(" {:25s}", to_cpp(pair.upper)); - result += fmt::format(" {:25s}", to_cpp(pair.lower)); + result += fmt::format(" {:25s}", to_cpp(pair.upper, mips2c_format)); + result += fmt::format(" {:25s}", to_cpp(pair.lower, mips2c_format)); } else { if (!is_nop(pair.upper)) { - result += fmt::format(" {:25s}", to_cpp(pair.upper)); + result += fmt::format(" {:25s}", to_cpp(pair.upper, mips2c_format)); } if (!is_nop(pair.lower)) { - result += fmt::format(" {:25s}", to_cpp(pair.lower)); + result += fmt::format(" {:25s}", to_cpp(pair.lower, mips2c_format)); } } diff --git a/decompiler/VuDisasm/VuDisassembler.h b/decompiler/VuDisasm/VuDisassembler.h index 6fd02e0170..6b1ffb8833 100644 --- a/decompiler/VuDisasm/VuDisassembler.h +++ b/decompiler/VuDisasm/VuDisassembler.h @@ -57,11 +57,11 @@ class VuDisassembler { VuDisassembler(VuKind kind); VuProgram disassemble(void* data, int size_bytes, bool debug_print = false); std::string to_string(const VuInstruction& instr) const; - std::string to_cpp(const VuInstruction& instr) const; + std::string to_cpp(const VuInstruction& instr, bool mips2c_format) const; std::string to_string(const VuInstructionPair& pair) const; - std::string to_string_with_cpp(const VuInstructionPair& pair) const; + std::string to_string_with_cpp(const VuInstructionPair& pair, bool mips2c_format, int idx) const; std::string to_string(const VuProgram& prog) const; - std::string to_string_with_cpp(const VuProgram& prog) const; + std::string to_string_with_cpp(const VuProgram& prog, bool mips2c_format) const; int add_label(int instr); void add_label_with_name(int instr, const std::string& name); diff --git a/decompiler/analysis/mips2c.cpp b/decompiler/analysis/mips2c.cpp index ad35ee381e..9d0cf18084 100644 --- a/decompiler/analysis/mips2c.cpp +++ b/decompiler/analysis/mips2c.cpp @@ -740,6 +740,18 @@ Mips2C_Line handle_vmadda_bc(const Instruction& i0, const std::string& instr_str instr_str}; } +Mips2C_Line handle_vmadda(const Instruction& i0, const std::string& instr_str) { + return {fmt::format("c->vmadda(DEST::{}, {}, {});", dest_to_char(i0.cop2_dest), + reg_to_name(i0.get_src(0)), reg_to_name(i0.get_src(1))), + instr_str}; +} + +Mips2C_Line handle_vadda_bc(const Instruction& i0, const std::string& instr_str) { + return {fmt::format("c->vadda_bc(DEST::{}, BC::{}, {}, {});", dest_to_char(i0.cop2_dest), + i0.cop2_bc_to_char(), reg_to_name(i0.get_src(0)), reg_to_name(i0.get_src(1))), + instr_str}; +} + Mips2C_Line handle_vmsuba_bc(const Instruction& i0, const std::string& instr_str) { return {fmt::format("c->vmsuba_bc(DEST::{}, BC::{}, {}, {});", dest_to_char(i0.cop2_dest), i0.cop2_bc_to_char(), reg_to_name(i0.get_src(0)), reg_to_name(i0.get_src(1))), @@ -869,9 +881,16 @@ Mips2C_Line handle_vopmsub(const Instruction& i0, const std::string& instr_strin instr_string}; } -Mips2C_Line handle_lui(const Instruction& i0, const std::string& instr_string) { - return {fmt::format("c->lui({}, {});", reg_to_name(i0.get_dst(0)), i0.get_src(0).get_imm()), - instr_string}; +Mips2C_Line handle_lui(const Instruction& i0, const std::string& instr_string, Mips2C_Output& op) { + if (i0.get_src(0).get_imm() == 0x7000) { + op.require_symbol("*fake-scratchpad-data*"); + return {fmt::format("get_fake_spad_addr({}, cache.fake_scratchpad_data, 0, c);", + reg_to_name(i0.get_dst(0))), + instr_string}; + } else { + return {fmt::format("c->lui({}, {});", reg_to_name(i0.get_dst(0)), i0.get_src(0).get_imm()), + instr_string}; + } } Mips2C_Line handle_clts(const Instruction& i0, const std::string& instr_string) { @@ -896,15 +915,35 @@ Mips2C_Line handle_pmfhl_lh(const Instruction& i0, const std::string& instr_stri return {fmt::format("c->pmfhl_lh({});", reg_to_name(i0.get_dst(0))), instr_string}; } +Mips2C_Line handle_ctc2(const Instruction& i0, const std::string& instr_string) { + return {fmt::format("{} = c->gpr_src({}).du16[0];", reg_to_name(i0.get_dst(0)), + reg_to_name(i0.get_src(0))), + instr_string}; +} + +Mips2C_Line handle_cfc2(const Instruction& i0, const std::string& instr_string) { + return {fmt::format("c->gprs[{}].du64[0] = {};", reg_to_name(i0.get_dst(0)), + reg_to_name(i0.get_src(0))), + instr_string}; +} + Mips2C_Line handle_normal_instr(Mips2C_Output& output, const Instruction& i0, const std::string& instr_str, int& unknown_count, const LinkedObjectFile* file) { switch (i0.kind) { + case InstructionKind::CTC2: + return handle_ctc2(i0, instr_str); + case InstructionKind::CFC2: + return handle_cfc2(i0, instr_str); case InstructionKind::LW: return handle_lw(output, i0, instr_str, file); case InstructionKind::LB: + case InstructionKind::LWL: + case InstructionKind::LWR: + case InstructionKind::LDR: + case InstructionKind::LDL: case InstructionKind::LBU: case InstructionKind::LWU: case InstructionKind::LQ: @@ -932,6 +971,8 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output, return handle_generic_op3_bc_mask(i0, instr_str, "vsub_bc"); case InstructionKind::VMUL_BC: return handle_generic_op3_bc_mask(i0, instr_str, "vmul_bc"); + case InstructionKind::VMADD: + return handle_generic_op3_mask(i0, instr_str, "vmadd"); case InstructionKind::VMUL: return handle_generic_op3_mask(i0, instr_str, "vmul"); case InstructionKind::VADD: @@ -978,6 +1019,7 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output, case InstructionKind::PSRAW: case InstructionKind::PSRAH: case InstructionKind::PSRLH: + case InstructionKind::PSLLW: return handle_generic_op2_u16(i0, instr_str); case InstructionKind::SLL: return handle_sll(i0, instr_str); @@ -988,6 +1030,7 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output, case InstructionKind::PEXTLB: case InstructionKind::MOVN: case InstructionKind::PEXTUW: + case InstructionKind::PEXTUH: case InstructionKind::PEXTLW: case InstructionKind::PCPYUD: case InstructionKind::PCPYLD: @@ -1008,7 +1051,12 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output, case InstructionKind::PMAXW: case InstructionKind::PMAXH: case InstructionKind::SUBU: + case InstructionKind::SLT: + case InstructionKind::SLTU: case InstructionKind::DSRAV: + case InstructionKind::DSLLV: + case InstructionKind::PAND: + case InstructionKind::PCEQB: return handle_generic_op3(i0, instr_str, {}); case InstructionKind::MULS: return handle_generic_op3(i0, instr_str, "muls"); @@ -1034,8 +1082,12 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output, return handle_vmula_bc(i0, instr_str); case InstructionKind::VMADDA_BC: return handle_vmadda_bc(i0, instr_str); + case InstructionKind::VADDA_BC: + return handle_vadda_bc(i0, instr_str); case InstructionKind::VMSUBA_BC: return handle_vmsuba_bc(i0, instr_str); + case InstructionKind::VMADDA: + return handle_vmadda(i0, instr_str); case InstructionKind::VMADD_BC: return handle_generic_op3_bc_mask(i0, instr_str, "vmadd_bc"); case InstructionKind::VMSUB_BC: @@ -1078,8 +1130,10 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output, return handle_generic_op2(i0, instr_str, "plzcw"); case InstructionKind::PCPYH: return handle_generic_op2(i0, instr_str, "pcpyh"); + case InstructionKind::PROT3W: + return handle_generic_op2(i0, instr_str, "prot3w"); case InstructionKind::LUI: - return handle_lui(i0, instr_str); + return handle_lui(i0, instr_str, output); case InstructionKind::CLTS: output.needs_cop1_bc = true; return handle_clts(i0, instr_str); @@ -1317,13 +1371,17 @@ void run_mips2c(Function* f) { // set the branch condition output.lines.push_back(handle_non_likely_branch_bc(instr, instr_str)); // then the delay slot - ASSERT(i + 1 < block.end_instr); + if (!(i + 1 < block.end_instr)) { + output.lines.emplace_back("DANGER jump to delay slot, this MUST be fixed manually!", + ""); + lg::warn("Delay slot weirdness in {}, block {}", f->name(), block_idx); + } i++; auto& delay_i = f->instructions.at(i); auto delay_i_str = delay_i.to_string(file->labels); output.lines.push_back( handle_normal_instr(output, delay_i, delay_i_str, unknown_count, file)); - ASSERT(i + 1 == block.end_instr); + // ASSERT(i + 1 == block.end_instr); // then the goto output.lines.emplace_back(fmt::format("if (bc) {{goto block_{};}}", block.succ_branch), "branch non-likely\n"); diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 413dc53019..a982351c28 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -6774,8 +6774,8 @@ ) (deftype generic-gif-tag (structure) - ((data uint32 4 :offset-assert 0) - (qword qword :inline :offset 0) + ((data uint32 4 :offset-assert 0 :score -1) + (qword qword :inline :offset 0 :score -1) (fan-prim uint32 :offset 0) (str-prim uint32 :offset 4) (regs uint32 :offset 8) @@ -6789,10 +6789,10 @@ (deftype ad-cmd (structure) ((word uint32 4 :offset-assert 0) (quad uint128 :offset 0) - (data uint64 :offset 0) + (data uint64 :offset 0 :score 1) (cmds uint64 :offset 8) - (cmd gs-reg :offset 8) - (x uint32 :offset 0) + (cmd gs-reg :offset 8 :score 1) + (x uint32 :offset 0 ) (y uint32 :offset 4) (z uint32 :offset 8) (w uint32 :offset 12) @@ -8634,7 +8634,7 @@ (next-chain uint32 :offset-assert 276) (buf-index uint32 :offset-assert 280) (fragment-count uint32 :offset-assert 284) - (write-limit int32 :offset-assert 288) + (write-limit pointer :offset-assert 288) (indexed-input-base generic-merc-input :offset-assert 292) (other-input-base generic-merc-input :offset-assert 296) (indexed-output-base generic-merc-output :offset-assert 300) @@ -9813,8 +9813,8 @@ (deftype merc-globals (structure) ((first uint32 :offset-assert 0) - (next uint32 :offset-assert 4) - (sink basic :offset-assert 8) ;; dma sink + (next (pointer uint32) :offset-assert 4) + (sink generic-dma-foreground-sink :offset-assert 8) ;; dma sink ) :allow-misaligned :method-count-assert 9 @@ -13651,9 +13651,9 @@ ) (deftype foreground-area (structure) - ((joint-work joint-work :inline :offset-assert 0) + ((joint-work joint-work :inline :offset-assert 0 :score 1999999999) (generic-work generic-work :inline :offset 0) - (bone-mem bone-memory :score 1999999999 :inline :offset 0) + (bone-mem bone-memory :inline :offset 0) (shadow-work shadow-work :inline :offset 0) ) :method-count-assert 9 @@ -16643,7 +16643,7 @@ (define-extern bones-debug (function none)) (define-extern dump-bone-mem (function none)) (define-extern draw-bones-shadow (function draw-control object object pointer)) -(define-extern draw-bones-generic-merc (function draw-control object object int pointer)) +(define-extern draw-bones-generic-merc (function draw-control pointer pointer int pointer)) (define-extern draw-bones-merc (function draw-control object object int int pointer)) (define-extern draw-bones-check-longest-edge (function draw-control float none)) (define-extern draw-bones-check-longest-edge-asm (function draw-control float symbol)) @@ -16716,10 +16716,10 @@ ;; - Functions -(define-extern generic-work-init function) +(define-extern generic-work-init (function generic-dma-foreground-sink none)) (define-extern generic-upload-vu0 function) -(define-extern upload-vu0-program function) -(define-extern generic-initialize-without-sink function) +(define-extern upload-vu0-program (function vu-function pointer none)) +(define-extern generic-initialize-without-sink (function matrix vu-lights none)) (define-extern generic-initialize function) (define-extern generic-wrapup function) (define-extern generic-dma-from-spr function) @@ -16765,6 +16765,7 @@ (init-data uint8 :offset-assert 1) (init-addr uint16 :offset-assert 2) ) + :pack-me :method-count-assert 9 :size-assert #x4 :flag-assert #x900000004 @@ -16772,15 +16773,15 @@ ;; - Functions -(define-extern generic-merc-init-asm function) +(define-extern generic-merc-init-asm (function none)) (define-extern mercneric-matrix-asm function) (define-extern mercneric-shader-asm function) (define-extern mercneric-bittable-asm function) (define-extern mercneric-convert function) -(define-extern high-speed-reject function) -(define-extern generic-merc-execute-asm function) -(define-extern generic-merc-add-to-cue (function basic none)) -(define-extern generic-merc-execute-all (function none)) +(define-extern high-speed-reject (function none)) +(define-extern generic-merc-execute-asm (function none)) +(define-extern generic-merc-add-to-cue (function generic-dma-foreground-sink none)) +(define-extern generic-merc-execute-all (function dma-buffer none)) ;; - Unknowns diff --git a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc index a767fad398..5949777e40 100644 --- a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc @@ -153,7 +153,6 @@ "upload-vu0-program", // generic-merc - "generic-merc-execute-all", "generic-merc-execute-asm", // CFG "high-speed-reject", "mercneric-convert", @@ -488,7 +487,8 @@ "(anon-function 2 snow-ball)": [22], "draw-bones-merc": [1, 3, 5, 7, 8, 10, 11, 12, 13], "(anon-function 48 lavatube-energy)": [13], - "generic-tie-execute": [4, 9] + "generic-tie-execute": [4, 9], + "generic-merc-execute-all":[3,7, 12] }, // Sometimes the game might use format strings that are fetched dynamically, @@ -571,7 +571,27 @@ "draw-bones-merc", "draw-bones-check-longest-edge-asm", "setup-blerc-chains-for-one-fragment", - "blerc-execute" + "blerc-execute", + + // generic merc + //"generic-merc-execute-all", + "generic-merc-execute-asm", + "high-speed-reject", + "mercneric-convert", + "mercneric-bittable-asm", + "mercneric-shader-asm", + "mercneric-matrix-asm", + "generic-merc-init-asm", + "generic-prepare-dma-double", + "generic-light-proc", + "generic-envmap-proc", + "draw-bones-generic-merc", + "generic-prepare-dma-single", + + "ripple-matrix-scale", + "ripple-apply-wave-table", + "ripple-create-wave-table", + "ripple-execute-init" ], "mips2c_jump_table_functions": { diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index e6bd3bd900..b96b810bc0 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -2111,6 +2111,10 @@ ["L6", "shadow-vu1-gifbuf-template"] ], + "generic-vu0": [ + ["L1", "vu-function"] + ], + // please do not add things after this entry! git is dumb. "object-file-that-doesnt-actually-exist-and-i-just-put-this-here-to-prevent-merge-conflicts-with-this-file": [] } diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index 3b82b6bbf5..aca78f6120 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -7338,5 +7338,45 @@ [24, "a0", "dma-packet"] ], + "draw-bones-generic-merc":[ + [11, "v1", "generic-merc-ctrl"], + [198, "v1", "generic-merc-ctrl"], + [274, "a0", "generic-merc-ctrl"], + [277, "a0", "pointer"], + [278, "a0", "merc-fragment-control"], + [[270, 274], "a0", "dma-packet"], + [[258, 262], "a0", "dma-packet"], + [280, "a0", "pointer"], + [[303, 306], "gp", "dma-packet"], + [281, "v1", "merc-fragment"] + ], + + "generic-merc-execute-all": [ + [[165,170], "v1", "terrain-context"], + [92, "a0", "terrain-context"], + [96, "v1", "terrain-context"], + [100, "v1", "terrain-context"], + [103, "a0", "generic-envmap-saves"], + [105, "v1", "(pointer int32)"], + [47, "v1", "terrain-context"], + [49, "v1", "terrain-context"], + [51, "v1", "terrain-context"], + [66, "a0", "terrain-context"], + [[114, 117], "v1", "dma-packet"] + ], + + "generic-initialize-without-sink": [ + [8, "a0", "terrain-context"], + [32, "a0", "terrain-context"] + ], + + "generic-work-init":[ + [10, "a0", "terrain-context"], + [13, "a0", "terrain-context"], + [16, "a0", "terrain-context"], + [18, "a0", "terrain-context"], + [[21, 42], "gp", "adgif-shader"] + ], + "placeholder-do-not-add-below": [] } diff --git a/decompiler/level_extractor/extract_tfrag.cpp b/decompiler/level_extractor/extract_tfrag.cpp index 2273eb8301..bec1c02b14 100644 --- a/decompiler/level_extractor/extract_tfrag.cpp +++ b/decompiler/level_extractor/extract_tfrag.cpp @@ -2064,7 +2064,6 @@ void make_tfrag3_data(std::map>& draws, // ASSERT((vert.rgba >> 2) < 1024); spider cave has 2048? ASSERT((vert.rgba & 3) == 0); - size_t vert_idx = vertices.size(); vertices.push_back(vtx); } tdraw.runs.push_back(run); diff --git a/decompiler/level_extractor/extract_tie.cpp b/decompiler/level_extractor/extract_tie.cpp index 71e8a36fd3..58d47e4a78 100644 --- a/decompiler/level_extractor/extract_tie.cpp +++ b/decompiler/level_extractor/extract_tie.cpp @@ -363,9 +363,6 @@ std::array extract_tie_matrix(const u16* data) { return result; } -// geometry we use (todo, should really look at this) -constexpr int GEOM_IDX = 0; // todo 0 or 1?? - /*! * Confirm that the initial value of all wind vectors is 0. * If this is true, we don't have to actually save them to the fr3 file, we can just create @@ -2229,7 +2226,6 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree, color_index += ifrag.color_index_offset_in_big_palette; } - size_t vert_idx = tree.packed_vertices.color_indices.size(); tree.packed_vertices.color_indices.push_back(color_index); // draw_to_add_to->vertex_index_stream.push_back(vert_idx); } diff --git a/decompiler/util/data_decompile.cpp b/decompiler/util/data_decompile.cpp index 94812ba011..1c1ce1da43 100644 --- a/decompiler/util/data_decompile.cpp +++ b/decompiler/util/data_decompile.cpp @@ -74,6 +74,11 @@ goos::Object decompile_at_label_with_hint(const LabelInfo& hint, // TODO - having this logic here isn't great. auto stride = align(field_type_info->get_size_in_memory(), field_type_info->get_inline_array_stride_alignment()); + fmt::print("decompiler {} stride {} {} = {}\n", field_type_info->get_name(), + field_type_info->get_size_in_memory(), + field_type_info->get_inline_array_stride_alignment(), + align(field_type_info->get_size_in_memory(), + field_type_info->get_inline_array_stride_alignment())); if (dynamic_cast(field_type_info)) { throw std::runtime_error("Plan basic arrays not supported yet"); @@ -330,7 +335,7 @@ goos::Object decomp_ref_to_integer_array_guess_size( int field_location, const TypeSystem& ts, const std::vector>& all_words, - const LinkedObjectFile* file, + const LinkedObjectFile* /*file*/, const TypeSpec& array_elt_type, int stride) { // fmt::print("Decomp decomp_ref_to_inline_array_guess_size {}\n", array_elt_type.print()); diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index a46ddb76b0..039af887dd 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -45,8 +45,11 @@ set(RUNTIME_SOURCE mips2c/functions/collide_mesh.cpp mips2c/functions/collide_probe.cpp mips2c/functions/draw_string.cpp + mips2c/functions/generic_effect.cpp + mips2c/functions/generic_merc.cpp mips2c/functions/joint.cpp mips2c/functions/merc_blend_shape.cpp + mips2c/functions/ripple.cpp mips2c/functions/sky_tng.cpp mips2c/functions/sparticle.cpp mips2c/functions/sparticle_launcher.cpp @@ -75,6 +78,8 @@ set(RUNTIME_SOURCE graphics/opengl_renderer/debug_gui.cpp graphics/opengl_renderer/DirectRenderer.cpp graphics/opengl_renderer/EyeRenderer.cpp + graphics/opengl_renderer/GenericProgram.cpp + graphics/opengl_renderer/GenericRenderer.cpp graphics/opengl_renderer/dma_helpers.cpp graphics/opengl_renderer/Loader.cpp graphics/opengl_renderer/MercProgram.cpp diff --git a/game/common/vu.h b/game/common/vu.h new file mode 100644 index 0000000000..fa89e4a8ed --- /dev/null +++ b/game/common/vu.h @@ -0,0 +1,494 @@ +#pragma once +#include "immintrin.h" +#include "common/math/Vector.h" + +enum class Mask { + NONE = 0, + x = 1, + y = 2, + xy = 3, + z = 4, + xz = 5, + yz = 6, + xyz = 7, + w = 8, + xw = 9, + yw = 10, + xyw = 11, + zw = 12, + xzw = 13, + yzw = 14, + xyzw = 15 +}; + +#ifdef __linux__ +#define REALLY_INLINE __attribute__((always_inline)) +#else +#define REALLY_INLINE __forceinline +#endif + +// note: must be aligned. +static inline REALLY_INLINE void copy_vector(void* dest, const void* src) { + __m128 val = _mm_load_ps((const float*)src); + _mm_store_ps((float*)dest, val); +} + +inline float vu_max(float a, float b) { + return std::max(b, a); + // s32 ai, bi; + // memcpy(&ai, &a, 4); + // memcpy(&bi, &b, 4); + // bool flip = ai < 0 && bi < 0; + // if (ai > bi) { + // return flip ? b : a; + // } else { + // return flip ? a : b; + // } +} + +inline float vu_min(float a, float b) { + s32 ai, bi; + memcpy(&ai, &a, 4); + memcpy(&bi, &b, 4); + bool flip = ai < 0 && bi < 0; + if (ai > bi) { + return flip ? a : b; + } else { + return flip ? b : a; + } +} + +struct alignas(16) Vf { + REALLY_INLINE __m128 load() const { return _mm_load_ps(data); } + + REALLY_INLINE void move_xyzw(const Vf& src) { copy_vector(data, src.data); } + + float data[4]; + float& x() { return data[0]; } + float& y() { return data[1]; } + float& z() { return data[2]; } + float& w() { return data[3]; } + + const float& x() const { return data[0]; } + const float& y() const { return data[1]; } + const float& z() const { return data[2]; } + const float& w() const { return data[3]; } + + std::string print() const { return fmt::format("{} {} {} {}", x(), y(), z(), w()); } + + std::string print_hex() const { + return fmt::format("0x{:x} 0x{:x} 0x{:x} 0x{:x}", x_as_u32(), y_as_u32(), z_as_u32(), + w_as_u32()); + } + + void set_zero() { + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + } + + u16 x_as_u16() const { + u16 result; + memcpy(&result, &data[0], 2); + return result; + } + + u16 y_as_u16() const { + u16 result; + memcpy(&result, &data[1], 2); + return result; + } + + u16 z_as_u16() const { + u16 result; + memcpy(&result, &data[2], 2); + return result; + } + + u16 w_as_u16() const { + u16 result; + memcpy(&result, &data[3], 2); + return result; + } + + u32 x_as_u32() const { + u32 result; + memcpy(&result, &data[0], 4); + return result; + } + + u32 y_as_u32() const { + u32 result; + memcpy(&result, &data[1], 4); + return result; + } + + u32 z_as_u32() const { + u32 result; + memcpy(&result, &data[2], 4); + return result; + } + + u32 w_as_u32() const { + u32 result; + memcpy(&result, &data[3], 4); + return result; + } + + Vf() = default; + Vf(const math::Vector4f& vec) { memcpy(data, vec.data(), 16); } + Vf(float a, float b, float c, float d) { + data[0] = a; + data[1] = b; + data[2] = c; + data[3] = d; + } + + std::string str_float() const { return fmt::format("{} {} {} {}", x(), y(), z(), w()); } + + float& operator[](int i) { return data[i]; } + float operator[](int i) const { return data[i]; } + + void mr32(Mask mask, const Vf& other) { + float temp[4]; + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + temp[i] = other[(i + 1) % 4]; + } + } + + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = temp[i]; + } + } + } + + REALLY_INLINE void mr32_z(const Vf& other) { data[2] = other.data[3]; } + + void mfir(Mask mask, s16 in) { + s32 sext = in; + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + memcpy(data + i, &sext, 4); + } + } + } + + void maxi(Mask mask, const Vf& other, float I) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = vu_max(other[i], I); + } + } + } + + void max(Mask mask, const Vf& other, float I) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = vu_max(other[i], I); + } + } + } + + void max(Mask mask, const Vf& other, const Vf& b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = vu_max(other[i], b[i]); + } + } + } + + REALLY_INLINE void max_xyzw(const Vf& a, const Vf& b) { + _mm_store_ps(data, _mm_max_ps(_mm_load_ps(a.data), _mm_load_ps(b.data))); + } + + REALLY_INLINE void max_xyzw(const Vf& a, float b) { + _mm_store_ps(data, _mm_max_ps(_mm_load_ps(a.data), _mm_set1_ps(b))); + } + + REALLY_INLINE void mini_xyzw(const Vf& a, const Vf& b) { + _mm_store_ps(data, _mm_min_ps(_mm_load_ps(a.data), _mm_load_ps(b.data))); + } + + REALLY_INLINE void mini_xyzw(const Vf& a, float b) { + _mm_store_ps(data, _mm_min_ps(_mm_load_ps(a.data), _mm_set1_ps(b))); + } + + void minii(Mask mask, const Vf& other, float I) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = vu_min(other[i], I); + } + } + } + + void mini(Mask mask, const Vf& other, float I) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = vu_min(other[i], I); + } + } + } + + void fill(float f) { + for (auto& x : data) { + x = f; + } + } + + void move(Mask mask, const Vf& other) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = other[i]; + } + } + } + + void mfp(Mask mask, float other) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = other; + } + } + } + + void add(Mask mask, const Vf& a, const Vf& b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = a[i] + b[i]; + } + } + } + + REALLY_INLINE void add_xyzw(const Vf& a, const Vf& b) { + _mm_store_ps(data, _mm_add_ps(_mm_load_ps(a.data), _mm_load_ps(b.data))); + } + + void add(Mask mask, const Vf& a, float b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = a[i] + b; + } + } + } + + void sub(Mask mask, const Vf& a, float b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = a[i] - b; + } + } + } + + void sub(Mask mask, const Vf& a, const Vf& b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = a[i] - b[i]; + } + } + } + + REALLY_INLINE void mul_xyzw(const Vf& a, const Vf& b) { + _mm_store_ps(data, _mm_mul_ps(_mm_load_ps(a.data), _mm_load_ps(b.data))); + } + + REALLY_INLINE void mul_xyzw(const Vf& a, float b) { + _mm_store_ps(data, _mm_mul_ps(_mm_load_ps(a.data), _mm_set1_ps(b))); + } + + void mul(Mask mask, const Vf& a, const Vf& b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = a[i] * b[i]; + } + } + } + + void mul(Mask mask, const Vf& a, float b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = a[i] * b; + } + } + } + + void itof0(Mask mask, const Vf& a) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + s32 val; + memcpy(&val, &a.data[i], 4); + data[i] = val; + } + } + } + + void itof12(Mask mask, const Vf& a) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + s32 val; + memcpy(&val, &a.data[i], 4); + data[i] = ((float)val) * (1.f / 4096.f); + } + } + } + + void itof15(Mask mask, const Vf& a) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + s32 val; + memcpy(&val, &a.data[i], 4); + data[i] = ((float)val) * (1.f / 32768.f); + } + } + } + + void ftoi4(Mask mask, const Vf& a) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + s32 val = a.data[i] * 16.f; + memcpy(&data[i], &val, 4); + } + } + } + + void ftoi12(Mask mask, const Vf& a) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + // if (std::isnan(a.data[i])) { + // ASSERT(false); + // } + s32 val = a.data[i] * 4096.f; + memcpy(&data[i], &val, 4); + } + } + } + + void ftoi0(Mask mask, const Vf& a) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + s32 val = a.data[i]; + memcpy(&data[i], &val, 4); + } + } + } +}; + +struct alignas(16) Accumulator { + float data[4]; + + void adda(Mask mask, const Vf& a, float b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = a[i] + b; + } + } + } + + void madda(Mask mask, const Vf& a, const Vf& b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] += a[i] * b[i]; + } + } + } + + void madda(Mask mask, const Vf& a, float b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] += a[i] * b; + } + } + } + + REALLY_INLINE void madda_xyzw(const Vf& _a, float _b) { + auto b = _mm_set1_ps(_b); + auto a = _mm_load_ps(_a.data); + auto acc = _mm_load_ps(data); + _mm_store_ps(data, _mm_add_ps(_mm_mul_ps(a, b), acc)); + } + + REALLY_INLINE void madda_xyzw(const Vf& _a, const Vf& _b) { + auto b = _mm_load_ps(_b.data); + auto a = _mm_load_ps(_a.data); + auto acc = _mm_load_ps(data); + _mm_store_ps(data, _mm_add_ps(_mm_mul_ps(a, b), acc)); + } + + void madd(Mask mask, Vf& dest, const Vf& a, const Vf& b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + dest[i] = data[i] + a[i] * b[i]; + } + } + } + + REALLY_INLINE void madd_xyzw(Vf& dest, const Vf& _a, float _b) { + auto b = _mm_set1_ps(_b); + auto a = _mm_load_ps(_a.data); + auto acc = _mm_load_ps(data); + _mm_store_ps(dest.data, _mm_add_ps(_mm_mul_ps(a, b), acc)); + } + + REALLY_INLINE void madd_xyz(Vf& dest, const Vf& _a, float _b) { + auto b = _mm_set1_ps(_b); + auto a = _mm_load_ps(_a.data); + auto acc = _mm_load_ps(data); + auto prod = _mm_add_ps(_mm_mul_ps(a, b), acc); + prod = _mm_blend_ps(prod, _mm_load_ps(dest.data), 0b1000); + _mm_store_ps(dest.data, prod); + } + + void madd(Mask mask, Vf& dest, const Vf& a, float b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + dest[i] = data[i] + a[i] * b; + } + } + } + + u16 madd_flag(Mask mask, Vf& dest, const Vf& a, float b) { + u16 result = 0; + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + dest[i] = data[i] + a[i] * b; + if (dest[i] < 0) { + result |= (1 << (3 - i)) << 4; + } + if (dest[i] == 0) { + result |= (1 << (3 - i)); + } + } + } + return result; + } + + void mula(Mask mask, const Vf& a, const Vf& b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = a[i] * b[i]; + } + } + } + + void mula(Mask mask, const Vf& a, float b) { + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + data[i] = a[i] * b; + } + } + } + + REALLY_INLINE void mula_xyzw(const Vf& _a, float _b) { + auto b = _mm_set1_ps(_b); + auto a = _mm_load_ps(_a.data); + _mm_store_ps(data, _mm_mul_ps(a, b)); + } + + REALLY_INLINE void mula_xyzw(const Vf& _a, const Vf& _b) { + auto b = _mm_load_ps(_b.data); + auto a = _mm_load_ps(_a.data); + _mm_store_ps(data, _mm_mul_ps(a, b)); + } +}; diff --git a/game/discord.cpp b/game/discord.cpp index 908f12f7ef..99d3a39e34 100644 --- a/game/discord.cpp +++ b/game/discord.cpp @@ -45,7 +45,7 @@ void set_discord_rpc(int state) { } // get full level name from symbol name ("village1" -> "Sandover Village") -const char* jak1_get_full_level_name(char* level_name) { +const char* jak1_get_full_level_name(const char* level_name) { // ignore sublevels if (!strcmp(level_name, "jungleb")) { level_name = "jungle"; @@ -75,6 +75,6 @@ void handleDiscordError(int errcode, const char* message) { printf("\nDiscord: error (%d: %s)\n", errcode, message); } -void handleDiscordJoin(const char* secret) {} -void handleDiscordJoinRequest(const DiscordUser* request) {} -void handleDiscordSpectate(const char* secret) {} +void handleDiscordJoin(const char* /*secret*/) {} +void handleDiscordJoinRequest(const DiscordUser* /*request*/) {} +void handleDiscordSpectate(const char* /*secret*/) {} diff --git a/game/discord.h b/game/discord.h index 4b7b125d12..7d5eed58ac 100644 --- a/game/discord.h +++ b/game/discord.h @@ -4,7 +4,7 @@ void init_discord_rpc(); void set_discord_rpc(int state); -const char* jak1_get_full_level_name(char* level_name); +const char* jak1_get_full_level_name(const char* level_name); void handleDiscordReady(const DiscordUser* user); void handleDiscordDisconnected(int errcode, const char* message); diff --git a/game/graphics/opengl_renderer/BucketRenderer.h b/game/graphics/opengl_renderer/BucketRenderer.h index efecb65055..e34605377f 100644 --- a/game/graphics/opengl_renderer/BucketRenderer.h +++ b/game/graphics/opengl_renderer/BucketRenderer.h @@ -19,12 +19,15 @@ enum class BucketId { TFRAG_LEVEL0 = 6, TIE_LEVEL0 = 9, MERC_TFRAG_TEX_LEVEL0 = 10, + GMERC_TFRAG_TEX_LEVEL0 = 11, TFRAG_TEX_LEVEL1 = 12, TFRAG_LEVEL1 = 13, TIE_LEVEL1 = 16, MERC_TFRAG_TEX_LEVEL1 = 17, + GMERC_TFRAG_TEX_LEVEL1 = 18, SHRUB_TEX_LEVEL0 = 19, SHRUB_TEX_LEVEL1 = 25, + GENERIC_SHRUB = 30, ALPHA_TEX_LEVEL0 = 31, TFRAG_TRANS0_AND_SKY_BLEND_LEVEL0 = 32, TFRAG_DIRT_LEVEL0 = 34, @@ -34,16 +37,22 @@ enum class BucketId { TFRAG_DIRT_LEVEL1 = 41, TFRAG_ICE_LEVEL1 = 43, MERC_AFTER_ALPHA = 45, + GENERIC_ALPHA = 46, PRIS_TEX_LEVEL0 = 48, MERC_PRIS_LEVEL0 = 49, + GENERIC_PRIS_LEVEL0 = 50, PRIS_TEX_LEVEL1 = 51, MERC_PRIS_LEVEL1 = 52, + GENERIC_PRIS_LEVEL1 = 53, MERC_EYES_AFTER_PRIS = 54, MERC_AFTER_PRIS = 55, + GENERIC_PRIS = 56, WATER_TEX_LEVEL0 = 57, MERC_WATER_LEVEL0 = 58, + GENERIC_WATER_LEVEL0 = 59, WATER_TEX_LEVEL1 = 60, MERC_WATER_LEVEL1 = 61, + GENERIC_WATER_LEVEL1 = 62, // ... PRE_SPRITE_TEX = 65, // maybe it's just common textures? SPRITE = 66, @@ -81,6 +90,8 @@ struct SharedRenderState { bool use_sky_cpu = true; bool use_occlusion_culling = true; bool render_debug = false; + bool enable_merc_xgkick = true; + bool enable_generic_xgkick = true; void reset(); bool has_camera_planes = false; diff --git a/game/graphics/opengl_renderer/DirectRenderer.cpp b/game/graphics/opengl_renderer/DirectRenderer.cpp index 4bfd36c479..ed7c5b502c 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.cpp +++ b/game/graphics/opengl_renderer/DirectRenderer.cpp @@ -259,6 +259,9 @@ void DirectRenderer::update_gl_prim(SharedRenderState* render_state) { glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::DIRECT_BASIC_TEXTURED].id(), "alpha_reject"), alpha_reject); + glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::DIRECT_BASIC_TEXTURED].id(), + "color_mult"), + m_ogl.color_mult); } // update_gl_texture(render_state); m_global_texture_state.needs_gl_update = true; @@ -342,10 +345,12 @@ void DirectRenderer::update_gl_texture(SharedRenderState* render_state, int unit void DirectRenderer::update_gl_blend() { const auto& state = m_blend_state; + m_ogl.color_mult = 1.f; if (!state.alpha_blend_enable) { glDisable(GL_BLEND); } else { glEnable(GL_BLEND); + glBlendColor(1, 1, 1, 1); if (state.a == GsAlpha::BlendMode::SOURCE && state.b == GsAlpha::BlendMode::DEST && state.c == GsAlpha::BlendMode::SOURCE && state.d == GsAlpha::BlendMode::DEST) { // (Cs - Cd) * As + Cd @@ -378,6 +383,19 @@ void DirectRenderer::update_gl_blend() { glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); glBlendColor(0, 0, 0, state.fix / 127.f); glBlendEquation(GL_FUNC_ADD); + } else if (state.a == GsAlpha::BlendMode::SOURCE && state.b == GsAlpha::BlendMode::SOURCE && + state.c == GsAlpha::BlendMode::SOURCE && state.d == GsAlpha::BlendMode::SOURCE) { + // this is very weird... + glBlendFunc(GL_ONE, GL_ZERO); + glBlendEquation(GL_FUNC_ADD); + } else if (state.a == GsAlpha::BlendMode::SOURCE && + state.b == GsAlpha::BlendMode::ZERO_OR_FIXED && + state.c == GsAlpha::BlendMode::DEST && state.d == GsAlpha::BlendMode::DEST) { + // (Cs - 0) * Ad + Cd + glBlendFunc(GL_DST_ALPHA, GL_ONE); + glBlendEquation(GL_FUNC_ADD); + m_ogl.color_mult = 0.5; + m_prim_gl_state_needs_gl_update = true; } else { // unsupported blend: a 0 b 2 c 2 d 1 lg::error("unsupported blend: a {} b {} c {} d {}", (int)state.a, (int)state.b, (int)state.c, @@ -911,6 +929,9 @@ void DirectRenderer::handle_xyzf2_common(u32 x, bool advance) { ASSERT(z < (1 << 24)); (void)f; // TODO: do something with this. + if (m_my_id == BucketId::GENERIC_PRIS) { + // fmt::print("0x{:x}, 0x{:x}, 0x{:x}\n", x, y, z); + } if (m_prim_buffer.is_full()) { lg::warn("Buffer wrapped in {} ({} verts, {} bytes)", m_name, m_ogl.vertex_buffer_max_verts, m_prim_buffer.vert_count * sizeof(Vertex)); diff --git a/game/graphics/opengl_renderer/DirectRenderer.h b/game/graphics/opengl_renderer/DirectRenderer.h index 95126963d5..c08fc04393 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.h +++ b/game/graphics/opengl_renderer/DirectRenderer.h @@ -63,6 +63,13 @@ class DirectRenderer : public BucketRenderer { void draw_debug_window() override; + void hack_disable_blend() { + m_blend_state.a = GsAlpha::BlendMode::SOURCE; + m_blend_state.b = GsAlpha::BlendMode::SOURCE; + m_blend_state.c = GsAlpha::BlendMode::SOURCE; + m_blend_state.d = GsAlpha::BlendMode::SOURCE; + } + private: void handle_ad(const u8* data, SharedRenderState* render_state, ScopedProfilerNode& prof); void handle_zbuf1(u64 val, SharedRenderState* render_state, ScopedProfilerNode& prof); @@ -239,6 +246,7 @@ class DirectRenderer : public BucketRenderer { GLuint vao; u32 vertex_buffer_bytes = 0; u32 vertex_buffer_max_verts = 0; + float color_mult = 1.0; } m_ogl; struct { diff --git a/game/graphics/opengl_renderer/GenericProgram.cpp b/game/graphics/opengl_renderer/GenericProgram.cpp new file mode 100644 index 0000000000..6d67da416d --- /dev/null +++ b/game/graphics/opengl_renderer/GenericProgram.cpp @@ -0,0 +1,2845 @@ +#include "game/graphics/opengl_renderer/GenericRenderer.h" + +void GenericRenderer::lq_buffer(Mask mask, Vf& dest, u16 addr) { + ASSERT(addr * 16 < sizeof(m_buffer.data)); + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + memcpy(dest.data + i, m_buffer.data + addr * 16 + i * 4, 4); + } + } +} + +void GenericRenderer::isw_buffer(Mask mask, u16 val, u16 addr) { + ASSERT(addr * 16 < sizeof(m_buffer.data)); + u32 val32 = val; + int offset; + switch (mask) { + case Mask::x: + offset = 0; + break; + case Mask::y: + offset = 4; + break; + case Mask::z: + offset = 8; + break; + case Mask::w: + offset = 12; + break; + default: + ASSERT(false); + } + memcpy(m_buffer.data + addr * 16 + offset, &val32, 4); +} + +u16 clip(const Vf& vector, float val, u16 old_clip) { + u16 result = (old_clip << 6); + float plus = std::abs(val); + float minus = -plus; + + if (vector.x() > plus) { + result |= 0b1; + } + if (vector.x() < minus) { + result |= 0b10; + } + + if (vector.y() > plus) { + result |= 0b100; + } + if (vector.y() < minus) { + result |= 0b1000; + } + + if (vector.z() > plus) { + result |= 0b10000; + } + if (vector.z() < minus) { + result |= 0b100000; + } + return result; +} + +bool clipping_hack = true; + +// clang-format off +void GenericRenderer::mscal0() { + // L4: + // iaddiu vi01, vi00, 0x381 | nop + vu.vi01 = 0x381; /* 897 */ + // lq.xyzw vf01, 0(vi01) | nop + lq_buffer(Mask::xyzw, vu.vf01, vu.vi01); + // lq.xyzw vf02, 1(vi01) | nop + lq_buffer(Mask::xyzw, vu.vf02, vu.vi01 + 1); + // lq.xyzw vf03, 2(vi01) | nop + lq_buffer(Mask::xyzw, vu.vf03, vu.vi01 + 2); + // lq.xyzw vf04, 3(vi01) | nop + lq_buffer(Mask::xyzw, vu.vf04, vu.vi01 + 3); + // lq.xyzw vf05, 4(vi01) | nop + lq_buffer(Mask::xyzw, vu.vf05, vu.vi01 + 4); + // lq.xyzw vf06, 5(vi01) | nop + lq_buffer(Mask::xyzw, vu.vf06, vu.vi01 + 5); + // lq.xyzw vf07, 6(vi01) | nop + lq_buffer(Mask::xyzw, vu.vf07, vu.vi01 + 6); + // L5: + // iaddiu vi13, vi00, 0x363 | nop + vu.vi13 = 0x363; /* 867 */ + // iaddi vi02, vi13, 0x5 | nop + vu.vi02 = vu.vi13 + 5; + // iaddi vi12, vi00, 0x0 | nop + vu.vi12 = 0; + // isw.x vi02, 9(vi01) | nop + isw_buffer(Mask::x, vu.vi02, vu.vi01 + 9); + // isw.y vi02, 9(vi01) | nop + isw_buffer(Mask::y, vu.vi02, vu.vi01 + 9); + // sq.xyzw vf00, 907(vi00) | nop + sq_buffer(Mask::xyzw, vu.vf00, 907); + // sq.xyzw vf00, 914(vi00) | nop + sq_buffer(Mask::xyzw, vu.vf00, 914); + // sq.xyzw vf00, 921(vi00) | nop + sq_buffer(Mask::xyzw, vu.vf00, 921); + // sq.xyzw vf00, 928(vi00) | nop + sq_buffer(Mask::xyzw, vu.vf00, 928); + // sq.xyzw vf00, 935(vi00) | nop + sq_buffer(Mask::xyzw, vu.vf00, 935); + // sq.xyzw vf00, 942(vi00) | nop + sq_buffer(Mask::xyzw, vu.vf00, 942); + // iaddiu vi01, vi00, 0x40f | nop + vu.vi01 = 0x40f; /* 1039 */ + // isw.z vi01, 907(vi00) | nop + isw_buffer(Mask::z, vu.vi01, 907); + // iaddiu vi01, vi00, 0x411 | nop + vu.vi01 = 0x411; /* 1041 */ + // isw.z vi01, 914(vi00) | nop + isw_buffer(Mask::z, vu.vi01, 914); + // iaddiu vi01, vi00, 0x413 | nop + vu.vi01 = 0x413; /* 1043 */ + // isw.z vi01, 921(vi00) | nop + isw_buffer(Mask::z, vu.vi01, 921); + // iaddiu vi01, vi00, 0x415 | nop + vu.vi01 = 0x415; /* 1045 */ + // isw.z vi01, 928(vi00) | nop + isw_buffer(Mask::z, vu.vi01, 928); + // iaddiu vi01, vi00, 0x417 | nop + vu.vi01 = 0x417; /* 1047 */ + // isw.z vi01, 935(vi00) | nop + isw_buffer(Mask::z, vu.vi01, 935); + // iaddiu vi01, vi00, 0x419 | nop :e + vu.vi01 = 0x419; /* 1049 */ + // isw.z vi01, 942(vi00) | nop + isw_buffer(Mask::z, vu.vi01, 942); +} + +void GenericRenderer::ilw_buffer(Mask mask, u16& dest, u16 addr) { + // fmt::print("addr is {}\n", addr); + ASSERT(addr * 16 < sizeof(m_buffer.data)); + int offset; + switch (mask) { + case Mask::x: + offset = 0; + break; + case Mask::y: + offset = 4; + break; + case Mask::z: + offset = 8; + break; + case Mask::w: + offset = 12; + break; + default: + ASSERT(false); + } + memcpy(&dest, m_buffer.data + addr * 16 + offset, 2); +} + + + +void GenericRenderer::mscal_dispatch(int imm, SharedRenderState* render_state, ScopedProfilerNode& prof) { + bool bc; + u16 cf = 0; + u16 cf0, cf1, cf2; + switch(imm) { + case 6: + goto L33; + case 8: + goto L8; + default: + fmt::print("Generic dispatch mscal: {}\n", imm); + ASSERT(false); + } + + // BRANCH! + // b L4 | nop 0 + bc = true; + // nop | nop 1 + + if (bc) { goto L4; } + + // BRANCH! + // b L5 | nop 2 + bc = true; + // nop | nop 3 + + if (bc) { goto L5; } + + // BRANCH! + // b L84 | nop 4 + bc = true; + // nop | nop 5 + + if (bc) { goto L84; } + + // BRANCH! + // b L33 | nop 6 + bc = true; + // nop | nop 7 + + if (bc) { goto L33; } + + // BRANCH! + // b L8 | nop 8 + bc = true; + // nop | nop 9 + + if (bc) { goto L8; } + + // BRANCH! + // b L1 | nop 10 + bc = true; + // nop | nop 11 + + if (bc) { goto L1; } + + // BRANCH! + // b L6 | nop 12 + bc = true; + // nop | nop 13 + + if (bc) { goto L6; } + + L1: + // iaddiu vi02, vi00, 0x381 | nop 14 + vu.vi02 = 0x381; /* 897 */ + // lq.xyzw vf31, 7(vi02) | nop 15 + lq_buffer(Mask::xyzw, vu.vf31, vu.vi02 + 7); + // isubiu vi02, vi13, 0x363 | addw.z vf22, vf00, vf00 16 + vu.vf22.add(Mask::z, vu.vf00, vu.vf00.w()); vu.vi02 = vu.vi13 - 0x363; /* 867 */ + // iaddiu vi13, vi13, 0x1e | addw.z vf23, vf00, vf00 17 + vu.vf23.add(Mask::z, vu.vf00, vu.vf00.w()); vu.vi13 = vu.vi13 + 0x1e; /* 30 */ + // BRANCH! + // ibne vi00, vi02, L2 | addw.z vf24, vf00, vf00 18 + vu.vf24.add(Mask::z, vu.vf00, vu.vf00.w()); bc = (vu.vi02 != 0); + // lq.xyzw vf03, 899(vi00) | addw.z vf25, vf00, vf00 19 + vu.vf25.add(Mask::z, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf03, 899); + if (bc) { goto L2; } + + // iaddiu vi13, vi00, 0x345 | nop 20 + vu.vi13 = 0x345; /* 837 */ + L2: + // ilw.x vi01, 5(vi13) | nop 21 + ilw_buffer(Mask::x, vu.vi01, vu.vi13 + 5); + // iaddi vi07, vi12, 0xa | nop 22 + vu.vi07 = vu.vi12 + 10; + // iaddi vi05, vi01, -0x1 | nop 23 + vu.vi05 = vu.vi01 + -1; + // lq.xyzw vf17, 4(vi13) | nop 24 + lq_buffer(Mask::xyzw, vu.vf17, vu.vi13 + 4); + // sq.xyzw vf31, 5(vi13) | nop 25 + sq_buffer(Mask::xyzw, vu.vf31, vu.vi13 + 5); + // sq.xyzw vf31, 6(vi13) | nop 26 + sq_buffer(Mask::xyzw, vu.vf31, vu.vi13 + 6); + // 0.0078125 | nop :i 27 + vu.I = 0.0078125; + // move.xyzw vf13, vf17 | muli.xyz vf17, vf17, I 28 + vu.vf17.mul(Mask::xyz, vu.vf17, vu.I); vu.vf13.move(Mask::xyzw, vu.vf17); + // move.xyzw vf14, vf17 | nop 29 + vu.vf14.move(Mask::xyzw, vu.vf17); + // move.xyzw vf15, vf17 | nop 30 + vu.vf15.move(Mask::xyzw, vu.vf17); + // move.xyzw vf16, vf17 | nop 31 + vu.vf16.move(Mask::xyzw, vu.vf17); + // sq.xyzw vf03, 4(vi13) | nop 32 + sq_buffer(Mask::xyzw, vu.vf03, vu.vi13 + 4); + // isw.w vi01, 5(vi13) | nop 33 + isw_buffer(Mask::w, vu.vi01, vu.vi13 + 5); + // isw.w vi00, 6(vi13) | nop 34 + isw_buffer(Mask::w, vu.vi00, vu.vi13 + 6); + L3: + // lq.xyz vf13, 0(vi07) | nop 35 + lq_buffer(Mask::xyz, vu.vf13, vu.vi07); + // lq.xyz vf14, 3(vi07) | nop 36 + lq_buffer(Mask::xyz, vu.vf14, vu.vi07 + 3); + // lq.xyz vf15, 6(vi07) | nop 37 + lq_buffer(Mask::xyz, vu.vf15, vu.vi07 + 6); + // lq.xyz vf16, 9(vi07) | nop 38 + lq_buffer(Mask::xyz, vu.vf16, vu.vi07 + 9); + // iaddi vi07, vi07, 0xc | itof0.xyz vf13, vf13 39 + vu.vf13.itof0(Mask::xyz, vu.vf13); vu.vi07 = vu.vi07 + 12; + // iaddi vi05, vi05, -0x4 | itof0.xyz vf14, vf14 40 + vu.vf14.itof0(Mask::xyz, vu.vf14); vu.vi05 = vu.vi05 + -4; + // nop | itof0.xyz vf15, vf15 41 + vu.vf15.itof0(Mask::xyz, vu.vf15); + // nop | itof0.xyz vf16, vf16 42 + vu.vf16.itof0(Mask::xyz, vu.vf16); + // nop | mul.xyz vf13, vf13, vf17 43 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.vf17); + // nop | mul.xyz vf14, vf14, vf17 44 + vu.vf14.mul(Mask::xyz, vu.vf14, vu.vf17); + // nop | mul.xyz vf15, vf15, vf17 45 + vu.vf15.mul(Mask::xyz, vu.vf15, vu.vf17); + // nop | mul.xyz vf16, vf16, vf17 46 + vu.vf16.mul(Mask::xyz, vu.vf16, vu.vf17); + // lq.xyzw vf18, -11(vi07) | ftoi0.xyz vf13, vf13 47 + vu.vf13.ftoi0(Mask::xyz, vu.vf13); lq_buffer(Mask::xyzw, vu.vf18, vu.vi07 + -11); + // lq.xyzw vf19, -8(vi07) | ftoi0.xyz vf14, vf14 48 + vu.vf14.ftoi0(Mask::xyz, vu.vf14); lq_buffer(Mask::xyzw, vu.vf19, vu.vi07 + -8); + // lq.xyzw vf20, -5(vi07) | ftoi0.xyz vf15, vf15 49 + vu.vf15.ftoi0(Mask::xyz, vu.vf15); lq_buffer(Mask::xyzw, vu.vf20, vu.vi07 + -5); + // lq.xyzw vf21, -2(vi07) | ftoi0.xyz vf16, vf16 50 + vu.vf16.ftoi0(Mask::xyz, vu.vf16); lq_buffer(Mask::xyzw, vu.vf21, vu.vi07 + -2); + // sq.xyzw vf13, -12(vi07) | itof0.xyzw vf18, vf18 51 + vu.vf18.itof0(Mask::xyzw, vu.vf18); sq_buffer(Mask::xyzw, vu.vf13, vu.vi07 + -12); + // sq.xyzw vf14, -9(vi07) | itof0.xyzw vf19, vf19 52 + vu.vf19.itof0(Mask::xyzw, vu.vf19); sq_buffer(Mask::xyzw, vu.vf14, vu.vi07 + -9); + // sq.xyzw vf15, -6(vi07) | itof0.xyzw vf20, vf20 53 + vu.vf20.itof0(Mask::xyzw, vu.vf20); sq_buffer(Mask::xyzw, vu.vf15, vu.vi07 + -6); + // sq.xyzw vf16, -3(vi07) | itof0.xyzw vf21, vf21 54 + vu.vf21.itof0(Mask::xyzw, vu.vf21); sq_buffer(Mask::xyzw, vu.vf16, vu.vi07 + -3); + // sq.xyzw vf18, -11(vi07) | nop 55 + sq_buffer(Mask::xyzw, vu.vf18, vu.vi07 + -11); + // sq.xyzw vf19, -8(vi07) | nop 56 + sq_buffer(Mask::xyzw, vu.vf19, vu.vi07 + -8); + // sq.xyzw vf20, -5(vi07) | nop 57 + sq_buffer(Mask::xyzw, vu.vf20, vu.vi07 + -5); + // BRANCH! + // ibgez vi05, L3 | nop 58 + bc = ((s16)vu.vi05) >= 0; + // sq.xyzw vf21, -2(vi07) | nop 59 + sq_buffer(Mask::xyzw, vu.vf21, vu.vi07 + -2); + if (bc) { goto L3; } + + // BRANCH! + // b L16 | nop 60 + bc = true; + // nop | nop 61 + + if (bc) { goto L16; } + + L4: + // iaddiu vi01, vi00, 0x381 | nop 62 + vu.vi01 = 0x381; /* 897 */ + // lq.xyzw vf01, 0(vi01) | nop 63 + lq_buffer(Mask::xyzw, vu.vf01, vu.vi01); + // lq.xyzw vf02, 1(vi01) | nop 64 + lq_buffer(Mask::xyzw, vu.vf02, vu.vi01 + 1); + // lq.xyzw vf03, 2(vi01) | nop 65 + lq_buffer(Mask::xyzw, vu.vf03, vu.vi01 + 2); + // lq.xyzw vf04, 3(vi01) | nop 66 + lq_buffer(Mask::xyzw, vu.vf04, vu.vi01 + 3); + // lq.xyzw vf05, 4(vi01) | nop 67 + lq_buffer(Mask::xyzw, vu.vf05, vu.vi01 + 4); + // lq.xyzw vf06, 5(vi01) | nop 68 + lq_buffer(Mask::xyzw, vu.vf06, vu.vi01 + 5); + // lq.xyzw vf07, 6(vi01) | nop 69 + lq_buffer(Mask::xyzw, vu.vf07, vu.vi01 + 6); + L5: + // iaddiu vi13, vi00, 0x363 | nop 70 + vu.vi13 = 0x363; /* 867 */ + // iaddi vi02, vi13, 0x5 | nop 71 + vu.vi02 = vu.vi13 + 5; + // iaddi vi12, vi00, 0x0 | nop 72 + vu.vi12 = 0; + // isw.x vi02, 9(vi01) | nop 73 + isw_buffer(Mask::x, vu.vi02, vu.vi01 + 9); + // isw.y vi02, 9(vi01) | nop 74 + isw_buffer(Mask::y, vu.vi02, vu.vi01 + 9); + // sq.xyzw vf00, 907(vi00) | nop 75 + sq_buffer(Mask::xyzw, vu.vf00, 907); + // sq.xyzw vf00, 914(vi00) | nop 76 + sq_buffer(Mask::xyzw, vu.vf00, 914); + // sq.xyzw vf00, 921(vi00) | nop 77 + sq_buffer(Mask::xyzw, vu.vf00, 921); + // sq.xyzw vf00, 928(vi00) | nop 78 + sq_buffer(Mask::xyzw, vu.vf00, 928); + // sq.xyzw vf00, 935(vi00) | nop 79 + sq_buffer(Mask::xyzw, vu.vf00, 935); + // sq.xyzw vf00, 942(vi00) | nop 80 + sq_buffer(Mask::xyzw, vu.vf00, 942); + // iaddiu vi01, vi00, 0x40f | nop 81 + vu.vi01 = 0x40f; /* 1039 */ + // isw.z vi01, 907(vi00) | nop 82 + isw_buffer(Mask::z, vu.vi01, 907); + // iaddiu vi01, vi00, 0x411 | nop 83 + vu.vi01 = 0x411; /* 1041 */ + // isw.z vi01, 914(vi00) | nop 84 + isw_buffer(Mask::z, vu.vi01, 914); + // iaddiu vi01, vi00, 0x413 | nop 85 + vu.vi01 = 0x413; /* 1043 */ + // isw.z vi01, 921(vi00) | nop 86 + isw_buffer(Mask::z, vu.vi01, 921); + // iaddiu vi01, vi00, 0x415 | nop 87 + vu.vi01 = 0x415; /* 1045 */ + // isw.z vi01, 928(vi00) | nop 88 + isw_buffer(Mask::z, vu.vi01, 928); + // iaddiu vi01, vi00, 0x417 | nop 89 + vu.vi01 = 0x417; /* 1047 */ + // isw.z vi01, 935(vi00) | nop 90 + isw_buffer(Mask::z, vu.vi01, 935); + // iaddiu vi01, vi00, 0x419 | nop :e 91 + vu.vi01 = 0x419; /* 1049 */ + // isw.z vi01, 942(vi00) | nop 92 + isw_buffer(Mask::z, vu.vi01, 942); + return; + + L6: + // iaddiu vi01, vi00, 0x381 | nop 93 + vu.vi01 = 0x381; /* 897 */ + // ilw.z vi13, 9(vi01) | nop 94 + ilw_buffer(Mask::z, vu.vi13, vu.vi01 + 9); + // ilw.w vi12, 9(vi01) | nop 95 + ilw_buffer(Mask::w, vu.vi12, vu.vi01 + 9); + // iaddi vi02, vi13, 0x6 | nop 96 + vu.vi02 = vu.vi13 + 6; + // isw.x vi02, 9(vi01) | nop :e 97 + isw_buffer(Mask::x, vu.vi02, vu.vi01 + 9); + // isw.y vi02, 9(vi01) | nop 98 + isw_buffer(Mask::y, vu.vi02, vu.vi01 + 9); + return; + + // isubiu vi02, vi13, 0x363 | nop 99 + vu.vi02 = vu.vi13 - 0x363; /* 867 */ + // iaddiu vi13, vi13, 0x1e | nop 100 + vu.vi13 = vu.vi13 + 0x1e; /* 30 */ + // BRANCH! + // ibne vi00, vi02, L7 | nop 101 + bc = (vu.vi02 != 0); + // isubiu vi01, vi01, 0x100 | nop 102 + vu.vi01 = vu.vi01 - 0x100; /* 256 */ + if (bc) { goto L7; } + + // iaddiu vi13, vi00, 0x345 | nop 103 + vu.vi13 = 0x345; /* 837 */ + L7: + // iaddi vi03, vi13, 0x7 | nop 104 + vu.vi03 = vu.vi13 + 7; + // iaddi vi03, vi13, 0x7 | nop 105 + vu.vi03 = vu.vi13 + 7; + // isw.x vi03, 906(vi00) | nop 106 + isw_buffer(Mask::x, vu.vi03, 906); + // jr vi15 | nop 107 + ASSERT(false); + // isw.y vi03, 906(vi00) | nop 108 + isw_buffer(Mask::y, vu.vi03, 906); + L8: + // isubiu vi02, vi13, 0x363 | addw.z vf22, vf00, vf00 109 + vu.vf22.add(Mask::z, vu.vf00, vu.vf00.w()); vu.vi02 = vu.vi13 - 0x363; /* 867 */ + // iaddiu vi13, vi13, 0x1e | addw.z vf23, vf00, vf00 110 + vu.vf23.add(Mask::z, vu.vf00, vu.vf00.w()); vu.vi13 = vu.vi13 + 0x1e; /* 30 */ + // BRANCH! + // ibne vi00, vi02, L9 | addw.z vf24, vf00, vf00 111 + vu.vf24.add(Mask::z, vu.vf00, vu.vf00.w()); bc = (vu.vi02 != 0); + // nop | addw.z vf25, vf00, vf00 112 + vu.vf25.add(Mask::z, vu.vf00, vu.vf00.w()); + if (bc) { goto L9; } + + // iaddiu vi13, vi00, 0x345 | nop 113 + vu.vi13 = 0x345; /* 837 */ + L9: + // iaddi vi03, vi13, 0x7 | nop 114 + vu.vi03 = vu.vi13 + 7; + // ilw.w vi01, 5(vi13) | nop 115 + ilw_buffer(Mask::w, vu.vi01, vu.vi13 + 5); + // isw.x vi03, 906(vi00) | nop 116 + isw_buffer(Mask::x, vu.vi03, 906); + // iaddi vi10, vi12, 0x9 | subw.w vf18, vf00, vf00 117 + vu.vf18.sub(Mask::w, vu.vf00, vu.vf00.w()); vu.vi10 = vu.vi12 + 9; + // lq.xyzw vf08, 0(vi13) | subw.w vf19, vf00, vf00 118 + vu.vf19.sub(Mask::w, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf08, vu.vi13); + // lq.xyzw vf09, 1(vi13) | subw.w vf20, vf00, vf00 119 + vu.vf20.sub(Mask::w, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf09, vu.vi13 + 1); + // lq.xyzw vf10, 2(vi13) | subw.w vf21, vf00, vf00 120 + vu.vf21.sub(Mask::w, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf10, vu.vi13 + 2); + // lq.xyzw vf11, 3(vi13) | ftoi12.z vf22, vf22 121 + // fmt::print("a: [{}] [{}]\n", vu.vf22.print(), vu.vf23.print()); + vu.vf22.ftoi12(Mask::z, vu.vf22); lq_buffer(Mask::xyzw, vu.vf11, vu.vi13 + 3); + // iadd vi02, vi01, vi01 | ftoi12.z vf23, vf23 122 + vu.vf23.ftoi12(Mask::z, vu.vf23); vu.vi02 = vu.vi01 + vu.vi01; + // iadd vi01, vi01, vi02 | sub.xyzw vf16, vf16, vf16 123 + vu.vf16.set_zero(); vu.vi01 = vu.vi01 + vu.vi02; + // iaddi vi11, vi00, -0x2 | sub.xyzw vf17, vf17, vf17 124 + vu.vf17.set_zero(); vu.vi11 = -2; + // lq.xy vf22, 0(vi10) | nop 125 + lq_buffer(Mask::xy, vu.vf22, vu.vi10); + // lq.xyz vf16, 2(vi10) | nop 126 + lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // mtir vi02, vf22.x | mulaw.xyzw ACC, vf11, vf00 127 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.vi02 = vu.vf22.x_as_u16(); + // iaddi vi10, vi10, 0x3 | maddax.xyzw ACC, vf08, vf16 128 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf23, 0(vi10) | madday.xyzw ACC, vf09, vf16 129 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); lq_buffer(Mask::xy, vu.vf23, vu.vi10); + // lq.xyz vf17, 2(vi10) | nop 130 + lq_buffer(Mask::xyz, vu.vf17, vu.vi10 + 2); + // iand vi06, vi02, vi11 | nop 131 + vu.vi06 = vu.vi02 & vu.vi11; + // mfir.x vf22, vi06 | maddz.xyzw vf12, vf10, vf16 132 + vu.acc.madd(Mask::xyzw, vu.vf12, vu.vf10, vu.vf16.z()); vu.vf22.mfir(Mask::x, vu.vi06); + // iadd vi14, vi10, vi01 | ftoi12.z vf24, vf24 133 + // fmt::print("b: [{}] [{}]\n", vu.vf24.print(), vu.vf25.print()); + vu.vf24.ftoi12(Mask::z, vu.vf24); vu.vi14 = vu.vi10 + vu.vi01; + // isw.w vi12, 906(vi00) | ftoi12.z vf25, vf25 134 + vu.vf25.ftoi12(Mask::z, vu.vf25); isw_buffer(Mask::w, vu.vi12, 906); + // nop | nop 135 + + // div Q, vf01.x, vf12.w | itof12.xyz vf18, vf22 136 + vu.vf18.itof12(Mask::xyz, vu.vf22); vu.Q = vu.vf01.x() / vu.vf12.w(); + // mtir vi03, vf23.x | mulaw.xyzw ACC, vf11, vf00 137 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.vi03 = vu.vf23.x_as_u16(); + // iaddi vi10, vi10, 0x3 | maddax.xyzw ACC, vf08, vf17 138 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf17.x()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf24, 0(vi10) | madday.xyzw ACC, vf09, vf17 139 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf17.y()); lq_buffer(Mask::xy, vu.vf24, vu.vi10); + // lq.xyz vf16, 2(vi10) | nop 140 + lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi07, vi03, vi11 | nop 141 + vu.vi07 = vu.vi03 & vu.vi11; + // mfir.x vf23, vi07 | maddz.xyzw vf13, vf10, vf17 142 + vu.acc.madd(Mask::xyzw, vu.vf13, vu.vf10, vu.vf17.z()); vu.vf23.mfir(Mask::x, vu.vi07); + // nop | mul.xyz vf12, vf12, Q 143 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); + // nop | mul.xyz vf18, vf18, Q 144 + vu.vf18.mul(Mask::xyz, vu.vf18, vu.Q); + // nop | nop 145 + + // div Q, vf01.x, vf13.w | itof12.xyz vf19, vf23 146 + vu.vf19.itof12(Mask::xyz, vu.vf23); vu.Q = vu.vf01.x() / vu.vf13.w(); + // nop | add.xyzw vf12, vf12, vf04 147 + vu.vf12.add(Mask::xyzw, vu.vf12, vu.vf04); + // mtir vi04, vf24.x | mulaw.xyzw ACC, vf11, vf00 148 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.vi04 = vu.vf24.x_as_u16(); + // iaddi vi10, vi10, 0x3 | maddax.xyzw ACC, vf08, vf16 149 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf25, 0(vi10) | madday.xyzw ACC, vf09, vf16 150 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); lq_buffer(Mask::xy, vu.vf25, vu.vi10); + // lq.xyz vf17, 2(vi10) | miniz.w vf12, vf12, vf01 151 + vu.vf12.mini(Mask::w, vu.vf12, vu.vf01.z()); lq_buffer(Mask::xyz, vu.vf17, vu.vi10 + 2); + // iand vi08, vi04, vi11 | nop 152 + vu.vi08 = vu.vi04 & vu.vi11; + // mfir.x vf24, vi08 | maddz.xyzw vf14, vf10, vf16 153 + vu.acc.madd(Mask::xyzw, vu.vf14, vu.vf10, vu.vf16.z()); vu.vf24.mfir(Mask::x, vu.vi08); + // nop | mul.xyz vf13, vf13, Q 154 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); + // nop | mul.xyz vf19, vf19, Q 155 + vu.vf19.mul(Mask::xyz, vu.vf19, vu.Q); + // iaddi vi14, vi14, 0x9 | maxy.w vf12, vf12, vf01 156 + vu.vf12.max(Mask::w, vu.vf12, vu.vf01.y()); vu.vi14 = vu.vi14 + 9; + // fmt::print("vf12-1a: [{}]\n", vu.vf12.print()); + +L10: + // fmt::print("vf12-1b: [{}]\n", vu.vf12.print()); + + // div Q, vf01.x, vf14.w | itof12.xyz vf20, vf24 157 + vu.vf20.itof12(Mask::xyz, vu.vf24); vu.Q = vu.vf01.x() / vu.vf14.w(); + // BRANCH! + // ibeq vi02, vi06, L11 | add.xyzw vf13, vf13, vf04 158 + vu.vf13.add(Mask::xyzw, vu.vf13, vu.vf04); bc = (vu.vi02 == vu.vi06); + // mtir vi05, vf25.x | mulaw.xyzw ACC, vf11, vf00 159 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.vi05 = vu.vf25.x_as_u16(); + if (bc) { goto L11; } + + // nop | addw.w vf12, vf12, vf01 160 + vu.vf12.add(Mask::w, vu.vf12, vu.vf01.w()); + L11: + // iaddi vi10, vi10, 0x3 | maddax.xyzw ACC, vf08, vf17 161 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf17.x()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf22, 0(vi10) | madday.xyzw ACC, vf09, vf17 162 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf17.y()); lq_buffer(Mask::xy, vu.vf22, vu.vi10); + // lq.xyz vf16, 2(vi10) | miniz.w vf13, vf13, vf01 163 + vu.vf13.mini(Mask::w, vu.vf13, vu.vf01.z()); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // fmt::print("vf16 vertex [{}] @ \n", vu.vf16.print(), vu.vi10 + 2); + // iand vi09, vi05, vi11 | ftoi4.xyzw vf12, vf12 164 + vu.vf12.ftoi4(Mask::xyzw, vu.vf12); vu.vi09 = vu.vi05 & vu.vi11; + // mfir.x vf25, vi09 | maddz.xyzw vf15, vf10, vf17 165 + vu.acc.madd(Mask::xyzw, vu.vf15, vu.vf10, vu.vf17.z()); vu.vf25.mfir(Mask::x, vu.vi09); + // sq.xyzw vf18, -12(vi10) | mul.xyz vf14, vf14, Q 166 + vu.vf14.mul(Mask::xyz, vu.vf14, vu.Q); sq_buffer(Mask::xyzw, vu.vf18, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L15 | mul.xyz vf20, vf20, Q 167 + vu.vf20.mul(Mask::xyz, vu.vf20, vu.Q); bc = (vu.vi14 == vu.vi10); + // fmt::print("store: {} {}\n", vu.vi10 - 10, vu.vf12.print_hex()); + // sq.xyzw vf12, -10(vi10) | maxy.w vf13, vf13, vf01 168 + vu.vf13.max(Mask::w, vu.vf13, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf12, vu.vi10 + -10); + if (bc) { goto L15; } + + // div Q, vf01.x, vf15.w | itof12.xyz vf21, vf25 169 + vu.vf21.itof12(Mask::xyz, vu.vf25); vu.Q = vu.vf01.x() / vu.vf15.w(); + // BRANCH! + // ibeq vi03, vi07, L12 | add.xyzw vf14, vf14, vf04 170 + vu.vf14.add(Mask::xyzw, vu.vf14, vu.vf04); bc = (vu.vi03 == vu.vi07); + // mtir vi02, vf22.x | mulaw.xyzw ACC, vf11, vf00 171 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.vi02 = vu.vf22.x_as_u16(); + if (bc) { goto L12; } + + // nop | addw.w vf13, vf13, vf01 172 + vu.vf13.add(Mask::w, vu.vf13, vu.vf01.w()); + L12: + // iaddi vi10, vi10, 0x3 | maddax.xyzw ACC, vf08, vf16 173 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf23, 0(vi10) | madday.xyzw ACC, vf09, vf16 174 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); lq_buffer(Mask::xy, vu.vf23, vu.vi10); + // lq.xyz vf17, 2(vi10) | miniz.w vf14, vf14, vf01 175 + vu.vf14.mini(Mask::w, vu.vf14, vu.vf01.z()); lq_buffer(Mask::xyz, vu.vf17, vu.vi10 + 2); + // iand vi06, vi02, vi11 | ftoi4.xyzw vf13, vf13 176 + vu.vf13.ftoi4(Mask::xyzw, vu.vf13); vu.vi06 = vu.vi02 & vu.vi11; + // mfir.x vf22, vi06 | maddz.xyzw vf12, vf10, vf16 177 + vu.acc.madd(Mask::xyzw, vu.vf12, vu.vf10, vu.vf16.z()); vu.vf22.mfir(Mask::x, vu.vi06); + // fmt::print("vf12 transformed: [{}]\n", vu.vf12.print()); + // sq.xyzw vf19, -12(vi10) | mul.xyz vf15, vf15, Q 178 + vu.vf15.mul(Mask::xyz, vu.vf15, vu.Q); sq_buffer(Mask::xyzw, vu.vf19, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L15 | mul.xyz vf21, vf21, Q 179 + vu.vf21.mul(Mask::xyz, vu.vf21, vu.Q); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf13, -10(vi10) | maxy.w vf14, vf14, vf01 180 + vu.vf14.max(Mask::w, vu.vf14, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf13, vu.vi10 + -10); + if (bc) { goto L15; } + + // div Q, vf01.x, vf12.w | itof12.xyz vf18, vf22 181 + vu.vf18.itof12(Mask::xyz, vu.vf22); vu.Q = vu.vf01.x() / vu.vf12.w(); + // BRANCH! + // ibeq vi04, vi08, L13 | add.xyzw vf15, vf15, vf04 182 + vu.vf15.add(Mask::xyzw, vu.vf15, vu.vf04); bc = (vu.vi04 == vu.vi08); + // mtir vi03, vf23.x | mulaw.xyzw ACC, vf11, vf00 183 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.vi03 = vu.vf23.x_as_u16(); + if (bc) { goto L13; } + + // nop | addw.w vf14, vf14, vf01 184 + vu.vf14.add(Mask::w, vu.vf14, vu.vf01.w()); + L13: + // iaddi vi10, vi10, 0x3 | maddax.xyzw ACC, vf08, vf17 185 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf17.x()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf24, 0(vi10) | madday.xyzw ACC, vf09, vf17 186 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf17.y()); lq_buffer(Mask::xy, vu.vf24, vu.vi10); + // lq.xyz vf16, 2(vi10) | miniz.w vf15, vf15, vf01 187 + vu.vf15.mini(Mask::w, vu.vf15, vu.vf01.z()); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi07, vi03, vi11 | ftoi4.xyzw vf14, vf14 188 + vu.vf14.ftoi4(Mask::xyzw, vu.vf14); vu.vi07 = vu.vi03 & vu.vi11; + // mfir.x vf23, vi07 | maddz.xyzw vf13, vf10, vf17 189 + vu.acc.madd(Mask::xyzw, vu.vf13, vu.vf10, vu.vf17.z()); vu.vf23.mfir(Mask::x, vu.vi07); + // sq.xyzw vf20, -12(vi10) | mul.xyz vf12, vf12, Q 190 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); sq_buffer(Mask::xyzw, vu.vf20, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L15 | mul.xyz vf18, vf18, Q 191 + vu.vf18.mul(Mask::xyz, vu.vf18, vu.Q); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf14, -10(vi10) | maxy.w vf15, vf15, vf01 192 + vu.vf15.max(Mask::w, vu.vf15, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf14, vu.vi10 + -10); + if (bc) { goto L15; } + + // div Q, vf01.x, vf13.w | itof12.xyz vf19, vf23 193 + vu.vf19.itof12(Mask::xyz, vu.vf23); vu.Q = vu.vf01.x() / vu.vf13.w(); + // BRANCH! + // ibeq vi05, vi09, L14 | add.xyzw vf12, vf12, vf04 194 + vu.vf12.add(Mask::xyzw, vu.vf12, vu.vf04); bc = (vu.vi05 == vu.vi09); + // mtir vi04, vf24.x | mulaw.xyzw ACC, vf11, vf00 195 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.vi04 = vu.vf24.x_as_u16(); + if (bc) { goto L14; } + + // nop | addw.w vf15, vf15, vf01 196 + vu.vf15.add(Mask::w, vu.vf15, vu.vf01.w()); + L14: + // iaddi vi10, vi10, 0x3 | maddax.xyzw ACC, vf08, vf16 197 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf25, 0(vi10) | madday.xyzw ACC, vf09, vf16 198 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); lq_buffer(Mask::xy, vu.vf25, vu.vi10); + // lq.xyz vf17, 2(vi10) | miniz.w vf12, vf12, vf01 199 + vu.vf12.mini(Mask::w, vu.vf12, vu.vf01.z()); lq_buffer(Mask::xyz, vu.vf17, vu.vi10 + 2); + // iand vi08, vi04, vi11 | ftoi4.xyzw vf15, vf15 200 + vu.vf15.ftoi4(Mask::xyzw, vu.vf15); vu.vi08 = vu.vi04 & vu.vi11; + // mfir.x vf24, vi08 | maddz.xyzw vf14, vf10, vf16 201 + vu.acc.madd(Mask::xyzw, vu.vf14, vu.vf10, vu.vf16.z()); vu.vf24.mfir(Mask::x, vu.vi08); + // sq.xyzw vf21, -12(vi10) | mul.xyz vf13, vf13, Q 202 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); sq_buffer(Mask::xyzw, vu.vf21, vu.vi10 + -12); + // BRANCH! + // ibne vi14, vi10, L10 | mul.xyz vf19, vf19, Q 203 + vu.vf19.mul(Mask::xyz, vu.vf19, vu.Q); bc = (vu.vi14 != vu.vi10); + // sq.xyzw vf15, -10(vi10) | maxy.w vf12, vf12, vf01 204 + // fmt::print("reloop {} {}\n", vu.vi14, vu.vi10); + vu.vf12.max(Mask::w, vu.vf12, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf15, vu.vi10 + -10); + if (bc) { goto L10; } + + L15: + // BRANCH! + // b L82 | nop 205 + bc = true; + // ilw.w vi12, 906(vi00) | nop 206 + ilw_buffer(Mask::w, vu.vi12, 906); + if (bc) { goto L82; } + + // isubiu vi02, vi13, 0x363 | addw.z vf22, vf00, vf00 207 + vu.vf22.add(Mask::z, vu.vf00, vu.vf00.w()); vu.vi02 = vu.vi13 - 0x363; /* 867 */ + // iaddiu vi13, vi13, 0x1e | addw.z vf23, vf00, vf00 208 + vu.vf23.add(Mask::z, vu.vf00, vu.vf00.w()); vu.vi13 = vu.vi13 + 0x1e; /* 30 */ + // BRANCH! + // ibne vi00, vi02, L16 | addw.z vf24, vf00, vf00 209 + vu.vf24.add(Mask::z, vu.vf00, vu.vf00.w()); bc = (vu.vi02 != 0); + // nop | addw.z vf25, vf00, vf00 210 + vu.vf25.add(Mask::z, vu.vf00, vu.vf00.w()); + if (bc) { goto L16; } + + // iaddiu vi13, vi00, 0x345 | nop 211 + vu.vi13 = 0x345; /* 837 */ + L16: + // iaddi vi03, vi13, 0x7 | nop 212 + vu.vi03 = vu.vi13 + 7; + // ilw.w vi01, 5(vi13) | nop 213 + ilw_buffer(Mask::w, vu.vi01, vu.vi13 + 5); + // isw.x vi03, 906(vi00) | nop 214 + isw_buffer(Mask::x, vu.vi03, 906); + // iaddi vi10, vi12, 0x9 | subw.w vf18, vf00, vf00 215 + vu.vf18.sub(Mask::w, vu.vf00, vu.vf00.w()); vu.vi10 = vu.vi12 + 9; + // lq.xyzw vf08, 0(vi13) | subw.w vf19, vf00, vf00 216 + vu.vf19.sub(Mask::w, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf08, vu.vi13); + // lq.xyzw vf09, 1(vi13) | subw.w vf20, vf00, vf00 217 + vu.vf20.sub(Mask::w, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf09, vu.vi13 + 1); + // lq.xyzw vf10, 2(vi13) | subw.w vf21, vf00, vf00 218 + vu.vf21.sub(Mask::w, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf10, vu.vi13 + 2); + // lq.xyzw vf11, 3(vi13) | ftoi12.z vf22, vf22 219 + vu.vf22.ftoi12(Mask::z, vu.vf22); lq_buffer(Mask::xyzw, vu.vf11, vu.vi13 + 3); + // iadd vi02, vi01, vi01 | ftoi12.z vf23, vf23 220 + vu.vf23.ftoi12(Mask::z, vu.vf23); vu.vi02 = vu.vi01 + vu.vi01; + // iadd vi01, vi01, vi02 | sub.xyzw vf16, vf16, vf16 221 + vu.vf16.set_zero(); vu.vi01 = vu.vi01 + vu.vi02; + // iaddi vi11, vi00, -0x2 | nop 222 + vu.vi11 = -2; + // iadd vi14, vi10, vi01 | ftoi12.z vf24, vf24 223 + vu.vf24.ftoi12(Mask::z, vu.vf24); vu.vi14 = vu.vi10 + vu.vi01; + // isw.w vi12, 906(vi00) | ftoi12.z vf25, vf25 224 + vu.vf25.ftoi12(Mask::z, vu.vf25); isw_buffer(Mask::w, vu.vi12, 906); + // iaddi vi14, vi14, 0x9 | nop 225 + vu.vi14 = vu.vi14 + 9; + // lq.xy vf22, 0(vi10) | nop 226 + lq_buffer(Mask::xy, vu.vf22, vu.vi10); + // lq.xyz vf16, 2(vi10) | nop 227 + lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // nop | nop 228 + + // nop | nop 229 + + // nop | mulaw.xyzw ACC, vf11, vf00 230 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); + // mtir vi02, vf22.x | maddax.xyzw ACC, vf08, vf16 231 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); vu.vi02 = vu.vf22.x_as_u16(); + // iaddi vi10, vi10, 0x3 | madday.xyzw ACC, vf09, vf16 232 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf23, 0(vi10) | maddz.xyzw vf12, vf10, vf16 233 + vu.acc.madd(Mask::xyzw, vu.vf12, vu.vf10, vu.vf16.z()); lq_buffer(Mask::xy, vu.vf23, vu.vi10); + // lq.xyz vf16, 2(vi10) | nop 234 + lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi06, vi02, vi11 | nop 235 + vu.vi06 = vu.vi02 & vu.vi11; + // mfir.x vf22, vi06 | nop 236 + vu.vf22.mfir(Mask::x, vu.vi06); + // nop | nop 237 + + // nop | nop 238 + + // nop | nop 239 + + // nop | itof12.xyz vf18, vf22 240 + vu.vf18.itof12(Mask::xyz, vu.vf22); + // div Q, vf01.x, vf12.w | mul.xyzw vf26, vf12, vf05 241 + vu.vf26.mul(Mask::xyzw, vu.vf12, vu.vf05); vu.Q = vu.vf01.x() / vu.vf12.w(); + // nop | nop 242 + + // nop | mulaw.xyzw ACC, vf11, vf00 243 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); + // mtir vi03, vf23.x | maddax.xyzw ACC, vf08, vf16 244 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); vu.vi03 = vu.vf23.x_as_u16(); + // iaddi vi10, vi10, 0x3 | madday.xyzw ACC, vf09, vf16 245 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf24, 0(vi10) | maddz.xyzw vf13, vf10, vf16 246 + vu.acc.madd(Mask::xyzw, vu.vf13, vu.vf10, vu.vf16.z()); lq_buffer(Mask::xy, vu.vf24, vu.vi10); + // lq.xyz vf16, 2(vi10) | nop 247 + lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi07, vi03, vi11 | nop 248 + vu.vi07 = vu.vi03 & vu.vi11; + // mfir.x vf23, vi07 | mul.xyz vf12, vf12, Q 249 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); vu.vf23.mfir(Mask::x, vu.vi07); + // fcset 0x0 | nop 250 + ASSERT(false); + // nop | nop 251 + + // nop | mul.xyz vf18, vf18, Q 252 + vu.vf18.mul(Mask::xyz, vu.vf18, vu.Q); + // nop | itof12.xyz vf19, vf23 253 + vu.vf19.itof12(Mask::xyz, vu.vf23); + // div Q, vf01.x, vf13.w | mulaw.xyzw ACC, vf11, vf00 254 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf13.w(); + // nop | add.xyzw vf12, vf12, vf04 255 + vu.vf12.add(Mask::xyzw, vu.vf12, vu.vf04); + // nop | maddax.xyzw ACC, vf08, vf16 256 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); + // mtir vi04, vf24.x | madday.xyzw ACC, vf09, vf16 257 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi04 = vu.vf24.x_as_u16(); + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf14, vf10, vf16 258 + vu.acc.madd(Mask::xyzw, vu.vf14, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf25, 0(vi10) | miniz.w vf12, vf12, vf01 259 + vu.vf12.mini(Mask::w, vu.vf12, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf25, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf27, vf13, vf05 260 + vu.vf27.mul(Mask::xyzw, vu.vf13, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi08, vi04, vi11 | nop 261 + vu.vi08 = vu.vi04 & vu.vi11; + // mfir.x vf24, vi08 | mul.xyz vf13, vf13, Q 262 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); vu.vf24.mfir(Mask::x, vu.vi08); + // nop | maxy.w vf12, vf12, vf01 263 + vu.vf12.max(Mask::w, vu.vf12, vu.vf01.y()); + // nop | clipw.xyz vf26, vf26 264 + ASSERT(false); cf = clip(vu.vf26, vu.vf26.w(), cf); + // nop | mul.xyz vf19, vf19, Q 265 + vu.vf19.mul(Mask::xyz, vu.vf19, vu.Q); + // BRANCH! + // ibeq vi02, vi06, L17 | itof12.xyz vf20, vf24 266 + vu.vf20.itof12(Mask::xyz, vu.vf24); bc = (vu.vi02 == vu.vi06); + // div Q, vf01.x, vf14.w | mulaw.xyzw ACC, vf11, vf00 267 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf14.w(); + if (bc) { goto L17; } + + // nop | addw.w vf12, vf12, vf01 268 + vu.vf12.add(Mask::w, vu.vf12, vu.vf01.w()); + L17: + // nop | add.xyzw vf13, vf13, vf04 269 + vu.vf13.add(Mask::xyzw, vu.vf13, vu.vf04); + // nop | maddax.xyzw ACC, vf08, vf16 270 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); + // mtir vi05, vf25.x | madday.xyzw ACC, vf09, vf16 271 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi05 = vu.vf25.x_as_u16(); + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf15, vf10, vf16 272 + vu.acc.madd(Mask::xyzw, vu.vf15, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf22, 0(vi10) | miniz.w vf13, vf13, vf01 273 + vu.vf13.mini(Mask::w, vu.vf13, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf22, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf28, vf14, vf05 274 + vu.vf28.mul(Mask::xyzw, vu.vf14, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi09, vi05, vi11 | ftoi4.xyzw vf12, vf12 275 + vu.vf12.ftoi4(Mask::xyzw, vu.vf12); vu.vi09 = vu.vi05 & vu.vi11; + // mfir.x vf25, vi09 | mul.xyz vf14, vf14, Q 276 + vu.vf14.mul(Mask::xyz, vu.vf14, vu.Q); vu.vf25.mfir(Mask::x, vu.vi09); + // sq.xyzw vf18, -12(vi10) | maxy.w vf13, vf13, vf01 277 + vu.vf13.max(Mask::w, vu.vf13, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf18, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L28 | clipw.xyz vf27, vf27 278 + ASSERT(false); cf = clip(vu.vf27, vu.vf27.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf12, -10(vi10) | mul.xyz vf20, vf20, Q 279 + vu.vf20.mul(Mask::xyz, vu.vf20, vu.Q); sq_buffer(Mask::xyzw, vu.vf12, vu.vi10 + -10); + if (bc) { goto L28; } + + // BRANCH! + // ibeq vi03, vi07, L18 | itof12.xyz vf21, vf25 280 + vu.vf21.itof12(Mask::xyz, vu.vf25); bc = (vu.vi03 == vu.vi07); + // div Q, vf01.x, vf15.w | mulaw.xyzw ACC, vf11, vf00 281 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf15.w(); + if (bc) { goto L18; } + + // nop | addw.w vf13, vf13, vf01 282 + vu.vf13.add(Mask::w, vu.vf13, vu.vf01.w()); + L18: + // nop | add.xyzw vf14, vf14, vf04 283 + vu.vf14.add(Mask::xyzw, vu.vf14, vu.vf04); + // nop | maddax.xyzw ACC, vf08, vf16 284 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); + // mtir vi02, vf22.x | madday.xyzw ACC, vf09, vf16 285 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi02 = vu.vf22.x_as_u16(); + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf12, vf10, vf16 286 + vu.acc.madd(Mask::xyzw, vu.vf12, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf23, 0(vi10) | miniz.w vf14, vf14, vf01 287 + vu.vf14.mini(Mask::w, vu.vf14, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf23, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf29, vf15, vf05 288 + vu.vf29.mul(Mask::xyzw, vu.vf15, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi06, vi02, vi11 | ftoi4.xyzw vf13, vf13 289 + vu.vf13.ftoi4(Mask::xyzw, vu.vf13); vu.vi06 = vu.vi02 & vu.vi11; + // mfir.x vf22, vi06 | mul.xyz vf15, vf15, Q 290 + vu.vf15.mul(Mask::xyz, vu.vf15, vu.Q); vu.vf22.mfir(Mask::x, vu.vi06); + // sq.xyzw vf19, -12(vi10) | maxy.w vf14, vf14, vf01 291 + vu.vf14.max(Mask::w, vu.vf14, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf19, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L28 | clipw.xyz vf28, vf28 292 + ASSERT(false); cf = clip(vu.vf28, vu.vf28.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf13, -10(vi10) | mul.xyz vf21, vf21, Q 293 + vu.vf21.mul(Mask::xyz, vu.vf21, vu.Q); sq_buffer(Mask::xyzw, vu.vf13, vu.vi10 + -10); + if (bc) { goto L28; } + + L19: + // BRANCH! + // ibeq vi04, vi08, L20 | itof12.xyz vf18, vf22 294 + vu.vf18.itof12(Mask::xyz, vu.vf22); bc = (vu.vi04 == vu.vi08); + // div Q, vf01.x, vf12.w | mulaw.xyzw ACC, vf11, vf00 295 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf12.w(); + if (bc) { goto L20; } + + // nop | addw.w vf14, vf14, vf01 296 + vu.vf14.add(Mask::w, vu.vf14, vu.vf01.w()); + L20: + // fcand vi01, 0x3ffff | add.xyzw vf15, vf15, vf04 297 + vu.vf15.add(Mask::xyzw, vu.vf15, vu.vf04); ASSERT(false); vu.vi01 = cf & 0x3ffff; + + // BRANCH! + // ibne vi00, vi01, L31 | maddax.xyzw ACC, vf08, vf16 298 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); bc = (vu.vi01 != 0); + // mtir vi03, vf23.x | madday.xyzw ACC, vf09, vf16 299 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi03 = vu.vf23.x_as_u16(); + if (bc) { goto L31; } + + L21: + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf13, vf10, vf16 300 + vu.acc.madd(Mask::xyzw, vu.vf13, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf24, 0(vi10) | miniz.w vf15, vf15, vf01 301 + vu.vf15.mini(Mask::w, vu.vf15, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf24, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf26, vf12, vf05 302 + vu.vf26.mul(Mask::xyzw, vu.vf12, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi07, vi03, vi11 | ftoi4.xyzw vf14, vf14 303 + vu.vf14.ftoi4(Mask::xyzw, vu.vf14); vu.vi07 = vu.vi03 & vu.vi11; + // mfir.x vf23, vi07 | mul.xyz vf12, vf12, Q 304 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); vu.vf23.mfir(Mask::x, vu.vi07); + // sq.xyzw vf20, -12(vi10) | maxy.w vf15, vf15, vf01 305 + vu.vf15.max(Mask::w, vu.vf15, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf20, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L28 | clipw.xyz vf29, vf29 306 + ASSERT(false); cf = clip(vu.vf29, vu.vf29.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf14, -10(vi10) | mul.xyz vf18, vf18, Q 307 + vu.vf18.mul(Mask::xyz, vu.vf18, vu.Q); sq_buffer(Mask::xyzw, vu.vf14, vu.vi10 + -10); + if (bc) { goto L28; } + + // BRANCH! + // ibeq vi05, vi09, L22 | itof12.xyz vf19, vf23 308 + vu.vf19.itof12(Mask::xyz, vu.vf23); bc = (vu.vi05 == vu.vi09); + // div Q, vf01.x, vf13.w | mulaw.xyzw ACC, vf11, vf00 309 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf13.w(); + if (bc) { goto L22; } + + // nop | addw.w vf15, vf15, vf01 310 + vu.vf15.add(Mask::w, vu.vf15, vu.vf01.w()); + L22: + // fcand vi01, 0x3ffff | add.xyzw vf12, vf12, vf04 311 + vu.vf12.add(Mask::xyzw, vu.vf12, vu.vf04); ASSERT(false); vu.vi01 = cf & 0x3ffff; + + // BRANCH! + // ibne vi00, vi01, L32 | maddax.xyzw ACC, vf08, vf16 312 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); bc = (vu.vi01 != 0); + // mtir vi04, vf24.x | madday.xyzw ACC, vf09, vf16 313 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi04 = vu.vf24.x_as_u16(); + if (bc) { goto L32; } + + L23: + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf14, vf10, vf16 314 + vu.acc.madd(Mask::xyzw, vu.vf14, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf25, 0(vi10) | miniz.w vf12, vf12, vf01 315 + vu.vf12.mini(Mask::w, vu.vf12, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf25, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf27, vf13, vf05 316 + vu.vf27.mul(Mask::xyzw, vu.vf13, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi08, vi04, vi11 | ftoi4.xyzw vf15, vf15 317 + vu.vf15.ftoi4(Mask::xyzw, vu.vf15); vu.vi08 = vu.vi04 & vu.vi11; + // mfir.x vf24, vi08 | mul.xyz vf13, vf13, Q 318 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); vu.vf24.mfir(Mask::x, vu.vi08); + // sq.xyzw vf21, -12(vi10) | maxy.w vf12, vf12, vf01 319 + vu.vf12.max(Mask::w, vu.vf12, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf21, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L28 | clipw.xyz vf26, vf26 320 + ASSERT(false); cf = clip(vu.vf26, vu.vf26.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf15, -10(vi10) | mul.xyz vf19, vf19, Q 321 + vu.vf19.mul(Mask::xyz, vu.vf19, vu.Q); sq_buffer(Mask::xyzw, vu.vf15, vu.vi10 + -10); + if (bc) { goto L28; } + + // BRANCH! + // ibeq vi02, vi06, L24 | itof12.xyz vf20, vf24 322 + vu.vf20.itof12(Mask::xyz, vu.vf24); bc = (vu.vi02 == vu.vi06); + // div Q, vf01.x, vf14.w | mulaw.xyzw ACC, vf11, vf00 323 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf14.w(); + if (bc) { goto L24; } + + // nop | addw.w vf12, vf12, vf01 324 + vu.vf12.add(Mask::w, vu.vf12, vu.vf01.w()); + L24: + // fcand vi01, 0x3ffff | add.xyzw vf13, vf13, vf04 325 + vu.vf13.add(Mask::xyzw, vu.vf13, vu.vf04); ASSERT(false); vu.vi01 = cf & 0x3ffff; + + // BRANCH! + // ibne vi00, vi01, L29 | maddax.xyzw ACC, vf08, vf16 326 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); bc = (vu.vi01 != 0); + // mtir vi05, vf25.x | madday.xyzw ACC, vf09, vf16 327 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi05 = vu.vf25.x_as_u16(); + if (bc) { goto L29; } + + L25: + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf15, vf10, vf16 328 + vu.acc.madd(Mask::xyzw, vu.vf15, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf22, 0(vi10) | miniz.w vf13, vf13, vf01 329 + vu.vf13.mini(Mask::w, vu.vf13, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf22, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf28, vf14, vf05 330 + vu.vf28.mul(Mask::xyzw, vu.vf14, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi09, vi05, vi11 | ftoi4.xyzw vf12, vf12 331 + vu.vf12.ftoi4(Mask::xyzw, vu.vf12); vu.vi09 = vu.vi05 & vu.vi11; + // mfir.x vf25, vi09 | mul.xyz vf14, vf14, Q 332 + vu.vf14.mul(Mask::xyz, vu.vf14, vu.Q); vu.vf25.mfir(Mask::x, vu.vi09); + // sq.xyzw vf18, -12(vi10) | maxy.w vf13, vf13, vf01 333 + vu.vf13.max(Mask::w, vu.vf13, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf18, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L28 | clipw.xyz vf27, vf27 334 + ASSERT(false); cf = clip(vu.vf27, vu.vf27.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf12, -10(vi10) | mul.xyz vf20, vf20, Q 335 + vu.vf20.mul(Mask::xyz, vu.vf20, vu.Q); sq_buffer(Mask::xyzw, vu.vf12, vu.vi10 + -10); + if (bc) { goto L28; } + + // BRANCH! + // ibeq vi03, vi07, L26 | itof12.xyz vf21, vf25 336 + vu.vf21.itof12(Mask::xyz, vu.vf25); bc = (vu.vi03 == vu.vi07); + // div Q, vf01.x, vf15.w | mulaw.xyzw ACC, vf11, vf00 337 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf15.w(); + if (bc) { goto L26; } + + // nop | addw.w vf13, vf13, vf01 338 + vu.vf13.add(Mask::w, vu.vf13, vu.vf01.w()); + L26: + // fcand vi01, 0x3ffff | add.xyzw vf14, vf14, vf04 339 + vu.vf14.add(Mask::xyzw, vu.vf14, vu.vf04); ASSERT(false); vu.vi01 = cf & 0x3ffff; + + // BRANCH! + // ibne vi00, vi01, L30 | maddax.xyzw ACC, vf08, vf16 340 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); bc = (vu.vi01 != 0); + // mtir vi02, vf22.x | madday.xyzw ACC, vf09, vf16 341 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi02 = vu.vf22.x_as_u16(); + if (bc) { goto L30; } + + L27: + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf12, vf10, vf16 342 + vu.acc.madd(Mask::xyzw, vu.vf12, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf23, 0(vi10) | miniz.w vf14, vf14, vf01 343 + vu.vf14.mini(Mask::w, vu.vf14, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf23, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf29, vf15, vf05 344 + vu.vf29.mul(Mask::xyzw, vu.vf15, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi06, vi02, vi11 | ftoi4.xyzw vf13, vf13 345 + vu.vf13.ftoi4(Mask::xyzw, vu.vf13); vu.vi06 = vu.vi02 & vu.vi11; + // mfir.x vf22, vi06 | mul.xyz vf15, vf15, Q 346 + vu.vf15.mul(Mask::xyz, vu.vf15, vu.Q); vu.vf22.mfir(Mask::x, vu.vi06); + // sq.xyzw vf19, -12(vi10) | maxy.w vf14, vf14, vf01 347 + vu.vf14.max(Mask::w, vu.vf14, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf19, vu.vi10 + -12); + // BRANCH! + // ibne vi14, vi10, L19 | clipw.xyz vf28, vf28 348 + ASSERT(false); cf = clip(vu.vf28, vu.vf28.w(), cf); bc = (vu.vi14 != vu.vi10); + // sq.xyzw vf13, -10(vi10) | mul.xyz vf21, vf21, Q 349 + vu.vf21.mul(Mask::xyz, vu.vf21, vu.Q); sq_buffer(Mask::xyzw, vu.vf13, vu.vi10 + -10); + if (bc) { goto L19; } + + L28: + // BRANCH! + // b L82 | nop 350 + bc = true; + // ilw.w vi12, 906(vi00) | nop 351 + ilw_buffer(Mask::w, vu.vi12, 906); + if (bc) { goto L82; } + + L29: + // BRANCH! + // b L25 | addw.w vf12, vf12, vf01 352 + vu.vf12.add(Mask::w, vu.vf12, vu.vf01.w()); bc = true; + // nop | nop 353 + + if (bc) { goto L25; } + + L30: + // BRANCH! + // b L27 | addw.w vf13, vf13, vf01 354 + vu.vf13.add(Mask::w, vu.vf13, vu.vf01.w()); bc = true; + // nop | nop 355 + + if (bc) { goto L27; } + + L31: + // BRANCH! + // b L21 | addw.w vf14, vf14, vf01 356 + vu.vf14.add(Mask::w, vu.vf14, vu.vf01.w()); bc = true; + // nop | nop 357 + + if (bc) { goto L21; } + + L32: + // BRANCH! + // b L23 | addw.w vf15, vf15, vf01 358 + vu.vf15.add(Mask::w, vu.vf15, vu.vf01.w()); bc = true; + // nop | nop 359 + + if (bc) { goto L23; } + + L33: + // isubiu vi02, vi13, 0x363 | addw.z vf22, vf00, vf00 360 + vu.vf22.add(Mask::z, vu.vf00, vu.vf00.w()); vu.vi02 = vu.vi13 - 0x363; /* 867 */ + // iaddiu vi13, vi13, 0x1e | addw.z vf23, vf00, vf00 361 + vu.vf23.add(Mask::z, vu.vf00, vu.vf00.w()); vu.vi13 = vu.vi13 + 0x1e; /* 30 */ + // BRANCH! + // ibne vi00, vi02, L34 | addw.z vf24, vf00, vf00 362 + vu.vf24.add(Mask::z, vu.vf00, vu.vf00.w()); bc = (vu.vi02 != 0); + // nop | addw.z vf25, vf00, vf00 363 + vu.vf25.add(Mask::z, vu.vf00, vu.vf00.w()); + if (bc) { goto L34; } + + // iaddiu vi13, vi00, 0x345 | nop 364 + vu.vi13 = 0x345; /* 837 */ + L34: + // iaddi vi03, vi13, 0x7 | nop 365 + vu.vi03 = vu.vi13 + 7; + // ilw.w vi01, 5(vi13) | nop 366 + ilw_buffer(Mask::w, vu.vi01, vu.vi13 + 5); + // isw.x vi03, 906(vi00) | nop 367 + isw_buffer(Mask::x, vu.vi03, 906); + // iaddi vi10, vi12, 0x9 | subw.w vf18, vf00, vf00 368 + vu.vf18.sub(Mask::w, vu.vf00, vu.vf00.w()); vu.vi10 = vu.vi12 + 9; + // lq.xyzw vf08, 0(vi13) | subw.w vf19, vf00, vf00 369 + vu.vf19.sub(Mask::w, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf08, vu.vi13); + // lq.xyzw vf09, 1(vi13) | subw.w vf20, vf00, vf00 370 + vu.vf20.sub(Mask::w, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf09, vu.vi13 + 1); + // lq.xyzw vf10, 2(vi13) | subw.w vf21, vf00, vf00 371 + vu.vf21.sub(Mask::w, vu.vf00, vu.vf00.w()); lq_buffer(Mask::xyzw, vu.vf10, vu.vi13 + 2); + // lq.xyzw vf11, 3(vi13) | ftoi12.z vf22, vf22 372 + vu.vf22.ftoi12(Mask::z, vu.vf22); lq_buffer(Mask::xyzw, vu.vf11, vu.vi13 + 3); + // iadd vi02, vi01, vi01 | ftoi12.z vf23, vf23 373 + vu.vf23.ftoi12(Mask::z, vu.vf23); vu.vi02 = vu.vi01 + vu.vi01; + // iadd vi01, vi01, vi02 | sub.xyzw vf16, vf16, vf16 374 + vu.vf16.set_zero(); vu.vi01 = vu.vi01 + vu.vi02; + // iaddi vi11, vi00, -0x2 | nop 375 + vu.vi11 = -2; + // iadd vi14, vi10, vi01 | ftoi12.z vf24, vf24 376 + vu.vf24.ftoi12(Mask::z, vu.vf24); vu.vi14 = vu.vi10 + vu.vi01; + // isw.w vi12, 906(vi00) | ftoi12.z vf25, vf25 377 + vu.vf25.ftoi12(Mask::z, vu.vf25); isw_buffer(Mask::w, vu.vi12, 906); + // iaddi vi14, vi14, 0x9 | nop 378 + vu.vi14 = vu.vi14 + 9; + // lq.xy vf22, 0(vi10) | nop 379 + lq_buffer(Mask::xy, vu.vf22, vu.vi10); + // lq.xyz vf16, 2(vi10) | nop 380 + lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // nop | nop 381 + + // nop | nop 382 + + // nop | mulaw.xyzw ACC, vf11, vf00 383 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); + // mtir vi02, vf22.x | maddax.xyzw ACC, vf08, vf16 384 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); vu.vi02 = vu.vf22.x_as_u16(); + // iaddi vi10, vi10, 0x3 | madday.xyzw ACC, vf09, vf16 385 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf23, 0(vi10) | maddz.xyzw vf12, vf10, vf16 386 + vu.acc.madd(Mask::xyzw, vu.vf12, vu.vf10, vu.vf16.z()); lq_buffer(Mask::xy, vu.vf23, vu.vi10); + // lq.xyz vf16, 2(vi10) | nop 387 + lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi06, vi02, vi11 | nop 388 + vu.vi06 = vu.vi02 & vu.vi11; + // mfir.x vf22, vi06 | nop 389 + vu.vf22.mfir(Mask::x, vu.vi06); + // nop | nop 390 + + // nop | nop 391 + + // nop | nop 392 + + // nop | itof12.xyz vf18, vf22 393 + vu.vf18.itof12(Mask::xyz, vu.vf22); + // div Q, vf01.x, vf12.w | mul.xyzw vf26, vf12, vf05 394 + vu.vf26.mul(Mask::xyzw, vu.vf12, vu.vf05); vu.Q = vu.vf01.x() / vu.vf12.w(); + // nop | nop 395 + + // nop | mulaw.xyzw ACC, vf11, vf00 396 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); + // mtir vi03, vf23.x | maddax.xyzw ACC, vf08, vf16 397 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); vu.vi03 = vu.vf23.x_as_u16(); + // iaddi vi10, vi10, 0x3 | madday.xyzw ACC, vf09, vf16 398 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf24, 0(vi10) | maddz.xyzw vf13, vf10, vf16 399 + vu.acc.madd(Mask::xyzw, vu.vf13, vu.vf10, vu.vf16.z()); lq_buffer(Mask::xy, vu.vf24, vu.vi10); + // lq.xyz vf16, 2(vi10) | nop 400 + lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi07, vi03, vi11 | nop 401 + vu.vi07 = vu.vi03 & vu.vi11; + // mfir.x vf23, vi07 | mul.xyz vf12, vf12, Q 402 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); vu.vf23.mfir(Mask::x, vu.vi07); + // fcset 0x0 | nop 403 + cf = 0; + // nop | nop 404 + + // nop | mul.xyz vf18, vf18, Q 405 + vu.vf18.mul(Mask::xyz, vu.vf18, vu.Q); + // nop | itof12.xyz vf19, vf23 406 + vu.vf19.itof12(Mask::xyz, vu.vf23); + // div Q, vf01.x, vf13.w | mulaw.xyzw ACC, vf11, vf00 407 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf13.w(); + // nop | add.xyzw vf12, vf12, vf04 408 + vu.vf12.add(Mask::xyzw, vu.vf12, vu.vf04); + // nop | maddax.xyzw ACC, vf08, vf16 409 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); + // mtir vi04, vf24.x | madday.xyzw ACC, vf09, vf16 410 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi04 = vu.vf24.x_as_u16(); + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf14, vf10, vf16 411 + vu.acc.madd(Mask::xyzw, vu.vf14, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf25, 0(vi10) | miniz.w vf12, vf12, vf01 412 + vu.vf12.mini(Mask::w, vu.vf12, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf25, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf27, vf13, vf05 413 + vu.vf27.mul(Mask::xyzw, vu.vf13, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi08, vi04, vi11 | nop 414 + vu.vi08 = vu.vi04 & vu.vi11; + // mfir.x vf24, vi08 | mul.xyz vf13, vf13, Q 415 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); vu.vf24.mfir(Mask::x, vu.vi08); + // nop | maxy.w vf12, vf12, vf01 416 + vu.vf12.max(Mask::w, vu.vf12, vu.vf01.y()); + // nop | clipw.xyz vf26, vf26 417 + cf = clip(vu.vf26, vu.vf26.w(), cf); + // nop | mul.xyz vf19, vf19, Q 418 + vu.vf19.mul(Mask::xyz, vu.vf19, vu.Q); + // BRANCH! + // ibeq vi02, vi06, L35 | itof12.xyz vf20, vf24 419 + vu.vf20.itof12(Mask::xyz, vu.vf24); bc = (vu.vi02 == vu.vi06); + // div Q, vf01.x, vf14.w | mulaw.xyzw ACC, vf11, vf00 420 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf14.w(); + if (bc) { goto L35; } + + // nop | addw.w vf12, vf12, vf01 421 + vu.vf12.add(Mask::w, vu.vf12, vu.vf01.w()); + L35: + // nop | add.xyzw vf13, vf13, vf04 422 + vu.vf13.add(Mask::xyzw, vu.vf13, vu.vf04); + // nop | maddax.xyzw ACC, vf08, vf16 423 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); + // mtir vi05, vf25.x | madday.xyzw ACC, vf09, vf16 424 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi05 = vu.vf25.x_as_u16(); + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf15, vf10, vf16 425 + vu.acc.madd(Mask::xyzw, vu.vf15, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf22, 0(vi10) | miniz.w vf13, vf13, vf01 426 + vu.vf13.mini(Mask::w, vu.vf13, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf22, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf28, vf14, vf05 427 + vu.vf28.mul(Mask::xyzw, vu.vf14, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi09, vi05, vi11 | ftoi4.xyzw vf12, vf12 428 + vu.vf12.ftoi4(Mask::xyzw, vu.vf12); vu.vi09 = vu.vi05 & vu.vi11; + // mfir.x vf25, vi09 | mul.xyz vf14, vf14, Q 429 + vu.vf14.mul(Mask::xyz, vu.vf14, vu.Q); vu.vf25.mfir(Mask::x, vu.vi09); + // sq.xyzw vf18, -12(vi10) | maxy.w vf13, vf13, vf01 430 + vu.vf13.max(Mask::w, vu.vf13, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf18, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L46 | clipw.xyz vf27, vf27 431 + cf = clip(vu.vf27, vu.vf27.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf12, -10(vi10) | mul.xyz vf20, vf20, Q 432 + vu.vf20.mul(Mask::xyz, vu.vf20, vu.Q); sq_buffer(Mask::xyzw, vu.vf12, vu.vi10 + -10); + if (bc) { goto L46; } + + // BRANCH! + // ibeq vi03, vi07, L36 | itof12.xyz vf21, vf25 433 + vu.vf21.itof12(Mask::xyz, vu.vf25); bc = (vu.vi03 == vu.vi07); + // div Q, vf01.x, vf15.w | mulaw.xyzw ACC, vf11, vf00 434 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf15.w(); + if (bc) { goto L36; } + + // nop | addw.w vf13, vf13, vf01 435 + vu.vf13.add(Mask::w, vu.vf13, vu.vf01.w()); + L36: + // nop | add.xyzw vf14, vf14, vf04 436 + vu.vf14.add(Mask::xyzw, vu.vf14, vu.vf04); + // nop | maddax.xyzw ACC, vf08, vf16 437 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); + // mtir vi02, vf22.x | madday.xyzw ACC, vf09, vf16 438 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi02 = vu.vf22.x_as_u16(); + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf12, vf10, vf16 439 + vu.acc.madd(Mask::xyzw, vu.vf12, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf23, 0(vi10) | miniz.w vf14, vf14, vf01 440 + vu.vf14.mini(Mask::w, vu.vf14, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf23, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf29, vf15, vf05 441 + vu.vf29.mul(Mask::xyzw, vu.vf15, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi06, vi02, vi11 | ftoi4.xyzw vf13, vf13 442 + vu.vf13.ftoi4(Mask::xyzw, vu.vf13); vu.vi06 = vu.vi02 & vu.vi11; + // mfir.x vf22, vi06 | mul.xyz vf15, vf15, Q 443 + vu.vf15.mul(Mask::xyz, vu.vf15, vu.Q); vu.vf22.mfir(Mask::x, vu.vi06); + // sq.xyzw vf19, -12(vi10) | maxy.w vf14, vf14, vf01 444 + vu.vf14.max(Mask::w, vu.vf14, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf19, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L46 | clipw.xyz vf28, vf28 445 + cf = clip(vu.vf28, vu.vf28.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf13, -10(vi10) | mul.xyz vf21, vf21, Q 446 + vu.vf21.mul(Mask::xyz, vu.vf21, vu.Q); sq_buffer(Mask::xyzw, vu.vf13, vu.vi10 + -10); + if (bc) { goto L46; } + + L37: + // BRANCH! + // ibeq vi04, vi08, L38 | itof12.xyz vf18, vf22 447 + vu.vf18.itof12(Mask::xyz, vu.vf22); bc = (vu.vi04 == vu.vi08); + // div Q, vf01.x, vf12.w | mulaw.xyzw ACC, vf11, vf00 448 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf12.w(); + if (bc) { goto L38; } + + // nop | addw.w vf14, vf14, vf01 449 + vu.vf14.add(Mask::w, vu.vf14, vu.vf01.w()); + L38: + // fcand vi01, 0x3ffff | add.xyzw vf15, vf15, vf04 450 + vu.vf15.add(Mask::xyzw, vu.vf15, vu.vf04); vu.vi01 = cf & 0x3ffff; + + // BRANCH! + // ibne vi00, vi01, L55 | maddax.xyzw ACC, vf08, vf16 451 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); bc = (vu.vi01 != 0); + // mtir vi03, vf23.x | madday.xyzw ACC, vf09, vf16 452 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi03 = vu.vf23.x_as_u16(); + if (bc) { goto L55; } + + L39: + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf13, vf10, vf16 453 + vu.acc.madd(Mask::xyzw, vu.vf13, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf24, 0(vi10) | miniz.w vf15, vf15, vf01 454 + vu.vf15.mini(Mask::w, vu.vf15, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf24, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf26, vf12, vf05 455 + vu.vf26.mul(Mask::xyzw, vu.vf12, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi07, vi03, vi11 | ftoi4.xyzw vf14, vf14 456 + vu.vf14.ftoi4(Mask::xyzw, vu.vf14); vu.vi07 = vu.vi03 & vu.vi11; + // mfir.x vf23, vi07 | mul.xyz vf12, vf12, Q 457 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); vu.vf23.mfir(Mask::x, vu.vi07); + // sq.xyzw vf20, -12(vi10) | maxy.w vf15, vf15, vf01 458 + vu.vf15.max(Mask::w, vu.vf15, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf20, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L46 | clipw.xyz vf29, vf29 459 + cf = clip(vu.vf29, vu.vf29.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf14, -10(vi10) | mul.xyz vf18, vf18, Q 460 + vu.vf18.mul(Mask::xyz, vu.vf18, vu.Q); sq_buffer(Mask::xyzw, vu.vf14, vu.vi10 + -10); + if (bc) { goto L46; } + + // BRANCH! + // ibeq vi05, vi09, L40 | itof12.xyz vf19, vf23 461 + vu.vf19.itof12(Mask::xyz, vu.vf23); bc = (vu.vi05 == vu.vi09); + // div Q, vf01.x, vf13.w | mulaw.xyzw ACC, vf11, vf00 462 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf13.w(); + if (bc) { goto L40; } + + // nop | addw.w vf15, vf15, vf01 463 + vu.vf15.add(Mask::w, vu.vf15, vu.vf01.w()); + L40: + // fcand vi01, 0x3ffff | add.xyzw vf12, vf12, vf04 464 + vu.vf12.add(Mask::xyzw, vu.vf12, vu.vf04); vu.vi01 = cf & 0x3ffff; + + // BRANCH! + // ibne vi00, vi01, L59 | maddax.xyzw ACC, vf08, vf16 465 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); bc = (vu.vi01 != 0); + // mtir vi04, vf24.x | madday.xyzw ACC, vf09, vf16 466 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi04 = vu.vf24.x_as_u16(); + if (bc) { goto L59; } + + L41: + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf14, vf10, vf16 467 + vu.acc.madd(Mask::xyzw, vu.vf14, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf25, 0(vi10) | miniz.w vf12, vf12, vf01 468 + vu.vf12.mini(Mask::w, vu.vf12, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf25, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf27, vf13, vf05 469 + vu.vf27.mul(Mask::xyzw, vu.vf13, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi08, vi04, vi11 | ftoi4.xyzw vf15, vf15 470 + vu.vf15.ftoi4(Mask::xyzw, vu.vf15); vu.vi08 = vu.vi04 & vu.vi11; + // mfir.x vf24, vi08 | mul.xyz vf13, vf13, Q 471 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); vu.vf24.mfir(Mask::x, vu.vi08); + // sq.xyzw vf21, -12(vi10) | maxy.w vf12, vf12, vf01 472 + vu.vf12.max(Mask::w, vu.vf12, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf21, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L46 | clipw.xyz vf26, vf26 473 + cf = clip(vu.vf26, vu.vf26.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf15, -10(vi10) | mul.xyz vf19, vf19, Q 474 + vu.vf19.mul(Mask::xyz, vu.vf19, vu.Q); sq_buffer(Mask::xyzw, vu.vf15, vu.vi10 + -10); + if (bc) { goto L46; } + + // BRANCH! + // ibeq vi02, vi06, L42 | itof12.xyz vf20, vf24 475 + vu.vf20.itof12(Mask::xyz, vu.vf24); bc = (vu.vi02 == vu.vi06); + // div Q, vf01.x, vf14.w | mulaw.xyzw ACC, vf11, vf00 476 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf14.w(); + if (bc) { goto L42; } + + // nop | addw.w vf12, vf12, vf01 477 + vu.vf12.add(Mask::w, vu.vf12, vu.vf01.w()); + L42: + // fcand vi01, 0x3ffff | add.xyzw vf13, vf13, vf04 478 + vu.vf13.add(Mask::xyzw, vu.vf13, vu.vf04); vu.vi01 = cf & 0x3ffff; + + // BRANCH! + // ibne vi00, vi01, L47 | maddax.xyzw ACC, vf08, vf16 479 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); bc = (vu.vi01 != 0); + // mtir vi05, vf25.x | madday.xyzw ACC, vf09, vf16 480 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi05 = vu.vf25.x_as_u16(); + if (bc) { goto L47; } + + L43: + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf15, vf10, vf16 481 + vu.acc.madd(Mask::xyzw, vu.vf15, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf22, 0(vi10) | miniz.w vf13, vf13, vf01 482 + vu.vf13.mini(Mask::w, vu.vf13, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf22, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf28, vf14, vf05 483 + vu.vf28.mul(Mask::xyzw, vu.vf14, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi09, vi05, vi11 | ftoi4.xyzw vf12, vf12 484 + vu.vf12.ftoi4(Mask::xyzw, vu.vf12); vu.vi09 = vu.vi05 & vu.vi11; + // mfir.x vf25, vi09 | mul.xyz vf14, vf14, Q 485 + vu.vf14.mul(Mask::xyz, vu.vf14, vu.Q); vu.vf25.mfir(Mask::x, vu.vi09); + // sq.xyzw vf18, -12(vi10) | maxy.w vf13, vf13, vf01 486 + vu.vf13.max(Mask::w, vu.vf13, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf18, vu.vi10 + -12); + // BRANCH! + // ibeq vi14, vi10, L46 | clipw.xyz vf27, vf27 487 + cf = clip(vu.vf27, vu.vf27.w(), cf); bc = (vu.vi14 == vu.vi10); + // sq.xyzw vf12, -10(vi10) | mul.xyz vf20, vf20, Q 488 + vu.vf20.mul(Mask::xyz, vu.vf20, vu.Q); sq_buffer(Mask::xyzw, vu.vf12, vu.vi10 + -10); + if (bc) { goto L46; } + + // BRANCH! + // ibeq vi03, vi07, L44 | itof12.xyz vf21, vf25 489 + vu.vf21.itof12(Mask::xyz, vu.vf25); bc = (vu.vi03 == vu.vi07); + // div Q, vf01.x, vf15.w | mulaw.xyzw ACC, vf11, vf00 490 + vu.acc.mula(Mask::xyzw, vu.vf11, vu.vf00.w()); vu.Q = vu.vf01.x() / vu.vf15.w(); + if (bc) { goto L44; } + + // nop | addw.w vf13, vf13, vf01 491 + vu.vf13.add(Mask::w, vu.vf13, vu.vf01.w()); + L44: + // fcand vi01, 0x3ffff | add.xyzw vf14, vf14, vf04 492 + vu.vf14.add(Mask::xyzw, vu.vf14, vu.vf04); vu.vi01 = cf & 0x3ffff; + + // BRANCH! + // ibne vi00, vi01, L51 | maddax.xyzw ACC, vf08, vf16 493 + vu.acc.madda(Mask::xyzw, vu.vf08, vu.vf16.x()); bc = (vu.vi01 != 0); + // mtir vi02, vf22.x | madday.xyzw ACC, vf09, vf16 494 + vu.acc.madda(Mask::xyzw, vu.vf09, vu.vf16.y()); vu.vi02 = vu.vf22.x_as_u16(); + if (bc) { goto L51; } + + L45: + // iaddi vi10, vi10, 0x3 | maddz.xyzw vf12, vf10, vf16 495 + vu.acc.madd(Mask::xyzw, vu.vf12, vu.vf10, vu.vf16.z()); vu.vi10 = vu.vi10 + 3; + // lq.xy vf23, 0(vi10) | miniz.w vf14, vf14, vf01 496 + vu.vf14.mini(Mask::w, vu.vf14, vu.vf01.z()); lq_buffer(Mask::xy, vu.vf23, vu.vi10); + // lq.xyz vf16, 2(vi10) | mul.xyzw vf29, vf15, vf05 497 + vu.vf29.mul(Mask::xyzw, vu.vf15, vu.vf05); lq_buffer(Mask::xyz, vu.vf16, vu.vi10 + 2); + // iand vi06, vi02, vi11 | ftoi4.xyzw vf13, vf13 498 + vu.vf13.ftoi4(Mask::xyzw, vu.vf13); vu.vi06 = vu.vi02 & vu.vi11; + // mfir.x vf22, vi06 | mul.xyz vf15, vf15, Q 499 + vu.vf15.mul(Mask::xyz, vu.vf15, vu.Q); vu.vf22.mfir(Mask::x, vu.vi06); + // sq.xyzw vf19, -12(vi10) | maxy.w vf14, vf14, vf01 500 + vu.vf14.max(Mask::w, vu.vf14, vu.vf01.y()); sq_buffer(Mask::xyzw, vu.vf19, vu.vi10 + -12); + // BRANCH! + // ibne vi14, vi10, L37 | clipw.xyz vf28, vf28 501 + cf = clip(vu.vf28, vu.vf28.w(), cf); bc = (vu.vi14 != vu.vi10); + // sq.xyzw vf13, -10(vi10) | mul.xyz vf21, vf21, Q 502 + vu.vf21.mul(Mask::xyz, vu.vf21, vu.Q); sq_buffer(Mask::xyzw, vu.vf13, vu.vi10 + -10); + if (bc) { goto L37; } + + L46: + // BRANCH! + // b L82 | nop 503 + bc = true; + // ilw.w vi12, 906(vi00) | nop 504 + ilw_buffer(Mask::w, vu.vi12, 906); + if (bc) { goto L82; } + + L47: + // BRANCH! + // ibne vi02, vi06, L43 | nop 505 + bc = (vu.vi02 != vu.vi06); + // sq.xyzw vf23, 998(vi00) | addw.w vf12, vf12, vf01 506 + vu.vf12.add(Mask::w, vu.vf12, vu.vf01.w()); sq_buffer(Mask::xyzw, vu.vf23, 998); + if (bc) { goto L43; } + + // sq.xyzw vf24, 999(vi00) | mul.xyzw vf23, vf28, vf07 507 + vu.vf23.mul(Mask::xyzw, vu.vf28, vu.vf07); sq_buffer(Mask::xyzw, vu.vf24, 999); + // sq.xyzw vf25, 1000(vi00) | mul.xyzw vf24, vf29, vf07 508 + vu.vf24.mul(Mask::xyzw, vu.vf29, vu.vf07); sq_buffer(Mask::xyzw, vu.vf25, 1000); + // isw.x vi01, 1001(vi00) | mul.xyzw vf25, vf26, vf07 509 + vu.vf25.mul(Mask::xyzw, vu.vf26, vu.vf07); isw_buffer(Mask::x, vu.vi01, 1001); + // isw.y vi02, 1001(vi00) | nop 510 + isw_buffer(Mask::y, vu.vi02, 1001); + // isw.z vi03, 1001(vi00) | clipw.xyz vf23, vf23 511 + // TODO: check clipping pipeline here. + cf0 = clip(vu.vf23, vu.vf23.w(), cf); isw_buffer(Mask::z, vu.vi03, 1001); + // isw.w vi04, 1001(vi00) | clipw.xyz vf24, vf24 512 + cf1 = clip(vu.vf24, vu.vf24.w(), cf0); isw_buffer(Mask::w, vu.vi04, 1001); + // mfir.x vf31, vi05 | clipw.xyz vf25, vf25 513 + cf2 = clip(vu.vf25, vu.vf25.w(), cf1); vu.vf31.mfir(Mask::x, vu.vi05); + // iaddiu vi04, vi00, 0x3f | nop 514 + vu.vi04 = 0x3f; /* 63 */ + // fcget vi01 | nop 515 + vu.vi01 = cf0; + // fcget vi02 | nop 516 + vu.vi02 = cf1; + // fcget vi03 | nop 517 + vu.vi03 = cf2; + cf = cf2; + // iand vi01, vi01, vi04 | clipw.xyz vf28, vf28 518 + // TODO, is this right? + cf = clip(vu.vf28, vu.vf28.w(), cf); vu.vi01 = vu.vi01 & vu.vi04; + // iand vi01, vi01, vi02 | clipw.xyz vf29, vf29 519 + cf = clip(vu.vf29, vu.vf29.w(), cf); vu.vi01 = vu.vi01 & vu.vi02; + // iand vi01, vi01, vi03 | clipw.xyz vf26, vf26 520 + cf = clip(vu.vf26, vu.vf26.w(), cf); vu.vi01 = vu.vi01 & vu.vi03; + // mfir.y vf31, vi06 | nop 521 + vu.vf31.mfir(Mask::y, vu.vi06); + // BRANCH! + // ibeq vi00, vi01, L49 | nop 522 + bc = (vu.vi01 == 0); + // mfir.z vf31, vi07 | nop 523 + vu.vf31.mfir(Mask::z, vu.vi07); + if (!clipping_hack && bc) { goto L49; } + + L48: + // div Q, vf01.x, vf14.w | nop 524 + vu.Q = vu.vf01.x() / vu.vf14.w(); + // lq.xyzw vf23, 998(vi00) | nop 525 + lq_buffer(Mask::xyzw, vu.vf23, 998); + // lq.xyzw vf24, 999(vi00) | nop 526 + lq_buffer(Mask::xyzw, vu.vf24, 999); + // lq.xyzw vf25, 1000(vi00) | nop 527 + lq_buffer(Mask::xyzw, vu.vf25, 1000); + // ilw.x vi01, 1001(vi00) | nop 528 + ilw_buffer(Mask::x, vu.vi01, 1001); + // ilw.y vi02, 1001(vi00) | nop 529 + ilw_buffer(Mask::y, vu.vi02, 1001); + // ilw.z vi03, 1001(vi00) | nop 530 + ilw_buffer(Mask::z, vu.vi03, 1001); + // BRANCH! + // b L43 | nop 531 + bc = true; + // ilw.w vi04, 1001(vi00) | nop 532 + ilw_buffer(Mask::w, vu.vi04, 1001); + if (bc) { goto L43; } + + L49: + // mfir.w vf31, vi08 | nop 533 + vu.vf31.mfir(Mask::w, vu.vi08); + // mfir.x vf30, vi09 | nop 534 + vu.vf30.mfir(Mask::x, vu.vi09); + // mfir.y vf30, vi10 | nop 535 + vu.vf30.mfir(Mask::y, vu.vi10); + // mfir.z vf30, vi11 | nop 536 + vu.vf30.mfir(Mask::z, vu.vi11); + // mfir.w vf30, vi12 | nop 537 + vu.vf30.mfir(Mask::w, vu.vi12); + // sq.xyzw vf12, 1004(vi00) | nop 538 + sq_buffer(Mask::xyzw, vu.vf12, 1004); + // lq.xyzw vf12, -15(vi10) | nop 539 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi10 + -15); + // sq.xyzw vf13, 1005(vi00) | nop 540 + sq_buffer(Mask::xyzw, vu.vf13, 1005); + // lq.xyzw vf13, -12(vi10) | nop 541 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi10 + -12); + // sq.xyzw vf14, 1006(vi00) | nop 542 + sq_buffer(Mask::xyzw, vu.vf14, 1006); + // div Q, vf00.w, vf12.z | nop 543 + vu.Q = vu.vf00.w() / vu.vf12.z(); + // sq.xyzw vf31, 1002(vi00) | nop 544 + sq_buffer(Mask::xyzw, vu.vf31, 1002); + // sq.xyzw vf30, 1003(vi00) | nop 545 + sq_buffer(Mask::xyzw, vu.vf30, 1003); + // sq.xyzw vf15, 1007(vi00) | nop 546 + sq_buffer(Mask::xyzw, vu.vf15, 1007); + // sq.xyzw vf16, 1008(vi00) | nop 547 + sq_buffer(Mask::xyzw, vu.vf16, 1008); + // lq.xyzw vf03, 4(vi13) | nop 548 + lq_buffer(Mask::xyzw, vu.vf03, vu.vi13 + 4); + // lq.xyzw vf15, -14(vi10) | sub.xw vf31, vf00, vf00 549 + vu.vf31.sub(Mask::xw, vu.vf00, vu.vf00); lq_buffer(Mask::xyzw, vu.vf15, vu.vi10 + -14); + // div Q, vf00.w, vf13.z | nop 550 + vu.Q = vu.vf00.w() / vu.vf13.z(); + // lq.xyzw vf16, -11(vi10) | mul.xyz vf12, vf12, Q 551 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); lq_buffer(Mask::xyzw, vu.vf16, vu.vi10 + -11); + // lq.xyzw vf17, -8(vi10) | addx.y vf31, vf00, vf03 552 + vu.vf31.add(Mask::y, vu.vf00, vu.vf03.x()); lq_buffer(Mask::xyzw, vu.vf17, vu.vi10 + -8); + // nop | itof0.xyzw vf15, vf15 553 + vu.vf15.itof0(Mask::xyzw, vu.vf15); + // sq.xyzw vf28, 989(vi00) | nop 554 + sq_buffer(Mask::xyzw, vu.vf28, 989); + // sq.xyzw vf12, 991(vi00) | itof0.xyzw vf16, vf16 555 + vu.vf16.itof0(Mask::xyzw, vu.vf16); sq_buffer(Mask::xyzw, vu.vf12, 991); + // sq.xyzw vf29, 992(vi00) | itof0.xyzw vf17, vf17 556 + vu.vf17.itof0(Mask::xyzw, vu.vf17); sq_buffer(Mask::xyzw, vu.vf29, 992); + // div Q, vf00.w, vf18.z | nop 557 + vu.Q = vu.vf00.w() / vu.vf18.z(); + // nop | mul.xyz vf13, vf13, Q 558 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); + // sq.xyzw vf26, 995(vi00) | nop 559 + sq_buffer(Mask::xyzw, vu.vf26, 995); + // move.z vf31, vf03 | nop 560 + vu.vf31.move(Mask::z, vu.vf03); + // sq.xyzw vf15, 990(vi00) | nop 561 + sq_buffer(Mask::xyzw, vu.vf15, 990); + // sq.xyzw vf16, 993(vi00) | nop 562 + sq_buffer(Mask::xyzw, vu.vf16, 993); + // sq.xyzw vf17, 996(vi00) | nop 563 + sq_buffer(Mask::xyzw, vu.vf17, 996); + // sq.xyzw vf13, 994(vi00) | nop 564 + sq_buffer(Mask::xyzw, vu.vf13, 994); + // sq.xyzw vf31, 961(vi00) | mul.xyz vf14, vf18, Q 565 + vu.vf14.mul(Mask::xyz, vu.vf18, vu.Q); sq_buffer(Mask::xyzw, vu.vf31, 961); + // nop | nop 566 + + // nop | nop 567 + + // BRANCH! + // bal vi15, L66 | nop 568 + ASSERT(false); + // sq.xyzw vf14, 997(vi00) | nop 569 + sq_buffer(Mask::xyzw, vu.vf14, 997); + if (bc) { goto L66; } + + // BRANCH! + // ibeq vi00, vi05, L50 | nop 570 + bc = (vu.vi05 == 0); + // nop | nop 571 + + if (bc) { goto L50; } + + // BRANCH! + // bal vi15, L63 | nop 572 + ASSERT(false); + // nop | nop 573 + + if (bc) { goto L63; } + + L50: + // ilw.x vi05, 1002(vi00) | nop 574 + ilw_buffer(Mask::x, vu.vi05, 1002); + // ilw.y vi06, 1002(vi00) | nop 575 + ilw_buffer(Mask::y, vu.vi06, 1002); + // ilw.z vi07, 1002(vi00) | nop 576 + ilw_buffer(Mask::z, vu.vi07, 1002); + // ilw.w vi08, 1002(vi00) | nop 577 + ilw_buffer(Mask::w, vu.vi08, 1002); + // ilw.x vi09, 1003(vi00) | nop 578 + ilw_buffer(Mask::x, vu.vi09, 1003); + // ilw.y vi10, 1003(vi00) | nop 579 + ilw_buffer(Mask::y, vu.vi10, 1003); + // ilw.z vi11, 1003(vi00) | nop 580 + ilw_buffer(Mask::z, vu.vi11, 1003); + // ilw.w vi12, 1003(vi00) | nop 581 + ilw_buffer(Mask::w, vu.vi12, 1003); + // lq.xyzw vf12, 1004(vi00) | nop 582 + lq_buffer(Mask::xyzw, vu.vf12, 1004); + // lq.xyzw vf13, 1005(vi00) | nop 583 + lq_buffer(Mask::xyzw, vu.vf13, 1005); + // lq.xyzw vf14, 1006(vi00) | nop 584 + lq_buffer(Mask::xyzw, vu.vf14, 1006); + // lq.xyzw vf15, 1007(vi00) | nop 585 + lq_buffer(Mask::xyzw, vu.vf15, 1007); + // BRANCH! + // b L48 | nop 586 + bc = true; + // lq.xyzw vf16, 1008(vi00) | nop 587 + lq_buffer(Mask::xyzw, vu.vf16, 1008); + if (bc) { goto L48; } + + L51: + // BRANCH! + // ibne vi03, vi07, L45 | nop 588 + bc = (vu.vi03 != vu.vi07); + // sq.xyzw vf23, 998(vi00) | addw.w vf13, vf13, vf01 589 + vu.vf13.add(Mask::w, vu.vf13, vu.vf01.w()); sq_buffer(Mask::xyzw, vu.vf23, 998); + if (bc) { goto L45; } + + // sq.xyzw vf24, 999(vi00) | mul.xyzw vf23, vf29, vf07 590 + vu.vf23.mul(Mask::xyzw, vu.vf29, vu.vf07); sq_buffer(Mask::xyzw, vu.vf24, 999); + // sq.xyzw vf25, 1000(vi00) | mul.xyzw vf24, vf26, vf07 591 + vu.vf24.mul(Mask::xyzw, vu.vf26, vu.vf07); sq_buffer(Mask::xyzw, vu.vf25, 1000); + // isw.x vi01, 1001(vi00) | mul.xyzw vf25, vf27, vf07 592 + vu.vf25.mul(Mask::xyzw, vu.vf27, vu.vf07); isw_buffer(Mask::x, vu.vi01, 1001); + // isw.y vi02, 1001(vi00) | nop 593 + isw_buffer(Mask::y, vu.vi02, 1001); + // TODO more clipping pipeline? + // isw.z vi03, 1001(vi00) | clipw.xyz vf23, vf23 594 + cf0 = clip(vu.vf23, vu.vf23.w(), cf); isw_buffer(Mask::z, vu.vi03, 1001); + // isw.w vi04, 1001(vi00) | clipw.xyz vf24, vf24 595 + cf1 = clip(vu.vf24, vu.vf24.w(), cf0); isw_buffer(Mask::w, vu.vi04, 1001); + // mfir.x vf31, vi05 | clipw.xyz vf25, vf25 596 + cf2 = clip(vu.vf25, vu.vf25.w(), cf1); vu.vf31.mfir(Mask::x, vu.vi05); + // iaddiu vi04, vi00, 0x3f | nop 597 + vu.vi04 = 0x3f; /* 63 */ + // fcget vi01 | nop 598 + vu.vi01 = cf0; + // fcget vi02 | nop 599 + vu.vi02 = cf1; + // fcget vi03 | nop 600 + vu.vi03 = cf2; + cf = cf2; + // iand vi01, vi01, vi04 | clipw.xyz vf29, vf29 601 + cf = clip(vu.vf29, vu.vf29.w(), cf); vu.vi01 = vu.vi01 & vu.vi04; + // iand vi01, vi01, vi02 | clipw.xyz vf26, vf26 602 + cf = clip(vu.vf26, vu.vf26.w(), cf); vu.vi01 = vu.vi01 & vu.vi02; + // iand vi01, vi01, vi03 | clipw.xyz vf27, vf27 603 + cf = clip(vu.vf27, vu.vf27.w(), cf); vu.vi01 = vu.vi01 & vu.vi03; + // mfir.y vf31, vi06 | nop 604 + vu.vf31.mfir(Mask::y, vu.vi06); + // BRANCH! + // ibeq vi00, vi01, L53 | nop 605 + bc = (vu.vi01 == 0); + // mfir.z vf31, vi07 | nop 606 + vu.vf31.mfir(Mask::z, vu.vi07); + if (!clipping_hack && bc) { goto L53; } + + L52: + // div Q, vf01.x, vf15.w | nop 607 + vu.Q = vu.vf01.x() / vu.vf15.w(); + // lq.xyzw vf23, 998(vi00) | nop 608 + lq_buffer(Mask::xyzw, vu.vf23, 998); + // lq.xyzw vf24, 999(vi00) | nop 609 + lq_buffer(Mask::xyzw, vu.vf24, 999); + // lq.xyzw vf25, 1000(vi00) | nop 610 + lq_buffer(Mask::xyzw, vu.vf25, 1000); + // ilw.x vi01, 1001(vi00) | nop 611 + ilw_buffer(Mask::x, vu.vi01, 1001); + // ilw.y vi02, 1001(vi00) | nop 612 + ilw_buffer(Mask::y, vu.vi02, 1001); + // ilw.z vi03, 1001(vi00) | nop 613 + ilw_buffer(Mask::z, vu.vi03, 1001); + // BRANCH! + // b L45 | nop 614 + bc = true; + // ilw.w vi04, 1001(vi00) | nop 615 + ilw_buffer(Mask::w, vu.vi04, 1001); + if (bc) { goto L45; } + + L53: + // mfir.w vf31, vi08 | nop 616 + vu.vf31.mfir(Mask::w, vu.vi08); + // mfir.x vf30, vi09 | nop 617 + vu.vf30.mfir(Mask::x, vu.vi09); + // mfir.y vf30, vi10 | nop 618 + vu.vf30.mfir(Mask::y, vu.vi10); + // mfir.z vf30, vi11 | nop 619 + vu.vf30.mfir(Mask::z, vu.vi11); + // mfir.w vf30, vi12 | nop 620 + vu.vf30.mfir(Mask::w, vu.vi12); + // sq.xyzw vf12, 1004(vi00) | nop 621 + sq_buffer(Mask::xyzw, vu.vf12, 1004); + // lq.xyzw vf12, -15(vi10) | nop 622 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi10 + -15); + // sq.xyzw vf13, 1005(vi00) | nop 623 + sq_buffer(Mask::xyzw, vu.vf13, 1005); + // lq.xyzw vf13, -12(vi10) | nop 624 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi10 + -12); + // sq.xyzw vf14, 1006(vi00) | nop 625 + sq_buffer(Mask::xyzw, vu.vf14, 1006); + // div Q, vf00.w, vf12.z | nop 626 + vu.Q = vu.vf00.w() / vu.vf12.z(); + // sq.xyzw vf31, 1002(vi00) | nop 627 + sq_buffer(Mask::xyzw, vu.vf31, 1002); + // sq.xyzw vf30, 1003(vi00) | nop 628 + sq_buffer(Mask::xyzw, vu.vf30, 1003); + // sq.xyzw vf15, 1007(vi00) | nop 629 + sq_buffer(Mask::xyzw, vu.vf15, 1007); + // sq.xyzw vf16, 1008(vi00) | nop 630 + sq_buffer(Mask::xyzw, vu.vf16, 1008); + // lq.xyzw vf03, 4(vi13) | nop 631 + lq_buffer(Mask::xyzw, vu.vf03, vu.vi13 + 4); + // lq.xyzw vf15, -14(vi10) | sub.xw vf31, vf00, vf00 632 + vu.vf31.sub(Mask::xw, vu.vf00, vu.vf00); lq_buffer(Mask::xyzw, vu.vf15, vu.vi10 + -14); + // div Q, vf00.w, vf13.z | nop 633 + vu.Q = vu.vf00.w() / vu.vf13.z(); + // lq.xyzw vf16, -11(vi10) | mul.xyz vf12, vf12, Q 634 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); lq_buffer(Mask::xyzw, vu.vf16, vu.vi10 + -11); + // lq.xyzw vf17, -8(vi10) | addx.y vf31, vf00, vf03 635 + vu.vf31.add(Mask::y, vu.vf00, vu.vf03.x()); lq_buffer(Mask::xyzw, vu.vf17, vu.vi10 + -8); + // nop | itof0.xyzw vf15, vf15 636 + vu.vf15.itof0(Mask::xyzw, vu.vf15); + // sq.xyzw vf29, 989(vi00) | nop 637 + sq_buffer(Mask::xyzw, vu.vf29, 989); + // sq.xyzw vf12, 991(vi00) | itof0.xyzw vf16, vf16 638 + vu.vf16.itof0(Mask::xyzw, vu.vf16); sq_buffer(Mask::xyzw, vu.vf12, 991); + // sq.xyzw vf26, 992(vi00) | itof0.xyzw vf17, vf17 639 + vu.vf17.itof0(Mask::xyzw, vu.vf17); sq_buffer(Mask::xyzw, vu.vf26, 992); + // div Q, vf00.w, vf19.z | nop 640 + vu.Q = vu.vf00.w() / vu.vf19.z(); + // nop | mul.xyz vf13, vf13, Q 641 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); + // sq.xyzw vf27, 995(vi00) | nop 642 + sq_buffer(Mask::xyzw, vu.vf27, 995); + // move.z vf31, vf03 | nop 643 + vu.vf31.move(Mask::z, vu.vf03); + // sq.xyzw vf15, 990(vi00) | nop 644 + sq_buffer(Mask::xyzw, vu.vf15, 990); + // sq.xyzw vf16, 993(vi00) | nop 645 + sq_buffer(Mask::xyzw, vu.vf16, 993); + // sq.xyzw vf17, 996(vi00) | nop 646 + sq_buffer(Mask::xyzw, vu.vf17, 996); + // sq.xyzw vf13, 994(vi00) | nop 647 + sq_buffer(Mask::xyzw, vu.vf13, 994); + // sq.xyzw vf31, 961(vi00) | mul.xyz vf14, vf19, Q 648 + vu.vf14.mul(Mask::xyz, vu.vf19, vu.Q); sq_buffer(Mask::xyzw, vu.vf31, 961); + // nop | nop 649 + + // nop | nop 650 + + // BRANCH! + // bal vi15, L66 | nop 651 + ASSERT(false); + // sq.xyzw vf14, 997(vi00) | nop 652 + sq_buffer(Mask::xyzw, vu.vf14, 997); + if (bc) { goto L66; } + + // BRANCH! + // ibeq vi00, vi05, L54 | nop 653 + bc = (vu.vi05 == 0); + // nop | nop 654 + + if (bc) { goto L54; } + + // BRANCH! + // bal vi15, L63 | nop 655 + ASSERT(false); + // nop | nop 656 + + if (bc) { goto L63; } + + L54: + // ilw.x vi05, 1002(vi00) | nop 657 + ilw_buffer(Mask::x, vu.vi05, 1002); + // ilw.y vi06, 1002(vi00) | nop 658 + ilw_buffer(Mask::y, vu.vi06, 1002); + // ilw.z vi07, 1002(vi00) | nop 659 + ilw_buffer(Mask::z, vu.vi07, 1002); + // ilw.w vi08, 1002(vi00) | nop 660 + ilw_buffer(Mask::w, vu.vi08, 1002); + // ilw.x vi09, 1003(vi00) | nop 661 + ilw_buffer(Mask::x, vu.vi09, 1003); + // ilw.y vi10, 1003(vi00) | nop 662 + ilw_buffer(Mask::y, vu.vi10, 1003); + // ilw.z vi11, 1003(vi00) | nop 663 + ilw_buffer(Mask::z, vu.vi11, 1003); + // ilw.w vi12, 1003(vi00) | nop 664 + ilw_buffer(Mask::w, vu.vi12, 1003); + // lq.xyzw vf12, 1004(vi00) | nop 665 + lq_buffer(Mask::xyzw, vu.vf12, 1004); + // lq.xyzw vf13, 1005(vi00) | nop 666 + lq_buffer(Mask::xyzw, vu.vf13, 1005); + // lq.xyzw vf14, 1006(vi00) | nop 667 + lq_buffer(Mask::xyzw, vu.vf14, 1006); + // lq.xyzw vf15, 1007(vi00) | nop 668 + lq_buffer(Mask::xyzw, vu.vf15, 1007); + // BRANCH! + // b L52 | nop 669 + bc = true; + // lq.xyzw vf16, 1008(vi00) | nop 670 + lq_buffer(Mask::xyzw, vu.vf16, 1008); + if (bc) { goto L52; } + + L55: + // BRANCH! + // ibne vi04, vi08, L39 | nop 671 + bc = (vu.vi04 != vu.vi08); + // sq.xyzw vf23, 998(vi00) | addw.w vf14, vf14, vf01 672 + vu.vf14.add(Mask::w, vu.vf14, vu.vf01.w()); sq_buffer(Mask::xyzw, vu.vf23, 998); + if (bc) { goto L39; } + + // sq.xyzw vf24, 999(vi00) | mul.xyzw vf23, vf26, vf07 673 + vu.vf23.mul(Mask::xyzw, vu.vf26, vu.vf07); sq_buffer(Mask::xyzw, vu.vf24, 999); + // sq.xyzw vf25, 1000(vi00) | mul.xyzw vf24, vf27, vf07 674 + vu.vf24.mul(Mask::xyzw, vu.vf27, vu.vf07); sq_buffer(Mask::xyzw, vu.vf25, 1000); + // isw.x vi01, 1001(vi00) | mul.xyzw vf25, vf28, vf07 675 + vu.vf25.mul(Mask::xyzw, vu.vf28, vu.vf07); isw_buffer(Mask::x, vu.vi01, 1001); + // isw.y vi02, 1001(vi00) | nop 676 + isw_buffer(Mask::y, vu.vi02, 1001); + // TODO more clipping? + // isw.z vi03, 1001(vi00) | clipw.xyz vf23, vf23 677 + cf0 = clip(vu.vf23, vu.vf23.w(), cf); isw_buffer(Mask::z, vu.vi03, 1001); + // isw.w vi04, 1001(vi00) | clipw.xyz vf24, vf24 678 + cf1 = clip(vu.vf24, vu.vf24.w(), cf0); isw_buffer(Mask::w, vu.vi04, 1001); + // mfir.x vf31, vi05 | clipw.xyz vf25, vf25 679 + cf2 = clip(vu.vf25, vu.vf25.w(), cf1); vu.vf31.mfir(Mask::x, vu.vi05); + // iaddiu vi04, vi00, 0x3f | nop 680 + vu.vi04 = 0x3f; /* 63 */ + // fcget vi01 | nop 681 + vu.vi01 = cf0; + // fcget vi02 | nop 682 + vu.vi02 = cf1; + // fcget vi03 | nop 683 + vu.vi03 = cf2; + cf = cf2; + // iand vi01, vi01, vi04 | clipw.xyz vf26, vf26 684 + cf = clip(vu.vf26, vu.vf26.w(), cf); vu.vi01 = vu.vi01 & vu.vi04; + // iand vi01, vi01, vi02 | clipw.xyz vf27, vf27 685 + cf = clip(vu.vf27, vu.vf27.w(), cf); vu.vi01 = vu.vi01 & vu.vi02; + // iand vi01, vi01, vi03 | clipw.xyz vf28, vf28 686 + cf = clip(vu.vf28, vu.vf28.w(), cf); vu.vi01 = vu.vi01 & vu.vi03; + // mfir.y vf31, vi06 | nop 687 + vu.vf31.mfir(Mask::y, vu.vi06); + // BRANCH! + // ibeq vi00, vi01, L57 | nop 688 + bc = (vu.vi01 == 0); + // mfir.z vf31, vi07 | nop 689 + vu.vf31.mfir(Mask::z, vu.vi07); + if (!clipping_hack && bc) { goto L57; } + + L56: + // div Q, vf01.x, vf12.w | nop 690 + vu.Q = vu.vf01.x() / vu.vf12.w(); + // lq.xyzw vf23, 998(vi00) | nop 691 + lq_buffer(Mask::xyzw, vu.vf23, 998); + // lq.xyzw vf24, 999(vi00) | nop 692 + lq_buffer(Mask::xyzw, vu.vf24, 999); + // lq.xyzw vf25, 1000(vi00) | nop 693 + lq_buffer(Mask::xyzw, vu.vf25, 1000); + // ilw.x vi01, 1001(vi00) | nop 694 + ilw_buffer(Mask::x, vu.vi01, 1001); + // ilw.y vi02, 1001(vi00) | nop 695 + ilw_buffer(Mask::y, vu.vi02, 1001); + // ilw.z vi03, 1001(vi00) | nop 696 + ilw_buffer(Mask::z, vu.vi03, 1001); + // BRANCH! + // b L39 | nop 697 + bc = true; + // ilw.w vi04, 1001(vi00) | nop 698 + ilw_buffer(Mask::w, vu.vi04, 1001); + if (bc) { goto L39; } + + L57: + // mfir.w vf31, vi08 | nop 699 + vu.vf31.mfir(Mask::w, vu.vi08); + // mfir.x vf30, vi09 | nop 700 + vu.vf30.mfir(Mask::x, vu.vi09); + // mfir.y vf30, vi10 | nop 701 + vu.vf30.mfir(Mask::y, vu.vi10); + // mfir.z vf30, vi11 | nop 702 + vu.vf30.mfir(Mask::z, vu.vi11); + // mfir.w vf30, vi12 | nop 703 + vu.vf30.mfir(Mask::w, vu.vi12); + // sq.xyzw vf12, 1004(vi00) | nop 704 + sq_buffer(Mask::xyzw, vu.vf12, 1004); + // lq.xyzw vf12, -15(vi10) | nop 705 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi10 + -15); + // sq.xyzw vf13, 1005(vi00) | nop 706 + sq_buffer(Mask::xyzw, vu.vf13, 1005); + // lq.xyzw vf13, -12(vi10) | nop 707 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi10 + -12); + // sq.xyzw vf14, 1006(vi00) | nop 708 + sq_buffer(Mask::xyzw, vu.vf14, 1006); + // div Q, vf00.w, vf12.z | nop 709 + vu.Q = vu.vf00.w() / vu.vf12.z(); + // sq.xyzw vf31, 1002(vi00) | nop 710 + sq_buffer(Mask::xyzw, vu.vf31, 1002); + // sq.xyzw vf30, 1003(vi00) | nop 711 + sq_buffer(Mask::xyzw, vu.vf30, 1003); + // sq.xyzw vf15, 1007(vi00) | nop 712 + sq_buffer(Mask::xyzw, vu.vf15, 1007); + // sq.xyzw vf16, 1008(vi00) | nop 713 + sq_buffer(Mask::xyzw, vu.vf16, 1008); + // lq.xyzw vf03, 4(vi13) | nop 714 + lq_buffer(Mask::xyzw, vu.vf03, vu.vi13 + 4); + // lq.xyzw vf15, -14(vi10) | sub.xw vf31, vf00, vf00 715 + vu.vf31.sub(Mask::xw, vu.vf00, vu.vf00); lq_buffer(Mask::xyzw, vu.vf15, vu.vi10 + -14); + // div Q, vf00.w, vf13.z | nop 716 + vu.Q = vu.vf00.w() / vu.vf13.z(); + // lq.xyzw vf16, -11(vi10) | mul.xyz vf12, vf12, Q 717 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); lq_buffer(Mask::xyzw, vu.vf16, vu.vi10 + -11); + // lq.xyzw vf17, -8(vi10) | addx.y vf31, vf00, vf03 718 + vu.vf31.add(Mask::y, vu.vf00, vu.vf03.x()); lq_buffer(Mask::xyzw, vu.vf17, vu.vi10 + -8); + // nop | itof0.xyzw vf15, vf15 719 + vu.vf15.itof0(Mask::xyzw, vu.vf15); + // sq.xyzw vf26, 989(vi00) | nop 720 + sq_buffer(Mask::xyzw, vu.vf26, 989); + // sq.xyzw vf12, 991(vi00) | itof0.xyzw vf16, vf16 721 + vu.vf16.itof0(Mask::xyzw, vu.vf16); sq_buffer(Mask::xyzw, vu.vf12, 991); + // sq.xyzw vf27, 992(vi00) | itof0.xyzw vf17, vf17 722 + vu.vf17.itof0(Mask::xyzw, vu.vf17); sq_buffer(Mask::xyzw, vu.vf27, 992); + // div Q, vf00.w, vf20.z | nop 723 + vu.Q = vu.vf00.w() / vu.vf20.z(); + // nop | mul.xyz vf13, vf13, Q 724 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); + // sq.xyzw vf28, 995(vi00) | nop 725 + sq_buffer(Mask::xyzw, vu.vf28, 995); + // move.z vf31, vf03 | nop 726 + vu.vf31.move(Mask::z, vu.vf03); + // sq.xyzw vf15, 990(vi00) | nop 727 + sq_buffer(Mask::xyzw, vu.vf15, 990); + // sq.xyzw vf16, 993(vi00) | nop 728 + sq_buffer(Mask::xyzw, vu.vf16, 993); + // sq.xyzw vf17, 996(vi00) | nop 729 + sq_buffer(Mask::xyzw, vu.vf17, 996); + // sq.xyzw vf13, 994(vi00) | nop 730 + sq_buffer(Mask::xyzw, vu.vf13, 994); + // sq.xyzw vf31, 961(vi00) | mul.xyz vf14, vf20, Q 731 + vu.vf14.mul(Mask::xyz, vu.vf20, vu.Q); sq_buffer(Mask::xyzw, vu.vf31, 961); + // nop | nop 732 + + // nop | nop 733 + + // BRANCH! + // bal vi15, L66 | nop 734 + ASSERT(false); + // sq.xyzw vf14, 997(vi00) | nop 735 + sq_buffer(Mask::xyzw, vu.vf14, 997); + if (bc) { goto L66; } + + // BRANCH! + // ibeq vi00, vi05, L58 | nop 736 + bc = (vu.vi05 == 0); + // nop | nop 737 + + if (bc) { goto L58; } + + // BRANCH! + // bal vi15, L63 | nop 738 + ASSERT(false); + // nop | nop 739 + + if (bc) { goto L63; } + + L58: + // ilw.x vi05, 1002(vi00) | nop 740 + ilw_buffer(Mask::x, vu.vi05, 1002); + // ilw.y vi06, 1002(vi00) | nop 741 + ilw_buffer(Mask::y, vu.vi06, 1002); + // ilw.z vi07, 1002(vi00) | nop 742 + ilw_buffer(Mask::z, vu.vi07, 1002); + // ilw.w vi08, 1002(vi00) | nop 743 + ilw_buffer(Mask::w, vu.vi08, 1002); + // ilw.x vi09, 1003(vi00) | nop 744 + ilw_buffer(Mask::x, vu.vi09, 1003); + // ilw.y vi10, 1003(vi00) | nop 745 + ilw_buffer(Mask::y, vu.vi10, 1003); + // ilw.z vi11, 1003(vi00) | nop 746 + ilw_buffer(Mask::z, vu.vi11, 1003); + // ilw.w vi12, 1003(vi00) | nop 747 + ilw_buffer(Mask::w, vu.vi12, 1003); + // lq.xyzw vf12, 1004(vi00) | nop 748 + lq_buffer(Mask::xyzw, vu.vf12, 1004); + // lq.xyzw vf13, 1005(vi00) | nop 749 + lq_buffer(Mask::xyzw, vu.vf13, 1005); + // lq.xyzw vf14, 1006(vi00) | nop 750 + lq_buffer(Mask::xyzw, vu.vf14, 1006); + // lq.xyzw vf15, 1007(vi00) | nop 751 + lq_buffer(Mask::xyzw, vu.vf15, 1007); + // BRANCH! + // b L56 | nop 752 + bc = true; + // lq.xyzw vf16, 1008(vi00) | nop 753 + lq_buffer(Mask::xyzw, vu.vf16, 1008); + if (bc) { goto L56; } + + L59: + // BRANCH! + // ibne vi05, vi09, L41 | nop 754 + bc = (vu.vi05 != vu.vi09); + // sq.xyzw vf23, 998(vi00) | addw.w vf15, vf15, vf01 755 + vu.vf15.add(Mask::w, vu.vf15, vu.vf01.w()); sq_buffer(Mask::xyzw, vu.vf23, 998); + if (bc) { goto L41; } + + // sq.xyzw vf24, 999(vi00) | mul.xyzw vf23, vf27, vf07 756 + vu.vf23.mul(Mask::xyzw, vu.vf27, vu.vf07); sq_buffer(Mask::xyzw, vu.vf24, 999); + // sq.xyzw vf25, 1000(vi00) | mul.xyzw vf24, vf28, vf07 757 + vu.vf24.mul(Mask::xyzw, vu.vf28, vu.vf07); sq_buffer(Mask::xyzw, vu.vf25, 1000); + // isw.x vi01, 1001(vi00) | mul.xyzw vf25, vf29, vf07 758 + vu.vf25.mul(Mask::xyzw, vu.vf29, vu.vf07); isw_buffer(Mask::x, vu.vi01, 1001); + // isw.y vi02, 1001(vi00) | nop 759 + isw_buffer(Mask::y, vu.vi02, 1001); + // isw.z vi03, 1001(vi00) | clipw.xyz vf23, vf23 760 + // TODO more clipping + cf0 = clip(vu.vf23, vu.vf23.w(), cf); isw_buffer(Mask::z, vu.vi03, 1001); + // isw.w vi04, 1001(vi00) | clipw.xyz vf24, vf24 761 + cf1 = clip(vu.vf24, vu.vf24.w(), cf0); isw_buffer(Mask::w, vu.vi04, 1001); + // mfir.x vf31, vi05 | clipw.xyz vf25, vf25 762 + cf2 = clip(vu.vf25, vu.vf25.w(), cf1); vu.vf31.mfir(Mask::x, vu.vi05); + // iaddiu vi04, vi00, 0x3f | nop 763 + cf = cf2; + vu.vi04 = 0x3f; /* 63 */ + // fcget vi01 | nop 764 + vu.vi01 = cf0; + // fcget vi02 | nop 765 + vu.vi02 = cf1; + // fcget vi03 | nop 766 + vu.vi03 = cf2; + // iand vi01, vi01, vi04 | clipw.xyz vf27, vf27 767 + cf = clip(vu.vf27, vu.vf27.w(), cf); vu.vi01 = vu.vi01 & vu.vi04; + // iand vi01, vi01, vi02 | clipw.xyz vf28, vf28 768 + cf = clip(vu.vf28, vu.vf28.w(), cf); vu.vi01 = vu.vi01 & vu.vi02; + // iand vi01, vi01, vi03 | clipw.xyz vf29, vf29 769 + cf = clip(vu.vf29, vu.vf29.w(), cf); vu.vi01 = vu.vi01 & vu.vi03; + // mfir.y vf31, vi06 | nop 770 + vu.vf31.mfir(Mask::y, vu.vi06); + // BRANCH! + // ibeq vi00, vi01, L61 | nop 771 + bc = (vu.vi01 == 0); + // mfir.z vf31, vi07 | nop 772 + vu.vf31.mfir(Mask::z, vu.vi07); + if (!clipping_hack && bc) { goto L61; } + + L60: + // div Q, vf01.x, vf13.w | nop 773 + vu.Q = vu.vf01.x() / vu.vf13.w(); + // lq.xyzw vf23, 998(vi00) | nop 774 + lq_buffer(Mask::xyzw, vu.vf23, 998); + // lq.xyzw vf24, 999(vi00) | nop 775 + lq_buffer(Mask::xyzw, vu.vf24, 999); + // lq.xyzw vf25, 1000(vi00) | nop 776 + lq_buffer(Mask::xyzw, vu.vf25, 1000); + // ilw.x vi01, 1001(vi00) | nop 777 + ilw_buffer(Mask::x, vu.vi01, 1001); + // ilw.y vi02, 1001(vi00) | nop 778 + ilw_buffer(Mask::y, vu.vi02, 1001); + // ilw.z vi03, 1001(vi00) | nop 779 + ilw_buffer(Mask::z, vu.vi03, 1001); + // BRANCH! + // b L41 | nop 780 + bc = true; + // ilw.w vi04, 1001(vi00) | nop 781 + ilw_buffer(Mask::w, vu.vi04, 1001); + if (bc) { goto L41; } + + L61: + // mfir.w vf31, vi08 | nop 782 + vu.vf31.mfir(Mask::w, vu.vi08); + // mfir.x vf30, vi09 | nop 783 + vu.vf30.mfir(Mask::x, vu.vi09); + // mfir.y vf30, vi10 | nop 784 + vu.vf30.mfir(Mask::y, vu.vi10); + // mfir.z vf30, vi11 | nop 785 + vu.vf30.mfir(Mask::z, vu.vi11); + // mfir.w vf30, vi12 | nop 786 + vu.vf30.mfir(Mask::w, vu.vi12); + // sq.xyzw vf12, 1004(vi00) | nop 787 + sq_buffer(Mask::xyzw, vu.vf12, 1004); + // lq.xyzw vf12, -15(vi10) | nop 788 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi10 + -15); + // sq.xyzw vf13, 1005(vi00) | nop 789 + sq_buffer(Mask::xyzw, vu.vf13, 1005); + // lq.xyzw vf13, -12(vi10) | nop 790 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi10 + -12); + // sq.xyzw vf14, 1006(vi00) | nop 791 + sq_buffer(Mask::xyzw, vu.vf14, 1006); + // div Q, vf00.w, vf12.z | nop 792 + vu.Q = vu.vf00.w() / vu.vf12.z(); + // sq.xyzw vf31, 1002(vi00) | nop 793 + sq_buffer(Mask::xyzw, vu.vf31, 1002); + // sq.xyzw vf30, 1003(vi00) | nop 794 + sq_buffer(Mask::xyzw, vu.vf30, 1003); + // sq.xyzw vf15, 1007(vi00) | nop 795 + sq_buffer(Mask::xyzw, vu.vf15, 1007); + // sq.xyzw vf16, 1008(vi00) | nop 796 + sq_buffer(Mask::xyzw, vu.vf16, 1008); + // lq.xyzw vf03, 4(vi13) | nop 797 + lq_buffer(Mask::xyzw, vu.vf03, vu.vi13 + 4); + // lq.xyzw vf15, -14(vi10) | sub.xw vf31, vf00, vf00 798 + vu.vf31.sub(Mask::xw, vu.vf00, vu.vf00); lq_buffer(Mask::xyzw, vu.vf15, vu.vi10 + -14); + // div Q, vf00.w, vf13.z | nop 799 + vu.Q = vu.vf00.w() / vu.vf13.z(); + // lq.xyzw vf16, -11(vi10) | mul.xyz vf12, vf12, Q 800 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); lq_buffer(Mask::xyzw, vu.vf16, vu.vi10 + -11); + // lq.xyzw vf17, -8(vi10) | addx.y vf31, vf00, vf03 801 + vu.vf31.add(Mask::y, vu.vf00, vu.vf03.x()); lq_buffer(Mask::xyzw, vu.vf17, vu.vi10 + -8); + // nop | itof0.xyzw vf15, vf15 802 + vu.vf15.itof0(Mask::xyzw, vu.vf15); + // sq.xyzw vf27, 989(vi00) | nop 803 + sq_buffer(Mask::xyzw, vu.vf27, 989); + // sq.xyzw vf12, 991(vi00) | itof0.xyzw vf16, vf16 804 + vu.vf16.itof0(Mask::xyzw, vu.vf16); sq_buffer(Mask::xyzw, vu.vf12, 991); + // sq.xyzw vf28, 992(vi00) | itof0.xyzw vf17, vf17 805 + vu.vf17.itof0(Mask::xyzw, vu.vf17); sq_buffer(Mask::xyzw, vu.vf28, 992); + // div Q, vf00.w, vf21.z | nop 806 + vu.Q = vu.vf00.w() / vu.vf21.z(); + // nop | mul.xyz vf13, vf13, Q 807 + vu.vf13.mul(Mask::xyz, vu.vf13, vu.Q); + // sq.xyzw vf29, 995(vi00) | nop 808 + sq_buffer(Mask::xyzw, vu.vf29, 995); + // move.z vf31, vf03 | nop 809 + vu.vf31.move(Mask::z, vu.vf03); + // sq.xyzw vf15, 990(vi00) | nop 810 + sq_buffer(Mask::xyzw, vu.vf15, 990); + // sq.xyzw vf16, 993(vi00) | nop 811 + sq_buffer(Mask::xyzw, vu.vf16, 993); + // sq.xyzw vf17, 996(vi00) | nop 812 + sq_buffer(Mask::xyzw, vu.vf17, 996); + // sq.xyzw vf13, 994(vi00) | nop 813 + sq_buffer(Mask::xyzw, vu.vf13, 994); + // sq.xyzw vf31, 961(vi00) | mul.xyz vf14, vf21, Q 814 + vu.vf14.mul(Mask::xyz, vu.vf21, vu.Q); sq_buffer(Mask::xyzw, vu.vf31, 961); + // nop | nop 815 + + // nop | nop 816 + + // BRANCH! + // bal vi15, L66 | nop 817 + ASSERT(false); + // sq.xyzw vf14, 997(vi00) | nop 818 + sq_buffer(Mask::xyzw, vu.vf14, 997); + if (bc) { goto L66; } + + // BRANCH! + // ibeq vi00, vi05, L62 | nop 819 + bc = (vu.vi05 == 0); + // nop | nop 820 + + if (bc) { goto L62; } + + // BRANCH! + // bal vi15, L63 | nop 821 + ASSERT(false); + // nop | nop 822 + + if (bc) { goto L63; } + + L62: + // ilw.x vi05, 1002(vi00) | nop 823 + ilw_buffer(Mask::x, vu.vi05, 1002); + // ilw.y vi06, 1002(vi00) | nop 824 + ilw_buffer(Mask::y, vu.vi06, 1002); + // ilw.z vi07, 1002(vi00) | nop 825 + ilw_buffer(Mask::z, vu.vi07, 1002); + // ilw.w vi08, 1002(vi00) | nop 826 + ilw_buffer(Mask::w, vu.vi08, 1002); + // ilw.x vi09, 1003(vi00) | nop 827 + ilw_buffer(Mask::x, vu.vi09, 1003); + // ilw.y vi10, 1003(vi00) | nop 828 + ilw_buffer(Mask::y, vu.vi10, 1003); + // ilw.z vi11, 1003(vi00) | nop 829 + ilw_buffer(Mask::z, vu.vi11, 1003); + // ilw.w vi12, 1003(vi00) | nop 830 + ilw_buffer(Mask::w, vu.vi12, 1003); + // lq.xyzw vf12, 1004(vi00) | nop 831 + lq_buffer(Mask::xyzw, vu.vf12, 1004); + // lq.xyzw vf13, 1005(vi00) | nop 832 + lq_buffer(Mask::xyzw, vu.vf13, 1005); + // lq.xyzw vf14, 1006(vi00) | nop 833 + lq_buffer(Mask::xyzw, vu.vf14, 1006); + // lq.xyzw vf15, 1007(vi00) | nop 834 + lq_buffer(Mask::xyzw, vu.vf15, 1007); + // BRANCH! + // b L60 | nop 835 + bc = true; + // lq.xyzw vf16, 1008(vi00) | nop 836 + lq_buffer(Mask::xyzw, vu.vf16, 1008); + if (bc) { goto L60; } + + L63: + // ilw.w vi01, 8(vi13) | nop 837 + ilw_buffer(Mask::w, vu.vi01, vu.vi13 + 8); + // ilw.y vi02, 1003(vi00) | nop 838 + ilw_buffer(Mask::y, vu.vi02, 1003); + // iaddi vi03, vi13, 0x7 | nop 839 + vu.vi03 = vu.vi13 + 7; + // BRANCH! + // ibltz vi01, L65 | nop 840 + bc = ((s16)vu.vi01) < 0; + // ilw.w vi04, 906(vi00) | nop 841 + ilw_buffer(Mask::w, vu.vi04, 906); + if (bc) { goto L65; } + + // iaddi vi02, vi02, -0xf | nop 842 + vu.vi02 = vu.vi02 + -15; + // isub vi02, vi02, vi04 | nop 843 + vu.vi02 = vu.vi02 - vu.vi04; + L64: + // ilw.w vi04, 5(vi03) | nop 844 + ilw_buffer(Mask::w, vu.vi04, vu.vi03 + 5); + // ilw.w vi01, 6(vi03) | nop 845 + ilw_buffer(Mask::w, vu.vi01, vu.vi03 + 6); + // nop | nop 846 + + // nop | nop 847 + + // isub vi04, vi02, vi04 | nop 848 + vu.vi04 = vu.vi02 - vu.vi04; + // nop | nop 849 + + // BRANCH! + // ibltz vi04, L65 | nop 850 + bc = ((s16)vu.vi04) < 0; + // nop | nop 851 + + if (bc) { goto L65; } + + // BRANCH! + // ibgtz vi01, L64 | nop 852 + bc = ((s16)vu.vi01) > 0; + // iaddi vi03, vi03, 0x5 | nop 853 + vu.vi03 = vu.vi03 + 5; + if (bc) { goto L64; } + + L65: + // iaddiu vi01, vi00, 0x3b9 | nop 854 + vu.vi01 = 0x3b9; /* 953 */ + // lq.xyzw vf12, 0(vi03) | nop 855 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi03); + // lq.xyzw vf13, 1(vi03) | nop 856 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi03 + 1); + // lq.xyzw vf14, 2(vi03) | nop 857 + lq_buffer(Mask::xyzw, vu.vf14, vu.vi03 + 2); + // lq.xyzw vf15, 3(vi03) | nop 858 + lq_buffer(Mask::xyzw, vu.vf15, vu.vi03 + 3); + // sq.xyzw vf02, 0(vi01) | nop 859 + sq_buffer(Mask::xyzw, vu.vf02, vu.vi01); + // sq.xyzw vf12, 1(vi01) | nop 860 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi01 + 1); + // sq.xyzw vf13, 2(vi01) | nop 861 + sq_buffer(Mask::xyzw, vu.vf13, vu.vi01 + 2); + // sq.xyzw vf14, 3(vi01) | nop 862 + sq_buffer(Mask::xyzw, vu.vf14, vu.vi01 + 3); + // sq.xyzw vf15, 4(vi01) | nop 863 + sq_buffer(Mask::xyzw, vu.vf15, vu.vi01 + 4); + // lq.xyzw vf12, 4(vi03) | nop 864 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi03 + 4); + // lq.xyzw vf13, 5(vi13) | nop 865 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi13 + 5); + // lq.xyzw vf14, 6(vi13) | nop 866 + lq_buffer(Mask::xyzw, vu.vf14, vu.vi13 + 6); + // sq.xyzw vf12, 5(vi01) | nop 867 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi01 + 5); + // sq.xyzw vf13, 6(vi01) | nop 868 + sq_buffer(Mask::xyzw, vu.vf13, vu.vi01 + 6); + // sq.xyzw vf14, 7(vi01) | nop 869 + sq_buffer(Mask::xyzw, vu.vf14, vu.vi01 + 7); + // xgkick vi01 | nop 870 + xgkick(vu.vi01, render_state, prof); + // lq.xyzw vf12, 905(vi00) | nop 871 + lq_buffer(Mask::xyzw, vu.vf12, 905); + // iaddiu vi01, vi00, 0x3f3 | nop 872 + vu.vi01 = 0x3f3; /* 1011 */ + // isubiu vi02, vi00, 0x7fff | nop 873 + vu.vi02 = -32767; + // sq.xyzw vf02, 0(vi01) | nop 874 + sq_buffer(Mask::xyzw, vu.vf02, vu.vi01); + // iswr.x vi02, vi01 | nop 875 + isw_buffer(Mask::x, vu.vi02, vu.vi01); + // sq.xyzw vf12, 1(vi01) | nop 876 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi01 + 1); + // xgkick vi01 | nop 877 + xgkick(vu.vi01, render_state, prof); + L66: + // sq.xyzw vf00, 907(vi00) | nop 878 + sq_buffer(Mask::xyzw, vu.vf00, 907); + // sq.xyzw vf00, 914(vi00) | nop 879 + sq_buffer(Mask::xyzw, vu.vf00, 914); + // sq.xyzw vf00, 921(vi00) | nop 880 + sq_buffer(Mask::xyzw, vu.vf00, 921); + // sq.xyzw vf00, 928(vi00) | nop 881 + sq_buffer(Mask::xyzw, vu.vf00, 928); + // sq.xyzw vf00, 935(vi00) | nop 882 + sq_buffer(Mask::xyzw, vu.vf00, 935); + // sq.xyzw vf00, 942(vi00) | nop 883 + sq_buffer(Mask::xyzw, vu.vf00, 942); + // iaddiu vi01, vi00, 0x40f | nop 884 + vu.vi01 = 0x40f; /* 1039 */ + // isw.z vi01, 907(vi00) | nop 885 + isw_buffer(Mask::z, vu.vi01, 907); + // iaddiu vi01, vi00, 0x411 | nop 886 + vu.vi01 = 0x411; /* 1041 */ + // isw.z vi01, 914(vi00) | nop 887 + isw_buffer(Mask::z, vu.vi01, 914); + // iaddiu vi01, vi00, 0x413 | nop 888 + vu.vi01 = 0x413; /* 1043 */ + // isw.z vi01, 921(vi00) | nop 889 + isw_buffer(Mask::z, vu.vi01, 921); + // iaddiu vi01, vi00, 0x415 | nop 890 + vu.vi01 = 0x415; /* 1045 */ + // isw.z vi01, 928(vi00) | nop 891 + isw_buffer(Mask::z, vu.vi01, 928); + // iaddiu vi01, vi00, 0x417 | nop 892 + vu.vi01 = 0x417; /* 1047 */ + // isw.z vi01, 935(vi00) | nop 893 + isw_buffer(Mask::z, vu.vi01, 935); + // iaddiu vi01, vi00, 0x419 | nop 894 + vu.vi01 = 0x419; /* 1049 */ + // isw.z vi01, 942(vi00) | nop 895 + isw_buffer(Mask::z, vu.vi01, 942); + // iaddiu vi03, vi00, 0x3c2 | nop 896 + vu.vi03 = 0x3c2; /* 962 */ + // iaddiu vi04, vi00, 0x3c1 | nop 897 + vu.vi04 = 0x3c1; /* 961 */ + // mfir.x vf31, vi15 | nop 898 + vu.vf31.mfir(Mask::x, vu.vi15); + // iaddi vi05, vi00, 0x0 | nop 899 + vu.vi05 = 0; + // BRANCH! + // bal vi15, L67 | nop 900 + ASSERT(false); + // iaddiu vi07, vi00, 0x3dd | nop 901 + vu.vi07 = 0x3dd; /* 989 */ + if (bc) { goto L67; } + + // BRANCH! + // bal vi15, L67 | nop 902 + ASSERT(false); + // iaddiu vi07, vi00, 0x3e0 | nop 903 + vu.vi07 = 0x3e0; /* 992 */ + if (bc) { goto L67; } + + // BRANCH! + // bal vi15, L67 | nop 904 + ASSERT(false); + // iaddiu vi07, vi00, 0x3e3 | nop 905 + vu.vi07 = 0x3e3; /* 995 */ + if (bc) { goto L67; } + + // BRANCH! + // b L76 | nop 906 + bc = true; + // nop | nop 907 + + if (bc) { goto L76; } + + L67: + // iaddiu vi09, vi00, 0x38b | nop 908 + vu.vi09 = 0x38b; /* 907 */ + L68: + // iaddi vi10, vi00, 0x0 | nop 909 + vu.vi10 = 0; + L69: + // isubiu vi01, vi09, 0x3b5 | nop 910 + vu.vi01 = vu.vi09 - 0x3b5; /* 949 */ + // ilwr.y vi08, vi09 | nop 911 + ilw_buffer(Mask::y, vu.vi08, vu.vi09); + // BRANCH! + // ibgez vi01, L73 | nop 912 + bc = ((s16)vu.vi01) >= 0; + // ilwr.z vi06, vi09 | nop 913 + ilw_buffer(Mask::z, vu.vi06, vu.vi09); + if (bc) { goto L73; } + + // lq.xyzw vf24, 0(vi07) | nop 914 + lq_buffer(Mask::xyzw, vu.vf24, vu.vi07); + // lq.xyzw vf23, 0(vi08) | nop 915 + lq_buffer(Mask::xyzw, vu.vf23, vu.vi08); + // BRANCH! + // ibne vi00, vi08, L70 | nop 916 + bc = (vu.vi08 != 0); + // iswr.y vi07, vi09 | nop 917 + isw_buffer(Mask::y, vu.vi07, vu.vi09); + if (bc) { goto L70; } + + // jalr vi11, vi06 | nop 918 + ASSERT(false); + // iswr.x vi07, vi09 | nop 919 + isw_buffer(Mask::x, vu.vi07, vu.vi09); + // nop | nop 920 + + // nop | nop 921 + + // nop | nop 922 + + // fsand vi02, 0x2 | nop 923 + ASSERT(false); + // BRANCH! + // ibne vi00, vi02, L74 | nop 924 + bc = (vu.vi02 != 0); + // nop | nop 925 + + if (bc) { goto L74; } + + // BRANCH! + // b L69 | nop 926 + bc = true; + // iaddi vi09, vi09, 0x7 | nop 927 + vu.vi09 = vu.vi09 + 7; + if (bc) { goto L69; } + + L70: + // jalr vi11, vi06 | nop 928 + ASSERT(false); + // lq.xyzw vf15, 1(vi08) | nop 929 + lq_buffer(Mask::xyzw, vu.vf15, vu.vi08 + 1); + // lq.xyzw vf16, 1(vi07) | nop 930 + lq_buffer(Mask::xyzw, vu.vf16, vu.vi07 + 1); + // lq.xyzw vf12, 2(vi08) | nop 931 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi08 + 2); + // fsand vi01, 0x2 | nop 932 + ASSERT(false); + // fsand vi02, 0x2 | subw.w vf31, vf30, vf31 933 + vu.vf31.sub(Mask::w, vu.vf30, vu.vf31.w()); ASSERT(false); + // BRANCH! + // ibne vi00, vi01, L72 | nop 934 + bc = (vu.vi01 != 0); + // lq.xyzw vf13, 2(vi07) | nop 935 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi07 + 2); + if (bc) { goto L72; } + + // BRANCH! + // ibne vi00, vi02, L71 | nop 936 + bc = (vu.vi02 != 0); + // div Q, vf30.w, vf31.w | nop 937 + vu.Q = vu.vf30.w() / vu.vf31.w(); + if (bc) { goto L71; } + + // BRANCH! + // b L69 | nop 938 + bc = true; + // iaddi vi09, vi09, 0x7 | nop 939 + vu.vi09 = vu.vi09 + 7; + if (bc) { goto L69; } + + L71: + // BRANCH! + // bal vi11, L81 | nop 940 + ASSERT(false); + // iaddi vi07, vi09, 0x1 | nop 941 + vu.vi07 = vu.vi09 + 1; + if (bc) { goto L81; } + + // sq.xyzw vf25, 1(vi09) | nop 942 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi09 + 1); + // sq.xyzw vf17, 2(vi09) | nop 943 + sq_buffer(Mask::xyzw, vu.vf17, vu.vi09 + 2); + // sq.xyzw vf14, 3(vi09) | nop 944 + sq_buffer(Mask::xyzw, vu.vf14, vu.vi09 + 3); + // BRANCH! + // b L69 | nop 945 + bc = true; + // iaddi vi09, vi09, 0x7 | nop 946 + vu.vi09 = vu.vi09 + 7; + if (bc) { goto L69; } + + L72: + // BRANCH! + // ibne vi00, vi02, L74 | nop 947 + bc = (vu.vi02 != 0); + // div Q, vf30.w, vf31.w | nop 948 + vu.Q = vu.vf30.w() / vu.vf31.w(); + if (bc) { goto L74; } + + // BRANCH! + // bal vi11, L81 | nop 949 + ASSERT(false); + // nop | nop 950 + + if (bc) { goto L81; } + + // sq.xyzw vf25, 4(vi09) | nop 951 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi09 + 4); + // sq.xyzw vf17, 5(vi09) | nop 952 + sq_buffer(Mask::xyzw, vu.vf17, vu.vi09 + 5); + // sq.xyzw vf14, 6(vi09) | nop 953 + sq_buffer(Mask::xyzw, vu.vf14, vu.vi09 + 6); + // iaddi vi09, vi09, 0x7 | nop 954 + vu.vi09 = vu.vi09 + 7; + // isw.x vi09, 949(vi10) | nop 955 + isw_buffer(Mask::x, vu.vi09, vu.vi10 + 949); + // isw.y vi07, 949(vi10) | nop 956 + isw_buffer(Mask::y, vu.vi07, vu.vi10 + 949); + // iaddi vi10, vi10, 0x1 | nop 957 + vu.vi10 = vu.vi10 + 1; + // BRANCH! + // b L69 | nop 958 + bc = true; + // iaddi vi07, vi09, -0x3 | nop 959 + vu.vi07 = vu.vi09 + -3; + if (bc) { goto L69; } + + L73: + // lq.xyzw vf23, 0(vi07) | nop 960 + lq_buffer(Mask::xyzw, vu.vf23, vu.vi07); + // lq.xyzw vf15, 1(vi07) | nop 961 + lq_buffer(Mask::xyzw, vu.vf15, vu.vi07 + 1); + // lq.xyzw vf12, 2(vi07) | nop 962 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi07 + 2); + // iaddi vi05, vi05, 0x1 | nop 963 + vu.vi05 = vu.vi05 + 1; + // nop | nop 964 + + // div Q, vf00.w, vf23.w | nop 965 + vu.Q = vu.vf00.w() / vu.vf23.w(); + // nop | ftoi0.xyzw vf15, vf15 966 + vu.vf15.ftoi0(Mask::xyzw, vu.vf15); + // nop | mul.xyzw vf23, vf23, vf06 967 + vu.vf23.mul(Mask::xyzw, vu.vf23, vu.vf06); + // iaddi vi03, vi03, 0x3 | nop 968 + vu.vi03 = vu.vi03 + 3; + // waitq | nop 969 + ASSERT(false); + // sq.xyzw vf15, -2(vi03) | mul.xyz vf23, vf23, Q 970 + vu.vf23.mul(Mask::xyz, vu.vf23, vu.Q); sq_buffer(Mask::xyzw, vu.vf15, vu.vi03 + -2); + // nop | mul.xyz vf12, vf12, Q 971 + vu.vf12.mul(Mask::xyz, vu.vf12, vu.Q); + // nop | add.xyzw vf23, vf23, vf04 972 + vu.vf23.add(Mask::xyzw, vu.vf23, vu.vf04); + // nop | maxy.w vf23, vf23, vf01 973 + vu.vf23.max(Mask::w, vu.vf23, vu.vf01.y()); + // nop | miniz.w vf23, vf23, vf01 974 + vu.vf23.mini(Mask::w, vu.vf23, vu.vf01.z()); + // nop | ftoi4.xyzw vf23, vf23 975 + vu.vf23.ftoi4(Mask::xyzw, vu.vf23); + // sq.xyzw vf12, -3(vi03) | nop 976 + sq_buffer(Mask::xyzw, vu.vf12, vu.vi03 + -3); + // sq.xyzw vf23, -1(vi03) | nop 977 + sq_buffer(Mask::xyzw, vu.vf23, vu.vi03 + -1); + L74: + // BRANCH! + // iblez vi10, L75 | nop 978 + bc = ((s16)vu.vi10) <= 0; + // nop | nop 979 + + if (bc) { goto L75; } + + // ilw.x vi09, 948(vi10) | nop 980 + ilw_buffer(Mask::x, vu.vi09, vu.vi10 + 948); + // ilw.y vi07, 948(vi10) | nop 981 + ilw_buffer(Mask::y, vu.vi07, vu.vi10 + 948); + // BRANCH! + // b L69 | nop 982 + bc = true; + // iaddi vi10, vi10, -0x1 | nop 983 + vu.vi10 = vu.vi10 + -1; + if (bc) { goto L69; } + + L75: + // jr vi15 | nop 984 + ASSERT(false); + // nop | nop 985 + + L76: + // iaddiu vi09, vi00, 0x38b | nop 986 + vu.vi09 = 0x38b; /* 907 */ + L77: + // ilwr.x vi08, vi09 | nop 987 + ilw_buffer(Mask::x, vu.vi08, vu.vi09); + // ilwr.y vi07, vi09 | nop 988 + ilw_buffer(Mask::y, vu.vi07, vu.vi09); + // ilwr.z vi06, vi09 | nop 989 + ilw_buffer(Mask::z, vu.vi06, vu.vi09); + // nop | nop 990 + + // BRANCH! + // ibeq vi00, vi08, L79 | nop 991 + bc = (vu.vi08 == 0); + // lq.xyzw vf23, 0(vi07) | nop 992 + lq_buffer(Mask::xyzw, vu.vf23, vu.vi07); + if (bc) { goto L79; } + + // BRANCH! + // ibeq vi07, vi08, L79 | nop 993 + bc = (vu.vi07 == vu.vi08); + // lq.xyzw vf24, 0(vi08) | nop 994 + lq_buffer(Mask::xyzw, vu.vf24, vu.vi08); + if (bc) { goto L79; } + + // jalr vi11, vi06 | nop 995 + ASSERT(false); + // lq.xyzw vf15, 1(vi07) | nop 996 + lq_buffer(Mask::xyzw, vu.vf15, vu.vi07 + 1); + // lq.xyzw vf16, 1(vi08) | nop 997 + lq_buffer(Mask::xyzw, vu.vf16, vu.vi08 + 1); + // lq.xyzw vf12, 2(vi07) | nop 998 + lq_buffer(Mask::xyzw, vu.vf12, vu.vi07 + 2); + // fsand vi01, 0x2 | nop 999 + ASSERT(false); + // fsand vi02, 0x2 | subw.w vf31, vf30, vf31 1000 + vu.vf31.sub(Mask::w, vu.vf30, vu.vf31.w()); ASSERT(false); + // BRANCH! + // ibeq vi02, vi01, L79 | nop 1001 + bc = (vu.vi02 == vu.vi01); + // lq.xyzw vf13, 2(vi08) | nop 1002 + lq_buffer(Mask::xyzw, vu.vf13, vu.vi08 + 2); + if (bc) { goto L79; } + + // BRANCH! + // ibeq vi00, vi01, L78 | nop 1003 + bc = (vu.vi01 == 0); + // div Q, vf30.w, vf31.w | nop 1004 + vu.Q = vu.vf30.w() / vu.vf31.w(); + if (bc) { goto L78; } + + // BRANCH! + // bal vi11, L81 | nop 1005 + ASSERT(false); + // nop | nop 1006 + + if (bc) { goto L81; } + + // sq.xyzw vf25, 4(vi09) | nop 1007 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi09 + 4); + // sq.xyzw vf17, 5(vi09) | nop 1008 + sq_buffer(Mask::xyzw, vu.vf17, vu.vi09 + 5); + // sq.xyzw vf14, 6(vi09) | nop 1009 + sq_buffer(Mask::xyzw, vu.vf14, vu.vi09 + 6); + // iaddi vi07, vi09, 0x4 | nop 1010 + vu.vi07 = vu.vi09 + 4; + // ior vi12, vi09, vi00 | nop 1011 + vu.vi12 = vu.vi09; + // BRANCH! + // bal vi15, L68 | nop 1012 + ASSERT(false); + // iaddi vi09, vi09, 0x7 | nop 1013 + vu.vi09 = vu.vi09 + 7; + if (bc) { goto L68; } + + // BRANCH! + // b L79 | nop 1014 + bc = true; + // ior vi09, vi12, vi00 | nop 1015 + vu.vi09 = vu.vi12; + if (bc) { goto L79; } + + L78: + // BRANCH! + // bal vi11, L81 | nop 1016 + ASSERT(false); + // nop | nop 1017 + + if (bc) { goto L81; } + + // sq.xyzw vf25, 1(vi09) | nop 1018 + sq_buffer(Mask::xyzw, vu.vf25, vu.vi09 + 1); + // sq.xyzw vf17, 2(vi09) | nop 1019 + sq_buffer(Mask::xyzw, vu.vf17, vu.vi09 + 2); + // sq.xyzw vf14, 3(vi09) | nop 1020 + sq_buffer(Mask::xyzw, vu.vf14, vu.vi09 + 3); + // iaddi vi07, vi09, 0x1 | nop 1021 + vu.vi07 = vu.vi09 + 1; + // ior vi12, vi09, vi00 | nop 1022 + vu.vi12 = vu.vi09; + // BRANCH! + // bal vi15, L68 | nop 1023 + ASSERT(false); + // iaddi vi09, vi09, 0x7 | nop 1024 + vu.vi09 = vu.vi09 + 7; + if (bc) { goto L68; } + + // ior vi09, vi12, vi00 | nop 1025 + vu.vi09 = vu.vi12; + L79: + // isubiu vi01, vi09, 0x3ae | nop 1026 + vu.vi01 = vu.vi09 - 0x3ae; /* 942 */ + // iswr.x vi00, vi09 | nop 1027 + isw_buffer(Mask::x, vu.vi00, vu.vi09); + // iswr.y vi00, vi09 | nop 1028 + isw_buffer(Mask::y, vu.vi00, vu.vi09); + // BRANCH! + // ibltz vi01, L77 | nop 1029 + bc = ((s16)vu.vi01) < 0; + // iaddi vi09, vi09, 0x7 | nop 1030 + vu.vi09 = vu.vi09 + 7; + if (bc) { goto L77; } + + // BRANCH! + // ibeq vi00, vi05, L80 | nop 1031 + bc = (vu.vi05 == 0); + // mtir vi15, vf31.x | nop 1032 + vu.vi15 = vu.vf31.x_as_u16(); + if (bc) { goto L80; } + + // iaddiu vi05, vi05, 0x4000 | nop 1033 + vu.vi05 = vu.vi05 + 0x4000; /* 16384 */ + // iaddiu vi05, vi05, 0x4000 | nop 1034 + vu.vi05 = vu.vi05 + 0x4000; /* 16384 */ + // iswr.x vi05, vi04 | nop 1035 + isw_buffer(Mask::x, vu.vi05, vu.vi04); + L80: + // nop | nop 1036 + + // jr vi15 | nop 1037 + ASSERT(false); + // nop | nop 1038 + + // jr vi11 | addx.w vf30, vf23, vf23 1039 + vu.vf30.add(Mask::w, vu.vf23, vu.vf23.x()); ASSERT(false); + // nop | addx.w vf31, vf24, vf24 1040 + vu.vf31.add(Mask::w, vu.vf24, vu.vf24.x()); + // jr vi11 | subx.w vf30, vf23, vf23 1041 + vu.vf30.sub(Mask::w, vu.vf23, vu.vf23.x()); ASSERT(false); + // nop | subx.w vf31, vf24, vf24 1042 + vu.vf31.sub(Mask::w, vu.vf24, vu.vf24.x()); + // jr vi11 | addy.w vf30, vf23, vf23 1043 + vu.vf30.add(Mask::w, vu.vf23, vu.vf23.y()); ASSERT(false); + // nop | addy.w vf31, vf24, vf24 1044 + vu.vf31.add(Mask::w, vu.vf24, vu.vf24.y()); + // jr vi11 | suby.w vf30, vf23, vf23 1045 + vu.vf30.sub(Mask::w, vu.vf23, vu.vf23.y()); ASSERT(false); + // nop | suby.w vf31, vf24, vf24 1046 + vu.vf31.sub(Mask::w, vu.vf24, vu.vf24.y()); + // jr vi11 | addz.w vf30, vf23, vf23 1047 + vu.vf30.add(Mask::w, vu.vf23, vu.vf23.z()); ASSERT(false); + // nop | addz.w vf31, vf24, vf24 1048 + vu.vf31.add(Mask::w, vu.vf24, vu.vf24.z()); + // jr vi11 | subz.w vf30, vf23, vf23 1049 + vu.vf30.sub(Mask::w, vu.vf23, vu.vf23.z()); ASSERT(false); + // nop | subz.w vf31, vf24, vf24 1050 + vu.vf31.sub(Mask::w, vu.vf24, vu.vf24.z()); + L81: + // nop | sub.xyzw vf25, vf24, vf23 1051 + vu.vf25.sub(Mask::xyzw, vu.vf24, vu.vf23); + // nop | sub.xyzw vf17, vf16, vf15 1052 + vu.vf17.sub(Mask::xyzw, vu.vf16, vu.vf15); + // nop | sub.xyzw vf14, vf13, vf12 1053 + vu.vf14.sub(Mask::xyzw, vu.vf13, vu.vf12); + // waitq | mul.xyzw vf25, vf25, Q 1054 + vu.vf25.mul(Mask::xyzw, vu.vf25, vu.Q); ASSERT(false); + // nop | mul.xyzw vf17, vf17, Q 1055 + vu.vf17.mul(Mask::xyzw, vu.vf17, vu.Q); + // nop | mul.xyzw vf14, vf14, Q 1056 + vu.vf14.mul(Mask::xyzw, vu.vf14, vu.Q); + // nop | add.xyzw vf25, vf23, vf25 1057 + vu.vf25.add(Mask::xyzw, vu.vf23, vu.vf25); + // jr vi11 | add.xyzw vf17, vf15, vf17 1058 + vu.vf17.add(Mask::xyzw, vu.vf15, vu.vf17); ASSERT(false); + // nop | add.xyzw vf14, vf12, vf14 1059 + vu.vf14.add(Mask::xyzw, vu.vf12, vu.vf14); + L82: + // iaddi vi14, vi13, 0x7 | nop 1060 + vu.vi14 = vu.vi13 + 7; + // lq.xyzw vf03, 4(vi13) | nop 1061 + lq_buffer(Mask::xyzw, vu.vf03, vu.vi13 + 4); + // ilw.w vi02, 6(vi13) | nop 1062 + ilw_buffer(Mask::w, vu.vi02, vu.vi13 + 6); + // lq.xyzw vf21, 5(vi13) | nop 1063 + lq_buffer(Mask::xyzw, vu.vf21, vu.vi13 + 5); + // lq.xyzw vf22, 6(vi13) | nop 1064 + lq_buffer(Mask::xyzw, vu.vf22, vu.vi13 + 6); + L83: + // ilwr.w vi03, vi14 | nop 1065 + ilw_buffer(Mask::w, vu.vi03, vu.vi14); + // ilw.w vi04, 1(vi14) | nop 1066 + ilw_buffer(Mask::w, vu.vi04, vu.vi14 + 1); + // lqi.xyzw vf16, vi14 | nop 1067 + lq_buffer(Mask::xyzw, vu.vf16, vu.vi14++); + // lqi.xyzw vf17, vi14 | nop 1068 + lq_buffer(Mask::xyzw, vu.vf17, vu.vi14++); + // lqi.xyzw vf18, vi14 | nop 1069 + lq_buffer(Mask::xyzw, vu.vf18, vu.vi14++); + // lqi.xyzw vf19, vi14 | nop 1070 + lq_buffer(Mask::xyzw, vu.vf19, vu.vi14++); + // lqi.xyzw vf20, vi14 | nop 1071 + lq_buffer(Mask::xyzw, vu.vf20, vu.vi14++); + // iadd vi06, vi03, vi12 | nop 1072 + vu.vi06 = vu.vi03 + vu.vi12; + // sqi.xyzw vf02, vi06 | nop 1073 + sq_buffer(Mask::xyzw, vu.vf02, vu.vi06++); + // sqi.xyzw vf16, vi06 | nop 1074 + sq_buffer(Mask::xyzw, vu.vf16, vu.vi06++); + // sqi.xyzw vf17, vi06 | nop 1075 + sq_buffer(Mask::xyzw, vu.vf17, vu.vi06++); + // sqi.xyzw vf18, vi06 | nop 1076 + sq_buffer(Mask::xyzw, vu.vf18, vu.vi06++); + // sqi.xyzw vf19, vi06 | nop 1077 + sq_buffer(Mask::xyzw, vu.vf19, vu.vi06++); + // sqi.xyzw vf20, vi06 | nop 1078 + sq_buffer(Mask::xyzw, vu.vf20, vu.vi06++); + // sqi.xyzw vf21, vi06 | nop 1079 + sq_buffer(Mask::xyzw, vu.vf21, vu.vi06++); + // sqi.xyzw vf22, vi06 | nop 1080 + sq_buffer(Mask::xyzw, vu.vf22, vu.vi06++); + // sqi.xyzw vf03, vi06 | nop 1081 + sq_buffer(Mask::xyzw, vu.vf03, vu.vi06++); + // BRANCH! + // ibgez vi04, L83 | nop 1082 + bc = ((s16)vu.vi04) >= 0; + // isw.x vi04, -1(vi06) | nop 1083 + isw_buffer(Mask::x, vu.vi04, vu.vi06 + -1); + if (bc) { goto L83; } + + // iadd vi02, vi12, vi02 | nop 1084 + vu.vi02 = vu.vi12 + vu.vi02; + // nop | nop 1085 + + // xgkick vi02 | nop 1086 + xgkick(vu.vi02, render_state, prof); + // isubiu vi01, vi12, 0x22e | nop 1087 + vu.vi01 = vu.vi12 - 0x22e; /* 558 */ + // nop | nop 1088 + + // BRANCH! + // ibltz vi01, L84 | nop 1089 + bc = ((s16)vu.vi01) < 0; + // iaddiu vi12, vi12, 0x117 | nop 1090 + vu.vi12 = vu.vi12 + 0x117; /* 279 */ + if (bc) { goto L84; } + + // iaddi vi12, vi00, 0x0 | nop 1091 + vu.vi12 = 0; + L84: + // nop | nop :e 1092 + + // nop | nop 1093 + + return; +} \ No newline at end of file diff --git a/game/graphics/opengl_renderer/GenericRenderer.cpp b/game/graphics/opengl_renderer/GenericRenderer.cpp new file mode 100644 index 0000000000..dd38796e9d --- /dev/null +++ b/game/graphics/opengl_renderer/GenericRenderer.cpp @@ -0,0 +1,298 @@ +#include "GenericRenderer.h" +#include "third-party/imgui/imgui.h" + +GenericRenderer::GenericRenderer(const std::string& name, BucketId my_id) + : BucketRenderer(name, my_id), m_direct(name, my_id, 0x4000, DirectRenderer::Mode::NORMAL) {} + +void GenericRenderer::render(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { + m_skipped_tags = 0; + m_debug.clear(); + m_direct.reset_state(); + + // if the first draw should have no blending, it sets ABE in PRIM, but not ALPHA. + // the default ALPHA doesn't seem to be right. I don't know what's supposed to set it here. + // although this is definitely a hack, it doesn't seem to cause problems when the first thing to + // draw is transparent. + m_direct.hack_disable_blend(); + + // skip if disabled + if (!m_enabled) { + while (dma.current_tag_offset() != render_state->next_bucket) { + dma.read_and_advance(); + } + return; + } + + while (dma.current_tag_offset() != render_state->next_bucket) { + auto data = dma.read_and_advance(); + m_debug += fmt::format("{} : {} {}\n", data.size_bytes, data.vifcode0().print(), + data.vifcode1().print()); + auto v0 = data.vifcode0(); + auto v1 = data.vifcode1(); + if (data.size_bytes == 0) { + m_debug += "Emtpy Tag\n"; + switch (v0.kind) { + case VifCode::Kind::STCYCL: + vu.stcycl = v0.immediate; + break; + case VifCode::Kind::NOP: + break; + default: + fmt::print("unknown vifcode0 empty tag: {}\n", v0.print()); + ASSERT(false); + } + switch (v1.kind) { + case VifCode::Kind::STCYCL: + vu.stcycl = v1.immediate; + break; + case VifCode::Kind::NOP: + break; + case VifCode::Kind::MSCAL: + mscal(v1.immediate, render_state, prof); + break; + default: + fmt::print("unknown vifcode1 empty tag: {}\n", v1.print()); + ASSERT(false); + } + } else if (v0.kind == VifCode::Kind::FLUSHA && v1.kind == VifCode::Kind::DIRECT) { + m_direct.render_gif(data.data, data.size_bytes, render_state, prof); + ASSERT(v1.immediate == data.size_bytes / 16); + } else if (v0.kind == VifCode::Kind::NOP && v1.kind == VifCode::Kind::DIRECT) { + m_direct.render_gif(data.data, data.size_bytes, render_state, prof); + ASSERT(v1.immediate == data.size_bytes / 16); + } else if (v0.kind == VifCode::Kind::STCYCL && v1.kind == VifCode::Kind::UNPACK_V4_32) { + vu.stcycl = v0.immediate; + u32 bytes_used = unpack32_4(VifCodeUnpack(v1), data.data, v1.num); + if (bytes_used < data.size_bytes) { + handle_dma_stream(data.data + bytes_used, data.size_bytes - bytes_used, render_state, prof); + } else if (bytes_used > data.size_bytes) { + ASSERT(false); + } + } else if (v0.kind == VifCode::Kind::MSCALF && v1.kind == VifCode::Kind::STMOD) { + mscal(v0.immediate, render_state, prof); + ASSERT(v1.immediate == 0); + + u32 data_offset = 0; + u32 base_vifcode_data; + memcpy(&base_vifcode_data, data.data + data_offset, 4); + VifCode base_vc(base_vifcode_data); + ASSERT(base_vc.immediate == 0); + data_offset += 4; + + u32 offset_vifcode_data; + memcpy(&offset_vifcode_data, data.data + data_offset, 4); + VifCode offset_vc(offset_vifcode_data); + ASSERT(offset_vc.immediate == 0); + data_offset += 4; + + for (int i = 0; i < 1; i++) { + u32 nop_vifcode_data; + memcpy(&nop_vifcode_data, data.data + data_offset, 4); + VifCode next_vc(nop_vifcode_data); + ASSERT(next_vc.kind == VifCode::Kind::NOP); + data_offset += 4; + } + + u32 strow_vifcode_data; + memcpy(&strow_vifcode_data, data.data + data_offset, 4); + VifCode strow_vc(strow_vifcode_data); + data_offset += 4; + ASSERT(strow_vc.kind == VifCode::Kind::STROW); + + memcpy(vu.row, data.data + data_offset, 16); + data_offset += 16; + + ASSERT(data_offset == 32); + ASSERT(data_offset == data.size_bytes); + } else if (v0.kind == VifCode::Kind::NOP && v1.kind == VifCode::Kind::UNPACK_V3_32) { + u32 bytes_used = unpack32_3(VifCodeUnpack(v1), data.data, v1.num); + if (bytes_used < data.size_bytes) { + handle_dma_stream(data.data + bytes_used, data.size_bytes - bytes_used, render_state, prof); + } else if (bytes_used > data.size_bytes) { + ASSERT(false); + } + } else { + fmt::print("Generic encountered unknown DMA.\n"); + fmt::print("Size bytes: {}\n", data.size_bytes); + fmt::print("VIF0: {}\n", data.vifcode0().print()); + fmt::print("VIF1: {}\n", data.vifcode1().print()); + ASSERT(false); + } + m_skipped_tags++; + } + m_direct.flush_pending(render_state, prof); +} + +void GenericRenderer::handle_dma_stream(const u8* data, + u32 bytes, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { + while (bytes) { + u32 tag_data; + memcpy(&tag_data, data, 4); + bytes -= 4; + data += 4; + VifCode vc(tag_data); + switch (vc.kind) { + case VifCode::Kind::NOP: + break; + case VifCode::Kind::STCYCL: + vu.stcycl = vc.immediate; + break; + case VifCode::Kind::UNPACK_V3_32: { + u32 bytes_transferred = unpack32_3(VifCodeUnpack(vc), data, vc.num); + bytes -= bytes_transferred; + data += bytes_transferred; + } break; + case VifCode::Kind::UNPACK_V4_8: { + u32 bytes_transferred = unpack8_4(VifCodeUnpack(vc), data, vc.num); + bytes -= bytes_transferred; + data += bytes_transferred; + } break; + case VifCode::Kind::UNPACK_V2_16: { + u32 bytes_transferred = unpack16_2(VifCodeUnpack(vc), data, vc.num); + bytes -= bytes_transferred; + data += bytes_transferred; + } break; + case VifCode::Kind::UNPACK_V4_32: { + u32 bytes_transferred = unpack32_4(VifCodeUnpack(vc), data, vc.num); + bytes -= bytes_transferred; + data += bytes_transferred; + } break; + case VifCode::Kind::MSCAL: + mscal(vc.immediate, render_state, prof); + break; + default: + fmt::print("Generic encountered unknown DMA in handle_dma_stream.\n"); + fmt::print("Bytes remaining: {}\n", bytes); + fmt::print("VIF: {}\n", vc.print()); + ASSERT(false); + } + } +} + +void GenericRenderer::draw_debug_window() { + ImGui::Text("Skipped %d tags", m_skipped_tags); + ImGui::Text("Debug:\n%s\n", m_debug.c_str()); + if (ImGui::TreeNode("Direct")) { + m_direct.draw_debug_window(); + ImGui::TreePop(); + } +} + +u32 GenericRenderer::unpack32_4(const VifCodeUnpack& up, const u8* data, u32 imm) { + ASSERT(vu.stcycl == 0x404); + ASSERT(!up.is_unsigned); + u32 addr = up.addr_qw; + ASSERT(imm != 0); + // ASSERT(!m_vif.stmod); + ASSERT(!up.use_tops_flag); + // if (up.use_tops_flag) { + // addr += xitop(); + // } + + u32 start_in_buff = (addr)*16; + u32 end_in_buff = start_in_buff + imm * 16; + ASSERT(start_in_buff < sizeof(m_buffer.data)); + ASSERT(end_in_buff <= sizeof(m_buffer.data)); + memcpy(m_buffer.data + start_in_buff, data, imm * 16); + + // fmt::print("---------------------------------unpack32_4: {} to {}\n", addr, addr + imm); + return imm * 16; +} + +u32 GenericRenderer::unpack32_3(const VifCodeUnpack& up, const u8* data, u32 imm) { + u32 bytes_read = 0; + ASSERT(!up.use_tops_flag); + ASSERT(!up.is_unsigned); + ASSERT(vu.stcycl == 0x103); // w = 1, c = 3 + ASSERT(imm != 0); + + for (u32 i = 0; i < imm; i++) { + u32 xyzw[4]; + memcpy(xyzw, data + bytes_read, 12); + bytes_read += 12; + xyzw[3] = 0xbeef; + + // check for garbage going into GENERIC VU1 code. + float f[3]; + memcpy(f, xyzw, 12); + // if (std::abs(f[0]) > 100000) { + // fmt::print("VERY SUSPICIOUS VERTEX: {} 0x{:x} at 0x{:x}\n", f[0], xyzw[0], + // (data + bytes_read) - g_ee_main_mem); + // } + + // fmt::print("vtx: {} {} {}\n", f[0], f[1], f[2]); + u32 total_addr = 16 * (up.addr_qw + 3 * i); + ASSERT(total_addr + 16 <= sizeof(m_buffer.data)); + memcpy(m_buffer.data + total_addr, xyzw, 16); + } + // fmt::print("---------------------------------unpack32_3: {} to {} imm {}\n", up.addr_qw, + // (up.addr_qw + 3 * imm), imm); + return bytes_read; +} + +u32 GenericRenderer::unpack8_4(const VifCodeUnpack& up, const u8* data, u32 imm) { + u32 bytes_read = 0; + ASSERT(!up.use_tops_flag); + ASSERT(up.is_unsigned); + ASSERT(vu.stcycl == 0x103); // w = 1, c = 3 + ASSERT(imm != 0); + for (u32 i = 0; i < imm; i++) { + u32 xyzw[4] = {data[0], data[1], data[2], data[3]}; + bytes_read += 4; + data += 4; + u32 total_addr = 16 * (up.addr_qw + 3 * i); + ASSERT(total_addr + 16 <= sizeof(m_buffer.data)); + memcpy(m_buffer.data + total_addr, xyzw, 16); + } + // fmt::print("---------------------------------unpack8_4: {} to {} imm {}\n", up.addr_qw, + // (up.addr_qw + 3 * imm), imm); + return bytes_read; +} + +u32 GenericRenderer::unpack16_2(const VifCodeUnpack& up, const u8* data, u32 imm) { + u32 bytes_read = 0; + ASSERT(!up.use_tops_flag); + ASSERT(!up.is_unsigned); + ASSERT(vu.stcycl == 0x103); // w = 1, c = 3 + ASSERT(imm != 0); + for (u32 i = 0; i < imm; i++) { + s32 xyzw[4]; + s16 x, y; + memcpy(&x, data + bytes_read, 2); + memcpy(&y, data + bytes_read + 2, 2); + bytes_read += 4; + xyzw[0] = x; + xyzw[1] = y; + xyzw[2] = 0; + xyzw[3] = 0; + + u32 total_addr = 16 * (up.addr_qw + 3 * i); + ASSERT(total_addr + 16 <= sizeof(m_buffer.data)); + memcpy(m_buffer.data + total_addr, xyzw, 16); + } + // fmt::print("---------------------------------unpack16_2: {} to {} imm {}\n", up.addr_qw, + // (up.addr_qw + 3 * imm), imm); + return bytes_read; +} + +void GenericRenderer::mscal(int imm, SharedRenderState* render_state, ScopedProfilerNode& prof) { + m_debug += fmt::format("mscal: {}\n", imm); + switch (imm) { + case 0: + mscal0(); + break; + default: + mscal_dispatch(imm, render_state, prof); + break; + } +} + +void GenericRenderer::xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof) { + if (render_state->enable_generic_xgkick) { + m_direct.render_gif(m_buffer.data + (16 * addr), UINT32_MAX, render_state, prof); + } +} \ No newline at end of file diff --git a/game/graphics/opengl_renderer/GenericRenderer.h b/game/graphics/opengl_renderer/GenericRenderer.h new file mode 100644 index 0000000000..4f2c3b2dc3 --- /dev/null +++ b/game/graphics/opengl_renderer/GenericRenderer.h @@ -0,0 +1,62 @@ +#pragma once + +#include "game/graphics/opengl_renderer/BucketRenderer.h" +#include "game/graphics/opengl_renderer/DirectRenderer.h" +#include "game/common/vu.h" + +class GenericRenderer : public BucketRenderer { + public: + GenericRenderer(const std::string& name, BucketId my_id); + void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override; + void draw_debug_window() override; + + private: + u32 unpack32_4(const VifCodeUnpack& up, const u8* data, u32 imm); + u32 unpack32_3(const VifCodeUnpack& up, const u8* data, u32 imm); + u32 unpack8_4(const VifCodeUnpack& up, const u8* data, u32 imm); + u32 unpack16_2(const VifCodeUnpack& up, const u8* data, u32 imm); + + void mscal(int imm, SharedRenderState* render_state, ScopedProfilerNode& prof); + void mscal0(); + void mscal_dispatch(int imm, SharedRenderState* render_state, ScopedProfilerNode& prof); + void handle_dma_stream(const u8* data, + u32 bytes, + SharedRenderState* render_state, + ScopedProfilerNode& prof); + void lq_buffer(Mask mask, Vf& dest, u16 addr); + void isw_buffer(Mask mask, u16 val, u16 addr); + void ilw_buffer(Mask mask, u16& dest, u16 addr); + void xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof); + + void sq_buffer(Mask mask, const Vf& data, u32 qw) { + ASSERT(qw * 16 < sizeof(m_buffer.data)); + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + memcpy(m_buffer.data + qw * 16 + i * 4, data.data + i, 4); + } + } + } + + int m_skipped_tags = 0; + DirectRenderer m_direct; + std::string m_debug; + + struct Vu { + u32 row[4]; + u32 stcycl = 0; + Vf vf01, vf02, vf03, vf04, vf05, vf06, vf07, vf08, vf09, vf10, vf11, vf12, vf13, vf14, vf15, + vf16, vf17, vf18, vf19, vf20, vf21, vf22, vf23, vf24, vf25, vf26, vf27, vf28, vf29, vf30, + vf31; + const Vf vf00; + u16 vi01, vi02, vi03, vi04, vi05, vi06, vi07, vi09, vi08, vi11, vi12, vi13, vi10, vi14, vi15; + float I, P, Q; + + Accumulator acc; + const u16 vi00 = 0; + Vu() : vf00(0, 0, 0, 1) {} + } vu; + + struct alignas(16) BufferMemory { + u8 data[1024 * 16]; + } m_buffer; +}; diff --git a/game/graphics/opengl_renderer/MercRenderer.cpp b/game/graphics/opengl_renderer/MercRenderer.cpp index 26a58fae4c..093c385e21 100644 --- a/game/graphics/opengl_renderer/MercRenderer.cpp +++ b/game/graphics/opengl_renderer/MercRenderer.cpp @@ -340,7 +340,7 @@ void MercRenderer::draw_debug_window() { } void MercRenderer::xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof) { - if (m_enable_send_to_direct) { + if (m_enable_send_to_direct && render_state->enable_merc_xgkick) { m_direct.render_gif(m_buffer.data + (16 * addr), UINT32_MAX, render_state, prof); } } diff --git a/game/graphics/opengl_renderer/MercRenderer.h b/game/graphics/opengl_renderer/MercRenderer.h index 67175285f7..36d7f7bf9e 100644 --- a/game/graphics/opengl_renderer/MercRenderer.h +++ b/game/graphics/opengl_renderer/MercRenderer.h @@ -3,426 +3,7 @@ #include "game/graphics/opengl_renderer/BucketRenderer.h" #include "common/math/Vector.h" #include "game/graphics/opengl_renderer/DirectRenderer.h" - -#include "immintrin.h" - -enum class Mask { - NONE = 0, - x = 1, - y = 2, - xy = 3, - z = 4, - xz = 5, - yz = 6, - xyz = 7, - w = 8, - xw = 9, - yw = 10, - xyw = 11, - zw = 12, - xzw = 13, - yzw = 14, - xyzw = 15 -}; - -#ifdef __linux__ -#define REALLY_INLINE __attribute__((always_inline)) -#else -#define REALLY_INLINE __forceinline -#endif - -// note: must be aligned. -static inline REALLY_INLINE void copy_vector(void* dest, const void* src) { - __m128 val = _mm_load_ps((const float*)src); - _mm_store_ps((float*)dest, val); -} - -inline float vu_max(float a, float b) { - return std::max(b, a); - // s32 ai, bi; - // memcpy(&ai, &a, 4); - // memcpy(&bi, &b, 4); - // bool flip = ai < 0 && bi < 0; - // if (ai > bi) { - // return flip ? b : a; - // } else { - // return flip ? a : b; - // } -} - -inline float vu_min(float a, float b) { - s32 ai, bi; - memcpy(&ai, &a, 4); - memcpy(&bi, &b, 4); - bool flip = ai < 0 && bi < 0; - if (ai > bi) { - return flip ? a : b; - } else { - return flip ? b : a; - } -} - -struct alignas(16) Vf { - REALLY_INLINE __m128 load() const { return _mm_load_ps(data); } - - REALLY_INLINE void move_xyzw(const Vf& src) { copy_vector(data, src.data); } - - float data[4]; - float& x() { return data[0]; } - float& y() { return data[1]; } - float& z() { return data[2]; } - float& w() { return data[3]; } - - const float& x() const { return data[0]; } - const float& y() const { return data[1]; } - const float& z() const { return data[2]; } - const float& w() const { return data[3]; } - - u16 x_as_u16() const { - u16 result; - memcpy(&result, &data[0], 2); - return result; - } - - u16 y_as_u16() const { - u16 result; - memcpy(&result, &data[1], 2); - return result; - } - - u16 z_as_u16() const { - u16 result; - memcpy(&result, &data[2], 2); - return result; - } - - u16 w_as_u16() const { - u16 result; - memcpy(&result, &data[3], 2); - return result; - } - - u32 x_as_u32() const { - u32 result; - memcpy(&result, &data[0], 4); - return result; - } - - u32 y_as_u32() const { - u32 result; - memcpy(&result, &data[1], 4); - return result; - } - - u32 z_as_u32() const { - u32 result; - memcpy(&result, &data[2], 4); - return result; - } - - u32 w_as_u32() const { - u32 result; - memcpy(&result, &data[3], 4); - return result; - } - - Vf() = default; - Vf(const math::Vector4f& vec) { memcpy(data, vec.data(), 16); } - Vf(float a, float b, float c, float d) { - data[0] = a; - data[1] = b; - data[2] = c; - data[3] = d; - } - - std::string str_float() const { return fmt::format("{} {} {} {}", x(), y(), z(), w()); } - - float& operator[](int i) { return data[i]; } - float operator[](int i) const { return data[i]; } - - void mr32(Mask mask, const Vf& other) { - float temp[4]; - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - temp[i] = other[(i + 1) % 4]; - } - } - - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = temp[i]; - } - } - } - - REALLY_INLINE void mr32_z(const Vf& other) { data[2] = other.data[3]; } - - void mfir(Mask mask, s16 in) { - s32 sext = in; - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - memcpy(data + i, &sext, 4); - } - } - } - - void maxi(Mask mask, const Vf& other, float I) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = vu_max(other[i], I); - } - } - } - - void max(Mask mask, const Vf& other, float I) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = vu_max(other[i], I); - } - } - } - - void max(Mask mask, const Vf& other, const Vf& b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = vu_max(other[i], b[i]); - } - } - } - - REALLY_INLINE void max_xyzw(const Vf& a, const Vf& b) { - _mm_store_ps(data, _mm_max_ps(_mm_load_ps(a.data), _mm_load_ps(b.data))); - } - - REALLY_INLINE void max_xyzw(const Vf& a, float b) { - _mm_store_ps(data, _mm_max_ps(_mm_load_ps(a.data), _mm_set1_ps(b))); - } - - REALLY_INLINE void mini_xyzw(const Vf& a, const Vf& b) { - _mm_store_ps(data, _mm_min_ps(_mm_load_ps(a.data), _mm_load_ps(b.data))); - } - - REALLY_INLINE void mini_xyzw(const Vf& a, float b) { - _mm_store_ps(data, _mm_min_ps(_mm_load_ps(a.data), _mm_set1_ps(b))); - } - - void minii(Mask mask, const Vf& other, float I) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = vu_min(other[i], I); - } - } - } - - void mini(Mask mask, const Vf& other, float I) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = vu_min(other[i], I); - } - } - } - - void move(Mask mask, const Vf& other) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = other[i]; - } - } - } - - void mfp(Mask mask, float other) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = other; - } - } - } - - void add(Mask mask, const Vf& a, const Vf& b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = a[i] + b[i]; - } - } - } - - REALLY_INLINE void add_xyzw(const Vf& a, const Vf& b) { - _mm_store_ps(data, _mm_add_ps(_mm_load_ps(a.data), _mm_load_ps(b.data))); - } - - void add(Mask mask, const Vf& a, float b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = a[i] + b; - } - } - } - - REALLY_INLINE void mul_xyzw(const Vf& a, const Vf& b) { - _mm_store_ps(data, _mm_mul_ps(_mm_load_ps(a.data), _mm_load_ps(b.data))); - } - - REALLY_INLINE void mul_xyzw(const Vf& a, float b) { - _mm_store_ps(data, _mm_mul_ps(_mm_load_ps(a.data), _mm_set1_ps(b))); - } - - void mul(Mask mask, const Vf& a, const Vf& b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = a[i] * b[i]; - } - } - } - - void mul(Mask mask, const Vf& a, float b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = a[i] * b; - } - } - } - - void itof0(Mask mask, const Vf& a) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - s32 val; - memcpy(&val, &a.data[i], 4); - data[i] = val; - } - } - } - - void itof15(Mask mask, const Vf& a) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - s32 val; - memcpy(&val, &a.data[i], 4); - data[i] = ((float)val) * (1.f / 32768.f); - ; - } - } - } - - void ftoi4(Mask mask, const Vf& a) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - s32 val = a.data[i] * 16.f; - memcpy(&data[i], &val, 4); - } - } - } - - void ftoi0(Mask mask, const Vf& a) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - s32 val = a.data[i]; - memcpy(&data[i], &val, 4); - } - } - } -}; - -struct alignas(16) Accumulator { - float data[4]; - - void adda(Mask mask, const Vf& a, float b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = a[i] + b; - } - } - } - - void madda(Mask mask, const Vf& a, const Vf& b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] += a[i] * b[i]; - } - } - } - - void madda(Mask mask, const Vf& a, float b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] += a[i] * b; - } - } - } - - REALLY_INLINE void madda_xyzw(const Vf& _a, float _b) { - auto b = _mm_set1_ps(_b); - auto a = _mm_load_ps(_a.data); - auto acc = _mm_load_ps(data); - _mm_store_ps(data, _mm_add_ps(_mm_mul_ps(a, b), acc)); - } - - REALLY_INLINE void madda_xyzw(const Vf& _a, const Vf& _b) { - auto b = _mm_load_ps(_b.data); - auto a = _mm_load_ps(_a.data); - auto acc = _mm_load_ps(data); - _mm_store_ps(data, _mm_add_ps(_mm_mul_ps(a, b), acc)); - } - - void madd(Mask mask, Vf& dest, const Vf& a, const Vf& b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - dest[i] = data[i] + a[i] * b[i]; - } - } - } - - REALLY_INLINE void madd_xyzw(Vf& dest, const Vf& _a, float _b) { - auto b = _mm_set1_ps(_b); - auto a = _mm_load_ps(_a.data); - auto acc = _mm_load_ps(data); - _mm_store_ps(dest.data, _mm_add_ps(_mm_mul_ps(a, b), acc)); - } - - REALLY_INLINE void madd_xyz(Vf& dest, const Vf& _a, float _b) { - auto b = _mm_set1_ps(_b); - auto a = _mm_load_ps(_a.data); - auto acc = _mm_load_ps(data); - auto prod = _mm_add_ps(_mm_mul_ps(a, b), acc); - prod = _mm_blend_ps(prod, _mm_load_ps(dest.data), 0b1000); - _mm_store_ps(dest.data, prod); - } - - void madd(Mask mask, Vf& dest, const Vf& a, float b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - dest[i] = data[i] + a[i] * b; - } - } - } - - void mula(Mask mask, const Vf& a, const Vf& b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = a[i] * b[i]; - } - } - } - - void mula(Mask mask, const Vf& a, float b) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - data[i] = a[i] * b; - } - } - } - - REALLY_INLINE void mula_xyzw(const Vf& _a, float _b) { - auto b = _mm_set1_ps(_b); - auto a = _mm_load_ps(_a.data); - _mm_store_ps(data, _mm_mul_ps(a, b)); - } - - REALLY_INLINE void mula_xyzw(const Vf& _a, const Vf& _b) { - auto b = _mm_load_ps(_b.data); - auto a = _mm_load_ps(_a.data); - _mm_store_ps(data, _mm_mul_ps(a, b)); - } -}; +#include "game/common/vu.h" class MercRenderer : public BucketRenderer { public: diff --git a/game/graphics/opengl_renderer/OpenGLRenderer.cpp b/game/graphics/opengl_renderer/OpenGLRenderer.cpp index 35e8929e6b..3e023feb67 100644 --- a/game/graphics/opengl_renderer/OpenGLRenderer.cpp +++ b/game/graphics/opengl_renderer/OpenGLRenderer.cpp @@ -13,6 +13,7 @@ #include "game/graphics/opengl_renderer/tfrag/Tie3.h" #include "game/graphics/opengl_renderer/MercRenderer.h" #include "game/graphics/opengl_renderer/EyeRenderer.h" +#include "game/graphics/opengl_renderer/GenericRenderer.h" // for the vif callback #include "game/kernel/kmachine.h" @@ -85,29 +86,31 @@ void OpenGLRenderer::init_bucket_renderers() { //----------------------- // LEVEL 0 tfrag texture //----------------------- - init_bucket_renderer("tfrag-tex-0", BucketId::TFRAG_TEX_LEVEL0); // 5 - init_bucket_renderer("tfrag-0", BucketId::TFRAG_LEVEL0, normal_tfrags, false, 0); // 6 + init_bucket_renderer("l0-tfrag-tex", BucketId::TFRAG_TEX_LEVEL0); // 5 + init_bucket_renderer("l0-tfrag-tfrag", BucketId::TFRAG_LEVEL0, normal_tfrags, false, + 0); // 6 // 7 // 8 - init_bucket_renderer("tie-0", BucketId::TIE_LEVEL0, 0); // 9 - init_bucket_renderer("merc-tf-0", BucketId::MERC_TFRAG_TEX_LEVEL0); // 10 - // 11 + init_bucket_renderer("l0-tfrag-tie", BucketId::TIE_LEVEL0, 0); // 9 + init_bucket_renderer("l0-tfrag-merc", BucketId::MERC_TFRAG_TEX_LEVEL0); // 10 + init_bucket_renderer("l0-tfrag-gmerc", BucketId::GMERC_TFRAG_TEX_LEVEL0); // 11 //----------------------- // LEVEL 1 tfrag texture //----------------------- - init_bucket_renderer("tfrag-tex-1", BucketId::TFRAG_TEX_LEVEL1); // 12 - init_bucket_renderer("tfrag-1", BucketId::TFRAG_LEVEL1, normal_tfrags, false, 1); + init_bucket_renderer("l1-tfrag-tex", BucketId::TFRAG_TEX_LEVEL1); // 12 + init_bucket_renderer("l1-tfrag-tfrag", BucketId::TFRAG_LEVEL1, normal_tfrags, false, + 1); // 14 // 15 - init_bucket_renderer("tie-1", BucketId::TIE_LEVEL1, 1); - init_bucket_renderer("merc-tf-1", BucketId::MERC_TFRAG_TEX_LEVEL1); // 17 - // 18?? + init_bucket_renderer("l1-tfrag-tie", BucketId::TIE_LEVEL1, 1); + init_bucket_renderer("l1-tfrag-merc", BucketId::MERC_TFRAG_TEX_LEVEL1); // 17 + init_bucket_renderer("l1-tfrag-gmerc", BucketId::GMERC_TFRAG_TEX_LEVEL1); // 18 //----------------------- // LEVEL 0 shrub texture //----------------------- - init_bucket_renderer("shrub-tex-0", BucketId::SHRUB_TEX_LEVEL0); // 19 + init_bucket_renderer("l0-shrub-tex", BucketId::SHRUB_TEX_LEVEL0); // 19 // 20 // 21 // 22 @@ -117,75 +120,82 @@ void OpenGLRenderer::init_bucket_renderers() { //----------------------- // LEVEL 1 shrub texture //----------------------- - init_bucket_renderer("shrub-tex-1", BucketId::SHRUB_TEX_LEVEL1); // 25 + init_bucket_renderer("l1-shrub-tex", BucketId::SHRUB_TEX_LEVEL1); // 25 // 26 // 27 // 28 // 29 - // 30 + + // I don't think this is actually used? or it might be wrong. + init_bucket_renderer("common-shrub-generic", BucketId::GENERIC_SHRUB); // 30 //----------------------- // LEVEL 0 alpha texture //----------------------- - init_bucket_renderer("alpha-tex-0", BucketId::ALPHA_TEX_LEVEL0); // 31 - init_bucket_renderer("sky-blend-and-tfrag-trans-0", + init_bucket_renderer("l0-alpha-tex", BucketId::ALPHA_TEX_LEVEL0); // 31 + init_bucket_renderer("l0-alpha-sky-blend-and-tfrag-trans", BucketId::TFRAG_TRANS0_AND_SKY_BLEND_LEVEL0, 0, sky_gpu_blender, sky_cpu_blender); // 32 // 33 - init_bucket_renderer("tfrag-dirt-0", BucketId::TFRAG_DIRT_LEVEL0, dirt_tfrags, false, + init_bucket_renderer("l0-alpha-tfrag", BucketId::TFRAG_DIRT_LEVEL0, dirt_tfrags, false, 0); // 34 // 35 - init_bucket_renderer("tfrag-ice-0", BucketId::TFRAG_ICE_LEVEL0, ice_tfrags, false, 0); + init_bucket_renderer("l0-alpha-tfrag-ice", BucketId::TFRAG_ICE_LEVEL0, ice_tfrags, + false, 0); // 37 //----------------------- // LEVEL 1 alpha texture //----------------------- - init_bucket_renderer("alpha-tex-1", BucketId::ALPHA_TEX_LEVEL1); // 38 - init_bucket_renderer("sky-blend-and-tfrag-trans-1", + init_bucket_renderer("l1-alpha-tex", BucketId::ALPHA_TEX_LEVEL1); // 38 + init_bucket_renderer("l1-alpha-sky-blend-and-tfrag-trans", BucketId::TFRAG_TRANS1_AND_SKY_BLEND_LEVEL1, 1, sky_gpu_blender, sky_cpu_blender); // 39 // 40 - init_bucket_renderer("tfrag-dirt-1", BucketId::TFRAG_DIRT_LEVEL1, dirt_tfrags, false, + init_bucket_renderer("l1-alpha-tfrag-dirt", BucketId::TFRAG_DIRT_LEVEL1, dirt_tfrags, + false, 1); // 41 // 42 - init_bucket_renderer("tfrag-ice-1", BucketId::TFRAG_ICE_LEVEL1, ice_tfrags, false, 1); + init_bucket_renderer("l1-alpha-tfrag-ice", BucketId::TFRAG_ICE_LEVEL1, ice_tfrags, + false, 1); // 44 - init_bucket_renderer("merc-after-alpha", BucketId::MERC_AFTER_ALPHA); - // 46? + + init_bucket_renderer("common-alpha-merc", BucketId::MERC_AFTER_ALPHA); + + init_bucket_renderer("common-alpha-generic", BucketId::GENERIC_ALPHA); // 46 // 47? //----------------------- // LEVEL 0 pris texture //----------------------- - init_bucket_renderer("pris-tex-0", BucketId::PRIS_TEX_LEVEL0); // 48 - init_bucket_renderer("merc-pris-0", BucketId::MERC_PRIS_LEVEL0); // 49 - // 50 + init_bucket_renderer("l0-pris-tex", BucketId::PRIS_TEX_LEVEL0); // 48 + init_bucket_renderer("l0-pris-merc", BucketId::MERC_PRIS_LEVEL0); // 49 + init_bucket_renderer("l0-pris-generic", BucketId::GENERIC_PRIS_LEVEL0); // 50 //----------------------- // LEVEL 1 pris texture //----------------------- - init_bucket_renderer("pris-tex-1", BucketId::PRIS_TEX_LEVEL1); // 51 - init_bucket_renderer("merc-pris-1", BucketId::MERC_PRIS_LEVEL1); // 52 - // 53 + init_bucket_renderer("l1-pris-tex", BucketId::PRIS_TEX_LEVEL1); // 51 + init_bucket_renderer("l1-pris-merc", BucketId::MERC_PRIS_LEVEL1); // 52 + init_bucket_renderer("l1-pris-generic", BucketId::GENERIC_PRIS_LEVEL1); // 53 - init_bucket_renderer("merc-eyes-after-pris", BucketId::MERC_EYES_AFTER_PRIS); // 54 - init_bucket_renderer("merc-after-pris", BucketId::MERC_AFTER_PRIS); // 55 - // 56? + init_bucket_renderer("common-pris-eyes", BucketId::MERC_EYES_AFTER_PRIS); // 54 + init_bucket_renderer("common-pris-merc", BucketId::MERC_AFTER_PRIS); // 55 + init_bucket_renderer("common-pris-generic", BucketId::GENERIC_PRIS); // 56 //----------------------- // LEVEL 0 water texture //----------------------- - init_bucket_renderer("water-tex-0", BucketId::WATER_TEX_LEVEL0); // 57 - init_bucket_renderer("merc-water-0", BucketId::MERC_WATER_LEVEL0); // 58 - // 59 + init_bucket_renderer("l0-water-tex", BucketId::WATER_TEX_LEVEL0); // 57 + init_bucket_renderer("l0-water-merc", BucketId::MERC_WATER_LEVEL0); // 58 + init_bucket_renderer("l0-water-generic", BucketId::GENERIC_WATER_LEVEL0); // 59 //----------------------- // LEVEL 1 water texture //----------------------- - init_bucket_renderer("water-tex-1", BucketId::WATER_TEX_LEVEL1); // 60 - init_bucket_renderer("merc-water-1", BucketId::MERC_WATER_LEVEL1); // 61 - // 62 + init_bucket_renderer("l1-water-tex", BucketId::WATER_TEX_LEVEL1); // 60 + init_bucket_renderer("l1-water-merc", BucketId::MERC_WATER_LEVEL1); // 61 + init_bucket_renderer("l1-water-generic", BucketId::GENERIC_WATER_LEVEL1); // 62 // 63? // 64? @@ -193,7 +203,7 @@ void OpenGLRenderer::init_bucket_renderers() { //----------------------- // COMMON texture //----------------------- - init_bucket_renderer("pre-sprite-tex", BucketId::PRE_SPRITE_TEX); // 65 + init_bucket_renderer("common-tex", BucketId::PRE_SPRITE_TEX); // 65 std::vector> sprite_renderers; // the first renderer added will be the default for sprite. @@ -280,6 +290,8 @@ void OpenGLRenderer::draw_renderer_selection_window() { ImGui::Checkbox("Sky CPU", &m_render_state.use_sky_cpu); ImGui::Checkbox("Occlusion Cull", &m_render_state.use_occlusion_culling); ImGui::Checkbox("Render Debug (slower)", &m_render_state.render_debug); + ImGui::Checkbox("Merc XGKICK", &m_render_state.enable_merc_xgkick); + ImGui::Checkbox("Generic XGKICK", &m_render_state.enable_generic_xgkick); for (size_t i = 0; i < m_bucket_renderers.size(); i++) { auto renderer = m_bucket_renderers[i].get(); diff --git a/game/graphics/opengl_renderer/shaders/direct_basic_textured.frag b/game/graphics/opengl_renderer/shaders/direct_basic_textured.frag index 348bd277d5..fd9451a0c4 100644 --- a/game/graphics/opengl_renderer/shaders/direct_basic_textured.frag +++ b/game/graphics/opengl_renderer/shaders/direct_basic_textured.frag @@ -5,6 +5,7 @@ out vec4 color; in vec4 fragment_color; in vec3 tex_coord; uniform float alpha_reject; +uniform float color_mult; in flat uvec2 tex_info; @@ -41,6 +42,7 @@ void main() { T0.w = 1.0; } color = fragment_color * T0 * 2.0; + color.xyz *= color_mult; if (color.a < alpha_reject) { discard; } diff --git a/game/graphics/opengl_renderer/tfrag/tfrag_common.cpp b/game/graphics/opengl_renderer/tfrag/tfrag_common.cpp index 067b4cec8b..4861d7ec03 100644 --- a/game/graphics/opengl_renderer/tfrag/tfrag_common.cpp +++ b/game/graphics/opengl_renderer/tfrag/tfrag_common.cpp @@ -302,6 +302,9 @@ void interp_time_of_day_fast_avx2(const float weights[8], } #else // unreachable. + (void)weights; + (void)in; + (void)out; ASSERT(false); #endif } diff --git a/game/mips2c/functions/generic_effect.cpp b/game/mips2c/functions/generic_effect.cpp new file mode 100644 index 0000000000..a4fec92ecd --- /dev/null +++ b/game/mips2c/functions/generic_effect.cpp @@ -0,0 +1,1953 @@ + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" + +// clang-format off + +namespace Mips2C { +namespace generic_prepare_dma_double { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* +} cache; + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + c->daddiu(sp, sp, -128); // daddiu sp, sp, -128 + c->sd(ra, 12432, at); // sd ra, 12432(at) + c->sq(s0, 12448, at); // sq s0, 12448(at) + c->sq(s1, 12464, at); // sq s1, 12464(at) + c->sq(s2, 12480, at); // sq s2, 12480(at) + c->sq(s3, 12496, at); // sq s3, 12496(at) + c->sq(s4, 12512, at); // sq s4, 12512(at) + c->sq(s5, 12528, at); // sq s5, 12528(at) + c->sq(gp, 12544, at); // sq gp, 12544(at) + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->lw(a3, 60, at); // lw a3, 60(at) + // nop // sll r0, r0, 0 + c->lbu(v1, 16, a3); // lbu v1, 16(a3) + // nop // sll r0, r0, 0 + c->lh(a0, 18, a3); // lh a0, 18(a3) + // nop // sll r0, r0, 0 + c->lw(t7, 40, at); // lw t7, 40(at) + c->sll(a2, v1, 2); // sll a2, v1, 2 + c->daddiu(a1, a0, 3); // daddiu a1, a0, 3 + c->daddu(a2, a2, v1); // daddu a2, a2, v1 + c->addiu(t0, r0, -4); // addiu t0, r0, -4 + c->and_(t6, a1, t0); // and t6, a1, t0 + c->sll(a1, a2, 4); // sll a1, a2, 4 + c->daddu(a2, t6, t6); // daddu a2, t6, t6 + c->daddiu(a1, a1, 112); // daddiu a1, a1, 112 + c->daddu(a2, a2, t6); // daddu a2, a2, t6 + c->dsll(t0, t6, 2); // dsll t0, t6, 2 + // nop // sll r0, r0, 0 + c->daddiu(t0, t0, 15); // daddiu t0, t0, 15 + c->dsll(a2, a2, 2); // dsll a2, a2, 2 + c->dsra(t0, t0, 4); // dsra t0, t0, 4 + c->daddiu(a2, a2, 15); // daddiu a2, a2, 15 + c->dsll(t0, t0, 4); // dsll t0, t0, 4 + c->dsra(t9, a2, 4); // dsra t9, a2, 4 + c->dsll(t2, t9, 4); // dsll t2, t9, 4 + c->mov64(a2, t7); // or a2, t7, r0 + c->dsra(t8, a1, 4); // dsra t8, a1, 4 + c->daddu(t1, a2, a1); // daddu t1, a2, a1 + // nop // sll r0, r0, 0 + c->daddu(gp, t1, t2); // daddu gp, t1, t2 + // nop // sll r0, r0, 0 + c->daddu(t2, gp, t0); // daddu t2, gp, t0 + // nop // sll r0, r0, 0 + c->daddu(t3, t2, t0); // daddu t3, t2, t0 + // nop // sll r0, r0, 0 + c->daddu(ra, t3, a1); // daddu ra, t3, a1 + // nop // sll r0, r0, 0 + c->daddu(t4, ra, t0); // daddu t4, ra, t0 + // nop // sll r0, r0, 0 + c->daddu(t5, t4, t0); // daddu t5, t4, t0 + c->daddiu(t0, t1, 32); // daddiu t0, t1, 32 + c->daddiu(t1, gp, 64); // daddiu t1, gp, 64 + c->daddiu(t2, t2, 80); // daddiu t2, t2, 80 + c->daddiu(a1, t3, 80); // daddiu a1, t3, 80 + c->daddiu(t3, ra, 112); // daddiu t3, ra, 112 + c->daddiu(t4, t4, 128); // daddiu t4, t4, 128 + c->daddiu(t5, t5, 128); // daddiu t5, t5, 128 + c->sq(r0, -16, t0); // sq r0, -16(t0) + c->sq(r0, -32, t1); // sq r0, -32(t1) + c->sq(r0, -16, t1); // sq r0, -16(t1) + c->sq(r0, -32, t2); // sq r0, -32(t2) + c->sq(r0, -16, t2); // sq r0, -16(t2) + c->sq(r0, -16, a1); // sq r0, -16(a1) + c->sq(r0, -16, t3); // sq r0, -16(t3) + c->sq(r0, -32, t4); // sq r0, -32(t4) + c->sq(r0, -16, t4); // sq r0, -16(t4) + c->sq(r0, -16, t5); // sq r0, -16(t5) + c->lq(ra, 11744, at); // lq ra, 11744(at) + c->lq(gp, 11760, at); // lq gp, 11760(at) + c->lq(s5, 11776, at); // lq s5, 11776(at) + c->lq(s4, 11792, at); // lq s4, 11792(at) + c->lw(s3, 11984, at); // lw s3, 11984(at) + c->sq(ra, 0, a2); // sq ra, 0(a2) + c->sq(gp, 0, a1); // sq gp, 0(a1) + c->sq(s5, 0, t5); // sq s5, 0(t5) + c->sh(t9, 0, t5); // sh t9, 0(t5) + c->sq(s4, 16, t5); // sq s4, 16(t5) + c->sw(s3, 24, t5); // sw s3, 24(t5) + c->subu(t9, t5, t7); // subu t9, t5, t7 + c->sra(t9, t9, 4); // sra t9, t9, 4 + c->daddiu(t9, t9, -1); // daddiu t9, t9, -1 + c->sh(t9, 0, t7); // sh t9, 0(t7) + c->daddiu(t7, t9, 3); // daddiu t7, t9, 3 + c->sw(t7, 56, at); // sw t7, 56(at) + c->lw(t7, 76, at); // lw t7, 76(at) + c->dsubu(t9, t0, a2); // dsubu t9, t0, a2 + c->daddu(t7, t7, t9); // daddu t7, t7, t9 + // nop // sll r0, r0, 0 + c->lw(t9, 12, a2); // lw t9, 12(a2) + c->sll(ra, t8, 16); // sll ra, t8, 16 + c->lw(t8, 84, at); // lw t8, 84(at) + // nop // sll r0, r0, 0 + c->lw(gp, 12, a1); // lw gp, 12(a1) + c->or_(s4, t9, t8); // or s4, t9, t8 + c->lw(t9, 88, at); // lw t9, 88(at) + c->xori(s5, t8, 38); // xori s5, t8, 38 + // nop // sll r0, r0, 0 + c->or_(s4, s4, ra); // or s4, s4, ra + c->lw(t8, 11968, at); // lw t8, 11968(at) + // nop // sll r0, r0, 0 + c->lw(s3, 11988, at); // lw s3, 11988(at) + c->or_(gp, gp, s5); // or gp, gp, s5 + c->sw(s4, 12, a2); // sw s4, 12(a2) + c->or_(s5, gp, ra); // or s5, gp, ra + c->lw(ra, 11972, at); // lw ra, 11972(at) + c->daddiu(gp, t9, 1); // daddiu gp, t9, 1 + c->sw(s5, 12, a1); // sw s5, 12(a1) + c->daddiu(s4, t9, 2); // daddiu s4, t9, 2 + c->lw(s3, 11976, at); // lw s3, 11976(at) + c->dsll(t6, t6, 16); // dsll t6, t6, 16 + c->lw(s5, 11980, at); // lw s5, 11980(at) + c->or_(s4, ra, s4); // or s4, ra, s4 + c->lw(ra, 11984, at); // lw ra, 11984(at) + c->or_(s3, s3, gp); // or s3, s3, gp + c->lw(gp, 11992, at); // lw gp, 11992(at) + c->mov64(s2, t9); // or s2, t9, r0 + c->sw(t8, -8, t0); // sw t8, -8(t0) + c->or_(s5, s5, s2); // or s5, s5, s2 + c->sw(gp, 4, a1); // sw gp, 4(a1) + c->or_(s4, s4, t6); // or s4, s4, t6 + c->sw(ra, 0, a1); // sw ra, 0(a1) + c->or_(s3, s3, t6); // or s3, s3, t6 + c->sw(s4, -4, t0); // sw s4, -4(t0) + c->or_(s5, s5, t6); // or s5, s5, t6 + c->sw(s3, -4, t1); // sw s3, -4(t1) + c->addiu(s4, r0, 567); // addiu s4, r0, 567 + c->sw(s5, -4, t2); // sw s5, -4(t2) + bc = c->sgpr64(t9) != c->sgpr64(s4); // bne t9, s4, L59 + c->daddiu(t9, t9, 279); // daddiu t9, t9, 279 + if (bc) {goto block_2;} // branch non-likely + + // nop // sll r0, r0, 0 + c->addiu(t9, r0, 9); // addiu t9, r0, 9 + + block_2: + c->daddiu(s1, t9, 1); // daddiu s1, t9, 1 + c->lw(s0, 11976, at); // lw s0, 11976(at) + c->mov64(s3, t9); // or s3, t9, r0 + c->lw(s2, 11980, at); // lw s2, 11980(at) + c->daddiu(s5, t9, 2); // daddiu s5, t9, 2 + c->lw(s4, 11972, at); // lw s4, 11972(at) + c->or_(s1, s0, s1); // or s1, s0, s1 + c->sw(t8, -8, t3); // sw t8, -8(t3) + c->or_(t8, s2, s3); // or t8, s2, s3 + c->sw(gp, 24, t5); // sw gp, 24(t5) + c->or_(gp, s4, s5); // or gp, s4, s5 + // nop // sll r0, r0, 0 + c->or_(s5, s1, t6); // or s5, s1, t6 + c->sw(ra, 28, t5); // sw ra, 28(t5) + c->or_(t8, t8, t6); // or t8, t8, t6 + c->sw(s5, -4, t3); // sw s5, -4(t3) + c->or_(ra, gp, t6); // or ra, gp, t6 + c->sw(t8, -4, t4); // sw t8, -4(t4) + c->addiu(t6, r0, 567); // addiu t6, r0, 567 + c->sw(t7, 4, t5); // sw t7, 4(t5) + // nop // sll r0, r0, 0 + c->sw(ra, 12, t5); // sw ra, 12(t5) + bc = c->sgpr64(t9) != c->sgpr64(t6); // bne t9, t6, L60 + c->daddiu(t5, t9, 279); // daddiu t5, t9, 279 + if (bc) {goto block_4;} // branch non-likely + + // nop // sll r0, r0, 0 + c->addiu(t5, r0, 9); // addiu t5, r0, 9 + + block_4: + // nop // sll r0, r0, 0 + c->sw(t5, 88, at); // sw t5, 88(at) + // nop // sll r0, r0, 0 + c->sw(t0, 20, at); // sw t0, 20(at) + // nop // sll r0, r0, 0 + c->sw(t1, 24, at); // sw t1, 24(at) + // nop // sll r0, r0, 0 + c->sw(t2, 28, at); // sw t2, 28(at) + // nop // sll r0, r0, 0 + c->sw(t3, 32, at); // sw t3, 32(at) + // nop // sll r0, r0, 0 + c->sw(t4, 36, at); // sw t4, 36(at) + // nop // sll r0, r0, 0 + c->lw(t0, 64, at); // lw t0, 64(at) + // nop // sll r0, r0, 0 + c->lq(t1, 11808, at); // lq t1, 11808(at) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L63 + c->lq(t2, 11824, at); // lq t2, 11824(at) + if (bc) {goto block_10;} // branch non-likely + + // nop // sll r0, r0, 0 + c->lq(t3, 11840, at); // lq t3, 11840(at) + // nop // sll r0, r0, 0 + c->lq(t4, 11856, at); // lq t4, 11856(at) + // nop // sll r0, r0, 0 + c->sq(t1, 16, a2); // sq t1, 16(a2) + // nop // sll r0, r0, 0 + c->sq(t2, 32, a2); // sq t2, 32(a2) + // nop // sll r0, r0, 0 + c->sq(t3, 48, a2); // sq t3, 48(a2) + // nop // sll r0, r0, 0 + c->sq(t4, 64, a2); // sq t4, 64(a2) + // nop // sll r0, r0, 0 + c->sq(t1, 16, a1); // sq t1, 16(a1) + // nop // sll r0, r0, 0 + c->sq(t2, 32, a1); // sq t2, 32(a1) + // nop // sll r0, r0, 0 + c->sq(t3, 48, a1); // sq t3, 48(a1) + // nop // sll r0, r0, 0 + c->sq(t4, 64, a1); // sq t4, 64(a1) + // nop // sll r0, r0, 0 + c->lq(t1, 11872, at); // lq t1, 11872(at) + // nop // sll r0, r0, 0 + c->lq(t2, 11888, at); // lq t2, 11888(at) + // nop // sll r0, r0, 0 + c->lq(t3, 11936, at); // lq t3, 11936(at) + // nop // sll r0, r0, 0 + c->lq(t4, 12032, at); // lq t4, 12032(at) + // nop // sll r0, r0, 0 + c->sq(t1, 80, a2); // sq t1, 80(a2) + // nop // sll r0, r0, 0 + c->sq(t2, 96, a2); // sq t2, 96(a2) + // nop // sll r0, r0, 0 + c->sq(t3, 112, a2); // sq t3, 112(a2) + // nop // sll r0, r0, 0 + c->sq(t4, 80, a1); // sq t4, 80(a1) + // nop // sll r0, r0, 0 + c->sq(t3, 96, a1); // sq t3, 96(a1) + // nop // sll r0, r0, 0 + c->sq(t3, 112, a1); // sq t3, 112(a1) + c->daddiu(t2, a3, 22); // daddiu t2, a3, 22 + c->addiu(t3, r0, 0); // addiu t3, r0, 0 + c->mov64(t4, v1); // or t4, v1, r0 + c->addiu(t6, r0, 128); // addiu t6, r0, 128 + c->mov64(t1, a2); // or t1, a2, r0 + // nop // sll r0, r0, 0 + + block_6: + c->daddu(t1, t1, t6); // daddu t1, t1, t6 + c->lq(t6, 0, t0); // lq t6, 0(t0) + c->daddiu(t4, t4, -1); // daddiu t4, t4, -1 + c->lbu(t5, 0, t2); // lbu t5, 0(t2) + // nop // sll r0, r0, 0 + c->lq(t7, 16, t0); // lq t7, 16(t0) + c->daddu(t9, t5, t5); // daddu t9, t5, t5 + c->lq(t8, 32, t0); // lq t8, 32(t0) + c->daddu(ra, t9, t5); // daddu ra, t9, t5 + c->lq(t9, 48, t0); // lq t9, 48(t0) + c->daddiu(gp, ra, 9); // daddiu gp, ra, 9 + c->lq(ra, 64, t0); // lq ra, 64(t0) + c->daddiu(t0, t0, 80); // daddiu t0, t0, 80 + c->sq(t6, 0, t1); // sq t6, 0(t1) + // nop // sll r0, r0, 0 + c->sw(t3, 12, t1); // sw t3, 12(t1) + c->daddiu(t2, t2, 1); // daddiu t2, t2, 1 + c->sq(t7, 16, t1); // sq t7, 16(t1) + c->daddu(t3, t3, gp); // daddu t3, t3, gp + c->sw(t5, 28, t1); // sw t5, 28(t1) + // nop // sll r0, r0, 0 + c->sq(t8, 32, t1); // sq t8, 32(t1) + c->addiu(t6, r0, 80); // addiu t6, r0, 80 + c->sq(t9, 48, t1); // sq t9, 48(t1) + bc = ((s64)c->sgpr64(t4)) > 0; // bgtz t4, L61 + c->sq(ra, 64, t1); // sq ra, 64(t1) + if (bc) {goto block_6;} // branch non-likely + + c->ori(t0, t5, 32768); // ori t0, t5, 32768 + c->sw(a0, 52, at); // sw a0, 52(at) + // nop // sll r0, r0, 0 + c->sw(t0, 28, t1); // sw t0, 28(t1) + // nop // sll r0, r0, 0 + c->sw(v1, 92, a2); // sw v1, 92(a2) + // nop // sll r0, r0, 0 + c->sw(a0, 108, a2); // sw a0, 108(a2) + // nop // sll r0, r0, 0 + c->sw(r0, 124, a2); // sw r0, 124(a2) + c->daddiu(a3, a3, 22); // daddiu a3, a3, 22 + c->addiu(t0, r0, 0); // addiu t0, r0, 0 + c->mov64(t1, v1); // or t1, v1, r0 + c->lw(t6, 68, at); // lw t6, 68(at) + c->mov64(a2, a1); // or a2, a1, r0 + c->addiu(t8, r0, 128); // addiu t8, r0, 128 + // nop // sll r0, r0, 0 + c->lq(t2, 0, t6); // lq t2, 0(t6) + // nop // sll r0, r0, 0 + c->lq(t3, 16, t6); // lq t3, 16(t6) + // nop // sll r0, r0, 0 + c->lq(t4, 32, t6); // lq t4, 32(t6) + // nop // sll r0, r0, 0 + c->lq(t5, 48, t6); // lq t5, 48(t6) + // nop // sll r0, r0, 0 + c->lq(t6, 64, t6); // lq t6, 64(t6) + + block_8: + c->daddu(a2, a2, t8); // daddu a2, a2, t8 + c->lbu(t7, 0, a3); // lbu t7, 0(a3) + c->daddiu(t1, t1, -1); // daddiu t1, t1, -1 + c->sq(t2, 0, a2); // sq t2, 0(a2) + c->daddu(t8, t7, t7); // daddu t8, t7, t7 + c->sw(t0, 12, a2); // sw t0, 12(a2) + c->daddu(t8, t8, t7); // daddu t8, t8, t7 + c->sq(t3, 16, a2); // sq t3, 16(a2) + c->daddiu(t8, t8, 9); // daddiu t8, t8, 9 + c->sw(t7, 28, a2); // sw t7, 28(a2) + c->daddiu(a3, a3, 1); // daddiu a3, a3, 1 + // nop // sll r0, r0, 0 + c->daddu(t0, t0, t8); // daddu t0, t0, t8 + c->sq(t4, 32, a2); // sq t4, 32(a2) + c->addiu(t8, r0, 80); // addiu t8, r0, 80 + c->sq(t5, 48, a2); // sq t5, 48(a2) + bc = ((s64)c->sgpr64(t1)) > 0; // bgtz t1, L62 + c->sq(t6, 64, a2); // sq t6, 64(a2) + if (bc) {goto block_8;} // branch non-likely + + c->ori(a3, t7, 32768); // ori a3, t7, 32768 + c->sw(a0, 52, at); // sw a0, 52(at) + // nop // sll r0, r0, 0 + c->sw(a3, 28, a2); // sw a3, 28(a2) + // nop // sll r0, r0, 0 + c->sw(v1, 92, a1); // sw v1, 92(a1) + // nop // sll r0, r0, 0 + c->sw(a0, 108, a1); // sw a0, 108(a1) + //beq r0, r0, L65 // beq r0, r0, L65 + c->sw(r0, 124, a1); // sw r0, 124(a1) + goto block_13; // branch always + + + block_10: + // nop // sll r0, r0, 0 + c->lq(a3, 16, a2); // lq a3, 16(a2) + // nop // sll r0, r0, 0 + c->lq(t0, 32, a2); // lq t0, 32(a2) + // nop // sll r0, r0, 0 + c->lq(t1, 48, a2); // lq t1, 48(a2) + // nop // sll r0, r0, 0 + c->lq(t2, 64, a2); // lq t2, 64(a2) + // nop // sll r0, r0, 0 + c->sq(a3, 16, a1); // sq a3, 16(a1) + // nop // sll r0, r0, 0 + c->sq(t0, 32, a1); // sq t0, 32(a1) + // nop // sll r0, r0, 0 + c->sq(t1, 48, a1); // sq t1, 48(a1) + // nop // sll r0, r0, 0 + c->sq(t2, 64, a1); // sq t2, 64(a1) + // nop // sll r0, r0, 0 + c->lq(a3, 12032, at); // lq a3, 12032(at) + // nop // sll r0, r0, 0 + c->lq(t0, 11936, at); // lq t0, 11936(at) + // nop // sll r0, r0, 0 + c->sq(a3, 80, a1); // sq a3, 80(a1) + // nop // sll r0, r0, 0 + c->sq(t0, 96, a1); // sq t0, 96(a1) + // nop // sll r0, r0, 0 + c->sq(t0, 112, a1); // sq t0, 112(a1) + c->mov64(a3, v1); // or a3, v1, r0 + c->lw(t5, 68, at); // lw t5, 68(at) + c->mov64(t0, a1); // or t0, a1, r0 + c->addiu(t7, r0, 128); // addiu t7, r0, 128 + // nop // sll r0, r0, 0 + c->lq(t1, 0, t5); // lq t1, 0(t5) + // nop // sll r0, r0, 0 + c->lq(t2, 16, t5); // lq t2, 16(t5) + // nop // sll r0, r0, 0 + c->lq(t3, 32, t5); // lq t3, 32(t5) + // nop // sll r0, r0, 0 + c->lq(t4, 48, t5); // lq t4, 48(t5) + // nop // sll r0, r0, 0 + c->lq(t5, 64, t5); // lq t5, 64(t5) + c->daddu(a2, a2, t7); // daddu a2, a2, t7 + // nop // sll r0, r0, 0 + + block_11: + c->daddu(t0, t0, t7); // daddu t0, t0, t7 + c->lwu(t8, 12, a2); // lwu t8, 12(a2) + c->daddiu(a3, a3, -1); // daddiu a3, a3, -1 + c->lwu(t7, 28, a2); // lwu t7, 28(a2) + c->daddiu(a2, a2, 80); // daddiu a2, a2, 80 + c->sq(t1, 0, t0); // sq t1, 0(t0) + // nop // sll r0, r0, 0 + c->sw(t8, 12, t0); // sw t8, 12(t0) + // nop // sll r0, r0, 0 + c->sq(t2, 16, t0); // sq t2, 16(t0) + c->daddu(t8, t8, t6); // daddu t8, t8, t6 + c->sw(t7, 28, t0); // sw t7, 28(t0) + // nop // sll r0, r0, 0 + c->sq(t3, 32, t0); // sq t3, 32(t0) + c->addiu(t7, r0, 80); // addiu t7, r0, 80 + c->sq(t4, 48, t0); // sq t4, 48(t0) + bc = ((s64)c->sgpr64(a3)) > 0; // bgtz a3, L64 + c->sq(t5, 64, t0); // sq t5, 64(t0) + if (bc) {goto block_11;} // branch non-likely + + // nop // sll r0, r0, 0 + c->sw(a0, 52, at); // sw a0, 52(at) + // nop // sll r0, r0, 0 + c->sw(v1, 92, a1); // sw v1, 92(a1) + // nop // sll r0, r0, 0 + c->sw(a0, 108, a1); // sw a0, 108(a1) + // nop // sll r0, r0, 0 + c->sw(r0, 124, a1); // sw r0, 124(a1) + + block_13: + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + c->ld(ra, 12432, at); // ld ra, 12432(at) + c->lq(gp, 12544, at); // lq gp, 12544(at) + c->lq(s5, 12528, at); // lq s5, 12528(at) + c->lq(s4, 12512, at); // lq s4, 12512(at) + c->lq(s3, 12496, at); // lq s3, 12496(at) + c->lq(s2, 12480, at); // lq s2, 12480(at) + c->lq(s1, 12464, at); // lq s1, 12464(at) + c->lq(s0, 12448, at); // lq s0, 12448(at) + //jr ra // jr ra + c->daddiu(sp, sp, 128); // daddiu sp, sp, 128 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + gLinkedFunctionTable.reg("generic-prepare-dma-double", execute, 256); +} + +} // namespace generic_prepare_dma_double +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace generic_light_proc { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* +} cache; + + +void vcallms0(ExecutionContext* c) { + // this function does lighting calculations for 4 vertices. + // the input colors (u8's) are in vf5, vf6, vf7, vf8 + +// fmt::print("nromal:\n {}\n {}\n {}\n {}\n\n", c->vf_src(vf1).vf.print(), c->vf_src(vf2).vf.print(), c->vf_src(vf3).vf.print(), c->vf_src(vf4).vf.print()); +// //fmt::print("dir:\n {}\n {}\n {}\n\n", c->vf_src(vf10).vf.print(), c->vf_src(vf11).vf.print(), c->vf_src(vf12).vf.print()); +// +// // hack to see normals as colors +// c->vfs[vf21].vf.move(Mask::xyzw, c->vf_src(vf17).vf); +// c->vfs[vf22].vf.move(Mask::xyzw, c->vf_src(vf18).vf); +// c->vfs[vf23].vf.move(Mask::xyzw, c->vf_src(vf19).vf); +// c->vfs[vf24].vf.move(Mask::xyzw, c->vf_src(vf20).vf); +// for (int vec = 0; vec < 4; vec++) { +// for (int cmp = 0; cmp < 3; cmp++) { +//// c->vfs[vf17 + vec].f[cmp] = vec * 16 + cmp * 4; +// u32 val = 128 + 127 * c->vfs[vf1 + vec].f[cmp]; +// fmt::print("{} ", val); +// memcpy(&c->vfs[vf17 + vec].f[cmp], &val, 4); +// } +// } +// fmt::print("\n"); +// return; + + // move.xyzw vf21, vf17 | mulax.xyzw ACC, vf10, vf01 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf10).vf, c->vf_src(vf01).vf.x()); c->vfs[vf21].vf.move(Mask::xyzw, c->vf_src(vf17).vf); + // move.xyzw vf22, vf18 | madday.xyzw ACC, vf11, vf01 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf11].vf, c->vfs[vf01].vf.y()); c->vfs[vf22].vf.move(Mask::xyzw, c->vf_src(vf18).vf); + // move.xyzw vf23, vf19 | maddz.xyzw vf01, vf12, vf01 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf01].vf, c->vf_src(vf12).vf, c->vf_src(vf01).vf.z()); c->vfs[vf23].vf.move(Mask::xyzw, c->vf_src(vf19).vf); + // move.xyzw vf24, vf20 | mulax.xyzw ACC, vf10, vf02 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf10).vf, c->vf_src(vf02).vf.x()); c->vfs[vf24].vf.move(Mask::xyzw, c->vf_src(vf20).vf); + // nop | itof0.xyzw vf17, vf05 + c->vfs[vf17].vf.itof0(Mask::xyzw, c->vf_src(vf05).vf); + // nop | itof0.xyzw vf18, vf06 + c->vfs[vf18].vf.itof0(Mask::xyzw, c->vf_src(vf06).vf); + // nop | itof0.xyzw vf19, vf07 + c->vfs[vf19].vf.itof0(Mask::xyzw, c->vf_src(vf07).vf); + // nop | itof0.xyzw vf20, vf08 + c->vfs[vf20].vf.itof0(Mask::xyzw, c->vf_src(vf08).vf); + + //fmt::print("light in:\n {}\n {}\n {}\n {}\n\n", c->vf_src(vf17).vf.print(), c->vf_src(vf18).vf.print(), c->vf_src(vf19).vf.print(), c->vf_src(vf20).vf.print()); + + // nop | madday.xyzw ACC, vf11, vf02 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf11].vf, c->vfs[vf02].vf.y()); + // nop | maddz.xyzw vf02, vf12, vf02 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf02].vf, c->vf_src(vf12).vf, c->vf_src(vf02).vf.z()); + // nop | mulax.xyzw ACC, vf10, vf03 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf10).vf, c->vf_src(vf03).vf.x()); + // nop | madday.xyzw ACC, vf11, vf03 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf11].vf, c->vfs[vf03].vf.y()); + // nop | maddz.xyzw vf03, vf12, vf03 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf03].vf, c->vf_src(vf12).vf, c->vf_src(vf03).vf.z()); + // nop | mulax.xyzw ACC, vf10, vf04 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf10).vf, c->vf_src(vf04).vf.x()); + // nop | madday.xyzw ACC, vf11, vf04 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf11].vf, c->vfs[vf04].vf.y()); + // nop | maddz.xyzw vf04, vf12, vf04 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf04].vf, c->vf_src(vf12).vf, c->vf_src(vf04).vf.z()); + // nop | maxx.xyzw vf01, vf01, vf00 + c->vfs[vf01].vf.max(Mask::xyzw, c->vf_src(vf01).vf, c->vf_src(vf00).vf.x()); + // nop | maxx.xyzw vf02, vf02, vf00 + c->vfs[vf02].vf.max(Mask::xyzw, c->vf_src(vf02).vf, c->vf_src(vf00).vf.x()); + // nop | maxx.xyzw vf03, vf03, vf00 + c->vfs[vf03].vf.max(Mask::xyzw, c->vf_src(vf03).vf, c->vf_src(vf00).vf.x()); + // nop | maxx.xyzw vf04, vf04, vf00 + c->vfs[vf04].vf.max(Mask::xyzw, c->vf_src(vf04).vf, c->vf_src(vf00).vf.x()); + // nop | mulaw.xyzw ACC, vf13, vf00 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf13).vf, c->vf_src(vf00).vf.w()); + // nop | maddax.xyzw ACC, vf14, vf01 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf14].vf, c->vfs[vf01].vf.x()); + // nop | madday.xyzw ACC, vf15, vf01 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf15].vf, c->vfs[vf01].vf.y()); + // nop | maddz.xyzw vf01, vf16, vf01 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf01].vf, c->vf_src(vf16).vf, c->vf_src(vf01).vf.z()); + // nop | mulaw.xyzw ACC, vf13, vf00 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf13).vf, c->vf_src(vf00).vf.w()); + // nop | maddax.xyzw ACC, vf14, vf02 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf14].vf, c->vfs[vf02].vf.x()); + // nop | madday.xyzw ACC, vf15, vf02 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf15].vf, c->vfs[vf02].vf.y()); + // nop | maddz.xyzw vf02, vf16, vf02 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf02].vf, c->vf_src(vf16).vf, c->vf_src(vf02).vf.z()); + // nop | mulaw.xyzw ACC, vf13, vf00 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf13).vf, c->vf_src(vf00).vf.w()); + // nop | maddax.xyzw ACC, vf14, vf03 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf14].vf, c->vfs[vf03].vf.x()); + // nop | madday.xyzw ACC, vf15, vf03 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf15].vf, c->vfs[vf03].vf.y()); + // nop | maddz.xyzw vf03, vf16, vf03 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf03].vf, c->vf_src(vf16).vf, c->vf_src(vf03).vf.z()); + // nop | mulaw.xyzw ACC, vf13, vf00 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf13).vf, c->vf_src(vf00).vf.w()); + // nop | maddax.xyzw ACC, vf14, vf04 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf14].vf, c->vfs[vf04].vf.x()); + // nop | madday.xyzw ACC, vf15, vf04 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf15].vf, c->vfs[vf04].vf.y()); + // nop | maddz.xyzw vf04, vf16, vf04 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf04].vf, c->vf_src(vf16).vf, c->vf_src(vf04).vf.z()); + // nop | mul.xyzw vf17, vf17, vf01 + c->vfs[vf17].vf.mul(Mask::xyzw, c->vf_src(vf17).vf, c->vf_src(vf01).vf); + // nop | mul.xyzw vf18, vf18, vf02 + c->vfs[vf18].vf.mul(Mask::xyzw, c->vf_src(vf18).vf, c->vf_src(vf02).vf); + // nop | mul.xyzw vf19, vf19, vf03 + c->vfs[vf19].vf.mul(Mask::xyzw, c->vf_src(vf19).vf, c->vf_src(vf03).vf); + // nop | mul.xyzw vf20, vf20, vf04 + c->vfs[vf20].vf.mul(Mask::xyzw, c->vf_src(vf20).vf, c->vf_src(vf04).vf); + // nop | minix.xyzw vf17, vf17, vf09 + c->vfs[vf17].vf.mini(Mask::xyzw, c->vf_src(vf17).vf, c->vf_src(vf09).vf.x()); + // nop | minix.xyzw vf18, vf18, vf09 + c->vfs[vf18].vf.mini(Mask::xyzw, c->vf_src(vf18).vf, c->vf_src(vf09).vf.x()); + // nop | minix.xyzw vf19, vf19, vf09 + c->vfs[vf19].vf.mini(Mask::xyzw, c->vf_src(vf19).vf, c->vf_src(vf09).vf.x()); + // nop | minix.xyzw vf20, vf20, vf09 + c->vfs[vf20].vf.mini(Mask::xyzw, c->vf_src(vf20).vf, c->vf_src(vf09).vf.x()); + //fmt::print("light:\n {}\n {}\n {}\n {}\n\n", c->vf_src(vf17).vf.print(), c->vf_src(vf18).vf.print(), c->vf_src(vf19).vf.print(), c->vf_src(vf20).vf.print()); + + + + // nop | ftoi0.xyzw vf17, vf17 + c->vfs[vf17].vf.ftoi0(Mask::xyzw, c->vf_src(vf17).vf); + // nop | ftoi0.xyzw vf18, vf18 + c->vfs[vf18].vf.ftoi0(Mask::xyzw, c->vf_src(vf18).vf); + // nop | ftoi0.xyzw vf19, vf19 :e + c->vfs[vf19].vf.ftoi0(Mask::xyzw, c->vf_src(vf19).vf); + // nop | ftoi0.xyzw vf20, vf20 + c->vfs[vf20].vf.ftoi0(Mask::xyzw, c->vf_src(vf20).vf); +} + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + c->daddiu(sp, sp, -96); // daddiu sp, sp, -96 + c->sd(ra, 12432, at); // sd ra, 12432(at) + c->sq(s2, 12448, at); // sq s2, 12448(at) + c->sq(s3, 12464, at); // sq s3, 12464(at) + c->sq(s4, 12480, at); // sq s4, 12480(at) + c->sq(s5, 12496, at); // sq s5, 12496(at) + c->sq(gp, 12512, at); // sq gp, 12512(at) + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->lw(v1, 60, at); // lw v1, 60(at) + // nop // sll r0, r0, 0 + c->lw(a1, 52, at); // lw a1, 52(at) + // nop // sll r0, r0, 0 + c->lw(a0, 4, v1); // lw a0, 4(v1) + // nop // sll r0, r0, 0 + c->lw(t0, 0, v1); // lw t0, 0(v1) + // nop // sll r0, r0, 0 + c->lw(t3, 20, at); // lw t3, 20(at) + // nop // sll r0, r0, 0 + c->lw(v1, 24, at); // lw v1, 24(at) + c->addiu(a3, r0, 255); // addiu a3, r0, 255 + c->lw(t2, 28, at); // lw t2, 28(at) + c->addiu(a2, r0, 256); // addiu a2, r0, 256 + c->lui(t1, -2); // lui t1, -2 + c->mov64(t4, a1); // or t4, a1, r0 + c->lqc2(vf10, 12688, at); // lqc2 vf10, 12688(at) + c->ori(a1, t1, 65534); // ori a1, t1, 65534 + c->lqc2(vf11, 12704, at); // lqc2 vf11, 12704(at) + c->pextlw(a1, a1, a1); // pextlw a1, a1, a1 + c->lqc2(vf12, 12720, at); // lqc2 vf12, 12720(at) + c->pextlw(t1, a0, a0); // pextlw t1, a0, a0 + c->lqc2(vf15, 12752, at); // lqc2 vf15, 12752(at) + c->pextlw(a0, a1, a1); // pextlw a0, a1, a1 + c->lqc2(vf14, 12736, at); // lqc2 vf14, 12736(at) + c->pextlw(a1, t1, t1); // pextlw a1, t1, t1 + c->lqc2(vf16, 12768, at); // lqc2 vf16, 12768(at) + c->pcpyh(a3, a3); // pcpyh a3, a3 + c->lqc2(vf13, 12784, at); // lqc2 vf13, 12784(at) + c->pcpyh(t1, a2); // pcpyh t1, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyld(a2, a3, a3); // pcpyld a2, a3, a3 + c->lqc2(vf9, 12144, at); // lqc2 vf9, 12144(at) + c->pcpyld(a3, t1, t1); // pcpyld a3, t1, t1 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->ldr(t1, 0, t0); // ldr t1, 0(t0) + // nop // sll r0, r0, 0 + c->ldl(t1, 7, t0); // ldl t1, 7(t0) + // nop // sll r0, r0, 0 + c->daddiu(t0, t0, 8); // daddiu t0, t0, 8 + c->pextlh(t1, r0, t1); // pextlh t1, r0, t1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t5, t1, a2); // pand t5, t1, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->psllw(t5, t5, 5); // psllw t5, t5, 5 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->paddw(s5, t5, a1); // paddw s5, t5, a1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->dsrl32(t9, s5, 0); // dsrl32 t9, s5, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyud(s4, s5, r0); // pcpyud s4, s5, r0 + c->lq(t6, 0, s5); // lq t6, 0(s5) + c->dsrl32(ra, s4, 0); // dsrl32 ra, s4, 0 + c->lq(t7, 0, t9); // lq t7, 0(t9) + c->pand(t8, t1, a3); // pand t8, t1, a3 + c->lq(t5, 0, s4); // lq t5, 0(s4) + c->psraw(gp, t8, 8); // psraw gp, t8, 8 + c->lq(t8, 0, ra); // lq t8, 0(ra) + c->pextuw(s3, t7, t6); // pextuw s3, t7, t6 + c->lq(s5, 16, s5); // lq s5, 16(s5) + c->pextuw(s2, t8, t5); // pextuw s2, t8, t5 + c->lq(t9, 16, t9); // lq t9, 16(t9) + c->pcpyud(s3, s3, s2); // pcpyud s3, s3, s2 + c->lq(s4, 16, s4); // lq s4, 16(s4) + c->pand(s3, s3, a0); // pand s3, s3, a0 + c->lq(ra, 16, ra); // lq ra, 16(ra) + c->por(s3, s3, gp); // por s3, s3, gp + c->mov128_vf_gpr(vf1, s5); // qmtc2.ni vf1, s5 + c->pextub(gp, r0, s5); // pextub gp, r0, s5 + c->sq(s3, 0, t2); // sq s3, 0(t2) + c->pextub(s5, r0, t9); // pextub s5, r0, t9 + c->mov128_vf_gpr(vf2, t9); // qmtc2.ni vf2, t9 + c->pextub(t9, r0, s4); // pextub t9, r0, s4 + c->mov128_vf_gpr(vf3, s4); // qmtc2.ni vf3, s4 + c->pextub(s4, r0, ra); // pextub s4, r0, ra + c->mov128_vf_gpr(vf4, ra); // qmtc2.ni vf4, ra + c->pextuh(ra, r0, gp); // pextuh ra, r0, gp + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextuh(gp, r0, s5); // pextuh gp, r0, s5 + c->mov128_vf_gpr(vf5, ra); // qmtc2.ni vf5, ra + c->pextuh(t9, r0, t9); // pextuh t9, r0, t9 + c->mov128_vf_gpr(vf6, gp); // qmtc2.ni vf6, gp + c->pextuh(ra, r0, s4); // pextuh ra, r0, s4 + c->mov128_vf_gpr(vf7, t9); // qmtc2.ni vf7, t9 + c->prot3w(t8, t8); // prot3w t8, t8 + c->mov128_vf_gpr(vf8, ra); // qmtc2.ni vf8, ra + c->prot3w(t7, t7); // prot3w t7, t7 + // Unknown instr: vcallms 0 + vcallms0(c); + c->pextuw(t9, t7, t6); // pextuw t9, t7, t6 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyld(t7, t5, t7); // pcpyld t7, t5, t7 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyld(t6, t9, t6); // pcpyld t6, t9, t6 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->daddiu(t2, t2, 16); // daddiu t2, t2, 16 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextuw(t5, t8, t5); // pextuw t5, t8, t5 + c->sq(t7, 16, t3); // sq t7, 16(t3) + c->pcpyld(t5, t8, t5); // pcpyld t5, t8, t5 + c->sq(t6, 0, t3); // sq t6, 0(t3) + // nop // sll r0, r0, 0 + c->sq(t5, 32, t3); // sq t5, 32(t3) + c->daddiu(t3, t3, 48); // daddiu t3, t3, 48 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->daddiu(t4, t4, -4); // daddiu t4, t4, -4 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + bc = ((s64)c->sgpr64(t4)) <= 0; // blez t4, L74 + c->mfc1(r0, f31); // mfc1 r0, f31 + if (bc) {goto block_2;} // branch non-likely + + + block_1: + // nop // sll r0, r0, 0 + c->ldr(t1, 0, t0); // ldr t1, 0(t0) + // nop // sll r0, r0, 0 + c->ldl(t1, 7, t0); // ldl t1, 7(t0) + // nop // sll r0, r0, 0 + c->daddiu(t0, t0, 8); // daddiu t0, t0, 8 + c->pextlh(t1, r0, t1); // pextlh t1, r0, t1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t5, t1, a2); // pand t5, t1, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->psllw(t5, t5, 5); // psllw t5, t5, 5 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->paddw(s5, t5, a1); // paddw s5, t5, a1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->dsrl32(t9, s5, 0); // dsrl32 t9, s5, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyud(s4, s5, r0); // pcpyud s4, s5, r0 + c->lq(t6, 0, s5); // lq t6, 0(s5) + c->dsrl32(ra, s4, 0); // dsrl32 ra, s4, 0 + c->lq(t7, 0, t9); // lq t7, 0(t9) + c->pand(t8, t1, a3); // pand t8, t1, a3 + c->lq(t5, 0, s4); // lq t5, 0(s4) + c->psraw(gp, t8, 8); // psraw gp, t8, 8 + c->lq(t8, 0, ra); // lq t8, 0(ra) + c->pextuw(s3, t7, t6); // pextuw s3, t7, t6 + c->lq(s5, 16, s5); // lq s5, 16(s5) + c->pextuw(s2, t8, t5); // pextuw s2, t8, t5 + c->lq(t9, 16, t9); // lq t9, 16(t9) + c->pcpyud(s3, s3, s2); // pcpyud s3, s3, s2 + c->lq(s4, 16, s4); // lq s4, 16(s4) + c->pand(s3, s3, a0); // pand s3, s3, a0 + c->lq(ra, 16, ra); // lq ra, 16(ra) + c->por(s3, s3, gp); // por s3, s3, gp + c->mov128_vf_gpr(vf1, s5); // qmtc2.ni vf1, s5 + c->pextub(gp, r0, s5); // pextub gp, r0, s5 + c->sq(s3, 0, t2); // sq s3, 0(t2) + c->pextub(s5, r0, t9); // pextub s5, r0, t9 + c->mov128_vf_gpr(vf2, t9); // qmtc2.ni vf2, t9 + c->pextub(t9, r0, s4); // pextub t9, r0, s4 + c->mov128_vf_gpr(vf3, s4); // qmtc2.ni vf3, s4 + c->pextub(s4, r0, ra); // pextub s4, r0, ra + c->mov128_vf_gpr(vf4, ra); // qmtc2.ni vf4, ra + c->pextuh(ra, r0, gp); // pextuh ra, r0, gp + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextuh(gp, r0, s5); // pextuh gp, r0, s5 + c->mov128_vf_gpr(vf5, ra); // qmtc2.ni vf5, ra + c->pextuh(t9, r0, t9); // pextuh t9, r0, t9 + c->mov128_vf_gpr(vf6, gp); // qmtc2.ni vf6, gp + c->pextuh(ra, r0, s4); // pextuh ra, r0, s4 + c->mov128_vf_gpr(vf7, t9); // qmtc2.ni vf7, t9 + c->prot3w(t8, t8); // prot3w t8, t8 + c->mov128_vf_gpr(vf8, ra); // qmtc2.ni vf8, ra + c->prot3w(t7, t7); // prot3w t7, t7 + // Unknown instr: vcallms 0 + vcallms0(c); + c->pextuw(t9, t7, t6); // pextuw t9, t7, t6 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyld(t7, t5, t7); // pcpyld t7, t5, t7 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyld(t6, t9, t6); // pcpyld t6, t9, t6 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextuw(t5, t8, t5); // pextuw t5, t8, t5 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyld(t5, t8, t5); // pcpyld t5, t8, t5 + c->sq(t6, 0, t3); // sq t6, 0(t3) + // nop // sll r0, r0, 0 + c->sq(t7, 16, t3); // sq t7, 16(t3) + // nop // sll r0, r0, 0 + c->sq(t5, 32, t3); // sq t5, 32(t3) + c->daddiu(t2, t2, 16); // daddiu t2, t2, 16 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->daddiu(t3, t3, 48); // daddiu t3, t3, 48 + c->mov128_gpr_vf(t7, vf21); // qmfc2.ni t7, vf21 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t8, vf22); // qmfc2.ni t8, vf22 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t5, vf23); // qmfc2.ni t5, vf23 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t6, vf24); // qmfc2.ni t6, vf24 + c->ppach(t7, t8, t7); // ppach t7, t8, t7 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->ppach(t5, t6, t5); // ppach t5, t6, t5 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->ppacb(t5, t5, t7); // ppacb t5, t5, t7 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->sq(t5, 0, v1); // sq t5, 0(v1) + c->daddiu(t4, t4, -4); // daddiu t4, t4, -4 + c->daddiu(v1, v1, 16); // daddiu v1, v1, 16 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + bc = ((s64)c->sgpr64(t4)) > 0; // bgtz t4, L73 + // nop // sll r0, r0, 0 + if (bc) {goto block_1;} // branch non-likely + + + block_2: + // nop // sll r0, r0, 0 + // nop // vnop + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(a2, vf17); // qmfc2.ni a2, vf17 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(a3, vf18); // qmfc2.ni a3, vf18 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(a0, vf19); // qmfc2.ni a0, vf19 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(a1, vf20); // qmfc2.ni a1, vf20 + c->ppach(a2, a3, a2); // ppach a2, a3, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->ppach(a0, a1, a0); // ppach a0, a1, a0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->ppacb(a0, a0, a2); // ppacb a0, a0, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->sq(a0, 0, v1); // sq a0, 0(v1) + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + c->ld(ra, 12432, at); // ld ra, 12432(at) + c->lq(gp, 12512, at); // lq gp, 12512(at) + c->lq(s5, 12496, at); // lq s5, 12496(at) + c->lq(s4, 12480, at); // lq s4, 12480(at) + c->lq(s3, 12464, at); // lq s3, 12464(at) + c->lq(s2, 12448, at); // lq s2, 12448(at) + //jr ra // jr ra + c->daddiu(sp, sp, 96); // daddiu sp, sp, 96 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + gLinkedFunctionTable.reg("generic-light-proc", execute, 128); +} + +} // namespace generic_light_proc +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace generic_envmap_proc { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* +} cache; + +void vcallms48(ExecutionContext* c) { + // nop | mulx.xyzw vf13, vf09, vf31 + c->vfs[vf13].vf.mul(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf31).vf.x()); + // nop | subw.z vf21, vf21, vf00 + c->vfs[vf21].vf.sub(Mask::z, c->vf_src(vf21).vf, c->vf_src(vf00).vf.w()); + // nop | addy.x vf29, vf29, vf29 + c->vfs[vf29].vf.add(Mask::x, c->vf_src(vf29).vf, c->vf_src(vf29).vf.y()); + // nop | mulx.xyz vf08, vf08, vf30 + c->vfs[vf08].vf.mul(Mask::xyz, c->vf_src(vf08).vf, c->vf_src(vf30).vf.x()); + // nop | addw.xy vf05, vf05, vf31 + c->vfs[vf05].vf.add(Mask::xy, c->vf_src(vf05).vf, c->vf_src(vf31).vf.w()); + // nop | mul.xyz vf30, vf21, vf13 + c->vfs[vf30].vf.mul(Mask::xyz, c->vf_src(vf21).vf, c->vf_src(vf13).vf); + // nop | addz.x vf29, vf29, vf29 + c->vfs[vf29].vf.add(Mask::x, c->vf_src(vf29).vf, c->vf_src(vf29).vf.z()); + // nop | add.xyz vf08, vf08, vf16 + c->vfs[vf08].vf.add(Mask::xyz, c->vf_src(vf08).vf, c->vf_src(vf16).vf); + // move.xyzw vf28, vf27 | ftoi12.xy vf17, vf05 + c->vfs[vf17].vf.ftoi12(Mask::xy, c->vf_src(vf05).vf); c->vfs[vf28].vf.move(Mask::xyzw, c->vf_src(vf27).vf); + // move.xyzw vf02, vf22 | addy.x vf30, vf30, vf30 + c->vfs[vf30].vf.add(Mask::x, c->vf_src(vf30).vf, c->vf_src(vf30).vf.y()); c->vfs[vf02].vf.move(Mask::xyzw, c->vf_src(vf22).vf); + // rsqrt Q, vf31.z, vf29.x | mul.xyz vf06, vf06, Q + c->vfs[vf06].vf.mul(Mask::xyz, c->vf_src(vf06).vf, c->Q); c->Q = c->vf_src(vf31).vf.z() / std::sqrt(c->vf_src(vf29).vf.x()); + // nop | mul.xyz vf29, vf08, vf08 + c->vfs[vf29].vf.mul(Mask::xyz, c->vf_src(vf08).vf, c->vf_src(vf08).vf); + // nop | mulx.xyz vf01, vf21, vf28 + c->vfs[vf01].vf.mul(Mask::xyz, c->vf_src(vf21).vf, c->vf_src(vf28).vf.x()); + // nop | addz.x vf30, vf30, vf30 + c->vfs[vf30].vf.add(Mask::x, c->vf_src(vf30).vf, c->vf_src(vf30).vf.z()); + // nop | mulx.xyzw vf14, vf10, vf31 + c->vfs[vf14].vf.mul(Mask::xyzw, c->vf_src(vf10).vf, c->vf_src(vf31).vf.x()); + // nop | subw.z vf02, vf02, vf00 + c->vfs[vf02].vf.sub(Mask::z, c->vf_src(vf02).vf, c->vf_src(vf00).vf.w()); + // nop | addy.x vf29, vf29, vf29 + c->vfs[vf29].vf.add(Mask::x, c->vf_src(vf29).vf, c->vf_src(vf29).vf.y()); + // nop | mulx.xyz vf01, vf01, vf30 + c->vfs[vf01].vf.mul(Mask::xyz, c->vf_src(vf01).vf, c->vf_src(vf30).vf.x()); + // nop | addw.xy vf06, vf06, vf31 + c->vfs[vf06].vf.add(Mask::xy, c->vf_src(vf06).vf, c->vf_src(vf31).vf.w()); + // nop | mul.xyz vf30, vf02, vf14 + c->vfs[vf30].vf.mul(Mask::xyz, c->vf_src(vf02).vf, c->vf_src(vf14).vf); + // nop | addz.x vf29, vf29, vf29 + c->vfs[vf29].vf.add(Mask::x, c->vf_src(vf29).vf, c->vf_src(vf29).vf.z()); + // nop | add.xyz vf01, vf01, vf13 + c->vfs[vf01].vf.add(Mask::xyz, c->vf_src(vf01).vf, c->vf_src(vf13).vf); + // nop | ftoi12.xy vf18, vf06 + c->vfs[vf18].vf.ftoi12(Mask::xy, c->vf_src(vf06).vf); + // nop | addy.x vf30, vf30, vf30 + c->vfs[vf30].vf.add(Mask::x, c->vf_src(vf30).vf, c->vf_src(vf30).vf.y()); + // rsqrt Q, vf31.z, vf29.x | mul.xyz vf07, vf07, Q + c->vfs[vf07].vf.mul(Mask::xyz, c->vf_src(vf07).vf, c->Q); c->Q = c->vf_src(vf31).vf.z() / std::sqrt(c->vf_src(vf29).vf.x()); + // move.xyzw vf03, vf23 | mul.xyz vf29, vf01, vf01 + c->vfs[vf29].vf.mul(Mask::xyz, c->vf_src(vf01).vf, c->vf_src(vf01).vf); c->vfs[vf03].vf.move(Mask::xyzw, c->vf_src(vf23).vf); + // nop | muly.xyz vf02, vf02, vf28 + c->vfs[vf02].vf.mul(Mask::xyz, c->vf_src(vf02).vf, c->vf_src(vf28).vf.y()); + // nop | addz.x vf30, vf30, vf30 + c->vfs[vf30].vf.add(Mask::x, c->vf_src(vf30).vf, c->vf_src(vf30).vf.z()); + // nop | mulx.xyzw vf15, vf11, vf31 + c->vfs[vf15].vf.mul(Mask::xyzw, c->vf_src(vf11).vf, c->vf_src(vf31).vf.x()); + // nop | subw.z vf03, vf03, vf00 + c->vfs[vf03].vf.sub(Mask::z, c->vf_src(vf03).vf, c->vf_src(vf00).vf.w()); + // nop | addy.x vf29, vf29, vf29 + c->vfs[vf29].vf.add(Mask::x, c->vf_src(vf29).vf, c->vf_src(vf29).vf.y()); + // nop | mulx.xyz vf02, vf02, vf30 + c->vfs[vf02].vf.mul(Mask::xyz, c->vf_src(vf02).vf, c->vf_src(vf30).vf.x()); + // nop | addw.xy vf07, vf07, vf31 + c->vfs[vf07].vf.add(Mask::xy, c->vf_src(vf07).vf, c->vf_src(vf31).vf.w()); + // nop | mul.xyz vf30, vf03, vf15 + c->vfs[vf30].vf.mul(Mask::xyz, c->vf_src(vf03).vf, c->vf_src(vf15).vf); + // nop | addz.x vf29, vf29, vf29 + c->vfs[vf29].vf.add(Mask::x, c->vf_src(vf29).vf, c->vf_src(vf29).vf.z()); + // nop | add.xyz vf02, vf02, vf14 + c->vfs[vf02].vf.add(Mask::xyz, c->vf_src(vf02).vf, c->vf_src(vf14).vf); + // nop | ftoi12.xy vf19, vf07 + c->vfs[vf19].vf.ftoi12(Mask::xy, c->vf_src(vf07).vf); + // nop | addy.x vf30, vf30, vf30 + c->vfs[vf30].vf.add(Mask::x, c->vf_src(vf30).vf, c->vf_src(vf30).vf.y()); + // rsqrt Q, vf31.z, vf29.x | mul.xyz vf08, vf08, Q + c->vfs[vf08].vf.mul(Mask::xyz, c->vf_src(vf08).vf, c->Q); c->Q = c->vf_src(vf31).vf.z() / std::sqrt(c->vf_src(vf29).vf.x()); + // move.xyzw vf04, vf24 | mul.xyz vf29, vf02, vf02 + c->vfs[vf29].vf.mul(Mask::xyz, c->vf_src(vf02).vf, c->vf_src(vf02).vf); c->vfs[vf04].vf.move(Mask::xyzw, c->vf_src(vf24).vf); + // nop | mulz.xyz vf03, vf03, vf28 + c->vfs[vf03].vf.mul(Mask::xyz, c->vf_src(vf03).vf, c->vf_src(vf28).vf.z()); + // nop | addz.x vf30, vf30, vf30 + c->vfs[vf30].vf.add(Mask::x, c->vf_src(vf30).vf, c->vf_src(vf30).vf.z()); + // nop | mulx.xyzw vf16, vf12, vf31 + c->vfs[vf16].vf.mul(Mask::xyzw, c->vf_src(vf12).vf, c->vf_src(vf31).vf.x()); + // nop | subw.z vf04, vf04, vf00 + c->vfs[vf04].vf.sub(Mask::z, c->vf_src(vf04).vf, c->vf_src(vf00).vf.w()); + // nop | addy.x vf29, vf29, vf29 + c->vfs[vf29].vf.add(Mask::x, c->vf_src(vf29).vf, c->vf_src(vf29).vf.y()); + // nop | mulx.xyz vf03, vf03, vf30 + c->vfs[vf03].vf.mul(Mask::xyz, c->vf_src(vf03).vf, c->vf_src(vf30).vf.x()); + // nop | addw.xy vf08, vf08, vf31 + c->vfs[vf08].vf.add(Mask::xy, c->vf_src(vf08).vf, c->vf_src(vf31).vf.w()); + // nop | mul.xyz vf30, vf04, vf16 + c->vfs[vf30].vf.mul(Mask::xyz, c->vf_src(vf04).vf, c->vf_src(vf16).vf); + // nop | addz.x vf29, vf29, vf29 + c->vfs[vf29].vf.add(Mask::x, c->vf_src(vf29).vf, c->vf_src(vf29).vf.z()); + // nop | add.xyz vf03, vf03, vf15 + c->vfs[vf03].vf.add(Mask::xyz, c->vf_src(vf03).vf, c->vf_src(vf15).vf); + // nop | ftoi12.xy vf20, vf08 + c->vfs[vf20].vf.ftoi12(Mask::xy, c->vf_src(vf08).vf); + // nop | addy.x vf30, vf30, vf30 + c->vfs[vf30].vf.add(Mask::x, c->vf_src(vf30).vf, c->vf_src(vf30).vf.y()); + // rsqrt Q, vf31.z, vf29.x | mul.xyz vf05, vf01, Q + c->vfs[vf05].vf.mul(Mask::xyz, c->vf_src(vf01).vf, c->Q); c->Q = c->vf_src(vf31).vf.z() / std::sqrt(c->vf_src(vf29).vf.x()); + // move.xyzw vf06, vf02 | mul.xyz vf29, vf03, vf03 + c->vfs[vf29].vf.mul(Mask::xyz, c->vf_src(vf03).vf, c->vf_src(vf03).vf); c->vfs[vf06].vf.move(Mask::xyzw, c->vf_src(vf02).vf); + // move.xyzw vf07, vf03 | mulw.xyz vf08, vf04, vf28 :e + c->vfs[vf08].vf.mul(Mask::xyz, c->vf_src(vf04).vf, c->vf_src(vf28).vf.w()); c->vfs[vf07].vf.move(Mask::xyzw, c->vf_src(vf03).vf); + // nop | addz.x vf30, vf30, vf30 + c->vfs[vf30].vf.add(Mask::x, c->vf_src(vf30).vf, c->vf_src(vf30).vf.z()); + +} + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + c->daddiu(sp, sp, -128); // daddiu sp, sp, -128 + c->sd(ra, 12432, at); // sd ra, 12432(at) + c->sq(s0, 12448, at); // sq s0, 12448(at) + c->sq(s1, 12464, at); // sq s1, 12464(at) + c->sq(s2, 12480, at); // sq s2, 12480(at) + c->sq(s3, 12496, at); // sq s3, 12496(at) + c->sq(s4, 12512, at); // sq s4, 12512(at) + c->sq(s5, 12528, at); // sq s5, 12528(at) + c->sq(gp, 12544, at); // sq gp, 12544(at) + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + // nop // sll r0, r0, 0 + c->lw(v1, 60, at); // lw v1, 60(at) + // nop // sll r0, r0, 0 + c->lw(a0, 52, at); // lw a0, 52(at) + // nop // sll r0, r0, 0 + c->lw(t0, 0, v1); // lw t0, 0(v1) + // nop // sll r0, r0, 0 + c->lw(a2, 4, v1); // lw a2, 4(v1) + // nop // sll r0, r0, 0 + c->lw(t3, 32, at); // lw t3, 32(at) + // nop // sll r0, r0, 0 + c->lw(v1, 36, at); // lw v1, 36(at) + // nop // sll r0, r0, 0 + c->addiu(t1, r0, 255); // addiu t1, r0, 255 + c->addiu(a3, r0, 256); // addiu a3, r0, 256 + c->lui(a1, -2); // lui a1, -2 + c->lui(t2, 16256); // lui t2, 16256 + c->ori(a1, a1, 65534); // ori a1, a1, 65534 + c->mtc1(f0, t2); // mtc1 f0, t2 + c->daddiu(t2, a0, 3); // daddiu t2, a0, 3 + c->sra(t5, t2, 2); // sra t5, t2, 2 + c->lq(t2, 12048, at); // lq t2, 12048(at) + c->sra(t4, t5, 2); // sra t4, t5, 2 + c->andi(t5, t5, 3); // andi t5, t5, 3 + bc = c->sgpr64(t4) == 0; // beq t4, r0, L68 + // nop // sll r0, r0, 0 + if (bc) {goto block_2;} // branch non-likely + + + block_1: + c->daddiu(t3, t3, 64); // daddiu t3, t3, 64 + c->sq(t2, -64, t3); // sq t2, -64(t3) + // nop // sll r0, r0, 0 + c->sq(t2, -48, t3); // sq t2, -48(t3) + c->daddiu(t4, t4, -1); // daddiu t4, t4, -1 + c->sq(t2, -32, t3); // sq t2, -32(t3) + bc = ((s64)c->sgpr64(t4)) > 0; // bgtz t4, L67 + c->sq(t2, -16, t3); // sq t2, -16(t3) + if (bc) {goto block_1;} // branch non-likely + + + block_2: + bc = c->sgpr64(t5) == 0; // beq t5, r0, L69 + c->daddiu(t4, t5, -1); // daddiu t4, t5, -1 + if (bc) {goto block_6;} // branch non-likely + + bc = c->sgpr64(t4) == 0; // beq t4, r0, L69 + c->sq(t2, 0, t3); // sq t2, 0(t3) + if (bc) {goto block_6;} // branch non-likely + + c->daddiu(t3, t3, 16); // daddiu t3, t3, 16 + c->daddiu(t4, t4, -1); // daddiu t4, t4, -1 + bc = c->sgpr64(t4) == 0; // beq t4, r0, L69 + c->sq(t2, 0, t3); // sq t2, 0(t3) + if (bc) {goto block_6;} // branch non-likely + + c->daddiu(t3, t3, 16); // daddiu t3, t3, 16 + c->daddiu(t4, t4, -1); // daddiu t4, t4, -1 + // nop // sll r0, r0, 0 + c->sq(t2, 0, t3); // sq t2, 0(t3) + + block_6: + c->daddiu(a0, a0, -4); // daddiu a0, a0, -4 + c->lqc2(vf31, 12016, at); // lqc2 vf31, 12016(at) + c->pextlw(a1, a1, a1); // pextlw a1, a1, a1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlw(a1, a1, a1); // pextlw a1, a1, a1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlw(a2, a2, a2); // pextlw a2, a2, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlw(a2, a2, a2); // pextlw a2, a2, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyh(t2, t1); // pcpyh t2, t1 + c->ld(t1, 0, t0); // ld t1, 0(t0) + c->pcpyld(t2, t2, t2); // pcpyld t2, t2, t2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyh(a3, a3); // pcpyh a3, a3 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyld(a3, a3, a3); // pcpyld a3, a3, a3 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->daddiu(t0, t0, 8); // daddiu t0, t0, 8 + c->sq(t2, 112, at); // sq t2, 112(at) + c->pextlh(t1, r0, t1); // pextlh t1, r0, t1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t2, t1, t2); // pand t2, t1, t2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->psllw(t2, t2, 5); // psllw t2, t2, 5 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->paddw(t5, t2, a2); // paddw t5, t2, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->dsrl32(t6, t5, 0); // dsrl32 t6, t5, 0 + c->lwc1(f4, 24, t5); // lwc1 f4, 24(t5) + c->pcpyud(t7, t5, r0); // pcpyud t7, t5, r0 + c->lwc1(f3, 24, t6); // lwc1 f3, 24(t6) + c->dsrl32(t8, t7, 0); // dsrl32 t8, t7, 0 + c->lwc1(f2, 24, t7); // lwc1 f2, 24(t7) + c->pand(t1, t1, a3); // pand t1, t1, a3 + c->lwc1(f1, 24, t8); // lwc1 f1, 24(t8) + c->psraw(t2, t1, 8); // psraw t2, t1, 8 + c->lq(t1, 16, t5); // lq t1, 16(t5) + c->mov128_gpr_gpr(s0, t2); // por s0, t2, r0 + c->subs(f4, f4, f0); // sub.s f4, f4, f0 + c->divs(f4, f0, f4); // div.s f4, f0, f4 + c->lq(t2, 16, t6); // lq t2, 16(t6) + // nop // sll r0, r0, 0 + c->lq(t3, 16, t7); // lq t3, 16(t7) + // nop // sll r0, r0, 0 + c->lq(t4, 16, t8); // lq t4, 16(t8) + // nop // sll r0, r0, 0 + c->lq(t5, 0, t5); // lq t5, 0(t5) + // nop // sll r0, r0, 0 + c->lq(t6, 0, t6); // lq t6, 0(t6) + // nop // sll r0, r0, 0 + c->lq(t7, 0, t7); // lq t7, 0(t7) + // nop // sll r0, r0, 0 + c->lq(t8, 0, t8); // lq t8, 0(t8) + c->muls(f4, f4, f0); // mul.s f4, f4, f0 + // nop // sll r0, r0, 0 + c->subs(f3, f3, f0); // sub.s f3, f3, f0 + // nop // sll r0, r0, 0 + c->divs(f3, f0, f3); // div.s f3, f0, f3 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(t9, f4); // mfc1 t9, f4 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->muls(f3, f3, f0); // mul.s f3, f3, f0 + // nop // sll r0, r0, 0 + c->subs(f2, f2, f0); // sub.s f2, f2, f0 + // nop // sll r0, r0, 0 + c->divs(f2, f0, f2); // div.s f2, f0, f2 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(ra, f3); // mfc1 ra, f3 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->muls(f2, f2, f0); // mul.s f2, f2, f0 + // nop // sll r0, r0, 0 + c->subs(f1, f1, f0); // sub.s f1, f1, f0 + // nop // sll r0, r0, 0 + c->divs(f1, f0, f1); // div.s f1, f0, f1 + // nop // sll r0, r0, 0 + c->pextlw(t9, ra, t9); // pextlw t9, ra, t9 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(ra, f2); // mfc1 ra, f2 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(gp, f1); // mfc1 gp, f1 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->pextlw(ra, gp, ra); // pextlw ra, gp, ra + // nop // sll r0, r0, 0 + c->pcpyld(t9, ra, t9); // pcpyld t9, ra, t9 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf21, t1); // qmtc2.ni vf21, t1 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf22, t2); // qmtc2.ni vf22, t2 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf23, t3); // qmtc2.ni vf23, t3 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf24, t4); // qmtc2.ni vf24, t4 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf9, t5); // qmtc2.ni vf9, t5 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf10, t6); // qmtc2.ni vf10, t6 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf11, t7); // qmtc2.ni vf11, t7 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf12, t8); // qmtc2.ni vf12, t8 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf27, t9); // qmtc2.ni vf27, t9 + c->lq(t2, 112, at); // lq t2, 112(at) + // Unknown instr: vcallms 48 + vcallms48(c); + // nop // sll r0, r0, 0 + c->ld(t1, 0, t0); // ld t1, 0(t0) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->daddiu(t0, t0, 8); // daddiu t0, t0, 8 + c->pextlh(t1, r0, t1); // pextlh t1, r0, t1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t2, t1, t2); // pand t2, t1, t2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->psllw(t2, t2, 5); // psllw t2, t2, 5 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->paddw(t5, t2, a2); // paddw t5, t2, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->dsrl32(t6, t5, 0); // dsrl32 t6, t5, 0 + c->lwc1(f3, 24, t5); // lwc1 f3, 24(t5) + c->pcpyud(t7, t5, r0); // pcpyud t7, t5, r0 + c->lwc1(f2, 24, t6); // lwc1 f2, 24(t6) + c->dsrl32(t8, t7, 0); // dsrl32 t8, t7, 0 + c->lwc1(f1, 24, t7); // lwc1 f1, 24(t7) + c->pand(t1, t1, a3); // pand t1, t1, a3 + c->lwc1(f4, 24, t8); // lwc1 f4, 24(t8) + c->psraw(t2, t1, 8); // psraw t2, t1, 8 + c->lq(t1, 16, t5); // lq t1, 16(t5) + c->mov128_gpr_gpr(s1, t2); // por s1, t2, r0 + c->subs(f5, f3, f0); // sub.s f5, f3, f0 + c->subs(f3, f2, f0); // sub.s f3, f2, f0 + // nop // sll r0, r0, 0 + c->subs(f2, f1, f0); // sub.s f2, f1, f0 + // nop // sll r0, r0, 0 + c->subs(f1, f4, f0); // sub.s f1, f4, f0 + // nop // sll r0, r0, 0 + c->divs(f4, f0, f5); // div.s f4, f0, f5 + c->lq(t2, 16, t6); // lq t2, 16(t6) + // nop // sll r0, r0, 0 + c->lq(t3, 16, t7); // lq t3, 16(t7) + // nop // sll r0, r0, 0 + c->lq(t4, 16, t8); // lq t4, 16(t8) + // nop // sll r0, r0, 0 + c->lq(t5, 0, t5); // lq t5, 0(t5) + // nop // sll r0, r0, 0 + c->lq(t6, 0, t6); // lq t6, 0(t6) + // nop // sll r0, r0, 0 + c->lq(t7, 0, t7); // lq t7, 0(t7) + // nop // sll r0, r0, 0 + c->lq(t8, 0, t8); // lq t8, 0(t8) + c->muls(f4, f4, f0); // mul.s f4, f4, f0 + // nop // sll r0, r0, 0 + c->divs(f3, f0, f3); // div.s f3, f0, f3 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(t9, f4); // mfc1 t9, f4 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->muls(f3, f3, f0); // mul.s f3, f3, f0 + // nop // sll r0, r0, 0 + c->divs(f2, f0, f2); // div.s f2, f0, f2 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(ra, f3); // mfc1 ra, f3 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->muls(f2, f2, f0); // mul.s f2, f2, f0 + // nop // sll r0, r0, 0 + c->divs(f1, f0, f1); // div.s f1, f0, f1 + // nop // sll r0, r0, 0 + c->pextlw(t9, ra, t9); // pextlw t9, ra, t9 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(ra, f2); // mfc1 ra, f2 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(gp, f1); // mfc1 gp, f1 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf21, t1); // qmtc2.ni vf21, t1 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf9, t5); // qmtc2.ni vf9, t5 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf10, t6); // qmtc2.ni vf10, t6 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf11, t7); // qmtc2.ni vf11, t7 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf12, t8); // qmtc2.ni vf12, t8 + c->pextlw(t1, gp, ra); // pextlw t1, gp, ra + // nop // sll r0, r0, 0 + c->pcpyld(t1, t1, t9); // pcpyld t1, t1, t9 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf22, t2); // qmtc2.ni vf22, t2 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf23, t3); // qmtc2.ni vf23, t3 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf24, t4); // qmtc2.ni vf24, t4 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf27, t1); // qmtc2.ni vf27, t1 + c->lq(t2, 112, at); // lq t2, 112(at) + // Unknown instr: vcallms 48 + vcallms48(c); + // nop // sll r0, r0, 0 + c->ld(t1, 0, t0); // ld t1, 0(t0) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->daddiu(t0, t0, 8); // daddiu t0, t0, 8 + c->pextlh(t1, r0, t1); // pextlh t1, r0, t1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t2, t1, t2); // pand t2, t1, t2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->psllw(t2, t2, 5); // psllw t2, t2, 5 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->paddw(t2, t2, a2); // paddw t2, t2, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->dsrl32(t3, t2, 0); // dsrl32 t3, t2, 0 + c->lwc1(f3, 24, t2); // lwc1 f3, 24(t2) + c->pcpyud(t7, t2, r0); // pcpyud t7, t2, r0 + c->lwc1(f2, 24, t3); // lwc1 f2, 24(t3) + c->dsrl32(t8, t7, 0); // dsrl32 t8, t7, 0 + c->lwc1(f1, 24, t7); // lwc1 f1, 24(t7) + c->pand(t1, t1, a3); // pand t1, t1, a3 + c->lwc1(f4, 24, t8); // lwc1 f4, 24(t8) + c->psraw(t4, t1, 8); // psraw t4, t1, 8 + c->lq(t1, 16, t2); // lq t1, 16(t2) + c->mov128_gpr_gpr(s2, t4); // por s2, t4, r0 + c->subs(f5, f3, f0); // sub.s f5, f3, f0 + c->subs(f3, f2, f0); // sub.s f3, f2, f0 + // nop // sll r0, r0, 0 + c->subs(f2, f1, f0); // sub.s f2, f1, f0 + // nop // sll r0, r0, 0 + c->subs(f1, f4, f0); // sub.s f1, f4, f0 + // nop // sll r0, r0, 0 + c->divs(f4, f0, f5); // div.s f4, f0, f5 + c->lq(t4, 16, t3); // lq t4, 16(t3) + // nop // sll r0, r0, 0 + c->lq(t5, 16, t7); // lq t5, 16(t7) + // nop // sll r0, r0, 0 + c->lq(t6, 16, t8); // lq t6, 16(t8) + // nop // sll r0, r0, 0 + c->lq(t2, 0, t2); // lq t2, 0(t2) + // nop // sll r0, r0, 0 + c->lq(t3, 0, t3); // lq t3, 0(t3) + // nop // sll r0, r0, 0 + c->lq(t7, 0, t7); // lq t7, 0(t7) + // nop // sll r0, r0, 0 + c->lq(t8, 0, t8); // lq t8, 0(t8) + c->muls(f4, f4, f0); // mul.s f4, f4, f0 + // nop // sll r0, r0, 0 + c->divs(f3, f0, f3); // div.s f3, f0, f3 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(t9, f4); // mfc1 t9, f4 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->muls(f3, f3, f0); // mul.s f3, f3, f0 + // nop // sll r0, r0, 0 + c->divs(f2, f0, f2); // div.s f2, f0, f2 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(ra, f3); // mfc1 ra, f3 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->muls(f2, f2, f0); // mul.s f2, f2, f0 + // nop // sll r0, r0, 0 + c->divs(f1, f0, f1); // div.s f1, f0, f1 + // nop // sll r0, r0, 0 + c->pextlw(t9, ra, t9); // pextlw t9, ra, t9 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->mfc1(ra, f2); // mfc1 ra, f2 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf21, t1); // qmtc2.ni vf21, t1 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf22, t4); // qmtc2.ni vf22, t4 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf23, t5); // qmtc2.ni vf23, t5 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf24, t6); // qmtc2.ni vf24, t6 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(t1, f1); // mfc1 t1, f1 + c->pextlw(t1, t1, ra); // pextlw t1, t1, ra + // nop // sll r0, r0, 0 + c->pcpyld(t1, t1, t9); // pcpyld t1, t1, t9 + c->mov128_vf_gpr(vf9, t2); // qmtc2.ni vf9, t2 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf10, t3); // qmtc2.ni vf10, t3 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf11, t7); // qmtc2.ni vf11, t7 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf12, t8); // qmtc2.ni vf12, t8 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf27, t1); // qmtc2.ni vf27, t1 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t4, vf17); // qmfc2.ni t4, vf17 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t5, vf18); // qmfc2.ni t5, vf18 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t6, vf19); // qmfc2.ni t6, vf19 + bc = ((s64)c->sgpr64(a0)) <= 0; // blez a0, L71 + c->mov128_gpr_vf(t7, vf20); // qmfc2.ni t7, vf20 + if (bc) {goto block_8;} // branch non-likely + + + block_7: + c->lq(t2, 112, at); // lq t2, 112(at) + // Unknown instr: vcallms 48 + vcallms48(c); + c->daddiu(a0, a0, -4); // daddiu a0, a0, -4 + c->ld(t1, 0, t0); // ld t1, 0(t0) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->daddiu(v1, v1, 16); // daddiu v1, v1, 16 + c->daddiu(t0, t0, 8); // daddiu t0, t0, 8 + c->pextlh(t1, r0, t1); // pextlh t1, r0, t1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t2, t1, t2); // pand t2, t1, t2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->psllw(t2, t2, 5); // psllw t2, t2, 5 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->paddw(t9, t2, a2); // paddw t9, t2, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->dsrl32(ra, t9, 0); // dsrl32 ra, t9, 0 + c->lwc1(f1, 24, t9); // lwc1 f1, 24(t9) + c->pcpyud(s4, t9, r0); // pcpyud s4, t9, r0 + c->lwc1(f4, 24, ra); // lwc1 f4, 24(ra) + c->subs(f3, f1, f0); // sub.s f3, f1, f0 + // nop // sll r0, r0, 0 + c->dsrl32(s3, s4, 0); // dsrl32 s3, s4, 0 + c->lwc1(f1, 24, s4); // lwc1 f1, 24(s4) + c->pand(t1, t1, a3); // pand t1, t1, a3 + c->lwc1(f2, 24, s3); // lwc1 f2, 24(s3) + c->psraw(s5, t1, 8); // psraw s5, t1, 8 + c->lq(t1, 16, t9); // lq t1, 16(t9) + c->divs(f3, f0, f3); // div.s f3, f0, f3 + c->lq(t2, 16, ra); // lq t2, 16(ra) + c->mov128_gpr_gpr(gp, s0); // por gp, s0, r0 + c->subs(f4, f4, f0); // sub.s f4, f4, f0 + c->ppach(t4, r0, t4); // ppach t4, r0, t4 + c->lq(t3, 16, s4); // lq t3, 16(s4) + c->ppach(t5, r0, t5); // ppach t5, r0, t5 + c->lq(t8, 16, s3); // lq t8, 16(s3) + c->ppach(t6, r0, t6); // ppach t6, r0, t6 + c->lq(t9, 0, t9); // lq t9, 0(t9) + c->ppach(t7, r0, t7); // ppach t7, r0, t7 + c->lq(ra, 0, ra); // lq ra, 0(ra) + c->pextlw(t4, t5, t4); // pextlw t4, t5, t4 + c->lq(t5, 0, s4); // lq t5, 0(s4) + c->pextlw(t6, t7, t6); // pextlw t6, t7, t6 + c->lq(t7, 0, s3); // lq t7, 0(s3) + c->mov128_gpr_gpr(s0, s1); // por s0, s1, r0 + c->muls(f5, f3, f0); // mul.s f5, f3, f0 + c->mov128_gpr_gpr(s1, s2); // por s1, s2, r0 + c->divs(f3, f0, f4); // div.s f3, f0, f4 + c->pcpyld(t4, t6, t4); // pcpyld t4, t6, t4 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t4, t4, a1); // pand t4, t4, a1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->mov128_gpr_gpr(s2, s5); // por s2, s5, r0 + c->mfc1(t6, f5); // mfc1 t6, f5 + c->subs(f4, f1, f0); // sub.s f4, f1, f0 + // nop // sll r0, r0, 0 + c->por(t4, t4, gp); // por t4, t4, gp + // nop // sll r0, r0, 0 + c->subs(f1, f2, f0); // sub.s f1, f2, f0 + // nop // sll r0, r0, 0 + c->muls(f2, f3, f0); // mul.s f2, f3, f0 + c->sq(t4, -16, v1); // sq t4, -16(v1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->divs(f3, f0, f4); // div.s f3, f0, f4 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(t4, f2); // mfc1 t4, f2 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->muls(f2, f3, f0); // mul.s f2, f3, f0 + // nop // sll r0, r0, 0 + c->pextlw(t4, t4, t6); // pextlw t4, t4, t6 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->divs(f1, f0, f1); // div.s f1, f0, f1 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(t6, f2); // mfc1 t6, f2 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf21, t1); // qmtc2.ni vf21, t1 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf22, t2); // qmtc2.ni vf22, t2 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf23, t3); // qmtc2.ni vf23, t3 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf24, t8); // qmtc2.ni vf24, t8 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(t1, f1); // mfc1 t1, f1 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf9, t9); // qmtc2.ni vf9, t9 + c->pextlw(t1, t1, t6); // pextlw t1, t1, t6 + c->mov128_vf_gpr(vf10, ra); // qmtc2.ni vf10, ra + c->pcpyld(t1, t1, t4); // pcpyld t1, t1, t4 + c->mov128_vf_gpr(vf11, t5); // qmtc2.ni vf11, t5 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf12, t7); // qmtc2.ni vf12, t7 + // nop // sll r0, r0, 0 + c->mov128_vf_gpr(vf27, t1); // qmtc2.ni vf27, t1 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t4, vf17); // qmfc2.ni t4, vf17 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t5, vf18); // qmfc2.ni t5, vf18 + // nop // sll r0, r0, 0 + c->mov128_gpr_vf(t6, vf19); // qmfc2.ni t6, vf19 + bc = ((s64)c->sgpr64(a0)) > 0; // bgtz a0, L70 + c->mov128_gpr_vf(t7, vf20); // qmfc2.ni t7, vf20 + if (bc) {goto block_7;} // branch non-likely + + + block_8: + c->daddiu(v1, v1, 16); // daddiu v1, v1, 16 + // nop // sll r0, r0, 0 + c->ppach(t4, r0, t4); // ppach t4, r0, t4 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->ppach(t5, r0, t5); // ppach t5, r0, t5 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->ppach(t6, r0, t6); // ppach t6, r0, t6 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->ppach(t7, r0, t7); // ppach t7, r0, t7 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlw(t4, t5, t4); // pextlw t4, t5, t4 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlw(t6, t7, t6); // pextlw t6, t7, t6 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyld(t4, t6, t4); // pcpyld t4, t6, t4 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t4, t4, a1); // pand t4, t4, a1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->por(t4, t4, s0); // por t4, t4, s0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->sq(t4, -16, v1); // sq t4, -16(v1) + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + c->ld(ra, 12432, at); // ld ra, 12432(at) + c->lq(gp, 12544, at); // lq gp, 12544(at) + c->lq(s5, 12528, at); // lq s5, 12528(at) + c->lq(s4, 12512, at); // lq s4, 12512(at) + c->lq(s3, 12496, at); // lq s3, 12496(at) + c->lq(s2, 12480, at); // lq s2, 12480(at) + c->lq(s1, 12464, at); // lq s1, 12464(at) + c->lq(s0, 12448, at); // lq s0, 12448(at) + //jr ra // jr ra + c->daddiu(sp, sp, 128); // daddiu sp, sp, 128 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + gLinkedFunctionTable.reg("generic-envmap-proc", execute, 256); +} + +} // namespace generic_envmap_proc +} // namespace Mips2C + + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace generic_prepare_dma_single { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* +} cache; + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + c->daddiu(sp, sp, -32); // daddiu sp, sp, -32 + c->sq(gp, 12448, at); // sq gp, 12448(at) + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + // nop // sll r0, r0, 0 + c->lw(t1, 60, at); // lw t1, 60(at) + // nop // sll r0, r0, 0 + c->lw(t8, 64, at); // lw t8, 64(at) + // nop // sll r0, r0, 0 + c->lw(v1, 40, at); // lw v1, 40(at) + // nop // sll r0, r0, 0 + c->lw(t3, 72, at); // lw t3, 72(at) + // nop // sll r0, r0, 0 + c->lh(a1, 18, t1); // lh a1, 18(t1) + c->mov64(a0, v1); // or a0, v1, r0 + c->lbu(a2, 16, t1); // lbu a2, 16(t1) + bc = c->sgpr64(t8) == 0; // beq t8, r0, L55 + c->lq(t4, 11744, at); // lq t4, 11744(at) + if (bc) {goto block_10;} // branch non-likely + + // nop // sll r0, r0, 0 + c->lq(t9, 11808, at); // lq t9, 11808(at) + // nop // sll r0, r0, 0 + c->lq(gp, 11824, at); // lq gp, 11824(at) + c->mov64(a3, a2); // or a3, a2, r0 + c->lq(t7, 11840, at); // lq t7, 11840(at) + bc = c->sgpr64(t3) != 0; // bne t3, r0, L49 + c->lq(t2, 11856, at); // lq t2, 11856(at) + if (bc) {goto block_3;} // branch non-likely + + // nop // sll r0, r0, 0 + c->lq(t0, 11872, at); // lq t0, 11872(at) + // nop // sll r0, r0, 0 + c->lq(t5, 11888, at); // lq t5, 11888(at) + //beq r0, r0, L50 // beq r0, r0, L50 + c->lq(t6, 11936, at); // lq t6, 11936(at) + goto block_4; // branch always + + + block_3: + // nop // sll r0, r0, 0 + c->lq(t0, 12032, at); // lq t0, 12032(at) + // nop // sll r0, r0, 0 + c->lq(t5, 11936, at); // lq t5, 11936(at) + // nop // sll r0, r0, 0 + c->lq(t6, 11936, at); // lq t6, 11936(at) + + block_4: + // nop // sll r0, r0, 0 + c->sq(t4, 0, a0); // sq t4, 0(a0) + // nop // sll r0, r0, 0 + c->sq(t9, 16, a0); // sq t9, 16(a0) + // nop // sll r0, r0, 0 + c->sq(gp, 32, a0); // sq gp, 32(a0) + c->mov64(t4, t8); // or t4, t8, r0 + c->sq(t7, 48, a0); // sq t7, 48(a0) + c->daddiu(t1, t1, 22); // daddiu t1, t1, 22 + c->sq(t2, 64, a0); // sq t2, 64(a0) + c->addiu(t2, r0, 0); // addiu t2, r0, 0 + c->sq(t0, 80, a0); // sq t0, 80(a0) + c->addiu(t0, r0, 128); // addiu t0, r0, 128 + c->sq(t5, 96, a0); // sq t5, 96(a0) + bc = c->sgpr64(t3) != 0; // bne t3, r0, L52 + c->sq(t6, 112, a0); // sq t6, 112(a0) + if (bc) {goto block_7;} // branch non-likely + + + block_5: + c->daddu(a0, a0, t0); // daddu a0, a0, t0 + c->lq(t0, 0, t4); // lq t0, 0(t4) + c->daddiu(a3, a3, -1); // daddiu a3, a3, -1 + c->lbu(t3, 0, t1); // lbu t3, 0(t1) + // nop // sll r0, r0, 0 + c->lq(t5, 16, t4); // lq t5, 16(t4) + c->daddu(t7, t3, t3); // daddu t7, t3, t3 + c->lq(t6, 32, t4); // lq t6, 32(t4) + c->daddu(t8, t7, t3); // daddu t8, t7, t3 + c->lq(t7, 48, t4); // lq t7, 48(t4) + c->daddiu(t9, t8, 9); // daddiu t9, t8, 9 + c->lq(t8, 64, t4); // lq t8, 64(t4) + c->daddiu(t4, t4, 80); // daddiu t4, t4, 80 + c->sq(t0, 0, a0); // sq t0, 0(a0) + // nop // sll r0, r0, 0 + c->sw(t2, 12, a0); // sw t2, 12(a0) + c->daddiu(t1, t1, 1); // daddiu t1, t1, 1 + c->sq(t5, 16, a0); // sq t5, 16(a0) + c->daddu(t2, t2, t9); // daddu t2, t2, t9 + c->sw(t3, 28, a0); // sw t3, 28(a0) + // nop // sll r0, r0, 0 + c->sq(t6, 32, a0); // sq t6, 32(a0) + c->addiu(t0, r0, 80); // addiu t0, r0, 80 + c->sq(t7, 48, a0); // sq t7, 48(a0) + bc = ((s64)c->sgpr64(a3)) > 0; // bgtz a3, L51 + c->sq(t8, 64, a0); // sq t8, 64(a0) + if (bc) {goto block_5;} // branch non-likely + + //beq r0, r0, L54 // beq r0, r0, L54 + // nop // sll r0, r0, 0 + goto block_9; // branch always + + + block_7: + // nop // sll r0, r0, 0 + c->lw(t3, 68, at); // lw t3, 68(at) + // nop // sll r0, r0, 0 + c->lq(t4, 0, t3); // lq t4, 0(t3) + // nop // sll r0, r0, 0 + c->lq(t5, 16, t3); // lq t5, 16(t3) + // nop // sll r0, r0, 0 + c->lq(t6, 32, t3); // lq t6, 32(t3) + // nop // sll r0, r0, 0 + c->lq(t7, 48, t3); // lq t7, 48(t3) + // nop // sll r0, r0, 0 + c->lq(t8, 64, t3); // lq t8, 64(t3) + + block_8: + c->daddu(a0, a0, t0); // daddu a0, a0, t0 + c->lbu(t3, 0, t1); // lbu t3, 0(t1) + c->daddiu(a3, a3, -1); // daddiu a3, a3, -1 + c->sq(t4, 0, a0); // sq t4, 0(a0) + c->daddu(t0, t3, t3); // daddu t0, t3, t3 + c->sw(t2, 12, a0); // sw t2, 12(a0) + c->daddu(t0, t0, t3); // daddu t0, t0, t3 + c->sq(t5, 16, a0); // sq t5, 16(a0) + c->daddiu(t0, t0, 9); // daddiu t0, t0, 9 + c->sw(t3, 28, a0); // sw t3, 28(a0) + c->daddiu(t1, t1, 1); // daddiu t1, t1, 1 + // nop // sll r0, r0, 0 + c->daddu(t2, t2, t0); // daddu t2, t2, t0 + c->sq(t6, 32, a0); // sq t6, 32(a0) + c->addiu(t0, r0, 80); // addiu t0, r0, 80 + c->sq(t7, 48, a0); // sq t7, 48(a0) + bc = ((s64)c->sgpr64(a3)) > 0; // bgtz a3, L53 + c->sq(t8, 64, a0); // sq t8, 64(a0) + if (bc) {goto block_8;} // branch non-likely + + + block_9: + c->ori(a3, t3, 32768); // ori a3, t3, 32768 + c->sw(a1, 52, at); // sw a1, 52(at) + // nop // sll r0, r0, 0 + c->sw(a3, 28, a0); // sw a3, 28(a0) + // nop // sll r0, r0, 0 + c->sw(a2, 92, a0); // sw a2, 92(a0) + // nop // sll r0, r0, 0 + c->sw(a1, 108, v1); // sw a1, 108(v1) + //beq r0, r0, L56 // beq r0, r0, L56 + c->sw(r0, 124, v1); // sw r0, 124(v1) + goto block_11; // branch always + + + block_10: + c->dsll(a3, a2, 2); // dsll a3, a2, 2 + c->sq(t4, 0, a0); // sq t4, 0(a0) + c->daddu(a3, a3, a2); // daddu a3, a3, a2 + c->sw(a1, 108, v1); // sw a1, 108(v1) + c->dsll(a3, a3, 4); // dsll a3, a3, 4 + // nop // sll r0, r0, 0 + c->daddiu(t0, a3, 128); // daddiu t0, a3, 128 + c->sw(a1, 52, at); // sw a1, 52(at) + + block_11: + c->dsll(t1, a2, 2); // dsll t1, a2, 2 + c->lw(a3, 12, v1); // lw a3, 12(v1) + c->daddu(a2, t1, a2); // daddu a2, t1, a2 + c->lw(t1, 84, at); // lw t1, 84(at) + c->daddiu(a2, a2, 7); // daddiu a2, a2, 7 + // nop // sll r0, r0, 0 + c->or_(t2, a3, t1); // or t2, a3, t1 + // nop // sll r0, r0, 0 + c->sll(t3, a2, 16); // sll t3, a2, 16 + c->xori(a3, t1, 38); // xori a3, t1, 38 + c->or_(t1, t2, t3); // or t1, t2, t3 + c->daddiu(a2, a2, 1); // daddiu a2, a2, 1 + // nop // sll r0, r0, 0 + c->sw(t1, 12, v1); // sw t1, 12(v1) + // nop // sll r0, r0, 0 + c->sw(a3, 84, at); // sw a3, 84(at) + c->daddiu(a1, a1, 3); // daddiu a1, a1, 3 + c->daddu(a0, a0, t0); // daddu a0, a0, t0 + c->dsra(a1, a1, 2); // dsra a1, a1, 2 + c->daddiu(a2, a0, 32); // daddiu a2, a0, 32 + c->dsll(t0, a1, 2); // dsll t0, a1, 2 + // nop // sll r0, r0, 0 + c->daddu(a3, t0, t0); // daddu a3, t0, t0 + c->dsll(a1, t0, 2); // dsll a1, t0, 2 + c->daddu(a3, a3, t0); // daddu a3, a3, t0 + c->daddiu(a1, a1, 15); // daddiu a1, a1, 15 + c->dsll(a3, a3, 2); // dsll a3, a3, 2 + c->dsra(a1, a1, 4); // dsra a1, a1, 4 + c->daddiu(a3, a3, 15); // daddiu a3, a3, 15 + c->dsll(t1, a1, 4); // dsll t1, a1, 4 + c->dsra(a3, a3, 4); // dsra a3, a3, 4 + c->lw(a1, 88, at); // lw a1, 88(at) + c->dsll(a3, a3, 4); // dsll a3, a3, 4 + // nop // sll r0, r0, 0 + c->daddu(a3, a2, a3); // daddu a3, a2, a3 + c->lw(t2, 11968, at); // lw t2, 11968(at) + c->daddu(a2, a3, t1); // daddu a2, a3, t1 + c->sq(r0, 0, a3); // sq r0, 0(a3) + c->daddiu(a2, a2, 16); // daddiu a2, a2, 16 + c->sq(r0, -16, a3); // sq r0, -16(a3) + c->daddu(t1, a2, t1); // daddu t1, a2, t1 + c->sq(r0, -32, a3); // sq r0, -32(a3) + c->daddiu(t1, t1, 16); // daddiu t1, t1, 16 + c->sq(r0, 0, a2); // sq r0, 0(a2) + c->subu(t3, t1, v1); // subu t3, t1, v1 + c->sq(r0, -16, a2); // sq r0, -16(a2) + c->sra(t3, t3, 4); // sra t3, t3, 4 + c->sq(r0, 0, a0); // sq r0, 0(a0) + // nop // sll r0, r0, 0 + c->sh(t3, 0, v1); // sh t3, 0(v1) + c->daddiu(v1, t3, 1); // daddiu v1, t3, 1 + c->sq(r0, 0, t1); // sq r0, 0(t1) + // nop // sll r0, r0, 0 + c->sq(r0, -16, t1); // sq r0, -16(t1) + // nop // sll r0, r0, 0 + c->daddiu(t5, a1, 1); // daddiu t5, a1, 1 + c->daddiu(t4, a1, 2); // daddiu t4, a1, 2 + c->lw(t3, 11988, at); // lw t3, 11988(at) + // nop // sll r0, r0, 0 + c->lw(t7, 11972, at); // lw t7, 11972(at) + c->dsll(t0, t0, 16); // dsll t0, t0, 16 + c->lw(t6, 11976, at); // lw t6, 11976(at) + c->or_(t4, t7, t4); // or t4, t7, t4 + c->lw(t7, 11980, at); // lw t7, 11980(at) + c->or_(t5, t6, t5); // or t5, t6, t5 + c->lw(t6, 11984, at); // lw t6, 11984(at) + // nop // sll r0, r0, 0 + c->lw(t8, 11992, at); // lw t8, 11992(at) + c->mov64(t9, a1); // or t9, a1, r0 + c->sw(t2, 8, a0); // sw t2, 8(a0) + c->or_(t2, t7, t9); // or t2, t7, t9 + c->sw(t8, 0, t1); // sw t8, 0(t1) + c->daddiu(a0, a0, 16); // daddiu a0, a0, 16 + c->sw(r0, 4, t1); // sw r0, 4(t1) + c->or_(t4, t4, t0); // or t4, t4, t0 + c->sw(t6, 8, t1); // sw t6, 8(t1) + c->daddiu(a3, a3, 16); // daddiu a3, a3, 16 + c->sw(t3, 12, t1); // sw t3, 12(t1) + c->or_(t1, t5, t0); // or t1, t5, t0 + c->sw(t4, -4, a0); // sw t4, -4(a0) + c->or_(t0, t2, t0); // or t0, t2, t0 + c->sw(t1, -4, a3); // sw t1, -4(a3) + c->daddiu(a2, a2, 16); // daddiu a2, a2, 16 + c->sw(t0, -4, a2); // sw t0, -4(a2) + c->addiu(t0, r0, 567); // addiu t0, r0, 567 + c->sw(v1, 56, at); // sw v1, 56(at) + bc = c->sgpr64(a1) != c->sgpr64(t0); // bne a1, t0, L57 + c->daddiu(v1, a1, 279); // daddiu v1, a1, 279 + if (bc) {goto block_13;} // branch non-likely + + // nop // sll r0, r0, 0 + c->addiu(v1, r0, 9); // addiu v1, r0, 9 + + block_13: + // nop // sll r0, r0, 0 + c->sw(v1, 88, at); // sw v1, 88(at) + // nop // sll r0, r0, 0 + c->sw(a0, 20, at); // sw a0, 20(at) + // nop // sll r0, r0, 0 + c->sw(a3, 24, at); // sw a3, 24(at) + // nop // sll r0, r0, 0 + c->sw(a2, 28, at); // sw a2, 28(at) + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + c->lq(gp, 12448, at); // lq gp, 12448(at) + //jr ra // jr ra + c->daddiu(sp, sp, 32); // daddiu sp, sp, 32 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + gLinkedFunctionTable.reg("generic-prepare-dma-single", execute, 128); +} + +} // namespace generic_prepare_dma_single +} // namespace Mips2C + diff --git a/game/mips2c/functions/generic_merc.cpp b/game/mips2c/functions/generic_merc.cpp new file mode 100644 index 0000000000..74db89aab4 --- /dev/null +++ b/game/mips2c/functions/generic_merc.cpp @@ -0,0 +1,3349 @@ +//--------------------------MIPS2C--------------------- +// clang-format off +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace generic_merc_init_asm { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* + void* gsf_buffer; // *gsf-buffer* + void* inv_init_table; // *inv-init-table* + void* math_camera; // *math-camera* + void* generic_envmap_proc; // generic-envmap-proc + void* generic_light_proc; // generic-light-proc + void* generic_prepare_dma_double; // generic-prepare-dma-double + void* generic_prepare_dma_single; // generic-prepare-dma-single + void* high_speed_reject; // high-speed-reject + void* mercneric_convert; // mercneric-convert + void* mercneric_vu0_block; // mercneric-vu0-block + void* upload_vu0_program; // upload-vu0-program +} cache; + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u32 call_addr = 0; + c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 + c->sd(ra, 0, sp); // sd ra, 0(sp) + c->sd(fp, 8, sp); // sd fp, 8(sp) + c->mov64(fp, t9); // or fp, t9, r0 + c->load_symbol(t9, cache.upload_vu0_program); // lw t9, upload-vu0-program(s7) + c->load_symbol(a0, cache.mercneric_vu0_block); // lw a0, mercneric-vu0-block(s7) + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->ori(a1, v1, 100); // ori a1, v1, 100 + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->load_symbol(v1, cache.mercneric_convert); // lw v1, mercneric-convert(s7) + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->sw(v1, 7328, a0); // sw v1, 7328(a0) + c->load_symbol(v1, cache.generic_prepare_dma_single);// lw v1, generic-prepare-dma-single(s7) + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->sw(v1, 7332, a0); // sw v1, 7332(a0) + c->load_symbol(v1, cache.generic_prepare_dma_double);// lw v1, generic-prepare-dma-double(s7) + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->sw(v1, 7336, a0); // sw v1, 7336(a0) + c->load_symbol(v1, cache.generic_light_proc); // lw v1, generic-light-proc(s7) + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->sw(v1, 7340, a0); // sw v1, 7340(a0) + c->load_symbol(v1, cache.generic_envmap_proc); // lw v1, generic-envmap-proc(s7) + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->sw(v1, 7344, a0); // sw v1, 7344(a0) + c->load_symbol(v1, cache.high_speed_reject); // lw v1, high-speed-reject(s7) + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->sw(v1, 7348, a0); // sw v1, 7348(a0) + c->load_symbol(v1, cache.math_camera); // lw v1, *math-camera*(s7) + c->addiu(a0, r0, 7008); // addiu a0, r0, 7008 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a3, a0, a1); // daddu a3, a0, a1 + c->daddiu(t0, v1, 156); // daddiu t0, v1, 156 + c->lq(a0, 0, t0); // lq a0, 0(t0) + c->lq(a1, 16, t0); // lq a1, 16(t0) + c->lq(a2, 32, t0); // lq a2, 32(t0) + c->lq(t0, 48, t0); // lq t0, 48(t0) + c->sq(a0, 0, a3); // sq a0, 0(a3) + c->sq(a1, 16, a3); // sq a1, 16(a3) + c->sq(a2, 32, a3); // sq a2, 32(a3) + c->sq(t0, 48, a3); // sq t0, 48(a3) + c->addiu(a0, r0, 7072); // addiu a0, r0, 7072 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a3, a0, a1); // daddu a3, a0, a1 + c->daddiu(t0, v1, 220); // daddiu t0, v1, 220 + c->lq(a0, 0, t0); // lq a0, 0(t0) + c->lq(a1, 16, t0); // lq a1, 16(t0) + c->lq(a2, 32, t0); // lq a2, 32(t0) + c->lq(t0, 48, t0); // lq t0, 48(t0) + c->sq(a0, 0, a3); // sq a0, 0(a3) + c->sq(a1, 16, a3); // sq a1, 16(a3) + c->sq(a2, 32, a3); // sq a2, 32(a3) + c->sq(t0, 48, a3); // sq t0, 48(a3) + c->addiu(a0, r0, 7136); // addiu a0, r0, 7136 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a3, a0, a1); // daddu a3, a0, a1 + c->daddiu(t0, v1, 428); // daddiu t0, v1, 428 + c->lq(a0, 0, t0); // lq a0, 0(t0) + c->lq(a1, 16, t0); // lq a1, 16(t0) + c->lq(a2, 32, t0); // lq a2, 32(t0) + c->lq(t0, 48, t0); // lq t0, 48(t0) + c->sq(a0, 0, a3); // sq a0, 0(a3) + c->sq(a1, 16, a3); // sq a1, 16(a3) + c->sq(a2, 32, a3); // sq a2, 32(a3) + c->sq(t0, 48, a3); // sq t0, 48(a3) + c->fprs[f0] = 1.0; // lwc1 f0, L163(fp) + c->lwc1(f1, 12, v1); // lwc1 f1, 12(v1) + c->divs(f1, f0, f1); // div.s f1, f0, f1 + c->fprs[f0] = 1.0; // lwc1 f0, L163(fp) + c->lwc1(f2, 16, v1); // lwc1 f2, 16(v1) + c->divs(f0, f0, f2); // div.s f0, f0, f2 + c->addiu(v1, r0, 7360); // addiu v1, r0, 7360 + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->daddu(a0, v1, a0); // daddu a0, v1, a0 + c->addiu(v1, r0, 7376); // addiu v1, r0, 7376 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(v1, v1, a1); // daddu v1, v1, a1 + c->swc1(f1, 0, a0); // swc1 f1, 0(a0) + c->negs(f1, f1); // neg.s f1, f1 + c->swc1(f1, 4, a0); // swc1 f1, 4(a0) + c->mtc1(f1, r0); // mtc1 f1, r0 + c->swc1(f1, 8, a0); // swc1 f1, 8(a0) + c->mtc1(f1, r0); // mtc1 f1, r0 + c->swc1(f1, 12, a0); // swc1 f1, 12(a0) + c->mtc1(f1, r0); // mtc1 f1, r0 + c->swc1(f1, 0, v1); // swc1 f1, 0(v1) + c->mtc1(f1, r0); // mtc1 f1, r0 + c->swc1(f1, 4, v1); // swc1 f1, 4(v1) + c->swc1(f0, 8, v1); // swc1 f0, 8(v1) + c->negs(f0, f0); // neg.s f0, f0 + c->swc1(f0, 12, v1); // swc1 f0, 12(v1) + c->load_symbol(v1, cache.gsf_buffer); // lw v1, *gsf-buffer*(s7) + c->daddiu(a0, v1, 32); // daddiu a0, v1, 32 + c->sw(a0, 0, v1); // sw a0, 0(v1) + c->daddiu(a0, v1, 448); // daddiu a0, v1, 448 + c->sw(a0, 4, v1); // sw a0, 4(v1) + c->daddiu(a0, v1, 6608); // daddiu a0, v1, 6608 + c->sw(a0, 8, v1); // sw a0, 8(v1) + c->daddiu(a0, v1, 2784); // daddiu a0, v1, 2784 + c->sw(a0, 2752, v1); // sw a0, 2752(v1) + c->daddiu(a0, v1, 3200); // daddiu a0, v1, 3200 + c->sw(a0, 2756, v1); // sw a0, 2756(v1) + c->daddiu(a0, v1, 6608); // daddiu a0, v1, 6608 + c->sw(a0, 2760, v1); // sw a0, 2760(v1) + c->load_symbol(v1, cache.gsf_buffer); // lw v1, *gsf-buffer*(s7) + c->daddiu(a0, v1, 5504); // daddiu a0, v1, 5504 + c->mov64(a0, a0); // or a0, a0, r0 + c->load_symbol(a1, cache.inv_init_table); // lw a1, *inv-init-table*(s7) + c->mov64(a1, a1); // or a1, a1, r0 + c->sq(r0, 0, a0); // sq r0, 0(a0) + c->sq(r0, 544, a0); // sq r0, 544(a0) + c->sq(r0, 16, a0); // sq r0, 16(a0) + c->sq(r0, 560, a0); // sq r0, 560(a0) + c->sq(r0, 208, a0); // sq r0, 208(a0) + c->sq(r0, 752, a0); // sq r0, 752(a0) + c->sq(r0, 224, a0); // sq r0, 224(a0) + c->sq(r0, 768, a0); // sq r0, 768(a0) + c->sq(r0, 240, a0); // sq r0, 240(a0) + c->sq(r0, 784, a0); // sq r0, 784(a0) + c->sq(r0, 384, a0); // sq r0, 384(a0) + c->sq(r0, 800, a0); // sq r0, 800(a0) + c->sq(r0, 400, a0); // sq r0, 400(a0) + c->sq(r0, 944, a0); // sq r0, 944(a0) + c->sq(r0, 416, a0); // sq r0, 416(a0) + c->sq(r0, 960, a0); // sq r0, 960(a0) + c->sq(r0, 432, a0); // sq r0, 432(a0) + c->sq(r0, 976, a0); // sq r0, 976(a0) + c->sq(r0, 448, a0); // sq r0, 448(a0) + c->sq(r0, 992, a0); // sq r0, 992(a0) + c->sq(r0, 464, a0); // sq r0, 464(a0) + c->sq(r0, 1008, a0); // sq r0, 1008(a0) + c->sq(r0, 480, a0); // sq r0, 480(a0) + c->sq(r0, 1024, a0); // sq r0, 1024(a0) + c->sq(r0, 496, a0); // sq r0, 496(a0) + c->sq(r0, 1040, a0); // sq r0, 1040(a0) + c->sq(r0, 512, a0); // sq r0, 512(a0) + c->sq(r0, 1056, a0); // sq r0, 1056(a0) + c->sq(r0, 528, a0); // sq r0, 528(a0) + c->sq(r0, 1072, a0); // sq r0, 1072(a0) + c->addiu(a2, r0, 8); // addiu a2, r0, 8 + // nop // sll r0, r0, 0 + + block_1: + c->lhu(t1, 2, a1); // lhu t1, 2(a1) + c->daddiu(a2, a2, -1); // daddiu a2, a2, -1 + c->lbu(a3, 0, a1); // lbu a3, 0(a1) + // nop // sll r0, r0, 0 + c->lbu(t0, 1, a1); // lbu t0, 1(a1) + // nop // sll r0, r0, 0 + c->daddu(t1, t1, a0); // daddu t1, t1, a0 + c->daddiu(a1, a1, 4); // daddiu a1, a1, 4 + + block_2: + c->sb(t0, 0, t1); // sb t0, 0(t1) + c->daddiu(a3, a3, -1); // daddiu a3, a3, -1 + c->sb(t0, 550, t1); // sb t0, 550(t1) + c->daddiu(t0, t0, 2); // daddiu t0, t0, 2 + c->daddiu(t1, t1, 3); // daddiu t1, t1, 3 + // nop // sll r0, r0, 0 + bc = c->sgpr64(a3) != 0; // bne a3, r0, L156 + // nop // sll r0, r0, 0 + if (bc) {goto block_2;} // branch non-likely + + bc = c->sgpr64(a2) != 0; // bne a2, r0, L155 + // nop // sll r0, r0, 0 + if (bc) {goto block_1;} // branch non-likely + + c->daddu(a0, r0, v1); // daddu a0, r0, v1 + c->mov64(a0, a0); // or a0, a0, r0 + c->sq(r0, 416, a0); // sq r0, 416(a0) + c->sq(r0, 432, a0); // sq r0, 432(a0) + c->daddiu(v1, v1, 2752); // daddiu v1, v1, 2752 + c->mov64(v1, v1); // or v1, v1, r0 + c->sq(r0, 416, v1); // sq r0, 416(v1) + c->sq(r0, 432, v1); // sq r0, 432(v1) + c->gprs[v1].du64[0] = 0; // or v1, r0, r0 + c->lui(v1, 4096); // lui v1, 4096 + c->ori(v1, v1, 32768); // ori v1, v1, 32768 + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->ori(a0, a0, 100); // ori a0, a0, 100 + // this is just to wait for dma to finish. +// c->lw(a1, 0, v1); // lw a1, 0(v1) +// c->andi(a1, a1, 256); // andi a1, a1, 256 +// bc = c->sgpr64(a1) == 0; // beq a1, r0, L158 +// // DANGER jump to delay slot, this MUST be fixed manually! +// // fine to execute the lw twice in the non-branch case. +// c->lw(a1, 0, a0); // lw a1, 0(a0) +// if (bc) {goto block_7;} // branch non-likely +// +// +// block_5: +// c->lw(a1, 0, a0); // lw a1, 0(a0) +// // nop // sll r0, r0, 0 +// c->lw(a2, 0, v1); // lw a2, 0(v1) +// // nop // sll r0, r0, 0 +// c->andi(a2, a2, 256); // andi a2, a2, 256 +// c->daddiu(a1, a1, 1); // daddiu a1, a1, 1 +// bc = c->sgpr64(a2) != 0; // bne a2, r0, L157 +// c->sw(a1, 0, a0); // sw a1, 0(a0) +// if (bc) {goto block_5;} // branch non-likely + + // block_7: + c->gprs[v1].du64[0] = 0; // or v1, r0, r0 + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + c->ld(ra, 0, sp); // ld ra, 0(sp) + c->ld(fp, 8, sp); // ld fp, 8(sp) + //jr ra // jr ra + c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 + goto end_of_function; // return + + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + cache.gsf_buffer = intern_from_c("*gsf-buffer*").c(); + cache.inv_init_table = intern_from_c("*inv-init-table*").c(); + cache.math_camera = intern_from_c("*math-camera*").c(); + cache.generic_envmap_proc = intern_from_c("generic-envmap-proc").c(); + cache.generic_light_proc = intern_from_c("generic-light-proc").c(); + cache.generic_prepare_dma_double = intern_from_c("generic-prepare-dma-double").c(); + cache.generic_prepare_dma_single = intern_from_c("generic-prepare-dma-single").c(); + cache.high_speed_reject = intern_from_c("high-speed-reject").c(); + cache.mercneric_convert = intern_from_c("mercneric-convert").c(); + cache.mercneric_vu0_block = intern_from_c("mercneric-vu0-block").c(); + cache.upload_vu0_program = intern_from_c("upload-vu0-program").c(); + gLinkedFunctionTable.reg("generic-merc-init-asm", execute, 256); +} + +} // namespace generic_merc_init_asm +} // namespace Mips2C + + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace generic_merc_execute_asm { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* + void* gsf_buffer; // *gsf-buffer* + void* merc_globals; // *merc-globals* + void* merc_death_spawn; // merc-death-spawn + void* vector_matrix; // vector-matrix*! +} cache; + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u32 call_addr = 0; + u32 qwc = 0; + u32 madr = 0; + c->daddiu(sp, sp, -272); // daddiu sp, sp, -272 + c->sd(ra, 0, sp); // sd ra, 0(sp) + c->sd(fp, 8, sp); // sd fp, 8(sp) + c->mov64(fp, t9); // or fp, t9, r0 + c->sq(s0, 160, sp); // sq s0, 160(sp) + c->sq(s1, 176, sp); // sq s1, 176(sp) + c->sq(s2, 192, sp); // sq s2, 192(sp) + c->sq(s3, 208, sp); // sq s3, 208(sp) + c->sq(s4, 224, sp); // sq s4, 224(sp) + c->sq(s5, 240, sp); // sq s5, 240(sp) + c->sq(gp, 256, sp); // sq gp, 256(sp) + c->load_symbol(v1, cache.merc_globals); // lw v1, *merc-globals*(s7) + c->lwu(s2, 0, v1); // lwu s2, 0(v1) + c->addiu(v1, r0, 0); // addiu v1, r0, 0 + c->addiu(gp, r0, 0); // addiu gp, r0, 0 + c->addiu(s5, r0, 0); // addiu s5, r0, 0 + c->load_symbol(s4, cache.gsf_buffer); // lw s4, *gsf-buffer*(s7) + c->lui(v1, 4096); // lui v1, 4096 + c->ori(s3, v1, 54272); // ori s3, v1, 54272 // spr to + c->addiu(v1, r0, 640); // addiu v1, r0, 640 + c->lui(a0, 4096); // lui a0, 4096 + c->ori(a0, a0, 54272); // ori a0, a0, 54272 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->ori(a1, a1, 104); // ori a1, a1, 104 +// just wait for dma to end. + //c->lw(a2, 0, a0); // lw a2, 0(a0) + //c->andi(a2, a2, 256); // andi a2, a2, 256 + //bc = c->sgpr64(a2) == 0; // beq a2, r0, L15 + // DANGER jump to delay slot, this MUST be fixed manually! + //c->lw(a2, 0, a1); // lw a2, 0(a1) + //if (bc) {goto block_3;} // branch non-likely + + +// block_1: +// c->lw(a2, 0, a1); // lw a2, 0(a1) +// // nop // sll r0, r0, 0 +// c->lw(a3, 0, a0); // lw a3, 0(a0) +// // nop // sll r0, r0, 0 +// c->andi(a3, a3, 256); // andi a3, a3, 256 +// c->daddiu(a2, a2, 1); // daddiu a2, a2, 1 +// bc = c->sgpr64(a3) != 0; // bne a3, r0, L14 +// c->sw(a2, 0, a1); // sw a2, 0(a1) +// if (bc) {goto block_1;} // branch non-likely + + // block_3: + c->gprs[a0].du64[0] = 0; // or a0, r0, r0 + // c->sw(v1, 128, s3); // sw v1, 128(s3) + u32 sadr = c->sgpr64(v1); + // c->sw(s2, 48, s3); // sw s2, 48(s3) + u32 tadr = c->sgpr64(s2); + // c->sw(r0, 32, s3); // sw r0, 32(s3) + // Unknown instr: sync.l + c->addiu(v1, r0, 324); // addiu v1, r0, 324 + // c->sw(v1, 0, s3); // sw v1, 0(s3) + spad_to_dma_blerc_chain(cache.fake_scratchpad_data, sadr, tadr); + // Unknown instr: sync.l + //beq r0, r0, L67 // beq r0, r0, L67 + // nop // sll r0, r0, 0 + goto block_101; // branch always + + + block_4: + bc = c->sgpr64(gp) != 0; // bne gp, r0, L17 + // nop // sll r0, r0, 0 + if (bc) {goto block_6;} // branch non-likely + + c->addiu(v1, r0, 640); // addiu v1, r0, 640 + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->daddu(v1, v1, a0); // daddu v1, v1, a0 + //beq r0, r0, L18 // beq r0, r0, L18 + // nop // sll r0, r0, 0 + goto block_7; // branch always + + + block_6: + c->addiu(v1, r0, 3616); // addiu v1, r0, 3616 + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->daddu(v1, v1, a0); // daddu v1, v1, a0 + + block_7: + bc = c->sgpr64(gp) != 0; // bne gp, r0, L19 + // nop // sll r0, r0, 0 + if (bc) {goto block_9;} // branch non-likely + + c->addiu(a0, r0, 3616); // addiu a0, r0, 3616 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a0, a0, a1); // daddu a0, a0, a1 + //beq r0, r0, L20 // beq r0, r0, L20 + // nop // sll r0, r0, 0 + goto block_10; // branch always + + + block_9: + c->addiu(a0, r0, 640); // addiu a0, r0, 640 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a0, a0, a1); // daddu a0, a0, a1 + + block_10: + bc = c->sgpr64(gp) != 0; // bne gp, r0, L21 + // nop // sll r0, r0, 0 + if (bc) {goto block_12;} // branch non-likely + + c->addiu(a1, r0, 3536); // addiu a1, r0, 3536 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->daddu(a1, a1, a2); // daddu a1, a1, a2 + //beq r0, r0, L22 // beq r0, r0, L22 + // nop // sll r0, r0, 0 + goto block_13; // branch always + + + block_12: + c->addiu(a1, r0, 6512); // addiu a1, r0, 6512 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->daddu(a1, a1, a2); // daddu a1, a1, a2 + + block_13: + bc = c->sgpr64(gp) != 0; // bne gp, r0, L23 + // nop // sll r0, r0, 0 + if (bc) {goto block_15;} // branch non-likely + + c->addiu(a1, r0, 6512); // addiu a1, r0, 6512 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->daddu(a1, a1, a2); // daddu a1, a1, a2 + //beq r0, r0, L24 // beq r0, r0, L24 + // nop // sll r0, r0, 0 + goto block_16; // branch always + + + block_15: + c->addiu(a1, r0, 3536); // addiu a1, r0, 3536 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->daddu(a1, a1, a2); // daddu a1, a1, a2 + + block_16: + bc = c->sgpr64(gp) != 0; // bne gp, r0, L25 + // nop // sll r0, r0, 0 + if (bc) {goto block_18;} // branch non-likely + + c->daddu(s1, r0, s4); // daddu s1, r0, s4 + //beq r0, r0, L26 // beq r0, r0, L26 + // nop // sll r0, r0, 0 + goto block_19; // branch always + + + block_18: + c->daddiu(s1, s4, 2752); // daddiu s1, s4, 2752 + + block_19: + bc = c->sgpr64(gp) != 0; // bne gp, r0, L27 + // nop // sll r0, r0, 0 + if (bc) {goto block_21;} // branch non-likely + + c->daddiu(a1, s4, 2752); // daddiu a1, s4, 2752 + //beq r0, r0, L28 // beq r0, r0, L28 + // nop // sll r0, r0, 0 + goto block_22; // branch always + + + block_21: + c->daddu(a1, r0, s4); // daddu a1, r0, s4 + + block_22: + c->addiu(a2, r0, 7008); // addiu a2, r0, 7008 + get_fake_spad_addr(a3, cache.fake_scratchpad_data, 0, c);// lui a3, 28672 + c->daddu(a2, a2, a3); // daddu a2, a2, a3 + c->sw(gp, 280, a2); // sw gp, 280(a2) + c->sw(s5, 284, a2); // sw s5, 284(a2) + c->sw(v1, 292, a2); // sw v1, 292(a2) + c->sw(a0, 296, a2); // sw a0, 296(a2) + c->sw(s1, 300, a2); // sw s1, 300(a2) + c->sw(a1, 304, a2); // sw a1, 304(a2) + c->sw(s4, 312, a2); // sw s4, 312(a2) + c->mov64(a1, s4); // or a1, s4, r0 + c->lui(a1, 4096); // lui a1, 4096 + c->ori(a1, a1, 54272); // ori a1, a1, 54272 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->ori(a2, a2, 104); // ori a2, a2, 104 +// c->lw(a3, 0, a1); // lw a3, 0(a1) +// c->andi(a3, a3, 256); // andi a3, a3, 256 +// bc = c->sgpr64(a3) == 0; // beq a3, r0, L30 + // DANGER jump to delay slot, this MUST be fixed manually! + c->lw(a3, 0, a2); // lw a3, 0(a2) +// if (bc) {goto block_25;} // branch non-likely + + +// block_23: +// c->lw(a3, 0, a2); // lw a3, 0(a2) +// // nop // sll r0, r0, 0 +// c->lw(t0, 0, a1); // lw t0, 0(a1) +// // nop // sll r0, r0, 0 +// c->andi(t0, t0, 256); // andi t0, t0, 256 +// c->daddiu(a3, a3, 1); // daddiu a3, a3, 1 +// bc = c->sgpr64(t0) != 0; // bne t0, r0, L29 +// c->sw(a3, 0, a2); // sw a3, 0(a2) +// if (bc) {goto block_23;} // branch non-likely + + // block_25: + c->gprs[a1].du64[0] = 0; // or a1, r0, r0 + c->lwu(s2, 12, v1); // lwu s2, 12(v1) + bc = c->sgpr64(s2) == 0; // beq s2, r0, L31 + c->mov64(a1, s7); // or a1, s7, r0 + if (bc) {goto block_27;} // branch non-likely + + c->daddu(a0, r0, a0); // daddu a0, r0, a0 + c->andi(a0, a0, 65535); // andi a0, a0, 65535 + // c->sw(a0, 128, s3); // sw a0, 128(s3) + sadr = c->sgpr64(a0); + //c->sw(s2, 48, s3); // sw s2, 48(s3) + tadr = c->sgpr64(s2); + //c->sw(r0, 32, s3); // sw r0, 32(s3) + // Unknown instr: sync.l + c->addiu(a0, r0, 324); // addiu a0, r0, 324 + // c->sw(a0, 0, s3); // sw a0, 0(s3) + // hack - I don't really know why, but the andi above puts sadr into a 64 kb + // range instead of a 16 kB range. I believe the hardware will just mask it. + // or, maybe there's something else wrong? Not sure, but the transfer does seem to go + // to the right spot when I use this. + spad_to_dma_blerc_chain(cache.fake_scratchpad_data, sadr & 0x3fff, tadr); + u32 debug2; + memcpy(&debug2, g_ee_main_mem + 12 + 0x175040, 4); + // Unknown instr: sync.l + c->gprs[a0].du64[0] = 0; // or a0, r0, r0 + + block_27: + bc = c->sgpr64(s5) != 0; // bne s5, r0, L39 + c->mov64(a0, s7); // or a0, s7, r0 + if (bc) {goto block_42;} // branch non-likely + + c->addiu(a0, r0, 6592); // addiu a0, r0, 6592 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a1, a0, a1); // daddu a1, a0, a1 + c->mov64(a2, v1); // or a2, v1, r0 + c->lwu(a0, 8, v1); // lwu a0, 8(v1) + // nop // sll r0, r0, 0 + c->daddiu(a3, a0, -4); // daddiu a3, a0, -4 + c->mov64(a1, a1); // or a1, a1, r0 + bc = ((s64)c->sgpr64(a3)) < 0; // bltz a3, L33 + c->mov64(a2, a2); // or a2, a2, r0 + if (bc) {goto block_30;} // branch non-likely + + + block_29: + // nop // sll r0, r0, 0 + c->lq(t2, 0, a2); // lq t2, 0(a2) + // nop // sll r0, r0, 0 + c->lq(a3, 16, a2); // lq a3, 16(a2) + c->daddiu(a0, a0, -4); // daddiu a0, a0, -4 + c->lq(t0, 32, a2); // lq t0, 32(a2) + c->daddiu(a1, a1, 64); // daddiu a1, a1, 64 + c->lq(t1, 48, a2); // lq t1, 48(a2) + c->daddiu(a2, a2, 64); // daddiu a2, a2, 64 + c->sq(t2, -64, a1); // sq t2, -64(a1) + c->daddiu(t2, a0, -4); // daddiu t2, a0, -4 + c->sq(a3, -48, a1); // sq a3, -48(a1) + // nop // sll r0, r0, 0 + c->sq(t0, -32, a1); // sq t0, -32(a1) + bc = ((s64)c->sgpr64(t2)) >= 0; // bgez t2, L32 + c->sq(t1, -16, a1); // sq t1, -16(a1) + if (bc) {goto block_29;} // branch non-likely + + + block_30: + bc = c->sgpr64(a0) == 0; // beq a0, r0, L34 + c->lq(a3, 0, a2); // lq a3, 0(a2) + if (bc) {goto block_35;} // branch non-likely + + c->daddiu(a2, a2, 16); // daddiu a2, a2, 16 + c->daddiu(a1, a1, 16); // daddiu a1, a1, 16 + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a3, -16, a1); // sq a3, -16(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L34 + c->lq(a3, 0, a2); // lq a3, 0(a2) + if (bc) {goto block_35;} // branch non-likely + + c->daddiu(a2, a2, 16); // daddiu a2, a2, 16 + c->daddiu(a1, a1, 16); // daddiu a1, a1, 16 + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a3, -16, a1); // sq a3, -16(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L34 + c->lq(a3, 0, a2); // lq a3, 0(a2) + if (bc) {goto block_35;} // branch non-likely + + c->daddiu(a2, a2, 16); // daddiu a2, a2, 16 + c->daddiu(a1, a1, 16); // daddiu a1, a1, 16 + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a3, -16, a1); // sq a3, -16(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L34 + c->lq(a3, 0, a2); // lq a3, 0(a2) + if (bc) {goto block_35;} // branch non-likely + + c->daddiu(a2, a2, 16); // daddiu a2, a2, 16 + c->daddiu(a1, a1, 16); // daddiu a1, a1, 16 + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a3, -16, a1); // sq a3, -16(a1) + + block_35: + c->gprs[a0].du64[0] = 0; // or a0, r0, r0 + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->lbu(a0, 6760, a0); // lbu a0, 6760(a0) + bc = c->sgpr64(a0) != 0; // bne a0, r0, L35 + // nop // sll r0, r0, 0 + if (bc) {goto block_37;} // branch non-likely + + c->addiu(a0, r0, 8); // addiu a0, r0, 8 + //beq r0, r0, L36 // beq r0, r0, L36 + // nop // sll r0, r0, 0 + goto block_38; // branch always + + + block_37: + c->addiu(a0, r0, 6); // addiu a0, r0, 6 + + block_38: + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->ori(a1, a1, 11984); // ori a1, a1, 11984 + c->sh(a0, 0, a1); // sh a0, 0(a1) + c->addiu(a0, r0, 12048); // addiu a0, r0, 12048 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a0, a0, a1); // daddu a0, a0, a1 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->lwu(a1, 6752, a1); // lwu a1, 6752(a1) + c->sw(a1, 0, a0); // sw a1, 0(a0) + c->sw(a1, 4, a0); // sw a1, 4(a0) + c->sw(a1, 8, a0); // sw a1, 8(a0) + c->sw(a1, 12, a0); // sw a1, 12(a0) + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->lbu(a0, 6761, a0); // lbu a0, 6761(a0) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L37 + // nop // sll r0, r0, 0 + if (bc) {goto block_40;} // branch non-likely + + c->addiu(a0, r0, 11808); // addiu a0, r0, 11808 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a0, a0, a1); // daddu a0, a0, a1 + c->addiu(a1, r0, 7072); // addiu a1, r0, 7072 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->daddu(t0, a1, a2); // daddu t0, a1, a2 + c->lq(a1, 0, t0); // lq a1, 0(t0) + c->lq(a2, 16, t0); // lq a2, 16(t0) + c->lq(a3, 32, t0); // lq a3, 32(t0) + c->lq(t0, 48, t0); // lq t0, 48(t0) + c->sq(a1, 0, a0); // sq a1, 0(a0) + c->sq(a2, 16, a0); // sq a2, 16(a0) + c->sq(a3, 32, a0); // sq a3, 32(a0) + c->sq(t0, 48, a0); // sq t0, 48(a0) + //beq r0, r0, L38 // beq r0, r0, L38 + // nop // sll r0, r0, 0 + goto block_41; // branch always + + + block_40: + c->addiu(a0, r0, 11808); // addiu a0, r0, 11808 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a0, a0, a1); // daddu a0, a0, a1 + c->addiu(a1, r0, 7008); // addiu a1, r0, 7008 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->daddu(t0, a1, a2); // daddu t0, a1, a2 + c->lq(a1, 0, t0); // lq a1, 0(t0) + c->lq(a2, 16, t0); // lq a2, 16(t0) + c->lq(a3, 32, t0); // lq a3, 32(t0) + c->lq(t0, 48, t0); // lq t0, 48(t0) + c->sq(a1, 0, a0); // sq a1, 0(a0) + c->sq(a2, 16, a0); // sq a2, 16(a0) + c->sq(a3, 32, a0); // sq a3, 32(a0) + c->sq(t0, 48, a0); // sq t0, 48(a0) + + block_41: + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->lbu(a0, 6763, a0); // lbu a0, 6763(a0) + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->sb(a0, 6773, a1); // sb a0, 6773(a1) + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + c->lqc2(vf1, 6608, at); // lqc2 vf1, 6608(at) + c->lqc2(vf2, 6624, at); // lqc2 vf2, 6624(at) + c->lqc2(vf3, 6640, at); // lqc2 vf3, 6640(at) + c->lqc2(vf4, 6656, at); // lqc2 vf4, 6656(at) + c->lqc2(vf5, 6672, at); // lqc2 vf5, 6672(at) + c->lqc2(vf6, 6688, at); // lqc2 vf6, 6688(at) + c->lqc2(vf7, 6704, at); // lqc2 vf7, 6704(at) + c->sqc2(vf1, 12688, at); // sqc2 vf1, 12688(at) + c->sqc2(vf2, 12704, at); // sqc2 vf2, 12704(at) + c->sqc2(vf3, 12720, at); // sqc2 vf3, 12720(at) + c->sqc2(vf4, 12736, at); // sqc2 vf4, 12736(at) + c->sqc2(vf5, 12752, at); // sqc2 vf5, 12752(at) + c->sqc2(vf6, 12768, at); // sqc2 vf6, 12768(at) + c->sqc2(vf7, 12784, at); // sqc2 vf7, 12784(at) + c->lwu(a0, 8, v1); // lwu a0, 8(v1) + c->dsll(a0, a0, 4); // dsll a0, a0, 4 + c->daddu(v1, v1, a0); // daddu v1, v1, a0 + c->mov64(a0, v1); // or a0, v1, r0 + + block_42: + c->daddiu(a0, s7, 8); // daddiu a0, s7, #t + bc = c->sgpr64(s7) == c->sgpr64(a0); // beq s7, a0, L40 + c->mov64(a0, s7); // or a0, s7, r0 + if (bc) {goto block_44;} // branch non-likely + + c->addiu(a0, r0, 7008); // addiu a0, r0, 7008 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a0, a0, a1); // daddu a0, a0, a1 + c->daddiu(v1, v1, 16); // daddiu v1, v1, 16 + c->sw(v1, 308, a0); // sw v1, 308(a0) + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(t9, 7328, v1); // lwu t9, 7328(v1) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + + block_44: + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->addiu(a0, r0, 1); // addiu a0, r0, 1 + c->lbu(a1, 6760, v1); // lbu a1, 6760(v1) + c->daddiu(a2, s1, 448); // daddiu a2, s1, 448 + c->lbu(a3, 6763, v1); // lbu a3, 6763(v1) + bc = c->sgpr64(a1) == 0; // beq a1, r0, L42 + c->lqc2(vf1, 0, a2); // lqc2 vf1, 0(a2) + if (bc) {goto block_50;} // branch non-likely + + bc = c->sgpr64(a3) == 0; // beq a3, r0, L42 + c->vmax_bc(DEST::xyzw, BC::w, vf9, vf0, vf0); // vmaxw.xyzw vf9, vf0, vf0 + if (bc) {goto block_50;} // branch non-likely + + c->sb(a0, 6773, v1); // sb a0, 6773(v1) + c->lqc2(vf10, 7360, v1); // lqc2 vf10, 7360(v1) + c->lqc2(vf11, 7376, v1); // lqc2 vf11, 7376(v1) + c->vmula_bc(DEST::xyzw, BC::z, vf9, vf1); // vmulaz.xyzw acc, vf9, vf1 + c->lw(a0, 8, a2); // lw a0, 8(a2) + c->vmadda_bc(DEST::xyzw, BC::x, vf10, vf1); // vmaddax.xyzw acc, vf10, vf1 + bc = ((s64)c->sgpr64(a0)) < 0; // bltz a0, L41 + c->lw(v1, 7348, v1); // lw v1, 7348(v1) + if (bc) {goto block_48;} // branch non-likely + + c->vmadd_bc(DEST::xyzw, BC::y, vf1, vf11, vf1); // vmaddy.xyzw vf1, vf11, vf1 + c->mov128_gpr_vf(a0, vf1); // qmfc2.i a0, vf1 + c->pcgtw(a0, r0, a0); // pcgtw a0, r0, a0 + c->ppach(a0, r0, a0); // ppach a0, r0, a0 + bc = c->sgpr64(a0) == 0; // beq a0, r0, L42 + // DANGER jump to delay slot, this MUST be fixed manually! + // nop // sll r0, r0, 0 + if (bc) {goto block_50;} // branch non-likely + + + block_48: + // nop // sll r0, r0, 0 + call_addr = c->gprs[v1].du32[0]; // function call: + // nop // sll r0, r0, 0 + c->jalr(call_addr); // jalr ra, v1 + + block_50: + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(v1, 6756, v1); // lwu v1, 6756(v1) + bc = c->sgpr64(v1) == 0; // beq v1, r0, L47 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_59;} // branch non-likely + + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(s0, 6756, v1); // lwu s0, 6756(v1) + c->lhu(v1, 20, s1); // lhu v1, 20(s1) + c->sq(v1, 48, sp); // sq v1, 48(sp) + c->lw(v1, 24, s0); // lw v1, 24(s0) + c->sq(v1, 64, sp); // sq v1, 64(sp) + c->lw(v1, 20, s0); // lw v1, 20(s0) + c->sq(v1, 80, sp); // sq v1, 80(sp) + bc = c->sgpr64(s5) != 0; // bne s5, r0, L43 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_53;} // branch non-likely + + c->addiu(v1, r0, 0); // addiu v1, r0, 0 + c->sq(v1, 80, sp); // sq v1, 80(sp) + c->lw(v1, 12, s0); // lw v1, 12(s0) + c->sq(v1, 64, sp); // sq v1, 64(sp) + c->lq(v1, 64, sp); // lq v1, 64(sp) + + block_53: + //beq r0, r0, L46 // beq r0, r0, L46 + // nop // sll r0, r0, 0 + goto block_57; // branch always + + + block_54: + c->lq(v1, 80, sp); // lq v1, 80(sp) + c->lw(a0, 0, s0); // lw a0, 0(s0) + c->slt(v1, v1, a0); // slt v1, v1, a0 + bc = c->sgpr64(v1) == 0; // beq v1, r0, L45 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_56;} // branch non-likely + + c->lq(v1, 80, sp); // lq v1, 80(sp) + c->dsll(v1, v1, 4); // dsll v1, v1, 4 + c->daddiu(v1, v1, 28); // daddiu v1, v1, 28 + c->daddu(a1, v1, s0); // daddu a1, v1, s0 + c->lq(v1, 64, sp); // lq v1, 64(sp) + c->dsll(v1, v1, 5); // dsll v1, v1, 5 + c->daddu(v1, v1, s1); // daddu v1, v1, s1 + c->lwc1(f0, 448, v1); // lwc1 f0, 448(v1) + c->swc1(f0, 0, a1); // swc1 f0, 0(a1) + c->lq(v1, 64, sp); // lq v1, 64(sp) + c->dsll(v1, v1, 5); // dsll v1, v1, 5 + c->daddu(v1, v1, s1); // daddu v1, v1, s1 + c->lwc1(f0, 452, v1); // lwc1 f0, 452(v1) + c->swc1(f0, 4, a1); // swc1 f0, 4(a1) + c->lq(v1, 64, sp); // lq v1, 64(sp) + c->dsll(v1, v1, 5); // dsll v1, v1, 5 + c->daddu(v1, v1, s1); // daddu v1, v1, s1 + c->lwc1(f0, 456, v1); // lwc1 f0, 456(v1) + c->swc1(f0, 8, a1); // swc1 f0, 8(a1) + c->fprs[f0] = 1.0; // lwc1 f0, L163(fp) + c->swc1(f0, 12, a1); // swc1 f0, 12(a1) + c->load_symbol(t9, cache.vector_matrix); // lw t9, vector-matrix*!(s7) + c->mov64(a0, a1); // or a0, a1, r0 + c->addiu(v1, r0, 7136); // addiu v1, r0, 7136 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->daddu(a2, v1, a2); // daddu a2, v1, a2 + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->lq(v1, 80, sp); // lq v1, 80(sp) + c->daddiu(v1, v1, 1); // daddiu v1, v1, 1 + c->sq(v1, 80, sp); // sq v1, 80(sp) + c->lq(v1, 80, sp); // lq v1, 80(sp) + + block_56: + c->lq(v1, 64, sp); // lq v1, 64(sp) + c->lw(a0, 16, s0); // lw a0, 16(s0) + c->daddu(v1, v1, a0); // daddu v1, v1, a0 + c->sq(v1, 64, sp); // sq v1, 64(sp) + + block_57: + c->lq(v1, 64, sp); // lq v1, 64(sp) + c->lq(a0, 48, sp); // lq a0, 48(sp) + c->slt(v1, v1, a0); // slt v1, v1, a0 + bc = c->sgpr64(v1) != 0; // bne v1, r0, L44 + // nop // sll r0, r0, 0 + if (bc) {goto block_54;} // branch non-likely + + c->mov64(v1, s7); // or v1, s7, r0 + c->lq(v1, 64, sp); // lq v1, 64(sp) + c->lq(a0, 48, sp); // lq a0, 48(sp) + c->dsubu(v1, v1, a0); // dsubu v1, v1, a0 + c->sw(v1, 24, s0); // sw v1, 24(s0) + c->lq(v1, 80, sp); // lq v1, 80(sp) + c->sw(v1, 20, s0); // sw v1, 20(s0) + + block_59: + c->daddiu(v1, s7, 8); // daddiu v1, s7, #t + bc = c->sgpr64(s7) == c->sgpr64(v1); // beq s7, v1, L50 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_65;} // branch non-likely + + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lhu(v1, 6764, v1); // lhu v1, 6764(v1) + bc = c->sgpr64(v1) == 0; // beq v1, r0, L50 + c->mov64(a0, s7); // or a0, s7, r0 + if (bc) {goto block_65;} // branch non-likely + + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lhu(s0, 6766, v1); // lhu s0, 6766(v1) + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lhu(v1, 6764, v1); // lhu v1, 6764(v1) + c->sq(v1, 96, sp); // sq v1, 96(sp) + c->lhu(v1, 20, s1); // lhu v1, 20(s1) + c->sq(v1, 112, sp); // sq v1, 112(sp) + c->daddiu(v1, sp, 16); // daddiu v1, sp, 16 + c->sq(v1, 128, sp); // sq v1, 128(sp) + c->lq(v1, 128, sp); // lq v1, 128(sp) + c->sq(r0, 0, v1); // sq r0, 0(v1) + c->daddiu(v1, sp, 32); // daddiu v1, sp, 32 + c->sq(v1, 144, sp); // sq v1, 144(sp) + c->lq(v1, 144, sp); // lq v1, 144(sp) + c->sq(r0, 0, v1); // sq r0, 0(v1) + //beq r0, r0, L49 // beq r0, r0, L49 + // nop // sll r0, r0, 0 + goto block_63; // branch always + + + block_62: + c->dsll(v1, s0, 5); // dsll v1, s0, 5 + c->daddu(v1, v1, s1); // daddu v1, v1, s1 + c->lwc1(f0, 448, v1); // lwc1 f0, 448(v1) + c->lq(v1, 128, sp); // lq v1, 128(sp) + c->swc1(f0, 0, v1); // swc1 f0, 0(v1) + c->dsll(v1, s0, 5); // dsll v1, s0, 5 + c->daddu(v1, v1, s1); // daddu v1, v1, s1 + c->lwc1(f0, 452, v1); // lwc1 f0, 452(v1) + c->lq(v1, 128, sp); // lq v1, 128(sp) + c->swc1(f0, 4, v1); // swc1 f0, 4(v1) + c->dsll(v1, s0, 5); // dsll v1, s0, 5 + c->daddu(v1, v1, s1); // daddu v1, v1, s1 + c->lwc1(f0, 456, v1); // lwc1 f0, 456(v1) + c->lq(v1, 128, sp); // lq v1, 128(sp) + c->swc1(f0, 8, v1); // swc1 f0, 8(v1) + c->fprs[f0] = 1.0; // lwc1 f0, L163(fp) + c->lq(v1, 128, sp); // lq v1, 128(sp) + c->swc1(f0, 12, v1); // swc1 f0, 12(v1) + c->dsll(v1, s0, 5); // dsll v1, s0, 5 + c->daddu(v1, v1, s1); // daddu v1, v1, s1 + c->lwc1(f0, 464, v1); // lwc1 f0, 464(v1) + c->lq(v1, 144, sp); // lq v1, 144(sp) + c->swc1(f0, 0, v1); // swc1 f0, 0(v1) + c->dsll(v1, s0, 5); // dsll v1, s0, 5 + c->daddu(v1, v1, s1); // daddu v1, v1, s1 + c->lwc1(f0, 468, v1); // lwc1 f0, 468(v1) + c->lq(v1, 144, sp); // lq v1, 144(sp) + c->swc1(f0, 4, v1); // swc1 f0, 4(v1) + c->dsll(v1, s0, 5); // dsll v1, s0, 5 + c->daddu(v1, v1, s1); // daddu v1, v1, s1 + c->lwc1(f0, 472, v1); // lwc1 f0, 472(v1) + c->lq(v1, 144, sp); // lq v1, 144(sp) + c->swc1(f0, 8, v1); // swc1 f0, 8(v1) + c->mtc1(f0, r0); // mtc1 f0, r0 + c->lq(v1, 144, sp); // lq v1, 144(sp) + c->swc1(f0, 12, v1); // swc1 f0, 12(v1) + c->load_symbol(t9, cache.vector_matrix); // lw t9, vector-matrix*!(s7) + c->lq(a0, 128, sp); // lq a0, 128(sp) + c->lq(a1, 128, sp); // lq a1, 128(sp) + c->addiu(v1, r0, 7136); // addiu v1, r0, 7136 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->daddu(a2, v1, a2); // daddu a2, v1, a2 + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->load_symbol(t9, cache.vector_matrix); // lw t9, vector-matrix*!(s7) + c->lq(a0, 144, sp); // lq a0, 144(sp) + c->lq(a1, 144, sp); // lq a1, 144(sp) + c->addiu(v1, r0, 7136); // addiu v1, r0, 7136 + get_fake_spad_addr(a2, cache.fake_scratchpad_data, 0, c);// lui a2, 28672 + c->daddu(a2, v1, a2); // daddu a2, v1, a2 + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->load_symbol(t9, cache.merc_death_spawn); // lw t9, merc-death-spawn(s7) + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(a0, 6768, v1); // lwu a0, 6768(v1) + c->lq(a1, 128, sp); // lq a1, 128(sp) + c->lq(a2, 144, sp); // lq a2, 144(sp) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->lq(v1, 96, sp); // lq v1, 96(sp) + c->daddu(s0, s0, v1); // daddu s0, s0, v1 + + block_63: + c->lq(v1, 112, sp); // lq v1, 112(sp) + c->sltu(v1, s0, v1); // sltu v1, s0, v1 + bc = c->sgpr64(v1) != 0; // bne v1, r0, L48 + // nop // sll r0, r0, 0 + if (bc) {goto block_62;} // branch non-likely + + c->mov64(v1, s7); // or v1, s7, r0 + c->lq(v1, 112, sp); // lq v1, 112(sp) + c->dsubu(a0, s0, v1); // dsubu a0, s0, v1 + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->sh(a0, 6766, v1); // sh a0, 6766(v1) + + block_65: + c->daddiu(v1, s7, 8); // daddiu v1, s7, #t + bc = c->sgpr64(s7) == c->sgpr64(v1); // beq s7, v1, L65 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_98;} // branch non-likely + + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lw(v1, 7296, v1); // lw v1, 7296(v1) + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->lwu(a0, 76, a0); // lwu a0, 76(a0) + c->dsubu(v1, v1, a0); // dsubu v1, v1, a0 + c->slt(v1, r0, v1); // slt v1, r0, v1 + bc = c->sgpr64(v1) != 0; // bne v1, r0, L51 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_68;} // branch non-likely + + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->sb(r0, 6773, v1); // sb r0, 6773(v1) + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->sb(r0, 6763, v1); // sb r0, 6763(v1) + c->gprs[v1].du64[0] = 0; // or v1, r0, r0 + + block_68: + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lbu(v1, 6773, v1); // lbu v1, 6773(v1) + bc = c->sgpr64(v1) == 0; // beq v1, r0, L65 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_98;} // branch non-likely + + c->addiu(v1, r0, 1); // addiu v1, r0, 1 + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->lbu(a0, 6827, a0); // lbu a0, 6827(a0) + c->dsubu(v1, v1, a0); // dsubu v1, v1, a0 + c->daddiu(a0, s7, 8); // daddiu a0, s7, 8 + c->movn(a0, s7, v1); // movn a0, s7, v1 + if (((s64)c->sgpr64(s7)) == ((s64)c->sgpr64(a0))) {// beql s7, a0, L52 + c->mov64(v1, a0); // or v1, a0, r0 + goto block_72; + } + + // block_71: + c->daddiu(v1, s7, 8); // daddiu v1, s7, 8 + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->lbu(a0, 6772, a0); // lbu a0, 6772(a0) + c->movz(v1, s7, a0); // movz v1, s7, a0 + + block_72: + bc = c->sgpr64(s7) == c->sgpr64(v1); // beq s7, v1, L57 + // nop // sll r0, r0, 0 + if (bc) {goto block_82;} // branch non-likely + + c->daddiu(v1, s7, 8); // daddiu v1, s7, #t + bc = c->sgpr64(s7) == c->sgpr64(v1); // beq s7, v1, L56 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_81;} // branch non-likely + + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + c->daddiu(v1, at, 12064); // daddiu v1, at, 12064 + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->lbu(a0, 6762, a0); // lbu a0, 6762(a0) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L53 + c->mov64(a0, s7); // or a0, s7, r0 + if (bc) {goto block_76;} // branch non-likely + + c->addiu(v1, r0, 6832); // addiu v1, r0, 6832 + get_fake_spad_addr(a0, cache.fake_scratchpad_data, 0, c);// lui a0, 28672 + c->daddu(v1, v1, a0); // daddu v1, v1, a0 + c->mov64(v1, v1); // or v1, v1, r0 + c->mov64(a0, v1); // or a0, v1, r0 + + block_76: + c->sw(r0, 64, at); // sw r0, 64(at) + c->sw(v1, 68, at); // sw v1, 68(at) + c->sw(s1, 60, at); // sw s1, 60(at) + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(t9, 7336, v1); // lwu t9, 7336(v1) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(t9, 7340, v1); // lwu t9, 7340(v1) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(t9, 7344, v1); // lwu t9, 7344(v1) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->lw(v1, 40, at); // lw v1, 40(at) + c->lw(a0, 56, at); // lw a0, 56(at) + c->mov64(a3, v1); // or a3, v1, r0 + // nop // sll r0, r0, 0 + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + c->lui(a2, 4096); // lui a2, 4096 + c->lwu(a1, 76, at); // lwu a1, 76(at) + c->ori(a2, a2, 53248); // ori a2, a2, 53248 + //c->lw(t1, 0, a2); // lw t1, 0(a2) + // nop // sll r0, r0, 0 + c->daddiu(t0, at, 108); // daddiu t0, at, 108 + c->andi(a3, a3, 16383); // andi a3, a3, 16383 + c->andi(t1, t1, 256); // andi t1, t1, 256 + // nop // sll r0, r0, 0 +// bc = c->sgpr64(t1) == 0; // beq t1, r0, L55 +// // nop // sll r0, r0, 0 +// if (bc) {goto block_80;} // branch non-likely +// +// c->mov64(t1, a2); // or t1, a2, r0 +// // nop // sll r0, r0, 0 +// +// block_78: +// c->lw(t2, 0, t0); // lw t2, 0(t0) +// // nop // sll r0, r0, 0 +// c->lw(t3, 0, t1); // lw t3, 0(t1) +// // nop // sll r0, r0, 0 +// c->andi(t3, t3, 256); // andi t3, t3, 256 +// c->daddiu(t2, t2, 1); // daddiu t2, t2, 1 +// bc = c->sgpr64(t3) != 0; // bne t3, r0, L54 +// c->sw(t2, 0, t0); // sw t2, 0(t0) +// if (bc) {goto block_78;} // branch non-likely +// +// c->gprs[t0].du64[0] = 0; // or t0, r0, r0 + + // block_80: +// spr from + c->dsll(t0, a0, 4); // dsll t0, a0, 4 + //c->sw(a3, 128, a2); // sw a3, 128(a2) + sadr = c->sgpr64(a3); + // nop // sll r0, r0, 0 + // c->sw(a1, 16, a2); // sw a1, 16(a2) + madr = c->sgpr64(a1); + c->addiu(a3, r0, 256); // addiu a3, r0, 256 + // c->sw(a0, 32, a2); // sw a0, 32(a2) + qwc = c->sgpr64(a0); + c->daddu(a0, a1, t0); // daddu a0, a1, t0 + // c->sw(a3, 0, a2); // sw a3, 0(a2) + spad_from_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + // nop // sll r0, r0, 0 + c->sw(a0, 76, at); // sw a0, 76(at) + c->gprs[a0].du64[0] = 0; // or a0, r0, r0 + c->xori(v1, v1, 4608); // xori v1, v1, 4608 + c->sw(v1, 40, at); // sw v1, 40(at) + + block_81: + //beq r0, r0, L65 // beq r0, r0, L65 + // nop // sll r0, r0, 0 + goto block_98; // branch always + + + block_82: + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lbu(v1, 6827, v1); // lbu v1, 6827(v1) + bc = c->sgpr64(v1) == 0; // beq v1, r0, L62 + // nop // sll r0, r0, 0 + if (bc) {goto block_92;} // branch non-likely + + c->daddiu(v1, s7, 8); // daddiu v1, s7, #t + bc = c->sgpr64(s7) == c->sgpr64(v1); // beq s7, v1, L61 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_91;} // branch non-likely + + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + c->mov64(v1, s1); // or v1, s1, r0 + c->daddiu(a0, at, 12064); // daddiu a0, at, 12064 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->lbu(a1, 6762, a1); // lbu a1, 6762(a1) + bc = c->sgpr64(a1) == 0; // beq a1, r0, L58 + c->mov64(a1, s7); // or a1, s7, r0 + if (bc) {goto block_86;} // branch non-likely + + c->addiu(a0, r0, 6832); // addiu a0, r0, 6832 + get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c);// lui a1, 28672 + c->daddu(a0, a0, a1); // daddu a0, a0, a1 + c->mov64(a0, a0); // or a0, a0, r0 + c->mov64(a1, a0); // or a1, a0, r0 + + block_86: + c->sw(r0, 64, at); // sw r0, 64(at) + c->sw(a0, 68, at); // sw a0, 68(at) + c->sw(v1, 60, at); // sw v1, 60(at) + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(t9, 7336, v1); // lwu t9, 7336(v1) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(t9, 7340, v1); // lwu t9, 7340(v1) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(t9, 7344, v1); // lwu t9, 7344(v1) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->lw(v1, 40, at); // lw v1, 40(at) + c->lw(a0, 56, at); // lw a0, 56(at) + c->mov64(a3, v1); // or a3, v1, r0 + // nop // sll r0, r0, 0 + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + c->lui(a2, 4096); // lui a2, 4096 + c->lwu(a1, 76, at); // lwu a1, 76(at) + c->ori(a2, a2, 53248); // ori a2, a2, 53248 +// c->lw(t1, 0, a2); // lw t1, 0(a2) + // nop // sll r0, r0, 0 + c->daddiu(t0, at, 108); // daddiu t0, at, 108 + c->andi(a3, a3, 16383); // andi a3, a3, 16383 + c->andi(t1, t1, 256); // andi t1, t1, 256 + // nop // sll r0, r0, 0 + bc = c->sgpr64(t1) == 0; // beq t1, r0, L60 + // nop // sll r0, r0, 0 +// if (bc) {goto block_90;} // branch non-likely +// +// c->mov64(t1, a2); // or t1, a2, r0 +// // nop // sll r0, r0, 0 +// +// block_88: +// c->lw(t2, 0, t0); // lw t2, 0(t0) +// // nop // sll r0, r0, 0 +// c->lw(t3, 0, t1); // lw t3, 0(t1) +// // nop // sll r0, r0, 0 +// c->andi(t3, t3, 256); // andi t3, t3, 256 +// c->daddiu(t2, t2, 1); // daddiu t2, t2, 1 +// bc = c->sgpr64(t3) != 0; // bne t3, r0, L59 +// c->sw(t2, 0, t0); // sw t2, 0(t0) +// if (bc) {goto block_88;} // branch non-likely +// +// c->gprs[t0].du64[0] = 0; // or t0, r0, r0 + + // block_90: + // spr from + c->dsll(t0, a0, 4); // dsll t0, a0, 4 + // c->sw(a3, 128, a2); // sw a3, 128(a2) + sadr = c->sgpr64(a3); + // nop // sll r0, r0, 0 + // c->sw(a1, 16, a2); // sw a1, 16(a2) + madr = c->sgpr64(a1); + c->addiu(a3, r0, 256); // addiu a3, r0, 256 + // c->sw(a0, 32, a2); // sw a0, 32(a2) + qwc = c->sgpr64(a0); + c->daddu(a0, a1, t0); // daddu a0, a1, t0 + // c->sw(a3, 0, a2); // sw a3, 0(a2) + spad_from_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + // nop // sll r0, r0, 0 + c->sw(a0, 76, at); // sw a0, 76(at) + c->gprs[a0].du64[0] = 0; // or a0, r0, r0 + c->xori(v1, v1, 4608); // xori v1, v1, 4608 + c->sw(v1, 40, at); // sw v1, 40(at) + + block_91: + //beq r0, r0, L65 // beq r0, r0, L65 + // nop // sll r0, r0, 0 + goto block_98; // branch always + + + block_92: + c->daddiu(v1, s7, 8); // daddiu v1, s7, #t + bc = c->sgpr64(s7) == c->sgpr64(v1); // beq s7, v1, L65 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_98;} // branch non-likely + + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + c->mov64(v1, s1); // or v1, s1, r0 + c->sw(r0, 64, at); // sw r0, 64(at) + c->sw(v1, 60, at); // sw v1, 60(at) + c->sw(r0, 72, at); // sw r0, 72(at) + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(t9, 7332, v1); // lwu t9, 7332(v1) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lwu(t9, 7340, v1); // lwu t9, 7340(v1) + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->lw(v1, 40, at); // lw v1, 40(at) + c->lw(a0, 56, at); // lw a0, 56(at) + c->mov64(a3, v1); // or a3, v1, r0 + // nop // sll r0, r0, 0 + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + c->lui(a2, 4096); // lui a2, 4096 + c->lwu(a1, 76, at); // lwu a1, 76(at) + c->ori(a2, a2, 53248); // ori a2, a2, 53248 + //c->lw(t1, 0, a2); // lw t1, 0(a2) + // nop // sll r0, r0, 0 + c->daddiu(t0, at, 108); // daddiu t0, at, 108 + c->andi(a3, a3, 16383); // andi a3, a3, 16383 + c->andi(t1, t1, 256); // andi t1, t1, 256 + // nop // sll r0, r0, 0 +// bc = c->sgpr64(t1) == 0; // beq t1, r0, L64 +// // nop // sll r0, r0, 0 +// if (bc) {goto block_97;} // branch non-likely + + c->mov64(t1, a2); // or t1, a2, r0 + // nop // sll r0, r0, 0 + +// block_95: +// c->lw(t2, 0, t0); // lw t2, 0(t0) +// // nop // sll r0, r0, 0 +// c->lw(t3, 0, t1); // lw t3, 0(t1) +// // nop // sll r0, r0, 0 +// c->andi(t3, t3, 256); // andi t3, t3, 256 +// c->daddiu(t2, t2, 1); // daddiu t2, t2, 1 +// bc = c->sgpr64(t3) != 0; // bne t3, r0, L63 +// c->sw(t2, 0, t0); // sw t2, 0(t0) +// if (bc) {goto block_95;} // branch non-likely +// +// c->gprs[t0].du64[0] = 0; // or t0, r0, r0 + + // block_97: + c->dsll(t0, a0, 4); // dsll t0, a0, 4 + // c->sw(a3, 128, a2); // sw a3, 128(a2) + sadr = c->sgpr64(a3); + // nop // sll r0, r0, 0 + // c->sw(a1, 16, a2); // sw a1, 16(a2) + madr = c->sgpr64(a1); + c->addiu(a3, r0, 256); // addiu a3, r0, 256 + // c->sw(a0, 32, a2); // sw a0, 32(a2) + qwc = c->sgpr64(a0); + c->daddu(a0, a1, t0); // daddu a0, a1, t0 + // c->sw(a3, 0, a2); // sw a3, 0(a2) + spad_from_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); + // nop // sll r0, r0, 0 + c->sw(a0, 76, at); // sw a0, 76(at) + c->gprs[a0].du64[0] = 0; // or a0, r0, r0 + c->xori(v1, v1, 4608); // xori v1, v1, 4608 + c->sw(v1, 40, at); // sw v1, 40(at) + + block_98: + c->addiu(v1, r0, 1); // addiu v1, r0, 1 + c->dsubu(gp, v1, gp); // dsubu gp, v1, gp + c->daddiu(s5, s5, 1); // daddiu s5, s5, 1 + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lhu(v1, 6818, v1); // lhu v1, 6818(v1) + bc = c->sgpr64(s5) != c->sgpr64(v1); // bne s5, v1, L66 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_100;} // branch non-likely + + c->addiu(s5, r0, 0); // addiu s5, r0, 0 + c->mov64(v1, s5); // or v1, s5, r0 + + block_100: + c->mov64(v1, s2); // or v1, s2, r0 + + block_101: + bc = c->sgpr64(s2) != 0; // bne s2, r0, L16 + // nop // sll r0, r0, 0 + if (bc) {goto block_4;} // branch non-likely + + c->mov64(v1, s7); // or v1, s7, r0 + c->load_symbol(v1, cache.merc_globals); // lw v1, *merc-globals*(s7) + c->sw(r0, 0, v1); // sw r0, 0(v1) + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + c->ld(ra, 0, sp); // ld ra, 0(sp) + c->ld(fp, 8, sp); // ld fp, 8(sp) + c->lq(gp, 256, sp); // lq gp, 256(sp) + c->lq(s5, 240, sp); // lq s5, 240(sp) + c->lq(s4, 224, sp); // lq s4, 224(sp) + c->lq(s3, 208, sp); // lq s3, 208(sp) + c->lq(s2, 192, sp); // lq s2, 192(sp) + c->lq(s1, 176, sp); // lq s1, 176(sp) + c->lq(s0, 160, sp); // lq s0, 160(sp) + //jr ra // jr ra + c->daddiu(sp, sp, 272); // daddiu sp, sp, 272 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + cache.gsf_buffer = intern_from_c("*gsf-buffer*").c(); + cache.merc_globals = intern_from_c("*merc-globals*").c(); + cache.merc_death_spawn = intern_from_c("merc-death-spawn").c(); + cache.vector_matrix = intern_from_c("vector-matrix*!").c(); + gLinkedFunctionTable.reg("generic-merc-execute-asm", execute, 1024); +} + +} // namespace generic_merc_execute_asm +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace mercneric_convert { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* +} cache; + +u8 vu0_data_mem[1024 * 4]; + +void sq_buffer(Mask mask, const Vf& data, u32 qw) { + ASSERT(qw * 16 < sizeof(vu0_data_mem)); + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + memcpy(vu0_data_mem + qw * 16 + i * 4, data.data + i, 4); + } + } +} + +void lq_buffer(Mask mask, Vf& data, u32 qw) { + ASSERT(qw * 16 < sizeof(vu0_data_mem)); + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + memcpy(data.data + i, vu0_data_mem + qw * 16 + i * 4, 4); + } + } +} + +void vcallms_280(ExecutionContext* c, u16* vis) { + bool bc; + // 0.003921569 | maxw.x vf17, vf00, vf00 :i + c->vfs[vf17].vf.max(Mask::x, c->vf_src(vf00).vf, c->vf_src(vf00).vf.w()); c->I = 0.003921569; + // -65537.0 | maxi.y vf17, vf00, I :i + c->vfs[vf17].vf.maxi(Mask::y, c->vf_src(vf00).vf, c->I); c->I = -65537.0; + // iaddiu vi10, vi10, 0x88 | minii.z vf05, vf00, I + c->vfs[vf05].vf.minii(Mask::z, c->vf_src(vf00).vf, c->I); vis[vi10] = vis[vi10] + 0x88; /* 136 */ + // iaddiu vi08, vi00, 0x8c | minii.z vf06, vf00, I + c->vfs[vf06].vf.minii(Mask::z, c->vf_src(vf00).vf, c->I); vis[vi08] = 0x8c; /* 140 */ + // sqi.xyzw vf01, vi08 | minii.z vf07, vf00, I + + c->vfs[vf07].vf.minii(Mask::z, c->vf_src(vf00).vf, c->I); sq_buffer(Mask::xyzw, c->vf_src(vf01).vf, vis[vi08]++); + // sqi.xyzw vf02, vi08 | minix.w vf05, vf00, vf27 + c->vfs[vf05].vf.mini(Mask::w, c->vf_src(vf00).vf, c->vf_src(vf27).vf.x()); sq_buffer(Mask::xyzw, c->vf_src(vf02).vf, vis[vi08]++); + // sqi.xyzw vf03, vi08 | miniy.w vf06, vf00, vf27 + c->vfs[vf06].vf.mini(Mask::w, c->vf_src(vf00).vf, c->vf_src(vf27).vf.y()); sq_buffer(Mask::xyzw, c->vf_src(vf03).vf, vis[vi08]++); + // sqi.xyzw vf04, vi08 | miniz.w vf07, vf00, vf27 + c->vfs[vf07].vf.mini(Mask::w, c->vf_src(vf00).vf, c->vf_src(vf27).vf.z()); sq_buffer(Mask::xyzw, c->vf_src(vf04).vf, vis[vi08]++); + + // BRANCH! + // ibne vi00, vi13, L1 | nop + bc = (vis[vi13] != 0); + // iaddiu vi05, vi00, 0x182 | nop + vis[vi05] = 0x182; /* 386 */ + if (bc) { goto L1; } + + // iaddiu vi05, vi00, 0x1ab | nop + vis[vi05] = 0x1ab; /* 427 */ + L1: + // BRANCH! + // ibne vi00, vi12, L2 | nop + bc = (vis[vi12] != 0); + // iaddiu vi03, vi00, 0x146 | nop + vis[vi03] = 0x146; /* 326 */ + if (bc) { goto L2; } + + // ior vi03, vi05, vi00 | nop + vis[vi03] = vis[vi05]; + L2: + // BRANCH! + // ibne vi00, vi11, L3 | nop + bc = (vis[vi11] != 0); + // iaddiu vi01, vi00, 0x13a | nop + vis[vi01] = 0x13a; /* 314 */ + if (bc) { goto L3; } + + // ior vi01, vi03, vi00 | nop + vis[vi01] = vis[vi03]; + L3: + // lqi.xyzw vf29, vi10 | nop + lq_buffer(Mask::xyzw, c->vfs[vf29].vf, vis[vi10]++); + // iadd vi02, vi08, vi11 | nop + vis[vi02] = vis[vi08] + vis[vi11]; + // iadd vi04, vi02, vi12 | nop + vis[vi04] = vis[vi02] + vis[vi12]; + // iadd vi06, vi04, vi13 | nop + vis[vi06] = vis[vi04] + vis[vi13]; + // mtir vi13, vf29.w | itof0.xyzw vf18, vf29 :e + c->vfs[vf18].vf.itof0(Mask::xyzw, c->vf_src(vf29).vf); vis[vi13] = c->vf_src(vf29).vf.w_as_u16(); + // iaddiu vi09, vi00, 0x7f | nop + vis[vi09] = 0x7f; /* 127 */ + + +} + +void vcallms_303(ExecutionContext* c, u16* vis) { + // vf21.x coming into here is bad (should be < 1, I think) + // sq.xyzw vf23, 3(vi14) | mulx.xyzw vf11, vf20, vf19 + c->vfs[vf11].vf.mul(Mask::xyzw, c->vf_src(vf20).vf, c->vf_src(vf19).vf.x()); sq_buffer(Mask::xyzw, c->vf_src(vf23).vf, vis[vi14] + 3); + // sq.xyzw vf24, 4(vi14) | mulx.xyzw vf12, vf21, vf19 + c->vfs[vf12].vf.mul(Mask::xyzw, c->vf_src(vf21).vf, c->vf_src(vf19).vf.x()); sq_buffer(Mask::xyzw, c->vf_src(vf24).vf, vis[vi14] + 4); + // sq.xyzw vf25, 5(vi14) | mulx.xyzw vf13, vf22, vf19 + c->vfs[vf13].vf.mul(Mask::xyzw, c->vf_src(vf22).vf, c->vf_src(vf19).vf.x()); sq_buffer(Mask::xyzw, c->vf_src(vf25).vf, vis[vi14] + 5); + + // sq.xyzw vf26, 6(vi14) | nop + sq_buffer(Mask::xyzw, c->vf_src(vf26).vf, vis[vi14] + 6); + // sq.xyzw vf11, 0(vi14) | nop + sq_buffer(Mask::xyzw, c->vf_src(vf11).vf, vis[vi14]); + // sq.xyzw vf12, 1(vi14) | nop + sq_buffer(Mask::xyzw, c->vf_src(vf12).vf, vis[vi14] + 1); + // sq.xyzw vf13, 2(vi14) | nop :e + sq_buffer(Mask::xyzw, c->vf_src(vf13).vf, vis[vi14] + 2); + // nop | nop + +} + +void vcallms_311(ExecutionContext* c, u16* vis) { + + // mtir vi11, vf01.x | maddz.xyzw vf11, vf26, vf10 ;; 311 + // jr vi01 | mul.xyzw vf14, vf13, Q + // sqi.xyzw vf04, vi08 | mulaw.xyzw ACC, vf20, vf08 + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + // lq.xyzw vf24, -124(vi11) | maddaw.xyzw ACC, vf22, vf10 + // lq.xyzw vf25, -123(vi11) | maddw.xyzw vf15, vf23, vf00 + + bool bc; + // mtir vi11, vf01.x | maddz.xyzw vf11, vf26, vf10 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf11].vf, c->vf_src(vf26).vf, c->vf_src(vf10).vf.z()); vis[vi11] = c->vf_src(vf01).vf.x_as_u16(); + // jr vi01 | mul.xyzw vf14, vf13, Q + c->vfs[vf14].vf.mul(Mask::xyzw, c->vf_src(vf13).vf, c->Q); + // sqi.xyzw vf04, vi08 | mulaw.xyzw ACC, vf20, vf08 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf20).vf, c->vf_src(vf08).vf.w()); sq_buffer(Mask::xyzw, c->vf_src(vf04).vf, vis[vi08]++); + + switch(vis[vi01]) { + case 314: + goto JUMP_314; + case 326: + goto JUMP_326; + case 353: + goto JUMP_353; + case 386: + goto JUMP_386; + case 427: + goto JUMP_427; + default: + fmt::print("BAD JUMP {}\n", vis[vi01]); + ASSERT(false); + } + + JUMP_314: + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf21].vf, c->vfs[vf09].vf.w()); c->Q = c->vf_src(vf00).vf.w() / std::sqrt(c->vf_src(vf16).vf.x()); + // lq.xyzw vf24, -124(vi11) | maddaw.xyzw ACC, vf22, vf10 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf22].vf, c->vfs[vf10].vf.w()); lq_buffer(Mask::xyzw, c->vfs[vf24].vf, vis[vi11] + -124); + // lq.xyzw vf25, -123(vi11) | maddw.xyzw vf15, vf23, vf00 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf15].vf, c->vf_src(vf23).vf, c->vf_src(vf00).vf.w()); lq_buffer(Mask::xyzw, c->vfs[vf25].vf, vis[vi11] + -123); +// if (c->vfs[vf15].f[0] > 100000) { +// fmt::print("likely bad vertex: {}\n", c->vfs[vf15].vf.print()); +// fmt::print(" rhs vf08: {} * {}\n", c->vfs[vf08].vf.w(), c->vfs[vf20].vf.x()); +// fmt::print(" rhs vf09: {} * {}\n", c->vfs[vf09].vf.w(), c->vfs[vf21].vf.x()); +// fmt::print(" rhs vf10: {} * {}\n", c->vfs[vf10].vf.w(), c->vfs[vf22].vf.x()); +// fmt::print(" rhs vf00: 1 * {}\n", c->vfs[vf22].vf.x()); +// +// fmt::print(" vf16.x was {}\n", c->vf_src(vf16).vf.x()); +// } + + // lq.xyzw vf26, -122(vi11) | mul.xyzw vf16, vf11, vf11 + c->vfs[vf16].vf.mul(Mask::xyzw, c->vf_src(vf11).vf, c->vf_src(vf11).vf); lq_buffer(Mask::xyzw, c->vfs[vf26].vf, vis[vi11] + -122); + // lq.xyzw vf20, -128(vi11) | add.xyzw vf08, vf01, vf05 + c->vfs[vf08].vf.add(Mask::xyzw, c->vf_src(vf01).vf, c->vf_src(vf05).vf); lq_buffer(Mask::xyzw, c->vfs[vf20].vf, vis[vi11] + -128); + // lq.xyzw vf21, -127(vi11) | add.xyzw vf09, vf02, vf06 + c->vfs[vf09].vf.add(Mask::xyzw, c->vf_src(vf02).vf, c->vf_src(vf06).vf); lq_buffer(Mask::xyzw, c->vfs[vf21].vf, vis[vi11] + -127); + // lq.xyzw vf22, -126(vi11) | add.xyzw vf10, vf03, vf07 + c->vfs[vf10].vf.add(Mask::xyzw, c->vf_src(vf03).vf, c->vf_src(vf07).vf); lq_buffer(Mask::xyzw, c->vfs[vf22].vf, vis[vi11] + -126); + // BRANCH! + // ibne vi08, vi02, L4 | adday.xyzw vf16, vf16 + c->acc.vf.adda(Mask::xyzw, c->vfs[vf16].vf, c->vfs[vf16].vf.y()); bc = (vis[vi08] != vis[vi02]); + // lq.xyzw vf23, -125(vi11) | maddz.xyzw vf16, vf17, vf16 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf16].vf, c->vf_src(vf17).vf, c->vf_src(vf16).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf23].vf, vis[vi11] + -125); + if (bc) { goto L4; } + + // ior vi01, vi03, vi00 | nop + vis[vi01] = vis[vi03]; + L4: + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf24).vf, c->vf_src(vf08).vf.z()); c->vfs[vf13].vf.move(Mask::xyzw, c->vf_src(vf12).vf); + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf25].vf, c->vfs[vf09].vf.z()); c->vfs[vf12].vf.move(Mask::xyzw, c->vf_src(vf11).vf); + return; + JUMP_326: + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf21].vf, c->vfs[vf09].vf.w()); c->Q = c->vf_src(vf00).vf.w() / std::sqrt(c->vf_src(vf16).vf.x()); + // mtir vi12, vf01.y | maddaw.xyzw ACC, vf22, vf10 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf22].vf, c->vfs[vf10].vf.w()); vis[vi12] = c->vf_src(vf01).vf.y_as_u16(); + // iand vi11, vi11, vi09 | maddw.xyzw vf15, vf23, vf00 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf15].vf, c->vf_src(vf23).vf, c->vf_src(vf00).vf.w()); vis[vi11] = vis[vi11] & vis[vi09]; + // lq.xyzw vf19, 4(vi11) | mul.xyzw vf16, vf11, vf11 + c->vfs[vf16].vf.mul(Mask::xyzw, c->vf_src(vf11).vf, c->vf_src(vf11).vf); lq_buffer(Mask::xyzw, c->vfs[vf19].vf, vis[vi11] + 4); + // BRANCH! + // ibeq vi09, vi11, L7 | add.xyzw vf08, vf01, vf05 + c->vfs[vf08].vf.add(Mask::xyzw, c->vf_src(vf01).vf, c->vf_src(vf05).vf); bc = (vis[vi09] == vis[vi11]); + // iand vi12, vi12, vi09 | add.xyzw vf09, vf02, vf06 + c->vfs[vf09].vf.add(Mask::xyzw, c->vf_src(vf02).vf, c->vf_src(vf06).vf); vis[vi12] = vis[vi12] & vis[vi09]; + if (bc) { goto L7; } + + // nop | muly.xyzw vf18, vf18, vf17 + c->vfs[vf18].vf.mul(Mask::xyzw, c->vf_src(vf18).vf, c->vf_src(vf17).vf.y()); + // lq.xyzw vf24, 4(vi12) | add.xyzw vf10, vf03, vf07 + c->vfs[vf10].vf.add(Mask::xyzw, c->vf_src(vf03).vf, c->vf_src(vf07).vf); lq_buffer(Mask::xyzw, c->vfs[vf24].vf, vis[vi12] + 4); + // lq.xyzw vf27, 5(vi11) | adday.xyzw vf16, vf16 + c->acc.vf.adda(Mask::xyzw, c->vfs[vf16].vf, c->vfs[vf16].vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf27].vf, vis[vi11] + 5); + // lq.xyzw vf25, 5(vi12) | maddz.xyzw vf16, vf17, vf16 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf16].vf, c->vf_src(vf17).vf, c->vf_src(vf16).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf25].vf, vis[vi12] + 5); + // lq.xyzw vf28, 6(vi11) | mulax.xyzw ACC, vf19, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf19).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf28].vf, vis[vi11] + 6); + // lq.xyzw vf26, 6(vi12) | maddy.xyzw vf24, vf24, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf24].vf, c->vf_src(vf24).vf, c->vf_src(vf18).vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf26].vf, vis[vi12] + 6); + // lq.xyzw vf29, 0(vi11) | mulax.xyzw ACC, vf27, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf27).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf29].vf, vis[vi11]); + // lq.xyzw vf20, 0(vi12) | maddy.xyzw vf25, vf25, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf25].vf, c->vf_src(vf25).vf, c->vf_src(vf18).vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf20].vf, vis[vi12]); + // lq.xyzw vf19, 1(vi11) | mulax.xyzw ACC, vf28, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf28).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf19].vf, vis[vi11] + 1); + // lq.xyzw vf21, 1(vi12) | maddy.xyzw vf26, vf26, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf26].vf, c->vf_src(vf26).vf, c->vf_src(vf18).vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf21].vf, vis[vi12] + 1); + // lq.xyzw vf27, 2(vi11) | mulax.xyzw ACC, vf29, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf29).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf27].vf, vis[vi11] + 2); + // lq.xyzw vf22, 2(vi12) | maddy.xyzw vf20, vf20, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf20].vf, c->vf_src(vf20).vf, c->vf_src(vf18).vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf22].vf, vis[vi12] + 2); + // lq.xyzw vf28, 3(vi11) | mulax.xyzw ACC, vf19, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf19).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf28].vf, vis[vi11] + 3); + // lq.xyzw vf23, 3(vi12) | maddy.xyzw vf21, vf21, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf21].vf, c->vf_src(vf21).vf, c->vf_src(vf18).vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf23].vf, vis[vi12] + 3); + // nop | mulax.xyzw ACC, vf27, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf27).vf, c->vf_src(vf18).vf.x()); + // iaddiu vi01, vi00, 0x161 | maddy.xyzw vf22, vf22, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf22].vf, c->vf_src(vf22).vf, c->vf_src(vf18).vf.y()); vis[vi01] = 0x161; /* 353 */ + // BRANCH! + // ibne vi08, vi04, L5 | mulax.xyzw ACC, vf28, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf28).vf, c->vf_src(vf18).vf.x()); bc = (vis[vi08] != vis[vi04]); + // nop | maddy.xyzw vf23, vf23, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf23].vf, c->vf_src(vf23).vf, c->vf_src(vf18).vf.y()); + if (bc) { goto L5; } + + // ior vi01, vi05, vi00 | nop + vis[vi01] = vis[vi05]; + L5: + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf24).vf, c->vf_src(vf08).vf.z()); c->vfs[vf13].vf.move(Mask::xyzw, c->vf_src(vf12).vf); + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf25].vf, c->vfs[vf09].vf.z()); c->vfs[vf12].vf.move(Mask::xyzw, c->vf_src(vf11).vf); + return; + JUMP_353: + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf21].vf, c->vfs[vf09].vf.w()); c->Q = c->vf_src(vf00).vf.w() / std::sqrt(c->vf_src(vf16).vf.x()); + // mtir vi12, vf01.y | maddaw.xyzw ACC, vf22, vf10 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf22].vf, c->vfs[vf10].vf.w()); vis[vi12] = c->vf_src(vf01).vf.y_as_u16(); + // iand vi11, vi11, vi09 | maddw.xyzw vf15, vf23, vf00 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf15].vf, c->vf_src(vf23).vf, c->vf_src(vf00).vf.w()); vis[vi11] = vis[vi11] & vis[vi09]; + // lq.xyzw vf19, 4(vi11) | mul.xyzw vf16, vf11, vf11 + c->vfs[vf16].vf.mul(Mask::xyzw, c->vf_src(vf11).vf, c->vf_src(vf11).vf); lq_buffer(Mask::xyzw, c->vfs[vf19].vf, vis[vi11] + 4); + // BRANCH! + // ibeq vi09, vi11, L7 | add.xyzw vf08, vf01, vf05 + c->vfs[vf08].vf.add(Mask::xyzw, c->vf_src(vf01).vf, c->vf_src(vf05).vf); bc = (vis[vi09] == vis[vi11]); + // iand vi12, vi12, vi09 | add.xyzw vf09, vf02, vf06 + c->vfs[vf09].vf.add(Mask::xyzw, c->vf_src(vf02).vf, c->vf_src(vf06).vf); vis[vi12] = vis[vi12] & vis[vi09]; + if (bc) { goto L7; } + + // lq.xyzw vf24, 4(vi12) | add.xyzw vf10, vf03, vf07 + c->vfs[vf10].vf.add(Mask::xyzw, c->vf_src(vf03).vf, c->vf_src(vf07).vf); lq_buffer(Mask::xyzw, c->vfs[vf24].vf, vis[vi12] + 4); + // lq.xyzw vf27, 5(vi11) | adday.xyzw vf16, vf16 + c->acc.vf.adda(Mask::xyzw, c->vfs[vf16].vf, c->vfs[vf16].vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf27].vf, vis[vi11] + 5); + // lq.xyzw vf25, 5(vi12) | maddz.xyzw vf16, vf17, vf16 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf16].vf, c->vf_src(vf17).vf, c->vf_src(vf16).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf25].vf, vis[vi12] + 5); + // lq.xyzw vf28, 6(vi11) | mulaz.xyzw ACC, vf19, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf19).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf28].vf, vis[vi11] + 6); + // lq.xyzw vf26, 6(vi12) | maddw.xyzw vf24, vf24, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf24].vf, c->vf_src(vf24).vf, c->vf_src(vf18).vf.w()); lq_buffer(Mask::xyzw, c->vfs[vf26].vf, vis[vi12] + 6); + // lq.xyzw vf29, 0(vi11) | mulaz.xyzw ACC, vf27, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf27).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf29].vf, vis[vi11]); + // lq.xyzw vf20, 0(vi12) | maddw.xyzw vf25, vf25, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf25].vf, c->vf_src(vf25).vf, c->vf_src(vf18).vf.w()); lq_buffer(Mask::xyzw, c->vfs[vf20].vf, vis[vi12]); + // lq.xyzw vf19, 1(vi11) | mulaz.xyzw ACC, vf28, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf28).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf19].vf, vis[vi11] + 1); + // lq.xyzw vf21, 1(vi12) | maddw.xyzw vf26, vf26, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf26].vf, c->vf_src(vf26).vf, c->vf_src(vf18).vf.w()); lq_buffer(Mask::xyzw, c->vfs[vf21].vf, vis[vi12] + 1); + // lq.xyzw vf27, 2(vi11) | mulaz.xyzw ACC, vf29, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf29).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf27].vf, vis[vi11] + 2); + // lq.xyzw vf22, 2(vi12) | maddw.xyzw vf20, vf20, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf20].vf, c->vf_src(vf20).vf, c->vf_src(vf18).vf.w()); lq_buffer(Mask::xyzw, c->vfs[vf22].vf, vis[vi12] + 2); + // lq.xyzw vf28, 3(vi11) | mulaz.xyzw ACC, vf19, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf19).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf28].vf, vis[vi11] + 3); + // lq.xyzw vf23, 3(vi12) | maddw.xyzw vf21, vf21, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf21].vf, c->vf_src(vf21).vf, c->vf_src(vf18).vf.w()); lq_buffer(Mask::xyzw, c->vfs[vf23].vf, vis[vi12] + 3); + // lqi.xyzw vf29, vi10 | mulaz.xyzw ACC, vf27, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf27).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf29].vf, vis[vi10]++); + // iaddiu vi01, vi00, 0x146 | maddw.xyzw vf22, vf22, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf22].vf, c->vf_src(vf22).vf, c->vf_src(vf18).vf.w()); vis[vi01] = 0x146; /* 326 */ + // BRANCH! + // ibne vi08, vi04, L6 | mulaz.xyzw ACC, vf28, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf28).vf, c->vf_src(vf18).vf.z()); bc = (vis[vi08] != vis[vi04]); + // nop | maddw.xyzw vf23, vf23, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf23].vf, c->vf_src(vf23).vf, c->vf_src(vf18).vf.w()); + if (bc) { goto L6; } + + // ior vi01, vi05, vi00 | nop + vis[vi01] = vis[vi05]; + L6: + // mtir vi13, vf29.w | itof0.xyzw vf18, vf29 + c->vfs[vf18].vf.itof0(Mask::xyzw, c->vf_src(vf29).vf); vis[vi13] = c->vf_src(vf29).vf.w_as_u16(); + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf24).vf, c->vf_src(vf08).vf.z()); c->vfs[vf13].vf.move(Mask::xyzw, c->vf_src(vf12).vf); + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf25].vf, c->vfs[vf09].vf.z()); c->vfs[vf12].vf.move(Mask::xyzw, c->vf_src(vf11).vf); + return; + L7: + // nop | add.xyzw vf10, vf03, vf07 + c->vfs[vf10].vf.add(Mask::xyzw, c->vf_src(vf03).vf, c->vf_src(vf07).vf); + // BRANCH! + // ibne vi08, vi04, L8 | adday.xyzw vf16, vf16 + c->acc.vf.adda(Mask::xyzw, c->vfs[vf16].vf, c->vfs[vf16].vf.y()); bc = (vis[vi08] != vis[vi04]); + // nop | maddz.xyzw vf16, vf17, vf16 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf16].vf, c->vf_src(vf17).vf, c->vf_src(vf16).vf.z()); + if (bc) { goto L8; } + + // ior vi01, vi05, vi00 | nop + vis[vi01] = vis[vi05]; + L8: + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf24).vf, c->vf_src(vf08).vf.z()); c->vfs[vf13].vf.move(Mask::xyzw, c->vf_src(vf12).vf); + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf25].vf, c->vfs[vf09].vf.z()); c->vfs[vf12].vf.move(Mask::xyzw, c->vf_src(vf11).vf); + return; + JUMP_386: + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf21].vf, c->vfs[vf09].vf.w()); c->Q = c->vf_src(vf00).vf.w() / std::sqrt(c->vf_src(vf16).vf.x()); + // mtir vi12, vf01.y | maddaw.xyzw ACC, vf22, vf10 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf22].vf, c->vfs[vf10].vf.w()); vis[vi12] = c->vf_src(vf01).vf.y_as_u16(); + // iand vi11, vi11, vi09 | maddw.xyzw vf15, vf23, vf00 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf15].vf, c->vf_src(vf23).vf, c->vf_src(vf00).vf.w()); vis[vi11] = vis[vi11] & vis[vi09]; + // lq.xyzw vf19, 4(vi11) | mul.xyzw vf16, vf11, vf11 + c->vfs[vf16].vf.mul(Mask::xyzw, c->vf_src(vf11).vf, c->vf_src(vf11).vf); lq_buffer(Mask::xyzw, c->vfs[vf19].vf, vis[vi11] + 4); + // BRANCH! + // ibeq vi09, vi11, L10 | add.xyzw vf08, vf01, vf05 + c->vfs[vf08].vf.add(Mask::xyzw, c->vf_src(vf01).vf, c->vf_src(vf05).vf); bc = (vis[vi09] == vis[vi11]); + // iand vi12, vi12, vi09 | add.xyzw vf09, vf02, vf06 + c->vfs[vf09].vf.add(Mask::xyzw, c->vf_src(vf02).vf, c->vf_src(vf06).vf); vis[vi12] = vis[vi12] & vis[vi09]; + if (bc) { goto L10; } + + // nop | muly.xyzw vf18, vf18, vf17 + c->vfs[vf18].vf.mul(Mask::xyzw, c->vf_src(vf18).vf, c->vf_src(vf17).vf.y()); + // lq.xyzw vf27, 4(vi12) | add.xyzw vf10, vf03, vf07 + c->vfs[vf10].vf.add(Mask::xyzw, c->vf_src(vf03).vf, c->vf_src(vf07).vf); lq_buffer(Mask::xyzw, c->vfs[vf27].vf, vis[vi12] + 4); + // lq.xyzw vf24, 4(vi13) | adday.xyzw vf16, vf16 + c->acc.vf.adda(Mask::xyzw, c->vfs[vf16].vf, c->vfs[vf16].vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf24].vf, vis[vi13] + 4); + // lq.xyzw vf28, 5(vi11) | maddz.xyzw vf16, vf17, vf16 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf16].vf, c->vf_src(vf17).vf, c->vf_src(vf16).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf28].vf, vis[vi11] + 5); + // lq.xyzw vf19, 5(vi12) | mulax.xyzw ACC, vf19, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf19).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf19].vf, vis[vi12] + 5); + // lq.xyzw vf25, 5(vi13) | madday.xyzw ACC, vf27, vf18 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf27].vf, c->vfs[vf18].vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf25].vf, vis[vi13] + 5); + // lq.xyzw vf27, 6(vi11) | maddz.xyzw vf24, vf24, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf24].vf, c->vf_src(vf24).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf27].vf, vis[vi11] + 6); + // lq.xyzw vf28, 6(vi12) | mulax.xyzw ACC, vf28, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf28).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf28].vf, vis[vi12] + 6); + // lq.xyzw vf26, 6(vi13) | madday.xyzw ACC, vf19, vf18 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf19].vf, c->vfs[vf18].vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf26].vf, vis[vi13] + 6); + // lq.xyzw vf19, 0(vi11) | maddz.xyzw vf25, vf25, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf25].vf, c->vf_src(vf25).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf19].vf, vis[vi11]); + // lq.xyzw vf27, 0(vi12) | mulax.xyzw ACC, vf27, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf27).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf27].vf, vis[vi12]); + // lq.xyzw vf20, 0(vi13) | madday.xyzw ACC, vf28, vf18 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf28].vf, c->vfs[vf18].vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf20].vf, vis[vi13]); + // lq.xyzw vf28, 1(vi11) | maddz.xyzw vf26, vf26, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf26].vf, c->vf_src(vf26).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf28].vf, vis[vi11] + 1); + // lq.xyzw vf19, 1(vi12) | mulax.xyzw ACC, vf19, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf19).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf19].vf, vis[vi12] + 1); + // lq.xyzw vf21, 1(vi13) | madday.xyzw ACC, vf27, vf18 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf27].vf, c->vfs[vf18].vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf21].vf, vis[vi13] + 1); + // lq.xyzw vf27, 2(vi11) | maddz.xyzw vf20, vf20, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf20].vf, c->vf_src(vf20).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf27].vf, vis[vi11] + 2); + // lq.xyzw vf28, 2(vi12) | mulax.xyzw ACC, vf28, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf28).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf28].vf, vis[vi12] + 2); + // lq.xyzw vf22, 2(vi13) | madday.xyzw ACC, vf19, vf18 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf19].vf, c->vfs[vf18].vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf22].vf, vis[vi13] + 2); + // lq.xyzw vf19, 3(vi11) | maddz.xyzw vf21, vf21, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf21].vf, c->vf_src(vf21).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf19].vf, vis[vi11] + 3); + // lq.xyzw vf27, 3(vi12) | mulax.xyzw ACC, vf27, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf27).vf, c->vf_src(vf18).vf.x()); lq_buffer(Mask::xyzw, c->vfs[vf27].vf, vis[vi12] + 3); + // lq.xyzw vf23, 3(vi13) | madday.xyzw ACC, vf28, vf18 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf28].vf, c->vfs[vf18].vf.y()); lq_buffer(Mask::xyzw, c->vfs[vf23].vf, vis[vi13] + 3); + // lqi.xyzw vf29, vi10 | maddz.xyzw vf22, vf22, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf22].vf, c->vf_src(vf22).vf, c->vf_src(vf18).vf.z()); lq_buffer(Mask::xyzw, c->vfs[vf29].vf, vis[vi10]++); + // BRANCH! + // ibne vi08, vi06, L9 | mulax.xyzw ACC, vf19, vf18 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf19).vf, c->vf_src(vf18).vf.x()); bc = (vis[vi08] != vis[vi06]); + // nop | madday.xyzw ACC, vf27, vf18 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf27].vf, c->vfs[vf18].vf.y()); + if (bc) { goto L9; } + + // iaddiu vi01, vi00, 0x1ab | nop + vis[vi01] = 0x1ab; /* 427 */ + L9: + // nop | maddz.xyzw vf23, vf23, vf18 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf23].vf, c->vf_src(vf23).vf, c->vf_src(vf18).vf.z()); + // mtir vi13, vf29.w | itof0.xyz vf18, vf29 + c->vfs[vf18].vf.itof0(Mask::xyz, c->vf_src(vf29).vf); vis[vi13] = c->vf_src(vf29).vf.w_as_u16(); + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf24).vf, c->vf_src(vf08).vf.z()); c->vfs[vf13].vf.move(Mask::xyzw, c->vf_src(vf12).vf); + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf25].vf, c->vfs[vf09].vf.z()); c->vfs[vf12].vf.move(Mask::xyzw, c->vf_src(vf11).vf); + return; + L10: + // nop | add.xyzw vf10, vf03, vf07 + c->vfs[vf10].vf.add(Mask::xyzw, c->vf_src(vf03).vf, c->vf_src(vf07).vf); + // BRANCH! + // ibne vi08, vi06, L11 | adday.xyzw vf16, vf16 + c->acc.vf.adda(Mask::xyzw, c->vfs[vf16].vf, c->vfs[vf16].vf.y()); bc = (vis[vi08] != vis[vi06]); + // nop | maddz.xyzw vf16, vf17, vf16 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf16].vf, c->vf_src(vf17).vf, c->vf_src(vf16).vf.z()); + if (bc) { goto L11; } + + // iaddiu vi01, vi00, 0x1ab | nop + vis[vi01] = 0x1ab; /* 427 */ + L11: + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf24).vf, c->vf_src(vf08).vf.z()); c->vfs[vf13].vf.move(Mask::xyzw, c->vf_src(vf12).vf); + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf25].vf, c->vfs[vf09].vf.z()); c->vfs[vf12].vf.move(Mask::xyzw, c->vf_src(vf11).vf); + return; + JUMP_427: + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf21].vf, c->vfs[vf09].vf.w()); c->Q = c->vf_src(vf00).vf.w() / std::sqrt(c->vf_src(vf16).vf.x()); + // nop | maddaw.xyzw ACC, vf22, vf10 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf22].vf, c->vfs[vf10].vf.w()); + // nop | maddw.xyzw vf15, vf23, vf00 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf15].vf, c->vf_src(vf23).vf, c->vf_src(vf00).vf.w()); + // nop | mul.xyzw vf16, vf11, vf11 + c->vfs[vf16].vf.mul(Mask::xyzw, c->vf_src(vf11).vf, c->vf_src(vf11).vf); + // nop | add.xyzw vf08, vf01, vf05 + c->vfs[vf08].vf.add(Mask::xyzw, c->vf_src(vf01).vf, c->vf_src(vf05).vf); + // nop | add.xyzw vf09, vf02, vf06 + c->vfs[vf09].vf.add(Mask::xyzw, c->vf_src(vf02).vf, c->vf_src(vf06).vf); + // nop | add.xyzw vf10, vf03, vf07 + c->vfs[vf10].vf.add(Mask::xyzw, c->vf_src(vf03).vf, c->vf_src(vf07).vf); + // nop | adday.xyzw vf16, vf16 + c->acc.vf.adda(Mask::xyzw, c->vfs[vf16].vf, c->vfs[vf16].vf.y()); + // nop | maddz.xyzw vf16, vf17, vf16 + c->acc.vf.madd(Mask::xyzw, c->vfs[vf16].vf, c->vf_src(vf17).vf, c->vf_src(vf16).vf.z()); + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf24).vf, c->vf_src(vf08).vf.z()); c->vfs[vf13].vf.move(Mask::xyzw, c->vf_src(vf12).vf); + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf25].vf, c->vfs[vf09].vf.z()); c->vfs[vf12].vf.move(Mask::xyzw, c->vf_src(vf11).vf); + return; + // nop | mulaz.xyzw ACC, vf09, vf01 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf01).vf.z()); + // nop | maddax.xyzw ACC, vf10, vf01 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf01].vf.x()); + // nop | maddy.xyzw vf01, vf11, vf01 + u16 f1 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf01].vf, c->vf_src(vf11).vf, c->vf_src(vf01).vf.y()); + // nop | mulaz.xyzw ACC, vf09, vf02 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf02).vf.z()); + // nop | maddax.xyzw ACC, vf10, vf02 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf02].vf.x()); + // nop | maddy.xyzw vf02, vf11, vf02 + u16 f2 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf02].vf, c->vf_src(vf11).vf, c->vf_src(vf02).vf.y()); + // fmand vi01, vi09 | mulaz.xyzw ACC, vf09, vf03 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf03).vf.z()); vis[vi01] = f1 & vis[vi09]; + // nop | maddax.xyzw ACC, vf10, vf03 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf03].vf.x()); + // nop | maddy.xyzw vf03, vf11, vf03 + u16 f3 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf03].vf, c->vf_src(vf11).vf, c->vf_src(vf03).vf.y()); + // fmand vi02, vi09 | mulaz.xyzw ACC, vf09, vf04 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf04).vf.z()); vis[vi02] = f2 & vis[vi09]; + // nop | maddax.xyzw ACC, vf10, vf04 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf04].vf.x()); + // nop | maddy.xyzw vf04, vf11, vf04 + u16 f4 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf04].vf, c->vf_src(vf11).vf, c->vf_src(vf04).vf.y()); + // fmand vi03, vi09 | nop + vis[vi03] = f3 & vis[vi09]; + // nop | nop + + // nop | nop :e + + // fmand vi04, vi09 | nop + vis[vi04] = f4 & vis[vi09]; + return; + + // nop | mulaz.xyzw ACC, vf09, vf05 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf05).vf.z()); + // nop | maddax.xyzw ACC, vf10, vf05 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf05].vf.x()); + // nop | maddy.xyzw vf05, vf11, vf05 + u16 f5 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf05].vf, c->vf_src(vf11).vf, c->vf_src(vf05).vf.y()); + // nop | mulaz.xyzw ACC, vf09, vf06 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf06).vf.z()); + // nop | maddax.xyzw ACC, vf10, vf06 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf06].vf.x()); + // nop | maddy.xyzw vf06, vf11, vf06 + u16 f6 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf06].vf, c->vf_src(vf11).vf, c->vf_src(vf06).vf.y()); + // fmand vi05, vi09 | mulaz.xyzw ACC, vf09, vf07 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf07).vf.z()); vis[vi05] = f5 & vis[vi09]; + // nop | maddax.xyzw ACC, vf10, vf07 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf07].vf.x()); + // nop | maddy.xyzw vf07, vf11, vf07 + u16 f7 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf07].vf, c->vf_src(vf11).vf, c->vf_src(vf07).vf.y()); + // fmand vi06, vi09 | mulaz.xyzw ACC, vf09, vf08 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf08).vf.z()); vis[vi06] = f6 & vis[vi09]; + // nop | maddax.xyzw ACC, vf10, vf08 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf08].vf.x()); + // nop | maddy.xyzw vf08, vf11, vf08 + u16 f8 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf08].vf, c->vf_src(vf11).vf, c->vf_src(vf08).vf.y()); + // fmand vi07, vi09 | nop + vis[vi07] = f7 & vis[vi09]; + // nop | nop + + // nop | nop :e + + // fmand vi08, vi09 | nop + vis[vi08] = f8 & vis[vi09]; + return; + + + + + // mtir vi11, vf01.x | maddz.xyzw vf11, vf26, vf10 ;; 311 + // jr vi01 | mul.xyzw vf14, vf13, Q + // sqi.xyzw vf04, vi08 | mulaw.xyzw ACC, vf20, vf08 + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + // lq.xyzw vf24, -124(vi11) | maddaw.xyzw ACC, vf22, vf10 + // lq.xyzw vf25, -123(vi11) | maddw.xyzw vf15, vf23, vf00 + // lq.xyzw vf26, -122(vi11) | mul.xyzw vf16, vf11, vf11 + // lq.xyzw vf20, -128(vi11) | add.xyzw vf08, vf01, vf05 + // lq.xyzw vf21, -127(vi11) | add.xyzw vf09, vf02, vf06 + // lq.xyzw vf22, -126(vi11) | add.xyzw vf10, vf03, vf07 + // ibne vi08, vi02, L4 | adday.xyzw vf16, vf16 + // lq.xyzw vf23, -125(vi11) | maddz.xyzw vf16, vf17, vf16 + // ior vi01, vi03, vi00 | nop + // L4: + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + // mtir vi12, vf01.y | maddaw.xyzw ACC, vf22, vf10 + // iand vi11, vi11, vi09 | maddw.xyzw vf15, vf23, vf00 + // lq.xyzw vf19, 4(vi11) | mul.xyzw vf16, vf11, vf11 + // ibeq vi09, vi11, L7 | add.xyzw vf08, vf01, vf05 + // iand vi12, vi12, vi09 | add.xyzw vf09, vf02, vf06 + // nop | muly.xyzw vf18, vf18, vf17 + // lq.xyzw vf24, 4(vi12) | add.xyzw vf10, vf03, vf07 + // lq.xyzw vf27, 5(vi11) | adday.xyzw vf16, vf16 + // lq.xyzw vf25, 5(vi12) | maddz.xyzw vf16, vf17, vf16 + // lq.xyzw vf28, 6(vi11) | mulax.xyzw ACC, vf19, vf18 + // lq.xyzw vf26, 6(vi12) | maddy.xyzw vf24, vf24, vf18 + // lq.xyzw vf29, 0(vi11) | mulax.xyzw ACC, vf27, vf18 + // lq.xyzw vf20, 0(vi12) | maddy.xyzw vf25, vf25, vf18 + // lq.xyzw vf19, 1(vi11) | mulax.xyzw ACC, vf28, vf18 + // lq.xyzw vf21, 1(vi12) | maddy.xyzw vf26, vf26, vf18 + // lq.xyzw vf27, 2(vi11) | mulax.xyzw ACC, vf29, vf18 + // lq.xyzw vf22, 2(vi12) | maddy.xyzw vf20, vf20, vf18 + // lq.xyzw vf28, 3(vi11) | mulax.xyzw ACC, vf19, vf18 + // lq.xyzw vf23, 3(vi12) | maddy.xyzw vf21, vf21, vf18 + // nop | mulax.xyzw ACC, vf27, vf18 + // iaddiu vi01, vi00, 0x161 | maddy.xyzw vf22, vf22, vf18 + // ibne vi08, vi04, L5 | mulax.xyzw ACC, vf28, vf18 + // nop | maddy.xyzw vf23, vf23, vf18 + // ior vi01, vi05, vi00 | nop + // L5: + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + // mtir vi12, vf01.y | maddaw.xyzw ACC, vf22, vf10 + // iand vi11, vi11, vi09 | maddw.xyzw vf15, vf23, vf00 + // lq.xyzw vf19, 4(vi11) | mul.xyzw vf16, vf11, vf11 + // ibeq vi09, vi11, L7 | add.xyzw vf08, vf01, vf05 + // iand vi12, vi12, vi09 | add.xyzw vf09, vf02, vf06 + // lq.xyzw vf24, 4(vi12) | add.xyzw vf10, vf03, vf07 + // lq.xyzw vf27, 5(vi11) | adday.xyzw vf16, vf16 + // lq.xyzw vf25, 5(vi12) | maddz.xyzw vf16, vf17, vf16 + // lq.xyzw vf28, 6(vi11) | mulaz.xyzw ACC, vf19, vf18 + // lq.xyzw vf26, 6(vi12) | maddw.xyzw vf24, vf24, vf18 + // lq.xyzw vf29, 0(vi11) | mulaz.xyzw ACC, vf27, vf18 + // lq.xyzw vf20, 0(vi12) | maddw.xyzw vf25, vf25, vf18 + // lq.xyzw vf19, 1(vi11) | mulaz.xyzw ACC, vf28, vf18 + // lq.xyzw vf21, 1(vi12) | maddw.xyzw vf26, vf26, vf18 + // lq.xyzw vf27, 2(vi11) | mulaz.xyzw ACC, vf29, vf18 + // lq.xyzw vf22, 2(vi12) | maddw.xyzw vf20, vf20, vf18 + // lq.xyzw vf28, 3(vi11) | mulaz.xyzw ACC, vf19, vf18 + // lq.xyzw vf23, 3(vi12) | maddw.xyzw vf21, vf21, vf18 + // lqi.xyzw vf29, vi10 | mulaz.xyzw ACC, vf27, vf18 + // iaddiu vi01, vi00, 0x146 | maddw.xyzw vf22, vf22, vf18 + // ibne vi08, vi04, L6 | mulaz.xyzw ACC, vf28, vf18 + // nop | maddw.xyzw vf23, vf23, vf18 + // ior vi01, vi05, vi00 | nop + // L6: + // mtir vi13, vf29.w | itof0.xyzw vf18, vf29 + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + // L7: + // nop | add.xyzw vf10, vf03, vf07 + // ibne vi08, vi04, L8 | adday.xyzw vf16, vf16 + // nop | maddz.xyzw vf16, vf17, vf16 + // ior vi01, vi05, vi00 | nop + // L8: + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + // mtir vi12, vf01.y | maddaw.xyzw ACC, vf22, vf10 + // iand vi11, vi11, vi09 | maddw.xyzw vf15, vf23, vf00 + // lq.xyzw vf19, 4(vi11) | mul.xyzw vf16, vf11, vf11 + // ibeq vi09, vi11, L10 | add.xyzw vf08, vf01, vf05 + // iand vi12, vi12, vi09 | add.xyzw vf09, vf02, vf06 + // nop | muly.xyzw vf18, vf18, vf17 + // lq.xyzw vf27, 4(vi12) | add.xyzw vf10, vf03, vf07 + // lq.xyzw vf24, 4(vi13) | adday.xyzw vf16, vf16 + // lq.xyzw vf28, 5(vi11) | maddz.xyzw vf16, vf17, vf16 + // lq.xyzw vf19, 5(vi12) | mulax.xyzw ACC, vf19, vf18 + // lq.xyzw vf25, 5(vi13) | madday.xyzw ACC, vf27, vf18 + // lq.xyzw vf27, 6(vi11) | maddz.xyzw vf24, vf24, vf18 + // lq.xyzw vf28, 6(vi12) | mulax.xyzw ACC, vf28, vf18 + // lq.xyzw vf26, 6(vi13) | madday.xyzw ACC, vf19, vf18 + // lq.xyzw vf19, 0(vi11) | maddz.xyzw vf25, vf25, vf18 + // lq.xyzw vf27, 0(vi12) | mulax.xyzw ACC, vf27, vf18 + // lq.xyzw vf20, 0(vi13) | madday.xyzw ACC, vf28, vf18 + // lq.xyzw vf28, 1(vi11) | maddz.xyzw vf26, vf26, vf18 + // lq.xyzw vf19, 1(vi12) | mulax.xyzw ACC, vf19, vf18 + // lq.xyzw vf21, 1(vi13) | madday.xyzw ACC, vf27, vf18 + // lq.xyzw vf27, 2(vi11) | maddz.xyzw vf20, vf20, vf18 + // lq.xyzw vf28, 2(vi12) | mulax.xyzw ACC, vf28, vf18 + // lq.xyzw vf22, 2(vi13) | madday.xyzw ACC, vf19, vf18 + // lq.xyzw vf19, 3(vi11) | maddz.xyzw vf21, vf21, vf18 + // lq.xyzw vf27, 3(vi12) | mulax.xyzw ACC, vf27, vf18 + // lq.xyzw vf23, 3(vi13) | madday.xyzw ACC, vf28, vf18 + // lqi.xyzw vf29, vi10 | maddz.xyzw vf22, vf22, vf18 + // ibne vi08, vi06, L9 | mulax.xyzw ACC, vf19, vf18 + // nop | madday.xyzw ACC, vf27, vf18 + // iaddiu vi01, vi00, 0x1ab | nop + // L9: + // nop | maddz.xyzw vf23, vf23, vf18 + // mtir vi13, vf29.w | itof0.xyz vf18, vf29 + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + // L10: + // nop | add.xyzw vf10, vf03, vf07 + // ibne vi08, vi06, L11 | adday.xyzw vf16, vf16 + // nop | maddz.xyzw vf16, vf17, vf16 + // iaddiu vi01, vi00, 0x1ab | nop + // L11: + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + // rsqrt Q, vf00.w, vf16.x | maddaw.xyzw ACC, vf21, vf09 + // nop | maddaw.xyzw ACC, vf22, vf10 + // nop | maddw.xyzw vf15, vf23, vf00 + // nop | mul.xyzw vf16, vf11, vf11 + // nop | add.xyzw vf08, vf01, vf05 + // nop | add.xyzw vf09, vf02, vf06 + // nop | add.xyzw vf10, vf03, vf07 + // nop | adday.xyzw vf16, vf16 + // nop | maddz.xyzw vf16, vf17, vf16 + // move.xyzw vf13, vf12 | mulaz.xyzw ACC, vf24, vf08 :e + // move.xyzw vf12, vf11 | maddaz.xyzw ACC, vf25, vf09 + // nop | mulaz.xyzw ACC, vf09, vf01 + // nop | maddax.xyzw ACC, vf10, vf01 + // nop | maddy.xyzw vf01, vf11, vf01 + // nop | mulaz.xyzw ACC, vf09, vf02 + // nop | maddax.xyzw ACC, vf10, vf02 + // nop | maddy.xyzw vf02, vf11, vf02 + // fmand vi01, vi09 | mulaz.xyzw ACC, vf09, vf03 + // nop | maddax.xyzw ACC, vf10, vf03 + // nop | maddy.xyzw vf03, vf11, vf03 + // fmand vi02, vi09 | mulaz.xyzw ACC, vf09, vf04 + // nop | maddax.xyzw ACC, vf10, vf04 + // nop | maddy.xyzw vf04, vf11, vf04 + // fmand vi03, vi09 | nop + // nop | nop + // nop | nop :e + // fmand vi04, vi09 | nop + // nop | mulaz.xyzw ACC, vf09, vf05 + // nop | maddax.xyzw ACC, vf10, vf05 + // nop | maddy.xyzw vf05, vf11, vf05 + // nop | mulaz.xyzw ACC, vf09, vf06 + // nop | maddax.xyzw ACC, vf10, vf06 + // nop | maddy.xyzw vf06, vf11, vf06 + // fmand vi05, vi09 | mulaz.xyzw ACC, vf09, vf07 + // nop | maddax.xyzw ACC, vf10, vf07 + // nop | maddy.xyzw vf07, vf11, vf07 + // fmand vi06, vi09 | mulaz.xyzw ACC, vf09, vf08 + // nop | maddax.xyzw ACC, vf10, vf08 + // nop | maddy.xyzw vf08, vf11, vf08 + // fmand vi07, vi09 | nop + // nop | nop + // nop | nop :e + // fmand vi08, vi09 | nop + +} + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u16 vis[16]; + + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + c->sq(s0, 7392, at); // sq s0, 7392(at) + c->sq(s1, 7408, at); // sq s1, 7408(at) + c->sq(s2, 7424, at); // sq s2, 7424(at) + c->sq(s3, 7440, at); // sq s3, 7440(at) + c->sq(s4, 7456, at); // sq s4, 7456(at) + c->sq(s5, 7472, at); // sq s5, 7472(at) + c->sq(s6, 7488, at); // sq s6, 7488(at) + c->sq(t8, 7504, at); // sq t8, 7504(at) + c->sq(t9, 7520, at); // sq t9, 7520(at) + c->sq(gp, 7536, at); // sq gp, 7536(at) + c->sq(sp, 7552, at); // sq sp, 7552(at) + c->sq(fp, 7568, at); // sq fp, 7568(at) + c->sq(ra, 7584, at); // sq ra, 7584(at) + // nop // sll r0, r0, 0 + get_fake_spad_addr(t2, cache.fake_scratchpad_data, 0, c);// lui t2, 28672 + c->addiu(a0, r0, 0); // addiu a0, r0, 0 + c->lbu(a1, 6827, t2); // lbu a1, 6827(t2) + c->addiu(a2, r0, 4); // addiu a2, r0, 4 + c->lw(t0, 7316, t2); // lw t0, 7316(t2) + // nop // sll r0, r0, 0 + c->lw(v1, 7320, t2); // lw v1, 7320(t2) + c->dsubu(t4, a1, r0); // dsubu t4, a1, r0 + c->lw(a1, 40, t2); // lw a1, 40(t2) + c->movn(a0, a2, t4); // movn a0, a2, t4 + c->lbu(t3, 6772, t2); // lbu t3, 6772(t2) + c->daddu(t1, a0, t2); // daddu t1, a0, t2 + c->lw(a0, 7300, t2); // lw a0, 7300(t2) + c->daddiu(a2, a1, 128); // daddiu a2, a1, 128 + c->lbu(a3, 10, t0); // lbu a3, 10(t0) + c->dsll(t5, t3, 1); // dsll t5, t3, 1 + c->lbu(t3, 9, t0); // lbu t3, 9(t0) + c->daddu(t1, t1, t5); // daddu t1, t1, t5 + c->lbu(t5, 11953, t1); // lbu t5, 11953(t1) + // nop // sll r0, r0, 0 + c->lbu(t6, 11952, t1); // lbu t6, 11952(t1) + // nop // sll r0, r0, 0 + c->lw(t1, 7304, t2); // lw t1, 7304(t2) + c->sll(t7, a3, 4); // sll t7, a3, 4 + c->daddu(t6, t6, t2); // daddu t6, t6, t2 + c->daddu(t8, t5, t2); // daddu t8, t5, t2 + c->lw(a3, 7308, t2); // lw a3, 7308(t2) + c->daddu(t5, t7, t0); // daddu t5, t7, t0 + c->sw(t5, 7324, t2); // sw t5, 7324(t2) + // nop // sll r0, r0, 0 + c->lbu(t0, 12, t5); // lbu t0, 12(t5) + c->addiu(t7, r0, 0); // addiu t7, r0, 0 + c->lq(t8, 11888, t8); // lq t8, 11888(t8) + c->movn(t7, r0, t4); // movn t7, r0, t4 + c->lq(t4, 11888, t6); // lq t4, 11888(t6) + c->movz(t7, r0, t3); // movz t7, r0, t3 + c->sq(t8, 96, a1); // sq t8, 96(a1) + c->daddiu(t6, v1, 5504); // daddiu t6, v1, 5504 + c->sq(t4, 112, a1); // sq t4, 112(a1) + c->daddiu(v1, v1, 6048); // daddiu v1, v1, 6048 + c->sw(t7, 124, a1); // sw t7, 124(a1) + c->movn(v1, t6, t3); // movn v1, t6, t3 + c->lq(gp, 11744, t2); // lq gp, 11744(t2) + c->daddiu(t6, t5, 16); // daddiu t6, t5, 16 + c->lq(s4, 11808, t2); // lq s4, 11808(t2) + c->addiu(t8, r0, 0); // addiu t8, r0, 0 + c->lq(s5, 11824, t2); // lq s5, 11824(t2) + c->addiu(t5, r0, 0); // addiu t5, r0, 0 + c->lq(t9, 11840, t2); // lq t9, 11840(t2) + c->addiu(t4, r0, -3); // addiu t4, r0, -3 + c->lq(ra, 11856, t2); // lq ra, 11856(t2) + c->addiu(t7, r0, 6); // addiu t7, r0, 6 + c->lq(t2, 11872, t2); // lq t2, 11872(t2) + // nop // sll r0, r0, 0 + c->sq(gp, 0, a1); // sq gp, 0(a1) + c->movz(t7, r0, t3); // movz t7, r0, t3 + c->sq(s4, 16, a1); // sq s4, 16(a1) + c->addiu(gp, r0, 0); // addiu gp, r0, 0 + c->sq(s5, 32, a1); // sq s5, 32(a1) + c->addiu(s5, r0, -32768); // addiu s5, r0, -32768 + c->sq(t9, 48, a1); // sq t9, 48(a1) + c->movz(gp, s5, t0); // movz gp, s5, t0 + c->sq(ra, 64, a1); // sq ra, 64(a1) + // nop // sll r0, r0, 0 + bc = c->sgpr64(t3) == 0; // beq t3, r0, L73 + c->sq(t2, 80, a1); // sq t2, 80(a1) + if (bc) {goto block_4;} // branch non-likely + + c->lq(t9, 2896, t1); // lq t9, 2896(t1) + c->daddu(gp, t3, gp); // daddu gp, t3, gp + c->lq(ra, 2912, t1); // lq ra, 2912(t1) + c->addiu(s5, r0, -6); // addiu s5, r0, -6 + c->lq(t3, 2928, t1); // lq t3, 2928(t1) + c->daddiu(t0, t0, 1); // daddiu t0, t0, 1 + c->lq(t2, 2944, t1); // lq t2, 2944(t1) + c->daddiu(s4, t0, -3); // daddiu s4, t0, -3 + bc = ((s64)c->sgpr64(s4)) <= 0; // blez s4, L75 + c->lq(t1, 2960, t1); // lq t1, 2960(t1) + if (bc) {goto block_8;} // branch non-likely + + c->daddiu(t8, t0, -5); // daddiu t8, t0, -5 + // nop // sll r0, r0, 0 + bc = ((s64)c->sgpr64(t8)) <= 0; // blez t8, L75 + c->lh(t8, 172, t6); // lh t8, 172(t6) + if (bc) {goto block_8;} // branch non-likely + + //beq r0, r0, L75 // beq r0, r0, L75 + c->lh(t5, 332, t6); // lh t5, 332(t6) + goto block_8; // branch always + + + block_4: + c->daddiu(t1, t0, -3); // daddiu t1, t0, -3 + // nop // sll r0, r0, 0 + bc = ((s64)c->sgpr64(t1)) <= 0; // blez t1, L74 + c->daddiu(t1, t0, -5); // daddiu t1, t0, -5 + if (bc) {goto block_7;} // branch non-likely + + bc = ((s64)c->sgpr64(t1)) <= 0; // blez t1, L74 + c->lh(t8, 252, t6); // lh t8, 252(t6) + if (bc) {goto block_7;} // branch non-likely + + // nop // sll r0, r0, 0 + c->lh(t5, 412, t6); // lh t5, 412(t6) + + block_7: + c->lh(s5, 12, t6); // lh s5, 12(t6) + // nop // sll r0, r0, 0 + c->lh(gp, 28, t6); // lh gp, 28(t6) + // nop // sll r0, r0, 0 + c->lq(t9, 0, t6); // lq t9, 0(t6) + // nop // sll r0, r0, 0 + c->lq(ra, 16, t6); // lq ra, 16(t6) + // nop // sll r0, r0, 0 + c->lq(t3, 32, t6); // lq t3, 32(t6) + // nop // sll r0, r0, 0 + c->lq(t2, 48, t6); // lq t2, 48(t6) + // nop // sll r0, r0, 0 + c->lq(t1, 64, t6); // lq t1, 64(t6) + c->daddiu(t6, t6, 80); // daddiu t6, t6, 80 + + block_8: + c->sq(t9, 0, a2); // sq t9, 0(a2) + c->daddu(s5, s5, t7); // daddu s5, s5, t7 + c->sq(ra, 16, a2); // sq ra, 16(a2) + c->daddiu(t7, t7, 2); // daddiu t7, t7, 2 + c->sq(t3, 32, a2); // sq t3, 32(a2) + c->daddu(t4, t4, gp); // daddu t4, t4, gp + c->sq(t2, 48, a2); // sq t2, 48(a2) + c->daddiu(t4, t4, 3); // daddiu t4, t4, 3 + c->sq(t1, 64, a2); // sq t1, 64(a2) + c->andi(t4, t4, 255); // andi t4, t4, 255 + c->sw(s5, 12, a2); // sw s5, 12(a2) + c->daddiu(a2, a2, 80); // daddiu a2, a2, 80 + bc = ((s64)c->sgpr64(gp)) > 0; // bgtz gp, L74 + c->sw(gp, -52, a2); // sw gp, -52(a2) + if (bc) {goto block_7;} // branch non-likely + + c->sw(t4, 108, a1); // sw t4, 108(a1) + c->daddiu(a1, t8, 7); // daddiu a1, t8, 7 + c->sq(t9, 2896, a0); // sq t9, 2896(a0) + c->daddiu(t5, t5, 7); // daddiu t5, t5, 7 + c->sq(ra, 2912, a0); // sq ra, 2912(a0) + c->sra(a2, a1, 4); // sra a2, a1, 4 + c->sq(t3, 2928, a0); // sq t3, 2928(a0) + c->sra(t3, t5, 4); // sra t3, t5, 4 + c->sq(t2, 2944, a0); // sq t2, 2944(a0) + c->daddiu(a1, a3, 192); // daddiu a1, a3, 192 + c->sq(t1, 2960, a0); // sq t1, 2960(a0) + c->dsll(a0, t0, 2); // dsll a0, t0, 2 + c->sh(t4, 18, a3); // sh t4, 18(a3) + c->daddu(a0, a0, t0); // daddu a0, a0, t0 + c->sb(t0, 16, a3); // sb t0, 16(a3) + c->daddiu(a0, a0, 7); // daddiu a0, a0, 7 + c->dsubu(a0, t3, a2); // dsubu a0, t3, a2 + c->lq(t0, 0, v1); // lq t0, 0(v1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->daddiu(t1, a2, -3); // daddiu t1, a2, -3 + c->lq(a3, 16, v1); // lq a3, 16(v1) + // nop // sll r0, r0, 0 + c->sq(t0, 0, a1); // sq t0, 0(a1) + bc = c->sgpr64(t1) == 0; // beq t1, r0, L76 + c->lq(a2, 32, v1); // lq a2, 32(v1) + if (bc) {goto block_21;} // branch non-likely + + c->daddiu(t0, t1, -1); // daddiu t0, t1, -1 + c->sq(a3, 16, a1); // sq a3, 16(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L77 + c->lq(a3, 48, v1); // lq a3, 48(v1) + if (bc) {goto block_22;} // branch non-likely + + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->sq(a2, 32, a1); // sq a2, 32(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L78 + c->lq(a2, 64, v1); // lq a2, 64(v1) + if (bc) {goto block_23;} // branch non-likely + + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->sq(a3, 48, a1); // sq a3, 48(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L79 + c->lq(a3, 80, v1); // lq a3, 80(v1) + if (bc) {goto block_24;} // branch non-likely + + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->sq(a2, 64, a1); // sq a2, 64(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L80 + c->lq(a2, 96, v1); // lq a2, 96(v1) + if (bc) {goto block_25;} // branch non-likely + + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->sq(a3, 80, a1); // sq a3, 80(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L81 + c->lq(a3, 112, v1); // lq a3, 112(v1) + if (bc) {goto block_26;} // branch non-likely + + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->sq(a2, 96, a1); // sq a2, 96(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L82 + c->lq(a2, 128, v1); // lq a2, 128(v1) + if (bc) {goto block_27;} // branch non-likely + + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->sq(a3, 112, a1); // sq a3, 112(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L83 + c->lq(a3, 144, v1); // lq a3, 144(v1) + if (bc) {goto block_28;} // branch non-likely + + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->sq(a2, 128, a1); // sq a2, 128(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L84 + c->lq(a2, 160, v1); // lq a2, 160(v1) + if (bc) {goto block_29;} // branch non-likely + + c->daddiu(t0, t0, -1); // daddiu t0, t0, -1 + c->sq(a3, 144, a1); // sq a3, 144(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L85 + c->lq(a3, 176, v1); // lq a3, 176(v1) + if (bc) {goto block_30;} // branch non-likely + + c->daddiu(a0, t0, -1); // daddiu a0, t0, -1 + c->sq(a2, 160, a1); // sq a2, 160(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L86 + c->lq(a0, 192, v1); // lq a0, 192(v1) + if (bc) {goto block_31;} // branch non-likely + + // nop // sll r0, r0, 0 + c->sq(a3, 176, a1); // sq a3, 176(a1) + // nop // sll r0, r0, 0 + c->lq(v1, 208, v1); // lq v1, 208(v1) + // nop // sll r0, r0, 0 + c->sq(a0, 192, a1); // sq a0, 192(a1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->sq(v1, 208, a1); // sq v1, 208(a1) + //beq r0, r0, L96 // beq r0, r0, L96 + // nop // sll r0, r0, 0 + goto block_41; // branch always + + + block_21: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a3, 16, a1); // sq a3, 16(a1) + // nop // sll r0, r0, 0 + c->lq(a3, 224, v1); // lq a3, 224(v1) + + block_22: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a2, 32, a1); // sq a2, 32(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L87 + c->lq(a2, 240, v1); // lq a2, 240(v1) + if (bc) {goto block_32;} // branch non-likely + + + block_23: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a3, 48, a1); // sq a3, 48(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L88 + c->lq(a3, 256, v1); // lq a3, 256(v1) + if (bc) {goto block_33;} // branch non-likely + + + block_24: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a2, 64, a1); // sq a2, 64(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L89 + c->lq(a2, 272, v1); // lq a2, 272(v1) + if (bc) {goto block_34;} // branch non-likely + + + block_25: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a3, 80, a1); // sq a3, 80(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L90 + c->lq(a3, 288, v1); // lq a3, 288(v1) + if (bc) {goto block_35;} // branch non-likely + + + block_26: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a2, 96, a1); // sq a2, 96(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L91 + c->lq(a2, 304, v1); // lq a2, 304(v1) + if (bc) {goto block_36;} // branch non-likely + + + block_27: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a3, 112, a1); // sq a3, 112(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L92 + c->lq(a3, 320, v1); // lq a3, 320(v1) + if (bc) {goto block_37;} // branch non-likely + + + block_28: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a2, 128, a1); // sq a2, 128(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L93 + c->lq(a2, 336, v1); // lq a2, 336(v1) + if (bc) {goto block_38;} // branch non-likely + + + block_29: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a3, 144, a1); // sq a3, 144(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L94 + c->lq(a3, 352, v1); // lq a3, 352(v1) + if (bc) {goto block_39;} // branch non-likely + + + block_30: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(a2, 160, a1); // sq a2, 160(a1) + bc = c->sgpr64(a0) == 0; // beq a0, r0, L95 + c->lq(a0, 368, v1); // lq a0, 368(v1) + if (bc) {goto block_40;} // branch non-likely + + + block_31: + // nop // sll r0, r0, 0 + c->sq(a3, 176, a1); // sq a3, 176(a1) + // nop // sll r0, r0, 0 + c->lq(v1, 384, v1); // lq v1, 384(v1) + // nop // sll r0, r0, 0 + c->sq(a0, 192, a1); // sq a0, 192(a1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->sq(v1, 208, a1); // sq v1, 208(a1) + //beq r0, r0, L96 // beq r0, r0, L96 + // nop // sll r0, r0, 0 + goto block_41; // branch always + + + block_32: + // nop // sll r0, r0, 0 + c->sq(a3, 48, a1); // sq a3, 48(a1) + // nop // sll r0, r0, 0 + c->lq(a3, 400, v1); // lq a3, 400(v1) + + block_33: + // nop // sll r0, r0, 0 + c->sq(a2, 64, a1); // sq a2, 64(a1) + // nop // sll r0, r0, 0 + c->lq(a2, 416, v1); // lq a2, 416(v1) + + block_34: + // nop // sll r0, r0, 0 + c->sq(a3, 80, a1); // sq a3, 80(a1) + // nop // sll r0, r0, 0 + c->lq(a3, 432, v1); // lq a3, 432(v1) + + block_35: + // nop // sll r0, r0, 0 + c->sq(a2, 96, a1); // sq a2, 96(a1) + // nop // sll r0, r0, 0 + c->lq(a2, 448, v1); // lq a2, 448(v1) + + block_36: + // nop // sll r0, r0, 0 + c->sq(a3, 112, a1); // sq a3, 112(a1) + // nop // sll r0, r0, 0 + c->lq(a3, 464, v1); // lq a3, 464(v1) + + block_37: + // nop // sll r0, r0, 0 + c->sq(a2, 128, a1); // sq a2, 128(a1) + // nop // sll r0, r0, 0 + c->lq(a2, 480, v1); // lq a2, 480(v1) + + block_38: + // nop // sll r0, r0, 0 + c->sq(a3, 144, a1); // sq a3, 144(a1) + // nop // sll r0, r0, 0 + c->lq(a3, 496, v1); // lq a3, 496(v1) + + block_39: + // nop // sll r0, r0, 0 + c->sq(a2, 160, a1); // sq a2, 160(a1) + // nop // sll r0, r0, 0 + c->lq(a0, 512, v1); // lq a0, 512(v1) + + block_40: + // nop // sll r0, r0, 0 + c->sq(a3, 176, a1); // sq a3, 176(a1) + // nop // sll r0, r0, 0 + c->lq(v1, 528, v1); // lq v1, 528(v1) + // nop // sll r0, r0, 0 + c->sq(a0, 192, a1); // sq a0, 192(a1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->sq(v1, 208, a1); // sq v1, 208(a1) + + block_41: + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + // nop // sll r0, r0, 0 + c->lw(a1, 7324, v1); // lw a1, 7324(v1) + // nop // sll r0, r0, 0 + c->lw(a0, 7308, v1); // lw a0, 7308(v1) + // nop // sll r0, r0, 0 + c->lbu(a2, 13, a1); // lbu a2, 13(a1) + // nop // sll r0, r0, 0 + c->lbu(v1, 14, a1); // lbu v1, 14(a1) + c->daddiu(a0, a0, 32); // daddiu a0, a0, 32 + c->lbu(a3, 15, a1); // lbu a3, 15(a1) + c->daddu(a1, a1, a2); // daddu a1, a1, a2 + c->mult3(a3, v1, a3); // mult3 a3, v1, a3 + c->mov64(a1, a1); // or a1, a1, r0 + c->mov64(v1, v1); // or v1, v1, r0 + c->mov64(a0, a0); // or a0, a0, r0 + c->addiu(a2, r0, 513); // addiu a2, r0, 513 + c->addiu(t0, r0, 257); // addiu t0, r0, 257 + c->dsll(t2, a2, 18); // dsll t2, a2, 18 + c->dsll(t1, t0, 16); // dsll t1, t0, 16 + c->or_(a2, a2, t2); // or a2, a2, t2 + c->or_(t0, t0, t1); // or t0, t0, t1 + c->dsll32(t2, a2, 4); // dsll32 t2, a2, 4 + c->dsll32(t1, t0, 0); // dsll32 t1, t0, 0 + c->or_(a2, a2, t2); // or a2, a2, t2 + c->or_(t0, t0, t1); // or t0, t0, t1 + c->pcpyld(a2, a2, a2); // pcpyld a2, a2, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyld(t0, t0, t0); // pcpyld t0, t0, t0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->daddu(a3, a3, a1); // daddu a3, a3, a1 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->lhu(t1, 0, a1); // lhu t1, 0(a1) + c->daddu(a1, a1, v1); // daddu a1, a1, v1 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + // nop // sll r0, r0, 0 + c->pextlb(t1, t1, t1); // pextlb t1, t1, t1 + //beq r0, r0, L98 // beq r0, r0, L98 + c->pextlb(t2, t1, t1); // pextlb t2, t1, t1 + goto block_43; // branch always + + + block_42: + c->daddu(a1, a1, v1); // daddu a1, a1, v1 + c->daddiu(a0, a0, 32); // daddiu a0, a0, 32 + c->pextlb(t2, t2, t2); // pextlb t2, t2, t2 + c->sq(t1, -16, a0); // sq t1, -16(a0) + + block_43: + c->pextlb(t1, t2, t2); // pextlb t1, t2, t2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t1, t1, a2); // pand t1, t1, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pceqb(t1, t1, a2); // pceqb t1, t1, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pand(t1, t1, t0); // pand t1, t1, t0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlb(t2, t1, r0); // pextlb t2, t1, r0 + c->lhu(t3, 0, a1); // lhu t3, 0(a1) + c->pextub(t1, t1, r0); // pextub t1, t1, r0 + c->sq(t2, 0, a0); // sq t2, 0(a0) + bc = c->sgpr64(a1) != c->sgpr64(a3); // bne a1, a3, L97 + c->pextlb(t2, t3, t3); // pextlb t2, t3, t3 + if (bc) {goto block_42;} // branch non-likely + + // nop // sll r0, r0, 0 + c->sq(t1, 16, a0); // sq t1, 16(a0) + get_fake_spad_addr(s4, cache.fake_scratchpad_data, 0, c);// lui s4, 28672 + // nop // sll r0, r0, 0 + c->lw(a0, 7316, s4); // lw a0, 7316(s4) + // nop // sll r0, r0, 0 + c->lw(a1, 7308, s4); // lw a1, 7308(s4) + // nop // sll r0, r0, 0 + c->lq(t8, 16, a0); // lq t8, 16(a0) + c->daddiu(s6, a0, 48); // daddiu s6, a0, 48 + c->lbu(a3, 12, a0); // lbu a3, 12(a0) + // nop // sll r0, r0, 0 + c->lbu(t2, 10, a0); // lbu t2, 10(a0) + c->pextlb(t9, r0, t8); // pextlb t9, r0, t8 + vis[10] = c->gpr_src(a3).du16[0]; // ctc2.ni vi10, a3 + c->pextlh(gp, r0, t9); // pextlh gp, r0, t9 + c->mov128_vf_gpr(vf1, gp); // qmtc2.ni vf1, gp + c->pextuh(t9, r0, t9); // pextuh t9, r0, t9 + c->mov128_vf_gpr(vf2, t9); // qmtc2.ni vf2, t9 + c->pextub(t9, r0, t8); // pextub t9, r0, t8 + c->lbu(a3, 4, a0); // lbu a3, 4(a0) + c->pextlh(gp, r0, t9); // pextlh gp, r0, t9 + c->mov128_vf_gpr(vf3, gp); // qmtc2.ni vf3, gp + c->pextuh(t9, r0, t9); // pextuh t9, r0, t9 + c->mov128_vf_gpr(vf4, t9); // qmtc2.ni vf4, t9 + c->sll(t2, t2, 4); // sll t2, t2, 4 + c->lbu(t0, 5, a0); // lbu t0, 5(a0) + c->daddu(t2, t2, a0); // daddu t2, t2, a0 + c->lbu(t1, 6, a0); // lbu t1, 6(a0) + c->daddiu(s5, a3, -1); // daddiu s5, a3, -1 + vis[11] = c->gpr_src(a3).du16[0]; // ctc2.ni vi11, a3 + c->daddu(s5, s5, t0); // daddu s5, s5, t0 + vis[12] = c->gpr_src(t0).du16[0]; // ctc2.ni vi12, t0 + c->daddu(s5, s5, t1); // daddu s5, s5, t1 + vis[13] = c->gpr_src(t1).du16[0]; // ctc2.ni vi13, t1 + c->daddiu(t4, a1, 32); // daddiu t4, a1, 32 + c->lqc2(vf27, 0, t2); // lqc2 vf27, 0(t2) + c->daddiu(t3, a1, 192); // daddiu t3, a1, 192 + // Unknown instr: vcallms 280 + vcallms_280(c, vis); + c->daddiu(v1, a1, 448); // daddiu v1, a1, 448 + c->lhu(s1, 6740, s4); // lhu s1, 6740(s4) + c->pextlw(t3, t3, t3); // pextlw t3, t3, t3 + c->lhu(s2, 6742, s4); // lhu s2, 6742(s4) + c->pcpyld(t3, t3, t3); // pcpyld t3, t3, t3 + c->lqc2(vf19, 6720, s4); // lqc2 vf19, 6720(s4) + c->pcpyh(s1, s1); // pcpyh s1, s1 + c->lbu(v0, 2, a0); // lbu v0, 2(a0) + c->addiu(t5, r0, 0); // addiu t5, r0, 0 + c->lbu(at, 1, a0); // lbu at, 1(a0) + c->addiu(s4, r0, -1); // addiu s4, r0, -1 + c->lui(a1, 19201); // lui a1, 19201 + c->daddiu(v0, v0, 3); // daddiu v0, v0, 3 + c->daddiu(a1, a1, 18304); // daddiu a1, a1, 18304 + c->andi(v0, v0, 252); // andi v0, v0, 252 + c->sll(at, at, 2); // sll at, at, 2 + c->sll(v0, v0, 2); // sll v0, v0, 2 + c->lq(t8, 32, a0); // lq t8, 32(a0) + c->daddu(v0, v0, a0); // daddu v0, v0, a0 + u32 val; + memcpy(&val, cache.fake_scratchpad_data, 4); + c->lbu(t0, 13, a0); // lbu t0, 13(a0) + c->daddu(at, at, a0); // daddu at, at, a0 + c->lbu(t2, 11, a0); // lbu t2, 11(a0) + c->pextlw(a1, a1, r0); // pextlw a1, a1, r0 + bc = c->sgpr64(t0) == 0; // beq t0, r0, L101 + c->pcpyld(a1, a1, a1); // pcpyld a1, a1, a1 + if (bc) {goto block_49;} // branch non-likely + + c->sll(t2, t2, 4); // sll t2, t2, 4 + c->daddiu(a3, a0, 14); // daddiu a3, a0, 14 + //beq r0, r0, L100 // beq r0, r0, L100 + c->daddu(t2, t2, a0); // daddu t2, t2, a0 + goto block_47; // branch always + + block_46: + // Unknown instr: vcallms 303 + vcallms_303(c, vis); + c->mov64(t0, t1); // or t0, t1, r0 + + block_47: + c->lbu(t1, 0, a3); // lbu t1, 0(a3) + c->daddiu(a3, a3, 1); // daddiu a3, a3, 1 + c->lqc2(vf23, 64, t2); // lqc2 vf23, 64(t2) + // nop // sll r0, r0, 0 + c->lqc2(vf24, 80, t2); // lqc2 vf24, 80(t2) + // nop // sll r0, r0, 0 + c->lqc2(vf25, 96, t2); // lqc2 vf25, 96(t2) + // nop // sll r0, r0, 0 + c->lqc2(vf26, 112, t2); // lqc2 vf26, 112(t2) + // nop // sll r0, r0, 0 + c->lqc2(vf20, 16, t2); // lqc2 vf20, 16(t2) + // nop // sll r0, r0, 0 + c->lqc2(vf21, 32, t2); // lqc2 vf21, 32(t2) + // nop // sll r0, r0, 0 + c->lqc2(vf22, 48, t2); // lqc2 vf22, 48(t2) + c->daddiu(t2, t2, 128); // daddiu t2, t2, 128 + bc = c->sgpr64(t1) != 0; // bne t1, r0, L99 + vis[14] = c->gpr_src(t0).du16[0]; // ctc2.ni vi14, t0 + if (bc) {goto block_46;} // branch non-likely + + // Unknown instr: vcallms 303 + vcallms_303(c, vis); + // nop // sll r0, r0, 0 + + block_49: + c->lq(a2, 0, v0); // lq a2, 0(v0) + c->pextlb(t9, r0, t8); // pextlb t9, r0, t8 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlh(gp, r0, t9); // pextlh gp, r0, t9 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlb(a3, r0, a2); // pextlb a3, r0, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextub(a2, r0, a2); // pextub a2, r0, a2 + c->mov128_vf_gpr(vf4, gp); // qmtc2.ni vf4, gp + c->pextlh(t0, a1, a3); // pextlh t0, a1, a3 + c->mov128_vf_gpr(vf1, t0); // qmtc2.ni vf1, t0 + c->pextuh(a3, a1, a3); // pextuh a3, a1, a3 + c->mov128_vf_gpr(vf2, a3); // qmtc2.ni vf2, a3 + c->pextlh(t1, a1, a2); // pextlh t1, a1, a2 + c->mov128_vf_gpr(vf3, t1); // qmtc2.ni vf3, t1 + c->pextuh(t9, r0, t9); // pextuh t9, r0, t9 + // Unknown instr: vcallms 311 + vcallms_311(c, vis); + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->lq(t2, 16, v0); // lq t2, 16(v0) + // nop // sll r0, r0, 0 + c->daddiu(at, at, -16); // daddiu at, at, -16 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextuh(a2, a1, a2); // pextuh a2, a1, a2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlb(t0, r0, t2); // pextlb t0, r0, t2 + c->mov128_vf_gpr(vf4, t9); // qmtc2.ni vf4, t9 + c->pextlh(t1, a1, t0); // pextlh t1, a1, t0 + c->mov128_vf_gpr(vf1, a2); // qmtc2.ni vf1, a2 + c->pextuh(t0, a1, t0); // pextuh t0, a1, t0 + c->mov128_vf_gpr(vf2, t1); // qmtc2.ni vf2, t1 + c->pextub(t9, r0, t8); // pextub t9, r0, t8 + c->mov128_vf_gpr(vf3, t0); // qmtc2.ni vf3, t0 + c->pextlh(gp, r0, t9); // pextlh gp, r0, t9 + // nop // sll r0, r0, 0 + c->daddiu(v0, v0, -48); // daddiu v0, v0, -48 + // Unknown instr: vcallms 311 + vcallms_311(c, vis); + // nop // sll r0, r0, 0 + c->addiu(t6, r0, 0); // addiu t6, r0, 0 + // nop // sll r0, r0, 0 + c->lwl(t6, 53, v0); // lwl t6, 53(v0) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlb(t6, r0, t6); // pextlb t6, r0, t6 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlb(t6, r0, t6); // pextlb t6, r0, t6 + c->lq(a3, 80, v0); // lq a3, 80(v0) + c->paddw(t6, t6, t3); // paddw t6, t6, t3 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextub(t2, r0, t2); // pextub t2, r0, t2 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlh(t0, a1, t2); // pextlh t0, a1, t2 + c->mov128_vf_gpr(vf4, gp); // qmtc2.ni vf4, gp + c->pextuh(t2, a1, t2); // pextuh t2, a1, t2 + c->mov128_vf_gpr(vf1, t0); // qmtc2.ni vf1, t0 + c->pextlb(t1, r0, a3); // pextlb t1, r0, a3 + c->mov128_vf_gpr(vf2, t2); // qmtc2.ni vf2, t2 + c->pextlh(a2, a1, t1); // pextlh a2, a1, t1 + c->mov128_vf_gpr(vf3, a2); // qmtc2.ni vf3, a2 + c->pextuh(t9, r0, t9); // pextuh t9, r0, t9 + // nop // sll r0, r0, 0 + c->daddiu(v1, v1, -64); // daddiu v1, v1, -64 + // nop // sll r0, r0, 0 + c->sqc2(vf15, 64, v1); // sqc2 vf15, 64(v1) + // Unknown instr: vcallms 311 + vcallms_311(c, vis); + // nop // sll r0, r0, 0 + c->lwr(s3, 56, v0); // lwr s3, 56(v0) + // nop // sll r0, r0, 0 + c->lwl(s3, 69, v0); // lwl s3, 69(v0) + // nop // sll r0, r0, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pcpyud(t6, t6, r0); // pcpyud t6, t6, r0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextlb(s3, r0, s3); // pextlb s3, r0, s3 + // nop // sll r0, r0, 0 + c->dsllv(s3, s3, s2); // dsllv s3, s3, s2 + c->lq(t8, 0, s6); // lq t8, 0(s6) + c->paddh(s3, s3, s1); // paddh s3, s3, s1 + c->lbu(t7, 0, t6); // lbu t7, 0(t6) + c->dsrl32(t6, t6, 0); // dsrl32 t6, t6, 0 + c->mfc1(r0, f31); // mfc1 r0, f31 + c->pextuh(t0, a1, t1); // pextuh t0, a1, t1 + c->lbu(s0, 0, t6); // lbu s0, 0(t6) + c->pextub(a3, r0, a3); // pextub a3, r0, a3 + c->mov128_vf_gpr(vf4, t9); // qmtc2.ni vf4, t9 + c->pextlh(t2, a1, a3); // pextlh t2, a1, a3 + c->mov128_vf_gpr(vf1, t0); // qmtc2.ni vf1, t0 + c->pextuh(a3, a1, a3); // pextuh a3, a1, a3 + c->mov128_vf_gpr(vf2, t2); // qmtc2.ni vf2, t2 + c->pextlb(t9, r0, t8); // pextlb t9, r0, t8 + c->mov128_vf_gpr(vf3, a3); // qmtc2.ni vf3, a3 + c->pextlh(gp, r0, t9); // pextlh gp, r0, t9 + // nop // sll r0, r0, 0 + c->daddiu(s6, s6, 16); // daddiu s6, s6, 16 + // nop // sll r0, r0, 0 + c->sqc2(vf15, 96, v1); // sqc2 vf15, 96(v1) + // Unknown instr: vcallms 311 + vcallms_311(c, vis); + c->sw(s3, 76, v1); // sw s3, 76(v1) + c->lwr(t6, 64, v0); // lwr t6, 64(v0) + c->daddu(t7, t7, t4); // daddu t7, t7, t4 + c->lwl(t6, 77, v0); // lwl t6, 77(v0) + c->daddu(s0, s0, t4); // daddu s0, s0, t4 + //beq r0, r0, L103 // beq r0, r0, L103 + c->dsrl32(s3, s3, 0); // dsrl32 s3, s3, 0 + goto block_51; // branch always + + + block_50: + // Unknown instr: vcallms 311 + vcallms_311(c, vis); + c->sw(s3, 76, v1); // sw s3, 76(v1) + c->lwr(t6, 64, v0); // lwr t6, 64(v0) + c->daddu(t7, t7, t4); // daddu t7, t7, t4 + c->lwl(t6, 77, v0); // lwl t6, 77(v0) + c->daddu(s0, s0, t4); // daddu s0, s0, t4 + c->sw(a0, 60, v1); // sw a0, 60(v1) + c->dsrl32(s3, s3, 0); // dsrl32 s3, s3, 0 + + block_51: + c->sb(t5, 0, t7); // sb t5, 0(t7) + c->pextlb(t6, r0, t6); // pextlb t6, r0, t6 + c->sb(t5, 0, s0); // sb t5, 0(s0) + c->pextlb(t6, r0, t6); // pextlb t6, r0, t6 + c->lq(a2, 96, v0); // lq a2, 96(v0) + c->paddw(t6, t6, t3); // paddw t6, t6, t3 + c->lbu(t7, 0, t6); // lbu t7, 0(t6) + c->dsrl32(t6, t6, 0); // dsrl32 t6, t6, 0 + c->lw(a0, 16, at); // lw a0, 16(at) + c->pextlb(a3, r0, a2); // pextlb a3, r0, a2 + c->lbu(s0, 0, t6); // lbu s0, 0(t6) + c->pextub(a2, r0, a2); // pextub a2, r0, a2 + c->mov128_vf_gpr(vf4, gp); // qmtc2.ni vf4, gp + c->pextlh(t0, a1, a3); // pextlh t0, a1, a3 + c->mov128_vf_gpr(vf1, t0); // qmtc2.ni vf1, t0 + c->pextuh(a3, a1, a3); // pextuh a3, a1, a3 + c->mov128_vf_gpr(vf2, a3); // qmtc2.ni vf2, a3 + c->pextlh(t1, a1, a2); // pextlh t1, a1, a2 + c->mov128_vf_gpr(vf3, t1); // qmtc2.ni vf3, t1 + c->pextuh(t9, r0, t9); // pextuh t9, r0, t9 + c->sqc2(vf14, 80, v1); // sqc2 vf14, 80(v1) + + c->daddiu(at, at, 16); // daddiu at, at, 16 + c->addiu(s4, s4, 2); // addiu s4, s4, 2 + c->sqc2(vf15, 128, v1); // sqc2 vf15, 128(v1) + bc = c->sgpr64(t5) == c->sgpr64(s5); // beq t5, s5, L104 + c->daddiu(t5, t5, 2); // daddiu t5, t5, 2 + if (bc) {goto block_56;} // branch non-likely + + // Unknown instr: vcallms 311 + vcallms_311(c, vis); + c->sw(s3, 108, v1); // sw s3, 108(v1) + c->lwr(s3, 80, v0); // lwr s3, 80(v0) + c->daddu(t7, t7, t4); // daddu t7, t7, t4 + c->lwl(s3, 93, v0); // lwl s3, 93(v0) + c->daddu(s0, s0, t4); // daddu s0, s0, t4 + c->sw(a0, 92, v1); // sw a0, 92(v1) + c->pcpyud(t6, t6, r0); // pcpyud t6, t6, r0 + c->sb(s4, 0, t7); // sb s4, 0(t7) + c->pextlb(s3, r0, s3); // pextlb s3, r0, s3 + c->sb(s4, 0, s0); // sb s4, 0(s0) + c->dsllv(s3, s3, s2); // dsllv s3, s3, s2 + c->lq(t2, 112, v0); // lq t2, 112(v0) + c->paddh(s3, s3, s1); // paddh s3, s3, s1 + c->lbu(t7, 0, t6); // lbu t7, 0(t6) + c->dsrl32(t6, t6, 0); // dsrl32 t6, t6, 0 + c->lw(a0, 4, at); // lw a0, 4(at) + c->pextuh(a2, a1, a2); // pextuh a2, a1, a2 + c->lbu(s0, 0, t6); // lbu s0, 0(t6) + c->pextlb(t0, r0, t2); // pextlb t0, r0, t2 + c->mov128_vf_gpr(vf4, t9); // qmtc2.ni vf4, t9 + c->pextlh(t1, a1, t0); // pextlh t1, a1, t0 + c->mov128_vf_gpr(vf1, a2); // qmtc2.ni vf1, a2 + c->pextuh(t0, a1, t0); // pextuh t0, a1, t0 + c->mov128_vf_gpr(vf2, t1); // qmtc2.ni vf2, t1 + c->pextub(t9, r0, t8); // pextub t9, r0, t8 + c->mov128_vf_gpr(vf3, t0); // qmtc2.ni vf3, t0 + c->pextlh(gp, r0, t9); // pextlh gp, r0, t9 + c->sqc2(vf14, 112, v1); // sqc2 vf14, 112(v1) + c->daddiu(v0, v0, 48); // daddiu v0, v0, 48 + bc = c->sgpr64(s4) == c->sgpr64(s5); // beq s4, s5, L105 + c->sqc2(vf15, 160, v1); // sqc2 vf15, 160(v1) + if (bc) {goto block_57;} // branch non-likely + + // Unknown instr: vcallms 311 + vcallms_311(c, vis); + c->sw(s3, 140, v1); // sw s3, 140(v1) + c->lwr(t6, 40, v0); // lwr t6, 40(v0) + c->daddu(t7, t7, t4); // daddu t7, t7, t4 + c->lwl(t6, 53, v0); // lwl t6, 53(v0) + c->daddu(s0, s0, t4); // daddu s0, s0, t4 + c->sw(a0, 124, v1); // sw a0, 124(v1) + c->dsrl32(s3, s3, 0); // dsrl32 s3, s3, 0 + c->sb(t5, 0, t7); // sb t5, 0(t7) + c->pextlb(t6, r0, t6); // pextlb t6, r0, t6 + c->sb(t5, 0, s0); // sb t5, 0(s0) + c->pextlb(t6, r0, t6); // pextlb t6, r0, t6 + c->lq(a3, 80, v0); // lq a3, 80(v0) + c->paddw(t6, t6, t3); // paddw t6, t6, t3 + c->lbu(t7, 0, t6); // lbu t7, 0(t6) + c->dsrl32(t6, t6, 0); // dsrl32 t6, t6, 0 + c->lw(a0, 8, at); // lw a0, 8(at) + c->pextub(t2, r0, t2); // pextub t2, r0, t2 + c->lbu(s0, 0, t6); // lbu s0, 0(t6) + c->pextlh(t0, a1, t2); // pextlh t0, a1, t2 + c->mov128_vf_gpr(vf4, gp); // qmtc2.ni vf4, gp + c->pextuh(t2, a1, t2); // pextuh t2, a1, t2 + c->mov128_vf_gpr(vf1, t0); // qmtc2.ni vf1, t0 + c->pextlb(t1, r0, a3); // pextlb t1, r0, a3 + c->mov128_vf_gpr(vf2, t2); // qmtc2.ni vf2, t2 + c->pextlh(a2, a1, t1); // pextlh a2, a1, t1 + c->mov128_vf_gpr(vf3, a2); // qmtc2.ni vf3, a2 + c->pextuh(t9, r0, t9); // pextuh t9, r0, t9 + c->sqc2(vf14, 144, v1); // sqc2 vf14, 144(v1) + c->daddiu(v1, v1, 128); // daddiu v1, v1, 128 + c->addiu(s4, s4, 2); // addiu s4, s4, 2 + c->sqc2(vf15, 64, v1); // sqc2 vf15, 64(v1) + bc = c->sgpr64(t5) == c->sgpr64(s5); // beq t5, s5, L106 + c->daddiu(t5, t5, 2); // daddiu t5, t5, 2 + if (bc) {goto block_58;} // branch non-likely + + // Unknown instr: vcallms 311 + vcallms_311(c, vis); + c->sw(s3, 44, v1); // sw s3, 44(v1) + c->lwr(s3, 56, v0); // lwr s3, 56(v0) + c->daddu(t7, t7, t4); // daddu t7, t7, t4 + c->lwl(s3, 69, v0); // lwl s3, 69(v0) + c->daddu(s0, s0, t4); // daddu s0, s0, t4 + c->sw(a0, 28, v1); // sw a0, 28(v1) + c->pcpyud(t6, t6, r0); // pcpyud t6, t6, r0 + c->sb(s4, 0, t7); // sb s4, 0(t7) + c->pextlb(s3, r0, s3); // pextlb s3, r0, s3 + c->sb(s4, 0, s0); // sb s4, 0(s0) + c->dsllv(s3, s3, s2); // dsllv s3, s3, s2 + c->lq(t8, 0, s6); // lq t8, 0(s6) + c->paddh(s3, s3, s1); // paddh s3, s3, s1 + c->lbu(t7, 0, t6); // lbu t7, 0(t6) + c->dsrl32(t6, t6, 0); // dsrl32 t6, t6, 0 + c->lw(a0, 12, at); // lw a0, 12(at) + c->pextuh(t0, a1, t1); // pextuh t0, a1, t1 + c->lbu(s0, 0, t6); // lbu s0, 0(t6) + c->pextub(a3, r0, a3); // pextub a3, r0, a3 + c->mov128_vf_gpr(vf4, t9); // qmtc2.ni vf4, t9 + c->pextlh(t2, a1, a3); // pextlh t2, a1, a3 + c->mov128_vf_gpr(vf1, t0); // qmtc2.ni vf1, t0 + c->pextuh(a3, a1, a3); // pextuh a3, a1, a3 + c->mov128_vf_gpr(vf2, t2); // qmtc2.ni vf2, t2 + c->pextlb(t9, r0, t8); // pextlb t9, r0, t8 + c->mov128_vf_gpr(vf3, a3); // qmtc2.ni vf3, a3 + c->pextlh(gp, r0, t9); // pextlh gp, r0, t9 + c->sqc2(vf14, 48, v1); // sqc2 vf14, 48(v1) + c->daddiu(s6, s6, 16); // daddiu s6, s6, 16 + bc = c->sgpr64(s4) != c->sgpr64(s5); // bne s4, s5, L102 + // HERE this one is storing garbage + c->sqc2(vf15, 96, v1); // sqc2 vf15, 96(v1) + if (bc) {goto block_50;} // branch non-likely + + //beq r0, r0, L106 // beq r0, r0, L106 + c->daddiu(v1, v1, 32); // daddiu v1, v1, 32 + goto block_58; // branch always + + + block_56: + //beq r0, r0, L106 // beq r0, r0, L106 + c->daddiu(v1, v1, 64); // daddiu v1, v1, 64 + goto block_58; // branch always + + + block_57: + //beq r0, r0, L106 // beq r0, r0, L106 + c->daddiu(v1, v1, 96); // daddiu v1, v1, 96 + goto block_58; // branch always + + + block_58: + c->sw(a0, 28, v1); // sw a0, 28(v1) + c->daddiu(v1, v1, 32); // daddiu v1, v1, 32 + c->daddiu(s5, s5, 1); // daddiu s5, s5, 1 + // nop // sll r0, r0, 0 + get_fake_spad_addr(a3, cache.fake_scratchpad_data, 0, c);// lui a3, 28672 + // nop // sll r0, r0, 0 + c->lw(a0, 7316, a3); // lw a0, 7316(a3) + // nop // sll r0, r0, 0 + c->lw(a1, 7308, a3); // lw a1, 7308(a3) + // nop // sll r0, r0, 0 + c->lw(a3, 7312, a3); // lw a3, 7312(a3) + // nop // sll r0, r0, 0 + c->lbu(s0, 0, a0); // lbu s0, 0(a0) + c->addiu(s4, r0, 0); // addiu s4, r0, 0 + c->lbu(s1, 7, a0); // lbu s1, 7(a0) + c->addiu(t8, r0, 0); // addiu t8, r0, 0 + c->lbu(s2, 8, a0); // lbu s2, 8(a0) + c->sll(s0, s0, 2); // sll s0, s0, 2 + c->daddu(s0, s0, a0); // daddu s0, s0, a0 + c->sll(s1, s1, 2); // sll s1, s1, 2 + bc = c->sgpr64(s1) == 0; // beq s1, r0, L108 + c->daddu(s1, s1, s0); // daddu s1, s1, s0 + if (bc) {goto block_61;} // branch non-likely + + + block_59: + c->lbu(s3, 0, s0); // lbu s3, 0(s0) + c->daddu(s4, s4, t4); // daddu s4, s4, t4 + c->lbu(s6, 1, s0); // lbu s6, 1(s0) + c->daddu(t8, t8, t4); // daddu t8, t8, t4 + c->lbu(t9, 0, s4); // lbu t9, 0(s4) + c->daddu(s3, s3, t3); // daddu s3, s3, t3 + c->lbu(s4, 0, s3); // lbu s4, 0(s3) + c->daddu(s6, s6, t3); // daddu s6, s6, t3 + c->sb(t9, 0, t8); // sb t9, 0(t8) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + bc = c->sgpr64(s0) != c->sgpr64(s1); // bne s0, s1, L107 + c->lbu(t8, 0, s6); // lbu t8, 0(s6) + if (bc) {goto block_59;} // branch non-likely + + // nop // sll r0, r0, 0 + c->daddu(s4, s4, t4); // daddu s4, s4, t4 + c->lbu(t9, 0, s4); // lbu t9, 0(s4) + c->daddu(t8, t8, t4); // daddu t8, t8, t4 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->sb(t9, 0, t8); // sb t9, 0(t8) + // nop // sll r0, r0, 0 + + block_61: + c->sll(s2, s2, 2); // sll s2, s2, 2 + c->daddiu(t5, a3, 32); // daddiu t5, a3, 32 + bc = c->sgpr64(s2) == 0; // beq s2, r0, L111 + c->daddu(s2, s2, s1); // daddu s2, s2, s1 + if (bc) {goto block_65;} // branch non-likely + + c->lbu(s3, 0, s0); // lbu s3, 0(s0) + c->daddiu(t6, a3, 192); // daddiu t6, a3, 192 + c->lbu(s6, 1, s0); // lbu s6, 1(s0) + c->daddiu(t7, a3, 448); // daddiu t7, a3, 448 + // nop // sll r0, r0, 0 + c->daddu(s3, s3, t6); // daddu s3, s3, t6 + c->lbu(s3, 0, s3); // lbu s3, 0(s3) + c->daddu(s6, s6, t3); // daddu s6, s6, t3 + c->lbu(s6, 0, s6); // lbu s6, 0(s6) + c->daddiu(v1, v1, -32); // daddiu v1, v1, -32 + // nop // sll r0, r0, 0 + c->daddu(s3, s3, t5); // daddu s3, s3, t5 + c->lbu(s4, 0, s3); // lbu s4, 0(s3) + c->daddu(s6, s6, t4); // daddu s6, s6, t4 + // nop // sll r0, r0, 0 + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->sb(s5, 0, s6); // sb s5, 0(s6) + c->daddiu(s5, s5, 1); // daddiu s5, s5, 1 + bc = c->sgpr64(s0) == c->sgpr64(s2); // beq s0, s2, L110 + // nop // sll r0, r0, 0 + if (bc) {goto block_64;} // branch non-likely + + + block_63: + c->lbu(s3, 0, s0); // lbu s3, 0(s0) + c->sll(s4, s4, 5); // sll s4, s4, 5 + c->lbu(s6, 1, s0); // lbu s6, 1(s0) + c->daddu(s4, s4, t7); // daddu s4, s4, t7 + c->lq(t9, 0, s4); // lq t9, 0(s4) + c->daddu(s3, s3, t6); // daddu s3, s3, t6 + c->lbu(s3, 0, s3); // lbu s3, 0(s3) + c->daddu(s6, s6, t3); // daddu s6, s6, t3 + c->lbu(s6, 0, s6); // lbu s6, 0(s6) + c->daddiu(v1, v1, 32); // daddiu v1, v1, 32 + c->lq(gp, 16, s4); // lq gp, 16(s4) + c->daddu(s3, s3, t5); // daddu s3, s3, t5 + c->lbu(s4, 0, s3); // lbu s4, 0(s3) + c->daddu(s6, s6, t4); // daddu s6, s6, t4 + c->sq(t9, 0, v1); // sq t9, 0(v1) + c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 + c->sb(s5, 0, s6); // sb s5, 0(s6) + c->daddiu(s5, s5, 1); // daddiu s5, s5, 1 + bc = c->sgpr64(s0) != c->sgpr64(s2); // bne s0, s2, L109 + c->sq(gp, 16, v1); // sq gp, 16(v1) + if (bc) {goto block_63;} // branch non-likely + + + block_64: + // nop // sll r0, r0, 0 + c->sll(s4, s4, 5); // sll s4, s4, 5 + // nop // sll r0, r0, 0 + c->daddu(s4, s4, t7); // daddu s4, s4, t7 + c->lq(t9, 0, s4); // lq t9, 0(s4) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->daddiu(v1, v1, 32); // daddiu v1, v1, 32 + c->lq(gp, 16, s4); // lq gp, 16(s4) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->sq(t9, 0, v1); // sq t9, 0(v1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->sq(gp, 16, v1); // sq gp, 16(v1) + + block_65: + c->sh(s5, 20, a1); // sh s5, 20(a1) + get_fake_spad_addr(at, cache.fake_scratchpad_data, 0, c);// lui at, 28672 + c->lq(s0, 7392, at); // lq s0, 7392(at) + c->lq(s1, 7408, at); // lq s1, 7408(at) + c->lq(s2, 7424, at); // lq s2, 7424(at) + c->lq(s3, 7440, at); // lq s3, 7440(at) + c->lq(s4, 7456, at); // lq s4, 7456(at) + c->lq(s5, 7472, at); // lq s5, 7472(at) + c->lq(s6, 7488, at); // lq s6, 7488(at) + c->lq(t8, 7504, at); // lq t8, 7504(at) + c->lq(t9, 7520, at); // lq t9, 7520(at) + c->lq(gp, 7536, at); // lq gp, 7536(at) + c->lq(ra, 7584, at); // lq ra, 7584(at) + c->lq(sp, 7552, at); // lq sp, 7552(at) + //jr ra // jr ra + c->lq(fp, 7568, at); // lq fp, 7568(at) + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + gLinkedFunctionTable.reg("mercneric-convert", execute, 256); +} + +} // namespace mercneric_convert +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace high_speed_reject { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* +} cache; + +void vcallms_438(ExecutionContext* c, u16* vis) { + + // nop | mulaz.xyzw ACC, vf09, vf01 158 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf01).vf.z()); + // nop | maddax.xyzw ACC, vf10, vf01 159 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf01].vf.x()); + // nop | maddy.xyzw vf01, vf11, vf01 160 + u16 f1 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf01].vf, c->vf_src(vf11).vf, c->vf_src(vf01).vf.y()); + // nop | mulaz.xyzw ACC, vf09, vf02 161 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf02).vf.z()); + // nop | maddax.xyzw ACC, vf10, vf02 162 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf02].vf.x()); + // nop | maddy.xyzw vf02, vf11, vf02 163 + u16 f2 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf02].vf, c->vf_src(vf11).vf, c->vf_src(vf02).vf.y()); + // fmand vi01, vi09 | mulaz.xyzw ACC, vf09, vf03 164 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf03).vf.z()); vis[1] = vis[9] & f1; + // nop | maddax.xyzw ACC, vf10, vf03 165 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf03].vf.x()); + // nop | maddy.xyzw vf03, vf11, vf03 166 + u16 f3 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf03].vf, c->vf_src(vf11).vf, c->vf_src(vf03).vf.y()); + // fmand vi02, vi09 | mulaz.xyzw ACC, vf09, vf04 167 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf04).vf.z()); vis[2] = vis[9] & f2; + // nop | maddax.xyzw ACC, vf10, vf04 168 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf04].vf.x()); + // nop | maddy.xyzw vf04, vf11, vf04 169 + c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf04].vf, c->vf_src(vf11).vf, c->vf_src(vf04).vf.y()); + // fmand vi03, vi09 | nop 170 + // ASSERT(false); + vis[3] = vis[9] & f3; + // nop | nop 171 + + // nop | nop :e 172 + + // fmand vi04, vi09 | nop 173 + // ASSERT(false); + vis[4] = vis[9] & f4; + +} + +void vcallms_454(ExecutionContext* c, u16* vis) { + // nop | mulaz.xyzw ACC, vf09, vf05 174 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf05).vf.z()); + // nop | maddax.xyzw ACC, vf10, vf05 175 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf05].vf.x()); + // nop | maddy.xyzw vf05, vf11, vf05 176 + u16 f1 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf05].vf, c->vf_src(vf11).vf, c->vf_src(vf05).vf.y()); + // nop | mulaz.xyzw ACC, vf09, vf06 177 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf06).vf.z()); + // nop | maddax.xyzw ACC, vf10, vf06 178 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf06].vf.x()); + // nop | maddy.xyzw vf06, vf11, vf06 179 + u16 f2 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf06].vf, c->vf_src(vf11).vf, c->vf_src(vf06).vf.y()); + // fmand vi05, vi09 | mulaz.xyzw ACC, vf09, vf07 180 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf07).vf.z()); vis[5] = vis[9] & f1; + // nop | maddax.xyzw ACC, vf10, vf07 181 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf07].vf.x()); + // nop | maddy.xyzw vf07, vf11, vf07 182 + u16 f3 = c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf07].vf, c->vf_src(vf11).vf, c->vf_src(vf07).vf.y()); + // fmand vi06, vi09 | mulaz.xyzw ACC, vf09, vf08 183 + c->acc.vf.mula(Mask::xyzw, c->vf_src(vf09).vf, c->vf_src(vf08).vf.z()); vis[5] = vis[9] & f2; + // nop | maddax.xyzw ACC, vf10, vf08 184 + c->acc.vf.madda(Mask::xyzw, c->vfs[vf10].vf, c->vfs[vf08].vf.x()); + // nop | maddy.xyzw vf08, vf11, vf08 185 + u16 f4 =c->acc.vf.madd_flag(Mask::xyzw, c->vfs[vf08].vf, c->vf_src(vf11).vf, c->vf_src(vf08).vf.y()); + // fmand vi07, vi09 | nop 186 + vis[7] = vis[9] & f3; + // nop | nop 187 + + // nop | nop :e 188 + + // fmand vi08, vi09 | nop 189 + // ASSERT(false); + vis[8] = vis[9] & f4; + +} + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u16 vis[16]; + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->lw(a0, 7308, v1); // lw a0, 7308(v1) + c->daddiu(a1, a0, 448); // daddiu a1, a0, 448 + c->lhu(a3, 20, a0); // lhu a3, 20(a0) + c->vmax_bc(DEST::xyzw, BC::w, vf9, vf0, vf0); // vmaxw.xyzw vf9, vf0, vf0 + c->lqc2(vf10, 7360, v1); // lqc2 vf10, 7360(v1) + c->lqc2(vf11, 7376, v1); // lqc2 vf11, 7376(v1) + c->lqc2(vf1, 0, a1); // lqc2 vf1, 0(a1) + c->addiu(a0, r0, 240); // addiu a0, r0, 240 + c->lqc2(vf2, 32, a1); // lqc2 vf2, 32(a1) + vis[9] = c->gpr_src(a0).du16[0]; // ctc2.i vi9, a0 + c->lqc2(vf3, 64, a1); // lqc2 vf3, 64(a1) + c->lqc2(vf4, 96, a1); // lqc2 vf4, 96(a1) + c->daddiu(a0, r0, -1); // daddiu a0, r0, -1 + // nop // sll r0, r0, 0 + // Unknown instr: vcallms 438 + vcallms_438(c, vis); + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->lqc2(vf5, 128, a1); // lqc2 vf5, 128(a1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->lqc2(vf6, 160, a1); // lqc2 vf6, 160(a1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->lwu(t0, 8, a1); // lwu t0, 8(a1) + c->lqc2(vf7, 192, a1); // lqc2 vf7, 192(a1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + c->gprs[a2].du64[0] = vis[1]; // cfc2.ni a2, vi1 + c->lqc2(vf8, 224, a1); // lqc2 vf8, 224(a1) + c->srl(t0, t0, 31); // srl t0, t0, 31 + c->or_(t0, a2, t0); // or t0, a2, t0 + c->lwu(a2, 40, a1); // lwu a2, 40(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L71 + c->and_(a0, a0, t0); // and a0, a0, t0 + if (bc) {goto block_20;} // branch non-likely + + c->daddiu(a1, a1, 128); // daddiu a1, a1, 128 + c->daddiu(a3, a3, -1); // daddiu a3, a3, -1 + bc = c->sgpr64(a3) == 0; // beq a3, r0, L70 + c->gprs[t0].du64[0] = vis[2]; // cfc2.ni t0, vi2 + if (bc) {goto block_18;} // branch non-likely + + + block_2: + // Unknown instr: vcallms 454 + vcallms_454(c, vis); + c->srl(a2, a2, 31); // srl a2, a2, 31 + c->or_(a2, t0, a2); // or a2, t0, a2 + c->lwu(t0, -56, a1); // lwu t0, -56(a1) + bc = c->sgpr64(a2) == 0; // beq a2, r0, L71 + c->and_(a0, a0, a2); // and a0, a0, a2 + if (bc) {goto block_20;} // branch non-likely + + c->lqc2(vf1, 128, a1); // lqc2 vf1, 128(a1) + c->daddiu(a2, a3, -1); // daddiu a2, a3, -1 + bc = c->sgpr64(a2) == 0; // beq a2, r0, L70 + c->gprs[a3].du64[0] = vis[3]; // cfc2.ni a3, vi3 + if (bc) {goto block_18;} // branch non-likely + + c->daddiu(a2, a2, -1); // daddiu a2, a2, -1 + c->srl(t0, t0, 31); // srl t0, t0, 31 + c->or_(t0, a3, t0); // or t0, a3, t0 + c->lwu(a3, -24, a1); // lwu a3, -24(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L71 + c->and_(a0, a0, t0); // and a0, a0, t0 + if (bc) {goto block_20;} // branch non-likely + + bc = c->sgpr64(a2) == 0; // beq a2, r0, L70 + c->gprs[t0].du64[0] = vis[4]; // cfc2.ni t0, vi4 + if (bc) {goto block_18;} // branch non-likely + + c->lqc2(vf2, 160, a1); // lqc2 vf2, 160(a1) + c->srl(a3, a3, 31); // srl a3, a3, 31 + c->or_(t0, t0, a3); // or t0, t0, a3 + c->lwu(a3, 8, a1); // lwu a3, 8(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L71 + c->and_(a0, a0, t0); // and a0, a0, t0 + if (bc) {goto block_20;} // branch non-likely + + c->lqc2(vf3, 192, a1); // lqc2 vf3, 192(a1) + c->daddiu(a2, a2, -1); // daddiu a2, a2, -1 + bc = c->sgpr64(a2) == 0; // beq a2, r0, L70 + c->gprs[t0].du64[0] = vis[5]; // cfc2.ni t0, vi5 + if (bc) {goto block_18;} // branch non-likely + + c->lqc2(vf4, 224, a1); // lqc2 vf4, 224(a1) + c->srl(a3, a3, 31); // srl a3, a3, 31 + c->or_(t0, t0, a3); // or t0, t0, a3 + c->lwu(a3, 40, a1); // lwu a3, 40(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L71 + c->and_(a0, a0, t0); // and a0, a0, t0 + if (bc) {goto block_20;} // branch non-likely + + c->daddiu(a1, a1, 128); // daddiu a1, a1, 128 + c->daddiu(a2, a2, -1); // daddiu a2, a2, -1 + bc = c->sgpr64(a2) == 0; // beq a2, r0, L70 + c->gprs[t0].du64[0] = vis[6]; // cfc2.ni t0, vi6 + if (bc) {goto block_18;} // branch non-likely + + // Unknown instr: vcallms 438 + vcallms_438(c, vis); + c->srl(a3, a3, 31); // srl a3, a3, 31 + c->or_(t0, t0, a3); // or t0, t0, a3 + c->lwu(a3, -56, a1); // lwu a3, -56(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L71 + c->and_(a0, a0, t0); // and a0, a0, t0 + if (bc) {goto block_20;} // branch non-likely + + c->lqc2(vf5, 128, a1); // lqc2 vf5, 128(a1) + c->daddiu(a2, a2, -1); // daddiu a2, a2, -1 + bc = c->sgpr64(a2) == 0; // beq a2, r0, L70 + c->gprs[t0].du64[0] = vis[7]; // cfc2.ni t0, vi7 + if (bc) {goto block_18;} // branch non-likely + + c->daddiu(a2, a2, -1); // daddiu a2, a2, -1 + c->srl(a3, a3, 31); // srl a3, a3, 31 + c->or_(t0, t0, a3); // or t0, t0, a3 + c->lwu(a3, -24, a1); // lwu a3, -24(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L71 + c->and_(a0, a0, t0); // and a0, a0, t0 + if (bc) {goto block_20;} // branch non-likely + + bc = c->sgpr64(a2) == 0; // beq a2, r0, L70 + c->gprs[t0].du64[0] = vis[8]; // cfc2.ni t0, vi8 + if (bc) {goto block_18;} // branch non-likely + + c->lqc2(vf6, 160, a1); // lqc2 vf6, 160(a1) + c->srl(a3, a3, 31); // srl a3, a3, 31 + c->or_(a3, t0, a3); // or a3, t0, a3 + c->lwu(t0, 8, a1); // lwu t0, 8(a1) + bc = c->sgpr64(a3) == 0; // beq a3, r0, L71 + c->and_(a0, a0, a3); // and a0, a0, a3 + if (bc) {goto block_20;} // branch non-likely + + c->lqc2(vf7, 192, a1); // lqc2 vf7, 192(a1) + c->daddiu(a3, a2, -1); // daddiu a3, a2, -1 + bc = c->sgpr64(a3) == 0; // beq a3, r0, L70 + c->gprs[a2].du64[0] = vis[1]; // cfc2.ni a2, vi1 + if (bc) {goto block_18;} // branch non-likely + + c->lqc2(vf8, 224, a1); // lqc2 vf8, 224(a1) + c->srl(t0, t0, 31); // srl t0, t0, 31 + c->or_(t0, a2, t0); // or t0, a2, t0 + c->lwu(a2, 40, a1); // lwu a2, 40(a1) + bc = c->sgpr64(t0) == 0; // beq t0, r0, L71 + c->and_(a0, a0, t0); // and a0, a0, t0 + if (bc) {goto block_20;} // branch non-likely + + c->daddiu(a1, a1, 128); // daddiu a1, a1, 128 + c->daddiu(a3, a3, -1); // daddiu a3, a3, -1 + bc = c->sgpr64(a3) != 0; // bne a3, r0, L69 + c->gprs[t0].du64[0] = vis[2]; // cfc2.ni t0, vi2 + if (bc) {goto block_2;} // branch non-likely + + + block_18: + bc = c->sgpr64(a0) == 0; // beq a0, r0, L71 + // nop // sll r0, r0, 0 + if (bc) {goto block_20;} // branch non-likely + + c->sb(r0, 6773, v1); // sb r0, 6773(v1) + + block_20: + //jr ra // jr ra + // nop // sll r0, r0, 0 + goto end_of_function; // return + + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + gLinkedFunctionTable.reg("high-speed-reject", execute, 128); +} + +} // namespace high_speed_reject +} // namespace Mips2C + + + diff --git a/game/mips2c/functions/ripple.cpp b/game/mips2c/functions/ripple.cpp new file mode 100644 index 0000000000..fc768aed81 --- /dev/null +++ b/game/mips2c/functions/ripple.cpp @@ -0,0 +1,580 @@ + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { + +struct RippleVu0 { + Vf data_mem[256]; + void sq(const Vf& reg, u16 addr) { + ASSERT(addr < 256); + data_mem[addr] = reg; + } + Vf lq(u16 addr) { + ASSERT(addr < 256); + return data_mem[addr]; + } +} gRippleVu0; + +namespace ripple_execute_init { +struct Cache { + void* cos_poly_vec; // *cos-poly-vec* +} cache; + +// clang-format off +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 + c->sd(fp, 8, sp); // sd fp, 8(sp) + c->mov64(fp, t9); // or fp, t9, r0 + c->load_symbol(v1, cache.cos_poly_vec); // lw v1, *cos-poly-vec*(s7) + c->lqc2(vf7, 0, v1); // lqc2 vf7, 0(v1) + c->fprs[f0] = 0.024543691; // lwc1 f0, L50(fp) + c->mfc1(v1, f0); // mfc1 v1, f0 + c->mov128_vf_gpr(vf6, v1); // qmtc2.i vf6, v1 + c->mov128_gpr_vf(v1, vf6); // qmfc2.i v1, vf6 + c->addiu(v1, r0, 128); // addiu v1, r0, 128 + u16 vi2 = c->gpr_src(v1).du16[0]; // ctc2.i vi2, v1 + c->gprs[v1].du64[0] = vi2; // cfc2.i v1, vi2 + c->fprs[f0] = 1.0; // lwc1 f0, L61(fp) + c->mfc1(v1, f0); // mfc1 v1, f0 + c->mov128_vf_gpr(vf9, v1); // qmtc2.i vf9, v1 + c->mov128_gpr_vf(v1, vf9); // qmfc2.i v1, vf9 + u16 vi1 = 0; // viaddi vi1, vi0, 0 + c->addiu(v1, r0, 128); // addiu v1, r0, 128 + c->vmove(DEST::xyzw, vf5, vf6); // vmove.xyzw vf5, vf6 + + block_1: + c->vmul(DEST::xyzw, vf1, vf5, vf5); // vmul.xyzw vf1, vf5, vf5 + c->vadda_bc(DEST::xyzw, BC::w, vf0, vf0); // vaddaw.xyzw acc, vf0, vf0 + c->vadd(DEST::x, vf5, vf5, vf6); // vadd.x vf5, vf5, vf6 + c->vsub_bc(DEST::y, BC::x, vf9, vf0, vf9); // vsubx.y vf9, vf0, vf9 + c->vmul(DEST::xyzw, vf2, vf1, vf1); // vmul.xyzw vf2, vf1, vf1 + c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf7); // vmaddax.xyzw acc, vf1, vf7 + c->vmul(DEST::xyzw, vf3, vf2, vf1); // vmul.xyzw vf3, vf2, vf1 + c->vmadda_bc(DEST::xyzw, BC::y, vf2, vf7); // vmadday.xyzw acc, vf2, vf7 + c->vmul(DEST::xyzw, vf4, vf2, vf2); // vmul.xyzw vf4, vf2, vf2 + c->vmadda_bc(DEST::xyzw, BC::z, vf3, vf7); // vmaddaz.xyzw acc, vf3, vf7 + c->daddiu(v1, v1, -1); // daddiu v1, v1, -1 + c->vmadd_bc(DEST::xyzw, BC::w, vf8, vf4, vf7); // vmaddw.xyzw vf8, vf4, vf7 + c->vadd_bc(DEST::y, BC::x, vf9, vf9, vf8); // vaddx.y vf9, vf9, vf8 + c->vsub(DEST::xyzw, vf10, vf0, vf9); // vsub.xyzw vf10, vf0, vf9 + gRippleVu0.sq(c->vfs[vf9].vf, vi1++); // vsqi.xyzw vf9, vi1 + c->vmove(DEST::xyzw, vf9, vf8); // vmove.xyzw vf9, vf8 + bc = c->sgpr64(v1) != 0; // bne v1, r0, L39 + gRippleVu0.sq(c->vfs[vf10].vf, vi2++); // vsqi.xyzw vf10, vi2 + if (bc) {goto block_1;} // branch non-likely + + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + c->ld(fp, 8, sp); // ld fp, 8(sp) + //jr ra // jr ra + c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.cos_poly_vec = intern_from_c("*cos-poly-vec*").c(); + gLinkedFunctionTable.reg("ripple-execute-init", execute, 32); +} + +} // namespace ripple_execute_init +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace ripple_create_wave_table { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* + void* setting_control; // *setting-control* + void* atan; // atan + void* cos; // cos + void* ntsc; // ntsc + void* pal; // pal + void* ripple_update_waveform_offs; // ripple-update-waveform-offs + void* sin; // sin +} cache; + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + u16 vi1, vi2; + u32 call_addr = 0; + c->daddiu(sp, sp, -80); // daddiu sp, sp, -80 + c->sd(ra, 0, sp); // sd ra, 0(sp) + c->sd(fp, 8, sp); // sd fp, 8(sp) + c->mov64(fp, t9); // or fp, t9, r0 + c->sq(s4, 16, sp); // sq s4, 16(sp) + c->sq(s5, 32, sp); // sq s5, 32(sp) + c->sq(gp, 48, sp); // sq gp, 48(sp) + c->swc1(f28, 64, sp); // swc1 f28, 64(sp) + c->swc1(f30, 68, sp); // swc1 f30, 68(sp) + c->mov64(gp, a0); // or gp, a0, r0 + c->lwu(v1, 4, gp); // lwu v1, 4(gp) + bc = c->sgpr64(s7) != c->sgpr64(v1); // bne s7, v1, L30 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_9;} // branch non-likely + + c->addiu(s5, r0, 0); // addiu s5, r0, 0 + //beq r0, r0, L29 // beq r0, r0, L29 + // nop // sll r0, r0, 0 + goto block_7; // branch always + + + block_2: + c->addiu(v1, r0, 28); // addiu v1, r0, 28 + c->mult3(v1, v1, s5); // mult3 v1, v1, s5 + c->daddiu(v1, v1, 16); // daddiu v1, v1, 16 + c->daddu(s4, v1, gp); // daddu s4, v1, gp + c->load_symbol(t9, cache.atan); // lw t9, atan(s7) + c->lh(v1, 10, s4); // lh v1, 10(s4) + c->mtc1(f0, v1); // mtc1 f0, v1 + c->cvtsw(f0, f0); // cvt.s.w f0, f0 + c->mfc1(a0, f0); // mfc1 a0, f0 + c->lh(v1, 8, s4); // lh v1, 8(s4) + c->mtc1(f0, v1); // mtc1 f0, v1 + c->cvtsw(f0, f0); // cvt.s.w f0, f0 + c->mfc1(a1, f0); // mfc1 a1, f0 + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->mtc1(f28, v0); // mtc1 f28, v0 + c->fprs[f0] = 16.0; // lwc1 f0, L60(fp) + c->lh(v1, 8, s4); // lh v1, 8(s4) + c->lh(a0, 8, s4); // lh a0, 8(s4) + c->mult3(v1, v1, a0); // mult3 v1, v1, a0 + c->lh(a0, 10, s4); // lh a0, 10(s4) + c->lh(a1, 10, s4); // lh a1, 10(s4) + c->mult3(a0, a0, a1); // mult3 a0, a0, a1 + c->daddu(v1, v1, a0); // daddu v1, v1, a0 + c->mtc1(f1, v1); // mtc1 f1, v1 + c->cvtsw(f1, f1); // cvt.s.w f1, f1 + c->sqrts(f1, f1); // sqrt.s f1, f1 + c->divs(f30, f0, f1); // div.s f30, f0, f1 + c->load_symbol(t9, cache.cos); // lw t9, cos(s7) + c->mfc1(a0, f28); // mfc1 a0, f28 + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->mtc1(f0, v0); // mtc1 f0, v0 + c->fprs[f1] = 65536.0; // lwc1 f1, L52(fp) + c->divs(f1, f1, f30); // div.s f1, f1, f30 + c->muls(f0, f0, f1); // mul.s f0, f0, f1 + c->swc1(f0, 16, s4); // swc1 f0, 16(s4) + c->load_symbol(t9, cache.sin); // lw t9, sin(s7) + c->mfc1(a0, f28); // mfc1 a0, f28 + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + c->mtc1(f0, v0); // mtc1 f0, v0 + c->fprs[f1] = 65536.0; // lwc1 f1, L52(fp) + c->divs(f1, f1, f30); // div.s f1, f1, f30 + c->muls(f0, f0, f1); // mul.s f0, f0, f1 + c->swc1(f0, 20, s4); // swc1 f0, 20(s4) + c->load_symbol(v1, cache.setting_control); // lw v1, *setting-control*(s7) + c->lwu(v1, 80, v1); // lwu v1, 80(v1) + c->load_symbol_addr(a0, cache.ntsc); // daddiu a0, s7, ntsc + bc = c->sgpr64(v1) != c->sgpr64(a0); // bne v1, a0, L27 + c->mov64(a0, s7); // or a0, s7, r0 + if (bc) {goto block_4;} // branch non-likely + + c->fprs[f0] = 0.016666668; // lwc1 f0, L55(fp) + c->fprs[f1] = -65536.0; // lwc1 f1, L53(fp) + c->divs(f1, f1, f30); // div.s f1, f1, f30 + c->muls(f0, f0, f1); // mul.s f0, f0, f1 + c->lwc1(f1, 12, s4); // lwc1 f1, 12(s4) + c->muls(f0, f0, f1); // mul.s f0, f0, f1 + c->swc1(f0, 24, s4); // swc1 f0, 24(s4) + c->mfc1(v1, f0); // mfc1 v1, f0 + //beq r0, r0, L28 // beq r0, r0, L28 + // nop // sll r0, r0, 0 + goto block_6; // branch always + + + block_4: + c->load_symbol_addr(a0, cache.pal); // daddiu a0, s7, pal + bc = c->sgpr64(v1) != c->sgpr64(a0); // bne v1, a0, L28 + c->mov64(v1, s7); // or v1, s7, r0 + if (bc) {goto block_6;} // branch non-likely + + c->fprs[f0] = 0.02; // lwc1 f0, L51(fp) + c->fprs[f1] = -65536.0; // lwc1 f1, L53(fp) + c->divs(f1, f1, f30); // div.s f1, f1, f30 + c->muls(f0, f0, f1); // mul.s f0, f0, f1 + c->lwc1(f1, 12, s4); // lwc1 f1, 12(s4) + c->muls(f0, f0, f1); // mul.s f0, f0, f1 + c->swc1(f0, 24, s4); // swc1 f0, 24(s4) + c->mfc1(v1, f0); // mfc1 v1, f0 + + block_6: + c->daddiu(s5, s5, 1); // daddiu s5, s5, 1 + + block_7: + c->lw(v1, 0, gp); // lw v1, 0(gp) + c->slt(v1, s5, v1); // slt v1, s5, v1 + bc = c->sgpr64(v1) != 0; // bne v1, r0, L26 + // nop // sll r0, r0, 0 + if (bc) {goto block_2;} // branch non-likely + + c->mov64(v1, s7); // or v1, s7, r0 + c->mov64(v1, s7); // or v1, s7, r0 + c->daddiu(v1, s7, 8); // daddiu v1, s7, #t + c->sw(v1, 4, gp); // sw v1, 4(gp) + + block_9: + c->load_symbol(t9, cache.ripple_update_waveform_offs);// lw t9, ripple-update-waveform-offs(s7) + c->mov64(a0, gp); // or a0, gp, r0 + call_addr = c->gprs[t9].du32[0]; // function call: + c->sll(v0, ra, 0); // sll v0, ra, 0 + c->jalr(call_addr); // jalr ra, t9 + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->addiu(a0, r0, 64); // addiu a0, r0, 64 + c->mov64(a1, v1); // or a1, v1, r0 + + block_10: + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + c->sq(r0, 0, a1); // sq r0, 0(a1) + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + bc = c->sgpr64(a0) != 0; // bne a0, r0, L31 + c->daddiu(a1, a1, 16); // daddiu a1, a1, 16 + if (bc) {goto block_10;} // branch non-likely + + c->addiu(a0, r0, 0); // addiu a0, r0, 0 + //beq r0, r0, L35 // beq r0, r0, L35 + // nop // sll r0, r0, 0 + goto block_17; // branch always + + + block_12: + c->addiu(a1, r0, 28); // addiu a1, r0, 28 + c->mult3(a1, a1, a0); // mult3 a1, a1, a0 + c->daddiu(a1, a1, 16); // daddiu a1, a1, 16 + c->daddu(a1, a1, gp); // daddu a1, a1, gp + c->fprs[f0] = 16384.0; // lwc1 f0, L54(fp) + c->fprs[f1] = 0.00390625; // lwc1 f1, L63(fp) + c->lwc1(f2, 4, a1); // lwc1 f2, 4(a1) + c->muls(f1, f1, f2); // mul.s f1, f1, f2 + c->adds(f0, f0, f1); // add.s f0, f0, f1 + c->fprs[f1] = 0.00390625; // lwc1 f1, L63(fp) + c->lwc1(f2, 16, a1); // lwc1 f2, 16(a1) + c->muls(f1, f1, f2); // mul.s f1, f1, f2 + c->fprs[f2] = 0.00390625; // lwc1 f2, L63(fp) + c->lwc1(f3, 20, a1); // lwc1 f3, 20(a1) + c->muls(f2, f2, f3); // mul.s f2, f2, f3 + c->lwc1(f3, 0, a1); // lwc1 f3, 0(a1) + c->addiu(a1, r0, 255); // addiu a1, r0, 255 + c->mfc1(a2, f0); // mfc1 a2, f0 + c->mov128_vf_gpr(vf1, a2); // qmtc2.i vf1, a2 + c->mfc1(a2, f1); // mfc1 a2, f1 + c->mov128_vf_gpr(vf2, a2); // qmtc2.i vf2, a2 + c->mfc1(a2, f2); // mfc1 a2, f2 + c->mov128_vf_gpr(vf3, a2); // qmtc2.i vf3, a2 + c->mfc1(a2, f3); // mfc1 a2, f3 + c->mov128_vf_gpr(vf4, a2); // qmtc2.i vf4, a2 + vi1 = c->gpr_src(a1).du16[0]; // ctc2.i vi1, a1 + c->mov64(a1, v1); // or a1, v1, r0 + c->addiu(a2, r0, 16); // addiu a2, r0, 16 + c->vmove(DEST::xyzw, vf6, vf0); // vmove.xyzw vf6, vf0 + + block_13: + c->addiu(a3, r0, 16); // addiu a3, r0, 16 + c->vmove(DEST::xyzw, vf5, vf0); // vmove.xyzw vf5, vf0 + + block_14: + c->lw(at, 0, a1); // lw at, 0(a1) + c->vadda_bc(DEST::xyzw, BC::x, vf1, vf0); // vaddax.xyzw acc, vf1, vf0 + c->vmadda(DEST::xyzw, vf2, vf5); // vmadda.xyzw acc, vf2, vf5 + c->vmadd(DEST::xyzw, vf7, vf3, vf6); // vmadd.xyzw vf7, vf3, vf6 + c->mov128_vf_gpr(vf10, at); // qmtc2.i vf10, at + c->vadd_bc(DEST::xyzw, BC::w, vf5, vf5, vf0); // vaddw.xyzw vf5, vf5, vf0 + c->vftoi0(DEST::xyzw, vf8, vf7); // vftoi0.xyzw vf8, vf7 + vi2 = c->vfs[vf8].vf.x_as_u16(); // vmtirx vi2, vf8 + c->vitof0(DEST::xyzw, vf8, vf8); // vitof0.xyzw vf8, vf8 + vi2 &= vi1; // Unknown instr: viand vi2, vi2, vi1 + c->vfs[vf9].vf = gRippleVu0.lq(vi2++); // Unknown instr: vlqi.xyzw vf9, vi2 + c->vsub(DEST::xyzw, vf7, vf7, vf8); // vsub.xyzw vf7, vf7, vf8 + c->vadda_bc(DEST::xyzw, BC::x, vf0, vf9); // vaddax.xyzw acc, vf0, vf9 + c->vmadd_bc(DEST::xyzw, BC::y, vf9, vf7, vf9); // vmaddy.xyzw vf9, vf7, vf9 + c->vadda_bc(DEST::xyzw, BC::x, vf10, vf0); // vaddax.xyzw acc, vf10, vf0 + c->vmadd(DEST::xyzw, vf10, vf9, vf4); // vmadd.xyzw vf10, vf9, vf4 + c->mov128_gpr_vf(at, vf10); // qmfc2.i at, vf10 + c->sw(at, 0, a1); // sw at, 0(a1) + c->daddiu(a3, a3, -1); // daddiu a3, a3, -1 + bc = c->sgpr64(a3) != 0; // bne a3, r0, L34 + c->daddiu(a1, a1, 4); // daddiu a1, a1, 4 + if (bc) {goto block_14;} // branch non-likely + + c->daddiu(a2, a2, -1); // daddiu a2, a2, -1 + bc = c->sgpr64(a2) != 0; // bne a2, r0, L33 + c->vadd_bc(DEST::xyzw, BC::w, vf6, vf6, vf0); // vaddw.xyzw vf6, vf6, vf0 + if (bc) {goto block_13;} // branch non-likely + + c->mov128_gpr_vf(a1, vf6); // qmfc2.i a1, vf6 + c->daddiu(a0, a0, 1); // daddiu a0, a0, 1 + + block_17: + c->lw(a1, 0, gp); // lw a1, 0(gp) + c->slt(a1, a0, a1); // slt a1, a0, a1 + bc = c->sgpr64(a1) != 0; // bne a1, r0, L32 + // nop // sll r0, r0, 0 + if (bc) {goto block_12;} // branch non-likely + + c->mov64(a0, s7); // or a0, s7, r0 + c->mov64(a0, s7); // or a0, s7, r0 + c->fprs[f1] = 128.0; // lwc1 f1, L57(fp) + c->fprs[f0] = 255.0; // lwc1 f0, L56(fp) + c->lwc1(f2, 12, gp); // lwc1 f2, 12(gp) + c->mfc1(a0, f2); // mfc1 a0, f2 + c->mov128_vf_gpr(vf16, a0); // qmtc2.i vf16, a0 + c->mfc1(a0, f1); // mfc1 a0, f1 + c->mov128_vf_gpr(vf14, a0); // qmtc2.i vf14, a0 + c->mfc1(a0, f0); // mfc1 a0, f0 + c->mov128_vf_gpr(vf15, a0); // qmtc2.i vf15, a0 + c->vmax_bc(DEST::xyzw, BC::x, vf16, vf0, vf16); // vmaxx.xyzw vf16, vf0, vf16 + c->vmini_bc(DEST::w, BC::x, vf16, vf0, vf0); // vminix.w vf16, vf0, vf0 + c->mov64(v1, v1); // or v1, v1, r0 + c->addiu(v0, r0, 15); // addiu v0, r0, 15 + + block_19: + c->addiu(a0, r0, 15); // addiu a0, r0, 15 + // nop // sll r0, r0, 0 + + block_20: + c->addiu(a2, r0, 4); // addiu a2, r0, 4 + c->addiu(at, r0, -60); // addiu at, r0, -60 + c->movz(a2, at, a0); // movz a2, at, a0 + c->addiu(a1, r0, 64); // addiu a1, r0, 64 + c->addiu(at, r0, -960); // addiu at, r0, -960 + c->daddu(a2, a2, v1); // daddu a2, a2, v1 + c->movz(a1, at, v0); // movz a1, at, v0 + c->lw(at, 0, v1); // lw at, 0(v1) + c->lw(a2, 0, a2); // lw a2, 0(a2) + c->daddu(a1, a1, v1); // daddu a1, a1, v1 + c->lw(a1, 0, a1); // lw a1, 0(a1) + c->mov128_vf_gpr(vf11, at); // qmtc2.i vf11, at + c->mov128_vf_gpr(vf12, a2); // qmtc2.i vf12, a2 + c->mov128_vf_gpr(vf13, a1); // qmtc2.i vf13, a1 + c->vadd_bc(DEST::xyzw, BC::x, vf11, vf0, vf11); // vaddx.xyzw vf11, vf0, vf11 + c->vsub_bc(DEST::y, BC::x, vf11, vf11, vf12); // vsubx.y vf11, vf11, vf12 + c->vsub_bc(DEST::z, BC::x, vf11, vf11, vf13); // vsubx.z vf11, vf11, vf13 + c->vmul(DEST::yzw, vf11, vf11, vf16); // vmul.yzw vf11, vf11, vf16 + c->vadd_bc(DEST::xyzw, BC::x, vf11, vf11, vf14); // vaddx.xyzw vf11, vf11, vf14 + c->vmax_bc(DEST::xyzw, BC::x, vf11, vf11, vf0); // vmaxx.xyzw vf11, vf11, vf0 + c->vmini_bc(DEST::xyzw, BC::x, vf11, vf11, vf15); // vminix.xyzw vf11, vf11, vf15 + c->vftoi0(DEST::xyzw, vf11, vf11); // vftoi0.xyzw vf11, vf11 + c->mov128_gpr_vf(at, vf11); // qmfc2.i at, vf11 + c->ppach(at, at, at); // ppach at, at, at + c->ppacb(at, at, at); // ppacb at, at, at + c->sw(at, 1024, v1); // sw at, 1024(v1) + c->daddiu(v1, v1, 4); // daddiu v1, v1, 4 + bc = c->sgpr64(a0) != 0; // bne a0, r0, L37 + c->daddiu(a0, a0, -1); // daddiu a0, a0, -1 + if (bc) {goto block_20;} // branch non-likely + + bc = c->sgpr64(v0) != 0; // bne v0, r0, L36 + c->daddiu(v0, v0, -1); // daddiu v0, v0, -1 + if (bc) {goto block_19;} // branch non-likely + + c->ld(ra, 0, sp); // ld ra, 0(sp) + c->ld(fp, 8, sp); // ld fp, 8(sp) + c->lwc1(f30, 68, sp); // lwc1 f30, 68(sp) + c->lwc1(f28, 64, sp); // lwc1 f28, 64(sp) + c->lq(gp, 48, sp); // lq gp, 48(sp) + c->lq(s5, 32, sp); // lq s5, 32(sp) + c->lq(s4, 16, sp); // lq s4, 16(sp) + //jr ra // jr ra + c->daddiu(sp, sp, 80); // daddiu sp, sp, 80 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + cache.setting_control = intern_from_c("*setting-control*").c(); + cache.atan = intern_from_c("atan").c(); + cache.cos = intern_from_c("cos").c(); + cache.ntsc = intern_from_c("ntsc").c(); + cache.pal = intern_from_c("pal").c(); + cache.ripple_update_waveform_offs = intern_from_c("ripple-update-waveform-offs").c(); + cache.sin = intern_from_c("sin").c(); + gLinkedFunctionTable.reg("ripple-create-wave-table", execute, 128); +} + +} // namespace ripple_create_wave_table +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace ripple_apply_wave_table { +struct Cache { + void* fake_scratchpad_data; // *fake-scratchpad-data* +} cache; + +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + + bool bc = false; + get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 + c->daddiu(v1, v1, 1024); // daddiu v1, v1, 1024 + c->lwu(a1, 4, a0); // lwu a1, 4(a0) + c->lwu(t2, 0, a0); // lwu t2, 0(a0) + c->lwu(a2, 8, a0); // lwu a2, 8(a0) + c->lwu(a3, 12, a0); // lwu a3, 12(a0) + c->lhu(a0, 18, a0); // lhu a0, 18(a0) + c->addiu(t0, r0, 0); // addiu t0, r0, 0 + //beq r0, r0, L24 // beq r0, r0, L24 + // nop // sll r0, r0, 0 + goto block_4; // branch always + + + block_1: + c->lbu(t1, 0, a3); // lbu t1, 0(a3) + c->lbu(t3, 0, a1); // lbu t3, 0(a1) + c->daddiu(t3, t3, 3); // daddiu t3, t3, 3 + c->dsrl(t3, t3, 2); // dsrl t3, t3, 2 + c->dsll(t3, t3, 4); // dsll t3, t3, 4 + c->daddu(t2, t2, t3); // daddu t2, t2, t3 + c->mov64(t4, t2); // or t4, t2, r0 + c->mov64(t3, t1); // or t3, t1, r0 + c->mov64(t5, t4); // or t5, t4, r0 + c->mov64(t4, a2); // or t4, a2, r0 + + block_2: + c->lb(t6, 0, t4); // lb t6, 0(t4) + c->lb(t7, 1, t4); // lb t7, 1(t4) + c->andi(t6, t6, 15); // andi t6, t6, 15 + c->andi(t7, t7, 15); // andi t7, t7, 15 + c->sll(t7, t7, 4); // sll t7, t7, 4 + c->daddu(t6, t6, t7); // daddu t6, t6, t7 + c->sll(t6, t6, 2); // sll t6, t6, 2 + c->daddu(t8, t6, v1); // daddu t8, t6, v1 + c->lb(t6, 0, t8); // lb t6, 0(t8) + c->lb(t7, 1, t8); // lb t7, 1(t8) + c->lb(t8, 2, t8); // lb t8, 2(t8) + c->sb(t6, 7, t5); // sb t6, 7(t5) + c->sb(t7, 2, t5); // sb t7, 2(t5) + c->sb(t8, 10, t5); // sb t8, 10(t5) + c->daddiu(t3, t3, -1); // daddiu t3, t3, -1 + c->daddiu(t4, t4, 2); // daddiu t4, t4, 2 + bc = c->sgpr64(t3) != 0; // bne t3, r0, L23 + c->daddiu(t5, t5, 12); // daddiu t5, t5, 12 + if (bc) {goto block_2;} // branch non-likely + + c->lbu(t3, 2, a1); // lbu t3, 2(a1) + c->lbu(t4, 1, a1); // lbu t4, 1(a1) + c->daddiu(t4, t4, 3); // daddiu t4, t4, 3 + c->dsrl(t4, t4, 2); // dsrl t4, t4, 2 + c->daddu(t3, t3, t4); // daddu t3, t3, t4 + c->dsll(t3, t3, 4); // dsll t3, t3, 4 + c->daddu(t2, t2, t3); // daddu t2, t2, t3 + c->lbu(t3, 3, a1); // lbu t3, 3(a1) + c->dsll(t3, t3, 1); // dsll t3, t3, 1 + c->daddiu(t3, t3, 4); // daddiu t3, t3, 4 + c->daddu(a1, a1, t3); // daddu a1, a1, t3 + c->dsll(t1, t1, 1); // dsll t1, t1, 1 + c->daddiu(t1, t1, 15); // daddiu t1, t1, 15 + c->andi(t1, t1, 65520); // andi t1, t1, 65520 + c->daddu(a2, a2, t1); // daddu a2, a2, t1 + c->daddiu(a3, a3, 2); // daddiu a3, a3, 2 + c->mov64(t1, a3); // or t1, a3, r0 + c->daddiu(t0, t0, 1); // daddiu t0, t0, 1 + + block_4: + c->slt(t1, t0, a0); // slt t1, t0, a0 + bc = c->sgpr64(t1) != 0; // bne t1, r0, L22 + // nop // sll r0, r0, 0 + if (bc) {goto block_1;} // branch non-likely + + c->mov64(v1, s7); // or v1, s7, r0 + c->mov64(v0, s7); // or v0, s7, r0 + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); + gLinkedFunctionTable.reg("ripple-apply-wave-table", execute, 128); +} + +} // namespace ripple_apply_wave_table +} // namespace Mips2C + +//--------------------------MIPS2C--------------------- +#include "game/mips2c/mips2c_private.h" +#include "game/kernel/kscheme.h" +namespace Mips2C { +namespace ripple_matrix_scale { +u64 execute(void* ctxt) { + auto* c = (ExecutionContext*)ctxt; + bool bc = false; + c->mov128_vf_gpr(vf1, a3); // qmtc2.i vf1, a3 + c->mov128_vf_gpr(vf2, a2); // qmtc2.i vf2, a2 + c->mov128_vf_gpr(vf3, t0); // qmtc2.i vf3, t0 + c->mov64(v1, t1); // or v1, t1, r0 + + block_1: + c->lqc2(vf5, 16, a0); // lqc2 vf5, 16(a0) + c->lqc2(vf6, 48, a0); // lqc2 vf6, 48(a0) + c->lqc2(vf7, 64, a0); // lqc2 vf7, 64(a0) + c->lqc2(vf8, 96, a0); // lqc2 vf8, 96(a0) + c->vmul_bc(DEST::xyzw, BC::x, vf4, vf5, vf2); // vmulx.xyzw vf4, vf5, vf2 + c->vmul_bc(DEST::xyzw, BC::x, vf5, vf5, vf1); // vmulx.xyzw vf5, vf5, vf1 + c->lq(a2, 0, a0); // lq a2, 0(a0) + c->vmul_bc(DEST::xyzw, BC::x, vf7, vf7, vf3); // vmulx.xyzw vf7, vf7, vf3 + c->lq(v1, 32, a0); // lq v1, 32(a0) + c->vmul_bc(DEST::xyzw, BC::x, vf8, vf8, vf3); // vmulx.xyzw vf8, vf8, vf3 + c->sq(a2, 0, t1); // sq a2, 0(t1) + c->lq(a2, 80, a0); // lq a2, 80(a0) + c->vsub(DEST::xyzw, vf6, vf6, vf4); // vsub.xyzw vf6, vf6, vf4 + c->sq(v1, 32, t1); // sq v1, 32(t1) + c->sqc2(vf5, 16, t1); // sqc2 vf5, 16(t1) + c->sq(a2, 80, t1); // sq a2, 80(t1) + c->daddiu(a1, a1, -1); // daddiu a1, a1, -1 + c->sqc2(vf7, 64, t1); // sqc2 vf7, 64(t1) + c->addiu(a0, a0, 128); // addiu a0, a0, 128 + c->sqc2(vf6, 48, t1); // sqc2 vf6, 48(t1) + c->addiu(t1, t1, 128); // addiu t1, t1, 128 + bc = c->sgpr64(a1) != 0; // bne a1, r0, L12 + c->sqc2(vf8, -32, t1); // sqc2 vf8, -32(t1) + if (bc) {goto block_1;} // branch non-likely + + c->gprs[v0].du64[0] = 0; // or v0, r0, r0 + //jr ra // jr ra + c->daddu(sp, sp, r0); // daddu sp, sp, r0 + goto end_of_function; // return + + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + // nop // sll r0, r0, 0 + end_of_function: + return c->gprs[v0].du64[0]; +} + +void link() { + gLinkedFunctionTable.reg("ripple-matrix-scale", execute, 128); +} + +} // namespace ripple_matrix_scale +} // namespace Mips2C diff --git a/game/mips2c/mips2c_private.h b/game/mips2c/mips2c_private.h index 6799108626..5fedd3e6bd 100644 --- a/game/mips2c/mips2c_private.h +++ b/game/mips2c/mips2c_private.h @@ -9,6 +9,7 @@ #include "third-party/fmt/core.h" #include "common/util/Assert.h" #include "common/dma/dma.h" +#include "game/common/vu.h" // This file contains utility functions for code generated by the mips2c pass. // This is only useful for @@ -61,6 +62,7 @@ enum Gpr { }; enum VfName { + vf00 = 0, vf0 = 0, vf1 = 1, vf01 = 1, @@ -104,6 +106,24 @@ enum VfName { vf31 = 31, }; +enum ViName { + vi00 = 0, + vi01 = 1, + vi02 = 2, + vi03 = 3, + vi04 = 4, + vi05 = 5, + vi06 = 6, + vi07 = 7, + vi08 = 8, + vi09 = 9, + vi10 = 10, + vi11 = 11, + vi12 = 12, + vi13 = 13, + vi14 = 14, +}; + enum FprName { f0 = 0, f1 = 1, @@ -161,17 +181,47 @@ enum class DEST { enum class BC { x = 0, y = 1, z = 2, w = 3 }; +struct Mips2c_vf { + union { + u64 du64[2]; + s64 ds64[2]; + u32 du32[4]; + s32 ds32[4]; + u16 du16[8]; + s16 ds16[8]; + u8 du8[16]; + s8 ds8[16]; + float f[4]; + Vf vf; + }; +}; + +struct Mips2c_acc { + union { + u64 du64[2]; + s64 ds64[2]; + u32 du32[4]; + s32 ds32[4]; + u16 du16[8]; + s16 ds16[8]; + u8 du8[16]; + s8 ds8[16]; + float f[4]; + Accumulator vf; + }; +}; + struct ExecutionContext { // EE general purpose registers u128 gprs[32]; // EE fprs float fprs[32]; // VU0 vf registers - u128 vfs[32]; - - u128 acc; + Mips2c_vf vfs[32]; + Mips2c_acc acc; float Q; + float I; u128 hi, lo; @@ -181,9 +231,9 @@ struct ExecutionContext { } } - u128 vf_src(int idx) { + Mips2c_vf vf_src(int idx) { if (idx == 0) { - u128 result; + Mips2c_vf result; result.f[0] = 0; result.f[1] = 0; result.f[2] = 0; @@ -215,6 +265,10 @@ struct ExecutionContext { gprs[gpr].ds64[0] = val; // sign extend and set } + void load_symbol_addr(int gpr, void* sym_addr) { + gprs[gpr].du64[0] = ((const u8*)sym_addr) - g_ee_main_mem; + } + void lbu(int dst, int offset, int src) { u8 val; memcpy(&val, g_ee_main_mem + gpr_src(src).du32[0] + offset, 1); @@ -228,6 +282,7 @@ struct ExecutionContext { } void lqc2(int vf, int offset, int gpr) { + ASSERT(((gpr_src(gpr).du32[0] + offset) & 0xf) == 0); memcpy(&vfs[vf], g_ee_main_mem + gpr_src(gpr).du32[0] + offset, 16); } @@ -354,6 +409,19 @@ struct ExecutionContext { } } + void pextuh(int dst, int src0, int src1) { + auto s0 = gpr_src(src0); + auto s1 = gpr_src(src1); + gprs[dst].du16[0] = s1.du16[4]; + gprs[dst].du16[1] = s0.du16[4]; + gprs[dst].du16[2] = s1.du16[5]; + gprs[dst].du16[3] = s0.du16[5]; + gprs[dst].du16[4] = s1.du16[6]; + gprs[dst].du16[5] = s0.du16[6]; + gprs[dst].du16[6] = s1.du16[7]; + gprs[dst].du16[7] = s0.du16[7]; + } + void pextuw(int dst, int src0, int src1) { auto s0 = gpr_src(src0); auto s1 = gpr_src(src1); @@ -382,8 +450,8 @@ struct ExecutionContext { void pcpyld(int dst, int src0, int src1) { auto s0 = gpr_src(src0); auto s1 = gpr_src(src1); - gprs[dst].du64[0] = s1.du64[0]; gprs[dst].du64[1] = s0.du64[0]; + gprs[dst].du64[0] = s1.du64[0]; } void pexew(int dst, int src) { @@ -573,10 +641,25 @@ struct ExecutionContext { void psraw(int dest, int src, int sa) { auto s = gpr_src(src); for (int i = 0; i < 4; i++) { - gprs[dest].ds32[i] = s.ds32[i] >> (sa & 0x1f); + gprs[dest].du32[i] = s.ds32[i] >> (sa & 0x1f); } } + void psllw(int dest, int src, int sa) { + auto s = gpr_src(src); + for (int i = 0; i < 4; i++) { + gprs[dest].ds32[i] = s.ds32[i] << (sa & 0x1f); + } + } + + void prot3w(int dst, int src) { + auto s = gpr_src(src); + gprs[dst].du32[0] = s.du32[1]; + gprs[dst].du32[1] = s.du32[2]; + gprs[dst].du32[2] = s.du32[0]; + gprs[dst].du32[3] = s.du32[3]; + } + void paddh(int dest, int rs, int rt) { auto s = gpr_src(rs); auto t = gpr_src(rt); @@ -596,6 +679,21 @@ struct ExecutionContext { } } + void pand(int dst, int rs, int rt) { + auto s = gpr_src(rs); + auto t = gpr_src(rt); + gprs[dst].du64[0] = s.du64[0] & t.du64[0]; + gprs[dst].du64[1] = s.du64[1] & t.du64[1]; + } + + void pceqb(int dst, int rs, int rt) { + auto s = gpr_src(rs); + auto t = gpr_src(rt); + for (int i = 0; i < 16; i++) { + gprs[dst].du8[i] = (s.du8[i] == t.du8[i]) ? 0xff : 0; + } + } + void pmfhl_lh(int dest) { gprs[dest].du16[0] = lo.du16[0]; gprs[dest].du16[1] = lo.du16[2]; @@ -695,6 +793,17 @@ struct ExecutionContext { } } + void vadda_bc(DEST mask, BC bc, int src0, int src1) { + auto s0 = vf_src(src0); + auto s1 = vf_src(src1); + + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + acc.f[i] = s0.f[i] + s1.f[(int)bc]; + } + } + } + void vmadda_bc(DEST mask, BC bc, int src0, int src1) { auto s0 = vf_src(src0); auto s1 = vf_src(src1); @@ -706,6 +815,17 @@ struct ExecutionContext { } } + void vmadda(DEST mask, int src0, int src1) { + auto s0 = vf_src(src0); + auto s1 = vf_src(src1); + + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + acc.f[i] += s0.f[i] * s1.f[i]; + } + } + } + void vmsuba_bc(DEST mask, BC bc, int src0, int src1) { auto s0 = vf_src(src0); auto s1 = vf_src(src1); @@ -728,6 +848,17 @@ struct ExecutionContext { } } + void vmadd(DEST mask, int dst, int src0, int src1) { + auto s0 = vf_src(src0); + auto s1 = vf_src(src1); + + for (int i = 0; i < 4; i++) { + if ((u64)mask & (1 << i)) { + vfs[dst].f[i] = acc.f[i] + s0.f[i] * s1.f[i]; + } + } + } + void vmsub_bc(DEST mask, BC bc, int dst, int src0, int src1) { auto s0 = vf_src(src0); auto s1 = vf_src(src1); @@ -810,6 +941,14 @@ struct ExecutionContext { } } + void slt(int dst, int src0, int src1) { + gprs[dst].du64[0] = (gpr_src(src0).ds64[0] < gpr_src(src1).ds64[0]) ? 1 : 0; + } + + void sltu(int dst, int src0, int src1) { + gprs[dst].du64[0] = (gpr_src(src0).du64[0] < gpr_src(src1).du64[0]) ? 1 : 0; + } + void sll(int dst, int src, int sa) { u32 value = gpr_src(src).du32[0] << sa; s32 value_signed = value; @@ -827,6 +966,9 @@ struct ExecutionContext { void dsrav(int dst, int src, int sa) { gprs[dst].ds64[0] = gpr_src(src).ds64[0] >> gpr_src(sa).du32[0]; } + void dsllv(int dst, int src, int sa) { + gprs[dst].ds64[0] = gpr_src(src).ds64[0] << (gpr_src(sa).du32[0] & 0b111111); + } void dsra32(int dst, int src, int sa) { gprs[dst].ds64[0] = gpr_src(src).ds64[0] >> (32 + sa); } void dsrl32(int dst, int src, int sa) { gprs[dst].du64[0] = gpr_src(src).du64[0] >> (32 + sa); } void sra(int dst, int src, int sa) { gprs[dst].ds64[0] = gpr_src(src).ds32[0] >> sa; } @@ -987,8 +1129,8 @@ struct ExecutionContext { } } - void mov128_vf_gpr(int dst, int src) { vfs[dst] = gpr_src(src); } - void mov128_gpr_vf(int dst, int src) { gprs[dst] = vf_src(src); } + void mov128_vf_gpr(int dst, int src) { memcpy(vfs[dst].f, gpr_src(src).f, 16); } + void mov128_gpr_vf(int dst, int src) { memcpy(gprs[dst].f, vf_src(src).f, 16); } void mov128_gpr_gpr(int dst, int src) { gprs[dst] = gpr_src(src); } void vitof0(DEST mask, int dst, int src) { @@ -1106,6 +1248,95 @@ struct ExecutionContext { vfs[dst].f[2] = acc.f[2] - s0.f[0] * s1.f[1]; } + // copied from PCSX2, to handle the weirdo special case in lwr. + static constexpr u32 LWL_MASK[4] = {0xffffff, 0x0000ffff, 0x000000ff, 0x00000000}; + static constexpr u32 LWR_MASK[4] = {0x000000, 0xff000000, 0xffff0000, 0xffffff00}; + static constexpr u8 LWL_SHIFT[4] = {24, 16, 8, 0}; + static constexpr u8 LWR_SHIFT[4] = {0, 8, 16, 24}; + + void lwl(int dst, int offset, int addr_reg) { + s32 addr = sgpr64(addr_reg) + offset; + u32 shift = addr & 3; + + u32 mem; + memcpy(&mem, g_ee_main_mem + (addr & ~3), 4); + + if (!dst) + return; + + // ensure the compiler does correct sign extension into 64 bits by using s32 + gprs[dst].ds64[0] = (s32)((gprs[dst].du32[0] & LWL_MASK[shift]) | (mem << LWL_SHIFT[shift])); + + /* + Mem = 1234. Reg = abcd + (result is always sign extended into the upper 32 bits of the Rt) + + 0 4bcd (mem << 24) | (reg & 0x00ffffff) + 1 34cd (mem << 16) | (reg & 0x0000ffff) + 2 234d (mem << 8) | (reg & 0x000000ff) + 3 1234 (mem ) | (reg & 0x00000000) + */ + } + + void lwr(int dst, int offset, int addr_reg) { + s32 addr = sgpr64(addr_reg) + offset; + u32 shift = addr & 3; + + u32 mem; + memcpy(&mem, g_ee_main_mem + (addr & ~3), 4); + + if (!dst) + return; + + // Use unsigned math here, and conditionally sign extend below, when needed. + mem = (gprs[dst].du32[0] & LWR_MASK[shift]) | (mem >> LWR_SHIFT[shift]); + + if (shift == 0) { + // This special case requires sign extension into the full 64 bit dest. + gprs[dst].ds64[0] = (s32)mem; + } else { + // This case sets the lower 32 bits of the target register. Upper + // 32 bits are always preserved. + gprs[dst].du32[0] = mem; + } + } + + static constexpr u64 LDL_MASK[8] = { + 0x00ffffffffffffffULL, 0x0000ffffffffffffULL, 0x000000ffffffffffULL, 0x00000000ffffffffULL, + 0x0000000000ffffffULL, 0x000000000000ffffULL, 0x00000000000000ffULL, 0x0000000000000000ULL}; + static constexpr u64 LDR_MASK[8] = { + 0x0000000000000000ULL, 0xff00000000000000ULL, 0xffff000000000000ULL, 0xffffff0000000000ULL, + 0xffffffff00000000ULL, 0xffffffffff000000ULL, 0xffffffffffff0000ULL, 0xffffffffffffff00ULL}; + + static constexpr u8 LDR_SHIFT[8] = {0, 8, 16, 24, 32, 40, 48, 56}; + static constexpr u8 LDL_SHIFT[8] = {56, 48, 40, 32, 24, 16, 8, 0}; + + void ldl(int dst, int offset, int addr_reg) { + u32 addr = sgpr64(addr_reg) + offset; + u32 shift = addr & 7; + + u64 mem; + // memRead64(addr & ~7, &mem); + memcpy(&mem, g_ee_main_mem + (addr & ~7), 8); + + if (!dst) + return; + gprs[dst].du64[0] = (gprs[dst].du64[0] & LDL_MASK[shift]) | (mem << LDL_SHIFT[shift]); + } + + void ldr(int dst, int offset, int addr_reg) { + u32 addr = sgpr64(addr_reg) + offset; + u32 shift = addr & 7; + + u64 mem; + // memRead64(addr & ~7, &mem); + memcpy(&mem, g_ee_main_mem + (addr & ~7), 8); + + if (!dst) + return; + gprs[dst].du64[0] = (gprs[dst].du64[0] & LDR_MASK[shift]) | (mem >> LDR_SHIFT[shift]); + } + std::string print_vf_float(int vf) { auto src = vf_src(vf); return fmt::format("{} {} {} {}", src.f[0], src.f[1], src.f[2], src.f[3]); @@ -1218,6 +1449,7 @@ inline void spad_to_dma_blerc_chain(void* spad_sym_addr, u32 sadr, u32 tadr) { u32 spad_addr_goal; memcpy(&spad_addr_goal, spad_sym_addr, 4); void* spad_addr_c = g_ee_main_mem + spad_addr_goal; + ASSERT(sadr < 0x4000); emulate_dma(g_ee_main_mem, spad_addr_c, tadr, sadr); } } // namespace Mips2C diff --git a/game/mips2c/mips2c_table.cpp b/game/mips2c/mips2c_table.cpp index 1dcacc92e6..31409ba2a4 100644 --- a/game/mips2c/mips2c_table.cpp +++ b/game/mips2c/mips2c_table.cpp @@ -224,6 +224,42 @@ extern void link(); namespace setup_blerc_chains_for_one_fragment { extern void link(); } +namespace generic_merc_init_asm { +extern void link(); +} +namespace generic_merc_execute_asm { +extern void link(); +} +namespace mercneric_convert { +extern void link(); +} +namespace generic_prepare_dma_double { +extern void link(); +} +namespace generic_light_proc { +extern void link(); +} +namespace generic_envmap_proc { +extern void link(); +} +namespace high_speed_reject { +extern void link(); +} +namespace generic_prepare_dma_single { +extern void link(); +} +namespace ripple_create_wave_table { +extern void link(); +} +namespace ripple_execute_init { +extern void link(); +} +namespace ripple_apply_wave_table { +extern void link(); +} +namespace ripple_matrix_scale { +extern void link(); +} LinkedFunctionTable gLinkedFunctionTable; Rng gRng; std::unordered_map> gMips2CLinkCallbacks = { @@ -259,7 +295,16 @@ std::unordered_map> gMips2CLinkCallbacks = {"joint", {calc_animation_from_spr::link, cspace_parented_transformq_joint::link}}, {"bones", {bones_mtx_calc::link, draw_bones_merc::link, draw_bones_check_longest_edge_asm::link}}, - {"merc-blend-shape", {blerc_execute::link, setup_blerc_chains_for_one_fragment::link}}}; + {"merc-blend-shape", {blerc_execute::link, setup_blerc_chains_for_one_fragment::link}}, + {"generic-merc", + {generic_merc_init_asm::link, generic_merc_execute_asm::link, mercneric_convert::link, + high_speed_reject::link}}, + {"generic-effect", + {generic_prepare_dma_double::link, generic_light_proc::link, generic_envmap_proc::link, + generic_prepare_dma_single::link}}, + {"ripple", + {ripple_execute_init::link, ripple_create_wave_table::link, ripple_apply_wave_table::link, + ripple_matrix_scale::link}}}; void LinkedFunctionTable::reg(const std::string& name, u64 (*exec)(void*), u32 stack_size) { const auto& it = m_executes.insert({name, {exec, Ptr()}}); diff --git a/goal_src/engine/anim/bones-h.gc b/goal_src/engine/anim/bones-h.gc index 201ece625e..56f2b059da 100644 --- a/goal_src/engine/anim/bones-h.gc +++ b/goal_src/engine/anim/bones-h.gc @@ -92,8 +92,8 @@ (deftype merc-globals (structure) ((first uint32 :offset-assert 0) - (next uint32 :offset-assert 4) - (sink basic :offset-assert 8) + (next (pointer uint32) :offset-assert 4) + (sink generic-dma-foreground-sink :offset-assert 8) ) :allow-misaligned :method-count-assert 9 diff --git a/goal_src/engine/anim/bones.gc b/goal_src/engine/anim/bones.gc index f550f8b72b..18f1dd576f 100644 --- a/goal_src/engine/anim/bones.gc +++ b/goal_src/engine/anim/bones.gc @@ -15,6 +15,7 @@ ;; It's more than just bones in here - submitting to merc is done from here. +(defglobalconstant USE_GENERIC #t) ;;;;;;;;;;;;;;;;;; ;; calc list @@ -350,7 +351,7 @@ ;; reset globals (let ((v1-3 *merc-globals*)) (set! (-> v1-3 first) (the-as uint 0)) - (set! (-> v1-3 next) (the-as uint 0)) + (set! (-> v1-3 next) (the-as (pointer uint32) 0)) ) ;; upload bones program. @@ -477,6 +478,9 @@ (.lvf vf27 (&-> v1-13 vector 2 quad)) (.mov v1-14 vf27) + ;; hack?? + + (bones-mtx-calc (the-as int (-> s4-0 matrix-area)) (the-as pointer (-> s4-0 joints)) @@ -525,10 +529,10 @@ (+! a0-22 -1) (.svf (&-> a1-9 4 quad) vf7) ;(.addiu v1-18 (the-as object v1-18) 128) - (&+ v1-18 128) + (&+! v1-18 128) (.svf (&-> a1-9 3 quad) vf6) ;;(.addiu (the-as (inline-array vector) a1-9) a1-9 128) - (&+ a1-9 128) + (&+! a1-9 128) (b! (nonzero? a0-22) cfg-8 :delay (.svf (&-> a1-9 -2 quad) vf8)) ) 0 @@ -656,108 +660,180 @@ ) ) -;; draw-bones-shadow -;; draw-bones-generic-merc +;; TODO draw-bones-shadow + +;(def-mips2c draw-bones-generic-merc (function draw-control pointer pointer int pointer)) +(defun draw-bones-generic-merc ((arg0 draw-control) (arg1 pointer) (arg2 pointer) (arg3 int)) + "Add data for generic merc drawing to the dma buffer. Note that this data is not yet converted to the generic format, + so it is not linked into the chain. This data is linked to itself and can be found again by following the chain + in *merc-globals*, which, despite the name, only contains generic merc data." + (local-vars + (sv-16 generic-merc-ctrl) + (sv-32 merc-effect) + (sv-48 int) + (sv-64 merc-fragment) + (sv-80 merc-fragment-control) + (sv-96 uint) + (sv-112 int) + (sv-128 int) + (sv-144 generic-merc-ctrl) + ) + (let ((gp-0 (the-as object (&+ arg2 0)))) + (let ((s2-0 (-> arg0 lod-set lod (-> arg0 cur-lod) geo)) + (s0-0 (-> *merc-globals* next)) + ) + (set! sv-144 (the-as generic-merc-ctrl (&+ arg2 16))) + (dotimes (s1-0 (the-as int (-> s2-0 header effect-count))) + (when (nonzero? (-> *merc-bucket-info* effect s1-0 use-mercneric)) + (set! sv-16 sv-144) + (set! sv-32 (-> s2-0 effect s1-0)) + (+! (-> *merc-global-stats* mercneric fragments) (-> sv-32 frag-count)) + (+! (-> *merc-global-stats* mercneric tris) (-> sv-32 tri-count)) + (+! (-> *merc-global-stats* mercneric dverts) (-> sv-32 dvert-count)) + (when (nonzero? s0-0) + (set! (-> s0-0 0) (the-as uint sv-16)) + sv-16 + ) + (when (zero? (-> *merc-globals* first)) + (set! (-> *merc-globals* first) (the-as uint sv-16)) + sv-16 + ) + (set! s0-0 (&-> sv-16 tag vif1)) + (quad-copy! (the-as pointer (-> sv-16 lights)) (the-as pointer (-> *merc-bucket-info* light)) 7) + (quad-copy! (the-as pointer (-> sv-16 header)) (the-as pointer (-> s2-0 header)) 5) + (set! (-> sv-16 header envmap-tint) (the-as uint (-> *merc-bucket-info* effect s1-0 color-fade))) + (set! (-> sv-16 header needs-clip) (the-as uint (-> *merc-bucket-info* needs-clip))) + (set! (-> sv-16 header use-isometric) (the-as uint arg3)) + (when (nonzero? arg3) + (set! (-> sv-16 header needs-clip) (the-as uint 0)) + 0 + ) + (set! (-> sv-16 header use-attached-shader) (the-as uint 0)) + (set! (-> sv-16 header display-triangles) (the-as uint 1)) + (set! (-> sv-16 header two-mat-count) (the-as uint 0)) + (set! (-> sv-16 header shader-upload-count) (the-as uint (if (logtest? (-> sv-32 effect-bits) 2) + 1 + 0 + ) + ) + ) + (when (nonzero? (-> arg0 death-timer)) + (when (>= (the-as int (- (-> arg0 death-timer-org) (-> arg0 death-timer))) + (the-as int (-> arg0 death-draw-overlap)) + ) + (set! (-> sv-16 header display-triangles) (the-as uint 0)) + 0 + ) + (when (not (paused?)) + (set! (-> sv-16 header two-mat-count) (-> arg0 death-vertex-skip)) + (set! (-> sv-16 header death-effect) (-> arg0 death-effect)) + (set! (-> sv-16 header two-mat-reuse-count) + (/ (* (-> arg0 death-vertex-skip) (- (-> arg0 death-timer-org) (-> arg0 death-timer))) + (-> arg0 death-timer-org) + ) + ) + ) + ) + (set! (-> sv-16 header query) (the-as basic 0)) + (when (logtest? (-> sv-32 effect-bits) 4) + (when (-> arg0 ripple) + (if (-> arg0 ripple send-query) + (set! (-> sv-16 header query) (-> arg0 ripple query)) + ) + ) + ) + (quad-copy! (the-as pointer (-> sv-16 effect)) (the-as pointer sv-32) 2) + (set! sv-48 15) + (when (nonzero? (-> sv-32 extra-info)) + (when (nonzero? (-> sv-32 extra-info shader-offset)) + (set! (-> sv-16 header use-attached-shader) (the-as uint 1)) + (quad-copy! + (the-as pointer (&+ sv-16 240)) + (the-as pointer (+ (the-as uint (-> sv-32 extra-info)) (* (-> sv-32 extra-info shader-offset) 16))) + 5 + ) + (set! sv-48 (+ sv-48 5)) + sv-48 + ) + ) + (set! (-> sv-16 tag dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc (+ sv-48 -1))) + (set! (-> sv-16 tag vif0) (the-as vif-tag sv-48)) + (set! (-> sv-16 tag vif1) (new 'static 'vif-tag)) + (set! sv-144 (the-as generic-merc-ctrl (+ (the-as uint sv-144) (* sv-48 16)))) + sv-144 + (set! sv-64 (-> sv-32 frag-geo)) + (set! sv-80 (-> sv-32 frag-ctrl)) + (set! sv-96 (-> sv-32 frag-count)) + (set! sv-112 0) + (while (< sv-112 (the-as int sv-96)) + (set! sv-128 (asize-of sv-80)) + (let ((v1-104 (asize-of sv-64))) + ;; (format 0 "~D TAG at #x~X merc size ~D bytes ~D qw~%" sv-112 sv-144 v1-104 (shr v1-104 4)) + (set! (-> sv-144 tag dma) + (new 'static 'dma-tag :id (dma-tag-id ref) :addr (the-as int sv-64) :qwc (shr v1-104 4)) + ) + (set! (-> sv-144 tag vif0) (new 'static 'vif-tag)) + (set! (-> sv-144 tag vif1) (new 'static 'vif-tag)) + (when (nonzero? sv-112) + (set! (-> (the-as (pointer vif-tag) s0-0) 0) (the-as vif-tag sv-144)) + (set! s0-0 (&-> sv-144 tag vif1)) + ) + (let ((a0-55 (the-as structure (-> sv-144 lights)))) + (dotimes (a1-17 (the-as int (-> sv-80 mat-xfer-count))) + (let ((a3-2 (&+ arg1 (* (-> sv-80 mat-dest-data a1-17 matrix-number) 128)))) + (set! (-> (the-as dma-packet a0-55) dma) + (new 'static 'dma-tag :qwc #x7 :id (dma-tag-id ref) :addr (the-as int a3-2)) + ) + ; (let ((vec (the vector (+ (the-as int a3-2) 16)))) + ; (format 0 "#x~X #x~X mat ~D: ~f ~f ~f~%" a0-55 a3-2 a1-17 (-> vec x) (-> vec y) (-> vec z)) + ; ) + + ) + (set! (-> (the-as dma-packet a0-55) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet a0-55) vif1) (new 'static 'vif-tag)) + (set! a0-55 (&+ (the-as dma-packet a0-55) 16)) + ) + (set! (-> (the-as dma-packet a0-55) dma) (new 'static 'dma-tag :id (dma-tag-id end))) + (set! (-> (the-as dma-packet a0-55) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet a0-55) vif1) (new 'static 'vif-tag)) + (set! sv-144 (the-as generic-merc-ctrl (&+ (the-as dma-packet a0-55) 16))) + ) + (set! sv-80 (the-as merc-fragment-control (&+ (the-as pointer sv-80) sv-128))) + (set! sv-64 (the-as merc-fragment (&+ (the-as pointer sv-64) v1-104))) + ) + sv-64 + (set! sv-112 (+ sv-112 1)) + ) + ) + ) + (set! (-> *merc-globals* next) s0-0) + ) + (set! (-> (the-as dma-packet gp-0) dma) + (new 'static 'dma-tag :id (dma-tag-id next) :addr (the-as int sv-144)) + ) + (set! (-> (the-as dma-packet gp-0) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet gp-0) vif1) (new 'static 'vif-tag)) + ) + 0 + (the-as pointer sv-144) + ) ;; draw-boes-merc ;; draw-bones-check-longest-edge ;; draw-bones-check-longest-edgei-asm ;; draw-bones ;; draw-bones-hud -;; HACK incomplete: -(defun draw-bones-hack ((arg0 draw-control) (arg1 dma-buffer) (arg2 float)) - (local-vars - (at-0 object) - (a0-16 int) - (a0-17 int) - (a0-62 int) - (a2-10 int) - (a2-12 int) - (sv-96 int) - (sv-112 int) - (sv-128 int) - (sv-144 ripple-control) - ) - (rlet ((vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf) - (vf4 :class vf) - (vf5 :class vf) - (vf6 :class vf) - (vf7 :class vf) - (vf8 :class vf) - (vf9 :class vf) - ) - (let* ((s1-0 (+ (-> arg0 mgeo num-joints) 3)) - (a0-1 (* s1-0 128)) - ) - ;;(.lui at-0 28672) - (let* ((v1-2 (-> arg1 base)) - (a1-1 (the-as object (&+ v1-2 16))) - (s3-0 (the-as object (&+ v1-2 64))) - ) - (let ((a2-1 (logand (the-as int s3-0) 48))) - (b! (zero? a2-1) cfg-2 :delay (nop!)) - (set! s3-0 (&- (&+ (the-as pointer s3-0) 64) (the-as uint a2-1))) - ) - (label cfg-2) - ; (let* ((a2-3 (-> *perf-stats* data 13)) - ; (a3-1 (-> a2-3 ctrl)) - ; ) - ; (+! (-> a2-3 count) 1) - ; (b! (zero? a3-1) cfg-4 :delay (nop!)) - ; (.mtc0 Perf r0) - ; (.sync.l) - ; (.sync.p) - ; (.mtpc pcr0 r0) - ; (.mtpc pcr1 r0) - ; (.sync.l) - ; (.sync.p) - ; (.mtc0 Perf a3-1) - ; ) - ; (.sync.l) - ; (.sync.p) - ; (label cfg-4) - 0 - (let ((a2-6 (the-as bone-regs (+ 240 (scratchpad-object int))))) - (set! (-> a2-6 joint-ptr) (the-as (inline-array joint) (-> arg0 jgeo data 0))) - (set! (-> a2-6 bone-ptr) (-> arg0 skeleton bones)) - (set! (-> a2-6 num-bones) (the-as uint s1-0)) - ) - (let ((t0-2 s3-0) - (t1-0 0) - (t4-0 (the-as bone-memory (+ 16 (scratchpad-object int)))) - (a2-8 *bone-calculation-list*) - (a3-8 (the-as bone-calculation a1-1)) - ) - (let ((t2-0 (-> t4-0 work regs joint-ptr)) - (t3-0 (-> t4-0 work regs bone-ptr)) - (t4-1 (-> t4-0 work regs num-bones)) - (t5-0 a3-8) - ) - (set! (-> t5-0 flags) (the-as bone-calc-flags t1-0)) - (set! (-> t5-0 num-bones) t4-1) - (set! (-> t5-0 matrix-area) (the-as (inline-array matrix) t0-2)) - (set! (-> t5-0 joints) t2-0) - (set! (-> t5-0 bones) t3-0) - (set! (-> t5-0 next) (the-as bone-calculation 0)) - ) - (if (nonzero? (-> a2-8 next)) - (set! (-> a2-8 next next) a3-8) - ) - (if (zero? (-> a2-8 first)) - (set! (-> a2-8 first) a3-8) - ) - (set! (-> a2-8 next) a3-8) - ;; total guess - (&+! (-> arg1 base) (* 2 (+ 256 a0-1))) - ) - ))) - (none)) - (def-mips2c draw-bones-merc (function draw-control object object int int pointer)) (def-mips2c draw-bones-check-longest-edge-asm (function draw-control float symbol)) +(defmacro store-qw (addr val) + `(set! (-> (the-as (pointer uint128) ,addr)) (the-as uint128 ,val)) + ) + +(defmacro store-u32 (addr val) + `(set! (-> (the-as (pointer uint32) ,addr)) ,val) + ) + (defun draw-bones ((arg0 draw-control) (dma-buf dma-buffer) (arg2 float)) "Main draw function for all bone-related renderers. Will set up merc, generic and shadow. and also add the bones to the calculation list." @@ -965,41 +1041,44 @@ ;; try ripple (when (logtest? (-> geom effect effect-idx effect-bits) 4) ;; TODO. - ; (when (-> arg0 ripple) - ; (set! sv-144 (-> arg0 ripple)) - ; (let* ((f1-4 (/ (- (-> sv-144 far-fade-dist) arg2) (- (-> sv-144 far-fade-dist) (-> sv-144 close-fade-dist)))) - ; (f1-6 (fmax 0.0 (fmin 1.0 f1-4))) - ; (f0-4 f1-6) - ; (f30-0 (* f1-6 (-> sv-144 global-scale))) - ; ) - ; (set! (-> sv-144 faded-scale) f30-0) - ; (let ((f1-9 (/ f30-0 (* 128.0 (-> geom header xyz-scale))))) - ; 0 - ; (.sll a0-16 num-bones 7) - ; (let ((v1-56 #x20000000)) - ; (.addu a0-17 a0-16 s2-0) - ; (s.q! s2-0 v1-56) - ; ) - ; (let ((v1-57 (+ a0-17 16))) - ; (s.w! (+ s2-0 4) v1-57) - ; ) - ; (.addiu matrix-data s2-0 16) - ; (let ((v1-59 (-> *bone-calculation-list* next))) - ; (logior! (-> v1-59 flags) (bone-calc-flags bncfl00)) - ; (set! (-> v1-59 ripple-scale) f30-0) - ; (set! (-> v1-59 ripple-y-scale) f1-9) - ; (set! (-> v1-59 ripple-normal-scale) (* f0-4 (-> sv-144 individual-normal-scale))) - ; (set! (-> v1-59 ripple-area) (the-as (inline-array vector) matrix-data)) - ; ) - ; ) - ; (set! (-> dma-buf base) (the-as pointer (-> (the-as (pointer uint32) s2-0) 1))) - ; (set! s2-0 (-> dma-buf base)) - ; (if (not (and (= f30-0 0.0) (= (-> sv-144 last-frame-scale) 0.0))) - ; (ripple-make-request (the-as ripple-wave (-> sv-144 waveform)) (-> geom effect effect-idx)) - ; ) - ; (set! (-> sv-144 last-frame-scale) f30-0) - ; ) - ; ) + (when (-> arg0 ripple) + (set! sv-144 (-> arg0 ripple)) + (let* ((f1-4 (/ (- (-> sv-144 far-fade-dist) arg2) (- (-> sv-144 far-fade-dist) (-> sv-144 close-fade-dist)))) + (f1-6 (fmax 0.0 (fmin 1.0 f1-4))) + (f0-4 f1-6) + (f30-0 (* f1-6 (-> sv-144 global-scale))) + ) + (set! (-> sv-144 faded-scale) f30-0) + (let ((f1-9 (/ f30-0 (* 128.0 (-> geom header xyz-scale))))) + 0 + (set! a0-16 (* num-bones 128)) + (let ((v1-56 #x20000000)) + (set! a0-17 (+ a0-16 (the-as int s2-0)));(.addu a0-17 a0-16 s2-0) + (logand! a0-17 #xffffffff) + ;(s.q! s2-0 v1-56) + (store-qw s2-0 v1-56) + ) + (let ((v1-57 (+ a0-17 16))) + ;(s.w! (+ s2-0 4) v1-57) + (store-u32 (&+ (the pointer s2-0) 4) v1-57) + ) + (set! matrix-data (&+ (the pointer s2-0) 16)) + (let ((v1-59 (-> *bone-calculation-list* next))) + (logior! (-> v1-59 flags) (bone-calc-flags bncfl00)) + (set! (-> v1-59 ripple-scale) f30-0) + (set! (-> v1-59 ripple-y-scale) f1-9) + (set! (-> v1-59 ripple-normal-scale) (* f0-4 (-> sv-144 individual-normal-scale))) + (set! (-> v1-59 ripple-area) (the-as (inline-array vector) matrix-data)) + ) + ) + (set! (-> dma-buf base) (the-as pointer (-> (the-as (pointer uint32) s2-0) 1))) + (set! s2-0 (-> dma-buf base)) + (if (not (and (= f30-0 0.0) (= (-> sv-144 last-frame-scale) 0.0))) + (ripple-make-request (the-as ripple-wave (-> sv-144 waveform)) (-> geom effect effect-idx)) + ) + (set! (-> sv-144 last-frame-scale) f30-0) + ) + ) ) @@ -1081,31 +1160,40 @@ ) ) - ;; HACK just use merc. - (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) - (unless (logtest? (-> arg0 status) (draw-status needs-clip)) - (set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0)) - ) - (when (and (logtest? (-> arg0 status) (draw-status needs-clip)) ;; we need to clip - ;;(nonzero? (-> arg0 longest-edge)) ;; we known the longest edge - ;;(draw-bones-check-longest-edge-asm arg0 arg2) ;; it's ok to use percprime. + ;; HACK just use merc if we aren't using generic. + (#unless USE_GENERIC + (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) + (unless (logtest? (-> arg0 status) (draw-status needs-clip)) + ;; no clip, but wants generic. Just use merc for now. + (set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0)) + (set! used-merc 1) ) - (set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0)) - (set! (-> *merc-bucket-info* need-mercprime-if-merc) 1) - ) - ) + (when (and (logtest? (-> arg0 status) (draw-status needs-clip)) ;; we need to clip + ;;(nonzero? (-> arg0 longest-edge)) ;; we known the longest edge + ;;(draw-bones-check-longest-edge-asm arg0 arg2) ;; it's ok to use percprime. + ) + ;; wants clip. in all cases, give to merc. this might give it to merc even if it fails the + ;; long edge check, but it does ok + (set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0)) + (set! (-> *merc-bucket-info* need-mercprime-if-merc) 1) + (set! used-merc 1) + ) + ) + ) + (set! effect-idx (+ effect-idx 1)) ) ;; end effect loop ;; draw generic! ;; note: this doesn't do the fully draw, there's some other stuff in process-drawable.gc to actually execute. - ;; TODO!! - ; (when (nonzero? used-mercneric) - ; (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) - ; (set! (-> dma-buf base) (draw-bones-generic-merc arg0 matrix-data s2-0 0)) - ; (set! s2-0 (-> dma-buf base)) - ; ) - ; ) + (#when USE_GENERIC + (when (nonzero? used-mercneric) + (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) + (set! (-> dma-buf base) (draw-bones-generic-merc arg0 (the pointer matrix-data) (the pointer s2-0) 0)) + (set! s2-0 (-> dma-buf base)) + ) + ) + ) ;; draw shadow! ;; TODO @@ -1118,7 +1206,7 @@ ;; draw merc! - (set! used-merc 1) + ;; (when (nonzero? used-merc) (when (logtest? *vu1-enable-user* (vu1-renderer-mask merc)) (when (= (-> arg0 cur-lod) (-> arg0 lod-set max-lod)) @@ -1177,7 +1265,156 @@ ) ) +;; TODO (defun draw-bones-hud ((arg0 draw-control) (arg1 dma-buffer)) + (local-vars + (at-0 object) + (at-2 int) + (t2-10 vu-lights) + (t3-3 uint128) + (t3-4 uint128) + (t3-5 uint128) + (t3-6 uint128) + ) + (let ((v1-0 arg0) + (gp-0 arg1) + ) + ;; (.lui at-0 28672) + (set! at-0 (scratchpad-object object)) + (let* ((a3-0 (-> gp-0 base)) + (a0-3 (+ (-> v1-0 mgeo num-joints) 3)) + (a2-0 (the-as object (&+ a3-0 16))) + (a1-1 (&+ a3-0 64)) + ) + (let ((t0-1 (scratchpad-object bone-regs :offset 240))) + (set! (-> t0-1 joint-ptr) (the-as (inline-array joint) (-> v1-0 jgeo data 0))) + (set! (-> t0-1 bone-ptr) (-> v1-0 skeleton bones)) + (set! (-> t0-1 num-bones) (the-as uint a0-3)) + ) + (let ((t2-0 a1-1) + (t3-0 2) + (t6-0 (scratchpad-object bone-memory :offset 16)) + (t0-3 *bone-calculation-list*) + (t1-6 (the-as bone-calculation a2-0)) + ) + (let ((t4-0 (-> t6-0 work regs joint-ptr)) + (t5-0 (-> t6-0 work regs bone-ptr)) + (t6-1 (-> t6-0 work regs num-bones)) + (t7-0 t1-6) + ) + (set! (-> t7-0 flags) (the-as bone-calc-flags t3-0)) + (set! (-> t7-0 num-bones) t6-1) + (set! (-> t7-0 matrix-area) (the-as (inline-array matrix) t2-0)) + (set! (-> t7-0 joints) t4-0) + (set! (-> t7-0 bones) t5-0) + (set! (-> t7-0 next) (the-as bone-calculation 0)) + ) + (if (nonzero? (-> t0-3 next)) + (set! (-> t0-3 next next) t1-6) + ) + (if (zero? (-> t0-3 first)) + (set! (-> t0-3 first) t1-6) + ) + (set! (-> t0-3 next) t1-6) + ) + (let ((a2-2 (the-as object (&+ (&+ (the-as pointer a2-0) 48) (* a0-3 128))))) + (set! (-> (the-as (pointer uint128) a3-0)) + (logior (-> (the-as terrain-context at-0) work foreground generic-work saves envmap verts 4) + (shl (the-as int a2-2) 32) + ) + ) + (when (= (-> v1-0 data-format) 1) + (let ((a0-9 (-> v1-0 lod-set lod 0 geo))) + (dotimes (a3-2 (the-as int (-> a0-9 header effect-count))) + (cond + ((nonzero? (-> a0-9 effect a3-2 envmap-usage)) + (let* ((t1-7 (-> *merc-bucket-info* light)) + (t2-9 (+ 64 (scratchpad-object int))) + (t0-10 7) + (t1-8 (the-as object t1-7)) + ) + (b! (< (+ t0-10 -4) 0) cfg-9 :delay (set! t2-10 (the-as vu-lights t2-9))) + (nop!) + (label cfg-8) + (let ((t6-2 (-> t2-10 direction 0 quad))) + (nop!) + (let ((t3-2 (-> t2-10 direction 1 quad))) + (+! t0-10 -4) + (let ((t4-1 (-> t2-10 direction 2 quad))) + (set! t1-8 (&+ (the-as pointer t1-8) 64)) + (let ((t5-1 (-> t2-10 color 0 quad))) + (set! t2-10 (the-as vu-lights (-> t2-10 color 1))) + (store-qw (&+ (the-as pointer t1-8) -64) t6-2) + (let ((t6-3 (+ t0-10 -4))) + (store-qw (&+ (the-as pointer t1-8) -48) t3-2) + (nop!) + (store-qw (&+ (the-as pointer t1-8) -32) t4-1) + (b! (>= t6-3 0) cfg-8 :delay (store-qw (&+ (the-as pointer t1-8) -16) t5-1)) + ) + ) + ) + ) + ) + (label cfg-9) + (b! (zero? t0-10) cfg-14 :delay (set! t3-3 (-> t2-10 direction 0 quad))) + (let ((t2-11 (-> t2-10 direction 1)) + (t1-9 (-> (the-as vu-lights t1-8) direction 1)) + (t0-11 (+ t0-10 -1)) + ) + (store-qw (&+ t1-9 -16) t3-3) + (b! (zero? t0-11) cfg-14 :delay (set! t3-4 (-> t2-11 quad))) + (let ((t2-12 (&+ t2-11 16)) + (t1-10 (&+ t1-9 16)) + (t0-12 (+ t0-11 -1)) + ) + (store-qw (&+ t1-10 -16) t3-4) + (b! (zero? t0-12) cfg-14 :delay (set! t3-5 (-> t2-12 quad))) + (let ((t2-13 (&+ t2-12 16)) + (t1-11 (&+ t1-10 16)) + (t0-13 (+ t0-12 -1)) + ) + (store-qw (&+ t1-11 -16) t3-5) + (b! (zero? t0-13) cfg-14 :delay (set! t3-6 (-> t2-13 quad))) + (&+ t2-13 16) + (let ((t1-12 (&+ t1-11 16))) + (+ t0-13 -1) + (store-qw (&+ t1-12 -16) t3-6) + ) + ) + ) + ) + ) + (label cfg-14) + 0 + (set! (-> *merc-bucket-info* effect a3-2 color-fade) (new 'static 'rgba :r #x80 :g #x80 :b #x80 :a #x80)) + (set! (-> *merc-bucket-info* effect a3-2 use-mercneric) (the-as uint 1)) + ) + (else + (set! (-> *merc-bucket-info* effect a3-2 use-mercneric) (the-as uint 1)) + ) + ) + ) + ) + (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) + (set! (-> gp-0 base) (draw-bones-generic-merc v1-0 a1-1 (the-as pointer a2-2) 1)) + (set! a2-2 (-> gp-0 base)) + ) + ) + (let ((a0-17 (logand (the-as int a2-2) 48))) + 0 + (b! (zero? a0-17) cfg-22 :delay (set! at-2 #x20000000)) + (set! (-> (the-as (pointer int128) a2-2)) (the-as int128 at-2)) + (let ((v1-2 (the-as pointer a2-2))) + (set! a2-2 (+ (&- (the-as pointer a2-2) (the-as uint a0-17)) 64)) + (store-u32 (&+ v1-2 4) (the-as int a2-2)) + ) + ) + (label cfg-22) + (set! (-> gp-0 base) (the-as pointer a2-2)) + ) + ) + ) + 0 (none) ) diff --git a/goal_src/engine/draw/drawable.gc b/goal_src/engine/draw/drawable.gc index a33cd68fcb..f856107e28 100644 --- a/goal_src/engine/draw/drawable.gc +++ b/goal_src/engine/draw/drawable.gc @@ -851,26 +851,26 @@ ) ) ;; todo - ; (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) - ; (when (nonzero? (-> *merc-globals* first)) - ; (let ((s4-1 (-> *display* frames (-> *display* on-screen) frame global-buf base))) - ; (let ((a0-25 (-> (the-as (pointer uint32) (+ (the-as uint *level*) (* 2608 arg2) (* arg3 32))) 69))) - ; (generic-merc-add-to-cue a0-25) - ; ) - ; (let ((a0-26 *dma-mem-usage*)) - ; (when (nonzero? a0-26) - ; (set! (-> a0-26 length) (max 87 (-> a0-26 length))) - ; (set! (-> a0-26 data 86 name) "pris-generic") - ; (+! (-> a0-26 data 86 count) 1) - ; (+! (-> a0-26 data 86 used) - ; (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint s4-1)) - ; ) - ; (set! (-> a0-26 data 86 total) (-> a0-26 data 86 used)) - ; ) - ; ) - ; ) - ; ) - ; ) + (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) + (when (nonzero? (-> *merc-globals* first)) + (let ((s4-1 (-> *display* frames (-> *display* on-screen) frame global-buf base))) + (let ((a0-25 (-> (the-as (pointer uint32) (+ (the-as uint *level*) (* 2608 arg2) (* arg3 32))) 69))) + (generic-merc-add-to-cue (the-as generic-dma-foreground-sink a0-25)) + ) + (let ((a0-26 *dma-mem-usage*)) + (when (nonzero? a0-26) + (set! (-> a0-26 length) (max 87 (-> a0-26 length))) + (set! (-> a0-26 data 86 name) "pris-generic") + (+! (-> a0-26 data 86 count) 1) + (+! (-> a0-26 data 86 used) + (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint s4-1)) + ) + (set! (-> a0-26 data 86 total) (-> a0-26 data 86 used)) + ) + ) + ) + ) + ) (when #t (let ((v1-41 *shadow-queue*)) (+! (-> v1-41 cur-run) 1) @@ -907,9 +907,12 @@ ) ) "Function to be executed to set up for engine dma" + + ;; update render enables from the debug menu (set! *vu1-enable-user* *vu1-enable-user-menu*) (set! *texture-enable-user* *texture-enable-user-menu*) + ;; reset and display dma memory stats. (when *debug-segment* (when (or *stats-memory* *stats-memory-short*) (dotimes (gp-0 (-> *level* length)) @@ -923,9 +926,9 @@ (reset! *dma-mem-usage*) ) - ;; todo debug memory ;; todo shrub matrix ;; todo generic init + (generic-init-buffers) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; texture uploads @@ -1081,7 +1084,7 @@ ) (let ((gp-9 (-> *display* frames (-> *display* on-screen) frame global-buf))) (bones-mtx-calc-execute) - ;;(generic-merc-execute-all) + (generic-merc-execute-all gp-9) ;;(shadow-execute-all gp-9 *shadow-queue*) ) ;; fg engine diff --git a/goal_src/engine/game/main-h.gc b/goal_src/engine/game/main-h.gc index 419b02bd3a..6cef2eb483 100644 --- a/goal_src/engine/game/main-h.gc +++ b/goal_src/engine/game/main-h.gc @@ -5,6 +5,9 @@ ;; name in dgo: main-h ;; dgos: GAME, ENGINE +;; hacks +(defglobalconstant SKIP_MERC_DEATH_PARTICLES #t) + ;; Global engine settings: (define *stats-poly* #f) (define *stats-memory* #f) diff --git a/goal_src/engine/game/main.gc b/goal_src/engine/game/main.gc index 6e570d4b64..df66ed5b3b 100644 --- a/goal_src/engine/game/main.gc +++ b/goal_src/engine/game/main.gc @@ -582,7 +582,7 @@ (blerc-execute) (blerc-init) (texscroll-execute) - ; (ripple-execute) + (ripple-execute) ;;;;;;;;;;;;;;;;;;;; ;; AMBIENT diff --git a/goal_src/engine/gfx/generic/generic-effect.gc b/goal_src/engine/gfx/generic/generic-effect.gc index 8884e18e8f..e2698781c5 100644 --- a/goal_src/engine/gfx/generic/generic-effect.gc +++ b/goal_src/engine/gfx/generic/generic-effect.gc @@ -5,3 +5,143 @@ ;; name in dgo: generic-effect ;; dgos: GAME, ENGINE +(define-extern *generic-envmap-texture* texture) + +(define *target-lock* (the-as symbol 0)) + +(define *generic-consts* + (new 'static 'generic-consts + :dma-header + (new 'static 'dma-packet + :dma + (new 'static 'dma-tag :id (dma-tag-id cnt)) + :vif0 + (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)) + :vif1 + (new 'static 'vif-tag :cmd (vif-cmd unpack-v4-32)) + ) + :vif-header + (new 'static 'array uint32 4 #x1000404 #x1000404 #x1000404 #x6c000000) + :dma-ref-vtxs + (new 'static 'dma-packet :dma (new 'static 'dma-tag :id (dma-tag-id ref))) + :dma-cnt-call + (new 'static 'dma-packet :dma (new 'static 'dma-tag :id (dma-tag-id cnt))) + :matrix + (new 'static 'matrix + :vector + (new 'static 'inline-array vector 4 + (new 'static 'vector :x 1.0) + (new 'static 'vector :y 1.0) + (new 'static 'vector :z 1.0) + (new 'static 'vector :w 1.0) + ) + ) + :base-strgif + (new 'static 'generic-gif-tag :data (new 'static 'array uint32 4 #x303ec000 #x303e4000 #x412 #x0)) + :alpha-opaque + (new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x0 #x0 #x42 #x0)) + :alpha-translucent + (new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x44 #x0 #x42 #x0)) + :ztest-normal + (new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x5026b #x0 #x47 #x0)) + :ztest-opaque + (new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x5000a #x0 #x47 #x0)) + :adcmd-offsets + (new 'static 'array uint8 16 #x0 #x20 #x10 #x20 #x0 #x30 #x20 #x20 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0) + :stcycle-tag #x1000103 + :unpack-vtx-tag #x68000000 + :unpack-clr-tag #x6e004000 + :unpack-tex-tag #x65000000 + :mscal-tag #x14000006 + :reset-cycle-tag #x1000404 + :dma-tag-cnt #x10000000 + :envmap + (new 'static 'generic-envmap-consts + :consts + (new 'static 'vector :x 1.0 :z 0.5 :w 0.5) + :strgif + (new 'static 'generic-gif-tag :data (new 'static 'array uint32 4 #x302ec000 #x302e4000 #x412 #x0)) + :colors + (new 'static 'vector4w :x -2139062144 :y -2139062144 :z -2139062144 :w -2139062144) + ) + :light-consts + (new 'static 'vector :x 255.0 :y 8388608.0) + ) + ) + +(defun generic-work-init ((arg0 generic-dma-foreground-sink)) + "Initialize generic-work." + ;; copy to scratchpad copy of the work + (quad-copy! (the-as pointer (-> (scratchpad-object terrain-context) work foreground generic-work fx-buf work consts)) + (the-as pointer *generic-consts*) + 27) + ;; set buffer addresses + (set! (-> (scratchpad-object terrain-context) work foreground generic-work saves gifbuf-adr) + (-> arg0 state gifbuf-adr) + ) + (set! (-> (scratchpad-object terrain-context) work foreground generic-work saves inbuf-adr) + (-> arg0 state inbuf-adr) + ) + (set! (-> (scratchpad-object terrain-context) work foreground generic-work saves cur-outbuf) + (the-as uint (+ 8192 (scratchpad-object int))) + ) + + ;; initialize the environment map "shader". This isn't a real shader, but just texturing settings. + (let ((gp-1 (-> (scratchpad-object terrain-context) work foreground generic-work fx-buf work consts envmap shader))) + (let ((a1-1 *generic-envmap-texture*)) + (adgif-shader<-texture! gp-1 a1-1) + ) + (set! (-> gp-1 tex1) (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (set! (-> gp-1 clamp) (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (set! (-> gp-1 alpha) (new 'static 'gs-alpha :b #x2 :c #x1 :d #x1)) + (set! (-> gp-1 prims 1) (gs-reg64 tex0-1)) + (set! (-> gp-1 prims 3) (gs-reg64 tex1-1)) + (set! (-> gp-1 prims 5) (gs-reg64 miptbp1-1)) + (set! (-> gp-1 clamp-reg) (gs-reg64 clamp-1)) + (set! (-> gp-1 prims 9) (gs-reg64 alpha-1)) + ) + (none) + ) + +(defun upload-vu0-program ((func vu-function) (wait-ptr pointer)) + (none) + ) + +(defun generic-initialize-without-sink ((arg0 matrix) (arg1 vu-lights)) + "Prepare for Generic. + Upload the generic vu0 block and set the matrix and lights. + The generic VU0 block is loaded to program address 0." + (upload-vu0-program generic-vu0-block (the-as pointer #x70000064)) + (let (;(a2-0 (+ #x2e20 (the-as int (the-as terrain-context #x70000000)))) + (a2-0 (-> (scratchpad-object terrain-context) work foreground generic-work fx-buf work consts matrix)) + (v1-1 (-> arg0 vector 0 quad)) + (a0-3 (-> arg0 vector 1 quad)) + (a1-2 (-> arg0 vector 2 quad)) + (a3-0 (-> arg0 vector 3 quad)) + ) + ;;(set! (-> (the-as (pointer uint128) a2-0)) v1-1) + (set! (-> a2-0 vector 0 quad) v1-1) + ;;(s.q! (+ a2-0 16) a0-3) + (set! (-> a2-0 vector 1 quad) a0-3) + ;; (s.q! (+ a2-0 32) a1-2) + (set! (-> a2-0 vector 2 quad) a1-2) + ;;(s.q! (+ a2-0 48) a3-0) + (set! (-> a2-0 vector 3 quad) a3-0) + ) + + (if arg1 + ;;(quad-copy! (the-as pointer (+ #x3190 #x70000000)) (the-as pointer arg1) 7) + (quad-copy! (the pointer (-> (scratchpad-object terrain-context) work foreground generic-work fx-buf work lights)) (the-as pointer arg1) 7) + ) + 0 + (none) + ) + +(def-mips2c generic-prepare-dma-single function) + + +(def-mips2c generic-prepare-dma-double function) + +(def-mips2c generic-light-proc function) + +(def-mips2c generic-envmap-proc function) \ No newline at end of file diff --git a/goal_src/engine/gfx/generic/generic-merc.gc b/goal_src/engine/gfx/generic/generic-merc.gc index ef17984d20..4240cfb61b 100644 --- a/goal_src/engine/gfx/generic/generic-merc.gc +++ b/goal_src/engine/gfx/generic/generic-merc.gc @@ -12,6 +12,7 @@ (init-data uint8 :offset-assert 1) (init-addr uint16 :offset-assert 2) ) + :pack-me :method-count-assert 9 :size-assert #x4 :flag-assert #x900000004 @@ -27,17 +28,17 @@ (define *inv-init-table* (new 'static 'inline-array invinitdata 8 (new 'static 'invinitdata :count #x48 :init-addr #x1) + (new 'static 'invinitdata :count #x43 :init-data #xc :init-addr #x11) + (new 'static 'invinitdata :count #x3d :init-data #x18 :init-addr #x21) + (new 'static 'invinitdata :count #x38 :init-data #x22 :init-addr #xe0) (new 'static 'invinitdata :count #x38 :init-data #x24 :init-addr #xe1) - (new 'static 'invinitdata :count #xbe) - (new 'static 'invinitdata :count #x81 :init-data #x80 :init-addr #x3b80) - (new 'static 'invinitdata :count #x88 :init-data #x50 :init-addr #x100a) - (new 'static 'invinitdata :count #x7d :init-data #xb :init-addr #x81e8) - (new 'static 'invinitdata :count #x7d :init-data #x1b :init-addr #x81e8) - (new 'static 'invinitdata :count #x2 :init-data #x68 :init-addr #x5200) + (new 'static 'invinitdata :count #x33 :init-data #x30 :init-addr #xf1) + (new 'static 'invinitdata :count #x2e :init-data #x3a :init-addr #x190) + (new 'static 'invinitdata :count #x2d :init-data #x3c :init-addr #x191) ) ) -;; (def-mips2c generic-merc-init-asm function) ;; TODO mips2c +(def-mips2c generic-merc-init-asm (function none)) ;; (def-mips2c mercneric-matrix-asm function) ;; TODO mips2c @@ -45,20 +46,160 @@ ;; (def-mips2c mercneric-bittable-asm function) ;; TODO mips2c -;; (def-mips2c mercneric-convert function) ;; TODO mips2c +(def-mips2c mercneric-convert function) ;; (def-mips2c high-speed-reject function) ;; TODO mips2c +(def-mips2c high-speed-reject (function none)) +(def-mips2c generic-merc-execute-asm (function none)) ;; TODO mips2c -;; (def-mips2c generic-merc-execute-asm function) ;; TODO mips2c - -(defun generic-merc-add-to-cue ((arg0 basic)) +(defun generic-merc-add-to-cue ((arg0 generic-dma-foreground-sink)) (set! (-> *merc-globals* sink) arg0) (+! (-> *merc-global-array* count) 1) (set! *merc-globals* (-> *merc-global-array* globals (-> *merc-global-array* count))) (none) ) -;; (def-mips2c generic-merc-execute-all function) ;; TODO mips2c +(defun generic-merc-execute-all ((arg0 dma-buffer)) + "Run the EE part of the generic renderer for all generic merc stuff. + This will build DMA data in the format for generic." + (local-vars (a0-26 int) (a0-28 int)) + ;; (format 0 "[GMERC] starting generic-merc-execute-all with ~d to execute~%" (-> *merc-global-array* count)) + (when (nonzero? (-> *merc-global-array* count)) + (let ((gp-0 (-> *display* frames (-> *display* on-screen) frame global-buf base))) + + ;; set up performance stats + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x40 :b #x40 :a #x80) + ) + ) + + (reset! (-> *perf-stats* data 1)) + (set! (-> (scratchpad-object terrain-context) work foreground generic-work saves to-vu0-waits) + (the-as uint 0) + ) + (set! (-> (scratchpad-object terrain-context) work foreground generic-work saves to-spr-waits) + (the-as uint 0) + ) + (set! (-> (scratchpad-object terrain-context) work foreground generic-work saves from-spr-waits) + (the-as uint 0) + ) + (flush-cache 0) + + ;; first, initialize the generic renderer. + (generic-initialize-without-sink (-> *math-camera* perspective) *default-lights*) + + ;; next, initialize the merc-specific stuff. + ;; this give us function pointers to + ;; - mercneric-convert + ;; - generic-prepare-dma-single + ;; - generic-prepare-dma-double + ;; - generic-light-proc + ;; - generic-envmap-proc + ;; - high-speed-reject + ;; and also loads the mercneric-vu0-block block with an offset of 280. + (generic-merc-init-asm) + + ;; set a limit, so we don't write off the end of the dma buffer. + (set! (-> (scratchpad-object terrain-context) work foreground generic-work in-buf merc shadow write-limit) + (&+ (-> arg0 end) -65536) + ) + + (dotimes (s4-0 (the-as int (-> *merc-global-array* count))) + (set! *merc-globals* (-> *merc-global-array* globals s4-0)) + (let ((s3-0 (-> *merc-globals* sink))) + (when (nonzero? (-> *merc-globals* first)) + (let* ((s1-0 (-> *display* frames (-> *display* on-screen) frame global-buf)) + (s2-0 (-> s1-0 base)) + ) + ;; (format 0 "[GMERC] running ~D~%" s4-0) + (generic-work-init s3-0) + (set! (-> (scratchpad-object terrain-context) work foreground generic-work saves basep) + (the-as uint (-> s1-0 base)) + ) + (generic-merc-execute-asm) + (set! (-> s1-0 base) + (the-as pointer (-> (scratchpad-object terrain-context) work foreground generic-work saves basep)) + ) + ;; todo: this part might be important... + ; (let ((v1-36 (the-as object #x1000d000)) + ; (a0-19 (the-as object #x7000006c)) + ; ) + ; (b! (zero? (logand (-> (the-as terrain-context v1-36) bsp lev-index) 256)) cfg-9 :delay (nop!)) + ; (let ((a1-6 (-> (the-as generic-envmap-saves a0-19) index-mask x))) + ; (nop!) + ; (let ((a2-1 (-> (the-as (pointer int32) v1-36) 0))) + ; (nop!) + ; (let ((a2-2 (logand a2-1 256)) + ; (a1-7 (+ a1-6 1)) + ; ) + ; (b! (nonzero? a2-2) cfg-8 :delay (s.w! (the-as int a0-19) a1-7)) + ; ) + ; ) + ; ) + ; ) + ; (label cfg-9) + ; 0 + (let ((a3-0 (-> s1-0 base))) + (let ((v1-38 (the-as object (-> s1-0 base)))) + (set! (-> (the-as dma-packet v1-38) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet v1-38) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-38) vif1) (new 'static 'vif-tag)) + (set! (-> s1-0 base) (&+ (the-as pointer v1-38) 16)) + ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) frame bucket-group) + (-> s3-0 bucket) + s2-0 + (the-as (pointer dma-tag) a3-0) + ) + ) + ) + + ; (let ((v1-44 (-> arg0 base))) + ; (.sync.l) + ; (.cache dxwbin v1-44 0) + ; (.sync.l) + ; (.cache dxwbin v1-44 1) + ; ) + ; (.sync.l) + 0 + ) + ) + ) + (read! (-> *perf-stats* data 1)) + 0 + (update-wait-stats + (-> *perf-stats* data 1) + (-> (scratchpad-object terrain-context) work foreground generic-work saves to-vu0-waits) + (-> (scratchpad-object terrain-context) work foreground generic-work saves to-spr-waits) + (-> (scratchpad-object terrain-context) work foreground generic-work saves from-spr-waits) + ) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) + ) + ) + (let ((v1-64 *dma-mem-usage*)) + (when (nonzero? v1-64) + (set! (-> v1-64 length) (max 87 (-> v1-64 length))) + (set! (-> v1-64 data 86 name) "pris-generic") + (+! (-> v1-64 data 86 count) 1) + (+! (-> v1-64 data 86 used) + (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint gp-0)) + ) + (set! (-> v1-64 data 86 total) (-> v1-64 data 86 used)) + ) + ) + ) + ) + ;; (format 0 "[GMERC] made it to the end of generic-merc-execute-all.~%") + (none) + ) diff --git a/goal_src/engine/gfx/merc/generic-merc-h.gc b/goal_src/engine/gfx/merc/generic-merc-h.gc index fe9c707416..a0a8c9f7cf 100644 --- a/goal_src/engine/gfx/merc/generic-merc-h.gc +++ b/goal_src/engine/gfx/merc/generic-merc-h.gc @@ -92,7 +92,7 @@ (next-chain uint32 :offset-assert 276) (buf-index uint32 :offset-assert 280) (fragment-count uint32 :offset-assert 284) - (write-limit int32 :offset-assert 288) + (write-limit pointer :offset-assert 288) (indexed-input-base generic-merc-input :offset-assert 292) (other-input-base generic-merc-input :offset-assert 296) (indexed-output-base generic-merc-output :offset-assert 300) diff --git a/goal_src/engine/gfx/merc/merc-death.gc b/goal_src/engine/gfx/merc/merc-death.gc index 3621183c58..6c49689d21 100644 --- a/goal_src/engine/gfx/merc/merc-death.gc +++ b/goal_src/engine/gfx/merc/merc-death.gc @@ -86,11 +86,13 @@ ) (defun merc-death-spawn ((arg0 int) (arg1 vector) (arg2 vector)) - (let ((v1-2 (-> *part-id-table* arg0))) - (if (and (nonzero? v1-2) (= (-> v1-2 type) sparticle-launcher)) - (sp-launch-particles-death *sp-particle-system-2d* v1-2 arg1) - ) - ) + (#unless SKIP_MERC_DEATH_PARTICLES + (let ((v1-2 (-> *part-id-table* arg0))) + (if (and (nonzero? v1-2) (= (-> v1-2 type) sparticle-launcher)) + (sp-launch-particles-death *sp-particle-system-2d* v1-2 arg1) + ) + ) + ) 0 (none) ) diff --git a/goal_src/engine/gfx/merc/merc.gc b/goal_src/engine/gfx/merc/merc.gc index 3d6602c2d2..7098a92233 100644 --- a/goal_src/engine/gfx/merc/merc.gc +++ b/goal_src/engine/gfx/merc/merc.gc @@ -93,6 +93,10 @@ (none) ) +(defmethod asize-of merc-fragment-control ((obj merc-fragment-control)) + (the-as int (+ (* (-> obj mat-xfer-count) 2) 4)) + ) + (defmethod inspect merc-fragment-control ((obj merc-fragment-control)) "Debug print a merc-fragment-control" (format #t "[~8x] ~A~%" obj 'merc-fragment-control) diff --git a/goal_src/engine/gfx/ripple.gc b/goal_src/engine/gfx/ripple.gc index cdb89c9d54..4ccebbae04 100644 --- a/goal_src/engine/gfx/ripple.gc +++ b/goal_src/engine/gfx/ripple.gc @@ -5,7 +5,6 @@ ;; name in dgo: ripple ;; dgos: GAME, ENGINE -(define-extern ripple-execute-init (function none)) (define-extern ripple-create-wave-table (function ripple-wave-set int)) (define-extern ripple-apply-wave-table (function merc-effect symbol)) @@ -67,13 +66,13 @@ ) ;; definition for function ripple-execute-init -;; ERROR: function was not converted to expressions. Cannot decompile. +(def-mips2c ripple-execute-init (function none)) ;; definition for function ripple-create-wave-table -;; ERROR: function was not converted to expressions. Cannot decompile. +(def-mips2c ripple-create-wave-table (function ripple-wave-set int)) ;; definition for function ripple-apply-wave-table -;; ERROR: function was not converted to expressions. Cannot decompile. +(def-mips2c ripple-apply-wave-table (function merc-effect symbol)) (defun ripple-execute () (when (-> *ripple-globals* count) diff --git a/goalc/data_compiler/game_subtitle.cpp b/goalc/data_compiler/game_subtitle.cpp index c3c0cd5cce..d87058b2cb 100644 --- a/goalc/data_compiler/game_subtitle.cpp +++ b/goalc/data_compiler/game_subtitle.cpp @@ -40,13 +40,6 @@ const goos::Object& cdr(const goos::Object& x) { return x.as_pair()->cdr; } -std::string get_string(const goos::Object& x) { - if (x.is_string()) { - return x.as_string()->data; - } - throw std::runtime_error(x.print() + " was supposed to be a string, but isn't"); -} - std::string uppercase(const std::string& in) { std::string result; result.reserve(in.size()); diff --git a/test/decompiler/reference/engine/anim/bones-h_REF.gc b/test/decompiler/reference/engine/anim/bones-h_REF.gc index d8e617135f..dd3f38a574 100644 --- a/test/decompiler/reference/engine/anim/bones-h_REF.gc +++ b/test/decompiler/reference/engine/anim/bones-h_REF.gc @@ -162,9 +162,9 @@ ;; definition of type merc-globals (deftype merc-globals (structure) - ((first uint32 :offset-assert 0) - (next uint32 :offset-assert 4) - (sink basic :offset-assert 8) + ((first uint32 :offset-assert 0) + (next (pointer uint32) :offset-assert 4) + (sink generic-dma-foreground-sink :offset-assert 8) ) :allow-misaligned :method-count-assert 9 diff --git a/test/decompiler/reference/engine/anim/joint_REF.gc b/test/decompiler/reference/engine/anim/joint_REF.gc index 935137ee41..054dfac254 100644 --- a/test/decompiler/reference/engine/anim/joint_REF.gc +++ b/test/decompiler/reference/engine/anim/joint_REF.gc @@ -957,9 +957,7 @@ (+! upl-idx 1) ) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 11 scale x) - (the-as float upl-idx) - ) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work num-uploads) upl-idx) ) (dotimes (v1-24 nb-channels) (set! (-> arg0 channel v1-24 inspector-amount) @@ -1281,149 +1279,149 @@ ;; definition for function make-joint-jump-tables (defun make-joint-jump-tables () - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 scale x) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 108 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 0) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 108 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 scale y) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 1) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 scale z) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 233 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 2) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 233 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 scale w) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 3) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 cache bone-matrix) - (the-as uint (+ (the-as uint decompress-fixed-data-to-accumulator) (* 301 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 4) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 301 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 cache parent-matrix) - (the-as uint (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 5) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 cache dummy) - (the-as uint (+ (the-as uint decompress-fixed-data-to-accumulator) (* 387 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 6) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 387 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 cache frame) - (the-as uint (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 7) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 0 x) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 155 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 8) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 155 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 0 y) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 9) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 0 z) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 261 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 10) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 261 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 0 w) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 11) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 1 x) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 335 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 12) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 335 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 1 y) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 13) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 1 z) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 402 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 14) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 402 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 1 w) - (the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 15) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 2 x) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 0) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 2 y) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 92 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 1) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 92 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 2 z) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 2) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 2 w) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 140 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 3) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 140 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 3 x) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 4) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 3 y) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 220 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 5) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 220 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 3 z) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 6) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 3 w) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 307 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 7) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 307 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 scale x) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 8) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 scale y) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 107 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 9) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 107 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 scale z) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 10) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 scale w) - (the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 174 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 11) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 174 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 cache bone-matrix) - (the-as uint (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 12) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 cache parent-matrix) - (the-as uint (+ (the-as uint decompress-frame-data-to-accumulator) (* 248 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 13) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 248 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 cache dummy) - (the-as uint (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 14) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 cache frame) - (the-as uint (+ (the-as uint decompress-frame-data-to-accumulator) (* 354 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 15) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 354 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 0 x) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 0) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 0 y) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 125 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 1) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 125 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 0 z) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 2) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 0 w) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 197 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 3) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 197 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 1 x) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 4) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 1 y) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 318 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 5) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 318 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 1 z) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 6) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 1 w) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 459 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 7) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 459 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 2 x) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 8) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 2 y) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 150 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 9) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 150 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 2 z) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 10) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 2 w) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 248 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 11) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 248 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 3 x) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 12) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 3 y) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 366 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 13) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 366 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 3 z) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 14) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4))) ) - (set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 3 w) - (the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 533 4))) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 15) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 533 4))) ) 0 ) diff --git a/test/decompiler/reference/engine/draw/drawable_REF.gc b/test/decompiler/reference/engine/draw/drawable_REF.gc index 8595becad7..03da4c2bc0 100644 --- a/test/decompiler/reference/engine/draw/drawable_REF.gc +++ b/test/decompiler/reference/engine/draw/drawable_REF.gc @@ -929,7 +929,7 @@ (when (nonzero? (-> *merc-globals* first)) (let ((s4-1 (-> *display* frames (-> *display* on-screen) frame global-buf base))) (let ((a0-25 (-> (the-as (pointer uint32) (+ (the-as uint *level*) (* 2608 arg2) (* arg3 32))) 69))) - (generic-merc-add-to-cue (the-as basic a0-25)) + (generic-merc-add-to-cue (the-as generic-dma-foreground-sink a0-25)) ) (let ((a0-26 *dma-mem-usage*)) (when (nonzero? a0-26) @@ -1322,7 +1322,7 @@ ) (let ((gp-9 (-> *display* frames (-> *display* on-screen) frame global-buf))) (bones-mtx-calc-execute) - (generic-merc-execute-all) + (generic-merc-execute-all gp-9) (shadow-execute-all gp-9 *shadow-queue*) ) (-> *display* frames (-> *display* on-screen) frame global-buf) diff --git a/test/decompiler/reference/engine/gfx/generic/generic-h_REF.gc b/test/decompiler/reference/engine/gfx/generic/generic-h_REF.gc index 03f2252d38..cf50dc7962 100644 --- a/test/decompiler/reference/engine/gfx/generic/generic-h_REF.gc +++ b/test/decompiler/reference/engine/gfx/generic/generic-h_REF.gc @@ -340,8 +340,8 @@ ;; definition for method 3 of type generic-gif-tag (defmethod inspect generic-gif-tag ((obj generic-gif-tag)) (format #t "[~8x] ~A~%" obj 'generic-gif-tag) - (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) - (format #t "~Tqword: #~%" (-> obj data)) + (format #t "~Tdata[4] @ #x~X~%" (&-> obj fan-prim)) + (format #t "~Tqword: #~%" (&-> obj fan-prim)) (format #t "~Tfan-prim: ~D~%" (-> obj fan-prim)) (format #t "~Tstr-prim: ~D~%" (-> obj str-prim)) (format #t "~Tregs: ~D~%" (-> obj regs)) @@ -370,7 +370,7 @@ ;; Used lq/sq (defmethod inspect ad-cmd ((obj ad-cmd)) (format #t "[~8x] ~A~%" obj 'ad-cmd) - (format #t "~Tword[4] @ #x~X~%" (-> obj word)) + (format #t "~Tword[4] @ #x~X~%" (&-> obj data)) (format #t "~Tquad: ~D~%" (-> obj quad)) (format #t "~Tdata: ~D~%" (-> obj data)) (format #t "~Tcmds: ~D~%" (-> obj cmds)) diff --git a/test/decompiler/reference/engine/gfx/generic/generic-merc_REF.gc b/test/decompiler/reference/engine/gfx/generic/generic-merc_REF.gc index 3353b6975f..0b862b4477 100644 --- a/test/decompiler/reference/engine/gfx/generic/generic-merc_REF.gc +++ b/test/decompiler/reference/engine/gfx/generic/generic-merc_REF.gc @@ -10,6 +10,7 @@ (init-data uint8 :offset-assert 1) (init-addr uint16 :offset-assert 2) ) + :pack-me :method-count-assert 9 :size-assert #x4 :flag-assert #x900000004 @@ -27,13 +28,13 @@ ;; definition for symbol *inv-init-table*, type (inline-array invinitdata) (define *inv-init-table* (new 'static 'inline-array invinitdata 8 (new 'static 'invinitdata :count #x48 :init-addr #x1) + (new 'static 'invinitdata :count #x43 :init-data #xc :init-addr #x11) + (new 'static 'invinitdata :count #x3d :init-data #x18 :init-addr #x21) + (new 'static 'invinitdata :count #x38 :init-data #x22 :init-addr #xe0) (new 'static 'invinitdata :count #x38 :init-data #x24 :init-addr #xe1) - (new 'static 'invinitdata :count #xbe) - (new 'static 'invinitdata :count #x81 :init-data #x80 :init-addr #x3b80) - (new 'static 'invinitdata :count #x88 :init-data #x50 :init-addr #x100a) - (new 'static 'invinitdata :count #x7d :init-data #xb :init-addr #x81e8) - (new 'static 'invinitdata :count #x7d :init-data #x1b :init-addr #x81e8) - (new 'static 'invinitdata :count #x2 :init-data #x68 :init-addr #x5200) + (new 'static 'invinitdata :count #x33 :init-data #x30 :init-addr #xf1) + (new 'static 'invinitdata :count #x2e :init-data #x3a :init-addr #x190) + (new 'static 'invinitdata :count #x2d :init-data #x3c :init-addr #x191) ) ) @@ -60,7 +61,7 @@ ;; definition for function generic-merc-add-to-cue ;; INFO: Return type mismatch merc-globals vs none. -(defun generic-merc-add-to-cue ((arg0 basic)) +(defun generic-merc-add-to-cue ((arg0 generic-dma-foreground-sink)) (set! (-> *merc-globals* sink) arg0) (+! (-> *merc-global-array* count) 1) (set! *merc-globals* (-> *merc-global-array* globals (-> *merc-global-array* count))) @@ -68,8 +69,176 @@ ) ;; definition for function generic-merc-execute-all -;; ERROR: function was not converted to expressions. Cannot decompile. - - - - +;; INFO: Return type mismatch profile-frame vs none. +;; WARN: Unsupported inline assembly instruction kind - [mtc0 Perf, r0] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [sync.p] +;; WARN: Unsupported inline assembly instruction kind - [mtpc pcr0, r0] +;; WARN: Unsupported inline assembly instruction kind - [mtpc pcr1, r0] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [sync.p] +;; WARN: Unsupported inline assembly instruction kind - [mtc0 Perf, a0] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [sync.p] +;; WARN: Unsupported inline assembly instruction kind - [mtc0 Perf, r0] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [sync.p] +;; WARN: Unsupported inline assembly instruction kind - [mfpc a0, pcr0] +;; WARN: Unsupported inline assembly instruction kind - [mfpc a0, pcr1] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [cache dxwbin v1, 0] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +;; WARN: Unsupported inline assembly instruction kind - [cache dxwbin v1, 1] +;; WARN: Unsupported inline assembly instruction kind - [sync.l] +(defun generic-merc-execute-all ((arg0 dma-buffer)) + (local-vars (a0-26 int) (a0-28 int)) + (when (nonzero? (-> *merc-global-array* count)) + (let ((gp-0 (-> *display* frames (-> *display* on-screen) frame global-buf base))) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #x40 :b #x40 :a #x80) + ) + ) + (let* ((v1-15 (-> *perf-stats* data 1)) + (a0-8 (-> v1-15 ctrl)) + ) + (+! (-> v1-15 count) 1) + (b! (zero? a0-8) cfg-5 :delay (nop!)) + (.mtc0 Perf r0) + (.sync.l) + (.sync.p) + (.mtpc pcr0 r0) + (.mtpc pcr1 r0) + (.sync.l) + (.sync.p) + (.mtc0 Perf a0-8) + ) + (.sync.l) + (.sync.p) + (label cfg-5) + 0 + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 y) + (the-as float 0) + ) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 z) + (the-as float 0) + ) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 w) + (the-as float 0) + ) + (flush-cache 0) + (generic-initialize-without-sink (-> *math-camera* perspective) *default-lights*) + (generic-merc-init-asm) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work tq-acc 99 trans x) + (the-as float (&+ (-> arg0 end) -65536)) + ) + (dotimes (s4-0 (the-as int (-> *merc-global-array* count))) + (set! *merc-globals* (-> *merc-global-array* globals s4-0)) + (let ((s3-0 (-> *merc-globals* sink))) + (when (nonzero? (-> *merc-globals* first)) + (let* ((s1-0 (-> *display* frames (-> *display* on-screen) frame global-buf)) + (s2-0 (-> s1-0 base)) + ) + (generic-work-init s3-0) + (set! (-> (the-as terrain-context #x70000000) work foreground joint-work temp-mtx vector 3 w) + (the-as float (-> s1-0 base)) + ) + (generic-merc-execute-asm) + (set! (-> s1-0 base) + (the-as pointer (-> (the-as terrain-context #x70000000) work foreground joint-work temp-mtx vector 3 w)) + ) + (let ((v1-36 (the-as object #x1000d000)) + (a0-19 (the-as object #x7000006c)) + ) + (b! (zero? (logand (-> (the-as terrain-context v1-36) bsp lev-index) 256)) cfg-9 :delay (nop!)) + (let ((a1-6 (-> (the-as generic-envmap-saves a0-19) index-mask x))) + (nop!) + (let ((a2-1 (-> (the-as (pointer int32) v1-36) 0))) + (nop!) + (let ((a2-2 (logand a2-1 256)) + (a1-7 (+ a1-6 1)) + ) + (b! (nonzero? a2-2) cfg-8 :delay (s.w! (the-as int a0-19) a1-7)) + ) + ) + ) + ) + (label cfg-9) + 0 + (let ((a3-0 (-> s1-0 base))) + (let ((v1-38 (the-as object (-> s1-0 base)))) + (set! (-> (the-as dma-packet v1-38) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet v1-38) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-38) vif1) (new 'static 'vif-tag)) + (set! (-> s1-0 base) (&+ (the-as pointer v1-38) 16)) + ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) frame bucket-group) + (-> s3-0 bucket) + s2-0 + (the-as (pointer dma-tag) a3-0) + ) + ) + ) + (let ((v1-44 (-> arg0 base))) + (.sync.l) + (.cache dxwbin v1-44 0) + (.sync.l) + (.cache dxwbin v1-44 1) + ) + (.sync.l) + 0 + ) + ) + ) + (let ((v1-51 (-> *perf-stats* data 1))) + (b! (zero? (-> v1-51 ctrl)) cfg-14 :delay (nop!)) + (.mtc0 Perf r0) + (.sync.l) + (.sync.p) + (.mfpc a0-26 pcr0) + (+! (-> v1-51 accum0) a0-26) + (.mfpc a0-28 pcr1) + (+! (-> v1-51 accum1) a0-28) + ) + (label cfg-14) + 0 + (update-wait-stats + (-> *perf-stats* data 1) + (the-as + uint + (-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 y) + ) + (the-as + uint + (-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 z) + ) + (the-as + uint + (-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 w) + ) + ) + (if *debug-segment* + (add-frame + (-> *display* frames (-> *display* on-screen) frame profile-bar 0) + 'draw + (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) + ) + ) + (let ((v1-64 *dma-mem-usage*)) + (when (nonzero? v1-64) + (set! (-> v1-64 length) (max 87 (-> v1-64 length))) + (set! (-> v1-64 data 86 name) "pris-generic") + (+! (-> v1-64 data 86 count) 1) + (+! (-> v1-64 data 86 used) + (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint gp-0)) + ) + (set! (-> v1-64 data 86 total) (-> v1-64 data 86 used)) + ) + ) + ) + ) + (none) + ) diff --git a/test/decompiler/reference/engine/gfx/merc/generic-merc-h_REF.gc b/test/decompiler/reference/engine/gfx/merc/generic-merc-h_REF.gc index a93c1286bc..a1a7b9cf62 100644 --- a/test/decompiler/reference/engine/gfx/merc/generic-merc-h_REF.gc +++ b/test/decompiler/reference/engine/gfx/merc/generic-merc-h_REF.gc @@ -176,7 +176,7 @@ (next-chain uint32 :offset-assert 276) (buf-index uint32 :offset-assert 280) (fragment-count uint32 :offset-assert 284) - (write-limit int32 :offset-assert 288) + (write-limit pointer :offset-assert 288) (indexed-input-base generic-merc-input :offset-assert 292) (other-input-base generic-merc-input :offset-assert 296) (indexed-output-base generic-merc-output :offset-assert 300) diff --git a/test/decompiler/reference/engine/gfx/shadow/shadow-vu1_REF.gc b/test/decompiler/reference/engine/gfx/shadow/shadow-vu1_REF.gc index a3b6c42874..194dea0956 100644 --- a/test/decompiler/reference/engine/gfx/shadow/shadow-vu1_REF.gc +++ b/test/decompiler/reference/engine/gfx/shadow/shadow-vu1_REF.gc @@ -64,66 +64,64 @@ ) ;; definition for symbol *shadow-vu1-tri-template*, type shadow-vu1-gifbuf-template -(define - *shadow-vu1-tri-template* - (new 'static 'shadow-vu1-gifbuf-template - :adgif - (new 'static 'gs-gif-tag - :tag - (new 'static 'gif-tag64 :nloop #x1 :nreg #x1) - :regs - (new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d)) - ) - :ad - (new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x0 #x0 #x3f #x0)) - :flush - (new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x0 #x3f800000 #x1 #x0)) - :trigif - (new 'static 'gs-gif-tag - :tag - (new 'static 'gif-tag64 - :nloop #x1 - :eop #x1 - :pre #x1 - :prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1) - :nreg #x7 +(define *shadow-vu1-tri-template* (new 'static 'shadow-vu1-gifbuf-template + :adgif + (new 'static 'gs-gif-tag + :tag + (new 'static 'gif-tag64 :nloop #x1 :nreg #x1) + :regs + (new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d)) + ) + :ad + (new 'static 'ad-cmd :cmd (gs-reg texflush)) + :flush + (new 'static 'ad-cmd :data #x3f80000000000000 :cmd (gs-reg rgbaq)) + :trigif + (new 'static 'gs-gif-tag + :tag + (new 'static 'gif-tag64 + :nloop #x1 + :eop #x1 + :pre #x1 + :prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1) + :nreg #x7 + ) + :regs + (new 'static 'gif-tag-regs + :regs0 (gif-reg-id rgbaq) + :regs1 (gif-reg-id st) + :regs2 (gif-reg-id xyzf2) + :regs3 (gif-reg-id st) + :regs4 (gif-reg-id xyzf2) + :regs5 (gif-reg-id st) + :regs6 (gif-reg-id xyzf2) + ) + ) + :quadgif + (new 'static 'gs-gif-tag + :tag + (new 'static 'gif-tag64 + :nloop #x1 + :eop #x1 + :pre #x1 + :prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1) + :nreg #x9 + ) + :regs + (new 'static 'gif-tag-regs + :regs0 (gif-reg-id rgbaq) + :regs1 (gif-reg-id st) + :regs2 (gif-reg-id xyzf2) + :regs3 (gif-reg-id st) + :regs4 (gif-reg-id xyzf2) + :regs5 (gif-reg-id st) + :regs6 (gif-reg-id xyzf2) + :regs7 (gif-reg-id st) + :regs8 (gif-reg-id xyzf2) + ) + ) + ) ) - :regs - (new 'static 'gif-tag-regs - :regs0 (gif-reg-id rgbaq) - :regs1 (gif-reg-id st) - :regs2 (gif-reg-id xyzf2) - :regs3 (gif-reg-id st) - :regs4 (gif-reg-id xyzf2) - :regs5 (gif-reg-id st) - :regs6 (gif-reg-id xyzf2) - ) - ) - :quadgif - (new 'static 'gs-gif-tag - :tag - (new 'static 'gif-tag64 - :nloop #x1 - :eop #x1 - :pre #x1 - :prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1) - :nreg #x9 - ) - :regs - (new 'static 'gif-tag-regs - :regs0 (gif-reg-id rgbaq) - :regs1 (gif-reg-id st) - :regs2 (gif-reg-id xyzf2) - :regs3 (gif-reg-id st) - :regs4 (gif-reg-id xyzf2) - :regs5 (gif-reg-id st) - :regs6 (gif-reg-id xyzf2) - :regs7 (gif-reg-id st) - :regs8 (gif-reg-id xyzf2) - ) - ) - ) - ) ;; definition for symbol shadow-vu1-block, type vu-function (define shadow-vu1-block (new 'static 'vu-function :length #x2e4 :qlength #x172)) @@ -247,7 +245,3 @@ ) (none) ) - - - - diff --git a/test/decompiler/reference/engine/gfx/tfrag/subdivide-h_REF.gc b/test/decompiler/reference/engine/gfx/tfrag/subdivide-h_REF.gc index cc6d5a0d37..dddd944826 100644 --- a/test/decompiler/reference/engine/gfx/tfrag/subdivide-h_REF.gc +++ b/test/decompiler/reference/engine/gfx/tfrag/subdivide-h_REF.gc @@ -298,10 +298,10 @@ ;; definition for method 3 of type foreground-area (defmethod inspect foreground-area ((obj foreground-area)) (format #t "[~8x] ~A~%" obj 'foreground-area) - (format #t "~Tjoint-work: #~%" (-> obj bone-mem)) - (format #t "~Tgeneric-work: #~%" (-> obj bone-mem)) - (format #t "~Tbone-mem: #~%" (-> obj bone-mem)) - (format #t "~Tshadow-work: #~%" (-> obj bone-mem)) + (format #t "~Tjoint-work: #~%" (-> obj joint-work)) + (format #t "~Tgeneric-work: #~%" (-> obj joint-work)) + (format #t "~Tbone-mem: #~%" (-> obj joint-work)) + (format #t "~Tshadow-work: #~%" (-> obj joint-work)) obj ) diff --git a/test/decompiler/test_VuDisasm.cpp b/test/decompiler/test_VuDisasm.cpp index 6122237a7a..e8a1424ae6 100644 --- a/test/decompiler/test_VuDisasm.cpp +++ b/test/decompiler/test_VuDisasm.cpp @@ -73,15 +73,29 @@ TEST(VuDisasm, OceanVu0) { TEST(VuDisasm, GenericVu0) { auto data = get_test_data("generic-vu0"); VuDisassembler disasm(VuDisassembler::VuKind::VU0); + // disasm.add_label_with_name(48, "JUMP_48"); auto prog = disasm.disassemble(data.data(), data.size() * 4, false); EXPECT_EQ(disasm.to_string(prog), get_expected("generic-vu0")); + // fmt::print("{}\n", disasm.to_string_with_cpp(prog, true)); } TEST(VuDisasm, MercnericVu0) { auto data = get_test_data("mercneric-vu0"); VuDisassembler disasm(VuDisassembler::VuKind::VU0); + // disasm.add_label_with_name(314 - 280, "JUMP_314"); + // disasm.add_label_with_name(326 - 280, "JUMP_326"); + // disasm.add_label_with_name(353 - 280, "JUMP_353"); + // disasm.add_label_with_name(386 - 280, "JUMP_386"); + // disasm.add_label_with_name(427 - 280, "JUMP_427"); + // disasm.add_label_with_name(438 - 280, "JUMP_438"); + // disasm.add_label_with_name(454 - 280, "JUMP_454"); + auto prog = disasm.disassemble(data.data(), data.size() * 4, false); EXPECT_EQ(disasm.to_string(prog), get_expected("mercneric-vu0")); + // disasm.add_label_with_name(0, "vcallms_280"); + // disasm.add_label_with_name(303 - 280, "vcallms_303"); + + // fmt::print("{}\n", disasm.to_string_with_cpp(prog, true)); } TEST(VuDisasm, OceanTexture) { @@ -138,6 +152,7 @@ TEST(VuDisasm, Generic) { VuDisassembler disasm(VuDisassembler::VuKind::VU1); auto prog = disasm.disassemble(data.data(), data.size() * 4, false); EXPECT_EQ(disasm.to_string(prog), get_expected("generic")); + fmt::print("{}\n", disasm.to_string_with_cpp(prog, false)); } TEST(VuDisasm, TieNear) { diff --git a/test/offline/config.jsonc b/test/offline/config.jsonc index 8b2f85322c..2d32db673c 100644 --- a/test/offline/config.jsonc +++ b/test/offline/config.jsonc @@ -231,7 +231,8 @@ "curve-evaluate!", - "generic-reset-buffers" + "generic-reset-buffers", + "generic-merc-execute-all" ], "skip_compile_states": { diff --git a/third-party/fpng/fpng.cpp b/third-party/fpng/fpng.cpp index 1b889306a6..8452e2a9fc 100644 --- a/third-party/fpng/fpng.cpp +++ b/third-party/fpng/fpng.cpp @@ -289,7 +289,7 @@ namespace fpng return crc32_slice_by_4(buf + simd_len, len - simd_len, c); } #endif - +/* #ifndef _MSC_VER static void do_cpuid(uint32_t eax, uint32_t ecx, uint32_t* regs) { @@ -307,6 +307,7 @@ namespace fpng regs[0] = eax; regs[1] = ebx; regs[2] = ecx; regs[3] = edx; } #endif +*/ #if FPNG_X86_OR_X64_CPU && !FPNG_NO_SSE struct cpu_info @@ -1591,8 +1592,8 @@ do_literals: for (y = 0; y < h; ++y) { - const uint8_t* pSrc = (uint8_t*)pImage + y * bpl; - const uint8_t* pPrev_src = y ? ((uint8_t*)pImage + (y - 1) * bpl) : nullptr; + const uint8_t* pSrc = (const uint8_t*)pImage + y * bpl; + const uint8_t* pPrev_src = y ? ((const uint8_t*)pImage + (y - 1) * bpl) : nullptr; uint8_t* pDst = &temp_buf[temp_buf_ofs]; @@ -1636,7 +1637,7 @@ do_literals: for (y = 0; y < h; ++y) { - const uint8_t* pSrc = (uint8_t*)pImage + y * bpl; + const uint8_t* pSrc = (const uint8_t*)pImage + y * bpl; uint8_t* pDst = &temp_buf[temp_buf_ofs]; diff --git a/third-party/imgui/imconfig.h b/third-party/imgui/imconfig.h index a0c86caada..c457042810 100644 --- a/third-party/imgui/imconfig.h +++ b/third-party/imgui/imconfig.h @@ -14,9 +14,13 @@ #pragma once +#include "common/util/Assert.h" + //---- Define assertion handler. Defaults to calling assert(). // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. -//#define IM_ASSERT(_EXPR) MyAssert(_EXPR) +#ifdef __linux__ +#define IM_ASSERT(_EXPR) ASSERT(_EXPR) +#endif //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows