full unboxing for extflonums, plus `ffi/unsafe' support
Includes a repair for floating-point `min' and `max' that affects all x86 builds that use SSE arithmetic, leaving the (otherwise unused) floating-point stack in a bad state, which might have affected x87-using C/foreign libraries running alongside Racket.
This commit is contained in:
parent
a348e5421d
commit
840fc9c657
|
@ -10,12 +10,12 @@
|
|||
cpointer? cpointer-gcable? prop:cpointer
|
||||
ptr-equal? ptr-add ptr-ref ptr-set! (protect-out cast)
|
||||
ptr-offset ptr-add! offset-ptr? set-ptr-offset!
|
||||
vector->cpointer flvector->cpointer saved-errno lookup-errno
|
||||
vector->cpointer flvector->cpointer extflvector->cpointer saved-errno lookup-errno
|
||||
ctype? make-ctype make-cstruct-type make-array-type make-union-type
|
||||
make-sized-byte-string ctype->layout
|
||||
_void _int8 _uint8 _int16 _uint16 _int32 _uint32 _int64 _uint64
|
||||
_fixint _ufixint _fixnum _ufixnum
|
||||
_float _double _double*
|
||||
_float _double _longdouble _double*
|
||||
_bool _pointer _gcpointer _scheme (rename-out [_scheme _racket]) _fpointer function-ptr
|
||||
memcpy memmove memset
|
||||
malloc-immobile-cell free-immobile-cell
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
(require "unsafe.rkt"
|
||||
racket/unsafe/ops
|
||||
racket/extflonum
|
||||
(for-syntax racket/extflonum)
|
||||
(for-syntax racket/base))
|
||||
|
||||
(define-syntax define*
|
||||
|
@ -37,6 +39,7 @@
|
|||
[_TAG* (id "_" "*")]
|
||||
[TAGname name]
|
||||
[f64? (if (eq? (syntax-e #'TAG) 'f64) #'#t #'#f)]
|
||||
[f80? (if (eq? (syntax-e #'TAG) 'f80) #'#t #'#f)]
|
||||
[s16? (if (eq? (syntax-e #'TAG) 's16) #'#t #'#f)]
|
||||
[u16? (if (eq? (syntax-e #'TAG) 'u16) #'#t #'#f)])
|
||||
#'(begin
|
||||
|
@ -62,6 +65,7 @@
|
|||
;; use JIT-inlined operation if available:
|
||||
(cond
|
||||
[f64? (unsafe-f64vector-ref v i)]
|
||||
[f80? (unsafe-f80vector-ref v i)]
|
||||
[s16? (unsafe-s16vector-ref v i)]
|
||||
[u16? (unsafe-u16vector-ref v i)]
|
||||
[else (ptr-ref (TAG-ptr v) type i)])
|
||||
|
@ -75,6 +79,8 @@
|
|||
(cond
|
||||
[(and f64? (inexact-real? x))
|
||||
(unsafe-f64vector-set! v i x)]
|
||||
[(and f80? (extflonum? x))
|
||||
(unsafe-f80vector-set! v i x)]
|
||||
[(and s16? (fixnum? x) (unsafe-fx<= -32768 x) (unsafe-fx<= x 32767))
|
||||
(unsafe-s16vector-set! v i x)]
|
||||
[(and u16? (fixnum? x) (unsafe-fx<= 0 x) (unsafe-fx<= x 65535))
|
||||
|
@ -135,6 +141,7 @@
|
|||
(srfi-4-define/provide u64 _uint64)
|
||||
(srfi-4-define/provide f32 _float)
|
||||
(srfi-4-define/provide f64 _double*)
|
||||
(srfi-4-define/provide f80 _longdouble)
|
||||
|
||||
;; simply rename bytes* to implement the u8vector type
|
||||
(provide (rename-out [bytes? u8vector? ]
|
||||
|
|
|
@ -180,6 +180,13 @@ coerce C values to double-precision Racket numbers.
|
|||
The type @racket[_double*]
|
||||
coerces any Racket real number to a C @cpp{double}.}
|
||||
|
||||
@defthing[_longdouble ctype?]{
|
||||
|
||||
Represents the @cpp{long double} type on platforms where it is
|
||||
supported, in which case Racket @tech[#:doc
|
||||
reference.scrbl]{extflonums} convert to and from @cpp{long double}
|
||||
values.}
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
|
||||
@section{Other Atomic Types}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#lang scribble/doc
|
||||
@(require "utils.rkt" (only-in scribble/decode make-splice))
|
||||
@(require "utils.rkt"
|
||||
(only-in scribble/decode make-splice)
|
||||
scribble/racket
|
||||
(for-label racket/extflonum))
|
||||
|
||||
@title[#:tag "homogeneous-vectors"]{Safe Homogenous Vectors}
|
||||
|
||||
|
@ -7,7 +10,7 @@
|
|||
|
||||
Homogenous vectors are similar to C vectors (see
|
||||
@secref["foreign:cvector"]), except that they define different types
|
||||
of vectors, each with a hard-wired type. An exception is the
|
||||
of vectors, each with a fixed element type. An exception is the
|
||||
@racketidfont{u8} family of bindings, which are just aliases for
|
||||
byte-string bindings; for example, @racket[make-u8vector] is an alias
|
||||
for @racket[make-bytes].
|
||||
|
@ -16,12 +19,12 @@ for @racket[make-bytes].
|
|||
(require (for-syntax scheme/base))
|
||||
(define-syntax (srfi-4-vector stx)
|
||||
(syntax-case stx ()
|
||||
[(_ id elem)
|
||||
#'(srfi-4-vector/desc id elem make-splice
|
||||
[(_ id elem number?)
|
||||
#'(srfi-4-vector/desc id elem number? make-splice
|
||||
"Like " (racket make-vector) ", etc., but for " (racket elem) " elements.")]))
|
||||
(define-syntax (srfi-4-vector/desc stx)
|
||||
(syntax-case stx ()
|
||||
[(_ id elem extra desc ...)
|
||||
[(_ id elem as-number? extra desc ...)
|
||||
(let ([mk
|
||||
(lambda l
|
||||
(datum->syntax
|
||||
|
@ -44,7 +47,10 @@ for @racket[make-bytes].
|
|||
[->list (mk #'id "vector->list")]
|
||||
[->cpointer (mk #'id "vector->cpointer")]
|
||||
[_vec (mk "_" #'id "vector")])
|
||||
#`(begin
|
||||
#`(let-syntax ([number? (make-element-id-transformer
|
||||
(lambda (stx)
|
||||
#'(racket as-number?)))])
|
||||
(list
|
||||
(defproc* ([(make [len exact-nonnegative-integer?]) ?]
|
||||
[(vecr [val number?] (... ...)) ?]
|
||||
[(? [v any/c]) boolean?]
|
||||
|
@ -92,22 +98,22 @@ for @racket[make-bytes].
|
|||
10))
|
||||
_vec]
|
||||
"Like " (racket _cvector) ", but for vectors of "
|
||||
(racket elem) " elements."))))])))
|
||||
(racket elem) " elements.")))))])))
|
||||
|
||||
|
||||
@srfi-4-vector/desc[u8 _uint8 (lambda (x) (make-splice null))]{
|
||||
@srfi-4-vector/desc[u8 _uint8 byte? (lambda (x) (make-splice null))]{
|
||||
|
||||
Like @racket[_cvector], but for vectors of @racket[_byte] elements. These are
|
||||
Like @racket[_cvector], but for vectors of @racket[_uint8] elements. These are
|
||||
aliases for @racketidfont{byte} operations, where @racket[u8vector->cpointer]
|
||||
is the identity function.}
|
||||
|
||||
@srfi-4-vector[s8 _int8]
|
||||
@srfi-4-vector[s16 _int16]
|
||||
@srfi-4-vector[u16 _uint16]
|
||||
@srfi-4-vector[s32 _int32]
|
||||
@srfi-4-vector[u32 _uint32]
|
||||
@srfi-4-vector[s64 _int64]
|
||||
@srfi-4-vector[u64 _uint64]
|
||||
@srfi-4-vector[f32 _float]
|
||||
@srfi-4-vector[f64 _double*]
|
||||
|
||||
@srfi-4-vector[s8 _int8 (integer-in -128 127)]
|
||||
@srfi-4-vector[s16 _int16 (integer-in -32768 32767)]
|
||||
@srfi-4-vector[u16 _uint16 (integer-in 0 65535)]
|
||||
@srfi-4-vector[s32 _int32 (integer-in -2147483648 2147483647)]
|
||||
@srfi-4-vector[u32 _uint32 (integer-in 0 4294967295)]
|
||||
@srfi-4-vector[s64 _int64 (integer-in -9223372036854775808 9223372036854775807)]
|
||||
@srfi-4-vector[u64 _uint64 (integer-in 0 18446744073709551615)]
|
||||
@srfi-4-vector[f32 _float real?]
|
||||
@srfi-4-vector[f64 _double* real?]
|
||||
@srfi-4-vector[f80 _longdouble extflonum?]
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
|
||||
(Section 'foreign)
|
||||
|
||||
(require mzlib/foreign)
|
||||
(unsafe!)
|
||||
(require ffi/unsafe
|
||||
ffi/unsafe/cvector
|
||||
ffi/vector
|
||||
racket/extflonum)
|
||||
|
||||
(test #f malloc 0)
|
||||
(test #f malloc 0 _int)
|
||||
|
@ -481,6 +483,17 @@
|
|||
(define _values (get-ffi-obj 'scheme_values #f (_fun _int (_list i _racket) -> _racket)))
|
||||
(test-values '(1 "b" three) (lambda () (_values 3 (list 1 "b" 'three)))))
|
||||
|
||||
(when (extflonum-available?)
|
||||
(define m (malloc _longdouble))
|
||||
(ptr-set! m _longdouble 13.57t0)
|
||||
(test 13.57t0 ptr-ref m _longdouble)
|
||||
|
||||
(define v (extflvector 1.1t0 2.2t0 3.3t0))
|
||||
(test 3.3t0 extflvector-ref v 2)
|
||||
(test (void) extflvector-set! v 2 4.4t0)
|
||||
(test 4.4t0 extflvector-ref v 2)
|
||||
(test 2.2t0 ptr-ref (ptr-add (extflvector->cpointer v) (ctype-sizeof _longdouble)) _longdouble))
|
||||
|
||||
(report-errs)
|
||||
|
||||
#| --- ignore everything below ---
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
(Section 'optimization)
|
||||
|
||||
(require racket/flonum
|
||||
racket/extflonum
|
||||
racket/fixnum
|
||||
racket/unsafe/ops
|
||||
compiler/zo-parse
|
||||
|
@ -15,6 +16,7 @@
|
|||
(parameterize ([current-namespace (make-base-namespace)]
|
||||
[eval-jit-enabled #t])
|
||||
(namespace-require 'racket/flonum)
|
||||
(namespace-require 'racket/extflonum)
|
||||
(namespace-require 'racket/fixnum)
|
||||
(eval '(define-values (prop:thing thing? thing-ref)
|
||||
(make-struct-type-property 'thing)))
|
||||
|
@ -25,7 +27,7 @@
|
|||
[check-error-message (lambda (name proc [fixnum? #f])
|
||||
(unless (memq name '(eq? eqv? equal?
|
||||
not null? pair? list?
|
||||
real? number? boolean?
|
||||
real? number? boolean?
|
||||
procedure? symbol?
|
||||
string? bytes?
|
||||
vector? box?
|
||||
|
@ -71,7 +73,7 @@
|
|||
[bin0 (lambda (v op arg1 arg2)
|
||||
;; (printf "Trying ~a ~a ~a\n" op arg1 arg2);
|
||||
(let ([name `(,op ,arg1 ,arg2)])
|
||||
(test v name ((eval `(lambda (x) (,op x ',arg2))) arg1))
|
||||
(test v name ((eval `(lambda (x) (,op x ',arg2))) arg1))
|
||||
(test v name ((eval `(lambda (x) (,op ',arg1 x))) arg2))
|
||||
(test v name ((eval `(lambda (x y) (,op x y))) arg1 arg2))
|
||||
(test v name ((eval `(lambda (x y)
|
||||
|
@ -172,6 +174,7 @@
|
|||
(check-error-message op (eval `(lambda (x) (,op (,get-arg1) ,arg2 x)))))
|
||||
(tri0 v op get-arg1 arg2 arg3 check-effect))])
|
||||
|
||||
|
||||
(un #f 'null? 0)
|
||||
(un-exact #t 'null? '())
|
||||
(un #f 'pair? 0)
|
||||
|
@ -662,6 +665,99 @@
|
|||
(tri0 '(1 2 . 3) 'list* (lambda () 1) 2 3 void)
|
||||
(un0 '#&1 'box 1)
|
||||
|
||||
(when (extflonum-available?)
|
||||
(define (extflonum-close? fl1 fl2)
|
||||
(extfl<= (extflabs (fl- fl1 fl2))
|
||||
(real->extfl 1e-8)))
|
||||
|
||||
(bin-exact #t 'extfl< 100.0t0 200.0t0 #t)
|
||||
(bin-exact #f 'extfl< 200.0t0 100.0t0)
|
||||
(bin-exact #f 'extfl< 200.0t0 200.0t0)
|
||||
|
||||
(bin-exact #t 'extfl<= 100.0t0 200.0t0 #t)
|
||||
(bin-exact #f 'extfl<= 200.0t0 100.0t0)
|
||||
(bin-exact #t 'extfl<= 200.0t0 200.0t0)
|
||||
|
||||
(bin-exact #f 'extfl> 100.0t0 200.0t0 #t)
|
||||
(bin-exact #t 'extfl> 200.0t0 100.0t0)
|
||||
(bin-exact #f 'extfl> 200.0t0 200.0t0)
|
||||
|
||||
(bin-exact #f 'extfl>= 100.0t0 200.0t0 #t)
|
||||
(bin-exact #t 'extfl>= 200.0t0 100.0t0)
|
||||
(bin-exact #t 'extfl>= 200.0t0 200.0t0)
|
||||
|
||||
(bin-exact #f 'extfl= 100.0t0 200.0t0 #t)
|
||||
(bin-exact #t 'extfl= 200.0t0 200.0t0)
|
||||
|
||||
(un-exact 3.0t0 'extflabs -3.0t0 #t)
|
||||
(un-exact 3.0t0 'extflsqrt 9.0t0 #t)
|
||||
(un-exact +nan.t 'extflsqrt -9.0t0)
|
||||
|
||||
(let ([test-trig
|
||||
(lambda (trig extfltrig)
|
||||
;;(un (real->extfl (trig 1.0)) extfltrig 1.0t0 #t)
|
||||
(un +nan.t extfltrig +nan.t))])
|
||||
(test-trig sin 'extflsin)
|
||||
(test-trig cos 'extflcos)
|
||||
(test-trig tan 'extfltan)
|
||||
(test-trig asin 'extflasin)
|
||||
(test-trig acos 'extflacos)
|
||||
(test-trig atan 'extflatan)
|
||||
(test-trig log 'extfllog)
|
||||
(test-trig exp 'extflexp))
|
||||
|
||||
(when (extflonum-available?)
|
||||
(for-each
|
||||
(lambda (v)
|
||||
(define (once v)
|
||||
(define (->fl v) (extfl->inexact v))
|
||||
(define (->extfl v) (real->extfl v))
|
||||
(un-exact (->extfl (round (->fl v))) 'extflround v #t)
|
||||
(un-exact (->extfl (ceiling (->fl v))) 'extflceiling v #t)
|
||||
(un-exact (->extfl (floor (->fl v))) 'extflfloor v #t)
|
||||
(un-exact (->extfl (truncate (->fl v))) 'extfltruncate v #t))
|
||||
(once v)
|
||||
(once (extfl- 0.0t0 v)))
|
||||
'(3.0t0 3.1t0 3.5t0 3.8t0 4.0t0 4.1t0 4.5t0 4.8t0 0.0t0)))
|
||||
|
||||
(bin-exact 9.0t0 'extflexpt 3.0t0 2.0t0 #t)
|
||||
(bin-exact (extflexpt 3.1t0 2.5t0) 'extflexpt 3.1t0 2.5t0 #t)
|
||||
(bin-exact -1.0t0 'extflexpt -1.0t0 3.0t0 #t)
|
||||
(bin-exact -0.125t0 'extflexpt -2.0t0 -3.0t0 #t)
|
||||
(bin-exact +nan.t 'extflexpt -1.0t0 3.1t0 #t)
|
||||
(bin-exact 0.0t0 'extflexpt 0.0t0 10.0t0 #t)
|
||||
(bin-exact +inf.t 'extflexpt 0.0t0 -1.0t0 #t)
|
||||
(bin-exact +1.0t0 'extflexpt 0.0t0 0.0t0 #t)
|
||||
(bin-exact +nan.t 'extflexpt +nan.t 2.7t0 #t)
|
||||
(bin-exact +nan.t 'extflexpt 2.7t0 +nan.t #t)
|
||||
(bin-exact +nan.t 'extflexpt +nan.t +nan.t #t)
|
||||
|
||||
(un-exact 10.0t0 '->extfl 10)
|
||||
(un-exact 10.0t0 'fx->extfl 10)
|
||||
|
||||
(un-exact 11 'extfl->exact-integer 11.0t0 #t)
|
||||
(un-exact -1 'extfl->exact-integer -1.0t0)
|
||||
(un-exact (inexact->exact 5e200) 'extfl->exact-integer (real->extfl 5e200))
|
||||
(un-exact 11 'extfl->fx 11.0t0 #t)
|
||||
(un-exact -11 'extfl->fx -11.0t0)
|
||||
|
||||
(bin-exact -0.75t0 'extfl- 1.5t0 2.25t0 #t)
|
||||
|
||||
(bin-exact 3.0t0 'extflmin 3.0t0 4.5t0 #t)
|
||||
(bin-exact 2.5t0 'extflmin 3.0t0 2.5t0)
|
||||
(bin0 3.5t0 '(lambda (x y) (extfl+ 1.0t0 (extflmin x y))) 3.0t0 2.5t0)
|
||||
(bin0 4.0t0 '(lambda (x y) (extfl+ 1.0t0 (extflmin x y))) 3.0t0 4.5t0)
|
||||
|
||||
(bin-exact 4.5t0 'extflmax 3.0t0 4.5t0 #t)
|
||||
(bin-exact 3.0t0 'extflmax 3.0t0 2.5t0)
|
||||
(bin0 5.5t0 '(lambda (x y) (extfl+ 1.0t0 (extflmax x y))) 3.0t0 4.5t0)
|
||||
(bin0 4.0t0 '(lambda (x y) (extfl+ 1.0t0 (extflmax x y))) 3.0t0 2.5t0)
|
||||
|
||||
(bin-exact 1.1t0 'extflvector-ref (extflvector 1.1t0 2.2t0 3.3t0) 0 #t)
|
||||
(bin-exact 3.3t0 'extflvector-ref (extflvector 1.1t0 2.2t0 3.3t0) 2)
|
||||
(un-exact 3 'extflvector-length (extflvector 1.1t0 2.2t0 3.3t0) #t)
|
||||
)
|
||||
|
||||
(let ([test-setter
|
||||
(lambda (make-X def-val set-val set-name set ref 3rd-all-ok?)
|
||||
(let ([v (make-X 3 def-val)])
|
||||
|
@ -1535,6 +1631,15 @@
|
|||
(+ (unsafe-flvector-length x) (unsafe-flvector-length x)))
|
||||
#f)
|
||||
|
||||
(when (extflonum-available?)
|
||||
(test-comp '(lambda (x)
|
||||
(let ([y (unsafe-extflvector-length x)])
|
||||
(let ([f (lambda () y)])
|
||||
(+ (f) (f)))))
|
||||
'(lambda (x)
|
||||
(+ (unsafe-extflvector-length x) (unsafe-extflvector-length x)))
|
||||
#f))
|
||||
|
||||
;; don't delay an unsafe car, because it might be space-unsafe
|
||||
(test-comp '(lambda (f x)
|
||||
(let ([y (unsafe-car x)])
|
||||
|
@ -1585,6 +1690,38 @@
|
|||
f)))
|
||||
#f)
|
||||
|
||||
(when (extflonum-available?)
|
||||
;; don't duplicate formerly once-used variable due to inlining
|
||||
(test-comp '(lambda (y)
|
||||
(let ([q (unsafe-extfl* y y)]) ; => q is known flonum
|
||||
(let ([x (unsafe-extfl* q q)]) ; can delay (but don't duplicate)
|
||||
(define (f z) (unsafe-extfl+ z x))
|
||||
(if y
|
||||
(f 10)
|
||||
f))))
|
||||
'(lambda (y)
|
||||
(let ([q (unsafe-extfl* y y)])
|
||||
(let ([x (unsafe-extfl* q q)])
|
||||
(define (f z) (unsafe-extfl+ z x))
|
||||
(if y
|
||||
(unsafe-extfl+ 10 x)
|
||||
f)))))
|
||||
;; double-check that previous test doesn't succeed due to copying
|
||||
(test-comp '(lambda (y)
|
||||
(let ([q (unsafe-extfl* y y)])
|
||||
(let ([x (unsafe-extfl* q q)])
|
||||
(define (f z) (unsafe-extfl+ z x))
|
||||
(if y
|
||||
(unsafe-extfl+ 10 x)
|
||||
f))))
|
||||
'(lambda (y)
|
||||
(let ([q (unsafe-extfl* y y)])
|
||||
(define (f z) (unsafe-extfl+ z (unsafe-extfl* q q)))
|
||||
(if y
|
||||
(unsafe-extfl+ 10 (unsafe-extfl* q q))
|
||||
f)))
|
||||
#f))
|
||||
|
||||
;; check move through an intermediate variable:
|
||||
(test-comp '(lambda (n)
|
||||
(let ([p (+ n n)])
|
||||
|
@ -1768,7 +1905,18 @@
|
|||
(unsafe-fxvector-set! x x x)
|
||||
(unsafe-f64vector-set! x x x)
|
||||
(unsafe-s16vector-set! x x x)
|
||||
(unsafe-u16vector-set! x x x))))
|
||||
(unsafe-u16vector-set! x x x)))
|
||||
|
||||
(when (extflonum-available?)
|
||||
(map check-omit-ok
|
||||
'((unsafe-extflvector-ref x x)
|
||||
(unsafe-f80vector-ref x x)))
|
||||
|
||||
(map (lambda (x) (check-omit-ok x #f))
|
||||
'((unsafe-extflvector-set! x x x)
|
||||
(unsafe-f80vector-set! x x x)
|
||||
))
|
||||
))
|
||||
|
||||
(test-comp '(lambda (x)
|
||||
(hash-ref '#hash((x . y)) x (lambda () 10)))
|
||||
|
@ -1953,6 +2101,8 @@
|
|||
(list (c? (c-q (c 1 2 3))))
|
||||
5)))
|
||||
|
||||
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Check splitting of definitions
|
||||
(test-comp `(module m racket/base
|
||||
|
@ -2191,6 +2341,22 @@
|
|||
(f y (sub1 y)))))
|
||||
(f 1.0 100)))
|
||||
|
||||
(when (extflonum-available?)
|
||||
(test '(done)
|
||||
'unboxing-inference-test
|
||||
(let ()
|
||||
(define (f x y)
|
||||
(if (zero? y)
|
||||
;; prevents inlining:
|
||||
'(done)
|
||||
(if (zero? y)
|
||||
;; incorrectly triggered unboxing,
|
||||
;; once upon a time:
|
||||
(extfl+ x 1.0t0)
|
||||
;; not a float argument => no unboxing of x:
|
||||
(f y (sub1 y)))))
|
||||
(f 1.0t0 100))))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Test against letrec-splitting bug:
|
||||
|
||||
|
@ -2257,6 +2423,19 @@
|
|||
(regexp-match #rx"1e[+]?100" (exn-message exn))))
|
||||
(test (inexact->exact 1e100) (lambda (x) (inexact->exact (fl/ (fl- x 0.0) 1.0))) 1e100)
|
||||
|
||||
(when (extflonum-available?)
|
||||
(test 1 (lambda (x) (extfl->fx (extfl/ (extfl- x 0.0t0) 1.0t0))) 1.0t0)
|
||||
(test 1 (lambda (x) (extfl->exact (extfl/ (extfl- x 0.0t0) 1.0t0))) 1.0t0)
|
||||
(err/rt-test (let ([f (lambda (x) (extfl->fx (extfl/ (extfl- x 0.0t0) 1.0t0)))])
|
||||
(set! f f)
|
||||
(f 1t100))
|
||||
;; make sure that exception reports actual bad argument, and
|
||||
;; not some bad argument due to the fact that the original
|
||||
;; was unboxed:
|
||||
(lambda (exn)
|
||||
(regexp-match #rx"1t[+]?100" (exn-message exn))))
|
||||
(test (extfl->exact 1t100) (lambda (x) (extfl->exact (extfl/ (extfl- x 0.0t0) 1.0t0))) 1t100))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Check that compiler handles shifting `#%variable-reference'
|
||||
|
||||
|
@ -2396,6 +2575,51 @@
|
|||
(test -2200000.0 non-tail2)
|
||||
(test-values '(-100001.0 100001.0) tail))
|
||||
|
||||
|
||||
(when (extflonum-available?)
|
||||
(let ()
|
||||
(define N 100000)
|
||||
|
||||
(define (non-tail)
|
||||
(define-values (a b)
|
||||
(let loop ([n N] [x -1.0t0] [y 1.0t0])
|
||||
(cond
|
||||
[(zero? n) (values x y)]
|
||||
[else (loop (sub1 n)
|
||||
(extfl+ x -1.0t0)
|
||||
(extfl+ y 1.0t0))])))
|
||||
(values a b))
|
||||
|
||||
(define (non-tail2ext)
|
||||
(for/fold ([v 0.0t0]) ([i (in-range N)])
|
||||
(define-values (a b)
|
||||
(let loop ([n 10] [x -1.0t0] [y 1.0t0])
|
||||
(cond
|
||||
[(zero? n) (values x y)]
|
||||
[else (loop (sub1 n)
|
||||
(extfl+ x -1.0t0)
|
||||
(extfl+ y 1.0t0))])))
|
||||
(extfl+ v (extfl- a b))))
|
||||
|
||||
(define (tail)
|
||||
(let loop ([n N] [x -1.0t0] [y 1.0t0])
|
||||
(cond
|
||||
[(zero? n) (values x y)]
|
||||
[else (loop (sub1 n)
|
||||
(extfl+ x -1.0t0)
|
||||
(extfl+ y 1.0t0))])))
|
||||
|
||||
(define x-tail #f)
|
||||
(define x-non-tail #f)
|
||||
(define x-non-tail2ext #f)
|
||||
(set! x-tail tail)
|
||||
(set! x-non-tail non-tail)
|
||||
(set! x-non-tail2ext non-tail2ext)
|
||||
|
||||
(test-values '(-100001.0t0 100001.0t0) non-tail)
|
||||
(test -2200000.0t0 non-tail2ext)
|
||||
(test-values '(-100001.0t0 100001.0t0) tail)))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Check for corect fixpoint calculation when lifting
|
||||
|
||||
|
@ -2614,6 +2838,24 @@
|
|||
;; too-aggressive compilation produces a validator failure here
|
||||
(read (open-input-bytes (get-output-bytes o)))))
|
||||
|
||||
(when (extflonum-available?)
|
||||
(let ([m '(module m racket/base
|
||||
(require racket/extflonum)
|
||||
(define (f x)
|
||||
(letrec ([z (if x (other 1) 'none)]
|
||||
[collect (lambda (x)
|
||||
(lambda (n)
|
||||
(list '(1 2 3)
|
||||
(extfl+ n x))))]
|
||||
[a (collect 0.0t0)]
|
||||
[other 6])
|
||||
(values a z))))])
|
||||
(define o (open-output-bytes))
|
||||
(write (compile m) o)
|
||||
(parameterize ([read-accept-compiled #t])
|
||||
;; too-aggressive compilation produces a validator failure here
|
||||
(read (open-input-bytes (get-output-bytes o))))))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; check error checking of JITted `continuation-mark-set-first'
|
||||
|
||||
|
@ -2636,6 +2878,19 @@
|
|||
|
||||
(test 4.0 (f 1.0) 2.0))
|
||||
|
||||
(when (extflonum-available?)
|
||||
(let ()
|
||||
(define f #f)
|
||||
(set! f
|
||||
(lambda (x)
|
||||
(let ([x (extfl+ x x)])
|
||||
(case-lambda
|
||||
[() (extfl+ x x)]
|
||||
[(y) (extfl+ x y)]))))
|
||||
|
||||
(test 4.0t0 (f 1.0t0) 2.0t0)
|
||||
))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
|
|
|
@ -380,7 +380,15 @@
|
|||
(test-tri (list (void) 27.4t0) 'unsafe-extflvector-set! v 2 27.4t0
|
||||
#:pre (lambda () (extflvector-set! v 2 0.0t0))
|
||||
#:post (lambda (x) (list x (extflvector-ref v 2)))
|
||||
#:literal-ok? #f)))
|
||||
#:literal-ok? #f))
|
||||
|
||||
(test-bin 9.5t0 'unsafe-f80vector-ref (f80vector 1.0t0 9.5t0 18.7t0) 1)
|
||||
(let ([v (f80vector 1.0t0 9.5t0 18.7t0)])
|
||||
(test-tri (list (void) 27.4t0) 'unsafe-f80vector-set! v 2 27.4t0
|
||||
#:pre (lambda () (f80vector-set! v 2 0.0t0))
|
||||
#:post (lambda (x) (list x (f80vector-ref v 2)))
|
||||
#:literal-ok? #f))
|
||||
)
|
||||
|
||||
(test-bin 95 'unsafe-fxvector-ref (fxvector 10 95 187) 1)
|
||||
(test-un 5 'unsafe-fxvector-length (fxvector 11 20 31 45 57))
|
||||
|
@ -437,6 +445,13 @@
|
|||
(unsafe-f64vector-ref y 1))
|
||||
1.2 (f64vector 1.0 4.2 6.7) 2.0)
|
||||
|
||||
(when (extflonum-available?)
|
||||
(test-tri 5.3999999999999999997t0 '(lambda (x y z) (unsafe-extfl+ x (unsafe-f80vector-ref y z))) 1.2t0 (f80vector 1.0t0 4.2t0 6.7t0) 1)
|
||||
(test-tri 3.2t0 '(lambda (x y z)
|
||||
(unsafe-f80vector-set! y 1 (unsafe-extfl+ x z))
|
||||
(unsafe-f80vector-ref y 1))
|
||||
1.2t0 (f80vector 1.0t0 4.2t0 6.7t0) 2.0t0))
|
||||
|
||||
(void))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -472,7 +487,7 @@
|
|||
(- n 1))))))])
|
||||
(test 500000.0 f 1.0))
|
||||
|
||||
(when (extflonum-available?)
|
||||
(when (extflonum-available?)
|
||||
(let ([f (lambda (x)
|
||||
(let ([x (unsafe-extfl+ x 1.0t0)])
|
||||
(let loop ([v 0.0t0][n 10000])
|
||||
|
@ -490,7 +505,6 @@
|
|||
(- n 1)
|
||||
(unsafe-extfl- 0.0t0 q))))))])
|
||||
(test 20002.0t0 f 1.0t0))
|
||||
|
||||
(let ([f (lambda (x)
|
||||
(let loop ([a 0.0t0][v 0.0t0][n 1000000])
|
||||
(if (zero? n)
|
||||
|
@ -502,7 +516,7 @@
|
|||
(loop a
|
||||
(unsafe-extfl+ v x)
|
||||
(- n 1))))))])
|
||||
(test 1000000.0t0 f 2.0t0)))
|
||||
(test 500000.0t0 f 1.0t0)))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
Version 5.3.3.3
|
||||
ffi/vector: added f8vectors
|
||||
|
||||
Version 5.3.3.2
|
||||
Added port-counts-lines?
|
||||
|
||||
|
|
|
@ -780,8 +780,42 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
* C->Racket: scheme_make_double(<C>)
|
||||
*/
|
||||
|
||||
#define ffi_type_slongdouble ffi_type_longdouble
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
typedef long double mz_long_double;
|
||||
#else /* MZ_LONG_DOUBLE undefined */
|
||||
typedef double mz_long_double;
|
||||
#endif /* MZ_LONG_DOUBLE */
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
#define SCHEME_MAYBE_LONG_DBL_VAL(x) SCHEME_LONG_DBL_VAL(x)
|
||||
#else /* MZ_LONG_DOUBLE undefined */
|
||||
#define SCHEME_MAYBE_LONG_DBL_VAL(x) unsupported_long_double_val()
|
||||
static mz_long_double unsupported_long_double_val() {
|
||||
scheme_raise_exn(MZEXN_FAIL_UNSUPPORTED, "_longdouble: " NOT_SUPPORTED_STR);
|
||||
return 0.0;
|
||||
}
|
||||
#endif /* MZ_LONG_DOUBLE */
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
#define scheme_make_maybe_long_double(x) scheme_make_long_double(x)
|
||||
#else /* MZ_LONG_DOUBLE undefined */
|
||||
#define scheme_make_maybe_long_double(x) unsupported_make_long_double()
|
||||
static Scheme_Object *unsupported_make_long_double() {
|
||||
scheme_raise_exn(MZEXN_FAIL_UNSUPPORTED, "_longdouble: " NOT_SUPPORTED_STR);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* MZ_LONG_DOUBLE */
|
||||
#define FOREIGN_longdouble (16)
|
||||
/* Type Name: longdouble
|
||||
* LibFfi type: ffi_type_slongdouble
|
||||
* C type: mz_long_double
|
||||
* Predicate: SCHEME_LONG_DBLP(<Scheme>)
|
||||
* Racket->C: SCHEME_MAYBE_LONG_DBL_VAL(<Scheme>)
|
||||
* S->C offset: 0
|
||||
* C->Racket: scheme_make_maybe_long_double(<C>)
|
||||
*/
|
||||
|
||||
/* A double that will coerce numbers to doubles: */
|
||||
#define FOREIGN_doubleS (16)
|
||||
#define FOREIGN_doubleS (17)
|
||||
/* Type Name: double* (doubleS)
|
||||
* LibFfi type: ffi_type_double
|
||||
* C type: double
|
||||
|
@ -792,7 +826,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
*/
|
||||
|
||||
/* Booleans -- implemented as an int which is 1 or 0: */
|
||||
#define FOREIGN_bool (17)
|
||||
#define FOREIGN_bool (18)
|
||||
/* Type Name: bool
|
||||
* LibFfi type: ffi_type_sint
|
||||
* C type: int
|
||||
|
@ -806,7 +840,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
* #f is not NULL only for byte-strings, for other strings it is
|
||||
* meaningless to use NULL. */
|
||||
|
||||
#define FOREIGN_string_ucs_4 (18)
|
||||
#define FOREIGN_string_ucs_4 (19)
|
||||
/* Type Name: string/ucs-4 (string_ucs_4)
|
||||
* LibFfi type: ffi_type_gcpointer
|
||||
* C type: mzchar*
|
||||
|
@ -816,7 +850,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
* C->Racket: scheme_make_char_string_without_copying(<C>)
|
||||
*/
|
||||
|
||||
#define FOREIGN_string_utf_16 (19)
|
||||
#define FOREIGN_string_utf_16 (20)
|
||||
/* Type Name: string/utf-16 (string_utf_16)
|
||||
* LibFfi type: ffi_type_gcpointer
|
||||
* C type: unsigned short*
|
||||
|
@ -829,7 +863,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
/* Byte strings -- not copying C strings, #f is NULL.
|
||||
* (note: these are not like char* which is just a pointer) */
|
||||
|
||||
#define FOREIGN_bytes (20)
|
||||
#define FOREIGN_bytes (21)
|
||||
/* Type Name: bytes
|
||||
* LibFfi type: ffi_type_gcpointer
|
||||
* C type: char*
|
||||
|
@ -839,7 +873,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
* C->Racket: (<C>==NULL)?scheme_false:scheme_make_byte_string_without_copying(<C>)
|
||||
*/
|
||||
|
||||
#define FOREIGN_path (21)
|
||||
#define FOREIGN_path (22)
|
||||
/* Type Name: path
|
||||
* LibFfi type: ffi_type_gcpointer
|
||||
* C type: char*
|
||||
|
@ -849,7 +883,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
* C->Racket: (<C>==NULL)?scheme_false:scheme_make_path_without_copying(<C>)
|
||||
*/
|
||||
|
||||
#define FOREIGN_symbol (22)
|
||||
#define FOREIGN_symbol (23)
|
||||
/* Type Name: symbol
|
||||
* LibFfi type: ffi_type_pointer
|
||||
* C type: char*
|
||||
|
@ -862,7 +896,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
/* This is for any C pointer: #f is NULL, cpointer values as well as
|
||||
* ffi-obj and string values pass their pointer. When used as a return
|
||||
* value, either a cpointer object or #f is returned. */
|
||||
#define FOREIGN_pointer (23)
|
||||
#define FOREIGN_pointer (24)
|
||||
/* Type Name: pointer
|
||||
* LibFfi type: ffi_type_pointer
|
||||
* C type: void*
|
||||
|
@ -872,7 +906,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
* C->Racket: scheme_make_foreign_external_cpointer(<C>)
|
||||
*/
|
||||
|
||||
#define FOREIGN_gcpointer (24)
|
||||
#define FOREIGN_gcpointer (25)
|
||||
/* Type Name: gcpointer
|
||||
* LibFfi type: ffi_type_gcpointer
|
||||
* C type: void*
|
||||
|
@ -884,7 +918,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
|
||||
/* This is used for passing and Scheme_Object* value as is. Useful for
|
||||
* functions that know about Scheme_Object*s, like Racket's. */
|
||||
#define FOREIGN_scheme (25)
|
||||
#define FOREIGN_scheme (26)
|
||||
/* Type Name: scheme
|
||||
* LibFfi type: ffi_type_gcpointer
|
||||
* C type: Scheme_Object*
|
||||
|
@ -897,7 +931,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
/* Special type, not actually used for anything except to mark values
|
||||
* that are treated like pointers but not referenced. Used for
|
||||
* creating function types. */
|
||||
#define FOREIGN_fpointer (26)
|
||||
#define FOREIGN_fpointer (27)
|
||||
/* Type Name: fpointer
|
||||
* LibFfi type: ffi_type_pointer
|
||||
* C type: void*
|
||||
|
@ -922,6 +956,7 @@ typedef union _ForeignAny {
|
|||
uintptr_t x_ufixnum;
|
||||
float x_float;
|
||||
double x_double;
|
||||
mz_long_double x_longdouble;
|
||||
double x_doubleS;
|
||||
int x_bool;
|
||||
mzchar* x_string_ucs_4;
|
||||
|
@ -936,9 +971,9 @@ typedef union _ForeignAny {
|
|||
} ForeignAny;
|
||||
|
||||
/* This is a tag that is used to identify user-made struct types. */
|
||||
#define FOREIGN_struct (27)
|
||||
#define FOREIGN_array (28)
|
||||
#define FOREIGN_union (29)
|
||||
#define FOREIGN_struct (28)
|
||||
#define FOREIGN_array (29)
|
||||
#define FOREIGN_union (30)
|
||||
|
||||
XFORM_NONGCING static int is_gcable_pointer(Scheme_Object *o) {
|
||||
if (SCHEME_FFIOBJP(o)) return 0;
|
||||
|
@ -1069,6 +1104,7 @@ XFORM_NONGCING static intptr_t ctype_sizeof(Scheme_Object *type)
|
|||
case FOREIGN_ufixnum: return sizeof(uintptr_t);
|
||||
case FOREIGN_float: return sizeof(float);
|
||||
case FOREIGN_double: return sizeof(double);
|
||||
case FOREIGN_longdouble: return sizeof(mz_long_double);
|
||||
case FOREIGN_doubleS: return sizeof(double);
|
||||
case FOREIGN_bool: return sizeof(int);
|
||||
case FOREIGN_string_ucs_4: return sizeof(mzchar*);
|
||||
|
@ -1667,6 +1703,7 @@ static Scheme_Object *C2SCHEME(Scheme_Object *already_ptr, Scheme_Object *type,
|
|||
case FOREIGN_ufixnum: return scheme_make_integer_from_unsigned(REF_CTYPE(uintptr_t));
|
||||
case FOREIGN_float: return scheme_make_double(REF_CTYPE(float));
|
||||
case FOREIGN_double: return scheme_make_double(REF_CTYPE(double));
|
||||
case FOREIGN_longdouble: return scheme_make_maybe_long_double(REF_CTYPE(mz_long_double));
|
||||
case FOREIGN_doubleS: return scheme_make_double(REF_CTYPE(double));
|
||||
case FOREIGN_bool: return (REF_CTYPE(int)?scheme_true:scheme_false);
|
||||
case FOREIGN_string_ucs_4: return scheme_make_char_string_without_copying(REF_CTYPE(mzchar*));
|
||||
|
@ -1902,6 +1939,21 @@ static void* SCHEME2C(const char *who,
|
|||
wrong_value(who, "_double", val);;
|
||||
return NULL; /* hush the compiler */
|
||||
}
|
||||
case FOREIGN_longdouble:
|
||||
# ifdef SCHEME_BIG_ENDIAN
|
||||
if (sizeof(mz_long_double)<sizeof(intptr_t) && ret_loc) {
|
||||
((int*)W_OFFSET(dst,delta))[0] = 0;
|
||||
delta += (sizeof(intptr_t)-sizeof(mz_long_double));
|
||||
}
|
||||
# endif /* SCHEME_BIG_ENDIAN */
|
||||
if (SCHEME_LONG_DBLP(val)) {
|
||||
mz_long_double tmp;
|
||||
tmp = (mz_long_double)(SCHEME_MAYBE_LONG_DBL_VAL(val));
|
||||
(((mz_long_double*)W_OFFSET(dst,delta))[0]) = tmp; return NULL;
|
||||
} else {
|
||||
wrong_value(who, "_longdouble", val);;
|
||||
return NULL; /* hush the compiler */
|
||||
}
|
||||
case FOREIGN_doubleS:
|
||||
# ifdef SCHEME_BIG_ENDIAN
|
||||
if (sizeof(double)<sizeof(intptr_t) && ret_loc) {
|
||||
|
@ -2273,7 +2325,7 @@ static Scheme_Object *foreign_compiler_sizeof(int argc, Scheme_Object *argv[])
|
|||
break;
|
||||
case 5: /* double */
|
||||
if (intsize==0) RETSIZE(double);
|
||||
else if (intsize==1) RETSIZE(long double);
|
||||
else if (intsize==1) RETSIZE(mz_long_double);
|
||||
else scheme_signal_error(MYNAME": bad qualifiers for 'double");
|
||||
break;
|
||||
default:
|
||||
|
@ -2690,6 +2742,21 @@ static Scheme_Object *foreign_flvector_to_cpointer(int argc, Scheme_Object *argv
|
|||
}
|
||||
#undef MYNAME
|
||||
|
||||
#define MYNAME "extflvector->cpointer"
|
||||
static Scheme_Object *foreign_extflvector_to_cpointer(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
# ifdef MZ_LONG_DOUBLE
|
||||
if (!SCHEME_EXTFLVECTORP(argv[0]))
|
||||
scheme_wrong_contract(MYNAME, "extflvector?", 0, argc, argv);
|
||||
return scheme_make_offset_cptr(argv[0], (intptr_t)SCHEME_EXTFLVEC_ELS((Scheme_Object *)0x0), NULL);
|
||||
# else /* MZ_LONG_DOUBLE undefined */
|
||||
scheme_raise_exn(MZEXN_FAIL_UNSUPPORTED,
|
||||
MYNAME ": " NOT_SUPPORTED_STR);
|
||||
return NULL;
|
||||
# endif /* MZ_LONG_DOUBLE */
|
||||
}
|
||||
#undef MYNAME
|
||||
|
||||
#define MYNAME "memset"
|
||||
static Scheme_Object *foreign_memset(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
|
@ -3886,6 +3953,8 @@ void scheme_init_foreign(Scheme_Env *env)
|
|||
scheme_make_prim_w_arity(foreign_vector_to_cpointer, "vector->cpointer", 1, 1), menv);
|
||||
scheme_add_global("flvector->cpointer",
|
||||
scheme_make_prim_w_arity(foreign_flvector_to_cpointer, "flvector->cpointer", 1, 1), menv);
|
||||
scheme_add_global("extflvector->cpointer",
|
||||
scheme_make_prim_w_arity(foreign_extflvector_to_cpointer, "extflvector->cpointer", 1, 1), menv);
|
||||
scheme_add_global("memset",
|
||||
scheme_make_prim_w_arity(foreign_memset, "memset", 3, 5), menv);
|
||||
scheme_add_global("memmove",
|
||||
|
@ -4019,6 +4088,13 @@ void scheme_init_foreign(Scheme_Env *env)
|
|||
t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_double));
|
||||
t->c_to_scheme = ((Scheme_Object*)FOREIGN_double);
|
||||
scheme_add_global("_double", (Scheme_Object*)t, menv);
|
||||
s = scheme_intern_symbol("longdouble");
|
||||
t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct));
|
||||
t->so.type = ctype_tag;
|
||||
t->basetype = (s);
|
||||
t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_slongdouble));
|
||||
t->c_to_scheme = ((Scheme_Object*)FOREIGN_longdouble);
|
||||
scheme_add_global("_longdouble", (Scheme_Object*)t, menv);
|
||||
s = scheme_intern_symbol("double*");
|
||||
t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct));
|
||||
t->so.type = ctype_tag;
|
||||
|
@ -4211,6 +4287,8 @@ void scheme_init_foreign(Scheme_Env *env)
|
|||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "vector->cpointer", 1, 1), menv);
|
||||
scheme_add_global("flvector->cpointer",
|
||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "flvector->cpointer", 1, 1), menv);
|
||||
scheme_add_global("extflvector->cpointer",
|
||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "extflvector->cpointer", 1, 1), menv);
|
||||
scheme_add_global("memset",
|
||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "memset", 3, 5), menv);
|
||||
scheme_add_global("memmove",
|
||||
|
@ -4254,6 +4332,7 @@ void scheme_init_foreign(Scheme_Env *env)
|
|||
scheme_add_global("_ufixnum", scheme_false, menv);
|
||||
scheme_add_global("_float", scheme_false, menv);
|
||||
scheme_add_global("_double", scheme_false, menv);
|
||||
scheme_add_global("_longdouble", scheme_false, menv);
|
||||
scheme_add_global("_double*", scheme_false, menv);
|
||||
scheme_add_global("_bool", scheme_false, menv);
|
||||
scheme_add_global("_string/ucs-4", scheme_false, menv);
|
||||
|
|
|
@ -738,9 +738,28 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
|
|||
@(defctype* 'float "float" "FLOAT" "FLOAT" "double")
|
||||
|
||||
@(defctype* 'double "double" "FLOAT" "FLOAT" "double")
|
||||
@;
|
||||
@; Not useful? not implemented in any case.
|
||||
@; (defctype* 'longdouble "long double" ...???...)
|
||||
|
||||
#define ffi_type_slongdouble ffi_type_longdouble
|
||||
@@@IFDEF{MZ_LONG_DOUBLE}{typedef long double mz_long_double;}{typedef double mz_long_double;}
|
||||
@@@IFDEF{MZ_LONG_DOUBLE}{
|
||||
@DEFINE{SCHEME_MAYBE_LONG_DBL_VAL(x) SCHEME_LONG_DBL_VAL(x)}
|
||||
}{
|
||||
@DEFINE{SCHEME_MAYBE_LONG_DBL_VAL(x) unsupported_long_double_val()}
|
||||
static mz_long_double unsupported_long_double_val() {
|
||||
scheme_raise_exn(MZEXN_FAIL_UNSUPPORTED, "_longdouble: " NOT_SUPPORTED_STR);
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
@@@IFDEF{MZ_LONG_DOUBLE}{
|
||||
@DEFINE{scheme_make_maybe_long_double(x) scheme_make_long_double(x)}
|
||||
}{
|
||||
@DEFINE{scheme_make_maybe_long_double(x) unsupported_make_long_double()}
|
||||
static Scheme_Object *unsupported_make_long_double() {
|
||||
scheme_raise_exn(MZEXN_FAIL_UNSUPPORTED, "_longdouble: " NOT_SUPPORTED_STR);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@(defctype* '(longdouble "longdouble") "mz_long_double" "LONG_DBL" "MAYBE_LONG_DBL" "maybe_long_double")
|
||||
|
||||
/* A double that will coerce numbers to doubles: */
|
||||
@(defctype* '(double* "double") "double"
|
||||
|
@ -1704,7 +1723,7 @@ static void* SCHEME2C(const char *who,
|
|||
break;
|
||||
case 5: /* double */
|
||||
if (intsize==0) RETSIZE(double);
|
||||
else if (intsize==1) RETSIZE(long double);
|
||||
else if (intsize==1) RETSIZE(mz_long_double);
|
||||
else scheme_signal_error(MYNAME": bad qualifiers for 'double");
|
||||
break;
|
||||
default:
|
||||
|
@ -2073,6 +2092,18 @@ static Scheme_Object *do_memop(const char *who, int mode,
|
|||
return scheme_make_offset_cptr(argv[0], (intptr_t)SCHEME_FLVEC_ELS((Scheme_Object *)0x0), NULL);
|
||||
}
|
||||
|
||||
@cdefine[extflvector->cpointer 1]{
|
||||
@@@IFDEF{MZ_LONG_DOUBLE}{
|
||||
if (!SCHEME_EXTFLVECTORP(argv[0]))
|
||||
scheme_wrong_contract(MYNAME, "extflvector?", 0, argc, argv);
|
||||
return scheme_make_offset_cptr(argv[0], (intptr_t)SCHEME_EXTFLVEC_ELS((Scheme_Object *)0x0), NULL);
|
||||
}{
|
||||
scheme_raise_exn(MZEXN_FAIL_UNSUPPORTED,
|
||||
MYNAME ": " NOT_SUPPORTED_STR);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@cdefine[memset 3 5]{return do_memop(MYNAME, 0, argc, argv);}
|
||||
@cdefine[memmove 3 6]{return do_memop(MYNAME, 1, argc, argv);}
|
||||
@cdefine[memcpy 3 6]{return do_memop(MYNAME, 2, argc, argv);}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,50,84,0,0,0,0,0,0,0,0,0,0,
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,51,84,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,51,0,0,0,1,0,0,10,0,14,0,
|
||||
19,0,32,0,37,0,40,0,47,0,54,0,59,0,63,0,67,0,74,0,83,
|
||||
21,0,28,0,33,0,37,0,40,0,45,0,58,0,62,0,67,0,74,0,83,
|
||||
0,87,0,93,0,107,0,121,0,124,0,130,0,134,0,136,0,147,0,149,0,
|
||||
163,0,170,0,192,0,194,0,208,0,19,1,48,1,59,1,70,1,96,1,129,
|
||||
1,162,1,224,1,24,2,105,2,161,2,166,2,187,2,84,3,105,3,158,3,
|
||||
225,3,114,4,2,5,56,5,67,5,150,5,0,0,112,7,0,0,69,35,37,
|
||||
109,105,110,45,115,116,120,29,11,11,11,64,119,104,101,110,72,112,97,114,97,
|
||||
109,101,116,101,114,105,122,101,64,99,111,110,100,62,111,114,66,100,101,102,105,
|
||||
110,101,66,108,101,116,114,101,99,64,108,101,116,42,63,108,101,116,63,97,110,
|
||||
109,105,110,45,115,116,120,29,11,11,11,66,100,101,102,105,110,101,66,108,101,
|
||||
116,114,101,99,64,108,101,116,42,63,97,110,100,62,111,114,64,119,104,101,110,
|
||||
72,112,97,114,97,109,101,116,101,114,105,122,101,63,108,101,116,64,99,111,110,
|
||||
100,66,117,110,108,101,115,115,68,104,101,114,101,45,115,116,120,29,11,11,11,
|
||||
65,113,117,111,116,101,29,94,2,15,68,35,37,107,101,114,110,101,108,11,29,
|
||||
94,2,15,68,35,37,112,97,114,97,109,122,11,62,105,102,65,98,101,103,105,
|
||||
|
@ -17,8 +17,8 @@
|
|||
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,36,11,8,240,
|
||||
110,91,0,0,95,159,2,17,36,36,159,2,16,36,36,159,2,16,36,36,16,
|
||||
20,2,3,2,2,2,5,2,2,2,4,2,2,2,6,2,2,2,7,2,2,
|
||||
2,8,2,2,2,9,2,2,2,10,2,2,2,11,2,2,2,12,2,2,97,
|
||||
20,2,3,2,2,2,4,2,2,2,5,2,2,2,6,2,2,2,7,2,2,
|
||||
2,8,2,2,2,11,2,2,2,10,2,2,2,9,2,2,2,12,2,2,97,
|
||||
37,11,8,240,110,91,0,0,93,159,2,16,36,37,16,2,2,13,161,2,2,
|
||||
37,2,13,2,2,2,13,96,11,11,8,240,110,91,0,0,16,0,96,38,11,
|
||||
8,240,110,91,0,0,16,0,18,98,64,104,101,114,101,13,16,6,36,2,14,
|
||||
|
@ -28,13 +28,13 @@
|
|||
2,18,248,22,104,199,249,22,79,2,19,248,22,106,201,12,27,248,22,81,248,
|
||||
22,163,4,196,28,248,22,87,193,20,14,159,37,36,37,28,248,22,87,248,22,
|
||||
81,194,248,22,177,17,193,249,22,156,4,80,158,39,36,251,22,89,2,18,248,
|
||||
22,177,17,199,249,22,79,2,11,248,22,178,17,201,11,18,100,10,13,16,6,
|
||||
22,177,17,199,249,22,79,2,6,248,22,178,17,201,11,18,100,10,13,16,6,
|
||||
36,2,14,2,2,11,11,11,8,32,8,31,8,30,8,29,16,4,11,11,2,
|
||||
20,3,1,8,101,110,118,49,55,52,48,56,16,4,11,11,2,21,3,1,8,
|
||||
101,110,118,49,55,52,48,57,27,248,22,81,248,22,163,4,196,28,248,22,87,
|
||||
193,20,14,159,37,36,37,28,248,22,87,248,22,81,194,248,22,177,17,193,249,
|
||||
22,156,4,80,158,39,36,250,22,89,2,22,248,22,89,249,22,89,248,22,89,
|
||||
2,23,248,22,177,17,201,251,22,89,2,18,2,23,2,23,249,22,79,2,6,
|
||||
2,23,248,22,177,17,201,251,22,89,2,18,2,23,2,23,249,22,79,2,7,
|
||||
248,22,178,17,204,18,100,11,13,16,6,36,2,14,2,2,11,11,11,8,32,
|
||||
8,31,8,30,8,29,16,4,11,11,2,20,3,1,8,101,110,118,49,55,52,
|
||||
49,49,16,4,11,11,2,21,3,1,8,101,110,118,49,55,52,49,50,248,22,
|
||||
|
@ -52,7 +52,7 @@
|
|||
37,47,11,9,222,33,43,248,22,163,4,248,22,80,201,248,22,178,17,198,27,
|
||||
248,22,81,248,22,163,4,196,27,248,22,163,4,248,22,80,195,249,22,156,4,
|
||||
80,158,40,36,28,248,22,87,195,250,22,90,2,22,9,248,22,81,199,250,22,
|
||||
89,2,10,248,22,89,248,22,80,199,250,22,90,2,9,248,22,178,17,201,248,
|
||||
89,2,10,248,22,89,248,22,80,199,250,22,90,2,5,248,22,178,17,201,248,
|
||||
22,81,202,27,248,22,81,248,22,163,4,23,197,1,27,249,22,1,22,93,249,
|
||||
22,2,22,163,4,248,22,163,4,248,22,80,199,248,22,183,4,249,22,156,4,
|
||||
80,158,41,36,251,22,89,1,22,119,105,116,104,45,99,111,110,116,105,110,117,
|
||||
|
@ -63,10 +63,10 @@
|
|||
204,27,248,22,81,248,22,163,4,196,28,248,22,87,193,20,14,159,37,36,37,
|
||||
249,22,156,4,80,158,39,36,27,248,22,163,4,248,22,80,197,28,249,22,154,
|
||||
9,62,61,62,248,22,157,4,248,22,104,196,250,22,89,2,22,248,22,89,249,
|
||||
22,89,21,93,2,27,248,22,80,199,250,22,90,2,5,249,22,89,2,27,249,
|
||||
22,89,21,93,2,27,248,22,80,199,250,22,90,2,11,249,22,89,2,27,249,
|
||||
22,89,248,22,113,203,2,27,248,22,81,202,251,22,89,2,18,28,249,22,154,
|
||||
9,248,22,157,4,248,22,80,200,64,101,108,115,101,10,248,22,177,17,197,250,
|
||||
22,90,2,22,9,248,22,178,17,200,249,22,79,2,5,248,22,81,202,99,13,
|
||||
22,90,2,22,9,248,22,178,17,200,249,22,79,2,11,248,22,81,202,99,13,
|
||||
16,6,36,2,14,2,2,11,11,11,8,32,8,31,8,30,8,29,16,4,11,
|
||||
11,2,20,3,1,8,101,110,118,49,55,52,51,52,16,4,11,11,2,21,3,
|
||||
1,8,101,110,118,49,55,52,51,53,18,158,94,10,64,118,111,105,100,8,48,
|
||||
|
@ -83,24 +83,24 @@
|
|||
0,36,36,11,12,11,11,16,0,16,0,16,0,36,36,16,11,16,5,11,20,
|
||||
15,16,2,20,14,159,36,36,37,80,158,36,36,36,20,114,159,36,16,1,2,
|
||||
13,16,1,33,33,10,16,5,2,12,88,163,8,36,37,53,37,9,223,0,33,
|
||||
34,36,20,114,159,36,16,1,2,13,16,0,11,16,5,2,3,88,163,8,36,
|
||||
34,36,20,114,159,36,16,1,2,13,16,0,11,16,5,2,8,88,163,8,36,
|
||||
37,53,37,9,223,0,33,35,36,20,114,159,36,16,1,2,13,16,0,11,16,
|
||||
5,2,11,88,163,8,36,37,53,37,9,223,0,33,36,36,20,114,159,36,16,
|
||||
1,2,13,16,1,33,37,11,16,5,2,6,88,163,8,36,37,56,37,9,223,
|
||||
5,2,6,88,163,8,36,37,53,37,9,223,0,33,36,36,20,114,159,36,16,
|
||||
1,2,13,16,1,33,37,11,16,5,2,7,88,163,8,36,37,56,37,9,223,
|
||||
0,33,38,36,20,114,159,36,16,1,2,13,16,1,33,39,11,16,5,2,10,
|
||||
88,163,8,36,37,58,37,9,223,0,33,42,36,20,114,159,36,16,1,2,13,
|
||||
16,0,11,16,5,2,8,88,163,8,36,37,53,37,9,223,0,33,44,36,20,
|
||||
114,159,36,16,1,2,13,16,0,11,16,5,2,9,88,163,8,36,37,54,37,
|
||||
9,223,0,33,45,36,20,114,159,36,16,1,2,13,16,0,11,16,5,2,4,
|
||||
16,0,11,16,5,2,4,88,163,8,36,37,53,37,9,223,0,33,44,36,20,
|
||||
114,159,36,16,1,2,13,16,0,11,16,5,2,5,88,163,8,36,37,54,37,
|
||||
9,223,0,33,45,36,20,114,159,36,16,1,2,13,16,0,11,16,5,2,9,
|
||||
88,163,8,36,37,56,37,9,223,0,33,46,36,20,114,159,36,16,1,2,13,
|
||||
16,0,11,16,5,2,5,88,163,8,36,37,58,37,9,223,0,33,47,36,20,
|
||||
114,159,36,16,1,2,13,16,1,33,49,11,16,5,2,7,88,163,8,36,37,
|
||||
16,0,11,16,5,2,11,88,163,8,36,37,58,37,9,223,0,33,47,36,20,
|
||||
114,159,36,16,1,2,13,16,1,33,49,11,16,5,2,3,88,163,8,36,37,
|
||||
54,37,9,223,0,33,50,36,20,114,159,36,16,1,2,13,16,0,11,16,0,
|
||||
94,2,16,2,17,93,2,16,9,9,36,0};
|
||||
EVAL_ONE_SIZED_STR((char *)expr, 2048);
|
||||
}
|
||||
{
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,50,84,0,0,0,0,0,0,0,0,0,0,
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,51,84,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,126,0,0,0,1,0,0,8,0,21,0,
|
||||
26,0,43,0,55,0,77,0,106,0,121,0,139,0,151,0,167,0,181,0,203,
|
||||
0,219,0,236,0,2,1,13,1,19,1,28,1,35,1,42,1,54,1,70,1,
|
||||
|
@ -376,7 +376,7 @@
|
|||
38,48,11,9,223,3,33,96,28,197,86,94,20,18,159,11,80,158,42,49,193,
|
||||
20,18,159,11,80,158,42,50,196,86,94,20,18,159,11,80,158,42,55,193,20,
|
||||
18,159,11,80,158,42,56,196,193,28,193,80,158,38,49,80,158,38,55,248,22,
|
||||
9,88,163,8,32,37,8,40,8,240,0,240,94,0,9,224,1,2,33,97,0,
|
||||
8,88,163,8,32,37,8,40,8,240,0,240,94,0,9,224,1,2,33,97,0,
|
||||
7,35,114,120,34,47,43,34,28,248,22,144,7,23,195,2,27,249,22,188,15,
|
||||
2,99,196,28,192,28,249,22,191,3,248,22,103,195,248,22,181,3,248,22,147,
|
||||
7,198,249,22,7,250,22,166,7,199,36,248,22,103,198,197,249,22,7,250,22,
|
||||
|
@ -582,7 +582,7 @@
|
|||
EVAL_ONE_SIZED_STR((char *)expr, 10044);
|
||||
}
|
||||
{
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,50,84,0,0,0,0,0,0,0,0,0,0,
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,51,84,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,14,0,0,0,1,0,0,15,0,40,0,
|
||||
57,0,75,0,97,0,120,0,140,0,162,0,169,0,176,0,183,0,190,0,197,
|
||||
0,0,0,222,1,0,0,74,35,37,112,108,97,99,101,45,115,116,114,117,99,
|
||||
|
@ -612,7 +612,7 @@
|
|||
EVAL_ONE_SIZED_STR((char *)expr, 548);
|
||||
}
|
||||
{
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,50,84,0,0,0,0,0,0,0,0,0,0,
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,51,84,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,89,0,0,0,1,0,0,7,0,18,0,
|
||||
45,0,51,0,60,0,67,0,89,0,102,0,128,0,145,0,167,0,175,0,187,
|
||||
0,202,0,218,0,236,0,0,1,12,1,28,1,51,1,63,1,94,1,101,1,
|
||||
|
@ -1022,7 +1022,7 @@
|
|||
EVAL_ONE_SIZED_STR((char *)expr, 8526);
|
||||
}
|
||||
{
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,50,84,0,0,0,0,0,0,0,0,0,0,
|
||||
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,51,46,51,46,51,84,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,11,0,0,0,1,0,0,10,0,16,0,
|
||||
29,0,44,0,58,0,78,0,90,0,104,0,118,0,170,0,0,0,98,1,0,
|
||||
0,69,35,37,98,117,105,108,116,105,110,65,113,117,111,116,101,29,94,2,2,
|
||||
|
|
|
@ -325,6 +325,20 @@ int scheme_jit_check_closure_flonum_bit(Scheme_Closure_Data *data, int pos, int
|
|||
else
|
||||
return 0;
|
||||
}
|
||||
int scheme_jit_check_closure_extflonum_bit(Scheme_Closure_Data *data, int pos, int delta)
|
||||
{
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
int ct;
|
||||
pos += delta;
|
||||
ct = scheme_boxmap_get(data->closure_map, pos, data->closure_size);
|
||||
if (ct == (CLOS_TYPE_TYPE_OFFSET + SCHEME_LOCAL_TYPE_EXTFLONUM))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NEED_LONG_BRANCHES
|
||||
|
@ -1096,25 +1110,26 @@ int scheme_generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int offse
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int local_pos, int target)
|
||||
static int generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int local_pos, int target, int extfl)
|
||||
{
|
||||
int offset;
|
||||
|
||||
offset = scheme_mz_flostack_pos(jitter, local_pos);
|
||||
offset = JIT_FRAME_FLOSTACK_OFFSET - offset;
|
||||
if (jitter->unbox) {
|
||||
int fpr0;
|
||||
fpr0 = JIT_FPR_0(jitter->unbox_depth);
|
||||
jit_ldxi_d_fppush(fpr0, JIT_FP, offset);
|
||||
fpr0 = JIT_FPUSEL_FPR_0(extfl, jitter->unbox_depth);
|
||||
jit_FPSEL_ldxi_xd_fppush(extfl, fpr0, JIT_FP, offset);
|
||||
jitter->unbox_depth++;
|
||||
} else {
|
||||
mz_rs_sync();
|
||||
scheme_generate_flonum_local_boxing(jitter, pos, offset, target, 0);
|
||||
scheme_generate_flonum_local_boxing(jitter, pos, offset, target, extfl);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int scheme_generate_flonum_local_unboxing(mz_jit_state *jitter, int push, int extfl)
|
||||
int scheme_generate_flonum_local_unboxing(mz_jit_state *jitter, int push, int no_store, int extfl)
|
||||
/* Move FPR0 onto C stack */
|
||||
{
|
||||
int sz, fpr0;
|
||||
|
@ -1126,13 +1141,15 @@ int scheme_generate_flonum_local_unboxing(mz_jit_state *jitter, int push, int ex
|
|||
jitter->flostack_space += space;
|
||||
jit_subi_l(JIT_SP, JIT_SP, space);
|
||||
}
|
||||
|
||||
jitter->flostack_offset += sz;
|
||||
|
||||
if (push) mz_runstack_flonum_pushed(jitter, jitter->flostack_offset);
|
||||
CHECK_LIMIT();
|
||||
|
||||
fpr0 = MZ_FPUSEL(extfl, JIT_FPU_FPR0, JIT_FPR0);
|
||||
mz_st_fppop(jitter->flostack_offset, fpr0, extfl);
|
||||
if (!no_store) {
|
||||
fpr0 = MZ_FPUSEL(extfl, JIT_FPU_FPR0, JIT_FPR0);
|
||||
mz_st_fppop(jitter->flostack_offset, fpr0, extfl);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1253,10 +1270,13 @@ static int generate_closure_prep(Scheme_Closure_Data *data, mz_jit_state *jitter
|
|||
size = data->closure_size;
|
||||
map = data->closure_map;
|
||||
for (j = 0; j < size; j++) {
|
||||
if (CLOSURE_CONTENT_IS_FLONUM(data, j)) {
|
||||
if (CLOSURE_CONTENT_IS_FLONUM(data, j)
|
||||
|| CLOSURE_CONTENT_IS_EXTFLONUM(data, j)) {
|
||||
int extfl;
|
||||
extfl = CLOSURE_CONTENT_IS_EXTFLONUM(data, j);
|
||||
pos = mz_remap(map[j]);
|
||||
jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(pos));
|
||||
generate_flonum_local_boxing(jitter, pos, map[j], JIT_R1);
|
||||
generate_flonum_local_boxing(jitter, pos, map[j], JIT_R1, extfl);
|
||||
CHECK_LIMIT();
|
||||
retval = 1;
|
||||
}
|
||||
|
@ -1964,12 +1984,17 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
{
|
||||
/* Other parts of the JIT rely on this code modifying only the target register,
|
||||
unless the type is SCHEME_FLONUM_TYPE */
|
||||
int pos, flonum;
|
||||
int pos, flonum, extfl;
|
||||
START_JIT_DATA();
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
flonum = (SCHEME_GET_LOCAL_TYPE(obj) == SCHEME_LOCAL_TYPE_FLONUM);
|
||||
if (MZ_LONG_DOUBLE_AND(SCHEME_GET_LOCAL_TYPE(obj) == SCHEME_LOCAL_TYPE_EXTFLONUM))
|
||||
flonum = extfl = 1;
|
||||
else
|
||||
extfl = 0;
|
||||
#else
|
||||
flonum = 0;
|
||||
extfl = 0;
|
||||
#endif
|
||||
pos = mz_remap(SCHEME_LOCAL_POS(obj));
|
||||
LOG_IT(("local %d [%d]\n", pos, SCHEME_LOCAL_FLAGS(obj)));
|
||||
|
@ -2026,7 +2051,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
CHECK_LIMIT();
|
||||
if (flonum && !result_ignored) {
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
generate_flonum_local_boxing(jitter, pos, SCHEME_LOCAL_POS(obj), target);
|
||||
generate_flonum_local_boxing(jitter, pos, SCHEME_LOCAL_POS(obj), target, extfl);
|
||||
CHECK_LIMIT();
|
||||
#endif
|
||||
} else {
|
||||
|
@ -2838,7 +2863,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
case scheme_let_one_type:
|
||||
{
|
||||
Scheme_Let_One *lv = (Scheme_Let_One *)obj;
|
||||
int flonum, unused;
|
||||
int flonum, unused, extfl;
|
||||
mz_jit_unbox_state ubs;
|
||||
START_JIT_DATA();
|
||||
|
||||
|
@ -2850,23 +2875,30 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
flonum = (SCHEME_LET_ONE_TYPE(lv) == SCHEME_LOCAL_TYPE_FLONUM);
|
||||
if (MZ_LONG_DOUBLE_AND(SCHEME_LET_ONE_TYPE(lv) == SCHEME_LOCAL_TYPE_EXTFLONUM))
|
||||
flonum = extfl = 1;
|
||||
else
|
||||
extfl = 0;
|
||||
#else
|
||||
flonum = 0;
|
||||
flonum = extfl = 0;
|
||||
#endif
|
||||
unused = SCHEME_LET_EVAL_TYPE(lv) & LET_ONE_UNUSED;
|
||||
|
||||
PAUSE_JIT_DATA();
|
||||
if (flonum) {
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
if (scheme_can_unbox_inline(lv->value, 5, JIT_FPR_NUM-1, 0, 0)) {
|
||||
if (scheme_can_unbox_inline(lv->value, 5, JIT_FPUSEL_FPR_NUM(extfl)-1, 0, extfl)) {
|
||||
jitter->unbox++;
|
||||
MZ_FPUSEL_STMT_ONLY(extfl, jitter->unbox_extflonum++;);
|
||||
scheme_generate_unboxed(lv->value, jitter, 2, 0);
|
||||
} else if (scheme_can_unbox_directly(lv->value, 0)) {
|
||||
} else if (scheme_can_unbox_directly(lv->value, extfl)) {
|
||||
jitter->unbox++;
|
||||
MZ_FPUSEL_STMT_ONLY(extfl, jitter->unbox_extflonum++;);
|
||||
scheme_generate_unboxed(lv->value, jitter, 1, 0);
|
||||
} else {
|
||||
/* validator should ensure that this is ok */
|
||||
jitter->unbox++;
|
||||
MZ_FPUSEL_STMT_ONLY(extfl, jitter->unbox_extflonum++;);
|
||||
scheme_generate_unboxed(lv->value, jitter, 0, 1);
|
||||
}
|
||||
#endif
|
||||
|
@ -2887,11 +2919,12 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
|
||||
if (flonum) {
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
MZ_FPUSEL_STMT_ONLY(extfl, --jitter->unbox_extflonum);
|
||||
--jitter->unbox;
|
||||
--jitter->unbox_depth;
|
||||
if (jitter->unbox_depth)
|
||||
scheme_signal_error("internal error: flonum let RHS leaves unbox depth");
|
||||
scheme_generate_flonum_local_unboxing(jitter, 1, 0);
|
||||
scheme_generate_flonum_local_unboxing(jitter, 1, 0, extfl);
|
||||
CHECK_LIMIT();
|
||||
(void)jit_movi_p(JIT_R0, NULL);
|
||||
#endif
|
||||
|
@ -3387,10 +3420,15 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
|
|||
zref = jit_bnei_l(jit_forward(), JIT_R1, f_offset);
|
||||
|
||||
for (i = data->num_params; i--; ) {
|
||||
if (CLOSURE_ARGUMENT_IS_FLONUM(data, i)) {
|
||||
if (CLOSURE_ARGUMENT_IS_FLONUM(data, i)
|
||||
|| CLOSURE_ARGUMENT_IS_EXTFLONUM(data, i)) {
|
||||
int extfl;
|
||||
extfl = CLOSURE_ARGUMENT_IS_EXTFLONUM(data, i);
|
||||
mz_rs_ldxi(JIT_R1, i);
|
||||
jit_ldxi_d_fppush(JIT_FPR0, JIT_R1, &((Scheme_Double *)0x0)->double_val);
|
||||
scheme_generate_flonum_local_unboxing(jitter, 1, 0);
|
||||
MZ_FPUSEL_STMT(extfl,
|
||||
jit_fpu_ldxi_ld_fppush(JIT_FPU_FPR0, JIT_R1, &((Scheme_Long_Double *)0x0)->long_double_val),
|
||||
jit_ldxi_d_fppush(JIT_FPR0, JIT_R1, &((Scheme_Double *)0x0)->double_val));
|
||||
scheme_generate_flonum_local_unboxing(jitter, 1, 0, extfl);
|
||||
CHECK_LIMIT();
|
||||
} else {
|
||||
mz_runstack_pushed(jitter, 1);
|
||||
|
@ -3463,10 +3501,15 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
|
|||
} else {
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
if ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS)
|
||||
&& (CLOSURE_CONTENT_IS_FLONUM(data, i))) {
|
||||
&& (CLOSURE_CONTENT_IS_FLONUM(data, i)
|
||||
|| CLOSURE_CONTENT_IS_EXTFLONUM(data, i))) {
|
||||
int extfl;
|
||||
extfl = CLOSURE_CONTENT_IS_EXTFLONUM(data, i);
|
||||
mz_rs_ldxi(JIT_R1, i);
|
||||
jit_ldxi_d_fppush(JIT_FPR0, JIT_R1, &((Scheme_Double *)0x0)->double_val);
|
||||
scheme_generate_flonum_local_unboxing(jitter, 1, 0);
|
||||
MZ_FPUSEL_STMT(extfl,
|
||||
jit_fpu_ldxi_ld_fppush(JIT_FPU_FPR0, JIT_R1, &((Scheme_Long_Double *)0x0)->long_double_val),
|
||||
jit_ldxi_d_fppush(JIT_FPR0, JIT_R1, &((Scheme_Double *)0x0)->double_val));
|
||||
scheme_generate_flonum_local_unboxing(jitter, 1, 0, extfl);
|
||||
CHECK_LIMIT();
|
||||
} else
|
||||
#endif
|
||||
|
@ -3482,10 +3525,15 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
|
|||
/* Unpack flonum closure data */
|
||||
if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS) {
|
||||
for (i = data->closure_size; i--; ) {
|
||||
if (CLOSURE_CONTENT_IS_FLONUM(data, i)) {
|
||||
if (CLOSURE_CONTENT_IS_FLONUM(data, i)
|
||||
|| CLOSURE_CONTENT_IS_EXTFLONUM(data, i)) {
|
||||
int extfl;
|
||||
extfl = CLOSURE_CONTENT_IS_EXTFLONUM(data, i);
|
||||
mz_rs_ldxi(JIT_R1, i);
|
||||
jit_ldxi_d_fppush(JIT_FPR0, JIT_R1, &((Scheme_Double *)0x0)->double_val);
|
||||
scheme_generate_flonum_local_unboxing(jitter, 1, 0);
|
||||
MZ_FPUSEL_STMT(extfl,
|
||||
jit_fpu_ldxi_ld_fppush(JIT_FPU_FPR0, JIT_R1, &((Scheme_Long_Double *)0x0)->long_double_val),
|
||||
jit_ldxi_d_fppush(JIT_FPR0, JIT_R1, &((Scheme_Double *)0x0)->double_val));
|
||||
scheme_generate_flonum_local_unboxing(jitter, 1, 0, extfl);
|
||||
CHECK_LIMIT();
|
||||
} else {
|
||||
mz_runstack_pushed(jitter, 1);
|
||||
|
|
|
@ -523,8 +523,10 @@ void *scheme_jit_get_threadlocal_table();
|
|||
# define mz_tl_ldi_i(reg, addr) (mz_tl_addr(reg, addr), mz_tl_ldr_i(reg, addr))
|
||||
# define mz_tl_sti_d_fppop(addr, reg, tmp_reg) (mz_tl_addr(tmp_reg, addr), mz_tl_str_d_fppop(tmp_reg, reg, addr))
|
||||
# define mz_tl_ldi_d_fppush(reg, addr, tmp_reg) (mz_tl_addr(tmp_reg, addr), mz_tl_ldr_d_fppush(reg, tmp_reg, addr))
|
||||
# define mz_fpu_tl_sti_ld_fppop(addr, reg, tmp_reg) (mz_tl_addr(tmp_reg, addr), mz_fpu_tl_str_ld_fppop(tmp_reg, reg, addr))
|
||||
# define mz_fpu_tl_ldi_ld_fppush(reg, addr, tmp_reg) (mz_tl_addr(tmp_reg, addr), mz_fpu_tl_ldr_ld_fppush(reg, tmp_reg, addr))
|
||||
# ifdef MZ_LONG_DOUBLE
|
||||
# define mz_fpu_tl_sti_ld_fppop(addr, reg, tmp_reg) (mz_tl_addr(tmp_reg, addr), mz_fpu_tl_str_ld_fppop(tmp_reg, reg, addr))
|
||||
# define mz_fpu_tl_ldi_ld_fppush(reg, addr, tmp_reg) (mz_tl_addr(tmp_reg, addr), mz_fpu_tl_ldr_ld_fppush(reg, tmp_reg, addr))
|
||||
# endif
|
||||
#else
|
||||
# define mz_tl_sti_p(addr, reg, tmp_reg) jit_sti_p(addr, reg)
|
||||
# define mz_tl_sti_l(addr, reg, tmp_reg) jit_sti_l(addr, reg)
|
||||
|
@ -1441,10 +1443,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int tail_ok, int w
|
|||
int scheme_generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inlined_ok, int unbox_anyway);
|
||||
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
int scheme_generate_flonum_local_unboxing(mz_jit_state *jitter, int push, int extfl);
|
||||
int scheme_generate_flonum_local_unboxing(mz_jit_state *jitter, int push, int no_store, int extfl);
|
||||
int scheme_generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int offset, int target, int extfl);
|
||||
#endif
|
||||
int scheme_generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inlined_ok, int unbox_anyway);
|
||||
int scheme_generate_non_tail_mark_pos_prefix(mz_jit_state *jitter);
|
||||
void scheme_generate_non_tail_mark_pos_suffix(mz_jit_state *jitter);
|
||||
|
||||
|
@ -1479,6 +1480,9 @@ int scheme_is_non_gc(Scheme_Object *obj, int depth);
|
|||
int scheme_jit_check_closure_flonum_bit(Scheme_Closure_Data *data, int pos, int delta);
|
||||
# define CLOSURE_ARGUMENT_IS_FLONUM(data, pos) scheme_jit_check_closure_flonum_bit(data, pos, 0)
|
||||
# define CLOSURE_CONTENT_IS_FLONUM(data, pos) scheme_jit_check_closure_flonum_bit(data, pos, data->num_params)
|
||||
int scheme_jit_check_closure_extflonum_bit(Scheme_Closure_Data *data, int pos, int delta);
|
||||
# define CLOSURE_ARGUMENT_IS_EXTFLONUM(data, pos) scheme_jit_check_closure_extflonum_bit(data, pos, 0)
|
||||
# define CLOSURE_CONTENT_IS_EXTFLONUM(data, pos) scheme_jit_check_closure_extflonum_bit(data, pos, data->num_params)
|
||||
#endif
|
||||
|
||||
Scheme_Object *scheme_extract_global(Scheme_Object *o, Scheme_Native_Closure *nc, int local_only);
|
||||
|
@ -1569,3 +1573,4 @@ Scheme_Object *scheme_jit_continuation_apply_install(Apply_LWC_Args *args);
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -150,13 +150,11 @@ int scheme_inline_alloc(mz_jit_state *jitter, int amt, Scheme_Type ty, int flags
|
|||
}
|
||||
} else if (keep_fpr1) {
|
||||
(void)jit_calli(sjc.retry_alloc_code_keep_fpr1);
|
||||
}
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
else if (keep_extfpr1) {
|
||||
} else if (keep_extfpr1) {
|
||||
(void)jit_calli(sjc.retry_alloc_code_keep_extfpr1);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
} else {
|
||||
(void)jit_calli(sjc.retry_alloc_code);
|
||||
}
|
||||
__START_TINY_JUMPS__(1);
|
||||
|
|
|
@ -119,6 +119,7 @@ static int is_inline_unboxable_op(Scheme_Object *obj, int flag, int unsafely, in
|
|||
if (IS_NAMED_PRIM(obj, "unsafe-extflmin")) return 1;
|
||||
if (IS_NAMED_PRIM(obj, "unsafe-extflmax")) return 1;
|
||||
if (IS_NAMED_PRIM(obj, "unsafe-fx->extfl")) return 1;
|
||||
if (IS_NAMED_PRIM(obj, "unsafe-f80vector-ref")) return 1;
|
||||
if (IS_NAMED_PRIM(obj, "unsafe-extflvector-ref")) return 1;
|
||||
|
||||
if (unsafely) {
|
||||
|
@ -263,9 +264,10 @@ int scheme_can_unbox_inline(Scheme_Object *obj, int fuel, int regs, int unsafely
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
#ifdef MZ_LONG_DOUBLE_UNBOXED
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
if ((SCHEME_PRIM_PROC_OPT_FLAGS(app->rator) & SCHEME_PRIM_IS_BINARY_INLINED)
|
||||
&& (IS_NAMED_PRIM(app->rator, "unsafe-extflvector-ref"))) {
|
||||
&& (IS_NAMED_PRIM(app->rator, "unsafe-f80vector-ref")
|
||||
|| IS_NAMED_PRIM(app->rator, "unsafe-extflvector-ref"))) {
|
||||
if (is_unboxing_immediate(app->rand1, 1, extfl)
|
||||
&& is_unboxing_immediate(app->rand2, 1, extfl)) {
|
||||
return 1;
|
||||
|
@ -303,7 +305,7 @@ int scheme_can_unbox_directly(Scheme_Object *obj, int extfl)
|
|||
|| IS_NAMED_PRIM(app->rator, "fx->fl"))
|
||||
return 1;
|
||||
}
|
||||
#ifdef MZ_LONG_DOUBLE_UNBOXED
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
if (extfl) {
|
||||
if (IS_NAMED_PRIM(app->rator, "->extfl")
|
||||
|| IS_NAMED_PRIM(app->rator, "fx->extfl"))
|
||||
|
@ -324,7 +326,7 @@ int scheme_can_unbox_directly(Scheme_Object *obj, int extfl)
|
|||
if (!extfl) {
|
||||
if (IS_NAMED_PRIM(app->rator, "flvector-ref")) return 1;
|
||||
}
|
||||
#ifdef MZ_LONG_DOUBLE_UNBOXED
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
if (extfl) {
|
||||
if (IS_NAMED_PRIM(app->rator, "extflvector-ref")) return 1;
|
||||
}
|
||||
|
@ -560,7 +562,7 @@ int scheme_generate_alloc_long_double(mz_jit_state *jitter, int inline_retry, in
|
|||
{
|
||||
#ifdef INLINE_FP_OPS
|
||||
# ifdef CAN_INLINE_ALLOC
|
||||
scheme_inline_alloc(jitter, sizeof(Scheme_Long_Double), scheme_long_double_type, 0, 0, 1, inline_retry, 1);
|
||||
scheme_inline_alloc(jitter, sizeof(Scheme_Long_Double), scheme_long_double_type, 0, 0, 0, inline_retry, 1);
|
||||
CHECK_LIMIT();
|
||||
jit_addi_p(dest, JIT_V1, OBJHEAD_SIZE);
|
||||
(void)jit_fpu_stxi_ld_fppop(&((Scheme_Long_Double *)0x0)->long_double_val, dest, JIT_FPU_FPR0);
|
||||
|
@ -660,11 +662,12 @@ static int generate_float_point_arith(mz_jit_state *jitter, Scheme_Object *rator
|
|||
/* inexact->exact needs no extra number */
|
||||
} else {
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
long double ld = second_const;
|
||||
#endif
|
||||
long double d = second_const;
|
||||
#else
|
||||
double d = second_const;
|
||||
#endif
|
||||
MZ_FPUSEL_STMT(extfl,
|
||||
mz_fpu_movi_ld_fppush(fpr1, ld, JIT_R2),
|
||||
mz_fpu_movi_ld_fppush(fpr1, d, JIT_R2),
|
||||
mz_movi_d_fppush(fpr1, d, JIT_R2));
|
||||
reversed = !reversed;
|
||||
cmp = -cmp;
|
||||
|
@ -679,7 +682,13 @@ static int generate_float_point_arith(mz_jit_state *jitter, Scheme_Object *rator
|
|||
}
|
||||
|
||||
#ifdef DIRECT_FPR_ACCESS
|
||||
if (unboxed && !extfl) {
|
||||
# define USES_DIRECT_FPR_ACCESS (!extfl)
|
||||
#else
|
||||
# define USES_DIRECT_FPR_ACCESS 0
|
||||
#endif
|
||||
|
||||
#ifdef DIRECT_FPR_ACCESS
|
||||
if (unboxed && USES_DIRECT_FPR_ACCESS) {
|
||||
/* arguments are backward */
|
||||
reversed = !reversed;
|
||||
cmp = -cmp;
|
||||
|
@ -783,9 +792,9 @@ static int generate_float_point_arith(mz_jit_state *jitter, Scheme_Object *rator
|
|||
__START_TINY_JUMPS__(1);
|
||||
refs2 = jit_bner_l(jit_forward(), JIT_R1, JIT_R2);
|
||||
__END_TINY_JUMPS__(1);
|
||||
#ifndef DIRECT_FPR_ACCESS
|
||||
if (unboxed)
|
||||
jit_FPSEL_roundr_xd_l_fppop(extfl, JIT_R1, fpr2); /* slow path won't be needed */
|
||||
#if !defined(DIRECT_FPR_ACCESS) || defined(MZ_LONG_DOUBLE)
|
||||
if (unboxed && !USES_DIRECT_FPR_ACCESS)
|
||||
jit_FPSEL_roundr_xd_l_fppop(extfl, JIT_R1, fpr1+1); /* slow path won't be needed */
|
||||
#endif
|
||||
}
|
||||
jit_fixnum_l(dest, JIT_R1);
|
||||
|
@ -913,13 +922,13 @@ static int generate_float_point_arith(mz_jit_state *jitter, Scheme_Object *rator
|
|||
scheme_generate_alloc_X_double(jitter, 0, dest, extfl);
|
||||
CHECK_LIMIT();
|
||||
#if defined(MZ_USE_JIT_I386)
|
||||
if (need_post_pop)
|
||||
if (need_post_pop && !USES_DIRECT_FPR_ACCESS)
|
||||
FSTPr(0);
|
||||
#endif
|
||||
} else if (unboxed_result) {
|
||||
jitter->unbox_depth++;
|
||||
#if defined(MZ_USE_JIT_I386)
|
||||
if (need_post_pop) {
|
||||
if (need_post_pop && !USES_DIRECT_FPR_ACCESS) {
|
||||
FXCHr(1);
|
||||
FSTPr(0);
|
||||
}
|
||||
|
@ -1105,11 +1114,11 @@ int scheme_generate_arith_for(mz_jit_state *jitter, Scheme_Object *rator, Scheme
|
|||
if (!rand) {
|
||||
inlined_flonum1 = inlined_flonum2 = 1;
|
||||
} else {
|
||||
if (scheme_can_unbox_inline(rand, 5, MZ_FPUSEL(extfl, JIT_FPU_FPR_NUM, JIT_FPR_NUM)-2, unsafe_fl > 0, extfl))
|
||||
if (scheme_can_unbox_inline(rand, 5, JIT_FPUSEL_FPR_NUM(extfl)-2, unsafe_fl > 0, extfl))
|
||||
inlined_flonum1 = 1;
|
||||
else
|
||||
inlined_flonum1 = 0;
|
||||
if (!rand2 || scheme_can_unbox_inline(rand2, 5, MZ_FPUSEL(extfl, JIT_FPU_FPR_NUM, JIT_FPR_NUM)-3, unsafe_fl > 0, extfl))
|
||||
if (!rand2 || scheme_can_unbox_inline(rand2, 5, JIT_FPUSEL_FPR_NUM(extfl)-3, unsafe_fl > 0, extfl))
|
||||
inlined_flonum2 = 1;
|
||||
else
|
||||
inlined_flonum2 = 0;
|
||||
|
@ -1188,7 +1197,7 @@ int scheme_generate_arith_for(mz_jit_state *jitter, Scheme_Object *rator, Scheme
|
|||
#ifdef USE_FLONUM_UNBOXING
|
||||
flostack = scheme_mz_flostack_save(jitter, &flopos);
|
||||
--jitter->unbox_depth;
|
||||
scheme_generate_flonum_local_unboxing(jitter, 0, extfl);
|
||||
scheme_generate_flonum_local_unboxing(jitter, 0, 0, extfl);
|
||||
CHECK_LIMIT();
|
||||
#endif
|
||||
}
|
||||
|
@ -1231,8 +1240,8 @@ int scheme_generate_arith_for(mz_jit_state *jitter, Scheme_Object *rator, Scheme
|
|||
flonum_depth = 2;
|
||||
}
|
||||
if (args_unboxed) {
|
||||
--jitter->unbox;
|
||||
MZ_FPUSEL_STMT_ONLY(extfl, --jitter->unbox_extflonum);
|
||||
--jitter->unbox;
|
||||
}
|
||||
jitter->unbox_depth -= flonum_depth;
|
||||
if (!jitter->unbox && jitter->unbox_depth && rand)
|
||||
|
|
|
@ -1071,7 +1071,8 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc
|
|||
}
|
||||
|
||||
static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, int num_rands, GC_CAN_IGNORE jit_insn *slow_code,
|
||||
int args_already_in_place, Scheme_App_Rec *app, Scheme_Object **alt_rands)
|
||||
int args_already_in_place, int direct_flostack_offset,
|
||||
Scheme_App_Rec *app, Scheme_Object **alt_rands)
|
||||
/* Last argument is in R0 */
|
||||
{
|
||||
GC_CAN_IGNORE jit_insn *refslow, *refagain;
|
||||
|
@ -1107,7 +1108,7 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i
|
|||
offset = jitter->flostack_offset;
|
||||
space = jitter->flostack_space;
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
arg_tmp_offset = offset;
|
||||
arg_tmp_offset = offset - direct_flostack_offset;
|
||||
#endif
|
||||
|
||||
/* Copy args to runstack after closure data: */
|
||||
|
@ -1116,32 +1117,37 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i
|
|||
for (i = num_rands; i--; ) {
|
||||
int already_loaded = (i == num_rands - 1);
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
int is_flonum, already_unboxed = 0;
|
||||
int is_flonum, already_unboxed = 0, extfl = 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)) {
|
||||
&& (CLOSURE_ARGUMENT_IS_FLONUM(jitter->self_data, i + args_already_in_place)
|
||||
|| CLOSURE_ARGUMENT_IS_EXTFLONUM(jitter->self_data, i + args_already_in_place))) {
|
||||
is_flonum = 1;
|
||||
extfl = CLOSURE_ARGUMENT_IS_EXTFLONUM(jitter->self_data, i + args_already_in_place);
|
||||
rand = (alt_rands
|
||||
? alt_rands[i+1+args_already_in_place]
|
||||
: app->args[i+1+args_already_in_place]);
|
||||
mz_ld_fppush(JIT_FPR0, arg_tmp_offset, 0);
|
||||
arg_tmp_offset -= sizeof(double);
|
||||
arg_tmp_offset += MZ_FPUSEL(extfl, 2*sizeof(double), sizeof(double));
|
||||
mz_ld_fppush(MZ_FPUSEL(extfl, JIT_FPU_FPR0, JIT_FPR0), arg_tmp_offset, extfl);
|
||||
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;
|
||||
is_flonum = extfl = 0;
|
||||
#endif
|
||||
if (!already_loaded)
|
||||
jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(i));
|
||||
jit_stxi_p(WORDS_TO_BYTES(i + closure_size + args_already_in_place), JIT_R2, JIT_R0);
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
if (is_flonum) {
|
||||
if (!already_unboxed)
|
||||
jit_ldxi_d_fppush(JIT_FPR0, JIT_R0, &((Scheme_Double *)0x0)->double_val);
|
||||
arg_offset += sizeof(double);
|
||||
mz_st_fppop(arg_offset, JIT_FPR0, 0);
|
||||
if (!already_unboxed) {
|
||||
MZ_FPUSEL_STMT(extfl,
|
||||
jit_fpu_ldxi_ld_fppush(JIT_FPU_FPR0, JIT_R0, &((Scheme_Long_Double *)0x0)->long_double_val),
|
||||
jit_ldxi_d_fppush(JIT_FPR0, JIT_R0, &((Scheme_Double *)0x0)->double_val));
|
||||
}
|
||||
arg_offset += MZ_FPUSEL(extfl, 2*sizeof(double), sizeof(double));
|
||||
mz_st_fppop(arg_offset, MZ_FPUSEL(extfl, JIT_FPU_FPR0, JIT_FPR0), extfl);
|
||||
}
|
||||
#endif
|
||||
CHECK_LIMIT();
|
||||
|
@ -1171,20 +1177,27 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i
|
|||
#ifdef USE_FLONUM_UNBOXING
|
||||
/* Need to box any arguments that we have only in flonum form */
|
||||
if (SCHEME_CLOSURE_DATA_FLAGS(jitter->self_data) & CLOS_HAS_TYPED_ARGS) {
|
||||
arg_tmp_offset = offset;
|
||||
arg_tmp_offset = offset - direct_flostack_offset;
|
||||
for (i = num_rands; i--; ) {
|
||||
if (CLOSURE_ARGUMENT_IS_FLONUM(jitter->self_data, i + args_already_in_place)) {
|
||||
if (CLOSURE_ARGUMENT_IS_FLONUM(jitter->self_data, i + args_already_in_place)
|
||||
|| CLOSURE_ARGUMENT_IS_EXTFLONUM(jitter->self_data, i + args_already_in_place)) {
|
||||
int extfl;
|
||||
extfl = CLOSURE_ARGUMENT_IS_EXTFLONUM(jitter->self_data, i + args_already_in_place);
|
||||
rand = (alt_rands
|
||||
? alt_rands[i+1+args_already_in_place]
|
||||
: app->args[i+1+args_already_in_place]);
|
||||
if (!SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type)
|
||||
|| (SCHEME_GET_LOCAL_TYPE(rand) == SCHEME_LOCAL_TYPE_FLONUM)) {
|
||||
int aoffset = JIT_FRAME_FLOSTACK_OFFSET - arg_tmp_offset;
|
||||
|| (!extfl && (SCHEME_GET_LOCAL_TYPE(rand) == SCHEME_LOCAL_TYPE_FLONUM))
|
||||
|| (extfl && (SCHEME_GET_LOCAL_TYPE(rand) == SCHEME_LOCAL_TYPE_EXTFLONUM))) {
|
||||
GC_CAN_IGNORE jit_insn *iref;
|
||||
int aoffset;
|
||||
arg_tmp_offset += MZ_FPUSEL(extfl, 2*sizeof(double), sizeof(double));
|
||||
aoffset = JIT_FRAME_FLOSTACK_OFFSET - arg_tmp_offset;
|
||||
if (i != num_rands - 1)
|
||||
mz_pushr_p(JIT_R0);
|
||||
if (SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type)) {
|
||||
/* assert: SCHEME_GET_LOCAL_TYPE(rand) == SCHEME_LOCAL_TYPE_FLONUM */
|
||||
/* or SCHEME_GET_LOCAL_TYPE(rand) == SCHEME_LOCAL_TYPE_EXTFLONUM */
|
||||
/* have to check for an existing box */
|
||||
if (i != num_rands - 1)
|
||||
mz_rs_ldxi(JIT_R0, i+1);
|
||||
|
@ -1196,7 +1209,9 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i
|
|||
iref = NULL;
|
||||
jit_movi_l(JIT_R0, aoffset);
|
||||
mz_rs_sync();
|
||||
(void)jit_calli(sjc.box_flonum_from_stack_code);
|
||||
MZ_FPUSEL_STMT(extfl,
|
||||
(void)jit_calli(sjc.box_extflonum_from_stack_code),
|
||||
(void)jit_calli(sjc.box_flonum_from_stack_code));
|
||||
if (i != num_rands - 1)
|
||||
mz_rs_stxi(i+1, JIT_R0);
|
||||
if (iref) {
|
||||
|
@ -1207,7 +1222,6 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i
|
|||
CHECK_LIMIT();
|
||||
if (i != num_rands - 1)
|
||||
mz_popr_p(JIT_R0);
|
||||
arg_tmp_offset -= sizeof(double);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1215,8 +1229,11 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i
|
|||
/* Arguments already in place may also need to be boxed. */
|
||||
arg_tmp_offset = jitter->self_restart_offset;
|
||||
for (i = 0; i < args_already_in_place; i++) {
|
||||
if (CLOSURE_ARGUMENT_IS_FLONUM(jitter->self_data, i)) {
|
||||
if (CLOSURE_ARGUMENT_IS_FLONUM(jitter->self_data, i)
|
||||
|| CLOSURE_ARGUMENT_IS_EXTFLONUM(jitter->self_data, i)) {
|
||||
GC_CAN_IGNORE jit_insn *iref;
|
||||
int extfl;
|
||||
extfl = CLOSURE_ARGUMENT_IS_EXTFLONUM(jitter->self_data, i);
|
||||
mz_pushr_p(JIT_R0);
|
||||
mz_ld_runstack_base_alt(JIT_R2);
|
||||
jit_subi_p(JIT_R2, JIT_RUNSTACK_BASE_OR_ALT(JIT_R2), WORDS_TO_BYTES(num_rands + args_already_in_place));
|
||||
|
@ -1228,7 +1245,9 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i
|
|||
{
|
||||
int aoffset = JIT_FRAME_FLOSTACK_OFFSET - arg_tmp_offset;
|
||||
jit_movi_l(JIT_R0, aoffset);
|
||||
(void)jit_calli(sjc.box_flonum_from_stack_code);
|
||||
MZ_FPUSEL_STMT(extfl,
|
||||
(void)jit_calli(sjc.box_extflonum_from_stack_code),
|
||||
(void)jit_calli(sjc.box_flonum_from_stack_code));
|
||||
mz_ld_runstack_base_alt(JIT_R2);
|
||||
jit_subi_p(JIT_R2, JIT_RUNSTACK_BASE_OR_ALT(JIT_R2), WORDS_TO_BYTES(num_rands + args_already_in_place));
|
||||
jit_stxi_p(WORDS_TO_BYTES(i), JIT_R2, JIT_R0);
|
||||
|
@ -1238,7 +1257,7 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i
|
|||
__END_TINY_JUMPS__(1);
|
||||
mz_popr_p(JIT_R0);
|
||||
CHECK_LIMIT();
|
||||
arg_tmp_offset -= sizeof(double);
|
||||
arg_tmp_offset -= MZ_FPUSEL(extfl, 2*sizeof(double), sizeof(double));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1515,58 +1534,24 @@ static jit_direct_arg *check_special_direct_args(Scheme_App_Rec *app, Scheme_Obj
|
|||
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
|
||||
static int generate_fp_argument_shuffle(int direct_flostack_offset, mz_jit_state *jitter)
|
||||
static int generate_fp_argument_shift(int direct_flostack_offset, mz_jit_state *jitter, int src_fp_reg)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
/* Copy unboxed flonums into place where the target code expects them,
|
||||
which is shifted and reverse of the order that we pushed. */
|
||||
if (direct_flostack_offset
|
||||
&& ((direct_flostack_offset > sizeof(double))
|
||||
|| (direct_flostack_offset != jitter->flostack_offset))) {
|
||||
/* If the source and target areas don't overlap (or if they
|
||||
overlap only by one item), we can do it in one step, otherwise
|
||||
reverse then shift. */
|
||||
if (jitter->flostack_offset >= ((2 * direct_flostack_offset) - sizeof(double))) {
|
||||
/* one step: */
|
||||
if (direct_flostack_offset != jitter->flostack_offset) {
|
||||
/* shift: */
|
||||
for (i = 0; i < direct_flostack_offset; i += sizeof(double)) {
|
||||
int i_pos, a_pos;
|
||||
i_pos = jitter->flostack_offset - direct_flostack_offset + i + sizeof(double);
|
||||
a_pos = direct_flostack_offset - i;
|
||||
if (i_pos != a_pos) {
|
||||
mz_ld_fppush(JIT_FPR0, i_pos, 0);
|
||||
mz_st_fppop(a_pos, JIT_FPR0, 0);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* reverse: */
|
||||
for (i = 0, j = direct_flostack_offset-sizeof(double); i < j; i += sizeof(double), j -= sizeof(double)) {
|
||||
int i_pos, j_pos;
|
||||
i_pos = jitter->flostack_offset - direct_flostack_offset + i + sizeof(double);
|
||||
j_pos = jitter->flostack_offset - direct_flostack_offset + j + sizeof(double);
|
||||
mz_ld_fppush(JIT_FPR1, i_pos, 0);
|
||||
mz_ld_fppush(JIT_FPR0, j_pos, 0);
|
||||
mz_st_fppop(i_pos, JIT_FPR0, 0);
|
||||
mz_st_fppop(j_pos, JIT_FPR1, 0);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
|
||||
if (direct_flostack_offset != jitter->flostack_offset) {
|
||||
/* shift: */
|
||||
for (i = 0; i < direct_flostack_offset; i += sizeof(double)) {
|
||||
int i_pos, a_pos;
|
||||
i_pos = jitter->flostack_offset - direct_flostack_offset + i + sizeof(double);
|
||||
mz_ld_fppush(JIT_FPR0, i_pos, 0);
|
||||
a_pos = i + sizeof(double);
|
||||
mz_st_fppop(a_pos, JIT_FPR0, 0);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((src_fp_reg == JIT_FP)
|
||||
&& (jitter->flostack_offset == direct_flostack_offset))
|
||||
/* no shift needed */
|
||||
return 1;
|
||||
|
||||
/* Since we're just shifting bytes, it's ok to pretend that all
|
||||
boxed values are `double's. */
|
||||
for (i = 0; i < direct_flostack_offset; i += sizeof(double)) {
|
||||
int i_pos, a_pos;
|
||||
i_pos = jitter->flostack_offset - direct_flostack_offset + i + sizeof(double);
|
||||
mz_ld_fppush_x(JIT_FPR0, i_pos, src_fp_reg, 0);
|
||||
a_pos = i + sizeof(double);
|
||||
mz_st_fppop(a_pos, JIT_FPR0, 0);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -1585,18 +1570,12 @@ static int generate_call_path_with_unboxes(mz_jit_state *jitter, int direct_flos
|
|||
/* Callback code to copy unboxed arguments.
|
||||
R1 has the return address, R2 holds the old FP */
|
||||
|
||||
offset = FLOSTACK_SPACE_CHUNK * ((direct_flostack_offset + (FLOSTACK_SPACE_CHUNK - 1))
|
||||
offset = FLOSTACK_SPACE_CHUNK * ((direct_flostack_offset + (FLOSTACK_SPACE_CHUNK - 1))
|
||||
/ FLOSTACK_SPACE_CHUNK);
|
||||
jit_subi_l(JIT_SP, JIT_SP, offset);
|
||||
|
||||
for (i = 0; i < direct_flostack_offset; i += sizeof(double)) {
|
||||
int i_pos, a_pos;
|
||||
i_pos = jitter->flostack_offset - direct_flostack_offset + i + sizeof(double);
|
||||
a_pos = direct_flostack_offset - i;
|
||||
mz_ld_fppush_x(JIT_FPR0, i_pos, JIT_R2, 0);
|
||||
mz_st_fppop(a_pos, JIT_FPR0, 0);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
generate_fp_argument_shift(direct_flostack_offset, jitter, JIT_R2);
|
||||
CHECK_LIMIT();
|
||||
|
||||
jit_jmpr(JIT_R1);
|
||||
|
||||
|
@ -1617,12 +1596,16 @@ static int generate_call_path_with_unboxes(mz_jit_state *jitter, int direct_flos
|
|||
/* box arguments for slow path */
|
||||
for (i = 0, k = 0; i < num_rands; i++) {
|
||||
if ((SCHEME_CLOSURE_DATA_FLAGS(direct_data) & CLOS_HAS_TYPED_ARGS)
|
||||
&& (CLOSURE_ARGUMENT_IS_FLONUM(direct_data, i))) {
|
||||
k += sizeof(double);
|
||||
&& (CLOSURE_ARGUMENT_IS_FLONUM(direct_data, i)
|
||||
|| CLOSURE_ARGUMENT_IS_EXTFLONUM(direct_data, i))) {
|
||||
int extfl;
|
||||
extfl = CLOSURE_ARGUMENT_IS_EXTFLONUM(direct_data, i);
|
||||
|
||||
k += MZ_FPUSEL(extfl, 2*sizeof(double), sizeof(double));
|
||||
offset = jitter->flostack_offset - direct_flostack_offset + k;
|
||||
offset = JIT_FRAME_FLOSTACK_OFFSET - offset;
|
||||
jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(i));
|
||||
scheme_generate_flonum_local_boxing(jitter, i, offset, JIT_R0, 0);
|
||||
scheme_generate_flonum_local_boxing(jitter, i, offset, JIT_R0, extfl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1632,7 +1615,6 @@ static int generate_call_path_with_unboxes(mz_jit_state *jitter, int direct_flos
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_rands,
|
||||
|
@ -1905,6 +1887,23 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
|
|||
direct_data = jitter->self_data;
|
||||
#endif
|
||||
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
/* we want to push flonums into local storage in reverse order
|
||||
of evaluation, so make a pass to create space: */
|
||||
if (direct_data
|
||||
&& (SCHEME_CLOSURE_DATA_FLAGS(direct_data) & CLOS_HAS_TYPED_ARGS)) {
|
||||
for (i = num_rands; i--; ) {
|
||||
int extfl;
|
||||
extfl = CLOSURE_ARGUMENT_IS_EXTFLONUM(direct_data, i+args_already_in_place);
|
||||
if (extfl || CLOSURE_ARGUMENT_IS_FLONUM(direct_data, i+args_already_in_place)) {
|
||||
/* make space: */
|
||||
scheme_generate_flonum_local_unboxing(jitter, 0, 1, extfl);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < num_rands; i++) {
|
||||
PAUSE_JIT_DATA();
|
||||
arg = (alt_rands
|
||||
|
@ -1918,30 +1917,40 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
|
|||
#ifdef USE_FLONUM_UNBOXING
|
||||
if (direct_data
|
||||
&& (SCHEME_CLOSURE_DATA_FLAGS(direct_data) & CLOS_HAS_TYPED_ARGS)
|
||||
&& (CLOSURE_ARGUMENT_IS_FLONUM(direct_data, i+args_already_in_place))) {
|
||||
&& (CLOSURE_ARGUMENT_IS_FLONUM(direct_data, i+args_already_in_place)
|
||||
|| CLOSURE_ARGUMENT_IS_EXTFLONUM(direct_data, i+args_already_in_place))) {
|
||||
int directly;
|
||||
int extfl;
|
||||
extfl = CLOSURE_ARGUMENT_IS_EXTFLONUM(direct_data, i+args_already_in_place);
|
||||
jitter->unbox++;
|
||||
if (scheme_can_unbox_inline(arg, 5, JIT_FPR_NUM-1, 0, 0))
|
||||
MZ_FPUSEL_STMT_ONLY(extfl, jitter->unbox_extflonum++);
|
||||
if (scheme_can_unbox_inline(arg, 5, JIT_FPUSEL_FPR_NUM(extfl)-1, 0, extfl))
|
||||
directly = 2;
|
||||
else if (scheme_can_unbox_directly(arg, 0))
|
||||
else if (scheme_can_unbox_directly(arg, extfl))
|
||||
directly = 1;
|
||||
else
|
||||
directly = 0;
|
||||
scheme_generate_unboxed(arg, jitter, directly, 1);
|
||||
MZ_FPUSEL_STMT_ONLY(extfl, --jitter->unbox_extflonum);
|
||||
--jitter->unbox;
|
||||
--jitter->unbox_depth;
|
||||
CHECK_LIMIT();
|
||||
scheme_generate_flonum_local_unboxing(jitter, 0, 0);
|
||||
|
||||
/* use space made by scheme_generate_flonum_local_unboxing() above: */
|
||||
mz_st_fppop(jitter->flostack_offset - direct_flostack_offset,
|
||||
MZ_FPUSEL(extfl, JIT_FPU_FPR0, JIT_FPR0),
|
||||
extfl);
|
||||
direct_flostack_offset += MZ_FPUSEL(extfl, 2 * sizeof(double), sizeof(double));
|
||||
CHECK_LIMIT();
|
||||
|
||||
if (SAME_TYPE(SCHEME_TYPE(arg), scheme_local_type)) {
|
||||
/* Keep local Scheme_Object view, in case a box has been allocated */
|
||||
/* Keep local Scheme_Object* view, in case a box has been allocated */
|
||||
int apos;
|
||||
apos = mz_remap(SCHEME_LOCAL_POS(arg));
|
||||
mz_rs_ldxi(JIT_R0, apos);
|
||||
} else {
|
||||
(void)jit_movi_p(JIT_R0, NULL);
|
||||
}
|
||||
direct_flostack_offset += sizeof(double);
|
||||
} else
|
||||
#endif
|
||||
if (inline_direct_args) {
|
||||
|
@ -2051,13 +2060,14 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
|
|||
code = sjc.shared_tail_code[dp][num_rands];
|
||||
if (direct_self) {
|
||||
LOG_IT(("<-self\n"));
|
||||
generate_self_tail_call(rator, jitter, num_rands, code, args_already_in_place, app, alt_rands);
|
||||
generate_self_tail_call(rator, jitter, num_rands, code, args_already_in_place, direct_flostack_offset,
|
||||
app, alt_rands);
|
||||
CHECK_LIMIT();
|
||||
} else if (inline_direct_native) {
|
||||
LOG_IT(("<-native-tail\n"));
|
||||
#ifdef USE_FLONUM_UNBOXING
|
||||
/* Copy unboxed flonums into place where the target code expects them: */
|
||||
generate_fp_argument_shuffle(direct_flostack_offset, jitter);
|
||||
generate_fp_argument_shift(direct_flostack_offset, jitter, JIT_FP);
|
||||
CHECK_LIMIT();
|
||||
#endif
|
||||
scheme_mz_flostack_restore(jitter,
|
||||
|
|
|
@ -1698,7 +1698,9 @@ static int common4(mz_jit_state *jitter, void *_data)
|
|||
jit_movi_i(JIT_R1, 3);
|
||||
if (i == 2) {
|
||||
/* need to box flonum */
|
||||
scheme_generate_alloc_double(jitter, 1, JIT_R0);
|
||||
MZ_FPUSEL_STMT(iii,
|
||||
scheme_generate_alloc_long_double(jitter, 1, JIT_R0),
|
||||
scheme_generate_alloc_double(jitter, 1, JIT_R0));
|
||||
jit_stxi_p(WORDS_TO_BYTES(2), JIT_RUNSTACK, JIT_R0);
|
||||
}
|
||||
}
|
||||
|
@ -2152,13 +2154,11 @@ static int common5(mz_jit_state *jitter, void *_data)
|
|||
sjc.retry_alloc_code = jit_get_ip().ptr;
|
||||
else if (i == 1)
|
||||
sjc.retry_alloc_code_keep_r0_r1 = jit_get_ip().ptr;
|
||||
else if (i == 2) {
|
||||
else if (i == 2)
|
||||
sjc.retry_alloc_code_keep_fpr1 = jit_get_ip().ptr;
|
||||
}
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
else if (i == 3) {
|
||||
else if (i == 3)
|
||||
sjc.retry_alloc_code_keep_extfpr1 = jit_get_ip().ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
mz_prolog(JIT_V1);
|
||||
|
@ -2248,9 +2248,26 @@ static int common5(mz_jit_state *jitter, void *_data)
|
|||
mz_epilog(JIT_R2);
|
||||
}
|
||||
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
/* *** box_extflonum_from_stack_code *** */
|
||||
/* R0 has offset from frame pointer to long double on stack */
|
||||
{
|
||||
sjc.box_extflonum_from_stack_code = jit_get_ip().ptr;
|
||||
|
||||
mz_prolog(JIT_R2);
|
||||
|
||||
JIT_UPDATE_THREAD_RSPTR();
|
||||
|
||||
jit_movr_p(JIT_R1, JIT_FP);
|
||||
jit_fpu_ldxr_ld_fppush(JIT_FPU_FPR0, JIT_R1, JIT_R0);
|
||||
scheme_generate_alloc_long_double(jitter, 1, JIT_R0);
|
||||
CHECK_LIMIT();
|
||||
|
||||
mz_epilog(JIT_R2);
|
||||
}
|
||||
|
||||
/* *** box_extflonum_from_reg_code *** */
|
||||
/* JIT_FPU_FPR2 (reg-based) or JIT_FPU_FPR0 (stack-based) has value */
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
{
|
||||
sjc.box_extflonum_from_reg_code = jit_get_ip().ptr;
|
||||
|
||||
|
@ -2258,10 +2275,6 @@ static int common5(mz_jit_state *jitter, void *_data)
|
|||
|
||||
JIT_UPDATE_THREAD_RSPTR();
|
||||
|
||||
#ifdef DISABLED_DIRECT_FPR_ACCESS
|
||||
jit_fpu_movr_ld(JIT_FPU_FPR0, JIT_FPU_FPR2);
|
||||
#endif
|
||||
|
||||
scheme_generate_alloc_long_double(jitter, 1, JIT_R0);
|
||||
CHECK_LIMIT();
|
||||
|
||||
|
|
|
@ -1372,9 +1372,10 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
|
|||
} else if (IS_NAMED_PRIM(rator, "fxvector-length")) {
|
||||
for_fx = 1;
|
||||
} else if (MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "extflvector-length"))) {
|
||||
for_fl = 1;
|
||||
extfl = 1;
|
||||
unsafe = 1;
|
||||
} else if (MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-extflvector-length"))) {
|
||||
for_fl = 1;
|
||||
extfl = 1;
|
||||
unsafe = 1;
|
||||
} else {
|
||||
|
@ -2590,6 +2591,9 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
} else if (IS_NAMED_PRIM(rator, "unsafe-extfl=")) {
|
||||
scheme_generate_extflonum_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, 1, NULL, dest);
|
||||
return 1;
|
||||
} else if (IS_NAMED_PRIM(rator, "extfl=")) {
|
||||
scheme_generate_extflonum_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, -1, NULL, dest);
|
||||
return 1;
|
||||
} else if (IS_NAMED_PRIM(rator, "unsafe-extfl<=")) {
|
||||
scheme_generate_extflonum_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, 0, 1, NULL, dest);
|
||||
return 1;
|
||||
|
@ -3013,14 +3017,17 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
return 1;
|
||||
} else if (IS_NAMED_PRIM(rator, "unsafe-f64vector-ref")
|
||||
|| IS_NAMED_PRIM(rator, "unsafe-flvector-ref")
|
||||
|| MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-extflvector-ref"))) {
|
||||
|| MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-extflvector-ref")
|
||||
|| IS_NAMED_PRIM(rator, "unsafe-f80vector-ref"))) {
|
||||
int fpr0;
|
||||
int is_f64;
|
||||
int extfl;
|
||||
mz_jit_unbox_state ubs;
|
||||
|
||||
is_f64 = IS_NAMED_PRIM(rator, "unsafe-f64vector-ref");
|
||||
extfl = MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-extflvector-ref"));
|
||||
is_f64 = IS_NAMED_PRIM(rator, "unsafe-f64vector-ref")
|
||||
|| MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-f80vector-ref"));
|
||||
extfl = MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-extflvector-ref")
|
||||
|| IS_NAMED_PRIM(rator, "unsafe-f80vector-ref"));
|
||||
|
||||
scheme_mz_unbox_save(jitter, &ubs); /* no unboxing of vector and index arguments */
|
||||
scheme_generate_two_args(app->rand1, app->rand2, jitter, 1, 2);
|
||||
|
@ -3042,7 +3049,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
}
|
||||
|
||||
if (jitter->unbox)
|
||||
fpr0 = JIT_FPR_0(jitter->unbox_depth);
|
||||
fpr0 = JIT_FPUSEL_FPR_0(jitter->unbox_extflonum, jitter->unbox_depth);
|
||||
else
|
||||
fpr0 = MZ_FPUSEL(extfl, JIT_FPU_FPR0, JIT_FPR0);
|
||||
|
||||
|
@ -3950,13 +3957,16 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
|
|||
return 1;
|
||||
} else if (IS_NAMED_PRIM(rator, "unsafe-f64vector-set!")
|
||||
|| IS_NAMED_PRIM(rator, "unsafe-flvector-set!")
|
||||
|| MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-extflvector-set!"))) {
|
||||
|| MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-extflvector-set!")
|
||||
|| IS_NAMED_PRIM(rator, "unsafe-f80vector-set!"))) {
|
||||
int is_f64;
|
||||
int can_direct, got_two;
|
||||
int extfl;
|
||||
|
||||
is_f64 = IS_NAMED_PRIM(rator, "unsafe-f64vector-set!");
|
||||
extfl = MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-extflvector-set!"));
|
||||
is_f64 = IS_NAMED_PRIM(rator, "unsafe-f64vector-set!")
|
||||
|| MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-f80vector-set!"));
|
||||
extfl = MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-extflvector-set!"))
|
||||
|| MZ_LONG_DOUBLE_AND(IS_NAMED_PRIM(rator, "unsafe-f80vector-set!"));
|
||||
|
||||
if (scheme_is_constant_and_avoids_r1(app->args[1])
|
||||
&& scheme_is_constant_and_avoids_r1(app->args[2])) {
|
||||
|
|
|
@ -162,6 +162,12 @@ union jit_fpu_double_imm {
|
|||
MOVQir(((intptr_t)is), JIT_R0), \
|
||||
jit_fpu_ldr_d_fppush(rd, JIT_R0), \
|
||||
MOVQrr(JIT_REXTMP, JIT_R0))
|
||||
|
||||
#define jit_fpu_ldi_ld_fppush(rd, is) \
|
||||
(MOVQrr(JIT_R0, JIT_REXTMP), \
|
||||
MOVQir(((intptr_t)is), JIT_R0), \
|
||||
jit_fpu_ldr_ld_fppush(rd, JIT_R0), \
|
||||
MOVQrr(JIT_REXTMP, JIT_R0))
|
||||
#else
|
||||
#define jit_fpu_ldi_f(rd, is) \
|
||||
((rd) == 0 ? (FSTPr (0), FLDSm((is), 0, 0, 0)) \
|
||||
|
@ -261,6 +267,13 @@ union jit_fpu_double_imm {
|
|||
MOVQir(((intptr_t)is), JIT_R0), \
|
||||
jit_fpu_str_d_fppop(JIT_R0, rd), \
|
||||
MOVQrr(JIT_REXTMP, JIT_R0))
|
||||
|
||||
#define jit_fpu_sti_ld_fppop(is, rd) \
|
||||
(MOVQrr(JIT_R0, JIT_REXTMP), \
|
||||
MOVQir(((intptr_t)is), JIT_R0), \
|
||||
jit_fpu_str_ld_fppop(JIT_R0, rd), \
|
||||
MOVQrr(JIT_REXTMP, JIT_R0))
|
||||
|
||||
#else
|
||||
#define jit_fpu_sti_f(id, rs) jit_fpu_fxch ((rs), FPX(), FSTSm((id), 0, 0, 0))
|
||||
#define jit_fpu_str_f(rd, rs) jit_fpu_fxch ((rs), FPX(), FSTSm(0, (rd), 0, 0))
|
||||
|
|
|
@ -208,6 +208,9 @@ static Scheme_Object *TO_FLOAT(const Scheme_Object *n);
|
|||
#endif
|
||||
Scheme_Object *scheme_TO_DOUBLE(const Scheme_Object *n);
|
||||
|
||||
static Scheme_Object *extfl_ref (int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *extfl_set (int argc, Scheme_Object *argv[]);
|
||||
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
static Scheme_Object *exact_to_extfl(int argc, Scheme_Object *argv[]);
|
||||
#endif
|
||||
|
@ -1487,6 +1490,28 @@ void scheme_init_extfl_unsafe_number(Scheme_Env *env)
|
|||
SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(flags
|
||||
| SCHEME_PRIM_WANTS_EXTFLONUM_THIRD);
|
||||
scheme_add_global_constant("unsafe-extflvector-set!", p, env);
|
||||
|
||||
p = scheme_make_immed_prim(extfl_ref, "unsafe-f80vector-ref",
|
||||
2, 2);
|
||||
if (MZ_LONG_DOUBLE_AND(scheme_can_inline_fp_op()))
|
||||
flags = SCHEME_PRIM_IS_BINARY_INLINED;
|
||||
else
|
||||
flags = SCHEME_PRIM_SOMETIMES_INLINED;
|
||||
SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(flags
|
||||
| SCHEME_PRIM_IS_UNSAFE_OMITABLE
|
||||
| SCHEME_PRIM_IS_OMITABLE
|
||||
| SCHEME_PRIM_PRODUCES_EXTFLONUM);
|
||||
scheme_add_global_constant("unsafe-f80vector-ref", p, env);
|
||||
|
||||
p = scheme_make_immed_prim(extfl_set, "unsafe-f80vector-set!",
|
||||
3, 3);
|
||||
if (MZ_LONG_DOUBLE_AND(1))
|
||||
flags = SCHEME_PRIM_IS_NARY_INLINED;
|
||||
else
|
||||
flags = SCHEME_PRIM_SOMETIMES_INLINED;
|
||||
SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(flags
|
||||
| SCHEME_PRIM_WANTS_EXTFLONUM_THIRD);
|
||||
scheme_add_global_constant("unsafe-f80vector-set!", p, env);
|
||||
}
|
||||
|
||||
Scheme_Object *
|
||||
|
@ -2485,8 +2510,40 @@ double scheme_double_floor(double x) { return floor(x); }
|
|||
double scheme_double_ceiling(double x) { return ceil(x); }
|
||||
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
XFORM_NONGCING static long double SCH_ROUNDL(long double d)
|
||||
{
|
||||
long double i, frac;
|
||||
int invert;
|
||||
|
||||
#ifdef FMOD_CAN_RETURN_POS_ZERO
|
||||
if ((d == 0.0L) && long_minus_zero_p(d))
|
||||
return d;
|
||||
#endif
|
||||
|
||||
if (d < 0.0L) {
|
||||
d = -d;
|
||||
invert = 1;
|
||||
} else
|
||||
invert = 0;
|
||||
|
||||
frac = modfl(d, &i);
|
||||
if (frac < 0.5L)
|
||||
d = i;
|
||||
else if (frac > 0.5L)
|
||||
d = i + 1;
|
||||
else if (fmodl(i, 2.0L) != 0.0L)
|
||||
d = i + 1;
|
||||
else
|
||||
d = i;
|
||||
|
||||
if (invert)
|
||||
d = -d;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
long double scheme_long_double_truncate(long double x) { return truncl(x); }
|
||||
long double scheme_long_double_round(long double x) { return roundl(x); }
|
||||
long double scheme_long_double_round(long double x) { return SCH_ROUNDL(x); }
|
||||
long double scheme_long_double_floor(long double x) { return floorl(x); }
|
||||
long double scheme_long_double_ceiling(long double x) { return ceill(x); }
|
||||
#endif
|
||||
|
@ -4618,6 +4675,31 @@ Scheme_Object *scheme_extflvector_length(Scheme_Object *vec)
|
|||
#endif
|
||||
}
|
||||
|
||||
static Scheme_Object *extfl_ref (int argc, Scheme_Object *argv[])
|
||||
{
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
long double v;
|
||||
Scheme_Object *p;
|
||||
p = ((Scheme_Structure *)argv[0])->slots[0];
|
||||
v = ((long double *)SCHEME_CPTR_VAL(p))[SCHEME_INT_VAL(argv[1])];
|
||||
return scheme_make_long_double(v);
|
||||
#else
|
||||
return unsupported("unsafe-f80vector-ref");
|
||||
#endif
|
||||
}
|
||||
|
||||
static Scheme_Object *extfl_set (int argc, Scheme_Object *argv[])
|
||||
{
|
||||
#ifdef MZ_LONG_DOUBLE
|
||||
Scheme_Object *p;
|
||||
p = ((Scheme_Structure *)argv[0])->slots[0];
|
||||
((long double *)SCHEME_CPTR_VAL(p))[SCHEME_INT_VAL(argv[1])] = SCHEME_LONG_DBL_VAL(argv[2]);
|
||||
return scheme_void;
|
||||
#else
|
||||
return unsupported("unsafe-f80vector-set!");
|
||||
#endif
|
||||
}
|
||||
|
||||
static Scheme_Object *extflvector_length (int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return scheme_extflvector_length(argv[0]);
|
||||
|
@ -4995,8 +5077,8 @@ static Scheme_Object *extfl_to_fx (int argc, Scheme_Object *argv[])
|
|||
Scheme_Object *o;
|
||||
|
||||
if (!SCHEME_LONG_DBLP(argv[0])
|
||||
&& !scheme_is_integer(argv[0]))
|
||||
scheme_wrong_contract("extfl->fx", "(and/c extflonum? integer?)", 0, argc, argv);
|
||||
/* && !scheme_is_integer(argv[0]) */)
|
||||
scheme_wrong_contract("extfl->fx", "(and/c extflonum?)", 0, argc, argv);
|
||||
|
||||
d = SCHEME_LONG_DBL_VAL(argv[0]);
|
||||
v = (intptr_t)d;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define USE_COMPILED_STARTUP 1
|
||||
|
||||
#define EXPECTED_PRIM_COUNT 1086
|
||||
#define EXPECTED_UNSAFE_COUNT 98
|
||||
#define EXPECTED_UNSAFE_COUNT 100
|
||||
#define EXPECTED_FLFXNUM_COUNT 69
|
||||
#define EXPECTED_EXTFL_COUNT 45
|
||||
#define EXPECTED_FUTURES_COUNT 15
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
consistently.)
|
||||
*/
|
||||
|
||||
#define MZSCHEME_VERSION "5.3.3.2"
|
||||
#define MZSCHEME_VERSION "5.3.3.3"
|
||||
|
||||
#define MZSCHEME_VERSION_X 5
|
||||
#define MZSCHEME_VERSION_Y 3
|
||||
#define MZSCHEME_VERSION_Z 3
|
||||
#define MZSCHEME_VERSION_W 2
|
||||
#define MZSCHEME_VERSION_W 3
|
||||
|
||||
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||
|
|
Loading…
Reference in New Issue
Block a user