about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-01-28 23:44:04 -0800
committerKartik Agaram <vc@akkartik.com>2020-01-28 23:47:19 -0800
commit261a1b7480f312c5fd73445e5ccf331ff4ca3f86 (patch)
tree01bb16e1fac8ff339dc60b6f3a927bfd75f1a078
parentf4408d76c5bb12fa7f8ef77bb39b36b7a3a1263e (diff)
downloadmu-261a1b7480f312c5fd73445e5ccf331ff4ca3f86.tar.gz
5945 - branches
-rwxr-xr-xapps/mubin91608 -> 95349 bytes
-rw-r--r--apps/mu.subx285
2 files changed, 285 insertions, 0 deletions
diff --git a/apps/mu b/apps/mu
index 7c9a9f55..db003516 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx
index 0022405c..5b883b99 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -1224,6 +1224,81 @@ test-convert-function-with-local-var-in-named-block:
     5d/pop-to-ebp
     c3/return
 
+test-convert-function-with-branches-in-block:
+    # empty function decl => function prologue and epilogue
+    #   fn foo x: int {
+    #     {
+    #       break-if->=
+    #       loop-if-addr<
+    #       increment x
+    #       loop
+    #     }
+    #   }
+    # =>
+    #   foo:
+    #     # . prologue
+    #     55/push-ebp
+    #     89/<- %ebp 4/r32/esp
+    #     {
+    #       {
+    #         0f 8d/jump-if->= break/disp32
+    #         0f 82/jump-if-addr< loop/disp32
+    #         ff 0/subop/increment *(ebp+8)
+    #         e9/jump loop/disp32
+    #       }
+    #     }
+    #     # . epilogue
+    #     89/<- %esp 5/r32/ebp
+    #     5d/pop-to-ebp
+    #     c3/return
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # setup
+    (clear-stream _test-input-stream)
+    (clear-stream $_test-input-buffered-file->buffer)
+    (clear-stream _test-output-stream)
+    (clear-stream $_test-output-buffered-file->buffer)
+    #
+    (write _test-input-stream "fn foo x: int {\n")
+    (write _test-input-stream "  {\n")
+    (write _test-input-stream "    break-if->=\n")
+    (write _test-input-stream "    loop-if-addr<\n")
+    (write _test-input-stream "    increment x\n")
+    (write _test-input-stream "    loop\n")
+    (write _test-input-stream "  }\n")
+    (write _test-input-stream "}\n")
+    # convert
+    (convert-mu _test-input-buffered-file _test-output-buffered-file)
+    (flush _test-output-buffered-file)
+#?     # dump _test-output-stream {{{
+#?     (write 2 "^")
+#?     (write-stream 2 _test-output-stream)
+#?     (write 2 "$\n")
+#?     (rewind-stream _test-output-stream)
+#?     # }}}
+    # check output
+    (check-next-stream-line-equal _test-output-stream "foo:"                  "F - test-convert-function-with-branches-in-block/0")
+    (check-next-stream-line-equal _test-output-stream "# . prologue"          "F - test-convert-function-with-branches-in-block/1")
+    (check-next-stream-line-equal _test-output-stream "55/push-ebp"           "F - test-convert-function-with-branches-in-block/2")
+    (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-branches-in-block/3")
+    (check-next-stream-line-equal _test-output-stream "{"                     "F - test-convert-function-with-branches-in-block/4")
+    (check-next-stream-line-equal _test-output-stream "{"                     "F - test-convert-function-with-branches-in-block/5")
+    (check-next-stream-line-equal _test-output-stream "0f 8d/jump-if->= break/disp32"  "F - test-convert-function-with-branches-in-block/6")
+    (check-next-stream-line-equal _test-output-stream "0f 82/jump-if-addr< loop/disp32"  "F - test-convert-function-with-branches-in-block/7")
+    (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0x00000008)"  "F - test-convert-function-with-branches-in-block/8")
+    (check-next-stream-line-equal _test-output-stream "e9/jump loop/disp32"   "F - test-convert-function-with-branches-in-block/9")
+    (check-next-stream-line-equal _test-output-stream "}"                     "F - test-convert-function-with-branches-in-block/10")
+    (check-next-stream-line-equal _test-output-stream "}"                     "F - test-convert-function-with-branches-in-block/12")
+    (check-next-stream-line-equal _test-output-stream "# . epilogue"          "F - test-convert-function-with-branches-in-block/13")
+    (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-branches-in-block/14")
+    (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp"         "F - test-convert-function-with-branches-in-block/15")
+    (check-next-stream-line-equal _test-output-stream "c3/return"             "F - test-convert-function-with-branches-in-block/16")
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
 #######################################################
 # Parsing
 #######################################################
@@ -4974,6 +5049,216 @@ _Primitive-copy-lit-to-mem:
     0/imm32/no-r32
     2/imm32/imm32-is-first-inout
     1/imm32/output-is-write-only
+    _Primitive-break-if-addr</imm32/next
+_Primitive-break-if-addr<:
+    "break-if-addr<"/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 82/jump-if-addr< break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-break-if-addr>=/imm32/next
+_Primitive-break-if-addr>=:
+    "break-if-addr>="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 83/jump-if-addr>= break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-break-if-=/imm32/next
+_Primitive-break-if-=:
+    "break-if-="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 84/jump-if-= break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-break-if-!=/imm32/next
+_Primitive-break-if-!=:
+    "break-if-!="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 85/jump-if-!= break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-break-if-addr<=/imm32/next
+_Primitive-break-if-addr<=:
+    "break-if-addr<="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 86/jump-if-addr<= break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-break-if-addr>/imm32/next
+_Primitive-break-if-addr>:
+    "break-if-addr>"/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 87/jump-if-addr> break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-break-if-</imm32/next
+_Primitive-break-if-<:
+    "break-if-<"/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 8c/jump-if-< break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-break-if->=/imm32/next
+_Primitive-break-if->=:
+    "break-if->="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 8d/jump-if->= break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-break-if-<=/imm32/next
+_Primitive-break-if-<=:
+    "break-if-<="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 8e/jump-if-<= break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-break-if->/imm32/next
+_Primitive-break-if->:
+    "break-if->"/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 8f/jump-if-> break/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if-addr</imm32/next
+_Primitive-loop-if-addr<:
+    "loop-if-addr<"/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 82/jump-if-addr< loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if-addr>=/imm32/next
+_Primitive-loop-if-addr>=:
+    "loop-if-addr>="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 83/jump-if-addr>= loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if-=/imm32/next
+_Primitive-loop-if-=:
+    "loop-if-="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 84/jump-if-= loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if-!=/imm32/next
+_Primitive-loop-if-!=:
+    "loop-if-!="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 85/jump-if-!= loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if-addr<=/imm32/next
+_Primitive-loop-if-addr<=:
+    "loop-if-addr<="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 86/jump-if-addr<= loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if-addr>/imm32/next
+_Primitive-loop-if-addr>:
+    "loop-if-addr>"/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 87/jump-if-addr> loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if-</imm32/next
+_Primitive-loop-if-<:
+    "loop-if-<"/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 8c/jump-if-< loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if->=/imm32/next
+_Primitive-loop-if->=:
+    "loop-if->="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 8d/jump-if->= loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if-<=/imm32/next
+_Primitive-loop-if-<=:
+    "loop-if-<="/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 8e/jump-if-<= loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop-if->/imm32/next
+_Primitive-loop-if->:
+    "loop-if->"/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "0f 8f/jump-if-> loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
+    _Primitive-loop/imm32/next  # we probably don't need an unconditional break
+_Primitive-loop:
+    "loop"/imm32/name
+    0/imm32/inouts
+    0/imm32/outputs
+    "e9/jump loop/disp32"/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-output
     0/imm32/next
 
 Single-int-var-on-stack: