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