From d4559cfd4c1ce9f7ae2dd96e26fdcf4a2d0938db Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Fri, 9 Mar 2007 19:28:38 -0500 Subject: [PATCH] cleanup of repository content. --- .bzrignore | 1 + benchmarks/prefix/prefix-ikarus.scm | 2 +- benchmarks/results.Larceny-r6rs | 20 + benchmarks/sys/larceny/compiler-prefix.scm | 1 - benchmarks/sys/larceny/compiler-suffix.scm | 1 - benchmarks/sys/larceny/compiler.scm | 12258 ------------------- benchmarks/sys/petite-chez/tak-prefix.scm | 1 - benchmarks/sys/petite-chez/tak-suffix.scm | 1 - benchmarks/sys/petite-chez/tak.scm | 513 - src/altmakefile.ss | 2 +- src/ikarus.boot | Bin 2857178 -> 2855617 bytes src/libaltcogen.ss | 1 + src/pass-specify-rep.ss | 157 +- 13 files changed, 87 insertions(+), 12871 deletions(-) delete mode 100644 benchmarks/sys/larceny/compiler-prefix.scm delete mode 100644 benchmarks/sys/larceny/compiler-suffix.scm delete mode 100644 benchmarks/sys/larceny/compiler.scm delete mode 100644 benchmarks/sys/petite-chez/tak-prefix.scm delete mode 100644 benchmarks/sys/petite-chez/tak-suffix.scm delete mode 100644 benchmarks/sys/petite-chez/tak.scm diff --git a/.bzrignore b/.bzrignore index 81ffb6b..1fd9348 100644 --- a/.bzrignore +++ b/.bzrignore @@ -4,3 +4,4 @@ .gdb_history .vimview .DS_Store +benchmarks/sys/* diff --git a/benchmarks/prefix/prefix-ikarus.scm b/benchmarks/prefix/prefix-ikarus.scm index ead8ffe..f01225a 100644 --- a/benchmarks/prefix/prefix-ikarus.scm +++ b/benchmarks/prefix/prefix-ikarus.scm @@ -8,7 +8,7 @@ ; (printf "[~s] compiling \n" (depth)) ; (pretty-print x) ; (alt-compile x)))) -;(current-eval alt-compile) +(current-eval alt-compile) (define (run-bench name count ok? run) (let loop ((i 0) (result (list 'undefined))) diff --git a/benchmarks/results.Larceny-r6rs b/benchmarks/results.Larceny-r6rs index 531c576..3082115 100644 --- a/benchmarks/results.Larceny-r6rs +++ b/benchmarks/results.Larceny-r6rs @@ -5500,3 +5500,23 @@ Words allocated: 34340444 Words reclaimed: 0 Elapsed time...: 1262 ms (User: 1254 ms; System: 7 ms) Elapsed GC time: 55 ms (CPU: 61 in 131 collections.) + +**************************** +Benchmarking Larceny-r6rs on Fri Mar 9 14:03:45 EST 2007 under Darwin dhcp-cs-244-155.cs.indiana.edu 8.8.3 Darwin Kernel Version 8.8.3: Wed Oct 18 21:57:10 PDT 2006; root:xnu-792.15.4.obj~4/RELEASE_I386 i386 i386 + +Testing nucleic under Larceny-r6rs +Compiling... +Larceny v0.93 "Deviated Prevert" (Nov 10 2006 04:27:45, precise:BSD Unix:unified) + + +> +> +Running... +Larceny v0.93 "Deviated Prevert" (Nov 10 2006 04:27:45, precise:BSD Unix:unified) + + +> +Words allocated: 151779492 +Words reclaimed: 0 +Elapsed time...: 4582 ms (User: 3117 ms; System: 1461 ms) +Elapsed GC time: 255 ms (CPU: 259 in 579 collections.) diff --git a/benchmarks/sys/larceny/compiler-prefix.scm b/benchmarks/sys/larceny/compiler-prefix.scm deleted file mode 100644 index 7be0875..0000000 --- a/benchmarks/sys/larceny/compiler-prefix.scm +++ /dev/null @@ -1 +0,0 @@ -; compiler compiler diff --git a/benchmarks/sys/larceny/compiler-suffix.scm b/benchmarks/sys/larceny/compiler-suffix.scm deleted file mode 100644 index 7be0875..0000000 --- a/benchmarks/sys/larceny/compiler-suffix.scm +++ /dev/null @@ -1 +0,0 @@ -; compiler compiler diff --git a/benchmarks/sys/larceny/compiler.scm b/benchmarks/sys/larceny/compiler.scm deleted file mode 100644 index 79b01c9..0000000 --- a/benchmarks/sys/larceny/compiler.scm +++ /dev/null @@ -1,12258 +0,0 @@ -; compiler compiler -(define-syntax if-fixflo (syntax-rules () ((if-fixflo yes no) no))) -;------------------------------------------------------------------------------ -(error-handler - (lambda l - (display "bench DIED!") (newline) (exit 118))) - -(define (run-bench name count ok? run) - (let loop ((i 0) (result (list 'undefined))) - (if (< i count) - (loop (+ i 1) (run)) - result))) - -(define (run-benchmark name count ok? run-maker . args) - (newline) - (let* ((run (apply run-maker args)) - (result (time (run-bench name count ok? run)))) - (if (not (ok? result)) - (begin - (display "*** wrong result ***") - (newline) - (display "*** got: ") - (write result) - (newline)))) - (exit 0)) - -(define (fatal-error . args) - (apply error #f args)) - -(define (call-with-output-file/truncate filename proc) - (call-with-output-file filename proc)) - -; Bitwise operations on exact integers. -; From the draft reference implementation of R6RS generic arithmetic. - -(define (bitwise-or i j) - (if (and (exact? i) - (integer? i) - (exact? j) - (integer? j)) - (cond ((or (= i -1) (= j -1)) - -1) - ((= i 0) - j) - ((= j 0) - i) - (else - (let* ((i0 (if (odd? i) 1 0)) - (j0 (if (odd? j) 1 0)) - (i1 (- i i0)) - (j1 (- j j0)) - (i/2 (quotient i1 2)) - (j/2 (quotient j1 2)) - (hi (* 2 (bitwise-or i/2 j/2))) - (lo (if (= 0 (+ i0 j0)) 0 1))) - (+ hi lo)))) - (error "illegal argument to bitwise-or" i j))) - -(define (bitwise-and i j) - (if (and (exact? i) - (integer? i) - (exact? j) - (integer? j)) - (cond ((or (= i 0) (= j 0)) - 0) - ((= i -1) - j) - ((= j -1) - i) - (else - (let* ((i0 (if (odd? i) 1 0)) - (j0 (if (odd? j) 1 0)) - (i1 (- i i0)) - (j1 (- j j0)) - (i/2 (quotient i1 2)) - (j/2 (quotient j1 2)) - (hi (* 2 (bitwise-and i/2 j/2))) - (lo (* i0 j0))) - (+ hi lo)))) - (error "illegal argument to bitwise-and" i j))) - -(define (bitwise-not i) - (if (and (exact? i) - (integer? i)) - (cond ((= i -1) - 0) - ((= i 0) - -1) - (else - (let* ((i0 (if (odd? i) 1 0)) - (i1 (- i i0)) - (i/2 (quotient i1 2)) - (hi (* 2 (bitwise-not i/2))) - (lo (- 1 i0))) - (+ hi lo)))) - (error "illegal argument to bitwise-not" i j))) - - - -;------------------------------------------------------------------------------ - -; Macros... - -(if-fixflo - -(begin - -; Specialize fixnum and flonum arithmetic. - -(define-syntax FLOATvector-const - (syntax-rules () - ((FLOATvector-const x ...) '#(x ...)))) - -(define-syntax FLOATvector? - (syntax-rules () - ((FLOATvector? x) (vector? x)))) - -(define-syntax FLOATvector - (syntax-rules () - ((FLOATvector x ...) (vector x ...)))) - -(define-syntax FLOATmake-vector - (syntax-rules () - ((FLOATmake-vector n) (make-vector n 0.0)) - ((FLOATmake-vector n init) (make-vector n init)))) - -(define-syntax FLOATvector-ref - (syntax-rules () - ((FLOATvector-ref v i) (vector-ref v i)))) - -(define-syntax FLOATvector-set! - (syntax-rules () - ((FLOATvector-set! v i x) (vector-set! v i x)))) - -(define-syntax FLOATvector-length - (syntax-rules () - ((FLOATvector-length v) (vector-length v)))) - -(define-syntax nuc-const - (syntax-rules () - ((FLOATnuc-const x ...) '#(x ...)))) - -(define-syntax FLOAT+ - (syntax-rules () - ((FLOAT+ x ...) (fl+ x ...)))) - -(define-syntax FLOAT- - (syntax-rules () - ((FLOAT- x ...) (fl- x ...)))) - -(define-syntax FLOAT* - (syntax-rules () - ((FLOAT* x ...) (fl* x ...)))) - -(define-syntax FLOAT/ - (syntax-rules () - ((FLOAT/ x ...) (/ x ...)))) ; FIXME - -(define-syntax FLOAT= - (syntax-rules () - ((FLOAT= x y) (fl= x y)))) - -(define-syntax FLOAT< - (syntax-rules () - ((FLOAT< x y) (fl< x y)))) - -(define-syntax FLOAT<= - (syntax-rules () - ((FLOAT<= x y) (fl<= x y)))) - -(define-syntax FLOAT> - (syntax-rules () - ((FLOAT> x y) (fl> x y)))) - -(define-syntax FLOAT>= - (syntax-rules () - ((FLOAT>= x y) (fl>= x y)))) - -(define-syntax FLOATnegative? - (syntax-rules () - ((FLOATnegative? x) (fl< x 0.0)))) - -(define-syntax FLOATpositive? - (syntax-rules () - ((FLOATpositive? x) (fl< 0.0 x)))) - -(define-syntax FLOATzero? - (syntax-rules () - ((FLOATzero? x) (fl= 0.0 x)))) - -(define-syntax FLOATabs - (syntax-rules () - ((FLOATabs x) (abs x)))) ; FIXME - -(define-syntax FLOATsin - (syntax-rules () - ((FLOATsin x) (sin x)))) ; FIXME - -(define-syntax FLOATcos - (syntax-rules () - ((FLOATcos x) (cos x)))) ; FIXME - -(define-syntax FLOATatan - (syntax-rules () - ((FLOATatan x) (atan x)))) ; FIXME - -(define-syntax FLOATsqrt - (syntax-rules () - ((FLOATsqrt x) (sqrt x)))) ; FIXME - -(define-syntax FLOATmin - (syntax-rules () - ((FLOATmin x y) (min x y)))) ; FIXME - -(define-syntax FLOATmax - (syntax-rules () - ((FLOATmax x y) (max x y)))) ; FIXME - -(define-syntax FLOATround - (syntax-rules () - ((FLOATround x) (round x)))) ; FIXME - -(define-syntax FLOATinexact->exact - (syntax-rules () - ((FLOATinexact->exact x) (inexact->exact x)))) - -(define (GENERIC+ x y) (+ x y)) -(define (GENERIC- x y) (- x y)) -(define (GENERIC* x y) (* x y)) -(define (GENERIC/ x y) (/ x y)) -(define (GENERICquotient x y) (quotient x y)) -(define (GENERICremainder x y) (remainder x y)) -(define (GENERICmodulo x y) (modulo x y)) -(define (GENERIC= x y) (= x y)) -(define (GENERIC< x y) (< x y)) -(define (GENERIC<= x y) (<= x y)) -(define (GENERIC> x y) (> x y)) -(define (GENERIC>= x y) (>= x y)) -(define (GENERICexpt x y) (expt x y)) - -(define-syntax + - (syntax-rules () - ((+ x ...) (fx+ x ...)))) - -(define-syntax - - (syntax-rules () - ((- x ...) (fx- x ...)))) - -(define-syntax * - (syntax-rules () - ((* x ...) (fx* x ...)))) - -;(define-syntax quotient -; (syntax-rules () -; ((quotient x ...) (quotient x ...)))) ; FIXME - -;(define-syntax modulo -; (syntax-rules () -; ((modulo x ...) (modulo x ...)))) ; FIXME - -;(define-syntax remainder -; (syntax-rules () -; ((remainder x ...) (remainder x ...)))) ; FIXME - -(define-syntax = - (syntax-rules () - ((= x y) (fx= x y)))) - -(define-syntax < - (syntax-rules () - ((< x y) (fx< x y)))) - -(define-syntax <= - (syntax-rules () - ((<= x y) (fx<= x y)))) - -(define-syntax > - (syntax-rules () - ((> x y) (fx> x y)))) - -(define-syntax >= - (syntax-rules () - ((>= x y) (fx>= x y)))) - -(define-syntax negative? - (syntax-rules () - ((negative? x) (fxnegative? x)))) - -(define-syntax positive? - (syntax-rules () - ((positive? x) (fxpositive? x)))) - -(define-syntax zero? - (syntax-rules () - ((zero? x) (fxzero? x)))) - -;(define-syntax odd? -; (syntax-rules () -; ((odd? x) (odd? x)))) ; FIXME - -;(define-syntax even? -; (syntax-rules () -; ((even? x) (even? x)))) ; FIXME - -(define-syntax bitwise-or - (syntax-rules () - ((bitwise-or x y) (fxlogior x y)))) - -(define-syntax bitwise-and - (syntax-rules () - ((bitwise-and x y) (fxlogand x y)))) - -(define-syntax bitwise-not - (syntax-rules () - ((bitwise-not x) (fxlognot x)))) -) - -(begin - -; Don't specialize fixnum and flonum arithmetic. - -(define-syntax FLOATvector-const - (syntax-rules () - ((FLOATvector-const x ...) '#(x ...)))) - -(define-syntax FLOATvector? - (syntax-rules () - ((FLOATvector? x) (vector? x)))) - -(define-syntax FLOATvector - (syntax-rules () - ((FLOATvector x ...) (vector x ...)))) - -(define-syntax FLOATmake-vector - (syntax-rules () - ((FLOATmake-vector n) (make-vector n 0.0)) - ((FLOATmake-vector n init) (make-vector n init)))) - -(define-syntax FLOATvector-ref - (syntax-rules () - ((FLOATvector-ref v i) (vector-ref v i)))) - -(define-syntax FLOATvector-set! - (syntax-rules () - ((FLOATvector-set! v i x) (vector-set! v i x)))) - -(define-syntax FLOATvector-length - (syntax-rules () - ((FLOATvector-length v) (vector-length v)))) - -(define-syntax nuc-const - (syntax-rules () - ((FLOATnuc-const x ...) '#(x ...)))) - -(define-syntax FLOAT+ - (syntax-rules () - ((FLOAT+ x ...) (+ x ...)))) - -(define-syntax FLOAT- - (syntax-rules () - ((FLOAT- x ...) (- x ...)))) - -(define-syntax FLOAT* - (syntax-rules () - ((FLOAT* x ...) (* x ...)))) - -(define-syntax FLOAT/ - (syntax-rules () - ((FLOAT/ x ...) (/ x ...)))) - -(define-syntax FLOAT= - (syntax-rules () - ((FLOAT= x y) (= x y)))) - -(define-syntax FLOAT< - (syntax-rules () - ((FLOAT< x y) (< x y)))) - -(define-syntax FLOAT<= - (syntax-rules () - ((FLOAT<= x y) (<= x y)))) - -(define-syntax FLOAT> - (syntax-rules () - ((FLOAT> x y) (> x y)))) - -(define-syntax FLOAT>= - (syntax-rules () - ((FLOAT>= x y) (>= x y)))) - -(define-syntax FLOATnegative? - (syntax-rules () - ((FLOATnegative? x) (negative? x)))) - -(define-syntax FLOATpositive? - (syntax-rules () - ((FLOATpositive? x) (positive? x)))) - -(define-syntax FLOATzero? - (syntax-rules () - ((FLOATzero? x) (zero? x)))) - -(define-syntax FLOATabs - (syntax-rules () - ((FLOATabs x) (abs x)))) - -(define-syntax FLOATsin - (syntax-rules () - ((FLOATsin x) (sin x)))) - -(define-syntax FLOATcos - (syntax-rules () - ((FLOATcos x) (cos x)))) - -(define-syntax FLOATatan - (syntax-rules () - ((FLOATatan x) (atan x)))) - -(define-syntax FLOATsqrt - (syntax-rules () - ((FLOATsqrt x) (sqrt x)))) - -(define-syntax FLOATmin - (syntax-rules () - ((FLOATmin x y) (min x y)))) - -(define-syntax FLOATmax - (syntax-rules () - ((FLOATmax x y) (max x y)))) - -(define-syntax FLOATround - (syntax-rules () - ((FLOATround x) (round x)))) - -(define-syntax FLOATinexact->exact - (syntax-rules () - ((FLOATinexact->exact x) (inexact->exact x)))) - -; Generic arithmetic. - -(define-syntax GENERIC+ - (syntax-rules () - ((GENERIC+ x ...) (+ x ...)))) - -(define-syntax GENERIC- - (syntax-rules () - ((GENERIC- x ...) (- x ...)))) - -(define-syntax GENERIC* - (syntax-rules () - ((GENERIC* x ...) (* x ...)))) - -(define-syntax GENERIC/ - (syntax-rules () - ((GENERIC/ x ...) (/ x ...)))) - -(define-syntax GENERICquotient - (syntax-rules () - ((GENERICquotient x y) (quotient x y)))) - -(define-syntax GENERICremainder - (syntax-rules () - ((GENERICremainder x y) (remainder x y)))) - -(define-syntax GENERICmodulo - (syntax-rules () - ((GENERICmodulo x y) (modulo x y)))) - -(define-syntax GENERIC= - (syntax-rules () - ((GENERIC= x y) (= x y)))) - -(define-syntax GENERIC< - (syntax-rules () - ((GENERIC< x y) (< x y)))) - -(define-syntax GENERIC<= - (syntax-rules () - ((GENERIC<= x y) (<= x y)))) - -(define-syntax GENERIC> - (syntax-rules () - ((GENERIC> x y) (> x y)))) - -(define-syntax GENERIC>= - (syntax-rules () - ((GENERIC>= x y) (>= x y)))) - -(define-syntax GENERICexpt - (syntax-rules () - ((GENERICexpt x y) (expt x y)))) -) -) - -;------------------------------------------------------------------------------ -; Gabriel benchmarks -(define boyer-iters 20) -(define browse-iters 600) -(define cpstak-iters 1000) -(define ctak-iters 100) -(define dderiv-iters 2000000) -(define deriv-iters 2000000) -(define destruc-iters 500) -(define diviter-iters 1000000) -(define divrec-iters 1000000) -(define puzzle-iters 100) -(define tak-iters 2000) -(define takl-iters 300) -(define trav1-iters 100) -(define trav2-iters 20) -(define triangl-iters 10) - -; Kernighan and Van Wyk benchmarks -(define ack-iters 1) -(define array1-iters 1) -(define cat-iters 1) -(define string-iters 1) -(define sum1-iters 1) -(define sumloop-iters 1) -(define tail-iters 1) -(define wc-iters 1) - -; C benchmarks -(define fft-iters 2000) -(define fib-iters 5) -(define fibfp-iters 2) -(define mbrot-iters 100) -(define nucleic-iters 5) -(define pnpoly-iters 100000) -(define sum-iters 10000) -(define sumfp-iters 5000) -(define tfib-iters 20) - -; Other benchmarks -(define conform-iters 40) -(define dynamic-iters 20) -(define earley-iters 200) -(define fibc-iters 500) -(define graphs-iters 300) -(define lattice-iters 1) -(define matrix-iters 400) -(define maze-iters 4000) -(define mazefun-iters 1000) -(define nqueens-iters 2000) -(define paraffins-iters 1000) -(define peval-iters 200) -(define pi-iters 2) -(define primes-iters 100000) -(define ray-iters 5) -(define scheme-iters 20000) -(define simplex-iters 100000) -(define slatex-iters 20) -(define perm9-iters 10) -(define nboyer-iters 100) -(define sboyer-iters 100) -(define gcbench-iters 1) -(define compiler-iters 300) - -; New benchmarks -(define parsing-iters 1000) -(define gcold-iters 10000) -;(define nbody-iters 1) ; nondeterministic (order of evaluation) - - -;(define integer->char ascii->char) -;(define char->integer char->ascii) - -(define open-input-file* open-input-file) -(define (pp-expression expr port) (write expr port) (newline port)) -(define (write-returning-len obj port) (write obj port) 1) -(define (display-returning-len obj port) (display obj port) 1) -(define (write-word w port) - (write-char (integer->char (quotient w 256)) port) - (write-char (integer->char (modulo w 256)) port)) -(define char-nul (integer->char 0)) -(define char-tab (integer->char 9)) -(define char-newline (integer->char 10)) -(define character-encoding char->integer) -(define max-character-encoding 255) -(define (fatal-err msg arg) (error msg arg)) -(define (scheme-global-var name) name) -(define (scheme-global-var-ref var) (scheme-global-eval var)) -(define (scheme-global-var-set! var val) - (scheme-global-eval (list 'set! var (list 'quote val)) fatal-err)) -(define (scheme-global-eval expr err) (eval expr)) -(define (pinpoint-error filename line char) #t) -(define file-path-sep #\:) -(define file-ext-sep #\.) -(define (path-absolute? x) - (and (> (string-length x) 0) - (let ((c (string-ref x 0))) (or (char=? c #\/) (char=? c #\~))))) -(define (file-path x) - (let loop1 ((i (string-length x))) - (if (and (> i 0) (not (char=? (string-ref x (- i 1)) file-path-sep))) - (loop1 (- i 1)) - (let ((result (make-string i))) - (let loop2 ((j (- i 1))) - (if (< j 0) - result - (begin - (string-set! result j (string-ref x j)) - (loop2 (- j 1))))))))) -(define (file-name x) - (let loop1 ((i (string-length x))) - (if (and (> i 0) (not (char=? (string-ref x (- i 1)) file-path-sep))) - (loop1 (- i 1)) - (let ((result (make-string (- (string-length x) i)))) - (let loop2 ((j (- (string-length x) 1))) - (if (< j i) - result - (begin - (string-set! result (- j i) (string-ref x j)) - (loop2 (- j 1))))))))) -(define (file-ext x) - (let loop1 ((i (string-length x))) - (if (or (= i 0) (char=? (string-ref x (- i 1)) file-path-sep)) - #f - (if (not (char=? (string-ref x (- i 1)) file-ext-sep)) - (loop1 (- i 1)) - (let ((result (make-string (- (string-length x) i)))) - (let loop2 ((j (- (string-length x) 1))) - (if (< j i) - result - (begin - (string-set! result (- j i) (string-ref x j)) - (loop2 (- j 1)))))))))) -(define (file-root x) - (let loop1 ((i (string-length x))) - (if (or (= i 0) (char=? (string-ref x (- i 1)) file-path-sep)) - x - (if (not (char=? (string-ref x (- i 1)) file-ext-sep)) - (loop1 (- i 1)) - (let ((result (make-string (- i 1)))) - (let loop2 ((j (- i 2))) - (if (< j 0) - result - (begin - (string-set! result j (string-ref x j)) - (loop2 (- j 1)))))))))) -(define (make-counter next limit limit-error) - (lambda () - (if (< next limit) - (let ((result next)) (set! next (+ next 1)) result) - (limit-error)))) -(define (pos-in-list x l) - (let loop ((l l) (i 0)) - (cond ((not (pair? l)) #f) - ((eq? (car l) x) i) - (else (loop (cdr l) (+ i 1)))))) -(define (string-pos-in-list x l) - (let loop ((l l) (i 0)) - (cond ((not (pair? l)) #f) - ((string=? (car l) x) i) - (else (loop (cdr l) (+ i 1)))))) -(define (nth-after l n) - (let loop ((l l) (n n)) (if (> n 0) (loop (cdr l) (- n 1)) l))) -(define (pair-up l1 l2) - (define (pair l1 l2) - (if (pair? l1) - (cons (cons (car l1) (car l2)) (pair (cdr l1) (cdr l2))) - '())) - (pair l1 l2)) -(define (my-last-pair l) - (let loop ((l l)) (if (pair? (cdr l)) (loop (cdr l)) l))) -(define (sort-list l vector l) - (let* ((n (length l)) (v (make-vector n))) - (let loop ((l l) (i 0)) - (if (pair? l) - (begin (vector-set! v i (car l)) (loop (cdr l) (+ i 1))) - v)))) -(define (vector->lst v) - (let loop ((l '()) (i (- (vector-length v) 1))) - (if (< i 0) l (loop (cons (vector-ref v i) l) (- i 1))))) -(define (lst->string l) - (let* ((n (length l)) (s (make-string n))) - (let loop ((l l) (i 0)) - (if (pair? l) - (begin (string-set! s i (car l)) (loop (cdr l) (+ i 1))) - s)))) -(define (string->lst s) - (let loop ((l '()) (i (- (string-length s) 1))) - (if (< i 0) l (loop (cons (string-ref s i) l) (- i 1))))) -(define (with-exception-handling proc) - (let ((old-exception-handler throw-to-exception-handler)) - (let ((val (call-with-current-continuation - (lambda (cont) - (set! throw-to-exception-handler cont) - (proc))))) - (set! throw-to-exception-handler old-exception-handler) - val))) -(define (throw-to-exception-handler val) - (fatal-err "Internal error, no exception handler at this point" val)) -(define (compiler-error msg . args) - (newline) - (display "*** ERROR -- ") - (display msg) - (for-each (lambda (x) (display " ") (write x)) args) - (newline) - (compiler-abort)) -(define (compiler-user-error loc msg . args) - (newline) - (display "*** ERROR -- In ") - (locat-show loc) - (newline) - (display "*** ") - (display msg) - (for-each (lambda (x) (display " ") (write x)) args) - (newline) - (compiler-abort)) -(define (compiler-internal-error msg . args) - (newline) - (display "*** ERROR -- Compiler internal error detected") - (newline) - (display "*** in procedure ") - (display msg) - (for-each (lambda (x) (display " ") (write x)) args) - (newline) - (compiler-abort)) -(define (compiler-limitation-error msg . args) - (newline) - (display "*** ERROR -- Compiler limit reached") - (newline) - (display "*** ") - (display msg) - (for-each (lambda (x) (display " ") (write x)) args) - (newline) - (compiler-abort)) -(define (compiler-abort) (throw-to-exception-handler #f)) -(define (make-gnode label edges) (vector label edges)) -(define (gnode-label x) (vector-ref x 0)) -(define (gnode-edges x) (vector-ref x 1)) -(define (transitive-closure graph) - (define changed? #f) - (define (closure edges) - (list->set - (set-union - edges - (apply set-union - (map (lambda (label) (gnode-edges (gnode-find label graph))) - (set->list edges)))))) - (let ((new-graph - (set-map (lambda (x) - (let ((new-edges (closure (gnode-edges x)))) - (if (not (set-equal? new-edges (gnode-edges x))) - (set! changed? #t)) - (make-gnode (gnode-label x) new-edges))) - graph))) - (if changed? (transitive-closure new-graph) new-graph))) -(define (gnode-find label graph) - (define (find label l) - (cond ((null? l) #f) - ((eq? (gnode-label (car l)) label) (car l)) - (else (find label (cdr l))))) - (find label (set->list graph))) -(define (topological-sort graph) - (if (set-empty? graph) - '() - (let ((to-remove (or (remove-no-edges graph) (remove-cycle graph)))) - (let ((labels (set-map gnode-label to-remove))) - (cons labels - (topological-sort - (set-map (lambda (x) - (make-gnode - (gnode-label x) - (set-difference (gnode-edges x) labels))) - (set-difference graph to-remove)))))))) -(define (remove-no-edges graph) - (let ((nodes-with-no-edges - (set-keep (lambda (x) (set-empty? (gnode-edges x))) graph))) - (if (set-empty? nodes-with-no-edges) #f nodes-with-no-edges))) -(define (remove-cycle graph) - (define (remove l) - (let ((edges (gnode-edges (car l)))) - (define (equal-edges? x) (set-equal? (gnode-edges x) edges)) - (define (member-edges? x) (set-member? (gnode-label x) edges)) - (if (set-member? (gnode-label (car l)) edges) - (let ((edge-graph (set-keep member-edges? graph))) - (if (set-every? equal-edges? edge-graph) - edge-graph - (remove (cdr l)))) - (remove (cdr l))))) - (remove (set->list graph))) -(define (list->set list) list) -(define (set->list set) set) -(define (set-empty) '()) -(define (set-empty? set) (null? set)) -(define (set-member? x set) (memq x set)) -(define (set-singleton x) (list x)) -(define (set-adjoin set x) (if (memq x set) set (cons x set))) -(define (set-remove set x) - (cond ((null? set) '()) - ((eq? (car set) x) (cdr set)) - (else (cons (car set) (set-remove (cdr set) x))))) -(define (set-equal? s1 s2) - (cond ((null? s1) (null? s2)) - ((memq (car s1) s2) (set-equal? (cdr s1) (set-remove s2 (car s1)))) - (else #f))) -(define (set-difference set . other-sets) - (define (difference s1 s2) - (cond ((null? s1) '()) - ((memq (car s1) s2) (difference (cdr s1) s2)) - (else (cons (car s1) (difference (cdr s1) s2))))) - (n-ary difference set other-sets)) -(define (set-union . sets) - (define (union s1 s2) - (cond ((null? s1) s2) - ((memq (car s1) s2) (union (cdr s1) s2)) - (else (cons (car s1) (union (cdr s1) s2))))) - (n-ary union '() sets)) -(define (set-intersection set . other-sets) - (define (intersection s1 s2) - (cond ((null? s1) '()) - ((memq (car s1) s2) (cons (car s1) (intersection (cdr s1) s2))) - (else (intersection (cdr s1) s2)))) - (n-ary intersection set other-sets)) -(define (n-ary function first rest) - (if (null? rest) - first - (n-ary function (function first (car rest)) (cdr rest)))) -(define (set-keep keep? set) - (cond ((null? set) '()) - ((keep? (car set)) (cons (car set) (set-keep keep? (cdr set)))) - (else (set-keep keep? (cdr set))))) -(define (set-every? pred? set) - (or (null? set) (and (pred? (car set)) (set-every? pred? (cdr set))))) -(define (set-map proc set) - (if (null? set) '() (cons (proc (car set)) (set-map proc (cdr set))))) -(define (list->queue list) - (cons list (if (pair? list) (my-last-pair list) '()))) -(define (queue->list queue) (car queue)) -(define (queue-empty) (cons '() '())) -(define (queue-empty? queue) (null? (car queue))) -(define (queue-get! queue) - (if (null? (car queue)) - (compiler-internal-error "queue-get!, queue is empty") - (let ((x (caar queue))) - (set-car! queue (cdar queue)) - (if (null? (car queue)) (set-cdr! queue '())) - x))) -(define (queue-put! queue x) - (let ((entry (cons x '()))) - (if (null? (car queue)) - (set-car! queue entry) - (set-cdr! (cdr queue) entry)) - (set-cdr! queue entry) - x)) -(define (string->canonical-symbol str) - (let ((len (string-length str))) - (let loop ((str str) (s (make-string len)) (i (- len 1))) - (if (>= i 0) - (begin - (string-set! s i (char-downcase (string-ref str i))) - (loop str s (- i 1))) - (string->symbol s))))) -(define quote-sym (string->canonical-symbol "QUOTE")) -(define quasiquote-sym (string->canonical-symbol "QUASIQUOTE")) -(define unquote-sym (string->canonical-symbol "UNQUOTE")) -(define unquote-splicing-sym (string->canonical-symbol "UNQUOTE-SPLICING")) -(define lambda-sym (string->canonical-symbol "LAMBDA")) -(define if-sym (string->canonical-symbol "IF")) -(define set!-sym (string->canonical-symbol "SET!")) -(define cond-sym (string->canonical-symbol "COND")) -(define =>-sym (string->canonical-symbol "=>")) -(define else-sym (string->canonical-symbol "ELSE")) -(define and-sym (string->canonical-symbol "AND")) -(define or-sym (string->canonical-symbol "OR")) -(define case-sym (string->canonical-symbol "CASE")) -(define let-sym (string->canonical-symbol "LET")) -(define let*-sym (string->canonical-symbol "LET*")) -(define letrec-sym (string->canonical-symbol "LETREC")) -(define begin-sym (string->canonical-symbol "BEGIN")) -(define do-sym (string->canonical-symbol "DO")) -(define define-sym (string->canonical-symbol "DEFINE")) -(define delay-sym (string->canonical-symbol "DELAY")) -(define future-sym (string->canonical-symbol "FUTURE")) -(define **define-macro-sym (string->canonical-symbol "DEFINE-MACRO")) -(define **declare-sym (string->canonical-symbol "DECLARE")) -(define **include-sym (string->canonical-symbol "INCLUDE")) -(define not-sym (string->canonical-symbol "NOT")) -(define **c-declaration-sym (string->canonical-symbol "C-DECLARATION")) -(define **c-init-sym (string->canonical-symbol "C-INIT")) -(define **c-procedure-sym (string->canonical-symbol "C-PROCEDURE")) -(define void-sym (string->canonical-symbol "VOID")) -(define char-sym (string->canonical-symbol "CHAR")) -(define signed-char-sym (string->canonical-symbol "SIGNED-CHAR")) -(define unsigned-char-sym (string->canonical-symbol "UNSIGNED-CHAR")) -(define short-sym (string->canonical-symbol "SHORT")) -(define unsigned-short-sym (string->canonical-symbol "UNSIGNED-SHORT")) -(define int-sym (string->canonical-symbol "INT")) -(define unsigned-int-sym (string->canonical-symbol "UNSIGNED-INT")) -(define long-sym (string->canonical-symbol "LONG")) -(define unsigned-long-sym (string->canonical-symbol "UNSIGNED-LONG")) -(define float-sym (string->canonical-symbol "FLOAT")) -(define double-sym (string->canonical-symbol "DOUBLE")) -(define pointer-sym (string->canonical-symbol "POINTER")) -(define boolean-sym (string->canonical-symbol "BOOLEAN")) -(define string-sym (string->canonical-symbol "STRING")) -(define scheme-object-sym (string->canonical-symbol "SCHEME-OBJECT")) -(define c-id-prefix "___") -(define false-object (if (eq? '() #f) (string->symbol "#f") #f)) -(define (false-object? obj) (eq? obj false-object)) -(define undef-object (string->symbol "#[undefined]")) -(define (undef-object? obj) (eq? obj undef-object)) -(define (symbol-object? obj) - (and (not (false-object? obj)) (not (undef-object? obj)) (symbol? obj))) -(define scm-file-exts '("scm" #f)) -(define compiler-version "2.2.2") -(define (open-sf filename) - (define (open-err) (compiler-error "Can't find file" filename)) - (if (not (file-ext filename)) - (let loop ((exts scm-file-exts)) - (if (pair? exts) - (let* ((ext (car exts)) - (full-name - (if ext (string-append filename "." ext) filename)) - (port (open-input-file* full-name))) - (if port (vector port full-name 0 1 0) (loop (cdr exts)))) - (open-err))) - (let ((port (open-input-file* filename))) - (if port (vector port filename 0 1 0) (open-err))))) -(define (close-sf sf) (close-input-port (vector-ref sf 0))) -(define (sf-read-char sf) - (let ((c (read-char (vector-ref sf 0)))) - (cond ((eof-object? c)) - ((char=? c char-newline) - (vector-set! sf 3 (+ (vector-ref sf 3) 1)) - (vector-set! sf 4 0)) - (else (vector-set! sf 4 (+ (vector-ref sf 4) 1)))) - c)) -(define (sf-peek-char sf) (peek-char (vector-ref sf 0))) -(define (sf-read-error sf msg . args) - (apply compiler-user-error - (cons (sf->locat sf) - (cons (string-append "Read error -- " msg) args)))) -(define (sf->locat sf) - (vector 'file - (vector-ref sf 1) - (vector-ref sf 2) - (vector-ref sf 3) - (vector-ref sf 4))) -(define (expr->locat expr source) (vector 'expr expr source)) -(define (locat-show loc) - (if loc - (case (vector-ref loc 0) - ((file) - (if (pinpoint-error - (vector-ref loc 1) - (vector-ref loc 3) - (vector-ref loc 4)) - (begin - (display "file \"") - (display (vector-ref loc 1)) - (display "\", line ") - (display (vector-ref loc 3)) - (display ", character ") - (display (vector-ref loc 4))))) - ((expr) - (display "expression ") - (write (vector-ref loc 1)) - (if (vector-ref loc 2) - (begin - (display " ") - (locat-show (source-locat (vector-ref loc 2)))))) - (else (compiler-internal-error "locat-show, unknown location tag"))) - (display "unknown location"))) -(define (locat-filename loc) - (if loc - (case (vector-ref loc 0) - ((file) (vector-ref loc 1)) - ((expr) - (let ((source (vector-ref loc 2))) - (if source (locat-filename (source-locat source)) ""))) - (else - (compiler-internal-error "locat-filename, unknown location tag"))) - "")) -(define (make-source code locat) (vector code locat)) -(define (source-code x) (vector-ref x 0)) -(define (source-code-set! x y) (vector-set! x 0 y) x) -(define (source-locat x) (vector-ref x 1)) -(define (expression->source expr source) - (define (expr->source x) - (make-source - (cond ((pair? x) (list->source x)) - ((vector? x) (vector->source x)) - ((symbol-object? x) (string->canonical-symbol (symbol->string x))) - (else x)) - (expr->locat x source))) - (define (list->source l) - (cond ((pair? l) (cons (expr->source (car l)) (list->source (cdr l)))) - ((null? l) '()) - (else (expr->source l)))) - (define (vector->source v) - (let* ((len (vector-length v)) (x (make-vector len))) - (let loop ((i (- len 1))) - (if (>= i 0) - (begin - (vector-set! x i (expr->source (vector-ref v i))) - (loop (- i 1))))) - x)) - (expr->source expr)) -(define (source->expression source) - (define (list->expression l) - (cond ((pair? l) - (cons (source->expression (car l)) (list->expression (cdr l)))) - ((null? l) '()) - (else (source->expression l)))) - (define (vector->expression v) - (let* ((len (vector-length v)) (x (make-vector len))) - (let loop ((i (- len 1))) - (if (>= i 0) - (begin - (vector-set! x i (source->expression (vector-ref v i))) - (loop (- i 1))))) - x)) - (let ((code (source-code source))) - (cond ((pair? code) (list->expression code)) - ((vector? code) (vector->expression code)) - (else code)))) -(define (file->sources filename info-port) - (if info-port - (begin - (display "(reading \"" info-port) - (display filename info-port) - (display "\"" info-port))) - (let ((sf (open-sf filename))) - (define (read-sources) - (let ((source (read-source sf))) - (if (not (eof-object? source)) - (begin - (if info-port (display "." info-port)) - (cons source (read-sources))) - '()))) - (let ((sources (read-sources))) - (if info-port (display ")" info-port)) - (close-sf sf) - sources))) -(define (file->sources* filename info-port loc) - (file->sources - (if (path-absolute? filename) - filename - (string-append (file-path (locat-filename loc)) filename)) - info-port)) -(define (read-source sf) - (define (read-char*) - (let ((c (sf-read-char sf))) - (if (eof-object? c) - (sf-read-error sf "Premature end of file encountered") - c))) - (define (read-non-whitespace-char) - (let ((c (read-char*))) - (cond ((< 0 (vector-ref read-table (char->integer c))) - (read-non-whitespace-char)) - ((char=? c #\;) - (let loop () - (if (not (char=? (read-char*) char-newline)) - (loop) - (read-non-whitespace-char)))) - (else c)))) - (define (delimiter? c) - (or (eof-object? c) (not (= (vector-ref read-table (char->integer c)) 0)))) - (define (read-list first) - (let ((result (cons first '()))) - (let loop ((end result)) - (let ((c (read-non-whitespace-char))) - (cond ((char=? c #\))) - ((and (char=? c #\.) (delimiter? (sf-peek-char sf))) - (let ((x (read-source sf))) - (if (char=? (read-non-whitespace-char) #\)) - (set-cdr! end x) - (sf-read-error sf "')' expected")))) - (else - (let ((tail (cons (rd* c) '()))) - (set-cdr! end tail) - (loop tail)))))) - result)) - (define (read-vector) - (define (loop i) - (let ((c (read-non-whitespace-char))) - (if (char=? c #\)) - (make-vector i '()) - (let* ((x (rd* c)) (v (loop (+ i 1)))) (vector-set! v i x) v)))) - (loop 0)) - (define (read-string) - (define (loop i) - (let ((c (read-char*))) - (cond ((char=? c #\") (make-string i #\space)) - ((char=? c #\\) - (let* ((c (read-char*)) (s (loop (+ i 1)))) - (string-set! s i c) - s)) - (else (let ((s (loop (+ i 1)))) (string-set! s i c) s))))) - (loop 0)) - (define (read-symbol/number-string i) - (if (delimiter? (sf-peek-char sf)) - (make-string i #\space) - (let* ((c (sf-read-char sf)) (s (read-symbol/number-string (+ i 1)))) - (string-set! s i (char-downcase c)) - s))) - (define (read-symbol/number c) - (let ((s (read-symbol/number-string 1))) - (string-set! s 0 (char-downcase c)) - (or (string->number s 10) (string->canonical-symbol s)))) - (define (read-prefixed-number c) - (let ((s (read-symbol/number-string 2))) - (string-set! s 0 #\#) - (string-set! s 1 c) - (string->number s 10))) - (define (read-special-symbol) - (let ((s (read-symbol/number-string 2))) - (string-set! s 0 #\#) - (string-set! s 1 #\#) - (string->canonical-symbol s))) - (define (rd c) - (cond ((eof-object? c) c) - ((< 0 (vector-ref read-table (char->integer c))) - (rd (sf-read-char sf))) - ((char=? c #\;) - (let loop () - (let ((c (sf-read-char sf))) - (cond ((eof-object? c) c) - ((char=? c char-newline) (rd (sf-read-char sf))) - (else (loop)))))) - (else (rd* c)))) - (define (rd* c) - (let ((source (make-source #f (sf->locat sf)))) - (source-code-set! - source - (cond ((char=? c #\() - (let ((x (read-non-whitespace-char))) - (if (char=? x #\)) '() (read-list (rd* x))))) - ((char=? c #\#) - (let ((c (char-downcase (sf-read-char sf)))) - (cond ((char=? c #\() (read-vector)) - ((char=? c #\f) false-object) - ((char=? c #\t) #t) - ((char=? c #\\) - (let ((c (read-char*))) - (if (or (not (char-alphabetic? c)) - (delimiter? (sf-peek-char sf))) - c - (let ((name (read-symbol/number c))) - (let ((x (assq name named-char-table))) - (if x - (cdr x) - (sf-read-error - sf - "Unknown character name" - name))))))) - ((char=? c #\#) (read-special-symbol)) - (else - (let ((num (read-prefixed-number c))) - (or num - (sf-read-error - sf - "Unknown '#' read macro" - c))))))) - ((char=? c #\") (read-string)) - ((char=? c #\') - (list (make-source quote-sym (sf->locat sf)) (read-source sf))) - ((char=? c #\`) - (list (make-source quasiquote-sym (sf->locat sf)) - (read-source sf))) - ((char=? c #\,) - (if (char=? (sf-peek-char sf) #\@) - (let ((x (make-source unquote-splicing-sym (sf->locat sf)))) - (sf-read-char sf) - (list x (read-source sf))) - (list (make-source unquote-sym (sf->locat sf)) - (read-source sf)))) - ((char=? c #\)) (sf-read-error sf "Misplaced ')'")) - ((or (char=? c #\[) (char=? c #\]) (char=? c #\{) (char=? c #\})) - (sf-read-error sf "Illegal character" c)) - (else - (if (char=? c #\.) - (if (delimiter? (sf-peek-char sf)) - (sf-read-error sf "Misplaced '.'"))) - (read-symbol/number c)))))) - (rd (sf-read-char sf))) -(define named-char-table - (list (cons (string->canonical-symbol "NUL") char-nul) - (cons (string->canonical-symbol "TAB") char-tab) - (cons (string->canonical-symbol "NEWLINE") char-newline) - (cons (string->canonical-symbol "SPACE") #\space))) -(define read-table - (let ((rt (make-vector (+ max-character-encoding 1) 0))) - (vector-set! rt (char->integer char-tab) 1) - (vector-set! rt (char->integer char-newline) 1) - (vector-set! rt (char->integer #\space) 1) - (vector-set! rt (char->integer #\;) -1) - (vector-set! rt (char->integer #\() -1) - (vector-set! rt (char->integer #\)) -1) - (vector-set! rt (char->integer #\") -1) - (vector-set! rt (char->integer #\') -1) - (vector-set! rt (char->integer #\`) -1) - rt)) -(define (make-var name bound refs sets source) - (vector var-tag name bound refs sets source #f)) -(define (var? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) var-tag))) -(define (var-name x) (vector-ref x 1)) -(define (var-bound x) (vector-ref x 2)) -(define (var-refs x) (vector-ref x 3)) -(define (var-sets x) (vector-ref x 4)) -(define (var-source x) (vector-ref x 5)) -(define (var-info x) (vector-ref x 6)) -(define (var-name-set! x y) (vector-set! x 1 y)) -(define (var-bound-set! x y) (vector-set! x 2 y)) -(define (var-refs-set! x y) (vector-set! x 3 y)) -(define (var-sets-set! x y) (vector-set! x 4 y)) -(define (var-source-set! x y) (vector-set! x 5 y)) -(define (var-info-set! x y) (vector-set! x 6 y)) -(define var-tag (list 'var-tag)) -(define (var-copy var) - (make-var (var-name var) #t (set-empty) (set-empty) (var-source var))) -(define (make-temp-var name) (make-var name #t (set-empty) (set-empty) #f)) -(define (temp-var? var) (eq? (var-bound var) #t)) -(define ret-var (make-temp-var 'ret)) -(define ret-var-set (set-singleton ret-var)) -(define closure-env-var (make-temp-var 'closure-env)) -(define empty-var (make-temp-var #f)) -(define make-global-environment #f) -(set! make-global-environment (lambda () (env-frame #f '()))) -(define (env-frame env vars) (vector (cons vars #f) '() '() env)) -(define (env-new-var! env name source) - (let* ((glob (not (env-parent-ref env))) - (var (make-var name (not glob) (set-empty) (set-empty) source))) - (env-vars-set! env (cons var (env-vars-ref env))) - var)) -(define (env-macro env name def) - (let ((name* (if (full-name? name) - name - (let ((prefix (env-namespace-prefix env name))) - (if prefix (make-full-name prefix name) name))))) - (vector (vector-ref env 0) - (cons (cons name* def) (env-macros-ref env)) - (env-decls-ref env) - (env-parent-ref env)))) -(define (env-declare env decl) - (vector (vector-ref env 0) - (env-macros-ref env) - (cons decl (env-decls-ref env)) - (env-parent-ref env))) -(define (env-vars-ref env) (car (vector-ref env 0))) -(define (env-vars-set! env vars) (set-car! (vector-ref env 0) vars)) -(define (env-macros-ref env) (vector-ref env 1)) -(define (env-decls-ref env) (vector-ref env 2)) -(define (env-parent-ref env) (vector-ref env 3)) -(define (env-namespace-prefix env name) - (let loop ((decls (env-decls-ref env))) - (if (pair? decls) - (let ((decl (car decls))) - (if (eq? (car decl) namespace-sym) - (let ((syms (cddr decl))) - (if (or (null? syms) (memq name syms)) - (cadr decl) - (loop (cdr decls)))) - (loop (cdr decls)))) - #f))) -(define (env-lookup env name stop-at-first-frame? proc) - (define (search env name full?) - (if full? - (search* env name full?) - (let ((prefix (env-namespace-prefix env name))) - (if prefix - (search* env (make-full-name prefix name) #t) - (search* env name full?))))) - (define (search* env name full?) - (define (search-macros macros) - (if (pair? macros) - (let ((m (car macros))) - (if (eq? (car m) name) - (proc env name (cdr m)) - (search-macros (cdr macros)))) - (search-vars (env-vars-ref env)))) - (define (search-vars vars) - (if (pair? vars) - (let ((v (car vars))) - (if (eq? (var-name v) name) - (proc env name v) - (search-vars (cdr vars)))) - (let ((env* (env-parent-ref env))) - (if (or stop-at-first-frame? (not env*)) - (proc env name #f) - (search env* name full?))))) - (search-macros (env-macros-ref env))) - (search env name (full-name? name))) -(define (valid-prefix? str) - (let ((l (string-length str))) - (or (= l 0) (and (>= l 2) (char=? (string-ref str (- l 1)) #\#))))) -(define (full-name? sym) - (let ((str (symbol->string sym))) - (let loop ((i (- (string-length str) 1))) - (if (< i 0) #f (if (char=? (string-ref str i) #\#) #t (loop (- i 1))))))) -(define (make-full-name prefix sym) - (if (= (string-length prefix) 0) - sym - (string->canonical-symbol (string-append prefix (symbol->string sym))))) -(define (env-lookup-var env name source) - (env-lookup - env - name - #f - (lambda (env name x) - (if x - (if (var? x) - x - (compiler-internal-error - "env-lookup-var, name is that of a macro" - name)) - (env-new-var! env name source))))) -(define (env-define-var env name source) - (env-lookup - env - name - #t - (lambda (env name x) - (if x - (if (var? x) - (pt-syntax-error source "Duplicate definition of a variable") - (compiler-internal-error - "env-define-var, name is that of a macro" - name)) - (env-new-var! env name source))))) -(define (env-lookup-global-var env name) - (let ((env* (env-global-env env))) - (define (search-vars vars) - (if (pair? vars) - (let ((v (car vars))) - (if (eq? (var-name v) name) v (search-vars (cdr vars)))) - (env-new-var! env* name #f))) - (search-vars (env-vars-ref env*)))) -(define (env-global-variables env) (env-vars-ref (env-global-env env))) -(define (env-global-env env) - (let loop ((env env)) - (let ((env* (env-parent-ref env))) (if env* (loop env*) env)))) -(define (env-lookup-macro env name) - (env-lookup - env - name - #f - (lambda (env name x) (if (or (not x) (var? x)) #f x)))) -(define (env-declarations env) env) -(define flag-declarations '()) -(define parameterized-declarations '()) -(define boolean-declarations '()) -(define namable-declarations '()) -(define namable-boolean-declarations '()) -(define namable-string-declarations '()) -(define (define-flag-decl name type) - (set! flag-declarations (cons (cons name type) flag-declarations)) - '()) -(define (define-parameterized-decl name) - (set! parameterized-declarations (cons name parameterized-declarations)) - '()) -(define (define-boolean-decl name) - (set! boolean-declarations (cons name boolean-declarations)) - '()) -(define (define-namable-decl name type) - (set! namable-declarations (cons (cons name type) namable-declarations)) - '()) -(define (define-namable-boolean-decl name) - (set! namable-boolean-declarations (cons name namable-boolean-declarations)) - '()) -(define (define-namable-string-decl name) - (set! namable-string-declarations (cons name namable-string-declarations)) - '()) -(define (flag-decl source type val) (list type val)) -(define (parameterized-decl source id parm) (list id parm)) -(define (boolean-decl source id pos) (list id pos)) -(define (namable-decl source type val names) (cons type (cons val names))) -(define (namable-boolean-decl source id pos names) (cons id (cons pos names))) -(define (namable-string-decl source id str names) - (if (and (eq? id namespace-sym) (not (valid-prefix? str))) - (pt-syntax-error source "Illegal namespace")) - (cons id (cons str names))) -(define (declaration-value name element default decls) - (if (not decls) - default - (let loop ((l (env-decls-ref decls))) - (if (pair? l) - (let ((d (car l))) - (if (and (eq? (car d) name) - (or (null? (cddr d)) (memq element (cddr d)))) - (cadr d) - (loop (cdr l)))) - (declaration-value name element default (env-parent-ref decls)))))) -(define namespace-sym (string->canonical-symbol "NAMESPACE")) -(define-namable-string-decl namespace-sym) -(define (node-parent x) (vector-ref x 1)) -(define (node-children x) (vector-ref x 2)) -(define (node-fv x) (vector-ref x 3)) -(define (node-decl x) (vector-ref x 4)) -(define (node-source x) (vector-ref x 5)) -(define (node-parent-set! x y) (vector-set! x 1 y)) -(define (node-fv-set! x y) (vector-set! x 3 y)) -(define (node-decl-set! x y) (vector-set! x 4 y)) -(define (node-source-set! x y) (vector-set! x 5 y)) -(define (node-children-set! x y) - (vector-set! x 2 y) - (for-each (lambda (child) (node-parent-set! child x)) y) - (node-fv-invalidate! x)) -(define (node-fv-invalidate! x) - (let loop ((node x)) - (if node (begin (node-fv-set! node #t) (loop (node-parent node)))))) -(define (make-cst parent children fv decl source val) - (vector cst-tag parent children fv decl source val)) -(define (cst? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) cst-tag))) -(define (cst-val x) (vector-ref x 6)) -(define (cst-val-set! x y) (vector-set! x 6 y)) -(define cst-tag (list 'cst-tag)) -(define (make-ref parent children fv decl source var) - (vector ref-tag parent children fv decl source var)) -(define (ref? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) ref-tag))) -(define (ref-var x) (vector-ref x 6)) -(define (ref-var-set! x y) (vector-set! x 6 y)) -(define ref-tag (list 'ref-tag)) -(define (make-set parent children fv decl source var) - (vector set-tag parent children fv decl source var)) -(define (set? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) set-tag))) -(define (set-var x) (vector-ref x 6)) -(define (set-var-set! x y) (vector-set! x 6 y)) -(define set-tag (list 'set-tag)) -(define (make-def parent children fv decl source var) - (vector def-tag parent children fv decl source var)) -(define (def? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) def-tag))) -(define (def-var x) (vector-ref x 6)) -(define (def-var-set! x y) (vector-set! x 6 y)) -(define def-tag (list 'def-tag)) -(define (make-tst parent children fv decl source) - (vector tst-tag parent children fv decl source)) -(define (tst? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) tst-tag))) -(define tst-tag (list 'tst-tag)) -(define (make-conj parent children fv decl source) - (vector conj-tag parent children fv decl source)) -(define (conj? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) conj-tag))) -(define conj-tag (list 'conj-tag)) -(define (make-disj parent children fv decl source) - (vector disj-tag parent children fv decl source)) -(define (disj? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) disj-tag))) -(define disj-tag (list 'disj-tag)) -(define (make-prc parent children fv decl source name min rest parms) - (vector prc-tag parent children fv decl source name min rest parms)) -(define (prc? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) prc-tag))) -(define (prc-name x) (vector-ref x 6)) -(define (prc-min x) (vector-ref x 7)) -(define (prc-rest x) (vector-ref x 8)) -(define (prc-parms x) (vector-ref x 9)) -(define (prc-name-set! x y) (vector-set! x 6 y)) -(define (prc-min-set! x y) (vector-set! x 7 y)) -(define (prc-rest-set! x y) (vector-set! x 8 y)) -(define (prc-parms-set! x y) (vector-set! x 9 y)) -(define prc-tag (list 'prc-tag)) -(define (make-app parent children fv decl source) - (vector app-tag parent children fv decl source)) -(define (app? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) app-tag))) -(define app-tag (list 'app-tag)) -(define (make-fut parent children fv decl source) - (vector fut-tag parent children fv decl source)) -(define (fut? x) - (and (vector? x) (> (vector-length x) 0) (eq? (vector-ref x 0) fut-tag))) -(define fut-tag (list 'fut-tag)) -(define (new-cst source decl val) (make-cst #f '() #t decl source val)) -(define (new-ref source decl var) - (let ((node (make-ref #f '() #t decl source var))) - (var-refs-set! var (set-adjoin (var-refs var) node)) - node)) -(define (new-ref-extended-bindings source name env) - (new-ref source - (add-extended-bindings (env-declarations env)) - (env-lookup-global-var env name))) -(define (new-set source decl var val) - (let ((node (make-set #f (list val) #t decl source var))) - (var-sets-set! var (set-adjoin (var-sets var) node)) - (node-parent-set! val node) - node)) -(define (set-val x) - (if (set? x) - (car (node-children x)) - (compiler-internal-error "set-val, 'set' node expected" x))) -(define (new-def source decl var val) - (let ((node (make-def #f (list val) #t decl source var))) - (var-sets-set! var (set-adjoin (var-sets var) node)) - (node-parent-set! val node) - node)) -(define (def-val x) - (if (def? x) - (car (node-children x)) - (compiler-internal-error "def-val, 'def' node expected" x))) -(define (new-tst source decl pre con alt) - (let ((node (make-tst #f (list pre con alt) #t decl source))) - (node-parent-set! pre node) - (node-parent-set! con node) - (node-parent-set! alt node) - node)) -(define (tst-pre x) - (if (tst? x) - (car (node-children x)) - (compiler-internal-error "tst-pre, 'tst' node expected" x))) -(define (tst-con x) - (if (tst? x) - (cadr (node-children x)) - (compiler-internal-error "tst-con, 'tst' node expected" x))) -(define (tst-alt x) - (if (tst? x) - (caddr (node-children x)) - (compiler-internal-error "tst-alt, 'tst' node expected" x))) -(define (new-conj source decl pre alt) - (let ((node (make-conj #f (list pre alt) #t decl source))) - (node-parent-set! pre node) - (node-parent-set! alt node) - node)) -(define (conj-pre x) - (if (conj? x) - (car (node-children x)) - (compiler-internal-error "conj-pre, 'conj' node expected" x))) -(define (conj-alt x) - (if (conj? x) - (cadr (node-children x)) - (compiler-internal-error "conj-alt, 'conj' node expected" x))) -(define (new-disj source decl pre alt) - (let ((node (make-disj #f (list pre alt) #t decl source))) - (node-parent-set! pre node) - (node-parent-set! alt node) - node)) -(define (disj-pre x) - (if (disj? x) - (car (node-children x)) - (compiler-internal-error "disj-pre, 'disj' node expected" x))) -(define (disj-alt x) - (if (disj? x) - (cadr (node-children x)) - (compiler-internal-error "disj-alt, 'disj' node expected" x))) -(define (new-prc source decl name min rest parms body) - (let ((node (make-prc #f (list body) #t decl source name min rest parms))) - (for-each (lambda (x) (var-bound-set! x node)) parms) - (node-parent-set! body node) - node)) -(define (prc-body x) - (if (prc? x) - (car (node-children x)) - (compiler-internal-error "prc-body, 'proc' node expected" x))) -(define (new-call source decl oper args) - (let ((node (make-app #f (cons oper args) #t decl source))) - (node-parent-set! oper node) - (for-each (lambda (x) (node-parent-set! x node)) args) - node)) -(define (new-call* source decl oper args) - (if *ptree-port* - (if (ref? oper) - (let ((var (ref-var oper))) - (if (global? var) - (let ((proc (standard-procedure - (var-name var) - (node-decl oper)))) - (if (and proc - (not (nb-args-conforms? - (length args) - (standard-procedure-call-pattern proc)))) - (begin - (display "*** WARNING -- \"" *ptree-port*) - (display (var-name var) *ptree-port*) - (display "\" is called with " *ptree-port*) - (display (length args) *ptree-port*) - (display " argument(s)." *ptree-port*) - (newline *ptree-port*)))))))) - (new-call source decl oper args)) -(define (app-oper x) - (if (app? x) - (car (node-children x)) - (compiler-internal-error "app-oper, 'call' node expected" x))) -(define (app-args x) - (if (app? x) - (cdr (node-children x)) - (compiler-internal-error "app-args, 'call' node expected" x))) -(define (oper-pos? node) - (let ((parent (node-parent node))) - (if parent (and (app? parent) (eq? (app-oper parent) node)) #f))) -(define (new-fut source decl val) - (let ((node (make-fut #f (list val) #t decl source))) - (node-parent-set! val node) - node)) -(define (fut-val x) - (if (fut? x) - (car (node-children x)) - (compiler-internal-error "fut-val, 'fut' node expected" x))) -(define (new-disj-call source decl pre oper alt) - (new-call* - source - decl - (let* ((parms (new-temps source '(temp))) (temp (car parms))) - (new-prc source - decl - #f - 1 - #f - parms - (new-tst source - decl - (new-ref source decl temp) - (new-call* - source - decl - oper - (list (new-ref source decl temp))) - alt))) - (list pre))) -(define (new-seq source decl before after) - (new-call* - source - decl - (new-prc source decl #f 1 #f (new-temps source '(temp)) after) - (list before))) -(define (new-let ptree proc vars vals body) - (if (pair? vars) - (new-call - (node-source ptree) - (node-decl ptree) - (new-prc (node-source proc) - (node-decl proc) - (prc-name proc) - (length vars) - #f - (reverse vars) - body) - (reverse vals)) - body)) -(define (new-temps source names) - (if (null? names) - '() - (cons (make-var (car names) #t (set-empty) (set-empty) source) - (new-temps source (cdr names))))) -(define (new-variables vars) - (if (null? vars) - '() - (cons (make-var - (source-code (car vars)) - #t - (set-empty) - (set-empty) - (car vars)) - (new-variables (cdr vars))))) -(define (set-prc-names! vars vals) - (let loop ((vars vars) (vals vals)) - (if (not (null? vars)) - (let ((var (car vars)) (val (car vals))) - (if (prc? val) (prc-name-set! val (symbol->string (var-name var)))) - (loop (cdr vars) (cdr vals)))))) -(define (free-variables node) - (if (eq? (node-fv node) #t) - (let ((x (apply set-union (map free-variables (node-children node))))) - (node-fv-set! - node - (cond ((ref? node) - (if (global? (ref-var node)) x (set-adjoin x (ref-var node)))) - ((set? node) - (if (global? (set-var node)) x (set-adjoin x (set-var node)))) - ((prc? node) (set-difference x (list->set (prc-parms node)))) - ((and (app? node) (prc? (app-oper node))) - (set-difference x (list->set (prc-parms (app-oper node))))) - (else x))))) - (node-fv node)) -(define (bound-variables node) (list->set (prc-parms node))) -(define (not-mutable? var) (set-empty? (var-sets var))) -(define (mutable? var) (not (not-mutable? var))) -(define (bound? var) (var-bound var)) -(define (global? var) (not (bound? var))) -(define (global-val var) - (and (global? var) - (let ((sets (set->list (var-sets var)))) - (and (pair? sets) - (null? (cdr sets)) - (def? (car sets)) - (eq? (compilation-strategy (node-decl (car sets))) block-sym) - (def-val (car sets)))))) -(define **not-sym (string->canonical-symbol "##NOT")) -(define **quasi-append-sym (string->canonical-symbol "##QUASI-APPEND")) -(define **quasi-list-sym (string->canonical-symbol "##QUASI-LIST")) -(define **quasi-cons-sym (string->canonical-symbol "##QUASI-CONS")) -(define **quasi-list->vector-sym - (string->canonical-symbol "##QUASI-LIST->VECTOR")) -(define **case-memv-sym (string->canonical-symbol "##CASE-MEMV")) -(define **unassigned?-sym (string->canonical-symbol "##UNASSIGNED?")) -(define **make-cell-sym (string->canonical-symbol "##MAKE-CELL")) -(define **cell-ref-sym (string->canonical-symbol "##CELL-REF")) -(define **cell-set!-sym (string->canonical-symbol "##CELL-SET!")) -(define **make-placeholder-sym (string->canonical-symbol "##MAKE-PLACEHOLDER")) -(define ieee-scheme-sym (string->canonical-symbol "IEEE-SCHEME")) -(define r4rs-scheme-sym (string->canonical-symbol "R4RS-SCHEME")) -(define multilisp-sym (string->canonical-symbol "MULTILISP")) -(define lambda-lift-sym (string->canonical-symbol "LAMBDA-LIFT")) -(define block-sym (string->canonical-symbol "BLOCK")) -(define separate-sym (string->canonical-symbol "SEPARATE")) -(define standard-bindings-sym (string->canonical-symbol "STANDARD-BINDINGS")) -(define extended-bindings-sym (string->canonical-symbol "EXTENDED-BINDINGS")) -(define safe-sym (string->canonical-symbol "SAFE")) -(define interrupts-enabled-sym (string->canonical-symbol "INTERRUPTS-ENABLED")) -(define-flag-decl ieee-scheme-sym 'dialect) -(define-flag-decl r4rs-scheme-sym 'dialect) -(define-flag-decl multilisp-sym 'dialect) -(define-boolean-decl lambda-lift-sym) -(define-flag-decl block-sym 'compilation-strategy) -(define-flag-decl separate-sym 'compilation-strategy) -(define-namable-boolean-decl standard-bindings-sym) -(define-namable-boolean-decl extended-bindings-sym) -(define-boolean-decl safe-sym) -(define-boolean-decl interrupts-enabled-sym) -(define (scheme-dialect decl) - (declaration-value 'dialect #f ieee-scheme-sym decl)) -(define (lambda-lift? decl) (declaration-value lambda-lift-sym #f #t decl)) -(define (compilation-strategy decl) - (declaration-value 'compilation-strategy #f separate-sym decl)) -(define (standard-binding? name decl) - (declaration-value standard-bindings-sym name #f decl)) -(define (extended-binding? name decl) - (declaration-value extended-bindings-sym name #f decl)) -(define (add-extended-bindings decl) - (add-decl (list extended-bindings-sym #t) decl)) -(define (intrs-enabled? decl) - (declaration-value interrupts-enabled-sym #f #t decl)) -(define (add-not-interrupts-enabled decl) - (add-decl (list interrupts-enabled-sym #f) decl)) -(define (safe? decl) (declaration-value safe-sym #f #f decl)) -(define (add-not-safe decl) (add-decl (list safe-sym #f) decl)) -(define (dialect-specific-keywords dialect) - (cond ((eq? dialect ieee-scheme-sym) ieee-scheme-specific-keywords) - ((eq? dialect r4rs-scheme-sym) r4rs-scheme-specific-keywords) - ((eq? dialect multilisp-sym) multilisp-specific-keywords) - (else - (compiler-internal-error - "dialect-specific-keywords, unknown dialect" - dialect)))) -(define (dialect-specific-procedures dialect) - (cond ((eq? dialect ieee-scheme-sym) ieee-scheme-specific-procedures) - ((eq? dialect r4rs-scheme-sym) r4rs-scheme-specific-procedures) - ((eq? dialect multilisp-sym) multilisp-specific-procedures) - (else - (compiler-internal-error - "dialect-specific-procedures, unknown dialect" - dialect)))) -(define (make-standard-procedure x) - (cons (string->canonical-symbol (car x)) (cdr x))) -(define (standard-procedure name decl) - (or (assq name (dialect-specific-procedures (scheme-dialect decl))) - (assq name common-procedures))) -(define (standard-procedure-call-pattern proc) (cdr proc)) -(define ieee-scheme-specific-keywords '()) -(define ieee-scheme-specific-procedures (map make-standard-procedure '())) -(define r4rs-scheme-specific-keywords (list delay-sym)) -(define r4rs-scheme-specific-procedures - (map make-standard-procedure - '(("LIST-TAIL" 2) - ("-" . 1) - ("/" . 1) - ("STRING->LIST" 1) - ("LIST->STRING" 1) - ("STRING-COPY" 1) - ("STRING-FILL!" 2) - ("VECTOR->LIST" 1) - ("LIST->VECTOR" 1) - ("VECTOR-FILL!" 2) - ("FORCE" 1) - ("WITH-INPUT-FROM-FILE" 2) - ("WITH-OUTPUT-TO-FILE" 2) - ("CHAR-READY?" 0 1) - ("LOAD" 1) - ("TRANSCRIPT-ON" 1) - ("TRANSCRIPT-OFF" 0)))) -(define multilisp-specific-keywords (list delay-sym future-sym)) -(define multilisp-specific-procedures - (map make-standard-procedure '(("FORCE" 1) ("TOUCH" 1)))) -(define common-keywords - (list quote-sym - quasiquote-sym - unquote-sym - unquote-splicing-sym - lambda-sym - if-sym - set!-sym - cond-sym - =>-sym - else-sym - and-sym - or-sym - case-sym - let-sym - let*-sym - letrec-sym - begin-sym - do-sym - define-sym - **define-macro-sym - **declare-sym - **include-sym)) -(define common-procedures - (map make-standard-procedure - '(("NOT" 1) - ("BOOLEAN?" 1) - ("EQV?" 2) - ("EQ?" 2) - ("EQUAL?" 2) - ("PAIR?" 1) - ("CONS" 2) - ("CAR" 1) - ("CDR" 1) - ("SET-CAR!" 2) - ("SET-CDR!" 2) - ("CAAR" 1) - ("CADR" 1) - ("CDAR" 1) - ("CDDR" 1) - ("CAAAR" 1) - ("CAADR" 1) - ("CADAR" 1) - ("CADDR" 1) - ("CDAAR" 1) - ("CDADR" 1) - ("CDDAR" 1) - ("CDDDR" 1) - ("CAAAAR" 1) - ("CAAADR" 1) - ("CAADAR" 1) - ("CAADDR" 1) - ("CADAAR" 1) - ("CADADR" 1) - ("CADDAR" 1) - ("CADDDR" 1) - ("CDAAAR" 1) - ("CDAADR" 1) - ("CDADAR" 1) - ("CDADDR" 1) - ("CDDAAR" 1) - ("CDDADR" 1) - ("CDDDAR" 1) - ("CDDDDR" 1) - ("NULL?" 1) - ("LIST?" 1) - ("LIST" . 0) - ("LENGTH" 1) - ("APPEND" . 0) - ("REVERSE" 1) - ("LIST-REF" 2) - ("MEMQ" 2) - ("MEMV" 2) - ("MEMBER" 2) - ("ASSQ" 2) - ("ASSV" 2) - ("ASSOC" 2) - ("SYMBOL?" 1) - ("SYMBOL->STRING" 1) - ("STRING->SYMBOL" 1) - ("NUMBER?" 1) - ("COMPLEX?" 1) - ("REAL?" 1) - ("RATIONAL?" 1) - ("INTEGER?" 1) - ("EXACT?" 1) - ("INEXACT?" 1) - ("=" . 2) - ("<" . 2) - (">" . 2) - ("<=" . 2) - (">=" . 2) - ("ZERO?" 1) - ("POSITIVE?" 1) - ("NEGATIVE?" 1) - ("ODD?" 1) - ("EVEN?" 1) - ("MAX" . 1) - ("MIN" . 1) - ("+" . 0) - ("*" . 0) - ("-" 1 2) - ("/" 1 2) - ("ABS" 1) - ("QUOTIENT" 2) - ("REMAINDER" 2) - ("MODULO" 2) - ("GCD" . 0) - ("LCM" . 0) - ("NUMERATOR" 1) - ("DENOMINATOR" 1) - ("FLOOR" 1) - ("CEILING" 1) - ("TRUNCATE" 1) - ("ROUND" 1) - ("RATIONALIZE" 2) - ("EXP" 1) - ("LOG" 1) - ("SIN" 1) - ("COS" 1) - ("TAN" 1) - ("ASIN" 1) - ("ACOS" 1) - ("ATAN" 1 2) - ("SQRT" 1) - ("EXPT" 2) - ("MAKE-RECTANGULAR" 2) - ("MAKE-POLAR" 2) - ("REAL-PART" 1) - ("IMAG-PART" 1) - ("MAGNITUDE" 1) - ("ANGLE" 1) - ("EXACT->INEXACT" 1) - ("INEXACT->EXACT" 1) - ("NUMBER->STRING" 1 2) - ("STRING->NUMBER" 1 2) - ("CHAR?" 1) - ("CHAR=?" 2) - ("CHAR?" 2) - ("CHAR<=?" 2) - ("CHAR>=?" 2) - ("CHAR-CI=?" 2) - ("CHAR-CI?" 2) - ("CHAR-CI<=?" 2) - ("CHAR-CI>=?" 2) - ("CHAR-ALPHABETIC?" 1) - ("CHAR-NUMERIC?" 1) - ("CHAR-WHITESPACE?" 1) - ("CHAR-UPPER-CASE?" 1) - ("CHAR-LOWER-CASE?" 1) - ("CHAR->INTEGER" 1) - ("INTEGER->CHAR" 1) - ("CHAR-UPCASE" 1) - ("CHAR-DOWNCASE" 1) - ("STRING?" 1) - ("MAKE-STRING" 1 2) - ("STRING" . 0) - ("STRING-LENGTH" 1) - ("STRING-REF" 2) - ("STRING-SET!" 3) - ("STRING=?" 2) - ("STRING?" 2) - ("STRING<=?" 2) - ("STRING>=?" 2) - ("STRING-CI=?" 2) - ("STRING-CI?" 2) - ("STRING-CI<=?" 2) - ("STRING-CI>=?" 2) - ("SUBSTRING" 3) - ("STRING-APPEND" . 0) - ("VECTOR?" 1) - ("MAKE-VECTOR" 1 2) - ("VECTOR" . 0) - ("VECTOR-LENGTH" 1) - ("VECTOR-REF" 2) - ("VECTOR-SET!" 3) - ("PROCEDURE?" 1) - ("APPLY" . 2) - ("MAP" . 2) - ("FOR-EACH" . 2) - ("CALL-WITH-CURRENT-CONTINUATION" 1) - ("CALL-WITH-INPUT-FILE" 2) - ("CALL-WITH-OUTPUT-FILE" 2) - ("INPUT-PORT?" 1) - ("OUTPUT-PORT?" 1) - ("CURRENT-INPUT-PORT" 0) - ("CURRENT-OUTPUT-PORT" 0) - ("OPEN-INPUT-FILE" 1) - ("OPEN-OUTPUT-FILE" 1) - ("CLOSE-INPUT-PORT" 1) - ("CLOSE-OUTPUT-PORT" 1) - ("EOF-OBJECT?" 1) - ("READ" 0 1) - ("READ-CHAR" 0 1) - ("PEEK-CHAR" 0 1) - ("WRITE" 1 2) - ("DISPLAY" 1 2) - ("NEWLINE" 0 1) - ("WRITE-CHAR" 1 2)))) -(define (parse-program program env module-name proc) - (define (parse-prog program env lst proc) - (if (null? program) - (proc (reverse lst) env) - (let ((source (car program))) - (cond ((macro-expr? source env) - (parse-prog - (cons (macro-expand source env) (cdr program)) - env - lst - proc)) - ((begin-defs-expr? source) - (parse-prog - (append (begin-defs-body source) (cdr program)) - env - lst - proc)) - ((include-expr? source) - (if *ptree-port* (display " " *ptree-port*)) - (let ((x (file->sources* - (include-filename source) - *ptree-port* - (source-locat source)))) - (if *ptree-port* (newline *ptree-port*)) - (parse-prog (append x (cdr program)) env lst proc))) - ((define-macro-expr? source env) - (if *ptree-port* - (begin - (display " \"macro\"" *ptree-port*) - (newline *ptree-port*))) - (parse-prog (cdr program) (add-macro source env) lst proc)) - ((declare-expr? source) - (if *ptree-port* - (begin - (display " \"decl\"" *ptree-port*) - (newline *ptree-port*))) - (parse-prog - (cdr program) - (add-declarations source env) - lst - proc)) - ((define-expr? source env) - (let* ((var** (definition-variable source)) - (var* (source-code var**)) - (var (env-lookup-var env var* var**))) - (if *ptree-port* - (begin - (display " " *ptree-port*) - (display (var-name var) *ptree-port*) - (newline *ptree-port*))) - (let ((node (pt (definition-value source) env 'true))) - (set-prc-names! (list var) (list node)) - (parse-prog - (cdr program) - env - (cons (cons (new-def source - (env-declarations env) - var - node) - env) - lst) - proc)))) - ((c-declaration-expr? source) - (if *ptree-port* - (begin - (display " \"c-decl\"" *ptree-port*) - (newline *ptree-port*))) - (add-c-declaration (source-code (cadr (source-code source)))) - (parse-prog (cdr program) env lst proc)) - ((c-init-expr? source) - (if *ptree-port* - (begin - (display " \"c-init\"" *ptree-port*) - (newline *ptree-port*))) - (add-c-init (source-code (cadr (source-code source)))) - (parse-prog (cdr program) env lst proc)) - (else - (if *ptree-port* - (begin - (display " \"expr\"" *ptree-port*) - (newline *ptree-port*))) - (parse-prog - (cdr program) - env - (cons (cons (pt source env 'true) env) lst) - proc)))))) - (if *ptree-port* - (begin (display "Parsing:" *ptree-port*) (newline *ptree-port*))) - (c-interface-begin module-name) - (parse-prog - program - env - '() - (lambda (lst env) - (if *ptree-port* (newline *ptree-port*)) - (proc lst env (c-interface-end))))) -(define (c-interface-begin module-name) - (set! c-interface-module-name module-name) - (set! c-interface-proc-count 0) - (set! c-interface-decls '()) - (set! c-interface-procs '()) - (set! c-interface-inits '()) - #f) -(define (c-interface-end) - (let ((i (make-c-intf - (reverse c-interface-decls) - (reverse c-interface-procs) - (reverse c-interface-inits)))) - (set! c-interface-module-name #f) - (set! c-interface-proc-count #f) - (set! c-interface-decls #f) - (set! c-interface-procs #f) - (set! c-interface-inits #f) - i)) -(define c-interface-module-name #f) -(define c-interface-proc-count #f) -(define c-interface-decls #f) -(define c-interface-procs #f) -(define c-interface-inits #f) -(define (make-c-intf decls procs inits) (vector decls procs inits)) -(define (c-intf-decls c-intf) (vector-ref c-intf 0)) -(define (c-intf-decls-set! c-intf x) (vector-set! c-intf 0 x)) -(define (c-intf-procs c-intf) (vector-ref c-intf 1)) -(define (c-intf-procs-set! c-intf x) (vector-set! c-intf 1 x)) -(define (c-intf-inits c-intf) (vector-ref c-intf 2)) -(define (c-intf-inits-set! c-intf x) (vector-set! c-intf 2 x)) -(define (c-declaration-expr? source) - (and (mymatch **c-declaration-sym 1 source) - (let ((code (source-code source))) - (or (string? (source-code (cadr code))) - (pt-syntax-error - source - "Argument to '##c-declaration' must be a string"))))) -(define (c-init-expr? source) - (and (mymatch **c-init-sym 1 source) - (let ((code (source-code source))) - (or (string? (source-code (cadr code))) - (pt-syntax-error - source - "Argument to '##c-init' must be a string"))))) -(define (c-procedure-expr? source) - (and (mymatch **c-procedure-sym 3 source) - (let ((code (source-code source))) - (if (not (string? (source-code (cadddr code)))) - (pt-syntax-error - source - "Last argument to '##c-procedure' must be a string") - (check-arg-and-result-types source (cadr code) (caddr code)))))) -(define scheme-to-c-notation - (list (list void-sym "VOID" "void") - (list char-sym "CHAR" "char") - (list signed-char-sym "SCHAR" "signed char") - (list unsigned-char-sym "UCHAR" "unsigned char") - (list short-sym "SHORT" "short") - (list unsigned-short-sym "USHORT" "unsigned short") - (list int-sym "INT" "int") - (list unsigned-int-sym "UINT" "unsigned int") - (list long-sym "LONG" "long") - (list unsigned-long-sym "ULONG" "unsigned long") - (list float-sym "FLOAT" "float") - (list double-sym "DOUBLE" "double") - (list pointer-sym "POINTER" "void*") - (list boolean-sym "BOOLEAN" "int") - (list string-sym "STRING" "char*") - (list scheme-object-sym "SCMOBJ" "long"))) -(define (convert-type typ) (if (assq typ scheme-to-c-notation) typ #f)) -(define (check-arg-and-result-types source arg-typs-source res-typ-source) - (let ((arg-typs (source-code arg-typs-source)) - (res-typ (source-code res-typ-source))) - (let ((res-type (convert-type res-typ))) - (if (not res-type) - (pt-syntax-error res-typ-source "Invalid result type") - (if (not (proper-length arg-typs)) - (pt-syntax-error - arg-typs-source - "Ill-terminated argument type list") - (let loop ((lst arg-typs)) - (if (pair? lst) - (let* ((arg-typ (source-code (car lst))) - (arg-type (convert-type arg-typ))) - (if (or (not arg-type) (eq? arg-type void-sym)) - (pt-syntax-error (car lst) "Invalid argument type") - (loop (cdr lst)))) - #t))))))) -(define (add-c-declaration declaration-string) - (set! c-interface-decls (cons declaration-string c-interface-decls)) - #f) -(define (add-c-init initialization-code-string) - (set! c-interface-inits (cons initialization-code-string c-interface-inits)) - #f) -(define (add-c-proc scheme-name c-name arity def) - (set! c-interface-procs - (cons (vector scheme-name c-name arity def) c-interface-procs)) - #f) -(define (pt-c-procedure source env use) - (let* ((code (source-code source)) - (name (build-c-procedure - (map source-code (source-code (cadr code))) - (source-code (caddr code)) - (source-code (cadddr code)))) - (decl (env-declarations env))) - (new-ref source decl (env-lookup-global-var env (string->symbol name))))) -(define (build-c-procedure argument-types result-type proc-name-or-code) - (define proc-name? - (let loop ((i (- (string-length proc-name-or-code) 1))) - (if (>= i 0) - (let ((c (string-ref proc-name-or-code i))) - (if (or (char-alphabetic? c) (char=? c #\_)) (loop (- i 1)) #f)) - #t))) - (define nl (string #\newline)) - (define undefined-value "UND") - (define scheme-arg-prefix "ARG") - (define scheme-result-name "RESULT") - (define c-arg-prefix "arg") - (define c-result-name "result") - (define scheme-to-c-prefix "SCMOBJ_TO_") - (define c-to-scheme-suffix "_TO_SCMOBJ") - (define (c-type-name typ) (cadr (assq typ scheme-to-c-notation))) - (define (c-type-decl typ) (caddr (assq typ scheme-to-c-notation))) - (define (listify strings) - (if (null? strings) - "" - (string-append - (car strings) - (apply string-append - (map (lambda (s) (string-append "," s)) (cdr strings)))))) - (define (scheme-arg-var t) - (string-append c-id-prefix scheme-arg-prefix (number->string (cdr t)))) - (define (c-arg-var t) - (string-append c-id-prefix c-arg-prefix (number->string (cdr t)))) - (define (make-c-procedure arg-types res-type) - (define (make-arg-decl) - (apply string-append - (map (lambda (t) - (string-append - (c-type-decl (car t)) - " " - (c-arg-var t) - ";" - nl)) - arg-types))) - (define (make-conversions) - (if (not (null? arg-types)) - (let loop ((lst arg-types) (str (string-append "if (" nl))) - (if (null? lst) - (string-append str " )" nl) - (let ((t (car lst)) (rest (cdr lst))) - (loop rest - (string-append - str - " " - c-id-prefix - scheme-to-c-prefix - (c-type-name (car t)) - "(" - (scheme-arg-var t) - "," - (c-arg-var t) - ")" - (if (null? rest) "" " &&") - nl))))) - "")) - (define (make-body) - (if proc-name? - (let* ((param-list (listify (map c-arg-var arg-types))) - (call (string-append proc-name-or-code "(" param-list ")"))) - (if (eq? res-type void-sym) - (string-append - "{" - nl - call - ";" - nl - c-id-prefix - scheme-result-name - " = " - c-id-prefix - undefined-value - ";" - nl - "}" - nl) - (string-append - c-id-prefix - (c-type-name res-type) - c-to-scheme-suffix - "(" - call - "," - c-id-prefix - scheme-result-name - ");" - nl))) - (if (eq? res-type void-sym) - (string-append - "{" - nl - proc-name-or-code - nl - c-id-prefix - scheme-result-name - " = " - c-id-prefix - undefined-value - ";" - nl - "}" - nl) - (string-append - "{" - nl - proc-name-or-code - nl - c-id-prefix - (c-type-name res-type) - c-to-scheme-suffix - "(" - c-id-prefix - c-result-name - "," - c-id-prefix - scheme-result-name - ");" - nl - "}" - nl)))) - (let* ((index (number->string c-interface-proc-count)) - (scheme-name (string-append "#!" c-interface-module-name "#" index)) - (c-name (string-append c-id-prefix (scheme-id->c-id scheme-name))) - (arity (length argument-types)) - (def (string-append - (if (or proc-name? (eq? res-type void-sym)) - "" - (string-append - (c-type-decl res-type) - " " - c-id-prefix - c-result-name - ";" - nl)) - (make-arg-decl) - (make-conversions) - (make-body)))) - (set! c-interface-proc-count (+ c-interface-proc-count 1)) - (add-c-proc scheme-name c-name arity def) - scheme-name)) - (let loop ((i 1) (lst1 argument-types) (lst2 '())) - (if (pair? lst1) - (loop (+ i 1) (cdr lst1) (cons (cons (car lst1) i) lst2)) - (make-c-procedure (reverse lst2) result-type)))) -(define (scheme-id->c-id s) - (define (hex->char i) (string-ref "0123456789abcdef" i)) - (let loop ((i (- (string-length s) 1)) (l '())) - (if (>= i 0) - (let ((c (string-ref s i))) - (cond ((or (char-alphabetic? c) (char-numeric? c)) - (loop (- i 1) (cons c l))) - ((char=? c #\_) (loop (- i 1) (cons c (cons c l)))) - (else - (let ((n (character-encoding c))) - (loop (- i 1) - (cons #\_ - (cons (hex->char (quotient n 16)) - (cons (hex->char (modulo n 16)) l)))))))) - (lst->string l)))) -(define (pt-syntax-error source msg . args) - (apply compiler-user-error - (cons (source-locat source) - (cons (string-append "Syntax error -- " msg) args)))) -(define (pt source env use) - (cond ((macro-expr? source env) (pt (macro-expand source env) env use)) - ((self-eval-expr? source) (pt-self-eval source env use)) - ((quote-expr? source) (pt-quote source env use)) - ((quasiquote-expr? source) (pt-quasiquote source env use)) - ((unquote-expr? source) - (pt-syntax-error source "Ill-placed 'unquote'")) - ((unquote-splicing-expr? source) - (pt-syntax-error source "Ill-placed 'unquote-splicing'")) - ((var-expr? source env) (pt-var source env use)) - ((set!-expr? source env) (pt-set! source env use)) - ((lambda-expr? source env) (pt-lambda source env use)) - ((if-expr? source) (pt-if source env use)) - ((cond-expr? source) (pt-cond source env use)) - ((and-expr? source) (pt-and source env use)) - ((or-expr? source) (pt-or source env use)) - ((case-expr? source) (pt-case source env use)) - ((let-expr? source env) (pt-let source env use)) - ((let*-expr? source env) (pt-let* source env use)) - ((letrec-expr? source env) (pt-letrec source env use)) - ((begin-expr? source) (pt-begin source env use)) - ((do-expr? source env) (pt-do source env use)) - ((define-expr? source env) - (pt-syntax-error source "Ill-placed 'define'")) - ((delay-expr? source env) (pt-delay source env use)) - ((future-expr? source env) (pt-future source env use)) - ((define-macro-expr? source env) - (pt-syntax-error source "Ill-placed '##define-macro'")) - ((begin-defs-expr? source) - (pt-syntax-error source "Ill-placed 'begin' style definitions")) - ((declare-expr? source) - (pt-syntax-error source "Ill-placed '##declare'")) - ((c-declaration-expr? source) - (pt-syntax-error source "Ill-placed '##c-declaration'")) - ((c-init-expr? source) - (pt-syntax-error source "Ill-placed '##c-init'")) - ((c-procedure-expr? source) (pt-c-procedure source env use)) - ((combination-expr? source) (pt-combination source env use)) - (else (compiler-internal-error "pt, unknown expression type" source)))) -(define (macro-expand source env) - (let ((code (source-code source))) - (expression->source - (apply (cdr (env-lookup-macro env (source-code (car code)))) - (cdr (source->expression source))) - source))) -(define (pt-self-eval source env use) - (let ((val (source->expression source))) - (if (eq? use 'none) - (new-cst source (env-declarations env) undef-object) - (new-cst source (env-declarations env) val)))) -(define (pt-quote source env use) - (let ((code (source-code source))) - (if (eq? use 'none) - (new-cst source (env-declarations env) undef-object) - (new-cst source - (env-declarations env) - (source->expression (cadr code)))))) -(define (pt-quasiquote source env use) - (let ((code (source-code source))) (pt-quasiquotation (cadr code) 1 env))) -(define (pt-quasiquotation form level env) - (cond ((= level 0) (pt form env 'true)) - ((quasiquote-expr? form) - (pt-quasiquotation-list form (source-code form) (+ level 1) env)) - ((unquote-expr? form) - (if (= level 1) - (pt (cadr (source-code form)) env 'true) - (pt-quasiquotation-list form (source-code form) (- level 1) env))) - ((unquote-splicing-expr? form) - (if (= level 1) - (pt-syntax-error form "Ill-placed 'unquote-splicing'") - (pt-quasiquotation-list form (source-code form) (- level 1) env))) - ((pair? (source-code form)) - (pt-quasiquotation-list form (source-code form) level env)) - ((vector? (source-code form)) - (vector-form - form - (pt-quasiquotation-list - form - (vector->lst (source-code form)) - level - env) - env)) - (else - (new-cst form (env-declarations env) (source->expression form))))) -(define (pt-quasiquotation-list form l level env) - (cond ((pair? l) - (if (and (unquote-splicing-expr? (car l)) (= level 1)) - (let ((x (pt (cadr (source-code (car l))) env 'true))) - (if (null? (cdr l)) - x - (append-form - (car l) - x - (pt-quasiquotation-list form (cdr l) 1 env) - env))) - (cons-form - form - (pt-quasiquotation (car l) level env) - (pt-quasiquotation-list form (cdr l) level env) - env))) - ((null? l) (new-cst form (env-declarations env) '())) - (else (pt-quasiquotation l level env)))) -(define (append-form source ptree1 ptree2 env) - (cond ((and (cst? ptree1) (cst? ptree2)) - (new-cst source - (env-declarations env) - (append (cst-val ptree1) (cst-val ptree2)))) - ((and (cst? ptree2) (null? (cst-val ptree2))) ptree1) - (else - (new-call* - source - (add-not-safe (env-declarations env)) - (new-ref-extended-bindings source **quasi-append-sym env) - (list ptree1 ptree2))))) -(define (cons-form source ptree1 ptree2 env) - (cond ((and (cst? ptree1) (cst? ptree2)) - (new-cst source - (env-declarations env) - (cons (cst-val ptree1) (cst-val ptree2)))) - ((and (cst? ptree2) (null? (cst-val ptree2))) - (new-call* - source - (add-not-safe (env-declarations env)) - (new-ref-extended-bindings source **quasi-list-sym env) - (list ptree1))) - (else - (new-call* - source - (add-not-safe (env-declarations env)) - (new-ref-extended-bindings source **quasi-cons-sym env) - (list ptree1 ptree2))))) -(define (vector-form source ptree env) - (if (cst? ptree) - (new-cst source (env-declarations env) (lst->vector (cst-val ptree))) - (new-call* - source - (add-not-safe (env-declarations env)) - (new-ref-extended-bindings source **quasi-list->vector-sym env) - (list ptree)))) -(define (pt-var source env use) - (if (eq? use 'none) - (new-cst source (env-declarations env) undef-object) - (new-ref source - (env-declarations env) - (env-lookup-var env (source-code source) source)))) -(define (pt-set! source env use) - (let ((code (source-code source))) - (new-set source - (env-declarations env) - (env-lookup-var env (source-code (cadr code)) (cadr code)) - (pt (caddr code) env 'true)))) -(define (pt-lambda source env use) - (let ((code (source-code source))) - (define (new-params parms) - (cond ((pair? parms) - (let* ((parm* (car parms)) - (parm (source-code parm*)) - (p* (if (pair? parm) (car parm) parm*))) - (cons (make-var (source-code p*) #t (set-empty) (set-empty) p*) - (new-params (cdr parms))))) - ((null? parms) '()) - (else - (list (make-var - (source-code parms) - #t - (set-empty) - (set-empty) - parms))))) - (define (min-params parms) - (let loop ((l parms) (n 0)) - (if (pair? l) - (if (pair? (source-code (car l))) n (loop (cdr l) (+ n 1))) - n))) - (define (rest-param? parms) - (if (pair? parms) (rest-param? (cdr parms)) (not (null? parms)))) - (define (optionals parms source body env) - (if (pair? parms) - (let* ((parm* (car parms)) (parm (source-code parm*))) - (if (and (pair? parm) (length? parm 2)) - (let* ((var (car parm)) - (vars (new-variables (list var))) - (decl (env-declarations env))) - (new-call* - parm* - decl - (new-prc parm* - decl - #f - 1 - #f - vars - (optionals - (cdr parms) - source - body - (env-frame env vars))) - (list (new-tst parm* - decl - (new-call* - parm* - decl - (new-ref-extended-bindings - parm* - **unassigned?-sym - env) - (list (new-ref parm* - decl - (env-lookup-var - env - (source-code var) - var)))) - (pt (cadr parm) env 'true) - (new-ref parm* - decl - (env-lookup-var - env - (source-code var) - var)))))) - (optionals (cdr parms) source body env))) - (pt-body source body env 'true))) - (if (eq? use 'none) - (new-cst source (env-declarations env) undef-object) - (let* ((parms (source->parms (cadr code))) (frame (new-params parms))) - (new-prc source - (env-declarations env) - #f - (min-params parms) - (rest-param? parms) - frame - (optionals - parms - source - (cddr code) - (env-frame env frame))))))) -(define (source->parms source) - (let ((x (source-code source))) (if (or (pair? x) (null? x)) x source))) -(define (pt-body source body env use) - (define (letrec-defines vars vals envs body env) - (cond ((null? body) - (pt-syntax-error - source - "Body must contain at least one evaluable expression")) - ((macro-expr? (car body) env) - (letrec-defines - vars - vals - envs - (cons (macro-expand (car body) env) (cdr body)) - env)) - ((begin-defs-expr? (car body)) - (letrec-defines - vars - vals - envs - (append (begin-defs-body (car body)) (cdr body)) - env)) - ((include-expr? (car body)) - (if *ptree-port* (display " " *ptree-port*)) - (let ((x (file->sources* - (include-filename (car body)) - *ptree-port* - (source-locat (car body))))) - (if *ptree-port* (newline *ptree-port*)) - (letrec-defines vars vals envs (append x (cdr body)) env))) - ((define-expr? (car body) env) - (let* ((var** (definition-variable (car body))) - (var* (source-code var**)) - (var (env-define-var env var* var**))) - (letrec-defines - (cons var vars) - (cons (definition-value (car body)) vals) - (cons env envs) - (cdr body) - env))) - ((declare-expr? (car body)) - (letrec-defines - vars - vals - envs - (cdr body) - (add-declarations (car body) env))) - ((define-macro-expr? (car body) env) - (letrec-defines - vars - vals - envs - (cdr body) - (add-macro (car body) env))) - ((c-declaration-expr? (car body)) - (add-c-declaration (source-code (cadr (source-code (car body))))) - (letrec-defines vars vals envs (cdr body) env)) - ((c-init-expr? (car body)) - (add-c-init (source-code (cadr (source-code (car body))))) - (letrec-defines vars vals envs (cdr body) env)) - ((null? vars) (pt-sequence source body env use)) - (else - (let ((vars* (reverse vars))) - (let loop ((vals* '()) (l1 vals) (l2 envs)) - (if (not (null? l1)) - (loop (cons (pt (car l1) (car l2) 'true) vals*) - (cdr l1) - (cdr l2)) - (pt-recursive-let source vars* vals* body env use))))))) - (letrec-defines '() '() '() body (env-frame env '()))) -(define (pt-sequence source seq env use) - (if (length? seq 1) - (pt (car seq) env use) - (new-seq source - (env-declarations env) - (pt (car seq) env 'none) - (pt-sequence source (cdr seq) env use)))) -(define (pt-if source env use) - (let ((code (source-code source))) - (new-tst source - (env-declarations env) - (pt (cadr code) env 'pred) - (pt (caddr code) env use) - (if (length? code 3) - (new-cst source (env-declarations env) undef-object) - (pt (cadddr code) env use))))) -(define (pt-cond source env use) - (define (pt-clauses clauses) - (if (length? clauses 0) - (new-cst source (env-declarations env) undef-object) - (let* ((clause* (car clauses)) (clause (source-code clause*))) - (cond ((eq? (source-code (car clause)) else-sym) - (pt-sequence clause* (cdr clause) env use)) - ((length? clause 1) - (new-disj - clause* - (env-declarations env) - (pt (car clause) env (if (eq? use 'true) 'true 'pred)) - (pt-clauses (cdr clauses)))) - ((eq? (source-code (cadr clause)) =>-sym) - (new-disj-call - clause* - (env-declarations env) - (pt (car clause) env 'true) - (pt (caddr clause) env 'true) - (pt-clauses (cdr clauses)))) - (else - (new-tst clause* - (env-declarations env) - (pt (car clause) env 'pred) - (pt-sequence clause* (cdr clause) env use) - (pt-clauses (cdr clauses)))))))) - (pt-clauses (cdr (source-code source)))) -(define (pt-and source env use) - (define (pt-exprs exprs) - (cond ((length? exprs 0) (new-cst source (env-declarations env) #t)) - ((length? exprs 1) (pt (car exprs) env use)) - (else - (new-conj - (car exprs) - (env-declarations env) - (pt (car exprs) env (if (eq? use 'true) 'true 'pred)) - (pt-exprs (cdr exprs)))))) - (pt-exprs (cdr (source-code source)))) -(define (pt-or source env use) - (define (pt-exprs exprs) - (cond ((length? exprs 0) - (new-cst source (env-declarations env) false-object)) - ((length? exprs 1) (pt (car exprs) env use)) - (else - (new-disj - (car exprs) - (env-declarations env) - (pt (car exprs) env (if (eq? use 'true) 'true 'pred)) - (pt-exprs (cdr exprs)))))) - (pt-exprs (cdr (source-code source)))) -(define (pt-case source env use) - (let ((code (source-code source)) (temp (new-temps source '(temp)))) - (define (pt-clauses clauses) - (if (length? clauses 0) - (new-cst source (env-declarations env) undef-object) - (let* ((clause* (car clauses)) (clause (source-code clause*))) - (if (eq? (source-code (car clause)) else-sym) - (pt-sequence clause* (cdr clause) env use) - (new-tst clause* - (env-declarations env) - (new-call* - clause* - (add-not-safe (env-declarations env)) - (new-ref-extended-bindings - clause* - **case-memv-sym - env) - (list (new-ref clause* - (env-declarations env) - (car temp)) - (new-cst (car clause) - (env-declarations env) - (source->expression (car clause))))) - (pt-sequence clause* (cdr clause) env use) - (pt-clauses (cdr clauses))))))) - (new-call* - source - (env-declarations env) - (new-prc source - (env-declarations env) - #f - 1 - #f - temp - (pt-clauses (cddr code))) - (list (pt (cadr code) env 'true))))) -(define (pt-let source env use) - (let ((code (source-code source))) - (if (bindable-var? (cadr code) env) - (let* ((self (new-variables (list (cadr code)))) - (bindings (map source-code (source-code (caddr code)))) - (vars (new-variables (map car bindings))) - (vals (map (lambda (x) (pt (cadr x) env 'true)) bindings)) - (env (env-frame (env-frame env vars) self)) - (self-proc - (list (new-prc source - (env-declarations env) - #f - (length vars) - #f - vars - (pt-body source (cdddr code) env use))))) - (set-prc-names! self self-proc) - (set-prc-names! vars vals) - (new-call* - source - (env-declarations env) - (new-prc source - (env-declarations env) - #f - 1 - #f - self - (new-call* - source - (env-declarations env) - (new-ref source (env-declarations env) (car self)) - vals)) - self-proc)) - (if (null? (source-code (cadr code))) - (pt-body source (cddr code) env use) - (let* ((bindings (map source-code (source-code (cadr code)))) - (vars (new-variables (map car bindings))) - (vals (map (lambda (x) (pt (cadr x) env 'true)) bindings)) - (env (env-frame env vars))) - (set-prc-names! vars vals) - (new-call* - source - (env-declarations env) - (new-prc source - (env-declarations env) - #f - (length vars) - #f - vars - (pt-body source (cddr code) env use)) - vals)))))) -(define (pt-let* source env use) - (let ((code (source-code source))) - (define (pt-bindings bindings env use) - (if (null? bindings) - (pt-body source (cddr code) env use) - (let* ((binding* (car bindings)) - (binding (source-code binding*)) - (vars (new-variables (list (car binding)))) - (vals (list (pt (cadr binding) env 'true))) - (env (env-frame env vars))) - (set-prc-names! vars vals) - (new-call* - binding* - (env-declarations env) - (new-prc binding* - (env-declarations env) - #f - 1 - #f - vars - (pt-bindings (cdr bindings) env use)) - vals)))) - (pt-bindings (source-code (cadr code)) env use))) -(define (pt-letrec source env use) - (let* ((code (source-code source)) - (bindings (map source-code (source-code (cadr code)))) - (vars* (new-variables (map car bindings))) - (env* (env-frame env vars*))) - (pt-recursive-let - source - vars* - (map (lambda (x) (pt (cadr x) env* 'true)) bindings) - (cddr code) - env* - use))) -(define (pt-recursive-let source vars vals body env use) - (define (dependency-graph vars vals) - (define (dgraph vars* vals*) - (if (null? vars*) - (set-empty) - (let ((var (car vars*)) (val (car vals*))) - (set-adjoin - (dgraph (cdr vars*) (cdr vals*)) - (make-gnode - var - (set-intersection (list->set vars) (free-variables val))))))) - (dgraph vars vals)) - (define (val-of var) - (list-ref vals (- (length vars) (length (memq var vars))))) - (define (bind-in-order order) - (if (null? order) - (pt-body source body env use) - (let* ((vars-set (car order)) (vars (set->list vars-set))) - (let loop1 ((l (reverse vars)) - (vars-b '()) - (vals-b '()) - (vars-a '())) - (if (not (null? l)) - (let* ((var (car l)) (val (val-of var))) - (if (or (prc? val) - (set-empty? - (set-intersection (free-variables val) vars-set))) - (loop1 (cdr l) - (cons var vars-b) - (cons val vals-b) - vars-a) - (loop1 (cdr l) vars-b vals-b (cons var vars-a)))) - (let* ((result1 (let loop2 ((l vars-a)) - (if (not (null? l)) - (let* ((var (car l)) (val (val-of var))) - (new-seq source - (env-declarations env) - (new-set source - (env-declarations - env) - var - val) - (loop2 (cdr l)))) - (bind-in-order (cdr order))))) - (result2 (if (null? vars-b) - result1 - (new-call* - source - (env-declarations env) - (new-prc source - (env-declarations env) - #f - (length vars-b) - #f - vars-b - result1) - vals-b))) - (result3 (if (null? vars-a) - result2 - (new-call* - source - (env-declarations env) - (new-prc source - (env-declarations env) - #f - (length vars-a) - #f - vars-a - result2) - (map (lambda (var) - (new-cst source - (env-declarations env) - undef-object)) - vars-a))))) - result3)))))) - (set-prc-names! vars vals) - (bind-in-order - (topological-sort (transitive-closure (dependency-graph vars vals))))) -(define (pt-begin source env use) - (pt-sequence source (cdr (source-code source)) env use)) -(define (pt-do source env use) - (let* ((code (source-code source)) - (loop (new-temps source '(loop))) - (bindings (map source-code (source-code (cadr code)))) - (vars (new-variables (map car bindings))) - (init (map (lambda (x) (pt (cadr x) env 'true)) bindings)) - (env (env-frame env vars)) - (step (map (lambda (x) - (pt (if (length? x 2) (car x) (caddr x)) env 'true)) - bindings)) - (exit (source-code (caddr code)))) - (set-prc-names! vars init) - (new-call* - source - (env-declarations env) - (new-prc source - (env-declarations env) - #f - 1 - #f - loop - (new-call* - source - (env-declarations env) - (new-ref source (env-declarations env) (car loop)) - init)) - (list (new-prc source - (env-declarations env) - #f - (length vars) - #f - vars - (new-tst source - (env-declarations env) - (pt (car exit) env 'pred) - (if (length? exit 1) - (new-cst (caddr code) - (env-declarations env) - undef-object) - (pt-sequence (caddr code) (cdr exit) env use)) - (if (length? code 3) - (new-call* - source - (env-declarations env) - (new-ref source - (env-declarations env) - (car loop)) - step) - (new-seq source - (env-declarations env) - (pt-sequence - source - (cdddr code) - env - 'none) - (new-call* - source - (env-declarations env) - (new-ref source - (env-declarations env) - (car loop)) - step))))))))) -(define (pt-combination source env use) - (let* ((code (source-code source)) - (oper (pt (car code) env 'true)) - (decl (node-decl oper))) - (new-call* - source - (env-declarations env) - oper - (map (lambda (x) (pt x env 'true)) (cdr code))))) -(define (pt-delay source env use) - (let ((code (source-code source))) - (new-call* - source - (add-not-safe (env-declarations env)) - (new-ref-extended-bindings source **make-placeholder-sym env) - (list (new-prc source - (env-declarations env) - #f - 0 - #f - '() - (pt (cadr code) env 'true)))))) -(define (pt-future source env use) - (let ((decl (env-declarations env)) (code (source-code source))) - (new-fut source decl (pt (cadr code) env 'true)))) -(define (self-eval-expr? source) - (let ((code (source-code source))) - (and (not (pair? code)) (not (symbol-object? code))))) -(define (quote-expr? source) (mymatch quote-sym 1 source)) -(define (quasiquote-expr? source) (mymatch quasiquote-sym 1 source)) -(define (unquote-expr? source) (mymatch unquote-sym 1 source)) -(define (unquote-splicing-expr? source) - (mymatch unquote-splicing-sym 1 source)) -(define (var-expr? source env) - (let ((code (source-code source))) - (and (symbol-object? code) - (not-keyword source env code) - (not-macro source env code)))) -(define (not-macro source env name) - (if (env-lookup-macro env name) - (pt-syntax-error source "Macro name can't be used as a variable:" name) - #t)) -(define (bindable-var? source env) - (let ((code (source-code source))) - (and (symbol-object? code) (not-keyword source env code)))) -(define (not-keyword source env name) - (if (or (memq name common-keywords) - (memq name - (dialect-specific-keywords - (scheme-dialect (env-declarations env))))) - (pt-syntax-error - source - "Predefined keyword can't be used as a variable:" - name) - #t)) -(define (set!-expr? source env) - (and (mymatch set!-sym 2 source) - (var-expr? (cadr (source-code source)) env))) -(define (lambda-expr? source env) - (and (mymatch lambda-sym -2 source) - (proper-parms? (source->parms (cadr (source-code source))) env))) -(define (if-expr? source) - (and (mymatch if-sym -2 source) - (or (<= (length (source-code source)) 4) - (pt-syntax-error source "Ill-formed special form" if-sym)))) -(define (cond-expr? source) - (and (mymatch cond-sym -1 source) (proper-clauses? source))) -(define (and-expr? source) (mymatch and-sym 0 source)) -(define (or-expr? source) (mymatch or-sym 0 source)) -(define (case-expr? source) - (and (mymatch case-sym -2 source) (proper-case-clauses? source))) -(define (let-expr? source env) - (and (mymatch let-sym -2 source) - (let ((code (source-code source))) - (if (bindable-var? (cadr code) env) - (and (proper-bindings? (caddr code) #t env) - (or (> (length code) 3) - (pt-syntax-error source "Ill-formed named 'let'"))) - (proper-bindings? (cadr code) #t env))))) -(define (let*-expr? source env) - (and (mymatch let*-sym -2 source) - (proper-bindings? (cadr (source-code source)) #f env))) -(define (letrec-expr? source env) - (and (mymatch letrec-sym -2 source) - (proper-bindings? (cadr (source-code source)) #t env))) -(define (begin-expr? source) (mymatch begin-sym -1 source)) -(define (do-expr? source env) - (and (mymatch do-sym -2 source) - (proper-do-bindings? source env) - (proper-do-exit? source))) -(define (define-expr? source env) - (and (mymatch define-sym -1 source) - (proper-definition? source env) - (let ((v (definition-variable source))) - (not-macro v env (source-code v))))) -(define (combination-expr? source) - (let ((length (proper-length (source-code source)))) - (if length - (or (> length 0) (pt-syntax-error source "Ill-formed procedure call")) - (pt-syntax-error source "Ill-terminated procedure call")))) -(define (delay-expr? source env) - (and (not (eq? (scheme-dialect (env-declarations env)) ieee-scheme-sym)) - (mymatch delay-sym 1 source))) -(define (future-expr? source env) - (and (eq? (scheme-dialect (env-declarations env)) multilisp-sym) - (mymatch future-sym 1 source))) -(define (macro-expr? source env) - (let ((code (source-code source))) - (and (pair? code) - (symbol-object? (source-code (car code))) - (let ((macr (env-lookup-macro env (source-code (car code))))) - (and macr - (let ((len (proper-length (cdr code)))) - (if len - (let ((len* (+ len 1)) (size (car macr))) - (or (if (> size 0) (= len* size) (>= len* (- size))) - (pt-syntax-error source "Ill-formed macro form"))) - (pt-syntax-error - source - "Ill-terminated macro form")))))))) -(define (define-macro-expr? source env) - (and (mymatch **define-macro-sym -1 source) (proper-definition? source env))) -(define (declare-expr? source) (mymatch **declare-sym -1 source)) -(define (include-expr? source) (mymatch **include-sym 1 source)) -(define (begin-defs-expr? source) (mymatch begin-sym 0 source)) -(define (mymatch keyword size source) - (let ((code (source-code source))) - (and (pair? code) - (eq? (source-code (car code)) keyword) - (let ((length (proper-length (cdr code)))) - (if length - (or (if (> size 0) (= length size) (>= length (- size))) - (pt-syntax-error source "Ill-formed special form" keyword)) - (pt-syntax-error - source - "Ill-terminated special form" - keyword)))))) -(define (proper-length l) - (define (length l n) - (cond ((pair? l) (length (cdr l) (+ n 1))) ((null? l) n) (else #f))) - (length l 0)) -(define (proper-definition? source env) - (let* ((code (source-code source)) - (pattern* (cadr code)) - (pattern (source-code pattern*)) - (body (cddr code))) - (cond ((bindable-var? pattern* env) - (cond ((length? body 0) #t) - ((length? body 1) #t) - (else (pt-syntax-error source "Ill-formed definition body")))) - ((pair? pattern) - (if (length? body 0) - (pt-syntax-error - source - "Body of a definition must have at least one expression")) - (if (bindable-var? (car pattern) env) - (proper-parms? (cdr pattern) env) - (pt-syntax-error - (car pattern) - "Procedure name must be an identifier"))) - (else (pt-syntax-error pattern* "Ill-formed definition pattern"))))) -(define (definition-variable def) - (let* ((code (source-code def)) (pattern (cadr code))) - (if (pair? (source-code pattern)) (car (source-code pattern)) pattern))) -(define (definition-value def) - (let ((code (source-code def)) (loc (source-locat def))) - (cond ((pair? (source-code (cadr code))) - (make-source - (cons (make-source lambda-sym loc) - (cons (parms->source (cdr (source-code (cadr code))) loc) - (cddr code))) - loc)) - ((null? (cddr code)) - (make-source - (list (make-source quote-sym loc) (make-source undef-object loc)) - loc)) - (else (caddr code))))) -(define (parms->source parms loc) - (if (or (pair? parms) (null? parms)) (make-source parms loc) parms)) -(define (proper-parms? parms env) - (define (proper-parms parms seen optional-seen) - (cond ((pair? parms) - (let* ((parm* (car parms)) (parm (source-code parm*))) - (cond ((pair? parm) - (if (eq? (scheme-dialect (env-declarations env)) - multilisp-sym) - (let ((length (proper-length parm))) - (if (or (eqv? length 1) (eqv? length 2)) - (let ((var (car parm))) - (if (bindable-var? var env) - (if (memq (source-code var) seen) - (pt-syntax-error - var - "Duplicate parameter in parameter list") - (proper-parms - (cdr parms) - (cons (source-code var) seen) - #t)) - (pt-syntax-error - var - "Parameter must be an identifier"))) - (pt-syntax-error - parm* - "Ill-formed optional parameter"))) - (pt-syntax-error - parm* - "optional parameters illegal in this dialect"))) - (optional-seen - (pt-syntax-error parm* "Optional parameter expected")) - ((bindable-var? parm* env) - (if (memq parm seen) - (pt-syntax-error - parm* - "Duplicate parameter in parameter list")) - (proper-parms (cdr parms) (cons parm seen) #f)) - (else - (pt-syntax-error - parm* - "Parameter must be an identifier"))))) - ((null? parms) #t) - ((bindable-var? parms env) - (if (memq (source-code parms) seen) - (pt-syntax-error parms "Duplicate parameter in parameter list") - #t)) - (else - (pt-syntax-error parms "Rest parameter must be an identifier")))) - (proper-parms parms '() #f)) -(define (proper-clauses? source) - (define (proper-clauses clauses) - (or (null? clauses) - (let* ((clause* (car clauses)) - (clause (source-code clause*)) - (length (proper-length clause))) - (if length - (if (>= length 1) - (if (eq? (source-code (car clause)) else-sym) - (cond ((= length 1) - (pt-syntax-error - clause* - "Else clause must have a body")) - ((not (null? (cdr clauses))) - (pt-syntax-error - clause* - "Else clause must be the last clause")) - (else (proper-clauses (cdr clauses)))) - (if (and (>= length 2) - (eq? (source-code (cadr clause)) =>-sym) - (not (= length 3))) - (pt-syntax-error - (cadr clause) - "'=>' must be followed by a single expression") - (proper-clauses (cdr clauses)))) - (pt-syntax-error clause* "Ill-formed 'cond' clause")) - (pt-syntax-error clause* "Ill-terminated 'cond' clause"))))) - (proper-clauses (cdr (source-code source)))) -(define (proper-case-clauses? source) - (define (proper-case-clauses clauses) - (or (null? clauses) - (let* ((clause* (car clauses)) - (clause (source-code clause*)) - (length (proper-length clause))) - (if length - (if (>= length 2) - (if (eq? (source-code (car clause)) else-sym) - (if (not (null? (cdr clauses))) - (pt-syntax-error - clause* - "Else clause must be the last clause") - (proper-case-clauses (cdr clauses))) - (begin - (proper-selector-list? (car clause)) - (proper-case-clauses (cdr clauses)))) - (pt-syntax-error - clause* - "A 'case' clause must have a selector list and a body")) - (pt-syntax-error clause* "Ill-terminated 'case' clause"))))) - (proper-case-clauses (cddr (source-code source)))) -(define (proper-selector-list? source) - (let* ((code (source-code source)) (length (proper-length code))) - (if length - (or (>= length 1) - (pt-syntax-error - source - "Selector list must contain at least one element")) - (pt-syntax-error source "Ill-terminated selector list")))) -(define (proper-bindings? bindings check-dupl? env) - (define (proper-bindings l seen) - (cond ((pair? l) - (let* ((binding* (car l)) (binding (source-code binding*))) - (if (eqv? (proper-length binding) 2) - (let ((var (car binding))) - (if (bindable-var? var env) - (if (and check-dupl? (memq (source-code var) seen)) - (pt-syntax-error - var - "Duplicate variable in bindings") - (proper-bindings - (cdr l) - (cons (source-code var) seen))) - (pt-syntax-error - var - "Binding variable must be an identifier"))) - (pt-syntax-error binding* "Ill-formed binding")))) - ((null? l) #t) - (else (pt-syntax-error bindings "Ill-terminated binding list")))) - (proper-bindings (source-code bindings) '())) -(define (proper-do-bindings? source env) - (let ((bindings (cadr (source-code source)))) - (define (proper-bindings l seen) - (cond ((pair? l) - (let* ((binding* (car l)) - (binding (source-code binding*)) - (length (proper-length binding))) - (if (or (eqv? length 2) (eqv? length 3)) - (let ((var (car binding))) - (if (bindable-var? var env) - (if (memq (source-code var) seen) - (pt-syntax-error - var - "Duplicate variable in bindings") - (proper-bindings - (cdr l) - (cons (source-code var) seen))) - (pt-syntax-error - var - "Binding variable must be an identifier"))) - (pt-syntax-error binding* "Ill-formed binding")))) - ((null? l) #t) - (else (pt-syntax-error bindings "Ill-terminated binding list")))) - (proper-bindings (source-code bindings) '()))) -(define (proper-do-exit? source) - (let* ((code (source-code (caddr (source-code source)))) - (length (proper-length code))) - (if length - (or (> length 0) (pt-syntax-error source "Ill-formed exit clause")) - (pt-syntax-error source "Ill-terminated exit clause")))) -(define (include-filename source) (source-code (cadr (source-code source)))) -(define (begin-defs-body source) (cdr (source-code source))) -(define (length? l n) - (cond ((null? l) (= n 0)) ((> n 0) (length? (cdr l) (- n 1))) (else #f))) -(define (transform-declaration source) - (let ((code (source-code source))) - (if (not (pair? code)) - (pt-syntax-error source "Ill-formed declaration") - (let* ((pos (not (eq? (source-code (car code)) not-sym))) - (x (if pos code (cdr code)))) - (if (not (pair? x)) - (pt-syntax-error source "Ill-formed declaration") - (let* ((id* (car x)) (id (source-code id*))) - (cond ((not (symbol-object? id)) - (pt-syntax-error - id* - "Declaration name must be an identifier")) - ((assq id flag-declarations) - (cond ((not pos) - (pt-syntax-error - id* - "Declaration can't be negated")) - ((null? (cdr x)) - (flag-decl - source - (cdr (assq id flag-declarations)) - id)) - (else - (pt-syntax-error - source - "Ill-formed declaration")))) - ((memq id parameterized-declarations) - (cond ((not pos) - (pt-syntax-error - id* - "Declaration can't be negated")) - ((eqv? (proper-length x) 2) - (parameterized-decl - source - id - (source->expression (cadr x)))) - (else - (pt-syntax-error - source - "Ill-formed declaration")))) - ((memq id boolean-declarations) - (if (null? (cdr x)) - (boolean-decl source id pos) - (pt-syntax-error source "Ill-formed declaration"))) - ((assq id namable-declarations) - (cond ((not pos) - (pt-syntax-error - id* - "Declaration can't be negated")) - (else - (namable-decl - source - (cdr (assq id namable-declarations)) - id - (map source->expression (cdr x)))))) - ((memq id namable-boolean-declarations) - (namable-boolean-decl - source - id - pos - (map source->expression (cdr x)))) - ((memq id namable-string-declarations) - (if (not (pair? (cdr x))) - (pt-syntax-error source "Ill-formed declaration") - (let* ((str* (cadr x)) (str (source-code str*))) - (cond ((not pos) - (pt-syntax-error - id* - "Declaration can't be negated")) - ((not (string? str)) - (pt-syntax-error str* "String expected")) - (else - (namable-string-decl - source - id - str - (map source->expression (cddr x)))))))) - (else (pt-syntax-error id* "Unknown declaration"))))))))) -(define (add-declarations source env) - (let loop ((l (cdr (source-code source))) (env env)) - (if (pair? l) - (loop (cdr l) (env-declare env (transform-declaration (car l)))) - env))) -(define (add-decl d decl) (env-declare decl d)) -(define (add-macro source env) - (define (form-size parms) - (let loop ((l parms) (n 1)) - (if (pair? l) (loop (cdr l) (+ n 1)) (if (null? l) n (- n))))) - (define (error-proc . msgs) - (apply compiler-user-error - (cons (source-locat source) (cons "(in macro body)" msgs)))) - (let ((var (definition-variable source)) (proc (definition-value source))) - (if (lambda-expr? proc env) - (env-macro - env - (source-code var) - (cons (form-size (source->parms (cadr (source-code proc)))) - (scheme-global-eval (source->expression proc) error-proc))) - (pt-syntax-error source "Macro value must be a lambda expression")))) -(define (ptree.begin! info-port) (set! *ptree-port* info-port) '()) -(define (ptree.end!) '()) -(define *ptree-port* '()) -(define (normalize-parse-tree ptree env) - (define (normalize ptree) - (let ((tree (assignment-convert (partial-evaluate ptree) env))) - (lambda-lift! tree) - tree)) - (if (def? ptree) - (begin - (node-children-set! ptree (list (normalize (def-val ptree)))) - ptree) - (normalize ptree))) -(define (partial-evaluate ptree) (pe ptree '())) -(define (pe ptree consts) - (cond ((cst? ptree) - (new-cst (node-source ptree) (node-decl ptree) (cst-val ptree))) - ((ref? ptree) - (let ((var (ref-var ptree))) - (var-refs-set! var (set-remove (var-refs var) ptree)) - (let ((x (assq var consts))) - (if x - (new-cst (node-source ptree) (node-decl ptree) (cdr x)) - (let ((y (global-val var))) - (if (and y (cst? y)) - (new-cst (node-source ptree) - (node-decl ptree) - (cst-val y)) - (new-ref (node-source ptree) - (node-decl ptree) - var))))))) - ((set? ptree) - (let ((var (set-var ptree)) (val (pe (set-val ptree) consts))) - (var-sets-set! var (set-remove (var-sets var) ptree)) - (new-set (node-source ptree) (node-decl ptree) var val))) - ((tst? ptree) - (let ((pre (pe (tst-pre ptree) consts))) - (if (cst? pre) - (let ((val (cst-val pre))) - (if (false-object? val) - (pe (tst-alt ptree) consts) - (pe (tst-con ptree) consts))) - (new-tst (node-source ptree) - (node-decl ptree) - pre - (pe (tst-con ptree) consts) - (pe (tst-alt ptree) consts))))) - ((conj? ptree) - (let ((pre (pe (conj-pre ptree) consts))) - (if (cst? pre) - (let ((val (cst-val pre))) - (if (false-object? val) pre (pe (conj-alt ptree) consts))) - (new-conj - (node-source ptree) - (node-decl ptree) - pre - (pe (conj-alt ptree) consts))))) - ((disj? ptree) - (let ((pre (pe (disj-pre ptree) consts))) - (if (cst? pre) - (let ((val (cst-val pre))) - (if (false-object? val) (pe (disj-alt ptree) consts) pre)) - (new-disj - (node-source ptree) - (node-decl ptree) - pre - (pe (disj-alt ptree) consts))))) - ((prc? ptree) - (new-prc (node-source ptree) - (node-decl ptree) - (prc-name ptree) - (prc-min ptree) - (prc-rest ptree) - (prc-parms ptree) - (pe (prc-body ptree) consts))) - ((app? ptree) - (let ((oper (app-oper ptree)) (args (app-args ptree))) - (if (and (prc? oper) - (not (prc-rest oper)) - (= (length (prc-parms oper)) (length args))) - (pe-let ptree consts) - (new-call - (node-source ptree) - (node-decl ptree) - (pe oper consts) - (map (lambda (x) (pe x consts)) args))))) - ((fut? ptree) - (new-fut (node-source ptree) - (node-decl ptree) - (pe (fut-val ptree) consts))) - (else (compiler-internal-error "pe, unknown parse tree node type")))) -(define (pe-let ptree consts) - (let* ((proc (app-oper ptree)) - (vals (app-args ptree)) - (vars (prc-parms proc)) - (non-mut-vars (set-keep not-mutable? (list->set vars)))) - (for-each - (lambda (var) - (var-refs-set! var (set-empty)) - (var-sets-set! var (set-empty))) - vars) - (let loop ((l vars) - (v vals) - (new-vars '()) - (new-vals '()) - (new-consts consts)) - (if (null? l) - (if (null? new-vars) - (pe (prc-body proc) new-consts) - (new-call - (node-source ptree) - (node-decl ptree) - (new-prc (node-source proc) - (node-decl proc) - #f - (length new-vars) - #f - (reverse new-vars) - (pe (prc-body proc) new-consts)) - (reverse new-vals))) - (let ((var (car l)) (val (pe (car v) consts))) - (if (and (set-member? var non-mut-vars) (cst? val)) - (loop (cdr l) - (cdr v) - new-vars - new-vals - (cons (cons var (cst-val val)) new-consts)) - (loop (cdr l) - (cdr v) - (cons var new-vars) - (cons val new-vals) - new-consts))))))) -(define (assignment-convert ptree env) - (ac ptree (env-declare env (list safe-sym #f)) '())) -(define (ac ptree env mut) - (cond ((cst? ptree) ptree) - ((ref? ptree) - (let ((var (ref-var ptree))) - (if (global? var) - ptree - (let ((x (assq var mut))) - (if x - (let ((source (node-source ptree))) - (var-refs-set! var (set-remove (var-refs var) ptree)) - (new-call - source - (node-decl ptree) - (new-ref-extended-bindings source **cell-ref-sym env) - (list (new-ref source (node-decl ptree) (cdr x))))) - ptree))))) - ((set? ptree) - (let ((var (set-var ptree)) - (source (node-source ptree)) - (val (ac (set-val ptree) env mut))) - (var-sets-set! var (set-remove (var-sets var) ptree)) - (if (global? var) - (new-set source (node-decl ptree) var val) - (new-call - source - (node-decl ptree) - (new-ref-extended-bindings source **cell-set!-sym env) - (list (new-ref source (node-decl ptree) (cdr (assq var mut))) - val))))) - ((tst? ptree) - (new-tst (node-source ptree) - (node-decl ptree) - (ac (tst-pre ptree) env mut) - (ac (tst-con ptree) env mut) - (ac (tst-alt ptree) env mut))) - ((conj? ptree) - (new-conj - (node-source ptree) - (node-decl ptree) - (ac (conj-pre ptree) env mut) - (ac (conj-alt ptree) env mut))) - ((disj? ptree) - (new-disj - (node-source ptree) - (node-decl ptree) - (ac (disj-pre ptree) env mut) - (ac (disj-alt ptree) env mut))) - ((prc? ptree) (ac-proc ptree env mut)) - ((app? ptree) - (let ((oper (app-oper ptree)) (args (app-args ptree))) - (if (and (prc? oper) - (not (prc-rest oper)) - (= (length (prc-parms oper)) (length args))) - (ac-let ptree env mut) - (new-call - (node-source ptree) - (node-decl ptree) - (ac oper env mut) - (map (lambda (x) (ac x env mut)) args))))) - ((fut? ptree) - (new-fut (node-source ptree) - (node-decl ptree) - (ac (fut-val ptree) env mut))) - (else (compiler-internal-error "ac, unknown parse tree node type")))) -(define (ac-proc ptree env mut) - (let* ((mut-parms (ac-mutables (prc-parms ptree))) - (mut-parms-copies (map var-copy mut-parms)) - (mut (append (pair-up mut-parms mut-parms-copies) mut)) - (new-body (ac (prc-body ptree) env mut))) - (new-prc (node-source ptree) - (node-decl ptree) - (prc-name ptree) - (prc-min ptree) - (prc-rest ptree) - (prc-parms ptree) - (if (null? mut-parms) - new-body - (new-call - (node-source ptree) - (node-decl ptree) - (new-prc (node-source ptree) - (node-decl ptree) - #f - (length mut-parms-copies) - #f - mut-parms-copies - new-body) - (map (lambda (var) - (new-call - (var-source var) - (node-decl ptree) - (new-ref-extended-bindings - (var-source var) - **make-cell-sym - env) - (list (new-ref (var-source var) - (node-decl ptree) - var)))) - mut-parms)))))) -(define (ac-let ptree env mut) - (let* ((proc (app-oper ptree)) - (vals (app-args ptree)) - (vars (prc-parms proc)) - (vals-fv (apply set-union (map free-variables vals))) - (mut-parms (ac-mutables vars)) - (mut-parms-copies (map var-copy mut-parms)) - (mut (append (pair-up mut-parms mut-parms-copies) mut))) - (let loop ((l vars) - (v vals) - (new-vars '()) - (new-vals '()) - (new-body (ac (prc-body proc) env mut))) - (if (null? l) - (new-let ptree proc new-vars new-vals new-body) - (let ((var (car l)) (val (car v))) - (if (memq var mut-parms) - (let ((src (node-source val)) - (decl (node-decl val)) - (var* (cdr (assq var mut)))) - (if (set-member? var vals-fv) - (loop (cdr l) - (cdr v) - (cons var* new-vars) - (cons (new-call - src - decl - (new-ref-extended-bindings - src - **make-cell-sym - env) - (list (new-cst src decl undef-object))) - new-vals) - (new-seq src - decl - (new-call - src - decl - (new-ref-extended-bindings - src - **cell-set!-sym - env) - (list (new-ref src decl var*) - (ac val env mut))) - new-body)) - (loop (cdr l) - (cdr v) - (cons var* new-vars) - (cons (new-call - src - decl - (new-ref-extended-bindings - src - **make-cell-sym - env) - (list (ac val env mut))) - new-vals) - new-body))) - (loop (cdr l) - (cdr v) - (cons var new-vars) - (cons (ac val env mut) new-vals) - new-body))))))) -(define (ac-mutables l) - (if (pair? l) - (let ((var (car l)) (rest (ac-mutables (cdr l)))) - (if (mutable? var) (cons var rest) rest)) - '())) -(define (lambda-lift! ptree) (ll! ptree (set-empty) '())) -(define (ll! ptree cst-procs env) - (define (new-env env vars) - (define (loop i l) - (if (pair? l) - (let ((var (car l))) - (cons (cons var (cons (length (set->list (var-refs var))) i)) - (loop (+ i 1) (cdr l)))) - env)) - (loop (length env) vars)) - (cond ((or (cst? ptree) - (ref? ptree) - (set? ptree) - (tst? ptree) - (conj? ptree) - (disj? ptree) - (fut? ptree)) - (for-each - (lambda (child) (ll! child cst-procs env)) - (node-children ptree))) - ((prc? ptree) - (ll! (prc-body ptree) cst-procs (new-env env (prc-parms ptree)))) - ((app? ptree) - (let ((oper (app-oper ptree)) (args (app-args ptree))) - (if (and (prc? oper) - (not (prc-rest oper)) - (= (length (prc-parms oper)) (length args))) - (ll!-let ptree cst-procs (new-env env (prc-parms oper))) - (for-each - (lambda (child) (ll! child cst-procs env)) - (node-children ptree))))) - (else (compiler-internal-error "ll!, unknown parse tree node type")))) -(define (ll!-let ptree cst-procs env) - (let* ((proc (app-oper ptree)) - (vals (app-args ptree)) - (vars (prc-parms proc)) - (var-val-map (pair-up vars vals))) - (define (var->val var) (cdr (assq var var-val-map))) - (define (liftable-proc-vars vars) - (let loop ((cst-proc-vars - (set-keep - (lambda (var) - (let ((val (var->val var))) - (and (prc? val) - (lambda-lift? (node-decl val)) - (set-every? oper-pos? (var-refs var))))) - (list->set vars)))) - (let* ((non-cst-proc-vars - (set-keep - (lambda (var) - (let ((val (var->val var))) - (and (prc? val) (not (set-member? var cst-proc-vars))))) - (list->set vars))) - (cst-proc-vars* - (set-keep - (lambda (var) - (let ((val (var->val var))) - (set-empty? - (set-intersection - (free-variables val) - non-cst-proc-vars)))) - cst-proc-vars))) - (if (set-equal? cst-proc-vars cst-proc-vars*) - cst-proc-vars - (loop cst-proc-vars*))))) - (define (transitively-closed-free-variables vars) - (let ((tcfv-map - (map (lambda (var) (cons var (free-variables (var->val var)))) - vars))) - (let loop ((changed? #f)) - (for-each - (lambda (var-tcfv) - (let loop2 ((l (set->list (cdr var-tcfv))) (fv (cdr var-tcfv))) - (if (null? l) - (if (not (set-equal? fv (cdr var-tcfv))) - (begin (set-cdr! var-tcfv fv) (set! changed? #t))) - (let ((x (assq (car l) tcfv-map))) - (loop2 (cdr l) (if x (set-union fv (cdr x)) fv)))))) - tcfv-map) - (if changed? (loop #f) tcfv-map)))) - (let* ((tcfv-map - (transitively-closed-free-variables (liftable-proc-vars vars))) - (cst-proc-vars-list (map car tcfv-map)) - (cst-procs* (set-union (list->set cst-proc-vars-list) cst-procs))) - (define (var->tcfv var) (cdr (assq var tcfv-map))) - (define (order-vars vars) - (map car - (sort-list - (map (lambda (var) (assq var env)) vars) - (lambda (x y) - (if (= (cadr x) (cadr y)) - (< (cddr x) (cddr y)) - (< (cadr x) (cadr y))))))) - (define (lifted-vars var) - (order-vars (set->list (set-difference (var->tcfv var) cst-procs*)))) - (define (lift-app! var) - (let* ((val (var->val var)) (vars (lifted-vars var))) - (define (new-ref* var) - (new-ref (var-source var) (node-decl val) var)) - (if (not (null? vars)) - (for-each - (lambda (oper) - (let ((node (node-parent oper))) - (node-children-set! - node - (cons (app-oper node) - (append (map new-ref* vars) (app-args node)))))) - (set->list (var-refs var)))))) - (define (lift-prc! var) - (let* ((val (var->val var)) (vars (lifted-vars var))) - (if (not (null? vars)) - (let ((var-copies (map var-copy vars))) - (prc-parms-set! val (append var-copies (prc-parms val))) - (for-each (lambda (x) (var-bound-set! x val)) var-copies) - (node-fv-invalidate! val) - (prc-min-set! val (+ (prc-min val) (length vars))) - (ll-rename! val (pair-up vars var-copies)))))) - (for-each lift-app! cst-proc-vars-list) - (for-each lift-prc! cst-proc-vars-list) - (for-each (lambda (node) (ll! node cst-procs* env)) vals) - (ll! (prc-body proc) cst-procs* env)))) -(define (ll-rename! ptree var-map) - (cond ((ref? ptree) - (let* ((var (ref-var ptree)) (x (assq var var-map))) - (if x - (begin - (var-refs-set! var (set-remove (var-refs var) ptree)) - (var-refs-set! (cdr x) (set-adjoin (var-refs (cdr x)) ptree)) - (ref-var-set! ptree (cdr x)))))) - ((set? ptree) - (let* ((var (set-var ptree)) (x (assq var var-map))) - (if x - (begin - (var-sets-set! var (set-remove (var-sets var) ptree)) - (var-sets-set! (cdr x) (set-adjoin (var-sets (cdr x)) ptree)) - (set-var-set! ptree (cdr x))))))) - (node-fv-set! ptree #t) - (for-each (lambda (child) (ll-rename! child var-map)) (node-children ptree))) -(define (parse-tree->expression ptree) (se ptree '() (list 0))) -(define (se ptree env num) - (cond ((cst? ptree) (list quote-sym (cst-val ptree))) - ((ref? ptree) - (let ((x (assq (ref-var ptree) env))) - (if x (cdr x) (var-name (ref-var ptree))))) - ((set? ptree) - (list set!-sym - (let ((x (assq (set-var ptree) env))) - (if x (cdr x) (var-name (set-var ptree)))) - (se (set-val ptree) env num))) - ((def? ptree) - (list define-sym - (let ((x (assq (def-var ptree) env))) - (if x (cdr x) (var-name (def-var ptree)))) - (se (def-val ptree) env num))) - ((tst? ptree) - (list if-sym - (se (tst-pre ptree) env num) - (se (tst-con ptree) env num) - (se (tst-alt ptree) env num))) - ((conj? ptree) - (list and-sym - (se (conj-pre ptree) env num) - (se (conj-alt ptree) env num))) - ((disj? ptree) - (list or-sym - (se (disj-pre ptree) env num) - (se (disj-alt ptree) env num))) - ((prc? ptree) - (let ((new-env (se-rename (prc-parms ptree) env num))) - (list lambda-sym - (se-parameters - (prc-parms ptree) - (prc-rest ptree) - (prc-min ptree) - new-env) - (se (prc-body ptree) new-env num)))) - ((app? ptree) - (let ((oper (app-oper ptree)) (args (app-args ptree))) - (if (and (prc? oper) - (not (prc-rest oper)) - (= (length (prc-parms oper)) (length args))) - (let ((new-env (se-rename (prc-parms oper) env num))) - (list (if (set-empty? - (set-intersection - (list->set (prc-parms oper)) - (apply set-union (map free-variables args)))) - let-sym - letrec-sym) - (se-bindings (prc-parms oper) args new-env num) - (se (prc-body oper) new-env num))) - (map (lambda (x) (se x env num)) (cons oper args))))) - ((fut? ptree) (list future-sym (se (fut-val ptree) env num))) - (else (compiler-internal-error "se, unknown parse tree node type")))) -(define (se-parameters parms rest min env) - (define (se-parms parms rest n env) - (cond ((null? parms) '()) - ((and rest (null? (cdr parms))) (cdr (assq (car parms) env))) - (else - (let ((parm (cdr (assq (car parms) env)))) - (cons (if (> n 0) parm (list parm)) - (se-parms (cdr parms) rest (- n 1) env)))))) - (se-parms parms rest min env)) -(define (se-bindings vars vals env num) - (if (null? vars) - '() - (cons (list (cdr (assq (car vars) env)) (se (car vals) env num)) - (se-bindings (cdr vars) (cdr vals) env num)))) -(define (se-rename vars env num) - (define (rename vars) - (if (null? vars) - env - (cons (cons (car vars) - (string->canonical-symbol - (string-append - (symbol->string (var-name (car vars))) - "#" - (number->string (car num))))) - (rename (cdr vars))))) - (set-car! num (+ (car num) 1)) - (rename vars)) -(define *opnd-table* '()) -(define *opnd-table-alloc* '()) -(define opnd-table-size 10000) -(define (enter-opnd arg1 arg2) - (let loop ((i 0)) - (if (< i *opnd-table-alloc*) - (let ((x (vector-ref *opnd-table* i))) - (if (and (eqv? (car x) arg1) (eqv? (cdr x) arg2)) i (loop (+ i 1)))) - (if (< *opnd-table-alloc* opnd-table-size) - (begin - (set! *opnd-table-alloc* (+ *opnd-table-alloc* 1)) - (vector-set! *opnd-table* i (cons arg1 arg2)) - i) - (compiler-limitation-error - "program is too long [virtual machine operand table overflow]"))))) -(define (contains-opnd? opnd1 opnd2) - (cond ((eqv? opnd1 opnd2) #t) - ((clo? opnd2) (contains-opnd? opnd1 (clo-base opnd2))) - (else #f))) -(define (any-contains-opnd? opnd opnds) - (if (null? opnds) - #f - (or (contains-opnd? opnd (car opnds)) - (any-contains-opnd? opnd (cdr opnds))))) -(define (make-reg num) num) -(define (reg? x) (< x 10000)) -(define (reg-num x) (modulo x 10000)) -(define (make-stk num) (+ num 10000)) -(define (stk? x) (= (quotient x 10000) 1)) -(define (stk-num x) (modulo x 10000)) -(define (make-glo name) (+ (enter-opnd name #t) 30000)) -(define (glo? x) (= (quotient x 10000) 3)) -(define (glo-name x) (car (vector-ref *opnd-table* (modulo x 10000)))) -(define (make-clo base index) (+ (enter-opnd base index) 40000)) -(define (clo? x) (= (quotient x 10000) 4)) -(define (clo-base x) (car (vector-ref *opnd-table* (modulo x 10000)))) -(define (clo-index x) (cdr (vector-ref *opnd-table* (modulo x 10000)))) -(define (make-lbl num) (+ num 20000)) -(define (lbl? x) (= (quotient x 10000) 2)) -(define (lbl-num x) (modulo x 10000)) -(define label-limit 9999) -(define (make-obj val) (+ (enter-opnd val #f) 50000)) -(define (obj? x) (= (quotient x 10000) 5)) -(define (obj-val x) (car (vector-ref *opnd-table* (modulo x 10000)))) -(define (make-pcontext fs map) (vector fs map)) -(define (pcontext-fs x) (vector-ref x 0)) -(define (pcontext-map x) (vector-ref x 1)) -(define (make-frame size slots regs closed live) - (vector size slots regs closed live)) -(define (frame-size x) (vector-ref x 0)) -(define (frame-slots x) (vector-ref x 1)) -(define (frame-regs x) (vector-ref x 2)) -(define (frame-closed x) (vector-ref x 3)) -(define (frame-live x) (vector-ref x 4)) -(define (frame-eq? x y) (= (frame-size x) (frame-size y))) -(define (frame-truncate frame nb-slots) - (let ((fs (frame-size frame))) - (make-frame - nb-slots - (nth-after (frame-slots frame) (- fs nb-slots)) - (frame-regs frame) - (frame-closed frame) - (frame-live frame)))) -(define (frame-live? var frame) - (let ((live (frame-live frame))) - (if (eq? var closure-env-var) - (let ((closed (frame-closed frame))) - (if (or (set-member? var live) - (not (set-empty? - (set-intersection live (list->set closed))))) - closed - #f)) - (if (set-member? var live) var #f)))) -(define (frame-first-empty-slot frame) - (let loop ((i 1) (s (reverse (frame-slots frame)))) - (if (pair? s) - (if (frame-live? (car s) frame) (loop (+ i 1) (cdr s)) i) - i))) -(define (make-proc-obj - name - primitive? - code - call-pat - side-effects? - strict-pat - type) - (let ((proc-obj - (vector proc-obj-tag - name - primitive? - code - call-pat - #f - #f - #f - side-effects? - strict-pat - type))) - (proc-obj-specialize-set! proc-obj (lambda (decls) proc-obj)) - proc-obj)) -(define proc-obj-tag (list 'proc-obj)) -(define (proc-obj? x) - (and (vector? x) - (> (vector-length x) 0) - (eq? (vector-ref x 0) proc-obj-tag))) -(define (proc-obj-name obj) (vector-ref obj 1)) -(define (proc-obj-primitive? obj) (vector-ref obj 2)) -(define (proc-obj-code obj) (vector-ref obj 3)) -(define (proc-obj-call-pat obj) (vector-ref obj 4)) -(define (proc-obj-test obj) (vector-ref obj 5)) -(define (proc-obj-inlinable obj) (vector-ref obj 6)) -(define (proc-obj-specialize obj) (vector-ref obj 7)) -(define (proc-obj-side-effects? obj) (vector-ref obj 8)) -(define (proc-obj-strict-pat obj) (vector-ref obj 9)) -(define (proc-obj-type obj) (vector-ref obj 10)) -(define (proc-obj-code-set! obj x) (vector-set! obj 3 x)) -(define (proc-obj-test-set! obj x) (vector-set! obj 5 x)) -(define (proc-obj-inlinable-set! obj x) (vector-set! obj 6 x)) -(define (proc-obj-specialize-set! obj x) (vector-set! obj 7 x)) -(define (make-pattern min-args nb-parms rest?) - (let loop ((x (if rest? (- nb-parms 1) (list nb-parms))) - (y (if rest? (- nb-parms 1) nb-parms))) - (let ((z (- y 1))) (if (< z min-args) x (loop (cons z x) z))))) -(define (pattern-member? n pat) - (cond ((pair? pat) (if (= (car pat) n) #t (pattern-member? n (cdr pat)))) - ((null? pat) #f) - (else (<= pat n)))) -(define (type-name type) (if (pair? type) (car type) type)) -(define (type-pot-fut? type) (pair? type)) -(define (make-bbs) - (vector (make-counter 1 label-limit bbs-limit-err) (queue-empty) '())) -(define (bbs-limit-err) - (compiler-limitation-error "procedure is too long [too many labels]")) -(define (bbs-lbl-counter bbs) (vector-ref bbs 0)) -(define (bbs-lbl-counter-set! bbs cntr) (vector-set! bbs 0 cntr)) -(define (bbs-bb-queue bbs) (vector-ref bbs 1)) -(define (bbs-bb-queue-set! bbs bbq) (vector-set! bbs 1 bbq)) -(define (bbs-entry-lbl-num bbs) (vector-ref bbs 2)) -(define (bbs-entry-lbl-num-set! bbs lbl-num) (vector-set! bbs 2 lbl-num)) -(define (bbs-new-lbl! bbs) ((bbs-lbl-counter bbs))) -(define (lbl-num->bb lbl-num bbs) - (let loop ((bb-list (queue->list (bbs-bb-queue bbs)))) - (if (= (bb-lbl-num (car bb-list)) lbl-num) - (car bb-list) - (loop (cdr bb-list))))) -(define (make-bb label-instr bbs) - (let ((bb (vector label-instr (queue-empty) '() '() '()))) - (queue-put! (vector-ref bbs 1) bb) - bb)) -(define (bb-lbl-num bb) (label-lbl-num (vector-ref bb 0))) -(define (bb-label-type bb) (label-type (vector-ref bb 0))) -(define (bb-label-instr bb) (vector-ref bb 0)) -(define (bb-label-instr-set! bb l) (vector-set! bb 0 l)) -(define (bb-non-branch-instrs bb) (queue->list (vector-ref bb 1))) -(define (bb-non-branch-instrs-set! bb l) (vector-set! bb 1 (list->queue l))) -(define (bb-branch-instr bb) (vector-ref bb 2)) -(define (bb-branch-instr-set! bb b) (vector-set! bb 2 b)) -(define (bb-references bb) (vector-ref bb 3)) -(define (bb-references-set! bb l) (vector-set! bb 3 l)) -(define (bb-precedents bb) (vector-ref bb 4)) -(define (bb-precedents-set! bb l) (vector-set! bb 4 l)) -(define (bb-entry-frame-size bb) - (frame-size (gvm-instr-frame (bb-label-instr bb)))) -(define (bb-exit-frame-size bb) - (frame-size (gvm-instr-frame (bb-branch-instr bb)))) -(define (bb-slots-gained bb) - (- (bb-exit-frame-size bb) (bb-entry-frame-size bb))) -(define (bb-put-non-branch! bb gvm-instr) - (queue-put! (vector-ref bb 1) gvm-instr)) -(define (bb-put-branch! bb gvm-instr) (vector-set! bb 2 gvm-instr)) -(define (bb-add-reference! bb ref) - (if (not (memq ref (vector-ref bb 3))) - (vector-set! bb 3 (cons ref (vector-ref bb 3))))) -(define (bb-add-precedent! bb prec) - (if (not (memq prec (vector-ref bb 4))) - (vector-set! bb 4 (cons prec (vector-ref bb 4))))) -(define (bb-last-non-branch-instr bb) - (let ((non-branch-instrs (bb-non-branch-instrs bb))) - (if (null? non-branch-instrs) - (bb-label-instr bb) - (let loop ((l non-branch-instrs)) - (if (pair? (cdr l)) (loop (cdr l)) (car l)))))) -(define (gvm-instr-type gvm-instr) (vector-ref gvm-instr 0)) -(define (gvm-instr-frame gvm-instr) (vector-ref gvm-instr 1)) -(define (gvm-instr-comment gvm-instr) (vector-ref gvm-instr 2)) -(define (make-label-simple lbl-num frame comment) - (vector 'label frame comment lbl-num 'simple)) -(define (make-label-entry lbl-num nb-parms min rest? closed? frame comment) - (vector 'label frame comment lbl-num 'entry nb-parms min rest? closed?)) -(define (make-label-return lbl-num frame comment) - (vector 'label frame comment lbl-num 'return)) -(define (make-label-task-entry lbl-num frame comment) - (vector 'label frame comment lbl-num 'task-entry)) -(define (make-label-task-return lbl-num frame comment) - (vector 'label frame comment lbl-num 'task-return)) -(define (label-lbl-num gvm-instr) (vector-ref gvm-instr 3)) -(define (label-lbl-num-set! gvm-instr n) (vector-set! gvm-instr 3 n)) -(define (label-type gvm-instr) (vector-ref gvm-instr 4)) -(define (label-entry-nb-parms gvm-instr) (vector-ref gvm-instr 5)) -(define (label-entry-min gvm-instr) (vector-ref gvm-instr 6)) -(define (label-entry-rest? gvm-instr) (vector-ref gvm-instr 7)) -(define (label-entry-closed? gvm-instr) (vector-ref gvm-instr 8)) -(define (make-apply prim opnds loc frame comment) - (vector 'apply frame comment prim opnds loc)) -(define (apply-prim gvm-instr) (vector-ref gvm-instr 3)) -(define (apply-opnds gvm-instr) (vector-ref gvm-instr 4)) -(define (apply-loc gvm-instr) (vector-ref gvm-instr 5)) -(define (make-copy opnd loc frame comment) - (vector 'copy frame comment opnd loc)) -(define (copy-opnd gvm-instr) (vector-ref gvm-instr 3)) -(define (copy-loc gvm-instr) (vector-ref gvm-instr 4)) -(define (make-close parms frame comment) (vector 'close frame comment parms)) -(define (close-parms gvm-instr) (vector-ref gvm-instr 3)) -(define (make-closure-parms loc lbl opnds) (vector loc lbl opnds)) -(define (closure-parms-loc x) (vector-ref x 0)) -(define (closure-parms-lbl x) (vector-ref x 1)) -(define (closure-parms-opnds x) (vector-ref x 2)) -(define (make-ifjump test opnds true false poll? frame comment) - (vector 'ifjump frame comment test opnds true false poll?)) -(define (ifjump-test gvm-instr) (vector-ref gvm-instr 3)) -(define (ifjump-opnds gvm-instr) (vector-ref gvm-instr 4)) -(define (ifjump-true gvm-instr) (vector-ref gvm-instr 5)) -(define (ifjump-false gvm-instr) (vector-ref gvm-instr 6)) -(define (ifjump-poll? gvm-instr) (vector-ref gvm-instr 7)) -(define (make-jump opnd nb-args poll? frame comment) - (vector 'jump frame comment opnd nb-args poll?)) -(define (jump-opnd gvm-instr) (vector-ref gvm-instr 3)) -(define (jump-nb-args gvm-instr) (vector-ref gvm-instr 4)) -(define (jump-poll? gvm-instr) (vector-ref gvm-instr 5)) -(define (first-class-jump? gvm-instr) (jump-nb-args gvm-instr)) -(define (make-comment) (cons 'comment '())) -(define (comment-put! comment name val) - (set-cdr! comment (cons (cons name val) (cdr comment)))) -(define (comment-get comment name) - (and comment (let ((x (assq name (cdr comment)))) (if x (cdr x) #f)))) -(define (bbs-purify! bbs) - (let loop () - (bbs-remove-jump-cascades! bbs) - (bbs-remove-dead-code! bbs) - (let* ((changed1? (bbs-remove-common-code! bbs)) - (changed2? (bbs-remove-useless-jumps! bbs))) - (if (or changed1? changed2?) (loop) (bbs-order! bbs))))) -(define (bbs-remove-jump-cascades! bbs) - (define (empty-bb? bb) - (and (eq? (bb-label-type bb) 'simple) (null? (bb-non-branch-instrs bb)))) - (define (jump-to-non-entry-lbl? branch) - (and (eq? (gvm-instr-type branch) 'jump) - (not (first-class-jump? branch)) - (jump-lbl? branch))) - (define (jump-cascade-to lbl-num fs poll? seen thunk) - (if (memq lbl-num seen) - (thunk lbl-num fs poll?) - (let ((bb (lbl-num->bb lbl-num bbs))) - (if (and (empty-bb? bb) (<= (bb-slots-gained bb) 0)) - (let ((jump-lbl-num - (jump-to-non-entry-lbl? (bb-branch-instr bb)))) - (if jump-lbl-num - (jump-cascade-to - jump-lbl-num - (+ fs (bb-slots-gained bb)) - (or poll? (jump-poll? (bb-branch-instr bb))) - (cons lbl-num seen) - thunk) - (thunk lbl-num fs poll?))) - (thunk lbl-num fs poll?))))) - (define (equiv-lbl lbl-num seen) - (if (memq lbl-num seen) - lbl-num - (let ((bb (lbl-num->bb lbl-num bbs))) - (if (empty-bb? bb) - (let ((jump-lbl-num - (jump-to-non-entry-lbl? (bb-branch-instr bb)))) - (if (and jump-lbl-num - (not (jump-poll? (bb-branch-instr bb))) - (= (bb-slots-gained bb) 0)) - (equiv-lbl jump-lbl-num (cons lbl-num seen)) - lbl-num)) - lbl-num)))) - (define (remove-cascade! bb) - (let ((branch (bb-branch-instr bb))) - (case (gvm-instr-type branch) - ((ifjump) - (bb-put-branch! - bb - (make-ifjump - (ifjump-test branch) - (ifjump-opnds branch) - (equiv-lbl (ifjump-true branch) '()) - (equiv-lbl (ifjump-false branch) '()) - (ifjump-poll? branch) - (gvm-instr-frame branch) - (gvm-instr-comment branch)))) - ((jump) - (if (not (first-class-jump? branch)) - (let ((dest-lbl-num (jump-lbl? branch))) - (if dest-lbl-num - (jump-cascade-to - dest-lbl-num - (frame-size (gvm-instr-frame branch)) - (jump-poll? branch) - '() - (lambda (lbl-num fs poll?) - (let* ((dest-bb (lbl-num->bb lbl-num bbs)) - (last-branch (bb-branch-instr dest-bb))) - (if (and (empty-bb? dest-bb) - (or (not poll?) - put-poll-on-ifjump? - (not (eq? (gvm-instr-type last-branch) - 'ifjump)))) - (let* ((new-fs (+ fs (bb-slots-gained dest-bb))) - (new-frame - (frame-truncate - (gvm-instr-frame branch) - new-fs))) - (define (adjust-opnd opnd) - (cond ((stk? opnd) - (make-stk - (+ (- fs (bb-entry-frame-size dest-bb)) - (stk-num opnd)))) - ((clo? opnd) - (make-clo - (adjust-opnd (clo-base opnd)) - (clo-index opnd))) - (else opnd))) - (case (gvm-instr-type last-branch) - ((ifjump) - (bb-put-branch! - bb - (make-ifjump - (ifjump-test last-branch) - (map adjust-opnd (ifjump-opnds last-branch)) - (equiv-lbl (ifjump-true last-branch) '()) - (equiv-lbl (ifjump-false last-branch) '()) - (or poll? (ifjump-poll? last-branch)) - new-frame - (gvm-instr-comment last-branch)))) - ((jump) - (bb-put-branch! - bb - (make-jump - (adjust-opnd (jump-opnd last-branch)) - (jump-nb-args last-branch) - (or poll? (jump-poll? last-branch)) - new-frame - (gvm-instr-comment last-branch)))) - (else - (compiler-internal-error - "bbs-remove-jump-cascades!, unknown branch type")))) - (bb-put-branch! - bb - (make-jump - (make-lbl lbl-num) - (jump-nb-args branch) - (or poll? (jump-poll? branch)) - (frame-truncate (gvm-instr-frame branch) fs) - (gvm-instr-comment branch))))))))))) - (else - (compiler-internal-error - "bbs-remove-jump-cascades!, unknown branch type"))))) - (for-each remove-cascade! (queue->list (bbs-bb-queue bbs)))) -(define (jump-lbl? branch) - (let ((opnd (jump-opnd branch))) (if (lbl? opnd) (lbl-num opnd) #f))) -(define put-poll-on-ifjump? #f) -(set! put-poll-on-ifjump? #t) -(define (bbs-remove-dead-code! bbs) - (let ((new-bb-queue (queue-empty)) (scan-queue (queue-empty))) - (define (reachable ref bb) - (if bb (bb-add-reference! bb ref)) - (if (not (memq ref (queue->list new-bb-queue))) - (begin - (bb-references-set! ref '()) - (bb-precedents-set! ref '()) - (queue-put! new-bb-queue ref) - (queue-put! scan-queue ref)))) - (define (direct-jump to-bb from-bb) - (reachable to-bb from-bb) - (bb-add-precedent! to-bb from-bb)) - (define (scan-instr gvm-instr bb) - (define (scan-opnd gvm-opnd) - (cond ((lbl? gvm-opnd) - (reachable (lbl-num->bb (lbl-num gvm-opnd) bbs) bb)) - ((clo? gvm-opnd) (scan-opnd (clo-base gvm-opnd))))) - (case (gvm-instr-type gvm-instr) - ((label) '()) - ((apply) - (for-each scan-opnd (apply-opnds gvm-instr)) - (if (apply-loc gvm-instr) (scan-opnd (apply-loc gvm-instr)))) - ((copy) - (scan-opnd (copy-opnd gvm-instr)) - (scan-opnd (copy-loc gvm-instr))) - ((close) - (for-each - (lambda (parm) - (reachable (lbl-num->bb (closure-parms-lbl parm) bbs) bb) - (scan-opnd (closure-parms-loc parm)) - (for-each scan-opnd (closure-parms-opnds parm))) - (close-parms gvm-instr))) - ((ifjump) - (for-each scan-opnd (ifjump-opnds gvm-instr)) - (direct-jump (lbl-num->bb (ifjump-true gvm-instr) bbs) bb) - (direct-jump (lbl-num->bb (ifjump-false gvm-instr) bbs) bb)) - ((jump) - (let ((opnd (jump-opnd gvm-instr))) - (if (lbl? opnd) - (direct-jump (lbl-num->bb (lbl-num opnd) bbs) bb) - (scan-opnd (jump-opnd gvm-instr))))) - (else - (compiler-internal-error - "bbs-remove-dead-code!, unknown GVM instruction type")))) - (reachable (lbl-num->bb (bbs-entry-lbl-num bbs) bbs) #f) - (let loop () - (if (not (queue-empty? scan-queue)) - (let ((bb (queue-get! scan-queue))) - (begin - (scan-instr (bb-label-instr bb) bb) - (for-each - (lambda (gvm-instr) (scan-instr gvm-instr bb)) - (bb-non-branch-instrs bb)) - (scan-instr (bb-branch-instr bb) bb) - (loop))))) - (bbs-bb-queue-set! bbs new-bb-queue))) -(define (bbs-remove-useless-jumps! bbs) - (let ((changed? #f)) - (define (remove-useless-jump bb) - (let ((branch (bb-branch-instr bb))) - (if (and (eq? (gvm-instr-type branch) 'jump) - (not (first-class-jump? branch)) - (not (jump-poll? branch)) - (jump-lbl? branch)) - (let* ((dest-bb (lbl-num->bb (jump-lbl? branch) bbs)) - (frame1 (gvm-instr-frame (bb-last-non-branch-instr bb))) - (frame2 (gvm-instr-frame (bb-label-instr dest-bb)))) - (if (and (eq? (bb-label-type dest-bb) 'simple) - (frame-eq? frame1 frame2) - (= (length (bb-precedents dest-bb)) 1)) - (begin - (set! changed? #t) - (bb-non-branch-instrs-set! - bb - (append (bb-non-branch-instrs bb) - (bb-non-branch-instrs dest-bb) - '())) - (bb-branch-instr-set! bb (bb-branch-instr dest-bb)) - (remove-useless-jump bb))))))) - (for-each remove-useless-jump (queue->list (bbs-bb-queue bbs))) - changed?)) -(define (bbs-remove-common-code! bbs) - (let* ((bb-list (queue->list (bbs-bb-queue bbs))) - (n (length bb-list)) - (hash-table-length (cond ((< n 50) 43) ((< n 500) 403) (else 4003))) - (hash-table (make-vector hash-table-length '())) - (prim-table '()) - (block-map '()) - (changed? #f)) - (define (hash-prim prim) - (let ((n (length prim-table)) (i (pos-in-list prim prim-table))) - (if i - (- n i) - (begin (set! prim-table (cons prim prim-table)) (+ n 1))))) - (define (hash-opnds l) - (let loop ((l l) (n 0)) - (if (pair? l) - (loop (cdr l) - (let ((x (car l))) - (if (lbl? x) - n - (modulo (+ (* n 10000) x) hash-table-length)))) - n))) - (define (hash-bb bb) - (let ((branch (bb-branch-instr bb))) - (modulo (case (gvm-instr-type branch) - ((ifjump) - (+ (hash-opnds (ifjump-opnds branch)) - (* 10 (hash-prim (ifjump-test branch))) - (* 100 (frame-size (gvm-instr-frame branch))))) - ((jump) - (+ (hash-opnds (list (jump-opnd branch))) - (* 10 (or (jump-nb-args branch) -1)) - (* 100 (frame-size (gvm-instr-frame branch))))) - (else 0)) - hash-table-length))) - (define (replacement-lbl-num lbl) - (let ((x (assv lbl block-map))) (if x (cdr x) lbl))) - (define (fix-map! bb1 bb2) - (let loop ((l block-map)) - (if (pair? l) - (let ((x (car l))) - (if (= bb1 (cdr x)) (set-cdr! x bb2)) - (loop (cdr l)))))) - (define (enter-bb! bb) - (let ((h (hash-bb bb))) - (vector-set! hash-table h (add-bb bb (vector-ref hash-table h))))) - (define (add-bb bb l) - (if (pair? l) - (let ((bb* (car l))) - (set! block-map - (cons (cons (bb-lbl-num bb) (bb-lbl-num bb*)) block-map)) - (if (eqv-bb? bb bb*) - (begin - (fix-map! (bb-lbl-num bb) (bb-lbl-num bb*)) - (set! changed? #t) - l) - (begin - (set! block-map (cdr block-map)) - (if (eqv-gvm-instr? - (bb-branch-instr bb) - (bb-branch-instr bb*)) - (extract-common-tail - bb - bb* - (lambda (head head* tail) - (if (null? tail) - (cons bb* (add-bb bb (cdr l))) - (let* ((lbl (bbs-new-lbl! bbs)) - (branch (bb-branch-instr bb)) - (fs** (need-gvm-instrs tail branch)) - (frame (frame-truncate - (gvm-instr-frame - (if (null? head) - (bb-label-instr bb) - (car head))) - fs**)) - (bb** (make-bb (make-label-simple - lbl - frame - #f) - bbs))) - (bb-non-branch-instrs-set! bb** tail) - (bb-branch-instr-set! bb** branch) - (bb-non-branch-instrs-set! bb* (reverse head*)) - (bb-branch-instr-set! - bb* - (make-jump (make-lbl lbl) #f #f frame #f)) - (bb-non-branch-instrs-set! bb (reverse head)) - (bb-branch-instr-set! - bb - (make-jump (make-lbl lbl) #f #f frame #f)) - (set! changed? #t) - (cons bb (cons bb* (add-bb bb** (cdr l)))))))) - (cons bb* (add-bb bb (cdr l))))))) - (list bb))) - (define (extract-common-tail bb1 bb2 cont) - (let loop ((l1 (reverse (bb-non-branch-instrs bb1))) - (l2 (reverse (bb-non-branch-instrs bb2))) - (tail '())) - (if (and (pair? l1) (pair? l2)) - (let ((i1 (car l1)) (i2 (car l2))) - (if (eqv-gvm-instr? i1 i2) - (loop (cdr l1) (cdr l2) (cons i1 tail)) - (cont l1 l2 tail))) - (cont l1 l2 tail)))) - (define (eqv-bb? bb1 bb2) - (let ((bb1-non-branch (bb-non-branch-instrs bb1)) - (bb2-non-branch (bb-non-branch-instrs bb2))) - (and (= (length bb1-non-branch) (length bb2-non-branch)) - (eqv-gvm-instr? (bb-label-instr bb1) (bb-label-instr bb2)) - (eqv-gvm-instr? (bb-branch-instr bb1) (bb-branch-instr bb2)) - (eqv-list? eqv-gvm-instr? bb1-non-branch bb2-non-branch)))) - (define (eqv-list? pred? l1 l2) - (if (pair? l1) - (and (pair? l2) - (pred? (car l1) (car l2)) - (eqv-list? pred? (cdr l1) (cdr l2))) - (not (pair? l2)))) - (define (eqv-lbl-num? lbl1 lbl2) - (= (replacement-lbl-num lbl1) (replacement-lbl-num lbl2))) - (define (eqv-gvm-opnd? opnd1 opnd2) - (if (not opnd1) - (not opnd2) - (and opnd2 - (cond ((lbl? opnd1) - (and (lbl? opnd2) - (eqv-lbl-num? (lbl-num opnd1) (lbl-num opnd2)))) - ((clo? opnd1) - (and (clo? opnd2) - (= (clo-index opnd1) (clo-index opnd2)) - (eqv-gvm-opnd? (clo-base opnd1) (clo-base opnd2)))) - (else (eqv? opnd1 opnd2)))))) - (define (eqv-gvm-instr? instr1 instr2) - (define (eqv-closure-parms? p1 p2) - (and (eqv-gvm-opnd? (closure-parms-loc p1) (closure-parms-loc p2)) - (eqv-lbl-num? (closure-parms-lbl p1) (closure-parms-lbl p2)) - (eqv-list? - eqv-gvm-opnd? - (closure-parms-opnds p1) - (closure-parms-opnds p2)))) - (let ((type1 (gvm-instr-type instr1)) (type2 (gvm-instr-type instr2))) - (and (eq? type1 type2) - (frame-eq? (gvm-instr-frame instr1) (gvm-instr-frame instr2)) - (case type1 - ((label) - (let ((ltype1 (label-type instr1)) - (ltype2 (label-type instr2))) - (and (eq? ltype1 ltype2) - (case ltype1 - ((simple return task-entry task-return) #t) - ((entry) - (and (= (label-entry-min instr1) - (label-entry-min instr2)) - (= (label-entry-nb-parms instr1) - (label-entry-nb-parms instr2)) - (eq? (label-entry-rest? instr1) - (label-entry-rest? instr2)) - (eq? (label-entry-closed? instr1) - (label-entry-closed? instr2)))) - (else - (compiler-internal-error - "eqv-gvm-instr?, unknown label type")))))) - ((apply) - (and (eq? (apply-prim instr1) (apply-prim instr2)) - (eqv-list? - eqv-gvm-opnd? - (apply-opnds instr1) - (apply-opnds instr2)) - (eqv-gvm-opnd? (apply-loc instr1) (apply-loc instr2)))) - ((copy) - (and (eqv-gvm-opnd? (copy-opnd instr1) (copy-opnd instr2)) - (eqv-gvm-opnd? (copy-loc instr1) (copy-loc instr2)))) - ((close) - (eqv-list? - eqv-closure-parms? - (close-parms instr1) - (close-parms instr2))) - ((ifjump) - (and (eq? (ifjump-test instr1) (ifjump-test instr2)) - (eqv-list? - eqv-gvm-opnd? - (ifjump-opnds instr1) - (ifjump-opnds instr2)) - (eqv-lbl-num? (ifjump-true instr1) (ifjump-true instr2)) - (eqv-lbl-num? (ifjump-false instr1) (ifjump-false instr2)) - (eq? (ifjump-poll? instr1) (ifjump-poll? instr2)))) - ((jump) - (and (eqv-gvm-opnd? (jump-opnd instr1) (jump-opnd instr2)) - (eqv? (jump-nb-args instr1) (jump-nb-args instr2)) - (eq? (jump-poll? instr1) (jump-poll? instr2)))) - (else - (compiler-internal-error - "eqv-gvm-instr?, unknown 'gvm-instr':" - instr1)))))) - (define (update-bb! bb) (replace-label-references! bb replacement-lbl-num)) - (for-each enter-bb! bb-list) - (bbs-entry-lbl-num-set! bbs (replacement-lbl-num (bbs-entry-lbl-num bbs))) - (let loop ((i 0) (result '())) - (if (< i hash-table-length) - (let ((bb-kept (vector-ref hash-table i))) - (for-each update-bb! bb-kept) - (loop (+ i 1) (append bb-kept result))) - (bbs-bb-queue-set! bbs (list->queue result)))) - changed?)) -(define (replace-label-references! bb replacement-lbl-num) - (define (update-gvm-opnd opnd) - (if opnd - (cond ((lbl? opnd) (make-lbl (replacement-lbl-num (lbl-num opnd)))) - ((clo? opnd) - (make-clo (update-gvm-opnd (clo-base opnd)) (clo-index opnd))) - (else opnd)) - opnd)) - (define (update-gvm-instr instr) - (define (update-closure-parms p) - (make-closure-parms - (update-gvm-opnd (closure-parms-loc p)) - (replacement-lbl-num (closure-parms-lbl p)) - (map update-gvm-opnd (closure-parms-opnds p)))) - (case (gvm-instr-type instr) - ((apply) - (make-apply - (apply-prim instr) - (map update-gvm-opnd (apply-opnds instr)) - (update-gvm-opnd (apply-loc instr)) - (gvm-instr-frame instr) - (gvm-instr-comment instr))) - ((copy) - (make-copy - (update-gvm-opnd (copy-opnd instr)) - (update-gvm-opnd (copy-loc instr)) - (gvm-instr-frame instr) - (gvm-instr-comment instr))) - ((close) - (make-close - (map update-closure-parms (close-parms instr)) - (gvm-instr-frame instr) - (gvm-instr-comment instr))) - ((ifjump) - (make-ifjump - (ifjump-test instr) - (map update-gvm-opnd (ifjump-opnds instr)) - (replacement-lbl-num (ifjump-true instr)) - (replacement-lbl-num (ifjump-false instr)) - (ifjump-poll? instr) - (gvm-instr-frame instr) - (gvm-instr-comment instr))) - ((jump) - (make-jump - (update-gvm-opnd (jump-opnd instr)) - (jump-nb-args instr) - (jump-poll? instr) - (gvm-instr-frame instr) - (gvm-instr-comment instr))) - (else - (compiler-internal-error "update-gvm-instr, unknown 'instr':" instr)))) - (bb-non-branch-instrs-set! - bb - (map update-gvm-instr (bb-non-branch-instrs bb))) - (bb-branch-instr-set! bb (update-gvm-instr (bb-branch-instr bb)))) -(define (bbs-order! bbs) - (let ((new-bb-queue (queue-empty)) - (left-to-schedule (queue->list (bbs-bb-queue bbs)))) - (define (remove x l) - (if (eq? (car l) x) (cdr l) (cons (car l) (remove x (cdr l))))) - (define (remove-bb! bb) - (set! left-to-schedule (remove bb left-to-schedule)) - bb) - (define (prec-bb bb) - (let loop ((l (bb-precedents bb)) (best #f) (best-fs #f)) - (if (null? l) - best - (let* ((x (car l)) (x-fs (bb-exit-frame-size x))) - (if (and (memq x left-to-schedule) - (or (not best) (< x-fs best-fs))) - (loop (cdr l) x x-fs) - (loop (cdr l) best best-fs)))))) - (define (succ-bb bb) - (define (branches-to-lbl? bb) - (let ((branch (bb-branch-instr bb))) - (case (gvm-instr-type branch) - ((ifjump) #t) - ((jump) (lbl? (jump-opnd branch))) - (else - (compiler-internal-error "bbs-order!, unknown branch type"))))) - (define (best-succ bb1 bb2) - (if (branches-to-lbl? bb1) - bb1 - (if (branches-to-lbl? bb2) - bb2 - (if (< (bb-exit-frame-size bb1) (bb-exit-frame-size bb2)) - bb2 - bb1)))) - (let ((branch (bb-branch-instr bb))) - (case (gvm-instr-type branch) - ((ifjump) - (let* ((true-bb (lbl-num->bb (ifjump-true branch) bbs)) - (true-bb* (and (memq true-bb left-to-schedule) true-bb)) - (false-bb (lbl-num->bb (ifjump-false branch) bbs)) - (false-bb* (and (memq false-bb left-to-schedule) false-bb))) - (if (and true-bb* false-bb*) - (best-succ true-bb* false-bb*) - (or true-bb* false-bb*)))) - ((jump) - (let ((opnd (jump-opnd branch))) - (and (lbl? opnd) - (let ((bb (lbl-num->bb (lbl-num opnd) bbs))) - (and (memq bb left-to-schedule) bb))))) - (else (compiler-internal-error "bbs-order!, unknown branch type"))))) - (define (schedule-from bb) - (queue-put! new-bb-queue bb) - (let ((x (succ-bb bb))) - (if x - (begin - (schedule-around (remove-bb! x)) - (let ((y (succ-bb bb))) - (if y (schedule-around (remove-bb! y))))))) - (schedule-refs bb)) - (define (schedule-around bb) - (let ((x (prec-bb bb))) - (if x - (let ((bb-list (schedule-back (remove-bb! x) '()))) - (queue-put! new-bb-queue x) - (schedule-forw bb) - (for-each schedule-refs bb-list)) - (schedule-from bb)))) - (define (schedule-back bb bb-list) - (let ((bb-list* (cons bb bb-list)) (x (prec-bb bb))) - (if x - (let ((bb-list (schedule-back (remove-bb! x) bb-list*))) - (queue-put! new-bb-queue x) - bb-list) - bb-list*))) - (define (schedule-forw bb) - (queue-put! new-bb-queue bb) - (let ((x (succ-bb bb))) - (if x - (begin - (schedule-forw (remove-bb! x)) - (let ((y (succ-bb bb))) - (if y (schedule-around (remove-bb! y))))))) - (schedule-refs bb)) - (define (schedule-refs bb) - (for-each - (lambda (x) - (if (memq x left-to-schedule) (schedule-around (remove-bb! x)))) - (bb-references bb))) - (schedule-from (remove-bb! (lbl-num->bb (bbs-entry-lbl-num bbs) bbs))) - (bbs-bb-queue-set! bbs new-bb-queue) - (let ((bb-list (queue->list new-bb-queue))) - (let loop ((l bb-list) (i 1) (lbl-map '())) - (if (pair? l) - (let* ((label-instr (bb-label-instr (car l))) - (old-lbl-num (label-lbl-num label-instr))) - (label-lbl-num-set! label-instr i) - (loop (cdr l) (+ i 1) (cons (cons old-lbl-num i) lbl-map))) - (let () - (define (replacement-lbl-num x) (cdr (assv x lbl-map))) - (define (update-bb! bb) - (replace-label-references! bb replacement-lbl-num)) - (for-each update-bb! bb-list) - (bbs-lbl-counter-set! - bbs - (make-counter - (* (+ 1 (quotient (bbs-new-lbl! bbs) 1000)) 1000) - label-limit - bbs-limit-err)))))))) -(define (make-code bb gvm-instr sn) (vector bb gvm-instr sn)) -(define (code-bb code) (vector-ref code 0)) -(define (code-gvm-instr code) (vector-ref code 1)) -(define (code-slots-needed code) (vector-ref code 2)) -(define (code-slots-needed-set! code n) (vector-set! code 2 n)) -(define (bbs->code-list bbs) - (let ((code-list (linearize bbs))) - (setup-slots-needed! code-list) - code-list)) -(define (linearize bbs) - (let ((code-queue (queue-empty))) - (define (put-bb bb) - (define (put-instr gvm-instr) - (queue-put! code-queue (make-code bb gvm-instr #f))) - (put-instr (bb-label-instr bb)) - (for-each put-instr (bb-non-branch-instrs bb)) - (put-instr (bb-branch-instr bb))) - (for-each put-bb (queue->list (bbs-bb-queue bbs))) - (queue->list code-queue))) -(define (setup-slots-needed! code-list) - (if (null? code-list) - #f - (let* ((code (car code-list)) - (gvm-instr (code-gvm-instr code)) - (sn-rest (setup-slots-needed! (cdr code-list)))) - (case (gvm-instr-type gvm-instr) - ((label) - (if (> sn-rest (frame-size (gvm-instr-frame gvm-instr))) - (compiler-internal-error - "setup-slots-needed!, incoherent slots needed for LABEL")) - (code-slots-needed-set! code sn-rest) - #f) - ((ifjump jump) - (let ((sn (frame-size (gvm-instr-frame gvm-instr)))) - (code-slots-needed-set! code sn) - (need-gvm-instr gvm-instr sn))) - (else - (code-slots-needed-set! code sn-rest) - (need-gvm-instr gvm-instr sn-rest)))))) -(define (need-gvm-instrs non-branch branch) - (if (pair? non-branch) - (need-gvm-instr - (car non-branch) - (need-gvm-instrs (cdr non-branch) branch)) - (need-gvm-instr branch (frame-size (gvm-instr-frame branch))))) -(define (need-gvm-instr gvm-instr sn-rest) - (case (gvm-instr-type gvm-instr) - ((label) sn-rest) - ((apply) - (let ((loc (apply-loc gvm-instr))) - (need-gvm-opnds - (apply-opnds gvm-instr) - (need-gvm-loc-opnd loc (need-gvm-loc loc sn-rest))))) - ((copy) - (let ((loc (copy-loc gvm-instr))) - (need-gvm-opnd - (copy-opnd gvm-instr) - (need-gvm-loc-opnd loc (need-gvm-loc loc sn-rest))))) - ((close) - (let ((parms (close-parms gvm-instr))) - (define (need-parms-opnds p) - (if (null? p) - sn-rest - (need-gvm-opnds - (closure-parms-opnds (car p)) - (need-parms-opnds (cdr p))))) - (define (need-parms-loc p) - (if (null? p) - (need-parms-opnds parms) - (let ((loc (closure-parms-loc (car p)))) - (need-gvm-loc-opnd - loc - (need-gvm-loc loc (need-parms-loc (cdr p))))))) - (need-parms-loc parms))) - ((ifjump) (need-gvm-opnds (ifjump-opnds gvm-instr) sn-rest)) - ((jump) (need-gvm-opnd (jump-opnd gvm-instr) sn-rest)) - (else - (compiler-internal-error - "need-gvm-instr, unknown 'gvm-instr':" - gvm-instr)))) -(define (need-gvm-loc loc sn-rest) - (if (and loc (stk? loc) (>= (stk-num loc) sn-rest)) - (- (stk-num loc) 1) - sn-rest)) -(define (need-gvm-loc-opnd gvm-loc slots-needed) - (if (and gvm-loc (clo? gvm-loc)) - (need-gvm-opnd (clo-base gvm-loc) slots-needed) - slots-needed)) -(define (need-gvm-opnd gvm-opnd slots-needed) - (cond ((stk? gvm-opnd) (max (stk-num gvm-opnd) slots-needed)) - ((clo? gvm-opnd) (need-gvm-opnd (clo-base gvm-opnd) slots-needed)) - (else slots-needed))) -(define (need-gvm-opnds gvm-opnds slots-needed) - (if (null? gvm-opnds) - slots-needed - (need-gvm-opnd - (car gvm-opnds) - (need-gvm-opnds (cdr gvm-opnds) slots-needed)))) -(define (write-bb bb port) - (write-gvm-instr (bb-label-instr bb) port) - (display " [precedents=" port) - (write (map bb-lbl-num (bb-precedents bb)) port) - (display "]" port) - (newline port) - (for-each - (lambda (x) (write-gvm-instr x port) (newline port)) - (bb-non-branch-instrs bb)) - (write-gvm-instr (bb-branch-instr bb) port)) -(define (write-bbs bbs port) - (for-each - (lambda (bb) - (if (= (bb-lbl-num bb) (bbs-entry-lbl-num bbs)) - (begin (display "**** Entry block:" port) (newline port))) - (write-bb bb port) - (newline port)) - (queue->list (bbs-bb-queue bbs)))) -(define (virtual.dump proc port) - (let ((proc-seen (queue-empty)) (proc-left (queue-empty))) - (define (scan-opnd gvm-opnd) - (cond ((obj? gvm-opnd) - (let ((val (obj-val gvm-opnd))) - (if (and (proc-obj? val) - (proc-obj-code val) - (not (memq val (queue->list proc-seen)))) - (begin - (queue-put! proc-seen val) - (queue-put! proc-left val))))) - ((clo? gvm-opnd) (scan-opnd (clo-base gvm-opnd))))) - (define (dump-proc p) - (define (scan-code code) - (let ((gvm-instr (code-gvm-instr code))) - (write-gvm-instr gvm-instr port) - (newline port) - (case (gvm-instr-type gvm-instr) - ((apply) - (for-each scan-opnd (apply-opnds gvm-instr)) - (if (apply-loc gvm-instr) (scan-opnd (apply-loc gvm-instr)))) - ((copy) - (scan-opnd (copy-opnd gvm-instr)) - (scan-opnd (copy-loc gvm-instr))) - ((close) - (for-each - (lambda (parms) - (scan-opnd (closure-parms-loc parms)) - (for-each scan-opnd (closure-parms-opnds parms))) - (close-parms gvm-instr))) - ((ifjump) (for-each scan-opnd (ifjump-opnds gvm-instr))) - ((jump) (scan-opnd (jump-opnd gvm-instr))) - (else '())))) - (if (proc-obj-primitive? p) - (display "**** #[primitive " port) - (display "**** #[procedure " port)) - (display (proc-obj-name p) port) - (display "] =" port) - (newline port) - (let loop ((l (bbs->code-list (proc-obj-code p))) - (prev-filename "") - (prev-line 0)) - (if (pair? l) - (let* ((code (car l)) - (instr (code-gvm-instr code)) - (src (comment-get (gvm-instr-comment instr) 'source)) - (loc (and src (source-locat src))) - (filename - (if (and loc (eq? (vector-ref loc 0) 'file)) - (vector-ref loc 1) - prev-filename)) - (line (if (and loc (eq? (vector-ref loc 0) 'file)) - (vector-ref loc 3) - prev-line))) - (if (or (not (string=? filename prev-filename)) - (not (= line prev-line))) - (begin - (display "#line " port) - (display line port) - (if (not (string=? filename prev-filename)) - (begin (display " " port) (write filename port))) - (newline port))) - (scan-code code) - (loop (cdr l) filename line)) - (newline port)))) - (scan-opnd (make-obj proc)) - (let loop () - (if (not (queue-empty? proc-left)) - (begin (dump-proc (queue-get! proc-left)) (loop)))))) -(define (write-gvm-instr gvm-instr port) - (define (write-closure-parms parms) - (display " " port) - (let ((len (+ 1 (write-gvm-opnd (closure-parms-loc parms) port)))) - (display " = (" port) - (let ((len (+ len (+ 4 (write-gvm-lbl (closure-parms-lbl parms) port))))) - (+ len - (write-terminated-opnd-list (closure-parms-opnds parms) port))))) - (define (write-terminated-opnd-list l port) - (let loop ((l l) (len 0)) - (if (pair? l) - (let ((opnd (car l))) - (display " " port) - (loop (cdr l) (+ len (+ 1 (write-gvm-opnd opnd port))))) - (begin (display ")" port) (+ len 1))))) - (define (write-param-pattern gvm-instr port) - (let ((len (if (not (= (label-entry-min gvm-instr) - (label-entry-nb-parms gvm-instr))) - (let ((len (write-returning-len - (label-entry-min gvm-instr) - port))) - (display "-" port) - (+ len 1)) - 0))) - (let ((len (+ len - (write-returning-len - (label-entry-nb-parms gvm-instr) - port)))) - (if (label-entry-rest? gvm-instr) - (begin (display "+" port) (+ len 1)) - len)))) - (define (write-prim-applic prim opnds port) - (display "(" port) - (let ((len (+ 1 (display-returning-len (proc-obj-name prim) port)))) - (+ len (write-terminated-opnd-list opnds port)))) - (define (write-instr gvm-instr) - (case (gvm-instr-type gvm-instr) - ((label) - (let ((len (write-gvm-lbl (label-lbl-num gvm-instr) port))) - (display " " port) - (let ((len (+ len - (+ 1 - (write-returning-len - (frame-size (gvm-instr-frame gvm-instr)) - port))))) - (case (label-type gvm-instr) - ((simple) len) - ((entry) - (if (label-entry-closed? gvm-instr) - (begin - (display " closure-entry-point " port) - (+ len (+ 21 (write-param-pattern gvm-instr port)))) - (begin - (display " entry-point " port) - (+ len (+ 13 (write-param-pattern gvm-instr port)))))) - ((return) (display " return-point" port) (+ len 13)) - ((task-entry) (display " task-entry-point" port) (+ len 17)) - ((task-return) (display " task-return-point" port) (+ len 18)) - (else - (compiler-internal-error - "write-gvm-instr, unknown label type")))))) - ((apply) - (display " " port) - (let ((len (+ 2 - (if (apply-loc gvm-instr) - (let ((len (write-gvm-opnd - (apply-loc gvm-instr) - port))) - (display " = " port) - (+ len 3)) - 0)))) - (+ len - (write-prim-applic - (apply-prim gvm-instr) - (apply-opnds gvm-instr) - port)))) - ((copy) - (display " " port) - (let ((len (+ 2 (write-gvm-opnd (copy-loc gvm-instr) port)))) - (display " = " port) - (+ len (+ 3 (write-gvm-opnd (copy-opnd gvm-instr) port))))) - ((close) - (display " close" port) - (let ((len (+ 7 (write-closure-parms (car (close-parms gvm-instr)))))) - (let loop ((l (cdr (close-parms gvm-instr))) (len len)) - (if (pair? l) - (let ((x (car l))) - (display "," port) - (loop (cdr l) (+ len (+ 1 (write-closure-parms x))))) - len)))) - ((ifjump) - (display " if " port) - (let ((len (+ 5 - (write-prim-applic - (ifjump-test gvm-instr) - (ifjump-opnds gvm-instr) - port)))) - (let ((len (+ len - (if (ifjump-poll? gvm-instr) - (begin (display " jump* " port) 7) - (begin (display " jump " port) 6))))) - (let ((len (+ len - (write-returning-len - (frame-size (gvm-instr-frame gvm-instr)) - port)))) - (display " " port) - (let ((len (+ len - (+ 1 - (write-gvm-lbl (ifjump-true gvm-instr) port))))) - (display " else " port) - (+ len (+ 6 (write-gvm-lbl (ifjump-false gvm-instr) port)))))))) - ((jump) - (display " " port) - (let ((len (+ 2 - (if (jump-poll? gvm-instr) - (begin (display "jump* " port) 6) - (begin (display "jump " port) 5))))) - (let ((len (+ len - (write-returning-len - (frame-size (gvm-instr-frame gvm-instr)) - port)))) - (display " " port) - (let ((len (+ len - (+ 1 (write-gvm-opnd (jump-opnd gvm-instr) port))))) - (+ len - (if (jump-nb-args gvm-instr) - (begin - (display " " port) - (+ 1 - (write-returning-len (jump-nb-args gvm-instr) port))) - 0)))))) - (else - (compiler-internal-error - "write-gvm-instr, unknown 'gvm-instr':" - gvm-instr)))) - (define (spaces n) - (if (> n 0) - (if (> n 7) - (begin (display " " port) (spaces (- n 8))) - (begin (display " " port) (spaces (- n 1)))))) - (let ((len (write-instr gvm-instr))) - (spaces (- 40 len)) - (display " " port) - (write-frame (gvm-instr-frame gvm-instr) port)) - (let ((x (gvm-instr-comment gvm-instr))) - (if x - (let ((y (comment-get x 'text))) - (if y (begin (display " ; " port) (display y port))))))) -(define (write-frame frame port) - (define (write-var var opnd sep) - (display sep port) - (write-gvm-opnd opnd port) - (if var - (begin - (display "=" port) - (cond ((eq? var closure-env-var) - (write (map (lambda (var) (var-name var)) - (frame-closed frame)) - port)) - ((eq? var ret-var) (display "#" port)) - ((temp-var? var) (display "." port)) - (else (write (var-name var) port)))))) - (define (live? var) - (let ((live (frame-live frame))) - (or (set-member? var live) - (and (eq? var closure-env-var) - (not (set-empty? - (set-intersection - live - (list->set (frame-closed frame))))))))) - (let loop1 ((i 1) (l (reverse (frame-slots frame))) (sep "; ")) - (if (pair? l) - (let ((var (car l))) - (write-var (if (live? var) var #f) (make-stk i) sep) - (loop1 (+ i 1) (cdr l) " ")) - (let loop2 ((i 0) (l (frame-regs frame)) (sep sep)) - (if (pair? l) - (let ((var (car l))) - (if (live? var) - (begin - (write-var var (make-reg i) sep) - (loop2 (+ i 1) (cdr l) " ")) - (loop2 (+ i 1) (cdr l) sep)))))))) -(define (write-gvm-opnd gvm-opnd port) - (define (write-opnd) - (cond ((reg? gvm-opnd) - (display "+" port) - (+ 1 (write-returning-len (reg-num gvm-opnd) port))) - ((stk? gvm-opnd) - (display "-" port) - (+ 1 (write-returning-len (stk-num gvm-opnd) port))) - ((glo? gvm-opnd) (write-returning-len (glo-name gvm-opnd) port)) - ((clo? gvm-opnd) - (let ((len (write-gvm-opnd (clo-base gvm-opnd) port))) - (display "(" port) - (let ((len (+ len - (+ 1 - (write-returning-len - (clo-index gvm-opnd) - port))))) - (display ")" port) - (+ len 1)))) - ((lbl? gvm-opnd) (write-gvm-lbl (lbl-num gvm-opnd) port)) - ((obj? gvm-opnd) - (display "'" port) - (+ (write-gvm-obj (obj-val gvm-opnd) port) 1)) - (else - (compiler-internal-error - "write-gvm-opnd, unknown 'gvm-opnd':" - gvm-opnd)))) - (write-opnd)) -(define (write-gvm-lbl lbl port) - (display "#" port) - (+ (write-returning-len lbl port) 1)) -(define (write-gvm-obj val port) - (cond ((false-object? val) (display "#f" port) 2) - ((undef-object? val) (display "#[undefined]" port) 12) - ((proc-obj? val) - (if (proc-obj-primitive? val) - (display "#[primitive " port) - (display "#[procedure " port)) - (let ((len (display-returning-len (proc-obj-name val) port))) - (display "]" port) - (+ len 13))) - (else (write-returning-len val port)))) -(define (virtual.begin!) - (set! *opnd-table* (make-vector opnd-table-size)) - (set! *opnd-table-alloc* 0) - '()) -(define (virtual.end!) (set! *opnd-table* '()) '()) -(define (make-target version name) - (define current-target-version 4) - (if (not (= version current-target-version)) - (compiler-internal-error - "make-target, version of target package is not current" - name)) - (let ((x (make-vector 11))) (vector-set! x 1 name) x)) -(define (target-name x) (vector-ref x 1)) -(define (target-begin! x) (vector-ref x 2)) -(define (target-begin!-set! x y) (vector-set! x 2 y)) -(define (target-end! x) (vector-ref x 3)) -(define (target-end!-set! x y) (vector-set! x 3 y)) -(define (target-dump x) (vector-ref x 4)) -(define (target-dump-set! x y) (vector-set! x 4 y)) -(define (target-nb-regs x) (vector-ref x 5)) -(define (target-nb-regs-set! x y) (vector-set! x 5 y)) -(define (target-prim-info x) (vector-ref x 6)) -(define (target-prim-info-set! x y) (vector-set! x 6 y)) -(define (target-label-info x) (vector-ref x 7)) -(define (target-label-info-set! x y) (vector-set! x 7 y)) -(define (target-jump-info x) (vector-ref x 8)) -(define (target-jump-info-set! x y) (vector-set! x 8 y)) -(define (target-proc-result x) (vector-ref x 9)) -(define (target-proc-result-set! x y) (vector-set! x 9 y)) -(define (target-task-return x) (vector-ref x 10)) -(define (target-task-return-set! x y) (vector-set! x 10 y)) -(define targets-loaded '()) -(define (get-target name) - (let ((x (assq name targets-loaded))) - (if x (cdr x) (compiler-error "Target package is not available" name)))) -(define (put-target targ) - (let* ((name (target-name targ)) (x (assq name targets-loaded))) - (if x - (set-cdr! x targ) - (set! targets-loaded (cons (cons name targ) targets-loaded))) - '())) -(define (default-target) - (if (null? targets-loaded) - (compiler-error "No target package is available") - (car (car targets-loaded)))) -(define (select-target! name info-port) - (set! target (get-target name)) - ((target-begin! target) info-port) - (set! target.dump (target-dump target)) - (set! target.nb-regs (target-nb-regs target)) - (set! target.prim-info (target-prim-info target)) - (set! target.label-info (target-label-info target)) - (set! target.jump-info (target-jump-info target)) - (set! target.proc-result (target-proc-result target)) - (set! target.task-return (target-task-return target)) - (set! **not-proc-obj (target.prim-info **not-sym)) - '()) -(define (unselect-target!) ((target-end! target)) '()) -(define target '()) -(define target.dump '()) -(define target.nb-regs '()) -(define target.prim-info '()) -(define target.label-info '()) -(define target.jump-info '()) -(define target.proc-result '()) -(define target.task-return '()) -(define **not-proc-obj '()) -(define (target.specialized-prim-info* name decl) - (let ((x (target.prim-info* name decl))) - (and x ((proc-obj-specialize x) decl)))) -(define (target.prim-info* name decl) - (and (if (standard-procedure name decl) - (standard-binding? name decl) - (extended-binding? name decl)) - (target.prim-info name))) -(define generic-sym (string->canonical-symbol "GENERIC")) -(define fixnum-sym (string->canonical-symbol "FIXNUM")) -(define flonum-sym (string->canonical-symbol "FLONUM")) -(define-namable-decl generic-sym 'arith) -(define-namable-decl fixnum-sym 'arith) -(define-namable-decl flonum-sym 'arith) -(define (arith-implementation name decls) - (declaration-value 'arith name generic-sym decls)) -(define (cf source target-name . opts) - (let* ((dest (file-root source)) - (module-name (file-name dest)) - (info-port (if (memq 'verbose opts) (current-output-port) #f)) - (result (compile-program - (list **include-sym source) - (if target-name target-name (default-target)) - opts - module-name - dest - info-port))) - (if (and info-port (not (eq? info-port (current-output-port)))) - (close-output-port info-port)) - result)) -(define (ce source target-name . opts) - (let* ((dest "program") - (module-name "program") - (info-port (if (memq 'verbose opts) (current-output-port) #f)) - (result (compile-program - source - (if target-name target-name (default-target)) - opts - module-name - dest - info-port))) - (if (and info-port (not (eq? info-port (current-output-port)))) - (close-output-port info-port)) - result)) -(define wrap-program #f) -(set! wrap-program (lambda (program) program)) -(define (compile-program program target-name opts module-name dest info-port) - (define (compiler-body) - (if (not (valid-module-name? module-name)) - (compiler-error - "Invalid characters in file name (must be a symbol with no \"#\")") - (begin - (ptree.begin! info-port) - (virtual.begin!) - (select-target! target-name info-port) - (parse-program - (list (expression->source (wrap-program program) #f)) - (make-global-environment) - module-name - (lambda (lst env c-intf) - (let ((parsed-program - (map (lambda (x) (normalize-parse-tree (car x) (cdr x))) - lst))) - (if (memq 'expansion opts) - (let ((port (current-output-port))) - (display "Expansion:" port) - (newline port) - (let loop ((l parsed-program)) - (if (pair? l) - (let ((ptree (car l))) - (pp-expression - (parse-tree->expression ptree) - port) - (loop (cdr l))))) - (newline port))) - (let ((module-init-proc - (compile-parsed-program - module-name - parsed-program - env - c-intf - info-port))) - (if (memq 'report opts) (generate-report env)) - (if (memq 'gvm opts) - (let ((gvm-port - (open-output-file (string-append dest ".gvm")))) - (virtual.dump module-init-proc gvm-port) - (close-output-port gvm-port))) - (target.dump module-init-proc dest c-intf opts) - (dump-c-intf module-init-proc dest c-intf))))) - (unselect-target!) - (virtual.end!) - (ptree.end!) - #t))) - (let ((successful (with-exception-handling compiler-body))) - (if info-port - (if successful - (begin - (display "Compilation finished." info-port) - (newline info-port)) - (begin - (display "Compilation terminated abnormally." info-port) - (newline info-port)))) - successful)) -(define (valid-module-name? module-name) - (define (valid-char? c) - (and (not (memv c - '(#\# - #\; - #\( - #\) - #\space - #\[ - #\] - #\{ - #\} - #\" - #\' - #\` - #\,))) - (not (char-whitespace? c)))) - (let ((n (string-length module-name))) - (and (> n 0) - (not (string=? module-name ".")) - (not (string->number module-name 10)) - (let loop ((i 0)) - (if (< i n) - (if (valid-char? (string-ref module-name i)) (loop (+ i 1)) #f) - #t))))) -(define (dump-c-intf module-init-proc dest c-intf) - (let ((decls (c-intf-decls c-intf)) - (procs (c-intf-procs c-intf)) - (inits (c-intf-inits c-intf))) - (if (or (not (null? decls)) (not (null? procs)) (not (null? inits))) - (let* ((module-name (proc-obj-name module-init-proc)) - (filename (string-append dest ".c")) - (port (open-output-file filename))) - (display "/* File: \"" port) - (display filename port) - (display "\", C-interface file produced by Gambit " port) - (display compiler-version port) - (display " */" port) - (newline port) - (display "#define " port) - (display c-id-prefix port) - (display "MODULE_NAME \"" port) - (display module-name port) - (display "\"" port) - (newline port) - (display "#define " port) - (display c-id-prefix port) - (display "MODULE_LINKER " port) - (display c-id-prefix port) - (display (scheme-id->c-id module-name) port) - (newline port) - (display "#define " port) - (display c-id-prefix port) - (display "VERSION \"" port) - (display compiler-version port) - (display "\"" port) - (newline port) - (if (not (null? procs)) - (begin - (display "#define " port) - (display c-id-prefix port) - (display "C_PRC_COUNT " port) - (display (length procs) port) - (newline port))) - (display "#include \"gambit.h\"" port) - (newline port) - (display c-id-prefix port) - (display "BEGIN_MODULE" port) - (newline port) - (for-each - (lambda (x) - (let ((scheme-name (vector-ref x 0))) - (display c-id-prefix port) - (display "SUPPLY_PRM(" port) - (display c-id-prefix port) - (display "P_" port) - (display (scheme-id->c-id scheme-name) port) - (display ")" port) - (newline port))) - procs) - (newline port) - (for-each (lambda (x) (display x port) (newline port)) decls) - (if (not (null? procs)) - (begin - (for-each - (lambda (x) - (let ((scheme-name (vector-ref x 0)) - (c-name (vector-ref x 1)) - (arity (vector-ref x 2)) - (def (vector-ref x 3))) - (display c-id-prefix port) - (display "BEGIN_C_COD(" port) - (display c-name port) - (display "," port) - (display c-id-prefix port) - (display "P_" port) - (display (scheme-id->c-id scheme-name) port) - (display "," port) - (display arity port) - (display ")" port) - (newline port) - (display "#undef ___ARG1" port) - (newline port) - (display "#define ___ARG1 ___R1" port) - (newline port) - (display "#undef ___ARG2" port) - (newline port) - (display "#define ___ARG2 ___R2" port) - (newline port) - (display "#undef ___ARG3" port) - (newline port) - (display "#define ___ARG3 ___R3" port) - (newline port) - (display "#undef ___RESULT" port) - (newline port) - (display "#define ___RESULT ___R1" port) - (newline port) - (display def port) - (display c-id-prefix port) - (display "END_C_COD" port) - (newline port))) - procs) - (newline port) - (display c-id-prefix port) - (display "BEGIN_C_PRC" port) - (newline port) - (let loop ((i 0) (lst procs)) - (if (not (null? lst)) - (let* ((x (car lst)) - (scheme-name (vector-ref x 0)) - (c-name (vector-ref x 1)) - (arity (vector-ref x 2))) - (if (= i 0) (display " " port) (display "," port)) - (display c-id-prefix port) - (display "DEF_C_PRC(" port) - (display c-name port) - (display "," port) - (display c-id-prefix port) - (display "P_" port) - (display (scheme-id->c-id scheme-name) port) - (display "," port) - (display arity port) - (display ")" port) - (newline port) - (loop (+ i 1) (cdr lst))))) - (display c-id-prefix port) - (display "END_C_PRC" port) - (newline port))) - (newline port) - (display c-id-prefix port) - (display "BEGIN_PRM" port) - (newline port) - (for-each (lambda (x) (display x port) (newline port)) inits) - (display c-id-prefix port) - (display "END_PRM" port) - (newline port) - (close-output-port port))))) -(define (generate-report env) - (let ((vars (sort-variables (env-global-variables env))) - (decl (env-declarations env))) - (define (report title pred? vars wrote-something?) - (if (pair? vars) - (let ((var (car vars))) - (if (pred? var) - (begin - (if (not wrote-something?) - (begin (display " ") (display title) (newline))) - (let loop1 ((l (var-refs var)) (r? #f) (c? #f)) - (if (pair? l) - (let* ((x (car l)) (y (node-parent x))) - (if (and y (app? y) (eq? x (app-oper y))) - (loop1 (cdr l) r? #t) - (loop1 (cdr l) #t c?))) - (let loop2 ((l (var-sets var)) (d? #f) (a? #f)) - (if (pair? l) - (if (set? (car l)) - (loop2 (cdr l) d? #t) - (loop2 (cdr l) #t a?)) - (begin - (display " [") - (if d? (display "D") (display " ")) - (if a? (display "A") (display " ")) - (if r? (display "R") (display " ")) - (if c? (display "C") (display " ")) - (display "] ") - (display (var-name var)) - (newline)))))) - (report title pred? (cdr vars) #t)) - (cons (car vars) - (report title pred? (cdr vars) wrote-something?)))) - (begin (if wrote-something? (newline)) '()))) - (display "Global variable usage:") - (newline) - (newline) - (report "OTHERS" - (lambda (x) #t) - (report "EXTENDED" - (lambda (x) (target.prim-info (var-name x))) - (report "STANDARD" - (lambda (x) (standard-procedure (var-name x) decl)) - vars - #f) - #f) - #f))) -(define (compile-parsed-program module-name program env c-intf info-port) - (if info-port (display "Compiling:" info-port)) - (set! trace-indentation 0) - (set! *bbs* (make-bbs)) - (set! *global-env* env) - (set! proc-queue '()) - (set! constant-vars '()) - (set! known-procs '()) - (restore-context (make-context 0 '() (list ret-var) '() (entry-poll) #f)) - (let* ((entry-lbl (bbs-new-lbl! *bbs*)) - (body-lbl (bbs-new-lbl! *bbs*)) - (frame (current-frame ret-var-set)) - (comment (if (null? program) #f (source-comment (car program))))) - (bbs-entry-lbl-num-set! *bbs* entry-lbl) - (set! entry-bb - (make-bb (make-label-entry entry-lbl 0 0 #f #f frame comment) *bbs*)) - (bb-put-branch! entry-bb (make-jump (make-lbl body-lbl) #f #f frame #f)) - (set! *bb* (make-bb (make-label-simple body-lbl frame comment) *bbs*)) - (let loop1 ((l (c-intf-procs c-intf))) - (if (not (null? l)) - (let* ((x (car l)) - (name (vector-ref x 0)) - (sym (string->canonical-symbol name)) - (var (env-lookup-global-var *global-env* sym))) - (add-constant-var - var - (make-obj (make-proc-obj name #t #f 0 #t '() '(#f)))) - (loop1 (cdr l))))) - (let loop2 ((l program)) - (if (not (null? l)) - (let ((node (car l))) - (if (def? node) - (let* ((var (def-var node)) (val (global-val var))) - (if (and val (prc? val)) - (add-constant-var - var - (make-obj - (make-proc-obj - (symbol->string (var-name var)) - #t - #f - (call-pattern val) - #t - '() - '(#f))))))) - (loop2 (cdr l))))) - (let loop3 ((l program)) - (if (null? l) - (let ((ret-opnd (var->opnd ret-var))) - (seal-bb #t 'return) - (dealloc-slots nb-slots) - (bb-put-branch! - *bb* - (make-jump ret-opnd #f #f (current-frame (set-empty)) #f))) - (let ((node (car l))) - (if (def? node) - (begin - (gen-define (def-var node) (def-val node) info-port) - (loop3 (cdr l))) - (if (null? (cdr l)) - (gen-node node ret-var-set 'tail) - (begin - (gen-node node ret-var-set 'need) - (loop3 (cdr l)))))))) - (let loop4 () - (if (pair? proc-queue) - (let ((x (car proc-queue))) - (set! proc-queue (cdr proc-queue)) - (gen-proc (car x) (cadr x) (caddr x) info-port) - (trace-unindent info-port) - (loop4)))) - (if info-port (begin (newline info-port) (newline info-port))) - (bbs-purify! *bbs*) - (let ((proc (make-proc-obj - (string-append "#!" module-name) - #t - *bbs* - '(0) - #t - '() - '(#f)))) - (set! *bb* '()) - (set! *bbs* '()) - (set! *global-env* '()) - (set! proc-queue '()) - (set! constant-vars '()) - (set! known-procs '()) - (clear-context) - proc))) -(define *bb* '()) -(define *bbs* '()) -(define *global-env* '()) -(define proc-queue '()) -(define constant-vars '()) -(define known-procs '()) -(define trace-indentation '()) -(define (trace-indent info-port) - (set! trace-indentation (+ trace-indentation 1)) - (if info-port - (begin - (newline info-port) - (let loop ((i trace-indentation)) - (if (> i 0) (begin (display " " info-port) (loop (- i 1)))))))) -(define (trace-unindent info-port) - (set! trace-indentation (- trace-indentation 1))) -(define (gen-define var node info-port) - (if (prc? node) - (let* ((p-bbs *bbs*) - (p-bb *bb*) - (p-proc-queue proc-queue) - (p-known-procs known-procs) - (p-context (current-context)) - (bbs (make-bbs)) - (lbl1 (bbs-new-lbl! bbs)) - (lbl2 (bbs-new-lbl! bbs)) - (context (entry-context node '())) - (frame (context->frame - context - (set-union (free-variables (prc-body node)) ret-var-set))) - (bb1 (make-bb (make-label-entry - lbl1 - (length (prc-parms node)) - (prc-min node) - (prc-rest node) - #f - frame - (source-comment node)) - bbs)) - (bb2 (make-bb (make-label-simple lbl2 frame (source-comment node)) - bbs))) - (define (do-body) - (gen-proc node bb2 context info-port) - (let loop () - (if (pair? proc-queue) - (let ((x (car proc-queue))) - (set! proc-queue (cdr proc-queue)) - (gen-proc (car x) (cadr x) (caddr x) info-port) - (trace-unindent info-port) - (loop)))) - (trace-unindent info-port) - (bbs-purify! *bbs*)) - (context-entry-bb-set! context bb1) - (bbs-entry-lbl-num-set! bbs lbl1) - (bb-put-branch! bb1 (make-jump (make-lbl lbl2) #f #f frame #f)) - (set! *bbs* bbs) - (set! proc-queue '()) - (set! known-procs '()) - (if (constant-var? var) - (let-constant-var - var - (make-lbl lbl1) - (lambda () (add-known-proc lbl1 node) (do-body))) - (do-body)) - (set! *bbs* p-bbs) - (set! *bb* p-bb) - (set! proc-queue p-proc-queue) - (set! known-procs p-known-procs) - (restore-context p-context) - (let* ((x (assq var constant-vars)) - (proc (if x - (let ((p (cdr x))) - (proc-obj-code-set! (obj-val p) bbs) - p) - (make-obj - (make-proc-obj - (symbol->string (var-name var)) - #f - bbs - (call-pattern node) - #t - '() - '(#f)))))) - (put-copy - proc - (make-glo (var-name var)) - #f - ret-var-set - (source-comment node)))) - (put-copy - (gen-node node ret-var-set 'need) - (make-glo (var-name var)) - #f - ret-var-set - (source-comment node)))) -(define (call-pattern node) - (make-pattern (prc-min node) (length (prc-parms node)) (prc-rest node))) -(define (make-context nb-slots slots regs closed poll entry-bb) - (vector nb-slots slots regs closed poll entry-bb)) -(define (context-nb-slots x) (vector-ref x 0)) -(define (context-slots x) (vector-ref x 1)) -(define (context-regs x) (vector-ref x 2)) -(define (context-closed x) (vector-ref x 3)) -(define (context-poll x) (vector-ref x 4)) -(define (context-entry-bb x) (vector-ref x 5)) -(define (context-entry-bb-set! x y) (vector-set! x 5 y)) -(define nb-slots '()) -(define slots '()) -(define regs '()) -(define closed '()) -(define poll '()) -(define entry-bb '()) -(define (restore-context context) - (set! nb-slots (context-nb-slots context)) - (set! slots (context-slots context)) - (set! regs (context-regs context)) - (set! closed (context-closed context)) - (set! poll (context-poll context)) - (set! entry-bb (context-entry-bb context))) -(define (clear-context) - (restore-context (make-context '() '() '() '() '() '()))) -(define (current-context) - (make-context nb-slots slots regs closed poll entry-bb)) -(define (current-frame live) (make-frame nb-slots slots regs closed live)) -(define (context->frame context live) - (make-frame - (context-nb-slots context) - (context-slots context) - (context-regs context) - (context-closed context) - live)) -(define (make-poll since-entry? delta) (cons since-entry? delta)) -(define (poll-since-entry? x) (car x)) -(define (poll-delta x) (cdr x)) -(define (entry-poll) (make-poll #f (- poll-period poll-head))) -(define (return-poll poll) - (let ((delta (poll-delta poll))) - (make-poll (poll-since-entry? poll) (+ poll-head (max delta poll-tail))))) -(define (poll-merge poll other-poll) - (make-poll - (or (poll-since-entry? poll) (poll-since-entry? other-poll)) - (max (poll-delta poll) (poll-delta other-poll)))) -(define poll-period #f) -(set! poll-period 90) -(define poll-head #f) -(set! poll-head 15) -(define poll-tail #f) -(set! poll-tail 15) -(define (entry-context proc closed) - (define (empty-vars-list n) - (if (> n 0) (cons empty-var (empty-vars-list (- n 1))) '())) - (let* ((parms (prc-parms proc)) - (pc (target.label-info - (prc-min proc) - (length parms) - (prc-rest proc) - (not (null? closed)))) - (fs (pcontext-fs pc)) - (slots-list (empty-vars-list fs)) - (regs-list (empty-vars-list target.nb-regs))) - (define (assign-var-to-loc var loc) - (let ((x (cond ((reg? loc) - (let ((i (reg-num loc))) - (if (<= i target.nb-regs) - (nth-after regs-list i) - (compiler-internal-error - "entry-context, reg out of bound in back-end's pcontext")))) - ((stk? loc) - (let ((i (stk-num loc))) - (if (<= i fs) - (nth-after slots-list (- fs i)) - (compiler-internal-error - "entry-context, stk out of bound in back-end's pcontext")))) - (else - (compiler-internal-error - "entry-context, loc other than reg or stk in back-end's pcontext"))))) - (if (eq? (car x) empty-var) - (set-car! x var) - (compiler-internal-error - "entry-context, duplicate location in back-end's pcontext")))) - (let loop ((l (pcontext-map pc))) - (if (not (null? l)) - (let* ((couple (car l)) (name (car couple)) (loc (cdr couple))) - (cond ((eq? name 'return) (assign-var-to-loc ret-var loc)) - ((eq? name 'closure-env) - (assign-var-to-loc closure-env-var loc)) - (else (assign-var-to-loc (list-ref parms (- name 1)) loc))) - (loop (cdr l))))) - (make-context fs slots-list regs-list closed (entry-poll) #f))) -(define (get-var opnd) - (cond ((glo? opnd) (env-lookup-global-var *global-env* (glo-name opnd))) - ((reg? opnd) (list-ref regs (reg-num opnd))) - ((stk? opnd) (list-ref slots (- nb-slots (stk-num opnd)))) - (else - (compiler-internal-error - "get-var, location must be global, register or stack slot")))) -(define (put-var opnd new) - (define (put-v opnd new) - (cond ((reg? opnd) (set! regs (replace-nth regs (reg-num opnd) new))) - ((stk? opnd) - (set! slots (replace-nth slots (- nb-slots (stk-num opnd)) new))) - (else - (compiler-internal-error - "put-var, location must be register or stack slot, for var:" - (var-name new))))) - (if (eq? new ret-var) - (let ((x (var->opnd ret-var))) (and x (put-v x empty-var)))) - (put-v opnd new)) -(define (flush-regs) (set! regs '())) -(define (push-slot) - (set! nb-slots (+ nb-slots 1)) - (set! slots (cons empty-var slots))) -(define (dealloc-slots n) - (set! nb-slots (- nb-slots n)) - (set! slots (nth-after slots n))) -(define (pop-slot) (dealloc-slots 1)) -(define (replace-nth l i v) - (if (null? l) - (if (= i 0) (list v) (cons empty-var (replace-nth l (- i 1) v))) - (if (= i 0) - (cons v (cdr l)) - (cons (car l) (replace-nth (cdr l) (- i 1) v))))) -(define (live-vars live) - (if (not (set-empty? (set-intersection live (list->set closed)))) - (set-adjoin live closure-env-var) - live)) -(define (dead-slots live) - (let ((live-v (live-vars live))) - (define (loop s l i) - (cond ((null? l) (list->set (reverse s))) - ((set-member? (car l) live-v) (loop s (cdr l) (- i 1))) - (else (loop (cons i s) (cdr l) (- i 1))))) - (loop '() slots nb-slots))) -(define (live-slots live) - (let ((live-v (live-vars live))) - (define (loop s l i) - (cond ((null? l) (list->set (reverse s))) - ((set-member? (car l) live-v) (loop (cons i s) (cdr l) (- i 1))) - (else (loop s (cdr l) (- i 1))))) - (loop '() slots nb-slots))) -(define (dead-regs live) - (let ((live-v (live-vars live))) - (define (loop s l i) - (cond ((>= i target.nb-regs) (list->set (reverse s))) - ((null? l) (loop (cons i s) l (+ i 1))) - ((and (set-member? (car l) live-v) (not (memq (car l) slots))) - (loop s (cdr l) (+ i 1))) - (else (loop (cons i s) (cdr l) (+ i 1))))) - (loop '() regs 0))) -(define (live-regs live) - (let ((live-v (live-vars live))) - (define (loop s l i) - (cond ((null? l) (list->set (reverse s))) - ((and (set-member? (car l) live-v) (not (memq (car l) slots))) - (loop (cons i s) (cdr l) (+ i 1))) - (else (loop s (cdr l) (+ i 1))))) - (loop '() regs 0))) -(define (lowest-dead-slot live) - (make-stk (or (lowest (dead-slots live)) (+ nb-slots 1)))) -(define (highest-live-slot live) (make-stk (or (highest (live-slots live)) 0))) -(define (lowest-dead-reg live) - (let ((x (lowest (set-remove (dead-regs live) 0)))) (if x (make-reg x) #f))) -(define (highest-dead-reg live) - (let ((x (highest (dead-regs live)))) (if x (make-reg x) #f))) -(define (highest set) (if (set-empty? set) #f (apply max (set->list set)))) -(define (lowest set) (if (set-empty? set) #f (apply min (set->list set)))) -(define (above set n) (set-keep (lambda (x) (> x n)) set)) -(define (below set n) (set-keep (lambda (x) (< x n)) set)) -(define (var->opnd var) - (let ((x (assq var constant-vars))) - (if x - (cdr x) - (if (global? var) - (make-glo (var-name var)) - (let ((n (pos-in-list var regs))) - (if n - (make-reg n) - (let ((n (pos-in-list var slots))) - (if n - (make-stk (- nb-slots n)) - (let ((n (pos-in-list var closed))) - (if n - (make-clo (var->opnd closure-env-var) (+ n 1)) - (compiler-internal-error - "var->opnd, variable is not accessible:" - (var-name var)))))))))))) -(define (source-comment node) - (let ((x (make-comment))) (comment-put! x 'source (node-source node)) x)) -(define (sort-variables lst) - (sort-list - lst - (lambda (x y) - (stringstring (var-name x)) (symbol->string (var-name y)))))) -(define (add-constant-var var opnd) - (set! constant-vars (cons (cons var opnd) constant-vars))) -(define (let-constant-var var opnd thunk) - (let* ((x (assq var constant-vars)) (temp (cdr x))) - (set-cdr! x opnd) - (thunk) - (set-cdr! x temp))) -(define (constant-var? var) (assq var constant-vars)) -(define (not-constant-var? var) (not (constant-var? var))) -(define (add-known-proc label proc) - (set! known-procs (cons (cons label proc) known-procs))) -(define (gen-proc proc bb context info-port) - (trace-indent info-port) - (if info-port - (if (prc-name proc) - (display (prc-name proc) info-port) - (display "\"unknown\"" info-port))) - (let ((lbl (bb-lbl-num bb)) - (live (set-union (free-variables (prc-body proc)) ret-var-set))) - (set! *bb* bb) - (restore-context context) - (gen-node (prc-body proc) ret-var-set 'tail))) -(define (schedule-gen-proc proc closed-list) - (let* ((lbl1 (bbs-new-lbl! *bbs*)) - (lbl2 (bbs-new-lbl! *bbs*)) - (context (entry-context proc closed-list)) - (frame (context->frame - context - (set-union (free-variables (prc-body proc)) ret-var-set))) - (bb1 (make-bb (make-label-entry - lbl1 - (length (prc-parms proc)) - (prc-min proc) - (prc-rest proc) - (not (null? closed-list)) - frame - (source-comment proc)) - *bbs*)) - (bb2 (make-bb (make-label-simple lbl2 frame (source-comment proc)) - *bbs*))) - (context-entry-bb-set! context bb1) - (bb-put-branch! bb1 (make-jump (make-lbl lbl2) #f #f frame #f)) - (set! proc-queue (cons (list proc bb2 context) proc-queue)) - (make-lbl lbl1))) -(define (gen-node node live why) - (cond ((cst? node) (gen-return (make-obj (cst-val node)) why node)) - ((ref? node) - (let* ((var (ref-var node)) (name (var-name var))) - (gen-return - (cond ((eq? why 'side) (make-obj undef-object)) - ((global? var) - (let ((prim (target.prim-info* name (node-decl node)))) - (if prim (make-obj prim) (var->opnd var)))) - (else (var->opnd var))) - why - node))) - ((set? node) - (let* ((src (gen-node - (set-val node) - (set-adjoin live (set-var node)) - 'keep)) - (dst (var->opnd (set-var node)))) - (put-copy src dst #f live (source-comment node)) - (gen-return (make-obj undef-object) why node))) - ((def? node) - (compiler-internal-error - "gen-node, 'def' node not at root of parse tree")) - ((tst? node) (gen-tst node live why)) - ((conj? node) (gen-conj/disj node live why)) - ((disj? node) (gen-conj/disj node live why)) - ((prc? node) - (let* ((closed (not-constant-closed-vars node)) - (closed-list (sort-variables (set->list closed))) - (proc-lbl (schedule-gen-proc node closed-list))) - (let ((opnd (if (null? closed-list) - (begin - (add-known-proc (lbl-num proc-lbl) node) - proc-lbl) - (begin - (dealloc-slots - (- nb-slots - (stk-num (highest-live-slot - (set-union closed live))))) - (push-slot) - (let ((slot (make-stk nb-slots)) - (var (make-temp-var 'closure))) - (put-var slot var) - (bb-put-non-branch! - *bb* - (make-close - (list (make-closure-parms - slot - (lbl-num proc-lbl) - (map var->opnd closed-list))) - (current-frame (set-adjoin live var)) - (source-comment node))) - slot))))) - (gen-return opnd why node)))) - ((app? node) (gen-call node live why)) - ((fut? node) (gen-fut node live why)) - (else - (compiler-internal-error - "gen-node, unknown parse tree node type:" - node)))) -(define (gen-return opnd why node) - (cond ((eq? why 'tail) - (let ((var (make-temp-var 'result))) - (put-copy - opnd - target.proc-result - var - ret-var-set - (source-comment node)) - (let ((ret-opnd (var->opnd ret-var))) - (seal-bb (intrs-enabled? (node-decl node)) 'return) - (dealloc-slots nb-slots) - (bb-put-branch! - *bb* - (make-jump - ret-opnd - #f - #f - (current-frame (set-singleton var)) - #f))))) - (else opnd))) -(define (not-constant-closed-vars val) - (set-keep not-constant-var? (free-variables val))) -(define (predicate node live cont) - (define (cont* true-lbl false-lbl) (cont false-lbl true-lbl)) - (define (generic-true-test) - (predicate-test node live **not-proc-obj '0 (list node) cont*)) - (cond ((or (conj? node) (disj? node)) (predicate-conj/disj node live cont)) - ((app? node) - (let ((proc (node->proc (app-oper node)))) - (if proc - (let ((spec (specialize-for-call proc (node-decl node)))) - (if (and (proc-obj-test spec) - (nb-args-conforms? - (length (app-args node)) - (proc-obj-call-pat spec))) - (if (eq? spec **not-proc-obj) - (predicate (car (app-args node)) live cont*) - (predicate-test - node - live - spec - (proc-obj-strict-pat proc) - (app-args node) - cont)) - (generic-true-test))) - (generic-true-test)))) - (else (generic-true-test)))) -(define (predicate-conj/disj node live cont) - (let* ((pre (if (conj? node) (conj-pre node) (disj-pre node))) - (alt (if (conj? node) (conj-alt node) (disj-alt node))) - (alt-live (set-union live (free-variables alt)))) - (predicate - pre - alt-live - (lambda (true-lbl false-lbl) - (let ((pre-context (current-context))) - (set! *bb* - (make-bb (make-label-simple - (if (conj? node) true-lbl false-lbl) - (current-frame alt-live) - (source-comment alt)) - *bbs*)) - (predicate - alt - live - (lambda (true-lbl2 false-lbl2) - (let ((alt-context (current-context))) - (restore-context pre-context) - (set! *bb* - (make-bb (make-label-simple - (if (conj? node) false-lbl true-lbl) - (current-frame live) - (source-comment alt)) - *bbs*)) - (merge-contexts-and-seal-bb - alt-context - live - (intrs-enabled? (node-decl node)) - 'internal - (source-comment node)) - (bb-put-branch! - *bb* - (make-jump - (make-lbl (if (conj? node) false-lbl2 true-lbl2)) - #f - #f - (current-frame live) - #f)) - (cont true-lbl2 false-lbl2))))))))) -(define (predicate-test node live test strict-pat args cont) - (let loop ((args* args) (liv live) (vars* '())) - (if (not (null? args*)) - (let* ((needed (vals-live-vars liv (cdr args*))) - (var (save-var - (gen-node (car args*) needed 'need) - (make-temp-var 'predicate) - needed - (source-comment (car args*))))) - (loop (cdr args*) (set-adjoin liv var) (cons var vars*))) - (let* ((true-lbl (bbs-new-lbl! *bbs*)) - (false-lbl (bbs-new-lbl! *bbs*))) - (seal-bb (intrs-enabled? (node-decl node)) 'internal) - (bb-put-branch! - *bb* - (make-ifjump - test - (map var->opnd (reverse vars*)) - true-lbl - false-lbl - #f - (current-frame live) - (source-comment node))) - (cont true-lbl false-lbl))))) -(define (gen-tst node live why) - (let ((pre (tst-pre node)) (con (tst-con node)) (alt (tst-alt node))) - (predicate - pre - (set-union live (free-variables con) (free-variables alt)) - (lambda (true-lbl false-lbl) - (let ((pre-context (current-context)) - (true-bb (make-bb (make-label-simple - true-lbl - (current-frame - (set-union live (free-variables con))) - (source-comment con)) - *bbs*)) - (false-bb - (make-bb (make-label-simple - false-lbl - (current-frame (set-union live (free-variables alt))) - (source-comment alt)) - *bbs*))) - (set! *bb* true-bb) - (let ((con-opnd (gen-node con live why))) - (if (eq? why 'tail) - (begin - (restore-context pre-context) - (set! *bb* false-bb) - (gen-node alt live why)) - (let* ((result-var (make-temp-var 'result)) - (live-after (set-adjoin live result-var))) - (save-opnd-to-reg - con-opnd - target.proc-result - result-var - live - (source-comment con)) - (let ((con-context (current-context)) (con-bb *bb*)) - (restore-context pre-context) - (set! *bb* false-bb) - (save-opnd-to-reg - (gen-node alt live why) - target.proc-result - result-var - live - (source-comment alt)) - (let ((next-lbl (bbs-new-lbl! *bbs*)) (alt-bb *bb*)) - (if (> (context-nb-slots con-context) nb-slots) - (begin - (seal-bb (intrs-enabled? (node-decl node)) - 'internal) - (let ((alt-context (current-context))) - (restore-context con-context) - (set! *bb* con-bb) - (merge-contexts-and-seal-bb - alt-context - live-after - (intrs-enabled? (node-decl node)) - 'internal - (source-comment node)))) - (let ((alt-context (current-context))) - (restore-context con-context) - (set! *bb* con-bb) - (seal-bb (intrs-enabled? (node-decl node)) - 'internal) - (let ((con-context* (current-context))) - (restore-context alt-context) - (set! *bb* alt-bb) - (merge-contexts-and-seal-bb - con-context* - live-after - (intrs-enabled? (node-decl node)) - 'internal - (source-comment node))))) - (let ((frame (current-frame live-after))) - (bb-put-branch! - con-bb - (make-jump (make-lbl next-lbl) #f #f frame #f)) - (bb-put-branch! - alt-bb - (make-jump (make-lbl next-lbl) #f #f frame #f)) - (set! *bb* - (make-bb (make-label-simple - next-lbl - frame - (source-comment node)) - *bbs*)) - target.proc-result))))))))))) -(define (nb-args-conforms? n call-pat) (pattern-member? n call-pat)) -(define (merge-contexts-and-seal-bb other-context live poll? where comment) - (let ((live-v (live-vars live)) - (other-nb-slots (context-nb-slots other-context)) - (other-regs (context-regs other-context)) - (other-slots (context-slots other-context)) - (other-poll (context-poll other-context)) - (other-entry-bb (context-entry-bb other-context))) - (let loop1 ((i (- target.nb-regs 1))) - (if (>= i 0) - (let ((other-var (reg->var other-regs i)) (var (reg->var regs i))) - (if (and (not (eq? var other-var)) (set-member? other-var live-v)) - (let ((r (make-reg i))) - (put-var r empty-var) - (if (not (or (not (set-member? var live-v)) - (memq var regs) - (memq var slots))) - (let ((top (make-stk (+ nb-slots 1)))) - (put-copy r top var live-v comment))) - (put-copy (var->opnd other-var) r other-var live-v comment))) - (loop1 (- i 1))))) - (let loop2 ((i 1)) - (if (<= i other-nb-slots) - (let ((other-var (stk->var other-slots i)) (var (stk->var slots i))) - (if (and (not (eq? var other-var)) (set-member? other-var live-v)) - (let ((s (make-stk i))) - (if (<= i nb-slots) (put-var s empty-var)) - (if (not (or (not (set-member? var live-v)) - (memq var regs) - (memq var slots))) - (let ((top (make-stk (+ nb-slots 1)))) - (put-copy s top var live-v comment))) - (put-copy (var->opnd other-var) s other-var live-v comment)) - (if (> i nb-slots) - (let ((top (make-stk (+ nb-slots 1)))) - (put-copy - (make-obj undef-object) - top - empty-var - live-v - comment)))) - (loop2 (+ i 1))))) - (dealloc-slots (- nb-slots other-nb-slots)) - (let loop3 ((i (- target.nb-regs 1))) - (if (>= i 0) - (let ((other-var (reg->var other-regs i)) (var (reg->var regs i))) - (if (not (eq? var other-var)) (put-var (make-reg i) empty-var)) - (loop3 (- i 1))))) - (let loop4 ((i 1)) - (if (<= i other-nb-slots) - (let ((other-var (stk->var other-slots i)) (var (stk->var slots i))) - (if (not (eq? var other-var)) (put-var (make-stk i) empty-var)) - (loop4 (+ i 1))))) - (seal-bb poll? where) - (set! poll (poll-merge poll other-poll)) - (if (not (eq? entry-bb other-entry-bb)) - (compiler-internal-error - "merge-contexts-and-seal-bb, entry-bb's do not agree")))) -(define (seal-bb poll? where) - (define (my-last-pair l) (if (pair? (cdr l)) (my-last-pair (cdr l)) l)) - (define (poll-at split-point) - (let loop ((i 0) (l1 (bb-non-branch-instrs *bb*)) (l2 '())) - (if (< i split-point) - (loop (+ i 1) (cdr l1) (cons (car l1) l2)) - (let* ((label-instr (bb-label-instr *bb*)) - (non-branch-instrs1 (reverse l2)) - (non-branch-instrs2 l1) - (frame (gvm-instr-frame - (car (my-last-pair - (cons label-instr non-branch-instrs1))))) - (prec-bb (make-bb label-instr *bbs*)) - (new-lbl (bbs-new-lbl! *bbs*))) - (bb-non-branch-instrs-set! prec-bb non-branch-instrs1) - (bb-put-branch! - prec-bb - (make-jump (make-lbl new-lbl) #f #t frame #f)) - (bb-label-instr-set! *bb* (make-label-simple new-lbl frame #f)) - (bb-non-branch-instrs-set! *bb* non-branch-instrs2) - (set! poll (make-poll #t 0)))))) - (define (poll-at-end) (poll-at (length (bb-non-branch-instrs *bb*)))) - (define (impose-polling-constraints) - (let ((n (+ (length (bb-non-branch-instrs *bb*)) 1)) - (delta (poll-delta poll))) - (if (> (+ delta n) poll-period) - (begin - (poll-at (max (- poll-period delta) 0)) - (impose-polling-constraints))))) - (if poll? (impose-polling-constraints)) - (let* ((n (+ (length (bb-non-branch-instrs *bb*)) 1)) - (delta (+ (poll-delta poll) n)) - (since-entry? (poll-since-entry? poll))) - (if (and poll? - (case where - ((call) (> delta (- poll-period poll-head))) - ((tail-call) (> delta poll-tail)) - ((return) (and since-entry? (> delta (+ poll-head poll-tail)))) - ((internal) #f) - (else - (compiler-internal-error "seal-bb, unknown 'where':" where)))) - (poll-at-end) - (set! poll (make-poll since-entry? delta))))) -(define (reg->var regs i) - (cond ((null? regs) '()) - ((> i 0) (reg->var (cdr regs) (- i 1))) - (else (car regs)))) -(define (stk->var slots i) - (let ((j (- (length slots) i))) (if (< j 0) '() (list-ref slots j)))) -(define (gen-conj/disj node live why) - (let ((pre (if (conj? node) (conj-pre node) (disj-pre node))) - (alt (if (conj? node) (conj-alt node) (disj-alt node)))) - (let ((needed (set-union live (free-variables alt))) - (bool? (boolean-value? pre)) - (predicate-var (make-temp-var 'predicate))) - (define (general-predicate node live cont) - (let* ((con-lbl (bbs-new-lbl! *bbs*)) (alt-lbl (bbs-new-lbl! *bbs*))) - (save-opnd-to-reg - (gen-node pre live 'need) - target.proc-result - predicate-var - live - (source-comment pre)) - (seal-bb (intrs-enabled? (node-decl node)) 'internal) - (bb-put-branch! - *bb* - (make-ifjump - **not-proc-obj - (list target.proc-result) - alt-lbl - con-lbl - #f - (current-frame (set-adjoin live predicate-var)) - (source-comment node))) - (cont con-lbl alt-lbl))) - (define (alternative con-lbl alt-lbl) - (let* ((pre-context (current-context)) - (result-var (make-temp-var 'result)) - (con-live (if bool? live (set-adjoin live predicate-var))) - (alt-live (set-union live (free-variables alt))) - (con-bb (make-bb (make-label-simple - con-lbl - (current-frame con-live) - (source-comment alt)) - *bbs*)) - (alt-bb (make-bb (make-label-simple - alt-lbl - (current-frame alt-live) - (source-comment alt)) - *bbs*))) - (if bool? - (begin - (set! *bb* con-bb) - (save-opnd-to-reg - (make-obj (if (conj? node) false-object #t)) - target.proc-result - result-var - live - (source-comment node))) - (put-var (var->opnd predicate-var) result-var)) - (let ((con-context (current-context))) - (set! *bb* alt-bb) - (restore-context pre-context) - (let ((alt-opnd (gen-node alt live why))) - (if (eq? why 'tail) - (begin - (restore-context con-context) - (set! *bb* con-bb) - (let ((ret-opnd (var->opnd ret-var)) - (result-set (set-singleton result-var))) - (seal-bb (intrs-enabled? (node-decl node)) 'return) - (dealloc-slots nb-slots) - (bb-put-branch! - *bb* - (make-jump - ret-opnd - #f - #f - (current-frame result-set) - #f)))) - (let ((alt-context* (current-context)) (alt-bb* *bb*)) - (restore-context con-context) - (set! *bb* con-bb) - (seal-bb (intrs-enabled? (node-decl node)) 'internal) - (let ((con-context* (current-context)) - (next-lbl (bbs-new-lbl! *bbs*))) - (restore-context alt-context*) - (set! *bb* alt-bb*) - (save-opnd-to-reg - alt-opnd - target.proc-result - result-var - live - (source-comment alt)) - (merge-contexts-and-seal-bb - con-context* - (set-adjoin live result-var) - (intrs-enabled? (node-decl node)) - 'internal - (source-comment node)) - (let ((frame (current-frame - (set-adjoin live result-var)))) - (bb-put-branch! - *bb* - (make-jump (make-lbl next-lbl) #f #f frame #f)) - (bb-put-branch! - con-bb - (make-jump (make-lbl next-lbl) #f #f frame #f)) - (set! *bb* - (make-bb (make-label-simple - next-lbl - frame - (source-comment node)) - *bbs*)) - target.proc-result)))))))) - ((if bool? predicate general-predicate) - pre - needed - (lambda (true-lbl false-lbl) - (if (conj? node) - (alternative false-lbl true-lbl) - (alternative true-lbl false-lbl))))))) -(define (gen-call node live why) - (let* ((oper (app-oper node)) (args (app-args node)) (nb-args (length args))) - (if (and (prc? oper) - (not (prc-rest oper)) - (= (length (prc-parms oper)) nb-args)) - (gen-let (prc-parms oper) args (prc-body oper) live why) - (if (inlinable-app? node) - (let ((eval-order (arg-eval-order #f args)) - (vars (map (lambda (x) (cons x #f)) args))) - (let loop ((l eval-order) (liv live)) - (if (not (null? l)) - (let* ((needed (vals-live-vars liv (map car (cdr l)))) - (arg (car (car l))) - (pos (cdr (car l))) - (var (save-var - (gen-node arg needed 'need) - (make-temp-var pos) - needed - (source-comment arg)))) - (set-cdr! (assq arg vars) var) - (loop (cdr l) (set-adjoin liv var))) - (let ((loc (if (eq? why 'side) - (make-reg 0) - (or (lowest-dead-reg live) - (lowest-dead-slot live))))) - (if (and (stk? loc) (> (stk-num loc) nb-slots)) - (push-slot)) - (let* ((args (map var->opnd (map cdr vars))) - (var (make-temp-var 'result)) - (proc (node->proc oper)) - (strict-pat (proc-obj-strict-pat proc))) - (if (not (eq? why 'side)) (put-var loc var)) - (bb-put-non-branch! - *bb* - (make-apply - (specialize-for-call proc (node-decl node)) - args - (if (eq? why 'side) #f loc) - (current-frame - (if (eq? why 'side) live (set-adjoin live var))) - (source-comment node))) - (gen-return loc why node)))))) - (let* ((calling-local-proc? - (and (ref? oper) - (let ((opnd (var->opnd (ref-var oper)))) - (and (lbl? opnd) - (let ((x (assq (lbl-num opnd) known-procs))) - (and x - (let ((proc (cdr x))) - (and (not (prc-rest proc)) - (= (prc-min proc) nb-args) - (= (length (prc-parms proc)) - nb-args) - (lbl-num opnd))))))))) - (jstate (get-jump-state - args - (if calling-local-proc? - (target.label-info nb-args nb-args #f #f) - (target.jump-info nb-args)))) - (in-stk (jump-state-in-stk jstate)) - (in-reg (jump-state-in-reg jstate)) - (eval-order - (arg-eval-order (if calling-local-proc? #f oper) in-reg)) - (live-after - (if (eq? why 'tail) (set-remove live ret-var) live)) - (live-for-regs (args-live-vars live eval-order)) - (return-lbl (if (eq? why 'tail) #f (bbs-new-lbl! *bbs*)))) - (save-regs - (live-regs live-after) - (stk-live-vars live-for-regs in-stk why) - (source-comment node)) - (let ((frame-start (stk-num (highest-live-slot live-after)))) - (let loop1 ((l in-stk) (liv live-after) (i (+ frame-start 1))) - (if (not (null? l)) - (let ((arg (car l)) - (slot (make-stk i)) - (needed (set-union - (stk-live-vars liv (cdr l) why) - live-for-regs))) - (if arg - (let ((var (if (and (eq? arg 'return) - (eq? why 'tail)) - ret-var - (make-temp-var (- frame-start i))))) - (save-opnd-to-stk - (if (eq? arg 'return) - (if (eq? why 'tail) - (var->opnd ret-var) - (make-lbl return-lbl)) - (gen-node arg needed 'need)) - slot - var - needed - (source-comment - (if (eq? arg 'return) node arg))) - (loop1 (cdr l) (set-adjoin liv var) (+ i 1))) - (begin - (if (> i nb-slots) - (put-copy - (make-obj undef-object) - slot - empty-var - liv - (source-comment node))) - (loop1 (cdr l) liv (+ i 1))))) - (let loop2 ((l eval-order) - (liv liv) - (reg-map '()) - (oper-var '())) - (if (not (null? l)) - (let* ((arg (car (car l))) - (pos (cdr (car l))) - (needed (args-live-vars liv (cdr l))) - (var (if (and (eq? arg 'return) - (eq? why 'tail)) - ret-var - (make-temp-var pos))) - (opnd (if (eq? arg 'return) - (if (eq? why 'tail) - (var->opnd ret-var) - (make-lbl return-lbl)) - (gen-node arg needed 'need)))) - (if (eq? pos 'operator) - (if (and (ref? arg) - (not (or (obj? opnd) (lbl? opnd)))) - (loop2 (cdr l) - (set-adjoin liv (ref-var arg)) - reg-map - (ref-var arg)) - (begin - (save-arg - opnd - var - needed - (source-comment - (if (eq? arg 'return) node arg))) - (loop2 (cdr l) - (set-adjoin liv var) - reg-map - var))) - (let ((reg (make-reg pos))) - (if (all-args-trivial? (cdr l)) - (save-opnd-to-reg - opnd - reg - var - needed - (source-comment - (if (eq? arg 'return) node arg))) - (save-in-slot - opnd - var - needed - (source-comment - (if (eq? arg 'return) node arg)))) - (loop2 (cdr l) - (set-adjoin liv var) - (cons (cons pos var) reg-map) - oper-var)))) - (let loop3 ((i (- target.nb-regs 1))) - (if (>= i 0) - (let ((couple (assq i reg-map))) - (if couple - (let ((var (cdr couple))) - (if (not (eq? (reg->var regs i) var)) - (save-opnd-to-reg - (var->opnd var) - (make-reg i) - var - liv - (source-comment node))))) - (loop3 (- i 1))) - (let ((opnd (if calling-local-proc? - (make-lbl - (+ calling-local-proc? 1)) - (var->opnd oper-var)))) - (seal-bb (intrs-enabled? (node-decl node)) - (if return-lbl 'call 'tail-call)) - (dealloc-slots - (- nb-slots - (+ frame-start (length in-stk)))) - (bb-put-branch! - *bb* - (make-jump - opnd - (if calling-local-proc? #f nb-args) - #f - (current-frame liv) - (source-comment node))) - (let ((result-var (make-temp-var 'result))) - (dealloc-slots (- nb-slots frame-start)) - (flush-regs) - (put-var target.proc-result result-var) - (if return-lbl - (begin - (set! poll (return-poll poll)) - (set! *bb* - (make-bb (make-label-return - return-lbl - (current-frame - (set-adjoin - live - result-var)) - (source-comment - node)) - *bbs*)))) - target.proc-result)))))))))))))) -(define (contained-reg/slot opnd) - (cond ((reg? opnd) opnd) - ((stk? opnd) opnd) - ((clo? opnd) (contained-reg/slot (clo-base opnd))) - (else #f))) -(define (opnd-needed opnd needed) - (let ((x (contained-reg/slot opnd))) - (if x (set-adjoin needed (get-var x)) needed))) -(define (save-opnd opnd live comment) - (let ((slot (lowest-dead-slot live))) - (put-copy opnd slot (get-var opnd) live comment))) -(define (save-regs regs live comment) - (for-each - (lambda (i) (save-opnd (make-reg i) live comment)) - (set->list regs))) -(define (save-opnd-to-reg opnd reg var live comment) - (if (set-member? (reg-num reg) (live-regs live)) - (save-opnd reg (opnd-needed opnd live) comment)) - (put-copy opnd reg var live comment)) -(define (save-opnd-to-stk opnd stk var live comment) - (if (set-member? (stk-num stk) (live-slots live)) - (save-opnd stk (opnd-needed opnd live) comment)) - (put-copy opnd stk var live comment)) -(define (all-args-trivial? l) - (if (null? l) - #t - (let ((arg (car (car l)))) - (or (eq? arg 'return) - (and (trivial? arg) (all-args-trivial? (cdr l))))))) -(define (every-trivial? l) - (or (null? l) (and (trivial? (car l)) (every-trivial? (cdr l))))) -(define (trivial? node) - (or (cst? node) - (ref? node) - (and (set? node) (trivial? (set-val node))) - (and (inlinable-app? node) (every-trivial? (app-args node))))) -(define (inlinable-app? node) - (if (app? node) - (let ((proc (node->proc (app-oper node)))) - (and proc - (let ((spec (specialize-for-call proc (node-decl node)))) - (and (proc-obj-inlinable spec) - (nb-args-conforms? - (length (app-args node)) - (proc-obj-call-pat spec)))))) - #f)) -(define (boolean-value? node) - (or (and (conj? node) - (boolean-value? (conj-pre node)) - (boolean-value? (conj-alt node))) - (and (disj? node) - (boolean-value? (disj-pre node)) - (boolean-value? (disj-alt node))) - (boolean-app? node))) -(define (boolean-app? node) - (if (app? node) - (let ((proc (node->proc (app-oper node)))) - (if proc (eq? (type-name (proc-obj-type proc)) 'boolean) #f)) - #f)) -(define (node->proc node) - (cond ((cst? node) (if (proc-obj? (cst-val node)) (cst-val node) #f)) - ((ref? node) - (if (global? (ref-var node)) - (target.prim-info* (var-name (ref-var node)) (node-decl node)) - #f)) - (else #f))) -(define (specialize-for-call proc decl) ((proc-obj-specialize proc) decl)) -(define (get-jump-state args pc) - (define (empty-node-list n) - (if (> n 0) (cons #f (empty-node-list (- n 1))) '())) - (let* ((fs (pcontext-fs pc)) - (slots-list (empty-node-list fs)) - (regs-list (empty-node-list target.nb-regs))) - (define (assign-node-to-loc var loc) - (let ((x (cond ((reg? loc) - (let ((i (reg-num loc))) - (if (<= i target.nb-regs) - (nth-after regs-list i) - (compiler-internal-error - "jump-state, reg out of bound in back-end's pcontext")))) - ((stk? loc) - (let ((i (stk-num loc))) - (if (<= i fs) - (nth-after slots-list (- i 1)) - (compiler-internal-error - "jump-state, stk out of bound in back-end's pcontext")))) - (else - (compiler-internal-error - "jump-state, loc other than reg or stk in back-end's pcontext"))))) - (if (not (car x)) - (set-car! x var) - (compiler-internal-error - "jump-state, duplicate location in back-end's pcontext")))) - (let loop ((l (pcontext-map pc))) - (if (not (null? l)) - (let* ((couple (car l)) (name (car couple)) (loc (cdr couple))) - (cond ((eq? name 'return) (assign-node-to-loc 'return loc)) - (else (assign-node-to-loc (list-ref args (- name 1)) loc))) - (loop (cdr l))))) - (vector slots-list regs-list))) -(define (jump-state-in-stk x) (vector-ref x 0)) -(define (jump-state-in-reg x) (vector-ref x 1)) -(define (arg-eval-order oper nodes) - (define (loop nodes pos part1 part2) - (cond ((null? nodes) - (let ((p1 (reverse part1)) (p2 (free-vars-order part2))) - (cond ((not oper) (append p1 p2)) - ((trivial? oper) - (append p1 p2 (list (cons oper 'operator)))) - (else (append (cons (cons oper 'operator) p1) p2))))) - ((not (car nodes)) (loop (cdr nodes) (+ pos 1) part1 part2)) - ((or (eq? (car nodes) 'return) (trivial? (car nodes))) - (loop (cdr nodes) - (+ pos 1) - part1 - (cons (cons (car nodes) pos) part2))) - (else - (loop (cdr nodes) - (+ pos 1) - (cons (cons (car nodes) pos) part1) - part2)))) - (loop nodes 0 '() '())) -(define (free-vars-order l) - (let ((bins '()) (ordered-args '())) - (define (free-v x) (if (eq? x 'return) (set-empty) (free-variables x))) - (define (add-to-bin! x) - (let ((y (assq x bins))) - (if y (set-cdr! y (+ (cdr y) 1)) (set! bins (cons (cons x 1) bins))))) - (define (payoff-if-removed node) - (let ((x (free-v node))) - (let loop ((l (set->list x)) (r 0)) - (if (null? l) - r - (let ((y (cdr (assq (car l) bins)))) - (loop (cdr l) (+ r (quotient 1000 (* y y))))))))) - (define (remove-free-vars! x) - (let loop ((l (set->list x))) - (if (not (null? l)) - (let ((y (assq (car l) bins))) - (set-cdr! y (- (cdr y) 1)) - (loop (cdr l)))))) - (define (find-max-payoff l thunk) - (if (null? l) - (thunk '() -1) - (find-max-payoff - (cdr l) - (lambda (best-arg best-payoff) - (let ((payoff (payoff-if-removed (car (car l))))) - (if (>= payoff best-payoff) - (thunk (car l) payoff) - (thunk best-arg best-payoff))))))) - (define (remove x l) - (cond ((null? l) '()) - ((eq? x (car l)) (cdr l)) - (else (cons (car l) (remove x (cdr l)))))) - (for-each - (lambda (x) (for-each add-to-bin! (set->list (free-v (car x))))) - l) - (let loop ((args l) (ordered-args '())) - (if (null? args) - (reverse ordered-args) - (find-max-payoff - args - (lambda (best-arg best-payoff) - (remove-free-vars! (free-v (car best-arg))) - (loop (remove best-arg args) (cons best-arg ordered-args)))))))) -(define (args-live-vars live order) - (cond ((null? order) live) - ((eq? (car (car order)) 'return) - (args-live-vars (set-adjoin live ret-var) (cdr order))) - (else - (args-live-vars - (set-union live (free-variables (car (car order)))) - (cdr order))))) -(define (stk-live-vars live slots why) - (cond ((null? slots) live) - ((not (car slots)) (stk-live-vars live (cdr slots) why)) - ((eq? (car slots) 'return) - (stk-live-vars - (if (eq? why 'tail) (set-adjoin live ret-var) live) - (cdr slots) - why)) - (else - (stk-live-vars - (set-union live (free-variables (car slots))) - (cdr slots) - why)))) -(define (gen-let vars vals node live why) - (let ((var-val-map (pair-up vars vals)) - (var-set (list->set vars)) - (all-live - (set-union - live - (free-variables node) - (apply set-union (map free-variables vals))))) - (define (var->val var) (cdr (assq var var-val-map))) - (define (proc-var? var) (prc? (var->val var))) - (define (closed-vars var const-proc-vars) - (set-difference - (not-constant-closed-vars (var->val var)) - const-proc-vars)) - (define (no-closed-vars? var const-proc-vars) - (set-empty? (closed-vars var const-proc-vars))) - (define (closed-vars? var const-proc-vars) - (not (no-closed-vars? var const-proc-vars))) - (define (compute-const-proc-vars proc-vars) - (let loop1 ((const-proc-vars proc-vars)) - (let ((new-const-proc-vars - (set-keep - (lambda (x) (no-closed-vars? x const-proc-vars)) - const-proc-vars))) - (if (not (set-equal? new-const-proc-vars const-proc-vars)) - (loop1 new-const-proc-vars) - const-proc-vars)))) - (let* ((proc-vars (set-keep proc-var? var-set)) - (const-proc-vars (compute-const-proc-vars proc-vars)) - (clo-vars - (set-keep (lambda (x) (closed-vars? x const-proc-vars)) proc-vars)) - (clo-vars-list (set->list clo-vars))) - (for-each - (lambda (proc-var) - (let ((label (schedule-gen-proc (var->val proc-var) '()))) - (add-known-proc (lbl-num label) (var->val proc-var)) - (add-constant-var proc-var label))) - (set->list const-proc-vars)) - (let ((non-clo-vars-list - (set->list - (set-keep - (lambda (var) - (and (not (set-member? var const-proc-vars)) - (not (set-member? var clo-vars)))) - vars))) - (liv (set-union - live - (apply set-union - (map (lambda (x) (closed-vars x const-proc-vars)) - clo-vars-list)) - (free-variables node)))) - (let loop2 ((vars* non-clo-vars-list)) - (if (not (null? vars*)) - (let* ((var (car vars*)) - (val (var->val var)) - (needed (vals-live-vars liv (map var->val (cdr vars*))))) - (if (var-useless? var) - (gen-node val needed 'side) - (save-val - (gen-node val needed 'need) - var - needed - (source-comment val))) - (loop2 (cdr vars*))))) - (if (pair? clo-vars-list) - (begin - (dealloc-slots (- nb-slots (stk-num (highest-live-slot liv)))) - (let loop3 ((l clo-vars-list)) - (if (not (null? l)) - (begin - (push-slot) - (let ((var (car l)) (slot (make-stk nb-slots))) - (put-var slot var) - (loop3 (cdr l)))))) - (bb-put-non-branch! - *bb* - (make-close - (map (lambda (var) - (let ((closed-list - (sort-variables - (set->list (closed-vars var const-proc-vars))))) - (if (null? closed-list) - (compiler-internal-error - "gen-let, no closed variables:" - (var-name var)) - (make-closure-parms - (var->opnd var) - (lbl-num (schedule-gen-proc - (var->val var) - closed-list)) - (map var->opnd closed-list))))) - clo-vars-list) - (current-frame liv) - (source-comment node))))) - (gen-node node live why))))) -(define (save-arg opnd var live comment) - (if (glo? opnd) - (add-constant-var var opnd) - (save-val opnd var live comment))) -(define (save-val opnd var live comment) - (cond ((or (obj? opnd) (lbl? opnd)) (add-constant-var var opnd)) - ((and (reg? opnd) (not (set-member? (reg-num opnd) (live-regs live)))) - (put-var opnd var)) - ((and (stk? opnd) (not (set-member? (stk-num opnd) (live-slots live)))) - (put-var opnd var)) - (else (save-in-slot opnd var live comment)))) -(define (save-in-slot opnd var live comment) - (let ((slot (lowest-dead-slot live))) (put-copy opnd slot var live comment))) -(define (save-var opnd var live comment) - (cond ((or (obj? opnd) (lbl? opnd)) (add-constant-var var opnd) var) - ((or (glo? opnd) (reg? opnd) (stk? opnd)) (get-var opnd)) - (else - (let ((dest (or (highest-dead-reg live) (lowest-dead-slot live)))) - (put-copy opnd dest var live comment) - var)))) -(define (put-copy opnd loc var live comment) - (if (and (stk? loc) (> (stk-num loc) nb-slots)) (push-slot)) - (if var (put-var loc var)) - (if (not (eq? opnd loc)) - (bb-put-non-branch! - *bb* - (make-copy - opnd - loc - (current-frame (if var (set-adjoin live var) live)) - comment)))) -(define (var-useless? var) - (and (set-empty? (var-refs var)) (set-empty? (var-sets var)))) -(define (vals-live-vars live vals) - (if (null? vals) - live - (vals-live-vars - (set-union live (free-variables (car vals))) - (cdr vals)))) -(define (gen-fut node live why) - (let* ((val (fut-val node)) - (clo-vars (not-constant-closed-vars val)) - (clo-vars-list (set->list clo-vars)) - (ret-var* (make-temp-var 0)) - (live-after live) - (live-starting-task - (set-adjoin (set-union live-after clo-vars) ret-var*)) - (task-lbl (bbs-new-lbl! *bbs*)) - (return-lbl (bbs-new-lbl! *bbs*))) - (save-regs (live-regs live-after) live-starting-task (source-comment node)) - (let ((frame-start (stk-num (highest-live-slot live-after)))) - (save-opnd-to-reg - (make-lbl return-lbl) - target.task-return - ret-var* - (set-remove live-starting-task ret-var*) - (source-comment node)) - (let loop1 ((l clo-vars-list) (i 0)) - (if (null? l) - (dealloc-slots (- nb-slots (+ frame-start i))) - (let ((var (car l)) (rest (cdr l))) - (if (memq var regs) - (loop1 rest i) - (let loop2 ((j (- target.nb-regs 1))) - (if (>= j 0) - (if (or (>= j (length regs)) - (not (set-member? - (list-ref regs j) - live-starting-task))) - (let ((reg (make-reg j))) - (put-copy - (var->opnd var) - reg - var - live-starting-task - (source-comment node)) - (loop1 rest i)) - (loop2 (- j 1))) - (let ((slot (make-stk (+ frame-start (+ i 1)))) - (needed (list->set rest))) - (if (and (or (> (stk-num slot) nb-slots) - (not (memq (list-ref - slots - (- nb-slots (stk-num slot))) - regs))) - (set-member? - (stk-num slot) - (live-slots needed))) - (save-opnd - slot - live-starting-task - (source-comment node))) - (put-copy - (var->opnd var) - slot - var - live-starting-task - (source-comment node)) - (loop1 rest (+ i 1))))))))) - (seal-bb (intrs-enabled? (node-decl node)) 'call) - (bb-put-branch! - *bb* - (make-jump - (make-lbl task-lbl) - #f - #f - (current-frame live-starting-task) - #f)) - (let ((task-context - (make-context - (- nb-slots frame-start) - (reverse (nth-after (reverse slots) frame-start)) - (cons ret-var (cdr regs)) - '() - poll - entry-bb)) - (return-context - (make-context - frame-start - (nth-after slots (- nb-slots frame-start)) - '() - closed - (return-poll poll) - entry-bb))) - (restore-context task-context) - (set! *bb* - (make-bb (make-label-task-entry - task-lbl - (current-frame live-starting-task) - (source-comment node)) - *bbs*)) - (gen-node val ret-var-set 'tail) - (let ((result-var (make-temp-var 'future))) - (restore-context return-context) - (put-var target.proc-result result-var) - (set! *bb* - (make-bb (make-label-task-return - return-lbl - (current-frame (set-adjoin live result-var)) - (source-comment node)) - *bbs*)) - (gen-return target.proc-result why node)))))) -(define prim-procs - '(("not" (1) #f 0 boolean) - ("boolean?" (1) #f 0 boolean) - ("eqv?" (2) #f 0 boolean) - ("eq?" (2) #f 0 boolean) - ("equal?" (2) #f 0 boolean) - ("pair?" (1) #f 0 boolean) - ("cons" (2) #f () pair) - ("car" (1) #f 0 (#f)) - ("cdr" (1) #f 0 (#f)) - ("set-car!" (2) #t (1) pair) - ("set-cdr!" (2) #t (1) pair) - ("caar" (1) #f 0 (#f)) - ("cadr" (1) #f 0 (#f)) - ("cdar" (1) #f 0 (#f)) - ("cddr" (1) #f 0 (#f)) - ("caaar" (1) #f 0 (#f)) - ("caadr" (1) #f 0 (#f)) - ("cadar" (1) #f 0 (#f)) - ("caddr" (1) #f 0 (#f)) - ("cdaar" (1) #f 0 (#f)) - ("cdadr" (1) #f 0 (#f)) - ("cddar" (1) #f 0 (#f)) - ("cdddr" (1) #f 0 (#f)) - ("caaaar" (1) #f 0 (#f)) - ("caaadr" (1) #f 0 (#f)) - ("caadar" (1) #f 0 (#f)) - ("caaddr" (1) #f 0 (#f)) - ("cadaar" (1) #f 0 (#f)) - ("cadadr" (1) #f 0 (#f)) - ("caddar" (1) #f 0 (#f)) - ("cadddr" (1) #f 0 (#f)) - ("cdaaar" (1) #f 0 (#f)) - ("cdaadr" (1) #f 0 (#f)) - ("cdadar" (1) #f 0 (#f)) - ("cdaddr" (1) #f 0 (#f)) - ("cddaar" (1) #f 0 (#f)) - ("cddadr" (1) #f 0 (#f)) - ("cdddar" (1) #f 0 (#f)) - ("cddddr" (1) #f 0 (#f)) - ("null?" (1) #f 0 boolean) - ("list?" (1) #f 0 boolean) - ("list" 0 #f () list) - ("length" (1) #f 0 integer) - ("append" 0 #f 0 list) - ("reverse" (1) #f 0 list) - ("list-ref" (2) #f 0 (#f)) - ("memq" (2) #f 0 list) - ("memv" (2) #f 0 list) - ("member" (2) #f 0 list) - ("assq" (2) #f 0 #f) - ("assv" (2) #f 0 #f) - ("assoc" (2) #f 0 #f) - ("symbol?" (1) #f 0 boolean) - ("symbol->string" (1) #f 0 string) - ("string->symbol" (1) #f 0 symbol) - ("number?" (1) #f 0 boolean) - ("complex?" (1) #f 0 boolean) - ("real?" (1) #f 0 boolean) - ("rational?" (1) #f 0 boolean) - ("integer?" (1) #f 0 boolean) - ("exact?" (1) #f 0 boolean) - ("inexact?" (1) #f 0 boolean) - ("=" 0 #f 0 boolean) - ("<" 0 #f 0 boolean) - (">" 0 #f 0 boolean) - ("<=" 0 #f 0 boolean) - (">=" 0 #f 0 boolean) - ("zero?" (1) #f 0 boolean) - ("positive?" (1) #f 0 boolean) - ("negative?" (1) #f 0 boolean) - ("odd?" (1) #f 0 boolean) - ("even?" (1) #f 0 boolean) - ("max" 1 #f 0 number) - ("min" 1 #f 0 number) - ("+" 0 #f 0 number) - ("*" 0 #f 0 number) - ("-" 1 #f 0 number) - ("/" 1 #f 0 number) - ("abs" (1) #f 0 number) - ("quotient" 1 #f 0 integer) - ("remainder" (2) #f 0 integer) - ("modulo" (2) #f 0 integer) - ("gcd" 1 #f 0 integer) - ("lcm" 1 #f 0 integer) - ("numerator" (1) #f 0 integer) - ("denominator" (1) #f 0 integer) - ("floor" (1) #f 0 integer) - ("ceiling" (1) #f 0 integer) - ("truncate" (1) #f 0 integer) - ("round" (1) #f 0 integer) - ("rationalize" (2) #f 0 number) - ("exp" (1) #f 0 number) - ("log" (1) #f 0 number) - ("sin" (1) #f 0 number) - ("cos" (1) #f 0 number) - ("tan" (1) #f 0 number) - ("asin" (1) #f 0 number) - ("acos" (1) #f 0 number) - ("atan" (1 2) #f 0 number) - ("sqrt" (1) #f 0 number) - ("expt" (2) #f 0 number) - ("make-rectangular" (2) #f 0 number) - ("make-polar" (2) #f 0 number) - ("real-part" (1) #f 0 real) - ("imag-part" (1) #f 0 real) - ("magnitude" (1) #f 0 real) - ("angle" (1) #f 0 real) - ("exact->inexact" (1) #f 0 number) - ("inexact->exact" (1) #f 0 number) - ("number->string" (1 2) #f 0 string) - ("string->number" (1 2) #f 0 number) - ("char?" (1) #f 0 boolean) - ("char=?" 0 #f 0 boolean) - ("char?" 0 #f 0 boolean) - ("char<=?" 0 #f 0 boolean) - ("char>=?" 0 #f 0 boolean) - ("char-ci=?" 0 #f 0 boolean) - ("char-ci?" 0 #f 0 boolean) - ("char-ci<=?" 0 #f 0 boolean) - ("char-ci>=?" 0 #f 0 boolean) - ("char-alphabetic?" (1) #f 0 boolean) - ("char-numeric?" (1) #f 0 boolean) - ("char-whitespace?" (1) #f 0 boolean) - ("char-upper-case?" (1) #f 0 boolean) - ("char-lower-case?" (1) #f 0 boolean) - ("char->integer" (1) #f 0 integer) - ("integer->char" (1) #f 0 char) - ("char-upcase" (1) #f 0 char) - ("char-downcase" (1) #f 0 char) - ("string?" (1) #f 0 boolean) - ("make-string" (1 2) #f 0 string) - ("string" 0 #f 0 string) - ("string-length" (1) #f 0 integer) - ("string-ref" (2) #f 0 char) - ("string-set!" (3) #t 0 string) - ("string=?" 0 #f 0 boolean) - ("string?" 0 #f 0 boolean) - ("string<=?" 0 #f 0 boolean) - ("string>=?" 0 #f 0 boolean) - ("string-ci=?" 0 #f 0 boolean) - ("string-ci?" 0 #f 0 boolean) - ("string-ci<=?" 0 #f 0 boolean) - ("string-ci>=?" 0 #f 0 boolean) - ("substring" (3) #f 0 string) - ("string-append" 0 #f 0 string) - ("vector?" (1) #f 0 boolean) - ("make-vector" (1 2) #f (1) vector) - ("vector" 0 #f () vector) - ("vector-length" (1) #f 0 integer) - ("vector-ref" (2) #f 0 (#f)) - ("vector-set!" (3) #t (1 2) vector) - ("procedure?" (1) #f 0 boolean) - ("apply" 2 #t 0 (#f)) - ("map" 2 #t 0 list) - ("for-each" 2 #t 0 #f) - ("call-with-current-continuation" (1) #t 0 (#f)) - ("call-with-input-file" (2) #t 0 (#f)) - ("call-with-output-file" (2) #t 0 (#f)) - ("input-port?" (1) #f 0 boolean) - ("output-port?" (1) #f 0 boolean) - ("current-input-port" (0) #f 0 port) - ("current-output-port" (0) #f 0 port) - ("open-input-file" (1) #t 0 port) - ("open-output-file" (1) #t 0 port) - ("close-input-port" (1) #t 0 #f) - ("close-output-port" (1) #t 0 #f) - ("eof-object?" (1) #f 0 boolean) - ("read" (0 1) #t 0 #f) - ("read-char" (0 1) #t 0 #f) - ("peek-char" (0 1) #t 0 #f) - ("write" (0 1) #t 0 #f) - ("display" (0 1) #t 0 #f) - ("newline" (0 1) #t 0 #f) - ("write-char" (1 2) #t 0 #f) - ("list-tail" (2) #f 0 (#f)) - ("string->list" (1) #f 0 list) - ("list->string" (1) #f 0 string) - ("string-copy" (1) #f 0 string) - ("string-fill!" (2) #t 0 string) - ("vector->list" (1) #f 0 list) - ("list->vector" (1) #f 0 vector) - ("vector-fill!" (2) #t 0 vector) - ("force" (1) #t 0 #f) - ("with-input-from-file" (2) #t 0 (#f)) - ("with-output-to-file" (2) #t 0 (#f)) - ("char-ready?" (0 1) #f 0 boolean) - ("load" (1) #t 0 (#f)) - ("transcript-on" (1) #t 0 #f) - ("transcript-off" (0) #t 0 #f) - ("touch" (1) #t 0 #f) - ("##type" (1) #f () integer) - ("##type-cast" (2) #f () (#f)) - ("##subtype" (1) #f () integer) - ("##subtype-set!" (2) #t () #f) - ("##not" (1) #f () boolean) - ("##null?" (1) #f () boolean) - ("##unassigned?" (1) #f () boolean) - ("##unbound?" (1) #f () boolean) - ("##eq?" (2) #f () boolean) - ("##fixnum?" (1) #f () boolean) - ("##flonum?" (1) #f () boolean) - ("##special?" (1) #f () boolean) - ("##pair?" (1) #f () boolean) - ("##subtyped?" (1) #f () boolean) - ("##procedure?" (1) #f () boolean) - ("##placeholder?" (1) #f () boolean) - ("##vector?" (1) #f () boolean) - ("##symbol?" (1) #f () boolean) - ("##ratnum?" (1) #f () boolean) - ("##cpxnum?" (1) #f () boolean) - ("##string?" (1) #f () boolean) - ("##bignum?" (1) #f () boolean) - ("##char?" (1) #f () boolean) - ("##closure?" (1) #f () boolean) - ("##subprocedure?" (1) #f () boolean) - ("##return-dynamic-env-bind?" (1) #f () boolean) - ("##fixnum.+" 0 #f () integer) - ("##fixnum.*" 0 #f () integer) - ("##fixnum.-" 1 #f () integer) - ("##fixnum.quotient" (2) #f () integer) - ("##fixnum.remainder" (2) #f () integer) - ("##fixnum.modulo" (2) #f () integer) - ("##fixnum.logior" 0 #f () integer) - ("##fixnum.logxor" 0 #f () integer) - ("##fixnum.logand" 0 #f () integer) - ("##fixnum.lognot" (1) #f () integer) - ("##fixnum.ash" (2) #f () integer) - ("##fixnum.lsh" (2) #f () integer) - ("##fixnum.zero?" (1) #f () boolean) - ("##fixnum.positive?" (1) #f () boolean) - ("##fixnum.negative?" (1) #f () boolean) - ("##fixnum.odd?" (1) #f () boolean) - ("##fixnum.even?" (1) #f () boolean) - ("##fixnum.=" 0 #f () boolean) - ("##fixnum.<" 0 #f () boolean) - ("##fixnum.>" 0 #f () boolean) - ("##fixnum.<=" 0 #f () boolean) - ("##fixnum.>=" 0 #f () boolean) - ("##flonum.->fixnum" (1) #f () integer) - ("##flonum.<-fixnum" (1) #f () real) - ("##flonum.+" 0 #f () real) - ("##flonum.*" 0 #f () real) - ("##flonum.-" 1 #f () real) - ("##flonum./" 1 #f () real) - ("##flonum.abs" (1) #f () real) - ("##flonum.truncate" (1) #f () real) - ("##flonum.round" (1) #f () real) - ("##flonum.exp" (1) #f () real) - ("##flonum.log" (1) #f () real) - ("##flonum.sin" (1) #f () real) - ("##flonum.cos" (1) #f () real) - ("##flonum.tan" (1) #f () real) - ("##flonum.asin" (1) #f () real) - ("##flonum.acos" (1) #f () real) - ("##flonum.atan" (1) #f () real) - ("##flonum.sqrt" (1) #f () real) - ("##flonum.zero?" (1) #f () boolean) - ("##flonum.positive?" (1) #f () boolean) - ("##flonum.negative?" (1) #f () boolean) - ("##flonum.=" 0 #f () boolean) - ("##flonum.<" 0 #f () boolean) - ("##flonum.>" 0 #f () boolean) - ("##flonum.<=" 0 #f () boolean) - ("##flonum.>=" 0 #f () boolean) - ("##char=?" 0 #f () boolean) - ("##char?" 0 #f () boolean) - ("##char<=?" 0 #f () boolean) - ("##char>=?" 0 #f () boolean) - ("##cons" (2) #f () pair) - ("##set-car!" (2) #t () pair) - ("##set-cdr!" (2) #t () pair) - ("##car" (1) #f () (#f)) - ("##cdr" (1) #f () (#f)) - ("##caar" (1) #f () (#f)) - ("##cadr" (1) #f () (#f)) - ("##cdar" (1) #f () (#f)) - ("##cddr" (1) #f () (#f)) - ("##caaar" (1) #f () (#f)) - ("##caadr" (1) #f () (#f)) - ("##cadar" (1) #f () (#f)) - ("##caddr" (1) #f () (#f)) - ("##cdaar" (1) #f () (#f)) - ("##cdadr" (1) #f () (#f)) - ("##cddar" (1) #f () (#f)) - ("##cdddr" (1) #f () (#f)) - ("##caaaar" (1) #f () (#f)) - ("##caaadr" (1) #f () (#f)) - ("##caadar" (1) #f () (#f)) - ("##caaddr" (1) #f () (#f)) - ("##cadaar" (1) #f () (#f)) - ("##cadadr" (1) #f () (#f)) - ("##caddar" (1) #f () (#f)) - ("##cadddr" (1) #f () (#f)) - ("##cdaaar" (1) #f () (#f)) - ("##cdaadr" (1) #f () (#f)) - ("##cdadar" (1) #f () (#f)) - ("##cdaddr" (1) #f () (#f)) - ("##cddaar" (1) #f () (#f)) - ("##cddadr" (1) #f () (#f)) - ("##cdddar" (1) #f () (#f)) - ("##cddddr" (1) #f () (#f)) - ("##make-cell" (1) #f () pair) - ("##cell-ref" (1) #f () (#f)) - ("##cell-set!" (2) #t () pair) - ("##vector" 0 #f () vector) - ("##make-vector" (2) #f () vector) - ("##vector-length" (1) #f () integer) - ("##vector-ref" (2) #f () (#f)) - ("##vector-set!" (3) #t () vector) - ("##vector-shrink!" (2) #t () vector) - ("##string" 0 #f () string) - ("##make-string" (2) #f () string) - ("##string-length" (1) #f () integer) - ("##string-ref" (2) #f () char) - ("##string-set!" (3) #t () string) - ("##string-shrink!" (2) #t () string) - ("##vector8" 0 #f () string) - ("##make-vector8" (2) #f () string) - ("##vector8-length" (1) #f () integer) - ("##vector8-ref" (2) #f () integer) - ("##vector8-set!" (3) #t () string) - ("##vector8-shrink!" (2) #t () string) - ("##vector16" 0 #f () string) - ("##make-vector16" (2) #f () string) - ("##vector16-length" (1) #f () integer) - ("##vector16-ref" (2) #f () integer) - ("##vector16-set!" (3) #t () string) - ("##vector16-shrink!" (2) #t () string) - ("##closure-code" (1) #f () #f) - ("##closure-ref" (2) #f () (#f)) - ("##closure-set!" (3) #t () #f) - ("##subprocedure-id" (1) #f () #f) - ("##subprocedure-parent" (1) #f () #f) - ("##return-fs" (1) #f () #f) - ("##return-link" (1) #f () #f) - ("##procedure-info" (1) #f () #f) - ("##pstate" (0) #f () #f) - ("##make-placeholder" (1) #f 0 (#f)) - ("##touch" (1) #t 0 #f) - ("##apply" (2) #t () (#f)) - ("##call-with-current-continuation" (1) #t () (#f)) - ("##global-var" (1) #t () #f) - ("##global-var-ref" (1) #f () (#f)) - ("##global-var-set!" (2) #t () #f) - ("##atomic-car" (1) #f () (#f)) - ("##atomic-cdr" (1) #f () (#f)) - ("##atomic-set-car!" (2) #t () pair) - ("##atomic-set-cdr!" (2) #t () pair) - ("##atomic-set-car-if-eq?!" (3) #t () boolean) - ("##atomic-set-cdr-if-eq?!" (3) #t () boolean) - ("##quasi-append" 0 #f 0 list) - ("##quasi-list" 0 #f () list) - ("##quasi-cons" (2) #f () pair) - ("##quasi-list->vector" (1) #f 0 vector) - ("##case-memv" (2) #f 0 list))) -(define ofile-version-major 5) -(define ofile-version-minor 0) -(define prim-proc-prefix 1) -(define user-proc-prefix 2) -(define pair-prefix 3) -(define flonum-prefix 4) -(define local-object-bits -524281) -(define symbol-object-bits -393209) -(define prim-proc-object-bits -262137) -(define padding-tag 0) -(define end-of-code-tag 32768) -(define m68020-proc-code-tag 32769) -(define m68881-proc-code-tag 32770) -(define stat-tag 32771) -(define global-var-ref-tag 34816) -(define global-var-set-tag 36864) -(define global-var-ref-jump-tag 38912) -(define prim-proc-ref-tag 40960) -(define local-proc-ref-tag 49152) -(define long-index-mask 16383) -(define word-index-mask 2047) -(define (ofile.begin! filename add-obj) - (set! ofile-add-obj add-obj) - (set! ofile-syms (queue-empty)) -; (set! *ofile-port1* (open-output-file (string-append filename ".O"))) - (if ofile-asm? - (begin - (set! *ofile-port2* - (asm-open-output-file (string-append filename ".asm"))) - (set! *ofile-pos* 0))) - (ofile-word ofile-version-major) - (ofile-word ofile-version-minor) - '()) -(define (ofile.end!) - (ofile-line "") -; (close-output-port *ofile-port1*) - (if ofile-asm? (asm-close-output-port *ofile-port2*)) - '()) -(define asm-output '()) -(define asm-line '()) -(define (asm-open-output-file filename) - (set! asm-output '()) - (set! asm-line '())) -(define (asm-close-output-port asm-port) #f) -(define (asm-newline asm-port) (asm-display char-newline asm-port)) -(define (asm-display obj asm-port) - (if (eqv? obj char-newline) - (begin - (set! asm-output - (cons (apply string-append (reverse asm-line)) asm-output)) - (set! asm-line '())) - (set! asm-line - (cons (cond ((string? obj) obj) - ((char? obj) (if (eqv? obj char-tab) " " (string obj))) - ((number? obj) (number->string obj)) - (else (compiler-internal-error "asm-display" obj))) - asm-line)))) -(define (asm-output-get) (reverse asm-output)) -(define *ofile-port1* '()) -(define *ofile-port2* '()) -(define *ofile-pos* '()) -(define ofile-nl char-newline) -(define ofile-tab char-tab) -(define ofile-asm? '()) -(set! ofile-asm? '()) -(define ofile-asm-bits? '()) -(set! ofile-asm-bits? #f) -(define ofile-asm-gvm? '()) -(set! ofile-asm-gvm? #f) -(define ofile-stats? '()) -(set! ofile-stats? '()) -(define ofile-add-obj '()) -(set! ofile-add-obj '()) -(define ofile-syms '()) -(set! ofile-syms '()) -(define (ofile-word n) - (let ((n (modulo n 65536))) - (if (and ofile-asm? ofile-asm-bits?) - (let () - (define (ofile-display x) - (asm-display x *ofile-port2*) - (cond ((eq? x ofile-nl) (set! *ofile-pos* 0)) - ((eq? x ofile-tab) - (set! *ofile-pos* (* (quotient (+ *ofile-pos* 8) 8) 8))) - (else (set! *ofile-pos* (+ *ofile-pos* (string-length x)))))) - (if (> *ofile-pos* 64) (ofile-display ofile-nl)) - (if (= *ofile-pos* 0) (ofile-display " .word") (ofile-display ",")) - (ofile-display ofile-tab) - (let ((s (make-string 6 #\0))) - (string-set! s 1 #\x) - (let loop ((i 5) (n n)) - (if (> n 0) - (begin - (string-set! - s - i - (string-ref "0123456789ABCDEF" (remainder n 16))) - (loop (- i 1) (quotient n 16))))) - (ofile-display s)))) -' (write-word n *ofile-port1*))) -(define (ofile-long x) (ofile-word (upper-16bits x)) (ofile-word x)) -(define (ofile-string s) - (let ((len (string-length s))) - (define (ref i) (if (>= i len) 0 (character-encoding (string-ref s i)))) - (let loop ((i 0)) - (if (< i len) - (begin - (ofile-word (+ (* (ref i) 256) (ref (+ i 1)))) - (loop (+ i 2))))) - (if (= (remainder len 2) 0) (ofile-word 0)))) -(define (ofile-wsym tag name) - (let ((n (string-pos-in-list name (queue->list ofile-syms)))) - (if n - (ofile-word (+ tag n)) - (let ((m (length (queue->list ofile-syms)))) - (queue-put! ofile-syms name) - (ofile-word (+ tag word-index-mask)) - (ofile-string name))))) -(define (ofile-lsym tag name) - (let ((n (string-pos-in-list name (queue->list ofile-syms)))) - (if n - (ofile-long (+ tag (* n 8))) - (let ((m (length (queue->list ofile-syms)))) - (queue-put! ofile-syms name) - (ofile-long (+ tag (* long-index-mask 8))) - (ofile-string name))))) -(define (ofile-ref obj) - (let ((n (obj-encoding obj))) - (if n - (ofile-long n) - (if (symbol-object? obj) - (begin (ofile-lsym symbol-object-bits (symbol->string obj))) - (let ((m (ofile-add-obj obj))) - (if m - (ofile-long (+ local-object-bits (* m 8))) - (begin - (ofile-lsym - prim-proc-object-bits - (proc-obj-name obj))))))))) -(define (ofile-prim-proc s) - (ofile-long prim-proc-prefix) - (ofile-wsym 0 s) - (ofile-comment (list "| #[primitive " s "] ="))) -(define (ofile-user-proc) (ofile-long user-proc-prefix)) -(define (ofile-line s) - (if ofile-asm? - (begin - (if (> *ofile-pos* 0) (asm-newline *ofile-port2*)) - (asm-display s *ofile-port2*) - (asm-newline *ofile-port2*) - (set! *ofile-pos* 0)))) -(define (ofile-tabs-to n) - (let loop () - (if (< *ofile-pos* n) - (begin - (asm-display ofile-tab *ofile-port2*) - (set! *ofile-pos* (* (quotient (+ *ofile-pos* 8) 8) 8)) - (loop))))) -(define (ofile-comment l) - (if ofile-asm? - (let () - (if ofile-asm-bits? - (begin (ofile-tabs-to 32) (asm-display "|" *ofile-port2*))) - (for-each (lambda (x) (asm-display x *ofile-port2*)) l) - (asm-newline *ofile-port2*) - (set! *ofile-pos* 0)))) -(define (ofile-gvm-instr code) - (if (and ofile-asm? ofile-asm-gvm?) - (let ((gvm-instr (code-gvm-instr code)) (sn (code-slots-needed code))) - (if (> *ofile-pos* 0) - (begin (asm-newline *ofile-port2*) (set! *ofile-pos* 0))) - (if ofile-asm-bits? (ofile-tabs-to 32)) - (asm-display "| GVM: [" *ofile-port2*) - (asm-display sn *ofile-port2*) - (asm-display "] " *ofile-port2*) - (asm-newline *ofile-port2*) - (set! *ofile-pos* 0)))) -(define (ofile-stat stat) - (define (obj->string x) - (cond ((string? x) x) - ((symbol-object? x) (symbol->string x)) - ((number? x) (number->string x)) - ((false-object? x) "#f") - ((eq? x #t) "#t") - ((null? x) "()") - ((pair? x) - (let loop ((l1 (cdr x)) (l2 (list (obj->string (car x)) "("))) - (cond ((pair? l1) - (loop (cdr l1) - (cons (obj->string (car l1)) (cons " " l2)))) - ((null? l1) (apply string-append (reverse (cons ")" l2)))) - (else - (apply string-append - (reverse (cons ")" - (cons (obj->string l1) - (cons " . " l2))))))))) - (else - (compiler-internal-error - "ofile-stat, can't convert to string 'x'" - x)))) - (ofile-string (obj->string stat))) -(define (upper-16bits x) - (cond ((>= x 0) (quotient x 65536)) - ((>= x (- 65536)) -1) - (else (- (quotient (+ x 65537) 65536) 2)))) -(define type-fixnum 0) -(define type-flonum 1) -(define type-special 7) -(define type-pair 4) -(define type-placeholder 5) -(define type-subtyped 3) -(define type-procedure 2) -(define subtype-vector 0) -(define subtype-symbol 1) -(define subtype-port 2) -(define subtype-ratnum 3) -(define subtype-cpxnum 4) -(define subtype-string 16) -(define subtype-bignum 17) -(define data-false (- 33686019)) -(define data-null (- 67372037)) -(define data-true -2) -(define data-undef -3) -(define data-unass -4) -(define data-unbound -5) -(define data-eof -6) -(define data-max-fixnum 268435455) -(define data-min-fixnum (- 268435456)) -(define (make-encoding data type) (+ (* data 8) type)) -(define (obj-type obj) - (cond ((false-object? obj) 'special) - ((undef-object? obj) 'special) - ((symbol-object? obj) 'subtyped) - ((proc-obj? obj) 'procedure) - ((eq? obj #t) 'special) - ((null? obj) 'special) - ((pair? obj) 'pair) - ((number? obj) - (cond ((and (integer? obj) - (exact? obj) - (>= obj data-min-fixnum) - (<= obj data-max-fixnum)) - 'fixnum) - ((and (inexact? (real-part obj)) - (zero? (imag-part obj)) - (exact? (imag-part obj))) - 'flonum) - (else 'subtyped))) - ((char? obj) 'special) - (else 'subtyped))) -(define (obj-subtype obj) - (cond ((symbol-object? obj) 'symbol) - ((number? obj) - (cond ((and (integer? obj) (exact? obj)) 'bignum) - ((and (rational? obj) (exact? obj)) 'ratnum) - (else 'cpxnum))) - ((vector? obj) 'vector) - ((string? obj) 'string) - (else - (compiler-internal-error "obj-subtype, unknown object 'obj'" obj)))) -(define (obj-type-tag obj) - (case (obj-type obj) - ((fixnum) type-fixnum) - ((flonum) type-flonum) - ((special) type-special) - ((pair) type-pair) - ((subtyped) type-subtyped) - ((procedure) type-procedure) - (else (compiler-internal-error "obj-type-tag, unknown object 'obj'" obj)))) -(define (obj-encoding obj) - (case (obj-type obj) - ((fixnum) (make-encoding obj type-fixnum)) - ((special) - (make-encoding - (cond ((false-object? obj) data-false) - ((undef-object? obj) data-undef) - ((eq? obj #t) data-true) - ((null? obj) data-null) - ((char? obj) (character-encoding obj)) - (else - (compiler-internal-error - "obj-encoding, unknown SPECIAL object 'obj'" - obj))) - type-special)) - (else #f))) -(define bits-false (make-encoding data-false type-special)) -(define bits-null (make-encoding data-null type-special)) -(define bits-true (make-encoding data-true type-special)) -(define bits-unass (make-encoding data-unass type-special)) -(define bits-unbound (make-encoding data-unbound type-special)) -(define (asm.begin!) - (set! asm-code-queue (queue-empty)) - (set! asm-const-queue (queue-empty)) - '()) -(define (asm.end! debug-info) - (asm-assemble! debug-info) - (set! asm-code-queue '()) - (set! asm-const-queue '()) - '()) -(define asm-code-queue '()) -(define asm-const-queue '()) -(define (asm-word x) (queue-put! asm-code-queue (modulo x 65536))) -(define (asm-long x) (asm-word (upper-16bits x)) (asm-word x)) -(define (asm-label lbl label-descr) - (queue-put! asm-code-queue (cons 'label (cons lbl label-descr)))) -(define (asm-comment x) (queue-put! asm-code-queue (cons 'comment x))) -(define (asm-align n offset) - (queue-put! asm-code-queue (cons 'align (cons n offset)))) -(define (asm-ref-glob glob) - (queue-put! - asm-code-queue - (cons 'ref-glob (symbol->string (glob-name glob))))) -(define (asm-set-glob glob) - (queue-put! - asm-code-queue - (cons 'set-glob (symbol->string (glob-name glob))))) -(define (asm-ref-glob-jump glob) - (queue-put! - asm-code-queue - (cons 'ref-glob-jump (symbol->string (glob-name glob))))) -(define (asm-proc-ref num offset) - (queue-put! asm-code-queue (cons 'proc-ref (cons num offset)))) -(define (asm-prim-ref proc offset) - (queue-put! - asm-code-queue - (cons 'prim-ref (cons (proc-obj-name proc) offset)))) -(define (asm-m68020-proc) (queue-put! asm-code-queue '(m68020-proc))) -(define (asm-m68881-proc) (queue-put! asm-code-queue '(m68881-proc))) -(define (asm-stat x) (queue-put! asm-code-queue (cons 'stat x))) -(define (asm-brel type lbl) - (queue-put! asm-code-queue (cons 'brab (cons type lbl)))) -(define (asm-wrel lbl offs) - (queue-put! asm-code-queue (cons 'wrel (cons lbl offs)))) -(define (asm-lrel lbl offs n) - (queue-put! asm-code-queue (cons 'lrel (cons lbl (cons offs n))))) -(define (asm-assemble! debug-info) - (define header-offset 2) - (define ref-glob-len 2) - (define set-glob-len 10) - (define ref-glob-jump-len 2) - (define proc-ref-len 4) - (define prim-ref-len 4) - (define stat-len 4) - (define (padding loc n offset) (modulo (- offset loc) n)) - (queue-put! asm-const-queue debug-info) - (asm-align 4 0) - (emit-label const-lbl) - (let ((code-list (queue->list asm-code-queue)) - (const-list (queue->list asm-const-queue))) - (let* ((fix-list - (let loop ((l code-list) (len header-offset) (x '())) - (if (null? l) - (reverse x) - (let ((part (car l)) (rest (cdr l))) - (if (pair? part) - (case (car part) - ((label align brab) - (loop rest 0 (cons (cons len part) x))) - ((wrel) (loop rest (+ len 2) x)) - ((lrel) (loop rest (+ len 4) x)) - ((ref-glob) (loop rest (+ len ref-glob-len) x)) - ((set-glob) (loop rest (+ len set-glob-len) x)) - ((ref-glob-jump) - (loop rest (+ len ref-glob-jump-len) x)) - ((proc-ref) (loop rest (+ len proc-ref-len) x)) - ((prim-ref) (loop rest (+ len prim-ref-len) x)) - ((stat) (loop rest (+ len stat-len) x)) - ((comment m68020-proc m68881-proc) (loop rest len x)) - (else - (compiler-internal-error - "asm-assemble!, unknown code list element" - part))) - (loop rest (+ len 2) x)))))) - (lbl-list - (let loop ((l fix-list) (x '())) - (if (null? l) - x - (let ((part (cdar l)) (rest (cdr l))) - (if (eq? (car part) 'label) - (loop rest (cons (cons (cadr part) part) x)) - (loop rest x))))))) - (define (replace-lbl-refs-by-pointer-to-label) - (let loop ((l code-list)) - (if (not (null? l)) - (let ((part (car l)) (rest (cdr l))) - (if (pair? part) - (case (car part) - ((brab) - (set-cdr! (cdr part) (cdr (assq (cddr part) lbl-list)))) - ((wrel) - (set-car! (cdr part) (cdr (assq (cadr part) lbl-list)))) - ((lrel) - (set-car! - (cdr part) - (cdr (assq (cadr part) lbl-list)))))) - (loop rest))))) - (define (assign-loc-to-labels) - (let loop ((l fix-list) (loc 0)) - (if (not (null? l)) - (let* ((first (car l)) - (rest (cdr l)) - (len (car first)) - (cur-loc (+ loc len)) - (part (cdr first))) - (case (car part) - ((label) - (if (cddr part) - (vector-set! - (cddr part) - 0 - (quotient (- cur-loc header-offset) 8))) - (set-car! (cdr part) cur-loc) - (loop rest cur-loc)) - ((align) - (loop rest - (+ cur-loc - (padding cur-loc (cadr part) (cddr part))))) - ((brab) (loop rest (+ cur-loc 2))) - ((braw) (loop rest (+ cur-loc 4))) - (else - (compiler-internal-error - "assign-loc-to-labels, unknown code list element" - part))))))) - (define (branch-tensioning-pass) - (assign-loc-to-labels) - (let loop ((changed? #f) (l fix-list) (loc 0)) - (if (null? l) - (if changed? (branch-tensioning-pass)) - (let* ((first (car l)) - (rest (cdr l)) - (len (car first)) - (cur-loc (+ loc len)) - (part (cdr first))) - (case (car part) - ((label) (loop changed? rest cur-loc)) - ((align) - (loop changed? - rest - (+ cur-loc - (padding cur-loc (cadr part) (cddr part))))) - ((brab) - (let ((dist (- (cadr (cddr part)) (+ cur-loc 2)))) - (if (or (< dist -128) (> dist 127) (= dist 0)) - (begin - (set-car! part 'braw) - (loop #t rest (+ cur-loc 2))) - (loop changed? rest (+ cur-loc 2))))) - ((braw) (loop changed? rest (+ cur-loc 4))) - (else - (compiler-internal-error - "branch-tensioning-pass, unknown code list element" - part))))))) - (define (write-block start-loc end-loc start end) - (if (> end-loc start-loc) - (ofile-word (quotient (- end-loc start-loc) 2))) - (let loop ((loc start-loc) (l start)) - (if (not (eq? l end)) - (let ((part (car l)) (rest (cdr l))) - (if (pair? part) - (case (car part) - ((label) (loop loc rest)) - ((align) - (let ((n (padding loc (cadr part) (cddr part)))) - (let pad ((i 0)) - (if (< i n) - (begin (ofile-word 0) (pad (+ i 2))) - (loop (+ loc n) rest))))) - ((brab) - (let ((dist (- (cadr (cddr part)) (+ loc 2)))) - (ofile-word (+ (cadr part) (modulo dist 256))) - (loop (+ loc 2) rest))) - ((braw) - (let ((dist (- (cadr (cddr part)) (+ loc 2)))) - (ofile-word (cadr part)) - (ofile-word (modulo dist 65536)) - (loop (+ loc 4) rest))) - ((wrel) - (let ((dist (+ (- (cadr (cadr part)) loc) (cddr part)))) - (ofile-word (modulo dist 65536)) - (loop (+ loc 2) rest))) - ((lrel) - (let ((dist (+ (- (cadr (cadr part)) loc) - (caddr part)))) - (ofile-long (+ (* dist 65536) (cdddr part))) - (loop (+ loc 4) rest))) - ((comment) - (let ((x (cdr part))) - (if (pair? x) (ofile-comment x) (ofile-gvm-instr x)) - (loop loc rest)))) - (begin (ofile-word part) (loop (+ loc 2) rest))))))) - (define (write-code) - (let ((proc-len - (+ (cadr (cdr (assq const-lbl lbl-list))) - (* (length const-list) 4)))) - (if (>= proc-len 32768) - (compiler-limitation-error - "procedure is too big (32K bytes limit per procedure)")) - (ofile-word (+ 32768 proc-len))) - (let loop1 ((start code-list) (start-loc header-offset)) - (let loop2 ((end start) (loc start-loc)) - (if (null? end) - (write-block start-loc loc start end) - (let ((part (car end)) (rest (cdr end))) - (if (pair? part) - (case (car part) - ((label comment) (loop2 rest loc)) - ((align) - (loop2 rest - (+ loc (padding loc (cadr part) (cddr part))))) - ((brab wrel) (loop2 rest (+ loc 2))) - ((braw) (loop2 rest (+ loc 4))) - ((lrel) (loop2 rest (+ loc 4))) - (else - (write-block start-loc loc start end) - (case (car part) - ((ref-glob) - (ofile-wsym global-var-ref-tag (cdr part)) - (loop1 rest (+ loc ref-glob-len))) - ((set-glob) - (ofile-wsym global-var-set-tag (cdr part)) - (loop1 rest (+ loc set-glob-len))) - ((ref-glob-jump) - (ofile-wsym global-var-ref-jump-tag (cdr part)) - (loop1 rest (+ loc ref-glob-jump-len))) - ((proc-ref) - (ofile-word (+ local-proc-ref-tag (cadr part))) - (ofile-word (cddr part)) - (loop1 rest (+ loc proc-ref-len))) - ((prim-ref) - (ofile-wsym prim-proc-ref-tag (cadr part)) - (ofile-word (cddr part)) - (loop1 rest (+ loc prim-ref-len))) - ((m68020-proc) - (ofile-word m68020-proc-code-tag) - (loop1 rest loc)) - ((m68881-proc) - (ofile-word m68881-proc-code-tag) - (loop1 rest loc)) - ((stat) - (ofile-word stat-tag) - (ofile-stat (cdr part)) - (loop1 rest (+ loc stat-len)))))) - (loop2 rest (+ loc 2))))))) - (ofile-word end-of-code-tag) - (for-each ofile-ref const-list) - (ofile-long (obj-encoding (+ (length const-list) 1)))) - (replace-lbl-refs-by-pointer-to-label) - (branch-tensioning-pass) - (write-code)))) -(define const-lbl 0) -(define (identical-opnd68? opnd1 opnd2) (eqv? opnd1 opnd2)) -(define (reg68? x) (or (dreg? x) (areg? x))) -(define (make-dreg num) num) -(define (dreg? x) (and (integer? x) (>= x 0) (< x 8))) -(define (dreg-num x) x) -(define (make-areg num) (+ num 8)) -(define (areg? x) (and (integer? x) (>= x 8) (< x 16))) -(define (areg-num x) (- x 8)) -(define (make-ind areg) (+ areg 8)) -(define (ind? x) (and (integer? x) (>= x 16) (< x 24))) -(define (ind-areg x) (- x 8)) -(define (make-pinc areg) (+ areg 16)) -(define (pinc? x) (and (integer? x) (>= x 24) (< x 32))) -(define (pinc-areg x) (- x 16)) -(define (make-pdec areg) (+ areg 24)) -(define (pdec? x) (and (integer? x) (>= x 32) (< x 40))) -(define (pdec-areg x) (- x 24)) -(define (make-disp areg offset) (+ (+ areg 32) (* (modulo offset 65536) 8))) -(define (disp? x) (and (integer? x) (>= x 40) (< x 524328))) -(define (disp-areg x) (+ (remainder x 8) 8)) -(define (disp-offset x) - (- (modulo (+ (quotient (- x 40) 8) 32768) 65536) 32768)) -(define (make-disp* areg offset) - (if (= offset 0) (make-ind areg) (make-disp areg offset))) -(define (disp*? x) (or (ind? x) (disp? x))) -(define (disp*-areg x) (if (ind? x) (ind-areg x) (disp-areg x))) -(define (disp*-offset x) (if (ind? x) 0 (disp-offset x))) -(define (make-inx areg ireg offset) - (+ (+ areg 524320) (* ireg 8) (* (modulo offset 256) 128))) -(define (inx? x) (and (integer? x) (>= x 524328) (< x 557096))) -(define (inx-areg x) (+ (remainder (- x 524328) 8) 8)) -(define (inx-ireg x) (quotient (remainder (- x 524328) 128) 8)) -(define (inx-offset x) - (- (modulo (+ (quotient (- x 524328) 128) 128) 256) 128)) -(define (make-freg num) (+ 557096 num)) -(define (freg? x) (and (integer? x) (>= x 557096) (< x 557104))) -(define (freg-num x) (- x 557096)) -(define (make-pcr lbl offset) - (+ 557104 (+ (modulo offset 65536) (* lbl 65536)))) -(define (pcr? x) (and (integer? x) (>= x 557104))) -(define (pcr-lbl x) (quotient (- x 557104) 65536)) -(define (pcr-offset x) (- (modulo (- x 524336) 65536) 32768)) -(define (make-imm val) (if (< val 0) (* val 2) (- -1 (* val 2)))) -(define (imm? x) (and (integer? x) (< x 0))) -(define (imm-val x) (if (even? x) (quotient x 2) (- (quotient x 2)))) -(define (make-glob name) name) -(define (glob? x) (symbol? x)) -(define (glob-name x) x) -(define (make-frame-base-rel slot) (make-disp sp-reg slot)) -(define (frame-base-rel? x) - (and (disp? x) (identical-opnd68? sp-reg (disp-areg x)))) -(define (frame-base-rel-slot x) (disp-offset x)) -(define (make-reg-list regs) regs) -(define (reg-list? x) (or (pair? x) (null? x))) -(define (reg-list-regs x) x) -(define first-dtemp 0) -(define gvm-reg1 1) -(define poll-timer-reg (make-dreg 5)) -(define null-reg (make-dreg 6)) -(define placeholder-reg (make-dreg 6)) -(define false-reg (make-dreg 7)) -(define pair-reg (make-dreg 7)) -(define gvm-reg0 0) -(define first-atemp 1) -(define heap-reg (make-areg 3)) -(define ltq-tail-reg (make-areg 4)) -(define pstate-reg (make-areg 5)) -(define table-reg (make-areg 6)) -(define sp-reg (make-areg 7)) -(define pdec-sp (make-pdec sp-reg)) -(define pinc-sp (make-pinc sp-reg)) -(define dtemp1 (make-dreg first-dtemp)) -(define atemp1 (make-areg first-atemp)) -(define atemp2 (make-areg (+ first-atemp 1))) -(define ftemp1 (make-freg 0)) -(define arg-count-reg dtemp1) -(define (trap-offset n) (+ 32768 (* (- n 32) 8))) -(define (emit-move.l opnd1 opnd2) - (let ((src (opnd->mode/reg opnd1)) (dst (opnd->reg/mode opnd2))) - (asm-word (+ 8192 (+ dst src))) - (opnd-ext-rd-long opnd1) - (opnd-ext-wr-long opnd2) - (if ofile-asm? - (emit-asm "movl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2))))) -(define (emit-move.w opnd1 opnd2) - (let ((src (opnd->mode/reg opnd1)) (dst (opnd->reg/mode opnd2))) - (asm-word (+ 12288 (+ dst src))) - (opnd-ext-rd-word opnd1) - (opnd-ext-wr-word opnd2) - (if ofile-asm? - (emit-asm "movw" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2))))) -(define (emit-move.b opnd1 opnd2) - (let ((src (opnd->mode/reg opnd1)) (dst (opnd->reg/mode opnd2))) - (asm-word (+ 4096 (+ dst src))) - (opnd-ext-rd-word opnd1) - (opnd-ext-wr-word opnd2) - (if ofile-asm? - (emit-asm "movb" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2))))) -(define (emit-moveq n opnd) - (asm-word (+ 28672 (+ (* (dreg-num opnd) 512) (modulo n 256)))) - (if ofile-asm? (emit-asm "moveq" ofile-tab "#" n "," (opnd-str opnd)))) -(define (emit-movem.l opnd1 opnd2) - (define (reg-mask reg-list flip-bits?) - (let loop ((i 15) (bit 32768) (mask 0)) - (if (>= i 0) - (loop (- i 1) - (quotient bit 2) - (if (memq i reg-list) - (+ mask (if flip-bits? (quotient 32768 bit) bit)) - mask)) - mask))) - (define (movem op reg-list opnd) - (asm-word (+ op (opnd->mode/reg opnd))) - (asm-word (reg-mask reg-list (pdec? opnd)))) - (if (reg-list? opnd1) - (begin (movem 18624 opnd1 opnd2) (opnd-ext-wr-long opnd2)) - (begin (movem 19648 opnd2 opnd1) (opnd-ext-rd-long opnd1))) - (if ofile-asm? - (emit-asm "moveml" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-exg opnd1 opnd2) - (define (exg r1 r2) - (let ((mode (if (dreg? r2) 49472 (if (dreg? r1) 49544 49480))) - (num1 (if (dreg? r1) (dreg-num r1) (areg-num r1))) - (num2 (if (dreg? r2) (dreg-num r2) (areg-num r2)))) - (asm-word (+ mode (+ (* num1 512) num2))))) - (if (dreg? opnd2) (exg opnd2 opnd1) (exg opnd1 opnd2)) - (if ofile-asm? - (emit-asm "exg" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-eor.l opnd1 opnd2) - (cond ((imm? opnd1) - (asm-word (+ 2688 (opnd->mode/reg opnd2))) - (opnd-ext-rd-long opnd1) - (opnd-ext-wr-long opnd2)) - (else - (asm-word - (+ 45440 (+ (* (dreg-num opnd1) 512) (opnd->mode/reg opnd2)))) - (opnd-ext-wr-long opnd2))) - (if ofile-asm? - (emit-asm "eorl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-and.l opnd1 opnd2) - (cond ((imm? opnd1) - (asm-word (+ 640 (opnd->mode/reg opnd2))) - (opnd-ext-rd-long opnd1) - (opnd-ext-wr-long opnd2)) - (else - (let ((mode (if (dreg? opnd2) 49280 49536)) - (reg (if (dreg? opnd2) (dreg-num opnd2) (dreg-num opnd1))) - (other (if (dreg? opnd2) opnd1 opnd2))) - (asm-word (+ mode (+ (* reg 512) (opnd->mode/reg other)))) - (if (dreg? opnd2) - (opnd-ext-rd-long other) - (opnd-ext-wr-long other))))) - (if ofile-asm? - (emit-asm "andl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-and.w opnd1 opnd2) - (cond ((imm? opnd1) - (asm-word (+ 576 (opnd->mode/reg opnd2))) - (opnd-ext-rd-word opnd1) - (opnd-ext-wr-word opnd2)) - (else - (let ((mode (if (dreg? opnd2) 49216 49472)) - (reg (if (dreg? opnd2) (dreg-num opnd2) (dreg-num opnd1))) - (other (if (dreg? opnd2) opnd1 opnd2))) - (asm-word (+ mode (+ (* reg 512) (opnd->mode/reg other)))) - (if (dreg? opnd2) - (opnd-ext-rd-word other) - (opnd-ext-wr-word other))))) - (if ofile-asm? - (emit-asm "andw" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-or.l opnd1 opnd2) - (cond ((imm? opnd1) - (asm-word (+ 128 (opnd->mode/reg opnd2))) - (opnd-ext-rd-long opnd1) - (opnd-ext-wr-long opnd2)) - (else - (let ((mode (if (dreg? opnd2) 32896 33152)) - (reg (if (dreg? opnd2) (dreg-num opnd2) (dreg-num opnd1))) - (other (if (dreg? opnd2) opnd1 opnd2))) - (asm-word (+ mode (+ (* reg 512) (opnd->mode/reg other)))) - (if (dreg? opnd2) - (opnd-ext-rd-long other) - (opnd-ext-wr-long other))))) - (if ofile-asm? - (emit-asm "orl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-addq.l n opnd) - (let ((m (if (= n 8) 0 n))) - (asm-word (+ 20608 (* m 512) (opnd->mode/reg opnd))) - (opnd-ext-wr-long opnd) - (if ofile-asm? (emit-asm "addql" ofile-tab "#" n "," (opnd-str opnd))))) -(define (emit-addq.w n opnd) - (let ((m (if (= n 8) 0 n))) - (asm-word (+ 20544 (* m 512) (opnd->mode/reg opnd))) - (opnd-ext-wr-word opnd) - (if ofile-asm? (emit-asm "addqw" ofile-tab "#" n "," (opnd-str opnd))))) -(define (emit-add.l opnd1 opnd2) - (cond ((areg? opnd2) - (asm-word - (+ 53696 (+ (* (areg-num opnd2) 512) (opnd->mode/reg opnd1)))) - (opnd-ext-rd-long opnd1)) - ((imm? opnd1) - (asm-word (+ 1664 (opnd->mode/reg opnd2))) - (opnd-ext-rd-long opnd1) - (opnd-ext-wr-long opnd2)) - (else - (let ((mode (if (dreg? opnd2) 53376 53632)) - (reg (if (dreg? opnd2) (dreg-num opnd2) (dreg-num opnd1))) - (other (if (dreg? opnd2) opnd1 opnd2))) - (asm-word (+ mode (+ (* reg 512) (opnd->mode/reg other)))) - (if (dreg? opnd2) - (opnd-ext-rd-long other) - (opnd-ext-wr-long other))))) - (if ofile-asm? - (emit-asm "addl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-add.w opnd1 opnd2) - (cond ((areg? opnd2) - (asm-word - (+ 53440 (+ (* (areg-num opnd2) 512) (opnd->mode/reg opnd1)))) - (opnd-ext-rd-word opnd1)) - ((imm? opnd1) - (asm-word (+ 1600 (opnd->mode/reg opnd2))) - (opnd-ext-rd-word opnd1) - (opnd-ext-wr-word opnd2)) - (else - (let ((mode (if (dreg? opnd2) 53312 53568)) - (reg (if (dreg? opnd2) (dreg-num opnd2) (dreg-num opnd1))) - (other (if (dreg? opnd2) opnd1 opnd2))) - (asm-word (+ mode (+ (* reg 512) (opnd->mode/reg other)))) - (if (dreg? opnd2) - (opnd-ext-rd-word other) - (opnd-ext-wr-word other))))) - (if ofile-asm? - (emit-asm "addw" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-addx.w opnd1 opnd2) - (if (dreg? opnd1) - (asm-word (+ 53568 (+ (* (dreg-num opnd2) 512) (dreg-num opnd1)))) - (asm-word - (+ 53576 - (+ (* (areg-num (pdec-areg opnd2)) 512) - (areg-num (pdec-areg opnd1)))))) - (if ofile-asm? - (emit-asm "addxw" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-subq.l n opnd) - (let ((m (if (= n 8) 0 n))) - (asm-word (+ 20864 (* m 512) (opnd->mode/reg opnd))) - (opnd-ext-wr-long opnd) - (if ofile-asm? (emit-asm "subql" ofile-tab "#" n "," (opnd-str opnd))))) -(define (emit-subq.w n opnd) - (let ((m (if (= n 8) 0 n))) - (asm-word (+ 20800 (* m 512) (opnd->mode/reg opnd))) - (opnd-ext-wr-word opnd) - (if ofile-asm? (emit-asm "subqw" ofile-tab "#" n "," (opnd-str opnd))))) -(define (emit-sub.l opnd1 opnd2) - (cond ((areg? opnd2) - (asm-word - (+ 37312 (+ (* (areg-num opnd2) 512) (opnd->mode/reg opnd1)))) - (opnd-ext-rd-long opnd1)) - ((imm? opnd1) - (asm-word (+ 1152 (opnd->mode/reg opnd2))) - (opnd-ext-rd-long opnd1) - (opnd-ext-wr-long opnd2)) - (else - (let ((mode (if (dreg? opnd2) 36992 37248)) - (reg (if (dreg? opnd2) (dreg-num opnd2) (dreg-num opnd1))) - (other (if (dreg? opnd2) opnd1 opnd2))) - (asm-word (+ mode (+ (* reg 512) (opnd->mode/reg other)))) - (if (dreg? opnd2) - (opnd-ext-rd-long other) - (opnd-ext-wr-long other))))) - (if ofile-asm? - (emit-asm "subl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-sub.w opnd1 opnd2) - (cond ((areg? opnd2) - (asm-word - (+ 37056 (+ (* (areg-num opnd2) 512) (opnd->mode/reg opnd1)))) - (opnd-ext-rd-word opnd1)) - ((imm? opnd1) - (asm-word (+ 1088 (opnd->mode/reg opnd2))) - (opnd-ext-rd-word opnd1) - (opnd-ext-wr-word opnd2)) - (else - (let ((mode (if (dreg? opnd2) 36928 37184)) - (reg (if (dreg? opnd2) (dreg-num opnd2) (dreg-num opnd1))) - (other (if (dreg? opnd2) opnd1 opnd2))) - (asm-word (+ mode (+ (* reg 512) (opnd->mode/reg other)))) - (if (dreg? opnd2) - (opnd-ext-rd-word other) - (opnd-ext-wr-word other))))) - (if ofile-asm? - (emit-asm "subw" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-asl.l opnd1 opnd2) - (if (dreg? opnd1) - (asm-word (+ 57760 (+ (* (dreg-num opnd1) 512) (dreg-num opnd2)))) - (let ((n (imm-val opnd1))) - (asm-word (+ 57728 (+ (* (if (= n 8) 0 n) 512) (dreg-num opnd2)))))) - (if ofile-asm? - (emit-asm "asll" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-asl.w opnd1 opnd2) - (if (dreg? opnd1) - (asm-word (+ 57696 (+ (* (dreg-num opnd1) 512) (dreg-num opnd2)))) - (let ((n (imm-val opnd1))) - (asm-word (+ 57664 (+ (* (if (= n 8) 0 n) 512) (dreg-num opnd2)))))) - (if ofile-asm? - (emit-asm "aslw" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-asr.l opnd1 opnd2) - (if (dreg? opnd1) - (asm-word (+ 57504 (+ (* (dreg-num opnd1) 512) (dreg-num opnd2)))) - (let ((n (imm-val opnd1))) - (asm-word (+ 57472 (+ (* (if (= n 8) 0 n) 512) (dreg-num opnd2)))))) - (if ofile-asm? - (emit-asm "asrl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-asr.w opnd1 opnd2) - (if (dreg? opnd1) - (asm-word (+ 57440 (+ (* (dreg-num opnd1) 512) (dreg-num opnd2)))) - (let ((n (imm-val opnd1))) - (asm-word (+ 57408 (+ (* (if (= n 8) 0 n) 512) (dreg-num opnd2)))))) - (if ofile-asm? - (emit-asm "asrw" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-lsl.l opnd1 opnd2) - (if (dreg? opnd1) - (asm-word (+ 57768 (+ (* (dreg-num opnd1) 512) (dreg-num opnd2)))) - (let ((n (imm-val opnd1))) - (asm-word (+ 57736 (+ (* (if (= n 8) 0 n) 512) (dreg-num opnd2)))))) - (if ofile-asm? - (emit-asm "lsll" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-lsr.l opnd1 opnd2) - (if (dreg? opnd1) - (asm-word (+ 57512 (+ (* (dreg-num opnd1) 512) (dreg-num opnd2)))) - (let ((n (imm-val opnd1))) - (asm-word (+ 57480 (+ (* (if (= n 8) 0 n) 512) (dreg-num opnd2)))))) - (if ofile-asm? - (emit-asm "lsrl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-lsr.w opnd1 opnd2) - (if (dreg? opnd1) - (asm-word (+ 57448 (+ (* (dreg-num opnd1) 512) (dreg-num opnd2)))) - (let ((n (imm-val opnd1))) - (asm-word (+ 57416 (+ (* (if (= n 8) 0 n) 512) (dreg-num opnd2)))))) - (if ofile-asm? - (emit-asm "lsrw" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-clr.l opnd) - (asm-word (+ 17024 (opnd->mode/reg opnd))) - (opnd-ext-wr-long opnd) - (if ofile-asm? (emit-asm "clrl" ofile-tab (opnd-str opnd)))) -(define (emit-neg.l opnd) - (asm-word (+ 17536 (opnd->mode/reg opnd))) - (opnd-ext-wr-long opnd) - (if ofile-asm? (emit-asm "negl" ofile-tab (opnd-str opnd)))) -(define (emit-not.l opnd) - (asm-word (+ 18048 (opnd->mode/reg opnd))) - (opnd-ext-wr-long opnd) - (if ofile-asm? (emit-asm "notl" ofile-tab (opnd-str opnd)))) -(define (emit-ext.l opnd) - (asm-word (+ 18624 (dreg-num opnd))) - (if ofile-asm? (emit-asm "extl" ofile-tab (opnd-str opnd)))) -(define (emit-ext.w opnd) - (asm-word (+ 18560 (dreg-num opnd))) - (if ofile-asm? (emit-asm "extw" ofile-tab (opnd-str opnd)))) -(define (emit-swap opnd) - (asm-word (+ 18496 (dreg-num opnd))) - (if ofile-asm? (emit-asm "swap" ofile-tab (opnd-str opnd)))) -(define (emit-cmp.l opnd1 opnd2) - (cond ((areg? opnd2) - (asm-word - (+ 45504 (+ (* (areg-num opnd2) 512) (opnd->mode/reg opnd1)))) - (opnd-ext-rd-long opnd1)) - ((imm? opnd1) - (asm-word (+ 3200 (opnd->mode/reg opnd2))) - (opnd-ext-rd-long opnd1) - (opnd-ext-rd-long opnd2)) - (else - (asm-word - (+ 45184 (+ (* (dreg-num opnd2) 512) (opnd->mode/reg opnd1)))) - (opnd-ext-rd-long opnd1))) - (if ofile-asm? - (emit-asm "cmpl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-cmp.w opnd1 opnd2) - (cond ((areg? opnd2) - (asm-word - (+ 45248 (+ (* (areg-num opnd2) 512) (opnd->mode/reg opnd1)))) - (opnd-ext-rd-word opnd1)) - ((imm? opnd1) - (asm-word (+ 3136 (opnd->mode/reg opnd2))) - (opnd-ext-rd-word opnd1) - (opnd-ext-rd-word opnd2)) - (else - (asm-word - (+ 45120 (+ (* (dreg-num opnd2) 512) (opnd->mode/reg opnd1)))) - (opnd-ext-rd-word opnd1))) - (if ofile-asm? - (emit-asm "cmpw" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-cmp.b opnd1 opnd2) - (cond ((imm? opnd1) - (asm-word (+ 3072 (opnd->mode/reg opnd2))) - (opnd-ext-rd-word opnd1) - (opnd-ext-rd-word opnd2)) - (else - (asm-word - (+ 45056 (+ (* (dreg-num opnd2) 512) (opnd->mode/reg opnd1)))) - (opnd-ext-rd-word opnd1))) - (if ofile-asm? - (emit-asm "cmpb" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-tst.l opnd) - (asm-word (+ 19072 (opnd->mode/reg opnd))) - (opnd-ext-rd-long opnd) - (if ofile-asm? (emit-asm "tstl" ofile-tab (opnd-str opnd)))) -(define (emit-tst.w opnd) - (asm-word (+ 19008 (opnd->mode/reg opnd))) - (opnd-ext-rd-word opnd) - (if ofile-asm? (emit-asm "tstw" ofile-tab (opnd-str opnd)))) -(define (emit-lea opnd areg) - (asm-word (+ 16832 (+ (* (areg-num areg) 512) (opnd->mode/reg opnd)))) - (opnd-ext-rd-long opnd) - (if ofile-asm? - (emit-asm "lea" ofile-tab (opnd-str opnd) "," (opnd-str areg)))) -(define (emit-unlk areg) - (asm-word (+ 20056 (areg-num areg))) - (if ofile-asm? (emit-asm "unlk" ofile-tab (opnd-str areg)))) -(define (emit-move-proc num opnd) - (let ((dst (opnd->reg/mode opnd))) - (asm-word (+ 8192 (+ dst 60))) - (asm-proc-ref num 0) - (opnd-ext-wr-long opnd) - (if ofile-asm? (emit-asm "MOVE_PROC(" num "," (opnd-str opnd) ")")))) -(define (emit-move-prim val opnd) - (let ((dst (opnd->reg/mode opnd))) - (asm-word (+ 8192 (+ dst 60))) - (asm-prim-ref val 0) - (opnd-ext-wr-long opnd) - (if ofile-asm? - (emit-asm "MOVE_PRIM(" (proc-obj-name val) "," (opnd-str opnd) ")")))) -(define (emit-pea opnd) - (asm-word (+ 18496 (opnd->mode/reg opnd))) - (opnd-ext-rd-long opnd) - (if ofile-asm? (emit-asm "pea" ofile-tab (opnd-str opnd)))) -(define (emit-pea* n) - (asm-word 18552) - (asm-word n) - (if ofile-asm? (emit-asm "pea" ofile-tab n))) -(define (emit-btst opnd1 opnd2) - (asm-word (+ 256 (+ (* (dreg-num opnd1) 512) (opnd->mode/reg opnd2)))) - (opnd-ext-rd-word opnd2) - (if ofile-asm? - (emit-asm "btst" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-bra lbl) - (asm-brel 24576 lbl) - (if ofile-asm? (emit-asm "bra" ofile-tab "L" lbl))) -(define (emit-bcc lbl) - (asm-brel 25600 lbl) - (if ofile-asm? (emit-asm "bcc" ofile-tab "L" lbl))) -(define (emit-bcs lbl) - (asm-brel 25856 lbl) - (if ofile-asm? (emit-asm "bcs" ofile-tab "L" lbl))) -(define (emit-bhi lbl) - (asm-brel 25088 lbl) - (if ofile-asm? (emit-asm "bhi" ofile-tab "L" lbl))) -(define (emit-bls lbl) - (asm-brel 25344 lbl) - (if ofile-asm? (emit-asm "bls" ofile-tab "L" lbl))) -(define (emit-bmi lbl) - (asm-brel 27392 lbl) - (if ofile-asm? (emit-asm "bmi" ofile-tab "L" lbl))) -(define (emit-bpl lbl) - (asm-brel 27136 lbl) - (if ofile-asm? (emit-asm "bpl" ofile-tab "L" lbl))) -(define (emit-beq lbl) - (asm-brel 26368 lbl) - (if ofile-asm? (emit-asm "beq" ofile-tab "L" lbl))) -(define (emit-bne lbl) - (asm-brel 26112 lbl) - (if ofile-asm? (emit-asm "bne" ofile-tab "L" lbl))) -(define (emit-blt lbl) - (asm-brel 27904 lbl) - (if ofile-asm? (emit-asm "blt" ofile-tab "L" lbl))) -(define (emit-bgt lbl) - (asm-brel 28160 lbl) - (if ofile-asm? (emit-asm "bgt" ofile-tab "L" lbl))) -(define (emit-ble lbl) - (asm-brel 28416 lbl) - (if ofile-asm? (emit-asm "ble" ofile-tab "L" lbl))) -(define (emit-bge lbl) - (asm-brel 27648 lbl) - (if ofile-asm? (emit-asm "bge" ofile-tab "L" lbl))) -(define (emit-dbra dreg lbl) - (asm-word (+ 20936 dreg)) - (asm-wrel lbl 0) - (if ofile-asm? (emit-asm "dbra" ofile-tab (opnd-str dreg) ",L" lbl))) -(define (emit-trap num) - (asm-word (+ 20032 num)) - (if ofile-asm? (emit-asm "trap" ofile-tab "#" num))) -(define (emit-trap1 num args) - (asm-word (+ 20136 (areg-num table-reg))) - (asm-word (trap-offset num)) - (let loop ((args args)) - (if (not (null? args)) (begin (asm-word (car args)) (loop (cdr args))))) - (if ofile-asm? - (let () - (define (words l) - (if (null? l) (list ")") (cons "," (cons (car l) (words (cdr l)))))) - (apply emit-asm (cons "TRAP1(" (cons num (words args))))))) -(define (emit-trap2 num args) - (asm-word (+ 20136 (areg-num table-reg))) - (asm-word (trap-offset num)) - (asm-align 8 (modulo (- 4 (* (length args) 2)) 8)) - (let loop ((args args)) - (if (not (null? args)) (begin (asm-word (car args)) (loop (cdr args))))) - (if ofile-asm? - (let () - (define (words l) - (if (null? l) (list ")") (cons "," (cons (car l) (words (cdr l)))))) - (apply emit-asm (cons "TRAP2(" (cons num (words args))))))) -(define (emit-trap3 num) - (asm-word (+ 20200 (areg-num table-reg))) - (asm-word (trap-offset num)) - (if ofile-asm? (emit-asm "TRAP3(" num ")"))) -(define (emit-rts) (asm-word 20085) (if ofile-asm? (emit-asm "rts"))) -(define (emit-nop) (asm-word 20081) (if ofile-asm? (emit-asm "nop"))) -(define (emit-jmp opnd) - (asm-word (+ 20160 (opnd->mode/reg opnd))) - (opnd-ext-rd-long opnd) - (if ofile-asm? (emit-asm "jmp" ofile-tab (opnd-str opnd)))) -(define (emit-jmp-glob glob) - (asm-word 8814) - (asm-ref-glob-jump glob) - (asm-word 20177) - (if ofile-asm? (emit-asm "JMP_GLOB(" (glob-name glob) ")"))) -(define (emit-jmp-proc num offset) - (asm-word 20217) - (asm-proc-ref num offset) - (if ofile-asm? (emit-asm "JMP_PROC(" num "," offset ")"))) -(define (emit-jmp-prim val offset) - (asm-word 20217) - (asm-prim-ref val offset) - (if ofile-asm? (emit-asm "JMP_PRIM(" (proc-obj-name val) "," offset ")"))) -(define (emit-jsr opnd) - (asm-word (+ 20096 (opnd->mode/reg opnd))) - (opnd-ext-rd-long opnd) - (if ofile-asm? (emit-asm "jsr" ofile-tab (opnd-str opnd)))) -(define (emit-word n) - (asm-word n) - (if ofile-asm? (emit-asm ".word" ofile-tab n))) -(define (emit-label lbl) - (asm-label lbl #f) - (if ofile-asm? (emit-asm* "L" lbl ":"))) -(define (emit-label-subproc lbl parent-lbl label-descr) - (asm-align 8 0) - (asm-wrel parent-lbl (- 32768 type-procedure)) - (asm-label lbl label-descr) - (if ofile-asm? - (begin (emit-asm "SUBPROC(L" parent-lbl ")") (emit-asm* "L" lbl ":")))) -(define (emit-label-return lbl parent-lbl fs link label-descr) - (asm-align 8 4) - (asm-word (* fs 4)) - (asm-word (* (- fs link) 4)) - (asm-wrel parent-lbl (- 32768 type-procedure)) - (asm-label lbl label-descr) - (if ofile-asm? - (begin - (emit-asm "RETURN(L" parent-lbl "," fs "," link ")") - (emit-asm* "L" lbl ":")))) -(define (emit-label-task-return lbl parent-lbl fs link label-descr) - (asm-align 8 4) - (asm-word (+ 32768 (* fs 4))) - (asm-word (* (- fs link) 4)) - (asm-wrel parent-lbl (- 32768 type-procedure)) - (asm-label lbl label-descr) - (if ofile-asm? - (begin - (emit-asm "TASK_RETURN(L" parent-lbl "," fs "," link ")") - (emit-asm* "L" lbl ":")))) -(define (emit-lbl-ptr lbl) - (asm-wrel lbl 0) - (if ofile-asm? (emit-asm "LBL_PTR(L" lbl ")"))) -(define (emit-set-glob glob) - (asm-set-glob glob) - (if ofile-asm? (emit-asm "SET_GLOB(" (glob-name glob) ")"))) -(define (emit-const obj) - (let ((n (pos-in-list obj (queue->list asm-const-queue)))) - (if n - (make-pcr const-lbl (* n 4)) - (let ((m (length (queue->list asm-const-queue)))) - (queue-put! asm-const-queue obj) - (make-pcr const-lbl (* m 4)))))) -(define (emit-stat stat) - (asm-word 21177) - (asm-stat stat) - (if ofile-asm? (emit-asm "STAT(" stat ")"))) -(define (emit-asm . l) (asm-comment (cons ofile-tab l))) -(define (emit-asm* . l) (asm-comment l)) -(define (emit-muls.l opnd1 opnd2) - (asm-m68020-proc) - (asm-word (+ 19456 (opnd->mode/reg opnd1))) - (asm-word (+ 2048 (* (dreg-num opnd2) 4096))) - (opnd-ext-rd-long opnd1) - (if ofile-asm? - (emit-asm "mulsl" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-divsl.l opnd1 opnd2 opnd3) - (asm-m68020-proc) - (asm-word (+ 19520 (opnd->mode/reg opnd1))) - (asm-word (+ 2048 (* (dreg-num opnd3) 4096) (dreg-num opnd2))) - (opnd-ext-rd-long opnd1) - (if ofile-asm? - (emit-asm - "divsll" - ofile-tab - (opnd-str opnd1) - "," - (opnd-str opnd2) - ":" - (opnd-str opnd3)))) -(define (emit-fint.dx opnd1 opnd2) (emit-fop.dx "int" 1 opnd1 opnd2)) -(define (emit-fsinh.dx opnd1 opnd2) (emit-fop.dx "sinh" 2 opnd1 opnd2)) -(define (emit-fintrz.dx opnd1 opnd2) (emit-fop.dx "intrz" 3 opnd1 opnd2)) -(define (emit-fsqrt.dx opnd1 opnd2) (emit-fop.dx "sqrt" 4 opnd1 opnd2)) -(define (emit-flognp1.dx opnd1 opnd2) (emit-fop.dx "lognp1" 6 opnd1 opnd2)) -(define (emit-fetoxm1.dx opnd1 opnd2) (emit-fop.dx "etoxm1" 8 opnd1 opnd2)) -(define (emit-ftanh.dx opnd1 opnd2) (emit-fop.dx "tanh" 9 opnd1 opnd2)) -(define (emit-fatan.dx opnd1 opnd2) (emit-fop.dx "atan" 10 opnd1 opnd2)) -(define (emit-fasin.dx opnd1 opnd2) (emit-fop.dx "asin" 12 opnd1 opnd2)) -(define (emit-fatanh.dx opnd1 opnd2) (emit-fop.dx "atanh" 13 opnd1 opnd2)) -(define (emit-fsin.dx opnd1 opnd2) (emit-fop.dx "sin" 14 opnd1 opnd2)) -(define (emit-ftan.dx opnd1 opnd2) (emit-fop.dx "tan" 15 opnd1 opnd2)) -(define (emit-fetox.dx opnd1 opnd2) (emit-fop.dx "etox" 16 opnd1 opnd2)) -(define (emit-ftwotox.dx opnd1 opnd2) (emit-fop.dx "twotox" 17 opnd1 opnd2)) -(define (emit-ftentox.dx opnd1 opnd2) (emit-fop.dx "tentox" 18 opnd1 opnd2)) -(define (emit-flogn.dx opnd1 opnd2) (emit-fop.dx "logn" 20 opnd1 opnd2)) -(define (emit-flog10.dx opnd1 opnd2) (emit-fop.dx "log10" 21 opnd1 opnd2)) -(define (emit-flog2.dx opnd1 opnd2) (emit-fop.dx "log2" 22 opnd1 opnd2)) -(define (emit-fabs.dx opnd1 opnd2) (emit-fop.dx "abs" 24 opnd1 opnd2)) -(define (emit-fcosh.dx opnd1 opnd2) (emit-fop.dx "cosh" 25 opnd1 opnd2)) -(define (emit-fneg.dx opnd1 opnd2) (emit-fop.dx "neg" 26 opnd1 opnd2)) -(define (emit-facos.dx opnd1 opnd2) (emit-fop.dx "acos" 28 opnd1 opnd2)) -(define (emit-fcos.dx opnd1 opnd2) (emit-fop.dx "cos" 29 opnd1 opnd2)) -(define (emit-fgetexp.dx opnd1 opnd2) (emit-fop.dx "getexp" 30 opnd1 opnd2)) -(define (emit-fgetman.dx opnd1 opnd2) (emit-fop.dx "getman" 31 opnd1 opnd2)) -(define (emit-fdiv.dx opnd1 opnd2) (emit-fop.dx "div" 32 opnd1 opnd2)) -(define (emit-fmod.dx opnd1 opnd2) (emit-fop.dx "mod" 33 opnd1 opnd2)) -(define (emit-fadd.dx opnd1 opnd2) (emit-fop.dx "add" 34 opnd1 opnd2)) -(define (emit-fmul.dx opnd1 opnd2) (emit-fop.dx "mul" 35 opnd1 opnd2)) -(define (emit-fsgldiv.dx opnd1 opnd2) (emit-fop.dx "sgldiv" 36 opnd1 opnd2)) -(define (emit-frem.dx opnd1 opnd2) (emit-fop.dx "rem" 37 opnd1 opnd2)) -(define (emit-fscale.dx opnd1 opnd2) (emit-fop.dx "scale" 38 opnd1 opnd2)) -(define (emit-fsglmul.dx opnd1 opnd2) (emit-fop.dx "sglmul" 39 opnd1 opnd2)) -(define (emit-fsub.dx opnd1 opnd2) (emit-fop.dx "sub" 40 opnd1 opnd2)) -(define (emit-fcmp.dx opnd1 opnd2) (emit-fop.dx "cmp" 56 opnd1 opnd2)) -(define (emit-fop.dx name code opnd1 opnd2) - (asm-m68881-proc) - (asm-word (+ 61952 (opnd->mode/reg opnd1))) - (asm-word - (+ (if (freg? opnd1) (* (freg-num opnd1) 1024) 21504) - (* (freg-num opnd2) 128) - code)) - (opnd-ext-rd-long opnd1) - (if ofile-asm? - (emit-asm - "f" - name - (if (freg? opnd1) "x" "d") - ofile-tab - (opnd-str opnd1) - "," - (opnd-str opnd2)))) -(define (emit-fmov.dx opnd1 opnd2) - (emit-fmov - (if (and (freg? opnd1) (freg? opnd2)) (* (freg-num opnd1) 1024) 21504) - opnd1 - opnd2) - (if ofile-asm? - (emit-asm - (if (and (freg? opnd1) (freg? opnd2)) "fmovex" "fmoved") - ofile-tab - (opnd-str opnd1) - "," - (opnd-str opnd2)))) -(define (emit-fmov.l opnd1 opnd2) - (emit-fmov 16384 opnd1 opnd2) - (if ofile-asm? - (emit-asm "fmovel" ofile-tab (opnd-str opnd1) "," (opnd-str opnd2)))) -(define (emit-fmov code opnd1 opnd2) - (define (fmov code opnd1 opnd2) - (asm-m68881-proc) - (asm-word (+ 61952 (opnd->mode/reg opnd1))) - (asm-word (+ (* (freg-num opnd2) 128) code)) - (opnd-ext-rd-long opnd1)) - (if (freg? opnd2) (fmov code opnd1 opnd2) (fmov (+ code 8192) opnd2 opnd1))) -(define (emit-fbeq lbl) - (asm-m68881-proc) - (asm-word 62081) - (asm-wrel lbl 0) - (if ofile-asm? (emit-asm "fbeq" ofile-tab "L" lbl))) -(define (emit-fbne lbl) - (asm-m68881-proc) - (asm-word 62094) - (asm-wrel lbl 0) - (if ofile-asm? (emit-asm "fbne" ofile-tab "L" lbl))) -(define (emit-fblt lbl) - (asm-m68881-proc) - (asm-word 62100) - (asm-wrel lbl 0) - (if ofile-asm? (emit-asm "fblt" ofile-tab "L" lbl))) -(define (emit-fbgt lbl) - (asm-m68881-proc) - (asm-word 62098) - (asm-wrel lbl 0) - (if ofile-asm? (emit-asm "fbgt" ofile-tab "L" lbl))) -(define (emit-fble lbl) - (asm-m68881-proc) - (asm-word 62101) - (asm-wrel lbl 0) - (if ofile-asm? (emit-asm "fble" ofile-tab "L" lbl))) -(define (emit-fbge lbl) - (asm-m68881-proc) - (asm-word 62099) - (asm-wrel lbl 0) - (if ofile-asm? (emit-asm "fbge" ofile-tab "L" lbl))) -(define (opnd->mode/reg opnd) - (cond ((disp? opnd) (+ 32 (disp-areg opnd))) - ((inx? opnd) (+ 40 (inx-areg opnd))) - ((pcr? opnd) 58) - ((imm? opnd) 60) - ((glob? opnd) (+ 32 table-reg)) - ((freg? opnd) 0) - (else opnd))) -(define (opnd->reg/mode opnd) - (let ((x (opnd->mode/reg opnd))) - (* (+ (* 8 (remainder x 8)) (quotient x 8)) 64))) -(define (opnd-ext-rd-long opnd) (opnd-extension opnd #f #f)) -(define (opnd-ext-rd-word opnd) (opnd-extension opnd #f #t)) -(define (opnd-ext-wr-long opnd) (opnd-extension opnd #t #f)) -(define (opnd-ext-wr-word opnd) (opnd-extension opnd #t #t)) -(define (opnd-extension opnd write? word?) - (cond ((disp? opnd) (asm-word (disp-offset opnd))) - ((inx? opnd) - (asm-word - (+ (+ (* (inx-ireg opnd) 4096) 2048) - (modulo (inx-offset opnd) 256)))) - ((pcr? opnd) (asm-wrel (pcr-lbl opnd) (pcr-offset opnd))) - ((imm? opnd) - (if word? (asm-word (imm-val opnd)) (asm-long (imm-val opnd)))) - ((glob? opnd) (if write? (asm-set-glob opnd) (asm-ref-glob opnd))))) -(define (opnd-str opnd) - (cond ((dreg? opnd) - (vector-ref - '#("d0" "d1" "d2" "d3" "d4" "d5" "d6" "d7") - (dreg-num opnd))) - ((areg? opnd) - (vector-ref - '#("a0" "a1" "a2" "a3" "a4" "a5" "a6" "sp") - (areg-num opnd))) - ((ind? opnd) - (vector-ref - '#("a0@" "a1@" "a2@" "a3@" "a4@" "a5@" "a6@" "sp@") - (areg-num (ind-areg opnd)))) - ((pinc? opnd) - (vector-ref - '#("a0@+" "a1@+" "a2@+" "a3@+" "a4@+" "a5@+" "a6@+" "sp@+") - (areg-num (pinc-areg opnd)))) - ((pdec? opnd) - (vector-ref - '#("a0@-" "a1@-" "a2@-" "a3@-" "a4@-" "a5@-" "a6@-" "sp@-") - (areg-num (pdec-areg opnd)))) - ((disp? opnd) - (string-append - (opnd-str (disp-areg opnd)) - "@(" - (number->string (disp-offset opnd)) - ")")) - ((inx? opnd) - (string-append - (opnd-str (inx-areg opnd)) - "@(" - (number->string (inx-offset opnd)) - "," - (opnd-str (inx-ireg opnd)) - ":l)")) - ((pcr? opnd) - (let ((lbl (pcr-lbl opnd)) (offs (pcr-offset opnd))) - (if (= offs 0) - (string-append "L" (number->string lbl)) - (string-append - "L" - (number->string lbl) - "+" - (number->string offs))))) - ((imm? opnd) (string-append "#" (number->string (imm-val opnd)))) - ((glob? opnd) - (string-append "GLOB(" (symbol->string (glob-name opnd)) ")")) - ((freg? opnd) - (vector-ref - '#("fp0" "fp1" "fp2" "fp3" "fp4" "fp5" "fp6" "fp7") - (freg-num opnd))) - ((reg-list? opnd) - (let loop ((l (reg-list-regs opnd)) (result "[") (sep "")) - (if (pair? l) - (loop (cdr l) (string-append result sep (opnd-str (car l))) "/") - (string-append result "]")))) - (else (compiler-internal-error "opnd-str, unknown 'opnd'" opnd)))) -(define (begin! info-port targ) - (set! return-reg (make-reg 0)) - (target-end!-set! targ end!) - (target-dump-set! targ dump) - (target-nb-regs-set! targ nb-gvm-regs) - (target-prim-info-set! targ prim-info) - (target-label-info-set! targ label-info) - (target-jump-info-set! targ jump-info) - (target-proc-result-set! targ (make-reg 1)) - (target-task-return-set! targ return-reg) - (set! *info-port* info-port) - '()) -(define (end!) '()) -(define *info-port* '()) -(define nb-gvm-regs 5) -(define nb-arg-regs 3) -(define pointer-size 4) -(define prim-proc-table - (map (lambda (x) - (cons (string->canonical-symbol (car x)) - (apply make-proc-obj (car x) #t #f (cdr x)))) - prim-procs)) -(define (prim-info name) - (let ((x (assq name prim-proc-table))) (if x (cdr x) #f))) -(define (get-prim-info name) - (let ((proc (prim-info (string->canonical-symbol name)))) - (if proc - proc - (compiler-internal-error "get-prim-info, unknown primitive:" name)))) -(define (label-info min-args nb-parms rest? closed?) - (let ((nb-stacked (max 0 (- nb-parms nb-arg-regs)))) - (define (location-of-parms i) - (if (> i nb-parms) - '() - (cons (cons i - (if (> i nb-stacked) - (make-reg (- i nb-stacked)) - (make-stk i))) - (location-of-parms (+ i 1))))) - (let ((x (cons (cons 'return 0) (location-of-parms 1)))) - (make-pcontext - nb-stacked - (if closed? - (cons (cons 'closure-env (make-reg (+ nb-arg-regs 1))) x) - x))))) -(define (jump-info nb-args) - (let ((nb-stacked (max 0 (- nb-args nb-arg-regs)))) - (define (location-of-args i) - (if (> i nb-args) - '() - (cons (cons i - (if (> i nb-stacked) - (make-reg (- i nb-stacked)) - (make-stk i))) - (location-of-args (+ i 1))))) - (make-pcontext - nb-stacked - (cons (cons 'return (make-reg 0)) (location-of-args 1))))) -(define (closed-var-offset i) (+ (* i pointer-size) 2)) -(define (dump proc filename c-intf options) - (if *info-port* - (begin (display "Dumping:" *info-port*) (newline *info-port*))) - (set! ofile-asm? (memq 'asm options)) - (set! ofile-stats? (memq 'stats options)) - (set! debug-info? (memq 'debug options)) - (set! object-queue (queue-empty)) - (set! objects-dumped (queue-empty)) - (ofile.begin! filename add-object) - (queue-put! object-queue proc) - (queue-put! objects-dumped proc) - (let loop ((index 0)) - (if (not (queue-empty? object-queue)) - (let ((obj (queue-get! object-queue))) - (dump-object obj index) - (loop (+ index 1))))) - (ofile.end!) - (if *info-port* (newline *info-port*)) - (set! object-queue '()) - (set! objects-dumped '())) -(define debug-info? '()) -(define object-queue '()) -(define objects-dumped '()) -(define (add-object obj) - (if (and (proc-obj? obj) (not (proc-obj-code obj))) - #f - (let ((n (pos-in-list obj (queue->list objects-dumped)))) - (if n - n - (let ((m (length (queue->list objects-dumped)))) - (queue-put! objects-dumped obj) - (queue-put! object-queue obj) - m))))) -(define (dump-object obj index) - (ofile-line "|------------------------------------------------------") - (case (obj-type obj) - ((pair) (dump-pair obj)) - ((flonum) (dump-flonum obj)) - ((subtyped) - (case (obj-subtype obj) - ((vector) (dump-vector obj)) - ((symbol) (dump-symbol obj)) - ((ratnum) (dump-ratnum obj)) - ((cpxnum) (dump-cpxnum obj)) - ((string) (dump-string obj)) - ((bignum) (dump-bignum obj)) - (else - (compiler-internal-error - "dump-object, can't dump object 'obj':" - obj)))) - ((procedure) (dump-procedure obj)) - (else - (compiler-internal-error "dump-object, can't dump object 'obj':" obj)))) -(define (dump-pair pair) - (ofile-long pair-prefix) - (ofile-ref (cdr pair)) - (ofile-ref (car pair))) -(define (dump-vector v) - (ofile-long (+ (* (vector-length v) 1024) (* subtype-vector 8))) - (let ((len (vector-length v))) - (let loop ((i 0)) - (if (< i len) (begin (ofile-ref (vector-ref v i)) (loop (+ i 1))))))) -(define (dump-symbol sym) - (compiler-internal-error "dump-symbol, can't dump SYMBOL type")) -(define (dump-ratnum x) - (ofile-long (+ (* 2 1024) (* subtype-ratnum 8))) - (ofile-ref (numerator x)) - (ofile-ref (denominator x))) -(define (dump-cpxnum x) - (ofile-long (+ (* 2 1024) (* subtype-cpxnum 8))) - (ofile-ref (real-part x)) - (ofile-ref (imag-part x))) -(define (dump-string s) - (ofile-long (+ (* (+ (string-length s) 1) 256) (* subtype-string 8))) - (let ((len (string-length s))) - (define (ref i) (if (>= i len) 0 (character-encoding (string-ref s i)))) - (let loop ((i 0)) - (if (<= i len) - (begin - (ofile-word (+ (* (ref i) 256) (ref (+ i 1)))) - (loop (+ i 2))))))) -(define (dump-flonum x) - (let ((bits (flonum->bits x))) - (ofile-long flonum-prefix) - (ofile-long (quotient bits 4294967296)) - (ofile-long (modulo bits 4294967296)))) -(define (flonum->inexact-exponential-format x) - (define (exp-form-pos x y i) - (let ((i*2 (+ i i))) - (let ((z (if (and (not (< flonum-e-bias i*2)) (not (< x y))) - (exp-form-pos x (* y y) i*2) - (cons x 0)))) - (let ((a (car z)) (b (cdr z))) - (let ((i+b (+ i b))) - (if (and (not (< flonum-e-bias i+b)) (not (< a y))) - (begin (set-car! z (/ a y)) (set-cdr! z i+b))) - z))))) - (define (exp-form-neg x y i) - (let ((i*2 (+ i i))) - (let ((z (if (and (< i*2 flonum-e-bias-minus-1) (< x y)) - (exp-form-neg x (* y y) i*2) - (cons x 0)))) - (let ((a (car z)) (b (cdr z))) - (let ((i+b (+ i b))) - (if (and (< i+b flonum-e-bias-minus-1) (< a y)) - (begin (set-car! z (/ a y)) (set-cdr! z i+b))) - z))))) - (define (exp-form x) - (if (< x inexact-+1) - (let ((z (exp-form-neg x inexact-+1/2 1))) - (set-car! z (* inexact-+2 (car z))) - (set-cdr! z (- -1 (cdr z))) - z) - (exp-form-pos x inexact-+2 1))) - (if (negative? x) - (let ((z (exp-form (- inexact-0 x)))) - (set-car! z (- inexact-0 (car z))) - z) - (exp-form x))) -(define (flonum->exact-exponential-format x) - (let ((z (flonum->inexact-exponential-format x))) - (let ((y (car z))) - (cond ((not (< y inexact-+2)) - (set-car! z flonum-+m-min) - (set-cdr! z flonum-e-bias-plus-1)) - ((not (< inexact--2 y)) - (set-car! z flonum--m-min) - (set-cdr! z flonum-e-bias-plus-1)) - (else - (set-car! - z - (truncate (inexact->exact (* (car z) inexact-m-min)))))) - (set-cdr! z (- (cdr z) flonum-m-bits)) - z))) -(define (flonum->bits x) - (define (bits a b) - (if (< a flonum-+m-min) - a - (+ (- a flonum-+m-min) - (* (+ (+ b flonum-m-bits) flonum-e-bias) flonum-+m-min)))) - (let ((z (flonum->exact-exponential-format x))) - (let ((a (car z)) (b (cdr z))) - (if (negative? a) (+ flonum-sign-bit (bits (- 0 a) b)) (bits a b))))) -(define flonum-m-bits 52) -(define flonum-e-bits 11) -(define flonum-sign-bit 9223372036854775808) -(define flonum-+m-min 4503599627370496) -(define flonum--m-min -4503599627370496) -(define flonum-e-bias 1023) -(define flonum-e-bias-plus-1 1024) -(define flonum-e-bias-minus-1 1022) -(define inexact-m-min (exact->inexact flonum-+m-min)) -(define inexact-+2 (exact->inexact 2)) -(define inexact--2 (exact->inexact -2)) -(define inexact-+1 (exact->inexact 1)) -(define inexact-+1/2 (exact->inexact (/ 1 2))) -(define inexact-0 (exact->inexact 0)) -(define (dump-bignum x) - (define radix 16384) - (define (integer->digits n) - (if (= n 0) - '() - (cons (remainder n radix) (integer->digits (quotient n radix))))) - (let ((l (integer->digits (abs x)))) - (ofile-long (+ (* (+ (length l) 1) 512) (* subtype-bignum 8))) - (if (< x 0) (ofile-word 0) (ofile-word 1)) - (for-each ofile-word l))) -(define (dump-procedure proc) - (let ((bbs (proc-obj-code proc))) - (set! entry-lbl-num (bbs-entry-lbl-num bbs)) - (set! label-counter (bbs-lbl-counter bbs)) - (set! var-descr-queue (queue-empty)) - (set! first-class-label-queue (queue-empty)) - (set! deferred-code-queue (queue-empty)) - (if *info-port* - (begin - (display " #[" *info-port*) - (if (proc-obj-primitive? proc) - (display "primitive " *info-port*) - (display "procedure " *info-port*)) - (display (proc-obj-name proc) *info-port*) - (display "]" *info-port*))) - (if (proc-obj-primitive? proc) - (ofile-prim-proc (proc-obj-name proc)) - (ofile-user-proc)) - (asm.begin!) - (let loop ((prev-bb #f) (prev-gvm-instr #f) (l (bbs->code-list bbs))) - (if (not (null? l)) - (let ((pres-bb (code-bb (car l))) - (pres-gvm-instr (code-gvm-instr (car l))) - (pres-slots-needed (code-slots-needed (car l))) - (next-gvm-instr - (if (null? (cdr l)) #f (code-gvm-instr (cadr l))))) - (if ofile-asm? (asm-comment (car l))) - (gen-gvm-instr - prev-gvm-instr - pres-gvm-instr - next-gvm-instr - pres-slots-needed) - (loop pres-bb pres-gvm-instr (cdr l))))) - (asm.end! - (if debug-info? - (vector (lst->vector (queue->list first-class-label-queue)) - (lst->vector (queue->list var-descr-queue))) - #f)) - (if *info-port* (newline *info-port*)) - (set! var-descr-queue '()) - (set! first-class-label-queue '()) - (set! deferred-code-queue '()) - (set! instr-source '()) - (set! entry-frame '()) - (set! exit-frame '()))) -(define label-counter '()) -(define entry-lbl-num '()) -(define var-descr-queue '()) -(define first-class-label-queue '()) -(define deferred-code-queue '()) -(define instr-source '()) -(define entry-frame '()) -(define exit-frame '()) -(define (defer-code! thunk) (queue-put! deferred-code-queue thunk)) -(define (gen-deferred-code!) - (let loop () - (if (not (queue-empty? deferred-code-queue)) - (let ((thunk (queue-get! deferred-code-queue))) (thunk) (loop))))) -(define (add-var-descr! descr) - (define (index x l) - (let loop ((l l) (i 0)) - (cond ((not (pair? l)) #f) - ((equal? (car l) x) i) - (else (loop (cdr l) (+ i 1)))))) - (let ((n (index descr (queue->list var-descr-queue)))) - (if n - n - (let ((m (length (queue->list var-descr-queue)))) - (queue-put! var-descr-queue descr) - m)))) -(define (add-first-class-label! source slots frame) - (let loop ((i 0) (l1 slots) (l2 '())) - (if (pair? l1) - (let ((var (car l1))) - (let ((x (frame-live? var frame))) - (if (and x (or (pair? x) (not (temp-var? x)))) - (let ((descr-index - (add-var-descr! - (if (pair? x) - (map (lambda (y) (add-var-descr! (var-name y))) x) - (var-name x))))) - (loop (+ i 1) - (cdr l1) - (cons (+ (* i 16384) descr-index) l2))) - (loop (+ i 1) (cdr l1) l2)))) - (let ((label-descr (lst->vector (cons 0 (cons source l2))))) - (queue-put! first-class-label-queue label-descr) - label-descr)))) -(define (gen-gvm-instr prev-gvm-instr gvm-instr next-gvm-instr sn) - (set! instr-source (comment-get (gvm-instr-comment gvm-instr) 'source)) - (set! exit-frame (gvm-instr-frame gvm-instr)) - (set! entry-frame (and prev-gvm-instr (gvm-instr-frame prev-gvm-instr))) - (case (gvm-instr-type gvm-instr) - ((label) - (set! entry-frame exit-frame) - (set! current-fs (frame-size exit-frame)) - (case (label-type gvm-instr) - ((simple) (gen-label-simple (label-lbl-num gvm-instr) sn)) - ((entry) - (gen-label-entry - (label-lbl-num gvm-instr) - (label-entry-nb-parms gvm-instr) - (label-entry-min gvm-instr) - (label-entry-rest? gvm-instr) - (label-entry-closed? gvm-instr) - sn)) - ((return) (gen-label-return (label-lbl-num gvm-instr) sn)) - ((task-entry) (gen-label-task-entry (label-lbl-num gvm-instr) sn)) - ((task-return) (gen-label-task-return (label-lbl-num gvm-instr) sn)) - (else (compiler-internal-error "gen-gvm-instr, unknown label type")))) - ((apply) - (gen-apply - (apply-prim gvm-instr) - (apply-opnds gvm-instr) - (apply-loc gvm-instr) - sn)) - ((copy) (gen-copy (copy-opnd gvm-instr) (copy-loc gvm-instr) sn)) - ((close) (gen-close (close-parms gvm-instr) sn)) - ((ifjump) - (gen-ifjump - (ifjump-test gvm-instr) - (ifjump-opnds gvm-instr) - (ifjump-true gvm-instr) - (ifjump-false gvm-instr) - (ifjump-poll? gvm-instr) - (if (and next-gvm-instr - (memq (label-type next-gvm-instr) '(simple task-entry))) - (label-lbl-num next-gvm-instr) - #f))) - ((jump) - (gen-jump - (jump-opnd gvm-instr) - (jump-nb-args gvm-instr) - (jump-poll? gvm-instr) - (if (and next-gvm-instr - (memq (label-type next-gvm-instr) '(simple task-entry))) - (label-lbl-num next-gvm-instr) - #f))) - (else - (compiler-internal-error - "gen-gvm-instr, unknown 'gvm-instr':" - gvm-instr)))) -(define (reg-in-opnd68 opnd) - (cond ((dreg? opnd) opnd) - ((areg? opnd) opnd) - ((ind? opnd) (ind-areg opnd)) - ((pinc? opnd) (pinc-areg opnd)) - ((pdec? opnd) (pdec-areg opnd)) - ((disp? opnd) (disp-areg opnd)) - ((inx? opnd) (inx-ireg opnd)) - (else #f))) -(define (temp-in-opnd68 opnd) - (let ((reg (reg-in-opnd68 opnd))) - (if reg - (cond ((identical-opnd68? reg dtemp1) reg) - ((identical-opnd68? reg atemp1) reg) - ((identical-opnd68? reg atemp2) reg) - (else #f)) - #f))) -(define (pick-atemp keep) - (if (and keep (identical-opnd68? keep atemp1)) atemp2 atemp1)) -(define return-reg '()) -(define max-nb-args 1024) -(define heap-allocation-fudge (* pointer-size (+ (* 2 max-nb-args) 1024))) -(define intr-flag 0) -(define ltq-tail 1) -(define ltq-head 2) -(define heap-lim 12) -(define closure-lim 17) -(define closure-ptr 18) -(define intr-flag-slot (make-disp* pstate-reg (* pointer-size intr-flag))) -(define ltq-tail-slot (make-disp* pstate-reg (* pointer-size ltq-tail))) -(define ltq-head-slot (make-disp* pstate-reg (* pointer-size ltq-head))) -(define heap-lim-slot (make-disp* pstate-reg (* pointer-size heap-lim))) -(define closure-lim-slot (make-disp* pstate-reg (* pointer-size closure-lim))) -(define closure-ptr-slot (make-disp* pstate-reg (* pointer-size closure-ptr))) -(define touch-trap 1) -(define non-proc-jump-trap 6) -(define rest-params-trap 7) -(define rest-params-closed-trap 8) -(define wrong-nb-arg1-trap 9) -(define wrong-nb-arg1-closed-trap 10) -(define wrong-nb-arg2-trap 11) -(define wrong-nb-arg2-closed-trap 12) -(define heap-alloc1-trap 13) -(define heap-alloc2-trap 14) -(define closure-alloc-trap 15) -(define intr-trap 24) -(define cache-line-length 16) -(define polling-intermittency '()) -(set! polling-intermittency 10) -(define (stat-clear!) (set! *stats* (cons 0 '()))) -(define (stat-dump!) (emit-stat (cdr *stats*))) -(define (stat-add! bin count) - (define (add! stats bin count) - (set-car! stats (+ (car stats) count)) - (if (not (null? bin)) - (let ((x (assoc (car bin) (cdr stats)))) - (if x - (add! (cdr x) (cdr bin) count) - (begin - (set-cdr! stats (cons (list (car bin) 0) (cdr stats))) - (add! (cdadr stats) (cdr bin) count)))))) - (add! *stats* bin count)) -(define (fetch-stat-add! gvm-opnd) (opnd-stat-add! 'fetch gvm-opnd)) -(define (store-stat-add! gvm-opnd) (opnd-stat-add! 'store gvm-opnd)) -(define (jump-stat-add! gvm-opnd) (opnd-stat-add! 'jump gvm-opnd)) -(define (opnd-stat-add! type opnd) - (cond ((reg? opnd) (stat-add! (list 'gvm-opnd 'reg type (reg-num opnd)) 1)) - ((stk? opnd) (stat-add! (list 'gvm-opnd 'stk type) 1)) - ((glo? opnd) (stat-add! (list 'gvm-opnd 'glo type (glo-name opnd)) 1)) - ((clo? opnd) - (stat-add! (list 'gvm-opnd 'clo type) 1) - (fetch-stat-add! (clo-base opnd))) - ((lbl? opnd) (stat-add! (list 'gvm-opnd 'lbl type) 1)) - ((obj? opnd) - (let ((val (obj-val opnd))) - (if (number? val) - (stat-add! (list 'gvm-opnd 'obj type val) 1) - (stat-add! (list 'gvm-opnd 'obj type (obj-type val)) 1)))) - (else - (compiler-internal-error "opnd-stat-add!, unknown 'opnd':" opnd)))) -(define (opnd-stat opnd) - (cond ((reg? opnd) 'reg) - ((stk? opnd) 'stk) - ((glo? opnd) 'glo) - ((clo? opnd) 'clo) - ((lbl? opnd) 'lbl) - ((obj? opnd) 'obj) - (else (compiler-internal-error "opnd-stat, unknown 'opnd':" opnd)))) -(define *stats* '()) -(define (move-opnd68-to-loc68 opnd loc) - (if (not (identical-opnd68? opnd loc)) - (if (imm? opnd) - (move-n-to-loc68 (imm-val opnd) loc) - (emit-move.l opnd loc)))) -(define (move-obj-to-loc68 obj loc) - (let ((n (obj-encoding obj))) - (if n (move-n-to-loc68 n loc) (emit-move.l (emit-const obj) loc)))) -(define (move-n-to-loc68 n loc) - (cond ((= n bits-null) (emit-move.l null-reg loc)) - ((= n bits-false) (emit-move.l false-reg loc)) - ((and (dreg? loc) (>= n -128) (<= n 127)) (emit-moveq n loc)) - ((and (areg? loc) (>= n -32768) (<= n 32767)) - (emit-move.w (make-imm n) loc)) - ((and (identical-opnd68? loc pdec-sp) (>= n -32768) (<= n 32767)) - (emit-pea* n)) - ((= n 0) (emit-clr.l loc)) - ((and (not (and (inx? loc) (= (inx-ireg loc) dtemp1))) - (>= n -128) - (<= n 127)) - (emit-moveq n dtemp1) - (emit-move.l dtemp1 loc)) - (else (emit-move.l (make-imm n) loc)))) -(define (add-n-to-loc68 n loc) - (if (not (= n 0)) - (cond ((and (>= n -8) (<= n 8)) - (if (> n 0) (emit-addq.l n loc) (emit-subq.l (- n) loc))) - ((and (areg? loc) (>= n -32768) (<= n 32767)) - (emit-lea (make-disp loc n) loc)) - ((and (not (identical-opnd68? loc dtemp1)) (>= n -128) (<= n 128)) - (emit-moveq (- (abs n)) dtemp1) - (if (> n 0) (emit-sub.l dtemp1 loc) (emit-add.l dtemp1 loc))) - (else (emit-add.l (make-imm n) loc))))) -(define (power-of-2 n) - (let loop ((i 0) (k 1)) - (cond ((= k n) i) ((> k n) #f) (else (loop (+ i 1) (* k 2)))))) -(define (mul-n-to-reg68 n reg) - (if (= n 0) - (emit-moveq 0 reg) - (let ((abs-n (abs n))) - (if (= abs-n 1) - (if (< n 0) (emit-neg.l reg)) - (let ((shift (power-of-2 abs-n))) - (if shift - (let ((m (min shift 32))) - (if (or (<= m 8) (identical-opnd68? reg dtemp1)) - (let loop ((i m)) - (if (> i 0) - (begin - (emit-asl.l (make-imm (min i 8)) reg) - (loop (- i 8))))) - (begin (emit-moveq m dtemp1) (emit-asl.l dtemp1 reg))) - (if (< n 0) (emit-neg.l reg))) - (emit-muls.l (make-imm n) reg))))))) -(define (div-n-to-reg68 n reg) - (let ((abs-n (abs n))) - (if (= abs-n 1) - (if (< n 0) (emit-neg.l reg)) - (let ((shift (power-of-2 abs-n))) - (if shift - (let ((m (min shift 32)) (lbl (new-lbl!))) - (emit-move.l reg reg) - (emit-bpl lbl) - (add-n-to-loc68 (* (- abs-n 1) 8) reg) - (emit-label lbl) - (if (or (<= m 8) (identical-opnd68? reg dtemp1)) - (let loop ((i m)) - (if (> i 0) - (begin - (emit-asr.l (make-imm (min i 8)) reg) - (loop (- i 8))))) - (begin (emit-moveq m dtemp1) (emit-asr.l dtemp1 reg))) - (if (< n 0) (emit-neg.l reg))) - (emit-divsl.l (make-imm n) reg reg)))))) -(define (cmp-n-to-opnd68 n opnd) - (cond ((= n bits-null) (emit-cmp.l opnd null-reg) #f) - ((= n bits-false) (emit-cmp.l opnd false-reg) #f) - ((or (pcr? opnd) (imm? opnd)) - (if (= n 0) - (begin (emit-move.l opnd dtemp1) #t) - (begin - (move-opnd68-to-loc68 opnd atemp1) - (if (and (>= n -32768) (<= n 32767)) - (emit-cmp.w (make-imm n) atemp1) - (emit-cmp.l (make-imm n) atemp1)) - #t))) - ((= n 0) (emit-move.l opnd dtemp1) #t) - ((and (>= n -128) (<= n 127) (not (identical-opnd68? opnd dtemp1))) - (emit-moveq n dtemp1) - (emit-cmp.l opnd dtemp1) - #f) - (else (emit-cmp.l (make-imm n) opnd) #t))) -(define current-fs '()) -(define (adjust-current-fs n) (set! current-fs (+ current-fs n))) -(define (new-lbl!) (label-counter)) -(define (needed? loc sn) (and loc (if (stk? loc) (<= (stk-num loc) sn) #t))) -(define (sn-opnd opnd sn) - (cond ((stk? opnd) (max (stk-num opnd) sn)) - ((clo? opnd) (sn-opnd (clo-base opnd) sn)) - (else sn))) -(define (sn-opnds opnds sn) - (if (null? opnds) sn (sn-opnd (car opnds) (sn-opnds (cdr opnds) sn)))) -(define (sn-opnd68 opnd sn) - (cond ((and (disp*? opnd) (identical-opnd68? (disp*-areg opnd) sp-reg)) - (max (disp*-offset opnd) sn)) - ((identical-opnd68? opnd pdec-sp) (max (+ current-fs 1) sn)) - ((identical-opnd68? opnd pinc-sp) (max current-fs sn)) - (else sn))) -(define (resize-frame n) - (let ((x (- n current-fs))) - (adjust-current-fs x) - (add-n-to-loc68 (* (- pointer-size) x) sp-reg))) -(define (shrink-frame n) - (cond ((< n current-fs) (resize-frame n)) - ((> n current-fs) - (compiler-internal-error "shrink-frame, can't increase frame size")))) -(define (make-top-of-frame n sn) - (if (and (< n current-fs) (>= n sn)) (resize-frame n))) -(define (make-top-of-frame-if-stk-opnd68 opnd sn) - (if (frame-base-rel? opnd) - (make-top-of-frame (frame-base-rel-slot opnd) sn))) -(define (make-top-of-frame-if-stk-opnds68 opnd1 opnd2 sn) - (if (frame-base-rel? opnd1) - (let ((slot1 (frame-base-rel-slot opnd1))) - (if (frame-base-rel? opnd2) - (make-top-of-frame (max (frame-base-rel-slot opnd2) slot1) sn) - (make-top-of-frame slot1 sn))) - (if (frame-base-rel? opnd2) - (make-top-of-frame (frame-base-rel-slot opnd2) sn)))) -(define (opnd68->true-opnd68 opnd sn) - (if (frame-base-rel? opnd) - (let ((slot (frame-base-rel-slot opnd))) - (cond ((> slot current-fs) (adjust-current-fs 1) pdec-sp) - ((and (= slot current-fs) (< sn current-fs)) - (adjust-current-fs -1) - pinc-sp) - (else (make-disp* sp-reg (* pointer-size (- current-fs slot)))))) - opnd)) -(define (move-opnd68-to-any-areg opnd keep sn) - (if (areg? opnd) - opnd - (let ((areg (pick-atemp keep))) - (make-top-of-frame-if-stk-opnd68 opnd sn) - (move-opnd68-to-loc68 (opnd68->true-opnd68 opnd sn) areg) - areg))) -(define (clo->opnd68 opnd keep sn) - (let ((base (clo-base opnd)) (offs (closed-var-offset (clo-index opnd)))) - (if (lbl? base) (make-pcr (lbl-num base) offs) (clo->loc68 opnd keep sn)))) -(define (clo->loc68 opnd keep sn) - (let ((base (clo-base opnd)) (offs (closed-var-offset (clo-index opnd)))) - (cond ((eq? base return-reg) (make-disp* (reg->reg68 base) offs)) - ((obj? base) - (let ((areg (pick-atemp keep))) - (move-obj-to-loc68 (obj-val base) areg) - (make-disp* areg offs))) - (else - (let ((areg (pick-atemp keep))) - (move-opnd-to-loc68 base areg sn) - (make-disp* areg offs)))))) -(define (reg->reg68 reg) (reg-num->reg68 (reg-num reg))) -(define (reg-num->reg68 num) - (if (= num 0) (make-areg gvm-reg0) (make-dreg (+ (- num 1) gvm-reg1)))) -(define (opnd->opnd68 opnd keep sn) - (cond ((lbl? opnd) - (let ((areg (pick-atemp keep))) - (emit-lea (make-pcr (lbl-num opnd) 0) areg) - areg)) - ((obj? opnd) - (let ((val (obj-val opnd))) - (if (proc-obj? val) - (let ((num (add-object val)) (areg (pick-atemp keep))) - (if num (emit-move-proc num areg) (emit-move-prim val areg)) - areg) - (let ((n (obj-encoding val))) - (if n (make-imm n) (emit-const val)))))) - ((clo? opnd) (clo->opnd68 opnd keep sn)) - (else (loc->loc68 opnd keep sn)))) -(define (loc->loc68 loc keep sn) - (cond ((reg? loc) (reg->reg68 loc)) - ((stk? loc) (make-frame-base-rel (stk-num loc))) - ((glo? loc) (make-glob (glo-name loc))) - ((clo? loc) (clo->loc68 loc keep sn)) - (else (compiler-internal-error "loc->loc68, unknown 'loc':" loc)))) -(define (move-opnd68-to-loc opnd loc sn) - (cond ((reg? loc) - (make-top-of-frame-if-stk-opnd68 opnd sn) - (move-opnd68-to-loc68 (opnd68->true-opnd68 opnd sn) (reg->reg68 loc))) - ((stk? loc) - (let* ((loc-slot (stk-num loc)) - (sn-after-opnd1 (if (< loc-slot sn) sn (- loc-slot 1)))) - (if (> current-fs loc-slot) - (make-top-of-frame - (if (frame-base-rel? opnd) - (let ((opnd-slot (frame-base-rel-slot opnd))) - (if (>= opnd-slot (- loc-slot 1)) opnd-slot loc-slot)) - loc-slot) - sn-after-opnd1)) - (let* ((opnd1 (opnd68->true-opnd68 opnd sn-after-opnd1)) - (opnd2 (opnd68->true-opnd68 - (make-frame-base-rel loc-slot) - sn))) - (move-opnd68-to-loc68 opnd1 opnd2)))) - ((glo? loc) - (make-top-of-frame-if-stk-opnd68 opnd sn) - (move-opnd68-to-loc68 - (opnd68->true-opnd68 opnd sn) - (make-glob (glo-name loc)))) - ((clo? loc) - (let ((clo (clo->loc68 - loc - (temp-in-opnd68 opnd) - (sn-opnd68 opnd sn)))) - (make-top-of-frame-if-stk-opnd68 opnd sn) - (move-opnd68-to-loc68 (opnd68->true-opnd68 opnd sn) clo))) - (else - (compiler-internal-error "move-opnd68-to-loc, unknown 'loc':" loc)))) -(define (move-opnd-to-loc68 opnd loc68 sn) - (if (and (lbl? opnd) (areg? loc68)) - (emit-lea (make-pcr (lbl-num opnd) 0) loc68) - (let* ((sn-after-opnd68 (sn-opnd68 loc68 sn)) - (opnd68 (opnd->opnd68 - opnd - (temp-in-opnd68 loc68) - sn-after-opnd68))) - (make-top-of-frame-if-stk-opnds68 opnd68 loc68 sn) - (let* ((opnd68* (opnd68->true-opnd68 opnd68 sn-after-opnd68)) - (loc68* (opnd68->true-opnd68 loc68 sn))) - (move-opnd68-to-loc68 opnd68* loc68*))))) -(define (copy-opnd-to-loc opnd loc sn) - (if (and (lbl? opnd) (eq? loc return-reg)) - (emit-lea (make-pcr (lbl-num opnd) 0) (reg->reg68 loc)) - (move-opnd68-to-loc (opnd->opnd68 opnd #f (sn-opnd loc sn)) loc sn))) -(define (touch-reg68-to-reg68 src dst) - (define (trap-to-touch-handler dreg lbl) - (if ofile-stats? - (emit-stat - '((touch 0 - (determined-placeholder -1) - (undetermined-placeholder 1))))) - (gen-trap - instr-source - entry-frame - #t - dreg - (+ touch-trap (dreg-num dreg)) - lbl)) - (define (touch-dreg-to-reg src dst) - (let ((lbl1 (new-lbl!))) - (emit-btst src placeholder-reg) - (emit-bne lbl1) - (if ofile-stats? - (emit-stat - '((touch 0 (non-placeholder -1) (determined-placeholder 1))))) - (trap-to-touch-handler src lbl1) - (move-opnd68-to-loc68 src dst))) - (define (touch-areg-to-dreg src dst) - (let ((lbl1 (new-lbl!))) - (emit-move.l src dst) - (emit-btst dst placeholder-reg) - (emit-bne lbl1) - (if ofile-stats? - (emit-stat - '((touch 0 (non-placeholder -1) (determined-placeholder 1))))) - (trap-to-touch-handler dst lbl1))) - (if ofile-stats? (emit-stat '((touch 1 (non-placeholder 1))))) - (cond ((dreg? src) (touch-dreg-to-reg src dst)) - ((dreg? dst) (touch-areg-to-dreg src dst)) - (else (emit-move.l src dtemp1) (touch-dreg-to-reg dtemp1 dst)))) -(define (touch-opnd-to-any-reg68 opnd sn) - (if (reg? opnd) - (let ((reg (reg->reg68 opnd))) (touch-reg68-to-reg68 reg reg) reg) - (let ((opnd68 (opnd->opnd68 opnd #f sn))) - (make-top-of-frame-if-stk-opnd68 opnd68 sn) - (move-opnd68-to-loc68 (opnd68->true-opnd68 opnd68 sn) dtemp1) - (touch-reg68-to-reg68 dtemp1 dtemp1) - dtemp1))) -(define (touch-opnd-to-loc opnd loc sn) - (if (reg? opnd) - (let ((reg68 (reg->reg68 opnd))) - (if (reg? loc) - (touch-reg68-to-reg68 reg68 (reg->reg68 loc)) - (begin - (touch-reg68-to-reg68 reg68 reg68) - (move-opnd68-to-loc reg68 loc sn)))) - (if (reg? loc) - (let ((reg68 (reg->reg68 loc))) - (move-opnd-to-loc68 opnd reg68 sn) - (touch-reg68-to-reg68 reg68 reg68)) - (let ((reg68 (touch-opnd-to-any-reg68 opnd sn))) - (move-opnd68-to-loc reg68 loc sn))))) -(define (gen-trap source frame save-live? not-save-reg num lbl) - (define (adjust-slots l n) - (cond ((= n 0) (append l '())) - ((< n 0) (adjust-slots (cdr l) (+ n 1))) - (else (adjust-slots (cons empty-var l) (- n 1))))) - (define (set-slot! slots i x) - (let loop ((l slots) (n (- (length slots) i))) - (if (> n 0) (loop (cdr l) (- n 1)) (set-car! l x)))) - (let ((ret-slot (frame-first-empty-slot frame))) - (let loop1 ((save1 '()) (save2 #f) (regs (frame-regs frame)) (i 0)) - (if (pair? regs) - (let ((var (car regs))) - (if (eq? var ret-var) - (let ((x (cons (reg->reg68 (make-reg i)) var))) - (if (> ret-slot current-fs) - (loop1 (cons x save1) save2 (cdr regs) (+ i 1)) - (loop1 save1 x (cdr regs) (+ i 1)))) - (if (and save-live? - (frame-live? var frame) - (not (eqv? not-save-reg (reg->reg68 (make-reg i))))) - (loop1 (cons (cons (reg->reg68 (make-reg i)) var) save1) - save2 - (cdr regs) - (+ i 1)) - (loop1 save1 save2 (cdr regs) (+ i 1))))) - (let ((order (sort-list save1 (lambda (x y) (< (car x) (car y)))))) - (let ((slots (append (map cdr order) - (adjust-slots - (frame-slots frame) - (- current-fs (frame-size frame))))) - (reg-list (map car order)) - (nb-regs (length order))) - (define (trap) - (emit-trap2 num '()) - (gen-label-return* - (new-lbl!) - (add-first-class-label! source slots frame) - slots - 0)) - (if save2 - (begin - (emit-move.l - (car save2) - (make-disp* - sp-reg - (* pointer-size (- current-fs ret-slot)))) - (set-slot! slots ret-slot (cdr save2)))) - (if (> (length order) 2) - (begin - (emit-movem.l reg-list pdec-sp) - (trap) - (emit-movem.l pinc-sp reg-list)) - (let loop2 ((l (reverse reg-list))) - (if (pair? l) - (let ((reg (car l))) - (emit-move.l reg pdec-sp) - (loop2 (cdr l)) - (emit-move.l pinc-sp reg)) - (trap)))) - (if save2 - (emit-move.l - (make-disp* sp-reg (* pointer-size (- current-fs ret-slot))) - (car save2))) - (emit-label lbl))))))) -(define (gen-label-simple lbl sn) - (if ofile-stats? - (begin (stat-clear!) (stat-add! '(gvm-instr label simple) 1))) - (set! pointers-allocated 0) - (emit-label lbl)) -(define (gen-label-entry lbl nb-parms min rest? closed? sn) - (if ofile-stats? - (begin - (stat-clear!) - (stat-add! - (list 'gvm-instr - 'label - 'entry - nb-parms - min - (if rest? 'rest 'not-rest) - (if closed? 'closed 'not-closed)) - 1))) - (set! pointers-allocated 0) - (let ((label-descr (add-first-class-label! instr-source '() exit-frame))) - (if (= lbl entry-lbl-num) - (emit-label lbl) - (emit-label-subproc lbl entry-lbl-num label-descr))) - (let* ((nb-parms* (if rest? (- nb-parms 1) nb-parms)) - (dispatch-lbls (make-vector (+ (- nb-parms min) 1))) - (optional-lbls (make-vector (+ (- nb-parms min) 1)))) - (let loop ((i min)) - (if (<= i nb-parms) - (let ((lbl (new-lbl!))) - (vector-set! optional-lbls (- nb-parms i) lbl) - (vector-set! - dispatch-lbls - (- nb-parms i) - (if (or (>= i nb-parms) (<= nb-parms nb-arg-regs)) - lbl - (new-lbl!))) - (loop (+ i 1))))) - (if closed? - (let ((closure-reg (reg-num->reg68 (+ nb-arg-regs 1)))) - (emit-move.l pinc-sp closure-reg) - (emit-subq.l 6 closure-reg) - (if (or (and (<= min 1) (<= 1 nb-parms*)) - (and (<= min 2) (<= 2 nb-parms*))) - (emit-move.w dtemp1 dtemp1)))) - (if (and (<= min 2) (<= 2 nb-parms*)) - (emit-beq (vector-ref dispatch-lbls (- nb-parms 2)))) - (if (and (<= min 1) (<= 1 nb-parms*)) - (emit-bmi (vector-ref dispatch-lbls (- nb-parms 1)))) - (let loop ((i min)) - (if (<= i nb-parms*) - (begin - (if (not (or (= i 1) (= i 2))) - (begin - (emit-cmp.w (make-imm (encode-arg-count i)) arg-count-reg) - (emit-beq (vector-ref dispatch-lbls (- nb-parms i))))) - (loop (+ i 1))))) - (cond (rest? - (emit-trap1 - (if closed? rest-params-closed-trap rest-params-trap) - (list min nb-parms*)) - (if (not closed?) (emit-lbl-ptr lbl)) - (set! pointers-allocated 1) - (gen-guarantee-fudge) - (emit-bra (vector-ref optional-lbls 0))) - ((= min nb-parms*) - (emit-trap1 - (if closed? wrong-nb-arg1-closed-trap wrong-nb-arg1-trap) - (list nb-parms*)) - (if (not closed?) (emit-lbl-ptr lbl))) - (else - (emit-trap1 - (if closed? wrong-nb-arg2-closed-trap wrong-nb-arg2-trap) - (list min nb-parms*)) - (if (not closed?) (emit-lbl-ptr lbl)))) - (if (> nb-parms nb-arg-regs) - (let loop1 ((i (- nb-parms 1))) - (if (>= i min) - (let ((nb-stacked (if (<= i nb-arg-regs) 0 (- i nb-arg-regs)))) - (emit-label (vector-ref dispatch-lbls (- nb-parms i))) - (let loop2 ((j 1)) - (if (and (<= j nb-arg-regs) - (<= j i) - (<= j (- (- nb-parms nb-arg-regs) nb-stacked))) - (begin - (emit-move.l (reg-num->reg68 j) pdec-sp) - (loop2 (+ j 1))) - (let loop3 ((k j)) - (if (and (<= k nb-arg-regs) (<= k i)) - (begin - (emit-move.l - (reg-num->reg68 k) - (reg-num->reg68 (+ (- k j) 1))) - (loop3 (+ k 1))))))) - (if (> i min) - (emit-bra (vector-ref optional-lbls (- nb-parms i)))) - (loop1 (- i 1)))))) - (let loop ((i min)) - (if (<= i nb-parms) - (let ((val (if (= i nb-parms*) bits-null bits-unass))) - (emit-label (vector-ref optional-lbls (- nb-parms i))) - (cond ((> (- nb-parms i) nb-arg-regs) - (move-n-to-loc68 val pdec-sp)) - ((< i nb-parms) - (move-n-to-loc68 - val - (reg-num->reg68 (parm->reg-num (+ i 1) nb-parms))))) - (loop (+ i 1))))))) -(define (encode-arg-count n) (cond ((= n 1) -1) ((= n 2) 0) (else (+ n 1)))) -(define (parm->reg-num i nb-parms) - (if (<= nb-parms nb-arg-regs) i (+ i (- nb-arg-regs nb-parms)))) -(define (no-arg-check-entry-offset proc nb-args) - (let ((x (proc-obj-call-pat proc))) - (if (and (pair? x) (null? (cdr x))) - (let ((arg-count (car x))) - (if (= arg-count nb-args) - (if (or (= arg-count 1) (= arg-count 2)) 10 14) - 0)) - 0))) -(define (gen-label-return lbl sn) - (if ofile-stats? - (begin (stat-clear!) (stat-add! '(gvm-instr label return) 1))) - (set! pointers-allocated 0) - (let ((slots (frame-slots exit-frame))) - (gen-label-return* - lbl - (add-first-class-label! instr-source slots exit-frame) - slots - 0))) -(define (gen-label-return* lbl label-descr slots extra) - (let ((i (pos-in-list ret-var slots))) - (if i - (let* ((fs (length slots)) (link (- fs i))) - (emit-label-return lbl entry-lbl-num (+ fs extra) link label-descr)) - (compiler-internal-error - "gen-label-return*, no return address in frame")))) -(define (gen-label-task-entry lbl sn) - (if ofile-stats? - (begin (stat-clear!) (stat-add! '(gvm-instr label task-entry) 1))) - (set! pointers-allocated 0) - (emit-label lbl) - (if (= current-fs 0) - (begin - (emit-move.l (reg->reg68 return-reg) pdec-sp) - (emit-move.l sp-reg (make-pinc ltq-tail-reg))) - (begin - (emit-move.l sp-reg atemp1) - (emit-move.l (make-pinc atemp1) pdec-sp) - (let loop ((i (- current-fs 1))) - (if (> i 0) - (begin - (emit-move.l (make-pinc atemp1) (make-disp atemp1 -8)) - (loop (- i 1))))) - (emit-move.l (reg->reg68 return-reg) (make-pdec atemp1)) - (emit-move.l atemp1 (make-pinc ltq-tail-reg)))) - (emit-move.l ltq-tail-reg ltq-tail-slot)) -(define (gen-label-task-return lbl sn) - (if ofile-stats? - (begin (stat-clear!) (stat-add! '(gvm-instr label task-return) 1))) - (set! pointers-allocated 0) - (let ((slots (frame-slots exit-frame))) - (set! current-fs (+ current-fs 1)) - (let ((dummy-lbl (new-lbl!)) (skip-lbl (new-lbl!))) - (gen-label-return* - dummy-lbl - (add-first-class-label! instr-source slots exit-frame) - slots - 1) - (emit-bra skip-lbl) - (gen-label-task-return* - lbl - (add-first-class-label! instr-source slots exit-frame) - slots - 1) - (emit-subq.l pointer-size ltq-tail-reg) - (emit-label skip-lbl)))) -(define (gen-label-task-return* lbl label-descr slots extra) - (let ((i (pos-in-list ret-var slots))) - (if i - (let* ((fs (length slots)) (link (- fs i))) - (emit-label-task-return - lbl - entry-lbl-num - (+ fs extra) - link - label-descr)) - (compiler-internal-error - "gen-label-task-return*, no return address in frame")))) -(define (gen-apply prim opnds loc sn) - (if ofile-stats? - (begin - (stat-add! - (list 'gvm-instr - 'apply - (string->canonical-symbol (proc-obj-name prim)) - (map opnd-stat opnds) - (if loc (opnd-stat loc) #f)) - 1) - (for-each fetch-stat-add! opnds) - (if loc (store-stat-add! loc)))) - (let ((x (proc-obj-inlinable prim))) - (if (not x) - (compiler-internal-error "gen-APPLY, unknown 'prim':" prim) - (if (or (needed? loc sn) (car x)) ((cdr x) opnds loc sn))))) -(define (define-apply name side-effects? proc) - (let ((prim (get-prim-info name))) - (proc-obj-inlinable-set! prim (cons side-effects? proc)))) -(define (gen-copy opnd loc sn) - (if ofile-stats? - (begin - (stat-add! (list 'gvm-instr 'copy (opnd-stat opnd) (opnd-stat loc)) 1) - (fetch-stat-add! opnd) - (store-stat-add! loc))) - (if (needed? loc sn) (copy-opnd-to-loc opnd loc sn))) -(define (gen-close parms sn) - (define (size->bytes size) - (* (quotient - (+ (* (+ size 2) pointer-size) (- cache-line-length 1)) - cache-line-length) - cache-line-length)) - (define (parms->bytes parms) - (if (null? parms) - 0 - (+ (size->bytes (length (closure-parms-opnds (car parms)))) - (parms->bytes (cdr parms))))) - (if ofile-stats? - (begin - (for-each - (lambda (x) - (stat-add! - (list 'gvm-instr - 'close - (opnd-stat (closure-parms-loc x)) - (map opnd-stat (closure-parms-opnds x))) - 1) - (store-stat-add! (closure-parms-loc x)) - (fetch-stat-add! (make-lbl (closure-parms-lbl x))) - (for-each fetch-stat-add! (closure-parms-opnds x))) - parms))) - (let ((total-space-needed (parms->bytes parms)) (lbl1 (new-lbl!))) - (emit-move.l closure-ptr-slot atemp2) - (move-n-to-loc68 total-space-needed dtemp1) - (emit-sub.l dtemp1 atemp2) - (emit-cmp.l closure-lim-slot atemp2) - (emit-bcc lbl1) - (gen-trap instr-source entry-frame #f #f closure-alloc-trap lbl1) - (emit-move.l atemp2 closure-ptr-slot) - (let* ((opnds* (apply append (map closure-parms-opnds parms))) - (sn* (sn-opnds opnds* sn))) - (let loop1 ((parms parms)) - (let ((loc (closure-parms-loc (car parms))) - (size (length (closure-parms-opnds (car parms)))) - (rest (cdr parms))) - (if (= size 1) - (emit-addq.l type-procedure atemp2) - (emit-move.w - (make-imm (+ 32768 (* (+ size 1) 4))) - (make-pinc atemp2))) - (move-opnd68-to-loc - atemp2 - loc - (sn-opnds (map closure-parms-loc rest) sn*)) - (if (null? rest) - (add-n-to-loc68 - (+ (- (size->bytes size) total-space-needed) 2) - atemp2) - (begin - (add-n-to-loc68 (- (size->bytes size) type-procedure) atemp2) - (loop1 rest))))) - (let loop2 ((parms parms)) - (let* ((opnds (closure-parms-opnds (car parms))) - (lbl (closure-parms-lbl (car parms))) - (size (length opnds)) - (rest (cdr parms))) - (emit-lea (make-pcr lbl 0) atemp1) - (emit-move.l atemp1 (make-pinc atemp2)) - (let loop3 ((opnds opnds)) - (if (not (null? opnds)) - (let ((sn** (sn-opnds - (apply append (map closure-parms-opnds rest)) - sn))) - (move-opnd-to-loc68 - (car opnds) - (make-pinc atemp2) - (sn-opnds (cdr opnds) sn**)) - (loop3 (cdr opnds))))) - (if (not (null? rest)) - (begin - (add-n-to-loc68 - (- (size->bytes size) (* (+ size 1) pointer-size)) - atemp2) - (loop2 rest)))))))) -(define (gen-ifjump test opnds true-lbl false-lbl poll? next-lbl) - (if ofile-stats? - (begin - (stat-add! - (list 'gvm-instr - 'ifjump - (string->canonical-symbol (proc-obj-name test)) - (map opnd-stat opnds) - (if poll? 'poll 'not-poll)) - 1) - (for-each fetch-stat-add! opnds) - (stat-dump!))) - (let ((proc (proc-obj-test test))) - (if proc - (gen-ifjump* proc opnds true-lbl false-lbl poll? next-lbl) - (compiler-internal-error "gen-IFJUMP, unknown 'test':" test)))) -(define (gen-ifjump* proc opnds true-lbl false-lbl poll? next-lbl) - (let ((fs (frame-size exit-frame))) - (define (double-branch) - (proc #t opnds false-lbl fs) - (if ofile-stats? - (emit-stat - '((gvm-instr.ifjump.fall-through 1) - (gvm-instr.ifjump.double-branch 1)))) - (emit-bra true-lbl) - (gen-deferred-code!)) - (gen-guarantee-fudge) - (if poll? (gen-poll)) - (if next-lbl - (cond ((= true-lbl next-lbl) - (proc #t opnds false-lbl fs) - (if ofile-stats? - (emit-stat '((gvm-instr.ifjump.fall-through 1))))) - ((= false-lbl next-lbl) - (proc #f opnds true-lbl fs) - (if ofile-stats? - (emit-stat '((gvm-instr.ifjump.fall-through 1))))) - (else (double-branch))) - (double-branch)))) -(define (define-ifjump name proc) - (define-apply - name - #f - (lambda (opnds loc sn) - (let ((true-lbl (new-lbl!)) - (cont-lbl (new-lbl!)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1))) - (proc #f opnds true-lbl current-fs) - (move-n-to-loc68 bits-false reg68) - (emit-bra cont-lbl) - (emit-label true-lbl) - (move-n-to-loc68 bits-true reg68) - (emit-label cont-lbl) - (move-opnd68-to-loc reg68 loc sn)))) - (proc-obj-test-set! (get-prim-info name) proc)) -(define (gen-jump opnd nb-args poll? next-lbl) - (let ((fs (frame-size exit-frame))) - (if ofile-stats? - (begin - (stat-add! - (list 'gvm-instr - 'jump - (opnd-stat opnd) - nb-args - (if poll? 'poll 'not-poll)) - 1) - (jump-stat-add! opnd) - (if (and (lbl? opnd) next-lbl (= next-lbl (lbl-num opnd))) - (stat-add! '(gvm-instr.jump.fall-through) 1)) - (stat-dump!))) - (gen-guarantee-fudge) - (cond ((glo? opnd) - (if poll? (gen-poll)) - (setup-jump fs nb-args) - (emit-jmp-glob (make-glob (glo-name opnd))) - (gen-deferred-code!)) - ((and (stk? opnd) (= (stk-num opnd) (+ fs 1)) (not nb-args)) - (if poll? (gen-poll)) - (setup-jump (+ fs 1) nb-args) - (emit-rts) - (gen-deferred-code!)) - ((lbl? opnd) - (if (and poll? - (= fs current-fs) - (not nb-args) - (not (and next-lbl (= next-lbl (lbl-num opnd))))) - (gen-poll-branch (lbl-num opnd)) - (begin - (if poll? (gen-poll)) - (setup-jump fs nb-args) - (if (not (and next-lbl (= next-lbl (lbl-num opnd)))) - (emit-bra (lbl-num opnd)))))) - ((obj? opnd) - (if poll? (gen-poll)) - (let ((val (obj-val opnd))) - (if (proc-obj? val) - (let ((num (add-object val)) - (offset (no-arg-check-entry-offset val nb-args))) - (setup-jump fs (if (<= offset 0) nb-args #f)) - (if num - (emit-jmp-proc num offset) - (emit-jmp-prim val offset)) - (gen-deferred-code!)) - (gen-jump* (opnd->opnd68 opnd #f fs) fs nb-args)))) - (else - (if poll? (gen-poll)) - (gen-jump* (opnd->opnd68 opnd #f fs) fs nb-args))))) -(define (gen-jump* opnd fs nb-args) - (if nb-args - (let ((lbl (new-lbl!))) - (make-top-of-frame-if-stk-opnd68 opnd fs) - (move-opnd68-to-loc68 (opnd68->true-opnd68 opnd fs) atemp1) - (shrink-frame fs) - (emit-move.l atemp1 dtemp1) - (emit-addq.w (modulo (- type-pair type-procedure) 8) dtemp1) - (emit-btst dtemp1 pair-reg) - (emit-beq lbl) - (move-n-to-loc68 (encode-arg-count nb-args) arg-count-reg) - (emit-trap3 non-proc-jump-trap) - (emit-label lbl) - (move-n-to-loc68 (encode-arg-count nb-args) arg-count-reg) - (emit-jmp (make-ind atemp1))) - (let ((areg (move-opnd68-to-any-areg opnd #f fs))) - (setup-jump fs nb-args) - (emit-jmp (make-ind areg)))) - (gen-deferred-code!)) -(define (setup-jump fs nb-args) - (shrink-frame fs) - (if nb-args (move-n-to-loc68 (encode-arg-count nb-args) arg-count-reg))) -(define (gen-poll) - (let ((lbl (new-lbl!))) - (emit-dbra poll-timer-reg lbl) - (emit-moveq (- polling-intermittency 1) poll-timer-reg) - (emit-cmp.l intr-flag-slot sp-reg) - (emit-bcc lbl) - (gen-trap instr-source entry-frame #f #f intr-trap lbl))) -(define (gen-poll-branch lbl) - (emit-dbra poll-timer-reg lbl) - (emit-moveq (- polling-intermittency 1) poll-timer-reg) - (emit-cmp.l intr-flag-slot sp-reg) - (emit-bcc lbl) - (gen-trap instr-source entry-frame #f #f intr-trap (new-lbl!)) - (emit-bra lbl)) -(define (make-gen-slot-ref slot type) - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) (opnd (car opnds))) - (move-opnd-to-loc68 opnd atemp1 sn-loc) - (move-opnd68-to-loc - (make-disp* atemp1 (- (* slot pointer-size) type)) - loc - sn)))) -(define (make-gen-slot-set! slot type) - (lambda (opnds loc sn) - (let ((sn-loc (if loc (sn-opnd loc sn) sn))) - (let* ((first-opnd (car opnds)) - (second-opnd (cadr opnds)) - (sn-second-opnd (sn-opnd second-opnd sn-loc))) - (move-opnd-to-loc68 first-opnd atemp1 sn-second-opnd) - (move-opnd-to-loc68 - second-opnd - (make-disp* atemp1 (- (* slot pointer-size) type)) - sn-loc) - (if loc - (if (not (eq? first-opnd loc)) - (move-opnd68-to-loc atemp1 loc sn))))))) -(define (gen-cons opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (let ((first-opnd (car opnds)) (second-opnd (cadr opnds))) - (gen-guarantee-space 2) - (if (contains-opnd? loc second-opnd) - (let ((sn-second-opnd (sn-opnd second-opnd sn-loc))) - (move-opnd-to-loc68 first-opnd (make-pdec heap-reg) sn-second-opnd) - (move-opnd68-to-loc68 heap-reg atemp2) - (move-opnd-to-loc68 second-opnd (make-pdec heap-reg) sn-loc) - (move-opnd68-to-loc atemp2 loc sn)) - (let* ((sn-second-opnd (sn-opnd second-opnd sn)) - (sn-loc (sn-opnd loc sn-second-opnd))) - (move-opnd-to-loc68 first-opnd (make-pdec heap-reg) sn-loc) - (move-opnd68-to-loc heap-reg loc sn-second-opnd) - (move-opnd-to-loc68 second-opnd (make-pdec heap-reg) sn)))))) -(define (make-gen-apply-c...r pattern) - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) (opnd (car opnds))) - (move-opnd-to-loc68 opnd atemp1 sn-loc) - (let loop ((pattern pattern)) - (if (<= pattern 3) - (if (= pattern 3) - (move-opnd68-to-loc (make-pdec atemp1) loc sn) - (move-opnd68-to-loc (make-ind atemp1) loc sn)) - (begin - (if (odd? pattern) - (emit-move.l (make-pdec atemp1) atemp1) - (emit-move.l (make-ind atemp1) atemp1)) - (loop (quotient pattern 2)))))))) -(define (gen-set-car! opnds loc sn) - (let ((sn-loc (if loc (sn-opnd loc sn) sn))) - (let* ((first-opnd (car opnds)) - (second-opnd (cadr opnds)) - (sn-second-opnd (sn-opnd second-opnd sn-loc))) - (move-opnd-to-loc68 first-opnd atemp1 sn-second-opnd) - (move-opnd-to-loc68 second-opnd (make-ind atemp1) sn-loc) - (if (and loc (not (eq? first-opnd loc))) - (move-opnd68-to-loc atemp1 loc sn))))) -(define (gen-set-cdr! opnds loc sn) - (let ((sn-loc (if loc (sn-opnd loc sn) sn))) - (let* ((first-opnd (car opnds)) - (second-opnd (cadr opnds)) - (sn-second-opnd (sn-opnd second-opnd sn-loc))) - (move-opnd-to-loc68 first-opnd atemp1 sn-second-opnd) - (if (and loc (not (eq? first-opnd loc))) - (move-opnd-to-loc68 - second-opnd - (make-disp atemp1 (- pointer-size)) - sn-loc) - (move-opnd-to-loc68 second-opnd (make-pdec atemp1) sn-loc)) - (if (and loc (not (eq? first-opnd loc))) - (move-opnd68-to-loc atemp1 loc sn))))) -(define (commut-oper gen opnds loc sn self? accum-self accum-other) - (if (null? opnds) - (gen (reverse accum-self) (reverse accum-other) loc sn self?) - (let ((opnd (car opnds)) (rest (cdr opnds))) - (cond ((and (not self?) (eq? opnd loc)) - (commut-oper gen rest loc sn #t accum-self accum-other)) - ((contains-opnd? loc opnd) - (commut-oper - gen - rest - loc - sn - self? - (cons opnd accum-self) - accum-other)) - (else - (commut-oper - gen - rest - loc - sn - self? - accum-self - (cons opnd accum-other))))))) -(define (gen-add-in-place opnds loc68 sn) - (if (not (null? opnds)) - (let* ((first-opnd (car opnds)) - (other-opnds (cdr opnds)) - (sn-other-opnds (sn-opnds other-opnds sn)) - (sn-first-opnd (sn-opnd first-opnd sn-other-opnds)) - (opnd68 (opnd->opnd68 - first-opnd - (temp-in-opnd68 loc68) - (sn-opnd68 loc68 sn)))) - (make-top-of-frame-if-stk-opnds68 opnd68 loc68 sn-other-opnds) - (if (imm? opnd68) - (add-n-to-loc68 - (imm-val opnd68) - (opnd68->true-opnd68 loc68 sn-other-opnds)) - (let ((opnd68* (opnd68->true-opnd68 opnd68 sn-other-opnds))) - (if (or (dreg? opnd68) (reg68? loc68)) - (emit-add.l - opnd68* - (opnd68->true-opnd68 loc68 sn-other-opnds)) - (begin - (move-opnd68-to-loc68 opnd68* dtemp1) - (emit-add.l - dtemp1 - (opnd68->true-opnd68 loc68 sn-other-opnds)))))) - (gen-add-in-place other-opnds loc68 sn)))) -(define (gen-add self-opnds other-opnds loc sn self?) - (let* ((opnds (append self-opnds other-opnds)) - (first-opnd (car opnds)) - (other-opnds (cdr opnds)) - (sn-other-opnds (sn-opnds other-opnds sn)) - (sn-first-opnd (sn-opnd first-opnd sn-other-opnds))) - (if (<= (length self-opnds) 1) - (let ((loc68 (loc->loc68 loc #f sn-first-opnd))) - (if self? - (gen-add-in-place opnds loc68 sn) - (begin - (move-opnd-to-loc68 first-opnd loc68 sn-other-opnds) - (gen-add-in-place other-opnds loc68 sn)))) - (begin - (move-opnd-to-loc68 first-opnd dtemp1 (sn-opnd loc sn-other-opnds)) - (gen-add-in-place other-opnds dtemp1 (sn-opnd loc sn)) - (if self? - (let ((loc68 (loc->loc68 loc dtemp1 sn))) - (make-top-of-frame-if-stk-opnd68 loc68 sn) - (emit-add.l dtemp1 (opnd68->true-opnd68 loc68 sn))) - (move-opnd68-to-loc dtemp1 loc sn)))))) -(define (gen-sub-in-place opnds loc68 sn) - (if (not (null? opnds)) - (let* ((first-opnd (car opnds)) - (other-opnds (cdr opnds)) - (sn-other-opnds (sn-opnds other-opnds sn)) - (sn-first-opnd (sn-opnd first-opnd sn-other-opnds)) - (opnd68 (opnd->opnd68 - first-opnd - (temp-in-opnd68 loc68) - (sn-opnd68 loc68 sn)))) - (make-top-of-frame-if-stk-opnds68 opnd68 loc68 sn-other-opnds) - (if (imm? opnd68) - (add-n-to-loc68 - (- (imm-val opnd68)) - (opnd68->true-opnd68 loc68 sn-other-opnds)) - (let ((opnd68* (opnd68->true-opnd68 opnd68 sn-other-opnds))) - (if (or (dreg? opnd68) (reg68? loc68)) - (emit-sub.l - opnd68* - (opnd68->true-opnd68 loc68 sn-other-opnds)) - (begin - (move-opnd68-to-loc68 opnd68* dtemp1) - (emit-sub.l - dtemp1 - (opnd68->true-opnd68 loc68 sn-other-opnds)))))) - (gen-sub-in-place other-opnds loc68 sn)))) -(define (gen-sub first-opnd other-opnds loc sn self-opnds?) - (if (null? other-opnds) - (if (and (or (reg? loc) (stk? loc)) (not (eq? loc return-reg))) - (begin - (copy-opnd-to-loc first-opnd loc (sn-opnd loc sn)) - (let ((loc68 (loc->loc68 loc #f sn))) - (make-top-of-frame-if-stk-opnd68 loc68 sn) - (emit-neg.l (opnd68->true-opnd68 loc68 sn)))) - (begin - (move-opnd-to-loc68 first-opnd dtemp1 (sn-opnd loc sn)) - (emit-neg.l dtemp1) - (move-opnd68-to-loc dtemp1 loc sn))) - (let* ((sn-other-opnds (sn-opnds other-opnds sn)) - (sn-first-opnd (sn-opnd first-opnd sn-other-opnds))) - (if (and (not self-opnds?) (or (reg? loc) (stk? loc))) - (let ((loc68 (loc->loc68 loc #f sn-first-opnd))) - (if (not (eq? first-opnd loc)) - (move-opnd-to-loc68 first-opnd loc68 sn-other-opnds)) - (gen-sub-in-place other-opnds loc68 sn)) - (begin - (move-opnd-to-loc68 - first-opnd - dtemp1 - (sn-opnd loc sn-other-opnds)) - (gen-sub-in-place other-opnds dtemp1 (sn-opnd loc sn)) - (move-opnd68-to-loc dtemp1 loc sn)))))) -(define (gen-mul-in-place opnds reg68 sn) - (if (not (null? opnds)) - (let* ((first-opnd (car opnds)) - (other-opnds (cdr opnds)) - (sn-other-opnds (sn-opnds other-opnds sn)) - (opnd68 (opnd->opnd68 first-opnd (temp-in-opnd68 reg68) sn))) - (make-top-of-frame-if-stk-opnd68 opnd68 sn-other-opnds) - (if (imm? opnd68) - (mul-n-to-reg68 (quotient (imm-val opnd68) 8) reg68) - (begin - (emit-asr.l (make-imm 3) reg68) - (emit-muls.l (opnd68->true-opnd68 opnd68 sn-other-opnds) reg68))) - (gen-mul-in-place other-opnds reg68 sn)))) -(define (gen-mul self-opnds other-opnds loc sn self?) - (let* ((opnds (append self-opnds other-opnds)) - (first-opnd (car opnds)) - (other-opnds (cdr opnds)) - (sn-other-opnds (sn-opnds other-opnds sn)) - (sn-first-opnd (sn-opnd first-opnd sn-other-opnds))) - (if (null? self-opnds) - (let ((loc68 (loc->loc68 loc #f sn-first-opnd))) - (if self? - (gen-mul-in-place opnds loc68 sn) - (begin - (move-opnd-to-loc68 first-opnd loc68 sn-other-opnds) - (gen-mul-in-place other-opnds loc68 sn)))) - (begin - (move-opnd-to-loc68 first-opnd dtemp1 (sn-opnd loc sn-other-opnds)) - (gen-mul-in-place other-opnds dtemp1 (sn-opnd loc sn)) - (if self? - (let ((loc68 (loc->loc68 loc dtemp1 sn))) - (make-top-of-frame-if-stk-opnd68 loc68 sn) - (emit-asr.l (make-imm 3) dtemp1) - (emit-muls.l dtemp1 (opnd68->true-opnd68 loc68 sn))) - (move-opnd68-to-loc dtemp1 loc sn)))))) -(define (gen-div-in-place opnds reg68 sn) - (if (not (null? opnds)) - (let* ((first-opnd (car opnds)) - (other-opnds (cdr opnds)) - (sn-other-opnds (sn-opnds other-opnds sn)) - (sn-first-opnd (sn-opnd first-opnd sn-other-opnds)) - (opnd68 (opnd->opnd68 first-opnd (temp-in-opnd68 reg68) sn))) - (make-top-of-frame-if-stk-opnd68 opnd68 sn-other-opnds) - (if (imm? opnd68) - (let ((n (quotient (imm-val opnd68) 8))) - (div-n-to-reg68 n reg68) - (if (> (abs n) 1) (emit-and.w (make-imm -8) reg68))) - (let ((opnd68* (opnd68->true-opnd68 opnd68 sn-other-opnds))) - (emit-divsl.l opnd68* reg68 reg68) - (emit-asl.l (make-imm 3) reg68))) - (gen-div-in-place other-opnds reg68 sn)))) -(define (gen-div first-opnd other-opnds loc sn self-opnds?) - (if (null? other-opnds) - (begin - (move-opnd-to-loc68 first-opnd pdec-sp (sn-opnd loc sn)) - (emit-moveq 8 dtemp1) - (emit-divsl.l pinc-sp dtemp1 dtemp1) - (emit-asl.l (make-imm 3) dtemp1) - (emit-and.w (make-imm -8) dtemp1) - (move-opnd68-to-loc dtemp1 loc sn)) - (let* ((sn-other-opnds (sn-opnds other-opnds sn)) - (sn-first-opnd (sn-opnd first-opnd sn-other-opnds))) - (if (and (reg? loc) (not self-opnds?) (not (eq? loc return-reg))) - (let ((reg68 (reg->reg68 loc))) - (if (not (eq? first-opnd loc)) - (move-opnd-to-loc68 first-opnd reg68 sn-other-opnds)) - (gen-div-in-place other-opnds reg68 sn)) - (begin - (move-opnd-to-loc68 - first-opnd - dtemp1 - (sn-opnd loc sn-other-opnds)) - (gen-div-in-place other-opnds dtemp1 (sn-opnd loc sn)) - (move-opnd68-to-loc dtemp1 loc sn)))))) -(define (gen-rem first-opnd second-opnd loc sn) - (let* ((sn-loc (sn-opnd loc sn)) - (sn-second-opnd (sn-opnd second-opnd sn-loc))) - (move-opnd-to-loc68 first-opnd dtemp1 sn-second-opnd) - (let ((opnd68 (opnd->opnd68 second-opnd #f sn-loc)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - false-reg))) - (make-top-of-frame-if-stk-opnd68 opnd68 sn-loc) - (let ((opnd68* (if (areg? opnd68) - (begin (emit-move.l opnd68 reg68) reg68) - (opnd68->true-opnd68 opnd68 sn-loc)))) - (emit-divsl.l opnd68* reg68 dtemp1)) - (move-opnd68-to-loc reg68 loc sn) - (if (not (and (reg? loc) (not (eq? loc return-reg)))) - (emit-move.l (make-imm bits-false) false-reg))))) -(define (gen-mod first-opnd second-opnd loc sn) - (let* ((sn-loc (sn-opnd loc sn)) - (sn-first-opnd (sn-opnd first-opnd sn-loc)) - (sn-second-opnd (sn-opnd second-opnd sn-first-opnd)) - (opnd68 (opnd->opnd68 second-opnd #f sn-second-opnd))) - (define (general-case) - (let ((lbl1 (new-lbl!)) - (lbl2 (new-lbl!)) - (lbl3 (new-lbl!)) - (opnd68** (opnd68->true-opnd68 opnd68 sn-second-opnd)) - (opnd68* (opnd68->true-opnd68 - (opnd->opnd68 first-opnd #f sn-second-opnd) - sn-second-opnd))) - (move-opnd68-to-loc68 opnd68* dtemp1) - (move-opnd68-to-loc68 opnd68** false-reg) - (emit-divsl.l false-reg false-reg dtemp1) - (emit-move.l false-reg false-reg) - (emit-beq lbl3) - (move-opnd68-to-loc68 opnd68* dtemp1) - (emit-bmi lbl1) - (move-opnd68-to-loc68 opnd68** dtemp1) - (emit-bpl lbl3) - (emit-bra lbl2) - (emit-label lbl1) - (move-opnd68-to-loc68 opnd68** dtemp1) - (emit-bmi lbl3) - (emit-label lbl2) - (emit-add.l dtemp1 false-reg) - (emit-label lbl3) - (move-opnd68-to-loc false-reg loc sn) - (emit-move.l (make-imm bits-false) false-reg))) - (make-top-of-frame-if-stk-opnd68 opnd68 sn-first-opnd) - (if (imm? opnd68) - (let ((n (quotient (imm-val opnd68) 8))) - (if (> n 0) - (let ((shift (power-of-2 n))) - (if shift - (let ((reg68 (if (and (reg? loc) - (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1))) - (move-opnd-to-loc68 first-opnd reg68 sn-loc) - (emit-and.l (make-imm (* (- n 1) 8)) reg68) - (move-opnd68-to-loc reg68 loc sn)) - (general-case))) - (general-case))) - (general-case)))) -(define (gen-op emit-op dst-ok?) - (define (gen-op-in-place opnds loc68 sn) - (if (not (null? opnds)) - (let* ((first-opnd (car opnds)) - (other-opnds (cdr opnds)) - (sn-other-opnds (sn-opnds other-opnds sn)) - (sn-first-opnd (sn-opnd first-opnd sn-other-opnds)) - (opnd68 (opnd->opnd68 - first-opnd - (temp-in-opnd68 loc68) - (sn-opnd68 loc68 sn)))) - (make-top-of-frame-if-stk-opnds68 opnd68 loc68 sn-other-opnds) - (if (imm? opnd68) - (emit-op opnd68 (opnd68->true-opnd68 loc68 sn-other-opnds)) - (let ((opnd68* (opnd68->true-opnd68 opnd68 sn-other-opnds))) - (if (or (dreg? opnd68) (dst-ok? loc68)) - (emit-op opnd68* - (opnd68->true-opnd68 loc68 sn-other-opnds)) - (begin - (move-opnd68-to-loc68 opnd68* dtemp1) - (emit-op dtemp1 - (opnd68->true-opnd68 loc68 sn-other-opnds)))))) - (gen-op-in-place other-opnds loc68 sn)))) - (lambda (self-opnds other-opnds loc sn self?) - (let* ((opnds (append self-opnds other-opnds)) - (first-opnd (car opnds)) - (other-opnds (cdr opnds)) - (sn-other-opnds (sn-opnds other-opnds sn)) - (sn-first-opnd (sn-opnd first-opnd sn-other-opnds))) - (if (<= (length self-opnds) 1) - (let ((loc68 (loc->loc68 loc #f sn-first-opnd))) - (if self? - (gen-op-in-place opnds loc68 sn) - (begin - (move-opnd-to-loc68 first-opnd loc68 sn-other-opnds) - (gen-op-in-place other-opnds loc68 sn)))) - (begin - (move-opnd-to-loc68 first-opnd dtemp1 (sn-opnd loc sn-other-opnds)) - (gen-op-in-place other-opnds dtemp1 (sn-opnd loc sn)) - (if self? - (let ((loc68 (loc->loc68 loc dtemp1 sn))) - (make-top-of-frame-if-stk-opnd68 loc68 sn) - (emit-op dtemp1 (opnd68->true-opnd68 loc68 sn))) - (move-opnd68-to-loc dtemp1 loc sn))))))) -(define gen-logior (gen-op emit-or.l dreg?)) -(define gen-logxor (gen-op emit-eor.l (lambda (x) #f))) -(define gen-logand (gen-op emit-and.l dreg?)) -(define (gen-shift right-shift) - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (let* ((opnd1 (car opnds)) - (opnd2 (cadr opnds)) - (sn-opnd1 (sn-opnd opnd1 sn-loc)) - (o2 (opnd->opnd68 opnd2 #f sn-opnd1))) - (make-top-of-frame-if-stk-opnd68 o2 sn-opnd1) - (if (imm? o2) - (let* ((reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1)) - (n (quotient (imm-val o2) 8)) - (emit-shft (if (> n 0) emit-lsl.l right-shift))) - (move-opnd-to-loc68 opnd1 reg68 sn-loc) - (let loop ((i (min (abs n) 29))) - (if (> i 0) - (begin - (emit-shft (make-imm (min i 8)) reg68) - (loop (- i 8))))) - (if (< n 0) (emit-and.w (make-imm -8) reg68)) - (move-opnd68-to-loc reg68 loc sn)) - (let* ((reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1)) - (reg68* (if (and (reg? loc) (not (eq? loc return-reg))) - dtemp1 - false-reg)) - (lbl1 (new-lbl!)) - (lbl2 (new-lbl!))) - (emit-move.l (opnd68->true-opnd68 o2 sn-opnd1) reg68*) - (move-opnd-to-loc68 opnd1 reg68 sn-loc) - (emit-asr.l (make-imm 3) reg68*) - (emit-bmi lbl1) - (emit-lsl.l reg68* reg68) - (emit-bra lbl2) - (emit-label lbl1) - (emit-neg.l reg68*) - (right-shift reg68* reg68) - (emit-and.w (make-imm -8) reg68) - (emit-label lbl2) - (move-opnd68-to-loc reg68 loc sn) - (if (not (and (reg? loc) (not (eq? loc return-reg)))) - (emit-move.l (make-imm bits-false) false-reg)))))))) -(define (flo-oper oper1 oper2 opnds loc sn) - (gen-guarantee-space 2) - (move-opnd-to-loc68 - (car opnds) - atemp1 - (sn-opnds (cdr opnds) (sn-opnd loc sn))) - (oper1 (make-disp* atemp1 (- type-flonum)) ftemp1) - (let loop ((opnds (cdr opnds))) - (if (not (null? opnds)) - (let* ((opnd (car opnds)) - (other-opnds (cdr opnds)) - (sn-other-opnds (sn-opnds other-opnds sn))) - (move-opnd-to-loc68 opnd atemp1 sn-other-opnds) - (oper2 (make-disp* atemp1 (- type-flonum)) ftemp1) - (loop (cdr opnds))))) - (add-n-to-loc68 (* -2 pointer-size) heap-reg) - (emit-fmov.dx ftemp1 (make-ind heap-reg)) - (let ((reg68 (if (reg? loc) (reg->reg68 loc) atemp1))) - (emit-move.l heap-reg reg68) - (emit-addq.l type-flonum reg68)) - (if (not (reg? loc)) (move-opnd68-to-loc atemp1 loc sn))) -(define (gen-make-placeholder opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (let ((opnd (car opnds))) - (gen-guarantee-space 4) - (emit-clr.l (make-pdec heap-reg)) - (move-opnd-to-loc68 opnd (make-pdec heap-reg) sn-loc) - (emit-move.l null-reg (make-pdec heap-reg)) - (move-opnd68-to-loc68 heap-reg atemp2) - (emit-addq.l (modulo (- type-placeholder type-pair) 8) atemp2) - (emit-move.l atemp2 (make-pdec heap-reg)) - (move-opnd68-to-loc atemp2 loc sn)))) -(define (gen-subprocedure-id opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) - (opnd (car opnds)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1))) - (move-opnd-to-loc68 opnd atemp1 sn-loc) - (move-n-to-loc68 32768 reg68) - (emit-sub.w (make-disp* atemp1 -2) reg68) - (move-opnd68-to-loc reg68 loc sn))) -(define (gen-subprocedure-parent opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) (opnd (car opnds))) - (move-opnd-to-loc68 opnd atemp1 sn-loc) - (emit-add.w (make-disp* atemp1 -2) atemp1) - (add-n-to-loc68 -32768 atemp1) - (move-opnd68-to-loc atemp1 loc sn))) -(define (gen-return-fs opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) - (opnd (car opnds)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1)) - (lbl (new-lbl!))) - (move-opnd-to-loc68 opnd atemp1 sn-loc) - (emit-moveq 0 reg68) - (emit-move.w (make-disp* atemp1 -6) reg68) - (emit-beq lbl) - (emit-and.w (make-imm 32767) reg68) - (emit-subq.l 8 reg68) - (emit-label lbl) - (emit-addq.l 8 reg68) - (emit-asl.l (make-imm 1) reg68) - (move-opnd68-to-loc reg68 loc sn))) -(define (gen-return-link opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) - (opnd (car opnds)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1)) - (lbl (new-lbl!))) - (move-opnd-to-loc68 opnd atemp1 sn-loc) - (emit-moveq 0 reg68) - (emit-move.w (make-disp* atemp1 -6) reg68) - (emit-beq lbl) - (emit-and.w (make-imm 32767) reg68) - (emit-subq.l 8 reg68) - (emit-label lbl) - (emit-addq.l 8 reg68) - (emit-sub.w (make-disp* atemp1 -4) reg68) - (emit-asl.l (make-imm 1) reg68) - (move-opnd68-to-loc reg68 loc sn))) -(define (gen-procedure-info opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) (opnd (car opnds))) - (move-opnd-to-loc68 opnd atemp1 sn-loc) - (emit-add.w (make-disp* atemp1 -2) atemp1) - (move-opnd68-to-loc (make-disp* atemp1 (- 32768 6)) loc sn))) -(define (gen-guarantee-space n) - (set! pointers-allocated (+ pointers-allocated n)) - (if (> pointers-allocated heap-allocation-fudge) - (begin (gen-guarantee-fudge) (set! pointers-allocated n)))) -(define (gen-guarantee-fudge) - (if (> pointers-allocated 0) - (let ((lbl (new-lbl!))) - (emit-cmp.l heap-lim-slot heap-reg) - (emit-bcc lbl) - (gen-trap instr-source entry-frame #f #f heap-alloc1-trap lbl) - (set! pointers-allocated 0)))) -(define pointers-allocated '()) -(define (gen-type opnds loc sn) - (let* ((sn-loc (sn-opnd loc sn)) - (opnd (car opnds)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1))) - (move-opnd-to-loc68 opnd reg68 sn-loc) - (emit-and.l (make-imm 7) reg68) - (emit-asl.l (make-imm 3) reg68) - (move-opnd68-to-loc reg68 loc sn))) -(define (gen-type-cast opnds loc sn) - (let ((sn-loc (if loc (sn-opnd loc sn) sn))) - (let ((first-opnd (car opnds)) (second-opnd (cadr opnds))) - (let* ((sn-loc (if (and loc (not (eq? first-opnd loc))) sn-loc sn)) - (o1 (opnd->opnd68 first-opnd #f (sn-opnd second-opnd sn-loc))) - (o2 (opnd->opnd68 second-opnd (temp-in-opnd68 o1) sn-loc)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1))) - (make-top-of-frame-if-stk-opnds68 o1 o2 sn-loc) - (move-opnd68-to-loc68 - (opnd68->true-opnd68 o1 (sn-opnd68 o2 sn-loc)) - reg68) - (emit-and.w (make-imm -8) reg68) - (if (imm? o2) - (let ((n (quotient (imm-val o2) 8))) - (if (> n 0) (emit-addq.w n reg68))) - (begin - (move-opnd68-to-loc68 (opnd68->true-opnd68 o2 sn-loc) atemp1) - (emit-exg atemp1 reg68) - (emit-asr.l (make-imm 3) reg68) - (emit-add.l atemp1 reg68))) - (move-opnd68-to-loc reg68 loc sn))))) -(define (gen-subtype opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) - (opnd (car opnds)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1))) - (move-opnd-to-loc68 opnd atemp1 sn-loc) - (emit-moveq 0 reg68) - (emit-move.b (make-ind atemp1) reg68) - (move-opnd68-to-loc reg68 loc sn))) -(define (gen-subtype-set! opnds loc sn) - (let ((sn-loc (if loc (sn-opnd loc sn) sn))) - (let ((first-opnd (car opnds)) (second-opnd (cadr opnds))) - (let* ((sn-loc (if (and loc (not (eq? first-opnd loc))) sn-loc sn)) - (o1 (opnd->opnd68 first-opnd #f (sn-opnd second-opnd sn-loc))) - (o2 (opnd->opnd68 second-opnd (temp-in-opnd68 o1) sn-loc))) - (make-top-of-frame-if-stk-opnds68 o1 o2 sn-loc) - (move-opnd68-to-loc68 - (opnd68->true-opnd68 o1 (sn-opnd68 o2 sn-loc)) - atemp1) - (if (imm? o2) - (emit-move.b (make-imm (imm-val o2)) (make-ind atemp1)) - (begin - (move-opnd68-to-loc68 (opnd68->true-opnd68 o2 sn-loc) dtemp1) - (emit-move.b dtemp1 (make-ind atemp1)))) - (if (and loc (not (eq? first-opnd loc))) - (move-opnd68-to-loc atemp1 loc sn)))))) -(define (vector-select kind vector string vector8 vector16) - (case kind - ((string) string) - ((vector8) vector8) - ((vector16) vector16) - (else vector))) -(define (obj-vector? kind) (vector-select kind #t #f #f #f)) -(define (make-gen-vector kind) - (lambda (opnds loc sn) - (let ((sn-loc (if loc (sn-opnd loc sn) sn))) - (let* ((n (length opnds)) - (bytes (+ pointer-size - (* (vector-select kind 4 1 1 2) - (+ n (if (eq? kind 'string) 1 0))))) - (adjust (modulo (- bytes) 8))) - (gen-guarantee-space - (quotient (* (quotient (+ bytes (- 8 1)) 8) 8) pointer-size)) - (if (not (= adjust 0)) (emit-subq.l adjust heap-reg)) - (if (eq? kind 'string) (emit-move.b (make-imm 0) (make-pdec heap-reg))) - (let loop ((opnds (reverse opnds))) - (if (pair? opnds) - (let* ((o (car opnds)) (sn-o (sn-opnds (cdr opnds) sn-loc))) - (if (eq? kind 'vector) - (move-opnd-to-loc68 o (make-pdec heap-reg) sn-o) - (begin - (move-opnd-to-loc68 o dtemp1 sn-o) - (emit-asr.l (make-imm 3) dtemp1) - (if (eq? kind 'vector16) - (emit-move.w dtemp1 (make-pdec heap-reg)) - (emit-move.b dtemp1 (make-pdec heap-reg))))) - (loop (cdr opnds))))) - (emit-move.l - (make-imm - (+ (* 256 (- bytes pointer-size)) - (* 8 (if (eq? kind 'vector) subtype-vector subtype-string)))) - (make-pdec heap-reg)) - (if loc - (begin - (emit-lea (make-disp* heap-reg type-subtyped) atemp2) - (move-opnd68-to-loc atemp2 loc sn))))))) -(define (make-gen-vector-length kind) - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) - (opnd (car opnds)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1))) - (move-opnd-to-loc68 opnd atemp1 sn-loc) - (move-opnd68-to-loc68 (make-disp* atemp1 (- type-subtyped)) reg68) - (emit-lsr.l (make-imm (vector-select kind 7 5 5 6)) reg68) - (if (not (eq? kind 'vector)) - (begin - (emit-and.w (make-imm -8) reg68) - (if (eq? kind 'string) (emit-subq.l 8 reg68)))) - (move-opnd68-to-loc reg68 loc sn)))) -(define (make-gen-vector-ref kind) - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (let ((first-opnd (car opnds)) - (second-opnd (cadr opnds)) - (reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1))) - (let* ((o2 (opnd->opnd68 second-opnd #f (sn-opnd first-opnd sn-loc))) - (o1 (opnd->opnd68 first-opnd (temp-in-opnd68 o2) sn-loc))) - (make-top-of-frame-if-stk-opnds68 o1 o2 sn-loc) - (let* ((offset (if (eq? kind 'closure) - (- pointer-size type-procedure) - (- pointer-size type-subtyped))) - (loc68 (if (imm? o2) - (begin - (move-opnd68-to-loc68 - (opnd68->true-opnd68 o1 sn-loc) - atemp1) - (make-disp* - atemp1 - (+ (quotient - (imm-val o2) - (vector-select kind 2 8 8 4)) - offset))) - (begin - (move-opnd68-to-loc68 - (opnd68->true-opnd68 o2 (sn-opnd68 o1 sn-loc)) - dtemp1) - (emit-asr.l - (make-imm (vector-select kind 1 3 3 2)) - dtemp1) - (move-opnd68-to-loc68 - (opnd68->true-opnd68 o1 sn-loc) - atemp1) - (if (and (identical-opnd68? reg68 dtemp1) - (not (obj-vector? kind))) - (begin - (emit-move.l dtemp1 atemp2) - (make-inx atemp1 atemp2 offset)) - (make-inx atemp1 dtemp1 offset)))))) - (if (not (obj-vector? kind)) (emit-moveq 0 reg68)) - (case kind - ((string vector8) (emit-move.b loc68 reg68)) - ((vector16) (emit-move.w loc68 reg68)) - (else (emit-move.l loc68 reg68))) - (if (not (obj-vector? kind)) - (begin - (emit-asl.l (make-imm 3) reg68) - (if (eq? kind 'string) (emit-addq.w type-special reg68)))) - (move-opnd68-to-loc reg68 loc sn))))))) -(define (make-gen-vector-set! kind) - (lambda (opnds loc sn) - (let ((sn-loc (if loc (sn-opnd loc sn) sn))) - (let ((first-opnd (car opnds)) - (second-opnd (cadr opnds)) - (third-opnd (caddr opnds))) - (let* ((sn-loc (if (and loc (not (eq? first-opnd loc))) - (sn-opnd first-opnd sn-loc) - sn)) - (sn-third-opnd (sn-opnd third-opnd sn-loc)) - (o2 (opnd->opnd68 - second-opnd - #f - (sn-opnd first-opnd sn-third-opnd))) - (o1 (opnd->opnd68 - first-opnd - (temp-in-opnd68 o2) - sn-third-opnd))) - (make-top-of-frame-if-stk-opnds68 o1 o2 sn-third-opnd) - (let* ((offset (if (eq? kind 'closure) - (- pointer-size type-procedure) - (- pointer-size type-subtyped))) - (loc68 (if (imm? o2) - (begin - (move-opnd68-to-loc68 - (opnd68->true-opnd68 o1 sn-third-opnd) - atemp1) - (make-disp* - atemp1 - (+ (quotient - (imm-val o2) - (vector-select kind 2 8 8 4)) - offset))) - (begin - (move-opnd68-to-loc68 - (opnd68->true-opnd68 o2 (sn-opnd68 o1 sn-loc)) - dtemp1) - (emit-asr.l - (make-imm (vector-select kind 1 3 3 2)) - dtemp1) - (move-opnd68-to-loc68 - (opnd68->true-opnd68 o1 sn-loc) - atemp1) - (if (obj-vector? kind) - (make-inx atemp1 dtemp1 offset) - (begin - (emit-move.l dtemp1 atemp2) - (make-inx atemp1 atemp2 offset))))))) - (if (obj-vector? kind) - (move-opnd-to-loc68 third-opnd loc68 sn-loc) - (begin - (move-opnd-to-loc68 third-opnd dtemp1 sn-loc) - (emit-asr.l (make-imm 3) dtemp1) - (if (eq? kind 'vector16) - (emit-move.w dtemp1 loc68) - (emit-move.b dtemp1 loc68)))) - (if (and loc (not (eq? first-opnd loc))) - (copy-opnd-to-loc first-opnd loc sn)))))))) -(define (make-gen-vector-shrink! kind) - (lambda (opnds loc sn) - (let ((sn-loc (if loc (sn-opnd loc sn) sn))) - (let ((first-opnd (car opnds)) (second-opnd (cadr opnds))) - (let* ((sn-loc (if (and loc (not (eq? first-opnd loc))) - (sn-opnd first-opnd sn-loc) - sn)) - (o2 (opnd->opnd68 second-opnd #f (sn-opnd first-opnd sn-loc))) - (o1 (opnd->opnd68 first-opnd (temp-in-opnd68 o2) sn-loc))) - (make-top-of-frame-if-stk-opnds68 o1 o2 sn-loc) - (move-opnd68-to-loc68 - (opnd68->true-opnd68 o2 (sn-opnd68 o1 sn-loc)) - dtemp1) - (emit-move.l (opnd68->true-opnd68 o1 sn-loc) atemp1) - (if (eq? kind 'string) - (begin - (emit-asr.l (make-imm 3) dtemp1) - (emit-move.b - (make-imm 0) - (make-inx atemp1 dtemp1 (- pointer-size type-subtyped))) - (emit-addq.l 1 dtemp1) - (emit-asl.l (make-imm 8) dtemp1)) - (emit-asl.l (make-imm (vector-select kind 7 5 5 6)) dtemp1)) - (emit-move.b (make-ind atemp1) dtemp1) - (emit-move.l dtemp1 (make-disp* atemp1 (- type-subtyped))) - (if (and loc (not (eq? first-opnd loc))) - (move-opnd68-to-loc atemp1 loc sn))))))) -(define (gen-eq-test bits not? opnds lbl fs) - (gen-compare* (opnd->opnd68 (car opnds) #f fs) (make-imm bits) fs) - (if not? (emit-bne lbl) (emit-beq lbl))) -(define (gen-compare opnd1 opnd2 fs) - (let* ((o1 (opnd->opnd68 opnd1 #f (sn-opnd opnd2 fs))) - (o2 (opnd->opnd68 opnd2 (temp-in-opnd68 o1) fs))) - (gen-compare* o1 o2 fs))) -(define (gen-compare* o1 o2 fs) - (make-top-of-frame-if-stk-opnds68 o1 o2 fs) - (let ((order-1-2 - (cond ((imm? o1) - (cmp-n-to-opnd68 (imm-val o1) (opnd68->true-opnd68 o2 fs))) - ((imm? o2) - (not (cmp-n-to-opnd68 - (imm-val o2) - (opnd68->true-opnd68 o1 fs)))) - ((reg68? o1) (emit-cmp.l (opnd68->true-opnd68 o2 fs) o1) #f) - ((reg68? o2) (emit-cmp.l (opnd68->true-opnd68 o1 fs) o2) #t) - (else - (emit-move.l (opnd68->true-opnd68 o1 (sn-opnd68 o2 fs)) dtemp1) - (emit-cmp.l (opnd68->true-opnd68 o2 fs) dtemp1) - #f)))) - (shrink-frame fs) - order-1-2)) -(define (gen-compares branch< branch>= branch> branch<= not? opnds lbl fs) - (gen-compares* - gen-compare - branch< - branch>= - branch> - branch<= - not? - opnds - lbl - fs)) -(define (gen-compares* - gen-comp - branch< - branch>= - branch> - branch<= - not? - opnds - lbl - fs) - (define (gen-compare-sequence opnd1 opnd2 rest) - (if (null? rest) - (if (gen-comp opnd1 opnd2 fs) - (if not? (branch<= lbl) (branch> lbl)) - (if not? (branch>= lbl) (branch< lbl))) - (let ((order-1-2 - (gen-comp opnd1 opnd2 (sn-opnd opnd2 (sn-opnds rest fs))))) - (if (= current-fs fs) - (if not? - (begin - (if order-1-2 (branch<= lbl) (branch>= lbl)) - (gen-compare-sequence opnd2 (car rest) (cdr rest))) - (let ((exit-lbl (new-lbl!))) - (if order-1-2 (branch<= exit-lbl) (branch>= exit-lbl)) - (gen-compare-sequence opnd2 (car rest) (cdr rest)) - (emit-label exit-lbl))) - (if not? - (let ((next-lbl (new-lbl!))) - (if order-1-2 (branch> next-lbl) (branch< next-lbl)) - (shrink-frame fs) - (emit-bra lbl) - (emit-label next-lbl) - (gen-compare-sequence opnd2 (car rest) (cdr rest))) - (let* ((next-lbl (new-lbl!)) (exit-lbl (new-lbl!))) - (if order-1-2 (branch> next-lbl) (branch< next-lbl)) - (shrink-frame fs) - (emit-bra exit-lbl) - (emit-label next-lbl) - (gen-compare-sequence opnd2 (car rest) (cdr rest)) - (emit-label exit-lbl))))))) - (if (or (null? opnds) (null? (cdr opnds))) - (begin (shrink-frame fs) (if (not not?) (emit-bra lbl))) - (gen-compare-sequence (car opnds) (cadr opnds) (cddr opnds)))) -(define (gen-compare-flo opnd1 opnd2 fs) - (let* ((o1 (opnd->opnd68 opnd1 #f (sn-opnd opnd2 fs))) - (o2 (opnd->opnd68 opnd2 (temp-in-opnd68 o1) fs))) - (make-top-of-frame-if-stk-opnds68 o1 o2 fs) - (emit-move.l (opnd68->true-opnd68 o1 (sn-opnd68 o2 fs)) atemp1) - (emit-move.l (opnd68->true-opnd68 o2 fs) atemp2) - (emit-fmov.dx (make-disp* atemp2 (- type-flonum)) ftemp1) - (emit-fcmp.dx (make-disp* atemp1 (- type-flonum)) ftemp1) - #t)) -(define (gen-compares-flo branch< branch>= branch> branch<= not? opnds lbl fs) - (gen-compares* - gen-compare-flo - branch< - branch>= - branch> - branch<= - not? - opnds - lbl - fs)) -(define (gen-type-test tag not? opnds lbl fs) - (let ((opnd (car opnds))) - (let ((o (opnd->opnd68 opnd #f fs))) - (define (mask-test set-reg correction) - (emit-btst - (if (= correction 0) - (if (dreg? o) - o - (begin - (emit-move.l (opnd68->true-opnd68 o fs) dtemp1) - dtemp1)) - (begin - (if (not (eq? o dtemp1)) - (emit-move.l (opnd68->true-opnd68 o fs) dtemp1)) - (emit-addq.w correction dtemp1) - dtemp1)) - set-reg)) - (make-top-of-frame-if-stk-opnd68 o fs) - (cond ((= tag 0) - (if (eq? o dtemp1) - (emit-and.w (make-imm 7) dtemp1) - (begin - (emit-move.l (opnd68->true-opnd68 o fs) dtemp1) - (emit-and.w (make-imm 7) dtemp1)))) - ((= tag type-placeholder) (mask-test placeholder-reg 0)) - (else (mask-test pair-reg (modulo (- type-pair tag) 8)))) - (shrink-frame fs) - (if not? (emit-bne lbl) (emit-beq lbl))))) -(define (gen-subtype-test type not? opnds lbl fs) - (let ((opnd (car opnds))) - (let ((o (opnd->opnd68 opnd #f fs)) (cont-lbl (new-lbl!))) - (make-top-of-frame-if-stk-opnd68 o fs) - (if (not (eq? o dtemp1)) (emit-move.l (opnd68->true-opnd68 o fs) dtemp1)) - (emit-move.l dtemp1 atemp1) - (emit-addq.w (modulo (- type-pair type-subtyped) 8) dtemp1) - (emit-btst dtemp1 pair-reg) - (shrink-frame fs) - (if not? (emit-bne lbl) (emit-bne cont-lbl)) - (emit-cmp.b (make-imm (* type 8)) (make-ind atemp1)) - (if not? (emit-bne lbl) (emit-beq lbl)) - (emit-label cont-lbl)))) -(define (gen-even-test not? opnds lbl fs) - (move-opnd-to-loc68 (car opnds) dtemp1 fs) - (emit-and.w (make-imm 8) dtemp1) - (shrink-frame fs) - (if not? (emit-bne lbl) (emit-beq lbl))) -(define (def-spec name specializer-maker) - (let ((proc-name (string->canonical-symbol name))) - (let ((proc (prim-info proc-name))) - (if proc - (proc-obj-specialize-set! proc (specializer-maker proc proc-name)) - (compiler-internal-error "def-spec, unknown primitive:" name))))) -(define (safe name) - (lambda (proc proc-name) - (let ((spec (get-prim-info name))) (lambda (decls) spec)))) -(define (unsafe name) - (lambda (proc proc-name) - (let ((spec (get-prim-info name))) - (lambda (decls) (if (not (safe? decls)) spec proc))))) -(define (safe-arith fix-name flo-name) (arith #t fix-name flo-name)) -(define (unsafe-arith fix-name flo-name) (arith #f fix-name flo-name)) -(define (arith fix-safe? fix-name flo-name) - (lambda (proc proc-name) - (let ((fix-spec (if fix-name (get-prim-info fix-name) proc)) - (flo-spec (if flo-name (get-prim-info flo-name) proc))) - (lambda (decls) - (let ((arith (arith-implementation proc-name decls))) - (cond ((eq? arith fixnum-sym) - (if (or fix-safe? (not (safe? decls))) fix-spec proc)) - ((eq? arith flonum-sym) (if (not (safe? decls)) flo-spec proc)) - (else proc))))))) -(define-apply "##TYPE" #f (lambda (opnds loc sn) (gen-type opnds loc sn))) -(define-apply - "##TYPE-CAST" - #f - (lambda (opnds loc sn) (gen-type-cast opnds loc sn))) -(define-apply - "##SUBTYPE" - #f - (lambda (opnds loc sn) (gen-subtype opnds loc sn))) -(define-apply - "##SUBTYPE-SET!" - #t - (lambda (opnds loc sn) (gen-subtype-set! opnds loc sn))) -(define-ifjump - "##NOT" - (lambda (not? opnds lbl fs) (gen-eq-test bits-false not? opnds lbl fs))) -(define-ifjump - "##NULL?" - (lambda (not? opnds lbl fs) (gen-eq-test bits-null not? opnds lbl fs))) -(define-ifjump - "##UNASSIGNED?" - (lambda (not? opnds lbl fs) (gen-eq-test bits-unass not? opnds lbl fs))) -(define-ifjump - "##UNBOUND?" - (lambda (not? opnds lbl fs) (gen-eq-test bits-unbound not? opnds lbl fs))) -(define-ifjump - "##EQ?" - (lambda (not? opnds lbl fs) - (gen-compares emit-beq emit-bne emit-beq emit-bne not? opnds lbl fs))) -(define-ifjump - "##FIXNUM?" - (lambda (not? opnds lbl fs) (gen-type-test type-fixnum not? opnds lbl fs))) -(define-ifjump - "##FLONUM?" - (lambda (not? opnds lbl fs) (gen-type-test type-flonum not? opnds lbl fs))) -(define-ifjump - "##SPECIAL?" - (lambda (not? opnds lbl fs) (gen-type-test type-special not? opnds lbl fs))) -(define-ifjump - "##PAIR?" - (lambda (not? opnds lbl fs) (gen-type-test type-pair not? opnds lbl fs))) -(define-ifjump - "##SUBTYPED?" - (lambda (not? opnds lbl fs) (gen-type-test type-subtyped not? opnds lbl fs))) -(define-ifjump - "##PROCEDURE?" - (lambda (not? opnds lbl fs) (gen-type-test type-procedure not? opnds lbl fs))) -(define-ifjump - "##PLACEHOLDER?" - (lambda (not? opnds lbl fs) - (gen-type-test type-placeholder not? opnds lbl fs))) -(define-ifjump - "##VECTOR?" - (lambda (not? opnds lbl fs) - (gen-subtype-test subtype-vector not? opnds lbl fs))) -(define-ifjump - "##SYMBOL?" - (lambda (not? opnds lbl fs) - (gen-subtype-test subtype-symbol not? opnds lbl fs))) -(define-ifjump - "##RATNUM?" - (lambda (not? opnds lbl fs) - (gen-subtype-test subtype-ratnum not? opnds lbl fs))) -(define-ifjump - "##CPXNUM?" - (lambda (not? opnds lbl fs) - (gen-subtype-test subtype-cpxnum not? opnds lbl fs))) -(define-ifjump - "##STRING?" - (lambda (not? opnds lbl fs) - (gen-subtype-test subtype-string not? opnds lbl fs))) -(define-ifjump - "##BIGNUM?" - (lambda (not? opnds lbl fs) - (gen-subtype-test subtype-bignum not? opnds lbl fs))) -(define-ifjump - "##CHAR?" - (lambda (not? opnds lbl fs) - (let ((opnd (car opnds))) - (let ((o (opnd->opnd68 opnd #f fs)) (cont-lbl (new-lbl!))) - (make-top-of-frame-if-stk-opnd68 o fs) - (emit-move.l (opnd68->true-opnd68 o fs) dtemp1) - (if not? (emit-bmi lbl) (emit-bmi cont-lbl)) - (emit-addq.w (modulo (- type-pair type-special) 8) dtemp1) - (emit-btst dtemp1 pair-reg) - (shrink-frame fs) - (if not? (emit-bne lbl) (emit-beq lbl)) - (emit-label cont-lbl))))) -(define-ifjump - "##CLOSURE?" - (lambda (not? opnds lbl fs) - (move-opnd-to-loc68 (car opnds) atemp1 fs) - (shrink-frame fs) - (emit-cmp.w (make-imm 20153) (make-ind atemp1)) - (if not? (emit-bne lbl) (emit-beq lbl)))) -(define-ifjump - "##SUBPROCEDURE?" - (lambda (not? opnds lbl fs) - (move-opnd-to-loc68 (car opnds) atemp1 fs) - (shrink-frame fs) - (emit-move.w (make-pdec atemp1) dtemp1) - (if not? (emit-bmi lbl) (emit-bpl lbl)))) -(define-ifjump - "##RETURN-DYNAMIC-ENV-BIND?" - (lambda (not? opnds lbl fs) - (move-opnd-to-loc68 (car opnds) atemp1 fs) - (shrink-frame fs) - (emit-move.w (make-disp* atemp1 -6) dtemp1) - (if not? (emit-bne lbl) (emit-beq lbl)))) -(define-apply - "##FIXNUM.+" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (cond ((null? opnds) (copy-opnd-to-loc (make-obj '0) loc sn)) - ((null? (cdr opnds)) (copy-opnd-to-loc (car opnds) loc sn)) - ((or (reg? loc) (stk? loc)) - (commut-oper gen-add opnds loc sn #f '() '())) - (else (gen-add opnds '() loc sn #f)))))) -(define-apply - "##FIXNUM.-" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (gen-sub (car opnds) - (cdr opnds) - loc - sn - (any-contains-opnd? loc (cdr opnds)))))) -(define-apply - "##FIXNUM.*" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (cond ((null? opnds) (copy-opnd-to-loc (make-obj '1) loc sn)) - ((null? (cdr opnds)) (copy-opnd-to-loc (car opnds) loc sn)) - ((and (reg? loc) (not (eq? loc return-reg))) - (commut-oper gen-mul opnds loc sn #f '() '())) - (else (gen-mul opnds '() loc sn #f)))))) -(define-apply - "##FIXNUM.QUOTIENT" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (gen-div (car opnds) - (cdr opnds) - loc - sn - (any-contains-opnd? loc (cdr opnds)))))) -(define-apply - "##FIXNUM.REMAINDER" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (gen-rem (car opnds) (cadr opnds) loc sn)))) -(define-apply - "##FIXNUM.MODULO" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (gen-mod (car opnds) (cadr opnds) loc sn)))) -(define-apply - "##FIXNUM.LOGIOR" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (cond ((null? opnds) (copy-opnd-to-loc (make-obj '0) loc sn)) - ((null? (cdr opnds)) (copy-opnd-to-loc (car opnds) loc sn)) - ((or (reg? loc) (stk? loc)) - (commut-oper gen-logior opnds loc sn #f '() '())) - (else (gen-logior opnds '() loc sn #f)))))) -(define-apply - "##FIXNUM.LOGXOR" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (cond ((null? opnds) (copy-opnd-to-loc (make-obj '0) loc sn)) - ((null? (cdr opnds)) (copy-opnd-to-loc (car opnds) loc sn)) - ((or (reg? loc) (stk? loc)) - (commut-oper gen-logxor opnds loc sn #f '() '())) - (else (gen-logxor opnds '() loc sn #f)))))) -(define-apply - "##FIXNUM.LOGAND" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (cond ((null? opnds) (copy-opnd-to-loc (make-obj '-1) loc sn)) - ((null? (cdr opnds)) (copy-opnd-to-loc (car opnds) loc sn)) - ((or (reg? loc) (stk? loc)) - (commut-oper gen-logand opnds loc sn #f '() '())) - (else (gen-logand opnds '() loc sn #f)))))) -(define-apply - "##FIXNUM.LOGNOT" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn)) (opnd (car opnds))) - (if (and (or (reg? loc) (stk? loc)) (not (eq? loc return-reg))) - (begin - (copy-opnd-to-loc opnd loc sn-loc) - (let ((loc68 (loc->loc68 loc #f sn))) - (make-top-of-frame-if-stk-opnd68 loc68 sn) - (emit-not.l (opnd68->true-opnd68 loc68 sn)) - (emit-and.w (make-imm -8) (opnd68->true-opnd68 loc68 sn)))) - (begin - (move-opnd-to-loc68 opnd dtemp1 (sn-opnd loc sn)) - (emit-not.l dtemp1) - (emit-and.w (make-imm -8) dtemp1) - (move-opnd68-to-loc dtemp1 loc sn)))))) -(define-apply "##FIXNUM.ASH" #f (gen-shift emit-asr.l)) -(define-apply "##FIXNUM.LSH" #f (gen-shift emit-lsr.l)) -(define-ifjump - "##FIXNUM.ZERO?" - (lambda (not? opnds lbl fs) (gen-eq-test 0 not? opnds lbl fs))) -(define-ifjump - "##FIXNUM.POSITIVE?" - (lambda (not? opnds lbl fs) - (gen-compares - emit-bgt - emit-ble - emit-blt - emit-bge - not? - (list (car opnds) (make-obj '0)) - lbl - fs))) -(define-ifjump - "##FIXNUM.NEGATIVE?" - (lambda (not? opnds lbl fs) - (gen-compares - emit-blt - emit-bge - emit-bgt - emit-ble - not? - (list (car opnds) (make-obj '0)) - lbl - fs))) -(define-ifjump - "##FIXNUM.ODD?" - (lambda (not? opnds lbl fs) (gen-even-test (not not?) opnds lbl fs))) -(define-ifjump - "##FIXNUM.EVEN?" - (lambda (not? opnds lbl fs) (gen-even-test not? opnds lbl fs))) -(define-ifjump - "##FIXNUM.=" - (lambda (not? opnds lbl fs) - (gen-compares emit-beq emit-bne emit-beq emit-bne not? opnds lbl fs))) -(define-ifjump - "##FIXNUM.<" - (lambda (not? opnds lbl fs) - (gen-compares emit-blt emit-bge emit-bgt emit-ble not? opnds lbl fs))) -(define-ifjump - "##FIXNUM.>" - (lambda (not? opnds lbl fs) - (gen-compares emit-bgt emit-ble emit-blt emit-bge not? opnds lbl fs))) -(define-ifjump - "##FIXNUM.<=" - (lambda (not? opnds lbl fs) - (gen-compares emit-ble emit-bgt emit-bge emit-blt not? opnds lbl fs))) -(define-ifjump - "##FIXNUM.>=" - (lambda (not? opnds lbl fs) - (gen-compares emit-bge emit-blt emit-ble emit-bgt not? opnds lbl fs))) -(define-apply - "##FLONUM.->FIXNUM" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (move-opnd-to-loc68 (car opnds) atemp1 sn-loc) - (let ((reg68 (if (and (reg? loc) (not (eq? loc return-reg))) - (reg->reg68 loc) - dtemp1))) - (emit-fmov.dx (make-disp* atemp1 (- type-flonum)) ftemp1) - (emit-fmov.l ftemp1 reg68) - (emit-asl.l (make-imm 3) reg68) - (if (not (and (reg? loc) (not (eq? loc return-reg)))) - (move-opnd68-to-loc reg68 loc sn)))))) -(define-apply - "##FLONUM.<-FIXNUM" - #f - (lambda (opnds loc sn) - (gen-guarantee-space 2) - (move-opnd-to-loc68 - (car opnds) - dtemp1 - (sn-opnds (cdr opnds) (sn-opnd loc sn))) - (emit-asr.l (make-imm 3) dtemp1) - (emit-fmov.l dtemp1 ftemp1) - (add-n-to-loc68 (* -2 pointer-size) heap-reg) - (emit-fmov.dx ftemp1 (make-ind heap-reg)) - (let ((reg68 (if (reg? loc) (reg->reg68 loc) atemp1))) - (emit-move.l heap-reg reg68) - (emit-addq.l type-flonum reg68)) - (if (not (reg? loc)) (move-opnd68-to-loc atemp1 loc sn)))) -(define-apply - "##FLONUM.+" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (cond ((null? opnds) (copy-opnd-to-loc (make-obj inexact-0) loc sn)) - ((null? (cdr opnds)) (copy-opnd-to-loc (car opnds) loc sn)) - (else (flo-oper emit-fmov.dx emit-fadd.dx opnds loc sn)))))) -(define-apply - "##FLONUM.*" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (cond ((null? opnds) (copy-opnd-to-loc (make-obj inexact-+1) loc sn)) - ((null? (cdr opnds)) (copy-opnd-to-loc (car opnds) loc sn)) - (else (flo-oper emit-fmov.dx emit-fmul.dx opnds loc sn)))))) -(define-apply - "##FLONUM.-" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (if (null? (cdr opnds)) - (flo-oper emit-fneg.dx #f opnds loc sn) - (flo-oper emit-fmov.dx emit-fsub.dx opnds loc sn))))) -(define-apply - "##FLONUM./" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (if (null? (cdr opnds)) - (flo-oper - emit-fmov.dx - emit-fdiv.dx - (cons (make-obj inexact-+1) opnds) - loc - sn) - (flo-oper emit-fmov.dx emit-fdiv.dx opnds loc sn))))) -(define-apply - "##FLONUM.ABS" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-fabs.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.TRUNCATE" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) - (flo-oper emit-fintrz.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.ROUND" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-fint.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.EXP" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-fetox.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.LOG" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-flogn.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.SIN" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-fsin.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.COS" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-fcos.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.TAN" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-ftan.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.ASIN" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-fasin.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.ACOS" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-facos.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.ATAN" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-fatan.dx #f opnds loc sn)))) -(define-apply - "##FLONUM.SQRT" - #f - (lambda (opnds loc sn) - (let ((sn-loc (sn-opnd loc sn))) (flo-oper emit-fsqrt.dx #f opnds loc sn)))) -(define-ifjump - "##FLONUM.ZERO?" - (lambda (not? opnds lbl fs) - (gen-compares-flo - emit-fbeq - emit-fbne - emit-fbeq - emit-fbne - not? - (list (car opnds) (make-obj inexact-0)) - lbl - fs))) -(define-ifjump - "##FLONUM.NEGATIVE?" - (lambda (not? opnds lbl fs) - (gen-compares-flo - emit-fblt - emit-fbge - emit-fbgt - emit-fble - not? - (list (car opnds) (make-obj inexact-0)) - lbl - fs))) -(define-ifjump - "##FLONUM.POSITIVE?" - (lambda (not? opnds lbl fs) - (gen-compares-flo - emit-fbgt - emit-fble - emit-fblt - emit-fbge - not? - (list (car opnds) (make-obj inexact-0)) - lbl - fs))) -(define-ifjump - "##FLONUM.=" - (lambda (not? opnds lbl fs) - (gen-compares-flo - emit-fbeq - emit-fbne - emit-fbeq - emit-fbne - not? - opnds - lbl - fs))) -(define-ifjump - "##FLONUM.<" - (lambda (not? opnds lbl fs) - (gen-compares-flo - emit-fblt - emit-fbge - emit-fbgt - emit-fble - not? - opnds - lbl - fs))) -(define-ifjump - "##FLONUM.>" - (lambda (not? opnds lbl fs) - (gen-compares-flo - emit-fbgt - emit-fble - emit-fblt - emit-fbge - not? - opnds - lbl - fs))) -(define-ifjump - "##FLONUM.<=" - (lambda (not? opnds lbl fs) - (gen-compares-flo - emit-fble - emit-fbgt - emit-fbge - emit-fblt - not? - opnds - lbl - fs))) -(define-ifjump - "##FLONUM.>=" - (lambda (not? opnds lbl fs) - (gen-compares-flo - emit-fbge - emit-fblt - emit-fble - emit-fbgt - not? - opnds - lbl - fs))) -(define-ifjump - "##CHAR=?" - (lambda (not? opnds lbl fs) - (gen-compares emit-beq emit-bne emit-beq emit-bne not? opnds lbl fs))) -(define-ifjump - "##CHAR?" - (lambda (not? opnds lbl fs) - (gen-compares emit-bgt emit-ble emit-blt emit-bge not? opnds lbl fs))) -(define-ifjump - "##CHAR<=?" - (lambda (not? opnds lbl fs) - (gen-compares emit-ble emit-bgt emit-bge emit-blt not? opnds lbl fs))) -(define-ifjump - "##CHAR>=?" - (lambda (not? opnds lbl fs) - (gen-compares emit-bge emit-blt emit-ble emit-bgt not? opnds lbl fs))) -(define-apply "##CONS" #f (lambda (opnds loc sn) (gen-cons opnds loc sn))) -(define-apply - "##SET-CAR!" - #t - (lambda (opnds loc sn) (gen-set-car! opnds loc sn))) -(define-apply - "##SET-CDR!" - #t - (lambda (opnds loc sn) (gen-set-cdr! opnds loc sn))) -(define-apply "##CAR" #f (make-gen-apply-c...r 2)) -(define-apply "##CDR" #f (make-gen-apply-c...r 3)) -(define-apply "##CAAR" #f (make-gen-apply-c...r 4)) -(define-apply "##CADR" #f (make-gen-apply-c...r 5)) -(define-apply "##CDAR" #f (make-gen-apply-c...r 6)) -(define-apply "##CDDR" #f (make-gen-apply-c...r 7)) -(define-apply "##CAAAR" #f (make-gen-apply-c...r 8)) -(define-apply "##CAADR" #f (make-gen-apply-c...r 9)) -(define-apply "##CADAR" #f (make-gen-apply-c...r 10)) -(define-apply "##CADDR" #f (make-gen-apply-c...r 11)) -(define-apply "##CDAAR" #f (make-gen-apply-c...r 12)) -(define-apply "##CDADR" #f (make-gen-apply-c...r 13)) -(define-apply "##CDDAR" #f (make-gen-apply-c...r 14)) -(define-apply "##CDDDR" #f (make-gen-apply-c...r 15)) -(define-apply "##CAAAAR" #f (make-gen-apply-c...r 16)) -(define-apply "##CAAADR" #f (make-gen-apply-c...r 17)) -(define-apply "##CAADAR" #f (make-gen-apply-c...r 18)) -(define-apply "##CAADDR" #f (make-gen-apply-c...r 19)) -(define-apply "##CADAAR" #f (make-gen-apply-c...r 20)) -(define-apply "##CADADR" #f (make-gen-apply-c...r 21)) -(define-apply "##CADDAR" #f (make-gen-apply-c...r 22)) -(define-apply "##CADDDR" #f (make-gen-apply-c...r 23)) -(define-apply "##CDAAAR" #f (make-gen-apply-c...r 24)) -(define-apply "##CDAADR" #f (make-gen-apply-c...r 25)) -(define-apply "##CDADAR" #f (make-gen-apply-c...r 26)) -(define-apply "##CDADDR" #f (make-gen-apply-c...r 27)) -(define-apply "##CDDAAR" #f (make-gen-apply-c...r 28)) -(define-apply "##CDDADR" #f (make-gen-apply-c...r 29)) -(define-apply "##CDDDAR" #f (make-gen-apply-c...r 30)) -(define-apply "##CDDDDR" #f (make-gen-apply-c...r 31)) -(define-apply - "##MAKE-CELL" - #f - (lambda (opnds loc sn) (gen-cons (list (car opnds) (make-obj '())) loc sn))) -(define-apply "##CELL-REF" #f (make-gen-apply-c...r 2)) -(define-apply - "##CELL-SET!" - #t - (lambda (opnds loc sn) (gen-set-car! opnds loc sn))) -(define-apply "##VECTOR" #f (make-gen-vector 'vector)) -(define-apply "##VECTOR-LENGTH" #f (make-gen-vector-length 'vector)) -(define-apply "##VECTOR-REF" #f (make-gen-vector-ref 'vector)) -(define-apply "##VECTOR-SET!" #t (make-gen-vector-set! 'vector)) -(define-apply "##VECTOR-SHRINK!" #t (make-gen-vector-shrink! 'vector)) -(define-apply "##STRING" #f (make-gen-vector 'string)) -(define-apply "##STRING-LENGTH" #f (make-gen-vector-length 'string)) -(define-apply "##STRING-REF" #f (make-gen-vector-ref 'string)) -(define-apply "##STRING-SET!" #t (make-gen-vector-set! 'string)) -(define-apply "##STRING-SHRINK!" #t (make-gen-vector-shrink! 'string)) -(define-apply "##VECTOR8" #f (make-gen-vector 'vector8)) -(define-apply "##VECTOR8-LENGTH" #f (make-gen-vector-length 'vector8)) -(define-apply "##VECTOR8-REF" #f (make-gen-vector-ref 'vector8)) -(define-apply "##VECTOR8-SET!" #t (make-gen-vector-set! 'vector8)) -(define-apply "##VECTOR8-SHRINK!" #t (make-gen-vector-shrink! 'vector8)) -(define-apply "##VECTOR16" #f (make-gen-vector 'vector16)) -(define-apply "##VECTOR16-LENGTH" #f (make-gen-vector-length 'vector16)) -(define-apply "##VECTOR16-REF" #f (make-gen-vector-ref 'vector16)) -(define-apply "##VECTOR16-SET!" #t (make-gen-vector-set! 'vector16)) -(define-apply "##VECTOR16-SHRINK!" #t (make-gen-vector-shrink! 'vector16)) -(define-apply "##CLOSURE-CODE" #f (make-gen-slot-ref 1 type-procedure)) -(define-apply "##CLOSURE-REF" #f (make-gen-vector-ref 'closure)) -(define-apply "##CLOSURE-SET!" #t (make-gen-vector-set! 'closure)) -(define-apply - "##SUBPROCEDURE-ID" - #f - (lambda (opnds loc sn) (gen-subprocedure-id opnds loc sn))) -(define-apply - "##SUBPROCEDURE-PARENT" - #f - (lambda (opnds loc sn) (gen-subprocedure-parent opnds loc sn))) -(define-apply - "##RETURN-FS" - #f - (lambda (opnds loc sn) (gen-return-fs opnds loc sn))) -(define-apply - "##RETURN-LINK" - #f - (lambda (opnds loc sn) (gen-return-link opnds loc sn))) -(define-apply - "##PROCEDURE-INFO" - #f - (lambda (opnds loc sn) (gen-procedure-info opnds loc sn))) -(define-apply - "##PSTATE" - #f - (lambda (opnds loc sn) (move-opnd68-to-loc pstate-reg loc sn))) -(define-apply - "##MAKE-PLACEHOLDER" - #f - (lambda (opnds loc sn) (gen-make-placeholder opnds loc sn))) -(define-apply - "##TOUCH" - #t - (lambda (opnds loc sn) - (let ((opnd (car opnds))) - (if loc - (touch-opnd-to-loc opnd loc sn) - (touch-opnd-to-any-reg68 opnd sn))))) -(def-spec "NOT" (safe "##NOT")) -(def-spec "NULL?" (safe "##NULL?")) -(def-spec "EQ?" (safe "##EQ?")) -(def-spec "PAIR?" (safe "##PAIR?")) -(def-spec "PROCEDURE?" (safe "##PROCEDURE?")) -(def-spec "VECTOR?" (safe "##VECTOR?")) -(def-spec "SYMBOL?" (safe "##SYMBOL?")) -(def-spec "STRING?" (safe "##STRING?")) -(def-spec "CHAR?" (safe "##CHAR?")) -(def-spec "ZERO?" (safe-arith "##FIXNUM.ZERO?" "##FLONUM.ZERO?")) -(def-spec "POSITIVE?" (safe-arith "##FIXNUM.POSITIVE?" "##FLONUM.POSITIVE?")) -(def-spec "NEGATIVE?" (safe-arith "##FIXNUM.NEGATIVE?" "##FLONUM.NEGATIVE?")) -(def-spec "ODD?" (safe-arith "##FIXNUM.ODD?" #f)) -(def-spec "EVEN?" (safe-arith "##FIXNUM.EVEN?" #f)) -(def-spec "+" (unsafe-arith "##FIXNUM.+" "##FLONUM.+")) -(def-spec "*" (unsafe-arith "##FIXNUM.*" "##FLONUM.*")) -(def-spec "-" (unsafe-arith "##FIXNUM.-" "##FLONUM.-")) -(def-spec "/" (unsafe-arith #f "##FLONUM./")) -(def-spec "QUOTIENT" (unsafe-arith "##FIXNUM.QUOTIENT" #f)) -(def-spec "REMAINDER" (unsafe-arith "##FIXNUM.REMAINDER" #f)) -(def-spec "MODULO" (unsafe-arith "##FIXNUM.MODULO" #f)) -(def-spec "=" (safe-arith "##FIXNUM.=" "##FLONUM.=")) -(def-spec "<" (safe-arith "##FIXNUM.<" "##FLONUM.<")) -(def-spec ">" (safe-arith "##FIXNUM.>" "##FLONUM.>")) -(def-spec "<=" (safe-arith "##FIXNUM.<=" "##FLONUM.<=")) -(def-spec ">=" (safe-arith "##FIXNUM.>=" "##FLONUM.>=")) -(def-spec "ABS" (unsafe-arith #f "##FLONUM.ABS")) -(def-spec "TRUNCATE" (unsafe-arith #f "##FLONUM.TRUNCATE")) -(def-spec "EXP" (unsafe-arith #f "##FLONUM.EXP")) -(def-spec "LOG" (unsafe-arith #f "##FLONUM.LOG")) -(def-spec "SIN" (unsafe-arith #f "##FLONUM.SIN")) -(def-spec "COS" (unsafe-arith #f "##FLONUM.COS")) -(def-spec "TAN" (unsafe-arith #f "##FLONUM.TAN")) -(def-spec "ASIN" (unsafe-arith #f "##FLONUM.ASIN")) -(def-spec "ACOS" (unsafe-arith #f "##FLONUM.ACOS")) -(def-spec "ATAN" (unsafe-arith #f "##FLONUM.ATAN")) -(def-spec "SQRT" (unsafe-arith #f "##FLONUM.SQRT")) -(def-spec "CHAR=?" (safe "##CHAR=?")) -(def-spec "CHAR?" (safe "##CHAR>?")) -(def-spec "CHAR<=?" (safe "##CHAR<=?")) -(def-spec "CHAR>=?" (safe "##CHAR>=?")) -(def-spec "CONS" (safe "##CONS")) -(def-spec "SET-CAR!" (unsafe "##SET-CAR!")) -(def-spec "SET-CDR!" (unsafe "##SET-CDR!")) -(def-spec "CAR" (unsafe "##CAR")) -(def-spec "CDR" (unsafe "##CDR")) -(def-spec "CAAR" (unsafe "##CAAR")) -(def-spec "CADR" (unsafe "##CADR")) -(def-spec "CDAR" (unsafe "##CDAR")) -(def-spec "CDDR" (unsafe "##CDDR")) -(def-spec "CAAAR" (unsafe "##CAAAR")) -(def-spec "CAADR" (unsafe "##CAADR")) -(def-spec "CADAR" (unsafe "##CADAR")) -(def-spec "CADDR" (unsafe "##CADDR")) -(def-spec "CDAAR" (unsafe "##CDAAR")) -(def-spec "CDADR" (unsafe "##CDADR")) -(def-spec "CDDAR" (unsafe "##CDDAR")) -(def-spec "CDDDR" (unsafe "##CDDDR")) -(def-spec "CAAAAR" (unsafe "##CAAAAR")) -(def-spec "CAAADR" (unsafe "##CAAADR")) -(def-spec "CAADAR" (unsafe "##CAADAR")) -(def-spec "CAADDR" (unsafe "##CAADDR")) -(def-spec "CADAAR" (unsafe "##CADAAR")) -(def-spec "CADADR" (unsafe "##CADADR")) -(def-spec "CADDAR" (unsafe "##CADDAR")) -(def-spec "CADDDR" (unsafe "##CADDDR")) -(def-spec "CDAAAR" (unsafe "##CDAAAR")) -(def-spec "CDAADR" (unsafe "##CDAADR")) -(def-spec "CDADAR" (unsafe "##CDADAR")) -(def-spec "CDADDR" (unsafe "##CDADDR")) -(def-spec "CDDAAR" (unsafe "##CDDAAR")) -(def-spec "CDDADR" (unsafe "##CDDADR")) -(def-spec "CDDDAR" (unsafe "##CDDDAR")) -(def-spec "CDDDDR" (unsafe "##CDDDDR")) -(def-spec "VECTOR" (safe "##VECTOR")) -(def-spec "VECTOR-LENGTH" (unsafe "##VECTOR-LENGTH")) -(def-spec "VECTOR-REF" (unsafe "##VECTOR-REF")) -(def-spec "VECTOR-SET!" (unsafe "##VECTOR-SET!")) -(def-spec "STRING" (safe "##STRING")) -(def-spec "STRING-LENGTH" (unsafe "##STRING-LENGTH")) -(def-spec "STRING-REF" (unsafe "##STRING-REF")) -(def-spec "STRING-SET!" (unsafe "##STRING-SET!")) -(def-spec "TOUCH" (safe "##TOUCH")) -(let ((targ (make-target 4 'm68000))) - (target-begin!-set! targ (lambda (info-port) (begin! info-port targ))) - (put-target targ)) - -(define input-source-code ' -(begin -(declare (standard-bindings) (fixnum) (not safe) (block)) - -(define (fib n) - (if (< n 2) - n - (+ (fib (- n 1)) - (fib (- n 2))))) - -(define (tak x y z) - (if (not (< y x)) - z - (tak (tak (- x 1) y z) - (tak (- y 1) z x) - (tak (- z 1) x y)))) - -(define (ack m n) - (cond ((= m 0) (+ n 1)) - ((= n 0) (ack (- m 1) 1)) - (else (ack (- m 1) (ack m (- n 1)))))) - -(define (create-x n) - (define result (make-vector n)) - (do ((i 0 (+ i 1))) - ((>= i n) result) - (vector-set! result i i))) - -(define (create-y x) - (let* ((n (vector-length x)) - (result (make-vector n))) - (do ((i (- n 1) (- i 1))) - ((< i 0) result) - (vector-set! result i (vector-ref x i))))) - -(define (my-try n) - (vector-length (create-y (create-x n)))) - -(define (go n) - (let loop ((repeat 100) - (result 0)) - (if (> repeat 0) - (loop (- repeat 1) (my-try n)) - result))) - -(+ (fib 20) - (tak 18 12 6) - (ack 3 9) - (go 200000)) -)) - -(define output-expected '( -"|------------------------------------------------------" -"| #[primitive #!program] =" -"L1:" -" cmpw #1,d0" -" beq L1000" -" TRAP1(9,0)" -" LBL_PTR(L1)" -"L1000:" -" MOVE_PROC(1,a1)" -" movl a1,GLOB(fib)" -" MOVE_PROC(2,a1)" -" movl a1,GLOB(tak)" -" MOVE_PROC(3,a1)" -" movl a1,GLOB(ack)" -" MOVE_PROC(4,a1)" -" movl a1,GLOB(create-x)" -" MOVE_PROC(5,a1)" -" movl a1,GLOB(create-y)" -" MOVE_PROC(6,a1)" -" movl a1,GLOB(my-try)" -" MOVE_PROC(7,a1)" -" movl a1,GLOB(go)" -" movl a0,sp@-" -" movl #160,d1" -" lea L2,a0" -" dbra d5,L1001" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1001" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1002:" -"L1001:" -" JMP_PROC(1,10)" -" RETURN(L1,1,1)" -"L2:" -" movl d1,sp@-" -" moveq #48,d3" -" moveq #96,d2" -" movl #144,d1" -" lea L3,a0" -" JMP_PROC(2,14)" -" RETURN(L1,2,1)" -"L3:" -" movl d1,sp@-" -" moveq #72,d2" -" moveq #24,d1" -" lea L4,a0" -" JMP_PROC(3,10)" -" RETURN(L1,3,1)" -"L4:" -" movl d1,sp@-" -" movl #1600000,d1" -" lea L5,a0" -" JMP_PROC(7,10)" -" RETURN(L1,4,1)" -"L5:" -" dbra d5,L1003" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1003" -" TRAP2(24)" -" RETURN(L1,4,1)" -"L1004:" -"L1003:" -"L6:" -" addl sp@(8),d1" -" addl sp@(4),d1" -" addl sp@+,d1" -" addql #8,sp" -" rts" -"L0:" -"|------------------------------------------------------" -"| #[primitive fib] =" -"L1:" -" bmi L1000" -" TRAP1(9,1)" -" LBL_PTR(L1)" -"L1000:" -" moveq #16,d0" -" cmpl d1,d0" -" ble L3" -" bra L4" -" RETURN(L1,2,1)" -"L2:" -" movl d1,sp@-" -" movl sp@(4),d1" -" moveq #-16,d0" -" addl d0,d1" -" lea L5,a0" -" moveq #16,d0" -" cmpl d1,d0" -" bgt L4" -"L3:" -" movl a0,sp@-" -" movl d1,sp@-" -" subql #8,d1" -" lea L2,a0" -" dbra d5,L1001" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1001" -" TRAP2(24)" -" RETURN(L1,2,1)" -"L1002:" -"L1001:" -" moveq #16,d0" -" cmpl d1,d0" -" ble L3" -"L4:" -" jmp a0@" -" RETURN(L1,3,1)" -"L5:" -" addl sp@+,d1" -" dbra d5,L1003" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1003" -" TRAP2(24)" -" RETURN(L1,2,1)" -"L1004:" -"L1003:" -" addql #4,sp" -" rts" -"L0:" -"|------------------------------------------------------" -"| #[primitive tak] =" -"L1:" -" cmpw #4,d0" -" beq L1000" -" TRAP1(9,3)" -" LBL_PTR(L1)" -"L1000:" -" cmpl d1,d2" -" bge L4" -" bra L3" -" RETURN(L1,6,1)" -"L2:" -" movl d1,d3" -" movl sp@(20),a0" -" movl sp@+,d2" -" movl sp@+,d1" -" dbra d5,L1001" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1001" -" movl a0,sp@(12)" -" TRAP2(24)" -" RETURN(L1,4,1)" -"L1002:" -" movl sp@(12),a0" -"L1001:" -" cmpl d1,d2" -" lea sp@(16),sp" -" bge L4" -"L3:" -" movl a0,sp@-" -" movl d1,sp@-" -" movl d2,sp@-" -" movl d3,sp@-" -" subql #8,d1" -" lea L5,a0" -" dbra d5,L1003" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1003" -" TRAP2(24)" -" RETURN(L1,4,1)" -"L1004:" -"L1003:" -" cmpl d1,d2" -" blt L3" -"L4:" -" movl d3,d1" -" jmp a0@" -" RETURN(L1,4,1)" -"L5:" -" movl d1,sp@-" -" movl sp@(12),d3" -" movl sp@(4),d2" -" movl sp@(8),d1" -" subql #8,d1" -" lea L6,a0" -" cmpl d1,d2" -" bge L4" -" bra L3" -" RETURN(L1,5,1)" -"L6:" -" movl d1,sp@-" -" movl sp@(12),d3" -" movl sp@(16),d2" -" movl sp@(8),d1" -" subql #8,d1" -" lea L2,a0" -" cmpl d1,d2" -" bge L4" -" bra L3" -"L0:" -"|------------------------------------------------------" -"| #[primitive ack] =" -"L1:" -" beq L1000" -" TRAP1(9,2)" -" LBL_PTR(L1)" -"L1000:" -" movl d1,d0" -" bne L3" -" bra L5" -" RETURN(L1,2,1)" -"L2:" -" movl d1,d2" -" movl sp@+,d1" -" subql #8,d1" -" movl sp@+,a0" -" dbra d5,L1001" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1001" -" movl a0,sp@-" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1002:" -" movl sp@+,a0" -"L1001:" -" movl d1,d0" -" beq L5" -"L3:" -" movl d2,d0" -" bne L6" -"L4:" -" subql #8,d1" -" moveq #8,d2" -" dbra d5,L1003" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1003" -" movl a0,sp@-" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1004:" -" movl sp@+,a0" -"L1003:" -" movl d1,d0" -" bne L3" -"L5:" -" movl d2,d1" -" addql #8,d1" -" jmp a0@" -"L6:" -" movl a0,sp@-" -" movl d1,sp@-" -" movl d2,d1" -" subql #8,d1" -" movl d1,d2" -" movl sp@,d1" -" lea L2,a0" -" dbra d5,L1005" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1005" -" TRAP2(24)" -" RETURN(L1,2,1)" -"L1006:" -"L1005:" -" movl d1,d0" -" bne L3" -" bra L5" -"L0:" -"|------------------------------------------------------" -"| #[primitive create-x] =" -"L1:" -" bmi L1000" -" TRAP1(9,1)" -" LBL_PTR(L1)" -"L1000:" -" movl a0,sp@-" -" movl d1,sp@-" -" lea L2,a0" -" dbra d5,L1001" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1001" -" TRAP2(24)" -" RETURN(L1,2,1)" -"L1002:" -"L1001:" -" moveq #-1,d0" -" JMP_PRIM(make-vector,0)" -" RETURN(L1,2,1)" -"L2:" -" movl d1,d2" -" movl sp@+,d1" -" moveq #0,d3" -" movl sp@+,a0" -" dbra d5,L1003" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1003" -" movl a0,sp@-" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1004:" -" movl sp@+,a0" -"L1003:" -" cmpl d1,d3" -" bge L4" -"L3:" -" movl d3,d0" -" asrl #1,d0" -" movl d2,a1" -" movl d3,a1@(1,d0:l)" -" addql #8,d3" -" dbra d5,L1005" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1005" -" movl a0,sp@-" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1006:" -" movl sp@+,a0" -"L1005:" -" cmpl d1,d3" -" blt L3" -"L4:" -" movl d2,d1" -" jmp a0@" -"L0:" -"|------------------------------------------------------" -"| #[primitive create-y] =" -"L1:" -" bmi L1000" -" TRAP1(9,1)" -" LBL_PTR(L1)" -"L1000:" -" movl d1,a1" -" movl a1@(-3),d2" -" lsrl #7,d2" -" movl a0,sp@-" -" movl d1,sp@-" -" movl d2,sp@-" -" movl d2,d1" -" lea L2,a0" -" dbra d5,L1001" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1001" -" TRAP2(24)" -" RETURN(L1,3,1)" -"L1002:" -"L1001:" -" moveq #-1,d0" -" JMP_PRIM(make-vector,0)" -" RETURN(L1,3,1)" -"L2:" -" movl sp@+,d2" -" subql #8,d2" -" movl d2,d3" -" movl d1,d2" -" movl sp@+,d1" -" movl sp@+,a0" -" dbra d5,L1003" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1003" -" movl a0,sp@-" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1004:" -" movl sp@+,a0" -"L1003:" -" movl d3,d0" -" blt L4" -"L3:" -" movl d3,d0" -" asrl #1,d0" -" movl d1,a1" -" movl a1@(1,d0:l),d4" -" movl d3,d0" -" asrl #1,d0" -" movl d2,a1" -" movl d4,a1@(1,d0:l)" -" subql #8,d3" -" dbra d5,L1005" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1005" -" movl a0,sp@-" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1006:" -" movl sp@+,a0" -"L1005:" -" movl d3,d0" -" bge L3" -"L4:" -" movl d2,d1" -" jmp a0@" -"L0:" -"|------------------------------------------------------" -"| #[primitive my-try] =" -"L1:" -" bmi L1000" -" TRAP1(9,1)" -" LBL_PTR(L1)" -"L1000:" -" movl a0,sp@-" -" lea L2,a0" -" dbra d5,L1001" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1001" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1002:" -"L1001:" -" JMP_PROC(4,10)" -" RETURN(L1,1,1)" -"L2:" -" lea L3,a0" -" JMP_PROC(5,10)" -" RETURN(L1,1,1)" -"L3:" -" movl d1,a1" -" movl a1@(-3),d1" -" lsrl #7,d1" -" dbra d5,L1003" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1003" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1004:" -"L1003:" -" rts" -"L0:" -"|------------------------------------------------------" -"| #[primitive go] =" -"L1:" -" bmi L1000" -" TRAP1(9,1)" -" LBL_PTR(L1)" -"L1000:" -" moveq #0,d3" -" movl #800,d2" -" dbra d5,L1001" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1001" -" movl a0,sp@-" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1002:" -" movl sp@+,a0" -"L1001:" -" movl d2,d0" -" ble L4" -" bra L3" -" RETURN(L1,3,1)" -"L2:" -" movl d1,d3" -" movl sp@+,d1" -" subql #8,d1" -" movl d1,d2" -" movl sp@+,d1" -" movl sp@+,a0" -" dbra d5,L1003" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1003" -" movl a0,sp@-" -" TRAP2(24)" -" RETURN(L1,1,1)" -"L1004:" -" movl sp@+,a0" -"L1003:" -" movl d2,d0" -" ble L4" -"L3:" -" movl a0,sp@-" -" movl d1,sp@-" -" movl d2,sp@-" -" lea L2,a0" -" dbra d5,L1005" -" moveq #9,d5" -" cmpl a5@,sp" -" bcc L1005" -" TRAP2(24)" -" RETURN(L1,3,1)" -"L1006:" -"L1005:" -" JMP_PROC(6,10)" -"L4:" -" movl d3,d1" -" jmp a0@" -"L0:" -"")) - -(define (main . args) - (run-benchmark - "compiler" - compiler-iters - (lambda (result) - (equal? result output-expected)) - (lambda (expr target opt) (lambda () (ce expr target opt) (asm-output-get))) - input-source-code - 'm68000 - 'asm)) -; compiler compiler diff --git a/benchmarks/sys/petite-chez/tak-prefix.scm b/benchmarks/sys/petite-chez/tak-prefix.scm deleted file mode 100644 index 132119b..0000000 --- a/benchmarks/sys/petite-chez/tak-prefix.scm +++ /dev/null @@ -1 +0,0 @@ -; tak tak diff --git a/benchmarks/sys/petite-chez/tak-suffix.scm b/benchmarks/sys/petite-chez/tak-suffix.scm deleted file mode 100644 index 132119b..0000000 --- a/benchmarks/sys/petite-chez/tak-suffix.scm +++ /dev/null @@ -1 +0,0 @@ -; tak tak diff --git a/benchmarks/sys/petite-chez/tak.scm b/benchmarks/sys/petite-chez/tak.scm deleted file mode 100644 index 62f2995..0000000 --- a/benchmarks/sys/petite-chez/tak.scm +++ /dev/null @@ -1,513 +0,0 @@ -; tak tak -(define-syntax if-fixflo (syntax-rules () ((if-fixflo yes no) no))) -;------------------------------------------------------------------------------ - -(define (run-bench name count ok? run) - (let loop ((i 0) (result (list 'undefined))) - (if (< i count) - (loop (+ i 1) (run)) - result))) - -(define (run-benchmark name count ok? run-maker . args) - (newline) - (let* ((run (apply run-maker args)) - (result (time (run-bench name count ok? run)))) - (if (not (ok? result)) - (begin - (display "*** wrong result ***") - (newline) - (display "*** got: ") - (write result) - (newline)))) - (exit 0)) - -(define (fatal-error . args) - (apply error #f args)) - - (define (call-with-output-file/truncate filename proc) - (call-with-output-file filename proc 'truncate)) - -;------------------------------------------------------------------------------ - -; Macros... - -(if-fixflo - -(begin - -; Specialize fixnum and flonum arithmetic. - -(define-syntax FLOATvector-const - (syntax-rules () - ((FLOATvector-const x ...) '#(x ...)))) - -(define-syntax FLOATvector? - (syntax-rules () - ((FLOATvector? x) (vector? x)))) - -(define-syntax FLOATvector - (syntax-rules () - ((FLOATvector x ...) (vector x ...)))) - -(define-syntax FLOATmake-vector - (syntax-rules () - ((FLOATmake-vector n) (make-vector n 0.0)) - ((FLOATmake-vector n init) (make-vector n init)))) - -(define-syntax FLOATvector-ref - (syntax-rules () - ((FLOATvector-ref v i) (vector-ref v i)))) - -(define-syntax FLOATvector-set! - (syntax-rules () - ((FLOATvector-set! v i x) (vector-set! v i x)))) - -(define-syntax FLOATvector-length - (syntax-rules () - ((FLOATvector-length v) (vector-length v)))) - -(define-syntax nuc-const - (syntax-rules () - ((FLOATnuc-const x ...) '#(x ...)))) - -(define-syntax FLOAT+ - (syntax-rules () - ((FLOAT+ x ...) (fl+ x ...)))) - -(define-syntax FLOAT- - (syntax-rules () - ((FLOAT- x ...) (fl- x ...)))) - -(define-syntax FLOAT* - (syntax-rules () - ((FLOAT* x ...) (fl* x ...)))) - -(define-syntax FLOAT/ - (syntax-rules () - ((FLOAT/ x ...) (fl/ x ...)))) - -(define-syntax FLOAT= - (syntax-rules () - ((FLOAT= x y) (fl= x y)))) - -(define-syntax FLOAT< - (syntax-rules () - ((FLOAT< x y) (fl< x y)))) - -(define-syntax FLOAT<= - (syntax-rules () - ((FLOAT<= x y) (fl<= x y)))) - -(define-syntax FLOAT> - (syntax-rules () - ((FLOAT> x y) (fl> x y)))) - -(define-syntax FLOAT>= - (syntax-rules () - ((FLOAT>= x y) (fl>= x y)))) - -(define-syntax FLOATnegative? - (syntax-rules () - ((FLOATnegative? x) (fl< x 0.0)))) - -(define-syntax FLOATpositive? - (syntax-rules () - ((FLOATpositive? x) (fl< 0.0 x)))) - -(define-syntax FLOATzero? - (syntax-rules () - ((FLOATzero? x) (fl= 0.0 x)))) - -(define-syntax FLOATabs - (syntax-rules () - ((FLOATabs x) (flabs x)))) - -(define-syntax FLOATsin - (syntax-rules () - ((FLOATsin x) (sin x)))) - -(define-syntax FLOATcos - (syntax-rules () - ((FLOATcos x) (cos x)))) - -(define-syntax FLOATatan - (syntax-rules () - ((FLOATatan x) (atan x)))) - -(define-syntax FLOATsqrt - (syntax-rules () - ((FLOATsqrt x) (sqrt x)))) - -(define-syntax FLOATmin - (syntax-rules () - ((FLOATmin x y) (min x y)))) - -(define-syntax FLOATmax - (syntax-rules () - ((FLOATmax x y) (max x y)))) - -(define-syntax FLOATround - (syntax-rules () - ((FLOATround x) (round x)))) - -(define-syntax FLOATinexact->exact - (syntax-rules () - ((FLOATinexact->exact x) (inexact->exact x)))) - -(define (GENERIC+ x y) (+ x y)) -(define (GENERIC- x y) (- x y)) -(define (GENERIC* x y) (* x y)) -(define (GENERIC/ x y) (/ x y)) -(define (GENERICquotient x y) (quotient x y)) -(define (GENERICremainder x y) (remainder x y)) -(define (GENERICmodulo x y) (modulo x y)) -(define (GENERIC= x y) (= x y)) -(define (GENERIC< x y) (< x y)) -(define (GENERIC<= x y) (<= x y)) -(define (GENERIC> x y) (> x y)) -(define (GENERIC>= x y) (>= x y)) -(define (GENERICexpt x y) (expt x y)) - -(define-syntax + - (syntax-rules () - ((+ x ...) (fx+ x ...)))) - -(define-syntax - - (syntax-rules () - ((- x ...) (fx- x ...)))) - -(define-syntax * - (syntax-rules () - ((* x ...) (fx* x ...)))) - -(define-syntax quotient - (syntax-rules () - ((quotient x ...) (fxquotient x ...)))) - -(define-syntax modulo - (syntax-rules () - ((modulo x ...) (fxmodulo x ...)))) - -(define-syntax remainder - (syntax-rules () - ((remainder x ...) (fxremainder x ...)))) - -(define-syntax = - (syntax-rules () - ((= x y) (fx= x y)))) - -(define-syntax < - (syntax-rules () - ((< x y) (fx< x y)))) - -(define-syntax <= - (syntax-rules () - ((<= x y) (fx<= x y)))) - -(define-syntax > - (syntax-rules () - ((> x y) (fx> x y)))) - -(define-syntax >= - (syntax-rules () - ((>= x y) (fx>= x y)))) - -(define-syntax negative? - (syntax-rules () - ((negative? x) (fxnegative? x)))) - -(define-syntax positive? - (syntax-rules () - ((positive? x) (fxpositive? x)))) - -(define-syntax zero? - (syntax-rules () - ((zero? x) (fxzero? x)))) - -(define-syntax odd? - (syntax-rules () - ((odd? x) (fxodd? x)))) - -(define-syntax even? - (syntax-rules () - ((even? x) (fxeven? x)))) - -; FIXME - -;(define-syntax bitwise-or -; (syntax-rules () -; ((bitwise-or x y) (fxior x y)))) - -;(define-syntax bitwise-and -; (syntax-rules () -; ((bitwise-and x y) (fxand x y)))) - -;(define-syntax bitwise-not -; (syntax-rules () -; ((bitwise-not x) (fxnot x)))) -) - -(begin - -; Don't specialize fixnum and flonum arithmetic. - -(define-syntax FLOATvector-const - (syntax-rules () - ((FLOATvector-const x ...) '#(x ...)))) - -(define-syntax FLOATvector? - (syntax-rules () - ((FLOATvector? x) (vector? x)))) - -(define-syntax FLOATvector - (syntax-rules () - ((FLOATvector x ...) (vector x ...)))) - -(define-syntax FLOATmake-vector - (syntax-rules () - ((FLOATmake-vector n) (make-vector n 0.0)) - ((FLOATmake-vector n init) (make-vector n init)))) - -(define-syntax FLOATvector-ref - (syntax-rules () - ((FLOATvector-ref v i) (vector-ref v i)))) - -(define-syntax FLOATvector-set! - (syntax-rules () - ((FLOATvector-set! v i x) (vector-set! v i x)))) - -(define-syntax FLOATvector-length - (syntax-rules () - ((FLOATvector-length v) (vector-length v)))) - -(define-syntax nuc-const - (syntax-rules () - ((FLOATnuc-const x ...) '#(x ...)))) - -(define-syntax FLOAT+ - (syntax-rules () - ((FLOAT+ x ...) (+ x ...)))) - -(define-syntax FLOAT- - (syntax-rules () - ((FLOAT- x ...) (- x ...)))) - -(define-syntax FLOAT* - (syntax-rules () - ((FLOAT* x ...) (* x ...)))) - -(define-syntax FLOAT/ - (syntax-rules () - ((FLOAT/ x ...) (/ x ...)))) - -(define-syntax FLOAT= - (syntax-rules () - ((FLOAT= x y) (= x y)))) - -(define-syntax FLOAT< - (syntax-rules () - ((FLOAT< x y) (< x y)))) - -(define-syntax FLOAT<= - (syntax-rules () - ((FLOAT<= x y) (<= x y)))) - -(define-syntax FLOAT> - (syntax-rules () - ((FLOAT> x y) (> x y)))) - -(define-syntax FLOAT>= - (syntax-rules () - ((FLOAT>= x y) (>= x y)))) - -(define-syntax FLOATnegative? - (syntax-rules () - ((FLOATnegative? x) (negative? x)))) - -(define-syntax FLOATpositive? - (syntax-rules () - ((FLOATpositive? x) (positive? x)))) - -(define-syntax FLOATzero? - (syntax-rules () - ((FLOATzero? x) (zero? x)))) - -(define-syntax FLOATabs - (syntax-rules () - ((FLOATabs x) (abs x)))) - -(define-syntax FLOATsin - (syntax-rules () - ((FLOATsin x) (sin x)))) - -(define-syntax FLOATcos - (syntax-rules () - ((FLOATcos x) (cos x)))) - -(define-syntax FLOATatan - (syntax-rules () - ((FLOATatan x) (atan x)))) - -(define-syntax FLOATsqrt - (syntax-rules () - ((FLOATsqrt x) (sqrt x)))) - -(define-syntax FLOATmin - (syntax-rules () - ((FLOATmin x y) (min x y)))) - -(define-syntax FLOATmax - (syntax-rules () - ((FLOATmax x y) (max x y)))) - -(define-syntax FLOATround - (syntax-rules () - ((FLOATround x) (round x)))) - -(define-syntax FLOATinexact->exact - (syntax-rules () - ((FLOATinexact->exact x) (inexact->exact x)))) - -; Generic arithmetic. - -(define-syntax GENERIC+ - (syntax-rules () - ((GENERIC+ x ...) (+ x ...)))) - -(define-syntax GENERIC- - (syntax-rules () - ((GENERIC- x ...) (- x ...)))) - -(define-syntax GENERIC* - (syntax-rules () - ((GENERIC* x ...) (* x ...)))) - -(define-syntax GENERIC/ - (syntax-rules () - ((GENERIC/ x ...) (/ x ...)))) - -(define-syntax GENERICquotient - (syntax-rules () - ((GENERICquotient x y) (quotient x y)))) - -(define-syntax GENERICremainder - (syntax-rules () - ((GENERICremainder x y) (remainder x y)))) - -(define-syntax GENERICmodulo - (syntax-rules () - ((GENERICmodulo x y) (modulo x y)))) - -(define-syntax GENERIC= - (syntax-rules () - ((GENERIC= x y) (= x y)))) - -(define-syntax GENERIC< - (syntax-rules () - ((GENERIC< x y) (< x y)))) - -(define-syntax GENERIC<= - (syntax-rules () - ((GENERIC<= x y) (<= x y)))) - -(define-syntax GENERIC> - (syntax-rules () - ((GENERIC> x y) (> x y)))) - -(define-syntax GENERIC>= - (syntax-rules () - ((GENERIC>= x y) (>= x y)))) - -(define-syntax GENERICexpt - (syntax-rules () - ((GENERICexpt x y) (expt x y)))) -) -) - -;------------------------------------------------------------------------------ -; Gabriel benchmarks -(define boyer-iters 20) -(define browse-iters 600) -(define cpstak-iters 1000) -(define ctak-iters 100) -(define dderiv-iters 2000000) -(define deriv-iters 2000000) -(define destruc-iters 500) -(define diviter-iters 1000000) -(define divrec-iters 1000000) -(define puzzle-iters 100) -(define tak-iters 2000) -(define takl-iters 300) -(define trav1-iters 100) -(define trav2-iters 20) -(define triangl-iters 10) - -; Kernighan and Van Wyk benchmarks -(define ack-iters 1) -(define array1-iters 1) -(define cat-iters 1) -(define string-iters 1) -(define sum1-iters 1) -(define sumloop-iters 1) -(define tail-iters 1) -(define wc-iters 1) - -; C benchmarks -(define fft-iters 2000) -(define fib-iters 5) -(define fibfp-iters 2) -(define mbrot-iters 100) -(define nucleic-iters 5) -(define pnpoly-iters 100000) -(define sum-iters 10000) -(define sumfp-iters 5000) -(define tfib-iters 20) - -; Other benchmarks -(define conform-iters 40) -(define dynamic-iters 20) -(define earley-iters 200) -(define fibc-iters 500) -(define graphs-iters 300) -(define lattice-iters 1) -(define matrix-iters 400) -(define maze-iters 4000) -(define mazefun-iters 1000) -(define nqueens-iters 2000) -(define paraffins-iters 1000) -(define peval-iters 200) -(define pi-iters 2) -(define primes-iters 100000) -(define ray-iters 5) -(define scheme-iters 20000) -(define simplex-iters 100000) -(define slatex-iters 20) -(define perm9-iters 10) -(define nboyer-iters 100) -(define sboyer-iters 100) -(define gcbench-iters 1) -(define compiler-iters 300) - -; New benchmarks -(define parsing-iters 1000) -(define gcold-iters 10000) -;(define nbody-iters 1) ; nondeterministic (order of evaluation) -;;; TAK -- A vanilla version of the TAKeuchi function. - -(define (tak x y z) - (if (not (< y x)) - z - (tak (tak (- x 1) y z) - (tak (- y 1) z x) - (tak (- z 1) x y)))) - -(define (main . args) - (run-benchmark - "tak" - tak-iters - (lambda (result) (equal? result 7)) - (lambda (x y z) (lambda () (tak x y z))) - 18 - 12 - 6)) -; tak tak diff --git a/src/altmakefile.ss b/src/altmakefile.ss index f6cd0c6..7aeef5c 100755 --- a/src/altmakefile.ss +++ b/src/altmakefile.ss @@ -98,7 +98,7 @@ exact? inexact? integer? string->number exact->inexact - flonum? flonum->string string->flonum + flonum? flonum->string string->flonum bignum? sin cos atan sqrt )) diff --git a/src/ikarus.boot b/src/ikarus.boot index e19318ac77136ab8a6c730af53afd19787b571d1..84f014fd3b2a424aae9add9a8815a27137275ac7 100644 GIT binary patch literal 2855617 zcmdqK4R}@6nKpa^L1RfxTB%JdYQ(5fi3GJ4YKQ@UV7H(|DAJk=fdohmNen@b)hZfj ziJ^+swzNe>r8CS(Emm~SR4fQ|U@Wa^_3GqmsiHD%_B2!TPBZP95+~n%KWneO*V;K} zpB#{R=X>`BCwuMntiR`f{hwRqe5QP2yfmhs#Gk%%an7#$9*O0&??1I;daU!hu`dti zzx?|VIm!K1u|YhEdjPq2UM_x}h4`t=!OyHYr{Z^c?XC4?Ew!z+%j?_fTb)9Ds*Zne z1peS@PYx8U-H(^fYf1(>`2XGZ{dt|&lWbS2*wnnyu#Qc$aV0h_uBX6cJ#C#7}frhy!};2S*OmskaK+SI11Q;tiuJ2 zlmgx>T>YC7s(_rm?a5@p+BK+5ruOuuXiuKB=cIg8cp++S6qlF2Jt!#Ie)#0}`UG)L04TbJ$K-9cRh;e3Ih@bIz zt0eEnPr(nL&MA`~j^zw4eQ(}Kgq%|T5PsI2)A3ufd}U)>LrY_Q+3mHBE9+O3)wi}b zw>s-C@SrN0Xx1DOPQ@HP9|e$Q=X?Y|cdsaJSW(>6+*Vv$+|t^-xV~;>YrV6OFifHn z*0!`X-r@9~r>h4_#^Ocz;e+N5{G}UYOm0lR?zA!COY zh2*=fq%&ijp3z=2D@bRj6dWNasu23FMsq7jA1B5)Qo&gdTnJ}W5cSSRd{jZnVA8o> zuoChSi&HW3**lNFPW&AFkY6f^&{=a(c&x6utoio()+LS2tDHR0#mKB1bX7rS<`jL@ zORXwb4wj4Ho9$q!3YPC2_>h%N9vZIN$Vxafpn;^2__YYKv1temmJ>pE-UGvsTF^ZT zz1W->R01*<`KcBNvbu?0N>znw5Rhurv3Vdt5PNRONImyoFjC{PFjA)6k@VH^ zz4+zB_CEN$_p%;UjJAWR3XK&8l$-gal;0gqD_T4o5FWv3C3uou-rkIIs z>YS4I%~+00^T$V!E^n|-^XD(PaGzw?@rB&ZvAG>zh;{s-eQyqoN&D_x3eW@ZfEg(_ zB1Fvd6OedcR$?#4ZbV&JVDw3aJ*U#fx&TK8Y9TUbVUnSQ|Jr8JPxp-_?x`@6hT(Mcn7c%?u%!GkI4OwFSTN@P6RW>fW-*iwHi#WbXOkU z1Os9whsy9*P+vZxv*LK^95v(H;`GQ@ljQ61#U#0y$x(Rw-9J$%$W^sCYs*omHIko67-=`Zq&HWd~HR-7Goo_ z@Hl|%wxn_8ie+WZE8ALDww1Lsx3)QPB1lv!USdvyKT2j!!|USarWMWbM~oCOG! z%NNzR7B?>`hPGb0yuPWexb*H77Z$fQ7vH_Y=?h_$ET0LZM}G>8UX%q!BOP*u#T`T; z9x?xaJqdl%fzNzS{`Zu6v zach0s%GRd(Iudt9L(|g6`eKPJhU#gnkGDB3$j20*B(i>9`b4P086cI?vv`r`m|VOPP&lQFcR4K~A_Et%97K`+@HN*? z`|Nbb?*W9(px+l5(q{_m-jNT3FQpDJYtqVU8##} z6-Go|tfikt4`ANROLC(9^__sUiTPqPh?$SifuD6Eh&jnu>&HdRF;wrV{Phy3ZJU@~ zXww`zkO2mVQ0Frfa&~>-scfjjk&(9Mma@kB+v^+Ez=}nepCX=*NbyT}p%lv)*@%L* zU-iONpq-;OKACzvu@_K=XNYdugn~8adr1R(`t}pbb3W;@ODv7d0*6Aquz5I8*KM(( z+)vy9?l=o&J9mLcPMFuT5T;`eHHtatwBnBCi<%pq!=Rz(k&y5qpgd>SqQA`sXS5(o;f}RYPne$SL-%-yo?6lnM;F6sL7bZuT1EEdZjZ`}ZGptMa=cS1zlgw?=huYx>(-I_glR;*lfoa9-AQpx3SEGOCW>bT*_zS~x7F{oG1m@YhdggF%i+ zE{R`U)^>b)REYx)#0_r~g{cKQ2 zw@RZ<&l0L$#tn$!BSSk=@dEXYej{8=4DGbPGqU|CR5<(1E>ssI{c&B5)a$++Lh7^4 z8mT+M5+_VkZ>DxlgVbWg&6-0ef=JyO_+b7BKv?5mJ^s?1T{k|H4N_S)k*c-3#gjA$ zd<3r-;l&$n0bWgGsFC>NcP9GU);(~8M&L{|;e;Vj2GZC&)(!AR$~4;MYZGO-++noc zd;n!Ctv?X8G4S74TuQZ()U(^}XD7VC zng66Wl-%#l2={5qdJ7~AByf*~B=2a$^4_!dN)96xX(2R^#N9;%%lQ|PrBMFB5EK+R-K z_Hyv#bJ_4DZBt20Ys2z}wuam5%M^Pq_So~w#5Nvb&t|+FH=iGzN1w#mq_LxvUlFT?=Y5=3SQnt#6x0Mqd#G6AZ{mlpt6<{+ zRk)hbMwQcHCc^@|avL+Uz)oYP>tT%<;)IS?XFMk`SkzLc7I5p{eV)c93#lu$jZLom z45jXLWbE|#tbSZlR|<|DB6X`_I3lDj7P2$zQ3IiXQq*zMNeEJdijp9m3vxPc8Pj=7 zJ}L7c)mp)NnlUQVjzd_WxwrifxgCc(Z;lNv{tI3wA1YXjOk(Q8KjJOc?&fxm$?q65 zdh&sSweJE88k_?aF(*$mfm%8d63`j6Bs4bOGP;nIIy1C)s|F0$X)jY&OL;QU zem3cyj-k92sM}}0J;Gm#V<=LJ+QNx%p@`wEK%J3d?PLE8)Sz=zx&qc9Ypa09lKy*V zmh=M$vG$+L0M7fd3W*k>eSdK$CwFT~`tHR9Z#lD7;UvPzDlfeM>h}r{|8@kUI_CoX z^Er4OP_Lu7qO$9^BRa6G4<9?`kJ>-|y~5r2FrAA@`#YwO5+YAO1%LVoya74kwIj~> z0aT+;!C-|j)@Dj1za~`%eY-|{@9h!k))yd$BEI%4M#|7rv}o zB6=1VbG(lK1|167YOH<)>-45$og?s(!jv5&D~~FvPsiGn9mB=GoF$YR#Ru`HU(FIy z7qKk0Ft;aNafeeBS0u&V&4Ge$aE#G_qM^n0pg5G;n{H7b3r@9qw}&bq#K8)4V~M$) z5N4y`LS*x*tlkA{tyb(qMEV?t4p|M?t#&>2)(G)y;^^Ms;m0^FD;|mW?K%Mz=Op8gjPkUp8 zzn1hcSwNm)tR?OD*OK;&iVIW~kS3bM#LJziq#{#V$(Lj%nZ9J}N!7zSl{~ZtTw>rQ zA4&T~p69|mOc5MG<91Hj4gv0%3&TJYgl>{5+Q2wWg;B*}B1Q>7-oQv1D9G1y?0 zYVb@y%$1Qv%za9giWTctTMZ+z8(ktJ$r$&u&|Xk{yDcGcMO@=PQi?w1RPMK*yKez7V?ROl?bYec3r6RTUTnO zIB>pBA^DAGkWQ^y%D=Hh$4Xt2=Xya|yFY6VlcIT)Rj&to643eGNkBqCjqD0 zM=zePq_pn`Ui+ZASOw*E$$(E$3irLY2;d>-#}Ga)+&0yr*V-cb)!U`Ds+qD^tF!79 z)nGW<^somyrhgEa9!6jEjEBT6>L0!a+y+`3TEXm#COLE?!hy;Ihdv95ux$XMl&}@@ zO$25WxKO1K)OVAum_ht;B%xIh#NL4yGLAy*Dew!D*h12I&){V2o?}9n6GmPvZGuMu zzu%STqAD@jDaTdW#B0yf;P>`@c>)^$VBpC=1pu?VE}nu{1J6@n4F*!z0Gr@W@!T4` zj`C}eD>ab4hnxbC8eAwf5Pzi8tU;Zw0qX2~1SjL;`{NPJB*x@9R*!(~?@Qf&I0GYIpE(VdHKrXe~AhjTD$e~Td~ zeMrXk_UuL*At)YKL+j|IB%DWU(M39we4({Cb-BQR(E3i)w|$>->Xi5*rRtrz3m^yX zg||T+v)AYB1fq?WHZmwpV~gVV0>#RrK=%JjHI1DJ87!bafC`DJ{ywEN=v4d?-{GyI z*j|9E?XBcIbVKZl%Z9(ZP>fXkQH(LEiW7Mp8UNN0=TcH!gQgn%k#9}}e2w)CMhBFd zmsDdtW#A11DFnfG)S&A7+1prJ+uJv$4&0(!50XI>Vkq-u!r2_9$}7AAi6o! zgWl;2NT#|yeNo*(k6X@vCm8-S%sU0cM5)Ow>sYTaw}?0$^2EvK7K_6l_AAy8<&5$N zM5^5)P|JOLwlE8}bXz?JW4vRw%`AoP$B{0(9z#u-Q9g+*fa27BvV71wRtkEVh;XNn zx5gpH=_%5r6l#}})dEgQ=;1llp-9r_lvv;hBuCIwq2M>gdF$vs2TJz<)Q*wgcm^ew z_R&fBo{8c-@==g>Be~4rygG2+d>=$o)Bv4|^I+y;@tv#|9@_A=)D_fOWG-Tu5sA*V zsTJ`7L=rZH`U~k8pfq_EL*E3MEU?+&UQAO;!mDoZmCDl8j z(A=+FB~s08s^*x7F<`MfqWU8~3n~(A~+1^f`dpE^$CSsh#MV2Te zOFdCgyV+;Z`3VGN-Fa4QZ;6f-A=|{DXlDptEdF!+@DUlAhZo>T;bQOPHP6wyUmvRm9lF3!mE^VR3Zl)~el9c|!_Fq~oWdu|l!;LMRrq`iFT^LB0=gG|#PDK_ zPWCoH84b@9i6^ZD@m_kcTgz4>y}@qVJbmL?C_$X~bkuKxU5xPXM zB_~47>bcL8EnygpiBM$^{0U8kLJp)F+I=>pq7sGyC=}|*ct*grlh9&My^}mk;%eb3 zsA~{u5}N7(LFNJUrTW(9tDG66L6FsID8CAp-x)qs#!)dhA?rHYjcs*}eqy6_!Kb^I;)s!rlxNh}L<*3-Wd z@kAwJ@$ch@kBDa@UdRq4Zu{U3-X?J{7nq~3#Bh2H<~V{h2K6GCLu{eX9FLGWZuw9q z=2#e(K4A`_?*ZF!ltoB^^fj`bf+NvN+)`EvDu6lIZif?K21Sd=228BR_tXk{XOf?X z$af2Js$d?@PNpUjRc6cV%r*mB!R0}!jZ(OUueyS+gA-@xPO1kj0bK#wC=#MkG3Oxc zfXbg;KPS#$0KAQyETv1Vze`*V5iVnF0KAoT6SP2DV$M3hMpEtp-EK7^IEf4>X(i`U z;8_LpnRY%jlM13f2>RkDS#6}c3knM6-6b}dcV{)iYiIV38j-W>NzAIJn+^6Rdr^6H zw$#v}P6!8%J@_~;Y>1$H}fay{(sJdxO4mkzsiAa}|=jBSu#*|C@& zyH~zIhQ*xR@EMl&BE|53CcbTd@EG{^9F5ukjeJWs3oyGto!$~=-=~fO!HZ^O!@e}w zo-lY!TZ%7yWVjcz+vtJo!FhDD24Yp{q49_hu6El#6*v>WZ6!PGy+zu}@3Lr*q0NtiX7LG7Nh~PO}aa+JbL$JQfs0 zEzk?=!vtu52n1Mk={s4-I8A%q%H=I(IOnjot#(mkeOm1IUz{EG@BM!c`$W_NA5mfK zkNz#Nzvs$qurKUS?AJB4w%t*7JFFtk*;5L3DErrzWk-M~{@)=0I|7gkA%Ng&fx?wX z1BxJ@#NwAe4lDPK2qip+5O1FsL8Yq+abIsl9+wef&*vi`&Lza6Ya$>{BgC|?ML>*{ zJlqI~KkZ~5H$*_ZLx?>M5fHBtV%#N}AVw5KKFVB8I2ZMi@ zBR7*i(}|>u(es~^pY&8q|RIy0eQRYw=5 zAQr!Z9F0dhx^xWS3&3izyW75hbjkxtyQ?tXX2m;u}hXxjCjUlxqu z44^+2Y;2hjuYj`c-~-Xq9EyvJLKrRQc>dG5{wnWxg|QF_LN~`V>|%UWHK6fu?VO z-`FHNejB?^ip?uWyPSiZZjjzD6`<1xk6lioDF(tTo%!q=PeO#ZG?VV8-T)Pc>5-Ij zBx|@EmjKpO&lq)zIgK2ynazyoZu(B9^sLyY17o6&JW18v{ReHuVjirj zI#86n!RMGO)Y z>tk+it3tf=sN@*iCL+|?4P?xk!x1YSHjAF7+A)mXFg!ca;XIE*5>XOgh#x+Jq#N;~ zkko;}b~(^+RKZ#rwaz<_dcieJ=8oeJMp|N>RX72SD#M>mz6xLWCg=!zzi#|xAX|C> z2mK)wVFVc~5)23_dhk)`J=M>PusN)6%wOh$ebHe(-?RQ8d>(rO3)?RaG%a zK-Hv%g*<**QQvls(}x-D>Nt#!JnhN;g0-A4HioY?>r6i?OO;0zDAp1FA%5Ly_@P3i zDa7BNlctH9V6bxVycRFoE*fXvvJBL4;^f+ZCYAijJ_Zb6siKCnrIoIau$gwM7s3acqFv(TWPd$ zu*_04!eOv`B{5sAW^k54HjO%O1&$T-sygF$4re>ejlb#`2Wf><1prmoU`B%+z`-M8(hcq)UBPjL0@5D$Ldsl|EZk4EHDyl~njaDs+43U-x_huQ_vF3qr?+ca*jA(&>3x?4j!rthEGWKB!PaVG>iuA7 zDeyQMTJnftGR~WBqnYs-S{V^%JLc!A<16uyNR^i2fuyTKJp%)kjCk{ulpH&c*kFbTmxPSZD^N1B7%jn7(wfx*Eb=LBB}t zd=%p?nqnISTvU}J&u*x7MUTUncJ!taX+}L1Xjf_jV&5Meocm*RD$?M9-BIG;D;I=u z@Wip=K;|p+fDJ=i`Z%bR=}QQNJVTu4(NNbp+C>RD&qSOz4Y(VMSEdCm&w=iV(}Jk? z2W`@^3DCC7WSu?e=M!zWoE=8nL&u6Xa%_6mq0i+A>%ftZIh%n-bt5oCWBFT)cf@~&DhQ*{(4j%%UeC<$BsMnS0MD{n)~>4!K2 zqUO z;`#=d_;P~Pi=v-*L-OX(i!?kr)z_^;Oa&Rt*~y81x|^!ADD(cp;o>=NhDEC&!JPTv zJ;P_*NG~<81my^d`DklyE?!>SbccVW_6lb^On@q@6aRnN`x(&6-1v z>*)dMmz6DFiFpiYfj(qf9iQxr0&sUReM4xqNRn?whHAL!!4S!(AqG6w#{pOJ+E;pW zW!E^ei}2|}`#v?#$zpLKq)P$@ z+|9+pVDNBPb{2p%itx8*$zOb=A3y`n1hUl?Z%SHPAoeM^xXNUF8 z8GClgDxg8e17wj)pxt{QLk7qDJGNBkW&<52vS%P$=+n_yu{&3Y*a~96*$VkHa_Irz zDiMH}2nMHY8FQ}AOm@vEj+GoGitq6m9ODE#JOweeYMbr|=5;cVk>RE!LL z4BOM#`7w#x(TKw%W|s8fGftN%LMd{}Lpd(l!Yjy*;~l~$J*cnTuhy?#KZsYhsVA{` zmoX%*76uoRqC2!%cWFn)Pjc|fgGif5z4}qXBy8Hj683K`8r~*SK zUSlzGtFB<4#${8)q!aWk#f}F1QYocQv?i#6rIgbQ(v0q4Y?&${A2};SOOiPW+QOiI zeZYXXN)#%=h$x3(R-S_t)fLnT&S7XJrCEZVxKd|2AqEa*gqtM=`l&V;=TBP=3D zk3t5)A3efG&3119>7(aplY7W#cJO~DK^un2C6lH#xfLSJzJ*otl=N#L4ll*6g5stG zP4YV~L6aPYD`+uPrt(~rK13n} z8F>cFHawoeg^E8wKpbc~z}a4?XdQx+)c}fdp`vJTU$ds43gG5G5#m{I(k>Z$rRiNwp6n}F`+dB?%ci%?@hf&TYJeZSx8pzDaP+QYYD*sc;8;hO zH@^=wC9kZ3Z~Z_$KOb#B3RpOCF*WD|_q!j<3791uaOIE7Y-P@`+xHA|t6#_Gaqs8Y zm;ajo^4lYFUfX}QTzZY`Iy)DP+$HEI49xE2-f+^Hw*h~mx9;+-pXk-ia4sv^ zYpAYZJDrVecHpFTVd%Aj(asD#M4&c{t%IYfuqEnmJ#(E6I5jUY$uC4qEN|LUuC6~G zR6%8I>|T?)y`MT&XgXXgjH%vO1S)Tljc>*e zA2G{c$BQQ$!!gV6QWgvqI}OR9TKl;Qkt+72@AzI=#JN$S!KhrbhwC=&g3+7wEGRF? zJ_srp_UtYOg=932&UP4$iekPUm-9m;4%?J%hPtV|2q`R6CTRC={NaRh^>N`@G-nDt zb3Le-vWJch&q~>G>Au_aAo2V}COlVOjFzVF+7_T|`yu2(jS*gJMdDOfF#YjShqxX# zb$HilB~^jtnhJGfcB-85Wr(k?yad0;MWt8MNCVgPl1k@y921p{^?aT*Jd}w_Y5|%^ z1CV~4_$Ky-jqim3uAG1$h41CHw_=@TurAG8MLw095|4}k{TybLI!Bfbo#aiSc$%b- ztEPdw-UsIRxQpmSa~-GQq3dC7Y?>{<(Abk}EE>oI{b|>|J-Nm@&TtLR`kd52#^C&} zhB_G2$ZrNX->gAmFJ(-59Nv&**R`n^bY2cMVJ7wTFn9c_LlD(1x<+9GNMTlk9xjYg&Q z0g@Q@Jr9^*`c!1?^~l=u-%EY627PmdRAUj;CNQy4h^zra^?2ZnNme689qfXE862vN zJLkxB{wg$Gg9n!TWR0l77P#4F4K!JOG-DyQNmipO8{kHmNj*Z)9&**U-b!htn4h1b z@;6dSc&wv76#-+^`}uA9N$ttzf;BJVJw$)y(atefvyG9ZE;nue`#8W_e|@9a`~~Do?m^ z8C=n3PI`yP0Byt1yb6B07j16F%uZ31D$v22jFjZ($WJ@Qm{7-25s2V z!gX~<9h9`VKSw7WI{~v~ z=T>kFpB%U7G{RppT&Nj0=%Bc->t=b0E6XJZ&MaUBXjv$ibDWBq0Ho_xIT1hcF8uJ3 zzQrEA5VdNpFggP!k|AbYIFH)re532uk90;mg(uTZ!W<@3g?fR;$;`!2=?1FhWM*6n zQH0J8?uk8$KfN7t9<+BrGbR^L#z&kEJsN+|PlPLzR}Di8LSsogMAE?70VpID6r52B z8vO`PXd2|0kD91h$WY8l@`u!+Uk}s#8TUR#(5Ip$WGiG&dFFdeG&yZHt#V3lUjC)$jC7)tR88m~OAa4>M8ggzIlx zS=)G(Q*#x*lAaY85-5+spk7r|5K+pA9*CV0Q92nxl^IRBR6W zlE&->FKotDVrt$$^Kfe;3<%YlBGu#v1*6fa+i%gGki7uU)) zW#fyNHn(vwVEY9+cUiL@;Jm0rY%{1o40KX|Nnze*!Vyp^d=jTkxdNNku8G)^Hj)tc;mo77o9h2m0f=!p ztS>FZJA~L1Rmy9U2aa${o5x;4ELss!%5ws7O9aGIQjcFnKs-!{Y3D^iv=d^)wg`w7 zgm`j61jJ%Oj4O|Tm_vyB{v`t9YCYA_kBE~9uE^@ zMAQKu?UKjZh&)zE9?wP8V=*D7;cTC@HJw9+rNX+hL}w<3Gb^J~E`Y3on+n!@*!1_-#K1T)k~y__T%b) zHO1atS3}Fd`yRLt6-LLyTVC?@!JJr{s8#8sYSKqdMU*@G|K!EgnVOsOJ>7c3wvPG} zt+HPo~-z~o`5U-<>0 zD@I|!=L5vEbTn$}z6;(cuJ*GYh82>nlhw+B+=Q@lw8Wp>4o^Y>mh+8P!|A2D64y>Z zI1{fxcp#qw;i2gU$ZQZ=fnZ+B137#p3TBOz+enVX$&MTFH4Ba#d>=TDLS%5iM-kc)UUruSMGW+7iWo#1ri{RmHz@L;K@s}+LDZ`BQ8nqKrXtE6eQy>N zfxgNlBLWgl5dn#&h=2qXDaN>+9ERX)EuP=rg~6{ZC}N=hm?`ok=K})o{vLxOcGRl$ zQ8nqKrXtE6eOne3fghZSA_5Xk5dn#&h=2qXiD9&|5}gli*q}4D0lSK zEGR;xWT1$EL{mgSqA4OE0Yx^S4~k&o)u0IbBlwyHMN-I!@o9K6!ofs?B3Bs{v7=U{ zkE%%@H5F0r=!scSgh>L_h+Hti~9U98m9B_FB~+!PhJ(VsO8f5#y7l zh(V+jGV&w_fDMXFFeqY2tx6wNlRj!HqTJEvWI>U_%oGujXo?6(G(`j?pvb~;pa|xX zd>K*w5q!;pA_lIHnIastHz;zpK@mG@Rr;u!^ifk0<&OSP78D^;GRTO4L{mgSqA4OE z0Y$2cK@rUN1r(9~2qqY_pok$5nj!{~hAAVMXfY^KU{Hi}FhSI+^iehGqoyLt9i5W} zMTnFP6cLbUiU>$FMFb?Eh@5tGnne-zN6yTOA_n@8nIelYIToP(>w~diw!w~Cl|HH_ zebiJ$VYcDq@N7f+v0ox314RTRnj!)cO%VYJC?d!8j1h`(RG6dj=#HF0f;^5eADRAn z2ruF3AHlvo{iEfjJY08UIy6z-n%CDt*HCcM>QkLo%|M1T!gAQJ24hv%#SoO zI2#daczrd-jw;wnM-QQO$^QC;uV~{IQi8@FyVA_!E!-f5wSF zivPsb$LftN@Mkca#-D-G6#T~tcmsd08u+uL?oS`pj3{^V%UR$LhmK^zpMXT;Pe20v z@xUNC4@mPL2Y9&MI}7|7$QmC0xWvK0-!21xcGUgpqnZ)rPJT8E{DCPl;ZH!K@h2bw z{&@b7cTkb=pK_z|F$?^q;6LM&=09WXg^NfG{QbbdpB;67`lx0^xs#vB0)L_>qxGMF zMB`6D0{j_gHF@|0|EZIj9tXYnWV9bC_%9lNT&82-4+Z&a1?;H%(?>NU%ANdB7Wm_I zdj|a{Akp{}kN|&j+7GuRdGd>XoIc)X*!VM$6(PR{|Lws-CTVY%z!@uiN>FR1o)FZ_gre~-R~;yA7&A%9}(ZhcnQ0I!fUqsr*UQa zdRVv@;3~1e#FZ8GD5Bh@)j)`J;|?J&!=YQxVBm^vrYk19EyXDlZ|x9%4G^A_qd;2t zCLo952g=bxy0vuH@GXnhrr->twc~gftv}C^xWQiATI_=wnEhL^C|l6&lxcf8ir=h>g3Aop7zLgi&H@ep!1#gIWm3{hl7 zF*0;yov|?HLIf+%!H>FcaWVY?goa%+1LJR7O!Tt?)+{HBnz0r^&Ab)RjrhnX@#5>B z#7fHkh}D=+6XMCIB34pa}b_2hvVyN;d@!-lE&tymCHR| zU5N-jLcXPVk*!5)e*rc%3PDM$|NKW#R&V+W-xk%6bZY;LcUzRd#BhLh#d6E!Ghe&H zUTV1boKrl_>z|E#!q!HnJZ@K^!&yxYMAHn} zu&^vgOnE(3E@I`>r-oZw+ZL!QE@*3B;L%K^kcv@JRDCV0^qQgsvQ6sdQFIBbsWyxC zCpNxh&@lJK*p1+CipmIBq}WdUH)yDKZ4)oD*(@L^*^>nQ)tV4N>pr9jn$MAr@kpwM zpZb8vA%`7%4Qe6w*&rtgVOHA>s9&5(z8(-E=T(U6@PiW6DZr4*h8Xg2un>vWF|H~K z$GGB4b^JQ~@)16tgcq%*f|En(26W;YfaFKLgA+NGKIG_B_v;hUPO0N~R@rZ-C+;66 z+u%uD`R|uP+;91H`lZzu6Jpxj2#7NXv1ncd#Argi9aYNFUgi;1${z?ZVnIYHzahl9 zD2SgDVpjHm5O+!*9TD}oRUlsJN?*#& zgxK>?L>`|Z#G=g+d0a_|aUY4u<6^1De?+w93_?uX8j;6nLOgj(1jNxl0AkOVA|U=C z5Kl!w{Du&Vz83-UQ-RnLfsYpnF>Osm9#0eEzULzF@m+z4qJAeK_WUp+k2?wRb`->| zgqU`JL``od#EAZgQa&RPQ8m3%N{NEFm=KGiAkHAfxXRbkbMk1(BMPTS|BZP>LHvOb z)5;@CQBKK5s6{7+j)+pwiyD@~54p8bviOqN1xpE z`$46nYqXA*O(*^dAl%#gmu`BY*z5cJFGuL>pj4s*tSF7dEZOl^;-7C+hEt7Jl!;SN zwyd_Pt`S!i9i9n;4)X+H8nWfhbt@a2oelU}9sd?S@R3~@9e6>bP%?L6-~^&~Mz$Y~ z6|9}b?|XHKeX5SX;wYl-jyEU%%gcjjpMzs{JG#F8m!lnBIr}@3I6}P-Dw11RNEDjl zfBNj0k!VW4zIOnH41qZ{1mphWOGgG(&zHxfDKjQ+P%*p#@fTM%tytO8(%jlsFDGhl zhE-Pvy_EKy=o#WD9j2+LuNg|akY=7Za(Zktzx&h3g%(~pH1+Y?#cgGk4Ndamv@n+T zv|8Pj^&npPh!MXRFPcZ%e?PK)5U8XHPkg5DQhoQC`sG>rvNxT?-IC((F&-#q;Qri6?#x9HjHg>Csg^^BU1Ew_5LYN8j@Hpz3Cg)ncJs zU*Fr3CFiDt3)#ReX-X_gk&`DD#97Jmm5pr;EsgbMvO(XI3x}?ntdmaZ;M(q+QURue z3u?=f-fHgbi8Kj{nGl@tDM>RR2}~wKJgJ^Qa^-wm`X&Q)t`xRL;k4=F1{>oLmSk- z>;=fx9fzNQr^mr^P<@;~&sHDav1L!63C@;2`B?m#oQ+n^$wyXoE1Q~{^_5Cg8%nQx z4R*GIf`&)G8ZNlE?opvdWZ^2O9N&kF77TR6_L}V!li=O@rsX+6%MkD(XbE7iV%7n2 zXjX}wc_HMuPtQt&mKfM%NH@om^wnswx&y6$Jn5lt>i>JY4a z@K~|J#ycUb6ju=;(2lsEfyn3rA*5Z<`QC8~DUZr$Py-M;Fp7fRM%JnLFplL`YhmDhY zEWTP5FU1j|D7H88UD#-dl6U=0FlZ*%;Bv;paIt`(*bsUkqoD}8d%kURg`U2*snIwu zght+9`Cu<<$(LiggJ|}RzaHUI>+(rZzsiG4d^6oa)aTzp#H$~q3&V50a9V1goSn+k zPkA^IuX4m{<()yWaPQj~b;IAD z^Z)sk5oj1re_~RvTGm~cuLGZo3FI#1e76b*Q_jQSDo%8T=qqJQm&fUzj30KK)GD!Z z1mzwx8P7EO3B@g~&5P^nR<_~{a)5g`lu^!WTUr|La4PW8(BZ}C6QuJzHeZ3#WL0D- z-i*TUx*WmTtP2&tQ_7&21*z%6OSSf@f{OPp04t@%z$4eFZo>=k+Ar5fQNx;4ci(<@ za1dFlSHe~gI7C1Q}2^(fqfzZAYBW|r-}>dufNsx%&dD3tyZ%E6r> zyM&3T6Ojv2@?79P<|s_$&gDs=-+bvEUU`KB?D}A`K}dBjp>crSLTF)=kjS9Vy#Z;F z45v4i&lmcuWQ8tG+3BndyKqLbLYC`JBoD}p;Upl(z-%1pgbdy)AZmWjSslQp6ay>| zysW^ufWw>G!lYXxL`Z>=7>+E@q~TZHPoXF4)JHULHGSho;yD$zy^iWsar;|!~& zB`}B_!-zST16OjD)g12dktvi#O^cdn>YYPqq;hmPjUUmIykvtYd`0H)OjoKtweRME z4-C@yed?4wNeZ1*u%&qg4nVuTe!-$9XC3Pp5N$U&M^+D1t91pd!4v6_6+@gt);e-X zpk&qqGm749w=;>spokU@L2$^)kwY2Cu!`4~*T&^U2AScmt}I5x`{Jc&x8a0%DUj8W zm!cg2%LwoByp%UW=JkKZOSyhXC5MfZ6X2!jvQr{xNu-ye(O4NmMtUh4#cvGpQvUvb)Jv(5Rn+uFDo&@e$kqW7LwGz6$T=vrI-bD+F$ns8IUq)s z(GH04M+OJv(f?fzh`I(fo!_DEkWA%nkQRo!QOsZ}cLSCloZ`D10w?ZGg@jX{}?T`9M&@q$W_bin(OK?wu~-7 zb(~`ke5A|tA9xXm8jE?<>u*xyXE;sR>Sx8o&z9QFx7~BJa>CFn zT;17^!XFcl<{&+7adn6mXRGaC_twhM=w{2sQ4wzB z^eo-Treks=;q@suvi|n^Cc2QEyD|K`?eOp9!lLSmb6I_v_mS$KhhUu8;Uf$~o>aqq z?T2BNFr9`@gLQ4NTXHvQ$sUWdo^l-^_W(W`#l{e8-fSYL8C`&MY6z2+#lZh3$g>aP zD<7%Cy?6rSy(c z&FL}1=&J`zBGY+nWZLOGMFUxJRzf&`c1zv=!Z{>$;ftI#R0&hA#FA zvI27*>a3yTCCJL-B}n`j39<+4-bj#Vh7hFeSO`Mg96LdX&*2k<&~n-k?X;RrZK_|2 z`PAF%uksEY+JhKAVorA8#r7E4?V~5~wXi3U$^K49Lb=XbklAGW@G@?!Wc1= zWeno!$jCUCICwk-blR~W?$h*pEK}2=@VPwrmP`ef{VaG-z_knDY8#p%xV%tWOQ-2 zj~qF{=MvKoJTmi{ivSofDb8mxzUs~Z zS~9?8u58gIFKzdi>ycaaWZ{RvOp^HUNJ;;7rbj$DkoP9aY##32IQ__Vv_>V(8xLUxhE{|D)W%$7lAgnK7_mbyyDRUPRbB>eTmM5xGCOUO2JHM zjB*hJhZvq;uCzUv^~D6xc$Og(K(Yohm>K%CL<|Nv8$PbSih|vgmHp%k5tZEmfsd}N zO9Z5o01-Xd@)21p{bsP)KvRs)8ATDb1RSjj+0LPp}8vKQs3S1l?{F+zLV}2 zT&;s-=tEm`Rq93_xes&`I>AP=JohUqNkmD@PPLM#l764Dq-&sKtdjnj_x^kVcy;Da z(Tazhqb5m3{T4CUgIQ6-EiXlkQaGFla}rlrvB}GItfZZRZip~m z?>o(J0^W=!Y(&3O1*OzH4yFjrBv=Y=G%B$Srd72U7>5NwFt#MFZGbbwH#|cBb=suJ zjZCxVz=Q)jFch1iT;~+y;|g5J*Hl-mZYqQ#VCsbPp3LCZO>1Ez> zGT;7`<6Cw78_1WB*dMBs#GPCW1HH!!oC?F&_(Bu+76J;F+kH+#b?K)^$ zh1^R~5p`eT;@ZZ>vQ-Uj%eF3x9-F#gQ>m$OjhDIz z0fxmL_XbKPi>mPnVNNO8KjGh#40M>K47tQ8P7pqO=keDmf-P6ogovV=q-tGrS@Z4n zt=O5h%Gr!?b)0g^N6=3Y~%l+b5w->fm4Ib4HWR`GqsA#=cz(`N=3~-oH%O6 z{yht7zLbfY6{P0z(e0Tm>85TQ@(HD`9NLU(RL7x3*t~?*C=$rJfV!(Qk zASSehtqkdcEo@AMZU|LXf1>o82B!k1tP!)edwShhp`cb5FN7J{njZQjd=irG;cv ze^N_mO(r$A3|eAz5Sm14b;_4ntK3~4tvxaN6WB4+NNB)REXZoUv2?iw`a=rZ+?cAM z`$Gju&7Ff}L$UVrAKGIQaP0y+>GA977-Tc~)xF^rY?y09DbAs* zEM>79{GQHERw1sE)^XMx;5~McbAUa6!(5_%>C(m!$7Mz_XWf-nqVWuhcAt#c_$>VJ z5$%Mk1=>k#pnv#L1TP;#3X7NBkq_vtftw)dhFVNO^%*AX5%9n2X>UQ}f)%Gr8W*%R zEU#bTEc_H&kN?kJN}6Rt7AM@dhO!y^n51zME zr{kh3j%NrL9r!SE4Op*{L8-jpay2AMwMuNELEf`zUEa1U4=+(UckQuqZ99i(obj|>*gpoqFAO|T9vwo6dHCrYrdcdA4)61AaDKiK#T7?Ft zB18S6R%bVJ6K|KxzE!C}Ec|B(ky%ejlG-#SCpSY|Ky@JB7>9ST>FrGRB(I|`!6V(G zu?Wx~;c&7V_x~uO5K6UvrQ>Kvx87MM-o@2+-;5Mj2fjdpu+h{27mW*W|8STl!Zxrh zl#WhlKVD-A9;e_>&xQo?#OQ zUjF@v7YBgDbB+c|n+K7g2FX9Na}(+;x#xcwL&-^O)j{v71*gCOfZc9?xM$u+P@q$) zNBb(FvORS@#StM9o*>HQm`%ARx~+EU6m(1`uy?|)NfWMcuGMoz8$j3!QqC!&>;w!_ zeLiyM5LL>&}ob1Y`ks9J1FWeBJ z`PnV7G=C;bUWM#kmO)&5eS!YO)lWv0vBe`h5-CqCAle9=FT;$MgeT~lm!n5ogcQyp z$hZ;?K|hE5QwbQ45~xC41##vaAX)>YciW19GasJvg>f;}&Z4H4#+8`vhol+;*#=fq z@N3W%6Mjit;N?8(DirLkim9uc=p9F$1+h?OEO7#f#r(yaIc8$vxF8bi`XR*n!m$#I zIQyR_mK=UP6$Pu)Hq_>H|M)QW)vM#2;Nl}P_Fs6hWsF)I(@TH$cTll2V=O-twHn%x zPi_oWpv~GO0z(19NR%;+NGjv*$p#0nneYy7 z=lfU(cm}HCaF3iJiN&zR=_GM8Jp|&|DaD&1iIaS37PoE;B^J_%lO-Ur5ht33)*o*ywyPsivCzUj4#US%IVb8kfl1yrm=Y` z4!Lp4VH~RC--QC;BaSw)5)9QRZvHPZdoo!1uL}s%U$AyAV8rgg5eE~=zC2i;J{Zhi zGlkU;I9Z5A1+Metyc<_3p=F9PKz#UI}C(kf8;P(0(aC;4`a>H#BSnUB;kJwmM`z6Ox zBD>IP!Rm}#h*fS;o{FuV9XyU)Yh=}a*bZ-#i6p9|lbSyjjL$tie*>ETVtP_=A% zCF!Ud%?k!N6 zkfDF#0=V>U9VyaqqE4_DNa9yFB5}Hr%6uP*Lp?c9do=B|$4oMf@f}2E-ThYm z*>?k;)fiu7eP+U1Dxzvbnf1u&OW%%Y??Ldlm46Ct86ML##*wr}y*{K--FvrTbfpZ< zbasxlm|!zZN;;cbjJS$vOth6_1Hwq)&X}_h?36CiVKAafvf;$8{ z82PPZFvxE=h@s$mbZ=5^;o1(}kPaE;h*QW&=~AQDP0aDyRWLXxF`*liIH*{P4NqoKLmcGgEN2;hs8ndJ@HhR; z#t~2B_l&&i*W5@A;Qqvtmm{>qwy+l3b(GWQbl2$LyFa@7SA%p`q7UGk0=&ADEab8! z=CL$x%O%}|W>Zu3Gw5)-u$XE7HHsyUhekD}%C0gh52@m6;`dGqzaCGdpZQ?-L@N513RYBB{do+OfhPvM zl%T`VE?g?InM|5~hGaf^Q&OQNZ}!u>jYDe6Udx|BHjX+2D+z$4tx zaF}z|QGSf|oNqm?8d{W6%SP9PGQUoRrQc@CqP2cx2Pi6JdG(_7Ix1B)1o7r++xM^z zUkcTsPK9OhwmnOy`W)ge?}G)GI(+6+WDWK?`fR;r9Cj{?;noB12E}ssdNl;9L$piY z0r8?LQ4V|>{B5Iz{cVU?LW~J$0J{ho2(XTgZ#NrjE%7nVP>RC?lE&V0ArYQ0MuE<= zeNt6e(anXeHd+i@f`v}QVV5Cv`a4#2%W$e%0)r}5eXca9szp&tO&S!RB1xd8Tc6bD$C}&IYN=sNO)>_(PsMw8{c_~l7 zjMN^6(Oh`BMQzQ@AWGP1?rjaL*i=YvM)$`3B7T^IChNl<>O{k(K)Uewx+}c8e|}tm z^f>{!{Kay%O$@8MEuXX-G;Eugsx{w0@$QD84*sq&yAEMBzhkmh2M`c;`D$ciCksp7 zhEG|^j>DY)lJ)+Xs<+q`3K_89W3N?GgUNE<-RcSt`-h6jIUG#xwe>_;C(W2*)m8~f z_VlW&w6c*iD$@BdLz(iDmM~Kek-L6!RnYHP7X}ay3^lu7>%36 zRI5=b^mRJ3w0W9W=G?P&nHf4N%fMKv^mRt}^bcf`l=j)GoZ;|{!N8Izrhhn#l^ce` zbI419qUe02aCoe;3?01hIcS?KSX= zXAYCng`cs?im=QdU7pf1$N1T@%tO$?y8_(F_%Y4$cS6#0pOPMqqlwq-d9c(l=?5S3 zuJ_verEL59eO^kBiTrk31Wl#Be?ku5?NwGZS_;GY0s5|Y&Gsty+lxsI8cynZ+UXu! z)D2xP{nWZ@iztf2!MkDrkvwVoD^@Ri=8ayN4QJ5cr5*_!mTU12igP`cro71%?Gzt< z>|C$R|Ga4U?G&dZ_p>S5IV`87*Gt)RuU}?{p8Sq^R$0CTr_ldj4D0_?e6R=n>%J6X z;%xz6q(6uH(0mVHKlxbTlvwO;=`Uk(*uKwsDLX$#OlL9Hw(av)>xa+oKPDUeqtPt- zV8Zs+aB0|(H^MPC3_KaqbtqHvVl$JPEn?4g7vjtncx1XmaPnYK6jB-Rs^44w=~S>Ly)taOuj6{ z}6hI?U;r zb+yoT%rdLIEWD8cFJ;e5AJHfZ`Xg4?J=`BT(qNV8)7UazLx|Y{9J*^1B1NNTG)B_E zjkj8bsRnxVU^W@}@exS9p$YuD4%NFa)TMMV9>-^EQ2YUWkVR+JCQ}$USy($W9%)kL z_uTXdwXHfu^(3TJSLawcUoJT(3m)VE6=(O3f91}G78E7VFjnsL`zv=a3QVU86jCdq z{Lu_jHF2@Jeu`U!+|_e_HE6Cs7S;|eS3Vty)FF3g7%8v28Y%tJ>LKhBBpPib`p{(| zYQz@*YS5i_+s?sxZ$VEu+q!bRsa~KEI~Ev(9~7&E109QBfge6XzEZq+OT+waB_nX{ zBiB!!A3n$S(&@S-h-@Y31x+kW!Ee($*|pAe=Z8~`FBTRy;Byp zn^(OW5+qxFqdhXco2|!@va+yLJAhoHEG6tBXMt|P+N4f^r97km?<9g#xyfC^rJU1M zOw8qA-ZA?>JPXOK47d0hN(aDWOO&)nWw`53@*oGuWa;2-f0SDTGEBCt0m|LUkRPRJSQ`MO^1}MJdq= zDJjL{J8Vk*+|MvXsa};~h*JA;!v-=iC^baUj3b%OGzDt-*1pY~?1h}FIb>=~@X0WZ zcZ)san~vSD@!K4_l46m8MA4Edk+}D0_>PM&_!)+fcxOr^-uDM&fQE$z#c#zpy!-vh zasp85+bUEq>om*YfH;HO(%|(8%Asb9;LFwXfcj5`JxrO4sNlEm9*XP z=Z&;Q=p7how=T9~duny8q@A?TijAX#Xr#?UPt(YG#?3lb(r!dw+lcMHNykc^m(8j6!ro^7P8w%FK{wN<>HlfLw z5|CVxnX_Bz?V7#`{;lPoUw0K0-nv<$@F06B z)-lW4sg3X%3_+4%Ubh{YK{-GwtRv5iv-x4zZFKvi0#SOvBD}d8I-g_vVqYE1|%y-P?2o)DR5+GBGc*$(##p|2FTfPUMrZ+ zSv?Io5ZBce;2Ny0uEdX&EVVv@=@_+4wEs!~g6*u`BnukrSFBjj+`6Ftww1MwP7x-K zjKuwDu1cKCHzsy^FT;;CMJgOaP*vp61TUfztR9QYxs`YkPdZn5(y}s1ub2ECBI#wc z4}!1gADH8t?$6@wdmGKQxA-#VF|wA*h2l*@A(*p}0NSM@0y?=NY(7?`Hl1hQxL=i~S5kxaC#S zrpi#b{rlgBaZ5I`jyG>3Vw+9GE>wu^vnMdk`6B2zVXV*mjNZ8@5_{x6Jl(n;;%s2w zQ-tceyCZfv#vE8(zE{pW*h?|2Ik55Y%Z+kQkmEX6Iq!N&8WeVxj_YZMQaY{!@ITzj zi!wQ`yP;-PBYiie&z-9Ls0hb(6G(3)D|F9|a=paKTL%4ZBvDRYsY({%VHVrT7VKWD&j1z_Kr^vtqX{(y?OMC)HZ9 zam)`GX%E=$Wgcck3`cGwCS;6qyXWgzAO$-@>1_tJT87y!BW-ey6+4OEW>DvKu*gQ* z1HOAHb)FCZz=+)l%Wb6X@!d=D7)t3yO3sotfl)LgZSoo&D|Mc6wH3Q=s*aVky;V9E z8aU=`VleQ6w!^VgUeI{F89oIMhEYDnSoka|LVTN+$%vq@8K7Xw5pE?LcIFvx1dg*vO9 z=V>@#7)QvKAYvxpV#V;im_c;~4Z9QC8&ikgoT`2s@TM*k+6a*}3TcC2E08tN3JPQZ z&WVAxLIhQDa?Ux6tEAD6SD%DmJmQM&rzu58fa5dT72AtQ-}4|{8JTLuxc<&;nILeB zR*HpAae?Q<5|L?e@Qd)e?F=9AGYt6x+f;@jKkLF*!@dB}B)-7!Pi`O72ZV7v*8M1c z*yoTA4Oq=`JgtfKeYr~W^!)V4^f7_J6kBXOmnyxdddPFmde%xVVz$=~#o%#zQ>AKj z)F4Tg-qi1Z7RKO*JPZ!%BhVteDQg7W@TR&Tl~mq6>xS!1@rn?o?)B&%dym?ivdS^M zsg}`RImJ@WFjf>z%D2inLEh9uhr*1Vr8hMj_W+W`Lc@TQQG55!k7x3xc*|ADcJ{e9 zE8`yFO>Hf-k`=mBqWl5zJleo5p^}pBG?gsEo0@GqVR>#zR7v7_jI|vwHDs3An@ZZr zhT~1`vmLPEdQ&_@!9c}uyeXc4X(Ul?%Ir)zC|#OTnYWKy%w^szPFQ@Y&Xj ztgP11He69fLvPa_&Mt%ji8v!$~`02*I#Wm7K)7;@P*<>OPCh80 zDv3|H4FJ+%D5Xys1!SeHXkK1CA$vsfco5R<$Mp+!<*Ffr82{z?h=Sa1Yr_ zjR(&7a!IfFsr+fh};UGsr=BjR#YRb_Pz(5|w|C&mLtO#tIY z3Z8bMvReJ~9FO}4e(Eg&P`-INf{Fk&2XusL(SAe-k>faRLWw*achLML4L6;^**gK} z@U8bpI--!ljSL3O>cT-D>R_F_{z1b@2HRiI88qTeHAW&Uf zCjkecK%+NX5p9p_tkyiHv)cG=8)Tyo@+}Rr^&1w*nnyIqBM)nkny&*SAbcK!L4~TY zB192>pi{#MP74wAP}gClXu~ZL9_qfT%Q*NIomLthXD}#ZJElQYqr0&+*NE70ug+@U zYMs@3tWhxW$6%0E%a?UllkTu0#>912C98B+y(_J(HZmAw)wM!rmAuW0c)dkubp#`% zs!N%~g+E5x*BgA0Wq1?z*|yXwZ9aoRX&Z1^kitQJorY7&c(Dc7R|_~%#&>-|!wEe$ z)F48nr|4!YMgQjzA*`IsH>u0a`8uuWjpR*Mit>4Y%O?}gpKC>2jss^sy>X+?D!8>Ta!=A(jTxo0Iy6#eC2X;d!Jt;Va{!l5roQVv{D{I+f-?Zq zCbaDSFGK_>b|kfx-1ir}ox!xr{?h`vreA~1{S)4Vs+;~pXD?Kp!C;W->OQ~;p4a`G z6;bEvtlE0;CZ!eq-U8|WR}GTOHv#E>!vfjyTMe@BkOtZLYk)|5Me>$07*uF;H{e9_ z#=oxN1TR&uAwuwS;1^bkEnT{d9k1d|8a?oHomOzamBFBl!v_JEPyE&VRKrPK@)!)@ zs{R>pQkP9XvEa7v(-Dn(t%xE9gA8WBtl{o@$%5OyQ%CH4K}Sd{yPijcv~nii47OOf zLr3)d&?;l!vxqo_jd^`L-lX|s@ut#B^AG&MN)dYoaMJwJZB|6?(>kj$f3LGjZm~dK ze@cTKc~XOHdqS5c95$c900$c$2b_}RN3DoQHtDRkd{<}H`yHK?RD2_YK~`NG0Vfqd z_)QHbbc-_>z-@m7a6-492d#*G59lIa|C%mx(|Vni6gh*zAgk5)>ms+Vvm(}fRcH0c zS9Df~)>>JuV=%~Sce~DN;L93LXkLh*qWQ)H`W7HU zSXtKY1Sz;nL~(3g4c>%fx81DM3Kixv7^K+nIl$$U#~bHpIB8Z9g8|%ZIQX9OVE0{= zjMQb}wTO_qjK!M~QGSh%n18jE)#cL=A!2pSRJ=(gxx>{ct)xPOTz;hn8JMiI7xHXn zFsR>Q^xPGBCS7htjJZr_RdT7$N-naKCMa1bw^DRn0ysfQ??t*uX=)5X)zs1ptrWSX zx{NUw=rU@~*J-7?c?<^CtttWB2Z;7OyBm1~tfP?A4>Bk&sri`BN+`3T2ob_zJICk< zsbAM=h!9dFKWvru|FQQz@KF}m`uGA7(>6*}s=1nK)QC}nMnw&}#0XKc8cL89Lx}T4Q*>}#n@9w@4^#1wW{b+dKojK>soH=vmnSW>dj?zpAGV#P3&&QMD$ol0JH1kO0 zV;$t9rBpr^-k&ZwXQFbdEEFZE2sUF!1q)6OQLOj5;Zvxj`0yF4JJNV#!H7A1)EM3; ziEXr?ZhCL!q49XOuOpm|$6cvUiBJ(OtZDFZELZe^#yS12b0*M=JPUyi8w>Z9I6g?; zIJG_)Id{=0FQ{aq`f6oS9YWzBhT1;)Kg^I{Z~h6_4~(F_XyUj{8q9D47A7sMDZNF7 zUd1t&%tJzAuO=P(B)s zTb`?NpK7YW`j9Mi%7avMT6sNLcGAB5BQ$;E6 zPUVA%6hXT`vKu|}9xmkYS9Z*>4fuk$cgMm%(Dts5nDG;I3)()?@0j_j%}@LH5HM$viz2eKjzi`Z1rZaw(nCrZ8h6P#A;DJkoWTT!``?D?k;tTDq2+d zLZk2YVB}@W`%8Vc=*AOe{mghovU^<^akpq(6|cZBXePTcqM>w)YIk?L}F zEqKvDfyPJ-2CF99)jRDAvFg$2z(hi(d+aX3Y`~ByZUD>9_R9hL2C)44Y5E$sVV%pW zUUt}9=qk#j2}=-SAowvO(cLpt&ibZz$xQ7Mlx zL9~Z4e1dh@rp$S)`8fVPWQV!kd0+muX>Ay^%|704-v4wtP0B(ZtK}IW^f)Y zBlgU-3wQsO)Hulxyzcv$t(`EoxFpxoljgMN+yP&gcymt_J~axxszr2u=Cy5 z30X<({LEjw?L1C7OW}2`#V*(DF;XQ4FoC7EvbuR5?E}E{*c5PuG%ZlW8jxB%7*9G+ z9atvx;B5_F9s5~`(gC2_}@rD0LVFN2| ztS74?<5kP^DNMSP;y)o81QrHXso;Xq%#l;AOZ~!zAq}iW4Bv@}RLV^Ke z;4n9pBGig^RVbi`K=>G}F42d#SDMq5g8`n5ZR+A2CSQi*KnCdE=3Y-?aEUX03S2(% zZ5;$E#o+7;36{2tX22=o);_pp2C^MzvmRg?JasMnZtptr3-HQlhUgVC(`tmH5i&!+=R8 zKB&WhP1e?r3vvgnTd^{4{lxlrJG_mEilf5YFx==nT3e(MO<}gWVwdFpU*|D`EYmtW z*{wW=pz8pVlBft~}EeB?BXv07^25maf zok3eVTc>iFIWU7m+aJ=YtSdVFrfA_Wak&VnMjc&a)DpmJkWfr$9o8cienGhpE)3X7 zpFkKe?e2hNXaZ!00b`eEpKwuO!2Zq-?|*(6Fm5sq1IA6pVZbWUT62TcX1>FKZNzeS zkmy1?E(M5Qz#Is*hLRpRErPix3j@|R4ICUhtS^KVfRsR}@j^TiaVY;h{2}D73S5ly zKB^$unDZ&?!&*`xyk|WA;=|~9x(9m3Ee&VzpMjig1LAZ*fPX2C?oI}93xxe-7#MZMwtB`Fx;=J+8#{Hz7`o8y%bw`=U*B?L zCycLgM4canT)LfN==Ms2 zJD!m0xwyDtbY@jeMO?bQ+*7x=rH&hxaN3YKZdemeTT|sD$KOdXeiXYUbs0i!3dDLH zT4eZ>2UyN>p28hsH7(Jzz!Zp=jy=ofLFC5x<~c~jd&21Bhv^|eg>`%5w|2w}cKrCrA$s}=|HpgS@sMVgbPV}SchSJlm`;$rHI+XzN7$klX zZw{c4LFOmo#h@fn?UWkv_DF1PBi`@93x{fMq!AEL3YWGMh{YIbM+S`&h;>p6vBGR1 zz#amzPHOt~Iu-iBMb#xDwQZ43MI8_!3|kilZ4H4~M{XB^Sch}8Ql~O)6M%)0+Cw1L zq0IsyF;XkBRcMqsLLk=RoJSzmp$!v=byB;qYi!WcuTvSRO@vw<+I|2SBQ=XI*>EbC zd0mN4#W;t2^vak6rA5$%nb0`Hr*7Z|1B~=us=-J{kxpPx6u?oE-~ys;f)GP)HQ^dY zIQ19ci4jild`*i{4Z)753W^-yANz_6ppU_7pg^-41`<-Ny3Z1GlN6@=d{emY&^kH214!7ppm69OJ~`HzN)fh zz=0WR%Yh42;zlq~C=7>L6J`)5hU56BKI4bQoob?GQ#w^1Kj_Tok=i4ESUo4CT1||P zAGRvS(1i)G$i}fm<)Gs)e%N234r>U1XtKib!=Ow)fZ#gP{>I8N{B=?&T6~!DWswf# z*5|b2RdbMVX--^Vuu;OLBVTqyQ4F#2YEcrnBn|=^+gVf5-N=zgel%LRlr2|3ZMY=l z7a>)DpgiGBvphIPyQ^E1gbC7VUb04(p?8x~Ew<;}nl@1Ul;ZkJ=O!d)U zrh-f5n5Y=zsTziFSEF~51;YGHL6&J%B^&S=T0|v@8itoBvLp+Hbi2N1;V`&&-sB%ZE$HWNqz!^ z)nkA$$ZWXu2s%$FOD@z^F2;8le{~>r32GuSP{R-)jPcGG#=0`|@bI-*(m1*jWq=5b7k1vw)ro0c8xi69HfpT*{q-Cx%OdlQk{eCJ+j}a#^^Ry=NdF zJQ9L(5yo*6HW9{QtF{vT(tfRTjNE6y>LCR_jjE`4}$I{T@}1+7omFtOsjj z&`yxhQ)n}Kk>U)TgheuXbvUnw1F)|i!-E+4df|gqf)f#pMRG*2N@B$k!C=WiXoQ(U z<(Q?@Zxez)YG?3Dc*WQWT*YPc3S0%47YNmn%DFaCsmi{XDhFb!%*T@wemK$gOI2p( zf)&O`MBF+Be;iFzoQwo+mFgTkaRd7e5S9ULE0L_C92mWgD&Z_ug3=Ian>9q&Fb(0` zNOdfHcZL?8fhR@FCeekz2E`C^E9*)gAdKtLdYE8UNUu)K>wpdws~z}V0cHKcm+S)p z3Vhe?MS?P?U+4s`Q7__!sTy^?hy?D`$CGxeUeNitCvN;H@^Meh@74(z9ML?_C|2Jfo zM`KyOuCvs9O=Kx~L}#gZSZCRcpkam$mC~zIp!Hutz6@%G?gw-})@g4m61cT0TLi^a z+=o`GD{0m;S`jo%$>2&C(yJq*?mpz>O1CwNg!%@}s_|aUYA=F@8LYze>agm>>a}7O zy`EGoIj7;l68SmK$SPZom_p z&)^Cnt&Lutg7+>*KGwnBr8*xwyfD2w`8uyhK6ZG)MLHk1NBOl#;P&XR5)|7OB0-t* z7xBbp$-tA*=3NT}#n9ErmqFFanlBQDD>SP#dSX^(xH@gHie4os3g&878MAdhu2xPN z61W~sR|tygkd{$js%3P~(zNX6YUtHb$(GBsjILslu;~)bYHN{ZH8@?cYNJ<&Rqw@` zRmS-`A8R*fDiT<`o6i#oo#*O=!gBngby=% zN>7%c2pp$bwH+-I>W|W_8Z$MkvI&A!^hiNbaD--6`5BQg_0yVF$)_}{)^yE^&7zQA zoeI{CN4^ZQ;*K#opBfDUNZ__i{|8bXih&V5!VZ6kC+^s7e-l~iqdH6D`*>14;6IUt zaT&L2^sj=VU>NyW&s~2K37h_?S#2G}6H6<7Ph`pcgU&M5(pl2q6eRA#AM$a}tLoSJSTA+IMgr?4`mchbuTRSucpXn%>3lpH-M;@dL6P|? z^0Dq)U(xxvEQR#yl%?(^U)Per~OdUfP( zd0ywse@5qH9Taav0_&jrX_3(TluoF8Qm~rZi3INFB|pLwD<|WJnwAZ->j^hYjP6@C zEqC@BdUcAsWi9ftva{=TKGsmr8j&xs8u?g5O|>GS`o@^Z8}P(Vp>~B}l|`?P$nxcy z)n3{a;cm~>+J7w)*pyw-#7nBQjEaSLVl&%}zeaa1rB_GB`by->AXmC?p3cYB8oCMz zT#t-WoxsA2XCZ-wk6bPiGV!Vs_$N~w8GSR6!2M_dQ-4*eo+8jXS+-8sS+)grmXV7! zdv1?*dUYuFPeVR#kGAtgLj6?Ds_{I{YVWz46DJHf0Km>Iqr~{gA9`fZ!3DmQ@l#{S6s8_)@7PJ6-4FvJ{|lN_Y+! z6u~YLAdD7YibB0$F*kf9l?)$_4|YwO+AF|v?}(0T1yqFqANmbdqr)&G)Amf@-_JAS zgQW_a1w#y2u&Cq*Xq@9OtLVN13g+>XCZ;H8QLgphL~?3uIoJoG%P)x|NDPcq%Yu<{ zchmhWbvd?SCsmqv`w_$I`2aeXg*FQC5uXldNi8JuvU_0H_KW|Y8A9y2Yky654JW@O-wC5ID?q1UlD4K#6^rxZ z#!gBdoC(Q`Y`Mv&iVNW>%o4g)eDyVM6~`5EJ?Zxjp`e**ok7=aC@+gf_pi1@P$Jv}t_WaDsM1x68UNZ8F~gw9!qJNohhEtRcHAtl z+>qEuc@={dZw8{eo5}#JLo#D!s8;XlMy1ELA@5f0#<0R=xbk)~4c>2&E#?mE(F(mA zEf%{;NH^J}2a7I1_aaw+-Rh^PxfoEnU7oISiYi)E zxJlzWPX?d`Q{GnNvqk%C3Y1G-F0tzp-=dQ$-7Okd#j7w7TC?#7rWgzIF`}xh1BN~L zJ3|GwpYV(Tz!&MuPqr)6ek)Z--Ru%h#T_s#>lD#o>dH&4lBq7Aitb>HF@aNUSwWU1 z4>t;#?rssWDP2nRG7B#w#!^whnq>EaL`KYUVp>nLi}>|rj%AEWp_?Yz9In2_r$Vbv zPo+>{jfO%?@@!e}EhSl_P-s5TwuhhbQfQnJK8se+mzKG~$uSYODNP)5H*8}YW?-zeSFR^Z zR_ey+!ewzCH0nSWUrleiSiY}rRz!>jotO`@_;MDnyo7ME!b=z~whdEEraX2HwYHBz zbMaKs+DQh@U01nXte28MdT_6%3+%Fg@j6H8SOg%YlfHDgm=wXiwq7VJ zG8>&TI0u(RR1LSA--g8iY6cM62bVA|&%|5udCSI&1ld6h=dV$@UsB~Z-AqIxaU+1$ z`k<}-eT&I*RQ!jeK8Y^47?o6=Wc2M-jg=RJ4F~s11bO4f{jG?uxvM|TAC4KlQGv%|GZt_+ebUsAF?TJ zBZ}2qG^m&R{ux>L4!f|7vP9w3!1-xf_*z$P7w*j)sWE8aBwtVCPDFM;!`JgXwR)~- z6g61GcG=y4Jn<~M46ANz04o;Kfakpu=nGoB3voI;U&2{6WAy9_TjpPH@Lx|p)0u{q zT*J+b0+bBel#zR4GKZv2-BXrr^M$Nf4~{qVv#xOae=j@u=rO?dVLyV~=w}NYP$JA- z_%FlUcQ3FhTNaR}N3qt{fh`e3)Ber<1u}!5DAOY|&|xbFCG2odE@}ac4S8^3Kr6oL zNWTZe+WB7PDCulh6Fc{g?fxMW9g$^7+aw)3rvMaewu+(RaN zg4QLr%&%Xq`&J4&ueeUgN@C}i&vM&&oN{i0leTJHp882;4GGs480XYsZo$ghzl;h_ zL#<}N2{68muf?MHgZRRKEU-;0mHf!nedKN9Vu6{apvL> zU1<;9@Xn8nI z!c?5dWYop?!o&b3V4pEa<2;)3e9z3GtK6d)q|@MNjjn=UkJ1xEA-V%I=pU1z$Dp1{1C%PF@95T;a z{Vytp+rOdrg*hJB&FY?8id_|)yA4>0TS^SBMoT%dz=}rMQXQDgc(;_0WwccNr);bE z_H^@tfAYxy``;?LubZf)e8mOh?(f-B={V{jn?7Y+FxgUjRD=MdrQ$paPI=mK!C)ZV zq5Kc)bgIKsh;BGzf z^;FmX(vH!UG@>M2rf$|Hx%RhTl4V+_C%cTtu(SgJN~tp@DQe{_vLx63nm#MY(yb$t zNn-1-z%b;JG-RcY3s!KPAoCL!Y($cfFOB+$3)YY0Jw^fj#0A^>PlALb4OywL{jIk* zbg}H^H!fINY%|wrr_@mr^0Gw%&A4C@;2Gl(Ro*JR7Gl^4(kZ7<7)LaW)Gk0rm5LhU zX4VZNwF&swpzQ~6H)yjk4KQfiuNSG2B|4Sm7A_X4{1c;GDwdm$DW$==bfKVaTOd;V zuhywdTQgszwqvcsD039cEe7X844_7td*+B#TC6f?E6YS`8hQ(Lh<+8Amw`VkZd_fz zXj$!|+NEpOgtD+PWY7$wyC|A8dLo+8;CcANM#tq0;8n@r2OCgEw;cJxytRS{2GD5= zK=Z*IeFE}#NF;Er3Zc9p5v#Y(Y>qkHYPp>^cSDFn)SKS-`-xL222KO@v-`@eO$ zgV6YZ+z2)HxT?|n*nr>7CpkX$xbgwVjaL4c@M^{Aqk3rvuA1eTeRfnYcHWrDtEgTh zfE`xR{i*Qkj!a$27&;lUE>(~)30~a{52AEqr z_331i7_Vl=BjX|K7b)vBD9JLdA0(5+b?TB}TGgpDWt}!jK%H)VC7C3y)8cq!><6zB zBoytm5?%nOtp{5U^N4KBbxH^3GDuXNQsdPDNoM2Kt?2%tevDAYFvr1X85yE*h|_@K z)JSc|Xlh`v!X+Y=gU>p&JrY%>W5>gwZNr9(!I^{4I<$ENGMxdt2D@1XZFHVU<>0dp zZ4*XhgSIDzDjBa<0)iQ-9DLTHjl@tT1BE;SkDSW1U6%`5zT)E0md+HZO_vJV!D5{X z4~&=$^y=W%&PxCtpiLAFPX?wa269oDA{$UeB`~C^n}!5}IHBlNBEyr4%hpFI1dAzv zIp^Yufl5A}6fG^~h5FAC6qyCcM<6y7K1(E2Owp{W!C$fJz*O5{RY|Xo@Qr6^R^6xR zeAg4_-drTWm;#|d4j@+zp5_J#9EFx`7p4te(#TSej;*pZ!YimO zBLF9c+A{H~#0_FV;)J3VkQSbc;ha7U#rDupO3SOj=o*UcLShVxWvLg6-W7K|hKT6< zcr37%*fK0~;jFK6LMogUAJq$y_-%$REYP7Cx^R}is9v-TYvF3Ivw90t6TlOj# zrR!lWE=f^qh9XOXrphGVA+2yUJH>B zWOU)W$J@S8r!sAHfuJp{)TvC{BUjx9 zMhHR*y$vWTlBr zLcJ=1Rk9IERVv9MnCg^j7^@gccp5#ib?w!FRasYT!H}ZX!D=ye2eL|yc_wJ z(9_^^IsxM;Tp_(W)#~j+KG+(5$K%I3-(q_0d{#54#go!0C#9uVU3H9IBtQx3m$RFugj}@0^8vT&@1gM8dWbEpqovEwXinX2qp1q*sSkU9lFK z9ux@!7im_*(=@B@LcywrUL96ju)m-bQB|Pxv9jy1ccPR%c$P>A;8i6wM&hDgnX>$ray>; zYD=@KkKl==W&K`c8UA;jC5@gqOaEIU%eFUlmfibwmhLx@h3m^buZCWo0&VF>KJIz> zeL5fOrTBFuuwHsz6%<>0wTx}A;E5|e^0KC7-M7=LBV+$w=TlZ6uud`bxbU&*TxR$-oAc1RHh9|=;7H`uD zk*9==-A^Kc&7!XpPh9QHQ4fP5L$VQc5pcbu+!WEH1ylOn0L645 z6Hl!1d^{PBtY1z+>F2SO4*Z7f4nUPfFl;;MS1{E1X-xjZr%*xh;hNNvE9kB8 zIb8VPZ1#I;4a-Ba&{fz7dYhwv>6_-Rb5y2{>*gDjCvep9d)~63X!Km9%UgXGX$$;F zk|M>ateDK{VyU7OSM~D2M2f&kGgmiyq@b2zd_y^kE)p1UKf^I<@ zl=>YLU$yt?9TMyT@-dX3c7wgVl-Dg`?!>N;U>J-7))d7|hvRy{_Fcm+-_>)!&%h>k z6H`DNuA#jZ{Xn&PPk0-dTYCMmc1u@1s#`jm{7jd#vtsW;+BL_KJXd3U>X+^tlU@q> z1Y>+nJ>IVDs%CP9>X;ZnN{XN$nZRs@;bBbk@MB)>&sJ~7V*5U|(^j)xMEo1o19>ZN zKkSWr;O-`;sG>!MFEsjY4@O?5yuZn3i_(vVnDyJ0uthKIakpq(6|cZBXy%nn9{PT(!om^`@>MdV2)jponO-xaZYK90oMo!z{=}8SyV{1v#q>@_i)n) z`gLPFfR#6!W%@Yc*m$atr7zHWnS+=0V|^!JVQGie#p>{|2)<99cbZ+ar|xqs!j~d5 zC)t$YM@Fg0s7(pYII%;7B83$iBQpJNA1gBLK9cD}k?jD}9#-h3$T*{W0R{BFb}#J2 zeeJ#;z}^t4?oQW&7Y!7&c`j|!s9x1%yLzWR9IGCU4ooCuxVjz3f?J;p^{V_cQ0YHUoq+^Krvm>H#K+f_faF)^O> zYBjH7Hc-Re<%k_JkGeMu8XC_%#}@l^1BvCf+E4^aNnxB(8q^f`Fa_MUN0?u)g2tJb z>9)x(5}#=5#;lXg{s@+-PBaO(Esp6JZhPxgoAULq=uVnqAg(=MQ9uXkIFMbJ_alG2@mZoPDoWHe#xc zTx#p+&WA`xK4Plv#)LXfH)2c>?O}MR4wwn|f}@-;-~PsgO(jBRY)o+Omg`xaYclaJ z8OvKrA<8j{!Wm#H2fm#PSAUl_7N1}$eU>Pk2bdBv4TTKZl#u|-^nn4oN`)*9rfAOP z40my6@&ak$C-G)6C?_)RUQm055au!ZC#qP*m9{cZzmt^774z59!7?E;*3$9aV{fH6TEk^%1bsU}!b&SOybLhX()r;=6)kUhM>8xSl+FN@fbDlI-U>%5!>2$x#1KH)? z^%f25<;JlM5wO0j3d)A6Ta2_oq_RO^lcYg~tPV)1vT%Cc8Moa9?PnYQ8ONDa+#Xo3gjKN4VUpg{)ZDjJMpQ zpL08QuZI2T0l~@^*k%9zZ4TP-v|rJG4Xjo1MVrI&+q5%GvG$aW-4kO}i1pi)_M6x@ z2|VHUP5S`N4SDcQfFYx*)3Ivkm+5=IB%2K&V}}k1LM>}~3 zWjmj^M3hVnK?yMuckL0IGIA%&@?qz@uM@J8*!h`1cH4QJa+bpDT8mw-*JGqg3}6CF zZDn=yJlY3<>9Hx`3TaxPhBY9ycrY$7qI;e?uuSN|+Zwz&_OlSB<7=B9J8=+4ZsV;r zLY`=2wPqvi$$%NHD{K{g-EVyDiW`KiSR0Gp9M_olP{r0ciu8-0&~1&btSW{%bRfCE z9gt+PGRFJc$G3SRg%*4*mcnnx7ybi*4Xm`aI&+x3Y+N8PbCErVIUmwMVEgN!A^za} z{-Fv4b_Z>_*@3`nzcZRZU^g0+=YG{^Ah3l7(ckZNwZ`C62n2T4t2z+a;H&y9(-_n` zw3%LknF2-R^iu}{8=Ei?*opoEfzb}GI}liJF9Lzl#?jm$l_J!NcU36ZMj(6)R+s3* z+bhj!%E16n#xBp{7^ZW14&B?|b{LNIDRBA3fw2_6AoY@(D-c-PE?S~V3AgsaEi;I{ zjOF+khA0?UTu%nt_hOP^L&nbr6f1tOL zISANVy6={9LvS6`Y$b0Y;cyN3s{UN{E_7NXrX+$ zo2z_nd<*#s{>5G1vxO!e;clUn!M|h+y-tAyL<{j?gDu+w$JsFmPod_)8BeDJjc&8F z!rsA!brK2?8c#72yMEUxkrI7f|6>>Esl-=CAN)%y@j)H@>q>3?xF2`Gx)m$))=xsI zuK)Gnq>QpiBbdT$b;B;n^}kLWwK2#tt+SI|%3}z+4j{=OVF+qXRb)x7|5bigkfmG4 zCX>VvD%al2MUzv+EB2f|f`0`t)iny}C-~Q1NuugBR>dnwQm1yz&kad_f`8GqZ-YeD zDfRWga(k!ORz;?jI+#LsY?n8ty{MJ?`d?I%nZdvEfMJZYUo{vt)!i6crogX=i_|DE zsY*qSaStA#)}ZZKu2Y$o<1*wUpSt8gc zv`v^P8)fFW3=VA;)&vaNb}UC2v=OW*8?+pk!J!QU-59j#SW+@*OK0m;E;GkvaA^BO zI+b-5q*qRbzr^XiQv4z8q)rj4^b9+Lt{+ z?Z3X|hD^Nn;5y}o+dKyqEvyo)qedHrnmkYXkUH(zMT%%)n=nH%*g>~g#fyid6Jn}x z=@tPSD7Y6v#qBo|%JD=}&&5Rxqob;xQG+k{)a`AlqlG1$EhLT>*7O?Ci(EBJh zN$N6$+7x#6I;+U2Cl6?xo$^zd(J9p9G>=%~avu|-!_KmK5T-G{c@7fjo-q2TVcPSn zs9|sX7N!sX?>b$#3&6uV?4ndacPpkAs**8SGh|IuSTYIFT`%!*rgcIx_{l)GOk!gN z3Ud@$5>S{Y@o~B}Hkl-D@?lA$K;h1mb?TLnI@9`2GD%#g&GC>rYPF}VQ&{5TbnE_P zlDJMK06KB)lp5&fNPO%E=nhH})lR8_ZjXf2HqiYZMyOB?R*#JFv7N9h#z;HLZIrO9 zGkO+cVc7tFJ%nAI)b#6hDg(dDB_g$Lkxpgcmxmn-gSLjSt0T9Iu&cv4TB%c+wu!K- zliEYr)uGL*5UG_{=~SkTV4yc>^XBMOE_0Z$tHZhLN}bBI^qW&gY7>D~M{YlGi;6C<49`I;7^S|AjeDkyS*f7CskbU+`2)j)w}H4G%ASaqKzSk=(0qp&S_ zRIK*q>3pk5B%LW#pf2-NfVz5oH#bPAD%6HGGlN6@=d{emY&^kH214!7ppm5!O{HqM z34K*%$$$eh)RqGmsKkw6px}g}wO|!K*Tirf_0(t7u(-oav|38L@9~4qd>*MOn5qjC z)N?|rMa1~1VXI;cU3lvO#n82g=r3y6U!e|b2!Cjf!qJbROg?wuI?4XV%j)Z-P_+0k zdnE5bZhbsEUNr{^m*&KU0~;k=I`U;V6vYrLZxkhgOXB>Wv5Peo-Hl<)k46iZvgM+u z4VQ!*1Mm0Qxg)b!4tal{aH-n{bf~Oz7&yLp4iYYP?t^xnjW|Tfz6LWCPc(Z6Cme8D z?kXJ?j3>$HnJUO?Wd=<3(KA!QrE*ME;)dbd)##lBF6CzmvP`Qg*?`Z`A}UGLFuX*O zC4ozHr_U&0x-~PIB!(7S;K&RTzi?@t#B+Y&QfWLe^8=T1KPw982QE>_qPRMxhD&=T zp7R5j+ThY$lKiX-)?pC$MRW8OW5AqNp#{H`Eb;3$2S|?$go9U?#P{xou@hl`TT*{q-Cx%OdlQk{eCJ+j} za#^^Ry=NdFJQ9|H3F9~kn+W4DtF4nXtJ>3$g$vHCvgp;JC_h!RT6dDp$8d?R^{9H( zo}d#LE$x7If`pzzo6(CDXW%5PjnS*ac|9C}ec>1$#K_kRAEXkTIAAQ2D~g5bh40SL!ZYxsXxSvX@YkRiLT+VU$-{ziJz5VFtP1JXsd*jHp<=b;6@*t|>kqzU zp94_fyKXNMlsWxECvc5=5hYC3sOv=}aHqy35-~zv(D`cVb>mNw?d;)yj> z(GeM@61F|2S?xx= zFeR=38#2qIu`FNLS!%u}vXnfcvs65+vusAFFvEsQ>D4LF`mZ2g2DL)>13Dk;w6_%r z+**|_f?_JJK`YgjG;0~H2oDzc&}!)7ooxoR$+Q| zSao7YMzM`9@@tX6?a^N) zD7Gy`f->bV;)%HQ6Ge0ethi&0&R0vXI|4}HwoLyAULA^o5k0~Ve~2gU*lm9kS?Z%Y zOXK@^Qa#{5k%e&?w`%mSf}&s;`B=|ge-a6s{-{}P9mEq$D}7I7$^C=QGS$*q(%%(X z2L4TF8Q!n648DadTp;dhZS?BYvUeZyanGyj*ZEj4b-zXe>m~ZHf}*ca%NTeaPh9DI zJQ>}-|2098`6}{dkg{7}(fPP6h4ku_rS2u<wb&UgyhyM(1N46mLTU>!AB-k~A( zwaC^M&5A`9(yJq~u33w0`;thgzfZGj+@M*NH40YI20>A9uVyv4PUov76Aj>1wRzL+ zf};91Eu%iHWpv-FX}Po4(5qA2Eo+gFm7QI$^Rb3{)`)xow5>h*p$G

KkJsZ@?2f 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%0Aa4Rmeg*CW^pF$CiS)6`*k(>7K`?ku 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 z

b9)%IEJS`3Z6%guXc^dLLwYIrOSe;;8Bv+l# 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