5752
Support binary operations with reg/mem and reg operands. Everything is passing. However, the self-hosting translator now generates some discrepancies compared to the C++ translator :(
This commit is contained in:
parent
0ea0ebcf81
commit
442fdabe30
|
@ -0,0 +1,15 @@
|
|||
== data
|
||||
Registers: # (table string int)
|
||||
# a table is a stream
|
||||
0x40/imm32/write
|
||||
0/imm32/read
|
||||
0x40/imm32/length
|
||||
# data
|
||||
"eax"/imm32 0/imm32
|
||||
"ecx"/imm32 1/imm32
|
||||
"edx"/imm32 2/imm32
|
||||
"ebx"/imm32 3/imm32
|
||||
"esp"/imm32 4/imm32
|
||||
"ebp"/imm32 5/imm32
|
||||
"esi"/imm32 6/imm32
|
||||
"edi"/imm32 7/imm32
|
BIN
apps/assort
BIN
apps/assort
Binary file not shown.
BIN
apps/braces
BIN
apps/braces
Binary file not shown.
BIN
apps/calls
BIN
apps/calls
Binary file not shown.
BIN
apps/crenshaw2-1
BIN
apps/crenshaw2-1
Binary file not shown.
Binary file not shown.
BIN
apps/dquotes
BIN
apps/dquotes
Binary file not shown.
BIN
apps/factorial
BIN
apps/factorial
Binary file not shown.
BIN
apps/handle
BIN
apps/handle
Binary file not shown.
174
apps/mu.subx
174
apps/mu.subx
|
@ -953,16 +953,26 @@ Primitives:
|
|||
1/imm32/rm32-is-first-inout
|
||||
0/imm32/no-r32
|
||||
0/imm32/no-imm32
|
||||
_Primitive-inc-reg/imm32
|
||||
_Primitive-inc-reg/imm32/next
|
||||
_Primitive-inc-reg:
|
||||
# var/reg <- increment => ff 0/subop/increment %__
|
||||
"increment"/imm32/name
|
||||
0/imm32/no-inouts
|
||||
Single-var-in-some-register/imm32/outputs
|
||||
Single-int-var-in-some-register/imm32/outputs
|
||||
"ff 0/subop/increment"/imm32/subx-name
|
||||
3/imm32/rm32-is-first-output
|
||||
0/imm32/no-r32
|
||||
0/imm32/no-imm32
|
||||
_Primitive-add-reg-to-reg/imm32/next
|
||||
_Primitive-add-reg-to-reg:
|
||||
# var1/reg <- add var2/reg => 01 var1/rm32 var2/r32
|
||||
"add"/imm32/name
|
||||
Single-int-var-in-some-register/imm32/inouts
|
||||
Single-int-var-in-some-register/imm32/outputs
|
||||
"01"/imm32/subx-name
|
||||
3/imm32/rm32-is-first-output
|
||||
1/imm32/r32-is-first-inout
|
||||
0/imm32/no-imm32
|
||||
0/imm32/next
|
||||
|
||||
Single-int-var-on-stack:
|
||||
|
@ -976,7 +986,7 @@ Int-var-on-stack:
|
|||
1/imm32/some-stack-offset
|
||||
0/imm32/no-register
|
||||
|
||||
Single-var-in-some-register:
|
||||
Single-int-var-in-some-register:
|
||||
Int-var-in-some-register/imm32
|
||||
0/imm32/next
|
||||
|
||||
|
@ -1001,8 +1011,8 @@ emit-subx-primitive: # out : (address buffered-file), stmt : (address statement
|
|||
(write-buffered *(ebp+8) *(ecx+0xc)) # Primitive-subx-name
|
||||
# emit rm32 if necessary
|
||||
(emit-subx-rm32 *(ebp+8) *(ecx+0x10) *(ebp+0xc)) # out, Primitive-subx-rm32, stmt
|
||||
#? # emit r32 if necessary
|
||||
#? (emit-subx-r32 *(ebp+8) *(ecx+0x14) *(ebp+0xc)) # out, Primitive-subx-r32, stmt
|
||||
# emit r32 if necessary
|
||||
(emit-subx-r32 *(ebp+8) *(ecx+0x14) *(ebp+0xc)) # out, Primitive-subx-r32, stmt
|
||||
#? # emit imm32 if necessary
|
||||
#? (emit-subx-imm32 *(ebp+8) *(ecx+0x18) *(ebp+0xc)) # out, Primitive-subx-imm32, stmt
|
||||
$emit-subx-primitive:end:
|
||||
|
@ -1101,10 +1111,15 @@ emit-subx-r32: # out : (address buffered-file), l : arg-location, stmt : (addre
|
|||
# . save registers
|
||||
50/push-eax
|
||||
51/push-ecx
|
||||
# location/ecx : enum = primitive->subx-r32
|
||||
# if (location == 0) return
|
||||
# var/ecx : var = get-operand(stmt, primitive->subx-rm32)
|
||||
# emit-subx-call-operand(out, var)
|
||||
81 7/subop/compare *(ebp+0xc) 0/imm32
|
||||
0f 84/jump-if-equal $emit-subx-r32:end/disp32
|
||||
#
|
||||
(get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax
|
||||
(maybe-get Registers *(eax+0x10) 8) # Var-register => eax : (address register-index)
|
||||
(write-buffered *(ebp+8) Space)
|
||||
(print-int32-buffered *(ebp+8) *eax)
|
||||
(write-buffered *(ebp+8) "/r32")
|
||||
$emit-subx-r32:end:
|
||||
# . restore registers
|
||||
59/pop-to-ecx
|
||||
|
@ -1121,8 +1136,12 @@ emit-subx-imm32: # out : (address buffered-file), l : arg-location, stmt : (add
|
|||
# . save registers
|
||||
50/push-eax
|
||||
51/push-ecx
|
||||
# var/ecx : var = get-operand(stmt, primitive->subx-rm32)
|
||||
# emit-subx-call-operand(out, var)
|
||||
# if (location == 0) return
|
||||
81 7/subop/compare *(ebp+0xc) 0/imm32
|
||||
74/jump-if-equal $emit-subx-imm32:end/disp8
|
||||
#
|
||||
(get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax
|
||||
(emit-subx-call-operand *(ebp+8) %eax) # out, var
|
||||
$emit-subx-imm32:end:
|
||||
# . restore registers
|
||||
59/pop-to-ecx
|
||||
|
@ -1394,7 +1413,7 @@ $mu-stmt-matches-primitive?:check-outputs:
|
|||
}
|
||||
# if (curr != curr2) return false
|
||||
{
|
||||
(output-operand-matches-primitive? *esi *edi) # => eax
|
||||
(operand-matches-primitive? *esi *edi) # => eax
|
||||
3d/compare-eax-and 0/imm32
|
||||
75/jump-if-not-equal break/disp8
|
||||
b8/copy-to-eax 0/imm32
|
||||
|
@ -1419,48 +1438,7 @@ $mu-stmt-matches-primitive?:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
operand-matches-primitive?: # var1 : (address var), var2 : (address var) => result/eax : boolean
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# esi = var1
|
||||
8b/-> *(ebp+8) 6/r32/esi
|
||||
# edi = var2
|
||||
8b/-> *(ebp+0xc) 7/r32/edi
|
||||
# if (var1->type != var2->type) return false
|
||||
# if (var1->register != var1->register) return false
|
||||
{
|
||||
# if addresses are equal, don't return here
|
||||
8b/-> *(esi+0x10) 0/r32/eax
|
||||
39/compare *(edi+0x10) 0/r32/eax
|
||||
74/jump-if-equal break/disp8
|
||||
# if either address is 0, return false
|
||||
3d/compare-eax-and 0/imm32
|
||||
74/jump-if-equal $operand-matches-primitive?:end/disp8 # eax goes from meaning var1->register to result
|
||||
81 7/subop/compare *(edi+0x10) 0/imm32
|
||||
74/jump-if-equal $operand-matches-primitive?:end/disp8 # eax goes from meaning var1->register to result
|
||||
# if string contents don't match, return false
|
||||
(string-equal? *(esi+0x10) *(edi+0x10)) # Var-register Var-register
|
||||
3d/compare-eax-and 0/imm32
|
||||
b8/copy-to-eax 0/imm32/false
|
||||
74/jump-if-equal $operand-matches-primitive?:end/disp8
|
||||
}
|
||||
# return true
|
||||
b8/copy-to-eax 1/imm32/true
|
||||
$operand-matches-primitive?:end:
|
||||
# . restore registers
|
||||
5f/pop-to-edi
|
||||
5e/pop-to-esi
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
# like operand-matches-primitive? but also handles "*" register in primitive
|
||||
output-operand-matches-primitive?: # var : (address var), primout-var : (address var) => result/eax : boolean
|
||||
operand-matches-primitive?: # var : (address var), primout-var : (address var) => result/eax : boolean
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
|
@ -1472,6 +1450,7 @@ output-operand-matches-primitive?: # var : (address var), primout-var : (addres
|
|||
# edi = primout-var
|
||||
8b/-> *(ebp+0xc) 7/r32/edi
|
||||
# if (var->type != primout-var->type) return false
|
||||
# TODO
|
||||
# return false if var->register doesn't match primout-var->register
|
||||
{
|
||||
# if addresses are equal, don't return here
|
||||
|
@ -1496,7 +1475,7 @@ output-operand-matches-primitive?: # var : (address var), primout-var : (addres
|
|||
}
|
||||
# return true
|
||||
b8/copy-to-eax 1/imm32/true
|
||||
$output-operand-matches-primitive?:end:
|
||||
$operand-matches-primitive?:end:
|
||||
# . restore registers
|
||||
5f/pop-to-edi
|
||||
5e/pop-to-esi
|
||||
|
@ -1576,9 +1555,7 @@ $aa-primitive-in-ebx:
|
|||
#? (rewind-stream _test-output-stream)
|
||||
#? # }}}
|
||||
# check output
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-statement-primitive/0")
|
||||
# . reclaim locals
|
||||
81 0/subop/add %esp 0x48/imm32
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-statement-primitive")
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
|
@ -1661,9 +1638,7 @@ test-emit-subx-statement-primitive-register:
|
|||
#? (rewind-stream _test-output-stream)
|
||||
#? # }}}
|
||||
# check output
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-primitive-register/0")
|
||||
# . reclaim locals
|
||||
81 0/subop/add %esp 0x48/imm32
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-primitive-register")
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
|
@ -1759,9 +1734,7 @@ test-emit-subx-statement-select-primitive:
|
|||
#? (rewind-stream _test-output-stream)
|
||||
#? # }}}
|
||||
# check output
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive/0")
|
||||
# . reclaim locals
|
||||
81 0/subop/add %esp 0x48/imm32
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive")
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
|
@ -1857,15 +1830,13 @@ test-emit-subx-statement-select-primitive-2:
|
|||
#? (rewind-stream _test-output-stream)
|
||||
#? # }}}
|
||||
# check output
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive-2/0")
|
||||
# . reclaim locals
|
||||
81 0/subop/add %esp 0x48/imm32
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive-2")
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
test-emit-subx-statement-select-primitive-using-global-primitives:
|
||||
test-increment-register:
|
||||
# Select the right primitive between overloads.
|
||||
# foo <- increment
|
||||
# =>
|
||||
|
@ -1918,15 +1889,13 @@ test-emit-subx-statement-select-primitive-using-global-primitives:
|
|||
#? (rewind-stream _test-output-stream)
|
||||
#? # }}}
|
||||
# check output
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive/0")
|
||||
# . reclaim locals
|
||||
81 0/subop/add %esp 0x48/imm32
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-increment-register")
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
test-emit-subx-statement-select-primitive-using-global-primitives-2:
|
||||
test-increment-var:
|
||||
# Select the right primitive between overloads.
|
||||
# foo <- increment
|
||||
# =>
|
||||
|
@ -1979,9 +1948,62 @@ test-emit-subx-statement-select-primitive-using-global-primitives-2:
|
|||
#? (rewind-stream _test-output-stream)
|
||||
#? # }}}
|
||||
# check output
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive-2/0")
|
||||
# . reclaim locals
|
||||
81 0/subop/add %esp 0x48/imm32
|
||||
(check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-increment-var")
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
test-add-reg-to-reg:
|
||||
# var1/reg <- add var2/reg
|
||||
# =>
|
||||
# 01 %var1 var2
|
||||
#
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# setup
|
||||
(clear-stream _test-output-stream)
|
||||
(clear-stream _test-output-buffered-file->buffer)
|
||||
# var-var1/ecx : var in eax
|
||||
68/push "eax"/imm32/register
|
||||
68/push 0/imm32/no-stack-offset
|
||||
68/push 1/imm32/block-depth
|
||||
68/push 1/imm32/type-int
|
||||
68/push "var1"/imm32
|
||||
89/<- %ecx 4/r32/esp
|
||||
# var-var2/edx : var in ecx
|
||||
68/push "ecx"/imm32/register
|
||||
68/push 0/imm32/no-stack-offset
|
||||
68/push 1/imm32/block-depth
|
||||
68/push 1/imm32/type-int
|
||||
68/push "var2"/imm32
|
||||
89/<- %edx 4/r32/esp
|
||||
# inouts/esi : (list var2)
|
||||
68/push 0/imm32/next
|
||||
52/push-edx/var-var2
|
||||
89/<- %esi 4/r32/esp
|
||||
# outputs/edi : (list var1)
|
||||
68/push 0/imm32/next
|
||||
51/push-ecx/var-var1
|
||||
89/<- %edi 4/r32/esp
|
||||
# stmt/esi : statement
|
||||
68/push 0/imm32/next
|
||||
57/push-edi/outputs
|
||||
56/push-esi/inouts
|
||||
68/push "add"/imm32/operation
|
||||
89/<- %esi 4/r32/esp
|
||||
# convert
|
||||
(emit-subx-statement _test-output-buffered-file %esi 0 Primitives 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 "01 %eax 0x00000001/r32" "F - test-add-reg-to-reg")
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
|
@ -2053,9 +2075,7 @@ test-emit-subx-statement-function-call:
|
|||
#? (rewind-stream _test-output-stream)
|
||||
#? # }}}
|
||||
# check output
|
||||
(check-next-stream-line-equal _test-output-stream "(f2 *(ebp+0xfffffff8))" "F - test-emit-subx-statement-function-call/0")
|
||||
# . reclaim locals
|
||||
81 0/subop/add %esp 0x3c/imm32
|
||||
(check-next-stream-line-equal _test-output-stream "(f2 *(ebp+0xfffffff8))" "F - test-emit-subx-statement-function-call")
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
|
|
BIN
apps/sigils
BIN
apps/sigils
Binary file not shown.
|
@ -4638,20 +4638,4 @@ test-next-positive-hex-int-0-prefix:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
== data
|
||||
Registers: # (table string int)
|
||||
# a table is a stream
|
||||
0x40/imm32/write
|
||||
0/imm32/read
|
||||
0x40/imm32/length
|
||||
# data
|
||||
"eax"/imm32 0/imm32
|
||||
"ecx"/imm32 1/imm32
|
||||
"edx"/imm32 2/imm32
|
||||
"ebx"/imm32 3/imm32
|
||||
"esp"/imm32 4/imm32
|
||||
"ebp"/imm32 5/imm32
|
||||
"esi"/imm32 6/imm32
|
||||
"edi"/imm32 7/imm32
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
BIN
apps/survey
BIN
apps/survey
Binary file not shown.
BIN
apps/tests
BIN
apps/tests
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue