;;; -*- Mode:LISP; Package:SIMULATOR; Readtable:CL; Base:10 -*- ;;; This is the stuff which processes the "OPCODE-FIELD-DEFS" file. ;;; Loading "OPCODE-FIELD-DEFS" will modify INSTRUCTION-FIEL-DATABASE ;;; with descriptions for the bit fields of each instruction type. ;;; Once the file is loaded, you can run the function (VERIFY-INSTRUCTION-DATABASE). ;;; This will write out a list of errors as well as a copy of the instruction ;;; byte field database, sorted by instruction type and field bit position into an ;;; editor buffer named "INSTRUCTION-DATABASE". ;;; The errors describe places in the word description for the instruction type ;;; for which a bit is either multiply-defined or undefined. An absence of errors ;;; is a guarantee that all 64 bits are in exactly one bit field. ;;; The types of instuction are ALU, ALU-16-BIT-IMMEDIATE, ALU-24-BIT-IMMEDIATE, LOAD-32-BIT-IMMEDIATE, ;;; FLOATING-POINT-ALU, FLOATING-POINT-MULTIPLIER, CONDITIONAL-BRANCH, CALLZ, JUMP, CALL and CALL-DISPATCH (defconst instruction-types '( COMMON ALU ALU-16-BIT-IMMEDIATE ALU-24-BIT-IMMEDIATE LOAD-32-BIT-IMMEDIATE FLOATING-POINT-ALU FLOATING-POINT-MULTIPLIER CONDITIONAL-BRANCH CALLZ JUMP CALL CALL-DISPATCH )) (defconst instruction-field-database (mapcar 'list instruction-types) "an alist, the CARs of each element are the instruction types and the CDRs are lists of (FIELD-NAME . BYTE-SPEC)") ;;; figure out what this should do later (defmacro def-inst-fields (instruction-types &rest field-descriptors) (do* ((fds field-descriptors (cddr fds)) (field-name (first fds) (first fds)) (field-byte (second fds) (second fds)) (forms nil)) ((null fds) (cons 'progn forms)) (dolist (i instruction-types) (push `(def-inst-field ',i ',field-name ,field-byte) forms) ))) (defun def-inst-field (instruction-type field-name field-byte) (let ((inst-fields (assoc instruction-type instruction-field-database)) ) (push (cons field-name field-byte) (cdr inst-fields)))) (defun verify-database () (mapcar 'verify-instruction-fields instruction-field-database)) (defun verify-instruction-fields (arg) (let* ((instruction-type (first arg)) (field-pairs (rest arg)) (fps (sort (copy-list field-pairs) '< :key #'(lambda (fp) (byte-position (cdr fp)))))) ;;; make sure that there are no overlaps and that the fields are contiguous from bits 0 to 63 (do* ((fpsl fps (cdr fpsl)) (this-name (caar fpsl) (caar fpsl)) (this-byte (cdar fpsl) (cdar fpsl)) ; (next-name (caadr fpsl) (caadr fpsl)) ; (next-byte (cdadr fpsl) (cdadr fpsl)) (current-pos 0) ) ((null fpsl) (unless (= current-pos 64.) (format t "~&; ~a ~d(~:*#o~o) Where's the rest" instruction-type current-pos))) (unless (= current-pos (byte-position this-byte)) (format t "~&; ~a instruction bit ~d(~:*#o~o): ~a (#o~o #o~o)" instruction-type current-pos this-name (byte-size this-byte) (byte-position this-byte))) (incf current-pos (byte-size this-byte))) (cons instruction-type fps))) (defun verify-instruction-database () (let ((*print-base* 8) (*package* (pkg-find-package 'hardware))) (with-open-file (*standard-output* "ed-buffer:instruction-database" :direction :output) (grind-top-level (prog1 (verify-database) (terpri) (terpri)) )))) ;;; now make something useful (defconst instruction-abbreviations '( (common "") (ALU "-alu") (ALU-16-BIT-IMMEDIATE "-alu-16i") (ALU-24-BIT-IMMEDIATE "-alu-24i") (LOAD-32-BIT-IMMEDIATE "-load-32i") (FLOATING-POINT-ALU "-float") (FLOATING-POINT-MULTIPLIER "-fmult") (CONDITIONAL-BRANCH "-branch") (CALLZ "-callz") (JUMP "-jump") (CALL "-call") (CALL-DISPATCH "-call-dispatch"))) (defconst opcode-field-file-name "jb:k.opcodes;opcode-fields.lisp") (defun dump-opcode-fields () (with-open-file (filestream opcode-field-file-name :direction :output) (format filestream ";;; -*- Mode:LISP; Package:HARDWARE; Base:10; Readtable:CL -*-~%") (terpri filestream) (format filestream ";;; Generated by ~a on ~\\date\\" user-id (get-universal-time)) (terpri filestream) (dolist (inst instruction-field-database) (terpri filestream) (let ((inst-type (car inst)) (fields (sort (copy-list (cdr inst)) '< :key #'(lambda (fp) (byte-position (cdr fp)))))) (format filestream ";;; ~a group" inst-type) (dolist (f fields) (format filestream "~&~a~&" (format nil "~&~((defconstant %%INST~a-~a ~64,10T(byte ~2d. ~2d.))~)" (second (assq inst-type instruction-abbreviations)) (car f) (byte-size (cdr f)) (byte-position (cdr f))))))) (terpri filestream)))