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