|
|
1.1 root 1: ;;- Machine description for DEC Alpha for GNU C compiler
2: ;; Copyright (C) 1992 Free Software Foundation, Inc.
3: ;; Contributed by Richard Kenner ([email protected])
4:
5: ;; This file is part of GNU CC.
6:
7: ;; GNU CC is free software; you can redistribute it and/or modify
8: ;; it under the terms of the GNU General Public License as published by
9: ;; the Free Software Foundation; either version 2, or (at your option)
10: ;; any later version.
11:
12: ;; GNU CC is distributed in the hope that it will be useful,
13: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: ;; GNU General Public License for more details.
16:
17: ;; You should have received a copy of the GNU General Public License
18: ;; along with GNU CC; see the file COPYING. If not, write to
19: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20:
21: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22:
23: ;; Define an insn type attribute. This is used in function unit delay
24: ;; computations, among other purposes. For the most part, we use the names
25: ;; defined in the EV4 documentation, but add a few that we have to know about
26: ;; separately.
27:
28: (define_attr "type"
29: "ld,st,ibr,fbr,jsr,iaddlog,shiftcm,icmp,imull,imulq,fpop,fdivs,fdivt,ldsym,isubr"
30: (const_string "shiftcm"))
31:
32: ;; We include four function units: ABOX, which computes the address,
33: ;; BBOX, used for branches, EBOX, used for integer operations, and FBOX,
34: ;; used for FP operations.
35: ;;
36: ;; We assume that we have been successful in getting double issues and
37: ;; hence multiply all costs by two insns per cycle. The minimum time in
38: ;; a function unit is 2 cycle, which will tend to produce the double
39: ;; issues.
40:
41: ;; Memory delivers its result in three cycles.
42: (define_function_unit "abox" 1 0 (eq_attr "type" "ld,ldsym,st") 6 2)
43:
44: ;; Branches have no delay cost, but do tie up the unit for two cycles.
45: (define_function_unit "bbox" 1 1 (eq_attr "type" "ibr,fbr,jsr") 4 4)
46:
47: ;; Arithmetic insns are normally have their results available after two
48: ;; cycles. There are a number of exceptions. They are encoded in
49: ;; ADJUST_COST. Some of the other insns have similar exceptions.
50:
51: (define_function_unit "ebox" 1 0 (eq_attr "type" "iaddlog,shiftcm,icmp") 4 2)
52:
53: ;; These really don't take up the integer pipeline, but they do occupy
54: ;; IBOX1; we approximate here.
55:
56: (define_function_unit "ebox" 1 0 (eq_attr "type" "imull") 42 2)
57: (define_function_unit "ebox" 1 0 (eq_attr "type" "imulq") 46 2)
58:
59: (define_function_unit "imult" 1 0 (eq_attr "type" "imull") 42 38)
60: (define_function_unit "imult" 1 0 (eq_attr "type" "imulq") 46 42)
61:
62: (define_function_unit "fbox" 1 0 (eq_attr "type" "fpop") 12 2)
63:
64: (define_function_unit "fbox" 1 0 (eq_attr "type" "fdivs") 68 0)
65: (define_function_unit "fbox" 1 0 (eq_attr "type" "fdivt") 126 0)
66:
67: (define_function_unit "divider" 1 0 (eq_attr "type" "fdivs") 68 60)
68: (define_function_unit "divider" 1 0 (eq_attr "type" "fdivt") 126 118)
69:
70: ;; First define the arithmetic insns. Note that the 32-bit forms also
71: ;; sign-extend.
72:
73: ;; Note that we can do sign extensions in both FP and integer registers.
74: ;; However, the result must be in the same type of register as the input.
75: ;; The register preferencing code can't handle this case very well, so, for
76: ;; now, don't let the FP case show up here for preferencing. Also,
77: ;; sign-extends in FP registers take two instructions.
78: (define_insn "extendsidi2"
79: [(set (match_operand:DI 0 "register_operand" "=r,r,*f")
80: (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,*f")))]
81: ""
82: "@
83: addl %1,$31,%0
84: ldl %0,%1
85: cvtql %1,%0\;cvtlq %0,%0"
86: [(set_attr "type" "iaddlog,ld,fpop")])
87:
88: (define_insn "addsi3"
89: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
90: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
91: (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
92: ""
93: "@
94: addl %r1,%2,%0
95: subl %r1,%n2,%0
96: lda %0,%2(%r1)
97: ldah %0,%h2(%r1)"
98: [(set_attr "type" "iaddlog")])
99:
100: (define_split
101: [(set (match_operand:SI 0 "register_operand" "")
102: (plus:SI (match_operand:SI 1 "register_operand" "")
103: (match_operand:SI 2 "const_int_operand" "")))]
104: "! add_operand (operands[2], SImode)"
105: [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
106: (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
107: "
108: {
109: HOST_WIDE_INT val = INTVAL (operands[2]);
110: HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
111: HOST_WIDE_INT rest = val - low;
112:
113: operands[3] = GEN_INT (rest);
114: operands[4] = GEN_INT (low);
115: }")
116:
117: (define_insn ""
118: [(set (match_operand:DI 0 "register_operand" "=r,r")
119: (sign_extend:DI
120: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
121: (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
122: ""
123: "@
124: addl %r1,%2,%0
125: subl %r1,%n2,%0"
126: [(set_attr "type" "iaddlog")])
127:
128: (define_split
129: [(set (match_operand:DI 0 "register_operand" "")
130: (sign_extend:DI
131: (plus:SI (match_operand:SI 1 "register_operand" "")
132: (match_operand:SI 2 "const_int_operand" ""))))
133: (clobber (match_operand:SI 3 "register_operand" ""))]
134: "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
135: && INTVAL (operands[2]) % 4 == 0"
136: [(set (match_dup 3) (match_dup 4))
137: (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
138: (match_dup 5))
139: (match_dup 1))))]
140: "
141: {
142: HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
143: int mult = 4;
144:
145: if (val % 2 == 0)
146: val /= 2, mult = 8;
147:
148: operands[4] = GEN_INT (val);
149: operands[5] = GEN_INT (mult);
150: }")
151:
152: (define_insn "adddi3"
153: [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
154: (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
155: (match_operand:DI 2 "add_operand" "rI,O,K,L")))]
156: ""
157: "@
158: addq %r1,%2,%0
159: subq %r1,%n2,%0
160: lda %0,%2(%r1)
161: ldah %0,%h2(%r1)"
162: [(set_attr "type" "iaddlog")])
163:
164: ;; Don't do this if we are adjusting SP since we don't want to do
165: ;; it in two steps.
166: (define_split
167: [(set (match_operand:DI 0 "register_operand" "")
168: (plus:DI (match_operand:DI 1 "register_operand" "")
169: (match_operand:DI 2 "const_int_operand" "")))]
170: "! add_operand (operands[2], DImode)
171: && REGNO (operands[0]) != STACK_POINTER_REGNUM"
172: [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
173: (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
174: "
175: {
176: HOST_WIDE_INT val = INTVAL (operands[2]);
177: HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
178: HOST_WIDE_INT rest = val - low;
179:
180: operands[3] = GEN_INT (rest);
181: operands[4] = GEN_INT (low);
182: }")
183:
184: (define_insn ""
185: [(set (match_operand:SI 0 "register_operand" "=r,r")
186: (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
187: (match_operand:SI 2 "const48_operand" "I,I"))
188: (match_operand:SI 3 "sext_add_operand" "rI,O")))]
189: ""
190: "@
191: s%2addl %r1,%3,%0
192: s%2subl %r1,%n3,%0"
193: [(set_attr "type" "iaddlog")])
194:
195: (define_insn ""
196: [(set (match_operand:DI 0 "register_operand" "=r,r")
197: (sign_extend:DI
198: (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
199: (match_operand:SI 2 "const48_operand" "I,I"))
200: (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
201: ""
202: "@
203: s%2addl %r1,%3,%0
204: s%2subl %r1,%n3,%0"
205: [(set_attr "type" "iaddlog")])
206:
207: (define_insn ""
208: [(set (match_operand:DI 0 "register_operand" "=r,r")
209: (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
210: (match_operand:DI 2 "const48_operand" "I,I"))
211: (match_operand:DI 3 "reg_or_8bit_operand" "rI,O")))]
212: ""
213: "@
214: s%2addq %r1,%3,%0
215: s%2subq %1,%n3,%0"
216: [(set_attr "type" "iaddlog")])
217:
218: ;; These variants of the above insns can occur if the third operand
219: ;; is the frame pointer. This is a kludge, but there doesn't
220: ;; seem to be a way around it. Only recognize them while reloading.
221:
222: (define_insn ""
223: [(set (match_operand:SI 0 "register_operand" "=&r")
224: (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
225: (match_operand:SI 2 "const48_operand" "I"))
226: (match_operand:SI 3 "register_operand" "r"))
227: (match_operand:SI 4 "const_int_operand" "rI")))]
228: "reload_in_progress"
229: "s%2addl %r1,%3,%0\;addl %0,%4,%0"
230: [(set_attr "type" "iaddlog")])
231:
232: (define_insn ""
233: [(set (match_operand:DI 0 "register_operand" "=&r")
234: (sign_extend:DI
235: (plus:SI (plus:SI
236: (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
237: (match_operand:SI 2 "const48_operand" "I"))
238: (match_operand:SI 3 "register_operand" "r"))
239: (match_operand:SI 4 "const_int_operand" "rI"))))]
240: "reload_in_progress"
241: "s%2addl %r1,%3,%0\;addl %0,%4,%0"
242: [(set_attr "type" "iaddlog")])
243:
244: (define_insn ""
245: [(set (match_operand:DI 0 "register_operand" "=&r")
246: (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
247: (match_operand:DI 2 "const48_operand" "I"))
248: (match_operand:DI 3 "register_operand" "r"))
249: (match_operand:DI 4 "const_int_operand" "rI")))]
250: "reload_in_progress"
251: "s%2addq %r1,%3,%0\;addq %0,%4,%0"
252: [(set_attr "type" "iaddlog")])
253:
254: (define_insn "negsi2"
255: [(set (match_operand:SI 0 "register_operand" "=r")
256: (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
257: ""
258: "subl $31,%1,%0"
259: [(set_attr "type" "iaddlog")])
260:
261: (define_insn ""
262: [(set (match_operand:DI 0 "register_operand" "=r")
263: (sign_extend:DI (neg:SI
264: (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
265: ""
266: "subl $31,%1,%0"
267: [(set_attr "type" "iaddlog")])
268:
269: (define_insn "negdi2"
270: [(set (match_operand:DI 0 "register_operand" "=r")
271: (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
272: ""
273: "subq $31,%1,%0"
274: [(set_attr "type" "iaddlog")])
275:
276: (define_insn "subsi3"
277: [(set (match_operand:SI 0 "register_operand" "=r")
278: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
279: (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
280: ""
281: "subl %r1,%2,%0"
282: [(set_attr "type" "iaddlog")])
283:
284: (define_insn ""
285: [(set (match_operand:DI 0 "register_operand" "=r")
286: (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
287: (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
288: ""
289: "subl %r1,%2,%0"
290: [(set_attr "type" "iaddlog")])
291:
292: (define_insn "subdi3"
293: [(set (match_operand:DI 0 "register_operand" "=r")
294: (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
295: (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
296: ""
297: "subq %r1,%2,%0"
298: [(set_attr "type" "iaddlog")])
299:
300: (define_insn ""
301: [(set (match_operand:SI 0 "register_operand" "=r")
302: (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
303: (match_operand:SI 2 "const48_operand" "I"))
304: (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
305: ""
306: "s%2subl %r1,%3,%0"
307: [(set_attr "type" "iaddlog")])
308:
309: (define_insn ""
310: [(set (match_operand:DI 0 "register_operand" "=r")
311: (sign_extend:DI
312: (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
313: (match_operand:SI 2 "const48_operand" "I"))
314: (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
315: ""
316: "s%2subl %r1,%3,%0"
317: [(set_attr "type" "iaddlog")])
318:
319: (define_insn ""
320: [(set (match_operand:DI 0 "register_operand" "=r")
321: (minus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
322: (match_operand:DI 2 "const48_operand" "I"))
323: (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
324: ""
325: "s%2subq %r1,%3,%0"
326: [(set_attr "type" "iaddlog")])
327:
328: (define_insn "mulsi3"
329: [(set (match_operand:SI 0 "register_operand" "=r")
330: (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
331: (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
332: ""
333: "mull %r1,%2,%0"
334: [(set_attr "type" "imull")])
335:
336: (define_insn ""
337: [(set (match_operand:DI 0 "register_operand" "=r")
338: (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
339: (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
340: ""
341: "mull %r1,%2,%0"
342: [(set_attr "type" "imull")])
343:
344: (define_insn "muldi3"
345: [(set (match_operand:DI 0 "register_operand" "=r")
346: (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
347: (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
348: ""
349: "mulq %r1,%2,%0"
350: [(set_attr "type" "imulq")])
351:
352: ;; The divide and remainder operations always take their inputs from
353: ;; r24 and r25, put their output in r27, and clobber r23 and r28.
354:
355: (define_expand "divsi3"
356: [(parallel [(set (reg:SI 27)
357: (div:SI (match_operand:SI 1 "general_operand" "")
358: (match_operand:SI 2 "general_operand" "")))
359: (clobber (reg:DI 23))
360: (clobber (reg:DI 28))])
361: (set (match_operand:SI 0 "general_operand" "")
362: (reg:SI 27))]
363: ""
364: "
365: { rtx in0 = gen_rtx (REG, SImode, 24);
366: rtx in1 = gen_rtx (REG, SImode, 25);
367:
368: emit_move_insn (in0, operands[1]);
369: emit_move_insn (in1, operands[2]);
370: operands[1] = in0, operands[2] = in1;
371: }")
372:
373: (define_expand "udivsi3"
374: [(parallel [(set (reg:SI 27)
375: (udiv:SI (match_operand:SI 1 "general_operand" "")
376: (match_operand:SI 2 "general_operand" "")))
377: (clobber (reg:DI 23))
378: (clobber (reg:DI 28))])
379: (set (match_operand:SI 0 "general_operand" "")
380: (reg:SI 27))]
381: ""
382: "
383: { rtx in0 = gen_rtx (REG, SImode, 24);
384: rtx in1 = gen_rtx (REG, SImode, 25);
385:
386: emit_move_insn (in0, operands[1]);
387: emit_move_insn (in1, operands[2]);
388: operands[1] = in0, operands[2] = in1;
389: }")
390:
391: (define_expand "modsi3"
392: [(parallel [(set (reg:SI 27)
393: (mod:SI (match_operand:SI 1 "general_operand" "")
394: (match_operand:SI 2 "general_operand" "")))
395: (clobber (reg:DI 23))
396: (clobber (reg:DI 28))])
397: (set (match_operand:SI 0 "general_operand" "")
398: (reg:SI 27))]
399: ""
400: "
401: { rtx in0 = gen_rtx (REG, SImode, 24);
402: rtx in1 = gen_rtx (REG, SImode, 25);
403:
404: emit_move_insn (in0, operands[1]);
405: emit_move_insn (in1, operands[2]);
406: operands[1] = in0, operands[2] = in1;
407: }")
408:
409: (define_expand "umodsi3"
410: [(parallel [(set (reg:SI 27)
411: (umod:SI (match_operand:SI 1 "general_operand" "")
412: (match_operand:SI 2 "general_operand" "")))
413: (clobber (reg:DI 23))
414: (clobber (reg:DI 28))])
415: (set (match_operand:SI 0 "general_operand" "")
416: (reg:SI 27))]
417: ""
418: "
419: { rtx in0 = gen_rtx (REG, SImode, 24);
420: rtx in1 = gen_rtx (REG, SImode, 25);
421:
422: emit_move_insn (in0, operands[1]);
423: emit_move_insn (in1, operands[2]);
424: operands[1] = in0, operands[2] = in1;
425: }")
426:
427: (define_expand "divdi3"
428: [(parallel [(set (reg:DI 27)
429: (div:DI (match_operand:DI 1 "general_operand" "")
430: (match_operand:DI 2 "general_operand" "")))
431: (clobber (reg:DI 23))
432: (clobber (reg:DI 28))])
433: (set (match_operand:DI 0 "general_operand" "")
434: (reg:DI 27))]
435: ""
436: "
437: { rtx in0 = gen_rtx (REG, DImode, 24);
438: rtx in1 = gen_rtx (REG, DImode, 25);
439:
440: emit_move_insn (in0, operands[1]);
441: emit_move_insn (in1, operands[2]);
442: operands[1] = in0, operands[2] = in1;
443: }")
444:
445: (define_expand "udivdi3"
446: [(parallel [(set (reg:DI 27)
447: (udiv:DI (match_operand:DI 1 "general_operand" "")
448: (match_operand:DI 2 "general_operand" "")))
449: (clobber (reg:DI 23))
450: (clobber (reg:DI 28))])
451: (set (match_operand:DI 0 "general_operand" "")
452: (reg:DI 27))]
453: ""
454: "
455: { rtx in0 = gen_rtx (REG, DImode, 24);
456: rtx in1 = gen_rtx (REG, DImode, 25);
457:
458: emit_move_insn (in0, operands[1]);
459: emit_move_insn (in1, operands[2]);
460: operands[1] = in0, operands[2] = in1;
461: }")
462:
463: (define_expand "moddi3"
464: [(parallel [(set (reg:DI 27)
465: (mod:DI (match_operand:DI 1 "general_operand" "")
466: (match_operand:DI 2 "general_operand" "")))
467: (clobber (reg:DI 23))
468: (clobber (reg:DI 28))])
469: (set (match_operand:DI 0 "general_operand" "")
470: (reg:DI 27))]
471: ""
472: "
473: { rtx in0 = gen_rtx (REG, DImode, 24);
474: rtx in1 = gen_rtx (REG, DImode, 25);
475:
476: emit_move_insn (in0, operands[1]);
477: emit_move_insn (in1, operands[2]);
478: operands[1] = in0, operands[2] = in1;
479: }")
480:
481: (define_expand "umoddi3"
482: [(parallel [(set (reg:DI 27)
483: (umod:DI (match_operand:DI 1 "general_operand" "")
484: (match_operand:DI 2 "general_operand" "")))
485: (clobber (reg:DI 23))
486: (clobber (reg:DI 28))])
487: (set (match_operand:DI 0 "general_operand" "")
488: (reg:DI 27))]
489: ""
490: "
491: { rtx in0 = gen_rtx (REG, DImode, 24);
492: rtx in1 = gen_rtx (REG, DImode, 25);
493:
494: emit_move_insn (in0, operands[1]);
495: emit_move_insn (in1, operands[2]);
496: operands[1] = in0, operands[2] = in1;
497: }")
498:
499: (define_insn ""
500: [(set (reg:SI 27)
501: (match_operator:SI 1 "divmod_operator"
502: [(reg:SI 24) (reg:SI 25)]))
503: (clobber (reg:DI 23))
504: (clobber (reg:DI 28))]
505: ""
506: "%E1 $24,$25,$27"
507: [(set_attr "type" "isubr")])
508:
509: (define_insn ""
510: [(set (reg:DI 27)
511: (match_operator:DI 1 "divmod_operator"
512: [(reg:DI 24) (reg:DI 25)]))
513: (clobber (reg:DI 23))
514: (clobber (reg:DI 28))]
515: ""
516: "%E1 $24,$25,$27"
517: [(set_attr "type" "isubr")])
518:
519: ;; Next are the basic logical operations. These only exist in DImode.
520:
521: (define_insn "anddi3"
522: [(set (match_operand:DI 0 "register_operand" "=r,r,r")
523: (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
524: (match_operand:DI 2 "and_operand" "rI,N,MH")))]
525: ""
526: "@
527: and %r1,%2,%0
528: bic %r1,%N2,%0
529: zapnot %r1,%m2,%0"
530: [(set_attr "type" "iaddlog,iaddlog,shiftcm")])
531:
532: ;; There are times when we can split and AND into two AND insns. This occurs
533: ;; when we can first clear any bytes and then clear anything else. For
534: ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
535: ;; Only to this when running on 64-bit host since the computations are
536: ;; too messy otherwise.
537:
538: (define_split
539: [(set (match_operand:DI 0 "register_operand" "")
540: (and:DI (match_operand:DI 1 "register_operand" "")
541: (match_operand:DI 2 "const_int_operand" "")))]
542: "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
543: [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
544: (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
545: "
546: {
547: unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
548: unsigned HOST_WIDE_INT mask2 = mask1;
549: int i;
550:
551: /* For each byte that isn't all zeros, make it all ones. */
552: for (i = 0; i < 64; i += 8)
553: if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
554: mask1 |= (HOST_WIDE_INT) 0xff << i;
555:
556: /* Now turn on any bits we've just turned off. */
557: mask2 |= ~ mask1;
558:
559: operands[3] = GEN_INT (mask1);
560: operands[4] = GEN_INT (mask2);
561: }")
562:
563: (define_insn "zero_extendqihi2"
564: [(set (match_operand:HI 0 "register_operand" "=r")
565: (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
566: ""
567: "zapnot %1,1,%0"
568: [(set_attr "type" "iaddlog")])
569:
570: (define_insn "zero_extendqisi2"
571: [(set (match_operand:SI 0 "register_operand" "=r")
572: (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
573: ""
574: "zapnot %1,1,%0"
575: [(set_attr "type" "iaddlog")])
576:
577: (define_insn "zero_extendqidi2"
578: [(set (match_operand:DI 0 "register_operand" "=r")
579: (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
580: ""
581: "zapnot %1,1,%0"
582: [(set_attr "type" "iaddlog")])
583:
584: (define_insn "zero_extendhisi2"
585: [(set (match_operand:SI 0 "register_operand" "=r")
586: (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
587: ""
588: "zapnot %1,3,%0"
589: [(set_attr "type" "iaddlog")])
590:
591: (define_insn "zero_extendhidi2"
592: [(set (match_operand:DI 0 "register_operand" "=r")
593: (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
594: ""
595: "zapnot %1,3,%0"
596: [(set_attr "type" "iaddlog")])
597:
598: (define_insn "zero_extendsidi2"
599: [(set (match_operand:DI 0 "register_operand" "=r")
600: (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
601: ""
602: "zapnot %1,15,%0"
603: [(set_attr "type" "iaddlog")])
604:
605: (define_insn ""
606: [(set (match_operand:DI 0 "register_operand" "=r")
607: (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
608: (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
609: ""
610: "bic %r2,%1,%0"
611: [(set_attr "type" "iaddlog")])
612:
613: (define_insn "iordi3"
614: [(set (match_operand:DI 0 "register_operand" "=r")
615: (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
616: (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
617: ""
618: "bis %r1,%2,%0"
619: [(set_attr "type" "iaddlog")])
620:
621: (define_insn "one_cmpldi2"
622: [(set (match_operand:DI 0 "register_operand" "=r")
623: (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
624: ""
625: "ornot $31,%1,%0"
626: [(set_attr "type" "iaddlog")])
627:
628: (define_insn ""
629: [(set (match_operand:DI 0 "register_operand" "=r")
630: (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
631: (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
632: ""
633: "ornot %r2,%1,%0"
634: [(set_attr "type" "iaddlog")])
635:
636: (define_insn "xordi3"
637: [(set (match_operand:DI 0 "register_operand" "=r")
638: (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
639: (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
640: ""
641: "xor %r1,%2,%0"
642: [(set_attr "type" "iaddlog")])
643:
644: (define_insn ""
645: [(set (match_operand:DI 0 "register_operand" "=r")
646: (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
647: (match_operand:DI 2 "reg_or_8bit_operand" "rI"))))]
648: ""
649: "eqv %r1,%2,%0"
650: [(set_attr "type" "iaddlog")])
651:
652: ;; Next come the shifts and the various extract and insert operations.
653:
654: (define_insn "ashldi3"
655: [(set (match_operand:DI 0 "register_operand" "=r,r")
656: (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
657: (match_operand:DI 2 "reg_or_6bit_operand" "P,rI")))]
658: ""
659: "*
660: {
661: switch (which_alternative)
662: {
663: case 0:
664: if (operands[2] == const1_rtx)
665: return \"addq %r1,%r1,%0\";
666: else
667: return \"s%P2addq %r1,0,%0\";
668: case 1:
669: return \"sll %r1,%2,%0\";
670: }
671: }"
672: [(set_attr "type" "iaddlog,shiftcm")])
673:
674: ;; This is the same as (sign_extend (shift X [123])).
675: (define_insn ""
676: [(set (match_operand:DI 0 "register_operand" "=r")
677: (ashiftrt:DI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
678: (match_operand:DI 2 "const_int_operand" "i"))
679: (const_int 32)))]
680: "INTVAL (operands[2]) >= 33 && INTVAL (operands[2]) <= 35"
681: "*
682: {
683: switch (INTVAL (operands[2]))
684: {
685: case 33:
686: return \"addl %r1,%r1,%0\";
687: case 34:
688: return \"s4addl %r1,0,%0\";
689: case 35:
690: return \"s8addl %r1,0,%0\";
691: default:
692: abort ();
693: }
694: }"
695: [(set_attr "type" "iaddlog")])
696:
697: (define_insn "lshrdi3"
698: [(set (match_operand:DI 0 "register_operand" "=r")
699: (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
700: (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
701: ""
702: "srl %r1,%2,%0")
703:
704: (define_insn "ashrdi3"
705: [(set (match_operand:DI 0 "register_operand" "=r")
706: (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
707: (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
708: ""
709: "sra %r1,%2,%0")
710:
711: (define_expand "extendqihi2"
712: [(set (match_dup 2)
713: (ashift:DI (match_operand:QI 1 "register_operand" "")
714: (const_int 56)))
715: (set (match_operand:HI 0 "register_operand" "")
716: (ashiftrt:DI (match_dup 2)
717: (const_int 56)))]
718: ""
719: "
720: { operands[0] = gen_lowpart (DImode, operands[0]);
721: operands[1] = gen_lowpart (DImode, operands[1]);
722: operands[2] = gen_reg_rtx (DImode);
723: }")
724:
725: (define_expand "extendqisi2"
726: [(set (match_dup 2)
727: (ashift:DI (match_operand:QI 1 "register_operand" "")
728: (const_int 56)))
729: (set (match_operand:SI 0 "register_operand" "")
730: (ashiftrt:DI (match_dup 2)
731: (const_int 56)))]
732: ""
733: "
734: { operands[0] = gen_lowpart (DImode, operands[0]);
735: operands[1] = gen_lowpart (DImode, operands[1]);
736: operands[2] = gen_reg_rtx (DImode);
737: }")
738:
739: (define_expand "extendqidi2"
740: [(set (match_dup 2)
741: (ashift:DI (match_operand:QI 1 "register_operand" "")
742: (const_int 56)))
743: (set (match_operand:DI 0 "register_operand" "")
744: (ashiftrt:DI (match_dup 2)
745: (const_int 56)))]
746: ""
747: "
748: { operands[1] = gen_lowpart (DImode, operands[1]);
749: operands[2] = gen_reg_rtx (DImode);
750: }")
751:
752: (define_expand "extendhisi2"
753: [(set (match_dup 2)
754: (ashift:DI (match_operand:HI 1 "register_operand" "")
755: (const_int 48)))
756: (set (match_operand:SI 0 "register_operand" "")
757: (ashiftrt:DI (match_dup 2)
758: (const_int 48)))]
759: ""
760: "
761: { operands[0] = gen_lowpart (DImode, operands[0]);
762: operands[1] = gen_lowpart (DImode, operands[1]);
763: operands[2] = gen_reg_rtx (DImode);
764: }")
765:
766: (define_expand "extendhidi2"
767: [(set (match_dup 2)
768: (ashift:DI (match_operand:HI 1 "register_operand" "")
769: (const_int 48)))
770: (set (match_operand:DI 0 "register_operand" "")
771: (ashiftrt:DI (match_dup 2)
772: (const_int 48)))]
773: ""
774: "
775: { operands[1] = gen_lowpart (DImode, operands[1]);
776: operands[2] = gen_reg_rtx (DImode);
777: }")
778:
779: (define_insn ""
780: [(set (match_operand:DI 0 "register_operand" "=r")
781: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
782: (match_operand:DI 2 "mode_width_operand" "n")
783: (match_operand:DI 3 "mul8_operand" "I")))]
784: ""
785: "ext%M2l %r1,%s3,%0")
786:
787: (define_insn ""
788: [(set (match_operand:DI 0 "register_operand" "=r")
789: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
790: (match_operand:DI 2 "mode_width_operand" "n")
791: (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
792: (const_int 3))))]
793: ""
794: "ext%M2l %r1,%3,%0")
795:
796: (define_insn ""
797: [(set (match_operand:DI 0 "register_operand" "=r")
798: (ashift:DI
799: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
800: (const_int 8)
801: (ashift:DI
802: (plus:DI
803: (match_operand:DI 2 "reg_or_8bit_operand" "rI")
804: (const_int -1))
805: (const_int 3)))
806: (const_int 56)))]
807: ""
808: "extqh %r1,%2,%0")
809:
810: (define_insn ""
811: [(set (match_operand:DI 0 "register_operand" "=r")
812: (ashift:DI
813: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
814: (const_int 16)
815: (ashift:DI
816: (plus:DI
817: (match_operand:DI 2 "reg_or_8bit_operand" "rI")
818: (const_int -2))
819: (const_int 3)))
820: (const_int 48)))]
821: ""
822: "extwh %r1,%2,%0")
823:
824: (define_insn ""
825: [(set (match_operand:DI 0 "register_operand" "=r")
826: (ashift:DI
827: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
828: (const_int 32)
829: (ashift:DI
830: (plus:DI
831: (match_operand:DI 2 "reg_or_8bit_operand" "rI")
832: (const_int -4))
833: (const_int 3)))
834: (const_int 32)))]
835: ""
836: "extlh %r1,%2,%0")
837:
838: ;; This converts an extXl into an extXh with an appropriate adjustment
839: ;; to the address calculation.
840:
841: (define_split
842: [(set (match_operand:DI 0 "register_operand" "")
843: (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
844: (match_operand:DI 2 "mode_width_operand" "")
845: (ashift:DI (match_operand:DI 3 "" "")
846: (const_int 3)))
847: (match_operand:DI 4 "const_int_operand" "")))
848: (clobber (match_operand:DI 5 "register_operand" ""))]
849: "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
850: [(set (match_dup 5) (match_dup 6))
851: (set (match_dup 0)
852: (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
853: (ashift:DI (plus:DI (match_dup 5)
854: (match_dup 7))
855: (const_int 3)))
856: (match_dup 4)))]
857: "
858: {
859: operands[6] = plus_constant (operands[3],
860: INTVAL (operands[2]) / BITS_PER_UNIT);
861: operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
862: }")
863:
864: (define_insn ""
865: [(set (match_operand:DI 0 "register_operand" "=r")
866: (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
867: (match_operand:DI 2 "mul8_operand" "I")))]
868: ""
869: "insbl %1,%s2,%0")
870:
871: (define_insn ""
872: [(set (match_operand:DI 0 "register_operand" "=r")
873: (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
874: (match_operand:DI 2 "mul8_operand" "I")))]
875: ""
876: "inswl %1,%s2,%0")
877:
878: (define_insn ""
879: [(set (match_operand:DI 0 "register_operand" "=r")
880: (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
881: (match_operand:DI 2 "mul8_operand" "I")))]
882: ""
883: "insll %1,%s2,%0")
884:
885: (define_insn ""
886: [(set (match_operand:DI 0 "register_operand" "=r")
887: (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
888: (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
889: (const_int 3))))]
890: ""
891: "insbl %1,%2,%0")
892:
893: (define_insn ""
894: [(set (match_operand:DI 0 "register_operand" "=r")
895: (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
896: (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
897: (const_int 3))))]
898: ""
899: "inswl %1,%2,%0")
900:
901: (define_insn ""
902: [(set (match_operand:DI 0 "register_operand" "=r")
903: (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
904: (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
905: (const_int 3))))]
906: ""
907: "insll %1,%2,%0")
908:
909: ;; We do not include the insXh insns because they are complex to express
910: ;; and it does not appear that we would ever want to generate them.
911:
912: (define_insn ""
913: [(set (match_operand:DI 0 "register_operand" "=r")
914: (and:DI (ashift:DI
915: (match_operand:DI 2 "mode_mask_operand" "n")
916: (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
917: (const_int 3)))
918: (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
919: ""
920: "msk%U2l %r1,%3,%0")
921:
922: ;; We do not include the mskXh insns because it does not appear we would ever
923: ;; generate one.
924:
925: ;; Floating-point operations. All the double-precision insns can extend
926: ;; from single, so indicate that. The exception are the ones that simply
927: ;; play with the sign bits; it's not clear what to do there.
928:
929: (define_insn "abssf2"
930: [(set (match_operand:SF 0 "register_operand" "=f")
931: (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
932: "TARGET_FP"
933: "cpys $f31,%R1,%0"
934: [(set_attr "type" "fpop")])
935:
936: (define_insn "absdf2"
937: [(set (match_operand:DF 0 "register_operand" "=f")
938: (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
939: "TARGET_FP"
940: "cpys $f31,%R1,%0"
941: [(set_attr "type" "fpop")])
942:
943: (define_insn "negsf2"
944: [(set (match_operand:SF 0 "register_operand" "=f")
945: (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
946: "TARGET_FP"
947: "cpysn %1,%R1,%0"
948: [(set_attr "type" "fpop")])
949:
950: (define_insn "negdf2"
951: [(set (match_operand:DF 0 "register_operand" "=f")
952: (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
953: "TARGET_FP"
954: "cpysn %1,%R1,%0"
955: [(set_attr "type" "fpop")])
956:
957: (define_insn "addsf3"
958: [(set (match_operand:SF 0 "register_operand" "=f")
959: (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
960: (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
961: "TARGET_FP"
962: "adds %R1,%R2,%0"
963: [(set_attr "type" "fpop")])
964:
965: (define_insn "adddf3"
966: [(set (match_operand:DF 0 "register_operand" "=f")
967: (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
968: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
969: "TARGET_FP"
970: "addt %R1,%R2,%0"
971: [(set_attr "type" "fpop")])
972:
973: (define_insn ""
974: [(set (match_operand:DF 0 "register_operand" "=f")
975: (plus:DF (float_extend:DF
976: (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
977: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
978: "TARGET_FP"
979: "addt %R1,%R2,%0"
980: [(set_attr "type" "fpop")])
981:
982: (define_insn ""
983: [(set (match_operand:DF 0 "register_operand" "=f")
984: (plus:DF (float_extend:DF
985: (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
986: (float_extend:DF
987: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
988: "TARGET_FP"
989: "addt %R1,%R2,%0"
990: [(set_attr "type" "fpop")])
991:
992: (define_insn "fix_truncdfdi2"
993: [(set (match_operand:DI 0 "register_operand" "=f")
994: (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
995: "TARGET_FP"
996: "cvttqc %R1,%0"
997: [(set_attr "type" "fpop")])
998:
999: (define_insn "fix_truncsfdi2"
1000: [(set (match_operand:DI 0 "register_operand" "=f")
1001: (fix:DI (float_extend:DF
1002: (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1003: "TARGET_FP"
1004: "cvttqc %R1,%0"
1005: [(set_attr "type" "fpop")])
1006:
1007: (define_insn "floatdisf2"
1008: [(set (match_operand:SF 0 "register_operand" "=f")
1009: (float:SF (match_operand:DI 1 "register_operand" "f")))]
1010: "TARGET_FP"
1011: "cvtqs %1,%0"
1012: [(set_attr "type" "fpop")])
1013:
1014: (define_insn "floatdidf2"
1015: [(set (match_operand:DF 0 "register_operand" "=f")
1016: (float:DF (match_operand:DI 1 "register_operand" "f")))]
1017: "TARGET_FP"
1018: "cvtqt %1,%0"
1019: [(set_attr "type" "fpop")])
1020:
1021: (define_insn "extendsfdf2"
1022: [(set (match_operand:DF 0 "register_operand" "=f,f")
1023: (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))]
1024: "TARGET_FP"
1025: "@
1026: addt $f31,%1,%0
1027: lds %0,%1"
1028: [(set_attr "type" "fpop,ld")])
1029:
1030: (define_insn "truncdfsf2"
1031: [(set (match_operand:SF 0 "register_operand" "=f")
1032: (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1033: "TARGET_FP"
1034: "cvtts %R1,%0"
1035: [(set_attr "type" "fpop")])
1036:
1037: (define_insn "divsf3"
1038: [(set (match_operand:SF 0 "register_operand" "=f")
1039: (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1040: (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1041: "TARGET_FP"
1042: "divs %R1,%R2,%0"
1043: [(set_attr "type" "fdivs")])
1044:
1045: (define_insn "divdf3"
1046: [(set (match_operand:DF 0 "register_operand" "=f")
1047: (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1048: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1049: "TARGET_FP"
1050: "divt %R1,%R2,%0"
1051: [(set_attr "type" "fdivt")])
1052:
1053: (define_insn ""
1054: [(set (match_operand:DF 0 "register_operand" "=f")
1055: (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1056: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1057: "TARGET_FP"
1058: "divt %R1,%R2,%0"
1059: [(set_attr "type" "fdivt")])
1060:
1061: (define_insn ""
1062: [(set (match_operand:DF 0 "register_operand" "=f")
1063: (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1064: (float_extend:DF
1065: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1066: "TARGET_FP"
1067: "divt %R1,%R2,%0"
1068: [(set_attr "type" "fdivt")])
1069:
1070: (define_insn ""
1071: [(set (match_operand:DF 0 "register_operand" "=f")
1072: (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1073: (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1074: "TARGET_FP"
1075: "divt %R1,%R2,%0"
1076: [(set_attr "type" "fdivt")])
1077:
1078: (define_insn "mulsf3"
1079: [(set (match_operand:SF 0 "register_operand" "=f")
1080: (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1081: (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1082: "TARGET_FP"
1083: "muls %R1,%R2,%0"
1084: [(set_attr "type" "fpop")])
1085:
1086: (define_insn "muldf3"
1087: [(set (match_operand:DF 0 "register_operand" "=f")
1088: (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1089: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1090: "TARGET_FP"
1091: "mult %R1,%R2,%0"
1092: [(set_attr "type" "fpop")])
1093:
1094: (define_insn ""
1095: [(set (match_operand:DF 0 "register_operand" "=f")
1096: (mult:DF (float_extend:DF
1097: (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1098: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1099: "TARGET_FP"
1100: "mult %R1,%R2,%0"
1101: [(set_attr "type" "fpop")])
1102:
1103: (define_insn ""
1104: [(set (match_operand:DF 0 "register_operand" "=f")
1105: (mult:DF (float_extend:DF
1106: (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1107: (float_extend:DF
1108: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1109: "TARGET_FP"
1110: "mult %R1,%R2,%0"
1111: [(set_attr "type" "fpop")])
1112:
1113: (define_insn "subsf3"
1114: [(set (match_operand:SF 0 "register_operand" "=f")
1115: (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1116: (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1117: "TARGET_FP"
1118: "subs %R1,%R2,%0"
1119: [(set_attr "type" "fpop")])
1120:
1121: (define_insn "subdf3"
1122: [(set (match_operand:DF 0 "register_operand" "=f")
1123: (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1124: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1125: "TARGET_FP"
1126: "subt %R1,%R2,%0"
1127: [(set_attr "type" "fpop")])
1128:
1129: (define_insn ""
1130: [(set (match_operand:DF 0 "register_operand" "=f")
1131: (minus:DF (float_extend:DF
1132: (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1133: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1134: "TARGET_FP"
1135: "subt %R1,%R2,%0"
1136: [(set_attr "type" "fpop")])
1137:
1138: (define_insn ""
1139: [(set (match_operand:DF 0 "register_operand" "=f")
1140: (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1141: (float_extend:DF
1142: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1143: "TARGET_FP"
1144: "subt %R1,%R2,%0"
1145: [(set_attr "type" "fpop")])
1146:
1147: (define_insn ""
1148: [(set (match_operand:DF 0 "register_operand" "=f")
1149: (minus:DF (float_extend:DF
1150: (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1151: (float_extend:DF
1152: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1153: "TARGET_FP"
1154: "subt %R1,%R2,%0"
1155: [(set_attr "type" "fpop")])
1156:
1157: ;; Next are all the integer comparisons, and conditional moves and branches
1158: ;; and some of the related define_expand's and define_split's.
1159:
1160: (define_insn ""
1161: [(set (match_operand:DI 0 "register_operand" "=r")
1162: (match_operator:DI 1 "alpha_comparison_operator"
1163: [(match_operand:DI 2 "reg_or_0_operand" "rJ")
1164: (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
1165: ""
1166: "cmp%C1 %r2,%3,%0"
1167: [(set_attr "type" "icmp")])
1168:
1169: ;; There are three important special-case that don't fit the above pattern
1170: ;; but which we want to handle here.
1171:
1172: (define_insn ""
1173: [(set (match_operand:DI 0 "register_operand" "=r")
1174: (ne:DI (match_operand:DI 1 "register_operand" "r")
1175: (const_int 0)))]
1176: ""
1177: "cmpult $31,%1,%0"
1178: [(set_attr "type" "icmp")])
1179:
1180: (define_insn ""
1181: [(set (match_operand:DI 0 "register_operand" "=r")
1182: (gt:DI (match_operand:DI 1 "register_operand" "r")
1183: (const_int 0)))]
1184: ""
1185: "cmplt $31,%1,%0"
1186: [(set_attr "type" "icmp")])
1187:
1188: (define_insn ""
1189: [(set (match_operand:DI 0 "register_operand" "=r")
1190: (ge:DI (match_operand:DI 1 "register_operand" "r")
1191: (const_int 0)))]
1192: ""
1193: "cmple $31,%1,%0"
1194: [(set_attr "type" "icmp")])
1195:
1196: (define_insn ""
1197: [(set (match_operand:DI 0 "register_operand" "=r,r")
1198: (if_then_else:DI
1199: (match_operator 2 "signed_comparison_operator"
1200: [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ")
1201: (const_int 0)])
1202: (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1203: (match_operand:DI 4 "reg_or_8bit_operand" "0,rI")))]
1204: ""
1205: "@
1206: cmov%C2 %r3,%1,%0
1207: cmov%D2 %r3,%4,%0")
1208:
1209: (define_insn ""
1210: [(set (match_operand:DI 0 "register_operand" "=r,r")
1211: (if_then_else:DI
1212: (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1213: (const_int 1)
1214: (const_int 0))
1215: (const_int 0))
1216: (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1217: (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1218: ""
1219: "@
1220: cmovlbc %r2,%1,%0
1221: cmovlbs %r2,%3,%0")
1222:
1223: (define_insn ""
1224: [(set (match_operand:DI 0 "register_operand" "=r,r")
1225: (if_then_else:DI
1226: (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1227: (const_int 1)
1228: (const_int 0))
1229: (const_int 0))
1230: (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1231: (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1232: ""
1233: "@
1234: cmovlbs %r2,%1,%0
1235: cmovlbc %r2,%3,%0")
1236:
1237: ;; This form is added since combine thinks that an IF_THEN_ELSE with both
1238: ;; arms constant is a single insn, so it won't try to form it if combine
1239: ;; knows they are really two insns. This occurs in divides by powers
1240: ;; of two.
1241:
1242: (define_insn ""
1243: [(set (match_operand:DI 0 "register_operand" "=r")
1244: (if_then_else:DI
1245: (match_operator 2 "signed_comparison_operator"
1246: [(match_operand:DI 3 "reg_or_0_operand" "rJ")
1247: (const_int 0)])
1248: (plus:DI (match_dup 0)
1249: (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1250: (match_dup 0)))
1251: (clobber (match_scratch:DI 4 "=&r"))]
1252: ""
1253: "addq %0,%1,%4\;cmov%C2 %r3,%4,%0")
1254:
1255: (define_split
1256: [(set (match_operand:DI 0 "register_operand" "")
1257: (if_then_else:DI
1258: (match_operator 2 "signed_comparison_operator"
1259: [(match_operand:DI 3 "reg_or_0_operand" "")
1260: (const_int 0)])
1261: (plus:DI (match_dup 0)
1262: (match_operand:DI 1 "reg_or_8bit_operand" ""))
1263: (match_dup 0)))
1264: (clobber (match_operand:DI 4 "register_operand" ""))]
1265: ""
1266: [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1)))
1267: (set (match_dup 0) (if_then_else:DI (match_op_dup 2
1268: [(match_dup 3)
1269: (const_int 0)])
1270: (match_dup 4) (match_dup 0)))]
1271: "")
1272:
1273: (define_split
1274: [(parallel
1275: [(set (match_operand:DI 0 "register_operand" "")
1276: (if_then_else:DI
1277: (match_operator 1 "comparison_operator"
1278: [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
1279: (const_int 1)
1280: (match_operand:DI 3 "const_int_operand" ""))
1281: (const_int 0)])
1282: (match_operand:DI 4 "reg_or_8bit_operand" "")
1283: (match_operand:DI 5 "reg_or_8bit_operand" "")))
1284: (clobber (match_operand:DI 6 "register_operand" ""))])]
1285: "INTVAL (operands[3]) != 0"
1286: [(set (match_dup 6)
1287: (lshiftrt:DI (match_dup 2) (match_dup 3)))
1288: (set (match_dup 0)
1289: (if_then_else:DI (match_op_dup 1
1290: [(zero_extract:DI (match_dup 6)
1291: (const_int 1)
1292: (const_int 0))
1293: (const_int 0)])
1294: (match_dup 4)
1295: (match_dup 5)))]
1296: "")
1297:
1298: ;; For ABS, we have two choices, depending on whether the input and output
1299: ;; registers are the same or not.
1300: (define_expand "absdi2"
1301: [(set (match_operand:DI 0 "register_operand" "")
1302: (abs:DI (match_operand:DI 1 "register_operand" "")))]
1303: ""
1304: "
1305: { if (rtx_equal_p (operands[0], operands[1]))
1306: emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
1307: else
1308: emit_insn (gen_absdi2_diff (operands[0], operands[1]));
1309:
1310: DONE;
1311: }")
1312:
1313: (define_expand "absdi2_same"
1314: [(set (match_operand:DI 1 "register_operand" "")
1315: (neg:DI (match_operand:DI 0 "register_operand" "")))
1316: (set (match_dup 0)
1317: (if_then_else:DI (ge (match_dup 0) (const_int 0))
1318: (match_dup 0)
1319: (match_dup 1)))]
1320: ""
1321: "")
1322:
1323: (define_expand "absdi2_diff"
1324: [(set (match_operand:DI 0 "register_operand" "")
1325: (neg:DI (match_operand:DI 1 "register_operand" "")))
1326: (set (match_dup 0)
1327: (if_then_else:DI (lt (match_dup 1) (const_int 0))
1328: (match_dup 0)
1329: (match_dup 1)))]
1330: ""
1331: "")
1332:
1333: (define_split
1334: [(set (match_operand:DI 0 "register_operand" "")
1335: (abs:DI (match_dup 0)))
1336: (clobber (match_operand:DI 2 "register_operand" ""))]
1337: ""
1338: [(set (match_dup 1) (neg:DI (match_dup 0)))
1339: (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
1340: (match_dup 0) (match_dup 1)))]
1341: "")
1342:
1343: (define_split
1344: [(set (match_operand:DI 0 "register_operand" "")
1345: (abs:DI (match_operand:DI 1 "register_operand" "")))]
1346: "! rtx_equal_p (operands[0], operands[1])"
1347: [(set (match_dup 0) (neg:DI (match_dup 1)))
1348: (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
1349: (match_dup 0) (match_dup 1)))]
1350: "")
1351:
1352: (define_split
1353: [(set (match_operand:DI 0 "register_operand" "")
1354: (neg:DI (abs:DI (match_dup 0))))
1355: (clobber (match_operand:DI 2 "register_operand" ""))]
1356: ""
1357: [(set (match_dup 1) (neg:DI (match_dup 0)))
1358: (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
1359: (match_dup 0) (match_dup 1)))]
1360: "")
1361:
1362: (define_split
1363: [(set (match_operand:DI 0 "register_operand" "")
1364: (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
1365: "! rtx_equal_p (operands[0], operands[1])"
1366: [(set (match_dup 0) (neg:DI (match_dup 1)))
1367: (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
1368: (match_dup 0) (match_dup 1)))]
1369: "")
1370:
1371: (define_expand "smaxdi3"
1372: [(set (match_dup 3)
1373: (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
1374: (match_operand:DI 2 "reg_or_8bit_operand" "")))
1375: (set (match_operand:DI 0 "register_operand" "")
1376: (if_then_else:DI (eq (match_dup 3) (const_int 0))
1377: (match_dup 1) (match_dup 2)))]
1378: ""
1379: "
1380: { operands[3] = gen_reg_rtx (DImode);
1381: }")
1382:
1383: (define_split
1384: [(set (match_operand:DI 0 "register_operand" "")
1385: (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
1386: (match_operand:DI 2 "reg_or_8bit_operand" "")))
1387: (clobber (match_operand:DI 3 "register_operand" ""))]
1388: "operands[2] != const0_rtx"
1389: [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
1390: (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
1391: (match_dup 1) (match_dup 2)))]
1392: "")
1393:
1394: (define_insn ""
1395: [(set (match_operand:DI 0 "register_operand" "=r")
1396: (smax:DI (match_operand:DI 1 "register_operand" "0")
1397: (const_int 0)))]
1398: ""
1399: "cmovlt %0,0,%0")
1400:
1401: (define_expand "smindi3"
1402: [(set (match_dup 3)
1403: (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
1404: (match_operand:DI 2 "reg_or_8bit_operand" "")))
1405: (set (match_operand:DI 0 "register_operand" "")
1406: (if_then_else:DI (ne (match_dup 3) (const_int 0))
1407: (match_dup 1) (match_dup 2)))]
1408: ""
1409: "
1410: { operands[3] = gen_reg_rtx (DImode);
1411: }")
1412:
1413: (define_split
1414: [(set (match_operand:DI 0 "register_operand" "")
1415: (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
1416: (match_operand:DI 2 "reg_or_8bit_operand" "")))
1417: (clobber (match_operand:DI 3 "register_operand" ""))]
1418: "operands[2] != const0_rtx"
1419: [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
1420: (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
1421: (match_dup 1) (match_dup 2)))]
1422: "")
1423:
1424: (define_insn ""
1425: [(set (match_operand:DI 0 "register_operand" "=r")
1426: (smin:DI (match_operand:DI 1 "register_operand" "0")
1427: (const_int 0)))]
1428: ""
1429: "cmovgt %0,0,%0")
1430:
1431: (define_expand "umaxdi3"
1432: [(set (match_dup 3)
1433: (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
1434: (match_operand:DI 2 "reg_or_8bit_operand" "")))
1435: (set (match_operand:DI 0 "register_operand" "")
1436: (if_then_else:DI (eq (match_dup 3) (const_int 0))
1437: (match_dup 1) (match_dup 2)))]
1438: ""
1439: "
1440: { operands[3] = gen_reg_rtx (DImode);
1441: }")
1442:
1443: (define_split
1444: [(set (match_operand:DI 0 "register_operand" "")
1445: (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
1446: (match_operand:DI 2 "reg_or_8bit_operand" "")))
1447: (clobber (match_operand:DI 3 "register_operand" ""))]
1448: "operands[2] != const0_rtx"
1449: [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
1450: (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
1451: (match_dup 1) (match_dup 2)))]
1452: "")
1453:
1454: (define_expand "umindi3"
1455: [(set (match_dup 3)
1456: (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
1457: (match_operand:DI 2 "reg_or_8bit_operand" "")))
1458: (set (match_operand:DI 0 "register_operand" "")
1459: (if_then_else:DI (ne (match_dup 3) (const_int 0))
1460: (match_dup 1) (match_dup 2)))]
1461: ""
1462: "
1463: { operands[3] = gen_reg_rtx (DImode);
1464: }")
1465:
1466: (define_split
1467: [(set (match_operand:DI 0 "register_operand" "")
1468: (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
1469: (match_operand:DI 2 "reg_or_8bit_operand" "")))
1470: (clobber (match_operand:DI 3 "register_operand" ""))]
1471: "operands[2] != const0_rtx"
1472: [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
1473: (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
1474: (match_dup 1) (match_dup 2)))]
1475: "")
1476:
1477: (define_insn ""
1478: [(set (pc)
1479: (if_then_else
1480: (match_operator 1 "signed_comparison_operator"
1481: [(match_operand:DI 2 "reg_or_0_operand" "rJ")
1482: (const_int 0)])
1483: (label_ref (match_operand 0 "" ""))
1484: (pc)))]
1485: ""
1486: "b%C1 %r2,%0"
1487: [(set_attr "type" "ibr")])
1488:
1489: (define_insn ""
1490: [(set (pc)
1491: (if_then_else
1492: (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1493: (const_int 1)
1494: (const_int 0))
1495: (const_int 0))
1496: (label_ref (match_operand 0 "" ""))
1497: (pc)))]
1498: ""
1499: "blbs %r1,%0"
1500: [(set_attr "type" "ibr")])
1501:
1502: (define_insn ""
1503: [(set (pc)
1504: (if_then_else
1505: (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1506: (const_int 1)
1507: (const_int 0))
1508: (const_int 0))
1509: (label_ref (match_operand 0 "" ""))
1510: (pc)))]
1511: ""
1512: "blbc %r1,%0"
1513: [(set_attr "type" "ibr")])
1514:
1515: (define_split
1516: [(parallel
1517: [(set (pc)
1518: (if_then_else
1519: (match_operator 1 "comparison_operator"
1520: [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
1521: (const_int 1)
1522: (match_operand:DI 3 "const_int_operand" ""))
1523: (const_int 0)])
1524: (label_ref (match_operand 0 "" ""))
1525: (pc)))
1526: (clobber (match_operand:DI 4 "register_operand" ""))])]
1527: "INTVAL (operands[3]) != 0"
1528: [(set (match_dup 4)
1529: (lshiftrt:DI (match_dup 2) (match_dup 3)))
1530: (set (pc)
1531: (if_then_else (match_op_dup 1
1532: [(zero_extract:DI (match_dup 4)
1533: (const_int 1)
1534: (const_int 0))
1535: (const_int 0)])
1536: (label_ref (match_dup 0))
1537: (pc)))]
1538: "")
1539:
1540: ;; The following are the corresponding floating-point insns. Recall
1541: ;; we need to have variants that expand the arguments from SF mode
1542: ;; to DFmode.
1543:
1544: (define_insn ""
1545: [(set (match_operand:DF 0 "register_operand" "=f")
1546: (match_operator:DF 1 "alpha_comparison_operator"
1547: [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
1548: (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
1549: "TARGET_FP"
1550: "cmpt%C1 %R2,%R3,%0"
1551: [(set_attr "type" "fpop")])
1552:
1553: (define_insn ""
1554: [(set (match_operand:DF 0 "register_operand" "=f")
1555: (match_operator:DF 1 "alpha_comparison_operator"
1556: [(float_extend:DF
1557: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
1558: (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
1559: "TARGET_FP"
1560: "cmpt%C1 %R2,%R3,%0"
1561: [(set_attr "type" "fpop")])
1562:
1563: (define_insn ""
1564: [(set (match_operand:DF 0 "register_operand" "=f")
1565: (match_operator:DF 1 "alpha_comparison_operator"
1566: [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
1567: (float_extend:DF
1568: (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
1569: "TARGET_FP"
1570: "cmpt%C1 %R2,%R3,%0"
1571: [(set_attr "type" "fpop")])
1572:
1573: (define_insn ""
1574: [(set (match_operand:DF 0 "register_operand" "=f")
1575: (match_operator:DF 1 "alpha_comparison_operator"
1576: [(float_extend:DF
1577: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
1578: (float_extend:DF
1579: (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
1580: "TARGET_FP"
1581: "cmpt%C1 %R2,%R3,%0"
1582: [(set_attr "type" "fpop")])
1583:
1584: (define_insn ""
1585: [(set (match_operand:DF 0 "register_operand" "=f,f")
1586: (if_then_else:DF
1587: (match_operator 3 "signed_comparison_operator"
1588: [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
1589: (match_operand:DF 2 "fp0_operand" "G,G")])
1590: (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
1591: (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
1592: "TARGET_FP"
1593: "@
1594: fcmov%C3 %R4,%R1,%0
1595: fcmov%D3 %R4,%R5,%0"
1596: [(set_attr "type" "fpop")])
1597:
1598: (define_insn ""
1599: [(set (match_operand:SF 0 "register_operand" "=f,f")
1600: (if_then_else:SF
1601: (match_operator 3 "signed_comparison_operator"
1602: [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
1603: (match_operand:DF 2 "fp0_operand" "G,G")])
1604: (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
1605: (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
1606: "TARGET_FP"
1607: "@
1608: fcmov%C3 %R4,%R1,%0
1609: fcmov%D3 %R4,%R5,%0"
1610: [(set_attr "type" "fpop")])
1611:
1612: (define_insn ""
1613: [(set (match_operand:DF 0 "register_operand" "=f,f")
1614: (if_then_else:DF
1615: (match_operator 3 "signed_comparison_operator"
1616: [(match_operand:DF 1 "reg_or_fp0_operand" "fG,fG")
1617: (match_operand:DF 2 "fp0_operand" "G,G")])
1618: (float_extend:DF (match_operand:SF 4 "reg_or_fp0_operand" "fG,0"))
1619: (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
1620: "TARGET_FP"
1621: "@
1622: fcmov%C3 %R4,%R1,%0
1623: fcmov%D3 %R4,%R5,%0"
1624: [(set_attr "type" "fpop")])
1625:
1626: (define_insn ""
1627: [(set (match_operand:DF 0 "register_operand" "=f,f")
1628: (if_then_else:DF
1629: (match_operator 3 "signed_comparison_operator"
1630: [(float_extend:DF
1631: (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
1632: (match_operand:DF 2 "fp0_operand" "G,G")])
1633: (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
1634: (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
1635: "TARGET_FP"
1636: "@
1637: fcmov%C3 %R4,%R1,%0
1638: fcmov%D3 %R4,%R5,%0"
1639: [(set_attr "type" "fpop")])
1640:
1641: (define_insn ""
1642: [(set (match_operand:SF 0 "register_operand" "=f,f")
1643: (if_then_else:SF
1644: (match_operator 3 "signed_comparison_operator"
1645: [(float_extend:DF
1646: (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
1647: (match_operand:DF 2 "fp0_operand" "G,G")])
1648: (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
1649: (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
1650: "TARGET_FP"
1651: "@
1652: fcmov%C3 %R4,%R1,%0
1653: fcmov%D3 %R4,%R5,%0"
1654: [(set_attr "type" "fpop")])
1655:
1656: (define_insn ""
1657: [(set (match_operand:DF 0 "register_operand" "=f,f")
1658: (if_then_else:DF
1659: (match_operator 3 "signed_comparison_operator"
1660: [(float_extend:DF
1661: (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
1662: (match_operand:DF 2 "fp0_operand" "G,G")])
1663: (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
1664: (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
1665: "TARGET_FP"
1666: "@
1667: fcmov%C3 %R4,%R1,%0
1668: fcmov%D3 %R4,%R5,%0"
1669: [(set_attr "type" "fpop")])
1670:
1671: (define_expand "maxdf3"
1672: [(set (match_dup 3)
1673: (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
1674: (match_operand:DF 2 "reg_or_fp0_operand" "")))
1675: (set (match_operand:DF 0 "register_operand" "")
1676: (if_then_else:DF (eq (match_dup 3) (const_int 0))
1677: (match_dup 1) (match_dup 2)))]
1678: "TARGET_FP"
1679: "
1680: { operands[3] = gen_reg_rtx (DFmode);
1681: }")
1682:
1683: (define_expand "mindf3"
1684: [(set (match_dup 3)
1685: (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
1686: (match_operand:DF 2 "reg_or_fp0_operand" "")))
1687: (set (match_operand:DF 0 "register_operand" "")
1688: (if_then_else:DF (ne (match_dup 3) (const_int 0))
1689: (match_dup 1) (match_dup 2)))]
1690: "TARGET_FP"
1691: "
1692: { operands[3] = gen_reg_rtx (DFmode);
1693: }")
1694:
1695: (define_expand "maxsf3"
1696: [(set (match_dup 3)
1697: (le:DF (match_operand:SF 1 "reg_or_fp0_operand" "")
1698: (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
1699: (set (match_operand:SF 0 "register_operand" "")
1700: (if_then_else:SF (eq (match_dup 3) (const_int 0))
1701: (match_dup 1) (match_dup 2)))]
1702: "TARGET_FP"
1703: "
1704: { operands[3] = gen_reg_rtx (SFmode);
1705: }")
1706:
1707: (define_expand "minsf3"
1708: [(set (match_dup 3)
1709: (lt:DF (match_operand:SF 1 "reg_or_fp0_operand" "")
1710: (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
1711: (set (match_operand:SF 0 "register_operand" "")
1712: (if_then_else:SF (ne (match_dup 3) (const_int 0))
1713: (match_dup 1) (match_dup 2)))]
1714: "TARGET_FP"
1715: "
1716: { operands[3] = gen_reg_rtx (SFmode);
1717: }")
1718:
1719: (define_insn ""
1720: [(set (pc)
1721: (if_then_else
1722: (match_operator 1 "signed_comparison_operator"
1723: [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
1724: (match_operand:DF 3 "fp0_operand" "G")])
1725: (label_ref (match_operand 0 "" ""))
1726: (pc)))]
1727: "TARGET_FP"
1728: "fb%C1 %R2,%0"
1729: [(set_attr "type" "fbr")])
1730:
1731: (define_insn ""
1732: [(set (pc)
1733: (if_then_else
1734: (match_operator 1 "signed_comparison_operator"
1735: [(float_extend:DF
1736: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
1737: (match_operand:DF 3 "fp0_operand" "G")])
1738: (label_ref (match_operand 0 "" ""))
1739: (pc)))]
1740: "TARGET_FP"
1741: "fb%C1 %R2,%0"
1742: [(set_attr "type" "fbr")])
1743:
1744: ;; These are the main define_expand's used to make conditional branches
1745: ;; and compares.
1746:
1747: (define_expand "cmpdf"
1748: [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
1749: (match_operand:DF 1 "reg_or_fp0_operand" "")))]
1750: ""
1751: "
1752: {
1753: alpha_compare_op0 = operands[0];
1754: alpha_compare_op1 = operands[1];
1755: alpha_compare_fp_p = 1;
1756: DONE;
1757: }")
1758:
1759: (define_expand "cmpdi"
1760: [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
1761: (match_operand:DI 1 "reg_or_8bit_operand" "")))]
1762: ""
1763: "
1764: {
1765: alpha_compare_op0 = operands[0];
1766: alpha_compare_op1 = operands[1];
1767: alpha_compare_fp_p = 0;
1768: DONE;
1769: }")
1770:
1771: (define_expand "beq"
1772: [(set (match_dup 1) (match_dup 2))
1773: (set (pc)
1774: (if_then_else (match_dup 3)
1775: (label_ref (match_operand 0 "" ""))
1776: (pc)))]
1777: ""
1778: "
1779: {
1780: enum machine_mode mode;
1781: enum rtx_code compare_code, branch_code;
1782:
1783: if (alpha_compare_fp_p)
1784: mode = DFmode, compare_code = EQ, branch_code = NE;
1785: else
1786: {
1787: mode = DImode, compare_code = MINUS, branch_code = EQ;
1788: if (GET_CODE (alpha_compare_op1) == CONST_INT)
1789: {
1790: compare_code = PLUS;
1791: alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
1792: }
1793: }
1794:
1795: operands[1] = gen_reg_rtx (mode);
1796: operands[2] = gen_rtx (compare_code, mode,
1797: alpha_compare_op0, alpha_compare_op1);
1798: operands[3] = gen_rtx (branch_code, VOIDmode,
1799: operands[1], CONST0_RTX (mode));
1800: }")
1801:
1802: (define_expand "bne"
1803: [(set (match_dup 1) (match_dup 2))
1804: (set (pc)
1805: (if_then_else (match_dup 3)
1806: (label_ref (match_operand 0 "" ""))
1807: (pc)))]
1808: ""
1809: "
1810: {
1811: enum machine_mode mode;
1812: enum rtx_code compare_code, branch_code;
1813:
1814: if (alpha_compare_fp_p)
1815: mode = DFmode, compare_code = EQ, branch_code = EQ;
1816: else
1817: {
1818: mode = DImode, compare_code = MINUS, branch_code = NE;
1819: if (GET_CODE (alpha_compare_op1) == CONST_INT)
1820: {
1821: compare_code = PLUS;
1822: alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
1823: }
1824: }
1825:
1826: operands[1] = gen_reg_rtx (mode);
1827: operands[2] = gen_rtx (compare_code, mode,
1828: alpha_compare_op0, alpha_compare_op1);
1829: operands[3] = gen_rtx (branch_code, VOIDmode,
1830: operands[1], CONST0_RTX (mode));
1831: }")
1832:
1833: (define_expand "blt"
1834: [(set (match_dup 1) (match_dup 2))
1835: (set (pc)
1836: (if_then_else (match_dup 3)
1837: (label_ref (match_operand 0 "" ""))
1838: (pc)))]
1839: ""
1840: "
1841: {
1842: enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
1843: operands[1] = gen_reg_rtx (mode);
1844: operands[2] = gen_rtx (LT, mode, alpha_compare_op0, alpha_compare_op1);
1845: operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
1846: }")
1847:
1848: (define_expand "ble"
1849: [(set (match_dup 1) (match_dup 2))
1850: (set (pc)
1851: (if_then_else (match_dup 3)
1852: (label_ref (match_operand 0 "" ""))
1853: (pc)))]
1854: ""
1855: "
1856: {
1857: enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
1858: operands[1] = gen_reg_rtx (mode);
1859: operands[2] = gen_rtx (LE, mode, alpha_compare_op0, alpha_compare_op1);
1860: operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
1861: }")
1862:
1863: (define_expand "bgt"
1864: [(set (match_dup 1) (match_dup 2))
1865: (set (pc)
1866: (if_then_else (match_dup 3)
1867: (label_ref (match_operand 0 "" ""))
1868: (pc)))]
1869: ""
1870: "
1871: {
1872: if (alpha_compare_fp_p)
1873: {
1874: operands[1] = gen_reg_rtx (DFmode);
1875: operands[2] = gen_rtx (LT, DFmode, alpha_compare_op1, alpha_compare_op0);
1876: operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
1877: }
1878: else
1879: {
1880: operands[1] = gen_reg_rtx (DImode);
1881: operands[2] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
1882: operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
1883: }
1884: }")
1885:
1886: (define_expand "bge"
1887: [(set (match_dup 1) (match_dup 2))
1888: (set (pc)
1889: (if_then_else (match_dup 3)
1890: (label_ref (match_operand 0 "" ""))
1891: (pc)))]
1892: ""
1893: "
1894: {
1895: if (alpha_compare_fp_p)
1896: {
1897: operands[1] = gen_reg_rtx (DFmode);
1898: operands[2] = gen_rtx (LE, DFmode, alpha_compare_op1, alpha_compare_op0);
1899: operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
1900: }
1901: else
1902: {
1903: operands[1] = gen_reg_rtx (DImode);
1904: operands[2] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
1905: operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
1906: }
1907: }")
1908:
1909: (define_expand "bltu"
1910: [(set (match_dup 1) (match_dup 2))
1911: (set (pc)
1912: (if_then_else (match_dup 3)
1913: (label_ref (match_operand 0 "" ""))
1914: (pc)))]
1915: ""
1916: "
1917: {
1918: operands[1] = gen_reg_rtx (DImode);
1919: operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
1920: operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
1921: }")
1922:
1923: (define_expand "bleu"
1924: [(set (match_dup 1) (match_dup 2))
1925: (set (pc)
1926: (if_then_else (match_dup 3)
1927: (label_ref (match_operand 0 "" ""))
1928: (pc)))]
1929: ""
1930: "
1931: {
1932: operands[1] = gen_reg_rtx (DImode);
1933: operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
1934: operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
1935: }")
1936:
1937: (define_expand "bgtu"
1938: [(set (match_dup 1) (match_dup 2))
1939: (set (pc)
1940: (if_then_else (match_dup 3)
1941: (label_ref (match_operand 0 "" ""))
1942: (pc)))]
1943: ""
1944: "
1945: {
1946: operands[1] = gen_reg_rtx (DImode);
1947: operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
1948: operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
1949: }")
1950:
1951: (define_expand "bgeu"
1952: [(set (match_dup 1) (match_dup 2))
1953: (set (pc)
1954: (if_then_else (match_dup 3)
1955: (label_ref (match_operand 0 "" ""))
1956: (pc)))]
1957: ""
1958: "
1959: {
1960: operands[1] = gen_reg_rtx (DImode);
1961: operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
1962: operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
1963: }")
1964:
1965: (define_expand "seq"
1966: [(set (match_operand:DI 0 "register_operand" "")
1967: (match_dup 1))]
1968: ""
1969: "
1970: {
1971: if (alpha_compare_fp_p)
1972: FAIL;
1973:
1974: operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
1975: }")
1976:
1977: (define_expand "sne"
1978: [(set (match_operand:DI 0 "register_operand" "")
1979: (match_dup 1))
1980: (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
1981: ""
1982: "
1983: {
1984: if (alpha_compare_fp_p)
1985: FAIL;
1986:
1987: operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
1988: }")
1989:
1990: (define_expand "slt"
1991: [(set (match_operand:DI 0 "register_operand" "")
1992: (match_dup 1))]
1993: ""
1994: "
1995: {
1996: if (alpha_compare_fp_p)
1997: FAIL;
1998:
1999: operands[1] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
2000: }")
2001:
2002: (define_expand "sle"
2003: [(set (match_operand:DI 0 "register_operand" "")
2004: (match_dup 1))]
2005: ""
2006: "
2007: {
2008: if (alpha_compare_fp_p)
2009: FAIL;
2010:
2011: operands[1] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
2012: }")
2013:
2014: (define_expand "sgt"
2015: [(set (match_operand:DI 0 "register_operand" "")
2016: (match_dup 1))]
2017: ""
2018: "
2019: {
2020: if (alpha_compare_fp_p)
2021: FAIL;
2022:
2023: operands[1] = gen_rtx (LT, DImode, force_reg (DImode, alpha_compare_op1),
2024: alpha_compare_op0);
2025: }")
2026:
2027: (define_expand "sge"
2028: [(set (match_operand:DI 0 "register_operand" "")
2029: (match_dup 1))]
2030: ""
2031: "
2032: {
2033: if (alpha_compare_fp_p)
2034: FAIL;
2035:
2036: operands[1] = gen_rtx (LE, DImode, force_reg (DImode, alpha_compare_op1),
2037: alpha_compare_op0);
2038: }")
2039:
2040: (define_expand "sltu"
2041: [(set (match_operand:DI 0 "register_operand" "")
2042: (match_dup 1))]
2043: ""
2044: "
2045: {
2046: if (alpha_compare_fp_p)
2047: FAIL;
2048:
2049: operands[1] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2050: }")
2051:
2052: (define_expand "sleu"
2053: [(set (match_operand:DI 0 "register_operand" "")
2054: (match_dup 1))]
2055: ""
2056: "
2057: {
2058: if (alpha_compare_fp_p)
2059: FAIL;
2060:
2061: operands[1] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2062: }")
2063:
2064: (define_expand "sgtu"
2065: [(set (match_operand:DI 0 "register_operand" "")
2066: (match_dup 1))]
2067: ""
2068: "
2069: {
2070: if (alpha_compare_fp_p)
2071: FAIL;
2072:
2073: operands[1] = gen_rtx (LTU, DImode, force_reg (DImode, alpha_compare_op1),
2074: alpha_compare_op0);
2075: }")
2076:
2077: (define_expand "sgeu"
2078: [(set (match_operand:DI 0 "register_operand" "")
2079: (match_dup 1))]
2080: ""
2081: "
2082: {
2083: if (alpha_compare_fp_p)
2084: FAIL;
2085:
2086: operands[1] = gen_rtx (LEU, DImode, force_reg (DImode, alpha_compare_op1),
2087: alpha_compare_op0);
2088: }")
2089:
2090: ;; These define_split definitions are used in cases when comparisons have
2091: ;; not be stated in the correct way and we need to reverse the second
2092: ;; comparison. For example, x >= 7 has to be done as x < 6 with the
2093: ;; comparison that tests the result being reversed. We have one define_split
2094: ;; for each use of a comparison. They do not match valid insns and need
2095: ;; not generate valid insns.
2096: ;;
2097: ;; We can also handle equality comparisons (and inequality comparisons in
2098: ;; cases where the resulting add cannot overflow) by doing an add followed by
2099: ;; a comparison with zero. This is faster since the addition takes one
2100: ;; less cycle than a compare when feeding into a conditional move.
2101: ;; For this case, we also have an SImode pattern since we can merge the add
2102: ;; and sign extend and the order doesn't matter.
2103: ;;
2104: ;; We do not do this for floating-point, since it isn't clear how the "wrong"
2105: ;; operation could have been generated.
2106:
2107: (define_split
2108: [(set (match_operand:DI 0 "register_operand" "")
2109: (if_then_else:DI
2110: (match_operator 1 "comparison_operator"
2111: [(match_operand:DI 2 "reg_or_0_operand" "")
2112: (match_operand:DI 3 "reg_or_cint_operand" "")])
2113: (match_operand:DI 4 "reg_or_cint_operand" "")
2114: (match_operand:DI 5 "reg_or_cint_operand" "")))
2115: (clobber (match_operand:DI 6 "register_operand" ""))]
2116: "operands[3] != const0_rtx"
2117: [(set (match_dup 6) (match_dup 7))
2118: (set (match_dup 0)
2119: (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
2120: "
2121: { enum rtx_code code = GET_CODE (operands[1]);
2122: int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2123:
2124: /* If we are comparing for equality with a constant and that constant
2125: appears in the arm when the register equals the constant, use the
2126: register since that is more likely to match (and to produce better code
2127: if both would). */
2128:
2129: if (code == EQ && GET_CODE (operands[3]) == CONST_INT
2130: && rtx_equal_p (operands[4], operands[3]))
2131: operands[4] = operands[2];
2132:
2133: else if (code == NE && GET_CODE (operands[3]) == CONST_INT
2134: && rtx_equal_p (operands[5], operands[3]))
2135: operands[5] = operands[2];
2136:
2137: if (code == NE || code == EQ
2138: || (extended_count (operands[2], DImode, unsignedp) >= 1
2139: && extended_count (operands[3], DImode, unsignedp) >= 1))
2140: {
2141: if (GET_CODE (operands[3]) == CONST_INT)
2142: operands[7] = gen_rtx (PLUS, DImode, operands[2],
2143: GEN_INT (- INTVAL (operands[3])));
2144: else
2145: operands[7] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
2146:
2147: operands[8] = gen_rtx (code, VOIDmode, operands[6], const0_rtx);
2148: }
2149:
2150: else if (code == EQ || code == LE || code == LT
2151: || code == LEU || code == LTU)
2152: {
2153: operands[7] = gen_rtx (code, DImode, operands[2], operands[3]);
2154: operands[8] = gen_rtx (NE, VOIDmode, operands[6], const0_rtx);
2155: }
2156: else
2157: {
2158: operands[7] = gen_rtx (reverse_condition (code), DImode, operands[2],
2159: operands[3]);
2160: operands[8] = gen_rtx (EQ, VOIDmode, operands[6], const0_rtx);
2161: }
2162: }")
2163:
2164: (define_split
2165: [(set (match_operand:DI 0 "register_operand" "")
2166: (if_then_else:DI
2167: (match_operator 1 "comparison_operator"
2168: [(match_operand:SI 2 "reg_or_0_operand" "")
2169: (match_operand:SI 3 "reg_or_cint_operand" "")])
2170: (match_operand:DI 4 "reg_or_8bit_operand" "")
2171: (match_operand:DI 5 "reg_or_8bit_operand" "")))
2172: (clobber (match_operand:DI 6 "register_operand" ""))]
2173: "operands[3] != const0_rtx
2174: && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
2175: [(set (match_dup 6) (match_dup 7))
2176: (set (match_dup 0)
2177: (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
2178: "
2179: { enum rtx_code code = GET_CODE (operands[1]);
2180: int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2181: rtx tem;
2182:
2183: if ((code != NE && code != EQ
2184: && ! (extended_count (operands[2], DImode, unsignedp) >= 1
2185: && extended_count (operands[3], DImode, unsignedp) >= 1)))
2186: FAIL;
2187:
2188: if (GET_CODE (operands[3]) == CONST_INT)
2189: tem = gen_rtx (PLUS, SImode, operands[2],
2190: GEN_INT (- INTVAL (operands[3])));
2191: else
2192: tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
2193:
2194: operands[7] = gen_rtx (SIGN_EXTEND, DImode, tem);
2195: operands[8] = gen_rtx (GET_CODE (operands[1]), VOIDmode, operands[6],
2196: const0_rtx);
2197: }")
2198:
2199: (define_split
2200: [(set (pc)
2201: (if_then_else
2202: (match_operator 1 "comparison_operator"
2203: [(match_operand:DI 2 "reg_or_0_operand" "")
2204: (match_operand:DI 3 "reg_or_cint_operand" "")])
2205: (label_ref (match_operand 0 "" ""))
2206: (pc)))
2207: (clobber (match_operand:DI 4 "register_operand" ""))]
2208: "operands[3] != const0_rtx"
2209: [(set (match_dup 4) (match_dup 5))
2210: (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
2211: "
2212: { enum rtx_code code = GET_CODE (operands[1]);
2213: int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2214:
2215: if (code == NE || code == EQ
2216: || (extended_count (operands[2], DImode, unsignedp) >= 1
2217: && extended_count (operands[3], DImode, unsignedp) >= 1))
2218: {
2219: if (GET_CODE (operands[3]) == CONST_INT)
2220: operands[5] = gen_rtx (PLUS, DImode, operands[2],
2221: GEN_INT (- INTVAL (operands[3])));
2222: else
2223: operands[5] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
2224:
2225: operands[6] = gen_rtx (code, VOIDmode, operands[4], const0_rtx);
2226: }
2227:
2228: else if (code == EQ || code == LE || code == LT
2229: || code == LEU || code == LTU)
2230: {
2231: operands[5] = gen_rtx (code, DImode, operands[2], operands[3]);
2232: operands[6] = gen_rtx (NE, VOIDmode, operands[4], const0_rtx);
2233: }
2234: else
2235: {
2236: operands[5] = gen_rtx (reverse_condition (code), DImode, operands[2],
2237: operands[3]);
2238: operands[6] = gen_rtx (EQ, VOIDmode, operands[4], const0_rtx);
2239: }
2240: }")
2241:
2242: (define_split
2243: [(set (pc)
2244: (if_then_else
2245: (match_operator 1 "comparison_operator"
2246: [(match_operand:SI 2 "reg_or_0_operand" "")
2247: (match_operand:SI 3 "const_int_operand" "")])
2248: (label_ref (match_operand 0 "" ""))
2249: (pc)))
2250: (clobber (match_operand:DI 4 "register_operand" ""))]
2251: "operands[3] != const0_rtx
2252: && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
2253: [(set (match_dup 4) (match_dup 5))
2254: (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
2255: "
2256: { rtx tem;
2257:
2258: if (GET_CODE (operands[3]) == CONST_INT)
2259: tem = gen_rtx (PLUS, SImode, operands[2],
2260: GEN_INT (- INTVAL (operands[3])));
2261: else
2262: tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
2263:
2264: operands[5] = gen_rtx (SIGN_EXTEND, DImode, tem);
2265: operands[6] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
2266: operands[4], const0_rtx);
2267: }")
2268:
2269: ;; Here are the CALL and unconditional branch insns.
2270:
2271: (define_expand "call"
2272: [(parallel [(call (mem:DI (match_dup 2))
2273: (match_operand 1 "" ""))
2274: (use (match_operand:DI 0 "" ""))
2275: (clobber (reg:DI 26))])]
2276: ""
2277: "
2278: { if (GET_CODE (operands[0]) != MEM)
2279: abort ();
2280: operands[0] = XEXP (operands[0], 0);
2281:
2282: operands[2] = gen_rtx (REG, DImode, 27);
2283: emit_move_insn (operands[2], operands[0]);
2284:
2285: if (GET_CODE (operands[0]) != SYMBOL_REF)
2286: operands[0] = const0_rtx;
2287: }")
2288:
2289: (define_expand "call_value"
2290: [(parallel [(set (match_operand 0 "" "")
2291: (call (mem:DI (match_dup 3))
2292: (match_operand 2 "" "")))
2293: (use (match_operand:DI 1 "" ""))
2294: (clobber (reg:DI 26))])]
2295: ""
2296: "
2297: { if (GET_CODE (operands[1]) != MEM)
2298: abort ();
2299:
2300: operands[1] = XEXP (operands[1], 0);
2301:
2302: operands[3] = gen_rtx (REG, DImode, 27);
2303: emit_move_insn (operands[3], operands[1]);
2304:
2305: if (GET_CODE (operands[1]) != SYMBOL_REF)
2306: operands[1] = const0_rtx;
2307: }")
2308:
2309: (define_insn ""
2310: [(call (mem:DI (reg:DI 27))
2311: (match_operand 0 "" ""))
2312: (use (match_operand:DI 1 "" ""))
2313: (clobber (reg:DI 26))]
2314: ""
2315: "jsr $26,($27),%1\;ldgp $29,0($26)"
2316: [(set_attr "type" "jsr")])
2317:
2318: (define_insn ""
2319: [(set (match_operand 0 "register_operand" "=rf")
2320: (call (mem:DI (reg:DI 27))
2321: (match_operand 1 "" "")))
2322: (use (match_operand:DI 2 "" ""))
2323: (clobber (reg:DI 26))]
2324: ""
2325: "jsr $26,($27),%2\;ldgp $29,0($26)"
2326: [(set_attr "type" "jsr")])
2327:
2328: (define_insn ""
2329: [(call (mem:DI (match_operand 1 "current_file_function_operand" "i"))
2330: (match_operand 0 "" ""))
2331: (use (match_dup 1))
2332: (clobber (reg:DI 26))]
2333: ""
2334: "bsr $26,%1..ng"
2335: [(set_attr "type" "ibr")])
2336:
2337: (define_insn ""
2338: [(set (match_operand 0 "register_operand" "=rf")
2339: (call (mem:DI (match_operand 1 "current_file_function_operand" "i"))
2340: (match_operand 2 "" "")))
2341: (use (match_dup 1))
2342: (clobber (reg:DI 26))]
2343: ""
2344: "bsr $26,%1..ng"
2345: [(set_attr "type" "ibr")])
2346:
2347: ;; Call subroutine returning any type.
2348:
2349: (define_expand "untyped_call"
2350: [(parallel [(call (match_operand 0 "" "")
2351: (const_int 0))
2352: (match_operand 1 "" "")
2353: (match_operand 2 "" "")])]
2354: ""
2355: "
2356: {
2357: int i;
2358:
2359: emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2360:
2361: for (i = 0; i < XVECLEN (operands[2], 0); i++)
2362: {
2363: rtx set = XVECEXP (operands[2], 0, i);
2364: emit_move_insn (SET_DEST (set), SET_SRC (set));
2365: }
2366:
2367: /* The optimizer does not know that the call sets the function value
2368: registers we stored in the result block. We avoid problems by
2369: claiming that all hard registers are used and clobbered at this
2370: point. */
2371: emit_insn (gen_blockage ());
2372:
2373: DONE;
2374: }")
2375:
2376: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2377: ;; all of memory. This blocks insns from being moved across this point.
2378:
2379: (define_insn "blockage"
2380: [(unspec_volatile [(const_int 0)] 1)]
2381: ""
2382: "")
2383:
2384: (define_insn "jump"
2385: [(set (pc)
2386: (label_ref (match_operand 0 "" "")))]
2387: ""
2388: "br $31,%l0"
2389: [(set_attr "type" "ibr")])
2390:
2391: (define_insn "return"
2392: [(return)]
2393: "direct_return ()"
2394: "ret $31,($26),1"
2395: [(set_attr "type" "ibr")])
2396:
2397: (define_insn "indirect_jump"
2398: [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
2399: ""
2400: "jmp $31,(%0),0"
2401: [(set_attr "type" "ibr")])
2402:
2403: (define_insn "nop"
2404: [(const_int 0)]
2405: ""
2406: "bis $31,$31,$31"
2407: [(set_attr "type" "iaddlog")])
2408:
2409: (define_expand "tablejump"
2410: [(set (match_dup 3)
2411: (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
2412: (parallel [(set (pc) (plus:DI (match_dup 3) (reg:DI 29)))
2413: (use (label_ref (match_operand 1 "" "")))
2414: (clobber (match_scratch:DI 2 "=r"))])]
2415: ""
2416: "
2417: { operands[3] = gen_reg_rtx (DImode); }")
2418:
2419: (define_insn ""
2420: [(set (pc)
2421: (plus:DI (match_operand:DI 0 "register_operand" "r")
2422: (reg:DI 29)))
2423: (use (label_ref (match_operand 1 "" "")))
2424: (clobber (match_scratch:DI 2 "=r"))]
2425: ""
2426: "*
2427: { rtx best_label = 0;
2428: rtx jump_table_insn = next_active_insn (operands[1]);
2429:
2430: if (GET_CODE (jump_table_insn) == JUMP_INSN
2431: && GET_CODE (PATTERN (jump_table_insn)) == ADDR_VEC)
2432: {
2433: rtx jump_table = PATTERN (jump_table_insn);
2434: int n_labels = XVECLEN (jump_table, 0);
2435: int best_count = -1;
2436: int i, j;
2437:
2438: for (i = 0; i < n_labels; i++)
2439: {
2440: int count = 1;
2441:
2442: for (j = i + 1; j < n_labels; j++)
2443: if (XEXP (XVECEXP (jump_table, 0, i), 0)
2444: == XEXP (XVECEXP (jump_table, 0, j), 0))
2445: count++;
2446:
2447: if (count > best_count)
2448: best_count = count, best_label = XVECEXP (jump_table, 0, i);
2449: }
2450: }
2451:
2452: if (best_label)
2453: {
2454: operands[3] = best_label;
2455: return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
2456: }
2457: else
2458: return \"addq %0,$29,%2\;jmp $31,(%2),0\";
2459: }"
2460: [(set_attr "type" "ibr")])
2461:
2462: ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't
2463: ;; want to have to include pal.h in our .s file.
2464: (define_insn ""
2465: [(unspec_volatile [(const_int 0)] 0)]
2466: ""
2467: "call_pal 0x86")
2468:
2469: ;; Finally, we have the basic data motion insns. The byte and word insns
2470: ;; are done via define_expand. Start with the floating-point insns, since
2471: ;; they are simpler.
2472:
2473: (define_insn ""
2474: [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
2475: (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
2476: "register_operand (operands[0], SFmode)
2477: || reg_or_fp0_operand (operands[1], SFmode)"
2478: "@
2479: bis %r1,%r1,%0
2480: ldl %0,%1
2481: stl %r1,%0
2482: cpys %1,%1,%0
2483: cpys $f31,$f31,%0
2484: lds %0,%1
2485: sts %R1,%0"
2486: [(set_attr "type" "iaddlog,ld,st,fpop,fpop,ld,st")])
2487:
2488: (define_insn ""
2489: [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
2490: (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
2491: "register_operand (operands[0], DFmode)
2492: || reg_or_fp0_operand (operands[1], DFmode)"
2493: "@
2494: bis %r1,%r1,%0
2495: ldq %0,%1
2496: stq %r1,%0
2497: cpys %1,%1,%0
2498: cpys $f31,$f31,%0
2499: ldt %0,%1
2500: stt %R1,%0"
2501: [(set_attr "type" "iaddlog,ld,st,fpop,fpop,ld,st")])
2502:
2503: (define_expand "movsf"
2504: [(set (match_operand:SF 0 "nonimmediate_operand" "")
2505: (match_operand:SF 1 "general_operand" ""))]
2506: ""
2507: "
2508: {
2509: if (GET_CODE (operands[0]) == MEM
2510: && ! reg_or_fp0_operand (operands[1], SFmode))
2511: operands[1] = force_reg (SFmode, operands[1]);
2512: }")
2513:
2514: (define_expand "movdf"
2515: [(set (match_operand:DF 0 "nonimmediate_operand" "")
2516: (match_operand:DF 1 "general_operand" ""))]
2517: ""
2518: "
2519: {
2520: if (GET_CODE (operands[0]) == MEM
2521: && ! reg_or_fp0_operand (operands[1], DFmode))
2522: operands[1] = force_reg (DFmode, operands[1]);
2523: }")
2524:
2525: ;; There is a problem with 32-bit values in FP registers. We keep such
2526: ;; values in the register as a quadword. This is done on loads by using
2527: ;; the cvtlq instruction. On stores, we can't do anything directly from
2528: ;; floating-point registers. Disallow such an operation and let reload
2529: ;; use an integer register instead. Don't encourage 32-bit values to
2530: ;; be placed in FP registers at all.
2531:
2532: (define_insn ""
2533: [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,*f")
2534: (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,*f,J,m"))]
2535: "register_operand (operands[0], SImode)
2536: || reg_or_0_operand (operands[1], SImode)"
2537: "@
2538: bis %1,%1,%0
2539: bis $31,$31,%0
2540: bis $31,%1,%0
2541: lda %0,%1
2542: ldah %0,%h1
2543: ldl %0,%1
2544: stl %r1,%0
2545: cpys %1,%1,%0
2546: cpys $f31,$f31,%0
2547: lds %0,%1\;cvtlq %0,%0"
2548: [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ld,st,fpop,fpop,ld")])
2549:
2550: (define_insn ""
2551: [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
2552: (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))]
2553: "register_operand (operands[0], HImode)
2554: || register_operand (operands[1], HImode)"
2555: "@
2556: bis %1,%1,%0
2557: bis $31,$31,%0
2558: bis $31,%1,%0
2559: lda %0,%L1
2560: cpys %1,%1,%0
2561: cpys $f31,$f31,%0"
2562: [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,fpop,fpop")])
2563:
2564: (define_insn ""
2565: [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
2566: (match_operand:QI 1 "input_operand" "r,J,I,n,f,J"))]
2567: "register_operand (operands[0], QImode)
2568: || register_operand (operands[1], QImode)"
2569: "@
2570: bis %1,%1,%0
2571: bis $31,$31,%0
2572: bis $31,%1,%0
2573: lda %0,%L1
2574: cpys %1,%1,%0
2575: cpys $f31,$f31,%0"
2576: [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,fpop,fpop")])
2577:
2578: ;; We do two major things here: handle mem->mem and construct long
2579: ;; constants.
2580:
2581: (define_expand "movsi"
2582: [(set (match_operand:SI 0 "general_operand" "")
2583: (match_operand:SI 1 "general_operand" ""))]
2584: ""
2585: "
2586: {
2587: if (GET_CODE (operands[0]) == MEM
2588: && ! reg_or_0_operand (operands[1], SImode))
2589: operands[1] = force_reg (SImode, operands[1]);
2590:
2591: if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2592: ;
2593: else if (GET_CODE (operands[1]) == CONST_INT)
2594: {
2595: if (alpha_emit_set_const (operands[0], INTVAL (operands[1]), 3))
2596: DONE;
2597: else
2598: abort ();
2599: }
2600: }")
2601:
2602: ;; Split a load of a large constant into the appropriate two-insn
2603: ;; sequence.
2604:
2605: (define_split
2606: [(set (match_operand:SI 0 "register_operand" "")
2607: (match_operand:SI 1 "const_int_operand" ""))]
2608: "! add_operand (operands[1], SImode)"
2609: [(set (match_dup 0) (match_dup 2))
2610: (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
2611: "
2612: { if (alpha_emit_set_const (operands[0], INTVAL (operands[1]), 2))
2613: DONE;
2614: else
2615: FAIL;
2616: }")
2617:
2618: (define_insn ""
2619: [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q")
2620: (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))]
2621: "register_operand (operands[0], DImode)
2622: || reg_or_0_operand (operands[1], DImode)"
2623: "@
2624: bis %1,%1,%0
2625: bis $31,$31,%0
2626: bis $31,%1,%0
2627: lda %0,%1
2628: ldah %0,%h1
2629: lda %0,%1
2630: ldq%A1 %0,%1
2631: stq%A0 %r1,%0
2632: cpys %1,%1,%0
2633: cpys $f31,$f31,%0
2634: ldt %0,%1
2635: stt %R1,%0"
2636: [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ldsym,ld,st,fpop,fpop,ld,st")])
2637:
2638: ;; We do three major things here: handle mem->mem, put 64-bit constants in
2639: ;; memory, and construct long 32-bit constants.
2640:
2641: (define_expand "movdi"
2642: [(set (match_operand:DI 0 "general_operand" "")
2643: (match_operand:DI 1 "general_operand" ""))]
2644: ""
2645: "
2646: {
2647: if (GET_CODE (operands[0]) == MEM
2648: && ! reg_or_0_operand (operands[1], DImode))
2649: operands[1] = force_reg (DImode, operands[1]);
2650:
2651: if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2652: ;
2653: else if (GET_CODE (operands[1]) == CONST_INT
2654: && alpha_emit_set_const (operands[0], INTVAL (operands[1]), 3))
2655: DONE;
2656: else if (CONSTANT_P (operands[1]))
2657: {
2658: operands[1] = force_const_mem (DImode, operands[1]);
2659: if (reload_in_progress)
2660: {
2661: emit_move_insn (operands[0], XEXP (operands[1], 0));
2662: XEXP (operands[1], 0) = operands[0];
2663: }
2664: else
2665: operands[1] = validize_mem (operands[1]);
2666: }
2667: else
2668: abort ();
2669: }")
2670:
2671: ;; Split a load of a large constant into the appropriate two-insn
2672: ;; sequence.
2673:
2674: (define_split
2675: [(set (match_operand:DI 0 "register_operand" "")
2676: (match_operand:DI 1 "const_int_operand" ""))]
2677: "! add_operand (operands[1], DImode)"
2678: [(set (match_dup 0) (match_dup 2))
2679: (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
2680: "
2681: { if (alpha_emit_set_const (operands[0], INTVAL (operands[1]), 2))
2682: DONE;
2683: else
2684: FAIL;
2685: }")
2686:
2687: ;; These are the partial-word cases.
2688: ;;
2689: ;; First we have the code to load an aligned word. Operand 0 is the register
2690: ;; in which to place the result. It's mode is QImode or HImode. Operand 1
2691: ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
2692: ;; number of bits within the word that the value is. Operand 3 is an SImode
2693: ;; scratch register. If operand 0 is a hard register, operand 3 may be the
2694: ;; same register. It is allowed to conflict with operand 1 as well.
2695:
2696: (define_expand "aligned_loadqi"
2697: [(set (match_operand:SI 3 "register_operand" "")
2698: (match_operand:SI 1 "memory_operand" ""))
2699: (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
2700: (zero_extract:DI (subreg:DI (match_dup 3) 0)
2701: (const_int 8)
2702: (match_operand:DI 2 "const_int_operand" "")))]
2703:
2704: ""
2705: "")
2706:
2707: (define_expand "aligned_loadhi"
2708: [(set (match_operand:SI 3 "register_operand" "")
2709: (match_operand:SI 1 "memory_operand" ""))
2710: (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
2711: (zero_extract:DI (subreg:DI (match_dup 3) 0)
2712: (const_int 16)
2713: (match_operand:DI 2 "const_int_operand" "")))]
2714:
2715: ""
2716: "")
2717:
2718: ;; Similar for unaligned loads. For QImode, we use the sequence from the
2719: ;; Alpha Architecture manual. However, for HImode, we do not. HImode pointers
2720: ;; are normally aligned to the byte boundary, so an HImode object cannot
2721: ;; cross a longword boundary. We could use a sequence similar to that for
2722: ;; QImode, but that would fail if the pointer, was, in fact, not aligned.
2723: ;; Instead, we clear bit 1 in the address and do an ldl. If the low-order
2724: ;; bit was not aligned, this will trap and the trap handler will do what is
2725: ;; needed.
2726: ;;
2727: ;; Here operand 1 is the address. Operands 2 and 3 are temporaries, where
2728: ;; operand 3 can overlap the input and output registers.
2729:
2730: (define_expand "unaligned_loadqi"
2731: [(set (match_operand:DI 2 "register_operand" "")
2732: (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
2733: (const_int -8))))
2734: (set (match_operand:DI 3 "register_operand" "")
2735: (match_dup 1))
2736: (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
2737: (zero_extract:DI (match_dup 2)
2738: (const_int 8)
2739: (ashift:DI (match_dup 3) (const_int 3))))]
2740: ""
2741: "")
2742:
2743: ;; For this, the address must already be in a register. We also need two
2744: ;; DImode temporaries, neither of which may overlap the input (and hence the
2745: ;; output, since they might be the same register), but both of which may
2746: ;; be the same.
2747:
2748: (define_expand "unaligned_loadhi"
2749: [(set (match_operand:DI 2 "register_operand" "")
2750: (and:DI (match_operand:DI 1 "register_operand" "")
2751: (const_int -7)))
2752: (set (match_operand:DI 3 "register_operand" "")
2753: (mem:DI (match_dup 2)))
2754: (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
2755: (zero_extract:DI (match_dup 3)
2756: (const_int 16)
2757: (ashift:DI (match_dup 1) (const_int 3))))]
2758: ""
2759: "")
2760:
2761: ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
2762: ;; aligned SImode MEM. Operand 1 is the register containing the
2763: ;; byte or word to store. Operand 2 is the number of bits within the word that
2764: ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
2765:
2766: (define_expand "aligned_store"
2767: [(set (match_operand:SI 3 "register_operand" "")
2768: (match_operand:SI 0 "memory_operand" ""))
2769: (set (subreg:DI (match_dup 3) 0)
2770: (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
2771: (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
2772: (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
2773: (match_operand:DI 2 "const_int_operand" "")))
2774: (set (subreg:DI (match_dup 4) 0)
2775: (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
2776: (set (match_dup 0) (match_dup 4))]
2777: ""
2778: "
2779: { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
2780: << INTVAL (operands[2])));
2781: }")
2782:
2783: ;; For the unaligned byte case, we use code similar to that in the
2784: ;; Architecture book, but reordered to lower the number of registers
2785: ;; required. Operand 0 is the address. Operand 1 is the data to store.
2786: ;; Operands 2, 3, and 4 are DImode temporaries, where the last two may
2787: ;; be the same temporary, if desired. If the address is in a register,
2788: ;; operand 2 can be that register.
2789:
2790: (define_expand "unaligned_storeqi"
2791: [(set (match_operand:DI 3 "register_operand" "")
2792: (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
2793: (const_int -8))))
2794: (set (match_operand:DI 2 "register_operand" "")
2795: (match_dup 0))
2796: (set (match_dup 3)
2797: (and:DI (ashift:DI (const_int 255)
2798: (ashift:DI (match_dup 2) (const_int 3)))
2799: (match_dup 3)))
2800: (set (match_operand:DI 4 "register_operand" "")
2801: (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
2802: (ashift:DI (match_dup 2) (const_int 3))))
2803: (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
2804: (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
2805: (match_dup 4))]
2806: ""
2807: "")
2808:
2809: ;; This is the code for storing into an unaligned short. It uses the same
2810: ;; trick as loading from an unaligned short. It needs lots of temporaries.
2811: ;; However, during reload, we only have two registers available. So we
2812: ;; repeat code so that only two temporaries are available. During RTL
2813: ;; generation, we can use different pseudos for each temporary and CSE
2814: ;; will remove the redundancies. During reload, we have to settle with
2815: ;; what we get. Luckily, unaligned accesses of this kind produced during
2816: ;; reload are quite rare.
2817: ;;
2818: ;; Operand 0 is the address of the memory location. Operand 1 contains the
2819: ;; data to store. The rest of the operands are all temporaries, with
2820: ;; various overlap possibilities during reload. See reload_outhi for
2821: ;; details of this use.
2822:
2823: (define_expand "unaligned_storehi"
2824: [(set (match_operand:DI 2 "register_operand" "")
2825: (match_operand:DI 0 "address_operand" ""))
2826: (set (match_operand:DI 3 "register_operand" "")
2827: (and:DI (match_dup 2) (const_int -7)))
2828: (set (match_operand:DI 4 "register_operand" "")
2829: (mem:DI (match_dup 3)))
2830: (set (match_operand:DI 5 "register_operand" "")
2831: (and:DI (ashift:DI (const_int 65535)
2832: (ashift:DI (match_dup 2) (const_int 3)))
2833: (match_dup 4)))
2834: (set (match_operand:DI 6 "register_operand" "")
2835: (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
2836: (ashift:DI (match_dup 2) (const_int 3))))
2837: (set (match_operand:DI 7 "register_operand" "")
2838: (ior:DI (match_dup 5) (match_dup 6)))
2839: (set (match_operand:DI 8 "register_operand" "") (match_dup 0))
2840: (set (match_operand:DI 9 "register_operand" "")
2841: (and:DI (match_dup 8) (const_int -7)))
2842: (set (mem:DI (match_dup 9)) (match_dup 7))]
2843: ""
2844: "")
2845:
2846: ;; Here are the define_expand's for QI and HI moves that use the above
2847: ;; patterns. We have the normal sets, plus the ones that need scratch
2848: ;; registers for reload.
2849:
2850: (define_expand "movqi"
2851: [(set (match_operand:QI 0 "general_operand" "")
2852: (match_operand:QI 1 "general_operand" ""))]
2853: ""
2854: "
2855: { extern rtx get_unaligned_address ();
2856:
2857: /* If the output is not a register, the input must be. */
2858: if (GET_CODE (operands[0]) == MEM)
2859: operands[1] = force_reg (QImode, operands[1]);
2860:
2861: /* Handle four memory cases, unaligned and aligned for either the input
2862: or the output. The only case where we can be called during reload is
2863: for aligned loads; all other cases require temporaries. */
2864:
2865: if (GET_CODE (operands[1]) == MEM
2866: || (GET_CODE (operands[1]) == SUBREG
2867: && GET_CODE (SUBREG_REG (operands[1])) == MEM)
2868: || (reload_in_progress && GET_CODE (operands[1]) == REG
2869: && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
2870: || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
2871: && GET_CODE (SUBREG_REG (operands[1])) == REG
2872: && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
2873: {
2874: if (aligned_memory_operand (operands[1], QImode))
2875: {
2876: rtx aligned_mem, bitnum;
2877: rtx scratch = (reload_in_progress
2878: ? gen_rtx (REG, SImode, REGNO (operands[0]))
2879: : gen_reg_rtx (SImode));
2880:
2881: get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2882:
2883: emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
2884: scratch));
2885: }
2886: else
2887: {
2888: /* Don't pass these as parameters since that makes the generated
2889: code depend on parameter evaluation order which will cause
2890: bootstrap failures. */
2891:
2892: rtx temp1 = gen_reg_rtx (DImode);
2893: rtx temp2 = gen_reg_rtx (DImode);
2894: rtx seq = gen_unaligned_loadqi (operands[0],
2895: get_unaligned_address (operands[1]),
2896: temp1, temp2);
2897:
2898: alpha_set_memflags (seq, operands[1]);
2899: emit_insn (seq);
2900: }
2901:
2902: DONE;
2903: }
2904:
2905: else if (GET_CODE (operands[0]) == MEM
2906: || (GET_CODE (operands[0]) == SUBREG
2907: && GET_CODE (SUBREG_REG (operands[0])) == MEM)
2908: || (reload_in_progress && GET_CODE (operands[0]) == REG
2909: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
2910: || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
2911: && GET_CODE (SUBREG_REG (operands[0])) == REG
2912: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
2913: {
2914: if (aligned_memory_operand (operands[0], QImode))
2915: {
2916: rtx aligned_mem, bitnum;
2917: rtx temp1 = gen_reg_rtx (SImode);
2918: rtx temp2 = gen_reg_rtx (SImode);
2919:
2920: get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2921:
2922: emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2923: temp1, temp2));
2924: }
2925: else
2926: {
2927: rtx temp1 = gen_reg_rtx (DImode);
2928: rtx temp2 = gen_reg_rtx (DImode);
2929: rtx temp3 = gen_reg_rtx (DImode);
2930: rtx seq = gen_unaligned_storeqi (get_unaligned_address (operands[0]),
2931: operands[1], temp1, temp2, temp3);
2932:
2933: alpha_set_memflags (seq, operands[0]);
2934: emit_insn (seq);
2935: }
2936: DONE;
2937: }
2938: }")
2939:
2940: (define_expand "movhi"
2941: [(set (match_operand:HI 0 "general_operand" "")
2942: (match_operand:HI 1 "general_operand" ""))]
2943: ""
2944: "
2945: { extern rtx get_unaligned_address ();
2946:
2947: /* If the output is not a register, the input must be. */
2948: if (GET_CODE (operands[0]) == MEM)
2949: operands[1] = force_reg (HImode, operands[1]);
2950:
2951: /* Handle four memory cases, unaligned and aligned for either the input
2952: or the output. The only case where we can be called during reload is
2953: for aligned loads; all other cases require temporaries. */
2954:
2955: if (GET_CODE (operands[1]) == MEM
2956: || (GET_CODE (operands[1]) == SUBREG
2957: && GET_CODE (SUBREG_REG (operands[1])) == MEM)
2958: || (reload_in_progress && GET_CODE (operands[1]) == REG
2959: && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
2960: || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
2961: && GET_CODE (SUBREG_REG (operands[1])) == REG
2962: && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
2963: {
2964: if (aligned_memory_operand (operands[1], HImode))
2965: {
2966: rtx aligned_mem, bitnum;
2967: rtx scratch = (reload_in_progress
2968: ? gen_rtx (REG, SImode, REGNO (operands[0]))
2969: : gen_reg_rtx (SImode));
2970:
2971: get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2972:
2973: emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
2974: scratch));
2975: }
2976: else
2977: {
2978: rtx addr
2979: = force_reg (DImode,
2980: force_operand (get_unaligned_address (operands[1]),
2981: NULL_RTX));
2982: rtx scratch1 = gen_reg_rtx (DImode);
2983: rtx scratch2 = gen_reg_rtx (DImode);
2984: rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch1,
2985: scratch2);
2986:
2987: alpha_set_memflags (seq, operands[1]);
2988: emit_insn (seq);
2989: }
2990:
2991: DONE;
2992: }
2993:
2994: else if (GET_CODE (operands[0]) == MEM
2995: || (GET_CODE (operands[0]) == SUBREG
2996: && GET_CODE (SUBREG_REG (operands[0])) == MEM)
2997: || (reload_in_progress && GET_CODE (operands[0]) == REG
2998: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
2999: || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
3000: && GET_CODE (SUBREG_REG (operands[0])) == REG
3001: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
3002: {
3003: if (aligned_memory_operand (operands[0], HImode))
3004: {
3005: rtx aligned_mem, bitnum;
3006: rtx temp1 = gen_reg_rtx (SImode);
3007: rtx temp2 = gen_reg_rtx (SImode);
3008:
3009: get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3010:
3011: emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3012: temp1, temp2));
3013: }
3014: else
3015: {
3016: rtx temp1 = gen_reg_rtx (DImode);
3017: rtx temp2 = gen_reg_rtx (DImode);
3018: rtx temp3 = gen_reg_rtx (DImode);
3019: rtx temp4 = gen_reg_rtx (DImode);
3020: rtx temp5 = gen_reg_rtx (DImode);
3021: rtx temp6 = gen_reg_rtx (DImode);
3022: rtx temp7 = gen_reg_rtx (DImode);
3023: rtx temp8 = gen_reg_rtx (DImode);
3024: rtx seq = gen_unaligned_storehi (get_unaligned_address (operands[0]),
3025: operands[1], temp1, temp2,temp3,
3026: temp4, temp5, temp6,temp7, temp8);
3027:
3028: alpha_set_memflags (seq, operands[0]);
3029: emit_insn (seq);
3030: }
3031:
3032: DONE;
3033: }
3034: }")
3035:
3036: ;; Here are the versions for reload. Note that in the unaligned cases
3037: ;; we know that the operand must not be a pseudo-register because stack
3038: ;; slots are always aligned references.
3039:
3040: (define_expand "reload_inqi"
3041: [(parallel [(match_operand:QI 0 "register_operand" "=r")
3042: (match_operand:QI 1 "unaligned_memory_operand" "m")
3043: (match_operand:DI 2 "register_operand" "=&r")])]
3044: ""
3045: "
3046: { extern rtx get_unaligned_address ();
3047: rtx addr = get_unaligned_address (operands[1]);
3048: rtx seq = gen_unaligned_loadqi (operands[0], addr, operands[2],
3049: gen_rtx (REG, DImode, REGNO (operands[0])));
3050:
3051: alpha_set_memflags (seq, operands[1]);
3052: emit_insn (seq);
3053: DONE;
3054: }")
3055:
3056: (define_expand "reload_inhi"
3057: [(parallel [(match_operand:HI 0 "register_operand" "=r")
3058: (match_operand:HI 1 "unaligned_memory_operand" "m")
3059: (match_operand:TI 2 "register_operand" "=&r")])]
3060: ""
3061: "
3062: { extern rtx get_unaligned_address ();
3063: rtx addr = get_unaligned_address (operands[1]);
3064: rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3065: rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3066: rtx seq;
3067:
3068: if (GET_CODE (addr) != REG)
3069: {
3070: emit_insn (gen_rtx (SET, VOIDmode, scratch2, addr));
3071: addr = scratch2;
3072: }
3073:
3074: seq = gen_unaligned_loadhi (operands[0], addr, scratch1, scratch1);
3075: alpha_set_memflags (seq, operands[1]);
3076: emit_insn (seq);
3077: DONE;
3078: }")
3079:
3080: (define_expand "reload_outqi"
3081: [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
3082: (match_operand:QI 1 "register_operand" "r")
3083: (match_operand:TI 2 "register_operand" "=&r")])]
3084: ""
3085: "
3086: { extern rtx get_unaligned_address ();
3087:
3088: if (aligned_memory_operand (operands[0], QImode))
3089: {
3090: rtx aligned_mem, bitnum;
3091:
3092: get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3093:
3094: emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3095: gen_rtx (REG, SImode, REGNO (operands[2])),
3096: gen_rtx (REG, SImode,
3097: REGNO (operands[2]) + 1)));
3098: }
3099: else
3100: {
3101: rtx addr = get_unaligned_address (operands[0]);
3102: rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3103: rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3104: rtx seq;
3105:
3106: if (GET_CODE (addr) == REG)
3107: scratch1 = addr;
3108:
3109: seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
3110: scratch2, scratch2);
3111: alpha_set_memflags (seq, operands[0]);
3112: emit_insn (seq);
3113: }
3114:
3115: DONE;
3116: }")
3117:
3118: (define_expand "reload_outhi"
3119: [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
3120: (match_operand:HI 1 "register_operand" "r")
3121: (match_operand:TI 2 "register_operand" "=&r")])]
3122: ""
3123: "
3124: { extern rtx get_unaligned_address ();
3125:
3126: if (aligned_memory_operand (operands[0], HImode))
3127: {
3128: rtx aligned_mem, bitnum;
3129:
3130: get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3131:
3132: emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3133: gen_rtx (REG, SImode, REGNO (operands[2])),
3134: gen_rtx (REG, SImode,
3135: REGNO (operands[2]) + 1)));
3136: }
3137: else
3138: {
3139: rtx addr = get_unaligned_address (operands[0]);
3140: rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3141: rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3142: rtx scratch_a = GET_CODE (addr) == REG ? addr : scratch1;
3143: rtx seq;
3144:
3145: seq = gen_unaligned_storehi (addr, operands[1], scratch_a,
3146: scratch2, scratch2, scratch2,
3147: scratch1, scratch2, scratch_a,
3148: scratch1);
3149: alpha_set_memflags (seq, operands[0]);
3150: emit_insn (seq);
3151: }
3152:
3153: DONE;
3154: }")
3155:
3156: ;; Subroutine of stack space allocation. Perform a stack probe.
3157: (define_expand "probe_stack"
3158: [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
3159: ""
3160: "
3161: {
3162: operands[0] = gen_rtx (MEM, DImode, plus_constant (stack_pointer_rtx,
3163: INTVAL (operands[0])));
3164: MEM_VOLATILE_P (operands[0]) = 1;
3165:
3166: operands[1] = gen_reg_rtx (DImode);
3167: }")
3168:
3169: ;; This is how we allocate stack space. If we are allocating a
3170: ;; constant amount of space and we know it is less than 4096
3171: ;; bytes, we need do nothing.
3172: ;;
3173: ;; If it is more than 4096 bytes, we need to probe the stack
3174: ;; periodically.
3175: (define_expand "allocate_stack"
3176: [(set (reg:DI 30)
3177: (plus:DI (reg:DI 30)
3178: (match_operand:DI 0 "reg_or_cint_operand" "")))]
3179: ""
3180: "
3181: {
3182: if (GET_CODE (operands[0]) == CONST_INT
3183: && INTVAL (operands[0]) < 32768)
3184: {
3185: if (INTVAL (operands[0]) >= 4096)
3186: {
3187: /* We do this the same way as in the prologue and generate explicit
3188: probes. Then we update the stack by the constant. */
3189:
3190: int probed = 4096;
3191:
3192: emit_insn (gen_probe_stack (GEN_INT (- probed)));
3193: while (probed + 8192 < INTVAL (operands[0]))
3194: emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
3195:
3196: if (probed + 4096 < INTVAL (operands[0]))
3197: emit_insn (gen_probe_stack (GEN_INT (- (probed += 4096))));
3198: }
3199:
3200: operands[0] = GEN_INT (- INTVAL (operands[0]));
3201: }
3202: else
3203: {
3204: rtx out_label = 0;
3205: rtx loop_label = gen_label_rtx ();
3206: rtx count = gen_reg_rtx (DImode);
3207: rtx access = gen_reg_rtx (Pmode);
3208: rtx memref = gen_rtx (MEM, DImode, access);
3209:
3210: MEM_VOLATILE_P (memref) = 1;
3211:
3212: /* If the amount to be allocated is not a constant, we only need to
3213: do something special if it is >= 4096. */
3214:
3215: if (GET_CODE (operands[0]) != CONST_INT)
3216: {
3217: operands[0] = force_reg (DImode, operands[0]);
3218: out_label = gen_label_rtx ();
3219: emit_insn (gen_cmpdi (operands[0],
3220: force_reg (DImode, GEN_INT (4096))));
3221: emit_jump_insn (gen_ble (out_label));
3222:
3223: /* Compute COUNT = (N + 4096) / 8192. N is known positive. */
3224: emit_insn (gen_adddi3 (count, operands[0], GEN_INT (4096)));
3225: emit_insn (gen_lshrdi3 (count, count, GEN_INT (13)));
3226: }
3227: else
3228: emit_move_insn (count, GEN_INT ((INTVAL (operands[0]) + 4096) >> 13));
3229:
3230: /* ACCESS = SP + 4096. */
3231: emit_insn (gen_adddi3 (access, stack_pointer_rtx, GEN_INT (4096)));
3232: emit_label (loop_label);
3233:
3234: /* Each iteration subtracts 8192 from ACCESS and references it. */
3235: emit_insn (gen_adddi3 (count, count, constm1_rtx));
3236: emit_insn (gen_adddi3 (access, access, GEN_INT (-8192)));
3237: emit_move_insn (gen_reg_rtx (DImode), memref);
3238: emit_insn (gen_cmpdi (count, const0_rtx));
3239: emit_jump_insn (gen_bgt (loop_label));
3240:
3241: if (out_label)
3242: emit_label (out_label);
3243:
3244: /* We need to subtract operands[0] from SP. We know it isn't a
3245: constant less than 32768, so we know we have to load it into
3246: a register. */
3247:
3248: emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
3249: force_reg (Pmode, operands[0])));
3250:
3251: /* Now, unless we have a constant and we know that we are within
3252: 4096 from the end, we need to access sp + 4096. */
3253: if (! (GET_CODE (operands[0]) == CONST_INT
3254: && (INTVAL (operands[0]) % 8192) < 4096))
3255: emit_insn (gen_probe_stack (GEN_INT (4096)));
3256:
3257: DONE;
3258: }
3259: }")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.