OSDN Git Service

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