xref: /openbsd/gnu/usr.bin/gcc/gcc/config/i960/i960.md (revision c87b03e5)
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
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
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
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
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
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
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
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
576;; Normal move instructions.
577;; This code is based on the sparc machine description.
578
579(define_expand "movsi"
580  [(set (match_operand:SI 0 "general_operand" "")
581	(match_operand:SI 1 "general_operand" ""))]
582  ""
583  "
584{
585  if (emit_move_sequence (operands, SImode))
586    DONE;
587}")
588
589;; The store case can not be separate, because reload may convert a register
590;; to register move insn to a store (or load) insn without rerecognizing
591;; the insn.
592
593;; The i960 does not have any store constant to memory instruction.  However,
594;; the calling convention is defined so that the arg pointer when it is not
595;; overwise being used is zero.  Thus, we can handle store zero to memory
596;; by storing an unused arg pointer.  The arg pointer will be unused if
597;; current_function_args_size is zero and this is not a stdarg
598;; function.  This value of the former variable is not valid until after
599;; all rtl generation is complete, including function inlining (because a
600;; function that doesn't need an arg pointer may be inlined into a function
601;; that does need an arg pointer), so we must also check that
602;; rtx_equal_function_value_matters is zero.
603
604(define_insn ""
605  [(set (match_operand:SI 0 "general_operand" "=d,d,d,m")
606	(match_operand:SI 1 "general_operand" "dI,i,m,dJ"))]
607  "(current_function_args_size == 0
608    && current_function_stdarg == 0
609    && rtx_equal_function_value_matters == 0)
610   && (register_operand (operands[0], SImode)
611       || register_operand (operands[1], SImode)
612       || operands[1] == const0_rtx)"
613  "*
614{
615  switch (which_alternative)
616    {
617    case 0:
618      if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
619	{
620	  if (GET_CODE (operands[1]) == REG)
621	    return \"lda	(%1),%0\";
622	  else
623	    return \"lda	%1,%0\";
624	}
625      return \"mov	%1,%0\";
626    case 1:
627      return i960_output_ldconst (operands[0], operands[1]);
628    case 2:
629      return \"ld	%1,%0\";
630    case 3:
631      if (operands[1] == const0_rtx)
632	return \"st	g14,%0\";
633      return \"st	%1,%0\";
634    default:
635      abort();
636    }
637}"
638  [(set_attr "type" "move,address,load,store")
639   (set_attr "length" "*,3,*,*")])
640
641(define_insn ""
642  [(set (match_operand:SI 0 "general_operand" "=d,d,d,m")
643	(match_operand:SI 1 "general_operand" "dI,i,m,d"))]
644  "(current_function_args_size != 0
645    || current_function_stdarg != 0
646    || rtx_equal_function_value_matters != 0)
647   && (register_operand (operands[0], SImode)
648       || register_operand (operands[1], SImode))"
649  "*
650{
651  switch (which_alternative)
652    {
653    case 0:
654      if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
655	{
656	  if (GET_CODE (operands[1]) == REG)
657	    return \"lda	(%1),%0\";
658	  else
659	    return \"lda	%1,%0\";
660	}
661      return \"mov	%1,%0\";
662    case 1:
663      return i960_output_ldconst (operands[0], operands[1]);
664    case 2:
665      return \"ld	%1,%0\";
666    case 3:
667      return \"st	%1,%0\";
668    default:
669      abort();
670    }
671}"
672  [(set_attr "type" "move,address,load,store")
673   (set_attr "length" "*,3,*,*")])
674
675(define_expand "movhi"
676  [(set (match_operand:HI 0 "general_operand" "")
677	(match_operand:HI 1 "general_operand" ""))]
678  ""
679  "
680{
681  if (emit_move_sequence (operands, HImode))
682    DONE;
683}")
684
685;; Special pattern for zero stores to memory for functions which don't use
686;; the arg pointer.
687
688;; The store case can not be separate.  See above.
689(define_insn ""
690  [(set (match_operand:HI 0 "general_operand" "=d,d,d,m")
691	(match_operand:HI 1 "general_operand" "dI,i,m,dJ"))]
692  "(current_function_args_size == 0
693    && current_function_stdarg == 0
694    && rtx_equal_function_value_matters == 0)
695   && (register_operand (operands[0], HImode)
696       || register_operand (operands[1], HImode)
697       || operands[1] == const0_rtx)"
698  "*
699{
700  switch (which_alternative)
701    {
702    case 0:
703      if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
704	{
705	  if (GET_CODE (operands[1]) == REG)
706	    return \"lda	(%1),%0\";
707	  else
708	    return \"lda	%1,%0\";
709	}
710      return \"mov	%1,%0\";
711    case 1:
712      return i960_output_ldconst (operands[0], operands[1]);
713    case 2:
714      return \"ldos	%1,%0\";
715    case 3:
716      if (operands[1] == const0_rtx)
717	return \"stos	g14,%0\";
718      return \"stos	%1,%0\";
719    default:
720      abort();
721    }
722}"
723  [(set_attr "type" "move,misc,load,store")
724   (set_attr "length" "*,3,*,*")])
725
726;; The store case can not be separate.  See above.
727(define_insn ""
728  [(set (match_operand:HI 0 "general_operand" "=d,d,d,m")
729	(match_operand:HI 1 "general_operand" "dI,i,m,d"))]
730  "(current_function_args_size != 0
731    || current_function_stdarg != 0
732    || rtx_equal_function_value_matters != 0)
733   && (register_operand (operands[0], HImode)
734       || register_operand (operands[1], HImode))"
735  "*
736{
737  switch (which_alternative)
738    {
739    case 0:
740      if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
741	{
742	  if (GET_CODE (operands[1]) == REG)
743	    return \"lda	(%1),%0\";
744	  else
745	    return \"lda	%1,%0\";
746	}
747      return \"mov	%1,%0\";
748    case 1:
749      return i960_output_ldconst (operands[0], operands[1]);
750    case 2:
751      return \"ldos	%1,%0\";
752    case 3:
753      return \"stos	%1,%0\";
754    default:
755      abort();
756    }
757}"
758  [(set_attr "type" "move,misc,load,store")
759   (set_attr "length" "*,3,*,*")])
760
761(define_expand "movqi"
762  [(set (match_operand:QI 0 "general_operand" "")
763	(match_operand:QI 1 "general_operand" ""))]
764  ""
765  "
766{
767  if (emit_move_sequence (operands, QImode))
768    DONE;
769}")
770
771;; The store case can not be separate.  See comment above.
772(define_insn ""
773  [(set (match_operand:QI 0 "general_operand" "=d,d,d,m")
774	(match_operand:QI 1 "general_operand" "dI,i,m,dJ"))]
775  "(current_function_args_size == 0
776    && current_function_stdarg == 0
777    && rtx_equal_function_value_matters == 0)
778   && (register_operand (operands[0], QImode)
779       || register_operand (operands[1], QImode)
780       || operands[1] == const0_rtx)"
781  "*
782{
783  switch (which_alternative)
784    {
785    case 0:
786      if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
787	{
788	  if (GET_CODE (operands[1]) == REG)
789	    return \"lda	(%1),%0\";
790	  else
791	    return \"lda	%1,%0\";
792	}
793      return \"mov	%1,%0\";
794    case 1:
795      return i960_output_ldconst (operands[0], operands[1]);
796    case 2:
797      return \"ldob	%1,%0\";
798    case 3:
799      if (operands[1] == const0_rtx)
800	return \"stob	g14,%0\";
801      return \"stob	%1,%0\";
802    default:
803      abort();
804    }
805}"
806  [(set_attr "type" "move,misc,load,store")
807   (set_attr "length" "*,3,*,*")])
808
809;; The store case can not be separate.  See comment above.
810(define_insn ""
811  [(set (match_operand:QI 0 "general_operand" "=d,d,d,m")
812	(match_operand:QI 1 "general_operand" "dI,i,m,d"))]
813  "(current_function_args_size != 0
814    || current_function_stdarg != 0
815    || rtx_equal_function_value_matters != 0)
816   && (register_operand (operands[0], QImode)
817       || register_operand (operands[1], QImode))"
818  "*
819{
820  switch (which_alternative)
821    {
822    case 0:
823      if (i960_last_insn_type == I_TYPE_REG && TARGET_C_SERIES)
824	{
825	  if (GET_CODE (operands[1]) == REG)
826	    return \"lda	(%1),%0\";
827	  else
828	    return \"lda	%1,%0\";
829	}
830      return \"mov	%1,%0\";
831    case 1:
832      return i960_output_ldconst (operands[0], operands[1]);
833    case 2:
834      return \"ldob	%1,%0\";
835    case 3:
836      return \"stob	%1,%0\";
837    default:
838      abort();
839    }
840}"
841  [(set_attr "type" "move,misc,load,store")
842   (set_attr "length" "*,3,*,*")])
843
844(define_expand "movdi"
845  [(set (match_operand:DI 0 "general_operand" "")
846	(match_operand:DI 1 "general_operand" ""))]
847  ""
848  "
849{
850  if (emit_move_sequence (operands, DImode))
851    DONE;
852}")
853
854;; The store case can not be separate.  See comment above.
855(define_insn ""
856  [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m,o")
857	(match_operand:DI 1 "general_operand" "d,I,i,m,d,J"))]
858  "(current_function_args_size == 0
859    && current_function_stdarg == 0
860    && rtx_equal_function_value_matters == 0)
861   && (register_operand (operands[0], DImode)
862       || register_operand (operands[1], DImode)
863       || operands[1] == const0_rtx)"
864  "*
865{
866  switch (which_alternative)
867    {
868    case 0:
869    case 1:
870    case 3:
871    case 4:
872      return i960_output_move_double (operands[0], operands[1]);
873    case 2:
874      return i960_output_ldconst (operands[0], operands[1]);
875    case 5:
876       return i960_output_move_double_zero (operands[0]);
877    default:
878      abort();
879    }
880}"
881  [(set_attr "type" "move,move,load,load,store,store")])
882
883;; The store case can not be separate.  See comment above.
884(define_insn ""
885  [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m")
886	(match_operand:DI 1 "general_operand" "d,I,i,m,d"))]
887  "(current_function_args_size != 0
888    || current_function_stdarg != 0
889    || rtx_equal_function_value_matters != 0)
890   && (register_operand (operands[0], DImode)
891       || register_operand (operands[1], DImode))"
892  "*
893{
894  switch (which_alternative)
895    {
896    case 0:
897    case 1:
898    case 3:
899    case 4:
900      return i960_output_move_double (operands[0], operands[1]);
901    case 2:
902      return i960_output_ldconst (operands[0], operands[1]);
903    default:
904      abort();
905    }
906}"
907  [(set_attr "type" "move,move,load,load,store")])
908
909(define_insn "*store_unaligned_di_reg"
910  [(set (match_operand:DI 0 "general_operand" "=d,m")
911	(match_operand:DI 1 "register_operand" "d,d"))
912   (clobber (match_scratch:SI 2 "=X,&d"))]
913  ""
914  "*
915{
916  if (which_alternative == 0)
917    return i960_output_move_double (operands[0], operands[1]);
918
919  operands[3] = gen_rtx_MEM (word_mode, operands[2]);
920  operands[4] = adjust_address (operands[3], word_mode, UNITS_PER_WORD);
921  return \"lda	%0,%2\;st	%1,%3\;st	%D1,%4\";
922}"
923  [(set_attr "type" "move,store")])
924
925(define_expand "movti"
926  [(set (match_operand:TI 0 "general_operand" "")
927	(match_operand:TI 1 "general_operand" ""))]
928  ""
929  "
930{
931  if (emit_move_sequence (operands, TImode))
932    DONE;
933}")
934
935;; The store case can not be separate.  See comment above.
936(define_insn ""
937  [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m,o")
938	(match_operand:TI 1 "general_operand" "d,I,i,m,d,J"))]
939  "(current_function_args_size == 0
940    && current_function_stdarg == 0
941    && rtx_equal_function_value_matters == 0)
942   && (register_operand (operands[0], TImode)
943       || register_operand (operands[1], TImode)
944       || operands[1] == const0_rtx)"
945  "*
946{
947  switch (which_alternative)
948    {
949    case 0:
950    case 1:
951    case 3:
952    case 4:
953      return i960_output_move_quad (operands[0], operands[1]);
954    case 2:
955      return i960_output_ldconst (operands[0], operands[1]);
956    case 5:
957      return i960_output_move_quad_zero (operands[0]);
958    default:
959      abort();
960    }
961}"
962  [(set_attr "type" "move,move,load,load,store,store")])
963
964;; The store case can not be separate.  See comment above.
965(define_insn ""
966  [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m")
967	(match_operand:TI 1 "general_operand" "d,I,i,m,d"))]
968  "(current_function_args_size != 0
969    || current_function_stdarg != 0
970    || rtx_equal_function_value_matters != 0)
971   && (register_operand (operands[0], TImode)
972       || register_operand (operands[1], TImode))"
973  "*
974{
975  switch (which_alternative)
976    {
977    case 0:
978    case 1:
979    case 3:
980    case 4:
981      return i960_output_move_quad (operands[0], operands[1]);
982    case 2:
983      return i960_output_ldconst (operands[0], operands[1]);
984    default:
985      abort();
986    }
987}"
988  [(set_attr "type" "move,move,load,load,store")])
989
990(define_insn "*store_unaligned_ti_reg"
991  [(set (match_operand:TI 0 "general_operand" "=d,m")
992	(match_operand:TI 1 "register_operand" "d,d"))
993   (clobber (match_scratch:SI 2 "=X,&d"))]
994  ""
995  "*
996{
997  if (which_alternative == 0)
998    return i960_output_move_quad (operands[0], operands[1]);
999
1000  operands[3] = gen_rtx_MEM (word_mode, operands[2]);
1001  operands[4] = adjust_address (operands[3], word_mode, UNITS_PER_WORD);
1002  operands[5] = adjust_address (operands[4], word_mode, UNITS_PER_WORD);
1003  operands[6] = adjust_address (operands[5], word_mode, UNITS_PER_WORD);
1004  return \"lda	%0,%2\;st	%1,%3\;st	%D1,%4\;st	%E1,%5\;st	%F1,%6\";
1005}"
1006  [(set_attr "type" "move,store")])
1007
1008(define_expand "store_multiple"
1009  [(set (match_operand:SI 0 "" "")	;;- dest
1010	(match_operand:SI 1 "" ""))	;;- src
1011   (use (match_operand:SI 2 "" ""))]	;;- nregs
1012  ""
1013  "
1014{
1015  int regno;
1016  int count;
1017  int offset = 0;
1018
1019  if (GET_CODE (operands[0]) != MEM
1020      || GET_CODE (operands[1]) != REG
1021      || GET_CODE (operands[2]) != CONST_INT)
1022    FAIL;
1023
1024  count = INTVAL (operands[2]);
1025  if (count > 12)
1026    FAIL;
1027
1028  regno = REGNO (operands[1]);
1029  while (count >= 4 && ((regno & 3) == 0))
1030    {
1031      emit_move_insn (adjust_address (operands[0], TImode, offset),
1032		      gen_rtx_REG (TImode, regno));
1033      count -= 4;
1034      regno += 4;
1035      offset += 16;
1036    }
1037  while (count >= 2 && ((regno & 1) == 0))
1038    {
1039      emit_move_insn (adjust_address (operands[0], DImode, offset),
1040		      gen_rtx_REG (DImode, regno));
1041      count -= 2;
1042      regno += 2;
1043      offset += 8;
1044    }
1045  while (count > 0)
1046    {
1047      emit_move_insn (adjust_address (operands[0], SImode, offset),
1048		      gen_rtx_REG (SImode, regno));
1049      count -= 1;
1050      regno += 1;
1051      offset += 4;
1052    }
1053  DONE;
1054}")
1055
1056;; Floating point move insns
1057
1058(define_expand "movdf"
1059  [(set (match_operand:DF 0 "general_operand" "")
1060	(match_operand:DF 1 "fpmove_src_operand" ""))]
1061  ""
1062  "
1063{
1064  if (emit_move_sequence (operands, DFmode))
1065    DONE;
1066}")
1067
1068(define_insn ""
1069  [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m,o")
1070	(match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d,G"))]
1071  "(current_function_args_size == 0
1072    && current_function_stdarg == 0
1073    && rtx_equal_function_value_matters == 0)
1074   && (register_operand (operands[0], DFmode)
1075       || register_operand (operands[1], DFmode)
1076       || operands[1] == CONST0_RTX (DFmode))"
1077  "*
1078{
1079  switch (which_alternative)
1080    {
1081    case 0:
1082      if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1083	return \"movrl	%1,%0\";
1084      else
1085	return \"movl	%1,%0\";
1086    case 1:
1087      return \"movrl	%1,%0\";
1088    case 2:
1089      return i960_output_ldconst (operands[0], operands[1]);
1090    case 3:
1091      return \"ldl	%1,%0\";
1092    case 4:
1093      return \"stl	%1,%0\";
1094    case 5:
1095      operands[1] = adjust_address (operands[0], VOIDmode, 4);
1096      return \"st	g14,%0\;st	g14,%1\";
1097    default:
1098      abort();
1099    }
1100}"
1101  [(set_attr "type" "move,move,load,fpload,fpstore,fpstore")])
1102
1103(define_insn ""
1104  [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m")
1105	(match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
1106  "(current_function_args_size != 0
1107    || current_function_stdarg != 0
1108    || rtx_equal_function_value_matters != 0)
1109   && (register_operand (operands[0], DFmode)
1110       || register_operand (operands[1], DFmode))"
1111  "*
1112{
1113  switch (which_alternative)
1114    {
1115    case 0:
1116      if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1117	return \"movrl	%1,%0\";
1118      else
1119	return \"movl	%1,%0\";
1120    case 1:
1121      return \"movrl	%1,%0\";
1122    case 2:
1123      return i960_output_ldconst (operands[0], operands[1]);
1124    case 3:
1125      return \"ldl	%1,%0\";
1126    case 4:
1127      return \"stl	%1,%0\";
1128    default:
1129      abort();
1130    }
1131}"
1132  [(set_attr "type" "move,move,load,fpload,fpstore")])
1133
1134(define_expand "movsf"
1135  [(set (match_operand:SF 0 "general_operand" "")
1136	(match_operand:SF 1 "fpmove_src_operand" ""))]
1137  ""
1138  "
1139{
1140  if (emit_move_sequence (operands, SFmode))
1141    DONE;
1142}")
1143
1144(define_insn ""
1145  [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m")
1146	(match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,dG"))]
1147  "(current_function_args_size == 0
1148    && current_function_stdarg == 0
1149    && rtx_equal_function_value_matters == 0)
1150   && (register_operand (operands[0], SFmode)
1151       || register_operand (operands[1], SFmode)
1152       || operands[1] == CONST0_RTX (SFmode))"
1153  "*
1154{
1155  switch (which_alternative)
1156    {
1157    case 0:
1158      if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1159	return \"movr	%1,%0\";
1160      else
1161	return \"mov	%1,%0\";
1162    case 1:
1163      return \"movr	%1,%0\";
1164    case 2:
1165      return i960_output_ldconst (operands[0], operands[1]);
1166    case 3:
1167      return \"ld	%1,%0\";
1168    case 4:
1169      if (operands[1] == CONST0_RTX (SFmode))
1170	return \"st	g14,%0\";
1171      return \"st	%1,%0\";
1172    default:
1173      abort();
1174    }
1175}"
1176  [(set_attr "type" "move,move,load,fpload,fpstore")])
1177
1178(define_insn ""
1179  [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m")
1180	(match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
1181  "(current_function_args_size != 0
1182    || current_function_stdarg != 0
1183    || rtx_equal_function_value_matters != 0)
1184   && (register_operand (operands[0], SFmode)
1185       || register_operand (operands[1], SFmode))"
1186  "*
1187{
1188  switch (which_alternative)
1189    {
1190    case 0:
1191      if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1192	return \"movr	%1,%0\";
1193      else
1194	return \"mov	%1,%0\";
1195    case 1:
1196      return \"movr	%1,%0\";
1197    case 2:
1198      return i960_output_ldconst (operands[0], operands[1]);
1199    case 3:
1200      return \"ld	%1,%0\";
1201    case 4:
1202      return \"st	%1,%0\";
1203    default:
1204      abort();
1205    }
1206}"
1207  [(set_attr "type" "move,move,load,fpload,fpstore")])
1208
1209;; Mixed-mode moves with sign and zero-extension.
1210
1211;; Note that the one starting from HImode comes before those for QImode
1212;; so that a constant operand will match HImode, not QImode.
1213
1214(define_expand "extendhisi2"
1215  [(set (match_operand:SI 0 "register_operand" "")
1216	(sign_extend:SI
1217	 (match_operand:HI 1 "nonimmediate_operand" "")))]
1218 ""
1219 "
1220{
1221  if (GET_CODE (operand1) == REG
1222      || (GET_CODE (operand1) == SUBREG
1223	  && GET_CODE (XEXP (operand1, 0)) == REG))
1224    {
1225      rtx temp = gen_reg_rtx (SImode);
1226      rtx shift_16 = GEN_INT (16);
1227      int op1_subreg_byte = 0;
1228
1229      if (GET_CODE (operand1) == SUBREG)
1230	{
1231	  op1_subreg_byte = SUBREG_BYTE (operand1);
1232	  op1_subreg_byte /= GET_MODE_SIZE (SImode);
1233	  op1_subreg_byte *= GET_MODE_SIZE (SImode);
1234	  operand1 = SUBREG_REG (operand1);
1235	}
1236      if (GET_MODE (operand1) != SImode)
1237	operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1238
1239      emit_insn (gen_ashlsi3 (temp, operand1, shift_16));
1240      emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1241      DONE;
1242    }
1243}")
1244
1245(define_insn ""
1246  [(set (match_operand:SI 0 "register_operand" "=d")
1247	(sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1248  ""
1249  "ldis	%1,%0"
1250  [(set_attr "type" "load")])
1251
1252(define_expand "extendqisi2"
1253  [(set (match_operand:SI 0 "register_operand" "")
1254	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1255  ""
1256  "
1257{
1258  if (GET_CODE (operand1) == REG
1259      || (GET_CODE (operand1) == SUBREG
1260	  && GET_CODE (XEXP (operand1, 0)) == REG))
1261    {
1262      rtx temp = gen_reg_rtx (SImode);
1263      rtx shift_24 = GEN_INT (24);
1264      int op1_subreg_byte = 0;
1265
1266      if (GET_CODE (operand1) == SUBREG)
1267	{
1268	  op1_subreg_byte = SUBREG_BYTE (operand1);
1269	  op1_subreg_byte /= GET_MODE_SIZE (SImode);
1270	  op1_subreg_byte *= GET_MODE_SIZE (SImode);
1271	  operand1 = SUBREG_REG (operand1);
1272	}
1273      if (GET_MODE (operand1) != SImode)
1274	operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1275
1276      emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1277      emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1278      DONE;
1279    }
1280}")
1281
1282(define_insn ""
1283  [(set (match_operand:SI 0 "register_operand" "=d")
1284	(sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1285  ""
1286  "ldib	%1,%0"
1287  [(set_attr "type" "load")])
1288
1289(define_expand "extendqihi2"
1290  [(set (match_operand:HI 0 "register_operand" "")
1291	(sign_extend:HI
1292	 (match_operand:QI 1 "nonimmediate_operand" "")))]
1293  ""
1294  "
1295{
1296  if (GET_CODE (operand1) == REG
1297      || (GET_CODE (operand1) == SUBREG
1298	  && GET_CODE (XEXP (operand1, 0)) == REG))
1299    {
1300      rtx temp = gen_reg_rtx (SImode);
1301      rtx shift_24 = GEN_INT (24);
1302      int op0_subreg_byte = 0;
1303      int op1_subreg_byte = 0;
1304
1305      if (GET_CODE (operand1) == SUBREG)
1306	{
1307	  op1_subreg_byte = SUBREG_BYTE (operand1);
1308	  op1_subreg_byte /= GET_MODE_SIZE (SImode);
1309	  op1_subreg_byte *= GET_MODE_SIZE (SImode);
1310	  operand1 = SUBREG_REG (operand1);
1311	}
1312      if (GET_MODE (operand1) != SImode)
1313	operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1314
1315      if (GET_CODE (operand0) == SUBREG)
1316	{
1317	  op0_subreg_byte = SUBREG_BYTE (operand0);
1318	  op0_subreg_byte /= GET_MODE_SIZE (SImode);
1319	  op0_subreg_byte *= GET_MODE_SIZE (SImode);
1320	  operand0 = SUBREG_REG (operand0);
1321	}
1322      if (GET_MODE (operand0) != SImode)
1323	operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subreg_byte);
1324
1325      emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1326      emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1327      DONE;
1328    }
1329}")
1330
1331(define_insn ""
1332  [(set (match_operand:HI 0 "register_operand" "=d")
1333	(sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1334  ""
1335  "ldib	%1,%0"
1336  [(set_attr "type" "load")])
1337
1338(define_expand "zero_extendhisi2"
1339  [(set (match_operand:SI 0 "register_operand" "")
1340	(zero_extend:SI
1341	 (match_operand:HI 1 "nonimmediate_operand" "")))]
1342 ""
1343 "
1344{
1345  if (GET_CODE (operand1) == REG
1346      || (GET_CODE (operand1) == SUBREG
1347	  && GET_CODE (XEXP (operand1, 0)) == REG))
1348    {
1349      rtx temp = gen_reg_rtx (SImode);
1350      rtx shift_16 = GEN_INT (16);
1351      int op1_subreg_byte = 0;
1352
1353      if (GET_CODE (operand1) == SUBREG)
1354	{
1355	  op1_subreg_byte = SUBREG_BYTE (operand1);
1356	  op1_subreg_byte /= GET_MODE_SIZE (SImode);
1357	  op1_subreg_byte *= GET_MODE_SIZE (SImode);
1358	  operand1 = SUBREG_REG (operand1);
1359	}
1360      if (GET_MODE (operand1) != SImode)
1361	operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1362
1363      emit_insn (gen_ashlsi3 (temp, operand1, shift_16));
1364      emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1365      DONE;
1366    }
1367}")
1368
1369(define_insn ""
1370  [(set (match_operand:SI 0 "register_operand" "=d")
1371	(zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1372  ""
1373  "ldos	%1,%0"
1374  [(set_attr "type" "load")])
1375
1376;; Using shifts here generates much better code than doing an `and 255'.
1377;; This is mainly because the `and' requires loading the constant separately,
1378;; the constant is likely to get optimized, and then the compiler can't
1379;; optimize the `and' because it doesn't know that one operand is a constant.
1380
1381(define_expand "zero_extendqisi2"
1382  [(set (match_operand:SI 0 "register_operand" "")
1383	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1384  ""
1385  "
1386{
1387  if (GET_CODE (operand1) == REG
1388      || (GET_CODE (operand1) == SUBREG
1389	  && GET_CODE (XEXP (operand1, 0)) == REG))
1390    {
1391      rtx temp = gen_reg_rtx (SImode);
1392      rtx shift_24 = GEN_INT (24);
1393      int op1_subreg_byte = 0;
1394
1395      if (GET_CODE (operand1) == SUBREG)
1396	{
1397          op1_subreg_byte = SUBREG_BYTE (operand1);
1398          op1_subreg_byte /= GET_MODE_SIZE (SImode);
1399          op1_subreg_byte *= GET_MODE_SIZE (SImode);
1400          operand1 = SUBREG_REG (operand1);
1401	}
1402      if (GET_MODE (operand1) != SImode)
1403	operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1404
1405      emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1406      emit_insn (gen_lshrsi3 (operand0, temp, shift_24));
1407      DONE;
1408    }
1409}")
1410
1411(define_insn ""
1412  [(set (match_operand:SI 0 "register_operand" "=d")
1413	(zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1414  ""
1415  "ldob	%1,%0"
1416  [(set_attr "type" "load")])
1417
1418(define_expand "zero_extendqihi2"
1419  [(set (match_operand:HI 0 "register_operand" "")
1420	(zero_extend:HI
1421	 (match_operand:QI 1 "nonimmediate_operand" "")))]
1422  ""
1423  "
1424{
1425  if (GET_CODE (operand1) == REG
1426      || (GET_CODE (operand1) == SUBREG
1427	  && GET_CODE (XEXP (operand1, 0)) == REG))
1428    {
1429      rtx temp = gen_reg_rtx (SImode);
1430      rtx shift_24 = GEN_INT (24);
1431      int op0_subreg_byte = 0;
1432      int op1_subreg_byte = 0;
1433
1434      if (GET_CODE (operand1) == SUBREG)
1435	{
1436	  op1_subreg_byte = SUBREG_BYTE (operand1);
1437	  operand1 = SUBREG_REG (operand1);
1438	}
1439      if (GET_MODE (operand1) != SImode)
1440	operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
1441
1442      if (GET_CODE (operand0) == SUBREG)
1443	{
1444	  op0_subreg_byte = SUBREG_BYTE (operand0);
1445	  operand0 = SUBREG_REG (operand0);
1446	}
1447      if (GET_MODE (operand0) != SImode)
1448	operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subreg_byte);
1449
1450      emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1451      emit_insn (gen_lshrsi3 (operand0, temp, shift_24));
1452      DONE;
1453    }
1454}")
1455
1456(define_insn ""
1457  [(set (match_operand:HI 0 "register_operand" "=d")
1458	(zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1459  ""
1460  "ldob	%1,%0"
1461  [(set_attr "type" "load")])
1462
1463;; Conversions between float and double.
1464
1465(define_insn "extendsfdf2"
1466  [(set (match_operand:DF 0 "register_operand" "=*f,d")
1467	(float_extend:DF (match_operand:SF 1 "fp_arith_operand" "dGH,fGH")))]
1468  "TARGET_NUMERICS"
1469  "@
1470  movr	%1,%0
1471  movrl	%1,%0"
1472  [(set_attr "type" "fpmove")])
1473
1474(define_insn "truncdfsf2"
1475  [(set (match_operand:SF 0 "register_operand" "=d")
1476	(float_truncate:SF
1477	 (match_operand:DF 1 "fp_arith_operand" "fGH")))]
1478  "TARGET_NUMERICS"
1479  "movr	%1,%0"
1480  [(set_attr "type" "fpmove")])
1481
1482;; Conversion between fixed point and floating point.
1483
1484(define_insn "floatsidf2"
1485  [(set (match_operand:DF 0 "register_operand" "=f")
1486	(float:DF (match_operand:SI 1 "register_operand" "d")))]
1487  "TARGET_NUMERICS"
1488  "cvtir	%1,%0"
1489  [(set_attr "type" "fpcvt")])
1490
1491(define_insn "floatsisf2"
1492  [(set (match_operand:SF 0 "register_operand" "=d*f")
1493	(float:SF (match_operand:SI 1 "register_operand" "d")))]
1494  "TARGET_NUMERICS"
1495  "cvtir	%1,%0"
1496  [(set_attr "type" "fpcvt")])
1497
1498;; Convert a float to an actual integer.
1499;; Truncation is performed as part of the conversion.
1500;; The i960 requires conversion from DFmode to DImode to make
1501;; unsigned conversions work properly.
1502
1503(define_insn "fixuns_truncdfdi2"
1504  [(set (match_operand:DI 0 "register_operand" "=d")
1505	(unsigned_fix:DI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))]
1506  "TARGET_NUMERICS"
1507  "cvtzril	%1,%0"
1508  [(set_attr "type" "fpcvt")])
1509
1510(define_insn "fixuns_truncsfdi2"
1511  [(set (match_operand:DI 0 "register_operand" "=d")
1512	(unsigned_fix:DI (fix:SF (match_operand:SF 1 "fp_arith_operand" "fGH"))))]
1513  "TARGET_NUMERICS"
1514  "cvtzril	%1,%0"
1515  [(set_attr "type" "fpcvt")])
1516
1517(define_insn "fix_truncdfsi2"
1518  [(set (match_operand:SI 0 "register_operand" "=d")
1519	(fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" "fGH"))))]
1520  "TARGET_NUMERICS"
1521  "cvtzri	%1,%0"
1522  [(set_attr "type" "fpcvt")])
1523
1524(define_expand "fixuns_truncdfsi2"
1525  [(set (match_operand:SI 0 "register_operand" "")
1526	(unsigned_fix:SI (fix:DF (match_operand:DF 1 "fp_arith_operand" ""))))]
1527  "TARGET_NUMERICS"
1528  "
1529{
1530  rtx temp = gen_reg_rtx (DImode);
1531  emit_insn (gen_rtx_SET (VOIDmode, temp,
1532			  gen_rtx_UNSIGNED_FIX (DImode,
1533						gen_rtx_FIX (DFmode,
1534							     operands[1]))));
1535  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1536			  gen_rtx_SUBREG (SImode, temp, 0)));
1537  DONE;
1538}")
1539
1540(define_insn "fix_truncsfsi2"
1541  [(set (match_operand:SI 0 "register_operand" "=d")
1542	(fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" "dfGH"))))]
1543  "TARGET_NUMERICS"
1544  "cvtzri	%1,%0"
1545  [(set_attr "type" "fpcvt")])
1546
1547(define_expand "fixuns_truncsfsi2"
1548  [(set (match_operand:SI 0 "register_operand" "")
1549	(unsigned_fix:SI (fix:SF (match_operand:SF 1 "fp_arith_operand" ""))))]
1550  "TARGET_NUMERICS"
1551  "
1552{
1553  rtx temp = gen_reg_rtx (DImode);
1554  emit_insn (gen_rtx_SET (VOIDmode, temp,
1555			  gen_rtx_UNSIGNED_FIX (DImode,
1556						gen_rtx_FIX (SFmode,
1557							     operands[1]))));
1558  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1559			  gen_rtx_SUBREG (SImode, temp, 0)));
1560  DONE;
1561}")
1562
1563;; Arithmetic instructions.
1564
1565(define_insn "subsi3"
1566  [(set (match_operand:SI 0 "register_operand" "=d")
1567	(minus:SI (match_operand:SI 1 "arith_operand" "dI")
1568		  (match_operand:SI 2 "arith_operand" "dI")))]
1569  ""
1570  "subo	%2,%1,%0")
1571
1572;; Try to generate an lda instruction when it would be faster than an
1573;; add instruction.
1574;; Some assemblers apparently won't accept two addresses added together.
1575
1576;; ??? The condition should be improved to reject the case of two
1577;; symbolic constants.
1578
1579(define_insn ""
1580  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1581	(plus:SI (match_operand:SI 1 "arith32_operand" "%dn,i,dn")
1582		 (match_operand:SI 2 "arith32_operand" "dn,dn,i")))]
1583  "(TARGET_C_SERIES) && (CONSTANT_P (operands[1]) || CONSTANT_P (operands[2]))"
1584  "*
1585{
1586  if (GET_CODE (operands[1]) == CONST_INT)
1587    {
1588      rtx tmp = operands[1];
1589      operands[1] = operands[2];
1590      operands[2] = tmp;
1591    }
1592  if (GET_CODE (operands[2]) == CONST_INT
1593      && GET_CODE (operands[1]) == REG
1594      && i960_last_insn_type != I_TYPE_REG)
1595    {
1596      if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) > -32)
1597	return \"subo	%n2,%1,%0\";
1598      else if (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32)
1599	return \"addo	%1,%2,%0\";
1600    }
1601  /* Non-canonical results (op1 == const, op2 != const) have been seen
1602     in reload output when both operands were symbols before reload, so
1603     we deal with it here.  This may be a fault of the constraints above.  */
1604  if (CONSTANT_P (operands[1]))
1605    {
1606      if (CONSTANT_P (operands[2]))
1607	return \"lda	%1+%2,%0\";
1608      else
1609	return \"lda	%1(%2),%0\";
1610    }
1611  return \"lda	%2(%1),%0\";
1612}")
1613
1614(define_insn "addsi3"
1615  [(set (match_operand:SI 0 "register_operand" "=d")
1616	(plus:SI (match_operand:SI 1 "signed_arith_operand" "%dI")
1617		 (match_operand:SI 2 "signed_arith_operand" "dIK")))]
1618  ""
1619  "*
1620{
1621  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1622    return \"subo	%n2,%1,%0\";
1623  if (i960_bypass (insn, operands[1], operands[2], 0))
1624    return \"addo	%2,%1,%0\";
1625  return \"addo	%1,%2,%0\";
1626}")
1627
1628(define_insn "mulsi3"
1629  [(set (match_operand:SI 0 "register_operand" "=d")
1630	(mult:SI (match_operand:SI 1 "arith_operand" "%dI")
1631		 (match_operand:SI 2 "arith_operand" "dI")))]
1632  ""
1633  "*
1634{
1635  if (i960_bypass (insn, operands[1], operands[2], 0))
1636    return \"mulo	%2,%1,%0\";
1637  return \"mulo	%1,%2,%0\";
1638}"
1639  [(set_attr "type" "mult")])
1640
1641(define_insn "umulsidi3"
1642  [(set (match_operand:DI 0 "register_operand" "=d")
1643	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1644		 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1645  ""
1646  "*
1647{
1648  if (i960_bypass (insn, operands[1], operands[2], 0))
1649    return \"emul	%2,%1,%0\";
1650  return \"emul	%1,%2,%0\";
1651}"
1652  [(set_attr "type" "mult")])
1653
1654(define_insn ""
1655  [(set (match_operand:DI 0 "register_operand" "=d")
1656	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%d"))
1657		 (match_operand:SI 2 "literal" "I")))]
1658  ""
1659  "*
1660{
1661  if (i960_bypass (insn, operands[1], operands[2], 0))
1662    return \"emul	%2,%1,%0\";
1663  return \"emul	%1,%2,%0\";
1664}"
1665  [(set_attr "type" "mult")])
1666
1667;; This goes after the move/add/sub/mul instructions
1668;; because those instructions are better when they apply.
1669
1670(define_insn ""
1671  [(set (match_operand:SI 0 "register_operand" "=d")
1672	(match_operand:SI 1 "address_operand" "p"))]
1673  ""
1674  "lda	%a1,%0"
1675  [(set_attr "type" "load")])
1676
1677;; This will never be selected because of an "optimization" that GCC does.
1678;; It always converts divides by a power of 2 into a sequence of instructions
1679;; that does a right shift, and then corrects the result if it was negative.
1680
1681;; (define_insn ""
1682;;   [(set (match_operand:SI 0 "register_operand" "=d")
1683;;         (div:SI (match_operand:SI 1 "arith_operand" "dI")
1684;;                 (match_operand:SI 2 "power2_operand" "nI")))]
1685;;   ""
1686;;   "*{
1687;; 	operands[2] = GEN_INT (bitpos (INTVAL (operands[2])));
1688;; 	return \"shrdi	%2,%1,%0\";
1689;;   }"
1690
1691(define_insn "divsi3"
1692  [(set (match_operand:SI 0 "register_operand" "=d")
1693        (div:SI (match_operand:SI 1 "arith_operand" "dI")
1694                (match_operand:SI 2 "arith_operand" "dI")))]
1695  ""
1696  "divi	%2,%1,%0"
1697  [(set_attr "type" "div")])
1698
1699(define_insn "udivsi3"
1700  [(set (match_operand:SI 0 "register_operand" "=d")
1701        (udiv:SI (match_operand:SI 1 "arith_operand" "dI")
1702		 (match_operand:SI 2 "arith_operand" "dI")))]
1703  ""
1704  "divo	%2,%1,%0"
1705  [(set_attr "type" "div")])
1706
1707;; We must use `remi' not `modi' here, to ensure that `%' has the effects
1708;; specified by the ANSI C standard.
1709
1710(define_insn "modsi3"
1711  [(set (match_operand:SI 0 "register_operand" "=d")
1712        (mod:SI (match_operand:SI 1 "arith_operand" "dI")
1713                (match_operand:SI 2 "arith_operand" "dI")))]
1714  ""
1715  "remi	%2,%1,%0"
1716  [(set_attr "type" "div")])
1717
1718(define_insn "umodsi3"
1719  [(set (match_operand:SI 0 "register_operand" "=d")
1720        (umod:SI (match_operand:SI 1 "arith_operand" "dI")
1721		 (match_operand:SI 2 "arith_operand" "dI")))]
1722  ""
1723  "remo	%2,%1,%0"
1724  [(set_attr "type" "div")])
1725
1726;; And instructions (with complement also).
1727
1728(define_insn "andsi3"
1729  [(set (match_operand:SI 0 "register_operand" "=d")
1730	(and:SI (match_operand:SI 1 "register_operand" "%d")
1731		(match_operand:SI 2 "logic_operand" "dIM")))]
1732  ""
1733  "*
1734{
1735  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1736    return \"andnot	%C2,%1,%0\";
1737  if (i960_bypass (insn, operands[1], operands[2], 0))
1738    return \"and	%2,%1,%0\";
1739  return \"and	%1,%2,%0\";
1740}")
1741
1742(define_insn ""
1743  [(set (match_operand:SI 0 "register_operand" "=d")
1744	(and:SI (match_operand:SI 1 "arith_operand" "dI")
1745		(match_operand:SI 2 "cmplpower2_operand" "n")))]
1746  ""
1747  "*
1748{
1749  operands[2] = GEN_INT (bitpos (~INTVAL (operands[2])));
1750  return \"clrbit	%2,%1,%0\";
1751}")
1752
1753(define_insn ""
1754  [(set (match_operand:SI 0 "register_operand" "=d")
1755	(and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1756		(match_operand:SI 2 "logic_operand" "dIM")))]
1757  ""
1758  "*
1759{
1760  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1761    return \"nor	%C2,%1,%0\";
1762  if (i960_bypass (insn, operands[1], operands[2], 0))
1763    return \"notand	%2,%1,%0\";
1764  return \"andnot	%1,%2,%0\";
1765}")
1766
1767(define_insn ""
1768  [(set (match_operand:SI 0 "register_operand" "=d")
1769	(ior:SI (not:SI (match_operand:SI 1 "register_operand" "%d"))
1770		(not:SI (match_operand:SI 2 "register_operand" "d"))))]
1771  ""
1772  "*
1773{
1774  if (i960_bypass (insn, operands[1], operands[2], 0))
1775    return \"nand	%2,%1,%0\";
1776  return \"nand	%1,%2,%0\";
1777}")
1778
1779(define_insn "iorsi3"
1780  [(set (match_operand:SI 0 "register_operand" "=d")
1781	(ior:SI (match_operand:SI 1 "register_operand" "%d")
1782		(match_operand:SI 2 "logic_operand" "dIM")))]
1783  ""
1784  "*
1785{
1786  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1787    return \"ornot	%C2,%1,%0\";
1788  if (i960_bypass (insn, operands[1], operands[2], 0))
1789    return \"or	%2,%1,%0\";
1790  return \"or	%1,%2,%0\";
1791}")
1792
1793(define_insn ""
1794  [(set (match_operand:SI 0 "register_operand" "=d")
1795	(ior:SI (match_operand:SI 1 "register_operand" "d")
1796		(match_operand:SI 2 "power2_operand" "n")))]
1797  ""
1798  "*
1799{
1800  operands[2] = GEN_INT (bitpos (INTVAL (operands[2])));
1801  return \"setbit	%2,%1,%0\";
1802}")
1803
1804(define_insn ""
1805  [(set (match_operand:SI 0 "register_operand" "=d")
1806	(ior:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1807		(match_operand:SI 2 "logic_operand" "dIM")))]
1808  ""
1809  "*
1810{
1811  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1812    return \"nand	%C2,%1,%0\";
1813  if (i960_bypass (insn, operands[1], operands[2], 0))
1814    return \"notor	%2,%1,%0\";
1815  return \"ornot	%1,%2,%0\";
1816}")
1817
1818(define_insn ""
1819  [(set (match_operand:SI 0 "register_operand" "=d")
1820	(and:SI (not:SI (match_operand:SI 1 "register_operand" "%d"))
1821		(not:SI (match_operand:SI 2 "register_operand" "d"))))]
1822  ""
1823  "*
1824{
1825  if (i960_bypass (insn, operands[1], operands[2], 0))
1826    return \"nor	%2,%1,%0\";
1827  return \"nor	%1,%2,%0\";
1828}")
1829
1830(define_insn "xorsi3"
1831  [(set (match_operand:SI 0 "register_operand" "=d")
1832	(xor:SI (match_operand:SI 1 "register_operand" "%d")
1833		(match_operand:SI 2 "logic_operand" "dIM")))]
1834  ""
1835  "*
1836{
1837  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1838    return \"xnor	%C2,%1,%0\";
1839  if (i960_bypass (insn, operands[1], operands[2], 0))
1840    return \"xor	%2,%1,%0\";
1841  return \"xor	%1,%2,%0\";
1842}")
1843
1844(define_insn ""
1845  [(set (match_operand:SI 0 "register_operand" "=d")
1846	(xor:SI (match_operand:SI 1 "arith_operand" "dI")
1847		(match_operand:SI 2 "power2_operand" "n")))]
1848  ""
1849  "*
1850{
1851  operands[2] = GEN_INT (bitpos (INTVAL (operands[2])));
1852  return \"notbit	%2,%1,%0\";
1853}")
1854
1855(define_insn ""
1856  [(set (match_operand:SI 0 "register_operand" "=d")
1857	(not:SI (xor:SI (match_operand:SI 1 "register_operand" "%d")
1858			(match_operand:SI 2 "register_operand" "d"))))]
1859  ""
1860  "*
1861{
1862  if (i960_bypass (insn, operands[1], operands[2], 0))
1863    return \"xnor	%2,%1,%0\";
1864  return \"xnor	%2,%1,%0\";
1865}")
1866
1867(define_insn ""
1868  [(set (match_operand:SI 0 "register_operand" "=d")
1869	(ior:SI (ashift:SI (const_int 1)
1870			   (match_operand:SI 1 "register_operand" "d"))
1871		(match_operand:SI 2 "arith_operand" "dI")))]
1872  ""
1873  "setbit	%1,%2,%0")
1874
1875;; (not (ashift 1 reg)) canonicalizes to (rotate -2 reg)
1876(define_insn ""
1877  [(set (match_operand:SI 0 "register_operand" "=d")
1878	(and:SI (rotate:SI (const_int -2)
1879			   (match_operand:SI 1 "register_operand" "d"))
1880		(match_operand:SI 2 "register_operand" "d")))]
1881  ""
1882  "clrbit	%1,%2,%0")
1883
1884;; The above pattern canonicalizes to this when both the input and output
1885;; are the same pseudo-register.
1886(define_insn ""
1887  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
1888			 (const_int 1)
1889			 (match_operand:SI 1 "register_operand" "d"))
1890	(const_int 0))]
1891  ""
1892  "clrbit	%1,%0,%0")
1893
1894(define_insn ""
1895  [(set (match_operand:SI 0 "register_operand" "=d")
1896	(xor:SI (ashift:SI (const_int 1)
1897			   (match_operand:SI 1 "register_operand" "d"))
1898		(match_operand:SI 2 "arith_operand" "dI")))]
1899  ""
1900  "notbit	%1,%2,%0")
1901
1902(define_insn "negsi2"
1903  [(set (match_operand:SI 0 "register_operand" "=d")
1904	(neg:SI (match_operand:SI 1 "arith_operand" "dI")))]
1905  ""
1906  "subo	%1,0,%0"
1907  [(set_attr "length" "1")])
1908
1909(define_insn "one_cmplsi2"
1910  [(set (match_operand:SI 0 "register_operand" "=d")
1911	(not:SI (match_operand:SI 1 "arith_operand" "dI")))]
1912  ""
1913  "not	%1,%0"
1914  [(set_attr "length" "1")])
1915
1916;; Floating point arithmetic instructions.
1917
1918(define_insn "adddf3"
1919  [(set (match_operand:DF 0 "register_operand" "=d*f")
1920	(plus:DF (match_operand:DF 1 "fp_arith_operand" "%rGH")
1921		 (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1922  "TARGET_NUMERICS"
1923  "addrl	%1,%2,%0"
1924  [(set_attr "type" "fpadd")])
1925
1926(define_insn "addsf3"
1927  [(set (match_operand:SF 0 "register_operand" "=d*f")
1928	(plus:SF (match_operand:SF 1 "fp_arith_operand" "%rGH")
1929		 (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1930  "TARGET_NUMERICS"
1931  "addr	%1,%2,%0"
1932  [(set_attr "type" "fpadd")])
1933
1934
1935(define_insn "subdf3"
1936  [(set (match_operand:DF 0 "register_operand" "=d*f")
1937	(minus:DF (match_operand:DF 1 "fp_arith_operand" "rGH")
1938		  (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1939  "TARGET_NUMERICS"
1940  "subrl	%2,%1,%0"
1941  [(set_attr "type" "fpadd")])
1942
1943(define_insn "subsf3"
1944  [(set (match_operand:SF 0 "register_operand" "=d*f")
1945	(minus:SF (match_operand:SF 1 "fp_arith_operand" "rGH")
1946		  (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1947  "TARGET_NUMERICS"
1948  "subr	%2,%1,%0"
1949  [(set_attr "type" "fpadd")])
1950
1951
1952(define_insn "muldf3"
1953  [(set (match_operand:DF 0 "register_operand" "=d*f")
1954	(mult:DF (match_operand:DF 1 "fp_arith_operand" "%rGH")
1955		 (match_operand:DF 2 "fp_arith_operand" "rGH")))]
1956  "TARGET_NUMERICS"
1957  "mulrl	%1,%2,%0"
1958  [(set_attr "type" "fpmul")])
1959
1960(define_insn "mulsf3"
1961  [(set (match_operand:SF 0 "register_operand" "=d*f")
1962	(mult:SF (match_operand:SF 1 "fp_arith_operand" "%rGH")
1963		 (match_operand:SF 2 "fp_arith_operand" "rGH")))]
1964  "TARGET_NUMERICS"
1965  "mulr	%1,%2,%0"
1966  [(set_attr "type" "fpmul")])
1967
1968
1969(define_insn "divdf3"
1970  [(set (match_operand:DF 0 "register_operand" "=d*f")
1971	(div:DF (match_operand:DF 1 "fp_arith_operand" "rGH")
1972		(match_operand:DF 2 "fp_arith_operand" "rGH")))]
1973  "TARGET_NUMERICS"
1974  "divrl	%2,%1,%0"
1975  [(set_attr "type" "fpdiv")])
1976
1977(define_insn "divsf3"
1978  [(set (match_operand:SF 0 "register_operand" "=d*f")
1979	(div:SF (match_operand:SF 1 "fp_arith_operand" "rGH")
1980		(match_operand:SF 2 "fp_arith_operand" "rGH")))]
1981  "TARGET_NUMERICS"
1982  "divr	%2,%1,%0"
1983  [(set_attr "type" "fpdiv")])
1984
1985(define_insn "negdf2"
1986  [(set (match_operand:DF 0 "register_operand" "=d,d*f")
1987	(neg:DF (match_operand:DF 1 "register_operand" "d,r")))]
1988  ""
1989  "*
1990{
1991  if (which_alternative == 0)
1992    {
1993      if (REGNO (operands[0]) == REGNO (operands[1]))
1994	return \"notbit	31,%D1,%D0\";
1995      return \"mov	%1,%0\;notbit	31,%D1,%D0\";
1996    }
1997  return \"subrl	%1,0f0.0,%0\";
1998}"
1999  [(set_attr "type" "fpadd")])
2000
2001(define_insn "negsf2"
2002  [(set (match_operand:SF 0 "register_operand" "=d,d*f")
2003	(neg:SF (match_operand:SF 1 "register_operand" "d,r")))]
2004  ""
2005  "@
2006  notbit	31,%1,%0
2007  subr	%1,0f0.0,%0"
2008  [(set_attr "type" "fpadd")])
2009
2010;;; The abs patterns also work even if the target machine doesn't have
2011;;; floating point, because in that case dstreg and srcreg will always be
2012;;; less than 32.
2013
2014(define_insn "absdf2"
2015  [(set (match_operand:DF 0 "register_operand" "=d*f")
2016	(abs:DF (match_operand:DF 1 "register_operand" "df")))]
2017  ""
2018  "*
2019{
2020  int dstreg = REGNO (operands[0]);
2021  int srcreg = REGNO (operands[1]);
2022
2023  if (dstreg < 32)
2024    {
2025      if (srcreg < 32)
2026	{
2027	  if (dstreg != srcreg)
2028	    output_asm_insn (\"mov	%1,%0\", operands);
2029	  return \"clrbit	31,%D1,%D0\";
2030	}
2031      /* Src is an fp reg.  */
2032      return \"movrl	%1,%0\;clrbit	31,%D1,%D0\";
2033    }
2034  if (srcreg >= 32)
2035    return \"cpysre	%1,0f0.0,%0\";
2036  return \"movrl	%1,%0\;cpysre	%0,0f0.0,%0\";
2037}"
2038  [(set_attr "type" "multi")])
2039
2040(define_insn "abssf2"
2041  [(set (match_operand:SF 0 "register_operand" "=d*f")
2042	(abs:SF (match_operand:SF 1 "register_operand" "df")))]
2043  ""
2044  "*
2045{
2046  int dstreg = REGNO (operands[0]);
2047  int srcreg = REGNO (operands[1]);
2048
2049  if (dstreg < 32 && srcreg < 32)
2050    return \"clrbit	31,%1,%0\";
2051
2052  if (dstreg >= 32 && srcreg >= 32)
2053    return \"cpysre	%1,0f0.0,%0\";
2054
2055  if (dstreg < 32)
2056    return \"movr	%1,%0\;clrbit	31,%0,%0\";
2057
2058  return \"movr	%1,%0\;cpysre	%0,0f0.0,%0\";
2059}"
2060  [(set_attr "type" "multi")])
2061
2062;; Tetra (16 byte) float support.
2063
2064(define_expand "cmptf"
2065  [(set (reg:CC 36)
2066	(compare:CC (match_operand:TF 0 "register_operand" "")
2067		    (match_operand:TF 1 "nonmemory_operand" "")))]
2068  "TARGET_NUMERICS"
2069  "
2070{
2071  i960_compare_op0 = operands[0];
2072  i960_compare_op1 = operands[1];
2073  DONE;
2074}")
2075
2076(define_insn ""
2077  [(set (reg:CC 36)
2078	(compare:CC (match_operand:TF 0 "register_operand" "f")
2079		    (match_operand:TF 1 "nonmemory_operand" "fGH")))]
2080  "TARGET_NUMERICS"
2081  "cmpr %0,%1"
2082  [(set_attr "type" "fpcc")])
2083
2084(define_expand "movtf"
2085  [(set (match_operand:TF 0 "general_operand" "")
2086	(match_operand:TF 1 "fpmove_src_operand" ""))]
2087  ""
2088  "
2089{
2090  if (emit_move_sequence (operands, TFmode))
2091    DONE;
2092}")
2093
2094(define_insn ""
2095  [(set (match_operand:TF 0 "general_operand" "=r,f,d,d,m")
2096	(match_operand:TF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
2097  "register_operand (operands[0], TFmode)
2098   || register_operand (operands[1], TFmode)"
2099  "*
2100{
2101  switch (which_alternative)
2102    {
2103    case 0:
2104      if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2105	return \"movre	%1,%0\";
2106      else
2107	return \"movq	%1,%0\";
2108    case 1:
2109      return \"movre	%1,%0\";
2110    case 2:
2111      return i960_output_ldconst (operands[0], operands[1]);
2112    case 3:
2113      return \"ldt	%1,%0\";
2114    case 4:
2115      return \"stt	%1,%0\";
2116    default:
2117      abort();
2118    }
2119}"
2120  [(set_attr "type" "move,move,load,fpload,fpstore")])
2121
2122(define_insn "extendsftf2"
2123  [(set (match_operand:TF 0 "register_operand" "=f,d")
2124	(float_extend:TF
2125	 (match_operand:SF 1 "register_operand" "d,f")))]
2126  "TARGET_NUMERICS"
2127  "@
2128  movr	%1,%0
2129  movre	%1,%0"
2130  [(set_attr "type" "fpmove")])
2131
2132(define_insn "extenddftf2"
2133  [(set (match_operand:TF 0 "register_operand" "=f,d")
2134	(float_extend:TF
2135	 (match_operand:DF 1 "register_operand" "d,f")))]
2136  "TARGET_NUMERICS"
2137  "@
2138  movrl	%1,%0
2139  movre	%1,%0"
2140  [(set_attr "type" "fpmove")])
2141
2142(define_insn "trunctfdf2"
2143  [(set (match_operand:DF 0 "register_operand" "=d")
2144	(float_truncate:DF
2145	 (match_operand:TF 1 "register_operand" "f")))]
2146  "TARGET_NUMERICS"
2147  "movrl	%1,%0"
2148  [(set_attr "type" "fpmove")])
2149
2150(define_insn "trunctfsf2"
2151  [(set (match_operand:SF 0 "register_operand" "=d")
2152	(float_truncate:SF
2153	 (match_operand:TF 1 "register_operand" "f")))]
2154  "TARGET_NUMERICS"
2155  "movr	%1,%0"
2156  [(set_attr "type" "fpmove")])
2157
2158(define_insn "floatsitf2"
2159  [(set (match_operand:TF 0 "register_operand" "=f")
2160	(float:TF (match_operand:SI 1 "register_operand" "d")))]
2161  "TARGET_NUMERICS"
2162  "cvtir	%1,%0"
2163  [(set_attr "type" "fpcvt")])
2164
2165(define_insn "fix_trunctfsi2"
2166  [(set (match_operand:SI 0 "register_operand" "=d")
2167	(fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
2168  "TARGET_NUMERICS"
2169  "cvtzri	%1,%0"
2170  [(set_attr "type" "fpcvt")])
2171
2172(define_insn "fixuns_trunctfsi2"
2173  [(set (match_operand:SI 0 "register_operand" "=d")
2174	(unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
2175  "TARGET_NUMERICS"
2176  "cvtzri	%1,%0"
2177  [(set_attr "type" "fpcvt")])
2178
2179(define_insn "addtf3"
2180  [(set (match_operand:TF 0 "register_operand" "=f")
2181	(plus:TF (match_operand:TF 1 "nonmemory_operand" "%fGH")
2182		 (match_operand:TF 2 "nonmemory_operand" "fGH")))]
2183  "TARGET_NUMERICS"
2184  "addr	%1,%2,%0"
2185  [(set_attr "type" "fpadd")])
2186
2187(define_insn "subtf3"
2188  [(set (match_operand:TF 0 "register_operand" "=f")
2189	(minus:TF (match_operand:TF 1 "nonmemory_operand" "fGH")
2190		  (match_operand:TF 2 "nonmemory_operand" "fGH")))]
2191  "TARGET_NUMERICS"
2192  "subr	%2,%1,%0"
2193  [(set_attr "type" "fpadd")])
2194
2195(define_insn "multf3"
2196  [(set (match_operand:TF 0 "register_operand" "=f")
2197	(mult:TF (match_operand:TF 1 "nonmemory_operand" "%fGH")
2198		 (match_operand:TF 2 "nonmemory_operand" "fGH")))]
2199  "TARGET_NUMERICS"
2200  "mulr	%1,%2,%0"
2201  [(set_attr "type" "fpmul")])
2202
2203(define_insn "divtf3"
2204  [(set (match_operand:TF 0 "register_operand" "=f")
2205	(div:TF (match_operand:TF 1 "nonmemory_operand" "fGH")
2206		(match_operand:TF 2 "nonmemory_operand" "fGH")))]
2207  "TARGET_NUMERICS"
2208  "divr	%2,%1,%0"
2209  [(set_attr "type" "fpdiv")])
2210
2211(define_insn "negtf2"
2212  [(set (match_operand:TF 0 "register_operand" "=f")
2213	(neg:TF (match_operand:TF 1 "register_operand" "f")))]
2214  "TARGET_NUMERICS"
2215  "subr	%1,0f0.0,%0"
2216  [(set_attr "type" "fpadd")])
2217
2218(define_insn "abstf2"
2219  [(set (match_operand:TF 0 "register_operand" "=f")
2220	(abs:TF (match_operand:TF 1 "register_operand" "f")))]
2221  "(TARGET_NUMERICS)"
2222  "cpysre	%1,0f0.0,%0"
2223  [(set_attr "type" "fpmove")])
2224
2225;; Arithmetic shift instructions.
2226
2227;; The shli instruction generates an overflow fault if the sign changes.
2228;; In the case of overflow, it does not give the natural result, it instead
2229;; gives the last shift value before the overflow.  We can not use this
2230;; instruction because gcc thinks that arithmetic left shift and logical
2231;; left shift are identical, and sometimes canonicalizes the logical left
2232;; shift to an arithmetic left shift.  Therefore we must always use the
2233;; logical left shift instruction.
2234
2235(define_insn "ashlsi3"
2236  [(set (match_operand:SI 0 "register_operand" "=d")
2237	(ashift:SI (match_operand:SI 1 "arith_operand" "dI")
2238		   (match_operand:SI 2 "arith_operand" "dI")))]
2239  ""
2240  "shlo	%2,%1,%0"
2241  [(set_attr "type" "alu2")])
2242
2243(define_insn "ashrsi3"
2244  [(set (match_operand:SI 0 "register_operand" "=d")
2245	(ashiftrt:SI (match_operand:SI 1 "arith_operand" "dI")
2246		     (match_operand:SI 2 "arith_operand" "dI")))]
2247  ""
2248  "shri	%2,%1,%0"
2249  [(set_attr "type" "alu2")])
2250
2251(define_insn "lshrsi3"
2252  [(set (match_operand:SI 0 "register_operand" "=d")
2253	(lshiftrt:SI (match_operand:SI 1 "arith_operand" "dI")
2254		   (match_operand:SI 2 "arith_operand" "dI")))]
2255  ""
2256  "shro	%2,%1,%0"
2257  [(set_attr "type" "alu2")])
2258
2259;; Unconditional and other jump instructions.
2260
2261(define_insn "jump"
2262  [(set (pc)
2263	(label_ref (match_operand 0 "" "")))]
2264  ""
2265  "b	%l0"
2266  [(set_attr "type" "branch")])
2267
2268(define_insn "indirect_jump"
2269  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2270  ""
2271  "bx	%a0"
2272  [(set_attr "type" "branch")])
2273
2274(define_insn "tablejump"
2275  [(set (pc) (match_operand:SI 0 "register_operand" "d"))
2276   (use (label_ref (match_operand 1 "" "")))]
2277  ""
2278  "*
2279{
2280  if (flag_pic)
2281    return \"bx	%l1(%0)\";
2282  else
2283    return \"bx	(%0)\";
2284}"
2285  [(set_attr "type" "branch")])
2286
2287;;- jump to subroutine
2288
2289(define_expand "call"
2290  [(call (match_operand:SI 0 "memory_operand" "m")
2291	 (match_operand:SI 1 "immediate_operand" "i"))]
2292  ""
2293  "
2294{
2295  emit_call_insn (gen_call_internal (operands[0], operands[1],
2296				     virtual_outgoing_args_rtx));
2297  DONE;
2298}")
2299
2300;; We need a call saved register allocated for the match_scratch, so we use
2301;; 'l' because all local registers are call saved.
2302
2303;; ??? I would prefer to use a match_scratch here, but match_scratch allocated
2304;; registers can't be used for spills.  In a function with lots of calls,
2305;; local-alloc may allocate all local registers to a match_scratch, leaving
2306;; no local registers available for spills.
2307
2308(define_insn "call_internal"
2309  [(call (match_operand:SI 0 "memory_operand" "m")
2310	 (match_operand:SI 1 "immediate_operand" "i"))
2311   (use (match_operand:SI 2 "address_operand" "p"))
2312   (clobber (reg:SI 19))]
2313  ""
2314  "* return i960_output_call_insn (operands[0], operands[1], operands[2],
2315				   insn);"
2316  [(set_attr "type" "call")])
2317
2318(define_expand "call_value"
2319  [(set (match_operand 0 "register_operand" "=d")
2320	(call (match_operand:SI 1 "memory_operand" "m")
2321	      (match_operand:SI 2 "immediate_operand" "i")))]
2322  ""
2323  "
2324{
2325  emit_call_insn (gen_call_value_internal (operands[0], operands[1],
2326					   operands[2],
2327				           virtual_outgoing_args_rtx));
2328  DONE;
2329}")
2330
2331;; We need a call saved register allocated for the match_scratch, so we use
2332;; 'l' because all local registers are call saved.
2333
2334(define_insn "call_value_internal"
2335  [(set (match_operand 0 "register_operand" "=d")
2336	(call (match_operand:SI 1 "memory_operand" "m")
2337	      (match_operand:SI 2 "immediate_operand" "i")))
2338   (use (match_operand:SI 3 "address_operand" "p"))
2339   (clobber (reg:SI 19))]
2340  ""
2341  "* return i960_output_call_insn (operands[1], operands[2], operands[3],
2342				   insn);"
2343  [(set_attr "type" "call")])
2344
2345(define_insn "return"
2346  [(return)]
2347  ""
2348  "* return i960_output_ret_insn (insn);"
2349  [(set_attr "type" "branch")])
2350
2351;; A return instruction.  Used only by nonlocal_goto to change the
2352;; stack pointer, frame pointer, previous frame pointer and the return
2353;; instruction pointer.
2354(define_insn "ret"
2355  [(set (pc) (unspec_volatile [(reg:SI 16)] 3))]
2356  ""
2357  "ret"
2358  [(set_attr "type" "branch")
2359   (set_attr "length" "1")])
2360
2361(define_expand "nonlocal_goto"
2362  [(match_operand:SI 0 "" "")
2363   (match_operand:SI 1 "general_operand" "")
2364   (match_operand:SI 2 "general_operand" "")
2365   (match_operand:SI 3 "general_operand" "")]
2366  ""
2367  "
2368{
2369  rtx chain = operands[0];
2370  rtx handler = operands[1];
2371  rtx stack = operands[2];
2372
2373  /* We must restore the stack pointer, frame pointer, previous frame
2374     pointer and the return instruction pointer.  Since the ret
2375     instruction does all this for us with one instruction, we arrange
2376     everything so that ret will do everything we need done.  */
2377
2378  /* First, we must flush the register windows, so that we can modify
2379     the saved local registers on the stack directly and because we
2380     are going to change the previous frame pointer.  */
2381
2382  emit_insn (gen_flush_register_windows ());
2383
2384  /* Load the static chain value for the containing fn into fp.  This is needed
2385     because STACK refers to fp.  */
2386  emit_move_insn (hard_frame_pointer_rtx, chain);
2387
2388  /* Now move the adjusted value into the pfp register for the following return
2389     instruction.  */
2390  emit_move_insn (gen_rtx (REG, SImode, 16),
2391		  plus_constant (hard_frame_pointer_rtx, -64));
2392
2393  /* Next, we put the address that we want to transfer to, into the
2394     saved $rip value in the frame.  Once we ret below, that value
2395     will be loaded into the pc (IP).  */
2396
2397  emit_move_insn (gen_rtx (MEM, SImode,
2398			   plus_constant (hard_frame_pointer_rtx, -56)),
2399		  handler);
2400
2401  /* Next, we put stack into the saved $sp value in the frame.  */
2402  emit_move_insn (gen_rtx (MEM, SImode,
2403			   plus_constant (hard_frame_pointer_rtx, -60)),
2404		  stack);
2405
2406  /* And finally, we can now just ret to get all the values saved
2407     above into all the right registers, and also, all the local
2408     register that were in use in the function, are restored from
2409     their saved values (from the call instruction) on the stack
2410     because we are very careful to ret from the exact save area in
2411     use during the original call.  */
2412
2413  emit_jump_insn (gen_ret ());
2414  emit_barrier ();
2415  DONE;
2416}")
2417
2418;; Special insn to flush register windows.
2419(define_insn "flush_register_windows"
2420  [(unspec_volatile [(const_int 0)] 1)]
2421  ""
2422  "flushreg"
2423  [(set_attr "type" "misc")
2424   (set_attr "length" "1")])
2425
2426(define_insn "nop"
2427  [(const_int 0)]
2428  ""
2429  "")
2430
2431;; Various peephole optimizations for multiple-word moves, loads, and stores.
2432;; Multiple register moves.
2433
2434;; Matched 5/28/91
2435(define_peephole
2436  [(set (match_operand:SI 0 "register_operand" "=r")
2437	(match_operand:SI 1 "register_operand" "r"))
2438   (set (match_operand:SI 2 "register_operand" "=r")
2439	(match_operand:SI 3 "register_operand" "r"))
2440   (set (match_operand:SI 4 "register_operand" "=r")
2441	(match_operand:SI 5 "register_operand" "r"))
2442   (set (match_operand:SI 6 "register_operand" "=r")
2443	(match_operand:SI 7 "register_operand" "r"))]
2444  "((REGNO (operands[0]) & 3) == 0)
2445   && ((REGNO (operands[1]) & 3) == 0)
2446   && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2447   && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2448   && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2449   && (REGNO (operands[1]) + 2 == REGNO (operands[5]))
2450   && (REGNO (operands[0]) + 3 == REGNO (operands[6]))
2451   && (REGNO (operands[1]) + 3 == REGNO (operands[7]))"
2452  "movq	%1,%0")
2453
2454;; Matched 4/17/92
2455(define_peephole
2456  [(set (match_operand:DI 0 "register_operand" "=r")
2457	(match_operand:DI 1 "register_operand" "r"))
2458   (set (match_operand:DI 2 "register_operand" "=r")
2459	(match_operand:DI 3 "register_operand" "r"))]
2460  "((REGNO (operands[0]) & 3) == 0)
2461   && ((REGNO (operands[1]) & 3) == 0)
2462   && (REGNO (operands[0]) + 2 == REGNO (operands[2]))
2463   && (REGNO (operands[1]) + 2 == REGNO (operands[3]))"
2464  "movq	%1,%0")
2465
2466;; Matched 4/17/92
2467(define_peephole
2468  [(set (match_operand:DI 0 "register_operand" "=r")
2469	(match_operand:DI 1 "register_operand" "r"))
2470   (set (match_operand:SI 2 "register_operand" "=r")
2471	(match_operand:SI 3 "register_operand" "r"))
2472   (set (match_operand:SI 4 "register_operand" "=r")
2473	(match_operand:SI 5 "register_operand" "r"))]
2474  "((REGNO (operands[0]) & 3) == 0)
2475   && ((REGNO (operands[1]) & 3) == 0)
2476   && (REGNO (operands[0]) + 2 == REGNO (operands[2]))
2477   && (REGNO (operands[1]) + 2 == REGNO (operands[3]))
2478   && (REGNO (operands[0]) + 3 == REGNO (operands[4]))
2479   && (REGNO (operands[1]) + 3 == REGNO (operands[5]))"
2480  "movq	%1,%0")
2481
2482;; Matched 4/17/92
2483(define_peephole
2484  [(set (match_operand:SI 0 "register_operand" "=r")
2485	(match_operand:SI 1 "register_operand" "r"))
2486   (set (match_operand:SI 2 "register_operand" "=r")
2487	(match_operand:SI 3 "register_operand" "r"))
2488   (set (match_operand:DI 4 "register_operand" "=r")
2489	(match_operand:DI 5 "register_operand" "r"))]
2490  "((REGNO (operands[0]) & 3) == 0)
2491   && ((REGNO (operands[1]) & 3) == 0)
2492   && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2493   && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2494   && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2495   && (REGNO (operands[1]) + 2 == REGNO (operands[5]))"
2496  "movq	%1,%0")
2497
2498;; Matched 4/17/92
2499(define_peephole
2500  [(set (match_operand:DI 0 "register_operand" "=r")
2501	(match_operand:DI 1 "register_operand" "r"))
2502   (set (match_operand:SI 2 "register_operand" "=r")
2503	(match_operand:SI 3 "register_operand" "r"))]
2504  "((REGNO (operands[0]) & 3) == 0)
2505   && ((REGNO (operands[1]) & 3) == 0)
2506   && (REGNO (operands[0]) + 2 == REGNO (operands[2]))
2507   && (REGNO (operands[1]) + 2 == REGNO (operands[3]))"
2508  "movt	%1,%0")
2509
2510;; Matched 5/28/91
2511(define_peephole
2512  [(set (match_operand:SI 0 "register_operand" "=r")
2513	(match_operand:SI 1 "register_operand" "r"))
2514   (set (match_operand:SI 2 "register_operand" "=r")
2515	(match_operand:SI 3 "register_operand" "r"))
2516   (set (match_operand:SI 4 "register_operand" "=r")
2517	(match_operand:SI 5 "register_operand" "r"))]
2518  "((REGNO (operands[0]) & 3) == 0)
2519   && ((REGNO (operands[1]) & 3) == 0)
2520   && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2521   && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2522   && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2523   && (REGNO (operands[1]) + 2 == REGNO (operands[5]))"
2524  "movt	%1,%0")
2525
2526;; Matched 5/28/91
2527(define_peephole
2528  [(set (match_operand:SI 0 "register_operand" "=r")
2529	(match_operand:SI 1 "register_operand" "r"))
2530   (set (match_operand:SI 2 "register_operand" "=r")
2531	(match_operand:SI 3 "register_operand" "r"))]
2532  "((REGNO (operands[0]) & 1) == 0)
2533   && ((REGNO (operands[1]) & 1) == 0)
2534   && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2535   && (REGNO (operands[1]) + 1 == REGNO (operands[3]))"
2536  "movl	%1,%0")
2537
2538; Multiple register loads.
2539
2540;; Matched 6/15/91
2541(define_peephole
2542  [(set (match_operand:SI 0 "register_operand" "=r")
2543	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2544			 (match_operand:SI 2 "immediate_operand" "n"))))
2545   (set (match_operand:SI 3 "register_operand" "=r")
2546	(mem:SI (plus:SI (match_dup 1)
2547			 (match_operand:SI 4 "immediate_operand" "n"))))
2548   (set (match_operand:SI 5 "register_operand" "=r")
2549	(mem:SI (plus:SI (match_dup 1)
2550			 (match_operand:SI 6 "immediate_operand" "n"))))
2551   (set (match_operand:SI 7 "register_operand" "=r")
2552	(mem:SI (plus:SI (match_dup 1)
2553			 (match_operand:SI 8 "immediate_operand" "n"))))]
2554  "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2555   && (REGNO (operands[1]) != REGNO (operands[0]))
2556   && (REGNO (operands[0]) + 1 == REGNO (operands[3]))
2557   && (REGNO (operands[1]) != REGNO (operands[3]))
2558   && (REGNO (operands[0]) + 2 == REGNO (operands[5]))
2559   && (REGNO (operands[1]) != REGNO (operands[5]))
2560   && (REGNO (operands[0]) + 3 == REGNO (operands[7]))
2561   && (INTVAL (operands[2]) + 4 == INTVAL (operands[4]))
2562   && (INTVAL (operands[2]) + 8 == INTVAL (operands[6]))
2563   && (INTVAL (operands[2]) + 12 == INTVAL (operands[8])))"
2564  "ldq	%2(%1),%0")
2565
2566;; Matched 5/28/91
2567(define_peephole
2568  [(set (match_operand:DF 0 "register_operand" "=d")
2569	(mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
2570			 (match_operand:SI 2 "immediate_operand" "n"))))
2571   (set (match_operand:DF 3 "register_operand" "=d")
2572	(mem:DF (plus:SI (match_dup 1)
2573			 (match_operand:SI 4 "immediate_operand" "n"))))]
2574  "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2575   && (REGNO (operands[1]) != REGNO (operands[0]))
2576   && (REGNO (operands[0]) + 2 == REGNO (operands[3]))
2577   && (REGNO (operands[1]) != REGNO (operands[3]))
2578   && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))"
2579  "ldq	%2(%1),%0")
2580
2581;; Matched 1/24/92
2582(define_peephole
2583  [(set (match_operand:DI 0 "register_operand" "=d")
2584	(mem:DI (plus:SI (match_operand:SI 1 "register_operand" "d")
2585			 (match_operand:SI 2 "immediate_operand" "n"))))
2586   (set (match_operand:DI 3 "register_operand" "=d")
2587	(mem:DI (plus:SI (match_dup 1)
2588			 (match_operand:SI 4 "immediate_operand" "n"))))]
2589  "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2590   && (REGNO (operands[1]) != REGNO (operands[0]))
2591   && (REGNO (operands[0]) + 2 == REGNO (operands[3]))
2592   && (REGNO (operands[1]) != REGNO (operands[3]))
2593   && (INTVAL (operands[2]) + 8 == INTVAL (operands[4])))"
2594  "ldq	%2(%1),%0")
2595
2596;; Matched 4/17/92
2597(define_peephole
2598  [(set (match_operand:SI 0 "register_operand" "=d")
2599	(mem:SI (match_operand:SI 1 "register_operand" "d")))
2600   (set (match_operand:SI 2 "register_operand" "=d")
2601	(mem:SI (plus:SI (match_dup 1)
2602			 (match_operand:SI 3 "immediate_operand" "n"))))
2603   (set (match_operand:SI 4 "register_operand" "=d")
2604	(mem:SI (plus:SI (match_dup 1)
2605			 (match_operand:SI 5 "immediate_operand" "n"))))
2606   (set (match_operand:SI 6 "register_operand" "=d")
2607	(mem:SI (plus:SI (match_dup 1)
2608			 (match_operand:SI 7 "immediate_operand" "n"))))]
2609  "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0)
2610   && (REGNO (operands[1]) != REGNO (operands[0]))
2611   && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2612   && (REGNO (operands[1]) != REGNO (operands[2]))
2613   && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2614   && (REGNO (operands[1]) != REGNO (operands[4]))
2615   && (REGNO (operands[0]) + 3 == REGNO (operands[6]))
2616   && (INTVAL (operands[3]) == 4)
2617   && (INTVAL (operands[5]) == 8)
2618   && (INTVAL (operands[7]) == 12))"
2619  "ldq	(%1),%0")
2620
2621;; Matched 5/28/91
2622(define_peephole
2623  [(set (match_operand:SI 0 "register_operand" "=d")
2624	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d")
2625			 (match_operand:SI 2 "immediate_operand" "n"))))
2626   (set (match_operand:SI 3 "register_operand" "=d")
2627	(mem:SI (plus:SI (match_dup 1)
2628			 (match_operand:SI 4 "immediate_operand" "n"))))
2629   (set (match_operand:SI 5 "register_operand" "=d")
2630	(mem:SI (plus:SI (match_dup 1)
2631			 (match_operand:SI 6 "immediate_operand" "n"))))]
2632  "(i960_si_ti (operands[1], operands[2]) && ((REGNO (operands[0]) & 3) == 0)
2633   && (REGNO (operands[1]) != REGNO (operands[0]))
2634   && (REGNO (operands[0]) + 1 == REGNO (operands[3]))
2635   && (REGNO (operands[1]) != REGNO (operands[3]))
2636   && (REGNO (operands[0]) + 2 == REGNO (operands[5]))
2637   && (INTVAL (operands[2]) + 4 == INTVAL (operands[4]))
2638   && (INTVAL (operands[2]) + 8 == INTVAL (operands[6])))"
2639  "ldt	%2(%1),%0")
2640
2641;; Matched 6/15/91
2642(define_peephole
2643  [(set (match_operand:SI 0 "register_operand" "=d")
2644	(mem:SI (match_operand:SI 1 "register_operand" "d")))
2645   (set (match_operand:SI 2 "register_operand" "=d")
2646	(mem:SI (plus:SI (match_dup 1)
2647			 (match_operand:SI 3 "immediate_operand" "n"))))
2648   (set (match_operand:SI 4 "register_operand" "=d")
2649	(mem:SI (plus:SI (match_dup 1)
2650			 (match_operand:SI 5 "immediate_operand" "n"))))]
2651  "(i960_si_ti (operands[1], 0) && ((REGNO (operands[0]) & 3) == 0)
2652   && (REGNO (operands[1]) != REGNO (operands[0]))
2653   && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2654   && (REGNO (operands[1]) != REGNO (operands[2]))
2655   && (REGNO (operands[0]) + 2 == REGNO (operands[4]))
2656   && (INTVAL (operands[3]) == 4)
2657   && (INTVAL (operands[5]) == 8))"
2658  "ldt	(%1),%0")
2659
2660;; Matched 5/28/91
2661(define_peephole
2662  [(set (match_operand:SI 0 "register_operand" "=d")
2663	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d")
2664			 (match_operand:SI 2 "immediate_operand" "n"))))
2665   (set (match_operand:SI 3 "register_operand" "=d")
2666	(mem:SI (plus:SI (match_dup 1)
2667			 (match_operand:SI 4 "immediate_operand" "n"))))]
2668  "(i960_si_di (operands[1], operands[2]) && ((REGNO (operands[0]) & 1) == 0)
2669   && (REGNO (operands[1]) != REGNO (operands[0]))
2670   && (REGNO (operands[0]) + 1 == REGNO (operands[3]))
2671   && (INTVAL (operands[2]) + 4 == INTVAL (operands[4])))"
2672  "ldl	%2(%1),%0")
2673
2674;; Matched 5/28/91
2675(define_peephole
2676  [(set (match_operand:SI 0 "register_operand" "=d")
2677	(mem:SI (match_operand:SI 1 "register_operand" "d")))
2678   (set (match_operand:SI 2 "register_operand" "=d")
2679	(mem:SI (plus:SI (match_dup 1)
2680			 (match_operand:SI 3 "immediate_operand" "n"))))]
2681  "(i960_si_di (operands[1], 0) && ((REGNO (operands[0]) & 1) == 0)
2682   && (REGNO (operands[1]) != REGNO (operands[0]))
2683   && (REGNO (operands[0]) + 1 == REGNO (operands[2]))
2684   && (INTVAL (operands[3]) == 4))"
2685  "ldl	(%1),%0")
2686
2687; Multiple register stores.
2688
2689;; Matched 5/28/91
2690(define_peephole
2691  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d")
2692			 (match_operand:SI 1 "immediate_operand" "n")))
2693	(match_operand:SI 2 "register_operand" "d"))
2694   (set (mem:SI (plus:SI (match_dup 0)
2695			 (match_operand:SI 3 "immediate_operand" "n")))
2696	(match_operand:SI 4 "register_operand" "d"))
2697   (set (mem:SI (plus:SI (match_dup 0)
2698			 (match_operand:SI 5 "immediate_operand" "n")))
2699	(match_operand:SI 6 "register_operand" "d"))
2700   (set (mem:SI (plus:SI (match_dup 0)
2701			 (match_operand:SI 7 "immediate_operand" "n")))
2702	(match_operand:SI 8 "register_operand" "d"))]
2703  "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2704   && (REGNO (operands[2]) + 1 == REGNO (operands[4]))
2705   && (REGNO (operands[2]) + 2 == REGNO (operands[6]))
2706   && (REGNO (operands[2]) + 3 == REGNO (operands[8]))
2707   && (INTVAL (operands[1]) + 4 == INTVAL (operands[3]))
2708   && (INTVAL (operands[1]) + 8 == INTVAL (operands[5]))
2709   && (INTVAL (operands[1]) + 12 == INTVAL (operands[7])))"
2710  "stq	%2,%1(%0)")
2711
2712;; Matched 6/16/91
2713(define_peephole
2714  [(set (mem:DF (plus:SI (match_operand:SI 0 "register_operand" "d")
2715			 (match_operand:SI 1 "immediate_operand" "n")))
2716	(match_operand:DF 2 "register_operand" "d"))
2717   (set (mem:DF (plus:SI (match_dup 0)
2718			 (match_operand:SI 3 "immediate_operand" "n")))
2719	(match_operand:DF 4 "register_operand" "d"))]
2720  "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2721   && (REGNO (operands[2]) + 2 == REGNO (operands[4]))
2722   && (INTVAL (operands[1]) + 8 == INTVAL (operands[3])))"
2723  "stq	%2,%1(%0)")
2724
2725;; Matched 4/17/92
2726(define_peephole
2727  [(set (mem:DI (plus:SI (match_operand:SI 0 "register_operand" "d")
2728			 (match_operand:SI 1 "immediate_operand" "n")))
2729	(match_operand:DI 2 "register_operand" "d"))
2730   (set (mem:DI (plus:SI (match_dup 0)
2731			 (match_operand:SI 3 "immediate_operand" "n")))
2732	(match_operand:DI 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 1/23/92
2739(define_peephole
2740  [(set (mem:SI (match_operand:SI 0 "register_operand" "d"))
2741	(match_operand:SI 1 "register_operand" "d"))
2742   (set (mem:SI (plus:SI (match_dup 0)
2743			 (match_operand:SI 2 "immediate_operand" "n")))
2744	(match_operand:SI 3 "register_operand" "d"))
2745   (set (mem:SI (plus:SI (match_dup 0)
2746			 (match_operand:SI 4 "immediate_operand" "n")))
2747	(match_operand:SI 5 "register_operand" "d"))
2748   (set (mem:SI (plus:SI (match_dup 0)
2749			 (match_operand:SI 6 "immediate_operand" "n")))
2750	(match_operand:SI 7 "register_operand" "d"))]
2751  "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0)
2752   && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2753   && (REGNO (operands[1]) + 2 == REGNO (operands[5]))
2754   && (REGNO (operands[1]) + 3 == REGNO (operands[7]))
2755   && (INTVAL (operands[2]) == 4)
2756   && (INTVAL (operands[4]) == 8)
2757   && (INTVAL (operands[6]) == 12))"
2758  "stq	%1,(%0)")
2759
2760;; Matched 5/29/91
2761(define_peephole
2762  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d")
2763			 (match_operand:SI 1 "immediate_operand" "n")))
2764	(match_operand:SI 2 "register_operand" "d"))
2765   (set (mem:SI (plus:SI (match_dup 0)
2766			 (match_operand:SI 3 "immediate_operand" "n")))
2767	(match_operand:SI 4 "register_operand" "d"))
2768   (set (mem:SI (plus:SI (match_dup 0)
2769			 (match_operand:SI 5 "immediate_operand" "n")))
2770	(match_operand:SI 6 "register_operand" "d"))]
2771  "(i960_si_ti (operands[0], operands[1]) && ((REGNO (operands[2]) & 3) == 0)
2772   && (REGNO (operands[2]) + 1 == REGNO (operands[4]))
2773   && (REGNO (operands[2]) + 2 == REGNO (operands[6]))
2774   && (INTVAL (operands[1]) + 4 == INTVAL (operands[3]))
2775   && (INTVAL (operands[1]) + 8 == INTVAL (operands[5])))"
2776  "stt	%2,%1(%0)")
2777
2778;; Matched 5/29/91
2779(define_peephole
2780  [(set (mem:SI (match_operand:SI 0 "register_operand" "d"))
2781	(match_operand:SI 1 "register_operand" "d"))
2782   (set (mem:SI (plus:SI (match_dup 0)
2783			 (match_operand:SI 2 "immediate_operand" "n")))
2784	(match_operand:SI 3 "register_operand" "d"))
2785   (set (mem:SI (plus:SI (match_dup 0)
2786			 (match_operand:SI 4 "immediate_operand" "n")))
2787	(match_operand:SI 5 "register_operand" "d"))]
2788  "(i960_si_ti (operands[0], 0) && ((REGNO (operands[1]) & 3) == 0)
2789   && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2790   && (REGNO (operands[1]) + 2 == REGNO (operands[5]))
2791   && (INTVAL (operands[2]) == 4)
2792   && (INTVAL (operands[4]) == 8))"
2793  "stt	%1,(%0)")
2794
2795;; Matched 5/28/91
2796(define_peephole
2797  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "d")
2798			 (match_operand:SI 1 "immediate_operand" "n")))
2799	(match_operand:SI 2 "register_operand" "d"))
2800   (set (mem:SI (plus:SI (match_dup 0)
2801			 (match_operand:SI 3 "immediate_operand" "n")))
2802	(match_operand:SI 4 "register_operand" "d"))]
2803  "(i960_si_di (operands[0], operands[1]) && ((REGNO (operands[2]) & 1) == 0)
2804   && (REGNO (operands[2]) + 1 == REGNO (operands[4]))
2805   && (INTVAL (operands[1]) + 4 == INTVAL (operands[3])))"
2806  "stl	%2,%1(%0)")
2807
2808;; Matched 5/28/91
2809(define_peephole
2810  [(set (mem:SI (match_operand:SI 0 "register_operand" "d"))
2811	(match_operand:SI 1 "register_operand" "d"))
2812   (set (mem:SI (plus:SI (match_dup 0)
2813			 (match_operand:SI 2 "immediate_operand" "n")))
2814	(match_operand:SI 3 "register_operand" "d"))]
2815  "(i960_si_di (operands[0], 0) && ((REGNO (operands[1]) & 1) == 0)
2816   && (REGNO (operands[1]) + 1 == REGNO (operands[3]))
2817   && (INTVAL (operands[2]) == 4))"
2818  "stl	%1,(%0)")
2819