[decompiler] Support accessing 128-bit bitfields (#514)

* support some 128-bit bitfield stuff

* fix bug

* support type stuff correctly
This commit is contained in:
water111
2021-05-21 20:36:04 -04:00
committed by GitHub
parent 6ac399ca33
commit 3fbdd662dc
14 changed files with 497 additions and 279 deletions
+24 -153
View File
@@ -767,160 +767,31 @@
;; definition for method 3 of type gif-tag
;; INFO: Return type mismatch object vs gif-tag.
;; WARN: Unsupported inline assembly instruction kind - [por gp, a0, r0]
;; WARN: Unsupported inline assembly instruction kind - [por a2, gp, r0]
;; WARN: Unsupported inline assembly instruction kind - [srl a2, v1, 28]
(defmethod inspect gif-tag ((obj gif-tag))
(local-vars
(r0-0 none)
(v1-6 uint128)
(v1-8 uint128)
(v1-10 uint128)
(v1-12 uint128)
(v1-14 uint128)
(v1-16 uint128)
(v1-18 uint128)
(v1-20 uint128)
(v1-21 uint128)
(v1-23 uint128)
(v1-25 uint128)
(v1-27 uint128)
(v1-29 uint128)
(v1-31 uint128)
(v1-33 uint128)
(v1-35 uint128)
(a2-0 uint128)
(a2-15 uint128)
(gp-0 uint128)
)
(.por gp-0 obj r0-0)
(let ((t9-0 format)
(a0-1 #t)
(a1-0 "[~8x] gif-tag~%")
)
(.por a2-0 gp-0 r0-0)
(t9-0 a0-1 a1-0 a2-0)
)
(format #t "~Tnloop: ~4d~%" (shr (shl (the-as int gp-0) 49) 49))
(format #t "~Teop : ~4d~%" (shr (shl (the-as int gp-0) 48) 63))
(format #t "~Tid : ~4d~%" (shr (shl (the-as int gp-0) 18) 50))
(format #t "~Tpre : ~4d~%" (shr (shl (the-as int gp-0) 17) 63))
(format #t "~Tprim : ~4d~%" (shr (* gp-0 64) 53))
(format #t "~Tflg : ~4d~%" (shr (* gp-0 16) 62))
(format #t "~Tnreg : ~4d~%" (shr (the-as int gp-0) 60))
(let ((t9-8 format)
(a0-9 #t)
(a1-8 "~Tregs0 : ~4d~%")
)
(.pcpyud v1-6 gp-0 r0-0)
(t9-8 a0-9 a1-8 (shr (shl (the-as int v1-6) 60) 60))
)
(let ((t9-9 format)
(a0-10 #t)
(a1-9 "~Tregs1 : ~4d~%")
)
(.pcpyud v1-8 gp-0 r0-0)
(t9-9 a0-10 a1-9 (shr (shl (the-as int v1-8) 56) 60))
)
(let ((t9-10 format)
(a0-11 #t)
(a1-10 "~Tregs2 : ~4d~%")
)
(.pcpyud v1-10 gp-0 r0-0)
(t9-10 a0-11 a1-10 (shr (shl (the-as int v1-10) 52) 60))
)
(let ((t9-11 format)
(a0-12 #t)
(a1-11 "~Tregs3 : ~4d~%")
)
(.pcpyud v1-12 gp-0 r0-0)
(t9-11 a0-12 a1-11 (shr (shl (the-as int v1-12) 48) 60))
)
(let ((t9-12 format)
(a0-13 #t)
(a1-12 "~Tregs4 : ~4d~%")
)
(.pcpyud v1-14 gp-0 r0-0)
(t9-12 a0-13 a1-12 (shr (shl (the-as int v1-14) 44) 60))
)
(let ((t9-13 format)
(a0-14 #t)
(a1-13 "~Tregs5 : ~4d~%")
)
(.pcpyud v1-16 gp-0 r0-0)
(t9-13 a0-14 a1-13 (shr (shl (the-as int v1-16) 40) 60))
)
(let ((t9-14 format)
(a0-15 #t)
(a1-14 "~Tregs6 : ~4d~%")
)
(.pcpyud v1-18 gp-0 r0-0)
(t9-14 a0-15 a1-14 (shr (shl (the-as int v1-18) 36) 60))
)
(let ((t9-15 format)
(a0-16 #t)
(a1-15 "~Tregs7 : ~4d~%")
)
(.pcpyud v1-20 gp-0 r0-0)
(.srl a2-15 v1-20 28)
(t9-15 a0-16 a1-15 a2-15)
)
(let ((t9-16 format)
(a0-17 #t)
(a1-16 "~Tregs8 : ~4d~%")
)
(.pcpyud v1-21 gp-0 r0-0)
(t9-16 a0-17 a1-16 (shr (shl (the-as int v1-21) 28) 60))
)
(let ((t9-17 format)
(a0-18 #t)
(a1-17 "~Tregs9 : ~4d~%")
)
(.pcpyud v1-23 gp-0 r0-0)
(t9-17 a0-18 a1-17 (shr (shl (the-as int v1-23) 24) 60))
)
(let ((t9-18 format)
(a0-19 #t)
(a1-18 "~Tregs10: ~4d~%")
)
(.pcpyud v1-25 gp-0 r0-0)
(t9-18 a0-19 a1-18 (shr (shl (the-as int v1-25) 20) 60))
)
(let ((t9-19 format)
(a0-20 #t)
(a1-19 "~Tregs11: ~4d~%")
)
(.pcpyud v1-27 gp-0 r0-0)
(t9-19 a0-20 a1-19 (shr (shl (the-as int v1-27) 16) 60))
)
(let ((t9-20 format)
(a0-21 #t)
(a1-20 "~Tregs12: ~4d~%")
)
(.pcpyud v1-29 gp-0 r0-0)
(t9-20 a0-21 a1-20 (shr (shl (the-as int v1-29) 12) 60))
)
(let ((t9-21 format)
(a0-22 #t)
(a1-21 "~Tregs13: ~4d~%")
)
(.pcpyud v1-31 gp-0 r0-0)
(t9-21 a0-22 a1-21 (shr (* v1-31 256) 60))
)
(let ((t9-22 format)
(a0-23 #t)
(a1-22 "~Tregs14: ~4d~%")
)
(.pcpyud v1-33 gp-0 r0-0)
(t9-22 a0-23 a1-22 (shr (* v1-33 16) 60))
)
(let ((t9-23 format)
(a0-24 #t)
(a1-23 "~Tregs15: ~4d~%")
)
(.pcpyud v1-35 gp-0 r0-0)
(the-as gif-tag (t9-23 a0-24 a1-23 (shr (the-as int v1-35) 60)))
)
(format #t "[~8x] gif-tag~%" obj)
(format #t "~Tnloop: ~4d~%" (-> obj nloop))
(format #t "~Teop : ~4d~%" (-> obj eop))
(format #t "~Tid : ~4d~%" (-> obj id))
(format #t "~Tpre : ~4d~%" (-> obj pre))
(format #t "~Tprim : ~4d~%" (-> obj prim))
(format #t "~Tflg : ~4d~%" (-> obj flg))
(format #t "~Tnreg : ~4d~%" (-> obj nreg))
(format #t "~Tregs0 : ~4d~%" (-> obj regs0))
(format #t "~Tregs1 : ~4d~%" (-> obj regs1))
(format #t "~Tregs2 : ~4d~%" (-> obj regs2))
(format #t "~Tregs3 : ~4d~%" (-> obj regs3))
(format #t "~Tregs4 : ~4d~%" (-> obj regs4))
(format #t "~Tregs5 : ~4d~%" (-> obj regs5))
(format #t "~Tregs6 : ~4d~%" (-> obj regs6))
(format #t "~Tregs7 : ~4d~%" (-> obj regs7))
(format #t "~Tregs8 : ~4d~%" (-> obj regs8))
(format #t "~Tregs9 : ~4d~%" (-> obj regs9))
(format #t "~Tregs10: ~4d~%" (-> obj regs10))
(format #t "~Tregs11: ~4d~%" (-> obj regs11))
(format #t "~Tregs12: ~4d~%" (-> obj regs12))
(format #t "~Tregs13: ~4d~%" (-> obj regs13))
(format #t "~Tregs14: ~4d~%" (-> obj regs14))
(the-as gif-tag (format #t "~Tregs15: ~4d~%" (-> obj regs15)))
)
;; definition for symbol *fog-color*, type int
+15 -82
View File
@@ -112,94 +112,27 @@
)
;; definition for method 3 of type vec4s
;; INFO: Return type mismatch uint128 vs vec4s.
;; WARN: Unsupported inline assembly instruction kind - [por gp, a0, r0]
;; WARN: Unsupported inline assembly instruction kind - [por a2, gp, r0]
;; WARN: Unsupported inline assembly instruction kind - [sllv a2, gp, r0]
;; WARN: Unsupported inline assembly instruction kind - [sllv a2, v1, r0]
;; WARN: Unsupported inline assembly instruction kind - [por v0, gp, r0]
(defmethod inspect vec4s ((obj vec4s))
(local-vars
(r0-0 none)
(v0-5 uint128)
(v1-0 uint128)
(v1-1 uint128)
(a2-0 uint128)
(a2-1 uint128)
(a2-3 uint128)
(gp-0 uint128)
)
(.por gp-0 obj r0-0)
(let ((t9-0 format)
(a0-1 #t)
(a1-0 "[~8x] ~A~%")
)
(.por a2-0 gp-0 r0-0)
(t9-0 a0-1 a1-0 a2-0 'vec4s)
)
(let ((t9-1 format)
(a0-2 #t)
(a1-1 "~Tx: ~f~%")
)
(.sllv a2-1 gp-0 r0-0)
(t9-1 a0-2 a1-1 a2-1)
)
(format #t "~Ty: ~f~%" (sar (the-as int gp-0) 32))
(let ((t9-3 format)
(a0-4 #t)
(a1-3 "~Tz: ~f~%")
)
(.pcpyud v1-0 gp-0 r0-0)
(.sllv a2-3 v1-0 r0-0)
(t9-3 a0-4 a1-3 a2-3)
)
(let ((t9-4 format)
(a0-5 #t)
(a1-4 "~Tw: ~f~%")
)
(.pcpyud v1-1 gp-0 r0-0)
(t9-4 a0-5 a1-4 (sar (the-as int v1-1) 32))
)
(.por v0-5 gp-0 r0-0)
(the-as vec4s v0-5)
(format #t "[~8x] ~A~%" obj 'vec4s)
(format #t "~Tx: ~f~%" (-> obj x))
(format #t "~Ty: ~f~%" (-> obj y))
(format #t "~Tz: ~f~%" (-> obj z))
(format #t "~Tw: ~f~%" (-> obj w))
obj
)
;; definition for method 2 of type vec4s
;; INFO: Return type mismatch uint128 vs vec4s.
;; WARN: Unsupported inline assembly instruction kind - [por gp, a0, r0]
;; WARN: Unsupported inline assembly instruction kind - [sllv a2, gp, r0]
;; WARN: Unsupported inline assembly instruction kind - [sllv t0, v1, r0]
;; WARN: Unsupported inline assembly instruction kind - [por t2, gp, r0]
;; WARN: Unsupported inline assembly instruction kind - [por v0, gp, r0]
(defmethod print vec4s ((obj vec4s))
(local-vars
(r0-0 none)
(v0-1 uint128)
(v1-0 uint128)
(v1-1 uint128)
(a2-0 uint128)
(t0-0 uint128)
(t2-0 uint128)
(gp-0 uint128)
(format
#t
"#<vector ~F ~F ~F ~F @ #x~X>"
(-> obj x)
(-> obj y)
(-> obj z)
(-> obj w)
obj
)
(.por gp-0 obj r0-0)
(let ((t9-0 format)
(a0-1 #t)
(a1-0 "#<vector ~F ~F ~F ~F @ #x~X>")
)
(.sllv a2-0 gp-0 r0-0)
(let ((a3-0 (sar (the-as int gp-0) 32)))
(.pcpyud v1-0 gp-0 r0-0)
(.sllv t0-0 v1-0 r0-0)
(.pcpyud v1-1 gp-0 r0-0)
(let ((t1-0 (sar (the-as int v1-1) 32)))
(.por t2-0 gp-0 r0-0)
(t9-0 a0-1 a1-0 a2-0 a3-0 t0-0 t1-0 t2-0)
)
)
)
(.por v0-1 gp-0 r0-0)
(the-as vec4s v0-1)
obj
)
;; definition of type bfloat
@@ -286,9 +286,8 @@
;; definition for method 2 of type handle
;; WARN: Unsupported inline assembly instruction kind - [subu a2, v1, s7]
;; WARN: Unsupported inline assembly instruction kind - [sllv a2, v1, r0]
(defmethod print handle ((obj handle))
(local-vars (r0-0 none) (a2-0 int) (a2-2 (pointer process)) (s7-0 none))
(local-vars (a2-0 int) (s7-0 none))
(cond
((nonzero? obj)
(let ((t9-0 format)
@@ -297,15 +296,17 @@
(v1-0 obj)
)
(.subu a2-0 v1-0 s7-0)
(t9-0 a0-1 a1-0 (and (nonzero? a2-0) (begin
(.sllv a2-2 v1-0 r0-0)
(let ((a3-0 (-> a2-2 0)))
(if (= (-> v1-0 pid) (-> a3-0 pid))
a3-0
)
)
)
)
(t9-0
a0-1
a1-0
(and
(nonzero? a2-0)
(let ((a3-0 (-> (the-as (pointer process) (-> v1-0 process)) 0)))
(if (= (-> v1-0 pid) (-> a3-0 pid))
a3-0
)
)
)
(-> obj pid)
)
)
@@ -1142,4 +1142,88 @@ TEST_F(FormRegressionTest, Method11FontContext) {
" arg0\n"
" )";
test_with_expr(func, type, expected);
}
// 128-bit bitfields, also type for pextuw
TEST_F(FormRegressionTest, Method4ResTag) {
std::string func =
"sll r0, r0, 0\n"
"L135:\n"
" pcpyud v1, a0, r0\n"
" dsrl32 v1, v1, 31\n"
" bne v1, r0, L136\n"
" sll r0, r0, 0\n"
" pcpyud v1, a0, r0\n"
" dsll v1, v1, 1\n"
" dsrl32 v1, v1, 17\n"
" dsll v0, v1, 2\n"
" beq r0, r0, L137\n"
" sll r0, r0, 0\n"
"L136:\n"
" pcpyud v1, a0, r0\n"
" dsll v1, v1, 1\n"
" dsrl32 v1, v1, 17\n"
" pextuw a0, r0, a0\n"
" lhu a0, 8(a0)\n"
" multu3 v0, v1, a0\n"
"L137:\n"
" jr ra\n"
" daddu sp, sp, r0";
std::string type = "(function res-tag int)";
std::string expected =
"(the-as int (if (zero? (-> arg0 inlined?))\n"
" (* (-> arg0 elt-count) 4)\n"
" (* (the-as uint (-> arg0 elt-count)) (-> arg0 elt-type size))\n"
" )\n"
" )";
test_with_expr(func, type, expected);
}
TEST_F(FormRegressionTest, Method2Vec4s) {
std::string func =
"sll r0, r0, 0\n"
" daddiu sp, sp, -32\n"
" sd ra, 0(sp)\n"
" sd fp, 8(sp)\n"
" or fp, t9, r0\n"
" sq gp, 16(sp)\n"
" por gp, a0, r0\n"
" lw t9, format(s7)\n"
" daddiu a0, s7, #t\n"
" daddiu a1, fp, L344\n"
" sllv a2, gp, r0\n"
" dsra32 a3, gp, 0\n"
" pcpyud v1, gp, r0\n"
" sllv t0, v1, r0\n"
" pcpyud v1, gp, r0\n"
" dsra32 t1, v1, 0\n"
" por t2, gp, r0\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" por v0, gp, r0\n"
" ld ra, 0(sp)\n"
" ld fp, 8(sp)\n"
" lq gp, 16(sp)\n"
" jr ra\n"
" daddiu sp, sp, 32";
std::string type = "(function vec4s vec4s)";
std::string expected =
"(begin\n"
" (format\n"
" #t\n"
" \"#<vector ~F ~F ~F ~F @ #x~X>\"\n"
" (-> arg0 x)\n"
" (-> arg0 y)\n"
" (-> arg0 z)\n"
" (-> arg0 w)\n"
" arg0\n"
" )\n"
" arg0\n"
" )";
test_with_expr(func, type, expected, false, "", {{"L344", "#<vector ~F ~F ~F ~F @ #x~X>"}});
}
-5
View File
@@ -75,8 +75,6 @@ const std::unordered_set<std::string> g_functions_to_skip_compiling = {
"abs", "ash", "min", "max", "lognor",
// weird PS2 specific debug registers:
"breakpoint-range-set!",
// int128 fancy stuff.
"(method 3 vec4s)", "(method 2 vec4s)",
// does weird stuff with the type system.
"print", "printl", "inspect",
// inline assembly
@@ -119,9 +117,6 @@ const std::unordered_set<std::string> g_functions_to_skip_compiling = {
// dma-disasm
"disasm-dma-list", // missing a single cast :(
// gs
"(method 3 gif-tag)", // inspect for a 128-bit type.
// math camera
"transform-point-vector!", "transform-point-qword!", "transform-point-vector-scale!",