unbox local floating-point arithmetic
Avoid allocating a flonum object for floating-opint calculations that are consumed only by other floating-point caculations. For this first cut, unboxing applies only to fl+, fl-, fl*, fl/, flabs, fl<, fl<=, fl=, fl>, fl>=, bytevector-ieee-double-[native-]ref, and bytevector-ieee-double-[native-]set!. Local variables can be unboxed in the same way as implicit temporaries, and loop arguments can be unboxed, but values in a closure and function-call arguments are always boxed. arm32 support is mostly in place, but not yet right. ppc32 support is not yet implemented. This commit includes a small change that is incompatible with previous Chez Scheme versions: `(fl= +nan.0)` (and similar for other comparisons) produces true instead of false. original commit: 36459e43f10705aa3e383376ca7d54cf2998b7ee
This commit is contained in:
parent
75f287befd
commit
7768b09118
|
@ -20,7 +20,7 @@ doit: $(bootfiles)
|
|||
%.boot:
|
||||
( cd .. ; ./workarea $* xc-$* )
|
||||
( cd ../xc-$*/s ; make -f Mf-cross base=../../$(workarea) --jobs=2 m=$(m) xm=$* )
|
||||
for x in `echo scheme.boot petite.boot scheme.h equates.h` ; do\
|
||||
for x in `echo scheme.boot petite.boot scheme.h equates.h gc-oce.inc gc-ocd.inc vfasl.inc` ; do\
|
||||
if [ ! -h ../xc-$*/boot/$*/$$x ] ; then \
|
||||
mv -f ../xc-$*/boot/$*/$$x ../boot/$*/$$x ;\
|
||||
fi ;\
|
||||
|
|
|
@ -62,7 +62,7 @@ InstallLZ4Target=
|
|||
# no changes should be needed below this point #
|
||||
###############################################################################
|
||||
|
||||
Version=csv9.5.3.28
|
||||
Version=csv9.5.3.29
|
||||
Include=boot/$m
|
||||
PetiteBoot=boot/$m/petite.boot
|
||||
SchemeBoot=boot/$m/scheme.boot
|
||||
|
|
68
mats/fl.ms
68
mats/fl.ms
|
@ -1038,3 +1038,71 @@
|
|||
'((3.0 . -2.0) (-2.0 . -2.0) (-3.0 . -2.0) (2.0 . -2.0)
|
||||
(0.0 . 4.0) (0.0 . -4.0) (-0.0 . 4.0) (0.0 . -4.0)))
|
||||
)
|
||||
|
||||
(mat fp-unboxing
|
||||
(begin
|
||||
(define-syntax check-loop-allocation
|
||||
(syntax-rules ()
|
||||
[(_ proc) ; proc should allocate only its result flonum
|
||||
(or (eq? (current-eval) interpret)
|
||||
(let ([before (+ (bytes-allocated) (bytes-deallocated))]
|
||||
[N 100000])
|
||||
(box?
|
||||
(let loop ([i N] [bx (box 0.0)])
|
||||
(if (zero? i)
|
||||
bx
|
||||
(loop (sub1 i) (let ([v (unbox bx)])
|
||||
(box (proc v)))))))
|
||||
(let ([allocated (- (+ (bytes-allocated) (bytes-deallocated)) before)]
|
||||
[expected (* N (+ (compute-size 1.0)
|
||||
(compute-size (box #f))))])
|
||||
(printf "~s ~s\n" allocated expected)
|
||||
(<= expected allocated (* 1.2 expected)))))]))
|
||||
#t)
|
||||
|
||||
(check-loop-allocation (lambda (v) (fl+ v v)))
|
||||
(check-loop-allocation (lambda (v) (fl* v v)))
|
||||
(check-loop-allocation (lambda (v) (fl- v 1.0)))
|
||||
(check-loop-allocation (lambda (v) (fl/ v 2.0)))
|
||||
|
||||
(check-loop-allocation (lambda (v) (fl+ v 2.0 v)))
|
||||
(check-loop-allocation (lambda (v) (fl+ v (fl* 2.0 v))))
|
||||
|
||||
(check-loop-allocation (lambda (v) (fl+ v v v)))
|
||||
(check-loop-allocation (lambda (v) (fl+ v (fl* v v) (fl/ v 2.0))))
|
||||
|
||||
(check-loop-allocation (lambda (v) (flabs v)))
|
||||
(check-loop-allocation (lambda (v) (fl- v)))
|
||||
|
||||
(check-loop-allocation (lambda (v) (flabs (fl+ v v))))
|
||||
(check-loop-allocation (lambda (v) (fl- (fl+ v v))))
|
||||
|
||||
(let ([i 0])
|
||||
(check-loop-allocation (lambda (v) (begin
|
||||
(set! i (add1 i))
|
||||
(fl+ v (fixnum->flonum i))))))
|
||||
|
||||
(check-loop-allocation (lambda (v) (if (fl= (fl+ v (fl* 2.0 v)) 7.0)
|
||||
(fl+ v 1.0)
|
||||
(fl- v 1.0))))
|
||||
(check-loop-allocation (lambda (v) (if (fl< (fl+ v v) v)
|
||||
(fl+ v 1.0)
|
||||
(fl- v 1.0))))
|
||||
(check-loop-allocation (lambda (v) (if (fl> (fl+ v v) v)
|
||||
(fl+ v 1.0)
|
||||
(fl- v 1.0))))
|
||||
(check-loop-allocation (lambda (v) (if (fl<= (fl+ v v) v)
|
||||
(fl+ v 1.0)
|
||||
(fl- v 1.0))))
|
||||
(check-loop-allocation (lambda (v) (if (fl>= (fl+ v v) v)
|
||||
(fl+ v 1.0)
|
||||
(fl- v 1.0))))
|
||||
|
||||
(let ([bv (make-bytevector 8 0)])
|
||||
(check-loop-allocation (lambda (v) (fl+ v (bytevector-ieee-double-native-ref bv 0)))))
|
||||
(let ([bv (make-bytevector 8 0)])
|
||||
(check-loop-allocation (lambda (v) (begin
|
||||
(bytevector-ieee-double-native-set! bv 0 (fl+ v 0.1))
|
||||
(fl* v 0.99)))))
|
||||
|
||||
)
|
||||
|
|
10
mats/ieee.ms
10
mats/ieee.ms
|
@ -159,7 +159,7 @@
|
|||
(mat fl=
|
||||
(let ((n (read (open-input-string "+nan.0"))))
|
||||
(not (fl= n n)))
|
||||
(not (fl= (nan)))
|
||||
(fl= (nan))
|
||||
(not (fl= (nan) +inf.0))
|
||||
(not (fl= (nan) -inf.0))
|
||||
(not (fl= (nan) (nan)))
|
||||
|
@ -171,7 +171,7 @@
|
|||
)
|
||||
|
||||
(mat fl<
|
||||
(not (fl< (nan)))
|
||||
(fl< (nan))
|
||||
(not (fl< (nan) (nan)))
|
||||
(not (fl< (nan) 0.0))
|
||||
(not (fl< 0.0 (nan)))
|
||||
|
@ -179,7 +179,7 @@
|
|||
)
|
||||
|
||||
(mat fl>
|
||||
(not (fl> (nan)))
|
||||
(fl> (nan))
|
||||
(not (fl> (nan) (nan)))
|
||||
(not (fl> (nan) 0.0))
|
||||
(not (fl> 0.0 (nan)))
|
||||
|
@ -189,14 +189,14 @@
|
|||
)
|
||||
|
||||
(mat fl<=
|
||||
(not (fl<= (nan)))
|
||||
(fl<= (nan))
|
||||
(not (fl<= (nan) (nan)))
|
||||
(not (fl<= (nan) 0.0))
|
||||
(not (fl<= 0.0 (nan)))
|
||||
)
|
||||
|
||||
(mat fl>=
|
||||
(not (fl>= (nan)))
|
||||
(fl>= (nan))
|
||||
(not (fl>= (nan) (nan)))
|
||||
(not (fl>= (nan) 0.0))
|
||||
(not (fl>= 0.0 (nan)))
|
||||
|
|
|
@ -5293,6 +5293,13 @@
|
|||
(condition-wait c m)
|
||||
(loop)))
|
||||
(mutex-release m)
|
||||
;; Wait for threads to exit
|
||||
(let ()
|
||||
(define $threads (foreign-procedure "(cs)threads" () scheme-object))
|
||||
(let loop ()
|
||||
(unless (= 1 (length ($threads)))
|
||||
(sleep (make-time 'time-duration 10000 0))
|
||||
(loop))))
|
||||
#t))
|
||||
|
||||
)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long long int")
|
||||
(define-constant typedef-uptr "unsigned long long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
436
s/arm32.ss
436
s/arm32.ss
|
@ -60,53 +60,52 @@
|
|||
|
||||
(define-registers
|
||||
(reserved
|
||||
[%tc %r9 #t 9]
|
||||
[%sfp %r10 #t 10]
|
||||
[%ap %r5 #t 5]
|
||||
[%tc %r9 #t 9 uptr]
|
||||
[%sfp %r10 #t 10 uptr]
|
||||
[%ap %r5 #t 5 uptr]
|
||||
#;[%esp]
|
||||
#;[%eap]
|
||||
[%trap %r8 #t 8])
|
||||
[%trap %r8 #t 8 uptr])
|
||||
(allocable
|
||||
[%ac0 %r4 #t 4]
|
||||
[%xp %r6 #t 6]
|
||||
[%ts %ip #f 12]
|
||||
[%td %r11 #t 11]
|
||||
[%ac0 %r4 #t 4 uptr]
|
||||
[%xp %r6 #t 6 uptr]
|
||||
[%ts %ip #f 12 uptr]
|
||||
[%td %r11 #t 11 uptr]
|
||||
#;[%ret]
|
||||
[%cp %r7 #t 7]
|
||||
[%cp %r7 #t 7 uptr]
|
||||
#;[%ac1]
|
||||
#;[%yp]
|
||||
[ %r0 %Carg1 %Cretval #f 0]
|
||||
[ %r1 %Carg2 #f 1]
|
||||
[ %r2 %Carg3 #f 2]
|
||||
[ %r3 %Carg4 #f 3]
|
||||
[ %lr #f 14] ; %lr is trashed by 'c' calls including calls to hand-coded routines like get-room
|
||||
[ %r0 %Carg1 %Cretval #f 0 uptr]
|
||||
[ %r1 %Carg2 #f 1 uptr]
|
||||
[ %r2 %Carg3 #f 2 uptr]
|
||||
[ %r3 %Carg4 #f 3 uptr]
|
||||
[ %lr #f 14 uptr] ; %lr is trashed by 'c' calls including calls to hand-coded routines like get-room
|
||||
[%fp1 %Cfparg5 %d4 %s8 #f 8 fp]
|
||||
[%fp2 %Cfparg6 %d5 %s10 #f 10 fp]
|
||||
)
|
||||
(machine-dependent
|
||||
[%sp #t 13]
|
||||
[%pc #f 15]
|
||||
[%Cfparg1 %Cfpretval %d0 %s0 #f 0] ; < 32: low bit goes in D, N, or M bit, high bits go in Vd, Vn, Vm
|
||||
[%Cfparg1b %s1 #f 1]
|
||||
[%Cfparg2 %d1 %s2 #f 2]
|
||||
[%Cfparg2b %s3 #f 3]
|
||||
[%Cfparg3 %d2 %s4 #f 4]
|
||||
[%Cfparg3b %s5 #f 5]
|
||||
[%Cfparg4 %d3 %s6 #f 6]
|
||||
[%Cfparg4b %s7 #f 7]
|
||||
[%Cfparg5 %d4 %s8 #f 8]
|
||||
[%Cfparg5b %s9 #f 9]
|
||||
[%Cfparg6 %d5 %s10 #f 10]
|
||||
[%Cfparg6b %s11 #f 11]
|
||||
[%Cfparg7 %d6 %s12 #f 12]
|
||||
[%Cfparg7b %s13 #f 13]
|
||||
[%Cfparg8 %d7 %s14 #f 14]
|
||||
[%Cfparg8b %s15 #f 15]
|
||||
[%flreg1 %d8 %s16 #f 16]
|
||||
[%flreg2 %d9 %s18 #f 18]
|
||||
[%sp #t 13 uptr]
|
||||
[%pc #f 15 uptr]
|
||||
[%Cfparg1 %Cfpretval %d0 %s0 #f 0 fp] ; < 32: low bit goes in D, N, or M bit, high bits go in Vd, Vn, Vm
|
||||
[%Cfparg1b %s1 #f 1 fp]
|
||||
[%Cfparg2 %d1 %s2 #f 2 fp]
|
||||
[%Cfparg2b %s3 #f 3 fp]
|
||||
[%Cfparg3 %d2 %s4 #f 4 fp]
|
||||
[%Cfparg3b %s5 #f 5 fp]
|
||||
[%Cfparg4 %d3 %s6 #f 6 fp]
|
||||
[%Cfparg4b %s7 #f 7 fp]
|
||||
[%Cfparg5b %s9 #f 9 fp]
|
||||
[%Cfparg6b %s11 #f 11 fp]
|
||||
[%Cfparg7 %fptmp1 %d6 %s12 #f 12 fp]
|
||||
[%Cfparg7b %fptmp2 %s13 #f 13 fp]
|
||||
[%Cfparg8 %d7 %s14 #f 14 fp]
|
||||
[%Cfparg8b %s15 #f 15 fp]
|
||||
;; etc., but other FP registers are preserved
|
||||
#;[ %d16 #t 32 fp] ; >= 32: high bit goes in D, N, or M bit, low bits go in Vd, Vn, Vm
|
||||
#;[ %d17 #t 33 fp]
|
||||
; etc.
|
||||
#;[ %d16 #f 32] ; >= 32: high bit goes in D, N, or M bit, low bits go in Vd, Vn, Vm
|
||||
#;[ %d17 #f 33]
|
||||
; etc.
|
||||
))
|
||||
)
|
||||
(reify-support %ts %lr %r3 %r2))
|
||||
|
||||
;;; SECTION 2: instructions
|
||||
(module (md-handle-jump) ; also sets primitive handlers
|
||||
|
@ -130,6 +129,18 @@
|
|||
(lambda (x)
|
||||
(or (lmem? x) (literal@? x))))
|
||||
|
||||
(define fpmem?
|
||||
(lambda (x)
|
||||
(nanopass-case (L15c Triv) x
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm ,type) (eq? type 'fp)]
|
||||
[else #f])))
|
||||
|
||||
(define-syntax mem-of-type?
|
||||
(lambda (stx)
|
||||
(syntax-case stx (mem fpmem)
|
||||
[(_ mem e) #'(lmem? e)]
|
||||
[(_ fpmem e) #'(fpmem? e)])))
|
||||
|
||||
(define imm-funky12?
|
||||
(lambda (x)
|
||||
(nanopass-case (L15c Triv) x
|
||||
|
@ -206,42 +217,42 @@
|
|||
(define mref->mref
|
||||
(lambda (a k)
|
||||
(define return
|
||||
(lambda (x0 x1 imm)
|
||||
(lambda (x0 x1 imm type)
|
||||
; arm load & store instructions support index or offset but not both
|
||||
(safe-assert (or (eq? x1 %zero) (eqv? imm 0)))
|
||||
(k (with-output-language (L15d Triv) `(mref ,x0 ,x1 ,imm)))))
|
||||
(k (with-output-language (L15d Triv) `(mref ,x0 ,x1 ,imm ,type)))))
|
||||
(nanopass-case (L15c Triv) a
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm)
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm ,type)
|
||||
(lvalue->ur lvalue0
|
||||
(lambda (x0)
|
||||
(lvalue->ur lvalue1
|
||||
(lambda (x1)
|
||||
(cond
|
||||
[(and (eq? x1 %zero) (or (unsigned12? imm) (unsigned12? (- imm))))
|
||||
(return x0 %zero imm)]
|
||||
(return x0 %zero imm type)]
|
||||
[(funky12 imm) =>
|
||||
; NB: dubious value? check to see if it's exercised
|
||||
(lambda (imm)
|
||||
(let ([u (make-tmp 'u)])
|
||||
(seq
|
||||
(build-set! ,u (asm ,null-info ,(asm-add #f) ,x0 (immediate ,imm)))
|
||||
(return u x1 0))))]
|
||||
(return u x1 0 type))))]
|
||||
[(funky12 (- imm)) =>
|
||||
; NB: dubious value? check to see if it's exercised
|
||||
(lambda (imm)
|
||||
(let ([u (make-tmp 'u)])
|
||||
(seq
|
||||
(build-set! ,u (asm ,null-info ,(asm-sub #f) ,x0 (immediate ,imm)))
|
||||
(return u x1 0))))]
|
||||
(return u x1 0 type))))]
|
||||
[else
|
||||
(let ([u (make-tmp 'u)])
|
||||
(seq
|
||||
(build-set! ,u (immediate ,imm))
|
||||
(if (eq? x1 %zero)
|
||||
(return x0 u 0)
|
||||
(return x0 u 0 type)
|
||||
(seq
|
||||
(build-set! ,u (asm ,null-info ,(asm-add #f) ,u ,x1))
|
||||
(return x0 u 0)))))])))))])))
|
||||
(return x0 u 0 type)))))])))))])))
|
||||
|
||||
(define mem->mem
|
||||
(lambda (a k)
|
||||
|
@ -250,14 +261,46 @@
|
|||
(let ([u (make-tmp 'u)])
|
||||
(seq
|
||||
(build-set! ,u ,(literal@->literal a))
|
||||
(k (with-output-language (L15d Lvalue) `(mref ,u ,%zero 0)))))]
|
||||
(k (with-output-language (L15d Lvalue) `(mref ,u ,%zero 0 uptr)))))]
|
||||
[else (mref->mref a k)])))
|
||||
|
||||
(define fpmem->fpmem
|
||||
(lambda (a k)
|
||||
(define return
|
||||
(lambda (x0 x1 imm)
|
||||
(k (with-output-language (L15d Triv) `(mref ,x0 ,x1 ,imm fp)))))
|
||||
(nanopass-case (L15c Triv) a
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm ,type)
|
||||
(lvalue->ur lvalue0
|
||||
(lambda (x0)
|
||||
(lvalue->ur lvalue1
|
||||
(lambda (x1)
|
||||
(cond
|
||||
[(not (and (<= 0 imm #x3FF)
|
||||
(fx= 0 (fxand imm #b11))))
|
||||
;; offset not aligned or out of range
|
||||
(let ([u (make-tmp 'umov)])
|
||||
(seq
|
||||
(build-set! ,u (asm ,null-info ,(asm-add #f) ,x0 (immediate ,imm)))
|
||||
(if (eq? x1 %zero)
|
||||
(return u %zero 0)
|
||||
(seq
|
||||
(build-set! ,u (asm ,null-info ,(asm-add #f) ,u ,x1))
|
||||
(return u %zero 0)))))]
|
||||
[(not (eq? x1 %zero))
|
||||
(let ([u (make-tmp 'umov)])
|
||||
(seq
|
||||
(build-set! ,u (asm ,null-info ,(asm-add #f) ,x0 ,x1))
|
||||
(return u %zero imm)))]
|
||||
[else
|
||||
(return x0 %zero imm)])))))])))
|
||||
|
||||
(define-syntax coercible?
|
||||
(syntax-rules ()
|
||||
[(_ ?a ?aty*)
|
||||
(let ([a ?a] [aty* ?aty*])
|
||||
(or (memq 'ur aty*)
|
||||
(or (and (memq 'ur aty*) (not (or (fpmem? a) (fpur? a))))
|
||||
(and (memq 'fpur aty*) (or (fpmem? a) (fpur? a)))
|
||||
(and (memq 'funky12 aty*) (imm-funky12? a))
|
||||
(and (memq 'negate-funky12 aty*) (imm-negate-funky12? a))
|
||||
(and (memq 'lognot-funky12 aty*) (imm-lognot-funky12? a))
|
||||
|
@ -298,6 +341,18 @@
|
|||
(build-set! ,u ,a)
|
||||
(k u)))))]
|
||||
[else (sorry! 'coerce-opnd "unexpected operand ~s" a)])]
|
||||
[(memq 'fpur aty*)
|
||||
(cond
|
||||
[(fpur? a) (k a)]
|
||||
[(fpmem? a)
|
||||
(fpmem->fpmem a
|
||||
(lambda (a)
|
||||
(let ([u (make-tmp 'u 'fp)])
|
||||
(seq
|
||||
(build-set! ,u ,a)
|
||||
(k u)))))]
|
||||
[else
|
||||
(sorry! 'coerce-opnd "unexpected operand ~s" a)])]
|
||||
[else (sorry! 'coerce-opnd "cannot coerce ~s to ~s" a aty*)]))]))
|
||||
|
||||
(define set-ur=mref
|
||||
|
@ -332,9 +387,15 @@
|
|||
|
||||
(define-syntax define-instruction
|
||||
(lambda (x)
|
||||
(define mem-type?
|
||||
(lambda (t)
|
||||
(syntax-case t (mem fpmem)
|
||||
[mem #t]
|
||||
[fpmem #t]
|
||||
[else #f])))
|
||||
(define make-value-clause
|
||||
(lambda (fmt)
|
||||
(syntax-case fmt (mem ur)
|
||||
(syntax-case fmt (mem fpmem ur fpur)
|
||||
[(op (c mem) (a ur))
|
||||
#`(lambda (c a)
|
||||
(if (lmem? c)
|
||||
|
@ -344,6 +405,20 @@
|
|||
(lambda (c)
|
||||
(rhs c a)))))
|
||||
(next c a)))]
|
||||
[(op (c fpmem) (a aty ...) ...)
|
||||
#`(lambda (c a ...)
|
||||
(if (and (fpmem? c) (coercible? a '(aty ...)) ...)
|
||||
#,(let f ([a* #'(a ...)] [aty** #'((aty ...) ...)])
|
||||
(cond
|
||||
[(null? a*)
|
||||
#'(fpmem->fpmem c
|
||||
(lambda (c)
|
||||
(rhs c a ...)))]
|
||||
[else
|
||||
#`(coerce-opnd #,(car a*) '#,(car aty**)
|
||||
(lambda (#,(car a*))
|
||||
#,(f (cdr a*) (cdr aty**))))]))
|
||||
(next c a ...)))]
|
||||
[(op (c ur) (a aty ...) ...)
|
||||
#`(lambda (c a ...)
|
||||
(if (and (coercible? a '(aty ...)) ...)
|
||||
|
@ -359,6 +434,22 @@
|
|||
(build-set! ,c ,u))))))
|
||||
#`(coerce-opnd #,(car a*) '#,(car aty**)
|
||||
(lambda (#,(car a*)) #,(f (cdr a*) (cdr aty**))))))
|
||||
(next c a ...)))]
|
||||
[(op (c fpur) (a aty ...) ...)
|
||||
#`(lambda (c a ...)
|
||||
(if (and (coercible? a '(aty ...)) ...)
|
||||
#,(let f ([a* #'(a ...)] [aty** #'((aty ...) ...)])
|
||||
(if (null? a*)
|
||||
#'(if (fpur? c)
|
||||
(rhs c a ...)
|
||||
(let ([u (make-tmp 'u 'fp)])
|
||||
(seq
|
||||
(rhs u a ...)
|
||||
(fpmem->fpmem c
|
||||
(lambda (c)
|
||||
(build-set! ,c ,u))))))
|
||||
#`(coerce-opnd #,(car a*) '#,(car aty**)
|
||||
(lambda (#,(car a*)) #,(f (cdr a*) (cdr aty**))))))
|
||||
(next c a ...)))])))
|
||||
|
||||
(define-who make-pred-clause
|
||||
|
@ -679,31 +770,58 @@
|
|||
(lambda (x1)
|
||||
(with-flonum-data-pointers (x2 ...) e1 e2 ...)))])))
|
||||
|
||||
(define-instruction effect (flt)
|
||||
[(op (x ur) (y ur))
|
||||
(with-flonum-data-pointers (y)
|
||||
`(asm ,info ,asm-flt ,x ,y))])
|
||||
(define (fpmem->mem mem dir)
|
||||
(with-output-language (L15d Triv)
|
||||
(nanopass-case (L15d Triv) mem
|
||||
[(mref ,x1 ,x2 ,imm ,type)
|
||||
(safe-assert (eq? type 'fp))
|
||||
(let ([delta (constant-case native-endianness
|
||||
[(little) (if (eq? dir 'lo) 0 4)]
|
||||
[(big) (if (eq? dir 'hi) 0 4)])])
|
||||
`(mref ,x1 ,x2 ,(fx+ imm delta) uptr))]
|
||||
[else (sorry! 'fpmem->mem "unexpected reference ~s" mem)])))
|
||||
|
||||
(define-instruction effect (fl+ fl- fl/ fl*)
|
||||
[(op (x ur) (y ur) (z ur))
|
||||
(with-flonum-data-pointers (x y z)
|
||||
`(asm ,info ,(asm-flop-2 op) ,x ,y ,z))])
|
||||
(define-instruction value (fpt)
|
||||
[(op (x fpur) (y ur))
|
||||
`(set! ,(make-live-info) ,x (asm ,info ,asm-fpt ,y))])
|
||||
|
||||
(define-instruction effect (flsqrt)
|
||||
[(op (x ur) (y ur))
|
||||
(with-flonum-data-pointers (x y)
|
||||
`(asm ,info ,asm-flsqrt ,x ,y))])
|
||||
(define-instruction value (fpmove)
|
||||
[(op (x fpmem) (y fpur)) `(set! ,(make-live-info) ,x ,y)]
|
||||
[(op (x fpur) (y fpur)) `(set! ,(make-live-info) ,x ,y)])
|
||||
|
||||
(define-instruction value (fpcastto/hi)
|
||||
[(op (x ur) (y fpmem)) `(set! ,(make-live-info) ,x ,(fpmem->mem y 'hi))]
|
||||
[(op (x ur) (y fpur)) `(set! ,(make-live-info) ,x (asm ,info ,(asm-fpcastto 'hi) ,y))])
|
||||
|
||||
(define-instruction value (fpcastto/lo)
|
||||
[(op (x ur) (y fpmem)) `(set! ,(make-live-info) ,x ,(fpmem->mem y 'lo))]
|
||||
[(op (x ur) (y fpur)) `(set! ,(make-live-info) ,x (asm ,info ,(asm-fpcastto 'lo) ,y))])
|
||||
|
||||
(define-instruction value (fpcastfrom)
|
||||
[(op (x fpmem) (hi ur) (lo ur)) (seq
|
||||
`(set! ,(make-live-info) ,(fpmem->mem x 'lo) ,lo)
|
||||
`(set! ,(make-live-info) ,(fpmem->mem x 'hi) ,hi))]
|
||||
[(op (x fpur) (hi ur) (lo ur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpcastfrom ,lo ,hi))])
|
||||
|
||||
|
||||
|
||||
(define-instruction value (fp+ fp- fp/ fp*)
|
||||
[(op (x fpur) (y fpur) (z fpur))
|
||||
`(set! ,(make-live-info) ,x (asm ,info ,(asm-fpop-2 op) ,y ,z))])
|
||||
|
||||
(define-instruction value (fpsqrt)
|
||||
[(op (x fpur) (y fpur))
|
||||
`(set! ,(make-live-info) ,x (asm ,info ,asm-fpsqrt ,y))])
|
||||
|
||||
(define-instruction value (trunc)
|
||||
[(op (z ur) (x ur))
|
||||
(with-flonum-data-pointers (x)
|
||||
`(set! ,(make-live-info) ,z (asm ,info ,asm-trunc ,x)))])
|
||||
|
||||
(define-instruction pred (fl= fl< fl<=)
|
||||
[(op (x ur) (y ur))
|
||||
(with-flonum-data-pointers (x y)
|
||||
(define-instruction pred (fp= fp< fp<=)
|
||||
[(op (x fpur) (y fpur))
|
||||
(let ([info (make-info-condition-code op #f #f)])
|
||||
(values '() `(asm ,info ,(asm-fl-relop info) ,x ,y))))]))
|
||||
(values '() `(asm ,info ,(asm-fp-relop info) ,x ,y)))]))
|
||||
|
||||
(define-instruction effect (inc-cc-counter)
|
||||
[(op (x ur) (w ur funky12) (z funky12 ur))
|
||||
|
@ -891,15 +1009,15 @@
|
|||
asm-move asm-move/extend asm-load asm-store asm-swap asm-library-call asm-library-call! asm-library-jump
|
||||
asm-mul asm-smull asm-cmp/shift asm-add asm-sub asm-rsb asm-logand asm-logor asm-logxor asm-bic
|
||||
asm-pop-multiple asm-shiftop asm-logand asm-lognot
|
||||
asm-logtest asm-fl-relop asm-relop asm-push-multiple asm-vpush-multiple
|
||||
asm-logtest asm-fp-relop asm-relop asm-push-multiple asm-vpush-multiple
|
||||
asm-indirect-jump asm-literal-jump
|
||||
asm-direct-jump asm-return-address asm-jump asm-conditional-jump asm-data-label
|
||||
asm-rp-header asm-rp-compact-header
|
||||
asm-indirect-call asm-condition-code
|
||||
asm-fl-load/store
|
||||
asm-fl-load/cvt asm-fl-store/cvt asm-flt asm-trunc
|
||||
asm-fl-load/cvt asm-fl-store/cvt asm-fpt asm-fpmove asm-fpcastto asm-fpcastfrom asm-trunc
|
||||
asm-lock asm-lock+/- asm-cas
|
||||
asm-flop-2 asm-flsqrt asm-c-simple-call
|
||||
asm-fpop-2 asm-fpsqrt asm-c-simple-call
|
||||
asm-save-flrv asm-restore-flrv asm-return asm-c-return asm-size
|
||||
asm-enter asm-foreign-call asm-foreign-callable
|
||||
asm-read-counter
|
||||
|
@ -1079,8 +1197,10 @@
|
|||
(define-op vstr.sgl vldr/vstr-op #b1010 #b00)
|
||||
(define-op vstr.dbl vldr/vstr-op #b1011 #b00)
|
||||
|
||||
(define-op vmov.gpr->s32 vmov-op #b0)
|
||||
(define-op vmov.s32->gpr vmov-op #b1)
|
||||
(define-op vmov.gpr->s32 vmov.gpr-op #b0)
|
||||
(define-op vmov.s32->gpr vmov.gpr-op #b1)
|
||||
(define-op vmov.gprgpr->s64 vmov.gpr64-op #b0)
|
||||
(define-op vmov.fpr vmov.fpr-op)
|
||||
|
||||
(define-op vcvt.sgl->dbl vcvt-op #b01 #b110111)
|
||||
(define-op vcvt.dbl->sgl vcvt-op #b11 #b110111)
|
||||
|
@ -1347,6 +1467,8 @@
|
|||
|
||||
(define vldr/vstr-op
|
||||
(lambda (op opc1 opc2 flreg reg offset code*)
|
||||
(safe-assert (and (<= 0 offset #x3FF)
|
||||
(fx= 0 (fxand offset #b11))))
|
||||
(let-values ([(d vd) (ax-flreg->bits flreg)])
|
||||
(emit-code (op flreg reg offset code*)
|
||||
[28 (ax-cond 'al)]
|
||||
|
@ -1360,9 +1482,9 @@
|
|||
[8 opc1]
|
||||
[0 (fxsrl offset 2)]))))
|
||||
|
||||
(define vmov-op
|
||||
(lambda (op dir flreg gpreg code*)
|
||||
(let-values ([(n vn) (ax-flreg->bits flreg)])
|
||||
(define vmov.gpr-op
|
||||
(lambda (op dir flreg flreg-delta gpreg code*)
|
||||
(let-values ([(n vn) (ax-flreg->bits flreg flreg-delta)])
|
||||
(emit-code (op flreg gpreg code*)
|
||||
[28 (ax-cond 'al)]
|
||||
[21 #b1110000]
|
||||
|
@ -1373,6 +1495,44 @@
|
|||
[7 n]
|
||||
[0 #b0010000]))))
|
||||
|
||||
(define vmov.gpr64-op
|
||||
(lambda (op dir flreg gpreglo gpreghi code*)
|
||||
(let-values ([(n vn) (ax-flreg->bits flreg)])
|
||||
(emit-code (op flreg gpreglo gpreghi code*)
|
||||
[28 (ax-cond 'al)]
|
||||
[23 #b11000]
|
||||
[22 1]
|
||||
[21 0]
|
||||
[20 dir] ; 0 to fp, 1 from fp
|
||||
[16 (ax-ea-reg-code gpreghi)]
|
||||
[12 (ax-ea-reg-code gpreglo)]
|
||||
[10 #b10]
|
||||
[8 #b11]
|
||||
[6 #b00]
|
||||
[5 n]
|
||||
[4 1]
|
||||
[0 vn]))))
|
||||
|
||||
(define vmov.fpr-op
|
||||
(lambda (op destreg srcreg code*)
|
||||
(let-values ([(d vd) (ax-flreg->bits destreg)]
|
||||
[(m vm) (ax-flreg->bits srcreg)])
|
||||
(emit-code (op destreg srcreg code*)
|
||||
[28 (ax-cond 'al)]
|
||||
[23 #b11101]
|
||||
[22 0] ; D
|
||||
[20 #b11]
|
||||
[19 d]
|
||||
[16 #b000]
|
||||
[12 vd]
|
||||
[10 #b10]
|
||||
[8 #b11]
|
||||
[7 0]
|
||||
[6 1]
|
||||
[5 m]
|
||||
[4 0]
|
||||
[00 vm]))))
|
||||
|
||||
(define vcvt-op
|
||||
(lambda (op szop opc2 dest src code*)
|
||||
(let-values ([(d vd) (ax-flreg->bits dest)]
|
||||
|
@ -1588,11 +1748,13 @@
|
|||
[else ($oops who "unsupported op ~s" op)])))
|
||||
|
||||
(define ax-flreg->bits
|
||||
(lambda (flreg)
|
||||
(let ([n (reg-mdinfo flreg)])
|
||||
(case-lambda
|
||||
[(flreg) (ax-flreg->bits flreg 0)]
|
||||
[(flreg flreg-delta)
|
||||
(let ([n (fx+ (reg-mdinfo flreg) flreg-delta)])
|
||||
(if (fx< n 32)
|
||||
(values (fxlogand n 1) (fxsrl n 1))
|
||||
(values (fxsrl n 4) (fxlogand n #b1111))))))
|
||||
(values (fxsrl n 4) (fxlogand n #b1111))))]))
|
||||
|
||||
(define-syntax emit-code
|
||||
(lambda (x)
|
||||
|
@ -1803,11 +1965,11 @@
|
|||
(Trivit (base offset)
|
||||
(case op
|
||||
[(load-single->double)
|
||||
(emit vldr.sgl %flreg2 base (ax-imm-data offset)
|
||||
(emit vcvt.sgl->dbl flreg %flreg2 code*))]
|
||||
(emit vldr.sgl %fptmp2 base (ax-imm-data offset)
|
||||
(emit vcvt.sgl->dbl flreg %fptmp2 code*))]
|
||||
[(load-double->single)
|
||||
(emit vldr.dbl %flreg2 base (ax-imm-data offset)
|
||||
(emit vcvt.dbl->sgl flreg %flreg2 code*))]
|
||||
(emit vldr.dbl %fptmp2 base (ax-imm-data offset)
|
||||
(emit vcvt.dbl->sgl flreg %fptmp2 code*))]
|
||||
[else (sorry! who "unrecognized op ~s" op)])))))
|
||||
|
||||
(define-who asm-fl-store/cvt
|
||||
|
@ -1816,8 +1978,8 @@
|
|||
(Trivit (base offset)
|
||||
(case op
|
||||
[(store-single->double)
|
||||
(emit vcvt.sgl->dbl %flreg2 flreg
|
||||
(emit vstr.dbl %flreg2 base (ax-imm-data offset) code*))]
|
||||
(emit vcvt.sgl->dbl %fptmp2 flreg
|
||||
(emit vstr.dbl %fptmp2 base (ax-imm-data offset) code*))]
|
||||
[else (sorry! who "unrecognized op ~s" op)])))))
|
||||
|
||||
(define-who asm-fl-load/store
|
||||
|
@ -1884,40 +2046,66 @@
|
|||
[else (sorry! who "unexpected mref type ~s" type)]))]
|
||||
[else (sorry! who "expected %zero index or 0 offset, got ~s and ~s" index offset)])))))))
|
||||
|
||||
(define-who asm-flop-2
|
||||
(define-who asm-fpop-2
|
||||
(lambda (op)
|
||||
(lambda (code* src1 src2 dest)
|
||||
(Trivit (src1 src2 dest)
|
||||
(emit vldr.dbl %flreg1 src1 0
|
||||
(emit vldr.dbl %flreg2 src2 0
|
||||
(let ([code* (emit vstr.dbl %flreg1 dest 0 code*)])
|
||||
(lambda (code* dest src1 src2)
|
||||
(case op
|
||||
[(fl+) (emit vadd %flreg1 %flreg1 %flreg2 code*)]
|
||||
[(fl-) (emit vsub %flreg1 %flreg1 %flreg2 code*)]
|
||||
[(fl*) (emit vmul %flreg1 %flreg1 %flreg2 code*)]
|
||||
[(fl/) (emit vdiv %flreg1 %flreg1 %flreg2 code*)]
|
||||
[else (sorry! who "unrecognized op ~s" op)]))))))))
|
||||
[(fp+) (emit vadd dest src1 src2 code*)]
|
||||
[(fp-) (emit vsub dest src1 src2 code*)]
|
||||
[(fp*) (emit vmul dest src1 src2 code*)]
|
||||
[(fp/) (emit vdiv dest src1 src2 code*)]
|
||||
[else (sorry! who "unrecognized op ~s" op)]))))
|
||||
|
||||
(define asm-flsqrt
|
||||
(lambda (code* src dest)
|
||||
(Trivit (src dest)
|
||||
(emit vldr.dbl %flreg1 src 0
|
||||
(emit vsqrt %flreg1 %flreg1
|
||||
(emit vstr.dbl %flreg1 dest 0 code*))))))
|
||||
(define asm-fpsqrt
|
||||
(lambda (code* dest src)
|
||||
(emit vsqrt dest src code*)))
|
||||
|
||||
(define asm-trunc
|
||||
(lambda (code* dest flonumreg)
|
||||
(Trivit (dest flonumreg)
|
||||
(emit vldr.dbl %flreg1 flonumreg 0
|
||||
(emit vcvt.dbl->s32 %flreg1 %flreg1
|
||||
(emit vmov.s32->gpr %flreg1 dest code*))))))
|
||||
(emit vldr.dbl %fptmp1 flonumreg 0
|
||||
(emit vcvt.dbl->s32 %fptmp1 %fptmp1
|
||||
(emit vmov.s32->gpr %fptmp1 0 dest code*))))))
|
||||
|
||||
(define asm-flt
|
||||
(lambda (code* src flonumreg)
|
||||
(Trivit (src flonumreg)
|
||||
(emit vmov.gpr->s32 %flreg1 src
|
||||
(emit vcvt.s32->dbl %flreg1 %flreg1
|
||||
(emit vstr.dbl %flreg1 flonumreg 0 code*))))))
|
||||
(define asm-fpt
|
||||
(lambda (code* dest src)
|
||||
(Trivit (src)
|
||||
(emit vmov.gpr->s32 %fptmp1 0 src
|
||||
(emit vcvt.s32->dbl %fptmp1 dest code*)))))
|
||||
|
||||
(define-who asm-fpmove
|
||||
;; fpmove pseudo instruction is used by set! case in
|
||||
;; select-instructions! and generate-code; at most one of src or
|
||||
;; dest can be an mref, and then the offset is double-aligned
|
||||
(lambda (code* dest src)
|
||||
(let ([dest-it dest]
|
||||
[src-it src])
|
||||
(Trivit (dest-it src-it)
|
||||
(record-case dest-it
|
||||
[(disp) (imm reg)
|
||||
(safe-assert (fx= 0 (fxand imm #b11)))
|
||||
(emit vstr.dbl src (cons 'reg reg) imm code*)]
|
||||
[(index) (n ireg breg) (sorry! who "cannot handle indexed fp dest ref")]
|
||||
[else
|
||||
(record-case src-it
|
||||
[(disp) (imm reg)
|
||||
(safe-assert (fx= 0 (fxand imm #b11)))
|
||||
(emit vldr.dbl dest (cons 'reg reg) imm code*)]
|
||||
[(index) (n ireg breg) (sorry! who "cannot handle indexed fp src ref")]
|
||||
[else (emit vmov.fpr dest src code*)])])))))
|
||||
|
||||
(define asm-fpcastto
|
||||
(lambda (part)
|
||||
(lambda (code* dest src)
|
||||
(Trivit (dest)
|
||||
(if (eq? part 'lo)
|
||||
(emit vmov.gpr->s32 src 0 dest code*)
|
||||
(emit vmov.gpr->s32 src 1 dest code*))))))
|
||||
|
||||
(define asm-fpcastfrom
|
||||
(lambda (code* dest lo-src hi-src)
|
||||
(Trivit (lo-src hi-src)
|
||||
(emit vmov.gprgpr->s64 dest lo-src hi-src code*))))
|
||||
|
||||
(define-who asm-swap
|
||||
(lambda (type)
|
||||
|
@ -1982,16 +2170,12 @@
|
|||
(emit cmpi tmp2 0
|
||||
code*))))))))
|
||||
|
||||
(define asm-fl-relop
|
||||
(define asm-fp-relop
|
||||
(lambda (info)
|
||||
(lambda (l1 l2 offset x y)
|
||||
(Trivit (x y)
|
||||
(values
|
||||
(emit vldr.dbl %flreg1 x 0
|
||||
(emit vldr.dbl %flreg2 y 0
|
||||
(emit vcmp %flreg1 %flreg2
|
||||
(emit fpscr->apsr '()))))
|
||||
(asm-conditional-jump info l1 l2 offset))))))
|
||||
(emit vcmp x y (emit fpscr->apsr '()))
|
||||
(asm-conditional-jump info l1 l2 offset)))))
|
||||
|
||||
(define-who asm-relop
|
||||
(lambda (info)
|
||||
|
@ -2231,9 +2415,9 @@
|
|||
[(overflow) (i? bvc bvs)]
|
||||
[(multiply-overflow) (i? beq bne)] ; result of comparing sign bit of low word with all bits in high word: eq if no overflow, ne if oveflow
|
||||
[(carry) (i? bcc bcs)]
|
||||
[(fl<) (i? (r? ble bcs) (r? bgt bcc))]
|
||||
[(fl<=) (i? (r? blt bhi) (r? bge bls))]
|
||||
[(fl=) (i? bne beq)]))))))
|
||||
[(fp<) (i? (r? ble bcs) (r? bgt bcc))]
|
||||
[(fp<=) (i? (r? blt bhi) (r? bge bls))]
|
||||
[(fp=) (i? bne beq)]))))))
|
||||
|
||||
(define asm-data-label
|
||||
(lambda (code* l offset func code-size)
|
||||
|
@ -2387,14 +2571,14 @@
|
|||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-double ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-double ,%sp ,%zero (immediate ,offset)))))]
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-double ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-double ,%sp ,%zero (immediate ,offset)))))]
|
||||
[load-single-stack
|
||||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-double->single ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-single ,%sp ,%zero (immediate ,offset)))))]
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-double->single ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-single ,%sp ,%zero (immediate ,offset)))))]
|
||||
[load-int-stack
|
||||
(lambda (offset)
|
||||
(lambda (rhs) ; requires rhs
|
||||
|
@ -2737,14 +2921,14 @@
|
|||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(define load-single-stack
|
||||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-single->double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-single->double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(define load-int-stack
|
||||
(lambda (type offset)
|
||||
(lambda (lvalue)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -732,16 +732,11 @@
|
|||
|
||||
(set-who! bytevector-ieee-double-native-ref
|
||||
(lambda (v i)
|
||||
(if ($bytevector-ref-check? 64 v i)
|
||||
(#3%bytevector-ieee-double-native-ref v i)
|
||||
(if (bytevector? v)
|
||||
(invalid-index who v i)
|
||||
(not-a-bytevector who v)))))
|
||||
(#2%bytevector-ieee-double-native-ref v i)))
|
||||
|
||||
(set-who! bytevector-ieee-single-native-set!
|
||||
(lambda (v i x)
|
||||
(if ($bytevector-set!-check? 32 v i)
|
||||
; inline routine checks to make sure x is a real number
|
||||
(#3%bytevector-ieee-single-native-set! v i x)
|
||||
(if (mutable-bytevector? v)
|
||||
(invalid-index who v i)
|
||||
|
@ -749,12 +744,7 @@
|
|||
|
||||
(set-who! bytevector-ieee-double-native-set!
|
||||
(lambda (v i x)
|
||||
(if ($bytevector-set!-check? 64 v i)
|
||||
; inline routine checks to make sure x is a real number
|
||||
(#3%bytevector-ieee-double-native-set! v i x)
|
||||
(if (mutable-bytevector? v)
|
||||
(invalid-index who v i)
|
||||
(not-a-mutable-bytevector who v)))))
|
||||
(#2%bytevector-ieee-double-native-set! v i x)))
|
||||
|
||||
(set-who! bytevector-copy
|
||||
(lambda (v)
|
||||
|
|
20
s/cmacros.ss
20
s/cmacros.ss
|
@ -328,7 +328,7 @@
|
|||
[(_ foo e1 e2) e1] ...
|
||||
[(_ bar e1 e2) e2]))))])))
|
||||
|
||||
(define-constant scheme-version #x0905031C)
|
||||
(define-constant scheme-version #x0905031D)
|
||||
|
||||
(define-syntax define-machine-types
|
||||
(lambda (x)
|
||||
|
@ -412,6 +412,11 @@
|
|||
(define-constant ptr-alignment
|
||||
(/ (constant byte-alignment) (constant ptr-bytes)))
|
||||
|
||||
;; Stack alignment may be needed for unboxed floating-point values:
|
||||
(constant-case ptr-bits
|
||||
[(32) (define-constant stack-word-alignment 2)]
|
||||
[(64) (define-constant stack-word-alignment 1)])
|
||||
|
||||
;; seginfo offsets, must be consistent with `seginfo` in "types.h"
|
||||
(define-constant seginfo-space-disp 0)
|
||||
(define-constant seginfo-generation-disp 1)
|
||||
|
@ -1448,7 +1453,8 @@
|
|||
[void* lz4-out-buffer]
|
||||
[U64 instr-counter]
|
||||
[U64 alloc-counter]
|
||||
[ptr parameters]))
|
||||
[ptr parameters]
|
||||
[double fpregs (constant asm-fpreg-max)]))
|
||||
|
||||
(define tc-field-list
|
||||
(let f ([ls (oblist)] [params '()])
|
||||
|
@ -1686,6 +1692,7 @@
|
|||
(unsafe #b00001000000000000000000)
|
||||
(unrestricted #b00010000000000000000000)
|
||||
(safeongoodargs #b00100000000000000000000)
|
||||
(unboxed-arguments #b10000000000000000000000) ; always accepts unboxed 'flonum arguments, up to inline-args-limit
|
||||
(cptypes2 #b01000000000000000000000)
|
||||
(cptypes3 cptypes2)
|
||||
(cptypes2x cptypes2)
|
||||
|
@ -1696,6 +1703,8 @@
|
|||
(partial-folder (or cp02 cp03))
|
||||
)
|
||||
|
||||
(define-constant inline-args-limit 10)
|
||||
|
||||
(define-flags cp0-info-mask
|
||||
(pure-known #b0000000001)
|
||||
(pure #b0000000010)
|
||||
|
@ -1806,6 +1815,9 @@
|
|||
(float-type-case
|
||||
[(ieee) (fx= ($flonum-exponent x) #x7ff)]))))
|
||||
|
||||
;; #t => incompatibility with older Chez Scheme:
|
||||
(define-constant nan-single-comparison-true? #t)
|
||||
|
||||
(define-syntax on-reset
|
||||
(syntax-rules ()
|
||||
((_ oops e1 e2 ...)
|
||||
|
@ -2503,6 +2515,7 @@
|
|||
(cfl/ #f 2 #f #t)
|
||||
(negate #f 1 #f #t)
|
||||
(flnegate #f 1 #t #t)
|
||||
(flabs #f 1 #t #t)
|
||||
(call-error #f 0 #f #f)
|
||||
(unsafe-unread-char #f 2 #f #t)
|
||||
(map-car #f 1 #f #t)
|
||||
|
@ -2523,6 +2536,7 @@
|
|||
(fxsll #f 2 #f #t)
|
||||
(fxsrl #f 2 #t #t)
|
||||
(fxsra #f 2 #t #t)
|
||||
(fixnum->flonum #f 1 #t #t)
|
||||
(append #f 2 #f #t)
|
||||
(values-error #f 0 #f #f)
|
||||
(dooverflow #f 0 #f #f)
|
||||
|
@ -2640,6 +2654,8 @@
|
|||
(bytevector-s8-set! #f 3 #f #t)
|
||||
(bytevector-u8-set! #f 3 #f #t)
|
||||
(bytevector=? #f 2 #f #f)
|
||||
(bytevector-ieee-double-native-ref #f 2 #t #t)
|
||||
(bytevector-ieee-double-native-set! #f 2 #t #t)
|
||||
(real->flonum #f 2 #f #t)
|
||||
(unsafe-port-eof? #f 1 #f #t)
|
||||
(unsafe-lookahead-u8 #f 1 #f #t)
|
||||
|
|
8
s/cp0.ss
8
s/cp0.ss
|
@ -550,7 +550,13 @@
|
|||
; pure OR body to be pure, since we can't separate non-pure
|
||||
; RHS and body expressions
|
||||
[(letrec ([,x* ,e*] ...) ,body)
|
||||
(guard (or (ivory? body) (andmap ivory1? e*)))
|
||||
(guard (and (or (ivory? body) (andmap ivory1? e*))
|
||||
;; don't break apart (potential) loops
|
||||
(not (and (fx= (length x*) 1)
|
||||
(nanopass-case (Lsrc Expr) body
|
||||
[(call ,preinfo (ref ,maybe-src ,x) ,e* ...)
|
||||
(eq? x (car x*))]
|
||||
[else #f])))))
|
||||
; assocate each lhs with cooked operand for corresponding rhs. see note above.
|
||||
(for-each (lambda (x e) (prelex-operand-set! x (build-cooked-opnd e)) (operand-name-set! opnd (prelex-name x))) x* e*)
|
||||
(values (make-lifted #f x* e*) body)]
|
||||
|
|
1154
s/cpnanopass.ss
1154
s/cpnanopass.ss
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
15
s/inspect.ss
15
s/inspect.ss
|
@ -2281,8 +2281,12 @@
|
|||
(values (make-vector count) count cp))
|
||||
(let ([obj (vector-ref vals i)] [var* (vector-ref vars i)])
|
||||
(cond
|
||||
[(eq? obj cookie)
|
||||
(unless (null? var*) ($oops who "expected value for ~s but it was not in lpm" (car var*)))
|
||||
[(and (eq? obj cookie)
|
||||
(or (null? var*)
|
||||
;; unboxed variable?
|
||||
(not (and (pair? var*) (box? (car var*)) (null? (cdr var*))))))
|
||||
(unless (null? var*)
|
||||
($oops who "expected value for ~s but it was not in lpm" (car var*)))
|
||||
(f (fx1+ i) count cp cpvar*)]
|
||||
[(null? var*)
|
||||
(let-values ([(v frame-count cp) (f (fx1+ i) (fx1+ count) cp cpvar*)])
|
||||
|
@ -2310,7 +2314,12 @@
|
|||
(vector->list var)))]
|
||||
[else
|
||||
(let-values ([(v frame-count cp) (g (cdr var*) (fx1+ count) cp cpvar*)])
|
||||
(vector-set! v count (make-variable-object obj var))
|
||||
(vector-set! v count (cond
|
||||
[(box? var)
|
||||
;; unboxed variable
|
||||
(make-variable-object '<unboxed-flonum> (unbox var))]
|
||||
[else
|
||||
(make-variable-object obj var)]))
|
||||
(values v frame-count cp))])))))]))))
|
||||
(lambda (v frame-count cp)
|
||||
(real-make-continuation-object x (rp-info-src rpi) (rp-info-sexpr rpi) cp v frame-count pos))))))]
|
||||
|
|
17
s/library.ss
17
s/library.ss
|
@ -303,6 +303,11 @@
|
|||
(define index-oops
|
||||
(lambda (who x i)
|
||||
($oops who "~s is not a valid index for ~s" i x)))
|
||||
(define bytevector-index-oops
|
||||
;; for consistency with error before library entry was introduced:
|
||||
(lambda (who x i)
|
||||
($oops who "invalid index ~s for bytevector ~s" i x)))
|
||||
|
||||
(define stencil-vector-oops
|
||||
(lambda (who x)
|
||||
($oops who "~s is not a vector" x)))
|
||||
|
@ -400,6 +405,16 @@
|
|||
(define-library-entry (stencil-vector-mask v)
|
||||
(stencil-vector-oops 'stencil-vector-mask v))
|
||||
|
||||
(define-library-entry (bytevector-ieee-double-native-ref v i)
|
||||
(if (bytevector? v)
|
||||
(bytevector-index-oops 'bytevector-ieee-double-native-ref v i)
|
||||
(bytevector-oops 'bytevector-ieee-double-native-ref v)))
|
||||
|
||||
(define-library-entry (bytevector-ieee-double-native-set! v i)
|
||||
(if (mutable-bytevector? v)
|
||||
(bytevector-index-oops 'bytevector-ieee-double-native-set! v i)
|
||||
(mutable-bytevector-oops 'bytevector-ieee-double-native-set! v)))
|
||||
|
||||
(define-library-entry (char=? x y) (char-oops 'char=? (if (char? x) y x)))
|
||||
(define-library-entry (char<? x y) (char-oops 'char<? (if (char? x) y x)))
|
||||
(define-library-entry (char>? x y) (char-oops 'char>? (if (char? x) y x)))
|
||||
|
@ -523,6 +538,7 @@
|
|||
(define-library-entry (fxxor x y) (fxnonfixnum2 'fxxor x y))
|
||||
(define-library-entry (fxand x y) (fxnonfixnum2 'fxand x y))
|
||||
(define-library-entry (fxnot x) (fxnonfixnum1 'fxnot x))
|
||||
(define-library-entry (fixnum->flonum x) (fxnonfixnum1 'fixnum->flonum x))
|
||||
(define-library-entry (fxpopcount x) ($oops 'fxpopcount32 "~s is not a non-negative fixnum" x))
|
||||
(define-library-entry (fxpopcount32 x) ($oops 'fxpopcount32 "~s is not a 32-bit fixnum" x))
|
||||
(define-library-entry (fxpopcount16 x) ($oops 'fxpopcount16 "~s is not a 16-bit fixnum" x))
|
||||
|
@ -658,6 +674,7 @@
|
|||
(define-library-entry (fl* x y) (flonum-oops 'fl* (if (flonum? x) y x)))
|
||||
(define-library-entry (fl/ x y) (flonum-oops 'fl/ (if (flonum? x) y x)))
|
||||
(define-library-entry (flnegate x) (flonum-oops 'fl- x))
|
||||
(define-library-entry (flabs x) (flonum-oops 'flabs x))
|
||||
)
|
||||
|
||||
(define-library-entry (flround x)
|
||||
|
|
|
@ -272,8 +272,7 @@
|
|||
|
||||
(set! flabs
|
||||
(lambda (x)
|
||||
(unless (flonum? x) (flargerr 'flabs x))
|
||||
(#3%flabs x)))
|
||||
(#2%flabs x)))
|
||||
|
||||
(set! flround
|
||||
(lambda (x)
|
||||
|
@ -682,8 +681,7 @@
|
|||
|
||||
(set! fixnum->flonum
|
||||
(lambda (x)
|
||||
(unless (fixnum? x) (fxargerr 'fixnum->flonum x))
|
||||
(#3%fixnum->flonum x)))
|
||||
(#2%fixnum->flonum x)))
|
||||
|
||||
(set-who! fxlength
|
||||
(lambda (x)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
(module np-languages ()
|
||||
(export sorry! var? var-index var-index-set! prelex->uvar make-tmp make-assigned-tmp
|
||||
make-unspillable make-cpvar make-restricted-unspillable
|
||||
uvar? uvar-name uvar-type uvar-source
|
||||
uvar? uvar-name uvar-type uvar-type-set! uvar-source
|
||||
uvar-referenced? uvar-referenced! uvar-assigned? uvar-assigned!
|
||||
uvar-was-closure-ref? uvar-was-closure-ref!
|
||||
uvar-unspillable? uvar-spilled? uvar-spilled! uvar-local-save? uvar-local-save!
|
||||
|
@ -29,13 +29,13 @@
|
|||
uvar-ref-weight uvar-ref-weight-set! uvar-save-weight uvar-save-weight-set!
|
||||
uvar-live-count uvar-live-count-set!
|
||||
uvar
|
||||
fv-offset
|
||||
fv-offset fv-type
|
||||
var-spillable-conflict* var-spillable-conflict*-set!
|
||||
var-unspillable-conflict* var-unspillable-conflict*-set!
|
||||
uvar-degree uvar-degree-set!
|
||||
uvar-info-lambda uvar-info-lambda-set!
|
||||
uvar-iii uvar-iii-set!
|
||||
ur?
|
||||
ur? fpur?
|
||||
block make-block block? block-label block-effect* block-src* block-pseudo-src block-in-link* block-flags
|
||||
block-label-set! block-effect*-set! block-src*-set! block-pseudo-src-set! block-in-link*-set! block-flags-set!
|
||||
block-live-in block-live-in-set! block-fp-offset block-fp-offset-set!
|
||||
|
@ -57,7 +57,7 @@
|
|||
live-info make-live-info live-info-live live-info-live-set! live-info-useless live-info-useless-set!
|
||||
primitive-pure? primitive-type primitive-handler primitive-handler-set!
|
||||
%primitive value-primitive? pred-primitive? effect-primitive?
|
||||
fv? $make-fv make-reg reg? reg-name reg-tc-disp reg-callee-save? reg-mdinfo
|
||||
fv? $make-fv make-reg reg? reg-name reg-tc-disp reg-callee-save? reg-mdinfo reg-type
|
||||
reg-precolored reg-precolored-set!
|
||||
label? label-name
|
||||
libspec-label? make-libspec-label libspec-label-libspec libspec-label-live-reg*
|
||||
|
@ -92,13 +92,13 @@
|
|||
|
||||
(define-record-type (fv $make-fv fv?)
|
||||
(parent var)
|
||||
(fields offset)
|
||||
(fields offset type)
|
||||
(nongenerative)
|
||||
(sealed #t)
|
||||
(protocol
|
||||
(lambda (pargs->new)
|
||||
(lambda (offset)
|
||||
((pargs->new) offset)))))
|
||||
(lambda (offset type)
|
||||
((pargs->new) offset type)))))
|
||||
|
||||
(module ()
|
||||
(record-writer (record-type-descriptor fv)
|
||||
|
@ -107,13 +107,13 @@
|
|||
|
||||
(define-record-type reg
|
||||
(parent var)
|
||||
(fields name mdinfo tc-disp callee-save? (mutable precolored))
|
||||
(fields name mdinfo tc-disp callee-save? type (mutable precolored))
|
||||
(nongenerative)
|
||||
(sealed #t)
|
||||
(protocol
|
||||
(lambda (pargs->new)
|
||||
(lambda (name mdinfo tc-disp callee-save?)
|
||||
((pargs->new) name mdinfo tc-disp callee-save? #f)))))
|
||||
(lambda (name mdinfo tc-disp callee-save? type)
|
||||
((pargs->new) name mdinfo tc-disp callee-save? type #f)))))
|
||||
|
||||
(module ()
|
||||
(record-writer (record-type-descriptor reg)
|
||||
|
@ -169,7 +169,7 @@
|
|||
(fields
|
||||
name
|
||||
source
|
||||
type
|
||||
(mutable type)
|
||||
conflict*
|
||||
(mutable flags)
|
||||
(mutable info-lambda)
|
||||
|
@ -206,8 +206,8 @@
|
|||
[(name) (make-assigned-tmp name 'ptr)]
|
||||
[(name type) ($make-uvar name #f type '() (uvar-flags-mask referenced assigned))]))
|
||||
(define make-unspillable
|
||||
(lambda (name)
|
||||
($make-uvar name #f 'ptr '() (uvar-flags-mask referenced unspillable))))
|
||||
(lambda (name type)
|
||||
($make-uvar name #f type '() (uvar-flags-mask referenced unspillable))))
|
||||
(define make-cpvar
|
||||
(lambda ()
|
||||
(include "types.ss")
|
||||
|
@ -220,7 +220,9 @@
|
|||
(module ()
|
||||
(record-writer (record-type-descriptor uvar)
|
||||
(lambda (x p wr)
|
||||
(write (lookup-unique-uvar x) p))))
|
||||
(write (lookup-unique-uvar x) p)
|
||||
(when (eq? (uvar-type x) 'fp)
|
||||
(write 'fp p)))))
|
||||
|
||||
(define lookup-unique-uvar
|
||||
(let ([ht (make-eq-hashtable)])
|
||||
|
@ -439,6 +441,12 @@
|
|||
(- (clause (x* ...) interface body))
|
||||
(+ (clause (x* ...) mcp interface body))))
|
||||
|
||||
(define (mref-type? t)
|
||||
;; Currently, only 'fp vesus non-'fp matters
|
||||
(or (eq? t 'ptr)
|
||||
(eq? t 'uptr)
|
||||
(eq? t 'fp)))
|
||||
|
||||
; move labels to top level and expands closures forms to more primitive operations
|
||||
(define-language L7 (extends L6)
|
||||
(terminals
|
||||
|
@ -446,7 +454,8 @@
|
|||
(fixnum (interface)))
|
||||
(+ (var (x))
|
||||
(primitive (prim)) ; moved up one language to support closure instrumentation
|
||||
(fixnum (interface offset))))
|
||||
(fixnum (interface offset))
|
||||
(mref-type (type))))
|
||||
(entry Program)
|
||||
(Program (prog)
|
||||
(+ (labels ([l* le*] ...) l) => (labels ([l* le*] ...) (l))))
|
||||
|
@ -454,7 +463,7 @@
|
|||
(+ (fcallable info l) => (fcallable info l)))
|
||||
(Lvalue (lvalue)
|
||||
(+ x
|
||||
(mref e1 e2 imm)))
|
||||
(mref e1 e2 imm type)))
|
||||
(Expr (e body)
|
||||
(- x
|
||||
(fcallable info)
|
||||
|
@ -471,7 +480,9 @@
|
|||
(set! lvalue e)
|
||||
; these two forms are added here so expand-inline handlers can expand into them
|
||||
(values info e* ...)
|
||||
(goto l))))
|
||||
(goto l)
|
||||
; for floating-point unboxing during expand-line:
|
||||
(unboxed-fp e))))
|
||||
|
||||
(define-record-type primitive
|
||||
(fields name type pure? (mutable handler))
|
||||
|
@ -525,14 +536,8 @@
|
|||
(declare-primitive c-simple-call effect #f)
|
||||
(declare-primitive c-simple-return effect #f)
|
||||
(declare-primitive deactivate-thread effect #f) ; threaded version only
|
||||
(declare-primitive fl* effect #f)
|
||||
(declare-primitive fl+ effect #f)
|
||||
(declare-primitive fl- effect #f)
|
||||
(declare-primitive fl/ effect #f)
|
||||
(declare-primitive fldl effect #f) ; x86
|
||||
(declare-primitive flds effect #f) ; x86
|
||||
(declare-primitive flsqrt effect #f) ; not implemented for some ppc32 (so we don't use it)
|
||||
(declare-primitive flt effect #f)
|
||||
(declare-primitive inc-cc-counter effect #f)
|
||||
(declare-primitive inc-profile-counter effect #f)
|
||||
(declare-primitive invoke-prelude effect #f)
|
||||
|
@ -567,9 +572,9 @@
|
|||
(declare-primitive >= pred #t)
|
||||
(declare-primitive condition-code pred #t)
|
||||
(declare-primitive eq? pred #t)
|
||||
(declare-primitive fl< pred #t)
|
||||
(declare-primitive fl<= pred #t)
|
||||
(declare-primitive fl= pred #t)
|
||||
(declare-primitive fp< pred #t)
|
||||
(declare-primitive fp<= pred #t)
|
||||
(declare-primitive fp= pred #t)
|
||||
(declare-primitive lock! pred #f)
|
||||
(declare-primitive logtest pred #t)
|
||||
(declare-primitive log!test pred #t)
|
||||
|
@ -615,6 +620,19 @@
|
|||
(declare-primitive zext16 value #t)
|
||||
(declare-primitive zext32 value #t) ; 64-bit only
|
||||
|
||||
(declare-primitive fpmove value #t)
|
||||
(declare-primitive fp+ value #t)
|
||||
(declare-primitive fp- value #t)
|
||||
(declare-primitive fp* value #t)
|
||||
(declare-primitive fp/ value #t)
|
||||
(declare-primitive fpt value #t)
|
||||
(declare-primitive fpsqrt value #t) ; not implemented for some ppc32 (so we don't use it)
|
||||
|
||||
(declare-primitive fpcastto value #t) ; 64-bit only
|
||||
(declare-primitive fpcastto/hi value #t) ; 32-bit only
|
||||
(declare-primitive fpcastto/lo value #t) ; 32-bit only
|
||||
(declare-primitive fpcastfrom value #t) ; 64-bit: 1 argument; 32-bit: 2 arguments
|
||||
|
||||
(define immediate?
|
||||
(let ([low (- (bitwise-arithmetic-shift-left 1 (fx- (constant ptr-bits) 1)))]
|
||||
[high (- (bitwise-arithmetic-shift-left 1 (constant ptr-bits)) 1)])
|
||||
|
@ -652,7 +670,8 @@
|
|||
(+ (hand-coded sym)))
|
||||
(Expr (e body)
|
||||
(- (quote d)
|
||||
pr)))
|
||||
pr
|
||||
(unboxed-fp e))))
|
||||
|
||||
; determine where we should be placing interrupt and overflow
|
||||
(define-language L9.5 (extends L9)
|
||||
|
@ -683,8 +702,8 @@
|
|||
(- (clause (x* ...) mcp interface body))
|
||||
(+ (clause (x* ...) (local* ...) mcp interface body)))
|
||||
(Lvalue (lvalue)
|
||||
(- (mref e1 e2 imm))
|
||||
(+ (mref x1 x2 imm)))
|
||||
(- (mref e1 e2 imm type))
|
||||
(+ (mref x1 x2 imm type)))
|
||||
(Triv (t)
|
||||
(+ lvalue
|
||||
(literal info) => info
|
||||
|
@ -854,7 +873,8 @@
|
|||
(label (l rpl))
|
||||
(source-object (src))
|
||||
(symbol (sym))
|
||||
(boolean (as-fallthrough)))
|
||||
(boolean (as-fallthrough))
|
||||
(mref-type (type)))
|
||||
(Program (prog)
|
||||
(labels ([l* le*] ...) l) => (letrec ([l* le*] ...) (l)))
|
||||
(CaseLambdaExpr (le)
|
||||
|
@ -862,7 +882,7 @@
|
|||
(hand-coded sym))
|
||||
(Lvalue (lvalue)
|
||||
x
|
||||
(mref x1 x2 imm))
|
||||
(mref x1 x2 imm type))
|
||||
(Triv (t)
|
||||
lvalue
|
||||
(literal info) => info
|
||||
|
@ -985,7 +1005,8 @@
|
|||
(return-label (mrvl))
|
||||
(boolean (error-on-values as-fallthrough))
|
||||
(fixnum (max-fv offset))
|
||||
(block (block entry-block)))
|
||||
(block (block entry-block))
|
||||
(mref-type (type)))
|
||||
(Program (pgm)
|
||||
(labels ([l* le*] ...) l) => (letrec ([l* le*] ...) (l)))
|
||||
(CaseLambdaExpr (le)
|
||||
|
@ -993,7 +1014,7 @@
|
|||
(Dummy (dumdum) (dummy))
|
||||
(Lvalue (lvalue)
|
||||
x
|
||||
(mref x1 x2 imm))
|
||||
(mref x1 x2 imm type))
|
||||
(Triv (t)
|
||||
lvalue
|
||||
(literal info) => info
|
||||
|
@ -1049,14 +1070,21 @@
|
|||
(lambda (x)
|
||||
(or (reg? x) (uvar? x))))
|
||||
|
||||
(define fpur?
|
||||
(lambda (x)
|
||||
(or (and (reg? x)
|
||||
(eq? (reg-type x) 'fp))
|
||||
(and (uvar? x)
|
||||
(eq? (uvar-type x) 'fp)))))
|
||||
|
||||
(define-language L15c (extends L15b)
|
||||
(terminals
|
||||
(- (var (x var)))
|
||||
(+ (ur (x))))
|
||||
; NB: base and index are really either regs or (mref %sfp %zero imm)
|
||||
(Lvalue (lvalue)
|
||||
(- (mref x1 x2 imm))
|
||||
(+ (mref lvalue1 lvalue2 imm)))
|
||||
(- (mref x1 x2 imm type))
|
||||
(+ (mref lvalue1 lvalue2 imm type)))
|
||||
(Effect (e)
|
||||
(- (fp-offset live-info imm))))
|
||||
|
||||
|
@ -1068,8 +1096,8 @@
|
|||
(+ (procedure (proc)) => $procedure-name))
|
||||
(entry Program)
|
||||
(Lvalue (lvalue)
|
||||
(- (mref lvalue1 lvalue2 imm))
|
||||
(+ (mref x1 x2 imm)))
|
||||
(- (mref lvalue1 lvalue2 imm type))
|
||||
(+ (mref x1 x2 imm type)))
|
||||
(Rhs (rhs)
|
||||
(- (inline info value-prim t* ...))
|
||||
(+ (asm info proc t* ...) => (asm proc t* ...)))
|
||||
|
|
|
@ -91,11 +91,11 @@
|
|||
(define-symbol-flags* ([libraries (rnrs) (rnrs arithmetic flonums)] [flags primitive proc])
|
||||
(flonum? [sig [(ptr) -> (boolean)]] [flags pure unrestricted mifoldable discard])
|
||||
(real->flonum [sig [(real) -> (flonum)]] [flags arith-op mifoldable discard safeongoodargs])
|
||||
(fl=? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; restricted to 2+ arguments
|
||||
(fl<? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; restricted to 2+ arguments
|
||||
(fl<=? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; restricted to 2+ arguments
|
||||
(fl>? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; restricted to 2+ arguments
|
||||
(fl>=? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; restricted to 2+ arguments
|
||||
(fl=? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs unboxed-arguments]) ; restricted to 2+ arguments
|
||||
(fl<? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs unboxed-arguments]) ; restricted to 2+ arguments
|
||||
(fl<=? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs unboxed-arguments]) ; restricted to 2+ arguments
|
||||
(fl>? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs unboxed-arguments]) ; restricted to 2+ arguments
|
||||
(fl>=? [sig [(flonum flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs unboxed-arguments]) ; restricted to 2+ arguments
|
||||
(flinteger? [sig [(flonum) -> (boolean)]] [flags pure mifoldable discard safeongoodargs])
|
||||
(flzero? [sig [(flonum) -> (boolean)]] [flags pure mifoldable discard safeongoodargs])
|
||||
(flpositive? [sig [(flonum) -> (boolean)]] [flags pure mifoldable discard safeongoodargs])
|
||||
|
@ -107,11 +107,11 @@
|
|||
(flnan? [sig [(flonum) -> (boolean)]] [flags pure mifoldable discard safeongoodargs])
|
||||
(flmax [sig [(flonum flonum ...) -> (flonum)]] [flags arith-op mifoldable discard safeongoodargs])
|
||||
(flmin [sig [(flonum flonum ...) -> (flonum)]] [flags arith-op mifoldable discard safeongoodargs])
|
||||
(fl* [sig [(flonum ...) -> (flonum)]] [flags arith-op partial-folder safeongoodargs])
|
||||
(fl+ [sig [(flonum ...) -> (flonum)]] [flags arith-op partial-folder safeongoodargs])
|
||||
(fl- [sig [(flonum flonum ...) -> (flonum)]] [flags arith-op partial-folder safeongoodargs])
|
||||
(fl/ [sig [(flonum flonum ...) -> (flonum)]] [flags arith-op partial-folder safeongoodargs])
|
||||
(flabs [sig [(flonum) -> (flonum)]] [flags arith-op mifoldable discard safeongoodargs])
|
||||
(fl* [sig [(flonum ...) -> (flonum)]] [flags arith-op partial-folder safeongoodargs unboxed-arguments])
|
||||
(fl+ [sig [(flonum ...) -> (flonum)]] [flags arith-op partial-folder safeongoodargs unboxed-arguments])
|
||||
(fl- [sig [(flonum flonum ...) -> (flonum)]] [flags arith-op partial-folder safeongoodargs unboxed-arguments])
|
||||
(fl/ [sig [(flonum flonum ...) -> (flonum)]] [flags arith-op partial-folder safeongoodargs unboxed-arguments])
|
||||
(flabs [sig [(flonum) -> (flonum)]] [flags arith-op mifoldable discard safeongoodargs unboxed-arguments])
|
||||
(fldiv-and-mod [sig [(flonum flonum) -> (flonum flonum)]] [flags discard])
|
||||
(fldiv [sig [(flonum flonum) -> (flonum)]] [flags arith-op mifoldable discard])
|
||||
(flmod [sig [(flonum flonum) -> (flonum)]] [flags arith-op mifoldable discard])
|
||||
|
@ -1327,10 +1327,10 @@
|
|||
(flonum->fixnum [sig [(flonum) -> (fixnum)]] [flags arith-op cp02])
|
||||
(flnonpositive? [sig [(flonum) -> (boolean)]] [flags pure mifoldable discard safeongoodargs])
|
||||
(flnonnegative? [sig [(flonum) -> (boolean)]] [flags pure mifoldable discard safeongoodargs])
|
||||
(fl= [sig [(flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; not restricted to 2+ arguments
|
||||
(fl< [sig [(flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; not restricted to 2+ arguments
|
||||
(fl<= [sig [(flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; not restricted to 2+ arguments
|
||||
(fl> [sig [(flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; not restricted to 2+ arguments
|
||||
(fl= [sig [(flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs unboxed-arguments]) ; not restricted to 2+ arguments
|
||||
(fl< [sig [(flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs unboxed-arguments]) ; not restricted to 2+ arguments
|
||||
(fl<= [sig [(flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs unboxed-arguments]) ; not restricted to 2+ arguments
|
||||
(fl> [sig [(flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs unboxed-arguments]) ; not restricted to 2+ arguments
|
||||
(fl>= [sig [(flonum flonum ...) -> (boolean)]] [flags pure mifoldable discard safeongoodargs]) ; not restricted to 2+ arguments
|
||||
(flush-output-port [sig [() (output-port) -> (void)]] [flags true]) ; not restricted to 1 argument
|
||||
(foreign-entry? [sig [(string) -> (boolean)]] [flags discard])
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long long int")
|
||||
(define-constant typedef-uptr "unsigned long long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 5)
|
||||
(define-constant asm-arg-reg-cnt 3)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "long int")
|
||||
(define-constant typedef-uptr "unsigned long int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 8)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
(define-constant max-integer-alignment 4)
|
||||
(define-constant asm-arg-reg-max 1)
|
||||
(define-constant asm-arg-reg-cnt 1)
|
||||
(define-constant asm-fpreg-max 2)
|
||||
(define-constant typedef-ptr "void *")
|
||||
(define-constant typedef-iptr "int")
|
||||
(define-constant typedef-uptr "unsigned int")
|
||||
|
|
314
s/x86.ss
314
s/x86.ss
|
@ -16,27 +16,30 @@
|
|||
;;; SECTION 1: registers
|
||||
(define-registers
|
||||
(reserved
|
||||
[%tc %edi #t 7]
|
||||
[%sfp %ebp #t 5]
|
||||
[%tc %edi #t 7 uptr]
|
||||
[%sfp %ebp #t 5 uptr]
|
||||
#;[%ap]
|
||||
#;[%esp]
|
||||
#;[%eap]
|
||||
#;[%trap])
|
||||
(allocable ; keep in sync with all-but-byte-registers below
|
||||
[%ac0 %edx #f 2]
|
||||
[%xp %ecx #f 1]
|
||||
[%ts %eax #f 0]
|
||||
[%td %ebx #t 3]
|
||||
[%ac0 %edx #f 2 uptr]
|
||||
[%xp %ecx #f 1 uptr]
|
||||
[%ts %eax #f 0 uptr]
|
||||
[%td %ebx #t 3 uptr]
|
||||
#;[%ret]
|
||||
#;[%cp]
|
||||
#;[%ac1]
|
||||
#;[%yp]
|
||||
[%esi #t 6])
|
||||
[%esi #t 6 uptr]
|
||||
[%fp1 %Cfparg3 #f 2 fp]
|
||||
[%fp2 %Cfparg4 #f 3 fp])
|
||||
(machine-dependent
|
||||
[%flreg1 #f 0]
|
||||
[%flreg2 #f 1]
|
||||
[%sp #t 4]
|
||||
#;[%esi #f 6]))
|
||||
[%fptmp1 #f 0 fp]
|
||||
[%fptmp2 #f 1 fp]
|
||||
[%sp #t 4 uptr]
|
||||
#;[%esi #f 6])
|
||||
(reify-support %ts))
|
||||
|
||||
;;; SECTION 2: instructions
|
||||
(module (md-handle-jump) ; also sets primitive handlers
|
||||
|
@ -66,6 +69,18 @@
|
|||
(lambda (x)
|
||||
(or (lmem? x) (literal@? x))))
|
||||
|
||||
(define fpmem?
|
||||
(lambda (x)
|
||||
(nanopass-case (L15c Triv) x
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm ,type) (eq? type 'fp)]
|
||||
[else #f])))
|
||||
|
||||
(define-syntax mem-of-type?
|
||||
(lambda (stx)
|
||||
(syntax-case stx (mem fpmem)
|
||||
[(_ mem e) #'(lmem? e)]
|
||||
[(_ fpmem e) #'(fpmem? e)])))
|
||||
|
||||
(define real-imm32?
|
||||
(lambda (x)
|
||||
(nanopass-case (L15c Triv) x
|
||||
|
@ -100,12 +115,12 @@
|
|||
(lambda (a k)
|
||||
(nanopass-case (L15c Triv) a
|
||||
; NOTE: x86_64 and risc arch's will need to deal with limitations on the offset
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm)
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm ,type)
|
||||
(lvalue->ur lvalue0
|
||||
(lambda (x0)
|
||||
(lvalue->ur lvalue1
|
||||
(lambda (x1)
|
||||
(k (with-output-language (L15d Triv) `(mref ,x0 ,x1 ,imm)))))))])))
|
||||
(k (with-output-language (L15d Triv) `(mref ,x0 ,x1 ,imm ,type)))))))])))
|
||||
|
||||
(define mem->mem
|
||||
(lambda (a k)
|
||||
|
@ -117,13 +132,15 @@
|
|||
(syntax-rules ()
|
||||
[(_ ?a ?aty*)
|
||||
(let ([a ?a] [aty* ?aty*])
|
||||
(or (memq 'ur aty*)
|
||||
(or (and (memq 'ur aty*) (not (or (fpmem? a) (fpur? a))))
|
||||
(and (memq 'fpur aty*) (or (fpmem? a) (fpur? a)))
|
||||
(or (and (memq 'imm32 aty*) (imm32? a))
|
||||
(and (memq 'imm aty*) (imm? a))
|
||||
(and (memq 'zero aty*) (imm0? a))
|
||||
(and (memq 'real-imm32 aty*) (real-imm32? a))
|
||||
(and (memq 'negatable-real-imm32 aty*) (negatable-real-imm32? a))
|
||||
(and (memq 'mem aty*) (mem? a)))))]))
|
||||
(and (memq 'mem aty*) (mem? a))
|
||||
(and (memq 'fpmem aty*) (fpmem? a)))))]))
|
||||
|
||||
(define-syntax coerce-opnd ; passes k something compatible with aty*
|
||||
(syntax-rules ()
|
||||
|
@ -131,6 +148,7 @@
|
|||
(let ([a ?a] [aty* ?aty*] [k ?k])
|
||||
(cond
|
||||
[(and (memq 'mem aty*) (mem? a)) (mem->mem a k)]
|
||||
[(and (memq 'fpmem aty*) (fpmem? a)) (mem->mem a k)]
|
||||
[(and (memq 'imm32 aty*) (imm32? a)) (k (imm->imm a))]
|
||||
[(and (memq 'imm aty*) (imm? a)) (k (imm->imm a))]
|
||||
[(and (memq 'zero aty*) (imm0? a)) (k (imm->imm a))]
|
||||
|
@ -152,6 +170,18 @@
|
|||
(build-set! ,u ,a)
|
||||
(k u)))))]
|
||||
[else (sorry! 'coerce-opnd "unexpected operand ~s" a)])]
|
||||
[(memq 'fpur aty*)
|
||||
(cond
|
||||
[(fpur? a) (k a)]
|
||||
[(fpmem? a)
|
||||
(mem->mem a
|
||||
(lambda (a)
|
||||
(let ([u (make-tmp 'u 'fp)])
|
||||
(seq
|
||||
(build-set! ,u ,a)
|
||||
(k u)))))]
|
||||
[else
|
||||
(sorry! 'coerce-opnd "unexpected operand ~s" a)])]
|
||||
[else (sorry! 'coerce-opnd "cannot coerce ~s to ~s" a aty*)]))]))
|
||||
|
||||
(define set-ur=mref
|
||||
|
@ -212,22 +242,29 @@
|
|||
[(mref? c)
|
||||
(nanopass-case (L15c Triv) c
|
||||
; NOTE: x86_64 and risc arch's will need to deal with limitations on the offset
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm)
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm ,type)
|
||||
(lvalue->ur lvalue0
|
||||
(lambda (x0)
|
||||
(lvalue->ur lvalue1
|
||||
(lambda (x1)
|
||||
(let ([u (make-tmp 'u)])
|
||||
(seq
|
||||
(build-set! ,u (mref ,x0 ,x1 ,imm))
|
||||
(build-set! ,u (mref ,x0 ,x1 ,imm ,type))
|
||||
(#,k u b)
|
||||
(build-set! (mref ,x0 ,x1 ,imm) ,u)))))))])]
|
||||
(build-set! (mref ,x0 ,x1 ,imm ,type) ,u)))))))])]
|
||||
[else (sorry! '#,(datum->syntax #'* who) "unexpected operand ~s" c)])))
|
||||
(next c a b)))))
|
||||
|
||||
(define mem-type?
|
||||
(lambda (t)
|
||||
(syntax-case t (mem fpmem)
|
||||
[mem #t]
|
||||
[fpmem #t]
|
||||
[else #f])))
|
||||
|
||||
(define make-value-clause
|
||||
(lambda (fmt)
|
||||
(syntax-case fmt (mem ur xp)
|
||||
(syntax-case fmt (mem ur fpur xp)
|
||||
[(op (c mem) (a ?c) (b bty* ...))
|
||||
(bound-identifier=? #'?c #'c)
|
||||
(acsame-mem #'c #'a #'b #'(bty* ...) #'(lambda (c b) (rhs c c b)))]
|
||||
|
@ -240,9 +277,10 @@
|
|||
[(op (c ur) (a aty* ...) (b ?c))
|
||||
(bound-identifier=? #'?c #'c)
|
||||
(acsame-ur #'c #'b #'a #'(aty* ...) #'(lambda (c a) (rhs c a c)))]
|
||||
[(op (c mem) (a aty ...) (b bty ...))
|
||||
[(op (c xmem) (a aty ...) (b bty ...))
|
||||
(mem-type? #'xmem)
|
||||
#`(lambda (c a b)
|
||||
(if (and (lmem? c) (coercible? a '(aty ...)) (coercible? b '(bty ...)))
|
||||
(if (and (mem-of-type? xmem c) (coercible? a '(aty ...)) (coercible? b '(bty ...)))
|
||||
(coerce-opnd b '(bty ...)
|
||||
(lambda (b)
|
||||
(coerce-opnd a '(aty ...)
|
||||
|
@ -265,6 +303,22 @@
|
|||
(lambda (c)
|
||||
(build-set! ,c ,u))))))))))
|
||||
(next c a b)))]
|
||||
[(op (c fpur) (a aty ...) (b bty ...))
|
||||
#`(lambda (c a b)
|
||||
(if (and (coercible? a '(aty ...)) (coercible? b '(bty ...)))
|
||||
(coerce-opnd b '(bty ...)
|
||||
(lambda (b)
|
||||
(coerce-opnd a '(aty ...)
|
||||
(lambda (a)
|
||||
(if (fpur? c)
|
||||
(rhs c a b)
|
||||
(let ([u (make-tmp 'u 'fp)])
|
||||
(seq
|
||||
(rhs u a b)
|
||||
(mref->mref c
|
||||
(lambda (c)
|
||||
(build-set! ,c ,u))))))))))
|
||||
(next c a b)))]
|
||||
; four-operand case below can require four unspillables
|
||||
[(op (c ur) (a ur) (b ur) (d dty ...))
|
||||
(not (memq 'mem (datum (dty ...))))
|
||||
|
@ -307,9 +361,10 @@
|
|||
(rhs u u)
|
||||
(build-set! ,c ,u))))))
|
||||
(next c a)))]
|
||||
[(op (c mem) (a aty ...))
|
||||
[(op (c xmem) (a aty ...))
|
||||
(mem-type? #'xmem)
|
||||
#`(lambda (c a)
|
||||
(if (and (lmem? c) (coercible? a '(aty ...)))
|
||||
(if (and (mem-of-type? xmem c) (coercible? a '(aty ...)))
|
||||
(coerce-opnd a '(aty ...)
|
||||
(lambda (a)
|
||||
(mem->mem c
|
||||
|
@ -330,6 +385,20 @@
|
|||
(rhs u a)
|
||||
(build-set! ,c ,u))))))))
|
||||
(next c a)))]
|
||||
[(op (c fpur) (a aty ...))
|
||||
#`(lambda (c a)
|
||||
(if (coercible? a '(aty ...))
|
||||
(coerce-opnd a '(aty ...)
|
||||
(lambda (a)
|
||||
(if (fpur? c)
|
||||
(rhs c a)
|
||||
(mem->mem c
|
||||
(lambda (c)
|
||||
(let ([u (make-tmp 'u 'fp)])
|
||||
(seq
|
||||
(rhs u a)
|
||||
(build-set! ,c ,u))))))))
|
||||
(next c a)))]
|
||||
[(op (c ur))
|
||||
#`(lambda (c)
|
||||
(if (ur? c)
|
||||
|
@ -754,14 +823,31 @@
|
|||
[(op (x ur) (y ur) (z imm32))
|
||||
`(asm ,info ,(asm-fl-load op (info-loadfl-flreg info)) ,x ,y ,z)])
|
||||
|
||||
(define-instruction effect (flt)
|
||||
[(op (x mem ur) (y ur)) `(asm ,info ,asm-flt ,x ,y)])
|
||||
(define-instruction value (fpt)
|
||||
[(op (x fpur) (y ur)) `(asm ,info ,asm-fpt ,x ,y)])
|
||||
|
||||
(define-instruction effect (fl+ fl- fl/ fl*)
|
||||
[(op (x ur) (y ur) (z ur)) `(asm ,info ,(asm-flop-2 op) ,x ,y ,z)])
|
||||
(define-instruction value (fpmove)
|
||||
[(op (x fpmem) (y fpur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpmove ,y))]
|
||||
[(op (x fpur) (y fpmem fpur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpmove ,y))])
|
||||
|
||||
(define-instruction effect (flsqrt)
|
||||
[(op (x ur) (y ur)) `(asm ,info ,asm-flsqrt ,x ,y)])
|
||||
(define-instruction value (fpcastto/hi) ; little endian: high bytes are at +4
|
||||
[(op (x ur) (y fpmem)) `(set! ,(make-live-info) ,x (asm ,info ,(asm-movefrom 4) ,y))]
|
||||
[(op (x ur) (y fpur)) `(set! ,(make-live-info) ,x (asm ,info ,(asm-fpcastto 32) ,y))])
|
||||
|
||||
(define-instruction value (fpcastto/lo) ; little endian: low byte are immediate bytes
|
||||
[(op (x ur) (y fpmem)) `(set! ,(make-live-info) ,x (asm ,info ,asm-move ,y))]
|
||||
[(op (x ur) (y fpur)) `(set! ,(make-live-info) ,x (asm ,info ,(asm-fpcastto 0) ,y))])
|
||||
|
||||
(define-instruction value (fpcastfrom)
|
||||
[(op (x fpmem) (hi ur) (lo ur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpmovefrom ,lo ,hi))]
|
||||
[(op (x fpur) (hi ur) (lo ur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpcastfrom ,lo ,hi))])
|
||||
|
||||
(define-instruction value (fp+ fp- fp* fp/)
|
||||
[(op (x fpur) (y fpmem fpur) (z fpmem fpur))
|
||||
`(set! ,(make-live-info) ,x (asm ,info ,(asm-fpop-2 op) ,y ,z))])
|
||||
|
||||
(define-instruction value (fpsqrt)
|
||||
[(op (x fpur) (y fpmem fpur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpsqrt ,y))])
|
||||
|
||||
(define-instruction effect inc-cc-counter
|
||||
[(op (x ur) (y imm32 ur) (z imm32 ur)) `(asm ,info ,asm-inc-cc-counter ,x ,y ,z)])
|
||||
|
@ -807,10 +893,13 @@
|
|||
(define-instruction value pop
|
||||
[(op (z ur)) `(set! ,(make-live-info) ,z (asm ,info ,asm-pop))])
|
||||
|
||||
(define-instruction pred (fl= fl< fl<=)
|
||||
[(op (x ur) (y ur))
|
||||
(define-instruction pred (fp= fp< fp<=)
|
||||
[(op (x fpmem) (y fpur))
|
||||
(let ([info (make-info-condition-code op #t #f)]) ; NB: reversed? flag is assumed to be #t
|
||||
(values '() `(asm ,info ,(asm-fl-relop info) ,x ,y)))])
|
||||
(values '() `(asm ,info ,(asm-fp-relop info) ,x ,y)))]
|
||||
[(op (x fpur) (y fpur))
|
||||
(let ([info (make-info-condition-code op #t #f)]) ; NB: reversed? flag is assumed to be #t
|
||||
(values '() `(asm ,info ,(asm-fp-relop info) ,x ,y)))])
|
||||
|
||||
(define-instruction pred (eq? u< < > <= >=)
|
||||
; the idea (following from the intel x86/x86_64 documentation)
|
||||
|
@ -871,7 +960,7 @@
|
|||
`(set! ,(make-live-info) ,uts (immediate 1))
|
||||
`(set! ,(make-live-info) ,uts
|
||||
(asm ,info ,asm-exchange ,uts
|
||||
(mref ,x ,y ,imm)))))])
|
||||
(mref ,x ,y ,imm uptr)))))])
|
||||
`(asm ,info-cc-eq ,asm-eq ,uts (immediate 0))))]))
|
||||
|
||||
(define-instruction effect (locked-incr!)
|
||||
|
@ -926,23 +1015,23 @@
|
|||
(constant-case machine-type-name
|
||||
[(i3osx ti3osx)
|
||||
(seq
|
||||
`(set! ,(make-live-info) ,%tc (mref ,%sp ,%zero 4))
|
||||
`(set! ,(make-live-info) ,%tc (mref ,%sp ,%zero 4 uptr))
|
||||
`(set! ,(make-live-info) ,%sp (asm ,info ,asm-sub ,%sp (immediate 12))))]
|
||||
[else `(set! ,(make-live-info) ,%tc (mref ,%sp ,%zero 4))])])
|
||||
[else `(set! ,(make-live-info) ,%tc (mref ,%sp ,%zero 4 uptr))])])
|
||||
)
|
||||
|
||||
;;; SECTION 3: assembler
|
||||
(module asm-module (; required exports
|
||||
asm-move asm-move/extend asm-load asm-store asm-swap asm-library-call asm-library-jump
|
||||
asm-move asm-move/extend asm-movefrom asm-load asm-store asm-swap asm-library-call asm-library-jump
|
||||
asm-mul asm-muli asm-addop asm-add asm-sub asm-negate asm-sub-negate
|
||||
asm-pop asm-shiftop asm-sll asm-logand asm-lognot
|
||||
asm-logtest asm-fl-relop asm-relop asm-push asm-indirect-jump asm-literal-jump
|
||||
asm-logtest asm-fp-relop asm-relop asm-push asm-indirect-jump asm-literal-jump
|
||||
asm-direct-jump asm-return-address asm-jump asm-conditional-jump asm-data-label
|
||||
asm-rp-header asm-rp-compact-header
|
||||
asm-lea1 asm-lea2 asm-indirect-call asm-fstpl asm-fstps asm-fldl asm-flds asm-condition-code
|
||||
asm-fl-cvt asm-fl-store asm-fl-load asm-flt asm-trunc asm-div
|
||||
asm-fl-cvt asm-fl-store asm-fl-load asm-fpt asm-trunc asm-div
|
||||
asm-exchange asm-pause asm-locked-incr asm-locked-decr asm-locked-cmpxchg
|
||||
asm-flop-2 asm-flsqrt asm-c-simple-call
|
||||
asm-fpop-2 asm-fpmove asm-fpmovefrom asm-fpcastfrom asm-fpcastto asm-fpsqrt asm-c-simple-call
|
||||
asm-save-flrv asm-restore-flrv asm-return asm-c-return asm-size
|
||||
asm-enter asm-foreign-call asm-foreign-callable
|
||||
asm-inc-profile-counter
|
||||
|
@ -961,6 +1050,9 @@
|
|||
[(x) (record-case x [(reg) r #t] [else #f])]
|
||||
[(x reg) (record-case x [(reg) r (eq? r reg)] [else #f])]))
|
||||
|
||||
(define ax-fp-register?
|
||||
(lambda (x) (record-case x [(reg) r (eq? 'fp (reg-type r))] [else #f])))
|
||||
|
||||
(define ax-ea-reg-code
|
||||
(lambda (ea)
|
||||
(record-case ea
|
||||
|
@ -1131,6 +1223,9 @@
|
|||
(define-op sse.subsd sse-op1 #xF2 #x5C)
|
||||
(define-op sse.ucomisd sse-op1 #x66 #x2E)
|
||||
(define-op sse.xorpd sse-op1 #x66 #x57)
|
||||
(define-op sse.psllq sse-shift 6)
|
||||
(define-op sse.psrlq sse-shift 2)
|
||||
(define-op sse.orpd sse-op1 #x66 #x56)
|
||||
|
||||
(define sse-op1
|
||||
(lambda (op prefix-code op-code source dest-reg code*)
|
||||
|
@ -1145,7 +1240,7 @@
|
|||
(define sse-op2
|
||||
(lambda (op prefix-code dstreg-op-code srcreg-op-code source dest code*)
|
||||
(cond
|
||||
[(ax-register? source)
|
||||
[(ax-fp-register? source)
|
||||
(emit-code (op source dest code*)
|
||||
(build byte prefix-code)
|
||||
(build byte #x0F)
|
||||
|
@ -1153,7 +1248,7 @@
|
|||
(ax-ea-modrm-reg dest source)
|
||||
(ax-ea-sib dest)
|
||||
(ax-ea-addr-disp dest))]
|
||||
[(ax-register? dest)
|
||||
[(ax-fp-register? dest)
|
||||
(emit-code (op source dest code*)
|
||||
(build byte prefix-code)
|
||||
(build byte #x0F)
|
||||
|
@ -1164,6 +1259,15 @@
|
|||
[else
|
||||
($oops 'assembler-internal "sse-op2 source=~s dest=~s" source dest)])))
|
||||
|
||||
(define sse-shift
|
||||
(lambda (op op-code dest-reg amt code*)
|
||||
(emit-code (op dest-reg amt code*)
|
||||
(build byte #x66)
|
||||
(build byte #x0F)
|
||||
(build byte #x73)
|
||||
(ax-ea-modrm-ttt dest-reg op-code)
|
||||
(build byte amt))))
|
||||
|
||||
(define float-op2
|
||||
(lambda (op op-code1 op-code2 source-ea code*)
|
||||
(emit-code (op source-ea code*)
|
||||
|
@ -1660,6 +1764,13 @@
|
|||
[(word) 2]
|
||||
[else 4])))
|
||||
|
||||
(define shift-address
|
||||
(lambda (src offset)
|
||||
(record-case src
|
||||
[(disp) (imm x1) `(disp ,(fx+ imm offset) ,x1)]
|
||||
[(index) (imm x2 x1) `(index ,(fx+ imm offset) ,x2 ,x1)]
|
||||
[else ($oops 'shift-address "unexpected shift-address argument ~s" src)])))
|
||||
|
||||
(define asm-move
|
||||
(lambda (code* dest src)
|
||||
(Trivit (dest src)
|
||||
|
@ -1682,6 +1793,12 @@
|
|||
[(zext16) (emit movzw src dest code*)]
|
||||
[else (sorry! who "unexpected op ~s" op)])))))
|
||||
|
||||
(define asm-movefrom
|
||||
(lambda (offset)
|
||||
(lambda (code* dest src)
|
||||
(Trivit (dest src)
|
||||
(emit mov (shift-address src offset) dest code*)))))
|
||||
|
||||
(define asm-fstpl
|
||||
(lambda (code* dest)
|
||||
(Trivit (dest)
|
||||
|
@ -1726,34 +1843,69 @@
|
|||
[(load-single) (emit sse.movss src (cons 'reg flreg) code*)]
|
||||
[(load-double) (emit sse.movsd src (cons 'reg flreg) code*)])))))
|
||||
|
||||
(define asm-flt
|
||||
(lambda (code* src flonumreg)
|
||||
(Trivit (src)
|
||||
(let ([dest `(disp ,(constant flonum-data-disp) ,flonumreg)]
|
||||
[flreg (cons 'reg %flreg1)])
|
||||
(emit sse.cvtsi2sd src flreg
|
||||
(emit sse.movsd flreg dest code*))))))
|
||||
(define asm-fpt
|
||||
(lambda (code* dest src)
|
||||
(Trivit (dest src)
|
||||
(emit sse.cvtsi2sd src dest code*))))
|
||||
|
||||
(define asm-flop-2
|
||||
(define asm-fpop-2
|
||||
(lambda (op)
|
||||
(lambda (code* src1 src2 dest)
|
||||
(let ([src1 `(disp ,(constant flonum-data-disp) ,src1)]
|
||||
[src2 `(disp ,(constant flonum-data-disp) ,src2)]
|
||||
[dest `(disp ,(constant flonum-data-disp) ,dest)])
|
||||
(let ([code* (emit sse.movsd (cons 'reg %flreg1) dest code*)])
|
||||
(let ([code* (case op
|
||||
[(fl+) (emit sse.addsd src2 (cons 'reg %flreg1) code*)]
|
||||
[(fl-) (emit sse.subsd src2 (cons 'reg %flreg1) code*)]
|
||||
[(fl*) (emit sse.mulsd src2 (cons 'reg %flreg1) code*)]
|
||||
[(fl/) (emit sse.divsd src2 (cons 'reg %flreg1) code*)])])
|
||||
(emit sse.movsd src1 (cons 'reg %flreg1) code*)))))))
|
||||
(lambda (code* dest-reg src1 src2)
|
||||
(define (emit-it src dest code*)
|
||||
(case op
|
||||
[(fp+) (emit sse.addsd src dest code*)]
|
||||
[(fp-) (emit sse.subsd src dest code*)]
|
||||
[(fp*) (emit sse.mulsd src dest code*)]
|
||||
[(fp/) (emit sse.divsd src dest code*)]))
|
||||
(cond
|
||||
[(eq? dest-reg src1)
|
||||
(Trivit (dest-reg src2)
|
||||
(emit-it src2 dest-reg code*))]
|
||||
[(and (eq? dest-reg src2)
|
||||
(memq op '(fp+ fp*)))
|
||||
(Trivit (dest-reg src1)
|
||||
(emit-it src1 dest-reg code*))]
|
||||
[else
|
||||
(Trivit (dest-reg src1 src2)
|
||||
(emit sse.movsd src2 (cons 'reg %fptmp1)
|
||||
(emit sse.movsd src1 dest-reg
|
||||
(emit-it (cons 'reg %fptmp1) dest-reg code*))))]))))
|
||||
|
||||
(define asm-flsqrt
|
||||
(lambda (code* src dest)
|
||||
(let ([src `(disp ,(constant flonum-data-disp) ,src)]
|
||||
[dest `(disp ,(constant flonum-data-disp) ,dest)])
|
||||
(emit sse.sqrtsd src (cons 'reg %flreg1)
|
||||
(emit sse.movsd (cons 'reg %flreg1) dest code*)))))
|
||||
(define asm-fpsqrt
|
||||
(lambda (code* dest-reg src)
|
||||
(Trivit (dest-reg src)
|
||||
(emit sse.sqrtsd src dest-reg code*))))
|
||||
|
||||
(define asm-fpmove
|
||||
(lambda (code* dest src)
|
||||
(Trivit (dest src)
|
||||
(emit sse.movsd src dest code*))))
|
||||
|
||||
(define asm-fpmovefrom
|
||||
(lambda (code* dest src1 src2)
|
||||
(Trivit (dest src1 src2)
|
||||
(emit mov src1 dest
|
||||
(emit mov src2 (shift-address dest 4) code*)))))
|
||||
|
||||
(define asm-fpcastfrom
|
||||
(lambda (code* dest-reg src1 src2)
|
||||
(Trivit (dest-reg src1 src2)
|
||||
(emit sse.movd src1 dest-reg
|
||||
(emit sse.movd src2 (cons 'reg %fptmp1)
|
||||
(emit sse.psllq (cons 'reg %fptmp1) 32
|
||||
(emit sse.orpd (cons 'reg %fptmp1) dest-reg code*)))))))
|
||||
|
||||
(define asm-fpcastto
|
||||
(lambda (shift)
|
||||
(lambda (code* dest src)
|
||||
(Trivit (dest src)
|
||||
(cond
|
||||
[(eqv? shift 0)
|
||||
(emit sse.movd src dest code*)]
|
||||
[else
|
||||
(emit sse.movsd src (cons 'reg %fptmp1)
|
||||
(emit sse.psrlq (cons 'reg %fptmp1) shift
|
||||
(emit sse.movd (cons 'reg %fptmp1) dest code*)))])))))
|
||||
|
||||
(define asm-trunc
|
||||
(lambda (code* dest flonumreg)
|
||||
|
@ -2073,14 +2225,12 @@
|
|||
(let-values ([(l1 l2) (if i? (values l2 l1) (values l1 l2))])
|
||||
(asm-conditional-jump info l2 l1 offset)))))))
|
||||
|
||||
(define asm-fl-relop
|
||||
(define asm-fp-relop
|
||||
(lambda (info)
|
||||
(lambda (l1 l2 offset x y)
|
||||
(values
|
||||
(let ([x `(disp ,(constant flonum-data-disp) ,x)]
|
||||
[y `(disp ,(constant flonum-data-disp) ,y)])
|
||||
(emit sse.movsd y (cons 'reg %flreg1)
|
||||
(emit sse.ucomisd x (cons 'reg %flreg1) '())))
|
||||
(Trivit (x y)
|
||||
(emit sse.ucomisd x y '()))
|
||||
(asm-conditional-jump info l1 l2 offset)))))
|
||||
|
||||
(define asm-relop
|
||||
|
@ -2277,11 +2427,11 @@
|
|||
[(carry) (i? bcc bcs)]
|
||||
; unordered: zf,pf,cf <- 111; gt: 000; lt: 001; eq: 100
|
||||
; reversed & inverted: !(fl< y x) = !(fl> x y) iff zf = 1 & cf = 1
|
||||
[(fl<) bls]
|
||||
[(fp<) bls]
|
||||
; reversed & inverted: !(fl<= y x) = !(fl>= x y) iff cf = 1
|
||||
[(fl<=) bcs]
|
||||
[(fp<=) bcs]
|
||||
; inverted: !(fl= x y) iff zf = 0 or cf (or pf) = 1
|
||||
[(fl=) (or bne bcs)]))))))
|
||||
[(fp=) (or bne bcs)]))))))
|
||||
|
||||
(define asm-data-label
|
||||
(lambda (code* l offset func code-size)
|
||||
|
@ -2403,14 +2553,14 @@
|
|||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-double ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-double ,%sp ,%zero (immediate ,offset)))))]
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-double ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-double ,%sp ,%zero (immediate ,offset)))))]
|
||||
[load-single-stack
|
||||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-double->single ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-single ,%sp ,%zero (immediate ,offset)))))]
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-double->single ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-single ,%sp ,%zero (immediate ,offset)))))]
|
||||
[load-stack
|
||||
(lambda (offset)
|
||||
(lambda (rhs) ; requires rhs
|
||||
|
@ -2703,14 +2853,14 @@
|
|||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(define load-single-stack
|
||||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-single->double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-single->double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(define load-stack
|
||||
(lambda (type offset)
|
||||
(lambda (lvalue) ; requires lvalue
|
||||
|
|
358
s/x86_64.ss
358
s/x86_64.ss
|
@ -17,66 +17,68 @@
|
|||
(if-feature windows
|
||||
(define-registers
|
||||
(reserved
|
||||
[%tc %r14 #t 14]
|
||||
[%sfp %r13 #t 13]
|
||||
[%ap %rdi #t 7]
|
||||
[%tc %r14 #t 14 uptr]
|
||||
[%sfp %r13 #t 13 uptr]
|
||||
[%ap %rdi #t 7 uptr]
|
||||
#;[%esp]
|
||||
#;[%eap]
|
||||
#;[%trap])
|
||||
(allocable
|
||||
[%ac0 %rbp #t 5]
|
||||
[%xp %r12 #t 12]
|
||||
[%ts %rax %Cretval #f 0]
|
||||
[%td %rbx #t 3]
|
||||
[%ac1 %r10 %deact #f 10]
|
||||
[%yp %r11 #f 11]
|
||||
[%cp %r15 #t 15]
|
||||
[#;%ret %rsi #t 6]
|
||||
[ %rdx %Carg2 #f 2]
|
||||
[ %r8 %Carg3 #f 8]
|
||||
[ %r9 %Carg4 #f 9]
|
||||
[ %rcx %Carg1 #f 1]) ; last to avoid use as a Scheme argument
|
||||
[%ac0 %rbp #t 5 uptr]
|
||||
[%xp %r12 #t 12 uptr]
|
||||
[%ts %rax %Cretval #f 0 uptr]
|
||||
[%td %rbx #t 3 uptr]
|
||||
[%ac1 %r10 %deact #f 10 uptr]
|
||||
[%yp %r11 #f 11 uptr]
|
||||
[%cp %r15 #t 15 uptr]
|
||||
[#;%ret %rsi #t 6 uptr]
|
||||
[ %rdx %Carg2 #f 2 uptr]
|
||||
[ %r8 %Carg3 #f 8 uptr]
|
||||
[ %r9 %Carg4 #f 9 uptr]
|
||||
[ %rcx %Carg1 #f 1 uptr] ; last to avoid use as a Scheme argument
|
||||
[%fp1 %Cfparg3 #f 2 fp]
|
||||
[%fp2 %Cfparg4 #f 3 fp])
|
||||
(machine-dependent
|
||||
[%Cfparg1 %Cfpretval #f 0]
|
||||
[%Cfparg2 #f 1]
|
||||
[%Cfparg3 #f 2]
|
||||
[%Cfparg4 #f 3]
|
||||
[%flreg1 #f 4] ; xmm 0-5 are caller-save
|
||||
[%flreg2 #f 5] ; xmm 6-15 are callee-save
|
||||
[%sp #t 4]))
|
||||
[%Cfparg1 %Cfpretval #f 0 fp]
|
||||
[%Cfparg2 #f 1 fp]
|
||||
[%fptmp1 #f 4 fp] ; xmm 0-5 are caller-save
|
||||
[%fptmp2 #f 5 fp] ; xmm 6-15 are callee-save
|
||||
[%sp #t 4 fp])
|
||||
(reify-support %ts))
|
||||
(define-registers
|
||||
(reserved
|
||||
[%tc %r14 #t 14]
|
||||
[%sfp %r13 #t 13]
|
||||
[%ap %r9 %Carg6 #f 9]
|
||||
[%tc %r14 #t 14 uptr]
|
||||
[%sfp %r13 #t 13 uptr]
|
||||
[%ap %r9 %Carg6 #f 9 uptr]
|
||||
#;[%esp]
|
||||
#;[%eap]
|
||||
#;[%trap])
|
||||
(allocable
|
||||
[%ac0 %rbp #t 5]
|
||||
[%xp %r12 #t 12]
|
||||
[%ts %rax %Cretval #f 0]
|
||||
[%td %rbx #t 3]
|
||||
[%ac1 %r10 %deact #f 10]
|
||||
[%yp %r11 #f 11]
|
||||
[%cp %r15 #t 15]
|
||||
[#;%ret %r8 %Carg5 #f 8]
|
||||
[ %rdi %Carg1 #f 7]
|
||||
[ %rsi %Carg2 #f 6]
|
||||
[ %rdx %Carg3 #f 2]
|
||||
[ %rcx %Carg4 #f 1])
|
||||
[%ac0 %rbp #t 5 uptr]
|
||||
[%xp %r12 #t 12 uptr]
|
||||
[%ts %rax %Cretval #f 0 uptr]
|
||||
[%td %rbx #t 3 uptr]
|
||||
[%ac1 %r10 %deact #f 10 uptr]
|
||||
[%yp %r11 #f 11 uptr]
|
||||
[%cp %r15 #t 15 uptr]
|
||||
[#;%ret %r8 %Carg5 #f 8 uptr]
|
||||
[ %rdi %Carg1 #f 7 uptr]
|
||||
[ %rsi %Carg2 #f 6 uptr]
|
||||
[ %rdx %Carg3 #f 2 uptr]
|
||||
[ %rcx %Carg4 #f 1 uptr]
|
||||
[%fp1 %Cfparg3 #f 2 fp]
|
||||
[%fp2 %Cfparg4 #f 3 fp])
|
||||
(machine-dependent
|
||||
[%Cfparg1 %Cfpretval #f 0]
|
||||
[%Cfparg2 #f 1]
|
||||
[%Cfparg3 #f 2]
|
||||
[%Cfparg4 #f 3]
|
||||
[%Cfparg5 #f 4]
|
||||
[%Cfparg6 #f 5]
|
||||
[%Cfparg7 #f 6]
|
||||
[%Cfparg8 #f 7]
|
||||
[%flreg1 #f 8]
|
||||
[%flreg2 #f 9]
|
||||
[%sp #t 4])))
|
||||
[%Cfparg1 %Cfpretval #f 0 fp]
|
||||
[%Cfparg2 #f 1 fp]
|
||||
[%Cfparg5 #f 4 fp]
|
||||
[%Cfparg6 #f 5 fp]
|
||||
[%Cfparg7 #f 6 fp]
|
||||
[%Cfparg8 #f 7 fp]
|
||||
[%fptmp1 #f 8 fp]
|
||||
[%fptmp2 #f 9 fp]
|
||||
[%sp #t 4 uptr])
|
||||
(reify-support %ts)))
|
||||
|
||||
;;; SECTION 2: instructions
|
||||
(module (md-handle-jump) ; also sets primitive handlers
|
||||
|
@ -100,6 +102,18 @@
|
|||
(lambda (x)
|
||||
(or (lmem? x) (literal@? x))))
|
||||
|
||||
(define fpmem?
|
||||
(lambda (x)
|
||||
(nanopass-case (L15c Triv) x
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm ,type) (eq? type 'fp)]
|
||||
[else #f])))
|
||||
|
||||
(define-syntax mem-of-type?
|
||||
(lambda (stx)
|
||||
(syntax-case stx (mem fpmem)
|
||||
[(_ mem e) #'(lmem? e)]
|
||||
[(_ fpmem e) #'(fpmem? e)])))
|
||||
|
||||
(define real-imm32?
|
||||
(lambda (x)
|
||||
(nanopass-case (L15c Triv) x
|
||||
|
@ -127,24 +141,24 @@
|
|||
(define mref->mref
|
||||
(lambda (a k)
|
||||
(define return
|
||||
(lambda (x0 x1 imm)
|
||||
(k (with-output-language (L15d Triv) `(mref ,x0 ,x1 ,imm)))))
|
||||
(lambda (x0 x1 imm type)
|
||||
(k (with-output-language (L15d Triv) `(mref ,x0 ,x1 ,imm ,type)))))
|
||||
(nanopass-case (L15c Triv) a
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm)
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm ,type)
|
||||
(lvalue->ur lvalue0
|
||||
(lambda (x0)
|
||||
(lvalue->ur lvalue1
|
||||
(lambda (x1)
|
||||
(if (signed-32? imm)
|
||||
(return x0 x1 imm)
|
||||
(return x0 x1 imm type)
|
||||
(let ([u (make-tmp 'u)])
|
||||
(seq
|
||||
(build-set! ,u (immediate ,imm))
|
||||
(if (eq? x1 %zero)
|
||||
(return x0 u 0)
|
||||
(return x0 u 0 type)
|
||||
(seq
|
||||
(build-set! ,u (asm ,null-info ,asm-add ,u ,x1))
|
||||
(return x0 u 0))))))))))])))
|
||||
(return x0 u 0 type))))))))))])))
|
||||
|
||||
(define mem->mem
|
||||
(lambda (a k)
|
||||
|
@ -153,20 +167,27 @@
|
|||
(let ([u (make-tmp 'u)])
|
||||
(seq
|
||||
(build-set! ,u ,(literal@->literal a))
|
||||
(k (with-output-language (L15d Lvalue) `(mref ,u ,%zero 0)))))]
|
||||
(k (with-output-language (L15d Lvalue) `(mref ,u ,%zero 0 ptr)))))]
|
||||
[else (mref->mref a k)])))
|
||||
|
||||
(define literal->literal
|
||||
(lambda (a)
|
||||
(nanopass-case (L15c Triv) a
|
||||
[(literal ,info) (with-output-language (L15d Triv) `(literal ,info))])))
|
||||
|
||||
(define-syntax coercible?
|
||||
(syntax-rules ()
|
||||
[(_ ?a ?aty*)
|
||||
(let ([a ?a] [aty* ?aty*])
|
||||
(or (memq 'ur aty*)
|
||||
(or (and (memq 'ur aty*) (not (or (fpmem? a) (fpur? a))))
|
||||
(and (memq 'fpur aty*) (or (fpmem? a) (fpur? a)))
|
||||
(or (and (memq 'imm32 aty*) (imm32? a))
|
||||
(and (memq 'imm aty*) (imm? a))
|
||||
(and (memq 'zero aty*) (imm0? a))
|
||||
(and (memq 'real-imm32 aty*) (real-imm32? a))
|
||||
(and (memq 'negatable-real-imm32 aty*) (negatable-real-imm32? a))
|
||||
(and (memq 'mem aty*) (mem? a)))))]))
|
||||
(and (memq 'mem aty*) (mem? a))
|
||||
(and (memq 'fpmem aty*) (fpmem? a)))))]))
|
||||
|
||||
(define-syntax coerce-opnd ; passes k something compatible with aty*
|
||||
(syntax-rules ()
|
||||
|
@ -174,6 +195,7 @@
|
|||
(let ([a ?a] [aty* ?aty*] [k ?k])
|
||||
(cond
|
||||
[(and (memq 'mem aty*) (mem? a)) (mem->mem a k)]
|
||||
[(and (memq 'fpmem aty*) (fpmem? a)) (mem->mem a k)]
|
||||
[(and (memq 'imm32 aty*) (imm32? a)) (k (imm->imm a))]
|
||||
[(and (memq 'imm aty*) (imm? a)) (k (imm->imm a))]
|
||||
[(and (memq 'zero aty*) (imm0? a)) (k (imm->imm a))]
|
||||
|
@ -195,6 +217,18 @@
|
|||
(build-set! ,u ,a)
|
||||
(k u)))))]
|
||||
[else (sorry! 'coerce-opnd "unexpected operand ~s" a)])]
|
||||
[(memq 'fpur aty*)
|
||||
(cond
|
||||
[(fpur? a) (k a)]
|
||||
[(fpmem? a)
|
||||
(mem->mem a
|
||||
(lambda (a)
|
||||
(let ([u (make-tmp 'u 'fp)])
|
||||
(seq
|
||||
(build-set! ,u ,a)
|
||||
(k u)))))]
|
||||
[else
|
||||
(sorry! 'coerce-opnd "unexpected operand ~s" a)])]
|
||||
[else (sorry! 'coerce-opnd "cannot coerce ~s to ~s" a aty*)]))]))
|
||||
|
||||
(define set-ur=mref
|
||||
|
@ -254,7 +288,7 @@
|
|||
[(ur? c) (#,k c b)]
|
||||
[(mref? c)
|
||||
(nanopass-case (L15c Triv) c
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm)
|
||||
[(mref ,lvalue0 ,lvalue1 ,imm ,type)
|
||||
; TODO: does this use too many registers? (no longer special casing fv x0, x1 case)
|
||||
(lvalue->ur lvalue0
|
||||
(lambda (x0)
|
||||
|
@ -263,23 +297,30 @@
|
|||
(let ([u1 (make-tmp 'u)])
|
||||
(if (signed-32? imm)
|
||||
(seq
|
||||
(build-set! ,u1 (mref ,x0 ,x1 ,imm))
|
||||
(build-set! ,u1 (mref ,x0 ,x1 ,imm ,type))
|
||||
(#,k u1 b)
|
||||
(build-set! (mref ,x0 ,x1 ,imm) ,u1))
|
||||
(build-set! (mref ,x0 ,x1 ,imm ,type) ,u1))
|
||||
(let ([u2 (make-tmp 'u)])
|
||||
(seq
|
||||
(build-set! ,u2 ,imm)
|
||||
(build-set! ,x1 (asm ,null-info ,asm-add ,x1 ,u2))
|
||||
(build-set! ,u1 (mref ,x0 ,x1 0))
|
||||
(build-set! ,u1 (mref ,x0 ,x1 0 ,type))
|
||||
(#,k u1 b)
|
||||
(build-set! (mref ,x0 ,x1 0) ,u1)))))))))])]
|
||||
(build-set! (mref ,x0 ,x1 0 ,type) ,u1)))))))))])]
|
||||
; can't be literal@ since literals can't be lvalues
|
||||
[else (sorry! '#,(datum->syntax #'* who) "unexpected operand ~s" c)])))
|
||||
(next c a b)))))
|
||||
|
||||
(define mem-type?
|
||||
(lambda (t)
|
||||
(syntax-case t (mem fpmem)
|
||||
[mem #t]
|
||||
[fpmem #t]
|
||||
[else #f])))
|
||||
|
||||
(define make-value-clause
|
||||
(lambda (fmt)
|
||||
(syntax-case fmt (mem ur xp)
|
||||
(syntax-case fmt (mem fpmem ur fpur xp)
|
||||
[(op (c mem) (a ?c) (b bty* ...))
|
||||
(bound-identifier=? #'?c #'c)
|
||||
(acsame-mem #'c #'a #'b #'(bty* ...) #'(lambda (c b) (rhs c c b)))]
|
||||
|
@ -292,9 +333,10 @@
|
|||
[(op (c ur) (a aty* ...) (b ?c))
|
||||
(bound-identifier=? #'?c #'c)
|
||||
(acsame-ur #'c #'b #'a #'(aty* ...) #'(lambda (c a) (rhs c a c)))]
|
||||
[(op (c mem) (a aty ...) (b bty ...))
|
||||
[(op (c xmem) (a aty ...) (b bty ...))
|
||||
(mem-type? #'xmem)
|
||||
#`(lambda (c a b)
|
||||
(if (and (lmem? c) (coercible? a '(aty ...)) (coercible? b '(bty ...)))
|
||||
(if (and (mem-of-type? xmem c) (coercible? a '(aty ...)) (coercible? b '(bty ...)))
|
||||
(coerce-opnd b '(bty ...)
|
||||
(lambda (b)
|
||||
(coerce-opnd a '(aty ...)
|
||||
|
@ -317,6 +359,22 @@
|
|||
(lambda (c)
|
||||
(build-set! ,c ,u))))))))))
|
||||
(next c a b)))]
|
||||
[(op (c fpur) (a aty ...) (b bty ...))
|
||||
#`(lambda (c a b)
|
||||
(if (and (coercible? a '(aty ...)) (coercible? b '(bty ...)))
|
||||
(coerce-opnd b '(bty ...)
|
||||
(lambda (b)
|
||||
(coerce-opnd a '(aty ...)
|
||||
(lambda (a)
|
||||
(if (fpur? c)
|
||||
(rhs c a b)
|
||||
(let ([u (make-tmp 'u 'fp)])
|
||||
(seq
|
||||
(rhs u a b)
|
||||
(mref->mref c
|
||||
(lambda (c)
|
||||
(build-set! ,c ,u))))))))))
|
||||
(next c a b)))]
|
||||
; four-operand case below can require four unspillables
|
||||
[(op (c ur) (a ur) (b ur) (d dty ...))
|
||||
(not (memq 'mem (datum (dty ...))))
|
||||
|
@ -359,9 +417,10 @@
|
|||
(rhs u u)
|
||||
(build-set! ,c ,u))))))
|
||||
(next c a)))]
|
||||
[(op (c mem) (a aty ...))
|
||||
[(op (c xmem) (a aty ...))
|
||||
(mem-type? #'xmem)
|
||||
#`(lambda (c a)
|
||||
(if (and (lmem? c) (coercible? a '(aty ...)))
|
||||
(if (and (mem-of-type? xmem c) (coercible? a '(aty ...)))
|
||||
(coerce-opnd a '(aty ...)
|
||||
(lambda (a)
|
||||
(mem->mem c
|
||||
|
@ -382,6 +441,20 @@
|
|||
(rhs u a)
|
||||
(build-set! ,c ,u))))))))
|
||||
(next c a)))]
|
||||
[(op (c fpur) (a aty ...))
|
||||
#`(lambda (c a)
|
||||
(if (coercible? a '(aty ...))
|
||||
(coerce-opnd a '(aty ...)
|
||||
(lambda (a)
|
||||
(if (fpur? c)
|
||||
(rhs c a)
|
||||
(mem->mem c
|
||||
(lambda (c)
|
||||
(let ([u (make-tmp 'u 'fp)])
|
||||
(seq
|
||||
(rhs u a)
|
||||
(build-set! ,c ,u))))))))
|
||||
(next c a)))]
|
||||
[(op (c ur))
|
||||
#`(lambda (c)
|
||||
(if (ur? c)
|
||||
|
@ -392,9 +465,10 @@
|
|||
(seq
|
||||
(rhs u)
|
||||
(build-set! ,c ,u)))))))]
|
||||
[(op (c mem))
|
||||
[(op (c xmem))
|
||||
(mem-type? #'xmem)
|
||||
#`(lambda (c)
|
||||
(if (lmem? c)
|
||||
(if (mem-of-type? xmem c)
|
||||
(mem->mem c
|
||||
(lambda (c)
|
||||
(rhs c)))
|
||||
|
@ -813,14 +887,29 @@
|
|||
`(set! ,(make-live-info) ,z
|
||||
(asm ,info ,(asm-get-double (info-loadfl-flreg info))))])
|
||||
|
||||
(define-instruction effect (flt)
|
||||
[(op (x mem ur) (y ur)) `(asm ,info ,asm-flt ,x ,y)])
|
||||
(define-instruction value (fpt)
|
||||
[(op (x fpur) (y ur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpt ,y))])
|
||||
|
||||
(define-instruction effect (fl+ fl- fl/ fl*)
|
||||
[(op (x ur) (y ur) (z ur)) `(asm ,info ,(asm-flop-2 op) ,x ,y ,z)])
|
||||
(define-instruction value (fpmove)
|
||||
[(op (x fpmem) (y fpur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpmove ,y))]
|
||||
[(op (x fpur) (y fpmem fpur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpmove ,y))])
|
||||
|
||||
(define-instruction effect (flsqrt)
|
||||
[(op (x ur) (y ur)) `(asm ,info ,asm-flsqrt ,x ,y)])
|
||||
(define-instruction value (fpcastto)
|
||||
[(op (x mem) (y fpur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpmove ,y))]
|
||||
[(op (x ur) (y fpmem)) `(set! ,(make-live-info) ,x (asm ,info ,asm-move ,y))]
|
||||
[(op (x ur) (y fpur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpcast ,y))])
|
||||
|
||||
(define-instruction value (fpcastfrom)
|
||||
[(op (x fpmem) (y ur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-move ,y))]
|
||||
[(op (x fpur) (y mem)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpmove ,y))]
|
||||
[(op (x fpur) (y ur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpcast ,y))])
|
||||
|
||||
(define-instruction value (fp+ fp- fp* fp/)
|
||||
[(op (x fpur) (y fpmem fpur) (z fpmem fpur))
|
||||
`(set! ,(make-live-info) ,x (asm ,info ,(asm-fpop-2 op) ,y ,z))])
|
||||
|
||||
(define-instruction value (fpsqrt)
|
||||
[(op (x fpur) (y fpmem fpur)) `(set! ,(make-live-info) ,x (asm ,info ,asm-fpsqrt ,y))])
|
||||
|
||||
(define-instruction effect inc-cc-counter
|
||||
[(op (x ur) (y imm32 ur) (z imm32 ur)) `(asm ,info ,asm-inc-cc-counter ,x ,y ,z)])
|
||||
|
@ -878,10 +967,13 @@
|
|||
(define-instruction value pop
|
||||
[(op (z ur)) `(set! ,(make-live-info) ,z (asm ,info ,asm-pop))])
|
||||
|
||||
(define-instruction pred (fl= fl< fl<=)
|
||||
[(op (x ur) (y ur))
|
||||
(define-instruction pred (fp= fp< fp<=)
|
||||
[(op (x fpmem) (y fpur))
|
||||
(let ([info (make-info-condition-code op #t #f)]) ; NB: reversed? flag is assumed to be #t
|
||||
(values '() `(asm ,info ,(asm-fl-relop info) ,x ,y)))])
|
||||
(values '() `(asm ,info ,(asm-fp-relop info) ,x ,y)))]
|
||||
[(op (x fpur) (y fpur))
|
||||
(let ([info (make-info-condition-code op #t #f)]) ; NB: reversed? flag is assumed to be #t
|
||||
(values '() `(asm ,info ,(asm-fp-relop info) ,x ,y)))])
|
||||
|
||||
(define-instruction pred (eq? u< < > <= >=)
|
||||
; the idea (following from the intel x86/x86_64 documentation)
|
||||
|
@ -942,7 +1034,7 @@
|
|||
`(set! ,(make-live-info) ,uts (immediate 1))
|
||||
`(set! ,(make-live-info) ,uts
|
||||
(asm ,info ,asm-exchange ,uts
|
||||
(mref ,x ,y ,imm)))))])
|
||||
(mref ,x ,y ,imm uptr)))))])
|
||||
`(asm ,info-cc-eq ,asm-eq ,uts (immediate 0))))]))
|
||||
|
||||
(define-instruction effect (locked-incr!)
|
||||
|
@ -1018,13 +1110,14 @@
|
|||
asm-move asm-move/extend asm-load asm-store asm-swap asm-library-call asm-library-jump
|
||||
asm-mul asm-muli asm-addop asm-add asm-sub asm-negate asm-sub-negate
|
||||
asm-pop asm-shiftop asm-sll asm-logand asm-lognot
|
||||
asm-logtest asm-fl-relop asm-relop asm-push asm-indirect-jump asm-literal-jump
|
||||
asm-logtest asm-fp-relop asm-relop asm-push asm-indirect-jump asm-literal-jump
|
||||
asm-direct-jump asm-return-address asm-jump asm-conditional-jump asm-data-label
|
||||
asm-rp-header asm-rp-compact-header
|
||||
asm-lea1 asm-lea2 asm-indirect-call asm-condition-code
|
||||
asm-fl-cvt asm-fl-store asm-fl-load asm-flt asm-trunc asm-div asm-popcount
|
||||
asm-fl-cvt asm-fl-store asm-fl-load asm-fpt asm-trunc asm-div asm-popcount
|
||||
asm-exchange asm-pause asm-locked-incr asm-locked-decr asm-locked-cmpxchg
|
||||
asm-flop-2 asm-flsqrt asm-c-simple-call
|
||||
asm-fpsqrt asm-fpop-2 asm-fpmove asm-fpcast
|
||||
asm-c-simple-call
|
||||
asm-save-flrv asm-restore-flrv asm-return asm-c-return asm-size
|
||||
asm-enter asm-foreign-call asm-foreign-callable
|
||||
asm-inc-profile-counter
|
||||
|
@ -1040,6 +1133,9 @@
|
|||
[(x) (record-case x [(reg) r #t] [else #f])]
|
||||
[(x reg) (record-case x [(reg) r (eq? r reg)] [else #f])]))
|
||||
|
||||
(define ax-fp-register?
|
||||
(lambda (x) (record-case x [(reg) r (eq? 'fp (reg-type r))] [else #f])))
|
||||
|
||||
(define ax-ea-reg-code
|
||||
(lambda (ea)
|
||||
(record-case ea
|
||||
|
@ -1223,7 +1319,7 @@
|
|||
(define sse-op2
|
||||
(lambda (op prefix-code dstreg-op-code srcreg-op-code w source dest code*)
|
||||
(cond
|
||||
[(ax-register? source)
|
||||
[(ax-fp-register? source)
|
||||
(emit-code (op source dest code*)
|
||||
(build byte prefix-code)
|
||||
(ax-ea-rex w dest source #f)
|
||||
|
@ -1232,7 +1328,7 @@
|
|||
(ax-ea-modrm-reg dest source)
|
||||
(ax-ea-sib dest)
|
||||
(ax-ea-addr-disp dest))]
|
||||
[(ax-register? dest)
|
||||
[(ax-fp-register? dest)
|
||||
(emit-code (op source dest code*)
|
||||
(build byte prefix-code)
|
||||
(ax-ea-rex w source dest #f)
|
||||
|
@ -1943,34 +2039,48 @@
|
|||
(lambda (code* dst)
|
||||
(emit sse.movd (cons 'reg flreg) (cons 'reg dst) code*))))
|
||||
|
||||
(define asm-flt
|
||||
(lambda (code* src flonumreg)
|
||||
(Trivit (src)
|
||||
(let ([dest `(disp ,(constant flonum-data-disp) ,flonumreg)]
|
||||
[flreg (cons 'reg %flreg1)])
|
||||
(emit sse.cvtsi2sd src flreg
|
||||
(emit sse.movsd flreg dest code*))))))
|
||||
(define asm-fpt
|
||||
(lambda (code* dest src)
|
||||
(Trivit (dest src)
|
||||
(emit sse.cvtsi2sd src dest code*))))
|
||||
|
||||
(define asm-flop-2
|
||||
(define asm-fpop-2
|
||||
(lambda (op)
|
||||
(lambda (code* src1 src2 dest)
|
||||
(let ([src1 `(disp ,(constant flonum-data-disp) ,src1)]
|
||||
[src2 `(disp ,(constant flonum-data-disp) ,src2)]
|
||||
[dest `(disp ,(constant flonum-data-disp) ,dest)])
|
||||
(let ([code* (emit sse.movsd (cons 'reg %flreg1) dest code*)])
|
||||
(let ([code* (case op
|
||||
[(fl+) (emit sse.addsd src2 (cons 'reg %flreg1) code*)]
|
||||
[(fl-) (emit sse.subsd src2 (cons 'reg %flreg1) code*)]
|
||||
[(fl*) (emit sse.mulsd src2 (cons 'reg %flreg1) code*)]
|
||||
[(fl/) (emit sse.divsd src2 (cons 'reg %flreg1) code*)])])
|
||||
(emit sse.movsd src1 (cons 'reg %flreg1) code*)))))))
|
||||
(lambda (code* dest-reg src1 src2)
|
||||
(define (emit-it src dest code*)
|
||||
(case op
|
||||
[(fp+) (emit sse.addsd src dest code*)]
|
||||
[(fp-) (emit sse.subsd src dest code*)]
|
||||
[(fp*) (emit sse.mulsd src dest code*)]
|
||||
[(fp/) (emit sse.divsd src dest code*)]))
|
||||
(cond
|
||||
[(eq? dest-reg src1)
|
||||
(Trivit (dest-reg src2)
|
||||
(emit-it src2 dest-reg code*))]
|
||||
[(and (eq? dest-reg src2)
|
||||
(memq op '(fp+ fp*)))
|
||||
(Trivit (dest-reg src1)
|
||||
(emit-it src1 dest-reg code*))]
|
||||
[else
|
||||
(Trivit (dest-reg src1 src2)
|
||||
(emit sse.movsd src2 (cons 'reg %fptmp1)
|
||||
(emit sse.movsd src1 dest-reg
|
||||
(emit-it (cons 'reg %fptmp1) dest-reg code*))))]))))
|
||||
|
||||
(define asm-flsqrt
|
||||
(lambda (code* src dest)
|
||||
(let ([src `(disp ,(constant flonum-data-disp) ,src)]
|
||||
[dest `(disp ,(constant flonum-data-disp) ,dest)])
|
||||
(emit sse.sqrtsd src (cons 'reg %flreg1)
|
||||
(emit sse.movsd (cons 'reg %flreg1) dest code*)))))
|
||||
(define asm-fpsqrt
|
||||
(lambda (code* dest-reg src)
|
||||
(Trivit (dest-reg src)
|
||||
(emit sse.sqrtsd src dest-reg code*))))
|
||||
|
||||
(define asm-fpmove
|
||||
(lambda (code* dest src)
|
||||
(Trivit (dest src)
|
||||
(emit sse.movsd src dest code*))))
|
||||
|
||||
(define asm-fpcast
|
||||
(lambda (code* dest src)
|
||||
(Trivit (dest src)
|
||||
(emit sse.movd src dest code*))))
|
||||
|
||||
(define asm-trunc
|
||||
(lambda (code* dest flonumreg)
|
||||
|
@ -2305,14 +2415,12 @@
|
|||
(let-values ([(l1 l2) (if i? (values l2 l1) (values l1 l2))])
|
||||
(asm-conditional-jump info l2 l1 offset)))))))
|
||||
|
||||
(define asm-fl-relop
|
||||
(define asm-fp-relop
|
||||
(lambda (info)
|
||||
(lambda (l1 l2 offset x y)
|
||||
(values
|
||||
(let ([x `(disp ,(constant flonum-data-disp) ,x)]
|
||||
[y `(disp ,(constant flonum-data-disp) ,y)])
|
||||
(emit sse.movsd y (cons 'reg %flreg1)
|
||||
(emit sse.ucomisd x (cons 'reg %flreg1) '())))
|
||||
(Trivit (x y)
|
||||
(emit sse.ucomisd x y '()))
|
||||
(asm-conditional-jump info l1 l2 offset)))))
|
||||
|
||||
(define asm-relop
|
||||
|
@ -2527,11 +2635,11 @@
|
|||
[(carry) (i? bcc bcs)]
|
||||
; unordered: zf,pf,cf <- 111; gt: 000; lt: 001; eq: 100
|
||||
; reversed & inverted: !(fl< y x) = !(fl> x y) iff zf = 1 & cf = 1
|
||||
[(fl<) bls]
|
||||
[(fp<) bls]
|
||||
; reversed & inverted: !(fl<= y x) = !(fl>= x y) iff cf = 1
|
||||
[(fl<=) bcs]
|
||||
[(fp<=) bcs]
|
||||
; inverted: !(fl= x y) iff zf = 0 or cf (or pf) = 1
|
||||
[(fl=) (or bne bcs)]))))))
|
||||
[(fp=) (or bne bcs)]))))))
|
||||
|
||||
(define asm-data-label
|
||||
(lambda (code* l offset func code-size)
|
||||
|
@ -2754,14 +2862,14 @@
|
|||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-double ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-double ,%sp ,%zero (immediate ,offset)))))]
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-double ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-double ,%sp ,%zero (immediate ,offset)))))]
|
||||
[load-single-stack
|
||||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-double->single ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-single ,%sp ,%zero (immediate ,offset)))))]
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-double->single ,x ,%zero ,(%constant flonum-data-disp))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-single ,%sp ,%zero (immediate ,offset)))))]
|
||||
[load-int-stack
|
||||
(lambda (offset)
|
||||
(lambda (rhs) ; requires rhs
|
||||
|
@ -3215,14 +3323,14 @@
|
|||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(define load-single-stack
|
||||
(lambda (offset)
|
||||
(lambda (x) ; requires var
|
||||
(%seq
|
||||
(inline ,(make-info-loadfl %flreg1) ,%load-single->double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %flreg1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%load-single->double ,%sp ,%zero (immediate ,offset))
|
||||
(inline ,(make-info-loadfl %fptmp1) ,%store-double ,x ,%zero ,(%constant flonum-data-disp))))))
|
||||
(define load-int-stack
|
||||
(lambda (type offset)
|
||||
(lambda (lvalue)
|
||||
|
|
Loading…
Reference in New Issue
Block a user