OSDN Git Service

(ASM_OUTPUT_LOCAL): New override.
[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   if (WORDS_BIG_ENDIAN)
1703     emit_insn (gen_mulsi3_big (operands[0], operands[1], operands[2]));
1704   else
1705     emit_insn (gen_mulsi3_little (operands[0], operands[1], operands[2]));
1706   DONE;
1707 }")
1708
1709 (define_expand "mulsi3_little"
1710   [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1711    (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1712    (clobber (match_dup 3))
1713    (set (subreg:SI (match_dup 3) 0)
1714         (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1715    (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1716   "! WORDS_BIG_ENDIAN"
1717   "
1718 {
1719   operands[3] = gen_reg_rtx (DImode);
1720   operands[4] = gen_reg_rtx (DImode);
1721   operands[5] = gen_reg_rtx (DImode);
1722 }")
1723
1724 (define_expand "mulsi3_big"
1725   [(set (subreg:SI (match_dup 4) 1) (match_operand:SI 1 "general_operand" ""))
1726    (set (subreg:SI (match_dup 5) 1) (match_operand:SI 2 "general_operand" ""))
1727    (clobber (match_dup 3))
1728    (set (subreg:SI (match_dup 3) 1)
1729         (mult:SI (subreg:SI (match_dup 4) 1) (subreg:SI (match_dup 5) 1)))
1730    (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 1))]
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_insn ""
1740   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
1741         (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
1742                  (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
1743   "! WORDS_BIG_ENDIAN"
1744   "fmlow.dd %2,%1,%0")
1745
1746 (define_insn ""
1747   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 1)
1748         (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 1)
1749                  (subreg:SI (match_operand:DI 2 "register_operand" "f") 1)))]
1750   "WORDS_BIG_ENDIAN"
1751   "fmlow.dd %2,%1,%0")
1752 \f
1753 ;;- and instructions (with compliment also)                        
1754 (define_insn "andsi3"
1755   [(set (match_operand:SI 0 "register_operand" "=r")
1756         (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1757                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1758   ""
1759   "*
1760 {
1761   rtx xop[3];
1762
1763   CC_STATUS_PARTIAL_INIT;
1764   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1765     return \"and %2,%1,%0\";
1766   if ((INTVAL (operands[2]) & 0xffff) == 0)
1767     {
1768       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1769                              (unsigned) INTVAL (operands[2]) >> 16);
1770       return \"andh %2,%1,%0\";
1771     }
1772   xop[0] = operands[0];
1773   xop[1] = operands[1];
1774   xop[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]) & 0xffff);
1775   output_asm_insn (\"andnot %2,%1,%0\", xop);
1776   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1777                          ~(unsigned) INTVAL (operands[2]) >> 16);
1778   return \"andnoth %2,%0,%0\";
1779 }")
1780
1781 (define_insn ""
1782   [(set (match_operand:SI 0 "register_operand" "=r")
1783         (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn"))
1784                 (match_operand:SI 2 "register_operand" "r")))]
1785   ""
1786   "*
1787 {
1788   rtx xop[3];
1789
1790   CC_STATUS_PARTIAL_INIT;
1791   if (REG_P (operands[1]) || LOGIC_INT (operands[1]))
1792     return \"andnot %1,%2,%0\";
1793   if ((INTVAL (operands[1]) & 0xffff) == 0)
1794     {
1795       operands[1] = gen_rtx (CONST_INT, VOIDmode, 
1796                              (unsigned) INTVAL (operands[1]) >> 16);
1797       return \"andnoth %1,%2,%0\";
1798     }
1799   xop[0] = operands[0];
1800   xop[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) & 0xffff));
1801   xop[2] = operands[2];
1802   output_asm_insn (\"andnot %1,%2,%0\", xop);
1803   operands[1] = gen_rtx (CONST_INT, VOIDmode, 
1804                          (unsigned) INTVAL (operands[1]) >> 16);
1805   return \"andnoth %1,%0,%0\";
1806 }")
1807
1808 (define_insn "iorsi3"
1809   [(set (match_operand:SI 0 "register_operand" "=r")
1810         (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1811                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1812   ""
1813   "*
1814 {
1815   rtx xop[3];
1816
1817   CC_STATUS_PARTIAL_INIT;
1818   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1819     return \"or %2,%1,%0\";
1820   if ((INTVAL (operands[2]) & 0xffff) == 0)
1821     {
1822       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1823                              (unsigned) INTVAL (operands[2]) >> 16);
1824       return \"orh %2,%1,%0\";
1825     }
1826   xop[0] = operands[0];
1827   xop[1] = operands[1];
1828   xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1829   output_asm_insn (\"or %2,%1,%0\", xop);
1830   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1831                          (unsigned) INTVAL (operands[2]) >> 16);
1832   return \"orh %2,%0,%0\";
1833 }")
1834
1835 (define_insn "xorsi3"
1836   [(set (match_operand:SI 0 "register_operand" "=r")
1837         (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1838                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1839   ""
1840   "*
1841 {
1842   rtx xop[3];
1843
1844   CC_STATUS_PARTIAL_INIT;
1845   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1846     return \"xor %2,%1,%0\";
1847   if ((INTVAL (operands[2]) & 0xffff) == 0)
1848     {
1849       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1850                              (unsigned) INTVAL (operands[2]) >> 16);
1851       return \"xorh %2,%1,%0\";
1852     }
1853   xop[0] = operands[0];
1854   xop[1] = operands[1];
1855   xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1856   output_asm_insn (\"xor %2,%1,%0\", xop);
1857   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1858                          (unsigned) INTVAL (operands[2]) >> 16);
1859   return \"xorh %2,%0,%0\";
1860 }")
1861
1862 ;(The i860 instruction set doesn't allow an immediate second operand in
1863 ; a subtraction.)
1864 (define_insn "negsi2"
1865   [(set (match_operand:SI 0 "general_operand" "=r")
1866         (neg:SI (match_operand:SI 1 "arith_operand" "r")))]
1867   ""
1868   "*
1869 {
1870   CC_STATUS_PARTIAL_INIT;
1871   return \"subu %?r0,%1,%0\";
1872 }")
1873
1874 (define_insn "one_cmplsi2"
1875   [(set (match_operand:SI 0 "general_operand" "=r")
1876         (not:SI (match_operand:SI 1 "arith_operand" "r")))]
1877   ""
1878   "*
1879 {
1880   CC_STATUS_PARTIAL_INIT;
1881   return \"subu -1,%1,%0\";
1882 }")
1883 \f
1884 ;; Floating point arithmetic instructions.
1885
1886 (define_insn "adddf3"
1887   [(set (match_operand:DF 0 "register_operand" "=f")
1888         (plus:DF (match_operand:DF 1 "register_operand" "f")
1889                  (match_operand:DF 2 "register_operand" "f")))]
1890   ""
1891   "fadd.dd %1,%2,%0")
1892
1893 (define_insn "addsf3"
1894   [(set (match_operand:SF 0 "register_operand" "=f")
1895         (plus:SF (match_operand:SF 1 "register_operand" "f")
1896                  (match_operand:SF 2 "register_operand" "f")))]
1897   ""
1898   "fadd.ss %1,%2,%0")
1899
1900 (define_insn "subdf3"
1901   [(set (match_operand:DF 0 "register_operand" "=f")
1902         (minus:DF (match_operand:DF 1 "register_operand" "f")
1903                   (match_operand:DF 2 "register_operand" "f")))]
1904   ""
1905   "fsub.dd %1,%2,%0")
1906
1907 (define_insn "subsf3"
1908   [(set (match_operand:SF 0 "register_operand" "=f")
1909         (minus:SF (match_operand:SF 1 "register_operand" "f")
1910                   (match_operand:SF 2 "register_operand" "f")))]
1911   ""
1912   "fsub.ss %1,%2,%0")
1913
1914 (define_insn "muldf3"
1915   [(set (match_operand:DF 0 "register_operand" "=f")
1916         (mult:DF (match_operand:DF 1 "register_operand" "f")
1917                  (match_operand:DF 2 "register_operand" "f")))]
1918   ""
1919   "fmul.dd %1,%2,%0")
1920
1921 (define_insn "mulsf3"
1922   [(set (match_operand:SF 0 "register_operand" "=f")
1923         (mult:SF (match_operand:SF 1 "register_operand" "f")
1924                  (match_operand:SF 2 "register_operand" "f")))]
1925   ""
1926   "fmul.ss %1,%2,%0")
1927
1928 (define_insn "negdf2"
1929   [(set (match_operand:DF 0 "register_operand" "=f")
1930         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1931   ""
1932   "fsub.dd %?f0,%1,%0")
1933
1934 (define_insn "negsf2"
1935   [(set (match_operand:SF 0 "register_operand" "=f")
1936         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1937   ""
1938   "fsub.ss %?f0,%1,%0")
1939 \f
1940 (define_insn "divdf3"
1941   [(set (match_operand:DF 0 "register_operand" "=&f")
1942         (div:DF (match_operand:DF 1 "register_operand" "f")
1943                  (match_operand:DF 2 "register_operand" "f")))
1944    (clobber (match_scratch:DF 3 "=&f"))
1945    (clobber (match_scratch:DF 4 "=&f"))]
1946   ""
1947   "*
1948 {
1949   CC_STATUS_PARTIAL_INIT;
1950   if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1951       || (cc_prev_status.flags & CC_HI_R31_ADJ)
1952       || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1953     {
1954       cc_status.flags |= CC_KNOW_HI_R31;
1955       cc_status.flags &= ~CC_HI_R31_ADJ;
1956       cc_status.mdep = CONST2_RTX (SFmode); 
1957       return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1958 orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1959 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1960 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1961 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1962     }
1963   else
1964     return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1965 ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1966 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1967 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1968 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1969 }")
1970
1971 (define_insn "divsf3"
1972   [(set (match_operand:SF 0 "register_operand" "=&f")
1973         (div:SF (match_operand:SF 1 "register_operand" "f")
1974                  (match_operand:SF 2 "register_operand" "f")))
1975    (clobber (match_scratch:SF 3 "=&f"))
1976    (clobber (match_scratch:SF 4 "=&f"))]
1977   ""
1978   "*
1979 {
1980   CC_STATUS_PARTIAL_INIT;
1981   if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1982       || (cc_prev_status.flags & CC_HI_R31_ADJ)
1983       || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1984     {
1985       cc_status.flags |= CC_KNOW_HI_R31;
1986       cc_status.flags &= ~CC_HI_R31_ADJ;
1987       cc_status.mdep = CONST2_RTX (SFmode);
1988       output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands);
1989     }
1990   return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\\
1991 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\\
1992 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\\
1993 fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\";
1994 }")
1995 \f
1996 ;; Shift instructions
1997
1998 ;; Optimized special case of shifting.
1999 ;; Must precede the general case.
2000
2001 (define_insn ""
2002   [(set (match_operand:SI 0 "register_operand" "=r")
2003         (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2004                      (const_int 24)))]
2005   ""
2006   "*
2007 {
2008   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
2009     {
2010       CC_STATUS_INIT;
2011       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
2012       cc_status.mdep = XEXP (operands[1], 0);
2013       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
2014     }
2015   return \"ld.b %1,%0\";
2016 }")
2017
2018 \f
2019 ;;- arithmetic shift instructions
2020 (define_insn "ashlsi3"
2021   [(set (match_operand:SI 0 "register_operand" "=r")
2022         (ashift:SI (match_operand:SI 1 "register_operand" "r")
2023                    (match_operand:SI 2 "shift_operand" "rn")))]
2024   ""
2025   "*
2026 {
2027   return \"shl %2,%1,%0\";
2028 }")
2029
2030 (define_insn "ashlhi3"
2031   [(set (match_operand:HI 0 "register_operand" "=r")
2032         (ashift:HI (match_operand:HI 1 "register_operand" "r")
2033                    (match_operand:HI 2 "shift_operand" "rn")))]
2034   ""
2035   "*
2036 {
2037   return \"shl %2,%1,%0\";
2038 }")
2039
2040 (define_insn "ashlqi3"
2041   [(set (match_operand:QI 0 "register_operand" "=r")
2042         (ashift:QI (match_operand:QI 1 "register_operand" "r")
2043                    (match_operand:QI 2 "shift_operand" "rn")))]
2044   ""
2045   "*
2046 {
2047   return \"shl %2,%1,%0\";
2048 }")
2049
2050 (define_insn "ashrsi3"
2051   [(set (match_operand:SI 0 "register_operand" "=r")
2052         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2053                      (match_operand:SI 2 "shift_operand" "rn")))]
2054   ""
2055   "*
2056 {
2057   return \"shra %2,%1,%0\";
2058 }")
2059
2060 (define_insn "lshrsi3"
2061   [(set (match_operand:SI 0 "register_operand" "=r")
2062         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2063                      (match_operand:SI 2 "shift_operand" "rn")))]
2064   ""
2065   "*
2066 {
2067   return \"shr %2,%1,%0\";
2068 }")
2069 \f
2070 ;; Unconditional and other jump instructions
2071
2072 (define_insn "jump"
2073   [(set (pc) (label_ref (match_operand 0 "" "")))]
2074   ""
2075   "*
2076 {
2077   return \"br %l0\;nop\";
2078 }")
2079
2080 ;; Here are two simple peepholes which fill the delay slot of
2081 ;; an unconditional branch.
2082
2083 (define_peephole
2084   [(set (match_operand:SI 0 "register_operand" "=rf")
2085         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2086    (set (pc) (label_ref (match_operand 2 "" "")))]
2087   ""
2088   "* return output_delayed_branch (\"br %l2\", operands, insn);")
2089
2090 (define_peephole
2091   [(set (match_operand:SI 0 "memory_operand" "=m")
2092         (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2093    (set (pc) (label_ref (match_operand 2 "" "")))]
2094   ""
2095   "* return output_delayed_branch (\"br %l2\", operands, insn);")
2096
2097 (define_insn "tablejump"
2098   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2099    (use (label_ref (match_operand 1 "" "")))]
2100   ""
2101   "bri %0\;nop")
2102
2103 (define_peephole
2104   [(set (match_operand:SI 0 "memory_operand" "=m")
2105         (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2106    (set (pc) (match_operand:SI 2 "register_operand" "r"))
2107    (use (label_ref (match_operand 3 "" "")))]
2108   ""
2109   "* return output_delayed_branch (\"bri %2\", operands, insn);")
2110
2111 ;;- jump to subroutine
2112 (define_expand "call"
2113   [(call (match_operand:SI 0 "memory_operand" "m")
2114          (match_operand 1 "" "i"))]
2115   ;; operand[2] is next_arg_register
2116   ""
2117   "
2118 {
2119   if (INTVAL (operands[1]) > 0)
2120     {
2121       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2122       emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2123     }
2124 }")
2125
2126 ;;- jump to subroutine
2127 (define_insn ""
2128   [(call (match_operand:SI 0 "memory_operand" "m")
2129          (match_operand 1 "" "i"))]
2130   ;; operand[2] is next_arg_register
2131   ""
2132   "*
2133 {
2134   /* strip the MEM.  */
2135   operands[0] = XEXP (operands[0], 0);
2136   CC_STATUS_INIT;
2137   if (GET_CODE (operands[0]) == REG)
2138     return \"calli %0\;nop\";
2139   return \"call %0\;nop\";
2140 }")
2141
2142 (define_peephole
2143   [(set (match_operand:SI 0 "register_operand" "=rf")
2144         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2145    (call (match_operand:SI 2 "memory_operand" "m")
2146          (match_operand 3 "" "i"))]
2147   ;;- Don't use operand 1 for most machines.
2148   "! reg_mentioned_p (operands[0], operands[2])"
2149   "*
2150 {
2151   /* strip the MEM.  */
2152   operands[2] = XEXP (operands[2], 0);
2153   if (GET_CODE (operands[2]) == REG)
2154     return output_delayed_branch (\"calli %2\", operands, insn);
2155   return output_delayed_branch (\"call %2\", operands, insn);
2156 }")
2157
2158 (define_peephole
2159   [(set (match_operand:SI 0 "memory_operand" "=m")
2160         (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2161    (call (match_operand:SI 2 "memory_operand" "m")
2162          (match_operand 3 "" "i"))]
2163   ;;- Don't use operand 1 for most machines.
2164   ""
2165   "*
2166 {
2167   /* strip the MEM.  */
2168   operands[2] = XEXP (operands[2], 0);
2169   if (GET_CODE (operands[2]) == REG)
2170     return output_delayed_branch (\"calli %2\", operands, insn);
2171   return output_delayed_branch (\"call %2\", operands, insn);
2172 }")
2173
2174 (define_expand "call_value"
2175   [(set (match_operand 0 "register_operand" "=rf")
2176         (call (match_operand:SI 1 "memory_operand" "m")
2177               (match_operand 2 "" "i")))]
2178   ;; operand 3 is next_arg_register
2179   ""
2180   "
2181 {
2182   if (INTVAL (operands[2]) > 0)
2183     {
2184       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2185       emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2186     }
2187 }")
2188
2189 (define_insn ""
2190   [(set (match_operand 0 "register_operand" "=rf")
2191         (call (match_operand:SI 1 "memory_operand" "m")
2192               (match_operand 2 "" "i")))]
2193   ;; operand 3 is next_arg_register
2194   ""
2195   "*
2196 {
2197   /* strip the MEM.  */
2198   operands[1] = XEXP (operands[1], 0);
2199   CC_STATUS_INIT;
2200   if (GET_CODE (operands[1]) == REG)
2201     return \"calli %1\;nop\";
2202   return \"call %1\;nop\";
2203 }")
2204
2205 (define_peephole
2206   [(set (match_operand:SI 0 "register_operand" "=rf")
2207         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2208    (set (match_operand 2 "" "=rf")
2209         (call (match_operand:SI 3 "memory_operand" "m")
2210               (match_operand 4 "" "i")))]
2211   ;;- Don't use operand 4 for most machines.
2212   "! reg_mentioned_p (operands[0], operands[3])"
2213   "*
2214 {
2215   /* strip the MEM.  */
2216   operands[3] = XEXP (operands[3], 0);
2217   if (GET_CODE (operands[3]) == REG)
2218     return output_delayed_branch (\"calli %3\", operands, insn);
2219   return output_delayed_branch (\"call %3\", operands, insn);
2220 }")
2221
2222 (define_peephole
2223   [(set (match_operand:SI 0 "memory_operand" "=m")
2224         (match_operand:SI 1 "reg_or_0_operand" "rJf"))
2225    (set (match_operand 2 "" "=rf")
2226         (call (match_operand:SI 3 "memory_operand" "m")
2227               (match_operand 4 "" "i")))]
2228   ;;- Don't use operand 4 for most machines.
2229   ""
2230   "*
2231 {
2232   /* strip the MEM.  */
2233   operands[3] = XEXP (operands[3], 0);
2234   if (GET_CODE (operands[3]) == REG)
2235     return output_delayed_branch (\"calli %3\", operands, insn);
2236   return output_delayed_branch (\"call %3\", operands, insn);
2237 }")
2238 \f
2239 (define_insn "nop"
2240   [(const_int 0)]
2241   ""
2242   "nop")
2243
2244 (define_insn "indirect_jump"
2245   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2246   ""
2247   "bri %0")
2248 \f
2249 ;;
2250 ;; A special insn that does the work to get setup just
2251 ;; before a table jump.
2252 ;;
2253 (define_insn ""
2254   [(set (match_operand:SI 0 "register_operand" "=r")
2255         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2256                          (label_ref (match_operand 2 "" "")))))]
2257   ""
2258   "*
2259 {
2260   CC_STATUS_INIT;
2261   return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\";
2262 }")
2263   
2264 (define_peephole
2265   [(set (match_operand:SI 0 "register_operand" "=rf")
2266         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2267    (set (pc) (match_operand:SI 2 "register_operand" "r"))
2268    (use (label_ref (match_operand 3 "" "")))]
2269   "REGNO (operands[0]) != REGNO (operands[2])"
2270   "* return output_delayed_branch (\"bri %2\", operands, insn);")
2271 \f
2272 ;;- Local variables:
2273 ;;- mode:emacs-lisp
2274 ;;- comment-start: ";;- "
2275 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2276 ;;- eval: (modify-syntax-entry ?[ "(]")
2277 ;;- eval: (modify-syntax-entry ?] ")[")
2278 ;;- eval: (modify-syntax-entry ?{ "(}")
2279 ;;- eval: (modify-syntax-entry ?} "){")
2280 ;;- End:
2281