diff --git a/decompiler/IR2/AtomicOp.cpp b/decompiler/IR2/AtomicOp.cpp index f8da73b146..09e6bdf063 100644 --- a/decompiler/IR2/AtomicOp.cpp +++ b/decompiler/IR2/AtomicOp.cpp @@ -289,6 +289,8 @@ std::string get_simple_expression_op_name(SimpleExpression::Kind kind) { return "max.si"; case SimpleExpression::Kind::MAX_UNSIGNED: return "max.ui"; + case SimpleExpression::Kind::PCPYLD: + return "pcypld"; default: assert(false); return {}; @@ -338,6 +340,7 @@ int get_simple_expression_arg_count(SimpleExpression::Kind kind) { case SimpleExpression::Kind::MIN_UNSIGNED: case SimpleExpression::Kind::MAX_SIGNED: case SimpleExpression::Kind::MAX_UNSIGNED: + case SimpleExpression::Kind::PCPYLD: return 2; default: assert(false); diff --git a/decompiler/IR2/AtomicOp.h b/decompiler/IR2/AtomicOp.h index 8f3aaf44ad..01f37a3afd 100644 --- a/decompiler/IR2/AtomicOp.h +++ b/decompiler/IR2/AtomicOp.h @@ -221,7 +221,8 @@ class SimpleExpression { MIN_SIGNED, MAX_SIGNED, MIN_UNSIGNED, - MAX_UNSIGNED + MAX_UNSIGNED, + PCPYLD, }; // how many arguments? diff --git a/decompiler/IR2/AtomicOpForm.cpp b/decompiler/IR2/AtomicOpForm.cpp index 89a1d963c9..b1c77bd1bf 100644 --- a/decompiler/IR2/AtomicOpForm.cpp +++ b/decompiler/IR2/AtomicOpForm.cpp @@ -636,7 +636,10 @@ Form* LoadVarOp::get_load_src(FormPool& pool, const Env& env) const { // smaller. We should check that the higher bits are all zero. int bits = as_bitfield->get_size_in_memory() * 8; assert(bits <= 64); - assert((value >> bits) == 0); + if (bits < 64) { + assert((value >> bits) == 0); + // technically ub if bits == 64. + } TypeSpec typespec(hint->second.type_name); auto defs = decompile_bitfield_from_int(typespec, ts, value); return pool.alloc_single_element_form(nullptr, typespec, defs, diff --git a/decompiler/IR2/AtomicOpTypeAnalysis.cpp b/decompiler/IR2/AtomicOpTypeAnalysis.cpp index 8fa14e2aa7..06a893b162 100644 --- a/decompiler/IR2/AtomicOpTypeAnalysis.cpp +++ b/decompiler/IR2/AtomicOpTypeAnalysis.cpp @@ -192,6 +192,7 @@ TP_Type SimpleExpression::get_type(const TypeState& input, return get_type_int1(input, env, dts); case Kind::DIV_UNSIGNED: case Kind::MOD_UNSIGNED: + case Kind::PCPYLD: return TP_Type::make_from_ts("uint"); default: throw std::runtime_error("Simple expression can't get_type: " + diff --git a/decompiler/IR2/Form.cpp b/decompiler/IR2/Form.cpp index 2352dc85b4..7f383bde62 100644 --- a/decompiler/IR2/Form.cpp +++ b/decompiler/IR2/Form.cpp @@ -1503,6 +1503,8 @@ std::string fixed_operator_to_string(FixedOperatorKind kind) { return "pair?"; case FixedOperatorKind::NONE: return "none"; + case FixedOperatorKind::PCPYLD: + return ".pcpyld"; default: assert(false); return ""; diff --git a/decompiler/IR2/Form.h b/decompiler/IR2/Form.h index b63b2c3ddb..c794da2204 100644 --- a/decompiler/IR2/Form.h +++ b/decompiler/IR2/Form.h @@ -177,6 +177,11 @@ class SimpleExpressionElement : public FormElement { FormStack& stack, std::vector* result, bool allow_side_effects); + void update_from_stack_pcypld(const Env& env, + FormPool& pool, + FormStack& stack, + std::vector* result, + bool allow_side_effects); const SimpleExpression& expr() const { return m_expr; } diff --git a/decompiler/IR2/FormExpressionAnalysis.cpp b/decompiler/IR2/FormExpressionAnalysis.cpp index 920d531ccf..3c22186296 100644 --- a/decompiler/IR2/FormExpressionAnalysis.cpp +++ b/decompiler/IR2/FormExpressionAnalysis.cpp @@ -201,6 +201,19 @@ void pop_helper(const std::vector& vars, } } +namespace { +Form* strip_pcypld_64(Form* in) { + auto m = match(Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::PCPYLD), + {Matcher::integer(0), Matcher::any(0)}), + in); + if (m.matched) { + return m.maps.forms.at(0); + } else { + return in; + } +} +} // namespace + /*! * This should be used to generate all casts. */ @@ -213,6 +226,9 @@ Form* cast_form(Form* in, const TypeSpec& new_type, FormPool& pool, const Env& e auto type_info = env.dts->ts.lookup_type(new_type); auto bitfield_info = dynamic_cast(type_info); if (bitfield_info) { + if (bitfield_info->get_load_size() == 8) { + in = strip_pcypld_64(in); + } return cast_to_bitfield(bitfield_info, new_type, pool, env, in); } @@ -314,13 +330,6 @@ bool is_ptr_or_child(const Env& env, int my_idx, RegisterAccess var, bool) { return type == "pointer"; } -bool is_var(Form* form) { - auto atom = form_as_atom(form); - if (atom) { - return atom->is_var(); - } - return false; -} } // namespace /*! @@ -846,6 +855,36 @@ void SimpleExpressionElement::update_from_stack_force_ui_2(const Env& env, result->push_back(new_form); } +void SimpleExpressionElement::update_from_stack_pcypld(const Env& env, + FormPool& pool, + FormStack& stack, + std::vector* result, + bool allow_side_effects) { + std::vector args; + std::vector ras; + for (int arg_idx = 0; arg_idx < m_expr.args(); arg_idx++) { + if (m_expr.get_arg(arg_idx).is_var()) { + ras.push_back(m_expr.get_arg(arg_idx).var()); + } + } + auto popped_args = pop_to_forms(ras, env, pool, stack, allow_side_effects); + + int ras_idx = 0; + for (int arg_idx = 0; arg_idx < m_expr.args(); arg_idx++) { + if (m_expr.get_arg(arg_idx).is_var()) { + args.push_back(popped_args.at(ras_idx)); + ras_idx++; + } else { + args.push_back( + pool.alloc_single_element_form(nullptr, m_expr.get_arg(arg_idx))); + } + } + + auto new_form = pool.alloc_element( + GenericOperator::make_fixed(FixedOperatorKind::PCPYLD), args.at(0), args.at(1)); + result->push_back(new_form); +} + void SimpleExpressionElement::update_from_stack_copy_first_int_2(const Env& env, FixedOperatorKind kind, FormPool& pool, @@ -966,9 +1005,11 @@ void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env, if (bitfield_info) { // either the immediate didn't fit in the 16-bit imm or it's with a variable + bool made_new_read_elt = false; auto read_elt = dynamic_cast(args.at(0)->try_as_single_element()); if (!read_elt) { read_elt = pool.alloc_element(args.at(0), arg0_type); + made_new_read_elt = true; } auto stripped_arg1 = strip_int_or_uint_cast(args.at(1)); @@ -987,7 +1028,7 @@ void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env, assert(!other); // shouldn't be complete. result->push_back(read_elt); return; - } else { + } else if (!made_new_read_elt) { BitfieldManip::Kind manip_kind; if (kind == FixedOperatorKind::LOGAND) { manip_kind = BitfieldManip::Kind::LOGAND_WITH_FORM; @@ -1325,6 +1366,9 @@ void SimpleExpressionElement::update_from_stack(const Env& env, case SimpleExpression::Kind::FLOAT_TO_INT: update_from_stack_float_to_int(env, pool, stack, result, allow_side_effects); break; + case SimpleExpression::Kind::PCPYLD: + update_from_stack_pcypld(env, pool, stack, result, allow_side_effects); + break; default: throw std::runtime_error( fmt::format("SimpleExpressionElement::update_from_stack NYI for {}", to_string(env))); @@ -2292,14 +2336,20 @@ void ShortCircuitElement::update_from_stack(const Env& env, already_rewritten = true; } +namespace { +Matcher make_int_uint_cast_matcher(const Matcher& thing) { + return Matcher::match_or({Matcher::cast("uint", thing), Matcher::cast("int", thing), thing}); +} +} // namespace + /////////////////// // ConditionElement /////////////////// -FormElement* ConditionElement::make_zero_check_generic(const Env&, +FormElement* ConditionElement::make_zero_check_generic(const Env& env, FormPool& pool, const std::vector& source_forms, - const std::vector&) { + const std::vector& source_types) { // (zero? (+ thing small-integer)) -> (= thing (- small-integer)) assert(source_forms.size() == 1); auto mr = match(Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::ADDITION), @@ -2311,9 +2361,26 @@ FormElement* ConditionElement::make_zero_check_generic(const Env&, nullptr, SimpleAtom::make_int_constant(value)); return pool.alloc_element(GenericOperator::make_fixed(FixedOperatorKind::EQ), std::vector{mr.maps.forms.at(0), value_form}); - } else { - return pool.alloc_element(GenericOperator::make_compare(m_kind), source_forms); } + + auto enum_type_info = env.dts->ts.try_enum_lookup(source_types.at(0)); + if (enum_type_info && !enum_type_info->is_bitfield()) { + // (zero? (+ (the-as uint arg0) (the-as uint -2))) check enum value + mr = match(Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::ADDITION), + {make_int_uint_cast_matcher(Matcher::any(0)), + make_int_uint_cast_matcher(Matcher::any_integer(1))}), + source_forms.at(0)); + if (mr.matched) { + s64 value = mr.maps.ints.at(1); + value = -value; + auto enum_constant = cast_to_int_enum(enum_type_info, pool, env, value); + return pool.alloc_element( + GenericOperator::make_fixed(FixedOperatorKind::EQ), + std::vector{mr.maps.forms.at(0), enum_constant}); + } + } + + return pool.alloc_element(GenericOperator::make_compare(m_kind), source_forms); } FormElement* ConditionElement::make_nonzero_check_generic(const Env& env, @@ -2682,6 +2749,7 @@ void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta } namespace { + void push_asm_srl_to_stack(const AsmOp* op, FormElement* form_elt, const Env& env, @@ -2714,6 +2782,21 @@ void push_asm_srl_to_stack(const AsmOp* op, } } +void push_asm_to_stack(const AsmOp* op, + FormElement* form_elt, + const Env& env, + FormPool& pool, + FormStack& stack) { + switch (op->instruction().kind) { + case InstructionKind::SRL: + push_asm_srl_to_stack(op, form_elt, env, pool, stack); + break; + default: + stack.push_form_element(form_elt, true); + break; + } +} + } // namespace void AtomicOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) { @@ -2737,14 +2820,7 @@ void AtomicOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& s auto as_asm = dynamic_cast(m_op); if (as_asm) { - switch (as_asm->instruction().kind) { - case InstructionKind::SRL: - push_asm_srl_to_stack(as_asm, this, env, pool, stack); - break; - default: - stack.push_form_element(this, true); - break; - } + push_asm_to_stack(as_asm, this, env, pool, stack); return; } @@ -2753,15 +2829,7 @@ void AtomicOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& s void AsmOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) { mark_popped(); - - switch (m_op->instruction().kind) { - case InstructionKind::SRL: - push_asm_srl_to_stack(m_op, this, env, pool, stack); - break; - default: - stack.push_form_element(this, true); - break; - } + push_asm_to_stack(m_op, this, env, pool, stack); } void GenericElement::update_from_stack(const Env& env, diff --git a/decompiler/IR2/IR2_common.h b/decompiler/IR2/IR2_common.h index 82973b86f2..b8820976c9 100644 --- a/decompiler/IR2/IR2_common.h +++ b/decompiler/IR2/IR2_common.h @@ -141,6 +141,7 @@ enum class FixedOperatorKind { NULLP, PAIRP, NONE, + PCPYLD, INVALID }; diff --git a/decompiler/IR2/OpenGoalMapping.cpp b/decompiler/IR2/OpenGoalMapping.cpp index d7b1a69823..a63d03a4f1 100644 --- a/decompiler/IR2/OpenGoalMapping.cpp +++ b/decompiler/IR2/OpenGoalMapping.cpp @@ -9,8 +9,8 @@ typedef OpenGOALAsm::InstructionModifiers MOD; const std::map MIPS_ASM_TO_OPEN_GOAL_FUNCS = { // ----- EE ------- // TODO - these are waiting on proper 128-bit int support in OpenGOAL - {InstructionKind::PSLLW, {"TODO.PSLLW", {}}}, - {InstructionKind::PSRAW, {"TODO.PSRAW", {}}}, + {InstructionKind::PSLLW, {".pw.sll", {}}}, + {InstructionKind::PSRAW, {".pw.sra", {}}}, {InstructionKind::PSUBW, {"TODO.PSUBW", {}}}, {InstructionKind::PEXTUW, {".pextuw", {}}}, diff --git a/decompiler/IR2/bitfields.cpp b/decompiler/IR2/bitfields.cpp index 0fad82f8aa..cd285502c9 100644 --- a/decompiler/IR2/bitfields.cpp +++ b/decompiler/IR2/bitfields.cpp @@ -216,6 +216,24 @@ std::optional get_bitfield_initial_set(Form* form, return def; } + // also possible to omit the shr if it would be zero: + auto matcher_no_shr = Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::SHL), + {Matcher::any(0), Matcher::any_integer(1)}); + auto mr_no_shr = match(matcher_no_shr, strip_int_or_uint_cast(form)); + if (mr_no_shr.matched) { + auto value = mr_no_shr.maps.forms.at(0); + int left = mr_no_shr.maps.ints.at(1); + int right = 0; + int size = 64 - left; + int offset = left - right; + auto& f = find_field(ts, type, offset, size, {}); + BitFieldDef def; + def.value = value; + def.field_name = f.name(); + def.is_signed = false; // we don't know. + return def; + } + return {}; } @@ -228,7 +246,7 @@ std::optional get_bitfield_initial_set(Form* form, FormElement* BitfieldAccessElement::push_step(const BitfieldManip step, const TypeSystem& ts, FormPool& pool, - const Env& env) { + const Env&) { if (m_steps.empty() && step.kind == BitfieldManip::Kind::LEFT_SHIFT) { // for left/right shift combo to get a field. m_steps.push_back(step); @@ -354,6 +372,12 @@ FormElement* BitfieldAccessElement::push_step(const BitfieldManip step, std::vector{*val}); } + lg::error("Invalid state in BitfieldReadElement. Previous steps:"); + for (auto& old_step : m_steps) { + lg::error(" {}", old_step.print()); + } + lg::error("Current: {}\n", step.print()); + throw std::runtime_error("Unknown state in BitfieldReadElement"); } @@ -409,8 +433,14 @@ BitFieldDef BitFieldDef::from_constant(const BitFieldConstantDef& constant, Form BitFieldDef bfd; bfd.field_name = constant.field_name; bfd.is_signed = constant.is_signed; - bfd.value = pool.alloc_single_element_form( - nullptr, SimpleAtom::make_int_constant(constant.value)); + if (constant.enum_constant) { + bfd.value = + pool.alloc_single_element_form(nullptr, *constant.enum_constant); + } else { + bfd.value = pool.alloc_single_element_form( + nullptr, SimpleAtom::make_int_constant(constant.value)); + } + return bfd; } @@ -426,7 +456,7 @@ Form* cast_to_bitfield(const BitFieldType* type_info, in = strip_int_or_uint_cast(in); // check if it's just a constant: auto in_as_atom = form_as_atom(in); - if (in_as_atom) { + if (in_as_atom && in_as_atom->is_int()) { auto fields = decompile_bitfield_from_int(typespec, env.dts->ts, in_as_atom->get_int()); return pool.alloc_single_element_form(nullptr, typespec, fields, pool); @@ -458,7 +488,8 @@ Form* cast_to_bitfield(const BitFieldType* type_info, // now variables for (auto& arg : args) { - auto maybe_field = get_bitfield_initial_set(arg, type_info, env.dts->ts); + auto maybe_field = + get_bitfield_initial_set(strip_int_or_uint_cast(arg), type_info, env.dts->ts); if (!maybe_field) { // failed, just return cast. return pool.alloc_single_element_form(nullptr, typespec, in); @@ -503,16 +534,19 @@ Form* cast_to_int_enum(const EnumType* type_info, assert(!type_info->is_bitfield()); auto integer = get_goal_integer_constant(strip_int_or_uint_cast(in), env); if (integer) { - auto entry = - decompile_int_enum_from_int(TypeSpec(type_info->get_name()), env.dts->ts, *integer); - auto oper = GenericOperator::make_function( - pool.alloc_single_element_form(nullptr, type_info->get_name())); - return pool.alloc_single_element_form( - nullptr, oper, pool.alloc_single_element_form(nullptr, entry)); + return cast_to_int_enum(type_info, pool, env, *integer); } else { // all failed, just return whatever. return pool.alloc_single_element_form(nullptr, typespec, in); } } +Form* cast_to_int_enum(const EnumType* type_info, FormPool& pool, const Env& env, s64 in) { + auto entry = decompile_int_enum_from_int(TypeSpec(type_info->get_name()), env.dts->ts, in); + auto oper = GenericOperator::make_function( + pool.alloc_single_element_form(nullptr, type_info->get_name())); + return pool.alloc_single_element_form( + nullptr, oper, pool.alloc_single_element_form(nullptr, entry)); +} + } // namespace decompiler \ No newline at end of file diff --git a/decompiler/IR2/bitfields.h b/decompiler/IR2/bitfields.h index 488d459391..ce0a322cd9 100644 --- a/decompiler/IR2/bitfields.h +++ b/decompiler/IR2/bitfields.h @@ -54,6 +54,30 @@ struct BitfieldManip { return result; } + std::string print() const { + switch (kind) { + case Kind::LEFT_SHIFT: + return "left-shift"; + case Kind::RIGHT_SHIFT_LOGICAL: + return "right-shift-logical"; + case Kind::RIGHT_SHIFT_LOGICAL_32BIT: + return "right-shift-logical32"; + case Kind::LOGAND_WITH_CONSTANT_INT: + return "logand-constant"; + case Kind::LOGIOR_WITH_CONSTANT_INT: + return "logior-constant"; + case Kind::LOGIOR_WITH_FORM: + return "logior-form"; + case Kind::LOGAND_WITH_FORM: + return "logand-form"; + case Kind::NONZERO_COMPARE: + return "nonzero-compare"; + case Kind::INVALID: + default: + assert(false); + } + } + private: BitfieldManip() = default; }; @@ -153,6 +177,8 @@ Form* cast_to_int_enum(const EnumType* type_info, const Env& env, Form* in); +Form* cast_to_int_enum(const EnumType* type_info, FormPool& pool, const Env& env, s64 in); + std::optional get_goal_integer_constant(Form* in, const Env&); const BitField& find_field(const TypeSystem& ts, diff --git a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp index 46de8bdb5e..794d8c594b 100644 --- a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp +++ b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp @@ -275,7 +275,11 @@ void ObjectFileDB::ir2_atomic_op_pass() { func.ir2.atomic_ops_attempted = true; attempted++; try { - auto ops = convert_function_to_atomic_ops(func, data.linked_data.labels, func.warnings); + bool inline_asm = + get_config().hint_inline_assembly_functions.find(func.guessed_name.to_string()) != + get_config().hint_inline_assembly_functions.end(); + auto ops = convert_function_to_atomic_ops(func, data.linked_data.labels, func.warnings, + inline_asm); func.ir2.atomic_ops = std::make_shared(std::move(ops)); func.ir2.atomic_ops_succeeded = true; func.ir2.env.set_end_var(func.ir2.atomic_ops->end_op().return_var()); diff --git a/decompiler/analysis/atomic_op_builder.cpp b/decompiler/analysis/atomic_op_builder.cpp index 3e7ff56c96..9b333b84e4 100644 --- a/decompiler/analysis/atomic_op_builder.cpp +++ b/decompiler/analysis/atomic_op_builder.cpp @@ -11,7 +11,7 @@ namespace decompiler { namespace { -std::unique_ptr convert_1(const Instruction& i0, int idx); +std::unique_ptr convert_1(const Instruction& i0, int idx, bool hint_inline_asm); ////////////////////// // Register Helpers @@ -67,6 +67,9 @@ RegisterAccess make_dst_var(const Instruction& i, int idx) { //////////////////////// SimpleAtom make_src_atom(Register reg, int idx) { + if (reg == Register(Reg::GPR, Reg::R0)) { + return SimpleAtom::make_int_constant(0); + } return SimpleAtom::make_var(make_src_var(reg, idx)); } @@ -399,7 +402,7 @@ std::unique_ptr make_branch(const IR2_Condition& condition, if (branch_delay.is_known()) { return std::make_unique(likely, condition, dest_label, branch_delay, my_idx); } else { - auto delay_op = std::shared_ptr(convert_1(delay, my_idx)); + auto delay_op = std::shared_ptr(convert_1(delay, my_idx, false)); return std::make_unique(likely, condition, dest_label, delay_op, my_idx); } } @@ -707,7 +710,7 @@ std::unique_ptr convert_bnel_1(const Instruction& i0, int idx, bool li return make_branch_no_delay(condition, likely, dest, idx); } -std::unique_ptr convert_1(const Instruction& i0, int idx) { +std::unique_ptr convert_1(const Instruction& i0, int idx, bool hint_inline_asm) { switch (i0.kind) { case InstructionKind::OR: return convert_or_1(i0, idx); @@ -715,6 +718,12 @@ std::unique_ptr convert_1(const Instruction& i0, int idx) { return convert_ori_1(i0, idx); case InstructionKind::AND: return make_3reg_op(i0, SimpleExpression::Kind::AND, idx); + case InstructionKind::PCPYLD: + if (hint_inline_asm) { + break; + } else { + return make_3reg_op(i0, SimpleExpression::Kind::PCPYLD, idx); + } case InstructionKind::MTC1: return convert_mtc1_1(i0, idx); case InstructionKind::MFC1: @@ -835,6 +844,7 @@ std::unique_ptr convert_1(const Instruction& i0, int idx) { default: return nullptr; } + return nullptr; } /////////////////////// @@ -1406,7 +1416,8 @@ int convert_block_to_atomic_ops(int begin_idx, std::vector::const_iterator end, const std::vector& labels, FunctionAtomicOps* container, - DecompWarnings& warnings) { + DecompWarnings& warnings, + bool hint_inline_asm) { container->block_id_to_first_atomic_op.push_back(container->ops.size()); for (auto& instr = begin; instr < end;) { // how many instructions can we look at, at most? @@ -1461,7 +1472,7 @@ int convert_block_to_atomic_ops(int begin_idx, if (!converted) { // try 1 instruction - op = convert_1(*instr, op_idx); + op = convert_1(*instr, op_idx, hint_inline_asm); if (op) { converted = true; length = 1; @@ -1502,7 +1513,8 @@ int convert_block_to_atomic_ops(int begin_idx, FunctionAtomicOps convert_function_to_atomic_ops(const Function& func, const std::vector& labels, - DecompWarnings& warnings) { + DecompWarnings& warnings, + bool hint_inline_asm) { FunctionAtomicOps result; int last_op = 0; @@ -1512,8 +1524,8 @@ FunctionAtomicOps convert_function_to_atomic_ops(const Function& func, if (block.end_word > block.start_word) { auto begin = func.instructions.begin() + block.start_word; auto end = func.instructions.begin() + block.end_word; - last_op = - convert_block_to_atomic_ops(block.start_word, begin, end, labels, &result, warnings); + last_op = convert_block_to_atomic_ops(block.start_word, begin, end, labels, &result, warnings, + hint_inline_asm); if (i == int(func.basic_blocks.size()) - 1) { // we're the last block. insert the function end op. result.ops.push_back(std::make_unique(int(result.ops.size()))); diff --git a/decompiler/analysis/atomic_op_builder.h b/decompiler/analysis/atomic_op_builder.h index f32fb146e6..4858deafc3 100644 --- a/decompiler/analysis/atomic_op_builder.h +++ b/decompiler/analysis/atomic_op_builder.h @@ -47,12 +47,14 @@ int convert_block_to_atomic_ops(int begin_idx, std::vector::const_iterator end, const std::vector& labels, FunctionAtomicOps* container, - DecompWarnings& warnings); + DecompWarnings& warnings, + bool inline_asm_hint = false); /*! * Convert an entire function to AtomicOps */ FunctionAtomicOps convert_function_to_atomic_ops(const Function& func, const std::vector& labels, - DecompWarnings& warnings); + DecompWarnings& warnings, + bool hint_inline_asm); } // namespace decompiler \ No newline at end of file diff --git a/decompiler/config.cpp b/decompiler/config.cpp index c962da633f..5d715f5b1f 100644 --- a/decompiler/config.cpp +++ b/decompiler/config.cpp @@ -55,6 +55,8 @@ void set_config(const std::string& path_to_config_file) { gConfig.analyze_expressions = cfg.at("analyze_expressions").get(); gConfig.run_ir2 = cfg.at("run_ir2").get(); gConfig.insert_lets = cfg.at("insert_lets").get(); + gConfig.hint_inline_assembly_functions = + cfg.at("inline_asm_hint").get>(); std::vector asm_functions_by_name = cfg.at("asm_functions_by_name").get>(); diff --git a/decompiler/config.h b/decompiler/config.h index a4d0b863ec..3d298b1d8b 100644 --- a/decompiler/config.h +++ b/decompiler/config.h @@ -78,6 +78,8 @@ struct Config { std::unordered_map> label_types; std::unordered_map> stack_var_hints_by_function; bool run_ir2 = false; + + std::unordered_set hint_inline_assembly_functions; }; Config& get_config(); diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index ef6912c00d..f0e793fddb 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -2881,14 +2881,32 @@ :flag-assert #x900000008 ) -(define-extern psm-size (function int int)) -(define-extern psm-page-height (function int int)) -(define-extern psm->string (function int string)) +(defenum gs-psm + :bitfield #f + :type uint8 + (ct32 0) + (ct24 1) + (ct16 2) + (ct16s 10) + (mt8 19) + (mt4 20) + (mt8h 27) + (mt4hl 36) + (mt4hh 44) + (mz32 48) + (mz24 49) + (mz16 50) + (mz16s 58) + ) + +(define-extern psm-size (function gs-psm int)) +(define-extern psm-page-height (function gs-psm int)) +(define-extern psm->string (function gs-psm string)) (deftype gs-display-fb (uint64) ((fbp uint16 :offset 0 :size 9) (fbw uint8 :offset 9 :size 6) - (psm uint8 :offset 15 :size 5) + (psm gs-psm :offset 15 :size 5) (dbx uint16 :offset 32 :size 11) (dby uint16 :offset 43 :size 11) ) @@ -3300,7 +3318,13 @@ :flag-assert #x900000004 ) (deftype gif-tag64 (uint64) - () + ((nloop uint16 :offset 0 :size 15) + (eop uint8 :offset 15 :size 1) + (id uint16 :offset 32 :size 14) + (pre uint8 :offset 46 :size 1) + (prim uint16 :offset 47 :size 11) + (flg uint8 :offset 58 :size 2) + (nreg uint8 :offset 60 :size 4)) :flag-assert #x900000008 ) (deftype gif-tag (uint128) @@ -3331,12 +3355,55 @@ :flag-assert #x900000010 ) +(defenum gs-reg-id + :bitfield #f + :type uint8 + (prim 0) + (rgbaq 1) + (st 2) + (uv 3) + (xyzf2 4) + (xyz2 5) + (tex0-1 6) + (tex0-2 7) + (clamp-1 8) + (clamp-2 9) + (fog 10) + (xyzf3 12) + (xyz3 13) + (a+d 14) + (nop 15) + ) + +(deftype gif-tag-regs (uint64) + ((regs0 gs-reg-id :offset 0 :size 4) + (regs1 gs-reg-id :offset 4 :size 4) + (regs2 gs-reg-id :offset 8 :size 4) + (regs3 gs-reg-id :offset 12 :size 4) + (regs4 gs-reg-id :offset 16 :size 4) + (regs5 gs-reg-id :offset 20 :size 4) + (regs6 gs-reg-id :offset 24 :size 4) + (regs7 gs-reg-id :offset 28 :size 4) + (regs8 gs-reg-id :offset 32 :size 4) + (regs9 gs-reg-id :offset 36 :size 4) + (regs10 gs-reg-id :offset 40 :size 4) + (regs11 gs-reg-id :offset 44 :size 4) + (regs12 gs-reg-id :offset 48 :size 4) + (regs13 gs-reg-id :offset 52 :size 4) + (regs14 gs-reg-id :offset 56 :size 4) + (regs15 gs-reg-id :offset 60 :size 4) + ) + ) + + (deftype gs-gif-tag (structure) ((qword uint128 :offset-assert 0) ;; is "qword" and inline? in game - (dword uint64 2 :offset 0) - (word uint32 4 :offset 0) - (tag uint64 :offset 0) - (regs uint64 :offset 8) + + (tag gif-tag64 :offset 0) + (regs gif-tag-regs :offset 8) + + (dword uint64 2 :offset 0) + (word uint32 4 :offset 0) ) :method-count-assert 9 :size-assert #x10 @@ -3350,8 +3417,9 @@ (deftype gif-packet (basic) ((reg-count int32 :offset-assert 4) - (gif-tag0 uint128 :offset-assert 16) - (gif-tag gs-gif-tag :inline :offset 16) ;; note- added + + (gif-tag gs-gif-tag :inline :offset-assert 16) ;; note- added + (gif-tag0 uint128 :offset 16) (args uint64 1 :offset-assert 32) ) @@ -3627,15 +3695,15 @@ (define-extern vector-cvt.s.w! (function vector vector vector)) (define-extern rot-zxy-from-vector! (function vector vector vector)) (define-extern rot-zyx-from-vector! (function vector vector vector)) -(define-extern vector-lerp! (function vector vector vector)) -(define-extern vector-lerp-clamp! (function vector vector float float vector)) -(define-extern vector4-lerp! (function vector vector vector)) -(define-extern vector4-lerp-clamp! (function vector vector float float vector)) +(define-extern vector-lerp! (function vector vector vector float vector)) +(define-extern vector-lerp-clamp! (function vector vector vector float vector)) +(define-extern vector4-lerp! (function vector vector vector float vector)) +(define-extern vector4-lerp-clamp! (function vector vector vector float vector)) (define-extern vector-degi (function vector vector vector)) (define-extern vector-degf (function vector vector vector)) (define-extern vector-degmod (function vector vector vector)) (define-extern vector-deg-diff (function vector vector vector vector)) -(define-extern vector-deg-lerp-clamp! function) ;; todo +(define-extern vector-deg-lerp-clamp! (function vector vector vector float vector)) ;; todo (define-extern vector3s-copy! (function vector vector vector)) (define-extern vector3s+! (function vector vector vector vector)) (define-extern vector3s*float! (function vector vector float vector)) @@ -3643,7 +3711,7 @@ (define-extern spheres-overlap? (function vector vector symbol)) (define-extern sphere<-vector! (function sphere vector sphere)) (define-extern sphere<-vector+r! (function sphere vector float sphere)) -(define-extern rand-vu-sphere-point! function) ;; todo +(define-extern rand-vu-sphere-point! (function vector sphere vector)) ;; todo ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/decompiler/config/jak1_ntsc_black_label.jsonc b/decompiler/config/jak1_ntsc_black_label.jsonc index cc4465bab6..d2dcf84b27 100644 --- a/decompiler/config/jak1_ntsc_black_label.jsonc +++ b/decompiler/config/jak1_ntsc_black_label.jsonc @@ -97,6 +97,8 @@ "no_type_analysis_functions_by_name":[], + // this provides a hint to the decompiler that these functions will have a lot of inline assembly. + "inline_asm_hint":["matrix-transpose!"], "asm_functions_by_name":[ // gcommon diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index 6c4f8130b7..311b87e000 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -123,9 +123,13 @@ ["L41", "float", true] ], + "dma-disasm": [["L148", "(array vif-disasm-element)", true]], + "gs": [["L53", "gif-tag64", true], + ["L51", "gif-tag-regs", true], + ["L52", "uint64", true]], + "loader-h": [["L10", "float", true]], - "dma-disasm": [["L148", "(array vif-disasm-element)", true]], "level-h": [["L3", "level-group", true]], "level-info": [ @@ -377,6 +381,7 @@ "collide-edge-grab-h": [["L1", "collide-edge-work", true]], "vector": [ + ["L114", "float", true], ["L113", "float", true], ["L112", "float", true], ["L111", "float", true] diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index 719ee97dc0..06c21ac944 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -211,6 +211,13 @@ [334, "v1", "(pointer uint64)"] ], + "default-buffer-init": [ + [[8, 15], "a1", "dma-gif-packet"], + [[18, 24], "a1", "gs-gif-tag"], + [[29, 64], "a1", "(pointer uint64)"], + [[69, 72], "a0", "dma-packet"] + ], + // LEVEL "lookup-level-info": [ [3, "a1", "symbol"], diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index 7764133e98..f16c5d3bb3 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -762,15 +762,15 @@ "default-buffer-init": { "args": ["buff"], "vars": { - "v1-0": "buff", - "v1-1": "buff", - "v1-3": "buff", - "v1-4": "buff", - "a1-4": "tag", - "a1-6": "tag2", - "a1-8": "data", - "a0-1": "tag3", - "v1-2": "buff" + "v1-0": "buff-ptr", + "v1-1": "buff-ptr2", + "v1-3": "buff-ptr3", + "v1-4": "buff-ptr4", + "a1-4": ["packet", "dma-gif-packet"], + "a1-6": ["gif-tag", "gs-gif-tag"], + "a1-8": ["data", "(pointer uint64)"], + "a0-1": ["ret-packet", "dma-packet"], + "v1-2": "buff-ptr5" } }, diff --git a/decompiler/util/data_decompile.cpp b/decompiler/util/data_decompile.cpp index fb83e4abb6..3ad3c1cfc9 100644 --- a/decompiler/util/data_decompile.cpp +++ b/decompiler/util/data_decompile.cpp @@ -532,7 +532,11 @@ goos::Object bitfield_defs_print(const TypeSpec& type, std::vector result; result.push_back(pretty_print::to_symbol(fmt::format("new 'static '{}", type.print()))); for (auto& def : defs) { - if (def.is_signed) { + if (def.enum_constant) { + assert(false); // this is untested. + result.push_back( + pretty_print::to_symbol(fmt::format(":{} {}", def.field_name, *def.enum_constant))); + } else if (def.is_signed) { result.push_back( pretty_print::to_symbol(fmt::format(":{} {}", def.field_name, (s64)def.value))); } else { @@ -865,6 +869,11 @@ std::vector decompile_bitfield_from_int(const TypeSpec& typ def.value = bitfield_value; def.field_name = field.name(); def.is_signed = is_signed; + auto enum_info = ts.try_enum_lookup(field.type()); + if (enum_info && !enum_info->is_bitfield()) { + auto name = decompile_int_enum_from_int(field.type(), ts, bitfield_value); + def.enum_constant = fmt::format("({} {})", field.type().print(), name); + } result.push_back(def); } diff --git a/decompiler/util/data_decompile.h b/decompiler/util/data_decompile.h index 21708ab4a7..c0f7419a27 100644 --- a/decompiler/util/data_decompile.h +++ b/decompiler/util/data_decompile.h @@ -62,6 +62,7 @@ goos::Object decompile_bitfield(const TypeSpec& type, struct BitFieldConstantDef { bool is_signed = false; u64 value = -1; + std::optional enum_constant; std::string field_name; }; diff --git a/goal_src/engine/gfx/hw/gs.gc b/goal_src/engine/gfx/hw/gs.gc index 65d090505a..a2f43ff9bb 100644 --- a/goal_src/engine/gfx/hw/gs.gc +++ b/goal_src/engine/gfx/hw/gs.gc @@ -34,69 +34,81 @@ ;; 50 = PSMZ16 ;; 58 = PSMZ16S -(defconstant TEX_MZ16S 58) -(defconstant TEX_MZ16 50) -(defconstant TEX_MZ24 49) -(defconstant TEX_MZ32 48) -(defconstant TEX_MT4HH 44) -(defconstant TEX_MT4HL 36) -(defconstant TEX_MT8H 27) -(defconstant TEX_MT4 20) -(defconstant TEX_MT8 19) -(defconstant TEX_CT16S 10) -(defconstant TEX_CT16 2) -(defconstant TEX_CT24 1) -(defconstant TEX_CT32 0) - -(defun psm-size ((arg0 int)) - "Not sure exactly what 'size' means, but this likely takes a texture format as an input." - (cond - ((= arg0 TEX_MT8) 64) - ((= arg0 TEX_MT4) 32) - (else - (if (or (= arg0 TEX_CT16) (= arg0 TEX_CT16S) (= arg0 TEX_MZ16) (= arg0 TEX_MZ16S)) - 128 - 256 - ) +(defenum gs-psm + :bitfield #f + :type uint8 + (ct32 0) + (ct24 1) + (ct16 2) + (ct16s 10) + (mt8 19) + (mt4 20) + (mt8h 27) + (mt4hl 36) + (mt4hh 44) + (mz32 48) + (mz24 49) + (mz16 50) + (mz16s 58) + ) + +(defun psm-size ((arg0 gs-psm)) + "Convert texture format to some type of size." + (cond + ((= arg0 (gs-psm mt8)) 64) + ((= arg0 (gs-psm mt4)) 32) + (else + (if (or (= arg0 (gs-psm ct16)) + (= arg0 (gs-psm ct16s)) + (= arg0 (gs-psm mz16)) + (= arg0 (gs-psm mz16s)) + ) + 128 + 256 + ) + ) ) - ) ) -(defun psm-page-height ((arg0 int)) - "texture format -> page height?" +(defun psm-page-height ((arg0 gs-psm)) + "Convert texture format to some type of page height" (cond - ((= arg0 TEX_MT8) 64) - ((= arg0 TEX_MT4) 128) - (else - (if (or (= arg0 TEX_CT16) (= arg0 TEX_CT16S) (= arg0 TEX_MZ16) (= arg0 TEX_MZ16S)) - 64 - 32 - ) + ((= arg0 (gs-psm mt8)) 64) + ((= arg0 (gs-psm mt4)) 128) + (else + (if (or (= arg0 (gs-psm ct16)) + (= arg0 (gs-psm ct16s)) + (= arg0 (gs-psm mz16)) + (= arg0 (gs-psm mz16s)) + ) + 64 + 32 + ) + ) ) - ) ) -(defun psm->string ((arg0 int)) - "Convert texture format to its name" - (local-vars (v1-0 int)) - (set! v1-0 arg0) - (cond - ((= v1-0 TEX_MZ16S) "mz16s") - ((= v1-0 TEX_MZ16) "mz16") - ((= v1-0 TEX_MZ24) "mz24") - ((= v1-0 TEX_MZ32) "mz32") - ((= v1-0 TEX_MT4HH) "mt4hh") - ((= v1-0 TEX_MT4HL) "mt4hl") - ((= v1-0 TEX_MT8H) "mt8h") - ((= v1-0 TEX_MT4) "mt4") - ((= v1-0 TEX_MT8) "mt8") - ((= v1-0 TEX_CT16S) "ct16s") - ((= v1-0 TEX_CT16) "ct16") - ((= v1-0 TEX_CT24) "ct24") - ((zero? v1-0) "ct32") - (else "*unknown*") - ) +(defun psm->string ((arg0 gs-psm)) + "Get the name of a texture format." + (let ((v1-0 arg0)) + (cond + ((= v1-0 (gs-psm mz16s)) "mz16s") + ((= v1-0 (gs-psm mz16)) "mz16") + ((= v1-0 (gs-psm mz24)) "mz24") + ((= v1-0 (gs-psm mz32)) "mz32") + ((= v1-0 (gs-psm mt4hh)) "mt4hh") + ((= v1-0 (gs-psm mt4hl)) "mt4hl") + ((= v1-0 (gs-psm mt8h)) "mt8h") + ((= v1-0 (gs-psm mt4)) "mt4") + ((= v1-0 (gs-psm mt8)) "mt8") + ((= v1-0 (gs-psm ct16s)) "ct16s") + ((= v1-0 (gs-psm ct16)) "ct16") + ((= v1-0 (gs-psm ct24)) "ct24") + ((zero? v1-0) "ct32") + (else "*unknown*") + ) + ) ) ;; the GS's DISPFB registers make settings for the frame buffer regarding information on @@ -105,12 +117,13 @@ (deftype gs-display-fb (uint64) ((fbp uint16 :offset 0 :size 9) (fbw uint8 :offset 9 :size 6) - (psm uint8 :offset 15 :size 5) + (psm gs-psm :offset 15 :size 5) (dbx uint16 :offset 32 :size 11) (dby uint16 :offset 43 :size 11) ) :flag-assert #x900000008 ) + ;; the GS's DISPLAY registers make settings for the display position on the screen regarding ;; information on Rectangular Area Read Output Circuit n for the PCRTC. ;; write-only @@ -124,6 +137,7 @@ ) :flag-assert #x900000008 ) + ;; the GS's BGCOLOR register sets the background color of the PCRTC with RGB value. ;; write-only (deftype gs-bgcolor (uint64) @@ -133,6 +147,7 @@ ) :flag-assert #x900000008 ) + ;; the GS's CSR register sets and obtains various GS statuses. ;; read-write. the fields have different effects depending on whether they're being read from ;; or written to. @@ -175,6 +190,7 @@ :size-assert #x1048 :flag-assert #x900001048 ) + ;; the GS's FRAME registers store various settings related to the frame buffer. (deftype gs-frame (uint64) ((fbp uint16 :offset 0 :size 9) @@ -184,6 +200,7 @@ ) :flag-assert #x900000008 ) + ;; the GS's ZBUF registers make various settings regarding Z buffer. (deftype gs-zbuf (uint64) ((zbp uint16 :offset 0 :size 9) @@ -517,7 +534,13 @@ :flag-assert #x900000004 ) (deftype gif-tag64 (uint64) - () + ((nloop uint16 :offset 0 :size 15) + (eop uint8 :offset 15 :size 1) + (id uint16 :offset 32 :size 14) + (pre uint8 :offset 46 :size 1) + (prim uint16 :offset 47 :size 11) + (flg uint8 :offset 58 :size 2) + (nreg uint8 :offset 60 :size 4)) :flag-assert #x900000008 ) (deftype gif-tag (uint128) @@ -548,12 +571,52 @@ :flag-assert #x900000010 ) +(defenum gs-reg-id + :bitfield #f + :type uint8 + (prim 0) + (rgbaq 1) + (st 2) + (uv 3) + (xyzf2 4) + (xyz2 5) + (tex0-1 6) + (tex0-2 7) + (clamp-1 8) + (clamp-2 9) + (fog 10) + (xyzf3 12) + (xyz3 13) + (a+d 14) + (nop 15) + ) + +(deftype gif-tag-regs (uint64) + ((regs0 gs-reg-id :offset 0 :size 4) + (regs1 gs-reg-id :offset 4 :size 4) + (regs2 gs-reg-id :offset 8 :size 4) + (regs3 gs-reg-id :offset 12 :size 4) + (regs4 gs-reg-id :offset 16 :size 4) + (regs5 gs-reg-id :offset 20 :size 4) + (regs6 gs-reg-id :offset 24 :size 4) + (regs7 gs-reg-id :offset 28 :size 4) + (regs8 gs-reg-id :offset 32 :size 4) + (regs9 gs-reg-id :offset 36 :size 4) + (regs10 gs-reg-id :offset 40 :size 4) + (regs11 gs-reg-id :offset 44 :size 4) + (regs12 gs-reg-id :offset 48 :size 4) + (regs13 gs-reg-id :offset 52 :size 4) + (regs14 gs-reg-id :offset 56 :size 4) + (regs15 gs-reg-id :offset 60 :size 4) + ) + ) + (deftype gs-gif-tag (structure) ((qword uint128 :offset-assert 0) ;; is "qword" and inline? in game + (tag gif-tag64 :offset 0) + (regs gif-tag-regs :offset 8) (dword uint64 2 :offset 0) (word uint32 4 :offset 0) - (tag uint64 :offset 0) - (regs uint64 :offset 8) ) :method-count-assert 9 :size-assert #x10 @@ -570,66 +633,108 @@ (define *default-regs-buffer* (new 'global 'dma-buffer 1024)) (defun default-buffer-init ((buff dma-buffer)) - "Puts some currently unknown gif tags in the buffer." - (local-vars - (tag3 gs-gif-tag) - (tag gs-gif-tag) - (tag2 gs-gif-tag) - (data (pointer uint64)) - ) - ;; reset the buffer base and end. - (set! (-> buff base) (-> buff data)) - (set! (-> buff end) (&-> buff data-buffer (-> buff allocated-length))) + "Set some GS registers back to default values. Ends with a ret dma-tag. + This is intended to live in its own separate dma-buffer and not be added + to the global buffer. Calling this will reset this dma-buffer." - ;; make a tag (maybe this is actually a dma/vif tag?) - (set! tag (the gs-gif-tag (-> buff base))) - (set! (-> tag dword 0) #x1000000a) - (set! (-> tag word 2) #x13000000) - (set! (-> tag word 3) #x5000000a) - (set! (-> buff base) (&+ (the-as pointer tag) 16)) + ;; reset the buffer. + (let ((buff-ptr buff)) + (set! (-> buff-ptr base) (-> buff-ptr data)) + (set! (-> buff-ptr end) + (&-> buff-ptr data-buffer (-> buff-ptr allocated-length)) + ) + ) - ;; make another tag. - (set! tag2 (the gs-gif-tag (-> buff base))) - ;; no idea what this is about, it doesn't matter. - ;;(set! a2-3 (l.d L53)) - ;;(.pcpyld a2-4 r0-0 a2-3) - (set! (-> tag2 dword 0) #x9000000000008001) - (set! (-> tag2 dword 1) #xeeeeeeeeeeeeeeee) - (set! (-> buff base) (&+ (the-as pointer tag2) 16)) + ;; set up a GIF transfer + (let* ((buff-ptr2 buff) + (tag (the-as dma-gif-packet (-> buff-ptr2 base))) + ) + ;; transfer 10 quadwords + (set! (-> tag dma-vif dma) + (new 'static 'dma-tag :qwc #xa :id (dma-tag-id cnt)) + ) + ;; flush the VIF + (set! (-> tag dma-vif vif0) + (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1) + ) + ;; DIRECT transfer to GIF. + (set! (-> tag dma-vif vif1) + (new 'static 'vif-tag :imm #xa :cmd (vif-cmd direct) :msk #x1) + ) + (set! (-> buff-ptr2 base) (&+ (the-as pointer tag) 16)) + ) - ;; now some payload. - (set! data (the (pointer uint64) (-> buff base))) - (set! (-> data 0) 68) - (set! (-> data 1) 66) - (set! (-> data 2) #x10001c0) - (set! (-> data 3) 78) - (set! (-> data 4) #x5000e) - (set! (-> data 5) 71) - (set! (-> data 6) 0) - (set! (-> data 7) 73) - (set! (-> data 8) 5) - (set! (-> data 9) 8) - (set! (-> data 10) 96) - (set! (-> data 11) 20) - (set! (-> data 12) (shl 128 32)) - (set! (-> data 13) 59) - (set! (-> data 14) 4) - (set! (-> data 15) 28) - (set! (-> data 16) *fog-color*) - (set! (-> data 17) 61) - (set! (-> buff base) (&-> data 18)) + ;; set up for 9 registers (each reg is 1 qw + 1 qw for this tag) + (let* ((buff-ptr5 buff) + (gif-tag (the-as gs-gif-tag (-> buff-ptr5 base))) + ) + ;; nreg = 9 here. + (set! (-> gif-tag tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x9)) + ;; this sets all the regs to a+d, but the ones after 9 are ignored. + (set! (-> gif-tag regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id a+d) + :regs1 (gs-reg-id a+d) + :regs2 (gs-reg-id a+d) + :regs3 (gs-reg-id a+d) + :regs4 (gs-reg-id a+d) + :regs5 (gs-reg-id a+d) + :regs6 (gs-reg-id a+d) + :regs7 (gs-reg-id a+d) + :regs8 (gs-reg-id a+d) + :regs9 (gs-reg-id a+d) + :regs10 (gs-reg-id a+d) + :regs11 (gs-reg-id a+d) + :regs12 (gs-reg-id a+d) + :regs13 (gs-reg-id a+d) + :regs14 (gs-reg-id a+d) + :regs15 (gs-reg-id a+d) + ) + ) + (set! (-> buff-ptr5 base) (&+ (the-as pointer gif-tag) 16)) + ) - ;; and a final tag. - (set! tag3 (the gs-gif-tag (-> buff base))) - (set! (-> tag3 dword 0) #x60000000) - (set! (-> tag3 word 2) 0) - (set! (-> tag3 word 3) 0) - (set! (-> buff base) (&+ (the-as pointer tag3) 16)) + ;; the actual address + register data. + (let* ((buff-ptr3 buff) + (data (the-as (pointer uint64) (-> buff-ptr3 base))) + ) + (set! (-> data 0) (the-as uint 68)) + (set! (-> data 1) (the-as uint 66)) + (set! (-> data 2) (the-as uint #x10001c0)) + (set! (-> data 3) (the-as uint 78)) + (set! (-> data 4) (the-as uint #x5000e)) + (set! (-> data 5) (the-as uint 71)) + (set! (-> data 6) (the-as uint 0)) + (set! (-> data 7) (the-as uint 73)) + (set! (-> data 8) (the-as uint 5)) + (set! (-> data 9) (the-as uint 8)) + (set! (-> data 10) (the-as uint 96)) + (set! (-> data 11) (the-as uint 20)) + (set! (-> data 12) (the-as uint (shl 128 32))) + (set! (-> data 13) (the-as uint 59)) + (set! (-> data 14) (the-as uint 4)) + (set! (-> data 15) (the-as uint 28)) + (set! (-> data 16) (the-as uint *fog-color*)) + (set! (-> data 17) (the-as uint 61)) + (set! (-> buff-ptr3 base) (&+ (the-as pointer data) 144)) + ) + + ;; return dma-tag. + (let* ((buff-ptr4 buff) + (ret-packet (the-as dma-packet (-> buff-ptr4 base))) + ) + (set! (-> ret-packet dma) (new 'static 'dma-tag :id (dma-tag-id ret))) + (set! (-> ret-packet vif0) (new 'static 'vif-tag)) + (set! (-> ret-packet vif1) (new 'static 'vif-tag)) + (set! (-> buff-ptr4 base) (&+ (the-as pointer ret-packet) 16)) + ) (none) ) + (default-buffer-init *default-regs-buffer*) + ;; This isn't a dynamic type in the type system, but it's used as one. ;; the array at the end is used as a dynamic array. ;; NOTE - this gif-packet stuff seems unused. Instead dma-gif-packet is used. @@ -644,8 +749,8 @@ (deftype gif-packet (basic) ((reg-count int32 :offset-assert 4) - (gif-tag0 uint128 :offset-assert 16) - (gif-tag gs-gif-tag :inline :offset 16) + (gif-tag gs-gif-tag :inline :offset-assert 16) + (gif-tag0 uint128 :offset 16) (args uint64 1 :offset-assert 32) ;; there's one here already. ) (:methods @@ -664,40 +769,38 @@ ) (defun open-gif-packet ((arg0 gif-packet)) - "Initialize a gif packet" + "Initialize an existing gif-packet for 0 registers" (set! (-> arg0 reg-count) 0) - (set! (-> arg0 gif-tag dword 1) 0) + (set! (-> arg0 gif-tag regs) (new 'static 'gif-tag-regs)) arg0 ) (defun add-reg-gif-packet ((packet gif-packet) (reg-idx int) (reg-val int)) - "Adds a register to reglist packet." - (local-vars (tag gs-gif-tag)) - (set! tag (-> packet gif-tag)) - ;; dword 1 contains the list of registers to set. each is 4-bits. - (set! (-> tag dword 1) - (logior (-> tag dword 1) - (the-as uint (ash reg-idx (shl (-> packet reg-count) 2))) ;; shift to the correct spot + "Add a register to the packet" + (let ((tag (-> packet gif-tag))) + ;; shift the register index into the right slot + (set! (-> tag regs) (logior + (-> tag regs) + (the-as uint (ash reg-idx (shl (-> packet reg-count) 2))) + ) + ) ) - ) - ;; ?? (-> packet args (-> packet reg-count)) - ;; store the value for the register. - (set! (-> (&-> packet args (-> packet reg-count)) 0) reg-val) - ;; increment the reg we're on. + ;; set register value and increment count. + (set! (-> packet args (-> packet reg-count)) (the-as uint reg-val)) (set! (-> packet reg-count) (+ (-> packet reg-count) 1)) (none) ) -(defun close-gif-packet ((arg0 gif-packet) (arg1 int)) - "Sets the lower dword of the giftag for reglist" - (local-vars (v1-2 int) (v1-3 int)) - (set! v1-2 - (logior (logior #x400000000000001 (the-as uint (shl (-> arg0 reg-count) 60))) - (the-as uint (shr (shl arg1 63) 48)) - ) - ) - ;;(.pcpyld v1-3 r0-0 v1-2)?? GOAL compiler is confused. - (set! (-> arg0 gif-tag dword 0) v1-2) +(defun close-gif-packet ((arg0 gif-packet) (eop int)) + "Finish adding registers." + (set! (-> arg0 gif-tag tag) + (new 'static 'gif-tag64 + :nloop #x1 + :flg #x1 + :eop eop + :nreg (-> arg0 reg-count) + ) + ) arg0 ) @@ -727,24 +830,19 @@ (color-0 rgba) ) "Allocate and initialize a draw-context" - (let - ((obj - (object-new allocation type-to-make (the-as int (-> type-to-make size))) - ) + (let ((obj (object-new allocation type-to-make (the-as int (-> type-to-make size))))) + (let ((v1-3 (the int (* (the float org-y) (-> *video-parms* relative-y-scale)))) + (a0-2 (the int (* (the float height) (-> *video-parms* relative-y-scale)))) + ) + (set! (-> obj orgx) org-x) + (set! (-> obj orgy) v1-3) + (set! (-> obj orgz) #xffffff) + (set! (-> obj width) width) + (set! (-> obj height) a0-2) + ) + (set! (-> obj color 0) color-0) + obj ) - (let - ((v1-3 (the int (* (the float org-y) (-> *video-parms* relative-y-scale)))) - (a0-2 (the int (* (the float height) (-> *video-parms* relative-y-scale)))) - ) - (set! (-> obj orgx) org-x) - (set! (-> obj orgy) v1-3) - (set! (-> obj orgz) #xffffff) - (set! (-> obj width) width) - (set! (-> obj height) a0-2) - ) - (set! (-> obj color 0) color-0) - obj - ) ) (defun draw-context-set-xy ((arg0 draw-context) (x int) (y int)) diff --git a/goal_src/engine/math/vector.gc b/goal_src/engine/math/vector.gc index f2ce71a320..209796c625 100644 --- a/goal_src/engine/math/vector.gc +++ b/goal_src/engine/math/vector.gc @@ -5,1072 +5,1212 @@ ;; name in dgo: vector ;; dgos: GAME, ENGINE -;; ---- TOP LEVEL COMMENT TODO ---- - -;; TODO - rand-vu-sphere-point! (fails to decomp) - -;; (defun sphere<-vector+r! ((arg0 sphere) (arg1 vector) (arg2 float)) -;; (local-vars (v1-0 int)) -;; (TODO.LQ v1-0 arg1) -;; (TODO.SQ v1-0 arg0) -;; (set! (-> arg0 data 3) arg2) -;; arg0 -;; ) - -;; (defun sphere<-vector! ((arg0 sphere) (arg1 vector)) -;; (local-vars (v1-0 int) (f0-0 float)) -;; (set! f0-0 (-> arg0 data 3)) -;; (TODO.LQ v1-0 arg1) -;; (TODO.SQ v1-0 arg0) -;; (set! (-> arg0 data 3) f0-0) -;; arg0 -;; ) - -;; (defun spheres-overlap? ((arg0 vector) (arg1 vector)) -;; "TODO" -;; (local-vars (v1-0 int) -;; (a0-1 int)) -;; (rlet ((vf0 :class vf) -;; (vf1 :class vf) -;; (vf2 :class vf) -;; (vf3 :class vf) -;; (vf4 :class vf)) -;; (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) -;; (.lvf vf1 arg0) -;; (.lvf vf2 arg1) -;; (.sub.vf vf3 vf1 vf2 :mask #b1110) -;; (.mul.vf vf3 vf3 vf3 :mask #b1110) -;; (.add.w.vf vf4 vf1 vf2 :mask #b1) -;; (.mul.w.vf vf4 vf4 vf4 :mask #b1) -;; (.add.y.vf vf3 vf3 vf3 :mask #b1000) -;; (.add.z.vf vf3 vf3 vf3 :mask #b1000) -;; (.add.w.vf vf4 vf0 vf4 :mask #b1000) -;; (.mov a0-1 vf4) -;; (.mov v1-0 vf3) -;; (>= (the-as float (gpr->fpr a0-1)) -;; (the-as float (gpr->fpr v1-0))))) - -(defun vector3s-! ((arg0 vector) (arg1 vector) (arg2 vector)) - "Subtract 2 vectors3: c = (a - b)" - (set! (-> arg0 data 0) (- (-> arg1 data 0) (-> arg2 data 0))) - (set! (-> arg0 data 1) (- (-> arg1 data 1) (-> arg2 data 1))) - (set! (-> arg0 data 2) (- (-> arg1 data 2) (-> arg2 data 2))) - arg0) - -(defun vector3s*float! ((arg0 vector) (arg1 vector) (arg2 float)) - "Multiply 2 vectors3 by some float" - (set! (-> arg0 data 0) (* (-> arg1 data 0) arg2)) - (set! (-> arg0 data 1) (* (-> arg1 data 1) arg2)) - (set! (-> arg0 data 2) (* (-> arg1 data 2) arg2)) - arg0) - -(defun vector3s+! ((arg0 vector) (arg1 vector) (arg2 vector)) - "Add 2 vectors3" - (set! (-> arg0 data 0) (+ (-> arg1 data 0) (-> arg2 data 0))) - (set! (-> arg0 data 1) (+ (-> arg1 data 1) (-> arg2 data 1))) - (set! (-> arg0 data 2) (+ (-> arg1 data 2) (-> arg2 data 2))) - arg0) - -(defun vector3s-copy! ((arg0 vector) (arg1 vector)) - "Copy a vector3s" - (set! (-> arg0 data 0) (-> arg1 data 0)) - (set! (-> arg0 data 1) (-> arg1 data 1)) - (set! (-> arg0 data 2) (-> arg1 data 2)) - arg0) - -;; TODO - vector-deg-lerp-clamp! (fails to decomp) -;; - WARN: Type Propagation failed: Function vector-deg-lerp-clamp! has unknown type - -;; (defun vector-deg-diff ((arg0 vector) (arg1 vector) (arg2 vector)) -;; "TODO" -;; (local-vars (v0-0 int) -;; (v1-0 int) -;; (v1-1 int) -;; (v1-2 int) -;; (v1-3 int) -;; (a1-1 int) -;; (a1-2 int)) -;; (rlet ((vf1 :class vf) -;; (vf2 :class vf)) -;; (.lvf vf1 arg1) -;; (.lvf vf2 arg2) -;; (.ftoi.vf vf1 vf1) -;; (.ftoi.vf vf2 vf2) -;; (.mov a1-1 vf1) -;; (.mov v1-0 vf2) -;; (TODO.PSLLW a1-2 a1-1 16) -;; (TODO.PSLLW v1-1 v1-0 16) -;; (TODO.PSUBW v1-2 a1-2 v1-1) -;; (TODO.PSRAW v1-3 v1-2 16) -;; (.mov vf1 v1-3) -;; (.itof.vf vf1 vf1) -;; (.svf arg0 vf1) -;; (.mov v0-0 vf1) -;; (the-as vector v0-0))) - -;; (defun vector-degmod ((arg0 vector) (arg1 vector)) -;; "TODO" -;; (local-vars (v1-0 int) -;; (v1-1 int) -;; (v1-2 int)) -;; (rlet ((vf1 :class vf)) -;; (.lvf vf1 arg1) -;; (.ftoi.vf vf1 vf1) -;; (.mov v1-0 vf1) -;; (TODO.PSLLW v1-1 v1-0 16) -;; (TODO.PSRAW v1-2 v1-1 16) -;; (.mov vf1 v1-2) -;; (.itof.vf vf1 vf1) -;; (.svf arg0 vf1) -;; arg0)) - -;; (defun vector-degf ((arg0 vector) (arg1 vector)) -;; "TODO" -;; (local-vars (v1-0 int) -;; (v1-1 int)) -;; (rlet ((vf1 :class vf)) -;; (TODO.LQ v1-0 arg1) -;; (TODO.PSRAW v1-1 v1-0 16) -;; (.mov vf1 v1-1) -;; (.itof.vf vf1 vf1) -;; (.svf arg0 vf1) -;; arg0)) - -;; (defun vector-degi ((arg0 vector) (arg1 vector)) -;; "TODO" -;; (local-vars (v1-0 int) -;; (v1-1 int)) -;; (rlet ((vf1 :class vf)) -;; (.lvf vf1 arg1) -;; (.ftoi.vf vf1 vf1) -;; (.mov v1-0 vf1) -;; (TODO.PSLLW v1-1 v1-0 16) -;; (TODO.SQ v1-1 arg0) -;; arg0)) - -;; (defun vector4-lerp-clamp! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) -;; "TODO" -;; (local-vars (v1-0 int) -;; (v1-1 int) -;; (v1-2 vector) -;; (a1-1 float) -;; (f0-2 float)) -;; (rlet ((vf1 :class vf) -;; (vf2 :class vf) -;; (vf3 :class vf) -;; (vf4 :class vf)) -;; (cond -;; ((>= 0.000000 arg3) -;; (TODO.LQ v1-0 arg1) -;; (TODO.SQ v1-0 arg0)) -;; ((>= arg3 (l.f POSITIVE_ONE)) -;; (TODO.LQ v1-1 arg2) -;; (TODO.SQ v1-1 arg0)) -;; (else -;; (set! v1-2 arg0) -;; (set! f0-2 arg3) -;; (.lvf vf1 arg1) -;; (.lvf vf2 arg2) -;; (set! a1-1 f0-2) -;; (.mov vf4 a1-1) -;; (.sub.vf vf2 vf2 vf1) -;; (.mul.x.vf vf2 vf2 vf4) -;; (.add.vf vf3 vf1 vf2) -;; (.svf v1-2 vf3))) -;; arg0)) - -(defun vector4-lerp! ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (a2-0 none) - (a3-0 none)) - (rlet ((vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf) - (vf4 :class vf)) - (.lvf vf1 arg1) - (.lvf vf2 a2-0) - (.mov vf4 a3-0) - (.sub.vf vf2 vf2 vf1) - (.mul.x.vf vf2 vf2 vf4) - (.add.vf vf3 vf1 vf2) - (.svf arg0 vf3) - arg0)) - -;; (defun vector-lerp-clamp! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) -;; "TODO" -;; (local-vars (v1-0 int) -;; (v1-1 int) -;; (v1-2 vector) -;; (a1-1 float) -;; (f0-2 float)) -;; (rlet ((vf0 :class vf) -;; (vf1 :class vf) -;; (vf2 :class vf) -;; (vf3 :class vf) -;; (vf4 :class vf)) -;; (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) -;; (cond -;; ((>= 0.000000 arg3) -;; (TODO.LQ v1-0 arg1) -;; (TODO.SQ v1-0 arg0)) -;; ((>= arg3 (l.f POSITIVE_ONE)) -;; (TODO.LQ v1-1 arg2) -;; (TODO.SQ v1-1 arg0)) -;; (else -;; (set! v1-2 arg0) -;; (set! f0-2 arg3) -;; (.lvf vf1 arg1) -;; (.lvf vf2 arg2) -;; (set! a1-1 f0-2) -;; (.mov vf4 a1-1) -;; (.add.x.vf vf3 vf0 vf0 :mask #b1) -;; (.sub.vf vf2 vf2 vf1) -;; (.mul.x.vf vf2 vf2 vf4) -;; (.add.vf vf3 vf1 vf2 :mask #b1110) -;; (.svf v1-2 vf3))) -;; arg0)) - -(defun vector-lerp! ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (a2-0 none) - (a3-0 none)) - (rlet ((vf0 :class vf) +(defun vector-cross! ((arg0 vector) (arg1 vector) (arg2 vector)) + "Compute the cross product." + (rlet ((acc :class vf) (vf1 :class vf) (vf2 :class vf) (vf3 :class vf) - (vf4 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 arg1) - (.lvf vf2 a2-0) - (.mov vf4 a3-0) - (.add.x.vf vf3 vf0 vf0 :mask #b1) - (.sub.vf vf2 vf2 vf1) - (.mul.x.vf vf2 vf2 vf4) - (.add.vf vf3 vf1 vf2 :mask #b1110) - (.svf arg0 vf3) - arg0)) + ) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (.outer.product.vf vf3 vf1 vf2) + (.svf (&-> arg0 quad) vf3) + arg0 + ) + ) -(defun rot-zyx-from-vector! ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (v1-0 float) - (f0-1 float) - (f0-5 float) - (f0-6 float) - (f26-0 float) - (f28-0 float) - (f30-0 float)) - (set! f28-0 (-> arg1 data 2)) - (set! f30-0 (- (-> arg1 data 1))) - (set! f0-1 (atan f30-0 f28-0)) - (set! (-> arg0 data 0) f0-1) - (set! f26-0 (- f0-1)) - (set! f0-5 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) - (set! f0-6 (atan (-> arg1 data 0) f0-5)) - (set! (-> arg0 data 1) f0-6) - (set! v1-0 f0-6) - (set! (-> arg0 data 2) 0.000000) - arg0) - -(defun rot-zxy-from-vector! ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (v1-0 float) - (f0-0 float) - (f0-4 float) - (f0-5 float) - (f26-0 float) - (f28-0 float) - (f30-0 float)) - (set! f28-0 (-> arg1 data 2)) - (set! f30-0 (-> arg1 data 0)) - (set! f0-0 (atan f30-0 f28-0)) - (set! (-> arg0 data 1) f0-0) - (set! f26-0 (- f0-0)) - (set! f0-4 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) - (set! f0-5 (atan (- (-> arg1 data 1)) f0-4)) - (set! (-> arg0 data 0) f0-5) - (set! v1-0 f0-5) - (set! (-> arg0 data 2) 0.000000) - arg0) - -(defun vector-cvt.s.w! ((arg0 vector) (arg1 vector)) - "TODO" - (rlet ((vf1 :class vf)) - (.lvf vf1 arg1) - (.itof.vf vf1 vf1) - (.svf arg0 vf1) - arg0)) - -(defun vector-cvt.w.s! ((arg0 vector) (arg1 vector)) - "TODO" - (rlet ((vf1 :class vf)) - (.lvf vf1 arg1) - (.ftoi.vf vf1 vf1) - (.svf arg0 vf1) +(defun vector+float! ((arg0 vector) (arg1 vector) (arg2 float)) + "Add float to each component of vector. The w component is set to 1" + (rlet ((vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.mov vf6 arg2) + (.lvf vf4 (&-> arg1 quad)) + (.add.x.vf vf5 vf0 vf0 :mask #b1000) + (.add.x.vf vf5 vf4 vf6 :mask #b111) + (.svf (&-> arg0 quad) vf5) arg0 ) ) -(defun rotate-y<-vector+vector ((arg0 vector) (arg1 vector)) - "TODO" - (atan - (- (-> arg1 data 0) (-> arg0 data 0)) - (- (-> arg1 data 2) (-> arg0 data 2)))) - -;; (defun vector-rotate-around-y! ((arg0 vector) (arg1 vector) (arg2 float)) -;; "TODO" -;; (local-vars (v1-0 int) (f0-0 float) (f26-0 float) (f28-0 float) (f30-0 float)) -;; (set! f26-0 (-> arg1 data 2)) -;; (set! f30-0 (-> arg1 data 0)) -;; (set! f28-0 (cos arg2)) -;; (set! f0-0 (sin arg2)) -;; (TODO.lq v1-0 arg1) -;; (TODO.sq v1-0 arg0) -;; (set! (-> arg0 data 2) (- (* f26-0 f28-0) (* f30-0 f0-0))) -;; (set! (-> arg0 data 0) (+ (* f26-0 f0-0) (* f30-0 f28-0))) -;; arg0) - -(defun vector-xz-length ((arg0 vector)) - "TODO" - (sqrtf - (+ (* (-> arg0 data 0) (-> arg0 data 0)) - (* (-> arg0 data 2) (-> arg0 data 2))))) - -(defun vector-xz-length-max! ((arg0 vector) (arg1 float)) - "TODO" - (local-vars (v1-4 float) - (f0-0 float) - (f0-1 float)) - (set! f0-0 (vector-xz-length arg0)) - (when - (not (or (= f0-0 0.000000) - (< f0-0 arg1))) - (set! f0-0 (/ f0-0 arg1)) - (when (!= f0-0 0.000000) - (set! (-> arg0 data 0) (/ (-> arg0 data 0) f0-0)) - (set! f0-1 (/ (-> arg0 data 2) f0-0)) - (set! (-> arg0 data 2) f0-1) - (set! v1-4 f0-1))) - arg0) - -(defun vector-length ((arg0 vector)) - "TODO" - (local-vars (v0-0 float)) - (rlet ((acc :class vf) - (Q :class vf) - (vf0 :class vf) - (vf1 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 arg0) - (.mul.vf vf1 vf1 vf1) - (.mul.x.vf acc vf0 vf1 :mask #b1) - (.add.mul.y.vf acc vf0 vf1 acc :mask #b1) - (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1) - (.sqrt.vf Q vf1 :ftf #b11) - (.add.w.vf vf1 vf0 vf0 :mask #b1000) - (.wait.vf) - (.mul.vf vf1 vf1 Q :mask #b1000) - (.nop.vf) - (.nop.vf) - (.mov v0-0 vf1) - (the-as float v0-0))) - -(defun vector-length-max! ((arg0 vector) (arg1 float)) - "TODO" - (local-vars (v1-4 float) - (f0-0 float) - (f0-1 float)) - (set! f0-0 (vector-length arg0)) - (when - (not (or (= f0-0 0.000000) - (< f0-0 arg1))) - (set! f0-0 (/ f0-0 arg1)) - (when (!= f0-0 0.000000) - (set! (-> arg0 data 0) (/ (-> arg0 data 0) f0-0)) - (set! (-> arg0 data 1) (/ (-> arg0 data 1) f0-0)) - (set! f0-1 (/ (-> arg0 data 2) f0-0)) - (set! (-> arg0 data 2) f0-1) - (set! v1-4 f0-1))) - arg0) - -(defun vector-xz-normalize! ((arg0 vector) (arg1 float)) - "TODO" - (local-vars (v1-1 float) - (v1-2 float) - (f0-0 float) - (f0-5 float)) - (set! f0-0 (vector-xz-length arg0)) - (when (!= f0-0 0.000000) - (set! v1-1 (/ arg1 f0-0)) - (set! (-> arg0 data 0) (* (-> arg0 data 0) v1-1)) - (set! f0-5 (* (-> arg0 data 2) v1-1)) - (set! (-> arg0 data 2) f0-5) - (set! v1-2 f0-5)) - arg0) - -;; (defun vector-normalize-copy! ((arg0 vector) (arg1 vector) (arg2 float)) -;; "TODO" -;; (local-vars (v1-0 int) -;; (v1-1 float) -;; (v1-2 float) -;; (f0-0 float) -;; (f0-7 float)) -;; (set! f0-0 (vector-length arg1)) -;; (cond -;; ((= f0-0 0.000000) -;; (TODO.LQ v1-0 arg1) -;; (TODO.SQ v1-0 arg0)) -;; (else -;; (set! v1-1 (/ arg2 f0-0)) -;; (set! (-> arg0 data 0) (* (-> arg1 data 0) v1-1)) -;; (set! (-> arg0 data 1) (* (-> arg1 data 1) v1-1)) -;; (set! f0-7 (* (-> arg1 data 2) v1-1)) -;; (set! (-> arg0 data 2) f0-7) -;; (set! v1-2 f0-7))) -;; (set! (-> arg0 data 3) (l.f POSITIVE_ONE)) -;; arg0) - -;; (defun vector-normalize-ret-len! ((a0-0 vector) (a1-0 float)) -;; "TODO" -;; (local-vars (v0-0 float) -;; (v1-0 float) -;; (v1-1 int) -;; (f0-0 int) -;; (f0-1 float)) -;; (rlet ((acc :class vf) -;; (Q :class vf) -;; (vf0 :class vf) -;; (vf1 :class vf) -;; (vf2 :class vf) -;; (vf3 :class vf)) -;; (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) -;; (.lvf vf1 a0-0) -;; (.mul.vf vf2 vf1 vf1 :mask #b1110) -;; (set! v1-0 a1-0) -;; (.mov vf3 v1-0) -;; (.mul.x.vf acc vf0 vf2 :mask #b1) -;; (.add.mul.y.vf acc vf0 vf2 acc :mask #b1) -;; (.add.mul.z.vf vf2 vf0 vf2 acc :mask #b1) -;; (.isqrt.vf Q vf3 vf2 :ftf #b0 :fsf #b11) -;; (.add.w.vf vf2 vf0 vf2 :mask #b1000) -;; (.mov v1-1 vf2) -;; (set! f0-0 (gpr->fpr v1-1)) -;; (set! f0-1 (sqrt.s f0-0)) -;; (set! v0-0 (fpr->gpr f0-1)) -;; (.wait.vf) -;; (.mul.vf vf1 vf1 Q :mask #b1110) -;; (.nop.vf) -;; (.nop.vf) -;; (.nop.vf) -;; (.svf a0-0 vf1) -;; (ret-value v0-0))) - -(defun vector-vector-xz-distance-squared ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (v0-0 int)) - (rlet ((vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf)) - (.lvf vf2 arg0) - (.lvf vf3 arg1) - (.sub.vf vf1 vf3 vf2) - (.mul.vf vf1 vf1 vf1) - (.add.z.vf vf1 vf1 vf1 :mask #b1000) - (.mov v0-0 vf1) - (the-as float v0-0))) - -(defun vector-vector-xz-distance ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (v0-0 int)) - (rlet ((acc :class vf) - (Q :class vf) - (vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf2 arg0) - (.lvf vf3 arg1) - (.sub.vf vf1 vf3 vf2) - (.mul.vf vf1 vf1 vf1) - (.mul.x.vf acc vf0 vf1 :mask #b1) - (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1) - (.sqrt.vf Q vf1 :ftf #b11) - (.add.w.vf vf1 vf0 vf0 :mask #b1000) - (.wait.vf) - (.mul.vf vf1 vf1 Q :mask #b1000) - (.nop.vf) - (.nop.vf) - (.mov v0-0 vf1) - (the-as float v0-0))) - -(defun vector-vector-distance-squared ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (v0-0 int)) - (rlet ((vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf)) - (.lvf vf2 arg0) - (.lvf vf3 arg1) - (.sub.vf vf1 vf3 vf2) - (.mul.vf vf1 vf1 vf1) - (.add.y.vf vf1 vf1 vf1 :mask #b1000) - (.add.z.vf vf1 vf1 vf1 :mask #b1000) - (.mov v0-0 vf1) - (the-as float v0-0))) - -(defun vector-vector-distance ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (v0-0 int)) - (rlet ((acc :class vf) - (Q :class vf) - (vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf2 arg0) - (.lvf vf3 arg1) - (.sub.vf vf1 vf3 vf2) - (.mul.vf vf1 vf1 vf1) - (.mul.x.vf acc vf0 vf1 :mask #b1) - (.add.mul.y.vf acc vf0 vf1 acc :mask #b1) - (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1) - (.sqrt.vf Q vf1 :ftf #b11) - (.add.w.vf vf1 vf0 vf0 :mask #b1000) - (.wait.vf) - (.mul.vf vf1 vf1 Q :mask #b1000) - (.nop.vf) - (.nop.vf) - (.mov v0-0 vf1) - (the-as float v0-0))) - -(defun vector-xz-length-squared ((arg0 vector)) - "TODO" - (+ (* (-> arg0 data 0) (-> arg0 data 0)) - (* (-> arg0 data 2) (-> arg0 data 2)))) - -(defun vector-length-squared ((arg0 vector)) - "TODO" - (local-vars (v0-0 int)) - (rlet ((acc :class vf) - (vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 arg0) - (.add.w.vf vf2 vf0 vf0 :mask #b1000) - (.mul.vf vf1 vf1 vf1) - (.mul.x.vf acc vf2 vf1 :mask #b1000) - (.add.mul.y.vf acc vf2 vf1 acc :mask #b1000) - (.add.mul.z.vf vf1 vf2 vf1 acc :mask #b1000) - (.mov v0-0 vf1) - (the-as float v0-0))) - -(defun vector-from-ups! ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (at-0 int) - (f0-0 float)) +(defun vector*! ((arg0 vector) (arg1 vector) (arg2 vector)) + "Elementwise product. Set w = 1" (rlet ((vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 arg1) - (set! f0-0 (-> *display* seconds-per-frame)) - (.mov at-0 f0-0) - (.mov vf2 at-0) - (.mov.vf vf1 vf0 :mask #b1) - (.mul.x.vf vf1 vf1 vf2 :mask #b1110) - (.svf arg0 vf1) - arg0)) - -(defun vector-to-ups! ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (at-0 int) - (f0-0 float)) - (rlet ((vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 arg1) - (set! f0-0 (-> *display* frames-per-second)) - (.mov at-0 f0-0) - (.mov vf2 at-0) - (.mov.vf vf1 vf0 :mask #b1) - (.mul.x.vf vf1 vf1 vf2 :mask #b1110) - (.svf arg0 vf1) - arg0)) - -(defun vector+float*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) - "TODO" - (rlet ((acc :class vf) - (vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf) - (vf4 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf2 arg2) - (.lvf vf1 arg1) - (.mov vf3 arg3) - (.add.x.vf vf4 vf0 vf0 :mask #b1) - (.mul.x.vf acc vf2 vf3) - (.add.mul.w.vf vf4 vf1 vf0 acc :mask #b1110) - (.svf arg0 vf4) - arg0)) - -(defun vector-v*float++! ((arg0 vector) (arg1 vector) (arg2 float)) - "TODO" - (vector+float*! arg0 arg0 arg1 (* arg2 (-> *display* seconds-per-frame))) - arg0) - -(defun vector-v*float! ((arg0 vector) (arg1 float) (arg2 float)) - "TODO" - (local-vars (v0-0 vector) - (v1-0 float) - (v1-1 float) - (f0-1 float)) - (rlet ((vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (set! v0-0 arg0) - (set! v1-0 arg1) - (set! f0-1 (* arg2 (-> *display* seconds-per-frame))) - (.lvf vf1 v1-0) - (set! v1-1 f0-1) - (.mov vf2 v1-1) - (.add.x.vf vf1 vf0 vf0 :mask #b1) - (.mul.x.vf vf1 vf1 vf2 :mask #b1110) - (.svf v0-0 vf1) - v0-0)) - -(defun vector-v++! ((arg0 vector) (arg1 vector)) - "TODO" - (vector+float*! arg0 arg0 arg1 (-> *display* seconds-per-frame)) - arg0) - -(defun vector-v*float+! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) - "TODO" - (vector+float*! arg0 arg1 arg2 (* arg3 (-> *display* seconds-per-frame))) - arg0) - -(defun vector-v+! ((arg0 vector) (arg1 vector) (arg2 vector)) - "TODO" - (vector+float*! arg0 arg1 arg2 (-> *display* seconds-per-frame)) - arg0) - -(defun vector-v! ((arg0 vector)) - "TODO" - (local-vars (v1-0 vector) - (a1-0 vector) - (a1-1 float) - (f0-0 float)) - (rlet ((vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (set! v1-0 arg0) - (set! a1-0 arg0) - (set! f0-0 (-> *display* seconds-per-frame)) - (.lvf vf1 a1-0) - (set! a1-1 f0-0) - (.mov vf2 a1-1) - (.add.x.vf vf1 vf0 vf0 :mask #b1) - (.mul.x.vf vf1 vf1 vf2 :mask #b1110) - (.svf v1-0 vf1) - arg0)) - -(defun vector-seconds! ((arg0 vector)) - "TODO" - (set! (-> arg0 data 0) (* 300.000000 (-> arg0 data 0))) - (set! (-> arg0 data 1) (* 300.000000 (-> arg0 data 1))) - (set! (-> arg0 data 2) (* 300.000000 (-> arg0 data 2))) - arg0) - -(defun vector-seconds ((arg0 vector) (arg1 vector)) - "TODO" - (set! (-> arg0 data 0) (* 300.000000 (-> arg1 data 0))) - (set! (-> arg0 data 1) (* 300.000000 (-> arg1 data 1))) - (set! (-> arg0 data 2) (* 300.000000 (-> arg1 data 2))) - arg0) - -(defun vector-identity! ((arg0 vector)) - "TODO" - (set! (-> arg0 data 0) 1.000000) - (set! (-> arg0 data 1) 1.000000) - (set! (-> arg0 data 2) 1.000000) - (set! (-> arg0 data 3) 1.000000) - arg0) - -(defun seek-with-smooth ((arg0 float) (arg1 float) (arg2 float) (arg3 float) (arg4 float)) - "TODO" - (local-vars (v1-1 float) - (v1-3 float) - (f0-1 float) - (f0-2 float) - (f1-4 float)) - (set! f0-1 (- arg1 arg0)) - (cond - ((>= arg4 (fabs f0-1)) arg1) - (else - (set! f0-2 (* f0-1 arg3)) - (set! f1-4 (- arg2)) - (cond - ((< f0-2 f1-4) - (set! f0-2 f1-4) - (set! v1-1 f0-2)) - ((< arg2 f0-2) - (set! f0-2 arg2) - (set! v1-3 f0-2))) - (+ f0-2 arg0)))) - -(defun vector-seek-3d-smooth! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) - "TODO" - (local-vars (v1-4 float) - (v1-5 float) - (f0-1 float) - (f0-4 float) - (f0-5 float) - (f0-7 float) - (f1-2 float) - (f1-3 float) - (f2-6 float) - (f3-1 float) - (f3-4 float) - (f3-5 float) - (f3-7 float)) - (set! f0-1 (- (-> arg1 data 0) (-> arg0 data 0))) - (set! f1-2 (- (-> arg1 data 1) (-> arg0 data 1))) - (set! f3-1 (- (-> arg1 data 2) (-> arg0 data 2))) - (when - (or (!= f0-1 0.000000) (!= f1-2 0.000000) (!= f3-1 0.000000)) - (set! f2-6 (* f0-1 arg3)) - (set! f1-3 (* f1-2 arg3)) - (set! f0-4 (* f3-1 arg3)) - (set! f3-4 (+ (+ (* f2-6 f2-6) (* f1-3 f1-3)) (* f0-4 f0-4))) - (set! f3-5 (sqrtf f0-4)) - (cond - ((>= arg2 f3-5) - (set! (-> arg0 data 0) (+ (-> arg0 data 0) f2-6)) - (set! (-> arg0 data 1) (+ (-> arg0 data 1) f1-3)) - (set! f0-5 (+ (-> arg0 data 2) f0-4)) - (set! (-> arg0 data 2) f0-5) - (set! v1-4 f0-5)) - (else - (set! f3-7 (/ arg2 f3-5)) - (set! (-> arg0 data 0) (+ (-> arg0 data 0) (* f3-7 f2-6))) - (set! (-> arg0 data 1) (+ (-> arg0 data 1) (* f3-7 f1-3))) - (set! f0-7 (+ (-> arg0 data 2) (* f3-7 f0-4))) - (set! (-> arg0 data 2) f0-7) - (set! v1-5 f0-7)))) - arg0) - -(defun vector-seek-2d-yz-smooth! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) - "TODO" - (local-vars (v1-3 float) - (v1-4 float) - (f0-1 float) - (f0-3 float) - (f0-4 float) - (f0-6 float) - (f1-5 float) - (f2-1 float) - (f2-3 float) - (f2-4 float) - (f2-6 float)) - (set! f0-1 (- (-> arg1 data 1) (-> arg0 data 1))) - (set! f2-1 (- (-> arg1 data 2) (-> arg0 data 2))) - (when - (or (!= f0-1 0.000000) (!= f2-1 0.000000)) - (set! f1-5 (* f0-1 arg3)) - (set! f0-3 (* f2-1 arg3)) - (set! f2-3 (+ (* f1-5 f1-5) (* f0-3 f0-3))) - (set! f2-4 (sqrtf f0-3)) - (cond - ((>= arg2 f2-4) - (set! (-> arg0 data 1) (+ (-> arg0 data 1) f1-5)) - (set! f0-4 (+ (-> arg0 data 2) f0-3)) - (set! (-> arg0 data 2) f0-4) - (set! v1-3 f0-4)) - (else - (set! f2-6 (/ arg2 f2-4)) - (set! (-> arg0 data 1) (+ (-> arg0 data 1) (* f2-6 f1-5))) - (set! f0-6 (+ (-> arg0 data 2) (* f2-6 f0-3))) - (set! (-> arg0 data 2) f0-6) - (set! v1-4 f0-6)))) - arg0) - -(defun vector-seek-2d-xz-smooth! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) - "TODO" - (local-vars (v1-3 float) - (v1-4 float) - (f0-1 float) - (f0-3 float) - (f0-4 float) - (f0-6 float) - (f1-5 float) - (f2-1 float) - (f2-3 float) - (f2-4 float) - (f2-6 float)) - (set! f0-1 (- (-> arg1 data 0) (-> arg0 data 0))) - (set! f2-1 (- (-> arg1 data 2) (-> arg0 data 2))) - (when - (or (!= f0-1 0.000000) (!= f2-1 0.000000)) - (set! f1-5 (* f0-1 arg3)) - (set! f0-3 (* f2-1 arg3)) - (set! f2-3 (+ (* f1-5 f1-5) (* f0-3 f0-3))) - (set! f2-4 (sqrtf f0-3)) - (cond - ((>= arg2 f2-4) - (set! (-> arg0 data 0) (+ (-> arg0 data 0) f1-5)) - (set! f0-4 (+ (-> arg0 data 2) f0-3)) - (set! (-> arg0 data 2) f0-4) - (set! v1-3 f0-4)) - (else - (set! f2-6 (/ arg2 f2-4)) - (set! (-> arg0 data 0) (+ (-> arg0 data 0) (* f2-6 f1-5))) - (set! f0-6 (+ (-> arg0 data 2) (* f2-6 f0-3))) - (set! (-> arg0 data 2) f0-6) - (set! v1-4 f0-6)))) - arg0) - -(defun vector-seek! ((arg0 vector) (arg1 vector) (arg2 float)) - "TODO" - (rlet ((vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf) (vf4 :class vf) - (vf5 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.mov vf4 arg2) - (.lvf vf1 arg1) - (.lvf vf2 arg0) - (.add.x.vf vf1 vf0 vf0 :mask #b1) - (.sub.x.vf vf5 vf0 vf4 :mask #b1000) - (.sub.vf vf3 vf1 vf2 :mask #b1110) - (.min.x.vf vf3 vf3 vf4 :mask #b1110) - (.max.x.vf vf3 vf3 vf5 :mask #b1110) - (.add.vf vf1 vf2 vf3 :mask #b1110) - (.svf arg0 vf1) - arg0)) - -(defun vector-delta ((arg0 vector) (arg1 vector)) - "TODO" - (local-vars (v0-0 int)) - (rlet ((acc :class vf) - (vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf)) + (vf5 :class vf) + (vf6 :class vf) + ) (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 arg0) - (.lvf vf2 arg1) - (.sub.vf vf1 vf2 vf1) - (.abs.vf vf1 vf1) - (.mul.x.vf acc vf0 vf1 :mask #b1) - (.add.mul.y.vf acc vf0 vf1 acc :mask #b1) - (.add.mul.z.vf vf3 vf0 vf1 acc :mask #b1) - (.add.w.vf vf3 vf0 vf3 :mask #b1000) - (.mov v0-0 vf3) - (the-as float v0-0))) + (.lvf vf4 (&-> arg1 quad)) + (.lvf vf5 (&-> arg2 quad)) + (.add.x.vf vf6 vf0 vf0 :mask #b1000) + (.mul.vf vf6 vf4 vf5 :mask #b111) + (.svf (&-> arg0 quad) vf6) + arg0 + ) + ) -;; TODO - vector= (decomp failed) - -(defun vector-negate-in-place! ((arg0 vector)) - "TODO" - (rlet ((vf0 :class vf) - (vf1 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 arg0) - (.sub.vf vf1 vf0 vf1 :mask #b1110) - (.svf arg0 vf1) - arg0)) - -(defun vector-negate! ((arg0 vector) (arg1 vector)) - "TODO" - (rlet ((vf0 :class vf) - (vf1 :class vf) - (vf4 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 arg1) - (.sub.vf vf4 vf0 vf1 :mask #b1110) - (.add.x.vf vf4 vf0 vf0 :mask #b1) - (.svf arg0 vf4) - arg0)) - -(defun vector-float/! ((arg0 vector) (arg1 vector) (arg2 float)) - "TODO" - (rlet ((Q :class vf) +(defun vector+*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + "set arg0 = arg1 + (arg3 * arg2). The w component will be set to 1" + (rlet ((acc :class vf) (vf0 :class vf) - (vf1 :class vf) - (vf3 :class vf) - (vf4 :class vf)) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + ) (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.mov vf3 arg2) - (.div.vf Q vf0 vf3 :ftf #b11 :fsf #b0) - (.lvf vf1 arg1) - (.add.x.vf vf4 vf0 vf0 :mask #b1) - (.wait.vf) - (.mul.vf vf4 vf1 Q :mask #b1110) - (.nop.vf) - (.nop.vf) - (.svf arg0 vf4) - arg0)) + (.mov vf7 arg3) + (.lvf vf5 (&-> arg2 quad)) + (.lvf vf4 (&-> arg1 quad)) + (.add.x.vf vf6 vf0 vf0 :mask #b1000) + (.mul.x.vf acc vf5 vf7 :mask #b111) + ;; acts as just an add. + (.add.mul.w.vf vf6 vf4 vf0 acc :mask #b111) + (.svf (&-> arg0 quad) vf6) + arg0 + ) + ) -(defun vector--float*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) - "TODO" +(defun vector-*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + "Set arg0 = arg1 - (arg3 * arg2). The w component will be set to 1." (rlet ((acc :class vf) (vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf) - (vf4 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf2 arg2) - (.lvf vf1 arg1) - (.mov vf3 arg3) - (.add.x.vf vf4 vf0 vf0 :mask #b1) - (.mul.w.vf acc vf1 vf0) - (.sub.mul.x.vf vf4 vf2 vf3 acc :mask #b1110) - (.svf arg0 vf4) - arg0)) - -(defun vector-average! ((arg0 vector) (arg1 vector) (arg2 vector)) - "TODO" - (local-vars (v1-0 int)) - (rlet ((acc :class vf) - (vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf) - (vf4 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (set! v1-0 #x3f000000) - (.lvf vf1 arg1) - (.lvf vf2 arg2) - (.mov vf3 v1-0) - (.add.x.vf vf4 vf0 vf0 :mask #b1) - (.mul.x.vf acc vf1 vf3) - (.add.mul.x.vf vf4 vf2 vf3 acc :mask #b1110) - (.svf arg0 vf4) - arg0)) - -(defun vector-float*! ((arg0 vector) (arg1 vector) (arg2 float)) - "TODO" - (rlet ((vf0 :class vf) - (vf1 :class vf) - (vf2 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 arg1) - (.mov vf2 arg2) - (.add.x.vf vf1 vf0 vf0 :mask #b1) - (.mul.x.vf vf1 vf1 vf2 :mask #b1110) - (.svf arg0 vf1) - arg0)) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.mov vf7 arg3) + (.lvf vf5 (&-> arg2 quad)) + (.lvf vf4 (&-> arg1 quad)) + (.add.x.vf vf6 vf0 vf0 :mask #b1000) + (.mul.w.vf acc vf4 vf0 :mask #b111) + (.sub.mul.x.vf vf6 vf5 vf7 acc :mask #b111) + (.svf (&-> arg0 quad) vf6) + arg0 + ) + ) (defun vector/! ((arg0 vector) (arg1 vector) (arg2 vector)) - "TODO" - (local-vars (v1-0 float)) + "Set arg0 = arg1 / arg2. The w component will be set to 1. + The implementation is kind of crazy." (rlet ((Q :class vf) (vf0 :class vf) (vf4 :class vf) (vf5 :class vf) (vf6 :class vf) - (vf7 :class vf)) + (vf7 :class vf) + ) (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf5 arg2) - (.div.vf Q vf0 vf5 :ftf #b11 :fsf #b1) - (.add.x.vf vf6 vf0 vf0 :mask #b1) - (.lvf vf4 arg1) - (set! v1-0 (/ (-> arg1 data 0) (-> arg2 data 0))) + (.lvf vf5 (&-> arg2 quad)) + ;; get started on the first divide ASAP. + ;; do this before loading the second value. + ;; q = 1 / arg2.y + (.div.vf Q vf0 vf5 :fsf #b11 :ftf #b1) + (.add.x.vf vf6 vf0 vf0 :mask #b1000) + (.lvf vf4 (&-> arg1 quad)) + ;; use FPU to divide x while VU0 is dividing y. + (let ((v1-0 (/ (-> arg1 data 0) (-> arg2 data 0)))) + (.wait.vf) + + (.mul.vf vf6 vf4 Q :mask #b10) + (.nop.vf) + (.nop.vf) + (.div.vf Q vf0 vf5 :fsf #b11 :ftf #b10) + (.mov vf7 v1-0) + ) + (.add.x.vf vf6 vf0 vf7 :mask #b1) (.wait.vf) (.mul.vf vf6 vf4 Q :mask #b100) (.nop.vf) (.nop.vf) - (.div.vf Q vf0 vf5 :ftf #b11 :fsf #b10) - (.mov vf7 v1-0) - (.add.x.vf vf6 vf0 vf7 :mask #b1000) - (.wait.vf) - (.mul.vf vf6 vf4 Q :mask #b10) - (.nop.vf) - (.nop.vf) - (.svf arg0 vf6) - arg0)) + (.svf (&-> arg0 quad) vf6) + arg0 + ) + ) -(defun vector-*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) - "TODO" - (rlet ((acc :class vf) - (vf0 :class vf) - (vf4 :class vf) - (vf5 :class vf) - (vf6 :class vf) - (vf7 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.mov vf7 arg3) - (.lvf vf5 arg2) - (.lvf vf4 arg1) - (.add.x.vf vf6 vf0 vf0 :mask #b1) - (.mul.w.vf acc vf4 vf0 :mask #b1110) - (.sub.mul.x.vf vf6 vf5 vf7 acc :mask #b1110) - (.svf arg0 vf6) - arg0)) - -(defun vector+*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) - "TODO" - (rlet ((acc :class vf) - (vf0 :class vf) - (vf4 :class vf) - (vf5 :class vf) - (vf6 :class vf) - (vf7 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.mov vf7 arg3) - (.lvf vf5 arg2) - (.lvf vf4 arg1) - (.add.x.vf vf6 vf0 vf0 :mask #b1) - (.mul.x.vf acc vf5 vf7 :mask #b1110) - (.add.mul.w.vf vf6 vf4 vf0 acc :mask #b1110) - (.svf arg0 vf6) - arg0)) - -(defun vector*! ((arg0 vector) (arg1 vector) (arg2 vector)) - "TODO" +(defun vector-float*! ((arg0 vector) (arg1 vector) (arg2 float)) + "Multiply all values in a vector by arg2. Set w to 1." (rlet ((vf0 :class vf) - (vf4 :class vf) - (vf5 :class vf) - (vf6 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf4 arg1) - (.lvf vf5 arg2) - (.add.x.vf vf6 vf0 vf0 :mask #b1) - (.mul.vf vf6 vf4 vf5 :mask #b1110) - (.svf arg0 vf6) - arg0)) - -(defun vector+float! ((arg0 vector) (arg1 vector) (arg2 float)) - "TODO" - (rlet ((vf0 :class vf) - (vf4 :class vf) - (vf5 :class vf) - (vf6 :class vf)) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.mov vf6 arg2) - (.lvf vf4 arg1) - (.add.x.vf vf5 vf0 vf0 :mask #b1) - (.add.x.vf vf5 vf4 vf6 :mask #b1110) - (.svf arg0 vf5) - arg0)) - -(defun vector-cross! ((arg0 vector) (arg1 vector) (arg2 vector)) - "TODO" - (rlet ((acc :class vf) (vf1 :class vf) (vf2 :class vf) - (vf3 :class vf)) - (.lvf vf1 arg1) - (.lvf vf2 arg2) - (.outer.product.vf vf3 vf1 vf2) - (.svf arg0 vf3) - arg0)) \ No newline at end of file + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 quad)) + (.mov vf2 arg2) + (.add.x.vf vf1 vf0 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +(defun vector-average! ((arg0 vector) (arg1 vector) (arg2 vector)) + "Set arg0 to the average of arg1 and arg2. Set w to 1." + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (let ((v1-0 #x3f000000)) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (.mov vf3 v1-0) + ) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.mul.x.vf acc vf1 vf3) + (.add.mul.x.vf vf4 vf2 vf3 acc :mask #b111) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + +(defun vector+float*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + "Set arg0 = arg1 + (arg2 * arg3). The w component will be set to 1. + Is this different at all from vector+*! ? The implementation is slightly different + but I think it comes out to the same thing." + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg2 quad)) + (.lvf vf1 (&-> arg1 quad)) + (.mov vf3 arg3) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.mul.x.vf acc vf2 vf3) + (.add.mul.w.vf vf4 vf1 vf0 acc :mask #b111) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + +(defun vector--float*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + "Set arg0 = arg1 - (arg2 * arg3). The w component will be set to 1 + Is this different from vector-*!" + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg2 quad)) + (.lvf vf1 (&-> arg1 quad)) + (.mov vf3 arg3) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.mul.w.vf acc vf1 vf0) + (.sub.mul.x.vf vf4 vf2 vf3 acc :mask #b111) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + +(defun vector-float/! ((arg0 vector) (arg1 vector) (arg2 float)) + "Divide all components by arg2. The w component will be set to 1." + (rlet ((Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.mov vf3 arg2) + (.div.vf Q vf0 vf3 :fsf #b11 :ftf #b0) + (.lvf vf1 (&-> arg1 quad)) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.wait.vf) + (.mul.vf vf4 vf1 Q :mask #b111) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + + +(defun vector-negate! ((arg0 vector) (arg1 vector)) + "Negate xyz, set w to 1" + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 quad)) + (.sub.vf vf4 vf0 vf1 :mask #b111) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + +(defun vector-negate-in-place! ((arg0 vector)) + "Negate xyz. Doesn't touch w." + (rlet ((vf0 :class vf) + (vf1 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.sub.vf vf1 vf0 vf1 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +(defun vector= ((arg0 vector) (arg1 vector)) + "Are the two vectors equal? Does not compare the w component. + The implementation is cool." + + ;; (label L91) + ;; (set! v0-0 #t) + ;; (set! v1-0 #xffff) + (let* ((v1-0 #xffff) + ;; (set! a0-1 (l.q a0-0)) + (a0-1 (-> arg0 quad)) + ;; (set! v1-1 (sll v1-0 48)) + (v1-1 (shl v1-0 48)) + ;; (set! a1-1 (l.q a1-0)) + (a1-1 (-> arg1 quad)) + (a0-2 (the uint128 0)) + (r0 (the uint128 0)) + ) + ;; (.pceqw a0-2 a0-1 a1-1) + (.pceqw a0-2 a0-1 a1-1) + ;; (.ppach a0-3 r0-0 a0-2) + (.ppach a0-2 r0 a0-2) + ;; (set! v1-2 (logior a0-3 v1-1)) + (set! v1-1 (logior (the int a0-2) v1-1)) + ;; (set! v1-3 (+ v1-2 1)) + ;; will overflow the 64-bit integer if xyz is equal. + (set! v1-1 (+ v1-1 1)) + (zero? v1-1) + ) + + ;; (b! (zero? v1-3) L92 (nop!)) + ;; (set! v0-0 #f) + ;; (label L92) + ;; (ret-value v0-0) + + ) + +(defun vector-delta ((arg0 vector) (arg1 vector)) + "Sum of the elementwise absolute value of differences" + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.lvf vf2 (&-> arg1 quad)) + (.sub.vf vf1 vf2 vf1) + (.abs.vf vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.z.vf vf3 vf0 vf1 acc :mask #b1000) + (.add.w.vf vf3 vf0 vf3 :mask #b1) + (.mov v0-0 vf3) + v0-0 + ) + ) + +(defun vector-seek! ((arg0 vector) (arg1 vector) (arg2 float)) + "Seek arg0 toward arg1. The arg0 is both read and written. + arg2 is saturated to (0, 1)" + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.mov vf4 arg2) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg0 quad)) + (.add.x.vf vf1 vf0 vf0 :mask #b1000) + (.sub.x.vf vf5 vf0 vf4 :mask #b1) + (.sub.vf vf3 vf1 vf2 :mask #b111) + (.min.x.vf vf3 vf3 vf4 :mask #b111) + (.max.x.vf vf3 vf3 vf5 :mask #b111) + (.add.vf vf1 vf2 vf3 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +(defun vector-seek-2d-xz-smooth! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) + (let ((f0-1 (- (-> arg1 data 0) (-> arg0 data 0))) + (f2-1 (- (-> arg1 data 2) (-> arg0 data 2))) + ) + (if (or (!= f0-1 0.0) (!= f2-1 0.0)) + (let* ((f1-5 (* f0-1 arg3)) + (f0-3 (* f2-1 arg3)) + (f2-4 (sqrtf (+ (* f1-5 f1-5) (* f0-3 f0-3)))) + ) + (cond + ((>= arg2 f2-4) + (set! (-> arg0 data 0) (+ (-> arg0 data 0) f1-5)) + (let ((f0-4 (+ (-> arg0 data 2) f0-3))) + (set! (-> arg0 data 2) f0-4) + ) + ) + (else + (let ((f2-6 (/ arg2 f2-4))) + (set! (-> arg0 data 0) (+ (-> arg0 data 0) (* f2-6 f1-5))) + (let ((f0-6 (+ (-> arg0 data 2) (* f2-6 f0-3)))) + (set! (-> arg0 data 2) f0-6) + ) + ) + ) + ) + ) + ) + ) + arg0 + ) + +(defun vector-seek-2d-yz-smooth! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) + (let ((f0-1 (- (-> arg1 data 1) (-> arg0 data 1))) + (f2-1 (- (-> arg1 data 2) (-> arg0 data 2))) + ) + (if (or (!= f0-1 0.0) (!= f2-1 0.0)) + (let* ((f1-5 (* f0-1 arg3)) + (f0-3 (* f2-1 arg3)) + (f2-4 (sqrtf (+ (* f1-5 f1-5) (* f0-3 f0-3)))) + ) + (cond + ((>= arg2 f2-4) + (set! (-> arg0 data 1) (+ (-> arg0 data 1) f1-5)) + (let ((f0-4 (+ (-> arg0 data 2) f0-3))) + (set! (-> arg0 data 2) f0-4) + ) + ) + (else + (let ((f2-6 (/ arg2 f2-4))) + (set! (-> arg0 data 1) (+ (-> arg0 data 1) (* f2-6 f1-5))) + (let ((f0-6 (+ (-> arg0 data 2) (* f2-6 f0-3)))) + (set! (-> arg0 data 2) f0-6) + ) + ) + ) + ) + ) + ) + ) + arg0 + ) + +(defun vector-seek-3d-smooth! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) + (let ((f0-1 (- (-> arg1 data 0) (-> arg0 data 0))) + (f1-2 (- (-> arg1 data 1) (-> arg0 data 1))) + (f3-1 (- (-> arg1 data 2) (-> arg0 data 2))) + ) + (if (or (!= f0-1 0.0) (!= f1-2 0.0) (!= f3-1 0.0)) + (let* ((f2-6 (* f0-1 arg3)) + (f1-3 (* f1-2 arg3)) + (f0-4 (* f3-1 arg3)) + (f3-5 (sqrtf (+ (+ (* f2-6 f2-6) (* f1-3 f1-3)) (* f0-4 f0-4)))) + ) + (cond + ((>= arg2 f3-5) + (set! (-> arg0 data 0) (+ (-> arg0 data 0) f2-6)) + (set! (-> arg0 data 1) (+ (-> arg0 data 1) f1-3)) + (let ((f0-5 (+ (-> arg0 data 2) f0-4))) + (set! (-> arg0 data 2) f0-5) + ) + ) + (else + (let ((f3-7 (/ arg2 f3-5))) + (set! (-> arg0 data 0) (+ (-> arg0 data 0) (* f3-7 f2-6))) + (set! (-> arg0 data 1) (+ (-> arg0 data 1) (* f3-7 f1-3))) + (let ((f0-7 (+ (-> arg0 data 2) (* f3-7 f0-4)))) + (set! (-> arg0 data 2) f0-7) + ) + ) + ) + ) + ) + ) + ) + arg0 + ) + +(defun seek-with-smooth ((arg0 float) (arg1 float) (arg2 float) (arg3 float) (arg4 float)) + (let ((f0-1 (- arg1 arg0))) + (if (>= arg4 (fabs f0-1)) + arg1 + (let ((f0-2 (* f0-1 arg3))) + (let ((f1-4 (- arg2))) + (cond + ((< f0-2 f1-4) + (set! f0-2 f1-4) + ) + ((< arg2 f0-2) + (set! f0-2 arg2) + ) + ) + ) + (+ f0-2 arg0) + ) + ) + ) + ) + +(defun vector-identity! ((arg0 vector)) + (set! (-> arg0 data 0) 1.0) + (set! (-> arg0 data 1) 1.0) + (set! (-> arg0 data 2) 1.0) + (set! (-> arg0 data 3) 1.0) + arg0 + ) + +(defun vector-seconds ((arg0 vector) (arg1 vector)) + (set! (-> arg0 data 0) (* 300.0 (-> arg1 data 0))) + (set! (-> arg0 data 1) (* 300.0 (-> arg1 data 1))) + (set! (-> arg0 data 2) (* 300.0 (-> arg1 data 2))) + arg0 + ) + +(defun vector-seconds! ((arg0 vector)) + (set! (-> arg0 data 0) (* 300.0 (-> arg0 data 0))) + (set! (-> arg0 data 1) (* 300.0 (-> arg0 data 1))) + (set! (-> arg0 data 2) (* 300.0 (-> arg0 data 2))) + arg0 + ) + +(defun vector-v! ((arg0 vector)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (let ((v1-0 arg0)) + (let ((a1-0 arg0) + (f0-0 (-> *display* seconds-per-frame)) + ) + (.lvf vf1 (&-> a1-0 quad)) + (let ((a1-1 f0-0)) + (.mov vf2 a1-1) + ) + ) + (.add.x.vf vf1 vf0 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> v1-0 quad) vf1) + ) + arg0 + ) + ) + +(defun vector-v+! ((arg0 vector) (arg1 vector) (arg2 vector)) + (vector+float*! arg0 arg1 arg2 (-> *display* seconds-per-frame)) + arg0 + ) + +(defun vector-v*float+! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (vector+float*! arg0 arg1 arg2 (* arg3 (-> *display* seconds-per-frame))) + arg0 + ) + +(defun vector-v++! ((arg0 vector) (arg1 vector)) + (vector+float*! arg0 arg0 arg1 (-> *display* seconds-per-frame)) + arg0 + ) + +(defun vector-v*float! ((arg0 vector) (arg1 float) (arg2 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (let ((v0-0 arg0)) + (let ((v1-0 arg1) + (f0-1 (* arg2 (-> *display* seconds-per-frame))) + ) + (.lvf vf1 v1-0) + (let ((v1-1 f0-1)) + (.mov vf2 v1-1) + ) + ) + (.add.x.vf vf1 vf0 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> v0-0 quad) vf1) + v0-0 + ) + ) + ) + +(defun vector-v*float++! ((arg0 vector) (arg1 vector) (arg2 float)) + (vector+float*! arg0 arg0 arg1 (* arg2 (-> *display* seconds-per-frame))) + arg0 + ) + +(defun vector-to-ups! ((arg0 vector) (arg1 vector)) + (local-vars (at-0 int)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 quad)) + (let ((f0-0 (-> *display* frames-per-second))) + (.mov at-0 f0-0) + ) + (.mov vf2 at-0) + (.mov.vf vf1 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +(defun vector-from-ups! ((arg0 vector) (arg1 vector)) + (local-vars (at-0 int)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 quad)) + (let ((f0-0 (-> *display* seconds-per-frame))) + (.mov at-0 f0-0) + ) + (.mov vf2 at-0) + (.mov.vf vf1 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +(defun vector-length ((arg0 vector)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) + (.sqrt.vf Q vf1 :ftf #b11) + (.add.w.vf vf1 vf0 vf0 :mask #b1) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b1) + (.nop.vf) + (.nop.vf) + (.mov v0-0 vf1) + v0-0 + ) + ) + +(defun vector-length-squared ((arg0 vector)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.add.w.vf vf2 vf0 vf0 :mask #b1) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf2 vf1 :mask #b1) + (.add.mul.y.vf acc vf2 vf1 acc :mask #b1) + (.add.mul.z.vf vf1 vf2 vf1 acc :mask #b1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +(defun vector-xz-length-squared ((arg0 vector)) + (+ + (* (-> arg0 data 0) (-> arg0 data 0)) + (* (-> arg0 data 2) (-> arg0 data 2)) + ) + ) + +(defun vector-xz-length ((arg0 vector)) + (sqrtf + (+ + (* (-> arg0 data 0) (-> arg0 data 0)) + (* (-> arg0 data 2) (-> arg0 data 2)) + ) + ) + ) + +(defun vector-vector-distance ((arg0 vector) (arg1 vector)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) + (.sqrt.vf Q vf1 :ftf #b11) + (.add.w.vf vf1 vf0 vf0 :mask #b1) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b1) + (.nop.vf) + (.nop.vf) + (.mov v0-0 vf1) + v0-0 + ) + ) + +(defun vector-vector-distance-squared ((arg0 vector) (arg1 vector)) + (local-vars (v0-0 float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.add.y.vf vf1 vf1 vf1 :mask #b1) + (.add.z.vf vf1 vf1 vf1 :mask #b1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +(defun vector-vector-xz-distance ((arg0 vector) (arg1 vector)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) + (.sqrt.vf Q vf1 :ftf #b11) + (.add.w.vf vf1 vf0 vf0 :mask #b1) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b1) + (.nop.vf) + (.nop.vf) + (.mov v0-0 vf1) + v0-0 + ) + ) + +(defun vector-vector-xz-distance-squared ((arg0 vector) (arg1 vector)) + (local-vars (v0-0 float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.add.z.vf vf1 vf1 vf1 :mask #b1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +(defun vector-normalize! ((arg0 vector) (arg1 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.mul.vf vf2 vf1 vf1 :mask #b111) + (let ((v1-0 arg1)) + (.mov vf3 v1-0) + ) + (.mul.x.vf acc vf0 vf2 :mask #b1000) + (.add.mul.y.vf acc vf0 vf2 acc :mask #b1000) + (.add.mul.z.vf vf2 vf0 vf2 acc :mask #b1000) + (.isqrt.vf Q vf3 vf2 :fsf #b0 :ftf #b11) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b111) + (.nop.vf) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +(defun vector-normalize-ret-len! ((arg0 vector) (arg1 float)) + (local-vars (v1-1 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.mul.vf vf2 vf1 vf1 :mask #b111) + (let ((v1-0 arg1)) + (.mov vf3 v1-0) + ) + (.mul.x.vf acc vf0 vf2 :mask #b1000) + (.add.mul.y.vf acc vf0 vf2 acc :mask #b1000) + (.add.mul.z.vf vf2 vf0 vf2 acc :mask #b1000) + (.isqrt.vf Q vf3 vf2 :fsf #b0 :ftf #b11) + (.add.w.vf vf2 vf0 vf2 :mask #b1) + (.mov v1-1 vf2) + (let ((v0-0 (sqrtf v1-1))) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b111) + (.nop.vf) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 quad) vf1) + v0-0 + ) + ) + ) + +(defun vector-normalize-copy! ((arg0 vector) (arg1 vector) (arg2 float)) + (let ((f0-0 (vector-length arg1))) + (if (= f0-0 0.0) + (set! (-> arg0 quad) (-> arg1 quad)) + (let ((v1-1 (/ arg2 f0-0))) + (set! (-> arg0 data 0) (* (-> arg1 data 0) v1-1)) + (set! (-> arg0 data 1) (* (-> arg1 data 1) v1-1)) + (let ((f0-7 (* (-> arg1 data 2) v1-1))) + (set! (-> arg0 data 2) f0-7) + ) + ) + ) + ) + (set! (-> arg0 data 3) 1.0) + arg0 + ) + +(defun vector-xz-normalize! ((arg0 vector) (arg1 float)) + (let ((f0-0 (vector-xz-length arg0))) + (if (!= f0-0 0.0) + (let ((v1-1 (/ arg1 f0-0))) + (set! (-> arg0 data 0) (* (-> arg0 data 0) v1-1)) + (let ((f0-5 (* (-> arg0 data 2) v1-1))) + (set! (-> arg0 data 2) f0-5) + ) + ) + ) + ) + arg0 + ) + +(defun vector-length-max! ((arg0 vector) (arg1 float)) + (let ((f0-0 (vector-length arg0))) + (when (not (or (= f0-0 0.0) (< f0-0 arg1))) + (set! f0-0 (/ f0-0 arg1)) + (when (!= f0-0 0.0) + (set! (-> arg0 data 0) (/ (-> arg0 data 0) f0-0)) + (set! (-> arg0 data 1) (/ (-> arg0 data 1) f0-0)) + (let ((f0-1 (/ (-> arg0 data 2) f0-0))) + (set! (-> arg0 data 2) f0-1) + ) + ) + ) + ) + arg0 + ) + +(defun vector-xz-length-max! ((arg0 vector) (arg1 float)) + (let ((f0-0 (vector-xz-length arg0))) + (when (not (or (= f0-0 0.0) (< f0-0 arg1))) + (set! f0-0 (/ f0-0 arg1)) + (when (!= f0-0 0.0) + (set! (-> arg0 data 0) (/ (-> arg0 data 0) f0-0)) + (let ((f0-1 (/ (-> arg0 data 2) f0-0))) + (set! (-> arg0 data 2) f0-1) + ) + ) + ) + ) + arg0 + ) + +(defun vector-rotate-around-y! ((arg0 vector) (arg1 vector) (arg2 float)) + (let ((f26-0 (-> arg1 data 2)) + (f30-0 (-> arg1 data 0)) + (f28-0 (cos arg2)) + (f0-0 (sin arg2)) + ) + (set! (-> arg0 quad) (-> arg1 quad)) + (set! (-> arg0 data 2) (- (* f26-0 f28-0) (* f30-0 f0-0))) + (set! (-> arg0 data 0) (+ (* f26-0 f0-0) (* f30-0 f28-0))) + ) + arg0 + ) + +(defun rotate-y<-vector+vector ((arg0 vector) (arg1 vector)) + (atan + (- (-> arg1 data 0) (-> arg0 data 0)) + (- (-> arg1 data 2) (-> arg0 data 2)) + ) + ) + +(defun vector-cvt.w.s! ((arg0 vector) (arg1 vector)) + (rlet ((vf1 :class vf)) + (.lvf vf1 (&-> arg1 quad)) + (.ftoi.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +(defun vector-cvt.s.w! ((arg0 vector) (arg1 vector)) + (rlet ((vf1 :class vf)) + (.lvf vf1 (&-> arg1 quad)) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +(defun rot-zxy-from-vector! ((arg0 vector) (arg1 vector)) + (let* ((f28-0 (-> arg1 data 2)) + (f30-0 (-> arg1 data 0)) + (f0-0 (atan f30-0 f28-0)) + ) + (set! (-> arg0 data 1) f0-0) + (let* ((f26-0 (- f0-0)) + (f0-4 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) + (f0-5 (atan (- (-> arg1 data 1)) f0-4)) + ) + (set! (-> arg0 data 0) f0-5) + ) + ) + (set! (-> arg0 data 2) 0.0) + arg0 + ) + +(defun rot-zyx-from-vector! ((arg0 vector) (arg1 vector)) + (let* ((f28-0 (-> arg1 data 2)) + (f30-0 (- (-> arg1 data 1))) + (f0-1 (atan f30-0 f28-0)) + ) + (set! (-> arg0 data 0) f0-1) + (let* ((f26-0 (- f0-1)) + (f0-5 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) + (f0-6 (atan (-> arg1 data 0) f0-5)) + ) + (set! (-> arg0 data 1) f0-6) + ) + ) + (set! (-> arg0 data 2) 0.0) + arg0 + ) + +;; definition for function vector-lerp! +(defun vector-lerp! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (.mov vf4 arg3) + (.add.x.vf vf3 vf0 vf0 :mask #b1000) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2 :mask #b111) + (.svf (&-> arg0 quad) vf3) + arg0 + ) + ) + +;; definition for function vector-lerp-clamp! +;; Used lq/sq +(defun + vector-lerp-clamp! + ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (cond + ((>= 0.0 arg3) + (set! (-> arg0 quad) (-> arg1 quad)) + ) + ((>= arg3 1.0) + (set! (-> arg0 quad) (-> arg2 quad)) + ) + (else + (let ((v1-2 arg0)) + (let ((f0-2 arg3)) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (let ((a1-1 f0-2)) + (.mov vf4 a1-1) + ) + ) + (.add.x.vf vf3 vf0 vf0 :mask #b1000) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2 :mask #b111) + (.svf (&-> v1-2 quad) vf3) + ) + ) + ) + arg0 + ) + ) + +;; definition for function vector4-lerp! +(defun vector4-lerp! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (.mov vf4 arg3) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2) + (.svf (&-> arg0 quad) vf3) + arg0 + ) + ) + +;; definition for function vector4-lerp-clamp! +;; Used lq/sq +(defun + vector4-lerp-clamp! + ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (cond + ((>= 0.0 arg3) + (set! (-> arg0 quad) (-> arg1 quad)) + ) + ((>= arg3 1.0) + (set! (-> arg0 quad) (-> arg2 quad)) + ) + (else + (let ((v1-2 arg0)) + (let ((f0-2 arg3)) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (let ((a1-1 f0-2)) + (.mov vf4 a1-1) + ) + ) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2) + (.svf (&-> v1-2 quad) vf3) + ) + ) + ) + arg0 + ) + ) + +(defun vector-degi ((arg0 vector) (arg1 vector)) + (local-vars (v1-0 float) (v1-1 uint128)) + (rlet ((vf1 :class vf)) + (.lvf vf1 (&-> arg1 quad)) + (.ftoi.vf vf1 vf1) + (.mov v1-0 vf1) + (.pw.sll v1-1 v1-0 16) + (set! (-> arg0 quad) (the-as uint128 v1-1)) + arg0 + ) + ) + +(defun vector-degf ((arg0 vector) (arg1 vector)) + (local-vars (v1-1 uint128)) + (rlet ((vf1 :class vf)) + (let ((v1-0 (-> arg1 quad))) + (.pw.sra v1-1 v1-0 16) + ) + (.mov vf1 v1-1) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +(defun vector-degmod ((arg0 vector) (arg1 vector)) + (local-vars (v1-0 float) (v1-1 uint128) (v1-2 uint128)) + (rlet ((vf1 :class vf)) + (.lvf vf1 (&-> arg1 quad)) + (.ftoi.vf vf1 vf1) + (.mov v1-0 vf1) + (.pw.sll v1-1 v1-0 16) + (.pw.sra v1-2 v1-1 16) + (.mov vf1 v1-2) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; todo: vector-deg-diff + +(defun vector-deg-lerp-clamp! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (cond + ((>= 0.0 arg3) + (let ((v1-0 arg0)) + (set! (-> v1-0 quad) (-> arg1 quad)) + ) + ) + ((>= arg3 1.0) + (let ((v1-1 arg0)) + (set! (-> v1-1 quad) (-> arg2 quad)) + ) + ) + (else + (set! + (-> arg0 data 0) + (deg-lerp-clamp (-> arg1 data 0) (-> arg2 data 0) arg3) + ) + (set! + (-> arg0 data 1) + (deg-lerp-clamp (-> arg1 data 1) (-> arg2 data 1) arg3) + ) + (set! + (-> arg0 data 2) + (deg-lerp-clamp (-> arg1 data 2) (-> arg2 data 2) arg3) + ) + (let ((f0-11 1.0)) + (set! (-> arg0 data 3) f0-11) + ) + ) + ) + arg0 + ) + +(defun vector3s-copy! ((arg0 vector) (arg1 vector)) + (let ((v1-0 "Copy a vector3s")) + ) + (set! (-> arg0 data 0) (-> arg1 data 0)) + (set! (-> arg0 data 1) (-> arg1 data 1)) + (set! (-> arg0 data 2) (-> arg1 data 2)) + arg0 + ) + +(defun vector3s+! ((arg0 vector) (arg1 vector) (arg2 vector)) + (let ((v1-0 "Add 2 vectors3.")) + ) + (set! (-> arg0 data 0) (+ (-> arg1 data 0) (-> arg2 data 0))) + (set! (-> arg0 data 1) (+ (-> arg1 data 1) (-> arg2 data 1))) + (set! (-> arg0 data 2) (+ (-> arg1 data 2) (-> arg2 data 2))) + arg0 + ) + +(defun vector3s*float! ((arg0 vector) (arg1 vector) (arg2 float)) + (let ((v1-0 "mult vectors3 by float")) + ) + (set! (-> arg0 data 0) (* (-> arg1 data 0) arg2)) + (set! (-> arg0 data 1) (* (-> arg1 data 1) arg2)) + (set! (-> arg0 data 2) (* (-> arg1 data 2) arg2)) + arg0 + ) + +(defun vector3s-! ((arg0 vector) (arg1 vector) (arg2 vector)) + (let ((v1-0 "Subtract 2 vectors3: c = (a - b).")) + ) + (set! (-> arg0 data 0) (- (-> arg1 data 0) (-> arg2 data 0))) + (set! (-> arg0 data 1) (- (-> arg1 data 1) (-> arg2 data 1))) + (set! (-> arg0 data 2) (- (-> arg1 data 2) (-> arg2 data 2))) + arg0 + ) + +(defun spheres-overlap? ((arg0 vector) (arg1 vector)) + (local-vars (v1-0 float) (a0-1 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.lvf vf2 (&-> arg1 quad)) + (.sub.vf vf3 vf1 vf2 :mask #b111) + (.mul.vf vf3 vf3 vf3 :mask #b111) + (.add.w.vf vf4 vf1 vf2 :mask #b1000) + (.mul.w.vf vf4 vf4 vf4 :mask #b1000) + (.add.y.vf vf3 vf3 vf3 :mask #b1) + (.add.z.vf vf3 vf3 vf3 :mask #b1) + (.add.w.vf vf4 vf0 vf4 :mask #b1) + (.mov a0-1 vf4) + (.mov v1-0 vf3) + (>= a0-1 v1-0) + ) + ) + +(defun sphere<-vector! ((arg0 sphere) (arg1 vector)) + (let ((f0-0 (-> arg0 data 3))) + (set! (-> arg0 quad) (-> arg1 quad)) + (set! (-> arg0 data 3) f0-0) + ) + arg0 + ) + +(defun sphere<-vector+r! ((arg0 sphere) (arg1 vector) (arg2 float)) + (set! (-> arg0 quad) (-> arg1 quad)) + (set! (-> arg0 data 3) arg2) + arg0 + ) + +(defun rand-vu-sphere-point! ((arg0 vector) (arg1 sphere)) + (let ((s4-0 arg0)) + (set! (-> s4-0 data 0) (rand-vu-float-range -1.0 1.0)) + (set! (-> s4-0 data 1) (rand-vu-float-range -1.0 1.0)) + (set! (-> s4-0 data 2) (rand-vu-float-range -1.0 1.0)) + (set! (-> s4-0 data 3) 1.0) + ) + (vector-normalize! arg0 (rand-vu-float-range 0.0 (the-as float arg1))) + ) diff --git a/goal_src/engine/ps2/pad.gc b/goal_src/engine/ps2/pad.gc index c31a3bbd1a..718b702317 100644 --- a/goal_src/engine/ps2/pad.gc +++ b/goal_src/engine/ps2/pad.gc @@ -12,36 +12,38 @@ ;; this gets set to #f later on. (define *cheat-mode* #t) +;; data that comes directly from hardware. (deftype hw-cpad (basic) - ((valid uint8 :offset-assert 4) - (status uint8 :offset-assert 5) - (button0 uint16 :offset-assert 6) - (rightx uint8 :offset-assert 8) - (righty uint8 :offset-assert 9) - (leftx uint8 :offset-assert 10) - (lefty uint8 :offset-assert 11) - (abutton uint8 12 :offset-assert 12) - (dummy uint8 12 :offset-assert 24) + ((valid uint8 :offset-assert 4) + (status uint8 :offset-assert 5) + (button0 uint16 :offset-assert 6) + (rightx uint8 :offset-assert 8) + (righty uint8 :offset-assert 9) + (leftx uint8 :offset-assert 10) + (lefty uint8 :offset-assert 11) + (abutton uint8 12 :offset-assert 12) + (dummy uint8 12 :offset-assert 24) ) :method-count-assert 9 :size-assert #x24 :flag-assert #x900000024 ) +;; data from hardware + additional info calculated here. (deftype cpad-info (hw-cpad) ((number int32 :offset-assert 36) (cpad-file int32 :offset-assert 40) - (button0-abs uint32 3 :offset-assert 44) ;; bitmask of buttons, pressed or not, with history - (button0-shadow-abs uint32 1 :offset-assert 56) ;; modify this to change button history in the future. - (button0-rel uint32 3 :offset-assert 60) ;; bitmask of if button going down. + (button0-abs uint32 3 :offset-assert 44) ;; bitmask of buttons, pressed or not, with history + (button0-shadow-abs uint32 1 :offset-assert 56) ;; modify this to change button history in the future. + (button0-rel uint32 3 :offset-assert 60) ;; bitmask of if button going down. (stick0-dir float :offset-assert 72) (stick0-speed float :offset-assert 76) (new-pad int32 :offset-assert 80) (state int32 :offset-assert 84) - (align uint8 6 :offset-assert 88) - (direct uint8 6 :offset-assert 94) ;; hardware control of buzzing. - (buzz-val uint8 2 :offset-assert 100) ;; intensity for buzzing - (buzz-time uint64 2 :offset-assert 104) ;; when to stop buzzing + (align uint8 6 :offset-assert 88) + (direct uint8 6 :offset-assert 94) ;; hardware control of buzzing. + (buzz-val uint8 2 :offset-assert 100) ;; intensity for buzzing + (buzz-time uint64 2 :offset-assert 104) ;; when to stop buzzing (buzz basic :offset-assert 120) ;; is vibration enabled? (buzz-act int32 :offset-assert 124) (change-time uint64 :offset-assert 128) @@ -54,9 +56,54 @@ :flag-assert #x900000088 ) +(defun cpad-invalid! ((pad cpad-info)) + "Reset all data in a cpad-info" + (set! (-> pad valid) (logior (-> pad valid) 128)) + (set! (-> pad button0) (the-as uint 0)) + (set! (-> pad button0-abs 0) (the-as uint 0)) + (set! (-> pad button0-shadow-abs 0) (the-as uint 0)) + (set! (-> pad button0-rel 0) (the-as uint 0)) + (dotimes (v1-2 12) + (nop!) + (set! (-> pad abutton v1-2) 0) + ) + (set! (-> pad stick0-dir) 0.0) + (set! (-> pad stick0-speed) 0.0) + (set! (-> pad rightx) (the-as uint 128)) + (set! (-> pad righty) (the-as uint 128)) + (set! (-> pad leftx) (the-as uint 128)) + (set! (-> pad lefty) (the-as uint 128)) + (set! (-> pad align 0) (the-as uint 0)) + (set! (-> pad align 1) (the-as uint 1)) + (set! (-> pad align 2) (the-as uint 255)) + (set! (-> pad align 3) (the-as uint 255)) + (set! (-> pad align 4) (the-as uint 255)) + (set! (-> pad align 5) (the-as uint 255)) + (dotimes (v1-14 6) + (set! (-> pad direct v1-14) 0) + ) + ;; probably a bug here, this should use v1-17 as the index. + (dotimes (v1-17 2) + (set! (-> pad buzz-val 0) (the-as uint 0)) + (set! (-> pad buzz-time 0) (the-as uint 0)) + ) + pad + ) + +(defmethod new cpad-info ((alloction symbol) (type-to-make type) (idx int)) + "Allocate a new cpad-info and open the pad itself through the kernel" + (let ((obj (object-new alloction type-to-make (the-as int (-> type-to-make size))))) + (set! (-> obj number) idx) + (set! (-> obj buzz) #f) + (cpad-open obj idx) ;; kernel function. + (cpad-invalid! obj) + ) + ) + +;; List of controllers. It always has 2 controllers. (deftype cpad-list (basic) - ((num-cpads int32 :offset-assert 4) - (cpads cpad-info 2 :offset-assert 8) ;; guess + ((num-cpads int32 :offset-assert 4) + (cpads cpad-info 2 :offset-assert 8) ) (:methods (new (symbol type) _type_ 0) @@ -66,92 +113,44 @@ :flag-assert #x900000010 ) -(defun cpad-invalid! ((pad cpad-info)) - "Make everything in a cpad-info set to default" - (local-vars (v1-2 int) (v1-14 int) (v1-17 int)) - (set! (-> pad valid) (logior (-> pad valid) 128)) - (set! (-> pad button0) 0) - (set! (-> pad button0-abs 0) 0) - (set! (-> pad button0-shadow-abs 0) 0) - (set! (-> pad button0-rel 0) 0) - (set! v1-2 0) - (while (< v1-2 12) - (nop!) - (set! (-> pad abutton v1-2) 0) - (+! v1-2 1) - ) - (set! (-> pad stick0-dir) 0.000000) - (set! (-> pad stick0-speed) 0.000000) - (set! (-> pad rightx) 128) - (set! (-> pad righty) 128) - (set! (-> pad leftx) 128) - (set! (-> pad lefty) 128) - (set! (-> pad align 0) 0) - (set! (-> pad align 1) 1) - (set! (-> pad align 2) 255) - (set! (-> pad align 3) 255) - (set! (-> pad align 4) 255) - (set! (-> pad align 5) 255) - (set! v1-14 0) - (while (< v1-14 6) - (set! (-> pad direct v1-14) 0) - (+! v1-14 1) - ) - (set! v1-17 0) - (while (< v1-17 2) - (set! (-> pad buzz-val 0) 0) - (set! (-> pad buzz-time 0) 0) - (+! v1-17 1) - ) - pad - ) - -(defmethod new cpad-info ((alloction symbol) (type-to-make type) (idx int)) - "Allocate a cpad. Also opens it using functions from the kernel." - (local-vars (obj cpad-info)) - (set! obj (object-new alloction type-to-make (the-as int (-> type-to-make size)))) - (set! (-> obj number) idx) - (set! (-> obj buzz) #f) - (cpad-open obj idx) - (cpad-invalid! obj) - ) (defmethod new cpad-list ((allocation symbol) (type-to-make type)) - "Allocate a cpad-list and set up two controllers, including openeing them." - (local-vars (gp-0 cpad-list)) - (set! gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))) - (set! (-> gp-0 num-cpads) 2) - (set! (-> gp-0 cpads 0) (new 'global 'cpad-info 0)) - (set! (-> gp-0 cpads 1) (new 'global 'cpad-info 1)) - gp-0 + "Create a cpad-list for 2 controllers. It's fine to do this even if one or both controllers + aren't connected yet. " + (let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))))) + (set! (-> gp-0 num-cpads) 2) + (set! (-> gp-0 cpads 0) (new 'global 'cpad-info 0)) + (set! (-> gp-0 cpads 1) (new 'global 'cpad-info 1)) + gp-0 + ) ) (defun analog-input ((in int) (offset float) (center-val float) (max-val float) (out-range float)) - "Take an integer input and convert it to a float between -out-range and +out-range. + "Convert integer input from pad into a float between -out-range and +out-range. The offset is applied directly to the input. - The center val is the expected value for 0 (after offset) - The max val is the expected value with the stick all the way pushed - " - (local-vars - (max-magnitude float) - (magnitude float) - (offset-in float) - ) - ;; do the offset - (set! offset-in (- (the float in) offset)) - ;; figure out the absolute value of the displacement from 0. - (set! magnitude (- (fabs offset-in) center-val)) - ;; the maximum allowed magnitude - (set! max-magnitude (- max-val center-val)) - ;; if we are negative, our output range should be negative. - (when (< offset-in 0.000000) - (set! out-range (- out-range)) - ) - (cond - ((>= 0.000000 magnitude) 0.000000) ;; shouldn't happen - ((>= magnitude max-magnitude) out-range) ;; too big - (else (/ (* magnitude out-range) max-magnitude)) ;; scale! - ) + The center val is the expected value for 0, after applying offset. + The max val is the expected value with the stick pushed all the way" + (let* ((offset-in (- (the float in) offset)) ;; apply offset to in + (magnitude (- (fabs offset-in) center-val)) ;; determine our magnitude + (max-magnitude (- max-val center-val)) ;; maximum expected magnitude. + ) + ;; flip the output if negative + (if (< offset-in 0.0) + (set! out-range (- out-range)) + ) + ;; scale and return value. + (cond + ((>= 0.0 magnitude) + 0.0 + ) + ((>= magnitude max-magnitude) + out-range + ) + (else + (/ (* magnitude out-range) max-magnitude) + ) + ) + ) ) (defun cpad-set-buzz! ((pad cpad-info) (buzz-idx int) (buzz-amount int) (duration int)) @@ -188,125 +187,113 @@ (define *cpad-debug* #f) (defun service-cpads () - "Call this once a frame to read the pad, handle vibration, and process the left stick" - (local-vars - (v1-10 int) - (current-button0 uint) - (buzz-idx int) - (pad cpad-info) - (pad-idx int) - (pad-list cpad-list) - (lefty-pos float) - (leftx-pos float) - ) - - ;; iterate through cpads. - (set! pad-list *cpad-list*) - (set! pad-idx 0) - (while (< pad-idx (-> pad-list num-cpads)) - (set! pad (-> *cpad-list* cpads pad-idx)) - ;; read data from pad. - (cpad-get-data pad) - (cond - ((zero? (logand (-> pad valid) 128)) - ;; pad is valid! update buzz. - (set! buzz-idx 0) - (while (< buzz-idx 2) - (cond - ;; when buzz enbaled, in buzz time, and in game mode: - ((and (-> pad buzz) - (< (the-as int (get-current-time)) - (the-as int (-> pad buzz-time buzz-idx)) + "Read from cpads and update vibration" + ;; iterate over pads + (let ((pad-list *cpad-list*)) + (dotimes (pad-idx (-> pad-list num-cpads)) + (let ((pad (-> *cpad-list* cpads pad-idx))) + ;; read from hardware. + (cpad-get-data pad) + (cond + ((zero? (logand (-> pad valid) 128)) + (dotimes (buzz-idx 2) + (cond + ;; check if okay to buzz: + ((and (-> pad buzz) + (< (the-as int (get-current-time)) + (the-as int (-> pad buzz-time buzz-idx)) + ) + (= *master-mode* 'game) + ) + (let ((v1-10 buzz-idx)) + (cond + ((zero? v1-10) + ;; vibration motor 0 only has on/off. This pulses it to approximate + ;; an analog control + (set! (-> pad direct buzz-idx) + (logand (ash (-> pad buzz-val buzz-idx) + (- (the-as int (logand (get-integral-current-time) 7))) + ) + 1 + ) + ) + ) + ((= v1-10 1) + ;; vibration motor 1 has analog control. set the speed. + (set! (-> pad direct buzz-idx) (-> pad buzz-val buzz-idx)) + ) ) - (= *master-mode* 'game) - ) - ;; case statement? - (set! v1-10 buzz-idx) - (cond ((zero? v1-10) - ;; buzz 0, I think the small one, doesn't have analog control. - ;; I _think_ this is some clever way to pulse it at a duty cycle proportional - ;; to the desired intensity. - (set! (-> pad direct buzz-idx) - (logand (ash (-> pad buzz-val buzz-idx) - (- (the-as int (logand (get-integral-current-time) 7))) - ) - 1 - ) - ) - ) - ((= v1-10 1) - ;; buzz 1, the big motor can be controlled directly by the PS2. - (set! (-> pad direct buzz-idx) (-> pad buzz-val buzz-idx)) - ) ) - ) - (else - ;; time to stop buzzing. set buzz-val and the hardware command to 0. - (set! (-> pad buzz-val buzz-idx) 0) - (set! (-> pad direct buzz-idx) 0) - ) - ) - (+! buzz-idx 1) - ) - ;; update buttons history - (set! (-> pad button0-abs 2) (-> pad button0-abs 1)) - ;; update abs history from shadow-abs - (set! (-> pad button0-abs 1) (-> pad button0-shadow-abs 0)) - ;; update rel history - (set! (-> pad button0-rel 2) (-> pad button0-rel 1)) - (set! (-> pad button0-rel 1) (-> pad button0-rel 0)) - ;; put in new buttons - (set! current-button0 (-> pad button0)) - (set! (-> pad button0-shadow-abs 0) current-button0) - (set! (-> pad button0-abs 0) current-button0) - ;; buttons going down - (set! (-> pad button0-rel 0) - (logand (-> pad button0-abs 0) (lognot (-> pad button0-abs 1))) - ) - ;; some weird leftover from debugging. - (when *cpad-debug* - (set! (-> pad leftx) 255) - (set! (-> pad rightx) 255) - ) - (set! (-> pad stick0-speed) 1.000) - (cond - ((= (shr (-> pad status) 4) 7) ;; status that we have analog? - (set! leftx-pos (* 0.0078125 (the float (+ (-> pad leftx) -128)))) - (set! lefty-pos (* 0.0078125 (the float (- 127 (-> pad lefty))))) - ;; heading of the stick. note that y -> -x, x -> y, so it's rotated... - (set! (-> pad stick0-dir) (atan (- leftx-pos) lefty-pos)) - ;; the "speed" is just the magnitude. - (set! (-> pad stick0-speed) (fmin 1.0 (sqrtf (+ (* leftx-pos leftx-pos) (* lefty-pos lefty-pos))))) - ;; deadband the speed at 0.3? this seems kinda high. - (when (< (-> pad stick0-speed) 0.3) - (set! (-> pad stick0-speed) 0.0) - ) - ) - (else - ;; invalid analog state, set things to safe defaults. - (set! (-> pad leftx) 128) - (set! (-> pad lefty) 128) - (set! (-> pad rightx) 128) - (set! (-> pad righty) 128) - (set! (-> pad stick0-dir) 0.000000) - (set! (-> pad stick0-speed) 0.0) - ) - ) - ;; did the pad change? - (if (or (!= (-> pad button0-abs 0) (-> pad button0-abs 1)) ;; button pushed - (or (< 0.3 (-> pad stick0-speed)) ;; stick away from origin - (zero? (-> pad change-time)) ;; initially zero - ) + ) + (else + ;; not okay to buzz this motor, set to zero. + (set! (-> pad buzz-val buzz-idx) 0) + (set! (-> pad direct buzz-idx) 0) + ) + ) + ) + ;; update button history. + (set! (-> pad button0-abs 2) (-> pad button0-abs 1)) + (set! (-> pad button0-abs 1) (-> pad button0-shadow-abs 0)) + (set! (-> pad button0-rel 2) (-> pad button0-rel 1)) + (set! (-> pad button0-rel 1) (-> pad button0-rel 0)) + ;; update current button + (let ((current-button0 (-> pad button0))) + (set! (-> pad button0-shadow-abs 0) current-button0) + (set! (-> pad button0-abs 0) current-button0) + ) + ;; buttons going down + (set! (-> pad button0-rel 0) + (logand (-> pad button0-abs 0) (lognot (-> pad button0-abs 1))) + ) + ;; ?? + (when *cpad-debug* + (set! (-> pad leftx) (the-as uint 255)) + (set! (-> pad rightx) (the-as uint 255)) + ) + + ;; compute a speed and direction for stick0 + (set! (-> pad stick0-speed) 1.0) + (cond + ;; check if analog is valid? + ((= (shr (-> pad status) 4) 7) + ;; compute speed and direction, with deadband. + (let ((f30-0 (* 0.0078125 (the float (+ (-> pad leftx) -128)))) + (f28-0 (* 0.0078125 (the float (- 127 (the-as int (-> pad lefty)))))) + ) + (set! (-> pad stick0-dir) (atan (- f30-0) f28-0)) + (set! (-> pad stick0-speed) + (fmin 1.0 (sqrtf (+ (* f30-0 f30-0) (* f28-0 f28-0)))) + ) + ) + (if (< (-> pad stick0-speed) 0.3) + (set! (-> pad stick0-speed) 0.0) + ) + ) + (else + ;; analog is invalid? set to zero. + (set! (-> pad leftx) (the-as uint 128)) + (set! (-> pad lefty) (the-as uint 128)) + (set! (-> pad rightx) (the-as uint 128)) + (set! (-> pad righty) (the-as uint 128)) + (set! (-> pad stick0-dir) 0.0) + (set! (-> pad stick0-speed) 0.0) + ) + ) + ;; if the pad was changed or stick0 pushed, update the last changed time. + (if (or (!= (-> pad button0-abs 0) (-> pad button0-abs 1)) + (or (< 0.3 (-> pad stick0-speed)) (zero? (-> pad change-time))) + ) + (set! (-> pad change-time) (get-current-time)) ) - (set! (-> pad change-time) (get-current-time)) ) - ) - (else - ;; invalid pad - (cpad-invalid! pad) - ) + (else + ;; invalid bits set, controller is not connected. + (cpad-invalid! pad) + ) + ) + ) ) - (+! pad-idx 1) ) *cpad-list* ) diff --git a/goal_src/kernel/gcommon.gc b/goal_src/kernel/gcommon.gc index c6cd0172de..1c0a58f741 100644 --- a/goal_src/kernel/gcommon.gc +++ b/goal_src/kernel/gcommon.gc @@ -1172,13 +1172,13 @@ ;; these are not quite right, but it's close enough. (defmacro start-of-symbol-table () - `(rlet ((st :reg r15 :reset-here #t :type uint)) + `(rlet ((st :reg r14 :reset-here #t :type uint)) (the uint (- st 32768)) ) ) (defmacro end-of-symbol-table () - `(rlet ((st :reg r15 :reset-here #t :type uint)) + `(rlet ((st :reg r14 :reset-here #t :type uint)) (the uint (+ st 32768)) ) ) diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index 87f5a36082..8c27833235 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -96,10 +96,10 @@ class Compiler { IR_VFMath2Asm::Kind kind, Env* env); - Val* compile_asm_vf_math2_imm_u8(const goos::Object& form, - const goos::Object& rest, - IR_VFMath2Asm::Kind kind, - Env* env); + Val* compile_asm_int128_math2_imm_u8(const goos::Object& form, + const goos::Object& rest, + IR_Int128Math2Asm::Kind kind, + Env* env); Val* compile_asm_vf_math4_two_operation(const goos::Object& form, const goos::Object& rest, diff --git a/goalc/compiler/IR.cpp b/goalc/compiler/IR.cpp index 02a740fb3e..1a95b10878 100644 --- a/goalc/compiler/IR.cpp +++ b/goalc/compiler/IR.cpp @@ -1523,16 +1523,11 @@ void IR_Int128Math3Asm::do_codegen(emitter::ObjectGenerator* gen, // AsmVF2 /////////////////////// -IR_VFMath2Asm::IR_VFMath2Asm(bool use_color, - const RegVal* dst, - const RegVal* src, - Kind kind, - std::optional imm) - : IR_Asm(use_color), m_dst(dst), m_src(src), m_kind(kind), m_imm(std::move(imm)) {} +IR_VFMath2Asm::IR_VFMath2Asm(bool use_color, const RegVal* dst, const RegVal* src, Kind kind) + : IR_Asm(use_color), m_dst(dst), m_src(src), m_kind(kind) {} std::string IR_VFMath2Asm::print() { std::string function; - bool use_imm = false; switch (m_kind) { case Kind::ITOF: function = ".itof.vf"; @@ -1540,6 +1535,56 @@ std::string IR_VFMath2Asm::print() { case Kind::FTOI: function = ".ftoi.vf"; break; + default: + assert(false); + } + + return fmt::format("{}{} {}, {}", function, get_color_suffix_string(), m_dst->print(), + m_src->print()); +} + +RegAllocInstr IR_VFMath2Asm::to_rai() { + RegAllocInstr rai; + if (m_use_coloring) { + rai.write.push_back(m_dst->ireg()); + rai.read.push_back(m_src->ireg()); + } + return rai; +} + +void IR_VFMath2Asm::do_codegen(emitter::ObjectGenerator* gen, + const AllocationResult& allocs, + emitter::IR_Record irec) { + auto dst = get_reg_asm(m_dst, allocs, irec, m_use_coloring); + auto src = get_reg_asm(m_src, allocs, irec, m_use_coloring); + + switch (m_kind) { + case Kind::ITOF: + gen->add_instr(IGen::itof_vf(dst, src), irec); + break; + case Kind::FTOI: + gen->add_instr(IGen::ftoi_vf(dst, src), irec); + break; + default: + assert(false); + } +} + +/////////////////////// +// AsmInt128-2 +/////////////////////// + +IR_Int128Math2Asm::IR_Int128Math2Asm(bool use_color, + const RegVal* dst, + const RegVal* src, + Kind kind, + std::optional imm) + : IR_Asm(use_color), m_dst(dst), m_src(src), m_kind(kind), m_imm(std::move(imm)) {} + +std::string IR_Int128Math2Asm::print() { + std::string function; + bool use_imm = false; + switch (m_kind) { case Kind::PW_SLL: use_imm = true; function = ".pw.sll"; @@ -1582,7 +1627,7 @@ std::string IR_VFMath2Asm::print() { } } -RegAllocInstr IR_VFMath2Asm::to_rai() { +RegAllocInstr IR_Int128Math2Asm::to_rai() { RegAllocInstr rai; if (m_use_coloring) { rai.write.push_back(m_dst->ireg()); @@ -1591,19 +1636,13 @@ RegAllocInstr IR_VFMath2Asm::to_rai() { return rai; } -void IR_VFMath2Asm::do_codegen(emitter::ObjectGenerator* gen, - const AllocationResult& allocs, - emitter::IR_Record irec) { +void IR_Int128Math2Asm::do_codegen(emitter::ObjectGenerator* gen, + const AllocationResult& allocs, + emitter::IR_Record irec) { auto dst = get_reg_asm(m_dst, allocs, irec, m_use_coloring); auto src = get_reg_asm(m_src, allocs, irec, m_use_coloring); switch (m_kind) { - case Kind::ITOF: - gen->add_instr(IGen::itof_vf(dst, src), irec); - break; - case Kind::FTOI: - gen->add_instr(IGen::ftoi_vf(dst, src), irec); - break; case Kind::PW_SLL: // you are technically allowed to put values > 32 in here. assert(m_imm.has_value()); diff --git a/goalc/compiler/IR.h b/goalc/compiler/IR.h index 8b0e986030..cdf283afde 100644 --- a/goalc/compiler/IR.h +++ b/goalc/compiler/IR.h @@ -567,14 +567,14 @@ class IR_Int128Math3Asm : public IR_Asm { Kind m_kind; }; -class IR_VFMath2Asm : public IR_Asm { +class IR_Int128Math2Asm : public IR_Asm { public: - enum class Kind { ITOF, FTOI, PW_SLL, PW_SRL, PW_SRA, VPSRLDQ, VPSLLDQ, VPSHUFLW, VPSHUFHW }; - IR_VFMath2Asm(bool use_color, - const RegVal* dst, - const RegVal* src, - Kind kind, - std::optional = std::nullopt); + enum class Kind { PW_SLL, PW_SRL, PW_SRA, VPSRLDQ, VPSLLDQ, VPSHUFLW, VPSHUFHW }; + IR_Int128Math2Asm(bool use_color, + const RegVal* dst, + const RegVal* src, + Kind kind, + std::optional = std::nullopt); std::string print() override; RegAllocInstr to_rai() override; void do_codegen(emitter::ObjectGenerator* gen, @@ -588,6 +588,22 @@ class IR_VFMath2Asm : public IR_Asm { std::optional m_imm; }; +class IR_VFMath2Asm : public IR_Asm { + public: + enum class Kind { ITOF, FTOI }; + IR_VFMath2Asm(bool use_color, const RegVal* dst, const RegVal* src, Kind kind); + std::string print() override; + RegAllocInstr to_rai() override; + void do_codegen(emitter::ObjectGenerator* gen, + const AllocationResult& allocs, + emitter::IR_Record irec) override; + + protected: + const RegVal* m_dst = nullptr; + const RegVal* m_src = nullptr; + Kind m_kind; +}; + class IR_BlendVF : public IR_Asm { public: IR_BlendVF(bool use_color, const RegVal* dst, const RegVal* src1, const RegVal* src2, u8 mask); diff --git a/goalc/compiler/compilation/Asm.cpp b/goalc/compiler/compilation/Asm.cpp index 682723d93e..6f0f1bd111 100644 --- a/goalc/compiler/compilation/Asm.cpp +++ b/goalc/compiler/compilation/Asm.cpp @@ -546,10 +546,10 @@ Val* Compiler::compile_asm_vf_math2(const goos::Object& form, return get_none(); } -Val* Compiler::compile_asm_vf_math2_imm_u8(const goos::Object& form, - const goos::Object& rest, - IR_VFMath2Asm::Kind kind, - Env* env) { +Val* Compiler::compile_asm_int128_math2_imm_u8(const goos::Object& form, + const goos::Object& rest, + IR_Int128Math2Asm::Kind kind, + Env* env) { auto args = get_va(form, rest); va_check( form, args, {{}, {}, {}}, @@ -561,7 +561,6 @@ Val* Compiler::compile_asm_vf_math2_imm_u8(const goos::Object& form, auto dest = compile_error_guard(args.unnamed.at(0), env)->to_reg(env); auto src = compile_error_guard(args.unnamed.at(1), env)->to_reg(env); - check_vector_float_regs(form, env, {{"destination", dest}, {"source", src}}); s64 imm; if (!try_getting_constant_integer(args.unnamed.at(2), &imm, env)) { throw_compiler_error(form, "Could not evaluate {} as a compile-time integer.", @@ -584,11 +583,11 @@ Val* Compiler::compile_asm_vf_math2_imm_u8(const goos::Object& form, // If the entire destination is to be copied, we can optimize out the blend if (mask == 0b1111) { - env->emit_ir(color, dest, src, kind, imm); + env->emit_ir(color, dest, src, kind, imm); } else { auto temp_reg = env->make_vfr(dest->type()); // Perform the arithmetic operation on the two vectors into a temporary register - env->emit_ir(color, temp_reg, src, kind, imm); + env->emit_ir(color, temp_reg, src, kind, imm); // Blend the result back into the destination register using the mask env->emit_ir(color, dest, dest, temp_reg, mask); } @@ -597,15 +596,15 @@ Val* Compiler::compile_asm_vf_math2_imm_u8(const goos::Object& form, } Val* Compiler::compile_asm_pw_sll(const goos::Object& form, const goos::Object& rest, Env* env) { - return compile_asm_vf_math2_imm_u8(form, rest, IR_VFMath2Asm::Kind::PW_SLL, env); + return compile_asm_int128_math2_imm_u8(form, rest, IR_Int128Math2Asm::Kind::PW_SLL, env); } Val* Compiler::compile_asm_pw_srl(const goos::Object& form, const goos::Object& rest, Env* env) { - return compile_asm_vf_math2_imm_u8(form, rest, IR_VFMath2Asm::Kind::PW_SRL, env); + return compile_asm_int128_math2_imm_u8(form, rest, IR_Int128Math2Asm::Kind::PW_SRL, env); } Val* Compiler::compile_asm_pw_sra(const goos::Object& form, const goos::Object& rest, Env* env) { - return compile_asm_vf_math2_imm_u8(form, rest, IR_VFMath2Asm::Kind::PW_SRA, env); + return compile_asm_int128_math2_imm_u8(form, rest, IR_Int128Math2Asm::Kind::PW_SRA, env); } Val* Compiler::compile_asm_pextlw(const goos::Object& form, const goos::Object& rest, Env* env) { @@ -641,12 +640,12 @@ Val* Compiler::compile_asm_ppach(const goos::Object& form, const goos::Object& r throw_compiler_error(form, "Cannot set destination"); } - env->emit_ir(true, temp, src1, IR_VFMath2Asm::Kind::VPSHUFLW, 0x88); - env->emit_ir(true, dest, src2, IR_VFMath2Asm::Kind::VPSHUFLW, 0x88); - env->emit_ir(true, temp, temp, IR_VFMath2Asm::Kind::VPSHUFHW, 0x88); - env->emit_ir(true, dest, dest, IR_VFMath2Asm::Kind::VPSHUFHW, 0x88); - env->emit_ir(true, temp, temp, IR_VFMath2Asm::Kind::VPSRLDQ, 4); - env->emit_ir(true, dest, dest, IR_VFMath2Asm::Kind::VPSRLDQ, 4); + env->emit_ir(true, temp, src1, IR_Int128Math2Asm::Kind::VPSHUFLW, 0x88); + env->emit_ir(true, dest, src2, IR_Int128Math2Asm::Kind::VPSHUFLW, 0x88); + env->emit_ir(true, temp, temp, IR_Int128Math2Asm::Kind::VPSHUFHW, 0x88); + env->emit_ir(true, dest, dest, IR_Int128Math2Asm::Kind::VPSHUFHW, 0x88); + env->emit_ir(true, temp, temp, IR_Int128Math2Asm::Kind::VPSRLDQ, 4); + env->emit_ir(true, dest, dest, IR_Int128Math2Asm::Kind::VPSRLDQ, 4); // is actually a VPUNPCKLQDQ with srcs swapped. env->emit_ir(true, dest, temp, dest, IR_Int128Math3Asm::Kind::PCPYLD); diff --git a/test/decompiler/FormRegressionTest.cpp b/test/decompiler/FormRegressionTest.cpp index 2c9202e877..f03e934e62 100644 --- a/test/decompiler/FormRegressionTest.cpp +++ b/test/decompiler/FormRegressionTest.cpp @@ -161,7 +161,7 @@ std::unique_ptr FormRegressionTest::make_function( // convert instruction to atomic ops DecompWarnings warnings; - auto ops = convert_function_to_atomic_ops(test->func, program.labels, warnings); + auto ops = convert_function_to_atomic_ops(test->func, program.labels, warnings, false); test->func.ir2.atomic_ops = std::make_shared(std::move(ops)); test->func.ir2.atomic_ops_succeeded = true; test->func.ir2.env.set_end_var(test->func.ir2.atomic_ops->end_op().return_var()); diff --git a/test/decompiler/reference/all_forward_declarations.gc b/test/decompiler/reference/all_forward_declarations.gc index b7442b855a..2a4bb1d6a1 100644 --- a/test/decompiler/reference/all_forward_declarations.gc +++ b/test/decompiler/reference/all_forward_declarations.gc @@ -63,7 +63,17 @@ (define-extern *listener-process* process) (define-extern *active-pool* process-tree) (define-extern reset-and-call (function thread function object)) -(define-extern ash (function int int int)) +(defun ash ((value int) (shift-amount int)) + "Arithmetic shift value by shift-amount. + A positive shift-amount will shift to the left and a negative will shift to the right. + " + ;; OpenGOAL does not support ash in the compiler, so we implement it here as an inline function. + (declare (inline)) + (if (> shift-amount 0) + (shl value shift-amount) + (sar value (- shift-amount)) + ) + ) (define-extern inspect-process-tree (function process-tree int int symbol process-tree)) (define-extern set-to-run-bootstrap (function none)) (define-extern dead-state state) @@ -87,6 +97,11 @@ '(none) ) +(defmacro gpr->fpr (in) + in) + +(define-extern get-current-time (function uint)) +(define-extern get-integral-current-time (function uint)) ;; math (define-extern fabs (function float float)) @@ -199,6 +214,75 @@ (end 7) ;; next, but ends. ) +(defenum gs-psm + :bitfield #f + :type uint8 + (ct32 0) + (ct24 1) + (ct16 2) + (ct16s 10) + (mt8 19) + (mt4 20) + (mt8h 27) + (mt4hl 36) + (mt4hh 44) + (mz32 48) + (mz24 49) + (mz16 50) + (mz16s 58) + ) +(defenum gs-prim-type + :type uint8 + (point 0) + (line 1) + (line-strip 2) + (tri 3) + (tri-strip 4) + (tri-fan 5) + (sprite 6) + ) + +(defenum gs-reg-id + :bitfield #f + :type uint8 + (prim 0) + (rgbaq 1) + (st 2) + (uv 3) + (xyzf2 4) + (xyz2 5) + (tex0-1 6) + (tex0-2 7) + (clamp-1 8) + (clamp-2 9) + (fog 10) + (xyzf3 12) + (xyz3 13) + (a+d 14) + (nop 15) + ) + +(deftype gif-tag-regs (uint64) + ((regs0 gs-reg-id :offset 0 :size 4) + (regs1 gs-reg-id :offset 4 :size 4) + (regs2 gs-reg-id :offset 8 :size 4) + (regs3 gs-reg-id :offset 12 :size 4) + (regs4 gs-reg-id :offset 16 :size 4) + (regs5 gs-reg-id :offset 20 :size 4) + (regs6 gs-reg-id :offset 24 :size 4) + (regs7 gs-reg-id :offset 28 :size 4) + (regs8 gs-reg-id :offset 32 :size 4) + (regs9 gs-reg-id :offset 36 :size 4) + (regs10 gs-reg-id :offset 40 :size 4) + (regs11 gs-reg-id :offset 44 :size 4) + (regs12 gs-reg-id :offset 48 :size 4) + (regs13 gs-reg-id :offset 52 :size 4) + (regs14 gs-reg-id :offset 56 :size 4) + (regs15 gs-reg-id :offset 60 :size 4) + ) + ) + + ;; display-h (deftype display-env (structure) ((pmode uint64 :offset-assert 0) diff --git a/test/decompiler/reference/dma-bucket_REF.gc b/test/decompiler/reference/dma-bucket_REF.gc index 5e34a6cb4f..899981f56c 100644 --- a/test/decompiler/reference/dma-bucket_REF.gc +++ b/test/decompiler/reference/dma-bucket_REF.gc @@ -9,7 +9,7 @@ (set! (-> current-bucket tag) (new 'static 'dma-tag - :id #x2 + :id (dma-tag-id next) :addr (the-as int (&+ (the-as pointer current-bucket) 16)) ) ) diff --git a/test/decompiler/reference/dma-buffer_REF.gc b/test/decompiler/reference/dma-buffer_REF.gc index 42bdf31831..f946417d7c 100644 --- a/test/decompiler/reference/dma-buffer_REF.gc +++ b/test/decompiler/reference/dma-buffer_REF.gc @@ -149,7 +149,11 @@ ) (set! (-> buf-ptr dma) - (new 'static 'dma-tag :id #x3 :addr (the-as int func-ptr) :qwc qwc-now) + (new 'static 'dma-tag + :id (dma-tag-id ref) + :addr (the-as int func-ptr) + :qwc qwc-now + ) ) (set! (-> buf-ptr vif0) @@ -157,7 +161,11 @@ ) (set! (-> buf-ptr vif1) - (new 'static 'vif-tag :cmd #x4a :num (shl qwc-now 1) :imm origin) + (new 'static 'vif-tag + :cmd (vif-cmd mpg) + :num (shl qwc-now 1) + :imm origin + ) ) (set! (-> dma-buf-2 base) (&+ (the-as pointer buf-ptr) 16)) ) diff --git a/test/decompiler/reference/dma-disasm_REF.gc b/test/decompiler/reference/dma-disasm_REF.gc index f43773879e..363a5f34eb 100644 --- a/test/decompiler/reference/dma-disasm_REF.gc +++ b/test/decompiler/reference/dma-disasm_REF.gc @@ -725,8 +725,8 @@ (empty-form) (cond ((or - (zero? (+ (the-as uint (-> current-tag id)) (the-as uint -3))) - (zero? (+ (the-as uint (-> current-tag id)) (the-as uint -4))) + (= (-> current-tag id) (dma-tag-id ref)) + (= (-> current-tag id) (dma-tag-id refs)) (zero? (-> current-tag id)) ) (set! addr (-> current-tag addr)) diff --git a/test/decompiler/reference/gs_REF.gc b/test/decompiler/reference/gs_REF.gc new file mode 100644 index 0000000000..8139b45b48 --- /dev/null +++ b/test/decompiler/reference/gs_REF.gc @@ -0,0 +1,1171 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition of type gs-pmode +(deftype gs-pmode (uint64) + ((en1 uint8 :offset 0 :size 1) + (en2 uint8 :offset 1 :size 1) + (crtmd uint8 :offset 2 :size 3) + (mmod uint8 :offset 5 :size 1) + (amod uint8 :offset 6 :size 1) + (slbg uint8 :offset 7 :size 1) + (alp uint8 :offset 8 :size 8) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-smode2 +(deftype gs-smode2 (uint64) + ((int uint8 :offset 0 :size 1) + (ffmd uint8 :offset 1 :size 1) + (dpms uint8 :offset 2 :size 2) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition for function psm-size +(defun psm-size ((arg0 gs-psm)) + (cond + ((= arg0 (gs-psm mt8)) + 64 + ) + ((= arg0 (gs-psm mt4)) + 32 + ) + (else + (if + (or + (= arg0 (gs-psm ct16)) + (= arg0 (gs-psm ct16s)) + (= arg0 (gs-psm mz16)) + (= arg0 (gs-psm mz16s)) + ) + 128 + 256 + ) + ) + ) + ) + +;; definition for function psm-page-height +(defun psm-page-height ((arg0 gs-psm)) + (cond + ((= arg0 (gs-psm mt8)) + 64 + ) + ((= arg0 (gs-psm mt4)) + 128 + ) + (else + (if + (or + (= arg0 (gs-psm ct16)) + (= arg0 (gs-psm ct16s)) + (= arg0 (gs-psm mz16)) + (= arg0 (gs-psm mz16s)) + ) + 64 + 32 + ) + ) + ) + ) + +;; definition for function psm->string +(defun psm->string ((arg0 gs-psm)) + (let ((v1-0 arg0)) + (cond + ((= v1-0 (gs-psm mz16s)) + "mz16s" + ) + ((= v1-0 (gs-psm mz16)) + "mz16" + ) + ((= v1-0 (gs-psm mz24)) + "mz24" + ) + ((= v1-0 (gs-psm mz32)) + "mz32" + ) + ((= v1-0 (gs-psm mt4hh)) + "mt4hh" + ) + ((= v1-0 (gs-psm mt4hl)) + "mt4hl" + ) + ((= v1-0 (gs-psm mt8h)) + "mt8h" + ) + ((= v1-0 (gs-psm mt4)) + "mt4" + ) + ((= v1-0 (gs-psm mt8)) + "mt8" + ) + ((= v1-0 (gs-psm ct16s)) + "ct16s" + ) + ((= v1-0 (gs-psm ct16)) + "ct16" + ) + ((= v1-0 (gs-psm ct24)) + "ct24" + ) + ((zero? v1-0) + "ct32" + ) + (else + "*unknown*" + ) + ) + ) + ) + +;; definition of type gs-display-fb +(deftype gs-display-fb (uint64) + ((fbp uint16 :offset 0 :size 9) + (fbw uint8 :offset 9 :size 6) + (psm gs-psm :offset 15 :size 5) + (dbx uint16 :offset 32 :size 11) + (dby uint16 :offset 43 :size 11) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-display +(deftype gs-display (uint64) + ((dx uint16 :offset 0 :size 12) + (dy uint16 :offset 12 :size 11) + (magh uint8 :offset 23 :size 4) + (magv uint8 :offset 27 :size 2) + (dw uint16 :offset 32 :size 12) + (dh uint16 :offset 44 :size 11) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-bgcolor +(deftype gs-bgcolor (uint64) + ((r uint8 :offset 0 :size 8) + (g uint8 :offset 8 :size 8) + (b uint8 :offset 16 :size 8) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-csr +(deftype gs-csr (uint64) + ((signal uint8 :offset 0 :size 1) + (finish uint8 :offset 1 :size 1) + (hsint uint8 :offset 2 :size 1) + (vsint uint8 :offset 3 :size 1) + (edwint uint8 :offset 4 :size 1) + (flush uint8 :offset 8 :size 1) + (reset uint8 :offset 9 :size 1) + (nfield uint8 :offset 12 :size 1) + (field uint8 :offset 13 :size 1) + (fifo uint8 :offset 14 :size 2) + (rev uint8 :offset 16 :size 8) + (id uint8 :offset 24 :size 8) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-bank +(deftype gs-bank (structure) + ((pmode gs-pmode :offset-assert 0) + (smode2 gs-smode2 :offset 32) + (dspfb1 gs-display-fb :offset 112) + (display1 gs-display :offset 128) + (dspfb2 gs-display-fb :offset 144) + (display2 gs-display :offset 160) + (extbuf uint64 :offset 176) + (extdata uint64 :offset 192) + (extwrite uint64 :offset 208) + (bgcolor gs-bgcolor :offset 224) + (csr gs-csr :offset 4096) + (imr uint64 :offset 4112) + (busdir uint64 :offset 4160) + ) + :method-count-assert 9 + :size-assert #x1048 + :flag-assert #x900001048 + ) + +;; definition for method 3 of type gs-bank +(defmethod inspect gs-bank ((obj gs-bank)) + (format #t "[~8x] ~A~%" obj 'gs-bank) + (format #t "~Tpmode: #x~X~%" (-> obj pmode)) + (format #t "~Tsmode2: #x~X~%" (-> obj smode2)) + (format #t "~Tdspfb1: #x~X~%" (-> obj dspfb1)) + (format #t "~Tdisplay1: #x~X~%" (-> obj display1)) + (format #t "~Tdspfb2: #x~X~%" (-> obj dspfb2)) + (format #t "~Tdisplay2: #x~X~%" (-> obj display2)) + (format #t "~Textbuf: #x~X~%" (-> obj extbuf)) + (format #t "~Textdata: #x~X~%" (-> obj extdata)) + (format #t "~Textwrite: #x~X~%" (-> obj extwrite)) + (format #t "~Tbgcolor: #x~X~%" (-> obj bgcolor)) + (format #t "~Tcsr: #x~X~%" (-> obj csr)) + (format #t "~Timr: #x~X~%" (-> obj imr)) + (format #t "~Tbusdir: #x~X~%" (-> obj busdir)) + obj + ) + +;; definition of type gs-frame +(deftype gs-frame (uint64) + ((fbp uint16 :offset 0 :size 9) + (fbw uint8 :offset 16 :size 6) + (psm uint8 :offset 24 :size 6) + (fbmsk uint32 :offset 32 :size 32) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-zbuf +(deftype gs-zbuf (uint64) + ((zbp uint16 :offset 0 :size 9) + (psm uint8 :offset 24 :size 4) + (zmsk uint8 :offset 32 :size 1) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-xy-offset +(deftype gs-xy-offset (uint64) + ((ofx uint16 :offset 0 :size 16) + (ofy uint16 :offset 32 :size 16) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-scissor +(deftype gs-scissor (uint64) + ((scax0 uint16 :offset 0 :size 11) + (scax1 uint16 :offset 16 :size 11) + (scay0 uint16 :offset 32 :size 11) + (scay1 uint16 :offset 48 :size 11) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-prmode-cont +(deftype gs-prmode-cont (uint64) + ((ac uint8 :offset 0 :size 1) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-color-clamp +(deftype gs-color-clamp (uint64) + ((clamp uint8 :offset 0 :size 1) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-dthe +(deftype gs-dthe (uint64) + ((dthe uint8 :offset 0 :size 1) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-test +(deftype gs-test (uint64) + ((ate uint8 :offset 0 :size 1) + (atst uint8 :offset 1 :size 3) + (aref uint8 :offset 4 :size 8) + (afail uint8 :offset 12 :size 2) + (date uint8 :offset 14 :size 1) + (datm uint8 :offset 15 :size 1) + (zte uint8 :offset 16 :size 1) + (ztst uint8 :offset 17 :size 2) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-prim +(deftype gs-prim (uint64) + ((prim gs-prim-type :offset 0 :size 3) + (iip uint8 :offset 3 :size 1) + (tme uint8 :offset 4 :size 1) + (fge uint8 :offset 5 :size 1) + (abe uint8 :offset 6 :size 1) + (aa1 uint8 :offset 7 :size 1) + (fst uint8 :offset 8 :size 1) + (ctxt uint8 :offset 9 :size 1) + (fix uint8 :offset 10 :size 1) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-rgbaq +(deftype gs-rgbaq (uint64) + ((r uint8 :offset 0 :size 8) + (g uint8 :offset 8 :size 8) + (b uint8 :offset 16 :size 8) + (a uint8 :offset 24 :size 8) + (q float :offset 32 :size 32) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-xyz +(deftype gs-xyz (uint64) + ((x uint16 :offset 0 :size 16) + (y uint16 :offset 16 :size 16) + (z uint32 :offset 32 :size 32) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-uv +(deftype gs-uv (uint64) + ((u uint16 :offset 0 :size 14) + (v uint16 :offset 16 :size 14) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-st +(deftype gs-st (uint64) + ((s float :offset 0 :size 32) + (t float :offset 32 :size 32) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-xyzf +(deftype gs-xyzf (uint64) + ((x uint16 :offset 0 :size 16) + (y uint16 :offset 16 :size 16) + (z uint32 :offset 32 :size 24) + (f uint8 :offset 56 :size 8) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-trxpos +(deftype gs-trxpos (uint64) + ((ssax uint16 :offset 0 :size 11) + (ssay uint16 :offset 16 :size 11) + (dsax uint16 :offset 32 :size 11) + (dsay uint16 :offset 48 :size 11) + (dir uint8 :offset 59 :size 2) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-trxreg +(deftype gs-trxreg (uint64) + ((rrw uint16 :offset 0 :size 12) + (rrh uint16 :offset 32 :size 12) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-trxdir +(deftype gs-trxdir (uint64) + ((xdir uint8 :offset 0 :size 2) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-bitbltbuf +(deftype gs-bitbltbuf (uint64) + ((sbp uint16 :offset 0 :size 14) + (sbw uint8 :offset 16 :size 6) + (spsm uint8 :offset 24 :size 6) + (dbp uint16 :offset 32 :size 14) + (dbw uint8 :offset 48 :size 6) + (dpsm uint8 :offset 56 :size 6) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-tex0 +(deftype gs-tex0 (uint64) + ((tbp0 uint16 :offset 0 :size 14) + (tbw uint8 :offset 14 :size 6) + (psm uint8 :offset 20 :size 6) + (tw uint8 :offset 26 :size 4) + (th uint8 :offset 30 :size 4) + (tcc uint8 :offset 34 :size 1) + (tfx uint8 :offset 35 :size 2) + (cbp uint16 :offset 37 :size 14) + (cpsm uint8 :offset 51 :size 4) + (csm uint8 :offset 55 :size 1) + (csa uint8 :offset 56 :size 5) + (cld uint8 :offset 61 :size 3) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-tex1 +(deftype gs-tex1 (uint64) + ((lcm uint8 :offset 0 :size 1) + (mxl uint8 :offset 2 :size 3) + (mmag uint8 :offset 5 :size 1) + (mmin uint8 :offset 6 :size 3) + (mtba uint8 :offset 9 :size 1) + (l uint8 :offset 19 :size 2) + (k int16 :offset 32 :size 12) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-texa +(deftype gs-texa (uint64) + ((ta0 uint8 :offset 0 :size 8) + (aem uint8 :offset 15 :size 1) + (ta1 uint8 :offset 32 :size 8) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-texclut +(deftype gs-texclut (uint64) + ((cbw uint8 :offset 0 :size 6) + (cou uint8 :offset 6 :size 6) + (cov uint16 :offset 12 :size 10) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-miptbp +(deftype gs-miptbp (uint64) + ((tbp1 uint16 :offset 0 :size 14) + (tbw1 uint8 :offset 14 :size 6) + (tbp2 uint16 :offset 20 :size 14) + (tbw2 uint8 :offset 34 :size 6) + (tbp3 uint16 :offset 40 :size 14) + (tbw3 uint8 :offset 54 :size 6) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-alpha +(deftype gs-alpha (uint64) + ((a uint8 :offset 0 :size 2) + (b uint8 :offset 2 :size 2) + (c uint8 :offset 4 :size 2) + (d uint8 :offset 6 :size 2) + (fix uint8 :offset 32 :size 8) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition for method 3 of type gs-alpha +(defmethod inspect gs-alpha ((obj gs-alpha)) + (format #t "[~8x] ~A~%" obj 'gs-alpha) + (format #t "~Ta: ~D~%" (-> obj a)) + (format #t "~Tb: ~D~%" (-> obj b)) + (format #t "~Tc: ~D~%" (-> obj c)) + (format #t "~Td: ~D~%" (-> obj d)) + (format #t "~Tfix: ~D~%" (-> obj fix)) + obj + ) + +;; definition of type gs-clamp +(deftype gs-clamp (uint64) + ((wms uint8 :offset 0 :size 2) + (wmt uint8 :offset 2 :size 2) + (minu uint16 :offset 4 :size 10) + (maxu uint16 :offset 14 :size 10) + (minv uint16 :offset 24 :size 10) + (maxv uint16 :offset 34 :size 10) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gs-fog +(deftype gs-fog (uint64) + ((f uint8 :offset 56 :size 8) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition for method 3 of type gs-fog +(defmethod inspect gs-fog ((obj gs-fog)) + (format #t "[~8x] ~A~%" obj 'gs-fog) + (format #t "~Tf: ~D~%" (-> obj f)) + obj + ) + +;; definition of type gs-fogcol +(deftype gs-fogcol (uint64) + ((fcr uint8 :offset 0 :size 8) + (fcg uint8 :offset 8 :size 8) + (fcb uint8 :offset 16 :size 8) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition for method 3 of type gs-fogcol +(defmethod inspect gs-fogcol ((obj gs-fogcol)) + (format #t "[~8x] ~A~%" obj 'gs-fogcol) + (format #t "~Tr: ~D~%" (-> obj fcr)) + (format #t "~Tg: ~D~%" (-> obj fcg)) + (format #t "~Tb: ~D~%" (-> obj fcb)) + obj + ) + +;; definition of type gif-ctrl +(deftype gif-ctrl (uint32) + ((rst uint8 :offset 0 :size 1) + (pse uint8 :offset 3 :size 1) + ) + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + +;; definition of type gif-mode +(deftype gif-mode (uint32) + ((m3r uint8 :offset 0 :size 1) + (imt uint8 :offset 2 :size 1) + ) + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + +;; definition of type gif-stat +(deftype gif-stat (uint32) + ((m3r uint8 :offset 0 :size 1) + (m3p uint8 :offset 1 :size 1) + (imt uint8 :offset 2 :size 1) + (pse uint8 :offset 3 :size 1) + (ip3 uint8 :offset 5 :size 1) + (p3q uint8 :offset 6 :size 1) + (p2q uint8 :offset 7 :size 1) + (p1q uint8 :offset 8 :size 1) + (oph uint8 :offset 9 :size 1) + (apath uint8 :offset 10 :size 2) + (dir uint8 :offset 12 :size 1) + (fqc uint8 :offset 24 :size 5) + ) + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + +;; definition of type gif-cnt +(deftype gif-cnt (uint32) + ((loopcnt uint16 :offset 0 :size 15) + (regcnt uint8 :offset 16 :size 4) + (vuaddr uint16 :offset 20 :size 10) + ) + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + +;; definition of type gif-p3cnt +(deftype gif-p3cnt (uint32) + ((p3cnt uint16 :offset 0 :size 15) + ) + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + +;; definition of type gif-p3tag +(deftype gif-p3tag (uint32) + ((loopcnt uint16 :offset 0 :size 15) + (eop uint8 :offset 15 :size 1) + ) + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + +;; definition of type gif-bank +(deftype gif-bank (structure) + ((ctrl gif-ctrl :offset 0) + (mode gif-mode :offset 16) + (stat gif-stat :offset 32) + (tag0 uint32 :offset 64) + (tag1 uint32 :offset 80) + (tag2 uint32 :offset 96) + (tag3 uint32 :offset 112) + (cnt gif-cnt :offset 128) + (p3cnt gif-p3cnt :offset 144) + (p3tag gif-p3tag :offset 160) + ) + :method-count-assert 9 + :size-assert #xa4 + :flag-assert #x9000000a4 + ) + +;; definition for method 3 of type gif-bank +(defmethod inspect gif-bank ((obj gif-bank)) + (format #t "[~8x] ~A~%" obj 'gif-bank) + (format #t "~Tctrl: #x~X~%" (-> obj ctrl)) + (format #t "~Tmode: #x~X~%" (-> obj mode)) + (format #t "~Tstat: #x~X~%" (-> obj stat)) + (format #t "~Ttag0: #x~X~%" (-> obj tag0)) + (format #t "~Ttag1: #x~X~%" (-> obj tag1)) + (format #t "~Ttag2: #x~X~%" (-> obj tag2)) + (format #t "~Ttag3: #x~X~%" (-> obj tag3)) + (format #t "~Tcnt: #x~X~%" (-> obj cnt)) + (format #t "~Tp3cnt: #x~X~%" (-> obj p3cnt)) + (format #t "~Tp3tag: #x~X~%" (-> obj p3tag)) + obj + ) + +;; definition of type gif-tag-prim +(deftype gif-tag-prim (uint32) + () + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + +;; definition of type gif-tag-count +(deftype gif-tag-count (uint32) + () + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + +;; definition of type gif-tag64 +(deftype gif-tag64 (uint64) + ((nloop uint16 :offset 0 :size 15) + (eop uint8 :offset 15 :size 1) + (id uint16 :offset 32 :size 14) + (pre uint8 :offset 46 :size 1) + (prim uint16 :offset 47 :size 11) + (flg uint8 :offset 58 :size 2) + (nreg uint8 :offset 60 :size 4) + ) + :method-count-assert 9 + :size-assert #x8 + :flag-assert #x900000008 + ) + +;; definition of type gif-tag +(deftype gif-tag (uint128) + ((nloop uint16 :offset 0 :size 15) + (eop uint8 :offset 15 :size 1) + (id uint16 :offset 32 :size 14) + (pre uint8 :offset 46 :size 1) + (prim uint16 :offset 47 :size 11) + (flg uint8 :offset 58 :size 2) + (nreg uint8 :offset 60 :size 4) + (regs0 uint8 :offset 64 :size 4) + (regs1 uint8 :offset 68 :size 4) + (regs2 uint8 :offset 72 :size 4) + (regs3 uint8 :offset 76 :size 4) + (regs4 uint8 :offset 80 :size 4) + (regs5 uint8 :offset 84 :size 4) + (regs6 uint8 :offset 88 :size 4) + (regs7 uint8 :offset 92 :size 4) + (regs8 uint8 :offset 96 :size 4) + (regs9 uint8 :offset 100 :size 4) + (regs10 uint8 :offset 104 :size 4) + (regs11 uint8 :offset 108 :size 4) + (regs12 uint8 :offset 112 :size 4) + (regs13 uint8 :offset 116 :size 4) + (regs14 uint8 :offset 120 :size 4) + (regs15 uint8 :offset 124 :size 4) + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + ) + +;; definition of type gs-gif-tag +(deftype gs-gif-tag (structure) + ((qword uint128 :offset-assert 0) + (tag gif-tag64 :offset 0) + (regs gif-tag-regs :offset 8) + (dword uint64 2 :offset 0) + (word uint32 4 :offset 0) + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + ) + +;; definition for method 3 of type gs-gif-tag +(defmethod inspect gs-gif-tag ((obj gs-gif-tag)) + (format #t "[~8x] ~A~%" obj 'gs-gif-tag) + (format #t "~Tqword: #~%" (&-> obj qword)) + (format #t "~Tdword[2] @ #x~X~%" (&-> obj qword)) + (format #t "~Tword[4] @ #x~X~%" (&-> obj qword)) + (format #t "~Ttag: ~D~%" (-> obj tag)) + (format #t "~Tregs: ~D~%" (-> obj regs)) + obj + ) + +;; definition for method 3 of type gif-tag +;; INFO: Return type mismatch object vs gif-tag. +;; WARN: Unsupported inline assembly instruction kind - [por gp, a0, r0] +;; WARN: Unsupported inline assembly instruction kind - [por a2, gp, r0] +;; WARN: Unsupported inline assembly instruction kind - [srl a2, v1, 28] +(defmethod inspect gif-tag ((obj gif-tag)) + (local-vars + (r0-0 none) + (v1-6 uint128) + (v1-8 uint128) + (v1-10 uint128) + (v1-12 uint128) + (v1-14 uint128) + (v1-16 uint128) + (v1-18 uint128) + (v1-20 uint128) + (v1-21 uint128) + (v1-23 uint128) + (v1-25 uint128) + (v1-27 uint128) + (v1-29 uint128) + (v1-31 uint128) + (v1-33 uint128) + (v1-35 uint128) + (a2-0 uint128) + (a2-15 uint128) + (gp-0 uint128) + ) + (.por gp-0 obj r0-0) + (let ((t9-0 format) + (a0-1 #t) + (a1-0 "[~8x] gif-tag~%") + ) + (.por a2-0 gp-0 r0-0) + (t9-0 a0-1 a1-0 a2-0) + ) + (format #t "~Tnloop: ~4d~%" (shr (shl (the-as int gp-0) 49) 49)) + (format #t "~Teop : ~4d~%" (shr (shl (the-as int gp-0) 48) 63)) + (format #t "~Tid : ~4d~%" (shr (shl (the-as int gp-0) 18) 50)) + (format #t "~Tpre : ~4d~%" (shr (shl (the-as int gp-0) 17) 63)) + (format #t "~Tprim : ~4d~%" (shr (shl (the-as int gp-0) 6) 53)) + (format #t "~Tflg : ~4d~%" (shr (shl (the-as int gp-0) 4) 62)) + (format #t "~Tnreg : ~4d~%" (shr (the-as int gp-0) 60)) + (let ((t9-8 format) + (a0-9 #t) + (a1-8 "~Tregs0 : ~4d~%") + ) + (.pcpyud v1-6 gp-0 r0-0) + (t9-8 a0-9 a1-8 (shr (shl (the-as int v1-6) 60) 60)) + ) + (let ((t9-9 format) + (a0-10 #t) + (a1-9 "~Tregs1 : ~4d~%") + ) + (.pcpyud v1-8 gp-0 r0-0) + (t9-9 a0-10 a1-9 (shr (shl (the-as int v1-8) 56) 60)) + ) + (let ((t9-10 format) + (a0-11 #t) + (a1-10 "~Tregs2 : ~4d~%") + ) + (.pcpyud v1-10 gp-0 r0-0) + (t9-10 a0-11 a1-10 (shr (shl (the-as int v1-10) 52) 60)) + ) + (let ((t9-11 format) + (a0-12 #t) + (a1-11 "~Tregs3 : ~4d~%") + ) + (.pcpyud v1-12 gp-0 r0-0) + (t9-11 a0-12 a1-11 (shr (shl (the-as int v1-12) 48) 60)) + ) + (let ((t9-12 format) + (a0-13 #t) + (a1-12 "~Tregs4 : ~4d~%") + ) + (.pcpyud v1-14 gp-0 r0-0) + (t9-12 a0-13 a1-12 (shr (shl (the-as int v1-14) 44) 60)) + ) + (let ((t9-13 format) + (a0-14 #t) + (a1-13 "~Tregs5 : ~4d~%") + ) + (.pcpyud v1-16 gp-0 r0-0) + (t9-13 a0-14 a1-13 (shr (shl (the-as int v1-16) 40) 60)) + ) + (let ((t9-14 format) + (a0-15 #t) + (a1-14 "~Tregs6 : ~4d~%") + ) + (.pcpyud v1-18 gp-0 r0-0) + (t9-14 a0-15 a1-14 (shr (shl (the-as int v1-18) 36) 60)) + ) + (let ((t9-15 format) + (a0-16 #t) + (a1-15 "~Tregs7 : ~4d~%") + ) + (.pcpyud v1-20 gp-0 r0-0) + (.srl a2-15 v1-20 28) + (t9-15 a0-16 a1-15 a2-15) + ) + (let ((t9-16 format) + (a0-17 #t) + (a1-16 "~Tregs8 : ~4d~%") + ) + (.pcpyud v1-21 gp-0 r0-0) + (t9-16 a0-17 a1-16 (shr (shl (the-as int v1-21) 28) 60)) + ) + (let ((t9-17 format) + (a0-18 #t) + (a1-17 "~Tregs9 : ~4d~%") + ) + (.pcpyud v1-23 gp-0 r0-0) + (t9-17 a0-18 a1-17 (shr (shl (the-as int v1-23) 24) 60)) + ) + (let ((t9-18 format) + (a0-19 #t) + (a1-18 "~Tregs10: ~4d~%") + ) + (.pcpyud v1-25 gp-0 r0-0) + (t9-18 a0-19 a1-18 (shr (shl (the-as int v1-25) 20) 60)) + ) + (let ((t9-19 format) + (a0-20 #t) + (a1-19 "~Tregs11: ~4d~%") + ) + (.pcpyud v1-27 gp-0 r0-0) + (t9-19 a0-20 a1-19 (shr (shl (the-as int v1-27) 16) 60)) + ) + (let ((t9-20 format) + (a0-21 #t) + (a1-20 "~Tregs12: ~4d~%") + ) + (.pcpyud v1-29 gp-0 r0-0) + (t9-20 a0-21 a1-20 (shr (shl (the-as int v1-29) 12) 60)) + ) + (let ((t9-21 format) + (a0-22 #t) + (a1-21 "~Tregs13: ~4d~%") + ) + (.pcpyud v1-31 gp-0 r0-0) + (t9-21 a0-22 a1-21 (shr (shl (the-as int v1-31) 8) 60)) + ) + (let ((t9-22 format) + (a0-23 #t) + (a1-22 "~Tregs14: ~4d~%") + ) + (.pcpyud v1-33 gp-0 r0-0) + (t9-22 a0-23 a1-22 (shr (shl (the-as int v1-33) 4) 60)) + ) + (let ((t9-23 format) + (a0-24 #t) + (a1-23 "~Tregs15: ~4d~%") + ) + (.pcpyud v1-35 gp-0 r0-0) + (the-as gif-tag (t9-23 a0-24 a1-23 (shr (the-as int v1-35) 60))) + ) + ) + +;; definition for symbol *fog-color*, type int +(define *fog-color* #xc88029) + +;; definition for symbol *default-regs-buffer*, type dma-buffer +(define *default-regs-buffer* (new 'global 'dma-buffer 1024)) + +;; definition for function default-buffer-init +;; INFO: Return type mismatch pointer vs none. +(defun default-buffer-init ((buff dma-buffer)) + (let ((buff-ptr buff)) + (set! (-> buff-ptr base) (-> buff-ptr data)) + (set! + (-> buff-ptr end) + (&-> buff-ptr data-buffer (-> buff-ptr allocated-length)) + ) + ) + (let* ((buff-ptr2 buff) + (packet (the-as dma-gif-packet (-> buff-ptr2 base))) + ) + (set! + (-> packet dma-vif dma) + (new 'static 'dma-tag :qwc #xa :id (dma-tag-id cnt)) + ) + (set! + (-> packet dma-vif vif0) + (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1) + ) + (set! + (-> packet dma-vif vif1) + (new 'static 'vif-tag :imm #xa :cmd (vif-cmd direct) :msk #x1) + ) + (set! (-> buff-ptr2 base) (&+ (the-as pointer packet) 16)) + ) + (let* ((buff-ptr5 buff) + (gif-tag (the-as gs-gif-tag (-> buff-ptr5 base))) + ) + (set! + (-> gif-tag tag) + (the-as gif-tag64 (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x9)) + ) + (set! + (-> gif-tag regs) + (new 'static 'gif-tag-regs + :regs0 (gs-reg-id a+d) + :regs1 (gs-reg-id a+d) + :regs2 (gs-reg-id a+d) + :regs3 (gs-reg-id a+d) + :regs4 (gs-reg-id a+d) + :regs5 (gs-reg-id a+d) + :regs6 (gs-reg-id a+d) + :regs7 (gs-reg-id a+d) + :regs8 (gs-reg-id a+d) + :regs9 (gs-reg-id a+d) + :regs10 (gs-reg-id a+d) + :regs11 (gs-reg-id a+d) + :regs12 (gs-reg-id a+d) + :regs13 (gs-reg-id a+d) + :regs14 (gs-reg-id a+d) + :regs15 (gs-reg-id a+d) + ) + ) + (set! (-> buff-ptr5 base) (&+ (the-as pointer gif-tag) 16)) + ) + (let* ((buff-ptr3 buff) + (data (the-as (pointer uint64) (-> buff-ptr3 base))) + ) + (set! (-> data 0) (the-as uint 68)) + (set! (-> data 1) (the-as uint 66)) + (set! (-> data 2) (the-as uint #x10001c0)) + (set! (-> data 3) (the-as uint 78)) + (set! (-> data 4) (the-as uint #x5000e)) + (set! (-> data 5) (the-as uint 71)) + (set! (-> data 6) (the-as uint 0)) + (set! (-> data 7) (the-as uint 73)) + (set! (-> data 8) (the-as uint 5)) + (set! (-> data 9) (the-as uint 8)) + (set! (-> data 10) (the-as uint 96)) + (set! (-> data 11) (the-as uint 20)) + (set! (-> data 12) (the-as uint (shl 128 32))) + (set! (-> data 13) (the-as uint 59)) + (set! (-> data 14) (the-as uint 4)) + (set! (-> data 15) (the-as uint 28)) + (set! (-> data 16) (the-as uint *fog-color*)) + (set! (-> data 17) (the-as uint 61)) + (set! (-> buff-ptr3 base) (&+ (the-as pointer data) 144)) + ) + (let* ((buff-ptr4 buff) + (ret-packet (the-as dma-packet (-> buff-ptr4 base))) + ) + (set! (-> ret-packet dma) (new 'static 'dma-tag :id (dma-tag-id ret))) + (set! (-> ret-packet vif0) (new 'static 'vif-tag)) + (set! (-> ret-packet vif1) (new 'static 'vif-tag)) + (set! (-> buff-ptr4 base) (&+ (the-as pointer ret-packet) 16)) + ) + (none) + ) + +;; failed to figure out what this is: +(default-buffer-init *default-regs-buffer*) + +;; definition of type gif-packet +(deftype gif-packet (basic) + ((reg-count int32 :offset-assert 4) + (gif-tag gs-gif-tag :inline :offset-assert 16) + (gif-tag0 uint128 :offset 16) + (args uint64 1 :offset-assert 32) + ) + :method-count-assert 9 + :size-assert #x28 + :flag-assert #x900000028 + (:methods + (new (symbol type int) _type_ 0) + ) + ) + +;; definition for method 3 of type gif-packet +;; Used lq/sq +(defmethod inspect gif-packet ((obj gif-packet)) + (format #t "[~8x] ~A~%" obj (-> obj type)) + (format #t "~Treg-count: ~D~%" (-> obj reg-count)) + (format #t "~Tgif-tag0: #x~X~%" (-> obj gif-tag qword)) + (format #t "~Targs[1] @ #x~X~%" (-> obj args)) + obj + ) + +;; definition for method 0 of type gif-packet +(defmethod new gif-packet ((allocation symbol) (type-to-make type) (arg0 int)) + (object-new + allocation + type-to-make + (the-as int (+ (-> type-to-make size) (the-as uint (shl (+ arg0 -1) 3)))) + ) + ) + +;; definition for function open-gif-packet +(defun open-gif-packet ((arg0 gif-packet)) + (set! (-> arg0 reg-count) 0) + (set! (-> arg0 gif-tag regs) (new 'static 'gif-tag-regs)) + arg0 + ) + +;; definition for function add-reg-gif-packet +;; INFO: Return type mismatch gif-packet vs none. +(defun add-reg-gif-packet ((packet gif-packet) (reg-idx int) (reg-val int)) + (let ((tag (-> packet gif-tag))) + (set! + (-> tag regs) + (logior + (-> tag regs) + (the-as uint (ash reg-idx (shl (-> packet reg-count) 2))) + ) + ) + ) + (set! (-> (&-> packet args (-> packet reg-count)) 0) (the-as uint reg-val)) + (set! (-> packet reg-count) (+ (-> packet reg-count) 1)) + (none) + ) + +;; definition for function close-gif-packet +(defun close-gif-packet ((arg0 gif-packet) (arg1 int)) + (set! + (-> arg0 gif-tag tag) + (new 'static 'gif-tag64 + :nloop #x1 + :flg #x1 + :eop arg1 + :nreg (-> arg0 reg-count) + ) + ) + arg0 + ) + +;; definition of type draw-context +(deftype draw-context (basic) + ((orgx int32 :offset-assert 4) + (orgy int32 :offset-assert 8) + (orgz int32 :offset-assert 12) + (width int32 :offset-assert 16) + (height int32 :offset-assert 20) + (color rgba 4 :offset-assert 24) + ) + :method-count-assert 9 + :size-assert #x28 + :flag-assert #x900000028 + (:methods + (new (symbol type int int int int rgba) _type_ 0) + ) + ) + +;; definition for method 3 of type draw-context +(defmethod inspect draw-context ((obj draw-context)) + (format #t "[~8x] ~A~%" obj (-> obj type)) + (format #t "~Torgx: ~D~%" (-> obj orgx)) + (format #t "~Torgy: ~D~%" (-> obj orgy)) + (format #t "~Torgz: ~D~%" (-> obj orgz)) + (format #t "~Twidth: ~D~%" (-> obj width)) + (format #t "~Theight: ~D~%" (-> obj height)) + (format #t "~Tcolor[4] @ #x~X~%" (-> obj color)) + obj + ) + +;; definition for method 0 of type draw-context +(defmethod + new + draw-context + ((allocation symbol) + (type-to-make type) + (org-x int) + (org-y int) + (width int) + (height int) + (color-0 rgba) + ) + (let + ((obj + (object-new allocation type-to-make (the-as int (-> type-to-make size))) + ) + ) + (let + ((v1-3 (the int (* (the float org-y) (-> *video-parms* relative-y-scale)))) + (a0-2 (the int (* (the float height) (-> *video-parms* relative-y-scale)))) + ) + (set! (-> obj orgx) org-x) + (set! (-> obj orgy) v1-3) + (set! (-> obj orgz) #xffffff) + (set! (-> obj width) width) + (set! (-> obj height) a0-2) + ) + (set! (-> obj color 0) color-0) + obj + ) + ) + +;; definition for function draw-context-set-xy +;; INFO: Return type mismatch int vs none. +(defun draw-context-set-xy ((ctxt draw-context) (x int) (y int)) + (let* ((y (gpr->fpr y)) + (v0-0 (the int (* (the float y) (-> *video-parms* relative-y-scale)))) + ) + (set! (-> ctxt orgx) x) + (set! (-> ctxt orgy) v0-0) + ) + (none) + ) + + diff --git a/test/decompiler/reference/pad_REF.gc b/test/decompiler/reference/pad_REF.gc new file mode 100644 index 0000000000..5eee589227 --- /dev/null +++ b/test/decompiler/reference/pad_REF.gc @@ -0,0 +1,371 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for symbol *cheat-mode*, type symbol +(define *cheat-mode* #t) + +;; definition of type hw-cpad +(deftype hw-cpad (basic) + ((valid uint8 :offset-assert 4) + (status uint8 :offset-assert 5) + (button0 uint16 :offset-assert 6) + (rightx uint8 :offset-assert 8) + (righty uint8 :offset-assert 9) + (leftx uint8 :offset-assert 10) + (lefty uint8 :offset-assert 11) + (abutton uint8 12 :offset-assert 12) + (dummy uint8 12 :offset-assert 24) + ) + :method-count-assert 9 + :size-assert #x24 + :flag-assert #x900000024 + ) + +;; definition for method 3 of type hw-cpad +(defmethod inspect hw-cpad ((obj hw-cpad)) + (format #t "[~8x] ~A~%" obj (-> obj type)) + (format #t "~Tvalid: #x~X~%" (-> obj valid)) + (format #t "~Tstatus: #x~X~%" (-> obj status)) + (format #t "~Tbutton0: #x~X~%" (-> obj button0)) + (format #t "~Trightx: ~D~%" (-> obj rightx)) + (format #t "~Trighty: ~D~%" (-> obj righty)) + (format #t "~Tleftx: ~D~%" (-> obj leftx)) + (format #t "~Tlefty: ~D~%" (-> obj lefty)) + (format #t "~Tabutton[12] @ #x~X~%" (-> obj abutton)) + (format #t "~Tdummy[12] @ #x~X~%" (-> obj dummy)) + obj + ) + +;; definition of type cpad-info +(deftype cpad-info (hw-cpad) + ((number int32 :offset-assert 36) + (cpad-file int32 :offset-assert 40) + (button0-abs uint32 3 :offset-assert 44) + (button0-shadow-abs uint32 1 :offset-assert 56) + (button0-rel uint32 3 :offset-assert 60) + (stick0-dir float :offset-assert 72) + (stick0-speed float :offset-assert 76) + (new-pad int32 :offset-assert 80) + (state int32 :offset-assert 84) + (align uint8 6 :offset-assert 88) + (direct uint8 6 :offset-assert 94) + (buzz-val uint8 2 :offset-assert 100) + (buzz-time uint64 2 :offset-assert 104) + (buzz basic :offset-assert 120) + (buzz-act int32 :offset-assert 124) + (change-time uint64 :offset-assert 128) + ) + :method-count-assert 9 + :size-assert #x88 + :flag-assert #x900000088 + (:methods + (new (symbol type int) _type_ 0) + ) + ) + +;; definition for method 3 of type cpad-info +(defmethod inspect cpad-info ((obj cpad-info)) + (format #t "[~8x] ~A~%" obj (-> obj type)) + (format #t "~Tvalid: #x~X~%" (-> obj valid)) + (format #t "~Tstatus: #x~X~%" (-> obj status)) + (format #t "~Tbutton0: #x~X~%" (-> obj button0)) + (format #t "~Trightx: ~D~%" (-> obj rightx)) + (format #t "~Trighty: ~D~%" (-> obj righty)) + (format #t "~Tleftx: ~D~%" (-> obj leftx)) + (format #t "~Tlefty: ~D~%" (-> obj lefty)) + (format #t "~Tabutton[12] @ #x~X~%" (-> obj abutton)) + (format #t "~Tdummy[12] @ #x~X~%" (-> obj dummy)) + (format #t "~Tnumber: ~D~%" (-> obj number)) + (format #t "~Tcpad-file: ~D~%" (-> obj cpad-file)) + (format #t "~Tbutton0-abs[3] @ #x~X~%" (-> obj button0-abs)) + (format #t "~Tbutton0-shadow-abs[1] @ #x~X~%" (-> obj button0-shadow-abs)) + (format #t "~Tbutton0-rel[3] @ #x~X~%" (-> obj button0-rel)) + (format #t "~Tstick0-dir: ~f~%" (-> obj stick0-dir)) + (format #t "~Tstick0-speed: ~f~%" (-> obj stick0-speed)) + (format #t "~Tnew-pad: ~D~%" (-> obj new-pad)) + (format #t "~Tstate: ~D~%" (-> obj state)) + (format #t "~Talign[6] @ #x~X~%" (-> obj align)) + (format #t "~Tdirect[6] @ #x~X~%" (-> obj direct)) + (format #t "~Tbuzz-val[2] @ #x~X~%" (-> obj buzz-val)) + (format #t "~Tbuzz-time[2] @ #x~X~%" (-> obj buzz-time)) + (format #t "~Tbuzz: ~A~%" (-> obj buzz)) + (format #t "~Tbuzz-act: ~D~%" (-> obj buzz-act)) + (format #t "~Tchange-time: ~D~%" (-> obj change-time)) + obj + ) + +;; definition for function cpad-invalid! +(defun cpad-invalid! ((pad cpad-info)) + (set! (-> pad valid) (logior (-> pad valid) 128)) + (set! (-> pad button0) (the-as uint 0)) + (set! (-> pad button0-abs 0) (the-as uint 0)) + (set! (-> pad button0-shadow-abs 0) (the-as uint 0)) + (set! (-> pad button0-rel 0) (the-as uint 0)) + (dotimes (v1-2 12) + (nop!) + (set! (-> pad abutton v1-2) 0) + ) + (set! (-> pad stick0-dir) 0.0) + (set! (-> pad stick0-speed) 0.0) + (set! (-> pad rightx) (the-as uint 128)) + (set! (-> pad righty) (the-as uint 128)) + (set! (-> pad leftx) (the-as uint 128)) + (set! (-> pad lefty) (the-as uint 128)) + (set! (-> pad align 0) (the-as uint 0)) + (set! (-> pad align 1) (the-as uint 1)) + (set! (-> pad align 2) (the-as uint 255)) + (set! (-> pad align 3) (the-as uint 255)) + (set! (-> pad align 4) (the-as uint 255)) + (set! (-> pad align 5) (the-as uint 255)) + (dotimes (v1-14 6) + (set! (-> pad direct v1-14) 0) + ) + (dotimes (v1-17 2) + (set! (-> pad buzz-val 0) (the-as uint 0)) + (set! (-> pad buzz-time 0) (the-as uint 0)) + ) + pad + ) + +;; definition for method 0 of type cpad-info +(defmethod new cpad-info ((alloction symbol) (type-to-make type) (idx int)) + (let + ((obj + (object-new alloction type-to-make (the-as int (-> type-to-make size))) + ) + ) + (set! (-> obj number) idx) + (set! (-> obj buzz) #f) + (cpad-open obj idx) + (cpad-invalid! obj) + ) + ) + +;; definition of type cpad-list +(deftype cpad-list (basic) + ((num-cpads int32 :offset-assert 4) + (cpads cpad-info 2 :offset-assert 8) + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + (:methods + (new (symbol type) _type_ 0) + ) + ) + +;; definition for method 3 of type cpad-list +(defmethod inspect cpad-list ((obj cpad-list)) + (format #t "[~8x] ~A~%" obj (-> obj type)) + (format #t "~Tnum-cpads: ~D~%" (-> obj num-cpads)) + (format #t "~Tcpads[2] @ #x~X~%" (-> obj cpads)) + obj + ) + +;; definition for method 0 of type cpad-list +(defmethod new cpad-list ((allocation symbol) (type-to-make type)) + (let + ((gp-0 + (object-new allocation type-to-make (the-as int (-> type-to-make size))) + ) + ) + (set! (-> gp-0 num-cpads) 2) + (set! (-> gp-0 cpads 0) (new 'global 'cpad-info 0)) + (set! (-> gp-0 cpads 1) (new 'global 'cpad-info 1)) + gp-0 + ) + ) + +;; definition for function analog-input +(defun + analog-input + ((in int) (offset float) (center-val float) (max-val float) (out-range float)) + (let* ((in (gpr->fpr in)) + (offset-in (- (the float in) offset)) + (magnitude (- (fabs offset-in) center-val)) + (max-magnitude (- max-val center-val)) + ) + (if (< offset-in 0.0) + (set! out-range (- out-range)) + ) + (cond + ((>= 0.0 magnitude) + 0.0 + ) + ((>= magnitude max-magnitude) + out-range + ) + (else + (/ (* magnitude out-range) max-magnitude) + ) + ) + ) + ) + +;; definition for function cpad-set-buzz! +;; INFO: Return type mismatch int vs none. +(defun + cpad-set-buzz! + ((pad cpad-info) (buzz-idx int) (buzz-amount int) (duration int)) + (cond + ((zero? buzz-amount) + (set! (-> pad buzz-val buzz-idx) 0) + (let ((v1-2 0)) + ) + ) + ((= buzz-amount (-> pad buzz-val buzz-idx)) + (set! + (-> pad buzz-time buzz-idx) + (max + (the-as int (-> pad buzz-time buzz-idx)) + (the-as int (+ (get-current-time) (the-as uint duration))) + ) + ) + ) + ((< (-> pad buzz-val buzz-idx) (the-as uint buzz-amount)) + (set! (-> pad buzz-val buzz-idx) buzz-amount) + (set! + (-> pad buzz-time buzz-idx) + (+ (get-current-time) (the-as uint duration)) + ) + ) + ) + (let ((v0-2 0)) + ) + (none) + ) + +;; definition for symbol *cpad-list*, type cpad-list +(define *cpad-list* (new 'global 'cpad-list)) + +;; definition for symbol *cpad-debug*, type symbol +(define *cpad-debug* #f) + +;; definition for function service-cpads +(defun service-cpads () + (let ((pad-list *cpad-list*)) + (dotimes (pad-idx (-> pad-list num-cpads)) + (let ((pad (-> *cpad-list* cpads pad-idx))) + (cpad-get-data pad) + (cond + ((zero? (logand (-> pad valid) 128)) + (dotimes (buzz-idx 2) + (cond + ((and + (-> pad buzz) + (< + (the-as int (get-current-time)) + (the-as int (-> pad buzz-time buzz-idx)) + ) + (= *master-mode* 'game) + ) + (let ((v1-10 buzz-idx)) + (cond + ((zero? v1-10) + (set! + (-> pad direct buzz-idx) + (logand + (ash + (-> pad buzz-val buzz-idx) + (- (the-as int (logand (get-integral-current-time) 7))) + ) + 1 + ) + ) + ) + ((= v1-10 1) + (set! (-> pad direct buzz-idx) (-> pad buzz-val buzz-idx)) + ) + ) + ) + ) + (else + (set! (-> pad buzz-val buzz-idx) 0) + (set! (-> pad direct buzz-idx) 0) + (let ((v1-22 0)) + ) + ) + ) + ) + (set! (-> pad button0-abs 2) (-> pad button0-abs 1)) + (set! (-> pad button0-abs 1) (-> pad button0-shadow-abs 0)) + (set! (-> pad button0-rel 2) (-> pad button0-rel 1)) + (set! (-> pad button0-rel 1) (-> pad button0-rel 0)) + (let ((current-button0 (-> pad button0))) + (set! (-> pad button0-shadow-abs 0) current-button0) + (set! (-> pad button0-abs 0) current-button0) + ) + (set! + (-> pad button0-rel 0) + (logand (-> pad button0-abs 0) (lognot (-> pad button0-abs 1))) + ) + (when *cpad-debug* + (set! (-> pad leftx) (the-as uint 255)) + (set! (-> pad rightx) (the-as uint 255)) + ) + (set! (-> pad stick0-speed) 1.0) + (cond + ((= (shr (-> pad status) 4) 7) + (let ((f30-0 (* 0.0078125 (the float (+ (-> pad leftx) -128)))) + (f28-0 + (* 0.0078125 (the float (- 127 (the-as int (-> pad lefty))))) + ) + ) + (set! (-> pad stick0-dir) (atan (- f30-0) f28-0)) + (set! + (-> pad stick0-speed) + (fmin 1.0 (sqrtf (+ (* f30-0 f30-0) (* f28-0 f28-0)))) + ) + ) + (if (< (-> pad stick0-speed) 0.3) + (let ((f0-8 0.0)) + (set! (-> pad stick0-speed) f0-8) + ) + ) + ) + (else + (set! (-> pad leftx) (the-as uint 128)) + (set! (-> pad lefty) (the-as uint 128)) + (set! (-> pad rightx) (the-as uint 128)) + (set! (-> pad righty) (the-as uint 128)) + (set! (-> pad stick0-dir) 0.0) + (let ((f0-10 0.0)) + (set! (-> pad stick0-speed) f0-10) + ) + ) + ) + (if + (or + (!= (-> pad button0-abs 0) (-> pad button0-abs 1)) + (or (< 0.3 (-> pad stick0-speed)) (zero? (-> pad change-time))) + ) + (set! (-> pad change-time) (get-current-time)) + ) + ) + (else + (cpad-invalid! pad) + ) + ) + ) + ) + ) + *cpad-list* + ) + +;; definition for function buzz-stop! +;; INFO: Return type mismatch int vs none. +(defun buzz-stop! ((idx int)) + (cpad-set-buzz! (-> *cpad-list* cpads idx) 0 0 0) + (cpad-set-buzz! (-> *cpad-list* cpads idx) 1 0 0) + (let ((v0-0 0)) + ) + (none) + ) + +;; failed to figure out what this is: +(let ((v0-4 0)) + ) + + + + diff --git a/test/decompiler/test_FormExpressionBuild2.cpp b/test/decompiler/test_FormExpressionBuild2.cpp index 83dd1fbfc2..7ae4673c38 100644 --- a/test/decompiler/test_FormExpressionBuild2.cpp +++ b/test/decompiler/test_FormExpressionBuild2.cpp @@ -967,7 +967,7 @@ TEST_F(FormRegressionTest, DmaBufferAddVuFunction) { " (quote static)\n" " (quote dma-tag)\n" " :id\n" - " 3\n" + " (dma-tag-id ref)\n" " :addr\n" " (the-as int v1-0)\n" " :qwc\n" @@ -984,7 +984,7 @@ TEST_F(FormRegressionTest, DmaBufferAddVuFunction) { " )\n" " (set!\n" " (-> (the-as dma-packet t2-0) vif1)\n" - " (new (quote static) (quote vif-tag) :cmd 74 :num (shl t0-1 1) :imm a1-1)\n" + " (new (quote static) (quote vif-tag) :cmd (vif-cmd mpg) :num (shl t0-1 1) :imm a1-1)\n" " )\n" " (set! (-> t1-1 base) (&+ (the-as pointer t2-0) 16))\n" " )\n" diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index 6266f2e772..08db621d18 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -17,7 +17,7 @@ const std::unordered_set g_object_files_to_decompile = { "trigonometry-h", /* transformq-h */ "matrix", "transform", "quaternion", "euler", /* geometry, trigonometry, */ "gsound-h", "timer-h", "timer", "vif-h", "dma-h", "video-h", "vu1-user-h", "dma", "dma-buffer", - "dma-bucket", "dma-disasm", + "dma-bucket", "dma-disasm", "pad", "gs", /* gap */ "bounding-box", /* gap */ @@ -32,7 +32,7 @@ const std::vector g_object_files_to_check_against_reference = { /* transformq-h, */ "matrix", "transform", "quaternion", "euler", /* geometry, trigonometry */ "gsound-h", "timer-h", /* timer, */ "vif-h", "dma-h", "video-h", "vu1-user-h", "dma", - "dma-buffer", "dma-bucket", "dma-disasm", + "dma-buffer", "dma-bucket", "dma-disasm", "pad", "gs", /* gap */ "bounding-box", /* gap */ "sync-info-h", "sync-info"}; @@ -118,7 +118,10 @@ const std::unordered_set skip_in_compiling = { "(method 3 profile-frame)", // double definition. // dma-disasm - "disasm-dma-list", + "disasm-dma-list", // missing a single cast :( + + // gs + "(method 3 gif-tag)", // inspect for a 128-bit type. // sync-info "(method 15 sync-info)", // needs display stuff first