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