diff --git a/fix32.tal b/fix32.tal index 75aca42..585eded 100644 --- a/fix32.tal +++ b/fix32.tal @@ -87,6 +87,12 @@ @x32-not-nan ( x/** -> bool^ ) #0000 NEQ2 STH #8000 NEQ2 STHr ORA JMP2r +@x32-not-pos-inf ( x/** -> bool^ ) + #ffff NEQ2 STH #7fff NEQ2 STHr ORA JMP2r + +@x32-not-neg-inf ( x/** -> bool^ ) + #0001 NEQ2 STH #8000 NEQ2 STHr ORA JMP2r + @x32-from-u8 ( x^ -> x/** ) #00 SWP ( >> ) @x32-from-u16 ( x* -> x/** ) @@ -143,9 +149,6 @@ @x32-gteq ( x/** y/** -> bool^ ) x32-prepare-cmp NEQk ?{ POP2 !u32-gteq } GTH STH POP8 STHr JMP2r -( TODO: support saturation at +/- infinity ) -( TODO: support signed operations ) - @x32-add ( x/** y/** -> z/** ) STH4 OVR2 #8000 AND2 ( x** xs* [ylo* yhi*] ) STH2kr #8000 AND2 ( x** xs* ys* [ylo* yhi*] ) @@ -167,6 +170,8 @@ @x32-mul ( x/** y/** -> z/** ) ;x32-mul-unsigned !x32-signed-op +( TODO: support saturation at +/- infinity ) + ( [x*y]/1000 = floor[x/1000] + [[x%1000]*y]/1000 ) @x32-mul-unsigned ( x/** y/** -> z/** ) STH4 DENOM32 u32-divmod ( q=x/1000** r=x%1000** [ylo* yhi*] ) @@ -216,8 +221,24 @@ LIT "a STH2kr JSR2 LIT "n STH2r JMP2 +@x32-draw-pos-inf ( x/** draw-char* -> ) + STH2 POP2 POP2 + LIT "+ STH2kr JSR2 + LIT "i STH2kr JSR2 + LIT "n STH2kr JSR2 + LIT "f STH2r JMP2 + +@x32-draw-neg-inf ( x/** draw-char* -> ) + STH2 POP2 POP2 + LIT "- STH2kr JSR2 + LIT "i STH2kr JSR2 + LIT "n STH2kr JSR2 + LIT "f STH2r JMP2 + @x32-draw ( x/** draw-char* -> ) STH2 DUP4 x32-not-nan ?{ STH2r !x32-draw-nan } + DUP4 x32-not-pos-inf ?{ STH2r !x32-draw-pos-inf } + DUP4 x32-not-neg-inf ?{ STH2r !x32-draw-neg-inf } OVR2 #8000 LTH2 ?{ LIT "- STH2kr JSR2 u32-negate diff --git a/test-fix32.tal b/test-fix32.tal index 0107c58..e68c088 100644 --- a/test-fix32.tal +++ b/test-fix32.tal @@ -22,13 +22,16 @@ #0a18 DEO #0000 #03e8 #0000 #07d0 LIT "+ ;x32-add #0000 #0bb8 test-binop ( 1 + 2 = 3 ) #ffff #fc18 #ffff #fc18 LIT "+ ;x32-add #ffff #f830 test-binop ( -1 + -1 = -2 ) + #6000 #0000 #6000 #0000 LIT "+ ;x32-add #7fff #ffff test-binop ( -1 + -1 = -2 ) #7fff #ffff #7fff #ffff LIT "+ ;x32-add #7fff #ffff test-binop ( inf + inf = inf ) #8000 #0001 #8000 #0001 LIT "+ ;x32-add #8000 #0001 test-binop ( -inf + -inf = -inf ) #0001 #e078 #ffff #a628 LIT "+ ;x32-add #0001 #86a0 test-binop ( 123.0 + -23.0 = 100.0 ) + #5968 #2f00 #5968 #2f00 LIT "+ ;x32-add #7fff #ffff test-binop ( 1.5M + 1.5M = inf ) + #a697 #d100 #a697 #d100 LIT "+ ;x32-add #8000 #0001 test-binop ( -1.5M + -1.5M = -inf ) #0a18 DEO #0000 #03e8 #0000 #03e8 LIT "* ;x32-mul #0000 #03e8 test-binop ( 1 * 1 = 1 ) #0000 #07d0 #0000 #0bb8 LIT "* ;x32-mul #0000 #1770 test-binop ( 2 * 3 = 6 ) - #0000 #4a38 #0000 #6978 LIT "* ;x32-mul #0007 #d3d8 test-binop ( 19 * 27 = 513 ) + #0000 #4a38 #0000 #6978 LIT "* ;x32-mul #0007 #d3e8 test-binop ( 19 * 27 = 513 ) #0000 #0064 #0000 #0064 LIT "* ;x32-mul #0000 #000a test-binop ( 0.1 * 0.1 = 0.01 ) #0000 #01f4 #0000 #0001 LIT "* ;x32-mul #0000 #0000 test-binop ( 0.5 * 0.001 = 0.0 ) #0000 #01f4 #0000 #0003 LIT "* ;x32-mul #0000 #0002 test-binop ( 0.5 * 0.003 = 0.002 ) @@ -37,6 +40,8 @@ #0000 #01f4 #0000 #0009 LIT "* ;x32-mul #0000 #0004 test-binop ( 0.5 * 0.009 = 0.004 ) #0000 #0bb8 #ffff #f830 LIT "* ;x32-mul #ffff #e890 test-binop ( 3 * -2 = -6 ) #ffff #fc18 #ffff #fc18 LIT "* ;x32-mul #0000 #03e8 test-binop ( -1 * -1 = 1 ) + #0100 #0000 #0100 #0000 LIT "* ;x32-mul #7fff #ffff test-binop + #7000 #0000 #7000 #0000 LIT "* ;x32-mul #1234 #5678 test-binop #0a18 DEO #0000 #1d4c #0000 #05dc LIT "/ ;x32-div #0000 #1388 test-binop ( 7.5 / 1.5 = 5.0 ) #0000 #03e8 #0000 #0001 LIT "/ ;x32-div #000f #4240 test-binop ( 1.0 / 0.001 = 1000.0 ) @@ -103,22 +108,22 @@ ~fix32.tal @test-binop ( x** y** op^ f* z** -> x** y** ) - STH2 STH2 ,&f STR2 ,&op STR ( x** y** [z1* z0*] ) - STH2 STH2 OVR2 OVR2 emit/long ( x** [z1* z0* y1* z0*] ; emit x ) - #2018 DEO ( x** [z1* z0* y1* y0*] ; emit space ) - LIT [ &op $1 ] #18 DEO ( x** [z1* z0* y1* y0*] ; emit operator symbol ) - #2018 DEO ( x** [z1* z0* y1* y0*] ; emit space ) - STH2r STH2r OVR2 OVR2 emit/long ( x** y** [z1* z0*] ; emit y ) - #2018 DEO ( x** y** [z1* z0*] ; emit space ) - LIT "= #18 DEO ( x** y** [z1* z0*] ; emit = ) - #2018 DEO ( x** y** [z1* z0*] ; emit space ) - LIT2 [ &f $2 ] JSR2 ( f[x,y]** [z1* z0*] ) - emit/long ( [z1* z0*] ; emit f[x,y] ) - STH2r STH2r #2018 DEO ( z** ; emit space ) - LIT "[ #18 DEO ( z** ; emit [ ) - emit/long ( ; emit z ) - LIT "] #18 DEO ( ; emit ] ) - #0a18 DEO JMP2r ( ; emit newline ) + STH2 STH2 ,&f STR2 ,&op STR ( x** y** [z1* z0*] ) + STH2 STH2 OVR2 OVR2 x32-emit ( x** [z1* z0* y1* z0*] ; emit x ) + #2018 DEO ( x** [z1* z0* y1* y0*] ; emit space ) + LIT [ &op $1 ] #18 DEO ( x** [z1* z0* y1* y0*] ; emit operator symbol ) + #2018 DEO ( x** [z1* z0* y1* y0*] ; emit space ) + STH2r STH2r OVR2 OVR2 x32-emit ( x** y** [z1* z0*] ; emit y ) + #2018 DEO ( x** y** [z1* z0*] ; emit space ) + LIT "= #18 DEO ( x** y** [z1* z0*] ; emit = ) + #2018 DEO ( x** y** [z1* z0*] ; emit space ) + LIT2 [ &f $2 ] JSR2 ( f[x,y]** [z1* z0*] ) + x32-emit ( [z1* z0*] ; emit f[x,y] ) + STH2r STH2r #2018 DEO ( z** ; emit space ) + LIT "[ #18 DEO ( z** ; emit [ ) + x32-emit ( ; emit z ) + LIT "] #18 DEO ( ; emit ] ) + #0a18 DEO JMP2r ( ; emit newline ) @emit &long SWP2 /short