#include "gtest/gtest.h" #include "FormRegressionTest.h" using namespace decompiler; TEST_F(FormRegressionTest, ExprDisasmVif) { std::string func = " sll r0, r0, 0\n" "L53:\n" " daddiu sp, sp, -192\n" " sd ra, 0(sp)\n" " sd fp, 8(sp)\n" " or fp, t9, r0\n" " sq s0, 80(sp)\n" " sq s1, 96(sp)\n" " sq s2, 112(sp)\n" " sq s3, 128(sp)\n" " sq s4, 144(sp)\n" " sq s5, 160(sp)\n" " sq gp, 176(sp)\n" " or s4, a0, r0\n" " or s5, a1, r0\n" " or s3, a2, r0\n" " or s2, a3, r0\n" " addiu gp, r0, 0\n" " beq r0, r0, L72\n" " sll r0, r0, 0\n" "L54:\n" " addiu s0, r0, 4\n" " lwu s1, 0(s4)\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L139\n" " or a2, s4, r0\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " addiu v1, r0, 0\n" " beq r0, r0, L71\n" " sll r0, r0, 0\n" "L55:\n" " dsll32 a0, s1, 1\n" " dsrl32 a0, a0, 25\n" " sq a0, 16(sp)\n" " dsll a0, v1, 2\n" " lw a1, *vif-disasm-table*(s7)\n" " daddu a0, a0, a1\n" " lwu a0, 12(a0)\n" " lwu a0, 4(a0)\n" " lq a1, 16(sp)\n" " dsll a2, v1, 2\n" " lw a3, *vif-disasm-table*(s7)\n" " daddu a2, a2, a3\n" " lwu a2, 12(a2)\n" " lwu a2, 0(a2)\n" " and a1, a1, a2\n" " bne a1, a0, L70\n" " or a0, s7, r0\n" " dsll a0, v1, 2\n" " lw a1, *vif-disasm-table*(s7)\n" " daddu a0, a0, a1\n" " lwu a0, 12(a0)\n" " lwu a0, 12(a0)\n" " bne a0, r0, L56\n" " or a1, s7, r0\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L138\n" " dsll v1, v1, 2\n" " lw a2, *vif-disasm-table*(s7)\n" " daddu v1, v1, a2\n" " lwu v1, 12(v1)\n" " lwu a2, 16(v1)\n" " srl a3, s1, 31\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " beq r0, r0, L69\n" " sll r0, r0, 0\n" "L56:\n" " addiu a1, r0, 1\n" " bne a0, a1, L57\n" " or a1, s7, r0\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L137\n" " dsll a2, v1, 2\n" " lw a3, *vif-disasm-table*(s7)\n" " daddu a2, a2, a3\n" " lwu a2, 12(a2)\n" " lwu a2, 16(a2)\n" " srl a3, s1, 31\n" " dsll v1, v1, 2\n" " lw t0, *vif-disasm-table*(s7)\n" " daddu v1, v1, t0\n" " lwu v1, 12(v1)\n" " lwu t0, 20(v1)\n" " dsll32 v1, s1, 16\n" " dsrl32 t1, v1, 16\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " beq r0, r0, L69\n" " sll r0, r0, 0\n" "L57:\n" " addiu a1, r0, 2\n" " bne a0, a1, L58\n" " or a1, s7, r0\n" " dsll32 a0, s1, 16\n" " dsrl32 t1, a0, 16\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L136\n" " dsll v1, v1, 2\n" " lw a2, *vif-disasm-table*(s7)\n" " daddu v1, v1, a2\n" " lwu v1, 12(v1)\n" " lwu a2, 16(v1)\n" " srl a3, s1, 31\n" " dsll32 v1, t1, 16\n" " dsrl32 t0, v1, 24\n" " dsll32 v1, t1, 24\n" " dsrl32 t1, v1, 24\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " beq r0, r0, L69\n" " sll r0, r0, 0\n" "L58:\n" " addiu a1, r0, 3\n" " bne a0, a1, L59\n" " or a1, s7, r0\n" " addiu s0, r0, 8\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L137\n" " dsll a2, v1, 2\n" " lw a3, *vif-disasm-table*(s7)\n" " daddu a2, a2, a3\n" " lwu a2, 12(a2)\n" " lwu a2, 16(a2)\n" " srl a3, s1, 31\n" " dsll v1, v1, 2\n" " lw t0, *vif-disasm-table*(s7)\n" " daddu v1, v1, t0\n" " lwu v1, 12(v1)\n" " lwu t0, 20(v1)\n" " lwu t1, 4(s4)\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " beq r0, r0, L69\n" " sll r0, r0, 0\n" "L59:\n" " addiu a1, r0, 4\n" " bne a0, a1, L60\n" " or a1, s7, r0\n" " addiu s0, r0, 20\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L135\n" " dsll a2, v1, 2\n" " lw a3, *vif-disasm-table*(s7)\n" " daddu a2, a2, a3\n" " lwu a2, 12(a2)\n" " lwu a2, 16(a2)\n" " srl a3, s1, 31\n" " dsll v1, v1, 2\n" " lw t0, *vif-disasm-table*(s7)\n" " daddu v1, v1, t0\n" " lwu v1, 12(v1)\n" " lwu t0, 20(v1)\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L134\n" " lwu a2, 4(s4)\n" " lwu a3, 8(s4)\n" " lwu t0, 12(s4)\n" " lwu t1, 16(s4)\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " beq r0, r0, L69\n" " sll r0, r0, 0\n" "L60:\n" " addiu a1, r0, 5\n" " bne a0, a1, L61\n" " or a1, s7, r0\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L133\n" " dsll v1, v1, 2\n" " lw a2, *vif-disasm-table*(s7)\n" " daddu v1, v1, a2\n" " lwu v1, 12(v1)\n" " lwu a2, 16(v1)\n" " srl a3, s1, 31\n" " dsll32 v1, s1, 8\n" " dsrl32 t0, v1, 24\n" " dsll32 v1, s1, 16\n" " dsrl32 t1, v1, 16\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " beq r0, r0, L69\n" " sll r0, r0, 0\n" "L61:\n" " addiu a1, r0, 6\n" " bne a0, a1, L66\n" " or a1, s7, r0\n" " dsll32 a0, s1, 16\n" " dsrl32 a0, a0, 16\n" " beq s7, a0, L62\n" " sll r0, r0, 0\n" " lui s0, 16\n" " or a0, s0, r0\n" " beq r0, r0, L63\n" " sll r0, r0, 0\n" "L62:\n" " dsll32 a0, s1, 16\n" " dsrl32 a0, a0, 16\n" " dsll s0, a0, 4\n" " or a0, s0, r0\n" "L63:\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L132\n" " dsll v1, v1, 2\n" " lw a2, *vif-disasm-table*(s7)\n" " daddu v1, v1, a2\n" " lwu v1, 12(v1)\n" " lwu a2, 16(v1)\n" " srl a3, s1, 31\n" " dsll32 v1, s1, 16\n" " dsrl32 t0, v1, 16\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " daddiu v1, s4, 4\n" " sq v1, 32(sp)\n" " addiu v1, r0, 0\n" " sq v1, 48(sp)\n" " beq r0, r0, L65\n" " sll r0, r0, 0\n" "L64:\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L145\n" " lq v1, 48(sp)\n" " dsll v1, v1, 4\n" " daddiu v1, v1, 4\n" " daddu a2, v1, s4\n" " lq v1, 32(sp)\n" " lq a3, 48(sp)\n" " dsll a3, a3, 2\n" " dsll a3, a3, 2\n" " daddu v1, v1, a3\n" " lwu a3, 0(v1)\n" " lq v1, 32(sp)\n" " lq t0, 48(sp)\n" " dsll t0, t0, 2\n" " daddiu t0, t0, 1\n" " dsll t0, t0, 2\n" " daddu v1, v1, t0\n" " lwu t0, 0(v1)\n" " lq v1, 32(sp)\n" " lq t1, 48(sp)\n" " dsll t1, t1, 2\n" " daddiu t1, t1, 2\n" " dsll t1, t1, 2\n" " daddu v1, v1, t1\n" " lwu t1, 0(v1)\n" " lq v1, 32(sp)\n" " lq t2, 48(sp)\n" " dsll t2, t2, 2\n" " daddiu t2, t2, 3\n" " dsll t2, t2, 2\n" " daddu v1, v1, t2\n" " lwu t2, 0(v1)\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " lq v1, 48(sp)\n" " daddiu v1, v1, 1\n" " sq v1, 48(sp)\n" "L65:\n" " lq v1, 48(sp)\n" " dsll32 a0, s1, 16\n" " dsrl32 a0, a0, 16\n" " slt v1, v1, a0\n" " bne v1, r0, L64\n" " sll r0, r0, 0\n" " or v1, s7, r0\n" " or v1, s7, r0\n" " or v0, v1, r0\n" " beq r0, r0, L69\n" " sll r0, r0, 0\n" "L66:\n" " addiu a1, r0, 7\n" " bne a0, a1, L68\n" " or a1, s7, r0\n" " addiu a0, r0, -4\n" " dsll a1, v1, 2\n" " lw a2, *vif-disasm-table*(s7)\n" " daddu a1, a1, a2\n" " lwu a1, 12(a1)\n" " lwu a1, 8(a1)\n" " dsll32 a2, s1, 8\n" " dsrl32 a2, a2, 24\n" " multu3 a1, a1, a2\n" " daddiu a1, a1, 3\n" " and a0, a0, a1\n" " daddiu s0, a0, 4\n" " dsll32 a0, s1, 16\n" " dsrl32 a0, a0, 16\n" " sq a0, 64(sp)\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L131\n" " dsll v1, v1, 2\n" " lw a2, *vif-disasm-table*(s7)\n" " daddu v1, v1, a2\n" " lwu v1, 12(v1)\n" " lwu a2, 16(v1)\n" " srl a3, s1, 31\n" " dsll32 v1, s1, 8\n" " dsrl32 t0, v1, 24\n" " lq v1, 64(sp)\n" " dsll32 v1, v1, 22\n" " dsrl32 t1, v1, 22\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L130\n" " dsll32 v1, s1, 3\n" " dsrl32 a2, v1, 31\n" " lq v1, 64(sp)\n" " dsll32 v1, v1, 16\n" " dsrl32 a3, v1, 31\n" " lq v1, 64(sp)\n" " dsll32 v1, v1, 17\n" " dsrl32 t0, v1, 31\n" " or t1, s0, r0\n" " jalr ra, t9\n" " sll v0, ra, 0\n" " beq s7, s2, L67\n" " or v0, s7, r0\n" " lw t9, disasm-vif-details(s7)\n" " or a0, s3, r0\n" " or a1, s4, r0\n" " lq v1, 16(sp)\n" " andi a2, v1, 239\n" " dsll32 v1, s1, 8\n" " dsrl32 a3, v1, 24\n" " jalr ra, t9\n" " sll v0, ra, 0\n" "L67:\n" " or v1, v0, r0\n" " or v0, v1, r0\n" " beq r0, r0, L69\n" " sll r0, r0, 0\n" "L68:\n" " addiu v1, r0, 8\n" " bne a0, v1, L69\n" " or v0, s7, r0\n" " lw t9, format(s7)\n" " or a0, s3, r0\n" " daddiu a1, fp, L129\n" " dsll32 v1, s1, 1\n" " dsrl32 a2, v1, 25\n" " jalr ra, t9\n" " sll v0, ra, 0\n" "L69:\n" " or v1, v0, r0\n" " lw v1, *vif-disasm-table*(s7)\n" " lw v1, 0(v1)\n" " or a0, v1, r0\n" "L70:\n" " daddiu v1, v1, 1\n" "L71:\n" " lw a0, *vif-disasm-table*(s7)\n" " lw a0, 0(a0)\n" " slt a0, v1, a0\n" " bne a0, r0, L55\n" " sll r0, r0, 0\n" " or v1, s7, r0\n" " or v1, s7, r0\n" " daddu gp, gp, s0\n" " daddu s4, s4, s0\n" " or v1, s4, r0\n" "L72:\n" " dsll v1, s5, 2\n" " slt v1, gp, v1\n" " bne v1, r0, L54\n" " sll r0, r0, 0\n" " or v1, s7, r0\n" " dsll v1, s5, 2\n" " dsubu v0, gp, v1\n" " ld ra, 0(sp)\n" " ld fp, 8(sp)\n" " lq gp, 176(sp)\n" " lq s5, 160(sp)\n" " lq s4, 144(sp)\n" " lq s3, 128(sp)\n" " lq s2, 112(sp)\n" " lq s1, 96(sp)\n" " lq s0, 80(sp)\n" " jr ra\n" " daddiu sp, sp, 192"; std::string type = "(function (pointer vif-tag) int symbol symbol int)"; std::string expected = "(let ((gp-0 0))\n" " (while (< gp-0 (* arg1 4))\n" " (let ((s0-0 4))\n" " (let ((s1-0 (-> arg0 0)))\n" " (format arg2 \" #x~X:\" arg0)\n" " (dotimes (v1-0 (-> *vif-disasm-table* length))\n" " (set! sv-16 (-> s1-0 cmd))\n" " (when\n" " (=\n" " (logand sv-16 (-> *vif-disasm-table* v1-0 mask))\n" " (-> *vif-disasm-table* v1-0 tag)\n" " )\n" " (let ((a0-12 (-> *vif-disasm-table* v1-0 print)))\n" " (cond\n" " ((zero? a0-12)\n" " (format\n" " arg2\n" " \" (~s :irq ~D)~%\"\n" " (-> *vif-disasm-table* v1-0 string1)\n" " (-> s1-0 irq)\n" " )\n" " )\n" " ((= a0-12 1)\n" " (format\n" " arg2\n" " \" (~s :irq ~D :~s #x~X)~%\"\n" " (-> *vif-disasm-table* v1-0 string1)\n" " (-> s1-0 irq)\n" " (-> *vif-disasm-table* v1-0 string2)\n" " (-> s1-0 imm)\n" " )\n" " )\n" " ((= a0-12 2)\n" " (let ((t1-1 (-> s1-0 imm)))\n" " (format\n" " arg2\n" " \" (~s :irq ~D :wl ~D :cl ~D)~%\"\n" " (-> *vif-disasm-table* v1-0 string1)\n" " (-> s1-0 irq)\n" " (shr (shl t1-1 48) 56)\n" " (shr (shl t1-1 56) 56)\n" " )\n" " )\n" " )\n" " ((= a0-12 3)\n" " (set! s0-0 8)\n" " (format\n" " arg2\n" " \" (~s :irq ~D :~s #x~X)~%\"\n" " (-> *vif-disasm-table* v1-0 string1)\n" " (-> s1-0 irq)\n" " (-> *vif-disasm-table* v1-0 string2)\n" " (-> arg0 1)\n" " )\n" " )\n" " ((= a0-12 4)\n" " (set! s0-0 20)\n" " (format\n" " arg2\n" " \" (~s :irq ~D :~s \"\n" " (-> *vif-disasm-table* v1-0 string1)\n" " (-> s1-0 irq)\n" " (-> *vif-disasm-table* v1-0 string2)\n" " )\n" " (format\n" " arg2\n" " \"#x~X #x~X #x~X #x~X)~%\"\n" " (-> arg0 1)\n" " (-> arg0 2)\n" " (-> arg0 3)\n" " (-> arg0 4)\n" " )\n" " )\n" " ((= a0-12 5)\n" " (format\n" " arg2\n" " \" (~s :irq ~D :instructions #x~D :addr #x~X)~%\"\n" " (-> *vif-disasm-table* v1-0 string1)\n" " (-> s1-0 irq)\n" " (-> s1-0 num)\n" " (-> s1-0 imm)\n" " )\n" " )\n" " ((= a0-12 6)\n" " (if (-> s1-0 imm)\n" " (set! s0-0 #x100000)\n" " (set! s0-0 (the-as int (* (-> s1-0 imm) 16)))\n" " )\n" " (format\n" " arg2\n" " \" (~s :irq ~D :qwc #x~D)~%\"\n" " (-> *vif-disasm-table* v1-0 string1)\n" " (-> s1-0 irq)\n" " (-> s1-0 imm)\n" " )\n" " (set! sv-32 (&-> arg0 1))\n" " (set! sv-48 0)\n" " (while (< sv-48 (the-as int (-> s1-0 imm)))\n" " (format\n" " arg2\n" " \" #x~X: #x~8x #x~8x #x~8x #x~8x~%\"\n" " (+ (+ (* sv-48 16) 4) (the-as int arg0))\n" " (-> sv-32 (* sv-48 4))\n" " (-> sv-32 (+ (* sv-48 4) 1))\n" " (-> sv-32 (+ (* sv-48 4) 2))\n" " (-> sv-32 (+ (* sv-48 4) 3))\n" " )\n" " (set! sv-48 (+ sv-48 1))\n" " )\n" " #f\n" " )\n" " ((= a0-12 7)\n" " (set!\n" " s0-0\n" " (the-as\n" " int\n" " (+\n" " (logand\n" " -4\n" " (+ (* (-> *vif-disasm-table* v1-0 val) (-> s1-0 num)) 3)\n" " )\n" " 4\n" " )\n" " )\n" " )\n" " (set! sv-64 (-> s1-0 imm))\n" " (format\n" " arg2\n" " \" (~s :irq ~D :num ~D :addr #x~X \"\n" " (-> *vif-disasm-table* v1-0 string1)\n" " (-> s1-0 irq)\n" " (-> s1-0 num)\n" " (shr (shl sv-64 54) 54)\n" " )\n" " (format\n" " arg2\n" " \":msk ~D :flg ~D :usn ~D [skip ~d])~%\"\n" " (-> s1-0 msk)\n" " (shr (shl sv-64 48) 63)\n" " (shr (shl sv-64 49) 63)\n" " (the-as uint s0-0)\n" " )\n" " (if arg3\n" " (disasm-vif-details\n" " arg2\n" " (the-as (pointer uint8) arg0)\n" " (logand sv-16 (vif-cmd cmd-mask))\n" " (the-as int (-> s1-0 num))\n" " )\n" " )\n" " )\n" " ((= a0-12 8)\n" " (format arg2 \" (*unknown* vif-tag #x~X)~%\" (-> s1-0 cmd))\n" " )\n" " )\n" " )\n" " (set! v1-0 (-> *vif-disasm-table* length))\n" " )\n" " )\n" " )\n" " (+! gp-0 s0-0)\n" " (&+! arg0 s0-0)\n" " )\n" " )\n" " (- gp-0 (* arg1 4))\n" " )"; test_with_expr(func, type, expected, false, "", {{"L139", " #x~X:"}, {"L138", " (~s :irq ~D)~%"}, {"L137", " (~s :irq ~D :~s #x~X)~%"}, {"L136", " (~s :irq ~D :wl ~D :cl ~D)~%"}, {"L135", " (~s :irq ~D :~s "}, {"L134", "#x~X #x~X #x~X #x~X)~%"}, {"L133", " (~s :irq ~D :instructions #x~D :addr #x~X)~%"}, {"L132", " (~s :irq ~D :qwc #x~D)~%"}, {"L145", " #x~X: #x~8x #x~8x #x~8x #x~8x~%"}, {"L131", " (~s :irq ~D :num ~D :addr #x~X "}, {"L130", ":msk ~D :flg ~D :usn ~D [skip ~d])~%"}, {"L129", " (*unknown* vif-tag #x~X)~%"}}); }