Home | History | Annotate | Download | only in cpu
      1 ; CRIS CPU description.  -*- Scheme -*-
      2 ;
      3 ; Copyright 2003, 2004, 2007, 2009 Free Software Foundation, Inc.
      4 ;
      5 ; Contributed by Axis Communications AB.
      6 ;
      7 ; This file is part of the GNU Binutils.
      8 ;
      9 ; This program is free software; you can redistribute it and/or modify
     10 ; it under the terms of the GNU General Public License as published by
     11 ; the Free Software Foundation; either version 3 of the License, or
     12 ; (at your option) any later version.
     13 ;
     14 ; This program is distributed in the hope that it will be useful,
     15 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 ; GNU General Public License for more details.
     18 ;
     19 ; You should have received a copy of the GNU General Public License
     20 ; along with this program; if not, write to the Free Software
     21 ; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     22 ; MA 02110-1301, USA.
     23 
     24 (include "simplify.inc")
     25 
     26 ;;;;;;;;;;;;;;;;;; -pmacro (generic ones)
     27 
     28 (define-pmacro (.car2 l) (.apply (.pmacro (a b) a) l))
     29 (define-pmacro (.cadr2 l) (.apply (.pmacro (a b) b) l))
     30 (define-pmacro (SI-ext x) "How to sign-extend a dword to dword (a nop)" x)
     31 (define-pmacro (HI-ext x) "How to sign-extend a word to dword" (ext SI x))
     32 (define-pmacro (QI-ext x) "How to sign-extend a byte to dword" (ext SI x))
     33 (define-pmacro (SI-zext x) "How to zero-extend a dword to dword (a nop)" x)
     34 (define-pmacro (HI-zext x) "How to zero-extend a word to dword" (zext SI x))
     35 (define-pmacro (QI-zext x) "How to zero-extend a byte to dword" (zext SI x))
     36 (define-pmacro
     37   (define-pmacro-map x)
     38   "On a list ((x0 y0) .. (xN yN)), 0 <= m <= N, (define-pmacro xm ym)"
     39   (.splice
     40    begin
     41    (.unsplice
     42     (.map
     43      (.pmacro (l) (.apply (.pmacro (xm ym) (define-pmacro xm ym)) l)) x)))
     44 )
     45 
     46 ;;;;;;;;;;;;;;;;;; -arch -isa -cpu -model
     47 
     48 (define-arch
     49   (name cris)
     50   (comment "Axis Communications CRIS")
     51   (default-alignment unaligned)
     52   (insn-lsb0? #t)
     53   (machs crisv0 crisv3 crisv8 crisv10 crisv32)
     54   (isas cris)
     55 )
     56 
     57 (define-isa
     58   (name cris)
     59   (base-insn-bitsize 16)
     60   (liw-insns 1)
     61   (parallel-insns 1)
     62 )
     63 
     64 (define-pmacro
     65   (define-cpu-cris x-suffix x-comment)
     66   "Define a CRIS CPU family"
     67   (define-cpu
     68     (name (.sym cris x-suffix f))
     69     (comment x-comment)
     70     (endian little)
     71     ; CGEN-FIXME: Should be deduced from the default?
     72     (word-bitsize 32)
     73     (file-transform (.str x-suffix))
     74   )
     75 )
     76 
     77 ; Useful when there's a need to iterate over all models.
     78 (define-pmacro (cris-cpu-model-numbers)
     79   "List of CRIS CPU model numbers (version register contents)"
     80   (0 3 8 10 32)
     81 )
     82 
     83 (define-pmacro (cris-cpu-models)
     84   "List of CRIS CPU model names"
     85   (.map (.pmacro (n) (.sym v n)) (cris-cpu-model-numbers))
     86 )
     87 
     88 ; Mapping from model name to number.
     89 (define-pmacro-map
     90   (.map (.pmacro (n) ((.sym v n -number) n))
     91 	(cris-cpu-model-numbers)))
     92 
     93 ; FIXME: Rationalize these rules.
     94 ; CPU names must be distinct from the architecture name and machine names.
     95 ; The "b" suffix stands for "base" and is the convention.
     96 ; The "f" suffix stands for "family" and is the convention.
     97 ; We ignore the "b" convention, partly because v0 isn't really a "base", at
     98 ; least not for some aspects of v32.
     99 (define-cpu-cris v0 "CRIS base family")
    100 (define-cpu-cris v3 "CRIS v3 family")
    101 (define-cpu-cris v8 "CRIS v8 family")
    102 (define-cpu-cris v10 "CRIS v10 family")
    103 (define-cpu-cris v32 "CRIS v32 family")
    104 
    105 (define-pmacro MACH-PRE-V32 (MACH crisv0,crisv3,crisv8,crisv10))
    106 (define-pmacro MACH-V3-UP (MACH crisv3,crisv8,crisv10,crisv32))
    107 (define-pmacro MACH-V32 (MACH crisv32))
    108 (define-pmacro MACH-PC MACH-PRE-V32)
    109 (define-pmacro MACH-ACR MACH-V32)
    110 (define-pmacro MACH-BRANCH-OFFSET-AT-INSN MACH-V32)
    111 (define-pmacro MACH-BRANCH-OFFSET-AFTER-INSN MACH-PRE-V32)
    112 
    113 (define-pmacro
    114   current-mach-is-v32
    115   "Whether the generated code is for V32.  See comment at h-v32."
    116   (reg h-v32)
    117 )
    118 
    119 (define-pmacro (define-mach-cris x-suffix x-comment x-name)
    120   "Define a CRIS mach"
    121   (define-mach
    122     (name (.sym cris x-suffix))
    123     ; They're all called "cris" in bfd.  Watch out for breakages for some
    124     ; uses.
    125     (bfd-name x-name)
    126     (comment x-comment)
    127     (cpu (.sym cris x-suffix f)))
    128 )
    129 
    130 (define-mach-cris v0 "Generic CRIS v0 CPU, ETRAX 1 .. 3" "cris")
    131 (define-mach-cris v3 "Generic CRIS v3 CPU, ETRAX 4" "cris")
    132 (define-mach-cris v8 "Generic CRIS v8 CPU, ETRAX 100" "cris")
    133 (define-mach-cris v10 "Generic CRIS v10 CPU, ETRAX 100 LX" "cris")
    134 (define-mach-cris v32 "Generic CRIS v32 CPU, ETRAX FS" "crisv32")
    135 
    136 (define-pmacro (define-model-simplecris x-name x-comment)
    137   "Define a simple CRIS model"
    138   (define-model
    139     (name (.sym cris x-name))
    140     (comment x-comment)
    141     (mach (.sym cris x-name))
    142 
    143     (unit u-exec "Execution Unit" () 1 1 () () () ())
    144     (unit u-mem "Memory Unit" () 1 1 () () () ())
    145 
    146     (unit u-const16 "Fetch 16-bit operand" () 1 1 () () () ())
    147     (unit u-const32 "Fetch 32-bit operand" () 1 1
    148 	  () () () ())
    149     ; Used in special-case insn, for example arithmetic with PC destination.
    150     (unit u-stall "Stall unit" () 1 1 () () () ())
    151     (unit u-skip4 "Skip 4 bytes" () 1 1 () () () ())
    152     (unit u-multiply "Multiply Unit" () 1 1 ((MACH crisv10)) () () ())
    153     (unit u-movem "Movem Unit" () 1 1 ()
    154 	  ((Rd INT -1))
    155 	  () ()))
    156 )
    157 
    158 (define-model-simplecris v0 "Model of CRIS v0, ETRAX 1 .. 3")
    159 (define-model-simplecris v3 "Model of CRIS v3, ETRAX 4")
    160 (define-model-simplecris v8 "Model of CRIS v8, ETRAX 100")
    161 (define-model-simplecris v10 "Model of CRIS v10, ETRAX 100 LX")
    162 
    163 ; For some reason, we get an error:
    164 ;  Generating arch.h ...
    165 ;  ERROR: In procedure vector-ref:
    166 ;  ERROR: Wrong type argument in position 1: ()
    167 ; if we include timings for machs that we don't generate sims for.
    168 ; Last checked: CVS as of 2004-11-18.
    169 ; CGEN-FIXME: Looks like another CGEN bug.  When it's fixed (or when
    170 ; generating sims for v0, v3 or v8), add 0, 3 and 8 to
    171 ; simplecris-timing-models.  But before that, simplecris-timing-x has to
    172 ; be rewritten to work on a multiple-element-list, not assume a single
    173 ; element.  (A change which seems likely to depend on lexical scoping for
    174 ; macros to be introduced: try the obvious implementation.)
    175 (define-pmacro simplecris-timing-models (10))
    176 (define-pmacro (simplecris-common-timing x-units)
    177   "Make timing models, using x-units for all simplecris-timing-models"
    178   ; CGEN-FIXME: Another CGEN bug: the part (.unsplice (10)) will remain
    179   ; unexpanded in (.sym crisv (.unsplice (10)) if we write this as
    180   ; ((.splice (.sym crisv (.unsplice simplecris-timing-models))
    181   ;	      (.unsplice x-units)))
    182   ((.splice (.sym crisv (.apply (.pmacro (x) x) simplecris-timing-models))
    183   	    (.unsplice x-units)))
    184 )
    185 
    186 (define-pmacro-map
    187   (
    188    ; Timing for memory instructions running on a simple cris model.
    189    ((simplecris-mem-timing)	(simplecris-common-timing
    190 				 ((unit u-mem) (unit u-exec))))
    191    ; Timing for movem instructions running on a simple cris model.
    192    ((simplecris-movem-timing)	(simplecris-common-timing
    193 				 ((unit u-movem) (unit u-exec))))
    194    ; Similar, for an 8- or 16-bit constant ([PC+]) operand.
    195    ((simplecris-const-timing-HI)
    196 				(simplecris-common-timing
    197 				 ((unit u-const16) (unit u-exec))))
    198    ; Similar, for a 32-bit constant ([PC+]) operand.
    199    ((simplecris-const-timing-SI)
    200 				(simplecris-common-timing
    201 				 ((unit u-const32) (unit u-exec))))
    202    ; Similar, no particular operand.
    203    ((simplecris-timing)		(simplecris-common-timing
    204 				 ((unit u-exec)))))
    205 )
    206 
    207 (define-model
    208   (name crisv32)
    209   (comment "Model of CRISv32")
    210   (mach crisv32)
    211 
    212   (state
    213     ; Bitmask of h-gr register (0..15) and h-sr register (17..31)
    214     ; modified by 3rd previous insn, updated by the u-exec unit.
    215     ; Because there's no need to mark writes to special registers BZ and
    216     ; WZ, bit 16 is for jump mark and bit 20 for memory-write mark.
    217     (prev-prev-prev-modf-regs UINT)
    218 
    219     ; Ditto for the 2nd previous insn.
    220     (prev-prev-modf-regs UINT)
    221 
    222     ; Ditto for the previous insn.
    223     (prev-modf-regs UINT)
    224 
    225     ; Bit-mask for regs modified by the current insn, propagated to
    226     ; prev-modf-regs.
    227     (modf-regs UINT)
    228 
    229     ; Registers loaded by movem are not forwarded to the execution
    230     ; stage, so we need to insert stall-cycles for ordinary insns
    231     ; accessing such registers.  In addition to the *modf-regs
    232     ; above, these are set to tell *ordinary* insns which registers
    233     ; are inaccessible.
    234 
    235     (prev-prev-prev-movem-dest-regs UINT)
    236 
    237     ; Ditto for the 2nd previous insn.
    238     (prev-prev-movem-dest-regs UINT)
    239 
    240     ; Ditto for the previous insn.
    241     (prev-movem-dest-regs UINT)
    242 
    243     ; Bit-mask for regs modified by the current insn, propagated to
    244     ; prev-movem-dest-regs.
    245     (movem-dest-regs UINT))
    246 
    247   ; It seems this pipeline description isn't used at all; this is just
    248   ; for show.
    249   ; Noteworthy is the placement of the memory stage before the execute stage.
    250   (pipeline all "" () ((fetch) (decode) (memory) (execute) (writeback)))
    251 
    252   ; Units that contribute only a constant pipeline delay are not included.
    253   (unit u-mem "Memory Unit" () 1 1 ()
    254 	((Rs INT -1))
    255 	() ())
    256 
    257   ; Artificial units for read/write-related hazard accounting.
    258   (unit u-mem-r "Memory Unit Read" () 1 1 () () () ())
    259   (unit u-mem-w "Memory Unit Write" () 1 1 () () () ())
    260 
    261   (unit u-movem-rtom "Movem-to-memory Unit" () 1 1 ()
    262 	((Rs INT -1) (Rd INT -1))
    263 	() ())
    264   (unit u-movem-mtor "Movem-to-register Unit" () 1 1 ()
    265 	((Rs INT -1) (Rd INT -1))
    266 	() ())
    267   (unit u-multiply "Multiply Unit" () 1 1 ()
    268 	((Rs INT -1) (Rd INT -1))
    269 	() ())
    270   (unit u-branch "Branch Unit" () 1 1 ()
    271 	()
    272 	() ())
    273   (unit u-jump-r "Jump-to-register Unit" () 1 1 ()
    274 	((Rs INT -1))
    275 	() ())
    276   (unit u-jump-sr "Jump-to-special-register Unit" () 1 1 ()
    277 	((Ps INT -1))
    278 	() ())
    279   (unit u-jump "JAS/BAS Unit, saving PC" () 1 1 ()
    280 	()
    281 	((Pd INT -1)) ())
    282 
    283   ; To keep track of PC; not really functional units.
    284   (unit u-const16 "Fetch 16-bit operand" () 1 1 () () () ())
    285   (unit u-const32 "Fetch 32-bit operand" () 1 1 () () () ())
    286   (unit u-skip4 "Skip 4 bytes" () 1 1 () () () ())
    287 
    288   ; For v32, we need to keep track of inputs (for movem destination
    289   ; cycle penalties) and output (for e.g. memory source and jump
    290   ; source cycle penalties).
    291   (unit u-exec "Execution Unit" () 1 1 ()
    292 	((Rd INT -1) (Rs INT -1))
    293 	((Rd INT -1))
    294 	())
    295 
    296   ; Special case of u-exec for movem: don't treat Rd as an incoming
    297   ; parameter.
    298   (unit u-exec-movem "Execution Unit" () 1 1 ()
    299 	((Rs INT -1))
    300 	((Rd INT -1))
    301 	())
    302 
    303   ; Special case of u-exec when the destination is a special
    304   ; register.
    305   (unit u-exec-to-sr "Execution Unit" () 1 1 ()
    306 	((Rs INT -1))
    307 	((Pd INT -1)) ())
    308 )
    309 
    310 (define-pmacro (crisv32-timing-destreg d)
    311   "Timing for instructions running on a crisv32 model"
    312   ((crisv32
    313     (.splice unit u-exec (.unsplice d))))
    314 )
    315 (define-pmacro (crisv32-timing) (crisv32-timing-destreg ()))
    316 
    317 (define-pmacro (cris-timing-Rd-sfield)
    318   (crisv32-timing-destreg ((out Rd Rd-sfield)))
    319 )
    320 
    321 (define-pmacro (crisv32-timing-c-HI)
    322   ((crisv32 (unit u-const16) (unit u-exec)))
    323 )
    324 
    325 (define-pmacro-map
    326   ((crisv32-timing-c-QI crisv32-timing-c-HI)
    327    ((crisv32-timing-c-SI) ((crisv32 (unit u-const32) (unit u-exec))))
    328    ((crisv32-timing-c-sr-SI) ((crisv32 (unit u-const32) (unit u-exec-to-sr))))
    329    ((crisv32-reg-sr-timing) ((crisv32 (unit u-exec-to-sr))))
    330    ((crisv32-mem-sr-timing)
    331     ((crisv32 (unit u-mem) (unit u-mem-r) (unit u-exec-to-sr))))
    332    ((crisv32-mem-timing) ((crisv32 (unit u-mem) (unit u-mem-r) (unit u-exec))))
    333    ((crisv32-mem-write-timing) ((crisv32 (unit u-mem) (unit u-exec) (unit u-mem-w)))))
    334 )
    335 
    336 (define-pmacro-map
    337   (
    338    ; Timing for instructions using memory operands.
    339    ((cris-mem-timing)		(.splice (.unsplice (simplecris-mem-timing))
    340 					 (.unsplice (crisv32-mem-timing))))
    341   ; Timing for instructions using memory operands.
    342    ((cris-mem-write-timing)	(.splice
    343 				 (.unsplice (simplecris-mem-timing))
    344 				 (.unsplice (crisv32-mem-write-timing))))
    345    ; Timing for moves from general register to special register.
    346    ((cris-reg-sr-timing)	(.splice (.unsplice (simplecris-timing))
    347 					 (.unsplice (crisv32-reg-sr-timing))))
    348    ; Timing for moves from memory to special register.
    349    ((cris-mem-sr-timing)	(.splice (.unsplice (simplecris-mem-timing))
    350 					 (.unsplice (crisv32-mem-sr-timing))))
    351    ; Timing for non-mul, non-memory, non-special-register, 16-bit instructions.
    352    ((cris-timing)		(.splice (.unsplice (simplecris-timing))
    353 					 (.unsplice (crisv32-timing))))
    354    ; Timing for instructions with 8- or 16-bit constant operand ([PC+]).
    355    ((cris-timing-const-HI)	(.splice
    356 				 (.unsplice (simplecris-const-timing-HI))
    357 				 (.unsplice (crisv32-timing-c-HI))))
    358    ; Timing for instructions with a 32-bit constant operand ([PC+]).
    359    ((cris-timing-const-SI)	(.splice
    360 				 (.unsplice (simplecris-const-timing-SI))
    361 				 (.unsplice (crisv32-timing-c-SI))))
    362    ; Like cris-timing-const-SI, but destination special register.
    363    ((cris-timing-const-sr-SI)	(.splice
    364 				 (.unsplice (simplecris-const-timing-SI))
    365 				 (.unsplice (crisv32-timing-c-sr-SI))))
    366    ; Like cris-timing-const-HI, but destination special register.
    367    ((cris-timing-const-sr-HI)	(.splice
    368 				 (.unsplice (simplecris-const-timing-HI))
    369 				 (.unsplice (crisv32-timing-c-sr-SI)))))
    370 )
    371 
    372 (define-pmacro cris-timing-const-QI cris-timing-const-HI)
    373 (define-pmacro cris-timing-const-sr-QI cris-timing-const-sr-HI)
    374 
    375 (define-pmacro (simplecris-common-writable-specregs)
    376   "The common writable special registers in pre-v32 models."
    377   ((HI 5) (SI 9) (SI 10) (SI 11) (SI 12) (SI 13))
    378 )
    379 
    380 (define-pmacro (simplecris-common-readable-specregs)
    381   "The common readable special registers in pre-v32 models."
    382   (.splice (.unsplice (simplecris-common-writable-specregs))
    383 	   (QI 0) (QI 1) (HI 4) (SI 8))
    384 )
    385 
    386 (define-pmacro (cris-implemented-writable-specregs-v0)
    387   "Special writable registers in v0 and their sizes"
    388   (.splice (.unsplice (simplecris-common-writable-specregs)) (HI 6) (HI 7))
    389 )
    390 (define-pmacro
    391   cris-implemented-specregs-const-v0
    392   cris-implemented-writable-specregs-v0
    393 )
    394 (define-pmacro (cris-implemented-readable-specregs-v0)
    395   "Special readable registers in v0 and their sizes"
    396   (.splice (.unsplice (simplecris-common-readable-specregs)) (HI 6) (HI 7))
    397 )
    398 
    399 (define-pmacro (cris-implemented-writable-specregs-v3)
    400   "Special writable registers in v3 and their sizes"
    401   (.splice (.unsplice (cris-implemented-writable-specregs-v0)) (SI 14))
    402 )
    403 (define-pmacro
    404   cris-implemented-specregs-const-v3
    405   cris-implemented-writable-specregs-v3
    406 )
    407 (define-pmacro (cris-implemented-readable-specregs-v3)
    408   "Special readable registers in v3 and their sizes"
    409   (.splice (.unsplice (cris-implemented-readable-specregs-v0)) (SI 14))
    410 )
    411 
    412 (define-pmacro (cris-implemented-writable-specregs-v8)
    413   "Special writable registers in v8 and their sizes"
    414   (.splice (.unsplice (simplecris-common-writable-specregs)) (SI 14))
    415 )
    416 (define-pmacro
    417   cris-implemented-specregs-const-v8
    418   cris-implemented-writable-specregs-v8
    419 )
    420 (define-pmacro (cris-implemented-readable-specregs-v8)
    421   "Special readable registers in v8 and their sizes"
    422   (.splice (.unsplice (simplecris-common-readable-specregs)) (SI 14))
    423 )
    424 
    425 (define-pmacro (cris-implemented-writable-specregs-v10)
    426   "Special writable registers in v10 and their sizes"
    427   (.splice (.unsplice (simplecris-common-writable-specregs))
    428 	   (SI 7) (SI 14) (SI 15))
    429 )
    430 (define-pmacro
    431   cris-implemented-specregs-const-v10
    432   cris-implemented-writable-specregs-v10
    433 )
    434 (define-pmacro (cris-implemented-readable-specregs-v10)
    435   "Special registers in v10 and their sizes"
    436   (.splice (.unsplice (simplecris-common-readable-specregs))
    437 	   (SI 7) (SI 14) (SI 15))
    438 )
    439 
    440 (define-pmacro (cris-implemented-writable-specregs-v32)
    441   "Special writable registers in v32 and their sizes"
    442   ((SI 2) (QI 3)
    443    (SI 5) (SI 6) (SI 7) (SI 9)
    444    (SI 10) (SI 11) (SI 12) (SI 13) (SI 14) (SI 15))
    445 )
    446 (define-pmacro (cris-implemented-readable-specregs-v32)
    447   "Special readable registers in v32 and their sizes"
    448   (.splice (.unsplice (cris-implemented-writable-specregs-v32))
    449 	   (QI 0) (QI 1) (HI 4) (SI 8))
    450 )
    451 
    452 ; For v32, all special register operations on constants (that is,
    453 ; move) take 32-bit operands, not the real size of the register, as in
    454 ; other move operations.
    455 (define-pmacro (cris-implemented-specregs-const-v32)
    456   (.map (.pmacro (x) (SI (.cadr2 x)))
    457 	(cris-implemented-writable-specregs-v32))
    458 )
    459 
    460 (define-pmacro cris-swap-codes
    461   "CRIS Swap codes in numeric order (no zero)"
    462   (   r  b  br  w  wr  wb  wbr
    463    n nr nb nbr nw nwr nwb nwbr)
    464 )
    465 
    466 (define-pmacro cris-flagnames
    467   "CRIS flag field values, dest and src fields concatenated"
    468   (c v z n x i u p) ; ... b m for pre-v32
    469 )
    470 
    471 (define-pmacro-map
    472   ; Bitnumber for each respective flag.
    473   (.map (.pmacro (x num) ((.sym x -bitnumber) num))
    474 	cris-flagnames (.iota 8))
    475 )
    476 
    477 ; I give up.  Here's a perl-script to get the values I want for this macro
    478 ; (not working along list principles, though).  You can run this region.
    479 ; perl -e '$x = "cvznxiup"; for ($i = 0; $i < 256; $i++) { $s = "";
    480 ;  for ($j = 0; $j < 8; $j++) { if ($i & (1 << $j)) {
    481 ; $s .= substr ($x, $j, 1);}}
    482 ; printf ("%s%s", $s eq "" ? "_" : $s, (($i + 1) % 8) == 0 ? "\n   " : " "); }'
    483 (define-pmacro cris-flag-combinations
    484   "Combinations of flags in numeric order"
    485   (_ c v cv z cz vz cvz
    486    n cn vn cvn zn czn vzn cvzn
    487    x cx vx cvx zx czx vzx cvzx
    488    nx cnx vnx cvnx znx cznx vznx cvznx
    489    i ci vi cvi zi czi vzi cvzi
    490    ni cni vni cvni zni czni vzni cvzni
    491    xi cxi vxi cvxi zxi czxi vzxi cvzxi
    492    nxi cnxi vnxi cvnxi znxi cznxi vznxi cvznxi
    493    u cu vu cvu zu czu vzu cvzu
    494    nu cnu vnu cvnu znu cznu vznu cvznu
    495    xu cxu vxu cvxu zxu czxu vzxu cvzxu
    496    nxu cnxu vnxu cvnxu znxu cznxu vznxu cvznxu
    497    iu ciu viu cviu ziu cziu vziu cvziu
    498    niu cniu vniu cvniu zniu czniu vzniu cvzniu
    499    xiu cxiu vxiu cvxiu zxiu czxiu vzxiu cvzxiu
    500    nxiu cnxiu vnxiu cvnxiu znxiu cznxiu vznxiu cvznxiu
    501    p cp vp cvp zp czp vzp cvzp
    502    np cnp vnp cvnp znp cznp vznp cvznp
    503    xp cxp vxp cvxp zxp czxp vzxp cvzxp
    504    nxp cnxp vnxp cvnxp znxp cznxp vznxp cvznxp
    505    ip cip vip cvip zip czip vzip cvzip
    506    nip cnip vnip cvnip znip cznip vznip cvznip
    507    xip cxip vxip cvxip zxip czxip vzxip cvzxip
    508    nxip cnxip vnxip cvnxip znxip cznxip vznxip cvznxip
    509    up cup vup cvup zup czup vzup cvzup
    510    nup cnup vnup cvnup znup cznup vznup cvznup
    511    xup cxup vxup cvxup zxup czxup vzxup cvzxup
    512    nxup cnxup vnxup cvnxup znxup cznxup vznxup cvznxup
    513    iup ciup viup cviup ziup cziup vziup cvziup
    514    niup cniup vniup cvniup zniup czniup vzniup cvzniup
    515    xiup cxiup vxiup cvxiup zxiup czxiup vzxiup cvzxiup
    516    nxiup cnxiup vnxiup cvnxiup znxiup cznxiup vznxiup cvznxiup
    517   )
    518 )
    519 
    520 (define-pmacro cc-condition (not cbit))
    521 (define-pmacro cs-condition cbit)
    522 (define-pmacro ne-condition (not zbit))
    523 (define-pmacro eq-condition zbit)
    524 (define-pmacro vc-condition (not vbit))
    525 (define-pmacro vs-condition vbit)
    526 (define-pmacro pl-condition (not nbit))
    527 (define-pmacro mi-condition nbit)
    528 (define-pmacro ls-condition (or cbit zbit))
    529 (define-pmacro hi-condition (not (or cbit zbit)))
    530 (define-pmacro ge-condition (not (xor vbit nbit)))
    531 (define-pmacro lt-condition (xor vbit nbit))
    532 (define-pmacro gt-condition (not (or (xor vbit nbit) zbit)))
    533 (define-pmacro le-condition (or (xor vbit nbit) zbit))
    534 (define-pmacro a-condition 1)
    535 
    536 ; FIXME: define this properly for v10 and pre-v10.
    537 (define-pmacro wf-condition pbit)
    538 
    539 (define-pmacro (cris-condition condno)
    540   "Return condition state for condition number CONDNO"
    541   (sequence
    542     BI
    543     ((SI tmpcond) (BI condres))
    544     (set tmpcond condno)
    545      (.splice
    546       cond
    547       (.unsplice
    548        (.map
    549 	(.pmacro
    550 	 (condn condc)
    551 	 ((eq tmpcond condn) (set condres (.sym condc -condition))))
    552 	(.iota 16)
    553 	cris-condition-codes)))
    554      condres)
    555 )
    556 
    557 ;;;;;;;;;;;;;;;;;; -keyword
    558 
    559 ; General registers.
    560 (define-pmacro (cris-general-gregs)
    561   (.splice (SP 14) (.unsplice (.map (.pmacro (n) ((.sym R n) n)) (.iota 15))))
    562 )
    563 
    564 ; Can't keep more than one gr-names definition at the same time;
    565 ; generated enum declarations in sim/cris/cris-desc.h will collide.
    566 ; FIXME: (include "different-mach-parts")
    567 
    568 (define-keyword
    569   (name gr-names-pcreg)
    570   (attrs MACH-PC)
    571   (print-name h-gr-real-pc)
    572   ; Put PC first so it is preferred over r15.
    573   (.splice values (PC 15) (.unsplice (cris-general-gregs)))
    574 )
    575 
    576 (define-keyword
    577   (name gr-names-acr)
    578   (attrs MACH-ACR)
    579   ; The print-name directive will control the enum prefix.  With the
    580   ; arguably more appropriate h-gr-v32 or h-gr-acr, we'd get names like
    581   ; H_GR_ACR_R0 instead of H_GR_R0.  Since we have to choose something for
    582   ; unprefixed names, we use the CRISv32 names.  FIXME: All users should
    583   ; change to use H_GR_V32_R0 (etc.), then change this to h-gr-v32.
    584   (print-name h-gr)
    585   ; Put ACR first so it is preferred over r15.
    586   (.splice values (ACR 15) (.unsplice (cris-general-gregs)))
    587 )
    588 
    589 (define-keyword
    590   (name gr-names-v32)
    591   (attrs MACH-V32)
    592   ; In preparation for implementing the FIXME above.
    593   (print-name h-gr-v32)
    594   ; Put ACR first so it is preferred over r15.
    595   (.splice values (ACR 15) (.unsplice (cris-general-gregs)))
    596 )
    597 
    598 ; Special registers with names common to all.
    599 (define-pmacro (cris-general-pregs)
    600   (.splice
    601    (VR 1)
    602    (SRP 11)
    603    (.unsplice (.map (.pmacro (n) ((.sym P n) n)) (.iota 15))))
    604 )
    605 
    606 (define-keyword
    607   (name p-names-v10)
    608   (attrs MACH-PRE-V32)
    609   (print-name h-sr-pre-v32)
    610   (.splice
    611    values
    612    (CCR 5)
    613    (MOF 7)
    614    (IBR 9)
    615    (IRP 10)
    616    (BAR 12)
    617    (DCCR 13)
    618    (BRP 14)
    619    (USP 15)
    620    (.unsplice (cris-general-pregs)))
    621 )
    622 
    623 (define-keyword
    624   (name p-names-v32)
    625   (attrs MACH-V32)
    626   ; See comment for gr-names-acr.
    627   (print-name h-sr)
    628   (.splice
    629    values
    630    (BZ 0)
    631    (PID 2)
    632    (SRS 3)
    633    (WZ 4)
    634    (EXS 5)
    635    (EDA 6)
    636    (MOF 7)
    637    (DZ 8)
    638    (EBP 9)
    639    (ERP 10)
    640    (NRP 12)
    641    (CCS 13)
    642    (USP 14)
    643    (SPC 15)
    644    (.unsplice (cris-general-pregs)))
    645 )
    646 
    647 ; Similarly as for h-gr-v32, in preparation.
    648 (define-keyword
    649   (name p-names-v32-x)
    650   (attrs MACH-V32)
    651   ; See comment for gr-names-acr.
    652   (print-name h-sr-v32)
    653   (.splice
    654    values
    655    (BZ 0)
    656    (PID 2)
    657    (SRS 3)
    658    (WZ 4)
    659    (EXS 5)
    660    (EDA 6)
    661    (MOF 7)
    662    (DZ 8)
    663    (EBP 9)
    664    (ERP 10)
    665    (NRP 12)
    666    (CCS 13)
    667    (USP 14)
    668    (SPC 15)
    669    (.unsplice (cris-general-pregs)))
    670 )
    671 
    672 (define-pmacro p0 (reg h-sr 0))
    673 (define-pmacro vr (reg h-sr 1))
    674 (define-pmacro pid (reg h-sr 2))
    675 (define-pmacro srs (reg h-sr 3))
    676 (define-pmacro p4 (reg h-sr 4))
    677 (define-pmacro ccr (reg h-sr 5))
    678 (define-pmacro mof (reg h-sr 7))
    679 (define-pmacro p8 (reg h-sr 8))
    680 (define-pmacro ibr (reg h-sr 9))
    681 (define-pmacro ebp (reg h-sr 9))
    682 (define-pmacro erp (reg h-sr 10))
    683 (define-pmacro srp (reg h-sr 11))
    684 (define-pmacro ccs (reg h-sr 13))
    685 (define-pmacro dccr (reg h-sr 13))
    686 (define-pmacro usp (reg h-sr 14))
    687 (define-pmacro spc (reg h-sr 15))
    688 
    689 (define-pmacro sp (reg h-gr 14))
    690 (define-pmacro acr (reg h-gr 15))
    691 
    692 (define-pmacro cris-condition-codes
    693   "CRIS condition codes in numeric order"
    694   (cc cs ne eq vc vs pl mi ls hi ge lt gt le a wf)
    695 )
    696 
    697 ; No use having different lists; this is the only CC that
    698 ; differs between v10 and v32, and mostly in the name.
    699 (define-pmacro sb wf)
    700 
    701 
    702 ;;;;;;;;;;;;;;;;;; -hardware
    703 
    704 ;; Various constant generators.
    705 
    706 (define-hardware
    707   (name h-inc)
    708   (comment "autoincrement-bit syntax specifier")
    709   (type immediate (UINT 1))
    710   (values keyword "" (("" 0) ("+" 1)))
    711 )
    712 
    713 (define-hardware
    714   (name h-ccode)
    715   (comment "Condition code specifier")
    716   (type immediate (UINT 4))
    717   (values keyword ""
    718 	  (.map (.pmacro (x y) ((.str x) y))
    719 		cris-condition-codes (.iota 16)))
    720 )
    721 
    722 (define-hardware
    723   (name h-swap)
    724   (comment "Swap option specifier")
    725   (type immediate (UINT 4))
    726   (values
    727    keyword ""
    728    (.splice
    729     (" " 0)
    730     (.unsplice
    731      (.map
    732       (.pmacro (x y) ((.str x) y)) cris-swap-codes (.iota 15 1)))))
    733 )
    734 
    735 (define-hardware
    736   (name h-flagbits)
    737   (comment "Flag bits specifier")
    738   (type immediate (UINT 8))
    739   (values
    740    keyword ""
    741    (.map (.pmacro (x y) ((.str x) y)) cris-flag-combinations (.iota 256)))
    742 )
    743 
    744 ; Apparently, the semantic-name isn't used for accessors, so external
    745 ; users like the sim glue and SID sees the -v32 and -pre-v32 munged names.
    746 ; Defining "dispatchers"; virtual registers whose getter and setter works
    747 ; on the "real" mach variants, seems to help.  CGEN-FIXME: Make
    748 ; semantic-name set the generated names.
    749 (define-pmacro (cris-d-hwreg x-name x-type)
    750   (define-hardware
    751     (name x-name)
    752     (comment (.str "Dispatcher for " x-name))
    753     (attrs VIRTUAL)
    754     (type register x-type)
    755     (get () (reg (.sym x-name -x)))
    756     (set (val) (set (reg (.sym x-name -x)) val)))
    757 )
    758 (define-pmacro (cris-d-hwregf-a x-name x-type x-n x-attrs)
    759   (define-hardware
    760     (name x-name)
    761     (comment (.str "Dispatcher for " x-name))
    762     (.splice attrs VIRTUAL (.unsplice x-attrs))
    763     (type register x-type (x-n))
    764     (get (index) (reg (.sym x-name -x) index))
    765     (set (index val) (set-quiet (reg (.sym x-name -x) index) val)))
    766 )
    767 (define-pmacro (cris-d-hwregf x-name x-type x-n)
    768   (cris-d-hwregf-a x-name x-type x-n ())
    769 )
    770 (define-pmacro (cris-d-hwregf-p x-name x-type x-n)
    771   (cris-d-hwregf-a x-name x-type x-n (PROFILE))
    772 )
    773 
    774 ; At first glance we could use (eq-attr (current-mach) ...) for
    775 ; everything, but that seems sometimes (always?) to yield false.  For
    776 ; ifields, it causes noncompilable C-code.  For the insn semantics code,
    777 ; it causes tests movei.ms and mulv32.ms to fail, apparently because the
    778 ; current-mach-is-v32 usage in flags setting is miscompiled as 0 (or
    779 ; rather, misgenerated).  Instead we use different definitions of a
    780 ; MACH-tagged virtual register yielding a constant, together with a
    781 ; pmacro.  CGEN-FIXME: If eq-attr is someday fixed, we could just remove
    782 ; these h-v32 virtual register definitions and change the pmacro
    783 ; definition for current-mach-is-v32.
    784 (define-hardware
    785   (semantic-name h-v32)
    786   (name h-v32-v32)
    787   (attrs MACH-V32 VIRTUAL)
    788   (type register BI)
    789   (get () (const BI 1))
    790   (set (val) (error "Can't set h-v32"))
    791 )
    792 (define-hardware
    793   (semantic-name h-v32)
    794   (name h-v32-non-v32)
    795   (attrs MACH-PRE-V32 VIRTUAL)
    796   (type register BI)
    797   (get () (const BI 0))
    798   (set (val) (error "Can't set h-v32"))
    799 )
    800 
    801 ;; "Real" hardware.
    802 
    803 (define-hardware
    804   (name h-pc)
    805   (comment "program counter")
    806   (attrs PC PROFILE)
    807   (type pc)
    808   ; There's no bit 0 in PC, so just ignore it when jumping etc.
    809   (set (val) (set (raw-reg h-pc) (and val (inv 1))))
    810 )
    811 
    812 ; Note that setting register 15 isn't handled here, but in each insn, so
    813 ; the proper "jump" attributes and other special stuff for speedy
    814 ; execution can be present.
    815 (cris-d-hwregf-p h-gr SI 16)
    816 (define-hardware
    817   (semantic-name h-gr-x)
    818   (name h-gr-pc)
    819   (attrs MACH-PC VIRTUAL)
    820   (comment "General purpose registers, aborting on PC access")
    821   (type register SI (16))
    822   (indices extern-keyword gr-names-pcreg)
    823   (get
    824    (index)
    825    (if SI (eq index 15)
    826        (error SI "General register read of PC is not implemented.")
    827        (reg SI h-gr-real-pc index)))
    828   (set
    829    (index val)
    830    (sequence
    831      ()
    832      (if (eq index 15)
    833 	 (error "General register write to PC is not implemented."))
    834      (set (reg SI h-gr-real-pc index) val)))
    835 )
    836 (define-hardware
    837   (name h-gr-real-pc)
    838   (attrs MACH-PC)
    839   (comment "General purpose registers")
    840   (type register SI (16))
    841   (indices extern-keyword gr-names-pcreg)
    842 )
    843 
    844 ; We have to use a virtual register trick to get the "raw", unaccounted
    845 ; contents of the global register; the raw-reg RTX only works for
    846 ; non-virtual register files.
    847 (define-hardware
    848   (semantic-name h-raw-gr)
    849   (name h-raw-gr-pc)
    850   (attrs MACH-PC VIRTUAL)
    851   (comment "Unaccounted version of general purpose registers")
    852   (type register SI (16))
    853   (get (index) (raw-reg h-gr-real-pc index))
    854   (set (index val) (set-quiet (raw-reg h-gr-real-pc index) val))
    855 )
    856 (define-hardware
    857   (semantic-name h-gr-x)
    858   (name h-gr-acr)
    859   (attrs MACH-ACR)
    860   (comment "General purpose registers")
    861   (type register SI (16))
    862   (indices extern-keyword gr-names-acr)
    863 )
    864 (define-hardware
    865   (semantic-name h-raw-gr)
    866   (name h-raw-gr-acr)
    867   (attrs MACH-ACR VIRTUAL)
    868   (comment "Unaccounted version of general purpose registers")
    869   (type register SI (16))
    870   (get (index) (raw-reg h-gr-x index))
    871   (set (index val) (set-quiet (raw-reg h-gr-x index) val))
    872 )
    873 
    874 ; FIXME: get and set semantics?  Unknown how to split semantics best; with
    875 ; get/set semantics or within the insn specification.  Doing the former for
    876 ; now.  Should use different names for pre-v10.
    877 ; FIXME: No dccr for v0 and v3.  Different high flag bits.
    878 (cris-d-hwregf-p h-sr SI 16)
    879 (define-pmacro
    880   (cris-h-sr machver)
    881   (define-hardware
    882     (semantic-name h-sr-x)
    883     (name (.sym h-sr-v machver))
    884     (attrs (MACH (.sym crisv machver)))
    885     (comment (.str "Special registers for v" machver))
    886     (type register SI (16))
    887     (indices extern-keyword p-names-v10)
    888     (get
    889      (index)
    890      (cond
    891       SI
    892       ((orif (orif (eq index (regno p0)) (eq index (regno p4)))
    893 	     (eq index (regno p8))) 0)
    894       ((eq index (regno vr)) machver)
    895       ((orif (eq index (regno ccr))
    896 	     (eq index (regno dccr)))
    897        ; Return "P U I X N Z V C" for the low 8 bits.
    898        ; FIXME: More bits.
    899        (or SI
    900 	   (and SI (raw-reg SI h-sr-x (regno ccr)) #xffffff00)
    901 	   (or
    902 	    (zext SI (reg BI h-cbit))
    903 	    (or
    904 	     (sll (zext SI (reg BI h-vbit)) 1)
    905 	     (or
    906 	      (sll (zext SI (reg BI h-zbit)) 2)
    907 	      (or
    908 	       (sll (zext SI (reg BI h-nbit)) 3)
    909 	       (or
    910 		(sll (zext SI (reg BI h-xbit)) 4)
    911 		(or
    912 		 (sll (zext SI (reg BI h-ibit)) 5)
    913 		 (or
    914 		  (sll (zext SI (reg BI h-ubit)) 6)
    915 		  (or
    916 		   (sll (zext SI (reg BI h-pbit)) 7)
    917 		   0))))))))))
    918       (else (raw-reg SI h-sr-x index))))
    919     (set
    920      (index val)
    921      (cond
    922       ((orif (orif (eq index (regno p0)) (eq index (regno p4)))
    923 	     (orif (eq index (regno p8)) (eq index (regno vr))))
    924        (nop))
    925       ((orif (eq index (regno ccr)) (eq index (regno dccr)))
    926        (sequence
    927 	 ()
    928 	 (set (reg BI h-cbit) (if BI (ne SI (and val (sll 1 0)) 0) 1 0))
    929 	 (set (reg BI h-vbit) (if BI (ne SI (and val (sll 1 1)) 0) 1 0))
    930 	 (set (reg BI h-zbit) (if BI (ne SI (and val (sll 1 2)) 0) 1 0))
    931 	 (set (reg BI h-nbit) (if BI (ne SI (and val (sll 1 3)) 0) 1 0))
    932 	 (set (reg BI h-xbit) (if BI (ne SI (and val (sll 1 4)) 0) 1 0))
    933 	 (set (reg BI h-ibit) (if BI (ne SI (and val (sll 1 5)) 0) 1 0))
    934 	 (set (reg BI h-ubit) (if BI (ne SI (and val (sll 1 6)) 0) 1 0))
    935 	 (set (reg BI h-pbit) (if BI (ne SI (and val (sll 1 7)) 0) 1 0))
    936 	 (set-quiet (raw-reg SI h-sr-x (regno ccr)) val)
    937 	 (set-quiet (raw-reg SI h-sr-x (regno dccr)) val)))
    938       (else (set-quiet (raw-reg SI h-sr-x index) val)))))
    939 )
    940 
    941 (cris-h-sr 0)
    942 (cris-h-sr 3)
    943 (cris-h-sr 8)
    944 (cris-h-sr 10)
    945 
    946 (define-hardware
    947   (semantic-name h-sr-x)
    948   (name h-sr-v32)
    949   (attrs MACH-V32)
    950   (comment "Special registers for v32")
    951   (type register SI (16))
    952   (indices extern-keyword p-names-v32)
    953 
    954   (get
    955    (index)
    956    (cond
    957     SI
    958     ((orif (orif (eq index (regno p0)) (eq index (regno p4)))
    959 	   (eq index (regno p8))) 0)
    960     ((eq index (regno vr)) 32)
    961     ((eq index (regno ccs))
    962      ; Return "S R P U I X N Z V C" for the low 10 bits.
    963      (or SI
    964 	 (and SI (raw-reg SI h-sr-x (regno ccs)) #x3ffffc00)
    965 	 (or
    966 	  (zext SI (reg BI h-cbit))
    967 	  (or
    968 	   (sll (zext SI (reg BI h-vbit)) 1)
    969 	   (or
    970 	    (sll (zext SI (reg BI h-zbit)) 2)
    971 	    (or
    972 	     (sll (zext SI (reg BI h-nbit)) 3)
    973 	     (or
    974 	      (sll (zext SI (reg BI h-xbit)) 4)
    975 	      (or
    976 	       (sll (zext SI (reg BI h-ibit)) 5)
    977 	       (or
    978 		(sll (zext SI (reg BI h-ubit)) 6)
    979 		(or
    980 		 (sll (zext SI (reg BI h-pbit)) 7)
    981 		 (or
    982 		  (sll (zext SI (reg BI h-rbit)) 8)
    983 		  (or
    984 		   (sll (zext SI (reg BI h-sbit)) 9)
    985 		   (or
    986 		    (sll (zext SI (reg BI h-mbit)) 30)
    987 		    (or
    988 		     (sll (zext SI (reg BI h-qbit)) 31)
    989 		     0))))))))))))))
    990     ((eq index (regno usp))
    991      ; In user mode, return general stack pointer.
    992      (if BI (reg BI h-ubit)
    993 	 (raw-reg SI h-gr-x (regno sp))
    994 	 (raw-reg SI h-sr-x (regno usp))))
    995     (else (raw-reg SI h-sr-x index))))
    996 
    997   (set
    998    (index val)
    999    (cond
   1000     ((orif (orif (eq index (regno p0)) (eq index (regno p4)))
   1001 	   (orif (eq index (regno p8)) (eq index (regno vr))))
   1002      (nop))
   1003     ((eq index (regno ccs))
   1004      (sequence
   1005        ()
   1006        ; Protected bits are handled as such in the respective setter function.
   1007        (set (reg BI h-cbit) (if BI (ne SI (and val (sll 1 0)) 0) 1 0))
   1008        (set (reg BI h-vbit) (if BI (ne SI (and val (sll 1 1)) 0) 1 0))
   1009        (set (reg BI h-zbit) (if BI (ne SI (and val (sll 1 2)) 0) 1 0))
   1010        (set (reg BI h-nbit) (if BI (ne SI (and val (sll 1 3)) 0) 1 0))
   1011        (set (reg BI h-xbit) (if BI (ne SI (and val (sll 1 4)) 0) 1 0))
   1012        (set (reg BI h-ibit) (if BI (ne SI (and val (sll 1 5)) 0) 1 0))
   1013        (set (reg BI h-sbit) (if BI (ne SI (and val (sll 1 9)) 0) 1 0))
   1014        (set (reg BI h-mbit) (if BI (ne SI (and val (sll 1 30)) 0) 1 0))
   1015        (set (reg BI h-pbit) (if BI (ne SI (and val (sll 1 7)) 0) 1 0))
   1016        (set (reg BI h-rbit) (if BI (ne SI (and val (sll 1 8)) 0) 1 0))
   1017        (set (reg BI h-qbit) (if BI (ne SI (and val (sll 1 31)) 0) 1 0))
   1018        ; Set the U bit last, so the setter functions for the other bits
   1019        ; don't see it as set from this operation.  It is not cleared from
   1020        ; this operation, so we don't have to handle that; it's only
   1021        ; cleared "manually" from within simulator-specific context-switch
   1022        ; machinery.
   1023        (set (reg BI h-ubit) (if BI (ne SI (and val (sll 1 6)) 0) 1 0))
   1024        (set-quiet (raw-reg SI h-sr-x index) val)))
   1025     ((eq index (regno usp))
   1026      ; In user mode, set general register 14 too, whenever setting USP.
   1027      (sequence
   1028        ()
   1029        (if (reg BI h-ubit) (set (raw-reg SI h-gr-x (regno sp)) val))
   1030        (set (raw-reg SI h-sr-x (regno usp)) val)))
   1031     ((eq index (regno srs))
   1032      (if (not (reg BI h-ubit)) (set (raw-reg h-sr-x (regno srs)) val)))
   1033     ((eq index (regno ebp))
   1034      (if (not (reg BI h-ubit)) (set (raw-reg h-sr-x (regno ebp)) val)))
   1035     ((eq index (regno pid))
   1036      (if (not (reg BI h-ubit))
   1037 	 (sequence
   1038 	   ()
   1039 	   (c-call VOID "@cpu@_write_pid_handler" val)
   1040 	   (set (raw-reg h-sr-x (regno pid)) val))))
   1041     ((eq index (regno spc))
   1042      (if (not (reg BI h-ubit)) (set (raw-reg h-sr-x (regno spc)) val)))
   1043     (else (set-quiet (raw-reg SI h-sr-x index) val))))
   1044 )
   1045 
   1046 (define-hardware
   1047   (name h-supr)
   1048   (attrs MACH-V32 VIRTUAL)
   1049   (comment "Support registers")
   1050   (type register SI (16))
   1051   (values keyword "" (.map (.pmacro (y) ((.str S y) y)) (.iota 16)))
   1052   (get (index) (c-call SI "@cpu@_read_supr" index))
   1053   (set (index val) (c-call VOID "@cpu@_write_supr" index val))
   1054 )
   1055 
   1056 (define-pmacro (cris-dsh semantic-name name comment attrs type)
   1057   "Like dsh, but the semantic-name is separate"
   1058   (define-full-hardware
   1059     name comment attrs semantic-name type () () () () () ())
   1060 )
   1061 
   1062 ; We define the condition codes that hold arithmetic flags separately
   1063 ; and "or" them in, in the get and set methods of the special
   1064 ; registers.  We define arithmetic flags as any of C V Z N X.  They
   1065 ; thankfully have that order (zero-based) in all processor versions.
   1066 
   1067 ; To avoid having two variants of most move-type instructions because V32
   1068 ; doesn't set C and V (and N and Z), we fake the setting to virtual
   1069 ; registers which have two different implementations.
   1070 (define-pmacro (cris-move-flag f f-name f-whence)
   1071   "Flag set differently in pre-v32 and v32 in some cases"
   1072   (begin
   1073     (dsh (.sym h- f bit) (.str f-name " bit") () (register BI))
   1074     (cris-d-hwreg (.sym h- f bit-move) BI)
   1075     (define-hardware
   1076       (semantic-name (.sym h- f bit-move-x))
   1077       (name (.sym h- f bit-move-v32))
   1078       (comment (.str f-name " bit set in " f-whence " instructions, ignored"))
   1079       (attrs MACH-V32 VIRTUAL)
   1080       (type register BI)
   1081       (get
   1082        ()
   1083        (sequence BI ()
   1084 		 (error (.str "Can't get h-" f "bit-move on CRISv32")) 0))
   1085       (set (val) (nop)))
   1086     (define-hardware
   1087       (semantic-name (.sym h- f bit-move-x))
   1088       (name (.sym h- f bit-move-pre-v32))
   1089       (comment
   1090        (.str
   1091 	f-name " bit set in " f-whence " instructions, same as " f "bit"))
   1092       (attrs MACH-PRE-V32 VIRTUAL)
   1093       (type register BI)
   1094       (get () (reg (.sym h- f bit)))
   1095       (set (val) (set (reg (.sym h- f bit)) val))))
   1096 )
   1097 
   1098 (cris-move-flag c "carry" "move-type")
   1099 (cris-move-flag v "overflow" "move-type")
   1100 (cris-move-flag z "zero" "moveq")
   1101 (cris-move-flag n "sign" "moveq")
   1102 
   1103 (dsh h-xbit "extended-arithmetic bit" () (register BI))
   1104 (cris-d-hwreg h-ibit BI)
   1105 (cris-dsh h-ibit-x h-ibit-pre-v32
   1106 	  "interrupt-enable bit" (MACH-PRE-V32) (register BI))
   1107 (dsh h-pbit "sequence-broken bit" ((MACH crisv10,crisv32)) (register BI))
   1108 (dsh h-rbit "carry bit for MCP+restore-p bit" (MACH-V32) (register BI))
   1109 (cris-d-hwreg h-ubit BI)
   1110 (cris-dsh h-ubit-x h-ubit-pre-v32
   1111 	  "user mode bit" ((MACH crisv10)) (register BI))
   1112 (dsh h-gbit "guru mode bit" (MACH-V32) (register BI))
   1113 
   1114 ; When doing a transition from kernel to user mode on V32, we save the
   1115 ; stack pointer in an internal register and copy USP to R14, so we don't
   1116 ; need non-trivial handlers for general registers.
   1117 (dsh
   1118  h-kernel-sp
   1119  "Kernel stack pointer during user mode"
   1120  (MACH-V32)
   1121  (register SI)
   1122 )
   1123 
   1124 (define-hardware
   1125   (semantic-name h-ubit-x)
   1126   (name h-ubit-v32)
   1127   (comment "User mode bit")
   1128   (attrs MACH-V32)
   1129   (type register BI)
   1130   (set
   1131    (val)
   1132    (sequence
   1133      ()
   1134      (if (andif val (not (raw-reg BI h-ubit-x)))
   1135 	 (sequence
   1136 	   ()
   1137 	   (set (reg SI h-kernel-sp) (raw-reg h-gr-x (regno sp)))
   1138 	   (set (raw-reg h-gr-x (regno sp)) (raw-reg h-sr-x (regno usp)))
   1139 	   (set (raw-reg BI h-ubit-x) val)
   1140 	   (c-call VOID "@cpu@_usermode_enabled")))))
   1141 )
   1142 
   1143 (define-hardware
   1144   (semantic-name h-ibit-x)
   1145   (name h-ibit-v32)
   1146   (comment "Interrupt-enable bit")
   1147   (attrs MACH-V32)
   1148   (type register BI)
   1149   (set
   1150    (val)
   1151    (sequence
   1152      ()
   1153      (if (not (reg BI h-ubit))
   1154 	 (sequence
   1155 	   ((BI enabled))
   1156 	   (set enabled (andif val (not (raw-reg BI h-ibit-x))))
   1157 	   (set (raw-reg BI h-ibit-x) val)
   1158 	   ; Call handler when enabling.
   1159 	   (if enabled (c-call VOID "@cpu@_interrupts_enabled"))))))
   1160 )
   1161 
   1162 (define-hardware
   1163   (name h-mbit)
   1164   (comment "NMI enable bit")
   1165   (attrs MACH-V32)
   1166   (type register BI)
   1167   (set
   1168    (val)
   1169    (sequence
   1170      ()
   1171      ; Don't allow clearing (through this handler) when once set.
   1172      (if (andif val (andif (not (raw-reg BI h-mbit)) (not (reg BI h-ubit))))
   1173 	 (sequence
   1174 	   ()
   1175 	   (set (raw-reg BI h-mbit) 1)
   1176 	   ; Call handler when enabling.
   1177 	   (c-call VOID "@cpu@_nmi_enabled")))))
   1178 )
   1179 
   1180 (define-pmacro
   1181   (dsh-cond-bit-v32 x-name x-comment x-cond)
   1182   "dsh bit for MACH-V32, with bit only changeable when X-COND"
   1183   (define-hardware
   1184     (name x-name)
   1185     (comment x-comment)
   1186     (attrs MACH-V32)
   1187     (type register BI)
   1188     (set (val) (sequence () (if x-cond (set (raw-reg BI x-name) val)))))
   1189 )
   1190 (define-pmacro
   1191   (dsh-protected-bit-v32 x-name x-comment)
   1192   "dsh bit for MACH-V32, with bit only changeable in kernel mode"
   1193   (dsh-cond-bit-v32 x-name x-comment (not (reg BI h-ubit)))
   1194 )
   1195 (dsh-protected-bit-v32 h-qbit "Pending single-step bit")
   1196 
   1197 (define-hardware
   1198   (name h-sbit)
   1199   (comment "Cause single step exception on ... [see CRISv32 ref] bit")
   1200   (attrs MACH-V32)
   1201   (type register BI)
   1202   (set
   1203    (val)
   1204    (sequence
   1205      ()
   1206      (if (not (reg BI h-ubit))
   1207 	 (sequence
   1208 	   ((BI enabled))
   1209 	   (set enabled (andif val (not (raw-reg BI h-sbit))))
   1210 	   (set (raw-reg BI h-sbit) val)
   1211 	   ; Call handler when enabling.
   1212 	   (if enabled (c-call VOID "@cpu@_single_step_enabled"))))))
   1213 )
   1214 
   1215 (dnop cbit "" (SEM-ONLY) h-cbit f-nil)
   1216 (dnop cbit-move
   1217       "cbit for pre-V32, nothing for newer" (SEM-ONLY) h-cbit-move f-nil)
   1218 (dnop vbit "" (SEM-ONLY) h-vbit f-nil)
   1219 (dnop vbit-move
   1220       "vbit for pre-V32, nothing for newer" (SEM-ONLY) h-vbit-move f-nil)
   1221 (dnop zbit "" (SEM-ONLY) h-zbit f-nil)
   1222 (dnop zbit-move
   1223       "zbit for pre-V32, nothing for newer" (SEM-ONLY) h-zbit-move f-nil)
   1224 (dnop nbit "" (SEM-ONLY) h-nbit f-nil)
   1225 (dnop nbit-move
   1226       "nbit for pre-V32, nothing for newer" (SEM-ONLY) h-nbit-move f-nil)
   1227 (dnop xbit "" (SEM-ONLY) h-xbit f-nil)
   1228 (dnop ibit "" (SEM-ONLY) h-ibit f-nil)
   1229 (dnop ubit "" (SEM-ONLY (MACH crisv10,crisv32)) h-ubit f-nil)
   1230 (dnop pbit "" (SEM-ONLY (MACH crisv10,crisv32)) h-pbit f-nil)
   1231 (dnop
   1232  rbit "carry bit for MCP+restore-P flag bit" (SEM-ONLY MACH-V32) h-rbit f-nil)
   1233 (dnop sbit "" (SEM-ONLY MACH-V32) h-sbit f-nil)
   1234 (dnop mbit "" (SEM-ONLY MACH-V32) h-mbit f-nil)
   1235 (dnop qbit "" (SEM-ONLY MACH-V32) h-qbit f-nil)
   1236 
   1237 (cris-d-hwreg h-insn-prefixed-p BI)
   1238 (cris-dsh
   1239  h-insn-prefixed-p-x
   1240  h-insn-prefixed-p-pre-v32
   1241  "instruction-is-prefixed bit"
   1242  (MACH-PRE-V32)
   1243  (register BI)
   1244 )
   1245 
   1246 ; CRISv32 has no prefixing on memory accesses.  CGEN-FIXME: [Once (eq-attr
   1247 ; (current-mach) ...) works]: can we change andif and/or orif so it
   1248 ; doesn't look too close at short-circuited operands and avoid defining an
   1249 ; operand that doesn't apply to a certain mach?
   1250 (define-hardware
   1251  (semantic-name h-insn-prefixed-p-x)
   1252  (name h-insn-prefixed-p-v32)
   1253  (attrs MACH-V32 VIRTUAL)
   1254  (comment "instruction-is-prefixed bit")
   1255  (type register BI)
   1256  (get () (const BI 0))
   1257  (set (val) (nop))
   1258 )
   1259 (dnop
   1260  prefix-set
   1261  "Instruction-prefixed flag"
   1262  (SEM-ONLY)
   1263  h-insn-prefixed-p
   1264  f-nil
   1265 )
   1266 
   1267 (cris-dsh
   1268  h-prefixreg h-prefixreg-pre-v32
   1269  "Prefix-address register" (MACH-PRE-V32) (register SI))
   1270 (define-hardware
   1271   (semantic-name h-prefixreg)
   1272   (name h-prefixreg-v32)
   1273   (comment "Prefix-address register, redirecting to ACR")
   1274   (attrs MACH-V32 VIRTUAL)
   1275   (type register SI)
   1276   ; Why can't we have just a "acr" a.k.a "(reg h-gr 15)" here?
   1277   (get () acr)
   1278   (set (value) (set acr value))
   1279 )
   1280 
   1281 (dnop
   1282  prefixreg
   1283  "Prefix address"
   1284  (SEM-ONLY)
   1285  h-prefixreg
   1286  f-nil
   1287 )
   1288 
   1289 ;;;;;;;;;;;;;;;;;; -ifield
   1290 
   1291 ;	  15                                            0
   1292 ;	 +-----------+-----+-----------+-----+-----------+
   1293 ;	 | Operand2  | Mode| Opcode    | Size| Operand1  |
   1294 ;	 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   1295 ;
   1296 ;	 Figure 5.  General instruction format.
   1297 ;
   1298 ; Some deviations from this format exist, [see below].
   1299 
   1300 ; Field specifiers in CGEN specify the highest numbered bit followed by
   1301 ; the number of bits.
   1302 
   1303 (dnf f-operand1 "Operand1" () 3 4)
   1304 (dnf f-size "Size" () 5 2)
   1305 (dnf f-opcode "Opcode" () 9 4)
   1306 (dnf f-mode "Mode" () 11 2)
   1307 (dnf f-operand2 "Operand2" () 15 4)
   1308 
   1309 ; Subfields.  FIXME: unfortunately there's some limitation in CGEN so we
   1310 ; can't (as would be somewhat intuitive) make f-mode a multi-ifield
   1311 ; consisting of these two, concatenated.
   1312 (dnf f-memmode "Indirect of autoincrement" () 10 1)
   1313 (dnf f-membit "Memory specifier" () 11 1)
   1314 
   1315 (dnf f-b5 "Bit 5 (zero for some quick operands)" () 5 1)
   1316 
   1317 ; When the addressing mode is quick immediate, the low bits are
   1318 ; part of the operand.
   1319 (dnf f-opcode-hi "Opcode field, high bits" () 9 2)
   1320 
   1321 ; Common synonyms for those fields.
   1322 (define-pmacro f-source f-operand1)
   1323 (define-pmacro f-dest f-operand2)
   1324 
   1325 (dnmf
   1326  f-dstsrc "Dest and source fields concatenated" () UINT
   1327  (f-dest f-source)
   1328  ; Insert-code.
   1329  (sequence
   1330    ((SI tmpval))
   1331    (set tmpval (ifield f-dstsrc))
   1332    (set (ifield f-dest) (and (srl tmpval 4) #xf))
   1333    (set (ifield f-source) (and tmpval #xf)))
   1334  ; Extract-code.
   1335  (set
   1336   (ifield f-dstsrc)
   1337   (and (or (ifield f-source) (sll (ifield f-dest) 4)) #xff))
   1338 )
   1339 
   1340 ;The 6-bit value may be sign or zero extended depending on the instruction.
   1341 ;
   1342 ;	  15                                            0
   1343 ;	 +-----------+-----+-----------+-----+-----------+
   1344 ;	 | Operand2  | Mode| Opcode    | Immediate value |
   1345 ;	 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   1346 ;
   1347 ;   Figure 6.  Quick immediate addressing mode instruction format.
   1348 
   1349 (dnf f-u6 "Quick immediate unsigned 6-bit" () 5 6)
   1350 (df f-s6 "Quick signed 6-bit" () 5 6 INT #f #f)
   1351 
   1352 ; There's also a variant used with shift insns, with one bit larger opcode
   1353 ; and one bit smaller immediate value, though it doesn't have a general
   1354 ; graphic description.
   1355 (dnf f-u5 "Quick unsigned 5-bit" () 4 5)
   1356 
   1357 ; Similarly, a four-bit immediate field.
   1358 (dnf f-u4 "Quick unsigned 4-bit" () 3 4)
   1359 
   1360 ; An 8-bit signed value, which doesn't have a general graphic description.
   1361 (df f-s8 "Source signed byte" () 7 8 INT #f #f)
   1362 
   1363 ; The 9-bit branch offset, with bit 0 in the field being bit 8 in the
   1364 ; offset, and bit 0 in the offset always 0.
   1365 (df f-disp9-hi "PC-relative 9-bit offset, sign bit" () 0 1 INT #f #f)
   1366 (dnf f-disp9-lo "PC-relative 9-bit offset, low bits" () 7 7)
   1367 
   1368 ; It would work to have this in two mach-specific variants, but
   1369 ; considering that current-mach-is-v32 is a compile-time constant, we
   1370 ; don't win any simulator performance.
   1371 (dnmf
   1372  f-disp9 "PC-relative 9-bit offset"
   1373  (PCREL-ADDR)
   1374  INT
   1375  (f-disp9-hi f-disp9-lo)
   1376  ; Insert-code.
   1377  (sequence
   1378    ((SI absval))
   1379    (set absval (srl (sub (sub SI (ifield f-disp9) pc)
   1380 			 (if SI current-mach-is-v32 0 2)) 1))
   1381    (set (ifield f-disp9-hi) (if (lt absval 0) 1 0))
   1382    (set (ifield f-disp9-lo) (and absval) #x7f))
   1383  ; Extract-code.
   1384  (sequence
   1385    ((SI abslo) (SI absval))
   1386    (set abslo (sll (ifield f-disp9-lo) 1))
   1387    (set absval
   1388 	(or (if SI (ne (ifield f-disp9-hi) 0)
   1389 		(inv SI #xff)
   1390 		0)
   1391 	    abslo))
   1392    (set (ifield f-disp9)
   1393 	(add SI (add SI pc absval) (if SI current-mach-is-v32 0 2))))
   1394 )
   1395 
   1396 ; The operand of LAPCQ is PC-relative, similar to f-disp9 but unsigned,
   1397 ; and only four bits.
   1398 (df
   1399  f-qo
   1400  "PC-relative 4-bit unsigned offset, counted from start of insn"
   1401  (MACH-V32 PCREL-ADDR)
   1402  3 4
   1403  UINT
   1404  ; Insert-code.
   1405  ((value pc) (srl SI (sub SI value pc) 1))
   1406  ; Extract-code.
   1407  ((value pc) (add SI pc (sll SI value 1)))
   1408 )
   1409 
   1410 ; 8-bit, 16-bit and 32-bit immediates.  The 8-bit values are constructed
   1411 ; through encoding/decoding functions, since the PC increment is by a
   1412 ; word.
   1413 (define-pmacro (dcrisf x-name x-comment x-attrs x-word-offset x-word-length
   1414 		       x-start x-length x-mode x-encode x-decode)
   1415   (define-ifield
   1416     (name x-name)
   1417     (comment x-comment)
   1418     (.splice attrs (.unsplice x-attrs))
   1419     (word-offset x-word-offset)
   1420     (word-length x-word-length)
   1421     (start x-start)
   1422     (length x-length)
   1423     (mode x-mode)
   1424     (.splice encode (.unsplice x-encode))
   1425     (.splice decode (.unsplice x-decode))
   1426   )
   1427 )
   1428 
   1429 (dcrisf
   1430  f-indir-pc+-byte "[PC+] 8-bit field" (SIGN-OPT)
   1431  16 16
   1432  15 16 ; CGEN-FIXME: Should be 7 8
   1433  INT (#f) (#f)
   1434 )
   1435 
   1436 (dcrisf
   1437  f-indir-pc+-word "[PC+] 16-bit field" (SIGN-OPT)
   1438  16 16 15 16 INT (#f) (#f)
   1439 )
   1440 
   1441 ; CGEN-FIXME: I shouldn't have to use trunc here, should I?
   1442 ; Sign-extension should be implicit through use of SI (as opposed to USI)
   1443 ; and additionally through SIGN-OPT.  The ext isn't actually needed, but
   1444 ; having it there rather than implicit makes more sense than to just have
   1445 ; the trunc.
   1446 (dcrisf
   1447  f-indir-pc+-word-pcrel "[PC+] PC-relative 16-bit field"
   1448  (PCREL-ADDR SIGN-OPT)
   1449  16 16 15 16 SI
   1450  ((value pc) (sub SI value (add SI pc (if SI current-mach-is-v32 0 4))))
   1451  ((value pc) (add SI (ext SI (trunc HI value)) (add SI pc (if SI current-mach-is-v32 0 4))))
   1452 )
   1453 
   1454 (dcrisf
   1455  f-indir-pc+-dword "PC autoincrement - 32-bit field" (SIGN-OPT)
   1456  16 32 31 32 INT (#f) (#f)
   1457 )
   1458 
   1459 (dcrisf
   1460  f-indir-pc+-dword-pcrel
   1461  "[PC+] PC-relative 32-bit field, counted from start of insn"
   1462  (SIGN-OPT MACH-V32 PCREL-ADDR)
   1463  16 32 31 32 INT
   1464  ((value pc) (sub SI value pc))
   1465  ((value pc) (add SI pc value))
   1466 )
   1467 
   1468 ;;;;;;;;;;;;;;;;;; -insn-enum -normal-operand -normal-derived-operand
   1469 
   1470 ;; How different fields are transformed into something we put in insns.
   1471 
   1472 ;	 m       := size modifier, byte (00), word (01) or dword (10)
   1473 ;	 z       := size modifier, byte (0) or word (1)
   1474 ; (For the latter, the "higher" bit is always 0, mapping trivially on m.)
   1475 
   1476 (define-normal-insn-enum
   1477   insn-size
   1478   "Standard instruction operand size"
   1479   ()
   1480   SIZE_
   1481   f-size
   1482   ("BYTE" "WORD" "DWORD" "FIXED")
   1483 )
   1484 
   1485 ; The mode field for insns with "s" operand (perhaps with a partial set of
   1486 ; operand types).
   1487 (define-normal-insn-enum
   1488   insn-mode
   1489   "Standard instruction addressing modes"
   1490   ()
   1491   MODE_
   1492   f-mode
   1493   ("QUICK_IMMEDIATE" "REGISTER" "INDIRECT" "AUTOINCREMENT")
   1494 )
   1495 
   1496 (define-normal-insn-enum
   1497   insn-memoryness-mode
   1498   "Whether the operand is indirect"
   1499   ()
   1500   MODEMEMP_
   1501   f-membit
   1502   ("NO" "YES")
   1503 )
   1504 
   1505 ; FIXME: Needed?
   1506 (define-normal-insn-enum
   1507   insn-memincness-mode
   1508   "Whether the indirect operand is autoincrement"
   1509   ()
   1510   MODEINCP_
   1511   f-memmode
   1512   ("NO" "YES")
   1513 )
   1514 
   1515 ; Special semantics for multiply.
   1516 (define-pmacro MODE_MULU MODE_INDIRECT)
   1517 (define-pmacro MODE_MULS MODE_AUTOINCREMENT)
   1518 
   1519 (define-normal-insn-enum
   1520   insn-signed-size
   1521   "Signed instruction operand size"
   1522   ()
   1523   SIGNED_
   1524   f-size
   1525   ("UNDEF_SIZE_0" "UNDEF_SIZE_1" "BYTE" "WORD")
   1526 )
   1527 
   1528 (define-normal-insn-enum
   1529   insn-unsigned-size
   1530   "Unsigned instruction operand size"
   1531   ()
   1532   UNSIGNED_
   1533   f-size
   1534   ("BYTE" "WORD" "UNDEF_SIZE_2" "UNDEF_SIZE_3")
   1535 )
   1536 
   1537 ;	 Rs      := source operand, register addressing mode
   1538 (dnop Rs "Source general register" () h-gr f-source)
   1539 
   1540 ;	 [Rs]    := source operand, indirect addressing mode
   1541 ; = MODE_INDIRECT Rs
   1542 
   1543 ;	 [Rs+]   := source operand, autoincrement addressing mode  (see note!)
   1544 ; = MODE_AUTOINCREMENT Rs
   1545 
   1546 ; The union of [Rs] and [Rs(+)]
   1547 ; = MODEMEMP_YES Rs
   1548 
   1549 ; Whether an indirect operand is increment can be obtained as an operand by
   1550 ; = inc
   1551 (dnop inc "Incrementness of indirect operand" () h-inc f-memmode)
   1552 
   1553 ; or as an affirmative specifier
   1554 ; = MODEINCP_YES
   1555 ; (or MODEINCP_NO)
   1556 
   1557 ;	 s       := source operand, any of the modes Rs, [Rs] or [Rs+]
   1558 ; No common operand; each are handled separately, using the above definitions.
   1559 
   1560 ;	 Ps      := source operand, special register
   1561 ; It's in the field usually used for the destination.
   1562 (dnop Ps "Source special register" () h-sr f-dest)
   1563 
   1564 ;	 Ss      := source operand, support register
   1565 ; It's in the field usually used for the destination.
   1566 (dnop Ss "Source support register" (MACH-V32) h-supr f-dest)
   1567 
   1568 ;	 Sd      := source operand, support register
   1569 (dnop Sd "Destination support register" (MACH-V32) h-supr f-dest)
   1570 
   1571 ;	 i       := 6-bit signed immediate operand
   1572 (dnop i "Quick signed 6-bit" () h-sint f-s6)
   1573 
   1574 ;	 j       := 6-bit unsigned immediate operand
   1575 (dnop j "Quick unsigned 6-bit" () h-uint f-u6)
   1576 
   1577 ;	 c       := 5-bit immediate shift value
   1578 (dnop c "Quick unsigned 5-bit" () h-uint f-u5)
   1579 
   1580 ;	 qo      := 4-bit unsigned immediate operand
   1581 (dnop qo "Quick unsigned 4-bit, PC-relative" (MACH-V32) h-addr f-qo)
   1582 
   1583 ;	 Rd      := destination operand, register addressing mode
   1584 (dnop Rd "Destination general register" () h-gr f-dest)
   1585 (define-pmacro Rd-sfield Rs)
   1586 (define-pmacro Rs-dfield Rd)
   1587 
   1588 ;	 [Rd]    := destination operand, indirect addressing mode
   1589 ; = MODE_INDIRECT Rd
   1590 
   1591 ;	 [Rd+]   := destination operand, autoincrement addressing mode
   1592 ; = MODE_AUTOINCREMENT Rd
   1593 
   1594 ;	 [PC+]   := destination operand PC, autoincrement addressing mode
   1595 ; = MODE_AUTOINCREMENT (f-dest 15) X
   1596 ; where X is one of sconst8, uconst8, sconst16, uconst16 or const32.
   1597 (dnop sconst8 "Signed byte [PC+]" () h-sint f-indir-pc+-byte)
   1598 (dnop uconst8 "Unsigned byte [PC+]" () h-uint f-indir-pc+-byte)
   1599 (dnop sconst16 "Signed word [PC+]" () h-sint f-indir-pc+-word)
   1600 (dnop uconst16 "Unsigned word [PC+]" () h-uint f-indir-pc+-word)
   1601 (dnop const32 "Dword [PC+]" () h-uint f-indir-pc+-dword)
   1602 (dnop const32-pcrel "Dword [PC+]" () h-addr f-indir-pc+-dword-pcrel)
   1603 
   1604 ;	 d       := destination operand, any of the modes Rd, [Rd] or [Rd+]
   1605 ; No common operand; each are handled separately, using the above definitions.
   1606 
   1607 ;	 Pd      := destination operand, special register
   1608 (dnop Pd "Destination special register" () h-sr f-dest)
   1609 
   1610 ;	 o       := 8-bit immediate offset value
   1611 (dnop o "Signed 8-bit" () h-sint f-s8)
   1612 
   1613 ; The division of operand semantics and insn fields in the CRIS
   1614 ; instruction set reference doesn't permit a simple mapping to a
   1615 ; simulator description, and the division of insn fields and
   1616 ; semantics in CGEN is not between the define-normal-ifield
   1617 ; vs. define-normal-operand.  For example, the "o" operand is
   1618 ; PC-relative for branch insns, as described by the CGEN f-disp9
   1619 ; field.
   1620 ; See comment at f-disp9; thankfully the mach
   1621 ; attribute works here to have two different definitions by the
   1622 ; same name.
   1623 (dnop o-pcrel "9-bit signed immediate PC-rel"
   1624       ()
   1625       h-iaddr f-disp9)
   1626 
   1627 (dnop o-word-pcrel "16-bit signed immediate PC-rel"
   1628       ()
   1629       h-iaddr f-indir-pc+-word-pcrel)
   1630 
   1631 ;	 cc      := condition code
   1632 (dnop cc "Condition codes" () h-ccode f-dest)
   1633 
   1634 ;	 n       := 4 bit breakpoint exception vector index
   1635 (dnop n "Quick unsigned 4-bit" () h-uint f-u4)
   1636 
   1637 ; The "option" in the SWAP insn.
   1638 (dnop swapoption "Swap option" () h-swap f-dest)
   1639 
   1640 (dnop list-of-flags "Flag bits as operand" () h-flagbits f-dstsrc)
   1641 
   1642 ; Enumerations for insn codes, for use in insn definitions
   1643 ; instead of raw numbers.  See it as operand definitions for the
   1644 ; opcode field.
   1645 
   1646 (define-normal-insn-enum
   1647   insn-qi-opc
   1648   "Insns for MODE_QUICK_IMMEDIATE"
   1649   ()
   1650   Q_
   1651   f-opcode
   1652   ("BCC_0" "BCC_1" "BCC_2" "BCC_3"
   1653    "BDAP_0" "BDAP_1" "BDAP_2" "BDAP_3"
   1654    "ADDQ" "MOVEQ" "SUBQ" "CMPQ"
   1655    "ANDQ" "ORQ" "ASHQ" "LSHQ")
   1656 )
   1657 
   1658 (define-normal-insn-enum
   1659   insn-qihi-opc
   1660   "Same as insn-qi-opc, though using only the high two bits of the opcode"
   1661   ()
   1662   QHI_
   1663   f-opcode-hi
   1664   ("BCC" "BDAP" "OTHER2" "OTHER3")
   1665 )
   1666 (define-pmacro QHI_ADDOQ QHI_BDAP)
   1667 
   1668 (define-normal-insn-enum
   1669   insn-r-opc
   1670   "Insns for MODE_REGISTER and either SIZE_BYTE, SIZE_WORD or SIZE_DWORD"
   1671   ()
   1672   R_
   1673   f-opcode
   1674   ("ADDX" "MOVX" "SUBX" "LSL"
   1675    "ADDI" "BIAP" "NEG" "BOUND"
   1676    "ADD" "MOVE" "SUB" "CMP"
   1677    "AND" "OR" "ASR" "LSR")
   1678 )
   1679 (define-pmacro R_ADDI_ACR R_BIAP)
   1680 
   1681 (define-normal-insn-enum
   1682   insn-rfix-opc
   1683   "Insns for MODE_REGISTER and SIZE_FIXED"
   1684   ()
   1685   RFIX_
   1686   f-opcode
   1687   ("ADDX" "MOVX" "SUBX" "BTST"
   1688    "SCC" "ADDC" "SETF" "CLEARF"
   1689    "MOVE_R_S" "MOVE_S_R" "ABS" "DSTEP"
   1690    "LZ" "SWAP" "XOR" "MSTEP")
   1691 )
   1692 (define-pmacro RFIX_MCP RFIX_MSTEP)
   1693 
   1694 (define-normal-insn-enum
   1695   insn-indir-opc
   1696   "Insns for (MODE_INDIRECT or MODE_AUTOINCREMENT) and either SIZE_BYTE, SIZE_WORD or SIZE_DWORD"
   1697   ()
   1698   INDIR_
   1699   f-opcode
   1700   ("ADDX" "MOVX" "SUBX" "CMPX"
   1701    "MUL" "BDAP_M" "ADDC" "BOUND"
   1702    "ADD" "MOVE_M_R" "SUB" "CMP"
   1703    "AND" "OR" "TEST" "MOVE_R_M")
   1704 )
   1705 (define-pmacro INDIR_ADDO INDIR_BDAP_M)
   1706 
   1707 (define-normal-insn-enum
   1708   insn-infix-opc
   1709   "Insns for (MODE_INDIRECT or MODE_AUTOINCREMENT) and SIZE_FIXED"
   1710   ()
   1711   INFIX_
   1712   f-opcode
   1713   ("ADDX" "MOVX" "SUBX" "CMPX"
   1714    "JUMP_M" "DIP" "JUMP_R" "BCC_M"
   1715    "MOVE_M_S" "MOVE_S_M" "BMOD" "BSTORE"
   1716    "RBF" "SBFS" "MOVEM_M_R" "MOVEM_R_M")
   1717 )
   1718 
   1719 (define-pmacro INFIX_MOVE_SS INFIX_SBFS)
   1720 (define-pmacro INFIX_LAPC INFIX_DIP)
   1721 (define-pmacro INFIX_RFE INFIX_JUMP_M)
   1722 (define-pmacro INFIX_RFN INFIX_JUMP_M)
   1723 (define-pmacro INFIX_HALT INFIX_JUMP_M)
   1724 (define-pmacro INFIX_SFE INFIX_JUMP_M)
   1725 (define-pmacro INFIX_RFG INFIX_JUMP_M)
   1726 (define-pmacro INFIX_JAS_R INFIX_JUMP_R)
   1727 (define-pmacro INFIX_JAS_M INFIX_JUMP_R)
   1728 (define-pmacro INFIX_JASC INFIX_RBF)
   1729 (define-pmacro INFIX_JUMP_P INFIX_BCC_M)
   1730 (define-pmacro INFIX_BAS INFIX_BMOD)
   1731 (define-pmacro INFIX_BASC INFIX_BSTORE)
   1732 (define-pmacro INFIX_BREAK INFIX_JUMP_M)
   1733 (define-pmacro INFIX_FIDXI INFIX_JUMP_M)
   1734 (define-pmacro INFIX_FIDXD INFIX_BAS)
   1735 (define-pmacro INFIX_FTAGI INFIX_JUMP_M)
   1736 (define-pmacro INFIX_FTAGD INFIX_BAS)
   1737 
   1738 ; Classes of insns:
   1739 ; Move-to-register, move-to-memory, move-to/from-other-register,
   1740 ; logical, arithmetic, branch.
   1741 ; Classes of operands:
   1742 ; quick, register, memory-indirect, memory-postinc.
   1743 
   1744 
   1745 ;;;;;;;;;;;;;;;;;; -normal-insn
   1746 
   1747 (define-pmacro (dni-bwd-attr name comment attr syntax fmt fsem timing)
   1748   (begin
   1749     (dni (.sym name .b) (.str "byte " comment) attr (.str name ".b " syntax)
   1750 	 (.splice (.unsplice fmt) SIZE_BYTE)
   1751 	 (fsem QI)
   1752 	 timing)
   1753     (dni (.sym name .w) (.str "word " comment) attr (.str name ".w " syntax)
   1754 	 (.splice (.unsplice fmt) SIZE_WORD)
   1755 	 (fsem HI)
   1756 	 timing)
   1757     (dni (.sym name .d) (.str "dword " comment) attr (.str name ".d " syntax)
   1758 	 (.splice (.unsplice fmt) SIZE_DWORD)
   1759 	 (fsem SI)
   1760 	 timing))
   1761 )
   1762 
   1763 (define-pmacro (dni-cdt-attr name comment attr syntax fmt semantics)
   1764   "dni without specifying timing"
   1765   (dni name comment attr syntax fmt semantics (cris-timing))
   1766 )
   1767 
   1768 (define-pmacro (dni-cdt-bwd-attr name comment attr syntax fmt fsem)
   1769   (begin
   1770     (dni-cdt-attr (.sym name .b-r) (.str "byte " comment) attr (.str name ".b " syntax)
   1771 		  (.splice (.unsplice fmt) SIZE_BYTE)
   1772 		  (fsem QI))
   1773     (dni-cdt-attr (.sym name .w-r) (.str "word " comment) attr (.str name ".w " syntax)
   1774 		  (.splice (.unsplice fmt) SIZE_WORD)
   1775 		  (fsem HI))
   1776     (dni-cdt-attr (.sym name .d-r) (.str "dword " comment) attr (.str name ".d " syntax)
   1777 		  (.splice (.unsplice fmt) SIZE_DWORD)
   1778 		  (fsem SI)))
   1779 )
   1780 
   1781 ; Some convenience macros based on the above ones.
   1782 (define-pmacro (dni-cdt-bwd name comment syntax fmt fsem)
   1783   (dni-cdt-bwd-attr name comment () syntax fmt fsem)
   1784 )
   1785 
   1786 (define-pmacro (dni-bwd name comment syntax fmt fsem timing)
   1787   (dni-bwd-attr comment () syntax fmt fsem timing)
   1788 )
   1789 
   1790 (define-pmacro-map
   1791   (((dni-cdt name comment syntax fmt semantics)
   1792     (dni-cdt-attr name comment () syntax fmt semantics))
   1793    ((dni-c-QI-attr name comment attr syntax fmt fsem)
   1794     (dni name comment attr syntax fmt fsem (cris-timing-const-QI)))
   1795    ((dni-c-HI-attr name comment attr syntax fmt fsem)
   1796     (dni name comment attr syntax fmt fsem (cris-timing-const-HI)))
   1797    ((dni-c-SI-attr name comment attr syntax fmt fsem)
   1798     (dni name comment attr syntax fmt fsem (cris-timing-const-SI))))
   1799 )
   1800 
   1801 (define-pmacro-map
   1802   (((dni-c-QI name comment syntax fmt fsem)
   1803     (dni-c-QI-attr name comment () syntax fmt fsem))
   1804    ((dni-c-HI name comment syntax fmt fsem)
   1805     (dni-c-HI-attr name comment () syntax fmt fsem))
   1806    ((dni-c-SI name comment syntax fmt fsem)
   1807     (dni-c-SI-attr name comment () syntax fmt fsem)))
   1808 )
   1809 
   1810 ; These flags are both cleared by all insns except prefixes (before
   1811 ; CRISv32) and "setf x", so we put them in a handy macro.
   1812 (define-pmacro
   1813   (reset-x-p)
   1814   (sequence
   1815     ()
   1816     (set xbit 0)
   1817     (set prefix-set 0))
   1818 )
   1819 
   1820 ;        NOP           | 0  0  0  0| 0  1| 0  1  0  0| 0  0| 1  1  1  1|
   1821 ; (For V32, "SETF" (no flags) is used.)
   1822 (dni-cdt-attr
   1823  nop "nop" (MACH-PC) "nop"
   1824  (+ (f-operand2 0) R_ADDI MODE_REGISTER SIZE_BYTE (f-operand1 15))
   1825  (reset-x-p)
   1826 )
   1827 
   1828 ; Pre- and v32+ variants MOVE insns set flags differently.  These two
   1829 ; macros for flag settings are meant to be used in all MOVE insns.
   1830 (define-pmacro (setf-moveq value)
   1831   (sequence
   1832     ()
   1833     (set-quiet nbit-move (lt SI value 0))
   1834     (set-quiet zbit-move (andif BI (eq SI value 0) (if BI xbit zbit 1)))
   1835     (set-quiet cbit-move 0)
   1836     (set-quiet vbit-move 0)
   1837     (reset-x-p))
   1838 )
   1839 
   1840 (define-pmacro (setf-move size value)
   1841   (sequence
   1842     ()
   1843     (set nbit (lt size value 0))
   1844     (set zbit (andif BI (eq size value 0) (if BI xbit zbit 1)))
   1845     (set-quiet cbit-move 0)
   1846     (set-quiet vbit-move 0)
   1847     (reset-x-p))
   1848 )
   1849 ; The CGEN binop-with-bit operations are not documented well enough that I
   1850 ; trust their semantics to remain stable.  Better define local ones: the
   1851 ; semantics become explicit.
   1852 (define-pmacro-map
   1853   (((add-overflow size R D S carry)
   1854     (orif BI (andif BI (andif BI (lt size S 0) (lt size D 0)) (ge size R 0))
   1855 	  (andif BI (andif BI (ge size S 0) (ge size D 0)) (lt size R 0))))
   1856    ((add-carry size R D S carry)
   1857     (orif BI (andif BI (lt size S 0) (lt size D 0))
   1858 	  (orif BI (andif BI (lt size D 0) (ge size R 0))
   1859 		(andif BI (lt size S 0) (ge size R 0)))))
   1860    ((sub-overflow size R D S carry)
   1861     (orif BI (andif BI (andif BI (ge size S 0) (lt size D 0)) (ge size R 0))
   1862 	  (andif BI (andif BI (lt size S 0) (ge size D 0)) (lt size R 0))))
   1863    ((sub-carry size R D S carry)
   1864     (orif BI (andif BI (lt size S 0) (ge size D 0))
   1865 	  (orif BI (andif BI (ge size D 0) (lt size R 0))
   1866 		(andif BI (lt size S 0) (lt size R 0)))))
   1867    ; Only valid for size := DI
   1868    ((mulu-overflow size R D S carry)
   1869     (ne DI R (zext DI (trunc SI R))))
   1870    ((mulu-carry size R D S carry)
   1871     (andif current-mach-is-v32 carry))
   1872    ((muls-overflow size R D S carry)
   1873     (ne DI R (ext DI (trunc SI R))))
   1874    ((muls-carry size R D S carry)
   1875     (andif current-mach-is-v32 carry)))
   1876 )
   1877 
   1878 (define-pmacro (setf-arit2 size op source1 source2 result carryin carryout)
   1879   "Set no-prefix, x=0, carryout, v, z and n according to operation OP in size SIZE"
   1880   (sequence
   1881     ()
   1882     (set carryout ((.sym op -carry) size result source1 source2 carryin))
   1883     (set nbit (lt size result 0))
   1884     (set zbit (andif BI (eq size result 0) (orif BI zbit (not BI xbit))))
   1885     (set vbit ((.sym op -overflow) size result source1 source2 carryin))
   1886     (reset-x-p))
   1887 )
   1888 (define-pmacro (setf-arit size op source1 source2 result carry)
   1889   "Set no-prefix, x=0, c, v, z and n according to operation OP in size SIZE"
   1890   (setf-arit2 size op source1 source2 result carry cbit)
   1891 )
   1892 
   1893 ; Let's have convienence macros for arithmetic, including evaluation of the
   1894 ; operation, destination modification, flag setting and carry propagation.
   1895 (define-pmacro
   1896   (cris-arit6-int arit size fdest fdest_op srcop1 srcop2 carryout carryin)
   1897   "Core for performing some three-operand arithmetic with carry as parameter"
   1898   (sequence
   1899    ((size tmpopd) (size tmpops) (BI carry) (size newval))
   1900    (set tmpops srcop2)
   1901    (set tmpopd srcop1)
   1902    (set carry carryin)
   1903    (set newval ((.sym arit c) tmpopd tmpops (if BI (eq xbit 0) 0 carry)))
   1904    (fdest size fdest_op newval)
   1905    (setf-arit2 size arit tmpopd tmpops newval carry carryout))
   1906 )
   1907 
   1908 (define-pmacro
   1909   (cris-arit5-int arit size destregno srcop1 srcop2 carryout carryin)
   1910   "As cris-arit6-int, but to set a part of a general register"
   1911   (cris-arit6-int
   1912    arit
   1913    size
   1914    (.pmacro (sz regno val) (set-subreg-gr sz regno val))
   1915    destregno
   1916    srcop1
   1917    srcop2
   1918    carryout
   1919    carryin)
   1920 )
   1921 
   1922 (define-pmacro (cris-arit5 arit size destreg srcop1 srcop2 carryout carryin)
   1923   "As cris-arit5-int, but takes a register as parameter, not register number"
   1924   (cris-arit5-int arit size (regno destreg) srcop1 srcop2 carryout carryin)
   1925 )
   1926 (define-pmacro (cris-arit3-int arit size destregno srcop1 srcop2)
   1927   "As cris-arit5-int, but with carry-in same as carry-out"
   1928   (cris-arit5-int arit size destregno srcop1 srcop2 cbit cbit)
   1929 )
   1930 (define-pmacro (cris-arit3 arit size destreg srcop1 srcop2)
   1931   "As cris-arit3-int, but takes a register as parameter, not register number"
   1932   (cris-arit3-int arit size (regno destreg) srcop1 srcop2)
   1933 )
   1934 (define-pmacro (cris-arit arit size destreg srcop)
   1935   "As cris-arit3, but with destination same as srcop1"
   1936   (cris-arit3 arit size destreg destreg srcop)
   1937 )
   1938 (define-pmacro (cris-arit-3op arit size destsrcop2 srcop1 dest-3op)
   1939   "Similar to cris-arit3-int, but for prefixed operand only"
   1940   (cris-arit3-int arit size
   1941 		  (if SI (andif prefix-set (not inc))
   1942 		      (regno dest-3op)
   1943 		      (regno destsrcop2))
   1944 		  destsrcop2 srcop1)
   1945 )
   1946 
   1947 ; Convenience macros to select a part of a value and its complement, for
   1948 ; the <op>.b, <op>.w and <op>.d operations.
   1949 (define-pmacro (QI-part val) (and SI val #xff))
   1950 (define-pmacro (non-QI-part val) (and SI val #xffffff00))
   1951 (define-pmacro (HI-part val) (and SI val #xffff))
   1952 (define-pmacro (non-HI-part val) (and SI val #xffff0000))
   1953 (define-pmacro (SI-part val) val)
   1954 (define-pmacro (non-SI-part val) 0)
   1955 (define-pmacro
   1956   (set-subreg-gr-bw BWD gregno newval)
   1957   "Set a byte or word part or full dword of a general register"
   1958   (sequence
   1959     ((SI oldregval))
   1960     (set oldregval (reg h-raw-gr gregno))
   1961     (set (reg h-gr gregno)
   1962 	 (or SI ((.sym BWD -part) newval) ((.sym non- BWD -part) oldregval))))
   1963 )
   1964 (define-pmacro (set-subreg-gr BWD gregno newval)
   1965   ((.sym set-subreg-gr- BWD) BWD gregno newval)
   1966 )
   1967 (define-pmacro (set-subreg-gr-SI SI gregno newval)
   1968   (set (reg h-gr gregno) newval)
   1969 )
   1970 (define-pmacro set-subreg-gr-HI set-subreg-gr-bw)
   1971 (define-pmacro set-subreg-gr-QI set-subreg-gr-bw)
   1972 
   1973 ; MOVE.m  Rs,Rd           [ Rd | 011001mm | Rs ]
   1974 (dni-cdt-bwd
   1975  move "move.m r,R"
   1976  "move.m ${Rs},${Rd}"
   1977  (+ Rd MODE_REGISTER R_MOVE Rs)
   1978  (.pmacro
   1979   (BWD)
   1980   (sequence
   1981     ((BWD newval))
   1982     (set newval Rs)
   1983     (set-subreg-gr BWD (regno Rd) newval)
   1984     (setf-move BWD newval)))
   1985 )
   1986 
   1987 ; MOVE.D  PC,Rd           [ Rd | 01100110 | 1111 ]
   1988 ; This insn is used in PIC code to find out the code address.  It's an
   1989 ; exception to the (guarded) non-implementation of PC operands in this
   1990 ; file.
   1991 (dni-cdt-attr
   1992  movepcr "move.d PC,R"
   1993  (MACH-PC UNCOND-CTI)
   1994  "move.d PC,${Rd}"
   1995  (+ Rd MODE_REGISTER R_MOVE SIZE_DWORD (f-source 15))
   1996  (sequence
   1997    ((SI pcval))
   1998    (set pcval (add SI pc 2))
   1999    (set Rd pcval)
   2000    (setf-move SI pcval))
   2001 )
   2002 
   2003 ; MOVEQ   i,Rd            [ Rd | 001001 | i ]
   2004 (dni-cdt
   2005  moveq "moveq"
   2006  "moveq $i,$Rd"
   2007  (+ Rd MODE_QUICK_IMMEDIATE Q_MOVEQ i)
   2008  (sequence
   2009    ((SI newval))
   2010    (set newval i)
   2011    (set Rd newval)
   2012    (setf-moveq newval))
   2013 )
   2014 
   2015 (define-pmacro (dni-cdt-sbw name comment syntax fmt fsem)
   2016   "Insn generator for insns with signed <op>.b and <op>.w variants"
   2017   (begin
   2018     (dni-cdt
   2019      (.sym name .b-r) (.str "byte " comment) (.str name ".b " syntax)
   2020      (.splice (.unsplice fmt) SIGNED_BYTE)
   2021      (fsem QI))
   2022     (dni-cdt
   2023      (.sym name .w-r) (.str "word " comment) (.str name ".w " syntax)
   2024      (.splice (.unsplice fmt) SIGNED_WORD)
   2025      (fsem HI)))
   2026 )
   2027 
   2028 ; MOVS.z  Rs,Rd           [ Rd | 0100011z | Rs ]
   2029 (dni-cdt-sbw
   2030  movs "movs.m r,R"
   2031  "movs.m ${Rs},${Rd}"
   2032  (+ Rd MODE_REGISTER R_MOVX Rs)
   2033  (.pmacro
   2034   (BW)
   2035   (sequence
   2036     ((BW tmpops) (SI newval))
   2037     (set tmpops Rs)
   2038     (set newval (ext SI tmpops))
   2039     (set Rd newval)
   2040     (setf-move SI newval)))
   2041 )
   2042 
   2043 (define-pmacro (dni-cdt-ubw name comment syntax fmt fsem)
   2044   "Similar to dni-cdt-sbw but for unsigned operations"
   2045   (begin
   2046     (dni-cdt
   2047      (.sym name .b-r) (.str "byte " comment) (.str name ".b " syntax)
   2048      (.splice (.unsplice fmt) UNSIGNED_BYTE)
   2049      (fsem QI))
   2050     (dni-cdt
   2051      (.sym name .w-r) (.str "word " comment) (.str name ".w " syntax)
   2052      (.splice (.unsplice fmt) UNSIGNED_WORD)
   2053      (fsem HI)))
   2054 )
   2055 
   2056 ; MOVU.z  Rs,Rd           [ Rd | 0100010z | Rs ]
   2057 (dni-cdt-ubw
   2058  movu "movu.m r,R"
   2059  "movu.m ${Rs},${Rd}"
   2060  (+ Rd MODE_REGISTER R_MOVX Rs)
   2061  (.pmacro
   2062   (BW)
   2063   (sequence
   2064     ((BW tmpops) (SI newval))
   2065     (set tmpops Rs)
   2066     (set newval (zext SI tmpops))
   2067     (set Rd newval)
   2068     (setf-move SI newval)))
   2069 )
   2070 
   2071 ; (MOVE.m  [PC+],Rd        [ Rd | 111001mm | 1111 ])
   2072 ; For the moment, it doesn't seem worthwhile to make a dni-c-bwd macro;
   2073 ; too many places to parametrize.
   2074 (dni-c-QI
   2075  movecbr "move.b [PC+],R"
   2076  "move.b ${sconst8},${Rd}"
   2077  (+ Rd MODE_AUTOINCREMENT INDIR_MOVE_M_R SIZE_BYTE (f-source 15) sconst8)
   2078  (sequence
   2079    ((QI newval))
   2080    (set newval sconst8)
   2081    (set-subreg-gr QI (regno Rd) newval)
   2082    (setf-move QI newval))
   2083 )
   2084 
   2085 (dni-c-HI
   2086  movecwr "move.w [PC+],R"
   2087  "move.w ${sconst16},${Rd}"
   2088  (+ Rd MODE_AUTOINCREMENT INDIR_MOVE_M_R SIZE_WORD (f-source 15) sconst16)
   2089  (sequence
   2090    ((HI newval))
   2091    (set newval sconst16)
   2092    (set-subreg-gr HI (regno Rd) newval)
   2093    (setf-move HI newval))
   2094 )
   2095 
   2096 (dni-c-SI
   2097  movecdr "move.d [PC+],R"
   2098  "move.d ${const32},${Rd}"
   2099  (+ Rd MODE_AUTOINCREMENT INDIR_MOVE_M_R SIZE_DWORD (f-source 15) const32)
   2100  (sequence
   2101    ((SI newval))
   2102    (set newval const32)
   2103    (set Rd newval)
   2104    (setf-move SI newval))
   2105 )
   2106 
   2107 ; (MOVS.z  [PC+],Rd        [ Rd | 1100011z | 1111 ])
   2108 ; Similarly, no likely net improvement for a dni-c-bw.
   2109 (dni-c-QI
   2110  movscbr "movs.b [PC+],R"
   2111  "movs.b ${sconst8},${Rd}"
   2112  (+ Rd MODE_AUTOINCREMENT INDIR_MOVX SIGNED_BYTE (f-source 15) sconst8)
   2113  (sequence
   2114    ((SI newval))
   2115    ; FIXME: Make trunc unnecessary.
   2116    (set newval (ext SI (trunc QI sconst8)))
   2117    (set Rd newval)
   2118    (setf-move SI newval))
   2119 )
   2120 
   2121 (dni-c-HI
   2122  movscwr "movs.w [PC+],R"
   2123  "movs.w ${sconst16},${Rd}"
   2124  (+ Rd MODE_AUTOINCREMENT INDIR_MOVX SIGNED_WORD (f-source 15) sconst16)
   2125  (sequence
   2126    ((SI newval))
   2127    ; FIXME: Make trunc unnecessary.
   2128    (set newval (ext SI (trunc HI sconst16)))
   2129    (set Rd newval)
   2130    (setf-move SI newval))
   2131 )
   2132 
   2133 ; (MOVU.z  [PC+],Rd        [ Rd | 1100010z | 1111 ])
   2134 (dni-c-QI
   2135  movucbr "movu.b [PC+],R"
   2136  "movu.b ${uconst8},${Rd}"
   2137  (+ Rd MODE_AUTOINCREMENT INDIR_MOVX UNSIGNED_BYTE (f-source 15) uconst8)
   2138  (sequence
   2139    ((SI newval))
   2140    ; FIXME: Make trunc unnecessary.
   2141    (set newval (zext SI (trunc QI uconst8)))
   2142    (set Rd newval)
   2143    (setf-move SI newval))
   2144 )
   2145 
   2146 (dni-c-HI
   2147  movucwr "movu.w [PC+],R"
   2148  "movu.w ${uconst16},${Rd}"
   2149  (+ Rd MODE_AUTOINCREMENT INDIR_MOVX UNSIGNED_WORD (f-source 15) uconst16)
   2150  (sequence
   2151    ((SI newval))
   2152    ; FIXME: Make trunc unnecessary.
   2153    (set newval (zext SI (trunc HI uconst16)))
   2154    (set Rd newval)
   2155    (setf-move SI newval))
   2156 )
   2157 
   2158 ; ADDQ    j,Rd            [ Rd | 001000 | j ]
   2159 (dni-cdt
   2160  addq "addq j,Rd"
   2161  "addq $j,$Rd"
   2162  (+ Rd MODE_QUICK_IMMEDIATE Q_ADDQ j)
   2163  (cris-arit add SI Rd j)
   2164 )
   2165 
   2166 ; SUBQ    j,Rd            [ Rd | 001010| j ]
   2167 (dni-cdt
   2168  subq "subq j,Rd"
   2169  "subq $j,$Rd"
   2170  (+ Rd MODE_QUICK_IMMEDIATE Q_SUBQ j)
   2171  (cris-arit sub SI Rd j)
   2172 )
   2173 
   2174 ; Convenience macros for insns with a memory operand.
   2175 (define-pmacro
   2176   (dni-cmt-attr-tim name comment attr syntax fmt semantics timing)
   2177   "dni with memory-access"
   2178   (dni name comment attr syntax
   2179        ; Specifying MODE_INDIRECT and MODE_AUTOINCREMENT in this
   2180        ; manner makes the autoincrementness handily available.
   2181        ; It also effectively excludes non-memory use of dni-cmt.
   2182        (.splice (.unsplice fmt) MODEMEMP_YES inc)
   2183        semantics
   2184        timing)
   2185 )
   2186 
   2187 (define-pmacro (dni-cmt-attr name comment attr syntax fmt semantics)
   2188   "dni with read memory-access timing"
   2189   (dni-cmt-attr-tim name comment attr syntax fmt semantics
   2190 		    (cris-mem-timing))
   2191 )
   2192 
   2193 (define-pmacro (dni-cmwt-attr  name comment attr syntax fmt semantics)
   2194   "dni with write memory-access timing"
   2195   (dni-cmt-attr-tim name comment attr syntax fmt semantics
   2196 		    (cris-mem-write-timing))
   2197 )
   2198 
   2199 (define-pmacro QI-size 1)
   2200 (define-pmacro HI-size 2)
   2201 (define-pmacro SI-size 4)
   2202 
   2203 (define-pmacro (cris-get-mem size regop)
   2204   "Handle reading memory in <size>, with source address register\
   2205  (read once, maybe set once) in <regop> or prefixed"
   2206   (sequence
   2207     size
   2208     ((SI addr) (size tmp-mem) (BI postinc))
   2209 
   2210     ; Cache the incrementness of the operand.
   2211     (set postinc inc)
   2212 
   2213     ; Get the address from somewhere.
   2214     (set addr
   2215 	 (if SI (eq prefix-set 0)
   2216 	     ; If the insn was prefixed, it's in the prefix-register.
   2217 	     regop
   2218 	     prefixreg))
   2219 
   2220     ; Get the memory contents.
   2221     (set tmp-mem (mem size addr))
   2222 
   2223     ; For non-prefixed post-increment, we increment the address by the
   2224     ; size of the memory access.
   2225     (if (ne postinc 0)
   2226 	(sequence
   2227 	  ()
   2228 	  (if (eq prefix-set 0)
   2229 	      (set addr (add addr (.sym size -size))))
   2230 	  ; Update the source-register for post-increments.
   2231 	  (set regop addr)))
   2232 
   2233     ; Don't forget the return-value.
   2234     tmp-mem)
   2235 )
   2236 
   2237 (define-pmacro (cris-set-mem size regop value)
   2238   "Handle writing <value> of <size> to memory, with memory address register\
   2239  (read once, maybe set once) in <regop> or prefixed."
   2240   (sequence
   2241     ((SI addr) (BI postinc))
   2242 
   2243     ; Cache the incrementness of the operand.
   2244     (set postinc inc)
   2245 
   2246     ; Get the address from somewhere.
   2247     (set addr
   2248 	 (if SI (eq prefix-set 0)
   2249 	     ; If the insn was prefixed, it's in the prefix-register.
   2250 	     regop
   2251 	     prefixreg))
   2252 
   2253     ; Set the memory contents.  Integral-write semantics apply.
   2254     ; FIXME: currently v32 only; when proper semantics needed, fix v10.
   2255     (if (andif current-mach-is-v32 (ne xbit 0))
   2256 	(if (eq pbit 0)
   2257 	    (sequence
   2258 	      ()
   2259 	      (set (mem size addr) value)
   2260 	      ; Write failures are signalled (by whatever entity "sends
   2261 	      ; the signal") by setting P at time of the write above, if X
   2262 	      ; is set.  Here, we just need to copy P into C.
   2263 	      (set cbit pbit))
   2264 	    (set cbit 1))
   2265 	(set (mem size addr) value))
   2266 
   2267     ; For non-prefixed post-increment, we increment the address by the
   2268     ; size of the memory access.  As for the integral-write, this needs to
   2269     ; be tweaked for pre-v32: increment should have been performed if
   2270     ; there's a fault at the memory access above.
   2271     (if (ne postinc 0)
   2272 	(sequence
   2273 	  ()
   2274 	  (if (eq prefix-set 0)
   2275 	      (set addr (add addr (.sym size -size))))
   2276 	  ; Update the source-register for post-increments.
   2277 	  (set regop addr))))
   2278 )
   2279 
   2280 (define-pmacro
   2281   (dni-cmt-bwd-attr-tim name comment attr syntax fmt fsem timing)
   2282   "Core generator macro for insns with <op>.b, <op>.w and <op>.d variants\
   2283  and a memory operand."
   2284   (begin
   2285     (dni-cmt-attr-tim
   2286      (.sym name .b-m)
   2287      (.str "byte mem " comment)
   2288      attr
   2289      (.str name ".b " syntax)
   2290      (.splice (.unsplice fmt) SIZE_BYTE)
   2291      (fsem QI)
   2292      timing)
   2293     (dni-cmt-attr-tim
   2294      (.sym name .w-m)
   2295      (.str "word mem " comment)
   2296      attr
   2297      (.str name ".w " syntax)
   2298      (.splice (.unsplice fmt) SIZE_WORD)
   2299      (fsem HI)
   2300      timing)
   2301     (dni-cmt-attr-tim
   2302      (.sym name .d-m)
   2303      (.str "dword mem " comment)
   2304      attr
   2305      (.str name ".d " syntax)
   2306      (.splice (.unsplice fmt) SIZE_DWORD)
   2307      (fsem SI)
   2308      timing))
   2309 )
   2310 
   2311 ; Further refinement macros.
   2312 (define-pmacro (dni-cmt-bwd-attr name comment attr syntax fmt fsem)
   2313   (dni-cmt-bwd-attr-tim name comment attr syntax fmt fsem
   2314 			(cris-mem-timing))
   2315 )
   2316 
   2317 (define-pmacro (dni-cmwt-bwd name comment syntax fmt fsem)
   2318   (dni-cmt-bwd-attr-tim name comment () syntax fmt fsem
   2319 			(cris-mem-write-timing))
   2320 )
   2321 
   2322 (define-pmacro (dni-cmt-bwd name comment syntax fmt fsem)
   2323   (dni-cmt-bwd-attr name comment () syntax fmt fsem)
   2324 )
   2325 
   2326 (define-pmacro (dni-cmt-sbw name comment syntax fmt fsem)
   2327   "Core generator macro for insns with <op>.b and <op>.w variants\
   2328  and a signed memory operand."
   2329   (begin
   2330     (dni-cmt-attr
   2331      (.sym name .b-m) (.str "byte mem " comment)
   2332      ()
   2333      (.str name ".b " syntax)
   2334      (.splice (.unsplice fmt) SIGNED_BYTE)
   2335      (fsem QI))
   2336     (dni-cmt-attr
   2337      (.sym name .w-m) (.str "word mem " comment)
   2338      ()
   2339      (.str name ".w " syntax)
   2340      (.splice (.unsplice fmt) SIGNED_WORD)
   2341      (fsem HI)))
   2342 )
   2343 
   2344 (define-pmacro (dni-cmt-ubw name comment syntax fmt fsem)
   2345   "Core generator macro for insns with <op>.b and <op>.w variants\
   2346  and an unsigned memory operand."
   2347   (begin
   2348     (dni-cmt-attr
   2349      (.sym name .b-m) (.str "byte mem " comment)
   2350      ()
   2351      (.str name ".b " syntax)
   2352      (.splice (.unsplice fmt) UNSIGNED_BYTE)
   2353      (fsem QI))
   2354     (dni-cmt-attr
   2355      (.sym name .w-m) (.str "word mem " comment)
   2356      ()
   2357      (.str name ".w " syntax)
   2358      (.splice (.unsplice fmt) UNSIGNED_WORD)
   2359      (fsem HI)))
   2360 )
   2361 
   2362 ; CMP.m   Rs,Rd           [ Rd | 011011mm | Rs ]
   2363 (dni-cdt-bwd
   2364  cmp-r "compare register to register"
   2365  "$Rs,$Rd"
   2366  (+ Rd MODE_REGISTER R_CMP Rs)
   2367  (.pmacro
   2368   (BWD)
   2369   (cris-arit6-int
   2370    sub BWD (.pmacro (sz regno val) (nop)) 0
   2371    Rd Rs cbit cbit))
   2372 )
   2373 
   2374 ; CMP.m   [Rs],Rd         [ Rd | 101011mm | Rs ]
   2375 ; CMP.m   [Rs+],Rd        [ Rd | 111011mm | Rs ]
   2376 (dni-cmt-bwd
   2377  cmp-m "compare memory to register"
   2378  "[${Rs}${inc}],${Rd}"
   2379  (+ INDIR_CMP Rs Rd)
   2380  (.pmacro
   2381   (BWD)
   2382   (cris-arit6-int
   2383    sub BWD (.pmacro (sz regno val) (nop)) 0
   2384    Rd (cris-get-mem BWD Rs) cbit cbit))
   2385 )
   2386 
   2387 ; (CMP.m   [PC+],Rd        [ Rd | 111011mm | 1111 ])
   2388 (dni-c-QI
   2389  cmpcbr "cmp constant byte to register"
   2390  "cmp.b $sconst8,$Rd"
   2391  (+ Rd MODE_AUTOINCREMENT INDIR_CMP SIZE_BYTE (f-source 15) sconst8)
   2392  (cris-arit6-int
   2393   sub QI (.pmacro (sz regno val) (nop)) 0
   2394   Rd (trunc QI sconst8) cbit cbit)
   2395 )
   2396 
   2397 (dni-c-HI
   2398  cmpcwr "cmp constant word to register"
   2399  "cmp.w $sconst16,$Rd"
   2400  (+ Rd MODE_AUTOINCREMENT INDIR_CMP SIZE_WORD (f-source 15) sconst16)
   2401  (cris-arit6-int
   2402   sub HI (.pmacro (sz regno val) (nop)) 0
   2403   Rd (trunc HI sconst16) cbit cbit)
   2404 )
   2405 
   2406 (dni-c-SI
   2407  cmpcdr "cmp constant dword to register"
   2408  "cmp.d $const32,$Rd"
   2409  (+ Rd MODE_AUTOINCREMENT INDIR_CMP SIZE_DWORD (f-source 15) const32)
   2410  (cris-arit6-int
   2411   sub SI (.pmacro (sz regno val) (nop)) 0
   2412   Rd const32 cbit cbit)
   2413 )
   2414 
   2415 ; CMPQ    i,Rd            [ Rd | 001011 | i ]
   2416 (dni-cdt
   2417  cmpq "cmpq i,Rd"
   2418  "cmpq $i,$Rd"
   2419  (+ Rd MODE_QUICK_IMMEDIATE Q_CMPQ i)
   2420  (cris-arit6-int
   2421   sub SI (.pmacro (sz regno val) (nop)) 0
   2422   Rd i cbit cbit)
   2423 )
   2424 
   2425 ; CMPS.z  [Rs],Rd         [ Rd | 1000111z | Rs ]
   2426 ; CMPS.z  [Rs+],Rd        [ Rd | 1100111z | Rs ]
   2427 (dni-cmt-sbw
   2428  cmps-m "cmp sign-extended from memory to register"
   2429  "[${Rs}${inc}],$Rd"
   2430  (+ Rd INDIR_CMPX Rs)
   2431  (.pmacro
   2432   (BW)
   2433   (cris-arit6-int
   2434    sub SI (.pmacro (sz regno val) (nop)) 0
   2435    Rd ((.sym BW -ext) (cris-get-mem BW Rs)) cbit cbit))
   2436 )
   2437 
   2438 ; (CMPS.z  [PC+],Rd        [ Rd | 1100111z | 1111 ])
   2439 (dni-c-QI
   2440  cmpscbr "cmp sign-extended constant byte to register"
   2441  "[${Rs}${inc}],$Rd"
   2442  (+ Rd MODE_AUTOINCREMENT INDIR_CMPX SIGNED_BYTE (f-source 15) sconst8)
   2443  (cris-arit6-int
   2444   sub SI (.pmacro (sz regno val) (nop)) 0
   2445   Rd (ext SI (trunc QI sconst8)) cbit cbit)
   2446 )
   2447 (dni-c-HI
   2448  cmpscwr "cmp sign-extended constant word to register"
   2449  "[${Rs}${inc}],$Rd"
   2450  (+ Rd MODE_AUTOINCREMENT INDIR_CMPX SIGNED_WORD (f-source 15) sconst16)
   2451  (cris-arit6-int
   2452   sub SI (.pmacro (sz regno val) (nop)) 0
   2453   Rd (ext SI (trunc HI sconst16)) cbit cbit)
   2454 )
   2455 
   2456 ; CMPU.z  [Rs],Rd         [ Rd | 1000110z | Rs ]
   2457 ; CMPU.z  [Rs+],Rd        [ Rd | 1100110z | Rs ]
   2458 (dni-cmt-ubw
   2459  cmpu-m "cmp zero-extended from memory to register"
   2460  "[${Rs}${inc}],$Rd"
   2461  (+ Rd INDIR_CMPX Rs)
   2462  (.pmacro
   2463   (BW)
   2464   (cris-arit6-int
   2465    sub SI (.pmacro (sz regno val) (nop)) 0
   2466    Rd ((.sym BW -zext) (cris-get-mem BW Rs)) cbit cbit))
   2467 )
   2468 
   2469 ; (CMPU.z  [PC+],Rd        [ Rd | 1100110z | 1111 ])
   2470 (dni-c-QI
   2471  cmpucbr "cmp zero-extended constant byte to register"
   2472  "[${Rs}${inc}],$Rd"
   2473  (+ Rd MODE_AUTOINCREMENT INDIR_CMPX UNSIGNED_BYTE (f-source 15) uconst8)
   2474  (cris-arit6-int
   2475   sub SI (.pmacro (sz regno val) (nop)) 0
   2476   Rd (zext SI (trunc QI uconst8)) cbit cbit)
   2477 )
   2478 (dni-c-HI
   2479  cmpucwr "cmp zero-extended constant word to register"
   2480  "[${Rs}${inc}],$Rd"
   2481  (+ Rd MODE_AUTOINCREMENT INDIR_CMPX UNSIGNED_WORD (f-source 15) uconst16)
   2482  (cris-arit6-int
   2483   sub SI (.pmacro (sz regno val) (nop)) 0
   2484   Rd (zext SI (trunc HI uconst16)) cbit cbit)
   2485 )
   2486 
   2487 ; MOVE.m  [Rs],Rd         [ Rd | 101001mm | Rs ]
   2488 ; MOVE.m  [Rs+],Rd        [ Rd | 111001mm | Rs ]
   2489 (dni-cmt-bwd
   2490  move-m "move from memory to register"
   2491  "[${Rs}${inc}],${Rd}"
   2492  (+ INDIR_MOVE_M_R Rs Rd)
   2493  (.pmacro
   2494   (BWD)
   2495   (sequence
   2496     ((SI tmp))
   2497     (set tmp (cris-get-mem BWD Rs))
   2498     (set-subreg-gr
   2499      BWD
   2500      (if SI (andif prefix-set (not inc)) (regno Rs) (regno Rd))
   2501      tmp)
   2502     (setf-move BWD tmp)))
   2503 )
   2504 
   2505 ; MOVS.z  [Rs],Rd         [ Rd | 1000011z | Rs ]
   2506 ; MOVS.z  [Rs+],Rd        [ Rd | 1100011z | Rs ]
   2507 (dni-cmt-sbw
   2508  movs-m "movs from memory to register"
   2509  "[${Rs}${inc}],${Rd}"
   2510  (+ INDIR_MOVX Rs Rd)
   2511  (.pmacro
   2512   (BW)
   2513   (sequence
   2514     ((SI tmp))
   2515     (set tmp (ext SI (cris-get-mem BW Rs)))
   2516     (if (andif prefix-set (not inc))
   2517 	(set Rs tmp)
   2518 	(set Rd tmp))
   2519     (setf-move SI tmp)))
   2520 )
   2521 
   2522 ; MOVU.z  [Rs],Rd         [ Rd | 1000010z | Rs ]
   2523 ; MOVU.z  [Rs+],Rd        [ Rd | 1100010z | Rs ]
   2524 (dni-cmt-ubw
   2525  movu-m "movu from memory to register"
   2526  "[${Rs}${inc}],${Rd}"
   2527  (+ INDIR_MOVX Rs Rd)
   2528  (.pmacro
   2529   (BW)
   2530   (sequence
   2531     ((SI tmp))
   2532     (set tmp (zext SI (cris-get-mem BW Rs)))
   2533     (if (andif prefix-set (not inc))
   2534 	(set Rs tmp)
   2535 	(set Rd tmp))
   2536     (setf-move SI tmp)))
   2537 )
   2538 
   2539 ; MOVE    Rs,Pd           [ Pd | 01100011 | Rs ]
   2540 (.splice
   2541  begin
   2542  (.unsplice
   2543   (.map
   2544    (.pmacro
   2545     (VER)
   2546     (dni
   2547      (.sym move-r-spr VER)
   2548      "Move from general register to special register"
   2549      ((MACH (.sym cris VER)))
   2550      "move ${Rs},${Pd}"
   2551      (+ RFIX_MOVE_R_S MODE_REGISTER SIZE_FIXED Rs Pd)
   2552      (sequence
   2553        ((SI tmp) (SI rno))
   2554        (set tmp Rs)
   2555        (set rno (regno Pd))
   2556        (cond
   2557 	; See reg-sr setter for most of the special-register semantics.
   2558 	; The sanity check for known read-only registers is for program
   2559 	; debug help; the real insn would be harmless and have no effect.
   2560 	; CGEN-FIXME: regno of symbolic h-sr names doesn't work here.
   2561 	((orif (orif (eq rno 0) (eq rno 1)) (orif (eq rno 4) (eq rno 8)))
   2562 	 (error "move-r-spr: trying to set a read-only special register"))
   2563 	(else (set Pd tmp)))
   2564        (reset-x-p))
   2565      (cris-reg-sr-timing)))
   2566    (cris-cpu-models)))
   2567 )
   2568 
   2569 (define-pmacro (dni-cdt-ver-attr name comment fattr syntax fmt fsem)
   2570   "Generator for each MACH, using default timing."
   2571   (.splice
   2572    begin
   2573    (.unsplice
   2574     (.map
   2575      (.pmacro (v) (dni-cdt-attr name comment (fattr v) syntax fmt (fsem v)))
   2576      (cris-cpu-models))))
   2577 )
   2578 
   2579 ; MOVE    Ps,Rd           [ Ps | 01100111 | Rd ]
   2580 ; Note that in the insn format, the Rd operand is in the Rs field (the
   2581 ; Rd field by the definition used everywhere else is the Ps position in
   2582 ; this insn).
   2583 ; It gets a little weird here because we can't get this insn into a
   2584 ; define-pmacro unless we make named pmacros for e.g. a separate attr
   2585 ; function and a semantics function: a .pmacro can't refer to the
   2586 ; parameters of the outer define-pmacro.  (The manual refers to this as
   2587 ; not implementing "lexical scoping").
   2588 (.splice
   2589  begin
   2590  (.unsplice
   2591   (.map
   2592    (.pmacro
   2593     (VER)
   2594     (dni-cdt-attr
   2595      (.sym move-spr-r VER)
   2596      "Move from special register to general register"
   2597      ((MACH (.sym cris VER)))
   2598      "move ${Ps},${Rd-sfield}"
   2599      (+ Ps RFIX_MOVE_S_R MODE_REGISTER SIZE_FIXED Rd-sfield)
   2600      (sequence
   2601        ((SI grno) (SI prno) (SI newval))
   2602        (set prno (regno Ps))
   2603        ; CGEN-FIXME: Can't use the following and then "grno" below because
   2604        ; CGEN will emit a "tmp_grno" *also* in decodev32.c:crisv32f_decode
   2605        ; (set grno (regno Rd-sfield))
   2606        (set newval Ps)
   2607        (.splice
   2608 	cond
   2609 	(.unsplice
   2610 	 (.map
   2611 	  (.pmacro
   2612 	   (r)
   2613 	   ((eq prno (.cadr2 r))
   2614 	    (set-subreg-gr (.car2 r) (regno Rd-sfield) newval)))
   2615 	  ((.sym cris-implemented-readable-specregs- VER))))
   2616 	(else (error "move-spr-r from unimplemented register")))
   2617        (reset-x-p))))
   2618    (cris-cpu-models)))
   2619 )
   2620 
   2621 ; MOVE    Ps,PC           [ Ps | 01100111 | 1111 ]
   2622 ; The move-special-register-to-pc insns are return-type instructions and
   2623 ; have to be special-cased to get the delay-slot and avoid being indicated
   2624 ; as invalid.
   2625 (dni-cdt-attr
   2626  ret-type
   2627  "ret-type"
   2628  (MACH-PC)
   2629  "ret/reti/retb"
   2630  (+ Ps MODE_REGISTER RFIX_MOVE_S_R SIZE_FIXED (f-source 15))
   2631  (sequence
   2632    ((SI retaddr))
   2633    (set retaddr Ps)
   2634    (reset-x-p)
   2635    (delay 1 (set pc retaddr)))
   2636 )
   2637 
   2638 ; MOVE    [Rs],Pd         [ Pd | 10100011 | Rs ]
   2639 ; MOVE    [Rs+],Pd        [ Pd | 11100011 | Rs ]
   2640 ; We make variants that loads constants or memory for each MACH version,
   2641 ; since each consider some subset of the "special registers" to have
   2642 ; different sizes.  FIXME: Should be able to simplify this.
   2643 (.splice
   2644  begin
   2645  (.unsplice
   2646   (.map
   2647    (.pmacro
   2648     (VER)
   2649     (dni
   2650      (.sym move-m-spr VER)
   2651      "Move from memory to special register"
   2652      ((MACH (.sym cris VER)))
   2653      "move [${Rs}${inc}],${Pd}"
   2654      (+ Pd INFIX_MOVE_M_S MODEMEMP_YES inc SIZE_FIXED Rs)
   2655      (sequence
   2656        ((SI rno) (SI newval))
   2657        (set rno (regno Pd))
   2658        (.splice
   2659 	cond
   2660 	; No sanity check for constant special register here, since the
   2661 	; memory read side-effect or post-increment may be the goal, or
   2662 	; for pre-v32 a prefix assignment side-effect.
   2663 	(.unsplice
   2664 	 (.map
   2665 	  (.pmacro
   2666 	   (r)
   2667 	   ((eq rno (.cadr2 r))
   2668 	    (set newval ((.sym (.car2 r) -ext) (cris-get-mem (.car2 r) Rs)))))
   2669 	  ((.sym cris-implemented-writable-specregs- VER))))
   2670 	(else (error "Trying to set unimplemented special register")))
   2671        (set Pd newval)
   2672        (reset-x-p))
   2673      (cris-mem-sr-timing)))
   2674    (cris-cpu-models)))
   2675 )
   2676 
   2677 (define-pmacro QI-operand sconst8)
   2678 (define-pmacro HI-operand sconst16)
   2679 (define-pmacro SI-operand const32)
   2680 
   2681 (define-pmacro
   2682   (cris-move-c-spr VER VERFN)
   2683   "Generator for loading constant into special register"
   2684   (.splice
   2685    begin
   2686    (.unsplice
   2687     (.map
   2688      (.pmacro
   2689       (srdef v)
   2690       (dni
   2691        (.sym move-c-spr v -p (.cadr2 srdef))
   2692        (.str "Move constant to special register p" (.cadr2 srdef))
   2693        ((MACH (.sym cris v)))
   2694        (.str "move ${" (.sym (.car2 srdef) -operand) "},${Pd}")
   2695        ; We use Pd in semantics without naming it in the format (which
   2696        ; would CGEN-FIXME: cause a CGEN error for some reason, likely
   2697        ; related to specifying an insn field multiple times).  This
   2698        ; currently works and is guarded with test-cases (specifically
   2699        ; wrt. the timing model) but may need to be tweaked in the future.
   2700        ; Note that using instead (ifield f-dest) causes incorrect timing
   2701        ; model to be generated; the timing model requires that Pd is set.
   2702        (+ (f-dest (.cadr2 srdef)) MODE_AUTOINCREMENT INFIX_MOVE_M_S SIZE_FIXED
   2703 	  (f-source 15) (.sym (.car2 srdef) -operand))
   2704        (sequence
   2705 	 ()
   2706 	 (set Pd (.sym (.car2 srdef) -operand)) ; (reg h-sr (.cadr2 srdef))
   2707 	 (reset-x-p))
   2708        ((.sym cris-timing-const-sr- (.car2 srdef)))))
   2709      ((.sym cris-implemented-specregs-const- VER))
   2710      (.map VERFN ((.sym cris-implemented-specregs-const- VER))))))
   2711 )
   2712 
   2713 ; CGEN-FIXME:
   2714 ; Unfortunately we can't iterate over the list of models due to the
   2715 ; problem with referring to the parameters of a surrounding pmacro from
   2716 ; within an enclosed .pmacro (perhaps related to "lexical scoping").
   2717 ; We get e.g. 'insn already defined:: (move-c-sprvn-p0)' with this:
   2718 ;(.splice
   2719 ; begin (.unsplice (.map (.pmacro (vn) (cris-move-c-spr vn (.pmacro (x) vn)))
   2720 ;			(cris-cpu-models)))
   2721 ;)
   2722 (cris-move-c-spr v0 (.pmacro (x) v0))
   2723 (cris-move-c-spr v3 (.pmacro (x) v3))
   2724 (cris-move-c-spr v8 (.pmacro (x) v8))
   2725 (cris-move-c-spr v10 (.pmacro (x) v10))
   2726 (cris-move-c-spr v32 (.pmacro (x) v32))
   2727 
   2728 ; MOVE    Ps,[Rd]         [ Ps | 10100111 | Rd ]
   2729 ; MOVE    Ps,[Rd+]        [ Ps | 11100111 | Rd ]
   2730 (.splice
   2731  begin
   2732  (.unsplice
   2733   (.map
   2734    (.pmacro
   2735     (VER)
   2736     (dni-cmwt-attr
   2737      (.sym move-spr-m VER)
   2738      "Move from special register to memory"
   2739      ((MACH (.sym cris VER)))
   2740      "move ${Ps},[${Rd-sfield}${inc}]"
   2741      (+ INFIX_MOVE_S_M SIZE_FIXED Rd-sfield Ps)
   2742      (sequence
   2743        ((SI rno))
   2744        (set rno (regno Ps))
   2745        (.splice
   2746 	cond
   2747 	(.unsplice
   2748 	 (.map
   2749 	  (.pmacro
   2750 	   (r)
   2751 	   ((eq rno (.cadr2 r))
   2752 	    (cris-set-mem (.car2 r) Rd-sfield Ps)))
   2753 	  ((.sym cris-implemented-readable-specregs- VER))))
   2754 	(else (error "write from unimplemented special register")))
   2755        (reset-x-p))))
   2756    (cris-cpu-models)))
   2757 )
   2758 
   2759 ; SBFS [Rs(+)]
   2760 ;  Instruction format:     |0 0 1 1 1 m 1 1 0 1 1 1| Dest. |
   2761 (dni-cdt-attr
   2762  sbfs
   2763  "sbfs"
   2764  ((MACH crisv10))
   2765  "sbfs [${Rd-sfield}${inc}]"
   2766  (+ (f-dest 3) INFIX_SBFS SIZE_FIXED MODEMEMP_YES inc Rd-sfield)
   2767  (error "SBFS isn't implemented")
   2768 )
   2769 
   2770 ;  MOVE    Ss,Rd            [ Ss | 11110111 | Rd ]
   2771 (dni-cdt-attr
   2772  move-ss-r
   2773  "move from support register to general register"
   2774  (MACH-V32)
   2775  "move ${Ss},${Rd-sfield}"
   2776  (+ Ss INFIX_MOVE_SS SIZE_FIXED (f-mode 3) Rd-sfield)
   2777  (sequence
   2778    ()
   2779    (set Rd-sfield Ss)
   2780    (reset-x-p))
   2781 )
   2782 
   2783 ; MOVE    Rs,Sd            [ Sd | 10110111 | Rs ]
   2784 (dni-cdt-attr
   2785  move-r-ss
   2786  "move from general register to support register"
   2787  (MACH-V32)
   2788  "move ${Rs},${Sd}"
   2789  (+ Sd INFIX_MOVE_SS SIZE_FIXED (f-mode 2) Rs)
   2790  (sequence
   2791    ()
   2792    (set Sd Rs)
   2793    (reset-x-p))
   2794 )
   2795 
   2796 ; MOVEM   Rs,[Rd]         [ Rs | 10111111 | Rd ]
   2797 ; MOVEM   Rs,[Rd+]        [ Rs | 11111111 | Rd ]
   2798 
   2799 (define-pmacro (movem-to-mem-step regn)
   2800   ; Without the SI attribute, UINT is generated, which isn't supported by
   2801   ; the sim framework.
   2802   (if (ge SI (regno Rs-dfield) regn)
   2803       (sequence
   2804 	((SI tmp))
   2805 	(set tmp (reg h-gr regn))
   2806 	(set (mem SI addr) tmp)
   2807 	(set addr (add addr 4))))
   2808 )
   2809 
   2810 (dni
   2811  movem-r-m
   2812  "movem to memory"
   2813  (MACH-PRE-V32)
   2814  "movem ${Rs-dfield},[${Rd-sfield}${inc}]"
   2815  (+ INFIX_MOVEM_R_M MODEMEMP_YES inc SIZE_FIXED Rs-dfield Rd-sfield)
   2816  (sequence
   2817    ((SI addr) (BI postinc))
   2818    ; FIXME: A copy of what's in cris-get-mem.
   2819 
   2820    ; Cache the incrementness of the operand.
   2821    (set postinc inc)
   2822 
   2823    ; CGEN-FIXME: Kludge to work around a CGEN bug: it doesn't see that
   2824    ; Rs-dfield is used as an input, causing the timing model to be wrong.
   2825    (sequence ((SI dummy)) (set dummy Rs-dfield))
   2826 
   2827    ; Get the address from somewhere.  If the insn was prefixed, it's in
   2828    ; the prefix-register.
   2829    (set addr
   2830 	(if SI (eq prefix-set 0)
   2831 	    Rd-sfield
   2832 	    prefixreg))
   2833 
   2834    (.splice
   2835     sequence ()
   2836     (.unsplice (.map movem-to-mem-step (.iota 16 15 -1))))
   2837 
   2838    ; Update the source-register for post-increments.
   2839    (if (ne postinc 0)
   2840        (set Rd-sfield
   2841 	    (if SI (eq prefix-set 0) addr prefixreg)))
   2842    (reset-x-p))
   2843    (simplecris-movem-timing)
   2844 )
   2845 
   2846 (dni
   2847  movem-r-m-v32
   2848  "movem to memory"
   2849  (MACH-V32)
   2850  "movem ${Rs-dfield},[${Rd-sfield}${inc}]"
   2851  (+ INFIX_MOVEM_R_M MODEMEMP_YES inc SIZE_FIXED Rs-dfield Rd-sfield)
   2852  (sequence
   2853    ((SI addr) (BI postinc))
   2854    ; FIXME: Mostly a copy of what's in cris-get-mem.
   2855 
   2856    ; Cache the incrementness of the operand.
   2857    (set postinc inc)
   2858 
   2859    ; CGEN-FIXME: See movem-r-m.
   2860    (sequence ((SI dummy)) (set dummy Rs-dfield))
   2861 
   2862    (set addr Rd-sfield)
   2863 
   2864    (.splice
   2865     sequence ()
   2866     (.unsplice (.map movem-to-mem-step (.iota 16))))
   2867 
   2868    ; Update the source-register for post-increments.
   2869    (if (ne postinc 0)
   2870        (set Rd-sfield addr))
   2871    (reset-x-p))
   2872  ; Unit u-mem must be specified before the u-movem-* for memory address
   2873  ; register stall count to be right.
   2874  ((crisv32 (unit u-mem) (unit u-movem-rtom) (unit u-exec-movem)
   2875 	   (unit u-mem-w)))
   2876 )
   2877 
   2878 ; MOVEM   [Rs],Rd         [ Rd | 10111011 | Rs ]
   2879 ; MOVEM   [Rs+],Rd        [ Rd | 11111011 | Rs ]
   2880 
   2881 (define-pmacro
   2882   (movem-to-reg-step regn)
   2883   ; Without the SI attribute, UINT is generated, which isn't supported by
   2884   ; the sim framework.
   2885   (if (ge SI (regno Rd) regn)
   2886       (sequence
   2887 	((SI tmp))
   2888 	(set tmp (mem SI addr))
   2889 	(set (reg h-gr regn) tmp)
   2890 	(set addr (add addr 4))))
   2891 )
   2892 
   2893 (dni
   2894  movem-m-r
   2895  "movem to register"
   2896  (MACH-PRE-V32)
   2897  "movem [${Rs}${inc}],${Rd}"
   2898  (+ Rd INFIX_MOVEM_M_R MODEMEMP_YES inc SIZE_FIXED Rs)
   2899  (sequence
   2900    ((SI addr) (BI postinc))
   2901    ; FIXME: Mostly a copy of what's in cris-get-mem.
   2902 
   2903    ; Cache the incrementness of the operand.
   2904    (set postinc inc)
   2905 
   2906    ; Get the address from somewhere.  If the insn was prefixed, it's in
   2907    ; the prefix-register.
   2908    (set addr
   2909 	(if SI (eq prefix-set 0)
   2910 	    Rs
   2911 	    prefixreg))
   2912 
   2913    ; CGEN-FIXME: See movem-r-m.
   2914    (sequence ((SI dummy)) (set dummy Rd))
   2915 
   2916    (.splice
   2917     sequence ()
   2918     ; The first movem step is left out because it can't happen; it's for
   2919     ; PC destination.  See the pattern below.
   2920     (.unsplice (.map movem-to-reg-step (.iota 15 14 -1))))
   2921 
   2922    ; Update the source-register for post-increments.
   2923    ; FIXME: No postinc-prefixed for v0 IIRC.
   2924    (if (ne postinc 0)
   2925        (set Rs (if SI (eq prefix-set 0) addr prefixreg)))
   2926    (reset-x-p))
   2927    (simplecris-movem-timing)
   2928 )
   2929 
   2930 ; (MOVEM   [Rs],PC         [ 1111 | 10111011 | Rs ])
   2931 ; (MOVEM   [Rs+],PC        [ 1111 | 11111011 | Rs ])
   2932 ; We have to special-case it for PC destination; used in longjump.
   2933 ; We shouldn't *have* to special-case it; the main reason is (FIXME:)
   2934 ; misgeneration of the simulator when the PC case is folded into the
   2935 ; generic PRE-V32 movem; possibly related to then being a COND-CTI rather
   2936 ; than an UNCOND-CTI.
   2937 (dni-cmt-attr
   2938  movem-m-pc
   2939  "movem to register, ending with PC"
   2940  (MACH-PRE-V32)
   2941  "movem [${Rs}${inc}],${Rd}"
   2942  (+ (f-dest 15) INFIX_MOVEM_M_R SIZE_FIXED Rs)
   2943  (sequence
   2944    ((SI addr) (BI postinc))
   2945    ; FIXME: Mostly a copy of what's in cris-get-mem.
   2946 
   2947    ; Cache the incrementness of the operand.
   2948    (set postinc inc)
   2949 
   2950    ; Get the address from somewhere.  If the insn was prefixed, it's in
   2951    ; the prefix-register.
   2952    (set addr
   2953 	(if SI (eq prefix-set 0)
   2954 	    Rs
   2955 	    prefixreg))
   2956 
   2957    ; FIXME: Add kludge here too *and* a test-case.
   2958 
   2959    (.splice
   2960     sequence ()
   2961     ; The first movem step is for PC destination, used in longjmp.
   2962     (set pc (mem SI addr))
   2963     (set addr (add addr 4))
   2964     (.unsplice
   2965      (.map
   2966       (.pmacro
   2967        (regn)
   2968        (sequence
   2969 	 ((SI tmp))
   2970 	 (set tmp (mem SI addr))
   2971 	 (set (reg h-gr regn) tmp)
   2972 	 (set addr (add addr 4))))
   2973       (.iota 15 14 -1))))
   2974 
   2975    ; Update the source-register for post-increments.
   2976    ; FIXME: No postinc-prefixed for v0.
   2977    (if (ne postinc 0)
   2978        (set Rs (if SI (eq prefix-set 0) addr prefixreg)))
   2979    (reset-x-p))
   2980 )
   2981 
   2982 (dni
   2983  movem-m-r-v32
   2984  "movem to register"
   2985  (MACH-V32)
   2986  "movem [${Rs}${inc}],${Rd}"
   2987  (+ INFIX_MOVEM_M_R MODEMEMP_YES inc SIZE_FIXED Rs Rd)
   2988  (sequence
   2989    ((SI addr) (BI postinc))
   2990    ; FIXME: A copy of what's in cris-get-mem
   2991 
   2992    ; Cache the incrementness of the operand.
   2993    (set postinc inc)
   2994 
   2995    ; Get the address from somewhere.
   2996    (set addr Rs)
   2997 
   2998    ; CGEN-FIXME: See movem-r-m.
   2999    (sequence ((SI dummy)) (set dummy Rd))
   3000 
   3001    (.splice
   3002     sequence ()
   3003     (.unsplice (.map movem-to-reg-step (.iota 16))))
   3004 
   3005    ; Update the source-register for post-increments.
   3006    ; FIXME: No postinc-prefixed for v0 IIRC.
   3007    (if (ne postinc 0)
   3008        (set Rs addr))
   3009    (reset-x-p))
   3010  ; u-mem must be specified before the u-movem-* for memory source
   3011  ; register stall count to be right.
   3012  ((crisv32 (unit u-mem) (unit u-mem-r) (unit u-movem-mtor)
   3013 	   (unit u-exec-movem)))
   3014 )
   3015 
   3016 ; ADD.m   Rs,Rd           [ Rd | 011000mm | Rs ]
   3017 (dni-cdt-bwd
   3018  add "add from register to register"
   3019  "$Rs,$Rd"
   3020  (+ Rd MODE_REGISTER R_ADD Rs)
   3021  (.pmacro (BWD) (cris-arit add BWD Rd Rs))
   3022 )
   3023 
   3024 ; ADD.m   [Rs],Rd         [ Rd | 101000mm | Rs ]
   3025 ; ADD.m   [Rs+],Rd        [ Rd | 111000mm | Rs ]
   3026 (dni-cmt-bwd
   3027  add-m "add from memory to register"
   3028  "[${Rs}${inc}],${Rd}"
   3029  (+ INDIR_ADD Rs Rd)
   3030  (.pmacro (BWD) (cris-arit-3op add BWD Rd (cris-get-mem BWD Rs) Rs))
   3031 )
   3032 ; (ADD.m   [PC+],Rd        [ Rd | 111000mm | 1111 ])
   3033 (dni-c-QI
   3034  addcbr "add constant byte to register"
   3035  "add.b ${sconst8}],${Rd}"
   3036  (+ Rd MODE_AUTOINCREMENT INDIR_ADD SIZE_BYTE (f-source 15) sconst8)
   3037  (cris-arit add QI Rd sconst8)
   3038 )
   3039 
   3040 (dni-c-HI
   3041  addcwr "add constant word to register"
   3042  "add.w ${sconst16}],${Rd}"
   3043  (+ Rd MODE_AUTOINCREMENT INDIR_ADD SIZE_WORD (f-source 15) sconst16)
   3044  (cris-arit add HI Rd sconst16)
   3045 )
   3046 
   3047 (dni-c-SI
   3048  addcdr "add constant dword to register"
   3049  "add.d ${const32}],${Rd}"
   3050  (+ Rd MODE_AUTOINCREMENT INDIR_ADD SIZE_DWORD (f-source 15) const32)
   3051  (cris-arit add SI Rd const32)
   3052 )
   3053 
   3054 ; (ADD.D   [PC+],PC        [ 1111 | 11100010 | 1111 ])
   3055 ; This insn is used for DSO-local jumps in PIC code.
   3056 (dni
   3057  addcpc "Relative jump by adding constant to PC"
   3058  (MACH-PC)
   3059  "add.d ${sconst32},PC"
   3060  (+ (f-dest 15) MODE_AUTOINCREMENT INDIR_ADD SIZE_DWORD (f-source 15) const32)
   3061  (sequence
   3062    ((SI newpc) (SI oldpc) (SI offs))
   3063    (set offs const32)
   3064    (set oldpc (add SI pc 6))
   3065    (set newpc (add SI oldpc offs))
   3066    (set pc newpc)
   3067    (setf-arit SI add oldpc offs newpc cbit))
   3068  (simplecris-common-timing ((unit u-const32) (unit u-stall) (unit u-exec)))
   3069 )
   3070 
   3071 ; ADDS.z  Rs,Rd           [ Rd | 0100001z | Rs ]
   3072 (dni-cdt-sbw
   3073  adds "add sign-extended from register to register"
   3074  "$Rs,$Rd"
   3075  (+ Rd MODE_REGISTER R_ADDX Rs)
   3076  (.pmacro (BW) (cris-arit add SI Rd ((.sym BW -ext) (trunc BW Rs))))
   3077 )
   3078 
   3079 ; ADDS.z  [Rs],Rd         [ Rd | 1000001z | Rs ]
   3080 ; ADDS.z  [Rs+],Rd        [ Rd | 1100001z | Rs ]
   3081 (dni-cmt-sbw
   3082  adds-m "add sign-extended from memory to register"
   3083  "[${Rs}${inc}],$Rd"
   3084  (+ Rd INDIR_ADDX Rs)
   3085  (.pmacro (BW) (cris-arit-3op add SI Rd ((.sym BW -ext) (cris-get-mem BW Rs)) Rs))
   3086 )
   3087 
   3088 ; (ADDS.z  [PC+],Rd        [ Rd | 1100001z | 1111 ])
   3089 (dni-c-QI
   3090  addscbr "add sign-extended constant byte to register"
   3091  "[${Rs}${inc}],$Rd"
   3092  (+ Rd MODE_AUTOINCREMENT INDIR_ADDX SIGNED_BYTE (f-source 15) sconst8)
   3093  (cris-arit add SI Rd (ext SI (trunc QI sconst8)))
   3094 )
   3095 (dni-c-HI
   3096  addscwr "add sign-extended constant word to register"
   3097  "[${Rs}${inc}],$Rd"
   3098  (+ Rd MODE_AUTOINCREMENT INDIR_ADDX SIGNED_WORD (f-source 15) sconst16)
   3099  (cris-arit add SI Rd (ext SI (trunc HI sconst16)))
   3100 )
   3101 
   3102 ; (ADDS.w  [],PC         [ 1111 | 10000011 | 1111 ])
   3103 ; For a PC destination, we support only the two-operand case
   3104 ; (dest == src), which is used in switch/case statements.
   3105 ; FIXME: Should implement ADD.D [PC],PC and ADDS.B [PC],PC for use if/when
   3106 ; implementing CASE_VECTOR_SHORTEN_MODE.
   3107 (dni
   3108  addspcpc "add sign-extended prefixed arg to PC"
   3109  (MACH-PC)
   3110  "adds.w [PC],PC"
   3111  (+ (f-dest 15) MODE_INDIRECT INDIR_ADDX SIGNED_WORD (f-source 15))
   3112  (sequence
   3113    ((SI newpc) (SI oldpc) (HI offs))
   3114    (if (not prefix-set)
   3115        (error "Unexpected adds.w [PC],PC without prefix"))
   3116    ; We don't use cris-get-mem but instead special-case this one, since we
   3117    ; have most instruction fields fixed where cris-get-mem expects
   3118    ; field-parametrization by certain names.
   3119    (set offs (mem HI prefixreg))
   3120    (set oldpc (add SI pc 2))
   3121    (set newpc (add SI oldpc offs))
   3122    (set pc newpc)
   3123    (setf-arit SI add oldpc (ext SI offs) newpc cbit))
   3124  (simplecris-common-timing ((unit u-mem) (unit u-stall) (unit u-exec)))
   3125 )
   3126 
   3127 ; ADDU.z  Rs,Rd           [ Rd | 0100000z | Rs ]
   3128 (dni-cdt-ubw
   3129  addu "add zero-extended from register to register"
   3130  "$Rs,$Rd"
   3131  (+ Rd MODE_REGISTER R_ADDX Rs)
   3132  (.pmacro (BW) (cris-arit add SI Rd ((.sym BW -zext) (trunc BW Rs))))
   3133 )
   3134 
   3135 ; ADDU.z  [Rs],Rd         [ Rd | 1000000z | Rs ]
   3136 ; ADDU.z  [Rs+],Rd        [ Rd | 1100000z | Rs ]
   3137 (dni-cmt-ubw
   3138  addu-m "add zero-extended from memory to register"
   3139  "[${Rs}${inc}],$Rd"
   3140  (+ Rd INDIR_ADDX Rs)
   3141  (.pmacro (BW)
   3142 	  (cris-arit-3op add SI Rd ((.sym BW -zext) (cris-get-mem BW Rs)) Rs))
   3143 )
   3144 
   3145 ; (ADDU.z  [PC+],Rd        [ Rd | 1100000z | 1111 ])
   3146 (dni-c-QI
   3147  adducbr "add zero-extended constant byte to register"
   3148  "[${Rs}${inc}],$Rd"
   3149  (+ Rd MODE_AUTOINCREMENT INDIR_ADDX UNSIGNED_BYTE (f-source 15) sconst8)
   3150  (cris-arit add SI Rd (zext SI (trunc QI sconst8)))
   3151 )
   3152 (dni-c-HI
   3153  adducwr "add zero-extended constant word to register"
   3154  "[${Rs}${inc}],$Rd"
   3155  (+ Rd MODE_AUTOINCREMENT INDIR_ADDX UNSIGNED_WORD (f-source 15) sconst16)
   3156  (cris-arit add SI Rd (zext SI (trunc HI sconst16)))
   3157 )
   3158 
   3159 ; SUB.m   Rs,Rd           [ Rd | 011010mm | Rs ]
   3160 (dni-cdt-bwd
   3161  sub "subtract from register to register"
   3162  "$Rs,$Rd"
   3163  (+ Rd MODE_REGISTER R_SUB Rs)
   3164  (.pmacro (BWD) (cris-arit sub BWD Rd Rs))
   3165 )
   3166 
   3167 ; SUB.m   [Rs],Rd         [ Rd | 101010mm | Rs ]
   3168 ; SUB.m   [Rs+],Rd        [ Rd | 111010mm | Rs ]
   3169 (dni-cmt-bwd
   3170  sub-m "subtract from memory to register"
   3171  "[${Rs}${inc}],${Rd}"
   3172  (+ INDIR_SUB Rs Rd)
   3173  (.pmacro (BWD) (cris-arit-3op sub BWD Rd (cris-get-mem BWD Rs) Rs))
   3174 )
   3175 
   3176 ; (SUB.m   [PC+],Rd        [ Rd | 111010mm | 1111 ]
   3177 (dni-c-QI
   3178  subcbr "subtract constant byte from register"
   3179  "sub.b ${sconst8}],${Rd}"
   3180  (+ Rd MODE_AUTOINCREMENT INDIR_SUB SIZE_BYTE (f-source 15) sconst8)
   3181  (cris-arit sub QI Rd sconst8)
   3182 )
   3183 
   3184 (dni-c-HI
   3185  subcwr "subtract constant word from register"
   3186  "sub.w ${sconst16}],${Rd}"
   3187  (+ Rd MODE_AUTOINCREMENT INDIR_SUB SIZE_WORD (f-source 15) sconst16)
   3188  (cris-arit sub HI Rd sconst16)
   3189 )
   3190 
   3191 (dni-c-SI
   3192  subcdr "subtract constant dword from register"
   3193  "sub.d ${const32}],${Rd}"
   3194  (+ Rd MODE_AUTOINCREMENT INDIR_SUB SIZE_DWORD (f-source 15) const32)
   3195  (cris-arit sub SI Rd const32)
   3196 )
   3197 
   3198 ; SUBS.z  Rs,Rd           [ Rd | 0100101z | Rs ]
   3199 (dni-cdt-sbw
   3200  subs "sub sign-extended from register to register"
   3201  "$Rs,$Rd"
   3202  (+ Rd MODE_REGISTER R_SUBX Rs)
   3203  (.pmacro (BW) (cris-arit sub SI Rd ((.sym BW -ext) (trunc BW Rs))))
   3204 )
   3205 
   3206 ; SUBS.z  [Rs],Rd         [ Rd | 1000101z | Rs ]
   3207 ; SUBS.z  [Rs+],Rd        [ Rd | 1100101z | Rs ]
   3208 (dni-cmt-sbw
   3209  subs-m "sub sign-extended from memory to register"
   3210  "[${Rs}${inc}],$Rd"
   3211  (+ Rd INDIR_SUBX Rs)
   3212  (.pmacro (BW)
   3213 	  (cris-arit-3op sub SI Rd ((.sym BW -ext) (cris-get-mem BW Rs)) Rs))
   3214 )
   3215 
   3216 ; (SUBS.z  [PC+],Rd        [ Rd | 1100101z | 1111 ])
   3217 (dni-c-QI
   3218  subscbr "sub sign-extended constant byte to register"
   3219  "[${Rs}${inc}],$Rd"
   3220  (+ Rd MODE_AUTOINCREMENT INDIR_SUBX SIGNED_BYTE (f-source 15) sconst8)
   3221  (cris-arit sub SI Rd (ext SI (trunc QI sconst8)))
   3222 )
   3223 (dni-c-HI
   3224  subscwr "sub sign-extended constant word to register"
   3225  "[${Rs}${inc}],$Rd"
   3226  (+ Rd MODE_AUTOINCREMENT INDIR_SUBX SIGNED_WORD (f-source 15) sconst16)
   3227  (cris-arit sub SI Rd (ext SI (trunc HI sconst16)))
   3228 )
   3229 
   3230 ; SUBU.z  Rs,Rd           [ Rd | 0100100z | Rs ]
   3231 (dni-cdt-ubw
   3232  subu "sub zero-extended from register to register"
   3233  "$Rs,$Rd"
   3234  (+ Rd MODE_REGISTER R_SUBX Rs)
   3235  (.pmacro (BW) (cris-arit sub SI Rd ((.sym BW -zext) (trunc BW Rs))))
   3236 )
   3237 
   3238 ; SUBU.z  [Rs],Rd         [ Rd | 1000100z | Rs ]
   3239 ; SUBU.z  [Rs+],Rd        [ Rd | 1100100z | Rs ]
   3240 (dni-cmt-ubw
   3241  subu-m "sub zero-extended from memory to register"
   3242  "[${Rs}${inc}],$Rd"
   3243  (+ Rd INDIR_SUBX Rs)
   3244  (.pmacro (BW)
   3245 	  (cris-arit-3op sub SI Rd ((.sym BW -zext) (cris-get-mem BW Rs)) Rs))
   3246 )
   3247 
   3248 ; (SUBU.z  [PC+],Rd        [ Rd | 1100100z | 1111 ])
   3249 (dni-c-QI
   3250  subucbr "sub zero-extended constant byte to register"
   3251  "[${Rs}${inc}],$Rd"
   3252  (+ Rd MODE_AUTOINCREMENT INDIR_SUBX UNSIGNED_BYTE (f-source 15) sconst8)
   3253  (cris-arit sub SI Rd (zext SI (trunc QI sconst8)))
   3254 )
   3255 (dni-c-HI
   3256  subucwr "sub zero-extended constant word to register"
   3257  "[${Rs}${inc}],$Rd"
   3258  (+ Rd MODE_AUTOINCREMENT INDIR_SUBX UNSIGNED_WORD (f-source 15) sconst16)
   3259  (cris-arit sub SI Rd (zext SI (trunc HI sconst16)))
   3260 )
   3261 
   3262 ; ADDC    Rs,Rd           [ Rd | 01010111 | Rs ]
   3263 (dni-cdt-attr
   3264  addc-r "addc from register to register"
   3265  (MACH-V32)
   3266  "addc $Rs,$Rd"
   3267  (+ Rd MODE_REGISTER RFIX_ADDC SIZE_FIXED Rs)
   3268  ; Since this is equivalent to "ax" plus "add.d Rs,Rd", we'll just do
   3269  ; that, semantically.
   3270  (sequence
   3271    ()
   3272    (set-quiet xbit 1)
   3273    (cris-arit add SI Rd Rs))
   3274 )
   3275 
   3276 ; ADDC    [Rs],Rd         [ Rd | 10011010 | Rs ]
   3277 ; ADDC    [Rs+],Rd        [ Rd | 11011010 | Rs ]
   3278 (dni-cmt-attr
   3279  addc-m "addc from memory to register"
   3280  (MACH-V32)
   3281  "addc [${Rs}${inc}],${Rd}"
   3282  (+ Rd INDIR_ADDC SIZE_DWORD Rs)
   3283  (sequence
   3284    ()
   3285    (set-quiet xbit 1)
   3286    (cris-arit add SI Rd (cris-get-mem SI Rs)))
   3287 )
   3288 
   3289 ; (ADDC    [Rs+],Rd        [ Rd | 11011010 | 1111 ])
   3290 (dni-c-SI-attr
   3291  addc-c "addc constant to register"
   3292  (MACH-V32)
   3293  "addc ${const32},${Rd}"
   3294  (+ Rd MODE_AUTOINCREMENT INDIR_ADDC SIZE_DWORD (f-source 15) const32)
   3295  (sequence
   3296    ()
   3297    (set-quiet xbit 1)
   3298    (cris-arit add SI Rd const32))
   3299 )
   3300 
   3301 ; LAPC   [PC+],Rd         [ Rd | 11010111 1111 ]
   3302 (dni-c-SI-attr
   3303  lapc-d "lapc.d"
   3304  (MACH-V32)
   3305  "lapc.d ${const32-pcrel},${Rd}"
   3306  (+ Rd MODE_AUTOINCREMENT INFIX_LAPC SIZE_FIXED (f-source 15) const32-pcrel)
   3307  (sequence
   3308    ()
   3309    (set Rd const32-pcrel)
   3310    (reset-x-p))
   3311 )
   3312 
   3313 ; LAPCQ  qo,Rd            [ Rd | 10010111 | qo ]
   3314 (dni-cdt-attr
   3315  lapcq "lapcq"
   3316  (MACH-V32)
   3317  "lapcq ${qo},${Rd}"
   3318  (+ Rd MODE_INDIRECT INFIX_LAPC SIZE_FIXED qo)
   3319  (sequence
   3320    ()
   3321    (set Rd qo)
   3322    (reset-x-p))
   3323 )
   3324 
   3325 ; ADDI    Rs.m,Rd         [ Rs | 010100mm | Rd ]
   3326 (dni-cdt-bwd
   3327  addi "addi"
   3328  "${Rs-dfield}.m,${Rd-sfield}"
   3329  (+ Rd-sfield MODE_REGISTER R_ADDI Rs-dfield)
   3330  (.pmacro
   3331   (BWD)
   3332   (sequence
   3333     ()
   3334     (set Rd-sfield (add SI Rd-sfield (mul Rs-dfield (.sym BWD -size))))
   3335     (reset-x-p)))
   3336 )
   3337 
   3338 ;  NEG.m   Rs,Rd           [ Rd | 010110mm | Rs ]
   3339 (dni-cdt-bwd
   3340  neg "neg.m Rs,Rd"
   3341  "$Rs,$Rd"
   3342  (+ Rd MODE_REGISTER R_NEG Rs)
   3343  (.pmacro (BWD) (cris-arit3 sub BWD Rd 0 Rs))
   3344 )
   3345 
   3346 ; TEST.m  [Rs]            [ 0000101110mm | Rs ]
   3347 ; TEST.m  [Rs+]           [ 0000111110mm | Rs ]
   3348 (dni-cmt-bwd
   3349  test-m "test.m [Rs(+)]"
   3350  "[${Rs}${inc}]"
   3351  (+ (f-dest 0) INDIR_TEST Rs)
   3352  (.pmacro
   3353   (BWD)
   3354   (sequence
   3355     ((BWD tmpd))
   3356     (set tmpd (cris-get-mem BWD Rs))
   3357     ; This is supposed to be the same result as for cmpq 0,X, hence same code.
   3358     (cris-arit6-int
   3359      sub BWD (.pmacro (sz regno val) (nop)) 0 tmpd 0 cbit cbit)))
   3360 )
   3361 
   3362 ; MOVE.m  Rs,[Rd]         [ Rs | 101111mm | Rd ]
   3363 ; MOVE.m  Rs,[Rd+]        [ Rs | 111111mm | Rd ]
   3364 
   3365 (dni-cmwt-bwd
   3366  move-r-m "move.m R,[]"
   3367  "${Rs-dfield},[${Rd-sfield}${inc}]"
   3368  (+ Rs-dfield INDIR_MOVE_R_M Rd-sfield)
   3369  (.pmacro
   3370   (BWD)
   3371   (sequence
   3372     ((BWD tmpd))
   3373     (set tmpd Rs-dfield)
   3374     (cris-set-mem BWD Rd-sfield tmpd)
   3375     (reset-x-p)))
   3376 )
   3377 
   3378 ; MULS.m  Rs,Rd           [ Rd | 110100mm | Rs ]
   3379 (dni-bwd-attr
   3380  muls "muls.m Rs,Rd"
   3381  ((MACH crisv10,crisv32))
   3382  "$Rs,$Rd"
   3383  (+ Rd MODE_MULS INDIR_MUL Rs)
   3384  (.pmacro
   3385   (BWD)
   3386   (sequence
   3387     ((DI src1) (DI src2) (DI tmpr))
   3388     (set src1 (ext DI (trunc BWD Rs)))
   3389     (set src2 (ext DI (trunc BWD Rd)))
   3390     (set tmpr (mul src1 src2))
   3391     (set Rd (trunc SI tmpr))
   3392     (set mof (trunc SI (srl tmpr 32)))
   3393     (setf-arit DI muls src1 src2 tmpr cbit)))
   3394  ((crisv10 (unit u-multiply) (unit u-exec))
   3395   (crisv32 (unit u-multiply) (unit u-exec)))
   3396 )
   3397 
   3398 ; MULU.m  Rs,Rd           [ Rd | 100100mm | Rs ]
   3399 (dni-bwd-attr
   3400  mulu "mulu.m Rs,Rd"
   3401  ((MACH crisv10,crisv32))
   3402  "$Rs,$Rd"
   3403  (+ Rd MODE_MULU INDIR_MUL Rs)
   3404  (.pmacro
   3405   (BWD)
   3406   (sequence
   3407     ((DI src1) (DI src2) (DI tmpr))
   3408     (set src1 (zext DI (trunc BWD Rs)))
   3409     (set src2 (zext DI (trunc BWD Rd)))
   3410     (set tmpr (mul src1 src2))
   3411     (set Rd (trunc SI tmpr))
   3412     (set mof (trunc SI (srl tmpr 32)))
   3413     (setf-arit DI mulu src1 src2 tmpr cbit)))
   3414  ((crisv10 (unit u-multiply) (unit u-exec))
   3415   (crisv32 (unit u-multiply) (unit u-exec)))
   3416 )
   3417 
   3418 ; MCP     Ps,Rd           [ Ps | 01111111 | Rd ]
   3419 (dni-cdt-attr
   3420  mcp "Multiply Carry Propagation"
   3421  (MACH-V32)
   3422  "mcp $Ps,$Rd"
   3423  (+ Ps MODE_REGISTER RFIX_MCP SIZE_FIXED Rd-sfield)
   3424  (sequence
   3425    ()
   3426    (set-quiet xbit 1)
   3427    (set-quiet zbit 1)
   3428    (cris-arit5 add SI Rd-sfield Rd-sfield Ps rbit rbit))
   3429 )
   3430 
   3431 ; MSTEP   Rs,Rd           [ Rd | 01111111 | Rs ]
   3432 (dni-cdt-attr
   3433  mstep "Multiply step"
   3434  (MACH-PRE-V32)
   3435  "mstep $Rs,$Rd"
   3436  (+ Rd MODE_REGISTER RFIX_MSTEP SIZE_FIXED Rs)
   3437  (sequence
   3438    ((SI tmpd) (SI tmps))
   3439    (set tmps Rs)
   3440    (set tmpd (add (sll Rd 1) (if SI nbit tmps 0)))
   3441    (set Rd tmpd)
   3442    (setf-move SI tmpd))
   3443 )
   3444 
   3445 ; DSTEP   Rs,Rd           [ Rd | 01101111 | Rs ]
   3446 (dni-cdt
   3447  dstep "Division step"
   3448  "dstep $Rs,$Rd"
   3449  (+ Rd MODE_REGISTER RFIX_DSTEP SIZE_FIXED Rs)
   3450  (sequence
   3451    ((SI tmp) (SI tmps) (SI tmpd))
   3452    (set tmps Rs)
   3453    (set tmp (sll Rd 1))
   3454    (set tmpd (if SI (geu tmp tmps) (sub tmp tmps) tmp))
   3455    (set Rd tmpd)
   3456    (setf-move SI tmpd))
   3457 )
   3458 
   3459 ;  ABS     Rs,Rd           [ Rd | 01101011 | Rs ]
   3460 (dni-cdt
   3461  abs "Absolut Instruction"
   3462  "abs $Rs,$Rd"
   3463  (+ Rd MODE_REGISTER RFIX_ABS SIZE_FIXED Rs)
   3464  (sequence
   3465    ((SI tmpd))
   3466    (set tmpd (abs Rs))
   3467    (set Rd tmpd)
   3468    (setf-move SI tmpd))
   3469 )
   3470 
   3471 ; AND.m   Rs,Rd           [ Rd | 011100mm | Rs ]
   3472 (dni-cdt-bwd
   3473  and "And from register to register"
   3474  "$Rs,$Rd"
   3475  (+ Rd MODE_REGISTER R_AND Rs)
   3476  (.pmacro
   3477   (BWD)
   3478   (sequence
   3479     ((BWD tmpd))
   3480     (set tmpd (and BWD Rd Rs))
   3481     (set-subreg-gr BWD (regno Rd) tmpd)
   3482     (setf-move BWD tmpd)))
   3483 )
   3484 
   3485 ; AND.m   [Rs],Rd         [ Rd | 101100mm | Rs ]
   3486 ; AND.m   [Rs+],Rd        [ Rd | 111100mm | Rs ]
   3487 (dni-cmt-bwd
   3488  and-m "And from memory to register"
   3489  "[${Rs}${inc}],${Rd}"
   3490  (+ INDIR_AND Rs Rd)
   3491  (.pmacro
   3492   (BWD)
   3493   (sequence
   3494     ((BWD tmpd))
   3495     (set tmpd (and BWD Rd (cris-get-mem BWD Rs)))
   3496     (set-subreg-gr
   3497      BWD
   3498      (if SI (andif prefix-set (not inc)) (regno Rs) (regno Rd))
   3499      tmpd)
   3500     (setf-move BWD tmpd)))
   3501 )
   3502 
   3503 ; (AND.m   [PC+],Rd        [ Rd | 111100mm | 1111 ])
   3504 (dni-c-QI
   3505  andcbr "And constant byte to register"
   3506  "and.b ${sconst8}],${Rd}"
   3507  (+ Rd MODE_AUTOINCREMENT INDIR_AND SIZE_BYTE (f-source 15) sconst8)
   3508  (sequence
   3509    ((QI tmpd))
   3510    (set tmpd (and QI Rd sconst8))
   3511    (set-subreg-gr QI (regno Rd) tmpd)
   3512    (setf-move QI tmpd))
   3513 )
   3514 
   3515 (dni-c-HI
   3516  andcwr "And constant word to register"
   3517  "and.w ${sconst16}],${Rd}"
   3518  (+ Rd MODE_AUTOINCREMENT INDIR_AND SIZE_WORD (f-source 15) sconst16)
   3519  (sequence
   3520    ((HI tmpd))
   3521    (set tmpd (and HI Rd sconst16))
   3522    (set-subreg-gr HI (regno Rd) tmpd)
   3523    (setf-move HI tmpd))
   3524 )
   3525 
   3526 (dni-c-SI
   3527  andcdr "And constant dword to register"
   3528  "and.d ${const32}],${Rd}"
   3529  (+ Rd MODE_AUTOINCREMENT INDIR_AND SIZE_DWORD (f-source 15) const32)
   3530  (sequence
   3531    ((SI tmpd))
   3532    (set tmpd (and SI Rd const32))
   3533    (set-subreg-gr SI (regno Rd) tmpd)
   3534    (setf-move SI tmpd))
   3535 )
   3536 
   3537 ; ANDQ    i,Rd            [ Rd | 001100 | i ]
   3538 (dni-cdt
   3539  andq "And quick-immediate to register"
   3540  "andq $i,$Rd"
   3541  (+ Rd MODE_QUICK_IMMEDIATE Q_ANDQ i)
   3542  (sequence
   3543    ((SI tmpd))
   3544    (set tmpd (and SI Rd i))
   3545    (set-subreg-gr SI (regno Rd) tmpd)
   3546    (setf-move SI tmpd))
   3547 )
   3548 
   3549 ; OR.m    Rs,Rd           [ Rd | 011101mm | Rs ]
   3550 (dni-cdt-bwd
   3551  orr "Or from register to register"
   3552  "$Rs,$Rd"
   3553  (+ Rd MODE_REGISTER R_OR Rs)
   3554  (.pmacro
   3555   (BWD)
   3556   (sequence
   3557     ((BWD tmpd))
   3558     (set tmpd (or BWD Rd Rs))
   3559     (set-subreg-gr BWD (regno Rd) tmpd)
   3560     (setf-move BWD tmpd)))
   3561 )
   3562 
   3563 ; OR.m    [Rs],Rd         [ Rd | 101101mm | Rs ]
   3564 ; OR.m    [Rs+],Rd        [ Rd | 111101mm | Rs ]
   3565 (dni-cmt-bwd
   3566  or-m "Or from memory to register"
   3567  "[${Rs}${inc}],${Rd}"
   3568  (+ INDIR_OR Rs Rd)
   3569  (.pmacro
   3570   (BWD)
   3571   (sequence
   3572     ((BWD tmpd))
   3573     (set tmpd (or BWD Rd (cris-get-mem BWD Rs)))
   3574     (set-subreg-gr
   3575      BWD
   3576      (if SI (andif prefix-set (not inc)) (regno Rs) (regno Rd))
   3577      tmpd)
   3578     (setf-move BWD tmpd)))
   3579 )
   3580 
   3581 ; (OR.m    [PC+],Rd        [ Rd | 111101mm | 1111 ])
   3582 (dni-c-QI
   3583  orcbr "Or constant byte to register"
   3584  "or.b ${sconst8}],${Rd}"
   3585  (+ Rd MODE_AUTOINCREMENT INDIR_OR SIZE_BYTE (f-source 15) sconst8)
   3586  (sequence
   3587    ((QI tmpd))
   3588    (set tmpd (or QI Rd sconst8))
   3589    (set-subreg-gr QI (regno Rd) tmpd)
   3590    (setf-move QI tmpd))
   3591 )
   3592 
   3593 (dni-c-HI
   3594  orcwr "Or constant word to register"
   3595  "or.w ${sconst16}],${Rd}"
   3596  (+ Rd MODE_AUTOINCREMENT INDIR_OR SIZE_WORD (f-source 15) sconst16)
   3597  (sequence
   3598    ((HI tmpd))
   3599    (set tmpd (or HI Rd sconst16))
   3600    (set-subreg-gr HI (regno Rd) tmpd)
   3601    (setf-move HI tmpd))
   3602 )
   3603 
   3604 (dni-c-SI
   3605  orcdr "Or constant dword to register"
   3606  "or.d ${const32}],${Rd}"
   3607  (+ Rd MODE_AUTOINCREMENT INDIR_OR SIZE_DWORD (f-source 15) const32)
   3608  (sequence
   3609    ((SI tmpd))
   3610    (set tmpd (or SI Rd const32))
   3611    (set-subreg-gr SI (regno Rd) tmpd)
   3612    (setf-move SI tmpd))
   3613 )
   3614 
   3615 ; ORQ     i,Rd            [ Rd | 001101 | i ]
   3616 (dni-cdt
   3617  orq "Or quick-immediate to register"
   3618  "orq $i,$Rd"
   3619  (+ Rd MODE_QUICK_IMMEDIATE Q_ORQ i)
   3620  (sequence
   3621    ((SI tmpd))
   3622    (set tmpd (or SI Rd i))
   3623    (set-subreg-gr SI (regno Rd) tmpd)
   3624    (setf-move SI tmpd))
   3625 )
   3626 
   3627 ; XOR     Rs,Rd           [ Rd | 01111011 | Rs ]
   3628 (dni-cdt
   3629  xor "Xor from register to register"
   3630  "xor $Rs,$Rd"
   3631  (+ Rd MODE_REGISTER RFIX_XOR SIZE_FIXED Rs)
   3632  (sequence
   3633    ((SI tmpd))
   3634    (set tmpd (xor SI Rd Rs))
   3635    (set Rd tmpd)
   3636    (setf-move SI tmpd))
   3637 )
   3638 
   3639 (define-pmacro (swap-r x)
   3640   "Perform bit-wise swap within each byte"
   3641   (sequence
   3642     SI
   3643     ((SI tmpr))
   3644     (set tmpr x)
   3645     (or (sll (and tmpr #x1010101) 7)
   3646 	(or (sll (and tmpr #x2020202) 5)
   3647 	    (or (sll (and tmpr #x4040404) 3)
   3648 		(or (sll (and tmpr #x8080808) 1)
   3649 		    (or (srl (and tmpr #x10101010) 1)
   3650 			(or (srl (and tmpr #x20202020) 3)
   3651 			    (or (srl (and tmpr #x40404040) 5)
   3652 				(srl (and tmpr #x80808080) 7)))))))))
   3653 )
   3654 
   3655 (define-pmacro (swap-b x)
   3656   "Perform byte-wise swap within each word"
   3657   (sequence
   3658     SI
   3659     ((SI tmpb))
   3660     (set tmpb x)
   3661     (or (and (sll tmpb 8) #xff00ff00)
   3662 	(and (srl tmpb 8) #xff00ff)))
   3663 )
   3664 
   3665 (define-pmacro (swap-w x)
   3666   "Perform word-wise swap within each dword"
   3667   (sequence
   3668     SI
   3669     ((SI tmpb))
   3670     (set tmpb x)
   3671     (or (and (sll tmpb 16) #xffff0000)
   3672 	(and (srl tmpb 16) #xffff)))
   3673 )
   3674 
   3675 (define-pmacro (swap-_ x)
   3676   "Do nothing swap-wise"
   3677   (error SI "SWAP without swap modifier isn't implemented")
   3678 )
   3679 
   3680 (define-pmacro (swap-n x)
   3681   "Perform bitwise not (that is, perform a not, not not perform)"
   3682   (inv x)
   3683 )
   3684 
   3685 (define-pmacro (swap-br x) "Combine swap-r and swap-b" (swap-r (swap-b x)))
   3686 (define-pmacro (swap-wr x) "Combine swap-r and swap-w" (swap-r (swap-w x)))
   3687 (define-pmacro (swap-wb x) "Combine swap-b and swap-w" (swap-b (swap-w x)))
   3688 (define-pmacro (swap-wbr x) "Combine swap-r and swap-wb" (swap-r (swap-wb x)))
   3689 (define-pmacro (swap-nr x) "Combine swap-r and swap-n" (swap-r (swap-n x)))
   3690 (define-pmacro (swap-nb x) "Combine swap-n and swap-b" (swap-b (swap-n x)))
   3691 (define-pmacro (swap-nbr x) "Combine swap-r and swap-nb" (swap-r (swap-nb x)))
   3692 (define-pmacro (swap-nw x) "Combine swap-n and swap-w" (swap-w (swap-n x)))
   3693 (define-pmacro (swap-nwr x) "Combine swap-r and swap-nw" (swap-r (swap-nw x)))
   3694 (define-pmacro (swap-nwb x) "Combine swap-b and swap-nw" (swap-b (swap-nw x)))
   3695 (define-pmacro (swap-nwbr x) "Combine swap-r and swap-nwb" (swap-r (swap-nwb x)))
   3696 
   3697 (define-pmacro (cris-swap swapcode val)
   3698   (sequence
   3699     SI
   3700     ((SI tmpcode) (SI tmpval) (SI tmpres))
   3701     (set tmpcode swapcode)
   3702     (set tmpval val)
   3703     (.splice
   3704      cond
   3705      (.unsplice
   3706       (.map
   3707        (.pmacro
   3708 	(x-swapcode x-swap)
   3709 	((eq tmpcode x-swapcode)
   3710 	 (set tmpres ((.sym swap- x-swap) tmpval))))
   3711        (.iota 16)
   3712        (.splice _ (.unsplice cris-swap-codes)))))
   3713     tmpres)
   3714 )
   3715 
   3716 ; NOT     Rd              alias for SWAPN Rd
   3717 (dni-cdt-attr
   3718  not "Not"
   3719  ((MACH crisv0,crisv3))
   3720  "not ${Rs}"
   3721  (+ (f-dest 8) RFIX_SWAP MODE_REGISTER SIZE_FIXED Rd-sfield)
   3722  (sequence
   3723    ((SI tmp) (SI tmpd))
   3724    (set tmp Rd-sfield)
   3725    (set tmpd (cris-swap 8 tmp))
   3726    (set Rd-sfield tmpd)
   3727    (setf-move SI tmpd))
   3728 )
   3729 
   3730 ; SWAP<option>    Rd      [ N W B R | 01110111 | Rd ]
   3731 (dni-cdt-attr
   3732  swap "Swap"
   3733  ((MACH crisv8,crisv10,crisv32))
   3734  "swap${swapoption} ${Rs}"
   3735  (+ swapoption RFIX_SWAP MODE_REGISTER SIZE_FIXED Rd-sfield)
   3736  (sequence
   3737    ((SI tmps) (SI tmpd))
   3738    (set tmps Rd-sfield)
   3739    (set tmpd (cris-swap swapoption tmps))
   3740    (set Rd-sfield tmpd)
   3741    (setf-move SI tmpd))
   3742 )
   3743 
   3744 ; ASR.m   Rs,Rd           [ Rd | 011110mm | Rs ]
   3745 (dni-cdt-bwd
   3746  asrr "Arithmetic shift right register count"
   3747  "$Rs,$Rd"
   3748  (+ Rd MODE_REGISTER R_ASR Rs)
   3749  (.pmacro
   3750   (BWD)
   3751   (sequence
   3752     ((BWD tmpd) (SI cnt1) (SI cnt2))
   3753     (set cnt1 Rs)
   3754     (set cnt2 (if SI (ne (and cnt1 32) 0) 31 (and cnt1 31)))
   3755     (set tmpd (sra SI (ext SI (trunc BWD Rd)) cnt2))
   3756     (set-subreg-gr BWD (regno Rd) tmpd)
   3757     (setf-move BWD tmpd)))
   3758 )
   3759 
   3760 ; ASRQ    c,Rd            [ Rd | 0011101 | c ]
   3761 (dni-cdt
   3762  asrq "Arithmetic shift right quick-immediate count"
   3763  "asrq $c,${Rd}"
   3764  (+ Rd Q_ASHQ MODE_QUICK_IMMEDIATE (f-b5 1) c)
   3765  (sequence
   3766    ((SI tmpd))
   3767    (set tmpd (sra Rd c))
   3768    (set Rd tmpd)
   3769    (setf-move SI tmpd))
   3770 )
   3771 
   3772 ; LSR.m   Rs,Rd           [ Rd | 011111mm | Rs ]
   3773 (dni-cdt-bwd
   3774  lsrr "Logical shift right register count"
   3775  "$Rs,$Rd"
   3776  (+ Rd MODE_REGISTER R_LSR Rs)
   3777  (.pmacro
   3778   (BWD)
   3779   (sequence
   3780     ((SI tmpd) (SI cnt))
   3781     (set cnt (and Rs 63))
   3782     (set
   3783      tmpd
   3784      (if SI (ne (and cnt 32) 0)
   3785 	 0
   3786 	 (srl SI (zext SI (trunc BWD Rd)) (and cnt 31))))
   3787     (set-subreg-gr BWD (regno Rd) tmpd)
   3788     (setf-move BWD tmpd)))
   3789 )
   3790 
   3791 ; LSRQ    c,Rd            [ Rd | 0011111 | c ]
   3792 (dni-cdt
   3793  lsrq "Logical shift right quick-immediate count"
   3794  "lsrq $c,${Rd}"
   3795  (+ Rd Q_LSHQ MODE_QUICK_IMMEDIATE (f-b5 1) c)
   3796  (sequence
   3797    ((SI tmpd))
   3798    (set tmpd (srl Rd c))
   3799    (set Rd tmpd)
   3800    (setf-move SI tmpd))
   3801 )
   3802 
   3803 ; LSL.m   Rs,Rd           [ Rd | 010011mm | Rs ]
   3804 (dni-cdt-bwd
   3805  lslr "Logical shift left register count"
   3806  "$Rs,$Rd"
   3807  (+ Rd MODE_REGISTER R_LSL Rs)
   3808  (.pmacro
   3809   (BWD)
   3810   (sequence
   3811     ((SI tmpd) (SI cnt))
   3812     (set cnt (and Rs 63))
   3813     (set
   3814      tmpd
   3815      (if SI (ne (and cnt 32) 0)
   3816 	 0
   3817 	 (sll SI (zext SI (trunc BWD Rd)) (and cnt 31))))
   3818     (set-subreg-gr BWD (regno Rd) tmpd)
   3819     (setf-move BWD tmpd)))
   3820 )
   3821 
   3822 ; LSLQ    c,Rd            [ Rd | 0011110 | c ]
   3823 (dni-cdt
   3824  lslq "Logical shift left quick-immediate count"
   3825  "lslq $c,${Rd}"
   3826  (+ Rd Q_LSHQ MODE_QUICK_IMMEDIATE (f-b5 0) c)
   3827  (sequence
   3828    ((SI tmpd))
   3829    (set tmpd (sll Rd c))
   3830    (set Rd tmpd)
   3831    (setf-move SI tmpd))
   3832 )
   3833 
   3834 ; BTST    Rs,Rd           [ Rd | 01001111 | Rs ]
   3835 (dni-cdt
   3836  btst "Bit test register number"
   3837  "$Rs,$Rd"
   3838  (+ Rd MODE_REGISTER RFIX_BTST SIZE_FIXED Rs)
   3839  (sequence
   3840    ((SI tmpd) (SI cnt))
   3841    (set tmpd (sll Rd (sub 31 (and Rs 31))))
   3842    (setf-move SI tmpd))
   3843 )
   3844 
   3845 ; BTSTQ   c,Rd            [ Rd | 0011100 | c ]
   3846 (dni-cdt
   3847  btstq "Bit test quick-immediate number"
   3848  "btstq $c,${Rd}"
   3849  (+ Rd Q_ASHQ MODE_QUICK_IMMEDIATE (f-b5 0) c)
   3850  (sequence
   3851    ((SI tmpd))
   3852    (set tmpd (sll Rd (sub 31 c)))
   3853    (setf-move SI tmpd))
   3854 )
   3855 
   3856 ; SETF    <list of flags> [ P U I X | 01011011 | N Z V C ]
   3857 (dni-cdt
   3858  setf "Set condition code flags explicitly"
   3859  "setf ${list-of-flags}"
   3860  ; The zero-flags case gets flag operands wrong; there's a "_"
   3861  ; where there should have been nothing.  Also, flags are in
   3862  ; assembly code allowed to be specified in any order, which
   3863  ; doesn't match the "flagbits" settings.  Luckily we don't
   3864  ; use this field for assembly.
   3865  (+ RFIX_SETF MODE_REGISTER SIZE_FIXED list-of-flags)
   3866  (.splice
   3867   sequence
   3868   ((SI tmp))
   3869   (set tmp list-of-flags)
   3870   (.unsplice
   3871    (.map
   3872     (.pmacro (ccbit)
   3873 	     (if (ne (and tmp (sll 1 (.sym ccbit -bitnumber))) 0)
   3874 		 (set (.sym ccbit bit) 1)))
   3875     cris-flagnames))
   3876    (set prefix-set 0)
   3877    ; Unless x was specified to be set, set it to 0.
   3878    (if (eq (and tmp (sll 1 x-bitnumber)) 0)
   3879        (set xbit 0)))
   3880 )
   3881 
   3882 ; CLEARF  <list of flags> [ P U I X | 01011111 | N Z V C ]
   3883 (dni-cdt
   3884  clearf "Clear condition code flags explicitly"
   3885  "clearf ${list-of-flags}"
   3886  ; The zero-flags case gets flag operands wrong; there's a "_"
   3887  ; where there should have been nothing.  Also, flags are in
   3888  ; assembly code allowed to be specified in any order, which
   3889  ; doesn't match the "flagbits" settings.  Luckily we don't
   3890  ; use this field for assembly.
   3891  (+ RFIX_CLEARF MODE_REGISTER SIZE_FIXED list-of-flags)
   3892  (.splice
   3893   sequence
   3894   ((SI tmp))
   3895   (set tmp list-of-flags)
   3896   (.unsplice
   3897    (.map
   3898     (.pmacro (ccbit)
   3899 	     (if (ne (and tmp (sll 1 (.sym ccbit -bitnumber))) 0)
   3900 		 (set (.sym ccbit bit) 0)))
   3901     cris-flagnames))
   3902    (reset-x-p))
   3903 )
   3904 
   3905 (define-pmacro
   3906   (rfe-rfn-guts)
   3907   "Common parts of RFE and RFN"
   3908   (sequence
   3909     ((USI oldccs) (USI samebits) (USI shiftbits) (USI keepmask) (BI p1))
   3910     (set oldccs ccs)
   3911     ; Keeping U, S and I in user mode is handled by the CCS setter, so we
   3912     ; don't have to bother.  Actually Q and M are handled too.  The reason
   3913     ; to mask those out is to not have them shifted down into the second
   3914     ; flags level.
   3915     (set keepmask #xc0000000)
   3916     (set samebits (and oldccs keepmask))
   3917     ; The P bit has its own equation.
   3918     (set shiftbits (and (srl (and oldccs #x3ffdfc00) 10) (inv keepmask)))
   3919     (set p1 (ne 0 (and oldccs #x20000)))
   3920     (set ccs (or (or samebits shiftbits)
   3921 		 (if SI (and rbit (not p1)) 0 #x80))))
   3922 )
   3923 
   3924 ; RFE                     [ 0010 10010011 0000 ]
   3925 (dni-cdt-attr
   3926  rfe
   3927  "RFE"
   3928  (MACH-V32)
   3929  "rfe"
   3930  (+ (f-dest 2) MODE_INDIRECT INFIX_RFE SIZE_FIXED (f-source 0))
   3931  (rfe-rfn-guts)
   3932 )
   3933 
   3934 ; SFE                     [ 0011 10010011 0000 ]
   3935 (dni-cdt-attr
   3936  sfe
   3937  "SFE"
   3938  (MACH-V32)
   3939  "sfe"
   3940  (+ (f-dest 3) MODE_INDIRECT INFIX_SFE SIZE_FIXED (f-source 0))
   3941  (sequence
   3942    ((SI oldccs) (SI savemask))
   3943    (set savemask #xc0000000)
   3944    (set oldccs ccs)
   3945    (set ccs
   3946 	(or (and savemask oldccs)
   3947 	    (and (inv savemask) (sll oldccs 10)))))
   3948 )
   3949 
   3950 ; RFG                     [ 0100 10010011 0000 ]
   3951 (dni-cdt-attr
   3952  rfg
   3953  "RFG"
   3954  (MACH-V32)
   3955  "rfg"
   3956  (+ (f-dest 4) MODE_INDIRECT INFIX_RFG SIZE_FIXED (f-source 0))
   3957  (c-call VOID "@cpu@_rfg_handler" pc)
   3958 )
   3959 
   3960 ; RFN                     [ 0101 10010011 0000 ]
   3961 (dni-cdt-attr
   3962  rfn
   3963  "RFN"
   3964  (MACH-V32)
   3965  "rfn"
   3966  (+ (f-dest 5) MODE_INDIRECT INFIX_RFN SIZE_FIXED (f-source 0))
   3967  (sequence () (rfe-rfn-guts) (set mbit 1))
   3968 )
   3969 
   3970 ; HALT                     [ 1111 10010011 0000 ]
   3971 (dni-cdt-attr
   3972  halt
   3973  "HALT"
   3974  (MACH-V32)
   3975  "halt"
   3976  (+ (f-dest 15) MODE_INDIRECT INFIX_HALT SIZE_FIXED (f-source 0))
   3977  (set pc (c-call USI "@cpu@_halt_handler" pc))
   3978 )
   3979 
   3980 ; Bcc     o               [ cc | 0000 | o ]
   3981 (dni
   3982  bcc-b "bcc byte operand"
   3983  ()
   3984  "b${cc} ${o-pcrel}"
   3985  (+ cc QHI_BCC MODE_QUICK_IMMEDIATE o-pcrel)
   3986  (sequence
   3987    ((BI truthval))
   3988    (set truthval (cris-condition cc))
   3989 
   3990    ; Amazing as it may seem, there's no simpler way to find out
   3991    ; whether a branch is taken or not than to mark it through a kludge
   3992    ; like this.
   3993    (c-call VOID "@cpu@_branch_taken" pc o-pcrel truthval)
   3994 
   3995    (reset-x-p)
   3996    (if truthval
   3997        (delay 1
   3998 	      (set pc o-pcrel))))
   3999  (.splice (.unsplice (simplecris-timing))
   4000 	  (crisv32 (unit u-branch) (unit u-exec)))
   4001 )
   4002 (dni
   4003  ba-b "ba byte operand"
   4004  ()
   4005  "ba ${o-pcrel}"
   4006  (+ (f-dest 14) QHI_BCC MODE_QUICK_IMMEDIATE o-pcrel)
   4007  (sequence
   4008    ()
   4009    (reset-x-p)
   4010    (delay 1
   4011 	  (set pc o-pcrel)))
   4012  ((crisv32 (unit u-jump) (unit u-exec)))
   4013 )
   4014 
   4015 ; Bcc     [PC+]           [ cc | 11011111 1111 ]
   4016 ; (We don't implement the generic for pre-V32 but unused variant
   4017 ; "Bcc [Rn(+)]" where n != 15.)
   4018 (dni
   4019  bcc-w "bcc, word operand"
   4020  ()
   4021  "b${cc} ${o-word-pcrel}"
   4022  (+ cc MODE_AUTOINCREMENT INFIX_BCC_M SIZE_FIXED (f-source 15) o-word-pcrel)
   4023  (sequence
   4024    ((BI truthval))
   4025    (set truthval (cris-condition cc))
   4026 
   4027    ; Amazing as it may seem, there's no simpler way to find out
   4028    ; whether a branch is taken or not than to mark it through a kludge
   4029    ; like this.
   4030    (c-call VOID "@cpu@_branch_taken" pc o-word-pcrel truthval)
   4031 
   4032    (reset-x-p)
   4033    (if truthval
   4034        (delay 1
   4035 	      (set pc o-word-pcrel))))
   4036  (.splice
   4037   (.unsplice (simplecris-common-timing ((unit u-const16) (unit u-exec))))
   4038   (crisv32 (unit u-const16) (unit u-branch) (unit u-exec)))
   4039 )
   4040 (dni
   4041  ba-w "ba word operand"
   4042  ()
   4043  "ba ${o-word-pcrel}"
   4044  (+ (f-dest 14) MODE_AUTOINCREMENT INFIX_BCC_M SIZE_FIXED (f-source 15) o-word-pcrel)
   4045  (sequence
   4046    ()
   4047    (reset-x-p)
   4048    (delay 1
   4049 	  (set pc o-word-pcrel)))
   4050  (.splice
   4051   (.unsplice (simplecris-common-timing ((unit u-const16) (unit u-exec))))
   4052   (crisv32 (unit u-const16) (unit u-jump) (unit u-exec)))
   4053 )
   4054 
   4055 ; JAS     Rs,Pd           [ Pd | 10011011 | Rs ]
   4056 (dni
   4057  jas-r "JAS register"
   4058  (MACH-V32)
   4059  "jas ${Rs},${Pd}"
   4060  (+ Pd MODE_INDIRECT INFIX_JAS_R SIZE_FIXED Rs)
   4061  (sequence
   4062    ()
   4063    (reset-x-p)
   4064    (if (andif (eq (regno Rs) 1) (eq (regno Pd) 11))
   4065        ; We use this as a trigger; a normally reasonably rare instruction
   4066        ; used in the v32 trampoline.  See comment at bdapqpc.
   4067        ; CGEN-FIXME: can't use (regno srp) [== (regno (reg h-sr 11))]
   4068        (c-call VOID "cris_flush_simulator_decode_cache" pc))
   4069    (delay 1
   4070 	  (sequence
   4071 	    ()
   4072 	    (set Pd (add SI pc 4))
   4073 	    (set pc Rs))))
   4074  ((crisv32 (unit u-jump-r) (unit u-jump) (unit u-exec)))
   4075 )
   4076 ; Same semantics in pre-V32, except no delay-slot.
   4077 ; FIXME: Missing JIRC/JSRC/JBRC.
   4078 (dni-cdt-attr
   4079  jump-r "JUMP/JSR/JIR register"
   4080  (MACH-PC)
   4081  "jump/jsr/jir ${Rs}"
   4082  (+ Pd MODE_INDIRECT INFIX_JUMP_R SIZE_FIXED Rs)
   4083  (sequence
   4084    ()
   4085    (set Pd (add SI pc 2))
   4086    (set pc Rs)
   4087    (reset-x-p))
   4088 )
   4089 
   4090 ; JAS     [PC+],Pd        [ Pd | 11011011 1111 ]
   4091 (dni
   4092  jas-c "JAS constant"
   4093  (MACH-V32)
   4094  "jas ${const32},${Pd}"
   4095  (+ Pd MODE_AUTOINCREMENT INFIX_JAS_M SIZE_FIXED (f-source 15) const32)
   4096  (sequence
   4097    ()
   4098    (reset-x-p)
   4099    (delay 1
   4100 	  (sequence
   4101 	    ()
   4102 	    (set Pd (add SI pc 8))
   4103 	    (set pc const32))))
   4104  ((crisv32 (unit u-const32) (unit u-jump) (unit u-exec)))
   4105 )
   4106 
   4107 ;        JUMP/JSR/JIR  | Special r.| 1  m| 0  1  0  0| 1  1| Source    |
   4108 (dni-cmt-attr
   4109  jump-m "JUMP/JSR/JIR memory"
   4110  (MACH-PC)
   4111  "jump/jsr/jir [${Rs}${inc}]"
   4112  (+ Pd INFIX_JUMP_M SIZE_FIXED Rs)
   4113  (sequence
   4114    ()
   4115    (set Pd (add SI pc 2))
   4116    (set pc (cris-get-mem SI Rs))
   4117    (reset-x-p))
   4118 )
   4119 (dni-c-SI-attr
   4120  jump-c "JUMP/JSR/JIR constant"
   4121  (MACH-PC)
   4122  "jump/jsr/jir ${const32}"
   4123  (+ Pd MODE_AUTOINCREMENT INFIX_JUMP_M SIZE_FIXED (f-source 15) const32)
   4124  (sequence
   4125    ()
   4126    (set Pd (add SI pc 6))
   4127    (set pc const32)
   4128    (reset-x-p))
   4129 )
   4130 
   4131 ; JUMP    Ps              [ Ps | 10011111 0000 ]
   4132 (dni
   4133  jump-p "JUMP special register"
   4134  (MACH-V32)
   4135  "jump ${Ps}"
   4136  (+ Ps MODE_INDIRECT INFIX_JUMP_P SIZE_FIXED (f-source 0))
   4137  (sequence
   4138    ()
   4139    (reset-x-p)
   4140    (delay 1
   4141 	  (set pc Ps)))
   4142  ((crisv32 (unit u-jump-sr)
   4143 	   (unit u-exec)))
   4144 )
   4145 
   4146 ; BAS     [PC+],Pd        [ Pd | 11101011 1111 ]
   4147 (dni
   4148  bas-c "BAS constant"
   4149  (MACH-V32)
   4150  "bas ${const32},${Pd}"
   4151  (+ Pd MODE_AUTOINCREMENT INFIX_BAS SIZE_FIXED (f-source 15) const32-pcrel)
   4152  (sequence
   4153    ()
   4154    (reset-x-p)
   4155    (delay 1
   4156 	  (sequence
   4157 	    ()
   4158 	    (set Pd (add SI pc 8))
   4159 	    (set pc const32-pcrel))))
   4160  ((crisv32 (unit u-const32) (unit u-jump) (unit u-exec)))
   4161 )
   4162 
   4163 ; JASC    Rs,Pd           [ Pd | 10110011 | Rs ]
   4164 (dni
   4165  jasc-r "JASC register"
   4166  (MACH-V32)
   4167  "jasc ${Rs},${Pd}"
   4168  (+ Pd MODE_INDIRECT INFIX_JASC SIZE_FIXED Rs)
   4169  (sequence
   4170    ()
   4171    (reset-x-p)
   4172    (delay 1
   4173 	  (sequence
   4174 	    ()
   4175 	    (set Pd (add SI pc 8))
   4176 	    (set pc Rs))))
   4177  ((crisv32 (unit u-jump-r) (unit u-skip4) (unit u-jump) (unit u-exec)))
   4178 )
   4179 
   4180 ; JASC    [PC+],Pd        [ Pd | 11110011 1111 ]
   4181 (dni
   4182  jasc-c "JASC constant"
   4183  (MACH-V32)
   4184  "jasc ${const32},${Pd}"
   4185  (+ Pd MODE_AUTOINCREMENT INFIX_JASC SIZE_FIXED (f-source 15) const32)
   4186  (sequence
   4187    ()
   4188    (reset-x-p)
   4189    (delay 1
   4190 	  (sequence
   4191 	    ()
   4192 	    (set Pd (add SI pc 12))
   4193 	    (set pc const32))))
   4194  ((crisv32 (unit u-const32) (unit u-skip4) (unit u-jump) (unit u-exec)))
   4195 )
   4196 
   4197 ; BASC    [PC+],Pd        [ Pd | 11101111 1111 ]
   4198 (dni
   4199  basc-c "BASC constant"
   4200  (MACH-V32)
   4201  "basc ${const32},${Pd}"
   4202  (+ Pd MODE_AUTOINCREMENT INFIX_BASC SIZE_FIXED (f-source 15) const32-pcrel)
   4203  (sequence
   4204    ()
   4205    (reset-x-p)
   4206    (delay 1
   4207 	  (sequence
   4208 	    ()
   4209 	    (set Pd (add SI pc 12))
   4210 	    (set pc const32-pcrel))))
   4211  ((crisv32 (unit u-const32) (unit u-skip4) (unit u-jump) (unit u-exec)))
   4212 )
   4213 
   4214 ; BREAK     n             [ 1110 | 10010011 | n ]
   4215 
   4216 (dni-cdt
   4217  break "break"
   4218  "break $n"
   4219  (+ (f-operand2 #xe) MODE_INDIRECT INFIX_BREAK SIZE_FIXED n)
   4220  (sequence () (reset-x-p) (set pc (c-call USI "@cpu@_break_handler" n pc)))
   4221 )
   4222 
   4223 ; BOUND.m Rs,Rd           [ Rd | 010111mm | Rs ]
   4224 (dni-cdt-bwd
   4225  bound-r "Bound register"
   4226  "${Rs},${Rd}"
   4227  (+ Rd R_BOUND MODE_REGISTER Rs)
   4228  (.pmacro
   4229   (BWD)
   4230   (sequence
   4231     ((SI tmpopd) (SI tmpops) (SI newval))
   4232     (set tmpops ((.sym BWD -zext) (trunc BWD Rs)))
   4233     (set tmpopd Rd)
   4234     (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd))
   4235     (set Rd newval)
   4236     (setf-move SI newval)))
   4237 )
   4238 
   4239 ; BOUND.m [Rs],Rd         [ Rd | 100111mm | Rs ]
   4240 ; BOUND.m [Rs+],Rd        [ Rd | 110111mm | Rs ]
   4241 (dni-cmt-bwd-attr
   4242  bound-m "Bound memory"
   4243  (MACH-PRE-V32)
   4244  "[${Rs}${inc}],${Rd}"
   4245  (+ Rd INDIR_BOUND Rs)
   4246  (.pmacro
   4247   (BWD)
   4248   (sequence
   4249     ((SI tmpopd) (SI tmpops) (SI newval))
   4250     (set tmpops ((.sym BWD -zext) (cris-get-mem BWD Rs)))
   4251     (set tmpopd Rd)
   4252     (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd))
   4253     (if (andif prefix-set (not inc))
   4254 	(set Rs newval)
   4255 	(set Rd newval))
   4256     (setf-move SI newval)))
   4257 )
   4258 
   4259 ; (BOUND.m [PC+],Rd        [ Rd | 110111mm | 1111 ])
   4260 (dni-c-QI
   4261  bound-cb "Bound constant byte"
   4262  "bound.b [PC+],${Rd}"
   4263  (+ Rd MODE_AUTOINCREMENT INDIR_BOUND SIZE_BYTE (f-source 15) uconst8)
   4264  (sequence
   4265    ((SI tmpopd) (SI tmpops) (SI newval))
   4266    (set tmpops (zext SI (trunc QI uconst8)))
   4267     (set tmpopd Rd)
   4268     (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd))
   4269     (set Rd newval)
   4270     (setf-move SI newval))
   4271 )
   4272 (dni-c-HI
   4273  bound-cw "Bound constant word"
   4274  "bound.w [PC+],${Rd}"
   4275  (+ Rd MODE_AUTOINCREMENT INDIR_BOUND SIZE_WORD (f-source 15) uconst16)
   4276  (sequence
   4277    ((SI tmpopd) (SI tmpops) (SI newval))
   4278    (set tmpops (zext SI uconst16))
   4279     (set tmpopd Rd)
   4280     (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd))
   4281     (set Rd newval)
   4282     (setf-move SI newval))
   4283 )
   4284 (dni-c-SI
   4285  bound-cd "Bound constant dword"
   4286  "bound.d [PC+],${Rd}"
   4287  (+ Rd MODE_AUTOINCREMENT INDIR_BOUND SIZE_DWORD (f-source 15) const32)
   4288  (sequence
   4289    ((SI tmpopd) (SI tmpops) (SI newval))
   4290    (set tmpops const32)
   4291     (set tmpopd Rd)
   4292     (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd))
   4293     (set Rd newval)
   4294     (setf-move SI newval))
   4295 )
   4296 
   4297 ; Scc     Rd              [ cc | 01010011 | Rd ]
   4298 (dni-cdt
   4299  scc "scc"
   4300  "s${cc} ${Rd-sfield}"
   4301  (+ cc MODE_REGISTER RFIX_SCC SIZE_FIXED Rd-sfield)
   4302  (sequence
   4303    ((BI truthval))
   4304    (set truthval (cris-condition cc))
   4305    (set Rd-sfield (zext SI truthval))
   4306    (reset-x-p))
   4307 )
   4308 
   4309 ; LZ      Rs,Rd           [ Rd | 01110011 | Rs ]
   4310 (dni-cdt-attr
   4311  lz "lz"
   4312  (MACH-V3-UP)
   4313  "lz ${Rs},${Rd}"
   4314  (+ Rd MODE_REGISTER RFIX_LZ SIZE_FIXED Rs)
   4315  (sequence
   4316    ((SI tmpd) (SI tmp))
   4317    (set tmp Rs)
   4318    (set tmpd 0)
   4319    (.splice
   4320     sequence
   4321     ()
   4322     (.unsplice
   4323      (.map
   4324       (.pmacro (n)
   4325 	       (if (ge tmp 0)
   4326 		   (sequence
   4327 		     ()
   4328 		     (set tmp (sll tmp 1))
   4329 		     (set tmpd (add tmpd 1)))))
   4330       (.iota 32))))
   4331    (set Rd tmpd)
   4332    (setf-move SI tmpd))
   4333 )
   4334 
   4335 ; ADDOQ   o,Rs,ACR        [ Rs | 0001 | o ]
   4336 (dni-cdt
   4337  addoq "addoq"
   4338  "addoq $o,$Rs,ACR"
   4339  (+ Rs-dfield MODE_QUICK_IMMEDIATE QHI_ADDOQ o)
   4340  (sequence
   4341    ()
   4342    (set prefixreg (add SI Rs-dfield o))
   4343    (set prefix-set 1))
   4344 )
   4345 
   4346 ; (BDAPQ   o,PC        [ 1111 | 0001 | o ])
   4347 ; This [PC+I] prefix is used in trampolines.
   4348 (dni-cdt-attr
   4349  bdapqpc "bdapq pc operand"
   4350  (MACH-PC UNCOND-CTI)
   4351  "bdapq $o,PC"
   4352  (+ (f-dest 15) MODE_QUICK_IMMEDIATE QHI_BDAP o)
   4353  (sequence
   4354    ()
   4355    (set prefixreg (add SI (add SI pc 2) o))
   4356    (set prefix-set 1)
   4357    ; When this *rare* instruction is seen, we're may be about to write
   4358    ; into code to be executed soon, *probably* covering addresses decoded
   4359    ; and executed before.  If the simulator does not implement snooping
   4360    ; and automatic decoder flush, it will execute old code.  This call
   4361    ; is a kludge for such simulators, asking it to abandon such cached
   4362    ; information.  Anyway, it is hopefully enough to make CGEN-sim not
   4363    ; hork on gcc trampolines.
   4364    ; We mark this insn as UNCOND-CTI so this insn will end a simulator
   4365    ; basic block (the atomic unit of translation).
   4366    (c-call VOID "cris_flush_simulator_decode_cache" pc))
   4367 )
   4368 
   4369 ; (BDAP.D  [PC+],PC   [ 1111 | 11010110 | 1111 ]
   4370 ; This [PC+I] prefix is used for DSO-local jumps in PIC code, together with
   4371 ; move-m-pcplus-p0: "move [pc=pc+N],p0"
   4372 (dni-c-SI-attr
   4373  bdap-32-pc "bdap.d [PC+],PC"
   4374  (MACH-PC)
   4375  "bdap ${sconst32},PC"
   4376  (+ (f-dest 15) MODE_AUTOINCREMENT INDIR_BDAP_M SIZE_DWORD (f-source 15) const32)
   4377  (sequence
   4378    ((SI newpc) (SI oldpc) (SI offs))
   4379    (set offs const32)
   4380    (set oldpc (add SI pc 6))
   4381    (set newpc (add SI oldpc offs))
   4382    (set prefixreg newpc)
   4383    (set prefix-set 1))
   4384 )
   4385 
   4386 ; (MOVE    [PC+],P0        [ 0000 | 11100011 | 1111 ])
   4387 ; This insn is used for DSO-local jumps in PIC code.  See bdap-32-pc.
   4388 (dni ; Must not use dni-cmt-* because we force MODE_AUTOINCREMENT.
   4389  move-m-pcplus-p0 "move [PC+],P0"
   4390  (MACH-PC)
   4391  "move [PC+],P0"
   4392  (+ (f-dest 0) MODE_AUTOINCREMENT INFIX_MOVE_M_S SIZE_FIXED (f-source 15))
   4393  (if prefix-set
   4394      (sequence
   4395        ((QI dummy))
   4396        ; We model the memory read, but throw the result away, as the
   4397        ; destination register is read-only.  We need to assign the result of
   4398        ; cris-get-mem though, as CGEN-FIXME: invalid C code will otherwise
   4399        ; be generated.
   4400        (set dummy (cris-get-mem QI pc))
   4401        (reset-x-p))
   4402      (error "move [PC+],P0 without prefix is not implemented"))
   4403  (cris-mem-timing)
   4404 )
   4405 
   4406 ; This insn is used in Linux in the form "move [$sp=$sp+16],$p8"; it's
   4407 ; similar to move-m-pcplus-p0 above.  The same comments apply here.
   4408 (dni
   4409  move-m-spplus-p8 "move [SP+],P8"
   4410  (MACH-PC)
   4411  "move [SP+],P8"
   4412  (+ (f-dest 8) MODE_AUTOINCREMENT INFIX_MOVE_M_S SIZE_FIXED (f-source 14))
   4413  (if prefix-set
   4414      (sequence
   4415        ((SI dummy))
   4416        (set dummy (cris-get-mem SI sp))
   4417        (reset-x-p))
   4418      (error "move [SP+],P8 without prefix is not implemented"))
   4419  (cris-mem-timing)
   4420 )
   4421 
   4422 ; ADDO.m  [Rs],Rd,ACR    [ Rd | 100101mm | Rs ]
   4423 ; ADDO.m  [Rs+],Rd,ACR   [ Rd | 110101mm | Rs ]
   4424 (dni-cmt-bwd
   4425  addo-m "addo.m memory"
   4426  "[${Rs}${inc}],$Rd,ACR"
   4427  (+ Rd INDIR_ADDO Rs)
   4428  (.pmacro
   4429   (BWD)
   4430   (sequence
   4431     ((BWD tmps))
   4432     (set tmps (cris-get-mem BWD Rs))
   4433     (set prefixreg (add SI Rd ((.sym BWD -ext) tmps)))
   4434     (set prefix-set 1)))
   4435 )
   4436 
   4437 ; (ADDO.m  [PC+],Rd,ACR   [ Rd | 110101mm | 1111 ]
   4438 (dni-c-QI
   4439  addo-cb "addo.b const"
   4440  "addo.b [PC+],$Rd,ACR"
   4441  (+ Rd MODE_AUTOINCREMENT INDIR_ADDO SIZE_BYTE (f-source 15) sconst8)
   4442  (sequence
   4443    ()
   4444    (set prefixreg (add SI Rd (ext SI (trunc QI sconst8))))
   4445    (set prefix-set 1))
   4446 )
   4447 (dni-c-HI
   4448  addo-cw "addo.w const"
   4449  "addo.w [PC+],$Rd,ACR"
   4450  (+ Rd MODE_AUTOINCREMENT INDIR_ADDO SIZE_WORD (f-source 15) sconst16)
   4451  (sequence
   4452    ()
   4453    (set prefixreg (add SI Rd (ext SI (trunc HI sconst16))))
   4454    (set prefix-set 1))
   4455 )
   4456 (dni-c-SI
   4457  addo-cd "addo.d const"
   4458  "addo.d [PC+],$Rd,ACR"
   4459  (+ Rd MODE_AUTOINCREMENT INDIR_ADDO SIZE_DWORD (f-source 15) const32)
   4460  (sequence
   4461    ()
   4462    (set prefixreg (add SI Rd const32))
   4463    (set prefix-set 1))
   4464 )
   4465 
   4466 ;         DIP    []   | 0  0  0  0| 1  m| 0  1  0  1| 1  1| Source    |
   4467 
   4468 (dni-cmt-attr
   4469  dip-m "dip mem"
   4470  (MACH-PRE-V32)
   4471  "dip [${Rs}${inc}]"
   4472  (+ (f-dest 0) INFIX_DIP SIZE_FIXED Rs)
   4473  (sequence
   4474    ((SI tmps))
   4475    (set tmps (cris-get-mem SI Rs))
   4476    (set prefixreg tmps)
   4477    (set prefix-set 1))
   4478 )
   4479 
   4480 ;         (DIP    []   | 0  0  0  0| 1  m| 0  1  0  1| 1  1| Source    |    )
   4481 (dni-c-SI-attr
   4482  dip-c "dip [PC+]"
   4483  (MACH-PC)
   4484  "dip [PC+]"
   4485  (+ (f-dest 0) MODE_AUTOINCREMENT INFIX_DIP SIZE_FIXED (f-source 15) const32)
   4486  (sequence
   4487    ()
   4488    (set prefixreg const32)
   4489    (set prefix-set 1))
   4490 )
   4491 
   4492 ; ADDI    Rs.m,Rd,ACR     [ Rs | 010101mm | Rd ]
   4493 ; a.k.a. biap
   4494 (dni-cdt-bwd
   4495  addi-acr "addi prefix"
   4496  "${Rs-dfield}.m,${Rd-sfield},ACR"
   4497  (+ Rd-sfield MODE_REGISTER R_ADDI_ACR Rs-dfield)
   4498  (.pmacro
   4499   (BWD)
   4500   (sequence
   4501     ()
   4502     (set prefixreg (add SI Rd-sfield (mul Rs-dfield (.sym BWD -size))))
   4503     (set prefix-set 1)))
   4504 )
   4505 
   4506 (dni-cdt-bwd-attr
   4507  biap-pc "biap.m ${Rs-dfield},PC"
   4508  (MACH-PC)
   4509  "${Rs-dfield}.m,PC"
   4510  (+ Rs-dfield MODE_REGISTER R_ADDI_ACR (f-source 15))
   4511  (.pmacro
   4512   (BWD)
   4513   (sequence
   4514     ()
   4515     (set prefixreg (add SI (add SI pc 4) (mul Rs-dfield (.sym BWD -size))))
   4516     (set prefix-set 1)))
   4517 )
   4518 
   4519 ; FIDXI    [Rs]            [ 0000 | 11010011 | Rs ]
   4520 (dni-cdt-attr
   4521  fidxi "fidxi [Rs]"
   4522  (MACH-V32)
   4523  "fidxi [$Rs]"
   4524  (+ (f-dest 0) MODE_AUTOINCREMENT INFIX_FIDXI SIZE_FIXED Rs)
   4525  (set pc (c-call USI "@cpu@_fidxi_handler" pc Rs))
   4526 )
   4527 
   4528 ; FTAGI    [Rs]            [ 0001 | 11010011 | Rs ]
   4529 (dni-cdt-attr
   4530  ftagi "ftagi [Rs]"
   4531  (MACH-V32)
   4532  "fidxi [$Rs]"
   4533  (+ (f-dest 1) MODE_AUTOINCREMENT INFIX_FTAGI SIZE_FIXED Rs)
   4534  (set pc (c-call USI "@cpu@_ftagi_handler" pc Rs))
   4535 )
   4536 
   4537 ; FIDXD    [Rs]            [ 0000 | 10101011 | Rs ]
   4538 (dni-cdt-attr
   4539  fidxd "fidxd [Rs]"
   4540  (MACH-V32)
   4541  "fidxd [$Rs]"
   4542  (+ (f-dest 0) MODE_INDIRECT INFIX_FIDXD SIZE_FIXED Rs)
   4543  (set pc (c-call USI "@cpu@_fidxd_handler" pc Rs))
   4544 )
   4545 
   4546 ; FTAGD    [Rs]            [ 0001 | 10101011 | Rs ]
   4547 (dni-cdt-attr
   4548  ftagd "ftagd [Rs]"
   4549  (MACH-V32)
   4550  "ftagd [$Rs]"
   4551  (+ (f-dest 1) MODE_INDIRECT INFIX_FTAGD SIZE_FIXED Rs)
   4552  (set pc (c-call USI "@cpu@_ftagd_handler" pc Rs))
   4553 )
   4554