OSDN Git Service

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