({zero_,}extend[qh]i[dsh]i2): Rework TARGET_BYTE_OPS cases.
[gcc.git] / gcc / config / alpha / alpha.md
1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
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, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 \f
24 ;; Processor type -- this attribute must exactly match the processor_type
25 ;; enumeration in alpha.h.
26
27 (define_attr "cpu" "ev4,ev5"
28 (const (symbol_ref "alpha_cpu")))
29
30 ;; Define an insn type attribute. This is used in function unit delay
31 ;; computations, among other purposes. For the most part, we use the names
32 ;; defined in the EV4 documentation, but add a few that we have to know about
33 ;; separately.
34
35 (define_attr "type"
36 "ld,st,ibr,fbr,jsr,iadd,ilog,shift,cmov,icmp,imull,imulq,fadd,fmul,fcpys,fdivs,fdivt,ldsym,isubr"
37 (const_string "iadd"))
38
39 ;; The TRAP_TYPE attribute marks instructions that may generate traps
40 ;; (which are imprecise and may need a trapb if software complention
41 ;; is desired).
42 (define_attr "trap" "yes,no" (const_string "no"))
43
44 ;; For the EV4 we include four function units: ABOX, which computes the address,
45 ;; BBOX, used for branches, EBOX, used for integer operations, and FBOX,
46 ;; used for FP operations.
47 ;;
48 ;; We assume that we have been successful in getting double issues and
49 ;; hence multiply all costs by two insns per cycle. The minimum time in
50 ;; a function unit is 2 cycle, which will tend to produce the double
51 ;; issues.
52
53 ;; Memory delivers its result in three cycles.
54 (define_function_unit "ev4_abox" 1 0
55 (and (eq_attr "cpu" "ev4")
56 (eq_attr "type" "ld,st"))
57 6 2)
58
59 ;; Branches have no delay cost, but do tie up the unit for two cycles.
60 (define_function_unit "ev4_bbox" 1 1
61 (and (eq_attr "cpu" "ev4")
62 (eq_attr "type" "ibr,fbr,jsr"))
63 4 4)
64
65 ;; Arithmetic insns are normally have their results available after two
66 ;; cycles. There are a number of exceptions. They are encoded in
67 ;; ADJUST_COST. Some of the other insns have similar exceptions.
68
69 (define_function_unit "ev4_ebox" 1 0
70 (and (eq_attr "cpu" "ev4")
71 (eq_attr "type" "iadd,ilog,ldsym,shift,cmov,icmp"))
72 4 2)
73
74 ;; These really don't take up the integer pipeline, but they do occupy
75 ;; IBOX1; we approximate here.
76
77 (define_function_unit "ev4_ebox" 1 0
78 (and (eq_attr "cpu" "ev4")
79 (eq_attr "type" "imull"))
80 42 2)
81
82 (define_function_unit "ev4_ebox" 1 0
83 (and (eq_attr "cpu" "ev4")
84 (eq_attr "type" "imulq"))
85 46 2)
86
87 (define_function_unit "ev4_imult" 1 0
88 (and (eq_attr "cpu" "ev4")
89 (eq_attr "type" "imull"))
90 42 38)
91
92 (define_function_unit "ev4_imult" 1 0
93 (and (eq_attr "cpu" "ev4")
94 (eq_attr "type" "imulq"))
95 46 42)
96
97 (define_function_unit "ev4_fbox" 1 0
98 (and (eq_attr "cpu" "ev4")
99 (eq_attr "type" "fadd,fmul,fcpys"))
100 12 2)
101
102 (define_function_unit "ev4_fbox" 1 0
103 (and (eq_attr "cpu" "ev4")
104 (eq_attr "type" "fdivs"))
105 68 0)
106
107 (define_function_unit "ev4_fbox" 1 0
108 (and (eq_attr "cpu" "ev4")
109 (eq_attr "type" "fdivt"))
110 126 0)
111
112 (define_function_unit "ev4_divider" 1 0
113 (and (eq_attr "cpu" "ev4")
114 (eq_attr "type" "fdivs"))
115 68 60)
116
117 (define_function_unit "ev4_divider" 1 0
118 (and (eq_attr "cpu" "ev4")
119 (eq_attr "type" "fdivt"))
120 126 118)
121 \f
122 ;; EV5 scheduling. EV5 can issue 4 insns per clock.
123 ;; Multiply all costs by 4.
124
125 ;; EV5 has two integer units.
126 (define_function_unit "ev5_ebox" 2 0
127 (and (eq_attr "cpu" "ev5")
128 (eq_attr "type" "iadd,ilog,icmp,ldsym"))
129 4 4)
130
131 ;; Memory takes at least 2 clocks.
132 ;; Conditional moves always take 2 ticks.
133 (define_function_unit "ev5_ebox" 2 0
134 (and (eq_attr "cpu" "ev5")
135 (eq_attr "type" "ld,cmov"))
136 8 4)
137
138 ;; Loads can dual issue. Store cannot; nor can loads + stores.
139 ;; Model this with a mythical load/store unit.
140 (define_function_unit "ev5_ldst" 1 0
141 (and (eq_attr "cpu" "ev5")
142 (eq_attr "type" "ld"))
143 8 4 [(eq_attr "type" "st")])
144
145 (define_function_unit "ev5_ldst" 1 0
146 (and (eq_attr "cpu" "ev5")
147 (eq_attr "type" "st"))
148 4 4)
149
150 (define_function_unit "ev5_ebox" 2 0
151 (and (eq_attr "cpu" "ev5")
152 (eq_attr "type" "imull"))
153 32 4)
154
155 (define_function_unit "ev5_ebox" 2 0
156 (and (eq_attr "cpu" "ev5")
157 (eq_attr "type" "imulq"))
158 48 4)
159
160 ;; Multiplies also use the integer multiplier.
161 (define_function_unit "ev5_imult" 1 0
162 (and (eq_attr "cpu" "ev5")
163 (eq_attr "type" "imull"))
164 16 8)
165
166 (define_function_unit "ev5_imult" 1 0
167 (and (eq_attr "cpu" "ev5")
168 (eq_attr "type" "imulq"))
169 48 32)
170
171 ;; There is only 1 shifter/zapper.
172 (define_function_unit "ev5_shift" 1 0
173 (and (eq_attr "cpu" "ev5")
174 (eq_attr "type" "shift"))
175 4 4)
176
177 ;; We pretend EV5 has symmetrical 2 fpus,
178 ;; even though cpys is the only insn that can issue on either unit.
179 (define_function_unit "ev5_fpu" 2 0
180 (and (eq_attr "cpu" "ev5")
181 (eq_attr "type" "fadd,fmul,fcpys"))
182 16 4)
183
184 ;; Multiplies (resp. adds) also use the fmul (resp. fadd) units.
185 (define_function_unit "ev5_fpmul" 1 0
186 (and (eq_attr "cpu" "ev5")
187 (eq_attr "type" "fmul"))
188 16 4)
189
190 (define_function_unit "ev5_fpadd" 1 0
191 (and (eq_attr "cpu" "ev5")
192 (eq_attr "type" "fadd"))
193 16 4)
194
195 (define_function_unit "ev5_fpadd" 1 0
196 (and (eq_attr "cpu" "ev5")
197 (eq_attr "type" "fbr"))
198 4 4)
199
200 (define_function_unit "ev5_fpadd" 1 0
201 (and (eq_attr "cpu" "ev5")
202 (eq_attr "type" "fdivs"))
203 60 4)
204
205 (define_function_unit "ev5_fpadd" 1 0
206 (and (eq_attr "cpu" "ev5")
207 (eq_attr "type" "fdivt"))
208 88 4)
209 \f
210 ;; First define the arithmetic insns. Note that the 32-bit forms also
211 ;; sign-extend.
212
213 ;; Note that we can do sign extensions in both FP and integer registers.
214 ;; However, the result must be in the same type of register as the input.
215 ;; The register preferencing code can't handle this case very well, so, for
216 ;; now, don't let the FP case show up here for preferencing. Also,
217 ;; sign-extends in FP registers take two instructions.
218 (define_insn "extendsidi2"
219 [(set (match_operand:DI 0 "register_operand" "=r,r,*f")
220 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,*f")))]
221 ""
222 "@
223 addl %1,$31,%0
224 ldl %0,%1
225 cvtql %1,%0\;cvtlq %0,%0"
226 [(set_attr "type" "iadd,ld,fadd")])
227
228 ;; Do addsi3 the way expand_binop would do if we didn't have one. This
229 ;; generates better code. We have the anonymous addsi3 pattern below in
230 ;; case combine wants to make it.
231 (define_expand "addsi3"
232 [(set (match_operand:SI 0 "register_operand" "")
233 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
234 (match_operand:SI 2 "add_operand" "")))]
235 ""
236 "
237 { emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]),
238 gen_rtx (PLUS, DImode,
239 gen_lowpart (DImode, operands[1]),
240 gen_lowpart (DImode, operands[2]))));
241 DONE;
242 } ")
243
244 (define_insn ""
245 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
246 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
247 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
248 ""
249 "@
250 addl %r1,%2,%0
251 subl %r1,%n2,%0
252 lda %0,%2(%r1)
253 ldah %0,%h2(%r1)")
254
255 (define_split
256 [(set (match_operand:SI 0 "register_operand" "")
257 (plus:SI (match_operand:SI 1 "register_operand" "")
258 (match_operand:SI 2 "const_int_operand" "")))]
259 "! add_operand (operands[2], SImode)"
260 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
261 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
262 "
263 {
264 HOST_WIDE_INT val = INTVAL (operands[2]);
265 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
266 HOST_WIDE_INT rest = val - low;
267
268 operands[3] = GEN_INT (rest);
269 operands[4] = GEN_INT (low);
270 }")
271
272 (define_insn ""
273 [(set (match_operand:DI 0 "register_operand" "=r,r")
274 (sign_extend:DI
275 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
276 (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
277 ""
278 "@
279 addl %r1,%2,%0
280 subl %r1,%n2,%0")
281
282 (define_split
283 [(set (match_operand:DI 0 "register_operand" "")
284 (sign_extend:DI
285 (plus:SI (match_operand:SI 1 "register_operand" "")
286 (match_operand:SI 2 "const_int_operand" ""))))
287 (clobber (match_operand:SI 3 "register_operand" ""))]
288 "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
289 && INTVAL (operands[2]) % 4 == 0"
290 [(set (match_dup 3) (match_dup 4))
291 (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
292 (match_dup 5))
293 (match_dup 1))))]
294 "
295 {
296 HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
297 int mult = 4;
298
299 if (val % 2 == 0)
300 val /= 2, mult = 8;
301
302 operands[4] = GEN_INT (val);
303 operands[5] = GEN_INT (mult);
304 }")
305
306 (define_split
307 [(set (match_operand:DI 0 "register_operand" "")
308 (sign_extend:DI
309 (plus:SI (match_operator:SI 1 "comparison_operator"
310 [(match_operand 2 "" "")
311 (match_operand 3 "" "")])
312 (match_operand:SI 4 "add_operand" ""))))
313 (clobber (match_operand:DI 5 "register_operand" ""))]
314 ""
315 [(set (match_dup 5) (match_dup 6))
316 (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
317 "
318 {
319 operands[6] = gen_rtx (GET_CODE (operands[1]), DImode,
320 operands[2], operands[3]);
321 operands[7] = gen_lowpart (SImode, operands[5]);
322 }")
323
324 (define_insn "adddi3"
325 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
326 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
327 (match_operand:DI 2 "add_operand" "rI,O,K,L")))]
328 ""
329 "@
330 addq %r1,%2,%0
331 subq %r1,%n2,%0
332 lda %0,%2(%r1)
333 ldah %0,%h2(%r1)")
334
335 ;; Don't do this if we are adjusting SP since we don't want to do
336 ;; it in two steps.
337 (define_split
338 [(set (match_operand:DI 0 "register_operand" "")
339 (plus:DI (match_operand:DI 1 "register_operand" "")
340 (match_operand:DI 2 "const_int_operand" "")))]
341 "! add_operand (operands[2], DImode)
342 && REGNO (operands[0]) != STACK_POINTER_REGNUM"
343 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
344 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
345 "
346 {
347 HOST_WIDE_INT val = INTVAL (operands[2]);
348 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
349 HOST_WIDE_INT rest = val - low;
350
351 operands[3] = GEN_INT (rest);
352 operands[4] = GEN_INT (low);
353 }")
354
355 (define_insn ""
356 [(set (match_operand:SI 0 "register_operand" "=r,r")
357 (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
358 (match_operand:SI 2 "const48_operand" "I,I"))
359 (match_operand:SI 3 "sext_add_operand" "rI,O")))]
360 ""
361 "@
362 s%2addl %r1,%3,%0
363 s%2subl %r1,%n3,%0")
364
365 (define_insn ""
366 [(set (match_operand:DI 0 "register_operand" "=r,r")
367 (sign_extend:DI
368 (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
369 (match_operand:SI 2 "const48_operand" "I,I"))
370 (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
371 ""
372 "@
373 s%2addl %r1,%3,%0
374 s%2subl %r1,%n3,%0")
375
376 (define_split
377 [(set (match_operand:DI 0 "register_operand" "")
378 (sign_extend:DI
379 (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
380 [(match_operand 2 "" "")
381 (match_operand 3 "" "")])
382 (match_operand:SI 4 "const48_operand" ""))
383 (match_operand:SI 5 "add_operand" ""))))
384 (clobber (match_operand:DI 6 "register_operand" ""))]
385 ""
386 [(set (match_dup 6) (match_dup 7))
387 (set (match_dup 0)
388 (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
389 (match_dup 5))))]
390 "
391 {
392 operands[7] = gen_rtx (GET_CODE (operands[1]), DImode,
393 operands[2], operands[3]);
394 operands[8] = gen_lowpart (SImode, operands[6]);
395 }")
396
397 (define_insn ""
398 [(set (match_operand:DI 0 "register_operand" "=r,r")
399 (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
400 (match_operand:DI 2 "const48_operand" "I,I"))
401 (match_operand:DI 3 "reg_or_8bit_operand" "rI,O")))]
402 ""
403 "@
404 s%2addq %r1,%3,%0
405 s%2subq %1,%n3,%0")
406
407 ;; These variants of the above insns can occur if the third operand
408 ;; is the frame pointer. This is a kludge, but there doesn't
409 ;; seem to be a way around it. Only recognize them while reloading.
410
411 (define_insn ""
412 [(set (match_operand:DI 0 "some_operand" "=&r")
413 (plus:DI (plus:DI (match_operand:DI 1 "some_operand" "r")
414 (match_operand:DI 2 "some_operand" "r"))
415 (match_operand:DI 3 "some_operand" "rIOKL")))]
416 "reload_in_progress"
417 "#")
418
419 (define_split
420 [(set (match_operand:DI 0 "register_operand" "")
421 (plus:DI (plus:DI (match_operand:DI 1 "register_operand" "")
422 (match_operand:DI 2 "register_operand" ""))
423 (match_operand:DI 3 "add_operand" "")))]
424 "reload_completed"
425 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
426 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
427 "")
428
429 (define_insn ""
430 [(set (match_operand:SI 0 "some_operand" "=&r")
431 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "some_operand" "rJ")
432 (match_operand:SI 2 "const48_operand" "I"))
433 (match_operand:SI 3 "some_operand" "r"))
434 (match_operand:SI 4 "some_operand" "rIOKL")))]
435 "reload_in_progress"
436 "#")
437
438 (define_split
439 [(set (match_operand:SI 0 "register_operand" "r")
440 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
441 (match_operand:SI 2 "const48_operand" ""))
442 (match_operand:SI 3 "register_operand" ""))
443 (match_operand:SI 4 "add_operand" "rIOKL")))]
444 "reload_completed"
445 [(set (match_dup 0)
446 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
447 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
448 "")
449
450 (define_insn ""
451 [(set (match_operand:DI 0 "some_operand" "=&r")
452 (sign_extend:DI
453 (plus:SI (plus:SI
454 (mult:SI (match_operand:SI 1 "some_operand" "rJ")
455 (match_operand:SI 2 "const48_operand" "I"))
456 (match_operand:SI 3 "some_operand" "r"))
457 (match_operand:SI 4 "some_operand" "rIOKL"))))]
458 "reload_in_progress"
459 "#")
460
461 (define_split
462 [(set (match_operand:DI 0 "register_operand" "")
463 (sign_extend:DI
464 (plus:SI (plus:SI
465 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
466 (match_operand:SI 2 "const48_operand" ""))
467 (match_operand:SI 3 "register_operand" ""))
468 (match_operand:SI 4 "add_operand" ""))))]
469 "reload_completed"
470 [(set (match_dup 5)
471 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
472 (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))]
473 "
474 { operands[5] = gen_lowpart (SImode, operands[0]);
475 }")
476
477 (define_insn ""
478 [(set (match_operand:DI 0 "some_operand" "=&r")
479 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "some_operand" "rJ")
480 (match_operand:DI 2 "const48_operand" "I"))
481 (match_operand:DI 3 "some_operand" "r"))
482 (match_operand:DI 4 "some_operand" "rIOKL")))]
483 "reload_in_progress"
484 "#")
485
486 (define_split
487 [(set (match_operand:DI 0 "register_operand" "=")
488 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "")
489 (match_operand:DI 2 "const48_operand" ""))
490 (match_operand:DI 3 "register_operand" ""))
491 (match_operand:DI 4 "add_operand" "")))]
492 "reload_completed"
493 [(set (match_dup 0)
494 (plus:DI (mult:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
495 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
496 "")
497
498 (define_insn "negsi2"
499 [(set (match_operand:SI 0 "register_operand" "=r")
500 (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
501 ""
502 "subl $31,%1,%0")
503
504 (define_insn ""
505 [(set (match_operand:DI 0 "register_operand" "=r")
506 (sign_extend:DI (neg:SI
507 (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
508 ""
509 "subl $31,%1,%0")
510
511 (define_insn "negdi2"
512 [(set (match_operand:DI 0 "register_operand" "=r")
513 (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
514 ""
515 "subq $31,%1,%0")
516
517 (define_expand "subsi3"
518 [(set (match_operand:SI 0 "register_operand" "")
519 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
520 (match_operand:SI 2 "reg_or_8bit_operand" "")))]
521 ""
522 "
523 { emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]),
524 gen_rtx (MINUS, DImode,
525 gen_lowpart (DImode, operands[1]),
526 gen_lowpart (DImode, operands[2]))));
527 DONE;
528
529 } ")
530
531 (define_insn ""
532 [(set (match_operand:SI 0 "register_operand" "=r")
533 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
534 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
535 ""
536 "subl %r1,%2,%0")
537
538 (define_insn ""
539 [(set (match_operand:DI 0 "register_operand" "=r")
540 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
541 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
542 ""
543 "subl %r1,%2,%0")
544
545 (define_insn "subdi3"
546 [(set (match_operand:DI 0 "register_operand" "=r")
547 (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
548 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
549 ""
550 "subq %r1,%2,%0")
551
552 (define_insn ""
553 [(set (match_operand:SI 0 "register_operand" "=r")
554 (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
555 (match_operand:SI 2 "const48_operand" "I"))
556 (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
557 ""
558 "s%2subl %r1,%3,%0")
559
560 (define_insn ""
561 [(set (match_operand:DI 0 "register_operand" "=r")
562 (sign_extend:DI
563 (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
564 (match_operand:SI 2 "const48_operand" "I"))
565 (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
566 ""
567 "s%2subl %r1,%3,%0")
568
569 (define_insn ""
570 [(set (match_operand:DI 0 "register_operand" "=r")
571 (minus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
572 (match_operand:DI 2 "const48_operand" "I"))
573 (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
574 ""
575 "s%2subq %r1,%3,%0")
576
577 (define_insn "mulsi3"
578 [(set (match_operand:SI 0 "register_operand" "=r")
579 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
580 (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
581 ""
582 "mull %r1,%r2,%0"
583 [(set_attr "type" "imull")])
584
585 (define_insn ""
586 [(set (match_operand:DI 0 "register_operand" "=r")
587 (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
588 (match_operand:SI 2 "reg_or_0_operand" "rJ"))))]
589 ""
590 "mull %r1,%r2,%0"
591 [(set_attr "type" "imull")])
592
593 (define_insn "muldi3"
594 [(set (match_operand:DI 0 "register_operand" "=r")
595 (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
596 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
597 ""
598 "mulq %r1,%r2,%0"
599 [(set_attr "type" "imulq")])
600
601 (define_insn "umuldi3_highpart"
602 [(set (match_operand:DI 0 "register_operand" "=r")
603 (truncate:DI
604 (lshiftrt:TI
605 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
606 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
607 (const_int 64))))]
608 ""
609 "umulh %1,%2,%0"
610 [(set_attr "type" "imulq")])
611
612 (define_insn ""
613 [(set (match_operand:DI 0 "register_operand" "=r")
614 (truncate:DI
615 (lshiftrt:TI
616 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
617 (match_operand:TI 2 "cint8_operand" "I"))
618 (const_int 64))))]
619 ""
620 "umulh %1,%2,%0"
621 [(set_attr "type" "imulq")])
622 \f
623 ;; The divide and remainder operations always take their inputs from
624 ;; r24 and r25, put their output in r27, and clobber r23 and r28.
625
626 ;; ??? comment out the divsi routines since the library functions
627 ;; don't seem to do the right thing with the high 32-bits of a
628 ;; register nonzero.
629
630 ;(define_expand "divsi3"
631 ; [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
632 ; (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
633 ; (parallel [(set (reg:SI 27)
634 ; (div:SI (reg:SI 24)
635 ; (reg:SI 25)))
636 ; (clobber (reg:DI 23))
637 ; (clobber (reg:DI 28))])
638 ; (set (match_operand:SI 0 "general_operand" "")
639 ; (reg:SI 27))]
640 ; "!TARGET_OPEN_VMS"
641 ; "")
642
643 ;(define_expand "udivsi3"
644 ; [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
645 ; (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
646 ; (parallel [(set (reg:SI 27)
647 ; (udiv:SI (reg:SI 24)
648 ; (reg:SI 25)))
649 ; (clobber (reg:DI 23))
650 ; (clobber (reg:DI 28))])
651 ; (set (match_operand:SI 0 "general_operand" "")
652 ; (reg:SI 27))]
653 ; "!TARGET_OPEN_VMS"
654 ; "")
655
656 ;(define_expand "modsi3"
657 ; [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
658 ; (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
659 ; (parallel [(set (reg:SI 27)
660 ; (mod:SI (reg:SI 24)
661 ; (reg:SI 25)))
662 ; (clobber (reg:DI 23))
663 ; (clobber (reg:DI 28))])
664 ; (set (match_operand:SI 0 "general_operand" "")
665 ; (reg:SI 27))]
666 ; "!TARGET_OPEN_VMS"
667 ; "")
668
669 ;(define_expand "umodsi3"
670 ; [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
671 ; (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
672 ; (parallel [(set (reg:SI 27)
673 ; (umod:SI (reg:SI 24)
674 ; (reg:SI 25)))
675 ; (clobber (reg:DI 23))
676 ; (clobber (reg:DI 28))])
677 ; (set (match_operand:SI 0 "general_operand" "")
678 ; (reg:SI 27))]
679 ; "!TARGET_OPEN_VMS"
680 ; "")
681
682 (define_expand "divdi3"
683 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
684 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
685 (parallel [(set (reg:DI 27)
686 (div:DI (reg:DI 24)
687 (reg:DI 25)))
688 (clobber (reg:DI 23))
689 (clobber (reg:DI 28))])
690 (set (match_operand:DI 0 "general_operand" "")
691 (reg:DI 27))]
692 "!TARGET_OPEN_VMS"
693 "")
694
695 (define_expand "udivdi3"
696 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
697 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
698 (parallel [(set (reg:DI 27)
699 (udiv:DI (reg:DI 24)
700 (reg:DI 25)))
701 (clobber (reg:DI 23))
702 (clobber (reg:DI 28))])
703 (set (match_operand:DI 0 "general_operand" "")
704 (reg:DI 27))]
705 "!TARGET_OPEN_VMS"
706 "")
707
708 (define_expand "moddi3"
709 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
710 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
711 (parallel [(set (reg:DI 27)
712 (mod:DI (reg:DI 24)
713 (reg:DI 25)))
714 (clobber (reg:DI 23))
715 (clobber (reg:DI 28))])
716 (set (match_operand:DI 0 "general_operand" "")
717 (reg:DI 27))]
718 "!TARGET_OPEN_VMS"
719 "")
720
721 (define_expand "umoddi3"
722 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
723 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
724 (parallel [(set (reg:DI 27)
725 (umod:DI (reg:DI 24)
726 (reg:DI 25)))
727 (clobber (reg:DI 23))
728 (clobber (reg:DI 28))])
729 (set (match_operand:DI 0 "general_operand" "")
730 (reg:DI 27))]
731 "!TARGET_OPEN_VMS"
732 "")
733
734 ;(define_insn ""
735 ; [(set (reg:SI 27)
736 ; (match_operator:SI 1 "divmod_operator"
737 ; [(reg:SI 24) (reg:SI 25)]))
738 ; (clobber (reg:DI 23))
739 ; (clobber (reg:DI 28))]
740 ; "!TARGET_OPEN_VMS"
741 ; "%E1 $24,$25,$27"
742 ; [(set_attr "type" "isubr")])
743
744 (define_insn ""
745 [(set (reg:DI 27)
746 (match_operator:DI 1 "divmod_operator"
747 [(reg:DI 24) (reg:DI 25)]))
748 (clobber (reg:DI 23))
749 (clobber (reg:DI 28))]
750 "!TARGET_OPEN_VMS"
751 "%E1 $24,$25,$27"
752 [(set_attr "type" "isubr")])
753 \f
754 ;; Next are the basic logical operations. These only exist in DImode.
755
756 (define_insn "anddi3"
757 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
758 (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
759 (match_operand:DI 2 "and_operand" "rI,N,MH")))]
760 ""
761 "@
762 and %r1,%2,%0
763 bic %r1,%N2,%0
764 zapnot %r1,%m2,%0"
765 [(set_attr "type" "ilog,ilog,shift")])
766
767 ;; There are times when we can split an AND into two AND insns. This occurs
768 ;; when we can first clear any bytes and then clear anything else. For
769 ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
770 ;; Only do this when running on 64-bit host since the computations are
771 ;; too messy otherwise.
772
773 (define_split
774 [(set (match_operand:DI 0 "register_operand" "")
775 (and:DI (match_operand:DI 1 "register_operand" "")
776 (match_operand:DI 2 "const_int_operand" "")))]
777 "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
778 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
779 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
780 "
781 {
782 unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
783 unsigned HOST_WIDE_INT mask2 = mask1;
784 int i;
785
786 /* For each byte that isn't all zeros, make it all ones. */
787 for (i = 0; i < 64; i += 8)
788 if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
789 mask1 |= (HOST_WIDE_INT) 0xff << i;
790
791 /* Now turn on any bits we've just turned off. */
792 mask2 |= ~ mask1;
793
794 operands[3] = GEN_INT (mask1);
795 operands[4] = GEN_INT (mask2);
796 }")
797
798 (define_insn "zero_extendqihi2"
799 [(set (match_operand:HI 0 "register_operand" "=r")
800 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
801 ""
802 "zapnot %1,1,%0"
803 [(set_attr "type" "shift")])
804
805 (define_insn ""
806 [(set (match_operand:SI 0 "register_operand" "=r,r")
807 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
808 "TARGET_BYTE_OPS"
809 "@
810 zapnot %1,1,%0
811 ldbu %0,%1"
812 [(set_attr "type" "shift,ld")])
813
814 (define_insn ""
815 [(set (match_operand:SI 0 "register_operand" "=r")
816 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
817 "! TARGET_BYTE_OPS"
818 "zapnot %1,1,%0"
819 [(set_attr "type" "shift")])
820
821 (define_expand "zero_extendqisi2"
822 [(set (match_operand:SI 0 "register_operand" "")
823 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
824 ""
825 "")
826
827 (define_insn ""
828 [(set (match_operand:DI 0 "register_operand" "=r,r")
829 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
830 "TARGET_BYTE_OPS"
831 "@
832 zapnot %1,1,%0
833 ldbu %0,%1"
834 [(set_attr "type" "shift,ld")])
835
836 (define_insn ""
837 [(set (match_operand:DI 0 "register_operand" "=r")
838 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
839 "! TARGET_BYTE_OPS"
840 "zapnot %1,1,%0"
841 [(set_attr "type" "shift")])
842
843 (define_expand "zero_extendqidi2"
844 [(set (match_operand:DI 0 "register_operand" "")
845 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
846 ""
847 "")
848
849 (define_insn ""
850 [(set (match_operand:SI 0 "register_operand" "=r,r")
851 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
852 "TARGET_BYTE_OPS"
853 "@
854 zapnot %1,3,%0
855 ldwu %0,%1"
856 [(set_attr "type" "shift,ld")])
857
858 (define_insn ""
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
861 "! TARGET_BYTE_OPS"
862 "zapnot %1,3,%0"
863 [(set_attr "type" "shift")])
864
865 (define_expand "zero_extendhisi2"
866 [(set (match_operand:SI 0 "register_operand" "")
867 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
868 ""
869 "")
870
871 (define_insn ""
872 [(set (match_operand:DI 0 "register_operand" "=r,r")
873 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
874 "TARGET_BYTE_OPS"
875 "@
876 zapnot %1,3,%0
877 ldwu %0,%1"
878 [(set_attr "type" "shift,ld")])
879
880 (define_insn ""
881 [(set (match_operand:DI 0 "register_operand" "=r")
882 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
883 ""
884 "zapnot %1,3,%0"
885 [(set_attr "type" "shift")])
886
887 (define_expand "zero_extendhidi2"
888 [(set (match_operand:DI 0 "register_operand" "")
889 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
890 ""
891 "")
892
893 (define_insn "zero_extendsidi2"
894 [(set (match_operand:DI 0 "register_operand" "=r")
895 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
896 ""
897 "zapnot %1,15,%0"
898 [(set_attr "type" "shift")])
899
900 (define_insn ""
901 [(set (match_operand:DI 0 "register_operand" "=r")
902 (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
903 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
904 ""
905 "bic %r2,%1,%0"
906 [(set_attr "type" "ilog")])
907
908 (define_insn "iordi3"
909 [(set (match_operand:DI 0 "register_operand" "=r,r")
910 (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
911 (match_operand:DI 2 "or_operand" "rI,N")))]
912 ""
913 "@
914 bis %r1,%2,%0
915 ornot %r1,%N2,%0"
916 [(set_attr "type" "ilog")])
917
918 (define_insn "one_cmpldi2"
919 [(set (match_operand:DI 0 "register_operand" "=r")
920 (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
921 ""
922 "ornot $31,%1,%0"
923 [(set_attr "type" "ilog")])
924
925 (define_insn ""
926 [(set (match_operand:DI 0 "register_operand" "=r")
927 (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
928 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
929 ""
930 "ornot %r2,%1,%0"
931 [(set_attr "type" "ilog")])
932
933 (define_insn "xordi3"
934 [(set (match_operand:DI 0 "register_operand" "=r,r")
935 (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
936 (match_operand:DI 2 "or_operand" "rI,N")))]
937 ""
938 "@
939 xor %r1,%2,%0
940 eqv %r1,%N2,%0"
941 [(set_attr "type" "ilog")])
942
943 (define_insn ""
944 [(set (match_operand:DI 0 "register_operand" "=r")
945 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
946 (match_operand:DI 2 "register_operand" "rI"))))]
947 ""
948 "eqv %r1,%2,%0"
949 [(set_attr "type" "ilog")])
950 \f
951 ;; Next come the shifts and the various extract and insert operations.
952
953 (define_insn "ashldi3"
954 [(set (match_operand:DI 0 "register_operand" "=r,r")
955 (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
956 (match_operand:DI 2 "reg_or_6bit_operand" "P,rI")))]
957 ""
958 "*
959 {
960 switch (which_alternative)
961 {
962 case 0:
963 if (operands[2] == const1_rtx)
964 return \"addq %r1,%r1,%0\";
965 else
966 return \"s%P2addq %r1,0,%0\";
967 case 1:
968 return \"sll %r1,%2,%0\";
969 }
970 }"
971 [(set_attr "type" "iadd,shift")])
972
973 ;; ??? The following pattern is made by combine, but earlier phases
974 ;; (specifically flow) can't handle it. This occurs in jump.c. Deal
975 ;; with this in a better way at some point.
976 ;;(define_insn ""
977 ;; [(set (match_operand:DI 0 "register_operand" "=r")
978 ;; (sign_extend:DI
979 ;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
980 ;; (match_operand:DI 2 "const_int_operand" "P"))
981 ;; 0)))]
982 ;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
983 ;; "*
984 ;;{
985 ;; if (operands[2] == const1_rtx)
986 ;; return \"addl %r1,%r1,%0\";
987 ;; else
988 ;; return \"s%P2addl %r1,0,%0\";
989 ;; }"
990 ;; [(set_attr "type" "iadd")])
991
992 (define_insn "lshrdi3"
993 [(set (match_operand:DI 0 "register_operand" "=r")
994 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
995 (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
996 ""
997 "srl %r1,%2,%0"
998 [(set_attr "type" "shift")])
999
1000 (define_insn "ashrdi3"
1001 [(set (match_operand:DI 0 "register_operand" "=r")
1002 (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1003 (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
1004 ""
1005 "sra %r1,%2,%0"
1006 [(set_attr "type" "shift")])
1007
1008 (define_expand "extendqihi2"
1009 [(set (match_dup 2)
1010 (ashift:DI (match_operand:QI 1 "some_operand" "")
1011 (const_int 56)))
1012 (set (match_operand:HI 0 "register_operand" "")
1013 (ashiftrt:DI (match_dup 2)
1014 (const_int 56)))]
1015 ""
1016 "
1017 {
1018 if (TARGET_BYTE_OPS)
1019 {
1020 emit_insn (gen_extendqihi2x (operands[0],
1021 force_reg (QImode, operands[1])));
1022 DONE;
1023 }
1024
1025 /* If we have an unaligned MEM, extend to DImode (which we do
1026 specially) and then copy to the result. */
1027 if (unaligned_memory_operand (operands[1], HImode))
1028 {
1029 rtx temp = gen_reg_rtx (DImode);
1030
1031 emit_insn (gen_extendqidi2 (temp, operands[1]));
1032 emit_move_insn (operands[0], gen_lowpart (HImode, temp));
1033 DONE;
1034 }
1035
1036 operands[0] = gen_lowpart (DImode, operands[0]);
1037 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1038 operands[2] = gen_reg_rtx (DImode);
1039 }")
1040
1041 (define_insn "extendqidi2x"
1042 [(set (match_operand:DI 0 "register_operand" "=r")
1043 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1044 "TARGET_BYTE_OPS"
1045 "sextb %1,%0"
1046 [(set_attr "type" "shift")])
1047
1048 (define_insn "extendhidi2x"
1049 [(set (match_operand:DI 0 "register_operand" "=r")
1050 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1051 "TARGET_BYTE_OPS"
1052 "sextw %1,%0"
1053 [(set_attr "type" "shift")])
1054
1055 (define_insn "extendqisi2x"
1056 [(set (match_operand:SI 0 "register_operand" "=r")
1057 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1058 "TARGET_BYTE_OPS"
1059 "sextb %1,%0"
1060 [(set_attr "type" "shift")])
1061
1062 (define_insn "extendhisi2x"
1063 [(set (match_operand:SI 0 "register_operand" "=r")
1064 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1065 "TARGET_BYTE_OPS"
1066 "sextw %1,%0"
1067 [(set_attr "type" "shift")])
1068
1069 (define_insn "extendqihi2x"
1070 [(set (match_operand:HI 0 "register_operand" "=r")
1071 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1072 "TARGET_BYTE_OPS"
1073 "sextb %1,%0"
1074 [(set_attr "type" "shift")])
1075
1076 (define_expand "extendqisi2"
1077 [(set (match_dup 2)
1078 (ashift:DI (match_operand:QI 1 "some_operand" "")
1079 (const_int 56)))
1080 (set (match_operand:SI 0 "register_operand" "")
1081 (ashiftrt:DI (match_dup 2)
1082 (const_int 56)))]
1083 ""
1084 "
1085 {
1086 if (TARGET_BYTE_OPS)
1087 {
1088 emit_insn (gen_extendqisi2x (operands[0],
1089 force_reg (QImode, operands[1])));
1090 DONE;
1091 }
1092
1093 /* If we have an unaligned MEM, extend to a DImode form of
1094 the result (which we do specially). */
1095 if (unaligned_memory_operand (operands[1], QImode))
1096 {
1097 rtx temp = gen_reg_rtx (DImode);
1098
1099 emit_insn (gen_extendqidi2 (temp, operands[1]));
1100 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1101 DONE;
1102 }
1103
1104 operands[0] = gen_lowpart (DImode, operands[0]);
1105 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1106 operands[2] = gen_reg_rtx (DImode);
1107 }")
1108
1109 (define_expand "extendqidi2"
1110 [(set (match_dup 2)
1111 (ashift:DI (match_operand:QI 1 "some_operand" "")
1112 (const_int 56)))
1113 (set (match_operand:DI 0 "register_operand" "")
1114 (ashiftrt:DI (match_dup 2)
1115 (const_int 56)))]
1116 ""
1117 "
1118 { extern rtx get_unaligned_address ();
1119
1120 if (TARGET_BYTE_OPS)
1121 {
1122 emit_insn (gen_extendqidi2x (operands[0],
1123 force_reg (QImode, operands[1])));
1124 DONE;
1125 }
1126
1127 if (unaligned_memory_operand (operands[1], QImode))
1128 {
1129 rtx seq
1130 = gen_unaligned_extendqidi (operands[0],
1131 get_unaligned_address (operands[1], 1));
1132
1133 alpha_set_memflags (seq, operands[1]);
1134 emit_insn (seq);
1135 DONE;
1136 }
1137
1138 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1139 operands[2] = gen_reg_rtx (DImode);
1140 }")
1141
1142 (define_expand "extendhisi2"
1143 [(set (match_dup 2)
1144 (ashift:DI (match_operand:HI 1 "some_operand" "")
1145 (const_int 48)))
1146 (set (match_operand:SI 0 "register_operand" "")
1147 (ashiftrt:DI (match_dup 2)
1148 (const_int 48)))]
1149 ""
1150 "
1151 {
1152 if (TARGET_BYTE_OPS)
1153 {
1154 emit_insn (gen_extendhisi2x (operands[0],
1155 force_reg (HImode, operands[1])));
1156 DONE;
1157 }
1158
1159 /* If we have an unaligned MEM, extend to a DImode form of
1160 the result (which we do specially). */
1161 if (unaligned_memory_operand (operands[1], HImode))
1162 {
1163 rtx temp = gen_reg_rtx (DImode);
1164
1165 emit_insn (gen_extendhidi2 (temp, operands[1]));
1166 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1167 DONE;
1168 }
1169
1170 operands[0] = gen_lowpart (DImode, operands[0]);
1171 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1172 operands[2] = gen_reg_rtx (DImode);
1173 }")
1174
1175 (define_expand "extendhidi2"
1176 [(set (match_dup 2)
1177 (ashift:DI (match_operand:HI 1 "some_operand" "")
1178 (const_int 48)))
1179 (set (match_operand:DI 0 "register_operand" "")
1180 (ashiftrt:DI (match_dup 2)
1181 (const_int 48)))]
1182 ""
1183 "
1184 { extern rtx get_unaligned_address ();
1185
1186 if (TARGET_BYTE_OPS)
1187 {
1188 emit_insn (gen_extendhidi2x (operands[0],
1189 force_reg (HImode, operands[1])));
1190 DONE;
1191 }
1192
1193 if (unaligned_memory_operand (operands[1], HImode))
1194 {
1195 rtx seq
1196 = gen_unaligned_extendhidi (operands[0],
1197 get_unaligned_address (operands[1], 2));
1198
1199 alpha_set_memflags (seq, operands[1]);
1200 emit_insn (seq);
1201 DONE;
1202 }
1203
1204 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1205 operands[2] = gen_reg_rtx (DImode);
1206 }")
1207
1208 ;; Here's how we sign extend an unaligned byte and halfword. Doing this
1209 ;; as a pattern saves one instruction. The code is similar to that for
1210 ;; the unaligned loads (see below).
1211 ;;
1212 ;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
1213 (define_expand "unaligned_extendqidi"
1214 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1215 (set (match_dup 3)
1216 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
1217 (const_int -8))))
1218 (set (match_dup 4)
1219 (ashift:DI (match_dup 3)
1220 (minus:DI (const_int 56)
1221 (ashift:DI
1222 (and:DI (plus:DI (match_dup 2) (const_int -1))
1223 (const_int 7))
1224 (const_int 3)))))
1225 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1226 (ashiftrt:DI (match_dup 4) (const_int 56)))]
1227 ""
1228 "
1229 { operands[2] = gen_reg_rtx (DImode);
1230 operands[3] = gen_reg_rtx (DImode);
1231 operands[4] = gen_reg_rtx (DImode);
1232 }")
1233
1234 (define_expand "unaligned_extendhidi"
1235 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1236 (set (match_dup 3)
1237 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
1238 (const_int -8))))
1239 (set (match_dup 4)
1240 (ashift:DI (match_dup 3)
1241 (minus:DI (const_int 56)
1242 (ashift:DI
1243 (and:DI (plus:DI (match_dup 2) (const_int -1))
1244 (const_int 7))
1245 (const_int 3)))))
1246 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1247 (ashiftrt:DI (match_dup 4) (const_int 48)))]
1248 ""
1249 "
1250 { operands[2] = gen_reg_rtx (DImode);
1251 operands[3] = gen_reg_rtx (DImode);
1252 operands[4] = gen_reg_rtx (DImode);
1253 }")
1254
1255 (define_insn ""
1256 [(set (match_operand:DI 0 "register_operand" "=r")
1257 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1258 (match_operand:DI 2 "mode_width_operand" "n")
1259 (match_operand:DI 3 "mul8_operand" "I")))]
1260 ""
1261 "ext%M2l %r1,%s3,%0"
1262 [(set_attr "type" "shift")])
1263
1264 (define_insn ""
1265 [(set (match_operand:DI 0 "register_operand" "=r")
1266 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1267 (match_operand:DI 2 "mode_width_operand" "n")
1268 (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1269 (const_int 3))))]
1270 ""
1271 "ext%M2l %r1,%3,%0"
1272 [(set_attr "type" "shift")])
1273
1274 (define_insn ""
1275 [(set (match_operand:DI 0 "register_operand" "=r")
1276 (ashift:DI
1277 (match_operand:DI 1 "reg_or_0_operand" "rJ")
1278 (minus:DI (const_int 56)
1279 (ashift:DI
1280 (and:DI
1281 (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1282 (const_int -1))
1283 (const_int 7))
1284 (const_int 3)))))]
1285 ""
1286 "extqh %r1,%2,%0"
1287 [(set_attr "type" "shift")])
1288
1289 (define_insn ""
1290 [(set (match_operand:DI 0 "register_operand" "=r")
1291 (ashift:DI
1292 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1293 (const_int 2147483647))
1294 (minus:DI (const_int 56)
1295 (ashift:DI
1296 (and:DI
1297 (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1298 (const_int -1))
1299 (const_int 7))
1300 (const_int 3)))))]
1301 ""
1302 "extlh %r1,%2,%0"
1303 [(set_attr "type" "shift")])
1304
1305 (define_insn ""
1306 [(set (match_operand:DI 0 "register_operand" "=r")
1307 (ashift:DI
1308 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1309 (const_int 65535))
1310 (minus:DI (const_int 56)
1311 (ashift:DI
1312 (and:DI
1313 (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1314 (const_int -1))
1315 (const_int 7))
1316 (const_int 3)))))]
1317 ""
1318 "extwh %r1,%2,%0"
1319 [(set_attr "type" "shift")])
1320
1321 ;; This converts an extXl into an extXh with an appropriate adjustment
1322 ;; to the address calculation.
1323
1324 ;;(define_split
1325 ;; [(set (match_operand:DI 0 "register_operand" "")
1326 ;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
1327 ;; (match_operand:DI 2 "mode_width_operand" "")
1328 ;; (ashift:DI (match_operand:DI 3 "" "")
1329 ;; (const_int 3)))
1330 ;; (match_operand:DI 4 "const_int_operand" "")))
1331 ;; (clobber (match_operand:DI 5 "register_operand" ""))]
1332 ;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1333 ;; [(set (match_dup 5) (match_dup 6))
1334 ;; (set (match_dup 0)
1335 ;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1336 ;; (ashift:DI (plus:DI (match_dup 5)
1337 ;; (match_dup 7))
1338 ;; (const_int 3)))
1339 ;; (match_dup 4)))]
1340 ;; "
1341 ;;{
1342 ;; operands[6] = plus_constant (operands[3],
1343 ;; INTVAL (operands[2]) / BITS_PER_UNIT);
1344 ;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1345 ;;}")
1346
1347 (define_insn ""
1348 [(set (match_operand:DI 0 "register_operand" "=r")
1349 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1350 (match_operand:DI 2 "mul8_operand" "I")))]
1351 ""
1352 "insbl %1,%s2,%0"
1353 [(set_attr "type" "shift")])
1354
1355 (define_insn ""
1356 [(set (match_operand:DI 0 "register_operand" "=r")
1357 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1358 (match_operand:DI 2 "mul8_operand" "I")))]
1359 ""
1360 "inswl %1,%s2,%0"
1361 [(set_attr "type" "shift")])
1362
1363 (define_insn ""
1364 [(set (match_operand:DI 0 "register_operand" "=r")
1365 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1366 (match_operand:DI 2 "mul8_operand" "I")))]
1367 ""
1368 "insll %1,%s2,%0"
1369 [(set_attr "type" "shift")])
1370
1371 (define_insn ""
1372 [(set (match_operand:DI 0 "register_operand" "=r")
1373 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1374 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1375 (const_int 3))))]
1376 ""
1377 "insbl %1,%2,%0"
1378 [(set_attr "type" "shift")])
1379
1380 (define_insn ""
1381 [(set (match_operand:DI 0 "register_operand" "=r")
1382 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1383 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1384 (const_int 3))))]
1385 ""
1386 "inswl %1,%2,%0"
1387 [(set_attr "type" "shift")])
1388
1389 (define_insn ""
1390 [(set (match_operand:DI 0 "register_operand" "=r")
1391 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1392 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1393 (const_int 3))))]
1394 ""
1395 "insll %1,%2,%0"
1396 [(set_attr "type" "shift")])
1397
1398 ;; We do not include the insXh insns because they are complex to express
1399 ;; and it does not appear that we would ever want to generate them.
1400
1401 (define_insn ""
1402 [(set (match_operand:DI 0 "register_operand" "=r")
1403 (and:DI (not:DI (ashift:DI
1404 (match_operand:DI 2 "mode_mask_operand" "n")
1405 (ashift:DI
1406 (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1407 (const_int 3))))
1408 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1409 ""
1410 "msk%U2l %r1,%3,%0"
1411 [(set_attr "type" "shift")])
1412
1413 ;; We do not include the mskXh insns because it does not appear we would ever
1414 ;; generate one.
1415 \f
1416 ;; Floating-point operations. All the double-precision insns can extend
1417 ;; from single, so indicate that. The exception are the ones that simply
1418 ;; play with the sign bits; it's not clear what to do there.
1419
1420 (define_insn "abssf2"
1421 [(set (match_operand:SF 0 "register_operand" "=f")
1422 (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1423 "TARGET_FP"
1424 "cpys $f31,%R1,%0"
1425 [(set_attr "type" "fcpys")])
1426
1427 (define_insn "absdf2"
1428 [(set (match_operand:DF 0 "register_operand" "=f")
1429 (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1430 "TARGET_FP"
1431 "cpys $f31,%R1,%0"
1432 [(set_attr "type" "fcpys")])
1433
1434 (define_insn "negsf2"
1435 [(set (match_operand:SF 0 "register_operand" "=f")
1436 (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1437 "TARGET_FP"
1438 "cpysn %R1,%R1,%0"
1439 [(set_attr "type" "fadd")])
1440
1441 (define_insn "negdf2"
1442 [(set (match_operand:DF 0 "register_operand" "=f")
1443 (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1444 "TARGET_FP"
1445 "cpysn %R1,%R1,%0"
1446 [(set_attr "type" "fadd")])
1447
1448 (define_insn ""
1449 [(set (match_operand:SF 0 "register_operand" "=&f")
1450 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1451 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1452 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1453 "add%,%)%& %R1,%R2,%0"
1454 [(set_attr "type" "fadd")
1455 (set_attr "trap" "yes")])
1456
1457 (define_insn "addsf3"
1458 [(set (match_operand:SF 0 "register_operand" "=f")
1459 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1460 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1461 "TARGET_FP"
1462 "add%,%)%& %R1,%R2,%0"
1463 [(set_attr "type" "fadd")
1464 (set_attr "trap" "yes")])
1465
1466 (define_insn ""
1467 [(set (match_operand:DF 0 "register_operand" "=&f")
1468 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1469 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1470 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1471 "add%-%)%& %R1,%R2,%0"
1472 [(set_attr "type" "fadd")
1473 (set_attr "trap" "yes")])
1474
1475 (define_insn "adddf3"
1476 [(set (match_operand:DF 0 "register_operand" "=f")
1477 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1478 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1479 "TARGET_FP"
1480 "add%-%)%& %R1,%R2,%0"
1481 [(set_attr "type" "fadd")
1482 (set_attr "trap" "yes")])
1483
1484 (define_insn ""
1485 [(set (match_operand:DF 0 "register_operand" "=f")
1486 (plus:DF (float_extend:DF
1487 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1488 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1489 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1490 "add%-%)%& %R1,%R2,%0"
1491 [(set_attr "type" "fadd")
1492 (set_attr "trap" "yes")])
1493
1494 (define_insn ""
1495 [(set (match_operand:DF 0 "register_operand" "=f")
1496 (plus:DF (float_extend:DF
1497 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1498 (float_extend:DF
1499 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1500 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1501 "add%-%)%& %R1,%R2,%0"
1502 [(set_attr "type" "fadd")
1503 (set_attr "trap" "yes")])
1504
1505 (define_insn "fix_truncdfdi2"
1506 [(set (match_operand:DI 0 "register_operand" "=f")
1507 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1508 "TARGET_FP"
1509 "cvt%-qc %R1,%0"
1510 [(set_attr "type" "fadd")])
1511
1512 (define_insn "fix_truncsfdi2"
1513 [(set (match_operand:DI 0 "register_operand" "=f")
1514 (fix:DI (float_extend:DF
1515 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1516 "TARGET_FP"
1517 "cvt%-qc %R1,%0"
1518 [(set_attr "type" "fadd")])
1519
1520 (define_insn "floatdisf2"
1521 [(set (match_operand:SF 0 "register_operand" "=f")
1522 (float:SF (match_operand:DI 1 "register_operand" "f")))]
1523 "TARGET_FP"
1524 "cvtq%,%+%& %1,%0"
1525 [(set_attr "type" "fadd")
1526 (set_attr "trap" "yes")])
1527
1528 (define_insn ""
1529 [(set (match_operand:DF 0 "register_operand" "=&f")
1530 (float:DF (match_operand:DI 1 "register_operand" "f")))]
1531 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1532 "cvtq%-%+%& %1,%0"
1533 [(set_attr "type" "fadd")
1534 (set_attr "trap" "yes")])
1535
1536 (define_insn "floatdidf2"
1537 [(set (match_operand:DF 0 "register_operand" "=f")
1538 (float:DF (match_operand:DI 1 "register_operand" "f")))]
1539 "TARGET_FP"
1540 "cvtq%-%+%& %1,%0"
1541 [(set_attr "type" "fadd")
1542 (set_attr "trap" "yes")])
1543
1544 (define_expand "extendsfdf2"
1545 [(use (match_operand:DF 0 "register_operand" ""))
1546 (use (match_operand:SF 1 "nonimmediate_operand" ""))]
1547 "TARGET_FP"
1548 "
1549 {
1550 if (alpha_tp == ALPHA_TP_INSN)
1551 emit_insn (gen_extendsfdf2_tp (operands[0],
1552 force_reg (SFmode, operands[1])));
1553 else
1554 emit_insn (gen_extendsfdf2_no_tp (operands[0], operands[1]));
1555
1556 DONE;
1557 }")
1558 ;; FIXME
1559 (define_insn "extendsfdf2_tp"
1560 [(set (match_operand:DF 0 "register_operand" "=&f")
1561 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
1562 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1563 "cvtsts %1,%0"
1564 [(set_attr "type" "fadd")
1565 (set_attr "trap" "yes")])
1566
1567 (define_insn "extendsfdf2_no_tp"
1568 [(set (match_operand:DF 0 "register_operand" "=f,f,m")
1569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
1570 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1571 "@
1572 cpys %1,%1,%0
1573 ld%, %0,%1
1574 st%- %1,%0"
1575 [(set_attr "type" "fcpys,ld,st")
1576 (set_attr "trap" "yes")])
1577
1578 (define_insn ""
1579 [(set (match_operand:SF 0 "register_operand" "=&f")
1580 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1581 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1582 "cvt%-%,%)%& %R1,%0"
1583 [(set_attr "type" "fadd")
1584 (set_attr "trap" "yes")])
1585
1586 (define_insn "truncdfsf2"
1587 [(set (match_operand:SF 0 "register_operand" "=f")
1588 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1589 "TARGET_FP"
1590 "cvt%-%,%)%& %R1,%0"
1591 [(set_attr "type" "fadd")
1592 (set_attr "trap" "yes")])
1593
1594 (define_insn ""
1595 [(set (match_operand:SF 0 "register_operand" "=&f")
1596 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1597 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1598 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1599 "div%,%)%& %R1,%R2,%0"
1600 [(set_attr "type" "fdivs")
1601 (set_attr "trap" "yes")])
1602
1603 (define_insn "divsf3"
1604 [(set (match_operand:SF 0 "register_operand" "=f")
1605 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1606 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1607 "TARGET_FP"
1608 "div%,%)%& %R1,%R2,%0"
1609 [(set_attr "type" "fdivs")
1610 (set_attr "trap" "yes")])
1611
1612 (define_insn ""
1613 [(set (match_operand:DF 0 "register_operand" "=&f")
1614 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1615 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1616 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1617 "div%-%)%& %R1,%R2,%0"
1618 [(set_attr "type" "fdivt")
1619 (set_attr "trap" "yes")])
1620
1621 (define_insn "divdf3"
1622 [(set (match_operand:DF 0 "register_operand" "=f")
1623 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1624 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1625 "TARGET_FP"
1626 "div%-%)%& %R1,%R2,%0"
1627 [(set_attr "type" "fdivt")
1628 (set_attr "trap" "yes")])
1629
1630 (define_insn ""
1631 [(set (match_operand:DF 0 "register_operand" "=f")
1632 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1633 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1634 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1635 "div%-%)%& %R1,%R2,%0"
1636 [(set_attr "type" "fdivt")
1637 (set_attr "trap" "yes")])
1638
1639 (define_insn ""
1640 [(set (match_operand:DF 0 "register_operand" "=f")
1641 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1642 (float_extend:DF
1643 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1644 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1645 "div%-%)%& %R1,%R2,%0"
1646 [(set_attr "type" "fdivt")
1647 (set_attr "trap" "yes")])
1648
1649 (define_insn ""
1650 [(set (match_operand:DF 0 "register_operand" "=f")
1651 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1652 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1653 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1654 "div%-%)%& %R1,%R2,%0"
1655 [(set_attr "type" "fdivt")
1656 (set_attr "trap" "yes")])
1657
1658 (define_insn ""
1659 [(set (match_operand:SF 0 "register_operand" "=&f")
1660 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1661 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1662 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1663 "mul%,%)%& %R1,%R2,%0"
1664 [(set_attr "type" "fmul")
1665 (set_attr "trap" "yes")])
1666
1667 (define_insn "mulsf3"
1668 [(set (match_operand:SF 0 "register_operand" "=f")
1669 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1670 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1671 "TARGET_FP"
1672 "mul%,%)%& %R1,%R2,%0"
1673 [(set_attr "type" "fmul")
1674 (set_attr "trap" "yes")])
1675
1676 (define_insn ""
1677 [(set (match_operand:DF 0 "register_operand" "=&f")
1678 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1679 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1680 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1681 "mul%-%)%& %R1,%R2,%0"
1682 [(set_attr "type" "fmul")
1683 (set_attr "trap" "yes")])
1684
1685 (define_insn "muldf3"
1686 [(set (match_operand:DF 0 "register_operand" "=f")
1687 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1688 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1689 "TARGET_FP"
1690 "mul%-%)%& %R1,%R2,%0"
1691 [(set_attr "type" "fmul")
1692 (set_attr "trap" "yes")])
1693
1694 (define_insn ""
1695 [(set (match_operand:DF 0 "register_operand" "=f")
1696 (mult:DF (float_extend:DF
1697 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1698 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1699 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1700 "mul%-%)%& %R1,%R2,%0"
1701 [(set_attr "type" "fmul")
1702 (set_attr "trap" "yes")])
1703
1704 (define_insn ""
1705 [(set (match_operand:DF 0 "register_operand" "=f")
1706 (mult:DF (float_extend:DF
1707 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1708 (float_extend:DF
1709 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1710 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1711 "mul%-%)%& %R1,%R2,%0"
1712 [(set_attr "type" "fmul")
1713 (set_attr "trap" "yes")])
1714
1715 (define_insn ""
1716 [(set (match_operand:SF 0 "register_operand" "=&f")
1717 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1718 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1719 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1720 "sub%,%)%& %R1,%R2,%0"
1721 [(set_attr "type" "fadd")
1722 (set_attr "trap" "yes")])
1723
1724 (define_insn "subsf3"
1725 [(set (match_operand:SF 0 "register_operand" "=f")
1726 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1727 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1728 "TARGET_FP"
1729 "sub%,%)%& %R1,%R2,%0"
1730 [(set_attr "type" "fadd")
1731 (set_attr "trap" "yes")])
1732
1733 (define_insn ""
1734 [(set (match_operand:DF 0 "register_operand" "=&f")
1735 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1736 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1737 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1738 "sub%-%)%& %R1,%R2,%0"
1739 [(set_attr "type" "fadd")
1740 (set_attr "trap" "yes")])
1741
1742 (define_insn "subdf3"
1743 [(set (match_operand:DF 0 "register_operand" "=f")
1744 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1745 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1746 "TARGET_FP"
1747 "sub%-%)%& %R1,%R2,%0"
1748 [(set_attr "type" "fadd")
1749 (set_attr "trap" "yes")])
1750
1751 (define_insn ""
1752 [(set (match_operand:DF 0 "register_operand" "=f")
1753 (minus:DF (float_extend:DF
1754 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1755 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1756 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1757 "sub%-%)%& %R1,%R2,%0"
1758 [(set_attr "type" "fadd")
1759 (set_attr "trap" "yes")])
1760
1761 (define_insn ""
1762 [(set (match_operand:DF 0 "register_operand" "=f")
1763 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1764 (float_extend:DF
1765 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1766 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1767 "sub%-%)%& %R1,%R2,%0"
1768 [(set_attr "type" "fadd")
1769 (set_attr "trap" "yes")])
1770
1771 (define_insn ""
1772 [(set (match_operand:DF 0 "register_operand" "=f")
1773 (minus:DF (float_extend:DF
1774 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1775 (float_extend:DF
1776 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1777 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1778 "sub%-%)%& %R1,%R2,%0"
1779 [(set_attr "type" "fadd")
1780 (set_attr "trap" "yes")])
1781 \f
1782 ;; Next are all the integer comparisons, and conditional moves and branches
1783 ;; and some of the related define_expand's and define_split's.
1784
1785 (define_insn ""
1786 [(set (match_operand:DI 0 "register_operand" "=r")
1787 (match_operator:DI 1 "alpha_comparison_operator"
1788 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
1789 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
1790 ""
1791 "cmp%C1 %r2,%3,%0"
1792 [(set_attr "type" "icmp")])
1793
1794 (define_insn ""
1795 [(set (match_operand:DI 0 "register_operand" "=r")
1796 (match_operator:DI 1 "alpha_swapped_comparison_operator"
1797 [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
1798 (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
1799 ""
1800 "cmp%c1 %r3,%2,%0"
1801 [(set_attr "type" "icmp")])
1802
1803 ;; This pattern exists so conditional moves of SImode values are handled.
1804 ;; Comparisons are still done in DImode though.
1805
1806 (define_insn ""
1807 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1808 (if_then_else:DI
1809 (match_operator 2 "signed_comparison_operator"
1810 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
1811 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
1812 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0")
1813 (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
1814 "operands[3] == const0_rtx || operands[4] == const0_rtx"
1815 "@
1816 cmov%C2 %r3,%1,%0
1817 cmov%D2 %r3,%5,%0
1818 cmov%c2 %r4,%1,%0
1819 cmov%d2 %r4,%5,%0"
1820 [(set_attr "type" "cmov")])
1821
1822 (define_insn ""
1823 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
1824 (if_then_else:DI
1825 (match_operator 2 "signed_comparison_operator"
1826 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
1827 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
1828 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0,rI,0")
1829 (match_operand:DI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
1830 "operands[3] == const0_rtx || operands[4] == const0_rtx"
1831 "@
1832 cmov%C2 %r3,%1,%0
1833 cmov%D2 %r3,%5,%0
1834 cmov%c2 %r4,%1,%0
1835 cmov%d2 %r4,%5,%0"
1836 [(set_attr "type" "cmov")])
1837
1838 (define_insn ""
1839 [(set (match_operand:DI 0 "register_operand" "=r,r")
1840 (if_then_else:DI
1841 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1842 (const_int 1)
1843 (const_int 0))
1844 (const_int 0))
1845 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1846 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1847 ""
1848 "@
1849 cmovlbc %r2,%1,%0
1850 cmovlbs %r2,%3,%0"
1851 [(set_attr "type" "cmov")])
1852
1853 (define_insn ""
1854 [(set (match_operand:DI 0 "register_operand" "=r,r")
1855 (if_then_else:DI
1856 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1857 (const_int 1)
1858 (const_int 0))
1859 (const_int 0))
1860 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1861 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1862 ""
1863 "@
1864 cmovlbs %r2,%1,%0
1865 cmovlbc %r2,%3,%0"
1866 [(set_attr "type" "cmov")])
1867
1868 ;; This form is added since combine thinks that an IF_THEN_ELSE with both
1869 ;; arms constant is a single insn, so it won't try to form it if combine
1870 ;; knows they are really two insns. This occurs in divides by powers
1871 ;; of two.
1872
1873 (define_insn ""
1874 [(set (match_operand:DI 0 "register_operand" "=r")
1875 (if_then_else:DI
1876 (match_operator 2 "signed_comparison_operator"
1877 [(match_operand:DI 3 "reg_or_0_operand" "rJ")
1878 (const_int 0)])
1879 (plus:DI (match_dup 0)
1880 (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1881 (match_dup 0)))
1882 (clobber (match_scratch:DI 4 "=&r"))]
1883 ""
1884 "addq %0,%1,%4\;cmov%C2 %r3,%4,%0"
1885 [(set_attr "type" "cmov")])
1886
1887 (define_split
1888 [(set (match_operand:DI 0 "register_operand" "")
1889 (if_then_else:DI
1890 (match_operator 2 "signed_comparison_operator"
1891 [(match_operand:DI 3 "reg_or_0_operand" "")
1892 (const_int 0)])
1893 (plus:DI (match_dup 0)
1894 (match_operand:DI 1 "reg_or_8bit_operand" ""))
1895 (match_dup 0)))
1896 (clobber (match_operand:DI 4 "register_operand" ""))]
1897 ""
1898 [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1)))
1899 (set (match_dup 0) (if_then_else:DI (match_op_dup 2
1900 [(match_dup 3)
1901 (const_int 0)])
1902 (match_dup 4) (match_dup 0)))]
1903 "")
1904
1905 (define_split
1906 [(parallel
1907 [(set (match_operand:DI 0 "register_operand" "")
1908 (if_then_else:DI
1909 (match_operator 1 "comparison_operator"
1910 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
1911 (const_int 1)
1912 (match_operand:DI 3 "const_int_operand" ""))
1913 (const_int 0)])
1914 (match_operand:DI 4 "reg_or_8bit_operand" "")
1915 (match_operand:DI 5 "reg_or_8bit_operand" "")))
1916 (clobber (match_operand:DI 6 "register_operand" ""))])]
1917 "INTVAL (operands[3]) != 0"
1918 [(set (match_dup 6)
1919 (lshiftrt:DI (match_dup 2) (match_dup 3)))
1920 (set (match_dup 0)
1921 (if_then_else:DI (match_op_dup 1
1922 [(zero_extract:DI (match_dup 6)
1923 (const_int 1)
1924 (const_int 0))
1925 (const_int 0)])
1926 (match_dup 4)
1927 (match_dup 5)))]
1928 "")
1929
1930 ;; For ABS, we have two choices, depending on whether the input and output
1931 ;; registers are the same or not.
1932 (define_expand "absdi2"
1933 [(set (match_operand:DI 0 "register_operand" "")
1934 (abs:DI (match_operand:DI 1 "register_operand" "")))]
1935 ""
1936 "
1937 { if (rtx_equal_p (operands[0], operands[1]))
1938 emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
1939 else
1940 emit_insn (gen_absdi2_diff (operands[0], operands[1]));
1941
1942 DONE;
1943 }")
1944
1945 (define_expand "absdi2_same"
1946 [(set (match_operand:DI 1 "register_operand" "")
1947 (neg:DI (match_operand:DI 0 "register_operand" "")))
1948 (set (match_dup 0)
1949 (if_then_else:DI (ge (match_dup 0) (const_int 0))
1950 (match_dup 0)
1951 (match_dup 1)))]
1952 ""
1953 "")
1954
1955 (define_expand "absdi2_diff"
1956 [(set (match_operand:DI 0 "register_operand" "")
1957 (neg:DI (match_operand:DI 1 "register_operand" "")))
1958 (set (match_dup 0)
1959 (if_then_else:DI (lt (match_dup 1) (const_int 0))
1960 (match_dup 0)
1961 (match_dup 1)))]
1962 ""
1963 "")
1964
1965 (define_split
1966 [(set (match_operand:DI 0 "register_operand" "")
1967 (abs:DI (match_dup 0)))
1968 (clobber (match_operand:DI 2 "register_operand" ""))]
1969 ""
1970 [(set (match_dup 1) (neg:DI (match_dup 0)))
1971 (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
1972 (match_dup 0) (match_dup 1)))]
1973 "")
1974
1975 (define_split
1976 [(set (match_operand:DI 0 "register_operand" "")
1977 (abs:DI (match_operand:DI 1 "register_operand" "")))]
1978 "! rtx_equal_p (operands[0], operands[1])"
1979 [(set (match_dup 0) (neg:DI (match_dup 1)))
1980 (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
1981 (match_dup 0) (match_dup 1)))]
1982 "")
1983
1984 (define_split
1985 [(set (match_operand:DI 0 "register_operand" "")
1986 (neg:DI (abs:DI (match_dup 0))))
1987 (clobber (match_operand:DI 2 "register_operand" ""))]
1988 ""
1989 [(set (match_dup 1) (neg:DI (match_dup 0)))
1990 (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
1991 (match_dup 0) (match_dup 1)))]
1992 "")
1993
1994 (define_split
1995 [(set (match_operand:DI 0 "register_operand" "")
1996 (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
1997 "! rtx_equal_p (operands[0], operands[1])"
1998 [(set (match_dup 0) (neg:DI (match_dup 1)))
1999 (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2000 (match_dup 0) (match_dup 1)))]
2001 "")
2002
2003 (define_expand "smaxdi3"
2004 [(set (match_dup 3)
2005 (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
2006 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2007 (set (match_operand:DI 0 "register_operand" "")
2008 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2009 (match_dup 1) (match_dup 2)))]
2010 ""
2011 "
2012 { operands[3] = gen_reg_rtx (DImode);
2013 }")
2014
2015 (define_split
2016 [(set (match_operand:DI 0 "register_operand" "")
2017 (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2018 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2019 (clobber (match_operand:DI 3 "register_operand" ""))]
2020 "operands[2] != const0_rtx"
2021 [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2022 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2023 (match_dup 1) (match_dup 2)))]
2024 "")
2025
2026 (define_insn ""
2027 [(set (match_operand:DI 0 "register_operand" "=r")
2028 (smax:DI (match_operand:DI 1 "register_operand" "0")
2029 (const_int 0)))]
2030 ""
2031 "cmovlt %0,0,%0"
2032 [(set_attr "type" "cmov")])
2033
2034 (define_expand "smindi3"
2035 [(set (match_dup 3)
2036 (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
2037 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2038 (set (match_operand:DI 0 "register_operand" "")
2039 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2040 (match_dup 1) (match_dup 2)))]
2041 ""
2042 "
2043 { operands[3] = gen_reg_rtx (DImode);
2044 }")
2045
2046 (define_split
2047 [(set (match_operand:DI 0 "register_operand" "")
2048 (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2049 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2050 (clobber (match_operand:DI 3 "register_operand" ""))]
2051 "operands[2] != const0_rtx"
2052 [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2053 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2054 (match_dup 1) (match_dup 2)))]
2055 "")
2056
2057 (define_insn ""
2058 [(set (match_operand:DI 0 "register_operand" "=r")
2059 (smin:DI (match_operand:DI 1 "register_operand" "0")
2060 (const_int 0)))]
2061 ""
2062 "cmovgt %0,0,%0"
2063 [(set_attr "type" "cmov")])
2064
2065 (define_expand "umaxdi3"
2066 [(set (match_dup 3)
2067 (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2068 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2069 (set (match_operand:DI 0 "register_operand" "")
2070 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2071 (match_dup 1) (match_dup 2)))]
2072 ""
2073 "
2074 { operands[3] = gen_reg_rtx (DImode);
2075 }")
2076
2077 (define_split
2078 [(set (match_operand:DI 0 "register_operand" "")
2079 (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2080 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2081 (clobber (match_operand:DI 3 "register_operand" ""))]
2082 "operands[2] != const0_rtx"
2083 [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2084 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2085 (match_dup 1) (match_dup 2)))]
2086 "")
2087
2088 (define_expand "umindi3"
2089 [(set (match_dup 3)
2090 (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2091 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2092 (set (match_operand:DI 0 "register_operand" "")
2093 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2094 (match_dup 1) (match_dup 2)))]
2095 ""
2096 "
2097 { operands[3] = gen_reg_rtx (DImode);
2098 }")
2099
2100 (define_split
2101 [(set (match_operand:DI 0 "register_operand" "")
2102 (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2103 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2104 (clobber (match_operand:DI 3 "register_operand" ""))]
2105 "operands[2] != const0_rtx"
2106 [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2107 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2108 (match_dup 1) (match_dup 2)))]
2109 "")
2110
2111 (define_insn ""
2112 [(set (pc)
2113 (if_then_else
2114 (match_operator 1 "signed_comparison_operator"
2115 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2116 (const_int 0)])
2117 (label_ref (match_operand 0 "" ""))
2118 (pc)))]
2119 ""
2120 "b%C1 %r2,%0"
2121 [(set_attr "type" "ibr")])
2122
2123 (define_insn ""
2124 [(set (pc)
2125 (if_then_else
2126 (match_operator 1 "signed_comparison_operator"
2127 [(const_int 0)
2128 (match_operand:DI 2 "register_operand" "r")])
2129 (label_ref (match_operand 0 "" ""))
2130 (pc)))]
2131 ""
2132 "b%c1 %2,%0"
2133 [(set_attr "type" "ibr")])
2134
2135 (define_insn ""
2136 [(set (pc)
2137 (if_then_else
2138 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2139 (const_int 1)
2140 (const_int 0))
2141 (const_int 0))
2142 (label_ref (match_operand 0 "" ""))
2143 (pc)))]
2144 ""
2145 "blbs %r1,%0"
2146 [(set_attr "type" "ibr")])
2147
2148 (define_insn ""
2149 [(set (pc)
2150 (if_then_else
2151 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2152 (const_int 1)
2153 (const_int 0))
2154 (const_int 0))
2155 (label_ref (match_operand 0 "" ""))
2156 (pc)))]
2157 ""
2158 "blbc %r1,%0"
2159 [(set_attr "type" "ibr")])
2160
2161 (define_split
2162 [(parallel
2163 [(set (pc)
2164 (if_then_else
2165 (match_operator 1 "comparison_operator"
2166 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
2167 (const_int 1)
2168 (match_operand:DI 3 "const_int_operand" ""))
2169 (const_int 0)])
2170 (label_ref (match_operand 0 "" ""))
2171 (pc)))
2172 (clobber (match_operand:DI 4 "register_operand" ""))])]
2173 "INTVAL (operands[3]) != 0"
2174 [(set (match_dup 4)
2175 (lshiftrt:DI (match_dup 2) (match_dup 3)))
2176 (set (pc)
2177 (if_then_else (match_op_dup 1
2178 [(zero_extract:DI (match_dup 4)
2179 (const_int 1)
2180 (const_int 0))
2181 (const_int 0)])
2182 (label_ref (match_dup 0))
2183 (pc)))]
2184 "")
2185 \f
2186 ;; The following are the corresponding floating-point insns. Recall
2187 ;; we need to have variants that expand the arguments from SF mode
2188 ;; to DFmode.
2189
2190 (define_insn ""
2191 [(set (match_operand:DF 0 "register_operand" "=&f")
2192 (match_operator:DF 1 "alpha_comparison_operator"
2193 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2194 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2195 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2196 "cmp%-%C1%' %R2,%R3,%0"
2197 [(set_attr "type" "fadd")
2198 (set_attr "trap" "yes")])
2199
2200 (define_insn ""
2201 [(set (match_operand:DF 0 "register_operand" "=f")
2202 (match_operator:DF 1 "alpha_comparison_operator"
2203 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2204 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2205 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2206 "cmp%-%C1%' %R2,%R3,%0"
2207 [(set_attr "type" "fadd")
2208 (set_attr "trap" "yes")])
2209
2210 (define_insn ""
2211 [(set (match_operand:DF 0 "register_operand" "=f")
2212 (match_operator:DF 1 "alpha_comparison_operator"
2213 [(float_extend:DF
2214 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2215 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2216 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2217 "cmp%-%C1%' %R2,%R3,%0"
2218 [(set_attr "type" "fadd")
2219 (set_attr "trap" "yes")])
2220
2221 (define_insn ""
2222 [(set (match_operand:DF 0 "register_operand" "=f")
2223 (match_operator:DF 1 "alpha_comparison_operator"
2224 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2225 (float_extend:DF
2226 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2227 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2228 "cmp%-%C1%' %R2,%R3,%0"
2229 [(set_attr "type" "fadd")
2230 (set_attr "trap" "yes")])
2231
2232 (define_insn ""
2233 [(set (match_operand:DF 0 "register_operand" "=f")
2234 (match_operator:DF 1 "alpha_comparison_operator"
2235 [(float_extend:DF
2236 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2237 (float_extend:DF
2238 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2239 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2240 "cmp%-%C1%' %R2,%R3,%0"
2241 [(set_attr "type" "fadd")
2242 (set_attr "trap" "yes")])
2243
2244 (define_insn ""
2245 [(set (match_operand:DF 0 "register_operand" "=&f,f")
2246 (if_then_else:DF
2247 (match_operator 3 "signed_comparison_operator"
2248 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2249 (match_operand:DF 2 "fp0_operand" "G,G")])
2250 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2251 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2252 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2253 "@
2254 fcmov%C3 %R4,%R1,%0
2255 fcmov%D3 %R4,%R5,%0"
2256 [(set_attr "type" "fadd")])
2257
2258 (define_insn ""
2259 [(set (match_operand:DF 0 "register_operand" "=f,f")
2260 (if_then_else:DF
2261 (match_operator 3 "signed_comparison_operator"
2262 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2263 (match_operand:DF 2 "fp0_operand" "G,G")])
2264 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2265 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2266 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2267 "@
2268 fcmov%C3 %R4,%R1,%0
2269 fcmov%D3 %R4,%R5,%0"
2270 [(set_attr "type" "fadd")])
2271
2272 (define_insn ""
2273 [(set (match_operand:SF 0 "register_operand" "=&f,f")
2274 (if_then_else:SF
2275 (match_operator 3 "signed_comparison_operator"
2276 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2277 (match_operand:DF 2 "fp0_operand" "G,G")])
2278 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2279 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2280 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2281 "@
2282 fcmov%C3 %R4,%R1,%0
2283 fcmov%D3 %R4,%R5,%0"
2284 [(set_attr "type" "fadd")])
2285
2286 (define_insn ""
2287 [(set (match_operand:SF 0 "register_operand" "=f,f")
2288 (if_then_else:SF
2289 (match_operator 3 "signed_comparison_operator"
2290 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2291 (match_operand:DF 2 "fp0_operand" "G,G")])
2292 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2293 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2294 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2295 "@
2296 fcmov%C3 %R4,%R1,%0
2297 fcmov%D3 %R4,%R5,%0"
2298 [(set_attr "type" "fadd")])
2299
2300 (define_insn ""
2301 [(set (match_operand:DF 0 "register_operand" "=f,f")
2302 (if_then_else:DF
2303 (match_operator 3 "signed_comparison_operator"
2304 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2305 (match_operand:DF 2 "fp0_operand" "G,G")])
2306 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2307 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2308 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2309 "@
2310 fcmov%C3 %R4,%R1,%0
2311 fcmov%D3 %R4,%R5,%0"
2312 [(set_attr "type" "fadd")])
2313
2314 (define_insn ""
2315 [(set (match_operand:DF 0 "register_operand" "=f,f")
2316 (if_then_else:DF
2317 (match_operator 3 "signed_comparison_operator"
2318 [(float_extend:DF
2319 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2320 (match_operand:DF 2 "fp0_operand" "G,G")])
2321 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2322 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2323 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2324 "@
2325 fcmov%C3 %R4,%R1,%0
2326 fcmov%D3 %R4,%R5,%0"
2327 [(set_attr "type" "fadd")])
2328
2329 (define_insn ""
2330 [(set (match_operand:SF 0 "register_operand" "=f,f")
2331 (if_then_else:SF
2332 (match_operator 3 "signed_comparison_operator"
2333 [(float_extend:DF
2334 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2335 (match_operand:DF 2 "fp0_operand" "G,G")])
2336 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2337 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2338 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2339 "@
2340 fcmov%C3 %R4,%R1,%0
2341 fcmov%D3 %R4,%R5,%0"
2342 [(set_attr "type" "fadd")])
2343
2344 (define_insn ""
2345 [(set (match_operand:DF 0 "register_operand" "=f,f")
2346 (if_then_else:DF
2347 (match_operator 3 "signed_comparison_operator"
2348 [(float_extend:DF
2349 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2350 (match_operand:DF 2 "fp0_operand" "G,G")])
2351 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2352 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2353 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2354 "@
2355 fcmov%C3 %R4,%R1,%0
2356 fcmov%D3 %R4,%R5,%0"
2357 [(set_attr "type" "fadd")])
2358
2359 (define_expand "maxdf3"
2360 [(set (match_dup 3)
2361 (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2362 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2363 (set (match_operand:DF 0 "register_operand" "")
2364 (if_then_else:DF (eq (match_dup 3) (match_dup 4))
2365 (match_dup 1) (match_dup 2)))]
2366 "TARGET_FP"
2367 "
2368 { operands[3] = gen_reg_rtx (DFmode);
2369 operands[4] = CONST0_RTX (DFmode);
2370 }")
2371
2372 (define_expand "mindf3"
2373 [(set (match_dup 3)
2374 (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2375 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2376 (set (match_operand:DF 0 "register_operand" "")
2377 (if_then_else:DF (ne (match_dup 3) (match_dup 4))
2378 (match_dup 1) (match_dup 2)))]
2379 "TARGET_FP"
2380 "
2381 { operands[3] = gen_reg_rtx (DFmode);
2382 operands[4] = CONST0_RTX (DFmode);
2383 }")
2384
2385 (define_expand "maxsf3"
2386 [(set (match_dup 3)
2387 (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2388 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2389 (set (match_operand:SF 0 "register_operand" "")
2390 (if_then_else:SF (eq (match_dup 3) (match_dup 4))
2391 (match_dup 1) (match_dup 2)))]
2392 "TARGET_FP"
2393 "
2394 { operands[3] = gen_reg_rtx (DFmode);
2395 operands[4] = CONST0_RTX (DFmode);
2396 }")
2397
2398 (define_expand "minsf3"
2399 [(set (match_dup 3)
2400 (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2401 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2402 (set (match_operand:SF 0 "register_operand" "")
2403 (if_then_else:SF (ne (match_dup 3) (match_dup 4))
2404 (match_dup 1) (match_dup 2)))]
2405 "TARGET_FP"
2406 "
2407 { operands[3] = gen_reg_rtx (DFmode);
2408 operands[4] = CONST0_RTX (DFmode);
2409 }")
2410
2411 (define_insn ""
2412 [(set (pc)
2413 (if_then_else
2414 (match_operator 1 "signed_comparison_operator"
2415 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2416 (match_operand:DF 3 "fp0_operand" "G")])
2417 (label_ref (match_operand 0 "" ""))
2418 (pc)))]
2419 "TARGET_FP"
2420 "fb%C1 %R2,%0"
2421 [(set_attr "type" "fbr")])
2422
2423 (define_insn ""
2424 [(set (pc)
2425 (if_then_else
2426 (match_operator 1 "signed_comparison_operator"
2427 [(float_extend:DF
2428 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2429 (match_operand:DF 3 "fp0_operand" "G")])
2430 (label_ref (match_operand 0 "" ""))
2431 (pc)))]
2432 "TARGET_FP"
2433 "fb%C1 %R2,%0"
2434 [(set_attr "type" "fbr")])
2435 \f
2436 ;; These are the main define_expand's used to make conditional branches
2437 ;; and compares.
2438
2439 (define_expand "cmpdf"
2440 [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
2441 (match_operand:DF 1 "reg_or_fp0_operand" "")))]
2442 "TARGET_FP"
2443 "
2444 {
2445 alpha_compare_op0 = operands[0];
2446 alpha_compare_op1 = operands[1];
2447 alpha_compare_fp_p = 1;
2448 DONE;
2449 }")
2450
2451 (define_expand "cmpdi"
2452 [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
2453 (match_operand:DI 1 "reg_or_8bit_operand" "")))]
2454 ""
2455 "
2456 {
2457 alpha_compare_op0 = operands[0];
2458 alpha_compare_op1 = operands[1];
2459 alpha_compare_fp_p = 0;
2460 DONE;
2461 }")
2462
2463 (define_expand "beq"
2464 [(set (match_dup 1) (match_dup 2))
2465 (set (pc)
2466 (if_then_else (match_dup 3)
2467 (label_ref (match_operand 0 "" ""))
2468 (pc)))]
2469 ""
2470 "
2471 {
2472 enum machine_mode mode;
2473 enum rtx_code compare_code, branch_code;
2474
2475 if (alpha_compare_fp_p)
2476 mode = DFmode, compare_code = EQ, branch_code = NE;
2477 else
2478 {
2479 mode = DImode, compare_code = MINUS, branch_code = EQ;
2480 if (GET_CODE (alpha_compare_op1) == CONST_INT)
2481 {
2482 compare_code = PLUS;
2483 alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
2484 }
2485 }
2486
2487 operands[1] = gen_reg_rtx (mode);
2488 operands[2] = gen_rtx (compare_code, mode,
2489 alpha_compare_op0, alpha_compare_op1);
2490 operands[3] = gen_rtx (branch_code, VOIDmode,
2491 operands[1], CONST0_RTX (mode));
2492 }")
2493
2494 (define_expand "bne"
2495 [(set (match_dup 1) (match_dup 2))
2496 (set (pc)
2497 (if_then_else (match_dup 3)
2498 (label_ref (match_operand 0 "" ""))
2499 (pc)))]
2500 ""
2501 "
2502 {
2503 enum machine_mode mode;
2504 enum rtx_code compare_code, branch_code;
2505
2506 if (alpha_compare_fp_p)
2507 mode = DFmode, compare_code = EQ, branch_code = EQ;
2508 else
2509 {
2510 mode = DImode, compare_code = MINUS, branch_code = NE;
2511 if (GET_CODE (alpha_compare_op1) == CONST_INT)
2512 {
2513 compare_code = PLUS;
2514 alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
2515 }
2516 }
2517
2518 operands[1] = gen_reg_rtx (mode);
2519 operands[2] = gen_rtx (compare_code, mode,
2520 alpha_compare_op0, alpha_compare_op1);
2521 operands[3] = gen_rtx (branch_code, VOIDmode,
2522 operands[1], CONST0_RTX (mode));
2523 }")
2524
2525 (define_expand "blt"
2526 [(set (match_dup 1) (match_dup 2))
2527 (set (pc)
2528 (if_then_else (match_dup 3)
2529 (label_ref (match_operand 0 "" ""))
2530 (pc)))]
2531 ""
2532 "
2533 {
2534 enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
2535 operands[1] = gen_reg_rtx (mode);
2536 operands[2] = gen_rtx (LT, mode, alpha_compare_op0, alpha_compare_op1);
2537 operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
2538 }")
2539
2540 (define_expand "ble"
2541 [(set (match_dup 1) (match_dup 2))
2542 (set (pc)
2543 (if_then_else (match_dup 3)
2544 (label_ref (match_operand 0 "" ""))
2545 (pc)))]
2546 ""
2547 "
2548 {
2549 enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
2550 operands[1] = gen_reg_rtx (mode);
2551 operands[2] = gen_rtx (LE, mode, alpha_compare_op0, alpha_compare_op1);
2552 operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
2553 }")
2554
2555 (define_expand "bgt"
2556 [(set (match_dup 1) (match_dup 2))
2557 (set (pc)
2558 (if_then_else (match_dup 3)
2559 (label_ref (match_operand 0 "" ""))
2560 (pc)))]
2561 ""
2562 "
2563 {
2564 if (alpha_compare_fp_p)
2565 {
2566 operands[1] = gen_reg_rtx (DFmode);
2567 operands[2] = gen_rtx (LT, DFmode, alpha_compare_op1, alpha_compare_op0);
2568 operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
2569 }
2570 else
2571 {
2572 operands[1] = gen_reg_rtx (DImode);
2573 operands[2] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
2574 operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2575 }
2576 }")
2577
2578 (define_expand "bge"
2579 [(set (match_dup 1) (match_dup 2))
2580 (set (pc)
2581 (if_then_else (match_dup 3)
2582 (label_ref (match_operand 0 "" ""))
2583 (pc)))]
2584 ""
2585 "
2586 {
2587 if (alpha_compare_fp_p)
2588 {
2589 operands[1] = gen_reg_rtx (DFmode);
2590 operands[2] = gen_rtx (LE, DFmode, alpha_compare_op1, alpha_compare_op0);
2591 operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
2592 }
2593 else
2594 {
2595 operands[1] = gen_reg_rtx (DImode);
2596 operands[2] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
2597 operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2598 }
2599 }")
2600
2601 (define_expand "bltu"
2602 [(set (match_dup 1) (match_dup 2))
2603 (set (pc)
2604 (if_then_else (match_dup 3)
2605 (label_ref (match_operand 0 "" ""))
2606 (pc)))]
2607 ""
2608 "
2609 {
2610 operands[1] = gen_reg_rtx (DImode);
2611 operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2612 operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
2613 }")
2614
2615 (define_expand "bleu"
2616 [(set (match_dup 1) (match_dup 2))
2617 (set (pc)
2618 (if_then_else (match_dup 3)
2619 (label_ref (match_operand 0 "" ""))
2620 (pc)))]
2621 ""
2622 "
2623 {
2624 operands[1] = gen_reg_rtx (DImode);
2625 operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2626 operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
2627 }")
2628
2629 (define_expand "bgtu"
2630 [(set (match_dup 1) (match_dup 2))
2631 (set (pc)
2632 (if_then_else (match_dup 3)
2633 (label_ref (match_operand 0 "" ""))
2634 (pc)))]
2635 ""
2636 "
2637 {
2638 operands[1] = gen_reg_rtx (DImode);
2639 operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2640 operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2641 }")
2642
2643 (define_expand "bgeu"
2644 [(set (match_dup 1) (match_dup 2))
2645 (set (pc)
2646 (if_then_else (match_dup 3)
2647 (label_ref (match_operand 0 "" ""))
2648 (pc)))]
2649 ""
2650 "
2651 {
2652 operands[1] = gen_reg_rtx (DImode);
2653 operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2654 operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2655 }")
2656
2657 (define_expand "seq"
2658 [(set (match_operand:DI 0 "register_operand" "")
2659 (match_dup 1))]
2660 ""
2661 "
2662 {
2663 if (alpha_compare_fp_p)
2664 FAIL;
2665
2666 operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
2667 }")
2668
2669 (define_expand "sne"
2670 [(set (match_operand:DI 0 "register_operand" "")
2671 (match_dup 1))
2672 (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
2673 ""
2674 "
2675 {
2676 if (alpha_compare_fp_p)
2677 FAIL;
2678
2679 operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
2680 }")
2681
2682 (define_expand "slt"
2683 [(set (match_operand:DI 0 "register_operand" "")
2684 (match_dup 1))]
2685 ""
2686 "
2687 {
2688 if (alpha_compare_fp_p)
2689 FAIL;
2690
2691 operands[1] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
2692 }")
2693
2694 (define_expand "sle"
2695 [(set (match_operand:DI 0 "register_operand" "")
2696 (match_dup 1))]
2697 ""
2698 "
2699 {
2700 if (alpha_compare_fp_p)
2701 FAIL;
2702
2703 operands[1] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
2704 }")
2705
2706 (define_expand "sgt"
2707 [(set (match_operand:DI 0 "register_operand" "")
2708 (match_dup 1))]
2709 ""
2710 "
2711 {
2712 if (alpha_compare_fp_p)
2713 FAIL;
2714
2715 operands[1] = gen_rtx (LT, DImode, force_reg (DImode, alpha_compare_op1),
2716 alpha_compare_op0);
2717 }")
2718
2719 (define_expand "sge"
2720 [(set (match_operand:DI 0 "register_operand" "")
2721 (match_dup 1))]
2722 ""
2723 "
2724 {
2725 if (alpha_compare_fp_p)
2726 FAIL;
2727
2728 operands[1] = gen_rtx (LE, DImode, force_reg (DImode, alpha_compare_op1),
2729 alpha_compare_op0);
2730 }")
2731
2732 (define_expand "sltu"
2733 [(set (match_operand:DI 0 "register_operand" "")
2734 (match_dup 1))]
2735 ""
2736 "
2737 {
2738 if (alpha_compare_fp_p)
2739 FAIL;
2740
2741 operands[1] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2742 }")
2743
2744 (define_expand "sleu"
2745 [(set (match_operand:DI 0 "register_operand" "")
2746 (match_dup 1))]
2747 ""
2748 "
2749 {
2750 if (alpha_compare_fp_p)
2751 FAIL;
2752
2753 operands[1] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2754 }")
2755
2756 (define_expand "sgtu"
2757 [(set (match_operand:DI 0 "register_operand" "")
2758 (match_dup 1))]
2759 ""
2760 "
2761 {
2762 if (alpha_compare_fp_p)
2763 FAIL;
2764
2765 operands[1] = gen_rtx (LTU, DImode, force_reg (DImode, alpha_compare_op1),
2766 alpha_compare_op0);
2767 }")
2768
2769 (define_expand "sgeu"
2770 [(set (match_operand:DI 0 "register_operand" "")
2771 (match_dup 1))]
2772 ""
2773 "
2774 {
2775 if (alpha_compare_fp_p)
2776 FAIL;
2777
2778 operands[1] = gen_rtx (LEU, DImode, force_reg (DImode, alpha_compare_op1),
2779 alpha_compare_op0);
2780 }")
2781 \f
2782 ;; These are the main define_expand's used to make conditional moves.
2783
2784 (define_expand "movsicc"
2785 [(set (match_operand:SI 0 "register_operand" "")
2786 (if_then_else:DI (match_operand 1 "comparison_operator" "")
2787 (match_operand:SI 2 "reg_or_8bit_operand" "")
2788 (match_operand:SI 3 "reg_or_8bit_operand" "")))]
2789 ""
2790 "
2791 {
2792 if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
2793 FAIL;
2794 }")
2795
2796 (define_expand "movdicc"
2797 [(set (match_operand:DI 0 "register_operand" "")
2798 (if_then_else:DI (match_operand 1 "comparison_operator" "")
2799 (match_operand:DI 2 "reg_or_8bit_operand" "")
2800 (match_operand:DI 3 "reg_or_8bit_operand" "")))]
2801 ""
2802 "
2803 {
2804 if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
2805 FAIL;
2806 }")
2807
2808 (define_expand "movsfcc"
2809 [(set (match_operand:SF 0 "register_operand" "")
2810 (if_then_else:SF (match_operand 1 "comparison_operator" "")
2811 (match_operand:SF 2 "reg_or_8bit_operand" "")
2812 (match_operand:SF 3 "reg_or_8bit_operand" "")))]
2813 ""
2814 "
2815 {
2816 if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
2817 FAIL;
2818 }")
2819
2820 (define_expand "movdfcc"
2821 [(set (match_operand:DF 0 "register_operand" "")
2822 (if_then_else:DF (match_operand 1 "comparison_operator" "")
2823 (match_operand:DF 2 "reg_or_8bit_operand" "")
2824 (match_operand:DF 3 "reg_or_8bit_operand" "")))]
2825 ""
2826 "
2827 {
2828 if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
2829 FAIL;
2830 }")
2831 \f
2832 ;; These define_split definitions are used in cases when comparisons have
2833 ;; not be stated in the correct way and we need to reverse the second
2834 ;; comparison. For example, x >= 7 has to be done as x < 6 with the
2835 ;; comparison that tests the result being reversed. We have one define_split
2836 ;; for each use of a comparison. They do not match valid insns and need
2837 ;; not generate valid insns.
2838 ;;
2839 ;; We can also handle equality comparisons (and inequality comparisons in
2840 ;; cases where the resulting add cannot overflow) by doing an add followed by
2841 ;; a comparison with zero. This is faster since the addition takes one
2842 ;; less cycle than a compare when feeding into a conditional move.
2843 ;; For this case, we also have an SImode pattern since we can merge the add
2844 ;; and sign extend and the order doesn't matter.
2845 ;;
2846 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
2847 ;; operation could have been generated.
2848
2849 (define_split
2850 [(set (match_operand:DI 0 "register_operand" "")
2851 (if_then_else:DI
2852 (match_operator 1 "comparison_operator"
2853 [(match_operand:DI 2 "reg_or_0_operand" "")
2854 (match_operand:DI 3 "reg_or_cint_operand" "")])
2855 (match_operand:DI 4 "reg_or_cint_operand" "")
2856 (match_operand:DI 5 "reg_or_cint_operand" "")))
2857 (clobber (match_operand:DI 6 "register_operand" ""))]
2858 "operands[3] != const0_rtx"
2859 [(set (match_dup 6) (match_dup 7))
2860 (set (match_dup 0)
2861 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
2862 "
2863 { enum rtx_code code = GET_CODE (operands[1]);
2864 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2865
2866 /* If we are comparing for equality with a constant and that constant
2867 appears in the arm when the register equals the constant, use the
2868 register since that is more likely to match (and to produce better code
2869 if both would). */
2870
2871 if (code == EQ && GET_CODE (operands[3]) == CONST_INT
2872 && rtx_equal_p (operands[4], operands[3]))
2873 operands[4] = operands[2];
2874
2875 else if (code == NE && GET_CODE (operands[3]) == CONST_INT
2876 && rtx_equal_p (operands[5], operands[3]))
2877 operands[5] = operands[2];
2878
2879 if (code == NE || code == EQ
2880 || (extended_count (operands[2], DImode, unsignedp) >= 1
2881 && extended_count (operands[3], DImode, unsignedp) >= 1))
2882 {
2883 if (GET_CODE (operands[3]) == CONST_INT)
2884 operands[7] = gen_rtx (PLUS, DImode, operands[2],
2885 GEN_INT (- INTVAL (operands[3])));
2886 else
2887 operands[7] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
2888
2889 operands[8] = gen_rtx (code, VOIDmode, operands[6], const0_rtx);
2890 }
2891
2892 else if (code == EQ || code == LE || code == LT
2893 || code == LEU || code == LTU)
2894 {
2895 operands[7] = gen_rtx (code, DImode, operands[2], operands[3]);
2896 operands[8] = gen_rtx (NE, VOIDmode, operands[6], const0_rtx);
2897 }
2898 else
2899 {
2900 operands[7] = gen_rtx (reverse_condition (code), DImode, operands[2],
2901 operands[3]);
2902 operands[8] = gen_rtx (EQ, VOIDmode, operands[6], const0_rtx);
2903 }
2904 }")
2905
2906 (define_split
2907 [(set (match_operand:DI 0 "register_operand" "")
2908 (if_then_else:DI
2909 (match_operator 1 "comparison_operator"
2910 [(match_operand:SI 2 "reg_or_0_operand" "")
2911 (match_operand:SI 3 "reg_or_cint_operand" "")])
2912 (match_operand:DI 4 "reg_or_8bit_operand" "")
2913 (match_operand:DI 5 "reg_or_8bit_operand" "")))
2914 (clobber (match_operand:DI 6 "register_operand" ""))]
2915 "operands[3] != const0_rtx
2916 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
2917 [(set (match_dup 6) (match_dup 7))
2918 (set (match_dup 0)
2919 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
2920 "
2921 { enum rtx_code code = GET_CODE (operands[1]);
2922 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2923 rtx tem;
2924
2925 if ((code != NE && code != EQ
2926 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
2927 && extended_count (operands[3], DImode, unsignedp) >= 1)))
2928 FAIL;
2929
2930 if (GET_CODE (operands[3]) == CONST_INT)
2931 tem = gen_rtx (PLUS, SImode, operands[2],
2932 GEN_INT (- INTVAL (operands[3])));
2933 else
2934 tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
2935
2936 operands[7] = gen_rtx (SIGN_EXTEND, DImode, tem);
2937 operands[8] = gen_rtx (GET_CODE (operands[1]), VOIDmode, operands[6],
2938 const0_rtx);
2939 }")
2940
2941 (define_split
2942 [(set (pc)
2943 (if_then_else
2944 (match_operator 1 "comparison_operator"
2945 [(match_operand:DI 2 "reg_or_0_operand" "")
2946 (match_operand:DI 3 "reg_or_cint_operand" "")])
2947 (label_ref (match_operand 0 "" ""))
2948 (pc)))
2949 (clobber (match_operand:DI 4 "register_operand" ""))]
2950 "operands[3] != const0_rtx"
2951 [(set (match_dup 4) (match_dup 5))
2952 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
2953 "
2954 { enum rtx_code code = GET_CODE (operands[1]);
2955 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2956
2957 if (code == NE || code == EQ
2958 || (extended_count (operands[2], DImode, unsignedp) >= 1
2959 && extended_count (operands[3], DImode, unsignedp) >= 1))
2960 {
2961 if (GET_CODE (operands[3]) == CONST_INT)
2962 operands[5] = gen_rtx (PLUS, DImode, operands[2],
2963 GEN_INT (- INTVAL (operands[3])));
2964 else
2965 operands[5] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
2966
2967 operands[6] = gen_rtx (code, VOIDmode, operands[4], const0_rtx);
2968 }
2969
2970 else if (code == EQ || code == LE || code == LT
2971 || code == LEU || code == LTU)
2972 {
2973 operands[5] = gen_rtx (code, DImode, operands[2], operands[3]);
2974 operands[6] = gen_rtx (NE, VOIDmode, operands[4], const0_rtx);
2975 }
2976 else
2977 {
2978 operands[5] = gen_rtx (reverse_condition (code), DImode, operands[2],
2979 operands[3]);
2980 operands[6] = gen_rtx (EQ, VOIDmode, operands[4], const0_rtx);
2981 }
2982 }")
2983
2984 (define_split
2985 [(set (pc)
2986 (if_then_else
2987 (match_operator 1 "comparison_operator"
2988 [(match_operand:SI 2 "reg_or_0_operand" "")
2989 (match_operand:SI 3 "const_int_operand" "")])
2990 (label_ref (match_operand 0 "" ""))
2991 (pc)))
2992 (clobber (match_operand:DI 4 "register_operand" ""))]
2993 "operands[3] != const0_rtx
2994 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
2995 [(set (match_dup 4) (match_dup 5))
2996 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
2997 "
2998 { rtx tem;
2999
3000 if (GET_CODE (operands[3]) == CONST_INT)
3001 tem = gen_rtx (PLUS, SImode, operands[2],
3002 GEN_INT (- INTVAL (operands[3])));
3003 else
3004 tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
3005
3006 operands[5] = gen_rtx (SIGN_EXTEND, DImode, tem);
3007 operands[6] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
3008 operands[4], const0_rtx);
3009 }")
3010
3011 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
3012 ;; This eliminates one, and sometimes two, insns when the AND can be done
3013 ;; with a ZAP.
3014 (define_split
3015 [(set (match_operand:DI 0 "register_operand" "")
3016 (match_operator 1 "comparison_operator"
3017 [(match_operand:DI 2 "register_operand" "")
3018 (match_operand:DI 3 "const_int_operand" "")]))
3019 (clobber (match_operand:DI 4 "register_operand" ""))]
3020 "exact_log2 (INTVAL (operands[3]) + 1) >= 0
3021 && (GET_CODE (operands[1]) == GTU
3022 || GET_CODE (operands[1]) == LEU
3023 || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
3024 && extended_count (operands[2], DImode, 1) > 0))"
3025 [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
3026 (set (match_dup 0) (match_dup 6))]
3027 "
3028 {
3029 operands[5] = GEN_INT (~ INTVAL (operands[3]));
3030 operands[6] = gen_rtx (((GET_CODE (operands[1]) == GTU
3031 || GET_CODE (operands[1]) == GT)
3032 ? NE : EQ),
3033 DImode, operands[4], const0_rtx);
3034 }")
3035 \f
3036 ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
3037 ;; work differently, so we have different patterns for each.
3038
3039 (define_expand "call"
3040 [(use (match_operand:DI 0 "" ""))
3041 (use (match_operand 1 "" ""))
3042 (use (match_operand 2 "" ""))
3043 (use (match_operand 3 "" ""))]
3044 ""
3045 "
3046 { if (TARGET_WINDOWS_NT)
3047 emit_call_insn (gen_call_nt (operands[0], operands[1]));
3048 else if (TARGET_OPEN_VMS)
3049 emit_call_insn (gen_call_vms (operands[0], operands[2]));
3050 else
3051 emit_call_insn (gen_call_osf (operands[0], operands[1]));
3052
3053 DONE;
3054 }")
3055
3056 (define_expand "call_osf"
3057 [(parallel [(call (mem:DI (match_operand 0 "" ""))
3058 (match_operand 1 "" ""))
3059 (clobber (reg:DI 27))
3060 (clobber (reg:DI 26))])]
3061 ""
3062 "
3063 { if (GET_CODE (operands[0]) != MEM)
3064 abort ();
3065
3066 operands[0] = XEXP (operands[0], 0);
3067
3068 if (GET_CODE (operands[0]) != SYMBOL_REF
3069 && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
3070 {
3071 rtx tem = gen_rtx (REG, DImode, 27);
3072 emit_move_insn (tem, operands[0]);
3073 operands[0] = tem;
3074 }
3075 }")
3076
3077 (define_expand "call_nt"
3078 [(parallel [(call (mem:DI (match_operand:DI 0 "" ""))
3079 (match_operand 1 "" ""))
3080 (clobber (reg:DI 26))])]
3081 ""
3082 "
3083 { if (GET_CODE (operands[0]) != MEM)
3084 abort ();
3085 operands[0] = XEXP (operands[0], 0);
3086
3087 if (GET_CODE (operands[1]) != SYMBOL_REF
3088 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3089 {
3090 rtx tem = gen_rtx (REG, DImode, 27);
3091 emit_move_insn (tem, operands[1]);
3092 operands[1] = tem;
3093 }
3094 }")
3095
3096 ;;
3097 ;; call openvms/alpha
3098 ;; op 0: symbol ref for called function
3099 ;; op 1: next_arg_reg (argument information value for R25)
3100 ;;
3101 (define_expand "call_vms"
3102 [(parallel [(call (mem:DI (match_operand 0 "" ""))
3103 (match_operand 1 "" ""))
3104 (use (match_dup 2))
3105 (use (reg:DI 25))
3106 (use (reg:DI 26))
3107 (clobber (reg:DI 27))])]
3108 ""
3109 "
3110 { if (GET_CODE (operands[0]) != MEM)
3111 abort ();
3112
3113 operands[0] = XEXP (operands[0], 0);
3114
3115 /* Always load AI with argument information, then handle symbolic and
3116 indirect call differently. Load RA and set operands[2] to PV in
3117 both cases. */
3118
3119 emit_move_insn (gen_rtx (REG, DImode, 25), operands[1]);
3120 if (GET_CODE (operands[0]) == SYMBOL_REF)
3121 {
3122 extern char *savealloc ();
3123 char *symbol = XSTR (operands[0], 0);
3124 char *linksym = savealloc (strlen (symbol) + 5);
3125 rtx linkage;
3126
3127 alpha_need_linkage (symbol, 0);
3128
3129 strcpy (linksym, symbol);
3130 strcat (linksym, \"..lk\");
3131 linkage = gen_rtx (SYMBOL_REF, Pmode, linksym);
3132
3133 emit_move_insn (gen_rtx (REG, Pmode, 26), gen_rtx (MEM, Pmode, linkage));
3134
3135 operands[2]
3136 = validize_mem (gen_rtx (MEM, Pmode, plus_constant (linkage, 8)));
3137 }
3138 else
3139 {
3140 emit_move_insn (gen_rtx (REG, Pmode, 26),
3141 gen_rtx (MEM, Pmode, plus_constant (operands[0], 8)));
3142
3143 operands[2] = operands[0];
3144 }
3145
3146 }")
3147
3148 (define_expand "call_value"
3149 [(use (match_operand 0 "" ""))
3150 (use (match_operand:DI 1 "" ""))
3151 (use (match_operand 2 "" ""))
3152 (use (match_operand 3 "" ""))
3153 (use (match_operand 4 "" ""))]
3154 ""
3155 "
3156 { if (TARGET_WINDOWS_NT)
3157 emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
3158 else if (TARGET_OPEN_VMS)
3159 emit_call_insn (gen_call_value_vms (operands[0], operands[1],
3160 operands[3]));
3161 else
3162 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
3163 operands[2]));
3164 DONE;
3165 }")
3166
3167 (define_expand "call_value_osf"
3168 [(parallel [(set (match_operand 0 "" "")
3169 (call (mem:DI (match_operand 1 "" ""))
3170 (match_operand 2 "" "")))
3171 (clobber (reg:DI 27))
3172 (clobber (reg:DI 26))])]
3173 ""
3174 "
3175 { if (GET_CODE (operands[1]) != MEM)
3176 abort ();
3177
3178 operands[1] = XEXP (operands[1], 0);
3179
3180 if (GET_CODE (operands[1]) != SYMBOL_REF
3181 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3182 {
3183 rtx tem = gen_rtx (REG, DImode, 27);
3184 emit_move_insn (tem, operands[1]);
3185 operands[1] = tem;
3186 }
3187 }")
3188
3189 (define_expand "call_value_nt"
3190 [(parallel [(set (match_operand 0 "" "")
3191 (call (mem:DI (match_operand:DI 1 "" ""))
3192 (match_operand 2 "" "")))
3193 (clobber (reg:DI 26))])]
3194 ""
3195 "
3196 { if (GET_CODE (operands[1]) != MEM)
3197 abort ();
3198
3199 operands[1] = XEXP (operands[1], 0);
3200 if (GET_CODE (operands[1]) != SYMBOL_REF
3201 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3202 {
3203 rtx tem = gen_rtx (REG, DImode, 27);
3204 emit_move_insn (tem, operands[1]);
3205 operands[1] = tem;
3206 }
3207 }")
3208
3209 (define_expand "call_value_vms"
3210 [(parallel [(set (match_operand 0 "" "")
3211 (call (mem:DI (match_operand:DI 1 "" ""))
3212 (match_operand 2 "" "")))
3213 (use (match_dup 3))
3214 (use (reg:DI 25))
3215 (use (reg:DI 26))
3216 (clobber (reg:DI 27))])]
3217 ""
3218 "
3219 { if (GET_CODE (operands[1]) != MEM)
3220 abort ();
3221
3222 operands[1] = XEXP (operands[1], 0);
3223
3224 /* Always load AI with argument information, then handle symbolic and
3225 indirect call differently. Load RA and set operands[3] to PV in
3226 both cases. */
3227
3228 emit_move_insn (gen_rtx (REG, DImode, 25), operands[2]);
3229 if (GET_CODE (operands[1]) == SYMBOL_REF)
3230 {
3231 extern char *savealloc ();
3232 char *symbol = XSTR (operands[1], 0);
3233 char *linksym = savealloc (strlen (symbol) + 5);
3234 rtx linkage;
3235
3236 alpha_need_linkage (symbol, 0);
3237 strcpy (linksym, symbol);
3238 strcat (linksym, \"..lk\");
3239 linkage = gen_rtx (SYMBOL_REF, Pmode, linksym);
3240
3241 emit_move_insn (gen_rtx (REG, Pmode, 26), gen_rtx (MEM, Pmode, linkage));
3242
3243 operands[3]
3244 = validize_mem (gen_rtx (MEM, Pmode, plus_constant (linkage, 8)));
3245 }
3246 else
3247 {
3248 emit_move_insn (gen_rtx (REG, Pmode, 26),
3249 gen_rtx (MEM, Pmode, plus_constant (operands[1], 8)));
3250
3251 operands[3] = operands[1];
3252 }
3253 }")
3254
3255 (define_insn ""
3256 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3257 (match_operand 1 "" ""))
3258 (clobber (reg:DI 27))
3259 (clobber (reg:DI 26))]
3260 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && alpha_tp == ALPHA_TP_INSN"
3261 "@
3262 jsr $26,($27),0\;trapb\;ldgp $29,4($26)
3263 bsr $26,%0..ng\;trapb
3264 jsr $26,%0\;trapb\;ldgp $29,4($26)"
3265 [(set_attr "type" "jsr,jsr,ibr")])
3266
3267 (define_insn ""
3268 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3269 (match_operand 1 "" ""))
3270 (clobber (reg:DI 27))
3271 (clobber (reg:DI 26))]
3272 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
3273 "@
3274 jsr $26,($27),0\;ldgp $29,0($26)
3275 bsr $26,%0..ng
3276 jsr $26,%0\;ldgp $29,0($26)"
3277 [(set_attr "type" "jsr,jsr,ibr")])
3278
3279 (define_insn ""
3280 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
3281 (match_operand 1 "" ""))
3282 (clobber (reg:DI 26))]
3283 "TARGET_WINDOWS_NT"
3284 "@
3285 jsr $26,(%0)
3286 bsr $26,%0"
3287 [(set_attr "type" "jsr")])
3288
3289 (define_insn ""
3290 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
3291 (match_operand 1 "" ""))
3292 (use (match_operand:DI 2 "general_operand" "r,m"))
3293 (use (reg:DI 25))
3294 (use (reg:DI 26))
3295 (clobber (reg:DI 27))]
3296 "TARGET_OPEN_VMS"
3297 "@
3298 bis %2,%2,$27\;jsr $26,0\;ldq $27,0($29)
3299 ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
3300 [(set_attr "type" "jsr")])
3301
3302 (define_insn ""
3303 [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3304 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3305 (match_operand 2 "" "")))
3306 (clobber (reg:DI 27))
3307 (clobber (reg:DI 26))]
3308 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && alpha_tp == ALPHA_TP_INSN"
3309 "@
3310 jsr $26,($27),0\;trapb\;ldgp $29,4($26)
3311 bsr $26,%1..ng\;trapb
3312 jsr $26,%1\;trapb\;ldgp $29,4($26)"
3313 [(set_attr "type" "jsr,jsr,ibr")])
3314
3315 (define_insn ""
3316 [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3317 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3318 (match_operand 2 "" "")))
3319 (clobber (reg:DI 27))
3320 (clobber (reg:DI 26))]
3321 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
3322 "@
3323 jsr $26,($27),0\;ldgp $29,0($26)
3324 bsr $26,%1..ng
3325 jsr $26,%1\;ldgp $29,0($26)"
3326 [(set_attr "type" "jsr,jsr,ibr")])
3327
3328 (define_insn ""
3329 [(set (match_operand 0 "register_operand" "=rf,rf")
3330 (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
3331 (match_operand 2 "" "")))
3332 (clobber (reg:DI 26))]
3333 "TARGET_WINDOWS_NT"
3334 "@
3335 jsr $26,(%1)
3336 bsr $26,%1"
3337 [(set_attr "type" "jsr")])
3338
3339 (define_insn ""
3340 [(set (match_operand 0 "register_operand" "")
3341 (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
3342 (match_operand 2 "" "")))
3343 (use (match_operand:DI 3 "general_operand" "r,m"))
3344 (use (reg:DI 25))
3345 (use (reg:DI 26))
3346 (clobber (reg:DI 27))]
3347 "TARGET_OPEN_VMS"
3348 "@
3349 bis %3,%3,$27\;jsr $26,0\;ldq $27,0($29)
3350 ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
3351 [(set_attr "type" "jsr")])
3352
3353 ;; Call subroutine returning any type.
3354
3355 (define_expand "untyped_call"
3356 [(parallel [(call (match_operand 0 "" "")
3357 (const_int 0))
3358 (match_operand 1 "" "")
3359 (match_operand 2 "" "")])]
3360 ""
3361 "
3362 {
3363 int i;
3364
3365 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3366
3367 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3368 {
3369 rtx set = XVECEXP (operands[2], 0, i);
3370 emit_move_insn (SET_DEST (set), SET_SRC (set));
3371 }
3372
3373 /* The optimizer does not know that the call sets the function value
3374 registers we stored in the result block. We avoid problems by
3375 claiming that all hard registers are used and clobbered at this
3376 point. */
3377 emit_insn (gen_blockage ());
3378
3379 DONE;
3380 }")
3381
3382 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3383 ;; all of memory. This blocks insns from being moved across this point.
3384
3385 (define_insn "blockage"
3386 [(unspec_volatile [(const_int 0)] 1)]
3387 ""
3388 "")
3389
3390 (define_insn "jump"
3391 [(set (pc)
3392 (label_ref (match_operand 0 "" "")))]
3393 ""
3394 "br $31,%l0"
3395 [(set_attr "type" "ibr")])
3396
3397 (define_insn "return"
3398 [(return)]
3399 "direct_return ()"
3400 "ret $31,($26),1"
3401 [(set_attr "type" "ibr")])
3402
3403 (define_insn "indirect_jump"
3404 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3405 ""
3406 "jmp $31,(%0),0"
3407 [(set_attr "type" "ibr")])
3408
3409 (define_insn "nop"
3410 [(const_int 0)]
3411 ""
3412 "bis $31,$31,$31"
3413 [(set_attr "type" "ilog")])
3414
3415 (define_expand "tablejump"
3416 [(use (match_operand:SI 0 "register_operand" ""))
3417 (use (match_operand:SI 1 "" ""))]
3418 ""
3419 "
3420 {
3421 if (TARGET_WINDOWS_NT)
3422 emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
3423 else if (TARGET_OPEN_VMS)
3424 emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
3425 else
3426 emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
3427
3428 DONE;
3429 }")
3430
3431 (define_expand "tablejump_osf"
3432 [(set (match_dup 3)
3433 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3434 (parallel [(set (pc)
3435 (plus:DI (match_dup 3)
3436 (label_ref:DI (match_operand 1 "" ""))))
3437 (clobber (match_scratch:DI 2 "=r"))])]
3438 ""
3439 "
3440 { operands[3] = gen_reg_rtx (DImode); }")
3441
3442 (define_expand "tablejump_nt"
3443 [(set (match_dup 3)
3444 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3445 (parallel [(set (pc)
3446 (match_dup 3))
3447 (use (label_ref (match_operand 1 "" "")))])]
3448 ""
3449 "
3450 { operands[3] = gen_reg_rtx (DImode); }")
3451
3452 ;;
3453 ;; tablejump, openVMS way
3454 ;; op 0: offset
3455 ;; op 1: label preceding jump-table
3456 ;;
3457 (define_expand "tablejump_vms"
3458 [(set (match_dup 2)
3459 (match_operand:DI 0 "register_operand" ""))
3460 (set (pc)
3461 (plus:DI (match_dup 2)
3462 (label_ref:DI (match_operand 1 "" ""))))]
3463 ""
3464 "
3465 { operands[2] = gen_reg_rtx (DImode); }")
3466
3467 (define_insn ""
3468 [(set (pc)
3469 (plus:DI (match_operand:DI 0 "register_operand" "r")
3470 (label_ref:DI (match_operand 1 "" ""))))
3471 (clobber (match_scratch:DI 2 "=r"))]
3472 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
3473 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3474 && PREV_INSN (next_active_insn (insn)) == operands[1]"
3475 "*
3476 { rtx best_label = 0;
3477 rtx jump_table_insn = next_active_insn (operands[1]);
3478
3479 if (GET_CODE (jump_table_insn) == JUMP_INSN
3480 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3481 {
3482 rtx jump_table = PATTERN (jump_table_insn);
3483 int n_labels = XVECLEN (jump_table, 1);
3484 int best_count = -1;
3485 int i, j;
3486
3487 for (i = 0; i < n_labels; i++)
3488 {
3489 int count = 1;
3490
3491 for (j = i + 1; j < n_labels; j++)
3492 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3493 == XEXP (XVECEXP (jump_table, 1, j), 0))
3494 count++;
3495
3496 if (count > best_count)
3497 best_count = count, best_label = XVECEXP (jump_table, 1, i);
3498 }
3499 }
3500
3501 if (best_label)
3502 {
3503 operands[3] = best_label;
3504 return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
3505 }
3506 else
3507 return \"addq %0,$29,%2\;jmp $31,(%2),0\";
3508 }"
3509 [(set_attr "type" "ibr")])
3510
3511 (define_insn ""
3512 [(set (pc)
3513 (match_operand:DI 0 "register_operand" "r"))
3514 (use (label_ref (match_operand 1 "" "")))]
3515 "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
3516 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3517 && PREV_INSN (next_active_insn (insn)) == operands[1]"
3518 "*
3519 { rtx best_label = 0;
3520 rtx jump_table_insn = next_active_insn (operands[1]);
3521
3522 if (GET_CODE (jump_table_insn) == JUMP_INSN
3523 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3524 {
3525 rtx jump_table = PATTERN (jump_table_insn);
3526 int n_labels = XVECLEN (jump_table, 1);
3527 int best_count = -1;
3528 int i, j;
3529
3530 for (i = 0; i < n_labels; i++)
3531 {
3532 int count = 1;
3533
3534 for (j = i + 1; j < n_labels; j++)
3535 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3536 == XEXP (XVECEXP (jump_table, 1, j), 0))
3537 count++;
3538
3539 if (count > best_count)
3540 best_count = count, best_label = XVECEXP (jump_table, 1, i);
3541 }
3542 }
3543
3544 if (best_label)
3545 {
3546 operands[2] = best_label;
3547 return \"jmp $31,(%0),%2\";
3548 }
3549 else
3550 return \"jmp $31,(%0),0\";
3551 }"
3552 [(set_attr "type" "ibr")])
3553
3554 ;;
3555 ;; op 0 is table offset
3556 ;; op 1 is table label
3557 ;;
3558
3559 (define_insn ""
3560 [(set (pc)
3561 (plus:DI (match_operand 0 "register_operand" "r")
3562 (label_ref (match_operand 1 "" ""))))]
3563 "TARGET_OPEN_VMS"
3564 "jmp $31,(%0),0"
3565 [(set_attr "type" "ibr")])
3566
3567 ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't
3568 ;; want to have to include pal.h in our .s file.
3569 (define_insn ""
3570 [(unspec_volatile [(const_int 0)] 0)]
3571 ""
3572 "call_pal 0x86"
3573 [(set_attr "type" "isubr")])
3574 \f
3575 ;; Finally, we have the basic data motion insns. The byte and word insns
3576 ;; are done via define_expand. Start with the floating-point insns, since
3577 ;; they are simpler.
3578
3579 (define_insn ""
3580 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
3581 (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
3582 "register_operand (operands[0], SFmode)
3583 || reg_or_fp0_operand (operands[1], SFmode)"
3584 "@
3585 bis %r1,%r1,%0
3586 ldl %0,%1
3587 stl %r1,%0
3588 cpys %1,%1,%0
3589 cpys $f31,$f31,%0
3590 ld%, %0,%1
3591 st%, %R1,%0"
3592 [(set_attr "type" "ilog,ld,st,fcpys,fcpys,ld,st")])
3593
3594 (define_insn ""
3595 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
3596 (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
3597 "register_operand (operands[0], DFmode)
3598 || reg_or_fp0_operand (operands[1], DFmode)"
3599 "@
3600 bis %r1,%r1,%0
3601 ldq %0,%1
3602 stq %r1,%0
3603 cpys %1,%1,%0
3604 cpys $f31,$f31,%0
3605 ld%- %0,%1
3606 st%- %R1,%0"
3607 [(set_attr "type" "ilog,ld,st,fcpys,fcpys,ld,st")])
3608
3609 (define_expand "movsf"
3610 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3611 (match_operand:SF 1 "general_operand" ""))]
3612 ""
3613 "
3614 {
3615 if (GET_CODE (operands[0]) == MEM
3616 && ! reg_or_fp0_operand (operands[1], SFmode))
3617 operands[1] = force_reg (SFmode, operands[1]);
3618 }")
3619
3620 (define_expand "movdf"
3621 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3622 (match_operand:DF 1 "general_operand" ""))]
3623 ""
3624 "
3625 {
3626 if (GET_CODE (operands[0]) == MEM
3627 && ! reg_or_fp0_operand (operands[1], DFmode))
3628 operands[1] = force_reg (DFmode, operands[1]);
3629 }")
3630
3631 (define_insn ""
3632 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m")
3633 (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG"))]
3634 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS
3635 && (register_operand (operands[0], SImode)
3636 || reg_or_0_operand (operands[1], SImode))"
3637 "@
3638 bis %1,%1,%0
3639 bis $31,$31,%0
3640 bis $31,%1,%0
3641 lda %0,%1
3642 ldah %0,%h1
3643 ldl %0,%1
3644 stl %r1,%0
3645 cpys %1,%1,%0
3646 cpys $f31,$f31,%0
3647 lds %0,%1
3648 sts %R1,%0"
3649 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ld,st,fcpys,fcpys,ld,st")])
3650
3651 (define_insn ""
3652 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,f,f,f,m")
3653 (match_operand:SI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))]
3654 "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3655 && (register_operand (operands[0], SImode)
3656 || reg_or_0_operand (operands[1], SImode))"
3657 "@
3658 bis %1,%1,%0
3659 bis $31,$31,%0
3660 bis $31,%1,%0
3661 lda %0,%1
3662 ldah %0,%h1
3663 lda %0,%1
3664 ldl %0,%1
3665 stl %r1,%0
3666 cpys %1,%1,%0
3667 cpys $f31,$f31,%0
3668 lds %0,%1
3669 sts %R1,%0"
3670 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ld,st,fcpys,fcpys,ld,st")])
3671
3672 (define_insn ""
3673 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
3674 (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))]
3675 "! TARGET_BYTE_OPS
3676 && (register_operand (operands[0], HImode)
3677 || register_operand (operands[1], HImode))"
3678 "@
3679 bis %1,%1,%0
3680 bis $31,$31,%0
3681 bis $31,%1,%0
3682 lda %0,%L1
3683 cpys %1,%1,%0
3684 cpys $f31,$f31,%0"
3685 [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
3686
3687 (define_insn ""
3688 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f")
3689 (match_operand:HI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))]
3690 "TARGET_BYTE_OPS
3691 && (register_operand (operands[0], HImode)
3692 || reg_or_0_operand (operands[1], HImode))"
3693 "@
3694 bis %1,%1,%0
3695 bis $31,$31,%0
3696 bis $31,%1,%0
3697 lda %0,%L1
3698 ldwu %0,%1
3699 stw %r1,%0
3700 cpys %1,%1,%0
3701 cpys $f31,$f31,%0"
3702 [(set_attr "type" "ilog,ilog,ilog,iadd,ld,st,fcpys,fcpys")])
3703
3704 (define_insn ""
3705 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
3706 (match_operand:QI 1 "input_operand" "r,J,I,n,f,J"))]
3707 "! TARGET_BYTE_OPS
3708 && (register_operand (operands[0], QImode)
3709 || register_operand (operands[1], QImode))"
3710 "@
3711 bis %1,%1,%0
3712 bis $31,$31,%0
3713 bis $31,%1,%0
3714 lda %0,%L1
3715 cpys %1,%1,%0
3716 cpys $f31,$f31,%0"
3717 [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
3718
3719 (define_insn ""
3720 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f")
3721 (match_operand:QI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))]
3722 "TARGET_BYTE_OPS
3723 && (register_operand (operands[0], QImode)
3724 || reg_or_0_operand (operands[1], QImode))"
3725 "@
3726 bis %1,%1,%0
3727 bis $31,$31,%0
3728 bis $31,%1,%0
3729 lda %0,%L1
3730 ldbu %0,%1
3731 stb %r1,%0
3732 cpys %1,%1,%0
3733 cpys $f31,$f31,%0"
3734 [(set_attr "type" "ilog,ilog,ilog,iadd,ld,st,fcpys,fcpys")])
3735
3736 ;; We do two major things here: handle mem->mem and construct long
3737 ;; constants.
3738
3739 (define_expand "movsi"
3740 [(set (match_operand:SI 0 "general_operand" "")
3741 (match_operand:SI 1 "general_operand" ""))]
3742 ""
3743 "
3744 {
3745 if (GET_CODE (operands[0]) == MEM
3746 && ! reg_or_0_operand (operands[1], SImode))
3747 operands[1] = force_reg (SImode, operands[1]);
3748
3749 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
3750 ;
3751 else if (GET_CODE (operands[1]) == CONST_INT)
3752 {
3753 operands[1]
3754 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
3755 if (rtx_equal_p (operands[0], operands[1]))
3756 DONE;
3757 }
3758 }")
3759
3760 ;; Split a load of a large constant into the appropriate two-insn
3761 ;; sequence.
3762
3763 (define_split
3764 [(set (match_operand:SI 0 "register_operand" "")
3765 (match_operand:SI 1 "const_int_operand" ""))]
3766 "! add_operand (operands[1], SImode)"
3767 [(set (match_dup 0) (match_dup 2))
3768 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3769 "
3770 { rtx tem
3771 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
3772
3773 if (tem == operands[0])
3774 DONE;
3775 else
3776 FAIL;
3777 }")
3778
3779 (define_insn ""
3780 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q")
3781 (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))]
3782 "register_operand (operands[0], DImode)
3783 || reg_or_0_operand (operands[1], DImode)"
3784 "@
3785 bis %1,%1,%0
3786 bis $31,$31,%0
3787 bis $31,%1,%0
3788 lda %0,%1
3789 ldah %0,%h1
3790 lda %0,%1
3791 ldq%A1 %0,%1
3792 stq%A0 %r1,%0
3793 cpys %1,%1,%0
3794 cpys $f31,$f31,%0
3795 ldt %0,%1
3796 stt %R1,%0"
3797 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ld,st,fcpys,fcpys,ld,st")])
3798
3799 ;; We do three major things here: handle mem->mem, put 64-bit constants in
3800 ;; memory, and construct long 32-bit constants.
3801
3802 (define_expand "movdi"
3803 [(set (match_operand:DI 0 "general_operand" "")
3804 (match_operand:DI 1 "general_operand" ""))]
3805 ""
3806 "
3807 {
3808 rtx tem;
3809
3810 if (GET_CODE (operands[0]) == MEM
3811 && ! reg_or_0_operand (operands[1], DImode))
3812 operands[1] = force_reg (DImode, operands[1]);
3813
3814 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
3815 ;
3816 else if (GET_CODE (operands[1]) == CONST_INT
3817 && (tem = alpha_emit_set_const (operands[0], DImode,
3818 INTVAL (operands[1]), 3)) != 0)
3819 {
3820 if (rtx_equal_p (tem, operands[0]))
3821 DONE;
3822 else
3823 operands[1] = tem;
3824 }
3825 else if (TARGET_BUILD_CONSTANTS
3826 && GET_CODE (operands[1]) == CONST_INT)
3827 {
3828 #if HOST_BITS_PER_WIDE_INT == 64
3829 tem = alpha_emit_set_long_const (operands[0], INTVAL (operands[1]));
3830 if (rtx_equal_p (tem, operands[0]))
3831 DONE;
3832 else
3833 operands[1] = tem;
3834 #else
3835 abort();
3836 #endif
3837 }
3838 else if (CONSTANT_P (operands[1]))
3839 {
3840 operands[1] = force_const_mem (DImode, operands[1]);
3841 if (reload_in_progress)
3842 {
3843 emit_move_insn (operands[0], XEXP (operands[1], 0));
3844 operands[1] = copy_rtx (operands[1]);
3845 XEXP (operands[1], 0) = operands[0];
3846 }
3847 else
3848 operands[1] = validize_mem (operands[1]);
3849 }
3850 else
3851 abort ();
3852 }")
3853
3854 ;; Split a load of a large constant into the appropriate two-insn
3855 ;; sequence.
3856
3857 (define_split
3858 [(set (match_operand:DI 0 "register_operand" "")
3859 (match_operand:DI 1 "const_int_operand" ""))]
3860 "! add_operand (operands[1], DImode)"
3861 [(set (match_dup 0) (match_dup 2))
3862 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3863 "
3864 { rtx tem
3865 = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
3866
3867 if (tem == operands[0])
3868 DONE;
3869 else
3870 FAIL;
3871 }")
3872
3873 ;; These are the partial-word cases.
3874 ;;
3875 ;; First we have the code to load an aligned word. Operand 0 is the register
3876 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
3877 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
3878 ;; number of bits within the word that the value is. Operand 3 is an SImode
3879 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
3880 ;; same register. It is allowed to conflict with operand 1 as well.
3881
3882 (define_expand "aligned_loadqi"
3883 [(set (match_operand:SI 3 "register_operand" "")
3884 (match_operand:SI 1 "memory_operand" ""))
3885 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
3886 (zero_extract:DI (subreg:DI (match_dup 3) 0)
3887 (const_int 8)
3888 (match_operand:DI 2 "const_int_operand" "")))]
3889
3890 ""
3891 "")
3892
3893 (define_expand "aligned_loadhi"
3894 [(set (match_operand:SI 3 "register_operand" "")
3895 (match_operand:SI 1 "memory_operand" ""))
3896 (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
3897 (zero_extract:DI (subreg:DI (match_dup 3) 0)
3898 (const_int 16)
3899 (match_operand:DI 2 "const_int_operand" "")))]
3900
3901 ""
3902 "")
3903
3904 ;; Similar for unaligned loads, where we use the sequence from the
3905 ;; Alpha Architecture manual.
3906 ;;
3907 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
3908 ;; operand 3 can overlap the input and output registers.
3909
3910 (define_expand "unaligned_loadqi"
3911 [(set (match_operand:DI 2 "register_operand" "")
3912 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
3913 (const_int -8))))
3914 (set (match_operand:DI 3 "register_operand" "")
3915 (match_dup 1))
3916 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
3917 (zero_extract:DI (match_dup 2)
3918 (const_int 8)
3919 (ashift:DI (match_dup 3) (const_int 3))))]
3920 ""
3921 "")
3922
3923 (define_expand "unaligned_loadhi"
3924 [(set (match_operand:DI 2 "register_operand" "")
3925 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
3926 (const_int -8))))
3927 (set (match_operand:DI 3 "register_operand" "")
3928 (match_dup 1))
3929 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
3930 (zero_extract:DI (match_dup 2)
3931 (const_int 16)
3932 (ashift:DI (match_dup 3) (const_int 3))))]
3933 ""
3934 "")
3935
3936 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
3937 ;; aligned SImode MEM. Operand 1 is the register containing the
3938 ;; byte or word to store. Operand 2 is the number of bits within the word that
3939 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
3940
3941 (define_expand "aligned_store"
3942 [(set (match_operand:SI 3 "register_operand" "")
3943 (match_operand:SI 0 "memory_operand" ""))
3944 (set (subreg:DI (match_dup 3) 0)
3945 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
3946 (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
3947 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
3948 (match_operand:DI 2 "const_int_operand" "")))
3949 (set (subreg:DI (match_dup 4) 0)
3950 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
3951 (set (match_dup 0) (match_dup 4))]
3952 ""
3953 "
3954 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
3955 << INTVAL (operands[2])));
3956 }")
3957
3958 ;; For the unaligned byte and halfword cases, we use code similar to that
3959 ;; in the ;; Architecture book, but reordered to lower the number of registers
3960 ;; required. Operand 0 is the address. Operand 1 is the data to store.
3961 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
3962 ;; be the same temporary, if desired. If the address is in a register,
3963 ;; operand 2 can be that register.
3964
3965 (define_expand "unaligned_storeqi"
3966 [(set (match_operand:DI 3 "register_operand" "")
3967 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
3968 (const_int -8))))
3969 (set (match_operand:DI 2 "register_operand" "")
3970 (match_dup 0))
3971 (set (match_dup 3)
3972 (and:DI (not:DI (ashift:DI (const_int 255)
3973 (ashift:DI (match_dup 2) (const_int 3))))
3974 (match_dup 3)))
3975 (set (match_operand:DI 4 "register_operand" "")
3976 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
3977 (ashift:DI (match_dup 2) (const_int 3))))
3978 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
3979 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
3980 (match_dup 4))]
3981 ""
3982 "")
3983
3984 (define_expand "unaligned_storehi"
3985 [(set (match_operand:DI 3 "register_operand" "")
3986 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
3987 (const_int -8))))
3988 (set (match_operand:DI 2 "register_operand" "")
3989 (match_dup 0))
3990 (set (match_dup 3)
3991 (and:DI (not:DI (ashift:DI (const_int 65535)
3992 (ashift:DI (match_dup 2) (const_int 3))))
3993 (match_dup 3)))
3994 (set (match_operand:DI 4 "register_operand" "")
3995 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
3996 (ashift:DI (match_dup 2) (const_int 3))))
3997 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
3998 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
3999 (match_dup 4))]
4000 ""
4001 "")
4002 \f
4003 ;; Here are the define_expand's for QI and HI moves that use the above
4004 ;; patterns. We have the normal sets, plus the ones that need scratch
4005 ;; registers for reload.
4006
4007 (define_expand "movqi"
4008 [(set (match_operand:QI 0 "general_operand" "")
4009 (match_operand:QI 1 "general_operand" ""))]
4010 ""
4011 "
4012 { extern rtx get_unaligned_address ();
4013
4014 if (TARGET_BYTE_OPS)
4015 {
4016 if (GET_CODE (operands[0]) == MEM
4017 && ! reg_or_0_operand (operands[1], QImode))
4018 operands[1] = force_reg (QImode, operands[1]);
4019
4020 if (GET_CODE (operands[1]) == CONST_INT
4021 && ! input_operand (operands[1], QImode))
4022 {
4023 operands[1] = alpha_emit_set_const (operands[0], QImode,
4024 INTVAL (operands[1]), 3);
4025
4026 if (rtx_equal_p (operands[0], operands[1]))
4027 DONE;
4028 }
4029
4030 goto def;
4031 }
4032
4033 /* If the output is not a register, the input must be. */
4034 if (GET_CODE (operands[0]) == MEM)
4035 operands[1] = force_reg (QImode, operands[1]);
4036
4037 /* Handle four memory cases, unaligned and aligned for either the input
4038 or the output. The only case where we can be called during reload is
4039 for aligned loads; all other cases require temporaries. */
4040
4041 if (GET_CODE (operands[1]) == MEM
4042 || (GET_CODE (operands[1]) == SUBREG
4043 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4044 || (reload_in_progress && GET_CODE (operands[1]) == REG
4045 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4046 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4047 && GET_CODE (SUBREG_REG (operands[1])) == REG
4048 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4049 {
4050 if (aligned_memory_operand (operands[1], QImode))
4051 {
4052 rtx aligned_mem, bitnum;
4053 rtx scratch = (reload_in_progress
4054 ? gen_rtx (REG, SImode, REGNO (operands[0]))
4055 : gen_reg_rtx (SImode));
4056
4057 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4058
4059 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
4060 scratch));
4061 }
4062 else
4063 {
4064 /* Don't pass these as parameters since that makes the generated
4065 code depend on parameter evaluation order which will cause
4066 bootstrap failures. */
4067
4068 rtx temp1 = gen_reg_rtx (DImode);
4069 rtx temp2 = gen_reg_rtx (DImode);
4070 rtx seq
4071 = gen_unaligned_loadqi (operands[0],
4072 get_unaligned_address (operands[1], 0),
4073 temp1, temp2);
4074
4075 alpha_set_memflags (seq, operands[1]);
4076 emit_insn (seq);
4077 }
4078
4079 DONE;
4080 }
4081
4082 else if (GET_CODE (operands[0]) == MEM
4083 || (GET_CODE (operands[0]) == SUBREG
4084 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4085 || (reload_in_progress && GET_CODE (operands[0]) == REG
4086 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4087 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4088 && GET_CODE (SUBREG_REG (operands[0])) == REG
4089 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4090 {
4091 if (aligned_memory_operand (operands[0], QImode))
4092 {
4093 rtx aligned_mem, bitnum;
4094 rtx temp1 = gen_reg_rtx (SImode);
4095 rtx temp2 = gen_reg_rtx (SImode);
4096
4097 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4098
4099 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4100 temp1, temp2));
4101 }
4102 else
4103 {
4104 rtx temp1 = gen_reg_rtx (DImode);
4105 rtx temp2 = gen_reg_rtx (DImode);
4106 rtx temp3 = gen_reg_rtx (DImode);
4107 rtx seq
4108 = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
4109 operands[1], temp1, temp2, temp3);
4110
4111 alpha_set_memflags (seq, operands[0]);
4112 emit_insn (seq);
4113 }
4114 DONE;
4115 }
4116 def:;
4117 }")
4118
4119 (define_expand "movhi"
4120 [(set (match_operand:HI 0 "general_operand" "")
4121 (match_operand:HI 1 "general_operand" ""))]
4122 ""
4123 "
4124 { extern rtx get_unaligned_address ();
4125
4126 if (TARGET_BYTE_OPS)
4127 {
4128 if (GET_CODE (operands[0]) == MEM
4129 && ! reg_or_0_operand (operands[1], HImode))
4130 operands[1] = force_reg (HImode, operands[1]);
4131
4132 if (GET_CODE (operands[1]) == CONST_INT
4133 && ! input_operand (operands[1], HImode))
4134 {
4135 operands[1] = alpha_emit_set_const (operands[0], HImode,
4136 INTVAL (operands[1]), 3);
4137
4138 if (rtx_equal_p (operands[0], operands[1]))
4139 DONE;
4140 }
4141
4142 goto def;
4143 }
4144
4145 /* If the output is not a register, the input must be. */
4146 if (GET_CODE (operands[0]) == MEM)
4147 operands[1] = force_reg (HImode, operands[1]);
4148
4149 /* Handle four memory cases, unaligned and aligned for either the input
4150 or the output. The only case where we can be called during reload is
4151 for aligned loads; all other cases require temporaries. */
4152
4153 if (GET_CODE (operands[1]) == MEM
4154 || (GET_CODE (operands[1]) == SUBREG
4155 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4156 || (reload_in_progress && GET_CODE (operands[1]) == REG
4157 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4158 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4159 && GET_CODE (SUBREG_REG (operands[1])) == REG
4160 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4161 {
4162 if (aligned_memory_operand (operands[1], HImode))
4163 {
4164 rtx aligned_mem, bitnum;
4165 rtx scratch = (reload_in_progress
4166 ? gen_rtx (REG, SImode, REGNO (operands[0]))
4167 : gen_reg_rtx (SImode));
4168
4169 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4170
4171 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
4172 scratch));
4173 }
4174 else
4175 {
4176 /* Don't pass these as parameters since that makes the generated
4177 code depend on parameter evaluation order which will cause
4178 bootstrap failures. */
4179
4180 rtx temp1 = gen_reg_rtx (DImode);
4181 rtx temp2 = gen_reg_rtx (DImode);
4182 rtx seq
4183 = gen_unaligned_loadhi (operands[0],
4184 get_unaligned_address (operands[1], 0),
4185 temp1, temp2);
4186
4187 alpha_set_memflags (seq, operands[1]);
4188 emit_insn (seq);
4189 }
4190
4191 DONE;
4192 }
4193
4194 else if (GET_CODE (operands[0]) == MEM
4195 || (GET_CODE (operands[0]) == SUBREG
4196 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4197 || (reload_in_progress && GET_CODE (operands[0]) == REG
4198 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4199 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4200 && GET_CODE (SUBREG_REG (operands[0])) == REG
4201 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4202 {
4203 if (aligned_memory_operand (operands[0], HImode))
4204 {
4205 rtx aligned_mem, bitnum;
4206 rtx temp1 = gen_reg_rtx (SImode);
4207 rtx temp2 = gen_reg_rtx (SImode);
4208
4209 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4210
4211 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4212 temp1, temp2));
4213 }
4214 else
4215 {
4216 rtx temp1 = gen_reg_rtx (DImode);
4217 rtx temp2 = gen_reg_rtx (DImode);
4218 rtx temp3 = gen_reg_rtx (DImode);
4219 rtx seq
4220 = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
4221 operands[1], temp1, temp2, temp3);
4222
4223 alpha_set_memflags (seq, operands[0]);
4224 emit_insn (seq);
4225 }
4226
4227 DONE;
4228 }
4229 def:;
4230 }")
4231
4232 ;; Here are the versions for reload. Note that in the unaligned cases
4233 ;; we know that the operand must not be a pseudo-register because stack
4234 ;; slots are always aligned references.
4235
4236 (define_expand "reload_inqi"
4237 [(parallel [(match_operand:QI 0 "register_operand" "=r")
4238 (match_operand:QI 1 "unaligned_memory_operand" "m")
4239 (match_operand:TI 2 "register_operand" "=&r")])]
4240 "! TARGET_BYTE_OPS"
4241 "
4242 { extern rtx get_unaligned_address ();
4243 rtx addr = get_unaligned_address (operands[1], 0);
4244 /* It is possible that one of the registers we got for operands[2]
4245 might coincide with that of operands[0] (which is why we made
4246 it TImode). Pick the other one to use as our scratch. */
4247 rtx scratch = gen_rtx (REG, DImode,
4248 REGNO (operands[0]) == REGNO (operands[2])
4249 ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
4250 rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch,
4251 gen_rtx (REG, DImode, REGNO (operands[0])));
4252
4253 alpha_set_memflags (seq, operands[1]);
4254 emit_insn (seq);
4255 DONE;
4256 }")
4257
4258 (define_expand "reload_inhi"
4259 [(parallel [(match_operand:HI 0 "register_operand" "=r")
4260 (match_operand:HI 1 "unaligned_memory_operand" "m")
4261 (match_operand:TI 2 "register_operand" "=&r")])]
4262 "! TARGET_BYTE_OPS"
4263 "
4264 { extern rtx get_unaligned_address ();
4265 rtx addr = get_unaligned_address (operands[1], 0);
4266 /* It is possible that one of the registers we got for operands[2]
4267 might coincide with that of operands[0] (which is why we made
4268 it TImode). Pick the other one to use as our scratch. */
4269 rtx scratch = gen_rtx (REG, DImode,
4270 REGNO (operands[0]) == REGNO (operands[2])
4271 ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
4272 rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch,
4273 gen_rtx (REG, DImode, REGNO (operands[0])));
4274
4275 alpha_set_memflags (seq, operands[1]);
4276 emit_insn (seq);
4277 DONE;
4278 }")
4279
4280 (define_expand "reload_outqi"
4281 [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
4282 (match_operand:QI 1 "register_operand" "r")
4283 (match_operand:TI 2 "register_operand" "=&r")])]
4284 "! TARGET_BYTE_OPS"
4285 "
4286 { extern rtx get_unaligned_address ();
4287
4288 if (aligned_memory_operand (operands[0], QImode))
4289 {
4290 rtx aligned_mem, bitnum;
4291
4292 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4293
4294 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4295 gen_rtx (REG, SImode, REGNO (operands[2])),
4296 gen_rtx (REG, SImode,
4297 REGNO (operands[2]) + 1)));
4298 }
4299 else
4300 {
4301 rtx addr = get_unaligned_address (operands[0], 0);
4302 rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
4303 rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
4304 rtx scratch3 = scratch1;
4305 rtx seq;
4306
4307 if (GET_CODE (addr) == REG)
4308 scratch1 = addr;
4309
4310 seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
4311 scratch2, scratch3);
4312 alpha_set_memflags (seq, operands[0]);
4313 emit_insn (seq);
4314 }
4315
4316 DONE;
4317 }")
4318
4319 (define_expand "reload_outhi"
4320 [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
4321 (match_operand:HI 1 "register_operand" "r")
4322 (match_operand:TI 2 "register_operand" "=&r")])]
4323 "! TARGET_BYTE_OPS"
4324 "
4325 { extern rtx get_unaligned_address ();
4326
4327 if (aligned_memory_operand (operands[0], HImode))
4328 {
4329 rtx aligned_mem, bitnum;
4330
4331 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4332
4333 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4334 gen_rtx (REG, SImode, REGNO (operands[2])),
4335 gen_rtx (REG, SImode,
4336 REGNO (operands[2]) + 1)));
4337 }
4338 else
4339 {
4340 rtx addr = get_unaligned_address (operands[0], 0);
4341 rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
4342 rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
4343 rtx scratch3 = scratch1;
4344 rtx seq;
4345
4346 if (GET_CODE (addr) == REG)
4347 scratch1 = addr;
4348
4349 seq = gen_unaligned_storehi (addr, operands[1], scratch1,
4350 scratch2, scratch3);
4351 alpha_set_memflags (seq, operands[0]);
4352 emit_insn (seq);
4353 }
4354
4355 DONE;
4356 }")
4357 \f
4358 ;; Subroutine of stack space allocation. Perform a stack probe.
4359 (define_expand "probe_stack"
4360 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
4361 ""
4362 "
4363 {
4364 operands[1] = gen_rtx (MEM, DImode, plus_constant (stack_pointer_rtx,
4365 INTVAL (operands[0])));
4366 MEM_VOLATILE_P (operands[1]) = 1;
4367
4368 operands[0] = const0_rtx;
4369 }")
4370
4371 ;; This is how we allocate stack space. If we are allocating a
4372 ;; constant amount of space and we know it is less than 4096
4373 ;; bytes, we need do nothing.
4374 ;;
4375 ;; If it is more than 4096 bytes, we need to probe the stack
4376 ;; periodically.
4377 (define_expand "allocate_stack"
4378 [(set (reg:DI 30)
4379 (plus:DI (reg:DI 30)
4380 (match_operand:DI 0 "reg_or_cint_operand" "")))]
4381 ""
4382 "
4383 {
4384 if (GET_CODE (operands[0]) == CONST_INT
4385 && INTVAL (operands[0]) < 32768)
4386 {
4387 if (INTVAL (operands[0]) >= 4096)
4388 {
4389 /* We do this the same way as in the prologue and generate explicit
4390 probes. Then we update the stack by the constant. */
4391
4392 int probed = 4096;
4393
4394 emit_insn (gen_probe_stack (GEN_INT (- probed)));
4395 while (probed + 8192 < INTVAL (operands[0]))
4396 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
4397
4398 if (probed + 4096 < INTVAL (operands[0]))
4399 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[0]))));
4400 }
4401
4402 operands[0] = GEN_INT (- INTVAL (operands[0]));
4403 }
4404 else
4405 {
4406 rtx out_label = 0;
4407 rtx loop_label = gen_label_rtx ();
4408 rtx want = gen_reg_rtx (Pmode);
4409 rtx tmp = gen_reg_rtx (Pmode);
4410 rtx memref;
4411
4412 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
4413 force_reg (Pmode, operands[0])));
4414 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
4415
4416 if (GET_CODE (operands[0]) != CONST_INT)
4417 {
4418 out_label = gen_label_rtx ();
4419 emit_insn (gen_cmpdi (want, tmp));
4420 emit_jump_insn (gen_bgeu (out_label));
4421 }
4422
4423 emit_label (loop_label);
4424 memref = gen_rtx (MEM, DImode, tmp);
4425 MEM_VOLATILE_P (memref) = 1;
4426 emit_move_insn (memref, const0_rtx);
4427 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
4428 emit_insn (gen_cmpdi (tmp, want));
4429 emit_jump_insn (gen_bgtu (loop_label));
4430 memref = gen_rtx (MEM, DImode, want);
4431 MEM_VOLATILE_P (memref) = 1;
4432 emit_move_insn (memref, const0_rtx);
4433
4434 if (out_label)
4435 emit_label (out_label);
4436
4437 emit_move_insn (stack_pointer_rtx, want);
4438
4439 DONE;
4440 }
4441 }")
4442
4443 (define_insn "exception_receiver"
4444 [(unspec_volatile [(const_int 0)] 2)]
4445 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
4446 ".long 0xc3a00000\;ldgp $29,0($29)")
4447
4448 (define_expand "nonlocal_goto_receiver"
4449 [(unspec_volatile [(const_int 0)] 1)
4450 (set (reg:DI 27) (mem:DI (reg:DI 29)))
4451 (unspec_volatile [(const_int 0)] 1)
4452 (use (reg:DI 27))]
4453 "TARGET_OPEN_VMS"
4454 "")
4455
4456 (define_insn "arg_home"
4457 [(unspec [(const_int 0)] 0)
4458 (use (reg:DI 1))
4459 (use (reg:DI 25))
4460 (use (reg:DI 16))
4461 (use (reg:DI 17))
4462 (use (reg:DI 18))
4463 (use (reg:DI 19))
4464 (use (reg:DI 20))
4465 (use (reg:DI 21))
4466 (use (reg:DI 48))
4467 (use (reg:DI 49))
4468 (use (reg:DI 50))
4469 (use (reg:DI 51))
4470 (use (reg:DI 52))
4471 (use (reg:DI 53))
4472 (clobber (mem:BLK (const_int 0)))
4473 (clobber (reg:DI 24))
4474 (clobber (reg:DI 25))
4475 (clobber (reg:DI 0))]
4476 "TARGET_OPEN_VMS"
4477 "lda $0,ots$home_args\;ldq $0,8($0)\;jsr $0,ots$home_args")