about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-10-04 11:12:23 -0700
committerKartik Agaram <vc@akkartik.com>2020-10-04 11:18:23 -0700
commitb8d613e7c2379b26cd4e989e736c6d389e78a5fe (patch)
tree38a364dad383e2d8e41ff4842c25c87eff56058f
parent0371140abecec1b3902ed58282cfb5ea0fcd2f69 (diff)
downloadmu-b8d613e7c2379b26cd4e989e736c6d389e78a5fe.tar.gz
6946 - print floats somewhat intuitively in hex
-rw-r--r--117write-int-hex.subx132
-rw-r--r--304screen.subx13
-rw-r--r--400.mu3
-rw-r--r--405screen.mu39
-rw-r--r--408print-float.mu171
-rwxr-xr-xapps/assortbin46466 -> 46532 bytes
-rwxr-xr-xapps/bracesbin48521 -> 48587 bytes
-rwxr-xr-xapps/callsbin53372 -> 53438 bytes
-rwxr-xr-xapps/crenshaw2-1bin45807 -> 45873 bytes
-rwxr-xr-xapps/crenshaw2-1bbin46354 -> 46420 bytes
-rwxr-xr-xapps/dquotesbin50088 -> 50154 bytes
-rwxr-xr-xapps/factorialbin44910 -> 44976 bytes
-rwxr-xr-xapps/hexbin48646 -> 48712 bytes
-rwxr-xr-xapps/mubin421479 -> 421605 bytes
-rwxr-xr-xapps/packbin59156 -> 59222 bytes
-rwxr-xr-xapps/sigilsbin60890 -> 60956 bytes
-rwxr-xr-xapps/surveybin56398 -> 56464 bytes
-rwxr-xr-xapps/testsbin45257 -> 45323 bytes
18 files changed, 314 insertions, 44 deletions
diff --git a/117write-int-hex.subx b/117write-int-hex.subx
index 27753e50..445ca2e9 100644
--- a/117write-int-hex.subx
+++ b/117write-int-hex.subx
@@ -176,24 +176,9 @@ test-write-byte-hex-buffered:
     c3/return
 
 write-int32-hex:  # f: (addr stream byte), n: int
-    # pseudocode:
-    #  write(f, "0x")
-    #  ecx = 28
-    #  while true
-    #    if (ecx < 0) break
-    #    eax = n >> ecx
-    #    eax = eax & 0xf
-    #    append-byte(f, AL)
-    #    ecx -= 4
-    #
     # . prologue
     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
-    # ecx = 28
-    b9/copy-to-ecx  0x1c/imm32
 $write-int32-hex:hex-prefix:
     # write(f, "0x")
     # . . push args
@@ -203,11 +188,48 @@ $write-int32-hex:hex-prefix:
     e8/call  write/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-$write-int32-hex:loop:
-    # if (ecx < 0) break
+$write-int32-hex:rest:
+    # write-int32-hex-bits(f, n, 32)
+    # . . push args
+    68/push  0x20/imm32
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+    # . . call
+    e8/call  write-int32-hex-bits/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+$write-int32-hex:end:
+    # . epilogue
+    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+    5d/pop-to-ebp
+    c3/return
+
+# print rightmost 'bits' of 'n'
+# bits must be multiple of 4
+write-int32-hex-bits:  # f: (addr stream byte), n: int, bits: int
+    # pseudocode:
+    #  bits -= 4
+    #  while true
+    #    if (bits < 0) break
+    #    eax = n >> bits
+    #    eax = eax & 0xf
+    #    append-byte(f, AL)
+    #    bits -= 4
+    #
+    # . prologue
+    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
+    # ecx = bits-4
+    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   0x10/disp8      .                 # copy *(ebp+16) to ecx
+    81          5/subop/subtract    3/mod/direct    1/rm32/ecx    .           .             .           .           .               4/imm32           # subtract from ecx
+$write-int32-hex-bits:loop:
+    # if (bits < 0) break
     81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0/imm32           # compare ecx
-    7c/jump-if-<  $write-int32-hex:end/disp8
-    # eax = n >> ecx
+    7c/jump-if-<  $write-int32-hex-bits:end/disp8
+    # eax = n >> bits
     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0xc/disp8       .                 # copy *(ebp+12) to eax
     d3/>>ecx    5/subop/pad-zeroes  3/mod/direct    0/rm32/eax    .           .             .           .           .               .                 # shift eax right by ecx bits, padding zeroes
     # eax = to-hex-char(AL)
@@ -221,10 +243,10 @@ $write-int32-hex:loop:
     e8/call  append-byte/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # ecx -= 4
+    # bits -= 4
     81          5/subop/subtract    3/mod/direct    1/rm32/ecx    .           .             .           .           .               4/imm32           # subtract from ecx
-    eb/jump  $write-int32-hex:loop/disp8
-$write-int32-hex:end:
+    eb/jump  $write-int32-hex-bits:loop/disp8
+$write-int32-hex-bits:end:
     # . restore registers
     59/pop-to-ecx
     58/pop-to-eax
@@ -264,24 +286,9 @@ test-write-int32-hex:
     c3/return
 
 write-int32-hex-buffered:  # f: (addr buffered-file), n: int
-    # pseudocode:
-    #  write-buffered(f, "0x")
-    #  ecx = 28
-    #  while true
-    #    if (ecx < 0) break
-    #    eax = n >> ecx
-    #    eax = eax & 0xf
-    #    write-byte-buffered(f, AL)
-    #    ecx -= 4
-    #
     # . prologue
     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
-    # ecx = 28
-    b9/copy-to-ecx  0x1c/imm32
 $write-int32-hex-buffered:hex-prefix:
     # write-buffered(f, "0x")
     # . . push args
@@ -291,11 +298,48 @@ $write-int32-hex-buffered:hex-prefix:
     e8/call  write-buffered/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-$write-int32-hex-buffered:loop:
-    # if (ecx < 0) break
+$write-int32-hex-buffered:rest:
+    # write-int32-hex-bits-buffered(f, n, 32)
+    # . . push args
+    68/push  0x20/imm32
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+    # . . call
+    e8/call  write-int32-hex-bits-buffered/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+$write-int32-hex-buffered:end:
+    # . epilogue
+    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+    5d/pop-to-ebp
+    c3/return
+
+# print rightmost 'bits' of 'n'
+# bits must be multiple of 4
+write-int32-hex-bits-buffered:  # f: (addr buffered-file), n: int, bits: int
+    # pseudocode:
+    #  bits -= 4
+    #  while true
+    #    if (bits < 0) break
+    #    eax = n >> bits
+    #    eax = eax & 0xf
+    #    write-byte-buffered(f, AL)
+    #    bits -= 4
+    #
+    # . prologue
+    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
+    # ecx = bits-4
+    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   0x10/disp8      .                 # copy *(ebp+16) to ecx
+    81          5/subop/subtract    3/mod/direct    1/rm32/ecx    .           .             .           .           .               4/imm32           # subtract from ecx
+$write-int32-hex-bits-buffered:loop:
+    # if (bits < 0) break
     81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0/imm32           # compare ecx
-    7c/jump-if-<  $write-int32-hex-buffered:end/disp8
-    # eax = n >> ecx
+    7c/jump-if-<  $write-int32-hex-bits-buffered:end/disp8
+    # eax = n >> bits
     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0xc/disp8       .                 # copy *(ebp+12) to eax
     d3/>>ecx    5/subop/pad-zeroes  3/mod/direct    0/rm32/eax    .           .             .           .           .               .                 # shift eax right by ecx bits, padding zeroes
     # eax = to-hex-char(AL)
@@ -309,10 +353,10 @@ $write-int32-hex-buffered:loop:
     e8/call  write-byte-buffered/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # ecx -= 4
+    # bits -= 4
     81          5/subop/subtract    3/mod/direct    1/rm32/ecx    .           .             .           .           .               4/imm32           # subtract from ecx
-    eb/jump  $write-int32-hex-buffered:loop/disp8
-$write-int32-hex-buffered:end:
+    eb/jump  $write-int32-hex-bits-buffered:loop/disp8
+$write-int32-hex-bits-buffered:end:
     # . restore registers
     59/pop-to-ecx
     58/pop-to-eax
diff --git a/304screen.subx b/304screen.subx
index 8ec33fd5..c961492f 100644
--- a/304screen.subx
+++ b/304screen.subx
@@ -236,6 +236,19 @@ $print-int32-hex-to-real-screen:end:
     5d/pop-to-ebp
     c3/return
 
+print-int32-hex-bits-to-real-screen:  # n: int, bits: int
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    #
+    (write-int32-hex-bits-buffered Stdout *(ebp+8) *(ebp+0xc) *(ebp+0x10))
+    (flush Stdout)
+$print-int32-hex-bits-to-real-screen:end:
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
 print-int32-decimal-to-real-screen:  # n: int
     # . prologue
     55/push-ebp
diff --git a/400.mu b/400.mu
index d6fa0b83..9f407565 100644
--- a/400.mu
+++ b/400.mu
@@ -62,7 +62,9 @@ sig write-buffered f: (addr buffered-file), msg: (addr array byte)
 sig append-byte-hex f: (addr stream byte), n: int
 sig write-byte-hex-buffered f: (addr buffered-file), n: int
 sig write-int32-hex f: (addr stream byte), n: int
+sig write-int32-hex-bits f: (addr stream byte), n: int, bits: int
 sig write-int32-hex-buffered f: (addr buffered-file), n: int
+sig write-int32-hex-bits-buffered f: (addr buffered-file), n: int, bits: int
 sig is-hex-int? in: (addr slice) -> result/eax: boolean
 sig parse-hex-int in: (addr array byte) -> result/eax: int
 sig parse-hex-int-from-slice in: (addr slice) -> result/eax: int
@@ -152,6 +154,7 @@ sig print-slice-to-real-screen s: (addr slice)
 sig print-stream-to-real-screen s: (addr stream byte)
 sig print-grapheme-to-real-screen c: grapheme
 sig print-int32-hex-to-real-screen n: int
+sig print-int32-hex-bits-to-real-screen n: int, bits: int
 sig print-int32-decimal-to-real-screen n: int
 sig write-int32-decimal-buffered f: (addr buffered-file), n: int
 sig reset-formatting-on-real-screen
diff --git a/405screen.mu b/405screen.mu
index 62bf1005..ba854e4a 100644
--- a/405screen.mu
+++ b/405screen.mu
@@ -435,6 +435,45 @@ $print-int32-hex:body: {
   {
     break-if-=
     # fake screen
+    var s2: (stream byte 0x100)
+    var s2-addr/esi: (addr stream byte) <- address s2
+    write-int32-hex s2-addr, n
+    var screen-addr/edi: (addr screen) <- copy screen
+    {
+      var done?/eax: boolean <- stream-empty? s2-addr
+      compare done?, 0
+      break-if-!=
+      var g/eax: grapheme <- read-grapheme s2-addr
+      print-grapheme screen, g
+      loop
+    }
+  }
+}
+}
+
+fn print-int32-hex-bits screen: (addr screen), n: int, bits: int {
+$print-int32-hex-bits:body: {
+  compare screen, 0
+  {
+    break-if-!=
+    print-int32-hex-bits-to-real-screen n, bits
+    break $print-int32-hex-bits:body
+  }
+  {
+    break-if-=
+    # fake screen
+    var s2: (stream byte 0x100)
+    var s2-addr/esi: (addr stream byte) <- address s2
+    write-int32-hex-bits s2-addr, n, bits
+    var screen-addr/edi: (addr screen) <- copy screen
+    {
+      var done?/eax: boolean <- stream-empty? s2-addr
+      compare done?, 0
+      break-if-!=
+      var g/eax: grapheme <- read-grapheme s2-addr
+      print-grapheme screen, g
+      loop
+    }
   }
 }
 }
diff --git a/408print-float.mu b/408print-float.mu
new file mode 100644
index 00000000..69dd3da6
--- /dev/null
+++ b/408print-float.mu
@@ -0,0 +1,171 @@
+# quick-n-dirty way to print out floats in hex
+
+# examples:
+#   0.5 = 0x3f000000 = 0011| 1111 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000
+#                    = 0 | 01111110 | 00000000000000000000000
+#                      +   exponent   mantissa
+#                    = 0 | 00000000000000000000000 | 01111110
+#                          mantissa                  exponent
+#                    = 0 | 000000000000000000000000 | 01111110
+#                          zero-pad mantissa          exponent
+#                   =   +1.000000                   e -01
+fn test-print-float-normal {
+  var screen-on-stack: screen
+  var screen/esi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 5, 0x20  # 32 columns should be more than enough
+  # print 0.5
+  var one/eax: int <- copy 1
+  var half/xmm0: float <- convert one
+  var two/eax: int <- copy 2
+  var two-f/xmm1: float <- convert two
+  half <- divide two-f
+  print-float screen, half
+  #
+  check-screen-row screen, 1, "1.000000e-01 ", "F - test-print-float-normal"
+}
+
+fn test-print-float-zero {
+  var screen-on-stack: screen
+  var screen/esi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 5, 0x20  # 32 columns should be more than enough
+  # print 0
+  var zero: float
+  print-float screen, zero
+  #
+  check-screen-row screen, 1, "0 ", "F - test-print-float-zero"
+}
+
+fn test-print-float-negative-zero {
+  var screen-on-stack: screen
+  var screen/esi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 5, 0x20  # 32 columns should be more than enough
+  # print 0
+  var n: int
+  copy-to n, 0x80000000
+  var negative-zero/xmm0: float <- reinterpret n
+  print-float screen, negative-zero
+  #
+  check-screen-row screen, 1, "-0 ", "F - test-print-float-negative-zero"
+}
+
+fn test-print-float-infinity {
+  var screen-on-stack: screen
+  var screen/esi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 5, 0x20  # 32 columns should be more than enough
+  # print
+  var n: int
+  #          0|11111111|00000000000000000000000
+  #          0111|1111|1000|0000|0000|0000|0000|0000
+  copy-to n, 0x7f800000
+  var infinity/xmm0: float <- reinterpret n
+  print-float screen, infinity
+  #
+  check-screen-row screen, 1, "Inf ", "F - test-print-float-infinity"
+}
+
+fn test-print-float-negative-infinity {
+  var screen-on-stack: screen
+  var screen/esi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 5, 0x20  # 32 columns should be more than enough
+  # print
+  var n: int
+  copy-to n, 0xff800000
+  var negative-infinity/xmm0: float <- reinterpret n
+  print-float screen, negative-infinity
+  #
+  check-screen-row screen, 1, "-Inf ", "F - test-print-float-negative-infinity"
+}
+
+fn test-print-float-not-a-number {
+  var screen-on-stack: screen
+  var screen/esi: (addr screen) <- address screen-on-stack
+  initialize-screen screen, 5, 0x20  # 32 columns should be more than enough
+  # print
+  var n: int
+  copy-to n, 0xffffffff  # exponent must be all 1's, and mantissa must be non-zero
+  var negative-infinity/xmm0: float <- reinterpret n
+  print-float screen, negative-infinity
+  #
+  check-screen-row screen, 1, "Nan ", "F - test-print-float-not-a-number"
+}
+
+fn print-float screen: (addr screen), n: float {
+$print-float:body: {
+  # - special names
+  var bits/eax: int <- reinterpret n
+  compare bits, 0
+  {
+    break-if-!=
+    print-string screen, "0"
+    break $print-float:body
+  }
+  compare bits, 0x80000000
+  {
+    break-if-!=
+    print-string screen, "-0"
+    break $print-float:body
+  }
+  compare bits, 0x7f800000
+  {
+    break-if-!=
+    print-string screen, "Inf"
+    break $print-float:body
+  }
+  compare bits, 0xff800000
+  {
+    break-if-!=
+    print-string screen, "-Inf"
+    break $print-float:body
+  }
+  var exponent/ecx: int <- copy bits
+  exponent <- shift-right 0x17  # 23 bits of mantissa
+  exponent <- and 0xff
+  compare exponent, 0xff
+  {
+    break-if-!=
+    print-string screen, "Nan"
+    break $print-float:body
+  }
+  # - regular numbers
+  var sign/edx: int <- copy bits
+  sign <- shift-right 0x1f
+  {
+    compare sign, 1
+    break-if-!=
+    print-string screen, "-"
+  }
+  $print-float:leading-digit: {
+    # check for subnormal numbers
+    compare exponent, 0
+    {
+      break-if-!=
+      print-string screen, "0."
+      exponent <- increment
+      break $print-float:leading-digit
+    }
+    # normal numbers
+    print-string screen, "1."
+  }
+  var mantissa/ebx: int <- copy bits
+  mantissa <- and 0x7fffff
+  print-int32-hex-bits screen, mantissa, 0x18
+  # print exponent
+  print-string screen, "e"
+  exponent <- subtract 0x7f
+  compare exponent, 0
+  {
+    break-if->=
+    print-string screen, "-"
+  }
+  var exp-magnitude/eax: int <- abs exponent
+  print-int32-hex-bits screen, exp-magnitude, 8
+}
+}
+
+#? fn main -> r/ebx: int {
+#?   run-tests
+#? #?   test-print-float-negative-zero
+#? #?   print-int32-hex 0, 0
+#? #?   test-print-float-normal
+#?   r <- copy 0
+#? }
diff --git a/apps/assort b/apps/assort
index 59229721..b96e8bce 100755
--- a/apps/assort
+++ b/apps/assort
Binary files differdiff --git a/apps/braces b/apps/braces
index cb648e0f..658a2906 100755
--- a/apps/braces
+++ b/apps/braces
Binary files differdiff --git a/apps/calls b/apps/calls
index 09382fec..ca22ce03 100755
--- a/apps/calls
+++ b/apps/calls
Binary files differdiff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1
index 68bd7758..0b69e083 100755
--- a/apps/crenshaw2-1
+++ b/apps/crenshaw2-1
Binary files differdiff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b
index 7d81f937..587b2655 100755
--- a/apps/crenshaw2-1b
+++ b/apps/crenshaw2-1b
Binary files differdiff --git a/apps/dquotes b/apps/dquotes
index 81421c0b..71aac388 100755
--- a/apps/dquotes
+++ b/apps/dquotes
Binary files differdiff --git a/apps/factorial b/apps/factorial
index b4f7fff5..c001d2d8 100755
--- a/apps/factorial
+++ b/apps/factorial
Binary files differdiff --git a/apps/hex b/apps/hex
index 62dcf42a..501feb40 100755
--- a/apps/hex
+++ b/apps/hex
Binary files differdiff --git a/apps/mu b/apps/mu
index 6546803e..74d614fc 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/pack b/apps/pack
index 38b33328..79c773fb 100755
--- a/apps/pack
+++ b/apps/pack
Binary files differdiff --git a/apps/sigils b/apps/sigils
index b734f16a..d464f947 100755
--- a/apps/sigils
+++ b/apps/sigils
Binary files differdiff --git a/apps/survey b/apps/survey
index cf95124b..24a7a699 100755
--- a/apps/survey
+++ b/apps/survey
Binary files differdiff --git a/apps/tests b/apps/tests
index 872f64fb..f49cff1a 100755
--- a/apps/tests
+++ b/apps/tests
Binary files differ