]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/i960/i960.md
GNU CC -> GCC
[thirdparty/gcc.git] / gcc / config / i960 / i960.md
CommitLineData
ba8ab355 1;;- Machine description for Intel 80960 chip for GNU C compiler
b72f00af 2;; Copyright (C) 1992, 1995, 1998, 2001 Free Software Foundation, Inc.
ba8ab355
JW
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
7ec022b2 7;; This file is part of GCC.
ba8ab355 8
7ec022b2 9;; GCC is free software; you can redistribute it and/or modify
ba8ab355
JW
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
7ec022b2 14;; GCC is distributed in the hope that it will be useful,
ba8ab355
JW
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
7ec022b2 20;; along with GCC; see the file COPYING. If not, write to
3f63df56
RK
21;; the Free Software Foundation, 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
ba8ab355
JW
23
24;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25\f
bc9c7a36
JW
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
0a1379a0 28;; code by discouraging pseudo-registers from being allocated to them.
bc9c7a36
JW
29;; However, we do want to allow all patterns which can store to them to
30;; include them in their constraints, so we always use '*f' in a destination
31;; constraint except when 'f' is the only alternative.
32\f
ba8ab355
JW
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}
c8e18a2b 59;; {ready-delay} {issue-delay} [{conflict-list}])
ba8ab355
JW
60
61;; The integer ALU
62(define_function_unit "alu" 2 0 (eq_attr "type" "arith,compare,move,address") 1 0)
63(define_function_unit "alu" 2 0 (eq_attr "type" "alu2") 2 0)
64(define_function_unit "alu" 2 0 (eq_attr "type" "mult") 5 0)
65(define_function_unit "alu" 2 0 (eq_attr "type" "div") 35 0)
66(define_function_unit "alu" 2 0 (eq_attr "type" "modscan") 3 0)
67
68;; Memory with load-delay of 1 (i.e., 2 cycle load).
69(define_function_unit "memory" 1 0 (eq_attr "type" "load,fpload") 2 0)
70
71;; Floating point operations.
72(define_function_unit "fp" 1 2 (eq_attr "type" "fpmove") 5 0)
73(define_function_unit "fp" 1 2 (eq_attr "type" "fpcvt") 35 0)
74(define_function_unit "fp" 1 2 (eq_attr "type" "fpcc") 10 0)
75(define_function_unit "fp" 1 2 (eq_attr "type" "fpadd") 10 0)
76(define_function_unit "fp" 1 2 (eq_attr "type" "fpmul") 20 0)
77(define_function_unit "fp" 1 2 (eq_attr "type" "fpdiv") 35 0)
78\f
79;; Compare instructions.
80;; This controls RTL generation and register allocation.
81
82;; We generate RTL for comparisons and branches by having the cmpxx
83;; patterns store away the operands. Then, the scc and bcc patterns
84;; emit RTL for both the compare and the branch.
85;;
38e01259 86;; We start with the DEFINE_EXPANDs, then DEFINE_INSNs to match
ba8ab355
JW
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
c77e04ae 167 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "d")
ba8ab355 168 (const_int 1)
c77e04ae 169 (match_operand:SI 1 "arith_operand" "dI"))
ba8ab355 170 (const_int 0))
c77e04ae 171 (label_ref (match_operand 2 "" ""))
ba8ab355
JW
172 (pc)))]
173 ""
c77e04ae 174 "bbs%+ %1,%0,%l2"
ba8ab355
JW
175 [(set_attr "type" "branch")])
176
177(define_insn ""
178 [(set (pc)
179 (if_then_else
c77e04ae 180 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "d")
ba8ab355 181 (const_int 1)
c77e04ae 182 (match_operand:SI 1 "arith_operand" "dI"))
ba8ab355 183 (const_int 0))
c77e04ae 184 (label_ref (match_operand 2 "" ""))
ba8ab355
JW
185 (pc)))]
186 ""
c77e04ae 187 "bbc%+ %1,%0,%l2"
ba8ab355
JW
188 [(set_attr "type" "branch")])
189
190(define_insn ""
191 [(set (pc)
192 (if_then_else
c77e04ae 193 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
ba8ab355 194 (const_int 1)
c77e04ae 195 (match_operand:SI 1 "arith_operand" "dI"))
ba8ab355 196 (const_int 0))
c77e04ae 197 (label_ref (match_operand 2 "" ""))
ba8ab355
JW
198 (pc)))]
199 ""
c77e04ae 200 "bbs%+ %1,%0,%l2"
ba8ab355
JW
201 [(set_attr "type" "branch")])
202
203(define_insn ""
204 [(set (pc)
205 (if_then_else
c77e04ae 206 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
ba8ab355 207 (const_int 1)
c77e04ae 208 (match_operand:SI 1 "arith_operand" "dI"))
ba8ab355 209 (const_int 0))
c77e04ae 210 (label_ref (match_operand 2 "" ""))
ba8ab355
JW
211 (pc)))]
212 ""
c77e04ae 213 "bbc%+ %1,%0,%l2"
ba8ab355
JW
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")
997718c7 223 (match_operand:SI 1 "arith_operand" "+d")))
ba8ab355
JW
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")
997718c7 232 (match_operand:SI 1 "arith_operand" "+d")))
ba8ab355
JW
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")
997718c7 241 (match_operand:SI 1 "arith_operand" "+d")))
ba8ab355
JW
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")
997718c7 250 (match_operand:SI 1 "arith_operand" "+d")))
ba8ab355
JW
251 (set (match_dup 1) (minus:SI (match_dup 1) (const_int 1)))]
252 "0"
253 "cmpdeco %0,%1"
254 [(set_attr "type" "compare")])
255\f
256;; Templates to store result of condition.
257;; '1' is stored if condition is true.
258;; '0' is stored if condition is false.
259;; These should use predicate "general_operand", since
260;; gcc seems to be creating mem references which use these
261;; templates.
262
263(define_expand "seq"
264 [(set (match_operand:SI 0 "general_operand" "=d")
bc1aa946 265 (eq:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
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")
bc1aa946 274 (ne:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
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")
bc1aa946 283 (gt:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
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")
bc1aa946 292 (gtu:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
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")
bc1aa946 301 (lt:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
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")
bc1aa946 310 (ltu:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
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")
bc1aa946 319 (ge:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
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")
bc1aa946 328 (geu:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
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")
bc1aa946 337 (le:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
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")
bc1aa946 346 (leu:SI (match_dup 1) (const_int 0)))]
ba8ab355
JW
347 ""
348 "
349{
350 operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1);
351}")
352
ef64fa15
TG
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
ba8ab355
JW
360(define_insn ""
361 [(set (match_operand:SI 0 "general_operand" "=d")
bc1aa946 362 (match_operator:SI 1 "comparison_operator" [(reg:CC 36) (const_int 0)]))]
ba8ab355 363 ""
4ec74aeb 364 "test%C1 %0"
ba8ab355
JW
365 [(set_attr "type" "compare")])
366
367(define_insn ""
368 [(set (match_operand:SI 0 "general_operand" "=d")
bc1aa946 369 (match_operator:SI 1 "comparison_operator" [(reg:CC_UNS 36) (const_int 0)]))]
ba8ab355 370 ""
4ec74aeb 371 "test%C1 %0"
ba8ab355
JW
372 [(set_attr "type" "compare")])
373\f
374;; These control RTL generation for conditional jump insns
375;; and match them for register allocation.
376
377(define_expand "beq"
378 [(set (pc)
379 (if_then_else (eq (match_dup 1)
380 (const_int 0))
381 (label_ref (match_operand 0 "" ""))
382 (pc)))]
383 ""
384 "
385{ operands[1] = gen_compare_reg (EQ, i960_compare_op0, i960_compare_op1); }")
386
387(define_expand "bne"
388 [(set (pc)
389 (if_then_else (ne (match_dup 1)
390 (const_int 0))
391 (label_ref (match_operand 0 "" ""))
392 (pc)))]
393 ""
394 "
395{ operands[1] = gen_compare_reg (NE, i960_compare_op0, i960_compare_op1); }")
396
397(define_expand "bgt"
398 [(set (pc)
399 (if_then_else (gt (match_dup 1)
400 (const_int 0))
401 (label_ref (match_operand 0 "" ""))
402 (pc)))]
403 ""
404 "
405{ operands[1] = gen_compare_reg (GT, i960_compare_op0, i960_compare_op1); }")
406
407(define_expand "bgtu"
408 [(set (pc)
409 (if_then_else (gtu (match_dup 1)
410 (const_int 0))
411 (label_ref (match_operand 0 "" ""))
412 (pc)))]
413 ""
414 "
415{ operands[1] = gen_compare_reg (GTU, i960_compare_op0, i960_compare_op1); }")
416
417(define_expand "blt"
418 [(set (pc)
419 (if_then_else (lt (match_dup 1)
420 (const_int 0))
421 (label_ref (match_operand 0 "" ""))
422 (pc)))]
423 ""
424 "
425{ operands[1] = gen_compare_reg (LT, i960_compare_op0, i960_compare_op1); }")
426
427(define_expand "bltu"
428 [(set (pc)
429 (if_then_else (ltu (match_dup 1)
430 (const_int 0))
431 (label_ref (match_operand 0 "" ""))
432 (pc)))]
433 ""
434 "
435{ operands[1] = gen_compare_reg (LTU, i960_compare_op0, i960_compare_op1); }")
436
437(define_expand "bge"
438 [(set (pc)
439 (if_then_else (ge (match_dup 1)
440 (const_int 0))
441 (label_ref (match_operand 0 "" ""))
442 (pc)))]
443 ""
444 "
445{ operands[1] = gen_compare_reg (GE, i960_compare_op0, i960_compare_op1); }")
446
447(define_expand "bgeu"
448 [(set (pc)
449 (if_then_else (geu (match_dup 1)
450 (const_int 0))
451 (label_ref (match_operand 0 "" ""))
452 (pc)))]
453 ""
454 "
455{ operands[1] = gen_compare_reg (GEU, i960_compare_op0, i960_compare_op1); }")
456
457(define_expand "ble"
458 [(set (pc)
459 (if_then_else (le (match_dup 1)
460 (const_int 0))
461 (label_ref (match_operand 0 "" ""))
462 (pc)))]
463 ""
464 "
465{ operands[1] = gen_compare_reg (LE, i960_compare_op0, i960_compare_op1); }")
466
467(define_expand "bleu"
468 [(set (pc)
469 (if_then_else (leu (match_dup 1)
470 (const_int 0))
471 (label_ref (match_operand 0 "" ""))
472 (pc)))]
473 ""
474 "
475{ operands[1] = gen_compare_reg (LEU, i960_compare_op0, i960_compare_op1); }")
476\f
477;; Now the normal branch insns (forward and reverse).
478
479(define_insn ""
480 [(set (pc)
481 (if_then_else (match_operator 0 "comparison_operator"
482 [(reg:CC 36) (const_int 0)])
483 (label_ref (match_operand 1 "" ""))
484 (pc)))]
485 ""
eb9c1bb6 486 "b%C0%+ %l1"
ba8ab355
JW
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 ""
eb9c1bb6 496 "b%I0%+ %l1"
ba8ab355
JW
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 ""
eb9c1bb6 506 "b%C0%+ %l1"
ba8ab355
JW
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 ""
eb9c1bb6 516 "b%I0%+ %l1"
ba8ab355
JW
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 ""
eb9c1bb6 528 "cmp%S0%B0%R0%+ %2,%1,%l3"
ba8ab355
JW
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 ""
eb9c1bb6 540 "cmp%S0%B0%X0%+ %2,%1,%l3"
ba8ab355
JW
541 [(set_attr "type" "branch")])
542\f
a157febd
GK
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 ""
cff27f1d 549 "cmpo g0,g0 ; faulte.t")
a157febd
GK
550
551(define_expand "conditional_trap"
552 [(trap_if (match_operator 0 "comparison_operator"
553 [(match_dup 2) (const_int 0)])
554 (match_operand 1 "const_int_operand" "i"))]
555 ""
556 "
557{
558 operands[2] = gen_compare_reg (GET_CODE (operands[0]),
559 i960_compare_op0, i960_compare_op1);
560}")
561
562(define_insn ""
563 [(trap_if (match_operator 0 "comparison_operator"
564 [(reg:CC 36) (const_int 0)])
565 (match_operand 1 "const_int_operand" "i"))]
566 ""
567 "fault%C0.f")
568
569(define_insn ""
570 [(trap_if (match_operator 0 "comparison_operator"
571 [(reg:CC_UNS 36) (const_int 0)])
572 (match_operand 1 "const_int_operand" "i"))]
573 ""
574 "fault%C0.f")
575\f
ba8ab355 576;; Normal move instructions.
2296cba3 577;; This code is based on the sparc machine description.
ba8ab355
JW
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
e770968b
JW
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
6c535c69 597;; current_function_args_size is zero and this is not a stdarg
f719a85d
RK
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.
ba8ab355
JW
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"))]
e770968b 607 "(current_function_args_size == 0
f719a85d 608 && current_function_stdarg == 0
e770968b 609 && rtx_equal_function_value_matters == 0)
ba8ab355
JW
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\";
1943c2c1
KG
634 default:
635 abort();
ba8ab355
JW
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"))]
e770968b 644 "(current_function_args_size != 0
f719a85d 645 || current_function_stdarg != 0
e770968b 646 || rtx_equal_function_value_matters != 0)
ba8ab355
JW
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\";
1943c2c1
KG
668 default:
669 abort();
ba8ab355
JW
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"))]
e770968b 692 "(current_function_args_size == 0
f719a85d 693 && current_function_stdarg == 0
e770968b 694 && rtx_equal_function_value_matters == 0)
ba8ab355
JW
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\";
1943c2c1
KG
719 default:
720 abort();
ba8ab355
JW
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"))]
e770968b 730 "(current_function_args_size != 0
f719a85d 731 || current_function_stdarg != 0
e770968b 732 || rtx_equal_function_value_matters != 0)
ba8ab355
JW
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\";
1943c2c1
KG
754 default:
755 abort();
ba8ab355
JW
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"))]
e770968b 775 "(current_function_args_size == 0
f719a85d 776 && current_function_stdarg == 0
e770968b 777 && rtx_equal_function_value_matters == 0)
ba8ab355
JW
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\";
1943c2c1
KG
802 default:
803 abort();
ba8ab355
JW
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"))]
e770968b 813 "(current_function_args_size != 0
f719a85d 814 || current_function_stdarg != 0
e770968b 815 || rtx_equal_function_value_matters != 0)
ba8ab355
JW
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\";
1943c2c1
KG
837 default:
838 abort();
ba8ab355
JW
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 ""
1fdf7338
RK
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"))]
e770968b 858 "(current_function_args_size == 0
f719a85d 859 && current_function_stdarg == 0
e770968b 860 && rtx_equal_function_value_matters == 0)
ba8ab355
JW
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:
ba8ab355 869 case 1:
ba8ab355 870 case 3:
76d76a0e 871 case 4:
e5e1552a
RK
872 return i960_output_move_double (operands[0], operands[1]);
873 case 2:
874 return i960_output_ldconst (operands[0], operands[1]);
1fdf7338 875 case 5:
e4d26fc7 876 return i960_output_move_double_zero (operands[0]);
1943c2c1
KG
877 default:
878 abort();
ba8ab355
JW
879 }
880}"
1fdf7338 881 [(set_attr "type" "move,move,load,load,store,store")])
ba8ab355
JW
882
883;; The store case can not be separate. See comment above.
884(define_insn ""
1fdf7338
RK
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"))]
e770968b 887 "(current_function_args_size != 0
f719a85d 888 || current_function_stdarg != 0
e770968b 889 || rtx_equal_function_value_matters != 0)
ba8ab355
JW
890 && (register_operand (operands[0], DImode)
891 || register_operand (operands[1], DImode))"
892 "*
893{
894 switch (which_alternative)
895 {
896 case 0:
ba8ab355 897 case 1:
ba8ab355 898 case 3:
1fdf7338 899 case 4:
e5e1552a
RK
900 return i960_output_move_double (operands[0], operands[1]);
901 case 2:
902 return i960_output_ldconst (operands[0], operands[1]);
1943c2c1
KG
903 default:
904 abort();
ba8ab355
JW
905 }
906}"
1fdf7338 907 [(set_attr "type" "move,move,load,load,store")])
ba8ab355 908
e5e1552a 909(define_insn "*store_unaligned_di_reg"
e5e809f4
JL
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"))]
e5e1552a
RK
913 ""
914 "*
915{
e5e809f4
JL
916 if (which_alternative == 0)
917 return i960_output_move_double (operands[0], operands[1]);
918
c5c76735 919 operands[3] = gen_rtx_MEM (word_mode, operands[2]);
b72f00af 920 operands[4] = adjust_address (operands[3], word_mode, UNITS_PER_WORD);
e5e1552a
RK
921 return \"lda %0,%2\;st %1,%3\;st %D1,%4\";
922}"
e5e809f4 923 [(set_attr "type" "move,store")])
e5e1552a 924
ba8ab355
JW
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 ""
e5e1552a
RK
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"))]
e770968b 939 "(current_function_args_size == 0
f719a85d 940 && current_function_stdarg == 0
e770968b 941 && rtx_equal_function_value_matters == 0)
ba8ab355
JW
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:
ba8ab355 950 case 1:
ba8ab355 951 case 3:
76d76a0e 952 case 4:
e5e1552a
RK
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:
e4d26fc7 957 return i960_output_move_quad_zero (operands[0]);
1943c2c1
KG
958 default:
959 abort();
ba8ab355
JW
960 }
961}"
e5e1552a 962 [(set_attr "type" "move,move,load,load,store,store")])
ba8ab355
JW
963
964;; The store case can not be separate. See comment above.
965(define_insn ""
e5e1552a
RK
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"))]
e770968b 968 "(current_function_args_size != 0
f719a85d 969 || current_function_stdarg != 0
e770968b 970 || rtx_equal_function_value_matters != 0)
ba8ab355
JW
971 && (register_operand (operands[0], TImode)
972 || register_operand (operands[1], TImode))"
973 "*
974{
975 switch (which_alternative)
976 {
977 case 0:
ba8ab355 978 case 1:
ba8ab355 979 case 3:
e5e1552a
RK
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]);
1943c2c1
KG
984 default:
985 abort();
ba8ab355
JW
986 }
987}"
e5e1552a
RK
988 [(set_attr "type" "move,move,load,load,store")])
989
990(define_insn "*store_unaligned_ti_reg"
e5e809f4
JL
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"))]
e5e1552a
RK
994 ""
995 "*
996{
e5e809f4
JL
997 if (which_alternative == 0)
998 return i960_output_move_quad (operands[0], operands[1]);
999
c5c76735 1000 operands[3] = gen_rtx_MEM (word_mode, operands[2]);
b72f00af
RK
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);
e5e1552a
RK
1004 return \"lda %0,%2\;st %1,%3\;st %D1,%4\;st %E1,%5\;st %F1,%6\";
1005}"
e5e809f4 1006 [(set_attr "type" "move,store")])
ba8ab355
JW
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;
792760b9 1017 int offset = 0;
ba8ab355
JW
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]);
ba8ab355
JW
1029 while (count >= 4 && ((regno & 3) == 0))
1030 {
792760b9 1031 emit_move_insn (adjust_address (operands[0], TImode, offset),
c2749e2d 1032 gen_rtx_REG (TImode, regno));
ba8ab355
JW
1033 count -= 4;
1034 regno += 4;
792760b9 1035 offset += 16;
ba8ab355
JW
1036 }
1037 while (count >= 2 && ((regno & 1) == 0))
1038 {
792760b9 1039 emit_move_insn (adjust_address (operands[0], DImode, offset),
c2749e2d 1040 gen_rtx_REG (DImode, regno));
ba8ab355
JW
1041 count -= 2;
1042 regno += 2;
792760b9 1043 offset += 8;
ba8ab355
JW
1044 }
1045 while (count > 0)
1046 {
792760b9 1047 emit_move_insn (adjust_address (operands[0], SImode, offset),
c2749e2d 1048 gen_rtx_REG (SImode, regno));
ba8ab355
JW
1049 count -= 1;
1050 regno += 1;
792760b9 1051 offset += 4;
ba8ab355
JW
1052 }
1053 DONE;
1054}")
1055\f
1056;; Floating point move insns
1057
1058(define_expand "movdf"
1059 [(set (match_operand:DF 0 "general_operand" "")
1060 (match_operand:DF 1 "fpmove_src_operand" ""))]
1061 ""
1062 "
1063{
1064 if (emit_move_sequence (operands, DFmode))
1065 DONE;
1066}")
1067
1068(define_insn ""
bc9c7a36 1069 [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m,o")
76d76a0e 1070 (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d,G"))]
e770968b 1071 "(current_function_args_size == 0
f719a85d 1072 && current_function_stdarg == 0
e770968b 1073 && rtx_equal_function_value_matters == 0)
ba8ab355
JW
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:
ba8ab355 1093 return \"stl %1,%0\";
76d76a0e 1094 case 5:
b72f00af 1095 operands[1] = adjust_address (operands[0], VOIDmode, 4);
76d76a0e 1096 return \"st g14,%0\;st g14,%1\";
1943c2c1
KG
1097 default:
1098 abort();
ba8ab355
JW
1099 }
1100}"
76d76a0e 1101 [(set_attr "type" "move,move,load,fpload,fpstore,fpstore")])
ba8ab355
JW
1102
1103(define_insn ""
bc9c7a36 1104 [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m")
ba8ab355 1105 (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
e770968b 1106 "(current_function_args_size != 0
f719a85d 1107 || current_function_stdarg != 0
e770968b 1108 || rtx_equal_function_value_matters != 0)
ba8ab355
JW
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\";
1943c2c1
KG
1128 default:
1129 abort();
ba8ab355
JW
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 ""
bc9c7a36 1145 [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m")
ba8ab355 1146 (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,dG"))]
e770968b 1147 "(current_function_args_size == 0
f719a85d 1148 && current_function_stdarg == 0
e770968b 1149 && rtx_equal_function_value_matters == 0)
ba8ab355
JW
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\";
1943c2c1
KG
1172 default:
1173 abort();
ba8ab355
JW
1174 }
1175}"
1176 [(set_attr "type" "move,move,load,fpload,fpstore")])
1177
1178(define_insn ""
bc9c7a36 1179 [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m")
ba8ab355 1180 (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,d"))]
e770968b 1181 "(current_function_args_size != 0
f719a85d 1182 || current_function_stdarg != 0
e770968b 1183 || rtx_equal_function_value_matters != 0)
ba8ab355
JW
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\";
1943c2c1
KG
1203 default:
1204 abort();
ba8ab355
JW
1205 }
1206}"
1207 [(set_attr "type" "move,move,load,fpload,fpstore")])
1208\f
1209;; Mixed-mode moves with sign and zero-extension.
1210
1211;; Note that the one starting from HImode comes before those for QImode
1212;; so that a constant operand will match HImode, not QImode.
1213
1214(define_expand "extendhisi2"
1215 [(set (match_operand:SI 0 "register_operand" "")
1216 (sign_extend:SI
1217 (match_operand:HI 1 "nonimmediate_operand" "")))]
1218 ""
1219 "
1220{
1221 if (GET_CODE (operand1) == REG
1222 || (GET_CODE (operand1) == SUBREG
1223 && GET_CODE (XEXP (operand1, 0)) == REG))
1224 {
1225 rtx temp = gen_reg_rtx (SImode);
3a598fbe 1226 rtx shift_16 = GEN_INT (16);
ddef6bc7 1227 int op1_subreg_byte = 0;
ba8ab355
JW
1228
1229 if (GET_CODE (operand1) == SUBREG)
1230 {
ddef6bc7
JJ
1231 op1_subreg_byte = SUBREG_BYTE (operand1);
1232 op1_subreg_byte /= GET_MODE_SIZE (SImode);
1233 op1_subreg_byte *= GET_MODE_SIZE (SImode);
ba8ab355
JW
1234 operand1 = SUBREG_REG (operand1);
1235 }
0197d76b 1236 if (GET_MODE (operand1) != SImode)
ddef6bc7 1237 operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
ba8ab355
JW
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);
3a598fbe 1263 rtx shift_24 = GEN_INT (24);
ddef6bc7 1264 int op1_subreg_byte = 0;
ba8ab355
JW
1265
1266 if (GET_CODE (operand1) == SUBREG)
1267 {
ddef6bc7
JJ
1268 op1_subreg_byte = SUBREG_BYTE (operand1);
1269 op1_subreg_byte /= GET_MODE_SIZE (SImode);
1270 op1_subreg_byte *= GET_MODE_SIZE (SImode);
ba8ab355
JW
1271 operand1 = SUBREG_REG (operand1);
1272 }
0197d76b 1273 if (GET_MODE (operand1) != SImode)
ddef6bc7 1274 operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
ba8ab355
JW
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);
3a598fbe 1301 rtx shift_24 = GEN_INT (24);
ddef6bc7
JJ
1302 int op0_subreg_byte = 0;
1303 int op1_subreg_byte = 0;
ba8ab355
JW
1304
1305 if (GET_CODE (operand1) == SUBREG)
1306 {
ddef6bc7
JJ
1307 op1_subreg_byte = SUBREG_BYTE (operand1);
1308 op1_subreg_byte /= GET_MODE_SIZE (SImode);
1309 op1_subreg_byte *= GET_MODE_SIZE (SImode);
ba8ab355
JW
1310 operand1 = SUBREG_REG (operand1);
1311 }
0197d76b 1312 if (GET_MODE (operand1) != SImode)
ddef6bc7 1313 operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
ba8ab355
JW
1314
1315 if (GET_CODE (operand0) == SUBREG)
1316 {
ddef6bc7
JJ
1317 op0_subreg_byte = SUBREG_BYTE (operand0);
1318 op0_subreg_byte /= GET_MODE_SIZE (SImode);
1319 op0_subreg_byte *= GET_MODE_SIZE (SImode);
ba8ab355
JW
1320 operand0 = SUBREG_REG (operand0);
1321 }
1322 if (GET_MODE (operand0) != SImode)
ddef6bc7 1323 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subreg_byte);
ba8ab355
JW
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);
3a598fbe 1350 rtx shift_16 = GEN_INT (16);
ddef6bc7 1351 int op1_subreg_byte = 0;
ba8ab355
JW
1352
1353 if (GET_CODE (operand1) == SUBREG)
1354 {
ddef6bc7
JJ
1355 op1_subreg_byte = SUBREG_BYTE (operand1);
1356 op1_subreg_byte /= GET_MODE_SIZE (SImode);
1357 op1_subreg_byte *= GET_MODE_SIZE (SImode);
ba8ab355
JW
1358 operand1 = SUBREG_REG (operand1);
1359 }
0197d76b 1360 if (GET_MODE (operand1) != SImode)
ddef6bc7 1361 operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
ba8ab355
JW
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
2b4bd1bc
JW
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
ba8ab355
JW
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);
3a598fbe 1392 rtx shift_24 = GEN_INT (24);
ddef6bc7 1393 int op1_subreg_byte = 0;
ba8ab355
JW
1394
1395 if (GET_CODE (operand1) == SUBREG)
1396 {
ddef6bc7
JJ
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);
ba8ab355 1401 }
0197d76b 1402 if (GET_MODE (operand1) != SImode)
ddef6bc7 1403 operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
ba8ab355
JW
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);
3a598fbe 1430 rtx shift_24 = GEN_INT (24);
ddef6bc7
JJ
1431 int op0_subreg_byte = 0;
1432 int op1_subreg_byte = 0;
ba8ab355
JW
1433
1434 if (GET_CODE (operand1) == SUBREG)
1435 {
ddef6bc7 1436 op1_subreg_byte = SUBREG_BYTE (operand1);
ba8ab355
JW
1437 operand1 = SUBREG_REG (operand1);
1438 }
0197d76b 1439 if (GET_MODE (operand1) != SImode)
ddef6bc7 1440 operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte);
ba8ab355
JW
1441
1442 if (GET_CODE (operand0) == SUBREG)
1443 {
ddef6bc7 1444 op0_subreg_byte = SUBREG_BYTE (operand0);
ba8ab355
JW
1445 operand0 = SUBREG_REG (operand0);
1446 }
1447 if (GET_MODE (operand0) != SImode)
ddef6bc7 1448 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subreg_byte);
ba8ab355
JW
1449
1450 emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
1451 emit_insn (gen_lshrsi3 (operand0, temp, shift_24));
1452 DONE;
1453 }
1454}")
1455
1456(define_insn ""
1457 [(set (match_operand:HI 0 "register_operand" "=d")
1458 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1459 ""
1460 "ldob %1,%0"
1461 [(set_attr "type" "load")])
1462\f
1463;; Conversions between float and double.
1464
1465(define_insn "extendsfdf2"
bc9c7a36 1466 [(set (match_operand:DF 0 "register_operand" "=*f,d")
ba8ab355
JW
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"
bc9c7a36 1492 [(set (match_operand:SF 0 "register_operand" "=d*f")
ba8ab355
JW
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);
c5c76735
JL
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)));
ba8ab355
JW
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);
c5c76735
JL
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)));
ba8ab355
JW
1560 DONE;
1561}")
1562\f
1563;; Arithmetic instructions.
1564
1565(define_insn "subsi3"
1566 [(set (match_operand:SI 0 "register_operand" "=d")
1567 (minus:SI (match_operand:SI 1 "arith_operand" "dI")
1568 (match_operand:SI 2 "arith_operand" "dI")))]
1569 ""
1570 "subo %2,%1,%0")
1571
1572;; Try to generate an lda instruction when it would be faster than an
1573;; add instruction.
1574;; Some assemblers apparently won't accept two addresses added together.
1575
292099cc
JW
1576;; ??? The condition should be improved to reject the case of two
1577;; symbolic constants.
1578
ba8ab355
JW
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 }
292099cc
JW
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. */
ba8ab355 1604 if (CONSTANT_P (operands[1]))
292099cc
JW
1605 {
1606 if (CONSTANT_P (operands[2]))
1607 return \"lda %1+%2,%0\";
1608 else
1609 return \"lda %1(%2),%0\";
1610 }
ba8ab355
JW
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{
4ec74aeb 1621 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
ba8ab355
JW
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
4ec74aeb
JW
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 "*
9116497e
JW
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"))
21d90119 1657 (match_operand:SI 2 "literal" "I")))]
9116497e
JW
1658 ""
1659 "*
4ec74aeb
JW
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
ba8ab355
JW
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;; "*{
3a598fbe 1687;; operands[2] = GEN_INT (bitpos (INTVAL (operands[2])));
ba8ab355
JW
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")
5d17176f
TG
1730 (and:SI (match_operand:SI 1 "register_operand" "%d")
1731 (match_operand:SI 2 "logic_operand" "dIM")))]
ba8ab355
JW
1732 ""
1733 "*
1734{
5d17176f
TG
1735 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1736 return \"andnot %C2,%1,%0\";
ba8ab355
JW
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")
5d17176f
TG
1744 (and:SI (match_operand:SI 1 "arith_operand" "dI")
1745 (match_operand:SI 2 "cmplpower2_operand" "n")))]
ba8ab355
JW
1746 ""
1747 "*
1748{
3a598fbe 1749 operands[2] = GEN_INT (bitpos (~INTVAL (operands[2])));
5d17176f
TG
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\";
ba8ab355
JW
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")
5d17176f
TG
1769 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "%d"))
1770 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
ba8ab355
JW
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
5d17176f
TG
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
ba8ab355
JW
1793(define_insn ""
1794 [(set (match_operand:SI 0 "register_operand" "=d")
5d17176f 1795 (ior:SI (match_operand:SI 1 "register_operand" "d")
4ec74aeb 1796 (match_operand:SI 2 "power2_operand" "n")))]
ba8ab355
JW
1797 ""
1798 "*
1799{
3a598fbe 1800 operands[2] = GEN_INT (bitpos (INTVAL (operands[2])));
4ec74aeb 1801 return \"setbit %2,%1,%0\";
ba8ab355
JW
1802}")
1803
1804(define_insn ""
1805 [(set (match_operand:SI 0 "register_operand" "=d")
5d17176f
TG
1806 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
1807 (match_operand:SI 2 "logic_operand" "dIM")))]
4ec74aeb 1808 ""
5d17176f
TG
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}")
4ec74aeb
JW
1817
1818(define_insn ""
1819 [(set (match_operand:SI 0 "register_operand" "=d")
5d17176f
TG
1820 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%d"))
1821 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
ba8ab355
JW
1822 ""
1823 "*
1824{
5d17176f
TG
1825 if (i960_bypass (insn, operands[1], operands[2], 0))
1826 return \"nor %2,%1,%0\";
1827 return \"nor %1,%2,%0\";
ba8ab355
JW
1828}")
1829
5d17176f 1830(define_insn "xorsi3"
ba8ab355 1831 [(set (match_operand:SI 0 "register_operand" "=d")
5d17176f
TG
1832 (xor:SI (match_operand:SI 1 "register_operand" "%d")
1833 (match_operand:SI 2 "logic_operand" "dIM")))]
3c9b2130 1834 ""
5d17176f
TG
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}")
3c9b2130 1843
4ec74aeb
JW
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 ""
ba8ab355
JW
1849 "*
1850{
3a598fbe 1851 operands[2] = GEN_INT (bitpos (INTVAL (operands[2])));
4ec74aeb 1852 return \"notbit %2,%1,%0\";
ba8ab355
JW
1853}")
1854
4ec74aeb
JW
1855(define_insn ""
1856 [(set (match_operand:SI 0 "register_operand" "=d")
5d17176f
TG
1857 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%d")
1858 (match_operand:SI 2 "register_operand" "d"))))]
ba8ab355
JW
1859 ""
1860 "*
1861{
1862 if (i960_bypass (insn, operands[1], operands[2], 0))
5d17176f
TG
1863 return \"xnor %2,%1,%0\";
1864 return \"xnor %2,%1,%0\";
ba8ab355
JW
1865}")
1866
1867(define_insn ""
1868 [(set (match_operand:SI 0 "register_operand" "=d")
5d17176f
TG
1869 (ior:SI (ashift:SI (const_int 1)
1870 (match_operand:SI 1 "register_operand" "d"))
ba8ab355
JW
1871 (match_operand:SI 2 "arith_operand" "dI")))]
1872 ""
5d17176f 1873 "setbit %1,%2,%0")
ba8ab355 1874
5d17176f 1875;; (not (ashift 1 reg)) canonicalizes to (rotate -2 reg)
ba8ab355
JW
1876(define_insn ""
1877 [(set (match_operand:SI 0 "register_operand" "=d")
5d17176f
TG
1878 (and:SI (rotate:SI (const_int -2)
1879 (match_operand:SI 1 "register_operand" "d"))
1880 (match_operand:SI 2 "register_operand" "d")))]
ba8ab355 1881 ""
5d17176f 1882 "clrbit %1,%2,%0")
ba8ab355 1883
5d17176f
TG
1884;; The above pattern canonicalizes to this when both the input and output
1885;; are the same pseudo-register.
1886(define_insn ""
c243fc1b 1887 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5d17176f
TG
1888 (const_int 1)
1889 (match_operand:SI 1 "register_operand" "d"))
1890 (const_int 0))]
ba8ab355 1891 ""
5d17176f 1892 "clrbit %1,%0,%0")
ba8ab355
JW
1893
1894(define_insn ""
1895 [(set (match_operand:SI 0 "register_operand" "=d")
5d17176f
TG
1896 (xor:SI (ashift:SI (const_int 1)
1897 (match_operand:SI 1 "register_operand" "d"))
1898 (match_operand:SI 2 "arith_operand" "dI")))]
ba8ab355 1899 ""
5d17176f 1900 "notbit %1,%2,%0")
ba8ab355
JW
1901
1902(define_insn "negsi2"
1903 [(set (match_operand:SI 0 "register_operand" "=d")
1904 (neg:SI (match_operand:SI 1 "arith_operand" "dI")))]
1905 ""
1906 "subo %1,0,%0"
1907 [(set_attr "length" "1")])
1908
1909(define_insn "one_cmplsi2"
1910 [(set (match_operand:SI 0 "register_operand" "=d")
1911 (not:SI (match_operand:SI 1 "arith_operand" "dI")))]
1912 ""
1913 "not %1,%0"
1914 [(set_attr "length" "1")])
1915\f
1916;; Floating point arithmetic instructions.
1917
1918(define_insn "adddf3"
bc9c7a36 1919 [(set (match_operand:DF 0 "register_operand" "=d*f")
ba8ab355
JW
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"
bc9c7a36 1927 [(set (match_operand:SF 0 "register_operand" "=d*f")
ba8ab355
JW
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"
bc9c7a36 1936 [(set (match_operand:DF 0 "register_operand" "=d*f")
ba8ab355
JW
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"
bc9c7a36 1944 [(set (match_operand:SF 0 "register_operand" "=d*f")
ba8ab355
JW
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"
bc9c7a36 1953 [(set (match_operand:DF 0 "register_operand" "=d*f")
4ec74aeb 1954 (mult:DF (match_operand:DF 1 "fp_arith_operand" "%rGH")
ba8ab355
JW
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"
bc9c7a36 1961 [(set (match_operand:SF 0 "register_operand" "=d*f")
4ec74aeb 1962 (mult:SF (match_operand:SF 1 "fp_arith_operand" "%rGH")
ba8ab355
JW
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"
bc9c7a36 1970 [(set (match_operand:DF 0 "register_operand" "=d*f")
ba8ab355
JW
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"
bc9c7a36 1978 [(set (match_operand:SF 0 "register_operand" "=d*f")
ba8ab355
JW
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"
bc9c7a36 1986 [(set (match_operand:DF 0 "register_operand" "=d,d*f")
ba8ab355
JW
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"
bc9c7a36 2002 [(set (match_operand:SF 0 "register_operand" "=d,d*f")
ba8ab355
JW
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"
bc9c7a36 2015 [(set (match_operand:DF 0 "register_operand" "=d*f")
ba8ab355
JW
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"
bc9c7a36 2041 [(set (match_operand:SF 0 "register_operand" "=d*f")
ba8ab355
JW
2042 (abs:SF (match_operand:SF 1 "register_operand" "df")))]
2043 ""
2044 "*
2045{
2046 int dstreg = REGNO (operands[0]);
2047 int srcreg = REGNO (operands[1]);
2048
2049 if (dstreg < 32 && srcreg < 32)
2050 return \"clrbit 31,%1,%0\";
2051
2052 if (dstreg >= 32 && srcreg >= 32)
2053 return \"cpysre %1,0f0.0,%0\";
2054
2055 if (dstreg < 32)
2056 return \"movr %1,%0\;clrbit 31,%0,%0\";
2057
2058 return \"movr %1,%0\;cpysre %0,0f0.0,%0\";
2059}"
2060 [(set_attr "type" "multi")])
2061\f
2062;; Tetra (16 byte) float support.
2063
87cb2a87 2064(define_expand "cmptf"
ba8ab355 2065 [(set (reg:CC 36)
87cb2a87
RH
2066 (compare:CC (match_operand:TF 0 "register_operand" "")
2067 (match_operand:TF 1 "nonmemory_operand" "")))]
ba8ab355 2068 "TARGET_NUMERICS"
34a28d1c
TG
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)
87cb2a87
RH
2078 (compare:CC (match_operand:TF 0 "register_operand" "f")
2079 (match_operand:TF 1 "nonmemory_operand" "fGH")))]
34a28d1c
TG
2080 "TARGET_NUMERICS"
2081 "cmpr %0,%1"
ba8ab355
JW
2082 [(set_attr "type" "fpcc")])
2083
87cb2a87
RH
2084(define_expand "movtf"
2085 [(set (match_operand:TF 0 "general_operand" "")
2086 (match_operand:TF 1 "fpmove_src_operand" ""))]
ba8ab355
JW
2087 ""
2088 "
2089{
87cb2a87 2090 if (emit_move_sequence (operands, TFmode))
ba8ab355
JW
2091 DONE;
2092}")
2093
2094(define_insn ""
87cb2a87
RH
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)"
ba8ab355
JW
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:
34a28d1c 2113 return \"ldt %1,%0\";
ba8ab355 2114 case 4:
34a28d1c 2115 return \"stt %1,%0\";
1943c2c1
KG
2116 default:
2117 abort();
ba8ab355
JW
2118 }
2119}"
2120 [(set_attr "type" "move,move,load,fpload,fpstore")])
2121
87cb2a87
RH
2122(define_insn "extendsftf2"
2123 [(set (match_operand:TF 0 "register_operand" "=f,d")
2124 (float_extend:TF
ba8ab355
JW
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
87cb2a87
RH
2132(define_insn "extenddftf2"
2133 [(set (match_operand:TF 0 "register_operand" "=f,d")
2134 (float_extend:TF
ba8ab355
JW
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
87cb2a87 2142(define_insn "trunctfdf2"
ba8ab355
JW
2143 [(set (match_operand:DF 0 "register_operand" "=d")
2144 (float_truncate:DF
87cb2a87 2145 (match_operand:TF 1 "register_operand" "f")))]
ba8ab355
JW
2146 "TARGET_NUMERICS"
2147 "movrl %1,%0"
2148 [(set_attr "type" "fpmove")])
2149
87cb2a87 2150(define_insn "trunctfsf2"
ba8ab355
JW
2151 [(set (match_operand:SF 0 "register_operand" "=d")
2152 (float_truncate:SF
87cb2a87 2153 (match_operand:TF 1 "register_operand" "f")))]
ba8ab355
JW
2154 "TARGET_NUMERICS"
2155 "movr %1,%0"
2156 [(set_attr "type" "fpmove")])
2157
87cb2a87
RH
2158(define_insn "floatsitf2"
2159 [(set (match_operand:TF 0 "register_operand" "=f")
2160 (float:TF (match_operand:SI 1 "register_operand" "d")))]
ba8ab355
JW
2161 "TARGET_NUMERICS"
2162 "cvtir %1,%0"
2163 [(set_attr "type" "fpcvt")])
2164
87cb2a87 2165(define_insn "fix_trunctfsi2"
ba8ab355 2166 [(set (match_operand:SI 0 "register_operand" "=d")
87cb2a87 2167 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
ba8ab355
JW
2168 "TARGET_NUMERICS"
2169 "cvtzri %1,%0"
2170 [(set_attr "type" "fpcvt")])
2171
87cb2a87 2172(define_insn "fixuns_trunctfsi2"
ba8ab355 2173 [(set (match_operand:SI 0 "register_operand" "=d")
87cb2a87 2174 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
ba8ab355
JW
2175 "TARGET_NUMERICS"
2176 "cvtzri %1,%0"
2177 [(set_attr "type" "fpcvt")])
2178
87cb2a87
RH
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")))]
ba8ab355
JW
2183 "TARGET_NUMERICS"
2184 "addr %1,%2,%0"
2185 [(set_attr "type" "fpadd")])
2186
87cb2a87
RH
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")))]
ba8ab355
JW
2191 "TARGET_NUMERICS"
2192 "subr %2,%1,%0"
2193 [(set_attr "type" "fpadd")])
2194
87cb2a87
RH
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")))]
ba8ab355
JW
2199 "TARGET_NUMERICS"
2200 "mulr %1,%2,%0"
2201 [(set_attr "type" "fpmul")])
2202
87cb2a87
RH
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")))]
ba8ab355
JW
2207 "TARGET_NUMERICS"
2208 "divr %2,%1,%0"
2209 [(set_attr "type" "fpdiv")])
2210
87cb2a87
RH
2211(define_insn "negtf2"
2212 [(set (match_operand:TF 0 "register_operand" "=f")
2213 (neg:TF (match_operand:TF 1 "register_operand" "f")))]
ba8ab355
JW
2214 "TARGET_NUMERICS"
2215 "subr %1,0f0.0,%0"
2216 [(set_attr "type" "fpadd")])
2217
87cb2a87
RH
2218(define_insn "abstf2"
2219 [(set (match_operand:TF 0 "register_operand" "=f")
2220 (abs:TF (match_operand:TF 1 "register_operand" "f")))]
ba8ab355
JW
2221 "(TARGET_NUMERICS)"
2222 "cpysre %1,0f0.0,%0"
2223 [(set_attr "type" "fpmove")])
2224\f
2225;; Arithmetic shift instructions.
2226
2b7794ad
JW
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
ba8ab355
JW
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 ""
2b7794ad 2240 "shlo %2,%1,%0"
ba8ab355
JW
2241 [(set_attr "type" "alu2")])
2242
2243(define_insn "ashrsi3"
2244 [(set (match_operand:SI 0 "register_operand" "=d")
2245 (ashiftrt:SI (match_operand:SI 1 "arith_operand" "dI")
2246 (match_operand:SI 2 "arith_operand" "dI")))]
2247 ""
2248 "shri %2,%1,%0"
2249 [(set_attr "type" "alu2")])
2250
2251(define_insn "lshrsi3"
2252 [(set (match_operand:SI 0 "register_operand" "=d")
2253 (lshiftrt:SI (match_operand:SI 1 "arith_operand" "dI")
2254 (match_operand:SI 2 "arith_operand" "dI")))]
2255 ""
2256 "shro %2,%1,%0"
2257 [(set_attr "type" "alu2")])
2258\f
2259;; Unconditional and other jump instructions.
2260
2261(define_insn "jump"
2262 [(set (pc)
2263 (label_ref (match_operand 0 "" "")))]
2264 ""
2265 "b %l0"
2266 [(set_attr "type" "branch")])
2267
2268(define_insn "indirect_jump"
369f5d84 2269 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
ba8ab355 2270 ""
369f5d84 2271 "bx %a0"
ba8ab355
JW
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 ""
e5e809f4
JL
2278 "*
2279{
2280 if (flag_pic)
2281 return \"bx %l1(%0)\";
2282 else
2283 return \"bx (%0)\";
2284}"
ba8ab355
JW
2285 [(set_attr "type" "branch")])
2286
2287;;- jump to subroutine
2288
2289(define_expand "call"
3a6f7177 2290 [(call (match_operand:SI 0 "memory_operand" "m")
7c080174 2291 (match_operand:SI 1 "immediate_operand" "i"))]
ba8ab355
JW
2292 ""
2293 "
2294{
41552736
RH
2295 emit_call_insn (gen_call_internal (operands[0], operands[1],
2296 virtual_outgoing_args_rtx));
ba8ab355
JW
2297 DONE;
2298}")
2299
eff864ab
JW
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
b6744f97
JW
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
7c080174 2308(define_insn "call_internal"
3a6f7177 2309 [(call (match_operand:SI 0 "memory_operand" "m")
7c080174
JW
2310 (match_operand:SI 1 "immediate_operand" "i"))
2311 (use (match_operand:SI 2 "address_operand" "p"))
b6744f97 2312 (clobber (reg:SI 19))]
ba8ab355 2313 ""
7c080174 2314 "* return i960_output_call_insn (operands[0], operands[1], operands[2],
b6744f97 2315 insn);"
ba8ab355
JW
2316 [(set_attr "type" "call")])
2317
2318(define_expand "call_value"
2319 [(set (match_operand 0 "register_operand" "=d")
3a6f7177 2320 (call (match_operand:SI 1 "memory_operand" "m")
ba8ab355
JW
2321 (match_operand:SI 2 "immediate_operand" "i")))]
2322 ""
2323 "
2324{
41552736
RH
2325 emit_call_insn (gen_call_value_internal (operands[0], operands[1],
2326 operands[2],
2327 virtual_outgoing_args_rtx));
ba8ab355
JW
2328 DONE;
2329}")
2330
eff864ab
JW
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
7c080174 2334(define_insn "call_value_internal"
ba8ab355 2335 [(set (match_operand 0 "register_operand" "=d")
3a6f7177 2336 (call (match_operand:SI 1 "memory_operand" "m")
7c080174
JW
2337 (match_operand:SI 2 "immediate_operand" "i")))
2338 (use (match_operand:SI 3 "address_operand" "p"))
b6744f97 2339 (clobber (reg:SI 19))]
ba8ab355 2340 ""
7c080174 2341 "* return i960_output_call_insn (operands[1], operands[2], operands[3],
b6744f97 2342 insn);"
ba8ab355
JW
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
0bc02db4
MS
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"
d337d653 2355 [(set (pc) (unspec_volatile [(reg:SI 16)] 3))]
0bc02db4
MS
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{
a45f3331
JW
2369 rtx chain = operands[0];
2370 rtx handler = operands[1];
0bc02db4 2371 rtx stack = operands[2];
0bc02db4
MS
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
0bc02db4
MS
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
a45f3331
JW
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
0bc02db4 2393 /* Next, we put the address that we want to transfer to, into the
a45f3331 2394 saved $rip value in the frame. Once we ret below, that value
0bc02db4
MS
2395 will be loaded into the pc (IP). */
2396
2397 emit_move_insn (gen_rtx (MEM, SImode,
a45f3331 2398 plus_constant (hard_frame_pointer_rtx, -56)),
157229c3 2399 handler);
0bc02db4 2400
a45f3331
JW
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)),
157229c3 2404 stack);
0bc02db4
MS
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
d337d653 2413 emit_jump_insn (gen_ret ());
0bc02db4
MS
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
ba8ab355
JW
2426(define_insn "nop"
2427 [(const_int 0)]
2428 ""
2429 "")
2430\f
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\f
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\f
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)")