diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-08-25 22:17:19 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-08-25 22:19:24 -0700 |
commit | c45371b319bb72b331f889f7340834c709e1f8a4 (patch) | |
tree | 6e226b9c757a2d22176930e26fc61fc50c17100b | |
parent | 9b62454975ef7cd0ef21ed8edd113f8209f32c11 (diff) | |
download | mu-c45371b319bb72b331f889f7340834c709e1f8a4.tar.gz |
compute-offset: literal index
-rwxr-xr-x | linux/mu | bin | 611784 -> 614607 bytes | |||
-rw-r--r-- | linux/mu.subx | 135 | ||||
-rw-r--r-- | mu_instructions | 2 |
3 files changed, 132 insertions, 5 deletions
diff --git a/linux/mu b/linux/mu index 0f9798a7..fdeacea0 100755 --- a/linux/mu +++ b/linux/mu Binary files differdiff --git a/linux/mu.subx b/linux/mu.subx index 0a6d6fdb..879b751e 100644 --- a/linux/mu.subx +++ b/linux/mu.subx @@ -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 @@ -29889,6 +29936,35 @@ translate-mu-compute-offset-stmt: # out: (addr buffered-file), stmt: (addr stmt 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 + # . save registers + 50/push-eax 51/push-ecx 52/push-edx 53/push-ebx @@ -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 diff --git a/mu_instructions b/mu_instructions index 2dca40c4..4898f9a1 100644 --- a/mu_instructions +++ b/mu_instructions @@ -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" |