home *** CD-ROM | disk | FTP | other *** search
- ;;; (C) Copyright 1990-1992 by Wade L. Hennessey. All rights reserved.
-
- ;;; Emit object x and all of it's sub-objects.
- ;;; Returns a string of C code which references the object.
- (defun emit-data (x)
- (cond ((wcl-fixnum? x) nil)
- ((characterp x) (format nil "char_tab[~D]" (char-code x)))
- (t (let ((label (gethash x *const-labels*)))
- (if (null label)
- (typecase x
- (symbol
- (let ((label (lisp->c-symbol-name x)))
- (if (null *emit-symbol-data-function*)
- (emit-win ":sym ~S~%" x)
- (funcall *emit-symbol-data-function* x))
- (emit-k "extern SYMBOL ~A; ~%" label)
- (setf (gethash x *const-labels*) label)))
- (t (let ((label (genstring "k")))
- ;; for circ consts
- (setf (gethash x *const-labels*) label)
- (etypecase x
- (vector (emit-vector label x))
- (array (emit-multi-array label x))
- (inner-proc
- (emit-null-oe-proc label x))
- (foreign-symbol (emit-foreign-symbol x))
- (cons (emit-cons label x))
- (float (emit-float label x))
- (ratio (emit-ratio label x))
- (complex (emit-complex label x))
- (compiled-function
- (emit-compiled-function label x))
- (structure (emit-structure label x))
- #-native-wcl
- (byte-specifier (emit-cross-byte-specifier label x))
- (integer (emit-bignum label x)))
- label)))
- label)))))
-
- (defun emit-lref (x)
- (if (wcl-fixnum? x)
- (format nil "(LP) ~D" (ash x 1))
- (format nil "LREF(~A)" (emit-data x))))
-
- (defun emit-foreign-symbol (x)
- x (error "fix"))
-
- (defun emit-float (label x)
- (emit-k "MAKE_FLOAT(~A,~F);~%" label x))
-
- (defun emit-ratio (label x)
- (let ((numerator (emit-lref (numerator x)))
- (denominator (emit-lref (denominator x))))
- (emit-k "MAKE_RATIO(~A,~A,~A);~%" label numerator denominator)))
-
- (defun emit-complex (label x)
- (let ((real (emit-lref (realpart x)))
- (imag (emit-lref (imagpart x))))
- (emit-k "MAKE_COMPLEX(~A,~A,~A);~%" label real imag)))
-
- (defun emit-cons (label x)
- (let ((car (emit-lref (car x)))
- (cdr (emit-lref (cdr x))))
- (emit-k "MAKE_CONS(~A,~A,~A);~%" label car cdr)))
-
- (defun emit-null-oe-proc (label x)
- (emit-k "MAKE_PROCEDURE(~A,~A);~%" label (proc-c-name x)))
-
- (defun emit-vector (label x)
- (cond ((simple-string-p x) (emit-simple-string label x))
- ((simple-array-p x) (emit-simple-1d-array label x))
- (t (emit-complex-1d-array label x))))
-
- (defun emit-multi-array (label x)
- (if (simple-array-p x)
- (emit-simple-multi-array label x)
- (emit-complex-multi-array label x)))
-
- (defun emit-string-using-c-syntax (string)
- (write-char #\" *k-stream*)
- (loop for c being the array-elements of string do
- (case c
- (#\newline (write-string "\\n" *k-stream*))
- (#\\ (write-string "\\\\" *k-stream*))
- (#\" (write-string "\\\"" *k-stream*))
- (t (write-char c *k-stream*))))
- (write-char #\" *k-stream*))
-
- (defun emit-simple-string (label x)
- (let ((len (length x)))
- (if (< len 80)
- (progn (emit-k "MAKE_SIMPLE_STRING(~A,~D," label len)
- (emit-string-using-c-syntax x)
- (emit-k ");~%"))
- ;; ARGHH!!! We cannot use MAKE_SIMPLE_STRING because the losing
- ;; MIPS cpp(1.31) will only pass strings of <= 80 chars as args!!!
- (progn
- (emit-k "static struct {unsigned long header; char string[~D+1];}~%"
- len)
- (emit-k "~A = {((~D << 8) + TYPE_SIMPLE_STRING), ~%"label len)
- (emit-string-using-c-syntax x)
- (emit-k "};~%")))))
-
- (defun emit-simple-1d-array (label x)
- (multiple-value-bind (element-type-tag element-size default-initial-value)
- (type->element-type-tag (array-element-type x))
- (declare (ignore default-initial-value))
- (let* ((objects (if (= element-type-tag element-type-bit)
- (bit-vector->word-list x)
- (loop for e being the elements of x
- collect (if (= element-type-tag element-type-ptr)
- (emit-lref e)
- e))))
- (object-len (length objects)))
- (declare (ignore default-initial-value))
- ;; Sun CC doesn't like 0 element arrays, so we include an unused
- ;; element (gcc doesn't seem to care). This is consistent with
- ;; zero length heap allocated vectors, although static vectors
- ;; don't really need the extra space since they will never be
- ;; converted to a forwarding pointer.
- (let ((c-type (select element-size
- (1 "unsigned long")
- (8 "unsigned char")
- (16 "unsigned short")
- (32 "LP")
- (64 "unsiged double"))))
- (emit-k "static struct {unsigned long header; ~A cells[~D];} ~%"
- c-type
- (if (= object-len 0) 1 object-len))
- (emit-k "~A = {0x~X, ~%{"
- label
- (+ (ash (length x) 8) element-type-tag))
- (if (= object-len 0)
- (emit-k " 0 ")
- (loop for rest on objects
- unless (eq rest objects) do (emit-k ",")
- do (emit-k "((~A)~A)" c-type (car rest))))
- (emit-k "}};~%")))))
-
- #-native-wcl
- (defun bit-vector->word-list (bits)
- (declare (ignore bits))
- (error "Cannot cross-emit bit vectors"))
-
- #+native-wcl
- ;;; This should be byte-order independent, since words are words....
- (defun bit-vector->word-list (bit-vector)
- (loop with word-len = (/ (object-size bit-vector) 4)
- with word-vector = (make-array word-len
- :displaced-to bit-vector
- :element-type '(unsigned-byte 32))
- for i from 0 below word-len
- collect (aref word-vector 0)))
-
- (defun emit-complex-1d-array (label x)
- label x
- (error "write complex-1d array emitter"))
-
- (defun emit-complex-multi-array (label x)
- label x
- (error "write complex multi-array emitter"))
-
- #-native-wcl
- (defun emit-simple-multi-array (label x)
- (declare (ignore label x))
- (warn "Cannot cross-emit simple array ~A, emitting a string instead" x)
- (emit-simple-string label "foobar"))
-
- #+native-wcl
- (defun emit-simple-multi-array (label x)
- (let ((header (object-header x))
- (underlying-vector (emit-lref (array-underlying-vector x)))
- (dims-vector (emit-lref (array-dims-vector x)))
- (multiplier-vector (emit-lref (array-multiplier-vector x))))
- (emit-k "static SIMPLE_MULTI_ARRAY ~A = " label)
- (emit-k "{0x~X, ~A, ~A, ~A};~%"
- header
- underlying-vector
- dims-vector
- multiplier-vector)))
-
- #-native-wcl
- (defun ref-structure-as-vector (s i)
- #+kcl (si:structure-ref1 s i)
- #+lucid (system:structure-ref s i (type-of s)))
-
- #-native-wcl
- (defun compiled-function-name (f)
- #+kcl (si:compiled-function-name f)
- #+lucid (system::procedure-name f))
-
- (defun emit-compiled-function (label x)
- (let ((c-name (lisp->c-proc-name (compiled-function-name x))))
- (emit-k "~%extern LP ~A();~%" c-name)
- (emit-k "MAKE_PROCEDURE(~A,~A);~%" label c-name)))
-
- #-native-wcl
- ;;; Bletch. Cross compilation hack to emit constant byte specifiers
- ;;; as a structure.
- (defun emit-cross-byte-specifier (label x)
- (let* ((len 3)
- (type-label (emit-lref 'byte))
- (objects (list (emit-lref (byte-size x))
- (emit-lref (byte-position x)))))
- (emit-k "static struct {unsigned long header; LP type;")
- (emit-k "LP cells[~D];} ~%" len)
- (emit-k "~A = {((~D << 8) + TYPE_STRUCTURE), ~A,~%{"
- label len type-label)
- (loop for rest on objects
- unless (eq rest objects) do (emit-k ",")
- do (emit-k "~A" (car rest)))
- (emit-k "}};~%")))
-
- (defun emit-structure (label s)
- (let* ((name (type-of s))
- (info (lookup-structure-info name)))
- (if (null info)
- (error "No structure info found for ~A" name)
- (let* ((len (struct-info-length info))
- (type-label (emit-lref (struct-info-name info)))
- (objects (loop for i from 0 below (1- len)
- collect (emit-lref
- (ref-structure-as-vector s i)))))
- (emit-k "static struct {unsigned long header; LP type;")
- (emit-k "LP cells[~D];} ~%" len)
- (emit-k "~A = {((~D << 8) + TYPE_STRUCTURE), ~A,~%{"
- label len type-label)
- (loop for rest on objects
- unless (eq rest objects) do (emit-k ",")
- do (emit-k "~A" (car rest)))
- (emit-k "}};~%")))))
-
-
- (defun wcl-fixnum? (n)
- #+native-wcl (fixnump n)
- #-native-wcl (and (integerp n) (<= n 1073741823) (>= n -1073741824))
- )
-
- (defun emit-bignum (label n)
- (let* ((abs (abs n))
- (hex-digits (write-to-string abs :base 16))
- (len (length hex-digits))
- (bignum-len (ceiling len 8))
- (header-len (+ (* bignum-len 4) 8))
- (header (+ type-bignum (ash header-len 8))))
- (emit-k
- "static struct {unsigned long header; unsigned long len; ~
- int sign; unsigned long digits[~D];} "
- bignum-len)
- (emit-k"~A = ~%{0x~X, ~D, ~D, {" label header bignum-len (if (> n 0) 1 -1))
- (loop for high from len downto 0 by 8
- for i from (1- bignum-len) downto 0
- do (progn (emit-k "0x~X~A"
- (subseq hex-digits (max (- high 8) 0) high)
- (if (= i 0) "" ","))))
- (emit-k "}};~%")))
-
-
-