Initial revision
[official-gcc.git] / gcc / config / m88k / m88k.md
blobbf5124b2244b090d7d6b299753ec50c999bb86ac
1 ;;- Machine description for the Motorola 88000 for GNU C compiler
2 ;;;  Copyright (C) 1988, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
3 ;;  Contributed by Michael Tiemann (tiemann@mcc.com)
4 ;;  Currently maintained by (gcc@dg-rtp.dg.com)
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; RCS rev field.  This is a NOP, just to get the RCS id into the
27 ;; program image.
28 (define_expand "m88k_rcs_id"
29   [(match_operand:SI 0 "" "")]
30   ""
31   "{ static char rcs_id[] = \"$What: <@(#) m88k.md,v    1.1.1.2.2.2> $\";
32      FAIL; }")
34 ;; Attribute describing the processor.  This attribute must match exactly
35 ;; with the processor_type enumeration in m88k.h.
37 ; Target CPU.
38 (define_attr "cpu" "m88100,m88110,m88000"
39   (const (symbol_ref "m88k_cpu")))
41 ; Type of each instruction.  Default is arithmetic.
42 ; I'd like to write the list as this, but genattrtab won't accept it.
44 ; "branch,jump,call,                    ; flow-control instructions
45 ;  load,store,loadd,loada,              ; data unit instructions
46 ;  spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions
47 ;  spmul,dpmul,imul,                    ; FPU multiply instructions
48 ;  arith,bit,mov                        ; integer unit instructions
49 ;  marith,weird"                        ; multi-word instructions
51 ; Classification of each insn.  Some insns of TYPE_BRANCH are multi-word.
52 (define_attr "type"
53   "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird"
54   (const_string "arith"))
56 (define_attr "fpu" "yes,no"
57   (if_then_else
58    (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv")
59    (const_string "yes") (const_string "no")))
61 ; Length in # of instructions of each insn.  The values are not exact, but
62 ; are safe.
63 (define_attr "length" ""
64   (cond [(eq_attr "type" "marith,weird,branch")
65          (const_int 2)]
66         (const_int 1)))
68 ; Describe a user's asm statement.
69 (define_asm_attributes
70   [(set_attr "type" "weird")])
72 ; Define the delay slot requirements for branches and calls.
73 ; The m88100 annuls instructions if a conditional branch is taken.
74 ; For insns of TYPE_BRANCH that are multi-word instructions, the
75 ; delay slot applies to the first instruction.
77 ; @@ For the moment, reorg.c requires that the delay slot of a branch not
78 ; be a call or branch.
80 (define_delay (eq_attr "type" "branch,jump")
81   [(and
82     (and
83      (eq_attr "type" "!branch,jump,call,marith,weird") ; required.
84      (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible.
85     (eq_attr "fpu" "no")) ; issue as-soon-as-possible.
86    (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1)
88 ; output_call supports an unconditional branch in the delay slot of
89 ; a call.  (@@ Support for this case is expected in reorg.c soon.)
91 (define_delay (eq_attr "type" "call")
92   [(eq_attr "type" "!branch,call,marith,weird") ; required.
93    (nil) (nil)])
95 ; An abstract block diagram of the function units for the m88100.
97 ;                           *
98 ;                           |
99 ;                       +---v----+
100 ;                       | decode |
101 ;                       +-vv-v-v-+       fpu
102 ;              ,----------'| | `----------------------.
103 ;              |           | |                        | ,-----.
104 ;         load |     store | | arith                  | |     |
105 ;              |           | |                      +-v-v-+   | dp source
106 ;              |           | |                      | fp1 |---'
107 ;     store    |           | |      div             +-v-v-+
108 ;   ,------.   |           | |    ,-----. ,-----------' `-----------.
109 ;   |      |   |           | |    |     | |                         |
110 ;   |   +--v---v--+    ,---' |    |   +-v-v---+                 +---v---+
111 ;   |   | stage 2 |    |     |    `---| add 2 |                 | mul 2 |
112 ;   |   +---------+    |  +--v--+     +-------+           imul  +-------+
113 ;   |   | stage 1 |    |  | alu |     | add 3 |        ,--------| mul 3 |
114 ;   |   +---------+    |  +--v--+     +-------+        |        +-------+
115 ;   |   | stage 0 |    |     |        | add 4 |        |        | mul 4 |
116 ;   |   +--v---v--+    |     |        +---v---+        |        +-------+
117 ;   |      |   |       |     |            |            |        | mul 5 |
118 ;   |      *   |       |     |            |            |        +---v---+
119 ;   |          |       |     |            |       +----v----+       |
120 ;   |     load |       |     |     fp add `------>| fp last |<------' fp mul
121 ;   |          |       |     |                    +---v-v--^+
122 ;   |          |       |     |                        | |  |
123 ;   |          |       |     |                        | `--' dp dest
124 ;   |          |    +--v-----v--+                     |
125 ;   |          `--->| writeback |<--------------------'
126 ;   |               +--v-----v--+
127 ;   |                  |     |
128 ;   `------------------'     *
130 ; The decode unit need not be specified.
131 ; Consideration of writeback contention is critical to superb scheduling.
133 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
134 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
136 ; Describing the '100 alu is currently not useful.
137 ;(define_function_unit "alu" 1 0 (eq_attr "type"
138 ;                                        "!store,marith,weird") 1 0)
139 ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0)
141 (define_function_unit "alu" 1 0
142   (and (eq_attr "type" "loada,arith,mov") (eq_attr "cpu" "!m88100")) 2 0)
143 (define_function_unit "alu" 1 0
144   (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0)
146 (define_function_unit "bit" 1 0
147   (and (eq_attr "type" "bit") (eq_attr "cpu" "!m88100")) 2 2)
149 (define_function_unit "mem100" 1 0
150   (and (eq_attr "type" "store,loada") (eq_attr "cpu" "m88100")) 1 0)
151 (define_function_unit "mem100" 1 0
152   (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 0)
153 (define_function_unit "mem100" 1 0
154   (and (eq_attr "type" "loadd") (eq_attr "cpu" "m88100")) 3 2)
156 (define_function_unit "mem110" 1 0
157   (and (eq_attr "type" "load,loadd") (eq_attr "cpu" "!m88100")) 3 2)
158 (define_function_unit "mem110" 1 0
159   (and (eq_attr "type" "store") (eq_attr "cpu" "!m88100")) 1 2)
161 ; The times are adjusted to include fp1 and fplast, but then are further
162 ; adjusted based on the actual generated code.  The notation to the right
163 ; is the total latency.  A range denotes a group of instructions and/or
164 ; conditions (the extra clock of fplast time with some sequences).
166 (define_function_unit "fpmul100" 1 0
167   (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 0)          ; 6-8
168 (define_function_unit "fpmul100" 1 0
169   (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 0)          ; 9-10
170 (define_function_unit "fpmul100" 1 0
171   (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 0)           ; 4
173 (define_function_unit "fpmul110" 1 0
174   (and (eq_attr "type" "imul,spmul,dpmul")
175        (eq_attr "cpu" "!m88100")) 5 2)                                  ; 3
177 (define_function_unit "fpadd100" 1 5
178   (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 0)    ; 5-6
179 (define_function_unit "fpadd100" 1 5
180   (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 0)    ; 6-7
182 (define_function_unit "fpadd110" 1 0
183   (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 5 2)   ; 3
184 (define_function_unit "fpadd110" 1 0
185   (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2)   ; 1
187 (define_function_unit "fpadd100" 1 5
188   (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 0)         ; 30-31
189 (define_function_unit "fpadd100" 1 5
190   (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 0)         ; 60-61
191 (define_function_unit "fpadd100" 1 5
192   (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 0)          ; 38
194 (define_function_unit "div" 1 1
195   (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 25 2)        ; 13
196 (define_function_unit "div" 1 1
197   (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 45 2)        ; 23
198 (define_function_unit "div" 1 1
199   (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 35 2)         ; 18
201 ;; Superoptimizer sequences
203 ;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; }
204 ;;      subu.co r5,r2,r3
205 ;;      addu.cio r6,r4,r0
207 (define_split
208   [(set (match_operand:SI 0 "register_operand" "=r")
209         (minus:SI (match_operand:SI 1 "register_operand" "r")
210                   (geu:SI (match_operand:SI 2 "register_operand" "r")
211                           (match_operand:SI 3 "register_operand" "r"))))]
212   ""
213   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
214    (set (match_dup 0)
215         (plus:SI (match_dup 1)
216                  (unspec:SI [(const_int 0)
217                              (reg:CC 0)] 0)))]
218   "")
220 ;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; }
221 ;;      subu.co r5,r3,r2
222 ;;      addu.cio r6,r4,r0
224 (define_split
225   [(set (match_operand:SI 0 "register_operand" "=r")
226         (minus:SI (match_operand:SI 1 "register_operand" "r")
227                   (leu:SI (match_operand:SI 3 "register_operand" "r")
228                           (match_operand:SI 2 "register_operand" "r"))))]
229   ""
230   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
231    (set (match_dup 0)
232         (plus:SI (match_dup 1)
233                  (unspec:SI [(const_int 0)
234                              (reg:CC 0)] 0)))]
235   "")
237 ;; eq0+: { r = (v0 == 0) + v1; }
238 ;;      subu.co r4,r0,r2
239 ;;      addu.cio r5,r3,r0
241 (define_split
242   [(set (match_operand:SI 0 "register_operand" "=r")
243         (minus:SI (match_operand:SI 1 "register_operand" "r")
244                   (eq:SI (match_operand:SI 2 "register_operand" "r")
245                          (const_int 0))))]
246   ""
247   [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
248    (set (match_dup 0)
249         (plus:SI (match_dup 1)
250                  (unspec:SI [(const_int 0)
251                              (reg:CC 0)] 0)))]
252   "")
254 ;; ltu-:  { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); }
255 ;;      subu.co r5,r2,r3
256 ;;      subu.cio r6,r4,r0
258 (define_split
259   [(set (match_operand:SI 0 "register_operand" "=r")
260         (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r")
261                          (match_operand:SI 3 "register_operand" "r"))
262                  (match_operand:SI 1 "register_operand" "r")))]
263   ""
264   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
265    (set (match_dup 0)
266         (minus:SI (match_dup 1)
267                   (unspec:SI [(const_int 0)
268                               (reg:CC 0)] 1)))]
269   "")
271 ;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); }
272 ;;      subu.co r5,r3,r2
273 ;;      subu.cio r6,r4,r0
275 (define_split
276   [(set (match_operand:SI 0 "register_operand" "=r")
277         (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r")
278                          (match_operand:SI 2 "register_operand" "r"))
279                  (match_operand:SI 1 "register_operand" "r")))]
280   ""
281   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
282    (set (match_dup 0)
283         (minus:SI (match_dup 1)
284                  (unspec:SI [(const_int 0)
285                              (reg:CC 0)] 1)))]
286   "")
288 ;; ne0-: { r = v1 - (v0 != 0); }
289 ;;      subu.co r4,r0,r2
290 ;;      subu.cio r5,r3,r0
292 (define_split
293   [(set (match_operand:SI 0 "register_operand" "=r")
294         (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r")
295                         (const_int 0))
296                  (match_operand:SI 1 "register_operand" "r")))]
297   ""
298   [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
299    (set (match_dup 0)
300         (minus:SI (match_dup 1)
301                   (unspec:SI [(const_int 0)
302                               (reg:CC 0)] 1)))]
303   "")
305 ;; ges0-: { r = v1 - ((signed_word) v0 >= 0); }
306 ;;      addu.co r4,r2,r2
307 ;;      subu.cio r5,r3,r0
309 (define_split
310   [(set (match_operand:SI 0 "register_operand" "=r")
311         (minus:SI (match_operand:SI 1 "register_operand" "r")
312                   (xor:SI (lshiftrt:SI
313                            (match_operand:SI 2 "register_operand" "r")
314                            (const_int 31))
315                           (const_int 1))))]
316   ""
317   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0))
318    (set (match_dup 0)
319         (minus:SI (match_dup 1)
320                   (unspec:SI [(const_int 0)
321                               (reg:CC 0)] 1)))]
322   "")
324 ;; This rich set of complex patterns are mostly due to Torbjorn Granlund
325 ;; (tege@sics.se).  They've changed since then, so don't complain to him
326 ;; if they don't work right.
328 ;; Regarding shifts, gen_lshlsi3 generates ASHIFT.  The gen functions
329 ;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing
330 ;; special needs to be done here.
332 ;; Optimize possible cases of the set instruction.
334 (define_insn ""
335   [(set (match_operand:SI 0 "register_operand" "=r")
336         (ashift:SI (const_int -1)
337             (match_operand:SI 1 "register_operand" "r")))]
338   ""
339   "set %0,%#r0,%1"
340   [(set_attr "type" "bit")])
342 (define_insn ""
343   [(set (match_operand:SI 0 "register_operand" "=r")
344         (ior:SI (ashift:SI (const_int -1)
345                     (match_operand:SI 1 "register_operand" "r"))
346          (match_operand:SI 2 "register_operand" "r")))]
347   ""
348   "set %0,%2,%1"
349   [(set_attr "type" "bit")])
351 (define_insn ""
352   [(set (match_operand:SI 0 "register_operand" "=r")
353         (ior:SI (match_operand:SI 1 "register_operand" "r")
354          (ashift:SI (const_int -1)
355                     (match_operand:SI 2 "register_operand" "r"))))]
356   ""
357   "set %0,%1,%2"
358   [(set_attr "type" "bit")])
360 ;; Optimize possible cases of the mak instruction.
362 (define_insn ""
363   [(set (match_operand:SI 0 "register_operand" "=r")
364         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
365                            (match_operand:SI 2 "int5_operand" ""))
366                 (match_operand:SI 3 "immediate_operand" "n")))]
367   "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))"
368   "*
370   operands[4] = gen_rtx (CONST_INT, SImode,
371                          exact_log2 (1 + (INTVAL (operands[3])
372                                           >> INTVAL(operands[2]))));
373   return \"mak %0,%1,%4<%2>\";
375   [(set_attr "type" "bit")])
377 ;; Optimize possible cases of output_and.
379 (define_insn ""
380   [(set (match_operand:SI 0 "register_operand" "=r")
381         (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
382                                     (match_operand:SI 2 "int5_operand" "")
383                                     (match_operand:SI 3 "int5_operand" ""))
384                    (match_operand:SI 4 "int5_operand" "")))]
385   "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
386   "*
388   operands[2]
389     = gen_rtx (CONST_INT, SImode,
390                ((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4]));
391   return output_and (operands);
393   [(set_attr "type" "marith")]) ; arith,bit,marith.  length is 1 or 2.
395 ;; Improve logical operations on compare words
397 ;; We define all logical operations on CCmode values to preserve the pairwise
398 ;; relationship of the compare bits.  This allows a future branch prediction
399 ;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.
400 ;; THIS IS CURRENTLY FALSE! 
402 ;; Opportunities arise when conditional expressions using && and || are made
403 ;; unconditional.  When these are used to branch, the sequence is
404 ;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}.  When these are used to create
405 ;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or
406 ;; cmp/cmp/ext/ext/{and,or} for -1 or 0.
408 ;; When the extracted conditions are the same, the define_split patterns
409 ;; below change extu/extu/{and,or} into {and,or}/extu.  If the reversed
410 ;; conditions match, one compare word can be complimented, resulting in
411 ;; {and.c,or.c}/extu.  These changes are done for ext/ext/{and,or} as well.
412 ;; If the conditions don't line up, one can be rotated.  To keep the pairwise
413 ;; relationship, it may be necessary to both rotate and compliment.  Rotating
414 ;; makes branching cheaper, but doesn't help (or hurt) creating a value, so
415 ;; we don't do this for ext/ext/{and,or}.
417 ;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined
418 ;; into an alternate form of bb0 and bb1.
420 (define_split
421   [(set (match_operand:SI 0 "register_operand" "=r")
422         (ior:SI (neg:SI 
423                  (match_operator 1 "even_relop"
424                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
425                                   (const_int 0)]))
426                 (neg:SI
427                  (match_operator 3 "relop"
428                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
429                                   (const_int 0)]))))
430    (clobber (match_operand:SI 5 "register_operand" "=r"))]
431   ""
432   [(set (match_dup 5)
433         (ior:CCEVEN (match_dup 4)
434                 (match_dup 2)))
435    (set (match_dup 0)
436         (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
437   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
438    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
439      ; /* The conditions match.  */
440    else if (GET_CODE (operands[1])
441             == reverse_condition (GET_CODE (operands[3])))
442      /* Reverse the condition by complimenting the compare word.  */
443      operands[4] = gen_rtx (NOT, CCmode, operands[4]);
444    else
445      {
446        /* Make the condition pairs line up by rotating the compare word.  */
447        int cv1 = condition_value (operands[1]);
448        int cv2 = condition_value (operands[3]);
450        operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
451                               gen_rtx (CONST_INT, VOIDmode,
452                                        ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
453        /* Reverse the condition if needed.  */
454        if ((cv1 & 1) != (cv2 & 1))
455          operands[4] = gen_rtx (NOT, CCmode, operands[4]);
456      }")
458 (define_split
459   [(set (match_operand:SI 0 "register_operand" "=r")
460         (ior:SI (neg:SI 
461                  (match_operator 1 "odd_relop"
462                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
463                                   (const_int 0)]))
464                 (neg:SI
465                  (match_operator 3 "odd_relop"
466                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
467                                   (const_int 0)]))))
468    (clobber (match_operand:SI 5 "register_operand" "=r"))]
469   ""
470   [(set (match_dup 5)
471         (and:CCEVEN (match_dup 4)
472                 (match_dup 2)))
473    (set (match_dup 0)
474         (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
475   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
476    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
477      ; /* The conditions match.  */
478    else
479      {
480        /* Make the condition pairs line up by rotating the compare word.  */
481        int cv1 = condition_value (operands[1]);
482        int cv2 = condition_value (operands[3]);
484        operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
485                               gen_rtx (CONST_INT, VOIDmode,
486                                        (cv2 - cv1) & 0x1f));
487      }")
489 (define_split
490   [(set (match_operand:SI 0 "register_operand" "=r")
491         (ior:SI (neg:SI 
492                  (match_operator 1 "odd_relop"
493                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
494                                   (const_int 0)]))
495                 (neg:SI
496                  (match_operator 3 "even_relop"
497                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
498                                   (const_int 0)]))))
499    (clobber (match_operand:SI 5 "register_operand" "=r"))]
500   ""
501   [(set (match_dup 5)
502         (ior:CCEVEN (not:CC (match_dup 2))
503                 (match_dup 4)))
504    (set (match_dup 0)
505         (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
506   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
507   if (GET_CODE (operands[1])
508             == reverse_condition (GET_CODE (operands[3])))
509      ; 
510    else
511      {
512        /* Make the condition pairs line up by rotating the compare word.  */
513        int cv1 = condition_value (operands[1]);
514        int cv2 = condition_value (operands[3]);
516        operands[2] = gen_rtx (ROTATE, CCmode, operands[2],
517                               gen_rtx (CONST_INT, VOIDmode,
518                                        ((cv1 & ~1) - (cv2 & ~1)) & 0x1f));
519      }")
521 (define_split
522   [(set (match_operand:SI 0 "register_operand" "=r")
523         (ior:SI (match_operator 1 "even_relop"
524                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
525                                  (const_int 0)])
526                 (match_operator 3 "relop"
527                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
528                                  (const_int 0)])))
529    (clobber (match_operand:SI 5 "register_operand" "=r"))]
530   "GET_CODE (operands[1]) == GET_CODE (operands[3])
531    || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
532   [(set (match_dup 5)
533         (ior:CCEVEN (match_dup 4)
534                 (match_dup 2)))
535    (set (match_dup 0)
536         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
537   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
538    /* Reverse the condition by  complimenting the compare word.  */
539    if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
540       operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
542 (define_split
543   [(set (match_operand:SI 0 "register_operand" "=r")
544         (ior:SI (match_operator 1 "odd_relop"
545                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
546                                  (const_int 0)])
547                 (match_operator 3 "odd_relop"
548                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
549                                  (const_int 0)])))
550    (clobber (match_operand:SI 5 "register_operand" "=r"))]
551   "GET_CODE (operands[1]) == GET_CODE (operands[3])"
552   [(set (match_dup 5)
553         (and:CCEVEN (match_dup 4)
554                 (match_dup 2)))
555    (set (match_dup 0)
556         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
557   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
559 (define_split
560   [(set (match_operand:SI 0 "register_operand" "=r")
561         (ior:SI (match_operator 1 "odd_relop"
562                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
563                                  (const_int 0)])
564                 (match_operator 3 "even_relop"
565                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
566                                  (const_int 0)])))
567    (clobber (match_operand:SI 5 "register_operand" "=r"))]
568   "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
569   [(set (match_dup 5)
570         (ior:CCEVEN (not:CC (match_dup 4))
571                 (match_dup 2)))
572    (set (match_dup 0)
573         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
574   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
576 (define_split
577   [(set (match_operand:SI 0 "register_operand" "=r")
578         (and:SI (neg:SI 
579                  (match_operator 1 "even_relop"
580                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
581                                   (const_int 0)]))
582                 (neg:SI
583                  (match_operator 3 "relop"
584                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
585                                   (const_int 0)]))))
586    (clobber (match_operand:SI 5 "register_operand" "=r"))]
587   ""
588   [(set (match_dup 5)
589         (and:CCEVEN (match_dup 4)
590                 (match_dup 2)))
591    (set (match_dup 0)
592         (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
593   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
594    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
595      ; /* The conditions match.  */
596    else if (GET_CODE (operands[1])
597             == reverse_condition (GET_CODE (operands[3])))
598      /* Reverse the condition by complimenting the compare word.  */
599      operands[4] = gen_rtx (NOT, CCmode, operands[4]);
600    else
601      {
602        /* Make the condition pairs line up by rotating the compare word.  */
603        int cv1 = condition_value (operands[1]);
604        int cv2 = condition_value (operands[3]);
605        operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
606                               gen_rtx (CONST_INT, VOIDmode,
607                                        ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
608        /* Reverse the condition if needed.  */
609        if ((cv1 & 1) != (cv2 & 1))
610          operands[4] = gen_rtx (NOT, CCmode, operands[4]);
611      }")
613 (define_split
614   [(set (match_operand:SI 0 "register_operand" "=r")
615         (and:SI (neg:SI 
616                  (match_operator 1 "odd_relop"
617                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
618                                   (const_int 0)]))
619                 (neg:SI
620                  (match_operator 3 "odd_relop"
621                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
622                                   (const_int 0)]))))
623    (clobber (match_operand:SI 5 "register_operand" "=r"))]
624   ""
625   [(set (match_dup 5)
626         (ior:CCEVEN (match_dup 4)
627                 (match_dup 2)))
628    (set (match_dup 0)
629         (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
630   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
631    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
632      ; /* The conditions match.  */
633    else
634      {
635        /* Make the condition pairs line up by rotating the compare word.  */
636        int cv1 = condition_value (operands[1]);
637        int cv2 = condition_value (operands[3]);
638        operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
639                               gen_rtx (CONST_INT, VOIDmode,
640                                        (cv2 - cv1) & 0x1f));
641      }")
643 (define_split
644   [(set (match_operand:SI 0 "register_operand" "=r")
645         (and:SI (neg:SI 
646                  (match_operator 1 "odd_relop"
647                                  [(match_operand 2 "partial_ccmode_register_operand" "%r")
648                                   (const_int 0)]))
649                 (neg:SI
650                  (match_operator 3 "even_relop"
651                                  [(match_operand 4 "partial_ccmode_register_operand" "r")
652                                   (const_int 0)]))))
653    (clobber (match_operand:SI 5 "register_operand" "=r"))]
654   ""
655   [(set (match_dup 5)
656         (and:CCEVEN (not:CC (match_dup 2))
657                 (match_dup 4)))
658    (set (match_dup 0)
659         (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
660   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
661    if (GET_CODE (operands[1])
662             == reverse_condition (GET_CODE (operands[3])))
663         ;
664    else
665      {
666        /* Make the condition pairs line up by rotating the compare word.  */
667        int cv1 = condition_value (operands[1]);
668        int cv2 = condition_value (operands[3]);
669        operands[2] = gen_rtx (ROTATE, CCmode, operands[2],
670                               gen_rtx (CONST_INT, VOIDmode,
671                                        ((cv1 & ~1) - (cv2 & ~1)) & 0x1f));
672      }")
674 (define_split
675   [(set (match_operand:SI 0 "register_operand" "=r")
676         (and:SI (match_operator 1 "even_relop"
677                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
678                                  (const_int 0)])
679                 (match_operator 3 "relop"
680                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
681                                  (const_int 0)])))
682    (clobber (match_operand:SI 5 "register_operand" "=r"))]
683   "GET_CODE (operands[1]) == GET_CODE (operands[3])
684    || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
685   [(set (match_dup 5)
686         (and:CCEVEN (match_dup 4)
687                 (match_dup 2)))
688    (set (match_dup 0)
689         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
690   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
691    /* Reverse the condition by  complimenting the compare word.  */
692    if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
693       operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
695 (define_split
696   [(set (match_operand:SI 0 "register_operand" "=r")
697         (and:SI (match_operator 1 "odd_relop"
698                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
699                                  (const_int 0)])
700                 (match_operator 3 "odd_relop"
701                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
702                                  (const_int 0)])))
703    (clobber (match_operand:SI 5 "register_operand" "=r"))]
704   "GET_CODE (operands[1]) == GET_CODE (operands[3])"
705   [(set (match_dup 5)
706         (ior:CCEVEN (match_dup 4)
707                 (match_dup 2)))
708    (set (match_dup 0)
709         (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
710   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
712 (define_split
713   [(set (match_operand:SI 0 "register_operand" "=r")
714         (and:SI (match_operator 1 "odd_relop"
715                                 [(match_operand 2 "partial_ccmode_register_operand" "%r")
716                                  (const_int 0)])
717                 (match_operator 3 "even_relop"
718                                 [(match_operand 4 "partial_ccmode_register_operand" "r")
719                                  (const_int 0)])))
720    (clobber (match_operand:SI 5 "register_operand" "=r"))]
721   "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
722   [(set (match_dup 5)
723         (and:CCEVEN (not:CC (match_dup 2))
724                 (match_dup 4)))
725    (set (match_dup 0)
726         (match_op_dup 3 [(match_dup 5) (const_int 0)]))]
727   "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
730 ;; Logical operations on compare words.
732 (define_insn ""
733   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
734         (and:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
735                 (match_operand 2 "partial_ccmode_register_operand" "r")))]
736   ""
737   "and.c %0,%2,%1")
739 (define_insn ""
740   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
741         (and:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
742                 (match_operand 2 "partial_ccmode_register_operand" "r")))]
743   ""
744   "and %0,%1,%2")
746 (define_insn ""
747   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
748         (ior:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
749                 (match_operand 2 "partial_ccmode_register_operand" "r")))]
750   ""
751   "or.c %0,%2,%1")
753 (define_insn ""
754   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
755         (ior:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
756                 (match_operand 2 "partial_ccmode_register_operand" "r")))]
757   ""
758   "or %0,%1,%2")
760 (define_insn ""
761   [(set (match_operand:CC 0 "register_operand" "=r")
762         (rotate:CC (match_operand:CC 1 "register_operand" "r")
763                    (match_operand:CC 2 "int5_operand" "")))]
764   ""
765   "rot %0,%1,%2"
766   [(set_attr "type" "bit")])
768 (define_insn ""
769   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
770         (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
771                    (match_operand:CC 2 "int5_operand" "")))]
772   ""
773   "rot %0,%1,%2"
774   [(set_attr "type" "bit")])
776 ;; rotate/and[.c] and rotate/ior[.c]
778 (define_split
779   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
780         (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
781                            (match_operand:CC 2 "int5_operand" ""))
782                 (match_operand 3 "partial_ccmode_register_operand" "r")))
783    (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
784   ""
785   [(set (match_dup 4)
786         (rotate:CC (match_dup 1) (match_dup 2)))
787    (set (match_dup 0)
788         (ior:CCEVEN (match_dup 4) (match_dup 3)))]
789   "")
791 (define_insn ""
792   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
793         (ior:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
794                            (match_operand:CC 2 "int5_operand" ""))
795                 (match_operand 3 "partial_ccmode_register_operand" "r")))
796    (clobber (match_scratch:CCEVEN 4 "=r"))]
797   ""
798   "#")
800 (define_split
801   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
802         (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
803                                    (match_operand:CC 2 "int5_operand" "")))
804                 (match_operand 3 "partial_ccmode_register_operand" "r")))
805    (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
806   ""
807   [(set (match_dup 4)
808         (rotate:CC (match_dup 1) (match_dup 2)))
809    (set (match_dup 0)
810         (ior:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
811   "")
813 (define_insn ""
814   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
815         (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
816                                    (match_operand:CC 2 "int5_operand" "")))
817                 (match_operand 3 "partial_ccmode_register_operand" "r")))
818    (clobber (match_scratch:CCEVEN 4 "=r"))]
819   ""
820   "#")
822 (define_split
823   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
824         (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
825                            (match_operand:CC 2 "int5_operand" ""))
826                 (match_operand 3 "partial_ccmode_register_operand" "r")))
827    (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
828   ""
829   [(set (match_dup 4)
830         (rotate:CC (match_dup 1) (match_dup 2)))
831    (set (match_dup 0)
832         (and:CCEVEN (match_dup 4) (match_dup 3)))]
833   "")
835 (define_insn ""
836   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
837         (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
838                            (match_operand:CC 2 "int5_operand" ""))
839                 (match_operand 3 "partial_ccmode_register_operand" "r")))
840    (clobber (match_scratch:CCEVEN 4 "=r"))]
841   ""
842   "#")
844 (define_split
845   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
846         (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
847                                    (match_operand:CC 2 "int5_operand" "")))
848                 (match_operand 3 "partial_ccmode_register_operand" "r")))
849    (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
850   ""
851   [(set (match_dup 4)
852         (rotate:CC (match_dup 1) (match_dup 2)))
853    (set (match_dup 0)
854         (and:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
855   "")
857 (define_insn ""
858   [(set (match_operand:CCEVEN 0 "register_operand" "=r")
859         (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
860                                    (match_operand:CC 2 "int5_operand" "")))
861                 (match_operand 3 "partial_ccmode_register_operand" "r")))
862    (clobber (match_scratch:CCEVEN 4 "=r"))]
863   ""
864   "#")
867 ;; Recognize bcnd instructions for integer values.  This is distinguished
868 ;; from a conditional branch instruction (below) with SImode instead of
869 ;; CCmode.
871 (define_insn ""
872   [(set (pc)
873         (if_then_else
874          (match_operator 0 "relop_no_unsigned"
875                          [(match_operand:SI 1 "register_operand" "r")
876                           (const_int 0)])
877          (match_operand 2 "pc_or_label_ref" "")
878          (match_operand 3 "pc_or_label_ref" "")))]
879   ""
880   "bcnd%. %R3%B0,%1,%P2%P3"
881   [(set_attr "type" "branch")])
883 ;; Recognize tests for sign and zero.
885 (define_insn ""
886   [(set (pc)
887         (if_then_else
888          (match_operator 0 "equality_op"
889                          [(match_operand:SI 1 "register_operand" "r")
890                           (const_int -2147483648)])
891          (match_operand 2 "pc_or_label_ref" "")
892          (match_operand 3 "pc_or_label_ref" "")))]
893   ""
894   "bcnd%. %R3%E0,%1,%P2%P3"
895   [(set_attr "type" "branch")])
897 (define_insn ""
898   [(set (pc)
899         (if_then_else
900          (match_operator 0 "equality_op"
901                          [(zero_extract:SI
902                            (match_operand:SI 1 "register_operand" "r")
903                            (const_int 31)
904                            (const_int 1))
905                           (const_int 0)])
906          (match_operand 2 "pc_or_label_ref" "")
907          (match_operand 3 "pc_or_label_ref" "")))]
908   ""
909   "bcnd%. %R3%D0,%1,%P2%P3"
910   [(set_attr "type" "branch")])
912 ;; Recognize bcnd instructions for double integer values
914 (define_insn ""
915   [(set (pc)
916         (if_then_else
917          (match_operator 0 "relop_no_unsigned"
918                          [(sign_extend:DI
919                            (match_operand:SI 1 "register_operand" "r"))
920                           (const_int 0)])
921          (match_operand 2 "pc_or_label_ref" "")
922          (match_operand 3 "pc_or_label_ref" "")))]
923   ""
924   "bcnd%. %R3%B0,%1,%P2%P3"
925   [(set_attr "type" "branch")])
927 (define_insn ""
928   [(set (pc)
929         (if_then_else
930          (match_operator 0 "equality_op"
931                          [(zero_extend:DI
932                            (match_operand:SI 1 "register_operand" "r"))
933                           (const_int 0)])
934          (match_operand 2 "pc_or_label_ref" "")
935          (match_operand 3 "pc_or_label_ref" "")))]
936   ""
937   "bcnd%. %R3%B0,%1,%P2%P3"
938   [(set_attr "type" "branch")])
940 ; @@ I doubt this is interesting until cmpdi is provided.  Anyway, it needs
941 ; to be reworked.
943 ;(define_insn ""
944 ;  [(set (pc)
945 ;       (if_then_else
946 ;        (match_operator 0 "relop_no_unsigned"
947 ;                        [(match_operand:DI 1 "register_operand" "r")
948 ;                         (const_int 0)])
949 ;        (match_operand 2 "pc_or_label_ref" "")
950 ;        (match_operand 3 "pc_or_label_ref" "")))]
951 ;  ""
952 ;  "*
954 ;  switch (GET_CODE (operands[0]))
955 ;    {
956 ;    case EQ:
957 ;    case NE:
958 ;      /* I'm not sure if it's safe to use .n here.  */
959 ;      return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\";
960 ;    case GE:
961 ;    case LT:
962 ;      return \"bcnd%. %R3%B0,%1,%P2%P3\";
963 ;    case GT:
964 ;      {
965 ;       rtx op2 = operands[2];
966 ;       operands[2] = operands[3];
967 ;       operands[3] = op2;
968 ;      }
969 ;    case LE:
970 ;      if (GET_CODE (operands[3]) == LABEL_REF)
971 ;       {
972 ;         int label_num;
973 ;         operands[2] = gen_label_rtx ();
974 ;         label_num = XINT (operands[2], 3);
975 ;         output_asm_insn
976 ;           (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands);
977 ;         output_label (label_num);
978 ;         return \"\";
979 ;       }
980 ;      else
981 ;       return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\";
982 ;    }
983 ;}")
985 ;; Recognize bcnd instructions for single precision float values
986 ;; Exclude relational operations as they must signal NaNs.
988 ;; @@ These bcnd insns for float and double values don't seem to be recognized.
990 (define_insn ""
991   [(set (pc)
992         (if_then_else
993          (match_operator 0 "equality_op"
994                          [(float_extend:DF
995                            (match_operand:SF 1 "register_operand" "r"))
996                           (const_int 0)])
997          (match_operand 2 "pc_or_label_ref" "")
998          (match_operand 3 "pc_or_label_ref" "")))]
999   ""
1000   "bcnd%. %R3%D0,%1,%P2%P3"
1001   [(set_attr "type" "branch")])
1003 (define_insn ""
1004   [(set (pc)
1005         (if_then_else
1006          (match_operator 0 "equality_op"
1007                          [(match_operand:SF 1 "register_operand" "r")
1008                           (const_int 0)])
1009          (match_operand 2 "pc_or_label_ref" "")
1010          (match_operand 3 "pc_or_label_ref" "")))]
1011   ""
1012   "bcnd%. %R3%D0,%1,%P2%P3"
1013   [(set_attr "type" "branch")])
1015 ;; Recognize bcnd instructions for double precision float values
1016 ;; Exclude relational operations as they must signal NaNs.
1018 (define_insn ""
1019   [(set (pc)
1020         (if_then_else
1021          (match_operator 0 "equality_op"
1022                          [(match_operand:DF 1 "register_operand" "r")
1023                           (const_int 0)])
1024          (match_operand 2 "pc_or_label_ref" "")
1025          (match_operand 3 "pc_or_label_ref" "")))]
1026   ""
1027   "*
1029   int label_num;
1031   if (GET_CODE (operands[0]) == NE)
1032     {
1033       rtx op2 = operands[2];
1034       operands[2] = operands[3];
1035       operands[3] = op2;
1036     }
1037   if (GET_CODE (operands[3]) == LABEL_REF)
1038     return \"bcnd 0x5,%1,%3\;bcnd %#ne0,%d1,%3\";
1040   operands[3] = gen_label_rtx ();
1041   label_num = XINT (operands[3], 3);
1042   output_asm_insn (\"bcnd 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands);
1043   output_label (label_num);
1044   return \"\";
1046   [(set_attr "type" "weird")
1047    (set_attr "length" "3")])
1049 ;; Recognize bb0 and bb1 instructions.  These use two unusual template
1050 ;; patterns, %Lx and %Px.  %Lx outputs a 1 if operand `x' is a LABEL_REF
1051 ;; otherwise it outputs a 0.  It then may print ".n" if the delay slot
1052 ;; is used.  %Px does noting if `x' is PC and outputs the operand if `x'
1053 ;; is a LABEL_REF.
1055 (define_insn ""
1056   [(set (pc)
1057         (if_then_else
1058          (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1059                               (const_int 1)
1060                               (match_operand:SI 1 "int5_operand" ""))
1061              (const_int 0))
1062          (match_operand 2 "pc_or_label_ref" "")
1063          (match_operand 3 "pc_or_label_ref" "")))]
1064   ""
1065   "bb%L2 (31-%1),%0,%P2%P3"
1066   [(set_attr "type" "branch")])
1068 (define_insn ""
1069   [(set (pc)
1070         (if_then_else
1071          (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1072                               (const_int 1)
1073                               (match_operand:SI 1 "int5_operand" ""))
1074              (const_int 0))
1075          (match_operand 2 "pc_or_label_ref" "")
1076          (match_operand 3 "pc_or_label_ref" "")))]
1077   ""
1078   "bb%L3 (31-%1),%0,%P2%P3"
1079   [(set_attr "type" "branch")])
1081 (define_insn ""
1082   [(set (pc)
1083         (if_then_else
1084          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1085                               (const_int 1)
1086                               (match_operand:SI 1 "int5_operand" ""))
1087              (const_int 0))
1088          (match_operand 2 "pc_or_label_ref" "")
1089          (match_operand 3 "pc_or_label_ref" "")))]
1090   ""
1091   "bb%L2 (31-%1),%0,%P2%P3"
1092   [(set_attr "type" "branch")])
1094 (define_insn ""
1095   [(set (pc)
1096         (if_then_else
1097          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1098                               (const_int 1)
1099                               (match_operand:SI 1 "int5_operand" ""))
1100              (const_int 0))
1101          (match_operand 2 "pc_or_label_ref" "")
1102          (match_operand 3 "pc_or_label_ref" "")))]
1103   ""
1104   "bb%L3 (31-%1),%0,%P2%P3"
1105   [(set_attr "type" "branch")])
1107 (define_insn ""
1108   [(set (pc)
1109         (if_then_else
1110          (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1111                      (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1112               (const_int 0))
1113          (match_operand 2 "pc_or_label_ref" "")
1114          (match_operand 3 "pc_or_label_ref" "")))]
1115   "(GET_CODE (operands[0]) == CONST_INT)
1116    != (GET_CODE (operands[1]) == CONST_INT)"
1117   "bb%L3 %p1,%0,%P2%P3"
1118   [(set_attr "type" "branch")])
1120 (define_insn ""
1121   [(set (pc)
1122         (if_then_else
1123          (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1124                      (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1125              (const_int 0))
1126          (match_operand 2 "pc_or_label_ref" "")
1127          (match_operand 3 "pc_or_label_ref" "")))]
1128   "(GET_CODE (operands[0]) == CONST_INT)
1129    != (GET_CODE (operands[1]) == CONST_INT)"
1130   "bb%L2 %p1,%0,%P2%P3"
1131   [(set_attr "type" "branch")])
1133 ;; The comparison operations store the comparison into a register and
1134 ;; record that register.  The following Bxx or Sxx insn uses that
1135 ;; register as an input.  To facilitate use of bcnd instead of cmp/bb1,
1136 ;; cmpsi records it's operands and produces no code when any operand
1137 ;; is constant.  In this case, the Bxx insns use gen_bcnd and the
1138 ;; Sxx insns use gen_test to ensure a cmp has been emitted.
1140 ;; This could also be done for SFmode and DFmode having only beq and bne
1141 ;; use gen_bcnd.  The others must signal NaNs.  It seems though that zero
1142 ;; has already been copied into a register.
1144 ;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand
1145 ;; is a constant.  (This idea is due to Torbjorn Granlund.)  Others can
1146 ;; use bcnd only if an operand is zero.
1148 ;; It is necessary to distinguish a register holding condition codes.
1149 ;; This is done by context.
1151 (define_expand "test"
1152   [(set (match_dup 2)
1153         (compare:CC (match_operand 0 "" "")
1154                     (match_operand 1 "" "")))]
1155   ""
1156   "
1158   if (m88k_compare_reg)
1159     abort ();
1161   if (GET_CODE (operands[0]) == CONST_INT
1162       && ! SMALL_INT (operands[0]))
1163     operands[0] = force_reg (SImode, operands[0]);
1165   if (GET_CODE (operands[1]) == CONST_INT
1166       && ! SMALL_INT (operands[1]))
1167     operands[1] = force_reg (SImode, operands[1]);
1169   operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1172 ; @@ The docs say don't do this.  It's probably a nop since the insn looks
1173 ; identical to cmpsi against zero.  Is there an advantage to providing
1174 ; this, perhaps with a different form?
1176 ;(define_expand "tstsi"
1177 ;  [(set (match_dup 1)
1178 ;       (compare:CC (match_operand:SI 0 "register_operand" "")
1179 ;                   (const_int 0)))]
1180 ; ""
1181 ; "
1183 ;  m88k_compare_reg = 0;
1184 ;  m88k_compare_op0 = operands[0];
1185 ;  m88k_compare_op1 = const0_rtx;
1186 ;  DONE;
1187 ;}")
1189 (define_expand "cmpsi"
1190   [(set (match_dup 2)
1191         (compare:CC (match_operand:SI 0 "register_operand" "")
1192                     (match_operand:SI 1 "arith32_operand" "")))]
1193   ""
1194   "
1196   if (GET_CODE (operands[0]) == CONST_INT
1197       || GET_CODE (operands[1]) == CONST_INT)
1198     {
1199       m88k_compare_reg = 0;
1200       m88k_compare_op0 = operands[0];
1201       m88k_compare_op1 = operands[1];
1202       DONE;
1203     }
1204   operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1207 (define_expand "cmpsf"
1208   [(set (match_dup 2)
1209         (compare:CC (match_operand:SF 0 "register_operand" "")
1210                     (match_operand:SF 1 "register_operand" "")))]
1211   ""
1212   "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")
1214 (define_expand "cmpdf"
1215   [(set (match_dup 2)
1216         (compare:CC (match_operand:DF 0 "general_operand" "")
1217                     (match_operand:DF 1 "general_operand" "")))]
1218   ""
1219   "
1221   operands[0] = legitimize_operand (operands[0], DFmode);
1222   operands[1] = legitimize_operand (operands[1], DFmode);
1223   operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1226 ; @@ Get back to this later on.
1228 ;(define_insn "cmpdi"
1229 ;  [(set (cc0)
1230 ;       (compare:CC (match_operand:DI 0 "register_operand" "r")
1231 ;                   (match_operand:DI 1 "register_operand" "r")))]
1232 ;  ""
1233 ;  "*
1235 ;  if ((cc_status.mdep & MDEP_LS_CHANGE) != 0)
1236 ;    abort ();  /* output_move_double MDEP_LS_CHANGE bits were set. */
1238 ;  cc_status.mdep &= ~ MDEP_LS_MASK;
1240 ;  operands[2] = gen_label_rtx ();
1241 ;  /* Remember, %! is the condition code register and %@ is the
1242 ;     literal synthesis register.  */
1244 ;  output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\",
1245 ;                  operands);
1247 ;  output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands);
1248 ;  output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands);
1249 ;  output_label (XINT (operands[2], 3));
1250 ;  return \"\";
1253 ;; The actual compare instructions.
1255 (define_insn ""
1256   [(set (match_operand:CC 0 "register_operand" "=r")
1257         (compare:CC (match_operand:SI 1 "register_operand" "rO")
1258                     (match_operand:SI 2 "arith_operand" "rI")))]
1259   ""
1260   "cmp %0,%r1,%2")
1262 (define_insn ""
1263   [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1264         (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x")
1265                     (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))]
1266   ""
1267   "@
1268    fcmp.sss %0,%1,%2
1269    fcmp.sss %0,%1,%#r0
1270    fcmp.sss %0,%1,%2
1271    fcmp.sss %0,%1,%#x0"
1272   [(set_attr "type" "spcmp")])
1274 (define_insn ""
1275   [(set (match_operand:CC 0 "register_operand" "=r,r")
1276         (compare:CC (match_operand:DF 1 "register_operand" "r,x")
1277                     (float_extend:DF
1278                      (match_operand:SF 2 "register_operand" "r,x"))))]
1279   ""
1280   "fcmp.sds %0,%1,%2"
1281   [(set_attr "type" "dpcmp")])
1283 (define_insn ""
1284   [(set (match_operand:CC 0 "register_operand" "=r,r")
1285         (compare:CC (float_extend:DF
1286                      (match_operand:SF 1 "register_operand" "r,x"))
1287                     (match_operand:DF 2 "register_operand" "r,x")))]
1288   ""
1289   "fcmp.ssd %0,%1,%2"
1290   [(set_attr "type" "dpcmp")])
1292 (define_insn ""
1293   [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1294         (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x")
1295                     (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))]
1296   ""
1297   "@
1298    fcmp.sdd %0,%1,%2
1299    fcmp.sds %0,%1,%#r0
1300    fcmp.sdd %0,%1,%2
1301    fcmp.sds %0,%1,%#x0"
1302   [(set_attr "type" "dpcmp")])
1304 ;; Store condition code insns.  The compare insns set a register
1305 ;; rather than cc0 and record that register for use here.  See above
1306 ;; for the special treatment of cmpsi with a constant operand.
1308 ;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons.
1310 (define_expand "seq"
1311   [(set (match_operand:SI 0 "register_operand" "")
1312         (match_dup 1))]
1313   ""
1314   "operands[1] = emit_test (EQ, SImode);")
1316 (define_expand "sne"
1317   [(set (match_operand:SI 0 "register_operand" "")
1318         (match_dup 1))]
1319   ""
1320   "operands[1] = emit_test (NE, SImode);")
1322 (define_expand "sgt"
1323   [(set (match_operand:SI 0 "register_operand" "")
1324         (match_dup 1))]
1325   ""
1326   "operands[1] = emit_test (GT, SImode);")
1328 (define_expand "sgtu"
1329   [(set (match_operand:SI 0 "register_operand" "")
1330         (match_dup 1))]
1331   ""
1332   "operands[1] = emit_test (GTU, SImode);")
1334 (define_expand "slt"
1335   [(set (match_operand:SI 0 "register_operand" "")
1336         (match_dup 1))]
1337   ""
1338   "operands[1] = emit_test (LT, SImode);")
1340 (define_expand "sltu"
1341   [(set (match_operand:SI 0 "register_operand" "")
1342         (match_dup 1))]
1343   ""
1344   "operands[1] = emit_test (LTU, SImode);")
1346 (define_expand "sge"
1347   [(set (match_operand:SI 0 "register_operand" "")
1348         (match_dup 1))]
1349   ""
1350   "operands[1] = emit_test (GE, SImode);")
1352 (define_expand "sgeu"
1353   [(set (match_operand:SI 0 "register_operand" "")
1354         (match_dup 1))]
1355   ""
1356   "operands[1] = emit_test (GEU, SImode);")
1358 (define_expand "sle"
1359   [(set (match_operand:SI 0 "register_operand" "")
1360         (match_dup 1))]
1361   ""
1362   "operands[1] = emit_test (LE, SImode);")
1364 (define_expand "sleu"
1365   [(set (match_operand:SI 0 "register_operand" "")
1366         (match_dup 1))]
1367   ""
1368   "operands[1] = emit_test (LEU, SImode);")
1370 ;; The actual set condition code instruction.
1372 (define_insn ""
1373   [(set (match_operand:SI 0 "register_operand" "=r")
1374         (match_operator:SI 1 "relop"
1375                            [(match_operand:CC 2 "register_operand" "r")
1376                             (const_int 0)]))]
1377   ""
1378   "ext %0,%2,1<%C1>"
1379   [(set_attr "type" "bit")])
1381 (define_insn ""
1382   [(set (match_operand:SI 0 "register_operand" "=r")
1383         (match_operator:SI 1 "even_relop"
1384                            [(match_operand:CCEVEN 2 "register_operand" "r")
1385                             (const_int 0)]))]
1386   ""
1387   "ext %0,%2,1<%C1>"
1388   [(set_attr "type" "bit")])
1390 (define_insn ""
1391   [(set (match_operand:SI 0 "register_operand" "=r")
1392         (not:SI (match_operator:SI 1 "odd_relop"
1393                            [(match_operand:CCEVEN 2 "register_operand" "r")
1394                             (const_int 0)])))]
1395   ""
1396   "ext %0,%2,1<%!%C1>"
1397   [(set_attr "type" "bit")])
1399 (define_split
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_operand:SI 3 "register_operand" "=r"))]
1405   ""
1406   [(set (match_dup 3) (not:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])))
1407    (set (match_dup 0) (not:SI (match_dup 3)))]
1408   "")
1410 (define_insn ""
1411   [(set (match_operand:SI 0 "register_operand" "=r")
1412         (match_operator:SI 1 "odd_relop"
1413                            [(match_operand:CCEVEN 2 "register_operand" "r")
1414                             (const_int 0)]))
1415    (clobber (match_scratch:SI 3 "=r"))]
1416   ""
1417   "#")
1419 (define_insn ""
1420   [(set (match_operand:SI 0 "register_operand" "=r")
1421         (neg:SI
1422          (match_operator:SI 1 "relop"
1423                             [(match_operand:CC 2 "register_operand" "r")
1424                              (const_int 0)])))]
1425   ""
1426   "extu %0,%2,1<%C1>"
1427   [(set_attr "type" "bit")])
1429 (define_insn ""
1430   [(set (match_operand:SI 0 "register_operand" "=r")
1431         (neg:SI
1432          (match_operator:SI 1 "even_relop"
1433                             [(match_operand:CCEVEN 2 "register_operand" "r")
1434                              (const_int 0)])))]
1435   ""
1436   "extu %0,%2,1<%C1>"
1437   [(set_attr "type" "bit")])
1439 (define_insn ""
1440   [(set (match_operand:SI 0 "register_operand" "=r")
1441         (neg:SI
1442          (not:SI (match_operator:SI 1 "odd_relop"
1443                             [(match_operand:CCEVEN 2 "register_operand" "r")
1444                              (const_int 0)]))))]
1445   ""
1446   "extu %0,%2,1<%!%C1>"
1447   [(set_attr "type" "bit")])
1449 (define_split
1450   [(set (match_operand:SI 0 "register_operand" "=r")
1451         (neg:SI (match_operator:SI 1 "odd_relop"
1452                            [(match_operand:CCEVEN 2 "register_operand" "r")
1453                             (const_int 0)])))
1454    (clobber (match_operand:SI 3 "register_operand" "=r"))]
1455   ""
1456   [(set (match_dup 3) (neg:SI (not:SI (match_op_dup 1 [(match_dup 2)
1457                                                        (const_int 0)]))))
1458    (set (match_dup 0) (xor:SI (match_dup 3) (const_int 1)))]
1459   "")
1461 (define_insn
1462  ""
1463   [(set (match_operand:SI 0 "register_operand" "=r")
1464         (neg:SI (match_operator:SI 1 "odd_relop"
1465                            [(match_operand:CCEVEN 2 "register_operand" "r")
1466                             (const_int 0)])))
1467    (clobber (match_scratch:SI 3 "=r"))]
1468   ""
1469   "#")
1474 ;; Conditional branch insns.  The compare insns set a register
1475 ;; rather than cc0 and record that register for use here.  See above
1476 ;; for the special case of cmpsi with a constant operand.
1478 (define_expand "bcnd"
1479   [(set (pc)
1480         (if_then_else (match_operand 0 "" "")
1481                       (label_ref (match_operand 1 "" ""))
1482                       (pc)))]
1483   ""
1484   "if (m88k_compare_reg) abort ();")
1486 (define_expand "bxx"
1487   [(set (pc)
1488         (if_then_else (match_operand 0 "" "")
1489                       (label_ref (match_operand 1 "" ""))
1490                       (pc)))]
1491   ""
1492   "if (m88k_compare_reg == 0) abort ();")
1494 (define_expand "beq"
1495   [(set (pc)
1496         (if_then_else (eq (match_dup 1) (const_int 0))
1497                       (label_ref (match_operand 0 "" ""))
1498                       (pc)))]
1499   ""
1500   "if (m88k_compare_reg == 0)
1501      {
1502        emit_bcnd (EQ, operands[0]);
1503        DONE;
1504      }
1505    operands[1] = m88k_compare_reg;")
1507 (define_expand "bne"
1508   [(set (pc)
1509         (if_then_else (ne (match_dup 1) (const_int 0))
1510                       (label_ref (match_operand 0 "" ""))
1511                       (pc)))]
1512   ""
1513   "if (m88k_compare_reg == 0)
1514      {
1515        emit_bcnd (NE, operands[0]);
1516        DONE;
1517      }
1518    operands[1] = m88k_compare_reg;")
1520 (define_expand "bgt"
1521   [(set (pc)
1522         (if_then_else (gt (match_dup 1) (const_int 0))
1523                       (label_ref (match_operand 0 "" ""))
1524                       (pc)))]
1525   ""
1526   "if (m88k_compare_reg == 0)
1527      {
1528        emit_bcnd (GT, operands[0]);
1529        DONE;
1530      }
1531    operands[1] = m88k_compare_reg;")
1533 (define_expand "bgtu"
1534   [(set (pc)
1535         (if_then_else (gtu (match_dup 1) (const_int 0))
1536                       (label_ref (match_operand 0 "" ""))
1537                       (pc)))]
1538   ""
1539   "if (m88k_compare_reg == 0)
1540      {
1541        emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0]));
1542        DONE;
1543      }
1544    operands[1] = m88k_compare_reg;")
1546 (define_expand "blt"
1547   [(set (pc)
1548         (if_then_else (lt (match_dup 1) (const_int 0))
1549                       (label_ref (match_operand 0 "" ""))
1550                       (pc)))]
1551   ""
1552   "if (m88k_compare_reg == 0)
1553      {
1554        emit_bcnd (LT, operands[0]);
1555        DONE;
1556      }
1557    operands[1] = m88k_compare_reg;")
1559 (define_expand "bltu"
1560   [(set (pc)
1561         (if_then_else (ltu (match_dup 1) (const_int 0))
1562                       (label_ref (match_operand 0 "" ""))
1563                       (pc)))]
1564   ""
1565   "if (m88k_compare_reg == 0)
1566      {
1567        emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0]));
1568        DONE;
1569      }
1570    operands[1] = m88k_compare_reg;")
1572 (define_expand "bge"
1573   [(set (pc)
1574         (if_then_else (ge (match_dup 1) (const_int 0))
1575                       (label_ref (match_operand 0 "" ""))
1576                       (pc)))]
1577   ""
1578   "if (m88k_compare_reg == 0)
1579      {
1580        emit_bcnd (GE, operands[0]);
1581        DONE;
1582      }
1583    operands[1] = m88k_compare_reg;")
1585 (define_expand "bgeu"
1586   [(set (pc)
1587         (if_then_else (geu (match_dup 1) (const_int 0))
1588                       (label_ref (match_operand 0 "" ""))
1589                       (pc)))]
1590   ""
1591   "if (m88k_compare_reg == 0)
1592      {
1593        emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0]));
1594        DONE;
1595      }
1596    operands[1] = m88k_compare_reg;")
1598 (define_expand "ble"
1599   [(set (pc)
1600         (if_then_else (le (match_dup 1) (const_int 0))
1601                       (label_ref (match_operand 0 "" ""))
1602                       (pc)))]
1603   ""
1604   "if (m88k_compare_reg == 0)
1605      {
1606        emit_bcnd (LE, operands[0]);
1607        DONE;
1608      }
1609    operands[1] = m88k_compare_reg;")
1611 (define_expand "bleu"
1612   [(set (pc)
1613         (if_then_else (leu (match_dup 1) (const_int 0))
1614                       (label_ref (match_operand 0 "" ""))
1615                       (pc)))]
1616   ""
1617   "if (m88k_compare_reg == 0)
1618      {
1619        emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0]));
1620        DONE;
1621      }
1622    operands[1] = m88k_compare_reg;")
1624 ;; The actual conditional branch instruction (both directions).  This
1625 ;; uses two unusual template patterns, %Rx and %Px.  %Rx is a prefix code
1626 ;; for the immediately following condition and reverses the condition iff
1627 ;; operand `x' is a LABEL_REF.  %Px does nothing if `x' is PC and outputs
1628 ;; the operand if `x' is a LABEL_REF.
1630 (define_insn ""
1631   [(set (pc) (if_then_else
1632               (match_operator 0 "relop"
1633                               [(match_operand:CC 1 "register_operand" "r")
1634                                (const_int 0)])
1635               (match_operand 2 "pc_or_label_ref" "")
1636               (match_operand 3 "pc_or_label_ref" "")))]
1637   ""
1638   "*
1640   if (mostly_false_jump (insn, operands[0]))
1641     return \"bb0%. %R2%C0,%1,%P2%P3\";
1642   else
1643     return \"bb1%. %R3%C0,%1,%P2%P3\";
1645   [(set_attr "type" "branch")])
1648 ;; Here branch prediction is sacrificed. To get it back, you need 
1649 ;;  - CCODD (CC mode where the ODD bits are valid)
1650 ;;  - several define_split that can apply De Morgan's Law.
1651 ;;  - transformations between CCEVEN and CCODD modes. 
1652 ;;  
1654 (define_insn ""
1655   [(set (pc) (if_then_else
1656               (match_operator 0 "even_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%L2%. %C0,%1,%P2%P3"
1663   [(set_attr "type" "branch")])
1665 (define_insn ""
1666   [(set (pc) (if_then_else
1667               (match_operator 0 "odd_relop"
1668                               [(match_operand:CCEVEN 1 "register_operand" "r")
1669                                (const_int 0)])
1670               (match_operand 2 "pc_or_label_ref" "")
1671               (match_operand 3 "pc_or_label_ref" "")))]
1672   ""
1673   "bb%L3%. %!%C0,%1,%P2%P3"
1674   [(set_attr "type" "branch")])
1676 ;; Branch conditional on scc values.  These arise from manipulations on
1677 ;; compare words above.
1678 ;; Are these really used ? 
1680 (define_insn ""
1681   [(set (pc)
1682         (if_then_else
1683          (ne (match_operator 0 "relop"
1684                              [(match_operand:CC 1 "register_operand" "r")
1685                               (const_int 0)])
1686              (const_int 0))
1687          (match_operand 2 "pc_or_label_ref" "")
1688          (match_operand 3 "pc_or_label_ref" "")))]
1689   ""
1690   "bb%L2 %C0,%1,%P2%P3"
1691   [(set_attr "type" "branch")])
1693 (define_insn ""
1694   [(set (pc)
1695         (if_then_else
1696          (ne (match_operator 0 "even_relop"
1697                              [(match_operand:CCEVEN 1 "register_operand" "r")
1698                               (const_int 0)])
1699              (const_int 0))
1700          (match_operand 2 "pc_or_label_ref" "")
1701          (match_operand 3 "pc_or_label_ref" "")))]
1702   ""
1703   "bb%L2 %C0,%1,%P2%P3"
1704   [(set_attr "type" "branch")])
1706 (define_insn ""
1707   [(set (pc)
1708         (if_then_else
1709          (ne (match_operator 0 "odd_relop"
1710                              [(match_operand:CCEVEN 1 "register_operand" "r")
1711                               (const_int 0)])
1712              (const_int 0))
1713          (match_operand 2 "pc_or_label_ref" "")
1714          (match_operand 3 "pc_or_label_ref" "")))]
1715   ""
1716   "bb%L3 %!%C0,%1,%P2%P3"
1717   [(set_attr "type" "branch")])
1719 (define_insn ""
1720   [(set (pc)
1721         (if_then_else
1722          (eq (match_operator 0 "relop"
1723                              [(match_operand:CC 1 "register_operand" "r")
1724                               (const_int 0)])
1725              (const_int 0))
1726          (match_operand 2 "pc_or_label_ref" "")
1727          (match_operand 3 "pc_or_label_ref" "")))]
1728   ""
1729   "bb%L3 %C0,%1,%P2%P3"
1730   [(set_attr "type" "branch")])
1732 (define_insn ""
1733   [(set (pc)
1734         (if_then_else
1735          (eq (match_operator 0 "even_relop"
1736                              [(match_operand:CCEVEN 1 "register_operand" "r")
1737                               (const_int 0)])
1738              (const_int 0))
1739          (match_operand 2 "pc_or_label_ref" "")
1740          (match_operand 3 "pc_or_label_ref" "")))]
1741   ""
1742   "bb%L3 %C0,%1,%P2%P3"
1743   [(set_attr "type" "branch")])
1745 (define_insn ""
1746   [(set (pc)
1747         (if_then_else
1748          (eq (match_operator 0 "odd_relop"
1749                              [(match_operand:CCEVEN 1 "register_operand" "r")
1750                               (const_int 0)])
1751              (const_int 0))
1752          (match_operand 2 "pc_or_label_ref" "")
1753          (match_operand 3 "pc_or_label_ref" "")))]
1754   ""
1755   "bb%L2 %!%C0,%1,%P2%P3"
1756   [(set_attr "type" "branch")])
1758 (define_insn "locate1"
1759   [(set (match_operand:SI 0 "register_operand" "=r")
1760         (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] 0)))]
1761   ""
1762   "or.u %0,%#r0,%#hi16(%1#abdiff)")
1764 (define_insn "locate2"
1765   [(parallel [(set (reg:SI 1) (pc))
1766               (set (match_operand:SI 0 "register_operand" "=r")
1767                    (lo_sum:SI (match_dup 0)
1768                               (unspec:SI
1769                                [(label_ref (match_operand 1 "" ""))] 0)))])]
1770   ""
1771   "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:"
1772   [(set_attr "length" "2")])
1774 ;; SImode move instructions
1776 (define_expand "movsi"
1777   [(set (match_operand:SI 0 "general_operand" "")
1778         (match_operand:SI 1 "general_operand" ""))]
1779   ""
1780   "
1782   if (emit_move_sequence (operands, SImode, 0))
1783     DONE;
1786 (define_expand "reload_insi"
1787   [(set (match_operand:SI 0 "register_operand" "=r")
1788         (match_operand:SI 1 "general_operand" ""))
1789    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1790   ""
1791   "
1793   if (emit_move_sequence (operands, SImode, operands[2]))
1794     DONE;
1796   /* We don't want the clobber emitted, so handle this ourselves.  */
1797   emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
1798   DONE;
1801 (define_insn ""
1802   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m")
1803         (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))]
1804   "(register_operand (operands[0], SImode)
1805     || register_operand (operands[1], SImode)
1806     || operands[1] == const0_rtx)"
1807   "@
1808    or %0,%#r0,%1
1809    %V1ld\\t %0,%1
1810    %v0st\\t %r1,%0
1811    subu %0,%#r0,%n1
1812    set %0,%#r0,%s1
1813    mov.s %0,%1
1814    mov.s %0,%1
1815    mov %0,%1
1816    %V1ld\\t %0,%1
1817    %v0st\\t %1,%0"
1818   [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")])
1820 (define_insn ""
1821   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1822         (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))]
1823   ""
1824   "@
1825    or %0,%#r0,%1
1826    subu %0,%#r0,%n1
1827    or.u %0,%#r0,%X1
1828    set %0,%#r0,%s1
1829    or.u %0,%#r0,%X1\;or %0,%0,%x1"
1830   [(set_attr "type" "arith,arith,arith,bit,marith")])
1832 ;; @@ Why the constraint "in"?  Doesn't `i' include `n'?
1833 (define_insn ""
1834   [(set (match_operand:SI 0 "register_operand" "=r")
1835         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1836                    (match_operand:SI 2 "immediate_operand" "in")))]
1837   ""
1838   "or %0,%1,%#lo16(%g2)")
1840 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1841 ;; confuse them with real addresses.
1842 (define_insn ""
1843   [(set (match_operand:SI 0 "register_operand" "=r")
1844         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1845                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1846   ""
1847   "or %0,%1,%#lo16(%g2)"
1848   ;; Need to set length for this arith insn because operand2
1849   ;; is not an "arith_operand".
1850   [(set_attr "length" "1")])
1852 (define_insn ""
1853   [(set (match_operand:SI 0 "register_operand" "=r")
1854         (high:SI (match_operand 1 "" "")))]
1855   ""
1856   "or.u %0,%#r0,%#hi16(%g1)")
1858 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1859 ;; confuse them with real addresses.
1860 (define_insn ""
1861   [(set (match_operand:SI 0 "register_operand" "=r")
1862         (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1863   ""
1864   "or.u %0,%#r0,%#hi16(%g1)"
1865   ;; Need to set length for this arith insn because operand2
1866   ;; is not an arith_operand.
1867   [(set_attr "length" "1")])
1869 ;; HImode move instructions
1871 (define_expand "movhi"
1872   [(set (match_operand:HI 0 "general_operand" "")
1873         (match_operand:HI 1 "general_operand" ""))]
1874   ""
1875   "
1877   if (emit_move_sequence (operands, HImode, 0))
1878     DONE;
1881 (define_insn ""
1882   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
1883         (match_operand:HI 1 "move_operand" "rP,m,rO,N"))]
1884   "(register_operand (operands[0], HImode)
1885     || register_operand (operands[1], HImode)
1886     || operands[1] == const0_rtx)"
1887   "@
1888    or %0,%#r0,%h1
1889    %V1ld.hu\\t %0,%1
1890    %v0st.h\\t %r1,%0
1891    subu %0,%#r0,%H1"
1892   [(set_attr "type" "arith,load,store,arith")])
1894 (define_insn ""
1895   [(set (match_operand:HI 0 "register_operand" "=r")
1896         (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1897                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
1898   "!flag_pic"
1899   "or %0,%1,%#lo16(%2)")
1901 ;; QImode move instructions
1903 (define_expand "movqi"
1904   [(set (match_operand:QI 0 "general_operand" "")
1905         (match_operand:QI 1 "general_operand" ""))]
1906   ""
1907   "
1909   if (emit_move_sequence (operands, QImode, 0))
1910     DONE;
1913 (define_insn ""
1914   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
1915         (match_operand:QI 1 "move_operand" "rP,m,rO,N"))]
1916   "(register_operand (operands[0], QImode)
1917     || register_operand (operands[1], QImode)
1918     || operands[1] == const0_rtx)"
1919   "@
1920    or %0,%#r0,%q1
1921    %V1ld.bu\\t %0,%1
1922    %v0st.b\\t %r1,%0
1923    subu %r0,%#r0,%Q1"
1924   [(set_attr "type" "arith,load,store,arith")])
1926 (define_insn ""
1927   [(set (match_operand:QI 0 "register_operand" "=r")
1928         (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1929                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
1930   "!flag_pic"
1931   "or %0,%1,%#lo16(%2)")
1933 ;; DImode move instructions
1935 (define_expand "movdi"
1936   [(set (match_operand:DI 0 "general_operand" "")
1937         (match_operand:DI 1 "general_operand" ""))]
1938   ""
1939   "
1941   if (emit_move_sequence (operands, DImode, 0))
1942     DONE;
1945 (define_insn ""
1946   [(set (match_operand:DI 0 "register_operand" "=r,x")
1947         (const_int 0))]
1948   ""
1949   "@
1950    or %0,%#r0,0\;or %d0,%#r0,0
1951    mov %0,%#x0"
1952   [(set_attr "type" "marith,mov")])
1954 (define_insn ""
1955   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m")
1956         (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))]
1957   ""
1958   "@
1959    or %0,%#r0,%1\;or %d0,%#r0,%d1
1960    %V1ld.d\\t %0,%1
1961    %v0st.d\\t %1,%0
1962    mov.d %0,%1
1963    mov.d %0,%1
1964    mov %0,%1
1965    %V1ld.d\\t %0,%1
1966    %v0st.d\\t %1,%0"
1967   [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
1969 (define_insn ""
1970   [(set (match_operand:DI 0 "register_operand" "=r")
1971         (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1972                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
1973   "!flag_pic"
1974   "or %0,%1,%#lo16(%2)")
1976 (define_insn ""
1977   [(set (match_operand:DI 0 "register_operand" "=r")
1978         (match_operand:DI 1 "immediate_operand" "n"))]
1979    ""
1980    "* return output_load_const_dimode (operands);"
1981   [(set_attr "type" "marith")
1982    (set_attr "length" "4")]) ; length is 2, 3 or 4.
1984 ;; DFmode move instructions
1986 (define_expand "movdf"
1987   [(set (match_operand:DF 0 "general_operand" "")
1988         (match_operand:DF 1 "general_operand" ""))]
1989   ""
1990   "
1992   if (emit_move_sequence (operands, DFmode, 0))
1993     DONE;
1996 (define_split
1997   [(set (match_operand:DF 0 "register_operand" "=r")
1998         (match_operand:DF 1 "register_operand" "r"))]
1999   "reload_completed
2000    && GET_CODE (operands[0]) == REG && !XRF_REGNO_P (REGNO (operands[0]))
2001    && GET_CODE (operands[1]) == REG && !XRF_REGNO_P (REGNO (operands[1]))"
2002   [(set (match_dup 2) (match_dup 3))
2003    (set (match_dup 4) (match_dup 5))]
2004   "
2005 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
2006   operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2007   operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2008   operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
2010 ;; @@ This pattern is incomplete and doesn't appear necessary.
2012 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2013 ;; to be reloaded by putting the constant into memory.
2014 ;; It must come before the more general movdf pattern.
2016 ;(define_insn ""
2017 ;  [(set (match_operand:DF 0 "general_operand" "=r,o")
2018 ;       (match_operand:DF 1 "" "G,G"))]
2019 ;  "GET_CODE (operands[1]) == CONST_DOUBLE"
2020 ;  "*
2022 ;  switch (which_alternative)
2023 ;    {
2024 ;    case 0:
2025 ;      return \"or %0,%#r0,0\;or %d0,%#r0,0\";
2026 ;    case 1:
2027 ;      operands[1] = adj_offsettable_operand (operands[0], 4);
2028 ;      return \"%v0st\\t %#r0,%0\;st %#r0,%1\";
2029 ;    }
2030 ;}")
2032 (define_insn ""
2033   [(set (match_operand:DF 0 "register_operand" "=r,x")
2034         (const_int 0))]
2035   ""
2036   "@
2037    or %0,%#r0,0\;or %d0,%#r0,0
2038    mov %0,%#x0"
2039   [(set_attr "type" "marith,mov")])
2041 (define_insn ""
2042   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2043         (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2044   ""
2045   "@
2046    or %0,%#r0,%1\;or %d0,%#r0,%d1
2047    %V1ld.d\\t %0,%1
2048    %v0st.d\\t %1,%0
2049    mov.d %0,%1
2050    mov.d %0,%1
2051    mov %0,%1
2052    %V1ld.d\\t %0,%1
2053    %v0st.d\\t %1,%0"
2054   [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
2056 (define_insn ""
2057   [(set (match_operand:DF 0 "register_operand" "=r")
2058         (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2059                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
2060   "!flag_pic"
2061   "or %0,%1,%#lo16(%2)")
2063 (define_insn ""
2064   [(set (match_operand:DF 0 "register_operand" "=r")
2065         (match_operand:DF 1 "immediate_operand" "F"))]
2066    ""
2067    "* return output_load_const_double (operands);"
2068   [(set_attr "type" "marith")
2069    (set_attr "length" "4")]) ; length is 2, 3, or 4.
2071 ;; SFmode move instructions
2073 (define_expand "movsf"
2074   [(set (match_operand:SF 0 "general_operand" "")
2075         (match_operand:SF 1 "general_operand" ""))]
2076   ""
2077   "
2079   if (emit_move_sequence (operands, SFmode, 0))
2080     DONE;
2083 ;; @@ What happens to fconst0_rtx?
2084 (define_insn ""
2085   [(set (match_operand:SF 0 "register_operand" "=r,x")
2086         (const_int 0))]
2087   ""
2088   "@
2089    or %0,%#r0,0
2090    mov %0,%#x0"
2091   [(set_attr "type" "arith,mov")])
2093 (define_insn ""
2094   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2095         (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2096   ""
2097   "@
2098    or %0,%#r0,%1
2099    %V1ld\\t %0,%1
2100    %v0st\\t %r1,%0
2101    mov.s %0,%1
2102    mov.s %0,%1
2103    mov %0,%1
2104    %V1ld\\t %0,%1
2105    %v0st\\t %r1,%0"
2106   [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")])
2108 (define_insn ""
2109   [(set (match_operand:SF 0 "register_operand" "=r")
2110         (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2111                               (match_operand:SI 2 "immediate_operand" "in")) 0))]
2112   "!flag_pic"
2113   "or %0,%1,%#lo16(%2)")
2115 (define_insn ""
2116   [(set (match_operand:SF 0 "register_operand" "=r")
2117         (match_operand:SF 1 "immediate_operand" "F"))]
2118   "operands[1] != const0_rtx"
2119   "* return output_load_const_float (operands);"
2120   [(set_attr "type" "marith")]) ; length is 1 or 2.
2122 ;; String/block move insn.  See m88k.c for details.
2124 (define_expand "movstrsi"
2125   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2126                    (mem:BLK (match_operand:BLK 1 "" "")))
2127               (use (match_operand:SI 2 "arith32_operand" ""))
2128               (use (match_operand:SI 3 "immediate_operand" ""))])]
2129   ""
2130   "
2132   rtx dest_mem = operands[0];
2133   rtx src_mem = operands[1];
2134   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
2135   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2136   expand_block_move (dest_mem, src_mem, operands);
2137   DONE;
2140 (define_insn ""
2141   [(set (match_operand:QI 0 "register_operand" "=r")
2142         (match_operand:BLK 1 "memory_operand" "m"))]
2143   ""
2144   "%V1ld.bu\\t %0,%1"
2145   [(set_attr "type" "load")])
2147 (define_insn ""
2148   [(set (match_operand:HI 0 "register_operand" "=r")
2149         (match_operand:BLK 1 "memory_operand" "m"))]
2150   ""
2151   "%V1ld.hu\\t %0,%1"
2152   [(set_attr "type" "load")])
2154 (define_insn ""
2155   [(set (match_operand:SI 0 "register_operand" "=r")
2156         (match_operand:BLK 1 "memory_operand" "m"))]
2157   ""
2158   "%V1ld\\t %0,%1"
2159   [(set_attr "type" "load")])
2161 (define_insn ""
2162   [(set (match_operand:DI 0 "register_operand" "=r")
2163         (match_operand:BLK 1 "memory_operand" "m"))]
2164   ""
2165   "%V1ld.d\\t %0,%1"
2166   [(set_attr "type" "loadd")])
2168 (define_insn ""
2169   [(set (match_operand:BLK 0 "memory_operand" "=m")
2170         (match_operand:QI 1 "register_operand" "r"))]
2171   ""
2172   "%v0st.b\\t %1,%0"
2173   [(set_attr "type" "store")])
2175 (define_insn ""
2176   [(set (match_operand:BLK 0 "memory_operand" "=m")
2177         (match_operand:HI 1 "register_operand" "r"))]
2178   ""
2179   "%v0st.h\\t %1,%0"
2180   [(set_attr "type" "store")])
2182 (define_insn ""
2183   [(set (match_operand:BLK 0 "memory_operand" "=m")
2184         (match_operand:SI 1 "register_operand" "r"))]
2185   ""
2186   "%v0st\\t %1,%0"
2187   [(set_attr "type" "store")])
2189 (define_insn ""
2190   [(set (match_operand:BLK 0 "memory_operand" "=m")
2191         (match_operand:DI 1 "register_operand" "r"))]
2192   ""
2193   "%v0st.d\\t %1,%0"
2194   [(set_attr "type" "store")])
2196 ;; Call a non-looping block move library function (e.g. __movstrSI96x64).
2197 ;; operand 0 is the function name
2198 ;; operand 1 is the destination pointer
2199 ;; operand 2 is the source pointer
2200 ;; operand 3 is the offset for the source and destination pointers
2201 ;; operand 4 is the first value to be loaded
2202 ;; operand 5 is the register to hold the value (r4 or r5)
2204 (define_expand "call_block_move"
2205   [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2206                              (match_operand:SI 3 "immediate_operand" "")))
2207    (set (match_operand 5 "register_operand" "")
2208         (match_operand 4 "memory_operand" ""))
2209    (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2210                              (match_dup 3)))
2211    (use (reg:SI 2))
2212    (use (reg:SI 3))
2213    (use (match_dup 5))
2214    (parallel [(set (reg:DI 2)
2215                    (call (mem:SI (match_operand 0 "" ""))
2216                          (const_int 0)))
2217               (clobber (reg:SI 1))])]
2218   ""
2219   "")
2221 ;; Call an SImode looping block move library function (e.g. __movstrSI64n68).
2222 ;; operands 0-5 as in the non-looping interface
2223 ;; operand 6 is the loop count
2225 (define_expand "call_movstrsi_loop"
2226   [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2227                              (match_operand:SI 3 "immediate_operand" "")))
2228    (set (match_operand:SI 5 "register_operand" "")
2229         (match_operand 4 "memory_operand" ""))
2230    (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2231                              (match_dup 3)))
2232    (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" ""))
2233    (use (reg:SI 2))
2234    (use (reg:SI 3))
2235    (use (match_dup 5))
2236    (use (reg:SI 6))
2237    (parallel [(set (reg:DI 2)
2238                    (call (mem:SI (match_operand 0 "" ""))
2239                          (const_int 0)))
2240               (clobber (reg:SI 1))])]
2241   ""
2242   "")
2244 ;;- zero extension instructions
2246 (define_expand "zero_extendhisi2"
2247   [(set (match_operand:SI 0 "register_operand" "")
2248         (zero_extend:SI (match_operand:HI 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:SI 0 "register_operand" "=r,r,r")
2260         (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))]
2261   "GET_CODE (operands[1]) != CONST_INT"
2262   "@
2263    mask %0,%1,0xffff
2264    or %0,%#r0,%h1
2265    %V1ld.hu\\t %0,%1"
2266   [(set_attr "type" "arith,arith,load")])
2268 (define_expand "zero_extendqihi2"
2269   [(set (match_operand:HI 0 "register_operand" "")
2270         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2271   ""
2272   "
2274   if (GET_CODE (operands[1]) == MEM
2275       && symbolic_address_p (XEXP (operands[1], 0)))
2276     operands[1]
2277       = legitimize_address (flag_pic, operands[1], 0, 0);
2280 (define_insn ""
2281   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
2282         (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))]
2283   "GET_CODE (operands[1]) != CONST_INT"
2284   "@
2285    mask %0,%1,0xff
2286    or %0,%#r0,%q1
2287    %V1ld.bu\\t %0,%1"
2288   [(set_attr "type" "arith,arith,load")])
2290 (define_expand "zero_extendqisi2"
2291   [(set (match_operand:SI 0 "register_operand" "")
2292         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2293   ""
2294   "
2296   if (GET_CODE (operands[1]) == MEM
2297       && symbolic_address_p (XEXP (operands[1], 0)))
2298     {
2299       operands[1]
2300         = legitimize_address (flag_pic, operands[1], 0, 0);
2301       emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2302                           gen_rtx (ZERO_EXTEND, SImode, operands[1])));
2303       DONE;
2304     }
2307 (define_insn ""
2308   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2309         (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))]
2310   "GET_CODE (operands[1]) != CONST_INT"
2311   "@
2312    mask %0,%1,0xff
2313    or %0,%#r0,%q1
2314    %V1ld.bu\\t %0,%1"
2315   [(set_attr "type" "arith,arith,load")])
2317 ;;- sign extension instructions
2319 (define_expand "extendsidi2"
2320   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
2321         (match_operand:SI 1 "general_operand" "g"))
2322    (set (subreg:SI (match_dup 0) 0)
2323         (ashiftrt:SI (subreg:SI (match_dup 0) 1)
2324                      (const_int 31)))]
2325   ""
2326   "")
2328 (define_expand "extendhisi2"
2329   [(set (match_operand:SI 0 "register_operand" "")
2330         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2331   ""
2332   "
2334   if (GET_CODE (operands[1]) == MEM
2335       && symbolic_address_p (XEXP (operands[1], 0)))
2336     operands[1]
2337       = legitimize_address (flag_pic, operands[1], 0, 0);
2340 (define_insn ""
2341   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2342         (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))]
2343   "GET_CODE (operands[1]) != CONST_INT"
2344   "@
2345    ext %0,%1,16<0>
2346    or %0,%#r0,%h1
2347    subu %0,%#r0,%H1
2348    %V1ld.h\\t %0,%1"
2349   [(set_attr "type" "bit,arith,arith,load")])
2351 (define_expand "extendqihi2"
2352   [(set (match_operand:HI 0 "register_operand" "")
2353         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2354   ""
2355   "
2357   if (GET_CODE (operands[1]) == MEM
2358       && symbolic_address_p (XEXP (operands[1], 0)))
2359     operands[1]
2360       = legitimize_address (flag_pic, operands[1], 0, 0);
2363 (define_insn ""
2364   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2365         (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2366   "GET_CODE (operands[1]) != CONST_INT"
2367   "@
2368    ext %0,%1,8<0>
2369    or %0,%#r0,%q1
2370    subu %0,%#r0,%Q1
2371    %V1ld.b\\t %0,%1"
2372   [(set_attr "type" "bit,arith,arith,load")])
2374 (define_expand "extendqisi2"
2375   [(set (match_operand:SI 0 "register_operand" "")
2376         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2377   ""
2378   "
2380   if (GET_CODE (operands[1]) == MEM
2381       && symbolic_address_p (XEXP (operands[1], 0)))
2382     operands[1]
2383       = legitimize_address (flag_pic, operands[1], 0, 0);
2386 (define_insn ""
2387   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2388         (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2389   "GET_CODE (operands[1]) != CONST_INT"
2390   "@
2391    ext %0,%1,8<0>
2392    or %0,%#r0,%q1
2393    subu %0,%#r0,%Q1
2394    %V1ld.b\\t %0,%1"
2395   [(set_attr "type" "bit,arith,arith,load")])
2397 ;; Conversions between float and double.
2399 ;; The fadd instruction does not conform to IEEE 754 when used to
2400 ;; convert between float and double.  In particular, the sign of -0 is
2401 ;; not preserved.  Interestingly, fsub does conform.
2403 (define_expand "extendsfdf2"
2404   [(set (match_operand:DF 0 "register_operand" "=r")
2405         (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2406   ""
2407   "")
2409 (define_insn ""
2410   [(set (match_operand:DF 0 "register_operand" "=r")
2411         (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2412   "! TARGET_88110"
2413   "fsub.dss %0,%1,%#r0"
2414   [(set_attr "type" "spadd")])
2416 (define_insn ""
2417   [(set (match_operand:DF 0 "register_operand" "=r,x")
2418         (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))]
2419   "TARGET_88110"
2420   "fcvt.ds %0,%1"
2421   [(set_attr "type" "spadd")])
2423 (define_expand "truncdfsf2"
2424   [(set (match_operand:SF 0 "register_operand" "=r")
2425         (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2426   ""
2427   "")
2429 (define_insn ""
2430   [(set (match_operand:SF 0 "register_operand" "=r")
2431         (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2432   "! TARGET_88110"
2433   "fsub.sds %0,%1,%#r0"
2434   [(set_attr "type" "dpadd")])
2436 (define_insn ""
2437   [(set (match_operand:SF 0 "register_operand" "=r,x")
2438         (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))]
2439   "TARGET_88110"
2440   "fcvt.sd %0,%1"
2441   [(set_attr "type" "dpadd")])
2443 ;; Conversions between floating point and integer
2445 (define_insn "floatsidf2"
2446   [(set (match_operand:DF 0 "register_operand" "=r,x")
2447         (float:DF (match_operand:SI 1 "register_operand" "r,r")))]
2448   ""
2449   "flt.ds %0,%1"
2450   [(set_attr "type" "spadd,dpadd")])
2452 (define_insn "floatsisf2"
2453   [(set (match_operand:SF 0 "register_operand" "=r,x")
2454         (float:SF (match_operand:SI 1 "register_operand" "r,r")))]
2455   ""
2456   "flt.ss %0,%1"
2457   [(set_attr "type" "spadd,spadd")])
2459 (define_insn "fix_truncdfsi2"
2460   [(set (match_operand:SI 0 "register_operand" "=r,r")
2461         (fix:SI (match_operand:DF 1 "register_operand" "r,x")))]
2462   ""
2463   "trnc.sd %0,%1"
2464   [(set_attr "type" "dpadd,dpadd")])
2466 (define_insn "fix_truncsfsi2"
2467   [(set (match_operand:SI 0 "register_operand" "=r,r")
2468         (fix:SI (match_operand:SF 1 "register_operand" "r,x")))]
2469   ""
2470   "trnc.ss %0,%1"
2471   [(set_attr "type" "spadd,dpadd")])
2474 ;;- arithmetic instructions
2475 ;;- add instructions
2477 (define_insn "addsi3"
2478   [(set (match_operand:SI 0 "register_operand" "=r,r")
2479         (plus:SI (match_operand:SI 1 "add_operand" "%r,r")
2480                  (match_operand:SI 2 "add_operand" "rI,J")))]
2481   ""
2482   "@
2483    addu %0,%1,%2
2484    subu %0,%1,%n2")
2486 ;; patterns for mixed mode floating point.
2487 ;; Do not define patterns that utilize mixed mode arithmetic that result
2488 ;; in narrowing the precision, because it loses accuracy, since the standard
2489 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2491 (define_expand "adddf3"
2492   [(set (match_operand:DF 0 "register_operand" "=r,x")
2493         (plus:DF (match_operand:DF 1 "general_operand" "%r,x")
2494                  (match_operand:DF 2 "general_operand" "r,x")))]
2495   ""
2496   "
2498   operands[1] = legitimize_operand (operands[1], DFmode);
2499   operands[2] = legitimize_operand (operands[2], DFmode);
2502 (define_insn ""
2503   [(set (match_operand:DF 0 "register_operand" "=r,x")
2504         (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2505                  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2506   ""
2507   "fadd.dss %0,%1,%2"
2508   [(set_attr "type" "spadd")])
2510 (define_insn ""
2511   [(set (match_operand:DF 0 "register_operand" "=r,x")
2512         (plus:DF (match_operand:DF 1 "register_operand" "r,x")
2513                  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2514   ""
2515   "fadd.dds %0,%1,%2"
2516   [(set_attr "type" "dpadd")])
2518 (define_insn ""
2519   [(set (match_operand:DF 0 "register_operand" "=r,x")
2520         (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2521                  (match_operand:DF 2 "register_operand" "r,x")))]
2522   ""
2523   "fadd.dsd %0,%1,%2"
2524   [(set_attr "type" "dpadd")])
2526 (define_insn ""
2527   [(set (match_operand:DF 0 "register_operand" "=r,x")
2528         (plus:DF (match_operand:DF 1 "register_operand" "%r,x")
2529                  (match_operand:DF 2 "register_operand" "r,x")))]
2530   ""
2531   "fadd.ddd %0,%1,%2"
2532   [(set_attr "type" "dpadd")])
2534 (define_insn "addsf3"
2535   [(set (match_operand:SF 0 "register_operand" "=r,x")
2536         (plus:SF (match_operand:SF 1 "register_operand" "%r,x")
2537                  (match_operand:SF 2 "register_operand" "r,x")))]
2538   ""
2539   "fadd.sss %0,%1,%2"
2540   [(set_attr "type" "spadd")])
2542 (define_insn ""
2543   [(set (match_operand:DI 0 "register_operand" "=r")
2544         (plus:DI (match_operand:DI 1 "register_operand" "r")
2545                  (zero_extend:DI
2546                   (match_operand:SI 2 "register_operand" "r"))))
2547    (clobber (reg:CC 0))]
2548   ""
2549   "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
2550   [(set_attr "type" "marith")])
2552 (define_insn ""
2553   [(set (match_operand:DI 0 "register_operand" "=r")
2554         (plus:DI (zero_extend:DI
2555                   (match_operand:SI 1 "register_operand" "r"))
2556                  (match_operand:DI 2 "register_operand" "r")))
2557    (clobber (reg:CC 0))]
2558   ""
2559   "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
2560   [(set_attr "type" "marith")])
2562 (define_insn "adddi3"
2563   [(set (match_operand:DI 0 "register_operand" "=r")
2564         (plus:DI (match_operand:DI 1 "register_operand" "%r")
2565                  (match_operand:DI 2 "register_operand" "r")))
2566    (clobber (reg:CC 0))]
2567   ""
2568   "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
2569   [(set_attr "type" "marith")])
2571 ;; Add with carry insns.
2573 (define_insn ""
2574   [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2575                    (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2576                             (match_operand:SI 2 "reg_or_0_operand" "rO")))
2577               (set (reg:CC 0)
2578                    (unspec:CC [(match_dup 1) (match_dup 2)] 0))])]
2579   ""
2580   "addu.co %r0,%r1,%r2")
2582 (define_insn ""
2583   [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2584                                (match_operand:SI 1 "reg_or_0_operand" "rO")]
2585                               0))]
2586   ""
2587   "addu.co %#r0,%r0,%r1")
2589 (define_insn ""
2590   [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2591         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2592                  (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2593                              (reg:CC 0)] 0)))]
2594   ""
2595   "addu.ci %r0,%r1,%r2")
2597 ;;- subtract instructions
2599 (define_insn "subsi3"
2600   [(set (match_operand:SI 0 "register_operand" "=r")
2601         (minus:SI (match_operand:SI 1 "register_operand" "r")
2602                   (match_operand:SI 2 "arith32_operand" "rI")))]
2603   ""
2604   "subu %0,%1,%2")
2606 ;; patterns for mixed mode floating point
2607 ;; Do not define patterns that utilize mixed mode arithmetic that result
2608 ;; in narrowing the precision, because it loses accuracy, since the standard
2609 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2611 (define_expand "subdf3"
2612   [(set (match_operand:DF 0 "register_operand" "=r,x")
2613         (minus:DF (match_operand:DF 1 "general_operand" "r,x")
2614                   (match_operand:DF 2 "general_operand" "r,x")))]
2615   ""
2616   "
2618   operands[1] = legitimize_operand (operands[1], DFmode);
2619   operands[2] = legitimize_operand (operands[2], DFmode);
2622 (define_insn ""
2623   [(set (match_operand:DF 0 "register_operand" "=r,x")
2624         (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2625                   (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2626   ""
2627   "fsub.dss %0,%1,%2"
2628   [(set_attr "type" "spadd")])
2630 (define_insn ""
2631   [(set (match_operand:DF 0 "register_operand" "=r,x")
2632         (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2633                   (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2634   ""
2635   "fsub.dds %0,%1,%2"
2636   [(set_attr "type" "dpadd")])
2638 (define_insn ""
2639   [(set (match_operand:DF 0 "register_operand" "=r,x")
2640         (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2641                   (match_operand:DF 2 "register_operand" "r,x")))]
2642   ""
2643   "fsub.dsd %0,%1,%2"
2644   [(set_attr "type" "dpadd")])
2646 (define_insn ""
2647   [(set (match_operand:DF 0 "register_operand" "=r,x")
2648         (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2649                   (match_operand:DF 2 "register_operand" "r,x")))]
2650   ""
2651   "fsub.ddd %0,%1,%2"
2652   [(set_attr "type" "dpadd")])
2654 (define_insn "subsf3"
2655   [(set (match_operand:SF 0 "register_operand" "=r,x")
2656         (minus:SF (match_operand:SF 1 "register_operand" "r,x")
2657                   (match_operand:SF 2 "register_operand" "r,x")))]
2658   ""
2659   "fsub.sss %0,%1,%2"
2660   [(set_attr "type" "spadd")])
2662 (define_insn ""
2663   [(set (match_operand:DI 0 "register_operand" "=r")
2664         (minus:DI (match_operand:DI 1 "register_operand" "r")
2665                   (zero_extend:DI
2666                    (match_operand:SI 2 "register_operand" "r"))))
2667    (clobber (reg:CC 0))]
2668   ""
2669   "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
2670   [(set_attr "type" "marith")])
2672 (define_insn ""
2673   [(set (match_operand:DI 0 "register_operand" "=r")
2674         (minus:DI (zero_extend:DI
2675                    (match_operand:SI 1 "register_operand" "r"))
2676                   (match_operand:DI 2 "register_operand" "r")))
2677    (clobber (reg:CC 0))]
2678   ""
2679   "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
2680   [(set_attr "type" "marith")])
2682 (define_insn "subdi3"
2683   [(set (match_operand:DI 0 "register_operand" "=r")
2684         (minus:DI (match_operand:DI 1 "register_operand" "r")
2685                   (match_operand:DI 2 "register_operand" "r")))
2686    (clobber (reg:CC 0))]
2687   ""
2688   "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
2689   [(set_attr "type" "marith")])
2691 ;; Subtract with carry insns.
2693 (define_insn ""
2694   [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2695                    (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2696                              (match_operand:SI 2 "reg_or_0_operand" "rO")))
2697               (set (reg:CC 0)
2698                    (unspec:CC [(match_dup 1) (match_dup 2)] 1))])]
2699   ""
2700   "subu.co %r0,%r1,%r2")
2702 (define_insn ""
2703   [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2704                                (match_operand:SI 1 "reg_or_0_operand" "rO")]
2705                               1))]
2706   ""
2707   "subu.co %#r0,%r0,%r1")
2709 (define_insn ""
2710   [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2711         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2712                   (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2713                               (reg:CC 0)] 1)))]
2714   ""
2715   "subu.ci %r0,%r1,%r2")
2717 ;;- multiply instructions
2719 ;; There is an unfounded silicon errata for E.1 requiring that an
2720 ;; immediate constant value in div/divu/mul instructions be less than
2721 ;; 0x800.  This is no longer provided for.
2723 (define_insn "mulsi3"
2724   [(set (match_operand:SI 0 "register_operand" "=r")
2725         (mult:SI (match_operand:SI 1 "arith32_operand" "%r")
2726                  (match_operand:SI 2 "arith32_operand" "rI")))]
2727   ""
2728   "mul %0,%1,%2"
2729   [(set_attr "type" "imul")])
2731 (define_insn "umulsidi3"
2732   [(set (match_operand:DI 0 "register_operand" "=r")
2733         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
2734                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
2735   "TARGET_88110"
2736   "mulu.d %0,%1,%2"
2737   [(set_attr "type" "imul")])
2739 ;; patterns for mixed mode floating point
2740 ;; Do not define patterns that utilize mixed mode arithmetic that result
2741 ;; in narrowing the precision, because it loses accuracy, since the standard
2742 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2744 (define_expand "muldf3"
2745   [(set (match_operand:DF 0 "register_operand" "=r,x")
2746         (mult:DF (match_operand:DF 1 "general_operand" "%r,x")
2747                  (match_operand:DF 2 "general_operand" "r,x")))]
2748   ""
2749   "
2751   operands[1] = legitimize_operand (operands[1], DFmode);
2752   operands[2] = legitimize_operand (operands[2], DFmode);
2755 (define_insn ""
2756   [(set (match_operand:DF 0 "register_operand" "=r,x")
2757         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2758                  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2759   ""
2760   "fmul.dss %0,%1,%2"
2761   [(set_attr "type" "spmul")])
2763 (define_insn ""
2764   [(set (match_operand:DF 0 "register_operand" "=r,x")
2765         (mult:DF (match_operand:DF 1 "register_operand" "r,x")
2766                  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2767   ""
2768   "fmul.dds %0,%1,%2"
2769   [(set_attr "type" "spmul")])
2771 (define_insn ""
2772   [(set (match_operand:DF 0 "register_operand" "=r,x")
2773         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2774                  (match_operand:DF 2 "register_operand" "r,x")))]
2775   ""
2776   "fmul.dsd %0,%1,%2"
2777   [(set_attr "type" "spmul")])
2779 (define_insn ""
2780   [(set (match_operand:DF 0 "register_operand" "=r,x")
2781         (mult:DF (match_operand:DF 1 "register_operand" "%r,x")
2782                  (match_operand:DF 2 "register_operand" "r,x")))]
2783   ""
2784   "fmul.ddd %0,%1,%2"
2785   [(set_attr "type" "dpmul")])
2787 (define_insn "mulsf3"
2788   [(set (match_operand:SF 0 "register_operand" "=r,x")
2789         (mult:SF (match_operand:SF 1 "register_operand" "%r,x")
2790                  (match_operand:SF 2 "register_operand" "r,x")))]
2791   ""
2792   "fmul.sss %0,%1,%2"
2793   [(set_attr "type" "spmul")])
2795 ;;- divide instructions
2797 ;; The 88k div and divu instructions don't reliably trap on
2798 ;; divide-by-zero.  A trap to vector 503 asserts divide-by-zero.  The
2799 ;; general scheme for doing divide is to do a 4-way split based on the
2800 ;; sign of the two operand and do the appropriate negates.
2802 ;; The conditional trap instruction is not used as this serializes the
2803 ;; processor.  Instead a conditional branch and an unconditional trap
2804 ;; are used, but after the divu.  Since the divu takes up to 38 cycles,
2805 ;; the conditional branch is essentially free.
2807 ;; Two target options control how divide is done.  One options selects
2808 ;; whether to do the branch and negate scheme instead of using the div
2809 ;; instruction; the other option selects whether to explicitly check
2810 ;; for divide-by-zero or take your chances.  If the div instruction is
2811 ;; used, the O/S must complete the operation if the operands are
2812 ;; negative.  The O/S will signal an overflow condition if the most
2813 ;; negative number (-2147483648) is divided by negative 1.
2815 ;; There is an unfounded silicon errata for E.1 requiring that an
2816 ;; immediate constant value in div/divu/mul instructions be less than
2817 ;; 0x800.  This is no longer provided for.
2819 ;; Division by 0 trap
2820 (define_insn "trap_divide_by_zero"
2821   [(trap_if (const_int 1) 503)]
2822   ""
2823   "tb0 0,%#r0,503"
2824   [(set_attr "type" "weird")])
2826 ;; Conditional division by 0 trap.
2827 (define_expand "tcnd_divide_by_zero"
2828   [(set (pc)
2829         (if_then_else (eq (match_operand:SI 0 "register_operand" "")
2830                           (const_int 0))
2831                       (pc)
2832                       (match_operand 1 "" "")))
2833    (trap_if (const_int 1) 503)]
2834   ""
2835   "
2837   emit_insn (gen_cmpsi (operands[0], const0_rtx));
2838   emit_jump_insn (gen_bne (operands[1]));
2839   emit_insn (gen_trap_divide_by_zero ());
2840   DONE;
2843 (define_expand "divsi3"
2844   [(set (match_operand:SI 0 "register_operand" "")
2845         (div:SI (match_operand:SI 1 "arith32_operand" "")
2846                 (match_operand:SI 2 "arith32_operand" "")))]
2847   ""
2848   "
2850   rtx op0 = operands[0];
2851   rtx op1 = operands[1];
2852   rtx op2 = operands[2];
2853   rtx join_label;
2855   /* @@ This needs to be reworked.  Torbjorn Granlund has suggested making
2856      it a runtime (perhaps quite special).  */
2858   if (GET_CODE (op1) == CONST_INT)
2859     op1 = force_reg (SImode, op1);
2861   else if (GET_CODE (op2) == CONST_INT
2862            && ! SMALL_INT (operands[2]))
2863     op2 = force_reg (SImode, op2);
2865   if (op2 == const0_rtx)
2866     {
2867       emit_insn (gen_trap_divide_by_zero ());
2868       emit_insn (gen_dummy (op0));
2869       DONE;
2870     }
2872   if (TARGET_USE_DIV)
2873     {
2874       emit_move_insn (op0, gen_rtx (DIV, SImode, op1, op2));
2875       if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT)
2876         {
2877           rtx label = gen_label_rtx ();
2878           emit_insn (gen_tcnd_divide_by_zero (op2, label));
2879           emit_label (label);
2880           emit_insn (gen_dummy (op0));
2881         }
2882       DONE;
2883     }
2885   join_label = gen_label_rtx ();
2886   if (GET_CODE (op1) == CONST_INT)
2887     {
2888       int neg = FALSE;
2889       rtx neg_op2 = gen_reg_rtx (SImode);
2890       rtx label1 = gen_label_rtx ();
2892       if (INTVAL (op1) < 0)
2893         {
2894           neg = TRUE;
2895           op1 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op1));
2896         }
2897       op1 = force_reg (SImode, op1);
2899       emit_insn (gen_negsi2 (neg_op2, op2));
2900       emit_insn (gen_cmpsi (op2, const0_rtx));
2901       emit_jump_insn (gen_bgt (label1));
2902                                                 /* constant / 0-or-negative */
2903       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
2904       if (!neg)
2905         emit_insn (gen_negsi2 (op0, op0));
2907       if (TARGET_CHECK_ZERO_DIV)
2908         emit_insn (gen_tcnd_divide_by_zero (op2, join_label));
2909       emit_jump_insn (gen_jump (join_label));
2910       emit_barrier ();
2912       emit_label (label1);                      /* constant / positive */
2913       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
2914       if (neg)
2915         emit_insn (gen_negsi2 (op0, op0));
2916     }
2918   else if (GET_CODE (op2) == CONST_INT)
2919     {
2920       int neg = FALSE;
2921       rtx neg_op1 = gen_reg_rtx (SImode);
2922       rtx label1 = gen_label_rtx ();
2924       if (INTVAL (op2) < 0)
2925         {
2926           neg = TRUE;
2927           op2 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op2));
2928         }
2929       else if (! SMALL_INT (operands[2]))
2930         op2 = force_reg (SImode, op2);
2932       emit_insn (gen_negsi2 (neg_op1, op1));
2933       emit_insn (gen_cmpsi (op1, const0_rtx));
2934       emit_jump_insn (gen_bge (label1));
2935                                                 /* 0-or-negative / constant */
2936       emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
2937       if (!neg)
2938         emit_insn (gen_negsi2 (op0, op0));
2940       emit_jump_insn (gen_jump (join_label));
2941       emit_barrier ();
2943       emit_label (label1);                      /* positive / constant */
2944       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
2945       if (neg)
2946         emit_insn (gen_negsi2 (op0, op0));
2947     }
2949   else
2950     {
2951       rtx neg_op1 = gen_reg_rtx (SImode);
2952       rtx neg_op2 = gen_reg_rtx (SImode);
2953       rtx label1 = gen_label_rtx ();
2954       rtx label2 = gen_label_rtx ();
2955       rtx label3 = gen_label_rtx ();
2956       rtx label4;
2958       emit_insn (gen_negsi2 (neg_op2, op2));
2959       emit_insn (gen_cmpsi (op2, const0_rtx));
2960       emit_jump_insn (gen_bgt (label1));
2962       emit_insn (gen_negsi2 (neg_op1, op1));
2963       emit_insn (gen_cmpsi (op1, const0_rtx));
2964       emit_jump_insn (gen_bge (label2));
2965                                                 /* negative / negative-or-0 */
2966       emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, neg_op2));
2968       if (TARGET_CHECK_ZERO_DIV)
2969         {
2970           label4 = gen_label_rtx ();
2971           emit_insn (gen_cmpsi (op2, const0_rtx));
2972           emit_jump_insn (gen_bne (join_label));
2973           emit_label (label4);
2974           emit_insn (gen_trap_divide_by_zero ());
2975         }
2976       emit_jump_insn (gen_jump (join_label));
2977       emit_barrier ();
2979       emit_label (label2);                      /* pos.-or-0 / neg.-or-0 */
2980       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
2982       if (TARGET_CHECK_ZERO_DIV)
2983         {
2984           emit_insn (gen_cmpsi (op2, const0_rtx));
2985           emit_jump_insn (gen_beq (label4));
2986         }
2988       emit_insn (gen_negsi2 (op0, op0));
2989       emit_jump_insn (gen_jump (join_label));
2990       emit_barrier ();
2992       emit_label (label1);
2993       emit_insn (gen_negsi2 (neg_op1, op1));
2994       emit_insn (gen_cmpsi (op1, const0_rtx));
2995       emit_jump_insn (gen_bge (label3));
2996                                                 /* negative / positive */
2997       emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
2998       emit_insn (gen_negsi2 (op0, op0));
2999       emit_jump_insn (gen_jump (join_label));
3000       emit_barrier ();
3002       emit_label (label3);                      /* positive-or-0 / positive */
3003       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
3004     }
3006   emit_label (join_label);
3008   emit_insn (gen_dummy (op0));
3009   DONE;
3012 (define_insn ""
3013   [(set (match_operand:SI 0 "register_operand" "=r")
3014         (div:SI (match_operand:SI 1 "register_operand" "r")
3015                 (match_operand:SI 2 "arith_operand" "rI")))]
3016   ""
3017   "div %0,%1,%2"
3018   [(set_attr "type" "idiv")])
3020 (define_expand "udivsi3"
3021   [(set (match_operand:SI 0 "register_operand" "")
3022         (udiv:SI (match_operand:SI 1 "register_operand" "")
3023                  (match_operand:SI 2 "arith32_operand" "")))]
3024   ""
3025   "
3027   rtx op2 = operands[2];
3029   if (op2 == const0_rtx)
3030     {
3031       emit_insn (gen_trap_divide_by_zero ());
3032       emit_insn (gen_dummy (operands[0]));
3033       DONE;
3034     }
3035   else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV)
3036     {
3037       rtx label = gen_label_rtx ();
3038       emit_insn (gen_rtx (SET, VOIDmode, operands[0],
3039                           gen_rtx (UDIV, SImode, operands[1], op2)));
3040       emit_insn (gen_tcnd_divide_by_zero (op2, label));
3041       emit_label (label);
3042       emit_insn (gen_dummy (operands[0]));
3043       DONE;
3044     }
3047 (define_insn ""
3048  [(set (match_operand:SI 0 "register_operand" "=r")
3049        (udiv:SI (match_operand:SI 1 "register_operand" "r")
3050                 (match_operand:SI 2 "arith32_operand" "rI")))]
3051   "operands[2] != const0_rtx"
3052   "divu %0,%1,%2"
3053   [(set_attr "type" "idiv")])
3055 (define_insn ""
3056  [(set (match_operand:SI 0 "register_operand" "=r")
3057        (udiv:SI (match_operand:SI 1 "register_operand" "r")
3058                 (const_int 0)))]
3059   ""
3060   "tb0 0,%#r0,503"
3061   [(set_attr "type" "weird")])
3063 ;; patterns for mixed mode floating point.
3064 ;; Do not define patterns that utilize mixed mode arithmetic that result
3065 ;; in narrowing the precision, because it loses accuracy, since the standard
3066 ;; requires double rounding, whereas the 88000 instruction only rounds once.
3068 (define_expand "divdf3"
3069   [(set (match_operand:DF 0 "register_operand" "=r,x")
3070         (div:DF (match_operand:DF 1 "general_operand" "r,x")
3071                 (match_operand:DF 2 "general_operand" "r,x")))]
3072   ""
3073   "
3075   operands[1] = legitimize_operand (operands[1], DFmode);
3076   if (real_power_of_2_operand (operands[2]))
3077     {
3078       union real_extract u;
3079       bcopy (&CONST_DOUBLE_LOW (operands[2]), &u, sizeof u);
3080       emit_insn (gen_muldf3 (operands[0], operands[1],
3081                              CONST_DOUBLE_FROM_REAL_VALUE (1.0/u.d, DFmode)));
3082       DONE;
3083     }
3084   else if (! register_operand (operands[2], DFmode))
3085     operands[2] = force_reg (DFmode, operands[2]);
3088 (define_insn ""
3089   [(set (match_operand:DF 0 "register_operand" "=r,x")
3090         (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3091                 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3092   ""
3093   "fdiv.dss %0,%1,%2"
3094   [(set_attr "type" "dpdiv")])
3096 (define_insn ""
3097   [(set (match_operand:DF 0 "register_operand" "=r,x")
3098         (div:DF (match_operand:DF 1 "register_operand" "r,x")
3099                 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3100   ""
3101   "fdiv.dds %0,%1,%2"
3102   [(set_attr "type" "dpdiv")])
3104 (define_insn ""
3105   [(set (match_operand:DF 0 "register_operand" "=r,x")
3106         (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3107                 (match_operand:DF 2 "register_operand" "r,x")))]
3108   ""
3109   "fdiv.dsd %0,%1,%2"
3110   [(set_attr "type" "dpdiv")])
3112 (define_insn "divsf3"
3113   [(set (match_operand:SF 0 "register_operand" "=r,x")
3114         (div:SF (match_operand:SF 1 "register_operand" "r,x")
3115                 (match_operand:SF 2 "register_operand" "r,x")))]
3116   ""
3117   "fdiv.sss %0,%1,%2"
3118   [(set_attr "type" "spdiv")])
3120 (define_insn ""
3121   [(set (match_operand:DF 0 "register_operand" "=r,x")
3122         (div:DF (match_operand:DF 1 "register_operand" "r,x")
3123                 (match_operand:DF 2 "register_operand" "r,x")))]
3124   ""
3125   "fdiv.ddd %0,%1,%2"
3126   [(set_attr "type" "dpdiv")])
3128 ;; - remainder instructions, don't define, since the hardware doesn't have any
3129 ;; direct support, and GNU can synthesis them out of div/mul just fine.
3131 ;;- load effective address, must come after add, so that we favor using
3132 ;;  addu reg,reg,reg  instead of:  lda reg,reg,reg (addu doesn't require
3133 ;;  the data unit), and also future 88k chips might not support unscaled
3134 ;;  lda instructions.
3136 (define_insn ""
3137   [(set (match_operand:SI 0 "register_operand" "=r")
3138         (match_operand:SI 1 "address_operand" "p"))]
3139   "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])"
3140   "addu %0,%a1")
3142 (define_insn ""
3143   [(set (match_operand:SI 0 "register_operand" "=r")
3144         (match_operand:HI 1 "address_operand" "p"))]
3145   ""
3146   "lda.h %0,%a1"
3147   [(set_attr "type" "loada")])
3149 (define_insn ""
3150   [(set (match_operand:SI 0 "register_operand" "=r")
3151         (match_operand:SI 1 "address_operand" "p"))]
3152   ""
3153   "lda %0,%a1"
3154   [(set_attr "type" "loada")])
3156 (define_insn ""
3157   [(set (match_operand:SI 0 "register_operand" "=r")
3158         (match_operand:DI 1 "address_operand" "p"))]
3159   ""
3160   "lda.d %0,%a1"
3161   [(set_attr "type" "loada")])
3163 (define_insn ""
3164   [(set (match_operand:SI 0 "register_operand" "=r")
3165         (match_operand:SF 1 "address_operand" "p"))]
3166   ""
3167   "lda %0,%a1"
3168   [(set_attr "type" "loada")])
3170 (define_insn ""
3171   [(set (match_operand:SI 0 "register_operand" "=r")
3172         (match_operand:DF 1 "address_operand" "p"))]
3173   ""
3174   "lda.d %0,%a1"
3175   [(set_attr "type" "loada")])
3177 ;;- and instructions (with complement also)
3178 (define_insn ""
3179   [(set (match_operand:SI 0 "register_operand" "=r")
3180         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3181                 (match_operand:SI 2 "register_operand" "r")))]
3182   ""
3183   "and.c %0,%2,%1")
3185 ;; If the operation is being performed on a 32-bit constant such that
3186 ;; it cannot be done in one insn, do it in two.  We may lose a bit on
3187 ;; CSE in pathological cases, but it seems better doing it this way.
3189 (define_expand "andsi3"
3190   [(set (match_operand:SI 0 "register_operand" "")
3191         (and:SI (match_operand:SI 1 "arith32_operand" "")
3192                 (match_operand:SI 2 "arith32_operand" "")))]
3193   ""
3194   "
3196   if (GET_CODE (operands[2]) == CONST_INT)
3197     {
3198       int value = INTVAL (operands[2]);
3200       if (! (SMALL_INTVAL (value)
3201              || (value & 0xffff0000) == 0xffff0000
3202              || (value & 0xffff) == 0xffff
3203              || (value & 0xffff) == 0
3204              || integer_ok_for_set (~value)))
3205         {
3206           emit_insn (gen_andsi3 (operands[0], operands[1],
3207                                  gen_rtx (CONST_INT, VOIDmode,
3208                                           value | 0xffff)));
3209           operands[1] = operands[0];
3210           operands[2] = gen_rtx (CONST_INT, VOIDmode, value | 0xffff0000);
3211         }
3212     }
3215 (define_insn ""
3216   [(set (match_operand:SI 0 "register_operand" "=r,r")
3217         (and:SI (match_operand:SI 1 "arith32_operand" "%r,r")
3218                 (match_operand:SI 2 "arith32_operand" "rIJL,rn")))]
3219   ""
3220   "* return output_and (operands);"
3221   [(set_attr "type" "arith,marith")])
3223 (define_insn ""
3224   [(set (match_operand:DI 0 "register_operand" "=r")
3225         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3226                 (match_operand:DI 2 "register_operand" "r")))]
3227   ""
3228   "and.c %d0,%d2,%d1\;and.c %0,%2,%1"
3229   [(set_attr "type" "marith")])
3231 (define_insn "anddi3"
3232   [(set (match_operand:DI 0 "register_operand" "=r")
3233         (and:DI (match_operand:DI 1 "arith64_operand" "%r")
3234                 (match_operand:DI 2 "arith64_operand" "rn")))]
3235   ""
3236   "*
3238   rtx xoperands[10];
3240   xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3241   xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3242   xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3244   output_asm_insn (output_and (xoperands), xoperands);
3246   operands[0] = operand_subword (operands[0], 0, 0, DImode);
3247   operands[1] = operand_subword (operands[1], 0, 0, DImode);
3248   operands[2] = operand_subword (operands[2], 0, 0, DImode);
3250   return output_and (operands);
3252   [(set_attr "type" "marith")
3253    (set_attr "length" "4")]) ; length is 2, 3, or 4.
3255 ;;- Bit set (inclusive or) instructions (with complement also)
3256 (define_insn ""
3257   [(set (match_operand:SI 0 "register_operand" "=r")
3258         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3259                 (match_operand:SI 2 "register_operand" "r")))]
3260   ""
3261   "or.c %0,%2,%1")
3263 (define_expand "iorsi3"
3264   [(set (match_operand:SI 0 "register_operand" "")
3265         (ior:SI (match_operand:SI 1 "arith32_operand" "")
3266                 (match_operand:SI 2 "arith32_operand" "")))]
3267   ""
3268   "
3270   if (GET_CODE (operands[2]) == CONST_INT)
3271     {
3272       int value = INTVAL (operands[2]);
3274       if (! (SMALL_INTVAL (value)
3275              || (value & 0xffff) == 0
3276              || integer_ok_for_set (value)))
3277         {
3278           emit_insn (gen_iorsi3 (operands[0], operands[1],
3279                                  gen_rtx (CONST_INT, VOIDmode,
3280                                           value & 0xffff0000)));
3281           operands[1] = operands[0];
3282           operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
3283         }
3284     }
3287 (define_insn ""
3288   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3289         (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r")
3290                 (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))]
3291   ""
3292   "@
3293    or %0,%1,%2
3294    or.u %0,%1,%X2
3295    set %0,%1,%s2
3296    or.u %0,%1,%X2\;or %0,%0,%x2"
3297   [(set_attr "type" "arith,arith,bit,marith")])
3299 (define_insn ""
3300   [(set (match_operand:DI 0 "register_operand" "=r")
3301         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3302                 (match_operand:DI 2 "register_operand" "r")))]
3303   ""
3304   "or.c %d0,%d2,%d1\;or.c %0,%2,%1"
3305   [(set_attr "type" "marith")])
3307 (define_insn "iordi3"
3308   [(set (match_operand:DI 0 "register_operand" "=r")
3309         (ior:DI (match_operand:DI 1 "arith64_operand" "%r")
3310                 (match_operand:DI 2 "arith64_operand" "rn")))]
3311   ""
3312   "*
3314   rtx xoperands[10];
3316   xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3317   xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3318   xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3320   output_asm_insn (output_ior (xoperands), xoperands);
3322   operands[0] = operand_subword (operands[0], 0, 0, DImode);
3323   operands[1] = operand_subword (operands[1], 0, 0, DImode);
3324   operands[2] = operand_subword (operands[2], 0, 0, DImode);
3326   return output_ior (operands);
3328   [(set_attr "type" "marith")
3329    (set_attr "length" "4")]) ; length is 2, 3, or 4.
3331 ;;- xor instructions (with complement also)
3332 (define_insn ""
3333   [(set (match_operand:SI 0 "register_operand" "=r")
3334         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r")
3335                         (match_operand:SI 2 "register_operand" "r"))))]
3336   ""
3337   "xor.c %0,%1,%2")
3339 (define_expand "xorsi3"
3340   [(set (match_operand:SI 0 "register_operand" "")
3341         (xor:SI (match_operand:SI 1 "arith32_operand" "")
3342                 (match_operand:SI 2 "arith32_operand" "")))]
3343   ""
3344   "
3346   if (GET_CODE (operands[2]) == CONST_INT)
3347     {
3348       int value = INTVAL (operands[2]);
3350       if (! (SMALL_INTVAL (value)
3351              || (value & 0xffff) == 0))
3352         {
3353           emit_insn (gen_xorsi3 (operands[0], operands[1],
3354                                  gen_rtx (CONST_INT, VOIDmode,
3355                                           value & 0xffff0000)));
3356           operands[1] = operands[0];
3357           operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
3358         }
3359     }
3362 (define_insn ""
3363   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3364         (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r")
3365                 (match_operand:SI 2 "arith32_operand" "rI,L,n")))]
3366   ""
3367   "@
3368    xor %0,%1,%2
3369    xor.u %0,%1,%X2
3370    xor.u %0,%1,%X2\;xor %0,%0,%x2"
3371   [(set_attr "type" "arith,arith,marith")])
3373 (define_insn ""
3374   [(set (match_operand:DI 0 "register_operand" "=r")
3375         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
3376                         (match_operand:DI 2 "register_operand" "r"))))]
3377   ""
3378   "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2"
3379   [(set_attr "type" "marith")])
3381 (define_insn "xordi3"
3382   [(set (match_operand:DI 0 "register_operand" "=r")
3383         (xor:DI (match_operand:DI 1 "arith64_operand" "%r")
3384                 (match_operand:DI 2 "arith64_operand" "rn")))]
3385   ""
3386   "*
3388   rtx xoperands[10];
3390   xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3391   xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3392   xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3394   output_asm_insn (output_xor (xoperands), xoperands);
3396   operands[0] = operand_subword (operands[0], 0, 0, DImode);
3397   operands[1] = operand_subword (operands[1], 0, 0, DImode);
3398   operands[2] = operand_subword (operands[2], 0, 0, DImode);
3400   return output_xor (operands);
3402   [(set_attr "type" "marith")
3403    (set_attr "length" "4")]) ; length is 2, 3, or 4.
3405 ;;- ones complement instructions
3406 (define_insn "one_cmplsi2"
3407   [(set (match_operand:SI 0 "register_operand" "=r")
3408         (not:SI (match_operand:SI 1 "register_operand" "r")))]
3409   ""
3410   "xor.c %0,%1,%#r0")
3412 (define_insn "one_cmpldi2"
3413   [(set (match_operand:DI 0 "register_operand" "=r")
3414         (not:DI (match_operand:DI 1 "register_operand" "r")))]
3415   ""
3416   "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0"
3417   [(set_attr "type" "marith")])
3419 ;; Optimized special cases of shifting.
3420 ;; Must precede the general case.
3422 ;; @@ What about HImode shifted by 8?
3424 (define_insn ""
3425   [(set (match_operand:SI 0 "register_operand" "=r")
3426         (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3427                      (const_int 24)))]
3428   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3429   "%V1ld.b\\t %0,%1"
3430   [(set_attr "type" "load")])
3432 (define_insn ""
3433   [(set (match_operand:SI 0 "register_operand" "=r")
3434         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3435                      (const_int 24)))]
3436   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3437   "%V1ld.bu\\t %0,%1"
3438   [(set_attr "type" "load")])
3440 (define_insn ""
3441   [(set (match_operand:SI 0 "register_operand" "=r")
3442         (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3443                      (const_int 16)))]
3444   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3445   "%V1ld.h\\t %0,%1"
3446   [(set_attr "type" "load")])
3448 (define_insn ""
3449   [(set (match_operand:SI 0 "register_operand" "=r")
3450         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3451                      (const_int 16)))]
3452   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3453   "%V1ld.hu\\t %0,%1"
3454   [(set_attr "type" "load")])
3456 ;;- arithmetic shift instructions.
3458 ;; @@ Do the optimized patterns with -1 get used?  Perhaps operand 1 should
3459 ;; be arith32_operand?
3461 ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT.
3462 (define_insn "tbnd"
3463   [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
3464                  (match_operand:SI 1 "arith_operand" "rI"))
3465             7)]
3466   ""
3467   "tbnd %r0,%1"
3468   [(set_attr "type" "weird")])
3470 ;; Just in case the optimizer decides to fold away the test.
3471 (define_insn ""
3472   [(trap_if (const_int 1) 7)]
3473   ""
3474   "tbnd %#r31,0"
3475   [(set_attr "type" "weird")])
3477 (define_expand "ashlsi3"
3478   [(set (match_operand:SI 0 "register_operand" "")
3479         (ashift:SI (match_operand:SI 1 "register_operand" "")
3480                    (match_operand:SI 2 "arith32_operand" "")))]
3481   ""
3482   "
3484   if (GET_CODE (operands[2]) == CONST_INT)
3485     {
3486       if ((unsigned) INTVAL (operands[2]) > 31)
3487         {
3488           if (TARGET_TRAP_LARGE_SHIFT)
3489             emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3490                                  gen_rtx (CONST_INT, VOIDmode, 31)));
3491           else
3492             emit_move_insn (operands[0], const0_rtx);
3493           DONE;
3494         }
3495     }
3497   else if (TARGET_TRAP_LARGE_SHIFT)
3498     emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3500   else if (TARGET_HANDLE_LARGE_SHIFT)
3501     {
3502       rtx reg = gen_reg_rtx (SImode);
3503       emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3504       emit_insn (gen_sleu (reg));
3505       emit_insn (gen_andsi3 (reg, operands[1], reg));
3506       operands[1] = reg;
3507     }
3510 (define_insn ""
3511   [(set (match_operand:SI 0 "register_operand" "=r,r")
3512         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
3513                    (match_operand:SI 2 "arith5_operand" "r,K")))]
3514   ""
3515   "@
3516    mak %0,%1,%2
3517    mak %0,%1,0<%2>"
3518   [(set_attr "type" "bit")])
3520 (define_expand "ashrsi3"
3521   [(set (match_operand:SI 0 "register_operand" "")
3522         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3523                      (match_operand:SI 2 "arith32_operand" "")))]
3524   ""
3525   "
3527   if (GET_CODE (operands[2]) == CONST_INT)
3528     {
3529       if ((unsigned) INTVAL (operands[2]) > 31)
3530         {
3531           if (TARGET_TRAP_LARGE_SHIFT)
3532             {
3533               emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3534                                    gen_rtx (CONST_INT, VOIDmode, 31)));
3535               DONE;
3536             }
3537           else
3538             operands[2] = gen_rtx (CONST_INT, VOIDmode, 31);
3539         }
3540     }
3542   else if (TARGET_TRAP_LARGE_SHIFT)
3543     emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3545   else if (TARGET_HANDLE_LARGE_SHIFT)
3546     {
3547       rtx reg = gen_reg_rtx (SImode);
3548       emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3549       emit_insn (gen_sgtu (reg));
3550       emit_insn (gen_iorsi3 (reg, operands[2], reg));
3551       operands[2] = reg;
3552     }
3555 (define_insn ""
3556   [(set (match_operand:SI 0 "register_operand" "=r,r")
3557         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3558                      (match_operand:SI 2 "arith5_operand" "r,K")))]
3559   ""
3560   "@
3561    ext %0,%1,%2
3562    ext %0,%1,0<%2>"
3563   [(set_attr "type" "bit")])
3565 ;;- logical shift instructions.  Logical shift left becomes arithmetic
3566 ;; shift left.  
3568 (define_expand "lshrsi3"
3569   [(set (match_operand:SI 0 "register_operand" "")
3570         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3571                      (match_operand:SI 2 "arith32_operand" "")))]
3572   ""
3573   "
3575   if (GET_CODE (operands[2]) == CONST_INT)
3576     {
3577       if ((unsigned) INTVAL (operands[2]) > 31)
3578         {
3579           if (TARGET_TRAP_LARGE_SHIFT)
3580             emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3581                                  gen_rtx (CONST_INT, VOIDmode, 31)));
3582           else
3583             emit_move_insn (operands[0], const0_rtx);
3584           DONE;
3585         }
3586     }
3588   else if (TARGET_TRAP_LARGE_SHIFT)
3589     emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3591   else if (TARGET_HANDLE_LARGE_SHIFT)
3592     {
3593       rtx reg = gen_reg_rtx (SImode);
3594       emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3595       emit_insn (gen_sleu (reg));
3596       emit_insn (gen_andsi3 (reg, operands[1], reg));
3597       operands[1] = reg;
3598     }
3601 (define_insn ""
3602   [(set (match_operand:SI 0 "register_operand" "=r,r")
3603         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3604                      (match_operand:SI 2 "arith5_operand" "r,K")))]
3605   ""
3606   "@
3607    extu %0,%1,%2
3608    extu %0,%1,0<%2>"
3609   [(set_attr "type" "bit")])
3611 ;;- rotate instructions
3613 (define_expand "rotlsi3"
3614   [(set (match_operand:SI 0 "register_operand" "")
3615         (rotatert:SI (match_operand:SI 1 "register_operand" "")
3616                      (match_operand:SI 2 "arith32_operand" "")))]
3617   ""
3618   "
3620   if (GET_CODE (operands[2]) == CONST_INT
3621       && (unsigned) INTVAL (operands[2]) >= 32)
3622     operands[2] = gen_rtx (CONST_INT, VOIDmode,
3623                            (32 - INTVAL (operands[2])) % 32);
3624   else
3625     {
3626       rtx op = gen_reg_rtx (SImode);
3627       emit_insn (gen_negsi2 (op, operands[2]));
3628       operands[2] = op;
3629     }
3632 (define_insn "rotrsi3"
3633   [(set (match_operand:SI 0 "register_operand" "=r")
3634         (rotatert:SI (match_operand:SI 1 "register_operand" "r")
3635                      (match_operand:SI 2 "arith_operand" "rI")))]
3636   ""
3637   "rot %0,%1,%2"
3638   [(set_attr "type" "bit")])
3640 ;; find first set.
3642 ;; The ff1 instruction searches from the most significant bit while ffs
3643 ;; searches from the least significant bit.  The bit index and treatment of
3644 ;; zero also differ.  This amazing sequence was discovered using the GNU
3645 ;; Superoptimizer.
3647 (define_insn "ffssi2"
3648   [(set (match_operand:SI 0 "register_operand" "=r,&r")
3649         (ffs:SI (match_operand:SI 1 "register_operand" "0,r")))
3650    (clobber (reg:CC 0))
3651    (clobber (match_scratch:SI 2 "=r,X"))]
3652   ""
3653   "@
3654    subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2
3655    subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0"
3656   [(set_attr "type" "marith")
3657    (set_attr "length" "4")])
3659 ;; Bit field instructions.
3661 (define_insn ""
3662   [(set (match_operand:SI 0 "register_operand" "=r")
3663         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3664                          (const_int 32)
3665                          (const_int 0)))]
3666   ""
3667   "or %0,%#r0,%1")
3669 (define_insn "extv"
3670   [(set (match_operand:SI 0 "register_operand" "=r")
3671         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3672                          (match_operand:SI 2 "int5_operand" "")
3673                          (match_operand:SI 3 "int5_operand" "")))]
3674   ""
3675   "*
3677   operands[4] = gen_rtx (CONST_INT, SImode,
3678                          (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3679   return \"ext %0,%1,%2<%4>\";  /* <(32-%2-%3)> */
3681   [(set_attr "type" "bit")])
3683 (define_insn ""
3684   [(set (match_operand:SI 0 "register_operand" "=r")
3685         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3686                          (const_int 32)
3687                          (const_int 0)))]
3688   ""
3689   "or %0,%#r0,%1")
3691 (define_insn "extzv"
3692   [(set (match_operand:SI 0 "register_operand" "=r")
3693         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3694                          (match_operand:SI 2 "int5_operand" "")
3695                          (match_operand:SI 3 "int5_operand" "")))]
3696   ""
3697   "*
3699   operands[4] = gen_rtx (CONST_INT, SImode,
3700                          (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3701   return \"extu %0,%1,%2<%4>\";  /* <(32-%2-%3)> */
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         (const_int 0))]
3710   ""
3711   "*
3713   operands[3] = gen_rtx (CONST_INT, SImode,
3714                          (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3715   return \"clr %0,%0,%1<%3>\";  /* <(32-%1-%2)> */
3717   [(set_attr "type" "bit")])
3719 (define_insn ""
3720   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3721                          (match_operand:SI 1 "int5_operand" "")
3722                          (match_operand:SI 2 "int5_operand" ""))
3723         (const_int -1))]
3724   ""
3725   "*
3727   operands[3] = gen_rtx (CONST_INT, SImode,
3728                          (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3729   return \"set %0,%0,%1<%3>\";  /* <(32-%1-%2)> */
3731   [(set_attr "type" "bit")])
3733 (define_insn ""
3734   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3735                          (match_operand:SI 1 "int5_operand" "")
3736                          (match_operand:SI 2 "int5_operand" ""))
3737         (match_operand:SI 3 "int32_operand" "n"))]
3738   ""
3739   "*
3741   int value = INTVAL (operands[3]);
3743   if (INTVAL (operands[1]) < 32)
3744     value &= (1 << INTVAL (operands[1])) - 1;
3746   operands[2] = gen_rtx (CONST_INT, VOIDmode,
3747                          32 - (INTVAL(operands[1]) + INTVAL(operands[2])));
3749   value <<= INTVAL (operands[2]);
3750   operands[3] = gen_rtx (CONST_INT, VOIDmode, value);
3752   if (SMALL_INTVAL (value))
3753     return \"clr %0,%0,%1<%2>\;or %0,%0,%3\";
3754   else if ((value & 0x0000ffff) == 0)
3755     return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\";
3756   else
3757     return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\";
3759   [(set_attr "type" "marith")
3760    (set_attr "length" "3")]) ; may be 2 or 3.
3762 ;; negate insns
3763 (define_insn "negsi2"
3764   [(set (match_operand:SI 0 "register_operand" "=r")
3765         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
3766   ""
3767   "subu %0,%#r0,%1")
3769 (define_insn ""
3770   [(set (match_operand:SF 0 "register_operand" "=r,x")
3771         (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))]
3772   ""
3773   "@
3774    fsub.ssd %0,%#r0,%1
3775    fsub.ssd %0,%#x0,%1"
3776   [(set_attr "type" "dpadd")])
3778 (define_insn "negdf2"
3779   [(set (match_operand:DF 0 "register_operand" "=&r,r")
3780         (neg:DF (match_operand:DF 1 "register_operand" "r,0")))]
3781   ""
3782   "@
3783    xor.u %0,%1,0x8000\;or %d0,%#r0,%d1
3784    xor.u %0,%0,0x8000"
3785   [(set_attr "type" "marith,arith")])
3787 (define_insn "negsf2"
3788   [(set (match_operand:SF 0 "register_operand" "=r")
3789         (neg:SF (match_operand:SF 1 "register_operand" "r")))]
3790   ""
3791   "xor.u %0,%1,0x8000")
3793 ;; absolute value insns for floating-point (integer abs can be done using the
3794 ;; machine-independent sequence).
3796 (define_insn "absdf2"
3797   [(set (match_operand:DF 0 "register_operand" "=&r,r")
3798         (abs:DF (match_operand:DF 1 "register_operand" "r,0")))]
3799   ""
3800   "@
3801    and.u %0,%1,0x7fff\;or %d0,%#r0,%d1
3802    and.u %0,%0,0x7fff"
3803   [(set_attr "type" "marith,arith")])
3805 (define_insn "abssf2"
3806   [(set (match_operand:SF 0 "register_operand" "=r")
3807         (abs:SF (match_operand:SF 1 "register_operand" "r")))]
3808   ""
3809   "and.u %0,%1,0x7fff")
3811 ;; Subroutines of "casesi".
3813 ;; Operand 0 is index
3814 ;; operand 1 is the minimum bound
3815 ;; operand 2 is the maximum bound - minimum bound + 1
3816 ;; operand 3 is CODE_LABEL for the table;
3817 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3819 (define_expand "casesi"
3820   ;; We don't use these for generating the RTL, but we must describe
3821   ;; the operands here.
3822   [(match_operand:SI 0 "general_operand" "")
3823    (match_operand:SI 1 "immediate_operand" "")
3824    (match_operand:SI 2 "immediate_operand" "")
3825    (match_operand 3 "" "")
3826    (match_operand 4 "" "")]
3827   ""
3828   "
3830   register rtx index_diff = gen_reg_rtx (SImode);
3831   register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
3832   register rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[3]);
3833   register rtx base;
3835   if (! CASE_VECTOR_INSNS)
3836     /* These instructions are likely to be scheduled and made loop invariant.
3837        This decreases the cost of the dispatch at the expense of the default
3838        case.  */
3839     base = force_reg (SImode, memory_address_noforce (SImode, label));
3841   /* Compute the index difference and handle the default case.  */
3842   emit_insn (gen_addsi3 (index_diff,
3843                          force_reg (SImode, operands[0]),
3844                          ADD_INT (low) ? low : force_reg (SImode, low)));
3845   emit_insn (gen_cmpsi (index_diff, operands[2]));
3846   /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1
3847      entry to the table.  However, that doesn't seem to win on the m88110.  */
3848   emit_jump_insn (gen_bgtu (operands[4]));
3850   if (CASE_VECTOR_INSNS)
3851     /* Call the jump that will branch to the appropriate case.  */
3852     emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3]));
3853   else
3854     /* Load the table entry and jump to it.  */
3855     emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff, operands[3]));
3857   /* Claim that flow drops into the table so it will be adjacent by not
3858      emitting a barrier.  */
3859   DONE;
3862 (define_expand "casesi_jump"
3863   [(set (match_operand:SI 0 "" "")
3864         (mem:SI (plus:SI (match_operand:SI 1 "" "")
3865                          (mult:SI (match_operand:SI 2 "" "")
3866                                   (const_int 4)))))
3867    (parallel [(set (pc) (match_dup 0))
3868               (use (label_ref (match_operand 3 "" "")))])]
3869   ""
3870   "")
3872 (define_insn ""
3873   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
3874    (use (label_ref (match_operand 1 "" "")))]
3875   ""
3876   "jmp%. %0"
3877   [(set_attr "type" "jump")])
3879 ;; The bsr.n instruction is directed to the END of the table.  See
3880 ;; ASM_OUTPUT_CASE_END.
3882 (define_insn "casesi_enter"
3883   [(set (pc) (match_operand 0 "" ""))
3884    (use (match_operand:SI 1 "register_operand" "r"))
3885    ;; The USE here is so that at least one jump-insn will refer to the label,
3886    ;; to keep it alive in jump_optimize.
3887    (use (label_ref (match_operand 2 "" "")))
3888    (clobber (reg:SI 1))]
3889   ""
3890   "*
3892   if (flag_delayed_branch)
3893     return \"bsr.n %0e\;lda %#r1,%#r1[%1]\";
3894   m88k_case_index = REGNO (operands[1]);
3895   return \"bsr %0e\";
3897   [(set_attr "type" "weird")
3898    (set_attr "length" "3")]) ; Including the "jmp r1".
3900 ;;- jump to subroutine
3901 (define_expand "call"
3902   [(parallel [(call (match_operand:SI 0 "" "")
3903                     (match_operand 1 "" ""))
3904               (clobber (reg:SI 1))])]
3905   ""
3906   "
3908   if (GET_CODE (operands[0]) == MEM
3909       && ! call_address_operand (XEXP (operands[0], 0), SImode))
3910     operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
3911                            force_reg (Pmode, XEXP (operands[0], 0)));
3914 (define_insn ""
3915   [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
3916                     (match_operand 1 "" ""))
3917               (clobber (reg:SI 1))])]
3918   ""
3919   "* return output_call (operands, operands[0]);"
3920   [(set_attr "type" "call")])
3922 (define_expand "call_value"
3923   [(parallel [(set (match_operand 0 "register_operand" "")
3924                    (call (match_operand:SI 1 "" "")
3925                          (match_operand 2 "" "")))
3926               (clobber (reg:SI 1))])]
3927   ""
3928   "
3930   if (GET_CODE (operands[1]) == MEM
3931       && ! call_address_operand (XEXP (operands[1], 0), SImode))
3932     operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
3933                            force_reg (Pmode, XEXP (operands[1], 0)));
3936 (define_insn ""
3937   [(parallel [(set (match_operand 0 "register_operand" "=r")
3938                    (call (mem:SI
3939                           (match_operand:SI 1 "call_address_operand" "rQ"))
3940                          (match_operand 2 "" "")))
3941               (clobber (reg:SI 1))])]
3942   ""
3943   "* return output_call (operands, operands[1]);"
3944   [(set_attr "type" "call")])
3946 ;; Nop instruction and others
3948 (define_insn "nop"
3949   [(const_int 0)]
3950   ""
3951   "ff0 %#r0,%#r0"
3952   [(set_attr "type" "bit")])
3954 (define_insn "return"
3955   [(return)]
3956   "reload_completed"
3957   "jmp%. %#r1"
3958   [(set_attr "type" "jump")])
3960 (define_expand "prologue"
3961   [(const_int 0)]
3962   ""
3963   "m88k_expand_prologue (); DONE;")
3965 (define_expand "epilogue"
3966   [(return)]
3967   "! null_prologue ()"
3968   "m88k_expand_epilogue ();")
3970 (define_insn "blockage"
3971   [(unspec_volatile [(const_int 0)] 0)]
3972   ""
3973   ""
3974   [(set_attr "length" "0")])
3976 (define_insn "indirect_jump"
3977   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
3978   ""
3979   "jmp%. %0"
3980   [(set_attr "type" "jump")])
3982 (define_insn "jump"
3983   [(set (pc)
3984         (label_ref (match_operand 0 "" "")))]
3985   ""
3986   "br%. %l0"
3987   [(set_attr "type" "jump")])
3989 ;; This insn is used for some loop tests, typically loops reversed when
3990 ;; strength reduction is used.  It is actually created when the instruction
3991 ;; combination phase combines the special loop test.  Since this insn
3992 ;; is both a jump insn and has an output, it must deal with it's own
3993 ;; reloads, hence the `m' constraints.  The `!' constraints direct reload
3994 ;; to not choose the register alternatives in the event a reload is needed.
3996 (define_expand "decrement_and_branch_until_zero"
3997   [(parallel [(set (pc)
3998                    (if_then_else
3999                     (match_operator 0 "relop_no_unsigned"
4000                                     [(match_operand:SI 1 "register_operand" "")
4001                                      (const_int 0)])
4002                     (label_ref (match_operand 2 "" ""))
4003                     (pc)))
4004               (set (match_dup 1)
4005                    (plus:SI (match_dup 1)
4006                             (match_operand:SI 3 "add_operand" "")))
4007               (clobber (match_scratch:SI 4 ""))
4008               (clobber (match_scratch:SI 5 "=X,X,&r,&r"))])]
4009   ""
4010   "")
4012 (define_insn ""
4013   [(set (pc)
4014         (if_then_else
4015          (match_operator 0 "relop_no_unsigned"
4016                          [(match_operand:SI 1 "register_operand" "+!r,!r,m,m")
4017                           (const_int 0)])
4018           (label_ref (match_operand 2 "" ""))
4019           (pc)))
4020    (set (match_dup 1)
4021         (plus:SI (match_dup 1)
4022                  (match_operand:SI 3 "add_operand" "rI,J,rI,J")))
4023    (clobber (match_scratch:SI 4 "=X,X,&r,&r"))
4024    (clobber (match_scratch:SI 5 "=X,X,&r,&r"))]
4025   "find_reg_note (insn, REG_NONNEG, 0)"
4026   "@
4027    bcnd.n %B0,%1,%2\;addu %1,%1,%3
4028    bcnd.n %B0,%1,%2\;subu %1,%1,%n3
4029    ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1
4030    ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1"
4031   [(set_attr "type" "weird")
4032    (set_attr "length" "2,2,4,4")])
4034 ;; Special insn to serve as the last insn of a define_expand.  This insn
4035 ;; will generate no code.
4037 (define_expand "dummy"
4038   [(set (match_operand 0 "" "") (match_dup 0))]
4039   ""
4040   "")