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