OSDN Git Service

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