OSDN Git Service

* hardware.scm (hw-pc?): New function.
[pf3gnuchains/pf3gnuchains4x.git] / cgen / iformat.scm
index 1717f38..9fda636 100644 (file)
@@ -1,5 +1,5 @@
 ; Instruction formats.
-; Copyright (C) 2000 Red Hat, Inc.
+; Copyright (C) 2000, 2009 Red Hat, Inc.
 ; This file is part of CGEN.
 ; See file COPYING.CGEN for details.
 
   (number key ifields mask-length length mask eg-insn)
 )
 
-; Traverse the ifield list to collect all base (non-derived) ifields used in it.
-(define (ifields-base-ifields ifld-list)
-  (collect (lambda (ifld)
-            (ifld-base-ifields ifld))
-          ifld-list)
-)
-
 ; Return enum cgen_fmt_type value for FMT.
 ; ??? Not currently used.
 
 ; All bits must be represent exactly once.
 
 (define (compute-insn-length fld-list)
-  (apply + (map ifld-length (collect ifld-base-ifields fld-list)))
+  (apply + (map ifld-length (ifields-base-ifields fld-list)))
 )
 
 ; Given FLD-LIST, compute the base length in bits.
-; Computing the min of state-base-insn-bitsize and the total-length
-; is for [V]LIW instruction sets.
+;
+; For variable length instruction sets, or with cpus with multiple
+; instruction sets, compute the base appropriate for this set of
+; ifields.  Check that ifields are not shared among isas with
+; inconsistent base insn lengths.
+;
+; ??? The algorithm here is a bit odd.  [Though there is value in verifying
+; ifields are from consistent ISAs.]
 
 (define (compute-insn-base-mask-length fld-list)
-  (min (state-base-insn-bitsize) (compute-insn-length fld-list))
+  (let* ((isa-base-bitsizes
+         (remove-duplicates
+          (map isa-base-insn-bitsize
+               (map current-isa-lookup
+                    (collect (lambda (ifld) 
+                               (atlist-attr-value (obj-atlist ifld) 'ISA #f))
+                             fld-list))))))
+    (if (= 1 (length isa-base-bitsizes))
+       (min (car isa-base-bitsizes) (compute-insn-length fld-list))
+       (error "ifields have inconsistent isa/base-insn-size values:" isa-base-bitsizes)))
 )
 
 ; Given FLD-LIST, compute the bitmask of constant values in the base part
     (apply +
           (map (lambda (fld) (ifld-mask fld mask-len mask-bitrange))
                ; Find the fields that have constant values.
-               (find ifld-constant? (collect ifld-base-ifields fld-list)))
-          )
-    )
+               (find ifld-constant? (ifields-base-ifields fld-list)))))
 )
 \f
 ; Return the <iformat> search key for a sorted field list.
 ; INSN is passed so that we can include its sanytize attribute, if present,
 ; so sanytized sources work (needed formats don't disappear).
 
-(define (-ifmt-search-key insn sorted-ifld-list)
+(define (/ifmt-search-key insn sorted-ifld-list)
   (string-map (lambda (ifld)
                (string-append " ("
-                              (or (obj-attr-value insn 'sanitize)
+                              (or (->string (obj-attr-value insn 'sanitize))
                                   "-nosan-")
                               " "
-                              (obj:name ifld)
+                              (obj:str-name ifld)
                               " "
                               (ifld-ilk ifld)
                               ")"))
 ; the generated code smaller (and sometimes faster - more usable common
 ; fragments in pbb simulators).  Don't cause spurious differences.
 
-(define (-sfmt-search-key insn cti? sorted-used-iflds sem-in-ops sem-out-ops)
+(define (/sfmt-search-key insn cti? sorted-used-iflds sem-in-ops sem-out-ops)
   (let ((op-key (lambda (op)
                  (string-append " ("
-                                (or (obj-attr-value insn 'sanitize)
+                                (or (->string (obj-attr-value insn 'sanitize))
                                     "-nosan-")
                                 " "
-                                (obj:name op)
+                                (obj:str-name op)
                                 ; ??? Including memory operands currently
                                 ; isn't necessary and it can account for some
                                 ; spurious differences.  On the other hand
                                 (if (memory? (op:type op))
                                     ""
                                     (string-append " "
-                                                   (obj:name (op:mode op))))
+                                                   (obj:str-name (op:mode op))))
                                 ; CGEN_OPERAND_INSTANCE_COND_REF is stored
                                 ; with the operand in the operand instance
                                 ; table thus formats must be distinguished
      cti?
      (insn-length insn)
      (string-map (lambda (ifld)
-                  (string-append " (" (obj:name ifld) " " (ifld-ilk ifld) ")"))
+                  (string-append " (" (obj:str-name ifld) " " (ifld-ilk ifld) ")"))
                 sorted-used-iflds)
      (string-map op-key
                 sem-in-ops)
 
 ; Sort IFLDS by dependencies and then by starting bit number.
 
-(define (-sfmt-order-iflds iflds)
+(define (/sfmt-order-iflds iflds)
   (let ((up? 
         ; ??? Something like this is preferable.
         ;(not (ifld-lsb0? (car ifld-list)))
 ; The important points are to help distinguish sformat's by the ifields used
 ; and to put ifields that others depend on first.
 
-(define (-sfmt-used-iflds in-ops out-ops)
+(define (/sfmt-used-iflds in-ops out-ops)
   (let ((in-iflds (map op-iflds-used in-ops))
        (out-iflds (map op-iflds-used out-ops)))
     (let ((all-iflds (nub (append (apply append in-iflds)
                                  (apply append out-iflds))
                          obj:name)))
-      (-sfmt-order-iflds all-iflds)))
+      (/sfmt-order-iflds all-iflds)))
 )
 \f
 ; The format descriptor is used to sort formats.
 
 ; Compute an iformat descriptor used to build an <iformat> object for INSN.
 ;
-; If COMPUTE-SFORMAT? is #t compile the semantics and compute the semantic
-; format (same as instruction format except that operands are used to
+; If COMPUTE-SFORMAT? is #t compute the semantic format
+; (same as instruction format except that operands are used to
 ; distinguish insns).
 ; Attributes derivable from the semantics are also computed.
 ; This is all done at the same time to minimize the number of times the
 ; semantic code is traversed.
+; The semantics of INSN must already be canonicalized and stored in
+; canonical-semantics.
 ;
 ; The result is (descriptor compiled-semantics attrs).
-; `descriptor' is #f for insns with an empty field list
-; (this happens for virtual insns).
-; `compiled-semantics' is #f if COMPUTE-SFORMAT? is #f.
+; `descriptor' and `compiled-semantics' are #f for insns with an empty
+; field list.  This happens for virtual insns.
 ; `attrs' is an <attr-list> object of attributes derived from the semantics.
 ;
 ; ??? We never traverse the semantics of virtual insns.
        ; Field list is unspecified.
        (list #f #f atlist-empty)
 
-       ; FIXME: error checking (e.g. missing or overlapping bits)
-       (let* (; A list of the various bits of semantic code.
-              (sems (list (insn-semantics insn)))
+       (let* ((sem (insn-canonical-semantics insn))
               ; Compute list of input and output operands if asked for.
               (sem-ops (if compute-sformat?
                            (semantic-compile #f ; FIXME: context
-                                             insn sems)
+                                             insn sem)
                            (csem-make #f #f #f
-                                      (if (insn-semantics insn)
+                                      (if sem
                                           (semantic-attrs #f ; FIXME: context
-                                                          insn sems)
-                                          atlist-empty))))
-              )
-         (let ((compiled-sems (csem-code sem-ops))
+                                                          insn sem)
+                                          atlist-empty)))))
+
+         (let ((compiled-sem (csem-code sem-ops))
                (in-ops (csem-inputs sem-ops))
                (out-ops (csem-outputs sem-ops))
                (attrs (csem-attrs sem-ops))
                (cti? (or (atlist-cti? (csem-attrs sem-ops))
-                         (insn-cti? insn))))
+                         (insn-cti-attr? insn))))
+
            (list (make <fmt-desc>
                    cti? sorted-ifields in-ops out-ops
                    (if (and in-ops out-ops)
-                       (-sfmt-used-iflds in-ops out-ops)
+                       (/sfmt-used-iflds in-ops out-ops)
                        #f)
                    attrs)
-                 compiled-sems
+                 compiled-sem
                  attrs)))))
 )
 
 ; FMT-DESC is INSN's <fmt-desc> object.
 ; IFMT-LIST is append!'d to and the found iformat is stored in INSN.
 
-(define (-ifmt-lookup-ifmt! insn fmt-desc ifmt-list)
-  (let* ((search-key (-ifmt-search-key insn (-fmt-desc-iflds fmt-desc)))
+(define (/ifmt-lookup-ifmt! insn fmt-desc ifmt-list)
+  (let* ((search-key (/ifmt-search-key insn (-fmt-desc-iflds fmt-desc)))
         (ifmt (find-first (lambda (elm)
                             (equal? (ifmt-key elm) search-key))
                           ifmt-list)))
 ;
 ; We assume INSN's <iformat> has already been recorded.
 
-(define (-ifmt-lookup-sfmt! insn fmt-desc sfmt-list)
-  (let* ((search-key (-sfmt-search-key insn (-fmt-desc-cti? fmt-desc)
+(define (/ifmt-lookup-sfmt! insn fmt-desc sfmt-list)
+  (let* ((search-key (/sfmt-search-key insn (-fmt-desc-cti? fmt-desc)
                                       (-fmt-desc-used-iflds fmt-desc)
                                       (-fmt-desc-in-ops fmt-desc)
                                       (-fmt-desc-out-ops fmt-desc)))
                                 (-fmt-desc-cti? fmt-desc)
                                 (-fmt-desc-in-ops fmt-desc)
                                 (-fmt-desc-out-ops fmt-desc)
-                                (-fmt-desc-used-iflds fmt-desc))))
+                                (ifields-base-ifields (-fmt-desc-used-iflds fmt-desc)))))
          (logit 3 "Creating sformat " (number->string sfmt-index) ".\n")
          (insn-set-sfmt! insn sfmt)
          (append! sfmt-list (list sfmt))
   ; intelligent processing of it later.
 
   (for-each (lambda (insn)
-             (logit 3 "Scanning operands of " (obj:name insn) ": "
+             (logit 2 "Scanning operands of " (obj:name insn) ": "
                     (insn-syntax insn) " ...\n")
              (let ((sem-ops (ifmt-analyze insn compute-sformat?)))
                (insn-set-fmt-desc! insn (car sem-ops))
                (if (and compute-sformat? (cadr sem-ops))
-                   (let ((compiled-sems (cadr sem-ops)))
-                     (insn-set-compiled-semantics! insn (car compiled-sems))))
+                   (let ((compiled-sem (cadr sem-ops)))
+                     (insn-set-compiled-semantics! insn compiled-sem)))
                (obj-set-atlist! insn
                                 (atlist-append (obj-atlist insn)
                                                (caddr sem-ops)))
         )
 
     (for-each (lambda (insn)
-               (logit 3 "Processing format for " (obj:name insn) ": "
+               (logit 2 "Processing format for " (obj:name insn) ": "
                       (insn-syntax insn) " ...\n")
 
                (let ((fmt-desc (insn-fmt-desc insn)))
                      (begin
                        ; Must compute <iformat> before <sformat>, the latter
                        ; needs the former.
-                       (-ifmt-lookup-ifmt! insn fmt-desc ifmt-list)
+                       (/ifmt-lookup-ifmt! insn fmt-desc ifmt-list)
                        (if compute-sformat?
-                           (-ifmt-lookup-sfmt! insn fmt-desc sfmt-list)))
+                           (/ifmt-lookup-sfmt! insn fmt-desc sfmt-list)))
 
                      ; No field list present, use empty format.
                      (begin