OSDN Git Service

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