mirror of
https://github.com/open-goal/jak-project
synced 2026-06-26 10:31:54 -04:00
[Decomp] Decompile gstring (#267)
* decompile gstring * update * Update code_status.md * Update code_status.md * decompile gstate * add test for states, hope it passes * also test throw and catch xmms * update doc
This commit is contained in:
@@ -102,6 +102,9 @@ std::unique_ptr<FormRegressionTest::TestData> FormRegressionTest::make_function(
|
||||
test->func.analyze_prologue(test->file);
|
||||
test->func.cfg = build_cfg(test->file, 0, test->func);
|
||||
EXPECT_TRUE(test->func.cfg->is_fully_resolved());
|
||||
if (!test->func.cfg->is_fully_resolved()) {
|
||||
fmt::print("CFG:\n{}\n", test->func.cfg->to_dot());
|
||||
}
|
||||
|
||||
auto ops = convert_function_to_atomic_ops(test->func, program.labels);
|
||||
test->func.ir2.atomic_ops = std::make_shared<FunctionAtomicOps>(std::move(ops));
|
||||
|
||||
@@ -2074,12 +2074,9 @@ TEST_F(FormRegressionTest, ExprPrintl) {
|
||||
" daddiu sp, sp, 32";
|
||||
std::string type = "(function object object)";
|
||||
|
||||
// todo - I think this is a sign that we're unscrambling method calls in the wrong order.
|
||||
// but I want to wait for a less confusing example before making a change.
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (set! a0-1 arg0)\n"
|
||||
" ((method-of-type (rtype-of a0-1) print) a0-1)\n"
|
||||
" ((method-of-type (rtype-of a0-1) print) arg0)\n"
|
||||
" (format (quote #t) \"~%\")\n"
|
||||
" arg0\n"
|
||||
" )";
|
||||
@@ -2355,4 +2352,155 @@ TEST_F(FormRegressionTest, ExprStopwatchElapsedSeconds) {
|
||||
|
||||
std::string expected = "(begin (set! v1-0 (abs arg0)) (* (l.f L20) (the float v1-0)))";
|
||||
test_with_expr(func, type, expected, false, "");
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, ExprCopyStringString) {
|
||||
std::string func =
|
||||
" sll r0, r0, 0\n"
|
||||
"L161:\n"
|
||||
" daddiu v1, a0, 4\n"
|
||||
" daddiu a1, a1, 4\n"
|
||||
" beq r0, r0, L163\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L162:\n"
|
||||
" lbu a2, 0(a1)\n"
|
||||
" sb a2, 0(v1)\n"
|
||||
" daddiu v1, v1, 1\n"
|
||||
" daddiu a1, a1, 1\n"
|
||||
|
||||
"L163:\n"
|
||||
" lbu a2, 0(a1)\n"
|
||||
" bne a2, r0, L162\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" or a1, s7, r0\n"
|
||||
" sb r0, 0(v1)\n"
|
||||
" or v0, a0, r0\n"
|
||||
" jr ra\n"
|
||||
" daddu sp, sp, r0";
|
||||
std::string type = "(function string string string)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (set! v1-0 (-> arg0 data))\n"
|
||||
" (set! a1-1 (-> arg1 data))\n"
|
||||
" (while\n"
|
||||
" (nonzero? (-> a1-1 0))\n"
|
||||
" (set! (-> v1-0 0) (-> a1-1 0))\n"
|
||||
" (set! v1-0 (&-> v1-0 1))\n"
|
||||
" (set! a1-1 (&-> a1-1 1))\n"
|
||||
" )\n"
|
||||
" (set! (-> v1-0 0) 0)\n"
|
||||
" arg0\n"
|
||||
" )";
|
||||
test_with_expr(func, type, expected, false, "");
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, StringLt) {
|
||||
std::string func =
|
||||
" sll r0, r0, 0\n"
|
||||
"L91:\n"
|
||||
" daddiu sp, sp, -64\n"
|
||||
" sd ra, 0(sp)\n"
|
||||
" sq s4, 16(sp)\n"
|
||||
" sq s5, 32(sp)\n"
|
||||
" sq gp, 48(sp)\n"
|
||||
|
||||
" or gp, a0, r0\n"
|
||||
" or s5, a1, r0\n"
|
||||
" or a0, gp, r0\n"
|
||||
" lw v1, string(s7)\n"
|
||||
" lwu t9, 32(v1)\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" or v1, v0, r0\n"
|
||||
" or s4, v1, r0\n"
|
||||
" or a0, s5, r0\n"
|
||||
" lw v1, string(s7)\n"
|
||||
" lwu t9, 32(v1)\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" or v1, v0, r0\n"
|
||||
" slt a0, s4, v1\n"
|
||||
" movz s4, v1, a0\n"
|
||||
" addiu v1, r0, 0\n"
|
||||
" beq r0, r0, L95\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L92:\n"
|
||||
" daddu a0, v1, gp\n"
|
||||
" lbu a0, 4(a0)\n"
|
||||
" daddu a1, v1, s5\n"
|
||||
" lbu a1, 4(a1)\n"
|
||||
" sltu a0, a0, a1\n"
|
||||
" beq a0, r0, L93\n"
|
||||
" or a0, s7, r0\n"
|
||||
|
||||
" daddiu v1, s7, #t\n"
|
||||
" or v0, v1, r0\n"
|
||||
" beq r0, r0, L96\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" or v1, r0, r0\n"
|
||||
" beq r0, r0, L94\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L93:\n"
|
||||
" daddu a0, v1, s5\n"
|
||||
" lbu a0, 4(a0)\n"
|
||||
" daddu a1, v1, gp\n"
|
||||
" lbu a1, 4(a1)\n"
|
||||
" sltu a0, a0, a1\n"
|
||||
" beq a0, r0, L94\n"
|
||||
" or a0, s7, r0\n"
|
||||
|
||||
" or v0, s7, r0\n"
|
||||
" beq r0, r0, L96\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" or v1, r0, r0\n"
|
||||
|
||||
"L94:\n"
|
||||
" daddiu v1, v1, 1\n"
|
||||
|
||||
"L95:\n"
|
||||
" slt a0, v1, s4\n"
|
||||
" bne a0, r0, L92\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" or v1, s7, r0\n"
|
||||
" or v1, s7, r0\n"
|
||||
" or v0, s7, r0\n"
|
||||
|
||||
"L96:\n"
|
||||
" ld ra, 0(sp)\n"
|
||||
" lq gp, 48(sp)\n"
|
||||
" lq s5, 32(sp)\n"
|
||||
" lq s4, 16(sp)\n"
|
||||
" jr ra\n"
|
||||
" daddiu sp, sp, 64";
|
||||
std::string type = "(function string string symbol)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (set!\n"
|
||||
" s4-1\n"
|
||||
" (min\n"
|
||||
" ((method-of-type string length) arg0)\n"
|
||||
" ((method-of-type string length) arg1)\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" (set! v1-4 0)\n"
|
||||
" (while\n"
|
||||
" (< v1-4 s4-1)\n"
|
||||
" (cond\n"
|
||||
" ((< (-> arg0 data v1-4) (-> arg1 data v1-4)) (return (quote #t)))\n"
|
||||
" ((< (-> arg1 data v1-4) (-> arg0 data v1-4)) (return (quote #f)))\n"
|
||||
" )\n"
|
||||
" (set! v1-4 (+ v1-4 1))\n"
|
||||
" )\n"
|
||||
" (quote #f)\n"
|
||||
" )";
|
||||
test_with_expr(func, type, expected, false, "");
|
||||
}
|
||||
@@ -2189,4 +2189,393 @@ TEST_F(FormRegressionTest, ExprValid) {
|
||||
{"L315", "ERROR: object #x~X ~S is not a valid object of type '~A' (not in symbol table)~%"},
|
||||
{"L314",
|
||||
"ERROR: object #x~X ~S is not a valid object of type '~A' (inside symbol table)~%"}});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, ExprStringToInt) {
|
||||
std::string func =
|
||||
" sll r0, r0, 0\n"
|
||||
"L14:\n"
|
||||
" daddiu a0, a0, 4\n"
|
||||
" addiu v0, r0, 0\n"
|
||||
" or v1, s7, r0\n"
|
||||
" addiu a1, r0, 35\n"
|
||||
" lbu a2, 0(a0)\n"
|
||||
" bne a2, a1, L33\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" daddiu a0, a0, 1\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" daddiu a1, a1, -120\n"
|
||||
" daddiu a2, s7, 8\n"
|
||||
" movn a2, s7, a1\n"
|
||||
" bnel s7, a2, L15\n"
|
||||
|
||||
" or a1, a2, r0\n"
|
||||
|
||||
" lbu a1, 0(a0)\n"
|
||||
" daddiu a2, a1, -88\n"
|
||||
" daddiu a1, s7, 8\n"
|
||||
" movn a1, s7, a2\n"
|
||||
|
||||
"L15:\n"
|
||||
" beq s7, a1, L27\n"
|
||||
" or a1, s7, r0\n"
|
||||
|
||||
" daddiu a0, a0, 1\n"
|
||||
" addiu a1, r0, 45\n"
|
||||
" lbu a2, 1(a0)\n"
|
||||
" bne a2, a1, L16\n"
|
||||
" or a1, s7, r0\n"
|
||||
|
||||
" daddiu v1, s7, #t\n"
|
||||
" daddiu a0, a0, 1\n"
|
||||
" or a1, a0, r0\n"
|
||||
|
||||
"L16:\n"
|
||||
" beq r0, r0, L23\n"
|
||||
" sll r0, r0, 0\n"
|
||||
"\n"
|
||||
|
||||
"L17:\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" sltiu a1, a1, 65\n"
|
||||
" daddiu a2, s7, 8\n"
|
||||
" movn a2, s7, a1\n"
|
||||
" beql s7, a2, L18\n"
|
||||
|
||||
" or a1, a2, r0\n"
|
||||
|
||||
" addiu a1, r0, 70\n"
|
||||
" lbu a2, 0(a0)\n"
|
||||
" sltu a2, a1, a2\n"
|
||||
" daddiu a1, s7, 8\n"
|
||||
" movn a1, s7, a2\n"
|
||||
|
||||
"L18:\n"
|
||||
" beq s7, a1, L19\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" lbu a1, 0(a0)\n"
|
||||
" daddiu a1, a1, -55\n"
|
||||
" dsll a2, v0, 4\n"
|
||||
" daddu v0, a1, a2\n"
|
||||
" or a1, v0, r0\n"
|
||||
" beq r0, r0, L22\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L19:\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" sltiu a1, a1, 97\n"
|
||||
" daddiu a2, s7, 8\n"
|
||||
" movn a2, s7, a1\n"
|
||||
" beql s7, a2, L20\n"
|
||||
|
||||
" or a1, a2, r0\n"
|
||||
|
||||
" addiu a1, r0, 102\n"
|
||||
" lbu a2, 0(a0)\n"
|
||||
" sltu a2, a1, a2\n"
|
||||
" daddiu a1, s7, 8\n"
|
||||
" movn a1, s7, a2\n"
|
||||
|
||||
"L20:\n"
|
||||
" beq s7, a1, L21\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" lbu a1, 0(a0)\n"
|
||||
" daddiu a1, a1, -87\n"
|
||||
" dsll a2, v0, 4\n"
|
||||
" daddu v0, a1, a2\n"
|
||||
" or a1, v0, r0\n"
|
||||
" beq r0, r0, L22\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L21:\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" daddiu a1, a1, -48\n"
|
||||
" dsll a2, v0, 4\n"
|
||||
" daddu v0, a1, a2\n"
|
||||
" or a1, v0, r0\n"
|
||||
|
||||
"L22:\n"
|
||||
" daddiu a0, a0, 1\n"
|
||||
|
||||
"L23:\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" sltiu a1, a1, 48\n"
|
||||
" daddiu a2, s7, 8\n"
|
||||
" movn a2, s7, a1\n"
|
||||
" beql s7, a2, L24\n"
|
||||
|
||||
" or a1, a2, r0\n"
|
||||
|
||||
" addiu a1, r0, 57\n"
|
||||
" lbu a2, 0(a0)\n"
|
||||
" sltu a2, a1, a2\n"
|
||||
" daddiu a1, s7, 8\n"
|
||||
" movn a1, s7, a2\n"
|
||||
|
||||
"L24:\n"
|
||||
" bnel s7, a1, L26\n"
|
||||
|
||||
" or a1, a1, r0\n"
|
||||
|
||||
" lbu a1, 0(a0)\n"
|
||||
" sltiu a1, a1, 65\n"
|
||||
" daddiu a2, s7, 8\n"
|
||||
" movn a2, s7, a1\n"
|
||||
" beql s7, a2, L25\n"
|
||||
|
||||
" or a1, a2, r0\n"
|
||||
|
||||
" addiu a1, r0, 70\n"
|
||||
" lbu a2, 0(a0)\n"
|
||||
" sltu a2, a1, a2\n"
|
||||
" daddiu a1, s7, 8\n"
|
||||
" movn a1, s7, a2\n"
|
||||
|
||||
"L25:\n"
|
||||
" bnel s7, a1, L26\n"
|
||||
|
||||
" or a1, a1, r0\n"
|
||||
|
||||
" lbu a1, 0(a0)\n"
|
||||
" sltiu a1, a1, 97\n"
|
||||
" daddiu a2, s7, 8\n"
|
||||
" movn a2, s7, a1\n"
|
||||
" beql s7, a2, L26\n"
|
||||
|
||||
" or a1, a2, r0\n"
|
||||
|
||||
" addiu a1, r0, 102\n"
|
||||
" lbu a2, 0(a0)\n"
|
||||
" sltu a2, a1, a2\n"
|
||||
" daddiu a1, s7, 8\n"
|
||||
" movn a1, s7, a2\n"
|
||||
|
||||
"L26:\n"
|
||||
" bne s7, a1, L17\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" or a1, s7, r0\n"
|
||||
" beq r0, r0, L32\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L27:\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" daddiu a1, a1, -98\n"
|
||||
" daddiu a2, s7, 8\n"
|
||||
" movn a2, s7, a1\n"
|
||||
" bnel s7, a2, L28\n"
|
||||
|
||||
" or a1, a2, r0\n"
|
||||
|
||||
" lbu a1, 0(a0)\n"
|
||||
" daddiu a2, a1, -66\n"
|
||||
" daddiu a1, s7, 8\n"
|
||||
" movn a1, s7, a2\n"
|
||||
|
||||
"L28:\n"
|
||||
" beq s7, a1, L32\n"
|
||||
" or a1, s7, r0\n"
|
||||
|
||||
" daddiu a0, a0, 1\n"
|
||||
" beq r0, r0, L30\n"
|
||||
" sll r0, r0, 0\n"
|
||||
"\n"
|
||||
|
||||
"L29:\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" daddiu a1, a1, -48\n"
|
||||
" dsll a2, v0, 1\n"
|
||||
" daddu v0, a1, a2\n"
|
||||
" daddiu a0, a0, 1\n"
|
||||
|
||||
"L30:\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" sltiu a1, a1, 48\n"
|
||||
" daddiu a2, s7, 8\n"
|
||||
" movn a2, s7, a1\n"
|
||||
" beql s7, a2, L31\n"
|
||||
|
||||
" or a1, a2, r0\n"
|
||||
|
||||
" addiu a1, r0, 49\n"
|
||||
" lbu a2, 0(a0)\n"
|
||||
" sltu a2, a1, a2\n"
|
||||
" daddiu a1, s7, 8\n"
|
||||
" movn a1, s7, a2\n"
|
||||
|
||||
"L31:\n"
|
||||
" bne s7, a1, L29\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" or a1, s7, r0\n"
|
||||
|
||||
"L32:\n"
|
||||
" beq r0, r0, L38\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L33:\n"
|
||||
" addiu a1, r0, 45\n"
|
||||
" lbu a2, 1(a0)\n"
|
||||
" bne a2, a1, L34\n"
|
||||
" or a1, s7, r0\n"
|
||||
|
||||
" daddiu v1, s7, #t\n"
|
||||
" daddiu a0, a0, 1\n"
|
||||
" or a1, a0, r0\n"
|
||||
|
||||
"L34:\n"
|
||||
" beq r0, r0, L36\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L35:\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" daddiu a1, a1, -48\n"
|
||||
" addiu a2, r0, 10\n"
|
||||
" mult3 a2, a2, v0\n"
|
||||
" daddu v0, a1, a2\n"
|
||||
" daddiu a0, a0, 1\n"
|
||||
|
||||
"L36:\n"
|
||||
" lbu a1, 0(a0)\n"
|
||||
" sltiu a1, a1, 48\n"
|
||||
" daddiu a2, s7, 8\n"
|
||||
" movn a2, s7, a1\n"
|
||||
" beql s7, a2, L37\n"
|
||||
|
||||
" or a1, a2, r0\n"
|
||||
|
||||
" addiu a1, r0, 57\n"
|
||||
" lbu a2, 0(a0)\n"
|
||||
" sltu a2, a1, a2\n"
|
||||
" daddiu a1, s7, 8\n"
|
||||
" movn a1, s7, a2\n"
|
||||
|
||||
"L37:\n"
|
||||
" bne s7, a1, L35\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" or a0, s7, r0\n"
|
||||
|
||||
"L38:\n"
|
||||
" beq s7, v1, L39\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" dsubu v0, r0, v0\n"
|
||||
" beq r0, r0, L39\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L39:\n"
|
||||
" jr ra\n"
|
||||
" daddu sp, sp, r0";
|
||||
std::string type = "(function string int)";
|
||||
std::string expected =
|
||||
"(defun test-function ((arg0 string))\n"
|
||||
" (local-vars\n"
|
||||
" (v0-0 int)\n"
|
||||
" (v1-0 symbol)\n"
|
||||
" (a0-1 (pointer uint8))\n"
|
||||
" (a0-2 (pointer uint8))\n"
|
||||
" (a0-3 (pointer uint8))\n"
|
||||
" (a0-4 (pointer uint8))\n"
|
||||
" (a0-5 symbol)\n"
|
||||
" (a1-8 (pointer uint8))\n"
|
||||
" (a1-14 uint)\n"
|
||||
" (a1-16 symbol)\n"
|
||||
" (a1-20 uint)\n"
|
||||
" (a1-23 uint)\n"
|
||||
" (a1-33 symbol)\n"
|
||||
" (a1-44 symbol)\n"
|
||||
" (a1-47 (pointer uint8))\n"
|
||||
" )\n"
|
||||
" (set! a0-1 (-> arg0 data))\n"
|
||||
" (set! v0-0 0)\n"
|
||||
" (set! v1-0 (quote #f))\n"
|
||||
" (cond\n"
|
||||
" ((= (-> a0-1 0) 35)\n"
|
||||
" (set! a0-2 (&-> a0-1 1))\n"
|
||||
" (cond\n"
|
||||
" ((or (zero? (+ (-> a0-2 0) -120)) (zero? (+ (-> a0-2 0) -88)))\n"
|
||||
" (set! a0-3 (&-> a0-2 1))\n"
|
||||
" (when\n"
|
||||
" (= (-> a0-3 1) 45)\n"
|
||||
" (set! v1-0 (quote #t))\n"
|
||||
" (set! a0-3 (&-> a0-3 1))\n"
|
||||
" (set! a1-8 a0-3)\n"
|
||||
" )\n"
|
||||
" (while\n"
|
||||
" (or\n"
|
||||
" (and\n"
|
||||
" (>= (-> a0-3 0) (the-as uint 48))\n"
|
||||
" (>= (the-as uint 57) (-> a0-3 0))\n"
|
||||
" )\n"
|
||||
" (and\n"
|
||||
" (>= (-> a0-3 0) (the-as uint 65))\n"
|
||||
" (>= (the-as uint 70) (-> a0-3 0))\n"
|
||||
" )\n"
|
||||
" (and\n"
|
||||
" (>= (-> a0-3 0) (the-as uint 97))\n"
|
||||
" (>= (the-as uint 102) (-> a0-3 0))\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" (cond\n"
|
||||
" ((and\n"
|
||||
" (>= (-> a0-3 0) (the-as uint 65))\n"
|
||||
" (>= (the-as uint 70) (-> a0-3 0))\n"
|
||||
" )\n"
|
||||
" (set! v0-0 (+ (+ (-> a0-3 0) -55) (the-as uint (shl v0-0 4))))\n"
|
||||
" (set! a1-14 v0-0)\n"
|
||||
" )\n"
|
||||
" (else\n"
|
||||
" (set!\n"
|
||||
" a1-16\n"
|
||||
" (and\n"
|
||||
" (>= (-> a0-3 0) (the-as uint 97))\n"
|
||||
" (>= (the-as uint 102) (-> a0-3 0))\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" (cond\n"
|
||||
" (a1-16\n"
|
||||
" (set! v0-0 (+ (+ (-> a0-3 0) -87) (the-as uint (shl v0-0 4))))\n"
|
||||
" (set! a1-20 v0-0)\n"
|
||||
" )\n"
|
||||
" (else\n"
|
||||
" (set! v0-0 (+ (+ (-> a0-3 0) -48) (the-as uint (shl v0-0 4))))\n"
|
||||
" (set! a1-23 v0-0)\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" (set! a0-3 (&-> a0-3 1))\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" ((or (zero? (+ (-> a0-2 0) -98)) (zero? (+ (-> a0-2 0) -66)))\n"
|
||||
" (set! a0-4 (&-> a0-2 1))\n"
|
||||
" (while\n"
|
||||
" (and (>= (-> a0-4 0) (the-as uint 48)) (>= (the-as uint 49) (-> a0-4 0)))\n"
|
||||
" (set! v0-0 (+ (+ (-> a0-4 0) -48) (the-as uint (shl v0-0 1))))\n"
|
||||
" (set! a0-4 (&-> a0-4 1))\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" (else\n"
|
||||
" (when\n"
|
||||
" (= (-> a0-1 1) 45)\n"
|
||||
" (set! v1-0 (quote #t))\n"
|
||||
" (set! a0-1 (&-> a0-1 1))\n"
|
||||
" (set! a1-47 a0-1)\n"
|
||||
" )\n"
|
||||
" (while\n"
|
||||
" (and (>= (-> a0-1 0) (the-as uint 48)) (>= (the-as uint 57) (-> a0-1 0)))\n"
|
||||
" (set! v0-0 (+ (+ (-> a0-1 0) -48) (the-as uint (* 10 v0-0))))\n"
|
||||
" (set! a0-1 (&-> a0-1 1))\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" (cond (v1-0 (- v0-0)) (else (empty) v0-0))\n"
|
||||
" )";
|
||||
test_final_function(func, type, expected);
|
||||
}
|
||||
|
||||
@@ -96,4 +96,96 @@
|
||||
1 0 0 0 0 0
|
||||
)
|
||||
0
|
||||
)
|
||||
|
||||
|
||||
(defstate die-state
|
||||
:enter (lambda () (format #t "enter die~%"))
|
||||
:exit (lambda () (format #t "exit die~%"))
|
||||
:code (lambda ()
|
||||
(format #t "time to die!~%")
|
||||
(process-deactivate)
|
||||
(format #t "don't see me~%")
|
||||
)
|
||||
)
|
||||
|
||||
(defun xmm-check-code (ax ay az aw)
|
||||
"This function relies on saved xmm register being backed up on a context switch"
|
||||
;; (declare (print-asm))
|
||||
;; compiler will put these in xmm8 and xmm9 to keep them from being clobbered
|
||||
(let ((x 12.34)
|
||||
(y 45.63))
|
||||
(dotimes (i 3)
|
||||
(format #t "run xmm-check ~f ~f ~D ~D ~D ~D~%" x y ax ay az aw)
|
||||
;; should preserve xmm8 and xmm9
|
||||
(suspend)
|
||||
)
|
||||
;; get the wreck process and make it go to die state.
|
||||
(go-process (process-by-name 'wreck-proc *active-pool*) die-state)
|
||||
(go die-state)
|
||||
(format #t "unreachable~%")
|
||||
)
|
||||
)
|
||||
|
||||
(defun xmm-wreck-code (ax ay az aw)
|
||||
"This function intentionally overwrites xmm8 and xmm9 and suspends"
|
||||
(while #t
|
||||
(rlet ((x :class fpr :type float :reg xmm8)
|
||||
(y :class fpr :type float :reg xmm9))
|
||||
(set! x 99.0)
|
||||
(set! y 101.0)
|
||||
(format #t "wreck: ~D ~D ~D ~D~%" ax ay az aw)
|
||||
(suspend)
|
||||
(set! x (+ x 1.0))
|
||||
(set! y (+ y 1.0))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; a state.
|
||||
(defstate xmm-check-state
|
||||
:enter (lambda (x y z w) (format #t "enter check: ~D ~D ~D ~D~%" x y z w))
|
||||
:exit (lambda () (format #t "exit check~%"))
|
||||
:code xmm-check-code
|
||||
)
|
||||
|
||||
(defstate xmm-wreck-state
|
||||
:enter (lambda (x y z w) (format #t "enter wreck: ~D ~D ~D ~D~%" x y z w))
|
||||
:exit (lambda () (format #t "exit wreck~%"))
|
||||
:code xmm-wreck-code
|
||||
)
|
||||
|
||||
(defun state-test ()
|
||||
(let ((proc (get-process *nk-dead-pool* process 1024)))
|
||||
(activate proc *active-pool* 'check-proc *kernel-dram-stack*)
|
||||
(run-now-in-process proc (lambda (x y z w) (go xmm-check-state x y z w))
|
||||
9 8 7 6)
|
||||
)
|
||||
|
||||
(let ((proc (get-process *nk-dead-pool* process 1024)))
|
||||
(activate proc *active-pool* 'wreck-proc *kernel-dram-stack*)
|
||||
(run-next-time-in-process proc (lambda (x y z w) (go xmm-wreck-state x y z w))
|
||||
3 4 5 6)
|
||||
)
|
||||
0
|
||||
)
|
||||
|
||||
(defun throw-backup-test ()
|
||||
(rlet ((x :reg xmm10 :class fpr :type float))
|
||||
(set! x 10.10)
|
||||
(let ((proc (get-process *nk-dead-pool* process 1024)))
|
||||
(activate proc *active-pool* 'asdf *kernel-dram-stack*)
|
||||
(format #t "value now is ~f~%" x)
|
||||
(run-now-in-process proc (lambda ()
|
||||
(rlet ((x2 :reg xmm10 :class fpr :type float))
|
||||
(set! x2 -1.0)
|
||||
)
|
||||
;; this will throw back.
|
||||
(process-deactivate)
|
||||
)
|
||||
)
|
||||
(format #t "now its ~f~%" x)
|
||||
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -108,4 +108,27 @@ TEST_F(KernelTest, RunFunctionInProcess) {
|
||||
"Stack Alignemnt 0/16\n"
|
||||
"run-function-in-process result: #f\n";
|
||||
EXPECT_EQ(expected, result);
|
||||
}
|
||||
|
||||
TEST_F(KernelTest, StateAndXmm) {
|
||||
runner.c->run_test_from_string("(ml \"test/goalc/source_templates/kernel/kernel-test.gc\")");
|
||||
std::string result = send_code_and_get_multiple_responses("(state-test)", 5, &runner);
|
||||
|
||||
std::string expected =
|
||||
"0\nenter wreck: 3 4 5 6\nwreck: 3 4 5 6\nenter check: 9 8 7 6\nrun xmm-check 12.3400 "
|
||||
"45.6300 9 8 7 6\nwreck: 3 4 5 6\nrun xmm-check 12.3400 45.6300 9 8 7 6\nwreck: 3 4 5 6\nrun "
|
||||
"xmm-check 12.3400 45.6300 9 8 7 6\nwreck: 3 4 5 6\nexit check\nenter die\ntime to "
|
||||
"die!\nexit die\nexit wreck\nenter die\ntime to die!\nexit die\n";
|
||||
EXPECT_EQ(expected, result);
|
||||
}
|
||||
|
||||
TEST_F(KernelTest, ThrowXmm) {
|
||||
runner.c->run_test_from_string("(ml \"test/goalc/source_templates/kernel/kernel-test.gc\")");
|
||||
std::string result = send_code_and_get_multiple_responses("(throw-backup-test)", 1, &runner);
|
||||
|
||||
std::string expected =
|
||||
"value now is 10.1000\n"
|
||||
"now its 10.1000\n"
|
||||
"0\n";
|
||||
EXPECT_EQ(expected, result);
|
||||
}
|
||||
Reference in New Issue
Block a user