about summary refs log tree commit diff stats
path: root/apps/mu.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-06-14 00:24:47 -0700
committerKartik Agaram <vc@akkartik.com>2020-06-14 00:28:23 -0700
commitad61776f498e8117756e4794eac840fab60cfac6 (patch)
tree73510284e749eab8c207aecef90084d0a5c57101 /apps/mu.subx
parentead3d08e774529f3026f8cd6f93b8a0d7c87ed08 (diff)
downloadmu-ad61776f498e8117756e4794eac840fab60cfac6.tar.gz
6520 - new app: parse-int
Several bugs fixed in the process, and expectation of further bugs is growing.
I'd somehow started assuming I don't need to have separate cases for rm32
as a register vs mem. That's not right. We might need more reg-reg Primitives.
Diffstat (limited to 'apps/mu.subx')
-rw-r--r--apps/mu.subx187
1 files changed, 179 insertions, 8 deletions
diff --git a/apps/mu.subx b/apps/mu.subx
index 5b6d712f..3658f332 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -6138,6 +6138,7 @@ parse-mu-var-def:  # line: (addr stream byte), vars: (addr stack live-var), out:
     {
       0f 84/jump-if-= break/disp32
       # TODO: disallow vars of type 'byte' in registers 'esi' or 'edi'
+      # TODO: vars of type 'byte' should only be initialized by clearing to 0
       # ensure that the next word is '<-'
       (next-mu-token *(ebp+8) %ecx)
       (slice-equal? %ecx "<-")  # => eax
@@ -7968,17 +7969,24 @@ compute-size-of-type-id:  # t: type-id -> result/eax: int
     89/<- %ecx 4/r32/esp
     # eax = t
     8b/-> *(ebp+8) 0/r32/eax
-    # if v is a literal, return 0
+    # if t is a literal, return 0
     3d/compare-eax-and 0/imm32/literal
-    74/jump-if-= $compute-size-of-type-id:end/disp8  # eax changes type from type-id to int
-    # if v is a byte, return 1
+    0f 84/jump-if-= $compute-size-of-type-id:end/disp32  # eax changes type from type-id to int
+    # if t is a byte, return 1
+    3d/compare-eax-and 8/imm32/byte
     {
-      3d/compare-eax-and 8/imm32/byte
       75/jump-if-!= break/disp8
       b8/copy-to-eax 1/imm32
       eb/jump $compute-size-of-type-id:end/disp8
     }
-    # if v has a user-defined type, compute its size
+    # if t is a handle, return 8
+    3d/compare-eax-and 4/imm32/handle
+    {
+      75/jump-if-!= break/disp8
+      b8/copy-to-eax 8/imm32
+      eb/jump $compute-size-of-type-id:end/disp8  # eax changes type from type-id to int
+    }
+    # if t is a user-defined type, compute its size
     # TODO: support non-atom type
     (find-typeinfo %eax %ecx)
     {
@@ -8490,7 +8498,14 @@ size-of-type-id:  # t: type-id -> result/eax: int
     8b/-> *(ebp+8) 0/r32/eax
     # if t is a literal, return 0
     3d/compare-eax-and 0/imm32
-    74/jump-if-= $size-of-type-id:end/disp8  # eax changes type from type-id to int
+    0f 84/jump-if-= $size-of-type-id:end/disp32  # eax changes type from type-id to int
+    # if v is a byte, return 1
+    3d/compare-eax-and 8/imm32/byte
+    {
+      75/jump-if-!= break/disp8
+      b8/copy-to-eax 1/imm32
+      eb/jump $size-of-type-id:end/disp8
+    }
     # if t is a handle, return 8
     3d/compare-eax-and 4/imm32/handle
     {
@@ -9857,6 +9872,7 @@ translate-mu-length-stmt:  # out: (addr buffered-file), stmt: (addr stmt), err:
     {
       81 7/subop/compare %ecx 1/imm32
       75/jump-if-!= break/disp8
+$translate-mu-length-stmt:size-1:
       (emit-save-size-to *(ebp+8) %ebx %edx)
       e9/jump $translate-mu-length-stmt:end/disp32
     }
@@ -9867,6 +9883,7 @@ translate-mu-length-stmt:  # out: (addr buffered-file), stmt: (addr stmt), err:
       74/jump-if-= break/disp8
       81 7/subop/compare %ecx 0xff/imm32
       7f/jump-if-> break/disp8
+$translate-mu-length-stmt:size-power-of-2:
       (emit-save-size-to *(ebp+8) %ebx %edx)
       (emit-divide-by-shift-right *(ebp+8) %edx %ecx)
       e9/jump $translate-mu-length-stmt:end/disp32
@@ -9874,6 +9891,7 @@ translate-mu-length-stmt:  # out: (addr buffered-file), stmt: (addr stmt), err:
     # otherwise, the complex case
     # . emit register spills
     {
+$translate-mu-length-stmt:complex:
       (string-equal? %edx "eax")  # => eax
       3d/compare-eax-and 0/imm32/false
       75/break-if-!= break/disp8
@@ -11733,8 +11751,26 @@ _Primitive-address:  # (payload primitive)
     0/imm32/no-disp32
     1/imm32/output-is-write-only
     0x11/imm32/alloc-id:fake
-    _Primitive-compare-mem-with-reg/imm32/next
+    _Primitive-compare-reg-with-reg/imm32/next
 # - compare
+_Primitive-compare-reg-with-reg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32
+    0x11/imm32/alloc-id:fake
+    _string-compare/imm32/name
+    0x11/imm32/alloc-id:fake
+    Two-int-args-in-regs/imm32/inouts
+    0/imm32/no-outputs
+    0/imm32/no-outputs
+    0x11/imm32/alloc-id:fake
+    _string_39_compare->/imm32/subx-name
+    1/imm32/rm32-is-first-inout
+    2/imm32/r32-is-second-inout
+    0/imm32/no-imm32
+    0/imm32/no-disp32
+    0/imm32/output-is-write-only
+    0x11/imm32/alloc-id:fake
+    _Primitive-compare-mem-with-reg/imm32/next
 _Primitive-compare-mem-with-reg:  # (payload primitive)
     0x11/imm32/alloc-id:fake:payload
     # compare var1 var2/reg => 39/compare var1/rm32 var2/r32
@@ -11824,8 +11860,26 @@ _Primitive-compare-mem-with-literal:  # (payload primitive)
     0/imm32/no-disp32
     0/imm32/output-is-write-only
     0x11/imm32/alloc-id:fake
-    _Primitive-multiply-reg-by-mem/imm32/next
+    _Primitive-multiply-reg-by-reg/imm32/next
 # - multiply
+_Primitive-multiply-reg-by-reg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32
+    0x11/imm32/alloc-id:fake
+    _string-multiply/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-int-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-int-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_0f_af_multiply/imm32/subx-name
+    1/imm32/rm32-is-first-inout
+    3/imm32/r32-is-first-output
+    0/imm32/no-imm32
+    0/imm32/no-disp32
+    0/imm32/output-is-write-only
+    0x11/imm32/alloc-id:fake
+    _Primitive-multiply-reg-by-mem/imm32/next
 _Primitive-multiply-reg-by-mem:  # (payload primitive)
     0x11/imm32/alloc-id:fake:payload
     # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32
@@ -13269,6 +13323,13 @@ Two-args-int-stack-int-reg:  # (payload list var)
     0x11/imm32/alloc-id:fake
     Single-int-var-in-some-register/imm32/next
 
+Two-int-args-in-regs:  # (payload list var)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    Int-var-in-some-register/imm32
+    0x11/imm32/alloc-id:fake
+    Single-int-var-in-some-register/imm32/next
+
 # Not really legal, but closest we can currently represent a dereference of an (addr byte)
 Two-args-byte-stack-byte-reg:  # (payload list var)
     0x11/imm32/alloc-id:fake:payload
@@ -15671,6 +15732,116 @@ $test-add-literal-to-mem:initialize-stmt-operation:
     5d/pop-to-ebp
     c3/return
 
+test-compare-reg-with-reg:
+    #   compare var1/ecx, var2/eax
+    # =>
+    #   39/compare %ecx 0/r32/eax
+    #
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # setup
+    (clear-stream _test-output-stream)
+    (clear-stream $_test-output-buffered-file->buffer)
+$test-compare-reg-with-reg:initialize-type:
+    # var type/ecx: (payload tree type-id) = int
+    68/push 0/imm32/right:null
+    68/push 0/imm32/right:null
+    68/push 0/imm32/left:unused
+    68/push 1/imm32/value:int
+    68/push 1/imm32/is-atom?:true
+    68/push 0x11/imm32/alloc-id:fake:payload
+    89/<- %ecx 4/r32/esp
+$test-compare-reg-with-reg:initialize-var1:
+    # var var1/ecx: (payload var)
+    68/push 0/imm32/register
+    68/push 0/imm32/register
+    68/push 0/imm32/no-stack-offset
+    68/push 1/imm32/block-depth
+    51/push-ecx
+    68/push 0x11/imm32/alloc-id:fake
+    68/push 0/imm32/name
+    68/push 0/imm32/name
+    68/push 0x11/imm32/alloc-id:fake:payload
+    89/<- %ecx 4/r32/esp
+$test-compare-reg-with-reg:initialize-var1-name:
+    # var1->name = "var1"
+    8d/copy-address *(ecx+4) 0/r32/eax  # Var-name + 4
+    (copy-array Heap "var1" %eax)
+$test-compare-reg-with-reg:initialize-var1-register:
+    # var1->register = "ecx"
+    8d/copy-address *(ecx+0x1c) 0/r32/eax  # Var-register + 4
+    (copy-array Heap "ecx" %eax)
+$test-compare-reg-with-reg:initialize-var2:
+    # var var2/edx: (payload var)
+    68/push 0/imm32/register
+    68/push 0/imm32/register
+    68/push 0/imm32/no-stack-offset
+    68/push 1/imm32/block-depth
+    ff 6/subop/push *(ecx+0x10)
+    68/push 0x11/imm32/alloc-id:fake
+    68/push 0/imm32/name
+    68/push 0/imm32/name
+    68/push 0x11/imm32/alloc-id:fake:payload
+    89/<- %edx 4/r32/esp
+$test-compare-reg-with-reg:initialize-var2-name:
+    # var2->name = "var2"
+    8d/copy-address *(edx+4) 0/r32/eax  # Var-name + 4
+    (copy-array Heap "var2" %eax)
+$test-compare-reg-with-reg:initialize-var2-register:
+    # var2->register = "eax"
+    8d/copy-address *(edx+0x1c) 0/r32/eax  # Var-register + 4
+    (copy-array Heap "eax" %eax)
+$test-compare-reg-with-reg:initialize-inouts:
+    # var inouts/esi: (payload stmt-var) = [var2]
+    68/push 0/imm32/is-deref:false
+    68/push 0/imm32/next
+    68/push 0/imm32/next
+    52/push-edx/var2
+    68/push 0x11/imm32/alloc-id:fake
+    68/push 0x11/imm32/alloc-id:fake:payload
+    89/<- %esi 4/r32/esp
+    # inouts = [var1, var2]
+    68/push 0/imm32/is-deref:false
+    56/push-esi/next
+    68/push 0x11/imm32/alloc-id:fake
+    51/push-ecx/var1
+    68/push 0x11/imm32/alloc-id:fake
+    68/push 0x11/imm32/alloc-id:fake:payload
+    89/<- %esi 4/r32/esp
+$test-compare-reg-with-reg:initialize-stmt:
+    # var stmt/esi: (addr statement)
+    68/push 0/imm32/next
+    68/push 0/imm32/next
+    68/push 0/imm32/outputs
+    68/push 0/imm32/outputs
+    56/push-esi/inouts
+    68/push 0x11/imm32/alloc-id:fake
+    68/push 0/imm32/operation
+    68/push 0/imm32/operation
+    68/push 1/imm32/tag:stmt1
+    89/<- %esi 4/r32/esp
+$test-compare-reg-with-reg:initialize-stmt-operation:
+    # stmt->operation = "compare"
+    8d/copy-address *(esi+4) 0/r32/eax  # Stmt1-operation
+    (copy-array Heap "compare" %eax)
+    # convert
+    c7 0/subop/copy *Curr-block-depth 0/imm32
+    (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0)
+    (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 "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg")
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
 test-compare-mem-with-reg:
     #   compare var1, var2/eax
     # =>