OSDN Git Service

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