From 156763463d07072bed54172f45d9083c207470c8 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 24 May 2020 13:27:08 -0700 Subject: 6390 - return `length` in elements --- apps/mu.subx | 110 +++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 22 deletions(-) (limited to 'apps/mu.subx') diff --git a/apps/mu.subx b/apps/mu.subx index 3d6c9dc2..1d1d60ab 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -2436,14 +2436,15 @@ test-convert-length-of-array: (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5") (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6") (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7") - (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/9") - (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/11") - (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/12") - (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/13") - (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/14") - (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/15") - (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/16") - (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/17") + (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8") + (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm32" "F - test-convert-length-of-array/9") + (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10") + (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11") + (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12") + (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13") + (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14") + (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15") + (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16") # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp @@ -2484,14 +2485,15 @@ test-convert-length-of-array-on-stack: (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7") (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8") (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9") - (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/10") - (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/11") - (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/12") - (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/13") - (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/14") - (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/15") - (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/16") - (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/17") + (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm32" "F - test-convert-length-of-array-on-stack/10") + (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11") + (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12") + (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13") + (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14") + (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15") + (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16") + (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17") + (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18") # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp @@ -8842,28 +8844,31 @@ translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt) # . save registers 50/push-eax 51/push-ecx + 52/push-edx + 53/push-ebx # ecx = stmt 8b/-> *(ebp+0xc) 1/r32/ecx # (emit-indent *(ebp+8) *Curr-block-depth) (write-buffered *(ebp+8) "8b/-> *") - # var base/eax: (handle var) = inouts[0] + # var base/ebx: (addr var) = inouts[0] (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 89/<- %ebx 0/r32/eax # if base is an (addr array ...) in a register { - 81 7/subop/compare *(eax+0x18)) 0/imm32 # Var-register + 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register 74/jump-if-= break/disp8 - (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax + (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax (write-buffered *(ebp+8) %eax) eb/jump $translate-mu-length-stmt:emit-output/disp8 } # otherwise if base is an (array ...) on the stack { - 81 7/subop/compare *(eax+0x14)) 0/imm32 # Var-offset + 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset 74/jump-if-= break/disp8 (write-buffered *(ebp+8) "(ebp+") - (print-int32-buffered *(ebp+8) *(eax+0x14)) # Var-offset + (print-int32-buffered *(ebp+8) *(ebx+0x14)) # Var-offset (write-buffered *(ebp+8) ")") } $translate-mu-length-stmt:emit-output: @@ -8871,12 +8876,40 @@ $translate-mu-length-stmt: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 + # edx = outputs[0]->register (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - (get Registers %eax 0xc "Registers") # => eax + 89/<- %edx 0/r32/eax + # + (get Registers %edx 0xc "Registers") # => eax (print-int32-buffered *(ebp+8) *eax) (write-buffered *(ebp+8) "/r32\n") +$translate-mu-length-stmt:check-power-of-2: + # ecx = size-of(element-type(base)) + (array-element-type-id %ebx) # => eax + (size-of-type-id %eax) # => eax + 89/<- %ecx 0/r32/eax + # + (power-of-2? %ecx) # => eax + 3d/compare-eax-and 0/imm32/false + { + 0f 84/jump-if-= break/disp32 +$translate-mu-length-stmt:is-power-of-2: + (emit-indent *(ebp+8) *Curr-block-depth) + (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") + (write-buffered *(ebp+8) %edx) + (write-buffered *(ebp+8) Space) + (num-shift-rights %ecx) # => eax + (print-int32-buffered *(ebp+8) %eax) + (write-buffered *(ebp+8) "/imm32\n") + eb/jump $translate-mu-length-stmt:end/disp8 + } + { + 75/jump-if-!= break/disp8 +$translate-mu-length-stmt:not-power-of-2: + } $translate-mu-length-stmt:end: # . restore registers + 5b/pop-to-ebx 59/pop-to-ecx 58/pop-to-eax # . epilogue @@ -9310,6 +9343,39 @@ $array-element-type-id:end: 5d/pop-to-ebp c3/return +power-of-2?: # n: int -> result/eax: boolean + # precondition: n is positive + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # eax = n + 8b/-> *(ebp+8) 0/r32/eax + # if (n < 0) abort + 3d/compare-eax-with 0/imm32 + 0f 8c/jump-if-< $power-of-2?:abort/disp32 + # var tmp/eax: int = n-1 + 48/decrement-eax + # var tmp2/eax: int = n & tmp + 23/and-> *(ebp+8) 0/r32/eax + # return (tmp2 == 0) + 3d/compare-eax-and 0/imm32 + 0f 94/set-byte-if-= %al + 81 4/subop/and %eax 0xff/imm32 +$power-of-2?:end: + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +$power-of-2?:abort: + (write-buffered Stderr "power-of-2?: negative number\n") + (flush Stderr) + # . syscall(exit, 1) + bb/copy-to-ebx 1/imm32 + b8/copy-to-eax 1/imm32/exit + cd/syscall 0x80/imm8 + # never gets here + num-shift-rights: # n: int -> result/eax: int # precondition: n is a positive power of 2 # . prologue -- cgit 1.4.1-2-gfad0