compute-offset: literal index

This commit is contained in:
Kartik K. Agaram 2021-08-25 22:17:19 -07:00
parent 9b62454975
commit c45371b319
3 changed files with 132 additions and 5 deletions

BIN
linux/mu

Binary file not shown.

View File

@ -6760,6 +6760,53 @@ test-convert-index-into-array-using-offset:
5d/pop-to-ebp
c3/return
test-convert-compute-offset-using-literal-index:
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# setup
(clear-stream _test-input-stream)
(clear-stream $_test-input-buffered-file->buffer)
(clear-stream _test-output-stream)
(clear-stream $_test-output-buffered-file->buffer)
#
(write _test-input-stream "fn foo {\n")
(write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n")
(write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, 3\n")
(write _test-input-stream "}\n")
# convert
(convert-mu _test-input-buffered-file _test-output-buffered-file 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 "foo:" "F - test-convert-compute-offset-using-literal-index/0")
(check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compute-offset-using-literal-index/1")
(check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compute-offset-using-literal-index/2")
(check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compute-offset-using-literal-index/3")
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compute-offset-using-literal-index/4")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compute-offset-using-literal-index/5")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-compute-offset-using-literal-index/6")
(check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-compute-offset-using-literal-index/7")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compute-offset-using-literal-index/8")
(check-next-stream-line-equal _test-output-stream " c7/copy %ecx 0x0000000c/imm32" "F - test-convert-compute-offset-using-literal-index/9")
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compute-offset-using-literal-index/10")
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-compute-offset-using-literal-index/11")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compute-offset-using-literal-index/12")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compute-offset-using-literal-index/13")
(check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compute-offset-using-literal-index/14")
(check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compute-offset-using-literal-index/15")
(check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compute-offset-using-literal-index/16")
(check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compute-offset-using-literal-index/17")
# . epilogue
89/<- %esp 5/r32/ebp
5d/pop-to-ebp
c3/return
test-convert-index-into-array-of-bytes-using-offset:
# . prologue
55/push-ebp
@ -29846,7 +29893,7 @@ $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done:
$translate-mu-index-stmt-with-array-on-stack:emit-literal-index:
# var idx-value/edx: int = parse-hex-int(index->name)
(lookup *edx *(edx+4)) # Var-name Var-name => eax
(parse-hex-int %eax) # Var-name => eax
(parse-hex-int %eax) # => eax
89/<- %edx 0/r32/eax
# offset = idx-value * array-element-size(base)
(array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax
@ -29884,6 +29931,35 @@ $translate-mu-index-stmt-with-array-on-stack:end:
c3/return
translate-mu-compute-offset-stmt: # out: (addr buffered-file), 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
# var index-type/eax: (addr type-tree) = stmt->inouts->next->value->type
8b/-> *(ebp+0xc) 0/r32/eax
(lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
(lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
(lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
(lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
(simple-mu-type? %eax 0) # literal => eax
3d/compare-eax-and 0/imm32/false
{
74/jump-if-= break/disp8
# special-case: index is a literal
(translate-mu-compute-offset-stmt-with-literal-index *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
eb/jump $translate-mu-compute-offset-stmt:end/disp8
}
(translate-mu-compute-offset-stmt-with-register-index *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
$translate-mu-compute-offset-stmt:end:
# . restore registers
58/pop-to-eax
# . epilogue
89/<- %esp 5/r32/ebp
5d/pop-to-ebp
c3/return
translate-mu-compute-offset-stmt-with-register-index: # out: (addr buffered-file), stmt-with-register-index: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
@ -29900,11 +29976,11 @@ translate-mu-compute-offset-stmt: # out: (addr buffered-file), stmt: (addr stmt
# var first-inout/ebx: (addr stmt-var) = stmt->inouts[0]
(lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
89/<- %ebx 0/r32/eax
$translate-mu-compute-offset-stmt:emit-index:
$translate-mu-compute-offset-stmt-with-register-index:emit-index:
(lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax
(emit-subx-var-as-rm32 *(ebp+8) %eax)
(write-buffered *(ebp+8) Space)
$translate-mu-compute-offset-stmt:emit-elem-size:
$translate-mu-compute-offset-stmt-with-register-index:emit-elem-size:
# var base/ebx: (addr var)
(lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax
89/<- %ebx 0/r32/eax
@ -29912,7 +29988,7 @@ $translate-mu-compute-offset-stmt:emit-elem-size:
(array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax
(write-int32-hex-buffered *(ebp+8) %eax)
(write-buffered *(ebp+8) "/imm32 ")
$translate-mu-compute-offset-stmt:emit-output:
$translate-mu-compute-offset-stmt-with-register-index:emit-output:
# outputs[0] "/r32"
(lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax
(lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
@ -29920,7 +29996,56 @@ $translate-mu-compute-offset-stmt:emit-output:
(get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int)
(write-int32-hex-buffered *(ebp+8) *eax)
(write-buffered *(ebp+8) "/r32\n")
$translate-mu-compute-offset-stmt:end:
$translate-mu-compute-offset-stmt-with-register-index:end:
# . restore registers
5b/pop-to-ebx
5a/pop-to-edx
59/pop-to-ecx
58/pop-to-eax
# . epilogue
89/<- %esp 5/r32/ebp
5d/pop-to-ebp
c3/return
translate-mu-compute-offset-stmt-with-literal-index: # out: (addr buffered-file), stmt-with-literal-index: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# . save registers
50/push-eax
51/push-ecx
52/push-edx
53/push-ebx
#
(emit-indent *(ebp+8) *Curr-block-depth)
(write-buffered *(ebp+8) "c7/copy %")
# ecx = stmt
8b/-> *(ebp+0xc) 1/r32/ecx
$translate-mu-compute-offset-stmt-with-literal-index:emit-output:
# emit outputs[0]->register
(lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax
(lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
(lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
(write-buffered *(ebp+8) %eax)
(write-buffered *(ebp+8) Space)
$translate-mu-compute-offset-stmt-with-literal-index:emit-offset:
# var first-inout/ebx: (addr stmt-var) = stmt->inouts
(lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
89/<- %ebx 0/r32/eax
# var index/edx: int = int(first-inout->next->value)
(lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax
(lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
(lookup *eax *(eax+4)) # Var-name Var-name => eax
(parse-hex-int %eax) # => eax
89/<- %edx 0/r32/eax
# var base/ebx: (addr var) = first-inout->value
(lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax
# emit index * sizeof(base element type)
(array-element-size %eax *(ebp+0x10) *(ebp+0x14)) # => eax
0f af/multiply %edx 0/r32/eax
(write-int32-hex-buffered *(ebp+8) %eax)
(write-buffered *(ebp+8) "/imm32\n")
$translate-mu-compute-offset-stmt-with-literal-index:end:
# . restore registers
5b/pop-to-ebx
5a/pop-to-edx

View File

@ -367,6 +367,8 @@ var/reg: (offset T) <- compute-offset arr: (addr array T), idx/regi: int # arr
=> "69/multiply %" regi " " size-of(T) "/imm32 " reg "/r32"
var/reg: (offset T) <- compute-offset arr: (addr array T), idx: int # arr can be in reg or mem
=> "69/multiply *(ebp+" idx.stack-offset ") " size-of(T) "/imm32 " reg "/r32"
var/reg: (offset T) <- compute-offset arr: (addr array T), n # arr can be in reg or mem
=> "c7 0/subop/copy %" reg " " n*size-of(T) "/imm32"
var/reg: (addr T) <- index arr/rega: (addr array T), o/rego: (offset T)
=> "81 7/subop/compare %" rega " 0/imm32"
"0f 84/jump-if-= __mu-abort-null-index-base-address/disp32"