;;; -*- Mode:LISP; Package:USER; Base:10; Readtable:CL; compile-in-roots: ("GLOBAL") -*- ;;;************************************************************************************************** ;;;***** This file should be identical to k-macros(-for-k-debugger) at all times WKF 5/5/88 ***** ;;;************************************************************************************************** ;;; These duplicate versions are needed to fool make-system since COMPILER-FOR-K and K-DEBUGGER ;;; both use this file and k-debugger loads it in the k-user hierarchy. ;;; The macros in this file are used by: ;; CONVERSIONS.LISP, MEMORY-MAP.LISP, QUANTUM-MAP.LISP, PCD-TABLE.LISP, REGION-BITS.LISP ;; AREA-DATA.LISP, ;; GC-RAM.LISP, TRANSPORTER-RAM.LISP, NUBUS-INTERRUPTS.LISP, ARRAY.LISP, ;; KOLD-LOADER.QFASL, ARRAY2.KFASL, CONTROL-PDL.KFASL, MAP-FAULT.KFASL, TYPE-PREDICATES.KFASL, ;; K2.KFASL, WARM-LOADER.KFASL ;;WKF 5/5/88 removed : from front of compile-in-roots above. ;compile-in-roots: ("COMPILER-PACKAGE-HIERARCHY") ; LOAD-QFASL-IN-ROOTS: ("COMPILER-PACKAGE-HIERARCHY" "SIMULATION-PACKAGE-HIERARCHY") -*- ;is to be loaded in both hierarchies, but compiled only in GLOBAL. For now, ; we will wind up READFILEing in the K-GLOBAL hierarchy until the load-qfasl-in-roots frob really ; exists. ;these moved to VINC and export eliminated. Reference package explicitly as needed. ;(export '( ; prims::defextractor ; prims::defflag-extractor ; prims::dpb-multiple-boxed ; prims::dpb-multiple-unboxed ; ) ; (find-package "PRIMITIVES" *package*)) ;;;;;;;;;;;;;;;;; ;;; DEFEXTRACTOR ;;;;;;;;;;;;;;;;; (prims:defmacro vinc::defextractor (name field) `(progn (PRIMS::DEFSUBST ,name (PRIMS::Q) (HW::LDB PRIMS::Q ,field 0.)) (PRIMS::DEFSETF ,name (PRIMS::Q) (PRIMS::VALUE) `(HW:DPB ,prims::value ,',field ,prims::q)))) (prims:defmacro vinc::defflag-extractor (name field value) `(PRIMS::DEFSUBST ,name (PRIMS::Q) (HW::32= (HW::LDB PRIMS::Q ,field 0.) ,value))) ;;;;;;;;;;;;;;;;; ;;; DPB Multiple ;;;;;;;;;;;;;;;;; (prims:defmacro vinc::dpb-multiple-boxed (&rest fields) (dpb-multiple-expander t fields)) (prims:defmacro vinc::dpb-multiple-unboxed (&rest fields) (dpb-multiple-expander nil fields)) (defun dpb-multiple-expander (boxed-result? fields) (cond ((null fields) (ferror nil "Even number of arguments to ~s" 'dpb-multiple)) ((null (rest fields)) (first fields)) (t `(,(if boxed-result? (intern "DPB-BOXED" (find-package "HW" *package*)) (intern "DPB-UNBOXED" (find-package "HW" *package*))) ,(first fields) ,(second fields) ,(dpb-multiple-expander nil (rest (rest fields))))))) ;;;;;;;;;;;;;;;;; ;;; Bytespec operations ;;;;;;;;;;;;;;;;; ;;; These are tools for manipulating byte specifiers. The idea is that you ;;; wouldn't need as big a vocabulary of byte specifiers if a certain minimal ;;; set could be combined in certain ways. ;;; BYTE-UNION Takes several byte specifiers and tries to produce a single ;;; byte specifier which describes all the fields together. ;;; This can only work if the argument fields form a contiguous ;;; field. (byte-union (byte 4 3) (byte 2 7)) ==> (byte 6 3) ;;; BYTE-COMPOSITION This is useful if you want to do a byte operation on a datum ;;; which is embedded in a larger datum. The second bytespec ;;; describes the field in the big datum where the little datum ;;; is stored. The first bytespec is the field (as it appears ;;; in the little datum) that you want to manipulate. The result ;;; is a bytespec describing where in the big datum the subfield ;;; that you want to operate on from the little datum is. ;;; (byte-composition (byte 2 4) (byte 10 3)) ==> (byte 2 7) ;;; BYTE-INTERSECTION For the byte specifiers provided as arguments, byte-intersection ;;; produces a single byte specifier which describes a field of those ;;; bits which are in common to all of the argument bytespecs. ;;; (byte-intersection (byte 10 5) (byte 5 10)) ==> (byte 5 5) ;;; BYTE-IN-BYTE Given two byte specifiers which both describe fields in ;;; a datum, this computes a byte specifier which locates the field ;;; described by the first bytespec in the field described by the second. ;;; (byte-in-byte (byte 4 18) (byte 16 16)) ==> (byte 4 2) ;;; union (defun byte-union1 (&rest byte-specs) "Given a set of byte specifiers which describe a contiguous field, return a single byte specifier for the entire field." (setq byte-specs (sort (copy-list Byte-specs) '< :key 'byte-position)) ;;; make sure they are contiguous (do ((specs byte-specs (cdr specs))) ((null (cdr specs)) t) (unless (>= (+ (byte-size (car specs)) (byte-position (car specs))) (byte-position (cadr specs))) (error nil "byte specs are not contiguous (BYTE ~d. ~d.) (BYTE ~d. ~d.)" (byte-size (car specs)) (byte-position (car specs)) (byte-size (cadr specs)) (byte-position (cadr specs))))) ;;; position is position of first one ;;; size is position of last plus size of last minus position of first (let ((last (car (last byte-specs)))) (byte (+ (- (byte-position last) (byte-position (first byte-specs))) (byte-size last)) (byte-position (first byte-specs))))) (defun prims:byte-union (&rest byte-specs) (if (and byte-specs (every byte-specs #'byte-macro-foldable)) (apply #'byte-union1 (mapcar #'eval byte-specs)) (error nil "BYTE-UNION can't cope with its arguments"))) ;;; composition (defun byte-composition1 (subspec of-spec) "Of-spec is a byte specifier describing a field foo of bar. subspec is a byte specifier describing a field baz of foo. Returns a byte-spec describing field baz of bar." ;;; a validity check (unless (<= (+ (byte-position subspec) (byte-size subspec)) (byte-size of-spec)) (error nil "(BYTE ~d. ~d.) does not fit in (BYTE ~d. ~d.)" (byte-size subspec) (byte-position subspec) (byte-size of-spec) (byte-position of-spec))) (byte (byte-size subspec) (+ (byte-position of-spec) (byte-position subspec)))) ;;This macro is not used any more WKF. 5/12/88 ;(defmacro prims:byte-composition (subspec of-spec) ; (if (and (byte-macro-foldable subspec) ; (byte-macro-foldable of-spec)) ; (byte-composition1 (eval subspec) (eval of-spec)) ; `(byte (byte-size ,subspec) ; (+ (byte-position ,of-spec) ; (byte-position ,subspec))))) (defun prims:byte-intersection (&rest bytes) "Make a byte specifier describing those bits which are in all of BYTES" (flet ((2-byte-intersect (byte1 byte2) (let* ((start1 (byte-position byte1)) (start2 (byte-position byte2)) (start (max start1 start2)) (end (min (+ start1 (byte-size byte1)) (+ start2 (byte-size byte2))))) (byte (- end start) start)))) (do* ((byte-spec (car bytes) (2-byte-intersect byte-spec (car byte-specs))) (byte-specs (cdr bytes) (cdr byte-specs))) ((null byte-specs) byte-spec)))) ;;; subtraction??? (defun byte-in-byte1 (byte in-byte &optional (safe nil)) "Given two byte specifiers BYTE and IN-BYTE into a word, return a byte specifier describing the field BYTE as it appears in IN-BYTE." (when (and safe (< (byte-position byte) (byte-position in-byte)) (> (+ (byte-position byte) (byte-size byte)) (+ (byte-position in-byte) (byte-size in-byte)))) (error nil "byte spec (BYTE ~d. ~d.) is not contained within (BYTE ~d. ~d.)" (byte-size byte) (byte-position byte) (byte-size in-byte) (byte-position in-byte))) (let ((bi (byte-intersection byte in-byte))) (byte (byte-size bi) (- (byte-position bi) (byte-position in-byte))))) ;;This macro is not being used any more wkf. 5/12/88 ;(defmacro prims:byte-in-byte (byte in-byte) ; (if (and (byte-macro-foldable byte) ; (byte-macro-foldable in-byte)) ; (byte-in-byte1 (eval byte) (eval in-byte)) ; (error nil "BYTE-IN-BYTE can't cope with its arguments"))) (defun byte-macro-foldable thing (or (constantp thing) (and (listp thing) (eq (first thing) 'prims:byte) (constantp (second thing)) (constantp (third thing)))))