; Mode objects.
-; Copyright (C) 2000 Red Hat, Inc.
+; Copyright (C) 2000, 2009, 2010 Red Hat, Inc.
; This file is part of CGEN.
; See file COPYING.CGEN for details.
; size in bytes
bytes
- ; NON-MODE-C-TYPE is the C type to use in situations where
- ; modes aren't available. A somewhat dubious feature, but at
- ; the moment the opcodes tables use it. It is either the C
- ; type as a string (e.g. "int") or #f for non-portable modes
- ; (??? could use other typedefs for #f, e.g. int64 for DI).
- ; Use of GCC can't be assumed though.
- non-mode-c-type
+ ; The C type to use or #f if there is no such C type.
+ ; This is generally the name of the mode.
+ c-type
; PRINTF-TYPE is the %<letter> arg to printf-like functions,
; however we define our own extensions for non-portable modes.
;
; Possible values:
; %x - as always
- ; %D - DI mode
+ ; %D - DI mode (8 bytes)
+ ; %T - TI mode (16 bytes)
+ ; %O - OI mode (32 bytes)
; %f - SF,DF modes
; %F - XF,TF modes
printf-type
; easy to define since the object doesn't exist before it's
; defined.
; ??? May wish to later remove SEM-MODE (e.g. mips signed add
- ; is different than mips unsigned add) however for now it keeps
- ; things simpler (and prevents being wildly dissimilar from
+ ; is different than mips unsigned add). However for now it keeps
+ ; things simpler, and prevents being wildly dissimilar from
; GCC-RTL. And the mips case needn't be handled with different
; adds anyway.
sem-mode
(define mode:class (elm-make-getter <mode> 'class))
(define mode:bits (elm-make-getter <mode> 'bits))
(define mode:bytes (elm-make-getter <mode> 'bytes))
-(define mode:non-mode-c-type (elm-make-getter <mode> 'non-mode-c-type))
+(define mode:c-type (elm-make-getter <mode> 'c-type))
(define mode:printf-type (elm-make-getter <mode> 'printf-type))
(define mode:sem-mode (elm-make-getter <mode> 'sem-mode))
; ptr-to is currently private so there is no accessor.
(define mode:host? (elm-make-getter <mode> 'host?))
-; Return C type to use for values of mode M.
+;; Utility to set the parameters of WI/UWI/AI/IAI modes.
-(define (mode:c-type m)
- (let ((ptr-to (elm-xget m 'ptr-to)))
- (if ptr-to
- (string-append (mode:c-type ptr-to) " *")
- (obj:name m)))
+(define (/mode-set-word-params! dst src)
+ (assert (mode? dst))
+ (assert (mode? src))
+ (object-assign! dst src)
+ *UNSPECIFIED*
)
; CM is short for "concat mode". It is a list of modes of the elements
(define cmode-elm-modes (elm-make-getter <concat-mode> 'elm-modes))
\f
-; List of all modes.
-
-(define mode-list nil)
+;; Table of all modes.
+(define /mode-table nil)
-; Return list of mode objects.
-; Hides the fact that its stored as an alist from caller.
-
-(define (mode-list-values) (map cdr mode-list))
+;; This exists to simplify mode-find.
+(define /mode-class-table nil)
; Return list of real mode objects (no aliases).
(define (mode-list-non-alias-values)
- (map cdr
- (find (lambda (m) (eq? (car m) (obj:name (cdr m))))
- mode-list))
+ (hash-fold (lambda (key value prior)
+ (if (eq? key (obj:name value))
+ (append value prior)
+ prior))
+ '()
+ /mode-table)
)
; Return a boolean indicating if X is a <mode> object.
; Return enum cgen_mode_types value for M.
(define (mode:enum m)
- (gen-c-symbol (string-append "MODE_" (string-upcase (obj:name m))))
+ (gen-c-symbol (string-append "MODE_" (string-upcase (obj:str-name m))))
)
; Return a boolean indicating if MODE1 is equal to MODE2
; Either may be the name of a mode or a <mode> object.
; Aliases are handled by refering to their real name.
+; ??? Might be useful to restrict this to <mode> objects only.
(define (mode:eq? mode1 mode2)
- (let ((mode1-name (mode-real-name mode1))
- (mode2-name (mode-real-name mode2)))
+ (let ((mode1-name (mode-real-name (mode-maybe-lookup mode1)))
+ (mode2-name (mode-real-name (mode-maybe-lookup mode2))))
(eq? mode1-name mode2-name))
)
(define (mode-class-numeric? class) (memq class '(INT UINT FLOAT)))
-; Return a boolean indicating if MODE has an integral mode class.
+; Return a boolean indicating if <mode> MODE has an integral mode class.
; Similarily for signed/unsigned.
(define (mode-integral? mode) (mode-class-integral? (mode:class mode)))
(define (mode-signed? mode) (mode-class-signed? (mode:class mode)))
(define (mode-unsigned? mode) (mode-class-unsigned? (mode:class mode)))
-; Return a boolean indicating if MODE has a floating point mode class.
+; Return a boolean indicating if <mode> MODE has a floating point mode class.
(define (mode-float? mode) (mode-class-float? (mode:class mode)))
-; Return a boolean indicating if MODE has a numeric mode class.
+; Return a boolean indicating if <mode> MODE has a numeric mode class.
(define (mode-numeric? mode) (mode-class-numeric? (mode:class mode)))
+;; Return a boolean indicating if <mode> MODE is VOID.
+
+(define (mode-void? mode)
+ (eq? mode VOID)
+)
+
; Return a boolean indicating if MODE1 is compatible with MODE2.
; MODE[12] are either names or <mode> objects.
; HOW is a symbol indicating how the test is performed:
; strict: modes must have same name
-; samesize: modes must be both float or both integer (int or uint) and have
-; same size
-; sameclass: modes must be both float or both integer (int or uint)
+; samesize: modes must be both float, or both integer (int or uint),
+; or both VOID and have same size
+; sameclass: modes must be both float, or both integer (int or uint),
+; or both VOID
; numeric: modes must be both numeric
(define (mode-compatible? how mode1 mode2)
- (let ((m1 (mode:lookup mode1))
- (m2 (mode:lookup mode2)))
+ (let ((m1 (mode-maybe-lookup mode1))
+ (m2 (mode-maybe-lookup mode2)))
(case how
((strict)
(eq? (obj:name m1) (obj:name m2)))
((mode-float? m1)
(and (mode-float? m2)
(= (mode:bits m1) (mode:bits m2))))
+ ((mode-void? m1)
+ (mode-void? m2))
(else #f)))
((sameclass)
(cond ((mode-integral? m1) (mode-integral? m2))
((mode-float? m1) (mode-float? m2))
+ ((mode-void? m1) (mode-void? m2))
(else #f)))
((numeric)
(and (mode-numeric? m1) (mode-numeric? m2)))
(else (error "bad `how' arg to mode-compatible?" how))))
)
-; Add MODE named NAME to the list of recognized modes.
+; Add MODE named NAME to the table of recognized modes.
; If NAME is already present, replace it with MODE.
; MODE is a mode object.
-; NAME exists to allow aliases of modes [e.g. WI, UWI, AI].
+; NAME exists to allow aliases of modes [e.g. WI, UWI, AI, IAI].
;
; No attempt to preserve any particular order of entries is done here.
; That is up to the caller.
(define (mode:add! name mode)
- (let ((entry (assq name mode-list)))
- (if entry
- (set-cdr! entry mode)
- (set! mode-list (acons name mode mode-list)))
- mode)
+ (hashq-set! /mode-table name mode)
+
+ ;; Add the mode to its mode class.
+ ;; There's no point in building this list in any particular order,
+ ;; if the user adds some they could be of any size.
+ ;; So build the list the simple way (in reverse).
+ ;; The list is sorted in mode-finish!.
+ (let ((class (mode:class mode)))
+ (hashq-set! /mode-class-table class
+ (cons mode (hashq-ref /mode-class-table class))))
+
+ *UNSPECIFIED*
)
\f
; Parse a mode.
; This is the main routine for building a mode object.
; All arguments are in raw (non-evaluated) form.
-(define (-mode-parse errtxt name comment attrs class bits bytes
- non-mode-c-type printf-type sem-mode ptr-to host?)
+(define (/mode-parse context name comment attrs class bits bytes
+ c-type printf-type sem-mode ptr-to host?)
(logit 2 "Processing mode " name " ...\n")
- (let* ((name (parse-name name errtxt))
- (errtxt (string-append errtxt " " name))
- (result (make <mode>
- name
- (parse-comment comment errtxt)
- (atlist-parse attrs "mode" errtxt)
- class bits bytes non-mode-c-type printf-type
- sem-mode ptr-to host?)))
- result)
+
+ ;; Pick out name first to augment the error context.
+ (let* ((name (parse-name context name))
+ (context (context-append-name context name)))
+
+ (make <mode>
+ name
+ (parse-comment context comment)
+ (atlist-parse context attrs "mode")
+ class bits bytes c-type printf-type
+ sem-mode ptr-to host?))
)
; ??? At present there is no define-mode that takes an associative list
; Define a mode object, all arguments specified.
(define (define-full-mode name comment attrs class bits bytes
- non-mode-c-type printf-type sem-mode ptr-to host?)
- (let ((m (-mode-parse "define-full-mode" name comment attrs
+ c-type printf-type sem-mode ptr-to host?)
+ (let ((m (/mode-parse (make-current-context "define-full-mode")
+ name comment attrs
class bits bytes
- non-mode-c-type printf-type sem-mode ptr-to host?)))
+ c-type printf-type sem-mode ptr-to host?)))
; Add it to the list of insn modes.
(mode:add! name m)
m)
; Return the found object or #f.
; If X is already a mode object, return that.
-(define (mode:lookup x)
- (if (mode? x)
- x
- (let ((result (assq x mode-list)))
- (if result
- (cdr result)
- #f)))
+(define (mode:lookup mode-name)
+; (if (mode? x)
+; x
+; (let ((result (assq x mode-list)))
+; (if result
+; (cdr result)
+; #f)))
+ (hashq-ref /mode-table mode-name)
+)
+
+;; Same as mode:lookup except MODE is either the mode name or a <mode> object.
+
+(define (mode-maybe-lookup mode)
+ (if (symbol? mode)
+ (hashq-ref /mode-table mode)
+ mode)
)
; Return a boolean indicating if X is a valid mode name.
(define (mode-name? x)
(and (symbol? x)
- ; FIXME: Time to make `mode-list' a hash table.
- (->bool (assq x mode-list)))
+ (->bool (mode:lookup x)))
)
-; Return the name of the real mode of M.
+; Return the name of the real mode of MODE, a <mode> object.
; This is a no-op unless M is an alias in which case we return the
; real mode of the alias.
-(define (mode-real-name m)
- (obj:name (mode:lookup m))
+(define (mode-real-name mode)
+ (obj:name mode)
)
-; Return the real mode of M.
+; Return the real mode of MODE, a <mode> object.
; This is a no-op unless M is an alias in which case we return the
; real mode of the alias.
-(define (mode-real-mode m)
- (mode:lookup (mode-real-name m))
+(define (mode-real-mode mode)
+ ;; Lookups of aliases return its real mode, so this function is a no-op.
+ ;; But that's an implementation detail, so I'm not ready to delete this
+ ;; function.
+ mode
)
; Return the version of MODE to use in semantic expressions.
+; MODE is a <mode> object.
; This (essentially) converts aliases to their real value and then uses
; mode:sem-mode. The implementation is the opposite but the effect is the
; same.
; disallow unsigned modes from being aliased and set sem-mode for aliased
; modes.
-(define (mode-sem-mode m)
- (let* ((m1 (mode:lookup m))
- (sm (mode:sem-mode m1)))
+(define (mode-sem-mode mode)
+ (let ((sm (mode:sem-mode mode)))
(if sm
sm
- (mode-real-mode m1)))
+ (mode-real-mode mode)))
)
-; Return #t if mode M1-NAME is bigger than mode M2-NAME.
+; Return #t if mode M1 is bigger than mode M2.
+; Both are <mode> objects.
-(define (mode-bigger? m1-name m2-name)
- (> (mode:bits (mode:lookup m1-name))
- (mode:bits (mode:lookup m2-name)))
+(define (mode-bigger? m1 m2)
+ (> (mode:bits m1)
+ (mode:bits m2))
)
; Return a mode in mode class CLASS wide enough to hold BITS.
+; This ignores "host" modes (e.g. INT,UINT).
(define (mode-find bits class)
- (let ((modes (find (lambda (mode) (eq? (mode:class (cdr mode)) class))
- mode-list)))
+ (let* ((class-modes (hashq-ref /mode-class-table class))
+ (modes (find (lambda (mode) (not (mode:host? mode)))
+ (or class-modes nil))))
(if (null? modes)
(error "invalid mode class" class))
(let loop ((modes modes))
(cond ((null? modes) (error "no modes for bits" bits))
- ((<= bits (mode:bits (cdar modes))) (cdar modes))
+ ((<= bits (mode:bits (car modes))) (car modes))
(else (loop (cdr modes))))))
)
; Parse MODE-NAME and return the mode object.
+; CONTEXT is a <context> object for error messages.
; An error is signalled if MODE isn't valid.
-(define (parse-mode-name mode-name errtxt)
+(define (parse-mode-name context mode-name)
(let ((m (mode:lookup mode-name)))
- (if (not m) (parse-error errtxt "not a valid mode" mode-name))
+ (if (not m)
+ (parse-error context "not a valid mode" mode-name))
m)
)
; Make a new INT/UINT mode.
-; These have a variable number of bits (1-32).
+; These have a variable number of bits (1-64).
(define (mode-make-int bits)
(if (or (<= bits 0) (> bits 64))
result)
)
\f
+; WI/UWI/AI/IAI modes
+; These are aliases for other modes, e.g. SI,DI.
+; Final values are defered until all cpu family definitions have been
+; read in so that we know the word size, etc.
+;
+; NOTE: We currently assume WI/AI/IAI all have the same size: cpu:word-bitsize.
+; If we ever add an architecture that needs different modes for WI/AI/IAI,
+; we can add the support then.
+
+; This is defined by the target in define-cpu:word-bitsize.
+(define WI #f)
+(define UWI #f)
+
+; An "address int". This is recorded in addition to a "word int" because it
+; is believed that some target will need it. It also stays consistent with
+; what BFD does. It also allows one to write rtl without having to care
+; what the real mode actually is.
+; ??? These are currently set from define-cpu:word-bitsize but that's just
+; laziness. If an architecture comes along that has different values,
+; add the support then.
+(define AI #f)
+(define IAI #f)
+
+; Kind of word size handling wanted.
+; BIGGEST: pick the largest word size
+; IDENTICAL: all word sizes must be identical
+(define /mode-word-sizes-kind #f)
+
+;; Set to true if mode-set-word-modes! has been called.
+(define /mode-word-sizes-defined? #f)
+
+; Called when a cpu-family is read in to set the word sizes.
+
+(define (mode-set-word-modes! bitsize)
+ (let ((current-word-bitsize (mode:bits WI))
+ (word-mode (mode-find bitsize 'INT))
+ (uword-mode (mode-find bitsize 'UINT))
+ (ignore? #f))
+
+ ; Ensure we found a precise match.
+ (if (!= bitsize (mode:bits word-mode))
+ (error "unable to find precise mode to match cpu word-bitsize" bitsize))
+
+ ; Enforce word size kind.
+ (if /mode-word-sizes-defined?
+ (case /mode-word-sizes-kind
+ ((IDENTICAL)
+ (if (!= current-word-bitsize (mode:bits word-mode))
+ (error "app requires all selected cpu families to have same word size"))
+ (set! ignore? #t))
+ ((BIGGEST)
+ (if (>= current-word-bitsize (mode:bits word-mode))
+ (set! ignore? #t)))
+ ))
+
+ (if (not ignore?)
+ (begin
+ (/mode-set-word-params! WI word-mode)
+ (/mode-set-word-params! UWI uword-mode)
+ (/mode-set-word-params! AI uword-mode)
+ (/mode-set-word-params! IAI uword-mode)
+ ))
+ )
+
+ (set! /mode-word-sizes-defined? #t)
+)
+
+; Called by apps to indicate cpu:word-bitsize always has one value.
+; It is an error to call this if the selected cpu families have
+; different word sizes.
+; Must be called before loading .cpu files.
+
+(define (mode-set-identical-word-bitsizes!)
+ (set! /mode-word-sizes-kind 'IDENTICAL)
+)
+
+; Called by apps to indicate using the biggest cpu:word-bitsize of all
+; selected cpu families.
+; Must be called before loading .cpu files.
+
+(define (mode-set-biggest-word-bitsizes!)
+ (set! /mode-word-sizes-kind 'BIGGEST)
+)
+
+; Ensure word sizes have been defined.
+; This must be called after all cpu families have been defined
+; and before any ifields, hardware, operand or insns have been read.
+; FIXME: sparc.cpu breaks this
+
+(define (mode-ensure-word-sizes-defined)
+ (if (not /mode-word-sizes-defined?)
+ (error "word sizes must be defined"))
+)
+\f
; Initialization.
; Some modes are refered to by the Scheme code.
(define VOID #f)
(define DFLT #f)
-; This is defined by the target. We provide a default def'n.
-(define WI #f)
-(define UWI #f)
-
-; An "address int". This is recorded in addition to a "word int" because it
-; is believed that some target will need it. It also stays consistent with
-; what BFD does.
-; This can also be defined by the target. We provide a default.
-(define AI #f)
-(define IAI #f)
-
; Variable sized portable ints.
(define INT #f)
(define UINT #f)
+;; Sort the modes for each class.
+
+(define (/sort-mode-classes!)
+ (for-each (lambda (class-name)
+ (hashq-set! /mode-class-table class-name
+ (sort (hashq-ref /mode-class-table class-name)
+ (lambda (a b)
+ (< (mode:bits a)
+ (mode:bits b))))))
+ '(RANDOM INT UINT FLOAT))
+
+ *UNSPECIFIED*
+)
+
(define (mode-init!)
- (set! mode-list nil)
+ (set! /mode-word-sizes-kind 'IDENTICAL)
+ (set! /mode-word-sizes-defined? #f)
(reader-add-command! 'define-full-mode
"\
; Elsewhere, functions are defined to perform the operation.
(define-attr '(for mode) '(type boolean) '(name FN-SUPPORT))
+ (set! /mode-class-table (make-hash-table 7))
+ (hashq-set! /mode-class-table 'RANDOM '())
+ (hashq-set! /mode-class-table 'INT '())
+ (hashq-set! /mode-class-table 'UINT '())
+ (hashq-set! /mode-class-table 'FLOAT '())
+
+ (set! /mode-table (make-hash-table 41))
+
(let ((dfm define-full-mode))
; This list must be defined in order of increasing size among each type.
+ ; FIXME: still true?
(dfm 'VOID "void" '() 'RANDOM 0 0 "void" "" #f #f #f) ; VOIDmode
; Special marker to indicate "use the default mode".
- ; ??? Not yet used everywhere it should be.
- (dfm 'DFLT "default mode" '() 'RANDOM 0 0 "" "" #f #f #f)
+ (dfm 'DFLT "default mode" '() 'RANDOM 0 0 #f "" #f #f #f)
+
+ ; Mode used in `symbol' rtxs.
+ (dfm 'SYM "symbol" '() 'RANDOM 0 0 #f "" #f #f #f)
+
+ ; Mode used in `current-insn' rtxs.
+ (dfm 'INSN "insn" '() 'RANDOM 0 0 #f "" #f #f #f)
+
+ ; Mode used in `current-mach' rtxs.
+ (dfm 'MACH "mach" '() 'RANDOM 0 0 #f "" #f #f #f)
; Not UINT on purpose.
- (dfm 'BI "one bit (0,1 not 0,-1)" '() 'INT 1 1 "int" "'x'" #f #f #f)
+ (dfm 'BI "one bit (0,1 not 0,-1)" '() 'INT 1 1 "BI" "'x'" #f #f #f)
+
+ (dfm 'QI "8 bit byte" '() 'INT 8 1 "QI" "'x'" #f #f #f)
+ (dfm 'HI "16 bit int" '() 'INT 16 2 "HI" "'x'" #f #f #f)
+ (dfm 'SI "32 bit int" '() 'INT 32 4 "SI" "'x'" #f #f #f)
+ (dfm 'DI "64 bit int" '(FN-SUPPORT) 'INT 64 8 "DI" "'D'" #f #f #f)
- (dfm 'QI "8 bit byte" '() 'INT 8 1 "int" "'x'" #f #f #f)
- (dfm 'HI "16 bit int" '() 'INT 16 2 "int" "'x'" #f #f #f)
- (dfm 'SI "32 bit int" '() 'INT 32 4 "int" "'x'" #f #f #f)
- (dfm 'DI "64 bit int" '(FN-SUPPORT) 'INT 64 8 "" "'D'" #f #f #f)
+ ; No unsigned versions on purpose for now.
+ (dfm 'TI "128 bit int" '(FN-SUPPORT) 'INT 128 16 "TI" "'T'" #f #f #f)
+ (dfm 'OI "256 bit int" '(FN-SUPPORT) 'INT 256 32 "OI" "'O'" #f #f #f)
(dfm 'UQI "8 bit unsigned byte" '() 'UINT
- 8 1 "unsigned int" "'x'" (mode:lookup 'QI) #f #f)
+ 8 1 "UQI" "'x'" (mode:lookup 'QI) #f #f)
(dfm 'UHI "16 bit unsigned int" '() 'UINT
- 16 2 "unsigned int" "'x'" (mode:lookup 'HI) #f #f)
+ 16 2 "UHI" "'x'" (mode:lookup 'HI) #f #f)
(dfm 'USI "32 bit unsigned int" '() 'UINT
- 32 4 "unsigned int" "'x'" (mode:lookup 'SI) #f #f)
+ 32 4 "USI" "'x'" (mode:lookup 'SI) #f #f)
(dfm 'UDI "64 bit unsigned int" '(FN-SUPPORT) 'UINT
- 64 8 "" "'D'" (mode:lookup 'DI) #f #f)
+ 64 8 "UDI" "'D'" (mode:lookup 'DI) #f #f)
; Floating point values.
(dfm 'SF "32 bit float" '(FN-SUPPORT) 'FLOAT
- 32 4 "" "'f'" #f #f #f)
+ 32 4 "SF" "'f'" #f #f #f)
(dfm 'DF "64 bit float" '(FN-SUPPORT) 'FLOAT
- 64 8 "" "'f'" #f #f #f)
+ 64 8 "DF" "'f'" #f #f #f)
(dfm 'XF "80/96 bit float" '(FN-SUPPORT) 'FLOAT
- 96 12 "" "'F'" #f #f #f)
+ 96 12 "XF" "'F'" #f #f #f)
(dfm 'TF "128 bit float" '(FN-SUPPORT) 'FLOAT
- 128 16 "" "'F'" #f #f #f)
+ 128 16 "TF" "'F'" #f #f #f)
; These are useful modes that represent host values.
; For INT/UINT the sizes indicate maximum portable values.
; and registers).
; FIXME: Can't be used to represent both host and target values.
; Either remove the distinction or add new modes with the distinction.
- (dfm 'INT "portable int" '() 'INT 32 4 "int" "'x'"
+ ; FIXME: IWBN to specify #f for sem-mode, but that means we'd need
+ ; TRUNCINTQI,etc.
+ (dfm 'INT "portable int" '() 'INT 32 4 "INT" "'x'"
(mode:lookup 'SI) #f #t)
- (dfm 'UINT "portable unsigned int" '() 'UINT 32 4 "unsigned int" "'x'"
+ (dfm 'UINT "portable unsigned int" '() 'UINT 32 4 "UINT" "'x'"
(mode:lookup 'SI) #f #t)
; ??? Experimental.
- (dfm 'PTR "host pointer" '() 'RANDOM 0 0 "PTR" "'x'"
+ (dfm 'PTR "host pointer" '() 'RANDOM 0 0 "void*" "'x'"
#f (mode:lookup 'VOID) #t)
)
(set! INT (mode:lookup 'INT))
(set! UINT (mode:lookup 'UINT))
- ; To redefine these, use mode:add! again.
- (set! WI (mode:add! 'WI (mode:lookup 'SI)))
- (set! UWI (mode:add! 'UWI (mode:lookup 'USI)))
- (set! AI (mode:add! 'AI (mode:lookup 'USI)))
- (set! IAI (mode:add! 'IAI (mode:lookup 'USI)))
+ ;; While setting the real values of WI/UWI/AI/IAI is defered to
+ ;; mode-set-word-modes!, create usable entries in the table.
+ ;; The entries must be usable as h/w elements may be defined that use them.
+ (set! WI (object-copy-top (mode:lookup 'SI)))
+ (set! UWI (object-copy-top (mode:lookup 'USI)))
+ (set! AI (object-copy-top (mode:lookup 'USI)))
+ (set! IAI (object-copy-top (mode:lookup 'USI)))
+ (mode:add! 'WI WI)
+ (mode:add! 'UWI UWI)
+ (mode:add! 'AI AI)
+ (mode:add! 'IAI IAI)
+
+ ;; Need to have usable mode classes at this point as define-cpu
+ ;; calls mode-set-word-modes!.
+ (/sort-mode-classes!)
*UNSPECIFIED*
)
(define (mode-finish!)
- ; Keep the fields sorted for mode-find.
- (set! mode-list (reverse mode-list))
-
- (if #f
- ; ???: Something like this would be nice if it was timed appropriately
- ; redefine WI/UWI/AI/IAI for this target
- (case (cpu-word-bitsize (current-cpu))
- ((32) (begin
- (display "Recognized 32-bit cpu.\n")))
- ((64) (begin
- (display "Recognized 64-bit cpu.\n")
- (set! WI (mode:add! 'WI (mode:lookup 'DI)))
- (set! UWI (mode:add! 'UWI (mode:lookup 'UDI)))
- (set! AI (mode:add! 'AI (mode:lookup 'UDI)))
- (set! IAI (mode:add! 'IAI (mode:lookup 'UDI)))))
- (else (error "Unknown word-bitsize for WI/UWI/AI/IAI mode!"))))
+ ;; FIXME: mode:add! should keep the class sorted.
+ ;; It's a cleaner way to handle modes from the .cpu file.
+ (/sort-mode-classes!)
*UNSPECIFIED*
)