From 7fac11ddf5479990c7fcbe95f451653ec65b58ee Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Thu, 25 Mar 2021 16:02:48 -0400 Subject: [PATCH] Support 128-bit variables (#336) * wip 128 bit support * add a few more files to offline test --- common/type_system/TypeFieldLookup.cpp | 5 +- decompiler/Function/Warnings.h | 11 +- decompiler/IR2/AtomicOp.cpp | 6 ++ decompiler/IR2/AtomicOpForm.cpp | 6 ++ decompiler/IR2/AtomicOpTypeAnalysis.cpp | 4 + decompiler/ObjectFile/ObjectFileDB_IR2.cpp | 2 +- decompiler/analysis/atomic_op_builder.cpp | 18 +++- decompiler/analysis/atomic_op_builder.h | 7 +- decompiler/config/all-types.gc | 11 +- .../jak1_ntsc_black_label/label_types.jsonc | 7 ++ .../jak1_ntsc_black_label/var_names.jsonc | 2 +- goal_src/engine/math/matrix-h.gc | 29 +++-- goal_src/engine/math/quaternion-h.gc | 2 +- goalc/compiler/Val.cpp | 26 ++++- goalc/compiler/Val.h | 10 +- goalc/compiler/compilation/Define.cpp | 8 ++ test/decompiler/FormRegressionTest.cpp | 3 +- test/decompiler/reference/euler-h_REF.gc | 43 ++++++++ test/decompiler/reference/gcommon_REF.gc | 64 +++++------ test/decompiler/reference/geometry-h_REF.gc | 62 +++++++++++ test/decompiler/reference/matrix-h_REF.gc | 85 +++++++++++++++ test/decompiler/reference/quaternion-h_REF.gc | 41 +++++++ test/decompiler/reference/transform-h_REF.gc | 50 +++++++++ .../reference/trigonometry-h_REF.gc | 10 ++ test/decompiler/reference/vector-h_REF.gc | 100 ++++-------------- test/decompiler/test_AtomicOpBuilder.cpp | 9 +- test/decompiler/test_FormExpressionBuild.cpp | 6 +- .../test_FormExpressionBuildLong.cpp | 34 +++--- test/offline/offline_test_main.cpp | 61 ++++++----- 29 files changed, 509 insertions(+), 213 deletions(-) create mode 100644 test/decompiler/reference/euler-h_REF.gc create mode 100644 test/decompiler/reference/geometry-h_REF.gc create mode 100644 test/decompiler/reference/matrix-h_REF.gc create mode 100644 test/decompiler/reference/quaternion-h_REF.gc create mode 100644 test/decompiler/reference/transform-h_REF.gc create mode 100644 test/decompiler/reference/trigonometry-h_REF.gc diff --git a/common/type_system/TypeFieldLookup.cpp b/common/type_system/TypeFieldLookup.cpp index 6e1cf4a369..6ea71ea430 100644 --- a/common/type_system/TypeFieldLookup.cpp +++ b/common/type_system/TypeFieldLookup.cpp @@ -339,9 +339,8 @@ bool TypeSystem::try_reverse_lookup_inline_array(const FieldReverseLookupInput& } // otherwise access within the element - if (elt_idx != 0) { - path->push_back(token); - } + path->push_back(token); + FieldReverseLookupInput next_input; next_input.deref = input.deref; next_input.stride = 0; diff --git a/decompiler/Function/Warnings.h b/decompiler/Function/Warnings.h index 4d85a2a74b..d7cdf51402 100644 --- a/decompiler/Function/Warnings.h +++ b/decompiler/Function/Warnings.h @@ -5,6 +5,7 @@ #include "third-party/fmt/core.h" +namespace decompiler { class DecompWarnings { public: DecompWarnings() = default; @@ -39,7 +40,8 @@ class DecompWarnings { warning(Warning::Kind::INFO, str, std::forward(args)...); } - bool has_warnings() const { return !m_warnings.empty(); } + bool has_warnings() const { return !m_warnings.empty() || m_used_lq_sq; } + void warn_sq_lq() { m_used_lq_sq = true; } std::string get_warning_text(bool as_comment) const { std::string result; @@ -49,6 +51,9 @@ class DecompWarnings { } result += w.print(); } + if (m_used_lq_sq) { + result += ";; Used lq/sq\n"; + } return result; } @@ -95,4 +100,6 @@ class DecompWarnings { } std::vector m_warnings; -}; \ No newline at end of file + bool m_used_lq_sq = false; +}; +} // namespace decompiler \ No newline at end of file diff --git a/decompiler/IR2/AtomicOp.cpp b/decompiler/IR2/AtomicOp.cpp index 9929768819..60bd12a023 100644 --- a/decompiler/IR2/AtomicOp.cpp +++ b/decompiler/IR2/AtomicOp.cpp @@ -989,6 +989,9 @@ goos::Object StoreOp::to_form(const std::vector& labels, const case 8: store_name = "s.d!"; break; + case 16: + store_name = "s.q!"; + break; default: assert(false); } @@ -1056,6 +1059,9 @@ goos::Object LoadVarOp::to_form(const std::vector& labels, cons case 8: forms.push_back(pretty_print::build_list("l.d", m_src.to_form(labels, env))); break; + case 16: + forms.push_back(pretty_print::build_list("l.q", m_src.to_form(labels, env))); + break; default: assert(false); } diff --git a/decompiler/IR2/AtomicOpForm.cpp b/decompiler/IR2/AtomicOpForm.cpp index f69a33f53c..50f0faab66 100644 --- a/decompiler/IR2/AtomicOpForm.cpp +++ b/decompiler/IR2/AtomicOpForm.cpp @@ -324,6 +324,9 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const { case 8: cast_type = "int64"; break; + case 16: + cast_type = "int128"; + break; default: assert(false); } @@ -486,6 +489,9 @@ FormElement* LoadVarOp::get_as_form(FormPool& pool, const Env& env) const { case 8: cast_type = "int64"; break; + case 16: + cast_type = "int128"; + break; default: assert(false); } diff --git a/decompiler/IR2/AtomicOpTypeAnalysis.cpp b/decompiler/IR2/AtomicOpTypeAnalysis.cpp index dc9b36b073..58d174b46b 100644 --- a/decompiler/IR2/AtomicOpTypeAnalysis.cpp +++ b/decompiler/IR2/AtomicOpTypeAnalysis.cpp @@ -699,6 +699,8 @@ TP_Type LoadVarOp::get_src_type(const TypeState& input, case 4: case 8: return TP_Type::make_from_ts(TypeSpec("uint")); + case 16: + return TP_Type::make_from_ts(TypeSpec("uint128")); default: break; } @@ -710,6 +712,8 @@ TP_Type LoadVarOp::get_src_type(const TypeState& input, case 4: case 8: return TP_Type::make_from_ts(TypeSpec("int")); + case 16: + return TP_Type::make_from_ts(TypeSpec("int128")); default: break; } diff --git a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp index 8b4064c0b8..60b32da5bd 100644 --- a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp +++ b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp @@ -254,7 +254,7 @@ 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); + auto ops = convert_function_to_atomic_ops(func, data.linked_data.labels, func.warnings); 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 a2ab72f659..00493c45e1 100644 --- a/decompiler/analysis/atomic_op_builder.cpp +++ b/decompiler/analysis/atomic_op_builder.cpp @@ -5,6 +5,7 @@ #include "decompiler/Function/Function.h" #include "decompiler/Disasm/InstructionMatching.h" #include "decompiler/util/TP_Type.h" +#include "decompiler/Function/Warnings.h" namespace decompiler { @@ -716,6 +717,8 @@ std::unique_ptr convert_1(const Instruction& i0, int idx) { return convert_lw_1(i0, idx); case InstructionKind::LD: return make_standard_load(i0, idx, 8, LoadVarOp::Kind::UNSIGNED); + case InstructionKind::LQ: + return make_standard_load(i0, idx, 16, LoadVarOp::Kind::UNSIGNED); case InstructionKind::DSLL: return make_2reg_1imm_op(i0, SimpleExpression::Kind::LEFT_SHIFT, idx); case InstructionKind::DSLL32: @@ -778,6 +781,8 @@ std::unique_ptr convert_1(const Instruction& i0, int idx) { return convert_sw_1(i0, idx); case InstructionKind::SD: return convert_sd_1(i0, idx); + case InstructionKind::SQ: + return make_standard_store(i0, idx, 16, false); case InstructionKind::SWC1: return make_standard_store(i0, idx, 4, true); case InstructionKind::CVTWS: // float to int @@ -1378,7 +1383,8 @@ int convert_block_to_atomic_ops(int begin_idx, std::vector::const_iterator begin, std::vector::const_iterator end, const std::vector& labels, - FunctionAtomicOps* container) { + FunctionAtomicOps* container, + DecompWarnings& warnings) { 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? @@ -1391,6 +1397,10 @@ int convert_block_to_atomic_ops(int begin_idx, bool converted = false; std::unique_ptr op; + if (instr[0].kind == InstructionKind::SQ || instr[0].kind == InstructionKind::LQ) { + warnings.warn_sq_lq(); + } + if (n_instr >= 5) { // try 5 instructions op = convert_5(instr[0], instr[1], instr[2], instr[3], instr[4], op_idx); @@ -1469,7 +1479,8 @@ int convert_block_to_atomic_ops(int begin_idx, } FunctionAtomicOps convert_function_to_atomic_ops(const Function& func, - const std::vector& labels) { + const std::vector& labels, + DecompWarnings& warnings) { FunctionAtomicOps result; int last_op = 0; @@ -1479,7 +1490,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); + last_op = + convert_block_to_atomic_ops(block.start_word, begin, end, labels, &result, warnings); 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 95404dcf09..f32fb146e6 100644 --- a/decompiler/analysis/atomic_op_builder.h +++ b/decompiler/analysis/atomic_op_builder.h @@ -6,6 +6,7 @@ namespace decompiler { class Function; struct BasicBlock; class LinkedObjectFile; +class DecompWarnings; /*! * A collection of Atomic Ops in a function @@ -45,11 +46,13 @@ int convert_block_to_atomic_ops(int begin_idx, std::vector::const_iterator begin, std::vector::const_iterator end, const std::vector& labels, - FunctionAtomicOps* container); + FunctionAtomicOps* container, + DecompWarnings& warnings); /*! * Convert an entire function to AtomicOps */ FunctionAtomicOps convert_function_to_atomic_ops(const Function& func, - const std::vector& labels); + const std::vector& labels, + DecompWarnings& warnings); } // namespace decompiler \ No newline at end of file diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 1fc77519fd..c438471bdb 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -1238,7 +1238,7 @@ ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; (deftype quaternion (structure) - ((data float 4 :offset-assert 0) + ((data float 4 :do-not-decompile :offset-assert 0) (x float :offset 0) (y float :offset 4) (z float :offset 8) @@ -1251,6 +1251,8 @@ :flag-assert #x900000010 ) +(define-extern *unity-quaternion* quaternion) + ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; EULER-H ;;;;;;;;;;;;;;;;;;;;;; @@ -1264,6 +1266,9 @@ :flag-assert #x900000010 ) +(define-extern EulNext (array int32)) +(define-extern EulSafe (array int32)) + ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; TRANSFORM-H ;;;;;;;;;;;;;;;;;;;;;; @@ -32495,11 +32500,9 @@ ;;(define-extern matrix3 object) ;; unknown type ;;(define-extern matrix object) ;; unknown type -;;(define-extern *unity-quaternion* object) ;; unknown type + ;;(define-extern quaternion object) ;; unknown type ;;(define-extern euler-angles object) ;; unknown type -;;(define-extern EulNext object) ;; unknown type -;;(define-extern EulSafe object) ;; unknown type ;;(define-extern transform object) ;; unknown type ;;(define-extern trs object) ;; unknown type ;;(define-extern border-plane object) ;; unknown type diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index 2aadb0a17e..2bebe23d87 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -38,6 +38,13 @@ ["L26", "vector", true] ], + "quaternion-h": [["L1", "quaternion", true]], + + "euler-h": [ + ["L3", "_auto_", true], + ["L2", "_auto_", true] + ], + "trigonometry": [ ["L143", "float", true], ["L144", "float", true], diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index 14a54341ae..248779a05a 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -165,7 +165,7 @@ }, "qmem-copy->!":{ "args":["dst", "src", "size"], - "vars":{"v0-0":"result", "v1-1":"qwc", "a0-1":"src-ptr", "a1-1":"dst-ptr", "a2-3":"value"} + "vars":{"v0-0":"result", "v1-1":"qwc", "a1-1":"src-ptr", "a0-1":"dst-ptr", "a2-3":"value"} }, "mem-set32!":{ "args":["dst", "size", "value"], diff --git a/goal_src/engine/math/matrix-h.gc b/goal_src/engine/math/matrix-h.gc index 4475b436c6..c897e08702 100644 --- a/goal_src/engine/math/matrix-h.gc +++ b/goal_src/engine/math/matrix-h.gc @@ -40,21 +40,16 @@ :flag-assert #x900000020 ) -(defun matrix-copy! ((dst matrix) (src matrix)) - "Copy src to dst." - (rlet ((r0 :class vf) - (r1 :class vf) - (r2 :class vf) - (r3 :class vf) - ) - (.lvf r0 (&-> src quad 0)) - (.lvf r1 (&-> src quad 1)) - (.lvf r2 (&-> src quad 2)) - (.lvf r3 (&-> src quad 3)) - (.svf (&-> dst quad 0) r0) - (.svf (&-> dst quad 1) r1) - (.svf (&-> dst quad 2) r2) - (.svf (&-> dst quad 3) r3) - ) - dst +(defun matrix-copy! ((arg0 matrix) (arg1 matrix)) + (let ((v1-0 (-> arg1 vector 0 quad)) + (a2-0 (-> arg1 vector 1 quad)) + (a3-0 (-> arg1 vector 2 quad)) + (a1-1 (-> arg1 vector 3 quad)) + ) + (set! (-> arg0 vector 0 quad) v1-0) + (set! (-> arg0 vector 1 quad) a2-0) + (set! (-> arg0 vector 2 quad) a3-0) + (set! (-> arg0 vector 3 quad) a1-1) + ) + arg0 ) diff --git a/goal_src/engine/math/quaternion-h.gc b/goal_src/engine/math/quaternion-h.gc index ca8333fce2..a0cad56963 100644 --- a/goal_src/engine/math/quaternion-h.gc +++ b/goal_src/engine/math/quaternion-h.gc @@ -6,7 +6,7 @@ ;; dgos: GAME, ENGINE (deftype quaternion (structure) - ((data float 4 :offset-assert 0) + ((data float 4 :do-not-decompile :offset-assert 0) (x float :offset 0) (y float :offset 4) (z float :offset 8) diff --git a/goalc/compiler/Val.cpp b/goalc/compiler/Val.cpp index 5826cc218b..0e7c0dd0b5 100644 --- a/goalc/compiler/Val.cpp +++ b/goalc/compiler/Val.cpp @@ -32,13 +32,26 @@ RegVal* Val::to_fpr(Env* fe) { } } +/*! + * Fallback to_xmm128 if a more optimized one is not provided. + */ +RegVal* Val::to_xmm128(Env* fe) { + auto rv = to_reg(fe); + if (rv->ireg().reg_class == RegClass::INT_128 || rv->ireg().reg_class == RegClass::VECTOR_FLOAT) { + return rv; + } else { + auto re = fe->make_ireg(coerce_to_reg_type(m_ts), RegClass::INT_128); + fe->emit(std::make_unique(re, rv)); + return re; + } +} + RegVal* RegVal::to_reg(Env* fe) { (void)fe; return this; } RegVal* RegVal::to_gpr(Env* fe) { - (void)fe; if (m_ireg.reg_class == RegClass::GPR_64) { return this; } else { @@ -49,7 +62,6 @@ RegVal* RegVal::to_gpr(Env* fe) { } RegVal* RegVal::to_fpr(Env* fe) { - (void)fe; if (m_ireg.reg_class == RegClass::FLOAT) { return this; } else { @@ -59,6 +71,16 @@ RegVal* RegVal::to_fpr(Env* fe) { } } +RegVal* RegVal::to_xmm128(Env* fe) { + if (m_ireg.reg_class == RegClass::INT_128 || m_ireg.reg_class == RegClass::VECTOR_FLOAT) { + return this; + } else { + auto re = fe->make_ireg(coerce_to_reg_type(m_ts), RegClass::INT_128); + fe->emit(std::make_unique(re, this)); + return re; + } +} + void RegVal::set_rlet_constraint(emitter::Register reg) { m_rlet_constraint = reg; } diff --git a/goalc/compiler/Val.h b/goalc/compiler/Val.h index 5e27b9cea3..b0972e1276 100644 --- a/goalc/compiler/Val.h +++ b/goalc/compiler/Val.h @@ -41,6 +41,7 @@ class Val { } virtual RegVal* to_gpr(Env* fe); virtual RegVal* to_fpr(Env* fe); + virtual RegVal* to_xmm128(Env* fe); const TypeSpec& type() const { return m_ts; } void set_type(TypeSpec ts) { m_ts = std::move(ts); } @@ -75,6 +76,7 @@ class RegVal : public Val { RegVal* to_reg(Env* fe) override; RegVal* to_gpr(Env* fe) override; RegVal* to_fpr(Env* fe) override; + RegVal* to_xmm128(Env* fe) override; void set_rlet_constraint(emitter::Register reg); const std::optional& rlet_constraint() const; @@ -182,7 +184,13 @@ class StackVarAddrVal : public Val { class MemoryOffsetConstantVal : public Val { public: MemoryOffsetConstantVal(TypeSpec ts, Val* _base, s64 _offset) - : Val(std::move(ts)), base(_base), offset(_offset) {} + : Val(std::move(ts)), base(_base), offset(_offset) { + auto base_as_offset = dynamic_cast(base); + if (base_as_offset) { + offset += base_as_offset->offset; + base = base_as_offset->base; + } + } std::string print() const override { return "(" + base->print() + " + " + std::to_string(offset) + ")"; } diff --git a/goalc/compiler/compilation/Define.cpp b/goalc/compiler/compilation/Define.cpp index 97b58b4954..20574011ee 100644 --- a/goalc/compiler/compilation/Define.cpp +++ b/goalc/compiler/compilation/Define.cpp @@ -161,6 +161,14 @@ Val* Compiler::do_set(const goos::Object& form, Val* dest, RegVal* src_in_reg, V typecheck_reg_type_allow_false(form, dest_type, src, "set! memory"); } + // we want to allow setting a 128-bit field from a 64-bit variable. + if (as_mem_deref->info.size == 16) { + auto fe = get_parent_env_of_type(env); + auto src_128 = fe->make_ireg(src_in_reg->type(), RegClass::INT_128); + env->emit_ir(src_128, src_in_reg); + src_in_reg = src_128; + } + // setting somewhere in memory auto base = as_mem_deref->base; auto base_as_mco = dynamic_cast(base); diff --git a/test/decompiler/FormRegressionTest.cpp b/test/decompiler/FormRegressionTest.cpp index 7afe955f30..af76c0fa45 100644 --- a/test/decompiler/FormRegressionTest.cpp +++ b/test/decompiler/FormRegressionTest.cpp @@ -146,7 +146,8 @@ std::unique_ptr FormRegressionTest::make_function( fmt::print("CFG:\n{}\n", test->func.cfg->to_dot()); } - auto ops = convert_function_to_atomic_ops(test->func, program.labels); + DecompWarnings warnings; + auto ops = convert_function_to_atomic_ops(test->func, program.labels, warnings); 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/euler-h_REF.gc b/test/decompiler/reference/euler-h_REF.gc new file mode 100644 index 0000000000..8f11ef2dc8 --- /dev/null +++ b/test/decompiler/reference/euler-h_REF.gc @@ -0,0 +1,43 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for symbol EulSafe, type (array int32) +(define + EulSafe + (the-as (array int32) (new 'static 'boxed-array int32 4 0 1 2 0)) + ) + +;; definition for symbol EulNext, type (array int32) +(define + EulNext + (the-as (array int32) (new 'static 'boxed-array int32 4 1 2 0 1)) + ) + +;; definition of type euler-angles +(deftype euler-angles (vector) + () + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + ) + +;; definition for method 3 of type euler-angles +;; Used lq/sq +(defmethod inspect euler-angles ((obj euler-angles)) + (format #t "[~8x] ~A~%" obj 'euler-angles) + (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) + (format #t "~Tx: ~f~%" (-> obj data 0)) + (format #t "~Ty: ~f~%" (-> obj data 1)) + (format #t "~Tz: ~f~%" (-> obj data 2)) + (format #t "~Tw: ~f~%" (-> obj data 3)) + (format #t "~Tquad: ~D~%" (-> obj quad)) + obj + ) + +;; failed to figure out what this is: +(let ((v0-1 0)) + ) + +;; failed to figure out what this is: +(none) + diff --git a/test/decompiler/reference/gcommon_REF.gc b/test/decompiler/reference/gcommon_REF.gc index 27655b6ead..7b7ccbd5e9 100644 --- a/test/decompiler/reference/gcommon_REF.gc +++ b/test/decompiler/reference/gcommon_REF.gc @@ -626,9 +626,8 @@ ) ;; definition for method 2 of type array -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod print array ((obj array)) - (local-vars (a2-8 int)) (format #t "#(") (if (type-type? (-> obj content-type) integer) (let ((content-type-sym (-> obj content-type symbol))) @@ -717,19 +716,11 @@ (cond ((or (= content-type-sym 'uint128) (= content-type-sym 'int128)) (dotimes (s5-8 (-> obj length)) - (let ((t9-10 format) - (a0-21 #t) - (a1-11 (if (zero? s5-8) - "#x~X" - " #x~X" - ) - ) - ) - (let - ((v1-42 (+ (shl s5-8 4) (the-as int (the-as (array uint128) obj))))) - (TODO.LQ a2-8 v1-42 :offset 12) - ) - (t9-10 a0-21 a1-11 a2-8) + (format #t (if (zero? s5-8) + "#x~X" + " #x~X" + ) + (-> (the-as (array uint128) obj) s5-8) ) ) ) @@ -771,9 +762,8 @@ ) ;; definition for method 3 of type array -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod inspect array ((obj array)) - (local-vars (a3-10 int)) (format #t "[~8x] ~A~%" obj (-> obj type)) (format #t "~Tallocated-length: ~D~%" (-> obj allocated-length)) (format #t "~Tlength: ~D~%" (-> obj length)) @@ -826,15 +816,11 @@ (cond ((or (= content-type-sym 'int128) (= content-type-sym 'uint128)) (dotimes (s5-8 (-> obj length)) - (let ((t9-14 format) - (a0-25 #t) - (a1-15 "~T [~D] #x~X~%") - (a2-13 s5-8) - ) - (let ((v1-42 (+ (shl s5-8 4) (the-as int obj)))) - (TODO.LQ a3-10 v1-42 :offset 12) - ) - (t9-14 a0-25 a1-15 a2-13 a3-10) + (format + #t + "~T [~D] #x~X~%" + s5-8 + (-> (the-as (pointer uint128) (+ (shl s5-8 4) (the-as int obj)))) ) ) ) @@ -900,16 +886,16 @@ ) ;; definition for function qmem-copy<-! -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] -;; WARN: Inline assembly instruction marked with TODO - [TODO.SQ] +;; Used lq/sq (defun qmem-copy<-! ((dst pointer) (src pointer) (size int)) - (local-vars (value int)) (let ((result dst)) (let ((qwc (sar (+ size 15) 4))) (while (nonzero? qwc) (+! qwc -1) - (TODO.LQ value src) - (TODO.SQ value dst) + (set! + (-> (the-as (pointer uint128) dst)) + (-> (the-as (pointer uint128) src)) + ) (&+! dst 16) (&+! src 16) ) @@ -919,21 +905,21 @@ ) ;; definition for function qmem-copy->! -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] -;; WARN: Inline assembly instruction marked with TODO - [TODO.SQ] +;; Used lq/sq (defun qmem-copy->! ((dst pointer) (src pointer) (size int)) - (local-vars (value int)) (let ((result dst)) (let* ((qwc (sar (+ size 15) 4)) - (src-ptr (&+ dst (shl qwc 4))) - (dst-ptr (&+ src (shl qwc 4))) + (dst-ptr (&+ dst (shl qwc 4))) + (src-ptr (&+ src (shl qwc 4))) ) (while (nonzero? qwc) (+! qwc -1) - (&+! src-ptr -16) (&+! dst-ptr -16) - (TODO.LQ value dst-ptr) - (TODO.SQ value src-ptr) + (&+! src-ptr -16) + (set! + (-> (the-as (pointer uint128) dst-ptr)) + (-> (the-as (pointer uint128) src-ptr)) + ) ) ) result diff --git a/test/decompiler/reference/geometry-h_REF.gc b/test/decompiler/reference/geometry-h_REF.gc new file mode 100644 index 0000000000..714741fffa --- /dev/null +++ b/test/decompiler/reference/geometry-h_REF.gc @@ -0,0 +1,62 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition of type curve +(deftype curve (structure) + ((cverts uint32 :offset-assert 0) + (num-cverts int32 :offset-assert 4) + (knots uint32 :offset-assert 8) + (num-knots int32 :offset-assert 12) + (length float :offset-assert 16) + ) + :method-count-assert 9 + :size-assert #x14 + :flag-assert #x900000014 + ) + +;; definition for method 3 of type curve +(defmethod inspect curve ((obj curve)) + (format #t "[~8x] ~A~%" obj 'curve) + (format #t "~Tcverts: #x~X~%" (-> obj cverts)) + (format #t "~Tnum-cverts: ~D~%" (-> obj num-cverts)) + (format #t "~Tknots: #x~X~%" (-> obj knots)) + (format #t "~Tnum-knots: ~D~%" (-> obj num-knots)) + (format #t "~Tlength: ~f~%" (-> obj length)) + obj + ) + +;; definition of type border-plane +(deftype border-plane (basic) + ((name basic :offset-assert 4) + (action basic :offset-assert 8) + (slot int8 :offset-assert 12) + (trans vector :inline :offset-assert 16) + (normal vector :inline :offset-assert 32) + ) + :method-count-assert 11 + :size-assert #x30 + :flag-assert #xb00000030 + (:methods + (dummy-9 () none 9) + (dummy-10 () none 10) + ) + ) + +;; definition for method 3 of type border-plane +(defmethod inspect border-plane ((obj border-plane)) + (format #t "[~8x] ~A~%" obj (-> obj type)) + (format #t "~Tname: ~A~%" (-> obj name)) + (format #t "~Taction: ~A~%" (-> obj action)) + (format #t "~Tslot: ~D~%" (-> obj slot)) + (format #t "~Ttrans: ~`vector`P~%" (-> obj trans)) + (format #t "~Tnormal: ~`vector`P~%" (-> obj normal)) + obj + ) + +;; failed to figure out what this is: +(let ((v0-2 0)) + ) + +;; failed to figure out what this is: +(none) + diff --git a/test/decompiler/reference/matrix-h_REF.gc b/test/decompiler/reference/matrix-h_REF.gc new file mode 100644 index 0000000000..b6cda33778 --- /dev/null +++ b/test/decompiler/reference/matrix-h_REF.gc @@ -0,0 +1,85 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition of type matrix +(deftype matrix (structure) + ((data float 16 :offset-assert 0) + (vector vector 4 :inline :offset 0) + (quad uint128 4 :offset 0) + ) + :method-count-assert 10 + :size-assert #x40 + :flag-assert #xa00000040 + (:methods + (dummy-9 () none 9) + ) + ) + +;; definition for method 3 of type matrix +(defmethod inspect matrix ((obj matrix)) + (format #t "[~8x] ~A~%" obj 'matrix) + (format #t "~Tdata[16] @ #x~X~%" (-> obj data)) + (format #t "~Tvector[4] @ #x~X~%" (-> obj data)) + (format #t "~Tquad[4] @ #x~X~%" (-> obj data)) + obj + ) + +;; definition of type matrix3 +(deftype matrix3 (structure) + ((data float 12 :offset-assert 0) + (vector vector 3 :inline :offset 0) + (quad uint128 3 :offset 0) + ) + :method-count-assert 9 + :size-assert #x30 + :flag-assert #x900000030 + ) + +;; definition for method 3 of type matrix3 +(defmethod inspect matrix3 ((obj matrix3)) + (format #t "[~8x] ~A~%" obj 'matrix3) + (format #t "~Tdata[12] @ #x~X~%" (-> obj data)) + (format #t "~Tvector[3] @ #x~X~%" (-> obj data)) + (format #t "~Tquad[3] @ #x~X~%" (-> obj data)) + obj + ) + +;; definition of type matrix4h +(deftype matrix4h (structure) + ((data int16 16 :offset-assert 0) + (vector4h vector4h 4 :inline :offset 0) + (long int64 4 :offset 0) + ) + :method-count-assert 9 + :size-assert #x20 + :flag-assert #x900000020 + ) + +;; definition for method 3 of type matrix4h +(defmethod inspect matrix4h ((obj matrix4h)) + (format #t "[~8x] ~A~%" obj 'matrix4h) + (format #t "~Tdata[16] @ #x~X~%" (-> obj data)) + (format #t "~Tvector4h[4] @ #x~X~%" (-> obj data)) + (format #t "~Tlong[4] @ #x~X~%" (-> obj data)) + obj + ) + +;; definition for function matrix-copy! +;; Used lq/sq +(defun matrix-copy! ((arg0 matrix) (arg1 matrix)) + (let ((v1-0 (-> arg1 vector 0 quad)) + (a2-0 (-> arg1 vector 1 quad)) + (a3-0 (-> arg1 vector 2 quad)) + (a1-1 (-> arg1 vector 3 quad)) + ) + (set! (-> arg0 vector 0 quad) v1-0) + (set! (-> arg0 vector 1 quad) a2-0) + (set! (-> arg0 vector 2 quad) a3-0) + (set! (-> arg0 vector 3 quad) a1-1) + ) + arg0 + ) + +;; failed to figure out what this is: +(none) + diff --git a/test/decompiler/reference/quaternion-h_REF.gc b/test/decompiler/reference/quaternion-h_REF.gc new file mode 100644 index 0000000000..8b53bf64e1 --- /dev/null +++ b/test/decompiler/reference/quaternion-h_REF.gc @@ -0,0 +1,41 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition of type quaternion +(deftype quaternion (structure) + ((data float 4 :offset-assert 0) + (x float :offset 0) + (y float :offset 4) + (z float :offset 8) + (w float :offset 12) + (vec vector :inline :offset 0) + (quad uint128 :offset 0) + ) + :method-count-assert 9 + :size-assert #x10 + :flag-assert #x900000010 + ) + +;; definition for method 3 of type quaternion +;; Used lq/sq +(defmethod inspect quaternion ((obj quaternion)) + (format #t "[~8x] ~A~%" obj 'quaternion) + (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) + (format #t "~Tx: ~f~%" (-> obj data 0)) + (format #t "~Ty: ~f~%" (-> obj data 1)) + (format #t "~Tz: ~f~%" (-> obj data 2)) + (format #t "~Tw: ~f~%" (-> obj data 3)) + (format #t "~Tvec: #~%" (-> obj data)) + (format #t "~Tquad: ~D~%" (-> obj vec quad)) + obj + ) + +;; definition for symbol *unity-quaternion*, type quaternion +(define *unity-quaternion* (new 'static 'quaternion :w 1.0)) + +;; failed to figure out what this is: +(let ((v0-1 0)) + ) + +;; failed to figure out what this is: +(none) diff --git a/test/decompiler/reference/transform-h_REF.gc b/test/decompiler/reference/transform-h_REF.gc new file mode 100644 index 0000000000..40f2fe6c0f --- /dev/null +++ b/test/decompiler/reference/transform-h_REF.gc @@ -0,0 +1,50 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition of type transform +(deftype transform (structure) + ((trans vector :inline :offset-assert 0) + (rot vector :inline :offset-assert 16) + (scale vector :inline :offset-assert 32) + ) + :method-count-assert 9 + :size-assert #x30 + :flag-assert #x900000030 + ) + +;; definition for method 3 of type transform +(defmethod inspect transform ((obj transform)) + (format #t "[~8x] ~A~%" obj 'transform) + (format #t "~Ttrans: ~`vector`P~%" (-> obj trans)) + (format #t "~Trot: ~`vector`P~%" (-> obj rot)) + (format #t "~Tscale: ~`vector`P~%" (-> obj scale)) + obj + ) + +;; definition of type trs +(deftype trs (basic) + ((trans vector :inline :offset-assert 16) + (rot vector :inline :offset-assert 32) + (scale vector :inline :offset-assert 48) + ) + :method-count-assert 9 + :size-assert #x40 + :flag-assert #x900000040 + ) + +;; definition for method 3 of type trs +(defmethod inspect trs ((obj trs)) + (format #t "[~8x] ~A~%" obj (-> obj type)) + (format #t "~Ttrans: ~`vector`P~%" (-> obj trans)) + (format #t "~Trot: ~`vector`P~%" (-> obj rot)) + (format #t "~Tscale: ~`vector`P~%" (-> obj scale)) + obj + ) + +;; failed to figure out what this is: +(let ((v0-2 0)) + ) + +;; failed to figure out what this is: +(none) + diff --git a/test/decompiler/reference/trigonometry-h_REF.gc b/test/decompiler/reference/trigonometry-h_REF.gc new file mode 100644 index 0000000000..e412f7e2ec --- /dev/null +++ b/test/decompiler/reference/trigonometry-h_REF.gc @@ -0,0 +1,10 @@ +;;-*-Lisp-*- +(in-package goal) + +;; failed to figure out what this is: +(let ((v0-0 0)) + ) + +;; failed to figure out what this is: +(none) + diff --git a/test/decompiler/reference/vector-h_REF.gc b/test/decompiler/reference/vector-h_REF.gc index 82a7be3637..56fd388aa1 100644 --- a/test/decompiler/reference/vector-h_REF.gc +++ b/test/decompiler/reference/vector-h_REF.gc @@ -282,9 +282,8 @@ ) ;; definition for method 3 of type vector4w -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod inspect vector4w ((obj vector4w)) - (local-vars (a2-7 int)) (format #t "[~8x] ~A~%" obj 'vector4w) (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) (format #t "~Tx: ~D~%" (-> obj data 0)) @@ -292,13 +291,7 @@ (format #t "~Tz: ~D~%" (-> obj data 2)) (format #t "~Tw: ~D~%" (-> obj data 3)) (format #t "~Tdword[2] @ #x~X~%" (-> obj data)) - (let ((t9-7 format) - (a0-8 #t) - (a1-7 "~Tquad: ~D~%") - ) - (TODO.LQ a2-7 obj) - (t9-7 a0-8 a1-7 a2-7) - ) + (format #t "~Tquad: ~D~%" (-> obj quad)) obj ) @@ -414,18 +407,11 @@ ) ;; definition for method 3 of type vector8h -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod inspect vector8h ((obj vector8h)) - (local-vars (a2-2 int)) (format #t "[~8x] ~A~%" obj 'vector8h) (format #t "~Tdata[8] @ #x~X~%" (-> obj data)) - (let ((t9-2 format) - (a0-3 #t) - (a1-2 "~Tquad: ~D~%") - ) - (TODO.LQ a2-2 obj) - (t9-2 a0-3 a1-2 a2-2) - ) + (format #t "~Tquad: ~D~%" (-> obj quad)) obj ) @@ -440,18 +426,11 @@ ) ;; definition for method 3 of type vector16b -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod inspect vector16b ((obj vector16b)) - (local-vars (a2-2 int)) (format #t "[~8x] ~A~%" obj 'vector16b) (format #t "~Tdata[8] @ #x~X~%" (-> obj data)) - (let ((t9-2 format) - (a0-3 #t) - (a1-2 "~Tquad: ~D~%") - ) - (TODO.LQ a2-2 obj) - (t9-2 a0-3 a1-2 a2-2) - ) + (format #t "~Tquad: ~D~%" (-> obj quad)) obj ) @@ -471,22 +450,15 @@ ;; definition for method 3 of type vector ;; INFO: this function exists in multiple non-identical object files -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod inspect vector ((obj vector)) - (local-vars (a2-6 int)) (format #t "[~8x] ~A~%" obj 'vector) (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) (format #t "~Tx: ~f~%" (-> obj data 0)) (format #t "~Ty: ~f~%" (-> obj data 1)) (format #t "~Tz: ~f~%" (-> obj data 2)) (format #t "~Tw: ~f~%" (-> obj data 3)) - (let ((t9-6 format) - (a0-7 #t) - (a1-6 "~Tquad: ~D~%") - ) - (TODO.LQ a2-6 obj) - (t9-6 a0-7 a1-6 a2-6) - ) + (format #t "~Tquad: ~D~%" (-> obj quad)) obj ) @@ -590,22 +562,15 @@ ) ;; definition for method 3 of type rgbaf -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod inspect rgbaf ((obj rgbaf)) - (local-vars (a2-6 int)) (format #t "[~8x] ~A~%" obj 'rgbaf) (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) (format #t "~Tx: ~f~%" (-> obj data 0)) (format #t "~Ty: ~f~%" (-> obj data 1)) (format #t "~Tz: ~f~%" (-> obj data 2)) (format #t "~Tw: ~f~%" (-> obj data 3)) - (let ((t9-6 format) - (a0-7 #t) - (a1-6 "~Tquad: ~D~%") - ) - (TODO.LQ a2-6 obj) - (t9-6 a0-7 a1-6 a2-6) - ) + (format #t "~Tquad: ~D~%" (-> obj quad)) (format #t "~Tr: ~f~%" (-> obj data 0)) (format #t "~Tg: ~f~%" (-> obj data 1)) (format #t "~Tb: ~f~%" (-> obj data 2)) @@ -626,22 +591,15 @@ ) ;; definition for method 3 of type plane -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod inspect plane ((obj plane)) - (local-vars (a2-6 int)) (format #t "[~8x] ~A~%" obj 'plane) (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) (format #t "~Tx: ~f~%" (-> obj data 0)) (format #t "~Ty: ~f~%" (-> obj data 1)) (format #t "~Tz: ~f~%" (-> obj data 2)) (format #t "~Tw: ~f~%" (-> obj data 3)) - (let ((t9-6 format) - (a0-7 #t) - (a1-6 "~Tquad: ~D~%") - ) - (TODO.LQ a2-6 obj) - (t9-6 a0-7 a1-6 a2-6) - ) + (format #t "~Tquad: ~D~%" (-> obj quad)) (format #t "~Ta: ~f~%" (-> obj data 0)) (format #t "~Tb: ~f~%" (-> obj data 1)) (format #t "~Tc: ~f~%" (-> obj data 2)) @@ -659,22 +617,15 @@ ) ;; definition for method 3 of type sphere -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod inspect sphere ((obj sphere)) - (local-vars (a2-6 int)) (format #t "[~8x] ~A~%" obj 'sphere) (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) (format #t "~Tx: ~f~%" (-> obj data 0)) (format #t "~Ty: ~f~%" (-> obj data 1)) (format #t "~Tz: ~f~%" (-> obj data 2)) (format #t "~Tw: ~f~%" (-> obj data 3)) - (let ((t9-6 format) - (a0-7 #t) - (a1-6 "~Tquad: ~D~%") - ) - (TODO.LQ a2-6 obj) - (t9-6 a0-7 a1-6 a2-6) - ) + (format #t "~Tquad: ~D~%" (-> obj quad)) (format #t "~Tr: ~f~%" (-> obj data 3)) obj ) @@ -834,22 +785,15 @@ ) ;; definition for method 3 of type qword -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] +;; Used lq/sq (defmethod inspect qword ((obj qword)) - (local-vars (a2-6 int)) (format #t "[~8x] ~A~%" obj 'qword) (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) (format #t "~Tbyte[16] @ #x~X~%" (-> obj data)) (format #t "~Thword[8] @ #x~X~%" (-> obj data)) (format #t "~Tword[4] @ #x~X~%" (-> obj data)) (format #t "~Tdword[2] @ #x~X~%" (-> obj data)) - (let ((t9-6 format) - (a0-7 #t) - (a1-6 "~Tquad: ~D~%") - ) - (TODO.LQ a2-6 obj) - (t9-6 a0-7 a1-6 a2-6) - ) + (format #t "~Tquad: ~D~%" (-> obj quad)) (format #t "~Tvector: #~%" (-> obj data)) (format #t "~Tvector4w: #~%" (-> obj data)) obj @@ -999,10 +943,9 @@ ) ;; definition for function vector-zero! -;; WARN: Inline assembly instruction marked with TODO - [TODO.SQ] +;; Used lq/sq (defun vector-zero! ((arg0 vector)) - (local-vars (r0-0 none)) - (TODO.SQ r0-0 arg0) + (set! (-> arg0 quad) (the-as uint128 0)) arg0 ) @@ -1016,12 +959,9 @@ ) ;; definition for function vector-copy! -;; WARN: Inline assembly instruction marked with TODO - [TODO.LQ] -;; WARN: Inline assembly instruction marked with TODO - [TODO.SQ] +;; Used lq/sq (defun vector-copy! ((arg0 vector) (arg1 vector)) - (local-vars (v1-0 int)) - (TODO.LQ v1-0 arg1) - (TODO.SQ v1-0 arg0) + (set! (-> arg0 quad) (-> arg1 quad)) arg0 ) diff --git a/test/decompiler/test_AtomicOpBuilder.cpp b/test/decompiler/test_AtomicOpBuilder.cpp index a518f35634..d31ebc2787 100644 --- a/test/decompiler/test_AtomicOpBuilder.cpp +++ b/test/decompiler/test_AtomicOpBuilder.cpp @@ -1,10 +1,11 @@ +#include #include "gtest/gtest.h" #include "decompiler/IR2/AtomicOp.h" #include "decompiler/analysis/atomic_op_builder.h" #include "decompiler/Disasm/InstructionParser.h" #include "third-party/fmt/core.h" #include "third-party/fmt/format.h" -#include +#include "decompiler/Function/Warnings.h" using namespace decompiler; @@ -42,8 +43,9 @@ void test_case(std::string assembly_lines, FunctionAtomicOps container; // treat the entire program as a single basic block, and convert! + DecompWarnings warnings; convert_block_to_atomic_ops(0, prg.instructions.begin(), prg.instructions.end(), prg.labels, - &container); + &container, warnings); // count operations EXPECT_EQ(container.ops.size(), output_lines.size()); @@ -126,8 +128,9 @@ TEST(DecompilerAtomicOpBuilder, RegUseDuplication) { ParsedProgram prg = parser.parse_program(assembly); EXPECT_EQ(prg.print(), assembly); FunctionAtomicOps container; + DecompWarnings warnings; convert_block_to_atomic_ops(0, prg.instructions.begin(), prg.instructions.end(), prg.labels, - &container); + &container, warnings); ASSERT_EQ(1, container.ops.size()); auto& op = container.ops.at(0); for (const auto& reg_group : {op->read_regs(), op->write_regs(), op->clobber_regs()}) { diff --git a/test/decompiler/test_FormExpressionBuild.cpp b/test/decompiler/test_FormExpressionBuild.cpp index 164bc58f85..92db303ec3 100644 --- a/test/decompiler/test_FormExpressionBuild.cpp +++ b/test/decompiler/test_FormExpressionBuild.cpp @@ -2618,8 +2618,10 @@ TEST_F(FormRegressionTest, QMemCpy) { " (+! v1-1 -1)\n" " (&+! a0-1 -16)\n" " (&+! a1-1 -16)\n" - " (.lq a2-3 0 a1-1)\n" - " (.sq a2-3 0 a0-1)\n" + " (set!\n" + " (-> (the-as (pointer uint128) a0-1))\n" + " (-> (the-as (pointer uint128) a1-1))\n" + " )\n" " )\n" " )\n" " v0-0\n" diff --git a/test/decompiler/test_FormExpressionBuildLong.cpp b/test/decompiler/test_FormExpressionBuildLong.cpp index 8cd8215747..697da1132e 100644 --- a/test/decompiler/test_FormExpressionBuildLong.cpp +++ b/test/decompiler/test_FormExpressionBuildLong.cpp @@ -627,18 +627,15 @@ TEST_F(FormRegressionTest, ExprArrayMethod2) { " (else\n" " (cond\n" " ((or (= v1-1 (quote uint128)) (= v1-1 (quote int128)))\n" - " (dotimes\n" - " (s5-8 (-> arg0 length))\n" - " (let\n" - " ((t9-10 format) (a0-21 #t) (a1-11 (if (zero? s5-8) \"#x~X\" \" #x~X\")))\n" - " (let\n" - " ((v1-42 (+ (shl s5-8 4) (the-as int (the-as (array uint128) arg0)))))\n" - " (.lq a2-8 12 v1-42)\n" - " )\n" - " (t9-10 a0-21 a1-11 a2-8)\n" + " (dotimes (s5-8 (-> arg0 length))\n" + " (format #t (if (zero? s5-8)\n" + " \"#x~X\"\n" + " \" #x~X\"\n" + " )\n" + " (-> (the-as (array uint128) arg0) s5-8)\n" " )\n" " )\n" - " )\n" + " )" " (else\n" " (dotimes\n" " (s5-9 (-> arg0 length))\n" @@ -1223,18 +1220,15 @@ TEST_F(FormRegressionTest, ExprArrayMethod3) { " (else\n" " (cond\n" " ((or (= v1-1 (quote int128)) (= v1-1 (quote uint128)))\n" - " (dotimes\n" - " (s5-8 (-> arg0 length))\n" - " (let\n" - " ((t9-14 format) (a0-25 #t) (a1-15 \"~T [~D] #x~X~%\") (a2-13 s5-8))\n" - " (let\n" - " ((v1-42 (+ (shl s5-8 4) (the-as int (the-as (array uint128) arg0)))))\n" - " (.lq a3-10 12 v1-42)\n" - " )\n" - " (t9-14 a0-25 a1-15 a2-13 a3-10)\n" + " (dotimes (s5-8 (-> arg0 length))\n" + " (format\n" + " #t\n" + " \"~T [~D] #x~X~%\"\n" + " s5-8\n" + " (-> (the-as (array uint128) arg0) s5-8)\n" " )\n" " )\n" - " )\n" + " )" " (else\n" " (dotimes\n" " (s5-9 (-> arg0 length))\n" diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index fc94a8f915..a6a705454a 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -10,25 +10,35 @@ namespace { // the object files to test -const std::unordered_set g_object_files_to_decompile = {"gcommon", - "gstring-h", - "gkernel-h", - "gkernel", - /*"pskernel",*/ "gstring", - "dgo-h", - "gstate", - "types-h", - "vu1-macros", - "math", - "vector-h", - "bounding-box-h", - /* gap */ "bounding-box"}; +const std::unordered_set g_object_files_to_decompile = { + "gcommon", "gstring-h", "gkernel-h", "gkernel", + /*"pskernel",*/ "gstring", "dgo-h", "gstate", "types-h", "vu1-macros", "math", "vector-h", + "bounding-box-h", "matrix-h", "quaternion-h", "euler-h", "transform-h", "geometry-h", + "trigonometry-h", + /* gap */ + "bounding-box"}; // the object files to check against a reference in test/decompiler/reference const std::vector g_object_files_to_check_against_reference = { "gcommon", // NOTE: this file needs work, but adding it for now just to test the framework. - "gstring-h", "gkernel-h", "gkernel", "gstring", "dgo-h", "gstate", - "types-h", "vu1-macros", "math", "vector-h", "bounding-box-h", /* gap */ "bounding-box"}; + "gstring-h", + "gkernel-h", + "gkernel", + "gstring", + "dgo-h", + "gstate", + "types-h", + "vu1-macros", + "math", + "vector-h", + "bounding-box-h", + "matrix-h", + "quaternion-h", + "euler-h", + "transform-h", + "geometry-h", + "trigonometry-h", + /* gap */ "bounding-box"}; // the functions we expect the decompiler to skip const std::unordered_set expected_skip_in_decompiler = { @@ -64,10 +74,8 @@ const std::unordered_set skip_in_compiling = { "abs", "ash", "min", "max", "lognor", // weird PS2 specific debug registers: "breakpoint-range-set!", - // these require 128-bit integers. We want these eventually, but disabling for now to focus - // on more important issues. - "(method 3 vec4s)", "(method 2 vec4s)", "qmem-copy<-!", "qmem-copy->!", "(method 2 array)", - "(method 3 array)", + // int128 fancy stuff. + "(method 3 vec4s)", "(method 2 vec4s)", // does weird stuff with the type system. "print", "printl", "inspect", // inline assembly @@ -89,18 +97,9 @@ const std::unordered_set skip_in_compiling = { "log2", // weird tricky int-as-float stuff /// VECTOR-H - "(method 3 vector4w)", // print quad - "(method 3 vector8h)", // print quad - "(method 3 vector16b)", // print quad - "(method 3 vector)", // print quad - "(method 3 rgbaf)", // print quad - "(method 3 plane)", // print quad - "(method 3 sphere)", // print quad - "(method 3 qword)", // print quad - "vector-zero!", // i128 - "vector-copy!", // i128 - "vector-dot", // fpu acc - "vector4-dot", // fpu acc + "(method 3 vector)", // this function appears twice, which confuses the compiler. + "vector-dot", // fpu acc + "vector4-dot", // fpu acc }; // default location for the data. It can be changed with a command line argument.