From 93c6352dda47f54c602a343b665bf7860678561b Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 4 Oct 2020 00:54:57 -0700 Subject: 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. --- apps/calls | Bin 53168 -> 53372 bytes apps/calls.subx | 59 +++++++++++++++++++++++++++++- apps/mu | Bin 422179 -> 421479 bytes apps/mu.subx | 109 +++++++------------------------------------------------- 4 files changed, 71 insertions(+), 97 deletions(-) (limited to 'apps') diff --git a/apps/calls b/apps/calls index 781eb04d..09382fec 100755 Binary files a/apps/calls and b/apps/calls differ diff --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 Binary files a/apps/mu and b/apps/mu differ diff --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 -- cgit 1.4.1-2-gfad0