OSDN Git Service

* config/alpha/alpha.md, config/arm/arm.c, config/arm/arm.h,
[pf3gnuchains/gcc-fork.git] / gcc / config / i860 / i860.md
1 ;;- Machine description for Intel 860 chip for GNU C compiler
2 ;;  Copyright (C) 1989, 1990, 1997, 1998, 1999, 2000
3 ;;  Free Software Foundation, Inc.
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
26 ;;- updates for most instructions.
27
28 ;;- Operand classes for the register allocator:
29 \f
30 /* Bit-test instructions.  */
31
32 (define_insn ""
33   [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
34                           (match_operand:SI 1 "logic_operand" "rL"))
35                   (const_int 0)))]
36   ""
37   "*
38 {
39   CC_STATUS_PARTIAL_INIT;
40   return \"and %1,%0,%?r0\";
41 }")
42
43 (define_insn ""
44   [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
45                           (match_operand:SI 1 "logic_operand" "rL"))
46                   (const_int 0)))]
47   ""
48   "*
49 {
50   CC_STATUS_PARTIAL_INIT;
51   cc_status.flags |= CC_NEGATED;
52   return \"and %1,%0,%?r0\";
53 }")
54
55 (define_insn ""
56   [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
57                           (match_operand:SI 1 "immediate_operand" "i"))
58                   (const_int 0)))]
59   "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
60   "*
61 {
62   CC_STATUS_PARTIAL_INIT;
63   return \"andh %H1,%0,%?r0\";
64 }")
65
66 (define_insn ""
67   [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
68                           (match_operand:SI 1 "immediate_operand" "i"))
69                   (const_int 0)))]
70   "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
71   "*
72 {
73   CC_STATUS_PARTIAL_INIT;
74   cc_status.flags |= CC_NEGATED;
75   return \"andh %H1,%0,%?r0\";
76 }")
77
78 (define_insn ""
79   [(set (cc0) (eq (ashiftrt:SI
80                    (sign_extend:SI
81                     (ashift:QI (match_operand:QI 0 "register_operand" "r")
82                                (match_operand:QI 1 "logic_int" "n")))
83                    (match_operand:SI 2 "logic_int" "n"))
84                   (const_int 0)))]
85   ""
86   "*
87 {
88   int width = 8 - INTVAL (operands[2]);
89   int pos = 8 - width - INTVAL (operands[1]);
90
91   CC_STATUS_PARTIAL_INIT;
92   operands[2] = GEN_INT (~((-1) << width) << pos);
93   return \"and %2,%0,%?r0\";
94 }")
95 \f
96 ;; -------------------------------------------------------------------------
97 ;; SImode signed integer comparisons
98 ;; -------------------------------------------------------------------------
99
100 (define_insn "cmpeqsi"
101   [(set (cc0) (eq (match_operand:SI 0 "logic_operand" "r,rL")
102                   (match_operand:SI 1 "logic_operand" "L,r")))]
103   ""
104   "*
105 {
106   CC_STATUS_PARTIAL_INIT;
107   if (REG_P (operands[0]))
108     return \"xor %1,%0,%?r0\";
109   else
110     return \"xor %0,%1,%?r0\";
111 }")
112
113 (define_insn "cmpnesi"
114   [(set (cc0) (ne (match_operand:SI 0 "logic_operand" "r,rL")
115                   (match_operand:SI 1 "logic_operand" "L,r")))]
116   ""
117   "*
118 {
119   CC_STATUS_PARTIAL_INIT;
120   cc_status.flags |= CC_NEGATED;
121   if (REG_P (operands[0]))
122     return \"xor %1,%0,%?r0\";
123   else
124     return \"xor %0,%1,%?r0\";
125 }")
126
127 (define_insn "cmpltsi"
128   [(set (cc0) (lt (match_operand:SI 0 "arith_operand" "r,rI")
129                   (match_operand:SI 1 "arith_operand" "I,r")))]
130   ""
131   "*
132 {
133   CC_STATUS_PARTIAL_INIT;
134   if (REG_P (operands[1]))
135     return \"subs %0,%1,%?r0\";
136   else
137     {
138       cc_status.flags |= CC_REVERSED;
139       operands[1] = GEN_INT (- INTVAL (operands[1]));
140       return \"adds %1,%0,%?r0\";
141     }
142 }")
143
144 (define_insn "cmpgtsi"
145   [(set (cc0) (gt (match_operand:SI 0 "arith_operand" "r,rI")
146                   (match_operand:SI 1 "arith_operand" "I,r")))]
147   ""
148   "*
149 {
150   CC_STATUS_PARTIAL_INIT;
151   if (REG_P (operands[0]))
152     return \"subs %1,%0,%?r0\";
153   else
154     {
155       cc_status.flags |= CC_REVERSED;
156       operands[0] = GEN_INT (- INTVAL (operands[0]));
157       return \"adds %0,%1,%?r0\";
158     }
159 }")
160
161 (define_insn "cmplesi"
162   [(set (cc0) (le (match_operand:SI 0 "arith_operand" "r,rI")
163                   (match_operand:SI 1 "arith_operand" "I,r")))]
164   ""
165   "*
166 {
167   CC_STATUS_PARTIAL_INIT;
168   cc_status.flags |= CC_NEGATED;
169   if (REG_P (operands[0]))
170     return \"subs %1,%0,%?r0\";
171   else
172     {
173       cc_status.flags |= CC_REVERSED;
174       operands[0] = GEN_INT (- INTVAL (operands[0]));
175       return \"adds %0,%1,%?r0\";
176     }
177 }")
178
179 (define_insn "cmpgesi"
180   [(set (cc0) (ge (match_operand:SI 0 "arith_operand" "r,rI")
181                   (match_operand:SI 1 "arith_operand" "I,r")))]
182   ""
183   "*
184 {
185   CC_STATUS_PARTIAL_INIT;
186   cc_status.flags |= CC_NEGATED;
187   if (REG_P (operands[1]))
188     return \"subs %0,%1,%?r0\";
189   else
190     {
191       cc_status.flags |= CC_REVERSED;
192       operands[1] = GEN_INT (- INTVAL (operands[1]));
193       return \"adds %1,%0,%?r0\";
194     }
195 }")
196
197 ;; -------------------------------------------------------------------------
198 ;; SImode unsigned integer comparisons
199 ;; -------------------------------------------------------------------------
200
201 ;; WARNING!  There is a small i860 hardware limitation (bug?) which we
202 ;; may run up against (if we are not careful) when we are trying to do
203 ;; unsigned comparisons like (x >= 0), (x < 0), (0 <= x), and (0 > x).
204 ;; Specifically, we must avoid using an `addu' instruction to perform
205 ;; such comparisons because the result (in the CC bit register) will
206 ;; come out wrong.  (This fact is documented in a footnote on page 7-10
207 ;; of the 1991 version of the i860 Microprocessor Family Programmer's
208 ;; Reference Manual).  Note that unsigned comparisons of this sort are
209 ;; always redundant anyway, because an unsigned quantity can never be
210 ;; less than zero.  When we see cases like this, we generate an
211 ;; `or K,%r0,%r0' instruction instead (where K is a constant 0 or -1)
212 ;; so as to get the CC bit register set properly for any subsequent
213 ;; conditional jump instruction.
214
215 (define_insn "cmpgeusi"
216   [(set (cc0) (geu (match_operand:SI 0 "arith_operand" "r,rI")
217                    (match_operand:SI 1 "arith_operand" "I,r")))]
218   ""
219   "*
220 {
221   CC_STATUS_PARTIAL_INIT;
222   if (REG_P (operands[1]))
223     return \"subu %0,%1,%?r0\";
224   else
225     {
226       if (INTVAL (operands[1]) == 0)
227         return \"or 0,%?r0,%?r0\";
228       else
229         {
230           cc_status.flags |= CC_REVERSED;
231           operands[1] = GEN_INT (- INTVAL (operands[1]));
232           return \"addu %1,%0,%?r0\";
233         }
234     }
235 }")
236
237 (define_insn "cmpleusi"
238   [(set (cc0) (leu (match_operand:SI 0 "arith_operand" "r,rI")
239                    (match_operand:SI 1 "arith_operand" "I,r")))]
240   ""
241   "*
242 {
243   CC_STATUS_PARTIAL_INIT;
244   if (REG_P (operands[0]))
245     return \"subu %1,%0,%?r0\";
246   else
247     {
248       if (INTVAL (operands[0]) == 0)
249         return \"or 0,%?r0,%?r0\";
250       else
251         {
252           cc_status.flags |= CC_REVERSED;
253           operands[0] = GEN_INT (- INTVAL (operands[0]));
254           return \"addu %0,%1,%?r0\";
255         }
256     }
257 }")
258
259 ;; -------------------------------------------------------------------------
260 ;; SFmode floating-point comparisons
261 ;; -------------------------------------------------------------------------
262
263 (define_insn "cmpeqsf"
264   [(set (cc0) (eq (match_operand:SF 0 "reg_or_0_operand" "fG")
265                   (match_operand:SF 1 "reg_or_0_operand" "fG")))]
266   ""
267   "*
268 {
269   CC_STATUS_PARTIAL_INIT;
270   return \"pfeq.ss %r0,%r1,%?f0\";
271 }")
272
273 (define_insn "cmpnesf"
274   [(set (cc0) (ne (match_operand:SF 0 "reg_or_0_operand" "fG")
275                   (match_operand:SF 1 "reg_or_0_operand" "fG")))]
276   ""
277   "*
278 {
279   CC_STATUS_PARTIAL_INIT;
280   cc_status.flags |= CC_NEGATED;
281   return \"pfeq.ss %r1,%r0,%?f0\";
282 }")
283
284 ;; NOTE:  The i860 Programmer's Reference Manual says that when we are
285 ;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these
286 ;; in order to be IEEE compliant (in case a trap occurs during these
287 ;; operations).  Conversely, for (A <= B) or (A >= B) comparisons, we
288 ;; must use pfle to be IEEE compliant.
289
290 (define_insn "cmpltsf"
291   [(set (cc0) (lt (match_operand:SF 0 "reg_or_0_operand" "fG")
292                   (match_operand:SF 1 "reg_or_0_operand" "fG")))]
293   ""
294   "*
295 {
296   CC_STATUS_PARTIAL_INIT;
297   return \"pfgt.ss %r1,%r0,%?f0\";
298 }")
299
300 (define_insn "cmpgtsf"
301   [(set (cc0) (gt (match_operand:SF 0 "reg_or_0_operand" "fG")
302                   (match_operand:SF 1 "reg_or_0_operand" "fG")))]
303   ""
304   "*
305 {
306   CC_STATUS_PARTIAL_INIT;
307   return \"pfgt.ss %r0,%r1,%?f0\";
308 }")
309
310 ;; NOTE:  The pfle opcode doesn't do what you think it does.  It is
311 ;; bass-ackwards.  It *clears* the CC flag if the first operand is
312 ;; less than or equal to the second.  Thus, we have to set CC_NEGATED
313 ;; for the following two patterns.
314
315 (define_insn "cmplesf"
316   [(set (cc0) (le (match_operand:SF 0 "reg_or_0_operand" "fG")
317                   (match_operand:SF 1 "reg_or_0_operand" "fG")))]
318   ""
319   "*
320 {
321   CC_STATUS_PARTIAL_INIT;
322   cc_status.flags |= CC_NEGATED;
323   return \"pfle.ss %r0,%r1,%?f0\";
324 }")
325
326 (define_insn "cmpgesf"
327   [(set (cc0) (ge (match_operand:SF 0 "reg_or_0_operand" "fG")
328                   (match_operand:SF 1 "reg_or_0_operand" "fG")))]
329   ""
330   "*
331 {
332   CC_STATUS_PARTIAL_INIT;
333   cc_status.flags |= CC_NEGATED;
334   return \"pfle.ss %r1,%r0,%?f0\";
335 }")
336
337 ;; -------------------------------------------------------------------------
338 ;; DFmode floating-point comparisons
339 ;; -------------------------------------------------------------------------
340
341 (define_insn "cmpeqdf"
342   [(set (cc0) (eq (match_operand:DF 0 "reg_or_0_operand" "fG")
343                   (match_operand:DF 1 "reg_or_0_operand" "fG")))]
344   ""
345   "*
346 {
347   CC_STATUS_PARTIAL_INIT;
348   return \"pfeq.dd %r0,%r1,%?f0\";
349 }")
350
351 (define_insn "cmpnedf"
352   [(set (cc0) (ne (match_operand:DF 0 "reg_or_0_operand" "fG")
353                   (match_operand:DF 1 "reg_or_0_operand" "fG")))]
354   ""
355   "*
356 {
357   CC_STATUS_PARTIAL_INIT;
358   cc_status.flags |= CC_NEGATED;
359   return \"pfeq.dd %r1,%r0,%?f0\";
360 }")
361
362 ;; NOTE:  The i860 Programmer's Reference Manual says that when we are
363 ;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these
364 ;; in order to be IEEE compliant (in case a trap occurs during these
365 ;; operations).  Conversely, for (A <= B) or (A >= B) comparisons, we
366 ;; must use pfle to be IEEE compliant.
367
368 (define_insn "cmpltdf"
369   [(set (cc0) (lt (match_operand:DF 0 "reg_or_0_operand" "fG")
370                   (match_operand:DF 1 "reg_or_0_operand" "fG")))]
371   ""
372   "*
373 {
374   CC_STATUS_PARTIAL_INIT;
375   return \"pfgt.dd %r1,%r0,%?f0\";
376 }")
377
378 (define_insn "cmpgtdf"
379   [(set (cc0) (gt (match_operand:DF 0 "reg_or_0_operand" "fG")
380                   (match_operand:DF 1 "reg_or_0_operand" "fG")))]
381   ""
382   "*
383 {
384   CC_STATUS_PARTIAL_INIT;
385   return \"pfgt.dd %r0,%r1,%?f0\";
386 }")
387
388 ;; NOTE:  The pfle opcode doesn't do what you think it does.  It is
389 ;; bass-ackwards.  It *clears* the CC flag if the first operand is
390 ;; less than or equal to the second.  Thus, we have to set CC_NEGATED
391 ;; for the following two patterns.
392
393 (define_insn "cmpledf"
394   [(set (cc0) (le (match_operand:DF 0 "reg_or_0_operand" "fG")
395                   (match_operand:DF 1 "reg_or_0_operand" "fG")))]
396   ""
397   "*
398 {
399   CC_STATUS_PARTIAL_INIT;
400   cc_status.flags |= CC_NEGATED;
401   return \"pfle.dd %r0,%r1,%?f0\";
402 }")
403
404 (define_insn "cmpgedf"
405   [(set (cc0) (ge (match_operand:DF 0 "reg_or_0_operand" "fG")
406                   (match_operand:DF 1 "reg_or_0_operand" "fG")))]
407   ""
408   "*
409 {
410   CC_STATUS_PARTIAL_INIT;
411   cc_status.flags |= CC_NEGATED;
412   return \"pfle.dd %r1,%r0,%?f0\";
413 }")
414
415 ;; ------------------------------------------------------------------------
416 ;; Integer EQ/NE comparisons against constant values which will fit in the
417 ;; 16-bit immediate field of an instruction.  These are made by combining.
418 ;; ------------------------------------------------------------------------
419
420 (define_insn ""
421   [(set (cc0) (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m"))
422                   (match_operand:SI 1 "small_int" "I")))]
423   "INTVAL (operands[1]) >= 0"
424   "*
425 {
426   CC_STATUS_PARTIAL_INIT;
427   return \"ld.s %0,%?r31\;xor %1,%?r31,%?r0\";
428 }")
429
430 (define_insn ""
431   [(set (cc0) (eq (match_operand:SI 0 "small_int" "I")
432                   (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))))]
433   "INTVAL (operands[0]) >= 0"
434   "*
435 {
436   CC_STATUS_PARTIAL_INIT;
437   return \"ld.s %1,%?r31\;xor %0,%?r31,%?r0\";
438 }")
439 \f
440 ;; ------------------------------------------------------------------------
441 ;; Define the real conditional branch instructions.
442 ;; ------------------------------------------------------------------------
443
444 (define_insn "cbranch"
445   [(set (pc) (if_then_else (eq (cc0) (const_int 0))
446                            (label_ref (match_operand 0 "" ""))
447                            (pc)))]
448   ""
449   "*
450 {
451   if ((cc_prev_status.flags & CC_NEGATED) == 0)
452     return \"bnc %l0\";
453   else
454     return \"bc %l0\";
455 }")
456
457 (define_insn "flipped_cbranch"
458   [(set (pc) (if_then_else (ne (cc0)
459                                (const_int 0))
460                            (pc)
461                            (label_ref (match_operand 0 "" ""))))]
462   ""
463   "*
464 {
465   if ((cc_prev_status.flags & CC_NEGATED) == 0)
466     return \"bnc %l0\";
467   else
468     return \"bc %l0\";
469 }")
470
471 (define_insn "inverse_cbranch"
472   [(set (pc) (if_then_else (eq (cc0)
473                                (const_int 0))
474                            (pc)
475                            (label_ref (match_operand 0 "" ""))))]
476   ""
477   "*
478 {
479   if ((cc_prev_status.flags & CC_NEGATED) == 0)
480     return \"bc %l0\";
481   else
482     return \"bnc %l0\";
483 }")
484
485
486 (define_insn "flipped_inverse_cbranch"
487   [(set (pc) (if_then_else (ne (cc0)
488                                (const_int 0))
489                            (label_ref (match_operand 0 "" ""))
490                            (pc)))]
491   ""
492   "*
493 {
494   if ((cc_prev_status.flags & CC_NEGATED) == 0)
495     return \"bc %l0\";
496   else
497     return \"bnc %l0\";
498 }")
499
500 ;; Simple BTE/BTNE compare-and-branch insns made by combining.
501 ;; Note that it is wrong to add similar patterns for QI or HImode
502 ;; because bte/btne always compare the whole register.
503
504 (define_insn ""
505   [(set (pc)
506         (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
507                           (match_operand:SI 1 "bte_operand" "rK"))
508                       (label_ref (match_operand 2 "" ""))
509                       (pc)))]
510   ""
511   "bte %1,%0,%2")
512
513 (define_insn ""
514   [(set (pc)
515         (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
516                           (match_operand:SI 1 "bte_operand" "rK"))
517                       (label_ref (match_operand 2 "" ""))
518                       (pc)))]
519   ""
520   "btne %1,%0,%2")
521
522 (define_insn ""
523   [(set (pc)
524         (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
525                           (match_operand:SI 1 "bte_operand" "rK"))
526                       (pc)
527                       (label_ref (match_operand 2 "" ""))))]
528   ""
529   "btne %1,%0,%2")
530
531 (define_insn ""
532   [(set (pc)
533         (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
534                           (match_operand:SI 1 "bte_operand" "rK"))
535                       (pc)
536                       (label_ref (match_operand 2 "" ""))))]
537   ""
538   "bte %1,%0,%2")
539
540 ;; Load byte/halfword, zero-extend, & compare-and-branch insns.
541 ;; These are made by combining.
542
543 (define_insn ""
544   [(set (pc)
545         (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
546                           (match_operand:SI 1 "bte_operand" "K"))
547                       (label_ref (match_operand 2 "" ""))
548                       (pc)))
549    (match_scratch:SI 3 "=r")]
550   ""
551   "ld.b %0,%3;bte %1,%3,%2")
552
553 (define_insn ""
554   [(set (pc)
555         (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
556                           (match_operand:SI 1 "bte_operand" "K"))
557                       (label_ref (match_operand 2 "" ""))
558                       (pc)))
559    (match_scratch:SI 3 "=r")]
560   ""
561   "ld.b %0,%3;btne %1,%3,%2")
562
563 (define_insn ""
564   [(set (pc)
565         (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
566                           (match_operand:SI 1 "bte_operand" "K"))
567                       (pc)
568                       (label_ref (match_operand 2 "" ""))))
569    (match_scratch:SI 3 "=r")]
570   ""
571   "ld.b %0,%3;btne %1,%3,%2")
572
573 (define_insn ""
574   [(set (pc)
575         (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
576                           (match_operand:SI 1 "bte_operand" "K"))
577                       (pc)
578                       (label_ref (match_operand 2 "" ""))))
579    (match_scratch:SI 3 "=r")]
580   ""
581   "ld.b %0,%3;bte %1,%3,%2")
582
583 (define_insn ""
584   [(set (pc)
585         (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
586                           (match_operand:SI 1 "bte_operand" "K"))
587                       (label_ref (match_operand 2 "" ""))
588                       (pc)))
589    (match_scratch:SI 3 "=r")]
590   ""
591   "ld.s %0,%3;bte %1,%3,%2")
592
593 (define_insn ""
594   [(set (pc)
595         (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
596                           (match_operand:SI 1 "bte_operand" "K"))
597                       (label_ref (match_operand 2 "" ""))
598                       (pc)))
599    (match_scratch:SI 3 "=r")]
600   ""
601   "ld.s %0,%3;btne %1,%3,%2")
602
603 (define_insn ""
604   [(set (pc)
605         (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
606                           (match_operand:SI 1 "bte_operand" "K"))
607                       (pc)
608                       (label_ref (match_operand 2 "" ""))))
609    (match_scratch:SI 3 "=r")]
610   ""
611   "ld.s %0,%3;btne %1,%3,%2")
612
613 (define_insn ""
614   [(set (pc)
615         (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
616                           (match_operand:SI 1 "bte_operand" "K"))
617                       (pc)
618                       (label_ref (match_operand 2 "" ""))))
619    (match_scratch:SI 3 "=r")]
620   ""
621   "ld.s %0,%3;bte %1,%3,%2")
622
623 \f
624 ;; Generation of conditionals.
625
626 ;; We save the compare operands in the cmpxx patterns and use then when
627 ;; we generate the branch.
628
629 (define_expand "cmpsi"
630   [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
631                        (match_operand:SI 1 "compare_operand" "")))]
632   ""
633   "
634 { i860_compare_op0 = operands[0];
635   i860_compare_op1 = operands[1];
636   DONE;
637 }")
638
639 (define_expand "cmpsf"
640   [(set (cc0) (compare (match_operand:SF 0 "register_operand" "")
641                        (match_operand:SF 1 "register_operand" "")))]
642   ""
643   "
644 { i860_compare_op0 = operands[0];
645   i860_compare_op1 = operands[1];
646   DONE;
647 }")
648
649 (define_expand "cmpdf"
650   [(set (cc0) (compare (match_operand:DF 0 "register_operand" "")
651                        (match_operand:DF 1 "register_operand" "")))]
652   ""
653   "
654 { i860_compare_op0 = operands[0];
655   i860_compare_op1 = operands[1];
656   DONE;
657 }")
658
659 ;; These are the standard-named conditional branch patterns.
660 ;; Detailed comments are found in the first one only.
661
662 (define_expand "beq"
663   [(set (pc)
664         (if_then_else (eq (cc0)
665                           (const_int 0))
666                       (label_ref (match_operand 0 "" ""))
667                       (pc)))]
668   ""
669   "
670 {
671   /* Emit a single-condition compare insn according to
672      the type of operands and the condition to be tested.  */
673
674   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
675     emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
676   else if (GET_MODE (i860_compare_op0) == SFmode)
677     emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
678   else if (GET_MODE (i860_compare_op0) == DFmode)
679     emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
680   else
681     abort ();
682
683   /* Emit branch-if-true.  */
684
685   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
686   DONE;
687 }")
688
689 (define_expand "bne"
690   [(set (pc)
691         (if_then_else (ne (cc0)
692                           (const_int 0))
693                       (label_ref (match_operand 0 "" ""))
694                       (pc)))]
695   ""
696   "
697 {
698   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
699     emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
700   else if (GET_MODE (i860_compare_op0) == SFmode)
701     emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
702   else if (GET_MODE (i860_compare_op0) == DFmode)
703     emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
704   else
705     abort ();
706
707   emit_jump_insn (gen_flipped_cbranch (operands[0]));
708
709   DONE;
710 }")
711
712 (define_expand "bgt"
713   [(set (pc)
714         (if_then_else (gt (cc0)
715                           (const_int 0))
716                       (label_ref (match_operand 0 "" ""))
717                       (pc)))]
718   ""
719   "
720 {
721   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
722     emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
723   else if (GET_MODE (i860_compare_op0) == SFmode)
724     emit_insn (gen_cmpgtsf (i860_compare_op0, i860_compare_op1));
725   else if (GET_MODE (i860_compare_op0) == DFmode)
726     emit_insn (gen_cmpgtdf (i860_compare_op0, i860_compare_op1));
727   else
728     abort ();
729
730   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
731   DONE;
732 }")
733
734 (define_expand "blt"
735   [(set (pc)
736         (if_then_else (lt (cc0)
737                           (const_int 0))
738                       (label_ref (match_operand 0 "" ""))
739                       (pc)))]
740   ""
741   "
742 {
743   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
744     emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
745   else if (GET_MODE (i860_compare_op0) == SFmode)
746     emit_insn (gen_cmpltsf (i860_compare_op0, i860_compare_op1));
747   else if (GET_MODE (i860_compare_op0) == DFmode)
748     emit_insn (gen_cmpltdf (i860_compare_op0, i860_compare_op1));
749   else
750     abort ();
751
752   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
753   DONE;
754 }")
755
756 (define_expand "ble"
757   [(set (pc)
758         (if_then_else (le (cc0)
759                           (const_int 0))
760                       (label_ref (match_operand 0 "" ""))
761                       (pc)))]
762   ""
763   "
764 {
765   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
766     {
767       emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
768       emit_jump_insn (gen_flipped_cbranch (operands[0]));
769     }
770   else
771     {
772       if (GET_MODE (i860_compare_op0) == SFmode)
773         emit_insn (gen_cmplesf (i860_compare_op0, i860_compare_op1));
774       else if (GET_MODE (i860_compare_op0) == DFmode)
775         emit_insn (gen_cmpledf (i860_compare_op0, i860_compare_op1));
776       else
777         abort ();
778       emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
779     }
780   DONE;
781 }")
782
783 (define_expand "bge"
784   [(set (pc)
785         (if_then_else (ge (cc0)
786                           (const_int 0))
787                       (label_ref (match_operand 0 "" ""))
788                       (pc)))]
789   ""
790   "
791 {
792   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
793     {
794       emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
795       emit_jump_insn (gen_flipped_cbranch (operands[0]));
796     }
797   else
798     {
799       if (GET_MODE (i860_compare_op0) == SFmode)
800         emit_insn (gen_cmpgesf (i860_compare_op0, i860_compare_op1));
801       else if (GET_MODE (i860_compare_op0) == DFmode)
802         emit_insn (gen_cmpgedf (i860_compare_op0, i860_compare_op1));
803       else
804         abort ();
805       emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
806     }
807   DONE;
808 }")
809
810 (define_expand "bgtu"
811   [(set (pc)
812         (if_then_else (gtu (cc0)
813                            (const_int 0))
814                       (label_ref (match_operand 0 "" ""))
815                       (pc)))]
816   ""
817   "
818 {
819   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
820     abort ();
821
822   emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
823   emit_jump_insn (gen_flipped_cbranch (operands[0]));
824   DONE;
825 }")
826
827 (define_expand "bltu"
828   [(set (pc)
829         (if_then_else (ltu (cc0)
830                            (const_int 0))
831                       (label_ref (match_operand 0 "" ""))
832                       (pc)))]
833   ""
834   "
835 {
836   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
837     abort ();
838
839   emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
840   emit_jump_insn (gen_flipped_cbranch (operands[0]));
841   DONE;
842 }")
843
844 (define_expand "bgeu"
845   [(set (pc)
846         (if_then_else (geu (cc0)
847                            (const_int 0))
848                       (label_ref (match_operand 0 "" ""))
849                       (pc)))]
850   ""
851   "
852 {
853   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
854     abort ();
855
856   emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
857   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
858   DONE;
859 }")
860
861 (define_expand "bleu"
862   [(set (pc)
863         (if_then_else (leu (cc0)
864                            (const_int 0))
865                       (label_ref (match_operand 0 "" ""))
866                       (pc)))]
867   ""
868   "
869 {
870   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
871     abort ();
872
873   emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
874   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
875   DONE;
876 }")
877 \f
878 ;; Move instructions
879
880 ;; Note that source operands for `mov' pseudo-instructions are no longer
881 ;; allowed (by the svr4 assembler) to be "big" things, i.e. constants that
882 ;; won't fit in 16-bits.  (This includes any sort of a relocatable address
883 ;; also.)  Thus, we must use an explicit orh/or pair of instructions if
884 ;; the source operand is something "big".
885
886 (define_insn "movsi"
887   [(set (match_operand:SI 0 "general_operand" "=r,m,f")
888         (match_operand:SI 1 "general_operand" "rmif,rfJ,rmfJ"))]
889   ""
890   "*
891 {
892   if (GET_CODE (operands[0]) == MEM)
893     {
894       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
895         return output_store (operands);
896       if (FP_REG_P (operands[1]))
897         return \"fst.l %1,%0\";
898       return \"st.l %r1,%0\";
899     }
900   if (GET_CODE (operands[1]) == MEM)
901     {
902       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
903         return output_load (operands);
904       if (FP_REG_P (operands[0]))
905         return \"fld.l %1,%0\";
906       return \"ld.l %1,%0\";
907     }
908   if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
909     return \"fmov.ss %1,%0\";
910   if (FP_REG_P (operands[1]))
911     return \"fxfr %1,%0\";
912   if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
913     return \"fmov.ss %?f0,%0\";
914   if (FP_REG_P (operands[0]))
915     return \"ixfr %1,%0\";
916
917   if (GET_CODE (operands[1]) == REG)
918     return \"shl %?r0,%1,%0\";
919
920   CC_STATUS_PARTIAL_INIT;
921
922   if (GET_CODE (operands[1]) == CONST_INT)
923     {
924       if((INTVAL (operands[1]) & 0xffff0000) == 0)
925         return \"or %L1,%?r0,%0\";
926       if((INTVAL (operands[1]) & 0x0000ffff) == 0)
927         return \"orh %H1,%?r0,%0\";
928     }
929   return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
930 }")
931  
932 (define_insn "movhi"
933   [(set (match_operand:HI 0 "general_operand" "=r,m,!*f,!r")
934         (match_operand:HI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
935   ""
936   "*
937 {
938   if (GET_CODE (operands[0]) == MEM)
939     {
940       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
941         return output_store (operands);
942       return \"st.s %r1,%0\";
943     }
944   if (GET_CODE (operands[1]) == MEM)
945     {
946       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
947         return output_load (operands);
948       return \"ld.s %1,%0\";
949     }
950   if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
951     return \"fmov.ss %1,%0\";
952   if (FP_REG_P (operands[1]))
953     return \"fxfr %1,%0\";
954   if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
955     return \"fmov.ss %?f0,%0\";
956   if (FP_REG_P (operands[0]))
957     return \"ixfr %1,%0\";
958
959   if (GET_CODE (operands[1]) == REG)
960     return \"shl %?r0,%1,%0\";
961
962   CC_STATUS_PARTIAL_INIT;
963
964   return \"or %L1,%?r0,%0\";
965 }")
966
967 (define_insn "movqi"
968   [(set (match_operand:QI 0 "general_operand" "=r,m,!*f,!r")
969         (match_operand:QI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
970   ""
971   "*
972 {
973   if (GET_CODE (operands[0]) == MEM)
974     {
975       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
976         return output_store (operands);
977       return \"st.b %r1,%0\";
978     }
979   if (GET_CODE (operands[1]) == MEM)
980     {
981       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
982         return output_load (operands);
983       return \"ld.b %1,%0\";
984     }
985   if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
986     return \"fmov.ss %1,%0\";
987   if (FP_REG_P (operands[1]))
988     return \"fxfr %1,%0\";
989   if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
990     return \"fmov.ss %?f0,%0\";
991   if (FP_REG_P (operands[0]))
992     return \"ixfr %1,%0\";
993
994   if (GET_CODE (operands[1]) == REG)
995     return \"shl %?r0,%1,%0\";
996
997   CC_STATUS_PARTIAL_INIT;
998
999   return \"or %L1,%?r0,%0\";
1000 }")
1001
1002 ;; The definition of this insn does not really explain what it does,
1003 ;; but it should suffice
1004 ;; that anything generated as this insn will be recognized as one
1005 ;; and that it won't successfully combine with anything.
1006 (define_expand "movstrsi"
1007   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
1008                    (match_operand:BLK 1 "general_operand" ""))
1009               (use (match_operand:SI 2 "nonmemory_operand" ""))
1010               (use (match_operand:SI 3 "immediate_operand" ""))
1011               (clobber (match_dup 4))
1012               (clobber (match_dup 5))
1013               (clobber (match_dup 6))
1014               (clobber (match_dup 7))
1015               (clobber (match_dup 8))])]
1016   ""
1017   "
1018 {
1019   operands[4] = gen_reg_rtx (SImode);
1020   operands[5] = gen_reg_rtx (SImode);
1021   operands[6] = gen_reg_rtx (SImode);
1022   operands[7] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1023   operands[8] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1024
1025   operands[0] = replace_equiv_address (operands[0], operands[7]);
1026   operands[1] = replace_equiv_address (operands[1], operands[8]);
1027 }")
1028
1029 (define_insn ""
1030   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
1031         (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1032    (use (match_operand:SI 2 "general_operand" "rn"))
1033    (use (match_operand:SI 3 "immediate_operand" "i"))
1034    (clobber (match_operand:SI 4 "register_operand" "=r"))
1035    (clobber (match_operand:SI 5 "register_operand" "=r"))
1036    (clobber (match_operand:SI 6 "register_operand" "=r"))
1037    (clobber (match_dup 0))
1038    (clobber (match_dup 1))]
1039   ""
1040   "* return output_block_move (operands);")
1041 \f
1042 ;; Floating point move insns
1043
1044 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1045 ;; to be reloaded by putting the constant into memory.
1046 ;; It must come before the more general movdf pattern.
1047 (define_insn ""
1048   [(set (match_operand:DF 0 "general_operand" "=r,f,o")
1049         (match_operand:DF 1 "" "mG,m,G"))]
1050   "GET_CODE (operands[1]) == CONST_DOUBLE"
1051   "*
1052 {
1053   if (FP_REG_P (operands[0]) || operands[1] == CONST0_RTX (DFmode))
1054     return output_fp_move_double (operands);
1055   return output_move_double (operands);
1056 }")
1057
1058 (define_insn "movdf"
1059   [(set (match_operand:DF 0 "general_operand" "=*rm,*r,?f,?*rm")
1060         (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))]
1061   ""
1062   "*
1063 {
1064   if (GET_CODE (operands[0]) == MEM
1065       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1066     return output_store (operands);
1067   if (GET_CODE (operands[1]) == MEM
1068       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1069     return output_load (operands);
1070
1071   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1072     return output_fp_move_double (operands);
1073   return output_move_double (operands);
1074 }")
1075
1076 (define_insn "movdi"
1077   [(set (match_operand:DI 0 "general_operand" "=rm,r,?f,?rm")
1078         (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))]
1079   ""
1080   "*
1081 {
1082   if (GET_CODE (operands[0]) == MEM
1083       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1084     return output_store (operands);
1085   if (GET_CODE (operands[1]) == MEM
1086       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1087     return output_load (operands);
1088
1089   /* ??? How can we have a DFmode arg here with DImode above? */
1090   if (FP_REG_P (operands[0]) && operands[1] == CONST0_RTX (DFmode))
1091     return \"fmov.dd %?f0,%0\";
1092
1093   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1094     return output_fp_move_double (operands);
1095   return output_move_double (operands);
1096 }")
1097
1098 ;; The alternative m/r is separate from m/f
1099 ;; The first alternative is separate from the second for the same reason.
1100 (define_insn "movsf"
1101   [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m")
1102         (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))]
1103   ""
1104   "*
1105 {
1106   if (GET_CODE (operands[0]) == MEM
1107       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1108     return output_store (operands);
1109   if (GET_CODE (operands[1]) == MEM
1110       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1111     return output_load (operands);
1112   if (FP_REG_P (operands[0]))
1113     {
1114       if (FP_REG_P (operands[1]))
1115         return \"fmov.ss %1,%0\";
1116       if (GET_CODE (operands[1]) == REG)
1117         return \"ixfr %1,%0\";
1118       if (operands[1] == CONST0_RTX (SFmode))
1119         return \"fmov.ss %?f0,%0\";
1120       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1121         {
1122           if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1123                  && (cc_prev_status.flags & CC_HI_R31_ADJ)
1124                  && cc_prev_status.mdep == XEXP(operands[1],0)))
1125             {
1126               CC_STATUS_INIT;
1127               cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1128               cc_status.mdep = XEXP (operands[1], 0);
1129               return \"orh %h1,%?r0,%?r31\;fld.l %L1(%?r31),%0\";
1130             }
1131           return \"fld.l %L1(%?r31),%0\";
1132         }
1133       return \"fld.l %1,%0\";
1134     }
1135   if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
1136     {
1137       if (GET_CODE (operands[0]) == REG && FP_REG_P (operands[1]))
1138         return \"fxfr %1,%0\";
1139       if (GET_CODE (operands[0]) == REG)
1140         {
1141           CC_STATUS_PARTIAL_INIT;
1142           if (GET_CODE (operands[1]) == CONST_DOUBLE)
1143             {
1144               register unsigned long ul;
1145
1146               ul = sfmode_constant_to_ulong (operands[1]);
1147               if ((ul & 0x0000ffff) == 0)
1148                 return \"orh %H1,%?r0,%0\";
1149               if ((ul & 0xffff0000) == 0)
1150                 return \"or %L1,%?r0,%0\";
1151             }
1152           return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
1153         }
1154       /* Now operand 0 must be memory.
1155          If operand 1 is CONST_DOUBLE, its value must be 0.  */
1156       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1157         {
1158           if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1159                  && (cc_prev_status.flags & CC_HI_R31_ADJ)
1160                  && XEXP (operands[0], 0) == cc_prev_status.mdep))
1161             {
1162               CC_STATUS_INIT;
1163               cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1164               cc_status.mdep = XEXP (operands[0], 0);
1165               output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1166             }
1167           return \"fst.l %r1,%L0(%?r31)\";
1168         }
1169       return \"fst.l %r1,%0\";
1170     }
1171   if (GET_CODE (operands[0]) == MEM)
1172     return \"st.l %r1,%0\";
1173   if (GET_CODE (operands[1]) == MEM)
1174     return \"ld.l %1,%0\";
1175   if (operands[1] == CONST0_RTX (SFmode))
1176     return \"shl %?r0,%?r0,%0\";
1177   return \"mov %1,%0\";
1178 }")
1179 \f
1180 ;; Special load insns for REG+REG addresses.
1181 ;; Such addresses are not "legitimate" because st rejects them.
1182
1183 (define_insn ""
1184   [(set (match_operand:DF 0 "register_operand" "=rf")
1185         (match_operand:DF 1 "indexed_operand" "m"))]
1186   ""
1187   "*
1188 {
1189   if (FP_REG_P (operands[0]))
1190     return output_fp_move_double (operands);
1191   return output_move_double (operands);
1192 }")
1193
1194 (define_insn ""
1195   [(set (match_operand:SF 0 "register_operand" "=rf")
1196         (match_operand:SF 1 "indexed_operand" "m"))]
1197   ""
1198   "*
1199 {
1200   if (FP_REG_P (operands[0]))
1201     return \"fld.l %1,%0\";
1202   return \"ld.l %1,%0\";
1203 }")
1204
1205 (define_insn ""
1206   [(set (match_operand:SI 0 "register_operand" "=rf")
1207         (match_operand:SI 1 "indexed_operand" "m"))]
1208   ""
1209   "*
1210 {
1211   if (FP_REG_P (operands[0]))
1212     return \"fld.l %1,%0\";
1213   return \"ld.l %1,%0\";
1214 }")
1215
1216 (define_insn ""
1217   [(set (match_operand:HI 0 "register_operand" "=r")
1218         (match_operand:HI 1 "indexed_operand" "m"))]
1219   ""
1220   "ld.s %1,%0")
1221
1222 (define_insn ""
1223   [(set (match_operand:QI 0 "register_operand" "=r")
1224         (match_operand:QI 1 "indexed_operand" "m"))]
1225   ""
1226   "ld.b %1,%0")
1227
1228 ;; Likewise for floating-point store insns.
1229
1230 (define_insn ""
1231   [(set (match_operand:DF 0 "indexed_operand" "=m")
1232         (match_operand:DF 1 "register_operand" "f"))]
1233   ""
1234   "fst.d %1,%0")
1235
1236 (define_insn ""
1237   [(set (match_operand:SF 0 "indexed_operand" "=m")
1238         (match_operand:SF 1 "register_operand" "f"))]
1239   ""
1240   "fst.l %1,%0")
1241 \f
1242 ;;- truncation instructions
1243 (define_insn "truncsiqi2"
1244   [(set (match_operand:QI 0 "general_operand" "=g")
1245         (truncate:QI
1246          (match_operand:SI 1 "register_operand" "r")))]
1247   ""
1248   "*
1249 {
1250   if (GET_CODE (operands[0]) == MEM)
1251   {
1252     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1253       {
1254         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1255                && (cc_prev_status.flags & CC_HI_R31_ADJ)
1256                && XEXP (operands[0], 0) == cc_prev_status.mdep))
1257           {
1258             CC_STATUS_INIT;
1259             cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1260             cc_status.mdep = XEXP (operands[0], 0);
1261             output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1262           }
1263         return \"st.b %1,%L0(%?r31)\";
1264       }
1265     else
1266       return \"st.b %1,%0\";
1267   }
1268   return \"shl %?r0,%1,%0\";
1269 }")
1270
1271 (define_insn "trunchiqi2"
1272   [(set (match_operand:QI 0 "general_operand" "=g")
1273         (truncate:QI
1274          (match_operand:HI 1 "register_operand" "r")))]
1275   ""
1276   "*
1277 {
1278   if (GET_CODE (operands[0]) == MEM)
1279   {
1280     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1281       {
1282         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1283                && (cc_prev_status.flags & CC_HI_R31_ADJ)
1284                && XEXP (operands[0], 0) == cc_prev_status.mdep))
1285           {
1286             CC_STATUS_INIT;
1287             cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1288             cc_status.mdep = XEXP (operands[0], 0);
1289             output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1290           }
1291         return \"st.b %1,%L0(%?r31)\";
1292       }
1293     else
1294       return \"st.b %1,%0\";
1295   }
1296   return \"shl %?r0,%1,%0\";
1297 }")
1298
1299 (define_insn "truncsihi2"
1300   [(set (match_operand:HI 0 "general_operand" "=g")
1301         (truncate:HI
1302          (match_operand:SI 1 "register_operand" "r")))]
1303   ""
1304   "*
1305 {
1306   if (GET_CODE (operands[0]) == MEM)
1307   {
1308     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1309       {
1310         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1311                && (cc_prev_status.flags & CC_HI_R31_ADJ)
1312                && XEXP (operands[0], 0) == cc_prev_status.mdep))
1313           {
1314             CC_STATUS_INIT;
1315             cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1316             cc_status.mdep = XEXP (operands[0], 0);
1317             output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1318           }
1319         return \"st.s %1,%L0(%?r31)\";
1320       }
1321     else
1322       return \"st.s %1,%0\";
1323   }
1324   return \"shl %?r0,%1,%0\";
1325 }")
1326 \f
1327 ;;- zero extension instructions
1328
1329 (define_insn "zero_extendhisi2"
1330   [(set (match_operand:SI 0 "register_operand" "=r")
1331         (zero_extend:SI
1332          (match_operand:HI 1 "register_operand" "r")))]
1333   ""
1334   "*
1335 {
1336   CC_STATUS_PARTIAL_INIT;
1337   return \"and 0xffff,%1,%0\";
1338 }")
1339
1340 (define_insn "zero_extendqihi2"
1341   [(set (match_operand:HI 0 "register_operand" "=r")
1342         (zero_extend:HI
1343          (match_operand:QI 1 "register_operand" "r")))]
1344   ""
1345   "*
1346 {
1347   CC_STATUS_PARTIAL_INIT;
1348   return \"and 0xff,%1,%0\";
1349 }")
1350
1351 (define_insn "zero_extendqisi2"
1352   [(set (match_operand:SI 0 "register_operand" "=r")
1353         (zero_extend:SI
1354          (match_operand:QI 1 "register_operand" "r")))]
1355   ""
1356   "*
1357 {
1358   CC_STATUS_PARTIAL_INIT;
1359   return \"and 0xff,%1,%0\";
1360 }")
1361 \f
1362 ;; Sign extension instructions.
1363
1364 (define_insn ""
1365   [(set (match_operand:SI 0 "register_operand" "=r")
1366         (sign_extend:SI
1367          (match_operand:HI 1 "indexed_operand" "m")))]
1368   ""
1369   "ld.s %1,%0")
1370
1371 (define_insn ""
1372   [(set (match_operand:HI 0 "register_operand" "=r")
1373         (sign_extend:HI
1374          (match_operand:QI 1 "indexed_operand" "m")))]
1375   ""
1376   "ld.b %1,%0")
1377
1378 (define_insn ""
1379   [(set (match_operand:SI 0 "register_operand" "=r")
1380         (sign_extend:SI
1381          (match_operand:QI 1 "indexed_operand" "m")))]
1382   ""
1383   "ld.b %1,%0")
1384
1385 (define_insn "extendhisi2"
1386   [(set (match_operand:SI 0 "register_operand" "=r")
1387         (sign_extend:SI
1388          (match_operand:HI 1 "nonimmediate_operand" "mr")))]
1389   ""
1390   "*
1391 {
1392   if (REG_P (operands[1]))
1393     return \"shl 16,%1,%0\;shra 16,%0,%0\";
1394   if (GET_CODE (operands[1]) == CONST_INT)
1395     abort ();
1396   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1397     {
1398       CC_STATUS_INIT;
1399       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1400       cc_status.mdep = XEXP (operands[1], 0);
1401       return \"orh %h1,%?r0,%?r31\;ld.s %L1(%?r31),%0\";
1402     }
1403   else
1404     return \"ld.s %1,%0\";
1405 }")
1406
1407 (define_insn "extendqihi2"
1408   [(set (match_operand:HI 0 "register_operand" "=r")
1409         (sign_extend:HI
1410          (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1411   ""
1412   "*
1413 {
1414   if (REG_P (operands[1]))
1415     return \"shl 24,%1,%0\;shra 24,%0,%0\";
1416   if (GET_CODE (operands[1]) == CONST_INT)
1417     abort ();
1418   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1419     {
1420       CC_STATUS_INIT;
1421       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1422       cc_status.mdep = XEXP (operands[1], 0);
1423       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1424     }
1425   else
1426     return \"ld.b %1,%0\";
1427 }")
1428
1429 (define_insn "extendqisi2"
1430   [(set (match_operand:SI 0 "register_operand" "=r")
1431         (sign_extend:SI
1432          (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1433   ""
1434   "*
1435 {
1436   if (REG_P (operands[1]))
1437     return \"shl 24,%1,%0\;shra 24,%0,%0\";
1438   if (GET_CODE (operands[1]) == CONST_INT)
1439     abort ();
1440   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1441     {
1442       CC_STATUS_INIT;
1443       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1444       cc_status.mdep = XEXP (operands[1], 0);
1445       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1446     }
1447   else
1448     return \"ld.b %1,%0\";
1449 }")
1450
1451 ;; Signed bitfield extractions come out looking like
1452 ;;      (shiftrt (sign_extend (shift <Y> <C1>)) <C2>)
1453 ;; which we expand poorly as four shift insns.
1454 ;; These patterns yield two shifts:
1455 ;;      (shiftrt (shift <Y> <C3>) <C4>)
1456 (define_insn ""
1457   [(set (match_operand:SI 0 "register_operand" "=r")
1458         (ashiftrt:SI
1459          (sign_extend:SI
1460           (match_operand:QI 1 "register_operand" "r"))
1461          (match_operand:SI 2 "logic_int" "n")))]
1462   "INTVAL (operands[2]) < 8"
1463   "*
1464 {
1465   return \"shl 24,%1,%0\;shra 24+%2,%0,%0\";
1466 }")
1467
1468 (define_insn ""
1469   [(set (match_operand:SI 0 "register_operand" "=r")
1470         (ashiftrt:SI
1471          (sign_extend:SI
1472           (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1473                                 (match_operand:SI 2 "logic_int" "n")) 0))
1474          (match_operand:SI 3 "logic_int" "n")))]
1475   "INTVAL (operands[3]) < 8"
1476   "*
1477 {
1478   return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1479 }")
1480
1481 (define_insn ""
1482   [(set (match_operand:SI 0 "register_operand" "=r")
1483         (ashiftrt:SI
1484          (sign_extend:SI
1485           (ashift:QI (match_operand:QI 1 "register_operand" "r")
1486                      (match_operand:QI 2 "logic_int" "n")))
1487          (match_operand:SI 3 "logic_int" "n")))]
1488   "INTVAL (operands[3]) < 8"
1489   "*
1490 {
1491   return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1492 }")
1493 \f
1494 ;; Special patterns for optimizing bit-field instructions.
1495
1496 ;; First two patterns are for bitfields that came from memory
1497 ;; testing only the high bit.  They work with old combiner.
1498
1499 (define_insn ""
1500   [(set (cc0)
1501         (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1502                                                     (const_int 7)) 0))
1503             (const_int 0)))]
1504   ""
1505   "*
1506 {
1507   CC_STATUS_PARTIAL_INIT;
1508   return \"and 128,%0,%?r0\";
1509 }")
1510
1511 (define_insn ""
1512   [(set (cc0)
1513         (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1514                                                     (const_int 7)) 0))
1515             (const_int 0)))]
1516   ""
1517   "*
1518 {
1519   CC_STATUS_PARTIAL_INIT;
1520   return \"and 128,%0,%?r0\";
1521 }")
1522
1523 ;; next two patterns are good for bitfields coming from memory
1524 ;; (via pseudo-register) or from a register, though this optimization
1525 ;; is only good for values contained wholly within the bottom 13 bits
1526 (define_insn ""
1527   [(set (cc0)
1528         (eq 
1529          (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1530                               (match_operand:SI 1 "logic_int" "n"))
1531                  (match_operand:SI 2 "logic_int" "n"))
1532          (const_int 0)))]
1533   "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1534   "*
1535 {
1536   CC_STATUS_PARTIAL_INIT;
1537   operands[2] = GEN_INT (INTVAL (operands[2]) << INTVAL (operands[1]));
1538   return \"and %2,%0,%?r0\";
1539 }")
1540
1541 (define_insn ""
1542   [(set (cc0)
1543         (eq 
1544          (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1545                               (match_operand:SI 1 "logic_int" "n"))
1546                  (match_operand:SI 2 "logic_int" "n"))
1547          (const_int 0)))]
1548   "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1549   "*
1550 {
1551   CC_STATUS_PARTIAL_INIT;
1552   operands[2] = GEN_INT (INTVAL (operands[2]) << INTVAL (operands[1]));
1553   return \"and %2,%0,%?r0\";
1554 }")
1555 \f
1556 ;; Conversions between float and double.
1557
1558 (define_insn "extendsfdf2"
1559   [(set (match_operand:DF 0 "register_operand" "=f")
1560         (float_extend:DF
1561          (match_operand:SF 1 "register_operand" "f")))]
1562   ""
1563   "fmov.sd %1,%0")
1564
1565 (define_insn "truncdfsf2"
1566   [(set (match_operand:SF 0 "register_operand" "=f")
1567         (float_truncate:SF
1568          (match_operand:DF 1 "register_operand" "f")))]
1569   ""
1570   "fmov.ds %1,%0")
1571 \f
1572 ;; Conversion between fixed point and floating point.
1573 ;; Note that among the fix-to-float insns
1574 ;; the ones that start with SImode come first.
1575 ;; That is so that an operand that is a CONST_INT
1576 ;; (and therefore lacks a specific machine mode).
1577 ;; will be recognized as SImode (which is always valid)
1578 ;; rather than as QImode or HImode.
1579
1580 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
1581 ;; to be reloaded by putting the constant into memory.
1582 ;; It must come before the more general floatsisf2 pattern.
1583 (define_expand "floatsidf2"
1584   [(set (match_dup 2) (match_dup 3))
1585    (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "")
1586                               (const_int -2147483648)))
1587    (set (match_dup 5) (match_dup 3))
1588    (set (subreg:SI (match_dup 5) 0) (match_dup 4))
1589    (set (match_operand:DF 0 "register_operand" "")
1590         (minus:DF (match_dup 5) (match_dup 2)))]
1591   ""
1592   "
1593 {
1594   REAL_VALUE_TYPE d;
1595   /* 4503601774854144 is  (1 << 30) * ((1 << 22) + (1 << 1)).  */
1596   d = REAL_VALUE_ATOF (\"4503601774854144\", DFmode);
1597   operands[2] = gen_reg_rtx (DFmode);
1598   operands[3] = CONST_DOUBLE_FROM_REAL_VALUE (d, DFmode);
1599   operands[4] = gen_reg_rtx (SImode);
1600   operands[5] = gen_reg_rtx (DFmode);
1601 }")
1602 \f
1603 ;; Floating to fixed conversion.
1604
1605 (define_expand "fix_truncdfsi2"
1606   ;; This first insn produces a double-word value
1607   ;; in which only the low word is valid.
1608   [(set (match_dup 2)
1609         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1610    (set (match_operand:SI 0 "register_operand" "=f")
1611         (subreg:SI (match_dup 2) 0))]
1612   ""
1613   "
1614 {
1615   operands[2] = gen_reg_rtx (DImode);
1616 }")
1617
1618 ;; Recognize the first insn generated above.
1619 ;; This RTL looks like a fix_truncdfdi2 insn,
1620 ;; but we don't call it that, because only 32 bits
1621 ;; of the result are valid.
1622 ;; This pattern will work for the intended purposes 
1623 ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2.
1624 (define_insn ""
1625   [(set (match_operand:DI 0 "register_operand" "=f")
1626         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1627   ""
1628   "ftrunc.dd %1,%0")
1629
1630 (define_expand "fix_truncsfsi2"
1631   ;; This first insn produces a double-word value
1632   ;; in which only the low word is valid.
1633   [(set (match_dup 2)
1634         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
1635    (set (match_operand:SI 0 "register_operand" "=f")
1636         (subreg:SI (match_dup 2) 0))]
1637   ""
1638   "
1639 {
1640   operands[2] = gen_reg_rtx (DImode);
1641 }")
1642
1643 ;; Recognize the first insn generated above.
1644 ;; This RTL looks like a fix_truncsfdi2 insn,
1645 ;; but we don't call it that, because only 32 bits
1646 ;; of the result are valid.
1647 ;; This pattern will work for the intended purposes 
1648 ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2.
1649 (define_insn ""
1650   [(set (match_operand:DI 0 "register_operand" "=f")
1651         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1652   ""
1653   "ftrunc.sd %1,%0")
1654 \f
1655 ;;- arithmetic instructions
1656
1657 (define_insn "addsi3"
1658   [(set (match_operand:SI 0 "register_operand" "=r,*f")
1659         (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f")
1660                  (match_operand:SI 2 "arith_operand" "rI,*f")))]
1661   ""
1662   "*
1663 {
1664   if (which_alternative == 1)
1665     return \"fiadd.ss %2,%1,%0\";
1666   CC_STATUS_PARTIAL_INIT;
1667   return \"addu %2,%1,%0\";
1668 }")
1669
1670 (define_insn "adddi3"
1671   [(set (match_operand:DI 0 "register_operand" "=f")
1672         (plus:DI (match_operand:DI 1 "register_operand" "%f")
1673                  (match_operand:DI 2 "register_operand" "f")))]
1674   ""
1675   "fiadd.dd %1,%2,%0")
1676
1677 (define_insn "subsi3"
1678   [(set (match_operand:SI 0 "register_operand" "=r,r,*f")
1679         (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f")
1680                   (match_operand:SI 2 "arith_operand" "rI,r,*f")))]
1681   ""
1682   "*
1683 {
1684   if (which_alternative == 2)
1685     return \"fisub.ss %1,%2,%0\";
1686   CC_STATUS_PARTIAL_INIT;
1687   if (REG_P (operands[2]))
1688     return \"subu %1,%2,%0\";
1689   operands[2] = GEN_INT (- INTVAL (operands[2]));
1690   return \"addu %2,%1,%0\";
1691 }")
1692
1693 (define_insn "subdi3"
1694   [(set (match_operand:DI 0 "register_operand" "=f")
1695         (minus:DI (match_operand:DI 1 "register_operand" "f")
1696                   (match_operand:DI 2 "register_operand" "f")))]
1697   ""
1698   "fisub.dd %1,%2,%0")
1699
1700 (define_expand "mulsi3"
1701   [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1702    (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1703    (clobber (match_dup 3))
1704    (set (subreg:SI (match_dup 3) 0)
1705         (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1706    (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1707   ""
1708   "
1709 {
1710   if (WORDS_BIG_ENDIAN)
1711     emit_insn (gen_mulsi3_big (operands[0], operands[1], operands[2]));
1712   else
1713     emit_insn (gen_mulsi3_little (operands[0], operands[1], operands[2]));
1714   DONE;
1715 }")
1716
1717 (define_expand "mulsi3_little"
1718   [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1719    (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1720    (clobber (match_dup 3))
1721    (set (subreg:SI (match_dup 3) 0)
1722         (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1723    (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1724   "! WORDS_BIG_ENDIAN"
1725   "
1726 {
1727   operands[3] = gen_reg_rtx (DImode);
1728   operands[4] = gen_reg_rtx (DImode);
1729   operands[5] = gen_reg_rtx (DImode);
1730 }")
1731
1732 (define_expand "mulsi3_big"
1733   [(set (subreg:SI (match_dup 4) 4) (match_operand:SI 1 "general_operand" ""))
1734    (set (subreg:SI (match_dup 5) 4) (match_operand:SI 2 "general_operand" ""))
1735    (clobber (match_dup 3))
1736    (set (subreg:SI (match_dup 3) 4)
1737         (mult:SI (subreg:SI (match_dup 4) 4) (subreg:SI (match_dup 5) 4)))
1738    (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 4))]
1739   "WORDS_BIG_ENDIAN"
1740   "
1741 {
1742   operands[3] = gen_reg_rtx (DImode);
1743   operands[4] = gen_reg_rtx (DImode);
1744   operands[5] = gen_reg_rtx (DImode);
1745 }")
1746
1747 (define_insn ""
1748   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
1749         (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
1750                  (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
1751   "! WORDS_BIG_ENDIAN"
1752   "fmlow.dd %2,%1,%0")
1753
1754 (define_insn ""
1755   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 4)
1756         (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 4)
1757                  (subreg:SI (match_operand:DI 2 "register_operand" "f") 4)))]
1758   "WORDS_BIG_ENDIAN"
1759   "fmlow.dd %2,%1,%0")
1760 \f
1761 ;;- and instructions (with compliment also)                        
1762 (define_insn "andsi3"
1763   [(set (match_operand:SI 0 "register_operand" "=r")
1764         (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1765                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1766   ""
1767   "*
1768 {
1769   rtx xop[3];
1770
1771   CC_STATUS_PARTIAL_INIT;
1772   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1773     return \"and %2,%1,%0\";
1774   if ((INTVAL (operands[2]) & 0xffff) == 0)
1775     {
1776       operands[2]
1777         = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1778       return \"andh %2,%1,%0\";
1779     }
1780   xop[0] = operands[0];
1781   xop[1] = operands[1];
1782   xop[2] = GEN_INT (~INTVAL (operands[2]) & 0xffff);
1783   output_asm_insn (\"andnot %2,%1,%0\", xop);
1784   operands[2] = GEN_INT (~(unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1785   return \"andnoth %2,%0,%0\";
1786 }")
1787
1788 (define_insn ""
1789   [(set (match_operand:SI 0 "register_operand" "=r")
1790         (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn"))
1791                 (match_operand:SI 2 "register_operand" "r")))]
1792   ""
1793   "*
1794 {
1795   rtx xop[3];
1796
1797   CC_STATUS_PARTIAL_INIT;
1798   if (REG_P (operands[1]) || LOGIC_INT (operands[1]))
1799     return \"andnot %1,%2,%0\";
1800   if ((INTVAL (operands[1]) & 0xffff) == 0)
1801     {
1802       operands[1]
1803         = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[1]) >> 16);
1804       return \"andnoth %1,%2,%0\";
1805     }
1806   xop[0] = operands[0];
1807   xop[1] = GEN_INT (INTVAL (operands[1]) & 0xffff);
1808   xop[2] = operands[2];
1809   output_asm_insn (\"andnot %1,%2,%0\", xop);
1810   operands[1] = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[1]) >> 16);
1811   return \"andnoth %1,%0,%0\";
1812 }")
1813
1814 (define_insn "iorsi3"
1815   [(set (match_operand:SI 0 "register_operand" "=r")
1816         (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1817                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1818   ""
1819   "*
1820 {
1821   rtx xop[3];
1822
1823   CC_STATUS_PARTIAL_INIT;
1824   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1825     return \"or %2,%1,%0\";
1826   if ((INTVAL (operands[2]) & 0xffff) == 0)
1827     {
1828       operands[2]
1829         = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1830       return \"orh %2,%1,%0\";
1831     }
1832   xop[0] = operands[0];
1833   xop[1] = operands[1];
1834   xop[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1835   output_asm_insn (\"or %2,%1,%0\", xop);
1836   operands[2] = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1837   return \"orh %2,%0,%0\";
1838 }")
1839
1840 (define_insn "xorsi3"
1841   [(set (match_operand:SI 0 "register_operand" "=r")
1842         (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1843                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1844   ""
1845   "*
1846 {
1847   rtx xop[3];
1848
1849   CC_STATUS_PARTIAL_INIT;
1850   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1851     return \"xor %2,%1,%0\";
1852   if ((INTVAL (operands[2]) & 0xffff) == 0)
1853     {
1854       operands[2]
1855         = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1856       return \"xorh %2,%1,%0\";
1857     }
1858   xop[0] = operands[0];
1859   xop[1] = operands[1];
1860   xop[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1861   output_asm_insn (\"xor %2,%1,%0\", xop);
1862   operands[2] = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1863   return \"xorh %2,%0,%0\";
1864 }")
1865
1866 ;(The i860 instruction set doesn't allow an immediate second operand in
1867 ; a subtraction.)
1868 (define_insn "negsi2"
1869   [(set (match_operand:SI 0 "general_operand" "=r")
1870         (neg:SI (match_operand:SI 1 "arith_operand" "r")))]
1871   ""
1872   "*
1873 {
1874   CC_STATUS_PARTIAL_INIT;
1875   return \"subu %?r0,%1,%0\";
1876 }")
1877
1878 (define_insn "one_cmplsi2"
1879   [(set (match_operand:SI 0 "general_operand" "=r")
1880         (not:SI (match_operand:SI 1 "arith_operand" "r")))]
1881   ""
1882   "*
1883 {
1884   CC_STATUS_PARTIAL_INIT;
1885   return \"subu -1,%1,%0\";
1886 }")
1887 \f
1888 ;; Floating point arithmetic instructions.
1889
1890 (define_insn "adddf3"
1891   [(set (match_operand:DF 0 "register_operand" "=f")
1892         (plus:DF (match_operand:DF 1 "register_operand" "f")
1893                  (match_operand:DF 2 "register_operand" "f")))]
1894   ""
1895   "fadd.dd %1,%2,%0")
1896
1897 (define_insn "addsf3"
1898   [(set (match_operand:SF 0 "register_operand" "=f")
1899         (plus:SF (match_operand:SF 1 "register_operand" "f")
1900                  (match_operand:SF 2 "register_operand" "f")))]
1901   ""
1902   "fadd.ss %1,%2,%0")
1903
1904 (define_insn "subdf3"
1905   [(set (match_operand:DF 0 "register_operand" "=f")
1906         (minus:DF (match_operand:DF 1 "register_operand" "f")
1907                   (match_operand:DF 2 "register_operand" "f")))]
1908   ""
1909   "fsub.dd %1,%2,%0")
1910
1911 (define_insn "subsf3"
1912   [(set (match_operand:SF 0 "register_operand" "=f")
1913         (minus:SF (match_operand:SF 1 "register_operand" "f")
1914                   (match_operand:SF 2 "register_operand" "f")))]
1915   ""
1916   "fsub.ss %1,%2,%0")
1917
1918 (define_insn "muldf3"
1919   [(set (match_operand:DF 0 "register_operand" "=f")
1920         (mult:DF (match_operand:DF 1 "register_operand" "f")
1921                  (match_operand:DF 2 "register_operand" "f")))]
1922   ""
1923   "fmul.dd %1,%2,%0")
1924
1925 (define_insn "mulsf3"
1926   [(set (match_operand:SF 0 "register_operand" "=f")
1927         (mult:SF (match_operand:SF 1 "register_operand" "f")
1928                  (match_operand:SF 2 "register_operand" "f")))]
1929   ""
1930   "fmul.ss %1,%2,%0")
1931
1932 (define_insn "negdf2"
1933   [(set (match_operand:DF 0 "register_operand" "=f")
1934         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1935   ""
1936   "fsub.dd %?f0,%1,%0")
1937
1938 (define_insn "negsf2"
1939   [(set (match_operand:SF 0 "register_operand" "=f")
1940         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1941   ""
1942   "fsub.ss %?f0,%1,%0")
1943 \f
1944 (define_insn "divdf3"
1945   [(set (match_operand:DF 0 "register_operand" "=&f")
1946         (div:DF (match_operand:DF 1 "register_operand" "f")
1947                  (match_operand:DF 2 "register_operand" "f")))
1948    (clobber (match_scratch:DF 3 "=&f"))
1949    (clobber (match_scratch:DF 4 "=&f"))]
1950   ""
1951   "*
1952 {
1953   CC_STATUS_PARTIAL_INIT;
1954   if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1955       || (cc_prev_status.flags & CC_HI_R31_ADJ)
1956       || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1957     {
1958       cc_status.flags |= CC_KNOW_HI_R31;
1959       cc_status.flags &= ~CC_HI_R31_ADJ;
1960       cc_status.mdep = CONST2_RTX (SFmode); 
1961       return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\
1962 orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\
1963 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\
1964 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\
1965 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1966     }
1967   else
1968     return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\
1969 ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\
1970 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\
1971 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\
1972 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1973 }")
1974
1975 (define_insn "divsf3"
1976   [(set (match_operand:SF 0 "register_operand" "=&f")
1977         (div:SF (match_operand:SF 1 "register_operand" "f")
1978                  (match_operand:SF 2 "register_operand" "f")))
1979    (clobber (match_scratch:SF 3 "=&f"))
1980    (clobber (match_scratch:SF 4 "=&f"))]
1981   ""
1982   "*
1983 {
1984   CC_STATUS_PARTIAL_INIT;
1985   if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1986       || (cc_prev_status.flags & CC_HI_R31_ADJ)
1987       || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1988     {
1989       cc_status.flags |= CC_KNOW_HI_R31;
1990       cc_status.flags &= ~CC_HI_R31_ADJ;
1991       cc_status.mdep = CONST2_RTX (SFmode);
1992       output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands);
1993     }
1994   return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\
1995 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\
1996 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\
1997 fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\";
1998 }")
1999 \f
2000 ;; Shift instructions
2001
2002 ;; Optimized special case of shifting.
2003 ;; Must precede the general case.
2004
2005 (define_insn ""
2006   [(set (match_operand:SI 0 "register_operand" "=r")
2007         (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2008                      (const_int 24)))]
2009   ""
2010   "*
2011 {
2012   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
2013     {
2014       CC_STATUS_INIT;
2015       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
2016       cc_status.mdep = XEXP (operands[1], 0);
2017       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
2018     }
2019   return \"ld.b %1,%0\";
2020 }")
2021
2022 \f
2023 ;;- arithmetic shift instructions
2024 (define_insn "ashlsi3"
2025   [(set (match_operand:SI 0 "register_operand" "=r")
2026         (ashift:SI (match_operand:SI 1 "register_operand" "r")
2027                    (match_operand:SI 2 "shift_operand" "rn")))]
2028   ""
2029   "*
2030 {
2031   return \"shl %2,%1,%0\";
2032 }")
2033
2034 (define_insn "ashlhi3"
2035   [(set (match_operand:HI 0 "register_operand" "=r")
2036         (ashift:HI (match_operand:HI 1 "register_operand" "r")
2037                    (match_operand:HI 2 "shift_operand" "rn")))]
2038   ""
2039   "*
2040 {
2041   return \"shl %2,%1,%0\";
2042 }")
2043
2044 (define_insn "ashlqi3"
2045   [(set (match_operand:QI 0 "register_operand" "=r")
2046         (ashift:QI (match_operand:QI 1 "register_operand" "r")
2047                    (match_operand:QI 2 "shift_operand" "rn")))]
2048   ""
2049   "*
2050 {
2051   return \"shl %2,%1,%0\";
2052 }")
2053
2054 (define_insn "ashrsi3"
2055   [(set (match_operand:SI 0 "register_operand" "=r")
2056         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2057                      (match_operand:SI 2 "shift_operand" "rn")))]
2058   ""
2059   "*
2060 {
2061   return \"shra %2,%1,%0\";
2062 }")
2063
2064 (define_insn "lshrsi3"
2065   [(set (match_operand:SI 0 "register_operand" "=r")
2066         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2067                      (match_operand:SI 2 "shift_operand" "rn")))]
2068   ""
2069   "*
2070 {
2071   return \"shr %2,%1,%0\";
2072 }")
2073 \f
2074 ;; Unconditional and other jump instructions
2075
2076 (define_insn "jump"
2077   [(set (pc) (label_ref (match_operand 0 "" "")))]
2078   ""
2079   "*
2080 {
2081   return \"br %l0\;nop\";
2082 }")
2083
2084 ;; Here are two simple peepholes which fill the delay slot of
2085 ;; an unconditional branch.
2086 ;
2087 ;; ??? All disabled, because output_delayed_branch is a crock
2088 ;; that will reliably segfault.  This should be using the dbr
2089 ;; pass in any case.  Anyone who cares is welcome to fix it.
2090 ;
2091 ;(define_peephole
2092 ;  [(set (match_operand:SI 0 "register_operand" "=rf")
2093 ;       (match_operand:SI 1 "single_insn_src_p" "gfG"))
2094 ;   (set (pc) (label_ref (match_operand 2 "" "")))]
2095 ;  ""
2096 ;  "* return output_delayed_branch (\"br %l2\", operands, insn);")
2097 ;
2098 ;(define_peephole
2099 ;  [(set (match_operand:SI 0 "memory_operand" "=m")
2100 ;       (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2101 ;   (set (pc) (label_ref (match_operand 2 "" "")))]
2102 ;  ""
2103 ;  "* return output_delayed_branch (\"br %l2\", operands, insn);")
2104
2105 (define_insn "tablejump"
2106   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2107    (use (label_ref (match_operand 1 "" "")))]
2108   ""
2109   "bri %0\;nop")
2110
2111 ;(define_peephole
2112 ;  [(set (match_operand:SI 0 "memory_operand" "=m")
2113 ;       (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2114 ;   (set (pc) (match_operand:SI 2 "register_operand" "r"))
2115 ;   (use (label_ref (match_operand 3 "" "")))]
2116 ;  ""
2117 ;  "* return output_delayed_branch (\"bri %2\", operands, insn);")
2118
2119 ;;- jump to subroutine
2120 (define_expand "call"
2121   [(call (match_operand:SI 0 "memory_operand" "m")
2122          (match_operand 1 "" "i"))]
2123   ;; operand[2] is next_arg_register
2124   ""
2125   "
2126 {
2127   /* Make sure the address is just one reg and will stay that way.  */
2128   if (! call_insn_operand (operands[0], QImode))
2129     operands[0]
2130       = replace_equiv_address (operands[0],
2131                                copy_to_mode_reg (Pmode,
2132                                                  XEXP (operands[0], 0)));
2133   if (INTVAL (operands[1]) > 0)
2134     {
2135       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2136       emit_insn (gen_rtx_USE (VOIDmode, arg_pointer_rtx));
2137     }
2138 }")
2139
2140 ;;- jump to subroutine
2141 (define_insn ""
2142   [(call (match_operand:SI 0 "call_insn_operand" "m")
2143          (match_operand 1 "" "i"))]
2144   ;; operand[2] is next_arg_register
2145   ""
2146   "*
2147 {
2148   /* strip the MEM.  */
2149   operands[0] = XEXP (operands[0], 0);
2150   CC_STATUS_INIT;
2151   if (GET_CODE (operands[0]) == REG)
2152     return \"calli %0\;nop\";
2153   return \"call %0\;nop\";
2154 }")
2155
2156 ;(define_peephole
2157 ;  [(set (match_operand:SI 0 "register_operand" "=rf")
2158 ;       (match_operand:SI 1 "single_insn_src_p" "gfG"))
2159 ;   (call (match_operand:SI 2 "memory_operand" "m")
2160 ;        (match_operand 3 "" "i"))]
2161 ;  ;;- Don't use operand 1 for most machines.
2162 ;  "! reg_mentioned_p (operands[0], operands[2])"
2163 ;  "*
2164 ;{
2165 ;  /* strip the MEM.  */
2166 ;  operands[2] = XEXP (operands[2], 0);
2167 ;  if (GET_CODE (operands[2]) == REG)
2168 ;    return output_delayed_branch (\"calli %2\", operands, insn);
2169 ;  return output_delayed_branch (\"call %2\", operands, insn);
2170 ;}")
2171
2172 ;(define_peephole
2173 ;  [(set (match_operand:SI 0 "memory_operand" "=m")
2174 ;       (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2175 ;   (call (match_operand:SI 2 "call_insn_operand" "m")
2176 ;        (match_operand 3 "" "i"))]
2177 ;  ;;- Don't use operand 1 for most machines.
2178 ;  ""
2179 ;  "*
2180 ;{
2181 ;  /* strip the MEM.  */
2182 ;  operands[2] = XEXP (operands[2], 0);
2183 ;  if (GET_CODE (operands[2]) == REG)
2184 ;    return output_delayed_branch (\"calli %2\", operands, insn);
2185 ;  return output_delayed_branch (\"call %2\", operands, insn);
2186 ;}")
2187
2188 (define_expand "call_value"
2189   [(set (match_operand 0 "register_operand" "=rf")
2190         (call (match_operand:SI 1 "memory_operand" "m")
2191               (match_operand 2 "" "i")))]
2192   ;; operand 3 is next_arg_register
2193   ""
2194   "
2195 {
2196   /* Make sure the address is just one reg and will stay that way.  */
2197   if (! call_insn_operand (operands[1], QImode))
2198     operands[1]
2199       = replace_equiv_address (operands[1],
2200                                copy_to_mode_reg (Pmode,
2201                                                  XEXP (operands[1], 0)));
2202   if (INTVAL (operands[2]) > 0)
2203     {
2204       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2205       emit_insn (gen_rtx_USE (VOIDmode, arg_pointer_rtx));
2206     }
2207 }")
2208
2209 (define_insn ""
2210   [(set (match_operand 0 "register_operand" "=rf")
2211         (call (match_operand:SI 1 "call_insn_operand" "m")
2212               (match_operand 2 "" "i")))]
2213   ;; operand 3 is next_arg_register
2214   ""
2215   "*
2216 {
2217   /* strip the MEM.  */
2218   operands[1] = XEXP (operands[1], 0);
2219   CC_STATUS_INIT;
2220   if (GET_CODE (operands[1]) == REG)
2221     return \"calli %1\;nop\";
2222   return \"call %1\;nop\";
2223 }")
2224
2225 ;(define_peephole
2226 ;  [(set (match_operand:SI 0 "register_operand" "=rf")
2227 ;       (match_operand:SI 1 "single_insn_src_p" "gfG"))
2228 ;   (set (match_operand 2 "" "=rf")
2229 ;       (call (match_operand:SI 3 "call_insn_operand" "m")
2230 ;             (match_operand 4 "" "i")))]
2231 ;  ;;- Don't use operand 4 for most machines.
2232 ;  "! reg_mentioned_p (operands[0], operands[3])"
2233 ;  "*
2234 ;{
2235 ;  /* strip the MEM.  */
2236 ;  operands[3] = XEXP (operands[3], 0);
2237 ;  if (GET_CODE (operands[3]) == REG)
2238 ;    return output_delayed_branch (\"calli %3\", operands, insn);
2239 ;  return output_delayed_branch (\"call %3\", operands, insn);
2240 ;}")
2241
2242 ;(define_peephole
2243 ;  [(set (match_operand:SI 0 "memory_operand" "=m")
2244 ;       (match_operand:SI 1 "reg_or_0_operand" "rJf"))
2245 ;   (set (match_operand 2 "" "=rf")
2246 ;       (call (match_operand:SI 3 "call_insn_operand" "m")
2247 ;             (match_operand 4 "" "i")))]
2248 ;  ;;- Don't use operand 4 for most machines.
2249 ;  ""
2250 ;  "*
2251 ;{
2252 ;  /* strip the MEM.  */
2253 ;  operands[3] = XEXP (operands[3], 0);
2254 ;  if (GET_CODE (operands[3]) == REG)
2255 ;    return output_delayed_branch (\"calli %3\", operands, insn);
2256 ;  return output_delayed_branch (\"call %3\", operands, insn);
2257 ;}")
2258
2259 ;; Call subroutine returning any type.
2260
2261 (define_expand "untyped_call"
2262   [(parallel [(call (match_operand 0 "" "")
2263                     (const_int 0))
2264               (match_operand 1 "" "")
2265               (match_operand 2 "" "")])]
2266   ""
2267   "
2268 {
2269   int i;
2270
2271   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
2272
2273   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2274     {
2275       rtx set = XVECEXP (operands[2], 0, i);
2276       emit_move_insn (SET_DEST (set), SET_SRC (set));
2277     }
2278
2279   /* The optimizer does not know that the call sets the function value
2280      registers we stored in the result block.  We avoid problems by
2281      claiming that all hard registers are used and clobbered at this
2282      point.  */
2283   emit_insn (gen_blockage ());
2284
2285   DONE;
2286 }")
2287
2288 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2289 ;; all of memory.  This blocks insns from being moved across this point.
2290
2291 (define_insn "blockage"
2292   [(unspec_volatile [(const_int 0)] 0)]
2293   ""
2294   "")
2295 \f
2296 (define_insn "nop"
2297   [(const_int 0)]
2298   ""
2299   "nop")
2300
2301 (define_insn "indirect_jump"
2302   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2303   ""
2304   "bri %0")
2305 \f
2306 ;;
2307 ;; A special insn that does the work to get setup just
2308 ;; before a table jump.
2309 ;;
2310 (define_insn ""
2311   [(set (match_operand:SI 0 "register_operand" "=r")
2312         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2313                          (label_ref (match_operand 2 "" "")))))]
2314   ""
2315   "*
2316 {
2317   CC_STATUS_INIT;
2318   return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\";
2319 }")
2320   
2321 ;(define_peephole
2322 ;  [(set (match_operand:SI 0 "register_operand" "=rf")
2323 ;       (match_operand:SI 1 "single_insn_src_p" "gfG"))
2324 ;   (set (pc) (match_operand:SI 2 "register_operand" "r"))
2325 ;   (use (label_ref (match_operand 3 "" "")))]
2326 ;  "REGNO (operands[0]) != REGNO (operands[2])"
2327 ;  "* return output_delayed_branch (\"bri %2\", operands, insn);")