OSDN Git Service

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