OSDN Git Service

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