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