OSDN Git Service

(QI and HI bte/btne patterns): Deleted.
[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 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, 675 Mass Ave, Cambridge, MA 02139, USA.
19
20
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
24 ;;- updates for most instructions.
25
26 ;;- Operand classes for the register allocator:
27 \f
28 /* Bit-test instructions.  */
29
30 (define_insn ""
31   [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
32                           (match_operand:SI 1 "logic_operand" "rL"))
33                   (const_int 0)))]
34   ""
35   "*
36 {
37   CC_STATUS_PARTIAL_INIT;
38   return \"and %1,%0,%?r0\";
39 }")
40
41 (define_insn ""
42   [(set (cc0) (ne (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   cc_status.flags |= CC_NEGATED;
50   return \"and %1,%0,%?r0\";
51 }")
52
53 (define_insn ""
54   [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
55                           (match_operand:SI 1 "immediate_operand" "i"))
56                   (const_int 0)))]
57   "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
58   "*
59 {
60   CC_STATUS_PARTIAL_INIT;
61   return \"andh %H1,%0,%?r0\";
62 }")
63
64 (define_insn ""
65   [(set (cc0) (ne (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   cc_status.flags |= CC_NEGATED;
73   return \"andh %H1,%0,%?r0\";
74 }")
75
76 (define_insn ""
77   [(set (cc0) (eq (ashiftrt:SI
78                    (sign_extend:SI
79                     (ashift:QI (match_operand:QI 0 "register_operand" "r")
80                                (match_operand:QI 1 "logic_int" "n")))
81                    (match_operand:SI 2 "logic_int" "n"))
82                   (const_int 0)))]
83   ""
84   "*
85 {
86   int width = 8 - INTVAL (operands[2]);
87   int pos = 8 - width - INTVAL (operands[1]);
88
89   CC_STATUS_PARTIAL_INIT;
90   operands[2] = gen_rtx (CONST_INT, VOIDmode,
91                          ~((-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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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 (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1007                    (mem:BLK (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 0))
1014               (clobber (match_dup 1))])]
1015   ""
1016   "
1017 {
1018   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1019   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1020   operands[4] = gen_reg_rtx (SImode);
1021   operands[5] = gen_reg_rtx (SImode);
1022   operands[6] = gen_reg_rtx (SImode);
1023 }")
1024
1025 (define_insn ""
1026   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
1027         (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1028    (use (match_operand:SI 2 "general_operand" "rn"))
1029    (use (match_operand:SI 3 "immediate_operand" "i"))
1030    (clobber (match_operand:SI 4 "register_operand" "=r"))
1031    (clobber (match_operand:SI 5 "register_operand" "=r"))
1032    (clobber (match_operand:SI 6 "register_operand" "=r"))
1033    (clobber (match_dup 0))
1034    (clobber (match_dup 1))]
1035   ""
1036   "* return output_block_move (operands);")
1037 \f
1038 ;; Floating point move insns
1039
1040 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1041 ;; to be reloaded by putting the constant into memory.
1042 ;; It must come before the more general movdf pattern.
1043 (define_insn ""
1044   [(set (match_operand:DF 0 "general_operand" "=r,f,o")
1045         (match_operand:DF 1 "" "mG,m,G"))]
1046   "GET_CODE (operands[1]) == CONST_DOUBLE"
1047   "*
1048 {
1049   if (FP_REG_P (operands[0]) || operands[1] == CONST0_RTX (DFmode))
1050     return output_fp_move_double (operands);
1051   return output_move_double (operands);
1052 }")
1053
1054 (define_insn "movdf"
1055   [(set (match_operand:DF 0 "general_operand" "=*rm,&*r,?f,?*rm")
1056         (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))]
1057   ""
1058   "*
1059 {
1060   if (GET_CODE (operands[0]) == MEM
1061       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1062     return output_store (operands);
1063   if (GET_CODE (operands[1]) == MEM
1064       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1065     return output_load (operands);
1066
1067   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1068     return output_fp_move_double (operands);
1069   return output_move_double (operands);
1070 }")
1071
1072 (define_insn "movdi"
1073   [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm")
1074         (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))]
1075   ""
1076   "*
1077 {
1078   if (GET_CODE (operands[0]) == MEM
1079       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1080     return output_store (operands);
1081   if (GET_CODE (operands[1]) == MEM
1082       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1083     return output_load (operands);
1084
1085   /* ??? How can we have a DFmode arg here with DImode above? */
1086   if (FP_REG_P (operands[0]) && operands[1] == CONST0_RTX (DFmode))
1087     return \"fmov.dd %?f0,%0\";
1088
1089   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1090     return output_fp_move_double (operands);
1091   return output_move_double (operands);
1092 }")
1093
1094 ;; The alternative m/r is separate from m/f
1095 ;; The first alternative is separate from the second for the same reason.
1096 (define_insn "movsf"
1097   [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m")
1098         (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))]
1099   ""
1100   "*
1101 {
1102   if (GET_CODE (operands[0]) == MEM
1103       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1104     return output_store (operands);
1105   if (GET_CODE (operands[1]) == MEM
1106       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1107     return output_load (operands);
1108   if (FP_REG_P (operands[0]))
1109     {
1110       if (FP_REG_P (operands[1]))
1111         return \"fmov.ss %1,%0\";
1112       if (GET_CODE (operands[1]) == REG)
1113         return \"ixfr %1,%0\";
1114       if (operands[1] == CONST0_RTX (SFmode))
1115         return \"fmov.ss %?f0,%0\";
1116       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1117         {
1118           if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1119                  && (cc_prev_status.flags & CC_HI_R31_ADJ)
1120                  && cc_prev_status.mdep == XEXP(operands[1],0)))
1121             {
1122               CC_STATUS_INIT;
1123               cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1124               cc_status.mdep = XEXP (operands[1], 0);
1125               return \"orh %h1,%?r0,%?r31\;fld.l %L1(%?r31),%0\";
1126             }
1127           return \"fld.l %L1(%?r31),%0\";
1128         }
1129       return \"fld.l %1,%0\";
1130     }
1131   if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
1132     {
1133       if (GET_CODE (operands[0]) == REG && FP_REG_P (operands[1]))
1134         return \"fxfr %1,%0\";
1135       if (GET_CODE (operands[0]) == REG)
1136         {
1137           CC_STATUS_PARTIAL_INIT;
1138           if (GET_CODE (operands[1]) == CONST_DOUBLE)
1139             {
1140               register unsigned long ul;
1141
1142               ul = sfmode_constant_to_ulong (operands[1]);
1143               if ((ul & 0x0000ffff) == 0)
1144                 return \"orh %H1,%?r0,%0\";
1145               if ((ul & 0xffff0000) == 0)
1146                 return \"or %L1,%?r0,%0\";
1147             }
1148           return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
1149         }
1150       /* Now operand 0 must be memory.
1151          If operand 1 is CONST_DOUBLE, its value must be 0.  */
1152       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1153         {
1154           if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1155                  && (cc_prev_status.flags & CC_HI_R31_ADJ)
1156                  && XEXP (operands[0], 0) == cc_prev_status.mdep))
1157             {
1158               CC_STATUS_INIT;
1159               cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1160               cc_status.mdep = XEXP (operands[0], 0);
1161               output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1162             }
1163           return \"fst.l %r1,%L0(%?r31)\";
1164         }
1165       return \"fst.l %r1,%0\";
1166     }
1167   if (GET_CODE (operands[0]) == MEM)
1168     return \"st.l %r1,%0\";
1169   if (GET_CODE (operands[1]) == MEM)
1170     return \"ld.l %1,%0\";
1171   if (operands[1] == CONST0_RTX (SFmode))
1172     return \"shl %?r0,%?r0,%0\";
1173   return \"mov %1,%0\";
1174 }")
1175 \f
1176 ;; Special load insns for REG+REG addresses.
1177 ;; Such addresses are not "legitimate" because st rejects them.
1178
1179 (define_insn ""
1180   [(set (match_operand:DF 0 "register_operand" "=rf")
1181         (match_operand:DF 1 "indexed_operand" "m"))]
1182   ""
1183   "*
1184 {
1185   if (FP_REG_P (operands[0]))
1186     return output_fp_move_double (operands);
1187   return output_move_double (operands);
1188 }")
1189
1190 (define_insn ""
1191   [(set (match_operand:SF 0 "register_operand" "=rf")
1192         (match_operand:SF 1 "indexed_operand" "m"))]
1193   ""
1194   "*
1195 {
1196   if (FP_REG_P (operands[0]))
1197     return \"fld.l %1,%0\";
1198   return \"ld.l %1,%0\";
1199 }")
1200
1201 (define_insn ""
1202   [(set (match_operand:SI 0 "register_operand" "=rf")
1203         (match_operand:SI 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:HI 0 "register_operand" "=r")
1214         (match_operand:HI 1 "indexed_operand" "m"))]
1215   ""
1216   "ld.s %1,%0")
1217
1218 (define_insn ""
1219   [(set (match_operand:QI 0 "register_operand" "=r")
1220         (match_operand:QI 1 "indexed_operand" "m"))]
1221   ""
1222   "ld.b %1,%0")
1223
1224 ;; Likewise for floating-point store insns.
1225
1226 (define_insn ""
1227   [(set (match_operand:DF 0 "indexed_operand" "=m")
1228         (match_operand:DF 1 "register_operand" "f"))]
1229   ""
1230   "fst.d %1,%0")
1231
1232 (define_insn ""
1233   [(set (match_operand:SF 0 "indexed_operand" "=m")
1234         (match_operand:SF 1 "register_operand" "f"))]
1235   ""
1236   "fst.l %1,%0")
1237 \f
1238 ;;- truncation instructions
1239 (define_insn "truncsiqi2"
1240   [(set (match_operand:QI 0 "general_operand" "=g")
1241         (truncate:QI
1242          (match_operand:SI 1 "register_operand" "r")))]
1243   ""
1244   "*
1245 {
1246   if (GET_CODE (operands[0]) == MEM)
1247     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1248       {
1249         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1250                && (cc_prev_status.flags & CC_HI_R31_ADJ)
1251                && XEXP (operands[0], 0) == cc_prev_status.mdep))
1252           {
1253             CC_STATUS_INIT;
1254             cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1255             cc_status.mdep = XEXP (operands[0], 0);
1256             output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1257           }
1258         return \"st.b %1,%L0(%?r31)\";
1259       }
1260     else
1261       return \"st.b %1,%0\";
1262   return \"shl %?r0,%1,%0\";
1263 }")
1264
1265 (define_insn "trunchiqi2"
1266   [(set (match_operand:QI 0 "general_operand" "=g")
1267         (truncate:QI
1268          (match_operand:HI 1 "register_operand" "r")))]
1269   ""
1270   "*
1271 {
1272   if (GET_CODE (operands[0]) == MEM)
1273     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1274       {
1275         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1276                && (cc_prev_status.flags & CC_HI_R31_ADJ)
1277                && XEXP (operands[0], 0) == cc_prev_status.mdep))
1278           {
1279             CC_STATUS_INIT;
1280             cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1281             cc_status.mdep = XEXP (operands[0], 0);
1282             output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1283           }
1284         return \"st.b %1,%L0(%?r31)\";
1285       }
1286     else
1287       return \"st.b %1,%0\";
1288   return \"shl %?r0,%1,%0\";
1289 }")
1290
1291 (define_insn "truncsihi2"
1292   [(set (match_operand:HI 0 "general_operand" "=g")
1293         (truncate:HI
1294          (match_operand:SI 1 "register_operand" "r")))]
1295   ""
1296   "*
1297 {
1298   if (GET_CODE (operands[0]) == MEM)
1299     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1300       {
1301         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1302                && (cc_prev_status.flags & CC_HI_R31_ADJ)
1303                && XEXP (operands[0], 0) == cc_prev_status.mdep))
1304           {
1305             CC_STATUS_INIT;
1306             cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1307             cc_status.mdep = XEXP (operands[0], 0);
1308             output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1309           }
1310         return \"st.s %1,%L0(%?r31)\";
1311       }
1312     else
1313       return \"st.s %1,%0\";
1314   return \"shl %?r0,%1,%0\";
1315 }")
1316 \f
1317 ;;- zero extension instructions
1318
1319 (define_insn "zero_extendhisi2"
1320   [(set (match_operand:SI 0 "register_operand" "=r")
1321         (zero_extend:SI
1322          (match_operand:HI 1 "register_operand" "r")))]
1323   ""
1324   "*
1325 {
1326   CC_STATUS_PARTIAL_INIT;
1327   return \"and 0xffff,%1,%0\";
1328 }")
1329
1330 (define_insn "zero_extendqihi2"
1331   [(set (match_operand:HI 0 "register_operand" "=r")
1332         (zero_extend:HI
1333          (match_operand:QI 1 "register_operand" "r")))]
1334   ""
1335   "*
1336 {
1337   CC_STATUS_PARTIAL_INIT;
1338   return \"and 0xff,%1,%0\";
1339 }")
1340
1341 (define_insn "zero_extendqisi2"
1342   [(set (match_operand:SI 0 "register_operand" "=r")
1343         (zero_extend:SI
1344          (match_operand:QI 1 "register_operand" "r")))]
1345   ""
1346   "*
1347 {
1348   CC_STATUS_PARTIAL_INIT;
1349   return \"and 0xff,%1,%0\";
1350 }")
1351 \f
1352 ;; Sign extension instructions.
1353
1354 (define_insn ""
1355   [(set (match_operand:SI 0 "register_operand" "=r")
1356         (sign_extend:SI
1357          (match_operand:HI 1 "indexed_operand" "m")))]
1358   ""
1359   "ld.s %1,%0")
1360
1361 (define_insn ""
1362   [(set (match_operand:HI 0 "register_operand" "=r")
1363         (sign_extend:HI
1364          (match_operand:QI 1 "indexed_operand" "m")))]
1365   ""
1366   "ld.b %1,%0")
1367
1368 (define_insn ""
1369   [(set (match_operand:SI 0 "register_operand" "=r")
1370         (sign_extend:SI
1371          (match_operand:QI 1 "indexed_operand" "m")))]
1372   ""
1373   "ld.b %1,%0")
1374
1375 (define_insn "extendhisi2"
1376   [(set (match_operand:SI 0 "register_operand" "=r")
1377         (sign_extend:SI
1378          (match_operand:HI 1 "nonimmediate_operand" "mr")))]
1379   ""
1380   "*
1381 {
1382   if (REG_P (operands[1]))
1383     return \"shl 16,%1,%0\;shra 16,%0,%0\";
1384   if (GET_CODE (operands[1]) == CONST_INT)
1385     abort ();
1386   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1387     {
1388       CC_STATUS_INIT;
1389       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1390       cc_status.mdep = XEXP (operands[1], 0);
1391       return \"orh %h1,%?r0,%?r31\;ld.s %L1(%?r31),%0\";
1392     }
1393   else
1394     return \"ld.s %1,%0\";
1395 }")
1396
1397 (define_insn "extendqihi2"
1398   [(set (match_operand:HI 0 "register_operand" "=r")
1399         (sign_extend:HI
1400          (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1401   ""
1402   "*
1403 {
1404   if (REG_P (operands[1]))
1405     return \"shl 24,%1,%0\;shra 24,%0,%0\";
1406   if (GET_CODE (operands[1]) == CONST_INT)
1407     abort ();
1408   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1409     {
1410       CC_STATUS_INIT;
1411       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1412       cc_status.mdep = XEXP (operands[1], 0);
1413       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1414     }
1415   else
1416     return \"ld.b %1,%0\";
1417 }")
1418
1419 (define_insn "extendqisi2"
1420   [(set (match_operand:SI 0 "register_operand" "=r")
1421         (sign_extend:SI
1422          (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1423   ""
1424   "*
1425 {
1426   if (REG_P (operands[1]))
1427     return \"shl 24,%1,%0\;shra 24,%0,%0\";
1428   if (GET_CODE (operands[1]) == CONST_INT)
1429     abort ();
1430   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1431     {
1432       CC_STATUS_INIT;
1433       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1434       cc_status.mdep = XEXP (operands[1], 0);
1435       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1436     }
1437   else
1438     return \"ld.b %1,%0\";
1439 }")
1440
1441 ;; Signed bitfield extractions come out looking like
1442 ;;      (shiftrt (sign_extend (shift <Y> <C1>)) <C2>)
1443 ;; which we expand poorly as four shift insns.
1444 ;; These patters yeild two shifts:
1445 ;;      (shiftrt (shift <Y> <C3>) <C4>)
1446 (define_insn ""
1447   [(set (match_operand:SI 0 "register_operand" "=r")
1448         (ashiftrt:SI
1449          (sign_extend:SI
1450           (match_operand:QI 1 "register_operand" "r"))
1451          (match_operand:SI 2 "logic_int" "n")))]
1452   "INTVAL (operands[2]) < 8"
1453   "*
1454 {
1455   return \"shl 24,%1,%0\;shra 24+%2,%0,%0\";
1456 }")
1457
1458 (define_insn ""
1459   [(set (match_operand:SI 0 "register_operand" "=r")
1460         (ashiftrt:SI
1461          (sign_extend:SI
1462           (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1463                                 (match_operand:SI 2 "logic_int" "n")) 0))
1464          (match_operand:SI 3 "logic_int" "n")))]
1465   "INTVAL (operands[3]) < 8"
1466   "*
1467 {
1468   return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1469 }")
1470
1471 (define_insn ""
1472   [(set (match_operand:SI 0 "register_operand" "=r")
1473         (ashiftrt:SI
1474          (sign_extend:SI
1475           (ashift:QI (match_operand:QI 1 "register_operand" "r")
1476                      (match_operand:QI 2 "logic_int" "n")))
1477          (match_operand:SI 3 "logic_int" "n")))]
1478   "INTVAL (operands[3]) < 8"
1479   "*
1480 {
1481   return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1482 }")
1483 \f
1484 ;; Special patterns for optimizing bit-field instructions.
1485
1486 ;; First two patterns are for bitfields that came from memory
1487 ;; testing only the high bit.  They work with old combiner.
1488
1489 (define_insn ""
1490   [(set (cc0)
1491         (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1492                                                     (const_int 7)) 0))
1493             (const_int 0)))]
1494   ""
1495   "*
1496 {
1497   CC_STATUS_PARTIAL_INIT;
1498   return \"and 128,%0,%?r0\";
1499 }")
1500
1501 (define_insn ""
1502   [(set (cc0)
1503         (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1504                                                     (const_int 7)) 0))
1505             (const_int 0)))]
1506   ""
1507   "*
1508 {
1509   CC_STATUS_PARTIAL_INIT;
1510   return \"and 128,%0,%?r0\";
1511 }")
1512
1513 ;; next two patterns are good for bitfields coming from memory
1514 ;; (via pseudo-register) or from a register, though this optimization
1515 ;; is only good for values contained wholly within the bottom 13 bits
1516 (define_insn ""
1517   [(set (cc0)
1518         (eq 
1519          (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1520                               (match_operand:SI 1 "logic_int" "n"))
1521                  (match_operand:SI 2 "logic_int" "n"))
1522          (const_int 0)))]
1523   "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1524   "*
1525 {
1526   CC_STATUS_PARTIAL_INIT;
1527   operands[2] = gen_rtx (CONST_INT, VOIDmode,
1528                          (INTVAL (operands[2]) << INTVAL (operands[1])));
1529   return \"and %2,%0,%?r0\";
1530 }")
1531
1532 (define_insn ""
1533   [(set (cc0)
1534         (eq 
1535          (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1536                               (match_operand:SI 1 "logic_int" "n"))
1537                  (match_operand:SI 2 "logic_int" "n"))
1538          (const_int 0)))]
1539   "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1540   "*
1541 {
1542   CC_STATUS_PARTIAL_INIT;
1543   operands[2] = gen_rtx (CONST_INT, VOIDmode,
1544                          (INTVAL (operands[2]) << INTVAL (operands[1])));
1545   return \"and %2,%0,%?r0\";
1546 }")
1547 \f
1548 ;; Conversions between float and double.
1549
1550 (define_insn "extendsfdf2"
1551   [(set (match_operand:DF 0 "register_operand" "=f")
1552         (float_extend:DF
1553          (match_operand:SF 1 "register_operand" "f")))]
1554   ""
1555   "fmov.sd %1,%0")
1556
1557 (define_insn "truncdfsf2"
1558   [(set (match_operand:SF 0 "register_operand" "=f")
1559         (float_truncate:SF
1560          (match_operand:DF 1 "register_operand" "f")))]
1561   ""
1562   "fmov.ds %1,%0")
1563 \f
1564 ;; Conversion between fixed point and floating point.
1565 ;; Note that among the fix-to-float insns
1566 ;; the ones that start with SImode come first.
1567 ;; That is so that an operand that is a CONST_INT
1568 ;; (and therefore lacks a specific machine mode).
1569 ;; will be recognized as SImode (which is always valid)
1570 ;; rather than as QImode or HImode.
1571
1572 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
1573 ;; to be reloaded by putting the constant into memory.
1574 ;; It must come before the more general floatsisf2 pattern.
1575 (define_expand "floatsidf2"
1576   [(set (match_dup 2) (match_dup 3))
1577    (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "")
1578                               (const_int -2147483648)))
1579    (set (match_dup 5) (match_dup 3))
1580    (set (subreg:SI (match_dup 5) 0) (match_dup 4))
1581    (set (match_operand:DF 0 "register_operand" "")
1582         (minus:DF (match_dup 5) (match_dup 2)))]
1583   ""
1584   "
1585 {
1586   REAL_VALUE_TYPE d;
1587   /* 4503601774854144 is  (1 << 30) * ((1 << 22) + (1 << 1)).  */
1588   d = REAL_VALUE_ATOF (\"4503601774854144\");
1589   operands[2] = gen_reg_rtx (DFmode);
1590   operands[3] = CONST_DOUBLE_FROM_REAL_VALUE (d, DFmode);
1591   operands[4] = gen_reg_rtx (SImode);
1592   operands[5] = gen_reg_rtx (DFmode);
1593 }")
1594 \f
1595 ;; Floating to fixed conversion.
1596
1597 (define_expand "fix_truncdfsi2"
1598   ;; This first insn produces a double-word value
1599   ;; in which only the low word is valid.
1600   [(set (match_dup 2)
1601         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1602    (set (match_operand:SI 0 "register_operand" "=f")
1603         (subreg:SI (match_dup 2) 0))]
1604   ""
1605   "
1606 {
1607   operands[2] = gen_reg_rtx (DImode);
1608 }")
1609
1610 ;; Recognize the first insn generated above.
1611 ;; This RTL looks like a fix_truncdfdi2 insn,
1612 ;; but we dont call it that, because only 32 bits
1613 ;; of the result are valid.
1614 ;; This pattern will work for the intended purposes 
1615 ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2.
1616 (define_insn ""
1617   [(set (match_operand:DI 0 "register_operand" "=f")
1618         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1619   ""
1620   "ftrunc.dd %1,%0")
1621
1622 (define_expand "fix_truncsfsi2"
1623   ;; This first insn produces a double-word value
1624   ;; in which only the low word is valid.
1625   [(set (match_dup 2)
1626         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
1627    (set (match_operand:SI 0 "register_operand" "=f")
1628         (subreg:SI (match_dup 2) 0))]
1629   ""
1630   "
1631 {
1632   operands[2] = gen_reg_rtx (DImode);
1633 }")
1634
1635 ;; Recognize the first insn generated above.
1636 ;; This RTL looks like a fix_truncsfdi2 insn,
1637 ;; but we dont call it that, because only 32 bits
1638 ;; of the result are valid.
1639 ;; This pattern will work for the intended purposes 
1640 ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2.
1641 (define_insn ""
1642   [(set (match_operand:DI 0 "register_operand" "=f")
1643         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1644   ""
1645   "ftrunc.sd %1,%0")
1646 \f
1647 ;;- arithmetic instructions
1648
1649 (define_insn "addsi3"
1650   [(set (match_operand:SI 0 "register_operand" "=r,*f")
1651         (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f")
1652                  (match_operand:SI 2 "arith_operand" "rI,*f")))]
1653   ""
1654   "*
1655 {
1656   if (which_alternative == 1)
1657     return \"fiadd.ss %2,%1,%0\";
1658   CC_STATUS_PARTIAL_INIT;
1659   return \"addu %2,%1,%0\";
1660 }")
1661
1662 (define_insn "adddi3"
1663   [(set (match_operand:DI 0 "register_operand" "=f")
1664         (plus:DI (match_operand:DI 1 "register_operand" "%f")
1665                  (match_operand:DI 2 "register_operand" "f")))]
1666   ""
1667   "fiadd.dd %1,%2,%0")
1668
1669 (define_insn "subsi3"
1670   [(set (match_operand:SI 0 "register_operand" "=r,r,*f")
1671         (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f")
1672                   (match_operand:SI 2 "arith_operand" "rI,r,*f")))]
1673   ""
1674   "*
1675 {
1676   if (which_alternative == 2)
1677     return \"fisub.ss %1,%2,%0\";
1678   CC_STATUS_PARTIAL_INIT;
1679   if (REG_P (operands[2]))
1680     return \"subu %1,%2,%0\";
1681   operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
1682   return \"addu %2,%1,%0\";
1683 }")
1684
1685 (define_insn "subdi3"
1686   [(set (match_operand:DI 0 "register_operand" "=f")
1687         (minus:DI (match_operand:DI 1 "register_operand" "%f")
1688                   (match_operand:DI 2 "register_operand" "f")))]
1689   ""
1690   "fisub.dd %1,%2,%0")
1691
1692 (define_expand "mulsi3"
1693   [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1694    (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1695    (clobber (match_dup 3))
1696    (set (subreg:SI (match_dup 3) 0)
1697         (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1698    (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1699   ""
1700   "
1701 {
1702   operands[3] = gen_reg_rtx (DImode);
1703   operands[4] = gen_reg_rtx (DImode);
1704   operands[5] = gen_reg_rtx (DImode);
1705 }")
1706
1707 (define_insn ""
1708   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
1709         (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
1710                  (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
1711   ""
1712   "fmlow.dd %2,%1,%0")
1713 \f
1714 ;;- and instructions (with compliment also)                        
1715 (define_insn "andsi3"
1716   [(set (match_operand:SI 0 "register_operand" "=r")
1717         (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1718                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1719   ""
1720   "*
1721 {
1722   rtx xop[3];
1723
1724   CC_STATUS_PARTIAL_INIT;
1725   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1726     return \"and %2,%1,%0\";
1727   if ((INTVAL (operands[2]) & 0xffff) == 0)
1728     {
1729       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1730                              (unsigned) INTVAL (operands[2]) >> 16);
1731       return \"andh %2,%1,%0\";
1732     }
1733   xop[0] = operands[0];
1734   xop[1] = operands[1];
1735   xop[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]) & 0xffff);
1736   output_asm_insn (\"andnot %2,%1,%0\", xop);
1737   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1738                          ~(unsigned) INTVAL (operands[2]) >> 16);
1739   return \"andnoth %2,%0,%0\";
1740 }")
1741
1742 (define_insn ""
1743   [(set (match_operand:SI 0 "register_operand" "=r")
1744         (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn"))
1745                 (match_operand:SI 2 "register_operand" "r")))]
1746   ""
1747   "*
1748 {
1749   rtx xop[3];
1750
1751   CC_STATUS_PARTIAL_INIT;
1752   if (REG_P (operands[1]) || LOGIC_INT (operands[1]))
1753     return \"andnot %1,%2,%0\";
1754   if ((INTVAL (operands[1]) & 0xffff) == 0)
1755     {
1756       operands[1] = gen_rtx (CONST_INT, VOIDmode, 
1757                              (unsigned) INTVAL (operands[1]) >> 16);
1758       return \"andnoth %1,%2,%0\";
1759     }
1760   xop[0] = operands[0];
1761   xop[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) & 0xffff));
1762   xop[2] = operands[2];
1763   output_asm_insn (\"andnot %1,%2,%0\", xop);
1764   operands[1] = gen_rtx (CONST_INT, VOIDmode, 
1765                          (unsigned) INTVAL (operands[1]) >> 16);
1766   return \"andnoth %1,%0,%0\";
1767 }")
1768
1769 (define_insn "iorsi3"
1770   [(set (match_operand:SI 0 "register_operand" "=r")
1771         (ior: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 \"or %2,%1,%0\";
1781   if ((INTVAL (operands[2]) & 0xffff) == 0)
1782     {
1783       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1784                              (unsigned) INTVAL (operands[2]) >> 16);
1785       return \"orh %2,%1,%0\";
1786     }
1787   xop[0] = operands[0];
1788   xop[1] = operands[1];
1789   xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1790   output_asm_insn (\"or %2,%1,%0\", xop);
1791   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1792                          (unsigned) INTVAL (operands[2]) >> 16);
1793   return \"orh %2,%0,%0\";
1794 }")
1795
1796 (define_insn "xorsi3"
1797   [(set (match_operand:SI 0 "register_operand" "=r")
1798         (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1799                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1800   ""
1801   "*
1802 {
1803   rtx xop[3];
1804
1805   CC_STATUS_PARTIAL_INIT;
1806   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1807     return \"xor %2,%1,%0\";
1808   if ((INTVAL (operands[2]) & 0xffff) == 0)
1809     {
1810       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1811                              (unsigned) INTVAL (operands[2]) >> 16);
1812       return \"xorh %2,%1,%0\";
1813     }
1814   xop[0] = operands[0];
1815   xop[1] = operands[1];
1816   xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1817   output_asm_insn (\"xor %2,%1,%0\", xop);
1818   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1819                          (unsigned) INTVAL (operands[2]) >> 16);
1820   return \"xorh %2,%0,%0\";
1821 }")
1822
1823 ;(The i860 instruction set doesn't allow an immediate second operand in
1824 ; a subtraction.)
1825 (define_insn "negsi2"
1826   [(set (match_operand:SI 0 "general_operand" "=r")
1827         (neg:SI (match_operand:SI 1 "arith_operand" "r")))]
1828   ""
1829   "*
1830 {
1831   CC_STATUS_PARTIAL_INIT;
1832   return \"subu %?r0,%1,%0\";
1833 }")
1834
1835 (define_insn "one_cmplsi2"
1836   [(set (match_operand:SI 0 "general_operand" "=r")
1837         (not:SI (match_operand:SI 1 "arith_operand" "r")))]
1838   ""
1839   "*
1840 {
1841   CC_STATUS_PARTIAL_INIT;
1842   return \"subu -1,%1,%0\";
1843 }")
1844 \f
1845 ;; Floating point arithmetic instructions.
1846
1847 (define_insn "adddf3"
1848   [(set (match_operand:DF 0 "register_operand" "=f")
1849         (plus:DF (match_operand:DF 1 "register_operand" "f")
1850                  (match_operand:DF 2 "register_operand" "f")))]
1851   ""
1852   "fadd.dd %1,%2,%0")
1853
1854 (define_insn "addsf3"
1855   [(set (match_operand:SF 0 "register_operand" "=f")
1856         (plus:SF (match_operand:SF 1 "register_operand" "f")
1857                  (match_operand:SF 2 "register_operand" "f")))]
1858   ""
1859   "fadd.ss %1,%2,%0")
1860
1861 (define_insn "subdf3"
1862   [(set (match_operand:DF 0 "register_operand" "=f")
1863         (minus:DF (match_operand:DF 1 "register_operand" "f")
1864                   (match_operand:DF 2 "register_operand" "f")))]
1865   ""
1866   "fsub.dd %1,%2,%0")
1867
1868 (define_insn "subsf3"
1869   [(set (match_operand:SF 0 "register_operand" "=f")
1870         (minus:SF (match_operand:SF 1 "register_operand" "f")
1871                   (match_operand:SF 2 "register_operand" "f")))]
1872   ""
1873   "fsub.ss %1,%2,%0")
1874
1875 (define_insn "muldf3"
1876   [(set (match_operand:DF 0 "register_operand" "=f")
1877         (mult:DF (match_operand:DF 1 "register_operand" "f")
1878                  (match_operand:DF 2 "register_operand" "f")))]
1879   ""
1880   "fmul.dd %1,%2,%0")
1881
1882 (define_insn "mulsf3"
1883   [(set (match_operand:SF 0 "register_operand" "=f")
1884         (mult:SF (match_operand:SF 1 "register_operand" "f")
1885                  (match_operand:SF 2 "register_operand" "f")))]
1886   ""
1887   "fmul.ss %1,%2,%0")
1888
1889 (define_insn "negdf2"
1890   [(set (match_operand:DF 0 "register_operand" "=f")
1891         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1892   ""
1893   "fsub.dd %?f0,%1,%0")
1894
1895 (define_insn "negsf2"
1896   [(set (match_operand:SF 0 "register_operand" "=f")
1897         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1898   ""
1899   "fsub.ss %?f0,%1,%0")
1900 \f
1901 (define_insn "divdf3"
1902   [(set (match_operand:DF 0 "register_operand" "=&f")
1903         (div:DF (match_operand:DF 1 "register_operand" "f")
1904                  (match_operand:DF 2 "register_operand" "f")))
1905    (clobber (match_scratch:DF 3 "=&f"))
1906    (clobber (match_scratch:DF 4 "=&f"))]
1907   ""
1908   "*
1909 {
1910   CC_STATUS_PARTIAL_INIT;
1911   if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1912       || (cc_prev_status.flags & CC_HI_R31_ADJ)
1913       || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1914     {
1915       cc_status.flags |= CC_KNOW_HI_R31;
1916       cc_status.flags &= ~CC_HI_R31_ADJ;
1917       cc_status.mdep = CONST2_RTX (SFmode); 
1918       return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1919 orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1920 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1921 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1922 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1923     }
1924   else
1925     return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1926 ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1927 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1928 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1929 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1930 }")
1931
1932 (define_insn "divsf3"
1933   [(set (match_operand:SF 0 "register_operand" "=&f")
1934         (div:SF (match_operand:SF 1 "register_operand" "f")
1935                  (match_operand:SF 2 "register_operand" "f")))
1936    (clobber (match_scratch:SF 3 "=&f"))
1937    (clobber (match_scratch:SF 4 "=&f"))]
1938   ""
1939   "*
1940 {
1941   CC_STATUS_PARTIAL_INIT;
1942   if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1943       || (cc_prev_status.flags & CC_HI_R31_ADJ)
1944       || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1945     {
1946       cc_status.flags |= CC_KNOW_HI_R31;
1947       cc_status.flags &= ~CC_HI_R31_ADJ;
1948       cc_status.mdep = CONST2_RTX (SFmode);
1949       output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands);
1950     }
1951   return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\\
1952 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\\
1953 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\\
1954 fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\";
1955 }")
1956 \f
1957 ;; Shift instructions
1958
1959 ;; Optimized special case of shifting.
1960 ;; Must precede the general case.
1961
1962 (define_insn ""
1963   [(set (match_operand:SI 0 "register_operand" "=r")
1964         (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
1965                      (const_int 24)))]
1966   ""
1967   "*
1968 {
1969   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1970     {
1971       CC_STATUS_INIT;
1972       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1973       cc_status.mdep = XEXP (operands[1], 0);
1974       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1975     }
1976   return \"ld.b %1,%0\";
1977 }")
1978
1979 \f
1980 ;;- arithmetic shift instructions
1981 (define_insn "ashlsi3"
1982   [(set (match_operand:SI 0 "register_operand" "=r")
1983         (ashift:SI (match_operand:SI 1 "register_operand" "r")
1984                    (match_operand:SI 2 "shift_operand" "rn")))]
1985   ""
1986   "*
1987 {
1988   return \"shl %2,%1,%0\";
1989 }")
1990
1991 (define_insn "ashlhi3"
1992   [(set (match_operand:HI 0 "register_operand" "=r")
1993         (ashift:HI (match_operand:HI 1 "register_operand" "r")
1994                    (match_operand:HI 2 "shift_operand" "rn")))]
1995   ""
1996   "*
1997 {
1998   return \"shl %2,%1,%0\";
1999 }")
2000
2001 (define_insn "ashlqi3"
2002   [(set (match_operand:QI 0 "register_operand" "=r")
2003         (ashift:QI (match_operand:QI 1 "register_operand" "r")
2004                    (match_operand:QI 2 "shift_operand" "rn")))]
2005   ""
2006   "*
2007 {
2008   return \"shl %2,%1,%0\";
2009 }")
2010
2011 (define_insn "ashrsi3"
2012   [(set (match_operand:SI 0 "register_operand" "=r")
2013         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2014                      (match_operand:SI 2 "shift_operand" "rn")))]
2015   ""
2016   "*
2017 {
2018   return \"shra %2,%1,%0\";
2019 }")
2020
2021 (define_insn "lshrsi3"
2022   [(set (match_operand:SI 0 "register_operand" "=r")
2023         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2024                      (match_operand:SI 2 "shift_operand" "rn")))]
2025   ""
2026   "*
2027 {
2028   return \"shr %2,%1,%0\";
2029 }")
2030 \f
2031 ;; Unconditional and other jump instructions
2032
2033 (define_insn "jump"
2034   [(set (pc) (label_ref (match_operand 0 "" "")))]
2035   ""
2036   "*
2037 {
2038   return \"br %l0\;nop\";
2039 }")
2040
2041 ;; Here are two simple peepholes which fill the delay slot of
2042 ;; an unconditional branch.
2043
2044 (define_peephole
2045   [(set (match_operand:SI 0 "register_operand" "=rf")
2046         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2047    (set (pc) (label_ref (match_operand 2 "" "")))]
2048   ""
2049   "* return output_delayed_branch (\"br %l2\", operands, insn);")
2050
2051 (define_peephole
2052   [(set (match_operand:SI 0 "memory_operand" "=m")
2053         (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2054    (set (pc) (label_ref (match_operand 2 "" "")))]
2055   ""
2056   "* return output_delayed_branch (\"br %l2\", operands, insn);")
2057
2058 (define_insn "tablejump"
2059   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2060    (use (label_ref (match_operand 1 "" "")))]
2061   ""
2062   "bri %0\;nop")
2063
2064 (define_peephole
2065   [(set (match_operand:SI 0 "memory_operand" "=m")
2066         (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2067    (set (pc) (match_operand:SI 2 "register_operand" "r"))
2068    (use (label_ref (match_operand 3 "" "")))]
2069   ""
2070   "* return output_delayed_branch (\"bri %2\", operands, insn);")
2071
2072 ;;- jump to subroutine
2073 (define_expand "call"
2074   [(call (match_operand:SI 0 "memory_operand" "m")
2075          (match_operand 1 "" "i"))]
2076   ;; operand[2] is next_arg_register
2077   ""
2078   "
2079 {
2080   if (INTVAL (operands[1]) > 0)
2081     {
2082       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2083       emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2084     }
2085 }")
2086
2087 ;;- jump to subroutine
2088 (define_insn ""
2089   [(call (match_operand:SI 0 "memory_operand" "m")
2090          (match_operand 1 "" "i"))]
2091   ;; operand[2] is next_arg_register
2092   ""
2093   "*
2094 {
2095   /* strip the MEM.  */
2096   operands[0] = XEXP (operands[0], 0);
2097   CC_STATUS_INIT;
2098   if (GET_CODE (operands[0]) == REG)
2099     return \"calli %0\;nop\";
2100   return \"call %0\;nop\";
2101 }")
2102
2103 (define_peephole
2104   [(set (match_operand:SI 0 "register_operand" "=rf")
2105         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2106    (call (match_operand:SI 2 "memory_operand" "m")
2107          (match_operand 3 "" "i"))]
2108   ;;- Don't use operand 1 for most machines.
2109   "! reg_mentioned_p (operands[0], operands[2])"
2110   "*
2111 {
2112   /* strip the MEM.  */
2113   operands[2] = XEXP (operands[2], 0);
2114   if (GET_CODE (operands[2]) == REG)
2115     return output_delayed_branch (\"calli %2\", operands, insn);
2116   return output_delayed_branch (\"call %2\", operands, insn);
2117 }")
2118
2119 (define_peephole
2120   [(set (match_operand:SI 0 "memory_operand" "=m")
2121         (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2122    (call (match_operand:SI 2 "memory_operand" "m")
2123          (match_operand 3 "" "i"))]
2124   ;;- Don't use operand 1 for most machines.
2125   ""
2126   "*
2127 {
2128   /* strip the MEM.  */
2129   operands[2] = XEXP (operands[2], 0);
2130   if (GET_CODE (operands[2]) == REG)
2131     return output_delayed_branch (\"calli %2\", operands, insn);
2132   return output_delayed_branch (\"call %2\", operands, insn);
2133 }")
2134
2135 (define_expand "call_value"
2136   [(set (match_operand 0 "register_operand" "=rf")
2137         (call (match_operand:SI 1 "memory_operand" "m")
2138               (match_operand 2 "" "i")))]
2139   ;; operand 3 is next_arg_register
2140   ""
2141   "
2142 {
2143   if (INTVAL (operands[2]) > 0)
2144     {
2145       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2146       emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2147     }
2148 }")
2149
2150 (define_insn ""
2151   [(set (match_operand 0 "register_operand" "=rf")
2152         (call (match_operand:SI 1 "memory_operand" "m")
2153               (match_operand 2 "" "i")))]
2154   ;; operand 3 is next_arg_register
2155   ""
2156   "*
2157 {
2158   /* strip the MEM.  */
2159   operands[1] = XEXP (operands[1], 0);
2160   CC_STATUS_INIT;
2161   if (GET_CODE (operands[1]) == REG)
2162     return \"calli %1\;nop\";
2163   return \"call %1\;nop\";
2164 }")
2165
2166 (define_peephole
2167   [(set (match_operand:SI 0 "register_operand" "=rf")
2168         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2169    (set (match_operand 2 "" "=rf")
2170         (call (match_operand:SI 3 "memory_operand" "m")
2171               (match_operand 4 "" "i")))]
2172   ;;- Don't use operand 4 for most machines.
2173   "! reg_mentioned_p (operands[0], operands[3])"
2174   "*
2175 {
2176   /* strip the MEM.  */
2177   operands[3] = XEXP (operands[3], 0);
2178   if (GET_CODE (operands[3]) == REG)
2179     return output_delayed_branch (\"calli %3\", operands, insn);
2180   return output_delayed_branch (\"call %3\", operands, insn);
2181 }")
2182
2183 (define_peephole
2184   [(set (match_operand:SI 0 "memory_operand" "=m")
2185         (match_operand:SI 1 "reg_or_0_operand" "rJf"))
2186    (set (match_operand 2 "" "=rf")
2187         (call (match_operand:SI 3 "memory_operand" "m")
2188               (match_operand 4 "" "i")))]
2189   ;;- Don't use operand 4 for most machines.
2190   ""
2191   "*
2192 {
2193   /* strip the MEM.  */
2194   operands[3] = XEXP (operands[3], 0);
2195   if (GET_CODE (operands[3]) == REG)
2196     return output_delayed_branch (\"calli %3\", operands, insn);
2197   return output_delayed_branch (\"call %3\", operands, insn);
2198 }")
2199 \f
2200 (define_insn "nop"
2201   [(const_int 0)]
2202   ""
2203   "nop")
2204
2205 (define_insn "indirect_jump"
2206   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2207   ""
2208   "bri %0")
2209 \f
2210 ;;
2211 ;; A special insn that does the work to get setup just
2212 ;; before a table jump.
2213 ;;
2214 (define_insn ""
2215   [(set (match_operand:SI 0 "register_operand" "=r")
2216         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2217                          (label_ref (match_operand 2 "" "")))))]
2218   ""
2219   "*
2220 {
2221   CC_STATUS_INIT;
2222   return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\";
2223 }")
2224   
2225 (define_peephole
2226   [(set (match_operand:SI 0 "register_operand" "=rf")
2227         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2228    (set (pc) (match_operand:SI 2 "register_operand" "r"))
2229    (use (label_ref (match_operand 3 "" "")))]
2230   "REGNO (operands[0]) != REGNO (operands[2])"
2231   "* return output_delayed_branch (\"bri %2\", operands, insn);")
2232 \f
2233 ;;- Local variables:
2234 ;;- mode:emacs-lisp
2235 ;;- comment-start: ";;- "
2236 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2237 ;;- eval: (modify-syntax-entry ?[ "(]")
2238 ;;- eval: (modify-syntax-entry ?] ")[")
2239 ;;- eval: (modify-syntax-entry ?{ "(}")
2240 ;;- eval: (modify-syntax-entry ?} "){")
2241 ;;- End:
2242