diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..000d64f312 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "cwd": "${workspaceFolder}/scripts" + } + ] +} \ No newline at end of file diff --git a/decompiler/IR2/AtomicOp.cpp b/decompiler/IR2/AtomicOp.cpp index c02f8e358c..886ddcd26b 100644 --- a/decompiler/IR2/AtomicOp.cpp +++ b/decompiler/IR2/AtomicOp.cpp @@ -198,11 +198,11 @@ std::string get_simple_expression_op_name(SimpleExpression::Kind kind) { case SimpleExpression::Kind::DIV_SIGNED: return "/.si"; case SimpleExpression::Kind::MOD_SIGNED: - return "%.si"; + return "mod.si"; case SimpleExpression::Kind::DIV_UNSIGNED: return "/.ui"; case SimpleExpression::Kind::MOD_UNSIGNED: - return "%.ui"; + return "mod.ui"; case SimpleExpression::Kind::OR: return "logior"; case SimpleExpression::Kind::AND: @@ -212,7 +212,7 @@ std::string get_simple_expression_op_name(SimpleExpression::Kind kind) { case SimpleExpression::Kind::XOR: return "logxor"; case SimpleExpression::Kind::LEFT_SHIFT: - return "shl"; + return "sll"; case SimpleExpression::Kind::RIGHT_SHIFT_ARITH: return "sra"; case SimpleExpression::Kind::RIGHT_SHIFT_LOGIC: diff --git a/scripts/gen-test-cases.py b/scripts/gen-test-cases.py index 9ff28970f7..28b5081d0e 100644 --- a/scripts/gen-test-cases.py +++ b/scripts/gen-test-cases.py @@ -8,26 +8,40 @@ content = [x.strip() for x in content] test_cases = {} +# TODO - there is a bug in this code if we add test-cases with multiple lists of registers. +# currently, its going to split too much breaking fragile assumptions. Fix when required + for case in content: + if not case: + continue + args = re.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", case) - assembly_lines = args[0].replace("\"", "").strip().split("\\n") - main_instruction = assembly_lines[0].split(" ")[0] - if re.match("^L\d*:\s*$", main_instruction): - main_instruction = assembly_lines[1].strip().split(" ")[0] - main_instruction = main_instruction.upper().replace(".", "_") + assembly_lines = args[0].replace("\\n\"", "").replace("\"", "").strip().split("\\n") + + instruction_summary = "" + instructions = [] + for line in assembly_lines: + if not re.match("^L\d*:\s*$", line): + instructions.append(line.strip().split(" ")[0].upper().replace(".", "")) + instruction_summary = "_".join(instructions) + assembly_lines = "{{{}}}".format(", ".join(["\"{}\"".format(x.replace("\\n", "").strip()) for x in assembly_lines])) output_lines = args[1].replace("\\n", "").strip() - write_regs = "{{{}}}".format(args[2].replace("\\n", "").strip().replace(" ", "\",\"")) - read_regs = "{{{}}}".format(args[3].replace("\\n", "").strip().replace(" ", "\",\"")) - clob_regs = "{{{}}}".format(args[4].replace("\\n", "").strip().replace(" ", "\",\"")) + write_regs = "{{{}}}".format(args[2].replace("\\n", "").strip().replace("\"\"", "").replace(" ", "\",\"")) + read_regs = "{{{}}}".format(args[3].replace("\\n", "").strip().replace("\"\"", "").replace(" ", "\",\"")) + clob_regs = "{{{}}}".format(args[4].replace("\\n", "").strip().replace("\"\"", "").replace(" ", "\",\"")) test_case = "test_case(assembly_from_list({}), {}, {}, {}, {});".format(assembly_lines, output_lines, write_regs, read_regs, clob_regs); - if main_instruction in test_cases: - test_cases[main_instruction].append(test_case) + if instruction_summary in test_cases: + test_cases[instruction_summary].append(test_case) else: - test_cases[main_instruction] = [] - test_cases[main_instruction].append(test_case) + test_cases[instruction_summary] = [] + test_cases[instruction_summary].append(test_case) + +import os +if os.path.exists("test-cases.cpp"): + os.remove("test-cases.cpp") with open("test-cases.cpp", "a") as f: instructions = test_cases.keys() diff --git a/scripts/test-cases.cpp b/scripts/test-cases.cpp new file mode 100644 index 0000000000..70ae2a77f0 --- /dev/null +++ b/scripts/test-cases.cpp @@ -0,0 +1,48 @@ +TEST(DecompilerAtomicOpBuilder, BEQ) {test_case(assembly_from_list({"L100:", "beq a0, a1, L100", "sll r0, r0, 0", ""}), {"(b! (= a0 a1) L100 (nop!))"}, {{""}}, {{"a0","a1"}}, {{""}});test_case(assembly_from_list({"L100:", "beq r0, r0, L100", "sll r0, r0, 0", ""}), {"(b! #t L100 (nop!))"}, {{""}}, {{""}}, {{""}});test_case(assembly_from_list({"L100:", "beq a0, r0, L100", "sll r0, r0, 0", ""}), {"(b! (zero? a0) L100 (nop!))"}, {{""}}, {{"a0"}}, {{""}});test_case(assembly_from_list({"L100:", "beq s7, a0, L100", "sll r0, r0, 0", ""}), {"(b! (not a0) L100 (nop!))"}, {{""}}, {{"a0"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, BEQL) {test_case(assembly_from_list({"L100:", "beql a0, a1, L100", "sll r0, r0, 0", ""}), {"(bl! (= a0 a1) L100 (nop!))"}, {{""}}, {{"a0","a1"}}, {{""}});test_case(assembly_from_list({"L100:", "beql r0, r0, L100", "sll r0, r0, 0", ""}), {"(bl! #t L100 (nop!))"}, {{""}}, {{""}}, {{""}});test_case(assembly_from_list({"L100:", "beql a0, r0, L100", "sll r0, r0, 0", ""}), {"(bl! (zero? a0) L100 (nop!))"}, {{""}}, {{"a0"}}, {{""}});test_case(assembly_from_list({"L100:", "beql s7, a0, L100", "sll r0, r0, 0", ""}), {"(bl! (not a0) L100 (nop!))"}, {{""}}, {{"a0"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, BGEZL) {test_case(assembly_from_list({"L100:", "bgezl a0, L100", "sll r0, r0, 0", ""}), {"(bl! (>=0.si a0) L100 (nop!))"}, {{""}}, {{"a0"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, BGTZL) {test_case(assembly_from_list({"L100:", "bgtzl a0, L100", "sll r0, r0, 0", ""}), {"(bl! (>0.si a0) L100 (nop!))"}, {{""}}, {{"a0"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, BLTZL) {test_case(assembly_from_list({"L100:", "bltzl a0, L100", "sll r0, r0, 0", ""}), {"(bl! (<0.si a0) L100 (nop!))"}, {{""}}, {{"a0"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, BNE) {test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "sll r0, r0, 0", ""}), {"(b! (!= a1 a2) L100 (nop!))"}, {{""}}, {{"a1","a2"}}, {{""}});test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "or a3, s7, r0", ""}), {"(b! (!= a1 a2) L100 (set! a3 #f))"}, {{"a3"}}, {{"a1","a2"}}, {{""}});test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "or a3, t0, r0", ""}), {"(b! (!= a1 a2) L100 (set! a3 t0))"}, {{"a3"}}, {{"a1","a2","t0"}}, {{""}});test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "daddiu a3, s7, 8", ""}), {"(b! (!= a1 a2) L100 (set! a3 #t))"}, {{"a3"}}, {{"a1","a2"}}, {{""}});test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "lw a3, pair(s7)", ""}), {"(b! (!= a1 a2) L100 (set! a3 pair))"}, {{"a3"}}, {{"a1","a2"}}, {{""}});test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "lw a3, binteger(s7)", ""}), {"(b! (!= a1 a2) L100 (set! a3 binteger))"}, {{"a3"}}, {{"a1","a2"}}, {{""}});test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "dsllv a3, t0, t1", ""}), {"(b! (!= a1 a2) L100 (set! a3 (sll t0 t1)))"}, {{"a3"}}, {{"a1","a2","t0","t1"}}, {{""}});test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "dsubu a3, r0, t1", ""}), {"(b! (!= a1 a2) L100 (set! a3 (- t1)))"}, {{"a3"}}, {{"a1","a2","","t1"}}, {{""}});test_case(assembly_from_list({"L100:", "bne a1, r0, L100", "sll r0, r0, 0", ""}), {"(b! (nonzero? a1) L100 (nop!))"}, {{""}}, {{"a1"}}, {{""}});test_case(assembly_from_list({"L100:", "bne s7, a1, L100", "sll r0, r0, 0", ""}), {"(b! (truthy a1) L100 (nop!))"}, {{""}}, {{"a1"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, BNEL) {test_case(assembly_from_list({"L100:", "bnel a1, a2, L100", "sll r0, r0, 0", ""}), {"(bl! (!= a1 a2) L100 (nop!))"}, {{""}}, {{"a1","a2"}}, {{""}});test_case(assembly_from_list({"L100:", "bnel a1, r0, L100", "sll r0, r0, 0", ""}), {"(bl! (nonzero? a1) L100 (nop!))"}, {{""}}, {{"a1"}}, {{""}});test_case(assembly_from_list({"L100:", "bnel s7, a1, L100", "sll r0, r0, 0", ""}), {"(bl! (truthy a1) L100 (nop!))"}, {{""}}, {{"a1"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, C_EQ_S) {test_case(assembly_from_list({"L100:", "c.eq.s f1, f2", "bc1t L100", "sll r0, r0, 0", ""}), {"(b! (=.s f1 f2) L100 (nop!))"}, {{""}}, {{"f1","f2"}}, {{""}});test_case(assembly_from_list({"L100:", "c.eq.s f1, f2", "bc1f L100", "sll r0, r0, 0", ""}), {"(b! (!=.s f1 f2) L100 (nop!))"}, {{""}}, {{"f1","f2"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, C_LE_S) {test_case(assembly_from_list({"L100:", "c.le.s f1, f2", "bc1t L100", "sll r0, r0, 0", ""}), {"(b! (<=.s f1 f2) L100 (nop!))"}, {{""}}, {{"f1","f2"}}, {{""}});test_case(assembly_from_list({"L100:", "c.le.s f1, f2", "bc1f L100", "sll r0, r0, 0", ""}), {"(b! (>.s f1 f2) L100 (nop!))"}, {{""}}, {{"f1","f2"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, C_LT_S) {test_case(assembly_from_list({"L100:", "c.lt.s f1, f2", "bc1t L100", "sll r0, r0, 0", ""}), {"(b! (<.s f1 f2) L100 (nop!))"}, {{""}}, {{"f1","f2"}}, {{""}});test_case(assembly_from_list({"L100:", "c.lt.s f1, f2", "bc1f L100", "sll r0, r0, 0", ""}), {"(b! (>=.s f1 f2) L100 (nop!))"}, {{""}}, {{"f1","f2"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, DADDIU) {test_case(assembly_from_list({"daddiu a1, s7, 8", "movn a1, s7, a0", ""}), {"(set! a1 (zero? a0))"}, {{"a1"}}, {{"a0"}}, {{""}});test_case(assembly_from_list({"daddiu a1, s7, 8", "movz a1, s7, a0", ""}), {"(set! a1 (nonzero? a0))"}, {{"a1"}}, {{"a0"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, DADDU) {test_case(assembly_from_list({"daddu v1, r0, v0", ""}), {"(set! v1 (+ v0 0))"}, {{"v1"}}, {{"v0"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, DIV) {test_case(assembly_from_list({"div a1, a2", "mflo a3", ""}), {"(set! a3 (/.si a1 a2))"}, {{"a3"}}, {{"a1","a2"}}, {{""}});test_case(assembly_from_list({"div a1, a2", "mfhi a3", ""}), {"(set! a3 (mod.si a1 a2))"}, {{"a3"}}, {{"a1","a2"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, DIVU) {test_case(assembly_from_list({"divu a1, a2", "mflo a3", ""}), {"(set! a3 (/.ui a1 a2))"}, {{"a3"}}, {{"a1","a2"}}, {{""}});test_case(assembly_from_list({"divu a1, a2", "mfhi a3", ""}), {"(set! a3 (mod.ui a1 a2))"}, {{"a3"}}, {{"a1","a2"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, DSLL32) {test_case(assembly_from_list({"L100:", "dsll32 v1, s4, 30", "slt v1, v1, r0", "beq v1, r0, L100", "sll r0, r0, 0", ""}), {"(b! (not-pair? s4) L100 (nop!))"}, {{""}}, {{"s4"}}, {{"v1"}});} + +TEST(DecompilerAtomicOpBuilder, DSUBU) {test_case(assembly_from_list({"dsubu a0, a1, a2", "daddiu t0, s7, 8", "movn t0, s7, a0", ""}), {"(set! t0 (= a1 a2))"}, {{"t0"}}, {{"a1","a2"}}, {{"a0"}});test_case(assembly_from_list({"dsubu a0, a1, a2", "daddiu t0, s7, 8", "movz t0, s7, a0", ""}), {"(set! t0 (!= a1 a2))"}, {{"t0"}}, {{"a1","a2"}}, {{"a0"}});} + +TEST(DecompilerAtomicOpBuilder, JALR) {test_case(assembly_from_list({"jalr ra, t9", "sll v0, ra, 0", ""}), {"(call!)"}, {{""}}, {{"t9"}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, LUI) {test_case(assembly_from_list({"L100:", "lui a0, 2", "ori a1, a0, 3", ""}), {"(set! a1 131075)"}, {{"a1"}}, {{""}}, {{"a0"}});test_case(assembly_from_list({"L100:", "lui a0, 2", "ori a0, a0, 3", ""}), {"(set! a0 131075)"}, {{"a0"}}, {{""}}, {{""}});test_case(assembly_from_list({"L100:", "lui a0, L100", "ori a1, a0, L100", ""}), {"(set! a1 L100)"}, {{"a1"}}, {{""}}, {{"a0"}});test_case(assembly_from_list({"L100:", "lui a0, L100", "ori a0, a0, L100", ""}), {"(set! a0 L100)"}, {{"a0"}}, {{""}}, {{""}});test_case(assembly_from_list({"L100:", "lui a0, L100", "ori a1, a0, L100", "addu a1, fp, a1", ""}), {"(set! a1 L100)"}, {{"a1"}}, {{""}}, {{"a0"}});test_case(assembly_from_list({"L100:", "lui a1, L100", "ori a1, a1, L100", "addu a1, fp, a1", ""}), {"(set! a1 L100)"}, {{"a1"}}, {{""}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, MTC1) {test_case(assembly_from_list({"mtc1 f3, r0", ""}), {"(set! f3 0)"}, {{"f3"}}, {{""}}, {{""}});} + +TEST(DecompilerAtomicOpBuilder, SLT) {test_case(assembly_from_list({"slt a0, a1, a2", "movz a1, a2, a0", ""}), {"(set! a1 (min.si a1 a2))"}, {{"a1"}}, {{"a1","a2"}}, {{"a0"}});test_case(assembly_from_list({"slt a0, a1, a2", "movn a1, a2, a0", ""}), {"(set! a1 (max.si a1 a2))"}, {{"a1"}}, {{"a1","a2"}}, {{"a0"}});test_case(assembly_from_list({"L100:", "slt a3, a0, a1", "bne a3, r0, L100", "or a3, s7, r0", ""}), {"(b! (<.si a0 a1) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0","a1"}}, {{""}});test_case(assembly_from_list({"L100:", "slt a3, a0, a1", "bne a3, r0, L100", "or a2, s7, r0", ""}), {"(b! (<.si a0 a1) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0","a1"}}, {{"a3"}});test_case(assembly_from_list({"L100:", "slt a3, a0, a1", "beq a3, r0, L100", "or a3, s7, r0", ""}), {"(b! (>=.si a0 a1) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0","a1"}}, {{""}});test_case(assembly_from_list({"L100:", "slt a3, a0, a1", "beq a3, r0, L100", "or a2, s7, r0", ""}), {"(b! (>=.si a0 a1) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0","a1"}}, {{"a3"}});test_case(assembly_from_list({"slt a3, a0, a1", "daddiu a2, s7, 8", "movz a2, s7, a3", ""}), {"(set! a2 (<.si a0 a1))"}, {{"a2"}}, {{"a0","a1"}}, {{"a3"}});test_case(assembly_from_list({"slt a3, a0, r0", "daddiu a2, s7, 8", "movz a2, s7, a3", ""}), {"(set! a2 (<0.si a0))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});test_case(assembly_from_list({"slt a3, a0, a1", "daddiu a2, s7, 8", "movn a2, s7, a3", ""}), {"(set! a2 (>=.si a0 a1))"}, {{"a2"}}, {{"a0","a1"}}, {{"a3"}});test_case(assembly_from_list({"slt a3, a0, r0", "daddiu a2, s7, 8", "movn a2, s7, a3", ""}), {"(set! a2 (>=0.si a0))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});test_case(assembly_from_list({"slt a3, r0, a0", "daddiu a2, s7, 8", "movz a2, s7, a3", ""}), {"(set! a2 (>0.si a0))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});test_case(assembly_from_list({"L100:", "slt v1, s2, r0", "beq v1, r0, L100", "or v1, s7, r0", ""}), {"(b! (>=0.si s2) L100 (set! v1 #f))"}, {{"v1"}}, {{"s2"}}, {{""}});test_case(assembly_from_list({"L100:", "slt v1, s2, r0", "beq v1, r0, L100", "or v0, s7, r0", ""}), {"(b! (>=0.si s2) L100 (set! v0 #f))"}, {{"v0"}}, {{"s2"}}, {{"v1"}});} + +TEST(DecompilerAtomicOpBuilder, SLTI) {test_case(assembly_from_list({"L100:", "slti a3, a0, 12", "bne a3, r0, L100", "or a3, s7, r0", ""}), {"(b! (<.si a0 12) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0"}}, {{""}});test_case(assembly_from_list({"L100:", "slti a3, a0, 12", "bne a3, r0, L100", "or a2, s7, r0", ""}), {"(b! (<.si a0 12) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});test_case(assembly_from_list({"L100:", "slti a3, a0, 12", "beq a3, r0, L100", "or a3, s7, r0", ""}), {"(b! (>=.si a0 12) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0"}}, {{""}});test_case(assembly_from_list({"L100:", "slti a3, a0, 12", "beq a3, r0, L100", "or a2, s7, r0", ""}), {"(b! (>=.si a0 12) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});test_case(assembly_from_list({"slti a3, a0, 12", "daddiu a2, s7, 8", "movz a2, s7, a3", ""}), {"(set! a2 (<.si a0 12))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});test_case(assembly_from_list({"slti a3, a0, 12", "daddiu a2, s7, 8", "movn a2, s7, a3", ""}), {"(set! a2 (>=.si a0 12))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});} + +TEST(DecompilerAtomicOpBuilder, SLTIU) {test_case(assembly_from_list({"L100:", "sltiu a3, a0, 12", "bne a3, r0, L100", "or a3, s7, r0", ""}), {"(b! (<.ui a0 12) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0"}}, {{""}});test_case(assembly_from_list({"L100:", "sltiu a3, a0, 12", "bne a3, r0, L100", "or a2, s7, r0", ""}), {"(b! (<.ui a0 12) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});test_case(assembly_from_list({"L100:", "sltiu a3, a0, 12", "beq a3, r0, L100", "or a3, s7, r0", ""}), {"(b! (>=.ui a0 12) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0"}}, {{""}});test_case(assembly_from_list({"L100:", "sltiu a3, a0, 12", "beq a3, r0, L100", "or a2, s7, r0", ""}), {"(b! (>=.ui a0 12) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});test_case(assembly_from_list({"sltiu a3, a0, 12", "daddiu a2, s7, 8", "movz a2, s7, a3", ""}), {"(set! a2 (<.ui a0 12))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});test_case(assembly_from_list({"sltiu a3, a0, 12", "daddiu a2, s7, 8", "movn a2, s7, a3", ""}), {"(set! a2 (>=.ui a0 12))"}, {{"a2"}}, {{"a0"}}, {{"a3"}});} + +TEST(DecompilerAtomicOpBuilder, SLTU) {test_case(assembly_from_list({"sltu a0, a1, a2", "movz a1, a2, a0", ""}), {"(set! a1 (min.ui a1 a2))"}, {{"a1"}}, {{"a1","a2"}}, {{"a0"}});test_case(assembly_from_list({"sltu a0, a1, a2", "movn a1, a2, a0", ""}), {"(set! a1 (max.ui a1 a2))"}, {{"a1"}}, {{"a1","a2"}}, {{"a0"}});test_case(assembly_from_list({"L100:", "sltu a3, a0, a1", "bne a3, r0, L100", "or a3, s7, r0", ""}), {"(b! (<.ui a0 a1) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0","a1"}}, {{""}});test_case(assembly_from_list({"L100:", "sltu a3, a0, a1", "bne a3, r0, L100", "or a2, s7, r0", ""}), {"(b! (<.ui a0 a1) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0","a1"}}, {{"a3"}});test_case(assembly_from_list({"L100:", "sltu a3, a0, a1", "beq a3, r0, L100", "or a3, s7, r0", ""}), {"(b! (>=.ui a0 a1) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0","a1"}}, {{""}});test_case(assembly_from_list({"L100:", "sltu a3, a0, a1", "beq a3, r0, L100", "or a2, s7, r0", ""}), {"(b! (>=.ui a0 a1) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0","a1"}}, {{"a3"}});test_case(assembly_from_list({"sltu a3, a0, a1", "daddiu a2, s7, 8", "movz a2, s7, a3", ""}), {"(set! a2 (<.ui a0 a1))"}, {{"a2"}}, {{"a0","a1"}}, {{"a3"}});test_case(assembly_from_list({"sltu a3, a0, a1", "daddiu a2, s7, 8", "movn a2, s7, a3", ""}), {"(set! a2 (>=.ui a0 a1))"}, {{"a2"}}, {{"a0","a1"}}, {{"a3"}});} + +TEST(DecompilerAtomicOpBuilder, SW) {test_case(assembly_from_list({"sw r0, test(s7)", ""}), {"(s.w! test 0)"}, {{""}}, {{""}}, {{""}});test_case(assembly_from_list({"sw r0, 2(a3)", ""}), {"(s.w! (+ a3 2) 0)"}, {{""}}, {{"a3"}}, {{""}});test_case(assembly_from_list({"sw r0, 0(a3)", ""}), {"(s.w! a3 0)"}, {{""}}, {{"a3"}}, {{""}});} + diff --git a/scripts/test-cases.txt b/scripts/test-cases.txt new file mode 100644 index 0000000000..9df97599ba --- /dev/null +++ b/scripts/test-cases.txt @@ -0,0 +1,183 @@ +" or a1, a2, a3\n", {"(set! a1 (logior a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" or a2, r0, r0\n", {"(set! a2 0)"}, {"a2"}, {""}, {""} +" or a1, s7, r0\n", {"(set! a1 '#f)"}, {"a1"}, {""}, {""} +" ori a2, r0, 1234\n", {"(set! a2 1234)"}, {"a2"}, {""}, {""} +" ori a2, r0, -1234\n", {"(set! a2 -1234)"}, {"a2"}, {""}, {""} +" ori a2, a3, -1234\n", {"(set! a2 (logior a3 -1234))"}, {"a2"}, {"a3"}, {""} +" mtc1 f3, a1\n", {"(set! f3 (gpr->fpr a1))"}, {"f3"}, {"a1"}, {""} +" mfc1 a1, f3\n", {"(set! a1 (fpr->gpr f3))"}, {"a1"}, {"f3"}, {""} +" and a1, a2, a3\n", {"(set! a1 (logand a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +"L123:\n lwc1 f3, L123(fp)\n", {"(set! f3 (l.f L123))"}, {"f3"}, {""}, {""} +" lwc1 f2, 0(a3)\n", {"(set! f2 (l.f a3))"}, {"f2"}, {"a3"}, {""} +" lwc1 f2, 12(a3)\n", {"(set! f2 (l.f (+ a3 12)))"}, {"f2"}, {"a3"}, {""} +"L123:\n lb a3, L123(fp)\n", {"(set! a3 (l.b L123))"}, {"a3"}, {""}, {""} +" lb a2, 0(a3)\n", {"(set! a2 (l.b a3))"}, {"a2"}, {"a3"}, {""} +" lb a2, 12(a3)\n", {"(set! a2 (l.b (+ a3 12)))"}, {"a2"}, {"a3"}, {""} +"L123:\n lbu a3, L123(fp)\n", {"(set! a3 (l.bu L123))"}, {"a3"}, {""}, {""} +" lbu a2, 0(a3)\n", {"(set! a2 (l.bu a3))"}, {"a2"}, {"a3"}, {""} +" lbu a2, 12(a3)\n", {"(set! a2 (l.bu (+ a3 12)))"}, {"a2"}, {"a3"}, {""} +"L123:\n lh a3, L123(fp)\n", {"(set! a3 (l.h L123))"}, {"a3"}, {""}, {""} +" lh a2, 0(a3)\n", {"(set! a2 (l.h a3))"}, {"a2"}, {"a3"}, {""} +" lh a2, 12(a3)\n", {"(set! a2 (l.h (+ a3 12)))"}, {"a2"}, {"a3"}, {""} +"L123:\n lhu a3, L123(fp)\n", {"(set! a3 (l.hu L123))"}, {"a3"}, {""}, {""} +" lhu a2, 0(a3)\n", {"(set! a2 (l.hu a3))"}, {"a2"}, {"a3"}, {""} +" lhu a2, 12(a3)\n", {"(set! a2 (l.hu (+ a3 12)))"}, {"a2"}, {"a3"}, {""} +"L123:\n lwu a3, L123(fp)\n", {"(set! a3 (l.wu L123))"}, {"a3"}, {""}, {""} +" lwu a2, 0(a3)\n", {"(set! a2 (l.wu a3))"}, {"a2"}, {"a3"}, {""} +" lwu a2, 12(a3)\n", {"(set! a2 (l.wu (+ a3 12)))"}, {"a2"}, {"a3"}, {""} +"L123:\n ld a3, L123(fp)\n", {"(set! a3 (l.d L123))"}, {"a3"}, {""}, {""} +" ld a2, 0(a3)\n", {"(set! a2 (l.d a3))"}, {"a2"}, {"a3"}, {""} +" ld a2, 12(a3)\n", {"(set! a2 (l.d (+ a3 12)))"}, {"a2"}, {"a3"}, {""} +" lw r0, 2(r0)\n", {"(break!)"}, {""}, {""}, {""} +" lw a2, test(s7)\n", {"(set! a2 test)"}, {"a2"}, {""}, {""} +"L123:\n lw a3, L123(fp)\n", {"(set! a3 (l.w L123))"}, {"a3"}, {""}, {""} +" lw a2, 0(a3)\n", {"(set! a2 (l.w a3))"}, {"a2"}, {"a3"}, {""} +" lw a2, 12(a3)\n", {"(set! a2 (l.w (+ a3 12)))"}, {"a2"}, {"a3"}, {""} +" dsll a2, a3, 3\n", {"(set! a2 (shl a3 3))"}, {"a2"}, {"a3"}, {""} +" dsll32 a2, a3, 3\n", {"(set! a2 (shl a3 35))"}, {"a2"}, {"a3"}, {""} +" dsrl a2, a3, 3\n", {"(set! a2 (srl a3 3))"}, {"a2"}, {"a3"}, {""} +" dsrl32 a2, a3, 3\n", {"(set! a2 (srl a3 35))"}, {"a2"}, {"a3"}, {""} +" dsra a2, a3, 3\n", {"(set! a2 (sra a3 3))"}, {"a2"}, {"a3"}, {""} +" dsra32 a2, a3, 3\n", {"(set! a2 (sra a3 35))"}, {"a2"}, {"a3"}, {""} +" div.s f1, f2, f3\n", {"(set! f1 (/.s f2 f3))"}, {"f1"}, {"f2 f3"}, {""} +" min.s f1, f2, f3\n", {"(set! f1 (min.s f2 f3))"}, {"f1"}, {"f2 f3"}, {""} +" max.s f1, f2, f3\n", {"(set! f1 (max.s f2 f3))"}, {"f1"}, {"f2 f3"}, {""} +" mul.s f1, f2, f3\n", {"(set! f1 (*.s f2 f3))"}, {"f1"}, {"f2 f3"}, {""} +" add.s f1, f2, f3\n", {"(set! f1 (+.s f2 f3))"}, {"f1"}, {"f2 f3"}, {""} +" sub.s f1, f2, f3\n", {"(set! f1 (-.s f2 f3))"}, {"f1"}, {"f2 f3"}, {""} +" daddiu a1, s7, test\n", {"(set! a1 'test)"}, {"a1"}, {""}, {""} +" daddiu a1, s7, -10\n", {"(set! a1 '())"}, {"a1"}, {""}, {""} +" daddiu a1, s7, -32768\n", {"(set! a1 __START-OF-TABLE__)"}, {"a1"}, {""}, {""} +" daddiu a1, s7, 8\n", {"(set! a1 '#t)"}, {"a1"}, {""}, {""} +"L123:\n daddiu a1, fp, L123\n", {"(set! a1 L123)"}, {"a1"}, {""}, {""} +" daddiu a1, a2, 1234\n", {"(set! a1 (+ a2 1234))"}, {"a1"}, {"a2"}, {""} +" daddu a1, a2, a3\n", {"(set! a1 (+ a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" dsubu a1, a2, a3\n", {"(set! a1 (- a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" dsubu a1, r0, a3\n", {"(set! a1 (- a3))"}, {"a1"}, {"a3"}, {""} +" mult3 a1, a2, a3\n", {"(set! a1 (*.si a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" multu3 a1, a2, a3\n", {"(set! a1 (*.ui a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" andi a1, a2, 1234\n", {"(set! a1 (logand a2 1234))"}, {"a1"}, {"a2"}, {""} +" xori a1, a2, 1234\n", {"(set! a1 (logxor a2 1234))"}, {"a1"}, {"a2"}, {""} +" nor a1, a2, r0\n", {"(set! a1 (lognot a2))"}, {"a1"}, {"a2"}, {""} +" nor a1, a2, a3\n", {"(set! a1 (lognor a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" xor a1, a2, a3\n", {"(set! a1 (logxor a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" addiu a1, r0, 12\n", {"(set! a1 12)"}, {"a1"}, {""}, {""} +" lui a3, 2\n", {"(set! a3 131072)"}, {"a3"}, {""}, {""} +" sll r0, r0, 0\n", {"(nop!)"}, {""}, {""}, {""} +" dsrav a1, a2, a3\n", {"(set! a1 (sra a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" dsrlv a1, a2, a3\n", {"(set! a1 (srl a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" dsllv a1, a2, a3\n", {"(set! a1 (sll a2 a3))"}, {"a1"}, {"a2 a3"}, {""} +" sb a1, 2(a3)\n", {"(s.b! (+ a3 2) a1)"}, {""}, {"a1 a3"}, {""} +" sb a1, 0(a3)\n", {"(s.b! a3 a1)"}, {""}, {"a1 a3"}, {""} +" sb s7, 2(a3)\n", {"(s.b! (+ a3 2) '#f)"}, {""}, {"a3"}, {""} +" sb s7, 0(a3)\n", {"(s.b! a3 '#f)"}, {""}, {"a3"}, {""} +" sh a1, 2(a3)\n", {"(s.h! (+ a3 2) a1)"}, {""}, {"a1 a3"}, {""} +" sh a1, 0(a3)\n", {"(s.h! a3 a1)"}, {""}, {"a1 a3"}, {""} +" sh s7, 2(a3)\n", {"(s.h! (+ a3 2) '#f)"}, {""}, {"a3"}, {""} +" sh s7, 0(a3)\n", {"(s.h! a3 '#f)"}, {""}, {"a3"}, {""} +" sw a1, test(s7)\n", {"(s.w! test a1)"}, {""}, {"a1"}, {""} +" sw s7, test(s7)\n", {"(s.w! test '#f)"}, {""}, {""}, {""} +" sw a1, 2(a3)\n", {"(s.w! (+ a3 2) a1)"}, {""}, {"a1 a3"}, {""} +" sw a1, 0(a3)\n", {"(s.w! a3 a1)"}, {""}, {"a1 a3"}, {""} +" sw s7, 2(a3)\n", {"(s.w! (+ a3 2) '#f)"}, {""}, {"a3"}, {""} +" sw s7, 0(a3)\n", {"(s.w! a3 '#f)"}, {""}, {"a3"}, {""} +" sd a1, 2(a3)\n", {"(s.d! (+ a3 2) a1)"}, {""}, {"a1 a3"}, {""} +" sd a1, 0(a3)\n", {"(s.d! a3 a1)"}, {""}, {"a1 a3"}, {""} +" sd s7, 2(a3)\n", {"(s.d! (+ a3 2) '#f)"}, {""}, {"a3"}, {""} +" sd s7, 0(a3)\n", {"(s.d! a3 '#f)"}, {""}, {"a3"}, {""} +" swc1 f2, 2(a3)\n", {"(s.f! (+ a3 2) f2)"}, {""}, {"f2 a3"}, {""} +" swc1 f2, 0(a3)\n", {"(s.f! a3 f2)"}, {""}, {"f2 a3"}, {""} +" cvt.s.w f1, f2\n", {"(set! f1 (i2f f2))"}, {"f1"}, {"f2"}, {""} +" cvt.w.s f1, f2\n", {"(set! f1 (f2i f2))"}, {"f1"}, {"f2"}, {""} +" abs.s f1, f2\n", {"(set! f1 (abs.s f2))"}, {"f1"}, {"f2"}, {""} +" neg.s f1, f2\n", {"(set! f1 (neg.s f2))"}, {"f1"}, {"f2"}, {""} +" sqrt.s f1, f2\n", {"(set! f1 (sqrt.s f2))"}, {"f1"}, {"f2"}, {""} +" mov.s f1, f2\n", {"(set! f1 f2)"}, {"f1"}, {"f2"}, {""} +" movz a1, s7, a2\n", {"(cmove-#f-zero a1 a2)"}, {"a1"}, {"a2"}, {""} +" movn a1, s7, a2\n", {"(cmove-#f-nonzero a1 a2)"}, {"a1"}, {"a2"}, {""} + + +" div a1, a2\n mflo a3\n", {"(set! a3 (/.si a1 a2))"}, {"a3"}, {"a1 a2"}, {""} +" divu a1, a2\n mflo a3\n", {"(set! a3 (/.ui a1 a2))"}, {"a3"}, {"a1 a2"}, {""} +" div a1, a2\n mfhi a3\n", {"(set! a3 (mod.si a1 a2))"}, {"a3"}, {"a1 a2"}, {""} +" divu a1, a2\n mfhi a3\n", {"(set! a3 (mod.ui a1 a2))"}, {"a3"}, {"a1 a2"}, {""} +" jalr ra, t9\n sll v0, ra, 0\n", {"(call!)"}, {""}, {"t9"}, {""} +"L100:\n bne a1, a2, L100\n sll r0, r0, 0\n", {"(b! (!= a1 a2) L100 (nop!))"}, {""}, {"a1 a2"}, {""} +"L100:\n bne a1, a2, L100\n or a3, s7, r0\n", {"(b! (!= a1 a2) L100 (set! a3 #f))"}, {"a3"}, {"a1 a2"}, {""} +"L100:\n bne a1, a2, L100\n or a3, t0, r0\n", {"(b! (!= a1 a2) L100 (set! a3 t0))"}, {"a3"}, {"a1 a2 t0"}, {""} +"L100:\n bne a1, a2, L100\n daddiu a3, s7, 8\n", {"(b! (!= a1 a2) L100 (set! a3 #t))"}, {"a3"}, {"a1 a2"}, {""} +"L100:\n bne a1, a2, L100\n lw a3, pair(s7)\n", {"(b! (!= a1 a2) L100 (set! a3 pair))"}, {"a3"}, {"a1 a2"}, {""} +"L100:\n bne a1, a2, L100\n lw a3, binteger(s7)\n", {"(b! (!= a1 a2) L100 (set! a3 binteger))"}, {"a3"}, {"a1 a2"}, {""} +"L100:\n bne a1, a2, L100\n dsllv a3, t0, t1\n", {"(b! (!= a1 a2) L100 (set! a3 (sll t0 t1)))"}, {"a3"}, {"a1 a2 t0 t1"}, {""} +"L100:\n bne a1, a2, L100\n dsubu a3, r0, t1\n", {"(b! (!= a1 a2) L100 (set! a3 (- t1)))"}, {"a3"}, {"a1 a2 t1"}, {""} +"L100:\n bne a1, r0, L100\n sll r0, r0, 0\n", {"(b! (nonzero? a1) L100 (nop!))"}, {""}, {"a1"}, {""} +"L100:\n bne s7, a1, L100\n sll r0, r0, 0\n", {"(b! (truthy a1) L100 (nop!))"}, {""}, {"a1"}, {""} +"L100:\n bnel a1, a2, L100\n sll r0, r0, 0\n", {"(bl! (!= a1 a2) L100 (nop!))"}, {""}, {"a1 a2"}, {""} +"L100:\n bnel a1, r0, L100\n sll r0, r0, 0\n", {"(bl! (nonzero? a1) L100 (nop!))"}, {""}, {"a1"}, {""} +"L100:\n bnel s7, a1, L100\n sll r0, r0, 0\n", {"(bl! (truthy a1) L100 (nop!))"}, {""}, {"a1"}, {""} +"L100:\n beq a0, a1, L100\n sll r0, r0, 0\n", {"(b! (= a0 a1) L100 (nop!))"}, {""}, {"a0 a1"}, {""} +"L100:\n beq r0, r0, L100\n sll r0, r0, 0\n", {"(b! #t L100 (nop!))"}, {""}, {""}, {""} +"L100:\n beq a0, r0, L100\n sll r0, r0, 0\n", {"(b! (zero? a0) L100 (nop!))"}, {""}, {"a0"}, {""} +"L100:\n beq s7, a0, L100\n sll r0, r0, 0\n", {"(b! (not a0) L100 (nop!))"}, {""}, {"a0"}, {""} +"L100:\n beql a0, a1, L100\n sll r0, r0, 0\n", {"(bl! (= a0 a1) L100 (nop!))"}, {""}, {"a0 a1"}, {""} +"L100:\n beql r0, r0, L100\n sll r0, r0, 0\n", {"(bl! #t L100 (nop!))"}, {""}, {""}, {""} +"L100:\n beql a0, r0, L100\n sll r0, r0, 0\n", {"(bl! (zero? a0) L100 (nop!))"}, {""}, {"a0"}, {""} +"L100:\n beql s7, a0, L100\n sll r0, r0, 0\n", {"(bl! (not a0) L100 (nop!))"}, {""}, {"a0"}, {""} +"L100:\n bgtzl a0, L100\n sll r0, r0, 0\n", {"(bl! (>0.si a0) L100 (nop!))"}, {""}, {"a0"}, {""} +"L100:\n bgezl a0, L100\n sll r0, r0, 0\n", {"(bl! (>=0.si a0) L100 (nop!))"}, {""}, {"a0"}, {""} +"L100:\n bltzl a0, L100\n sll r0, r0, 0\n", {"(bl! (<0.si a0) L100 (nop!))"}, {""}, {"a0"}, {""} +" daddiu a1, s7, 8\n movn a1, s7, a0\n", {"(set! a1 (zero? a0))"}, {"a1"}, {"a0"}, {""} +" daddiu a1, s7, 8\n movz a1, s7, a0\n", {"(set! a1 (nonzero? a0))"}, {"a1"}, {"a0"}, {""} +"L100:\n lui a0, 2\n ori a1, a0, 3\n", {"(set! a1 131075)"}, {"a1"}, {""}, {"a0"} +"L100:\n lui a0, 2\n ori a0, a0, 3\n", {"(set! a0 131075)"}, {"a0"}, {""}, {""} +"L100:\n lui a0, L100\n ori a1, a0, L100\n", {"(set! a1 L100)"}, {"a1"}, {""}, {"a0"} +"L100:\n lui a0, L100\n ori a0, a0, L100\n", {"(set! a0 L100)"}, {"a0"}, {""}, {""} +" slt a0, a1, a2\n movz a1, a2, a0\n", {"(set! a1 (min.si a1 a2))"}, {"a1"}, {"a1 a2"}, {"a0"} +" slt a0, a1, a2\n movn a1, a2, a0\n", {"(set! a1 (max.si a1 a2))"}, {"a1"}, {"a1 a2"}, {"a0"} +" sltu a0, a1, a2\n movz a1, a2, a0\n", {"(set! a1 (min.ui a1 a2))"}, {"a1"}, {"a1 a2"}, {"a0"} +" sltu a0, a1, a2\n movn a1, a2, a0\n", {"(set! a1 (max.ui a1 a2))"}, {"a1"}, {"a1 a2"}, {"a0"} +"L100:\n lui a0, L100\n ori a1, a0, L100\n addu a1, fp, a1\n", {"(set! a1 L100)"}, {"a1"}, {""}, {"a0"} +"L100:\n lui a1, L100\n ori a1, a1, L100\n addu a1, fp, a1\n", {"(set! a1 L100)"}, {"a1"}, {""}, {""} +" dsubu a0, a1, a2\n daddiu t0, s7, 8\n movn t0, s7, a0\n", {"(set! t0 (= a1 a2))"}, {"t0"}, {"a1 a2"}, {"a0"} +" dsubu a0, a1, a2\n daddiu t0, s7, 8\n movz t0, s7, a0\n", {"(set! t0 (!= a1 a2))"}, {"t0"}, {"a1 a2"}, {"a0"} +"L100:\n slt a3, a0, a1\n bne a3, r0, L100\n or a3, s7, r0\n", {"(b! (<.si a0 a1) L100 (set! a3 #f))"}, {"a3"}, {"a0 a1"}, {""} +"L100:\n slt a3, a0, a1\n bne a3, r0, L100\n or a2, s7, r0\n", {"(b! (<.si a0 a1) L100 (set! a2 #f))"}, {"a2"}, {"a0 a1"}, {"a3"} +"L100:\n sltu a3, a0, a1\n bne a3, r0, L100\n or a3, s7, r0\n", {"(b! (<.ui a0 a1) L100 (set! a3 #f))"}, {"a3"}, {"a0 a1"}, {""} +"L100:\n sltu a3, a0, a1\n bne a3, r0, L100\n or a2, s7, r0\n", {"(b! (<.ui a0 a1) L100 (set! a2 #f))"}, {"a2"}, {"a0 a1"}, {"a3"} +"L100:\n slt a3, a0, a1\n beq a3, r0, L100\n or a3, s7, r0\n", {"(b! (>=.si a0 a1) L100 (set! a3 #f))"}, {"a3"}, {"a0 a1"}, {""} +"L100:\n slt a3, a0, a1\n beq a3, r0, L100\n or a2, s7, r0\n", {"(b! (>=.si a0 a1) L100 (set! a2 #f))"}, {"a2"}, {"a0 a1"}, {"a3"} +"L100:\n sltu a3, a0, a1\n beq a3, r0, L100\n or a3, s7, r0\n", {"(b! (>=.ui a0 a1) L100 (set! a3 #f))"}, {"a3"}, {"a0 a1"}, {""} +"L100:\n sltu a3, a0, a1\n beq a3, r0, L100\n or a2, s7, r0\n", {"(b! (>=.ui a0 a1) L100 (set! a2 #f))"}, {"a2"}, {"a0 a1"}, {"a3"} +" slt a3, a0, a1\n daddiu a2, s7, 8\n movz a2, s7, a3\n", {"(set! a2 (<.si a0 a1))"}, {"a2"}, {"a0 a1"}, {"a3"} +" slt a3, a0, r0\n daddiu a2, s7, 8\n movz a2, s7, a3\n", {"(set! a2 (<0.si a0))"}, {"a2"}, {"a0"}, {"a3"} +" sltu a3, a0, a1\n daddiu a2, s7, 8\n movz a2, s7, a3\n", {"(set! a2 (<.ui a0 a1))"}, {"a2"}, {"a0 a1"}, {"a3"} +" slt a3, a0, a1\n daddiu a2, s7, 8\n movn a2, s7, a3\n", {"(set! a2 (>=.si a0 a1))"}, {"a2"}, {"a0 a1"}, {"a3"} +" slt a3, a0, r0\n daddiu a2, s7, 8\n movn a2, s7, a3\n", {"(set! a2 (>=0.si a0))"}, {"a2"}, {"a0"}, {"a3"} +" sltu a3, a0, a1\n daddiu a2, s7, 8\n movn a2, s7, a3\n", {"(set! a2 (>=.ui a0 a1))"}, {"a2"}, {"a0 a1"}, {"a3"} +"L100:\n slti a3, a0, 12\n bne a3, r0, L100\n or a3, s7, r0\n", {"(b! (<.si a0 12) L100 (set! a3 #f))"}, {"a3"}, {"a0"}, {""} +"L100:\n slti a3, a0, 12\n bne a3, r0, L100\n or a2, s7, r0\n", {"(b! (<.si a0 12) L100 (set! a2 #f))"}, {"a2"}, {"a0"}, {"a3"} +"L100:\n sltiu a3, a0, 12\n bne a3, r0, L100\n or a3, s7, r0\n", {"(b! (<.ui a0 12) L100 (set! a3 #f))"}, {"a3"}, {"a0"}, {""} +"L100:\n sltiu a3, a0, 12\n bne a3, r0, L100\n or a2, s7, r0\n", {"(b! (<.ui a0 12) L100 (set! a2 #f))"}, {"a2"}, {"a0"}, {"a3"} +"L100:\n slti a3, a0, 12\n beq a3, r0, L100\n or a3, s7, r0\n", {"(b! (>=.si a0 12) L100 (set! a3 #f))"}, {"a3"}, {"a0"}, {""} +"L100:\n slti a3, a0, 12\n beq a3, r0, L100\n or a2, s7, r0\n", {"(b! (>=.si a0 12) L100 (set! a2 #f))"}, {"a2"}, {"a0"}, {"a3"} +"L100:\n sltiu a3, a0, 12\n beq a3, r0, L100\n or a3, s7, r0\n", {"(b! (>=.ui a0 12) L100 (set! a3 #f))"}, {"a3"}, {"a0"}, {""} +"L100:\n sltiu a3, a0, 12\n beq a3, r0, L100\n or a2, s7, r0\n", {"(b! (>=.ui a0 12) L100 (set! a2 #f))"}, {"a2"}, {"a0"}, {"a3"} +" slti a3, a0, 12\n daddiu a2, s7, 8\n movz a2, s7, a3\n", {"(set! a2 (<.si a0 12))"}, {"a2"}, {"a0"}, {"a3"} +" sltiu a3, a0, 12\n daddiu a2, s7, 8\n movz a2, s7, a3\n", {"(set! a2 (<.ui a0 12))"}, {"a2"}, {"a0"}, {"a3"} +" slti a3, a0, 12\n daddiu a2, s7, 8\n movn a2, s7, a3\n", {"(set! a2 (>=.si a0 12))"}, {"a2"}, {"a0"}, {"a3"} +" sltiu a3, a0, 12\n daddiu a2, s7, 8\n movn a2, s7, a3\n", {"(set! a2 (>=.ui a0 12))"}, {"a2"}, {"a0"}, {"a3"} +"L100:\n c.eq.s f1, f2\n bc1t L100\n sll r0, r0, 0\n", {"(b! (=.s f1 f2) L100 (nop!))"}, {""}, {"f1 f2"}, {""} +"L100:\n c.eq.s f1, f2\n bc1f L100\n sll r0, r0, 0\n", {"(b! (!=.s f1 f2) L100 (nop!))"}, {""}, {"f1 f2"}, {""} +"L100:\n c.lt.s f1, f2\n bc1t L100\n sll r0, r0, 0\n", {"(b! (<.s f1 f2) L100 (nop!))"}, {""}, {"f1 f2"}, {""} +"L100:\n c.lt.s f1, f2\n bc1f L100\n sll r0, r0, 0\n", {"(b! (>=.s f1 f2) L100 (nop!))"}, {""}, {"f1 f2"}, {""} +"L100:\n c.le.s f1, f2\n bc1t L100\n sll r0, r0, 0\n", {"(b! (<=.s f1 f2) L100 (nop!))"}, {""}, {"f1 f2"}, {""} +"L100:\n c.le.s f1, f2\n bc1f L100\n sll r0, r0, 0\n", {"(b! (>.s f1 f2) L100 (nop!))"}, {""}, {"f1 f2"}, {""} +"L100:\n dsll32 v1, s4, 30\n slt v1, v1, r0\n beq v1, r0, L100\n sll r0, r0, 0\n", {"(b! (not-pair? s4) L100 (nop!))"}, {""}, {"s4"}, {"v1"} +" slt a3, r0, a0\n daddiu a2, s7, 8\n movz a2, s7, a3\n", {"(set! a2 (>0.si a0))"}, {"a2"}, {"a0"}, {"a3"} +" daddu v1, r0, v0\n", {"(set! v1 (+ v0 0))"}, {"v1"}, {"v0"}, {""} +" sw r0, test(s7)\n", {"(s.w! test 0)"}, {""}, {""}, {""} +" sw r0, 2(a3)\n", {"(s.w! (+ a3 2) 0)"}, {""}, {"a3"}, {""} +" sw r0, 0(a3)\n", {"(s.w! a3 0)"}, {""}, {"a3"}, {""} +"L100:\n slt v1, s2, r0\n beq v1, r0, L100\n or v1, s7, r0\n", {"(b! (>=0.si s2) L100 (set! v1 #f))"}, {"v1"}, {"s2"}, {""} +"L100:\n slt v1, s2, r0\n beq v1, r0, L100\n or v0, s7, r0\n", {"(b! (>=0.si s2) L100 (set! v0 #f))"}, {"v0"}, {"s2"}, {"v1"} +" mtc1 f3, r0\n", {"(set! f3 0)"}, {"f3"}, {""}, {""} \ No newline at end of file diff --git a/test/decompiler/test_AtomicOpBuilder.cpp b/test/decompiler/test_AtomicOpBuilder.cpp index e1be81487e..c18fc53c22 100644 --- a/test/decompiler/test_AtomicOpBuilder.cpp +++ b/test/decompiler/test_AtomicOpBuilder.cpp @@ -145,7 +145,7 @@ TEST(DecompilerAtomicOpBuilder, Example) { {{"v1", "a3"}, {"a2", "a2"}}, {{}, {}}); } -TEST(DecompilerAtomicOpBuilder, ABS_S) { +TEST(DecompilerAtomicOpBuilder, ABSS) { test_case(assembly_from_list({"abs.s f1, f2"}), {"(set! f1 (abs.s f2))"}, {{"f1"}}, {{"f2"}}, {{}}); } @@ -154,7 +154,7 @@ TEST(DecompilerAtomicOpBuilder, ADDIU) { test_case(assembly_from_list({"addiu a1, r0, 12"}), {"(set! a1 12)"}, {{"a1"}}, {{}}, {{}}); } -TEST(DecompilerAtomicOpBuilder, ADD_S) { +TEST(DecompilerAtomicOpBuilder, ADDS) { test_case(assembly_from_list({"add.s f1, f2, f3"}), {"(set! f1 (+.s f2 f3))"}, {{"f1"}}, {{"f2", "f3"}}, {{}}); } @@ -169,12 +169,127 @@ TEST(DecompilerAtomicOpBuilder, ANDI) { {{"a2"}}, {{}}); } -TEST(DecompilerAtomicOpBuilder, CVT_S_W) { +TEST(DecompilerAtomicOpBuilder, BEQL_SLL) { + test_case(assembly_from_list({"L100:", "beql a0, a1, L100", "sll r0, r0, 0"}), + {"(bl! (= a0 a1) L100 (nop!))"}, {{}}, {{"a0", "a1"}}, {{}}); + test_case(assembly_from_list({"L100:", "beql r0, r0, L100", "sll r0, r0, 0"}), + {"(bl! #t L100 (nop!))"}, {{}}, {{}}, {{}}); + test_case(assembly_from_list({"L100:", "beql a0, r0, L100", "sll r0, r0, 0"}), + {"(bl! (zero? a0) L100 (nop!))"}, {{}}, {{"a0"}}, {{}}); + test_case(assembly_from_list({"L100:", "beql s7, a0, L100", "sll r0, r0, 0"}), + {"(bl! (not a0) L100 (nop!))"}, {{}}, {{"a0"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BEQ_SLL) { + test_case(assembly_from_list({"L100:", "beq a0, a1, L100", "sll r0, r0, 0"}), + {"(b! (= a0 a1) L100 (nop!))"}, {{}}, {{"a0", "a1"}}, {{}}); + test_case(assembly_from_list({"L100:", "beq r0, r0, L100", "sll r0, r0, 0"}), + {"(b! #t L100 (nop!))"}, {{}}, {{}}, {{}}); + test_case(assembly_from_list({"L100:", "beq a0, r0, L100", "sll r0, r0, 0"}), + {"(b! (zero? a0) L100 (nop!))"}, {{}}, {{"a0"}}, {{}}); + test_case(assembly_from_list({"L100:", "beq s7, a0, L100", "sll r0, r0, 0"}), + {"(b! (not a0) L100 (nop!))"}, {{}}, {{"a0"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BGEZL_SLL) { + test_case(assembly_from_list({"L100:", "bgezl a0, L100", "sll r0, r0, 0"}), + {"(bl! (>=0.si a0) L100 (nop!))"}, {{}}, {{"a0"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BGTZL_SLL) { + test_case(assembly_from_list({"L100:", "bgtzl a0, L100", "sll r0, r0, 0"}), + {"(bl! (>0.si a0) L100 (nop!))"}, {{}}, {{"a0"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BLTZL_SLL) { + test_case(assembly_from_list({"L100:", "bltzl a0, L100", "sll r0, r0, 0"}), + {"(bl! (<0.si a0) L100 (nop!))"}, {{}}, {{"a0"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BNEL_SLL) { + test_case(assembly_from_list({"L100:", "bnel a1, a2, L100", "sll r0, r0, 0"}), + {"(bl! (!= a1 a2) L100 (nop!))"}, {{}}, {{"a1", "a2"}}, {{}}); + test_case(assembly_from_list({"L100:", "bnel a1, r0, L100", "sll r0, r0, 0"}), + {"(bl! (nonzero? a1) L100 (nop!))"}, {{}}, {{"a1"}}, {{}}); + test_case(assembly_from_list({"L100:", "bnel s7, a1, L100", "sll r0, r0, 0"}), + {"(bl! (truthy a1) L100 (nop!))"}, {{}}, {{"a1"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BNE_DADDIU) { + test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "daddiu a3, s7, 8"}), + {"(b! (!= a1 a2) L100 (set! a3 #t))"}, {{"a3"}}, {{"a1", "a2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BNE_DSLLV) { + test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "dsllv a3, t0, t1"}), + {"(b! (!= a1 a2) L100 (set! a3 (sll t0 t1)))"}, {{"a3"}}, {{"a1", "a2", "t0", "t1"}}, + {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BNE_DSUBU) { + test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "dsubu a3, r0, t1"}), + {"(b! (!= a1 a2) L100 (set! a3 (- t1)))"}, {{"a3"}}, {{"a1", "a2", "t1"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BNE_LW) { + test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "lw a3, pair(s7)"}), + {"(b! (!= a1 a2) L100 (set! a3 pair))"}, {{"a3"}}, {{"a1", "a2"}}, {{}}); + test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "lw a3, binteger(s7)"}), + {"(b! (!= a1 a2) L100 (set! a3 binteger))"}, {{"a3"}}, {{"a1", "a2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BNE_OR) { + test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "or a3, s7, r0"}), + {"(b! (!= a1 a2) L100 (set! a3 #f))"}, {{"a3"}}, {{"a1", "a2"}}, {{}}); + test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "or a3, t0, r0"}), + {"(b! (!= a1 a2) L100 (set! a3 t0))"}, {{"a3"}}, {{"a1", "a2", "t0"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, BNE_SLL) { + test_case(assembly_from_list({"L100:", "bne a1, a2, L100", "sll r0, r0, 0"}), + {"(b! (!= a1 a2) L100 (nop!))"}, {{}}, {{"a1", "a2"}}, {{}}); + test_case(assembly_from_list({"L100:", "bne a1, r0, L100", "sll r0, r0, 0"}), + {"(b! (nonzero? a1) L100 (nop!))"}, {{}}, {{"a1"}}, {{}}); + test_case(assembly_from_list({"L100:", "bne s7, a1, L100", "sll r0, r0, 0"}), + {"(b! (truthy a1) L100 (nop!))"}, {{}}, {{"a1"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, CEQS_BC1F_SLL) { + test_case(assembly_from_list({"L100:", "c.eq.s f1, f2", "bc1f L100", "sll r0, r0, 0"}), + {"(b! (!=.s f1 f2) L100 (nop!))"}, {{}}, {{"f1", "f2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, CEQS_BC1T_SLL) { + test_case(assembly_from_list({"L100:", "c.eq.s f1, f2", "bc1t L100", "sll r0, r0, 0"}), + {"(b! (=.s f1 f2) L100 (nop!))"}, {{}}, {{"f1", "f2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, CLES_BC1F_SLL) { + test_case(assembly_from_list({"L100:", "c.le.s f1, f2", "bc1f L100", "sll r0, r0, 0"}), + {"(b! (>.s f1 f2) L100 (nop!))"}, {{}}, {{"f1", "f2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, CLES_BC1T_SLL) { + test_case(assembly_from_list({"L100:", "c.le.s f1, f2", "bc1t L100", "sll r0, r0, 0"}), + {"(b! (<=.s f1 f2) L100 (nop!))"}, {{}}, {{"f1", "f2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, CLTS_BC1F_SLL) { + test_case(assembly_from_list({"L100:", "c.lt.s f1, f2", "bc1f L100", "sll r0, r0, 0"}), + {"(b! (>=.s f1 f2) L100 (nop!))"}, {{}}, {{"f1", "f2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, CLTS_BC1T_SLL) { + test_case(assembly_from_list({"L100:", "c.lt.s f1, f2", "bc1t L100", "sll r0, r0, 0"}), + {"(b! (<.s f1 f2) L100 (nop!))"}, {{}}, {{"f1", "f2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, CVTSW) { test_case(assembly_from_list({"cvt.s.w f1, f2"}), {"(set! f1 (i2f f2))"}, {{"f1"}}, {{"f2"}}, {{}}); } -TEST(DecompilerAtomicOpBuilder, CVT_W_S) { +TEST(DecompilerAtomicOpBuilder, CVTWS) { test_case(assembly_from_list({"cvt.w.s f1, f2"}), {"(set! f1 (f2i f2))"}, {{"f1"}}, {{"f2"}}, {{}}); } @@ -191,28 +306,66 @@ TEST(DecompilerAtomicOpBuilder, DADDIU) { {{"a2"}}, {{}}); } +TEST(DecompilerAtomicOpBuilder, DADDIU_MOVN) { + test_case(assembly_from_list({"daddiu a1, s7, 8", "movn a1, s7, a0"}), {"(set! a1 (zero? a0))"}, + {{"a1"}}, {{"a0"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, DADDIU_MOVZ) { + test_case(assembly_from_list({"daddiu a1, s7, 8", "movz a1, s7, a0"}), + {"(set! a1 (nonzero? a0))"}, {{"a1"}}, {{"a0"}}, {{}}); +} + TEST(DecompilerAtomicOpBuilder, DADDU) { test_case(assembly_from_list({"daddu a1, a2, a3"}), {"(set! a1 (+ a2 a3))"}, {{"a1"}}, {{"a2", "a3"}}, {{}}); + test_case(assembly_from_list({"daddu v1, r0, v0"}), {"(set! v1 (+ v0 0))"}, {{"v1"}}, {{"v0"}}, + {{}}); } -TEST(DecompilerAtomicOpBuilder, DIV_S) { +TEST(DecompilerAtomicOpBuilder, DIVS) { test_case(assembly_from_list({"div.s f1, f2, f3"}), {"(set! f1 (/.s f2 f3))"}, {{"f1"}}, {{"f2", "f3"}}, {{}}); } +TEST(DecompilerAtomicOpBuilder, DIVU_MFHI) { + test_case(assembly_from_list({"divu a1, a2", "mfhi a3"}), {"(set! a3 (mod.ui a1 a2))"}, {{"a3"}}, + {{"a1", "a2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, DIVU_MFLO) { + test_case(assembly_from_list({"divu a1, a2", "mflo a3"}), {"(set! a3 (/.ui a1 a2))"}, {{"a3"}}, + {{"a1", "a2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, DIV_MFHI) { + test_case(assembly_from_list({"div a1, a2", "mfhi a3"}), {"(set! a3 (mod.si a1 a2))"}, {{"a3"}}, + {{"a1", "a2"}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, DIV_MFLO) { + test_case(assembly_from_list({"div a1, a2", "mflo a3"}), {"(set! a3 (/.si a1 a2))"}, {{"a3"}}, + {{"a1", "a2"}}, {{}}); +} + TEST(DecompilerAtomicOpBuilder, DSLL) { - test_case(assembly_from_list({"dsll a2, a3, 3"}), {"(set! a2 (shl a3 3))"}, {{"a2"}}, {{"a3"}}, + test_case(assembly_from_list({"dsll a2, a3, 3"}), {"(set! a2 (sll a3 3))"}, {{"a2"}}, {{"a3"}}, {{}}); } TEST(DecompilerAtomicOpBuilder, DSLL32) { - test_case(assembly_from_list({"dsll32 a2, a3, 3"}), {"(set! a2 (shl a3 35))"}, {{"a2"}}, {{"a3"}}, + test_case(assembly_from_list({"dsll32 a2, a3, 3"}), {"(set! a2 (sll a3 35))"}, {{"a2"}}, {{"a3"}}, {{}}); } +TEST(DecompilerAtomicOpBuilder, DSLL32_SLT_BEQ_SLL) { + test_case(assembly_from_list({"L100:", "dsll32 v1, s4, 30", "slt v1, v1, r0", "beq v1, r0, L100", + "sll r0, r0, 0"}), + {"(b! (not-pair? s4) L100 (nop!))"}, {{}}, {{"s4"}}, {{"v1"}}); +} + TEST(DecompilerAtomicOpBuilder, DSLLV) { - test_case(assembly_from_list({"dsllv a1, a2, a3"}), {"(set! a1 (shl a2 a3))"}, {{"a1"}}, + test_case(assembly_from_list({"dsllv a1, a2, a3"}), {"(set! a1 (sll a2 a3))"}, {{"a1"}}, {{"a2", "a3"}}, {{}}); } @@ -253,6 +406,21 @@ TEST(DecompilerAtomicOpBuilder, DSUBU) { {{}}); } +TEST(DecompilerAtomicOpBuilder, DSUBU_DADDIU_MOVN) { + test_case(assembly_from_list({"dsubu a0, a1, a2", "daddiu t0, s7, 8", "movn t0, s7, a0"}), + {"(set! t0 (= a1 a2))"}, {{"t0"}}, {{"a1", "a2"}}, {{"a0"}}); +} + +TEST(DecompilerAtomicOpBuilder, DSUBU_DADDIU_MOVZ) { + test_case(assembly_from_list({"dsubu a0, a1, a2", "daddiu t0, s7, 8", "movz t0, s7, a0"}), + {"(set! t0 (!= a1 a2))"}, {{"t0"}}, {{"a1", "a2"}}, {{"a0"}}); +} + +TEST(DecompilerAtomicOpBuilder, JALR_SLL) { + test_case(assembly_from_list({"jalr ra, t9", "sll v0, ra, 0"}), {"(call!)"}, {{}}, {{"t9"}}, + {{}}); +} + TEST(DecompilerAtomicOpBuilder, LB) { test_case(assembly_from_list({"L123:", "lb a3, L123(fp)"}), {"(set! a3 (l.b L123))"}, {{"a3"}}, {{}}, {{}}); @@ -299,6 +467,24 @@ TEST(DecompilerAtomicOpBuilder, LUI) { test_case(assembly_from_list({"lui a3, 2"}), {"(set! a3 131072)"}, {{"a3"}}, {{}}, {{}}); } +TEST(DecompilerAtomicOpBuilder, LUI_ORI) { + test_case(assembly_from_list({"L100:", "lui a0, 2", "ori a1, a0, 3"}), {"(set! a1 131075)"}, + {{"a1"}}, {{}}, {{"a0"}}); + test_case(assembly_from_list({"L100:", "lui a0, 2", "ori a0, a0, 3"}), {"(set! a0 131075)"}, + {{"a0"}}, {{}}, {{}}); + test_case(assembly_from_list({"L100:", "lui a0, L100", "ori a1, a0, L100"}), {"(set! a1 L100)"}, + {{"a1"}}, {{}}, {{"a0"}}); + test_case(assembly_from_list({"L100:", "lui a0, L100", "ori a0, a0, L100"}), {"(set! a0 L100)"}, + {{"a0"}}, {{}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, LUI_ORI_ADDU) { + test_case(assembly_from_list({"L100:", "lui a0, L100", "ori a1, a0, L100", "addu a1, fp, a1"}), + {"(set! a1 L100)"}, {{"a1"}}, {{}}, {{"a0"}}); + test_case(assembly_from_list({"L100:", "lui a1, L100", "ori a1, a1, L100", "addu a1, fp, a1"}), + {"(set! a1 L100)"}, {{"a1"}}, {{}}, {{}}); +} + TEST(DecompilerAtomicOpBuilder, LW) { test_case(assembly_from_list({"lw r0, 2(r0)"}), {"(break!)"}, {{}}, {{}}, {{}}); test_case(assembly_from_list({"lw a2, test(s7)"}), {"(set! a2 test)"}, {{"a2"}}, {{}}, {{}}); @@ -327,7 +513,7 @@ TEST(DecompilerAtomicOpBuilder, LWU) { {{"a3"}}, {{}}); } -TEST(DecompilerAtomicOpBuilder, MAX_S) { +TEST(DecompilerAtomicOpBuilder, MAXS) { test_case(assembly_from_list({"max.s f1, f2, f3"}), {"(set! f1 (max.s f2 f3))"}, {{"f1"}}, {{"f2", "f3"}}, {{}}); } @@ -337,7 +523,7 @@ TEST(DecompilerAtomicOpBuilder, MFC1) { {{}}); } -TEST(DecompilerAtomicOpBuilder, MIN_S) { +TEST(DecompilerAtomicOpBuilder, MINS) { test_case(assembly_from_list({"min.s f1, f2, f3"}), {"(set! f1 (min.s f2 f3))"}, {{"f1"}}, {{"f2", "f3"}}, {{}}); } @@ -347,18 +533,24 @@ TEST(DecompilerAtomicOpBuilder, MOVN) { {{"a2"}}, {{}}); } +TEST(DecompilerAtomicOpBuilder, MOVS) { + test_case(assembly_from_list({"mov.s f1, f2"}), {"(set! f1 f2)"}, {{"f1"}}, {{"f2"}}, {{}}); +} + TEST(DecompilerAtomicOpBuilder, MOVZ) { test_case(assembly_from_list({"movz a1, s7, a2"}), {"(cmove-#f-zero a1 a2)"}, {{"a1"}}, {{"a2"}}, {{}}); } -TEST(DecompilerAtomicOpBuilder, MOV_S) { - test_case(assembly_from_list({"mov.s f1, f2"}), {"(set! f1 f2)"}, {{"f1"}}, {{"f2"}}, {{}}); -} - TEST(DecompilerAtomicOpBuilder, MTC1) { test_case(assembly_from_list({"mtc1 f3, a1"}), {"(set! f3 (gpr->fpr a1))"}, {{"f3"}}, {{"a1"}}, {{}}); + test_case(assembly_from_list({"mtc1 f3, r0"}), {"(set! f3 0)"}, {{"f3"}}, {{}}, {{}}); +} + +TEST(DecompilerAtomicOpBuilder, MULS) { + test_case(assembly_from_list({"mul.s f1, f2, f3"}), {"(set! f1 (*.s f2 f3))"}, {{"f1"}}, + {{"f2", "f3"}}, {{}}); } TEST(DecompilerAtomicOpBuilder, MULT3) { @@ -371,12 +563,7 @@ TEST(DecompilerAtomicOpBuilder, MULTU3) { {{"a2", "a3"}}, {{}}); } -TEST(DecompilerAtomicOpBuilder, MUL_S) { - test_case(assembly_from_list({"mul.s f1, f2, f3"}), {"(set! f1 (*.s f2 f3))"}, {{"f1"}}, - {{"f2", "f3"}}, {{}}); -} - -TEST(DecompilerAtomicOpBuilder, NEG_S) { +TEST(DecompilerAtomicOpBuilder, NEGS) { test_case(assembly_from_list({"neg.s f1, f2"}), {"(set! f1 (neg.s f2))"}, {{"f1"}}, {{"f2"}}, {{}}); } @@ -430,12 +617,138 @@ TEST(DecompilerAtomicOpBuilder, SLL) { test_case(assembly_from_list({"sll r0, r0, 0"}), {"(nop!)"}, {{}}, {{}}, {{}}); } -TEST(DecompilerAtomicOpBuilder, SQRT_S) { +TEST(DecompilerAtomicOpBuilder, SLTIU_BEQ_OR) { + test_case(assembly_from_list({"L100:", "sltiu a3, a0, 12", "beq a3, r0, L100", "or a3, s7, r0"}), + {"(b! (>=.ui a0 12) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0"}}, {{}}); + test_case(assembly_from_list({"L100:", "sltiu a3, a0, 12", "beq a3, r0, L100", "or a2, s7, r0"}), + {"(b! (>=.ui a0 12) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTIU_BNE_OR) { + test_case(assembly_from_list({"L100:", "sltiu a3, a0, 12", "bne a3, r0, L100", "or a3, s7, r0"}), + {"(b! (<.ui a0 12) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0"}}, {{}}); + test_case(assembly_from_list({"L100:", "sltiu a3, a0, 12", "bne a3, r0, L100", "or a2, s7, r0"}), + {"(b! (<.ui a0 12) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTIU_DADDIU_MOVN) { + test_case(assembly_from_list({"sltiu a3, a0, 12", "daddiu a2, s7, 8", "movn a2, s7, a3"}), + {"(set! a2 (>=.ui a0 12))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTIU_DADDIU_MOVZ) { + test_case(assembly_from_list({"sltiu a3, a0, 12", "daddiu a2, s7, 8", "movz a2, s7, a3"}), + {"(set! a2 (<.ui a0 12))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTI_BEQ_OR) { + test_case(assembly_from_list({"L100:", "slti a3, a0, 12", "beq a3, r0, L100", "or a3, s7, r0"}), + {"(b! (>=.si a0 12) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0"}}, {{}}); + test_case(assembly_from_list({"L100:", "slti a3, a0, 12", "beq a3, r0, L100", "or a2, s7, r0"}), + {"(b! (>=.si a0 12) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTI_BNE_OR) { + test_case(assembly_from_list({"L100:", "slti a3, a0, 12", "bne a3, r0, L100", "or a3, s7, r0"}), + {"(b! (<.si a0 12) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0"}}, {{}}); + test_case(assembly_from_list({"L100:", "slti a3, a0, 12", "bne a3, r0, L100", "or a2, s7, r0"}), + {"(b! (<.si a0 12) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTI_DADDIU_MOVN) { + test_case(assembly_from_list({"slti a3, a0, 12", "daddiu a2, s7, 8", "movn a2, s7, a3"}), + {"(set! a2 (>=.si a0 12))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTI_DADDIU_MOVZ) { + test_case(assembly_from_list({"slti a3, a0, 12", "daddiu a2, s7, 8", "movz a2, s7, a3"}), + {"(set! a2 (<.si a0 12))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTU_BEQ_OR) { + test_case(assembly_from_list({"L100:", "sltu a3, a0, a1", "beq a3, r0, L100", "or a3, s7, r0"}), + {"(b! (>=.ui a0 a1) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0", "a1"}}, {{}}); + test_case(assembly_from_list({"L100:", "sltu a3, a0, a1", "beq a3, r0, L100", "or a2, s7, r0"}), + {"(b! (>=.ui a0 a1) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0", "a1"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTU_BNE_OR) { + test_case(assembly_from_list({"L100:", "sltu a3, a0, a1", "bne a3, r0, L100", "or a3, s7, r0"}), + {"(b! (<.ui a0 a1) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0", "a1"}}, {{}}); + test_case(assembly_from_list({"L100:", "sltu a3, a0, a1", "bne a3, r0, L100", "or a2, s7, r0"}), + {"(b! (<.ui a0 a1) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0", "a1"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTU_DADDIU_MOVN) { + test_case(assembly_from_list({"sltu a3, a0, a1", "daddiu a2, s7, 8", "movn a2, s7, a3"}), + {"(set! a2 (>=.ui a0 a1))"}, {{"a2"}}, {{"a0", "a1"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTU_DADDIU_MOVZ) { + test_case(assembly_from_list({"sltu a3, a0, a1", "daddiu a2, s7, 8", "movz a2, s7, a3"}), + {"(set! a2 (<.ui a0 a1))"}, {{"a2"}}, {{"a0", "a1"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTU_MOVN) { + test_case(assembly_from_list({"sltu a0, a1, a2", "movn a1, a2, a0"}), + {"(set! a1 (max.ui a1 a2))"}, {{"a1"}}, {{"a1", "a2"}}, {{"a0"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLTU_MOVZ) { + test_case(assembly_from_list({"sltu a0, a1, a2", "movz a1, a2, a0"}), + {"(set! a1 (min.ui a1 a2))"}, {{"a1"}}, {{"a1", "a2"}}, {{"a0"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLT_BEQ_OR) { + test_case(assembly_from_list({"L100:", "slt a3, a0, a1", "beq a3, r0, L100", "or a3, s7, r0"}), + {"(b! (>=.si a0 a1) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0", "a1"}}, {{}}); + test_case(assembly_from_list({"L100:", "slt a3, a0, a1", "beq a3, r0, L100", "or a2, s7, r0"}), + {"(b! (>=.si a0 a1) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0", "a1"}}, {{"a3"}}); + test_case(assembly_from_list({"L100:", "slt v1, s2, r0", "beq v1, r0, L100", "or v1, s7, r0"}), + {"(b! (>=0.si s2) L100 (set! v1 #f))"}, {{"v1"}}, {{"s2"}}, {{}}); + test_case(assembly_from_list({"L100:", "slt v1, s2, r0", "beq v1, r0, L100", "or v0, s7, r0"}), + {"(b! (>=0.si s2) L100 (set! v0 #f))"}, {{"v0"}}, {{"s2"}}, {{"v1"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLT_BNE_OR) { + test_case(assembly_from_list({"L100:", "slt a3, a0, a1", "bne a3, r0, L100", "or a3, s7, r0"}), + {"(b! (<.si a0 a1) L100 (set! a3 #f))"}, {{"a3"}}, {{"a0", "a1"}}, {{}}); + test_case(assembly_from_list({"L100:", "slt a3, a0, a1", "bne a3, r0, L100", "or a2, s7, r0"}), + {"(b! (<.si a0 a1) L100 (set! a2 #f))"}, {{"a2"}}, {{"a0", "a1"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLT_DADDIU_MOVN) { + test_case(assembly_from_list({"slt a3, a0, a1", "daddiu a2, s7, 8", "movn a2, s7, a3"}), + {"(set! a2 (>=.si a0 a1))"}, {{"a2"}}, {{"a0", "a1"}}, {{"a3"}}); + test_case(assembly_from_list({"slt a3, a0, r0", "daddiu a2, s7, 8", "movn a2, s7, a3"}), + {"(set! a2 (>=0.si a0))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLT_DADDIU_MOVZ) { + test_case(assembly_from_list({"slt a3, a0, a1", "daddiu a2, s7, 8", "movz a2, s7, a3"}), + {"(set! a2 (<.si a0 a1))"}, {{"a2"}}, {{"a0", "a1"}}, {{"a3"}}); + test_case(assembly_from_list({"slt a3, a0, r0", "daddiu a2, s7, 8", "movz a2, s7, a3"}), + {"(set! a2 (<0.si a0))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); + test_case(assembly_from_list({"slt a3, r0, a0", "daddiu a2, s7, 8", "movz a2, s7, a3"}), + {"(set! a2 (>0.si a0))"}, {{"a2"}}, {{"a0"}}, {{"a3"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLT_MOVN) { + test_case(assembly_from_list({"slt a0, a1, a2", "movn a1, a2, a0"}), {"(set! a1 (max.si a1 a2))"}, + {{"a1"}}, {{"a1", "a2"}}, {{"a0"}}); +} + +TEST(DecompilerAtomicOpBuilder, SLT_MOVZ) { + test_case(assembly_from_list({"slt a0, a1, a2", "movz a1, a2, a0"}), {"(set! a1 (min.si a1 a2))"}, + {{"a1"}}, {{"a1", "a2"}}, {{"a0"}}); +} + +TEST(DecompilerAtomicOpBuilder, SQRTS) { test_case(assembly_from_list({"sqrt.s f1, f2"}), {"(set! f1 (sqrt.s f2))"}, {{"f1"}}, {{"f2"}}, {{}}); } -TEST(DecompilerAtomicOpBuilder, SUB_S) { +TEST(DecompilerAtomicOpBuilder, SUBS) { test_case(assembly_from_list({"sub.s f1, f2, f3"}), {"(set! f1 (-.s f2 f3))"}, {{"f1"}}, {{"f2", "f3"}}, {{}}); } @@ -448,6 +761,9 @@ TEST(DecompilerAtomicOpBuilder, SW) { test_case(assembly_from_list({"sw a1, 0(a3)"}), {"(s.w! a3 a1)"}, {{}}, {{"a1", "a3"}}, {{}}); test_case(assembly_from_list({"sw s7, 2(a3)"}), {"(s.w! (+ a3 2) '#f)"}, {{}}, {{"a3"}}, {{}}); test_case(assembly_from_list({"sw s7, 0(a3)"}), {"(s.w! a3 '#f)"}, {{}}, {{"a3"}}, {{}}); + test_case(assembly_from_list({"sw r0, test(s7)"}), {"(s.w! test 0)"}, {{}}, {{}}, {{}}); + test_case(assembly_from_list({"sw r0, 2(a3)"}), {"(s.w! (+ a3 2) 0)"}, {{}}, {{"a3"}}, {{}}); + test_case(assembly_from_list({"sw r0, 0(a3)"}), {"(s.w! a3 0)"}, {{}}, {{"a3"}}, {{}}); } TEST(DecompilerAtomicOpBuilder, SWC1) {