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.
This commit is contained in:
parent
1bf5d5f44e
commit
93c6352dda
BIN
apps/calls
BIN
apps/calls
Binary file not shown.
|
@ -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
|
||||
|
|
109
apps/mu.subx
109
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
|
||||
|
|
Loading…
Reference in New Issue