diff options
author | Kartik Agaram <vc@akkartik.com> | 2019-09-19 21:01:43 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2019-09-19 23:25:49 -0700 |
commit | fd91f7f61bfa84cbc24590d5394d75891cc1cfcc (patch) | |
tree | 6cbaebc23ed7c3b8627dac22e7054f14c4d38fe9 /084print-int-decimal.subx | |
parent | 881c7f02708ceaef54a0d8b5fcc136a3003d3e09 (diff) | |
download | mu-fd91f7f61bfa84cbc24590d5394d75891cc1cfcc.tar.gz |
5675 - move helpers from subx-common into layers
This undoes 5672 in favor of a new plan: Layers 000 - 099 are for running without syntax sugar. We use them for building syntax-sugar passes. Layers 100 and up are for running with all syntax sugar. The layers are arranged in approximate order so more phases rely on earlier layers than later ones. I plan to not use intermediate syntax sugar (just sigils without calls, or sigils and calls without braces) anywhere except in the specific passes implementing them.
Diffstat (limited to '084print-int-decimal.subx')
-rw-r--r-- | 084print-int-decimal.subx | 307 |
1 files changed, 0 insertions, 307 deletions
diff --git a/084print-int-decimal.subx b/084print-int-decimal.subx deleted file mode 100644 index f7898fe9..00000000 --- a/084print-int-decimal.subx +++ /dev/null @@ -1,307 +0,0 @@ -# Helper to print an int32 in decimal. - -== code -# instruction effective address register displacement immediate -# . op subop mod rm32 base index scale r32 -# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes - -print-int32-decimal: # out : (address stream), n : int32 - # works by generating characters from lowest to highest and pushing them - # to the stack, before popping them one by one into the stream - # - # pseudocode: - # push sentinel - # eax = abs(n) - # while true - # sign-extend eax into edx - # eax, edx = eax/10, eax%10 - # edx += '0' - # push edx - # if (eax == 0) break - # if n < 0 - # push '-' - # w = out->write - # curr = &out->data[out->write] - # max = &out->data[out->length] - # while true - # pop into eax - # if (eax == sentinel) break - # if (curr >= max) abort - # *curr = AL - # ++curr - # ++w - # out->write = w - # (based on K&R itoa: https://en.wikibooks.org/wiki/C_Programming/stdlib.h/itoa) - # (this pseudocode contains registers because operations like division - # require specific registers in x86) - # - # . prolog - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # . save registers - 50/push-eax - 51/push-ecx - 52/push-edx - 53/push-ebx - 57/push-edi - # ten/ecx = 10 - b9/copy-to-ecx 0xa/imm32 - # push sentinel - 68/push 0/imm32/sentinel - # eax = abs(n) - 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax - 3d/compare-eax-with 0/imm32 - 7d/jump-if-greater-or-equal $print-int32-decimal:read-loop/disp8 -$print-int32-decimal:negative: - f7 3/subop/negate 3/mod/direct 0/rm32/eax . . . . . . # negate eax -$print-int32-decimal:read-loop: - # eax, edx = eax / 10, eax % 10 - 99/sign-extend-eax-into-edx - f7 7/subop/idiv 3/mod/direct 1/rm32/ecx . . . . . . # divide edx:eax by ecx, storing quotient in eax and remainder in edx - # edx += '0' - 81 0/subop/add 3/mod/direct 2/rm32/edx . . . . . 0x30/imm32 # add to edx - # push edx - 52/push-edx - # if (eax == 0) break - 3d/compare-eax-and 0/imm32 - 7f/jump-if-greater $print-int32-decimal:read-loop/disp8 -$print-int32-decimal:read-break: - # if (n < 0) push('-') - 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 0/imm32 # compare *(ebp+12) - 7d/jump-if-greater-or-equal $print-int32-decimal:write/disp8 -$print-int32-decimal:push-negative: - 68/push 0x2d/imm32/- -$print-int32-decimal:write: - # edi = out - 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi - # w/edx = out->write - 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx - # curr/ecx = &out->data[out->write] - 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 1/r32/ecx 0xc/disp8 . # copy ebx+edx+12 to ecx - # max/ebx = &out->data[out->length] - 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 8/disp8 . # copy *(edi+8) to ebx - 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 3/index/ebx . 3/r32/ebx 0xc/disp8 . # copy edi+ebx+12 to ebx -$print-int32-decimal:write-loop: - # pop into eax - 58/pop-to-eax - # if (eax == sentinel) break - 3d/compare-eax-and 0/imm32/sentinel - 74/jump-if-equal $print-int32-decimal:write-break/disp8 - # if (curr >= max) abort - 39/compare 3/mod/direct 1/rm32/ecx . . . 3/r32/ebx . . # compare ecx with ebx - 73/jump-if-greater-or-equal-unsigned $print-int32-decimal:abort/disp8 -$print-int32-decimal:write-char: - # *curr = AL - 88/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy AL to byte at *ecx - # ++curr - 41/increment-ecx - # ++w - 42/increment-edx - eb/jump $print-int32-decimal:write-loop/disp8 -$print-int32-decimal:write-break: - # out->write = w - 89/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy edx to *edi -$print-int32-decimal:end: - # . restore registers - 5f/pop-to-edi - 5b/pop-to-ebx - 5a/pop-to-edx - 59/pop-to-ecx - 58/pop-to-eax - # . epilog - 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 5d/pop-to-ebp - c3/return - -$print-int32-decimal:abort: - # . _write(2/stderr, error) - # . . push args - 68/push "print-int32-decimal: out of space\n"/imm32 - 68/push 2/imm32/stderr - # . . call - e8/call _write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . syscall(exit, 1) - bb/copy-to-ebx 1/imm32 - b8/copy-to-eax 1/imm32/exit - cd/syscall 0x80/imm8 - # never gets here - -test-print-int32-decimal: - # - check that a single-digit number converts correctly - # setup - # . clear-stream(_test-stream) - # . . push args - 68/push _test-stream/imm32 - # . . call - e8/call clear-stream/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # print-int32-decimal(_test-stream, 9) - # . . push args - 68/push 9/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call print-int32-decimal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # check-stream-equal(_test-stream, "9", msg) - # . . push args - 68/push "F - test-print-int32-decimal"/imm32 - 68/push "9"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call check-stream-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # . end - c3/return - -test-print-int32-decimal-zero: - # - check that 0 converts correctly - # setup - # . clear-stream(_test-stream) - # . . push args - 68/push _test-stream/imm32 - # . . call - e8/call clear-stream/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # print-int32-decimal(_test-stream, 0) - # . . push args - 68/push 0/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call print-int32-decimal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # check-stream-equal(_test-stream, "0", msg) - # . . push args - 68/push "F - test-print-int32-decimal-zero"/imm32 - 68/push "0"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call check-stream-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # . end - c3/return - -test-print-int32-decimal-multiple-digits: - # - check that a multi-digit number converts correctly - # setup - # . clear-stream(_test-stream) - # . . push args - 68/push _test-stream/imm32 - # . . call - e8/call clear-stream/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # print-int32-decimal(_test-stream, 10) - # . . push args - 68/push 0xa/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call print-int32-decimal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # check-stream-equal(_test-stream, "10", msg) - # . . push args - 68/push "F - test-print-int32-decimal-multiple-digits"/imm32 - 68/push "10"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call check-stream-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # . end - c3/return - -test-print-int32-decimal-negative: - # - check that a negative single-digit number converts correctly - # setup - # . clear-stream(_test-stream) - # . . push args - 68/push _test-stream/imm32 - # . . call - e8/call clear-stream/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # print-int32-decimal(_test-stream, -9) - # . . push args - 68/push -9/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call print-int32-decimal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -#? # dump _test-stream {{{ -#? # . write(2/stderr, "^") -#? # . . push args -#? 68/push "^"/imm32 -#? 68/push 2/imm32/stderr -#? # . . call -#? e8/call write/disp32 -#? # . . discard args -#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -#? # . write-stream(2/stderr, _test-stream) -#? # . . push args -#? 68/push _test-stream/imm32 -#? 68/push 2/imm32/stderr -#? # . . call -#? e8/call write-stream/disp32 -#? # . . discard args -#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -#? # . write(2/stderr, "$\n") -#? # . . push args -#? 68/push "$\n"/imm32 -#? 68/push 2/imm32/stderr -#? # . . call -#? e8/call write/disp32 -#? # . . discard args -#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -#? # }}} - # check-stream-equal(_test-stream, "-9", msg) - # . . push args - 68/push "F - test-print-int32-decimal-negative"/imm32 - 68/push "-9"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call check-stream-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # . end - c3/return - -test-print-int32-decimal-negative-multiple-digits: - # - check that a multi-digit number converts correctly - # setup - # . clear-stream(_test-stream) - # . . push args - 68/push _test-stream/imm32 - # . . call - e8/call clear-stream/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # print-int32-decimal(_test-stream, -10) - # . . push args - 68/push -0xa/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call print-int32-decimal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # check-stream-equal(_test-stream, "-10", msg) - # . . push args - 68/push "F - test-print-int32-decimal-negative-multiple-digits"/imm32 - 68/push "-10"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call check-stream-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # . end - c3/return - -# . . vim:nowrap:textwidth=0 |