OSDN Git Service

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