OSDN Git Service

* ginclude/varargs.h: Replace with stub which issues #error.
[pf3gnuchains/gcc-fork.git] / gcc / config / i960 / i960.md
1 ;;- Machine description for Intel 80960 chip for GNU C compiler
2 ;;   Copyright (C) 1992, 1995, 1998, 2001 Free Software Foundation, Inc.
3 ;;   Contributed by Steven McGeady, Intel Corp.
4 ;;   Additional work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson
5 ;;   Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support.
6
7 ;; This file is part of GNU CC.
8
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 \f
26 ;; There are very few (4) 'f' registers, they can't be loaded/stored from/to
27 ;; memory, and some instructions explicitly require them, so we get better
28 ;; code by discouraging pseudo-registers from being allocated to them.
29 ;; However, we do want to allow all patterns which can store to them to
30 ;; include them in their constraints, so we always use '*f' in a destination
31 ;; constraint except when 'f' is the only alternative.
32 \f
33 ;; Insn attributes which describe the i960.
34
35 ;; Modscan is not used, since the compiler never emits any of these insns.
36 (define_attr "type"
37   "move,arith,alu2,mult,div,modscan,load,store,branch,call,address,compare,fpload,fpstore,fpmove,fpcvt,fpcc,fpadd,fpmul,fpdiv,multi,misc"
38   (const_string "arith"))
39
40 ;; Length (in # of insns).
41 (define_attr "length" ""
42   (cond [(eq_attr "type" "load,fpload")
43               (if_then_else (match_operand 1 "symbolic_memory_operand" "")
44                             (const_int 2)
45                             (const_int 1))
46          (eq_attr "type" "store,fpstore")
47               (if_then_else (match_operand 0 "symbolic_memory_operand" "")
48                             (const_int 2)
49                             (const_int 1))
50          (eq_attr "type" "address")
51               (const_int 2)]
52         (const_int 1)))
53
54 (define_asm_attributes
55   [(set_attr "length" "1")
56    (set_attr "type" "multi")])
57
58 ;; (define_function_unit {name} {num-units} {n-users} {test}
59 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
60
61 ;; The integer ALU
62 (define_function_unit "alu" 2 0 (eq_attr "type" "arith,compare,move,address") 1 0)
63 (define_function_unit "alu" 2 0 (eq_attr "type" "alu2") 2 0)
64 (define_function_unit "alu" 2 0 (eq_attr "type" "mult") 5 0)
65 (define_function_unit "alu" 2 0 (eq_attr "type" "div") 35 0)
66 (define_function_unit "alu" 2 0 (eq_attr "type" "modscan") 3 0)
67
68 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
69 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fpload") 2 0)
70
71 ;; Floating point operations.
72 (define_function_unit "fp" 1 2 (eq_attr "type" "fpmove") 5 0)
73 (define_function_unit "fp" 1 2 (eq_attr "type" "fpcvt") 35 0)
74 (define_function_unit "fp" 1 2 (eq_attr "type" "fpcc") 10 0)
75 (define_function_unit "fp" 1 2 (eq_attr "type" "fpadd") 10 0)
76 (define_function_unit "fp" 1 2 (eq_attr "type" "fpmul") 20 0)
77 (define_function_unit "fp" 1 2 (eq_attr "type" "fpdiv") 35 0)
78 \f
79 ;; Compare instructions.
80 ;; This controls RTL generation and register allocation.
81
82 ;; We generate RTL for comparisons and branches by having the cmpxx 
83 ;; patterns store away the operands.  Then, the scc and bcc patterns
84 ;; emit RTL for both the compare and the branch.
85 ;;
86 ;; We start with the DEFINE_EXPANDs, then DEFINE_INSNs to match
87 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
88 ;; insns that actually require more than one machine instruction.
89
90 ;; Put cmpsi first because it is expected to be the most common.
91
92 (define_expand "cmpsi"
93   [(set (reg:CC 36)
94         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
95                     (match_operand:SI 1 "general_operand" "")))]
96   ""
97   "
98 {
99   i960_compare_op0 = operands[0];
100   i960_compare_op1 = operands[1];
101   DONE;
102 }")
103
104 (define_expand "cmpdf"
105   [(set (reg:CC 36)
106         (compare:CC (match_operand:DF 0 "register_operand" "r")
107                     (match_operand:DF 1 "nonmemory_operand" "rGH")))]
108   "TARGET_NUMERICS"
109   "
110 {
111   i960_compare_op0 = operands[0];
112   i960_compare_op1 = operands[1];
113   DONE;
114 }")
115
116 (define_expand "cmpsf"
117   [(set (reg:CC 36)
118         (compare:CC (match_operand:SF 0 "register_operand" "r")
119                     (match_operand:SF 1 "nonmemory_operand" "rGH")))]
120   "TARGET_NUMERICS"
121   "
122 {
123   i960_compare_op0 = operands[0];
124   i960_compare_op1 = operands[1];
125   DONE;
126 }")
127
128 ;; Now the DEFINE_INSNs for the compare and scc cases.  First the compares.
129
130 (define_insn ""
131   [(set (reg:CC 36)
132         (compare:CC (match_operand:SI 0 "register_operand" "d")
133                     (match_operand:SI 1 "arith_operand" "dI")))]
134   ""
135   "cmpi %0,%1"
136   [(set_attr "type" "compare")])
137
138 (define_insn ""
139   [(set (reg:CC_UNS 36)
140         (compare:CC_UNS (match_operand:SI 0 "register_operand" "d")
141                         (match_operand:SI 1 "arith_operand" "dI")))]
142   ""
143   "cmpo %0,%1"
144   [(set_attr "type" "compare")])
145
146 (define_insn ""
147   [(set (reg:CC 36)
148         (compare:CC (match_operand:DF 0 "register_operand" "r")
149                     (match_operand:DF 1 "nonmemory_operand" "rGH")))]
150   "TARGET_NUMERICS"
151   "cmprl %0,%1"
152   [(set_attr "type" "fpcc")])
153
154 (define_insn ""
155   [(set (reg:CC 36)
156         (compare:CC (match_operand:SF 0 "register_operand" "r")
157                     (match_operand:SF 1 "nonmemory_operand" "rGH")))]
158   "TARGET_NUMERICS"
159   "cmpr %0,%1"
160   [(set_attr "type" "fpcc")])
161
162 ;; Instruction definitions for branch-on-bit-set and clear insns.
163
164 (define_insn ""
165   [(set (pc)
166         (if_then_else
167          (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "d")
168                               (const_int 1)
169                               (match_operand:SI 1 "arith_operand" "dI"))
170              (const_int 0))
171          (label_ref (match_operand 2 "" ""))
172          (pc)))]
173   ""
174   "bbs%+        %1,%0,%l2"
175   [(set_attr "type" "branch")])
176
177 (define_insn ""
178   [(set (pc)
179         (if_then_else
180          (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "d")
181                               (const_int 1)
182                               (match_operand:SI 1 "arith_operand" "dI"))
183              (const_int 0))
184          (label_ref (match_operand 2 "" ""))
185          (pc)))]
186   ""
187   "bbc%+        %1,%0,%l2"
188   [(set_attr "type" "branch")])
189
190 (define_insn ""
191   [(set (pc)
192         (if_then_else
193          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
194                               (const_int 1)
195                               (match_operand:SI 1 "arith_operand" "dI"))
196              (const_int 0))
197          (label_ref (match_operand 2 "" ""))
198          (pc)))]
199   ""
200   "bbs%+        %1,%0,%l2"
201   [(set_attr "type" "branch")])
202
203 (define_insn ""
204   [(set (pc)
205         (if_then_else
206          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
207                               (const_int 1)
208                               (match_operand:SI 1 "arith_operand" "dI"))
209              (const_int 0))
210          (label_ref (match_operand 2 "" ""))
211          (pc)))]
212   ""
213   "bbc%+        %1,%0,%l2"
214   [(set_attr "type" "branch")])
215
216 ;; ??? These will never match.  The LOG_LINKs necessary to make these match
217 ;; are not created by flow.  These remain as a reminder to make this work
218 ;; some day.
219
220 (define_insn ""
221   [(set (reg:CC 36)
222         (compare (match_operand:SI 0 "arith_operand" "d")
223                  (match_operand:SI 1 "arith_operand" "+d")))
224    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))]
225   "0"
226   "cmpinci      %0,%1"
227   [(set_attr "type" "compare")])
228
229 (define_insn ""
230   [(set (reg:CC_UNS 36)
231         (compare (match_operand:SI 0 "arith_operand" "d")
232                  (match_operand:SI 1 "arith_operand" "+d")))
233    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))]
234   "0"
235   "cmpinco      %0,%1"
236   [(set_attr "type" "compare")])
237
238 (define_insn ""
239   [(set (reg:CC 36)
240         (compare (match_operand:SI 0 "arith_operand" "d")
241                  (match_operand:SI 1 "arith_operand" "+d")))
242    (set (match_dup 1) (minus:SI (match_dup 1) (const_int 1)))]
243   "0"
244   "cmpdeci      %0,%1"
245   [(set_attr "type" "compare")])
246
247 (define_insn ""
248   [(set (reg:CC_UNS 36)
249         (compare (match_operand:SI 0 "arith_operand" "d")
250                  (match_operand:SI 1 "arith_operand" "+d")))
251    (set (match_dup 1) (minus:SI (match_dup 1) (const_int 1)))]
252   "0"
253   "cmpdeco      %0,%1"
254   [(set_attr "type" "compare")])
255 \f
256 ;; Templates to store result of condition.
257 ;; '1' is stored if condition is true.
258 ;; '0' is stored if condition is false.
259 ;; These should use predicate "general_operand", since
260 ;; gcc seems to be creating mem references which use these
261 ;; templates.
262
263 (define_expand "seq"
264   [(set (match_operand:SI 0 "general_operand" "=d")
265         (eq:SI (match_dup 1) (const_int 0)))]
266   ""
267   "
268 {
269   operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1);
270 }")
271
272 (define_expand "sne"
273   [(set (match_operand:SI 0 "general_operand" "=d")
274         (ne:SI (match_dup 1) (const_int 0)))]
275   ""
276   "
277 {
278   operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1);
279 }")
280
281 (define_expand "sgt"
282   [(set (match_operand:SI 0 "general_operand" "=d")
283         (gt:SI (match_dup 1) (const_int 0)))]
284   ""
285   "
286 {
287   operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1);
288 }")
289
290 (define_expand "sgtu"
291   [(set (match_operand:SI 0 "general_operand" "=d")
292         (gtu:SI (match_dup 1) (const_int 0)))]
293   ""
294   "
295 {
296   operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1);
297 }")
298
299 (define_expand "slt"
300   [(set (match_operand:SI 0 "general_operand" "=d")
301         (lt:SI (match_dup 1) (const_int 0)))]
302   ""
303   "
304 {
305   operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1);
306 }")
307
308 (define_expand "sltu"
309   [(set (match_operand:SI 0 "general_operand" "=d")
310         (ltu:SI (match_dup 1) (const_int 0)))]
311   ""
312   "
313 {
314   operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1);
315 }")
316
317 (define_expand "sge"
318   [(set (match_operand:SI 0 "general_operand" "=d")
319         (ge:SI (match_dup 1) (const_int 0)))]
320   ""
321   "
322 {
323   operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1);
324 }")
325
326 (define_expand "sgeu"
327   [(set (match_operand:SI 0 "general_operand" "=d")
328         (geu:SI (match_dup 1) (const_int 0)))]
329   ""
330   "
331 {
332   operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1);
333 }")
334
335 (define_expand "sle"
336   [(set (match_operand:SI 0 "general_operand" "=d")
337         (le:SI (match_dup 1) (const_int 0)))]
338   ""
339   "
340 {
341   operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1);
342 }")
343
344 (define_expand "sleu"
345   [(set (match_operand:SI 0 "general_operand" "=d")
346         (leu:SI (match_dup 1) (const_int 0)))]
347   ""
348   "
349 {
350   operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1);
351 }")
352
353 (define_insn ""
354   [(set (match_operand:SI 0 "general_operand" "=d")
355         (eq:SI (match_operand:SI 1 "register_operand" "d") (const_int 0)))]
356   ""
357   "shro %1,1,%0"
358   [(set_attr "type" "alu2")])
359
360 (define_insn ""
361   [(set (match_operand:SI 0 "general_operand" "=d")
362         (match_operator:SI 1 "comparison_operator" [(reg:CC 36) (const_int 0)]))]
363   ""
364   "test%C1      %0"
365   [(set_attr "type" "compare")])
366
367 (define_insn ""
368   [(set (match_operand:SI 0 "general_operand" "=d")
369         (match_operator:SI 1 "comparison_operator" [(reg:CC_UNS 36) (const_int 0)]))]
370   ""
371   "test%C1      %0"
372   [(set_attr "type" "compare")])
373 \f
374 ;; These control RTL generation for conditional jump insns
375 ;; and match them for register allocation.
376
377 (define_expand "beq"
378   [(set (pc)
379         (if_then_else (eq (match_dup 1)
380                           (const_int 0))
381                       (label_ref (match_operand 0 "" ""))
382                       (pc)))]
383   ""
384   "
385 { operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1); }")
386
387 (define_expand "bne"
388   [(set (pc)
389         (if_then_else (ne (match_dup 1)
390                           (const_int 0))
391                       (label_ref (match_operand 0 "" ""))
392                       (pc)))]
393   ""
394   "
395 { operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1); }")
396
397 (define_expand "bgt"
398   [(set (pc)
399         (if_then_else (gt (match_dup 1)
400                           (const_int 0))
401                       (label_ref (match_operand 0 "" ""))
402                       (pc)))]
403   ""
404   "
405 { operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1); }")
406
407 (define_expand "bgtu"
408   [(set (pc)
409         (if_then_else (gtu (match_dup 1)
410                            (const_int 0))
411                       (label_ref (match_operand 0 "" ""))
412                       (pc)))]
413   ""
414   "
415 { operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1); }")
416
417 (define_expand "blt"
418   [(set (pc)
419         (if_then_else (lt (match_dup 1)
420                           (const_int 0))
421                       (label_ref (match_operand 0 "" ""))
422                       (pc)))]
423   ""
424   "
425 { operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1); }")
426
427 (define_expand "bltu"
428   [(set (pc)
429         (if_then_else (ltu (match_dup 1)
430                            (const_int 0))
431                       (label_ref (match_operand 0 "" ""))
432                       (pc)))]
433   ""
434   "
435 { operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1); }")
436
437 (define_expand "bge"
438   [(set (pc)
439         (if_then_else (ge (match_dup 1)
440                           (const_int 0))
441                       (label_ref (match_operand 0 "" ""))
442                       (pc)))]
443   ""
444   "
445 { operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1); }")
446
447 (define_expand "bgeu"
448   [(set (pc)
449         (if_then_else (geu (match_dup 1)
450                            (const_int 0))
451                       (label_ref (match_operand 0 "" ""))
452                       (pc)))]
453   ""
454   "
455 { operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1); }")
456
457 (define_expand "ble"
458   [(set (pc)
459         (if_then_else (le (match_dup 1)
460                           (const_int 0))
461                       (label_ref (match_operand 0 "" ""))
462                       (pc)))]
463   ""
464   "
465 { operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1); }")
466
467 (define_expand "bleu"
468   [(set (pc)
469         (if_then_else (leu (match_dup 1)
470                            (const_int 0))
471                       (label_ref (match_operand 0 "" ""))
472                       (pc)))]
473   ""
474   "
475 { operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1); }")
476 \f
477 ;; Now the normal branch insns (forward and reverse).
478
479 (define_insn ""
480   [(set (pc)
481         (if_then_else (match_operator 0 "comparison_operator"
482                                       [(reg:CC 36) (const_int 0)])
483                       (label_ref (match_operand 1 "" ""))
484                       (pc)))]
485   ""
486   "b%C0%+ %l1"
487   [(set_attr "type" "branch")])
488
489 (define_insn ""
490   [(set (pc)
491         (if_then_else (match_operator 0 "comparison_operator"
492                                       [(reg:CC 36) (const_int 0)])
493                       (pc)
494                       (label_ref (match_operand 1 "" ""))))]
495   ""
496   "b%I0%+ %l1"
497   [(set_attr "type" "branch")])
498
499 (define_insn ""
500   [(set (pc)
501         (if_then_else (match_operator 0 "comparison_operator"
502                                       [(reg:CC_UNS 36) (const_int 0)])
503                       (label_ref (match_operand 1 "" ""))
504                       (pc)))]
505   ""
506   "b%C0%+ %l1"
507   [(set_attr "type" "branch")])
508
509 (define_insn ""
510   [(set (pc)
511         (if_then_else (match_operator 0 "comparison_operator"
512                                       [(reg:CC_UNS 36) (const_int 0)])
513                       (pc)
514                       (label_ref (match_operand 1 "" ""))))]
515   ""
516   "b%I0%+ %l1"
517   [(set_attr "type" "branch")])
518
519 (define_insn ""
520   [(set (pc)
521         (if_then_else
522          (match_operator 0 "comparison_operator"
523                          [(match_operand:SI 1 "arith_operand" "d")
524                           (match_operand:SI 2 "arith_operand" "dI")])
525          (label_ref (match_operand 3 "" ""))
526          (pc)))]
527   ""
528   "cmp%S0%B0%R0%+       %2,%1,%l3"
529   [(set_attr "type" "branch")])
530
531 (define_insn ""
532   [(set (pc)
533         (if_then_else
534          (match_operator 0 "comparison_operator"
535                          [(match_operand:SI 1 "arith_operand" "d")
536                           (match_operand:SI 2 "arith_operand" "dI")])
537          (pc)
538          (label_ref (match_operand 3 "" ""))))]
539   ""
540   "cmp%S0%B0%X0%+       %2,%1,%l3"
541   [(set_attr "type" "branch")])
542 \f
543 ;; Now the trap instructions.  The i960 appears to only have conditional
544 ;; traps...
545
546 (define_insn ("trap")
547   [(trap_if (const_int 1) (const_int 0))]
548   ""
549   "cmpo g0,g0 ; faulte.t")
550
551 (define_expand "conditional_trap"
552   [(trap_if (match_operator 0 "comparison_operator"
553              [(match_dup 2) (const_int 0)]) 
554             (match_operand 1 "const_int_operand" "i"))]
555   ""
556   "
557 {
558   operands[2] = gen_compare_reg (GET_CODE (operands[0]), 
559                                  i960_compare_op0, i960_compare_op1);
560 }")
561
562 (define_insn ""
563   [(trap_if (match_operator 0 "comparison_operator"
564              [(reg:CC 36) (const_int 0)]) 
565             (match_operand 1 "const_int_operand" "i"))]
566   ""
567   "fault%C0.f")
568
569 (define_insn ""
570   [(trap_if (match_operator 0 "comparison_operator"
571              [(reg:CC_UNS 36) (const_int 0)]) 
572             (match_operand 1 "const_int_operand" "i"))]
573   ""
574   "fault%C0.f")
575 \f
576 ;; Normal move instructions.
577 ;; This code is based on the sparc machine description.
578
579 (define_expand "movsi"
580   [(set (match_operand:SI 0 "general_operand" "")
581         (match_operand:SI 1 "general_operand" ""))]
582   ""
583   "
584 {
585   if (emit_move_sequence (operands, SImode))
586     DONE;
587 }")
588
589 ;; The store case can not be separate, because reload may convert a register
590 ;; to register move insn to a store (or load) insn without rerecognizing
591 ;; the insn.
592
593 ;; The i960 does not have any store constant to memory instruction.  However,
594 ;; the calling convention is defined so that the arg pointer when it is not
595 ;; overwise being used is zero.  Thus, we can handle store zero to memory
596 ;; by storing an unused arg pointer.  The arg pointer will be unused if
597 ;; current_function_args_size is zero and this is not a stdarg
598 ;; function.  This value of the former variable is not valid until after
599 ;; all rtl generation is complete, including function inlining (because a
600 ;; function that doesn't need an arg pointer may be inlined into a function
601 ;; that does need an arg pointer), so we must also check that
602 ;; rtx_equal_function_value_matters is zero.
603
604 (define_insn ""
605   [(set (match_operand:SI 0 "general_operand" "=d,d,d,m")
606         (match_operand:SI 1 "general_operand" "dI,i,m,dJ"))]
607   "(current_function_args_size == 0
608     && current_function_stdarg == 0
609     && rtx_equal_function_value_matters == 0)
610    && (register_operand (operands[0], SImode)
611        || register_operand (operands[1], SImode)
612        || operands[1] == const0_rtx)"
613   "*
614 {
615   switch (which_alternative)
616     {
617     case 0:
618       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
619         {
620           if (GET_CODE (operands[1]) == REG)
621             return \"lda        (%1),%0\";
622           else
623             return \"lda        %1,%0\";
624         }
625       return \"mov      %1,%0\";
626     case 1:
627       return i960_output_ldconst (operands[0], operands[1]);
628     case 2:
629       return \"ld       %1,%0\";
630     case 3:
631       if (operands[1] == const0_rtx)
632         return \"st     g14,%0\";
633       return \"st       %1,%0\";      
634     default:
635       abort();
636     }
637 }"
638   [(set_attr "type" "move,address,load,store")
639    (set_attr "length" "*,3,*,*")])
640
641 (define_insn ""
642   [(set (match_operand:SI 0 "general_operand" "=d,d,d,m")
643         (match_operand:SI 1 "general_operand" "dI,i,m,d"))]
644   "(current_function_args_size != 0
645     || current_function_stdarg != 0
646     || rtx_equal_function_value_matters != 0)
647    && (register_operand (operands[0], SImode)
648        || register_operand (operands[1], SImode))"
649   "*
650 {
651   switch (which_alternative)
652     {
653     case 0:
654       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
655         {
656           if (GET_CODE (operands[1]) == REG)
657             return \"lda        (%1),%0\";
658           else
659             return \"lda        %1,%0\";
660         }
661       return \"mov      %1,%0\";
662     case 1:
663       return i960_output_ldconst (operands[0], operands[1]);
664     case 2:
665       return \"ld       %1,%0\";
666     case 3:
667       return \"st       %1,%0\";      
668     default:
669       abort();
670     }
671 }"
672   [(set_attr "type" "move,address,load,store")
673    (set_attr "length" "*,3,*,*")])
674
675 (define_expand "movhi"
676   [(set (match_operand:HI 0 "general_operand" "")
677         (match_operand:HI 1 "general_operand" ""))]
678   ""
679   "
680 {
681   if (emit_move_sequence (operands, HImode))
682     DONE;
683 }")
684
685 ;; Special pattern for zero stores to memory for functions which don't use
686 ;; the arg pointer.
687
688 ;; The store case can not be separate.  See above.
689 (define_insn ""
690   [(set (match_operand:HI 0 "general_operand" "=d,d,d,m")
691         (match_operand:HI 1 "general_operand" "dI,i,m,dJ"))]
692   "(current_function_args_size == 0
693     && current_function_stdarg == 0
694     && rtx_equal_function_value_matters == 0)
695    && (register_operand (operands[0], HImode)
696        || register_operand (operands[1], HImode)
697        || operands[1] == const0_rtx)"
698   "*
699 {
700   switch (which_alternative)
701     {
702     case 0:
703       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
704         {
705           if (GET_CODE (operands[1]) == REG)
706             return \"lda        (%1),%0\";
707           else
708             return \"lda        %1,%0\";
709         }
710       return \"mov      %1,%0\";
711     case 1:
712       return i960_output_ldconst (operands[0], operands[1]);
713     case 2:
714       return \"ldos     %1,%0\";
715     case 3:
716       if (operands[1] == const0_rtx)
717         return \"stos   g14,%0\";
718       return \"stos     %1,%0\";
719     default:
720       abort();
721     }
722 }"
723   [(set_attr "type" "move,misc,load,store")
724    (set_attr "length" "*,3,*,*")])
725
726 ;; The store case can not be separate.  See above.
727 (define_insn ""
728   [(set (match_operand:HI 0 "general_operand" "=d,d,d,m")
729         (match_operand:HI 1 "general_operand" "dI,i,m,d"))]
730   "(current_function_args_size != 0
731     || current_function_stdarg != 0
732     || rtx_equal_function_value_matters != 0)
733    && (register_operand (operands[0], HImode)
734        || register_operand (operands[1], HImode))"
735   "*
736 {
737   switch (which_alternative)
738     {
739     case 0:
740       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
741         {
742           if (GET_CODE (operands[1]) == REG)
743             return \"lda        (%1),%0\";
744           else
745             return \"lda        %1,%0\";
746         }
747       return \"mov      %1,%0\";
748     case 1:
749       return i960_output_ldconst (operands[0], operands[1]);
750     case 2:
751       return \"ldos     %1,%0\";
752     case 3:
753       return \"stos     %1,%0\";
754     default:
755       abort();
756     }
757 }"
758   [(set_attr "type" "move,misc,load,store")
759    (set_attr "length" "*,3,*,*")])
760
761 (define_expand "movqi"
762   [(set (match_operand:QI 0 "general_operand" "")
763         (match_operand:QI 1 "general_operand" ""))]
764   ""
765   "
766 {
767   if (emit_move_sequence (operands, QImode))
768     DONE;
769 }")
770
771 ;; The store case can not be separate.  See comment above.
772 (define_insn ""
773   [(set (match_operand:QI 0 "general_operand" "=d,d,d,m")
774         (match_operand:QI 1 "general_operand" "dI,i,m,dJ"))]
775   "(current_function_args_size == 0
776     && current_function_stdarg == 0
777     && rtx_equal_function_value_matters == 0)
778    && (register_operand (operands[0], QImode)
779        || register_operand (operands[1], QImode)
780        || operands[1] == const0_rtx)"
781   "*
782 {
783   switch (which_alternative)
784     {
785     case 0:
786       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
787         {
788           if (GET_CODE (operands[1]) == REG)
789             return \"lda        (%1),%0\";
790           else
791             return \"lda        %1,%0\";
792         }
793       return \"mov      %1,%0\";
794     case 1:
795       return i960_output_ldconst (operands[0], operands[1]);
796     case 2:
797       return \"ldob     %1,%0\";
798     case 3:
799       if (operands[1] == const0_rtx)
800         return \"stob   g14,%0\";
801       return \"stob     %1,%0\";
802     default:
803       abort();
804     }
805 }"
806   [(set_attr "type" "move,misc,load,store")
807    (set_attr "length" "*,3,*,*")])
808
809 ;; The store case can not be separate.  See comment above.
810 (define_insn ""
811   [(set (match_operand:QI 0 "general_operand" "=d,d,d,m")
812         (match_operand:QI 1 "general_operand" "dI,i,m,d"))]
813   "(current_function_args_size != 0
814     || current_function_stdarg != 0
815     || rtx_equal_function_value_matters != 0)
816    && (register_operand (operands[0], QImode)
817        || register_operand (operands[1], QImode))"
818   "*
819 {
820   switch (which_alternative)
821     {
822     case 0:
823       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
824         {
825           if (GET_CODE (operands[1]) == REG)
826             return \"lda        (%1),%0\";
827           else
828             return \"lda        %1,%0\";
829         }
830       return \"mov      %1,%0\";
831     case 1:
832       return i960_output_ldconst (operands[0], operands[1]);
833     case 2:
834       return \"ldob     %1,%0\";
835     case 3:
836       return \"stob     %1,%0\";
837     default:
838       abort();
839     }
840 }"
841   [(set_attr "type" "move,misc,load,store")
842    (set_attr "length" "*,3,*,*")])
843
844 (define_expand "movdi"
845   [(set (match_operand:DI 0 "general_operand" "")
846         (match_operand:DI 1 "general_operand" ""))]
847   ""
848   "
849 {
850   if (emit_move_sequence (operands, DImode))
851     DONE;
852 }")
853
854 ;; The store case can not be separate.  See comment above.
855 (define_insn ""
856   [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m,o")
857         (match_operand:DI 1 "general_operand" "d,I,i,m,d,J"))]
858   "(current_function_args_size == 0
859     && current_function_stdarg == 0
860     && rtx_equal_function_value_matters == 0)
861    && (register_operand (operands[0], DImode)
862        || register_operand (operands[1], DImode)
863        || operands[1] == const0_rtx)"
864   "*
865 {
866   switch (which_alternative)
867     {
868     case 0:
869     case 1:
870     case 3:
871     case 4:
872       return i960_output_move_double (operands[0], operands[1]);
873     case 2:
874       return i960_output_ldconst (operands[0], operands[1]);
875     case 5:
876        return i960_output_move_double_zero (operands[0]);
877     default:
878       abort();
879     }
880 }"
881   [(set_attr "type" "move,move,load,load,store,store")])
882
883 ;; The store case can not be separate.  See comment above.
884 (define_insn ""
885   [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m")
886         (match_operand:DI 1 "general_operand" "d,I,i,m,d"))]
887   "(current_function_args_size != 0
888     || current_function_stdarg != 0
889     || rtx_equal_function_value_matters != 0)
890    && (register_operand (operands[0], DImode)
891        || register_operand (operands[1], DImode))"
892   "*
893 {
894   switch (which_alternative)
895     {
896     case 0:
897     case 1:
898     case 3:
899     case 4:
900       return i960_output_move_double (operands[0], operands[1]);
901     case 2:
902       return i960_output_ldconst (operands[0], operands[1]);
903     default:
904       abort();
905     }
906 }"
907   [(set_attr "type" "move,move,load,load,store")])
908
909 (define_insn "*store_unaligned_di_reg"
910   [(set (match_operand:DI 0 "general_operand" "=d,m")
911         (match_operand:DI 1 "register_operand" "d,d"))
912    (clobber (match_scratch:SI 2 "=X,&d"))]
913   ""
914   "*
915 {
916   if (which_alternative == 0)
917     return i960_output_move_double (operands[0], operands[1]);
918     
919   operands[3] = gen_rtx_MEM (word_mode, operands[2]);
920   operands[4] = adjust_address (operands[3], word_mode, UNITS_PER_WORD);
921   return \"lda  %0,%2\;st       %1,%3\;st       %D1,%4\";
922 }"
923   [(set_attr "type" "move,store")])
924
925 (define_expand "movti"
926   [(set (match_operand:TI 0 "general_operand" "")
927         (match_operand:TI 1 "general_operand" ""))]
928   ""
929   "
930 {
931   if (emit_move_sequence (operands, TImode))
932     DONE;
933 }")
934
935 ;; The store case can not be separate.  See comment above.
936 (define_insn ""
937   [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m,o")
938         (match_operand:TI 1 "general_operand" "d,I,i,m,d,J"))]
939   "(current_function_args_size == 0
940     && current_function_stdarg == 0
941     && rtx_equal_function_value_matters == 0)
942    && (register_operand (operands[0], TImode)
943        || register_operand (operands[1], TImode)
944        || operands[1] == const0_rtx)"
945   "*
946 {
947   switch (which_alternative)
948     {
949     case 0:
950     case 1:
951     case 3:
952     case 4:
953       return i960_output_move_quad (operands[0], operands[1]);
954     case 2:
955       return i960_output_ldconst (operands[0], operands[1]);
956     case 5:
957       return i960_output_move_quad_zero (operands[0]);
958     default:
959       abort();
960     }
961 }"
962   [(set_attr "type" "move,move,load,load,store,store")])
963
964 ;; The store case can not be separate.  See comment above.
965 (define_insn ""
966   [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m")
967         (match_operand:TI 1 "general_operand" "d,I,i,m,d"))]
968   "(current_function_args_size != 0
969     || current_function_stdarg != 0
970     || rtx_equal_function_value_matters != 0)
971    && (register_operand (operands[0], TImode)
972        || register_operand (operands[1], TImode))"
973   "*
974 {
975   switch (which_alternative)
976     {
977     case 0:
978     case 1:
979     case 3:
980     case 4:
981       return i960_output_move_quad (operands[0], operands[1]);
982     case 2:
983       return i960_output_ldconst (operands[0], operands[1]);
984     default:
985       abort();
986     }
987 }"
988   [(set_attr "type" "move,move,load,load,store")])
989
990 (define_insn "*store_unaligned_ti_reg"
991   [(set (match_operand:TI 0 "general_operand" "=d,m")
992         (match_operand:TI 1 "register_operand" "d,d"))
993    (clobber (match_scratch:SI 2 "=X,&d"))]
994   ""
995   "*
996 {
997   if (which_alternative == 0)
998     return i960_output_move_quad (operands[0], operands[1]);
999
1000   operands[3] = gen_rtx_MEM (word_mode, operands[2]);
1001   operands[4] = adjust_address (operands[3], word_mode, UNITS_PER_WORD);
1002   operands[5] = adjust_address (operands[4], word_mode, UNITS_PER_WORD);
1003   operands[6] = adjust_address (operands[5], word_mode, UNITS_PER_WORD);
1004   return \"lda  %0,%2\;st       %1,%3\;st       %D1,%4\;st      %E1,%5\;st      %F1,%6\";
1005 }"
1006   [(set_attr "type" "move,store")])
1007
1008 (define_expand "store_multiple"
1009   [(set (match_operand:SI 0 "" "")      ;;- dest
1010         (match_operand:SI 1 "" ""))     ;;- src
1011    (use (match_operand:SI 2 "" ""))]    ;;- nregs
1012   ""
1013   "
1014 {
1015   int regno;
1016   int count;
1017   int offset = 0;
1018
1019   if (GET_CODE (operands[0]) != MEM
1020       || GET_CODE (operands[1]) != REG
1021       || GET_CODE (operands[2]) != CONST_INT)
1022     FAIL;
1023
1024   count = INTVAL (operands[2]);
1025   if (count > 12)
1026     FAIL;
1027
1028   regno = REGNO (operands[1]);
1029   while (count >= 4 && ((regno & 3) == 0))
1030     {
1031       emit_move_insn (adjust_address (operands[0], TImode, offset),
1032                       gen_rtx_REG (TImode, regno));
1033       count -= 4;
1034       regno += 4;
1035       offset += 16;
1036     }
1037   while (count >= 2 && ((regno & 1) == 0))
1038     {
1039       emit_move_insn (adjust_address (operands[0], DImode, offset),
1040                       gen_rtx_REG (DImode, regno));
1041       count -= 2;
1042       regno += 2;
1043       offset += 8;
1044     }
1045   while (count > 0)
1046     {
1047       emit_move_insn (adjust_address (operands[0], SImode, offset),
1048                       gen_rtx_REG (SImode, regno));
1049       count -= 1;
1050       regno += 1;
1051       offset += 4;
1052     }
1053   DONE;
1054 }")
1055 \f
1056 ;; Floating point move insns
1057
1058 (define_expand "movdf"
1059   [(set (match_operand:DF 0 "general_operand" "")
1060         (match_operand:DF 1 "fpmove_src_operand" ""))]
1061   ""
1062   "
1063 {
1064   if (emit_move_sequence (operands, DFmode))
1065     DONE;
1066 }")
1067
1068 (define_insn ""
1069   [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m,o")
1070         (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d,G"))]
1071   "(current_function_args_size == 0
1072     && current_function_stdarg == 0
1073     && rtx_equal_function_value_matters == 0)
1074    && (register_operand (operands[0], DFmode)
1075        || register_operand (operands[1], DFmode)
1076        || operands[1] == CONST0_RTX (DFmode))"
1077   "*
1078 {
1079   switch (which_alternative)
1080     {
1081     case 0:
1082       if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1083         return \"movrl  %1,%0\";
1084       else
1085         return \"movl   %1,%0\";
1086     case 1:
1087       return \"movrl    %1,%0\";
1088     case 2:
1089       return i960_output_ldconst (operands[0], operands[1]);
1090     case 3:
1091       return \"ldl      %1,%0\";
1092     case 4:
1093       return \"stl      %1,%0\";
1094     case 5:
1095       operands[1] = adjust_address (operands[0], VOIDmode, 4);
1096       return \"st       g14,%0\;st      g14,%1\";
1097     default:
1098       abort();
1099     }
1100 }"
1101   [(set_attr "type" "move,move,load,fpload,fpstore,fpstore")])
1102
1103 (define_insn ""
1104   [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m")
1105         (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
1106   "(current_function_args_size != 0
1107     || current_function_stdarg != 0
1108     || rtx_equal_function_value_matters != 0)
1109    && (register_operand (operands[0], DFmode)
1110        || register_operand (operands[1], DFmode))"
1111   "*
1112 {
1113   switch (which_alternative)
1114     {
1115     case 0:
1116       if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1117         return \"movrl  %1,%0\";
1118       else
1119         return \"movl   %1,%0\";
1120     case 1:
1121       return \"movrl    %1,%0\";
1122     case 2:
1123       return i960_output_ldconst (operands[0], operands[1]);
1124     case 3:
1125       return \"ldl      %1,%0\";
1126     case 4:
1127       return \"stl      %1,%0\";
1128     default:
1129       abort();
1130     }
1131 }"
1132   [(set_attr "type" "move,move,load,fpload,fpstore")])
1133
1134 (define_expand "movsf"
1135   [(set (match_operand:SF 0 "general_operand" "")
1136         (match_operand:SF 1 "fpmove_src_operand" ""))]
1137   ""
1138   "
1139 {
1140   if (emit_move_sequence (operands, SFmode))
1141     DONE;
1142 }")
1143
1144 (define_insn ""
1145   [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m")
1146         (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,dG"))]
1147   "(current_function_args_size == 0
1148     && current_function_stdarg == 0
1149     && rtx_equal_function_value_matters == 0)
1150    && (register_operand (operands[0], SFmode)
1151        || register_operand (operands[1], SFmode)
1152        || operands[1] == CONST0_RTX (SFmode))"
1153   "*
1154 {
1155   switch (which_alternative)
1156     {
1157     case 0:
1158       if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1159         return \"movr   %1,%0\";
1160       else
1161         return \"mov    %1,%0\";
1162     case 1:
1163       return \"movr     %1,%0\";
1164     case 2:
1165       return i960_output_ldconst (operands[0], operands[1]);
1166     case 3:
1167       return \"ld       %1,%0\";
1168     case 4:
1169       if (operands[1] == CONST0_RTX (SFmode))
1170         return \"st     g14,%0\";
1171       return \"st       %1,%0\";
1172     default:
1173       abort();
1174     }
1175 }"
1176   [(set_attr "type" "move,move,load,fpload,fpstore")])
1177
1178 (define_insn ""
1179   [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m")
1180         (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
1181   "(current_function_args_size != 0
1182     || current_function_stdarg != 0
1183     || rtx_equal_function_value_matters != 0)
1184    && (register_operand (operands[0], SFmode)
1185        || register_operand (operands[1], SFmode))"
1186   "*
1187 {
1188   switch (which_alternative)
1189     {
1190     case 0:
1191       if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1192         return \"movr   %1,%0\";
1193       else
1194         return \"mov    %1,%0\";
1195     case 1:
1196       return \"movr     %1,%0\";
1197     case 2:
1198       return i960_output_ldconst (operands[0], operands[1]);
1199     case 3:
1200       return \"ld       %1,%0\";
1201     case 4:
1202       return \"st       %1,%0\";
1203     default:
1204       abort();
1205     }
1206 }"
1207   [(set_attr "type" "move,move,load,fpload,fpstore")])
1208 \f
1209 ;; Mixed-mode moves with sign and zero-extension.
1210
1211 ;; Note that the one starting from HImode comes before those for QImode
1212 ;; so that a constant operand will match HImode, not QImode.
1213
1214 (define_expand "extendhisi2"
1215   [(set (match_operand:SI 0 "register_operand" "")
1216         (sign_extend:SI
1217          (match_operand:HI 1 "nonimmediate_operand" "")))]
1218  ""
1219  "
1220 {
1221   if (GET_CODE (operand1) == REG
1222       || (GET_CODE (operand1) == SUBREG
1223           && GET_CODE (XEXP (operand1, 0)) == REG))
1224     {
1225       rtx temp = gen_reg_rtx (SImode);
1226       rtx shift_16 = GEN_INT (16);
1227       int op1_subreg_byte = 0;
1228
1229       if (GET_CODE (operand1) == SUBREG)
1230         {
1231           op1_subreg_byte = SUBREG_BYTE (operand1);
1232           op1_subreg_byte /= GET_MODE_SIZE (SImode);
1233           op1_subreg_byte *= GET_MODE_SIZE (SImode);
1234           operand1 = SUBREG_REG (operand1);
1235         }
1236       if (GET_MODE (operand1) != SImode)
1237         operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1238
1239       emit_insn (gen_ashlsi3 (temp, operand1, shift_16));
1240       emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1241       DONE;
1242     }
1243 }")
1244
1245 (define_insn ""
1246   [(set (match_operand:SI 0 "register_operand" "=d")
1247         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1248   ""
1249   "ldis %1,%0"
1250   [(set_attr "type" "load")])
1251
1252 (define_expand "extendqisi2"
1253   [(set (match_operand:SI 0 "register_operand" "")
1254         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1255   ""
1256   "
1257 {
1258   if (GET_CODE (operand1) == REG
1259       || (GET_CODE (operand1) == SUBREG
1260           && GET_CODE (XEXP (operand1, 0)) == REG))
1261     {
1262       rtx temp = gen_reg_rtx (SImode);
1263       rtx shift_24 = GEN_INT (24);
1264       int op1_subreg_byte = 0;
1265
1266       if (GET_CODE (operand1) == SUBREG)
1267         {
1268           op1_subreg_byte = SUBREG_BYTE (operand1);
1269           op1_subreg_byte /= GET_MODE_SIZE (SImode);
1270           op1_subreg_byte *= GET_MODE_SIZE (SImode);
1271           operand1 = SUBREG_REG (operand1);
1272         }
1273       if (GET_MODE (operand1) != SImode)
1274         operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1275
1276       emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1277       emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1278       DONE;
1279     }
1280 }")
1281
1282 (define_insn ""
1283   [(set (match_operand:SI 0 "register_operand" "=d")
1284         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1285   ""
1286   "ldib %1,%0"
1287   [(set_attr "type" "load")])
1288
1289 (define_expand "extendqihi2"
1290   [(set (match_operand:HI 0 "register_operand" "")
1291         (sign_extend:HI
1292          (match_operand:QI 1 "nonimmediate_operand" "")))]
1293   ""
1294   "
1295 {
1296   if (GET_CODE (operand1) == REG
1297       || (GET_CODE (operand1) == SUBREG
1298           && GET_CODE (XEXP (operand1, 0)) == REG))
1299     {
1300       rtx temp = gen_reg_rtx (SImode);
1301       rtx shift_24 = GEN_INT (24);
1302       int op0_subreg_byte = 0;
1303       int op1_subreg_byte = 0;
1304
1305       if (GET_CODE (operand1) == SUBREG)
1306         {
1307           op1_subreg_byte = SUBREG_BYTE (operand1);
1308           op1_subreg_byte /= GET_MODE_SIZE (SImode);
1309           op1_subreg_byte *= GET_MODE_SIZE (SImode);
1310           operand1 = SUBREG_REG (operand1);
1311         }
1312       if (GET_MODE (operand1) != SImode)
1313         operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1314
1315       if (GET_CODE (operand0) == SUBREG)
1316         {
1317           op0_subreg_byte = SUBREG_BYTE (operand0);
1318           op0_subreg_byte /= GET_MODE_SIZE (SImode);
1319           op0_subreg_byte *= GET_MODE_SIZE (SImode);
1320           operand0 = SUBREG_REG (operand0);
1321         }
1322       if (GET_MODE (operand0) != SImode)
1323         operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subreg_byte);
1324
1325       emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1326       emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1327       DONE;
1328     }
1329 }")
1330
1331 (define_insn ""
1332   [(set (match_operand:HI 0 "register_operand" "=d")
1333         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1334   ""
1335   "ldib %1,%0"
1336   [(set_attr "type" "load")])
1337
1338 (define_expand "zero_extendhisi2"
1339   [(set (match_operand:SI 0 "register_operand" "")
1340         (zero_extend:SI
1341          (match_operand:HI 1 "nonimmediate_operand" "")))]
1342  ""
1343  "
1344 {
1345   if (GET_CODE (operand1) == REG
1346       || (GET_CODE (operand1) == SUBREG
1347           && GET_CODE (XEXP (operand1, 0)) == REG))
1348     {
1349       rtx temp = gen_reg_rtx (SImode);
1350       rtx shift_16 = GEN_INT (16);
1351       int op1_subreg_byte = 0;
1352
1353       if (GET_CODE (operand1) == SUBREG)
1354         {
1355           op1_subreg_byte = SUBREG_BYTE (operand1);
1356           op1_subreg_byte /= GET_MODE_SIZE (SImode);
1357           op1_subreg_byte *= GET_MODE_SIZE (SImode);
1358           operand1 = SUBREG_REG (operand1);
1359         }
1360       if (GET_MODE (operand1) != SImode)
1361         operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1362
1363       emit_insn (gen_ashlsi3 (temp, operand1, shift_16));
1364       emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1365       DONE;
1366     }
1367 }")
1368
1369 (define_insn ""
1370   [(set (match_operand:SI 0 "register_operand" "=d")
1371         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1372   ""
1373   "ldos %1,%0"
1374   [(set_attr "type" "load")])
1375
1376 ;; Using shifts here generates much better code than doing an `and 255'.
1377 ;; This is mainly because the `and' requires loading the constant separately,
1378 ;; the constant is likely to get optimized, and then the compiler can't
1379 ;; optimize the `and' because it doesn't know that one operand is a constant.
1380
1381 (define_expand "zero_extendqisi2"
1382   [(set (match_operand:SI 0 "register_operand" "")
1383         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1384   ""
1385   "
1386 {
1387   if (GET_CODE (operand1) == REG
1388       || (GET_CODE (operand1) == SUBREG
1389           && GET_CODE (XEXP (operand1, 0)) == REG))
1390     {
1391       rtx temp = gen_reg_rtx (SImode);
1392       rtx shift_24 = GEN_INT (24);
1393       int op1_subreg_byte = 0;
1394
1395       if (GET_CODE (operand1) == SUBREG)
1396         {
1397           op1_subreg_byte = SUBREG_BYTE (operand1);
1398           op1_subreg_byte /= GET_MODE_SIZE (SImode);
1399           op1_subreg_byte *= GET_MODE_SIZE (SImode);
1400           operand1 = SUBREG_REG (operand1);
1401         }
1402       if (GET_MODE (operand1) != SImode)
1403         operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1404
1405       emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1406       emit_insn (gen_lshrsi3 (operand0, temp, shift_24));
1407       DONE;
1408     }
1409 }")
1410
1411 (define_insn ""
1412   [(set (match_operand:SI 0 "register_operand" "=d")
1413         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1414   ""
1415   "ldob %1,%0"
1416   [(set_attr "type" "load")])
1417
1418 (define_expand "zero_extendqihi2"
1419   [(set (match_operand:HI 0 "register_operand" "")
1420         (zero_extend:HI
1421          (match_operand:QI 1 "nonimmediate_operand" "")))]
1422   ""
1423   "
1424 {
1425   if (GET_CODE (operand1) == REG
1426       || (GET_CODE (operand1) == SUBREG
1427           && GET_CODE (XEXP (operand1, 0)) == REG))
1428     {
1429       rtx temp = gen_reg_rtx (SImode);
1430       rtx shift_24 = GEN_INT (24);
1431       int op0_subreg_byte = 0;
1432       int op1_subreg_byte = 0;
1433
1434       if (GET_CODE (operand1) == SUBREG)
1435         {
1436           op1_subreg_byte = SUBREG_BYTE (operand1);
1437           operand1 = SUBREG_REG (operand1);
1438         }
1439       if (GET_MODE (operand1) != SImode)
1440         operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1441
1442       if (GET_CODE (operand0) == SUBREG)
1443         {
1444           op0_subreg_byte = SUBREG_BYTE (operand0);
1445           operand0 = SUBREG_REG (operand0);
1446         }
1447       if (GET_MODE (operand0) != SImode)
1448         operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subreg_byte);
1449
1450       emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1451       emit_insn (gen_lshrsi3 (operand0, temp, shift_24));
1452       DONE;
1453     }
1454 }")
1455
1456 (define_insn ""
1457   [(set (match_operand:HI 0 "register_operand" "=d")
1458         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1459   ""
1460   "ldob %1,%0"
1461   [(set_attr "type" "load")])
1462 \f
1463 ;; Conversions between float and double.
1464
1465 (define_insn "extendsfdf2"
1466   [(set (match_operand:DF 0 "register_operand" "=*f,d")
1467         (float_extend:DF (match_operand:SF 1 "fp_arith_operand" "dGH,fGH")))]
1468   "TARGET_NUMERICS"
1469   "@
1470   movr  %1,%0
1471   movrl %1,%0"
1472   [(set_attr "type" "fpmove")])
1473
1474 (define_insn "truncdfsf2"
1475   [(set (match_operand:SF 0 "register_operand" "=d")
1476         (float_truncate:SF
1477          (match_operand:DF 1 "fp_arith_operand" "fGH")))]
1478   "TARGET_NUMERICS"
1479   "movr %1,%0"
1480   [(set_attr "type" "fpmove")])
1481
1482 ;; Conversion between fixed point and floating point.
1483
1484 (define_insn "floatsidf2"
1485   [(set (match_operand:DF 0 "register_operand" "=f")
1486         (float:DF (match_operand:SI 1 "register_operand" "d")))]
1487   "TARGET_NUMERICS"
1488   "cvtir        %1,%0"
1489   [(set_attr "type" "fpcvt")])
1490
1491 (define_insn "floatsisf2"
1492   [(set (match_operand:SF 0 "register_operand" "=d*f")
1493         (float:SF (match_operand:SI 1 "register_operand" "d")))]
1494   "TARGET_NUMERICS"
1495   "cvtir        %1,%0"
1496   [(set_attr "type" "fpcvt")])
1497
1498 ;; Convert a float to an actual integer.
1499 ;; Truncation is performed as part of the conversion.
1500 ;; The i960 requires conversion from DFmode to DImode to make
1501 ;; unsigned conversions work properly.
1502
1503 (define_insn "fixuns_truncdfdi2"
1504   [(set (match_operand:DI 0 "register_operand" "=d")
1505         (unsigned_fix:DI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))]
1506   "TARGET_NUMERICS"
1507   "cvtzril      %1,%0"
1508   [(set_attr "type" "fpcvt")])
1509
1510 (define_insn "fixuns_truncsfdi2"
1511   [(set (match_operand:DI 0 "register_operand" "=d")
1512         (unsigned_fix:DI (fix:SF (match_operand:SF 1 "fp_arith_operand" "fGH"))))]
1513   "TARGET_NUMERICS"
1514   "cvtzril      %1,%0"
1515   [(set_attr "type" "fpcvt")])
1516
1517 (define_insn "fix_truncdfsi2"
1518   [(set (match_operand:SI 0 "register_operand" "=d")
1519         (fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))]
1520   "TARGET_NUMERICS"
1521   "cvtzri       %1,%0"
1522   [(set_attr "type" "fpcvt")])
1523
1524 (define_expand "fixuns_truncdfsi2"
1525   [(set (match_operand:SI 0 "register_operand" "")
1526         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" ""))))]
1527   "TARGET_NUMERICS"
1528   "
1529 {
1530   rtx temp = gen_reg_rtx (DImode);
1531   emit_insn (gen_rtx_SET (VOIDmode, temp,
1532                           gen_rtx_UNSIGNED_FIX (DImode,
1533                                                 gen_rtx_FIX (DFmode,
1534                                                              operands[1]))));
1535   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1536                           gen_rtx_SUBREG (SImode, temp, 0)));
1537   DONE;
1538 }")
1539
1540 (define_insn "fix_truncsfsi2"
1541   [(set (match_operand:SI 0 "register_operand" "=d")
1542         (fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" "dfGH"))))]
1543   "TARGET_NUMERICS"
1544   "cvtzri       %1,%0"
1545   [(set_attr "type" "fpcvt")])
1546
1547 (define_expand "fixuns_truncsfsi2"
1548   [(set (match_operand:SI 0 "register_operand" "")
1549         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" ""))))]
1550   "TARGET_NUMERICS"
1551   "
1552 {
1553   rtx temp = gen_reg_rtx (DImode);
1554   emit_insn (gen_rtx_SET (VOIDmode, temp,
1555                           gen_rtx_UNSIGNED_FIX (DImode,
1556                                                 gen_rtx_FIX (SFmode,
1557                                                              operands[1]))));
1558   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1559                           gen_rtx_SUBREG (SImode, temp, 0)));
1560   DONE;
1561 }")
1562 \f
1563 ;; Arithmetic instructions.
1564
1565 (define_insn "subsi3"
1566   [(set (match_operand:SI 0 "register_operand" "=d")
1567         (minus:SI (match_operand:SI 1 "arith_operand" "dI")
1568                   (match_operand:SI 2 "arith_operand" "dI")))]
1569   ""
1570   "subo %2,%1,%0")
1571
1572 ;; Try to generate an lda instruction when it would be faster than an
1573 ;; add instruction.
1574 ;; Some assemblers apparently won't accept two addresses added together.
1575
1576 ;; ??? The condition should be improved to reject the case of two
1577 ;; symbolic constants.
1578
1579 (define_insn ""
1580   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1581         (plus:SI (match_operand:SI 1 "arith32_operand" "%dn,i,dn")
1582                  (match_operand:SI 2 "arith32_operand" "dn,dn,i")))]
1583   "(TARGET_C_SERIES) && (CONSTANT_P (operands[1]) || CONSTANT_P (operands[2]))"
1584   "*
1585 {
1586   if (GET_CODE (operands[1]) == CONST_INT)
1587     {
1588       rtx tmp = operands[1];
1589       operands[1] = operands[2];
1590       operands[2] = tmp;
1591     }
1592   if (GET_CODE (operands[2]) == CONST_INT
1593       && GET_CODE (operands[1]) == REG
1594       && i960_last_insn_type != I_TYPE_REG)
1595     {
1596       if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) > -32)
1597         return \"subo   %n2,%1,%0\";
1598       else if (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32)
1599         return \"addo   %1,%2,%0\";
1600     }
1601   /* Non-canonical results (op1 == const, op2 != const) have been seen
1602      in reload output when both operands were symbols before reload, so
1603      we deal with it here.  This may be a fault of the constraints above.  */
1604   if (CONSTANT_P (operands[1]))
1605     {
1606       if (CONSTANT_P (operands[2]))
1607         return \"lda    %1+%2,%0\";
1608       else
1609         return \"lda    %1(%2),%0\";
1610     }
1611   return \"lda  %2(%1),%0\";
1612 }")
1613
1614 (define_insn "addsi3"
1615   [(set (match_operand:SI 0 "register_operand" "=d")
1616         (plus:SI (match_operand:SI 1 "signed_arith_operand" "%dI")
1617                  (match_operand:SI 2 "signed_arith_operand" "dIK")))]
1618   ""
1619   "*
1620 {
1621   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1622     return \"subo       %n2,%1,%0\";
1623   if (i960_bypass (insn, operands[1], operands[2], 0))
1624     return \"addo       %2,%1,%0\";
1625   return \"addo %1,%2,%0\";
1626 }")
1627
1628 (define_insn "mulsi3"
1629   [(set (match_operand:SI 0 "register_operand" "=d")
1630         (mult:SI (match_operand:SI 1 "arith_operand" "%dI")
1631                  (match_operand:SI 2 "arith_operand" "dI")))]
1632   ""
1633   "*
1634 {
1635   if (i960_bypass (insn, operands[1], operands[2], 0))
1636     return \"mulo       %2,%1,%0\";
1637   return \"mulo %1,%2,%0\";
1638 }"
1639   [(set_attr "type" "mult")])
1640
1641 (define_insn "umulsidi3"
1642   [(set (match_operand:DI 0 "register_operand" "=d")
1643         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1644                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1645   ""
1646   "*
1647 {
1648   if (i960_bypass (insn, operands[1], operands[2], 0))
1649     return \"emul       %2,%1,%0\";
1650   return \"emul %1,%2,%0\";
1651 }"
1652   [(set_attr "type" "mult")])
1653
1654 (define_insn ""
1655   [(set (match_operand:DI 0 "register_operand" "=d")
1656         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%d"))
1657                  (match_operand:SI 2 "literal" "I")))]
1658   ""
1659   "*
1660 {
1661   if (i960_bypass (insn, operands[1], operands[2], 0))
1662     return \"emul       %2,%1,%0\";
1663   return \"emul %1,%2,%0\";
1664 }"
1665   [(set_attr "type" "mult")])
1666
1667 ;; This goes after the move/add/sub/mul instructions  
1668 ;; because those instructions are better when they apply.
1669
1670 (define_insn ""
1671   [(set (match_operand:SI 0 "register_operand" "=d")
1672         (match_operand:SI 1 "address_operand" "p"))]
1673   ""
1674   "lda  %a1,%0"
1675   [(set_attr "type" "load")])
1676
1677 ;; This will never be selected because of an "optimization" that GCC does.
1678 ;; It always converts divides by a power of 2 into a sequence of instructions
1679 ;; that does a right shift, and then corrects the result if it was negative.
1680
1681 ;; (define_insn ""
1682 ;;   [(set (match_operand:SI 0 "register_operand" "=d")
1683 ;;         (div:SI (match_operand:SI 1 "arith_operand" "dI")
1684 ;;                 (match_operand:SI 2 "power2_operand" "nI")))]
1685 ;;   ""
1686 ;;   "*{
1687 ;;      operands[2] = GEN_INT (bitpos (INTVAL (operands[2])));
1688 ;;      return \"shrdi  %2,%1,%0\";
1689 ;;   }"
1690
1691 (define_insn "divsi3"
1692   [(set (match_operand:SI 0 "register_operand" "=d")
1693         (div:SI (match_operand:SI 1 "arith_operand" "dI")
1694                 (match_operand:SI 2 "arith_operand" "dI")))]
1695   ""
1696   "divi %2,%1,%0"
1697   [(set_attr "type" "div")])
1698
1699 (define_insn "udivsi3"
1700   [(set (match_operand:SI 0 "register_operand" "=d")
1701         (udiv:SI (match_operand:SI 1 "arith_operand" "dI")
1702                  (match_operand:SI 2 "arith_operand" "dI")))]
1703   ""
1704   "divo %2,%1,%0"
1705   [(set_attr "type" "div")])
1706
1707 ;; We must use `remi' not `modi' here, to ensure that `%' has the effects
1708 ;; specified by the ANSI C standard.
1709
1710 (define_insn "modsi3"
1711   [(set (match_operand:SI 0 "register_operand" "=d")
1712         (mod:SI (match_operand:SI 1 "arith_operand" "dI")
1713                 (match_operand:SI 2 "arith_operand" "dI")))]
1714   ""
1715   "remi %2,%1,%0"
1716   [(set_attr "type" "div")])
1717
1718 (define_insn "umodsi3"
1719   [(set (match_operand:SI 0 "register_operand" "=d")
1720         (umod:SI (match_operand:SI 1 "arith_operand" "dI")
1721                  (match_operand:SI 2 "arith_operand" "dI")))]
1722   ""
1723   "remo %2,%1,%0"
1724   [(set_attr "type" "div")])
1725
1726 ;; And instructions (with complement also).
1727
1728 (define_insn "andsi3"
1729   [(set (match_operand:SI 0 "register_operand" "=d")
1730         (and:SI (match_operand:SI 1 "register_operand" "%d")
1731                 (match_operand:SI 2 "logic_operand" "dIM")))]
1732   ""
1733   "*
1734 {
1735   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1736     return \"andnot     %C2,%1,%0\";
1737   if (i960_bypass (insn, operands[1], operands[2], 0))
1738     return \"and        %2,%1,%0\";
1739   return \"and  %1,%2,%0\";
1740 }")
1741
1742 (define_insn ""
1743   [(set (match_operand:SI 0 "register_operand" "=d")
1744         (and:SI (match_operand:SI 1 "arith_operand" "dI")
1745                 (match_operand:SI 2 "cmplpower2_operand" "n")))]
1746   ""
1747   "*
1748 {
1749   operands[2] = GEN_INT (bitpos (~INTVAL (operands[2])));
1750   return \"clrbit       %2,%1,%0\";
1751 }")
1752
1753 (define_insn ""
1754   [(set (match_operand:SI 0 "register_operand" "=d")
1755         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1756                 (match_operand:SI 2 "logic_operand" "dIM")))]
1757   ""
1758   "*
1759 {
1760   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1761     return \"nor        %C2,%1,%0\";
1762   if (i960_bypass (insn, operands[1], operands[2], 0))
1763     return \"notand     %2,%1,%0\";
1764   return \"andnot       %1,%2,%0\";
1765 }")
1766
1767 (define_insn ""
1768   [(set (match_operand:SI 0 "register_operand" "=d")
1769         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "%d"))
1770                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
1771   ""
1772   "*
1773 {
1774   if (i960_bypass (insn, operands[1], operands[2], 0))
1775     return \"nand       %2,%1,%0\";
1776   return \"nand %1,%2,%0\";
1777 }")
1778
1779 (define_insn "iorsi3"
1780   [(set (match_operand:SI 0 "register_operand" "=d")
1781         (ior:SI (match_operand:SI 1 "register_operand" "%d")
1782                 (match_operand:SI 2 "logic_operand" "dIM")))]
1783   ""
1784   "*
1785 {
1786   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1787     return \"ornot      %C2,%1,%0\";
1788   if (i960_bypass (insn, operands[1], operands[2], 0))
1789     return \"or %2,%1,%0\";
1790   return \"or   %1,%2,%0\";
1791 }")
1792
1793 (define_insn ""
1794   [(set (match_operand:SI 0 "register_operand" "=d")
1795         (ior:SI (match_operand:SI 1 "register_operand" "d")
1796                 (match_operand:SI 2 "power2_operand" "n")))]
1797   ""
1798   "*
1799 {
1800   operands[2] = GEN_INT (bitpos (INTVAL (operands[2])));
1801   return \"setbit       %2,%1,%0\";
1802 }")
1803
1804 (define_insn ""
1805   [(set (match_operand:SI 0 "register_operand" "=d")
1806         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1807                 (match_operand:SI 2 "logic_operand" "dIM")))]
1808   ""
1809   "*
1810 {
1811   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1812     return \"nand       %C2,%1,%0\";
1813   if (i960_bypass (insn, operands[1], operands[2], 0))
1814     return \"notor      %2,%1,%0\";
1815   return \"ornot        %1,%2,%0\";
1816 }")
1817
1818 (define_insn ""
1819   [(set (match_operand:SI 0 "register_operand" "=d")
1820         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%d"))
1821                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
1822   ""
1823   "*
1824 {
1825   if (i960_bypass (insn, operands[1], operands[2], 0))
1826     return \"nor        %2,%1,%0\";
1827   return \"nor  %1,%2,%0\";
1828 }")
1829
1830 (define_insn "xorsi3"
1831   [(set (match_operand:SI 0 "register_operand" "=d")
1832         (xor:SI (match_operand:SI 1 "register_operand" "%d")
1833                 (match_operand:SI 2 "logic_operand" "dIM")))]
1834   ""
1835   "*
1836 {
1837   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1838     return \"xnor       %C2,%1,%0\";
1839   if (i960_bypass (insn, operands[1], operands[2], 0))
1840     return \"xor        %2,%1,%0\";
1841   return \"xor  %1,%2,%0\";
1842 }")
1843
1844 (define_insn ""
1845   [(set (match_operand:SI 0 "register_operand" "=d")
1846         (xor:SI (match_operand:SI 1 "arith_operand" "dI")
1847                 (match_operand:SI 2 "power2_operand" "n")))]
1848   ""
1849   "*
1850 {
1851   operands[2] = GEN_INT (bitpos (INTVAL (operands[2])));
1852   return \"notbit       %2,%1,%0\";
1853 }")
1854
1855 (define_insn ""
1856   [(set (match_operand:SI 0 "register_operand" "=d")
1857         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%d")
1858                         (match_operand:SI 2 "register_operand" "d"))))]
1859   ""
1860   "*
1861 {
1862   if (i960_bypass (insn, operands[1], operands[2], 0))
1863     return \"xnor       %2,%1,%0\";
1864   return \"xnor %2,%1,%0\";
1865 }")
1866
1867 (define_insn ""
1868   [(set (match_operand:SI 0 "register_operand" "=d")
1869         (ior:SI (ashift:SI (const_int 1)
1870                            (match_operand:SI 1 "register_operand" "d"))
1871                 (match_operand:SI 2 "arith_operand" "dI")))]
1872   ""
1873   "setbit       %1,%2,%0")
1874
1875 ;; (not (ashift 1 reg)) canonicalizes to (rotate -2 reg)
1876 (define_insn ""
1877   [(set (match_operand:SI 0 "register_operand" "=d")
1878         (and:SI (rotate:SI (const_int -2)
1879                            (match_operand:SI 1 "register_operand" "d"))
1880                 (match_operand:SI 2 "register_operand" "d")))]
1881   ""
1882   "clrbit       %1,%2,%0")
1883
1884 ;; The above pattern canonicalizes to this when both the input and output
1885 ;; are the same pseudo-register.
1886 (define_insn ""
1887   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
1888                          (const_int 1)
1889                          (match_operand:SI 1 "register_operand" "d"))
1890         (const_int 0))]
1891   ""
1892   "clrbit       %1,%0,%0")
1893
1894 (define_insn ""
1895   [(set (match_operand:SI 0 "register_operand" "=d")
1896         (xor:SI (ashift:SI (const_int 1)
1897                            (match_operand:SI 1 "register_operand" "d"))
1898                 (match_operand:SI 2 "arith_operand" "dI")))]
1899   ""
1900   "notbit       %1,%2,%0")
1901
1902 (define_insn "negsi2"
1903   [(set (match_operand:SI 0 "register_operand" "=d")
1904         (neg:SI (match_operand:SI 1 "arith_operand" "dI")))]
1905   ""
1906   "subo %1,0,%0"
1907   [(set_attr "length" "1")])
1908
1909 (define_insn "one_cmplsi2"
1910   [(set (match_operand:SI 0 "register_operand" "=d")
1911         (not:SI (match_operand:SI 1 "arith_operand" "dI")))]
1912   ""
1913   "not  %1,%0"
1914   [(set_attr "length" "1")])
1915 \f
1916 ;; Floating point arithmetic instructions.
1917
1918 (define_insn "adddf3"
1919   [(set (match_operand:DF 0 "register_operand" "=d*f")
1920         (plus:DF (match_operand:DF 1 "fp_arith_operand" "%rGH")
1921                  (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1922   "TARGET_NUMERICS"
1923   "addrl        %1,%2,%0"
1924   [(set_attr "type" "fpadd")])
1925
1926 (define_insn "addsf3"
1927   [(set (match_operand:SF 0 "register_operand" "=d*f")
1928         (plus:SF (match_operand:SF 1 "fp_arith_operand" "%rGH")
1929                  (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1930   "TARGET_NUMERICS"
1931   "addr %1,%2,%0"
1932   [(set_attr "type" "fpadd")])
1933
1934
1935 (define_insn "subdf3"
1936   [(set (match_operand:DF 0 "register_operand" "=d*f")
1937         (minus:DF (match_operand:DF 1 "fp_arith_operand" "rGH")
1938                   (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1939   "TARGET_NUMERICS"
1940   "subrl        %2,%1,%0"
1941   [(set_attr "type" "fpadd")])
1942
1943 (define_insn "subsf3"
1944   [(set (match_operand:SF 0 "register_operand" "=d*f")
1945         (minus:SF (match_operand:SF 1 "fp_arith_operand" "rGH")
1946                   (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1947   "TARGET_NUMERICS"
1948   "subr %2,%1,%0"
1949   [(set_attr "type" "fpadd")])
1950
1951
1952 (define_insn "muldf3"
1953   [(set (match_operand:DF 0 "register_operand" "=d*f")
1954         (mult:DF (match_operand:DF 1 "fp_arith_operand" "%rGH")
1955                  (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1956   "TARGET_NUMERICS"
1957   "mulrl        %1,%2,%0"
1958   [(set_attr "type" "fpmul")])
1959
1960 (define_insn "mulsf3"
1961   [(set (match_operand:SF 0 "register_operand" "=d*f")
1962         (mult:SF (match_operand:SF 1 "fp_arith_operand" "%rGH")
1963                  (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1964   "TARGET_NUMERICS"
1965   "mulr %1,%2,%0"
1966   [(set_attr "type" "fpmul")])
1967
1968
1969 (define_insn "divdf3"
1970   [(set (match_operand:DF 0 "register_operand" "=d*f")
1971         (div:DF (match_operand:DF 1 "fp_arith_operand" "rGH")
1972                 (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1973   "TARGET_NUMERICS"
1974   "divrl        %2,%1,%0"
1975   [(set_attr "type" "fpdiv")])
1976
1977 (define_insn "divsf3"
1978   [(set (match_operand:SF 0 "register_operand" "=d*f")
1979         (div:SF (match_operand:SF 1 "fp_arith_operand" "rGH")
1980                 (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1981   "TARGET_NUMERICS"
1982   "divr %2,%1,%0"
1983   [(set_attr "type" "fpdiv")])
1984
1985 (define_insn "negdf2"
1986   [(set (match_operand:DF 0 "register_operand" "=d,d*f")
1987         (neg:DF (match_operand:DF 1 "register_operand" "d,r")))]
1988   ""
1989   "*
1990 {
1991   if (which_alternative == 0)
1992     {
1993       if (REGNO (operands[0]) == REGNO (operands[1]))
1994         return \"notbit 31,%D1,%D0\";
1995       return \"mov      %1,%0\;notbit   31,%D1,%D0\";
1996     }
1997   return \"subrl        %1,0f0.0,%0\";
1998 }"
1999   [(set_attr "type" "fpadd")])
2000
2001 (define_insn "negsf2"
2002   [(set (match_operand:SF 0 "register_operand" "=d,d*f")
2003         (neg:SF (match_operand:SF 1 "register_operand" "d,r")))]
2004   ""
2005   "@
2006   notbit        31,%1,%0
2007   subr  %1,0f0.0,%0"
2008   [(set_attr "type" "fpadd")])
2009
2010 ;;; The abs patterns also work even if the target machine doesn't have
2011 ;;; floating point, because in that case dstreg and srcreg will always be
2012 ;;; less than 32.
2013
2014 (define_insn "absdf2"
2015   [(set (match_operand:DF 0 "register_operand" "=d*f")
2016         (abs:DF (match_operand:DF 1 "register_operand" "df")))]
2017   ""
2018   "*
2019 {
2020   int dstreg = REGNO (operands[0]);
2021   int srcreg = REGNO (operands[1]);
2022
2023   if (dstreg < 32)
2024     {
2025       if (srcreg < 32)
2026         {
2027           if (dstreg != srcreg)
2028             output_asm_insn (\"mov      %1,%0\", operands);
2029           return \"clrbit       31,%D1,%D0\";
2030         }
2031       /* Src is an fp reg.  */
2032       return \"movrl    %1,%0\;clrbit   31,%D1,%D0\";
2033     }
2034   if (srcreg >= 32)
2035     return \"cpysre     %1,0f0.0,%0\";
2036   return \"movrl        %1,%0\;cpysre   %0,0f0.0,%0\";
2037 }"
2038   [(set_attr "type" "multi")])
2039
2040 (define_insn "abssf2"
2041   [(set (match_operand:SF 0 "register_operand" "=d*f")
2042         (abs:SF (match_operand:SF 1 "register_operand" "df")))]
2043   ""
2044   "*
2045 {
2046   int dstreg = REGNO (operands[0]);
2047   int srcreg = REGNO (operands[1]);
2048
2049   if (dstreg < 32 && srcreg < 32)
2050     return \"clrbit     31,%1,%0\";
2051
2052   if (dstreg >= 32 && srcreg >= 32)
2053     return \"cpysre     %1,0f0.0,%0\";
2054
2055   if (dstreg < 32)
2056     return \"movr       %1,%0\;clrbit   31,%0,%0\";
2057
2058   return \"movr %1,%0\;cpysre   %0,0f0.0,%0\";
2059 }"
2060   [(set_attr "type" "multi")])
2061 \f
2062 ;; Tetra (16 byte) float support.
2063
2064 (define_expand "cmpxf"
2065   [(set (reg:CC 36)
2066         (compare:CC (match_operand:XF 0 "register_operand" "")
2067                     (match_operand:XF 1 "nonmemory_operand" "")))]
2068   "TARGET_NUMERICS"
2069   "
2070 {
2071   i960_compare_op0 = operands[0];
2072   i960_compare_op1 = operands[1];
2073   DONE;
2074 }")
2075
2076 (define_insn ""
2077   [(set (reg:CC 36)
2078         (compare:CC (match_operand:XF 0 "register_operand" "f")
2079                     (match_operand:XF 1 "nonmemory_operand" "fGH")))]
2080   "TARGET_NUMERICS"
2081   "cmpr %0,%1"
2082   [(set_attr "type" "fpcc")])
2083
2084 (define_expand "movxf"
2085   [(set (match_operand:XF 0 "general_operand" "")
2086         (match_operand:XF 1 "fpmove_src_operand" ""))]
2087   ""
2088   "
2089 {
2090   if (emit_move_sequence (operands, XFmode))
2091     DONE;
2092 }")
2093
2094 (define_insn ""
2095   [(set (match_operand:XF 0 "general_operand" "=r,f,d,d,m")
2096         (match_operand:XF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
2097   "register_operand (operands[0], XFmode)
2098    || register_operand (operands[1], XFmode)"
2099   "*
2100 {
2101   switch (which_alternative)
2102     {
2103     case 0:
2104       if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2105         return \"movre  %1,%0\";
2106       else
2107         return \"movq   %1,%0\";
2108     case 1:
2109       return \"movre    %1,%0\";
2110     case 2:
2111       return i960_output_ldconst (operands[0], operands[1]);
2112     case 3:
2113       return \"ldt      %1,%0\";
2114     case 4:
2115       return \"stt      %1,%0\";
2116     default:
2117       abort();
2118     }
2119 }"
2120   [(set_attr "type" "move,move,load,fpload,fpstore")])
2121
2122 (define_insn "extendsfxf2"
2123   [(set (match_operand:XF 0 "register_operand" "=f,d")
2124         (float_extend:XF
2125          (match_operand:SF 1 "register_operand" "d,f")))]
2126   "TARGET_NUMERICS"
2127   "@
2128   movr  %1,%0
2129   movre %1,%0"
2130   [(set_attr "type" "fpmove")])
2131
2132 (define_insn "extenddfxf2"
2133   [(set (match_operand:XF 0 "register_operand" "=f,d")
2134         (float_extend:XF
2135          (match_operand:DF 1 "register_operand" "d,f")))]
2136   "TARGET_NUMERICS"
2137   "@
2138   movrl %1,%0
2139   movre %1,%0"
2140   [(set_attr "type" "fpmove")])
2141
2142 (define_insn "truncxfdf2"
2143   [(set (match_operand:DF 0 "register_operand" "=d")
2144         (float_truncate:DF
2145          (match_operand:XF 1 "register_operand" "f")))]
2146   "TARGET_NUMERICS"
2147   "movrl        %1,%0"
2148   [(set_attr "type" "fpmove")])
2149
2150 (define_insn "truncxfsf2"
2151   [(set (match_operand:SF 0 "register_operand" "=d")
2152         (float_truncate:SF
2153          (match_operand:XF 1 "register_operand" "f")))]
2154   "TARGET_NUMERICS"
2155   "movr %1,%0"
2156   [(set_attr "type" "fpmove")])
2157
2158 (define_insn "floatsixf2"
2159   [(set (match_operand:XF 0 "register_operand" "=f")
2160         (float:XF (match_operand:SI 1 "register_operand" "d")))]
2161   "TARGET_NUMERICS"
2162   "cvtir        %1,%0"
2163   [(set_attr "type" "fpcvt")])
2164
2165 (define_insn "fix_truncxfsi2"
2166   [(set (match_operand:SI 0 "register_operand" "=d")
2167         (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))]
2168   "TARGET_NUMERICS"
2169   "cvtzri       %1,%0"
2170   [(set_attr "type" "fpcvt")])
2171
2172 (define_insn "fixuns_truncxfsi2"
2173   [(set (match_operand:SI 0 "register_operand" "=d")
2174         (unsigned_fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))]
2175   "TARGET_NUMERICS"
2176   "cvtzri       %1,%0"
2177   [(set_attr "type" "fpcvt")])
2178
2179 (define_insn "addxf3"
2180   [(set (match_operand:XF 0 "register_operand" "=f")
2181         (plus:XF (match_operand:XF 1 "nonmemory_operand" "%fGH")
2182                  (match_operand:XF 2 "nonmemory_operand" "fGH")))]
2183   "TARGET_NUMERICS"
2184   "addr %1,%2,%0"
2185   [(set_attr "type" "fpadd")])
2186
2187 (define_insn "subxf3"
2188   [(set (match_operand:XF 0 "register_operand" "=f")
2189         (minus:XF (match_operand:XF 1 "nonmemory_operand" "fGH")
2190                   (match_operand:XF 2 "nonmemory_operand" "fGH")))]
2191   "TARGET_NUMERICS"
2192   "subr %2,%1,%0"
2193   [(set_attr "type" "fpadd")])
2194
2195 (define_insn "mulxf3"
2196   [(set (match_operand:XF 0 "register_operand" "=f")
2197         (mult:XF (match_operand:XF 1 "nonmemory_operand" "%fGH")
2198                  (match_operand:XF 2 "nonmemory_operand" "fGH")))]
2199   "TARGET_NUMERICS"
2200   "mulr %1,%2,%0"
2201   [(set_attr "type" "fpmul")])
2202
2203 (define_insn "divxf3"
2204   [(set (match_operand:XF 0 "register_operand" "=f")
2205         (div:XF (match_operand:XF 1 "nonmemory_operand" "fGH")
2206                 (match_operand:XF 2 "nonmemory_operand" "fGH")))]
2207   "TARGET_NUMERICS"
2208   "divr %2,%1,%0"
2209   [(set_attr "type" "fpdiv")])
2210
2211 (define_insn "negxf2"
2212   [(set (match_operand:XF 0 "register_operand" "=f")
2213         (neg:XF (match_operand:XF 1 "register_operand" "f")))]
2214   "TARGET_NUMERICS"
2215   "subr %1,0f0.0,%0"
2216   [(set_attr "type" "fpadd")])
2217
2218 (define_insn "absxf2"
2219   [(set (match_operand:XF 0 "register_operand" "=f")
2220         (abs:XF (match_operand:XF 1 "register_operand" "f")))]
2221   "(TARGET_NUMERICS)"
2222   "cpysre       %1,0f0.0,%0"
2223   [(set_attr "type" "fpmove")])
2224 \f
2225 ;; Arithmetic shift instructions.
2226
2227 ;; The shli instruction generates an overflow fault if the sign changes.
2228 ;; In the case of overflow, it does not give the natural result, it instead
2229 ;; gives the last shift value before the overflow.  We can not use this
2230 ;; instruction because gcc thinks that arithmetic left shift and logical
2231 ;; left shift are identical, and sometimes canonicalizes the logical left
2232 ;; shift to an arithmetic left shift.  Therefore we must always use the
2233 ;; logical left shift instruction.
2234
2235 (define_insn "ashlsi3"
2236   [(set (match_operand:SI 0 "register_operand" "=d")
2237         (ashift:SI (match_operand:SI 1 "arith_operand" "dI")
2238                    (match_operand:SI 2 "arith_operand" "dI")))]
2239   ""
2240   "shlo %2,%1,%0"
2241   [(set_attr "type" "alu2")])
2242
2243 (define_insn "ashrsi3"
2244   [(set (match_operand:SI 0 "register_operand" "=d")
2245         (ashiftrt:SI (match_operand:SI 1 "arith_operand" "dI")
2246                      (match_operand:SI 2 "arith_operand" "dI")))]
2247   ""
2248   "shri %2,%1,%0"
2249   [(set_attr "type" "alu2")])
2250
2251 (define_insn "lshrsi3"
2252   [(set (match_operand:SI 0 "register_operand" "=d")
2253         (lshiftrt:SI (match_operand:SI 1 "arith_operand" "dI")
2254                    (match_operand:SI 2 "arith_operand" "dI")))]
2255   ""
2256   "shro %2,%1,%0"
2257   [(set_attr "type" "alu2")])
2258 \f
2259 ;; Unconditional and other jump instructions.
2260
2261 (define_insn "jump"
2262   [(set (pc)
2263         (label_ref (match_operand 0 "" "")))]
2264   ""
2265   "b    %l0"
2266   [(set_attr "type" "branch")])
2267
2268 (define_insn "indirect_jump"
2269   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2270   ""
2271   "bx   %a0"
2272   [(set_attr "type" "branch")])
2273
2274 (define_insn "tablejump"
2275   [(set (pc) (match_operand:SI 0 "register_operand" "d"))
2276    (use (label_ref (match_operand 1 "" "")))]
2277   ""
2278   "*
2279 {
2280   if (flag_pic)
2281     return \"bx %l1(%0)\";
2282   else
2283     return \"bx (%0)\";
2284 }"
2285   [(set_attr "type" "branch")])
2286
2287 ;;- jump to subroutine
2288
2289 (define_expand "call"
2290   [(call (match_operand:SI 0 "memory_operand" "m")
2291          (match_operand:SI 1 "immediate_operand" "i"))]
2292   ""
2293   "
2294 {
2295   emit_insn (gen_call_internal (operands[0], operands[1],
2296                                 virtual_outgoing_args_rtx));
2297   DONE;
2298 }")
2299
2300 ;; We need a call saved register allocated for the match_scratch, so we use
2301 ;; 'l' because all local registers are call saved.
2302
2303 ;; ??? I would prefer to use a match_scratch here, but match_scratch allocated
2304 ;; registers can't be used for spills.  In a function with lots of calls,
2305 ;; local-alloc may allocate all local registers to a match_scratch, leaving
2306 ;; no local registers available for spills.
2307
2308 (define_insn "call_internal"
2309   [(call (match_operand:SI 0 "memory_operand" "m")
2310          (match_operand:SI 1 "immediate_operand" "i"))
2311    (use (match_operand:SI 2 "address_operand" "p"))
2312    (clobber (reg:SI 19))]
2313   ""
2314   "* return i960_output_call_insn (operands[0], operands[1], operands[2],
2315                                    insn);"
2316   [(set_attr "type" "call")])
2317
2318 (define_expand "call_value"
2319   [(set (match_operand 0 "register_operand" "=d")
2320         (call (match_operand:SI 1 "memory_operand" "m")
2321               (match_operand:SI 2 "immediate_operand" "i")))]
2322   ""
2323   "
2324 {
2325   emit_insn (gen_call_value_internal (operands[0], operands[1], operands[2],
2326                                       virtual_outgoing_args_rtx));
2327   DONE;
2328 }")
2329
2330 ;; We need a call saved register allocated for the match_scratch, so we use
2331 ;; 'l' because all local registers are call saved.
2332
2333 (define_insn "call_value_internal"
2334   [(set (match_operand 0 "register_operand" "=d")
2335         (call (match_operand:SI 1 "memory_operand" "m")
2336               (match_operand:SI 2 "immediate_operand" "i")))
2337    (use (match_operand:SI 3 "address_operand" "p"))
2338    (clobber (reg:SI 19))]
2339   ""
2340   "* return i960_output_call_insn (operands[1], operands[2], operands[3],
2341                                    insn);"
2342   [(set_attr "type" "call")])
2343
2344 (define_insn "return"
2345   [(return)]
2346   ""
2347   "* return i960_output_ret_insn (insn);"
2348   [(set_attr "type" "branch")])
2349
2350 ;; A return instruction.  Used only by nonlocal_goto to change the
2351 ;; stack pointer, frame pointer, previous frame pointer and the return
2352 ;; instruction pointer.
2353 (define_insn "ret"
2354   [(set (pc) (unspec_volatile [(reg:SI 16)] 3))]
2355   ""
2356   "ret"
2357   [(set_attr "type" "branch")
2358    (set_attr "length" "1")])
2359
2360 (define_expand "nonlocal_goto"
2361   [(match_operand:SI 0 "" "")
2362    (match_operand:SI 1 "general_operand" "")
2363    (match_operand:SI 2 "general_operand" "")
2364    (match_operand:SI 3 "general_operand" "")]
2365   ""
2366   "
2367 {
2368   rtx chain = operands[0];
2369   rtx handler = operands[1];
2370   rtx stack = operands[2];
2371
2372   /* We must restore the stack pointer, frame pointer, previous frame
2373      pointer and the return instruction pointer.  Since the ret
2374      instruction does all this for us with one instruction, we arrange
2375      everything so that ret will do everything we need done.  */
2376
2377   /* First, we must flush the register windows, so that we can modify
2378      the saved local registers on the stack directly and because we
2379      are going to change the previous frame pointer.  */
2380
2381   emit_insn (gen_flush_register_windows ());
2382
2383   /* Load the static chain value for the containing fn into fp.  This is needed
2384      because STACK refers to fp.  */
2385   emit_move_insn (hard_frame_pointer_rtx, chain);
2386
2387   /* Now move the adjusted value into the pfp register for the following return
2388      instruction.  */
2389   emit_move_insn (gen_rtx (REG, SImode, 16),
2390                   plus_constant (hard_frame_pointer_rtx, -64));
2391
2392   /* Next, we put the address that we want to transfer to, into the
2393      saved $rip value in the frame.  Once we ret below, that value
2394      will be loaded into the pc (IP).  */
2395
2396   emit_move_insn (gen_rtx (MEM, SImode,
2397                            plus_constant (hard_frame_pointer_rtx, -56)),
2398                   handler);
2399
2400   /* Next, we put stack into the saved $sp value in the frame.  */
2401   emit_move_insn (gen_rtx (MEM, SImode,
2402                            plus_constant (hard_frame_pointer_rtx, -60)),
2403                   stack);
2404
2405   /* And finally, we can now just ret to get all the values saved
2406      above into all the right registers, and also, all the local
2407      register that were in use in the function, are restored from
2408      their saved values (from the call instruction) on the stack
2409      because we are very careful to ret from the exact save area in
2410      use during the original call.  */
2411
2412   emit_jump_insn (gen_ret ());
2413   emit_barrier ();
2414   DONE;
2415 }")
2416
2417 ;; Special insn to flush register windows.
2418 (define_insn "flush_register_windows"
2419   [(unspec_volatile [(const_int 0)] 1)]
2420   ""
2421   "flushreg"
2422   [(set_attr "type" "misc")
2423    (set_attr "length" "1")])
2424
2425 (define_insn "nop"
2426   [(const_int 0)]
2427   ""
2428   "")
2429 \f
2430 ;; Various peephole optimizations for multiple-word moves, loads, and stores.
2431 ;; Multiple register moves.
2432
2433 ;; Matched 5/28/91
2434 (define_peephole
2435   [(set (match_operand:SI 0 "register_operand" "=r")
2436         (match_operand:SI 1 "register_operand" "r"))
2437    (set (match_operand:SI 2 "register_operand" "=r")
2438         (match_operand:SI 3 "register_operand" "r"))
2439    (set (match_operand:SI 4 "register_operand" "=r")
2440         (match_operand:SI 5 "register_operand" "r"))
2441    (set (match_operand:SI 6 "register_operand" "=r")
2442         (match_operand:SI 7 "register_operand" "r"))]
2443   "((REGNO (operands[0]) & 3) == 0)
2444    && ((REGNO (operands[1]) & 3) == 0)
2445    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2446    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2447    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2448    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))
2449    && (REGNO (operands[0]) + 3 == REGNO (operands[6]))
2450    && (REGNO (operands[1]) + 3 == REGNO (operands[7]))"
2451   "movq %1,%0")
2452
2453 ;; Matched 4/17/92
2454 (define_peephole
2455   [(set (match_operand:DI 0 "register_operand" "=r")
2456         (match_operand:DI 1 "register_operand" "r"))
2457    (set (match_operand:DI 2 "register_operand" "=r")
2458         (match_operand:DI 3 "register_operand" "r"))]
2459   "((REGNO (operands[0]) & 3) == 0)
2460    && ((REGNO (operands[1]) & 3) == 0)
2461    && (REGNO (operands[0]) + 2 == REGNO (operands[2]))
2462    && (REGNO (operands[1]) + 2 == REGNO (operands[3]))"
2463   "movq %1,%0")
2464
2465 ;; Matched 4/17/92
2466 (define_peephole
2467   [(set (match_operand:DI 0 "register_operand" "=r")
2468         (match_operand:DI 1 "register_operand" "r"))
2469    (set (match_operand:SI 2 "register_operand" "=r")
2470         (match_operand:SI 3 "register_operand" "r"))
2471    (set (match_operand:SI 4 "register_operand" "=r")
2472         (match_operand:SI 5 "register_operand" "r"))]
2473   "((REGNO (operands[0]) & 3) == 0)
2474    && ((REGNO (operands[1]) & 3) == 0)
2475    && (REGNO (operands[0]) + 2 == REGNO (operands[2]))
2476    && (REGNO (operands[1]) + 2 == REGNO (operands[3]))
2477    && (REGNO (operands[0]) + 3 == REGNO (operands[4]))
2478    && (REGNO (operands[1]) + 3 == REGNO (operands[5]))"
2479   "movq %1,%0")
2480
2481 ;; Matched 4/17/92
2482 (define_peephole
2483   [(set (match_operand:SI 0 "register_operand" "=r")
2484         (match_operand:SI 1 "register_operand" "r"))
2485    (set (match_operand:SI 2 "register_operand" "=r")
2486         (match_operand:SI 3 "register_operand" "r"))
2487    (set (match_operand:DI 4 "register_operand" "=r")
2488         (match_operand:DI 5 "register_operand" "r"))]
2489   "((REGNO (operands[0]) & 3) == 0)
2490    && ((REGNO (operands[1]) & 3) == 0)
2491    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2492    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2493    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2494    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))"
2495   "movq %1,%0")
2496
2497 ;; Matched 4/17/92
2498 (define_peephole
2499   [(set (match_operand:DI 0 "register_operand" "=r")
2500         (match_operand:DI 1 "register_operand" "r"))
2501    (set (match_operand:SI 2 "register_operand" "=r")
2502         (match_operand:SI 3 "register_operand" "r"))]
2503   "((REGNO (operands[0]) & 3) == 0)
2504    && ((REGNO (operands[1]) & 3) == 0)
2505    && (REGNO (operands[0]) + 2 == REGNO (operands[2]))
2506    && (REGNO (operands[1]) + 2 == REGNO (operands[3]))"
2507   "movt %1,%0")
2508
2509 ;; Matched 5/28/91
2510 (define_peephole
2511   [(set (match_operand:SI 0 "register_operand" "=r")
2512         (match_operand:SI 1 "register_operand" "r"))
2513    (set (match_operand:SI 2 "register_operand" "=r")
2514         (match_operand:SI 3 "register_operand" "r"))
2515    (set (match_operand:SI 4 "register_operand" "=r")
2516         (match_operand:SI 5 "register_operand" "r"))]
2517   "((REGNO (operands[0]) & 3) == 0)
2518    && ((REGNO (operands[1]) & 3) == 0)
2519    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2520    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2521    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2522    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))"
2523   "movt %1,%0")
2524
2525 ;; Matched 5/28/91
2526 (define_peephole
2527   [(set (match_operand:SI 0 "register_operand" "=r")
2528         (match_operand:SI 1 "register_operand" "r"))
2529    (set (match_operand:SI 2 "register_operand" "=r")
2530         (match_operand:SI 3 "register_operand" "r"))]
2531   "((REGNO (operands[0]) & 1) == 0)
2532    && ((REGNO (operands[1]) & 1) == 0)
2533    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2534    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))"
2535   "movl %1,%0")
2536 \f
2537 ; Multiple register loads.
2538
2539 ;; Matched 6/15/91
2540 (define_peephole
2541   [(set (match_operand:SI 0 "register_operand" "=r")
2542         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2543                          (match_operand:SI 2 "immediate_operand" "n"))))
2544    (set (match_operand:SI 3 "register_operand" "=r")
2545         (mem:SI (plus:SI (match_dup 1)
2546                          (match_operand:SI 4 "immediate_operand" "n"))))
2547    (set (match_operand:SI 5 "register_operand" "=r")
2548         (mem:SI (plus:SI (match_dup 1)
2549                          (match_operand:SI 6 "immediate_operand" "n"))))
2550    (set (match_operand:SI 7 "register_operand" "=r")
2551         (mem:SI (plus:SI (match_dup 1)
2552                          (match_operand:SI 8 "immediate_operand" "n"))))]
2553   "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2554    && (REGNO (operands[1]) != REGNO (operands[0]))
2555    && (REGNO (operands[0]) + 1 == REGNO (operands[3]))
2556    && (REGNO (operands[1]) != REGNO (operands[3]))
2557    && (REGNO (operands[0]) + 2 == REGNO (operands[5]))
2558    && (REGNO (operands[1]) != REGNO (operands[5]))
2559    && (REGNO (operands[0]) + 3 == REGNO (operands[7]))
2560    && (INTVAL (operands[2]) + 4 == INTVAL (operands[4]))
2561    && (INTVAL (operands[2]) + 8 == INTVAL (operands[6]))
2562    && (INTVAL (operands[2]) + 12 == INTVAL (operands[8])))"
2563   "ldq  %2(%1),%0")
2564
2565 ;; Matched 5/28/91
2566 (define_peephole
2567   [(set (match_operand:DF 0 "register_operand" "=d")
2568         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
2569                          (match_operand:SI 2 "immediate_operand" "n"))))
2570    (set (match_operand:DF 3 "register_operand" "=d")
2571         (mem:DF (plus:SI (match_dup 1)
2572                          (match_operand:SI 4 "immediate_operand" "n"))))]
2573   "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2574    && (REGNO (operands[1]) != REGNO (operands[0]))
2575    && (REGNO (operands[0]) + 2 == REGNO (operands[3]))
2576    && (REGNO (operands[1]) != REGNO (operands[3]))
2577    && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))"
2578   "ldq  %2(%1),%0")
2579
2580 ;; Matched 1/24/92
2581 (define_peephole
2582   [(set (match_operand:DI 0 "register_operand" "=d")
2583         (mem:DI (plus:SI (match_operand:SI 1 "register_operand" "d")
2584                          (match_operand:SI 2 "immediate_operand" "n"))))
2585    (set (match_operand:DI 3 "register_operand" "=d")
2586         (mem:DI (plus:SI (match_dup 1)
2587                          (match_operand:SI 4 "immediate_operand" "n"))))]
2588   "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2589    && (REGNO (operands[1]) != REGNO (operands[0]))
2590    && (REGNO (operands[0]) + 2 == REGNO (operands[3]))
2591    && (REGNO (operands[1]) != REGNO (operands[3]))
2592    && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))"
2593   "ldq  %2(%1),%0")
2594
2595 ;; Matched 4/17/92
2596 (define_peephole
2597   [(set (match_operand:SI 0 "register_operand" "=d")
2598         (mem:SI (match_operand:SI 1 "register_operand" "d")))
2599    (set (match_operand:SI 2 "register_operand" "=d")
2600         (mem:SI (plus:SI (match_dup 1)
2601                          (match_operand:SI 3 "immediate_operand" "n"))))
2602    (set (match_operand:SI 4 "register_operand" "=d")
2603         (mem:SI (plus:SI (match_dup 1)
2604                          (match_operand:SI 5 "immediate_operand" "n"))))
2605    (set (match_operand:SI 6 "register_operand" "=d")
2606         (mem:SI (plus:SI (match_dup 1)
2607                          (match_operand:SI 7 "immediate_operand" "n"))))]
2608   "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0)
2609    && (REGNO (operands[1]) != REGNO (operands[0]))
2610    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2611    && (REGNO (operands[1]) != REGNO (operands[2]))
2612    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2613    && (REGNO (operands[1]) != REGNO (operands[4]))
2614    && (REGNO (operands[0]) + 3 == REGNO (operands[6]))
2615    && (INTVAL (operands[3]) == 4)
2616    && (INTVAL (operands[5]) == 8)
2617    && (INTVAL (operands[7]) == 12))"
2618   "ldq  (%1),%0")
2619
2620 ;; Matched 5/28/91
2621 (define_peephole
2622   [(set (match_operand:SI 0 "register_operand" "=d")
2623         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d")
2624                          (match_operand:SI 2 "immediate_operand" "n"))))
2625    (set (match_operand:SI 3 "register_operand" "=d")
2626         (mem:SI (plus:SI (match_dup 1)
2627                          (match_operand:SI 4 "immediate_operand" "n"))))
2628    (set (match_operand:SI 5 "register_operand" "=d")
2629         (mem:SI (plus:SI (match_dup 1)
2630                          (match_operand:SI 6 "immediate_operand" "n"))))]
2631   "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2632    && (REGNO (operands[1]) != REGNO (operands[0]))
2633    && (REGNO (operands[0]) + 1 == REGNO (operands[3]))
2634    && (REGNO (operands[1]) != REGNO (operands[3]))
2635    && (REGNO (operands[0]) + 2 == REGNO (operands[5]))
2636    && (INTVAL (operands[2]) + 4 == INTVAL (operands[4]))
2637    && (INTVAL (operands[2]) + 8 == INTVAL (operands[6])))"
2638   "ldt  %2(%1),%0")
2639
2640 ;; Matched 6/15/91
2641 (define_peephole
2642   [(set (match_operand:SI 0 "register_operand" "=d")
2643         (mem:SI (match_operand:SI 1 "register_operand" "d")))
2644    (set (match_operand:SI 2 "register_operand" "=d")
2645         (mem:SI (plus:SI (match_dup 1)
2646                          (match_operand:SI 3 "immediate_operand" "n"))))
2647    (set (match_operand:SI 4 "register_operand" "=d")
2648         (mem:SI (plus:SI (match_dup 1)
2649                          (match_operand:SI 5 "immediate_operand" "n"))))]
2650   "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0)
2651    && (REGNO (operands[1]) != REGNO (operands[0]))
2652    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2653    && (REGNO (operands[1]) != REGNO (operands[2]))
2654    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2655    && (INTVAL (operands[3]) == 4)
2656    && (INTVAL (operands[5]) == 8))"
2657   "ldt  (%1),%0")
2658
2659 ;; Matched 5/28/91
2660 (define_peephole
2661   [(set (match_operand:SI 0 "register_operand" "=d")
2662         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d")
2663                          (match_operand:SI 2 "immediate_operand" "n"))))
2664    (set (match_operand:SI 3 "register_operand" "=d")
2665         (mem:SI (plus:SI (match_dup 1)
2666                          (match_operand:SI 4 "immediate_operand" "n"))))]
2667   "(i960_si_di (operands[1], operands[2]) && ((REGNO (operands[0]) & 1) == 0)
2668    && (REGNO (operands[1]) != REGNO (operands[0]))
2669    && (REGNO (operands[0]) + 1 == REGNO (operands[3]))
2670    && (INTVAL (operands[2]) + 4 == INTVAL (operands[4])))"
2671   "ldl  %2(%1),%0")
2672
2673 ;; Matched 5/28/91
2674 (define_peephole
2675   [(set (match_operand:SI 0 "register_operand" "=d")
2676         (mem:SI (match_operand:SI 1 "register_operand" "d")))
2677    (set (match_operand:SI 2 "register_operand" "=d")
2678         (mem:SI (plus:SI (match_dup 1)
2679                          (match_operand:SI 3 "immediate_operand" "n"))))]
2680   "(i960_si_di (operands[1], 0) && ((REGNO (operands[0]) & 1) == 0)
2681    && (REGNO (operands[1]) != REGNO (operands[0]))
2682    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2683    && (INTVAL (operands[3]) == 4))"
2684   "ldl  (%1),%0")
2685 \f
2686 ; Multiple register stores.
2687
2688 ;; Matched 5/28/91
2689 (define_peephole
2690   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d")
2691                          (match_operand:SI 1 "immediate_operand" "n")))
2692         (match_operand:SI 2 "register_operand" "d"))
2693    (set (mem:SI (plus:SI (match_dup 0)
2694                          (match_operand:SI 3 "immediate_operand" "n")))
2695         (match_operand:SI 4 "register_operand" "d"))
2696    (set (mem:SI (plus:SI (match_dup 0)
2697                          (match_operand:SI 5 "immediate_operand" "n")))
2698         (match_operand:SI 6 "register_operand" "d"))
2699    (set (mem:SI (plus:SI (match_dup 0)
2700                          (match_operand:SI 7 "immediate_operand" "n")))
2701         (match_operand:SI 8 "register_operand" "d"))]
2702   "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2703    && (REGNO (operands[2]) + 1 == REGNO (operands[4]))
2704    && (REGNO (operands[2]) + 2 == REGNO (operands[6]))
2705    && (REGNO (operands[2]) + 3 == REGNO (operands[8]))
2706    && (INTVAL (operands[1]) + 4 == INTVAL (operands[3]))
2707    && (INTVAL (operands[1]) + 8 == INTVAL (operands[5]))
2708    && (INTVAL (operands[1]) + 12 == INTVAL (operands[7])))"
2709   "stq  %2,%1(%0)")
2710
2711 ;; Matched 6/16/91
2712 (define_peephole
2713   [(set (mem:DF (plus:SI (match_operand:SI 0 "register_operand" "d")
2714                          (match_operand:SI 1 "immediate_operand" "n")))
2715         (match_operand:DF 2 "register_operand" "d"))
2716    (set (mem:DF (plus:SI (match_dup 0)
2717                          (match_operand:SI 3 "immediate_operand" "n")))
2718         (match_operand:DF 4 "register_operand" "d"))]
2719   "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2720    && (REGNO (operands[2]) + 2 == REGNO (operands[4]))
2721    && (INTVAL (operands[1]) + 8 == INTVAL (operands[3])))"
2722   "stq  %2,%1(%0)")
2723
2724 ;; Matched 4/17/92
2725 (define_peephole
2726   [(set (mem:DI (plus:SI (match_operand:SI 0 "register_operand" "d")
2727                          (match_operand:SI 1 "immediate_operand" "n")))
2728         (match_operand:DI 2 "register_operand" "d"))
2729    (set (mem:DI (plus:SI (match_dup 0)
2730                          (match_operand:SI 3 "immediate_operand" "n")))
2731         (match_operand:DI 4 "register_operand" "d"))]
2732   "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2733    && (REGNO (operands[2]) + 2 == REGNO (operands[4]))
2734    && (INTVAL (operands[1]) + 8 == INTVAL (operands[3])))"
2735   "stq  %2,%1(%0)")
2736
2737 ;; Matched 1/23/92
2738 (define_peephole
2739   [(set (mem:SI (match_operand:SI 0 "register_operand" "d"))
2740         (match_operand:SI 1 "register_operand" "d"))
2741    (set (mem:SI (plus:SI (match_dup 0)
2742                          (match_operand:SI 2 "immediate_operand" "n")))
2743         (match_operand:SI 3 "register_operand" "d"))
2744    (set (mem:SI (plus:SI (match_dup 0)
2745                          (match_operand:SI 4 "immediate_operand" "n")))
2746         (match_operand:SI 5 "register_operand" "d"))
2747    (set (mem:SI (plus:SI (match_dup 0)
2748                          (match_operand:SI 6 "immediate_operand" "n")))
2749         (match_operand:SI 7 "register_operand" "d"))]
2750   "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0)
2751    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2752    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))
2753    && (REGNO (operands[1]) + 3 == REGNO (operands[7]))
2754    && (INTVAL (operands[2]) == 4)
2755    && (INTVAL (operands[4]) == 8)
2756    && (INTVAL (operands[6]) == 12))"
2757   "stq  %1,(%0)")
2758
2759 ;; Matched 5/29/91
2760 (define_peephole
2761   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d")
2762                          (match_operand:SI 1 "immediate_operand" "n")))
2763         (match_operand:SI 2 "register_operand" "d"))
2764    (set (mem:SI (plus:SI (match_dup 0)
2765                          (match_operand:SI 3 "immediate_operand" "n")))
2766         (match_operand:SI 4 "register_operand" "d"))
2767    (set (mem:SI (plus:SI (match_dup 0)
2768                          (match_operand:SI 5 "immediate_operand" "n")))
2769         (match_operand:SI 6 "register_operand" "d"))]
2770   "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2771    && (REGNO (operands[2]) + 1 == REGNO (operands[4]))
2772    && (REGNO (operands[2]) + 2 == REGNO (operands[6]))
2773    && (INTVAL (operands[1]) + 4 == INTVAL (operands[3]))
2774    && (INTVAL (operands[1]) + 8 == INTVAL (operands[5])))"
2775   "stt  %2,%1(%0)")
2776
2777 ;; Matched 5/29/91
2778 (define_peephole
2779   [(set (mem:SI (match_operand:SI 0 "register_operand" "d"))
2780         (match_operand:SI 1 "register_operand" "d"))
2781    (set (mem:SI (plus:SI (match_dup 0)
2782                          (match_operand:SI 2 "immediate_operand" "n")))
2783         (match_operand:SI 3 "register_operand" "d"))
2784    (set (mem:SI (plus:SI (match_dup 0)
2785                          (match_operand:SI 4 "immediate_operand" "n")))
2786         (match_operand:SI 5 "register_operand" "d"))]
2787   "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0)
2788    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2789    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))
2790    && (INTVAL (operands[2]) == 4)
2791    && (INTVAL (operands[4]) == 8))"
2792   "stt  %1,(%0)")
2793
2794 ;; Matched 5/28/91
2795 (define_peephole
2796   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d")
2797                          (match_operand:SI 1 "immediate_operand" "n")))
2798         (match_operand:SI 2 "register_operand" "d"))
2799    (set (mem:SI (plus:SI (match_dup 0)
2800                          (match_operand:SI 3 "immediate_operand" "n")))
2801         (match_operand:SI 4 "register_operand" "d"))]
2802   "(i960_si_di (operands[0], operands[1]) && ((REGNO (operands[2]) & 1) == 0)
2803    && (REGNO (operands[2]) + 1 == REGNO (operands[4]))
2804    && (INTVAL (operands[1]) + 4 == INTVAL (operands[3])))"
2805   "stl  %2,%1(%0)")
2806
2807 ;; Matched 5/28/91
2808 (define_peephole
2809   [(set (mem:SI (match_operand:SI 0 "register_operand" "d"))
2810         (match_operand:SI 1 "register_operand" "d"))
2811    (set (mem:SI (plus:SI (match_dup 0)
2812                          (match_operand:SI 2 "immediate_operand" "n")))
2813         (match_operand:SI 3 "register_operand" "d"))]
2814   "(i960_si_di (operands[0], 0) && ((REGNO (operands[1]) & 1) == 0)
2815    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2816    && (INTVAL (operands[2]) == 4))"
2817   "stl  %1,(%0)")