diff options
-rw-r--r-- | 075print-int-decimal.subx | 61 | ||||
-rwxr-xr-x | apps/assort | bin | 44233 -> 44392 bytes | |||
-rwxr-xr-x | apps/braces | bin | 46096 -> 46255 bytes | |||
-rwxr-xr-x | apps/calls | bin | 50743 -> 50902 bytes | |||
-rwxr-xr-x | apps/crenshaw2-1 | bin | 43574 -> 43733 bytes | |||
-rwxr-xr-x | apps/crenshaw2-1b | bin | 44121 -> 44280 bytes | |||
-rwxr-xr-x | apps/dquotes | bin | 47855 -> 48014 bytes | |||
-rwxr-xr-x | apps/factorial | bin | 42677 -> 42836 bytes | |||
-rwxr-xr-x | apps/hex | bin | 46413 -> 46572 bytes | |||
-rwxr-xr-x | apps/mu | bin | 278754 -> 280373 bytes | |||
-rw-r--r-- | apps/mu.subx | 187 | ||||
-rwxr-xr-x | apps/pack | bin | 56548 -> 56707 bytes | |||
-rw-r--r-- | apps/parse-int.mu | 50 | ||||
-rwxr-xr-x | apps/sigils | bin | 58465 -> 58624 bytes | |||
-rwxr-xr-x | apps/survey | bin | 54165 -> 54324 bytes | |||
-rwxr-xr-x | apps/tests | bin | 43005 -> 43164 bytes |
16 files changed, 290 insertions, 8 deletions
diff --git a/075print-int-decimal.subx b/075print-int-decimal.subx index 62d9b6e0..38edd445 100644 --- a/075print-int-decimal.subx +++ b/075print-int-decimal.subx @@ -402,4 +402,65 @@ test-is-decimal-digit-above-9: 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp c3/return +to-decimal-digit: # in: byte -> out/eax: int + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # eax = in + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax +$to-decimal-digit:check0: + # if (eax < '0') goto abort + 3d/compare-eax-with 0x30/imm32/0 + 7c/jump-if-< $to-decimal-digit:abort/disp8 +$to-decimal-digit:check1: + # if (eax > '9') goto abort + 3d/compare-eax-with 0x39/imm32/f + 7f/jump-if-> $to-decimal-digit:abort/disp8 +$to-decimal-digit:digit: + # return eax - '0' + 2d/subtract-from-eax 0x30/imm32/0 +$to-decimal-digit:end: + # . epilogue + 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 5d/pop-to-ebp + c3/return + +$to-decimal-digit:abort: + # . write-buffered(stderr, error) + # . . push args + 68/push "to-decimal-digit: not a digit character: "/imm32 + 68/push Stderr/imm32 + # . . call + e8/call write-buffered/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . write-byte-buffered(stderr, %eax) + # . . push args + 50/push-eax + 68/push Stderr/imm32 + # . . call +#? e8/call write-byte-buffered/disp32 + e8/call print-int32-buffered/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . write-buffered(stderr, "\n") + # . . push args + 68/push Newline/imm32 + 68/push Stderr/imm32 + # . . call + e8/call write-buffered/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . flush(Stderr) + # . . push args + 68/push Stderr/imm32 + # . . call + e8/call flush/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # . syscall(exit, 1) + bb/copy-to-ebx 1/imm32 + e8/call syscall_exit/disp32 + # never gets here + # . . vim:nowrap:textwidth=0 diff --git a/apps/assort b/apps/assort index 37b188ee..f6b0c31d 100755 --- a/apps/assort +++ b/apps/assort Binary files differdiff --git a/apps/braces b/apps/braces index d3111278..2254389c 100755 --- a/apps/braces +++ b/apps/braces Binary files differdiff --git a/apps/calls b/apps/calls index 500c9009..1b3202f0 100755 --- a/apps/calls +++ b/apps/calls Binary files differdiff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1 index 41429db7..104c787f 100755 --- a/apps/crenshaw2-1 +++ b/apps/crenshaw2-1 Binary files differdiff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b index 81bbd4f7..ec4c777c 100755 --- a/apps/crenshaw2-1b +++ b/apps/crenshaw2-1b Binary files differdiff --git a/apps/dquotes b/apps/dquotes index 90bcf0b3..7f935bb2 100755 --- a/apps/dquotes +++ b/apps/dquotes Binary files differdiff --git a/apps/factorial b/apps/factorial index 79c0e8da..34a2c970 100755 --- a/apps/factorial +++ b/apps/factorial Binary files differdiff --git a/apps/hex b/apps/hex index 794ce191..ebbafb6a 100755 --- a/apps/hex +++ b/apps/hex Binary files differdiff --git a/apps/mu b/apps/mu index dc9ce88d..5b65cf19 100755 --- a/apps/mu +++ b/apps/mu Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx index 5b6d712f..3658f332 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -6138,6 +6138,7 @@ parse-mu-var-def: # line: (addr stream byte), vars: (addr stack live-var), out: { 0f 84/jump-if-= break/disp32 # TODO: disallow vars of type 'byte' in registers 'esi' or 'edi' + # TODO: vars of type 'byte' should only be initialized by clearing to 0 # ensure that the next word is '<-' (next-mu-token *(ebp+8) %ecx) (slice-equal? %ecx "<-") # => eax @@ -7968,17 +7969,24 @@ compute-size-of-type-id: # t: type-id -> result/eax: int 89/<- %ecx 4/r32/esp # eax = t 8b/-> *(ebp+8) 0/r32/eax - # if v is a literal, return 0 + # if t is a literal, return 0 3d/compare-eax-and 0/imm32/literal - 74/jump-if-= $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int - # if v is a byte, return 1 + 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int + # if t is a byte, return 1 + 3d/compare-eax-and 8/imm32/byte { - 3d/compare-eax-and 8/imm32/byte 75/jump-if-!= break/disp8 b8/copy-to-eax 1/imm32 eb/jump $compute-size-of-type-id:end/disp8 } - # if v has a user-defined type, compute its size + # if t is a handle, return 8 + 3d/compare-eax-and 4/imm32/handle + { + 75/jump-if-!= break/disp8 + b8/copy-to-eax 8/imm32 + eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int + } + # if t is a user-defined type, compute its size # TODO: support non-atom type (find-typeinfo %eax %ecx) { @@ -8490,7 +8498,14 @@ size-of-type-id: # t: type-id -> result/eax: int 8b/-> *(ebp+8) 0/r32/eax # if t is a literal, return 0 3d/compare-eax-and 0/imm32 - 74/jump-if-= $size-of-type-id:end/disp8 # eax changes type from type-id to int + 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int + # if v is a byte, return 1 + 3d/compare-eax-and 8/imm32/byte + { + 75/jump-if-!= break/disp8 + b8/copy-to-eax 1/imm32 + eb/jump $size-of-type-id:end/disp8 + } # if t is a handle, return 8 3d/compare-eax-and 4/imm32/handle { @@ -9857,6 +9872,7 @@ translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: { 81 7/subop/compare %ecx 1/imm32 75/jump-if-!= break/disp8 +$translate-mu-length-stmt:size-1: (emit-save-size-to *(ebp+8) %ebx %edx) e9/jump $translate-mu-length-stmt:end/disp32 } @@ -9867,6 +9883,7 @@ translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: 74/jump-if-= break/disp8 81 7/subop/compare %ecx 0xff/imm32 7f/jump-if-> break/disp8 +$translate-mu-length-stmt:size-power-of-2: (emit-save-size-to *(ebp+8) %ebx %edx) (emit-divide-by-shift-right *(ebp+8) %edx %ecx) e9/jump $translate-mu-length-stmt:end/disp32 @@ -9874,6 +9891,7 @@ translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: # otherwise, the complex case # . emit register spills { +$translate-mu-length-stmt:complex: (string-equal? %edx "eax") # => eax 3d/compare-eax-and 0/imm32/false 75/break-if-!= break/disp8 @@ -11733,8 +11751,26 @@ _Primitive-address: # (payload primitive) 0/imm32/no-disp32 1/imm32/output-is-write-only 0x11/imm32/alloc-id:fake - _Primitive-compare-mem-with-reg/imm32/next + _Primitive-compare-reg-with-reg/imm32/next # - compare +_Primitive-compare-reg-with-reg: # (payload primitive) + 0x11/imm32/alloc-id:fake:payload + # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32 + 0x11/imm32/alloc-id:fake + _string-compare/imm32/name + 0x11/imm32/alloc-id:fake + Two-int-args-in-regs/imm32/inouts + 0/imm32/no-outputs + 0/imm32/no-outputs + 0x11/imm32/alloc-id:fake + _string_39_compare->/imm32/subx-name + 1/imm32/rm32-is-first-inout + 2/imm32/r32-is-second-inout + 0/imm32/no-imm32 + 0/imm32/no-disp32 + 0/imm32/output-is-write-only + 0x11/imm32/alloc-id:fake + _Primitive-compare-mem-with-reg/imm32/next _Primitive-compare-mem-with-reg: # (payload primitive) 0x11/imm32/alloc-id:fake:payload # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 @@ -11824,8 +11860,26 @@ _Primitive-compare-mem-with-literal: # (payload primitive) 0/imm32/no-disp32 0/imm32/output-is-write-only 0x11/imm32/alloc-id:fake - _Primitive-multiply-reg-by-mem/imm32/next + _Primitive-multiply-reg-by-reg/imm32/next # - multiply +_Primitive-multiply-reg-by-reg: # (payload primitive) + 0x11/imm32/alloc-id:fake:payload + # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 + 0x11/imm32/alloc-id:fake + _string-multiply/imm32/name + 0x11/imm32/alloc-id:fake + Single-int-var-in-some-register/imm32/inouts + 0x11/imm32/alloc-id:fake + Single-int-var-in-some-register/imm32/outputs + 0x11/imm32/alloc-id:fake + _string_0f_af_multiply/imm32/subx-name + 1/imm32/rm32-is-first-inout + 3/imm32/r32-is-first-output + 0/imm32/no-imm32 + 0/imm32/no-disp32 + 0/imm32/output-is-write-only + 0x11/imm32/alloc-id:fake + _Primitive-multiply-reg-by-mem/imm32/next _Primitive-multiply-reg-by-mem: # (payload primitive) 0x11/imm32/alloc-id:fake:payload # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 @@ -13269,6 +13323,13 @@ Two-args-int-stack-int-reg: # (payload list var) 0x11/imm32/alloc-id:fake Single-int-var-in-some-register/imm32/next +Two-int-args-in-regs: # (payload list var) + 0x11/imm32/alloc-id:fake:payload + 0x11/imm32/alloc-id:fake + Int-var-in-some-register/imm32 + 0x11/imm32/alloc-id:fake + Single-int-var-in-some-register/imm32/next + # Not really legal, but closest we can currently represent a dereference of an (addr byte) Two-args-byte-stack-byte-reg: # (payload list var) 0x11/imm32/alloc-id:fake:payload @@ -15671,6 +15732,116 @@ $test-add-literal-to-mem:initialize-stmt-operation: 5d/pop-to-ebp c3/return +test-compare-reg-with-reg: + # compare var1/ecx, var2/eax + # => + # 39/compare %ecx 0/r32/eax + # + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # setup + (clear-stream _test-output-stream) + (clear-stream $_test-output-buffered-file->buffer) +$test-compare-reg-with-reg:initialize-type: + # var type/ecx: (payload tree type-id) = int + 68/push 0/imm32/right:null + 68/push 0/imm32/right:null + 68/push 0/imm32/left:unused + 68/push 1/imm32/value:int + 68/push 1/imm32/is-atom?:true + 68/push 0x11/imm32/alloc-id:fake:payload + 89/<- %ecx 4/r32/esp +$test-compare-reg-with-reg:initialize-var1: + # var var1/ecx: (payload var) + 68/push 0/imm32/register + 68/push 0/imm32/register + 68/push 0/imm32/no-stack-offset + 68/push 1/imm32/block-depth + 51/push-ecx + 68/push 0x11/imm32/alloc-id:fake + 68/push 0/imm32/name + 68/push 0/imm32/name + 68/push 0x11/imm32/alloc-id:fake:payload + 89/<- %ecx 4/r32/esp +$test-compare-reg-with-reg:initialize-var1-name: + # var1->name = "var1" + 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 + (copy-array Heap "var1" %eax) +$test-compare-reg-with-reg:initialize-var1-register: + # var1->register = "ecx" + 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 + (copy-array Heap "ecx" %eax) +$test-compare-reg-with-reg:initialize-var2: + # var var2/edx: (payload var) + 68/push 0/imm32/register + 68/push 0/imm32/register + 68/push 0/imm32/no-stack-offset + 68/push 1/imm32/block-depth + ff 6/subop/push *(ecx+0x10) + 68/push 0x11/imm32/alloc-id:fake + 68/push 0/imm32/name + 68/push 0/imm32/name + 68/push 0x11/imm32/alloc-id:fake:payload + 89/<- %edx 4/r32/esp +$test-compare-reg-with-reg:initialize-var2-name: + # var2->name = "var2" + 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 + (copy-array Heap "var2" %eax) +$test-compare-reg-with-reg:initialize-var2-register: + # var2->register = "eax" + 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 + (copy-array Heap "eax" %eax) +$test-compare-reg-with-reg:initialize-inouts: + # var inouts/esi: (payload stmt-var) = [var2] + 68/push 0/imm32/is-deref:false + 68/push 0/imm32/next + 68/push 0/imm32/next + 52/push-edx/var2 + 68/push 0x11/imm32/alloc-id:fake + 68/push 0x11/imm32/alloc-id:fake:payload + 89/<- %esi 4/r32/esp + # inouts = [var1, var2] + 68/push 0/imm32/is-deref:false + 56/push-esi/next + 68/push 0x11/imm32/alloc-id:fake + 51/push-ecx/var1 + 68/push 0x11/imm32/alloc-id:fake + 68/push 0x11/imm32/alloc-id:fake:payload + 89/<- %esi 4/r32/esp +$test-compare-reg-with-reg:initialize-stmt: + # var stmt/esi: (addr statement) + 68/push 0/imm32/next + 68/push 0/imm32/next + 68/push 0/imm32/outputs + 68/push 0/imm32/outputs + 56/push-esi/inouts + 68/push 0x11/imm32/alloc-id:fake + 68/push 0/imm32/operation + 68/push 0/imm32/operation + 68/push 1/imm32/tag:stmt1 + 89/<- %esi 4/r32/esp +$test-compare-reg-with-reg:initialize-stmt-operation: + # stmt->operation = "compare" + 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation + (copy-array Heap "compare" %eax) + # convert + c7 0/subop/copy *Curr-block-depth 0/imm32 + (emit-subx-stmt _test-output-buffered-file %esi Primitives 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 "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg") + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + test-compare-mem-with-reg: # compare var1, var2/eax # => diff --git a/apps/pack b/apps/pack index ad15dd42..2b9e77dd 100755 --- a/apps/pack +++ b/apps/pack Binary files differdiff --git a/apps/parse-int.mu b/apps/parse-int.mu new file mode 100644 index 00000000..c9c1d945 --- /dev/null +++ b/apps/parse-int.mu @@ -0,0 +1,50 @@ +# parse a decimal int at the commandline +# +# To run: +# $ ./translate_mu apps/parse-int.mu +# $ ./a.elf 123 +# $ echo $? +# 123 + +fn main _args: (addr array (addr array byte)) -> exit-status/ebx: int { +$main-body: { + # if no args, print a message and exit + var args/esi: (addr array (addr array byte)) <- copy _args + var n/ecx: int <- length args + compare n, 1 + { + break-if-> + print-string "usage: parse-int <integer>\n" + exit-status <- copy 1 + break $main-body + } + # otherwise parse the first arg as an integer + var in/ecx: (addr addr array byte) <- index args, 1 + var out/eax: int <- parse-int *in + exit-status <- copy out +} +} + +fn parse-int _in: (addr array byte) -> result/eax: int { + var in/esi: (addr array byte) <- copy _in + var len/edx: int <- length in + var i/ecx: int <- copy 0 + var out/edi: int <- copy 0 + { + compare i, len + break-if->= + # out *= 10 + var ten/eax: int <- copy 0xa + out <- multiply ten + # c = in[i] + var tmp/ebx: (addr byte) <- index in, i + var c/eax: byte <- copy 0 + c <- copy-byte *tmp + # + var digit/eax: int <- to-decimal-digit c + out <- add digit + i <- increment + loop + } + result <- copy out +} diff --git a/apps/sigils b/apps/sigils index b2ab77cf..29dafc9d 100755 --- a/apps/sigils +++ b/apps/sigils Binary files differdiff --git a/apps/survey b/apps/survey index 0d94f444..9d00da8a 100755 --- a/apps/survey +++ b/apps/survey Binary files differdiff --git a/apps/tests b/apps/tests index 5f431146..8e318bb3 100755 --- a/apps/tests +++ b/apps/tests Binary files differ |