gcc2 snapshot 980401 import
[official-gcc.git] / gcc / config / i960 / i960.md
blob679f8dac4ebea1d641d2e26709b25c1ff9cd1d28
1 ;;- Machine description for Intel 80960 chip for GNU C compiler
2 ;;   Copyright (C) 1992, 1995, 1998 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.
7 ;; This file is part of GNU CC.
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.
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.
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.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
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.
33 ;; Insn attributes which describe the i960.
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"))
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)))
54 (define_asm_attributes
55   [(set_attr "length" "1")
56    (set_attr "type" "multi")])
58 ;; (define_function_unit {name} {num-units} {n-users} {test}
59 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
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)
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)
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)
79 ;; Compare instructions.
80 ;; This controls RTL generation and register allocation.
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.
86 ;; We start with the DEFINE_EXPANDs, then 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.
90 ;; Put cmpsi first because it is expected to be the most common.
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   "
99   i960_compare_op0 = operands[0];
100   i960_compare_op1 = operands[1];
101   DONE;
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   "
111   i960_compare_op0 = operands[0];
112   i960_compare_op1 = operands[1];
113   DONE;
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   "
123   i960_compare_op0 = operands[0];
124   i960_compare_op1 = operands[1];
125   DONE;
128 ;; Now the DEFINE_INSNs for the compare and scc cases.  First the compares.
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")])
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")])
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")])
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")])
162 ;; Instruction definitions for branch-on-bit-set and clear insns.
164 (define_insn ""
165   [(set (pc)
166         (if_then_else
167          (ne (sign_extract:SI (match_operand:SI 1 "register_operand" "d")
168                               (const_int 1)
169                               (match_operand:SI 2 "arith_operand" "dI"))
170              (const_int 0))
171          (label_ref (match_operand 3 "" ""))
172          (pc)))]
173   ""
174   "bbs  %2,%1,%l3"
175   [(set_attr "type" "branch")])
177 (define_insn ""
178   [(set (pc)
179         (if_then_else
180          (eq (sign_extract:SI (match_operand:SI 1 "register_operand" "d")
181                               (const_int 1)
182                               (match_operand:SI 2 "arith_operand" "dI"))
183              (const_int 0))
184          (label_ref (match_operand 3 "" ""))
185          (pc)))]
186   ""
187   "bbc  %2,%1,%l3"
188   [(set_attr "type" "branch")])
190 (define_insn ""
191   [(set (pc)
192         (if_then_else
193          (ne (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
194                               (const_int 1)
195                               (match_operand:SI 2 "arith_operand" "dI"))
196              (const_int 0))
197          (label_ref (match_operand 3 "" ""))
198          (pc)))]
199   ""
200   "bbs  %2,%1,%l3"
201   [(set_attr "type" "branch")])
203 (define_insn ""
204   [(set (pc)
205         (if_then_else
206          (eq (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
207                               (const_int 1)
208                               (match_operand:SI 2 "arith_operand" "dI"))
209              (const_int 0))
210          (label_ref (match_operand 3 "" ""))
211          (pc)))]
212   ""
213   "bbc  %2,%1,%l3"
214   [(set_attr "type" "branch")])
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.
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")])
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")])
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")])
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")])
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.
263 (define_expand "seq"
264   [(set (match_operand:SI 0 "general_operand" "=d")
265         (eq:SI (match_dup 1) (const_int 0)))]
266   ""
267   "
269   operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1);
272 (define_expand "sne"
273   [(set (match_operand:SI 0 "general_operand" "=d")
274         (ne:SI (match_dup 1) (const_int 0)))]
275   ""
276   "
278   operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1);
281 (define_expand "sgt"
282   [(set (match_operand:SI 0 "general_operand" "=d")
283         (gt:SI (match_dup 1) (const_int 0)))]
284   ""
285   "
287   operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1);
290 (define_expand "sgtu"
291   [(set (match_operand:SI 0 "general_operand" "=d")
292         (gtu:SI (match_dup 1) (const_int 0)))]
293   ""
294   "
296   operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1);
299 (define_expand "slt"
300   [(set (match_operand:SI 0 "general_operand" "=d")
301         (lt:SI (match_dup 1) (const_int 0)))]
302   ""
303   "
305   operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1);
308 (define_expand "sltu"
309   [(set (match_operand:SI 0 "general_operand" "=d")
310         (ltu:SI (match_dup 1) (const_int 0)))]
311   ""
312   "
314   operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1);
317 (define_expand "sge"
318   [(set (match_operand:SI 0 "general_operand" "=d")
319         (ge:SI (match_dup 1) (const_int 0)))]
320   ""
321   "
323   operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1);
326 (define_expand "sgeu"
327   [(set (match_operand:SI 0 "general_operand" "=d")
328         (geu:SI (match_dup 1) (const_int 0)))]
329   ""
330   "
332   operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1);
335 (define_expand "sle"
336   [(set (match_operand:SI 0 "general_operand" "=d")
337         (le:SI (match_dup 1) (const_int 0)))]
338   ""
339   "
341   operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1);
344 (define_expand "sleu"
345   [(set (match_operand:SI 0 "general_operand" "=d")
346         (leu:SI (match_dup 1) (const_int 0)))]
347   ""
348   "
350   operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1);
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")])
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")])
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")])
374 ;; These control RTL generation for conditional jump insns
375 ;; and match them for register allocation.
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); }")
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); }")
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); }")
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); }")
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); }")
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); }")
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); }")
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); }")
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); }")
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); }")
477 ;; Now the normal branch insns (forward and reverse).
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")])
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")])
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")])
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")])
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")])
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")])
543 ;; Normal move instructions.
544 ;; This code is based on the sparc machine description.
546 (define_expand "movsi"
547   [(set (match_operand:SI 0 "general_operand" "")
548         (match_operand:SI 1 "general_operand" ""))]
549   ""
550   "
552   if (emit_move_sequence (operands, SImode))
553     DONE;
556 ;; The store case can not be separate, because reload may convert a register
557 ;; to register move insn to a store (or load) insn without rerecognizing
558 ;; the insn.
560 ;; The i960 does not have any store constant to memory instruction.  However,
561 ;; the calling convention is defined so that the arg pointer when it is not
562 ;; overwise being used is zero.  Thus, we can handle store zero to memory
563 ;; by storing an unused arg pointer.  The arg pointer will be unused if
564 ;; current_function_args_size is zero and this is not a stdarg/varargs
565 ;; function.  This value of the former variable is not valid until after
566 ;; all rtl generation is complete, including function inlining (because a
567 ;; function that doesn't need an arg pointer may be inlined into a function
568 ;; that does need an arg pointer), so we must also check that
569 ;; rtx_equal_function_value_matters is zero.
571 (define_insn ""
572   [(set (match_operand:SI 0 "general_operand" "=d,d,d,m")
573         (match_operand:SI 1 "general_operand" "dI,i,m,dJ"))]
574   "(current_function_args_size == 0
575     && current_function_varargs == 0
576     && current_function_stdarg == 0
577     && rtx_equal_function_value_matters == 0)
578    && (register_operand (operands[0], SImode)
579        || register_operand (operands[1], SImode)
580        || operands[1] == const0_rtx)"
581   "*
583   switch (which_alternative)
584     {
585     case 0:
586       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
587         {
588           if (GET_CODE (operands[1]) == REG)
589             return \"lda        (%1),%0\";
590           else
591             return \"lda        %1,%0\";
592         }
593       return \"mov      %1,%0\";
594     case 1:
595       return i960_output_ldconst (operands[0], operands[1]);
596     case 2:
597       return \"ld       %1,%0\";
598     case 3:
599       if (operands[1] == const0_rtx)
600         return \"st     g14,%0\";
601       return \"st       %1,%0\";      
602     }
604   [(set_attr "type" "move,address,load,store")
605    (set_attr "length" "*,3,*,*")])
607 (define_insn ""
608   [(set (match_operand:SI 0 "general_operand" "=d,d,d,m")
609         (match_operand:SI 1 "general_operand" "dI,i,m,d"))]
610   "(current_function_args_size != 0
611     || current_function_varargs != 0
612     || current_function_stdarg != 0
613     || rtx_equal_function_value_matters != 0)
614    && (register_operand (operands[0], SImode)
615        || register_operand (operands[1], SImode))"
616   "*
618   switch (which_alternative)
619     {
620     case 0:
621       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
622         {
623           if (GET_CODE (operands[1]) == REG)
624             return \"lda        (%1),%0\";
625           else
626             return \"lda        %1,%0\";
627         }
628       return \"mov      %1,%0\";
629     case 1:
630       return i960_output_ldconst (operands[0], operands[1]);
631     case 2:
632       return \"ld       %1,%0\";
633     case 3:
634       return \"st       %1,%0\";      
635     }
637   [(set_attr "type" "move,address,load,store")
638    (set_attr "length" "*,3,*,*")])
640 (define_expand "movhi"
641   [(set (match_operand:HI 0 "general_operand" "")
642         (match_operand:HI 1 "general_operand" ""))]
643   ""
644   "
646   if (emit_move_sequence (operands, HImode))
647     DONE;
650 ;; Special pattern for zero stores to memory for functions which don't use
651 ;; the arg pointer.
653 ;; The store case can not be separate.  See above.
654 (define_insn ""
655   [(set (match_operand:HI 0 "general_operand" "=d,d,d,m")
656         (match_operand:HI 1 "general_operand" "dI,i,m,dJ"))]
657   "(current_function_args_size == 0
658     && current_function_varargs == 0
659     && current_function_stdarg == 0
660     && rtx_equal_function_value_matters == 0)
661    && (register_operand (operands[0], HImode)
662        || register_operand (operands[1], HImode)
663        || operands[1] == const0_rtx)"
664   "*
666   switch (which_alternative)
667     {
668     case 0:
669       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
670         {
671           if (GET_CODE (operands[1]) == REG)
672             return \"lda        (%1),%0\";
673           else
674             return \"lda        %1,%0\";
675         }
676       return \"mov      %1,%0\";
677     case 1:
678       return i960_output_ldconst (operands[0], operands[1]);
679     case 2:
680       return \"ldos     %1,%0\";
681     case 3:
682       if (operands[1] == const0_rtx)
683         return \"stos   g14,%0\";
684       return \"stos     %1,%0\";
685     }
687   [(set_attr "type" "move,misc,load,store")
688    (set_attr "length" "*,3,*,*")])
690 ;; The store case can not be separate.  See above.
691 (define_insn ""
692   [(set (match_operand:HI 0 "general_operand" "=d,d,d,m")
693         (match_operand:HI 1 "general_operand" "dI,i,m,d"))]
694   "(current_function_args_size != 0
695     || current_function_varargs != 0
696     || current_function_stdarg != 0
697     || rtx_equal_function_value_matters != 0)
698    && (register_operand (operands[0], HImode)
699        || register_operand (operands[1], HImode))"
700   "*
702   switch (which_alternative)
703     {
704     case 0:
705       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
706         {
707           if (GET_CODE (operands[1]) == REG)
708             return \"lda        (%1),%0\";
709           else
710             return \"lda        %1,%0\";
711         }
712       return \"mov      %1,%0\";
713     case 1:
714       return i960_output_ldconst (operands[0], operands[1]);
715     case 2:
716       return \"ldos     %1,%0\";
717     case 3:
718       return \"stos     %1,%0\";
719     }
721   [(set_attr "type" "move,misc,load,store")
722    (set_attr "length" "*,3,*,*")])
724 (define_expand "movqi"
725   [(set (match_operand:QI 0 "general_operand" "")
726         (match_operand:QI 1 "general_operand" ""))]
727   ""
728   "
730   if (emit_move_sequence (operands, QImode))
731     DONE;
734 ;; The store case can not be separate.  See comment above.
735 (define_insn ""
736   [(set (match_operand:QI 0 "general_operand" "=d,d,d,m")
737         (match_operand:QI 1 "general_operand" "dI,i,m,dJ"))]
738   "(current_function_args_size == 0
739     && current_function_varargs == 0
740     && current_function_stdarg == 0
741     && rtx_equal_function_value_matters == 0)
742    && (register_operand (operands[0], QImode)
743        || register_operand (operands[1], QImode)
744        || operands[1] == const0_rtx)"
745   "*
747   switch (which_alternative)
748     {
749     case 0:
750       if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
751         {
752           if (GET_CODE (operands[1]) == REG)
753             return \"lda        (%1),%0\";
754           else
755             return \"lda        %1,%0\";
756         }
757       return \"mov      %1,%0\";
758     case 1:
759       return i960_output_ldconst (operands[0], operands[1]);
760     case 2:
761       return \"ldob     %1,%0\";
762     case 3:
763       if (operands[1] == const0_rtx)
764         return \"stob   g14,%0\";
765       return \"stob     %1,%0\";
766     }
768   [(set_attr "type" "move,misc,load,store")
769    (set_attr "length" "*,3,*,*")])
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,d"))]
775   "(current_function_args_size != 0
776     || current_function_varargs != 0
777     || current_function_stdarg != 0
778     || rtx_equal_function_value_matters != 0)
779    && (register_operand (operands[0], QImode)
780        || register_operand (operands[1], QImode))"
781   "*
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       return \"stob     %1,%0\";
800     }
802   [(set_attr "type" "move,misc,load,store")
803    (set_attr "length" "*,3,*,*")])
805 (define_expand "movdi"
806   [(set (match_operand:DI 0 "general_operand" "")
807         (match_operand:DI 1 "general_operand" ""))]
808   ""
809   "
811   if (emit_move_sequence (operands, DImode))
812     DONE;
815 ;; The store case can not be separate.  See comment above.
816 (define_insn ""
817   [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m,o")
818         (match_operand:DI 1 "general_operand" "d,I,i,m,d,J"))]
819   "(current_function_args_size == 0
820     && current_function_varargs == 0
821     && current_function_stdarg == 0
822     && rtx_equal_function_value_matters == 0)
823    && (register_operand (operands[0], DImode)
824        || register_operand (operands[1], DImode)
825        || operands[1] == const0_rtx)"
826   "*
828   switch (which_alternative)
829     {
830     case 0:
831     case 1:
832     case 3:
833     case 4:
834       return i960_output_move_double (operands[0], operands[1]);
835     case 2:
836       return i960_output_ldconst (operands[0], operands[1]);
837     case 5:
838       operands[1] = adj_offsettable_operand (operands[0], 4);
839       return \"st       g14,%0\;st      g14,%1\";
840     }
842   [(set_attr "type" "move,move,load,load,store,store")])
844 ;; The store case can not be separate.  See comment above.
845 (define_insn ""
846   [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m")
847         (match_operand:DI 1 "general_operand" "d,I,i,m,d"))]
848   "(current_function_args_size != 0
849     || current_function_varargs != 0
850     || current_function_stdarg != 0
851     || rtx_equal_function_value_matters != 0)
852    && (register_operand (operands[0], DImode)
853        || register_operand (operands[1], DImode))"
854   "*
856   switch (which_alternative)
857     {
858     case 0:
859     case 1:
860     case 3:
861     case 4:
862       return i960_output_move_double (operands[0], operands[1]);
863     case 2:
864       return i960_output_ldconst (operands[0], operands[1]);
865     }
867   [(set_attr "type" "move,move,load,load,store")])
869 (define_insn "*store_unaligned_di_reg"
870   [(set (match_operand:DI 0 "general_operand" "=d,m")
871         (match_operand:DI 1 "register_operand" "d,d"))
872    (clobber (match_scratch:SI 2 "=X,&d"))]
873   ""
874   "*
876   if (which_alternative == 0)
877     return i960_output_move_double (operands[0], operands[1]);
878     
879   operands[3] = gen_rtx (MEM, word_mode, operands[2]);
880   operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD);
881   return \"lda  %0,%2\;st       %1,%3\;st       %D1,%4\";
883   [(set_attr "type" "move,store")])
885 (define_expand "movti"
886   [(set (match_operand:TI 0 "general_operand" "")
887         (match_operand:TI 1 "general_operand" ""))]
888   ""
889   "
891   if (emit_move_sequence (operands, TImode))
892     DONE;
895 ;; The store case can not be separate.  See comment above.
896 (define_insn ""
897   [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m,o")
898         (match_operand:TI 1 "general_operand" "d,I,i,m,d,J"))]
899   "(current_function_args_size == 0
900     && current_function_varargs == 0
901     && current_function_stdarg == 0
902     && rtx_equal_function_value_matters == 0)
903    && (register_operand (operands[0], TImode)
904        || register_operand (operands[1], TImode)
905        || operands[1] == const0_rtx)"
906   "*
908   switch (which_alternative)
909     {
910     case 0:
911     case 1:
912     case 3:
913     case 4:
914       return i960_output_move_quad (operands[0], operands[1]);
915     case 2:
916       return i960_output_ldconst (operands[0], operands[1]);
917     case 5:
918       operands[1] = adj_offsettable_operand (operands[0], 4);
919       operands[2] = adj_offsettable_operand (operands[0], 8);
920       operands[3] = adj_offsettable_operand (operands[0], 12);
921       return \"st       g14,%0\;st      g14,%1\;st      g14,%2\;st      g14,%3\";
922     }
924   [(set_attr "type" "move,move,load,load,store,store")])
926 ;; The store case can not be separate.  See comment above.
927 (define_insn ""
928   [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m")
929         (match_operand:TI 1 "general_operand" "d,I,i,m,d"))]
930   "(current_function_args_size != 0
931     || current_function_varargs != 0
932     || current_function_stdarg != 0
933     || rtx_equal_function_value_matters != 0)
934    && (register_operand (operands[0], TImode)
935        || register_operand (operands[1], TImode))"
936   "*
938   switch (which_alternative)
939     {
940     case 0:
941     case 1:
942     case 3:
943     case 4:
944       return i960_output_move_quad (operands[0], operands[1]);
945     case 2:
946       return i960_output_ldconst (operands[0], operands[1]);
947     }
949   [(set_attr "type" "move,move,load,load,store")])
951 (define_insn "*store_unaligned_ti_reg"
952   [(set (match_operand:TI 0 "general_operand" "=d,m")
953         (match_operand:TI 1 "register_operand" "d,d"))
954    (clobber (match_scratch:SI 2 "=X,&d"))]
955   ""
956   "*
958   if (which_alternative == 0)
959     return i960_output_move_quad (operands[0], operands[1]);
961   operands[3] = gen_rtx (MEM, word_mode, operands[2]);
962   operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD);
963   operands[5] = adj_offsettable_operand (operands[4], UNITS_PER_WORD);
964   operands[6] = adj_offsettable_operand (operands[5], UNITS_PER_WORD);
965   return \"lda  %0,%2\;st       %1,%3\;st       %D1,%4\;st      %E1,%5\;st      %F1,%6\";
967   [(set_attr "type" "move,store")])
969 (define_expand "store_multiple"
970   [(set (match_operand:SI 0 "" "")      ;;- dest
971         (match_operand:SI 1 "" ""))     ;;- src
972    (use (match_operand:SI 2 "" ""))]    ;;- nregs
973   ""
974   "
976   int regno;
977   int count;
978   rtx from;
979   int i;
981   if (GET_CODE (operands[0]) != MEM
982       || GET_CODE (operands[1]) != REG
983       || GET_CODE (operands[2]) != CONST_INT)
984     FAIL;
986   count = INTVAL (operands[2]);
987   if (count > 12)
988     FAIL;
990   regno = REGNO (operands[1]);
991   from = memory_address (SImode, XEXP (operands[0], 0));
992   while (count >= 4 && ((regno & 3) == 0))
993     {
994       emit_insn (gen_rtx (SET, VOIDmode,
995                           gen_rtx (MEM, TImode, from),
996                           gen_rtx (REG, TImode, regno)));
997       count -= 4;
998       regno += 4;
999       from = memory_address (TImode, plus_constant (from, 16));
1000     }
1001   while (count >= 2 && ((regno & 1) == 0))
1002     {
1003       emit_insn (gen_rtx (SET, VOIDmode,
1004                           gen_rtx (MEM, DImode, from),
1005                           gen_rtx (REG, DImode, regno)));
1006       count -= 2;
1007       regno += 2;
1008       from = memory_address (DImode, plus_constant (from, 8));
1009     }
1010   while (count > 0)
1011     {
1012       emit_insn (gen_rtx (SET, VOIDmode,
1013                           gen_rtx (MEM, SImode, from),
1014                           gen_rtx (REG, SImode, regno)));
1015       count -= 1;
1016       regno += 1;
1017       from = memory_address (SImode, plus_constant (from, 4));
1018     }
1019   DONE;
1022 ;; Floating point move insns
1024 (define_expand "movdf"
1025   [(set (match_operand:DF 0 "general_operand" "")
1026         (match_operand:DF 1 "fpmove_src_operand" ""))]
1027   ""
1028   "
1030   if (emit_move_sequence (operands, DFmode))
1031     DONE;
1034 (define_insn ""
1035   [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m,o")
1036         (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d,G"))]
1037   "(current_function_args_size == 0
1038     && current_function_varargs == 0
1039     && current_function_stdarg == 0
1040     && rtx_equal_function_value_matters == 0)
1041    && (register_operand (operands[0], DFmode)
1042        || register_operand (operands[1], DFmode)
1043        || operands[1] == CONST0_RTX (DFmode))"
1044   "*
1046   switch (which_alternative)
1047     {
1048     case 0:
1049       if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1050         return \"movrl  %1,%0\";
1051       else
1052         return \"movl   %1,%0\";
1053     case 1:
1054       return \"movrl    %1,%0\";
1055     case 2:
1056       return i960_output_ldconst (operands[0], operands[1]);
1057     case 3:
1058       return \"ldl      %1,%0\";
1059     case 4:
1060       return \"stl      %1,%0\";
1061     case 5:
1062       operands[1] = adj_offsettable_operand (operands[0], 4);
1063       return \"st       g14,%0\;st      g14,%1\";
1064     }
1066   [(set_attr "type" "move,move,load,fpload,fpstore,fpstore")])
1068 (define_insn ""
1069   [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m")
1070         (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
1071   "(current_function_args_size != 0
1072     || current_function_varargs != 0
1073     || current_function_stdarg != 0
1074     || rtx_equal_function_value_matters != 0)
1075    && (register_operand (operands[0], DFmode)
1076        || register_operand (operands[1], DFmode))"
1077   "*
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     }
1096   [(set_attr "type" "move,move,load,fpload,fpstore")])
1098 (define_expand "movsf"
1099   [(set (match_operand:SF 0 "general_operand" "")
1100         (match_operand:SF 1 "fpmove_src_operand" ""))]
1101   ""
1102   "
1104   if (emit_move_sequence (operands, SFmode))
1105     DONE;
1108 (define_insn ""
1109   [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m")
1110         (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,dG"))]
1111   "(current_function_args_size == 0
1112     && current_function_varargs == 0
1113     && current_function_stdarg == 0
1114     && rtx_equal_function_value_matters == 0)
1115    && (register_operand (operands[0], SFmode)
1116        || register_operand (operands[1], SFmode)
1117        || operands[1] == CONST0_RTX (SFmode))"
1118   "*
1120   switch (which_alternative)
1121     {
1122     case 0:
1123       if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1124         return \"movr   %1,%0\";
1125       else
1126         return \"mov    %1,%0\";
1127     case 1:
1128       return \"movr     %1,%0\";
1129     case 2:
1130       return i960_output_ldconst (operands[0], operands[1]);
1131     case 3:
1132       return \"ld       %1,%0\";
1133     case 4:
1134       if (operands[1] == CONST0_RTX (SFmode))
1135         return \"st     g14,%0\";
1136       return \"st       %1,%0\";
1137     }
1139   [(set_attr "type" "move,move,load,fpload,fpstore")])
1141 (define_insn ""
1142   [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m")
1143         (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
1144   "(current_function_args_size != 0
1145     || current_function_varargs != 0
1146     || current_function_stdarg != 0
1147     || rtx_equal_function_value_matters != 0)
1148    && (register_operand (operands[0], SFmode)
1149        || register_operand (operands[1], SFmode))"
1150   "*
1152   switch (which_alternative)
1153     {
1154     case 0:
1155       if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1156         return \"movr   %1,%0\";
1157       else
1158         return \"mov    %1,%0\";
1159     case 1:
1160       return \"movr     %1,%0\";
1161     case 2:
1162       return i960_output_ldconst (operands[0], operands[1]);
1163     case 3:
1164       return \"ld       %1,%0\";
1165     case 4:
1166       return \"st       %1,%0\";
1167     }
1169   [(set_attr "type" "move,move,load,fpload,fpstore")])
1171 ;; Mixed-mode moves with sign and zero-extension.
1173 ;; Note that the one starting from HImode comes before those for QImode
1174 ;; so that a constant operand will match HImode, not QImode.
1176 (define_expand "extendhisi2"
1177   [(set (match_operand:SI 0 "register_operand" "")
1178         (sign_extend:SI
1179          (match_operand:HI 1 "nonimmediate_operand" "")))]
1180  ""
1183   if (GET_CODE (operand1) == REG
1184       || (GET_CODE (operand1) == SUBREG
1185           && GET_CODE (XEXP (operand1, 0)) == REG))
1186     {
1187       rtx temp = gen_reg_rtx (SImode);
1188       rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1189       int op1_subreg_word = 0;
1191       if (GET_CODE (operand1) == SUBREG)
1192         {
1193           op1_subreg_word = SUBREG_WORD (operand1);
1194           operand1 = SUBREG_REG (operand1);
1195         }
1196       operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
1198       emit_insn (gen_ashlsi3 (temp, operand1, shift_16));
1199       emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1200       DONE;
1201     }
1204 (define_insn ""
1205   [(set (match_operand:SI 0 "register_operand" "=d")
1206         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1207   ""
1208   "ldis %1,%0"
1209   [(set_attr "type" "load")])
1211 (define_expand "extendqisi2"
1212   [(set (match_operand:SI 0 "register_operand" "")
1213         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1214   ""
1215   "
1217   if (GET_CODE (operand1) == REG
1218       || (GET_CODE (operand1) == SUBREG
1219           && GET_CODE (XEXP (operand1, 0)) == REG))
1220     {
1221       rtx temp = gen_reg_rtx (SImode);
1222       rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1223       int op1_subreg_word = 0;
1225       if (GET_CODE (operand1) == SUBREG)
1226         {
1227           op1_subreg_word = SUBREG_WORD (operand1);
1228           operand1 = SUBREG_REG (operand1);
1229         }
1230       operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word),
1232       emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1233       emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1234       DONE;
1235     }
1238 (define_insn ""
1239   [(set (match_operand:SI 0 "register_operand" "=d")
1240         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1241   ""
1242   "ldib %1,%0"
1243   [(set_attr "type" "load")])
1245 (define_expand "extendqihi2"
1246   [(set (match_operand:HI 0 "register_operand" "")
1247         (sign_extend:HI
1248          (match_operand:QI 1 "nonimmediate_operand" "")))]
1249   ""
1250   "
1252   if (GET_CODE (operand1) == REG
1253       || (GET_CODE (operand1) == SUBREG
1254           && GET_CODE (XEXP (operand1, 0)) == REG))
1255     {
1256       rtx temp = gen_reg_rtx (SImode);
1257       rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1258       int op0_subreg_word = 0;
1259       int op1_subreg_word = 0;
1261       if (GET_CODE (operand1) == SUBREG)
1262         {
1263           op1_subreg_word = SUBREG_WORD (operand1);
1264           operand1 = SUBREG_REG (operand1);
1265         }
1266       operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
1268       if (GET_CODE (operand0) == SUBREG)
1269         {
1270           op0_subreg_word = SUBREG_WORD (operand0);
1271           operand0 = SUBREG_REG (operand0);
1272         }
1273       if (GET_MODE (operand0) != SImode)
1274         operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subreg_word);
1276       emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1277       emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1278       DONE;
1279     }
1282 (define_insn ""
1283   [(set (match_operand:HI 0 "register_operand" "=d")
1284         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1285   ""
1286   "ldib %1,%0"
1287   [(set_attr "type" "load")])
1289 (define_expand "zero_extendhisi2"
1290   [(set (match_operand:SI 0 "register_operand" "")
1291         (zero_extend:SI
1292          (match_operand:HI 1 "nonimmediate_operand" "")))]
1293  ""
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_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1302       int op1_subreg_word = 0;
1304       if (GET_CODE (operand1) == SUBREG)
1305         {
1306           op1_subreg_word = SUBREG_WORD (operand1);
1307           operand1 = SUBREG_REG (operand1);
1308         }
1309       operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
1311       emit_insn (gen_ashlsi3 (temp, operand1, shift_16));
1312       emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1313       DONE;
1314     }
1317 (define_insn ""
1318   [(set (match_operand:SI 0 "register_operand" "=d")
1319         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1320   ""
1321   "ldos %1,%0"
1322   [(set_attr "type" "load")])
1324 ;; Using shifts here generates much better code than doing an `and 255'.
1325 ;; This is mainly because the `and' requires loading the constant separately,
1326 ;; the constant is likely to get optimized, and then the compiler can't
1327 ;; optimize the `and' because it doesn't know that one operand is a constant.
1329 (define_expand "zero_extendqisi2"
1330   [(set (match_operand:SI 0 "register_operand" "")
1331         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1332   ""
1333   "
1335   if (GET_CODE (operand1) == REG
1336       || (GET_CODE (operand1) == SUBREG
1337           && GET_CODE (XEXP (operand1, 0)) == REG))
1338     {
1339       rtx temp = gen_reg_rtx (SImode);
1340       rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1341       int op1_subreg_word = 0;
1343       if (GET_CODE (operand1) == SUBREG)
1344         {
1345           op1_subreg_word = SUBREG_WORD (operand1);
1346           operand1 = SUBREG_REG (operand1);
1347         }
1348       operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
1350       emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1351       emit_insn (gen_lshrsi3 (operand0, temp, shift_24));
1352       DONE;
1353     }
1356 (define_insn ""
1357   [(set (match_operand:SI 0 "register_operand" "=d")
1358         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1359   ""
1360   "ldob %1,%0"
1361   [(set_attr "type" "load")])
1363 (define_expand "zero_extendqihi2"
1364   [(set (match_operand:HI 0 "register_operand" "")
1365         (zero_extend:HI
1366          (match_operand:QI 1 "nonimmediate_operand" "")))]
1367   ""
1368   "
1370   if (GET_CODE (operand1) == REG
1371       || (GET_CODE (operand1) == SUBREG
1372           && GET_CODE (XEXP (operand1, 0)) == REG))
1373     {
1374       rtx temp = gen_reg_rtx (SImode);
1375       rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1376       int op0_subreg_word = 0;
1377       int op1_subreg_word = 0;
1379       if (GET_CODE (operand1) == SUBREG)
1380         {
1381           op1_subreg_word = SUBREG_WORD (operand1);
1382           operand1 = SUBREG_REG (operand1);
1383         }
1384       operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
1386       if (GET_CODE (operand0) == SUBREG)
1387         {
1388           op0_subreg_word = SUBREG_WORD (operand0);
1389           operand0 = SUBREG_REG (operand0);
1390         }
1391       if (GET_MODE (operand0) != SImode)
1392         operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subreg_word);
1394       emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1395       emit_insn (gen_lshrsi3 (operand0, temp, shift_24));
1396       DONE;
1397     }
1400 (define_insn ""
1401   [(set (match_operand:HI 0 "register_operand" "=d")
1402         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1403   ""
1404   "ldob %1,%0"
1405   [(set_attr "type" "load")])
1407 ;; Conversions between float and double.
1409 (define_insn "extendsfdf2"
1410   [(set (match_operand:DF 0 "register_operand" "=*f,d")
1411         (float_extend:DF (match_operand:SF 1 "fp_arith_operand" "dGH,fGH")))]
1412   "TARGET_NUMERICS"
1413   "@
1414   movr  %1,%0
1415   movrl %1,%0"
1416   [(set_attr "type" "fpmove")])
1418 (define_insn "truncdfsf2"
1419   [(set (match_operand:SF 0 "register_operand" "=d")
1420         (float_truncate:SF
1421          (match_operand:DF 1 "fp_arith_operand" "fGH")))]
1422   "TARGET_NUMERICS"
1423   "movr %1,%0"
1424   [(set_attr "type" "fpmove")])
1426 ;; Conversion between fixed point and floating point.
1428 (define_insn "floatsidf2"
1429   [(set (match_operand:DF 0 "register_operand" "=f")
1430         (float:DF (match_operand:SI 1 "register_operand" "d")))]
1431   "TARGET_NUMERICS"
1432   "cvtir        %1,%0"
1433   [(set_attr "type" "fpcvt")])
1435 (define_insn "floatsisf2"
1436   [(set (match_operand:SF 0 "register_operand" "=d*f")
1437         (float:SF (match_operand:SI 1 "register_operand" "d")))]
1438   "TARGET_NUMERICS"
1439   "cvtir        %1,%0"
1440   [(set_attr "type" "fpcvt")])
1442 ;; Convert a float to an actual integer.
1443 ;; Truncation is performed as part of the conversion.
1444 ;; The i960 requires conversion from DFmode to DImode to make
1445 ;; unsigned conversions work properly.
1447 (define_insn "fixuns_truncdfdi2"
1448   [(set (match_operand:DI 0 "register_operand" "=d")
1449         (unsigned_fix:DI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))]
1450   "TARGET_NUMERICS"
1451   "cvtzril      %1,%0"
1452   [(set_attr "type" "fpcvt")])
1454 (define_insn "fixuns_truncsfdi2"
1455   [(set (match_operand:DI 0 "register_operand" "=d")
1456         (unsigned_fix:DI (fix:SF (match_operand:SF 1 "fp_arith_operand" "fGH"))))]
1457   "TARGET_NUMERICS"
1458   "cvtzril      %1,%0"
1459   [(set_attr "type" "fpcvt")])
1461 (define_insn "fix_truncdfsi2"
1462   [(set (match_operand:SI 0 "register_operand" "=d")
1463         (fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))]
1464   "TARGET_NUMERICS"
1465   "cvtzri       %1,%0"
1466   [(set_attr "type" "fpcvt")])
1468 (define_expand "fixuns_truncdfsi2"
1469   [(set (match_operand:SI 0 "register_operand" "")
1470         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" ""))))]
1471   "TARGET_NUMERICS"
1472   "
1474   rtx temp = gen_reg_rtx (DImode);
1475   emit_insn (gen_rtx (SET, VOIDmode, temp,
1476                       gen_rtx (UNSIGNED_FIX, DImode,
1477                                gen_rtx (FIX, DFmode, operands[1]))));
1478   emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1479                       gen_rtx (SUBREG, SImode, temp, 0)));
1480   DONE;
1483 (define_insn "fix_truncsfsi2"
1484   [(set (match_operand:SI 0 "register_operand" "=d")
1485         (fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" "dfGH"))))]
1486   "TARGET_NUMERICS"
1487   "cvtzri       %1,%0"
1488   [(set_attr "type" "fpcvt")])
1490 (define_expand "fixuns_truncsfsi2"
1491   [(set (match_operand:SI 0 "register_operand" "")
1492         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" ""))))]
1493   "TARGET_NUMERICS"
1494   "
1496   rtx temp = gen_reg_rtx (DImode);
1497   emit_insn (gen_rtx (SET, VOIDmode, temp,
1498                       gen_rtx (UNSIGNED_FIX, DImode,
1499                                gen_rtx (FIX, SFmode, operands[1]))));
1500   emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1501                       gen_rtx (SUBREG, SImode, temp, 0)));
1502   DONE;
1505 ;; Arithmetic instructions.
1507 (define_insn "subsi3"
1508   [(set (match_operand:SI 0 "register_operand" "=d")
1509         (minus:SI (match_operand:SI 1 "arith_operand" "dI")
1510                   (match_operand:SI 2 "arith_operand" "dI")))]
1511   ""
1512   "subo %2,%1,%0")
1514 ;; Try to generate an lda instruction when it would be faster than an
1515 ;; add instruction.
1516 ;; Some assemblers apparently won't accept two addresses added together.
1518 ;; ??? The condition should be improved to reject the case of two
1519 ;; symbolic constants.
1521 (define_insn ""
1522   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1523         (plus:SI (match_operand:SI 1 "arith32_operand" "%dn,i,dn")
1524                  (match_operand:SI 2 "arith32_operand" "dn,dn,i")))]
1525   "(TARGET_C_SERIES) && (CONSTANT_P (operands[1]) || CONSTANT_P (operands[2]))"
1526   "*
1528   if (GET_CODE (operands[1]) == CONST_INT)
1529     {
1530       rtx tmp = operands[1];
1531       operands[1] = operands[2];
1532       operands[2] = tmp;
1533     }
1534   if (GET_CODE (operands[2]) == CONST_INT
1535       && GET_CODE (operands[1]) == REG
1536       && i960_last_insn_type != I_TYPE_REG)
1537     {
1538       if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) > -32)
1539         return \"subo   %n2,%1,%0\";
1540       else if (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32)
1541         return \"addo   %1,%2,%0\";
1542     }
1543   /* Non-canonical results (op1 == const, op2 != const) have been seen
1544      in reload output when both operands were symbols before reload, so
1545      we deal with it here.  This may be a fault of the constraints above.  */
1546   if (CONSTANT_P (operands[1]))
1547     {
1548       if (CONSTANT_P (operands[2]))
1549         return \"lda    %1+%2,%0\";
1550       else
1551         return \"lda    %1(%2),%0\";
1552     }
1553   return \"lda  %2(%1),%0\";
1556 (define_insn "addsi3"
1557   [(set (match_operand:SI 0 "register_operand" "=d")
1558         (plus:SI (match_operand:SI 1 "signed_arith_operand" "%dI")
1559                  (match_operand:SI 2 "signed_arith_operand" "dIK")))]
1560   ""
1561   "*
1563   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1564     return \"subo       %n2,%1,%0\";
1565   if (i960_bypass (insn, operands[1], operands[2], 0))
1566     return \"addo       %2,%1,%0\";
1567   return \"addo %1,%2,%0\";
1570 (define_insn "mulsi3"
1571   [(set (match_operand:SI 0 "register_operand" "=d")
1572         (mult:SI (match_operand:SI 1 "arith_operand" "%dI")
1573                  (match_operand:SI 2 "arith_operand" "dI")))]
1574   ""
1575   "*
1577   if (i960_bypass (insn, operands[1], operands[2], 0))
1578     return \"mulo       %2,%1,%0\";
1579   return \"mulo %1,%2,%0\";
1581   [(set_attr "type" "mult")])
1583 (define_insn "umulsidi3"
1584   [(set (match_operand:DI 0 "register_operand" "=d")
1585         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1586                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1587   ""
1588   "*
1590   if (i960_bypass (insn, operands[1], operands[2], 0))
1591     return \"emul       %2,%1,%0\";
1592   return \"emul %1,%2,%0\";
1594   [(set_attr "type" "mult")])
1596 (define_insn ""
1597   [(set (match_operand:DI 0 "register_operand" "=d")
1598         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%d"))
1599                  (match_operand:SI 2 "literal" "I")))]
1600   ""
1601   "*
1603   if (i960_bypass (insn, operands[1], operands[2], 0))
1604     return \"emul       %2,%1,%0\";
1605   return \"emul %1,%2,%0\";
1607   [(set_attr "type" "mult")])
1609 ;; This goes after the move/add/sub/mul instructions  
1610 ;; because those instructions are better when they apply.
1612 (define_insn ""
1613   [(set (match_operand:SI 0 "register_operand" "=d")
1614         (match_operand:SI 1 "address_operand" "p"))]
1615   ""
1616   "lda  %a1,%0"
1617   [(set_attr "type" "load")])
1619 ;; This will never be selected because of an "optimization" that GCC does.
1620 ;; It always converts divides by a power of 2 into a sequence of instructions
1621 ;; that does a right shift, and then corrects the result if it was negative.
1623 ;; (define_insn ""
1624 ;;   [(set (match_operand:SI 0 "register_operand" "=d")
1625 ;;         (div:SI (match_operand:SI 1 "arith_operand" "dI")
1626 ;;                 (match_operand:SI 2 "power2_operand" "nI")))]
1627 ;;   ""
1628 ;;   "*{
1629 ;;      operands[2] = gen_rtx(CONST_INT, VOIDmode,bitpos (INTVAL (operands[2])));
1630 ;;      return \"shrdi  %2,%1,%0\";
1631 ;;   }"
1633 (define_insn "divsi3"
1634   [(set (match_operand:SI 0 "register_operand" "=d")
1635         (div:SI (match_operand:SI 1 "arith_operand" "dI")
1636                 (match_operand:SI 2 "arith_operand" "dI")))]
1637   ""
1638   "divi %2,%1,%0"
1639   [(set_attr "type" "div")])
1641 (define_insn "udivsi3"
1642   [(set (match_operand:SI 0 "register_operand" "=d")
1643         (udiv:SI (match_operand:SI 1 "arith_operand" "dI")
1644                  (match_operand:SI 2 "arith_operand" "dI")))]
1645   ""
1646   "divo %2,%1,%0"
1647   [(set_attr "type" "div")])
1649 ;; We must use `remi' not `modi' here, to ensure that `%' has the effects
1650 ;; specified by the ANSI C standard.
1652 (define_insn "modsi3"
1653   [(set (match_operand:SI 0 "register_operand" "=d")
1654         (mod:SI (match_operand:SI 1 "arith_operand" "dI")
1655                 (match_operand:SI 2 "arith_operand" "dI")))]
1656   ""
1657   "remi %2,%1,%0"
1658   [(set_attr "type" "div")])
1660 (define_insn "umodsi3"
1661   [(set (match_operand:SI 0 "register_operand" "=d")
1662         (umod:SI (match_operand:SI 1 "arith_operand" "dI")
1663                  (match_operand:SI 2 "arith_operand" "dI")))]
1664   ""
1665   "remo %2,%1,%0"
1666   [(set_attr "type" "div")])
1668 ;; And instructions (with complement also).
1670 (define_insn "andsi3"
1671   [(set (match_operand:SI 0 "register_operand" "=d")
1672         (and:SI (match_operand:SI 1 "register_operand" "%d")
1673                 (match_operand:SI 2 "logic_operand" "dIM")))]
1674   ""
1675   "*
1677   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1678     return \"andnot     %C2,%1,%0\";
1679   if (i960_bypass (insn, operands[1], operands[2], 0))
1680     return \"and        %2,%1,%0\";
1681   return \"and  %1,%2,%0\";
1684 (define_insn ""
1685   [(set (match_operand:SI 0 "register_operand" "=d")
1686         (and:SI (match_operand:SI 1 "arith_operand" "dI")
1687                 (match_operand:SI 2 "cmplpower2_operand" "n")))]
1688   ""
1689   "*
1691   operands[2] = gen_rtx (CONST_INT, VOIDmode,
1692                          bitpos (~INTVAL (operands[2])));
1693   return \"clrbit       %2,%1,%0\";
1696 (define_insn ""
1697   [(set (match_operand:SI 0 "register_operand" "=d")
1698         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1699                 (match_operand:SI 2 "logic_operand" "dIM")))]
1700   ""
1701   "*
1703   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1704     return \"nor        %C2,%1,%0\";
1705   if (i960_bypass (insn, operands[1], operands[2], 0))
1706     return \"notand     %2,%1,%0\";
1707   return \"andnot       %1,%2,%0\";
1710 (define_insn ""
1711   [(set (match_operand:SI 0 "register_operand" "=d")
1712         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "%d"))
1713                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
1714   ""
1715   "*
1717   if (i960_bypass (insn, operands[1], operands[2], 0))
1718     return \"nand       %2,%1,%0\";
1719   return \"nand %1,%2,%0\";
1722 (define_insn "iorsi3"
1723   [(set (match_operand:SI 0 "register_operand" "=d")
1724         (ior:SI (match_operand:SI 1 "register_operand" "%d")
1725                 (match_operand:SI 2 "logic_operand" "dIM")))]
1726   ""
1727   "*
1729   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1730     return \"ornot      %C2,%1,%0\";
1731   if (i960_bypass (insn, operands[1], operands[2], 0))
1732     return \"or %2,%1,%0\";
1733   return \"or   %1,%2,%0\";
1736 (define_insn ""
1737   [(set (match_operand:SI 0 "register_operand" "=d")
1738         (ior:SI (match_operand:SI 1 "register_operand" "d")
1739                 (match_operand:SI 2 "power2_operand" "n")))]
1740   ""
1741   "*
1743   operands[2] = gen_rtx (CONST_INT, VOIDmode,
1744                          bitpos (INTVAL (operands[2])));
1745   return \"setbit       %2,%1,%0\";
1748 (define_insn ""
1749   [(set (match_operand:SI 0 "register_operand" "=d")
1750         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1751                 (match_operand:SI 2 "logic_operand" "dIM")))]
1752   ""
1753   "*
1755   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1756     return \"nand       %C2,%1,%0\";
1757   if (i960_bypass (insn, operands[1], operands[2], 0))
1758     return \"notor      %2,%1,%0\";
1759   return \"ornot        %1,%2,%0\";
1762 (define_insn ""
1763   [(set (match_operand:SI 0 "register_operand" "=d")
1764         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%d"))
1765                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
1766   ""
1767   "*
1769   if (i960_bypass (insn, operands[1], operands[2], 0))
1770     return \"nor        %2,%1,%0\";
1771   return \"nor  %1,%2,%0\";
1774 (define_insn "xorsi3"
1775   [(set (match_operand:SI 0 "register_operand" "=d")
1776         (xor:SI (match_operand:SI 1 "register_operand" "%d")
1777                 (match_operand:SI 2 "logic_operand" "dIM")))]
1778   ""
1779   "*
1781   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1782     return \"xnor       %C2,%1,%0\";
1783   if (i960_bypass (insn, operands[1], operands[2], 0))
1784     return \"xor        %2,%1,%0\";
1785   return \"xor  %1,%2,%0\";
1788 (define_insn ""
1789   [(set (match_operand:SI 0 "register_operand" "=d")
1790         (xor:SI (match_operand:SI 1 "arith_operand" "dI")
1791                 (match_operand:SI 2 "power2_operand" "n")))]
1792   ""
1793   "*
1795   operands[2] = gen_rtx (CONST_INT, VOIDmode,
1796                          bitpos (INTVAL (operands[2])));
1797   return \"notbit       %2,%1,%0\";
1800 (define_insn ""
1801   [(set (match_operand:SI 0 "register_operand" "=d")
1802         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%d")
1803                         (match_operand:SI 2 "register_operand" "d"))))]
1804   ""
1805   "*
1807   if (i960_bypass (insn, operands[1], operands[2], 0))
1808     return \"xnor       %2,%1,%0\";
1809   return \"xnor %2,%1,%0\";
1812 (define_insn ""
1813   [(set (match_operand:SI 0 "register_operand" "=d")
1814         (ior:SI (ashift:SI (const_int 1)
1815                            (match_operand:SI 1 "register_operand" "d"))
1816                 (match_operand:SI 2 "arith_operand" "dI")))]
1817   ""
1818   "setbit       %1,%2,%0")
1820 ;; (not (ashift 1 reg)) canonicalizes to (rotate -2 reg)
1821 (define_insn ""
1822   [(set (match_operand:SI 0 "register_operand" "=d")
1823         (and:SI (rotate:SI (const_int -2)
1824                            (match_operand:SI 1 "register_operand" "d"))
1825                 (match_operand:SI 2 "register_operand" "d")))]
1826   ""
1827   "clrbit       %1,%2,%0")
1829 ;; The above pattern canonicalizes to this when both the input and output
1830 ;; are the same pseudo-register.
1831 (define_insn ""
1832   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "=d")
1833                          (const_int 1)
1834                          (match_operand:SI 1 "register_operand" "d"))
1835         (const_int 0))]
1836   ""
1837   "clrbit       %1,%0,%0")
1839 (define_insn ""
1840   [(set (match_operand:SI 0 "register_operand" "=d")
1841         (xor:SI (ashift:SI (const_int 1)
1842                            (match_operand:SI 1 "register_operand" "d"))
1843                 (match_operand:SI 2 "arith_operand" "dI")))]
1844   ""
1845   "notbit       %1,%2,%0")
1847 (define_insn "negsi2"
1848   [(set (match_operand:SI 0 "register_operand" "=d")
1849         (neg:SI (match_operand:SI 1 "arith_operand" "dI")))]
1850   ""
1851   "subo %1,0,%0"
1852   [(set_attr "length" "1")])
1854 (define_insn "one_cmplsi2"
1855   [(set (match_operand:SI 0 "register_operand" "=d")
1856         (not:SI (match_operand:SI 1 "arith_operand" "dI")))]
1857   ""
1858   "not  %1,%0"
1859   [(set_attr "length" "1")])
1861 ;; Floating point arithmetic instructions.
1863 (define_insn "adddf3"
1864   [(set (match_operand:DF 0 "register_operand" "=d*f")
1865         (plus:DF (match_operand:DF 1 "fp_arith_operand" "%rGH")
1866                  (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1867   "TARGET_NUMERICS"
1868   "addrl        %1,%2,%0"
1869   [(set_attr "type" "fpadd")])
1871 (define_insn "addsf3"
1872   [(set (match_operand:SF 0 "register_operand" "=d*f")
1873         (plus:SF (match_operand:SF 1 "fp_arith_operand" "%rGH")
1874                  (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1875   "TARGET_NUMERICS"
1876   "addr %1,%2,%0"
1877   [(set_attr "type" "fpadd")])
1880 (define_insn "subdf3"
1881   [(set (match_operand:DF 0 "register_operand" "=d*f")
1882         (minus:DF (match_operand:DF 1 "fp_arith_operand" "rGH")
1883                   (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1884   "TARGET_NUMERICS"
1885   "subrl        %2,%1,%0"
1886   [(set_attr "type" "fpadd")])
1888 (define_insn "subsf3"
1889   [(set (match_operand:SF 0 "register_operand" "=d*f")
1890         (minus:SF (match_operand:SF 1 "fp_arith_operand" "rGH")
1891                   (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1892   "TARGET_NUMERICS"
1893   "subr %2,%1,%0"
1894   [(set_attr "type" "fpadd")])
1897 (define_insn "muldf3"
1898   [(set (match_operand:DF 0 "register_operand" "=d*f")
1899         (mult:DF (match_operand:DF 1 "fp_arith_operand" "%rGH")
1900                  (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1901   "TARGET_NUMERICS"
1902   "mulrl        %1,%2,%0"
1903   [(set_attr "type" "fpmul")])
1905 (define_insn "mulsf3"
1906   [(set (match_operand:SF 0 "register_operand" "=d*f")
1907         (mult:SF (match_operand:SF 1 "fp_arith_operand" "%rGH")
1908                  (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1909   "TARGET_NUMERICS"
1910   "mulr %1,%2,%0"
1911   [(set_attr "type" "fpmul")])
1914 (define_insn "divdf3"
1915   [(set (match_operand:DF 0 "register_operand" "=d*f")
1916         (div:DF (match_operand:DF 1 "fp_arith_operand" "rGH")
1917                 (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1918   "TARGET_NUMERICS"
1919   "divrl        %2,%1,%0"
1920   [(set_attr "type" "fpdiv")])
1922 (define_insn "divsf3"
1923   [(set (match_operand:SF 0 "register_operand" "=d*f")
1924         (div:SF (match_operand:SF 1 "fp_arith_operand" "rGH")
1925                 (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1926   "TARGET_NUMERICS"
1927   "divr %2,%1,%0"
1928   [(set_attr "type" "fpdiv")])
1930 (define_insn "negdf2"
1931   [(set (match_operand:DF 0 "register_operand" "=d,d*f")
1932         (neg:DF (match_operand:DF 1 "register_operand" "d,r")))]
1933   ""
1934   "*
1936   if (which_alternative == 0)
1937     {
1938       if (REGNO (operands[0]) == REGNO (operands[1]))
1939         return \"notbit 31,%D1,%D0\";
1940       return \"mov      %1,%0\;notbit   31,%D1,%D0\";
1941     }
1942   return \"subrl        %1,0f0.0,%0\";
1944   [(set_attr "type" "fpadd")])
1946 (define_insn "negsf2"
1947   [(set (match_operand:SF 0 "register_operand" "=d,d*f")
1948         (neg:SF (match_operand:SF 1 "register_operand" "d,r")))]
1949   ""
1950   "@
1951   notbit        31,%1,%0
1952   subr  %1,0f0.0,%0"
1953   [(set_attr "type" "fpadd")])
1955 ;;; The abs patterns also work even if the target machine doesn't have
1956 ;;; floating point, because in that case dstreg and srcreg will always be
1957 ;;; less than 32.
1959 (define_insn "absdf2"
1960   [(set (match_operand:DF 0 "register_operand" "=d*f")
1961         (abs:DF (match_operand:DF 1 "register_operand" "df")))]
1962   ""
1963   "*
1965   int dstreg = REGNO (operands[0]);
1966   int srcreg = REGNO (operands[1]);
1968   if (dstreg < 32)
1969     {
1970       if (srcreg < 32)
1971         {
1972           if (dstreg != srcreg)
1973             output_asm_insn (\"mov      %1,%0\", operands);
1974           return \"clrbit       31,%D1,%D0\";
1975         }
1976       /* Src is an fp reg.  */
1977       return \"movrl    %1,%0\;clrbit   31,%D1,%D0\";
1978     }
1979   if (srcreg >= 32)
1980     return \"cpysre     %1,0f0.0,%0\";
1981   return \"movrl        %1,%0\;cpysre   %0,0f0.0,%0\";
1983   [(set_attr "type" "multi")])
1985 (define_insn "abssf2"
1986   [(set (match_operand:SF 0 "register_operand" "=d*f")
1987         (abs:SF (match_operand:SF 1 "register_operand" "df")))]
1988   ""
1989   "*
1991   int dstreg = REGNO (operands[0]);
1992   int srcreg = REGNO (operands[1]);
1994   if (dstreg < 32 && srcreg < 32)
1995     return \"clrbit     31,%1,%0\";
1997   if (dstreg >= 32 && srcreg >= 32)
1998     return \"cpysre     %1,0f0.0,%0\";
2000   if (dstreg < 32)
2001     return \"movr       %1,%0\;clrbit   31,%0,%0\";
2003   return \"movr %1,%0\;cpysre   %0,0f0.0,%0\";
2005   [(set_attr "type" "multi")])
2007 ;; Tetra (16 byte) float support.
2009 (define_expand "cmpxf"
2010   [(set (reg:CC 36)
2011         (compare:CC (match_operand:XF 0 "register_operand" "")
2012                     (match_operand:XF 1 "nonmemory_operand" "")))]
2013   "TARGET_NUMERICS"
2014   "
2016   i960_compare_op0 = operands[0];
2017   i960_compare_op1 = operands[1];
2018   DONE;
2021 (define_insn ""
2022   [(set (reg:CC 36)
2023         (compare:CC (match_operand:XF 0 "register_operand" "f")
2024                     (match_operand:XF 1 "nonmemory_operand" "fGH")))]
2025   "TARGET_NUMERICS"
2026   "cmpr %0,%1"
2027   [(set_attr "type" "fpcc")])
2029 (define_expand "movxf"
2030   [(set (match_operand:XF 0 "general_operand" "")
2031         (match_operand:XF 1 "fpmove_src_operand" ""))]
2032   ""
2033   "
2035   if (emit_move_sequence (operands, XFmode))
2036     DONE;
2039 (define_insn ""
2040   [(set (match_operand:XF 0 "general_operand" "=r,f,d,d,m")
2041         (match_operand:XF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
2042   "register_operand (operands[0], XFmode)
2043    || register_operand (operands[1], XFmode)"
2044   "*
2046   switch (which_alternative)
2047     {
2048     case 0:
2049       if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2050         return \"movre  %1,%0\";
2051       else
2052         return \"movq   %1,%0\";
2053     case 1:
2054       return \"movre    %1,%0\";
2055     case 2:
2056       return i960_output_ldconst (operands[0], operands[1]);
2057     case 3:
2058       return \"ldt      %1,%0\";
2059     case 4:
2060       return \"stt      %1,%0\";
2061     }
2063   [(set_attr "type" "move,move,load,fpload,fpstore")])
2065 (define_insn "extendsfxf2"
2066   [(set (match_operand:XF 0 "register_operand" "=f,d")
2067         (float_extend:XF
2068          (match_operand:SF 1 "register_operand" "d,f")))]
2069   "TARGET_NUMERICS"
2070   "@
2071   movr  %1,%0
2072   movre %1,%0"
2073   [(set_attr "type" "fpmove")])
2075 (define_insn "extenddfxf2"
2076   [(set (match_operand:XF 0 "register_operand" "=f,d")
2077         (float_extend:XF
2078          (match_operand:DF 1 "register_operand" "d,f")))]
2079   "TARGET_NUMERICS"
2080   "@
2081   movrl %1,%0
2082   movre %1,%0"
2083   [(set_attr "type" "fpmove")])
2085 (define_insn "truncxfdf2"
2086   [(set (match_operand:DF 0 "register_operand" "=d")
2087         (float_truncate:DF
2088          (match_operand:XF 1 "register_operand" "f")))]
2089   "TARGET_NUMERICS"
2090   "movrl        %1,%0"
2091   [(set_attr "type" "fpmove")])
2093 (define_insn "truncxfsf2"
2094   [(set (match_operand:SF 0 "register_operand" "=d")
2095         (float_truncate:SF
2096          (match_operand:XF 1 "register_operand" "f")))]
2097   "TARGET_NUMERICS"
2098   "movr %1,%0"
2099   [(set_attr "type" "fpmove")])
2101 (define_insn "floatsixf2"
2102   [(set (match_operand:XF 0 "register_operand" "=f")
2103         (float:XF (match_operand:SI 1 "register_operand" "d")))]
2104   "TARGET_NUMERICS"
2105   "cvtir        %1,%0"
2106   [(set_attr "type" "fpcvt")])
2108 (define_insn "fix_truncxfsi2"
2109   [(set (match_operand:SI 0 "register_operand" "=d")
2110         (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))]
2111   "TARGET_NUMERICS"
2112   "cvtzri       %1,%0"
2113   [(set_attr "type" "fpcvt")])
2115 (define_insn "fixuns_truncxfsi2"
2116   [(set (match_operand:SI 0 "register_operand" "=d")
2117         (unsigned_fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))]
2118   "TARGET_NUMERICS"
2119   "cvtzri       %1,%0"
2120   [(set_attr "type" "fpcvt")])
2122 (define_insn "addxf3"
2123   [(set (match_operand:XF 0 "register_operand" "=f")
2124         (plus:XF (match_operand:XF 1 "nonmemory_operand" "%fGH")
2125                  (match_operand:XF 2 "nonmemory_operand" "fGH")))]
2126   "TARGET_NUMERICS"
2127   "addr %1,%2,%0"
2128   [(set_attr "type" "fpadd")])
2130 (define_insn "subxf3"
2131   [(set (match_operand:XF 0 "register_operand" "=f")
2132         (minus:XF (match_operand:XF 1 "nonmemory_operand" "fGH")
2133                   (match_operand:XF 2 "nonmemory_operand" "fGH")))]
2134   "TARGET_NUMERICS"
2135   "subr %2,%1,%0"
2136   [(set_attr "type" "fpadd")])
2138 (define_insn "mulxf3"
2139   [(set (match_operand:XF 0 "register_operand" "=f")
2140         (mult:XF (match_operand:XF 1 "nonmemory_operand" "%fGH")
2141                  (match_operand:XF 2 "nonmemory_operand" "fGH")))]
2142   "TARGET_NUMERICS"
2143   "mulr %1,%2,%0"
2144   [(set_attr "type" "fpmul")])
2146 (define_insn "divxf3"
2147   [(set (match_operand:XF 0 "register_operand" "=f")
2148         (div:XF (match_operand:XF 1 "nonmemory_operand" "fGH")
2149                 (match_operand:XF 2 "nonmemory_operand" "fGH")))]
2150   "TARGET_NUMERICS"
2151   "divr %2,%1,%0"
2152   [(set_attr "type" "fpdiv")])
2154 (define_insn "negxf2"
2155   [(set (match_operand:XF 0 "register_operand" "=f")
2156         (neg:XF (match_operand:XF 1 "register_operand" "f")))]
2157   "TARGET_NUMERICS"
2158   "subr %1,0f0.0,%0"
2159   [(set_attr "type" "fpadd")])
2161 (define_insn "absxf2"
2162   [(set (match_operand:XF 0 "register_operand" "=f")
2163         (abs:XF (match_operand:XF 1 "register_operand" "f")))]
2164   "(TARGET_NUMERICS)"
2165   "cpysre       %1,0f0.0,%0"
2166   [(set_attr "type" "fpmove")])
2168 ;; Arithmetic shift instructions.
2170 ;; The shli instruction generates an overflow fault if the sign changes.
2171 ;; In the case of overflow, it does not give the natural result, it instead
2172 ;; gives the last shift value before the overflow.  We can not use this
2173 ;; instruction because gcc thinks that arithmetic left shift and logical
2174 ;; left shift are identical, and sometimes canonicalizes the logical left
2175 ;; shift to an arithmetic left shift.  Therefore we must always use the
2176 ;; logical left shift instruction.
2178 (define_insn "ashlsi3"
2179   [(set (match_operand:SI 0 "register_operand" "=d")
2180         (ashift:SI (match_operand:SI 1 "arith_operand" "dI")
2181                    (match_operand:SI 2 "arith_operand" "dI")))]
2182   ""
2183   "shlo %2,%1,%0"
2184   [(set_attr "type" "alu2")])
2186 (define_insn "ashrsi3"
2187   [(set (match_operand:SI 0 "register_operand" "=d")
2188         (ashiftrt:SI (match_operand:SI 1 "arith_operand" "dI")
2189                      (match_operand:SI 2 "arith_operand" "dI")))]
2190   ""
2191   "shri %2,%1,%0"
2192   [(set_attr "type" "alu2")])
2194 (define_insn "lshrsi3"
2195   [(set (match_operand:SI 0 "register_operand" "=d")
2196         (lshiftrt:SI (match_operand:SI 1 "arith_operand" "dI")
2197                    (match_operand:SI 2 "arith_operand" "dI")))]
2198   ""
2199   "shro %2,%1,%0"
2200   [(set_attr "type" "alu2")])
2202 ;; Unconditional and other jump instructions.
2204 (define_insn "jump"
2205   [(set (pc)
2206         (label_ref (match_operand 0 "" "")))]
2207   ""
2208   "b    %l0"
2209   [(set_attr "type" "branch")])
2211 (define_insn "indirect_jump"
2212   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2213   ""
2214   "bx   %a0"
2215   [(set_attr "type" "branch")])
2217 (define_insn "tablejump"
2218   [(set (pc) (match_operand:SI 0 "register_operand" "d"))
2219    (use (label_ref (match_operand 1 "" "")))]
2220   ""
2221   "*
2223   if (flag_pic)
2224     return \"bx %l1(%0)\";
2225   else
2226     return \"bx (%0)\";
2228   [(set_attr "type" "branch")])
2230 ;;- jump to subroutine
2232 (define_expand "call"
2233   [(call (match_operand:SI 0 "memory_operand" "m")
2234          (match_operand:SI 1 "immediate_operand" "i"))]
2235   ""
2236   "
2238   emit_insn (gen_call_internal (operands[0], operands[1],
2239                                 virtual_outgoing_args_rtx));
2240   DONE;
2243 ;; We need a call saved register allocated for the match_scratch, so we use
2244 ;; 'l' because all local registers are call saved.
2246 ;; ??? I would prefer to use a match_scratch here, but match_scratch allocated
2247 ;; registers can't be used for spills.  In a function with lots of calls,
2248 ;; local-alloc may allocate all local registers to a match_scratch, leaving
2249 ;; no local registers available for spills.
2251 (define_insn "call_internal"
2252   [(call (match_operand:SI 0 "memory_operand" "m")
2253          (match_operand:SI 1 "immediate_operand" "i"))
2254    (use (match_operand:SI 2 "address_operand" "p"))
2255    (clobber (reg:SI 19))]
2256   ""
2257   "* return i960_output_call_insn (operands[0], operands[1], operands[2],
2258                                    insn);"
2259   [(set_attr "type" "call")])
2261 (define_expand "call_value"
2262   [(set (match_operand 0 "register_operand" "=d")
2263         (call (match_operand:SI 1 "memory_operand" "m")
2264               (match_operand:SI 2 "immediate_operand" "i")))]
2265   ""
2266   "
2268   emit_insn (gen_call_value_internal (operands[0], operands[1], operands[2],
2269                                       virtual_outgoing_args_rtx));
2270   DONE;
2273 ;; We need a call saved register allocated for the match_scratch, so we use
2274 ;; 'l' because all local registers are call saved.
2276 (define_insn "call_value_internal"
2277   [(set (match_operand 0 "register_operand" "=d")
2278         (call (match_operand:SI 1 "memory_operand" "m")
2279               (match_operand:SI 2 "immediate_operand" "i")))
2280    (use (match_operand:SI 3 "address_operand" "p"))
2281    (clobber (reg:SI 19))]
2282   ""
2283   "* return i960_output_call_insn (operands[1], operands[2], operands[3],
2284                                    insn);"
2285   [(set_attr "type" "call")])
2287 (define_insn "return"
2288   [(return)]
2289   ""
2290   "* return i960_output_ret_insn (insn);"
2291   [(set_attr "type" "branch")])
2293 (define_insn "nop"
2294   [(const_int 0)]
2295   ""
2296   "")
2298 ;; Various peephole optimizations for multiple-word moves, loads, and stores.
2299 ;; Multiple register moves.
2301 ;; Matched 5/28/91
2302 (define_peephole
2303   [(set (match_operand:SI 0 "register_operand" "=r")
2304         (match_operand:SI 1 "register_operand" "r"))
2305    (set (match_operand:SI 2 "register_operand" "=r")
2306         (match_operand:SI 3 "register_operand" "r"))
2307    (set (match_operand:SI 4 "register_operand" "=r")
2308         (match_operand:SI 5 "register_operand" "r"))
2309    (set (match_operand:SI 6 "register_operand" "=r")
2310         (match_operand:SI 7 "register_operand" "r"))]
2311   "((REGNO (operands[0]) & 3) == 0)
2312    && ((REGNO (operands[1]) & 3) == 0)
2313    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2314    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2315    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2316    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))
2317    && (REGNO (operands[0]) + 3 == REGNO (operands[6]))
2318    && (REGNO (operands[1]) + 3 == REGNO (operands[7]))"
2319   "movq %1,%0")
2321 ;; Matched 4/17/92
2322 (define_peephole
2323   [(set (match_operand:DI 0 "register_operand" "=r")
2324         (match_operand:DI 1 "register_operand" "r"))
2325    (set (match_operand:DI 2 "register_operand" "=r")
2326         (match_operand:DI 3 "register_operand" "r"))]
2327   "((REGNO (operands[0]) & 3) == 0)
2328    && ((REGNO (operands[1]) & 3) == 0)
2329    && (REGNO (operands[0]) + 2 == REGNO (operands[2]))
2330    && (REGNO (operands[1]) + 2 == REGNO (operands[3]))"
2331   "movq %1,%0")
2333 ;; Matched 4/17/92
2334 (define_peephole
2335   [(set (match_operand:DI 0 "register_operand" "=r")
2336         (match_operand:DI 1 "register_operand" "r"))
2337    (set (match_operand:SI 2 "register_operand" "=r")
2338         (match_operand:SI 3 "register_operand" "r"))
2339    (set (match_operand:SI 4 "register_operand" "=r")
2340         (match_operand:SI 5 "register_operand" "r"))]
2341   "((REGNO (operands[0]) & 3) == 0)
2342    && ((REGNO (operands[1]) & 3) == 0)
2343    && (REGNO (operands[0]) + 2 == REGNO (operands[2]))
2344    && (REGNO (operands[1]) + 2 == REGNO (operands[3]))
2345    && (REGNO (operands[0]) + 3 == REGNO (operands[4]))
2346    && (REGNO (operands[1]) + 3 == REGNO (operands[5]))"
2347   "movq %1,%0")
2349 ;; Matched 4/17/92
2350 (define_peephole
2351   [(set (match_operand:SI 0 "register_operand" "=r")
2352         (match_operand:SI 1 "register_operand" "r"))
2353    (set (match_operand:SI 2 "register_operand" "=r")
2354         (match_operand:SI 3 "register_operand" "r"))
2355    (set (match_operand:DI 4 "register_operand" "=r")
2356         (match_operand:DI 5 "register_operand" "r"))]
2357   "((REGNO (operands[0]) & 3) == 0)
2358    && ((REGNO (operands[1]) & 3) == 0)
2359    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2360    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2361    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2362    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))"
2363   "movq %1,%0")
2365 ;; Matched 4/17/92
2366 (define_peephole
2367   [(set (match_operand:DI 0 "register_operand" "=r")
2368         (match_operand:DI 1 "register_operand" "r"))
2369    (set (match_operand:SI 2 "register_operand" "=r")
2370         (match_operand:SI 3 "register_operand" "r"))]
2371   "((REGNO (operands[0]) & 3) == 0)
2372    && ((REGNO (operands[1]) & 3) == 0)
2373    && (REGNO (operands[0]) + 2 == REGNO (operands[2]))
2374    && (REGNO (operands[1]) + 2 == REGNO (operands[3]))"
2375   "movt %1,%0")
2377 ;; Matched 5/28/91
2378 (define_peephole
2379   [(set (match_operand:SI 0 "register_operand" "=r")
2380         (match_operand:SI 1 "register_operand" "r"))
2381    (set (match_operand:SI 2 "register_operand" "=r")
2382         (match_operand:SI 3 "register_operand" "r"))
2383    (set (match_operand:SI 4 "register_operand" "=r")
2384         (match_operand:SI 5 "register_operand" "r"))]
2385   "((REGNO (operands[0]) & 3) == 0)
2386    && ((REGNO (operands[1]) & 3) == 0)
2387    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2388    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2389    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2390    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))"
2391   "movt %1,%0")
2393 ;; Matched 5/28/91
2394 (define_peephole
2395   [(set (match_operand:SI 0 "register_operand" "=r")
2396         (match_operand:SI 1 "register_operand" "r"))
2397    (set (match_operand:SI 2 "register_operand" "=r")
2398         (match_operand:SI 3 "register_operand" "r"))]
2399   "((REGNO (operands[0]) & 1) == 0)
2400    && ((REGNO (operands[1]) & 1) == 0)
2401    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2402    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))"
2403   "movl %1,%0")
2405 ; Multiple register loads.
2407 ;; Matched 6/15/91
2408 (define_peephole
2409   [(set (match_operand:SI 0 "register_operand" "=r")
2410         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2411                          (match_operand:SI 2 "immediate_operand" "n"))))
2412    (set (match_operand:SI 3 "register_operand" "=r")
2413         (mem:SI (plus:SI (match_dup 1)
2414                          (match_operand:SI 4 "immediate_operand" "n"))))
2415    (set (match_operand:SI 5 "register_operand" "=r")
2416         (mem:SI (plus:SI (match_dup 1)
2417                          (match_operand:SI 6 "immediate_operand" "n"))))
2418    (set (match_operand:SI 7 "register_operand" "=r")
2419         (mem:SI (plus:SI (match_dup 1)
2420                          (match_operand:SI 8 "immediate_operand" "n"))))]
2421   "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2422    && (REGNO (operands[1]) != REGNO (operands[0]))
2423    && (REGNO (operands[0]) + 1 == REGNO (operands[3]))
2424    && (REGNO (operands[1]) != REGNO (operands[3]))
2425    && (REGNO (operands[0]) + 2 == REGNO (operands[5]))
2426    && (REGNO (operands[1]) != REGNO (operands[5]))
2427    && (REGNO (operands[0]) + 3 == REGNO (operands[7]))
2428    && (INTVAL (operands[2]) + 4 == INTVAL (operands[4]))
2429    && (INTVAL (operands[2]) + 8 == INTVAL (operands[6]))
2430    && (INTVAL (operands[2]) + 12 == INTVAL (operands[8])))"
2431   "ldq  %2(%1),%0")
2433 ;; Matched 5/28/91
2434 (define_peephole
2435   [(set (match_operand:DF 0 "register_operand" "=d")
2436         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
2437                          (match_operand:SI 2 "immediate_operand" "n"))))
2438    (set (match_operand:DF 3 "register_operand" "=d")
2439         (mem:DF (plus:SI (match_dup 1)
2440                          (match_operand:SI 4 "immediate_operand" "n"))))]
2441   "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2442    && (REGNO (operands[1]) != REGNO (operands[0]))
2443    && (REGNO (operands[0]) + 2 == REGNO (operands[3]))
2444    && (REGNO (operands[1]) != REGNO (operands[3]))
2445    && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))"
2446   "ldq  %2(%1),%0")
2448 ;; Matched 1/24/92
2449 (define_peephole
2450   [(set (match_operand:DI 0 "register_operand" "=d")
2451         (mem:DI (plus:SI (match_operand:SI 1 "register_operand" "d")
2452                          (match_operand:SI 2 "immediate_operand" "n"))))
2453    (set (match_operand:DI 3 "register_operand" "=d")
2454         (mem:DI (plus:SI (match_dup 1)
2455                          (match_operand:SI 4 "immediate_operand" "n"))))]
2456   "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2457    && (REGNO (operands[1]) != REGNO (operands[0]))
2458    && (REGNO (operands[0]) + 2 == REGNO (operands[3]))
2459    && (REGNO (operands[1]) != REGNO (operands[3]))
2460    && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))"
2461   "ldq  %2(%1),%0")
2463 ;; Matched 4/17/92
2464 (define_peephole
2465   [(set (match_operand:SI 0 "register_operand" "=d")
2466         (mem:SI (match_operand:SI 1 "register_operand" "d")))
2467    (set (match_operand:SI 2 "register_operand" "=d")
2468         (mem:SI (plus:SI (match_dup 1)
2469                          (match_operand:SI 3 "immediate_operand" "n"))))
2470    (set (match_operand:SI 4 "register_operand" "=d")
2471         (mem:SI (plus:SI (match_dup 1)
2472                          (match_operand:SI 5 "immediate_operand" "n"))))
2473    (set (match_operand:SI 6 "register_operand" "=d")
2474         (mem:SI (plus:SI (match_dup 1)
2475                          (match_operand:SI 7 "immediate_operand" "n"))))]
2476   "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0)
2477    && (REGNO (operands[1]) != REGNO (operands[0]))
2478    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2479    && (REGNO (operands[1]) != REGNO (operands[2]))
2480    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2481    && (REGNO (operands[1]) != REGNO (operands[4]))
2482    && (REGNO (operands[0]) + 3 == REGNO (operands[6]))
2483    && (INTVAL (operands[3]) == 4)
2484    && (INTVAL (operands[5]) == 8)
2485    && (INTVAL (operands[7]) == 12))"
2486   "ldq  (%1),%0")
2488 ;; Matched 5/28/91
2489 (define_peephole
2490   [(set (match_operand:SI 0 "register_operand" "=d")
2491         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d")
2492                          (match_operand:SI 2 "immediate_operand" "n"))))
2493    (set (match_operand:SI 3 "register_operand" "=d")
2494         (mem:SI (plus:SI (match_dup 1)
2495                          (match_operand:SI 4 "immediate_operand" "n"))))
2496    (set (match_operand:SI 5 "register_operand" "=d")
2497         (mem:SI (plus:SI (match_dup 1)
2498                          (match_operand:SI 6 "immediate_operand" "n"))))]
2499   "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2500    && (REGNO (operands[1]) != REGNO (operands[0]))
2501    && (REGNO (operands[0]) + 1 == REGNO (operands[3]))
2502    && (REGNO (operands[1]) != REGNO (operands[3]))
2503    && (REGNO (operands[0]) + 2 == REGNO (operands[5]))
2504    && (INTVAL (operands[2]) + 4 == INTVAL (operands[4]))
2505    && (INTVAL (operands[2]) + 8 == INTVAL (operands[6])))"
2506   "ldt  %2(%1),%0")
2508 ;; Matched 6/15/91
2509 (define_peephole
2510   [(set (match_operand:SI 0 "register_operand" "=d")
2511         (mem:SI (match_operand:SI 1 "register_operand" "d")))
2512    (set (match_operand:SI 2 "register_operand" "=d")
2513         (mem:SI (plus:SI (match_dup 1)
2514                          (match_operand:SI 3 "immediate_operand" "n"))))
2515    (set (match_operand:SI 4 "register_operand" "=d")
2516         (mem:SI (plus:SI (match_dup 1)
2517                          (match_operand:SI 5 "immediate_operand" "n"))))]
2518   "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0)
2519    && (REGNO (operands[1]) != REGNO (operands[0]))
2520    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2521    && (REGNO (operands[1]) != REGNO (operands[2]))
2522    && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2523    && (INTVAL (operands[3]) == 4)
2524    && (INTVAL (operands[5]) == 8))"
2525   "ldt  (%1),%0")
2527 ;; Matched 5/28/91
2528 (define_peephole
2529   [(set (match_operand:SI 0 "register_operand" "=d")
2530         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d")
2531                          (match_operand:SI 2 "immediate_operand" "n"))))
2532    (set (match_operand:SI 3 "register_operand" "=d")
2533         (mem:SI (plus:SI (match_dup 1)
2534                          (match_operand:SI 4 "immediate_operand" "n"))))]
2535   "(i960_si_di (operands[1], operands[2]) && ((REGNO (operands[0]) & 1) == 0)
2536    && (REGNO (operands[1]) != REGNO (operands[0]))
2537    && (REGNO (operands[0]) + 1 == REGNO (operands[3]))
2538    && (INTVAL (operands[2]) + 4 == INTVAL (operands[4])))"
2539   "ldl  %2(%1),%0")
2541 ;; Matched 5/28/91
2542 (define_peephole
2543   [(set (match_operand:SI 0 "register_operand" "=d")
2544         (mem:SI (match_operand:SI 1 "register_operand" "d")))
2545    (set (match_operand:SI 2 "register_operand" "=d")
2546         (mem:SI (plus:SI (match_dup 1)
2547                          (match_operand:SI 3 "immediate_operand" "n"))))]
2548   "(i960_si_di (operands[1], 0) && ((REGNO (operands[0]) & 1) == 0)
2549    && (REGNO (operands[1]) != REGNO (operands[0]))
2550    && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2551    && (INTVAL (operands[3]) == 4))"
2552   "ldl  (%1),%0")
2554 ; Multiple register stores.
2556 ;; Matched 5/28/91
2557 (define_peephole
2558   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d")
2559                          (match_operand:SI 1 "immediate_operand" "n")))
2560         (match_operand:SI 2 "register_operand" "d"))
2561    (set (mem:SI (plus:SI (match_dup 0)
2562                          (match_operand:SI 3 "immediate_operand" "n")))
2563         (match_operand:SI 4 "register_operand" "d"))
2564    (set (mem:SI (plus:SI (match_dup 0)
2565                          (match_operand:SI 5 "immediate_operand" "n")))
2566         (match_operand:SI 6 "register_operand" "d"))
2567    (set (mem:SI (plus:SI (match_dup 0)
2568                          (match_operand:SI 7 "immediate_operand" "n")))
2569         (match_operand:SI 8 "register_operand" "d"))]
2570   "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2571    && (REGNO (operands[2]) + 1 == REGNO (operands[4]))
2572    && (REGNO (operands[2]) + 2 == REGNO (operands[6]))
2573    && (REGNO (operands[2]) + 3 == REGNO (operands[8]))
2574    && (INTVAL (operands[1]) + 4 == INTVAL (operands[3]))
2575    && (INTVAL (operands[1]) + 8 == INTVAL (operands[5]))
2576    && (INTVAL (operands[1]) + 12 == INTVAL (operands[7])))"
2577   "stq  %2,%1(%0)")
2579 ;; Matched 6/16/91
2580 (define_peephole
2581   [(set (mem:DF (plus:SI (match_operand:SI 0 "register_operand" "d")
2582                          (match_operand:SI 1 "immediate_operand" "n")))
2583         (match_operand:DF 2 "register_operand" "d"))
2584    (set (mem:DF (plus:SI (match_dup 0)
2585                          (match_operand:SI 3 "immediate_operand" "n")))
2586         (match_operand:DF 4 "register_operand" "d"))]
2587   "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2588    && (REGNO (operands[2]) + 2 == REGNO (operands[4]))
2589    && (INTVAL (operands[1]) + 8 == INTVAL (operands[3])))"
2590   "stq  %2,%1(%0)")
2592 ;; Matched 4/17/92
2593 (define_peephole
2594   [(set (mem:DI (plus:SI (match_operand:SI 0 "register_operand" "d")
2595                          (match_operand:SI 1 "immediate_operand" "n")))
2596         (match_operand:DI 2 "register_operand" "d"))
2597    (set (mem:DI (plus:SI (match_dup 0)
2598                          (match_operand:SI 3 "immediate_operand" "n")))
2599         (match_operand:DI 4 "register_operand" "d"))]
2600   "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2601    && (REGNO (operands[2]) + 2 == REGNO (operands[4]))
2602    && (INTVAL (operands[1]) + 8 == INTVAL (operands[3])))"
2603   "stq  %2,%1(%0)")
2605 ;; Matched 1/23/92
2606 (define_peephole
2607   [(set (mem:SI (match_operand:SI 0 "register_operand" "d"))
2608         (match_operand:SI 1 "register_operand" "d"))
2609    (set (mem:SI (plus:SI (match_dup 0)
2610                          (match_operand:SI 2 "immediate_operand" "n")))
2611         (match_operand:SI 3 "register_operand" "d"))
2612    (set (mem:SI (plus:SI (match_dup 0)
2613                          (match_operand:SI 4 "immediate_operand" "n")))
2614         (match_operand:SI 5 "register_operand" "d"))
2615    (set (mem:SI (plus:SI (match_dup 0)
2616                          (match_operand:SI 6 "immediate_operand" "n")))
2617         (match_operand:SI 7 "register_operand" "d"))]
2618   "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0)
2619    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2620    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))
2621    && (REGNO (operands[1]) + 3 == REGNO (operands[7]))
2622    && (INTVAL (operands[2]) == 4)
2623    && (INTVAL (operands[4]) == 8)
2624    && (INTVAL (operands[6]) == 12))"
2625   "stq  %1,(%0)")
2627 ;; Matched 5/29/91
2628 (define_peephole
2629   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d")
2630                          (match_operand:SI 1 "immediate_operand" "n")))
2631         (match_operand:SI 2 "register_operand" "d"))
2632    (set (mem:SI (plus:SI (match_dup 0)
2633                          (match_operand:SI 3 "immediate_operand" "n")))
2634         (match_operand:SI 4 "register_operand" "d"))
2635    (set (mem:SI (plus:SI (match_dup 0)
2636                          (match_operand:SI 5 "immediate_operand" "n")))
2637         (match_operand:SI 6 "register_operand" "d"))]
2638   "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2639    && (REGNO (operands[2]) + 1 == REGNO (operands[4]))
2640    && (REGNO (operands[2]) + 2 == REGNO (operands[6]))
2641    && (INTVAL (operands[1]) + 4 == INTVAL (operands[3]))
2642    && (INTVAL (operands[1]) + 8 == INTVAL (operands[5])))"
2643   "stt  %2,%1(%0)")
2645 ;; Matched 5/29/91
2646 (define_peephole
2647   [(set (mem:SI (match_operand:SI 0 "register_operand" "d"))
2648         (match_operand:SI 1 "register_operand" "d"))
2649    (set (mem:SI (plus:SI (match_dup 0)
2650                          (match_operand:SI 2 "immediate_operand" "n")))
2651         (match_operand:SI 3 "register_operand" "d"))
2652    (set (mem:SI (plus:SI (match_dup 0)
2653                          (match_operand:SI 4 "immediate_operand" "n")))
2654         (match_operand:SI 5 "register_operand" "d"))]
2655   "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0)
2656    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2657    && (REGNO (operands[1]) + 2 == REGNO (operands[5]))
2658    && (INTVAL (operands[2]) == 4)
2659    && (INTVAL (operands[4]) == 8))"
2660   "stt  %1,(%0)")
2662 ;; Matched 5/28/91
2663 (define_peephole
2664   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d")
2665                          (match_operand:SI 1 "immediate_operand" "n")))
2666         (match_operand:SI 2 "register_operand" "d"))
2667    (set (mem:SI (plus:SI (match_dup 0)
2668                          (match_operand:SI 3 "immediate_operand" "n")))
2669         (match_operand:SI 4 "register_operand" "d"))]
2670   "(i960_si_di (operands[0], operands[1]) && ((REGNO (operands[2]) & 1) == 0)
2671    && (REGNO (operands[2]) + 1 == REGNO (operands[4]))
2672    && (INTVAL (operands[1]) + 4 == INTVAL (operands[3])))"
2673   "stl  %2,%1(%0)")
2675 ;; Matched 5/28/91
2676 (define_peephole
2677   [(set (mem:SI (match_operand:SI 0 "register_operand" "d"))
2678         (match_operand:SI 1 "register_operand" "d"))
2679    (set (mem:SI (plus:SI (match_dup 0)
2680                          (match_operand:SI 2 "immediate_operand" "n")))
2681         (match_operand:SI 3 "register_operand" "d"))]
2682   "(i960_si_di (operands[0], 0) && ((REGNO (operands[1]) & 1) == 0)
2683    && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2684    && (INTVAL (operands[2]) == 4))"
2685   "stl  %1,(%0)")