diff options
-rw-r--r-- | 405screen.mu | 13 | ||||
-rw-r--r-- | 406try-divide.mu | 28 | ||||
-rw-r--r-- | 408print-float.mu | 343 |
3 files changed, 379 insertions, 5 deletions
diff --git a/405screen.mu b/405screen.mu index e271bf79..0fd0f4e3 100644 --- a/405screen.mu +++ b/405screen.mu @@ -485,7 +485,18 @@ fn print-int32-decimal screen: (addr screen), n: int { return } # fake screen - # TODO + var s2: (stream byte 0x100) + var s2-addr/esi: (addr stream byte) <- address s2 + write-int32-decimal 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 reset-formatting screen: (addr screen) { diff --git a/406try-divide.mu b/406try-divide.mu index e5034e55..d8588162 100644 --- a/406try-divide.mu +++ b/406try-divide.mu @@ -99,6 +99,34 @@ fn test-try-modulo-negative-nr { check-ints-equal result, 3, "F - test-try-modulo-negative-nr" } +# slow, iterative shift-left instruction +# preconditions: _nr >= 0, _dr > 0 +fn repeated-shift-left nr: int, dr: int -> _/eax: int { + var result/eax: int <- copy nr + { + compare dr, 0 + break-if-<= + result <- shift-left 1 + decrement dr + loop + } + return result +} + +# slow, iterative shift-right instruction +# preconditions: _nr >= 0, _dr > 0 +fn repeated-shift-right nr: int, dr: int -> _/eax: int { + var result/eax: int <- copy nr + { + compare dr, 0 + break-if-<= + result <- shift-right 1 + decrement dr + loop + } + return result +} + fn abs n: int -> _/eax: int { var result/eax: int <- copy n { diff --git a/408print-float.mu b/408print-float.mu index e1c916f6..626a098a 100644 --- a/408print-float.mu +++ b/408print-float.mu @@ -1,4 +1,7 @@ -# quick-n-dirty way to print out floats in hex +# quick-n-dirty way to print out floats + +######## In hex, following C's %a format +# https://www.exploringbinary.com/hexadecimal-floating-point-constants # examples: # 0.5 = 0x3f000000 = 0011| 1111 | 0000 | 0000 | 0000 | 0000 | 0000 | 0000 @@ -24,6 +27,63 @@ fn test-print-float-normal { check-screen-row screen, 1, "1.000000P-01 ", "F - test-print-float-normal" } +fn test-print-float-normal-2 { + 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.25 + var one/eax: int <- copy 1 + var quarter/xmm0: float <- convert one + var four/eax: int <- copy 4 + var four-f/xmm1: float <- convert four + quarter <- divide four-f + print-float screen, quarter + # + check-screen-row screen, 1, "1.000000P-02 ", "F - test-print-float-normal-2" +} + +fn test-print-float-normal-3 { + 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.75 + var three/eax: int <- copy 3 + var three-quarters/xmm0: float <- convert three + var four/eax: int <- copy 4 + var four-f/xmm1: float <- convert four + three-quarters <- divide four-f + print-float screen, three-quarters + # + check-screen-row screen, 1, "1.800000P-01 ", "F - test-print-float-normal-3" +} + +fn test-print-float-normal-4 { + 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.1 + var one/eax: int <- copy 1 + var tenth/xmm0: float <- convert one + var ten/eax: int <- copy 0xa + var ten-f/xmm1: float <- convert ten + tenth <- divide ten-f + print-float screen, tenth + # + check-screen-row screen, 1, "1.99999aP-04 ", "F - test-print-float-normal-4" +} + +fn test-print-float-integer { + 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 1 + var one/eax: int <- copy 1 + var one-f/xmm0: float <- convert one + print-float screen, one-f + # + check-screen-row screen, 1, "1.000000P00 ", "F - test-print-float-integer" +} + fn test-print-float-zero { var screen-on-stack: screen var screen/esi: (addr screen) <- address screen-on-stack @@ -119,7 +179,8 @@ fn print-float screen: (addr screen), n: float { var exponent/ecx: int <- copy bits exponent <- shift-right 0x17 # 23 bits of mantissa exponent <- and 0xff - compare exponent, 0xff + exponent <- subtract 0x7f + compare exponent, 0x80 { break-if-!= print-string screen, "Nan" @@ -135,7 +196,7 @@ fn print-float screen: (addr screen), n: float { } $print-float:leading-digit: { # check for subnormal numbers - compare exponent, 0 + compare exponent, -0x7f { break-if-!= print-string screen, "0." @@ -147,10 +208,10 @@ fn print-float screen: (addr screen), n: float { } var mantissa/ebx: int <- copy bits mantissa <- and 0x7fffff + mantissa <- shift-left 1 # pad to whole nibbles print-int32-hex-bits screen, mantissa, 0x18 # print exponent print-string screen, "P" - exponent <- subtract 0x7f compare exponent, 0 { break-if->= @@ -167,3 +228,277 @@ fn print-float screen: (addr screen), n: float { #? #? test-print-float-normal #? return 0 #? } + +######## In decimal + +fn test-print-float-decimal-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-decimal screen, half + # + check-screen-row screen, 1, "1P-1 ", "F - test-print-float-decimal-normal" +} + +fn test-print-float-decimal-normal-2 { + 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.25 + var one/eax: int <- copy 1 + var quarter/xmm0: float <- convert one + var four/eax: int <- copy 4 + var four-f/xmm1: float <- convert four + quarter <- divide four-f + print-float-decimal screen, quarter + # + check-screen-row screen, 1, "1P-2 ", "F - test-print-float-decimal-normal-2" +} + +fn test-print-float-decimal-normal-3 { + 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.75 + var three/eax: int <- copy 3 + var three-quarters/xmm0: float <- convert three + var four/eax: int <- copy 4 + var four-f/xmm1: float <- convert four + three-quarters <- divide four-f + print-float-decimal screen, three-quarters + # + check-screen-row screen, 1, "3P-2 ", "F - test-print-float-decimal-normal-3" +} + +# print whole integers without decimals +fn test-print-float-decimal-integer { + 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 1 + var one/eax: int <- copy 1 + var one-f/xmm0: float <- convert one + print-float-decimal screen, one-f + # + check-screen-row screen, 1, "1 ", "F - test-print-float-decimal-integer" +} + +fn test-print-float-decimal-integer-2 { + 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 2 + var two/eax: int <- copy 2 + var two-f/xmm0: float <- convert two + print-float-decimal screen, two-f + # + check-screen-row screen, 1, "2 ", "F - test-print-float-decimal-integer-2" +} + +fn test-print-float-decimal-integer-3 { + 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 10 + var ten/eax: int <- copy 0xa + var ten-f/xmm0: float <- convert ten + print-float-decimal screen, ten-f + # + check-screen-row screen, 1, "10 ", "F - test-print-float-decimal-integer-3" +} + +fn test-print-float-decimal-integer-4 { + 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 -10 + var minus-ten/eax: int <- copy -0xa + var minus-ten-f/xmm0: float <- convert minus-ten + print-float-decimal screen, minus-ten-f + # + check-screen-row screen, 1, "-10 ", "F - test-print-float-decimal-integer-4" +} + +fn test-print-float-decimal-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-decimal screen, zero + # + check-screen-row screen, 1, "0 ", "F - test-print-float-decimal-zero" +} + +fn test-print-float-decimal-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-decimal screen, negative-zero + # + check-screen-row screen, 1, "-0 ", "F - test-print-float-decimal-negative-zero" +} + +fn test-print-float-decimal-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-decimal screen, infinity + # + check-screen-row screen, 1, "Inf ", "F - test-print-float-decimal-infinity" +} + +fn test-print-float-decimal-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-decimal screen, negative-infinity + # + check-screen-row screen, 1, "-Inf ", "F - test-print-float-decimal-negative-infinity" +} + +fn test-print-float-decimal-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-decimal screen, negative-infinity + # + check-screen-row screen, 1, "Nan ", "F - test-print-float-decimal-not-a-number" +} + +fn print-float-decimal screen: (addr screen), n: float { + # - special names + var bits/eax: int <- reinterpret n + compare bits, 0 + { + break-if-!= + print-string screen, "0" + return + } + compare bits, 0x80000000 + { + break-if-!= + print-string screen, "-0" + return + } + compare bits, 0x7f800000 + { + break-if-!= + print-string screen, "Inf" + return + } + compare bits, 0xff800000 + { + break-if-!= + print-string screen, "-Inf" + return + } + var exponent/ecx: int <- copy bits + exponent <- shift-right 0x17 # 23 bits of mantissa + exponent <- and 0xff +#? print-string 0, "exponent0: " +#? print-int32-hex 0, exponent +#? print-string 0, "\n" + exponent <- subtract 0x7f + compare exponent, 0x80 + { + break-if-!= + print-string screen, "Nan" + return + } + # - regular numbers + var sign/edx: int <- copy bits + sign <- shift-right 0x1f + { + compare sign, 1 + break-if-!= + print-string screen, "-" + } + var mantissa/ebx: int <- copy bits + mantissa <- and 0x7fffff +#? print-string 0, "mantissa0: " +#? print-int32-hex 0, mantissa +#? print-string 0, "\n" + # whole integers + compare exponent, 0 + { + break-if-< +#? print-string 0, "mantissa: " +#? print-int32-hex 0, mantissa +#? print-string 0, "\n" +#? print-string 0, "exponent: " +#? print-int32-hex 0, exponent +#? print-string 0, "\n" + var tmp/eax: int <- copy mantissa + tmp <- shift-left 9 # move to MSB + tmp <- repeated-shift-left tmp, exponent + compare tmp, 0 + break-if-!= + var result/eax: int <- copy mantissa + result <- or 0x00800000 # insert implicit 1 + result <- repeated-shift-left result, exponent + result <- shift-right 0x17 # 24 bits +#? print-string 0, "result: " +#? print-int32-hex 0, result +#? print-string 0, "\n" + print-int32-decimal screen, result + return + } + $print-float-decimal:leading-digit: { + # check for subnormal numbers + compare exponent, -0x7f + { + break-if-!= + print-string screen, "0" + exponent <- increment + break $print-float-decimal:leading-digit + } + # normal numbers + print-string screen, "1" + } +#? var mantissa/ebx: int <- copy bits +#? mantissa <- and 0x7fffff + compare mantissa, 0 + { + break-if-= + print-string screen, "." + # TODO + mantissa <- shift-left 1 # whole number of nibbles + print-int32-hex-bits screen, mantissa, 0x18 + } + # print exponent if necessary + compare exponent, 0 + break-if-= + print-string screen, "P" + print-int32-decimal screen, exponent +} + +#? fn main -> _/ebx: int { +#? run-tests +#? #? test-print-float-decimal-integer +#? return 0 +#? } |