FSF GCC merge 02/23/03
[official-gcc.git] / gcc / config / m88k / m88k.md
blobedefd23db088f2b2f8f3249f2ebf63fd00099114
1 ;;- Machine description for the Motorola 88000 for GNU C compiler
2 ;;  Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
3 ;;  Free Software Foundation, Inc.
4 ;;  Contributed by Michael Tiemann (tiemann@mcc.com)
5 ;;  Currently maintained by (gcc@dg-rtp.dg.com)
7 ;; This file is part of GNU CC.
9 ;; GNU CC 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 2, or (at your option)
12 ;; any later version.
14 ;; GNU CC 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.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; Attribute describing the processor.  This attribute must match exactly
28 ;; with the processor_type enumeration in m88k.h.
30 ; Target CPU.
31 (define_attr "cpu" "m88100,m88110,m88000"
32   (const (symbol_ref "m88k_cpu")))
34 ; Type of each instruction.  Default is arithmetic.
35 ; I'd like to write the list as this, but genattrtab won't accept it.
37 ; "branch,jump,call,                    ; flow-control instructions
38 ;  load,store,loadd,loada,              ; data unit instructions
39 ;  spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions
40 ;  spmul,dpmul,imul,                    ; FPU multiply instructions
41 ;  arith,bit,mov                        ; integer unit instructions
42 ;  marith,weird"                        ; multi-word instructions
44 ; Classification of each insn.  Some insns of TYPE_BRANCH are multi-word.
45 (define_attr "type"
46   "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird"
47   (const_string "arith"))
49 (define_attr "fpu" "yes,no"
50   (if_then_else
51    (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv")
52    (const_string "yes") (const_string "no")))
54 ; Length in # of instructions of each insn.  The values are not exact, but
55 ; are safe.
56 (define_attr "length" ""
57   (cond [(eq_attr "type" "marith,weird,branch")
58          (const_int 2)]
59         (const_int 1)))
61 ; Describe a user's asm statement.
62 (define_asm_attributes
63   [(set_attr "type" "weird")])
65 ; Define the delay slot requirements for branches and calls.
66 ; The m88100 annuls instructions if a conditional branch is taken.
67 ; For insns of TYPE_BRANCH that are multi-word instructions, the
68 ; delay slot applies to the first instruction.
70 ; @@ For the moment, reorg.c requires that the delay slot of a branch not
71 ; be a call or branch.
73 (define_delay (eq_attr "type" "branch,jump")
74   [(and
75     (and
76      (eq_attr "type" "!branch,jump,call,marith,weird") ; required.
77      (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible.
78     (eq_attr "fpu" "no")) ; issue as-soon-as-possible.
79    (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1)
81 ; output_call supports an unconditional branch in the delay slot of
82 ; a call.  (@@ Support for this case is expected in reorg.c soon.)
84 (define_delay (eq_attr "type" "call")
85   [(eq_attr "type" "!branch,call,marith,weird") ; required.
86    (nil) (nil)])
88 ; An abstract block diagram of the function units for the m88100.
90 ;                           *
91 ;                           |
92 ;                       +---v----+
93 ;                       | decode |
94 ;                       +-vv-v-v-+       fpu
95 ;              ,----------'| | `----------------------.
96 ;              |           | |                        | ,-----.
97 ;         load |     store | | arith                  | |     |
98 ;              |           | |                      +-v-v-+   | dp source
99 ;              |           | |                      | fp1 |---'
100 ;     store    |           | |      div             +-v-v-+
101 ;   ,------.   |           | |    ,-----. ,-----------' `-----------.
102 ;   |      |   |           | |    |     | |                         |
103 ;   |   +--v---v--+    ,---' |    |   +-v-v---+                 +---v---+
104 ;   |   | stage 2 |    |     |    `---| add 2 |                 | mul 2 |
105 ;   |   +---------+    |  +--v--+     +-------+           imul  +-------+
106 ;   |   | stage 1 |    |  | alu |     | add 3 |        ,--------| mul 3 |
107 ;   |   +---------+    |  +--v--+     +-------+        |        +-------+
108 ;   |   | stage 0 |    |     |        | add 4 |        |        | mul 4 |
109 ;   |   +--v---v--+    |     |        +---v---+        |        +-------+
110 ;   |      |   |       |     |            |            |        | mul 5 |
111 ;   |      *   |       |     |            |            |        +---v---+
112 ;   |          |       |     |            |       +----v----+       |
113 ;   |     load |       |     |     fp add `------>| fp last |<------' fp mul
114 ;   |          |       |     |                    +---v-v--^+
115 ;   |          |       |     |                        | |  |
116 ;   |          |       |     |                        | `--' dp dest
117 ;   |          |    +--v-----v--+                     |
118 ;   |          `--->| writeback |<--------------------'
119 ;   |               +--v-----v--+
120 ;   |                  |     |
121 ;   `------------------'     *
123 ; The decode unit need not be specified.
124 ; Consideration of writeback contention is critical to superb scheduling.
126 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
127 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
129 ; Describing the '100 alu is currently not useful.
130 ;(define_function_unit "alu" 1 0 (eq_attr "type"
131 ;                                        "!store,marith,weird") 1 0)
132 ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0)
134 (define_function_unit "alu" 1 0
135   (and (eq_attr "type" "loada,arith,mov") (eq_attr "cpu" "!m88100")) 2 0)
136 (define_function_unit "alu" 1 0
137   (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0)
139 (define_function_unit "bit" 1 0
140   (and (eq_attr "type" "bit") (eq_attr "cpu" "!m88100")) 2 2)
142 (define_function_unit "mem100" 1 0
143   (and (eq_attr "type" "store,loada") (eq_attr "cpu" "m88100")) 1 0)
144 (define_function_unit "mem100" 1 0
145   (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 0)
146 (define_function_unit "mem100" 1 0
147   (and (eq_attr "type" "loadd") (eq_attr "cpu" "m88100")) 3 2)
149 (define_function_unit "mem110" 1 0
150   (and (eq_attr "type" "load,loadd") (eq_attr "cpu" "!m88100")) 3 2)
151 (define_function_unit "mem110" 1 0
152   (and (eq_attr "type" "store") (eq_attr "cpu" "!m88100")) 1 2)
154 ; The times are adjusted to include fp1 and fplast, but then are further
155 ; adjusted based on the actual generated code.  The notation to the right
156 ; is the total latency.  A range denotes a group of instructions and/or
157 ; conditions (the extra clock of fplast time with some sequences).
159 (define_function_unit "fpmul100" 1 0
160   (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 0)          ; 6-8
161 (define_function_unit "fpmul100" 1 0
162   (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 0)          ; 9-10
163 (define_function_unit "fpmul100" 1 0
164   (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 0)           ; 4
166 (define_function_unit "fpmul110" 1 0
167   (and (eq_attr "type" "imul,spmul,dpmul")
168        (eq_attr "cpu" "!m88100")) 5 2)                                  ; 3
170 (define_function_unit "fpadd100" 1 5
171   (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 0)    ; 5-6
172 (define_function_unit "fpadd100" 1 5
173   (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 0)    ; 6-7
175 (define_function_unit "fpadd110" 1 0
176   (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 5 2)   ; 3
177 (define_function_unit "fpadd110" 1 0
178   (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2)   ; 1
180 (define_function_unit "fpadd100" 1 5
181   (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 0)         ; 30-31
182 (define_function_unit "fpadd100" 1 5
183   (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 0)         ; 60-61
184 (define_function_unit "fpadd100" 1 5
185   (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 0)          ; 38
187 (define_function_unit "div" 1 1
188   (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 25 2)        ; 13
189 (define_function_unit "div" 1 1
190   (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 45 2)        ; 23
191 (define_function_unit "div" 1 1
192   (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 35 2)         ; 18
194 ;; Superoptimizer sequences
196 ;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; }
197 ;;      subu.co r5,r2,r3
198 ;;      addu.cio r6,r4,r0
200 (define_split
201   [(set (match_operand:SI 0 "register_operand" "=r")
202         (minus:SI (match_operand:SI 1 "register_operand" "r")
203                   (geu:SI (match_operand:SI 2 "register_operand" "r")
204                           (match_operand:SI 3 "register_operand" "r"))))]
205   ""
206   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
207    (set (match_dup 0)
208         (plus:SI (match_dup 1)
209                  (unspec:SI [(const_int 0)
210                              (reg:CC 0)] 0)))]
211   "")
213 ;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; }
214 ;;      subu.co r5,r3,r2
215 ;;      addu.cio r6,r4,r0
217 (define_split
218   [(set (match_operand:SI 0 "register_operand" "=r")
219         (minus:SI (match_operand:SI 1 "register_operand" "r")
220                   (leu:SI (match_operand:SI 3 "register_operand" "r")
221                           (match_operand:SI 2 "register_operand" "r"))))]
222   ""
223   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
224    (set (match_dup 0)
225         (plus:SI (match_dup 1)
226                  (unspec:SI [(const_int 0)
227                              (reg:CC 0)] 0)))]
228   "")
230 ;; eq0+: { r = (v0 == 0) + v1; }
231 ;;      subu.co r4,r0,r2
232 ;;      addu.cio r5,r3,r0
234 (define_split
235   [(set (match_operand:SI 0 "register_operand" "=r")
236         (minus:SI (match_operand:SI 1 "register_operand" "r")
237                   (eq:SI (match_operand:SI 2 "register_operand" "r")
238                          (const_int 0))))]
239   ""
240   [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
241    (set (match_dup 0)
242         (plus:SI (match_dup 1)
243                  (unspec:SI [(const_int 0)
244                              (reg:CC 0)] 0)))]
245   "")
247 ;; ltu-:  { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); }
248 ;;      subu.co r5,r2,r3
249 ;;      subu.cio r6,r4,r0
251 (define_split
252   [(set (match_operand:SI 0 "register_operand" "=r")
253         (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r")
254                          (match_operand:SI 3 "register_operand" "r"))
255                  (match_operand:SI 1 "register_operand" "r")))]
256   ""
257   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
258    (set (match_dup 0)
259         (minus:SI (match_dup 1)
260                   (unspec:SI [(const_int 0)
261                               (reg:CC 0)] 1)))]
262   "")
264 ;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); }
265 ;;      subu.co r5,r3,r2
266 ;;      subu.cio r6,r4,r0
268 (define_split
269   [(set (match_operand:SI 0 "register_operand" "=r")
270         (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r")
271                          (match_operand:SI 2 "register_operand" "r"))
272                  (match_operand:SI 1 "register_operand" "r")))]
273   ""
274   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
275    (set (match_dup 0)
276         (minus:SI (match_dup 1)
277                  (unspec:SI [(const_int 0)
278                              (reg:CC 0)] 1)))]
279   "")
281 ;; ne0-: { r = v1 - (v0 != 0); }
282 ;;      subu.co r4,r0,r2
283 ;;      subu.cio r5,r3,r0
285 (define_split
286   [(set (match_operand:SI 0 "register_operand" "=r")
287         (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r")
288                         (const_int 0))
289                  (match_operand:SI 1 "register_operand" "r")))]
290   ""
291   [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
292    (set (match_dup 0)
293         (minus:SI (match_dup 1)
294                   (unspec:SI [(const_int 0)
295                               (reg:CC 0)] 1)))]
296   "")
298 ;; ges0-: { r = v1 - ((signed_word) v0 >= 0); }
299 ;;      addu.co r4,r2,r2
300 ;;      subu.cio r5,r3,r0
302 (define_split
303   [(set (match_operand:SI 0 "register_operand" "=r")
304         (minus:SI (match_operand:SI 1 "register_operand" "r")
305                   (xor:SI (lshiftrt:SI
306                            (match_operand:SI 2 "register_operand" "r")
307                            (const_int 31))
308                           (const_int 1))))]
309   ""
310   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0))
311    (set (match_dup 0)
312         (minus:SI (match_dup 1)
313                   (unspec:SI [(const_int 0)
314                               (reg:CC 0)] 1)))]
315   "")
317 ;; This rich set of complex patterns are mostly due to Torbjorn Granlund
318 ;; (tege@sics.se).  They've changed since then, so don't complain to him
319 ;; if they don't work right.
321 ;; Regarding shifts, gen_lshlsi3 generates ASHIFT.  The gen functions
322 ;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing
323 ;; special needs to be done here.
325 ;; Optimize possible cases of the set instruction.
327 (define_insn ""
328   [(set (match_operand:SI 0 "register_operand" "=r")
329         (ashift:SI (const_int -1)
330             (match_operand:SI 1 "register_operand" "r")))]
331   ""
332   "set %0,%#r0,%1"
333   [(set_attr "type" "bit")])
335 (define_insn ""
336   [(set (match_operand:SI 0 "register_operand" "=r")
337         (ior:SI (ashift:SI (const_int -1)
338                     (match_operand:SI 1 "register_operand" "r"))
339          (match_operand:SI 2 "register_operand" "r")))]
340   ""
341   "set %0,%2,%1"
342   [(set_attr "type" "bit")])
344 (define_insn ""
345   [(set (match_operand:SI 0 "register_operand" "=r")
346         (ior:SI (match_operand:SI 1 "register_operand" "r")
347          (ashift:SI (const_int -1)
348                     (match_operand:SI 2 "register_operand" "r"))))]
349   ""
350   "set %0,%1,%2"
351   [(set_attr "type" "bit")])
353 ;; Optimize possible cases of the mak instruction.
355 (define_insn ""
356   [(set (match_operand:SI 0 "register_operand" "=r")
357         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
358                            (match_operand:SI 2 "int5_operand" ""))
359                 (match_operand:SI 3 "immediate_operand" "n")))]
360   "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))"
361   "*
363   operands[4] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3])
364                                           >> INTVAL(operands[2]))));
365   return \"mak %0,%1,%4<%2>\";
367   [(set_attr "type" "bit")])
369 ;; Optimize possible cases of output_and.
371 (define_insn ""
372   [(set (match_operand:SI 0 "register_operand" "=r")
373         (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
374                                     (match_operand:SI 2 "int5_operand" "")
375                                     (match_operand:SI 3 "int5_operand" ""))
376                    (match_operand:SI 4 "int5_operand" "")))]
377   "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
378   "*
380   operands[2]
381     = GEN_INT (((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4]));
382   return output_and (operands);
384   [(set_attr "type" "marith")]) ; arith,bit,marith.  length is 1 or 2.
386 ;; Improve logical operations on compare words
388 ;; We define all logical operations on CCmode values to preserve the pairwise
389 ;; relationship of the compare bits.  This allows a future branch prediction
390 ;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.
391 ;; THIS IS CURRENTLY FALSE! 
393 ;; Opportunities arise when conditional expressions using && and || are made
394 ;; unconditional.  When these are used to branch, the sequence is
395 ;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}.  When these are used to create
396 ;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or
397 ;; cmp/cmp/ext/ext/{and,or} for -1 or 0.
399 ;; When the extracted conditions are the same, the define_split patterns
400 ;; below change extu/extu/{and,or} into {and,or}/extu.  If the reversed
401 ;; conditions match, one compare word can be complemented, resulting in
402 ;; {and.c,or.c}/extu.  These changes are done for ext/ext/{and,or} as well.
403 ;; If the conditions don't line up, one can be rotated.  To keep the pairwise
404 ;; relationship, it may be necessary to both rotate and complement.  Rotating
405 ;; makes branching cheaper, but doesn't help (or hurt) creating a value, so
406 ;; we don't do this for ext/ext/{and,or}.
408 ;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined
409 ;; into an alternate form of bb0 and bb1.
411 (define_split
412   [(set (match_operand:SI 0 "register_operand" "=r")
413         (ior:SI (neg:SI 
414                  (match_operator 1 "even_relop"
415                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
416                                   (const_int 0)]))
417                 (neg:SI
418                  (match_operator 3 "relop"
419                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
420                                   (const_int 0)]))))
421    (clobber (match_operand:SI 5 "register_operand" "=r"))]
422   ""
423   [(set (match_dup 5)
424         (ior:CCEVEN (match_dup 4)
425                 (match_dup 2)))
426    (set (match_dup 0)
427         (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
428   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
429    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
430      ; /* The conditions match.  */
431    else if (GET_CODE (operands[1])
432             == reverse_condition (GET_CODE (operands[3])))
433      /* Reverse the condition by complementing the compare word.  */
434      operands[4] = gen_rtx_NOT (CCmode, operands[4]);
435    else
436      {
437        /* Make the condition pairs line up by rotating the compare word.  */
438        int cv1 = condition_value (operands[1]);
439        int cv2 = condition_value (operands[3]);
441        operands[4] = gen_rtx_ROTATE (CCmode, operands[4],
442                                      GEN_INT (((cv2 & ~1) - (cv1 & ~1))
443                                               & 0x1f));
444        /* Reverse the condition if needed.  */
445        if ((cv1 & 1) != (cv2 & 1))
446          operands[4] = gen_rtx_NOT (CCmode, operands[4]);
447      }")
449 (define_split
450   [(set (match_operand:SI 0 "register_operand" "=r")
451         (ior:SI (neg:SI 
452                  (match_operator 1 "odd_relop"
453                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
454                                   (const_int 0)]))
455                 (neg:SI
456                  (match_operator 3 "odd_relop"
457                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
458                                   (const_int 0)]))))
459    (clobber (match_operand:SI 5 "register_operand" "=r"))]
460   ""
461   [(set (match_dup 5)
462         (and:CCEVEN (match_dup 4)
463                 (match_dup 2)))
464    (set (match_dup 0)
465         (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
466   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
467    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
468      ; /* The conditions match.  */
469    else
470      {
471        /* Make the condition pairs line up by rotating the compare word.  */
472        int cv1 = condition_value (operands[1]);
473        int cv2 = condition_value (operands[3]);
475        operands[4] = gen_rtx_ROTATE (CCmode, operands[4],
476                                      GEN_INT ((cv2 - cv1) & 0x1f));
477      }")
479 (define_split
480   [(set (match_operand:SI 0 "register_operand" "=r")
481         (ior:SI (neg:SI 
482                  (match_operator 1 "odd_relop"
483                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
484                                   (const_int 0)]))
485                 (neg:SI
486                  (match_operator 3 "even_relop"
487                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
488                                   (const_int 0)]))))
489    (clobber (match_operand:SI 5 "register_operand" "=r"))]
490   ""
491   [(set (match_dup 5)
492         (ior:CCEVEN (not:CC (match_dup 2))
493                 (match_dup 4)))
494    (set (match_dup 0)
495         (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
496   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
497   if (GET_CODE (operands[1])
498             == reverse_condition (GET_CODE (operands[3])))
499      ; 
500    else
501      {
502        /* Make the condition pairs line up by rotating the compare word.  */
503        int cv1 = condition_value (operands[1]);
504        int cv2 = condition_value (operands[3]);
506        operands[2] = gen_rtx_ROTATE (CCmode, operands[2],
507                                      GEN_INT (((cv1 & ~1) - (cv2 & ~1))
508                                               & 0x1f));
509      }")
511 (define_split
512   [(set (match_operand:SI 0 "register_operand" "=r")
513         (ior:SI (match_operator 1 "even_relop"
514                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
515                                  (const_int 0)])
516                 (match_operator 3 "relop"
517                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
518                                  (const_int 0)])))
519    (clobber (match_operand:SI 5 "register_operand" "=r"))]
520   "GET_CODE (operands[1]) == GET_CODE (operands[3])
521    || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
522   [(set (match_dup 5)
523         (ior:CCEVEN (match_dup 4)
524                 (match_dup 2)))
525    (set (match_dup 0)
526         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
527   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
528    /* Reverse the condition by complementing the compare word.  */
529    if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
530       operands[4] = gen_rtx_NOT (CCmode, operands[4]);")
532 (define_split
533   [(set (match_operand:SI 0 "register_operand" "=r")
534         (ior:SI (match_operator 1 "odd_relop"
535                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
536                                  (const_int 0)])
537                 (match_operator 3 "odd_relop"
538                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
539                                  (const_int 0)])))
540    (clobber (match_operand:SI 5 "register_operand" "=r"))]
541   "GET_CODE (operands[1]) == GET_CODE (operands[3])"
542   [(set (match_dup 5)
543         (and:CCEVEN (match_dup 4)
544                 (match_dup 2)))
545    (set (match_dup 0)
546         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
547   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
549 (define_split
550   [(set (match_operand:SI 0 "register_operand" "=r")
551         (ior:SI (match_operator 1 "odd_relop"
552                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
553                                  (const_int 0)])
554                 (match_operator 3 "even_relop"
555                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
556                                  (const_int 0)])))
557    (clobber (match_operand:SI 5 "register_operand" "=r"))]
558   "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
559   [(set (match_dup 5)
560         (ior:CCEVEN (not:CC (match_dup 4))
561                 (match_dup 2)))
562    (set (match_dup 0)
563         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
564   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
566 (define_split
567   [(set (match_operand:SI 0 "register_operand" "=r")
568         (and:SI (neg:SI 
569                  (match_operator 1 "even_relop"
570                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
571                                   (const_int 0)]))
572                 (neg:SI
573                  (match_operator 3 "relop"
574                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
575                                   (const_int 0)]))))
576    (clobber (match_operand:SI 5 "register_operand" "=r"))]
577   ""
578   [(set (match_dup 5)
579         (and:CCEVEN (match_dup 4)
580                 (match_dup 2)))
581    (set (match_dup 0)
582         (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
583   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
584    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
585      ; /* The conditions match.  */
586    else if (GET_CODE (operands[1])
587             == reverse_condition (GET_CODE (operands[3])))
588      /* Reverse the condition by complementing the compare word.  */
589      operands[4] = gen_rtx_NOT (CCmode, operands[4]);
590    else
591      {
592        /* Make the condition pairs line up by rotating the compare word.  */
593        int cv1 = condition_value (operands[1]);
594        int cv2 = condition_value (operands[3]);
595        operands[4] = gen_rtx_ROTATE (CCmode, operands[4],
596                                      GEN_INT (((cv2 & ~1) - (cv1 & ~1))
597                                               & 0x1f));
598        /* Reverse the condition if needed.  */
599        if ((cv1 & 1) != (cv2 & 1))
600          operands[4] = gen_rtx_NOT (CCmode, operands[4]);
601      }")
603 (define_split
604   [(set (match_operand:SI 0 "register_operand" "=r")
605         (and:SI (neg:SI 
606                  (match_operator 1 "odd_relop"
607                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
608                                   (const_int 0)]))
609                 (neg:SI
610                  (match_operator 3 "odd_relop"
611                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
612                                   (const_int 0)]))))
613    (clobber (match_operand:SI 5 "register_operand" "=r"))]
614   ""
615   [(set (match_dup 5)
616         (ior:CCEVEN (match_dup 4)
617                 (match_dup 2)))
618    (set (match_dup 0)
619         (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
620   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
621    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
622      ; /* The conditions match.  */
623    else
624      {
625        /* Make the condition pairs line up by rotating the compare word.  */
626        int cv1 = condition_value (operands[1]);
627        int cv2 = condition_value (operands[3]);
628        operands[4] = gen_rtx_ROTATE (CCmode, operands[4],
629                                      GEN_INT ((cv2 - cv1) & 0x1f));
630      }")
632 (define_split
633   [(set (match_operand:SI 0 "register_operand" "=r")
634         (and:SI (neg:SI 
635                  (match_operator 1 "odd_relop"
636                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
637                                   (const_int 0)]))
638                 (neg:SI
639                  (match_operator 3 "even_relop"
640                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
641                                   (const_int 0)]))))
642    (clobber (match_operand:SI 5 "register_operand" "=r"))]
643   ""
644   [(set (match_dup 5)
645         (and:CCEVEN (not:CC (match_dup 2))
646                 (match_dup 4)))
647    (set (match_dup 0)
648         (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
649   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
650    if (GET_CODE (operands[1])
651             == reverse_condition (GET_CODE (operands[3])))
652         ;
653    else
654      {
655        /* Make the condition pairs line up by rotating the compare word.  */
656        int cv1 = condition_value (operands[1]);
657        int cv2 = condition_value (operands[3]);
658        operands[2] = gen_rtx_ROTATE (CCmode, operands[2],
659                                      GEN_INT (((cv1 & ~1) - (cv2 & ~1))
660                                               & 0x1f));
661      }")
663 (define_split
664   [(set (match_operand:SI 0 "register_operand" "=r")
665         (and:SI (match_operator 1 "even_relop"
666                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
667                                  (const_int 0)])
668                 (match_operator 3 "relop"
669                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
670                                  (const_int 0)])))
671    (clobber (match_operand:SI 5 "register_operand" "=r"))]
672   "GET_CODE (operands[1]) == GET_CODE (operands[3])
673    || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
674   [(set (match_dup 5)
675         (and:CCEVEN (match_dup 4)
676                 (match_dup 2)))
677    (set (match_dup 0)
678         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
679   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
680    /* Reverse the condition by complementing the compare word.  */
681    if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
682       operands[4] = gen_rtx_NOT (CCmode, operands[4]);")
684 (define_split
685   [(set (match_operand:SI 0 "register_operand" "=r")
686         (and:SI (match_operator 1 "odd_relop"
687                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
688                                  (const_int 0)])
689                 (match_operator 3 "odd_relop"
690                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
691                                  (const_int 0)])))
692    (clobber (match_operand:SI 5 "register_operand" "=r"))]
693   "GET_CODE (operands[1]) == GET_CODE (operands[3])"
694   [(set (match_dup 5)
695         (ior:CCEVEN (match_dup 4)
696                 (match_dup 2)))
697    (set (match_dup 0)
698         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
699   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
701 (define_split
702   [(set (match_operand:SI 0 "register_operand" "=r")
703         (and:SI (match_operator 1 "odd_relop"
704                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
705                                  (const_int 0)])
706                 (match_operator 3 "even_relop"
707                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
708                                  (const_int 0)])))
709    (clobber (match_operand:SI 5 "register_operand" "=r"))]
710   "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
711   [(set (match_dup 5)
712         (and:CCEVEN (not:CC (match_dup 2))
713                 (match_dup 4)))
714    (set (match_dup 0)
715         (match_op_dup 3 [(match_dup 5) (const_int 0)]))]
716   "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
719 ;; Logical operations on compare words.
721 (define_insn ""
722   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
723         (and:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
724                 (match_operand 2 "partial_ccmode_register_operand" "r")))]
725   ""
726   "and.c %0,%2,%1")
728 (define_insn ""
729   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
730         (and:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
731                 (match_operand 2 "partial_ccmode_register_operand" "r")))]
732   ""
733   "and %0,%1,%2")
735 (define_insn ""
736   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
737         (ior:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
738                 (match_operand 2 "partial_ccmode_register_operand" "r")))]
739   ""
740   "or.c %0,%2,%1")
742 (define_insn ""
743   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
744         (ior:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
745                 (match_operand 2 "partial_ccmode_register_operand" "r")))]
746   ""
747   "or %0,%1,%2")
749 (define_insn ""
750   [(set (match_operand:CC 0 "register_operand" "=r")
751         (rotate:CC (match_operand:CC 1 "register_operand" "r")
752                    (match_operand:CC 2 "int5_operand" "")))]
753   ""
754   "rot %0,%1,%2"
755   [(set_attr "type" "bit")])
757 (define_insn ""
758   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
759         (rotate:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "r")
760                    (match_operand:CC 2 "int5_operand" "")))]
761   ""
762   "rot %0,%1,%2"
763   [(set_attr "type" "bit")])
765 ;; rotate/and[.c] and rotate/ior[.c]
767 (define_split
768   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
769         (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
770                            (match_operand:CC 2 "int5_operand" ""))
771                 (match_operand 3 "partial_ccmode_register_operand" "r")))
772    (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
773   ""
774   [(set (match_dup 4)
775         (rotate:CC (match_dup 1) (match_dup 2)))
776    (set (match_dup 0)
777         (ior:CCEVEN (match_dup 4) (match_dup 3)))]
778   "")
780 (define_insn ""
781   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
782         (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
783                            (match_operand:CC 2 "int5_operand" ""))
784                 (match_operand 3 "partial_ccmode_register_operand" "r")))
785    (clobber (match_scratch:CCEVEN 4 "=r"))]
786   ""
787   "#")
789 (define_split
790   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
791         (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
792                                    (match_operand:CC 2 "int5_operand" "")))
793                 (match_operand 3 "partial_ccmode_register_operand" "r")))
794    (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
795   ""
796   [(set (match_dup 4)
797         (rotate:CC (match_dup 1) (match_dup 2)))
798    (set (match_dup 0)
799         (ior:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
800   "")
802 (define_insn ""
803   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
804         (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
805                                    (match_operand:CC 2 "int5_operand" "")))
806                 (match_operand 3 "partial_ccmode_register_operand" "r")))
807    (clobber (match_scratch:CCEVEN 4 "=r"))]
808   ""
809   "#")
811 (define_split
812   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
813         (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
814                            (match_operand:CC 2 "int5_operand" ""))
815                 (match_operand 3 "partial_ccmode_register_operand" "r")))
816    (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
817   ""
818   [(set (match_dup 4)
819         (rotate:CC (match_dup 1) (match_dup 2)))
820    (set (match_dup 0)
821         (and:CCEVEN (match_dup 4) (match_dup 3)))]
822   "")
824 (define_insn ""
825   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
826         (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
827                            (match_operand:CC 2 "int5_operand" ""))
828                 (match_operand 3 "partial_ccmode_register_operand" "r")))
829    (clobber (match_scratch:CCEVEN 4 "=r"))]
830   ""
831   "#")
833 (define_split
834   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
835         (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
836                                    (match_operand:CC 2 "int5_operand" "")))
837                 (match_operand 3 "partial_ccmode_register_operand" "r")))
838    (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
839   ""
840   [(set (match_dup 4)
841         (rotate:CC (match_dup 1) (match_dup 2)))
842    (set (match_dup 0)
843         (and:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
844   "")
846 (define_insn ""
847   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
848         (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
849                                    (match_operand:CC 2 "int5_operand" "")))
850                 (match_operand 3 "partial_ccmode_register_operand" "r")))
851    (clobber (match_scratch:CCEVEN 4 "=r"))]
852   ""
853   "#")
856 ;; Recognize bcnd instructions for integer values.  This is distinguished
857 ;; from a conditional branch instruction (below) with SImode instead of
858 ;; CCmode.
860 (define_insn ""
861   [(set (pc)
862         (if_then_else
863          (match_operator 0 "relop_no_unsigned"
864                          [(match_operand:SI 1 "register_operand" "r")
865                           (const_int 0)])
866          (match_operand 2 "pc_or_label_ref" "")
867          (match_operand 3 "pc_or_label_ref" "")))]
868   ""
869   "bcnd%. %R3%B0,%1,%P2%P3"
870   [(set_attr "type" "branch")])
872 ;; Recognize tests for sign and zero.
874 (define_insn ""
875   [(set (pc)
876         (if_then_else
877          (match_operator 0 "equality_op"
878                          [(match_operand:SI 1 "register_operand" "r")
879                           (const_int -2147483648)])
880          (match_operand 2 "pc_or_label_ref" "")
881          (match_operand 3 "pc_or_label_ref" "")))]
882   ""
883   "bcnd%. %R3%E0,%1,%P2%P3"
884   [(set_attr "type" "branch")])
886 (define_insn ""
887   [(set (pc)
888         (if_then_else
889          (match_operator 0 "equality_op"
890                          [(zero_extract:SI
891                            (match_operand:SI 1 "register_operand" "r")
892                            (const_int 31)
893                            (const_int 1))
894                           (const_int 0)])
895          (match_operand 2 "pc_or_label_ref" "")
896          (match_operand 3 "pc_or_label_ref" "")))]
897   ""
898   "bcnd%. %R3%D0,%1,%P2%P3"
899   [(set_attr "type" "branch")])
901 ;; Recognize bcnd instructions for double integer values
903 (define_insn ""
904   [(set (pc)
905         (if_then_else
906          (match_operator 0 "relop_no_unsigned"
907                          [(sign_extend:DI
908                            (match_operand:SI 1 "register_operand" "r"))
909                           (const_int 0)])
910          (match_operand 2 "pc_or_label_ref" "")
911          (match_operand 3 "pc_or_label_ref" "")))]
912   ""
913   "bcnd%. %R3%B0,%1,%P2%P3"
914   [(set_attr "type" "branch")])
916 (define_insn ""
917   [(set (pc)
918         (if_then_else
919          (match_operator 0 "equality_op"
920                          [(zero_extend:DI
921                            (match_operand:SI 1 "register_operand" "r"))
922                           (const_int 0)])
923          (match_operand 2 "pc_or_label_ref" "")
924          (match_operand 3 "pc_or_label_ref" "")))]
925   ""
926   "bcnd%. %R3%B0,%1,%P2%P3"
927   [(set_attr "type" "branch")])
929 ; @@ I doubt this is interesting until cmpdi is provided.  Anyway, it needs
930 ; to be reworked.
932 ;(define_insn ""
933 ;  [(set (pc)
934 ;       (if_then_else
935 ;        (match_operator 0 "relop_no_unsigned"
936 ;                        [(match_operand:DI 1 "register_operand" "r")
937 ;                         (const_int 0)])
938 ;        (match_operand 2 "pc_or_label_ref" "")
939 ;        (match_operand 3 "pc_or_label_ref" "")))]
940 ;  ""
941 ;  "*
943 ;  switch (GET_CODE (operands[0]))
944 ;    {
945 ;    case EQ:
946 ;    case NE:
947 ;      /* I'm not sure if it's safe to use .n here.  */
948 ;      return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\";
949 ;    case GE:
950 ;    case LT:
951 ;      return \"bcnd%. %R3%B0,%1,%P2%P3\";
952 ;    case GT:
953 ;      {
954 ;       rtx op2 = operands[2];
955 ;       operands[2] = operands[3];
956 ;       operands[3] = op2;
957 ;      }
958 ;    case LE:
959 ;      if (GET_CODE (operands[3]) == LABEL_REF)
960 ;       {
961 ;         int label_num;
962 ;         operands[2] = gen_label_rtx ();
963 ;         label_num = XINT (operands[2], 3);
964 ;         output_asm_insn
965 ;           (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands);
966 ;         output_label (label_num);
967 ;         return \"\";
968 ;       }
969 ;      else
970 ;       return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\";
971 ;    }
972 ;}")
974 ;; Recognize bcnd instructions for single precision float values
975 ;; Exclude relational operations as they must signal NaNs.
977 ;; @@ These bcnd insns for float and double values don't seem to be recognized.
979 (define_insn ""
980   [(set (pc)
981         (if_then_else
982          (match_operator 0 "equality_op"
983                          [(float_extend:DF
984                            (match_operand:SF 1 "register_operand" "r"))
985                           (const_int 0)])
986          (match_operand 2 "pc_or_label_ref" "")
987          (match_operand 3 "pc_or_label_ref" "")))]
988   ""
989   "bcnd%. %R3%D0,%1,%P2%P3"
990   [(set_attr "type" "branch")])
992 (define_insn ""
993   [(set (pc)
994         (if_then_else
995          (match_operator 0 "equality_op"
996                          [(match_operand:SF 1 "register_operand" "r")
997                           (const_int 0)])
998          (match_operand 2 "pc_or_label_ref" "")
999          (match_operand 3 "pc_or_label_ref" "")))]
1000   ""
1001   "bcnd%. %R3%D0,%1,%P2%P3"
1002   [(set_attr "type" "branch")])
1004 ;; Recognize bcnd instructions for double precision float values
1005 ;; Exclude relational operations as they must signal NaNs.
1007 (define_insn ""
1008   [(set (pc)
1009         (if_then_else
1010          (match_operator 0 "equality_op"
1011                          [(match_operand:DF 1 "register_operand" "r")
1012                           (const_int 0)])
1013          (match_operand 2 "pc_or_label_ref" "")
1014          (match_operand 3 "pc_or_label_ref" "")))]
1015   ""
1016   "*
1018   int label_num;
1020   if (GET_CODE (operands[0]) == NE)
1021     {
1022       rtx op2 = operands[2];
1023       operands[2] = operands[3];
1024       operands[3] = op2;
1025     }
1026   if (GET_CODE (operands[3]) == LABEL_REF)
1027     return \"bcnd 0x5,%1,%3\;bcnd %#ne0,%d1,%3\";
1029   operands[3] = gen_label_rtx ();
1030   label_num = XINT (operands[3], 3);
1031   output_asm_insn (\"bcnd 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands);
1032   output_label (label_num);
1033   return \"\";
1035   [(set_attr "type" "weird")
1036    (set_attr "length" "3")])
1038 ;; Recognize bb0 and bb1 instructions.  These use two unusual template
1039 ;; patterns, %Lx and %Px.  %Lx outputs a 1 if operand `x' is a LABEL_REF
1040 ;; otherwise it outputs a 0.  It then may print ".n" if the delay slot
1041 ;; is used.  %Px does noting if `x' is PC and outputs the operand if `x'
1042 ;; is a LABEL_REF.
1044 (define_insn ""
1045   [(set (pc)
1046         (if_then_else
1047          (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1048                               (const_int 1)
1049                               (match_operand:SI 1 "int5_operand" ""))
1050              (const_int 0))
1051          (match_operand 2 "pc_or_label_ref" "")
1052          (match_operand 3 "pc_or_label_ref" "")))]
1053   ""
1054   "bb%L2 (31-%1),%0,%P2%P3"
1055   [(set_attr "type" "branch")])
1057 (define_insn ""
1058   [(set (pc)
1059         (if_then_else
1060          (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1061                               (const_int 1)
1062                               (match_operand:SI 1 "int5_operand" ""))
1063              (const_int 0))
1064          (match_operand 2 "pc_or_label_ref" "")
1065          (match_operand 3 "pc_or_label_ref" "")))]
1066   ""
1067   "bb%L3 (31-%1),%0,%P2%P3"
1068   [(set_attr "type" "branch")])
1070 (define_insn ""
1071   [(set (pc)
1072         (if_then_else
1073          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1074                               (const_int 1)
1075                               (match_operand:SI 1 "int5_operand" ""))
1076              (const_int 0))
1077          (match_operand 2 "pc_or_label_ref" "")
1078          (match_operand 3 "pc_or_label_ref" "")))]
1079   ""
1080   "bb%L2 (31-%1),%0,%P2%P3"
1081   [(set_attr "type" "branch")])
1083 (define_insn ""
1084   [(set (pc)
1085         (if_then_else
1086          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1087                               (const_int 1)
1088                               (match_operand:SI 1 "int5_operand" ""))
1089              (const_int 0))
1090          (match_operand 2 "pc_or_label_ref" "")
1091          (match_operand 3 "pc_or_label_ref" "")))]
1092   ""
1093   "bb%L3 (31-%1),%0,%P2%P3"
1094   [(set_attr "type" "branch")])
1096 (define_insn ""
1097   [(set (pc)
1098         (if_then_else
1099          (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1100                      (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1101               (const_int 0))
1102          (match_operand 2 "pc_or_label_ref" "")
1103          (match_operand 3 "pc_or_label_ref" "")))]
1104   "(GET_CODE (operands[0]) == CONST_INT)
1105    != (GET_CODE (operands[1]) == CONST_INT)"
1106   "bb%L3 %p1,%0,%P2%P3"
1107   [(set_attr "type" "branch")])
1109 (define_insn ""
1110   [(set (pc)
1111         (if_then_else
1112          (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1113                      (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1114              (const_int 0))
1115          (match_operand 2 "pc_or_label_ref" "")
1116          (match_operand 3 "pc_or_label_ref" "")))]
1117   "(GET_CODE (operands[0]) == CONST_INT)
1118    != (GET_CODE (operands[1]) == CONST_INT)"
1119   "bb%L2 %p1,%0,%P2%P3"
1120   [(set_attr "type" "branch")])
1122 ;; The comparison operations store the comparison into a register and
1123 ;; record that register.  The following Bxx or Sxx insn uses that
1124 ;; register as an input.  To facilitate use of bcnd instead of cmp/bb1,
1125 ;; cmpsi records its operands and produces no code when any operand
1126 ;; is constant.  In this case, the Bxx insns use gen_bcnd and the
1127 ;; Sxx insns use gen_test to ensure a cmp has been emitted.
1129 ;; This could also be done for SFmode and DFmode having only beq and bne
1130 ;; use gen_bcnd.  The others must signal NaNs.  It seems though that zero
1131 ;; has already been copied into a register.
1133 ;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand
1134 ;; is a constant.  (This idea is due to Torbjorn Granlund.)  Others can
1135 ;; use bcnd only if an operand is zero.
1137 ;; It is necessary to distinguish a register holding condition codes.
1138 ;; This is done by context.
1140 (define_expand "test"
1141   [(set (match_dup 2)
1142         (compare:CC (match_operand 0 "" "")
1143                     (match_operand 1 "" "")))]
1144   ""
1145   "
1147   if (m88k_compare_reg)
1148     abort ();
1150   if (GET_CODE (operands[0]) == CONST_INT
1151       && ! SMALL_INT (operands[0]))
1152     operands[0] = force_reg (SImode, operands[0]);
1154   if (GET_CODE (operands[1]) == CONST_INT
1155       && ! SMALL_INT (operands[1]))
1156     operands[1] = force_reg (SImode, operands[1]);
1158   operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1161 ; @@ The docs say don't do this.  It's probably a nop since the insn looks
1162 ; identical to cmpsi against zero.  Is there an advantage to providing
1163 ; this, perhaps with a different form?
1165 ;(define_expand "tstsi"
1166 ;  [(set (match_dup 1)
1167 ;       (compare:CC (match_operand:SI 0 "register_operand" "")
1168 ;                   (const_int 0)))]
1169 ; ""
1170 ; "
1172 ;  m88k_compare_reg = 0;
1173 ;  m88k_compare_op0 = operands[0];
1174 ;  m88k_compare_op1 = const0_rtx;
1175 ;  DONE;
1176 ;}")
1178 (define_expand "cmpsi"
1179   [(set (match_dup 2)
1180         (compare:CC (match_operand:SI 0 "register_operand" "")
1181                     (match_operand:SI 1 "arith32_operand" "")))]
1182   ""
1183   "
1185   if (GET_CODE (operands[0]) == CONST_INT
1186       || GET_CODE (operands[1]) == CONST_INT)
1187     {
1188       m88k_compare_reg = 0;
1189       m88k_compare_op0 = operands[0];
1190       m88k_compare_op1 = operands[1];
1191       DONE;
1192     }
1193   operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1196 (define_expand "cmpsf"
1197   [(set (match_dup 2)
1198         (compare:CC (match_operand:SF 0 "register_operand" "")
1199                     (match_operand:SF 1 "register_operand" "")))]
1200   ""
1201   "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")
1203 (define_expand "cmpdf"
1204   [(set (match_dup 2)
1205         (compare:CC (match_operand:DF 0 "general_operand" "")
1206                     (match_operand:DF 1 "general_operand" "")))]
1207   ""
1208   "
1210   operands[0] = legitimize_operand (operands[0], DFmode);
1211   operands[1] = legitimize_operand (operands[1], DFmode);
1212   operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1215 ; @@ Get back to this later on.
1217 ;(define_insn "cmpdi"
1218 ;  [(set (cc0)
1219 ;       (compare:CC (match_operand:DI 0 "register_operand" "r")
1220 ;                   (match_operand:DI 1 "register_operand" "r")))]
1221 ;  ""
1222 ;  "*
1224 ;  if ((cc_status.mdep & MDEP_LS_CHANGE) != 0)
1225 ;    abort ();  /* output_move_double MDEP_LS_CHANGE bits were set. */
1227 ;  cc_status.mdep &= ~ MDEP_LS_MASK;
1229 ;  operands[2] = gen_label_rtx ();
1230 ;  /* Remember, %! is the condition code register and %@ is the
1231 ;     literal synthesis register.  */
1233 ;  output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\",
1234 ;                  operands);
1236 ;  output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands);
1237 ;  output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands);
1238 ;  output_label (XINT (operands[2], 3));
1239 ;  return \"\";
1242 ;; The actual compare instructions.
1244 (define_insn ""
1245   [(set (match_operand:CC 0 "register_operand" "=r")
1246         (compare:CC (match_operand:SI 1 "register_operand" "rO")
1247                     (match_operand:SI 2 "arith_operand" "rI")))]
1248   ""
1249   "cmp %0,%r1,%2")
1251 (define_insn ""
1252   [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1253         (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x")
1254                     (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))]
1255   ""
1256   "@
1257    fcmp.sss %0,%1,%2
1258    fcmp.sss %0,%1,%#r0
1259    fcmp.sss %0,%1,%2
1260    fcmp.sss %0,%1,%#x0"
1261   [(set_attr "type" "spcmp")])
1263 (define_insn ""
1264   [(set (match_operand:CC 0 "register_operand" "=r,r")
1265         (compare:CC (match_operand:DF 1 "register_operand" "r,x")
1266                     (float_extend:DF
1267                      (match_operand:SF 2 "register_operand" "r,x"))))]
1268   ""
1269   "fcmp.sds %0,%1,%2"
1270   [(set_attr "type" "dpcmp")])
1272 (define_insn ""
1273   [(set (match_operand:CC 0 "register_operand" "=r,r")
1274         (compare:CC (float_extend:DF
1275                      (match_operand:SF 1 "register_operand" "r,x"))
1276                     (match_operand:DF 2 "register_operand" "r,x")))]
1277   ""
1278   "fcmp.ssd %0,%1,%2"
1279   [(set_attr "type" "dpcmp")])
1281 (define_insn ""
1282   [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1283         (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x")
1284                     (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))]
1285   ""
1286   "@
1287    fcmp.sdd %0,%1,%2
1288    fcmp.sds %0,%1,%#r0
1289    fcmp.sdd %0,%1,%2
1290    fcmp.sds %0,%1,%#x0"
1291   [(set_attr "type" "dpcmp")])
1293 ;; Store condition code insns.  The compare insns set a register
1294 ;; rather than cc0 and record that register for use here.  See above
1295 ;; for the special treatment of cmpsi with a constant operand.
1297 ;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons.
1299 (define_expand "seq"
1300   [(set (match_operand:SI 0 "register_operand" "")
1301         (match_dup 1))]
1302   ""
1303   "operands[1] = emit_test (EQ, SImode);")
1305 (define_expand "sne"
1306   [(set (match_operand:SI 0 "register_operand" "")
1307         (match_dup 1))]
1308   ""
1309   "operands[1] = emit_test (NE, SImode);")
1311 (define_expand "sgt"
1312   [(set (match_operand:SI 0 "register_operand" "")
1313         (match_dup 1))]
1314   ""
1315   "operands[1] = emit_test (GT, SImode);")
1317 (define_expand "sgtu"
1318   [(set (match_operand:SI 0 "register_operand" "")
1319         (match_dup 1))]
1320   ""
1321   "operands[1] = emit_test (GTU, SImode);")
1323 (define_expand "slt"
1324   [(set (match_operand:SI 0 "register_operand" "")
1325         (match_dup 1))]
1326   ""
1327   "operands[1] = emit_test (LT, SImode);")
1329 (define_expand "sltu"
1330   [(set (match_operand:SI 0 "register_operand" "")
1331         (match_dup 1))]
1332   ""
1333   "operands[1] = emit_test (LTU, SImode);")
1335 (define_expand "sge"
1336   [(set (match_operand:SI 0 "register_operand" "")
1337         (match_dup 1))]
1338   ""
1339   "operands[1] = emit_test (GE, SImode);")
1341 (define_expand "sgeu"
1342   [(set (match_operand:SI 0 "register_operand" "")
1343         (match_dup 1))]
1344   ""
1345   "operands[1] = emit_test (GEU, SImode);")
1347 (define_expand "sle"
1348   [(set (match_operand:SI 0 "register_operand" "")
1349         (match_dup 1))]
1350   ""
1351   "operands[1] = emit_test (LE, SImode);")
1353 (define_expand "sleu"
1354   [(set (match_operand:SI 0 "register_operand" "")
1355         (match_dup 1))]
1356   ""
1357   "operands[1] = emit_test (LEU, SImode);")
1359 ;; The actual set condition code instruction.
1361 (define_insn ""
1362   [(set (match_operand:SI 0 "register_operand" "=r")
1363         (match_operator:SI 1 "relop"
1364                            [(match_operand:CC 2 "register_operand" "r")
1365                             (const_int 0)]))]
1366   ""
1367   "ext %0,%2,1<%C1>"
1368   [(set_attr "type" "bit")])
1370 (define_insn ""
1371   [(set (match_operand:SI 0 "register_operand" "=r")
1372         (match_operator:SI 1 "even_relop"
1373                            [(match_operand:CCEVEN 2 "register_operand" "r")
1374                             (const_int 0)]))]
1375   ""
1376   "ext %0,%2,1<%C1>"
1377   [(set_attr "type" "bit")])
1379 (define_insn ""
1380   [(set (match_operand:SI 0 "register_operand" "=r")
1381         (not:SI (match_operator:SI 1 "odd_relop"
1382                            [(match_operand:CCEVEN 2 "register_operand" "r")
1383                             (const_int 0)])))]
1384   ""
1385   "ext %0,%2,1<%!%C1>"
1386   [(set_attr "type" "bit")])
1388 (define_split
1389   [(set (match_operand:SI 0 "register_operand" "=r")
1390         (match_operator:SI 1 "odd_relop"
1391                            [(match_operand:CCEVEN 2 "register_operand" "r")
1392                             (const_int 0)]))
1393    (clobber (match_operand:SI 3 "register_operand" "=r"))]
1394   ""
1395   [(set (match_dup 3) (not:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])))
1396    (set (match_dup 0) (not:SI (match_dup 3)))]
1397   "")
1399 (define_insn ""
1400   [(set (match_operand:SI 0 "register_operand" "=r")
1401         (match_operator:SI 1 "odd_relop"
1402                            [(match_operand:CCEVEN 2 "register_operand" "r")
1403                             (const_int 0)]))
1404    (clobber (match_scratch:SI 3 "=r"))]
1405   ""
1406   "#")
1408 (define_insn ""
1409   [(set (match_operand:SI 0 "register_operand" "=r")
1410         (neg:SI
1411          (match_operator:SI 1 "relop"
1412                             [(match_operand:CC 2 "register_operand" "r")
1413                              (const_int 0)])))]
1414   ""
1415   "extu %0,%2,1<%C1>"
1416   [(set_attr "type" "bit")])
1418 (define_insn ""
1419   [(set (match_operand:SI 0 "register_operand" "=r")
1420         (neg:SI
1421          (match_operator:SI 1 "even_relop"
1422                             [(match_operand:CCEVEN 2 "register_operand" "r")
1423                              (const_int 0)])))]
1424   ""
1425   "extu %0,%2,1<%C1>"
1426   [(set_attr "type" "bit")])
1428 (define_insn ""
1429   [(set (match_operand:SI 0 "register_operand" "=r")
1430         (neg:SI
1431          (not:SI (match_operator:SI 1 "odd_relop"
1432                             [(match_operand:CCEVEN 2 "register_operand" "r")
1433                              (const_int 0)]))))]
1434   ""
1435   "extu %0,%2,1<%!%C1>"
1436   [(set_attr "type" "bit")])
1438 (define_split
1439   [(set (match_operand:SI 0 "register_operand" "=r")
1440         (neg:SI (match_operator:SI 1 "odd_relop"
1441                            [(match_operand:CCEVEN 2 "register_operand" "r")
1442                             (const_int 0)])))
1443    (clobber (match_operand:SI 3 "register_operand" "=r"))]
1444   ""
1445   [(set (match_dup 3) (neg:SI (not:SI (match_op_dup 1 [(match_dup 2)
1446                                                        (const_int 0)]))))
1447    (set (match_dup 0) (xor:SI (match_dup 3) (const_int 1)))]
1448   "")
1450 (define_insn
1451  ""
1452   [(set (match_operand:SI 0 "register_operand" "=r")
1453         (neg:SI (match_operator:SI 1 "odd_relop"
1454                            [(match_operand:CCEVEN 2 "register_operand" "r")
1455                             (const_int 0)])))
1456    (clobber (match_scratch:SI 3 "=r"))]
1457   ""
1458   "#")
1463 ;; Conditional branch insns.  The compare insns set a register
1464 ;; rather than cc0 and record that register for use here.  See above
1465 ;; for the special case of cmpsi with a constant operand.
1467 (define_expand "bcnd"
1468   [(set (pc)
1469         (if_then_else (match_operand 0 "" "")
1470                       (label_ref (match_operand 1 "" ""))
1471                       (pc)))]
1472   ""
1473   "if (m88k_compare_reg) abort ();")
1475 (define_expand "bxx"
1476   [(set (pc)
1477         (if_then_else (match_operand 0 "" "")
1478                       (label_ref (match_operand 1 "" ""))
1479                       (pc)))]
1480   ""
1481   "if (m88k_compare_reg == 0) abort ();")
1483 (define_expand "beq"
1484   [(set (pc)
1485         (if_then_else (eq (match_dup 1) (const_int 0))
1486                       (label_ref (match_operand 0 "" ""))
1487                       (pc)))]
1488   ""
1489   "if (m88k_compare_reg == 0)
1490      {
1491        emit_bcnd (EQ, operands[0]);
1492        DONE;
1493      }
1494    operands[1] = m88k_compare_reg;")
1496 (define_expand "bne"
1497   [(set (pc)
1498         (if_then_else (ne (match_dup 1) (const_int 0))
1499                       (label_ref (match_operand 0 "" ""))
1500                       (pc)))]
1501   ""
1502   "if (m88k_compare_reg == 0)
1503      {
1504        emit_bcnd (NE, operands[0]);
1505        DONE;
1506      }
1507    operands[1] = m88k_compare_reg;")
1509 (define_expand "bgt"
1510   [(set (pc)
1511         (if_then_else (gt (match_dup 1) (const_int 0))
1512                       (label_ref (match_operand 0 "" ""))
1513                       (pc)))]
1514   ""
1515   "if (m88k_compare_reg == 0)
1516      {
1517        emit_bcnd (GT, operands[0]);
1518        DONE;
1519      }
1520    operands[1] = m88k_compare_reg;")
1522 (define_expand "bgtu"
1523   [(set (pc)
1524         (if_then_else (gtu (match_dup 1) (const_int 0))
1525                       (label_ref (match_operand 0 "" ""))
1526                       (pc)))]
1527   ""
1528   "if (m88k_compare_reg == 0)
1529      {
1530        emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0]));
1531        DONE;
1532      }
1533    operands[1] = m88k_compare_reg;")
1535 (define_expand "blt"
1536   [(set (pc)
1537         (if_then_else (lt (match_dup 1) (const_int 0))
1538                       (label_ref (match_operand 0 "" ""))
1539                       (pc)))]
1540   ""
1541   "if (m88k_compare_reg == 0)
1542      {
1543        emit_bcnd (LT, operands[0]);
1544        DONE;
1545      }
1546    operands[1] = m88k_compare_reg;")
1548 (define_expand "bltu"
1549   [(set (pc)
1550         (if_then_else (ltu (match_dup 1) (const_int 0))
1551                       (label_ref (match_operand 0 "" ""))
1552                       (pc)))]
1553   ""
1554   "if (m88k_compare_reg == 0)
1555      {
1556        emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0]));
1557        DONE;
1558      }
1559    operands[1] = m88k_compare_reg;")
1561 (define_expand "bge"
1562   [(set (pc)
1563         (if_then_else (ge (match_dup 1) (const_int 0))
1564                       (label_ref (match_operand 0 "" ""))
1565                       (pc)))]
1566   ""
1567   "if (m88k_compare_reg == 0)
1568      {
1569        emit_bcnd (GE, operands[0]);
1570        DONE;
1571      }
1572    operands[1] = m88k_compare_reg;")
1574 (define_expand "bgeu"
1575   [(set (pc)
1576         (if_then_else (geu (match_dup 1) (const_int 0))
1577                       (label_ref (match_operand 0 "" ""))
1578                       (pc)))]
1579   ""
1580   "if (m88k_compare_reg == 0)
1581      {
1582        emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0]));
1583        DONE;
1584      }
1585    operands[1] = m88k_compare_reg;")
1587 (define_expand "ble"
1588   [(set (pc)
1589         (if_then_else (le (match_dup 1) (const_int 0))
1590                       (label_ref (match_operand 0 "" ""))
1591                       (pc)))]
1592   ""
1593   "if (m88k_compare_reg == 0)
1594      {
1595        emit_bcnd (LE, operands[0]);
1596        DONE;
1597      }
1598    operands[1] = m88k_compare_reg;")
1600 (define_expand "bleu"
1601   [(set (pc)
1602         (if_then_else (leu (match_dup 1) (const_int 0))
1603                       (label_ref (match_operand 0 "" ""))
1604                       (pc)))]
1605   ""
1606   "if (m88k_compare_reg == 0)
1607      {
1608        emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0]));
1609        DONE;
1610      }
1611    operands[1] = m88k_compare_reg;")
1613 ;; The actual conditional branch instruction (both directions).  This
1614 ;; uses two unusual template patterns, %Rx and %Px.  %Rx is a prefix code
1615 ;; for the immediately following condition and reverses the condition iff
1616 ;; operand `x' is a LABEL_REF.  %Px does nothing if `x' is PC and outputs
1617 ;; the operand if `x' is a LABEL_REF.
1619 (define_insn ""
1620   [(set (pc) (if_then_else
1621               (match_operator 0 "relop"
1622                               [(match_operand:CC 1 "register_operand" "r")
1623                                (const_int 0)])
1624               (match_operand 2 "pc_or_label_ref" "")
1625               (match_operand 3 "pc_or_label_ref" "")))]
1626   ""
1627   "*
1629   if (mostly_false_jump (insn, operands[0]))
1630     return \"bb0%. %R2%C0,%1,%P2%P3\";
1631   else
1632     return \"bb1%. %R3%C0,%1,%P2%P3\";
1634   [(set_attr "type" "branch")])
1637 ;; Here branch prediction is sacrificed. To get it back, you need 
1638 ;;  - CCODD (CC mode where the ODD bits are valid)
1639 ;;  - several define_split that can apply De Morgan's Law.
1640 ;;  - transformations between CCEVEN and CCODD modes. 
1641 ;;  
1643 (define_insn ""
1644   [(set (pc) (if_then_else
1645               (match_operator 0 "even_relop"
1646                               [(match_operand:CCEVEN 1 "register_operand" "r")
1647                                (const_int 0)])
1648               (match_operand 2 "pc_or_label_ref" "")
1649               (match_operand 3 "pc_or_label_ref" "")))]
1650   ""
1651   "bb%L2%. %C0,%1,%P2%P3"
1652   [(set_attr "type" "branch")])
1654 (define_insn ""
1655   [(set (pc) (if_then_else
1656               (match_operator 0 "odd_relop"
1657                               [(match_operand:CCEVEN 1 "register_operand" "r")
1658                                (const_int 0)])
1659               (match_operand 2 "pc_or_label_ref" "")
1660               (match_operand 3 "pc_or_label_ref" "")))]
1661   ""
1662   "bb%L3%. %!%C0,%1,%P2%P3"
1663   [(set_attr "type" "branch")])
1665 ;; Branch conditional on scc values.  These arise from manipulations on
1666 ;; compare words above.
1667 ;; Are these really used ? 
1669 (define_insn ""
1670   [(set (pc)
1671         (if_then_else
1672          (ne (match_operator 0 "relop"
1673                              [(match_operand:CC 1 "register_operand" "r")
1674                               (const_int 0)])
1675              (const_int 0))
1676          (match_operand 2 "pc_or_label_ref" "")
1677          (match_operand 3 "pc_or_label_ref" "")))]
1678   ""
1679   "bb%L2 %C0,%1,%P2%P3"
1680   [(set_attr "type" "branch")])
1682 (define_insn ""
1683   [(set (pc)
1684         (if_then_else
1685          (ne (match_operator 0 "even_relop"
1686                              [(match_operand:CCEVEN 1 "register_operand" "r")
1687                               (const_int 0)])
1688              (const_int 0))
1689          (match_operand 2 "pc_or_label_ref" "")
1690          (match_operand 3 "pc_or_label_ref" "")))]
1691   ""
1692   "bb%L2 %C0,%1,%P2%P3"
1693   [(set_attr "type" "branch")])
1695 (define_insn ""
1696   [(set (pc)
1697         (if_then_else
1698          (ne (match_operator 0 "odd_relop"
1699                              [(match_operand:CCEVEN 1 "register_operand" "r")
1700                               (const_int 0)])
1701              (const_int 0))
1702          (match_operand 2 "pc_or_label_ref" "")
1703          (match_operand 3 "pc_or_label_ref" "")))]
1704   ""
1705   "bb%L3 %!%C0,%1,%P2%P3"
1706   [(set_attr "type" "branch")])
1708 (define_insn ""
1709   [(set (pc)
1710         (if_then_else
1711          (eq (match_operator 0 "relop"
1712                              [(match_operand:CC 1 "register_operand" "r")
1713                               (const_int 0)])
1714              (const_int 0))
1715          (match_operand 2 "pc_or_label_ref" "")
1716          (match_operand 3 "pc_or_label_ref" "")))]
1717   ""
1718   "bb%L3 %C0,%1,%P2%P3"
1719   [(set_attr "type" "branch")])
1721 (define_insn ""
1722   [(set (pc)
1723         (if_then_else
1724          (eq (match_operator 0 "even_relop"
1725                              [(match_operand:CCEVEN 1 "register_operand" "r")
1726                               (const_int 0)])
1727              (const_int 0))
1728          (match_operand 2 "pc_or_label_ref" "")
1729          (match_operand 3 "pc_or_label_ref" "")))]
1730   ""
1731   "bb%L3 %C0,%1,%P2%P3"
1732   [(set_attr "type" "branch")])
1734 (define_insn ""
1735   [(set (pc)
1736         (if_then_else
1737          (eq (match_operator 0 "odd_relop"
1738                              [(match_operand:CCEVEN 1 "register_operand" "r")
1739                               (const_int 0)])
1740              (const_int 0))
1741          (match_operand 2 "pc_or_label_ref" "")
1742          (match_operand 3 "pc_or_label_ref" "")))]
1743   ""
1744   "bb%L2 %!%C0,%1,%P2%P3"
1745   [(set_attr "type" "branch")])
1747 (define_insn "locate1"
1748   [(set (match_operand:SI 0 "register_operand" "=r")
1749         (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] 0)))]
1750   ""
1751   "or.u %0,%#r0,%#hi16(%1#abdiff)")
1753 (define_insn "locate2"
1754   [(parallel [(set (reg:SI 1) (pc))
1755               (set (match_operand:SI 0 "register_operand" "=r")
1756                    (lo_sum:SI (match_dup 0)
1757                               (unspec:SI
1758                                [(label_ref (match_operand 1 "" ""))] 0)))])]
1759   ""
1760   "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:"
1761   [(set_attr "length" "2")])
1763 ;; SImode move instructions
1765 (define_expand "movsi"
1766   [(set (match_operand:SI 0 "general_operand" "")
1767         (match_operand:SI 1 "general_operand" ""))]
1768   ""
1769   "
1771   if (emit_move_sequence (operands, SImode, 0))
1772     DONE;
1775 (define_expand "reload_insi"
1776   [(set (match_operand:SI 0 "register_operand" "=r")
1777         (match_operand:SI 1 "general_operand" ""))
1778    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1779   ""
1780   "
1782   if (emit_move_sequence (operands, SImode, operands[2]))
1783     DONE;
1785   /* We don't want the clobber emitted, so handle this ourselves.  */
1786   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1787   DONE;
1790 (define_insn ""
1791   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m")
1792         (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))]
1793   "(register_operand (operands[0], SImode)
1794     || register_operand (operands[1], SImode)
1795     || operands[1] == const0_rtx)"
1796   "@
1797    or %0,%#r0,%1
1798    %V1ld\\t %0,%1
1799    %v0st\\t %r1,%0
1800    subu %0,%#r0,%n1
1801    set %0,%#r0,%s1
1802    mov.s %0,%1
1803    mov.s %0,%1
1804    mov %0,%1
1805    %V1ld\\t %0,%1
1806    %v0st\\t %1,%0"
1807   [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")])
1809 (define_insn ""
1810   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1811         (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))]
1812   ""
1813   "@
1814    or %0,%#r0,%1
1815    subu %0,%#r0,%n1
1816    or.u %0,%#r0,%X1
1817    set %0,%#r0,%s1
1818    or.u %0,%#r0,%X1\;or %0,%0,%x1"
1819   [(set_attr "type" "arith,arith,arith,bit,marith")])
1821 ;; @@ Why the constraint "in"?  Doesn't `i' include `n'?
1822 (define_insn ""
1823   [(set (match_operand:SI 0 "register_operand" "=r")
1824         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1825                    (match_operand:SI 2 "immediate_operand" "in")))]
1826   ""
1827   "or %0,%1,%#lo16(%g2)")
1829 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1830 ;; confuse them with real addresses.
1831 (define_insn ""
1832   [(set (match_operand:SI 0 "register_operand" "=r")
1833         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1834                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1835   ""
1836   "or %0,%1,%#lo16(%g2)"
1837   ;; Need to set length for this arith insn because operand2
1838   ;; is not an "arith_operand".
1839   [(set_attr "length" "1")])
1841 (define_insn ""
1842   [(set (match_operand:SI 0 "register_operand" "=r")
1843         (high:SI (match_operand 1 "" "")))]
1844   ""
1845   "or.u %0,%#r0,%#hi16(%g1)")
1847 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1848 ;; confuse them with real addresses.
1849 (define_insn ""
1850   [(set (match_operand:SI 0 "register_operand" "=r")
1851         (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1852   ""
1853   "or.u %0,%#r0,%#hi16(%g1)"
1854   ;; Need to set length for this arith insn because operand2
1855   ;; is not an arith_operand.
1856   [(set_attr "length" "1")])
1858 ;; HImode move instructions
1860 (define_expand "movhi"
1861   [(set (match_operand:HI 0 "general_operand" "")
1862         (match_operand:HI 1 "general_operand" ""))]
1863   ""
1864   "
1866   if (emit_move_sequence (operands, HImode, 0))
1867     DONE;
1870 (define_insn ""
1871   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
1872         (match_operand:HI 1 "move_operand" "rP,m,rO,N"))]
1873   "(register_operand (operands[0], HImode)
1874     || register_operand (operands[1], HImode)
1875     || operands[1] == const0_rtx)"
1876   "@
1877    or %0,%#r0,%h1
1878    %V1ld.hu\\t %0,%1
1879    %v0st.h\\t %r1,%0
1880    subu %0,%#r0,%H1"
1881   [(set_attr "type" "arith,load,store,arith")])
1883 (define_insn ""
1884   [(set (match_operand:HI 0 "register_operand" "=r")
1885         (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1886                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
1887   "!flag_pic"
1888   "or %0,%1,%#lo16(%2)")
1890 ;; QImode move instructions
1892 (define_expand "movqi"
1893   [(set (match_operand:QI 0 "general_operand" "")
1894         (match_operand:QI 1 "general_operand" ""))]
1895   ""
1896   "
1898   if (emit_move_sequence (operands, QImode, 0))
1899     DONE;
1902 (define_insn ""
1903   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
1904         (match_operand:QI 1 "move_operand" "rP,m,rO,N"))]
1905   "(register_operand (operands[0], QImode)
1906     || register_operand (operands[1], QImode)
1907     || operands[1] == const0_rtx)"
1908   "@
1909    or %0,%#r0,%q1
1910    %V1ld.bu\\t %0,%1
1911    %v0st.b\\t %r1,%0
1912    subu %r0,%#r0,%Q1"
1913   [(set_attr "type" "arith,load,store,arith")])
1915 (define_insn ""
1916   [(set (match_operand:QI 0 "register_operand" "=r")
1917         (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1918                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
1919   "!flag_pic"
1920   "or %0,%1,%#lo16(%2)")
1922 ;; DImode move instructions
1924 (define_expand "movdi"
1925   [(set (match_operand:DI 0 "general_operand" "")
1926         (match_operand:DI 1 "general_operand" ""))]
1927   ""
1928   "
1930   if (emit_move_sequence (operands, DImode, 0))
1931     DONE;
1934 (define_insn ""
1935   [(set (match_operand:DI 0 "register_operand" "=r,x")
1936         (const_int 0))]
1937   ""
1938   "@
1939    or %0,%#r0,0\;or %d0,%#r0,0
1940    mov %0,%#x0"
1941   [(set_attr "type" "marith,mov")])
1943 (define_insn ""
1944   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m")
1945         (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))]
1946   ""
1947   "@
1948    or %0,%#r0,%1\;or %d0,%#r0,%d1
1949    %V1ld.d\\t %0,%1
1950    %v0st.d\\t %1,%0
1951    mov.d %0,%1
1952    mov.d %0,%1
1953    mov %0,%1
1954    %V1ld.d\\t %0,%1
1955    %v0st.d\\t %1,%0"
1956   [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
1958 (define_insn ""
1959   [(set (match_operand:DI 0 "register_operand" "=r")
1960         (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1961                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
1962   "!flag_pic"
1963   "or %0,%1,%#lo16(%2)")
1965 (define_insn ""
1966   [(set (match_operand:DI 0 "register_operand" "=r")
1967         (match_operand:DI 1 "immediate_operand" "n"))]
1968    ""
1969    "* return output_load_const_dimode (operands);"
1970   [(set_attr "type" "marith")
1971    (set_attr "length" "4")]) ; length is 2, 3 or 4.
1973 ;; DFmode move instructions
1975 (define_expand "movdf"
1976   [(set (match_operand:DF 0 "general_operand" "")
1977         (match_operand:DF 1 "general_operand" ""))]
1978   ""
1979   "
1981   if (emit_move_sequence (operands, DFmode, 0))
1982     DONE;
1985 (define_split
1986   [(set (match_operand:DF 0 "register_operand" "=r")
1987         (match_operand:DF 1 "register_operand" "r"))]
1988   "reload_completed
1989    && GET_CODE (operands[0]) == REG && !XRF_REGNO_P (REGNO (operands[0]))
1990    && GET_CODE (operands[1]) == REG && !XRF_REGNO_P (REGNO (operands[1]))"
1991   [(set (match_dup 2) (match_dup 3))
1992    (set (match_dup 4) (match_dup 5))]
1993   "
1994 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1995   operands[3] = operand_subword (operands[1], 0, 0, DFmode);
1996   operands[4] = operand_subword (operands[0], 1, 0, DFmode);
1997   operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
1999 ;; @@ This pattern is incomplete and doesn't appear necessary.
2001 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2002 ;; to be reloaded by putting the constant into memory.
2003 ;; It must come before the more general movdf pattern.
2005 ;(define_insn ""
2006 ;  [(set (match_operand:DF 0 "general_operand" "=r,o")
2007 ;       (match_operand:DF 1 "" "G,G"))]
2008 ;  "GET_CODE (operands[1]) == CONST_DOUBLE"
2009 ;  "*
2011 ;  switch (which_alternative)
2012 ;    {
2013 ;    case 0:
2014 ;      return \"or %0,%#r0,0\;or %d0,%#r0,0\";
2015 ;    case 1:
2016 ;      operands[1] = adjust_address (operands[0], SImode, 4);
2017 ;      return \"%v0st\\t %#r0,%0\;st %#r0,%1\";
2018 ;    }
2019 ;}")
2021 (define_insn ""
2022   [(set (match_operand:DF 0 "register_operand" "=r,x")
2023         (const_int 0))]
2024   ""
2025   "@
2026    or %0,%#r0,0\;or %d0,%#r0,0
2027    mov %0,%#x0"
2028   [(set_attr "type" "marith,mov")])
2030 (define_insn ""
2031   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2032         (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2033   ""
2034   "@
2035    or %0,%#r0,%1\;or %d0,%#r0,%d1
2036    %V1ld.d\\t %0,%1
2037    %v0st.d\\t %1,%0
2038    mov.d %0,%1
2039    mov.d %0,%1
2040    mov %0,%1
2041    %V1ld.d\\t %0,%1
2042    %v0st.d\\t %1,%0"
2043   [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
2045 (define_insn ""
2046   [(set (match_operand:DF 0 "register_operand" "=r")
2047         (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2048                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
2049   "!flag_pic"
2050   "or %0,%1,%#lo16(%2)")
2052 (define_insn ""
2053   [(set (match_operand:DF 0 "register_operand" "=r")
2054         (match_operand:DF 1 "immediate_operand" "F"))]
2055    ""
2056    "* return output_load_const_double (operands);"
2057   [(set_attr "type" "marith")
2058    (set_attr "length" "4")]) ; length is 2, 3, or 4.
2060 ;; SFmode move instructions
2062 (define_expand "movsf"
2063   [(set (match_operand:SF 0 "general_operand" "")
2064         (match_operand:SF 1 "general_operand" ""))]
2065   ""
2066   "
2068   if (emit_move_sequence (operands, SFmode, 0))
2069     DONE;
2072 ;; @@ What happens to fconst0_rtx?
2073 (define_insn ""
2074   [(set (match_operand:SF 0 "register_operand" "=r,x")
2075         (const_int 0))]
2076   ""
2077   "@
2078    or %0,%#r0,0
2079    mov %0,%#x0"
2080   [(set_attr "type" "arith,mov")])
2082 (define_insn ""
2083   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2084         (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2085   ""
2086   "@
2087    or %0,%#r0,%1
2088    %V1ld\\t %0,%1
2089    %v0st\\t %r1,%0
2090    mov.s %0,%1
2091    mov.s %0,%1
2092    mov %0,%1
2093    %V1ld\\t %0,%1
2094    %v0st\\t %r1,%0"
2095   [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")])
2097 (define_insn ""
2098   [(set (match_operand:SF 0 "register_operand" "=r")
2099         (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2100                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
2101   "!flag_pic"
2102   "or %0,%1,%#lo16(%2)")
2104 (define_insn ""
2105   [(set (match_operand:SF 0 "register_operand" "=r")
2106         (match_operand:SF 1 "immediate_operand" "F"))]
2107   "operands[1] != const0_rtx"
2108   "* return output_load_const_float (operands);"
2109   [(set_attr "type" "marith")]) ; length is 1 or 2.
2111 ;; String/block move insn.  See m88k.c for details.
2113 (define_expand "movstrsi"
2114   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2115                    (mem:BLK (match_operand:BLK 1 "" "")))
2116               (use (match_operand:SI 2 "arith32_operand" ""))
2117               (use (match_operand:SI 3 "immediate_operand" ""))])]
2118   ""
2119   "
2121   rtx dest_mem = operands[0];
2122   rtx src_mem = operands[1];
2123   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
2124   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2125   expand_block_move (dest_mem, src_mem, operands);
2126   DONE;
2129 ;; ??? We shouldn't be allowing such mode mismatches
2130 (define_insn ""
2131   [(set (match_operand 0 "register_operand" "=r")
2132         (match_operand:BLK 1 "memory_operand" "m"))]
2133   ""
2134   "*
2136   switch (GET_MODE (operands[0]))
2137     {
2138     case QImode:
2139       return \"%V1ld.bu\\t %0,%1\";
2140     case HImode:
2141       return \"%V1ld.hu\\t %0,%1\";
2142     case SImode:
2143       return \"%V1ld\\t %0,%1\";
2144     case DImode:
2145       return \"%V1ld.d\\t %0,%1\";
2146     default:
2147       abort ();
2148     }
2150   [(set_attr "type" "load")])
2152 (define_insn ""
2153   [(set (match_operand:BLK 0 "memory_operand" "=m")
2154         (match_operand 1 "register_operand" "r"))]
2155   ""
2156   "*
2158   switch (GET_MODE (operands[1]))
2159     {
2160     case QImode:
2161       return \"%v0st.b\\t %1,%0\";
2162     case HImode:
2163       return \"%v0st.h\\t %1,%0\";
2164     case SImode:
2165       return \"%v0st\\t %1,%0\";
2166     case DImode:
2167       return \"%v0st.d\\t %1,%0\";
2168     default:
2169       abort ();
2170     }
2172   [(set_attr "type" "store")])
2174 ;; Call a non-looping block move library function (e.g. __movstrSI96x64).
2175 ;; operand 0 is the function name
2176 ;; operand 1 is the destination pointer
2177 ;; operand 2 is the source pointer
2178 ;; operand 3 is the offset for the source and destination pointers
2179 ;; operand 4 is the first value to be loaded
2180 ;; operand 5 is the register to hold the value (r4 or r5)
2182 (define_expand "call_block_move"
2183   [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2184                              (match_operand:SI 3 "immediate_operand" "")))
2185    (set (match_operand 5 "register_operand" "")
2186         (match_operand 4 "memory_operand" ""))
2187    (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2188                              (match_dup 3)))
2189    (use (reg:SI 2))
2190    (use (reg:SI 3))
2191    (use (match_dup 5))
2192    (parallel [(set (reg:DI 2)
2193                    (call (mem:SI (match_operand 0 "" ""))
2194                          (const_int 0)))
2195               (clobber (reg:SI 1))])]
2196   ""
2197   "")
2199 ;; Call an SImode looping block move library function (e.g. __movstrSI64n68).
2200 ;; operands 0-5 as in the non-looping interface
2201 ;; operand 6 is the loop count
2203 (define_expand "call_movstrsi_loop"
2204   [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2205                              (match_operand:SI 3 "immediate_operand" "")))
2206    (set (match_operand:SI 5 "register_operand" "")
2207         (match_operand 4 "memory_operand" ""))
2208    (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2209                              (match_dup 3)))
2210    (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" ""))
2211    (use (reg:SI 2))
2212    (use (reg:SI 3))
2213    (use (match_dup 5))
2214    (use (reg:SI 6))
2215    (parallel [(set (reg:DI 2)
2216                    (call (mem:SI (match_operand 0 "" ""))
2217                          (const_int 0)))
2218               (clobber (reg:SI 1))])]
2219   ""
2220   "")
2222 ;;- zero extension instructions
2224 (define_expand "zero_extendhisi2"
2225   [(set (match_operand:SI 0 "register_operand" "")
2226         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2227   ""
2228   "
2230   if (GET_CODE (operands[1]) == MEM
2231       && symbolic_address_p (XEXP (operands[1], 0)))
2232     operands[1]
2233       = legitimize_address (flag_pic, operands[1], 0, 0);
2236 (define_insn ""
2237   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2238         (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))]
2239   "GET_CODE (operands[1]) != CONST_INT"
2240   "@
2241    mask %0,%1,0xffff
2242    or %0,%#r0,%h1
2243    %V1ld.hu\\t %0,%1"
2244   [(set_attr "type" "arith,arith,load")])
2246 (define_expand "zero_extendqihi2"
2247   [(set (match_operand:HI 0 "register_operand" "")
2248         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2249   ""
2250   "
2252   if (GET_CODE (operands[1]) == MEM
2253       && symbolic_address_p (XEXP (operands[1], 0)))
2254     operands[1]
2255       = legitimize_address (flag_pic, operands[1], 0, 0);
2258 (define_insn ""
2259   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
2260         (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))]
2261   "GET_CODE (operands[1]) != CONST_INT"
2262   "@
2263    mask %0,%1,0xff
2264    or %0,%#r0,%q1
2265    %V1ld.bu\\t %0,%1"
2266   [(set_attr "type" "arith,arith,load")])
2268 (define_expand "zero_extendqisi2"
2269   [(set (match_operand:SI 0 "register_operand" "")
2270         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2271   ""
2272   "
2274   if (GET_CODE (operands[1]) == MEM
2275       && symbolic_address_p (XEXP (operands[1], 0)))
2276     {
2277       operands[1]
2278         = legitimize_address (flag_pic, operands[1], 0, 0);
2279       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2280                               gen_rtx_ZERO_EXTEND (SImode, operands[1])));
2281       DONE;
2282     }
2285 (define_insn ""
2286   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2287         (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))]
2288   "GET_CODE (operands[1]) != CONST_INT"
2289   "@
2290    mask %0,%1,0xff
2291    or %0,%#r0,%q1
2292    %V1ld.bu\\t %0,%1"
2293   [(set_attr "type" "arith,arith,load")])
2295 ;;- sign extension instructions
2297 (define_expand "extendsidi2"
2298   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 4)
2299         (match_operand:SI 1 "general_operand" "g"))
2300    (set (subreg:SI (match_dup 0) 0)
2301         (ashiftrt:SI (subreg:SI (match_dup 0) 4)
2302                      (const_int 31)))]
2303   ""
2304   "")
2306 (define_expand "extendhisi2"
2307   [(set (match_operand:SI 0 "register_operand" "")
2308         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2309   ""
2310   "
2312   if (GET_CODE (operands[1]) == MEM
2313       && symbolic_address_p (XEXP (operands[1], 0)))
2314     operands[1]
2315       = legitimize_address (flag_pic, operands[1], 0, 0);
2318 (define_insn ""
2319   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2320         (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))]
2321   "GET_CODE (operands[1]) != CONST_INT"
2322   "@
2323    ext %0,%1,16<0>
2324    or %0,%#r0,%h1
2325    subu %0,%#r0,%H1
2326    %V1ld.h\\t %0,%1"
2327   [(set_attr "type" "bit,arith,arith,load")])
2329 (define_expand "extendqihi2"
2330   [(set (match_operand:HI 0 "register_operand" "")
2331         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2332   ""
2333   "
2335   if (GET_CODE (operands[1]) == MEM
2336       && symbolic_address_p (XEXP (operands[1], 0)))
2337     operands[1]
2338       = legitimize_address (flag_pic, operands[1], 0, 0);
2341 (define_insn ""
2342   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2343         (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2344   "GET_CODE (operands[1]) != CONST_INT"
2345   "@
2346    ext %0,%1,8<0>
2347    or %0,%#r0,%q1
2348    subu %0,%#r0,%Q1
2349    %V1ld.b\\t %0,%1"
2350   [(set_attr "type" "bit,arith,arith,load")])
2352 (define_expand "extendqisi2"
2353   [(set (match_operand:SI 0 "register_operand" "")
2354         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2355   ""
2356   "
2358   if (GET_CODE (operands[1]) == MEM
2359       && symbolic_address_p (XEXP (operands[1], 0)))
2360     operands[1]
2361       = legitimize_address (flag_pic, operands[1], 0, 0);
2364 (define_insn ""
2365   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2366         (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2367   "GET_CODE (operands[1]) != CONST_INT"
2368   "@
2369    ext %0,%1,8<0>
2370    or %0,%#r0,%q1
2371    subu %0,%#r0,%Q1
2372    %V1ld.b\\t %0,%1"
2373   [(set_attr "type" "bit,arith,arith,load")])
2375 ;; Conversions between float and double.
2377 ;; The fadd instruction does not conform to IEEE 754 when used to
2378 ;; convert between float and double.  In particular, the sign of -0 is
2379 ;; not preserved.  Interestingly, fsub does conform.
2381 (define_expand "extendsfdf2"
2382   [(set (match_operand:DF 0 "register_operand" "=r")
2383         (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2384   ""
2385   "")
2387 (define_insn ""
2388   [(set (match_operand:DF 0 "register_operand" "=r")
2389         (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2390   "! TARGET_88110"
2391   "fsub.dss %0,%1,%#r0"
2392   [(set_attr "type" "spadd")])
2394 (define_insn ""
2395   [(set (match_operand:DF 0 "register_operand" "=r,x")
2396         (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))]
2397   "TARGET_88110"
2398   "fcvt.ds %0,%1"
2399   [(set_attr "type" "spadd")])
2401 (define_expand "truncdfsf2"
2402   [(set (match_operand:SF 0 "register_operand" "=r")
2403         (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2404   ""
2405   "")
2407 (define_insn ""
2408   [(set (match_operand:SF 0 "register_operand" "=r")
2409         (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2410   "! TARGET_88110"
2411   "fsub.sds %0,%1,%#r0"
2412   [(set_attr "type" "dpadd")])
2414 (define_insn ""
2415   [(set (match_operand:SF 0 "register_operand" "=r,x")
2416         (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))]
2417   "TARGET_88110"
2418   "fcvt.sd %0,%1"
2419   [(set_attr "type" "dpadd")])
2421 ;; Conversions between floating point and integer
2423 (define_insn "floatsidf2"
2424   [(set (match_operand:DF 0 "register_operand" "=r,x")
2425         (float:DF (match_operand:SI 1 "register_operand" "r,r")))]
2426   ""
2427   "flt.ds %0,%1"
2428   [(set_attr "type" "spadd,dpadd")])
2430 (define_insn "floatsisf2"
2431   [(set (match_operand:SF 0 "register_operand" "=r,x")
2432         (float:SF (match_operand:SI 1 "register_operand" "r,r")))]
2433   ""
2434   "flt.ss %0,%1"
2435   [(set_attr "type" "spadd,spadd")])
2437 (define_insn "fix_truncdfsi2"
2438   [(set (match_operand:SI 0 "register_operand" "=r,r")
2439         (fix:SI (match_operand:DF 1 "register_operand" "r,x")))]
2440   ""
2441   "trnc.sd %0,%1"
2442   [(set_attr "type" "dpadd,dpadd")])
2444 (define_insn "fix_truncsfsi2"
2445   [(set (match_operand:SI 0 "register_operand" "=r,r")
2446         (fix:SI (match_operand:SF 1 "register_operand" "r,x")))]
2447   ""
2448   "trnc.ss %0,%1"
2449   [(set_attr "type" "spadd,dpadd")])
2452 ;;- arithmetic instructions
2453 ;;- add instructions
2455 (define_insn "addsi3"
2456   [(set (match_operand:SI 0 "register_operand" "=r,r")
2457         (plus:SI (match_operand:SI 1 "add_operand" "%r,r")
2458                  (match_operand:SI 2 "add_operand" "rI,J")))]
2459   ""
2460   "@
2461    addu %0,%1,%2
2462    subu %0,%1,%n2")
2464 ;; patterns for mixed mode floating point.
2465 ;; Do not define patterns that utilize mixed mode arithmetic that result
2466 ;; in narrowing the precision, because it loses accuracy, since the standard
2467 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2469 (define_expand "adddf3"
2470   [(set (match_operand:DF 0 "register_operand" "=r,x")
2471         (plus:DF (match_operand:DF 1 "general_operand" "%r,x")
2472                  (match_operand:DF 2 "general_operand" "r,x")))]
2473   ""
2474   "
2476   operands[1] = legitimize_operand (operands[1], DFmode);
2477   operands[2] = legitimize_operand (operands[2], DFmode);
2480 (define_insn ""
2481   [(set (match_operand:DF 0 "register_operand" "=r,x")
2482         (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2483                  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2484   ""
2485   "fadd.dss %0,%1,%2"
2486   [(set_attr "type" "spadd")])
2488 (define_insn ""
2489   [(set (match_operand:DF 0 "register_operand" "=r,x")
2490         (plus:DF (match_operand:DF 1 "register_operand" "r,x")
2491                  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2492   ""
2493   "fadd.dds %0,%1,%2"
2494   [(set_attr "type" "dpadd")])
2496 (define_insn ""
2497   [(set (match_operand:DF 0 "register_operand" "=r,x")
2498         (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2499                  (match_operand:DF 2 "register_operand" "r,x")))]
2500   ""
2501   "fadd.dsd %0,%1,%2"
2502   [(set_attr "type" "dpadd")])
2504 (define_insn ""
2505   [(set (match_operand:DF 0 "register_operand" "=r,x")
2506         (plus:DF (match_operand:DF 1 "register_operand" "%r,x")
2507                  (match_operand:DF 2 "register_operand" "r,x")))]
2508   ""
2509   "fadd.ddd %0,%1,%2"
2510   [(set_attr "type" "dpadd")])
2512 (define_insn "addsf3"
2513   [(set (match_operand:SF 0 "register_operand" "=r,x")
2514         (plus:SF (match_operand:SF 1 "register_operand" "%r,x")
2515                  (match_operand:SF 2 "register_operand" "r,x")))]
2516   ""
2517   "fadd.sss %0,%1,%2"
2518   [(set_attr "type" "spadd")])
2520 (define_insn ""
2521   [(set (match_operand:DI 0 "register_operand" "=r")
2522         (plus:DI (match_operand:DI 1 "register_operand" "r")
2523                  (zero_extend:DI
2524                   (match_operand:SI 2 "register_operand" "r"))))
2525    (clobber (reg:CC 0))]
2526   ""
2527   "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
2528   [(set_attr "type" "marith")])
2530 (define_insn ""
2531   [(set (match_operand:DI 0 "register_operand" "=r")
2532         (plus:DI (zero_extend:DI
2533                   (match_operand:SI 1 "register_operand" "r"))
2534                  (match_operand:DI 2 "register_operand" "r")))
2535    (clobber (reg:CC 0))]
2536   ""
2537   "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
2538   [(set_attr "type" "marith")])
2540 (define_insn "adddi3"
2541   [(set (match_operand:DI 0 "register_operand" "=r")
2542         (plus:DI (match_operand:DI 1 "register_operand" "%r")
2543                  (match_operand:DI 2 "register_operand" "r")))
2544    (clobber (reg:CC 0))]
2545   ""
2546   "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
2547   [(set_attr "type" "marith")])
2549 ;; Add with carry insns.
2551 (define_insn ""
2552   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
2553                    (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2554                             (match_operand:SI 2 "reg_or_0_operand" "rO")))
2555               (set (reg:CC 0)
2556                    (unspec:CC [(match_dup 1) (match_dup 2)] 0))])]
2557   ""
2558   "addu.co %r0,%r1,%r2")
2560 (define_insn ""
2561   [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2562                                (match_operand:SI 1 "reg_or_0_operand" "rO")]
2563                               0))]
2564   ""
2565   "addu.co %#r0,%r0,%r1")
2567 (define_insn ""
2568   [(set (match_operand:SI 0 "register_operand" "=r")
2569         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2570                  (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2571                              (reg:CC 0)] 0)))]
2572   ""
2573   "addu.ci %r0,%r1,%r2")
2575 ;;- subtract instructions
2577 (define_insn "subsi3"
2578   [(set (match_operand:SI 0 "register_operand" "=r")
2579         (minus:SI (match_operand:SI 1 "register_operand" "r")
2580                   (match_operand:SI 2 "arith32_operand" "rI")))]
2581   ""
2582   "subu %0,%1,%2")
2584 ;; patterns for mixed mode floating point
2585 ;; Do not define patterns that utilize mixed mode arithmetic that result
2586 ;; in narrowing the precision, because it loses accuracy, since the standard
2587 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2589 (define_expand "subdf3"
2590   [(set (match_operand:DF 0 "register_operand" "=r,x")
2591         (minus:DF (match_operand:DF 1 "general_operand" "r,x")
2592                   (match_operand:DF 2 "general_operand" "r,x")))]
2593   ""
2594   "
2596   operands[1] = legitimize_operand (operands[1], DFmode);
2597   operands[2] = legitimize_operand (operands[2], DFmode);
2600 (define_insn ""
2601   [(set (match_operand:DF 0 "register_operand" "=r,x")
2602         (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2603                   (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2604   ""
2605   "fsub.dss %0,%1,%2"
2606   [(set_attr "type" "spadd")])
2608 (define_insn ""
2609   [(set (match_operand:DF 0 "register_operand" "=r,x")
2610         (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2611                   (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2612   ""
2613   "fsub.dds %0,%1,%2"
2614   [(set_attr "type" "dpadd")])
2616 (define_insn ""
2617   [(set (match_operand:DF 0 "register_operand" "=r,x")
2618         (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2619                   (match_operand:DF 2 "register_operand" "r,x")))]
2620   ""
2621   "fsub.dsd %0,%1,%2"
2622   [(set_attr "type" "dpadd")])
2624 (define_insn ""
2625   [(set (match_operand:DF 0 "register_operand" "=r,x")
2626         (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2627                   (match_operand:DF 2 "register_operand" "r,x")))]
2628   ""
2629   "fsub.ddd %0,%1,%2"
2630   [(set_attr "type" "dpadd")])
2632 (define_insn "subsf3"
2633   [(set (match_operand:SF 0 "register_operand" "=r,x")
2634         (minus:SF (match_operand:SF 1 "register_operand" "r,x")
2635                   (match_operand:SF 2 "register_operand" "r,x")))]
2636   ""
2637   "fsub.sss %0,%1,%2"
2638   [(set_attr "type" "spadd")])
2640 (define_insn ""
2641   [(set (match_operand:DI 0 "register_operand" "=r")
2642         (minus:DI (match_operand:DI 1 "register_operand" "r")
2643                   (zero_extend:DI
2644                    (match_operand:SI 2 "register_operand" "r"))))
2645    (clobber (reg:CC 0))]
2646   ""
2647   "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
2648   [(set_attr "type" "marith")])
2650 (define_insn ""
2651   [(set (match_operand:DI 0 "register_operand" "=r")
2652         (minus:DI (zero_extend:DI
2653                    (match_operand:SI 1 "register_operand" "r"))
2654                   (match_operand:DI 2 "register_operand" "r")))
2655    (clobber (reg:CC 0))]
2656   ""
2657   "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
2658   [(set_attr "type" "marith")])
2660 (define_insn "subdi3"
2661   [(set (match_operand:DI 0 "register_operand" "=r")
2662         (minus:DI (match_operand:DI 1 "register_operand" "r")
2663                   (match_operand:DI 2 "register_operand" "r")))
2664    (clobber (reg:CC 0))]
2665   ""
2666   "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
2667   [(set_attr "type" "marith")])
2669 ;; Subtract with carry insns.
2671 (define_insn ""
2672   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
2673                    (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2674                              (match_operand:SI 2 "reg_or_0_operand" "rO")))
2675               (set (reg:CC 0)
2676                    (unspec:CC [(match_dup 1) (match_dup 2)] 1))])]
2677   ""
2678   "subu.co %r0,%r1,%r2")
2680 (define_insn ""
2681   [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2682                                (match_operand:SI 1 "reg_or_0_operand" "rO")]
2683                               1))]
2684   ""
2685   "subu.co %#r0,%r0,%r1")
2687 (define_insn ""
2688   [(set (match_operand:SI 0 "register_operand" "=r")
2689         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2690                   (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2691                               (reg:CC 0)] 1)))]
2692   ""
2693   "subu.ci %r0,%r1,%r2")
2695 ;;- multiply instructions
2697 ;; There is an unfounded silicon errata for E.1 requiring that an
2698 ;; immediate constant value in div/divu/mul instructions be less than
2699 ;; 0x800.  This is no longer provided for.
2701 (define_insn "mulsi3"
2702   [(set (match_operand:SI 0 "register_operand" "=r")
2703         (mult:SI (match_operand:SI 1 "arith32_operand" "%r")
2704                  (match_operand:SI 2 "arith32_operand" "rI")))]
2705   ""
2706   "mul %0,%1,%2"
2707   [(set_attr "type" "imul")])
2709 (define_insn "umulsidi3"
2710   [(set (match_operand:DI 0 "register_operand" "=r")
2711         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
2712                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
2713   "TARGET_88110"
2714   "mulu.d %0,%1,%2"
2715   [(set_attr "type" "imul")])
2717 ;; patterns for mixed mode floating point
2718 ;; Do not define patterns that utilize mixed mode arithmetic that result
2719 ;; in narrowing the precision, because it loses accuracy, since the standard
2720 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2722 (define_expand "muldf3"
2723   [(set (match_operand:DF 0 "register_operand" "=r,x")
2724         (mult:DF (match_operand:DF 1 "general_operand" "%r,x")
2725                  (match_operand:DF 2 "general_operand" "r,x")))]
2726   ""
2727   "
2729   operands[1] = legitimize_operand (operands[1], DFmode);
2730   operands[2] = legitimize_operand (operands[2], DFmode);
2733 (define_insn ""
2734   [(set (match_operand:DF 0 "register_operand" "=r,x")
2735         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2736                  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2737   ""
2738   "fmul.dss %0,%1,%2"
2739   [(set_attr "type" "spmul")])
2741 (define_insn ""
2742   [(set (match_operand:DF 0 "register_operand" "=r,x")
2743         (mult:DF (match_operand:DF 1 "register_operand" "r,x")
2744                  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2745   ""
2746   "fmul.dds %0,%1,%2"
2747   [(set_attr "type" "spmul")])
2749 (define_insn ""
2750   [(set (match_operand:DF 0 "register_operand" "=r,x")
2751         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2752                  (match_operand:DF 2 "register_operand" "r,x")))]
2753   ""
2754   "fmul.dsd %0,%1,%2"
2755   [(set_attr "type" "spmul")])
2757 (define_insn ""
2758   [(set (match_operand:DF 0 "register_operand" "=r,x")
2759         (mult:DF (match_operand:DF 1 "register_operand" "%r,x")
2760                  (match_operand:DF 2 "register_operand" "r,x")))]
2761   ""
2762   "fmul.ddd %0,%1,%2"
2763   [(set_attr "type" "dpmul")])
2765 (define_insn "mulsf3"
2766   [(set (match_operand:SF 0 "register_operand" "=r,x")
2767         (mult:SF (match_operand:SF 1 "register_operand" "%r,x")
2768                  (match_operand:SF 2 "register_operand" "r,x")))]
2769   ""
2770   "fmul.sss %0,%1,%2"
2771   [(set_attr "type" "spmul")])
2773 ;;- divide instructions
2775 ;; The 88k div and divu instructions don't reliably trap on
2776 ;; divide-by-zero.  A trap to vector 503 asserts divide-by-zero.  The
2777 ;; general scheme for doing divide is to do a 4-way split based on the
2778 ;; sign of the two operand and do the appropriate negates.
2780 ;; The conditional trap instruction is not used as this serializes the
2781 ;; processor.  Instead a conditional branch and an unconditional trap
2782 ;; are used, but after the divu.  Since the divu takes up to 38 cycles,
2783 ;; the conditional branch is essentially free.
2785 ;; Two target options control how divide is done.  One options selects
2786 ;; whether to do the branch and negate scheme instead of using the div
2787 ;; instruction; the other option selects whether to explicitly check
2788 ;; for divide-by-zero or take your chances.  If the div instruction is
2789 ;; used, the O/S must complete the operation if the operands are
2790 ;; negative.  The O/S will signal an overflow condition if the most
2791 ;; negative number (-2147483648) is divided by negative 1.
2793 ;; There is an unfounded silicon errata for E.1 requiring that an
2794 ;; immediate constant value in div/divu/mul instructions be less than
2795 ;; 0x800.  This is no longer provided for.
2797 ;; Division by 0 trap
2798 (define_insn "trap_divide_by_zero"
2799   [(trap_if (const_int 1) (const_int 503))]
2800   ""
2801   "tb0 0,%#r0,503"
2802   [(set_attr "type" "weird")])
2804 ;; Conditional division by 0 trap.
2805 (define_expand "tcnd_divide_by_zero"
2806   [(set (pc)
2807         (if_then_else (eq (match_operand:SI 0 "register_operand" "")
2808                           (const_int 0))
2809                       (pc)
2810                       (match_operand 1 "" "")))
2811    (trap_if (const_int 1) (const_int 503))]
2812   ""
2813   "
2815   emit_insn (gen_cmpsi (operands[0], const0_rtx));
2816   emit_jump_insn (gen_bne (operands[1]));
2817   emit_insn (gen_trap_divide_by_zero ());
2818   DONE;
2821 (define_expand "divsi3"
2822   [(set (match_operand:SI 0 "register_operand" "")
2823         (div:SI (match_operand:SI 1 "arith32_operand" "")
2824                 (match_operand:SI 2 "arith32_operand" "")))]
2825   ""
2826   "
2828   rtx op0 = operands[0];
2829   rtx op1 = operands[1];
2830   rtx op2 = operands[2];
2831   rtx join_label;
2833   /* @@ This needs to be reworked.  Torbjorn Granlund has suggested making
2834      it a runtime (perhaps quite special).  */
2836   if (GET_CODE (op1) == CONST_INT)
2837     op1 = force_reg (SImode, op1);
2839   else if (GET_CODE (op2) == CONST_INT
2840            && ! SMALL_INT (operands[2]))
2841     op2 = force_reg (SImode, op2);
2843   if (op2 == const0_rtx)
2844     {
2845       emit_insn (gen_trap_divide_by_zero ());
2846       emit_insn (gen_dummy (op0));
2847       DONE;
2848     }
2850   if (TARGET_USE_DIV)
2851     {
2852       emit_move_insn (op0, gen_rtx_DIV (SImode, op1, op2));
2853       if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT)
2854         {
2855           rtx label = gen_label_rtx ();
2856           emit_insn (gen_tcnd_divide_by_zero (op2, label));
2857           emit_label (label);
2858           emit_insn (gen_dummy (op0));
2859         }
2860       DONE;
2861     }
2863   join_label = gen_label_rtx ();
2864   if (GET_CODE (op1) == CONST_INT)
2865     {
2866       int neg = FALSE;
2867       rtx neg_op2 = gen_reg_rtx (SImode);
2868       rtx label1 = gen_label_rtx ();
2870       if (INTVAL (op1) < 0)
2871         {
2872           neg = TRUE;
2873           op1 = GEN_INT (-INTVAL (op1));
2874         }
2875       op1 = force_reg (SImode, op1);
2877       emit_insn (gen_negsi2 (neg_op2, op2));
2878       emit_insn (gen_cmpsi (op2, const0_rtx));
2879       emit_jump_insn (gen_bgt (label1));
2880                                                 /* constant / 0-or-negative */
2881       emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, neg_op2));
2882       if (!neg)
2883         emit_insn (gen_negsi2 (op0, op0));
2885       if (TARGET_CHECK_ZERO_DIV)
2886         emit_insn (gen_tcnd_divide_by_zero (op2, join_label));
2887       emit_jump_insn (gen_jump (join_label));
2888       emit_barrier ();
2890       emit_label (label1);                      /* constant / positive */
2891       emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2));
2892       if (neg)
2893         emit_insn (gen_negsi2 (op0, op0));
2894     }
2896   else if (GET_CODE (op2) == CONST_INT)
2897     {
2898       int neg = FALSE;
2899       rtx neg_op1 = gen_reg_rtx (SImode);
2900       rtx label1 = gen_label_rtx ();
2902       if (INTVAL (op2) < 0)
2903         {
2904           neg = TRUE;
2905           op2 = GEN_INT (-INTVAL (op2));
2906         }
2907       else if (! SMALL_INT (operands[2]))
2908         op2 = force_reg (SImode, op2);
2910       emit_insn (gen_negsi2 (neg_op1, op1));
2911       emit_insn (gen_cmpsi (op1, const0_rtx));
2912       emit_jump_insn (gen_bge (label1));
2913                                                 /* 0-or-negative / constant */
2914       emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, op2));
2915       if (!neg)
2916         emit_insn (gen_negsi2 (op0, op0));
2918       emit_jump_insn (gen_jump (join_label));
2919       emit_barrier ();
2921       emit_label (label1);                      /* positive / constant */
2922       emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2));
2923       if (neg)
2924         emit_insn (gen_negsi2 (op0, op0));
2925     }
2927   else
2928     {
2929       rtx neg_op1 = gen_reg_rtx (SImode);
2930       rtx neg_op2 = gen_reg_rtx (SImode);
2931       rtx label1 = gen_label_rtx ();
2932       rtx label2 = gen_label_rtx ();
2933       rtx label3 = gen_label_rtx ();
2934       rtx label4 = NULL_RTX;
2936       emit_insn (gen_negsi2 (neg_op2, op2));
2937       emit_insn (gen_cmpsi (op2, const0_rtx));
2938       emit_jump_insn (gen_bgt (label1));
2940       emit_insn (gen_negsi2 (neg_op1, op1));
2941       emit_insn (gen_cmpsi (op1, const0_rtx));
2942       emit_jump_insn (gen_bge (label2));
2943                                                 /* negative / negative-or-0 */
2944       emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, neg_op2));
2946       if (TARGET_CHECK_ZERO_DIV)
2947         {
2948           label4 = gen_label_rtx ();
2949           emit_insn (gen_cmpsi (op2, const0_rtx));
2950           emit_jump_insn (gen_bne (join_label));
2951           emit_label (label4);
2952           emit_insn (gen_trap_divide_by_zero ());
2953         }
2954       emit_jump_insn (gen_jump (join_label));
2955       emit_barrier ();
2957       emit_label (label2);                      /* pos.-or-0 / neg.-or-0 */
2958       emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, neg_op2));
2960       if (TARGET_CHECK_ZERO_DIV)
2961         {
2962           emit_insn (gen_cmpsi (op2, const0_rtx));
2963           emit_jump_insn (gen_beq (label4));
2964         }
2966       emit_insn (gen_negsi2 (op0, op0));
2967       emit_jump_insn (gen_jump (join_label));
2968       emit_barrier ();
2970       emit_label (label1);
2971       emit_insn (gen_negsi2 (neg_op1, op1));
2972       emit_insn (gen_cmpsi (op1, const0_rtx));
2973       emit_jump_insn (gen_bge (label3));
2974                                                 /* negative / positive */
2975       emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, op2));
2976       emit_insn (gen_negsi2 (op0, op0));
2977       emit_jump_insn (gen_jump (join_label));
2978       emit_barrier ();
2980       emit_label (label3);                      /* positive-or-0 / positive */
2981       emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2));
2982     }
2984   emit_label (join_label);
2986   emit_insn (gen_dummy (op0));
2987   DONE;
2990 (define_insn ""
2991   [(set (match_operand:SI 0 "register_operand" "=r")
2992         (div:SI (match_operand:SI 1 "register_operand" "r")
2993                 (match_operand:SI 2 "arith_operand" "rI")))]
2994   ""
2995   "div %0,%1,%2"
2996   [(set_attr "type" "idiv")])
2998 (define_expand "udivsi3"
2999   [(set (match_operand:SI 0 "register_operand" "")
3000         (udiv:SI (match_operand:SI 1 "register_operand" "")
3001                  (match_operand:SI 2 "arith32_operand" "")))]
3002   ""
3003   "
3005   rtx op2 = operands[2];
3007   if (op2 == const0_rtx)
3008     {
3009       emit_insn (gen_trap_divide_by_zero ());
3010       emit_insn (gen_dummy (operands[0]));
3011       DONE;
3012     }
3013   else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV)
3014     {
3015       rtx label = gen_label_rtx ();
3016       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3017                               gen_rtx_UDIV (SImode, operands[1], op2)));
3018       emit_insn (gen_tcnd_divide_by_zero (op2, label));
3019       emit_label (label);
3020       emit_insn (gen_dummy (operands[0]));
3021       DONE;
3022     }
3025 (define_insn ""
3026  [(set (match_operand:SI 0 "register_operand" "=r")
3027        (udiv:SI (match_operand:SI 1 "register_operand" "r")
3028                 (match_operand:SI 2 "arith32_operand" "rI")))]
3029   "operands[2] != const0_rtx"
3030   "divu %0,%1,%2"
3031   [(set_attr "type" "idiv")])
3033 (define_insn ""
3034  [(set (match_operand:SI 0 "register_operand" "=r")
3035        (udiv:SI (match_operand:SI 1 "register_operand" "r")
3036                 (const_int 0)))]
3037   ""
3038   "tb0 0,%#r0,503"
3039   [(set_attr "type" "weird")])
3041 ;; patterns for mixed mode floating point.
3042 ;; Do not define patterns that utilize mixed mode arithmetic that result
3043 ;; in narrowing the precision, because it loses accuracy, since the standard
3044 ;; requires double rounding, whereas the 88000 instruction only rounds once.
3046 (define_expand "divdf3"
3047   [(set (match_operand:DF 0 "register_operand" "=r,x")
3048         (div:DF (match_operand:DF 1 "general_operand" "r,x")
3049                 (match_operand:DF 2 "general_operand" "r,x")))]
3050   ""
3051   "
3053   operands[1] = legitimize_operand (operands[1], DFmode);
3054   if (real_power_of_2_operand (operands[2], DFmode))
3055     {
3056       REAL_VALUE_TYPE r;
3057       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3058       if (!exact_real_inverse (DFmode, &r))
3059         abort ();
3060       emit_insn (gen_muldf3 (operands[0], operands[1],
3061                              CONST_DOUBLE_FROM_REAL_VALUE (r, DFmode)));
3062       DONE;
3063     }
3064   else if (! register_operand (operands[2], DFmode))
3065     operands[2] = force_reg (DFmode, operands[2]);
3068 (define_insn ""
3069   [(set (match_operand:DF 0 "register_operand" "=r,x")
3070         (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3071                 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3072   ""
3073   "fdiv.dss %0,%1,%2"
3074   [(set_attr "type" "dpdiv")])
3076 (define_insn ""
3077   [(set (match_operand:DF 0 "register_operand" "=r,x")
3078         (div:DF (match_operand:DF 1 "register_operand" "r,x")
3079                 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3080   ""
3081   "fdiv.dds %0,%1,%2"
3082   [(set_attr "type" "dpdiv")])
3084 (define_insn ""
3085   [(set (match_operand:DF 0 "register_operand" "=r,x")
3086         (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3087                 (match_operand:DF 2 "register_operand" "r,x")))]
3088   ""
3089   "fdiv.dsd %0,%1,%2"
3090   [(set_attr "type" "dpdiv")])
3092 (define_insn "divsf3"
3093   [(set (match_operand:SF 0 "register_operand" "=r,x")
3094         (div:SF (match_operand:SF 1 "register_operand" "r,x")
3095                 (match_operand:SF 2 "register_operand" "r,x")))]
3096   ""
3097   "fdiv.sss %0,%1,%2"
3098   [(set_attr "type" "spdiv")])
3100 (define_insn ""
3101   [(set (match_operand:DF 0 "register_operand" "=r,x")
3102         (div:DF (match_operand:DF 1 "register_operand" "r,x")
3103                 (match_operand:DF 2 "register_operand" "r,x")))]
3104   ""
3105   "fdiv.ddd %0,%1,%2"
3106   [(set_attr "type" "dpdiv")])
3108 ;; - remainder instructions, don't define, since the hardware doesn't have any
3109 ;; direct support, and GNU can synthesis them out of div/mul just fine.
3111 ;;- load effective address, must come after add, so that we favor using
3112 ;;  addu reg,reg,reg  instead of:  lda reg,reg,reg (addu doesn't require
3113 ;;  the data unit), and also future 88k chips might not support unscaled
3114 ;;  lda instructions.
3116 (define_insn ""
3117   [(set (match_operand:SI 0 "register_operand" "=r")
3118         (match_operand:SI 1 "address_operand" "p"))]
3119   "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])"
3120   "addu %0,%a1")
3122 (define_insn ""
3123   [(set (match_operand:SI 0 "register_operand" "=r")
3124         (match_operand:HI 1 "address_operand" "p"))]
3125   ""
3126   "lda.h %0,%a1"
3127   [(set_attr "type" "loada")])
3129 (define_insn ""
3130   [(set (match_operand:SI 0 "register_operand" "=r")
3131         (match_operand:SI 1 "address_operand" "p"))]
3132   ""
3133   "lda %0,%a1"
3134   [(set_attr "type" "loada")])
3136 (define_insn ""
3137   [(set (match_operand:SI 0 "register_operand" "=r")
3138         (match_operand:DI 1 "address_operand" "p"))]
3139   ""
3140   "lda.d %0,%a1"
3141   [(set_attr "type" "loada")])
3143 (define_insn ""
3144   [(set (match_operand:SI 0 "register_operand" "=r")
3145         (match_operand:SF 1 "address_operand" "p"))]
3146   ""
3147   "lda %0,%a1"
3148   [(set_attr "type" "loada")])
3150 (define_insn ""
3151   [(set (match_operand:SI 0 "register_operand" "=r")
3152         (match_operand:DF 1 "address_operand" "p"))]
3153   ""
3154   "lda.d %0,%a1"
3155   [(set_attr "type" "loada")])
3157 ;;- and instructions (with complement also)
3158 (define_insn ""
3159   [(set (match_operand:SI 0 "register_operand" "=r")
3160         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3161                 (match_operand:SI 2 "register_operand" "r")))]
3162   ""
3163   "and.c %0,%2,%1")
3165 ;; If the operation is being performed on a 32-bit constant such that
3166 ;; it cannot be done in one insn, do it in two.  We may lose a bit on
3167 ;; CSE in pathological cases, but it seems better doing it this way.
3169 (define_expand "andsi3"
3170   [(set (match_operand:SI 0 "register_operand" "")
3171         (and:SI (match_operand:SI 1 "arith32_operand" "")
3172                 (match_operand:SI 2 "arith32_operand" "")))]
3173   ""
3174   "
3176   if (GET_CODE (operands[2]) == CONST_INT)
3177     {
3178       int value = INTVAL (operands[2]);
3180       if (! (SMALL_INTVAL (value)
3181              || (value & 0xffff0000) == 0xffff0000
3182              || (value & 0xffff) == 0xffff
3183              || (value & 0xffff) == 0
3184              || integer_ok_for_set (~value)))
3185         {
3186           emit_insn (gen_andsi3 (operands[0], operands[1],
3187                                  GEN_INT (value | 0xffff)));
3188           operands[1] = operands[0];
3189           operands[2] = GEN_INT (value | 0xffff0000);
3190         }
3191     }
3194 (define_insn ""
3195   [(set (match_operand:SI 0 "register_operand" "=r,r")
3196         (and:SI (match_operand:SI 1 "arith32_operand" "%r,r")
3197                 (match_operand:SI 2 "arith32_operand" "rIJL,rn")))]
3198   ""
3199   "* return output_and (operands);"
3200   [(set_attr "type" "arith,marith")])
3202 (define_insn ""
3203   [(set (match_operand:DI 0 "register_operand" "=r")
3204         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3205                 (match_operand:DI 2 "register_operand" "r")))]
3206   ""
3207   "and.c %d0,%d2,%d1\;and.c %0,%2,%1"
3208   [(set_attr "type" "marith")])
3210 (define_insn "anddi3"
3211   [(set (match_operand:DI 0 "register_operand" "=r")
3212         (and:DI (match_operand:DI 1 "arith64_operand" "%r")
3213                 (match_operand:DI 2 "arith64_operand" "rn")))]
3214   ""
3215   "*
3217   rtx xoperands[10];
3219   xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3220   xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3221   xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3223   output_asm_insn (output_and (xoperands), xoperands);
3225   operands[0] = operand_subword (operands[0], 0, 0, DImode);
3226   operands[1] = operand_subword (operands[1], 0, 0, DImode);
3227   operands[2] = operand_subword (operands[2], 0, 0, DImode);
3229   return output_and (operands);
3231   [(set_attr "type" "marith")
3232    (set_attr "length" "4")]) ; length is 2, 3, or 4.
3234 ;;- Bit set (inclusive or) instructions (with complement also)
3235 (define_insn ""
3236   [(set (match_operand:SI 0 "register_operand" "=r")
3237         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3238                 (match_operand:SI 2 "register_operand" "r")))]
3239   ""
3240   "or.c %0,%2,%1")
3242 (define_expand "iorsi3"
3243   [(set (match_operand:SI 0 "register_operand" "")
3244         (ior:SI (match_operand:SI 1 "arith32_operand" "")
3245                 (match_operand:SI 2 "arith32_operand" "")))]
3246   ""
3247   "
3249   if (GET_CODE (operands[2]) == CONST_INT)
3250     {
3251       int value = INTVAL (operands[2]);
3253       if (! (SMALL_INTVAL (value)
3254              || (value & 0xffff) == 0
3255              || integer_ok_for_set (value)))
3256         {
3257           emit_insn (gen_iorsi3 (operands[0], operands[1],
3258                                  GEN_INT (value & 0xffff0000)));
3259           operands[1] = operands[0];
3260           operands[2] = GEN_INT (value & 0xffff);
3261         }
3262     }
3265 (define_insn ""
3266   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3267         (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r")
3268                 (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))]
3269   ""
3270   "@
3271    or %0,%1,%2
3272    or.u %0,%1,%X2
3273    set %0,%1,%s2
3274    or.u %0,%1,%X2\;or %0,%0,%x2"
3275   [(set_attr "type" "arith,arith,bit,marith")])
3277 (define_insn ""
3278   [(set (match_operand:DI 0 "register_operand" "=r")
3279         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3280                 (match_operand:DI 2 "register_operand" "r")))]
3281   ""
3282   "or.c %d0,%d2,%d1\;or.c %0,%2,%1"
3283   [(set_attr "type" "marith")])
3285 (define_insn "iordi3"
3286   [(set (match_operand:DI 0 "register_operand" "=r")
3287         (ior:DI (match_operand:DI 1 "arith64_operand" "%r")
3288                 (match_operand:DI 2 "arith64_operand" "rn")))]
3289   ""
3290   "*
3292   rtx xoperands[10];
3294   xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3295   xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3296   xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3298   output_asm_insn (output_ior (xoperands), xoperands);
3300   operands[0] = operand_subword (operands[0], 0, 0, DImode);
3301   operands[1] = operand_subword (operands[1], 0, 0, DImode);
3302   operands[2] = operand_subword (operands[2], 0, 0, DImode);
3304   return output_ior (operands);
3306   [(set_attr "type" "marith")
3307    (set_attr "length" "4")]) ; length is 2, 3, or 4.
3309 ;;- xor instructions (with complement also)
3310 (define_insn ""
3311   [(set (match_operand:SI 0 "register_operand" "=r")
3312         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r")
3313                         (match_operand:SI 2 "register_operand" "r"))))]
3314   ""
3315   "xor.c %0,%1,%2")
3317 (define_expand "xorsi3"
3318   [(set (match_operand:SI 0 "register_operand" "")
3319         (xor:SI (match_operand:SI 1 "arith32_operand" "")
3320                 (match_operand:SI 2 "arith32_operand" "")))]
3321   ""
3322   "
3324   if (GET_CODE (operands[2]) == CONST_INT)
3325     {
3326       int value = INTVAL (operands[2]);
3328       if (! (SMALL_INTVAL (value)
3329              || (value & 0xffff) == 0))
3330         {
3331           emit_insn (gen_xorsi3 (operands[0], operands[1],
3332                                  GEN_INT (value & 0xffff0000)));
3333           operands[1] = operands[0];
3334           operands[2] = GEN_INT (value & 0xffff);
3335         }
3336     }
3339 (define_insn ""
3340   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3341         (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r")
3342                 (match_operand:SI 2 "arith32_operand" "rI,L,n")))]
3343   ""
3344   "@
3345    xor %0,%1,%2
3346    xor.u %0,%1,%X2
3347    xor.u %0,%1,%X2\;xor %0,%0,%x2"
3348   [(set_attr "type" "arith,arith,marith")])
3350 (define_insn ""
3351   [(set (match_operand:DI 0 "register_operand" "=r")
3352         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
3353                         (match_operand:DI 2 "register_operand" "r"))))]
3354   ""
3355   "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2"
3356   [(set_attr "type" "marith")])
3358 (define_insn "xordi3"
3359   [(set (match_operand:DI 0 "register_operand" "=r")
3360         (xor:DI (match_operand:DI 1 "arith64_operand" "%r")
3361                 (match_operand:DI 2 "arith64_operand" "rn")))]
3362   ""
3363   "*
3365   rtx xoperands[10];
3367   xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3368   xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3369   xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3371   output_asm_insn (output_xor (xoperands), xoperands);
3373   operands[0] = operand_subword (operands[0], 0, 0, DImode);
3374   operands[1] = operand_subword (operands[1], 0, 0, DImode);
3375   operands[2] = operand_subword (operands[2], 0, 0, DImode);
3377   return output_xor (operands);
3379   [(set_attr "type" "marith")
3380    (set_attr "length" "4")]) ; length is 2, 3, or 4.
3382 ;;- ones complement instructions
3383 (define_insn "one_cmplsi2"
3384   [(set (match_operand:SI 0 "register_operand" "=r")
3385         (not:SI (match_operand:SI 1 "register_operand" "r")))]
3386   ""
3387   "xor.c %0,%1,%#r0")
3389 (define_insn "one_cmpldi2"
3390   [(set (match_operand:DI 0 "register_operand" "=r")
3391         (not:DI (match_operand:DI 1 "register_operand" "r")))]
3392   ""
3393   "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0"
3394   [(set_attr "type" "marith")])
3396 ;; Optimized special cases of shifting.
3397 ;; Must precede the general case.
3399 ;; @@ What about HImode shifted by 8?
3401 (define_insn ""
3402   [(set (match_operand:SI 0 "register_operand" "=r")
3403         (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3404                      (const_int 24)))]
3405   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3406   "%V1ld.b\\t %0,%1"
3407   [(set_attr "type" "load")])
3409 (define_insn ""
3410   [(set (match_operand:SI 0 "register_operand" "=r")
3411         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3412                      (const_int 24)))]
3413   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3414   "%V1ld.bu\\t %0,%1"
3415   [(set_attr "type" "load")])
3417 (define_insn ""
3418   [(set (match_operand:SI 0 "register_operand" "=r")
3419         (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3420                      (const_int 16)))]
3421   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3422   "%V1ld.h\\t %0,%1"
3423   [(set_attr "type" "load")])
3425 (define_insn ""
3426   [(set (match_operand:SI 0 "register_operand" "=r")
3427         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3428                      (const_int 16)))]
3429   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3430   "%V1ld.hu\\t %0,%1"
3431   [(set_attr "type" "load")])
3433 ;;- arithmetic shift instructions.
3435 ;; @@ Do the optimized patterns with -1 get used?  Perhaps operand 1 should
3436 ;; be arith32_operand?
3438 ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT.
3439 (define_insn "tbnd"
3440   [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
3441                  (match_operand:SI 1 "arith_operand" "rI"))
3442             (const_int 7))]
3443   ""
3444   "tbnd %r0,%1"
3445   [(set_attr "type" "weird")])
3447 ;; Just in case the optimizer decides to fold away the test.
3448 (define_insn ""
3449   [(trap_if (const_int 1) (const_int 7))]
3450   ""
3451   "tbnd %#r31,0"
3452   [(set_attr "type" "weird")])
3454 (define_expand "ashlsi3"
3455   [(set (match_operand:SI 0 "register_operand" "")
3456         (ashift:SI (match_operand:SI 1 "register_operand" "")
3457                    (match_operand:SI 2 "arith32_operand" "")))]
3458   ""
3459   "
3461   if (GET_CODE (operands[2]) == CONST_INT)
3462     {
3463       if ((unsigned) INTVAL (operands[2]) > 31)
3464         {
3465           if (TARGET_TRAP_LARGE_SHIFT)
3466             emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3467                                  GEN_INT (31)));
3468           else
3469             emit_move_insn (operands[0], const0_rtx);
3470           DONE;
3471         }
3472     }
3474   else if (TARGET_TRAP_LARGE_SHIFT)
3475     emit_insn (gen_tbnd (operands[2], GEN_INT (31)));
3477   else if (TARGET_HANDLE_LARGE_SHIFT)
3478     {
3479       rtx reg = gen_reg_rtx (SImode);
3480       emit_insn (gen_cmpsi (operands[2], GEN_INT (31)));
3481       emit_insn (gen_sleu (reg));
3482       emit_insn (gen_andsi3 (reg, operands[1], reg));
3483       operands[1] = reg;
3484     }
3487 (define_insn ""
3488   [(set (match_operand:SI 0 "register_operand" "=r,r")
3489         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
3490                    (match_operand:SI 2 "arith5_operand" "r,K")))]
3491   ""
3492   "@
3493    mak %0,%1,%2
3494    mak %0,%1,0<%2>"
3495   [(set_attr "type" "bit")])
3497 (define_expand "ashrsi3"
3498   [(set (match_operand:SI 0 "register_operand" "")
3499         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3500                      (match_operand:SI 2 "arith32_operand" "")))]
3501   ""
3502   "
3504   if (GET_CODE (operands[2]) == CONST_INT)
3505     {
3506       if ((unsigned) INTVAL (operands[2]) > 31)
3507         {
3508           if (TARGET_TRAP_LARGE_SHIFT)
3509             {
3510               emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3511                                    GEN_INT (31)));
3512               DONE;
3513             }
3514           else
3515             operands[2] = GEN_INT (31);
3516         }
3517     }
3519   else if (TARGET_TRAP_LARGE_SHIFT)
3520     emit_insn (gen_tbnd (operands[2], GEN_INT (31)));
3522   else if (TARGET_HANDLE_LARGE_SHIFT)
3523     {
3524       rtx reg = gen_reg_rtx (SImode);
3525       emit_insn (gen_cmpsi (operands[2], GEN_INT (31)));
3526       emit_insn (gen_sgtu (reg));
3527       emit_insn (gen_iorsi3 (reg, operands[2], reg));
3528       operands[2] = reg;
3529     }
3532 (define_insn ""
3533   [(set (match_operand:SI 0 "register_operand" "=r,r")
3534         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3535                      (match_operand:SI 2 "arith5_operand" "r,K")))]
3536   ""
3537   "@
3538    ext %0,%1,%2
3539    ext %0,%1,0<%2>"
3540   [(set_attr "type" "bit")])
3542 ;;- logical shift instructions.  Logical shift left becomes arithmetic
3543 ;; shift left.  
3545 (define_expand "lshrsi3"
3546   [(set (match_operand:SI 0 "register_operand" "")
3547         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3548                      (match_operand:SI 2 "arith32_operand" "")))]
3549   ""
3550   "
3552   if (GET_CODE (operands[2]) == CONST_INT)
3553     {
3554       if ((unsigned) INTVAL (operands[2]) > 31)
3555         {
3556           if (TARGET_TRAP_LARGE_SHIFT)
3557             emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3558                                  GEN_INT (31)));
3559           else
3560             emit_move_insn (operands[0], const0_rtx);
3561           DONE;
3562         }
3563     }
3565   else if (TARGET_TRAP_LARGE_SHIFT)
3566     emit_insn (gen_tbnd (operands[2], GEN_INT (31)));
3568   else if (TARGET_HANDLE_LARGE_SHIFT)
3569     {
3570       rtx reg = gen_reg_rtx (SImode);
3571       emit_insn (gen_cmpsi (operands[2], GEN_INT (31)));
3572       emit_insn (gen_sleu (reg));
3573       emit_insn (gen_andsi3 (reg, operands[1], reg));
3574       operands[1] = reg;
3575     }
3578 (define_insn ""
3579   [(set (match_operand:SI 0 "register_operand" "=r,r")
3580         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3581                      (match_operand:SI 2 "arith5_operand" "r,K")))]
3582   ""
3583   "@
3584    extu %0,%1,%2
3585    extu %0,%1,0<%2>"
3586   [(set_attr "type" "bit")])
3588 ;;- rotate instructions
3590 (define_expand "rotlsi3"
3591   [(set (match_operand:SI 0 "register_operand" "")
3592         (rotatert:SI (match_operand:SI 1 "register_operand" "")
3593                      (match_operand:SI 2 "arith32_operand" "")))]
3594   ""
3595   "
3597   if (GET_CODE (operands[2]) == CONST_INT
3598       && (unsigned) INTVAL (operands[2]) >= 32)
3599     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3600   else
3601     {
3602       rtx op = gen_reg_rtx (SImode);
3603       emit_insn (gen_negsi2 (op, operands[2]));
3604       operands[2] = op;
3605     }
3608 (define_insn "rotrsi3"
3609   [(set (match_operand:SI 0 "register_operand" "=r")
3610         (rotatert:SI (match_operand:SI 1 "register_operand" "r")
3611                      (match_operand:SI 2 "arith_operand" "rI")))]
3612   ""
3613   "rot %0,%1,%2"
3614   [(set_attr "type" "bit")])
3616 ;; find first set.
3618 ;; The ff1 instruction searches from the most significant bit while ffs
3619 ;; searches from the least significant bit.  The bit index and treatment of
3620 ;; zero also differ.  This amazing sequence was discovered using the GNU
3621 ;; Superoptimizer.
3623 (define_insn "ffssi2"
3624   [(set (match_operand:SI 0 "register_operand" "=r,&r")
3625         (ffs:SI (match_operand:SI 1 "register_operand" "0,r")))
3626    (clobber (reg:CC 0))
3627    (clobber (match_scratch:SI 2 "=r,X"))]
3628   ""
3629   "@
3630    subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2
3631    subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0"
3632   [(set_attr "type" "marith")
3633    (set_attr "length" "4")])
3635 ;; Bit field instructions.
3637 (define_insn ""
3638   [(set (match_operand:SI 0 "register_operand" "=r")
3639         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3640                          (const_int 32)
3641                          (const_int 0)))]
3642   ""
3643   "or %0,%#r0,%1")
3645 (define_insn "extv"
3646   [(set (match_operand:SI 0 "register_operand" "=r")
3647         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3648                          (match_operand:SI 2 "int5_operand" "")
3649                          (match_operand:SI 3 "int5_operand" "")))]
3650   ""
3651   "*
3653   operands[4] = GEN_INT ((32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3654   return \"ext %0,%1,%2<%4>\";  /* <(32-%2-%3)> */
3656   [(set_attr "type" "bit")])
3658 (define_insn ""
3659   [(set (match_operand:SI 0 "register_operand" "=r")
3660         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3661                          (const_int 32)
3662                          (const_int 0)))]
3663   ""
3664   "or %0,%#r0,%1")
3666 (define_insn "extzv"
3667   [(set (match_operand:SI 0 "register_operand" "=r")
3668         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3669                          (match_operand:SI 2 "int5_operand" "")
3670                          (match_operand:SI 3 "int5_operand" "")))]
3671   ""
3672   "*
3674   operands[4] = GEN_INT ((32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3675   return \"extu %0,%1,%2<%4>\";  /* <(32-%2-%3)> */
3677   [(set_attr "type" "bit")])
3679 (define_insn ""
3680   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3681                          (match_operand:SI 1 "int5_operand" "")
3682                          (match_operand:SI 2 "int5_operand" ""))
3683         (const_int 0))]
3684   ""
3685   "*
3687   operands[3] = GEN_INT ((32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3688   return \"clr %0,%0,%1<%3>\";  /* <(32-%1-%2)> */
3690   [(set_attr "type" "bit")])
3692 (define_insn ""
3693   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3694                          (match_operand:SI 1 "int5_operand" "")
3695                          (match_operand:SI 2 "int5_operand" ""))
3696         (const_int -1))]
3697   ""
3698   "*
3700   operands[3] = GEN_INT ((32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3701   return \"set %0,%0,%1<%3>\";  /* <(32-%1-%2)> */
3703   [(set_attr "type" "bit")])
3705 (define_insn ""
3706   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3707                          (match_operand:SI 1 "int5_operand" "")
3708                          (match_operand:SI 2 "int5_operand" ""))
3709         (match_operand:SI 3 "int32_operand" "n"))]
3710   ""
3711   "*
3713   int value = INTVAL (operands[3]);
3715   if (INTVAL (operands[1]) < 32)
3716     value &= (1 << INTVAL (operands[1])) - 1;
3718   operands[2] = GEN_INT (32 - (INTVAL(operands[1]) + INTVAL(operands[2])));
3720   value <<= INTVAL (operands[2]);
3721   operands[3] = GEN_INT (value);
3723   if (SMALL_INTVAL (value))
3724     return \"clr %0,%0,%1<%2>\;or %0,%0,%3\";
3725   else if ((value & 0x0000ffff) == 0)
3726     return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\";
3727   else
3728     return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\";
3730   [(set_attr "type" "marith")
3731    (set_attr "length" "3")]) ; may be 2 or 3.
3733 ;; negate insns
3734 (define_insn "negsi2"
3735   [(set (match_operand:SI 0 "register_operand" "=r")
3736         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
3737   ""
3738   "subu %0,%#r0,%1")
3740 (define_insn ""
3741   [(set (match_operand:SF 0 "register_operand" "=r,x")
3742         (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))]
3743   ""
3744   "@
3745    fsub.ssd %0,%#r0,%1
3746    fsub.ssd %0,%#x0,%1"
3747   [(set_attr "type" "dpadd")])
3749 (define_insn "negdf2"
3750   [(set (match_operand:DF 0 "register_operand" "=&r,r")
3751         (neg:DF (match_operand:DF 1 "register_operand" "r,0")))]
3752   ""
3753   "@
3754    xor.u %0,%1,0x8000\;or %d0,%#r0,%d1
3755    xor.u %0,%0,0x8000"
3756   [(set_attr "type" "marith,arith")])
3758 (define_insn "negsf2"
3759   [(set (match_operand:SF 0 "register_operand" "=r")
3760         (neg:SF (match_operand:SF 1 "register_operand" "r")))]
3761   ""
3762   "xor.u %0,%1,0x8000")
3764 ;; absolute value insns for floating-point (integer abs can be done using the
3765 ;; machine-independent sequence).
3767 (define_insn "absdf2"
3768   [(set (match_operand:DF 0 "register_operand" "=&r,r")
3769         (abs:DF (match_operand:DF 1 "register_operand" "r,0")))]
3770   ""
3771   "@
3772    and.u %0,%1,0x7fff\;or %d0,%#r0,%d1
3773    and.u %0,%0,0x7fff"
3774   [(set_attr "type" "marith,arith")])
3776 (define_insn "abssf2"
3777   [(set (match_operand:SF 0 "register_operand" "=r")
3778         (abs:SF (match_operand:SF 1 "register_operand" "r")))]
3779   ""
3780   "and.u %0,%1,0x7fff")
3782 ;; Subroutines of "casesi".
3784 ;; Operand 0 is index
3785 ;; operand 1 is the minimum bound
3786 ;; operand 2 is the maximum bound - minimum bound + 1
3787 ;; operand 3 is CODE_LABEL for the table;
3788 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3790 (define_expand "casesi"
3791   ;; We don't use these for generating the RTL, but we must describe
3792   ;; the operands here.
3793   [(match_operand:SI 0 "general_operand" "")
3794    (match_operand:SI 1 "immediate_operand" "")
3795    (match_operand:SI 2 "immediate_operand" "")
3796    (match_operand 3 "" "")
3797    (match_operand 4 "" "")]
3798   ""
3799   "
3801   register rtx index_diff = gen_reg_rtx (SImode);
3802   register rtx low = GEN_INT (-INTVAL (operands[1]));
3803   register rtx label = gen_rtx_LABEL_REF (Pmode, operands[3]);
3804   register rtx base = NULL_RTX;
3806   if (! CASE_VECTOR_INSNS)
3807     /* These instructions are likely to be scheduled and made loop invariant.
3808        This decreases the cost of the dispatch at the expense of the default
3809        case.  */
3810     base = force_reg (SImode, memory_address_noforce (SImode, label));
3812   /* Compute the index difference and handle the default case.  */
3813   emit_insn (gen_addsi3 (index_diff,
3814                          force_reg (SImode, operands[0]),
3815                          ADD_INT (low) ? low : force_reg (SImode, low)));
3816   emit_insn (gen_cmpsi (index_diff, operands[2]));
3817   /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1
3818      entry to the table.  However, that doesn't seem to win on the m88110.  */
3819   emit_jump_insn (gen_bgtu (operands[4]));
3821   if (CASE_VECTOR_INSNS)
3822     /* Call the jump that will branch to the appropriate case.  */
3823     emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3]));
3824   else
3825     /* Load the table entry and jump to it.  */
3826     emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff, operands[3]));
3828   /* Claim that flow drops into the table so it will be adjacent by not
3829      emitting a barrier.  */
3830   DONE;
3833 (define_expand "casesi_jump"
3834   [(set (match_operand:SI 0 "" "")
3835         (mem:SI (plus:SI (match_operand:SI 1 "" "")
3836                          (mult:SI (match_operand:SI 2 "" "")
3837                                   (const_int 4)))))
3838    (parallel [(set (pc) (match_dup 0))
3839               (use (label_ref (match_operand 3 "" "")))])]
3840   ""
3841   "")
3843 (define_insn ""
3844   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
3845    (use (label_ref (match_operand 1 "" "")))]
3846   ""
3847   "jmp%. %0"
3848   [(set_attr "type" "jump")])
3850 ;; The bsr.n instruction is directed to the END of the table.  See
3851 ;; ASM_OUTPUT_CASE_END.
3853 (define_insn "casesi_enter"
3854   [(set (pc) (match_operand 0 "" ""))
3855    (use (match_operand:SI 1 "register_operand" "r"))
3856    ;; The USE here is so that at least one jump-insn will refer to the label,
3857    ;; to keep it alive in jump_optimize.
3858    (use (label_ref (match_operand 2 "" "")))
3859    (clobber (reg:SI 1))]
3860   ""
3861   "*
3863   if (flag_delayed_branch)
3864     return \"bsr.n %0e\;lda %#r1,%#r1[%1]\";
3865   m88k_case_index = REGNO (operands[1]);
3866   return \"bsr %0e\";
3868   [(set_attr "type" "weird")
3869    (set_attr "length" "3")]) ; Including the "jmp r1".
3871 ;;- jump to subroutine
3872 (define_expand "call"
3873   [(parallel [(call (match_operand:SI 0 "" "")
3874                     (match_operand 1 "" ""))
3875               (clobber (reg:SI 1))])]
3876   ""
3877   "
3879   if (GET_CODE (operands[0]) == MEM
3880       && ! call_address_operand (XEXP (operands[0], 0), SImode))
3881     operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
3882                                force_reg (Pmode, XEXP (operands[0], 0)));
3885 (define_insn ""
3886   [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
3887                     (match_operand 1 "" ""))
3888               (clobber (reg:SI 1))])]
3889   ""
3890   "* return output_call (operands, operands[0]);"
3891   [(set_attr "type" "call")])
3893 (define_expand "call_value"
3894   [(parallel [(set (match_operand 0 "register_operand" "")
3895                    (call (match_operand:SI 1 "" "")
3896                          (match_operand 2 "" "")))
3897               (clobber (reg:SI 1))])]
3898   ""
3899   "
3901   if (GET_CODE (operands[1]) == MEM
3902       && ! call_address_operand (XEXP (operands[1], 0), SImode))
3903     operands[1] = gen_rtx_MEM (GET_MODE (operands[1]),
3904                                force_reg (Pmode, XEXP (operands[1], 0)));
3907 (define_insn ""
3908   [(parallel [(set (match_operand 0 "register_operand" "=r")
3909                    (call (mem:SI
3910                           (match_operand:SI 1 "call_address_operand" "rQ"))
3911                          (match_operand 2 "" "")))
3912               (clobber (reg:SI 1))])]
3913   ""
3914   "* return output_call (operands, operands[1]);"
3915   [(set_attr "type" "call")])
3917 ;; Nop instruction and others
3919 (define_insn "nop"
3920   [(const_int 0)]
3921   ""
3922   "ff0 %#r0,%#r0"
3923   [(set_attr "type" "bit")])
3925 (define_insn "return"
3926   [(return)]
3927   "reload_completed"
3928   "jmp%. %#r1"
3929   [(set_attr "type" "jump")])
3931 (define_expand "prologue"
3932   [(const_int 0)]
3933   ""
3934   "m88k_expand_prologue (); DONE;")
3936 (define_expand "epilogue"
3937   [(return)]
3938   "! null_prologue ()"
3939   "m88k_expand_epilogue ();")
3941 (define_insn "blockage"
3942   [(unspec_volatile [(const_int 0)] 0)]
3943   ""
3944   ""
3945   [(set_attr "length" "0")])
3947 (define_insn "indirect_jump"
3948   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
3949   ""
3950   "jmp%. %0"
3951   [(set_attr "type" "jump")])
3953 (define_insn "jump"
3954   [(set (pc)
3955         (label_ref (match_operand 0 "" "")))]
3956   ""
3957   "br%. %l0"
3958   [(set_attr "type" "jump")])
3960 ;; This insn is used for some loop tests, typically loops reversed when
3961 ;; strength reduction is used.  It is actually created when the instruction
3962 ;; combination phase combines the special loop test.  Since this insn
3963 ;; is both a jump insn and has an output, it must deal with its own
3964 ;; reloads, hence the `m' constraints.  The `!' constraints direct reload
3965 ;; to not choose the register alternatives in the event a reload is needed.
3967 (define_expand "decrement_and_branch_until_zero"
3968   [(parallel [(set (pc)
3969                    (if_then_else
3970                     (match_operator 0 "relop_no_unsigned"
3971                                     [(match_operand:SI 1 "register_operand" "")
3972                                      (const_int 0)])
3973                     (label_ref (match_operand 2 "" ""))
3974                     (pc)))
3975               (set (match_dup 1)
3976                    (plus:SI (match_dup 1)
3977                             (match_operand:SI 3 "add_operand" "")))
3978               (clobber (match_scratch:SI 4 ""))
3979               (clobber (match_scratch:SI 5 "=X,X,&r,&r"))])]
3980   ""
3981   "")
3983 (define_insn ""
3984   [(set (pc)
3985         (if_then_else
3986          (match_operator 0 "relop_no_unsigned"
3987                          [(match_operand:SI 1 "register_operand" "+!r,!r,m,m")
3988                           (const_int 0)])
3989           (label_ref (match_operand 2 "" ""))
3990           (pc)))
3991    (set (match_dup 1)
3992         (plus:SI (match_dup 1)
3993                  (match_operand:SI 3 "add_operand" "rI,J,rI,J")))
3994    (clobber (match_scratch:SI 4 "=X,X,&r,&r"))
3995    (clobber (match_scratch:SI 5 "=X,X,&r,&r"))]
3996   "find_reg_note (insn, REG_NONNEG, 0)"
3997   "@
3998    bcnd.n %B0,%1,%2\;addu %1,%1,%3
3999    bcnd.n %B0,%1,%2\;subu %1,%1,%n3
4000    ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1
4001    ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1"
4002   [(set_attr "type" "weird")
4003    (set_attr "length" "2,2,4,4")])
4005 ;; Special insn to serve as the last insn of a define_expand.  This insn
4006 ;; will generate no code.
4008 (define_expand "dummy"
4009   [(set (match_operand 0 "" "") (match_dup 0))]
4010   ""
4011   "")