409 lines
12 KiB
ArmAsm
409 lines
12 KiB
ArmAsm
|
|
|||
|
; -*- Mode: Lisp -*- Filename: pboot.s
|
|||
|
|
|||
|
; Last Revision: 3-Sep-85 1500ct
|
|||
|
|
|||
|
;--------------------------------------------------------------------------;
|
|||
|
; ;
|
|||
|
; TI SCHEME -- PCS Compiler ;
|
|||
|
; Copyright 1985 (c) Texas Instruments ;
|
|||
|
; ;
|
|||
|
; David Bartley ;
|
|||
|
; ;
|
|||
|
; Bootstrap Driver ;
|
|||
|
; ;
|
|||
|
; ;
|
|||
|
; This routine contains compiler-specific code which should be used ;
|
|||
|
; when compiling the compiler itself. It is generally loaded by the ;
|
|||
|
; file "COMPILE.ALL" which handles compilation of the compiler and ;
|
|||
|
; runtime routines. ;
|
|||
|
; ;
|
|||
|
; The file contains compiler-type definitions and macro definitions ;
|
|||
|
; which must be included when compiling the compiler files. ;
|
|||
|
; ;
|
|||
|
;--------------------------------------------------------------------------;
|
|||
|
|
|||
|
(begin
|
|||
|
;
|
|||
|
; Define aliases for the major parts of the compiler
|
|||
|
;
|
|||
|
(alias pme pcs-macro-expand)
|
|||
|
(alias psimp pcs-simplify)
|
|||
|
(alias pca pcs-closure-analysis)
|
|||
|
(alias pmr pcs-make-readable)
|
|||
|
(alias pcg pcs-gencode)
|
|||
|
(alias ppeep pcs-postgen)
|
|||
|
(alias pal pcs-princode)
|
|||
|
(alias pasm pcs-assembler)
|
|||
|
|
|||
|
;
|
|||
|
; Initialize compile-time variable definitions
|
|||
|
;
|
|||
|
(set! pcs-local-var-count 0)
|
|||
|
(set! pcs-verbose-flag #!true)
|
|||
|
(set! pcs-permit-peep-1 #!true)
|
|||
|
(set! pcs-permit-peep-2 #!true)
|
|||
|
(set! pcs-error-flag #!false)
|
|||
|
(set! pcs-binary-output #!false)
|
|||
|
|
|||
|
;
|
|||
|
; Set up variables to hold compiler-intermediate data and timing info
|
|||
|
;
|
|||
|
(define pme= '())
|
|||
|
(define psimp= '())
|
|||
|
(define pca= '())
|
|||
|
(define pcg= '())
|
|||
|
(define ppeep= '())
|
|||
|
(define pasm= '())
|
|||
|
(define problem)
|
|||
|
(define t-0)
|
|||
|
(define t-pme)
|
|||
|
(define t-psimp)
|
|||
|
(define t-pca)
|
|||
|
(define t-pcg)
|
|||
|
(define t-ppeep)
|
|||
|
(define t-pasm)
|
|||
|
)
|
|||
|
|
|||
|
;;; --------------------------------------------------------------------
|
|||
|
;;;
|
|||
|
;;; "Type definitions"
|
|||
|
;;;
|
|||
|
;;; The following macros are used by the compiler itself and must
|
|||
|
;;; be defined when compiling the compiler. By keeping them here,
|
|||
|
;;; the macro definitions will not be around in the object files
|
|||
|
;;; of the compiler
|
|||
|
;;;
|
|||
|
;;; --------------------------------------------------------------------
|
|||
|
|
|||
|
(macro pcs-make-id ; PCS-MAKE-ID
|
|||
|
(lambda (form)
|
|||
|
(let ((name (cadr form)))
|
|||
|
`(begin
|
|||
|
(set! pcs-local-var-count (+ pcs-local-var-count 1))
|
|||
|
(list 'T ; the symbol T, not #!TRUE !!
|
|||
|
(cons ,name
|
|||
|
pcs-local-var-count)
|
|||
|
'() '() '())))))
|
|||
|
|
|||
|
|
|||
|
;;; ---- (t (original-name . unique-number)
|
|||
|
;;; funargsees? freeref? set!? . init) ----
|
|||
|
|
|||
|
(begin
|
|||
|
(syntax (id-name id) (caadr id))
|
|||
|
(syntax (id-number id) (cdadr id))
|
|||
|
(syntax (id-funargsees? id) (car (cddr id)))
|
|||
|
(syntax (id-freeref? id) (car (cdddr id)))
|
|||
|
(syntax (id-set!? id) (cadr (cdddr id)))
|
|||
|
(syntax (id-init id) (cddr (cdddr id)))
|
|||
|
|
|||
|
(syntax (id-rtv? id)
|
|||
|
(or (id-set!? id)
|
|||
|
(null? (id-init id))
|
|||
|
(lambda-closed? (id-init id))))
|
|||
|
|
|||
|
(syntax (id-heap? id)
|
|||
|
(and (id-funargsees? id)
|
|||
|
(id-freeref? id)
|
|||
|
(id-rtv? id)))
|
|||
|
|
|||
|
(syntax (set-id-funargsees? id val) (set-car! (cddr id) val))
|
|||
|
(syntax (set-id-freeref? id val) (set-car! (cdddr id) val))
|
|||
|
(syntax (set-id-set!? id val) (set-car! (cdr (cdddr id)) val))
|
|||
|
(syntax (set-id-init id val) (set-cdr! (cdr (cdddr id)) val))
|
|||
|
)
|
|||
|
|
|||
|
;;; ------ (lambda bvl body . (nargs label . closed)) ------
|
|||
|
|
|||
|
(begin
|
|||
|
(syntax (lambda-bvl x) (car (cdr x)))
|
|||
|
(syntax (lambda-body x) (car (cddr x)))
|
|||
|
(syntax (lambda-body-list x) (cddr x))
|
|||
|
(syntax (lambda-nargs x) (car (cdddr x)))
|
|||
|
(syntax (lambda-label x) (car (cdr (cdddr x))))
|
|||
|
(syntax (lambda-debug x) (car (cddr (cdddr x))))
|
|||
|
(syntax (lambda-closed? x) (car (cdddr (cdddr x))))
|
|||
|
|
|||
|
(syntax (set-lambda-body x val) (set-car! (cddr x) val))
|
|||
|
(syntax (set-lambda-nargs x val) (set-car! (cdddr x) val))
|
|||
|
(syntax (set-lambda-label x val) (set-car! (cdr (cdddr x)) val))
|
|||
|
(syntax (set-lambda-debug x val) (set-car! (cddr (cdddr x)) val))
|
|||
|
(syntax (set-lambda-closed? x val) (set-car! (cdddr (cdddr x)) val))
|
|||
|
|
|||
|
(macro pcs-extend-lambda
|
|||
|
(lambda (form)
|
|||
|
`(let ((x ,(cadr form)))
|
|||
|
(set-cdr! (cdddr x) ; X = ('lambda bvl body nargs)
|
|||
|
(list '() ; label
|
|||
|
'() ; debug info
|
|||
|
'())) ; closed?
|
|||
|
x)))
|
|||
|
)
|
|||
|
|
|||
|
;;; ------ (letrec pairs body) ------
|
|||
|
|
|||
|
(begin
|
|||
|
(syntax (letrec-pairs x) (car (cdr x)))
|
|||
|
(syntax (letrec-body x) (car (cddr x)))
|
|||
|
(syntax (letrec-body-list x) (cddr x))
|
|||
|
|
|||
|
(syntax (set-letrec-body x val) (set-car! (cddr x) val))
|
|||
|
)
|
|||
|
|
|||
|
;;; ------ (if pred then else) ------
|
|||
|
|
|||
|
(begin
|
|||
|
(syntax (if-pred x) (car (cdr x)))
|
|||
|
(syntax (if-then x) (car (cddr x)))
|
|||
|
(syntax (if-else x) (car (cdddr x)))
|
|||
|
|
|||
|
(syntax (set-if-pred x val) (set-car! (cdr x) val))
|
|||
|
(syntax (set-if-then x val) (set-car! (cddr x) val))
|
|||
|
(syntax (set-if-else x val) (set-car! (cdddr x) val))
|
|||
|
)
|
|||
|
|
|||
|
;;; ------ (set! id exp) ------
|
|||
|
|
|||
|
(begin
|
|||
|
(syntax (set!-id x) (car (cdr x)))
|
|||
|
(syntax (set!-exp x) (car (cddr x)))
|
|||
|
|
|||
|
(syntax (set-set!-id x val) (set-car! (cdr x) val))
|
|||
|
(syntax (set-set!-exp x val) (set-car! (cddr x) val))
|
|||
|
)
|
|||
|
|
|||
|
;;; --------------------------------------------------------------------
|
|||
|
|
|||
|
(define pcs-make-readable ; PCS-MAKE-READABLE
|
|||
|
(lambda (x)
|
|||
|
(letrec
|
|||
|
;-------!
|
|||
|
((pmr-exp
|
|||
|
(lambda (x)
|
|||
|
(if (atom? x)
|
|||
|
x
|
|||
|
(case (car x)
|
|||
|
(quote x)
|
|||
|
(t (pmr-id x))
|
|||
|
(lambda (pmr-lambda x))
|
|||
|
(letrec (pmr-letrec x))
|
|||
|
(else (mapcar pmr-exp x))))))
|
|||
|
|
|||
|
(pmr-id
|
|||
|
(lambda (x)(cadr x)))
|
|||
|
|
|||
|
(pmr-full-id
|
|||
|
(lambda (x)
|
|||
|
`(t (,(id-name x) . ,(id-number x))
|
|||
|
(funargsees?= ,(id-funargsees? x))
|
|||
|
(freeref?= ,(id-freeref? x))
|
|||
|
(set!?= ,(id-set!? x))
|
|||
|
(init= ,(if (id-init x) 'lambda '())))))
|
|||
|
|
|||
|
(pmr-lambda
|
|||
|
(lambda (x)
|
|||
|
`(lambda
|
|||
|
,(mapcar pmr-full-id (lambda-bvl x))
|
|||
|
,(pmr-exp (lambda-body x))
|
|||
|
(label= ,(lambda-label x))
|
|||
|
(closed?= ,(lambda-closed? x)))))
|
|||
|
|
|||
|
(pmr-letrec
|
|||
|
(lambda (x)
|
|||
|
`(letrec
|
|||
|
,(pmr-pairs (letrec-pairs x) '())
|
|||
|
,(pmr-exp (letrec-body x)))))
|
|||
|
|
|||
|
(pmr-pairs
|
|||
|
(lambda (old new)
|
|||
|
(if (null? old)
|
|||
|
(reverse! new)
|
|||
|
(pmr-pairs (cdr old)
|
|||
|
(cons (list (pmr-full-id (caar old))
|
|||
|
(pmr-exp (cadar old)))
|
|||
|
new)))))
|
|||
|
|
|||
|
)
|
|||
|
(pmr-exp x))))
|
|||
|
|
|||
|
;;; --------------------------------------------------------------------
|
|||
|
|
|||
|
;
|
|||
|
; filename-manipulating functions
|
|||
|
;
|
|||
|
(define filename-sans-extension
|
|||
|
(lambda (file)
|
|||
|
(let ((period (substring-find-next-char-in-set
|
|||
|
file 0 (string-length file) ".")))
|
|||
|
(if period
|
|||
|
(substring file 0 period)
|
|||
|
file))))
|
|||
|
|
|||
|
(define extension-sans-filename
|
|||
|
(lambda (file)
|
|||
|
(let ((period (substring-find-next-char-in-set
|
|||
|
file 0 (string-length file) ".")))
|
|||
|
(if period
|
|||
|
(substring file period (string-length file))
|
|||
|
""))))
|
|||
|
|
|||
|
;;; --------------------------------------------------------------------
|
|||
|
|
|||
|
;
|
|||
|
; Routine to compile a form, setting timing info and intermediate (between
|
|||
|
; compiler phases) data.
|
|||
|
;
|
|||
|
(define pcs
|
|||
|
(lambda (exp)
|
|||
|
(begin
|
|||
|
(set! pme= '())
|
|||
|
(set! psimp= '())
|
|||
|
(set! pca= '())
|
|||
|
(set! pcg= '())
|
|||
|
(set! pasm= '())
|
|||
|
(set! pcs-local-var-count 0)
|
|||
|
(set! problem exp)
|
|||
|
(set! pcs-error-flag #!false)
|
|||
|
(set! t-0 (car (ptime)))
|
|||
|
(set! pme= (pme exp ))
|
|||
|
(set! t-pme (car (ptime)))
|
|||
|
(if pcs-error-flag
|
|||
|
(error "[Compilation terminated because of errors]")
|
|||
|
(begin
|
|||
|
(set! psimp= (psimp pme=))
|
|||
|
(set! t-psimp (car (ptime)))
|
|||
|
(pca psimp=)
|
|||
|
(set! t-pca (car (ptime)))
|
|||
|
(set! pcg= (pcg psimp=))
|
|||
|
(set! t-pcg (car (ptime)))
|
|||
|
(set! ppeep= (ppeep pcg=))
|
|||
|
(set! t-ppeep (car (ptime)))
|
|||
|
(set! pasm= (pasm ppeep=))
|
|||
|
(set! t-pasm (car (ptime)))
|
|||
|
))
|
|||
|
`(Times- Total= ,(- t-pasm t-0)
|
|||
|
pme= ,(- t-pme t-0)
|
|||
|
psimp= ,(- t-psimp t-pme)
|
|||
|
pca= ,(- t-pca t-psimp)
|
|||
|
pcg= ,(- t-pcg t-pca)
|
|||
|
ppeep= ,(- t-ppeep t-pcg)
|
|||
|
pasm= ,(- t-pasm t-ppeep))
|
|||
|
)))
|
|||
|
|
|||
|
;
|
|||
|
; Compiles a given expression without executing the result
|
|||
|
;
|
|||
|
(define pcs-compile
|
|||
|
(lambda (exp)
|
|||
|
(set! pcs-verbose-flag #!false)
|
|||
|
(set! pcs-binary-output #!true)
|
|||
|
(set! pcs-local-var-count 0)
|
|||
|
(set! pcs-error-flag #!false)
|
|||
|
(let ((t1 (pme exp)))
|
|||
|
(if pcs-error-flag
|
|||
|
(error "[Compilation terminated because of errors.]")
|
|||
|
(let ((t2 (psimp t1)))
|
|||
|
(pca t2)
|
|||
|
(pasm (ppeep (pcg t2))))))))
|
|||
|
|
|||
|
|
|||
|
;
|
|||
|
; Set up compile-time aliases. When encountered in a source file,
|
|||
|
; anything assigned via compile-time-alias will be defined as
|
|||
|
; an alias, but will not be written to the object file.
|
|||
|
; See pcs-compile-file in this file !!!
|
|||
|
;
|
|||
|
(alias compile-time-alias alias)
|
|||
|
|
|||
|
|
|||
|
;
|
|||
|
; Compiles a given file without executing (unless form is a macro, alias,
|
|||
|
; syntax, or define-integrable) the result. Also report compilation info.
|
|||
|
;
|
|||
|
(define pcs-compile-file
|
|||
|
(lambda (filename1 filename2)
|
|||
|
(if (or (not (string? filename1))
|
|||
|
(not (string? filename2))
|
|||
|
(equal? filename1 filename2))
|
|||
|
(error "PCS-COMPILE-FILE arguments must be distinct file names"
|
|||
|
filename1
|
|||
|
filename2)
|
|||
|
(fluid-let ((input-port (open-input-file filename1)))
|
|||
|
(let ((o-port (open-output-file filename2)))
|
|||
|
(letrec
|
|||
|
((loop
|
|||
|
(lambda (form)
|
|||
|
(if (eof-object? form)
|
|||
|
(begin (close-input-port (fluid input-port))
|
|||
|
(close-output-port o-port)
|
|||
|
'ok)
|
|||
|
(begin (compile-to-file form)
|
|||
|
(set! form '()) ; for GC
|
|||
|
(loop (read))))))
|
|||
|
(compile-to-file
|
|||
|
(lambda (form)
|
|||
|
(let* ((cform (pcs-compile form))
|
|||
|
(nconstants (cadr cform))
|
|||
|
(nbytes (caddr cform))
|
|||
|
(name?? (car (cadddr cform))))
|
|||
|
(if (pair? form)
|
|||
|
(if (eq? (car form) 'COMPILE-TIME-ALIAS)
|
|||
|
(%execute cform)
|
|||
|
;else
|
|||
|
(begin
|
|||
|
(when (and (pair? form)
|
|||
|
(memq (car form)
|
|||
|
'(MACRO SYNTAX ALIAS
|
|||
|
DEFINE-INTEGRABLE)))
|
|||
|
(%execute cform))
|
|||
|
(writeln " " name?? ": ("
|
|||
|
nconstants "," nbytes ")")
|
|||
|
(fluid-let ((output-port o-port))
|
|||
|
(set-line-length! 74) ; was 120 !!
|
|||
|
(prin1 `(%execute (quote ,cform)))
|
|||
|
(newline)))))))))
|
|||
|
(loop (read))))))))
|
|||
|
;
|
|||
|
; Compile object code to file. The code generated by ppeep (the peephole
|
|||
|
; optimizer is written to the specified file.
|
|||
|
;
|
|||
|
;
|
|||
|
(define %compile-file
|
|||
|
(lambda (filename1 filename2)
|
|||
|
(if (or (not (string? filename1))
|
|||
|
(not (string? filename2))
|
|||
|
(equal? filename1 filename2))
|
|||
|
(error "%COMPILE-FILE arguments must be distinct file names"
|
|||
|
filename1
|
|||
|
filename2)
|
|||
|
(fluid-let ((input-port (open-input-file filename1)))
|
|||
|
(let ((o-port (open-output-file filename2)))
|
|||
|
(letrec
|
|||
|
((loop
|
|||
|
(lambda (form)
|
|||
|
(if (eof-object? form)
|
|||
|
(begin (close-input-port (fluid input-port))
|
|||
|
(close-output-port o-port)
|
|||
|
'ok)
|
|||
|
(begin (compile-to-file form)
|
|||
|
(set! form '()) ; for GC
|
|||
|
(loop (read))))))
|
|||
|
(compile-to-file
|
|||
|
(lambda (form)
|
|||
|
(let ((t1 (pme form)))
|
|||
|
(if pcs-error-flag
|
|||
|
(writeln "[Compilation terminated because of errors.]")
|
|||
|
(let ((t2 (psimp t1)))
|
|||
|
(pca t2)
|
|||
|
(set! ppeep= (ppeep (pcg t2))))))
|
|||
|
(fluid-let ((output-port o-port))
|
|||
|
(set-line-length! 74) ; was 120 !!
|
|||
|
(newline)
|
|||
|
(pp form)
|
|||
|
(newline)
|
|||
|
(pcs-princode ppeep=)
|
|||
|
(newline)))))
|
|||
|
(loop (read))))))))
|
|||
|
|
|||
|
|