about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-10-04 00:54:57 -0700
committerKartik Agaram <vc@akkartik.com>2020-10-04 00:54:57 -0700
commit93c6352dda47f54c602a343b665bf7860678561b (patch)
treefbabe18c92ddce00872ceafd81d5fc65f0f44edc
parent1bf5d5f44eed31d08565a8798ac4b81ffda17af8 (diff)
downloadmu-93c6352dda47f54c602a343b665bf7860678561b.tar.gz
6943
Move some implementation around for floating-point.

I originally thought I wouldn't bother supporting sigils like %xmm0. But
it turns out I need them to pass floats into SubX function calls. And it
turns out the sigils work fine for free.
-rwxr-xr-xapps/callsbin53168 -> 53372 bytes
-rw-r--r--apps/calls.subx59
-rwxr-xr-xapps/mubin422179 -> 421479 bytes
-rw-r--r--apps/mu.subx109
4 files changed, 71 insertions, 97 deletions
diff --git a/apps/calls b/apps/calls
index 781eb04d..09382fec 100755
--- a/apps/calls
+++ b/apps/calls
Binary files differdiff --git a/apps/calls.subx b/apps/calls.subx
index 4b91b628..9f8b2658 100644
--- a/apps/calls.subx
+++ b/apps/calls.subx
@@ -348,7 +348,12 @@ emit-call:  # out: (addr buffered-file), words: (addr stream slice)
     #   # emit pushes
     #   while true
     #     if (curr <= min) break
-    #     if *curr->start in '%' '*'
+    #     if slice-starts-with?(curr, "%x")    # floating-point register
+    #       write-buffered(out, "81 5/subop/subtract %esp 4/imm32\n")
+    #       write-buffered(out, "f3 0f 11/<- *esp ")
+    #       write-byte-buffered(out, *(curr->start+4))
+    #       write-buffered(out, "/x32\n")
+    #     else if *curr->start in '%' '*'
     #       write-buffered(out, "ff 6/subop/push ")
     #       write-slice-buffered(out, curr)
     #       write-buffered(out, "\n")
@@ -390,6 +395,57 @@ $emit-call:push-loop:
     # if (curr <= min) break
     39/compare %ecx 2/r32/edx
     0f 8e/jump-if-<= $emit-call:call-instruction/disp32
+    # if !slice-starts-with?(curr, "%x") goto next check
+    # . eax = slice-starts-with?(curr, "%x")
+    # . . push args
+    68/push "%x"/imm32
+    51/push-ecx
+    # . . call
+    e8/call slice-starts-with?/disp32
+    # . . discard args
+    81 0/subop/add %esp 8/imm32
+    # . if (eax != 0) goto next check
+    3d/compare-eax-and 0/imm32/false
+    74/jump-if-= $emit-call:push-int/disp8
+    # emit floating-point push
+    # . write-buffered(out, "81 5/subop/subtract %esp 4/imm32\n")
+    # . . push args
+    68/push "81 5/subop/subtract %esp 4/imm32\n"/imm32
+    ff 6/subop/push *(ebp+8)
+    # . . call
+    e8/call write-buffered/disp32
+    # . . discard args
+    81 0/subop/add %esp 8/imm32
+    # . write-buffered(out, "f3 0f 11/<- *esp ")
+    # . . push args
+    68/push "f3 0f 11/<- *esp "/imm32
+    ff 6/subop/push *(ebp+8)
+    # . . call
+    e8/call write-buffered/disp32
+    # . . discard args
+    81 0/subop/add %esp 8/imm32
+    # . write-byte-buffered(out, *(curr->start+4))
+    # . . eax = *(curr->start+4)
+    8b/-> *ecx 0/r32/eax
+    8a/copy-byte *(eax+4) 0/r32/eax
+    81 4/subop/and %eax 0xff/imm32
+    # . . push args
+    50/push-eax
+    ff 6/subop/push *(ebp+8)
+    # . . call
+    e8/call write-byte-buffered/disp32
+    # . . discard args
+    81 0/subop/add %esp 8/imm32
+    # . write-buffered(out, "/x32\n")
+    68/push "/x32\n"/imm32
+    ff 6/subop/push *(ebp+8)
+    # . . call
+    e8/call write-buffered/disp32
+    # . . discard args
+    81 0/subop/add %esp 8/imm32
+    # . continue
+    e9/jump $emit-call:next-push/disp32
+$emit-call:push-int:
     # if (*curr->start in '%' '*') goto push-rm32
     # . var start/eax: (addr byte) = curr->start
     8b/-> *ecx 0/r32/eax
@@ -404,6 +460,7 @@ $emit-call:push-loop:
     74/jump-if-= $emit-call:push-rm32/disp8
 $emit-call:push-imm32:
     # write-buffered(out, "68/push ")
+    # . . push args
     68/push "68/push "/imm32
     ff 6/subop/push *(ebp+8)
     # . . call
diff --git a/apps/mu b/apps/mu
index bb779b37..6546803e 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx
index 81261870..1322118a 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -4425,7 +4425,7 @@ test-convert-floating-point-convert-2:
     (check-next-stream-line-equal _test-output-stream "    81 5/subop/subtract %esp 4/imm32"  "F - test-convert-floating-point-convert-2/8")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 11/<- *esp 1/x32"  "F - test-convert-floating-point-convert-2/9")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 2a/convert-to-float %eax 0x00000001/x32"  "F - test-convert-floating-point-convert-2/10")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 2d/convert-to-int 3/mod 0x00000001/xm32 0x00000000/r32"  "F - test-convert-floating-point-convert-2/11")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 2d/convert-to-int %xmm1 0x00000000/r32"  "F - test-convert-floating-point-convert-2/11")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 10/-> *esp 1/x32"  "F - test-convert-floating-point-convert-2/12")
     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 4/imm32"  "F - test-convert-length-of-array-on-stack/13")
     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-floating-point-convert-2/14")
@@ -4500,27 +4500,27 @@ test-convert-floating-point-operation:
     (check-next-stream-line-equal _test-output-stream "    81 5/subop/subtract %esp 4/imm32"                                   "F - test-convert-floating-point-operation/10")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 11/<- *esp 5/x32"                                             "F - test-convert-floating-point-operation/11")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 10/copy *(ebp+0xfffffffc) 0x00000005/x32"                     "F - test-convert-floating-point-operation/12")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/copy 3/mod 0x00000001/xm32 0x00000005/x32"                 "F - test-convert-floating-point-operation/13")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/copy %xmm1 0x00000005/x32"                                 "F - test-convert-floating-point-operation/13")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 11/copy *(ebp+0xfffffffc) 0x00000005/x32"                     "F - test-convert-floating-point-operation/14")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 58/add 3/mod 0x00000005/xm32 0x00000001/x32"                  "F - test-convert-floating-point-operation/15")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 58/add %xmm5 0x00000001/x32"                                  "F - test-convert-floating-point-operation/15")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 58/add *(ebp+0xfffffffc) 0x00000001/x32"                      "F - test-convert-floating-point-operation/16")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 5c/subtract 3/mod 0x00000005/xm32 0x00000001/x32"             "F - test-convert-floating-point-operation/17")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5c/subtract %xmm5 0x00000001/x32"                             "F - test-convert-floating-point-operation/17")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 5c/subtract *(ebp+0xfffffffc) 0x00000001/x32"                 "F - test-convert-floating-point-operation/18")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 59/multiply 3/mod 0x00000005/xm32 0x00000001/x32"             "F - test-convert-floating-point-operation/19")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 59/multiply %xmm5 0x00000001/x32"                             "F - test-convert-floating-point-operation/19")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 59/multiply *(ebp+0xfffffffc) 0x00000001/x32"                 "F - test-convert-floating-point-operation/20")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 5e/divide 3/mod 0x00000005/xm32 0x00000001/x32"               "F - test-convert-floating-point-operation/21")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5e/divide %xmm5 0x00000001/x32"                               "F - test-convert-floating-point-operation/21")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 5e/divide *(ebp+0xfffffffc) 0x00000001/x32"                   "F - test-convert-floating-point-operation/22")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 53/reciprocal 3/mod 0x00000005/xm32 0x00000001/x32"           "F - test-convert-floating-point-operation/23")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 53/reciprocal %xmm5 0x00000001/x32"                           "F - test-convert-floating-point-operation/23")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 53/reciprocal *(ebp+0xfffffffc) 0x00000001/x32"               "F - test-convert-floating-point-operation/24")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 51/square-root 3/mod 0x00000005/xm32 0x00000001/x32"          "F - test-convert-floating-point-operation/25")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 51/square-root %xmm5 0x00000001/x32"                          "F - test-convert-floating-point-operation/25")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 51/square-root *(ebp+0xfffffffc) 0x00000001/x32"              "F - test-convert-floating-point-operation/26")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 52/inverse-square-root 3/mod 0x00000005/xm32 0x00000001/x32"  "F - test-convert-floating-point-operation/27")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 52/inverse-square-root %xmm5 0x00000001/x32"                  "F - test-convert-floating-point-operation/27")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 52/inverse-square-root *(ebp+0xfffffffc) 0x00000001/x32"      "F - test-convert-floating-point-operation/28")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 5f/max 3/mod 0x00000005/xm32 0x00000001/x32"                  "F - test-convert-floating-point-operation/29")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5f/max %xmm5 0x00000001/x32"                                  "F - test-convert-floating-point-operation/29")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 5f/max *(ebp+0xfffffffc) 0x00000001/x32"                      "F - test-convert-floating-point-operation/30")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 5d/min 3/mod 0x00000005/xm32 0x00000001/x32"                  "F - test-convert-floating-point-operation/31")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5d/min %xmm5 0x00000001/x32"                                  "F - test-convert-floating-point-operation/31")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 5d/min *(ebp+0xfffffffc) 0x00000001/x32"                      "F - test-convert-floating-point-operation/32")
-    (check-next-stream-line-equal _test-output-stream "    0f 2f/compare 3/mod 0x00000001/xm32 0x00000005/x32"                 "F - test-convert-floating-point-operation/33")
+    (check-next-stream-line-equal _test-output-stream "    0f 2f/compare %xmm1 0x00000005/x32"                                 "F - test-convert-floating-point-operation/33")
     (check-next-stream-line-equal _test-output-stream "    0f 2f/compare *(ebp+0xfffffffc) 0x00000001/x32"                     "F - test-convert-floating-point-operation/34")
     (check-next-stream-line-equal _test-output-stream "    f3 0f 10/-> *esp 5/x32"                                             "F - test-convert-floating-point-operation/35")
     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 4/imm32"                                        "F - test-convert-floating-point-operation/36")
@@ -22697,7 +22697,7 @@ emit-subx-primitive:  # out: (addr buffered-file), stmt: (addr stmt), primitive:
     # emit rm32 if necessary
     (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18))  # Primitive-subx-rm32
     # emit xm32 if necessary
-    (emit-subx-xm32 *(ebp+8) *(ecx+0x34) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18))  # Primitive-subx-xm32
+    (emit-subx-rm32 *(ebp+8) *(ecx+0x34) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18))  # Primitive-subx-xm32
     # emit r32 if necessary
     (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc))  # Primitive-subx-r32
     # emit x32 if necessary
@@ -22823,26 +22823,6 @@ $emit-subx-r32:end:
     5d/pop-to-ebp
     c3/return
 
-emit-subx-xm32:  # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
-    # . prologue
-    55/push-ebp
-    89/<- %ebp 4/r32/esp
-    # . save registers
-    50/push-eax
-    # if (l == 0) return
-    81 7/subop/compare *(ebp+0xc) 0/imm32
-    74/jump-if-= $emit-subx-xm32:end/disp8
-    # var v/eax: (addr stmt-var)
-    (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18))  # => eax
-    (emit-subx-var-as-xm32 *(ebp+8) %eax)
-$emit-subx-xm32:end:
-    # . restore registers
-    58/pop-to-eax
-    # . epilogue
-    89/<- %esp 5/r32/ebp
-    5d/pop-to-ebp
-    c3/return
-
 emit-subx-x32:  # out: (addr buffered-file), l: arg-location, stmt: (addr stmt)
     # . prologue
     55/push-ebp
@@ -23219,69 +23199,6 @@ $emit-subx-var-as-rm32:end:
     5d/pop-to-ebp
     c3/return
 
-# xm32 is like rm32, except that direct mode uses floating-point registers.
-# Indirect mode is the same.
-emit-subx-var-as-xm32:  # out: (addr buffered-file), s: (addr stmt-var)
-    # . prologue
-    55/push-ebp
-    89/<- %ebp 4/r32/esp
-    # . save registers
-    50/push-eax
-    51/push-ecx
-    56/push-esi
-    # ecx = s
-    8b/-> *(ebp+0xc) 1/r32/ecx
-    # var operand/esi: (addr var) = lookup(s->value)
-    (lookup *ecx *(ecx+4))  # Stmt-var-value Stmt-var-value => eax
-    89/<- %esi 0/r32/eax
-    # if (operand->register && s->is-deref?) emit "*__"
-    {
-$emit-subx-var-as-xm32:check-for-register-indirect:
-      81 7/subop/compare *(esi+0x18) 0/imm32  # Var-register
-      74/jump-if-= break/disp8
-      81 7/subop/compare *(ecx+0x10) 0/imm32/false  # Stmt-var-is-deref
-      74/jump-if-= break/disp8
-$emit-subx-var-as-xm32:register-indirect:
-      (write-buffered *(ebp+8) " *")
-      (lookup *(esi+0x18) *(esi+0x1c))  # Var-register Var-register => eax
-      (write-buffered *(ebp+8) %eax)
-      e9/jump $emit-subx-var-as-xm32:end/disp32
-    }
-    # if (operand->register && !s->is-deref?) emit "3/mod __/xm32"
-    {
-$emit-subx-var-as-xm32:check-for-register-direct:
-      81 7/subop/compare *(esi+0x18) 0/imm32  # Var-register
-      0f 84/jump-if-= break/disp32
-      81 7/subop/compare *(ecx+0x10) 0/imm32/false  # Stmt-var-is-deref
-      75/jump-if-!= break/disp8
-$emit-subx-var-as-xm32:register-direct:
-      (write-buffered *(ebp+8) " 3/mod ")
-      (lookup *(esi+0x18) *(esi+0x1c))  # Var-register Var-register => eax
-      (maybe-get Mu-registers %eax 0xc)  # => eax: (addr register-index)
-      (write-int32-hex-buffered *(ebp+8) *eax)
-      (write-buffered *(ebp+8) "/xm32")
-      e9/jump $emit-subx-var-as-xm32:end/disp32
-    }
-    # else if (operand->stack-offset) emit "*(ebp+__)"
-    {
-      81 7/subop/compare *(esi+0x14) 0/imm32  # Var-offset
-      74/jump-if-= break/disp8
-$emit-subx-var-as-xm32:stack:
-      (write-buffered *(ebp+8) Space)
-      (write-buffered *(ebp+8) "*(ebp+")
-      (write-int32-hex-buffered *(ebp+8) *(esi+0x14))  # Var-offset
-      (write-buffered *(ebp+8) ")")
-    }
-$emit-subx-var-as-xm32:end:
-    # . restore registers
-    5e/pop-to-esi
-    59/pop-to-ecx
-    58/pop-to-eax
-    # . epilogue
-    89/<- %esp 5/r32/ebp
-    5d/pop-to-ebp
-    c3/return
-
 find-matching-primitive:  # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive)
     # . prologue
     55/push-ebp