OSDN Git Service

* config/alpha/alpha.md (sibcall_osf_1): Load destination
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.md
1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 ;; 2000, 2001 Free Software Foundation, Inc.
4 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;;
6 ;; This file is part of GNU CC.
7 ;;
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 ;; Uses of UNSPEC in this file:
26
27 (define_constants
28   [(UNSPEC_ARG_HOME     0)
29    (UNSPEC_CTTZ         1)
30    (UNSPEC_INSXH        2)
31    (UNSPEC_MSKXH        3)
32    (UNSPEC_CVTQL        4)
33    (UNSPEC_NT_LDA       5)
34    (UNSPEC_UMK_LAUM     6)
35    (UNSPEC_UMK_LALM     7)
36    (UNSPEC_UMK_LAL      8)
37    (UNSPEC_UMK_LOAD_CIW 9)
38    (UNSPEC_LDGP2        10)
39    (UNSPEC_LITERAL      11)
40    (UNSPEC_LITUSE       12)
41   ])
42
43 ;; UNSPEC_VOLATILE:
44
45 (define_constants
46   [(UNSPECV_IMB         0)
47    (UNSPECV_BLOCKAGE    1)
48    (UNSPECV_SETJMPR     2)      ; builtin_setjmp_receiver
49    (UNSPECV_LONGJMP     3)      ; builtin_longjmp
50    (UNSPECV_TRAPB       4)
51    (UNSPECV_PSPL        5)      ; prologue_stack_probe_loop
52    (UNSPECV_REALIGN     6)
53    (UNSPECV_EHR         7)      ; exception_receiver
54    (UNSPECV_MCOUNT      8)
55    (UNSPECV_FORCE_MOV   9)
56    (UNSPECV_LDGP1       10)
57    (UNSPECV_PLDGP2      11)     ; prologue ldgp
58   ])
59
60 ;; Where necessary, the suffixes _le and _be are used to distinguish between
61 ;; little-endian and big-endian patterns.
62 ;;
63 ;; Note that the Unicos/Mk assembler does not support the following
64 ;; opcodes: mov, fmov, nop, fnop, unop.
65 \f
66 ;; Processor type -- this attribute must exactly match the processor_type
67 ;; enumeration in alpha.h.
68
69 (define_attr "cpu" "ev4,ev5,ev6"
70   (const (symbol_ref "alpha_cpu")))
71
72 ;; Define an insn type attribute.  This is used in function unit delay
73 ;; computations, among other purposes.  For the most part, we use the names
74 ;; defined in the EV4 documentation, but add a few that we have to know about
75 ;; separately.
76
77 (define_attr "type"
78   "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,\
79 fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
80   (const_string "iadd"))
81
82 ;; Describe a user's asm statement.
83 (define_asm_attributes
84   [(set_attr "type" "multi")])
85
86 ;; Define the operand size an insn operates on.  Used primarily by mul
87 ;; and div operations that have size dependant timings.
88
89 (define_attr "opsize" "si,di,udi"
90   (const_string "di"))
91
92 ;; The TRAP attribute marks instructions that may generate traps
93 ;; (which are imprecise and may need a trapb if software completion
94 ;; is desired).
95
96 (define_attr "trap" "no,yes"
97   (const_string "no"))
98
99 ;; The ROUND_SUFFIX attribute marks which instructions require a
100 ;; rounding-mode suffix.  The value NONE indicates no suffix,
101 ;; the value NORMAL indicates a suffix controled by alpha_fprm.
102
103 (define_attr "round_suffix" "none,normal,c"
104   (const_string "none"))
105
106 ;; The TRAP_SUFFIX attribute marks instructions requiring a trap-mode suffix:
107 ;;   NONE       no suffix
108 ;;   SU         accepts only /su (cmpt et al)
109 ;;   SUI        accepts only /sui (cvtqt and cvtqs)
110 ;;   V_SV       accepts /v and /sv (cvtql only)
111 ;;   V_SV_SVI   accepts /v, /sv and /svi (cvttq only)
112 ;;   U_SU_SUI   accepts /u, /su and /sui (most fp instructions)
113 ;;
114 ;; The actual suffix emitted is controled by alpha_fptm.
115
116 (define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui"
117   (const_string "none"))
118
119 ;; The length of an instruction sequence in bytes.
120
121 (define_attr "length" ""
122   (const_int 4))
123 \f
124 ;; On EV4 there are two classes of resources to consider: resources needed
125 ;; to issue, and resources needed to execute.  IBUS[01] are in the first
126 ;; category.  ABOX, BBOX, EBOX, FBOX, IMUL & FDIV make up the second.
127 ;; (There are a few other register-like resources, but ...)
128
129 ; First, describe all of the issue constraints with single cycle delays.
130 ; All insns need a bus, but all except loads require one or the other.
131 (define_function_unit "ev4_ibus0" 1 0
132   (and (eq_attr "cpu" "ev4")
133        (eq_attr "type" "fst,fbr,iadd,imul,ilog,shift,icmov,icmp"))
134   1 1)
135
136 (define_function_unit "ev4_ibus1" 1 0
137   (and (eq_attr "cpu" "ev4")
138        (eq_attr "type" "ist,ibr,jsr,fadd,fcmov,fcpys,fmul,fdiv,misc"))
139   1 1)
140
141 ; Memory delivers its result in three cycles.  Actually return one and
142 ; take care of this in adjust_cost, since we want to handle user-defined
143 ; memory latencies.
144 (define_function_unit "ev4_abox" 1 0
145   (and (eq_attr "cpu" "ev4")
146        (eq_attr "type" "ild,fld,ldsym,ist,fst"))
147   1 1)
148
149 ; Branches have no delay cost, but do tie up the unit for two cycles.
150 (define_function_unit "ev4_bbox" 1 1
151   (and (eq_attr "cpu" "ev4")
152        (eq_attr "type" "ibr,fbr,jsr"))
153   2 2)
154
155 ; Arithmetic insns are normally have their results available after
156 ; two cycles.  There are a number of exceptions.  They are encoded in
157 ; ADJUST_COST.  Some of the other insns have similar exceptions.
158 (define_function_unit "ev4_ebox" 1 0
159   (and (eq_attr "cpu" "ev4")
160        (eq_attr "type" "iadd,ilog,shift,icmov,icmp,misc"))
161   2 1)
162
163 (define_function_unit "imul" 1 0
164   (and (eq_attr "cpu" "ev4")
165        (and (eq_attr "type" "imul")
166             (eq_attr "opsize" "si")))
167   21 19)
168
169 (define_function_unit "imul" 1 0
170   (and (eq_attr "cpu" "ev4")
171        (and (eq_attr "type" "imul")
172             (eq_attr "opsize" "!si")))
173   23 21)
174
175 (define_function_unit "ev4_fbox" 1 0
176   (and (eq_attr "cpu" "ev4")
177        (eq_attr "type" "fadd,fmul,fcpys,fcmov"))
178   6 1)
179
180 (define_function_unit "fdiv" 1 0
181   (and (eq_attr "cpu" "ev4")
182        (and (eq_attr "type" "fdiv")
183             (eq_attr "opsize" "si")))
184   34 30)
185
186 (define_function_unit "fdiv" 1 0
187   (and (eq_attr "cpu" "ev4")
188        (and (eq_attr "type" "fdiv")
189             (eq_attr "opsize" "di")))
190   63 59)
191 \f
192 ;; EV5 scheduling.  EV5 can issue 4 insns per clock.
193 ;;
194 ;; EV5 has two asymetric integer units.  Model this with E0 & E1 along
195 ;; with the combined resource EBOX.
196
197 (define_function_unit "ev5_ebox" 2 0
198   (and (eq_attr "cpu" "ev5")
199        (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv"))
200   1 1)
201
202 ; Memory takes at least 2 clocks.  Return one from here and fix up with
203 ; user-defined latencies in adjust_cost.
204 (define_function_unit "ev5_ebox" 2 0
205   (and (eq_attr "cpu" "ev5")
206        (eq_attr "type" "ild,fld,ldsym"))
207   1 1)
208
209 ; Loads can dual issue with one another, but loads and stores do not mix.
210 (define_function_unit "ev5_e0" 1 0
211   (and (eq_attr "cpu" "ev5")
212        (eq_attr "type" "ild,fld,ldsym"))
213   1 1
214   [(eq_attr "type" "ist,fst")])
215
216 ; Stores, shifts, multiplies can only issue to E0
217 (define_function_unit "ev5_e0" 1 0
218   (and (eq_attr "cpu" "ev5")
219        (eq_attr "type" "ist,fst,shift,imul"))
220   1 1)
221
222 ; Motion video insns also issue only to E0, and take two ticks.
223 (define_function_unit "ev5_e0" 1 0
224   (and (eq_attr "cpu" "ev5")
225        (eq_attr "type" "mvi"))
226   2 1)
227
228 ; Conditional moves always take 2 ticks.
229 (define_function_unit "ev5_ebox" 2 0
230   (and (eq_attr "cpu" "ev5")
231        (eq_attr "type" "icmov"))
232   2 1)
233
234 ; Branches can only issue to E1
235 (define_function_unit "ev5_e1" 1 0
236   (and (eq_attr "cpu" "ev5")
237        (eq_attr "type" "ibr,jsr"))
238   1 1)
239
240 ; Multiplies also use the integer multiplier.
241 ; ??? How to: "No instruction can be issued to pipe E0 exactly two
242 ; cycles before an integer multiplication completes."
243 (define_function_unit "imul" 1 0
244   (and (eq_attr "cpu" "ev5")
245        (and (eq_attr "type" "imul")
246             (eq_attr "opsize" "si")))
247   8 4)
248
249 (define_function_unit "imul" 1 0
250   (and (eq_attr "cpu" "ev5")
251        (and (eq_attr "type" "imul")
252             (eq_attr "opsize" "di")))
253   12 8)
254
255 (define_function_unit "imul" 1 0
256   (and (eq_attr "cpu" "ev5")
257        (and (eq_attr "type" "imul")
258             (eq_attr "opsize" "udi")))
259   14 8)
260
261 ;; Similarly for the FPU we have two asymetric units.  But fcpys can issue
262 ;; on either so we have to play the game again.
263
264 (define_function_unit "ev5_fbox" 2 0
265   (and (eq_attr "cpu" "ev5")
266        (eq_attr "type" "fadd,fcmov,fmul,fcpys,fbr,fdiv"))
267   4 1)
268
269 (define_function_unit "ev5_fm" 1 0
270   (and (eq_attr "cpu" "ev5")
271        (eq_attr "type" "fmul"))
272   4 1)
273
274 ; Add and cmov as you would expect; fbr never produces a result;
275 ; fdiv issues through fa to the divider,
276 (define_function_unit "ev5_fa" 1 0
277   (and (eq_attr "cpu" "ev5")
278        (eq_attr "type" "fadd,fcmov,fbr,fdiv"))
279   4 1)
280
281 ; ??? How to: "No instruction can be issued to pipe FA exactly five
282 ; cycles before a floating point divide completes."
283 (define_function_unit "fdiv" 1 0
284   (and (eq_attr "cpu" "ev5")
285        (and (eq_attr "type" "fdiv")
286             (eq_attr "opsize" "si")))
287   15 15)                                ; 15 to 31 data dependant
288
289 (define_function_unit "fdiv" 1 0
290   (and (eq_attr "cpu" "ev5")
291        (and (eq_attr "type" "fdiv")
292             (eq_attr "opsize" "di")))
293   22 22)                                ; 22 to 60 data dependant
294 \f
295 ;; EV6 scheduling.  EV6 can issue 4 insns per clock.
296 ;;
297 ;; EV6 has two symmetric pairs ("clusters") of two asymetric integer units
298 ;; ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
299
300 ;; Conditional moves decompose into two independant primitives, each
301 ;; taking one cycle.  Since ev6 is out-of-order, we can't see anything
302 ;; but two cycles.
303 (define_function_unit "ev6_ebox" 4 0
304   (and (eq_attr "cpu" "ev6")
305        (eq_attr "type" "icmov"))
306   2 1)
307
308 (define_function_unit "ev6_ebox" 4 0
309   (and (eq_attr "cpu" "ev6")
310        (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv,fsqrt"))
311   1 1)
312
313 ;; Integer loads take at least 3 clocks, and only issue to lower units.
314 ;; Return one from here and fix up with user-defined latencies in adjust_cost.
315 (define_function_unit "ev6_l" 2 0
316   (and (eq_attr "cpu" "ev6")
317        (eq_attr "type" "ild,ldsym,ist,fst"))
318   1 1)
319
320 ;; FP loads take at least 4 clocks.  Return two from here...
321 (define_function_unit "ev6_l" 2 0
322   (and (eq_attr "cpu" "ev6")
323        (eq_attr "type" "fld"))
324   2 1)
325
326 ;; Motion video insns also issue only to U0, and take three ticks.
327 (define_function_unit "ev6_u0" 1 0
328   (and (eq_attr "cpu" "ev6")
329        (eq_attr "type" "mvi"))
330   3 1)
331
332 (define_function_unit "ev6_u" 2 0
333   (and (eq_attr "cpu" "ev6")
334        (eq_attr "type" "mvi"))
335   3 1)
336
337 ;; Shifts issue to either upper pipe.
338 (define_function_unit "ev6_u" 2 0
339   (and (eq_attr "cpu" "ev6")
340        (eq_attr "type" "shift"))
341   1 1)
342
343 ;; Multiplies issue only to U1, and all take 7 ticks.
344 ;; Rather than create a new function unit just for U1, reuse IMUL
345 (define_function_unit "imul" 1 0
346   (and (eq_attr "cpu" "ev6")
347        (eq_attr "type" "imul"))
348   7 1)
349
350 (define_function_unit "ev6_u" 2 0
351   (and (eq_attr "cpu" "ev6")
352        (eq_attr "type" "imul"))
353   7 1)
354
355 ;; Branches issue to either upper pipe
356 (define_function_unit "ev6_u" 2 0
357   (and (eq_attr "cpu" "ev6")
358        (eq_attr "type" "ibr"))
359   3 1)
360
361 ;; Calls only issue to L0.
362 (define_function_unit "ev6_l0" 1 0
363   (and (eq_attr "cpu" "ev6")
364        (eq_attr "type" "jsr"))
365   1 1)
366
367 (define_function_unit "ev6_l" 2 0
368   (and (eq_attr "cpu" "ev6")
369        (eq_attr "type" "jsr"))
370   1 1)
371
372 ;; Ftoi/itof only issue to lower pipes
373 (define_function_unit "ev6_l" 2 0
374   (and (eq_attr "cpu" "ev6")
375        (eq_attr "type" "ftoi"))
376   3 1)
377
378 (define_function_unit "ev6_l" 2 0
379   (and (eq_attr "cpu" "ev6")
380        (eq_attr "type" "itof"))
381   4 1)
382
383 ;; For the FPU we are very similar to EV5, except there's no insn that
384 ;; can issue to fm & fa, so we get to leave that out.
385
386 (define_function_unit "ev6_fm" 1 0
387   (and (eq_attr "cpu" "ev6")
388        (eq_attr "type" "fmul"))
389   4 1)
390
391 (define_function_unit "ev6_fa" 1 0
392   (and (eq_attr "cpu" "ev6")
393        (eq_attr "type" "fadd,fcpys,fbr,fdiv,fsqrt"))
394   4 1)
395
396 (define_function_unit "ev6_fa" 1 0
397   (and (eq_attr "cpu" "ev6")
398        (eq_attr "type" "fcmov"))
399   8 1)
400
401 (define_function_unit "fdiv" 1 0
402   (and (eq_attr "cpu" "ev6")
403        (and (eq_attr "type" "fdiv")
404             (eq_attr "opsize" "si")))
405   12 10)
406
407 (define_function_unit "fdiv" 1 0
408   (and (eq_attr "cpu" "ev6")
409        (and (eq_attr "type" "fdiv")
410             (eq_attr "opsize" "di")))
411   15 13)
412
413 (define_function_unit "fsqrt" 1 0
414   (and (eq_attr "cpu" "ev6")
415        (and (eq_attr "type" "fsqrt")
416             (eq_attr "opsize" "si")))
417   16 14)
418
419 (define_function_unit "fsqrt" 1 0
420   (and (eq_attr "cpu" "ev6")
421        (and (eq_attr "type" "fsqrt")
422             (eq_attr "opsize" "di")))
423   32 30)
424
425 ; ??? The FPU communicates with memory and the integer register file
426 ; via two fp store units.  We need a slot in the fst immediately, and
427 ; a slot in LOW after the operand data is ready.  At which point the
428 ; data may be moved either to the store queue or the integer register
429 ; file and the insn retired.
430
431 \f
432 ;; First define the arithmetic insns.  Note that the 32-bit forms also
433 ;; sign-extend.
434
435 ;; Handle 32-64 bit extension from memory to a floating point register
436 ;; specially, since this ocurrs frequently in int->double conversions.
437 ;;
438 ;; Note that while we must retain the =f case in the insn for reload's
439 ;; benefit, it should be eliminated after reload, so we should never emit
440 ;; code for that case.  But we don't reject the possibility.
441
442 (define_expand "extendsidi2"
443   [(set (match_operand:DI 0 "register_operand" "")
444         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
445   ""
446   "")
447
448 (define_insn "*extendsidi2_nofix"
449   [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
450         (sign_extend:DI
451           (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
452   "! TARGET_FIX"
453   "@
454    addl %1,$31,%0
455    ldl %0,%1
456    cvtlq %1,%0
457    lds %0,%1\;cvtlq %0,%0"
458   [(set_attr "type" "iadd,ild,fadd,fld")
459    (set_attr "length" "*,*,*,8")])
460
461 (define_insn "*extendsidi2_fix"
462   [(set (match_operand:DI 0 "register_operand" "=r,r,r,*f,?*f")
463         (sign_extend:DI
464           (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
465   "TARGET_FIX"
466   "@
467    addl %1,$31,%0
468    ldl %0,%1
469    ftois %1,%0
470    cvtlq %1,%0
471    lds %0,%1\;cvtlq %0,%0"
472   [(set_attr "type" "iadd,ild,ftoi,fadd,fld")
473    (set_attr "length" "*,*,*,*,8")])
474
475 ;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
476 (define_split
477   [(set (match_operand:DI 0 "hard_fp_register_operand" "")
478         (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
479   "reload_completed"
480   [(set (match_dup 2) (match_dup 1))
481    (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
482   "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
483
484 ;; Optimize sign-extension of SImode loads.  This shows up in the wake of
485 ;; reload when converting fp->int.
486
487 (define_peephole2
488   [(set (match_operand:SI 0 "hard_int_register_operand" "")
489         (match_operand:SI 1 "memory_operand" ""))
490    (set (match_operand:DI 2 "hard_int_register_operand" "")
491         (sign_extend:DI (match_dup 0)))]
492   "true_regnum (operands[0]) == true_regnum (operands[2])
493    || peep2_reg_dead_p (2, operands[0])"
494   [(set (match_dup 2)
495         (sign_extend:DI (match_dup 1)))]
496   "")
497
498 (define_peephole2
499   [(set (match_operand:SI 0 "hard_int_register_operand" "")
500         (match_operand:SI 1 "hard_fp_register_operand" ""))
501    (set (match_operand:DI 2 "hard_int_register_operand" "")
502         (sign_extend:DI (match_dup 0)))]
503   "TARGET_FIX
504    && (true_regnum (operands[0]) == true_regnum (operands[2])
505        || peep2_reg_dead_p (2, operands[0]))"
506   [(set (match_dup 2)
507         (sign_extend:DI (match_dup 1)))]
508   "")
509
510 (define_peephole2
511   [(set (match_operand:DI 0 "hard_fp_register_operand" "")
512         (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
513    (set (match_operand:DI 2 "hard_int_register_operand" "")
514         (match_dup 0))]
515   "TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
516   [(set (match_dup 2)
517         (sign_extend:DI (match_dup 1)))]
518   "")
519
520 ;; Do addsi3 the way expand_binop would do if we didn't have one.  This
521 ;; generates better code.  We have the anonymous addsi3 pattern below in
522 ;; case combine wants to make it.
523 (define_expand "addsi3"
524   [(set (match_operand:SI 0 "register_operand" "")
525         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
526                  (match_operand:SI 2 "add_operand" "")))]
527   ""
528 {
529   if (optimize)
530     {
531       rtx op1 = gen_lowpart (DImode, operands[1]);
532       rtx op2 = gen_lowpart (DImode, operands[2]);
533
534       if (! cse_not_expected)
535         {
536           rtx tmp = gen_reg_rtx (DImode);
537           emit_insn (gen_adddi3 (tmp, op1, op2));
538           emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
539         }
540       else
541         emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
542       DONE;
543     }
544 })
545
546 (define_insn "*addsi_internal"
547   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
548         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
549                  (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
550   ""
551   "@
552    addl %r1,%2,%0
553    subl %r1,%n2,%0
554    lda %0,%2(%r1)
555    ldah %0,%h2(%r1)")
556
557 (define_split
558   [(set (match_operand:SI 0 "register_operand" "")
559         (plus:SI (match_operand:SI 1 "register_operand" "")
560                  (match_operand:SI 2 "const_int_operand" "")))]
561   "! add_operand (operands[2], SImode)"
562   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
563    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
564 {
565   HOST_WIDE_INT val = INTVAL (operands[2]);
566   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
567   HOST_WIDE_INT rest = val - low;
568
569   operands[3] = GEN_INT (rest);
570   operands[4] = GEN_INT (low);
571 })
572
573 (define_insn "*addsi_se"
574   [(set (match_operand:DI 0 "register_operand" "=r,r")
575         (sign_extend:DI
576          (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
577                   (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
578   ""
579   "@
580    addl %r1,%2,%0
581    subl %r1,%n2,%0")
582
583 (define_split
584   [(set (match_operand:DI 0 "register_operand" "")
585         (sign_extend:DI
586          (plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
587                   (match_operand:SI 2 "const_int_operand" ""))))
588    (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
589   "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
590    && INTVAL (operands[2]) % 4 == 0"
591   [(set (match_dup 3) (match_dup 4))
592    (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
593                                                         (match_dup 5))
594                                                (match_dup 1))))]
595 {
596   HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
597   int mult = 4;
598
599   if (val % 2 == 0)
600     val /= 2, mult = 8;
601
602   operands[4] = GEN_INT (val);
603   operands[5] = GEN_INT (mult);
604 })
605
606 (define_split
607   [(set (match_operand:DI 0 "register_operand" "")
608         (sign_extend:DI
609          (plus:SI (match_operator:SI 1 "comparison_operator"
610                                      [(match_operand 2 "" "")
611                                       (match_operand 3 "" "")])
612                   (match_operand:SI 4 "add_operand" ""))))
613    (clobber (match_operand:DI 5 "register_operand" ""))]
614   ""
615   [(set (match_dup 5) (match_dup 6))
616    (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
617 {
618   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
619                                 operands[2], operands[3]);
620   operands[7] = gen_lowpart (SImode, operands[5]);
621 })
622
623 (define_insn "addvsi3"
624   [(set (match_operand:SI 0 "register_operand" "=r,r")
625         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
626                  (match_operand:SI 2 "sext_add_operand" "rI,O")))
627    (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
628                          (sign_extend:DI (match_dup 2)))
629                 (sign_extend:DI (plus:SI (match_dup 1)
630                                          (match_dup 2))))
631             (const_int 0))]
632   ""
633   "@
634    addlv %r1,%2,%0
635    sublv %r1,%n2,%0")
636
637 (define_expand "adddi3"
638   [(set (match_operand:DI 0 "register_operand" "")
639         (plus:DI (match_operand:DI 1 "register_operand" "")
640                  (match_operand:DI 2 "add_operand" "")))]
641   ""
642   "")
643
644 (define_insn "*adddi_er_high_l"
645   [(set (match_operand:DI 0 "register_operand" "=r")
646         (plus:DI (match_operand:DI 1 "register_operand" "r")
647                  (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
648   "TARGET_EXPLICIT_RELOCS"
649   "ldah %0,%2(%1)\t\t!gprelhigh")
650
651 ;; We used to expend quite a lot of effort choosing addq/subq/lda.
652 ;; With complications like
653 ;;
654 ;;   The NT stack unwind code can't handle a subq to adjust the stack
655 ;;   (that's a bug, but not one we can do anything about).  As of NT4.0 SP3,
656 ;;   the exception handling code will loop if a subq is used and an
657 ;;   exception occurs.
658 ;;
659 ;;   The 19980616 change to emit prologues as RTL also confused some
660 ;;   versions of GDB, which also interprets prologues.  This has been
661 ;;   fixed as of GDB 4.18, but it does not harm to unconditionally
662 ;;   use lda here.
663 ;;
664 ;; and the fact that the three insns schedule exactly the same, it's
665 ;; just not worth the effort.
666
667 (define_insn "*adddi_internal"
668   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
669         (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
670                  (match_operand:DI 2 "add_operand" "r,K,L")))]
671   ""
672   "@
673    addq %1,%2,%0
674    lda %0,%2(%1)
675    ldah %0,%h2(%1)")
676
677 ;; ??? Allow large constants when basing off the frame pointer or some
678 ;; virtual register that may eliminate to the frame pointer.  This is
679 ;; done because register elimination offsets will change the hi/lo split,
680 ;; and if we split before reload, we will require additional instructions.
681
682 (define_insn "*adddi_fp_hack"
683   [(set (match_operand:DI 0 "register_operand" "=r")
684         (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
685                  (match_operand:DI 2 "const_int_operand" "n")))]
686   "NONSTRICT_REG_OK_FP_BASE_P (operands[1])
687    && INTVAL (operands[2]) >= 0
688    /* This is the largest constant an lda+ldah pair can add, minus
689       an upper bound on the displacement between SP and AP during
690       register elimination.  See INITIAL_ELIMINATION_OFFSET.  */
691    && INTVAL (operands[2])
692         < (0x7fff8000
693            - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
694            - ALPHA_ROUND(current_function_outgoing_args_size)
695            - (ALPHA_ROUND (get_frame_size ()
696                            + max_reg_num () * UNITS_PER_WORD
697                            + current_function_pretend_args_size)
698               - current_function_pretend_args_size))"
699   "#")
700
701 ;; Don't do this if we are adjusting SP since we don't want to do it
702 ;; in two steps.  Don't split FP sources for the reason listed above.
703 (define_split
704   [(set (match_operand:DI 0 "register_operand" "")
705         (plus:DI (match_operand:DI 1 "register_operand" "")
706                  (match_operand:DI 2 "const_int_operand" "")))]
707   "! add_operand (operands[2], DImode)
708    && operands[0] != stack_pointer_rtx
709    && operands[1] != frame_pointer_rtx
710    && operands[1] != arg_pointer_rtx"
711   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
712    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
713 {
714   HOST_WIDE_INT val = INTVAL (operands[2]);
715   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
716   HOST_WIDE_INT rest = val - low;
717
718   operands[4] = GEN_INT (low);
719   if (CONST_OK_FOR_LETTER_P (rest, 'L'))
720     operands[3] = GEN_INT (rest);
721   else if (! no_new_pseudos)
722     {
723       operands[3] = gen_reg_rtx (DImode);
724       emit_move_insn (operands[3], operands[2]);
725       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
726       DONE;
727     }
728   else
729     FAIL;
730 })
731
732 (define_insn "*saddl"
733   [(set (match_operand:SI 0 "register_operand" "=r,r")
734         (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
735                           (match_operand:SI 2 "const48_operand" "I,I"))
736                  (match_operand:SI 3 "sext_add_operand" "rI,O")))]
737   ""
738   "@
739    s%2addl %1,%3,%0
740    s%2subl %1,%n3,%0")
741
742 (define_insn "*saddl_se"
743   [(set (match_operand:DI 0 "register_operand" "=r,r")
744         (sign_extend:DI
745          (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
746                            (match_operand:SI 2 "const48_operand" "I,I"))
747                   (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
748   ""
749   "@
750    s%2addl %1,%3,%0
751    s%2subl %1,%n3,%0")
752
753 (define_split
754   [(set (match_operand:DI 0 "register_operand" "")
755         (sign_extend:DI
756          (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
757                                               [(match_operand 2 "" "")
758                                                (match_operand 3 "" "")])
759                            (match_operand:SI 4 "const48_operand" ""))
760                   (match_operand:SI 5 "sext_add_operand" ""))))
761    (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
762   ""
763   [(set (match_dup 6) (match_dup 7))
764    (set (match_dup 0)
765         (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
766                                  (match_dup 5))))]
767 {
768   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
769                                 operands[2], operands[3]);
770   operands[8] = gen_lowpart (SImode, operands[6]);
771 })
772
773 (define_insn "*saddq"
774   [(set (match_operand:DI 0 "register_operand" "=r,r")
775         (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
776                           (match_operand:DI 2 "const48_operand" "I,I"))
777                  (match_operand:DI 3 "sext_add_operand" "rI,O")))]
778   ""
779   "@
780    s%2addq %1,%3,%0
781    s%2subq %1,%n3,%0")
782
783 (define_insn "addvdi3"
784   [(set (match_operand:DI 0 "register_operand" "=r,r")
785         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
786                  (match_operand:DI 2 "sext_add_operand" "rI,O")))
787    (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
788                          (sign_extend:TI (match_dup 2)))
789                 (sign_extend:TI (plus:DI (match_dup 1)
790                                          (match_dup 2))))
791             (const_int 0))]
792   ""
793   "@
794    addqv %r1,%2,%0
795    subqv %r1,%n2,%0")
796
797 (define_insn "negsi2"
798   [(set (match_operand:SI 0 "register_operand" "=r")
799         (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
800   ""
801   "subl $31,%1,%0")
802
803 (define_insn "*negsi_se"
804   [(set (match_operand:DI 0 "register_operand" "=r")
805         (sign_extend:DI (neg:SI
806                          (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
807   ""
808   "subl $31,%1,%0")
809
810 (define_insn "negvsi2"
811   [(set (match_operand:SI 0 "register_operand" "=r")
812         (neg:SI (match_operand:SI 1 "register_operand" "r")))
813    (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
814                 (sign_extend:DI (neg:SI (match_dup 1))))
815             (const_int 0))]
816   ""
817   "sublv $31,%1,%0")
818
819 (define_insn "negdi2"
820   [(set (match_operand:DI 0 "register_operand" "=r")
821         (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
822   ""
823   "subq $31,%1,%0")
824
825 (define_insn "negvdi2"
826   [(set (match_operand:DI 0 "register_operand" "=r")
827         (neg:DI (match_operand:DI 1 "register_operand" "r")))
828    (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
829                 (sign_extend:TI (neg:DI (match_dup 1))))
830             (const_int 0))]
831   ""
832   "subqv $31,%1,%0")
833
834 (define_expand "subsi3"
835   [(set (match_operand:SI 0 "register_operand" "")
836         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
837                   (match_operand:SI 2 "reg_or_8bit_operand" "")))]
838   ""
839 {
840   if (optimize)
841     {
842       rtx op1 = gen_lowpart (DImode, operands[1]);
843       rtx op2 = gen_lowpart (DImode, operands[2]);
844
845       if (! cse_not_expected)
846         {
847           rtx tmp = gen_reg_rtx (DImode);
848           emit_insn (gen_subdi3 (tmp, op1, op2));
849           emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
850         }
851       else
852         emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
853       DONE;
854     }
855 })
856
857 (define_insn "*subsi_internal"
858   [(set (match_operand:SI 0 "register_operand" "=r")
859         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
860                   (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
861   ""
862   "subl %r1,%2,%0")
863
864 (define_insn "*subsi_se"
865   [(set (match_operand:DI 0 "register_operand" "=r")
866         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
867                                   (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
868   ""
869   "subl %r1,%2,%0")
870
871 (define_insn "subvsi3"
872   [(set (match_operand:SI 0 "register_operand" "=r")
873         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
874                   (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
875    (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
876                           (sign_extend:DI (match_dup 2)))
877                 (sign_extend:DI (minus:SI (match_dup 1)
878                                           (match_dup 2))))
879             (const_int 0))]
880   ""
881   "sublv %r1,%2,%0")
882
883 (define_insn "subdi3"
884   [(set (match_operand:DI 0 "register_operand" "=r")
885         (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
886                   (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
887   ""
888   "subq %r1,%2,%0")
889
890 (define_insn "*ssubl"
891   [(set (match_operand:SI 0 "register_operand" "=r")
892         (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
893                            (match_operand:SI 2 "const48_operand" "I"))
894                   (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
895   ""
896   "s%2subl %1,%3,%0")
897
898 (define_insn "*ssubl_se"
899   [(set (match_operand:DI 0 "register_operand" "=r")
900         (sign_extend:DI
901          (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
902                             (match_operand:SI 2 "const48_operand" "I"))
903                    (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
904   ""
905   "s%2subl %1,%3,%0")
906
907 (define_insn "*ssubq"
908   [(set (match_operand:DI 0 "register_operand" "=r")
909         (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
910                            (match_operand:DI 2 "const48_operand" "I"))
911                   (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
912   ""
913   "s%2subq %1,%3,%0")
914
915 (define_insn "subvdi3"
916   [(set (match_operand:DI 0 "register_operand" "=r")
917         (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
918                   (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
919    (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
920                           (sign_extend:TI (match_dup 2)))
921                 (sign_extend:TI (minus:DI (match_dup 1)
922                                           (match_dup 2))))
923             (const_int 0))]
924   ""
925   "subqv %r1,%2,%0")
926
927 ;; The Unicos/Mk assembler doesn't support mull.
928
929 (define_insn "mulsi3"
930   [(set (match_operand:SI 0 "register_operand" "=r")
931         (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
932                  (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
933   "!TARGET_ABI_UNICOSMK"
934   "mull %r1,%2,%0"
935   [(set_attr "type" "imul")
936    (set_attr "opsize" "si")])
937
938 (define_insn "*mulsi_se"
939   [(set (match_operand:DI 0 "register_operand" "=r")
940         (sign_extend:DI
941           (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
942                    (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
943   "!TARGET_ABI_UNICOSMK"
944   "mull %r1,%2,%0"
945   [(set_attr "type" "imul")
946    (set_attr "opsize" "si")])
947
948 (define_insn "mulvsi3"
949   [(set (match_operand:SI 0 "register_operand" "=r")
950         (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
951                  (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
952    (trap_if (ne (mult:DI (sign_extend:DI (match_dup 1))
953                          (sign_extend:DI (match_dup 2)))
954                 (sign_extend:DI (mult:SI (match_dup 1)
955                                          (match_dup 2))))
956             (const_int 0))]
957   "!TARGET_ABI_UNICOSMK"
958   "mullv %r1,%2,%0"
959   [(set_attr "type" "imul")
960    (set_attr "opsize" "si")])
961
962 (define_insn "muldi3"
963   [(set (match_operand:DI 0 "register_operand" "=r")
964         (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
965                  (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
966   ""
967   "mulq %r1,%2,%0"
968   [(set_attr "type" "imul")])
969
970 (define_insn "mulvdi3"
971   [(set (match_operand:DI 0 "register_operand" "=r")
972         (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
973                  (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
974    (trap_if (ne (mult:TI (sign_extend:TI (match_dup 1))
975                          (sign_extend:TI (match_dup 2)))
976                 (sign_extend:TI (mult:DI (match_dup 1)
977                                          (match_dup 2))))
978             (const_int 0))]
979   ""
980   "mulqv %r1,%2,%0"
981   [(set_attr "type" "imul")])
982
983 (define_insn "umuldi3_highpart"
984   [(set (match_operand:DI 0 "register_operand" "=r")
985         (truncate:DI
986          (lshiftrt:TI
987           (mult:TI (zero_extend:TI
988                      (match_operand:DI 1 "reg_or_0_operand" "%rJ"))
989                    (zero_extend:TI
990                      (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
991           (const_int 64))))]
992   ""
993   "umulh %r1,%2,%0"
994   [(set_attr "type" "imul")
995    (set_attr "opsize" "udi")])
996
997 (define_insn "*umuldi3_highpart_const"
998   [(set (match_operand:DI 0 "register_operand" "=r")
999         (truncate:DI
1000          (lshiftrt:TI
1001           (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
1002                    (match_operand:TI 2 "cint8_operand" "I"))
1003           (const_int 64))))]
1004   ""
1005   "umulh %1,%2,%0"
1006   [(set_attr "type" "imul")
1007    (set_attr "opsize" "udi")])
1008 \f
1009 ;; The divide and remainder operations take their inputs from r24 and
1010 ;; r25, put their output in r27, and clobber r23 and r28 on all
1011 ;; systems except Unicos/Mk. On Unicos, the standard library provides
1012 ;; subroutines which use the standard calling convention and work on
1013 ;; DImode operands.
1014
1015 ;; ??? Force sign-extension here because some versions of OSF/1 and
1016 ;; Interix/NT don't do the right thing if the inputs are not properly
1017 ;; sign-extended.  But Linux, for instance, does not have this
1018 ;; problem.  Is it worth the complication here to eliminate the sign
1019 ;; extension?
1020
1021 (define_expand "divsi3"
1022   [(set (reg:DI 24)
1023         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
1024    (set (reg:DI 25)
1025         (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
1026    (parallel [(set (reg:DI 27)
1027                    (sign_extend:DI (div:SI (reg:DI 24) (reg:DI 25))))
1028               (clobber (reg:DI 23))
1029               (clobber (reg:DI 28))])
1030    (set (match_operand:SI 0 "nonimmediate_operand" "")
1031         (subreg:SI (reg:DI 27) 0))]
1032   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1033   "")
1034
1035 (define_expand "udivsi3"
1036   [(set (reg:DI 24)
1037         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
1038    (set (reg:DI 25)
1039         (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
1040    (parallel [(set (reg:DI 27)
1041                    (sign_extend:DI (udiv:SI (reg:DI 24) (reg:DI 25))))
1042               (clobber (reg:DI 23))
1043               (clobber (reg:DI 28))])
1044    (set (match_operand:SI 0 "nonimmediate_operand" "")
1045         (subreg:SI (reg:DI 27) 0))]
1046   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1047   "")
1048
1049 (define_expand "modsi3"
1050   [(set (reg:DI 24)
1051         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
1052    (set (reg:DI 25)
1053         (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
1054    (parallel [(set (reg:DI 27)
1055                    (sign_extend:DI (mod:SI (reg:DI 24) (reg:DI 25))))
1056               (clobber (reg:DI 23))
1057               (clobber (reg:DI 28))])
1058    (set (match_operand:SI 0 "nonimmediate_operand" "")
1059         (subreg:SI (reg:DI 27) 0))]
1060   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1061   "")
1062
1063 (define_expand "umodsi3"
1064   [(set (reg:DI 24)
1065         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
1066    (set (reg:DI 25)
1067         (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
1068    (parallel [(set (reg:DI 27)
1069                    (sign_extend:DI (umod:SI (reg:DI 24) (reg:DI 25))))
1070               (clobber (reg:DI 23))
1071               (clobber (reg:DI 28))])
1072    (set (match_operand:SI 0 "nonimmediate_operand" "")
1073         (subreg:SI (reg:DI 27) 0))]
1074   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1075   "")
1076
1077 (define_expand "divdi3"
1078   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
1079    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
1080    (parallel [(set (reg:DI 27)
1081                    (div:DI (reg:DI 24)
1082                            (reg:DI 25)))
1083               (clobber (reg:DI 23))
1084               (clobber (reg:DI 28))])
1085    (set (match_operand:DI 0 "nonimmediate_operand" "")
1086         (reg:DI 27))]
1087   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1088   "")
1089
1090 (define_expand "udivdi3"
1091   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
1092    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
1093    (parallel [(set (reg:DI 27)
1094                    (udiv:DI (reg:DI 24)
1095                             (reg:DI 25)))
1096               (clobber (reg:DI 23))
1097               (clobber (reg:DI 28))])
1098    (set (match_operand:DI 0 "nonimmediate_operand" "")
1099         (reg:DI 27))]
1100   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1101   "")
1102
1103 (define_expand "moddi3"
1104   [(use (match_operand:DI 0 "nonimmediate_operand" ""))
1105    (use (match_operand:DI 1 "input_operand" ""))
1106    (use (match_operand:DI 2 "input_operand" ""))]
1107   "!TARGET_ABI_OPEN_VMS"
1108 {
1109   if (TARGET_ABI_UNICOSMK)
1110     emit_insn (gen_moddi3_umk (operands[0], operands[1], operands[2]));
1111   else
1112     emit_insn (gen_moddi3_dft (operands[0], operands[1], operands[2]));
1113   DONE;
1114 })
1115
1116 (define_expand "moddi3_dft"
1117   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
1118    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
1119    (parallel [(set (reg:DI 27)
1120                    (mod:DI (reg:DI 24)
1121                            (reg:DI 25)))
1122               (clobber (reg:DI 23))
1123               (clobber (reg:DI 28))])
1124    (set (match_operand:DI 0 "nonimmediate_operand" "")
1125         (reg:DI 27))]
1126   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1127   "")
1128
1129 ;; On Unicos/Mk, we do as the system's C compiler does:
1130 ;; compute the quotient, multiply and subtract.
1131
1132 (define_expand "moddi3_umk"
1133   [(use (match_operand:DI 0 "nonimmediate_operand" ""))
1134    (use (match_operand:DI 1 "input_operand" ""))
1135    (use (match_operand:DI 2 "input_operand" ""))]
1136   "TARGET_ABI_UNICOSMK"
1137 {
1138   rtx mul, div, tmp;
1139
1140   mul = gen_reg_rtx (DImode);
1141   tmp = gen_reg_rtx (DImode);
1142   operands[1] = force_reg (DImode, operands[1]);
1143   operands[2] = force_reg (DImode, operands[2]);
1144
1145   div = expand_binop (DImode, sdiv_optab, operands[1], operands[2],
1146                       NULL_RTX, 0, OPTAB_LIB);
1147   div = force_reg (DImode, div);
1148   emit_insn (gen_muldi3 (mul, operands[2], div));
1149   emit_insn (gen_subdi3 (tmp, operands[1], mul));
1150   emit_move_insn (operands[0], tmp);
1151   DONE;
1152 })
1153
1154 (define_expand "umoddi3"
1155   [(use (match_operand:DI 0 "nonimmediate_operand" ""))
1156    (use (match_operand:DI 1 "input_operand" ""))
1157    (use (match_operand:DI 2 "input_operand" ""))]
1158   "! TARGET_ABI_OPEN_VMS"
1159 {
1160   if (TARGET_ABI_UNICOSMK)
1161     emit_insn (gen_umoddi3_umk (operands[0], operands[1], operands[2]));
1162   else
1163     emit_insn (gen_umoddi3_dft (operands[0], operands[1], operands[2]));
1164   DONE;
1165 })
1166
1167 (define_expand "umoddi3_dft"
1168   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
1169    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
1170    (parallel [(set (reg:DI 27)
1171                    (umod:DI (reg:DI 24)
1172                             (reg:DI 25)))
1173               (clobber (reg:DI 23))
1174               (clobber (reg:DI 28))])
1175    (set (match_operand:DI 0 "nonimmediate_operand" "")
1176         (reg:DI 27))]
1177   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1178   "")
1179
1180 (define_expand "umoddi3_umk"
1181   [(use (match_operand:DI 0 "nonimmediate_operand" ""))
1182    (use (match_operand:DI 1 "input_operand" ""))
1183    (use (match_operand:DI 2 "input_operand" ""))]
1184   "TARGET_ABI_UNICOSMK"
1185 {
1186   rtx mul, div, tmp;
1187
1188   mul = gen_reg_rtx (DImode);
1189   tmp = gen_reg_rtx (DImode);
1190   operands[1] = force_reg (DImode, operands[1]);
1191   operands[2] = force_reg (DImode, operands[2]);
1192
1193   div = expand_binop (DImode, udiv_optab, operands[1], operands[2],
1194                       NULL_RTX, 1, OPTAB_LIB);
1195   div = force_reg (DImode, div);
1196   emit_insn (gen_muldi3 (mul, operands[2], div));
1197   emit_insn (gen_subdi3 (tmp, operands[1], mul));
1198   emit_move_insn (operands[0], tmp);
1199   DONE;
1200 })
1201
1202 ;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
1203 ;; expanded by the assembler.
1204
1205 (define_insn "*divmodsi_internal_er"
1206   [(set (reg:DI 27)
1207         (sign_extend:DI (match_operator:SI 0 "divmod_operator"
1208                         [(reg:DI 24) (reg:DI 25)])))
1209    (clobber (reg:DI 23))
1210    (clobber (reg:DI 28))]
1211   "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
1212   "ldq $27,__%E0($29)\t\t!literal!%#\;jsr $23,($27),__%E0\t\t!lituse_jsr!%#"
1213   [(set_attr "type" "jsr")
1214    (set_attr "length" "8")])
1215
1216 (define_insn "*divmodsi_internal"
1217   [(set (reg:DI 27)
1218         (sign_extend:DI (match_operator:SI 0 "divmod_operator"
1219                         [(reg:DI 24) (reg:DI 25)])))
1220    (clobber (reg:DI 23))
1221    (clobber (reg:DI 28))]
1222   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1223   "%E0 $24,$25,$27"
1224   [(set_attr "type" "jsr")
1225    (set_attr "length" "8")])
1226
1227 (define_insn "*divmoddi_internal_er"
1228   [(set (reg:DI 27)
1229         (match_operator:DI 0 "divmod_operator"
1230                         [(reg:DI 24) (reg:DI 25)]))
1231    (clobber (reg:DI 23))
1232    (clobber (reg:DI 28))]
1233   "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
1234   "ldq $27,__%E0($29)\t\t!literal!%#\;jsr $23,($27),__%E0\t\t!lituse_jsr!%#"
1235   [(set_attr "type" "jsr")
1236    (set_attr "length" "8")])
1237
1238 (define_insn "*divmoddi_internal"
1239   [(set (reg:DI 27)
1240         (match_operator:DI 0 "divmod_operator"
1241                         [(reg:DI 24) (reg:DI 25)]))
1242    (clobber (reg:DI 23))
1243    (clobber (reg:DI 28))]
1244   "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1245   "%E0 $24,$25,$27"
1246   [(set_attr "type" "jsr")
1247    (set_attr "length" "8")])
1248 \f
1249 ;; Next are the basic logical operations.  These only exist in DImode.
1250
1251 (define_insn "anddi3"
1252   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1253         (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
1254                 (match_operand:DI 2 "and_operand" "rI,N,MH")))]
1255   ""
1256   "@
1257    and %r1,%2,%0
1258    bic %r1,%N2,%0
1259    zapnot %r1,%m2,%0"
1260   [(set_attr "type" "ilog,ilog,shift")])
1261
1262 ;; There are times when we can split an AND into two AND insns.  This occurs
1263 ;; when we can first clear any bytes and then clear anything else.  For
1264 ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
1265 ;; Only do this when running on 64-bit host since the computations are
1266 ;; too messy otherwise.
1267
1268 (define_split
1269   [(set (match_operand:DI 0 "register_operand" "")
1270         (and:DI (match_operand:DI 1 "register_operand" "")
1271                 (match_operand:DI 2 "const_int_operand" "")))]
1272   "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
1273   [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
1274    (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
1275 {
1276   unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
1277   unsigned HOST_WIDE_INT mask2 = mask1;
1278   int i;
1279
1280   /* For each byte that isn't all zeros, make it all ones.  */
1281   for (i = 0; i < 64; i += 8)
1282     if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
1283       mask1 |= (HOST_WIDE_INT) 0xff << i;
1284
1285   /* Now turn on any bits we've just turned off.  */
1286   mask2 |= ~ mask1;
1287
1288   operands[3] = GEN_INT (mask1);
1289   operands[4] = GEN_INT (mask2);
1290 })
1291
1292 (define_expand "zero_extendqihi2"
1293   [(set (match_operand:HI 0 "register_operand" "")
1294         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1295   ""
1296 {
1297   if (! TARGET_BWX)
1298     operands[1] = force_reg (QImode, operands[1]);
1299 })
1300
1301 (define_insn "*zero_extendqihi2_bwx"
1302   [(set (match_operand:HI 0 "register_operand" "=r,r")
1303         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1304   "TARGET_BWX"
1305   "@
1306    and %1,0xff,%0
1307    ldbu %0,%1"
1308   [(set_attr "type" "ilog,ild")])
1309
1310 (define_insn "*zero_extendqihi2_nobwx"
1311   [(set (match_operand:HI 0 "register_operand" "=r")
1312         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1313   "! TARGET_BWX"
1314   "and %1,0xff,%0"
1315   [(set_attr "type" "ilog")])
1316
1317 (define_expand "zero_extendqisi2"
1318   [(set (match_operand:SI 0 "register_operand" "")
1319         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1320   ""
1321 {
1322   if (! TARGET_BWX)
1323     operands[1] = force_reg (QImode, operands[1]);
1324 })
1325
1326 (define_insn "*zero_extendqisi2_bwx"
1327   [(set (match_operand:SI 0 "register_operand" "=r,r")
1328         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1329   "TARGET_BWX"
1330   "@
1331    and %1,0xff,%0
1332    ldbu %0,%1"
1333   [(set_attr "type" "ilog,ild")])
1334
1335 (define_insn "*zero_extendqisi2_nobwx"
1336   [(set (match_operand:SI 0 "register_operand" "=r")
1337         (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1338   "! TARGET_BWX"
1339   "and %1,0xff,%0"
1340   [(set_attr "type" "ilog")])
1341
1342 (define_expand "zero_extendqidi2"
1343   [(set (match_operand:DI 0 "register_operand" "")
1344         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
1345   ""
1346 {
1347   if (! TARGET_BWX)
1348     operands[1] = force_reg (QImode, operands[1]);
1349 })
1350
1351 (define_insn "*zero_extendqidi2_bwx"
1352   [(set (match_operand:DI 0 "register_operand" "=r,r")
1353         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1354   "TARGET_BWX"
1355   "@
1356    and %1,0xff,%0
1357    ldbu %0,%1"
1358   [(set_attr "type" "ilog,ild")])
1359
1360 (define_insn "*zero_extendqidi2_nobwx"
1361   [(set (match_operand:DI 0 "register_operand" "=r")
1362         (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1363   "! TARGET_BWX"
1364   "and %1,0xff,%0"
1365   [(set_attr "type" "ilog")])
1366
1367 (define_expand "zero_extendhisi2"
1368   [(set (match_operand:SI 0 "register_operand" "")
1369         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1370   ""
1371 {
1372   if (! TARGET_BWX)
1373     operands[1] = force_reg (HImode, operands[1]);
1374 })
1375
1376 (define_insn "*zero_extendhisi2_bwx"
1377   [(set (match_operand:SI 0 "register_operand" "=r,r")
1378         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1379   "TARGET_BWX"
1380   "@
1381    zapnot %1,3,%0
1382    ldwu %0,%1"
1383   [(set_attr "type" "shift,ild")])
1384
1385 (define_insn "*zero_extendhisi2_nobwx"
1386   [(set (match_operand:SI 0 "register_operand" "=r")
1387         (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1388   "! TARGET_BWX"
1389   "zapnot %1,3,%0"
1390   [(set_attr "type" "shift")])
1391
1392 (define_expand "zero_extendhidi2"
1393   [(set (match_operand:DI 0 "register_operand" "")
1394         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
1395   ""
1396 {
1397   if (! TARGET_BWX)
1398     operands[1] = force_reg (HImode, operands[1]);
1399 })
1400
1401 (define_insn "*zero_extendhidi2_bwx"
1402   [(set (match_operand:DI 0 "register_operand" "=r,r")
1403         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1404   "TARGET_BWX"
1405   "@
1406    zapnot %1,3,%0
1407    ldwu %0,%1"
1408   [(set_attr "type" "shift,ild")])
1409
1410 (define_insn "*zero_extendhidi2_nobwx"
1411   [(set (match_operand:DI 0 "register_operand" "=r")
1412         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1413   ""
1414   "zapnot %1,3,%0"
1415   [(set_attr "type" "shift")])
1416
1417 (define_insn "zero_extendsidi2"
1418   [(set (match_operand:DI 0 "register_operand" "=r")
1419         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1420   ""
1421   "zapnot %1,15,%0"
1422   [(set_attr "type" "shift")])
1423
1424 (define_insn "andnotdi3"
1425   [(set (match_operand:DI 0 "register_operand" "=r")
1426         (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1427                 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1428   ""
1429   "bic %r2,%1,%0"
1430   [(set_attr "type" "ilog")])
1431
1432 (define_insn "iordi3"
1433   [(set (match_operand:DI 0 "register_operand" "=r,r")
1434         (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1435                 (match_operand:DI 2 "or_operand" "rI,N")))]
1436   ""
1437   "@
1438    bis %r1,%2,%0
1439    ornot %r1,%N2,%0"
1440   [(set_attr "type" "ilog")])
1441
1442 (define_insn "one_cmpldi2"
1443   [(set (match_operand:DI 0 "register_operand" "=r")
1444         (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
1445   ""
1446   "ornot $31,%1,%0"
1447   [(set_attr "type" "ilog")])
1448
1449 (define_insn "*iornot"
1450   [(set (match_operand:DI 0 "register_operand" "=r")
1451         (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1452                 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1453   ""
1454   "ornot %r2,%1,%0"
1455   [(set_attr "type" "ilog")])
1456
1457 (define_insn "xordi3"
1458   [(set (match_operand:DI 0 "register_operand" "=r,r")
1459         (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1460                 (match_operand:DI 2 "or_operand" "rI,N")))]
1461   ""
1462   "@
1463    xor %r1,%2,%0
1464    eqv %r1,%N2,%0"
1465   [(set_attr "type" "ilog")])
1466
1467 (define_insn "*xornot"
1468   [(set (match_operand:DI 0 "register_operand" "=r")
1469         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
1470                         (match_operand:DI 2 "register_operand" "rI"))))]
1471   ""
1472   "eqv %r1,%2,%0"
1473   [(set_attr "type" "ilog")])
1474 \f
1475 ;; Handle the FFS insn iff we support CIX.
1476
1477 (define_expand "ffsdi2"
1478   [(set (match_dup 2)
1479         (unspec:DI [(match_operand:DI 1 "register_operand" "")] UNSPEC_CTTZ))
1480    (set (match_dup 3)
1481         (plus:DI (match_dup 2) (const_int 1)))
1482    (set (match_operand:DI 0 "register_operand" "")
1483         (if_then_else:DI (eq (match_dup 1) (const_int 0))
1484                          (const_int 0) (match_dup 3)))]
1485   "TARGET_CIX"
1486 {
1487   operands[2] = gen_reg_rtx (DImode);
1488   operands[3] = gen_reg_rtx (DImode);
1489 })
1490
1491 (define_insn "*cttz"
1492   [(set (match_operand:DI 0 "register_operand" "=r")
1493         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_CTTZ))]
1494   "TARGET_CIX"
1495   "cttz %1,%0"
1496   ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
1497   ; reuse the existing type name.
1498   [(set_attr "type" "mvi")])
1499 \f
1500 ;; Next come the shifts and the various extract and insert operations.
1501
1502 (define_insn "ashldi3"
1503   [(set (match_operand:DI 0 "register_operand" "=r,r")
1504         (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
1505                    (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
1506   ""
1507 {
1508   switch (which_alternative)
1509     {
1510     case 0:
1511       if (operands[2] == const1_rtx)
1512         return "addq %r1,%r1,%0";
1513       else
1514         return "s%P2addq %r1,0,%0";
1515     case 1:
1516       return "sll %r1,%2,%0";
1517     default:
1518       abort();
1519     }
1520 }
1521   [(set_attr "type" "iadd,shift")])
1522
1523 ;; ??? The following pattern is made by combine, but earlier phases
1524 ;; (specifically flow) can't handle it.  This occurs in jump.c.  Deal
1525 ;; with this in a better way at some point.
1526 ;;(define_insn ""
1527 ;;  [(set (match_operand:DI 0 "register_operand" "=r")
1528 ;;      (sign_extend:DI
1529 ;;       (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1530 ;;                             (match_operand:DI 2 "const_int_operand" "P"))
1531 ;;                  0)))]
1532 ;;  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
1533 ;;{
1534 ;;  if (operands[2] == const1_rtx)
1535 ;;    return "addl %r1,%r1,%0";
1536 ;;  else
1537 ;;    return "s%P2addl %r1,0,%0";
1538 ;;}
1539 ;;  [(set_attr "type" "iadd")])
1540
1541 (define_insn "lshrdi3"
1542   [(set (match_operand:DI 0 "register_operand" "=r")
1543         (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1544                      (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1545   ""
1546   "srl %r1,%2,%0"
1547   [(set_attr "type" "shift")])
1548
1549 (define_insn "ashrdi3"
1550   [(set (match_operand:DI 0 "register_operand" "=r")
1551         (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1552                      (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1553   ""
1554   "sra %r1,%2,%0"
1555   [(set_attr "type" "shift")])
1556
1557 (define_expand "extendqihi2"
1558   [(set (match_dup 2)
1559         (ashift:DI (match_operand:QI 1 "some_operand" "")
1560                    (const_int 56)))
1561    (set (match_operand:HI 0 "register_operand" "")
1562         (ashiftrt:DI (match_dup 2)
1563                      (const_int 56)))]
1564   ""
1565 {
1566   if (TARGET_BWX)
1567     {
1568       emit_insn (gen_extendqihi2x (operands[0],
1569                                    force_reg (QImode, operands[1])));
1570       DONE;
1571     }
1572
1573  /* If we have an unaligned MEM, extend to DImode (which we do
1574      specially) and then copy to the result.  */
1575   if (unaligned_memory_operand (operands[1], HImode))
1576     {
1577       rtx temp = gen_reg_rtx (DImode);
1578
1579       emit_insn (gen_extendqidi2 (temp, operands[1]));
1580       emit_move_insn (operands[0], gen_lowpart (HImode, temp));
1581       DONE;
1582     }
1583
1584   operands[0] = gen_lowpart (DImode, operands[0]);
1585   operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1586   operands[2] = gen_reg_rtx (DImode);
1587 })
1588
1589 (define_insn "extendqidi2x"
1590   [(set (match_operand:DI 0 "register_operand" "=r")
1591         (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1592   "TARGET_BWX"
1593   "sextb %1,%0"
1594   [(set_attr "type" "shift")])
1595
1596 (define_insn "extendhidi2x"
1597   [(set (match_operand:DI 0 "register_operand" "=r")
1598         (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1599   "TARGET_BWX"
1600   "sextw %1,%0"
1601   [(set_attr "type" "shift")])
1602
1603 (define_insn "extendqisi2x"
1604   [(set (match_operand:SI 0 "register_operand" "=r")
1605         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1606   "TARGET_BWX"
1607   "sextb %1,%0"
1608   [(set_attr "type" "shift")])
1609
1610 (define_insn "extendhisi2x"
1611   [(set (match_operand:SI 0 "register_operand" "=r")
1612         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1613   "TARGET_BWX"
1614   "sextw %1,%0"
1615   [(set_attr "type" "shift")])
1616
1617 (define_insn "extendqihi2x"
1618   [(set (match_operand:HI 0 "register_operand" "=r")
1619         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1620   "TARGET_BWX"
1621   "sextb %1,%0"
1622   [(set_attr "type" "shift")])
1623
1624 (define_expand "extendqisi2"
1625   [(set (match_dup 2)
1626         (ashift:DI (match_operand:QI 1 "some_operand" "")
1627                    (const_int 56)))
1628    (set (match_operand:SI 0 "register_operand" "")
1629         (ashiftrt:DI (match_dup 2)
1630                      (const_int 56)))]
1631   ""
1632 {
1633   if (TARGET_BWX)
1634     {
1635       emit_insn (gen_extendqisi2x (operands[0],
1636                                    force_reg (QImode, operands[1])));
1637       DONE;
1638     }
1639
1640   /* If we have an unaligned MEM, extend to a DImode form of
1641      the result (which we do specially).  */
1642   if (unaligned_memory_operand (operands[1], QImode))
1643     {
1644       rtx temp = gen_reg_rtx (DImode);
1645
1646       emit_insn (gen_extendqidi2 (temp, operands[1]));
1647       emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1648       DONE;
1649     }
1650
1651   operands[0] = gen_lowpart (DImode, operands[0]);
1652   operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1653   operands[2] = gen_reg_rtx (DImode);
1654 })
1655
1656 (define_expand "extendqidi2"
1657   [(set (match_dup 2)
1658         (ashift:DI (match_operand:QI 1 "some_operand" "")
1659                    (const_int 56)))
1660    (set (match_operand:DI 0 "register_operand" "")
1661         (ashiftrt:DI (match_dup 2)
1662                      (const_int 56)))]
1663   ""
1664 {
1665   if (TARGET_BWX)
1666     {
1667       emit_insn (gen_extendqidi2x (operands[0],
1668                                    force_reg (QImode, operands[1])));
1669       DONE;
1670     }
1671
1672   if (unaligned_memory_operand (operands[1], QImode))
1673     {
1674       rtx seq
1675         = gen_unaligned_extendqidi (operands[0],
1676                                     get_unaligned_address (operands[1], 1));
1677
1678       alpha_set_memflags (seq, operands[1]);
1679       emit_insn (seq);
1680       DONE;
1681     }
1682
1683   operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1684   operands[2] = gen_reg_rtx (DImode);
1685 })
1686
1687 (define_expand "extendhisi2"
1688   [(set (match_dup 2)
1689         (ashift:DI (match_operand:HI 1 "some_operand" "")
1690                    (const_int 48)))
1691    (set (match_operand:SI 0 "register_operand" "")
1692         (ashiftrt:DI (match_dup 2)
1693                      (const_int 48)))]
1694   ""
1695 {
1696   if (TARGET_BWX)
1697     {
1698       emit_insn (gen_extendhisi2x (operands[0],
1699                                    force_reg (HImode, operands[1])));
1700       DONE;
1701     }
1702
1703   /* If we have an unaligned MEM, extend to a DImode form of
1704      the result (which we do specially).  */
1705   if (unaligned_memory_operand (operands[1], HImode))
1706     {
1707       rtx temp = gen_reg_rtx (DImode);
1708
1709       emit_insn (gen_extendhidi2 (temp, operands[1]));
1710       emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1711       DONE;
1712     }
1713
1714   operands[0] = gen_lowpart (DImode, operands[0]);
1715   operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1716   operands[2] = gen_reg_rtx (DImode);
1717 })
1718
1719 (define_expand "extendhidi2"
1720   [(set (match_dup 2)
1721         (ashift:DI (match_operand:HI 1 "some_operand" "")
1722                    (const_int 48)))
1723    (set (match_operand:DI 0 "register_operand" "")
1724         (ashiftrt:DI (match_dup 2)
1725                      (const_int 48)))]
1726   ""
1727 {
1728   if (TARGET_BWX)
1729     {
1730       emit_insn (gen_extendhidi2x (operands[0],
1731                                    force_reg (HImode, operands[1])));
1732       DONE;
1733     }
1734
1735   if (unaligned_memory_operand (operands[1], HImode))
1736     {
1737       rtx seq
1738         = gen_unaligned_extendhidi (operands[0],
1739                                     get_unaligned_address (operands[1], 2));
1740
1741       alpha_set_memflags (seq, operands[1]);
1742       emit_insn (seq);
1743       DONE;
1744     }
1745
1746   operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1747   operands[2] = gen_reg_rtx (DImode);
1748 })
1749
1750 ;; Here's how we sign extend an unaligned byte and halfword.  Doing this
1751 ;; as a pattern saves one instruction.  The code is similar to that for
1752 ;; the unaligned loads (see below).
1753 ;;
1754 ;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
1755 (define_expand "unaligned_extendqidi"
1756   [(use (match_operand:QI 0 "register_operand" ""))
1757    (use (match_operand:DI 1 "address_operand" ""))]
1758   ""
1759 {
1760   if (WORDS_BIG_ENDIAN)
1761     emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1]));
1762   else
1763     emit_insn (gen_unaligned_extendqidi_le (operands[0], operands[1]));
1764   DONE;
1765 })
1766
1767 (define_expand "unaligned_extendqidi_le"
1768   [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1769    (set (match_dup 3)
1770         (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
1771                         (const_int -8))))
1772    (set (match_dup 4)
1773         (ashift:DI (match_dup 3)
1774                    (minus:DI (const_int 64)
1775                              (ashift:DI
1776                               (and:DI (match_dup 2) (const_int 7))
1777                               (const_int 3)))))
1778    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1779         (ashiftrt:DI (match_dup 4) (const_int 56)))]
1780   "! WORDS_BIG_ENDIAN"
1781 {
1782   operands[2] = gen_reg_rtx (DImode);
1783   operands[3] = gen_reg_rtx (DImode);
1784   operands[4] = gen_reg_rtx (DImode);
1785 })
1786
1787 (define_expand "unaligned_extendqidi_be"
1788   [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1789    (set (match_dup 3) (plus:DI (match_dup 2) (const_int -1)))
1790    (set (match_dup 4)
1791         (mem:DI (and:DI (match_dup 3)
1792                         (const_int -8))))
1793    (set (match_dup 5) (plus:DI (match_dup 2) (const_int -2)))
1794    (set (match_dup 6)
1795         (ashift:DI (match_dup 4)
1796                    (ashift:DI
1797                      (and:DI
1798                        (plus:DI (match_dup 5) (const_int 1))
1799                        (const_int 7))
1800                      (const_int 3))))
1801    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1802         (ashiftrt:DI (match_dup 6) (const_int 56)))]
1803   "WORDS_BIG_ENDIAN"
1804 {
1805   operands[2] = gen_reg_rtx (DImode);
1806   operands[3] = gen_reg_rtx (DImode);
1807   operands[4] = gen_reg_rtx (DImode);
1808   operands[5] = gen_reg_rtx (DImode);
1809   operands[6] = gen_reg_rtx (DImode);
1810 })
1811
1812 (define_expand "unaligned_extendhidi"
1813   [(use (match_operand:QI 0 "register_operand" ""))
1814    (use (match_operand:DI 1 "address_operand" ""))]
1815   ""
1816 {
1817   if (WORDS_BIG_ENDIAN)
1818     emit_insn (gen_unaligned_extendhidi_be (operands[0], operands[1]));
1819   else
1820     emit_insn (gen_unaligned_extendhidi_le (operands[0], operands[1]));
1821   DONE;
1822 })
1823
1824 (define_expand "unaligned_extendhidi_le"
1825   [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1826    (set (match_dup 3)
1827         (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
1828                         (const_int -8))))
1829    (set (match_dup 4)
1830         (ashift:DI (match_dup 3)
1831                    (minus:DI (const_int 64)
1832                              (ashift:DI
1833                               (and:DI (match_dup 2) (const_int 7))
1834                               (const_int 3)))))
1835    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1836         (ashiftrt:DI (match_dup 4) (const_int 48)))]
1837   "! WORDS_BIG_ENDIAN"
1838 {
1839   operands[2] = gen_reg_rtx (DImode);
1840   operands[3] = gen_reg_rtx (DImode);
1841   operands[4] = gen_reg_rtx (DImode);
1842 })
1843
1844 (define_expand "unaligned_extendhidi_be"
1845   [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1846    (set (match_dup 3) (plus:DI (match_dup 2) (const_int -2)))
1847    (set (match_dup 4)
1848         (mem:DI (and:DI (match_dup 3)
1849                         (const_int -8))))
1850    (set (match_dup 5) (plus:DI (match_dup 2) (const_int -3)))
1851    (set (match_dup 6)
1852         (ashift:DI (match_dup 4)
1853                    (ashift:DI
1854                      (and:DI
1855                        (plus:DI (match_dup 5) (const_int 1))
1856                        (const_int 7))
1857                      (const_int 3))))
1858    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1859         (ashiftrt:DI (match_dup 6) (const_int 48)))]
1860   "WORDS_BIG_ENDIAN"
1861 {
1862   operands[2] = gen_reg_rtx (DImode);
1863   operands[3] = gen_reg_rtx (DImode);
1864   operands[4] = gen_reg_rtx (DImode);
1865   operands[5] = gen_reg_rtx (DImode);
1866   operands[6] = gen_reg_rtx (DImode);
1867 })
1868
1869 (define_insn "*extxl_const"
1870   [(set (match_operand:DI 0 "register_operand" "=r")
1871         (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1872                          (match_operand:DI 2 "mode_width_operand" "n")
1873                          (match_operand:DI 3 "mul8_operand" "I")))]
1874   ""
1875   "ext%M2l %r1,%s3,%0"
1876   [(set_attr "type" "shift")])
1877
1878 (define_insn "extxl_le"
1879   [(set (match_operand:DI 0 "register_operand" "=r")
1880         (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1881                          (match_operand:DI 2 "mode_width_operand" "n")
1882                          (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1883                                     (const_int 3))))]
1884   "! WORDS_BIG_ENDIAN"
1885   "ext%M2l %r1,%3,%0"
1886   [(set_attr "type" "shift")])
1887
1888 (define_insn "extxl_be"
1889   [(set (match_operand:DI 0 "register_operand" "=r")
1890         (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1891                          (match_operand:DI 2 "mode_width_operand" "n")
1892                          (minus:DI
1893                            (const_int 56)
1894                            (ashift:DI
1895                              (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1896                              (const_int 3)))))]
1897   "WORDS_BIG_ENDIAN"
1898   "ext%M2l %r1,%3,%0"
1899   [(set_attr "type" "shift")])
1900
1901 ;; Combine has some strange notion of preserving existing undefined behaviour
1902 ;; in shifts larger than a word size.  So capture these patterns that it
1903 ;; should have turned into zero_extracts.
1904
1905 (define_insn "*extxl_1_le"
1906   [(set (match_operand:DI 0 "register_operand" "=r")
1907         (and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1908                   (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1909                              (const_int 3)))
1910              (match_operand:DI 3 "mode_mask_operand" "n")))]
1911   "! WORDS_BIG_ENDIAN"
1912   "ext%U3l %1,%2,%0"
1913   [(set_attr "type" "shift")])
1914
1915 (define_insn "*extxl_1_be"
1916   [(set (match_operand:DI 0 "register_operand" "=r")
1917         (and:DI (lshiftrt:DI
1918                   (match_operand:DI 1 "reg_or_0_operand" "rJ")
1919                   (minus:DI (const_int 56)
1920                     (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1921                                (const_int 3))))
1922                 (match_operand:DI 3 "mode_mask_operand" "n")))]
1923   "WORDS_BIG_ENDIAN"
1924   "ext%U3l %1,%2,%0"
1925   [(set_attr "type" "shift")])
1926
1927 (define_insn "*extql_2_le"
1928   [(set (match_operand:DI 0 "register_operand" "=r")
1929         (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1930           (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1931                      (const_int 3))))]
1932   "! WORDS_BIG_ENDIAN"
1933   "extql %1,%2,%0"
1934   [(set_attr "type" "shift")])
1935
1936 (define_insn "*extql_2_be"
1937   [(set (match_operand:DI 0 "register_operand" "=r")
1938         (lshiftrt:DI
1939           (match_operand:DI 1 "reg_or_0_operand" "rJ")
1940           (minus:DI (const_int 56)
1941                     (ashift:DI
1942                       (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1943                       (const_int 3)))))]
1944   "WORDS_BIG_ENDIAN"
1945   "extql %1,%2,%0"
1946   [(set_attr "type" "shift")])
1947
1948 (define_insn "extqh_le"
1949   [(set (match_operand:DI 0 "register_operand" "=r")
1950         (ashift:DI
1951          (match_operand:DI 1 "reg_or_0_operand" "rJ")
1952           (minus:DI (const_int 64)
1953                     (ashift:DI
1954                      (and:DI
1955                       (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1956                       (const_int 7))
1957                      (const_int 3)))))]
1958   "! WORDS_BIG_ENDIAN"
1959   "extqh %r1,%2,%0"
1960   [(set_attr "type" "shift")])
1961
1962 (define_insn "extqh_be"
1963   [(set (match_operand:DI 0 "register_operand" "=r")
1964         (ashift:DI
1965           (match_operand:DI 1 "reg_or_0_operand" "rJ")
1966           (ashift:DI
1967             (and:DI
1968               (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1969                        (const_int 1))
1970               (const_int 7))
1971             (const_int 3))))]
1972   "WORDS_BIG_ENDIAN"
1973   "extqh %r1,%2,%0"
1974   [(set_attr "type" "shift")])
1975
1976 (define_insn "extlh_le"
1977   [(set (match_operand:DI 0 "register_operand" "=r")
1978         (ashift:DI
1979          (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1980                  (const_int 2147483647))
1981          (minus:DI (const_int 64)
1982                     (ashift:DI
1983                      (and:DI
1984                       (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1985                       (const_int 7))
1986                      (const_int 3)))))]
1987   "! WORDS_BIG_ENDIAN"
1988   "extlh %r1,%2,%0"
1989   [(set_attr "type" "shift")])
1990
1991 (define_insn "extlh_be"
1992   [(set (match_operand:DI 0 "register_operand" "=r")
1993         (and:DI
1994           (ashift:DI
1995             (match_operand:DI 1 "reg_or_0_operand" "rJ")
1996             (ashift:DI
1997               (and:DI
1998                 (plus:DI
1999                   (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2000                   (const_int 1))
2001                 (const_int 7))
2002               (const_int 3)))
2003           (const_int 2147483647)))]
2004   "WORDS_BIG_ENDIAN"
2005   "extlh %r1,%2,%0"
2006   [(set_attr "type" "shift")])
2007
2008 (define_insn "extwh_le"
2009   [(set (match_operand:DI 0 "register_operand" "=r")
2010         (ashift:DI
2011          (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2012                  (const_int 65535))
2013          (minus:DI (const_int 64)
2014                     (ashift:DI
2015                      (and:DI
2016                       (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2017                       (const_int 7))
2018                      (const_int 3)))))]
2019   "! WORDS_BIG_ENDIAN"
2020   "extwh %r1,%2,%0"
2021   [(set_attr "type" "shift")])
2022
2023 (define_insn "extwh_be"
2024   [(set (match_operand:DI 0 "register_operand" "=r")
2025         (and:DI
2026           (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2027                      (ashift:DI
2028                        (and:DI
2029                          (plus:DI
2030                            (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2031                            (const_int 1))
2032                          (const_int 7))
2033                        (const_int 3)))
2034           (const_int 65535)))]
2035   "WORDS_BIG_ENDIAN"
2036   "extwh %r1,%2,%0"
2037   [(set_attr "type" "shift")])
2038
2039 ;; This converts an extXl into an extXh with an appropriate adjustment
2040 ;; to the address calculation.
2041
2042 ;;(define_split
2043 ;;  [(set (match_operand:DI 0 "register_operand" "")
2044 ;;      (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
2045 ;;                                  (match_operand:DI 2 "mode_width_operand" "")
2046 ;;                                  (ashift:DI (match_operand:DI 3 "" "")
2047 ;;                                             (const_int 3)))
2048 ;;                 (match_operand:DI 4 "const_int_operand" "")))
2049 ;;   (clobber (match_operand:DI 5 "register_operand" ""))]
2050 ;;  "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
2051 ;;  [(set (match_dup 5) (match_dup 6))
2052 ;;   (set (match_dup 0)
2053 ;;      (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
2054 ;;                                  (ashift:DI (plus:DI (match_dup 5)
2055 ;;                                                      (match_dup 7))
2056 ;;                                             (const_int 3)))
2057 ;;                 (match_dup 4)))]
2058 ;;  "
2059 ;;{
2060 ;;  operands[6] = plus_constant (operands[3],
2061 ;;                             INTVAL (operands[2]) / BITS_PER_UNIT);
2062 ;;  operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
2063 ;;}")
2064
2065 (define_insn "*insbl_const"
2066   [(set (match_operand:DI 0 "register_operand" "=r")
2067         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2068                    (match_operand:DI 2 "mul8_operand" "I")))]
2069   ""
2070   "insbl %1,%s2,%0"
2071   [(set_attr "type" "shift")])
2072
2073 (define_insn "*inswl_const"
2074   [(set (match_operand:DI 0 "register_operand" "=r")
2075         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
2076                    (match_operand:DI 2 "mul8_operand" "I")))]
2077   ""
2078   "inswl %1,%s2,%0"
2079   [(set_attr "type" "shift")])
2080
2081 (define_insn "*insll_const"
2082   [(set (match_operand:DI 0 "register_operand" "=r")
2083         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
2084                    (match_operand:DI 2 "mul8_operand" "I")))]
2085   ""
2086   "insll %1,%s2,%0"
2087   [(set_attr "type" "shift")])
2088
2089 (define_insn "insbl_le"
2090   [(set (match_operand:DI 0 "register_operand" "=r")
2091         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2092                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2093                               (const_int 3))))]
2094   "! WORDS_BIG_ENDIAN"
2095   "insbl %1,%2,%0"
2096   [(set_attr "type" "shift")])
2097
2098 (define_insn "insbl_be"
2099  [(set (match_operand:DI 0 "register_operand" "=r")
2100        (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2101          (minus:DI (const_int 56)
2102            (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2103                       (const_int 3)))))]
2104   "WORDS_BIG_ENDIAN"
2105   "insbl %1,%2,%0"
2106   [(set_attr "type" "shift")])
2107
2108 (define_insn "inswl_le"
2109   [(set (match_operand:DI 0 "register_operand" "=r")
2110         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
2111                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2112                               (const_int 3))))]
2113   "! WORDS_BIG_ENDIAN"
2114   "inswl %1,%2,%0"
2115   [(set_attr "type" "shift")])
2116
2117 (define_insn "inswl_be"
2118   [(set (match_operand:DI 0 "register_operand" "=r")
2119         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
2120           (minus:DI (const_int 56)
2121             (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2122                        (const_int 3)))))]
2123   "WORDS_BIG_ENDIAN"
2124   "inswl %1,%2,%0"
2125   [(set_attr "type" "shift")])
2126
2127 (define_insn "insll_le"
2128   [(set (match_operand:DI 0 "register_operand" "=r")
2129         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
2130                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2131                               (const_int 3))))]
2132   "! WORDS_BIG_ENDIAN"
2133   "insll %1,%2,%0"
2134   [(set_attr "type" "shift")])
2135
2136 (define_insn "insll_be"
2137   [(set (match_operand:DI 0 "register_operand" "=r")
2138         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
2139           (minus:DI (const_int 56)
2140             (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2141                        (const_int 3)))))]
2142   "WORDS_BIG_ENDIAN"
2143   "insll %1,%2,%0"
2144   [(set_attr "type" "shift")])
2145
2146 (define_insn "insql_le"
2147   [(set (match_operand:DI 0 "register_operand" "=r")
2148         (ashift:DI (match_operand:DI 1 "register_operand" "r")
2149                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2150                               (const_int 3))))]
2151   "! WORDS_BIG_ENDIAN"
2152   "insql %1,%2,%0"
2153   [(set_attr "type" "shift")])
2154
2155 (define_insn "insql_be"
2156   [(set (match_operand:DI 0 "register_operand" "=r")
2157         (ashift:DI (match_operand:DI 1 "register_operand" "r")
2158           (minus:DI (const_int 56)
2159             (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2160                        (const_int 3)))))]
2161   "WORDS_BIG_ENDIAN"
2162   "insql %1,%2,%0"
2163   [(set_attr "type" "shift")])
2164
2165 ;; Combine has this sometimes habit of moving the and outside of the
2166 ;; shift, making life more interesting.
2167
2168 (define_insn "*insxl"
2169   [(set (match_operand:DI 0 "register_operand" "=r")
2170         (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
2171                            (match_operand:DI 2 "mul8_operand" "I"))
2172                 (match_operand:DI 3 "immediate_operand" "i")))]
2173   "HOST_BITS_PER_WIDE_INT == 64
2174    && GET_CODE (operands[3]) == CONST_INT
2175    && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
2176         == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2177        || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
2178         == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2179        || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
2180         == (unsigned HOST_WIDE_INT) INTVAL (operands[3])))"
2181 {
2182 #if HOST_BITS_PER_WIDE_INT == 64
2183   if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
2184       == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2185     return "insbl %1,%s2,%0";
2186   if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
2187       == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2188     return "inswl %1,%s2,%0";
2189   if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
2190       == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2191     return "insll %1,%s2,%0";
2192 #endif
2193   abort();
2194 }
2195   [(set_attr "type" "shift")])
2196
2197 ;; We do not include the insXh insns because they are complex to express
2198 ;; and it does not appear that we would ever want to generate them.
2199 ;;
2200 ;; Since we need them for block moves, though, cop out and use unspec.
2201
2202 (define_insn "insxh"
2203   [(set (match_operand:DI 0 "register_operand" "=r")
2204         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
2205                     (match_operand:DI 2 "mode_width_operand" "n")
2206                     (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
2207                    UNSPEC_INSXH))]
2208   ""
2209   "ins%M2h %1,%3,%0"
2210   [(set_attr "type" "shift")])
2211
2212 (define_insn "mskxl_le"
2213   [(set (match_operand:DI 0 "register_operand" "=r")
2214         (and:DI (not:DI (ashift:DI
2215                          (match_operand:DI 2 "mode_mask_operand" "n")
2216                          (ashift:DI
2217                           (match_operand:DI 3 "reg_or_8bit_operand" "rI")
2218                           (const_int 3))))
2219                 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
2220   "! WORDS_BIG_ENDIAN"
2221   "msk%U2l %r1,%3,%0"
2222   [(set_attr "type" "shift")])
2223
2224 (define_insn "mskxl_be"
2225   [(set (match_operand:DI 0 "register_operand" "=r")
2226         (and:DI (not:DI (ashift:DI
2227                           (match_operand:DI 2 "mode_mask_operand" "n")
2228                           (minus:DI (const_int 56)
2229                             (ashift:DI
2230                               (match_operand:DI 3 "reg_or_8bit_operand" "rI")
2231                               (const_int 3)))))
2232                 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
2233   "WORDS_BIG_ENDIAN"
2234   "msk%U2l %r1,%3,%0"
2235   [(set_attr "type" "shift")])
2236
2237 ;; We do not include the mskXh insns because it does not appear we would
2238 ;; ever generate one.
2239 ;;
2240 ;; Again, we do for block moves and we use unspec again.
2241
2242 (define_insn "mskxh"
2243   [(set (match_operand:DI 0 "register_operand" "=r")
2244         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
2245                     (match_operand:DI 2 "mode_width_operand" "n")
2246                     (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
2247                    UNSPEC_MSKXH))]
2248   ""
2249   "msk%M2h %1,%3,%0"
2250   [(set_attr "type" "shift")])
2251
2252 ;; Prefer AND + NE over LSHIFTRT + AND.
2253
2254 (define_insn_and_split "*ze_and_ne"
2255   [(set (match_operand:DI 0 "register_operand" "=r")
2256         (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2257                          (const_int 1)
2258                          (match_operand 2 "const_int_operand" "I")))]
2259   "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
2260   "#"
2261   "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
2262   [(set (match_dup 0)
2263         (and:DI (match_dup 1) (match_dup 3)))
2264    (set (match_dup 0)
2265         (ne:DI (match_dup 0) (const_int 0)))]
2266   "operands[3] = GEN_INT (1 << INTVAL (operands[2]));")
2267 \f
2268 ;; Floating-point operations.  All the double-precision insns can extend
2269 ;; from single, so indicate that.  The exception are the ones that simply
2270 ;; play with the sign bits; it's not clear what to do there.
2271
2272 (define_insn "abssf2"
2273   [(set (match_operand:SF 0 "register_operand" "=f")
2274         (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2275   "TARGET_FP"
2276   "cpys $f31,%R1,%0"
2277   [(set_attr "type" "fcpys")])
2278
2279 (define_insn "*nabssf2"
2280   [(set (match_operand:SF 0 "register_operand" "=f")
2281         (neg:SF (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
2282   "TARGET_FP"
2283   "cpysn $f31,%R1,%0"
2284   [(set_attr "type" "fadd")])
2285
2286 (define_insn "absdf2"
2287   [(set (match_operand:DF 0 "register_operand" "=f")
2288         (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2289   "TARGET_FP"
2290   "cpys $f31,%R1,%0"
2291   [(set_attr "type" "fcpys")])
2292
2293 (define_insn "*nabsdf2"
2294   [(set (match_operand:DF 0 "register_operand" "=f")
2295         (neg:DF (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG"))))]
2296   "TARGET_FP"
2297   "cpysn $f31,%R1,%0"
2298   [(set_attr "type" "fadd")])
2299
2300 (define_expand "abstf2"
2301   [(parallel [(set (match_operand:TF 0 "register_operand" "")
2302                    (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
2303               (use (match_dup 2))])]
2304   "TARGET_HAS_XFLOATING_LIBS"
2305 {
2306 #if HOST_BITS_PER_WIDE_INT >= 64
2307   operands[2] = force_reg (DImode, GEN_INT (0x8000000000000000));
2308 #else
2309   operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
2310 #endif
2311 })
2312
2313 (define_insn_and_split "*abstf_internal"
2314   [(set (match_operand:TF 0 "register_operand" "=r")
2315         (abs:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
2316    (use (match_operand:DI 2 "register_operand" "r"))]
2317   "TARGET_HAS_XFLOATING_LIBS"
2318   "#"
2319   "&& reload_completed"
2320   [(const_int 0)]
2321   "alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
2322
2323 (define_insn "negsf2"
2324   [(set (match_operand:SF 0 "register_operand" "=f")
2325         (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2326   "TARGET_FP"
2327   "cpysn %R1,%R1,%0"
2328   [(set_attr "type" "fadd")])
2329
2330 (define_insn "negdf2"
2331   [(set (match_operand:DF 0 "register_operand" "=f")
2332         (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2333   "TARGET_FP"
2334   "cpysn %R1,%R1,%0"
2335   [(set_attr "type" "fadd")])
2336
2337 (define_expand "negtf2"
2338   [(parallel [(set (match_operand:TF 0 "register_operand" "")
2339                    (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
2340               (use (match_dup 2))])]
2341   "TARGET_HAS_XFLOATING_LIBS"
2342 {
2343 #if HOST_BITS_PER_WIDE_INT >= 64
2344   operands[2] = force_reg (DImode, GEN_INT (0x8000000000000000));
2345 #else
2346   operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
2347 #endif
2348 })
2349
2350 (define_insn_and_split "*negtf_internal"
2351   [(set (match_operand:TF 0 "register_operand" "=r")
2352         (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
2353    (use (match_operand:DI 2 "register_operand" "r"))]
2354   "TARGET_HAS_XFLOATING_LIBS"
2355   "#"
2356   "&& reload_completed"
2357   [(const_int 0)]
2358   "alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
2359
2360 (define_insn "*addsf_ieee"
2361   [(set (match_operand:SF 0 "register_operand" "=&f")
2362         (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2363                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2364   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2365   "add%,%/ %R1,%R2,%0"
2366   [(set_attr "type" "fadd")
2367    (set_attr "trap" "yes")
2368    (set_attr "round_suffix" "normal")
2369    (set_attr "trap_suffix" "u_su_sui")])
2370
2371 (define_insn "addsf3"
2372   [(set (match_operand:SF 0 "register_operand" "=f")
2373         (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2374                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2375   "TARGET_FP"
2376   "add%,%/ %R1,%R2,%0"
2377   [(set_attr "type" "fadd")
2378    (set_attr "trap" "yes")
2379    (set_attr "round_suffix" "normal")
2380    (set_attr "trap_suffix" "u_su_sui")])
2381
2382 (define_insn "*adddf_ieee"
2383   [(set (match_operand:DF 0 "register_operand" "=&f")
2384         (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2385                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2386   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2387   "add%-%/ %R1,%R2,%0"
2388   [(set_attr "type" "fadd")
2389    (set_attr "trap" "yes")
2390    (set_attr "round_suffix" "normal")
2391    (set_attr "trap_suffix" "u_su_sui")])
2392
2393 (define_insn "adddf3"
2394   [(set (match_operand:DF 0 "register_operand" "=f")
2395         (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2396                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2397   "TARGET_FP"
2398   "add%-%/ %R1,%R2,%0"
2399   [(set_attr "type" "fadd")
2400    (set_attr "trap" "yes")
2401    (set_attr "round_suffix" "normal")
2402    (set_attr "trap_suffix" "u_su_sui")])
2403
2404 (define_insn "*adddf_ext1"
2405   [(set (match_operand:DF 0 "register_operand" "=f")
2406         (plus:DF (float_extend:DF
2407                   (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2408                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2409   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2410   "add%-%/ %R1,%R2,%0"
2411   [(set_attr "type" "fadd")
2412    (set_attr "trap" "yes")
2413    (set_attr "round_suffix" "normal")
2414    (set_attr "trap_suffix" "u_su_sui")])
2415
2416 (define_insn "*adddf_ext2"
2417   [(set (match_operand:DF 0 "register_operand" "=f")
2418         (plus:DF (float_extend:DF
2419                   (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
2420                  (float_extend:DF
2421                   (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2422   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2423   "add%-%/ %R1,%R2,%0"
2424   [(set_attr "type" "fadd")
2425    (set_attr "trap" "yes")
2426    (set_attr "round_suffix" "normal")
2427    (set_attr "trap_suffix" "u_su_sui")])
2428
2429 (define_expand "addtf3"
2430   [(use (match_operand 0 "register_operand" ""))
2431    (use (match_operand 1 "general_operand" ""))
2432    (use (match_operand 2 "general_operand" ""))]
2433   "TARGET_HAS_XFLOATING_LIBS"
2434   "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
2435
2436 ;; Define conversion operators between DFmode and SImode, using the cvtql
2437 ;; instruction.  To allow combine et al to do useful things, we keep the
2438 ;; operation as a unit until after reload, at which point we split the
2439 ;; instructions.
2440 ;;
2441 ;; Note that we (attempt to) only consider this optimization when the
2442 ;; ultimate destination is memory.  If we will be doing further integer
2443 ;; processing, it is cheaper to do the truncation in the int regs.
2444
2445 (define_insn "*cvtql"
2446   [(set (match_operand:SI 0 "register_operand" "=f")
2447         (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")]
2448                    UNSPEC_CVTQL))]
2449   "TARGET_FP"
2450   "cvtql%/ %R1,%0"
2451   [(set_attr "type" "fadd")
2452    (set_attr "trap" "yes")
2453    (set_attr "trap_suffix" "v_sv")])
2454
2455 (define_insn_and_split "*fix_truncdfsi_ieee"
2456   [(set (match_operand:SI 0 "memory_operand" "=m")
2457         (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
2458    (clobber (match_scratch:DI 2 "=&f"))
2459    (clobber (match_scratch:SI 3 "=&f"))]
2460   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2461   "#"
2462   "&& reload_completed"
2463   [(set (match_dup 2) (fix:DI (match_dup 1)))
2464    (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
2465    (set (match_dup 0) (match_dup 3))]
2466   ""
2467   [(set_attr "type" "fadd")
2468    (set_attr "trap" "yes")])
2469
2470 (define_insn_and_split "*fix_truncdfsi_internal"
2471   [(set (match_operand:SI 0 "memory_operand" "=m")
2472         (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
2473    (clobber (match_scratch:DI 2 "=f"))]
2474   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2475   "#"
2476   "&& reload_completed"
2477   [(set (match_dup 2) (fix:DI (match_dup 1)))
2478    (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
2479    (set (match_dup 0) (match_dup 3))]
2480   ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
2481   "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
2482   [(set_attr "type" "fadd")
2483    (set_attr "trap" "yes")])
2484
2485 (define_insn "*fix_truncdfdi_ieee"
2486   [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2487         (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2488   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2489   "cvt%-q%/ %R1,%0"
2490   [(set_attr "type" "fadd")
2491    (set_attr "trap" "yes")
2492    (set_attr "round_suffix" "c")
2493    (set_attr "trap_suffix" "v_sv_svi")])
2494
2495 (define_insn "fix_truncdfdi2"
2496   [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2497         (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2498   "TARGET_FP"
2499   "cvt%-q%/ %R1,%0"
2500   [(set_attr "type" "fadd")
2501    (set_attr "trap" "yes")
2502    (set_attr "round_suffix" "c")
2503    (set_attr "trap_suffix" "v_sv_svi")])
2504
2505 ;; Likewise between SFmode and SImode.
2506
2507 (define_insn_and_split "*fix_truncsfsi_ieee"
2508   [(set (match_operand:SI 0 "memory_operand" "=m")
2509         (subreg:SI (fix:DI (float_extend:DF
2510                  (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
2511    (clobber (match_scratch:DI 2 "=&f"))
2512    (clobber (match_scratch:SI 3 "=&f"))]
2513   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2514   "#"
2515   "&& reload_completed"
2516   [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
2517    (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
2518    (set (match_dup 0) (match_dup 3))]
2519   ""
2520   [(set_attr "type" "fadd")
2521    (set_attr "trap" "yes")])
2522
2523 (define_insn_and_split "*fix_truncsfsi_internal"
2524   [(set (match_operand:SI 0 "memory_operand" "=m")
2525         (subreg:SI (fix:DI (float_extend:DF
2526                  (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
2527    (clobber (match_scratch:DI 2 "=f"))]
2528   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2529   "#"
2530   "&& reload_completed"
2531   [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
2532    (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
2533    (set (match_dup 0) (match_dup 3))]
2534   ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
2535   "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
2536   [(set_attr "type" "fadd")
2537    (set_attr "trap" "yes")])
2538
2539 (define_insn "*fix_truncsfdi_ieee"
2540   [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2541         (fix:DI (float_extend:DF
2542                  (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
2543   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2544   "cvt%-q%/ %R1,%0"
2545   [(set_attr "type" "fadd")
2546    (set_attr "trap" "yes")
2547    (set_attr "round_suffix" "c")
2548    (set_attr "trap_suffix" "v_sv_svi")])
2549
2550 (define_insn "fix_truncsfdi2"
2551   [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2552         (fix:DI (float_extend:DF
2553                  (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
2554   "TARGET_FP"
2555   "cvt%-q%/ %R1,%0"
2556   [(set_attr "type" "fadd")
2557    (set_attr "trap" "yes")
2558    (set_attr "round_suffix" "c")
2559    (set_attr "trap_suffix" "v_sv_svi")])
2560
2561 (define_expand "fix_trunctfdi2"
2562   [(use (match_operand:DI 0 "register_operand" ""))
2563    (use (match_operand:TF 1 "general_operand" ""))]
2564   "TARGET_HAS_XFLOATING_LIBS"
2565   "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
2566
2567 (define_insn "*floatdisf_ieee"
2568   [(set (match_operand:SF 0 "register_operand" "=&f")
2569         (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2570   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2571   "cvtq%,%/ %1,%0"
2572   [(set_attr "type" "fadd")
2573    (set_attr "trap" "yes")
2574    (set_attr "round_suffix" "normal")
2575    (set_attr "trap_suffix" "sui")])
2576
2577 (define_insn "floatdisf2"
2578   [(set (match_operand:SF 0 "register_operand" "=f")
2579         (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2580   "TARGET_FP"
2581   "cvtq%,%/ %1,%0"
2582   [(set_attr "type" "fadd")
2583    (set_attr "trap" "yes")
2584    (set_attr "round_suffix" "normal")
2585    (set_attr "trap_suffix" "sui")])
2586
2587 (define_insn "*floatdidf_ieee"
2588   [(set (match_operand:DF 0 "register_operand" "=&f")
2589         (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2590   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2591   "cvtq%-%/ %1,%0"
2592   [(set_attr "type" "fadd")
2593    (set_attr "trap" "yes")
2594    (set_attr "round_suffix" "normal")
2595    (set_attr "trap_suffix" "sui")])
2596
2597 (define_insn "floatdidf2"
2598   [(set (match_operand:DF 0 "register_operand" "=f")
2599         (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2600   "TARGET_FP"
2601   "cvtq%-%/ %1,%0"
2602   [(set_attr "type" "fadd")
2603    (set_attr "trap" "yes")
2604    (set_attr "round_suffix" "normal")
2605    (set_attr "trap_suffix" "sui")])
2606
2607 (define_expand "floatditf2"
2608   [(use (match_operand:TF 0 "register_operand" ""))
2609    (use (match_operand:DI 1 "general_operand" ""))]
2610   "TARGET_HAS_XFLOATING_LIBS"
2611   "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
2612
2613 (define_expand "floatunsdisf2"
2614   [(use (match_operand:SF 0 "register_operand" ""))
2615    (use (match_operand:DI 1 "register_operand" ""))]
2616   "TARGET_FP"
2617   "alpha_emit_floatuns (operands); DONE;")
2618
2619 (define_expand "floatunsdidf2"
2620   [(use (match_operand:DF 0 "register_operand" ""))
2621    (use (match_operand:DI 1 "register_operand" ""))]
2622   "TARGET_FP"
2623   "alpha_emit_floatuns (operands); DONE;")
2624
2625 (define_expand "floatunsditf2"
2626   [(use (match_operand:TF 0 "register_operand" ""))
2627    (use (match_operand:DI 1 "general_operand" ""))]
2628   "TARGET_HAS_XFLOATING_LIBS"
2629   "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
2630
2631 (define_expand "extendsfdf2"
2632   [(set (match_operand:DF 0 "register_operand" "")
2633         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
2634   "TARGET_FP"
2635 {
2636   if (alpha_fptm >= ALPHA_FPTM_SU)
2637     operands[1] = force_reg (SFmode, operands[1]);
2638 })
2639
2640 ;; The Unicos/Mk assembler doesn't support cvtst, but we've already
2641 ;; asserted that alpha_fptm == ALPHA_FPTM_N.
2642
2643 (define_insn "*extendsfdf2_ieee"
2644   [(set (match_operand:DF 0 "register_operand" "=&f")
2645         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2646   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2647   "cvtsts %1,%0"
2648   [(set_attr "type" "fadd")
2649    (set_attr "trap" "yes")])
2650
2651 (define_insn "*extendsfdf2_internal"
2652   [(set (match_operand:DF 0 "register_operand" "=f,f,m")
2653         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
2654   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2655   "@
2656    cpys %1,%1,%0
2657    ld%, %0,%1
2658    st%- %1,%0"
2659   [(set_attr "type" "fcpys,fld,fst")])
2660
2661 (define_expand "extendsftf2"
2662   [(use (match_operand:TF 0 "register_operand" ""))
2663    (use (match_operand:SF 1 "general_operand" ""))]
2664   "TARGET_HAS_XFLOATING_LIBS"
2665 {
2666   rtx tmp = gen_reg_rtx (DFmode);
2667   emit_insn (gen_extendsfdf2 (tmp, operands[1]));
2668   emit_insn (gen_extenddftf2 (operands[0], tmp));
2669   DONE;
2670 })
2671
2672 (define_expand "extenddftf2"
2673   [(use (match_operand:TF 0 "register_operand" ""))
2674    (use (match_operand:DF 1 "general_operand" ""))]
2675   "TARGET_HAS_XFLOATING_LIBS"
2676   "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
2677
2678 (define_insn "*truncdfsf2_ieee"
2679   [(set (match_operand:SF 0 "register_operand" "=&f")
2680         (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2681   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2682   "cvt%-%,%/ %R1,%0"
2683   [(set_attr "type" "fadd")
2684    (set_attr "trap" "yes")
2685    (set_attr "round_suffix" "normal")
2686    (set_attr "trap_suffix" "u_su_sui")])
2687
2688 (define_insn "truncdfsf2"
2689   [(set (match_operand:SF 0 "register_operand" "=f")
2690         (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2691   "TARGET_FP"
2692   "cvt%-%,%/ %R1,%0"
2693   [(set_attr "type" "fadd")
2694    (set_attr "trap" "yes")
2695    (set_attr "round_suffix" "normal")
2696    (set_attr "trap_suffix" "u_su_sui")])
2697
2698 (define_expand "trunctfdf2"
2699   [(use (match_operand:DF 0 "register_operand" ""))
2700    (use (match_operand:TF 1 "general_operand" ""))]
2701   "TARGET_HAS_XFLOATING_LIBS"
2702   "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
2703
2704 (define_expand "trunctfsf2"
2705   [(use (match_operand:SF 0 "register_operand" ""))
2706    (use (match_operand:TF 1 "general_operand" ""))]
2707   "TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
2708 {
2709   rtx tmpf, sticky, arg, lo, hi;
2710
2711   tmpf = gen_reg_rtx (DFmode);
2712   sticky = gen_reg_rtx (DImode);
2713   arg = copy_to_mode_reg (TFmode, operands[1]);
2714   lo = gen_lowpart (DImode, arg);
2715   hi = gen_highpart (DImode, arg);
2716
2717   /* Convert the low word of the TFmode value into a sticky rounding bit,
2718      then or it into the low bit of the high word.  This leaves the sticky
2719      bit at bit 48 of the fraction, which is representable in DFmode,
2720      which prevents rounding error in the final conversion to SFmode.  */
2721
2722   emit_insn (gen_rtx_SET (VOIDmode, sticky,
2723                           gen_rtx_NE (DImode, lo, const0_rtx)));
2724   emit_insn (gen_iordi3 (hi, hi, sticky));
2725   emit_insn (gen_trunctfdf2 (tmpf, arg));
2726   emit_insn (gen_truncdfsf2 (operands[0], tmpf));
2727   DONE;
2728 })
2729
2730 (define_insn "*divsf3_ieee"
2731   [(set (match_operand:SF 0 "register_operand" "=&f")
2732         (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2733                 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2734   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2735   "div%,%/ %R1,%R2,%0"
2736   [(set_attr "type" "fdiv")
2737    (set_attr "opsize" "si")
2738    (set_attr "trap" "yes")
2739    (set_attr "round_suffix" "normal")
2740    (set_attr "trap_suffix" "u_su_sui")])
2741
2742 (define_insn "divsf3"
2743   [(set (match_operand:SF 0 "register_operand" "=f")
2744         (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2745                 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2746   "TARGET_FP"
2747   "div%,%/ %R1,%R2,%0"
2748   [(set_attr "type" "fdiv")
2749    (set_attr "opsize" "si")
2750    (set_attr "trap" "yes")
2751    (set_attr "round_suffix" "normal")
2752    (set_attr "trap_suffix" "u_su_sui")])
2753
2754 (define_insn "*divdf3_ieee"
2755   [(set (match_operand:DF 0 "register_operand" "=&f")
2756         (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2757                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2758   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2759   "div%-%/ %R1,%R2,%0"
2760   [(set_attr "type" "fdiv")
2761    (set_attr "trap" "yes")
2762    (set_attr "round_suffix" "normal")
2763    (set_attr "trap_suffix" "u_su_sui")])
2764
2765 (define_insn "divdf3"
2766   [(set (match_operand:DF 0 "register_operand" "=f")
2767         (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2768                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2769   "TARGET_FP"
2770   "div%-%/ %R1,%R2,%0"
2771   [(set_attr "type" "fdiv")
2772    (set_attr "trap" "yes")
2773    (set_attr "round_suffix" "normal")
2774    (set_attr "trap_suffix" "u_su_sui")])
2775
2776 (define_insn "*divdf_ext1"
2777   [(set (match_operand:DF 0 "register_operand" "=f")
2778         (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2779                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2780   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2781   "div%-%/ %R1,%R2,%0"
2782   [(set_attr "type" "fdiv")
2783    (set_attr "trap" "yes")
2784    (set_attr "round_suffix" "normal")
2785    (set_attr "trap_suffix" "u_su_sui")])
2786
2787 (define_insn "*divdf_ext2"
2788   [(set (match_operand:DF 0 "register_operand" "=f")
2789         (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2790                 (float_extend:DF
2791                  (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2792   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2793   "div%-%/ %R1,%R2,%0"
2794   [(set_attr "type" "fdiv")
2795    (set_attr "trap" "yes")
2796    (set_attr "round_suffix" "normal")
2797    (set_attr "trap_suffix" "u_su_sui")])
2798
2799 (define_insn "*divdf_ext3"
2800   [(set (match_operand:DF 0 "register_operand" "=f")
2801         (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2802                 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2803   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2804   "div%-%/ %R1,%R2,%0"
2805   [(set_attr "type" "fdiv")
2806    (set_attr "trap" "yes")
2807    (set_attr "round_suffix" "normal")
2808    (set_attr "trap_suffix" "u_su_sui")])
2809
2810 (define_expand "divtf3"
2811   [(use (match_operand 0 "register_operand" ""))
2812    (use (match_operand 1 "general_operand" ""))
2813    (use (match_operand 2 "general_operand" ""))]
2814   "TARGET_HAS_XFLOATING_LIBS"
2815   "alpha_emit_xfloating_arith (DIV, operands); DONE;")
2816
2817 (define_insn "*mulsf3_ieee"
2818   [(set (match_operand:SF 0 "register_operand" "=&f")
2819         (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2820                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2821   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2822   "mul%,%/ %R1,%R2,%0"
2823   [(set_attr "type" "fmul")
2824    (set_attr "trap" "yes")
2825    (set_attr "round_suffix" "normal")
2826    (set_attr "trap_suffix" "u_su_sui")])
2827
2828 (define_insn "mulsf3"
2829   [(set (match_operand:SF 0 "register_operand" "=f")
2830         (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2831                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2832   "TARGET_FP"
2833   "mul%,%/ %R1,%R2,%0"
2834   [(set_attr "type" "fmul")
2835    (set_attr "trap" "yes")
2836    (set_attr "round_suffix" "normal")
2837    (set_attr "trap_suffix" "u_su_sui")])
2838
2839 (define_insn "*muldf3_ieee"
2840   [(set (match_operand:DF 0 "register_operand" "=&f")
2841         (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2842                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2843   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2844   "mul%-%/ %R1,%R2,%0"
2845   [(set_attr "type" "fmul")
2846    (set_attr "trap" "yes")
2847    (set_attr "round_suffix" "normal")
2848    (set_attr "trap_suffix" "u_su_sui")])
2849
2850 (define_insn "muldf3"
2851   [(set (match_operand:DF 0 "register_operand" "=f")
2852         (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2853                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2854   "TARGET_FP"
2855   "mul%-%/ %R1,%R2,%0"
2856   [(set_attr "type" "fmul")
2857    (set_attr "trap" "yes")
2858    (set_attr "round_suffix" "normal")
2859    (set_attr "trap_suffix" "u_su_sui")])
2860
2861 (define_insn "*muldf_ext1"
2862   [(set (match_operand:DF 0 "register_operand" "=f")
2863         (mult:DF (float_extend:DF
2864                   (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2865                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2866   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2867   "mul%-%/ %R1,%R2,%0"
2868   [(set_attr "type" "fmul")
2869    (set_attr "trap" "yes")
2870    (set_attr "round_suffix" "normal")
2871    (set_attr "trap_suffix" "u_su_sui")])
2872
2873 (define_insn "*muldf_ext2"
2874   [(set (match_operand:DF 0 "register_operand" "=f")
2875         (mult:DF (float_extend:DF
2876                   (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
2877                  (float_extend:DF
2878                   (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2879   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2880   "mul%-%/ %R1,%R2,%0"
2881   [(set_attr "type" "fmul")
2882    (set_attr "trap" "yes")
2883    (set_attr "round_suffix" "normal")
2884    (set_attr "trap_suffix" "u_su_sui")])
2885
2886 (define_expand "multf3"
2887   [(use (match_operand 0 "register_operand" ""))
2888    (use (match_operand 1 "general_operand" ""))
2889    (use (match_operand 2 "general_operand" ""))]
2890   "TARGET_HAS_XFLOATING_LIBS"
2891   "alpha_emit_xfloating_arith (MULT, operands); DONE;")
2892
2893 (define_insn "*subsf3_ieee"
2894   [(set (match_operand:SF 0 "register_operand" "=&f")
2895         (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2896                   (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2897   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2898   "sub%,%/ %R1,%R2,%0"
2899   [(set_attr "type" "fadd")
2900    (set_attr "trap" "yes")
2901    (set_attr "round_suffix" "normal")
2902    (set_attr "trap_suffix" "u_su_sui")])
2903
2904 (define_insn "subsf3"
2905   [(set (match_operand:SF 0 "register_operand" "=f")
2906         (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2907                   (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2908   "TARGET_FP"
2909   "sub%,%/ %R1,%R2,%0"
2910   [(set_attr "type" "fadd")
2911    (set_attr "trap" "yes")
2912    (set_attr "round_suffix" "normal")
2913    (set_attr "trap_suffix" "u_su_sui")])
2914
2915 (define_insn "*subdf3_ieee"
2916   [(set (match_operand:DF 0 "register_operand" "=&f")
2917         (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2918                   (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2919   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2920   "sub%-%/ %R1,%R2,%0"
2921   [(set_attr "type" "fadd")
2922    (set_attr "trap" "yes")
2923    (set_attr "round_suffix" "normal")
2924    (set_attr "trap_suffix" "u_su_sui")])
2925
2926 (define_insn "subdf3"
2927   [(set (match_operand:DF 0 "register_operand" "=f")
2928         (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2929                   (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2930   "TARGET_FP"
2931   "sub%-%/ %R1,%R2,%0"
2932   [(set_attr "type" "fadd")
2933    (set_attr "trap" "yes")
2934    (set_attr "round_suffix" "normal")
2935    (set_attr "trap_suffix" "u_su_sui")])
2936
2937 (define_insn "*subdf_ext1"
2938   [(set (match_operand:DF 0 "register_operand" "=f")
2939         (minus:DF (float_extend:DF
2940                    (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2941                   (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2942   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2943   "sub%-%/ %R1,%R2,%0"
2944   [(set_attr "type" "fadd")
2945    (set_attr "trap" "yes")
2946    (set_attr "round_suffix" "normal")
2947    (set_attr "trap_suffix" "u_su_sui")])
2948
2949 (define_insn "*subdf_ext2"
2950   [(set (match_operand:DF 0 "register_operand" "=f")
2951         (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2952                   (float_extend:DF
2953                    (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2954   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2955   "sub%-%/ %R1,%R2,%0"
2956   [(set_attr "type" "fadd")
2957    (set_attr "trap" "yes")
2958    (set_attr "round_suffix" "normal")
2959    (set_attr "trap_suffix" "u_su_sui")])
2960
2961 (define_insn "*subdf_ext3"
2962   [(set (match_operand:DF 0 "register_operand" "=f")
2963         (minus:DF (float_extend:DF
2964                    (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2965                   (float_extend:DF
2966                    (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2967   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2968   "sub%-%/ %R1,%R2,%0"
2969   [(set_attr "type" "fadd")
2970    (set_attr "trap" "yes")
2971    (set_attr "round_suffix" "normal")
2972    (set_attr "trap_suffix" "u_su_sui")])
2973
2974 (define_expand "subtf3"
2975   [(use (match_operand 0 "register_operand" ""))
2976    (use (match_operand 1 "general_operand" ""))
2977    (use (match_operand 2 "general_operand" ""))]
2978   "TARGET_HAS_XFLOATING_LIBS"
2979   "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
2980
2981 (define_insn "*sqrtsf2_ieee"
2982   [(set (match_operand:SF 0 "register_operand" "=&f")
2983         (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2984   "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
2985   "sqrt%,%/ %R1,%0"
2986   [(set_attr "type" "fsqrt")
2987    (set_attr "opsize" "si")
2988    (set_attr "trap" "yes")
2989    (set_attr "round_suffix" "normal")
2990    (set_attr "trap_suffix" "u_su_sui")])
2991
2992 (define_insn "sqrtsf2"
2993   [(set (match_operand:SF 0 "register_operand" "=f")
2994         (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2995   "TARGET_FP && TARGET_FIX"
2996   "sqrt%,%/ %R1,%0"
2997   [(set_attr "type" "fsqrt")
2998    (set_attr "opsize" "si")
2999    (set_attr "trap" "yes")
3000    (set_attr "round_suffix" "normal")
3001    (set_attr "trap_suffix" "u_su_sui")])
3002
3003 (define_insn "*sqrtdf2_ieee"
3004   [(set (match_operand:DF 0 "register_operand" "=&f")
3005         (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
3006   "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
3007   "sqrt%-%/ %R1,%0"
3008   [(set_attr "type" "fsqrt")
3009    (set_attr "trap" "yes")
3010    (set_attr "round_suffix" "normal")
3011    (set_attr "trap_suffix" "u_su_sui")])
3012
3013 (define_insn "sqrtdf2"
3014   [(set (match_operand:DF 0 "register_operand" "=f")
3015         (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
3016   "TARGET_FP && TARGET_FIX"
3017   "sqrt%-%/ %1,%0"
3018   [(set_attr "type" "fsqrt")
3019    (set_attr "trap" "yes")
3020    (set_attr "round_suffix" "normal")
3021    (set_attr "trap_suffix" "u_su_sui")])
3022 \f
3023 ;; Next are all the integer comparisons, and conditional moves and branches
3024 ;; and some of the related define_expand's and define_split's.
3025
3026 (define_insn "*setcc_internal"
3027   [(set (match_operand 0 "register_operand" "=r")
3028         (match_operator 1 "alpha_comparison_operator"
3029                            [(match_operand:DI 2 "register_operand" "r")
3030                             (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
3031   "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
3032    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
3033    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
3034   "cmp%C1 %2,%3,%0"
3035   [(set_attr "type" "icmp")])
3036
3037 ;; Yes, we can technically support reg_or_8bit_operand in operand 2,
3038 ;; but that's non-canonical rtl and allowing that causes inefficiencies
3039 ;; from cse on.
3040 (define_insn "*setcc_swapped_internal"
3041   [(set (match_operand 0 "register_operand" "=r")
3042         (match_operator 1 "alpha_swapped_comparison_operator"
3043                            [(match_operand:DI 2 "register_operand" "r")
3044                             (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
3045   "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
3046    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
3047    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
3048   "cmp%c1 %r3,%2,%0"
3049   [(set_attr "type" "icmp")])
3050
3051 ;; Use match_operator rather than ne directly so that we can match
3052 ;; multiple integer modes.
3053 (define_insn "*setne_internal"
3054   [(set (match_operand 0 "register_operand" "=r")
3055         (match_operator 1 "signed_comparison_operator"
3056                           [(match_operand:DI 2 "register_operand" "r")
3057                            (const_int 0)]))]
3058   "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
3059    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
3060    && GET_CODE (operands[1]) == NE
3061    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
3062   "cmpult $31,%2,%0"
3063   [(set_attr "type" "icmp")])
3064
3065 ;; The mode folding trick can't be used with const_int operands, since
3066 ;; reload needs to know the proper mode.
3067 ;;
3068 ;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
3069 ;; in order to create more pairs of constants.  As long as we're allowing
3070 ;; two constants at the same time, and will have to reload one of them...
3071
3072 (define_insn "*movqicc_internal"
3073   [(set (match_operand:QI 0 "register_operand" "=r,r,r,r")
3074         (if_then_else:QI
3075          (match_operator 2 "signed_comparison_operator"
3076                          [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
3077                           (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
3078          (match_operand:QI 1 "add_operand" "rI,0,rI,0")
3079          (match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
3080   "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
3081   "@
3082    cmov%C2 %r3,%1,%0
3083    cmov%D2 %r3,%5,%0
3084    cmov%c2 %r4,%1,%0
3085    cmov%d2 %r4,%5,%0"
3086   [(set_attr "type" "icmov")])
3087
3088 (define_insn "*movhicc_internal"
3089   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
3090         (if_then_else:HI
3091          (match_operator 2 "signed_comparison_operator"
3092                          [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
3093                           (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
3094          (match_operand:HI 1 "add_operand" "rI,0,rI,0")
3095          (match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
3096   "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
3097   "@
3098    cmov%C2 %r3,%1,%0
3099    cmov%D2 %r3,%5,%0
3100    cmov%c2 %r4,%1,%0
3101    cmov%d2 %r4,%5,%0"
3102   [(set_attr "type" "icmov")])
3103
3104 (define_insn "*movsicc_internal"
3105   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3106         (if_then_else:SI
3107          (match_operator 2 "signed_comparison_operator"
3108                          [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
3109                           (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
3110          (match_operand:SI 1 "add_operand" "rI,0,rI,0")
3111          (match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
3112   "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
3113   "@
3114    cmov%C2 %r3,%1,%0
3115    cmov%D2 %r3,%5,%0
3116    cmov%c2 %r4,%1,%0
3117    cmov%d2 %r4,%5,%0"
3118   [(set_attr "type" "icmov")])
3119
3120 (define_insn "*movdicc_internal"
3121   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
3122         (if_then_else:DI
3123          (match_operator 2 "signed_comparison_operator"
3124                          [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
3125                           (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
3126          (match_operand:DI 1 "add_operand" "rI,0,rI,0")
3127          (match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
3128   "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
3129   "@
3130    cmov%C2 %r3,%1,%0
3131    cmov%D2 %r3,%5,%0
3132    cmov%c2 %r4,%1,%0
3133    cmov%d2 %r4,%5,%0"
3134   [(set_attr "type" "icmov")])
3135
3136 (define_insn "*movqicc_lbc"
3137   [(set (match_operand:QI 0 "register_operand" "=r,r")
3138         (if_then_else:QI
3139          (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3140                               (const_int 1)
3141                               (const_int 0))
3142              (const_int 0))
3143          (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
3144          (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
3145   ""
3146   "@
3147    cmovlbc %r2,%1,%0
3148    cmovlbs %r2,%3,%0"
3149   [(set_attr "type" "icmov")])
3150
3151 (define_insn "*movhicc_lbc"
3152   [(set (match_operand:HI 0 "register_operand" "=r,r")
3153         (if_then_else:HI
3154          (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3155                               (const_int 1)
3156                               (const_int 0))
3157              (const_int 0))
3158          (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
3159          (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
3160   ""
3161   "@
3162    cmovlbc %r2,%1,%0
3163    cmovlbs %r2,%3,%0"
3164   [(set_attr "type" "icmov")])
3165
3166 (define_insn "*movsicc_lbc"
3167   [(set (match_operand:SI 0 "register_operand" "=r,r")
3168         (if_then_else:SI
3169          (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3170                               (const_int 1)
3171                               (const_int 0))
3172              (const_int 0))
3173          (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
3174          (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
3175   ""
3176   "@
3177    cmovlbc %r2,%1,%0
3178    cmovlbs %r2,%3,%0"
3179   [(set_attr "type" "icmov")])
3180
3181 (define_insn "*movdicc_lbc"
3182   [(set (match_operand:DI 0 "register_operand" "=r,r")
3183         (if_then_else:DI
3184          (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3185                               (const_int 1)
3186                               (const_int 0))
3187              (const_int 0))
3188          (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
3189          (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
3190   ""
3191   "@
3192    cmovlbc %r2,%1,%0
3193    cmovlbs %r2,%3,%0"
3194   [(set_attr "type" "icmov")])
3195
3196 (define_insn "*movqicc_lbs"
3197   [(set (match_operand:QI 0 "register_operand" "=r,r")
3198         (if_then_else:QI
3199          (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3200                               (const_int 1)
3201                               (const_int 0))
3202              (const_int 0))
3203          (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
3204          (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
3205   ""
3206   "@
3207    cmovlbs %r2,%1,%0
3208    cmovlbc %r2,%3,%0"
3209   [(set_attr "type" "icmov")])
3210
3211 (define_insn "*movhicc_lbs"
3212   [(set (match_operand:HI 0 "register_operand" "=r,r")
3213         (if_then_else:HI
3214          (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3215                               (const_int 1)
3216                               (const_int 0))
3217              (const_int 0))
3218          (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
3219          (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
3220   ""
3221   "@
3222    cmovlbs %r2,%1,%0
3223    cmovlbc %r2,%3,%0"
3224   [(set_attr "type" "icmov")])
3225
3226 (define_insn "*movsicc_lbs"
3227   [(set (match_operand:SI 0 "register_operand" "=r,r")
3228         (if_then_else:SI
3229          (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3230                               (const_int 1)
3231                               (const_int 0))
3232              (const_int 0))
3233          (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
3234          (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
3235   ""
3236   "@
3237    cmovlbs %r2,%1,%0
3238    cmovlbc %r2,%3,%0"
3239   [(set_attr "type" "icmov")])
3240
3241 (define_insn "*movdicc_lbs"
3242   [(set (match_operand:DI 0 "register_operand" "=r,r")
3243         (if_then_else:DI
3244          (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3245                               (const_int 1)
3246                               (const_int 0))
3247              (const_int 0))
3248          (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
3249          (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
3250   ""
3251   "@
3252    cmovlbs %r2,%1,%0
3253    cmovlbc %r2,%3,%0"
3254   [(set_attr "type" "icmov")])
3255
3256 ;; For ABS, we have two choices, depending on whether the input and output
3257 ;; registers are the same or not.
3258 (define_expand "absdi2"
3259   [(set (match_operand:DI 0 "register_operand" "")
3260         (abs:DI (match_operand:DI 1 "register_operand" "")))]
3261   ""
3262 {
3263   if (rtx_equal_p (operands[0], operands[1]))
3264     emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
3265   else
3266     emit_insn (gen_absdi2_diff (operands[0], operands[1]));
3267   DONE;
3268 })
3269
3270 (define_expand "absdi2_same"
3271   [(set (match_operand:DI 1 "register_operand" "")
3272         (neg:DI (match_operand:DI 0 "register_operand" "")))
3273    (set (match_dup 0)
3274         (if_then_else:DI (ge (match_dup 0) (const_int 0))
3275                          (match_dup 0)
3276                          (match_dup 1)))]
3277   ""
3278   "")
3279
3280 (define_expand "absdi2_diff"
3281   [(set (match_operand:DI 0 "register_operand" "")
3282         (neg:DI (match_operand:DI 1 "register_operand" "")))
3283    (set (match_dup 0)
3284         (if_then_else:DI (lt (match_dup 1) (const_int 0))
3285                          (match_dup 0)
3286                          (match_dup 1)))]
3287   ""
3288   "")
3289
3290 (define_split
3291   [(set (match_operand:DI 0 "register_operand" "")
3292         (abs:DI (match_dup 0)))
3293    (clobber (match_operand:DI 1 "register_operand" ""))]
3294   ""
3295   [(set (match_dup 1) (neg:DI (match_dup 0)))
3296    (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
3297                                        (match_dup 0) (match_dup 1)))]
3298   "")
3299
3300 (define_split
3301   [(set (match_operand:DI 0 "register_operand" "")
3302         (abs:DI (match_operand:DI 1 "register_operand" "")))]
3303   "! rtx_equal_p (operands[0], operands[1])"
3304   [(set (match_dup 0) (neg:DI (match_dup 1)))
3305    (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
3306                                        (match_dup 0) (match_dup 1)))]
3307   "")
3308
3309 (define_split
3310   [(set (match_operand:DI 0 "register_operand" "")
3311         (neg:DI (abs:DI (match_dup 0))))
3312    (clobber (match_operand:DI 1 "register_operand" ""))]
3313   ""
3314   [(set (match_dup 1) (neg:DI (match_dup 0)))
3315    (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
3316                                        (match_dup 0) (match_dup 1)))]
3317   "")
3318
3319 (define_split
3320   [(set (match_operand:DI 0 "register_operand" "")
3321         (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
3322   "! rtx_equal_p (operands[0], operands[1])"
3323   [(set (match_dup 0) (neg:DI (match_dup 1)))
3324    (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
3325                                        (match_dup 0) (match_dup 1)))]
3326   "")
3327
3328 (define_insn "sminqi3"
3329   [(set (match_operand:QI 0 "register_operand" "=r")
3330         (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
3331                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
3332   "TARGET_MAX"
3333   "minsb8 %r1,%2,%0"
3334   [(set_attr "type" "mvi")])
3335
3336 (define_insn "uminqi3"
3337   [(set (match_operand:QI 0 "register_operand" "=r")
3338         (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
3339                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
3340   "TARGET_MAX"
3341   "minub8 %r1,%2,%0"
3342   [(set_attr "type" "mvi")])
3343
3344 (define_insn "smaxqi3"
3345   [(set (match_operand:QI 0 "register_operand" "=r")
3346         (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
3347                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
3348   "TARGET_MAX"
3349   "maxsb8 %r1,%2,%0"
3350   [(set_attr "type" "mvi")])
3351
3352 (define_insn "umaxqi3"
3353   [(set (match_operand:QI 0 "register_operand" "=r")
3354         (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
3355                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
3356   "TARGET_MAX"
3357   "maxub8 %r1,%2,%0"
3358   [(set_attr "type" "mvi")])
3359
3360 (define_insn "sminhi3"
3361   [(set (match_operand:HI 0 "register_operand" "=r")
3362         (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
3363                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
3364   "TARGET_MAX"
3365   "minsw4 %r1,%2,%0"
3366   [(set_attr "type" "mvi")])
3367
3368 (define_insn "uminhi3"
3369   [(set (match_operand:HI 0 "register_operand" "=r")
3370         (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
3371                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
3372   "TARGET_MAX"
3373   "minuw4 %r1,%2,%0"
3374   [(set_attr "type" "mvi")])
3375
3376 (define_insn "smaxhi3"
3377   [(set (match_operand:HI 0 "register_operand" "=r")
3378         (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
3379                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
3380   "TARGET_MAX"
3381   "maxsw4 %r1,%2,%0"
3382   [(set_attr "type" "mvi")])
3383
3384 (define_insn "umaxhi3"
3385   [(set (match_operand:HI 0 "register_operand" "=r")
3386         (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
3387                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
3388   "TARGET_MAX"
3389   "maxuw4 %r1,%2,%0"
3390   [(set_attr "type" "shift")])
3391
3392 (define_expand "smaxdi3"
3393   [(set (match_dup 3)
3394         (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
3395                (match_operand:DI 2 "reg_or_8bit_operand" "")))
3396    (set (match_operand:DI 0 "register_operand" "")
3397         (if_then_else:DI (eq (match_dup 3) (const_int 0))
3398                          (match_dup 1) (match_dup 2)))]
3399   ""
3400   { operands[3] = gen_reg_rtx (DImode); })
3401
3402 (define_split
3403   [(set (match_operand:DI 0 "register_operand" "")
3404         (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
3405                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
3406    (clobber (match_operand:DI 3 "register_operand" ""))]
3407   "operands[2] != const0_rtx"
3408   [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
3409    (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
3410                                        (match_dup 1) (match_dup 2)))]
3411   "")
3412
3413 (define_insn "*smax_const0"
3414   [(set (match_operand:DI 0 "register_operand" "=r")
3415         (smax:DI (match_operand:DI 1 "register_operand" "0")
3416                  (const_int 0)))]
3417   ""
3418   "cmovlt %0,0,%0"
3419   [(set_attr "type" "icmov")])
3420
3421 (define_expand "smindi3"
3422   [(set (match_dup 3)
3423         (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
3424                (match_operand:DI 2 "reg_or_8bit_operand" "")))
3425    (set (match_operand:DI 0 "register_operand" "")
3426         (if_then_else:DI (ne (match_dup 3) (const_int 0))
3427                          (match_dup 1) (match_dup 2)))]
3428   ""
3429   { operands[3] = gen_reg_rtx (DImode); })
3430
3431 (define_split
3432   [(set (match_operand:DI 0 "register_operand" "")
3433         (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
3434                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
3435    (clobber (match_operand:DI 3 "register_operand" ""))]
3436   "operands[2] != const0_rtx"
3437   [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
3438    (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
3439                                        (match_dup 1) (match_dup 2)))]
3440   "")
3441
3442 (define_insn "*smin_const0"
3443   [(set (match_operand:DI 0 "register_operand" "=r")
3444         (smin:DI (match_operand:DI 1 "register_operand" "0")
3445                  (const_int 0)))]
3446   ""
3447   "cmovgt %0,0,%0"
3448   [(set_attr "type" "icmov")])
3449
3450 (define_expand "umaxdi3"
3451   [(set (match_dup 3)
3452         (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
3453                 (match_operand:DI 2 "reg_or_8bit_operand" "")))
3454    (set (match_operand:DI 0 "register_operand" "")
3455         (if_then_else:DI (eq (match_dup 3) (const_int 0))
3456                          (match_dup 1) (match_dup 2)))]
3457   ""
3458   "operands[3] = gen_reg_rtx (DImode);")
3459
3460 (define_split
3461   [(set (match_operand:DI 0 "register_operand" "")
3462         (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
3463                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
3464    (clobber (match_operand:DI 3 "register_operand" ""))]
3465   "operands[2] != const0_rtx"
3466   [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
3467    (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
3468                                        (match_dup 1) (match_dup 2)))]
3469   "")
3470
3471 (define_expand "umindi3"
3472   [(set (match_dup 3)
3473         (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
3474                 (match_operand:DI 2 "reg_or_8bit_operand" "")))
3475    (set (match_operand:DI 0 "register_operand" "")
3476         (if_then_else:DI (ne (match_dup 3) (const_int 0))
3477                          (match_dup 1) (match_dup 2)))]
3478   ""
3479   "operands[3] = gen_reg_rtx (DImode);")
3480
3481 (define_split
3482   [(set (match_operand:DI 0 "register_operand" "")
3483         (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
3484                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
3485    (clobber (match_operand:DI 3 "register_operand" ""))]
3486   "operands[2] != const0_rtx"
3487   [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
3488    (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
3489                                        (match_dup 1) (match_dup 2)))]
3490   "")
3491
3492 (define_insn "*bcc_normal"
3493   [(set (pc)
3494         (if_then_else
3495          (match_operator 1 "signed_comparison_operator"
3496                          [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3497                           (const_int 0)])
3498          (label_ref (match_operand 0 "" ""))
3499          (pc)))]
3500   ""
3501   "b%C1 %r2,%0"
3502   [(set_attr "type" "ibr")])
3503
3504 (define_insn "*bcc_reverse"
3505   [(set (pc)
3506         (if_then_else
3507          (match_operator 1 "signed_comparison_operator"
3508                          [(match_operand:DI 2 "register_operand" "r")
3509                           (const_int 0)])
3510
3511          (pc)
3512          (label_ref (match_operand 0 "" ""))))]
3513   ""
3514   "b%c1 %2,%0"
3515   [(set_attr "type" "ibr")])
3516
3517 (define_insn "*blbs_normal"
3518   [(set (pc)
3519         (if_then_else
3520          (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3521                               (const_int 1)
3522                               (const_int 0))
3523              (const_int 0))
3524          (label_ref (match_operand 0 "" ""))
3525          (pc)))]
3526   ""
3527   "blbs %r1,%0"
3528   [(set_attr "type" "ibr")])
3529
3530 (define_insn "*blbc_normal"
3531   [(set (pc)
3532         (if_then_else
3533          (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3534                               (const_int 1)
3535                               (const_int 0))
3536              (const_int 0))
3537          (label_ref (match_operand 0 "" ""))
3538          (pc)))]
3539   ""
3540   "blbc %r1,%0"
3541   [(set_attr "type" "ibr")])
3542
3543 (define_split
3544   [(parallel
3545     [(set (pc)
3546           (if_then_else
3547            (match_operator 1 "comparison_operator"
3548                            [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
3549                                              (const_int 1)
3550                                              (match_operand:DI 3 "const_int_operand" ""))
3551                             (const_int 0)])
3552            (label_ref (match_operand 0 "" ""))
3553            (pc)))
3554      (clobber (match_operand:DI 4 "register_operand" ""))])]
3555   "INTVAL (operands[3]) != 0"
3556   [(set (match_dup 4)
3557         (lshiftrt:DI (match_dup 2) (match_dup 3)))
3558    (set (pc)
3559         (if_then_else (match_op_dup 1
3560                                     [(zero_extract:DI (match_dup 4)
3561                                                       (const_int 1)
3562                                                       (const_int 0))
3563                                      (const_int 0)])
3564                       (label_ref (match_dup 0))
3565                       (pc)))]
3566   "")
3567 \f
3568 ;; The following are the corresponding floating-point insns.  Recall
3569 ;; we need to have variants that expand the arguments from SFmode
3570 ;; to DFmode.
3571
3572 (define_insn "*cmpdf_ieee"
3573   [(set (match_operand:DF 0 "register_operand" "=&f")
3574         (match_operator:DF 1 "alpha_fp_comparison_operator"
3575                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3576                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3577   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3578   "cmp%-%C1%/ %R2,%R3,%0"
3579   [(set_attr "type" "fadd")
3580    (set_attr "trap" "yes")
3581    (set_attr "trap_suffix" "su")])
3582
3583 (define_insn "*cmpdf_internal"
3584   [(set (match_operand:DF 0 "register_operand" "=f")
3585         (match_operator:DF 1 "alpha_fp_comparison_operator"
3586                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3587                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3588   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3589   "cmp%-%C1%/ %R2,%R3,%0"
3590   [(set_attr "type" "fadd")
3591    (set_attr "trap" "yes")
3592    (set_attr "trap_suffix" "su")])
3593
3594 (define_insn "*cmpdf_ieee_ext1"
3595   [(set (match_operand:DF 0 "register_operand" "=&f")
3596         (match_operator:DF 1 "alpha_fp_comparison_operator"
3597                            [(float_extend:DF
3598                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3599                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3600   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3601   "cmp%-%C1%/ %R2,%R3,%0"
3602   [(set_attr "type" "fadd")
3603    (set_attr "trap" "yes")
3604    (set_attr "trap_suffix" "su")])
3605
3606 (define_insn "*cmpdf_ext1"
3607   [(set (match_operand:DF 0 "register_operand" "=f")
3608         (match_operator:DF 1 "alpha_fp_comparison_operator"
3609                            [(float_extend:DF
3610                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3611                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3612   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3613   "cmp%-%C1%/ %R2,%R3,%0"
3614   [(set_attr "type" "fadd")
3615    (set_attr "trap" "yes")
3616    (set_attr "trap_suffix" "su")])
3617
3618 (define_insn "*cmpdf_ieee_ext2"
3619   [(set (match_operand:DF 0 "register_operand" "=&f")
3620         (match_operator:DF 1 "alpha_fp_comparison_operator"
3621                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3622                             (float_extend:DF
3623                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3624   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3625   "cmp%-%C1%/ %R2,%R3,%0"
3626   [(set_attr "type" "fadd")
3627    (set_attr "trap" "yes")
3628    (set_attr "trap_suffix" "su")])
3629
3630 (define_insn "*cmpdf_ext2"
3631   [(set (match_operand:DF 0 "register_operand" "=f")
3632         (match_operator:DF 1 "alpha_fp_comparison_operator"
3633                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3634                             (float_extend:DF
3635                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3636   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3637   "cmp%-%C1%/ %R2,%R3,%0"
3638   [(set_attr "type" "fadd")
3639    (set_attr "trap" "yes")
3640    (set_attr "trap_suffix" "su")])
3641
3642 (define_insn "*cmpdf_ieee_ext3"
3643   [(set (match_operand:DF 0 "register_operand" "=&f")
3644         (match_operator:DF 1 "alpha_fp_comparison_operator"
3645                            [(float_extend:DF
3646                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3647                             (float_extend:DF
3648                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3649   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3650   "cmp%-%C1%/ %R2,%R3,%0"
3651   [(set_attr "type" "fadd")
3652    (set_attr "trap" "yes")
3653    (set_attr "trap_suffix" "su")])
3654
3655 (define_insn "*cmpdf_ext3"
3656   [(set (match_operand:DF 0 "register_operand" "=f")
3657         (match_operator:DF 1 "alpha_fp_comparison_operator"
3658                            [(float_extend:DF
3659                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3660                             (float_extend:DF
3661                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3662   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3663   "cmp%-%C1%/ %R2,%R3,%0"
3664   [(set_attr "type" "fadd")
3665    (set_attr "trap" "yes")
3666    (set_attr "trap_suffix" "su")])
3667
3668 (define_insn "*movdfcc_internal"
3669   [(set (match_operand:DF 0 "register_operand" "=f,f")
3670         (if_then_else:DF
3671          (match_operator 3 "signed_comparison_operator"
3672                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
3673                           (match_operand:DF 2 "fp0_operand" "G,G")])
3674          (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
3675          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3676   "TARGET_FP"
3677   "@
3678    fcmov%C3 %R4,%R1,%0
3679    fcmov%D3 %R4,%R5,%0"
3680   [(set_attr "type" "fcmov")])
3681
3682 (define_insn "*movsfcc_internal"
3683   [(set (match_operand:SF 0 "register_operand" "=f,f")
3684         (if_then_else:SF
3685          (match_operator 3 "signed_comparison_operator"
3686                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
3687                           (match_operand:DF 2 "fp0_operand" "G,G")])
3688          (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
3689          (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
3690   "TARGET_FP"
3691   "@
3692    fcmov%C3 %R4,%R1,%0
3693    fcmov%D3 %R4,%R5,%0"
3694   [(set_attr "type" "fcmov")])
3695
3696 (define_insn "*movdfcc_ext1"
3697   [(set (match_operand:DF 0 "register_operand" "=f,f")
3698         (if_then_else:DF
3699          (match_operator 3 "signed_comparison_operator"
3700                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
3701                           (match_operand:DF 2 "fp0_operand" "G,G")])
3702          (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
3703          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3704   "TARGET_FP"
3705   "@
3706    fcmov%C3 %R4,%R1,%0
3707    fcmov%D3 %R4,%R5,%0"
3708   [(set_attr "type" "fcmov")])
3709
3710 (define_insn "*movdfcc_ext2"
3711   [(set (match_operand:DF 0 "register_operand" "=f,f")
3712         (if_then_else:DF
3713          (match_operator 3 "signed_comparison_operator"
3714                          [(float_extend:DF
3715                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
3716                           (match_operand:DF 2 "fp0_operand" "G,G")])
3717          (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
3718          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3719   "TARGET_FP"
3720   "@
3721    fcmov%C3 %R4,%R1,%0
3722    fcmov%D3 %R4,%R5,%0"
3723   [(set_attr "type" "fcmov")])
3724
3725 (define_insn "*movdfcc_ext3"
3726   [(set (match_operand:SF 0 "register_operand" "=f,f")
3727         (if_then_else:SF
3728          (match_operator 3 "signed_comparison_operator"
3729                          [(float_extend:DF
3730                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
3731                           (match_operand:DF 2 "fp0_operand" "G,G")])
3732          (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
3733          (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
3734   "TARGET_FP"
3735   "@
3736    fcmov%C3 %R4,%R1,%0
3737    fcmov%D3 %R4,%R5,%0"
3738   [(set_attr "type" "fcmov")])
3739
3740 (define_insn "*movdfcc_ext4"
3741   [(set (match_operand:DF 0 "register_operand" "=f,f")
3742         (if_then_else:DF
3743          (match_operator 3 "signed_comparison_operator"
3744                          [(float_extend:DF
3745                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
3746                           (match_operand:DF 2 "fp0_operand" "G,G")])
3747          (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
3748          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3749   "TARGET_FP"
3750   "@
3751    fcmov%C3 %R4,%R1,%0
3752    fcmov%D3 %R4,%R5,%0"
3753   [(set_attr "type" "fcmov")])
3754
3755 (define_expand "maxdf3"
3756   [(set (match_dup 3)
3757         (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
3758                (match_operand:DF 2 "reg_or_fp0_operand" "")))
3759    (set (match_operand:DF 0 "register_operand" "")
3760         (if_then_else:DF (eq (match_dup 3) (match_dup 4))
3761                          (match_dup 1) (match_dup 2)))]
3762   "TARGET_FP"
3763 {
3764   operands[3] = gen_reg_rtx (DFmode);
3765   operands[4] = CONST0_RTX (DFmode);
3766 })
3767
3768 (define_expand "mindf3"
3769   [(set (match_dup 3)
3770         (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
3771                (match_operand:DF 2 "reg_or_fp0_operand" "")))
3772    (set (match_operand:DF 0 "register_operand" "")
3773         (if_then_else:DF (ne (match_dup 3) (match_dup 4))
3774                          (match_dup 1) (match_dup 2)))]
3775   "TARGET_FP"
3776 {
3777   operands[3] = gen_reg_rtx (DFmode);
3778   operands[4] = CONST0_RTX (DFmode);
3779 })
3780
3781 (define_expand "maxsf3"
3782   [(set (match_dup 3)
3783         (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
3784                (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
3785    (set (match_operand:SF 0 "register_operand" "")
3786         (if_then_else:SF (eq (match_dup 3) (match_dup 4))
3787                          (match_dup 1) (match_dup 2)))]
3788   "TARGET_FP"
3789 {
3790   operands[3] = gen_reg_rtx (DFmode);
3791   operands[4] = CONST0_RTX (DFmode);
3792 })
3793
3794 (define_expand "minsf3"
3795   [(set (match_dup 3)
3796         (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
3797                (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
3798    (set (match_operand:SF 0 "register_operand" "")
3799         (if_then_else:SF (ne (match_dup 3) (match_dup 4))
3800                       (match_dup 1) (match_dup 2)))]
3801   "TARGET_FP"
3802 {
3803   operands[3] = gen_reg_rtx (DFmode);
3804   operands[4] = CONST0_RTX (DFmode);
3805 })
3806
3807 (define_insn "*fbcc_normal"
3808   [(set (pc)
3809         (if_then_else
3810          (match_operator 1 "signed_comparison_operator"
3811                          [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3812                           (match_operand:DF 3 "fp0_operand" "G")])
3813          (label_ref (match_operand 0 "" ""))
3814          (pc)))]
3815   "TARGET_FP"
3816   "fb%C1 %R2,%0"
3817   [(set_attr "type" "fbr")])
3818
3819 (define_insn "*fbcc_ext_normal"
3820   [(set (pc)
3821         (if_then_else
3822          (match_operator 1 "signed_comparison_operator"
3823                          [(float_extend:DF
3824                            (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3825                           (match_operand:DF 3 "fp0_operand" "G")])
3826          (label_ref (match_operand 0 "" ""))
3827          (pc)))]
3828   "TARGET_FP"
3829   "fb%C1 %R2,%0"
3830   [(set_attr "type" "fbr")])
3831 \f
3832 ;; These are the main define_expand's used to make conditional branches
3833 ;; and compares.
3834
3835 (define_expand "cmpdf"
3836   [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
3837                        (match_operand:DF 1 "reg_or_fp0_operand" "")))]
3838   "TARGET_FP"
3839 {
3840   alpha_compare.op0 = operands[0];
3841   alpha_compare.op1 = operands[1];
3842   alpha_compare.fp_p = 1;
3843   DONE;
3844 })
3845
3846 (define_expand "cmptf"
3847   [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
3848                        (match_operand:TF 1 "general_operand" "")))]
3849   "TARGET_HAS_XFLOATING_LIBS"
3850 {
3851   alpha_compare.op0 = operands[0];
3852   alpha_compare.op1 = operands[1];
3853   alpha_compare.fp_p = 1;
3854   DONE;
3855 })
3856
3857 (define_expand "cmpdi"
3858   [(set (cc0) (compare (match_operand:DI 0 "general_operand" "")
3859                        (match_operand:DI 1 "general_operand" "")))]
3860   ""
3861 {
3862   alpha_compare.op0 = operands[0];
3863   alpha_compare.op1 = operands[1];
3864   alpha_compare.fp_p = 0;
3865   DONE;
3866 })
3867
3868 (define_expand "beq"
3869   [(set (pc)
3870         (if_then_else (match_dup 1)
3871                       (label_ref (match_operand 0 "" ""))
3872                       (pc)))]
3873   ""
3874   "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
3875
3876 (define_expand "bne"
3877   [(set (pc)
3878         (if_then_else (match_dup 1)
3879                       (label_ref (match_operand 0 "" ""))
3880                       (pc)))]
3881   ""
3882   "{ operands[1] = alpha_emit_conditional_branch (NE); }")
3883
3884 (define_expand "blt"
3885   [(set (pc)
3886         (if_then_else (match_dup 1)
3887                       (label_ref (match_operand 0 "" ""))
3888                       (pc)))]
3889   ""
3890   "{ operands[1] = alpha_emit_conditional_branch (LT); }")
3891
3892 (define_expand "ble"
3893   [(set (pc)
3894         (if_then_else (match_dup 1)
3895                       (label_ref (match_operand 0 "" ""))
3896                       (pc)))]
3897   ""
3898   "{ operands[1] = alpha_emit_conditional_branch (LE); }")
3899
3900 (define_expand "bgt"
3901   [(set (pc)
3902         (if_then_else (match_dup 1)
3903                       (label_ref (match_operand 0 "" ""))
3904                       (pc)))]
3905   ""
3906   "{ operands[1] = alpha_emit_conditional_branch (GT); }")
3907
3908 (define_expand "bge"
3909   [(set (pc)
3910         (if_then_else (match_dup 1)
3911                       (label_ref (match_operand 0 "" ""))
3912                       (pc)))]
3913   ""
3914   "{ operands[1] = alpha_emit_conditional_branch (GE); }")
3915
3916 (define_expand "bltu"
3917   [(set (pc)
3918         (if_then_else (match_dup 1)
3919                       (label_ref (match_operand 0 "" ""))
3920                       (pc)))]
3921   ""
3922   "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
3923
3924 (define_expand "bleu"
3925   [(set (pc)
3926         (if_then_else (match_dup 1)
3927                       (label_ref (match_operand 0 "" ""))
3928                       (pc)))]
3929   ""
3930   "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
3931
3932 (define_expand "bgtu"
3933   [(set (pc)
3934         (if_then_else (match_dup 1)
3935                       (label_ref (match_operand 0 "" ""))
3936                       (pc)))]
3937   ""
3938   "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
3939
3940 (define_expand "bgeu"
3941   [(set (pc)
3942         (if_then_else (match_dup 1)
3943                       (label_ref (match_operand 0 "" ""))
3944                       (pc)))]
3945   ""
3946   "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
3947
3948 (define_expand "bunordered"
3949   [(set (pc)
3950         (if_then_else (match_dup 1)
3951                       (label_ref (match_operand 0 "" ""))
3952                       (pc)))]
3953   ""
3954   "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }")
3955
3956 (define_expand "bordered"
3957   [(set (pc)
3958         (if_then_else (match_dup 1)
3959                       (label_ref (match_operand 0 "" ""))
3960                       (pc)))]
3961   ""
3962   "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }")
3963
3964 (define_expand "seq"
3965   [(set (match_operand:DI 0 "register_operand" "")
3966         (match_dup 1))]
3967   ""
3968   "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }")
3969
3970 (define_expand "sne"
3971   [(set (match_operand:DI 0 "register_operand" "")
3972         (match_dup 1))]
3973   ""
3974   "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }")
3975
3976 (define_expand "slt"
3977   [(set (match_operand:DI 0 "register_operand" "")
3978         (match_dup 1))]
3979   ""
3980   "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }")
3981
3982 (define_expand "sle"
3983   [(set (match_operand:DI 0 "register_operand" "")
3984         (match_dup 1))]
3985   ""
3986   "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }")
3987
3988 (define_expand "sgt"
3989   [(set (match_operand:DI 0 "register_operand" "")
3990         (match_dup 1))]
3991   ""
3992   "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }")
3993
3994 (define_expand "sge"
3995   [(set (match_operand:DI 0 "register_operand" "")
3996         (match_dup 1))]
3997   ""
3998   "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }")
3999
4000 (define_expand "sltu"
4001   [(set (match_operand:DI 0 "register_operand" "")
4002         (match_dup 1))]
4003   ""
4004   "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }")
4005
4006 (define_expand "sleu"
4007   [(set (match_operand:DI 0 "register_operand" "")
4008         (match_dup 1))]
4009   ""
4010   "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }")
4011
4012 (define_expand "sgtu"
4013   [(set (match_operand:DI 0 "register_operand" "")
4014         (match_dup 1))]
4015   ""
4016   "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }")
4017
4018 (define_expand "sgeu"
4019   [(set (match_operand:DI 0 "register_operand" "")
4020         (match_dup 1))]
4021   ""
4022   "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }")
4023
4024 (define_expand "sunordered"
4025   [(set (match_operand:DI 0 "register_operand" "")
4026         (match_dup 1))]
4027   ""
4028   "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }")
4029
4030 (define_expand "sordered"
4031   [(set (match_operand:DI 0 "register_operand" "")
4032         (match_dup 1))]
4033   ""
4034   "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }")
4035 \f
4036 ;; These are the main define_expand's used to make conditional moves.
4037
4038 (define_expand "movsicc"
4039   [(set (match_operand:SI 0 "register_operand" "")
4040         (if_then_else:SI (match_operand 1 "comparison_operator" "")
4041                          (match_operand:SI 2 "reg_or_8bit_operand" "")
4042                          (match_operand:SI 3 "reg_or_8bit_operand" "")))]
4043   ""
4044 {
4045   if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
4046     FAIL;
4047 })
4048
4049 (define_expand "movdicc"
4050   [(set (match_operand:DI 0 "register_operand" "")
4051         (if_then_else:DI (match_operand 1 "comparison_operator" "")
4052                          (match_operand:DI 2 "reg_or_8bit_operand" "")
4053                          (match_operand:DI 3 "reg_or_8bit_operand" "")))]
4054   ""
4055 {
4056   if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
4057     FAIL;
4058 })
4059
4060 (define_expand "movsfcc"
4061   [(set (match_operand:SF 0 "register_operand" "")
4062         (if_then_else:SF (match_operand 1 "comparison_operator" "")
4063                          (match_operand:SF 2 "reg_or_8bit_operand" "")
4064                          (match_operand:SF 3 "reg_or_8bit_operand" "")))]
4065   ""
4066 {
4067   if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
4068     FAIL;
4069 })
4070
4071 (define_expand "movdfcc"
4072   [(set (match_operand:DF 0 "register_operand" "")
4073         (if_then_else:DF (match_operand 1 "comparison_operator" "")
4074                          (match_operand:DF 2 "reg_or_8bit_operand" "")
4075                          (match_operand:DF 3 "reg_or_8bit_operand" "")))]
4076   ""
4077 {
4078   if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
4079     FAIL;
4080 })
4081 \f
4082 ;; These define_split definitions are used in cases when comparisons have
4083 ;; not be stated in the correct way and we need to reverse the second
4084 ;; comparison.  For example, x >= 7 has to be done as x < 6 with the
4085 ;; comparison that tests the result being reversed.  We have one define_split
4086 ;; for each use of a comparison.  They do not match valid insns and need
4087 ;; not generate valid insns.
4088 ;;
4089 ;; We can also handle equality comparisons (and inequality comparisons in
4090 ;; cases where the resulting add cannot overflow) by doing an add followed by
4091 ;; a comparison with zero.  This is faster since the addition takes one
4092 ;; less cycle than a compare when feeding into a conditional move.
4093 ;; For this case, we also have an SImode pattern since we can merge the add
4094 ;; and sign extend and the order doesn't matter.
4095 ;;
4096 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
4097 ;; operation could have been generated.
4098
4099 (define_split
4100   [(set (match_operand:DI 0 "register_operand" "")
4101         (if_then_else:DI
4102          (match_operator 1 "comparison_operator"
4103                          [(match_operand:DI 2 "reg_or_0_operand" "")
4104                           (match_operand:DI 3 "reg_or_cint_operand" "")])
4105          (match_operand:DI 4 "reg_or_cint_operand" "")
4106          (match_operand:DI 5 "reg_or_cint_operand" "")))
4107    (clobber (match_operand:DI 6 "register_operand" ""))]
4108   "operands[3] != const0_rtx"
4109   [(set (match_dup 6) (match_dup 7))
4110    (set (match_dup 0)
4111         (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
4112 {
4113   enum rtx_code code = GET_CODE (operands[1]);
4114   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
4115
4116   /* If we are comparing for equality with a constant and that constant
4117      appears in the arm when the register equals the constant, use the
4118      register since that is more likely to match (and to produce better code
4119      if both would).  */
4120
4121   if (code == EQ && GET_CODE (operands[3]) == CONST_INT
4122       && rtx_equal_p (operands[4], operands[3]))
4123     operands[4] = operands[2];
4124
4125   else if (code == NE && GET_CODE (operands[3]) == CONST_INT
4126            && rtx_equal_p (operands[5], operands[3]))
4127     operands[5] = operands[2];
4128
4129   if (code == NE || code == EQ
4130       || (extended_count (operands[2], DImode, unsignedp) >= 1
4131           && extended_count (operands[3], DImode, unsignedp) >= 1))
4132     {
4133       if (GET_CODE (operands[3]) == CONST_INT)
4134         operands[7] = gen_rtx_PLUS (DImode, operands[2],
4135                                     GEN_INT (- INTVAL (operands[3])));
4136       else
4137         operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
4138
4139       operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
4140     }
4141
4142   else if (code == EQ || code == LE || code == LT
4143            || code == LEU || code == LTU)
4144     {
4145       operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
4146       operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
4147     }
4148   else
4149     {
4150       operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
4151                                     operands[2], operands[3]);
4152       operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
4153     }
4154 })
4155
4156 (define_split
4157   [(set (match_operand:DI 0 "register_operand" "")
4158         (if_then_else:DI
4159          (match_operator 1 "comparison_operator"
4160                          [(match_operand:SI 2 "reg_or_0_operand" "")
4161                           (match_operand:SI 3 "reg_or_cint_operand" "")])
4162          (match_operand:DI 4 "reg_or_8bit_operand" "")
4163          (match_operand:DI 5 "reg_or_8bit_operand" "")))
4164    (clobber (match_operand:DI 6 "register_operand" ""))]
4165   "operands[3] != const0_rtx
4166    && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
4167   [(set (match_dup 6) (match_dup 7))
4168    (set (match_dup 0)
4169         (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
4170 {
4171   enum rtx_code code = GET_CODE (operands[1]);
4172   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
4173   rtx tem;
4174
4175   if ((code != NE && code != EQ
4176        && ! (extended_count (operands[2], DImode, unsignedp) >= 1
4177              && extended_count (operands[3], DImode, unsignedp) >= 1)))
4178     FAIL;
4179
4180   if (GET_CODE (operands[3]) == CONST_INT)
4181     tem = gen_rtx_PLUS (SImode, operands[2],
4182                         GEN_INT (- INTVAL (operands[3])));
4183   else
4184     tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
4185
4186   operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
4187   operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
4188                                 operands[6], const0_rtx);
4189 })
4190
4191 (define_split
4192   [(set (pc)
4193         (if_then_else
4194          (match_operator 1 "comparison_operator"
4195                          [(match_operand:DI 2 "reg_or_0_operand" "")
4196                           (match_operand:DI 3 "reg_or_cint_operand" "")])
4197          (label_ref (match_operand 0 "" ""))
4198          (pc)))
4199    (clobber (match_operand:DI 4 "register_operand" ""))]
4200   "operands[3] != const0_rtx"
4201   [(set (match_dup 4) (match_dup 5))
4202    (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
4203 {
4204   enum rtx_code code = GET_CODE (operands[1]);
4205   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
4206
4207   if (code == NE || code == EQ
4208       || (extended_count (operands[2], DImode, unsignedp) >= 1
4209           && extended_count (operands[3], DImode, unsignedp) >= 1))
4210     {
4211       if (GET_CODE (operands[3]) == CONST_INT)
4212         operands[5] = gen_rtx_PLUS (DImode, operands[2],
4213                                     GEN_INT (- INTVAL (operands[3])));
4214       else
4215         operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
4216
4217       operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
4218     }
4219
4220   else if (code == EQ || code == LE || code == LT
4221            || code == LEU || code == LTU)
4222     {
4223       operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
4224       operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
4225     }
4226   else
4227     {
4228       operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
4229                                     operands[2], operands[3]);
4230       operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
4231     }
4232 })
4233
4234 (define_split
4235   [(set (pc)
4236         (if_then_else
4237          (match_operator 1 "comparison_operator"
4238                          [(match_operand:SI 2 "reg_or_0_operand" "")
4239                           (match_operand:SI 3 "const_int_operand" "")])
4240          (label_ref (match_operand 0 "" ""))
4241          (pc)))
4242    (clobber (match_operand:DI 4 "register_operand" ""))]
4243   "operands[3] != const0_rtx
4244    && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
4245   [(set (match_dup 4) (match_dup 5))
4246    (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
4247 {
4248   rtx tem;
4249
4250   if (GET_CODE (operands[3]) == CONST_INT)
4251     tem = gen_rtx_PLUS (SImode, operands[2],
4252                         GEN_INT (- INTVAL (operands[3])));
4253   else
4254     tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
4255
4256   operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
4257   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
4258                                 operands[4], const0_rtx);
4259 })
4260
4261 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
4262 ;; This eliminates one, and sometimes two, insns when the AND can be done
4263 ;; with a ZAP.
4264 (define_split
4265   [(set (match_operand:DI 0 "register_operand" "")
4266         (match_operator:DI 1 "comparison_operator"
4267                         [(match_operand:DI 2 "register_operand" "")
4268                          (match_operand:DI 3 "const_int_operand" "")]))
4269    (clobber (match_operand:DI 4 "register_operand" ""))]
4270   "exact_log2 (INTVAL (operands[3]) + 1) >= 0
4271    && (GET_CODE (operands[1]) == GTU
4272        || GET_CODE (operands[1]) == LEU
4273        || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
4274            && extended_count (operands[2], DImode, 1) > 0))"
4275   [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
4276    (set (match_dup 0) (match_dup 6))]
4277 {
4278   operands[5] = GEN_INT (~ INTVAL (operands[3]));
4279   operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
4280                                   || GET_CODE (operands[1]) == GT)
4281                                  ? NE : EQ),
4282                                 DImode, operands[4], const0_rtx);
4283 })
4284
4285 ;; Prefer to use cmp and arithmetic when possible instead of a cmove.
4286
4287 (define_split
4288   [(set (match_operand 0 "register_operand" "")
4289         (if_then_else (match_operator 1 "signed_comparison_operator"
4290                            [(match_operand:DI 2 "reg_or_0_operand" "")
4291                             (const_int 0)])
4292           (match_operand 3 "const_int_operand" "")
4293           (match_operand 4 "const_int_operand" "")))]
4294   ""
4295   [(const_int 0)]
4296 {
4297   if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
4298                                     operands[2], operands[3], operands[4]))
4299     DONE;
4300   else
4301     FAIL;
4302 })
4303
4304 ;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
4305 ;; Oh well, we match it in movcc, so it must be partially our fault.
4306 (define_split
4307   [(set (match_operand 0 "register_operand" "")
4308         (if_then_else (match_operator 1 "signed_comparison_operator"
4309                            [(const_int 0)
4310                             (match_operand:DI 2 "reg_or_0_operand" "")])
4311           (match_operand 3 "const_int_operand" "")
4312           (match_operand 4 "const_int_operand" "")))]
4313   ""
4314   [(const_int 0)]
4315 {
4316   if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
4317                                     operands[0], operands[2], operands[3],
4318                                     operands[4]))
4319     DONE;
4320   else
4321     FAIL;
4322 })
4323
4324 (define_insn_and_split "*cmp_sadd_di"
4325   [(set (match_operand:DI 0 "register_operand" "=r")
4326         (plus:DI (if_then_else:DI
4327                    (match_operator 1 "alpha_zero_comparison_operator"
4328                      [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4329                       (const_int 0)])
4330                    (match_operand:DI 3 "const48_operand" "I")
4331                    (const_int 0))
4332                  (match_operand:DI 4 "sext_add_operand" "rIO")))
4333    (clobber (match_scratch:DI 5 "=r"))]
4334   ""
4335   "#"
4336   "! no_new_pseudos || reload_completed"
4337   [(set (match_dup 5)
4338         (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
4339    (set (match_dup 0)
4340         (plus:DI (mult:DI (match_dup 5) (match_dup 3))
4341                  (match_dup 4)))]
4342 {
4343   if (! no_new_pseudos)
4344     operands[5] = gen_reg_rtx (DImode);
4345   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4346     operands[5] = operands[0];
4347 })
4348
4349 (define_insn_and_split "*cmp_sadd_si"
4350   [(set (match_operand:SI 0 "register_operand" "=r")
4351         (plus:SI (if_then_else:SI
4352                    (match_operator 1 "alpha_zero_comparison_operator"
4353                      [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4354                       (const_int 0)])
4355                    (match_operand:SI 3 "const48_operand" "I")
4356                    (const_int 0))
4357                  (match_operand:SI 4 "sext_add_operand" "rIO")))
4358    (clobber (match_scratch:SI 5 "=r"))]
4359   ""
4360   "#"
4361   "! no_new_pseudos || reload_completed"
4362   [(set (match_dup 5)
4363         (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4364    (set (match_dup 0)
4365         (plus:SI (mult:SI (match_dup 5) (match_dup 3))
4366                  (match_dup 4)))]
4367 {
4368   if (! no_new_pseudos)
4369     operands[5] = gen_reg_rtx (DImode);
4370   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4371     operands[5] = operands[0];
4372 })
4373
4374 (define_insn_and_split "*cmp_sadd_sidi"
4375   [(set (match_operand:DI 0 "register_operand" "=r")
4376         (sign_extend:DI
4377           (plus:SI (if_then_else:SI
4378                      (match_operator 1 "alpha_zero_comparison_operator"
4379                        [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4380                         (const_int 0)])
4381                      (match_operand:SI 3 "const48_operand" "I")
4382                      (const_int 0))
4383                    (match_operand:SI 4 "sext_add_operand" "rIO"))))
4384    (clobber (match_scratch:SI 5 "=r"))]
4385   ""
4386   "#"
4387   "! no_new_pseudos || reload_completed"
4388   [(set (match_dup 5)
4389         (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4390    (set (match_dup 0)
4391         (sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3))
4392                                  (match_dup 4))))]
4393 {
4394   if (! no_new_pseudos)
4395     operands[5] = gen_reg_rtx (DImode);
4396   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4397     operands[5] = operands[0];
4398 })
4399
4400 (define_insn_and_split "*cmp_ssub_di"
4401   [(set (match_operand:DI 0 "register_operand" "=r")
4402         (minus:DI (if_then_else:DI
4403                     (match_operator 1 "alpha_zero_comparison_operator"
4404                       [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4405                        (const_int 0)])
4406                     (match_operand:DI 3 "const48_operand" "I")
4407                     (const_int 0))
4408                   (match_operand:DI 4 "reg_or_8bit_operand" "rI")))
4409    (clobber (match_scratch:DI 5 "=r"))]
4410   ""
4411   "#"
4412   "! no_new_pseudos || reload_completed"
4413   [(set (match_dup 5)
4414         (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
4415    (set (match_dup 0)
4416         (minus:DI (mult:DI (match_dup 5) (match_dup 3))
4417                   (match_dup 4)))]
4418 {
4419   if (! no_new_pseudos)
4420     operands[5] = gen_reg_rtx (DImode);
4421   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4422     operands[5] = operands[0];
4423 })
4424
4425 (define_insn_and_split "*cmp_ssub_si"
4426   [(set (match_operand:SI 0 "register_operand" "=r")
4427         (minus:SI (if_then_else:SI
4428                     (match_operator 1 "alpha_zero_comparison_operator"
4429                       [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4430                        (const_int 0)])
4431                     (match_operand:SI 3 "const48_operand" "I")
4432                     (const_int 0))
4433                   (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
4434    (clobber (match_scratch:SI 5 "=r"))]
4435   ""
4436   "#"
4437   "! no_new_pseudos || reload_completed"
4438   [(set (match_dup 5)
4439         (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4440    (set (match_dup 0)
4441         (minus:SI (mult:SI (match_dup 5) (match_dup 3))
4442                  (match_dup 4)))]
4443 {
4444   if (! no_new_pseudos)
4445     operands[5] = gen_reg_rtx (DImode);
4446   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4447     operands[5] = operands[0];
4448 })
4449
4450 (define_insn_and_split "*cmp_ssub_sidi"
4451   [(set (match_operand:DI 0 "register_operand" "=r")
4452         (sign_extend:DI
4453           (minus:SI (if_then_else:SI
4454                       (match_operator 1 "alpha_zero_comparison_operator"
4455                         [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4456                          (const_int 0)])
4457                       (match_operand:SI 3 "const48_operand" "I")
4458                       (const_int 0))
4459                     (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
4460    (clobber (match_scratch:SI 5 "=r"))]
4461   ""
4462   "#"
4463   "! no_new_pseudos || reload_completed"
4464   [(set (match_dup 5)
4465         (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4466    (set (match_dup 0)
4467         (sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3))
4468                                   (match_dup 4))))]
4469 {
4470   if (! no_new_pseudos)
4471     operands[5] = gen_reg_rtx (DImode);
4472   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4473     operands[5] = operands[0];
4474 })
4475 \f
4476 ;; Here are the CALL and unconditional branch insns.  Calls on NT and OSF
4477 ;; work differently, so we have different patterns for each.
4478
4479 ;; On Unicos/Mk a call information word (CIW) must be generated for each
4480 ;; call. The CIW contains information about arguments passed in registers
4481 ;; and is stored in the caller's SSIB. Its offset relative to the beginning
4482 ;; of the SSIB is passed in $25. Handling this properly is quite complicated
4483 ;; in the presence of inlining since the CIWs for calls performed by the
4484 ;; inlined function must be stored in the SSIB of the function it is inlined
4485 ;; into as well. We encode the CIW in an unspec and append it to the list
4486 ;; of the CIWs for the current function only when the instruction for loading
4487 ;; $25 is generated.
4488
4489 (define_expand "call"
4490   [(use (match_operand:DI 0 "" ""))
4491    (use (match_operand 1 "" ""))
4492    (use (match_operand 2 "" ""))
4493    (use (match_operand 3 "" ""))]
4494   ""
4495 {
4496   if (TARGET_ABI_WINDOWS_NT)
4497     emit_call_insn (gen_call_nt (operands[0], operands[1]));
4498   else if (TARGET_ABI_OPEN_VMS)
4499     emit_call_insn (gen_call_vms (operands[0], operands[2]));
4500   else if (TARGET_ABI_UNICOSMK)
4501     emit_call_insn (gen_call_umk (operands[0], operands[2]));
4502   else
4503     emit_call_insn (gen_call_osf (operands[0], operands[1]));
4504   DONE;
4505 })
4506
4507 (define_expand "sibcall"
4508   [(parallel [(call (mem:DI (match_operand 0 "" ""))
4509                             (match_operand 1 "" ""))
4510               (use (reg:DI 29))])]
4511   "TARGET_ABI_OSF"
4512 {
4513   if (GET_CODE (operands[0]) != MEM)
4514     abort ();
4515   operands[0] = XEXP (operands[0], 0);
4516 })
4517
4518 (define_expand "call_osf"
4519   [(parallel [(call (mem:DI (match_operand 0 "" ""))
4520                     (match_operand 1 "" ""))
4521               (use (reg:DI 29))
4522               (clobber (reg:DI 26))])]
4523   ""
4524 {
4525   if (GET_CODE (operands[0]) != MEM)
4526     abort ();
4527
4528   operands[0] = XEXP (operands[0], 0);
4529   if (! call_operand (operands[0], Pmode))
4530     {
4531       rtx pv = gen_rtx_REG (Pmode, 27);
4532       emit_move_insn (pv, operands[0]);
4533       operands[0] = pv;
4534     }
4535 })
4536
4537 (define_expand "call_nt"
4538   [(parallel [(call (mem:DI (match_operand 0 "" ""))
4539                     (match_operand 1 "" ""))
4540               (clobber (reg:DI 26))])]
4541   ""
4542 {
4543   if (GET_CODE (operands[0]) != MEM)
4544     abort ();
4545
4546   operands[0] = XEXP (operands[0], 0);
4547   if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
4548     operands[0] = force_reg (DImode, operands[0]);
4549 })
4550
4551 ;; Calls on Unicos/Mk are always indirect.
4552 ;; op 0: symbol ref for called function
4553 ;; op 1: CIW for $25 represented by an unspec
4554
4555 (define_expand "call_umk"
4556    [(parallel [(call (mem:DI (match_operand 0 "" ""))
4557                      (match_operand 1 "" ""))
4558                (use (reg:DI 25))
4559                (clobber (reg:DI 26))])]
4560    ""
4561 {
4562   if (GET_CODE (operands[0]) != MEM)
4563     abort ();
4564
4565   /* Always load the address of the called function into a register;
4566      load the CIW in $25.  */
4567
4568   operands[0] = XEXP (operands[0], 0);
4569   if (GET_CODE (operands[0]) != REG)
4570     operands[0] = force_reg (DImode, operands[0]);
4571
4572   emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
4573 })
4574
4575 ;;
4576 ;; call openvms/alpha
4577 ;; op 0: symbol ref for called function
4578 ;; op 1: next_arg_reg (argument information value for R25)
4579 ;;
4580 (define_expand "call_vms"
4581   [(parallel [(call (mem:DI (match_operand 0 "" ""))
4582                     (match_operand 1 "" ""))
4583               (use (match_dup 2))
4584               (use (reg:DI 25))
4585               (use (reg:DI 26))
4586               (clobber (reg:DI 27))])]
4587   ""
4588 {
4589   if (GET_CODE (operands[0]) != MEM)
4590     abort ();
4591
4592   operands[0] = XEXP (operands[0], 0);
4593
4594   /* Always load AI with argument information, then handle symbolic and
4595      indirect call differently.  Load RA and set operands[2] to PV in
4596      both cases.  */
4597
4598   emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
4599   if (GET_CODE (operands[0]) == SYMBOL_REF)
4600     {
4601       rtx linkage = alpha_need_linkage (XSTR (operands[0], 0), 0);
4602
4603       emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
4604       operands[2]
4605         = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
4606     }
4607   else
4608     {
4609       emit_move_insn (gen_rtx_REG (Pmode, 26),
4610                       gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
4611       operands[2] = operands[0];
4612     }
4613
4614 })
4615
4616 (define_expand "call_value"
4617   [(use (match_operand 0 "" ""))
4618    (use (match_operand:DI 1 "" ""))
4619    (use (match_operand 2 "" ""))
4620    (use (match_operand 3 "" ""))
4621    (use (match_operand 4 "" ""))]
4622   ""
4623 {
4624   if (TARGET_ABI_WINDOWS_NT)
4625     emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
4626   else if (TARGET_ABI_OPEN_VMS)
4627     emit_call_insn (gen_call_value_vms (operands[0], operands[1],
4628                                         operands[3]));
4629   else if (TARGET_ABI_UNICOSMK)
4630     emit_call_insn (gen_call_value_umk (operands[0], operands[1],
4631                                         operands[3]));
4632   else
4633     emit_call_insn (gen_call_value_osf (operands[0], operands[1],
4634                                         operands[2]));
4635   DONE;
4636 })
4637
4638 (define_expand "sibcall_value"
4639   [(parallel [(set (match_operand 0 "" "")
4640                    (call (mem:DI (match_operand 1 "" ""))
4641                          (match_operand 2 "" "")))
4642               (use (reg:DI 29))])]
4643   "TARGET_ABI_OSF"
4644 {
4645   if (GET_CODE (operands[1]) != MEM)
4646     abort ();
4647   operands[1] = XEXP (operands[1], 0);
4648 })
4649
4650 (define_expand "call_value_osf"
4651   [(parallel [(set (match_operand 0 "" "")
4652                    (call (mem:DI (match_operand 1 "" ""))
4653                          (match_operand 2 "" "")))
4654               (use (reg:DI 29))
4655               (clobber (reg:DI 26))])]
4656   ""
4657 {
4658   if (GET_CODE (operands[1]) != MEM)
4659     abort ();
4660
4661   operands[1] = XEXP (operands[1], 0);
4662   if (! call_operand (operands[1], Pmode))
4663     {
4664       rtx pv = gen_rtx_REG (Pmode, 27);
4665       emit_move_insn (pv, operands[1]);
4666       operands[1] = pv;
4667     }
4668 })
4669
4670 (define_expand "call_value_nt"
4671   [(parallel [(set (match_operand 0 "" "")
4672                    (call (mem:DI (match_operand 1 "" ""))
4673                          (match_operand 2 "" "")))
4674               (clobber (reg:DI 26))])]
4675   ""
4676 {
4677   if (GET_CODE (operands[1]) != MEM)
4678     abort ();
4679
4680   operands[1] = XEXP (operands[1], 0);
4681   if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
4682     operands[1] = force_reg (DImode, operands[1]);
4683 })
4684
4685 (define_expand "call_value_vms"
4686   [(parallel [(set (match_operand 0 "" "")
4687                    (call (mem:DI (match_operand:DI 1 "" ""))
4688                          (match_operand 2 "" "")))
4689               (use (match_dup 3))
4690               (use (reg:DI 25))
4691               (use (reg:DI 26))
4692               (clobber (reg:DI 27))])]
4693   ""
4694 {
4695   if (GET_CODE (operands[1]) != MEM)
4696     abort ();
4697
4698   operands[1] = XEXP (operands[1], 0);
4699
4700   /* Always load AI with argument information, then handle symbolic and
4701      indirect call differently.  Load RA and set operands[3] to PV in
4702      both cases.  */
4703
4704   emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
4705   if (GET_CODE (operands[1]) == SYMBOL_REF)
4706     {
4707       rtx linkage = alpha_need_linkage (XSTR (operands[1], 0), 0);
4708
4709       emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
4710       operands[3]
4711         = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
4712     }
4713   else
4714     {
4715       emit_move_insn (gen_rtx_REG (Pmode, 26),
4716                       gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
4717       operands[3] = operands[1];
4718     }
4719 })
4720
4721 (define_expand "call_value_umk"
4722   [(parallel [(set (match_operand 0 "" "")
4723                    (call (mem:DI (match_operand 1 "" ""))
4724                          (match_operand 2 "" "")))
4725               (use (reg:DI 25))
4726               (clobber (reg:DI 26))])]
4727   ""
4728 {
4729   if (GET_CODE (operands[1]) != MEM)
4730     abort ();
4731
4732   operands[1] = XEXP (operands[1], 0);
4733   if (GET_CODE (operands[1]) != REG)
4734     operands[1] = force_reg (DImode, operands[1]);
4735
4736   emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
4737 })
4738
4739 (define_insn "*call_osf_1_er"
4740   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
4741          (match_operand 1 "" ""))
4742    (use (reg:DI 29))
4743    (clobber (reg:DI 26))]
4744   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4745   "@
4746    jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
4747    bsr $26,$%0..ng
4748    ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
4749   [(set_attr "type" "jsr")
4750    (set_attr "length" "12,*,16")])
4751
4752 ;; We must use peep2 instead of a split because we need accurate life
4753 ;; information for $gp.  Consider the case of { bar(); while (1); }.
4754 (define_peephole2
4755   [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
4756                     (match_operand 1 "" ""))
4757               (use (reg:DI 29))
4758               (clobber (reg:DI 26))])]
4759   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
4760    && ! current_file_function_operand (operands[0], Pmode)
4761    && peep2_regno_dead_p (1, 29)"
4762   [(parallel [(call (mem:DI (match_dup 2))
4763                     (match_dup 1))
4764               (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
4765               (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
4766               (use (match_dup 0))])]
4767 {
4768   if (CONSTANT_P (operands[0]))
4769     {
4770       operands[2] = gen_rtx_REG (Pmode, 27);
4771       emit_move_insn (operands[2], operands[0]);
4772     }
4773   else
4774     {
4775       operands[2] = operands[0];
4776       operands[0] = const0_rtx;
4777     }
4778 })
4779
4780 (define_peephole2
4781   [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
4782                     (match_operand 1 "" ""))
4783               (use (reg:DI 29))
4784               (clobber (reg:DI 26))])]
4785   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
4786    && ! current_file_function_operand (operands[0], Pmode)
4787    && ! peep2_regno_dead_p (1, 29)"
4788   [(parallel [(call (mem:DI (match_dup 2))
4789                     (match_dup 1))
4790               (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
4791               (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
4792               (use (match_dup 0))])
4793    (set (reg:DI 29)
4794         (unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1))
4795    (set (reg:DI 29)
4796         (unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))]
4797 {
4798   if (CONSTANT_P (operands[0]))
4799     {
4800       operands[2] = gen_rtx_REG (Pmode, 27);
4801       emit_move_insn (operands[2], operands[0]);
4802     }
4803   else
4804     {
4805       operands[2] = operands[0];
4806       operands[0] = const0_rtx;
4807     }
4808   operands[3] = GEN_INT (alpha_next_sequence_number++);
4809 })
4810
4811 ;; We add a blockage unspec_volatile to prevent insns from moving down
4812 ;; from above the call to in between the call and the ldah gpdisp.
4813
4814 (define_insn "*call_osf_2_er"
4815   [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
4816          (match_operand 1 "" ""))
4817    (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
4818    (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
4819    (use (match_operand 2 "" ""))]
4820   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4821   "jsr $26,(%0),%2"
4822   [(set_attr "type" "jsr")])
4823
4824 (define_insn "*call_osf_1_noreturn"
4825   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
4826          (match_operand 1 "" ""))
4827    (use (reg:DI 29))
4828    (clobber (reg:DI 26))]
4829   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
4830    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4831   "@
4832    jsr $26,($27),0
4833    bsr $26,$%0..ng
4834    jsr $26,%0"
4835   [(set_attr "type" "jsr")
4836    (set_attr "length" "*,*,8")])
4837
4838 (define_insn "*call_osf_1"
4839   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
4840          (match_operand 1 "" ""))
4841    (use (reg:DI 29))
4842    (clobber (reg:DI 26))]
4843   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4844   "@
4845    jsr $26,($27),0\;ldgp $29,0($26)
4846    bsr $26,$%0..ng
4847    jsr $26,%0\;ldgp $29,0($26)"
4848   [(set_attr "type" "jsr")
4849    (set_attr "length" "12,*,16")])
4850
4851 ;; Need 's' alternative for OSF/1, which implements profiling via linker
4852 ;; tricks.  Note that the DEC assembler expands "jmp foo" with $at, which
4853 ;; doesn't do what we want.
4854 (define_insn "*sibcall_osf_1"
4855   [(call (mem:DI (match_operand:DI 0 "current_file_function_operand" "R,s"))
4856          (match_operand 1 "" ""))
4857    (use (reg:DI 29))]
4858   "TARGET_ABI_OSF"
4859   "@
4860    br $31,$%0..ng
4861    lda $27,%0\;jmp $31,($27),%0"
4862   [(set_attr "type" "jsr")
4863    (set_attr "length" "*,8")])
4864
4865 (define_insn "*call_nt_1"
4866   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,s"))
4867          (match_operand 1 "" ""))
4868    (clobber (reg:DI 26))]
4869   "TARGET_ABI_WINDOWS_NT"
4870   "@
4871    jsr $26,(%0)
4872    bsr $26,%0
4873    jsr $26,%0"
4874   [(set_attr "type" "jsr")
4875    (set_attr "length" "*,*,12")])
4876
4877 (define_insn "*call_vms_1"
4878   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
4879          (match_operand 1 "" ""))
4880    (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
4881    (use (reg:DI 25))
4882    (use (reg:DI 26))
4883    (clobber (reg:DI 27))]
4884   "TARGET_ABI_OPEN_VMS"
4885   "@
4886    mov %2,$27\;jsr $26,0\;ldq $27,0($29)
4887    ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
4888   [(set_attr "type" "jsr")
4889    (set_attr "length" "12,16")])
4890
4891 (define_insn "*call_umk_1"
4892   [(call (mem:DI (match_operand:DI 0 "call_operand" "r"))
4893          (match_operand 1 "" ""))
4894    (use (reg:DI 25))
4895    (clobber (reg:DI 26))]
4896   "TARGET_ABI_UNICOSMK"
4897   "jsr $26,(%0)"
4898   [(set_attr "type" "jsr")])
4899
4900 ;; Call subroutine returning any type.
4901
4902 (define_expand "untyped_call"
4903   [(parallel [(call (match_operand 0 "" "")
4904                     (const_int 0))
4905               (match_operand 1 "" "")
4906               (match_operand 2 "" "")])]
4907   ""
4908 {
4909   int i;
4910
4911   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
4912
4913   for (i = 0; i < XVECLEN (operands[2], 0); i++)
4914     {
4915       rtx set = XVECEXP (operands[2], 0, i);
4916       emit_move_insn (SET_DEST (set), SET_SRC (set));
4917     }
4918
4919   /* The optimizer does not know that the call sets the function value
4920      registers we stored in the result block.  We avoid problems by
4921      claiming that all hard registers are used and clobbered at this
4922      point.  */
4923   emit_insn (gen_blockage ());
4924
4925   DONE;
4926 })
4927
4928 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4929 ;; all of memory.  This blocks insns from being moved across this point.
4930
4931 (define_insn "blockage"
4932   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
4933   ""
4934   ""
4935   [(set_attr "length" "0")])
4936
4937 (define_insn "jump"
4938   [(set (pc)
4939         (label_ref (match_operand 0 "" "")))]
4940   ""
4941   "br $31,%l0"
4942   [(set_attr "type" "ibr")])
4943
4944 (define_expand "return"
4945   [(return)]
4946   "direct_return ()"
4947   "")
4948
4949 (define_insn "*return_internal"
4950   [(return)]
4951   "reload_completed"
4952   "ret $31,($26),1"
4953   [(set_attr "type" "ibr")])
4954
4955 (define_insn "indirect_jump"
4956   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
4957   ""
4958   "jmp $31,(%0),0"
4959   [(set_attr "type" "ibr")])
4960
4961 (define_expand "tablejump"
4962   [(parallel [(set (pc)
4963                    (match_operand 0 "register_operand" ""))
4964               (use (label_ref:DI (match_operand 1 "" "")))])]
4965   ""
4966 {
4967   if (TARGET_ABI_WINDOWS_NT)
4968     {
4969       rtx dest = gen_reg_rtx (DImode);
4970       emit_insn (gen_extendsidi2 (dest, operands[0]));
4971       operands[0] = dest;
4972     }
4973   else if (TARGET_ABI_OSF)
4974     {
4975       rtx dest = gen_reg_rtx (DImode);
4976       emit_insn (gen_extendsidi2 (dest, operands[0]));
4977       emit_insn (gen_adddi3 (dest, gen_rtx_REG (DImode, 29), dest));    
4978       operands[0] = dest;
4979     }
4980 })
4981
4982 (define_insn "*tablejump_osf_nt_internal"
4983   [(set (pc)
4984         (match_operand:DI 0 "register_operand" "r"))
4985    (use (label_ref:DI (match_operand 1 "" "")))]
4986   "(TARGET_ABI_OSF || TARGET_ABI_WINDOWS_NT)
4987    && alpha_tablejump_addr_vec (insn)"
4988 {
4989   operands[2] = alpha_tablejump_best_label (insn);
4990   return "jmp $31,(%0),%2";
4991 }
4992   [(set_attr "type" "ibr")])
4993
4994 (define_insn "*tablejump_internal"
4995   [(set (pc)
4996         (match_operand:DI 0 "register_operand" "r"))
4997    (use (label_ref (match_operand 1 "" "")))]
4998   ""
4999   "jmp $31,(%0),0"
5000   [(set_attr "type" "ibr")])
5001
5002 ;; Cache flush.  Used by INITIALIZE_TRAMPOLINE.  0x86 is PAL_imb, but we don't
5003 ;; want to have to include pal.h in our .s file.
5004 ;;
5005 ;; Technically the type for call_pal is jsr, but we use that for determining
5006 ;; if we need a GP.  Use ibr instead since it has the same EV5 scheduling
5007 ;; characteristics.
5008 (define_insn "imb"
5009   [(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
5010   ""
5011   "call_pal 0x86"
5012   [(set_attr "type" "ibr")])
5013 \f
5014 ;; Finally, we have the basic data motion insns.  The byte and word insns
5015 ;; are done via define_expand.  Start with the floating-point insns, since
5016 ;; they are simpler.
5017
5018 (define_insn "*movsf_nofix"
5019   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
5020         (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
5021   "TARGET_FPREGS && ! TARGET_FIX
5022    && (register_operand (operands[0], SFmode)
5023        || reg_or_fp0_operand (operands[1], SFmode))"
5024   "@
5025    cpys %R1,%R1,%0
5026    ld%, %0,%1
5027    bis $31,%r1,%0
5028    ldl %0,%1
5029    st%, %R1,%0
5030    stl %r1,%0"
5031   [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
5032
5033 (define_insn "*movsf_fix"
5034   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
5035         (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
5036   "TARGET_FPREGS && TARGET_FIX
5037    && (register_operand (operands[0], SFmode)
5038        || reg_or_fp0_operand (operands[1], SFmode))"
5039   "@
5040    cpys %R1,%R1,%0
5041    ld%, %0,%1
5042    bis $31,%r1,%0
5043    ldl %0,%1
5044    st%, %R1,%0
5045    stl %r1,%0
5046    itofs %1,%0
5047    ftois %1,%0"
5048   [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
5049
5050 (define_insn "*movsf_nofp"
5051   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5052         (match_operand:SF 1 "input_operand" "rG,m,r"))]
5053   "! TARGET_FPREGS
5054    && (register_operand (operands[0], SFmode)
5055        || reg_or_fp0_operand (operands[1], SFmode))"
5056   "@
5057    bis $31,%r1,%0
5058    ldl %0,%1
5059    stl %r1,%0"
5060   [(set_attr "type" "ilog,ild,ist")])
5061
5062 (define_insn "*movdf_nofix"
5063   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
5064         (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
5065   "TARGET_FPREGS && ! TARGET_FIX
5066    && (register_operand (operands[0], DFmode)
5067        || reg_or_fp0_operand (operands[1], DFmode))"
5068   "@
5069    cpys %R1,%R1,%0
5070    ld%- %0,%1
5071    bis $31,%r1,%0
5072    ldq %0,%1
5073    st%- %R1,%0
5074    stq %r1,%0"
5075   [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
5076
5077 (define_insn "*movdf_fix"
5078   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
5079         (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
5080   "TARGET_FPREGS && TARGET_FIX
5081    && (register_operand (operands[0], DFmode)
5082        || reg_or_fp0_operand (operands[1], DFmode))"
5083   "@
5084    cpys %R1,%R1,%0
5085    ld%- %0,%1
5086    bis $31,%r1,%0
5087    ldq %0,%1
5088    st%- %R1,%0
5089    stq %r1,%0
5090    itoft %1,%0
5091    ftoit %1,%0"
5092   [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
5093
5094 (define_insn "*movdf_nofp"
5095   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
5096         (match_operand:DF 1 "input_operand" "rG,m,r"))]
5097   "! TARGET_FPREGS
5098    && (register_operand (operands[0], DFmode)
5099        || reg_or_fp0_operand (operands[1], DFmode))"
5100   "@
5101    bis $31,%r1,%0
5102    ldq %0,%1
5103    stq %r1,%0"
5104   [(set_attr "type" "ilog,ild,ist")])
5105
5106 ;; Subregs suck for register allocation.  Pretend we can move TFmode
5107 ;; data between general registers until after reload.
5108
5109 (define_insn_and_split "*movtf_internal"
5110   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
5111         (match_operand:TF 1 "input_operand" "roG,rG"))]
5112   "register_operand (operands[0], TFmode)
5113    || reg_or_fp0_operand (operands[1], TFmode)"
5114   "#"
5115   "reload_completed"
5116   [(set (match_dup 0) (match_dup 2))
5117    (set (match_dup 1) (match_dup 3))]
5118 {
5119   alpha_split_tfmode_pair (operands);
5120   if (reg_overlap_mentioned_p (operands[0], operands[3]))
5121     {
5122       rtx tmp;
5123       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
5124       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
5125     }
5126 })
5127
5128 (define_expand "movsf"
5129   [(set (match_operand:SF 0 "nonimmediate_operand" "")
5130         (match_operand:SF 1 "general_operand" ""))]
5131   ""
5132 {
5133   if (GET_CODE (operands[0]) == MEM
5134       && ! reg_or_fp0_operand (operands[1], SFmode))
5135     operands[1] = force_reg (SFmode, operands[1]);
5136 })
5137
5138 (define_expand "movdf"
5139   [(set (match_operand:DF 0 "nonimmediate_operand" "")
5140         (match_operand:DF 1 "general_operand" ""))]
5141   ""
5142 {
5143   if (GET_CODE (operands[0]) == MEM
5144       && ! reg_or_fp0_operand (operands[1], DFmode))
5145     operands[1] = force_reg (DFmode, operands[1]);
5146 })
5147
5148 (define_expand "movtf"
5149   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5150         (match_operand:TF 1 "general_operand" ""))]
5151   ""
5152 {
5153   if (GET_CODE (operands[0]) == MEM
5154       && ! reg_or_fp0_operand (operands[1], TFmode))
5155     operands[1] = force_reg (TFmode, operands[1]);
5156 })
5157
5158 (define_insn "*movsi_nofix"
5159   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
5160         (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
5161   "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) && ! TARGET_FIX
5162    && (register_operand (operands[0], SImode)
5163        || reg_or_0_operand (operands[1], SImode))"
5164   "@
5165    bis $31,%r1,%0
5166    lda %0,%1($31)
5167    ldah %0,%h1($31)
5168    ldl %0,%1
5169    stl %r1,%0
5170    cpys %R1,%R1,%0
5171    ld%, %0,%1
5172    st%, %R1,%0"
5173   [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
5174
5175 (define_insn "*movsi_fix"
5176   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
5177         (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
5178   "TARGET_ABI_OSF && TARGET_FIX
5179    && (register_operand (operands[0], SImode)
5180        || reg_or_0_operand (operands[1], SImode))"
5181   "@
5182    bis $31,%r1,%0
5183    lda %0,%1($31)
5184    ldah %0,%h1($31)
5185    ldl %0,%1
5186    stl %r1,%0
5187    cpys %R1,%R1,%0
5188    ld%, %0,%1
5189    st%, %R1,%0
5190    ftois %1,%0
5191    itofs %1,%0"
5192   [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
5193
5194 (define_insn "*movsi_nt_vms"
5195   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
5196         (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
5197   "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
5198     && (register_operand (operands[0], SImode)
5199         || reg_or_0_operand (operands[1], SImode))"
5200   "@
5201    bis $31,%1,%0
5202    lda %0,%1
5203    ldah %0,%h1
5204    lda %0,%1
5205    ldl %0,%1
5206    stl %r1,%0
5207    cpys %R1,%R1,%0
5208    ld%, %0,%1
5209    st%, %R1,%0"
5210   [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
5211
5212 (define_insn "*movhi_nobwx"
5213   [(set (match_operand:HI 0 "register_operand" "=r,r")
5214         (match_operand:HI 1 "input_operand" "rJ,n"))]
5215   "! TARGET_BWX
5216    && (register_operand (operands[0], HImode)
5217        || register_operand (operands[1], HImode))"
5218   "@
5219    bis $31,%r1,%0
5220    lda %0,%L1($31)"
5221   [(set_attr "type" "ilog,iadd")])
5222
5223 (define_insn "*movhi_bwx"
5224   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
5225         (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
5226   "TARGET_BWX
5227    && (register_operand (operands[0], HImode)
5228        || reg_or_0_operand (operands[1], HImode))"
5229   "@
5230    bis $31,%r1,%0
5231    lda %0,%L1($31)
5232    ldwu %0,%1
5233    stw %r1,%0"
5234   [(set_attr "type" "ilog,iadd,ild,ist")])
5235
5236 (define_insn "*movqi_nobwx"
5237   [(set (match_operand:QI 0 "register_operand" "=r,r")
5238         (match_operand:QI 1 "input_operand" "rJ,n"))]
5239   "! TARGET_BWX
5240    && (register_operand (operands[0], QImode)
5241        || register_operand (operands[1], QImode))"
5242   "@
5243    bis $31,%r1,%0
5244    lda %0,%L1($31)"
5245   [(set_attr "type" "ilog,iadd")])
5246
5247 (define_insn "*movqi_bwx"
5248   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
5249         (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
5250   "TARGET_BWX
5251    && (register_operand (operands[0], QImode)
5252        || reg_or_0_operand (operands[1], QImode))"
5253   "@
5254    bis $31,%r1,%0
5255    lda %0,%L1($31)
5256    ldbu %0,%1
5257    stb %r1,%0"
5258   [(set_attr "type" "ilog,iadd,ild,ist")])
5259
5260 ;; We do two major things here: handle mem->mem and construct long
5261 ;; constants.
5262
5263 (define_expand "movsi"
5264   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5265         (match_operand:SI 1 "general_operand" ""))]
5266   ""
5267 {
5268   if (alpha_expand_mov (SImode, operands))
5269     DONE;
5270 })
5271
5272 ;; Split a load of a large constant into the appropriate two-insn
5273 ;; sequence.
5274
5275 (define_split
5276   [(set (match_operand:SI 0 "register_operand" "")
5277         (match_operand:SI 1 "const_int_operand" ""))]
5278   "! add_operand (operands[1], SImode)"
5279   [(set (match_dup 0) (match_dup 2))
5280    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
5281 {
5282   rtx tem
5283     = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
5284
5285   if (tem == operands[0])
5286     DONE;
5287   else
5288     FAIL;
5289 })
5290
5291 ;; Split the load of an address into a four-insn sequence on Unicos/Mk.
5292 ;; Always generate a REG_EQUAL note for the last instruction to facilitate
5293 ;; optimisations. If the symbolic operand is a label_ref, generate REG_LABEL
5294 ;; notes and update LABEL_NUSES because this is not done automatically.
5295 ;; Labels may be incorrectly deleted if we don't do this.
5296 ;;
5297 ;; Describing what the individual instructions do correctly is too complicated
5298 ;; so use UNSPECs for each of the three parts of an address.
5299
5300 (define_split
5301   [(set (match_operand:DI 0 "register_operand" "")
5302         (match_operand:DI 1 "symbolic_operand" ""))]
5303   "TARGET_ABI_UNICOSMK && reload_completed"
5304   [(const_int 0)]
5305 {
5306   rtx insn1, insn2, insn3;
5307
5308   insn1 = emit_insn (gen_umk_laum (operands[0], operands[1]));
5309   emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5310   insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1]));
5311   insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1]));
5312   REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5313                                          REG_NOTES (insn3));
5314   if (GET_CODE (operands[1]) == LABEL_REF)
5315     {
5316       rtx label;
5317
5318       label = XEXP (operands[1], 0);
5319       REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL, label,
5320                                              REG_NOTES (insn1));
5321       REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL, label,
5322                                              REG_NOTES (insn2));
5323       REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL, label,
5324                                              REG_NOTES (insn3));
5325       LABEL_NUSES (label) += 3;
5326     }
5327   DONE;
5328 })
5329
5330 ;; Instructions for loading the three parts of an address on Unicos/Mk.
5331
5332 (define_insn "umk_laum"
5333   [(set (match_operand:DI 0 "register_operand" "=r")
5334         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
5335                    UNSPEC_UMK_LAUM))]
5336   "TARGET_ABI_UNICOSMK"
5337   "laum %r0,%t1($31)"
5338   [(set_attr "type" "iadd")])
5339
5340 (define_insn "umk_lalm"
5341   [(set (match_operand:DI 0 "register_operand" "=r")
5342         (plus:DI (match_operand:DI 1 "register_operand" "r")
5343                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
5344                             UNSPEC_UMK_LALM)))] 
5345   "TARGET_ABI_UNICOSMK"
5346   "lalm %r0,%t2(%r1)"
5347   [(set_attr "type" "iadd")])
5348
5349 (define_insn "umk_lal"
5350   [(set (match_operand:DI 0 "register_operand" "=r")
5351         (plus:DI (match_operand:DI 1 "register_operand" "r")
5352                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
5353                             UNSPEC_UMK_LAL)))]
5354   "TARGET_ABI_UNICOSMK"
5355   "lal %r0,%t2(%r1)"
5356   [(set_attr "type" "iadd")])
5357
5358 ;; Add a new call information word to the current function's list of CIWs
5359 ;; and load its index into $25. Doing it here ensures that the CIW will be
5360 ;; associated with the correct function even in the presence of inlining.
5361
5362 (define_insn "*umk_load_ciw"
5363   [(set (reg:DI 25)
5364         (unspec:DI [(match_operand 0 "" "")] UNSPEC_UMK_LOAD_CIW))]
5365   "TARGET_ABI_UNICOSMK"
5366 {
5367   operands[0] = unicosmk_add_call_info_word (operands[0]);
5368   return "lda $25,%0";
5369 }
5370   [(set_attr "type" "iadd")])
5371
5372 (define_insn "*movdi_er_low_l"
5373   [(set (match_operand:DI 0 "register_operand" "=r")
5374         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
5375                    (match_operand:DI 2 "local_symbolic_operand" "")))]
5376   "TARGET_EXPLICIT_RELOCS"
5377 {
5378   if (true_regnum (operands[1]) == 29)
5379     return "lda %0,%2(%1)\t\t!gprel";
5380   else
5381     return "lda %0,%2(%1)\t\t!gprellow";
5382 })
5383
5384 (define_insn "movdi_er_high_g"
5385   [(set (match_operand:DI 0 "register_operand" "=r")
5386         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5387                     (match_operand:DI 2 "global_symbolic_operand" "")
5388                     (match_operand 3 "const_int_operand" "")]
5389                    UNSPEC_LITERAL))]
5390   "TARGET_EXPLICIT_RELOCS"
5391   "ldq %0,%2(%1)\t\t!literal"
5392   [(set_attr "type" "ldsym")])
5393
5394 (define_insn "*movdi_er_nofix"
5395   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q")
5396         (match_operand:DI 1 "input_operand" "rJ,K,L,T,m,rJ,*fJ,Q,*f"))]
5397   "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
5398    && (register_operand (operands[0], DImode)
5399        || reg_or_0_operand (operands[1], DImode))"
5400   "@
5401    mov %r1,%0
5402    lda %0,%1($31)
5403    ldah %0,%h1($31)
5404    ldah %0,%H1
5405    ldq%A1 %0,%1
5406    stq%A0 %r1,%0
5407    fmov %R1,%0
5408    ldt %0,%1
5409    stt %R1,%0"
5410   [(set_attr "type" "ilog,iadd,iadd,iadd,ild,ist,fcpys,fld,fst")])
5411
5412 ;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
5413 ;; have been split up by the rules above but we shouldn't reject the
5414 ;; possibility of them getting through.
5415
5416 (define_insn "*movdi_nofix"
5417   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
5418         (match_operand:DI 1 "input_operand" "rJ,K,L,U,s,m,rJ,*fJ,Q,*f"))]
5419   "! TARGET_FIX
5420    && (register_operand (operands[0], DImode)
5421        || reg_or_0_operand (operands[1], DImode))"
5422   "@
5423    bis $31,%r1,%0
5424    lda %0,%1($31)
5425    ldah %0,%h1($31)
5426    laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0)
5427    lda %0,%1
5428    ldq%A1 %0,%1
5429    stq%A0 %r1,%0
5430    cpys %R1,%R1,%0
5431    ldt %0,%1
5432    stt %R1,%0"
5433   [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,ild,ist,fcpys,fld,fst")
5434    (set_attr "length" "*,*,*,16,*,*,*,*,*,*")])
5435
5436 (define_insn "*movdi_er_fix"
5437   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
5438         (match_operand:DI 1 "input_operand" "rJ,K,L,T,m,rJ,*fJ,Q,*f,*f,r"))]
5439   "TARGET_EXPLICIT_RELOCS && TARGET_FIX
5440    && (register_operand (operands[0], DImode)
5441        || reg_or_0_operand (operands[1], DImode))"
5442   "@
5443    mov %r1,%0
5444    lda %0,%1($31)
5445    ldah %0,%h1($31)
5446    ldah %0,%H1
5447    ldq%A1 %0,%1
5448    stq%A0 %r1,%0
5449    fmov %R1,%0
5450    ldt %0,%1
5451    stt %R1,%0
5452    ftoit %1,%0
5453    itoft %1,%0"
5454   [(set_attr "type" "ilog,iadd,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
5455
5456 (define_insn "*movdi_fix"
5457   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
5458         (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
5459   "! TARGET_EXPLICIT_RELOCS && TARGET_FIX
5460    && (register_operand (operands[0], DImode)
5461        || reg_or_0_operand (operands[1], DImode))"
5462   "@
5463    bis $31,%r1,%0
5464    lda %0,%1($31)
5465    ldah %0,%h1($31)
5466    lda %0,%1
5467    ldq%A1 %0,%1
5468    stq%A0 %r1,%0
5469    cpys %R1,%R1,%0
5470    ldt %0,%1
5471    stt %R1,%0
5472    ftoit %1,%0
5473    itoft %1,%0"
5474   [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
5475
5476 ;; VMS needs to set up "vms_base_regno" for unwinding.  This move
5477 ;; often appears dead to the life analysis code, at which point we
5478 ;; abort for emitting dead prologue instructions.  Force this live.
5479
5480 (define_insn "force_movdi"
5481   [(set (match_operand:DI 0 "register_operand" "=r")
5482         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
5483                             UNSPECV_FORCE_MOV))]
5484   ""
5485   "mov %1,%0"
5486   [(set_attr "type" "ilog")])
5487
5488 ;; We do three major things here: handle mem->mem, put 64-bit constants in
5489 ;; memory, and construct long 32-bit constants.
5490
5491 (define_expand "movdi"
5492   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5493         (match_operand:DI 1 "general_operand" ""))]
5494   ""
5495 {
5496   if (alpha_expand_mov (DImode, operands))
5497     DONE;
5498 })
5499
5500 ;; Split a load of a large constant into the appropriate two-insn
5501 ;; sequence.
5502
5503 (define_split
5504   [(set (match_operand:DI 0 "register_operand" "")
5505         (match_operand:DI 1 "const_int_operand" ""))]
5506   "! add_operand (operands[1], DImode)"
5507   [(set (match_dup 0) (match_dup 2))
5508    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
5509 {
5510   rtx tem
5511     = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
5512
5513   if (tem == operands[0])
5514     DONE;
5515   else
5516     FAIL;
5517 })
5518
5519 ;; These are the partial-word cases.
5520 ;;
5521 ;; First we have the code to load an aligned word.  Operand 0 is the register
5522 ;; in which to place the result.  It's mode is QImode or HImode.  Operand 1
5523 ;; is an SImode MEM at the low-order byte of the proper word.  Operand 2 is the
5524 ;; number of bits within the word that the value is.  Operand 3 is an SImode
5525 ;; scratch register.  If operand 0 is a hard register, operand 3 may be the
5526 ;; same register.  It is allowed to conflict with operand 1 as well.
5527
5528 (define_expand "aligned_loadqi"
5529   [(set (match_operand:SI 3 "register_operand" "")
5530         (match_operand:SI 1 "memory_operand" ""))
5531    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5532         (zero_extract:DI (subreg:DI (match_dup 3) 0)
5533                          (const_int 8)
5534                          (match_operand:DI 2 "const_int_operand" "")))]
5535
5536   ""
5537   "")
5538
5539 (define_expand "aligned_loadhi"
5540   [(set (match_operand:SI 3 "register_operand" "")
5541         (match_operand:SI 1 "memory_operand" ""))
5542    (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
5543         (zero_extract:DI (subreg:DI (match_dup 3) 0)
5544                          (const_int 16)
5545                          (match_operand:DI 2 "const_int_operand" "")))]
5546
5547   ""
5548   "")
5549
5550 ;; Similar for unaligned loads, where we use the sequence from the
5551 ;; Alpha Architecture manual. We have to distinguish between little-endian
5552 ;; and big-endian systems as the sequences are different.
5553 ;;
5554 ;; Operand 1 is the address.  Operands 2 and 3 are temporaries, where
5555 ;; operand 3 can overlap the input and output registers.
5556
5557 (define_expand "unaligned_loadqi"
5558   [(use (match_operand:QI 0 "register_operand" ""))
5559    (use (match_operand:DI 1 "address_operand" ""))
5560    (use (match_operand:DI 2 "register_operand" ""))
5561    (use (match_operand:DI 3 "register_operand" ""))]
5562   ""
5563 {
5564   if (WORDS_BIG_ENDIAN)
5565     emit_insn (gen_unaligned_loadqi_be (operands[0], operands[1],
5566                                         operands[2], operands[3]));
5567   else
5568     emit_insn (gen_unaligned_loadqi_le (operands[0], operands[1],
5569                                         operands[2], operands[3]));
5570   DONE;
5571 })
5572
5573 (define_expand "unaligned_loadqi_le"
5574   [(set (match_operand:DI 2 "register_operand" "")
5575         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5576                         (const_int -8))))
5577    (set (match_operand:DI 3 "register_operand" "")
5578         (match_dup 1))
5579    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5580         (zero_extract:DI (match_dup 2)
5581                          (const_int 8)
5582                          (ashift:DI (match_dup 3) (const_int 3))))]
5583   "! WORDS_BIG_ENDIAN"
5584   "")
5585
5586 (define_expand "unaligned_loadqi_be"
5587   [(set (match_operand:DI 2 "register_operand" "")
5588         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5589                         (const_int -8))))
5590    (set (match_operand:DI 3 "register_operand" "")
5591         (match_dup 1))
5592    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5593         (zero_extract:DI (match_dup 2)
5594                          (const_int 8)
5595                          (minus:DI
5596                            (const_int 56)
5597                            (ashift:DI (match_dup 3) (const_int 3)))))]
5598   "WORDS_BIG_ENDIAN"
5599   "")
5600
5601 (define_expand "unaligned_loadhi"
5602   [(use (match_operand:QI 0 "register_operand" ""))
5603    (use (match_operand:DI 1 "address_operand" ""))
5604    (use (match_operand:DI 2 "register_operand" ""))
5605    (use (match_operand:DI 3 "register_operand" ""))]
5606   ""
5607 {
5608   if (WORDS_BIG_ENDIAN)
5609     emit_insn (gen_unaligned_loadhi_be (operands[0], operands[1],
5610                                         operands[2], operands[3]));
5611   else
5612     emit_insn (gen_unaligned_loadhi_le (operands[0], operands[1],
5613                                         operands[2], operands[3]));
5614   DONE;
5615 })
5616
5617 (define_expand "unaligned_loadhi_le"
5618   [(set (match_operand:DI 2 "register_operand" "")
5619         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5620                         (const_int -8))))
5621    (set (match_operand:DI 3 "register_operand" "")
5622         (match_dup 1))
5623    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5624         (zero_extract:DI (match_dup 2)
5625                          (const_int 16)
5626                          (ashift:DI (match_dup 3) (const_int 3))))]
5627   "! WORDS_BIG_ENDIAN"
5628   "")
5629
5630 (define_expand "unaligned_loadhi_be"
5631   [(set (match_operand:DI 2 "register_operand" "")
5632         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5633                         (const_int -8))))
5634    (set (match_operand:DI 3 "register_operand" "")
5635         (plus:DI (match_dup 1) (const_int 1)))
5636    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5637         (zero_extract:DI (match_dup 2)
5638                          (const_int 16)
5639                          (minus:DI
5640                            (const_int 56)
5641                            (ashift:DI (match_dup 3) (const_int 3)))))]
5642   "WORDS_BIG_ENDIAN"
5643   "")
5644
5645 ;; Storing an aligned byte or word requires two temporaries.  Operand 0 is the
5646 ;; aligned SImode MEM.  Operand 1 is the register containing the
5647 ;; byte or word to store.  Operand 2 is the number of bits within the word that
5648 ;; the value should be placed.  Operands 3 and 4 are SImode temporaries.
5649
5650 (define_expand "aligned_store"
5651   [(set (match_operand:SI 3 "register_operand" "")
5652         (match_operand:SI 0 "memory_operand" ""))
5653    (set (subreg:DI (match_dup 3) 0)
5654         (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
5655    (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
5656         (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
5657                    (match_operand:DI 2 "const_int_operand" "")))
5658    (set (subreg:DI (match_dup 4) 0)
5659         (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
5660    (set (match_dup 0) (match_dup 4))]
5661   ""
5662 {
5663   operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
5664                             << INTVAL (operands[2])));
5665 })
5666
5667 ;; For the unaligned byte and halfword cases, we use code similar to that
5668 ;; in the ;; Architecture book, but reordered to lower the number of registers
5669 ;; required.  Operand 0 is the address.  Operand 1 is the data to store.
5670 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
5671 ;; be the same temporary, if desired.  If the address is in a register,
5672 ;; operand 2 can be that register.
5673
5674 (define_expand "unaligned_storeqi"
5675   [(use (match_operand:DI 0 "address_operand" ""))
5676    (use (match_operand:QI 1 "register_operand" ""))
5677    (use (match_operand:DI 2 "register_operand" ""))
5678    (use (match_operand:DI 3 "register_operand" ""))
5679    (use (match_operand:DI 4 "register_operand" ""))]
5680   ""
5681 {
5682   if (WORDS_BIG_ENDIAN)
5683     emit_insn (gen_unaligned_storeqi_be (operands[0], operands[1],
5684                                          operands[2], operands[3],
5685                                          operands[4]));
5686   else
5687     emit_insn (gen_unaligned_storeqi_le (operands[0], operands[1],
5688                                          operands[2], operands[3],
5689                                          operands[4]));
5690   DONE;
5691 })
5692
5693 (define_expand "unaligned_storeqi_le"
5694   [(set (match_operand:DI 3 "register_operand" "")
5695         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5696                         (const_int -8))))
5697    (set (match_operand:DI 2 "register_operand" "")
5698         (match_dup 0))
5699    (set (match_dup 3)
5700         (and:DI (not:DI (ashift:DI (const_int 255)
5701                                    (ashift:DI (match_dup 2) (const_int 3))))
5702                 (match_dup 3)))
5703    (set (match_operand:DI 4 "register_operand" "")
5704         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
5705                    (ashift:DI (match_dup 2) (const_int 3))))
5706    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5707    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5708         (match_dup 4))]
5709   "! WORDS_BIG_ENDIAN"
5710   "")
5711
5712 (define_expand "unaligned_storeqi_be"
5713   [(set (match_operand:DI 3 "register_operand" "")
5714         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5715                         (const_int -8))))
5716    (set (match_operand:DI 2 "register_operand" "")
5717         (match_dup 0))
5718    (set (match_dup 3)
5719         (and:DI (not:DI (ashift:DI (const_int 255)
5720                           (minus:DI (const_int 56)
5721                                     (ashift:DI (match_dup 2) (const_int 3)))))
5722                 (match_dup 3)))
5723    (set (match_operand:DI 4 "register_operand" "")
5724         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
5725                    (minus:DI (const_int 56)
5726                      (ashift:DI (match_dup 2) (const_int 3)))))
5727    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5728    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5729         (match_dup 4))]
5730   "WORDS_BIG_ENDIAN"
5731   "")
5732
5733 (define_expand "unaligned_storehi"
5734   [(use (match_operand:DI 0 "address_operand" ""))
5735    (use (match_operand:HI 1 "register_operand" ""))
5736    (use (match_operand:DI 2 "register_operand" ""))
5737    (use (match_operand:DI 3 "register_operand" ""))
5738    (use (match_operand:DI 4 "register_operand" ""))]
5739   ""
5740 {
5741   if (WORDS_BIG_ENDIAN)
5742     emit_insn (gen_unaligned_storehi_be (operands[0], operands[1],
5743                                          operands[2], operands[3],
5744                                          operands[4]));
5745   else
5746     emit_insn (gen_unaligned_storehi_le (operands[0], operands[1],
5747                                          operands[2], operands[3],
5748                                          operands[4]));
5749   DONE;
5750 })
5751
5752 (define_expand "unaligned_storehi_le"
5753   [(set (match_operand:DI 3 "register_operand" "")
5754         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5755                         (const_int -8))))
5756    (set (match_operand:DI 2 "register_operand" "")
5757         (match_dup 0))
5758    (set (match_dup 3)
5759         (and:DI (not:DI (ashift:DI (const_int 65535)
5760                                    (ashift:DI (match_dup 2) (const_int 3))))
5761                 (match_dup 3)))
5762    (set (match_operand:DI 4 "register_operand" "")
5763         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
5764                    (ashift:DI (match_dup 2) (const_int 3))))
5765    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5766    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5767         (match_dup 4))]
5768   "! WORDS_BIG_ENDIAN"
5769   "")
5770
5771 (define_expand "unaligned_storehi_be"
5772   [(set (match_operand:DI 3 "register_operand" "")
5773         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5774                         (const_int -8))))
5775    (set (match_operand:DI 2 "register_operand" "")
5776         (plus:DI (match_dup 0) (const_int 1)))
5777    (set (match_dup 3)
5778         (and:DI (not:DI (ashift:DI
5779                           (const_int 65535)
5780                           (minus:DI (const_int 56)
5781                                     (ashift:DI (match_dup 2) (const_int 3)))))
5782                 (match_dup 3)))
5783    (set (match_operand:DI 4 "register_operand" "")
5784         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
5785                    (minus:DI (const_int 56)
5786                              (ashift:DI (match_dup 2) (const_int 3)))))
5787    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5788    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5789         (match_dup 4))]
5790   "WORDS_BIG_ENDIAN"
5791   "")
5792 \f
5793 ;; Here are the define_expand's for QI and HI moves that use the above
5794 ;; patterns.  We have the normal sets, plus the ones that need scratch
5795 ;; registers for reload.
5796
5797 (define_expand "movqi"
5798   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5799         (match_operand:QI 1 "general_operand" ""))]
5800   ""
5801 {
5802   if (TARGET_BWX
5803       ? alpha_expand_mov (QImode, operands)
5804       : alpha_expand_mov_nobwx (QImode, operands))
5805     DONE;
5806 })
5807
5808 (define_expand "movhi"
5809   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5810         (match_operand:HI 1 "general_operand" ""))]
5811   ""
5812 {
5813   if (TARGET_BWX
5814       ? alpha_expand_mov (HImode, operands)
5815       : alpha_expand_mov_nobwx (HImode, operands))
5816     DONE;
5817 })
5818
5819 ;; Here are the versions for reload.  Note that in the unaligned cases
5820 ;; we know that the operand must not be a pseudo-register because stack
5821 ;; slots are always aligned references.
5822
5823 (define_expand "reload_inqi"
5824   [(parallel [(match_operand:QI 0 "register_operand" "=r")
5825               (match_operand:QI 1 "any_memory_operand" "m")
5826               (match_operand:TI 2 "register_operand" "=&r")])]
5827   "! TARGET_BWX"
5828 {
5829   rtx scratch, seq;
5830
5831   if (GET_CODE (operands[1]) != MEM)
5832     abort ();
5833
5834   if (aligned_memory_operand (operands[1], QImode))
5835     {
5836       seq = gen_reload_inqi_help (operands[0], operands[1],
5837                                   gen_rtx_REG (SImode, REGNO (operands[2])));
5838     }
5839   else
5840     {
5841       rtx addr;
5842
5843       /* It is possible that one of the registers we got for operands[2]
5844          might coincide with that of operands[0] (which is why we made
5845          it TImode).  Pick the other one to use as our scratch.  */
5846       if (REGNO (operands[0]) == REGNO (operands[2]))
5847         scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5848       else
5849         scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5850
5851       addr = get_unaligned_address (operands[1], 0);
5852       seq = gen_unaligned_loadqi (operands[0], addr, scratch,
5853                           gen_rtx_REG (DImode, REGNO (operands[0])));
5854       alpha_set_memflags (seq, operands[1]);
5855     }
5856   emit_insn (seq);
5857   DONE;
5858 })
5859
5860 (define_expand "reload_inhi"
5861   [(parallel [(match_operand:HI 0 "register_operand" "=r")
5862               (match_operand:HI 1 "any_memory_operand" "m")
5863               (match_operand:TI 2 "register_operand" "=&r")])]
5864   "! TARGET_BWX"
5865 {
5866   rtx scratch, seq;
5867
5868   if (GET_CODE (operands[1]) != MEM)
5869     abort ();
5870
5871   if (aligned_memory_operand (operands[1], HImode))
5872     {
5873       seq = gen_reload_inhi_help (operands[0], operands[1],
5874                                   gen_rtx_REG (SImode, REGNO (operands[2])));
5875     }
5876   else
5877     {
5878       rtx addr;
5879
5880       /* It is possible that one of the registers we got for operands[2]
5881          might coincide with that of operands[0] (which is why we made
5882          it TImode).  Pick the other one to use as our scratch.  */
5883       if (REGNO (operands[0]) == REGNO (operands[2]))
5884         scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5885       else
5886         scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5887
5888       addr = get_unaligned_address (operands[1], 0);
5889       seq = gen_unaligned_loadhi (operands[0], addr, scratch,
5890                           gen_rtx_REG (DImode, REGNO (operands[0])));
5891       alpha_set_memflags (seq, operands[1]);
5892     }
5893   emit_insn (seq);
5894   DONE;
5895 })
5896
5897 (define_expand "reload_outqi"
5898   [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
5899               (match_operand:QI 1 "register_operand" "r")
5900               (match_operand:TI 2 "register_operand" "=&r")])]
5901   "! TARGET_BWX"
5902 {
5903   if (GET_CODE (operands[0]) != MEM)
5904     abort ();
5905
5906   if (aligned_memory_operand (operands[0], QImode))
5907     {
5908       emit_insn (gen_reload_outqi_help
5909                  (operands[0], operands[1],
5910                   gen_rtx_REG (SImode, REGNO (operands[2])),
5911                   gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
5912     }
5913   else
5914     {
5915       rtx addr = get_unaligned_address (operands[0], 0);
5916       rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
5917       rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5918       rtx scratch3 = scratch1;
5919       rtx seq;
5920
5921       if (GET_CODE (addr) == REG)
5922         scratch1 = addr;
5923
5924       seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
5925                                    scratch2, scratch3);
5926       alpha_set_memflags (seq, operands[0]);
5927       emit_insn (seq);
5928     }
5929   DONE;
5930 })
5931
5932 (define_expand "reload_outhi"
5933   [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
5934               (match_operand:HI 1 "register_operand" "r")
5935               (match_operand:TI 2 "register_operand" "=&r")])]
5936   "! TARGET_BWX"
5937 {
5938   if (GET_CODE (operands[0]) != MEM)
5939     abort ();
5940
5941   if (aligned_memory_operand (operands[0], HImode))
5942     {
5943       emit_insn (gen_reload_outhi_help
5944                  (operands[0], operands[1],
5945                   gen_rtx_REG (SImode, REGNO (operands[2])),
5946                   gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
5947     }
5948   else
5949     {
5950       rtx addr = get_unaligned_address (operands[0], 0);
5951       rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
5952       rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5953       rtx scratch3 = scratch1;
5954       rtx seq;
5955
5956       if (GET_CODE (addr) == REG)
5957         scratch1 = addr;
5958
5959       seq = gen_unaligned_storehi (addr, operands[1], scratch1,
5960                                    scratch2, scratch3);
5961       alpha_set_memflags (seq, operands[0]);
5962       emit_insn (seq);
5963     }
5964   DONE;
5965 })
5966
5967 ;; Helpers for the above.  The way reload is structured, we can't
5968 ;; always get a proper address for a stack slot during reload_foo
5969 ;; expansion, so we must delay our address manipulations until after.
5970
5971 (define_insn "reload_inqi_help"
5972   [(set (match_operand:QI 0 "register_operand" "=r")
5973         (match_operand:QI 1 "memory_operand" "m"))
5974    (clobber (match_operand:SI 2 "register_operand" "=r"))]
5975   "! TARGET_BWX && (reload_in_progress || reload_completed)"
5976   "#")
5977
5978 (define_insn "reload_inhi_help"
5979   [(set (match_operand:HI 0 "register_operand" "=r")
5980         (match_operand:HI 1 "memory_operand" "m"))
5981    (clobber (match_operand:SI 2 "register_operand" "=r"))]
5982   "! TARGET_BWX && (reload_in_progress || reload_completed)"
5983   "#")
5984
5985 (define_insn "reload_outqi_help"
5986   [(set (match_operand:QI 0 "memory_operand" "=m")
5987         (match_operand:QI 1 "register_operand" "r"))
5988    (clobber (match_operand:SI 2 "register_operand" "=r"))
5989    (clobber (match_operand:SI 3 "register_operand" "=r"))]
5990   "! TARGET_BWX && (reload_in_progress || reload_completed)"
5991   "#")
5992
5993 (define_insn "reload_outhi_help"
5994   [(set (match_operand:HI 0 "memory_operand" "=m")
5995         (match_operand:HI 1 "register_operand" "r"))
5996    (clobber (match_operand:SI 2 "register_operand" "=r"))
5997    (clobber (match_operand:SI 3 "register_operand" "=r"))]
5998   "! TARGET_BWX && (reload_in_progress || reload_completed)"
5999   "#")
6000
6001 (define_split
6002   [(set (match_operand:QI 0 "register_operand" "")
6003         (match_operand:QI 1 "memory_operand" ""))
6004    (clobber (match_operand:SI 2 "register_operand" ""))]
6005   "! TARGET_BWX && reload_completed"
6006   [(const_int 0)]
6007 {
6008   rtx aligned_mem, bitnum;
6009   get_aligned_mem (operands[1], &aligned_mem, &bitnum);
6010
6011   emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
6012                                  operands[2]));
6013   DONE;
6014 })
6015
6016 (define_split
6017   [(set (match_operand:HI 0 "register_operand" "")
6018         (match_operand:HI 1 "memory_operand" ""))
6019    (clobber (match_operand:SI 2 "register_operand" ""))]
6020   "! TARGET_BWX && reload_completed"
6021   [(const_int 0)]
6022 {
6023   rtx aligned_mem, bitnum;
6024   get_aligned_mem (operands[1], &aligned_mem, &bitnum);
6025
6026   emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
6027                                  operands[2]));
6028   DONE;
6029 })
6030
6031 (define_split
6032   [(set (match_operand:QI 0 "memory_operand" "")
6033         (match_operand:QI 1 "register_operand" ""))
6034    (clobber (match_operand:SI 2 "register_operand" ""))
6035    (clobber (match_operand:SI 3 "register_operand" ""))]
6036   "! TARGET_BWX && reload_completed"
6037   [(const_int 0)]
6038 {
6039   rtx aligned_mem, bitnum;
6040   get_aligned_mem (operands[0], &aligned_mem, &bitnum);
6041   emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
6042                                 operands[2], operands[3]));
6043   DONE;
6044 })
6045
6046 (define_split
6047   [(set (match_operand:HI 0 "memory_operand" "")
6048         (match_operand:HI 1 "register_operand" ""))
6049    (clobber (match_operand:SI 2 "register_operand" ""))
6050    (clobber (match_operand:SI 3 "register_operand" ""))]
6051   "! TARGET_BWX && reload_completed"
6052   [(const_int 0)]
6053 {
6054   rtx aligned_mem, bitnum;
6055   get_aligned_mem (operands[0], &aligned_mem, &bitnum);
6056   emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
6057                                 operands[2], operands[3]));
6058   DONE;
6059 })
6060 \f
6061 ;; Bit field extract patterns which use ext[wlq][lh]
6062
6063 (define_expand "extv"
6064   [(set (match_operand:DI 0 "register_operand" "")
6065         (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
6066                          (match_operand:DI 2 "immediate_operand" "")
6067                          (match_operand:DI 3 "immediate_operand" "")))]
6068   ""
6069 {
6070   int ofs;
6071
6072   /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
6073   if (INTVAL (operands[3]) % 8 != 0
6074       || (INTVAL (operands[2]) != 16
6075           && INTVAL (operands[2]) != 32
6076           && INTVAL (operands[2]) != 64))
6077     FAIL;
6078
6079   /* From mips.md: extract_bit_field doesn't verify that our source
6080      matches the predicate, so we force it to be a MEM here.  */
6081   if (GET_CODE (operands[1]) != MEM)
6082     FAIL;
6083
6084   /* The bit number is relative to the mode of operand 1 which is
6085      usually QImode (this might actually be a bug in expmed.c). Note 
6086      that the bit number is negative in big-endian mode in this case.
6087      We have to convert that to the offset.  */
6088   if (WORDS_BIG_ENDIAN)
6089     ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
6090           - INTVAL (operands[2]) - INTVAL (operands[3]);
6091   else
6092     ofs = INTVAL (operands[3]);
6093
6094   ofs = ofs / 8;
6095
6096   alpha_expand_unaligned_load (operands[0], operands[1],
6097                                INTVAL (operands[2]) / 8,
6098                                ofs, 1);
6099   DONE;
6100 })
6101
6102 (define_expand "extzv"
6103   [(set (match_operand:DI 0 "register_operand" "")
6104         (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
6105                          (match_operand:DI 2 "immediate_operand" "")
6106                          (match_operand:DI 3 "immediate_operand" "")))]
6107   ""
6108 {
6109   /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
6110   if (INTVAL (operands[3]) % 8 != 0
6111       || (INTVAL (operands[2]) != 8
6112           && INTVAL (operands[2]) != 16
6113           && INTVAL (operands[2]) != 32
6114           && INTVAL (operands[2]) != 64))
6115     FAIL;
6116
6117   if (GET_CODE (operands[1]) == MEM)
6118     {
6119       int ofs;
6120
6121       /* Fail 8 bit fields, falling back on a simple byte load.  */
6122       if (INTVAL (operands[2]) == 8)
6123         FAIL;
6124
6125       /* The bit number is relative to the mode of operand 1 which is
6126          usually QImode (this might actually be a bug in expmed.c). Note 
6127          that the bit number is negative in big-endian mode in this case.
6128          We have to convert that to the offset.  */
6129       if (WORDS_BIG_ENDIAN)
6130         ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
6131               - INTVAL (operands[2]) - INTVAL (operands[3]);
6132       else
6133         ofs = INTVAL (operands[3]);
6134
6135       ofs = ofs / 8;
6136
6137       alpha_expand_unaligned_load (operands[0], operands[1],
6138                                    INTVAL (operands[2]) / 8,
6139                                    ofs, 0);
6140       DONE;
6141     }
6142 })
6143
6144 (define_expand "insv"
6145   [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
6146                          (match_operand:DI 1 "immediate_operand" "")
6147                          (match_operand:DI 2 "immediate_operand" ""))
6148         (match_operand:DI 3 "register_operand" ""))]
6149   ""
6150 {
6151   int ofs;
6152
6153   /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
6154   if (INTVAL (operands[2]) % 8 != 0
6155       || (INTVAL (operands[1]) != 16
6156           && INTVAL (operands[1]) != 32
6157           && INTVAL (operands[1]) != 64))
6158     FAIL;
6159
6160   /* From mips.md: store_bit_field doesn't verify that our source
6161      matches the predicate, so we force it to be a MEM here.  */
6162   if (GET_CODE (operands[0]) != MEM)
6163     FAIL;
6164
6165   /* The bit number is relative to the mode of operand 1 which is
6166      usually QImode (this might actually be a bug in expmed.c). Note 
6167      that the bit number is negative in big-endian mode in this case.
6168      We have to convert that to the offset.  */
6169   if (WORDS_BIG_ENDIAN)
6170     ofs = GET_MODE_BITSIZE (GET_MODE (operands[0]))
6171           - INTVAL (operands[1]) - INTVAL (operands[2]);
6172   else
6173     ofs = INTVAL (operands[2]);
6174
6175   ofs = ofs / 8;
6176
6177   alpha_expand_unaligned_store (operands[0], operands[3],
6178                                 INTVAL (operands[1]) / 8, ofs);
6179   DONE;
6180 })
6181
6182 ;; Block move/clear, see alpha.c for more details.
6183 ;; Argument 0 is the destination
6184 ;; Argument 1 is the source
6185 ;; Argument 2 is the length
6186 ;; Argument 3 is the alignment
6187
6188 (define_expand "movstrqi"
6189   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6190                    (match_operand:BLK 1 "memory_operand" ""))
6191               (use (match_operand:DI 2 "immediate_operand" ""))
6192               (use (match_operand:DI 3 "immediate_operand" ""))])]
6193   ""
6194 {
6195   if (alpha_expand_block_move (operands))
6196     DONE;
6197   else
6198     FAIL;
6199 })
6200
6201 (define_expand "clrstrqi"
6202   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6203                    (const_int 0))
6204               (use (match_operand:DI 1 "immediate_operand" ""))
6205               (use (match_operand:DI 2 "immediate_operand" ""))])]
6206   ""
6207 {
6208   if (alpha_expand_block_clear (operands))
6209     DONE;
6210   else
6211     FAIL;
6212 })
6213 \f
6214 ;; Subroutine of stack space allocation.  Perform a stack probe.
6215 (define_expand "probe_stack"
6216   [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
6217   ""
6218 {
6219   operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
6220                                                     INTVAL (operands[0])));
6221   MEM_VOLATILE_P (operands[1]) = 1;
6222
6223   operands[0] = const0_rtx;
6224 })
6225
6226 ;; This is how we allocate stack space.  If we are allocating a
6227 ;; constant amount of space and we know it is less than 4096
6228 ;; bytes, we need do nothing.
6229 ;;
6230 ;; If it is more than 4096 bytes, we need to probe the stack
6231 ;; periodically.
6232 (define_expand "allocate_stack"
6233   [(set (reg:DI 30)
6234         (plus:DI (reg:DI 30)
6235                  (match_operand:DI 1 "reg_or_cint_operand" "")))
6236    (set (match_operand:DI 0 "register_operand" "=r")
6237         (match_dup 2))]
6238   ""
6239 {
6240   if (GET_CODE (operands[1]) == CONST_INT
6241       && INTVAL (operands[1]) < 32768)
6242     {
6243       if (INTVAL (operands[1]) >= 4096)
6244         {
6245           /* We do this the same way as in the prologue and generate explicit
6246              probes.  Then we update the stack by the constant.  */
6247
6248           int probed = 4096;
6249
6250           emit_insn (gen_probe_stack (GEN_INT (- probed)));
6251           while (probed + 8192 < INTVAL (operands[1]))
6252             emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
6253
6254           if (probed + 4096 < INTVAL (operands[1]))
6255             emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
6256         }
6257
6258       operands[1] = GEN_INT (- INTVAL (operands[1]));
6259       operands[2] = virtual_stack_dynamic_rtx;
6260     }
6261   else
6262     {
6263       rtx out_label = 0;
6264       rtx loop_label = gen_label_rtx ();
6265       rtx want = gen_reg_rtx (Pmode);
6266       rtx tmp = gen_reg_rtx (Pmode);
6267       rtx memref;
6268
6269       emit_insn (gen_subdi3 (want, stack_pointer_rtx,
6270                              force_reg (Pmode, operands[1])));
6271       emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
6272
6273       if (GET_CODE (operands[1]) != CONST_INT)
6274         {
6275           out_label = gen_label_rtx ();
6276           emit_insn (gen_cmpdi (want, tmp));
6277           emit_jump_insn (gen_bgeu (out_label));
6278         }
6279
6280       emit_label (loop_label);
6281       memref = gen_rtx_MEM (DImode, tmp);
6282       MEM_VOLATILE_P (memref) = 1;
6283       emit_move_insn (memref, const0_rtx);
6284       emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
6285       emit_insn (gen_cmpdi (tmp, want));
6286       emit_jump_insn (gen_bgtu (loop_label));
6287
6288       memref = gen_rtx_MEM (DImode, want);
6289       MEM_VOLATILE_P (memref) = 1;
6290       emit_move_insn (memref, const0_rtx);
6291
6292       if (out_label)
6293         emit_label (out_label);
6294
6295       emit_move_insn (stack_pointer_rtx, want);
6296       emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
6297       DONE;
6298     }
6299 })
6300
6301 ;; This is used by alpha_expand_prolog to do the same thing as above,
6302 ;; except we cannot at that time generate new basic blocks, so we hide
6303 ;; the loop in this one insn.
6304
6305 (define_insn "prologue_stack_probe_loop"
6306   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
6307                      (match_operand:DI 1 "register_operand" "r")]
6308                     UNSPECV_PSPL)]
6309   ""
6310 {
6311   operands[2] = gen_label_rtx ();
6312   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
6313                              CODE_LABEL_NUMBER (operands[2]));
6314
6315   return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
6316 }
6317   [(set_attr "length" "16")
6318    (set_attr "type" "multi")])
6319
6320 (define_expand "prologue"
6321   [(clobber (const_int 0))]
6322   ""
6323 {
6324   alpha_expand_prologue ();
6325   DONE;
6326 })
6327
6328 ;; These take care of emitting the ldgp insn in the prologue. This will be
6329 ;; an lda/ldah pair and we want to align them properly.  So we have two
6330 ;; unspec_volatile insns, the first of which emits the ldgp assembler macro
6331 ;; and the second of which emits nothing.  However, both are marked as type
6332 ;; IADD (the default) so the alignment code in alpha.c does the right thing
6333 ;; with them.
6334
6335 (define_expand "prologue_ldgp"
6336   [(set (match_dup 0)
6337         (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
6338    (set (match_dup 0)
6339         (unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
6340   ""
6341 {
6342   operands[0] = pic_offset_table_rtx;
6343   operands[1] = gen_rtx_REG (Pmode, 27);
6344   operands[2] = (TARGET_EXPLICIT_RELOCS
6345                  ? GEN_INT (alpha_next_sequence_number++)
6346                  : const0_rtx);
6347 })
6348
6349 (define_insn "*ldgp_er_1"
6350   [(set (match_operand:DI 0 "register_operand" "=r")
6351         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6352                              (match_operand 2 "const_int_operand" "")]
6353                             UNSPECV_LDGP1))]
6354   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6355   "ldah %0,0(%1)\t\t!gpdisp!%2")
6356
6357 (define_insn "*ldgp_er_2"
6358   [(set (match_operand:DI 0 "register_operand" "=r")
6359         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6360                     (match_operand 2 "const_int_operand" "")]
6361                    UNSPEC_LDGP2))]
6362   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6363   "lda %0,0(%1)\t\t!gpdisp!%2")
6364
6365 (define_insn "*prologue_ldgp_er_2"
6366   [(set (match_operand:DI 0 "register_operand" "=r")
6367         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6368                              (match_operand 2 "const_int_operand" "")]
6369                             UNSPECV_PLDGP2))]
6370   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6371   "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
6372
6373 (define_insn "*prologue_ldgp_1"
6374   [(set (match_operand:DI 0 "register_operand" "=r")
6375         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6376                              (match_operand 2 "const_int_operand" "")]
6377                             UNSPECV_LDGP1))]
6378   ""
6379   "ldgp %0,0(%1)\n$%~..ng:")
6380
6381 (define_insn "*prologue_ldgp_2"
6382   [(set (match_operand:DI 0 "register_operand" "=r")
6383         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6384                              (match_operand 2 "const_int_operand" "")]
6385                             UNSPECV_PLDGP2))]
6386   ""
6387   "")
6388
6389 ;; The _mcount profiling hook has special calling conventions, and
6390 ;; does not clobber all the registers that a normal call would.  So
6391 ;; hide the fact this is a call at all.
6392
6393 (define_insn "prologue_mcount"
6394   [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
6395   ""
6396   "lda $28,_mcount\;jsr $28,($28),_mcount"
6397   [(set_attr "type" "multi")
6398    (set_attr "length" "8")])
6399
6400 (define_insn "init_fp"
6401   [(set (match_operand:DI 0 "register_operand" "=r")
6402         (match_operand:DI 1 "register_operand" "r"))
6403    (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
6404   ""
6405   "bis $31,%1,%0")
6406
6407 (define_expand "epilogue"
6408   [(return)]
6409   ""
6410 {
6411   alpha_expand_epilogue ();
6412 })
6413
6414 (define_expand "sibcall_epilogue"
6415   [(return)]
6416   "TARGET_ABI_OSF"
6417 {
6418   alpha_expand_epilogue ();
6419   DONE;
6420 })
6421
6422 ;; In creating a large stack frame, NT _must_ use ldah+lda to load
6423 ;; the frame size into a register.  We use this pattern to ensure
6424 ;; we get lda instead of addq.
6425 (define_insn "nt_lda"
6426   [(set (match_operand:DI 0 "register_operand" "=r")
6427         (unspec:DI [(match_dup 0)
6428                     (match_operand:DI 1 "const_int_operand" "n")]
6429                    UNSPEC_NT_LDA))]
6430   ""
6431   "lda %0,%1(%0)")
6432
6433 (define_expand "builtin_longjmp"
6434   [(use (match_operand:DI 0 "register_operand" "r"))]
6435   "TARGET_ABI_OSF"
6436 {
6437   /* The elements of the buffer are, in order:  */
6438   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6439   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
6440   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
6441   rtx pv = gen_rtx_REG (Pmode, 27);
6442
6443   /* This bit is the same as expand_builtin_longjmp.  */
6444   emit_move_insn (hard_frame_pointer_rtx, fp);
6445   emit_move_insn (pv, lab);
6446   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6447   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6448   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6449
6450   /* Load the label we are jumping through into $27 so that we know
6451      where to look for it when we get back to setjmp's function for
6452      restoring the gp.  */
6453   emit_jump_insn (gen_builtin_longjmp_internal (pv));
6454   emit_barrier ();
6455   DONE;
6456 })
6457
6458 ;; This is effectively a copy of indirect_jump, but constrained such
6459 ;; that register renaming cannot foil our cunning plan with $27.
6460 (define_insn "builtin_longjmp_internal"
6461   [(set (pc)
6462         (unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
6463                          UNSPECV_LONGJMP))]
6464   ""
6465   "jmp $31,(%0),0"
6466   [(set_attr "type" "ibr")])
6467
6468 (define_insn "*builtin_setjmp_receiver_er_sl_1"
6469   [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6470   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
6471   "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
6472   
6473 (define_insn "*builtin_setjmp_receiver_er_1"
6474   [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6475   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6476   "br $27,$LSJ%=\n$LSJ%=:"
6477   [(set_attr "type" "ibr")])
6478
6479 (define_split
6480   [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6481   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
6482    && prev_nonnote_insn (insn) == operands[0]"
6483   [(const_int 0)]
6484   "DONE;")
6485
6486 (define_insn "*builtin_setjmp_receiver_1"
6487   [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6488   "TARGET_ABI_OSF"
6489   "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"
6490   [(set_attr "length" "12")
6491    (set_attr "type" "multi")])
6492
6493 (define_expand "builtin_setjmp_receiver_er"
6494   [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)
6495    (set (match_dup 1)
6496         (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
6497    (set (match_dup 1)
6498         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
6499   ""
6500 {
6501   operands[1] = pic_offset_table_rtx;
6502   operands[2] = gen_rtx_REG (Pmode, 27);
6503   operands[3] = GEN_INT (alpha_next_sequence_number++);
6504 })
6505
6506 (define_expand "builtin_setjmp_receiver"
6507   [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6508   "TARGET_ABI_OSF"
6509 {
6510   if (TARGET_EXPLICIT_RELOCS)
6511     {
6512       emit_insn (gen_builtin_setjmp_receiver_er (operands[0]));
6513       DONE;
6514     }
6515 })
6516
6517 (define_expand "exception_receiver_er"
6518   [(set (match_dup 0)
6519         (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
6520    (set (match_dup 0)
6521         (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
6522   ""
6523 {
6524   operands[0] = pic_offset_table_rtx;
6525   operands[1] = gen_rtx_REG (Pmode, 26);
6526   operands[2] = GEN_INT (alpha_next_sequence_number++);
6527 })
6528
6529 (define_expand "exception_receiver"
6530   [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
6531   "TARGET_ABI_OSF"
6532 {
6533   if (TARGET_LD_BUGGY_LDGP)
6534     operands[0] = alpha_gp_save_rtx ();
6535   else if (TARGET_EXPLICIT_RELOCS)
6536     {
6537       emit_insn (gen_exception_receiver_er ());
6538       DONE;
6539     }
6540   else
6541     operands[0] = const0_rtx;
6542 })
6543
6544 (define_insn "*exception_receiver_1"
6545   [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
6546   "! TARGET_LD_BUGGY_LDGP"
6547   "ldgp $29,0($26)"
6548   [(set_attr "length" "8")
6549    (set_attr "type" "multi")])
6550
6551 (define_insn "*exception_receiver_2"
6552   [(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")]
6553                     UNSPECV_EHR)]
6554   "TARGET_LD_BUGGY_LDGP"
6555   "@
6556    bis $31,%0,$29
6557    ldq $29,%0"
6558   [(set_attr "type" "ilog,ild")])
6559
6560 (define_expand "nonlocal_goto_receiver"
6561   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
6562    (set (reg:DI 27) (mem:DI (reg:DI 29)))
6563    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
6564    (use (reg:DI 27))]
6565   "TARGET_ABI_OPEN_VMS"
6566   "")
6567
6568 (define_insn "arg_home"
6569   [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
6570    (use (reg:DI 1))
6571    (use (reg:DI 25))
6572    (use (reg:DI 16))
6573    (use (reg:DI 17))
6574    (use (reg:DI 18))
6575    (use (reg:DI 19))
6576    (use (reg:DI 20))
6577    (use (reg:DI 21))
6578    (use (reg:DI 48))
6579    (use (reg:DI 49))
6580    (use (reg:DI 50))
6581    (use (reg:DI 51))
6582    (use (reg:DI 52))
6583    (use (reg:DI 53))
6584    (clobber (mem:BLK (const_int 0)))
6585    (clobber (reg:DI 24))
6586    (clobber (reg:DI 25))
6587    (clobber (reg:DI 0))]
6588   "TARGET_ABI_OPEN_VMS"
6589   "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
6590   [(set_attr "length" "16")
6591    (set_attr "type" "multi")])
6592
6593 ;; Load the CIW into r2 for calling __T3E_MISMATCH
6594
6595 (define_expand "umk_mismatch_args"
6596   [(set:DI (match_dup 1) (mem:DI (plus:DI (reg:DI 15) (const_int -16))))
6597    (set:DI (match_dup 2) (mem:DI (plus:DI (match_dup 1) (const_int -32))))
6598    (set:DI (reg:DI 1) (match_operand:DI 0 "const_int_operand" ""))
6599    (set:DI (match_dup 3) (plus:DI (mult:DI (reg:DI 25)
6600                                            (const_int 8))
6601                                   (match_dup 2)))
6602    (set:DI (reg:DI 2) (mem:DI (match_dup 3)))]
6603   "TARGET_ABI_UNICOSMK"
6604 {
6605   operands[1] = gen_reg_rtx (DImode);
6606   operands[2] = gen_reg_rtx (DImode);
6607   operands[3] = gen_reg_rtx (DImode);
6608 })
6609
6610 (define_insn "arg_home_umk"
6611   [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
6612    (use (reg:DI 1))
6613    (use (reg:DI 2))
6614    (use (reg:DI 16))
6615    (use (reg:DI 17))
6616    (use (reg:DI 18))
6617    (use (reg:DI 19))
6618    (use (reg:DI 20))
6619    (use (reg:DI 21))
6620    (use (reg:DI 48))
6621    (use (reg:DI 49))
6622    (use (reg:DI 50))
6623    (use (reg:DI 51))
6624    (use (reg:DI 52))
6625    (use (reg:DI 53))
6626    (clobber (mem:BLK (const_int 0)))
6627    (parallel [
6628    (clobber (reg:DI 22))
6629    (clobber (reg:DI 23))
6630    (clobber (reg:DI 24))
6631    (clobber (reg:DI 0))
6632    (clobber (reg:DI 1))
6633    (clobber (reg:DI 2))
6634    (clobber (reg:DI 3))
6635    (clobber (reg:DI 4))
6636    (clobber (reg:DI 5))
6637    (clobber (reg:DI 6))
6638    (clobber (reg:DI 7))
6639    (clobber (reg:DI 8))])]
6640   "TARGET_ABI_UNICOSMK"
6641   "laum $4,__T3E_MISMATCH($31)\;sll $4,32,$4\;lalm $4,__T3E_MISMATCH($4)\;lal $4,__T3E_MISMATCH($4)\;jsr $3,($4)"
6642   [(set_attr "length" "16")
6643    (set_attr "type" "multi")])
6644
6645 ;; Close the trap shadow of preceeding instructions.  This is generated
6646 ;; by alpha_reorg.
6647
6648 (define_insn "trapb"
6649   [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
6650   ""
6651   "trapb"
6652   [(set_attr "type" "misc")])
6653
6654 ;; No-op instructions used by machine-dependant reorg to preserve
6655 ;; alignment for instruction issue.
6656 ;; The Unicos/Mk assembler does not support these opcodes.
6657
6658 (define_insn "nop"
6659   [(const_int 0)]
6660   ""
6661   "bis $31,$31,$31"
6662   [(set_attr "type" "ilog")])
6663
6664 (define_insn "fnop"
6665   [(const_int 1)]
6666   "TARGET_FP"
6667   "cpys $f31,$f31,$f31"
6668   [(set_attr "type" "fcpys")])
6669
6670 (define_insn "unop"
6671   [(const_int 2)]
6672   ""
6673   "ldq_u $31,($31)")
6674
6675 ;; On Unicos/Mk we use a macro for aligning code.
6676
6677 (define_insn "realign"
6678   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
6679                     UNSPECV_REALIGN)]
6680   ""
6681 {
6682   if (TARGET_ABI_UNICOSMK)
6683     return "gcc@code@align %0";
6684   else
6685     return ".align %0 #realign";
6686 })
6687
6688 ;; The call patterns are at the end of the file because their
6689 ;; wildcard operand0 interferes with nice recognition.
6690
6691 (define_insn "*call_value_osf_1_er"
6692   [(set (match_operand 0 "" "")
6693         (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6694               (match_operand 2 "" "")))
6695    (use (reg:DI 29))
6696    (clobber (reg:DI 26))]
6697   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6698   "@
6699    jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
6700    bsr $26,$%1..ng
6701    ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
6702   [(set_attr "type" "jsr")
6703    (set_attr "length" "12,*,16")])
6704
6705 ;; We must use peep2 instead of a split because we need accurate life
6706 ;; information for $gp.  Consider the case of { bar(); while (1); }.
6707 (define_peephole2
6708   [(parallel [(set (match_operand 0 "" "")
6709                    (call (mem:DI (match_operand:DI 1 "call_operand" ""))
6710                          (match_operand 2 "" "")))
6711               (use (reg:DI 29))
6712               (clobber (reg:DI 26))])]
6713   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF  && reload_completed
6714    && ! current_file_function_operand (operands[0], Pmode)
6715    && peep2_regno_dead_p (1, 29)"
6716   [(parallel [(set (match_dup 0)
6717                    (call (mem:DI (match_dup 3))
6718                          (match_dup 2)))
6719               (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
6720               (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
6721               (use (match_dup 1))])]
6722 {
6723   if (CONSTANT_P (operands[1]))
6724     {
6725       operands[3] = gen_rtx_REG (Pmode, 27);
6726       emit_move_insn (operands[3], operands[1]);
6727     }
6728   else
6729     {
6730       operands[3] = operands[1];
6731       operands[1] = const0_rtx;
6732     }
6733 })
6734
6735 (define_peephole2
6736   [(parallel [(set (match_operand 0 "" "")
6737                    (call (mem:DI (match_operand:DI 1 "call_operand" ""))
6738                          (match_operand 2 "" "")))
6739               (use (reg:DI 29))
6740               (clobber (reg:DI 26))])]
6741   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF  && reload_completed
6742    && ! current_file_function_operand (operands[0], Pmode)
6743    && ! peep2_regno_dead_p (1, 29)"
6744   [(parallel [(set (match_dup 0)
6745                    (call (mem:DI (match_dup 3))
6746                          (match_dup 2)))
6747               (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
6748               (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
6749               (use (match_dup 1))])
6750    (set (reg:DI 29)
6751         (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
6752    (set (reg:DI 29)
6753         (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
6754 {
6755   if (CONSTANT_P (operands[1]))
6756     {
6757       operands[3] = gen_rtx_REG (Pmode, 27);
6758       emit_move_insn (operands[3], operands[1]);
6759     }
6760   else
6761     {
6762       operands[3] = operands[1];
6763       operands[1] = const0_rtx;
6764     }
6765   operands[4] = GEN_INT (alpha_next_sequence_number++);
6766 })
6767
6768 ;; We add a blockage unspec_volatile to prevent insns from moving down
6769 ;; from above the call to in between the call and the ldah gpdisp.
6770 (define_insn "*call_value_osf_2_er"
6771   [(set (match_operand 0 "" "")
6772         (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
6773               (match_operand 2 "" "")))
6774    (set (reg:DI 26)
6775         (plus:DI (pc) (const_int 4)))
6776    (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
6777    (use (match_operand 3 "" ""))]
6778   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6779   "jsr $26,(%1),%3"
6780   [(set_attr "type" "jsr")])
6781
6782 (define_insn "*call_value_osf_1_noreturn"
6783   [(set (match_operand 0 "" "")
6784         (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6785               (match_operand 2 "" "")))
6786    (use (reg:DI 29))
6787    (clobber (reg:DI 26))]
6788   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
6789    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
6790   "@
6791    jsr $26,($27),0
6792    bsr $26,$%1..ng
6793    jsr $26,%1"
6794   [(set_attr "type" "jsr")
6795    (set_attr "length" "*,*,8")])
6796
6797 (define_insn "*call_value_osf_1"
6798   [(set (match_operand 0 "" "")
6799         (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6800               (match_operand 2 "" "")))
6801    (use (reg:DI 29))
6802    (clobber (reg:DI 26))]
6803   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6804   "@
6805    jsr $26,($27),0\;ldgp $29,0($26)
6806    bsr $26,$%1..ng
6807    jsr $26,%1\;ldgp $29,0($26)"
6808   [(set_attr "type" "jsr")
6809    (set_attr "length" "12,*,16")])
6810
6811 ;; Need 's' alternative for OSF/1, which implements profiling
6812 ;; via linker tricks.
6813 (define_insn "*sibcall_value_osf_1"
6814   [(set (match_operand 0 "" "")
6815         (call (mem:DI (match_operand:DI 1 "current_file_function_operand" "R,s"))
6816               (match_operand 2 "" "")))
6817    (use (reg:DI 29))]
6818   "TARGET_ABI_OSF"
6819   "@
6820    br $31,$%1..ng
6821    lda $27,%1\;jmp $31,($27),%1"
6822   [(set_attr "type" "jsr")
6823    (set_attr "length" "*,8")])
6824
6825 (define_insn "*call_value_nt_1"
6826   [(set (match_operand 0 "" "")
6827         (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,s"))
6828               (match_operand 2 "" "")))
6829    (clobber (reg:DI 26))]
6830   "TARGET_ABI_WINDOWS_NT"
6831   "@
6832    jsr $26,(%1)
6833    bsr $26,%1
6834    jsr $26,%1"
6835   [(set_attr "type" "jsr")
6836    (set_attr "length" "*,*,12")])
6837
6838 (define_insn "*call_value_vms_1"
6839   [(set (match_operand 0 "" "")
6840         (call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
6841               (match_operand 2 "" "")))
6842    (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
6843    (use (reg:DI 25))
6844    (use (reg:DI 26))
6845    (clobber (reg:DI 27))]
6846   "TARGET_ABI_OPEN_VMS"
6847   "@
6848    mov %3,$27\;jsr $26,0\;ldq $27,0($29)
6849    ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
6850   [(set_attr "type" "jsr")
6851    (set_attr "length" "12,16")])
6852
6853 (define_insn "*call_value_umk"
6854   [(set (match_operand 0 "" "")
6855         (call (mem:DI (match_operand:DI 1 "call_operand" "r"))
6856               (match_operand 2 "" "")))
6857    (use (reg:DI 25))
6858    (clobber (reg:DI 26))]
6859   "TARGET_ABI_UNICOSMK"
6860   "jsr $26,(%1)"
6861   [(set_attr "type" "jsr")])
6862