OSDN Git Service

82f450487bb3c41133270128fb52dcbeb35345e5
[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
501 (define_insn ""
502   [(set (pc)
503         (if_then_else (eq (match_operand:QI 0 "register_operand" "r")
504                           (match_operand:QI 1 "bte_operand" "rK"))
505                       (label_ref (match_operand 2 "" ""))
506                       (pc)))]
507   ""
508   "bte %1,%0,%2")
509
510 (define_insn ""
511   [(set (pc)
512         (if_then_else (ne (match_operand:QI 0 "register_operand" "r")
513                           (match_operand:QI 1 "bte_operand" "rK"))
514                       (label_ref (match_operand 2 "" ""))
515                       (pc)))]
516   ""
517   "btne %1,%0,%2")
518
519 (define_insn ""
520   [(set (pc)
521         (if_then_else (eq (match_operand:QI 0 "register_operand" "r")
522                           (match_operand:QI 1 "bte_operand" "rK"))
523                       (pc)
524                       (label_ref (match_operand 2 "" ""))))]
525   ""
526   "btne %1,%0,%2")
527
528 (define_insn ""
529   [(set (pc)
530         (if_then_else (ne (match_operand:QI 0 "register_operand" "r")
531                           (match_operand:QI 1 "bte_operand" "rK"))
532                       (pc)
533                       (label_ref (match_operand 2 "" ""))))]
534   ""
535   "bte %1,%0,%2")
536
537 (define_insn ""
538   [(set (pc)
539         (if_then_else (eq (match_operand:HI 0 "register_operand" "r")
540                           (match_operand:HI 1 "bte_operand" "rK"))
541                       (label_ref (match_operand 2 "" ""))
542                       (pc)))]
543   ""
544   "bte %1,%0,%2")
545
546 (define_insn ""
547   [(set (pc)
548         (if_then_else (ne (match_operand:HI 0 "register_operand" "r")
549                           (match_operand:HI 1 "bte_operand" "rK"))
550                       (label_ref (match_operand 2 "" ""))
551                       (pc)))]
552   ""
553   "btne %1,%0,%2")
554
555 (define_insn ""
556   [(set (pc)
557         (if_then_else (eq (match_operand:HI 0 "register_operand" "r")
558                           (match_operand:HI 1 "bte_operand" "rK"))
559                       (pc)
560                       (label_ref (match_operand 2 "" ""))))]
561   ""
562   "btne %1,%0,%2")
563
564 (define_insn ""
565   [(set (pc)
566         (if_then_else (ne (match_operand:HI 0 "register_operand" "r")
567                           (match_operand:HI 1 "bte_operand" "rK"))
568                       (pc)
569                       (label_ref (match_operand 2 "" ""))))]
570   ""
571   "bte %1,%0,%2")
572
573 (define_insn ""
574   [(set (pc)
575         (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
576                           (match_operand:SI 1 "bte_operand" "rK"))
577                       (label_ref (match_operand 2 "" ""))
578                       (pc)))]
579   ""
580   "bte %1,%0,%2")
581
582 (define_insn ""
583   [(set (pc)
584         (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
585                           (match_operand:SI 1 "bte_operand" "rK"))
586                       (label_ref (match_operand 2 "" ""))
587                       (pc)))]
588   ""
589   "btne %1,%0,%2")
590
591 (define_insn ""
592   [(set (pc)
593         (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
594                           (match_operand:SI 1 "bte_operand" "rK"))
595                       (pc)
596                       (label_ref (match_operand 2 "" ""))))]
597   ""
598   "btne %1,%0,%2")
599
600 (define_insn ""
601   [(set (pc)
602         (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
603                           (match_operand:SI 1 "bte_operand" "rK"))
604                       (pc)
605                       (label_ref (match_operand 2 "" ""))))]
606   ""
607   "bte %1,%0,%2")
608
609 ;; Load byte/halfword, zero-extend, & compare-and-branch insns.
610 ;; These are made by combining.
611
612 (define_insn ""
613   [(set (pc)
614         (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
615                           (match_operand:SI 1 "bte_operand" "K"))
616                       (label_ref (match_operand 2 "" ""))
617                       (pc)))
618    (match_scratch:SI 3 "=r")]
619   ""
620   "ld.b %0,%3;bte %1,%3,%2")
621
622 (define_insn ""
623   [(set (pc)
624         (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
625                           (match_operand:SI 1 "bte_operand" "K"))
626                       (label_ref (match_operand 2 "" ""))
627                       (pc)))
628    (match_scratch:SI 3 "=r")]
629   ""
630   "ld.b %0,%3;btne %1,%3,%2")
631
632 (define_insn ""
633   [(set (pc)
634         (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
635                           (match_operand:SI 1 "bte_operand" "K"))
636                       (pc)
637                       (label_ref (match_operand 2 "" ""))))
638    (match_scratch:SI 3 "=r")]
639   ""
640   "ld.b %0,%3;btne %1,%3,%2")
641
642 (define_insn ""
643   [(set (pc)
644         (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
645                           (match_operand:SI 1 "bte_operand" "K"))
646                       (pc)
647                       (label_ref (match_operand 2 "" ""))))
648    (match_scratch:SI 3 "=r")]
649   ""
650   "ld.b %0,%3;bte %1,%3,%2")
651
652 (define_insn ""
653   [(set (pc)
654         (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
655                           (match_operand:SI 1 "bte_operand" "K"))
656                       (label_ref (match_operand 2 "" ""))
657                       (pc)))
658    (match_scratch:SI 3 "=r")]
659   ""
660   "ld.s %0,%3;bte %1,%3,%2")
661
662 (define_insn ""
663   [(set (pc)
664         (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
665                           (match_operand:SI 1 "bte_operand" "K"))
666                       (label_ref (match_operand 2 "" ""))
667                       (pc)))
668    (match_scratch:SI 3 "=r")]
669   ""
670   "ld.s %0,%3;btne %1,%3,%2")
671
672 (define_insn ""
673   [(set (pc)
674         (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
675                           (match_operand:SI 1 "bte_operand" "K"))
676                       (pc)
677                       (label_ref (match_operand 2 "" ""))))
678    (match_scratch:SI 3 "=r")]
679   ""
680   "ld.s %0,%3;btne %1,%3,%2")
681
682 (define_insn ""
683   [(set (pc)
684         (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
685                           (match_operand:SI 1 "bte_operand" "K"))
686                       (pc)
687                       (label_ref (match_operand 2 "" ""))))
688    (match_scratch:SI 3 "=r")]
689   ""
690   "ld.s %0,%3;bte %1,%3,%2")
691
692 \f
693 ;; Generation of conditionals.
694
695 ;; We save the compare operands in the cmpxx patterns and use then when
696 ;; we generate the branch.
697
698 (define_expand "cmpsi"
699   [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
700                        (match_operand:SI 1 "compare_operand" "")))]
701   ""
702   "
703 { i860_compare_op0 = operands[0];
704   i860_compare_op1 = operands[1];
705   DONE;
706 }")
707
708 (define_expand "cmpsf"
709   [(set (cc0) (compare (match_operand:SF 0 "register_operand" "")
710                        (match_operand:SF 1 "register_operand" "")))]
711   ""
712   "
713 { i860_compare_op0 = operands[0];
714   i860_compare_op1 = operands[1];
715   DONE;
716 }")
717
718 (define_expand "cmpdf"
719   [(set (cc0) (compare (match_operand:DF 0 "register_operand" "")
720                        (match_operand:DF 1 "register_operand" "")))]
721   ""
722   "
723 { i860_compare_op0 = operands[0];
724   i860_compare_op1 = operands[1];
725   DONE;
726 }")
727
728 ;; These are the standard-named conditional branch patterns.
729 ;; Detailed comments are found in the first one only.
730
731 (define_expand "beq"
732   [(set (pc)
733         (if_then_else (eq (cc0)
734                           (const_int 0))
735                       (label_ref (match_operand 0 "" ""))
736                       (pc)))]
737   ""
738   "
739 {
740   /* Emit a single-condition compare insn according to
741      the type of operands and the condition to be tested.  */
742
743   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
744     emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
745   else if (GET_MODE (i860_compare_op0) == SFmode)
746     emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
747   else if (GET_MODE (i860_compare_op0) == DFmode)
748     emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
749   else
750     abort ();
751
752   /* Emit branch-if-true.  */
753
754   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
755   DONE;
756 }")
757
758 (define_expand "bne"
759   [(set (pc)
760         (if_then_else (ne (cc0)
761                           (const_int 0))
762                       (label_ref (match_operand 0 "" ""))
763                       (pc)))]
764   ""
765   "
766 {
767   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
768     emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
769   else if (GET_MODE (i860_compare_op0) == SFmode)
770     emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
771   else if (GET_MODE (i860_compare_op0) == DFmode)
772     emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
773   else
774     abort ();
775
776   emit_jump_insn (gen_flipped_cbranch (operands[0]));
777
778   DONE;
779 }")
780
781 (define_expand "bgt"
782   [(set (pc)
783         (if_then_else (gt (cc0)
784                           (const_int 0))
785                       (label_ref (match_operand 0 "" ""))
786                       (pc)))]
787   ""
788   "
789 {
790   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
791     emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
792   else if (GET_MODE (i860_compare_op0) == SFmode)
793     emit_insn (gen_cmpgtsf (i860_compare_op0, i860_compare_op1));
794   else if (GET_MODE (i860_compare_op0) == DFmode)
795     emit_insn (gen_cmpgtdf (i860_compare_op0, i860_compare_op1));
796   else
797     abort ();
798
799   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
800   DONE;
801 }")
802
803 (define_expand "blt"
804   [(set (pc)
805         (if_then_else (lt (cc0)
806                           (const_int 0))
807                       (label_ref (match_operand 0 "" ""))
808                       (pc)))]
809   ""
810   "
811 {
812   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
813     emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
814   else if (GET_MODE (i860_compare_op0) == SFmode)
815     emit_insn (gen_cmpltsf (i860_compare_op0, i860_compare_op1));
816   else if (GET_MODE (i860_compare_op0) == DFmode)
817     emit_insn (gen_cmpltdf (i860_compare_op0, i860_compare_op1));
818   else
819     abort ();
820
821   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
822   DONE;
823 }")
824
825 (define_expand "ble"
826   [(set (pc)
827         (if_then_else (le (cc0)
828                           (const_int 0))
829                       (label_ref (match_operand 0 "" ""))
830                       (pc)))]
831   ""
832   "
833 {
834   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
835     {
836       emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
837       emit_jump_insn (gen_flipped_cbranch (operands[0]));
838     }
839   else
840     {
841       if (GET_MODE (i860_compare_op0) == SFmode)
842         emit_insn (gen_cmplesf (i860_compare_op0, i860_compare_op1));
843       else if (GET_MODE (i860_compare_op0) == DFmode)
844         emit_insn (gen_cmpledf (i860_compare_op0, i860_compare_op1));
845       else
846         abort ();
847       emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
848     }
849   DONE;
850 }")
851
852 (define_expand "bge"
853   [(set (pc)
854         (if_then_else (ge (cc0)
855                           (const_int 0))
856                       (label_ref (match_operand 0 "" ""))
857                       (pc)))]
858   ""
859   "
860 {
861   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
862     {
863       emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
864       emit_jump_insn (gen_flipped_cbranch (operands[0]));
865     }
866   else
867     {
868       if (GET_MODE (i860_compare_op0) == SFmode)
869         emit_insn (gen_cmpgesf (i860_compare_op0, i860_compare_op1));
870       else if (GET_MODE (i860_compare_op0) == DFmode)
871         emit_insn (gen_cmpgedf (i860_compare_op0, i860_compare_op1));
872       else
873         abort ();
874       emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
875     }
876   DONE;
877 }")
878
879 (define_expand "bgtu"
880   [(set (pc)
881         (if_then_else (gtu (cc0)
882                            (const_int 0))
883                       (label_ref (match_operand 0 "" ""))
884                       (pc)))]
885   ""
886   "
887 {
888   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
889     abort ();
890
891   emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
892   emit_jump_insn (gen_flipped_cbranch (operands[0]));
893   DONE;
894 }")
895
896 (define_expand "bltu"
897   [(set (pc)
898         (if_then_else (ltu (cc0)
899                            (const_int 0))
900                       (label_ref (match_operand 0 "" ""))
901                       (pc)))]
902   ""
903   "
904 {
905   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
906     abort ();
907
908   emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
909   emit_jump_insn (gen_flipped_cbranch (operands[0]));
910   DONE;
911 }")
912
913 (define_expand "bgeu"
914   [(set (pc)
915         (if_then_else (geu (cc0)
916                            (const_int 0))
917                       (label_ref (match_operand 0 "" ""))
918                       (pc)))]
919   ""
920   "
921 {
922   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
923     abort ();
924
925   emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
926   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
927   DONE;
928 }")
929
930 (define_expand "bleu"
931   [(set (pc)
932         (if_then_else (leu (cc0)
933                            (const_int 0))
934                       (label_ref (match_operand 0 "" ""))
935                       (pc)))]
936   ""
937   "
938 {
939   if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
940     abort ();
941
942   emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
943   emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
944   DONE;
945 }")
946 \f
947 ;; Move instructions
948
949 ;; Note that source operands for `mov' pseudo-instructions are no longer
950 ;; allowed (by the svr4 assembler) to be "big" things, i.e. constants that
951 ;; won't fit in 16-bits.  (This includes any sort of a relocatable address
952 ;; also.)  Thus, we must use an explicit orh/or pair of instructions if
953 ;; the source operand is something "big".
954
955 (define_insn "movsi"
956   [(set (match_operand:SI 0 "general_operand" "=r,m,f")
957         (match_operand:SI 1 "general_operand" "rmif,rfJ,rmfJ"))]
958   ""
959   "*
960 {
961   if (GET_CODE (operands[0]) == MEM)
962     {
963       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
964         return output_store (operands);
965       if (FP_REG_P (operands[1]))
966         return \"fst.l %1,%0\";
967       return \"st.l %r1,%0\";
968     }
969   if (GET_CODE (operands[1]) == MEM)
970     {
971       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
972         return output_load (operands);
973       if (FP_REG_P (operands[0]))
974         return \"fld.l %1,%0\";
975       return \"ld.l %1,%0\";
976     }
977   if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
978     return \"fmov.ss %1,%0\";
979   if (FP_REG_P (operands[1]))
980     return \"fxfr %1,%0\";
981   if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
982     return \"fmov.ss %?f0,%0\";
983   if (FP_REG_P (operands[0]))
984     return \"ixfr %1,%0\";
985
986   if (GET_CODE (operands[1]) == REG)
987     return \"shl %?r0,%1,%0\";
988
989   CC_STATUS_PARTIAL_INIT;
990
991   if (GET_CODE (operands[1]) == CONST_INT)
992     {
993       if((INTVAL (operands[1]) & 0xffff0000) == 0)
994         return \"or %L1,%?r0,%0\";
995       if((INTVAL (operands[1]) & 0x0000ffff) == 0)
996         return \"orh %H1,%?r0,%0\";
997     }
998   return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
999 }")
1000  
1001 (define_insn "movhi"
1002   [(set (match_operand:HI 0 "general_operand" "=r,m,!*f,!r")
1003         (match_operand:HI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
1004   ""
1005   "*
1006 {
1007   if (GET_CODE (operands[0]) == MEM)
1008     {
1009       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1010         return output_store (operands);
1011       return \"st.s %r1,%0\";
1012     }
1013   if (GET_CODE (operands[1]) == MEM)
1014     {
1015       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1016         return output_load (operands);
1017       return \"ld.s %1,%0\";
1018     }
1019   if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
1020     return \"fmov.ss %1,%0\";
1021   if (FP_REG_P (operands[1]))
1022     return \"fxfr %1,%0\";
1023   if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
1024     return \"fmov.ss %?f0,%0\";
1025   if (FP_REG_P (operands[0]))
1026     return \"ixfr %1,%0\";
1027
1028   if (GET_CODE (operands[1]) == REG)
1029     return \"shl %?r0,%1,%0\";
1030
1031   CC_STATUS_PARTIAL_INIT;
1032
1033   return \"or %L1,%?r0,%0\";
1034 }")
1035
1036 (define_insn "movqi"
1037   [(set (match_operand:QI 0 "general_operand" "=r,m,!*f,!r")
1038         (match_operand:QI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
1039   ""
1040   "*
1041 {
1042   if (GET_CODE (operands[0]) == MEM)
1043     {
1044       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1045         return output_store (operands);
1046       return \"st.b %r1,%0\";
1047     }
1048   if (GET_CODE (operands[1]) == MEM)
1049     {
1050       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1051         return output_load (operands);
1052       return \"ld.b %1,%0\";
1053     }
1054   if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
1055     return \"fmov.ss %1,%0\";
1056   if (FP_REG_P (operands[1]))
1057     return \"fxfr %1,%0\";
1058   if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
1059     return \"fmov.ss %?f0,%0\";
1060   if (FP_REG_P (operands[0]))
1061     return \"ixfr %1,%0\";
1062
1063   if (GET_CODE (operands[1]) == REG)
1064     return \"shl %?r0,%1,%0\";
1065
1066   CC_STATUS_PARTIAL_INIT;
1067
1068   return \"or %L1,%?r0,%0\";
1069 }")
1070
1071 ;; The definition of this insn does not really explain what it does,
1072 ;; but it should suffice
1073 ;; that anything generated as this insn will be recognized as one
1074 ;; and that it won't successfully combine with anything.
1075 (define_expand "movstrsi"
1076   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1077                    (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1078               (use (match_operand:SI 2 "nonmemory_operand" ""))
1079               (use (match_operand:SI 3 "immediate_operand" ""))
1080               (clobber (match_dup 4))
1081               (clobber (match_dup 5))
1082               (clobber (match_dup 6))
1083               (clobber (match_dup 0))
1084               (clobber (match_dup 1))])]
1085   ""
1086   "
1087 {
1088   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1089   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1090   operands[4] = gen_reg_rtx (SImode);
1091   operands[5] = gen_reg_rtx (SImode);
1092   operands[6] = gen_reg_rtx (SImode);
1093 }")
1094
1095 (define_insn ""
1096   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
1097         (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1098    (use (match_operand:SI 2 "general_operand" "rn"))
1099    (use (match_operand:SI 3 "immediate_operand" "i"))
1100    (clobber (match_operand:SI 4 "register_operand" "=r"))
1101    (clobber (match_operand:SI 5 "register_operand" "=r"))
1102    (clobber (match_operand:SI 6 "register_operand" "=r"))
1103    (clobber (match_dup 0))
1104    (clobber (match_dup 1))]
1105   ""
1106   "* return output_block_move (operands);")
1107 \f
1108 ;; Floating point move insns
1109
1110 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1111 ;; to be reloaded by putting the constant into memory.
1112 ;; It must come before the more general movdf pattern.
1113 (define_insn ""
1114   [(set (match_operand:DF 0 "general_operand" "=r,f,o")
1115         (match_operand:DF 1 "" "mG,m,G"))]
1116   "GET_CODE (operands[1]) == CONST_DOUBLE"
1117   "*
1118 {
1119   if (FP_REG_P (operands[0]) || operands[1] == CONST0_RTX (DFmode))
1120     return output_fp_move_double (operands);
1121   return output_move_double (operands);
1122 }")
1123
1124 (define_insn "movdf"
1125   [(set (match_operand:DF 0 "general_operand" "=*rm,&*r,?f,?*rm")
1126         (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))]
1127   ""
1128   "*
1129 {
1130   if (GET_CODE (operands[0]) == MEM
1131       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1132     return output_store (operands);
1133   if (GET_CODE (operands[1]) == MEM
1134       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1135     return output_load (operands);
1136
1137   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1138     return output_fp_move_double (operands);
1139   return output_move_double (operands);
1140 }")
1141
1142 (define_insn "movdi"
1143   [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm")
1144         (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))]
1145   ""
1146   "*
1147 {
1148   if (GET_CODE (operands[0]) == MEM
1149       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1150     return output_store (operands);
1151   if (GET_CODE (operands[1]) == MEM
1152       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1153     return output_load (operands);
1154
1155   /* ??? How can we have a DFmode arg here with DImode above? */
1156   if (FP_REG_P (operands[0]) && operands[1] == CONST0_RTX (DFmode))
1157     return \"fmov.dd %?f0,%0\";
1158
1159   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1160     return output_fp_move_double (operands);
1161   return output_move_double (operands);
1162 }")
1163
1164 ;; The alternative m/r is separate from m/f
1165 ;; The first alternative is separate from the second for the same reason.
1166 (define_insn "movsf"
1167   [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m")
1168         (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))]
1169   ""
1170   "*
1171 {
1172   if (GET_CODE (operands[0]) == MEM
1173       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1174     return output_store (operands);
1175   if (GET_CODE (operands[1]) == MEM
1176       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1177     return output_load (operands);
1178   if (FP_REG_P (operands[0]))
1179     {
1180       if (FP_REG_P (operands[1]))
1181         return \"fmov.ss %1,%0\";
1182       if (GET_CODE (operands[1]) == REG)
1183         return \"ixfr %1,%0\";
1184       if (operands[1] == CONST0_RTX (SFmode))
1185         return \"fmov.ss %?f0,%0\";
1186       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1187         {
1188           if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1189                  && (cc_prev_status.flags & CC_HI_R31_ADJ)
1190                  && cc_prev_status.mdep == XEXP(operands[1],0)))
1191             {
1192               CC_STATUS_INIT;
1193               cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1194               cc_status.mdep = XEXP (operands[1], 0);
1195               return \"orh %h1,%?r0,%?r31\;fld.l %L1(%?r31),%0\";
1196             }
1197           return \"fld.l %L1(%?r31),%0\";
1198         }
1199       return \"fld.l %1,%0\";
1200     }
1201   if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
1202     {
1203       if (GET_CODE (operands[0]) == REG && FP_REG_P (operands[1]))
1204         return \"fxfr %1,%0\";
1205       if (GET_CODE (operands[0]) == REG)
1206         {
1207           CC_STATUS_PARTIAL_INIT;
1208           if (GET_CODE (operands[1]) == CONST_DOUBLE)
1209             {
1210               register unsigned long ul;
1211
1212               ul = sfmode_constant_to_ulong (operands[1]);
1213               if ((ul & 0x0000ffff) == 0)
1214                 return \"orh %H1,%?r0,%0\";
1215               if ((ul & 0xffff0000) == 0)
1216                 return \"or %L1,%?r0,%0\";
1217             }
1218           return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
1219         }
1220       /* Now operand 0 must be memory.
1221          If operand 1 is CONST_DOUBLE, its value must be 0.  */
1222       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1223         {
1224           if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1225                  && (cc_prev_status.flags & CC_HI_R31_ADJ)
1226                  && XEXP (operands[0], 0) == cc_prev_status.mdep))
1227             {
1228               CC_STATUS_INIT;
1229               cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1230               cc_status.mdep = XEXP (operands[0], 0);
1231               output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1232             }
1233           return \"fst.l %r1,%L0(%?r31)\";
1234         }
1235       return \"fst.l %r1,%0\";
1236     }
1237   if (GET_CODE (operands[0]) == MEM)
1238     return \"st.l %r1,%0\";
1239   if (GET_CODE (operands[1]) == MEM)
1240     return \"ld.l %1,%0\";
1241   if (operands[1] == CONST0_RTX (SFmode))
1242     return \"shl %?r0,%?r0,%0\";
1243   return \"mov %1,%0\";
1244 }")
1245 \f
1246 ;; Special load insns for REG+REG addresses.
1247 ;; Such addresses are not "legitimate" because st rejects them.
1248
1249 (define_insn ""
1250   [(set (match_operand:DF 0 "register_operand" "=rf")
1251         (match_operand:DF 1 "indexed_operand" "m"))]
1252   ""
1253   "*
1254 {
1255   if (FP_REG_P (operands[0]))
1256     return output_fp_move_double (operands);
1257   return output_move_double (operands);
1258 }")
1259
1260 (define_insn ""
1261   [(set (match_operand:SF 0 "register_operand" "=rf")
1262         (match_operand:SF 1 "indexed_operand" "m"))]
1263   ""
1264   "*
1265 {
1266   if (FP_REG_P (operands[0]))
1267     return \"fld.l %1,%0\";
1268   return \"ld.l %1,%0\";
1269 }")
1270
1271 (define_insn ""
1272   [(set (match_operand:SI 0 "register_operand" "=rf")
1273         (match_operand:SI 1 "indexed_operand" "m"))]
1274   ""
1275   "*
1276 {
1277   if (FP_REG_P (operands[0]))
1278     return \"fld.l %1,%0\";
1279   return \"ld.l %1,%0\";
1280 }")
1281
1282 (define_insn ""
1283   [(set (match_operand:HI 0 "register_operand" "=r")
1284         (match_operand:HI 1 "indexed_operand" "m"))]
1285   ""
1286   "ld.s %1,%0")
1287
1288 (define_insn ""
1289   [(set (match_operand:QI 0 "register_operand" "=r")
1290         (match_operand:QI 1 "indexed_operand" "m"))]
1291   ""
1292   "ld.b %1,%0")
1293
1294 ;; Likewise for floating-point store insns.
1295
1296 (define_insn ""
1297   [(set (match_operand:DF 0 "indexed_operand" "=m")
1298         (match_operand:DF 1 "register_operand" "f"))]
1299   ""
1300   "fst.d %1,%0")
1301
1302 (define_insn ""
1303   [(set (match_operand:SF 0 "indexed_operand" "=m")
1304         (match_operand:SF 1 "register_operand" "f"))]
1305   ""
1306   "fst.l %1,%0")
1307 \f
1308 ;;- truncation instructions
1309 (define_insn "truncsiqi2"
1310   [(set (match_operand:QI 0 "general_operand" "=g")
1311         (truncate:QI
1312          (match_operand:SI 1 "register_operand" "r")))]
1313   ""
1314   "*
1315 {
1316   if (GET_CODE (operands[0]) == MEM)
1317     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1318       {
1319         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1320                && (cc_prev_status.flags & CC_HI_R31_ADJ)
1321                && XEXP (operands[0], 0) == cc_prev_status.mdep))
1322           {
1323             CC_STATUS_INIT;
1324             cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1325             cc_status.mdep = XEXP (operands[0], 0);
1326             output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1327           }
1328         return \"st.b %1,%L0(%?r31)\";
1329       }
1330     else
1331       return \"st.b %1,%0\";
1332   return \"shl %?r0,%1,%0\";
1333 }")
1334
1335 (define_insn "trunchiqi2"
1336   [(set (match_operand:QI 0 "general_operand" "=g")
1337         (truncate:QI
1338          (match_operand:HI 1 "register_operand" "r")))]
1339   ""
1340   "*
1341 {
1342   if (GET_CODE (operands[0]) == MEM)
1343     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1344       {
1345         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1346                && (cc_prev_status.flags & CC_HI_R31_ADJ)
1347                && XEXP (operands[0], 0) == cc_prev_status.mdep))
1348           {
1349             CC_STATUS_INIT;
1350             cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1351             cc_status.mdep = XEXP (operands[0], 0);
1352             output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1353           }
1354         return \"st.b %1,%L0(%?r31)\";
1355       }
1356     else
1357       return \"st.b %1,%0\";
1358   return \"shl %?r0,%1,%0\";
1359 }")
1360
1361 (define_insn "truncsihi2"
1362   [(set (match_operand:HI 0 "general_operand" "=g")
1363         (truncate:HI
1364          (match_operand:SI 1 "register_operand" "r")))]
1365   ""
1366   "*
1367 {
1368   if (GET_CODE (operands[0]) == MEM)
1369     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1370       {
1371         if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1372                && (cc_prev_status.flags & CC_HI_R31_ADJ)
1373                && XEXP (operands[0], 0) == cc_prev_status.mdep))
1374           {
1375             CC_STATUS_INIT;
1376             cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1377             cc_status.mdep = XEXP (operands[0], 0);
1378             output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1379           }
1380         return \"st.s %1,%L0(%?r31)\";
1381       }
1382     else
1383       return \"st.s %1,%0\";
1384   return \"shl %?r0,%1,%0\";
1385 }")
1386 \f
1387 ;;- zero extension instructions
1388
1389 (define_insn "zero_extendhisi2"
1390   [(set (match_operand:SI 0 "register_operand" "=r")
1391         (zero_extend:SI
1392          (match_operand:HI 1 "register_operand" "r")))]
1393   ""
1394   "*
1395 {
1396   CC_STATUS_PARTIAL_INIT;
1397   return \"and 0xffff,%1,%0\";
1398 }")
1399
1400 (define_insn "zero_extendqihi2"
1401   [(set (match_operand:HI 0 "register_operand" "=r")
1402         (zero_extend:HI
1403          (match_operand:QI 1 "register_operand" "r")))]
1404   ""
1405   "*
1406 {
1407   CC_STATUS_PARTIAL_INIT;
1408   return \"and 0xff,%1,%0\";
1409 }")
1410
1411 (define_insn "zero_extendqisi2"
1412   [(set (match_operand:SI 0 "register_operand" "=r")
1413         (zero_extend:SI
1414          (match_operand:QI 1 "register_operand" "r")))]
1415   ""
1416   "*
1417 {
1418   CC_STATUS_PARTIAL_INIT;
1419   return \"and 0xff,%1,%0\";
1420 }")
1421 \f
1422 ;; Sign extension instructions.
1423
1424 (define_insn ""
1425   [(set (match_operand:SI 0 "register_operand" "=r")
1426         (sign_extend:SI
1427          (match_operand:HI 1 "indexed_operand" "m")))]
1428   ""
1429   "ld.s %1,%0")
1430
1431 (define_insn ""
1432   [(set (match_operand:HI 0 "register_operand" "=r")
1433         (sign_extend:HI
1434          (match_operand:QI 1 "indexed_operand" "m")))]
1435   ""
1436   "ld.b %1,%0")
1437
1438 (define_insn ""
1439   [(set (match_operand:SI 0 "register_operand" "=r")
1440         (sign_extend:SI
1441          (match_operand:QI 1 "indexed_operand" "m")))]
1442   ""
1443   "ld.b %1,%0")
1444
1445 (define_insn "extendhisi2"
1446   [(set (match_operand:SI 0 "register_operand" "=r")
1447         (sign_extend:SI
1448          (match_operand:HI 1 "nonimmediate_operand" "mr")))]
1449   ""
1450   "*
1451 {
1452   if (REG_P (operands[1]))
1453     return \"shl 16,%1,%0\;shra 16,%0,%0\";
1454   if (GET_CODE (operands[1]) == CONST_INT)
1455     abort ();
1456   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1457     {
1458       CC_STATUS_INIT;
1459       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1460       cc_status.mdep = XEXP (operands[1], 0);
1461       return \"orh %h1,%?r0,%?r31\;ld.s %L1(%?r31),%0\";
1462     }
1463   else
1464     return \"ld.s %1,%0\";
1465 }")
1466
1467 (define_insn "extendqihi2"
1468   [(set (match_operand:HI 0 "register_operand" "=r")
1469         (sign_extend:HI
1470          (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1471   ""
1472   "*
1473 {
1474   if (REG_P (operands[1]))
1475     return \"shl 24,%1,%0\;shra 24,%0,%0\";
1476   if (GET_CODE (operands[1]) == CONST_INT)
1477     abort ();
1478   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1479     {
1480       CC_STATUS_INIT;
1481       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1482       cc_status.mdep = XEXP (operands[1], 0);
1483       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1484     }
1485   else
1486     return \"ld.b %1,%0\";
1487 }")
1488
1489 (define_insn "extendqisi2"
1490   [(set (match_operand:SI 0 "register_operand" "=r")
1491         (sign_extend:SI
1492          (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1493   ""
1494   "*
1495 {
1496   if (REG_P (operands[1]))
1497     return \"shl 24,%1,%0\;shra 24,%0,%0\";
1498   if (GET_CODE (operands[1]) == CONST_INT)
1499     abort ();
1500   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1501     {
1502       CC_STATUS_INIT;
1503       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1504       cc_status.mdep = XEXP (operands[1], 0);
1505       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1506     }
1507   else
1508     return \"ld.b %1,%0\";
1509 }")
1510
1511 ;; Signed bitfield extractions come out looking like
1512 ;;      (shiftrt (sign_extend (shift <Y> <C1>)) <C2>)
1513 ;; which we expand poorly as four shift insns.
1514 ;; These patters yeild two shifts:
1515 ;;      (shiftrt (shift <Y> <C3>) <C4>)
1516 (define_insn ""
1517   [(set (match_operand:SI 0 "register_operand" "=r")
1518         (ashiftrt:SI
1519          (sign_extend:SI
1520           (match_operand:QI 1 "register_operand" "r"))
1521          (match_operand:SI 2 "logic_int" "n")))]
1522   "INTVAL (operands[2]) < 8"
1523   "*
1524 {
1525   return \"shl 24,%1,%0\;shra 24+%2,%0,%0\";
1526 }")
1527
1528 (define_insn ""
1529   [(set (match_operand:SI 0 "register_operand" "=r")
1530         (ashiftrt:SI
1531          (sign_extend:SI
1532           (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1533                                 (match_operand:SI 2 "logic_int" "n")) 0))
1534          (match_operand:SI 3 "logic_int" "n")))]
1535   "INTVAL (operands[3]) < 8"
1536   "*
1537 {
1538   return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1539 }")
1540
1541 (define_insn ""
1542   [(set (match_operand:SI 0 "register_operand" "=r")
1543         (ashiftrt:SI
1544          (sign_extend:SI
1545           (ashift:QI (match_operand:QI 1 "register_operand" "r")
1546                      (match_operand:QI 2 "logic_int" "n")))
1547          (match_operand:SI 3 "logic_int" "n")))]
1548   "INTVAL (operands[3]) < 8"
1549   "*
1550 {
1551   return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1552 }")
1553 \f
1554 ;; Special patterns for optimizing bit-field instructions.
1555
1556 ;; First two patterns are for bitfields that came from memory
1557 ;; testing only the high bit.  They work with old combiner.
1558
1559 (define_insn ""
1560   [(set (cc0)
1561         (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1562                                                     (const_int 7)) 0))
1563             (const_int 0)))]
1564   ""
1565   "*
1566 {
1567   CC_STATUS_PARTIAL_INIT;
1568   return \"and 128,%0,%?r0\";
1569 }")
1570
1571 (define_insn ""
1572   [(set (cc0)
1573         (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1574                                                     (const_int 7)) 0))
1575             (const_int 0)))]
1576   ""
1577   "*
1578 {
1579   CC_STATUS_PARTIAL_INIT;
1580   return \"and 128,%0,%?r0\";
1581 }")
1582
1583 ;; next two patterns are good for bitfields coming from memory
1584 ;; (via pseudo-register) or from a register, though this optimization
1585 ;; is only good for values contained wholly within the bottom 13 bits
1586 (define_insn ""
1587   [(set (cc0)
1588         (eq 
1589          (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1590                               (match_operand:SI 1 "logic_int" "n"))
1591                  (match_operand:SI 2 "logic_int" "n"))
1592          (const_int 0)))]
1593   "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1594   "*
1595 {
1596   CC_STATUS_PARTIAL_INIT;
1597   operands[2] = gen_rtx (CONST_INT, VOIDmode,
1598                          (INTVAL (operands[2]) << INTVAL (operands[1])));
1599   return \"and %2,%0,%?r0\";
1600 }")
1601
1602 (define_insn ""
1603   [(set (cc0)
1604         (eq 
1605          (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1606                               (match_operand:SI 1 "logic_int" "n"))
1607                  (match_operand:SI 2 "logic_int" "n"))
1608          (const_int 0)))]
1609   "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1610   "*
1611 {
1612   CC_STATUS_PARTIAL_INIT;
1613   operands[2] = gen_rtx (CONST_INT, VOIDmode,
1614                          (INTVAL (operands[2]) << INTVAL (operands[1])));
1615   return \"and %2,%0,%?r0\";
1616 }")
1617 \f
1618 ;; Conversions between float and double.
1619
1620 (define_insn "extendsfdf2"
1621   [(set (match_operand:DF 0 "register_operand" "=f")
1622         (float_extend:DF
1623          (match_operand:SF 1 "register_operand" "f")))]
1624   ""
1625   "fmov.sd %1,%0")
1626
1627 (define_insn "truncdfsf2"
1628   [(set (match_operand:SF 0 "register_operand" "=f")
1629         (float_truncate:SF
1630          (match_operand:DF 1 "register_operand" "f")))]
1631   ""
1632   "fmov.ds %1,%0")
1633 \f
1634 ;; Conversion between fixed point and floating point.
1635 ;; Note that among the fix-to-float insns
1636 ;; the ones that start with SImode come first.
1637 ;; That is so that an operand that is a CONST_INT
1638 ;; (and therefore lacks a specific machine mode).
1639 ;; will be recognized as SImode (which is always valid)
1640 ;; rather than as QImode or HImode.
1641
1642 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
1643 ;; to be reloaded by putting the constant into memory.
1644 ;; It must come before the more general floatsisf2 pattern.
1645 (define_expand "floatsidf2"
1646   [(set (match_dup 2) (match_dup 3))
1647    (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "")
1648                               (const_int -2147483648)))
1649    (set (match_dup 5) (match_dup 3))
1650    (set (subreg:SI (match_dup 5) 0) (match_dup 4))
1651    (set (match_operand:DF 0 "register_operand" "")
1652         (minus:DF (match_dup 5) (match_dup 2)))]
1653   ""
1654   "
1655 {
1656   REAL_VALUE_TYPE d;
1657   /* 4503601774854144 is  (1 << 30) * ((1 << 22) + (1 << 1)).  */
1658   d = REAL_VALUE_ATOF (\"4503601774854144\");
1659   operands[2] = gen_reg_rtx (DFmode);
1660   operands[3] = CONST_DOUBLE_FROM_REAL_VALUE (d, DFmode);
1661   operands[4] = gen_reg_rtx (SImode);
1662   operands[5] = gen_reg_rtx (DFmode);
1663 }")
1664 \f
1665 ;; Floating to fixed conversion.
1666
1667 (define_expand "fix_truncdfsi2"
1668   ;; This first insn produces a double-word value
1669   ;; in which only the low word is valid.
1670   [(set (match_dup 2)
1671         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1672    (set (match_operand:SI 0 "register_operand" "=f")
1673         (subreg:SI (match_dup 2) 0))]
1674   ""
1675   "
1676 {
1677   operands[2] = gen_reg_rtx (DImode);
1678 }")
1679
1680 ;; Recognize the first insn generated above.
1681 ;; This RTL looks like a fix_truncdfdi2 insn,
1682 ;; but we dont call it that, because only 32 bits
1683 ;; of the result are valid.
1684 ;; This pattern will work for the intended purposes 
1685 ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2.
1686 (define_insn ""
1687   [(set (match_operand:DI 0 "register_operand" "=f")
1688         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1689   ""
1690   "ftrunc.dd %1,%0")
1691
1692 (define_expand "fix_truncsfsi2"
1693   ;; This first insn produces a double-word value
1694   ;; in which only the low word is valid.
1695   [(set (match_dup 2)
1696         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
1697    (set (match_operand:SI 0 "register_operand" "=f")
1698         (subreg:SI (match_dup 2) 0))]
1699   ""
1700   "
1701 {
1702   operands[2] = gen_reg_rtx (DImode);
1703 }")
1704
1705 ;; Recognize the first insn generated above.
1706 ;; This RTL looks like a fix_truncsfdi2 insn,
1707 ;; but we dont call it that, because only 32 bits
1708 ;; of the result are valid.
1709 ;; This pattern will work for the intended purposes 
1710 ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2.
1711 (define_insn ""
1712   [(set (match_operand:DI 0 "register_operand" "=f")
1713         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1714   ""
1715   "ftrunc.sd %1,%0")
1716 \f
1717 ;;- arithmetic instructions
1718
1719 (define_insn "addsi3"
1720   [(set (match_operand:SI 0 "register_operand" "=r,*f")
1721         (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f")
1722                  (match_operand:SI 2 "arith_operand" "rI,*f")))]
1723   ""
1724   "*
1725 {
1726   if (which_alternative == 1)
1727     return \"fiadd.ss %2,%1,%0\";
1728   CC_STATUS_PARTIAL_INIT;
1729   return \"addu %2,%1,%0\";
1730 }")
1731
1732 (define_insn "adddi3"
1733   [(set (match_operand:DI 0 "register_operand" "=f")
1734         (plus:DI (match_operand:DI 1 "register_operand" "%f")
1735                  (match_operand:DI 2 "register_operand" "f")))]
1736   ""
1737   "fiadd.dd %1,%2,%0")
1738
1739 (define_insn "subsi3"
1740   [(set (match_operand:SI 0 "register_operand" "=r,r,*f")
1741         (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f")
1742                   (match_operand:SI 2 "arith_operand" "rI,r,*f")))]
1743   ""
1744   "*
1745 {
1746   if (which_alternative == 2)
1747     return \"fisub.ss %1,%2,%0\";
1748   CC_STATUS_PARTIAL_INIT;
1749   if (REG_P (operands[2]))
1750     return \"subu %1,%2,%0\";
1751   operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
1752   return \"addu %2,%1,%0\";
1753 }")
1754
1755 (define_insn "subdi3"
1756   [(set (match_operand:DI 0 "register_operand" "=f")
1757         (minus:DI (match_operand:DI 1 "register_operand" "%f")
1758                   (match_operand:DI 2 "register_operand" "f")))]
1759   ""
1760   "fisub.dd %1,%2,%0")
1761
1762 (define_expand "mulsi3"
1763   [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1764    (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1765    (clobber (match_dup 3))
1766    (set (subreg:SI (match_dup 3) 0)
1767         (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1768    (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1769   ""
1770   "
1771 {
1772   operands[3] = gen_reg_rtx (DImode);
1773   operands[4] = gen_reg_rtx (DImode);
1774   operands[5] = gen_reg_rtx (DImode);
1775 }")
1776
1777 (define_insn ""
1778   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
1779         (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
1780                  (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
1781   ""
1782   "fmlow.dd %2,%1,%0")
1783 \f
1784 ;;- and instructions (with compliment also)                        
1785 (define_insn "andsi3"
1786   [(set (match_operand:SI 0 "register_operand" "=r")
1787         (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1788                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1789   ""
1790   "*
1791 {
1792   rtx xop[3];
1793
1794   CC_STATUS_PARTIAL_INIT;
1795   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1796     return \"and %2,%1,%0\";
1797   if ((INTVAL (operands[2]) & 0xffff) == 0)
1798     {
1799       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1800                              (unsigned) INTVAL (operands[2]) >> 16);
1801       return \"andh %2,%1,%0\";
1802     }
1803   xop[0] = operands[0];
1804   xop[1] = operands[1];
1805   xop[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]) & 0xffff);
1806   output_asm_insn (\"andnot %2,%1,%0\", xop);
1807   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1808                          ~(unsigned) INTVAL (operands[2]) >> 16);
1809   return \"andnoth %2,%0,%0\";
1810 }")
1811
1812 (define_insn ""
1813   [(set (match_operand:SI 0 "register_operand" "=r")
1814         (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn"))
1815                 (match_operand:SI 2 "register_operand" "r")))]
1816   ""
1817   "*
1818 {
1819   rtx xop[3];
1820
1821   CC_STATUS_PARTIAL_INIT;
1822   if (REG_P (operands[1]) || LOGIC_INT (operands[1]))
1823     return \"andnot %1,%2,%0\";
1824   if ((INTVAL (operands[1]) & 0xffff) == 0)
1825     {
1826       operands[1] = gen_rtx (CONST_INT, VOIDmode, 
1827                              (unsigned) INTVAL (operands[1]) >> 16);
1828       return \"andnoth %1,%2,%0\";
1829     }
1830   xop[0] = operands[0];
1831   xop[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) & 0xffff));
1832   xop[2] = operands[2];
1833   output_asm_insn (\"andnot %1,%2,%0\", xop);
1834   operands[1] = gen_rtx (CONST_INT, VOIDmode, 
1835                          (unsigned) INTVAL (operands[1]) >> 16);
1836   return \"andnoth %1,%0,%0\";
1837 }")
1838
1839 (define_insn "iorsi3"
1840   [(set (match_operand:SI 0 "register_operand" "=r")
1841         (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1842                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1843   ""
1844   "*
1845 {
1846   rtx xop[3];
1847
1848   CC_STATUS_PARTIAL_INIT;
1849   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1850     return \"or %2,%1,%0\";
1851   if ((INTVAL (operands[2]) & 0xffff) == 0)
1852     {
1853       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1854                              (unsigned) INTVAL (operands[2]) >> 16);
1855       return \"orh %2,%1,%0\";
1856     }
1857   xop[0] = operands[0];
1858   xop[1] = operands[1];
1859   xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1860   output_asm_insn (\"or %2,%1,%0\", xop);
1861   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1862                          (unsigned) INTVAL (operands[2]) >> 16);
1863   return \"orh %2,%0,%0\";
1864 }")
1865
1866 (define_insn "xorsi3"
1867   [(set (match_operand:SI 0 "register_operand" "=r")
1868         (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1869                 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1870   ""
1871   "*
1872 {
1873   rtx xop[3];
1874
1875   CC_STATUS_PARTIAL_INIT;
1876   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1877     return \"xor %2,%1,%0\";
1878   if ((INTVAL (operands[2]) & 0xffff) == 0)
1879     {
1880       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1881                              (unsigned) INTVAL (operands[2]) >> 16);
1882       return \"xorh %2,%1,%0\";
1883     }
1884   xop[0] = operands[0];
1885   xop[1] = operands[1];
1886   xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1887   output_asm_insn (\"xor %2,%1,%0\", xop);
1888   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
1889                          (unsigned) INTVAL (operands[2]) >> 16);
1890   return \"xorh %2,%0,%0\";
1891 }")
1892
1893 ;(The i860 instruction set doesn't allow an immediate second operand in
1894 ; a subtraction.)
1895 (define_insn "negsi2"
1896   [(set (match_operand:SI 0 "general_operand" "=r")
1897         (neg:SI (match_operand:SI 1 "arith_operand" "r")))]
1898   ""
1899   "*
1900 {
1901   CC_STATUS_PARTIAL_INIT;
1902   return \"subu %?r0,%1,%0\";
1903 }")
1904
1905 (define_insn "one_cmplsi2"
1906   [(set (match_operand:SI 0 "general_operand" "=r")
1907         (not:SI (match_operand:SI 1 "arith_operand" "r")))]
1908   ""
1909   "*
1910 {
1911   CC_STATUS_PARTIAL_INIT;
1912   return \"subu -1,%1,%0\";
1913 }")
1914 \f
1915 ;; Floating point arithmetic instructions.
1916
1917 (define_insn "adddf3"
1918   [(set (match_operand:DF 0 "register_operand" "=f")
1919         (plus:DF (match_operand:DF 1 "register_operand" "f")
1920                  (match_operand:DF 2 "register_operand" "f")))]
1921   ""
1922   "fadd.dd %1,%2,%0")
1923
1924 (define_insn "addsf3"
1925   [(set (match_operand:SF 0 "register_operand" "=f")
1926         (plus:SF (match_operand:SF 1 "register_operand" "f")
1927                  (match_operand:SF 2 "register_operand" "f")))]
1928   ""
1929   "fadd.ss %1,%2,%0")
1930
1931 (define_insn "subdf3"
1932   [(set (match_operand:DF 0 "register_operand" "=f")
1933         (minus:DF (match_operand:DF 1 "register_operand" "f")
1934                   (match_operand:DF 2 "register_operand" "f")))]
1935   ""
1936   "fsub.dd %1,%2,%0")
1937
1938 (define_insn "subsf3"
1939   [(set (match_operand:SF 0 "register_operand" "=f")
1940         (minus:SF (match_operand:SF 1 "register_operand" "f")
1941                   (match_operand:SF 2 "register_operand" "f")))]
1942   ""
1943   "fsub.ss %1,%2,%0")
1944
1945 (define_insn "muldf3"
1946   [(set (match_operand:DF 0 "register_operand" "=f")
1947         (mult:DF (match_operand:DF 1 "register_operand" "f")
1948                  (match_operand:DF 2 "register_operand" "f")))]
1949   ""
1950   "fmul.dd %1,%2,%0")
1951
1952 (define_insn "mulsf3"
1953   [(set (match_operand:SF 0 "register_operand" "=f")
1954         (mult:SF (match_operand:SF 1 "register_operand" "f")
1955                  (match_operand:SF 2 "register_operand" "f")))]
1956   ""
1957   "fmul.ss %1,%2,%0")
1958
1959 (define_insn "negdf2"
1960   [(set (match_operand:DF 0 "register_operand" "=f")
1961         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1962   ""
1963   "fsub.dd %?f0,%1,%0")
1964
1965 (define_insn "negsf2"
1966   [(set (match_operand:SF 0 "register_operand" "=f")
1967         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1968   ""
1969   "fsub.ss %?f0,%1,%0")
1970 \f
1971 (define_insn "divdf3"
1972   [(set (match_operand:DF 0 "register_operand" "=&f")
1973         (div:DF (match_operand:DF 1 "register_operand" "f")
1974                  (match_operand:DF 2 "register_operand" "f")))
1975    (clobber (match_scratch:DF 3 "=&f"))
1976    (clobber (match_scratch:DF 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       return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1989 orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1990 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1991 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1992 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1993     }
1994   else
1995     return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1996 ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1997 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1998 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1999 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
2000 }")
2001
2002 (define_insn "divsf3"
2003   [(set (match_operand:SF 0 "register_operand" "=&f")
2004         (div:SF (match_operand:SF 1 "register_operand" "f")
2005                  (match_operand:SF 2 "register_operand" "f")))
2006    (clobber (match_scratch:SF 3 "=&f"))
2007    (clobber (match_scratch:SF 4 "=&f"))]
2008   ""
2009   "*
2010 {
2011   CC_STATUS_PARTIAL_INIT;
2012   if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
2013       || (cc_prev_status.flags & CC_HI_R31_ADJ)
2014       || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
2015     {
2016       cc_status.flags |= CC_KNOW_HI_R31;
2017       cc_status.flags &= ~CC_HI_R31_ADJ;
2018       cc_status.mdep = CONST2_RTX (SFmode);
2019       output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands);
2020     }
2021   return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\\
2022 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\\
2023 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\\
2024 fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\";
2025 }")
2026 \f
2027 ;; Shift instructions
2028
2029 ;; Optimized special case of shifting.
2030 ;; Must precede the general case.
2031
2032 (define_insn ""
2033   [(set (match_operand:SI 0 "register_operand" "=r")
2034         (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2035                      (const_int 24)))]
2036   ""
2037   "*
2038 {
2039   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
2040     {
2041       CC_STATUS_INIT;
2042       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
2043       cc_status.mdep = XEXP (operands[1], 0);
2044       return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
2045     }
2046   return \"ld.b %1,%0\";
2047 }")
2048
2049 \f
2050 ;;- arithmetic shift instructions
2051 (define_insn "ashlsi3"
2052   [(set (match_operand:SI 0 "register_operand" "=r")
2053         (ashift:SI (match_operand:SI 1 "register_operand" "r")
2054                    (match_operand:SI 2 "shift_operand" "rn")))]
2055   ""
2056   "*
2057 {
2058   return \"shl %2,%1,%0\";
2059 }")
2060
2061 (define_insn "ashlhi3"
2062   [(set (match_operand:HI 0 "register_operand" "=r")
2063         (ashift:HI (match_operand:HI 1 "register_operand" "r")
2064                    (match_operand:HI 2 "shift_operand" "rn")))]
2065   ""
2066   "*
2067 {
2068   return \"shl %2,%1,%0\";
2069 }")
2070
2071 (define_insn "ashlqi3"
2072   [(set (match_operand:QI 0 "register_operand" "=r")
2073         (ashift:QI (match_operand:QI 1 "register_operand" "r")
2074                    (match_operand:QI 2 "shift_operand" "rn")))]
2075   ""
2076   "*
2077 {
2078   return \"shl %2,%1,%0\";
2079 }")
2080
2081 (define_insn "ashrsi3"
2082   [(set (match_operand:SI 0 "register_operand" "=r")
2083         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2084                      (match_operand:SI 2 "shift_operand" "rn")))]
2085   ""
2086   "*
2087 {
2088   return \"shra %2,%1,%0\";
2089 }")
2090
2091 (define_insn "lshrsi3"
2092   [(set (match_operand:SI 0 "register_operand" "=r")
2093         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2094                      (match_operand:SI 2 "shift_operand" "rn")))]
2095   ""
2096   "*
2097 {
2098   return \"shr %2,%1,%0\";
2099 }")
2100 \f
2101 ;; Unconditional and other jump instructions
2102
2103 (define_insn "jump"
2104   [(set (pc) (label_ref (match_operand 0 "" "")))]
2105   ""
2106   "*
2107 {
2108   return \"br %l0\;nop\";
2109 }")
2110
2111 ;; Here are two simple peepholes which fill the delay slot of
2112 ;; an unconditional branch.
2113
2114 (define_peephole
2115   [(set (match_operand:SI 0 "register_operand" "=rf")
2116         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2117    (set (pc) (label_ref (match_operand 2 "" "")))]
2118   ""
2119   "* return output_delayed_branch (\"br %l2\", operands, insn);")
2120
2121 (define_peephole
2122   [(set (match_operand:SI 0 "memory_operand" "=m")
2123         (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2124    (set (pc) (label_ref (match_operand 2 "" "")))]
2125   ""
2126   "* return output_delayed_branch (\"br %l2\", operands, insn);")
2127
2128 (define_insn "tablejump"
2129   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2130    (use (label_ref (match_operand 1 "" "")))]
2131   ""
2132   "bri %0\;nop")
2133
2134 (define_peephole
2135   [(set (match_operand:SI 0 "memory_operand" "=m")
2136         (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2137    (set (pc) (match_operand:SI 2 "register_operand" "r"))
2138    (use (label_ref (match_operand 3 "" "")))]
2139   ""
2140   "* return output_delayed_branch (\"bri %2\", operands, insn);")
2141
2142 ;;- jump to subroutine
2143 (define_expand "call"
2144   [(call (match_operand:SI 0 "memory_operand" "m")
2145          (match_operand 1 "" "i"))]
2146   ;; operand[2] is next_arg_register
2147   ""
2148   "
2149 {
2150   if (INTVAL (operands[1]) > 0)
2151     {
2152       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2153       emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2154     }
2155 }")
2156
2157 ;;- jump to subroutine
2158 (define_insn ""
2159   [(call (match_operand:SI 0 "memory_operand" "m")
2160          (match_operand 1 "" "i"))]
2161   ;; operand[2] is next_arg_register
2162   ""
2163   "*
2164 {
2165   /* strip the MEM.  */
2166   operands[0] = XEXP (operands[0], 0);
2167   CC_STATUS_INIT;
2168   if (GET_CODE (operands[0]) == REG)
2169     return \"calli %0\;nop\";
2170   return \"call %0\;nop\";
2171 }")
2172
2173 (define_peephole
2174   [(set (match_operand:SI 0 "register_operand" "=rf")
2175         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2176    (call (match_operand:SI 2 "memory_operand" "m")
2177          (match_operand 3 "" "i"))]
2178   ;;- Don't use operand 1 for most machines.
2179   "! reg_mentioned_p (operands[0], operands[2])"
2180   "*
2181 {
2182   /* strip the MEM.  */
2183   operands[2] = XEXP (operands[2], 0);
2184   if (GET_CODE (operands[2]) == REG)
2185     return output_delayed_branch (\"calli %2\", operands, insn);
2186   return output_delayed_branch (\"call %2\", operands, insn);
2187 }")
2188
2189 (define_peephole
2190   [(set (match_operand:SI 0 "memory_operand" "=m")
2191         (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2192    (call (match_operand:SI 2 "memory_operand" "m")
2193          (match_operand 3 "" "i"))]
2194   ;;- Don't use operand 1 for most machines.
2195   ""
2196   "*
2197 {
2198   /* strip the MEM.  */
2199   operands[2] = XEXP (operands[2], 0);
2200   if (GET_CODE (operands[2]) == REG)
2201     return output_delayed_branch (\"calli %2\", operands, insn);
2202   return output_delayed_branch (\"call %2\", operands, insn);
2203 }")
2204
2205 (define_expand "call_value"
2206   [(set (match_operand 0 "register_operand" "=rf")
2207         (call (match_operand:SI 1 "memory_operand" "m")
2208               (match_operand 2 "" "i")))]
2209   ;; operand 3 is next_arg_register
2210   ""
2211   "
2212 {
2213   if (INTVAL (operands[2]) > 0)
2214     {
2215       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2216       emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2217     }
2218 }")
2219
2220 (define_insn ""
2221   [(set (match_operand 0 "register_operand" "=rf")
2222         (call (match_operand:SI 1 "memory_operand" "m")
2223               (match_operand 2 "" "i")))]
2224   ;; operand 3 is next_arg_register
2225   ""
2226   "*
2227 {
2228   /* strip the MEM.  */
2229   operands[1] = XEXP (operands[1], 0);
2230   CC_STATUS_INIT;
2231   if (GET_CODE (operands[1]) == REG)
2232     return \"calli %1\;nop\";
2233   return \"call %1\;nop\";
2234 }")
2235
2236 (define_peephole
2237   [(set (match_operand:SI 0 "register_operand" "=rf")
2238         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2239    (set (match_operand 2 "" "=rf")
2240         (call (match_operand:SI 3 "memory_operand" "m")
2241               (match_operand 4 "" "i")))]
2242   ;;- Don't use operand 4 for most machines.
2243   "! reg_mentioned_p (operands[0], operands[3])"
2244   "*
2245 {
2246   /* strip the MEM.  */
2247   operands[3] = XEXP (operands[3], 0);
2248   if (GET_CODE (operands[3]) == REG)
2249     return output_delayed_branch (\"calli %3\", operands, insn);
2250   return output_delayed_branch (\"call %3\", operands, insn);
2251 }")
2252
2253 (define_peephole
2254   [(set (match_operand:SI 0 "memory_operand" "=m")
2255         (match_operand:SI 1 "reg_or_0_operand" "rJf"))
2256    (set (match_operand 2 "" "=rf")
2257         (call (match_operand:SI 3 "memory_operand" "m")
2258               (match_operand 4 "" "i")))]
2259   ;;- Don't use operand 4 for most machines.
2260   ""
2261   "*
2262 {
2263   /* strip the MEM.  */
2264   operands[3] = XEXP (operands[3], 0);
2265   if (GET_CODE (operands[3]) == REG)
2266     return output_delayed_branch (\"calli %3\", operands, insn);
2267   return output_delayed_branch (\"call %3\", operands, insn);
2268 }")
2269 \f
2270 (define_insn "nop"
2271   [(const_int 0)]
2272   ""
2273   "nop")
2274
2275 (define_insn "indirect_jump"
2276   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2277   ""
2278   "bri %0")
2279 \f
2280 ;;
2281 ;; A special insn that does the work to get setup just
2282 ;; before a table jump.
2283 ;;
2284 (define_insn ""
2285   [(set (match_operand:SI 0 "register_operand" "=r")
2286         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2287                          (label_ref (match_operand 2 "" "")))))]
2288   ""
2289   "*
2290 {
2291   CC_STATUS_INIT;
2292   return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\";
2293 }")
2294   
2295 (define_peephole
2296   [(set (match_operand:SI 0 "register_operand" "=rf")
2297         (match_operand:SI 1 "single_insn_src_p" "gfG"))
2298    (set (pc) (match_operand:SI 2 "register_operand" "r"))
2299    (use (label_ref (match_operand 3 "" "")))]
2300   "REGNO (operands[0]) != REGNO (operands[2])"
2301   "* return output_delayed_branch (\"bri %2\", operands, insn);")
2302 \f
2303 ;;- Local variables:
2304 ;;- mode:emacs-lisp
2305 ;;- comment-start: ";;- "
2306 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2307 ;;- eval: (modify-syntax-entry ?[ "(]")
2308 ;;- eval: (modify-syntax-entry ?] ")[")
2309 ;;- eval: (modify-syntax-entry ?{ "(}")
2310 ;;- eval: (modify-syntax-entry ?} "){")
2311 ;;- End:
2312