From fdd71229944231e92f07ff61660e6cb9279a7e35 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 18 Dec 2009 15:40:00 +0000 Subject: [PATCH] scheme/flonum (v4.2.3.8) svn: r17348 --- collects/compiler/decompile.ss | 26 +- collects/r6rs/private/num-inline.ss | 89 ++- collects/rnrs/arithmetic/fixnums-6.ss | 52 +- collects/rnrs/arithmetic/flonums-6.ss | 86 +- collects/scheme/flonum.ss | 4 + collects/scribblings/guide/performance.scrbl | 45 +- collects/scribblings/mzc/decompile.scrbl | 8 +- collects/scribblings/reference/numbers.scrbl | 49 +- collects/scribblings/reference/unsafe.scrbl | 16 +- .../benchmarks/shootout/mandelbrot-generic.ss | 79 ++ .../benchmarks/shootout/mandelbrot.ss | 42 +- .../benchmarks/shootout/nbody-generic.ss | 157 ++++ .../benchmarks/shootout/nbody-vec-unsafe.ss | 1 + .../mzscheme/benchmarks/shootout/nbody.ss | 57 +- .../mzscheme/benchmarks/shootout/recursive.ss | 11 +- .../shootout/spectralnorm-generic.ss | 58 ++ .../shootout/spectralnorm-unsafe.ss | 1 + .../benchmarks/shootout/spectralnorm.ss | 23 +- collects/tests/mzscheme/optimize.ss | 27 + collects/tests/mzscheme/unsafe.ss | 1 + doc/release-notes/mzscheme/HISTORY.txt | 3 + src/mzscheme/src/cstartup.inc | 738 +++++++++--------- src/mzscheme/src/env.c | 63 +- src/mzscheme/src/eval.c | 102 ++- src/mzscheme/src/jit.c | 600 ++++++++++++-- src/mzscheme/src/module.c | 45 +- src/mzscheme/src/numarith.c | 117 ++- src/mzscheme/src/number.c | 23 + src/mzscheme/src/numcomp.c | 73 +- src/mzscheme/src/read.c | 2 +- src/mzscheme/src/schminc.h | 3 +- src/mzscheme/src/schpriv.h | 12 +- src/mzscheme/src/schvers.h | 4 +- src/mzscheme/src/syntax.c | 2 +- 34 files changed, 1853 insertions(+), 766 deletions(-) create mode 100644 collects/scheme/flonum.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/mandelbrot-generic.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/nbody-generic.ss create mode 100644 collects/tests/mzscheme/benchmarks/shootout/spectralnorm-generic.ss diff --git a/collects/compiler/decompile.ss b/collects/compiler/decompile.ss index 5059b8dfa5..8f650e09a1 100644 --- a/collects/compiler/decompile.ss +++ b/collects/compiler/decompile.ss @@ -14,6 +14,7 @@ (parameterize ([current-namespace ns]) (namespace-require ''#%kernel) (namespace-require ''#%unsafe) + (namespace-require ''#%flonum) (for/list ([l (namespace-mapped-symbols)]) (cons l (with-handlers ([exn:fail? (lambda (x) #f)]) (compile l))))))] @@ -350,16 +351,23 @@ [else #f])) (if (and (symbol? (car a)) (case (length a) - [(2) (memq (car a) '(unsafe-flabs - unsafe-flsqrt - unsafe-fx->fl))] - [(3) (memq (car a) '(unsafe-fl+ unsafe-fl- unsafe-fl* unsafe-fl/ - unsafe-fl< unsafe-fl> - unsafe-fl= - unsafe-fl<= unsafe-fl>= - unsafe-flvector-ref))] + [(2) (memq (car a) '(flabs flsqrt ->fl + unsafe-flabs + unsafe-flsqrt + unsafe-fx->fl))] + [(3) (memq (car a) '(fl+ fl- fl* fl/ + fl< fl> fl<= fl>= fl= + flvector-ref + unsafe-fl+ unsafe-fl- unsafe-fl* unsafe-fl/ + unsafe-fl< unsafe-fl> + unsafe-fl= + unsafe-fl<= unsafe-fl>= + unsafe-flvector-ref + unsafe-f64vector-ref))] - [(4) (memq (car a) '(unsafe-flvector-set!))] + [(4) (memq (car a) '(flvector-set! + unsafe-flvector-set! + unsafe-f64vector-set!))] [else #f]) (andmap unboxable? args (cdr a))) (cons '#%flonum a) diff --git a/collects/r6rs/private/num-inline.ss b/collects/r6rs/private/num-inline.ss index c1b1c7b1fd..12b3e50179 100644 --- a/collects/r6rs/private/num-inline.ss +++ b/collects/r6rs/private/num-inline.ss @@ -19,37 +19,42 @@ (define-syntax-rule (define-inliner define-fx numtype? numtype-str) (... (begin - (define-syntax define-an-fx - (syntax-rules () - [(_ orig fx check-result ([(arg ...) (tmp ...)] ...) . rest) - (begin - (provide fx) - (define fx-proc - (let ([fx (case-lambda - [(arg ...) - (unless (numtype? arg) - (raise-type-error 'fx numtype-str arg)) - ... - (let ([r (orig arg ...)]) - (check-result r (implementation-restriction 'fx r)))] - ... - . rest)]) - fx)) - (define-syntax fx - (inline-rules - fx-proc - [(_ arg ...) - (let ([tmp arg] ...) - (if (and (numtype? tmp) ...) - (let ([v (orig tmp ...)]) - (check-result v (fx-proc tmp ...))) - (fx-proc tmp ...)))] - ...)))])) + (define-syntax (define-an-fx stx) + (syntax-case stx () + [(_ orig fx binary-op check-result ([(arg ...) (tmp ...)] ...) . rest) + (with-syntax ([(extra-clauses ...) + (if (syntax-e #'binary-op) + #'([(_ arg1 arg2) (binary-op arg1 arg2)]) + #'())]) + #'(begin + (provide fx) + (define fx-proc + (let ([fx (case-lambda + [(arg ...) + (unless (numtype? arg) + (raise-type-error 'fx numtype-str arg)) + ... + (let ([r (orig arg ...)]) + (check-result r (implementation-restriction 'fx r)))] + ... + . rest)]) + fx)) + (define-syntax fx + (inline-rules + fx-proc + extra-clauses ... + [(_ arg ...) + (let ([tmp arg] ...) + (if (and (numtype? tmp) ...) + (let ([v (orig tmp ...)]) + (check-result v (fx-proc tmp ...))) + (fx-proc tmp ...)))] + ...))))])) (define-syntax define-an-fx+rest (syntax-rules () - [(_ orig fx check clauses) - (define-an-fx orig fx check clauses + [(_ orig fx binary-op check clauses) + (define-an-fx orig fx binary-op check clauses [args (for-each (lambda (arg) (unless (numtype? arg) (raise-type-error 'fx numtype-str arg))) @@ -61,28 +66,28 @@ (define-syntax define-fx (syntax-rules (...) - [(_ orig fx [(a) (b c)] check) - (define-an-fx orig fx check + [(_ orig fx binary-op [(a) (b c)] check) + (define-an-fx orig fx binary-op check ([(a) (t1)] [(b c) (t1 t2)]))] - [(_ orig fx [(a) (b c (... ...))] check) - (define-an-fx+rest orig fx check + [(_ orig fx binary-op [(a) (b c (... ...))] check) + (define-an-fx+rest orig fx binary-op check ([(a) (t1)] [(b c) (t1 t2)]))] - [(_ orig fx (a b c (... ...)) check) - (define-an-fx+rest orig fx check + [(_ orig fx binary-op (a b c (... ...)) check) + (define-an-fx+rest orig fx binary-op check ([(a b) (t1 t2)]))] - [(_ orig fx (a b (... ...)) check) - (define-an-fx+rest orig fx check + [(_ orig fx binary-op (a b (... ...)) check) + (define-an-fx+rest orig fx binary-op check ([(a) (t1)] [(a b) (t1 t2)] [(a b c) (t1 t2 t3)]))] - [(_ orig fx (a) check) - (define-an-fx+rest orig fx check + [(_ orig fx binary-op (a) check) + (define-an-fx+rest orig fx binary-op check ([(a) (t1)]))] - [(_ orig fx (a b) check) - (define-an-fx orig fx check + [(_ orig fx binary-op (a b) check) + (define-an-fx orig fx binary-op check ([(a b) (t1 t2)]))] - [(_ orig fx (a b c) check) - (define-an-fx orig fx check + [(_ orig fx binary-op (a b c) check) + (define-an-fx orig fx binary-op check ([(a b c) (t1 t2 t3)]))]))))) diff --git a/collects/rnrs/arithmetic/fixnums-6.ss b/collects/rnrs/arithmetic/fixnums-6.ss index e9ba199a4a..1f1b161087 100644 --- a/collects/rnrs/arithmetic/fixnums-6.ss +++ b/collects/rnrs/arithmetic/fixnums-6.ss @@ -36,24 +36,24 @@ (define-inliner define-fx fixnum? "fixnum") -(define-fx = fx=? (a b c ...) nocheck) -(define-fx > fx>? (a b c ...) nocheck) -(define-fx < fx= fx>=? (a b c ...) nocheck) +(define-fx = fx=? #f (a b c ...) nocheck) +(define-fx > fx>? #f (a b c ...) nocheck) +(define-fx < fx= fx>=? #f (a b c ...) nocheck) -(define-fx zero? fxzero? (a) nocheck) -(define-fx positive? fxpositive? (a) nocheck) -(define-fx negative? fxnegative? (a) nocheck) -(define-fx odd? fxodd? (a) nocheck) -(define-fx even? fxeven? (a) nocheck) +(define-fx zero? fxzero? #f (a) nocheck) +(define-fx positive? fxpositive? #f (a) nocheck) +(define-fx negative? fxnegative? #f (a) nocheck) +(define-fx odd? fxodd? #f (a) nocheck) +(define-fx even? fxeven? #f (a) nocheck) -(define-fx max fxmax (a b ...) nocheck) -(define-fx min fxmin (a b ...) nocheck) +(define-fx max fxmax #f (a b ...) nocheck) +(define-fx min fxmin #f (a b ...) nocheck) -(define-fx + fx+ (a b) check) -(define-fx * fx* (a b) check) -(define-fx - fx- [(a) (a b)] check) +(define-fx + fx+ #f (a b) check) +(define-fx * fx* #f (a b) check) +(define-fx - fx- #f [(a) (a b)] check) (provide fxdiv-and-mod fxdiv0-and-mod0) @@ -65,8 +65,8 @@ (let-values ([(d m) (div-and-mod a b)]) (check d (implementation-restriction 'div-and-mod d)) (values d m))) -(define-fx div fxdiv (a b) check) -(define-fx mod fxmod (a b) nocheck) +(define-fx div fxdiv #f (a b) check) +(define-fx mod fxmod #f (a b) nocheck) (define (fxdiv0-and-mod0 a b) (unless (fixnum? a) (raise-type-error 'fxdiv0-and-mod0 "fixnum" a)) @@ -75,8 +75,8 @@ (let-values ([(d m) (div0-and-mod0 a b)]) (check d (implementation-restriction 'div0-and-mod0 d)) (values d m))) -(define-fx div0 fxdiv0 (a b) check) -(define-fx mod0 fxmod0 (a b) nocheck) +(define-fx div0 fxdiv0 #f (a b) check) +(define-fx mod0 fxmod0 #f (a b) nocheck) (define-syntax-rule (define-carry fx/carry (a b c) expr) (begin @@ -96,18 +96,18 @@ (define-carry fx-/carry (a b c) (- a b c)) (define-carry fx*/carry (a b c) (+ (* a b) c)) -(define-fx bitwise-not fxnot (a) nocheck) -(define-fx bitwise-and fxand (a b ...) nocheck) -(define-fx bitwise-ior fxior (a b ...) nocheck) -(define-fx bitwise-xor fxxor (a b ...) nocheck) +(define-fx bitwise-not fxnot #f (a) nocheck) +(define-fx bitwise-and fxand #f (a b ...) nocheck) +(define-fx bitwise-ior fxior #f (a b ...) nocheck) +(define-fx bitwise-xor fxxor #f (a b ...) nocheck) (define-syntax-rule (fixnum-bitwise-if a b c) (bitwise-ior (bitwise-and a b) (bitwise-and (bitwise-not a) c))) -(define-fx fixnum-bitwise-if fxif (a b c) nocheck) +(define-fx fixnum-bitwise-if fxif #f (a b c) nocheck) -(define-fx bitwise-length fxlength (a) nocheck) -(define-fx bitwise-first-bit-set fxfirst-bit-set (a) nocheck) +(define-fx bitwise-length fxlength #f (a) nocheck) +(define-fx bitwise-first-bit-set fxfirst-bit-set #f (a) nocheck) (define positive-fixnum-width-bounds (string-append "exact integer in [0, " (number->string (- (fixnum-width) 1)) "]")) diff --git a/collects/rnrs/arithmetic/flonums-6.ss b/collects/rnrs/arithmetic/flonums-6.ss index 4d5ca26dfc..051c30b5c2 100644 --- a/collects/rnrs/arithmetic/flonums-6.ss +++ b/collects/rnrs/arithmetic/flonums-6.ss @@ -5,17 +5,17 @@ div0-and-mod0 div0 mod0 [integer? r6rs:integer?] finite? infinite? nan?) + (prefix-in core: scheme/flonum) (only-in rnrs/arithmetic/fixnums-6 fixnum?) rnrs/conditions-6 - r6rs/private/num-inline - (for-syntax r6rs/private/inline-rules)) + r6rs/private/num-inline) (provide (rename-out [inexact-real? flonum?]) real->flonum flnumerator fldenominator - fllog flsqrt flexpt + fllog (rename-out [core:flsqrt flsqrt]) flexpt &no-infinities make-no-infinities-violation no-infinities-violation? &no-nans make-no-nans-violation no-nans-violation? fixnum->flonum) @@ -23,31 +23,31 @@ (define-inliner define-fl inexact-real? "flonum") -(define-fl = fl=? (a b c ...) nocheck) -(define-fl > fl>? (a b c ...) nocheck) -(define-fl < fl= fl>=? (a b c ...) nocheck) +(define-fl = fl=? core:fl= (a b c ...) nocheck) +(define-fl > fl>? core:fl> (a b c ...) nocheck) +(define-fl < fl= fl>=? core:fl>= (a b c ...) nocheck) -(define-fl integer? flinteger? (a) nocheck) -(define-fl zero? flzero? (a) nocheck) -(define-fl positive? flpositive? (a) nocheck) -(define-fl negative? flnegative? (a) nocheck) -(define-fl odd? flodd? (a) nocheck) -(define-fl even? fleven? (a) nocheck) -(define-fl finite? flfinite? (a) nocheck) -(define-fl infinite? flinfinite? (a) nocheck) -(define-fl nan? flnan? (a) nocheck) +(define-fl integer? flinteger? #f (a) nocheck) +(define-fl zero? flzero? #f (a) nocheck) +(define-fl positive? flpositive? #f (a) nocheck) +(define-fl negative? flnegative? #f (a) nocheck) +(define-fl odd? flodd? #f (a) nocheck) +(define-fl even? fleven? #f (a) nocheck) +(define-fl finite? flfinite? #f (a) nocheck) +(define-fl infinite? flinfinite? #f (a) nocheck) +(define-fl nan? flnan? #f (a) nocheck) -(define-fl max flmax (a b ...) nocheck) -(define-fl min flmin (a b ...) nocheck) +(define-fl max flmax #f (a b ...) nocheck) +(define-fl min flmin #f (a b ...) nocheck) -(define-fl + fl+ (a b ...) nocheck) -(define-fl * fl* (a b ...) nocheck) -(define-fl - fl- [(a) (a b ...)] nocheck) -(define-fl / fl/ [(a) (a b ...)] nocheck) +(define-fl + fl+ core:fl+ (a b ...) nocheck) +(define-fl * fl* core:fl* (a b ...) nocheck) +(define-fl - fl- core:fl- [(a) (a b ...)] nocheck) +(define-fl / fl/ core:fl/ [(a) (a b ...)] nocheck) -(define-fl abs flabs (a) nocheck) +(define-fl abs flabs core:flabs (a) nocheck) (provide fldiv-and-mod fldiv0-and-mod0) @@ -57,16 +57,16 @@ (unless (inexact-real? b) (raise-type-error 'fldiv-and-mod "flonum" b)) (div-and-mod a b)) -(define-fl div fldiv (a b) nocheck) -(define-fl mod flmod (a b) nocheck) +(define-fl div fldiv #f (a b) nocheck) +(define-fl mod flmod #f (a b) nocheck) (define (fldiv0-and-mod0 a b) (unless (inexact-real? a) (raise-type-error 'fldiv0-and-mod0 "flonum" a)) (unless (inexact-real? b) (raise-type-error 'fldiv0-and-mod0 "flonum" b)) (div0-and-mod0 a b)) -(define-fl div0 fldiv0 (a b) nocheck) -(define-fl mod0 flmod0 (a b) nocheck) +(define-fl div0 fldiv0 #f (a b) nocheck) +(define-fl mod0 flmod0 #f (a b) nocheck) (define (flnumerator c) (if (inexact-real? c) @@ -83,12 +83,12 @@ 1.0) (raise-type-error 'fldenominator "flonum" c))) -(define-fl floor flfloor (a) nocheck) -(define-fl ceiling flceiling (a) nocheck) -(define-fl truncate fltruncate (a) nocheck) -(define-fl round flround (a) nocheck) +(define-fl floor flfloor #f (a) nocheck) +(define-fl ceiling flceiling #f (a) nocheck) +(define-fl truncate fltruncate #f (a) nocheck) +(define-fl round flround #f (a) nocheck) -(define-fl exp flexp (a) nocheck) +(define-fl exp flexp #f (a) nocheck) (define fllog (case-lambda @@ -102,20 +102,12 @@ [(v1 v2) (/ (fllog v1) (fllog v2))])) -(define-fl sin flsin (a) nocheck) -(define-fl cos flcos (a) nocheck) -(define-fl tan fltan (a) nocheck) -(define-fl asin flasin (a) nocheck) -(define-fl acos flacos (a) nocheck) -(define-fl atan flatan [(a) (a b)] nocheck) - -(define (flsqrt v) - (unless (inexact-real? v) - (raise-type-error 'flsqrt "flonum" v)) - (let ([v (sqrt v)]) - (if (inexact-real? v) - v - +nan.0))) +(define-fl sin flsin #f (a) nocheck) +(define-fl cos flcos #f (a) nocheck) +(define-fl tan fltan #f (a) nocheck) +(define-fl asin flasin #f (a) nocheck) +(define-fl acos flacos #f (a) nocheck) +(define-fl atan flatan #f [(a) (a b)] nocheck) (define (flexpt a b) (unless (inexact-real? a) diff --git a/collects/scheme/flonum.ss b/collects/scheme/flonum.ss new file mode 100644 index 0000000000..0f46a08446 --- /dev/null +++ b/collects/scheme/flonum.ss @@ -0,0 +1,4 @@ +#lang scheme/base +(require '#%flonum) + +(provide (all-from-out '#%flonum)) diff --git a/collects/scribblings/guide/performance.scrbl b/collects/scribblings/guide/performance.scrbl index 6adecb9fa6..46ba7ec801 100644 --- a/collects/scribblings/guide/performance.scrbl +++ b/collects/scribblings/guide/performance.scrbl @@ -1,7 +1,7 @@ #lang scribble/doc @(require scribble/manual "guide-utils.ss" - (for-label scheme/unsafe/ops)) + (for-label scheme/flonum scheme/unsafe/ops)) @title[#:tag "performance"]{Performance} @@ -257,30 +257,35 @@ arguments, such as @scheme[+], inlining works for two or more arguments (except for @scheme[-], whose one-argument case is also inlined) when the arguments are either all fixnums or all flonums. -Flonums are @defterm{boxed}, which means that memory is allocated to -hold every result of a flonum computation. Fortunately, the -generational garbage collector (described later in @secref["gc-perf"]) -makes allocation for short-lived results reasonably cheap. Fixnums, in -contrast are never boxed, so they are especially cheap to use. +Flonums are typically @defterm{boxed}, which means that memory is +allocated to hold every result of a flonum computation. Fortunately, +the generational garbage collector (described later in +@secref["gc-perf"]) makes allocation for short-lived results +reasonably cheap. Fixnums, in contrast are never boxed, so they are +typically cheap to use. -The @schememodname[scheme/unsafe/ops] library provides fixnum- and -flonum-specific operations, and combinations of unchecked flonum -operations allow the @tech{JIT} compiler to generate code that avoids -boxing and unboxing intermediate results. Expressions involving a -combination of unchecked flonum operations, @scheme[unsafe-fx->fl], -constants, and variable references are optimized to avoid boxing. When -such a result is bound with @scheme[let] and then consumed by another -unchecked flonum operation, the result is similarly unboxed. Finally, -the compiler can detect some flonum-valued loop accumulators. The -bytecode decompiler (see @secref[#:doc '(lib -"scribblings/mzc/mzc.scrbl") "decompile"] annotates combinations where -the JIT can avoid boxes with @schemeidfont{#%flonum}, -@schemeidfont{#%as-flonum}, and @schemeidfont{#%from-flonum}. See also -@secref["unchecked-unsafe"], especially the warnings about unsafety. +The @schememodname[scheme/flonum] library provides flonum-specific +operations, and combinations of flonum operations allow the @tech{JIT} +compiler to generate code that avoids boxing and unboxing intermediate +results. Besides results within immediate combinations, +flonum-specific results that are bound with @scheme[let] and consumed +by a later flonum-specific operation are unboxed within temporary +storage. Finally, the compiler can detect some flonum-valued loop +accumulators and avoid boxing of the accumulator. The bytecode +decompiler (see @secref[#:doc '(lib "scribblings/mzc/mzc.scrbl") +"decompile"]) annotates combinations where the JIT can avoid boxes with +@schemeidfont{#%flonum}, @schemeidfont{#%as-flonum}, and +@schemeidfont{#%from-flonum}. @margin-note{Unboxing of local bindings and accumualtors is not supported by the JIT for PowerPC.} +The @schememodname[scheme/unsafe/ops] library provides unchecked +fixnum- and flonum-specific operations. Unchecked flonum-specific +operations allow unboxing, and sometimes they allow the compiler to +reorder expressions to improve performance. See also +@secref["unchecked-unsafe"], especially the warnings about unsafety. + @; ---------------------------------------------------------------------- @section[#:tag "unchecked-unsafe"]{Unchecked, Unsafe Operations} diff --git a/collects/scribblings/mzc/decompile.scrbl b/collects/scribblings/mzc/decompile.scrbl index 2c6f6b482f..0cdcd6b2fa 100644 --- a/collects/scribblings/mzc/decompile.scrbl +++ b/collects/scribblings/mzc/decompile.scrbl @@ -81,11 +81,11 @@ Many forms in the decompiled code, such as @scheme[module], inline the operation. (Inlining information is not part of the bytecode, but is instead based on an enumeration of primitives that the JIT is known to handle specially.) Operations from - @schememodname[scheme/unsafe/ops] are always inlined, so - @schemeidfont{#%in} is not shown for them.} + @schememodname[scheme/flonum] and @schememodname[scheme/unsafe/ops] + are always inlined, so @schemeidfont{#%in} is not shown for them.} - @item{Some applications of unsafe flonum operations from - @schememodname[scheme/unsafe/ops] are annotated with + @item{Some applications of flonum operations from @schememodname[scheme/flonum] + and @schememodname[scheme/unsafe/ops] are annotated with @schemeidfont{#%flonum}, indicating a place where the JIT compiler might avoid allocation for intermediate flonum results. A single @schemeidfont{#%flonum} by itself is not useful, but a diff --git a/collects/scribblings/reference/numbers.scrbl b/collects/scribblings/reference/numbers.scrbl index 9426b51eb1..972ec64b73 100644 --- a/collects/scribblings/reference/numbers.scrbl +++ b/collects/scribblings/reference/numbers.scrbl @@ -1,7 +1,8 @@ #lang scribble/doc @(require "mz.ss" scheme/math - (for-label scheme/math)) + (for-label scheme/math + scheme/flonum)) @(define math-eval (make-base-eval)) @(interaction-eval #:eval math-eval (require scheme/math)) @@ -850,7 +851,51 @@ for the machine running Scheme, @scheme[#f] if the native encoding is little-endian.} @; ------------------------------------------------------------------------ -@section{Inexact-Real Vectors} +@section{Inexact-Real (Flonum) Operations} + +@defmodule[scheme/flonum] + +The @schememodname[scheme/flonum] library provides operations like +@scheme[fl+] that consume and produce only real @tech{inexact +numbers}, which are also known as @deftech{flonums}. Flonum-specific +operations provide can better performance when used consistently, and +they are as safe as generic operations like @scheme[+]. + +@margin-note{See @guidesecref["fixnums+flonums"].} + +@subsection{Flonum Arithmetic} + +@deftogether[( +@defproc[(fl+ [a inexact-real?][b inexact-real?]) inexact-real?] +@defproc[(fl- [a inexact-real?][b inexact-real?]) inexact-real?] +@defproc[(fl* [a inexact-real?][b inexact-real?]) inexact-real?] +@defproc[(fl/ [a inexact-real?][b inexact-real?]) inexact-real?] +@defproc[(flabs [a inexact-real?]) inexact-real?] +@defproc[(flsqrt [a inexact-real?]) inexact-real?] +)]{ + +Like @scheme[+], @scheme[-], @scheme[*], @scheme[/], @scheme[abs], and +@scheme[sqrt], but constrained to consume @tech{flonums}. The result +is always a @tech{flonum}. If a negative number is provided to +@scheme[sqrt], the result is @scheme[+nan.0].} + +@deftogether[( +@defproc[(fl= [a inexact-real?][b inexact-real?]) boolean?] +@defproc[(fl< [a inexact-real?][b inexact-real?]) boolean?] +@defproc[(fl> [a inexact-real?][b inexact-real?]) boolean?] +@defproc[(fl<= [a inexact-real?][b inexact-real?]) boolean?] +@defproc[(fl>= [a inexact-real?][b inexact-real?]) boolean?] +)]{ + +Like @scheme[=], @scheme[<], @scheme[>], @scheme[<=], and @scheme[>=], +but constrained to consume @tech{flonums}.} + +@defproc[(->fl [a exact-integer?]) inexact-real?]{ +Like @scheme[exact->inexact], but constrained to consume exact integers, +so the result is always a @tech{flonum}. +} + +@subsection{Flonum Vectors} A @deftech{flvector} is like a @tech{vector}, but it holds only inexact real numbers. This representation can be more compact, and diff --git a/collects/scribblings/reference/unsafe.scrbl b/collects/scribblings/reference/unsafe.scrbl index 84ca7e5b42..3a6877f57a 100644 --- a/collects/scribblings/reference/unsafe.scrbl +++ b/collects/scribblings/reference/unsafe.scrbl @@ -1,6 +1,7 @@ #lang scribble/doc @(require "mz.ss" (for-label scheme/unsafe/ops + scheme/flonum (only-in scheme/foreign f64vector? f64vector-ref @@ -85,7 +86,7 @@ For @tech{fixnums}: Like @scheme[=], @scheme[<], @scheme[>], @defproc[(unsafe-fx->fl [a fixnum?]) inexact-real?]{ -Like @scheme[exact->inexact], but constrained to consume @tech{fixnums}. +Unchecked version of @scheme[->fl]. } @@ -98,11 +99,8 @@ Like @scheme[exact->inexact], but constrained to consume @tech{fixnums}. @defproc[(unsafe-flsqrt [a inexact-real?]) inexact-real?] )]{ -For real @tech{inexact numbers}: Like @scheme[+], @scheme[-], -@scheme[*], @scheme[/], and @scheme[abs], but constrained to consume -real @tech{inexact numbers}. The result is always a real @tech{inexact -number}. If a negative number is provided to @scheme[unsafe-sqrt], the -result is @scheme[+nan.0].} +For @tech{flonums}: Unchecked versions of @scheme[fl+], @scheme[fl-], +@scheme[fl*], @scheme[fl/], @scheme[flabs], and @scheme[flsqrt].} @deftogether[( @@ -113,9 +111,9 @@ result is @scheme[+nan.0].} @defproc[(unsafe-fl>= [a inexact-real?][b inexact-real?]) boolean?] )]{ -For real @tech{inexact numbers}: Like @scheme[=], @scheme[<], -@scheme[>], @scheme[<=], and @scheme[>=], but constrained to consume -real @tech{inexact numbers}.} +For @tech{flonums}: Unchecked versions of @scheme[fl=], +@scheme[fl<], @scheme[fl>], @scheme[fl<=], and @scheme[fl>=], but constrained +to consume @tech{flonums}.} @section{Unsafe Data Extraction} diff --git a/collects/tests/mzscheme/benchmarks/shootout/mandelbrot-generic.ss b/collects/tests/mzscheme/benchmarks/shootout/mandelbrot-generic.ss new file mode 100644 index 0000000000..37b3526660 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/mandelbrot-generic.ss @@ -0,0 +1,79 @@ +;; --------------------------------------------------------------------- +;; The Great Computer Language Shootout +;; http://shootout.alioth.debian.org/ +;; +;; Derived from the Chicken variant, which was +;; Contributed by Anthony Borla + +;; The version that uses complex number is a little +;; more elegant, but much slower: +;; (define (mandelbrot iterations x y n ci) +;; (let ((c (+ (- (/ (* 2.0 x) n) 1.5) +;; (* ci 0.0+1.0i)))) +;; (let loop ((i 0) (z 0.0+0.0i)) +;; (cond +;; [(> i iterations) 1] +;; [(> (magnitude z) 2.0) 0] +;; [else (loop (add1 i) (+ (* z z) c))])))) + +#lang scheme/base +(require scheme/cmdline) + +(define +limit-sqr+ 4.0) + +(define +iterations+ 50) + +;; ------------------------------- + +(define (mandelbrot iterations x y n ci) + (let ((cr (- (/ (* 2.0 x) n) 1.5))) + (let loop ((i 0) (zr 0.0) (zi 0.0)) + (if (> i iterations) + 1 + (let ((zrq (* zr zr)) + (ziq (* zi zi))) + (cond + ((> (+ zrq ziq) +limit-sqr+) 0) + (else (loop (add1 i) + (+ (- zrq ziq) cr) + (+ (* 2.0 zr zi) ci))))))))) + +;; ------------------------------- + +(define (main n) + (let ((out (current-output-port))) + + (fprintf out "P4\n~a ~a\n" n n) + + (let loop-y ((y 0)) + + (when (< y n) + + (let ([ci (- (/ (* 2.0 y) n) 1.0)]) + + (let loop-x ((x 0) (bitnum 0) (byteacc 0)) + + (if (< x n) + (let ([bitnum (add1 bitnum)] + [byteacc (+ (arithmetic-shift byteacc 1) + (mandelbrot +iterations+ x y n ci))]) + + (cond + ((= bitnum 8) + (write-byte byteacc out) + (loop-x (add1 x) 0 0)) + + [else (loop-x (add1 x) bitnum byteacc)])) + + (begin + (when (positive? bitnum) + (write-byte (arithmetic-shift byteacc + (- 8 (bitwise-and n #x7))) + out)) + + (loop-y (add1 y)))))))))) + +;; ------------------------------- + +(command-line #:args (n) + (main (string->number n))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/mandelbrot.ss b/collects/tests/mzscheme/benchmarks/shootout/mandelbrot.ss index 37b3526660..866f69b707 100644 --- a/collects/tests/mzscheme/benchmarks/shootout/mandelbrot.ss +++ b/collects/tests/mzscheme/benchmarks/shootout/mandelbrot.ss @@ -4,20 +4,10 @@ ;; ;; Derived from the Chicken variant, which was ;; Contributed by Anthony Borla - -;; The version that uses complex number is a little -;; more elegant, but much slower: -;; (define (mandelbrot iterations x y n ci) -;; (let ((c (+ (- (/ (* 2.0 x) n) 1.5) -;; (* ci 0.0+1.0i)))) -;; (let loop ((i 0) (z 0.0+0.0i)) -;; (cond -;; [(> i iterations) 1] -;; [(> (magnitude z) 2.0) 0] -;; [else (loop (add1 i) (+ (* z z) c))])))) #lang scheme/base -(require scheme/cmdline) +(require scheme/cmdline + scheme/flonum) (define +limit-sqr+ 4.0) @@ -25,18 +15,16 @@ ;; ------------------------------- -(define (mandelbrot iterations x y n ci) - (let ((cr (- (/ (* 2.0 x) n) 1.5))) +(define (mandelbrot x y n ci) + (let ((cr (fl- (fl/ (fl* 2.0 (->fl x)) (->fl n)) 1.5))) (let loop ((i 0) (zr 0.0) (zi 0.0)) - (if (> i iterations) + (if (> i +iterations+) 1 - (let ((zrq (* zr zr)) - (ziq (* zi zi))) - (cond - ((> (+ zrq ziq) +limit-sqr+) 0) - (else (loop (add1 i) - (+ (- zrq ziq) cr) - (+ (* 2.0 zr zi) ci))))))))) + (cond + ((fl> (fl+ (fl* zr zr) (fl* zi zi)) +limit-sqr+) 0) + (else (loop (+ 1 i) + (fl+ (fl- (fl* zr zr) (fl* zi zi)) cr) + (fl+ (fl* 2.0 (fl* zr zi)) ci)))))))) ;; ------------------------------- @@ -49,21 +37,21 @@ (when (< y n) - (let ([ci (- (/ (* 2.0 y) n) 1.0)]) + (let ([ci (fl- (fl/ (fl* 2.0 (->fl y)) (->fl n)) 1.0)]) (let loop-x ((x 0) (bitnum 0) (byteacc 0)) (if (< x n) - (let ([bitnum (add1 bitnum)] + (let ([bitnum (+ 1 bitnum)] [byteacc (+ (arithmetic-shift byteacc 1) - (mandelbrot +iterations+ x y n ci))]) + (mandelbrot x y n ci))]) (cond ((= bitnum 8) (write-byte byteacc out) - (loop-x (add1 x) 0 0)) + (loop-x (+ 1 x) 0 0)) - [else (loop-x (add1 x) bitnum byteacc)])) + [else (loop-x (+ 1 x) bitnum byteacc)])) (begin (when (positive? bitnum) diff --git a/collects/tests/mzscheme/benchmarks/shootout/nbody-generic.ss b/collects/tests/mzscheme/benchmarks/shootout/nbody-generic.ss new file mode 100644 index 0000000000..3311cc344e --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/nbody-generic.ss @@ -0,0 +1,157 @@ +#!/usr/bin/mzscheme -qu +;; The Computer Language Benchmarks Game +;; http://shootout.alioth.debian.org/ +;; +;; Imperative-style implementation based on the SBCL implementation by +;; Patrick Frankenberger and Juho Snellman, but using only native Scheme +;; idioms like 'named let' and 'do' special form. +;; +;; Contributed by Anthony Borla, then converted for mzscheme +;; by Matthew Flatt and Brent Fulgham + +#| +Correct output N = 1000 is + +-0.169075164 +-0.169087605 +|# + +#lang scheme/base +(require scheme/cmdline) + +;; ------------------------------ +;; define planetary masses, initial positions & velocity + +(define +pi+ 3.141592653589793) +(define +days-per-year+ 365.24) + +(define +solar-mass+ (* 4 +pi+ +pi+)) + +(define +dt+ 0.01) + +(define-struct body (x y z vx vy vz mass) + #:mutable) + +(define *sun* + (make-body 0.0 0.0 0.0 0.0 0.0 0.0 +solar-mass+)) + +(define *jupiter* + (make-body 4.84143144246472090 + -1.16032004402742839 + -1.03622044471123109e-1 + (* 1.66007664274403694e-3 +days-per-year+) + (* 7.69901118419740425e-3 +days-per-year+) + (* -6.90460016972063023e-5 +days-per-year+) + (* 9.54791938424326609e-4 +solar-mass+))) + +(define *saturn* + (make-body 8.34336671824457987 + 4.12479856412430479 + -4.03523417114321381e-1 + (* -2.76742510726862411e-3 +days-per-year+) + (* 4.99852801234917238e-3 +days-per-year+) + (* 2.30417297573763929e-5 +days-per-year+) + (* 2.85885980666130812e-4 +solar-mass+))) + +(define *uranus* + (make-body 1.28943695621391310e1 + -1.51111514016986312e1 + -2.23307578892655734e-1 + (* 2.96460137564761618e-03 +days-per-year+) + (* 2.37847173959480950e-03 +days-per-year+) + (* -2.96589568540237556e-05 +days-per-year+) + (* 4.36624404335156298e-05 +solar-mass+))) + +(define *neptune* + (make-body 1.53796971148509165e+01 + -2.59193146099879641e+01 + 1.79258772950371181e-01 + (* 2.68067772490389322e-03 +days-per-year+) + (* 1.62824170038242295e-03 +days-per-year+) + (* -9.51592254519715870e-05 +days-per-year+) + (* 5.15138902046611451e-05 +solar-mass+))) + +(define *system* (list *sun* *jupiter* *saturn* *uranus* *neptune*)) + +;; ------------------------------- +(define (offset-momentum) + (let loop-i ([i *system*] [px 0.0] [py 0.0] [pz 0.0]) + (if (null? i) + (begin + (set-body-vx! (car *system*) (/ (- px) +solar-mass+)) + (set-body-vy! (car *system*) (/ (- py) +solar-mass+)) + (set-body-vz! (car *system*) (/ (- pz) +solar-mass+))) + (let ([i1 (car i)]) + (loop-i (cdr i) + (+ px (* (body-vx i1) (body-mass i1))) + (+ py (* (body-vy i1) (body-mass i1))) + (+ pz (* (body-vz i1) (body-mass i1)))))))) + +;; ------------------------------- +(define (energy) + (let loop-o ([o *system*] [e 0.0]) + (if (null? o) + e + (let* ([o1 (car o)] + [e (+ e (* 0.5 + (body-mass o1) + (+ (* (body-vx o1) (body-vx o1)) + (* (body-vy o1) (body-vy o1)) + (* (body-vz o1) (body-vz o1)))))]) + (let loop-i ([i (cdr o)] [e e]) + (if (null? i) + (loop-o (cdr o) e) + (let* ([i1 (car i)] + [dx (- (body-x o1) (body-x i1))] + [dy (- (body-y o1) (body-y i1))] + [dz (- (body-z o1) (body-z i1))] + [dist (sqrt (+ (* dx dx) (* dy dy) (* dz dz)))] + [e (- e (/ (* (body-mass o1) (body-mass i1)) dist))]) + (loop-i (cdr i) e)))))))) + +;; ------------------------------- +(define (advance) + (let loop-o ([o *system*]) + (when (pair? o) + (let* ([o1 (car o)] + [o1x (body-x o1)] + [o1y (body-y o1)] + [o1z (body-z o1)] + [om (body-mass o1)]) + (let loop-i ([i (cdr o)] + [vx (body-vx o1)] + [vy (body-vy o1)] + [vz (body-vz o1)]) + (if (pair? i) + (let* ([i1 (car i)] + [dx (- o1x (body-x i1))] + [dy (- o1y (body-y i1))] + [dz (- o1z (body-z i1))] + [dist2 (+ (* dx dx) (* dy dy) (* dz dz))] + [mag (/ +dt+ (* dist2 (sqrt dist2)))] + [dxmag (* dx mag)] + [dymag (* dy mag)] + [dzmag (* dz mag)] + [im (body-mass i1)]) + (set-body-vx! i1 (+ (body-vx i1) (* dxmag om))) + (set-body-vy! i1 (+ (body-vy i1) (* dymag om))) + (set-body-vz! i1 (+ (body-vz i1) (* dzmag om))) + (loop-i (cdr i) + (- vx (* dxmag im)) + (- vy (* dymag im)) + (- vz (* dzmag im)))) + (begin (set-body-vx! o1 vx) + (set-body-vy! o1 vy) + (set-body-vz! o1 vz) + (set-body-x! o1 (+ o1x (* +dt+ vx))) + (set-body-y! o1 (+ o1y (* +dt+ vy))) + (set-body-z! o1 (+ o1z (* +dt+ vz))))))) + (loop-o (cdr o))))) + +;; ------------------------------- + +(let ([n (command-line #:args (n) (string->number n))]) + (offset-momentum) + (printf "~a\n" (real->decimal-string (energy) 9)) + (for ([i (in-range n)]) (advance)) + (printf "~a\n" (real->decimal-string (energy) 9))) diff --git a/collects/tests/mzscheme/benchmarks/shootout/nbody-vec-unsafe.ss b/collects/tests/mzscheme/benchmarks/shootout/nbody-vec-unsafe.ss index fac48a2690..0b7a40daa3 100644 --- a/collects/tests/mzscheme/benchmarks/shootout/nbody-vec-unsafe.ss +++ b/collects/tests/mzscheme/benchmarks/shootout/nbody-vec-unsafe.ss @@ -18,6 +18,7 @@ Correct output N = 1000 is #lang scheme/base (require scheme/cmdline scheme/require + (only-in scheme/flonum flvector) (for-syntax scheme/base) (filtered-in (lambda (name) diff --git a/collects/tests/mzscheme/benchmarks/shootout/nbody.ss b/collects/tests/mzscheme/benchmarks/shootout/nbody.ss index 3311cc344e..00d98461b2 100644 --- a/collects/tests/mzscheme/benchmarks/shootout/nbody.ss +++ b/collects/tests/mzscheme/benchmarks/shootout/nbody.ss @@ -17,7 +17,8 @@ Correct output N = 1000 is |# #lang scheme/base -(require scheme/cmdline) +(require scheme/cmdline + scheme/flonum) ;; ------------------------------ ;; define planetary masses, initial positions & velocity @@ -93,20 +94,20 @@ Correct output N = 1000 is (if (null? o) e (let* ([o1 (car o)] - [e (+ e (* 0.5 - (body-mass o1) - (+ (* (body-vx o1) (body-vx o1)) - (* (body-vy o1) (body-vy o1)) - (* (body-vz o1) (body-vz o1)))))]) + [e (+ e (fl* 0.5 + (fl* (body-mass o1) + (fl+ (fl+ (fl* (body-vx o1) (body-vx o1)) + (fl* (body-vy o1) (body-vy o1))) + (fl* (body-vz o1) (body-vz o1))))))]) (let loop-i ([i (cdr o)] [e e]) (if (null? i) (loop-o (cdr o) e) (let* ([i1 (car i)] - [dx (- (body-x o1) (body-x i1))] - [dy (- (body-y o1) (body-y i1))] - [dz (- (body-z o1) (body-z i1))] - [dist (sqrt (+ (* dx dx) (* dy dy) (* dz dz)))] - [e (- e (/ (* (body-mass o1) (body-mass i1)) dist))]) + [dx (fl- (body-x o1) (body-x i1))] + [dy (fl- (body-y o1) (body-y i1))] + [dz (fl- (body-z o1) (body-z i1))] + [dist (flsqrt (fl+ (fl+ (fl* dx dx) (fl* dy dy)) (fl* dz dz)))] + [e (fl- e (fl/ (fl* (body-mass o1) (body-mass i1)) dist))]) (loop-i (cdr i) e)))))))) ;; ------------------------------- @@ -124,28 +125,28 @@ Correct output N = 1000 is [vz (body-vz o1)]) (if (pair? i) (let* ([i1 (car i)] - [dx (- o1x (body-x i1))] - [dy (- o1y (body-y i1))] - [dz (- o1z (body-z i1))] - [dist2 (+ (* dx dx) (* dy dy) (* dz dz))] - [mag (/ +dt+ (* dist2 (sqrt dist2)))] - [dxmag (* dx mag)] - [dymag (* dy mag)] - [dzmag (* dz mag)] + [dx (fl- o1x (body-x i1))] + [dy (fl- o1y (body-y i1))] + [dz (fl- o1z (body-z i1))] + [dist2 (fl+ (fl+ (fl* dx dx) (fl* dy dy)) (fl* dz dz))] + [mag (fl/ +dt+ (fl* dist2 (flsqrt dist2)))] + [dxmag (fl* dx mag)] + [dymag (fl* dy mag)] + [dzmag (fl* dz mag)] [im (body-mass i1)]) - (set-body-vx! i1 (+ (body-vx i1) (* dxmag om))) - (set-body-vy! i1 (+ (body-vy i1) (* dymag om))) - (set-body-vz! i1 (+ (body-vz i1) (* dzmag om))) + (set-body-vx! i1 (fl+ (body-vx i1) (fl* dxmag om))) + (set-body-vy! i1 (fl+ (body-vy i1) (fl* dymag om))) + (set-body-vz! i1 (fl+ (body-vz i1) (fl* dzmag om))) (loop-i (cdr i) - (- vx (* dxmag im)) - (- vy (* dymag im)) - (- vz (* dzmag im)))) + (fl- vx (fl* dxmag im)) + (fl- vy (fl* dymag im)) + (fl- vz (fl* dzmag im)))) (begin (set-body-vx! o1 vx) (set-body-vy! o1 vy) (set-body-vz! o1 vz) - (set-body-x! o1 (+ o1x (* +dt+ vx))) - (set-body-y! o1 (+ o1y (* +dt+ vy))) - (set-body-z! o1 (+ o1z (* +dt+ vz))))))) + (set-body-x! o1 (fl+ o1x (fl* +dt+ vx))) + (set-body-y! o1 (fl+ o1y (fl* +dt+ vy))) + (set-body-z! o1 (fl+ o1z (fl* +dt+ vz))))))) (loop-o (cdr o))))) ;; ------------------------------- diff --git a/collects/tests/mzscheme/benchmarks/shootout/recursive.ss b/collects/tests/mzscheme/benchmarks/shootout/recursive.ss index 96e7cdef44..dd6785034b 100644 --- a/collects/tests/mzscheme/benchmarks/shootout/recursive.ss +++ b/collects/tests/mzscheme/benchmarks/shootout/recursive.ss @@ -9,7 +9,8 @@ ;; --------------------------------------------------------------------- #lang scheme/base -(require scheme/cmdline) +(require scheme/cmdline + scheme/flonum) ;; ------------------------------- @@ -25,8 +26,8 @@ (else (+ (fib (- n 2)) (fib (- n 1)))))) (define (fibflt n) - (cond ((< n 2.0) 1.0) - (else (+ (fibflt (- n 2.0)) (fibflt (- n 1.0)))))) + (cond ((fl< n 2.0) 1.0) + (else (fl+ (fibflt (fl- n 2.0)) (fibflt (fl- n 1.0)))))) ;; -------------- @@ -35,8 +36,8 @@ (else (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y))))) (define (takflt x y z) - (cond ((not (< y x)) z) - (else (takflt (takflt (- x 1.0) y z) (takflt (- y 1.0) z x) (takflt (- z 1.0) x y))))) + (cond ((not (fl< y x)) z) + (else (takflt (takflt (fl- x 1.0) y z) (takflt (fl- y 1.0) z x) (takflt (fl- z 1.0) x y))))) ;; ------------------------------- diff --git a/collects/tests/mzscheme/benchmarks/shootout/spectralnorm-generic.ss b/collects/tests/mzscheme/benchmarks/shootout/spectralnorm-generic.ss new file mode 100644 index 0000000000..fd348b0ec7 --- /dev/null +++ b/collects/tests/mzscheme/benchmarks/shootout/spectralnorm-generic.ss @@ -0,0 +1,58 @@ +;; The Great Computer Language Shootout +;; http://shootout.alioth.debian.org/ + +;; Translated directly from the C# version, which was: +;; contributed by Isaac Gouy + +#lang scheme/base +(require scheme/cmdline) + +(define (Approximate n) + (let ([u (make-vector n 1.0)] + [v (make-vector n 0.0)]) + ;; 20 steps of the power method + (for ([i (in-range 10)]) + (MultiplyAtAv n u v) + (MultiplyAtAv n v u)) + + ;; B=AtA A multiplied by A transposed + ;; v.Bv /(v.v) eigenvalue of v + (let loop ([i 0][vBv 0][vv 0]) + (if (= i n) + (sqrt (/ vBv vv)) + (let ([vi (vector-ref v i)]) + (loop (add1 i) + (+ vBv (* (vector-ref u i) vi)) + (+ vv (* vi vi)))))))) + +;; return element i,j of infinite matrix A +(define (A i j) + (/ 1.0 (+ (* (+ i j) (/ (+ i (+ j 1)) 2.0)) (+ i 1)))) + +;; multiply vector v by matrix A +(define (MultiplyAv n v Av) + (for ([i (in-range n)]) + (vector-set! Av i + (for/fold ([r 0]) + ([j (in-range n)]) + (+ r (* (A i j) (vector-ref v j))))))) + +;; multiply vector v by matrix A transposed +(define (MultiplyAtv n v Atv) + (for ([i (in-range n)]) + (vector-set! Atv i + (for/fold ([r 0]) + ([j (in-range n)]) + (+ r (* (A j i) (vector-ref v j))))))) + +;; multiply vector v by matrix A and then by matrix A transposed +(define (MultiplyAtAv n v AtAv) + (let ([u (make-vector n 0.0)]) + (MultiplyAv n v u) + (MultiplyAtv n u AtAv))) + +(printf "~a\n" + (real->decimal-string + (Approximate (command-line #:args (n) (string->number n))) + 9)) + diff --git a/collects/tests/mzscheme/benchmarks/shootout/spectralnorm-unsafe.ss b/collects/tests/mzscheme/benchmarks/shootout/spectralnorm-unsafe.ss index 6e558fdeea..ac7325e151 100644 --- a/collects/tests/mzscheme/benchmarks/shootout/spectralnorm-unsafe.ss +++ b/collects/tests/mzscheme/benchmarks/shootout/spectralnorm-unsafe.ss @@ -6,6 +6,7 @@ #lang scheme/base (require scheme/cmdline + scheme/flonum scheme/unsafe/ops) (define (Approximate n) diff --git a/collects/tests/mzscheme/benchmarks/shootout/spectralnorm.ss b/collects/tests/mzscheme/benchmarks/shootout/spectralnorm.ss index fd348b0ec7..acb2e0bcf7 100644 --- a/collects/tests/mzscheme/benchmarks/shootout/spectralnorm.ss +++ b/collects/tests/mzscheme/benchmarks/shootout/spectralnorm.ss @@ -5,7 +5,8 @@ ;; contributed by Isaac Gouy #lang scheme/base -(require scheme/cmdline) +(require scheme/cmdline + scheme/flonum) (define (Approximate n) (let ([u (make-vector n 1.0)] @@ -17,33 +18,35 @@ ;; B=AtA A multiplied by A transposed ;; v.Bv /(v.v) eigenvalue of v - (let loop ([i 0][vBv 0][vv 0]) + (let loop ([i 0][vBv 0.0][vv 0.0]) (if (= i n) - (sqrt (/ vBv vv)) + (flsqrt (fl/ vBv vv)) (let ([vi (vector-ref v i)]) (loop (add1 i) - (+ vBv (* (vector-ref u i) vi)) - (+ vv (* vi vi)))))))) + (fl+ vBv (fl* (vector-ref u i) vi)) + (fl+ vv (fl* vi vi)))))))) ;; return element i,j of infinite matrix A (define (A i j) - (/ 1.0 (+ (* (+ i j) (/ (+ i (+ j 1)) 2.0)) (+ i 1)))) + (fl/ 1.0 (fl+ (fl* (->fl (+ i j)) + (fl/ (->fl (+ i (+ j 1))) 2.0)) + (->fl (+ i 1))))) ;; multiply vector v by matrix A (define (MultiplyAv n v Av) (for ([i (in-range n)]) (vector-set! Av i - (for/fold ([r 0]) + (for/fold ([r 0.0]) ([j (in-range n)]) - (+ r (* (A i j) (vector-ref v j))))))) + (fl+ r (fl* (A i j) (vector-ref v j))))))) ;; multiply vector v by matrix A transposed (define (MultiplyAtv n v Atv) (for ([i (in-range n)]) (vector-set! Atv i - (for/fold ([r 0]) + (for/fold ([r 0.0]) ([j (in-range n)]) - (+ r (* (A j i) (vector-ref v j))))))) + (fl+ r (fl* (A j i) (vector-ref v j))))))) ;; multiply vector v by matrix A and then by matrix A transposed (define (MultiplyAtAv n v AtAv) diff --git a/collects/tests/mzscheme/optimize.ss b/collects/tests/mzscheme/optimize.ss index 79e0a6bccf..ec6a92b2c1 100644 --- a/collects/tests/mzscheme/optimize.ss +++ b/collects/tests/mzscheme/optimize.ss @@ -3,11 +3,14 @@ (Section 'optimization) +(require scheme/flonum) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check JIT inlining of primitives: (parameterize ([current-namespace (make-base-namespace)] [eval-jit-enabled #t]) + (namespace-require 'scheme/flonum) (let* ([check-error-message (lambda (name proc) (unless (memq name '(eq? not null? pair? real? number? boolean? @@ -215,6 +218,9 @@ (tri-if #t '< (lambda () 1) 2 3 void) (tri-if #f '< (lambda () 1) 3 3 void) (tri-if #f '< (lambda () 1) -1 3 void) + (bin-exact #t 'fl< 100.0 200.0) + (bin-exact #f 'fl< 200.0 100.0) + (bin-exact #f 'fl< 200.0 200.0) (bin #t '<= 100 200) (bin #f '<= 200 100) @@ -224,6 +230,9 @@ (tri-if #t '<= (lambda () 1) 2 3 void) (tri-if #t '<= (lambda () 1) 3 3 void) (tri-if #f '<= (lambda () 1) -1 3 void) + (bin-exact #t 'fl<= 100.0 200.0) + (bin-exact #f 'fl<= 200.0 100.0) + (bin-exact #t 'fl<= 200.0 200.0) (bin #f '> 100 200) (bin #t '> 200 100) @@ -234,6 +243,9 @@ (tri-if #t '> (lambda () 3) 2 1 void) (tri-if #f '> (lambda () 3) 3 1 void) (tri-if #f '> (lambda () 3) -1 1 void) + (bin-exact #f 'fl> 100.0 200.0) + (bin-exact #t 'fl> 200.0 100.0) + (bin-exact #f 'fl> 200.0 200.0) (bin #f '>= 100 200) (bin #t '>= 200 100) @@ -243,6 +255,9 @@ (tri-if #t '>= (lambda () 3) 2 1 void) (tri-if #t '>= (lambda () 3) 3 1 void) (tri-if #f '>= (lambda () 3) -1 1 void) + (bin-exact #f 'fl>= 100.0 200.0) + (bin-exact #t 'fl>= 200.0 100.0) + (bin-exact #t 'fl>= 200.0 200.0) (bin #f '= 100 200) (bin #f '= 200 100) @@ -253,6 +268,8 @@ (tri-if #f '= (lambda () 3) 3 1 void) (tri-if #f '= (lambda () 3) 1 3 void) (tri-if #f '= (lambda () 1) 3 3 void) + (bin-exact #f 'fl= 100.0 200.0) + (bin-exact #t 'fl= 200.0 200.0) (un 3 'add1 2) (un -3 'add1 -4) @@ -276,6 +293,10 @@ (un (expt 2 30) 'abs (- (expt 2 30))) (un (sub1 (expt 2 62)) 'abs (sub1 (expt 2 62))) (un (expt 2 62) 'abs (- (expt 2 62))) + (un-exact 3.0 'flabs -3.0) + + (un-exact 3.0 'flsqrt 9.0) + (un-exact +nan.0 'flsqrt -9.0) (un 1.0 'exact->inexact 1) (un 1073741823.0 'exact->inexact (sub1 (expt 2 30))) @@ -283,12 +304,15 @@ (un 4611686018427387903.0 'exact->inexact (sub1 (expt 2 62))) (un -4611686018427387904.0 'exact->inexact (- (expt 2 62))) + (un-exact 10.0 '->fl 10) + (bin 11 '+ 4 7) (bin -3 '+ 4 -7) (bin (expt 2 30) '+ (expt 2 29) (expt 2 29)) (bin (- (expt 2 31) 2) '+ (sub1 (expt 2 30)) (sub1 (expt 2 30))) (tri 6 '+ (lambda () 1) 2 3 void) (tri 13/2 '+ (lambda () 1) 5/2 3 void) + (bin-exact 3.4 'fl+ 1.1 2.3) (bin 3 '- 7 4) (bin 11 '- 7 -4) @@ -298,6 +322,7 @@ (bin (- 2 (expt 2 31)) '- (- 1 (expt 2 30)) (sub1 (expt 2 30))) (tri 6 '- (lambda () 10) 3 1 void) (tri 13/2 '- (lambda () 10) 3 1/2 void) + (bin-exact -0.75 'fl- 1.5 2.25) (bin 4 '* 1 4) (bin 0 '* 0 4) @@ -311,6 +336,7 @@ (bin (- (expt 2 30)) '* 2 (- (expt 2 29))) (tri 30 '* (lambda () 2) 3 5 void) (tri 5 '* (lambda () 2) 3 5/6 void) + (bin-exact 2.53 'fl* 1.1 2.3) (bin 0 '/ 0 4) (bin 1/4 '/ 1 4) @@ -321,6 +347,7 @@ (bin 4 '/ -16 -4) (tri 3 '/ (lambda () 30) 5 2 void) (tri 12 '/ (lambda () 30) 5 1/2 void) + (bin-exact (/ 1.1 2.3) 'fl/ 1.1 2.3) (bin-int 3 'quotient 10 3) (bin-int -3 'quotient 10 -3) diff --git a/collects/tests/mzscheme/unsafe.ss b/collects/tests/mzscheme/unsafe.ss index 00c98c371f..bf26096f5c 100644 --- a/collects/tests/mzscheme/unsafe.ss +++ b/collects/tests/mzscheme/unsafe.ss @@ -4,6 +4,7 @@ (Section 'unsafe) (require scheme/unsafe/ops + scheme/flonum scheme/foreign) (let () diff --git a/doc/release-notes/mzscheme/HISTORY.txt b/doc/release-notes/mzscheme/HISTORY.txt index a57468b829..2787cbd016 100644 --- a/doc/release-notes/mzscheme/HISTORY.txt +++ b/doc/release-notes/mzscheme/HISTORY.txt @@ -1,3 +1,6 @@ +Version 4.2.3.8 +Added scheme/flonum; moved flvector operations to scheme/flonum + Version 4.2.3.6 Changed JIT to support unboxed local binding of known-flonum arguments to unsafe-fl functions diff --git a/src/mzscheme/src/cstartup.inc b/src/mzscheme/src/cstartup.inc index a757dff6a2..422aaa86c8 100644 --- a/src/mzscheme/src/cstartup.inc +++ b/src/mzscheme/src/cstartup.inc @@ -1,77 +1,77 @@ { - static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,52,46,50,46,51,46,55,50,0,0,0,1,0,0,3,0,12,0, -19,0,23,0,28,0,31,0,36,0,43,0,50,0,63,0,67,0,72,0,78, + static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,52,46,50,46,51,46,56,50,0,0,0,1,0,0,3,0,12,0, +16,0,23,0,26,0,39,0,44,0,51,0,56,0,61,0,68,0,72,0,78, 0,92,0,106,0,109,0,115,0,119,0,121,0,132,0,134,0,148,0,155,0, 177,0,179,0,193,0,4,1,33,1,44,1,55,1,65,1,101,1,134,1,167, 1,226,1,36,2,114,2,180,2,185,2,205,2,96,3,116,3,167,3,233,3, 118,4,4,5,56,5,79,5,158,5,0,0,105,7,0,0,29,11,11,68,104, -101,114,101,45,115,116,120,66,100,101,102,105,110,101,63,97,110,100,64,108,101, -116,42,62,111,114,64,99,111,110,100,66,108,101,116,114,101,99,66,117,110,108, -101,115,115,72,112,97,114,97,109,101,116,101,114,105,122,101,63,108,101,116,64, -119,104,101,110,65,113,117,111,116,101,29,94,2,13,68,35,37,107,101,114,110, +101,114,101,45,115,116,120,63,108,101,116,66,100,101,102,105,110,101,62,111,114, +72,112,97,114,97,109,101,116,101,114,105,122,101,64,108,101,116,42,66,117,110, +108,101,115,115,64,99,111,110,100,64,119,104,101,110,66,108,101,116,114,101,99, +63,97,110,100,65,113,117,111,116,101,29,94,2,13,68,35,37,107,101,114,110, 101,108,11,29,94,2,13,68,35,37,112,97,114,97,109,122,11,62,105,102,65, 98,101,103,105,110,63,115,116,120,61,115,70,108,101,116,45,118,97,108,117,101, 115,61,120,73,108,101,116,114,101,99,45,118,97,108,117,101,115,66,108,97,109, 98,100,97,1,20,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110, 45,107,101,121,61,118,73,100,101,102,105,110,101,45,118,97,108,117,101,115,97, 35,11,8,240,121,78,0,0,95,159,2,15,35,35,159,2,14,35,35,159,2, -14,35,35,16,20,2,3,2,1,2,6,2,1,2,4,2,1,2,5,2,1, -2,8,2,1,2,7,2,1,2,10,2,1,2,9,2,1,2,11,2,1,2, +14,35,35,16,20,2,3,2,1,2,4,2,1,2,11,2,1,2,5,2,1, +2,7,2,1,2,8,2,1,2,9,2,1,2,10,2,1,2,6,2,1,2, 12,2,1,97,36,11,8,240,121,78,0,0,93,159,2,14,35,36,16,2,2, 2,161,2,1,36,2,2,2,1,2,2,96,11,11,8,240,121,78,0,0,16, 0,96,37,11,8,240,121,78,0,0,16,0,13,16,4,35,29,11,11,2,1, 11,18,16,2,99,64,104,101,114,101,8,31,8,30,8,29,8,28,8,27,93, -8,224,128,78,0,0,95,9,8,224,128,78,0,0,2,1,27,248,22,143,4, -195,249,22,136,4,80,158,38,35,251,22,77,2,16,248,22,92,199,12,249,22, -67,2,17,248,22,94,201,27,248,22,143,4,195,249,22,136,4,80,158,38,35, +8,224,128,78,0,0,95,9,8,224,128,78,0,0,2,1,27,248,22,137,4, +195,249,22,130,4,80,158,38,35,251,22,77,2,16,248,22,92,199,12,249,22, +67,2,17,248,22,94,201,27,248,22,137,4,195,249,22,130,4,80,158,38,35, 251,22,77,2,16,248,22,92,199,249,22,67,2,17,248,22,94,201,12,27,248, -22,69,248,22,143,4,196,28,248,22,75,193,20,15,159,36,35,36,28,248,22, -75,248,22,69,194,248,22,68,193,249,22,136,4,80,158,38,35,251,22,77,2, -16,248,22,68,199,249,22,67,2,4,248,22,69,201,11,18,16,2,101,10,8, +22,69,248,22,137,4,196,28,248,22,75,193,20,15,159,36,35,36,28,248,22, +75,248,22,69,194,248,22,68,193,249,22,130,4,80,158,38,35,251,22,77,2, +16,248,22,68,199,249,22,67,2,12,248,22,69,201,11,18,16,2,101,10,8, 31,8,30,8,29,8,28,8,27,16,4,11,11,2,18,3,1,8,101,110,118, 49,50,55,53,50,16,4,11,11,2,19,3,1,8,101,110,118,49,50,55,53, 51,93,8,224,129,78,0,0,95,9,8,224,129,78,0,0,2,1,27,248,22, -69,248,22,143,4,196,28,248,22,75,193,20,15,159,36,35,36,28,248,22,75, -248,22,69,194,248,22,68,193,249,22,136,4,80,158,38,35,250,22,77,2,20, +69,248,22,137,4,196,28,248,22,75,193,20,15,159,36,35,36,28,248,22,75, +248,22,69,194,248,22,68,193,249,22,130,4,80,158,38,35,250,22,77,2,20, 248,22,77,249,22,77,248,22,77,2,21,248,22,68,201,251,22,77,2,16,2, -21,2,21,249,22,67,2,6,248,22,69,204,18,16,2,101,11,8,31,8,30, +21,2,21,249,22,67,2,5,248,22,69,204,18,16,2,101,11,8,31,8,30, 8,29,8,28,8,27,16,4,11,11,2,18,3,1,8,101,110,118,49,50,55, 53,53,16,4,11,11,2,19,3,1,8,101,110,118,49,50,55,53,54,93,8, -224,130,78,0,0,95,9,8,224,130,78,0,0,2,1,248,22,143,4,193,27, -248,22,143,4,194,249,22,67,248,22,77,248,22,68,196,248,22,69,195,27,248, -22,69,248,22,143,4,23,197,1,249,22,136,4,80,158,38,35,28,248,22,53, -248,22,137,4,248,22,68,23,198,2,27,249,22,2,32,0,89,162,8,44,36, -42,9,222,33,39,248,22,143,4,248,22,92,23,200,2,250,22,77,2,22,248, +224,130,78,0,0,95,9,8,224,130,78,0,0,2,1,248,22,137,4,193,27, +248,22,137,4,194,249,22,67,248,22,77,248,22,68,196,248,22,69,195,27,248, +22,69,248,22,137,4,23,197,1,249,22,130,4,80,158,38,35,28,248,22,53, +248,22,131,4,248,22,68,23,198,2,27,249,22,2,32,0,89,162,8,44,36, +42,9,222,33,39,248,22,137,4,248,22,92,23,200,2,250,22,77,2,22,248, 22,77,249,22,77,248,22,77,248,22,68,23,204,2,250,22,78,2,23,249,22, 2,22,68,23,204,2,248,22,94,23,206,2,249,22,67,248,22,68,23,202,1, 249,22,2,22,92,23,200,1,250,22,78,2,20,249,22,2,32,0,89,162,8, -44,36,46,9,222,33,40,248,22,143,4,248,22,68,201,248,22,69,198,27,248, -22,143,4,194,249,22,67,248,22,77,248,22,68,196,248,22,69,195,27,248,22, -69,248,22,143,4,23,197,1,249,22,136,4,80,158,38,35,250,22,78,2,22, -249,22,2,32,0,89,162,8,44,36,46,9,222,33,42,248,22,143,4,248,22, -68,201,248,22,69,198,27,248,22,69,248,22,143,4,196,27,248,22,143,4,248, -22,68,195,249,22,136,4,80,158,39,35,28,248,22,75,195,250,22,78,2,20, -9,248,22,69,199,250,22,77,2,11,248,22,77,248,22,68,199,250,22,78,2, -5,248,22,69,201,248,22,69,202,27,248,22,69,248,22,143,4,23,197,1,27, -249,22,1,22,81,249,22,2,22,143,4,248,22,143,4,248,22,68,199,249,22, -136,4,80,158,39,35,251,22,77,1,22,119,105,116,104,45,99,111,110,116,105, +44,36,46,9,222,33,40,248,22,137,4,248,22,68,201,248,22,69,198,27,248, +22,137,4,194,249,22,67,248,22,77,248,22,68,196,248,22,69,195,27,248,22, +69,248,22,137,4,23,197,1,249,22,130,4,80,158,38,35,250,22,78,2,22, +249,22,2,32,0,89,162,8,44,36,46,9,222,33,42,248,22,137,4,248,22, +68,201,248,22,69,198,27,248,22,69,248,22,137,4,196,27,248,22,137,4,248, +22,68,195,249,22,130,4,80,158,39,35,28,248,22,75,195,250,22,78,2,20, +9,248,22,69,199,250,22,77,2,3,248,22,77,248,22,68,199,250,22,78,2, +7,248,22,69,201,248,22,69,202,27,248,22,69,248,22,137,4,23,197,1,27, +249,22,1,22,81,249,22,2,22,137,4,248,22,137,4,248,22,68,199,249,22, +130,4,80,158,39,35,251,22,77,1,22,119,105,116,104,45,99,111,110,116,105, 110,117,97,116,105,111,110,45,109,97,114,107,2,24,250,22,78,1,23,101,120, 116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110, 21,95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109,97,114,107, 45,115,101,116,45,102,105,114,115,116,11,2,24,201,250,22,78,2,20,9,248, -22,69,203,27,248,22,69,248,22,143,4,196,28,248,22,75,193,20,15,159,36, -35,36,249,22,136,4,80,158,38,35,27,248,22,143,4,248,22,68,197,28,249, -22,173,8,62,61,62,248,22,137,4,248,22,92,196,250,22,77,2,20,248,22, -77,249,22,77,21,93,2,25,248,22,68,199,250,22,78,2,7,249,22,77,2, +22,69,203,27,248,22,69,248,22,137,4,196,28,248,22,75,193,20,15,159,36, +35,36,249,22,130,4,80,158,38,35,27,248,22,137,4,248,22,68,197,28,249, +22,167,8,62,61,62,248,22,131,4,248,22,92,196,250,22,77,2,20,248,22, +77,249,22,77,21,93,2,25,248,22,68,199,250,22,78,2,9,249,22,77,2, 25,249,22,77,248,22,101,203,2,25,248,22,69,202,251,22,77,2,16,28,249, -22,173,8,248,22,137,4,248,22,68,200,64,101,108,115,101,10,248,22,68,197, -250,22,78,2,20,9,248,22,69,200,249,22,67,2,7,248,22,69,202,100,8, +22,167,8,248,22,131,4,248,22,68,200,64,101,108,115,101,10,248,22,68,197, +250,22,78,2,20,9,248,22,69,200,249,22,67,2,9,248,22,69,202,100,8, 31,8,30,8,29,8,28,8,27,16,4,11,11,2,18,3,1,8,101,110,118, 49,50,55,55,56,16,4,11,11,2,19,3,1,8,101,110,118,49,50,55,55, 57,93,8,224,131,78,0,0,18,16,2,158,94,10,64,118,111,105,100,8,47, -95,9,8,224,131,78,0,0,2,1,27,248,22,69,248,22,143,4,196,249,22, -136,4,80,158,38,35,28,248,22,53,248,22,137,4,248,22,68,197,250,22,77, -2,26,248,22,77,248,22,68,199,248,22,92,198,27,248,22,137,4,248,22,68, +95,9,8,224,131,78,0,0,2,1,27,248,22,69,248,22,137,4,196,249,22, +130,4,80,158,38,35,28,248,22,53,248,22,131,4,248,22,68,197,250,22,77, +2,26,248,22,77,248,22,68,199,248,22,92,198,27,248,22,131,4,248,22,68, 197,250,22,77,2,26,248,22,77,248,22,68,197,250,22,78,2,23,248,22,69, 199,248,22,69,202,159,35,20,102,159,35,16,1,11,16,0,83,158,41,20,100, 144,69,35,37,109,105,110,45,115,116,120,2,1,11,11,11,10,35,80,158,35, @@ -81,25 +81,25 @@ 2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,35, 45,36,11,11,11,16,0,16,0,16,0,35,35,11,11,11,11,16,0,16,0, 16,0,35,35,16,11,16,5,2,2,20,15,159,35,35,35,35,20,102,159,35, -16,0,16,1,33,32,10,16,5,2,9,89,162,8,44,36,52,9,223,0,33, -33,35,20,102,159,35,16,1,2,2,16,0,11,16,5,2,12,89,162,8,44, +16,0,16,1,33,32,10,16,5,2,8,89,162,8,44,36,52,9,223,0,33, +33,35,20,102,159,35,16,1,2,2,16,0,11,16,5,2,10,89,162,8,44, 36,52,9,223,0,33,34,35,20,102,159,35,16,1,2,2,16,0,11,16,5, -2,4,89,162,8,44,36,52,9,223,0,33,35,35,20,102,159,35,16,1,2, -2,16,1,33,36,11,16,5,2,6,89,162,8,44,36,55,9,223,0,33,37, -35,20,102,159,35,16,1,2,2,16,1,33,38,11,16,5,2,11,89,162,8, +2,12,89,162,8,44,36,52,9,223,0,33,35,35,20,102,159,35,16,1,2, +2,16,1,33,36,11,16,5,2,5,89,162,8,44,36,55,9,223,0,33,37, +35,20,102,159,35,16,1,2,2,16,1,33,38,11,16,5,2,3,89,162,8, 44,36,57,9,223,0,33,41,35,20,102,159,35,16,1,2,2,16,0,11,16, -5,2,8,89,162,8,44,36,52,9,223,0,33,43,35,20,102,159,35,16,1, -2,2,16,0,11,16,5,2,5,89,162,8,44,36,53,9,223,0,33,44,35, -20,102,159,35,16,1,2,2,16,0,11,16,5,2,10,89,162,8,44,36,54, -9,223,0,33,45,35,20,102,159,35,16,1,2,2,16,0,11,16,5,2,7, +5,2,11,89,162,8,44,36,52,9,223,0,33,43,35,20,102,159,35,16,1, +2,2,16,0,11,16,5,2,7,89,162,8,44,36,53,9,223,0,33,44,35, +20,102,159,35,16,1,2,2,16,0,11,16,5,2,6,89,162,8,44,36,54, +9,223,0,33,45,35,20,102,159,35,16,1,2,2,16,0,11,16,5,2,9, 89,162,8,44,36,57,9,223,0,33,46,35,20,102,159,35,16,1,2,2,16, -1,33,48,11,16,5,2,3,89,162,8,44,36,53,9,223,0,33,49,35,20, +1,33,48,11,16,5,2,4,89,162,8,44,36,53,9,223,0,33,49,35,20, 102,159,35,16,1,2,2,16,0,11,16,0,94,2,14,2,15,93,2,14,9, 9,35,0}; EVAL_ONE_SIZED_STR((char *)expr, 2018); } { - static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,52,46,50,46,51,46,55,62,0,0,0,1,0,0,13,0,18,0, + static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,52,46,50,46,51,46,56,62,0,0,0,1,0,0,13,0,18,0, 35,0,50,0,68,0,84,0,94,0,112,0,132,0,148,0,166,0,197,0,226, 0,248,0,6,1,12,1,26,1,31,1,41,1,49,1,77,1,109,1,115,1, 160,1,205,1,229,1,12,2,14,2,71,2,161,3,202,3,37,5,141,5,245, @@ -132,262 +132,262 @@ 6,36,36,99,97,110,110,111,116,32,97,100,100,32,97,32,115,117,102,102,105, 120,32,116,111,32,97,32,114,111,111,116,32,112,97,116,104,58,32,5,0,27, 20,14,159,80,158,36,50,250,80,158,39,51,249,22,27,11,80,158,41,50,22, -131,13,10,248,22,166,5,23,196,2,28,248,22,163,6,23,194,2,12,87,94, -248,22,177,8,23,194,1,248,80,159,37,53,36,195,28,248,22,75,23,195,2, -9,27,248,22,68,23,196,2,27,28,248,22,177,13,23,195,2,23,194,1,28, -248,22,176,13,23,195,2,249,22,178,13,23,196,1,250,80,158,42,48,248,22, -129,14,2,19,11,10,250,80,158,40,48,248,22,129,14,2,19,23,197,1,10, -28,23,193,2,249,22,67,248,22,180,13,249,22,178,13,23,198,1,247,22,130, -14,27,248,22,69,23,200,1,28,248,22,75,23,194,2,9,27,248,22,68,23, -195,2,27,28,248,22,177,13,23,195,2,23,194,1,28,248,22,176,13,23,195, -2,249,22,178,13,23,196,1,250,80,158,47,48,248,22,129,14,2,19,11,10, -250,80,158,45,48,248,22,129,14,2,19,23,197,1,10,28,23,193,2,249,22, -67,248,22,180,13,249,22,178,13,23,198,1,247,22,130,14,248,80,159,45,52, +189,12,10,248,22,160,5,23,196,2,28,248,22,157,6,23,194,2,12,87,94, +248,22,171,8,23,194,1,248,80,159,37,53,36,195,28,248,22,75,23,195,2, +9,27,248,22,68,23,196,2,27,28,248,22,171,13,23,195,2,23,194,1,28, +248,22,170,13,23,195,2,249,22,172,13,23,196,1,250,80,158,42,48,248,22, +187,13,2,19,11,10,250,80,158,40,48,248,22,187,13,2,19,23,197,1,10, +28,23,193,2,249,22,67,248,22,174,13,249,22,172,13,23,198,1,247,22,188, +13,27,248,22,69,23,200,1,28,248,22,75,23,194,2,9,27,248,22,68,23, +195,2,27,28,248,22,171,13,23,195,2,23,194,1,28,248,22,170,13,23,195, +2,249,22,172,13,23,196,1,250,80,158,47,48,248,22,187,13,2,19,11,10, +250,80,158,45,48,248,22,187,13,2,19,23,197,1,10,28,23,193,2,249,22, +67,248,22,174,13,249,22,172,13,23,198,1,247,22,188,13,248,80,159,45,52, 36,248,22,69,23,199,1,87,94,23,193,1,248,80,159,43,52,36,248,22,69, 23,197,1,87,94,23,193,1,27,248,22,69,23,198,1,28,248,22,75,23,194, -2,9,27,248,22,68,23,195,2,27,28,248,22,177,13,23,195,2,23,194,1, -28,248,22,176,13,23,195,2,249,22,178,13,23,196,1,250,80,158,45,48,248, -22,129,14,2,19,11,10,250,80,158,43,48,248,22,129,14,2,19,23,197,1, -10,28,23,193,2,249,22,67,248,22,180,13,249,22,178,13,23,198,1,247,22, -130,14,248,80,159,43,52,36,248,22,69,23,199,1,248,80,159,41,52,36,248, -22,69,196,27,248,22,153,13,23,195,2,28,23,193,2,192,87,94,23,193,1, -28,248,22,168,6,23,195,2,27,248,22,175,13,195,28,192,192,248,22,176,13, -195,11,87,94,28,28,248,22,154,13,23,195,2,10,27,248,22,153,13,23,196, -2,28,23,193,2,192,87,94,23,193,1,28,248,22,168,6,23,196,2,27,248, -22,175,13,23,197,2,28,23,193,2,192,87,94,23,193,1,248,22,176,13,23, -197,2,11,12,250,22,141,9,76,110,111,114,109,97,108,45,112,97,116,104,45, +2,9,27,248,22,68,23,195,2,27,28,248,22,171,13,23,195,2,23,194,1, +28,248,22,170,13,23,195,2,249,22,172,13,23,196,1,250,80,158,45,48,248, +22,187,13,2,19,11,10,250,80,158,43,48,248,22,187,13,2,19,23,197,1, +10,28,23,193,2,249,22,67,248,22,174,13,249,22,172,13,23,198,1,247,22, +188,13,248,80,159,43,52,36,248,22,69,23,199,1,248,80,159,41,52,36,248, +22,69,196,27,248,22,147,13,23,195,2,28,23,193,2,192,87,94,23,193,1, +28,248,22,162,6,23,195,2,27,248,22,169,13,195,28,192,192,248,22,170,13, +195,11,87,94,28,28,248,22,148,13,23,195,2,10,27,248,22,147,13,23,196, +2,28,23,193,2,192,87,94,23,193,1,28,248,22,162,6,23,196,2,27,248, +22,169,13,23,197,2,28,23,193,2,192,87,94,23,193,1,248,22,170,13,23, +197,2,11,12,250,22,135,9,76,110,111,114,109,97,108,45,112,97,116,104,45, 99,97,115,101,6,42,42,112,97,116,104,32,40,102,111,114,32,97,110,121,32, 115,121,115,116,101,109,41,32,111,114,32,118,97,108,105,100,45,112,97,116,104, -32,115,116,114,105,110,103,23,197,2,28,28,248,22,154,13,23,195,2,249,22, -173,8,248,22,155,13,23,197,2,2,20,249,22,173,8,247,22,187,7,2,20, -27,28,248,22,168,6,23,196,2,23,195,2,248,22,177,7,248,22,158,13,23, -197,2,28,249,22,142,14,0,21,35,114,120,34,94,91,92,92,93,91,92,92, -93,91,63,93,91,92,92,93,34,23,195,2,28,248,22,168,6,195,248,22,161, -13,195,194,27,248,22,143,7,23,195,1,249,22,162,13,248,22,180,7,250,22, -148,14,0,6,35,114,120,34,47,34,28,249,22,142,14,0,22,35,114,120,34, +32,115,116,114,105,110,103,23,197,2,28,28,248,22,148,13,23,195,2,249,22, +167,8,248,22,149,13,23,197,2,2,20,249,22,167,8,247,22,181,7,2,20, +27,28,248,22,162,6,23,196,2,23,195,2,248,22,171,7,248,22,152,13,23, +197,2,28,249,22,136,14,0,21,35,114,120,34,94,91,92,92,93,91,92,92, +93,91,63,93,91,92,92,93,34,23,195,2,28,248,22,162,6,195,248,22,155, +13,195,194,27,248,22,137,7,23,195,1,249,22,156,13,248,22,174,7,250,22, +142,14,0,6,35,114,120,34,47,34,28,249,22,136,14,0,22,35,114,120,34, 91,47,92,92,93,91,46,32,93,43,91,47,92,92,93,42,36,34,23,201,2, -23,199,1,250,22,148,14,0,19,35,114,120,34,91,32,46,93,43,40,91,47, +23,199,1,250,22,142,14,0,19,35,114,120,34,91,32,46,93,43,40,91,47, 92,92,93,42,41,36,34,23,202,1,6,2,2,92,49,80,159,43,36,37,2, -20,28,248,22,168,6,194,248,22,161,13,194,193,87,94,28,27,248,22,153,13, -23,196,2,28,23,193,2,192,87,94,23,193,1,28,248,22,168,6,23,196,2, -27,248,22,175,13,23,197,2,28,23,193,2,192,87,94,23,193,1,248,22,176, -13,23,197,2,11,12,250,22,141,9,23,196,2,2,21,23,197,2,28,248,22, -175,13,23,195,2,12,248,22,171,11,249,22,180,10,248,22,133,7,250,22,152, -7,2,22,23,200,1,23,201,1,247,22,23,87,94,28,27,248,22,153,13,23, -196,2,28,23,193,2,192,87,94,23,193,1,28,248,22,168,6,23,196,2,27, -248,22,175,13,23,197,2,28,23,193,2,192,87,94,23,193,1,248,22,176,13, -23,197,2,11,12,250,22,141,9,23,196,2,2,21,23,197,2,28,248,22,175, -13,23,195,2,12,248,22,171,11,249,22,180,10,248,22,133,7,250,22,152,7, -2,22,23,200,1,23,201,1,247,22,23,87,94,87,94,28,27,248,22,153,13, -23,196,2,28,23,193,2,192,87,94,23,193,1,28,248,22,168,6,23,196,2, -27,248,22,175,13,23,197,2,28,23,193,2,192,87,94,23,193,1,248,22,176, -13,23,197,2,11,12,250,22,141,9,195,2,21,23,197,2,28,248,22,175,13, -23,195,2,12,248,22,171,11,249,22,180,10,248,22,133,7,250,22,152,7,2, +20,28,248,22,162,6,194,248,22,155,13,194,193,87,94,28,27,248,22,147,13, +23,196,2,28,23,193,2,192,87,94,23,193,1,28,248,22,162,6,23,196,2, +27,248,22,169,13,23,197,2,28,23,193,2,192,87,94,23,193,1,248,22,170, +13,23,197,2,11,12,250,22,135,9,23,196,2,2,21,23,197,2,28,248,22, +169,13,23,195,2,12,248,22,165,11,249,22,174,10,248,22,191,6,250,22,146, +7,2,22,23,200,1,23,201,1,247,22,23,87,94,28,27,248,22,147,13,23, +196,2,28,23,193,2,192,87,94,23,193,1,28,248,22,162,6,23,196,2,27, +248,22,169,13,23,197,2,28,23,193,2,192,87,94,23,193,1,248,22,170,13, +23,197,2,11,12,250,22,135,9,23,196,2,2,21,23,197,2,28,248,22,169, +13,23,195,2,12,248,22,165,11,249,22,174,10,248,22,191,6,250,22,146,7, +2,22,23,200,1,23,201,1,247,22,23,87,94,87,94,28,27,248,22,147,13, +23,196,2,28,23,193,2,192,87,94,23,193,1,28,248,22,162,6,23,196,2, +27,248,22,169,13,23,197,2,28,23,193,2,192,87,94,23,193,1,248,22,170, +13,23,197,2,11,12,250,22,135,9,195,2,21,23,197,2,28,248,22,169,13, +23,195,2,12,248,22,165,11,249,22,174,10,248,22,191,6,250,22,146,7,2, 22,199,23,201,1,247,22,23,249,22,3,89,162,8,44,36,49,9,223,2,33, -34,196,87,94,28,27,248,22,153,13,23,195,2,28,23,193,2,192,87,94,23, -193,1,28,248,22,168,6,23,195,2,27,248,22,175,13,23,196,2,28,23,193, -2,192,87,94,23,193,1,248,22,176,13,23,196,2,11,12,250,22,141,9,2, -6,2,21,23,196,2,28,248,22,175,13,23,194,2,12,248,22,171,11,249,22, -180,10,248,22,133,7,250,22,152,7,2,22,2,6,23,200,1,247,22,23,32, +34,196,87,94,28,27,248,22,147,13,23,195,2,28,23,193,2,192,87,94,23, +193,1,28,248,22,162,6,23,195,2,27,248,22,169,13,23,196,2,28,23,193, +2,192,87,94,23,193,1,248,22,170,13,23,196,2,11,12,250,22,135,9,2, +6,2,21,23,196,2,28,248,22,169,13,23,194,2,12,248,22,165,11,249,22, +174,10,248,22,191,6,250,22,146,7,2,22,2,6,23,200,1,247,22,23,32, 37,89,162,8,44,39,57,2,23,222,33,38,28,248,22,75,23,197,2,87,94, -23,196,1,248,22,171,11,249,22,146,11,251,22,152,7,2,24,2,6,28,248, -22,75,23,203,2,87,94,23,202,1,23,201,1,250,22,1,22,171,13,23,204, -1,23,205,1,23,200,1,247,22,23,27,249,22,171,13,248,22,68,23,200,2, -23,197,2,28,248,22,166,13,23,194,2,27,250,22,1,22,171,13,23,197,1, -23,200,2,28,248,22,166,13,23,194,2,192,87,94,23,193,1,27,248,22,69, -23,200,1,28,248,22,75,23,194,2,87,94,23,193,1,248,22,171,11,249,22, -146,11,251,22,152,7,2,24,2,6,28,248,22,75,23,206,2,87,94,23,205, -1,23,204,1,250,22,1,22,171,13,23,207,1,23,208,1,23,203,1,247,22, -23,27,249,22,171,13,248,22,68,23,197,2,23,200,2,28,248,22,166,13,23, -194,2,27,250,22,1,22,171,13,23,197,1,202,28,248,22,166,13,193,192,251, +23,196,1,248,22,165,11,249,22,140,11,251,22,146,7,2,24,2,6,28,248, +22,75,23,203,2,87,94,23,202,1,23,201,1,250,22,1,22,165,13,23,204, +1,23,205,1,23,200,1,247,22,23,27,249,22,165,13,248,22,68,23,200,2, +23,197,2,28,248,22,160,13,23,194,2,27,250,22,1,22,165,13,23,197,1, +23,200,2,28,248,22,160,13,23,194,2,192,87,94,23,193,1,27,248,22,69, +23,200,1,28,248,22,75,23,194,2,87,94,23,193,1,248,22,165,11,249,22, +140,11,251,22,146,7,2,24,2,6,28,248,22,75,23,206,2,87,94,23,205, +1,23,204,1,250,22,1,22,165,13,23,207,1,23,208,1,23,203,1,247,22, +23,27,249,22,165,13,248,22,68,23,197,2,23,200,2,28,248,22,160,13,23, +194,2,27,250,22,1,22,165,13,23,197,1,202,28,248,22,160,13,193,192,251, 2,37,201,202,203,248,22,69,199,251,2,37,200,201,202,248,22,69,198,87,94, 23,193,1,27,248,22,69,23,199,1,28,248,22,75,23,194,2,87,94,23,193, -1,248,22,171,11,249,22,146,11,251,22,152,7,2,24,2,6,28,248,22,75, -23,205,2,87,94,23,204,1,23,203,1,250,22,1,22,171,13,23,206,1,23, -207,1,23,202,1,247,22,23,27,249,22,171,13,248,22,68,23,197,2,23,199, -2,28,248,22,166,13,23,194,2,27,250,22,1,22,171,13,23,197,1,201,28, -248,22,166,13,193,192,251,2,37,200,201,202,248,22,69,199,251,2,37,199,200, -201,248,22,69,198,87,94,87,94,87,94,28,27,248,22,153,13,194,28,23,193, -2,192,87,94,23,193,1,28,248,22,168,6,194,27,248,22,175,13,195,28,23, -193,2,192,87,94,23,193,1,248,22,176,13,195,11,12,250,22,141,9,2,6, -2,21,195,28,248,22,175,13,193,12,248,22,171,11,249,22,180,10,248,22,133, -7,250,22,152,7,2,22,2,6,199,247,22,23,249,22,3,32,0,89,162,8, -44,36,48,9,222,33,36,195,27,247,22,131,14,251,2,37,196,197,198,196,32, +1,248,22,165,11,249,22,140,11,251,22,146,7,2,24,2,6,28,248,22,75, +23,205,2,87,94,23,204,1,23,203,1,250,22,1,22,165,13,23,206,1,23, +207,1,23,202,1,247,22,23,27,249,22,165,13,248,22,68,23,197,2,23,199, +2,28,248,22,160,13,23,194,2,27,250,22,1,22,165,13,23,197,1,201,28, +248,22,160,13,193,192,251,2,37,200,201,202,248,22,69,199,251,2,37,199,200, +201,248,22,69,198,87,94,87,94,87,94,28,27,248,22,147,13,194,28,23,193, +2,192,87,94,23,193,1,28,248,22,162,6,194,27,248,22,169,13,195,28,23, +193,2,192,87,94,23,193,1,248,22,170,13,195,11,12,250,22,135,9,2,6, +2,21,195,28,248,22,169,13,193,12,248,22,165,11,249,22,174,10,248,22,191, +6,250,22,146,7,2,22,2,6,199,247,22,23,249,22,3,32,0,89,162,8, +44,36,48,9,222,33,36,195,27,247,22,189,13,251,2,37,196,197,198,196,32, 40,89,162,43,41,58,2,23,222,33,41,28,248,22,75,23,199,2,87,94,23, -198,1,248,23,196,1,251,22,152,7,2,24,23,199,1,28,248,22,75,23,203, -2,87,94,23,202,1,23,201,1,250,22,1,22,171,13,23,204,1,23,205,1, -23,198,1,27,249,22,171,13,248,22,68,23,202,2,23,199,2,28,248,22,166, -13,23,194,2,27,250,22,1,22,171,13,23,197,1,23,202,2,28,248,22,166, +198,1,248,23,196,1,251,22,146,7,2,24,23,199,1,28,248,22,75,23,203, +2,87,94,23,202,1,23,201,1,250,22,1,22,165,13,23,204,1,23,205,1, +23,198,1,27,249,22,165,13,248,22,68,23,202,2,23,199,2,28,248,22,160, +13,23,194,2,27,250,22,1,22,165,13,23,197,1,23,202,2,28,248,22,160, 13,23,194,2,192,87,94,23,193,1,27,248,22,69,23,202,1,28,248,22,75, -23,194,2,87,94,23,193,1,248,23,199,1,251,22,152,7,2,24,23,202,1, -28,248,22,75,23,206,2,87,94,23,205,1,23,204,1,250,22,1,22,171,13, -23,207,1,23,208,1,23,201,1,27,249,22,171,13,248,22,68,23,197,2,23, -202,2,28,248,22,166,13,23,194,2,27,250,22,1,22,171,13,23,197,1,204, -28,248,22,166,13,193,192,253,2,40,203,204,205,206,23,15,248,22,69,201,253, +23,194,2,87,94,23,193,1,248,23,199,1,251,22,146,7,2,24,23,202,1, +28,248,22,75,23,206,2,87,94,23,205,1,23,204,1,250,22,1,22,165,13, +23,207,1,23,208,1,23,201,1,27,249,22,165,13,248,22,68,23,197,2,23, +202,2,28,248,22,160,13,23,194,2,27,250,22,1,22,165,13,23,197,1,204, +28,248,22,160,13,193,192,253,2,40,203,204,205,206,23,15,248,22,69,201,253, 2,40,202,203,204,205,206,248,22,69,200,87,94,23,193,1,27,248,22,69,23, -201,1,28,248,22,75,23,194,2,87,94,23,193,1,248,23,198,1,251,22,152, +201,1,28,248,22,75,23,194,2,87,94,23,193,1,248,23,198,1,251,22,146, 7,2,24,23,201,1,28,248,22,75,23,205,2,87,94,23,204,1,23,203,1, -250,22,1,22,171,13,23,206,1,23,207,1,23,200,1,27,249,22,171,13,248, -22,68,23,197,2,23,201,2,28,248,22,166,13,23,194,2,27,250,22,1,22, -171,13,23,197,1,203,28,248,22,166,13,193,192,253,2,40,202,203,204,205,206, -248,22,69,201,253,2,40,201,202,203,204,205,248,22,69,200,27,247,22,131,14, -253,2,40,198,199,200,201,202,198,87,95,28,28,248,22,154,13,23,194,2,10, -27,248,22,153,13,23,195,2,28,23,193,2,192,87,94,23,193,1,28,248,22, -168,6,23,195,2,27,248,22,175,13,23,196,2,28,23,193,2,192,87,94,23, -193,1,248,22,176,13,23,196,2,11,12,252,22,141,9,23,200,2,2,25,35, -23,198,2,23,199,2,28,28,248,22,168,6,23,195,2,10,248,22,156,7,23, -195,2,87,94,23,194,1,12,252,22,141,9,23,200,2,2,26,36,23,198,2, -23,199,1,91,159,38,11,90,161,38,35,11,248,22,174,13,23,197,2,87,94, -23,195,1,87,94,28,192,12,250,22,142,9,23,201,1,2,27,23,199,1,249, -22,7,194,195,91,159,37,11,90,161,37,35,11,87,95,28,28,248,22,154,13, -23,196,2,10,27,248,22,153,13,23,197,2,28,23,193,2,192,87,94,23,193, -1,28,248,22,168,6,23,197,2,27,248,22,175,13,23,198,2,28,23,193,2, -192,87,94,23,193,1,248,22,176,13,23,198,2,11,12,252,22,141,9,2,9, -2,25,35,23,200,2,23,201,2,28,28,248,22,168,6,23,197,2,10,248,22, -156,7,23,197,2,12,252,22,141,9,2,9,2,26,36,23,200,2,23,201,2, -91,159,38,11,90,161,38,35,11,248,22,174,13,23,199,2,87,94,23,195,1, -87,94,28,192,12,250,22,142,9,2,9,2,27,23,201,2,249,22,7,194,195, -27,249,22,163,13,250,22,147,14,0,20,35,114,120,35,34,40,63,58,91,46, -93,91,94,46,93,42,124,41,36,34,248,22,159,13,23,201,1,28,248,22,168, -6,23,203,2,249,22,180,7,23,204,1,8,63,23,202,1,28,248,22,154,13, -23,199,2,248,22,155,13,23,199,1,87,94,23,198,1,247,22,156,13,28,248, -22,153,13,194,249,22,171,13,195,194,192,91,159,37,11,90,161,37,35,11,87, -95,28,28,248,22,154,13,23,196,2,10,27,248,22,153,13,23,197,2,28,23, -193,2,192,87,94,23,193,1,28,248,22,168,6,23,197,2,27,248,22,175,13, -23,198,2,28,23,193,2,192,87,94,23,193,1,248,22,176,13,23,198,2,11, -12,252,22,141,9,2,10,2,25,35,23,200,2,23,201,2,28,28,248,22,168, -6,23,197,2,10,248,22,156,7,23,197,2,12,252,22,141,9,2,10,2,26, -36,23,200,2,23,201,2,91,159,38,11,90,161,38,35,11,248,22,174,13,23, -199,2,87,94,23,195,1,87,94,28,192,12,250,22,142,9,2,10,2,27,23, -201,2,249,22,7,194,195,27,249,22,163,13,249,22,166,7,250,22,148,14,0, -9,35,114,120,35,34,91,46,93,34,248,22,159,13,23,203,1,6,1,1,95, -28,248,22,168,6,23,202,2,249,22,180,7,23,203,1,8,63,23,201,1,28, -248,22,154,13,23,199,2,248,22,155,13,23,199,1,87,94,23,198,1,247,22, -156,13,28,248,22,153,13,194,249,22,171,13,195,194,192,249,247,22,135,5,194, -11,249,80,159,37,46,36,9,9,249,80,159,37,46,36,195,9,27,247,22,133, -14,249,80,158,38,47,28,23,195,2,27,248,22,185,7,6,11,11,80,76,84, +250,22,1,22,165,13,23,206,1,23,207,1,23,200,1,27,249,22,165,13,248, +22,68,23,197,2,23,201,2,28,248,22,160,13,23,194,2,27,250,22,1,22, +165,13,23,197,1,203,28,248,22,160,13,193,192,253,2,40,202,203,204,205,206, +248,22,69,201,253,2,40,201,202,203,204,205,248,22,69,200,27,247,22,189,13, +253,2,40,198,199,200,201,202,198,87,95,28,28,248,22,148,13,23,194,2,10, +27,248,22,147,13,23,195,2,28,23,193,2,192,87,94,23,193,1,28,248,22, +162,6,23,195,2,27,248,22,169,13,23,196,2,28,23,193,2,192,87,94,23, +193,1,248,22,170,13,23,196,2,11,12,252,22,135,9,23,200,2,2,25,35, +23,198,2,23,199,2,28,28,248,22,162,6,23,195,2,10,248,22,150,7,23, +195,2,87,94,23,194,1,12,252,22,135,9,23,200,2,2,26,36,23,198,2, +23,199,1,91,159,38,11,90,161,38,35,11,248,22,168,13,23,197,2,87,94, +23,195,1,87,94,28,192,12,250,22,136,9,23,201,1,2,27,23,199,1,249, +22,7,194,195,91,159,37,11,90,161,37,35,11,87,95,28,28,248,22,148,13, +23,196,2,10,27,248,22,147,13,23,197,2,28,23,193,2,192,87,94,23,193, +1,28,248,22,162,6,23,197,2,27,248,22,169,13,23,198,2,28,23,193,2, +192,87,94,23,193,1,248,22,170,13,23,198,2,11,12,252,22,135,9,2,9, +2,25,35,23,200,2,23,201,2,28,28,248,22,162,6,23,197,2,10,248,22, +150,7,23,197,2,12,252,22,135,9,2,9,2,26,36,23,200,2,23,201,2, +91,159,38,11,90,161,38,35,11,248,22,168,13,23,199,2,87,94,23,195,1, +87,94,28,192,12,250,22,136,9,2,9,2,27,23,201,2,249,22,7,194,195, +27,249,22,157,13,250,22,141,14,0,20,35,114,120,35,34,40,63,58,91,46, +93,91,94,46,93,42,124,41,36,34,248,22,153,13,23,201,1,28,248,22,162, +6,23,203,2,249,22,174,7,23,204,1,8,63,23,202,1,28,248,22,148,13, +23,199,2,248,22,149,13,23,199,1,87,94,23,198,1,247,22,150,13,28,248, +22,147,13,194,249,22,165,13,195,194,192,91,159,37,11,90,161,37,35,11,87, +95,28,28,248,22,148,13,23,196,2,10,27,248,22,147,13,23,197,2,28,23, +193,2,192,87,94,23,193,1,28,248,22,162,6,23,197,2,27,248,22,169,13, +23,198,2,28,23,193,2,192,87,94,23,193,1,248,22,170,13,23,198,2,11, +12,252,22,135,9,2,10,2,25,35,23,200,2,23,201,2,28,28,248,22,162, +6,23,197,2,10,248,22,150,7,23,197,2,12,252,22,135,9,2,10,2,26, +36,23,200,2,23,201,2,91,159,38,11,90,161,38,35,11,248,22,168,13,23, +199,2,87,94,23,195,1,87,94,28,192,12,250,22,136,9,2,10,2,27,23, +201,2,249,22,7,194,195,27,249,22,157,13,249,22,160,7,250,22,142,14,0, +9,35,114,120,35,34,91,46,93,34,248,22,153,13,23,203,1,6,1,1,95, +28,248,22,162,6,23,202,2,249,22,174,7,23,203,1,8,63,23,201,1,28, +248,22,148,13,23,199,2,248,22,149,13,23,199,1,87,94,23,198,1,247,22, +150,13,28,248,22,147,13,194,249,22,165,13,195,194,192,249,247,22,129,5,194, +11,249,80,159,37,46,36,9,9,249,80,159,37,46,36,195,9,27,247,22,191, +13,249,80,158,38,47,28,23,195,2,27,248,22,179,7,6,11,11,80,76,84, 67,79,76,76,69,67,84,83,28,192,192,6,0,0,6,0,0,27,28,23,196, -1,250,22,171,13,248,22,129,14,69,97,100,100,111,110,45,100,105,114,247,22, -183,7,6,8,8,99,111,108,108,101,99,116,115,11,27,248,80,159,41,52,36, -250,22,81,23,203,1,248,22,77,248,22,129,14,72,99,111,108,108,101,99,116, +1,250,22,165,13,248,22,187,13,69,97,100,100,111,110,45,100,105,114,247,22, +177,7,6,8,8,99,111,108,108,101,99,116,115,11,27,248,80,159,41,52,36, +250,22,81,23,203,1,248,22,77,248,22,187,13,72,99,111,108,108,101,99,116, 115,45,100,105,114,23,204,1,28,193,249,22,67,195,194,192,32,50,89,162,8, -44,38,58,2,18,222,33,51,27,249,22,140,14,23,197,2,23,198,2,28,23, +44,38,58,2,18,222,33,51,27,249,22,134,14,23,197,2,23,198,2,28,23, 193,2,87,94,23,196,1,27,248,22,92,23,195,2,27,27,248,22,101,23,197, -1,27,249,22,140,14,23,201,2,23,196,2,28,23,193,2,87,94,23,194,1, -27,248,22,92,23,195,2,27,27,248,22,101,23,197,1,27,249,22,140,14,23, +1,27,249,22,134,14,23,201,2,23,196,2,28,23,193,2,87,94,23,194,1, +27,248,22,92,23,195,2,27,27,248,22,101,23,197,1,27,249,22,134,14,23, 205,2,23,196,2,28,23,193,2,87,94,23,194,1,27,248,22,92,23,195,2, -27,250,2,50,23,207,2,23,208,1,248,22,101,23,199,1,28,249,22,162,7, -23,196,2,2,28,249,22,81,23,206,2,194,249,22,67,248,22,162,13,23,197, -1,194,87,95,23,203,1,23,193,1,28,249,22,162,7,23,196,2,2,28,249, -22,81,23,204,2,9,249,22,67,248,22,162,13,23,197,1,9,28,249,22,162, -7,23,196,2,2,28,249,22,81,23,202,2,194,249,22,67,248,22,162,13,23, -197,1,194,87,94,23,193,1,28,249,22,162,7,23,196,2,2,28,249,22,81, -23,200,2,9,249,22,67,248,22,162,13,23,197,1,9,28,249,22,162,7,23, -196,2,2,28,249,22,81,197,194,87,94,23,196,1,249,22,67,248,22,162,13, -23,197,1,194,87,94,23,193,1,28,249,22,162,7,23,198,2,2,28,249,22, -81,195,9,87,94,23,194,1,249,22,67,248,22,162,13,23,199,1,9,87,95, -28,28,248,22,156,7,194,10,248,22,168,6,194,12,250,22,141,9,2,13,6, +27,250,2,50,23,207,2,23,208,1,248,22,101,23,199,1,28,249,22,156,7, +23,196,2,2,28,249,22,81,23,206,2,194,249,22,67,248,22,156,13,23,197, +1,194,87,95,23,203,1,23,193,1,28,249,22,156,7,23,196,2,2,28,249, +22,81,23,204,2,9,249,22,67,248,22,156,13,23,197,1,9,28,249,22,156, +7,23,196,2,2,28,249,22,81,23,202,2,194,249,22,67,248,22,156,13,23, +197,1,194,87,94,23,193,1,28,249,22,156,7,23,196,2,2,28,249,22,81, +23,200,2,9,249,22,67,248,22,156,13,23,197,1,9,28,249,22,156,7,23, +196,2,2,28,249,22,81,197,194,87,94,23,196,1,249,22,67,248,22,156,13, +23,197,1,194,87,94,23,193,1,28,249,22,156,7,23,198,2,2,28,249,22, +81,195,9,87,94,23,194,1,249,22,67,248,22,156,13,23,199,1,9,87,95, +28,28,248,22,150,7,194,10,248,22,162,6,194,12,250,22,135,9,2,13,6, 21,21,98,121,116,101,32,115,116,114,105,110,103,32,111,114,32,115,116,114,105, -110,103,196,28,28,248,22,76,195,249,22,4,22,153,13,196,11,12,250,22,141, +110,103,196,28,28,248,22,76,195,249,22,4,22,147,13,196,11,12,250,22,135, 9,2,13,6,13,13,108,105,115,116,32,111,102,32,112,97,116,104,115,197,250, -2,50,197,195,28,248,22,168,6,197,248,22,179,7,197,196,32,53,89,162,43, +2,50,197,195,28,248,22,162,6,197,248,22,173,7,197,196,32,53,89,162,43, 38,8,26,70,102,111,117,110,100,45,101,120,101,99,222,33,54,28,23,193,2, -91,159,38,11,90,161,38,35,11,248,22,174,13,23,199,2,87,95,23,195,1, -23,194,1,27,28,23,198,2,27,248,22,179,13,23,201,2,28,249,22,175,8, -23,195,2,23,202,2,11,28,248,22,175,13,23,194,2,27,249,22,171,13,23, -198,2,23,196,1,28,23,199,2,91,159,38,11,90,161,38,35,11,248,22,174, -13,23,197,2,87,95,23,195,1,23,194,1,27,28,23,204,2,27,248,22,179, -13,23,199,2,28,249,22,175,8,23,195,2,23,200,2,11,28,248,22,175,13, -23,194,2,250,2,53,23,207,2,23,208,2,249,22,171,13,23,200,2,23,198, +91,159,38,11,90,161,38,35,11,248,22,168,13,23,199,2,87,95,23,195,1, +23,194,1,27,28,23,198,2,27,248,22,173,13,23,201,2,28,249,22,169,8, +23,195,2,23,202,2,11,28,248,22,169,13,23,194,2,27,249,22,165,13,23, +198,2,23,196,1,28,23,199,2,91,159,38,11,90,161,38,35,11,248,22,168, +13,23,197,2,87,95,23,195,1,23,194,1,27,28,23,204,2,27,248,22,173, +13,23,199,2,28,249,22,169,8,23,195,2,23,200,2,11,28,248,22,169,13, +23,194,2,250,2,53,23,207,2,23,208,2,249,22,165,13,23,200,2,23,198, 1,250,2,53,23,207,2,23,208,2,23,196,1,11,28,23,193,2,192,87,94, -23,193,1,27,28,248,22,153,13,23,196,2,27,249,22,171,13,23,198,2,23, -207,2,28,28,248,22,166,13,193,10,248,22,165,13,193,192,11,11,28,23,193, -2,192,87,94,23,193,1,28,23,205,2,11,27,248,22,179,13,23,200,2,28, -249,22,175,8,23,195,2,23,201,1,11,28,248,22,175,13,23,194,2,250,2, -53,23,208,2,23,209,2,249,22,171,13,23,201,1,23,198,1,87,94,23,196, +23,193,1,27,28,248,22,147,13,23,196,2,27,249,22,165,13,23,198,2,23, +207,2,28,28,248,22,160,13,193,10,248,22,159,13,193,192,11,11,28,23,193, +2,192,87,94,23,193,1,28,23,205,2,11,27,248,22,173,13,23,200,2,28, +249,22,169,8,23,195,2,23,201,1,11,28,248,22,169,13,23,194,2,250,2, +53,23,208,2,23,209,2,249,22,165,13,23,201,1,23,198,1,87,94,23,196, 1,250,2,53,23,208,2,23,209,2,23,196,1,192,28,23,198,2,91,159,38, -11,90,161,38,35,11,248,22,174,13,23,197,2,87,95,23,195,1,23,194,1, -27,28,23,203,2,27,248,22,179,13,23,199,2,28,249,22,175,8,23,195,2, -23,200,2,11,28,248,22,175,13,23,194,2,250,2,53,23,206,2,23,207,2, -249,22,171,13,23,200,2,23,198,1,250,2,53,23,206,2,23,207,2,23,196, -1,11,28,23,193,2,192,87,94,23,193,1,27,28,248,22,153,13,23,196,2, -27,249,22,171,13,23,198,2,23,206,2,28,28,248,22,166,13,193,10,248,22, -165,13,193,192,11,11,28,23,193,2,192,87,94,23,193,1,28,23,204,2,11, -27,248,22,179,13,23,200,2,28,249,22,175,8,23,195,2,23,201,1,11,28, -248,22,175,13,23,194,2,250,2,53,23,207,2,23,208,2,249,22,171,13,23, +11,90,161,38,35,11,248,22,168,13,23,197,2,87,95,23,195,1,23,194,1, +27,28,23,203,2,27,248,22,173,13,23,199,2,28,249,22,169,8,23,195,2, +23,200,2,11,28,248,22,169,13,23,194,2,250,2,53,23,206,2,23,207,2, +249,22,165,13,23,200,2,23,198,1,250,2,53,23,206,2,23,207,2,23,196, +1,11,28,23,193,2,192,87,94,23,193,1,27,28,248,22,147,13,23,196,2, +27,249,22,165,13,23,198,2,23,206,2,28,28,248,22,160,13,193,10,248,22, +159,13,193,192,11,11,28,23,193,2,192,87,94,23,193,1,28,23,204,2,11, +27,248,22,173,13,23,200,2,28,249,22,169,8,23,195,2,23,201,1,11,28, +248,22,169,13,23,194,2,250,2,53,23,207,2,23,208,2,249,22,165,13,23, 201,1,23,198,1,87,94,23,196,1,250,2,53,23,207,2,23,208,2,23,196, -1,192,11,28,23,193,2,192,87,94,23,193,1,27,28,248,22,153,13,23,196, -2,27,249,22,171,13,23,198,2,23,201,2,28,28,248,22,166,13,193,10,248, -22,165,13,193,192,11,11,28,23,193,2,192,87,94,23,193,1,28,23,199,2, -11,27,248,22,179,13,23,202,2,28,249,22,175,8,23,195,2,23,203,1,11, -28,248,22,175,13,23,194,2,27,249,22,171,13,23,199,1,23,196,1,28,23, -200,2,91,159,38,11,90,161,38,35,11,248,22,174,13,23,197,2,87,95,23, -195,1,23,194,1,27,28,23,205,2,27,248,22,179,13,23,199,2,28,249,22, -175,8,23,195,2,23,200,2,11,28,248,22,175,13,23,194,2,250,2,53,23, -208,2,23,209,2,249,22,171,13,23,200,2,23,198,1,250,2,53,23,208,2, +1,192,11,28,23,193,2,192,87,94,23,193,1,27,28,248,22,147,13,23,196, +2,27,249,22,165,13,23,198,2,23,201,2,28,28,248,22,160,13,193,10,248, +22,159,13,193,192,11,11,28,23,193,2,192,87,94,23,193,1,28,23,199,2, +11,27,248,22,173,13,23,202,2,28,249,22,169,8,23,195,2,23,203,1,11, +28,248,22,169,13,23,194,2,27,249,22,165,13,23,199,1,23,196,1,28,23, +200,2,91,159,38,11,90,161,38,35,11,248,22,168,13,23,197,2,87,95,23, +195,1,23,194,1,27,28,23,205,2,27,248,22,173,13,23,199,2,28,249,22, +169,8,23,195,2,23,200,2,11,28,248,22,169,13,23,194,2,250,2,53,23, +208,2,23,209,2,249,22,165,13,23,200,2,23,198,1,250,2,53,23,208,2, 23,209,2,23,196,1,11,28,23,193,2,192,87,94,23,193,1,27,28,248,22, -153,13,23,196,2,27,249,22,171,13,23,198,2,23,208,2,28,28,248,22,166, -13,193,10,248,22,165,13,193,192,11,11,28,23,193,2,192,87,94,23,193,1, -28,23,206,2,11,27,248,22,179,13,23,200,2,28,249,22,175,8,23,195,2, -23,201,1,11,28,248,22,175,13,23,194,2,250,2,53,23,209,1,23,210,1, -249,22,171,13,23,201,1,23,198,1,250,2,53,23,16,23,17,195,192,87,94, -23,196,1,28,23,199,2,91,159,38,11,90,161,38,35,11,248,22,174,13,23, -197,2,87,95,23,195,1,23,194,1,27,28,23,204,2,27,248,22,179,13,23, -199,2,28,249,22,175,8,23,195,2,23,200,2,11,28,248,22,175,13,23,194, -2,250,2,53,23,207,2,23,208,2,249,22,171,13,23,200,2,23,198,1,250, +147,13,23,196,2,27,249,22,165,13,23,198,2,23,208,2,28,28,248,22,160, +13,193,10,248,22,159,13,193,192,11,11,28,23,193,2,192,87,94,23,193,1, +28,23,206,2,11,27,248,22,173,13,23,200,2,28,249,22,169,8,23,195,2, +23,201,1,11,28,248,22,169,13,23,194,2,250,2,53,23,209,1,23,210,1, +249,22,165,13,23,201,1,23,198,1,250,2,53,23,16,23,17,195,192,87,94, +23,196,1,28,23,199,2,91,159,38,11,90,161,38,35,11,248,22,168,13,23, +197,2,87,95,23,195,1,23,194,1,27,28,23,204,2,27,248,22,173,13,23, +199,2,28,249,22,169,8,23,195,2,23,200,2,11,28,248,22,169,13,23,194, +2,250,2,53,23,207,2,23,208,2,249,22,165,13,23,200,2,23,198,1,250, 2,53,23,207,2,23,208,2,23,196,1,11,28,23,193,2,192,87,94,23,193, -1,27,28,248,22,153,13,23,196,2,27,249,22,171,13,23,198,2,23,207,2, -28,28,248,22,166,13,193,10,248,22,165,13,193,192,11,11,28,23,193,2,192, -87,94,23,193,1,28,23,205,2,11,27,248,22,179,13,23,200,2,28,249,22, -175,8,23,195,2,23,201,1,11,28,248,22,175,13,23,194,2,250,2,53,23, -208,1,23,209,1,249,22,171,13,23,201,1,23,198,1,250,2,53,23,15,23, +1,27,28,248,22,147,13,23,196,2,27,249,22,165,13,23,198,2,23,207,2, +28,28,248,22,160,13,193,10,248,22,159,13,193,192,11,11,28,23,193,2,192, +87,94,23,193,1,28,23,205,2,11,27,248,22,173,13,23,200,2,28,249,22, +169,8,23,195,2,23,201,1,11,28,248,22,169,13,23,194,2,250,2,53,23, +208,1,23,209,1,249,22,165,13,23,201,1,23,198,1,250,2,53,23,15,23, 16,195,192,194,32,55,89,162,43,39,8,31,2,18,222,33,56,28,248,22,75, -23,197,2,11,27,248,22,178,13,248,22,68,23,199,2,27,249,22,171,13,23, -196,1,23,197,2,28,248,22,165,13,23,194,2,250,2,53,198,199,195,87,94, +23,197,2,11,27,248,22,172,13,248,22,68,23,199,2,27,249,22,165,13,23, +196,1,23,197,2,28,248,22,159,13,23,194,2,250,2,53,198,199,195,87,94, 23,193,1,27,248,22,69,23,200,1,28,248,22,75,23,194,2,11,27,248,22, -178,13,248,22,68,23,196,2,27,249,22,171,13,23,196,1,23,200,2,28,248, -22,165,13,23,194,2,250,2,53,201,202,195,87,94,23,193,1,27,248,22,69, -23,197,1,28,248,22,75,23,194,2,11,27,248,22,178,13,248,22,68,23,196, -2,27,249,22,171,13,23,196,1,23,203,2,28,248,22,165,13,23,194,2,250, +172,13,248,22,68,23,196,2,27,249,22,165,13,23,196,1,23,200,2,28,248, +22,159,13,23,194,2,250,2,53,201,202,195,87,94,23,193,1,27,248,22,69, +23,197,1,28,248,22,75,23,194,2,11,27,248,22,172,13,248,22,68,23,196, +2,27,249,22,165,13,23,196,1,23,203,2,28,248,22,159,13,23,194,2,250, 2,53,204,205,195,87,94,23,193,1,27,248,22,69,23,197,1,28,248,22,75, -23,194,2,11,27,248,22,178,13,248,22,68,23,196,2,27,249,22,171,13,23, -196,1,23,206,2,28,248,22,165,13,23,194,2,250,2,53,23,15,23,16,195, +23,194,2,11,27,248,22,172,13,248,22,68,23,196,2,27,249,22,165,13,23, +196,1,23,206,2,28,248,22,159,13,23,194,2,250,2,53,23,15,23,16,195, 87,94,23,193,1,27,248,22,69,23,197,1,28,248,22,75,23,194,2,11,27, -248,22,178,13,248,22,68,23,196,2,27,249,22,171,13,23,196,1,23,209,2, -28,248,22,165,13,23,194,2,250,2,53,23,18,23,19,195,87,94,23,193,1, -27,248,22,69,23,197,1,28,248,22,75,23,194,2,11,27,248,22,178,13,248, -22,68,195,27,249,22,171,13,23,196,1,23,19,28,248,22,165,13,193,250,2, +248,22,172,13,248,22,68,23,196,2,27,249,22,165,13,23,196,1,23,209,2, +28,248,22,159,13,23,194,2,250,2,53,23,18,23,19,195,87,94,23,193,1, +27,248,22,69,23,197,1,28,248,22,75,23,194,2,11,27,248,22,172,13,248, +22,68,195,27,249,22,165,13,23,196,1,23,19,28,248,22,159,13,193,250,2, 53,23,21,23,22,195,251,2,55,23,21,23,22,23,23,248,22,69,199,87,95, -28,27,248,22,153,13,23,196,2,28,23,193,2,192,87,94,23,193,1,28,248, -22,168,6,23,196,2,27,248,22,175,13,23,197,2,28,23,193,2,192,87,94, -23,193,1,248,22,176,13,23,197,2,11,12,250,22,141,9,2,14,6,25,25, +28,27,248,22,147,13,23,196,2,28,23,193,2,192,87,94,23,193,1,28,248, +22,162,6,23,196,2,27,248,22,169,13,23,197,2,28,23,193,2,192,87,94, +23,193,1,248,22,170,13,23,197,2,11,12,250,22,135,9,2,14,6,25,25, 112,97,116,104,32,111,114,32,115,116,114,105,110,103,32,40,115,97,110,115,32, -110,117,108,41,23,197,2,28,28,23,195,2,28,27,248,22,153,13,23,197,2, -28,23,193,2,192,87,94,23,193,1,28,248,22,168,6,23,197,2,27,248,22, -175,13,23,198,2,28,23,193,2,192,87,94,23,193,1,248,22,176,13,23,198, -2,11,248,22,175,13,23,196,2,11,10,12,250,22,141,9,2,14,6,29,29, +110,117,108,41,23,197,2,28,28,23,195,2,28,27,248,22,147,13,23,197,2, +28,23,193,2,192,87,94,23,193,1,28,248,22,162,6,23,197,2,27,248,22, +169,13,23,198,2,28,23,193,2,192,87,94,23,193,1,248,22,170,13,23,198, +2,11,248,22,169,13,23,196,2,11,10,12,250,22,135,9,2,14,6,29,29, 35,102,32,111,114,32,114,101,108,97,116,105,118,101,32,112,97,116,104,32,111, -114,32,115,116,114,105,110,103,23,198,2,28,28,248,22,175,13,23,195,2,91, -159,38,11,90,161,38,35,11,248,22,174,13,23,198,2,249,22,173,8,194,68, -114,101,108,97,116,105,118,101,11,27,248,22,185,7,6,4,4,80,65,84,72, -27,28,23,194,2,27,249,80,159,40,47,37,23,197,1,9,28,249,22,173,8, -247,22,187,7,2,20,249,22,67,248,22,162,13,5,1,46,194,192,87,94,23, -194,1,9,28,248,22,75,23,194,2,11,27,248,22,178,13,248,22,68,23,196, -2,27,249,22,171,13,23,196,1,23,200,2,28,248,22,165,13,23,194,2,250, +114,32,115,116,114,105,110,103,23,198,2,28,28,248,22,169,13,23,195,2,91, +159,38,11,90,161,38,35,11,248,22,168,13,23,198,2,249,22,167,8,194,68, +114,101,108,97,116,105,118,101,11,27,248,22,179,7,6,4,4,80,65,84,72, +27,28,23,194,2,27,249,80,159,40,47,37,23,197,1,9,28,249,22,167,8, +247,22,181,7,2,20,249,22,67,248,22,156,13,5,1,46,194,192,87,94,23, +194,1,9,28,248,22,75,23,194,2,11,27,248,22,172,13,248,22,68,23,196, +2,27,249,22,165,13,23,196,1,23,200,2,28,248,22,159,13,23,194,2,250, 2,53,201,202,195,87,94,23,193,1,27,248,22,69,23,197,1,28,248,22,75, -23,194,2,11,27,248,22,178,13,248,22,68,23,196,2,27,249,22,171,13,23, -196,1,23,203,2,28,248,22,165,13,23,194,2,250,2,53,204,205,195,87,94, +23,194,2,11,27,248,22,172,13,248,22,68,23,196,2,27,249,22,165,13,23, +196,1,23,203,2,28,248,22,159,13,23,194,2,250,2,53,204,205,195,87,94, 23,193,1,27,248,22,69,23,197,1,28,248,22,75,23,194,2,11,27,248,22, -178,13,248,22,68,195,27,249,22,171,13,23,196,1,205,28,248,22,165,13,193, +172,13,248,22,68,195,27,249,22,165,13,23,196,1,205,28,248,22,159,13,193, 250,2,53,23,15,23,16,195,251,2,55,23,15,23,16,23,17,248,22,69,199, -27,248,22,178,13,23,196,1,28,248,22,165,13,193,250,2,53,198,199,195,11, +27,248,22,172,13,23,196,1,28,248,22,159,13,193,250,2,53,198,199,195,11, 250,80,159,38,48,36,196,197,11,250,80,159,38,48,36,196,11,11,87,94,249, -22,159,6,247,22,131,5,195,248,22,185,5,249,22,180,3,35,249,22,164,3, +22,153,6,247,22,189,4,195,248,22,179,5,249,22,174,3,35,249,22,158,3, 197,198,27,28,23,197,2,87,95,23,196,1,23,195,1,23,197,1,87,94,23, -197,1,27,248,22,129,14,2,19,27,249,80,159,40,48,36,23,196,1,11,27, -27,248,22,183,3,23,200,1,28,192,192,35,27,27,248,22,183,3,23,202,1, -28,192,192,35,249,22,162,5,23,197,1,83,158,39,20,97,95,89,162,8,44, -35,47,9,224,3,2,33,60,23,195,1,23,196,1,27,248,22,147,5,23,195, +197,1,27,248,22,187,13,2,19,27,249,80,159,40,48,36,23,196,1,11,27, +27,248,22,177,3,23,200,1,28,192,192,35,27,27,248,22,177,3,23,202,1, +28,192,192,35,249,22,156,5,23,197,1,83,158,39,20,97,95,89,162,8,44, +35,47,9,224,3,2,33,60,23,195,1,23,196,1,27,248,22,141,5,23,195, 1,248,80,159,38,53,36,193,159,35,20,102,159,35,16,1,11,16,0,83,158, 41,20,100,144,67,35,37,117,116,105,108,115,29,11,11,11,11,11,10,42,80, 158,35,35,20,102,159,37,16,17,2,1,2,2,2,3,2,4,2,5,2,6, @@ -403,7 +403,7 @@ 17,83,158,35,16,2,89,162,43,36,48,2,18,223,0,33,29,80,159,35,53, 36,83,158,35,16,2,89,162,8,44,36,55,2,18,223,0,33,30,80,159,35, 52,36,83,158,35,16,2,32,0,89,162,43,36,44,2,1,222,33,31,80,159, -35,35,36,83,158,35,16,2,249,22,170,6,7,92,7,92,80,159,35,36,36, +35,35,36,83,158,35,16,2,249,22,164,6,7,92,7,92,80,159,35,36,36, 83,158,35,16,2,89,162,43,36,53,2,3,223,0,33,32,80,159,35,37,36, 83,158,35,16,2,32,0,89,162,8,44,37,49,2,4,222,33,33,80,159,35, 38,36,83,158,35,16,2,32,0,89,162,8,44,38,50,2,5,222,33,35,80, @@ -416,8 +416,8 @@ 43,2,11,222,33,46,80,159,35,45,36,83,158,35,16,2,83,158,38,20,96, 96,2,12,89,162,43,35,43,9,223,0,33,47,89,162,43,36,44,9,223,0, 33,48,89,162,43,37,54,9,223,0,33,49,80,159,35,46,36,83,158,35,16, -2,27,248,22,136,14,248,22,179,7,27,28,249,22,173,8,247,22,187,7,2, -20,6,1,1,59,6,1,1,58,250,22,152,7,6,14,14,40,91,94,126,97, +2,27,248,22,130,14,248,22,173,7,27,28,249,22,167,8,247,22,181,7,2, +20,6,1,1,59,6,1,1,58,250,22,146,7,6,14,14,40,91,94,126,97, 93,42,41,126,97,40,46,42,41,23,196,2,23,196,1,89,162,8,44,37,47, 2,13,223,0,33,52,80,159,35,47,36,83,158,35,16,2,83,158,38,20,96, 96,2,14,89,162,43,38,59,9,223,0,33,57,89,162,43,37,46,9,223,0, @@ -428,7 +428,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 6834); } { - static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,52,46,50,46,51,46,55,8,0,0,0,1,0,0,6,0,19,0, + static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,52,46,50,46,51,46,56,8,0,0,0,1,0,0,6,0,19,0, 34,0,48,0,62,0,76,0,118,0,0,0,38,1,0,0,65,113,117,111,116, 101,29,94,2,1,67,35,37,117,116,105,108,115,11,29,94,2,1,69,35,37, 110,101,116,119,111,114,107,11,29,94,2,1,68,35,37,112,97,114,97,109,122, @@ -447,7 +447,7 @@ EVAL_ONE_SIZED_STR((char *)expr, 331); } { - static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,52,46,50,46,51,46,55,55,0,0,0,1,0,0,11,0,38,0, + static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,52,46,50,46,51,46,56,55,0,0,0,1,0,0,11,0,38,0, 44,0,57,0,66,0,73,0,95,0,117,0,143,0,155,0,173,0,193,0,205, 0,221,0,244,0,0,1,31,1,38,1,43,1,48,1,53,1,58,1,67,1, 72,1,76,1,84,1,93,1,101,1,146,1,166,1,195,1,226,1,26,2,36, @@ -471,50 +471,50 @@ 3,46,122,111,6,6,6,110,97,116,105,118,101,64,108,111,111,112,63,108,105, 98,67,105,103,110,111,114,101,100,249,22,14,195,80,159,37,45,37,249,80,159, 37,48,36,195,10,20,14,159,80,158,35,39,250,80,158,38,40,249,22,27,11, -80,158,40,39,22,136,5,28,248,22,153,13,23,198,2,23,197,1,87,94,23, -197,1,247,22,130,14,247,194,250,22,171,13,23,197,1,23,199,1,249,80,158, -42,38,23,198,1,2,22,252,22,171,13,23,199,1,23,201,1,2,23,247,22, -188,7,249,80,158,44,38,23,200,1,80,159,44,35,37,87,94,23,194,1,27, -250,22,188,13,196,11,32,0,89,162,8,44,35,40,9,222,11,28,192,249,22, -67,195,194,11,27,252,22,171,13,23,200,1,23,202,1,2,23,247,22,188,7, -249,80,158,45,38,23,201,1,80,159,45,35,37,27,250,22,188,13,196,11,32, +80,158,40,39,22,130,5,28,248,22,147,13,23,198,2,23,197,1,87,94,23, +197,1,247,22,188,13,247,194,250,22,165,13,23,197,1,23,199,1,249,80,158, +42,38,23,198,1,2,22,252,22,165,13,23,199,1,23,201,1,2,23,247,22, +182,7,249,80,158,44,38,23,200,1,80,159,44,35,37,87,94,23,194,1,27, +250,22,182,13,196,11,32,0,89,162,8,44,35,40,9,222,11,28,192,249,22, +67,195,194,11,27,252,22,165,13,23,200,1,23,202,1,2,23,247,22,182,7, +249,80,158,45,38,23,201,1,80,159,45,35,37,27,250,22,182,13,196,11,32, 0,89,162,8,44,35,40,9,222,11,28,192,249,22,67,195,194,11,249,247,22, -135,14,248,22,68,195,195,27,250,22,171,13,23,198,1,23,200,1,249,80,158, -43,38,23,199,1,2,22,27,250,22,188,13,196,11,32,0,89,162,8,44,35, -40,9,222,11,28,192,249,22,67,195,194,11,249,247,22,134,5,248,22,68,195, -195,249,247,22,134,5,194,195,87,94,28,248,80,158,36,37,23,195,2,12,250, -22,141,9,77,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100, +129,14,248,22,68,195,195,27,250,22,165,13,23,198,1,23,200,1,249,80,158, +43,38,23,199,1,2,22,27,250,22,182,13,196,11,32,0,89,162,8,44,35, +40,9,222,11,28,192,249,22,67,195,194,11,249,247,22,128,5,248,22,68,195, +195,249,247,22,128,5,194,195,87,94,28,248,80,158,36,37,23,195,2,12,250, +22,135,9,77,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100, 6,25,25,112,97,116,104,32,111,114,32,118,97,108,105,100,45,112,97,116,104, 32,115,116,114,105,110,103,23,197,2,91,159,41,11,90,161,36,35,11,28,248, -22,177,13,23,201,2,23,200,1,27,247,22,136,5,28,23,193,2,249,22,178, -13,23,203,1,23,195,1,200,90,161,38,36,11,248,22,174,13,23,194,2,87, -94,23,196,1,90,161,36,39,11,28,249,22,173,8,23,196,2,68,114,101,108, +22,171,13,23,201,2,23,200,1,27,247,22,130,5,28,23,193,2,249,22,172, +13,23,203,1,23,195,1,200,90,161,38,36,11,248,22,168,13,23,194,2,87, +94,23,196,1,90,161,36,39,11,28,249,22,167,8,23,196,2,68,114,101,108, 97,116,105,118,101,87,94,23,194,1,2,21,23,194,1,90,161,36,40,11,247, -22,132,14,27,89,162,43,36,49,62,122,111,225,7,5,3,33,30,27,89,162, +22,190,13,27,89,162,43,36,49,62,122,111,225,7,5,3,33,30,27,89,162, 43,36,51,9,225,8,6,4,33,31,27,249,22,5,89,162,8,44,36,46,9, 223,5,33,32,23,203,2,27,28,23,195,1,27,249,22,5,89,162,8,44,36, 52,9,225,13,11,9,33,33,23,205,2,27,28,23,196,2,11,193,28,192,192, -28,193,28,23,196,2,28,249,22,176,3,248,22,69,196,248,22,69,23,199,2, +28,193,28,23,196,2,28,249,22,170,3,248,22,69,196,248,22,69,23,199,2, 193,11,11,11,11,28,23,193,2,249,80,159,47,58,36,202,89,162,43,35,45, 9,224,14,2,33,34,87,94,23,193,1,27,28,23,197,1,27,249,22,5,83, 158,39,20,97,94,89,162,8,44,36,50,9,225,14,12,10,33,35,23,203,1, -23,206,1,27,28,196,11,193,28,192,192,28,193,28,196,28,249,22,176,3,248, +23,206,1,27,28,196,11,193,28,192,192,28,193,28,196,28,249,22,170,3,248, 22,69,196,248,22,69,199,193,11,11,11,11,28,192,249,80,159,48,58,36,203, 89,162,43,35,45,9,224,15,2,33,36,249,80,159,48,58,36,203,89,162,43, 35,44,9,224,15,7,33,37,0,17,35,114,120,34,94,40,46,42,63,41,47, 40,46,42,41,36,34,32,40,89,162,8,44,36,8,39,2,24,222,33,41,27, -249,22,140,14,2,39,23,196,2,28,23,193,2,87,94,23,194,1,249,22,67, -248,22,92,23,196,2,27,248,22,101,23,197,1,27,249,22,140,14,2,39,23, +249,22,134,14,2,39,23,196,2,28,23,193,2,87,94,23,194,1,249,22,67, +248,22,92,23,196,2,27,248,22,101,23,197,1,27,249,22,134,14,2,39,23, 196,2,28,23,193,2,87,94,23,194,1,249,22,67,248,22,92,23,196,2,27, -248,22,101,23,197,1,27,249,22,140,14,2,39,23,196,2,28,23,193,2,87, +248,22,101,23,197,1,27,249,22,134,14,2,39,23,196,2,28,23,193,2,87, 94,23,194,1,249,22,67,248,22,92,23,196,2,27,248,22,101,23,197,1,27, -249,22,140,14,2,39,23,196,2,28,23,193,2,87,94,23,194,1,249,22,67, -248,22,92,23,196,2,27,248,22,101,23,197,1,27,249,22,140,14,2,39,23, +249,22,134,14,2,39,23,196,2,28,23,193,2,87,94,23,194,1,249,22,67, +248,22,92,23,196,2,27,248,22,101,23,197,1,27,249,22,134,14,2,39,23, 196,2,28,23,193,2,87,94,23,194,1,249,22,67,248,22,92,23,196,2,27, -248,22,101,23,197,1,27,249,22,140,14,2,39,23,196,2,28,23,193,2,87, +248,22,101,23,197,1,27,249,22,134,14,2,39,23,196,2,28,23,193,2,87, 94,23,194,1,249,22,67,248,22,92,23,196,2,27,248,22,101,23,197,1,27, -249,22,140,14,2,39,23,196,2,28,23,193,2,87,94,23,194,1,249,22,67, -248,22,92,23,196,2,27,248,22,101,23,197,1,27,249,22,140,14,2,39,23, +249,22,134,14,2,39,23,196,2,28,23,193,2,87,94,23,194,1,249,22,67, +248,22,92,23,196,2,27,248,22,101,23,197,1,27,249,22,134,14,2,39,23, 196,2,28,23,193,2,87,94,23,194,1,249,22,67,248,22,92,23,196,2,248, 2,40,248,22,101,23,197,1,248,22,77,194,248,22,77,194,248,22,77,194,248, 22,77,194,248,22,77,194,248,22,77,194,248,22,77,194,248,22,77,194,32,42, @@ -531,12 +531,12 @@ 67,248,22,68,199,196,195,249,22,7,249,22,67,248,22,68,199,196,195,249,22, 7,249,22,67,248,22,68,199,196,195,249,22,7,249,22,67,248,22,68,199,196, 195,249,22,7,249,22,67,248,22,68,199,196,195,249,22,7,249,22,67,248,22, -68,199,196,195,27,27,249,22,140,14,2,39,23,197,2,28,23,193,2,87,94, +68,199,196,195,27,27,249,22,134,14,2,39,23,197,2,28,23,193,2,87,94, 23,195,1,249,22,67,248,22,92,23,196,2,27,248,22,101,23,197,1,27,249, -22,140,14,2,39,23,196,2,28,23,193,2,87,94,23,194,1,249,22,67,248, -22,92,23,196,2,27,248,22,101,23,197,1,27,249,22,140,14,2,39,23,196, +22,134,14,2,39,23,196,2,28,23,193,2,87,94,23,194,1,249,22,67,248, +22,92,23,196,2,27,248,22,101,23,197,1,27,249,22,134,14,2,39,23,196, 2,28,23,193,2,87,94,23,194,1,249,22,67,248,22,92,23,196,2,27,248, -22,101,23,197,1,27,249,22,140,14,2,39,23,196,2,28,23,193,2,87,94, +22,101,23,197,1,27,249,22,134,14,2,39,23,196,2,28,23,193,2,87,94, 23,194,1,249,22,67,248,22,92,23,196,2,248,2,40,248,22,101,23,197,1, 248,22,77,194,248,22,77,194,248,22,77,194,248,22,77,195,28,23,195,1,192, 28,248,22,75,248,22,69,23,195,2,249,22,7,9,248,22,68,195,91,159,37, @@ -545,109 +545,109 @@ 196,28,248,22,75,248,22,69,23,195,2,249,22,7,9,248,22,68,195,91,159, 37,11,90,161,37,35,11,248,2,42,248,22,69,196,249,22,7,249,22,67,248, 22,68,199,196,195,249,22,7,249,22,67,248,22,68,199,196,195,249,22,7,249, -22,67,248,22,68,199,196,195,87,95,28,248,22,180,4,195,12,250,22,141,9, +22,67,248,22,68,199,196,195,87,95,28,248,22,174,4,195,12,250,22,135,9, 2,17,6,20,20,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45, 112,97,116,104,197,28,24,193,2,248,24,194,1,195,87,94,23,193,1,12,27, -27,250,22,141,2,80,159,41,42,37,248,22,160,14,247,22,135,12,11,28,23, +27,250,22,141,2,80,159,41,42,37,248,22,154,14,247,22,129,12,11,28,23, 193,2,192,87,94,23,193,1,27,247,22,125,87,94,250,22,139,2,80,159,42, -42,37,248,22,160,14,247,22,135,12,195,192,250,22,139,2,195,198,66,97,116, -116,97,99,104,251,211,197,198,199,10,28,192,250,22,140,9,11,196,195,248,22, -138,9,194,28,249,22,174,6,194,6,1,1,46,2,21,28,249,22,174,6,194, -6,2,2,46,46,62,117,112,192,28,249,22,175,8,248,22,69,23,200,2,23, -197,1,28,249,22,173,8,248,22,68,23,200,2,23,196,1,251,22,138,9,2, +42,37,248,22,154,14,247,22,129,12,195,192,250,22,139,2,195,198,66,97,116, +116,97,99,104,251,211,197,198,199,10,28,192,250,22,134,9,11,196,195,248,22, +132,9,194,28,249,22,168,6,194,6,1,1,46,2,21,28,249,22,168,6,194, +6,2,2,46,46,62,117,112,192,28,249,22,169,8,248,22,69,23,200,2,23, +197,1,28,249,22,167,8,248,22,68,23,200,2,23,196,1,251,22,132,9,2, 17,6,26,26,99,121,99,108,101,32,105,110,32,108,111,97,100,105,110,103,32, 97,116,32,126,101,58,32,126,101,23,200,1,249,22,2,22,69,248,22,82,249, 22,67,23,206,1,23,202,1,12,12,247,192,20,14,159,80,159,39,44,37,249, -22,67,248,22,160,14,247,22,135,12,23,197,1,20,14,159,80,158,39,39,250, -80,158,42,40,249,22,27,11,80,158,44,39,22,162,4,23,196,1,249,247,22, -135,5,23,198,1,248,22,55,248,22,157,13,23,198,1,87,94,28,28,248,22, -153,13,23,196,2,10,248,22,186,4,23,196,2,12,28,23,197,2,250,22,140, +22,67,248,22,154,14,247,22,129,12,23,197,1,20,14,159,80,158,39,39,250, +80,158,42,40,249,22,27,11,80,158,44,39,22,156,4,23,196,1,249,247,22, +129,5,23,198,1,248,22,55,248,22,151,13,23,198,1,87,94,28,28,248,22, +147,13,23,196,2,10,248,22,180,4,23,196,2,12,28,23,197,2,250,22,134, 9,11,6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97,116,104,23, -200,2,250,22,141,9,2,17,6,19,19,109,111,100,117,108,101,45,112,97,116, +200,2,250,22,135,9,2,17,6,19,19,109,111,100,117,108,101,45,112,97,116, 104,32,111,114,32,112,97,116,104,23,198,2,28,28,248,22,65,23,196,2,249, -22,173,8,248,22,68,23,198,2,2,3,11,248,22,181,4,248,22,92,196,28, -28,248,22,65,23,196,2,249,22,173,8,248,22,68,23,198,2,66,112,108,97, +22,167,8,248,22,68,23,198,2,2,3,11,248,22,175,4,248,22,92,196,28, +28,248,22,65,23,196,2,249,22,167,8,248,22,68,23,198,2,66,112,108,97, 110,101,116,11,87,94,28,207,12,20,14,159,80,158,36,51,80,158,36,49,90, -161,36,35,10,249,22,163,4,21,94,2,25,6,18,18,112,108,97,110,101,116, +161,36,35,10,249,22,157,4,21,94,2,25,6,18,18,112,108,97,110,101,116, 47,114,101,115,111,108,118,101,114,46,115,115,1,27,112,108,97,110,101,116,45, 109,111,100,117,108,101,45,110,97,109,101,45,114,101,115,111,108,118,101,114,12, 252,212,199,200,201,202,80,158,41,49,87,94,23,193,1,27,89,162,8,44,36, 45,79,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110,45,101,114,114, 223,5,33,47,27,28,248,22,53,23,198,2,27,250,22,141,2,80,159,42,43, -37,249,22,67,23,203,2,247,22,131,14,11,28,23,193,2,192,87,94,23,193, +37,249,22,67,23,203,2,247,22,189,13,11,28,23,193,2,192,87,94,23,193, 1,91,159,37,11,90,161,37,35,11,249,80,159,43,48,36,248,22,58,23,203, 2,11,27,251,80,158,46,52,2,17,23,202,1,28,248,22,75,23,199,2,23, 199,2,248,22,68,23,199,2,28,248,22,75,23,199,2,9,248,22,69,23,199, -2,249,22,171,13,23,195,1,28,248,22,75,23,197,1,87,94,23,197,1,6, -7,7,109,97,105,110,46,115,115,249,22,191,6,23,199,1,6,3,3,46,115, -115,28,248,22,168,6,23,198,2,87,94,23,194,1,27,27,28,23,200,2,28, -249,22,173,8,23,202,2,80,158,42,46,80,158,40,47,27,248,22,182,4,23, -202,2,28,248,22,153,13,23,194,2,91,159,38,11,90,161,38,35,11,248,22, -174,13,23,197,1,87,95,83,160,37,11,80,158,44,46,23,204,2,83,160,37, +2,249,22,165,13,23,195,1,28,248,22,75,23,197,1,87,94,23,197,1,6, +7,7,109,97,105,110,46,115,115,249,22,185,6,23,199,1,6,3,3,46,115, +115,28,248,22,162,6,23,198,2,87,94,23,194,1,27,27,28,23,200,2,28, +249,22,167,8,23,202,2,80,158,42,46,80,158,40,47,27,248,22,176,4,23, +202,2,28,248,22,147,13,23,194,2,91,159,38,11,90,161,38,35,11,248,22, +168,13,23,197,1,87,95,83,160,37,11,80,158,44,46,23,204,2,83,160,37, 11,80,158,44,47,192,192,11,11,28,23,193,2,192,87,94,23,193,1,27,247, -22,136,5,28,23,193,2,192,87,94,23,193,1,247,22,130,14,27,250,22,141, +22,130,5,28,23,193,2,192,87,94,23,193,1,247,22,188,13,27,250,22,141, 2,80,159,43,43,37,249,22,67,23,204,2,23,199,2,11,28,23,193,2,192, 87,94,23,193,1,91,159,37,11,90,161,37,35,11,249,80,159,44,48,36,23, -203,2,11,250,22,1,22,171,13,23,199,1,249,22,81,249,22,2,32,0,89, +203,2,11,250,22,1,22,165,13,23,199,1,249,22,81,249,22,2,32,0,89, 162,8,44,36,43,9,222,33,48,23,200,1,248,22,77,23,200,1,28,248,22, -153,13,23,198,2,87,94,23,194,1,28,248,22,176,13,23,198,2,23,197,2, +147,13,23,198,2,87,94,23,194,1,28,248,22,170,13,23,198,2,23,197,2, 248,22,77,6,26,26,32,40,97,32,112,97,116,104,32,109,117,115,116,32,98, -101,32,97,98,115,111,108,117,116,101,41,28,249,22,173,8,248,22,68,23,200, +101,32,97,98,115,111,108,117,116,101,41,28,249,22,167,8,248,22,68,23,200, 2,2,25,27,250,22,141,2,80,159,42,43,37,249,22,67,23,203,2,247,22, -131,14,11,28,23,193,2,192,87,94,23,193,1,91,159,38,11,90,161,37,35, +189,13,11,28,23,193,2,192,87,94,23,193,1,91,159,38,11,90,161,37,35, 11,249,80,159,44,48,36,248,22,92,23,204,2,11,90,161,36,37,11,28,248, -22,75,248,22,94,23,203,2,28,248,22,75,23,194,2,249,22,142,14,0,8, +22,75,248,22,94,23,203,2,28,248,22,75,23,194,2,249,22,136,14,0,8, 35,114,120,34,91,46,93,34,23,196,2,11,10,27,27,28,23,197,2,249,22, 81,28,248,22,75,248,22,94,23,207,2,21,93,6,5,5,109,122,108,105,98, 249,22,1,22,81,249,22,2,80,159,50,59,36,248,22,94,23,210,2,23,197, 2,28,248,22,75,23,196,2,248,22,77,23,197,2,23,195,2,251,80,158,48, -52,2,17,23,204,1,248,22,68,23,198,2,248,22,69,23,198,1,249,22,171, +52,2,17,23,204,1,248,22,68,23,198,2,248,22,69,23,198,1,249,22,165, 13,23,195,1,28,23,198,1,87,94,23,196,1,23,197,1,28,248,22,75,23, -197,1,87,94,23,197,1,6,7,7,109,97,105,110,46,115,115,28,249,22,142, -14,0,8,35,114,120,34,91,46,93,34,23,199,2,23,197,1,249,22,191,6, -23,199,1,6,3,3,46,115,115,28,249,22,173,8,248,22,68,23,200,2,64, -102,105,108,101,249,22,178,13,248,22,182,13,248,22,92,23,201,2,27,28,23, -201,2,28,249,22,173,8,23,203,2,80,158,43,46,80,158,41,47,27,248,22, -182,4,23,203,2,28,248,22,153,13,23,194,2,91,159,38,11,90,161,38,35, -11,248,22,174,13,23,197,1,87,95,83,160,37,11,80,158,45,46,23,205,2, +197,1,87,94,23,197,1,6,7,7,109,97,105,110,46,115,115,28,249,22,136, +14,0,8,35,114,120,34,91,46,93,34,23,199,2,23,197,1,249,22,185,6, +23,199,1,6,3,3,46,115,115,28,249,22,167,8,248,22,68,23,200,2,64, +102,105,108,101,249,22,172,13,248,22,176,13,248,22,92,23,201,2,27,28,23, +201,2,28,249,22,167,8,23,203,2,80,158,43,46,80,158,41,47,27,248,22, +176,4,23,203,2,28,248,22,147,13,23,194,2,91,159,38,11,90,161,38,35, +11,248,22,168,13,23,197,1,87,95,83,160,37,11,80,158,45,46,23,205,2, 83,160,37,11,80,158,45,47,192,192,11,11,28,23,193,2,192,87,94,23,193, -1,27,247,22,136,5,28,23,193,2,192,87,94,23,193,1,247,22,130,14,12, -87,94,28,28,248,22,153,13,23,194,2,10,248,22,190,7,23,194,2,87,94, -23,199,1,12,28,23,199,2,250,22,140,9,67,114,101,113,117,105,114,101,249, -22,152,7,6,17,17,98,97,100,32,109,111,100,117,108,101,32,112,97,116,104, +1,27,247,22,130,5,28,23,193,2,192,87,94,23,193,1,247,22,188,13,12, +87,94,28,28,248,22,147,13,23,194,2,10,248,22,184,7,23,194,2,87,94, +23,199,1,12,28,23,199,2,250,22,134,9,67,114,101,113,117,105,114,101,249, +22,146,7,6,17,17,98,97,100,32,109,111,100,117,108,101,32,112,97,116,104, 126,97,28,23,198,2,248,22,68,23,199,2,6,0,0,23,202,1,87,94,23, -199,1,250,22,141,9,2,17,249,22,152,7,6,13,13,109,111,100,117,108,101, +199,1,250,22,135,9,2,17,249,22,146,7,6,13,13,109,111,100,117,108,101, 32,112,97,116,104,126,97,28,23,198,2,248,22,68,23,199,2,6,0,0,23, -200,2,27,28,248,22,190,7,23,195,2,249,22,131,8,23,196,2,35,249,22, -180,13,248,22,181,13,23,197,2,11,27,28,248,22,190,7,23,196,2,249,22, -131,8,23,197,2,36,248,80,158,41,53,23,195,2,91,159,38,11,90,161,38, -35,11,28,248,22,190,7,23,199,2,250,22,7,2,26,249,22,131,8,23,203, -2,37,2,26,248,22,174,13,23,198,2,87,95,23,195,1,23,193,1,27,28, -248,22,190,7,23,200,2,249,22,131,8,23,201,2,38,249,80,158,46,54,23, -197,2,5,0,27,28,248,22,190,7,23,201,2,249,22,131,8,23,202,2,39, -248,22,181,4,23,200,2,27,27,250,22,141,2,80,159,50,42,37,248,22,160, -14,247,22,135,12,11,28,23,193,2,192,87,94,23,193,1,27,247,22,125,87, -94,250,22,139,2,80,159,51,42,37,248,22,160,14,247,22,135,12,195,192,87, +200,2,27,28,248,22,184,7,23,195,2,249,22,189,7,23,196,2,35,249,22, +174,13,248,22,175,13,23,197,2,11,27,28,248,22,184,7,23,196,2,249,22, +189,7,23,197,2,36,248,80,158,41,53,23,195,2,91,159,38,11,90,161,38, +35,11,28,248,22,184,7,23,199,2,250,22,7,2,26,249,22,189,7,23,203, +2,37,2,26,248,22,168,13,23,198,2,87,95,23,195,1,23,193,1,27,28, +248,22,184,7,23,200,2,249,22,189,7,23,201,2,38,249,80,158,46,54,23, +197,2,5,0,27,28,248,22,184,7,23,201,2,249,22,189,7,23,202,2,39, +248,22,175,4,23,200,2,27,27,250,22,141,2,80,159,50,42,37,248,22,154, +14,247,22,129,12,11,28,23,193,2,192,87,94,23,193,1,27,247,22,125,87, +94,250,22,139,2,80,159,51,42,37,248,22,154,14,247,22,129,12,195,192,87, 95,28,23,208,1,27,250,22,141,2,23,197,2,197,11,28,23,193,1,12,87, 95,27,27,28,248,22,17,80,159,50,45,37,80,159,49,45,37,247,22,19,250, -22,25,248,22,23,23,197,2,80,159,52,44,37,23,196,1,27,248,22,160,14, -247,22,135,12,249,22,3,83,158,39,20,97,94,89,162,8,44,36,54,9,226, +22,25,248,22,23,23,197,2,80,159,52,44,37,23,196,1,27,248,22,154,14, +247,22,129,12,249,22,3,83,158,39,20,97,94,89,162,8,44,36,54,9,226, 12,11,2,3,33,49,23,195,1,23,196,1,248,28,248,22,17,80,159,49,45, 37,32,0,89,162,43,36,41,9,222,33,50,80,159,48,8,25,36,89,162,43, 35,50,9,227,13,9,8,4,3,33,51,250,22,139,2,23,197,1,197,10,12, -28,28,248,22,190,7,23,202,1,11,27,248,22,168,6,23,207,2,28,192,192, -27,248,22,53,23,208,2,28,192,192,28,248,22,65,23,208,2,249,22,173,8, +28,28,248,22,184,7,23,202,1,11,27,248,22,162,6,23,207,2,28,192,192, +27,248,22,53,23,208,2,28,192,192,28,248,22,65,23,208,2,249,22,167,8, 248,22,68,23,210,2,2,25,11,250,22,139,2,80,159,49,43,37,28,248,22, -168,6,23,209,2,249,22,67,23,210,1,27,28,23,212,2,28,249,22,173,8, -23,214,2,80,158,54,46,87,94,23,212,1,80,158,52,47,27,248,22,182,4, -23,214,2,28,248,22,153,13,23,194,2,91,159,38,11,90,161,38,35,11,248, -22,174,13,23,197,1,87,95,83,160,37,11,80,158,56,46,23,23,83,160,37, +162,6,23,209,2,249,22,67,23,210,1,27,28,23,212,2,28,249,22,167,8, +23,214,2,80,158,54,46,87,94,23,212,1,80,158,52,47,27,248,22,176,4, +23,214,2,28,248,22,147,13,23,194,2,91,159,38,11,90,161,38,35,11,248, +22,168,13,23,197,1,87,95,83,160,37,11,80,158,56,46,23,23,83,160,37, 11,80,158,56,47,192,192,11,11,28,23,193,2,192,87,94,23,193,1,27,247, -22,136,5,28,23,193,2,192,87,94,23,193,1,247,22,130,14,249,22,67,23, -210,1,247,22,131,14,252,22,128,8,23,208,1,23,207,1,23,205,1,23,203, +22,130,5,28,23,193,2,192,87,94,23,193,1,247,22,188,13,249,22,67,23, +210,1,247,22,189,13,252,22,186,7,23,208,1,23,207,1,23,205,1,23,203, 1,201,12,193,87,96,83,160,37,11,80,158,35,49,248,80,158,36,57,249,22, -27,11,80,158,38,51,248,22,161,4,80,159,36,50,37,248,22,135,5,80,159, -36,36,36,248,22,190,12,80,159,36,41,36,83,160,37,11,80,158,35,49,248, +27,11,80,158,38,51,248,22,155,4,80,159,36,50,37,248,22,129,5,80,159, +36,36,36,248,22,184,12,80,159,36,41,36,83,160,37,11,80,158,35,49,248, 80,158,36,57,249,22,27,11,80,158,38,51,159,35,20,102,159,35,16,1,11, 16,0,83,158,41,20,100,144,66,35,37,98,111,111,116,29,11,11,11,11,11, 10,37,80,158,35,35,20,102,159,38,16,23,2,1,2,2,30,2,4,72,112, @@ -667,7 +667,7 @@ 9,223,0,33,27,80,159,35,8,25,36,83,158,35,16,2,89,162,43,36,44, 9,223,0,33,28,80,159,35,59,36,83,158,35,16,2,89,162,43,37,48,68, 119,105,116,104,45,100,105,114,223,0,33,29,80,159,35,58,36,83,158,35,16, -2,248,22,187,7,69,115,111,45,115,117,102,102,105,120,80,159,35,35,36,83, +2,248,22,181,7,69,115,111,45,115,117,102,102,105,120,80,159,35,35,36,83, 158,35,16,2,89,162,43,37,59,2,2,223,0,33,38,80,159,35,36,36,83, 158,35,16,2,32,0,89,162,8,44,36,41,2,8,222,192,80,159,35,41,36, 83,158,35,16,2,247,22,128,2,80,159,35,42,36,83,158,35,16,2,247,22, diff --git a/src/mzscheme/src/env.c b/src/mzscheme/src/env.c index 6ed199f85a..4ed0d3b738 100644 --- a/src/mzscheme/src/env.c +++ b/src/mzscheme/src/env.c @@ -56,6 +56,7 @@ static int env_uid_counter = 0; static Scheme_Object *kernel_symbol; static Scheme_Env *kernel_env; static Scheme_Env *unsafe_env; +static Scheme_Env *flonum_env; #define MAX_CONST_LOCAL_POS 64 #define MAX_CONST_LOCAL_TYPES 2 @@ -436,10 +437,40 @@ static void init_unsafe(Scheme_Env *env) #endif } +static void init_flonum(Scheme_Env *env) +{ + Scheme_Module_Phase_Exports *pt; + REGISTER_SO(flonum_env); + + flonum_env = scheme_primitive_module(scheme_intern_symbol("#%flonum"), env); + + scheme_init_flonum_number(flonum_env); + scheme_init_flonum_numarith(flonum_env); + scheme_init_flonum_numcomp(flonum_env); + + scheme_finish_primitive_module(flonum_env); + pt = flonum_env->module->me->rt; + scheme_populate_pt_ht(pt); + scheme_protect_primitive_provide(flonum_env, NULL); + +#if USE_COMPILED_STARTUP + if (builtin_ref_counter != (EXPECTED_PRIM_COUNT + EXPECTED_UNSAFE_COUNT + EXPECTED_FLONUM_COUNT)) { + printf("Flonum count %d doesn't match expected count %d\n", + builtin_ref_counter - EXPECTED_PRIM_COUNT - EXPECTED_UNSAFE_COUNT, + EXPECTED_FLONUM_COUNT); + abort(); + } +#endif +} + Scheme_Env *scheme_get_unsafe_env() { return unsafe_env; } +Scheme_Env *scheme_get_flonum_env() { + return flonum_env; +} + static Scheme_Env *place_instance_init_post_kernel(int initial_main_os_thread) { Scheme_Env *env; /* error handling and buffers */ @@ -692,6 +723,7 @@ static void make_kernel_env(void) #endif init_unsafe(env); + init_flonum(env); scheme_init_print_global_constants(); @@ -1344,11 +1376,13 @@ Scheme_Object **scheme_make_builtin_references_table(void) scheme_misc_count += sizeof(Scheme_Object *) * (builtin_ref_counter + 1); #endif - for (j = 0; j < 2; j++) { + for (j = 0; j < 3; j++) { if (!j) kenv = kernel_env; - else + else if (j == 1) kenv = unsafe_env; + else + kenv = flonum_env; ht = kenv->toplevel; @@ -1375,11 +1409,13 @@ Scheme_Hash_Table *scheme_map_constants_to_globals(void) result = scheme_make_hash_table(SCHEME_hash_ptr); - for (j = 0; j < 2; j++) { + for (j = 0; j < 3; j++) { if (!j) kenv = kernel_env; - else + else if (j == 1) kenv = unsafe_env; + else + kenv = flonum_env; ht = kenv->toplevel; bs = ht->buckets; @@ -1403,11 +1439,13 @@ const char *scheme_look_for_primitive(void *code) long i; int j; - for (j = 0; j < 2; j++) { + for (j = 0; j < 3; j++) { if (!j) kenv = kernel_env; - else + else if (j == 1) kenv = unsafe_env; + else + kenv = flonum_env; ht = kenv->toplevel; bs = ht->buckets; @@ -3018,7 +3056,9 @@ scheme_lookup_binding(Scheme_Object *find_id, Scheme_Comp_Env *env, int flags, /* Used to have `&& !SAME_OBJ(modidx, modname)' below, but that was a bad idea, because it causes module instances to be preserved. */ if (modname && !(flags & SCHEME_RESOLVE_MODIDS) - && (!(scheme_is_kernel_modname(modname) || scheme_is_unsafe_modname(modname)) + && (!(scheme_is_kernel_modname(modname) + || scheme_is_unsafe_modname(modname) + || scheme_is_flonum_modname(modname)) || (flags & SCHEME_REFERENCING))) { /* Create a module variable reference, so that idx is preserved: */ return scheme_hash_module_variable(env->genv, modidx, find_id, @@ -3057,6 +3097,15 @@ Scheme_Object *scheme_extract_unsafe(Scheme_Object *o) return NULL; } +Scheme_Object *scheme_extract_flonum(Scheme_Object *o) +{ + Scheme_Env *home = ((Scheme_Bucket_With_Home *)o)->home; + if (home && home->module && scheme_is_flonum_modname(home->module->modname)) + return (Scheme_Object *)((Scheme_Bucket *)o)->val; + else + return NULL; +} + int *scheme_env_get_flags(Scheme_Comp_Env *frame, int start, int count) { int *v, i; diff --git a/src/mzscheme/src/eval.c b/src/mzscheme/src/eval.c index 44a0b40bfd..2ebda0d5a1 100644 --- a/src/mzscheme/src/eval.c +++ b/src/mzscheme/src/eval.c @@ -2686,11 +2686,58 @@ static int purely_functional_primitive(Scheme_Object *rator, int n) #define IS_NAMED_PRIM(p, nm) (!strcmp(((Scheme_Primitive_Proc *)p)->name, nm)) -int scheme_wants_flonum_arguments(Scheme_Object *rator) +int scheme_wants_flonum_arguments(Scheme_Object *rator, int rotate_mode) { if (SCHEME_PRIMP(rator)) { if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL) { if (IS_NAMED_PRIM(rator, "unsafe-flabs") + || IS_NAMED_PRIM(rator, "unsafe-flsqrt") + || IS_NAMED_PRIM(rator, "unsafe-fl+") + || IS_NAMED_PRIM(rator, "unsafe-fl-") + || IS_NAMED_PRIM(rator, "unsafe-fl*") + || IS_NAMED_PRIM(rator, "unsafe-fl/") + || IS_NAMED_PRIM(rator, "unsafe-fl<") + || IS_NAMED_PRIM(rator, "unsafe-fl<=") + || IS_NAMED_PRIM(rator, "unsafe-fl=") + || IS_NAMED_PRIM(rator, "unsafe-fl>") + || IS_NAMED_PRIM(rator, "unsafe-fl>=") + || IS_NAMED_PRIM(rator, "unsafe-flvector-ref")) + return 1; + } else if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNARY_INLINED) { + if (!rotate_mode) { + if (IS_NAMED_PRIM(rator, "flabs") + || IS_NAMED_PRIM(rator, "flsqrt")) + return 1; + } + } else if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_BINARY_INLINED) { + if (!rotate_mode) { + if (IS_NAMED_PRIM(rator, "fl+") + || IS_NAMED_PRIM(rator, "fl-") + || IS_NAMED_PRIM(rator, "fl*") + || IS_NAMED_PRIM(rator, "fl/") + || IS_NAMED_PRIM(rator, "fl<") + || IS_NAMED_PRIM(rator, "fl<=") + || IS_NAMED_PRIM(rator, "fl=") + || IS_NAMED_PRIM(rator, "fl>") + || IS_NAMED_PRIM(rator, "fl>=") + || IS_NAMED_PRIM(rator, "flvector-ref")) + return 1; + } + } else if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_NARY_INLINED) { + if (IS_NAMED_PRIM(rator, "unsafe-flvector-set!")) + return 1; + } + } + + return 0; +} + +static int produces_unboxed(Scheme_Object *rator) +{ + if (SCHEME_PRIMP(rator)) { + if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL) { + if (IS_NAMED_PRIM(rator, "unsafe-flabs") + || IS_NAMED_PRIM(rator, "unsafe-flsqrt") || IS_NAMED_PRIM(rator, "unsafe-fl+") || IS_NAMED_PRIM(rator, "unsafe-fl-") || IS_NAMED_PRIM(rator, "unsafe-fl*") @@ -2703,8 +2750,24 @@ int scheme_wants_flonum_arguments(Scheme_Object *rator) || IS_NAMED_PRIM(rator, "unsafe-flvector-ref") || IS_NAMED_PRIM(rator, "unsafe-fx->fl")) return 1; - } else if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_NARY_INLINED) { - if (IS_NAMED_PRIM(rator, "unsafe-flvector-set!")) + } else if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNARY_INLINED) { + if (IS_NAMED_PRIM(rator, "flabs") + || IS_NAMED_PRIM(rator, "flsqrt") + || IS_NAMED_PRIM(rator, "->fl")) + return 1; + } else if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_BINARY_INLINED) { + if (IS_NAMED_PRIM(rator, "flabs") + || IS_NAMED_PRIM(rator, "flsqrt") + || IS_NAMED_PRIM(rator, "fl+") + || IS_NAMED_PRIM(rator, "fl-") + || IS_NAMED_PRIM(rator, "fl*") + || IS_NAMED_PRIM(rator, "fl/") + || IS_NAMED_PRIM(rator, "fl<") + || IS_NAMED_PRIM(rator, "fl<=") + || IS_NAMED_PRIM(rator, "fl=") + || IS_NAMED_PRIM(rator, "fl>") + || IS_NAMED_PRIM(rator, "fl>=") + || IS_NAMED_PRIM(rator, "flvector-ref")) return 1; } } @@ -2712,28 +2775,6 @@ int scheme_wants_flonum_arguments(Scheme_Object *rator) return 0; } -static int produces_unboxed(Scheme_Object *rator) -{ - if (SCHEME_PRIMP(rator) - && (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL)) { - if (IS_NAMED_PRIM(rator, "unsafe-flabs") - || IS_NAMED_PRIM(rator, "unsafe-fl+") - || IS_NAMED_PRIM(rator, "unsafe-fl-") - || IS_NAMED_PRIM(rator, "unsafe-fl*") - || IS_NAMED_PRIM(rator, "unsafe-fl/") - || IS_NAMED_PRIM(rator, "unsafe-fl<") - || IS_NAMED_PRIM(rator, "unsafe-fl<=") - || IS_NAMED_PRIM(rator, "unsafe-fl=") - || IS_NAMED_PRIM(rator, "unsafe-fl>") - || IS_NAMED_PRIM(rator, "unsafe-fl>=") - || IS_NAMED_PRIM(rator, "unsafe-flvector-ref") - || IS_NAMED_PRIM(rator, "unsafe-fx->fl")) - return 1; - } - - return 0; -} - static int is_unboxed_argument(Scheme_Object *rand, int fuel, Optimize_Info *info, int lifted) { if (fuel > 0) { @@ -2827,7 +2868,7 @@ static Scheme_Object *check_unbox_rotation(Scheme_Object *_app, Scheme_Object *r Scheme_Compiled_Let_Value *inner = NULL; int i, lifted = 0; - if (scheme_wants_flonum_arguments(rator)) { + if (scheme_wants_flonum_arguments(rator, 1)) { for (i = 0; i < count; i++) { if (count == 1) rand = ((Scheme_App2_Rec *)_app)->rand; @@ -2988,7 +3029,7 @@ static Scheme_Object *optimize_application(Scheme_Object *o, Optimize_Info *info return le; } - if (scheme_wants_flonum_arguments(app->args[0])) + if (scheme_wants_flonum_arguments(app->args[0], 0)) sub_context |= OPT_CONTEXT_FLONUM_ARG; } @@ -3093,7 +3134,7 @@ static Scheme_Object *optimize_application2(Scheme_Object *o, Optimize_Info *inf return le; } - if (scheme_wants_flonum_arguments(app->rator)) + if (scheme_wants_flonum_arguments(app->rator, 0)) sub_context |= OPT_CONTEXT_FLONUM_ARG; le = scheme_optimize_expr(app->rand, info, sub_context); @@ -3165,7 +3206,7 @@ static Scheme_Object *optimize_application3(Scheme_Object *o, Optimize_Info *inf return le; } - if (scheme_wants_flonum_arguments(app->rator)) + if (scheme_wants_flonum_arguments(app->rator, 0)) sub_context |= OPT_CONTEXT_FLONUM_ARG; /* 1st arg */ @@ -6071,6 +6112,9 @@ scheme_compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env, && scheme_extract_unsafe(var)) { scheme_register_unsafe_in_prefix(env, rec, drec, menv); return scheme_extract_unsafe(var); + } else if (SAME_TYPE(SCHEME_TYPE(var), scheme_variable_type) + && scheme_extract_flonum(var)) { + return scheme_extract_flonum(var); } else if (SAME_TYPE(SCHEME_TYPE(var), scheme_variable_type) || SAME_TYPE(SCHEME_TYPE(var), scheme_module_variable_type)) return scheme_register_toplevel_in_prefix(var, env, rec, drec); diff --git a/src/mzscheme/src/jit.c b/src/mzscheme/src/jit.c index 4fa480e26b..cd55e9be12 100644 --- a/src/mzscheme/src/jit.c +++ b/src/mzscheme/src/jit.c @@ -151,7 +151,7 @@ static void *bad_flvector_length_code; static void *vector_ref_code, *vector_ref_check_index_code, *vector_set_code, *vector_set_check_index_code; static void *string_ref_code, *string_ref_check_index_code, *string_set_code, *string_set_check_index_code; static void *bytes_ref_code, *bytes_ref_check_index_code, *bytes_set_code, *bytes_set_check_index_code; -static void *flvector_ref_check_index_code, *flvector_set_check_index_code; +static void *flvector_ref_check_index_code, *flvector_set_check_index_code, *flvector_set_flonum_check_index_code; static void *syntax_e_code; void *scheme_on_demand_jit_code; static void *on_demand_jit_arity_code; @@ -167,6 +167,7 @@ static void *app_values_slow_code, *app_values_multi_slow_code, *app_values_tail static void *finish_tail_call_code, *finish_tail_call_fixup_code; static void *module_run_start_code, *module_start_start_code; static void *box_flonum_from_stack_code; +static void *fl1_fail_code, *fl2rr_fail_code[2], *fl2fr_fail_code[2], *fl2rf_fail_code[2]; typedef struct { MZTAG_IF_REQUIRED @@ -222,6 +223,7 @@ static Native_Get_Arity_Proc get_arity_code; static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends, int ignored); static int generate(Scheme_Object *obj, mz_jit_state *jitter, int tail_ok, int multi_ok, int target); +static int generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inlined_ok, int unbox_anyway); static void *generate_lambda_simple_arity_check(int num_params, int has_rest, int is_method, int permanent); static void generate_case_lambda(Scheme_Case_Lambda *c, Scheme_Native_Closure_Data *ndata, int is_method); @@ -238,7 +240,8 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ static int is_simple(Scheme_Object *obj, int depth, int just_markless, mz_jit_state *jitter, int stack_start); static int lambda_has_been_jitted(Scheme_Native_Closure_Data *ndata); -static int can_unbox(Scheme_Object *obj, int fuel, int regs); +static int can_unbox_inline(Scheme_Object *obj, int fuel, int regs, int unsafely); +static int can_unbox_directly(Scheme_Object *obj); #ifdef USE_FLONUM_UNBOXING static int generate_flonum_local_unboxing(mz_jit_state *jitter, int push); #endif @@ -609,6 +612,9 @@ static void *generate_one(mz_jit_state *old_jitter, ok = generate(jitter, data); + if (jitter->unbox || jitter->unbox_depth) + scheme_signal_error("ended with unbox or depth"); + if (save_ptr) { mz_retain_it(jitter, save_ptr); } @@ -3145,20 +3151,18 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i int is_flonum, already_unboxed = 0; if ((SCHEME_CLOSURE_DATA_FLAGS(jitter->self_data) & CLOS_HAS_TYPED_ARGS) && CLOSURE_ARGUMENT_IS_FLONUM(jitter->self_data, i + args_already_in_place)) { + int aoffset; is_flonum = 1; rand = (alt_rands ? alt_rands[i+1+args_already_in_place] : app->args[i+1+args_already_in_place]); - if (can_unbox(rand, 5, JIT_FPR_NUM-1)) { - int aoffset; - aoffset = JIT_FRAME_FLONUM_OFFSET - (arg_tmp_offset * sizeof(double)); - jit_ldxi_d_fppush(JIT_FPR0, JIT_FP, aoffset); - --arg_tmp_offset; - already_unboxed = 1; - if (!already_loaded && !SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type)) { - already_loaded = 1; - (void)jit_movi_p(JIT_R0, NULL); - } + aoffset = JIT_FRAME_FLONUM_OFFSET - (arg_tmp_offset * sizeof(double)); + jit_ldxi_d_fppush(JIT_FPR0, JIT_FP, aoffset); + --arg_tmp_offset; + already_unboxed = 1; + if (!already_loaded && !SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type)) { + already_loaded = 1; + (void)jit_movi_p(JIT_R0, NULL); } } else is_flonum = 0; @@ -3203,9 +3207,8 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i rand = (alt_rands ? alt_rands[i+1+args_already_in_place] : app->args[i+1+args_already_in_place]); - if (can_unbox(rand, 5, JIT_FPR_NUM-1) - && (!SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type) - || (SCHEME_GET_LOCAL_FLAGS(rand) == SCHEME_LOCAL_FLONUM))) { + if (!SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type) + || (SCHEME_GET_LOCAL_FLAGS(rand) == SCHEME_LOCAL_FLONUM)) { int aoffset = JIT_FRAME_FLONUM_OFFSET - (arg_tmp_offset * sizeof(double)); GC_CAN_IGNORE jit_insn *iref; if (i != num_rands - 1) @@ -3681,11 +3684,18 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if (direct_self && is_tail && (SCHEME_CLOSURE_DATA_FLAGS(jitter->self_data) & CLOS_HAS_TYPED_ARGS) - && (CLOSURE_ARGUMENT_IS_FLONUM(jitter->self_data, i+args_already_in_place)) - && can_unbox(arg, 5, JIT_FPR_NUM-1)) { + && (CLOSURE_ARGUMENT_IS_FLONUM(jitter->self_data, i+args_already_in_place))) { + int directly; jitter->unbox++; - generate(arg, jitter, 0, 0, JIT_R0); + if (can_unbox_inline(arg, 5, JIT_FPR_NUM-1, 0)) + directly = 1; + else if (can_unbox_directly(arg)) + directly = 1; + else + directly = 0; + generate_unboxed(arg, jitter, directly, 1); --jitter->unbox; + --jitter->unbox_depth; CHECK_LIMIT(); generate_flonum_local_unboxing(jitter, 0); CHECK_LIMIT(); @@ -3841,7 +3851,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ return is_tail ? 2 : 1; } -static int is_unboxable_op(Scheme_Object *obj, int flag) +static int is_inline_unboxable_op(Scheme_Object *obj, int flag, int unsafely) { if (!SCHEME_PRIMP(obj)) return 0; @@ -3858,6 +3868,17 @@ static int is_unboxable_op(Scheme_Object *obj, int flag) if (IS_NAMED_PRIM(obj, "unsafe-f64vector-ref")) return 1; if (IS_NAMED_PRIM(obj, "unsafe-flvector-ref")) return 1; + if (unsafely) { + /* These are inline-unboxable when their args are + safely inline-unboxable: */ + if (IS_NAMED_PRIM(obj, "fl+")) return 1; + if (IS_NAMED_PRIM(obj, "fl-")) return 1; + if (IS_NAMED_PRIM(obj, "fl*")) return 1; + if (IS_NAMED_PRIM(obj, "fl/")) return 1; + if (IS_NAMED_PRIM(obj, "flabs")) return 1; + if (IS_NAMED_PRIM(obj, "flsqrt")) return 1; + } + return 0; } @@ -3875,7 +3896,28 @@ static int generate_pop_unboxed(mz_jit_state *jitter) return 1; } -static int can_unbox(Scheme_Object *obj, int fuel, int regs) +static int is_unboxing_immediate(Scheme_Object *obj, int unsafely) +{ + Scheme_Type t; + + t = SCHEME_TYPE(obj); + switch (t) { + case scheme_local_type: + if (SCHEME_LOCAL_FLAGS(obj) == SCHEME_LOCAL_FLONUM) + return 1; + return unsafely; + case scheme_toplevel_type: + case scheme_local_unbox_type: + return unsafely; + break; + default: + if (!unsafely) + return SCHEME_FLOATP(obj); + return (t > _scheme_values_types_); + } +} + +static int can_unbox_inline(Scheme_Object *obj, int fuel, int regs, int unsafely) /* Assuming that `arg' is unsafely assumed to produce a flonum, can we just unbox it without using more than `regs' registers? There cannot be any errors or function calls, unless we've specifically @@ -3892,29 +3934,67 @@ static int can_unbox(Scheme_Object *obj, int fuel, int regs) case scheme_application2_type: { Scheme_App2_Rec *app = (Scheme_App2_Rec *)obj; - if (!is_unboxable_op(app->rator, SCHEME_PRIM_IS_UNARY_INLINED)) + if (!is_inline_unboxable_op(app->rator, SCHEME_PRIM_IS_UNARY_INLINED, unsafely)) return 0; - return can_unbox(app->rand, fuel - 1, regs); + return can_unbox_inline(app->rand, fuel - 1, regs, unsafely); } case scheme_application3_type: { Scheme_App3_Rec *app = (Scheme_App3_Rec *)obj; - if (!is_unboxable_op(app->rator, SCHEME_PRIM_IS_BINARY_INLINED)) + if (!is_inline_unboxable_op(app->rator, SCHEME_PRIM_IS_BINARY_INLINED, unsafely)) return 0; - if (!can_unbox(app->rand1, fuel - 1, regs)) + if (IS_NAMED_PRIM(app->rator, "unsafe-f64vector-ref") + || IS_NAMED_PRIM(app->rator, "unsafe-flvector-ref")) { + if (is_unboxing_immediate(app->rand1, 1) + && is_unboxing_immediate(app->rand1, 2)) { + return 1; + } + } + if (!can_unbox_inline(app->rand1, fuel - 1, regs, unsafely)) return 0; - return can_unbox(app->rand2, fuel - 1, regs - 1); + return can_unbox_inline(app->rand2, fuel - 1, regs - 1, unsafely); } - case scheme_toplevel_type: - case scheme_local_type: - case scheme_local_unbox_type: - return 1; - break; default: - return (t > _scheme_values_types_); + return is_unboxing_immediate(obj, unsafely); } } +static int can_unbox_directly(Scheme_Object *obj) +/* Used only when !can_unbox_inline(). Detects safe operations that + produce flonums when they don't raise an exception. */ +{ + Scheme_Type t; + + t = SCHEME_TYPE(obj); + switch (t) { + case scheme_application2_type: + { + Scheme_App2_Rec *app = (Scheme_App2_Rec *)obj; + if (is_inline_unboxable_op(app->rator, SCHEME_PRIM_IS_UNARY_INLINED, 1)) + return 1; + if (SCHEME_PRIMP(app->rator) + && (SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_UNARY_INLINED)) { + if (IS_NAMED_PRIM(app->rator, "->fl")) + return 1; + } + } + break; + case scheme_application3_type: + { + Scheme_App3_Rec *app = (Scheme_App3_Rec *)obj; + if (is_inline_unboxable_op(app->rator, SCHEME_PRIM_IS_BINARY_INLINED, 1)) + return 1; + if (SCHEME_PRIMP(app->rator) + && (SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_BINARY_INLINED)) { + if (IS_NAMED_PRIM(app->rator, "flvector-ref")) return 1; + } + } + break; + } + + return 0; +} + static jit_insn *generate_arith_slow_path(mz_jit_state *jitter, Scheme_Object *rator, jit_insn **_ref, jit_insn **_ref4, jit_insn **for_branch, @@ -4054,23 +4134,23 @@ static int can_fast_double(int arith, int cmp, int two_args) #define jit_extr_l_d_fppush(rd, rs) jit_extr_l_d(rd, rs) #endif -static int generate_unboxing(mz_jit_state *jitter) +static int generate_unboxing(mz_jit_state *jitter, int target) { int fpr0; fpr0 = JIT_FPR(jitter->unbox_depth); - jit_ldxi_d_fppush(fpr0, JIT_R0, &((Scheme_Double *)0x0)->double_val); + jit_ldxi_d_fppush(fpr0, target, &((Scheme_Double *)0x0)->double_val); jitter->unbox_depth++; return 1; } -static int generate_alloc_double(mz_jit_state *jitter) +static int generate_alloc_double(mz_jit_state *jitter, int inline_retry) /* value should be in JIT_FPR0; R0-R2 not saved; V1 used */ { #ifdef INLINE_FP_OPS # ifdef CAN_INLINE_ALLOC - inline_alloc(jitter, sizeof(Scheme_Double), scheme_double_type, 0, 0, 1, 0); + inline_alloc(jitter, sizeof(Scheme_Double), scheme_double_type, 0, 0, 1, inline_retry); CHECK_LIMIT(); jit_addi_p(JIT_R0, JIT_V1, GC_OBJHEAD_SIZE); (void)jit_stxi_d_fppop(&((Scheme_Double *)0x0)->double_val, JIT_R0, JIT_FPR0); @@ -4225,7 +4305,7 @@ static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int r if (!no_alloc) { mz_rs_sync(); /* needed if arguments were unboxed */ - generate_alloc_double(jitter); + generate_alloc_double(jitter, 0); CHECK_LIMIT(); } else if (unboxed_result) { jitter->unbox_depth++; @@ -4283,6 +4363,37 @@ static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int r return 1; } +static int check_flonum_result(mz_jit_state *jitter, int reg, void *fail_code, Scheme_Object *rator) +/* Doesn't use R0 or R1, except for `reg' */ +{ + /* Check for flonum result */ + GC_CAN_IGNORE jit_insn *ref, *reffail; + + mz_rs_sync(); + + __START_TINY_JUMPS__(1); + ref = jit_bmci_l(jit_forward(), reg, 0x1); + __END_TINY_JUMPS__(1); + + reffail = _jit.x.pc; + jit_movi_p(JIT_V1, ((Scheme_Primitive_Proc *)rator)->prim_val); + (void)jit_calli(fail_code); + + __START_TINY_JUMPS__(1); + mz_patch_branch(ref); + __END_TINY_JUMPS__(1); + + jit_ldxi_s(JIT_R2, JIT_R0, &((Scheme_Object *)0x0)->type); + __START_SHORT_JUMPS__(1); + (void)jit_bnei_i(reffail, JIT_R2, scheme_double_type); + __END_SHORT_JUMPS__(1); + CHECK_LIMIT(); + + generate_unboxing(jitter, reg); + + return 1; +} + static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Object *rand, Scheme_Object *rand2, int orig_args, int arith, int cmp, int v, jit_insn **for_branch, int branch_short, int unsafe_fx, int unsafe_fl, GC_CAN_IGNORE jit_insn *overflow_refslow) @@ -4314,42 +4425,157 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj already in R0 (fixnum or min/max) or a floating-point register (flonum) and the second arguement is in R1 (fixnum or min/max) or a floating-point register (flonum). + For unsafe_fx or unsafe_fl, -1 means safe but specific to the type. */ { GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4, *refd = NULL, *refdt = NULL, *refslow; - int skipped, simple_rand, simple_rand2, reversed = 0, has_fixnum_fast = 1; + int skipped, simple_rand, simple_rand2, reversed = 0; + int has_fixnum_fast = 1, has_flonum_fast = 1; + int inlined_flonum1, inlined_flonum2; LOG_IT(("inlined %s\n", ((Scheme_Primitive_Proc *)rator)->name)); + if (unsafe_fx < 0) { + unsafe_fx = 0; + has_flonum_fast = 0; + } + + if (unsafe_fl) { + if (!rand) { + inlined_flonum1 = inlined_flonum2 = 1; + } else { + if (can_unbox_inline(rand, 5, JIT_FPR_NUM-2, unsafe_fl > 0)) + inlined_flonum1 = 1; + else + inlined_flonum1 = 0; + if (!rand2 || can_unbox_inline(rand2, 5, JIT_FPR_NUM-3, unsafe_fl > 0)) + inlined_flonum2 = 1; + else + inlined_flonum2 = 0; + } + } else + inlined_flonum1 = inlined_flonum2 = 0; + if (unsafe_fl - && (!rand - || (can_unbox(rand, 5, JIT_FPR_NUM-2) - && (!rand2 || can_unbox(rand2, 5, JIT_FPR_NUM-3))))) { - /* Unsafe, unboxed floating-point ops. */ +#ifndef USE_FLONUM_UNBOXING + && inlined_flonum1 && inlined_flonum2 +#endif + ) { + /* Unboxed (and maybe unsafe) floating-point ops. */ int args_unboxed = ((arith != 9) && (arith != 10)); + int flonum_depth, fl_reversed = 0, can_direct1, can_direct2; + + if (inlined_flonum1 && inlined_flonum2) /* safe can be implemented as unsafe */ + unsafe_fl = 1; + + if (!args_unboxed && rand) + scheme_signal_error("unvalid mode"); + + if (inlined_flonum1 && !inlined_flonum2) { + GC_CAN_IGNORE Scheme_Object *tmp; + reversed = !reversed; + cmp = -cmp; + fl_reversed = 1; + tmp = rand; + rand = rand2; + rand2 = tmp; + inlined_flonum1 = 0; + inlined_flonum2 = 1; + } + + if (inlined_flonum1) + can_direct1 = 1; + else + can_direct1 = can_unbox_directly(rand); + if (inlined_flonum2) + can_direct2 = 1; + else + can_direct2 = can_unbox_directly(rand2); + if (args_unboxed) jitter->unbox++; if (!rand) { CHECK_LIMIT(); + if (args_unboxed) + flonum_depth = 2; + else + flonum_depth = 0; } else if (!rand2) { mz_runstack_skipped(jitter, 1); - generate(rand, jitter, 0, 1, JIT_R0); + generate_unboxed(rand, jitter, can_direct1, (unsafe_fl > 0)); CHECK_LIMIT(); mz_runstack_unskipped(jitter, 1); + if (!can_direct1 && (unsafe_fl <= 0)) { + check_flonum_result(jitter, JIT_R0, fl1_fail_code, rator); + CHECK_LIMIT(); + } + flonum_depth = 1; } else { +#ifdef USE_FLONUM_UNBOXING + int flostack = 0, flopos = 0; +#endif mz_runstack_skipped(jitter, 2); - generate(rand, jitter, 0, 1, JIT_R0); + generate_unboxed(rand, jitter, can_direct1, (unsafe_fl > 0)); CHECK_LIMIT(); - generate(rand2, jitter, 0, 1, JIT_R0); + if (!(inlined_flonum1 && inlined_flonum2)) { + if (!can_direct1 && (unsafe_fl <= 0)) { + mz_pushr_p(JIT_R0); + } else if (!inlined_flonum2) { +#ifdef USE_FLONUM_UNBOXING + flostack = mz_flostack_save(jitter, &flopos); + --jitter->unbox_depth; + generate_flonum_local_unboxing(jitter, 0); + CHECK_LIMIT(); +#endif + } + } + generate_unboxed(rand2, jitter, can_direct2, (unsafe_fl > 0)); CHECK_LIMIT(); + if (!(inlined_flonum1 && inlined_flonum2)) { + if ((can_direct1 || (unsafe_fl > 0)) && !inlined_flonum2) { +#ifdef USE_FLONUM_UNBOXING + int aoffset; + int fpr0; + fpr0 = JIT_FPR(jitter->unbox_depth); + aoffset = JIT_FRAME_FLONUM_OFFSET - (jitter->flostack_offset * sizeof(double)); + jit_ldxi_d_fppush(fpr0, JIT_FP, aoffset); + mz_flostack_restore(jitter, flostack, flopos, 1); + CHECK_LIMIT(); + jitter->unbox_depth++; +#endif + } + if (!can_direct2 && (unsafe_fl <= 0)) { + jit_movr_p(JIT_R1, JIT_R0); + if (!can_direct1) { + mz_popr_p(JIT_R0); + check_flonum_result(jitter, JIT_R0, fl2rr_fail_code[fl_reversed], rator); + CHECK_LIMIT(); + } + check_flonum_result(jitter, JIT_R1, fl2fr_fail_code[fl_reversed], rator); + CHECK_LIMIT(); + } else { + if (!can_direct1 && (unsafe_fl <= 0)) { + mz_popr_p(JIT_R0); + check_flonum_result(jitter, JIT_R0, fl2rf_fail_code[fl_reversed], rator); + CHECK_LIMIT(); + } + if (!(can_direct1 || (unsafe_fl > 0)) || !inlined_flonum2) { + cmp = -cmp; + reversed = !reversed; + } + } + } mz_runstack_unskipped(jitter, 2); + flonum_depth = 2; } - if (args_unboxed) { + if (args_unboxed) --jitter->unbox; - jitter->unbox_depth -= (rand ? (rand2 ? 2 : 1) : 2); - } + jitter->unbox_depth -= flonum_depth; + if (!jitter->unbox && jitter->unbox_depth && rand) + scheme_signal_error("broken unbox depth"); if (for_branch) mz_rs_sync(); /* needed if arguments were unboxed */ + generate_double_arith(jitter, arith, cmp, reversed, !!rand2, 0, &refd, &refdt, branch_short, 1, args_unboxed, jitter->unbox); @@ -4504,7 +4730,9 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj if (for_branch) mz_rs_sync(); } - if (unsafe_fl || (!unsafe_fx && !SCHEME_INTP(rand) && can_fast_double(arith, cmp, 1))) { + if (unsafe_fl || (!unsafe_fx && !SCHEME_INTP(rand) + && has_flonum_fast + && can_fast_double(arith, cmp, 1))) { /* Maybe they're both doubles... */ if (unsafe_fl) mz_rs_sync(); generate_double_arith(jitter, arith, cmp, reversed, 1, 0, &refd, &refdt, branch_short, unsafe_fl, 0, 0); @@ -4553,7 +4781,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj CHECK_LIMIT(); } - if (unsafe_fl || (!unsafe_fx && can_fast_double(arith, cmp, 1))) { + if (unsafe_fl || (!unsafe_fx && has_flonum_fast && can_fast_double(arith, cmp, 1))) { /* Maybe they're both doubles... */ if (unsafe_fl) mz_rs_sync(); generate_double_arith(jitter, arith, cmp, reversed, 1, 0, &refd, &refdt, branch_short, unsafe_fl, 0, 0); @@ -4598,6 +4826,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj || ((orig_args != 2) /* <- heuristic: we could generate code when an exact argument is given, but the extra FP code is probably not worthwhile. */ && !unsafe_fx + && has_flonum_fast && can_fast_double(arith, cmp, 0) /* watch out: divide by 0 is special: */ && ((arith != -2) || v || reversed))) { @@ -4928,7 +5157,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj if (!unbox) { mz_rs_sync(); /* needed for unsafe op before allocation */ __END_SHORT_JUMPS__(branch_short); - generate_alloc_double(jitter); + generate_alloc_double(jitter, 0); __START_SHORT_JUMPS__(branch_short); } else { jitter->unbox_depth++; @@ -5061,7 +5290,7 @@ static int extract_nary_arg(int reg, int n, mz_jit_state *jitter, Scheme_App_Rec if (!alt_args) { jit_ldxi_p(reg, JIT_RUNSTACK, WORDS_TO_BYTES(n)); if (jitter->unbox) - generate_unboxing(jitter); + generate_unboxing(jitter, JIT_R0); } else if (is_constant_and_avoids_r1(app->args[n+1])) { __END_SHORT_JUMPS__(old_short_jumps); generate(app->args[n+1], jitter, 0, 0, reg); @@ -5075,7 +5304,7 @@ static int extract_nary_arg(int reg, int n, mz_jit_state *jitter, Scheme_App_Rec } jit_ldxi_p(reg, JIT_RUNSTACK, WORDS_TO_BYTES(j)); if (jitter->unbox) - generate_unboxing(jitter); + generate_unboxing(jitter, JIT_R0); } CHECK_LIMIT(); return 1; @@ -5932,15 +6161,24 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in } else if (IS_NAMED_PRIM(rator, "unsafe-flabs")) { generate_arith(jitter, rator, app->rand, NULL, 1, 11, 0, 0, NULL, 1, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "flabs")) { + generate_arith(jitter, rator, app->rand, NULL, 1, 11, 0, 0, NULL, 1, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-flsqrt")) { generate_arith(jitter, rator, app->rand, NULL, 1, 13, 0, 0, NULL, 1, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "flsqrt")) { + generate_arith(jitter, rator, app->rand, NULL, 1, 13, 0, 0, NULL, 1, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "exact->inexact")) { generate_arith(jitter, rator, app->rand, NULL, 1, 12, 0, 0, NULL, 1, 0, 0, NULL); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx->fl")) { generate_arith(jitter, rator, app->rand, NULL, 1, 12, 0, 0, NULL, 1, 1, 0, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "->fl")) { + generate_arith(jitter, rator, app->rand, NULL, 1, 12, 0, 0, NULL, 1, -1, 0, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "bitwise-not")) { generate_arith(jitter, rator, app->rand, NULL, 1, 7, 0, 9, NULL, 1, 0, 0, NULL); return 1; @@ -6167,7 +6405,7 @@ static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app, } static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int base_offset, - int for_fl, int unsafe) + int for_fl, int unsafe, int unbox_flonum) /* if int_ready, JIT_R1 has num index (for safe mode) and JIT_V1 has pre-computed offset, otherwise JIT_R1 has fixnum index */ { @@ -6186,6 +6424,8 @@ static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int if (set) { if (!for_fl) (void)jit_calli(vector_set_check_index_code); + else if (unbox_flonum) + (void)jit_calli(flvector_set_flonum_check_index_code); else (void)jit_calli(flvector_set_check_index_code); } else { @@ -6217,7 +6457,7 @@ static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int } CHECK_LIMIT(); - if (for_fl && set) { + if (for_fl && set && !unbox_flonum) { jit_ldr_p(JIT_R2, JIT_RUNSTACK); (void)jit_bmsi_ul(reffail, JIT_R2, 0x1); jit_ldxi_s(JIT_R2, JIT_R2, &((Scheme_Object *)0x0)->type); @@ -6239,20 +6479,30 @@ static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int jit_addi_p(JIT_V1, JIT_V1, base_offset); } if (set) { - jit_ldr_p(JIT_R2, JIT_RUNSTACK); + if (!unbox_flonum) + jit_ldr_p(JIT_R2, JIT_RUNSTACK); if (!for_fl) { jit_stxr_p(JIT_V1, JIT_R0, JIT_R2); } else { - jit_ldxi_d_fppush(JIT_FPR0, JIT_R2, &((Scheme_Double *)0x0)->double_val); + if (!unbox_flonum) + jit_ldxi_d_fppush(JIT_FPR0, JIT_R2, &((Scheme_Double *)0x0)->double_val); jit_stxr_d_fppop(JIT_V1, JIT_R0, JIT_FPR0); + if (unbox_flonum) { + --jitter->unbox_depth; + } } (void)jit_movi_p(JIT_R0, scheme_void); } else { if (!for_fl) { jit_ldxr_p(JIT_R0, JIT_R0, JIT_V1); } else { - jit_ldxr_d_fppush(JIT_FPR0, JIT_R0, JIT_V1); - generate_alloc_double(jitter); + int fpr0; + fpr0 = JIT_FPR(jitter->unbox_depth); + jit_ldxr_d_fppush(fpr0, JIT_R0, JIT_V1); + if (unbox_flonum) + jitter->unbox_depth++; + else + generate_alloc_double(jitter, 0); } } @@ -6369,6 +6619,9 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "unsafe-fl=")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 0, 0, for_branch, branch_short, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "fl=")) { + generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 0, 0, for_branch, branch_short, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "<=")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, -1, 0, for_branch, branch_short, 0, 0, NULL); return 1; @@ -6378,6 +6631,9 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "unsafe-fl<=")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, -1, 0, for_branch, branch_short, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "fl<=")) { + generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, -1, 0, for_branch, branch_short, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "<")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, -2, 0, for_branch, branch_short, 0, 0, NULL); return 1; @@ -6387,6 +6643,9 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "unsafe-fl<")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, -2, 0, for_branch, branch_short, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "fl<")) { + generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, -2, 0, for_branch, branch_short, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, ">=")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 1, 0, for_branch, branch_short, 0, 0, NULL); return 1; @@ -6396,6 +6655,9 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "unsafe-fl>=")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 1, 0, for_branch, branch_short, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "fl>=")) { + generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 1, 0, for_branch, branch_short, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, ">")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 2, 0, for_branch, branch_short, 0, 0, NULL); return 1; @@ -6405,6 +6667,9 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "unsafe-fl>")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 2, 0, for_branch, branch_short, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "fl>")) { + generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 2, 0, for_branch, branch_short, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "bitwise-bit-set?")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 3, 0, for_branch, branch_short, 0, 0, NULL); return 1; @@ -6421,6 +6686,9 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "unsafe-fl+")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 1, 0, 0, NULL, 1, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "fl+")) { + generate_arith(jitter, rator, app->rand1, app->rand2, 2, 1, 0, 0, NULL, 1, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "-")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, -1, 0, 0, NULL, 1, 0, 0, NULL); return 1; @@ -6430,6 +6698,9 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "unsafe-fl-")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, -1, 0, 0, NULL, 1, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "fl-")) { + generate_arith(jitter, rator, app->rand1, app->rand2, 2, -1, 0, 0, NULL, 1, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "*")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 2, 0, 0, NULL, 1, 0, 0, NULL); return 1; @@ -6439,12 +6710,18 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "unsafe-fl*")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, 2, 0, 0, NULL, 1, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "fl*")) { + generate_arith(jitter, rator, app->rand1, app->rand2, 2, 2, 0, 0, NULL, 1, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "/")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, -2, 0, 0, NULL, 1, 0, 0, NULL); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl/")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, -2, 0, 0, NULL, 1, 0, 1, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "fl/")) { + generate_arith(jitter, rator, app->rand1, app->rand2, 2, -2, 0, 0, NULL, 1, 0, -1, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "quotient")) { generate_arith(jitter, rator, app->rand1, app->rand2, 2, -3, 0, 0, NULL, 1, 0, 0, NULL); return 1; @@ -6500,6 +6777,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i || IS_NAMED_PRIM(rator, "flvector-ref")) { int simple; int which, unsafe = 0, base_offset = ((int)&SCHEME_VEC_ELS(0x0)); + int unbox = jitter->unbox; if (IS_NAMED_PRIM(rator, "vector-ref")) which = 0; @@ -6509,6 +6787,10 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else if (IS_NAMED_PRIM(rator, "flvector-ref")) { which = 3; base_offset = ((int)&SCHEME_FLVEC_ELS(0x0)); + if (unbox) { + if (jitter->unbox_depth) scheme_signal_error("bad depth for flvector-ref"); + jitter->unbox = 0; + } } else if (IS_NAMED_PRIM(rator, "unsafe-struct-ref")) { which = 0; unsafe = 1; @@ -6538,11 +6820,11 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i if (!which) { /* vector-ref is relatively simple and worth inlining */ - generate_vector_op(jitter, 0, 0, base_offset, 0, unsafe); + generate_vector_op(jitter, 0, 0, base_offset, 0, unsafe, 0); CHECK_LIMIT(); } else if (which == 3) { /* flvector-ref is relatively simple and worth inlining */ - generate_vector_op(jitter, 0, 0, base_offset, 1, unsafe); + generate_vector_op(jitter, 0, 0, base_offset, 1, unsafe, unbox); CHECK_LIMIT(); } else if (which == 1) { if (unsafe) { @@ -6592,11 +6874,11 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jit_movi_l(JIT_V1, offset); if (!which) { /* vector-ref is relatively simple and worth inlining */ - generate_vector_op(jitter, 0, 1, base_offset, 0, unsafe); + generate_vector_op(jitter, 0, 1, base_offset, 0, unsafe, 0); CHECK_LIMIT(); } else if (which == 3) { /* flvector-ref is relatively simple and worth inlining */ - generate_vector_op(jitter, 0, 1, base_offset, 1, unsafe); + generate_vector_op(jitter, 0, 1, base_offset, 1, unsafe, unbox); CHECK_LIMIT(); } else if (which == 1) { if (unsafe) { @@ -6624,6 +6906,8 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i mz_runstack_unskipped(jitter, 2); } + if (unbox) jitter->unbox = unbox; + return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-f64vector-ref") || IS_NAMED_PRIM(rator, "unsafe-flvector-ref")) { @@ -6659,7 +6943,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jitter->unbox_depth++; else { mz_rs_sync(); - generate_alloc_double(jitter); + generate_alloc_double(jitter, 0); } return 1; @@ -6846,7 +7130,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int || IS_NAMED_PRIM(rator, "unsafe-bytes-set!")) { int simple, constval; int which, unsafe = 0, base_offset = ((int)&SCHEME_VEC_ELS(0x0)); - int pushed; + int pushed, flonum_arg; if (IS_NAMED_PRIM(rator, "vector-set!")) which = 0; @@ -6911,30 +7195,46 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } } - generate_non_tail(app->args[3], jitter, 0, 1, 0); /* sync'd below */ + if ((which == 3) + && (can_unbox_inline(app->args[3], 5, JIT_FPR_NUM-3, 0) + || can_unbox_directly(app->args[3]))) + flonum_arg = 1; + else + flonum_arg = 0; + + if (flonum_arg) { + jitter->unbox++; + generate_unboxed(app->args[3], jitter, 1, 0); + --jitter->unbox; + } else { + generate_non_tail(app->args[3], jitter, 0, 1, 0); /* sync'd below */ + } CHECK_LIMIT(); mz_rs_sync(); if (!constval || !simple) { - jit_movr_p(JIT_R2, JIT_R0); + if (!flonum_arg) + jit_movr_p(JIT_R2, JIT_R0); jit_ldr_p(JIT_R0, JIT_RUNSTACK); - jit_str_p(JIT_RUNSTACK, JIT_R2); + if (!flonum_arg) + jit_str_p(JIT_RUNSTACK, JIT_R2); if (!simple && !constval) { jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(1)); } } else { - jit_str_p(JIT_RUNSTACK, JIT_R0); + if (!flonum_arg) + jit_str_p(JIT_RUNSTACK, JIT_R0); jit_movr_p(JIT_R0, JIT_V1); } if (!simple) { if (!which) { /* vector-set! is relatively simple and worth inlining */ - generate_vector_op(jitter, 1, 0, base_offset, 0, unsafe); + generate_vector_op(jitter, 1, 0, base_offset, 0, unsafe, flonum_arg); CHECK_LIMIT(); } else if (which == 3) { /* flvector-set! is relatively simple and worth inlining */ - generate_vector_op(jitter, 1, 0, base_offset, 1, unsafe); + generate_vector_op(jitter, 1, 0, base_offset, 1, unsafe, flonum_arg); CHECK_LIMIT(); } else if (which == 1) { if (unsafe) { @@ -6973,11 +7273,11 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_movi_l(JIT_V1, offset); if (!which) { /* vector-set! is relatively simple and worth inlining */ - generate_vector_op(jitter, 1, 1, base_offset, 0, unsafe); + generate_vector_op(jitter, 1, 1, base_offset, 0, unsafe, flonum_arg); CHECK_LIMIT(); } else if (which == 3) { /* flvector-set! is relatively simple and worth inlining */ - generate_vector_op(jitter, 1, 1, base_offset, 1, unsafe); + generate_vector_op(jitter, 1, 1, base_offset, 1, unsafe, flonum_arg); CHECK_LIMIT(); } else if (which == 1) { if (unsafe) { @@ -7012,7 +7312,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int || IS_NAMED_PRIM(rator, "unsafe-flvector-set!")) { int is_f64; is_f64 = IS_NAMED_PRIM(rator, "unsafe-f64vector-set!"); - if (can_unbox(app->args[3], 5, JIT_FPR_NUM-1)) { + if (can_unbox_inline(app->args[3], 5, JIT_FPR_NUM-1, 1)) { int got_two; if (is_constant_and_avoids_r1(app->args[1]) && is_constant_and_avoids_r1(app->args[2])) { @@ -7027,7 +7327,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int generate(app->args[3], jitter, 0, 0, JIT_R0); /* to FP reg */ CHECK_LIMIT(); --jitter->unbox; - jitter->unbox_depth -= 1; + --jitter->unbox_depth; if (!got_two) { generate(app->args[2], jitter, 0, 0, JIT_R1); CHECK_LIMIT(); @@ -7307,6 +7607,7 @@ static int generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int local int fpr0; fpr0 = JIT_FPR(jitter->unbox_depth); jit_ldxi_d_fppush(fpr0, JIT_FP, offset); + jitter->unbox_depth++; } else { GC_CAN_IGNORE jit_insn *ref; mz_rs_sync(); @@ -7684,6 +7985,35 @@ static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, return 1; } +static int generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inlined_ok, int unbox_anyway) +/* de-sync's; if refslow, failure jumps conditionally with non-flonum in R0 */ +{ + int saved; + + if (inlined_ok) { + return generate(obj, jitter, 0, 1, JIT_R0); + } + + if (!jitter->unbox || jitter->unbox_depth) + scheme_signal_error("bad unboxing mode or depth"); + + /* It probably would be useful to special-case a let-one + sequence down to something that can be unboxed. */ + + saved = jitter->unbox; + jitter->unbox = 0; + generate_non_tail(obj, jitter, 0, 1, 0); + CHECK_LIMIT(); + jitter->unbox = saved; + + if (inlined_ok || unbox_anyway) { + /* Move result into floating-point register: */ + generate_unboxing(jitter, JIT_R0); + } + + return 1; +} + /*========================================================================*/ /* expression codegen */ /*========================================================================*/ @@ -7770,7 +8100,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m CHECK_LIMIT(); (void)jit_beqi_p(unbound_global_code, target, 0); } - if (jitter->unbox) generate_unboxing(jitter); + if (jitter->unbox) generate_unboxing(jitter, target); END_JIT_DATA(0); } return 1; @@ -7806,7 +8136,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m CHECK_LIMIT(); #endif } else { - if (jitter->unbox) generate_unboxing(jitter); + if (jitter->unbox) generate_unboxing(jitter, target); } END_JIT_DATA(2); return 1; @@ -7828,7 +8158,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m } VALIDATE_RESULT(target); CHECK_LIMIT(); - if (jitter->unbox) generate_unboxing(jitter); + if (jitter->unbox) generate_unboxing(jitter, target); END_JIT_DATA(3); return 1; @@ -8668,6 +8998,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m if (flonum) { #ifdef USE_FLONUM_UNBOXING --jitter->unbox; + --jitter->unbox_depth; generate_flonum_local_unboxing(jitter, 1); CHECK_LIMIT(); (void)jit_movi_p(JIT_R0, NULL); @@ -9675,11 +10006,13 @@ static int do_generate_common(mz_jit_state *jitter, void *_data) /* *** {flvector}_{ref,set}_check_index_code *** */ /* Same calling convention as for vector ops. */ - for (i = 0; i < 2; i++) { + for (i = 0; i < 3; i++) { if (!i) { flvector_ref_check_index_code = jit_get_ip().ptr; - } else { + } else if (i == 1) { flvector_set_check_index_code = jit_get_ip().ptr; + } else { + flvector_set_flonum_check_index_code = jit_get_ip().ptr; } mz_prolog(JIT_R2); @@ -9691,8 +10024,14 @@ static int do_generate_common(mz_jit_state *jitter, void *_data) if (!i) { jit_movi_i(JIT_R1, 2); } else { - /* In set mode, value was already on run stack */ + /* In set mode, value was already on run stack + or in FP register */ jit_movi_i(JIT_R1, 3); + if (i == 2) { + /* need to box flonum */ + generate_alloc_double(jitter, 1); + jit_stxi_p(WORDS_TO_BYTES(2), JIT_RUNSTACK, JIT_R0); + } } CHECK_LIMIT(); JIT_UPDATE_THREAD_RSPTR(); @@ -10054,12 +10393,109 @@ static int do_generate_common(mz_jit_state *jitter, void *_data) jit_movr_p(JIT_R1, JIT_FP); jit_ldxr_d_fppush(JIT_FPR0, JIT_R1, JIT_R0); - generate_alloc_double(jitter); + generate_alloc_double(jitter, 1); CHECK_LIMIT(); mz_epilog(JIT_R2); } + /* *** fl1_code *** */ + /* R0 has argument, V1 has primitive proc */ + { + void *code, *code_end; + + code = jit_get_ip().ptr; + fl1_fail_code = code; + + mz_prolog(JIT_R2); + + jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + JIT_UPDATE_THREAD_RSPTR(); + jit_str_p(JIT_RUNSTACK, JIT_R0); + + jit_movi_i(JIT_R1, 1); + CHECK_LIMIT(); + + mz_prepare_direct_prim(2); + { + mz_generate_direct_prim(jit_pusharg_p(JIT_RUNSTACK), + jit_pusharg_i(JIT_R1), + JIT_V1, noncm_prim_indirect); + CHECK_LIMIT(); + } + + code_end = jit_get_ip().ptr; + add_symbol((unsigned long)code, (unsigned long)code_end - 1, scheme_false, 0); + } + + /* *** fl2{rf}{rf}_code *** */ + /* R0 and/or R1 have arguments, V1 has primitive proc, + non-register argument is in FPR0 */ + for (ii = 0; ii < 2; ii++) { + for (i = 0; i < 3; i++) { + void *code, *code_end; + int a0, a1; + + code = jit_get_ip().ptr; + switch (i) { + case 0: + fl2rr_fail_code[ii] = code; + break; + case 1: + fl2fr_fail_code[ii] = code; + break; + case 2: + fl2rf_fail_code[ii] = code; + break; + } + + if (!ii) { + a0 = 0; a1 = 1; + } else { + a0 = 1; a1 = 0; + } + + mz_prolog(JIT_R2); + + jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(2)); + JIT_UPDATE_THREAD_RSPTR(); + if ((i == 0) || (i == 2)) + jit_stxi_p(WORDS_TO_BYTES(a0), JIT_RUNSTACK, JIT_R0); + else + jit_stxi_p(WORDS_TO_BYTES(a0), JIT_RUNSTACK, JIT_V1); + if ((i == 0) || (i == 1)) + jit_stxi_p(WORDS_TO_BYTES(a1), JIT_RUNSTACK, JIT_R1); + else + jit_stxi_p(WORDS_TO_BYTES(a1), JIT_RUNSTACK, JIT_V1); + + if (i != 0) { + generate_alloc_double(jitter, 1); + CHECK_LIMIT(); + if (i == 1) { + jit_ldxi_p(JIT_V1, JIT_RUNSTACK, WORDS_TO_BYTES(a0)); + jit_stxi_p(WORDS_TO_BYTES(a0), JIT_RUNSTACK, JIT_R0); + } else { + jit_ldxi_p(JIT_V1, JIT_RUNSTACK, WORDS_TO_BYTES(a1)); + jit_stxi_p(WORDS_TO_BYTES(a1), JIT_RUNSTACK, JIT_R0); + } + } + + jit_movi_i(JIT_R1, 2); + CHECK_LIMIT(); + + mz_prepare_direct_prim(2); + { + mz_generate_direct_prim(jit_pusharg_p(JIT_RUNSTACK), + jit_pusharg_i(JIT_R1), + JIT_V1, noncm_prim_indirect); + CHECK_LIMIT(); + } + + code_end = jit_get_ip().ptr; + add_symbol((unsigned long)code, (unsigned long)code_end - 1, scheme_false, 0); + } + } + return 1; } @@ -10069,7 +10505,7 @@ static int do_generate_more_common(mz_jit_state *jitter, void *_data) /* arguments are on the Scheme stack */ { void *code_end; - jit_insn *ref, *ref2, *ref3, *refslow; + GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *refslow; struct_proc_extract_code = jit_get_ip().ptr; mz_prolog(JIT_V1); diff --git a/src/mzscheme/src/module.c b/src/mzscheme/src/module.c index 89c19d0a7c..bef573f27f 100644 --- a/src/mzscheme/src/module.c +++ b/src/mzscheme/src/module.c @@ -134,6 +134,7 @@ static Scheme_Object *kernel_modname; static Scheme_Object *kernel_symbol; static Scheme_Object *kernel_modidx; static Scheme_Module *kernel; +static Scheme_Object *flonum_modname; static Scheme_Object *unsafe_modname; /* global read-only symbols */ @@ -332,6 +333,7 @@ void scheme_init_module(Scheme_Env *env) REGISTER_SO(kernel_modname); REGISTER_SO(kernel_modidx); REGISTER_SO(unsafe_modname); + REGISTER_SO(flonum_modname); kernel_symbol = scheme_intern_symbol("#%kernel"); kernel_modname = scheme_intern_resolved_module_path(kernel_symbol); kernel_modidx = scheme_make_modidx(scheme_make_pair(quote_symbol, @@ -340,6 +342,7 @@ void scheme_init_module(Scheme_Env *env) scheme_false, kernel_modname); (void)scheme_hash_key(kernel_modidx); unsafe_modname = scheme_intern_resolved_module_path(scheme_intern_symbol("#%unsafe")); + flonum_modname = scheme_intern_resolved_module_path(scheme_intern_symbol("#%flonum")); REGISTER_SO(module_symbol); REGISTER_SO(module_begin_symbol); @@ -597,10 +600,16 @@ int scheme_is_unsafe_modname(Scheme_Object *modname) return SAME_OBJ(modname, unsafe_modname); } +int scheme_is_flonum_modname(Scheme_Object *modname) +{ + return SAME_OBJ(modname, flonum_modname); +} + static int is_builtin_modname(Scheme_Object *modname) { return (SAME_OBJ(modname, kernel_modname) - || SAME_OBJ(modname, unsafe_modname)); + || SAME_OBJ(modname, unsafe_modname) + || SAME_OBJ(modname, flonum_modname)); } Scheme_Object *scheme_sys_wraps(Scheme_Comp_Env *env) @@ -1785,7 +1794,8 @@ static Scheme_Object *namespace_unprotect_module(int argc, Scheme_Object *argv[] code_insp = scheme_get_param(scheme_current_config(), MZCONFIG_CODE_INSPECTOR); - if (!SAME_OBJ(name, kernel_modname)) { + if (!SAME_OBJ(name, kernel_modname) + && !SAME_OBJ(name, flonum_modname)) { if (SAME_OBJ(name, unsafe_modname)) menv2 = scheme_get_unsafe_env(); else @@ -2447,6 +2457,8 @@ void scheme_prep_namespace_rename(Scheme_Env *menv) im = kernel; else if (SAME_OBJ(name, unsafe_modname)) im = scheme_get_unsafe_env()->module; + else if (SAME_OBJ(name, flonum_modname)) + im = scheme_get_flonum_env()->module; else im = (Scheme_Module *)scheme_hash_get(menv->module_registry, name); @@ -2841,6 +2853,8 @@ static Scheme_Object *module_export_protected_p(int argc, Scheme_Object **argv) mv = (Scheme_Object *)kernel; else if (SAME_OBJ(modname, unsafe_modname)) mv = (Scheme_Object *)scheme_get_unsafe_env()->module; + else if (SAME_OBJ(modname, flonum_modname)) + mv = (Scheme_Object *)scheme_get_flonum_env()->module; else mv = scheme_hash_get(env->module_registry, modname); if (!mv) { @@ -3134,6 +3148,8 @@ static Scheme_Module *module_load(Scheme_Object *name, Scheme_Env *env, const ch return kernel; else if (name == unsafe_modname) return scheme_get_unsafe_env()->module; + else if (name == flonum_modname) + return scheme_get_flonum_env()->module; else { Scheme_Module *m; @@ -3218,6 +3234,8 @@ Scheme_Env *scheme_module_access(Scheme_Object *name, Scheme_Env *env, int rev_m return scheme_get_kernel_env(); else if ((name == unsafe_modname) && !rev_mod_phase) return scheme_get_unsafe_env(); + else if ((name == flonum_modname) && !rev_mod_phase) + return scheme_get_flonum_env(); else { Scheme_Object *chain; Scheme_Env *menv; @@ -3556,7 +3574,8 @@ int scheme_module_export_position(Scheme_Object *modname, Scheme_Env *env, Schem Scheme_Object *pos; if (SAME_OBJ(modname, kernel_modname) - || SAME_OBJ(modname, unsafe_modname)) + || SAME_OBJ(modname, unsafe_modname) + || SAME_OBJ(modname, flonum_modname)) return -1; m = module_load(modname, env, NULL); @@ -3580,8 +3599,9 @@ Scheme_Object *scheme_module_syntax(Scheme_Object *modname, Scheme_Env *env, Sch kenv = scheme_get_kernel_env(); name = SCHEME_STX_SYM(name); return scheme_lookup_in_table(kenv->syntax, (char *)name); - } else if (SAME_OBJ(modname, unsafe_modname)) { - /* no unsafe syntax */ + } else if (SAME_OBJ(modname, unsafe_modname) + || SAME_OBJ(modname, flonum_modname)) { + /* no unsafe or flonum syntax */ return NULL; } else { Scheme_Env *menv; @@ -4528,6 +4548,12 @@ Scheme_Object *scheme_builtin_value(const char *name) if (v) return v; + /* Try flonum next: */ + a[0] = flonum_modname; + v = _dynamic_require(2, a, scheme_get_env(NULL), 0, 0, 0, 0, 0, -1); + if (v) + return v; + /* Try unsafe next: */ a[0] = unsafe_modname; v = _dynamic_require(2, a, scheme_get_env(NULL), 0, 0, 0, 0, 0, -1); @@ -4836,6 +4862,8 @@ module_execute(Scheme_Object *data) if (SAME_OBJ(m->modname, kernel_modname)) old_menv = scheme_get_kernel_env(); + else if (SAME_OBJ(m->modname, flonum_modname)) + old_menv = scheme_get_flonum_env(); else if (SAME_OBJ(m->modname, unsafe_modname)) old_menv = scheme_get_unsafe_env(); else @@ -5457,12 +5485,15 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, LOG_START_EXPAND(m); if (SAME_OBJ(m->modname, kernel_modname) - || SAME_OBJ(m->modname, unsafe_modname)) { + || SAME_OBJ(m->modname, unsafe_modname) + || SAME_OBJ(m->modname, flonum_modname)) { /* Too confusing. Give it a different name while compiling. */ Scheme_Object *k2; const char *kname; if (SAME_OBJ(m->modname, kernel_modname)) kname = "#%kernel"; + else if (SAME_OBJ(m->modname, flonum_modname)) + kname = "#%flonum"; else kname = "#%unsafe"; k2 = scheme_intern_resolved_module_path(scheme_make_symbol(kname)); /* uninterned! */ @@ -8800,6 +8831,8 @@ void scheme_do_module_rename_unmarshal(Scheme_Object *rn, Scheme_Object *info, me = kernel->me; } else if (SAME_OBJ(unsafe_modname, name)) { me = scheme_get_unsafe_env()->module->me; + } else if (SAME_OBJ(flonum_modname, name)) { + me = scheme_get_flonum_env()->module->me; } else { if (!export_registry) { env = scheme_get_env(scheme_current_config()); diff --git a/src/mzscheme/src/numarith.c b/src/mzscheme/src/numarith.c index 7b923af9bf..572db76c42 100644 --- a/src/mzscheme/src/numarith.c +++ b/src/mzscheme/src/numarith.c @@ -49,6 +49,13 @@ static Scheme_Object *fl_div (int argc, Scheme_Object *argv[]); static Scheme_Object *fl_abs (int argc, Scheme_Object *argv[]); static Scheme_Object *fl_sqrt (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_plus (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_minus (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_mult (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_div (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_abs (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_sqrt (int argc, Scheme_Object *argv[]); + #define zeroi scheme_exact_zero void scheme_init_numarith(Scheme_Env *env) @@ -109,6 +116,41 @@ void scheme_init_numarith(Scheme_Env *env) env); } +void scheme_init_flonum_numarith(Scheme_Env *env) +{ + Scheme_Object *p; + + p = scheme_make_folding_prim(fl_plus, "fl+", 2, 2, 1); + if (scheme_can_inline_fp_op()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; + scheme_add_global_constant("fl+", p, env); + + p = scheme_make_folding_prim(fl_minus, "fl-", 2, 2, 1); + if (scheme_can_inline_fp_op()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; + scheme_add_global_constant("fl-", p, env); + + p = scheme_make_folding_prim(fl_mult, "fl*", 2, 2, 1); + if (scheme_can_inline_fp_op()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; + scheme_add_global_constant("fl*", p, env); + + p = scheme_make_folding_prim(fl_div, "fl/", 2, 2, 1); + if (scheme_can_inline_fp_op()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; + scheme_add_global_constant("fl/", p, env); + + p = scheme_make_folding_prim(fl_abs, "flabs", 1, 1, 1); + if (scheme_can_inline_fp_op()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + scheme_add_global_constant("flabs", p, env); + + p = scheme_make_folding_prim(fl_sqrt, "flsqrt", 1, 1, 1); + if (scheme_can_inline_fp_op()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + scheme_add_global_constant("flsqrt", p, env); +} + void scheme_init_unsafe_numarith(Scheme_Env *env) { Scheme_Object *p; @@ -145,37 +187,37 @@ void scheme_init_unsafe_numarith(Scheme_Env *env) scheme_add_global_constant("unsafe-fxabs", p, env); - p = scheme_make_folding_prim(fl_plus, "unsafe-fl+", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_fl_plus, "unsafe-fl+", 2, 2, 1); if (scheme_can_inline_fp_op()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; scheme_add_global_constant("unsafe-fl+", p, env); - p = scheme_make_folding_prim(fl_minus, "unsafe-fl-", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_fl_minus, "unsafe-fl-", 2, 2, 1); if (scheme_can_inline_fp_op()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; scheme_add_global_constant("unsafe-fl-", p, env); - p = scheme_make_folding_prim(fl_mult, "unsafe-fl*", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_fl_mult, "unsafe-fl*", 2, 2, 1); if (scheme_can_inline_fp_op()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; scheme_add_global_constant("unsafe-fl*", p, env); - p = scheme_make_folding_prim(fl_div, "unsafe-fl/", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_fl_div, "unsafe-fl/", 2, 2, 1); if (scheme_can_inline_fp_op()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; scheme_add_global_constant("unsafe-fl/", p, env); - p = scheme_make_folding_prim(fl_abs, "unsafe-flabs", 1, 1, 1); + p = scheme_make_folding_prim(unsafe_fl_abs, "unsafe-flabs", 1, 1, 1); if (scheme_can_inline_fp_op()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; scheme_add_global_constant("unsafe-flabs", p, env); - p = scheme_make_folding_prim(fl_sqrt, "unsafe-flsqrt", 1, 1, 1); + p = scheme_make_folding_prim(unsafe_fl_sqrt, "unsafe-flsqrt", 1, 1, 1); if (scheme_can_inline_fp_op()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; @@ -834,25 +876,48 @@ static Scheme_Object *fx_abs(int argc, Scheme_Object *argv[]) return scheme_make_double(v); \ } -UNSAFE_FL(fl_plus, +, plus) -UNSAFE_FL(fl_minus, -, minus) -UNSAFE_FL(fl_mult, *, mult) -UNSAFE_FL(fl_div, /, div_prim) +UNSAFE_FL(unsafe_fl_plus, +, plus) +UNSAFE_FL(unsafe_fl_minus, -, minus) +UNSAFE_FL(unsafe_fl_mult, *, mult) +UNSAFE_FL(unsafe_fl_div, /, div_prim) -static Scheme_Object *fl_abs(int argc, Scheme_Object *argv[]) -{ - double v; - if (scheme_current_thread->constant_folding) return scheme_abs(argc, argv); - v = SCHEME_DBL_VAL(argv[0]); - v = fabs(v); - return scheme_make_double(v); -} +#define UNSAFE_FL1(name, op, fold) \ + static Scheme_Object *name(int argc, Scheme_Object *argv[]) \ + { \ + double v; \ + if (scheme_current_thread->constant_folding) return fold(argc, argv); \ + v = SCHEME_DBL_VAL(argv[0]); \ + v = op(v); \ + return scheme_make_double(v); \ + } -static Scheme_Object *fl_sqrt(int argc, Scheme_Object *argv[]) -{ - double v; - if (scheme_current_thread->constant_folding) return scheme_sqrt(argc, argv); - v = SCHEME_DBL_VAL(argv[0]); - v = sqrt(v); - return scheme_make_double(v); -} +UNSAFE_FL1(unsafe_fl_abs, fabs, scheme_abs) +UNSAFE_FL1(unsafe_fl_sqrt, sqrt, scheme_sqrt) + +#define SAFE_FL(name, sname, op) \ + static Scheme_Object *name(int argc, Scheme_Object *argv[]) \ + { \ + double v; \ + if (!SCHEME_FLOATP(argv[0])) scheme_wrong_type(sname, "inexact-real", 0, argc, argv); \ + if (!SCHEME_FLOATP(argv[1])) scheme_wrong_type(sname, "inexact-real", 1, argc, argv); \ + v = SCHEME_DBL_VAL(argv[0]) op SCHEME_DBL_VAL(argv[1]); \ + return scheme_make_double(v); \ + } + +SAFE_FL(fl_plus, "fl+", +) +SAFE_FL(fl_minus, "fl-", -) +SAFE_FL(fl_mult, "fl*", *) +SAFE_FL(fl_div, "fl/", /) + +#define SAFE_FL1(name, sname, op) \ + static Scheme_Object *name(int argc, Scheme_Object *argv[]) \ + { \ + double v; \ + if (!SCHEME_FLOATP(argv[0])) scheme_wrong_type(sname, "inexact-real", 0, argc, argv); \ + v = SCHEME_DBL_VAL(argv[0]); \ + v = op(v); \ + return scheme_make_double(v); \ + } + +SAFE_FL1(fl_abs, "flabs", fabs) +SAFE_FL1(fl_sqrt, "flsqrt", sqrt) diff --git a/src/mzscheme/src/number.c b/src/mzscheme/src/number.c index 42feaa95b8..563d59e5b7 100644 --- a/src/mzscheme/src/number.c +++ b/src/mzscheme/src/number.c @@ -103,6 +103,8 @@ static Scheme_Object *flvector_p (int argc, Scheme_Object *argv[]); static Scheme_Object *flvector_length (int argc, Scheme_Object *argv[]); static Scheme_Object *make_flvector (int argc, Scheme_Object *argv[]); +static Scheme_Object *integer_to_fl (int argc, Scheme_Object *argv[]); + static Scheme_Object *fx_and (int argc, Scheme_Object *argv[]); static Scheme_Object *fx_or (int argc, Scheme_Object *argv[]); static Scheme_Object *fx_xor (int argc, Scheme_Object *argv[]); @@ -506,6 +508,11 @@ scheme_init_number (Scheme_Env *env) 1, 1, 1), env); +} +void scheme_init_flonum_number(Scheme_Env *env) +{ + Scheme_Object *p; + scheme_add_global_constant("flvector", scheme_make_prim_w_arity(flvector, "flvector", @@ -538,6 +545,11 @@ scheme_init_number (Scheme_Env *env) 3, 3); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_NARY_INLINED; scheme_add_global_constant("flvector-set!", p, env); + + p = scheme_make_folding_prim(integer_to_fl, "->fl", 1, 1, 1); + if (scheme_can_inline_fp_op()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + scheme_add_global_constant("->fl", p, env); } void scheme_init_unsafe_number(Scheme_Env *env) @@ -3091,3 +3103,14 @@ static Scheme_Object *unsafe_flvector_set (int argc, Scheme_Object *argv[]) return scheme_void; } + +static Scheme_Object *integer_to_fl (int argc, Scheme_Object *argv[]) +{ + if (SCHEME_INTP(argv[0]) + || SCHEME_BIGNUMP(argv[0])) { + return scheme_exact_to_inexact(argc, argv); + } else { + scheme_wrong_type("->fl", "exact integer", 0, argc, argv); + return NULL; + } +} diff --git a/src/mzscheme/src/numcomp.c b/src/mzscheme/src/numcomp.c index 919b066624..19ff06f001 100644 --- a/src/mzscheme/src/numcomp.c +++ b/src/mzscheme/src/numcomp.c @@ -50,6 +50,12 @@ static Scheme_Object *fl_gt (int argc, Scheme_Object *argv[]); static Scheme_Object *fl_lt_eq (int argc, Scheme_Object *argv[]); static Scheme_Object *fl_gt_eq (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_eq (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_lt (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_gt (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_lt_eq (int argc, Scheme_Object *argv[]); +static Scheme_Object *unsafe_fl_gt_eq (int argc, Scheme_Object *argv[]); + #define zeroi scheme_exact_zero void scheme_init_numcomp(Scheme_Env *env) @@ -104,6 +110,36 @@ void scheme_init_numcomp(Scheme_Env *env) scheme_add_global_constant("min", p, env); } +void scheme_init_flonum_numcomp(Scheme_Env *env) +{ + Scheme_Object *p; + + p = scheme_make_folding_prim(fl_eq, "fl=", 2, 2, 1); + if (scheme_can_inline_fp_comp()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; + scheme_add_global_constant("fl=", p, env); + + p = scheme_make_folding_prim(fl_lt, "fl<", 2, 2, 1); + if (scheme_can_inline_fp_comp()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; + scheme_add_global_constant("fl<", p, env); + + p = scheme_make_folding_prim(fl_gt, "fl>", 2, 2, 1); + if (scheme_can_inline_fp_comp()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; + scheme_add_global_constant("fl>", p, env); + + p = scheme_make_folding_prim(fl_lt_eq, "fl<=", 2, 2, 1); + if (scheme_can_inline_fp_comp()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; + scheme_add_global_constant("fl<=", p, env); + + p = scheme_make_folding_prim(fl_gt_eq, "fl>=", 2, 2, 1); + if (scheme_can_inline_fp_comp()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; + scheme_add_global_constant("fl>=", p, env); +} + void scheme_init_unsafe_numcomp(Scheme_Env *env) { Scheme_Object *p; @@ -133,31 +169,31 @@ void scheme_init_unsafe_numcomp(Scheme_Env *env) | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); scheme_add_global_constant("unsafe-fx>=", p, env); - p = scheme_make_folding_prim(fl_eq, "unsafe-fl=", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_fl_eq, "unsafe-fl=", 2, 2, 1); if (scheme_can_inline_fp_comp()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; scheme_add_global_constant("unsafe-fl=", p, env); - p = scheme_make_folding_prim(fl_lt, "unsafe-fl<", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_fl_lt, "unsafe-fl<", 2, 2, 1); if (scheme_can_inline_fp_comp()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; scheme_add_global_constant("unsafe-fl<", p, env); - p = scheme_make_folding_prim(fl_gt, "unsafe-fl>", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_fl_gt, "unsafe-fl>", 2, 2, 1); if (scheme_can_inline_fp_comp()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; scheme_add_global_constant("unsafe-fl>", p, env); - p = scheme_make_folding_prim(fl_lt_eq, "unsafe-fl<=", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_fl_lt_eq, "unsafe-fl<=", 2, 2, 1); if (scheme_can_inline_fp_comp()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; scheme_add_global_constant("unsafe-fl<=", p, env); - p = scheme_make_folding_prim(fl_gt_eq, "unsafe-fl>=", 2, 2, 1); + p = scheme_make_folding_prim(unsafe_fl_gt_eq, "unsafe-fl>=", 2, 2, 1); if (scheme_can_inline_fp_comp()) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; @@ -387,6 +423,23 @@ UNSAFE_FX(fx_gt, >, scheme_bin_gt) UNSAFE_FX(fx_lt_eq, <=, scheme_bin_lt_eq) UNSAFE_FX(fx_gt_eq, >=, scheme_bin_gt_eq) +#define SAFE_FL(name, sname, op) \ + static Scheme_Object *name(int argc, Scheme_Object *argv[]) \ + { \ + if (!SCHEME_FLOATP(argv[0])) scheme_wrong_type(sname, "inexact-real", 0, argc, argv); \ + if (!SCHEME_FLOATP(argv[1])) scheme_wrong_type(sname, "inexact-real", 1, argc, argv); \ + if (SCHEME_DBL_VAL(argv[0]) op SCHEME_DBL_VAL(argv[1])) \ + return scheme_true; \ + else \ + return scheme_false; \ + } + +SAFE_FL(fl_eq, "fl=", ==) +SAFE_FL(fl_lt, "fl<", <) +SAFE_FL(fl_gt, "fl>", >) +SAFE_FL(fl_lt_eq, "fl<=", <=) +SAFE_FL(fl_gt_eq, "fl>=", >=) + #define UNSAFE_FL(name, op, fold) \ static Scheme_Object *name(int argc, Scheme_Object *argv[]) \ { \ @@ -397,8 +450,8 @@ UNSAFE_FX(fx_gt_eq, >=, scheme_bin_gt_eq) return scheme_false; \ } -UNSAFE_FL(fl_eq, ==, scheme_bin_eq) -UNSAFE_FL(fl_lt, <, scheme_bin_lt) -UNSAFE_FL(fl_gt, >, scheme_bin_gt) -UNSAFE_FL(fl_lt_eq, <=, scheme_bin_lt_eq) -UNSAFE_FL(fl_gt_eq, >=, scheme_bin_gt_eq) +UNSAFE_FL(unsafe_fl_eq, ==, scheme_bin_eq) +UNSAFE_FL(unsafe_fl_lt, <, scheme_bin_lt) +UNSAFE_FL(unsafe_fl_gt, >, scheme_bin_gt) +UNSAFE_FL(unsafe_fl_lt_eq, <=, scheme_bin_lt_eq) +UNSAFE_FL(unsafe_fl_gt_eq, >=, scheme_bin_gt_eq) diff --git a/src/mzscheme/src/read.c b/src/mzscheme/src/read.c index b034f3ecd1..f006c9f721 100644 --- a/src/mzscheme/src/read.c +++ b/src/mzscheme/src/read.c @@ -4688,7 +4688,7 @@ static Scheme_Object *read_compact(CPort *port, int use_stack) break; case CPT_REFERENCE: l = read_compact_number(port); - RANGE_CHECK(l, < (EXPECTED_PRIM_COUNT + EXPECTED_UNSAFE_COUNT)); + RANGE_CHECK(l, < (EXPECTED_PRIM_COUNT + EXPECTED_UNSAFE_COUNT + EXPECTED_FLONUM_COUNT)); return variable_references[l]; break; case CPT_LOCAL: diff --git a/src/mzscheme/src/schminc.h b/src/mzscheme/src/schminc.h index f66b6740f2..5251caa6a3 100644 --- a/src/mzscheme/src/schminc.h +++ b/src/mzscheme/src/schminc.h @@ -13,8 +13,9 @@ #define USE_COMPILED_STARTUP 1 -#define EXPECTED_PRIM_COUNT 965 +#define EXPECTED_PRIM_COUNT 959 #define EXPECTED_UNSAFE_COUNT 53 +#define EXPECTED_FLONUM_COUNT 18 #ifdef MZSCHEME_SOMETHING_OMITTED # undef USE_COMPILED_STARTUP diff --git a/src/mzscheme/src/schpriv.h b/src/mzscheme/src/schpriv.h index f2cbb2d300..8527a0741f 100644 --- a/src/mzscheme/src/schpriv.h +++ b/src/mzscheme/src/schpriv.h @@ -184,10 +184,13 @@ void scheme_init_vector(Scheme_Env *env); void scheme_init_unsafe_vector(Scheme_Env *env); void scheme_init_string(Scheme_Env *env); void scheme_init_number(Scheme_Env *env); -void scheme_init_numarith(Scheme_Env *env); -void scheme_init_unsafe_numarith(Scheme_Env *env); +void scheme_init_flonum_number(Scheme_Env *env); void scheme_init_unsafe_number(Scheme_Env *env); +void scheme_init_numarith(Scheme_Env *env); +void scheme_init_flonum_numarith(Scheme_Env *env); +void scheme_init_unsafe_numarith(Scheme_Env *env); void scheme_init_numcomp(Scheme_Env *env); +void scheme_init_flonum_numcomp(Scheme_Env *env); void scheme_init_unsafe_numcomp(Scheme_Env *env); void scheme_init_numstr(Scheme_Env *env); void scheme_init_eval(Scheme_Env *env); @@ -2117,6 +2120,7 @@ Scheme_Object *scheme_lookup_binding(Scheme_Object *symbol, Scheme_Comp_Env *env Scheme_Object **_lexical_binding_id); Scheme_Object *scheme_extract_unsafe(Scheme_Object *o); +Scheme_Object *scheme_extract_flonum(Scheme_Object *o); Scheme_Object *scheme_add_env_renames(Scheme_Object *stx, Scheme_Comp_Env *env, Scheme_Comp_Env *upto); @@ -2321,7 +2325,7 @@ Scheme_Object *scheme_toplevel_to_flagged_toplevel(Scheme_Object *tl, int flags) void scheme_env_make_closure_map(Optimize_Info *frame, mzshort *size, mzshort **map); int scheme_env_uses_toplevel(Optimize_Info *frame); -int scheme_wants_flonum_arguments(Scheme_Object *rator); +int scheme_wants_flonum_arguments(Scheme_Object *rator, int rotate_mode); int scheme_expr_produces_flonum(Scheme_Object *expr); typedef struct Scheme_Once_Used { @@ -2851,6 +2855,7 @@ Scheme_Object *scheme_hash_module_variable(Scheme_Env *env, Scheme_Object *modid Scheme_Env *scheme_get_kernel_env(); int scheme_is_kernel_env(); Scheme_Env *scheme_get_unsafe_env(); +Scheme_Env *scheme_get_flonum_env(); void scheme_install_initial_module_set(Scheme_Env *env); Scheme_Bucket_Table *scheme_clone_toplevel(Scheme_Bucket_Table *ht, Scheme_Env *home); @@ -2863,6 +2868,7 @@ Scheme_Module *scheme_extract_compiled_module(Scheme_Object *o); int scheme_is_kernel_modname(Scheme_Object *modname); int scheme_is_unsafe_modname(Scheme_Object *modname); +int scheme_is_flonum_modname(Scheme_Object *modname); void scheme_clear_modidx_cache(void); void scheme_clear_shift_cache(void); diff --git a/src/mzscheme/src/schvers.h b/src/mzscheme/src/schvers.h index 3cec7839a6..c8d9ebdd33 100644 --- a/src/mzscheme/src/schvers.h +++ b/src/mzscheme/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "4.2.3.7" +#define MZSCHEME_VERSION "4.2.3.8" #define MZSCHEME_VERSION_X 4 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 3 -#define MZSCHEME_VERSION_W 7 +#define MZSCHEME_VERSION_W 8 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/src/mzscheme/src/syntax.c b/src/mzscheme/src/syntax.c index 46180fc1f5..fae1bc9eab 100644 --- a/src/mzscheme/src/syntax.c +++ b/src/mzscheme/src/syntax.c @@ -3854,7 +3854,7 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info) if (SAME_TYPE(SCHEME_TYPE(app->rand), scheme_local_type) && (SCHEME_LOCAL_POS(app->rand) == 1)) { if ((SCHEME_TYPE(app->rator) > _scheme_values_types_) - && !scheme_wants_flonum_arguments(app->rator)) { + && !scheme_wants_flonum_arguments(app->rator, 1)) { /* Move to app, and drop let-one: */ app->rand = ((Scheme_Let_One *)body)->value; scheme_reset_app2_eval_type(app);