xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/alpha/alpha.md (revision f3cfa6f6ce31685c6c4a758bc430e69eb99f50a4)
1;; Machine description for DEC Alpha for GNU C compiler
2;; Copyright (C) 1992-2016 Free Software Foundation, Inc.
3;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 3, or (at your option)
10;; any later version.
11;;
12;; GCC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15;; GNU General Public License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23;; Uses of UNSPEC in this file:
24
25(define_c_enum "unspec" [
26  UNSPEC_XFLT_COMPARE
27  UNSPEC_ARG_HOME
28  UNSPEC_LDGP1
29  UNSPEC_INSXH
30  UNSPEC_MSKXH
31  UNSPEC_CVTQL
32  UNSPEC_CVTLQ
33  UNSPEC_LDGP2
34  UNSPEC_LITERAL
35  UNSPEC_LITUSE
36  UNSPEC_SIBCALL
37  UNSPEC_SYMBOL
38
39  ;; TLS Support
40  UNSPEC_TLSGD_CALL
41  UNSPEC_TLSLDM_CALL
42  UNSPEC_TLSGD
43  UNSPEC_TLSLDM
44  UNSPEC_DTPREL
45  UNSPEC_TPREL
46  UNSPEC_TP
47
48  ;; Builtins
49  UNSPEC_CMPBGE
50  UNSPEC_ZAP
51  UNSPEC_AMASK
52  UNSPEC_IMPLVER
53  UNSPEC_PERR
54  UNSPEC_COPYSIGN
55
56  ;; Atomic operations
57  UNSPEC_MB
58  UNSPEC_ATOMIC
59  UNSPEC_CMPXCHG
60  UNSPEC_XCHG
61])
62
63;; UNSPEC_VOLATILE:
64
65(define_c_enum "unspecv" [
66  UNSPECV_IMB
67  UNSPECV_BLOCKAGE
68  UNSPECV_SETJMPR	; builtin_setjmp_receiver
69  UNSPECV_LONGJMP	; builtin_longjmp
70  UNSPECV_TRAPB
71  UNSPECV_PSPL		; prologue_stack_probe_loop
72  UNSPECV_REALIGN
73  UNSPECV_EHR		; exception_receiver
74  UNSPECV_MCOUNT
75  UNSPECV_FORCE_MOV
76  UNSPECV_LDGP1
77  UNSPECV_PLDGP2	; prologue ldgp
78  UNSPECV_SET_TP
79  UNSPECV_RPCC
80  UNSPECV_SETJMPR_ER	; builtin_setjmp_receiver fragment
81  UNSPECV_LL		; load-locked
82  UNSPECV_SC		; store-conditional
83  UNSPECV_CMPXCHG
84])
85
86;; On non-BWX targets, CQImode must be handled the similarly to HImode
87;; when generating reloads.
88(define_mode_iterator RELOAD12 [QI HI CQI])
89(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")])
90
91;; Other mode iterators
92(define_mode_iterator IMODE [QI HI SI DI])
93(define_mode_iterator I12MODE [QI HI])
94(define_mode_iterator I124MODE [QI HI SI])
95(define_mode_iterator I24MODE [HI SI])
96(define_mode_iterator I248MODE [HI SI DI])
97(define_mode_iterator I48MODE [SI DI])
98
99(define_mode_attr DWI [(SI "DI") (DI "TI")])
100(define_mode_attr modesuffix [(QI "b") (HI "w") (SI "l") (DI "q")
101		  	      (V8QI "b8") (V4HI "w4")
102			      (SF "%,") (DF "%-")])
103(define_mode_attr vecmodesuffix [(QI "b8") (HI "w4")])
104
105(define_code_iterator any_maxmin [smax smin umax umin])
106
107(define_code_attr maxmin [(smax "maxs") (smin "mins")
108			  (umax "maxu") (umin "minu")])
109
110;; Where necessary, the suffixes _le and _be are used to distinguish between
111;; little-endian and big-endian patterns.
112;;
113;; Note that the Unicos/Mk assembler does not support the following
114;; opcodes: mov, fmov, nop, fnop, unop.
115
116;; Processor type -- this attribute must exactly match the processor_type
117;; enumeration in alpha.h.
118
119(define_attr "tune" "ev4,ev5,ev6"
120  (const (symbol_ref "((enum attr_tune) alpha_tune)")))
121
122;; Define an insn type attribute.  This is used in function unit delay
123;; computations, among other purposes.  For the most part, we use the names
124;; defined in the EV4 documentation, but add a few that we have to know about
125;; separately.
126
127(define_attr "type"
128  "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
129   icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,mb,ld_l,st_c,
130   multi,none"
131  (const_string "iadd"))
132
133;; Describe a user's asm statement.
134(define_asm_attributes
135  [(set_attr "type" "multi")])
136
137;; Define the operand size an insn operates on.  Used primarily by mul
138;; and div operations that have size dependent timings.
139
140(define_attr "opsize" "si,di,udi"
141  (const_string "di"))
142
143;; The TRAP attribute marks instructions that may generate traps
144;; (which are imprecise and may need a trapb if software completion
145;; is desired).
146
147(define_attr "trap" "no,yes"
148  (const_string "no"))
149
150;; The ROUND_SUFFIX attribute marks which instructions require a
151;; rounding-mode suffix.  The value NONE indicates no suffix,
152;; the value NORMAL indicates a suffix controlled by alpha_fprm.
153
154(define_attr "round_suffix" "none,normal,c"
155  (const_string "none"))
156
157;; The TRAP_SUFFIX attribute marks instructions requiring a trap-mode suffix:
158;;   NONE	no suffix
159;;   SU		accepts only /su (cmpt et al)
160;;   SUI	accepts only /sui (cvtqt and cvtqs)
161;;   V_SV	accepts /v and /sv (cvtql only)
162;;   V_SV_SVI	accepts /v, /sv and /svi (cvttq only)
163;;   U_SU_SUI	accepts /u, /su and /sui (most fp instructions)
164;;
165;; The actual suffix emitted is controlled by alpha_fptm.
166
167(define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui"
168  (const_string "none"))
169
170;; The length of an instruction sequence in bytes.
171
172(define_attr "length" ""
173  (const_int 4))
174
175;; The USEGP attribute marks instructions that have relocations that use
176;; the GP.
177
178(define_attr "usegp" "no,yes"
179  (cond [(eq_attr "type" "ldsym,jsr")
180	   (const_string "yes")
181	 (eq_attr "type" "ild,fld,ist,fst")
182	   (symbol_ref "((enum attr_usegp) alpha_find_lo_sum_using_gp (insn))")
183	]
184	(const_string "no")))
185
186;; The CANNOT_COPY attribute marks instructions with relocations that
187;; cannot easily be duplicated.  This includes insns with gpdisp relocs
188;; since they have to stay in 1-1 correspondence with one another.  This
189;; also includes jsr insns, since they must stay in correspondence with
190;; the immediately following gpdisp instructions.
191
192(define_attr "cannot_copy" "false,true"
193  (const_string "false"))
194
195;; Used to control the "enabled" attribute on a per-instruction basis.
196;; For convenience, conflate ABI issues re loading of addresses with
197;; an "isa".
198(define_attr "isa" "base,bwx,max,fix,cix,vms,ner,er"
199  (const_string "base"))
200
201(define_attr "enabled" ""
202  (cond [(eq_attr "isa" "bwx")	(symbol_ref "TARGET_BWX")
203	 (eq_attr "isa" "max")	(symbol_ref "TARGET_MAX")
204	 (eq_attr "isa" "fix")	(symbol_ref "TARGET_FIX")
205	 (eq_attr "isa" "cix")	(symbol_ref "TARGET_CIX")
206	 (eq_attr "isa" "vms")  (symbol_ref "TARGET_ABI_OPEN_VMS")
207	 (eq_attr "isa" "ner")	(symbol_ref "!TARGET_EXPLICIT_RELOCS")
208	 (eq_attr "isa" "er")	(symbol_ref "TARGET_EXPLICIT_RELOCS")
209	]
210	(const_int 1)))
211
212;; Include scheduling descriptions.
213
214(include "ev4.md")
215(include "ev5.md")
216(include "ev6.md")
217
218
219;; Operand and operator predicates and constraints
220
221(include "predicates.md")
222(include "constraints.md")
223
224
225;; First define the arithmetic insns.  Note that the 32-bit forms also
226;; sign-extend.
227
228;; Handle 32-64 bit extension from memory to a floating point register
229;; specially, since this occurs frequently in int->double conversions.
230;;
231;; Note that while we must retain the =f case in the insn for reload's
232;; benefit, it should be eliminated after reload, so we should never emit
233;; code for that case.  But we don't reject the possibility.
234
235(define_expand "extendsidi2"
236  [(set (match_operand:DI 0 "register_operand")
237	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
238
239(define_insn "*cvtlq"
240  [(set (match_operand:DI 0 "register_operand" "=f")
241	(unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
242		   UNSPEC_CVTLQ))]
243  ""
244  "cvtlq %1,%0"
245  [(set_attr "type" "fadd")])
246
247(define_insn "*extendsidi2_1"
248  [(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
249	(sign_extend:DI
250	  (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
251  ""
252  "@
253   addl $31,%1,%0
254   ldl %0,%1
255   lds %0,%1\;cvtlq %0,%0"
256  [(set_attr "type" "iadd,ild,fld")
257   (set_attr "length" "*,*,8")])
258
259(define_split
260  [(set (match_operand:DI 0 "hard_fp_register_operand")
261	(sign_extend:DI (match_operand:SI 1 "memory_operand")))]
262  "reload_completed"
263  [(set (match_dup 2) (match_dup 1))
264   (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
265{
266  operands[1] = adjust_address (operands[1], SFmode, 0);
267  operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
268})
269
270;; Optimize sign-extension of SImode loads.  This shows up in the wake of
271;; reload when converting fp->int.
272
273(define_peephole2
274  [(set (match_operand:SI 0 "hard_int_register_operand")
275        (match_operand:SI 1 "memory_operand"))
276   (set (match_operand:DI 2 "hard_int_register_operand")
277        (sign_extend:DI (match_dup 0)))]
278  "true_regnum (operands[0]) == true_regnum (operands[2])
279   || peep2_reg_dead_p (2, operands[0])"
280  [(set (match_dup 2)
281	(sign_extend:DI (match_dup 1)))])
282
283(define_insn "addsi3"
284  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
285	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
286		 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
287  ""
288  "@
289   addl %r1,%2,%0
290   subl %r1,%n2,%0
291   lda %0,%2(%r1)
292   ldah %0,%h2(%r1)")
293
294(define_split
295  [(set (match_operand:SI 0 "register_operand")
296	(plus:SI (match_operand:SI 1 "register_operand")
297		 (match_operand:SI 2 "const_int_operand")))]
298  "! add_operand (operands[2], SImode)"
299  [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
300   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
301{
302  HOST_WIDE_INT val = INTVAL (operands[2]);
303  HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
304  HOST_WIDE_INT rest = val - low;
305
306  operands[3] = GEN_INT (rest);
307  operands[4] = GEN_INT (low);
308})
309
310(define_insn "*addsi_se"
311  [(set (match_operand:DI 0 "register_operand" "=r,r")
312	(sign_extend:DI
313	 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
314		  (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
315  ""
316  "@
317   addl %r1,%2,%0
318   subl %r1,%n2,%0")
319
320(define_insn "*addsi_se2"
321  [(set (match_operand:DI 0 "register_operand" "=r,r")
322	(sign_extend:DI
323	 (subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
324			     (match_operand:DI 2 "sext_add_operand" "rI,O"))
325		    0)))]
326  ""
327  "@
328   addl %r1,%2,%0
329   subl %r1,%n2,%0")
330
331(define_split
332  [(set (match_operand:DI 0 "register_operand")
333	(sign_extend:DI
334	 (plus:SI (match_operand:SI 1 "reg_not_elim_operand")
335		  (match_operand:SI 2 "const_int_operand"))))
336   (clobber (match_operand:SI 3 "reg_not_elim_operand"))]
337  "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
338   && INTVAL (operands[2]) % 4 == 0"
339  [(set (match_dup 3) (match_dup 4))
340   (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
341							(match_dup 5))
342					       (match_dup 1))))]
343{
344  HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
345  int mult = 4;
346
347  if (val % 2 == 0)
348    val /= 2, mult = 8;
349
350  operands[4] = GEN_INT (val);
351  operands[5] = GEN_INT (mult);
352})
353
354(define_split
355  [(set (match_operand:DI 0 "register_operand")
356	(sign_extend:DI
357	 (plus:SI (match_operator:SI 1 "comparison_operator"
358				     [(match_operand 2)
359				      (match_operand 3)])
360		  (match_operand:SI 4 "add_operand"))))
361   (clobber (match_operand:DI 5 "register_operand"))]
362  ""
363  [(set (match_dup 5) (match_dup 6))
364   (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
365{
366  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
367				operands[2], operands[3]);
368  operands[7] = gen_lowpart (SImode, operands[5]);
369})
370
371(define_expand "adddi3"
372  [(set (match_operand:DI 0 "register_operand")
373	(plus:DI (match_operand:DI 1 "register_operand")
374		 (match_operand:DI 2 "add_operand")))])
375
376(define_insn "*adddi_er_lo16_dtp"
377  [(set (match_operand:DI 0 "register_operand" "=r")
378	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
379		   (match_operand:DI 2 "dtp16_symbolic_operand")))]
380  "HAVE_AS_TLS"
381  "lda %0,%2(%1)\t\t!dtprel")
382
383(define_insn "*adddi_er_hi32_dtp"
384  [(set (match_operand:DI 0 "register_operand" "=r")
385	(plus:DI (match_operand:DI 1 "register_operand" "r")
386		 (high:DI (match_operand:DI 2 "dtp32_symbolic_operand"))))]
387  "HAVE_AS_TLS"
388  "ldah %0,%2(%1)\t\t!dtprelhi")
389
390(define_insn "*adddi_er_lo32_dtp"
391  [(set (match_operand:DI 0 "register_operand" "=r")
392	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
393		   (match_operand:DI 2 "dtp32_symbolic_operand")))]
394  "HAVE_AS_TLS"
395  "lda %0,%2(%1)\t\t!dtprello")
396
397(define_insn "*adddi_er_lo16_tp"
398  [(set (match_operand:DI 0 "register_operand" "=r")
399	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
400		   (match_operand:DI 2 "tp16_symbolic_operand")))]
401  "HAVE_AS_TLS"
402  "lda %0,%2(%1)\t\t!tprel")
403
404(define_insn "*adddi_er_hi32_tp"
405  [(set (match_operand:DI 0 "register_operand" "=r")
406	(plus:DI (match_operand:DI 1 "register_operand" "r")
407		 (high:DI (match_operand:DI 2 "tp32_symbolic_operand"))))]
408  "HAVE_AS_TLS"
409  "ldah %0,%2(%1)\t\t!tprelhi")
410
411(define_insn "*adddi_er_lo32_tp"
412  [(set (match_operand:DI 0 "register_operand" "=r")
413	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
414		   (match_operand:DI 2 "tp32_symbolic_operand")))]
415  "HAVE_AS_TLS"
416  "lda %0,%2(%1)\t\t!tprello")
417
418(define_insn "*adddi_er_high_l"
419  [(set (match_operand:DI 0 "register_operand" "=r")
420	(plus:DI (match_operand:DI 1 "register_operand" "r")
421		 (high:DI (match_operand:DI 2 "local_symbolic_operand"))))]
422  "TARGET_EXPLICIT_RELOCS && reload_completed"
423  "ldah %0,%2(%1)\t\t!gprelhigh"
424  [(set_attr "usegp" "yes")])
425
426(define_split
427  [(set (match_operand:DI 0 "register_operand")
428        (high:DI (match_operand:DI 1 "local_symbolic_operand")))]
429  "TARGET_EXPLICIT_RELOCS && reload_completed"
430  [(set (match_dup 0)
431	(plus:DI (match_dup 2) (high:DI (match_dup 1))))]
432  "operands[2] = pic_offset_table_rtx;")
433
434;; We used to expend quite a lot of effort choosing addq/subq/lda.
435;; With complications like
436;;
437;;   The NT stack unwind code can't handle a subq to adjust the stack
438;;   (that's a bug, but not one we can do anything about).  As of NT4.0 SP3,
439;;   the exception handling code will loop if a subq is used and an
440;;   exception occurs.
441;;
442;;   The 19980616 change to emit prologues as RTL also confused some
443;;   versions of GDB, which also interprets prologues.  This has been
444;;   fixed as of GDB 4.18, but it does not harm to unconditionally
445;;   use lda here.
446;;
447;; and the fact that the three insns schedule exactly the same, it's
448;; just not worth the effort.
449
450(define_insn "*adddi_internal"
451  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
452	(plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
453		 (match_operand:DI 2 "add_operand" "r,K,L")))]
454  ""
455  "@
456   addq %1,%2,%0
457   lda %0,%2(%1)
458   ldah %0,%h2(%1)")
459
460;; ??? Allow large constants when basing off the frame pointer or some
461;; virtual register that may eliminate to the frame pointer.  This is
462;; done because register elimination offsets will change the hi/lo split,
463;; and if we split before reload, we will require additional instructions.
464
465(define_insn "*adddi_fp_hack"
466  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
467        (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r,r,r")
468		 (match_operand:DI 2 "const_int_operand" "K,L,n")))]
469  "NONSTRICT_REG_OK_FP_BASE_P (operands[1])
470   && INTVAL (operands[2]) >= 0
471   /* This is the largest constant an lda+ldah pair can add, minus
472      an upper bound on the displacement between SP and AP during
473      register elimination.  See INITIAL_ELIMINATION_OFFSET.  */
474   && INTVAL (operands[2])
475	< (0x7fff8000
476	   - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
477	   - ALPHA_ROUND(crtl->outgoing_args_size)
478	   - (ALPHA_ROUND (get_frame_size ()
479			   + max_reg_num () * UNITS_PER_WORD
480			   + crtl->args.pretend_args_size)
481	      - crtl->args.pretend_args_size))"
482  "@
483   lda %0,%2(%1)
484   ldah %0,%h2(%1)
485   #")
486
487;; Don't do this if we are adjusting SP since we don't want to do it
488;; in two steps.  Don't split FP sources for the reason listed above.
489(define_split
490  [(set (match_operand:DI 0 "register_operand")
491	(plus:DI (match_operand:DI 1 "register_operand")
492		 (match_operand:DI 2 "const_int_operand")))]
493  "! add_operand (operands[2], DImode)
494   && operands[0] != stack_pointer_rtx
495   && operands[1] != frame_pointer_rtx
496   && operands[1] != arg_pointer_rtx"
497  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
498   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
499{
500  HOST_WIDE_INT val = INTVAL (operands[2]);
501  HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
502  HOST_WIDE_INT rest = val - low;
503  rtx rest_rtx = GEN_INT (rest);
504
505  operands[4] = GEN_INT (low);
506  if (satisfies_constraint_L (rest_rtx))
507    operands[3] = rest_rtx;
508  else if (can_create_pseudo_p ())
509    {
510      operands[3] = gen_reg_rtx (DImode);
511      emit_move_insn (operands[3], operands[2]);
512      emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
513      DONE;
514    }
515  else
516    FAIL;
517})
518
519(define_insn "*sadd<modesuffix>"
520  [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
521	(plus:I48MODE
522	 (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r,r")
523		       (match_operand:I48MODE 2 "const48_operand" "I,I"))
524	 (match_operand:I48MODE 3 "sext_add_operand" "rI,O")))]
525  ""
526  "@
527   s%2add<modesuffix> %1,%3,%0
528   s%2sub<modesuffix> %1,%n3,%0")
529
530(define_insn "*saddl_se"
531  [(set (match_operand:DI 0 "register_operand" "=r,r")
532	(sign_extend:DI
533	 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
534			   (match_operand:SI 2 "const48_operand" "I,I"))
535		  (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
536  ""
537  "@
538   s%2addl %1,%3,%0
539   s%2subl %1,%n3,%0")
540
541(define_split
542  [(set (match_operand:DI 0 "register_operand")
543	(sign_extend:DI
544	 (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
545					      [(match_operand 2)
546					       (match_operand 3)])
547			   (match_operand:SI 4 "const48_operand"))
548		  (match_operand:SI 5 "sext_add_operand"))))
549   (clobber (match_operand:DI 6 "reg_not_elim_operand"))]
550  ""
551  [(set (match_dup 6) (match_dup 7))
552   (set (match_dup 0)
553	(sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
554				 (match_dup 5))))]
555{
556  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
557				operands[2], operands[3]);
558  operands[8] = gen_lowpart (SImode, operands[6]);
559})
560
561(define_insn "addv<mode>3"
562  [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
563	(plus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ,rJ")
564		      (match_operand:I48MODE 2 "sext_add_operand" "rI,O")))
565   (trap_if (ne (plus:<DWI> (sign_extend:<DWI> (match_dup 1))
566			    (sign_extend:<DWI> (match_dup 2)))
567		(sign_extend:<DWI> (plus:I48MODE (match_dup 1)
568						 (match_dup 2))))
569	    (const_int 0))]
570  ""
571  "@
572   add<modesuffix>v %r1,%2,%0
573   sub<modesuffix>v %r1,%n2,%0")
574
575(define_insn "neg<mode>2"
576  [(set (match_operand:I48MODE 0 "register_operand" "=r")
577	(neg:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI")))]
578  ""
579  "sub<modesuffix> $31,%1,%0")
580
581(define_insn "*negsi_se"
582  [(set (match_operand:DI 0 "register_operand" "=r")
583	(sign_extend:DI (neg:SI
584			 (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
585  ""
586  "subl $31,%1,%0")
587
588(define_insn "negv<mode>2"
589  [(set (match_operand:I48MODE 0 "register_operand" "=r")
590	(neg:I48MODE (match_operand:I48MODE 1 "register_operand" "r")))
591   (trap_if (ne (neg:<DWI> (sign_extend:<DWI> (match_dup 1)))
592		(sign_extend:<DWI> (neg:I48MODE (match_dup 1))))
593	    (const_int 0))]
594  ""
595  "sub<modesuffix>v $31,%1,%0")
596
597(define_insn "sub<mode>3"
598  [(set (match_operand:I48MODE 0 "register_operand" "=r")
599	(minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ")
600		       (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))]
601  ""
602  "sub<modesuffix> %r1,%2,%0")
603
604(define_insn "*subsi_se"
605  [(set (match_operand:DI 0 "register_operand" "=r")
606	(sign_extend:DI
607	 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
608		   (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
609  ""
610  "subl %r1,%2,%0")
611
612(define_insn "*subsi_se2"
613  [(set (match_operand:DI 0 "register_operand" "=r")
614	(sign_extend:DI
615	 (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
616			      (match_operand:DI 2 "reg_or_8bit_operand" "rI"))
617		    0)))]
618  ""
619  "subl %r1,%2,%0")
620
621(define_insn "*ssub<modesuffix>"
622  [(set (match_operand:I48MODE 0 "register_operand" "=r")
623	(minus:I48MODE
624	 (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r")
625		       (match_operand:I48MODE 2 "const48_operand" "I"))
626		  (match_operand:I48MODE 3 "reg_or_8bit_operand" "rI")))]
627  ""
628  "s%2sub<modesuffix> %1,%3,%0")
629
630(define_insn "*ssubl_se"
631  [(set (match_operand:DI 0 "register_operand" "=r")
632	(sign_extend:DI
633	 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
634			    (match_operand:SI 2 "const48_operand" "I"))
635		   (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
636  ""
637  "s%2subl %1,%3,%0")
638
639(define_insn "subv<mode>3"
640  [(set (match_operand:I48MODE 0 "register_operand" "=r")
641	(minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ")
642		       (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
643   (trap_if (ne (minus:<DWI> (sign_extend:<DWI> (match_dup 1))
644			     (sign_extend:<DWI> (match_dup 2)))
645		(sign_extend:<DWI> (minus:I48MODE (match_dup 1)
646						  (match_dup 2))))
647	    (const_int 0))]
648  ""
649  "sub<modesuffix>v %r1,%2,%0")
650
651(define_insn "mul<mode>3"
652  [(set (match_operand:I48MODE 0 "register_operand" "=r")
653	(mult:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ")
654		      (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))]
655  ""
656  "mul<modesuffix> %r1,%2,%0"
657  [(set_attr "type" "imul")
658   (set_attr "opsize" "<mode>")])
659
660(define_insn "*mulsi_se"
661  [(set (match_operand:DI 0 "register_operand" "=r")
662	(sign_extend:DI
663	  (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
664		   (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
665  ""
666  "mull %r1,%2,%0"
667  [(set_attr "type" "imul")
668   (set_attr "opsize" "si")])
669
670(define_insn "mulv<mode>3"
671  [(set (match_operand:I48MODE 0 "register_operand" "=r")
672	(mult:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ")
673		      (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
674   (trap_if (ne (mult:<DWI> (sign_extend:<DWI> (match_dup 1))
675			    (sign_extend:<DWI> (match_dup 2)))
676		(sign_extend:<DWI> (mult:I48MODE (match_dup 1)
677						 (match_dup 2))))
678	    (const_int 0))]
679  ""
680  "mul<modesuffix>v %r1,%2,%0"
681  [(set_attr "type" "imul")
682   (set_attr "opsize" "<mode>")])
683
684(define_expand "umuldi3_highpart"
685  [(set (match_operand:DI 0 "register_operand")
686	(truncate:DI
687	 (lshiftrt:TI
688	  (mult:TI (zero_extend:TI
689		     (match_operand:DI 1 "register_operand"))
690		   (match_operand:DI 2 "reg_or_8bit_operand"))
691	  (const_int 64))))]
692  ""
693{
694  if (REG_P (operands[2]))
695    operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]);
696})
697
698(define_insn "*umuldi3_highpart_reg"
699  [(set (match_operand:DI 0 "register_operand" "=r")
700	(truncate:DI
701	 (lshiftrt:TI
702	  (mult:TI (zero_extend:TI
703		     (match_operand:DI 1 "register_operand" "r"))
704		   (zero_extend:TI
705		     (match_operand:DI 2 "register_operand" "r")))
706	  (const_int 64))))]
707  ""
708  "umulh %1,%2,%0"
709  [(set_attr "type" "imul")
710   (set_attr "opsize" "udi")])
711
712(define_insn "*umuldi3_highpart_const"
713  [(set (match_operand:DI 0 "register_operand" "=r")
714	(truncate:DI
715	 (lshiftrt:TI
716	  (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
717		   (match_operand:TI 2 "cint8_operand" "I"))
718	  (const_int 64))))]
719  ""
720  "umulh %1,%2,%0"
721  [(set_attr "type" "imul")
722   (set_attr "opsize" "udi")])
723
724(define_expand "umulditi3"
725  [(set (match_operand:TI 0 "register_operand")
726       (mult:TI
727	 (zero_extend:TI (match_operand:DI 1 "reg_no_subreg_operand"))
728	 (zero_extend:TI (match_operand:DI 2 "reg_no_subreg_operand"))))]
729  ""
730{
731  rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode);
732  emit_insn (gen_muldi3 (l, operands[1], operands[2]));
733  emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2]));
734  emit_move_insn (gen_lowpart (DImode, operands[0]), l);
735  emit_move_insn (gen_highpart (DImode, operands[0]), h);
736  DONE;
737})
738
739;; The divide and remainder operations take their inputs from r24 and
740;; r25, put their output in r27, and clobber r23 and r28 on all systems.
741;;
742;; ??? Force sign-extension here because some versions of OSF/1 and
743;; Interix/NT don't do the right thing if the inputs are not properly
744;; sign-extended.  But Linux, for instance, does not have this
745;; problem.  Is it worth the complication here to eliminate the sign
746;; extension?
747
748(define_code_iterator any_divmod [div mod udiv umod])
749
750(define_expand "<code>si3"
751  [(set (match_dup 3)
752	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand")))
753   (set (match_dup 4)
754	(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand")))
755   (parallel [(set (match_dup 5)
756		   (sign_extend:DI
757		    (any_divmod:SI (match_dup 3) (match_dup 4))))
758	      (clobber (reg:DI 23))
759	      (clobber (reg:DI 28))])
760   (set (match_operand:SI 0 "nonimmediate_operand")
761	(subreg:SI (match_dup 5) 0))]
762  "TARGET_ABI_OSF"
763{
764  operands[3] = gen_reg_rtx (DImode);
765  operands[4] = gen_reg_rtx (DImode);
766  operands[5] = gen_reg_rtx (DImode);
767})
768
769(define_expand "<code>di3"
770  [(parallel [(set (match_operand:DI 0 "register_operand")
771		   (any_divmod:DI
772		    (match_operand:DI 1 "register_operand")
773		    (match_operand:DI 2 "register_operand")))
774	      (clobber (reg:DI 23))
775	      (clobber (reg:DI 28))])]
776  "TARGET_ABI_OSF")
777
778;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
779;; expanded by the assembler.
780
781(define_insn_and_split "*divmodsi_internal_er"
782  [(set (match_operand:DI 0 "register_operand" "=c")
783	(sign_extend:DI (match_operator:SI 3 "divmod_operator"
784			[(match_operand:DI 1 "register_operand" "a")
785			 (match_operand:DI 2 "register_operand" "b")])))
786   (clobber (reg:DI 23))
787   (clobber (reg:DI 28))]
788  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
789  "#"
790  "&& reload_completed"
791  [(parallel [(set (match_dup 0)
792		   (sign_extend:DI (match_dup 3)))
793	      (use (match_dup 0))
794	      (use (match_dup 4))
795	      (clobber (reg:DI 23))
796	      (clobber (reg:DI 28))])]
797{
798  const char *str;
799  switch (GET_CODE (operands[3]))
800    {
801    case DIV:
802      str = "__divl";
803      break;
804    case UDIV:
805      str = "__divlu";
806      break;
807    case MOD:
808      str = "__reml";
809      break;
810    case UMOD:
811      str = "__remlu";
812      break;
813    default:
814      gcc_unreachable ();
815    }
816  operands[4] = GEN_INT (alpha_next_sequence_number++);
817  emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
818				  gen_rtx_SYMBOL_REF (DImode, str),
819				  operands[4]));
820}
821  [(set_attr "type" "jsr")
822   (set_attr "length" "8")])
823
824(define_insn "*divmodsi_internal_er_1"
825  [(set (match_operand:DI 0 "register_operand" "=c")
826	(sign_extend:DI (match_operator:SI 3 "divmod_operator"
827                        [(match_operand:DI 1 "register_operand" "a")
828                         (match_operand:DI 2 "register_operand" "b")])))
829   (use (match_operand:DI 4 "register_operand" "c"))
830   (use (match_operand 5 "const_int_operand"))
831   (clobber (reg:DI 23))
832   (clobber (reg:DI 28))]
833  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
834  "jsr $23,($27),__%E3%j5"
835  [(set_attr "type" "jsr")
836   (set_attr "length" "4")])
837
838(define_insn "*divmodsi_internal"
839  [(set (match_operand:DI 0 "register_operand" "=c")
840	(sign_extend:DI (match_operator:SI 3 "divmod_operator"
841			[(match_operand:DI 1 "register_operand" "a")
842			 (match_operand:DI 2 "register_operand" "b")])))
843   (clobber (reg:DI 23))
844   (clobber (reg:DI 28))]
845  "TARGET_ABI_OSF"
846  "%E3 %1,%2,%0"
847  [(set_attr "type" "jsr")
848   (set_attr "length" "8")])
849
850(define_insn_and_split "*divmoddi_internal_er"
851  [(set (match_operand:DI 0 "register_operand" "=c")
852	(match_operator:DI 3 "divmod_operator"
853			[(match_operand:DI 1 "register_operand" "a")
854			 (match_operand:DI 2 "register_operand" "b")]))
855   (clobber (reg:DI 23))
856   (clobber (reg:DI 28))]
857  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
858  "#"
859  "&& reload_completed"
860  [(parallel [(set (match_dup 0) (match_dup 3))
861	      (use (match_dup 0))
862	      (use (match_dup 4))
863	      (clobber (reg:DI 23))
864	      (clobber (reg:DI 28))])]
865{
866  const char *str;
867  switch (GET_CODE (operands[3]))
868    {
869    case DIV:
870      str = "__divq";
871      break;
872    case UDIV:
873      str = "__divqu";
874      break;
875    case MOD:
876      str = "__remq";
877      break;
878    case UMOD:
879      str = "__remqu";
880      break;
881    default:
882      gcc_unreachable ();
883    }
884  operands[4] = GEN_INT (alpha_next_sequence_number++);
885  emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
886				  gen_rtx_SYMBOL_REF (DImode, str),
887				  operands[4]));
888}
889  [(set_attr "type" "jsr")
890   (set_attr "length" "8")])
891
892(define_insn "*divmoddi_internal_er_1"
893  [(set (match_operand:DI 0 "register_operand" "=c")
894	(match_operator:DI 3 "divmod_operator"
895                        [(match_operand:DI 1 "register_operand" "a")
896                         (match_operand:DI 2 "register_operand" "b")]))
897   (use (match_operand:DI 4 "register_operand" "c"))
898   (use (match_operand 5 "const_int_operand"))
899   (clobber (reg:DI 23))
900   (clobber (reg:DI 28))]
901  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
902  "jsr $23,($27),__%E3%j5"
903  [(set_attr "type" "jsr")
904   (set_attr "length" "4")])
905
906(define_insn "*divmoddi_internal"
907  [(set (match_operand:DI 0 "register_operand" "=c")
908	(match_operator:DI 3 "divmod_operator"
909			[(match_operand:DI 1 "register_operand" "a")
910			 (match_operand:DI 2 "register_operand" "b")]))
911   (clobber (reg:DI 23))
912   (clobber (reg:DI 28))]
913  "TARGET_ABI_OSF"
914  "%E3 %1,%2,%0"
915  [(set_attr "type" "jsr")
916   (set_attr "length" "8")])
917
918;; Next are the basic logical operations.  We only expose the DImode operations
919;; to the rtl expanders, but SImode versions exist for combine as well as for
920;; the atomic operation splitters.
921
922(define_insn "*andsi_internal"
923  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
924	(and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
925		(match_operand:SI 2 "and_operand" "rI,N,M")))]
926  ""
927  "@
928   and %r1,%2,%0
929   bic %r1,%N2,%0
930   zapnot %r1,%m2,%0"
931  [(set_attr "type" "ilog,ilog,shift")])
932
933(define_insn "anddi3"
934  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
935	(and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
936		(match_operand:DI 2 "and_operand" "rI,N,M")))]
937  ""
938  "@
939   and %r1,%2,%0
940   bic %r1,%N2,%0
941   zapnot %r1,%m2,%0"
942  [(set_attr "type" "ilog,ilog,shift")])
943
944;; There are times when we can split an AND into two AND insns.  This occurs
945;; when we can first clear any bytes and then clear anything else.  For
946;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
947;; Only do this when running on 64-bit host since the computations are
948;; too messy otherwise.
949
950(define_split
951  [(set (match_operand:DI 0 "register_operand")
952	(and:DI (match_operand:DI 1 "register_operand")
953		(match_operand:DI 2 "const_int_operand")))]
954  "! and_operand (operands[2], DImode)"
955  [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
956   (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
957{
958  unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
959  unsigned HOST_WIDE_INT mask2 = mask1;
960  int i;
961
962  /* For each byte that isn't all zeros, make it all ones.  */
963  for (i = 0; i < 64; i += 8)
964    if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
965      mask1 |= (HOST_WIDE_INT) 0xff << i;
966
967  /* Now turn on any bits we've just turned off.  */
968  mask2 |= ~ mask1;
969
970  operands[3] = GEN_INT (mask1);
971  operands[4] = GEN_INT (mask2);
972})
973
974(define_insn "zero_extendqi<mode>2"
975  [(set (match_operand:I248MODE 0 "register_operand" "=r,r")
976	(zero_extend:I248MODE
977	  (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
978  ""
979  "@
980   and %1,0xff,%0
981   ldbu %0,%1"
982  [(set_attr "type" "ilog,ild")
983   (set_attr "isa" "*,bwx")])
984
985(define_insn "zero_extendhi<mode>2"
986  [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
987	(zero_extend:I48MODE
988	  (match_operand:HI 1 "reg_or_bwx_memory_operand" "r,m")))]
989  ""
990  "@
991   zapnot %1,3,%0
992   ldwu %0,%1"
993  [(set_attr "type" "shift,ild")
994   (set_attr "isa" "*,bwx")])
995
996(define_insn "zero_extendsidi2"
997  [(set (match_operand:DI 0 "register_operand" "=r")
998	(zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
999  ""
1000  "zapnot %1,15,%0"
1001  [(set_attr "type" "shift")])
1002
1003(define_insn "andnot<mode>3"
1004  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1005	(and:I48MODE
1006	 (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
1007	 (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))]
1008  ""
1009  "bic %r2,%1,%0"
1010  [(set_attr "type" "ilog")])
1011
1012(define_insn "*iorsi_internal"
1013  [(set (match_operand:SI 0 "register_operand" "=r,r")
1014	(ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
1015		(match_operand:SI 2 "or_operand" "rI,N")))]
1016  ""
1017  "@
1018   bis %r1,%2,%0
1019   ornot %r1,%N2,%0"
1020  [(set_attr "type" "ilog")])
1021
1022(define_insn "iordi3"
1023  [(set (match_operand:DI 0 "register_operand" "=r,r")
1024	(ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1025		(match_operand:DI 2 "or_operand" "rI,N")))]
1026  ""
1027  "@
1028   bis %r1,%2,%0
1029   ornot %r1,%N2,%0"
1030  [(set_attr "type" "ilog")])
1031
1032(define_insn "*one_cmplsi_internal"
1033  [(set (match_operand:SI 0 "register_operand" "=r")
1034	(not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
1035  ""
1036  "ornot $31,%1,%0"
1037  [(set_attr "type" "ilog")])
1038
1039(define_insn "one_cmpldi2"
1040  [(set (match_operand:DI 0 "register_operand" "=r")
1041	(not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
1042  ""
1043  "ornot $31,%1,%0"
1044  [(set_attr "type" "ilog")])
1045
1046(define_insn "*iornot<mode>3"
1047  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1048	(ior:I48MODE
1049	 (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
1050	 (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))]
1051  ""
1052  "ornot %r2,%1,%0"
1053  [(set_attr "type" "ilog")])
1054
1055(define_insn "*xorsi_internal"
1056  [(set (match_operand:SI 0 "register_operand" "=r,r")
1057	(xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
1058		(match_operand:SI 2 "or_operand" "rI,N")))]
1059  ""
1060  "@
1061   xor %r1,%2,%0
1062   eqv %r1,%N2,%0"
1063  [(set_attr "type" "ilog")])
1064
1065(define_insn "xordi3"
1066  [(set (match_operand:DI 0 "register_operand" "=r,r")
1067	(xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1068		(match_operand:DI 2 "or_operand" "rI,N")))]
1069  ""
1070  "@
1071   xor %r1,%2,%0
1072   eqv %r1,%N2,%0"
1073  [(set_attr "type" "ilog")])
1074
1075(define_insn "*xornot<mode>3"
1076  [(set (match_operand:I48MODE 0 "register_operand" "=r")
1077	(not:I48MODE (xor:I48MODE
1078		      (match_operand:I48MODE 1 "register_operand" "%rJ")
1079		      (match_operand:I48MODE 2 "register_operand" "rI"))))]
1080  ""
1081  "eqv %r1,%2,%0"
1082  [(set_attr "type" "ilog")])
1083
1084;; Handle FFS and related insns iff we support CIX.
1085
1086(define_expand "ffsdi2"
1087  [(set (match_dup 2)
1088	(ctz:DI (match_operand:DI 1 "register_operand")))
1089   (set (match_dup 3)
1090	(plus:DI (match_dup 2) (const_int 1)))
1091   (set (match_operand:DI 0 "register_operand")
1092	(if_then_else:DI (eq (match_dup 1) (const_int 0))
1093			 (const_int 0) (match_dup 3)))]
1094  "TARGET_CIX"
1095{
1096  operands[2] = gen_reg_rtx (DImode);
1097  operands[3] = gen_reg_rtx (DImode);
1098})
1099
1100(define_insn "clzdi2"
1101  [(set (match_operand:DI 0 "register_operand" "=r")
1102	(clz:DI (match_operand:DI 1 "register_operand" "r")))]
1103  "TARGET_CIX"
1104  "ctlz %1,%0"
1105  [(set_attr "type" "mvi")])
1106
1107(define_insn "ctzdi2"
1108  [(set (match_operand:DI 0 "register_operand" "=r")
1109	(ctz:DI (match_operand:DI 1 "register_operand" "r")))]
1110  "TARGET_CIX"
1111  "cttz %1,%0"
1112  [(set_attr "type" "mvi")])
1113
1114(define_insn "popcountdi2"
1115  [(set (match_operand:DI 0 "register_operand" "=r")
1116	(popcount:DI (match_operand:DI 1 "register_operand" "r")))]
1117  "TARGET_CIX"
1118  "ctpop %1,%0"
1119  [(set_attr "type" "mvi")])
1120
1121(define_expand "bswapsi2"
1122  [(set (match_operand:SI 0 "register_operand")
1123	(bswap:SI (match_operand:SI 1 "register_operand")))]
1124  "!optimize_size"
1125{
1126  rtx t0, t1;
1127
1128  t0 = gen_reg_rtx (DImode);
1129  t1 = gen_reg_rtx (DImode);
1130
1131  emit_insn (gen_inslh (t0, gen_lowpart (DImode, operands[1]), GEN_INT (7)));
1132  emit_insn (gen_inswl_const (t1, gen_lowpart (HImode, operands[1]),
1133			      GEN_INT (24)));
1134  emit_insn (gen_iordi3 (t1, t0, t1));
1135  emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
1136  emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x5)));
1137  emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xa)));
1138  emit_insn (gen_addsi3 (operands[0], gen_lowpart (SImode, t0),
1139			 gen_lowpart (SImode, t1)));
1140  DONE;
1141})
1142
1143(define_expand "bswapdi2"
1144  [(set (match_operand:DI 0 "register_operand")
1145	(bswap:DI (match_operand:DI 1 "register_operand")))]
1146  "!optimize_size"
1147{
1148  rtx t0, t1;
1149
1150  t0 = gen_reg_rtx (DImode);
1151  t1 = gen_reg_rtx (DImode);
1152
1153  /* This method of shifting and masking is not specific to Alpha, but
1154     is only profitable on Alpha because of our handy byte zap insn.  */
1155
1156  emit_insn (gen_lshrdi3 (t0, operands[1], GEN_INT (32)));
1157  emit_insn (gen_ashldi3 (t1, operands[1], GEN_INT (32)));
1158  emit_insn (gen_iordi3 (t1, t0, t1));
1159
1160  emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
1161  emit_insn (gen_ashldi3 (t1, t1, GEN_INT (16)));
1162  emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xcc)));
1163  emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x33)));
1164  emit_insn (gen_iordi3 (t1, t0, t1));
1165
1166  emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (8)));
1167  emit_insn (gen_ashldi3 (t1, t1, GEN_INT (8)));
1168  emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xaa)));
1169  emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x55)));
1170  emit_insn (gen_iordi3 (operands[0], t0, t1));
1171  DONE;
1172})
1173
1174;; Next come the shifts and the various extract and insert operations.
1175
1176(define_insn "ashldi3"
1177  [(set (match_operand:DI 0 "register_operand" "=r,r")
1178	(ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
1179		   (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
1180  ""
1181{
1182  switch (which_alternative)
1183    {
1184    case 0:
1185      if (operands[2] == const1_rtx)
1186	return "addq %r1,%r1,%0";
1187      else
1188	return "s%P2addq %r1,0,%0";
1189    case 1:
1190      return "sll %r1,%2,%0";
1191    default:
1192      gcc_unreachable ();
1193    }
1194}
1195  [(set_attr "type" "iadd,shift")])
1196
1197(define_insn "*ashldi_se"
1198  [(set (match_operand:DI 0 "register_operand" "=r")
1199	(sign_extend:DI
1200	 (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1201			       (match_operand:DI 2 "const_int_operand" "P"))
1202		    0)))]
1203  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
1204{
1205  if (operands[2] == const1_rtx)
1206    return "addl %r1,%r1,%0";
1207  else
1208    return "s%P2addl %r1,0,%0";
1209}
1210  [(set_attr "type" "iadd")])
1211
1212(define_insn "lshrdi3"
1213  [(set (match_operand:DI 0 "register_operand" "=r")
1214	(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1215		     (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1216  ""
1217  "srl %r1,%2,%0"
1218  [(set_attr "type" "shift")])
1219
1220(define_insn "ashrdi3"
1221  [(set (match_operand:DI 0 "register_operand" "=r")
1222	(ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1223		     (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1224  ""
1225  "sra %r1,%2,%0"
1226  [(set_attr "type" "shift")])
1227
1228(define_insn "extendqi<mode>2"
1229  [(set (match_operand:I24MODE 0 "register_operand" "=r")
1230	(sign_extend:I24MODE
1231	 (match_operand:QI 1 "register_operand" "r")))]
1232  "TARGET_BWX"
1233  "sextb %1,%0"
1234  [(set_attr "type" "shift")])
1235
1236(define_expand "extendqidi2"
1237  [(set (match_operand:DI 0 "register_operand")
1238	(sign_extend:DI (match_operand:QI 1 "general_operand")))]
1239  ""
1240{
1241  if (TARGET_BWX)
1242    operands[1] = force_reg (QImode, operands[1]);
1243  else
1244    {
1245      rtx x, t1, t2, i56;
1246
1247      if (unaligned_memory_operand (operands[1], QImode))
1248	{
1249	  x = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0));
1250	  alpha_set_memflags (x, operands[1]);
1251	  emit_insn (x);
1252	  DONE;
1253	}
1254
1255      t1 = gen_reg_rtx (DImode);
1256      t2 = gen_reg_rtx (DImode);
1257      i56 = GEN_INT (56);
1258
1259      x = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1260      emit_move_insn (t1, x);
1261      emit_insn (gen_ashldi3 (t2, t1, i56));
1262      emit_insn (gen_ashrdi3 (operands[0], t2, i56));
1263      DONE;
1264    }
1265})
1266
1267(define_insn "*extendqidi2_bwx"
1268  [(set (match_operand:DI 0 "register_operand" "=r")
1269	(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1270  "TARGET_BWX"
1271  "sextb %1,%0"
1272  [(set_attr "type" "shift")])
1273
1274(define_insn "extendhisi2"
1275  [(set (match_operand:SI 0 "register_operand" "=r")
1276	(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1277  "TARGET_BWX"
1278  "sextw %1,%0"
1279  [(set_attr "type" "shift")])
1280
1281(define_expand "extendhidi2"
1282  [(set (match_operand:DI 0 "register_operand")
1283	(sign_extend:DI (match_operand:HI 1 "general_operand")))]
1284  ""
1285{
1286  if (TARGET_BWX)
1287    operands[1] = force_reg (HImode, operands[1]);
1288  else
1289    {
1290      rtx x, t1, t2, i48;
1291
1292      if (unaligned_memory_operand (operands[1], HImode))
1293	{
1294	  x = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0));
1295	  alpha_set_memflags (x, operands[1]);
1296	  emit_insn (x);
1297	  DONE;
1298	}
1299
1300      t1 = gen_reg_rtx (DImode);
1301      t2 = gen_reg_rtx (DImode);
1302      i48 = GEN_INT (48);
1303
1304      x = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1305      emit_move_insn (t1, x);
1306      emit_insn (gen_ashldi3 (t2, t1, i48));
1307      emit_insn (gen_ashrdi3 (operands[0], t2, i48));
1308      DONE;
1309    }
1310})
1311
1312(define_insn "*extendhidi2_bwx"
1313  [(set (match_operand:DI 0 "register_operand" "=r")
1314	(sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1315  "TARGET_BWX"
1316  "sextw %1,%0"
1317  [(set_attr "type" "shift")])
1318
1319;; Here's how we sign extend an unaligned byte and halfword.  Doing this
1320;; as a pattern saves one instruction.  The code is similar to that for
1321;; the unaligned loads (see below).
1322;;
1323;; Operand 1 is the address, operand 0 is the result.
1324
1325(define_expand "unaligned_extendqidi"
1326  [(set (match_dup 3)
1327	(mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8))))
1328   (set (match_dup 4)
1329	(ashift:DI (match_dup 3)
1330		   (minus:DI (const_int 64)
1331			     (ashift:DI
1332			      (and:DI (match_dup 2) (const_int 7))
1333			      (const_int 3)))))
1334   (set (match_operand:QI 0 "register_operand")
1335	(ashiftrt:DI (match_dup 4) (const_int 56)))]
1336  ""
1337{
1338  operands[0] = gen_lowpart (DImode, operands[0]);
1339  operands[2] = get_unaligned_offset (operands[1], 1);
1340  operands[3] = gen_reg_rtx (DImode);
1341  operands[4] = gen_reg_rtx (DImode);
1342})
1343
1344(define_expand "unaligned_extendhidi"
1345  [(set (match_dup 3)
1346	(mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8))))
1347   (set (match_dup 4)
1348	(ashift:DI (match_dup 3)
1349		   (minus:DI (const_int 64)
1350			     (ashift:DI
1351			      (and:DI (match_dup 2) (const_int 7))
1352			      (const_int 3)))))
1353   (set (match_operand:HI 0 "register_operand")
1354	(ashiftrt:DI (match_dup 4) (const_int 48)))]
1355  ""
1356{
1357  operands[0] = gen_lowpart (DImode, operands[0]);
1358  operands[2] = get_unaligned_offset (operands[1], 2);
1359  operands[3] = gen_reg_rtx (DImode);
1360  operands[4] = gen_reg_rtx (DImode);
1361})
1362
1363(define_insn "*extxl_const"
1364  [(set (match_operand:DI 0 "register_operand" "=r")
1365	(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1366			 (match_operand:DI 2 "mode_width_operand" "n")
1367			 (match_operand:DI 3 "mul8_operand" "I")))]
1368  ""
1369  "ext%M2l %r1,%s3,%0"
1370  [(set_attr "type" "shift")])
1371
1372(define_insn "extxl"
1373  [(set (match_operand:DI 0 "register_operand" "=r")
1374	(zero_extract:DI
1375	  (match_operand:DI 1 "reg_or_0_operand" "rJ")
1376	  (match_operand:DI 2 "mode_width_operand" "n")
1377	  (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1378		     (const_int 3))))]
1379  ""
1380  "ext%M2l %r1,%3,%0"
1381  [(set_attr "type" "shift")])
1382
1383;; Combine has some strange notion of preserving existing undefined behavior
1384;; in shifts larger than a word size.  So capture these patterns that it
1385;; should have turned into zero_extracts.
1386
1387(define_insn "*extxl_1"
1388  [(set (match_operand:DI 0 "register_operand" "=r")
1389	(and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1390		  (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1391			     (const_int 3)))
1392	     (match_operand:DI 3 "mode_mask_operand" "n")))]
1393  ""
1394  "ext%U3l %1,%2,%0"
1395  [(set_attr "type" "shift")])
1396
1397(define_insn "*extql_2"
1398  [(set (match_operand:DI 0 "register_operand" "=r")
1399	(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1400	  (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1401		     (const_int 3))))]
1402  ""
1403  "extql %1,%2,%0"
1404  [(set_attr "type" "shift")])
1405
1406(define_insn "extqh"
1407  [(set (match_operand:DI 0 "register_operand" "=r")
1408	(ashift:DI
1409	 (match_operand:DI 1 "reg_or_0_operand" "rJ")
1410	  (minus:DI (const_int 64)
1411		    (ashift:DI
1412		     (and:DI
1413		      (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1414		      (const_int 7))
1415		     (const_int 3)))))]
1416  ""
1417  "extqh %r1,%2,%0"
1418  [(set_attr "type" "shift")])
1419
1420(define_insn "extwh"
1421  [(set (match_operand:DI 0 "register_operand" "=r")
1422	(ashift:DI
1423	 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1424		 (const_int 65535))
1425	 (minus:DI (const_int 64)
1426		    (ashift:DI
1427		     (and:DI
1428		      (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1429		      (const_int 7))
1430		     (const_int 3)))))]
1431  ""
1432  "extwh %r1,%2,%0"
1433  [(set_attr "type" "shift")])
1434
1435(define_insn "extlh"
1436  [(set (match_operand:DI 0 "register_operand" "=r")
1437	(ashift:DI
1438	 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1439		 (const_int 2147483647))
1440	 (minus:DI (const_int 64)
1441		    (ashift:DI
1442		     (and:DI
1443		      (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1444		      (const_int 7))
1445		     (const_int 3)))))]
1446  ""
1447  "extlh %r1,%2,%0"
1448  [(set_attr "type" "shift")])
1449
1450;; This converts an extXl into an extXh with an appropriate adjustment
1451;; to the address calculation.
1452
1453;;(define_split
1454;;  [(set (match_operand:DI 0 "register_operand")
1455;;	(ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand")
1456;;				    (match_operand:DI 2 "mode_width_operand")
1457;;				    (ashift:DI (match_operand:DI 3)
1458;;					       (const_int 3)))
1459;;		   (match_operand:DI 4 "const_int_operand")))
1460;;   (clobber (match_operand:DI 5 "register_operand"))]
1461;;  "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1462;;  [(set (match_dup 5) (match_dup 6))
1463;;   (set (match_dup 0)
1464;;	(ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1465;;				    (ashift:DI (plus:DI (match_dup 5)
1466;;							(match_dup 7))
1467;;					       (const_int 3)))
1468;;		   (match_dup 4)))]
1469;;  "
1470;;{
1471;;  operands[6] = plus_constant (DImode, operands[3],
1472;;			       INTVAL (operands[2]) / BITS_PER_UNIT);
1473;;  operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1474;;}")
1475
1476(define_insn "ins<modesuffix>l_const"
1477  [(set (match_operand:DI 0 "register_operand" "=r")
1478	(ashift:DI (zero_extend:DI
1479		    (match_operand:I124MODE 1 "register_operand" "r"))
1480		   (match_operand:DI 2 "mul8_operand" "I")))]
1481  ""
1482  "ins<modesuffix>l %1,%s2,%0"
1483  [(set_attr "type" "shift")])
1484
1485(define_insn "ins<modesuffix>l"
1486  [(set (match_operand:DI 0 "register_operand" "=r")
1487	(ashift:DI (zero_extend:DI
1488		    (match_operand:I124MODE 1 "register_operand" "r"))
1489		   (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1490			      (const_int 3))))]
1491  ""
1492  "ins<modesuffix>l %1,%2,%0"
1493  [(set_attr "type" "shift")])
1494
1495(define_insn "insql"
1496  [(set (match_operand:DI 0 "register_operand" "=r")
1497	(ashift:DI (match_operand:DI 1 "register_operand" "r")
1498		   (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1499			      (const_int 3))))]
1500  ""
1501  "insql %1,%2,%0"
1502  [(set_attr "type" "shift")])
1503
1504;; Combine has this sometimes habit of moving the and outside of the
1505;; shift, making life more interesting.
1506
1507(define_insn "*insxl"
1508  [(set (match_operand:DI 0 "register_operand" "=r")
1509	(and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
1510		   	   (match_operand:DI 2 "mul8_operand" "I"))
1511		(match_operand:DI 3 "const_int_operand" "i")))]
1512  "((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1513    == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1514    || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1515        == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1516    || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1517        == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))"
1518{
1519  if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1520      == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1521    return "insbl %1,%s2,%0";
1522  if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1523      == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1524    return "inswl %1,%s2,%0";
1525  if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1526      == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1527    return "insll %1,%s2,%0";
1528
1529  gcc_unreachable ();
1530}
1531  [(set_attr "type" "shift")])
1532
1533;; We do not include the insXh insns because they are complex to express
1534;; and it does not appear that we would ever want to generate them.
1535;;
1536;; Since we need them for block moves, though, cop out and use unspec.
1537
1538(define_insn "insxh"
1539  [(set (match_operand:DI 0 "register_operand" "=r")
1540	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
1541		    (match_operand:DI 2 "mode_width_operand" "n")
1542		    (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
1543		   UNSPEC_INSXH))]
1544  ""
1545  "ins%M2h %1,%3,%0"
1546  [(set_attr "type" "shift")])
1547
1548(define_insn "mskxl"
1549  [(set (match_operand:DI 0 "register_operand" "=r")
1550	(and:DI (not:DI (ashift:DI
1551			 (match_operand:DI 2 "mode_mask_operand" "n")
1552			 (ashift:DI
1553			  (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1554			  (const_int 3))))
1555		(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1556  ""
1557  "msk%U2l %r1,%3,%0"
1558  [(set_attr "type" "shift")])
1559
1560;; We do not include the mskXh insns because it does not appear we would
1561;; ever generate one.
1562;;
1563;; Again, we do for block moves and we use unspec again.
1564
1565(define_insn "mskxh"
1566  [(set (match_operand:DI 0 "register_operand" "=r")
1567	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
1568		    (match_operand:DI 2 "mode_width_operand" "n")
1569		    (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
1570		   UNSPEC_MSKXH))]
1571  ""
1572  "msk%M2h %1,%3,%0"
1573  [(set_attr "type" "shift")])
1574
1575;; Prefer AND + NE over LSHIFTRT + AND.
1576
1577(define_insn_and_split "*ze_and_ne"
1578  [(set (match_operand:DI 0 "register_operand" "=r")
1579	(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1580			 (const_int 1)
1581			 (match_operand 2 "const_int_operand" "I")))]
1582  "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
1583  "#"
1584  "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
1585  [(set (match_dup 0)
1586	(and:DI (match_dup 1) (match_dup 3)))
1587   (set (match_dup 0)
1588	(ne:DI (match_dup 0) (const_int 0)))]
1589  "operands[3] = GEN_INT (1 << INTVAL (operands[2]));")
1590
1591;; Floating-point operations.  All the double-precision insns can extend
1592;; from single, so indicate that.  The exception are the ones that simply
1593;; play with the sign bits; it's not clear what to do there.
1594
1595(define_mode_iterator FMODE [SF DF])
1596
1597(define_mode_attr opmode [(SF "si") (DF "di")])
1598
1599(define_insn "abs<mode>2"
1600  [(set (match_operand:FMODE 0 "register_operand" "=f")
1601	(abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1602  "TARGET_FP"
1603  "cpys $f31,%R1,%0"
1604  [(set_attr "type" "fcpys")])
1605
1606(define_insn "*nabs<mode>2"
1607  [(set (match_operand:FMODE 0 "register_operand" "=f")
1608	(neg:FMODE
1609	 (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG"))))]
1610  "TARGET_FP"
1611  "cpysn $f31,%R1,%0"
1612  [(set_attr "type" "fadd")])
1613
1614(define_expand "abstf2"
1615  [(parallel [(set (match_operand:TF 0 "register_operand")
1616		   (abs:TF (match_operand:TF 1 "reg_or_0_operand")))
1617	      (use (match_dup 2))])]
1618  "TARGET_HAS_XFLOATING_LIBS"
1619  "operands[2] = force_reg (DImode, GEN_INT (HOST_WIDE_INT_1U << 63));")
1620
1621(define_insn_and_split "*abstf_internal"
1622  [(set (match_operand:TF 0 "register_operand" "=r")
1623	(abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
1624   (use (match_operand:DI 2 "register_operand" "r"))]
1625  "TARGET_HAS_XFLOATING_LIBS"
1626  "#"
1627  "&& reload_completed"
1628  [(const_int 0)]
1629  "alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
1630
1631(define_insn "neg<mode>2"
1632  [(set (match_operand:FMODE 0 "register_operand" "=f")
1633	(neg:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1634  "TARGET_FP"
1635  "cpysn %R1,%R1,%0"
1636  [(set_attr "type" "fadd")])
1637
1638(define_expand "negtf2"
1639  [(parallel [(set (match_operand:TF 0 "register_operand")
1640		   (neg:TF (match_operand:TF 1 "reg_or_0_operand")))
1641	      (use (match_dup 2))])]
1642  "TARGET_HAS_XFLOATING_LIBS"
1643  "operands[2] = force_reg (DImode, GEN_INT (HOST_WIDE_INT_1U << 63));")
1644
1645(define_insn_and_split "*negtf_internal"
1646  [(set (match_operand:TF 0 "register_operand" "=r")
1647	(neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
1648   (use (match_operand:DI 2 "register_operand" "r"))]
1649  "TARGET_HAS_XFLOATING_LIBS"
1650  "#"
1651  "&& reload_completed"
1652  [(const_int 0)]
1653  "alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
1654
1655(define_insn "copysign<mode>3"
1656  [(set (match_operand:FMODE 0 "register_operand" "=f")
1657	(unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
1658		       (match_operand:FMODE 2 "reg_or_0_operand" "fG")]
1659		      UNSPEC_COPYSIGN))]
1660  "TARGET_FP"
1661  "cpys %R2,%R1,%0"
1662  [(set_attr "type" "fadd")])
1663
1664(define_insn "*ncopysign<mode>3"
1665  [(set (match_operand:FMODE 0 "register_operand" "=f")
1666	(neg:FMODE
1667	 (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
1668			(match_operand:FMODE 2 "reg_or_0_operand" "fG")]
1669		       UNSPEC_COPYSIGN)))]
1670  "TARGET_FP"
1671  "cpysn %R2,%R1,%0"
1672  [(set_attr "type" "fadd")])
1673
1674(define_insn "*add<mode>3_ieee"
1675  [(set (match_operand:FMODE 0 "register_operand" "=&f")
1676	(plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1677		    (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1678  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1679  "add<modesuffix>%/ %R1,%R2,%0"
1680  [(set_attr "type" "fadd")
1681   (set_attr "trap" "yes")
1682   (set_attr "round_suffix" "normal")
1683   (set_attr "trap_suffix" "u_su_sui")])
1684
1685(define_insn "add<mode>3"
1686  [(set (match_operand:FMODE 0 "register_operand" "=f")
1687	(plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1688		    (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1689  "TARGET_FP"
1690  "add<modesuffix>%/ %R1,%R2,%0"
1691  [(set_attr "type" "fadd")
1692   (set_attr "trap" "yes")
1693   (set_attr "round_suffix" "normal")
1694   (set_attr "trap_suffix" "u_su_sui")])
1695
1696(define_insn "*adddf_ext1"
1697  [(set (match_operand:DF 0 "register_operand" "=f")
1698	(plus:DF (float_extend:DF
1699		  (match_operand:SF 1 "reg_or_0_operand" "fG"))
1700		 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1701  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1702  "add%-%/ %R1,%R2,%0"
1703  [(set_attr "type" "fadd")
1704   (set_attr "trap" "yes")
1705   (set_attr "round_suffix" "normal")
1706   (set_attr "trap_suffix" "u_su_sui")])
1707
1708(define_insn "*adddf_ext2"
1709  [(set (match_operand:DF 0 "register_operand" "=f")
1710	(plus:DF (float_extend:DF
1711		  (match_operand:SF 1 "reg_or_0_operand" "%fG"))
1712		 (float_extend:DF
1713		  (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1714  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1715  "add%-%/ %R1,%R2,%0"
1716  [(set_attr "type" "fadd")
1717   (set_attr "trap" "yes")
1718   (set_attr "round_suffix" "normal")
1719   (set_attr "trap_suffix" "u_su_sui")])
1720
1721(define_expand "addtf3"
1722  [(use (match_operand:TF 0 "register_operand"))
1723   (use (match_operand:TF 1 "general_operand"))
1724   (use (match_operand:TF 2 "general_operand"))]
1725  "TARGET_HAS_XFLOATING_LIBS"
1726  "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
1727
1728(define_insn "*sub<mode>3_ieee"
1729  [(set (match_operand:FMODE 0 "register_operand" "=&f")
1730	(minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1731		     (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1732  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1733  "sub<modesuffix>%/ %R1,%R2,%0"
1734  [(set_attr "type" "fadd")
1735   (set_attr "trap" "yes")
1736   (set_attr "round_suffix" "normal")
1737   (set_attr "trap_suffix" "u_su_sui")])
1738
1739(define_insn "sub<mode>3"
1740  [(set (match_operand:FMODE 0 "register_operand" "=f")
1741	(minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1742		     (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1743  "TARGET_FP"
1744  "sub<modesuffix>%/ %R1,%R2,%0"
1745  [(set_attr "type" "fadd")
1746   (set_attr "trap" "yes")
1747   (set_attr "round_suffix" "normal")
1748   (set_attr "trap_suffix" "u_su_sui")])
1749
1750(define_insn "*subdf_ext1"
1751  [(set (match_operand:DF 0 "register_operand" "=f")
1752	(minus:DF (float_extend:DF
1753		   (match_operand:SF 1 "reg_or_0_operand" "fG"))
1754		  (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1755  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1756  "sub%-%/ %R1,%R2,%0"
1757  [(set_attr "type" "fadd")
1758   (set_attr "trap" "yes")
1759   (set_attr "round_suffix" "normal")
1760   (set_attr "trap_suffix" "u_su_sui")])
1761
1762(define_insn "*subdf_ext2"
1763  [(set (match_operand:DF 0 "register_operand" "=f")
1764	(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
1765		  (float_extend:DF
1766		   (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1767  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1768  "sub%-%/ %R1,%R2,%0"
1769  [(set_attr "type" "fadd")
1770   (set_attr "trap" "yes")
1771   (set_attr "round_suffix" "normal")
1772   (set_attr "trap_suffix" "u_su_sui")])
1773
1774(define_insn "*subdf_ext3"
1775  [(set (match_operand:DF 0 "register_operand" "=f")
1776	(minus:DF (float_extend:DF
1777		   (match_operand:SF 1 "reg_or_0_operand" "fG"))
1778		  (float_extend:DF
1779		   (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1780  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1781  "sub%-%/ %R1,%R2,%0"
1782  [(set_attr "type" "fadd")
1783   (set_attr "trap" "yes")
1784   (set_attr "round_suffix" "normal")
1785   (set_attr "trap_suffix" "u_su_sui")])
1786
1787(define_expand "subtf3"
1788  [(use (match_operand:TF 0 "register_operand"))
1789   (use (match_operand:TF 1 "general_operand"))
1790   (use (match_operand:TF 2 "general_operand"))]
1791  "TARGET_HAS_XFLOATING_LIBS"
1792  "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
1793
1794(define_insn "*mul<mode>3_ieee"
1795  [(set (match_operand:FMODE 0 "register_operand" "=&f")
1796	(mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1797		    (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1798  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1799  "mul<modesuffix>%/ %R1,%R2,%0"
1800  [(set_attr "type" "fmul")
1801   (set_attr "trap" "yes")
1802   (set_attr "round_suffix" "normal")
1803   (set_attr "trap_suffix" "u_su_sui")])
1804
1805(define_insn "mul<mode>3"
1806  [(set (match_operand:FMODE 0 "register_operand" "=f")
1807	(mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1808		    (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1809  "TARGET_FP"
1810  "mul<modesuffix>%/ %R1,%R2,%0"
1811  [(set_attr "type" "fmul")
1812   (set_attr "trap" "yes")
1813   (set_attr "round_suffix" "normal")
1814   (set_attr "trap_suffix" "u_su_sui")])
1815
1816(define_insn "*muldf_ext1"
1817  [(set (match_operand:DF 0 "register_operand" "=f")
1818	(mult:DF (float_extend:DF
1819		  (match_operand:SF 1 "reg_or_0_operand" "fG"))
1820		 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1821  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1822  "mul%-%/ %R1,%R2,%0"
1823  [(set_attr "type" "fmul")
1824   (set_attr "trap" "yes")
1825   (set_attr "round_suffix" "normal")
1826   (set_attr "trap_suffix" "u_su_sui")])
1827
1828(define_insn "*muldf_ext2"
1829  [(set (match_operand:DF 0 "register_operand" "=f")
1830	(mult:DF (float_extend:DF
1831		  (match_operand:SF 1 "reg_or_0_operand" "%fG"))
1832		 (float_extend:DF
1833		  (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1834  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1835  "mul%-%/ %R1,%R2,%0"
1836  [(set_attr "type" "fmul")
1837   (set_attr "trap" "yes")
1838   (set_attr "round_suffix" "normal")
1839   (set_attr "trap_suffix" "u_su_sui")])
1840
1841(define_expand "multf3"
1842  [(use (match_operand:TF 0 "register_operand"))
1843   (use (match_operand:TF 1 "general_operand"))
1844   (use (match_operand:TF 2 "general_operand"))]
1845  "TARGET_HAS_XFLOATING_LIBS"
1846  "alpha_emit_xfloating_arith (MULT, operands); DONE;")
1847
1848(define_insn "*div<mode>3_ieee"
1849  [(set (match_operand:FMODE 0 "register_operand" "=&f")
1850	(div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1851		   (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1852  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1853  "div<modesuffix>%/ %R1,%R2,%0"
1854  [(set_attr "type" "fdiv")
1855   (set_attr "opsize" "<opmode>")
1856   (set_attr "trap" "yes")
1857   (set_attr "round_suffix" "normal")
1858   (set_attr "trap_suffix" "u_su_sui")])
1859
1860(define_insn "div<mode>3"
1861  [(set (match_operand:FMODE 0 "register_operand" "=f")
1862	(div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1863		   (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1864  "TARGET_FP"
1865  "div<modesuffix>%/ %R1,%R2,%0"
1866  [(set_attr "type" "fdiv")
1867   (set_attr "opsize" "<opmode>")
1868   (set_attr "trap" "yes")
1869   (set_attr "round_suffix" "normal")
1870   (set_attr "trap_suffix" "u_su_sui")])
1871
1872(define_insn "*divdf_ext1"
1873  [(set (match_operand:DF 0 "register_operand" "=f")
1874	(div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
1875		(match_operand:DF 2 "reg_or_0_operand" "fG")))]
1876  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1877  "div%-%/ %R1,%R2,%0"
1878  [(set_attr "type" "fdiv")
1879   (set_attr "trap" "yes")
1880   (set_attr "round_suffix" "normal")
1881   (set_attr "trap_suffix" "u_su_sui")])
1882
1883(define_insn "*divdf_ext2"
1884  [(set (match_operand:DF 0 "register_operand" "=f")
1885	(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
1886		(float_extend:DF
1887		 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1888  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1889  "div%-%/ %R1,%R2,%0"
1890  [(set_attr "type" "fdiv")
1891   (set_attr "trap" "yes")
1892   (set_attr "round_suffix" "normal")
1893   (set_attr "trap_suffix" "u_su_sui")])
1894
1895(define_insn "*divdf_ext3"
1896  [(set (match_operand:DF 0 "register_operand" "=f")
1897	(div:DF (float_extend:DF
1898		 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1899		(float_extend:DF
1900		 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1901  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1902  "div%-%/ %R1,%R2,%0"
1903  [(set_attr "type" "fdiv")
1904   (set_attr "trap" "yes")
1905   (set_attr "round_suffix" "normal")
1906   (set_attr "trap_suffix" "u_su_sui")])
1907
1908(define_expand "divtf3"
1909  [(use (match_operand:TF 0 "register_operand"))
1910   (use (match_operand:TF 1 "general_operand"))
1911   (use (match_operand:TF 2 "general_operand"))]
1912  "TARGET_HAS_XFLOATING_LIBS"
1913  "alpha_emit_xfloating_arith (DIV, operands); DONE;")
1914
1915(define_insn "*sqrt<mode>2_ieee"
1916  [(set (match_operand:FMODE 0 "register_operand" "=&f")
1917	(sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1918  "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
1919  "sqrt<modesuffix>%/ %R1,%0"
1920  [(set_attr "type" "fsqrt")
1921   (set_attr "opsize" "<opmode>")
1922   (set_attr "trap" "yes")
1923   (set_attr "round_suffix" "normal")
1924   (set_attr "trap_suffix" "u_su_sui")])
1925
1926(define_insn "sqrt<mode>2"
1927  [(set (match_operand:FMODE 0 "register_operand" "=f")
1928	(sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1929  "TARGET_FP && TARGET_FIX"
1930  "sqrt<modesuffix>%/ %R1,%0"
1931  [(set_attr "type" "fsqrt")
1932   (set_attr "opsize" "<opmode>")
1933   (set_attr "trap" "yes")
1934   (set_attr "round_suffix" "normal")
1935   (set_attr "trap_suffix" "u_su_sui")])
1936
1937;; Define conversion operators between DFmode and SImode, using the cvtql
1938;; instruction.  To allow combine et al to do useful things, we keep the
1939;; operation as a unit until after reload, at which point we split the
1940;; instructions.
1941;;
1942;; Note that we (attempt to) only consider this optimization when the
1943;; ultimate destination is memory.  If we will be doing further integer
1944;; processing, it is cheaper to do the truncation in the int regs.
1945
1946(define_insn "*cvtql"
1947  [(set (match_operand:SF 0 "register_operand" "=f")
1948	(unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
1949		   UNSPEC_CVTQL))]
1950  "TARGET_FP"
1951  "cvtql%/ %R1,%0"
1952  [(set_attr "type" "fadd")
1953   (set_attr "trap" "yes")
1954   (set_attr "trap_suffix" "v_sv")])
1955
1956(define_insn_and_split "*fix_truncdfsi_ieee"
1957  [(set (match_operand:SI 0 "memory_operand" "=m")
1958	(subreg:SI
1959	  (match_operator:DI 4 "fix_operator"
1960	    [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
1961   (clobber (match_scratch:DI 2 "=&f"))
1962   (clobber (match_scratch:SF 3 "=&f"))]
1963  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1964  "#"
1965  "&& reload_completed"
1966  [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)]))
1967   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
1968   (set (match_dup 5) (match_dup 3))]
1969{
1970  operands[5] = adjust_address (operands[0], SFmode, 0);
1971}
1972  [(set_attr "type" "fadd")
1973   (set_attr "trap" "yes")])
1974
1975(define_insn_and_split "*fix_truncdfsi_internal"
1976  [(set (match_operand:SI 0 "memory_operand" "=m")
1977	(subreg:SI
1978	  (match_operator:DI 3 "fix_operator"
1979	    [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
1980   (clobber (match_scratch:DI 2 "=f"))]
1981  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1982  "#"
1983  "&& reload_completed"
1984  [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)]))
1985   (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
1986   (set (match_dup 5) (match_dup 4))]
1987{
1988  operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
1989  operands[5] = adjust_address (operands[0], SFmode, 0);
1990}
1991  [(set_attr "type" "fadd")
1992   (set_attr "trap" "yes")])
1993
1994(define_insn "*fix_truncdfdi_ieee"
1995  [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
1996	(match_operator:DI 2 "fix_operator"
1997	  [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
1998  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1999  "cvt%-q%/ %R1,%0"
2000  [(set_attr "type" "fadd")
2001   (set_attr "trap" "yes")
2002   (set_attr "round_suffix" "c")
2003   (set_attr "trap_suffix" "v_sv_svi")])
2004
2005(define_insn "*fix_truncdfdi2"
2006  [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2007	(match_operator:DI 2 "fix_operator"
2008	  [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
2009  "TARGET_FP"
2010  "cvt%-q%/ %R1,%0"
2011  [(set_attr "type" "fadd")
2012   (set_attr "trap" "yes")
2013   (set_attr "round_suffix" "c")
2014   (set_attr "trap_suffix" "v_sv_svi")])
2015
2016(define_expand "fix_truncdfdi2"
2017  [(set (match_operand:DI 0 "reg_no_subreg_operand")
2018	(fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
2019  "TARGET_FP")
2020
2021(define_expand "fixuns_truncdfdi2"
2022  [(set (match_operand:DI 0 "reg_no_subreg_operand")
2023	(unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
2024  "TARGET_FP")
2025
2026;; Likewise between SFmode and SImode.
2027
2028(define_insn_and_split "*fix_truncsfsi_ieee"
2029  [(set (match_operand:SI 0 "memory_operand" "=m")
2030	(subreg:SI
2031	  (match_operator:DI 4 "fix_operator"
2032	    [(float_extend:DF
2033	       (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
2034   (clobber (match_scratch:DI 2 "=&f"))
2035   (clobber (match_scratch:SF 3 "=&f"))]
2036  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2037  "#"
2038  "&& reload_completed"
2039  [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
2040   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2041   (set (match_dup 5) (match_dup 3))]
2042  "operands[5] = adjust_address (operands[0], SFmode, 0);"
2043  [(set_attr "type" "fadd")
2044   (set_attr "trap" "yes")])
2045
2046(define_insn_and_split "*fix_truncsfsi_internal"
2047  [(set (match_operand:SI 0 "memory_operand" "=m")
2048	(subreg:SI
2049	  (match_operator:DI 3 "fix_operator"
2050	    [(float_extend:DF
2051	       (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
2052   (clobber (match_scratch:DI 2 "=f"))]
2053  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2054  "#"
2055  "&& reload_completed"
2056  [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))]))
2057   (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2058   (set (match_dup 5) (match_dup 4))]
2059{
2060  operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
2061  operands[5] = adjust_address (operands[0], SFmode, 0);
2062}
2063  [(set_attr "type" "fadd")
2064   (set_attr "trap" "yes")])
2065
2066(define_insn "*fix_truncsfdi_ieee"
2067  [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2068	(match_operator:DI 2 "fix_operator"
2069	  [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
2070  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2071  "cvt%-q%/ %R1,%0"
2072  [(set_attr "type" "fadd")
2073   (set_attr "trap" "yes")
2074   (set_attr "round_suffix" "c")
2075   (set_attr "trap_suffix" "v_sv_svi")])
2076
2077(define_insn "*fix_truncsfdi2"
2078  [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2079	(match_operator:DI 2 "fix_operator"
2080	  [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
2081  "TARGET_FP"
2082  "cvt%-q%/ %R1,%0"
2083  [(set_attr "type" "fadd")
2084   (set_attr "trap" "yes")
2085   (set_attr "round_suffix" "c")
2086   (set_attr "trap_suffix" "v_sv_svi")])
2087
2088(define_expand "fix_truncsfdi2"
2089  [(set (match_operand:DI 0 "reg_no_subreg_operand")
2090	(fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
2091  "TARGET_FP")
2092
2093(define_expand "fixuns_truncsfdi2"
2094  [(set (match_operand:DI 0 "reg_no_subreg_operand")
2095	(unsigned_fix:DI
2096	  (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
2097  "TARGET_FP")
2098
2099(define_expand "fix_trunctfdi2"
2100  [(use (match_operand:DI 0 "register_operand"))
2101   (use (match_operand:TF 1 "general_operand"))]
2102  "TARGET_HAS_XFLOATING_LIBS"
2103  "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
2104
2105(define_expand "fixuns_trunctfdi2"
2106  [(use (match_operand:DI 0 "register_operand"))
2107   (use (match_operand:TF 1 "general_operand"))]
2108  "TARGET_HAS_XFLOATING_LIBS"
2109  "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
2110
2111(define_insn "*floatdisf_ieee"
2112  [(set (match_operand:SF 0 "register_operand" "=&f")
2113	(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2114  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2115  "cvtq%,%/ %1,%0"
2116  [(set_attr "type" "fadd")
2117   (set_attr "trap" "yes")
2118   (set_attr "round_suffix" "normal")
2119   (set_attr "trap_suffix" "sui")])
2120
2121(define_insn "floatdisf2"
2122  [(set (match_operand:SF 0 "register_operand" "=f")
2123	(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2124  "TARGET_FP"
2125  "cvtq%,%/ %1,%0"
2126  [(set_attr "type" "fadd")
2127   (set_attr "trap" "yes")
2128   (set_attr "round_suffix" "normal")
2129   (set_attr "trap_suffix" "sui")])
2130
2131(define_insn_and_split "*floatsisf2_ieee"
2132  [(set (match_operand:SF 0 "register_operand" "=&f")
2133	(float:SF (match_operand:SI 1 "memory_operand" "m")))
2134   (clobber (match_scratch:DI 2 "=&f"))
2135   (clobber (match_scratch:SF 3 "=&f"))]
2136  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2137  "#"
2138  "&& reload_completed"
2139  [(set (match_dup 3) (match_dup 1))
2140   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2141   (set (match_dup 0) (float:SF (match_dup 2)))]
2142  "operands[1] = adjust_address (operands[1], SFmode, 0);")
2143
2144(define_insn_and_split "*floatsisf2"
2145  [(set (match_operand:SF 0 "register_operand" "=f")
2146	(float:SF (match_operand:SI 1 "memory_operand" "m")))]
2147  "TARGET_FP"
2148  "#"
2149  "&& reload_completed"
2150  [(set (match_dup 0) (match_dup 1))
2151   (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
2152   (set (match_dup 0) (float:SF (match_dup 2)))]
2153{
2154  operands[1] = adjust_address (operands[1], SFmode, 0);
2155  operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
2156})
2157
2158(define_insn "*floatdidf_ieee"
2159  [(set (match_operand:DF 0 "register_operand" "=&f")
2160	(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2161  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2162  "cvtq%-%/ %1,%0"
2163  [(set_attr "type" "fadd")
2164   (set_attr "trap" "yes")
2165   (set_attr "round_suffix" "normal")
2166   (set_attr "trap_suffix" "sui")])
2167
2168(define_insn "floatdidf2"
2169  [(set (match_operand:DF 0 "register_operand" "=f")
2170	(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2171  "TARGET_FP"
2172  "cvtq%-%/ %1,%0"
2173  [(set_attr "type" "fadd")
2174   (set_attr "trap" "yes")
2175   (set_attr "round_suffix" "normal")
2176   (set_attr "trap_suffix" "sui")])
2177
2178(define_insn_and_split "*floatsidf2_ieee"
2179  [(set (match_operand:DF 0 "register_operand" "=&f")
2180	(float:DF (match_operand:SI 1 "memory_operand" "m")))
2181   (clobber (match_scratch:DI 2 "=&f"))
2182   (clobber (match_scratch:SF 3 "=&f"))]
2183  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2184  "#"
2185  "&& reload_completed"
2186  [(set (match_dup 3) (match_dup 1))
2187   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2188   (set (match_dup 0) (float:DF (match_dup 2)))]
2189  "operands[1] = adjust_address (operands[1], SFmode, 0);")
2190
2191(define_insn_and_split "*floatsidf2"
2192  [(set (match_operand:DF 0 "register_operand" "=f")
2193	(float:DF (match_operand:SI 1 "memory_operand" "m")))]
2194  "TARGET_FP"
2195  "#"
2196  "&& reload_completed"
2197  [(set (match_dup 3) (match_dup 1))
2198   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2199   (set (match_dup 0) (float:DF (match_dup 2)))]
2200{
2201  operands[1] = adjust_address (operands[1], SFmode, 0);
2202  operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
2203  operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
2204})
2205
2206(define_expand "floatditf2"
2207  [(use (match_operand:TF 0 "register_operand"))
2208   (use (match_operand:DI 1 "general_operand"))]
2209  "TARGET_HAS_XFLOATING_LIBS"
2210  "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
2211
2212(define_expand "floatunsdisf2"
2213  [(use (match_operand:SF 0 "register_operand"))
2214   (use (match_operand:DI 1 "register_operand"))]
2215  "TARGET_FP"
2216  "alpha_emit_floatuns (operands); DONE;")
2217
2218(define_expand "floatunsdidf2"
2219  [(use (match_operand:DF 0 "register_operand"))
2220   (use (match_operand:DI 1 "register_operand"))]
2221  "TARGET_FP"
2222  "alpha_emit_floatuns (operands); DONE;")
2223
2224(define_expand "floatunsditf2"
2225  [(use (match_operand:TF 0 "register_operand"))
2226   (use (match_operand:DI 1 "general_operand"))]
2227  "TARGET_HAS_XFLOATING_LIBS"
2228  "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
2229
2230(define_expand "extendsfdf2"
2231  [(set (match_operand:DF 0 "register_operand")
2232	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand")))]
2233  "TARGET_FP"
2234{
2235  if (alpha_fptm >= ALPHA_FPTM_SU)
2236    operands[1] = force_reg (SFmode, operands[1]);
2237})
2238
2239;; The Unicos/Mk assembler doesn't support cvtst, but we've already
2240;; asserted that alpha_fptm == ALPHA_FPTM_N.
2241
2242(define_insn "*extendsfdf2_ieee"
2243  [(set (match_operand:DF 0 "register_operand" "=&f")
2244	(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2245  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2246  "cvtsts %1,%0"
2247  [(set_attr "type" "fadd")
2248   (set_attr "trap" "yes")])
2249
2250(define_insn "*extendsfdf2_internal"
2251  [(set (match_operand:DF 0 "register_operand" "=f,f,m")
2252	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
2253  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2254  "@
2255   cpys %1,%1,%0
2256   ld%, %0,%1
2257   st%- %1,%0"
2258  [(set_attr "type" "fcpys,fld,fst")])
2259
2260;; Use register_operand for operand 1 to prevent compress_float_constant
2261;; from doing something silly.  When optimizing we'll put things back
2262;; together anyway.
2263(define_expand "extendsftf2"
2264  [(use (match_operand:TF 0 "register_operand"))
2265   (use (match_operand:SF 1 "register_operand"))]
2266  "TARGET_HAS_XFLOATING_LIBS"
2267{
2268  rtx tmp = gen_reg_rtx (DFmode);
2269  emit_insn (gen_extendsfdf2 (tmp, operands[1]));
2270  emit_insn (gen_extenddftf2 (operands[0], tmp));
2271  DONE;
2272})
2273
2274(define_expand "extenddftf2"
2275  [(use (match_operand:TF 0 "register_operand"))
2276   (use (match_operand:DF 1 "register_operand"))]
2277  "TARGET_HAS_XFLOATING_LIBS"
2278  "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
2279
2280(define_insn "*truncdfsf2_ieee"
2281  [(set (match_operand:SF 0 "register_operand" "=&f")
2282	(float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2283  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2284  "cvt%-%,%/ %R1,%0"
2285  [(set_attr "type" "fadd")
2286   (set_attr "trap" "yes")
2287   (set_attr "round_suffix" "normal")
2288   (set_attr "trap_suffix" "u_su_sui")])
2289
2290(define_insn "truncdfsf2"
2291  [(set (match_operand:SF 0 "register_operand" "=f")
2292	(float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2293  "TARGET_FP"
2294  "cvt%-%,%/ %R1,%0"
2295  [(set_attr "type" "fadd")
2296   (set_attr "trap" "yes")
2297   (set_attr "round_suffix" "normal")
2298   (set_attr "trap_suffix" "u_su_sui")])
2299
2300(define_expand "trunctfdf2"
2301  [(use (match_operand:DF 0 "register_operand"))
2302   (use (match_operand:TF 1 "general_operand"))]
2303  "TARGET_HAS_XFLOATING_LIBS"
2304  "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
2305
2306(define_expand "trunctfsf2"
2307  [(use (match_operand:SF 0 "register_operand"))
2308   (use (match_operand:TF 1 "general_operand"))]
2309  "TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
2310{
2311  rtx tmpf, sticky, arg, lo, hi;
2312
2313  tmpf = gen_reg_rtx (DFmode);
2314  sticky = gen_reg_rtx (DImode);
2315  arg = copy_to_mode_reg (TFmode, operands[1]);
2316  lo = gen_lowpart (DImode, arg);
2317  hi = gen_highpart (DImode, arg);
2318
2319  /* Convert the low word of the TFmode value into a sticky rounding bit,
2320     then or it into the low bit of the high word.  This leaves the sticky
2321     bit at bit 48 of the fraction, which is representable in DFmode,
2322     which prevents rounding error in the final conversion to SFmode.  */
2323
2324  emit_insn (gen_rtx_SET (sticky, gen_rtx_NE (DImode, lo, const0_rtx)));
2325  emit_insn (gen_iordi3 (hi, hi, sticky));
2326  emit_insn (gen_trunctfdf2 (tmpf, arg));
2327  emit_insn (gen_truncdfsf2 (operands[0], tmpf));
2328  DONE;
2329})
2330
2331;; Next are all the integer comparisons, and conditional moves and branches
2332;; and some of the related define_expand's and define_split's.
2333
2334(define_insn "*setcc_internal"
2335  [(set (match_operand 0 "register_operand" "=r")
2336	(match_operator 1 "alpha_comparison_operator"
2337			   [(match_operand:DI 2 "register_operand" "r")
2338			    (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
2339  "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2340   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2341   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2342  "cmp%C1 %2,%3,%0"
2343  [(set_attr "type" "icmp")])
2344
2345;; Yes, we can technically support reg_or_8bit_operand in operand 2,
2346;; but that's non-canonical rtl and allowing that causes inefficiencies
2347;; from cse on.
2348(define_insn "*setcc_swapped_internal"
2349  [(set (match_operand 0 "register_operand" "=r")
2350        (match_operator 1 "alpha_swapped_comparison_operator"
2351			   [(match_operand:DI 2 "register_operand" "r")
2352			    (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
2353  "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2354   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2355   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2356  "cmp%c1 %r3,%2,%0"
2357  [(set_attr "type" "icmp")])
2358
2359;; Use match_operator rather than ne directly so that we can match
2360;; multiple integer modes.
2361(define_insn "*setne_internal"
2362  [(set (match_operand 0 "register_operand" "=r")
2363	(match_operator 1 "signed_comparison_operator"
2364			  [(match_operand:DI 2 "register_operand" "r")
2365			   (const_int 0)]))]
2366  "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2367   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2368   && GET_CODE (operands[1]) == NE
2369   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2370  "cmpult $31,%2,%0"
2371  [(set_attr "type" "icmp")])
2372
2373;; The mode folding trick can't be used with const_int operands, since
2374;; reload needs to know the proper mode.
2375;;
2376;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
2377;; in order to create more pairs of constants.  As long as we're allowing
2378;; two constants at the same time, and will have to reload one of them...
2379
2380(define_insn "*mov<mode>cc_internal"
2381  [(set (match_operand:IMODE 0 "register_operand" "=r,r,r,r")
2382	(if_then_else:IMODE
2383	 (match_operator 2 "signed_comparison_operator"
2384			 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2385			  (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2386	 (match_operand:IMODE 1 "add_operand" "rI,0,rI,0")
2387	 (match_operand:IMODE 5 "add_operand" "0,rI,0,rI")))]
2388  "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
2389  "@
2390   cmov%C2 %r3,%1,%0
2391   cmov%D2 %r3,%5,%0
2392   cmov%c2 %r4,%1,%0
2393   cmov%d2 %r4,%5,%0"
2394  [(set_attr "type" "icmov")])
2395
2396(define_insn "*mov<mode>cc_lbc"
2397  [(set (match_operand:IMODE 0 "register_operand" "=r,r")
2398	(if_then_else:IMODE
2399	 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2400			      (const_int 1)
2401			      (const_int 0))
2402	     (const_int 0))
2403	 (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
2404	 (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
2405  ""
2406  "@
2407   cmovlbc %r2,%1,%0
2408   cmovlbs %r2,%3,%0"
2409  [(set_attr "type" "icmov")])
2410
2411(define_insn "*mov<mode>cc_lbs"
2412  [(set (match_operand:IMODE 0 "register_operand" "=r,r")
2413	(if_then_else:IMODE
2414	 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2415			      (const_int 1)
2416			      (const_int 0))
2417	     (const_int 0))
2418	 (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
2419	 (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
2420  ""
2421  "@
2422   cmovlbs %r2,%1,%0
2423   cmovlbc %r2,%3,%0"
2424  [(set_attr "type" "icmov")])
2425
2426;; For ABS, we have two choices, depending on whether the input and output
2427;; registers are the same or not.
2428(define_expand "absdi2"
2429  [(set (match_operand:DI 0 "register_operand")
2430	(abs:DI (match_operand:DI 1 "register_operand")))]
2431  ""
2432{
2433  if (rtx_equal_p (operands[0], operands[1]))
2434    emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
2435  else
2436    emit_insn (gen_absdi2_diff (operands[0], operands[1]));
2437  DONE;
2438})
2439
2440(define_expand "absdi2_same"
2441  [(set (match_operand:DI 1 "register_operand")
2442	(neg:DI (match_operand:DI 0 "register_operand")))
2443   (set (match_dup 0)
2444	(if_then_else:DI (ge (match_dup 0) (const_int 0))
2445			 (match_dup 0)
2446			 (match_dup 1)))])
2447
2448(define_expand "absdi2_diff"
2449  [(set (match_operand:DI 0 "register_operand")
2450	(neg:DI (match_operand:DI 1 "register_operand")))
2451   (set (match_dup 0)
2452	(if_then_else:DI (lt (match_dup 1) (const_int 0))
2453			 (match_dup 0)
2454			 (match_dup 1)))])
2455
2456(define_split
2457  [(set (match_operand:DI 0 "register_operand")
2458	(abs:DI (match_dup 0)))
2459   (clobber (match_operand:DI 1 "register_operand"))]
2460  ""
2461  [(set (match_dup 1) (neg:DI (match_dup 0)))
2462   (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2463				       (match_dup 0) (match_dup 1)))])
2464
2465(define_split
2466  [(set (match_operand:DI 0 "register_operand")
2467	(abs:DI (match_operand:DI 1 "register_operand")))]
2468  "! rtx_equal_p (operands[0], operands[1])"
2469  [(set (match_dup 0) (neg:DI (match_dup 1)))
2470   (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2471				       (match_dup 0) (match_dup 1)))])
2472
2473(define_split
2474  [(set (match_operand:DI 0 "register_operand")
2475	(neg:DI (abs:DI (match_dup 0))))
2476   (clobber (match_operand:DI 1 "register_operand"))]
2477  ""
2478  [(set (match_dup 1) (neg:DI (match_dup 0)))
2479   (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2480				       (match_dup 0) (match_dup 1)))])
2481
2482(define_split
2483  [(set (match_operand:DI 0 "register_operand")
2484	(neg:DI (abs:DI (match_operand:DI 1 "register_operand"))))]
2485  "! rtx_equal_p (operands[0], operands[1])"
2486  [(set (match_dup 0) (neg:DI (match_dup 1)))
2487   (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2488				       (match_dup 0) (match_dup 1)))])
2489
2490(define_insn "<code><mode>3"
2491  [(set (match_operand:I12MODE 0 "register_operand" "=r")
2492	(any_maxmin:I12MODE
2493	 (match_operand:I12MODE 1 "reg_or_0_operand" "%rJ")
2494	 (match_operand:I12MODE 2 "reg_or_8bit_operand" "rI")))]
2495  "TARGET_MAX"
2496  "<maxmin><vecmodesuffix> %r1,%2,%0"
2497  [(set_attr "type" "mvi")])
2498
2499(define_expand "smaxdi3"
2500  [(set (match_dup 3)
2501	(le:DI (match_operand:DI 1 "reg_or_0_operand")
2502	       (match_operand:DI 2 "reg_or_8bit_operand")))
2503   (set (match_operand:DI 0 "register_operand")
2504	(if_then_else:DI (eq (match_dup 3) (const_int 0))
2505			 (match_dup 1) (match_dup 2)))]
2506  ""
2507  "operands[3] = gen_reg_rtx (DImode);")
2508
2509(define_split
2510  [(set (match_operand:DI 0 "register_operand")
2511	(smax:DI (match_operand:DI 1 "reg_or_0_operand")
2512		 (match_operand:DI 2 "reg_or_8bit_operand")))
2513   (clobber (match_operand:DI 3 "register_operand"))]
2514  "operands[2] != const0_rtx"
2515  [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2516   (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2517				       (match_dup 1) (match_dup 2)))])
2518
2519(define_insn "*smax_const0"
2520  [(set (match_operand:DI 0 "register_operand" "=r")
2521	(smax:DI (match_operand:DI 1 "register_operand" "0")
2522		 (const_int 0)))]
2523  ""
2524  "cmovlt %0,0,%0"
2525  [(set_attr "type" "icmov")])
2526
2527(define_expand "smindi3"
2528  [(set (match_dup 3)
2529	(lt:DI (match_operand:DI 1 "reg_or_0_operand")
2530	       (match_operand:DI 2 "reg_or_8bit_operand")))
2531   (set (match_operand:DI 0 "register_operand")
2532	(if_then_else:DI (ne (match_dup 3) (const_int 0))
2533			 (match_dup 1) (match_dup 2)))]
2534  ""
2535  "operands[3] = gen_reg_rtx (DImode);")
2536
2537(define_split
2538  [(set (match_operand:DI 0 "register_operand")
2539	(smin:DI (match_operand:DI 1 "reg_or_0_operand")
2540		 (match_operand:DI 2 "reg_or_8bit_operand")))
2541   (clobber (match_operand:DI 3 "register_operand"))]
2542  "operands[2] != const0_rtx"
2543  [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2544   (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2545				       (match_dup 1) (match_dup 2)))])
2546
2547(define_insn "*smin_const0"
2548  [(set (match_operand:DI 0 "register_operand" "=r")
2549	(smin:DI (match_operand:DI 1 "register_operand" "0")
2550		 (const_int 0)))]
2551  ""
2552  "cmovgt %0,0,%0"
2553  [(set_attr "type" "icmov")])
2554
2555(define_expand "umaxdi3"
2556  [(set (match_dup 3)
2557	(leu:DI (match_operand:DI 1 "reg_or_0_operand")
2558		(match_operand:DI 2 "reg_or_8bit_operand")))
2559   (set (match_operand:DI 0 "register_operand")
2560	(if_then_else:DI (eq (match_dup 3) (const_int 0))
2561			 (match_dup 1) (match_dup 2)))]
2562  ""
2563  "operands[3] = gen_reg_rtx (DImode);")
2564
2565(define_split
2566  [(set (match_operand:DI 0 "register_operand")
2567	(umax:DI (match_operand:DI 1 "reg_or_0_operand")
2568		 (match_operand:DI 2 "reg_or_8bit_operand")))
2569   (clobber (match_operand:DI 3 "register_operand"))]
2570  "operands[2] != const0_rtx"
2571  [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2572   (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2573				       (match_dup 1) (match_dup 2)))])
2574
2575(define_expand "umindi3"
2576  [(set (match_dup 3)
2577	(ltu:DI (match_operand:DI 1 "reg_or_0_operand")
2578		(match_operand:DI 2 "reg_or_8bit_operand")))
2579   (set (match_operand:DI 0 "register_operand")
2580	(if_then_else:DI (ne (match_dup 3) (const_int 0))
2581			 (match_dup 1) (match_dup 2)))]
2582  ""
2583  "operands[3] = gen_reg_rtx (DImode);")
2584
2585(define_split
2586  [(set (match_operand:DI 0 "register_operand")
2587	(umin:DI (match_operand:DI 1 "reg_or_0_operand")
2588		 (match_operand:DI 2 "reg_or_8bit_operand")))
2589   (clobber (match_operand:DI 3 "register_operand"))]
2590  "operands[2] != const0_rtx"
2591  [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2592   (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2593				       (match_dup 1) (match_dup 2)))])
2594
2595(define_insn "*bcc_normal"
2596  [(set (pc)
2597	(if_then_else
2598	 (match_operator 1 "signed_comparison_operator"
2599			 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2600			  (const_int 0)])
2601	 (label_ref (match_operand 0))
2602	 (pc)))]
2603  ""
2604  "b%C1 %r2,%0"
2605  [(set_attr "type" "ibr")])
2606
2607(define_insn "*bcc_reverse"
2608  [(set (pc)
2609	(if_then_else
2610	 (match_operator 1 "signed_comparison_operator"
2611			 [(match_operand:DI 2 "register_operand" "r")
2612			  (const_int 0)])
2613
2614	 (pc)
2615	 (label_ref (match_operand 0))))]
2616  ""
2617  "b%c1 %2,%0"
2618  [(set_attr "type" "ibr")])
2619
2620(define_insn "*blbs_normal"
2621  [(set (pc)
2622	(if_then_else
2623	 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2624			      (const_int 1)
2625			      (const_int 0))
2626	     (const_int 0))
2627	 (label_ref (match_operand 0))
2628	 (pc)))]
2629  ""
2630  "blbs %r1,%0"
2631  [(set_attr "type" "ibr")])
2632
2633(define_insn "*blbc_normal"
2634  [(set (pc)
2635	(if_then_else
2636	 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2637			      (const_int 1)
2638			      (const_int 0))
2639	     (const_int 0))
2640	 (label_ref (match_operand 0))
2641	 (pc)))]
2642  ""
2643  "blbc %r1,%0"
2644  [(set_attr "type" "ibr")])
2645
2646(define_split
2647  [(parallel
2648    [(set (pc)
2649	  (if_then_else
2650	   (match_operator 1 "comparison_operator"
2651	     [(zero_extract:DI (match_operand:DI 2 "register_operand")
2652			       (const_int 1)
2653			       (match_operand:DI 3 "const_int_operand"))
2654	      (const_int 0)])
2655	   (label_ref (match_operand 0))
2656	   (pc)))
2657     (clobber (match_operand:DI 4 "register_operand"))])]
2658  "INTVAL (operands[3]) != 0"
2659  [(set (match_dup 4)
2660	(lshiftrt:DI (match_dup 2) (match_dup 3)))
2661   (set (pc)
2662	(if_then_else (match_op_dup 1
2663				    [(zero_extract:DI (match_dup 4)
2664						      (const_int 1)
2665						      (const_int 0))
2666				     (const_int 0)])
2667		      (label_ref (match_dup 0))
2668		      (pc)))]
2669 )
2670
2671;; The following are the corresponding floating-point insns.  Recall
2672;; we need to have variants that expand the arguments from SFmode
2673;; to DFmode.
2674
2675(define_insn "*cmpdf_ieee"
2676  [(set (match_operand:DF 0 "register_operand" "=&f")
2677	(match_operator:DF 1 "alpha_fp_comparison_operator"
2678			   [(match_operand:DF 2 "reg_or_0_operand" "fG")
2679			    (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
2680  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2681  "cmp%-%C1%/ %R2,%R3,%0"
2682  [(set_attr "type" "fadd")
2683   (set_attr "trap" "yes")
2684   (set_attr "trap_suffix" "su")])
2685
2686(define_insn "*cmpdf_internal"
2687  [(set (match_operand:DF 0 "register_operand" "=f")
2688	(match_operator:DF 1 "alpha_fp_comparison_operator"
2689			   [(match_operand:DF 2 "reg_or_0_operand" "fG")
2690			    (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
2691  "TARGET_FP"
2692  "cmp%-%C1%/ %R2,%R3,%0"
2693  [(set_attr "type" "fadd")
2694   (set_attr "trap" "yes")
2695   (set_attr "trap_suffix" "su")])
2696
2697(define_insn "*cmpdf_ext1"
2698  [(set (match_operand:DF 0 "register_operand" "=f")
2699	(match_operator:DF 1 "alpha_fp_comparison_operator"
2700			   [(float_extend:DF
2701			     (match_operand:SF 2 "reg_or_0_operand" "fG"))
2702			    (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
2703  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2704  "cmp%-%C1%/ %R2,%R3,%0"
2705  [(set_attr "type" "fadd")
2706   (set_attr "trap" "yes")
2707   (set_attr "trap_suffix" "su")])
2708
2709(define_insn "*cmpdf_ext2"
2710  [(set (match_operand:DF 0 "register_operand" "=f")
2711	(match_operator:DF 1 "alpha_fp_comparison_operator"
2712			   [(match_operand:DF 2 "reg_or_0_operand" "fG")
2713			    (float_extend:DF
2714			     (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
2715  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2716  "cmp%-%C1%/ %R2,%R3,%0"
2717  [(set_attr "type" "fadd")
2718   (set_attr "trap" "yes")
2719   (set_attr "trap_suffix" "su")])
2720
2721(define_insn "*cmpdf_ext3"
2722  [(set (match_operand:DF 0 "register_operand" "=f")
2723	(match_operator:DF 1 "alpha_fp_comparison_operator"
2724			   [(float_extend:DF
2725			     (match_operand:SF 2 "reg_or_0_operand" "fG"))
2726			    (float_extend:DF
2727			     (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
2728  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2729  "cmp%-%C1%/ %R2,%R3,%0"
2730  [(set_attr "type" "fadd")
2731   (set_attr "trap" "yes")
2732   (set_attr "trap_suffix" "su")])
2733
2734(define_insn "*mov<mode>cc_internal"
2735  [(set (match_operand:FMODE 0 "register_operand" "=f,f")
2736	(if_then_else:FMODE
2737	 (match_operator 3 "signed_comparison_operator"
2738			 [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
2739			  (match_operand:DF 2 "const0_operand" "G,G")])
2740	 (match_operand:FMODE 1 "reg_or_0_operand" "fG,0")
2741	 (match_operand:FMODE 5 "reg_or_0_operand" "0,fG")))]
2742  "TARGET_FP"
2743  "@
2744   fcmov%C3 %R4,%R1,%0
2745   fcmov%D3 %R4,%R5,%0"
2746  [(set_attr "type" "fcmov")])
2747
2748(define_insn "*movdfcc_ext1"
2749  [(set (match_operand:DF 0 "register_operand" "=f,f")
2750	(if_then_else:DF
2751	 (match_operator 3 "signed_comparison_operator"
2752			 [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
2753			  (match_operand:DF 2 "const0_operand" "G,G")])
2754	 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
2755	 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
2756  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2757  "@
2758   fcmov%C3 %R4,%R1,%0
2759   fcmov%D3 %R4,%R5,%0"
2760  [(set_attr "type" "fcmov")])
2761
2762(define_insn "*movdfcc_ext2"
2763  [(set (match_operand:DF 0 "register_operand" "=f,f")
2764	(if_then_else:DF
2765	 (match_operator 3 "signed_comparison_operator"
2766			 [(float_extend:DF
2767			   (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
2768			  (match_operand:DF 2 "const0_operand" "G,G")])
2769	 (match_operand:DF 1 "reg_or_0_operand" "fG,0")
2770	 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
2771  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2772  "@
2773   fcmov%C3 %R4,%R1,%0
2774   fcmov%D3 %R4,%R5,%0"
2775  [(set_attr "type" "fcmov")])
2776
2777(define_insn "*movdfcc_ext3"
2778  [(set (match_operand:SF 0 "register_operand" "=f,f")
2779	(if_then_else:SF
2780	 (match_operator 3 "signed_comparison_operator"
2781			 [(float_extend:DF
2782			   (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
2783			  (match_operand:DF 2 "const0_operand" "G,G")])
2784	 (match_operand:SF 1 "reg_or_0_operand" "fG,0")
2785	 (match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
2786  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2787  "@
2788   fcmov%C3 %R4,%R1,%0
2789   fcmov%D3 %R4,%R5,%0"
2790  [(set_attr "type" "fcmov")])
2791
2792(define_insn "*movdfcc_ext4"
2793  [(set (match_operand:DF 0 "register_operand" "=f,f")
2794	(if_then_else:DF
2795	 (match_operator 3 "signed_comparison_operator"
2796			 [(float_extend:DF
2797			   (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
2798			  (match_operand:DF 2 "const0_operand" "G,G")])
2799	 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
2800	 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
2801  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2802  "@
2803   fcmov%C3 %R4,%R1,%0
2804   fcmov%D3 %R4,%R5,%0"
2805  [(set_attr "type" "fcmov")])
2806
2807(define_expand "smaxdf3"
2808  [(set (match_dup 3)
2809	(le:DF (match_operand:DF 1 "reg_or_0_operand")
2810	       (match_operand:DF 2 "reg_or_0_operand")))
2811   (set (match_operand:DF 0 "register_operand")
2812	(if_then_else:DF (eq (match_dup 3) (match_dup 4))
2813			 (match_dup 1) (match_dup 2)))]
2814  "TARGET_FP"
2815{
2816  operands[3] = gen_reg_rtx (DFmode);
2817  operands[4] = CONST0_RTX (DFmode);
2818})
2819
2820(define_expand "smindf3"
2821  [(set (match_dup 3)
2822	(lt:DF (match_operand:DF 1 "reg_or_0_operand")
2823	       (match_operand:DF 2 "reg_or_0_operand")))
2824   (set (match_operand:DF 0 "register_operand")
2825	(if_then_else:DF (ne (match_dup 3) (match_dup 4))
2826			 (match_dup 1) (match_dup 2)))]
2827  "TARGET_FP"
2828{
2829  operands[3] = gen_reg_rtx (DFmode);
2830  operands[4] = CONST0_RTX (DFmode);
2831})
2832
2833(define_expand "smaxsf3"
2834  [(set (match_dup 3)
2835	(le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
2836	       (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
2837   (set (match_operand:SF 0 "register_operand")
2838	(if_then_else:SF (eq (match_dup 3) (match_dup 4))
2839			 (match_dup 1) (match_dup 2)))]
2840  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2841{
2842  operands[3] = gen_reg_rtx (DFmode);
2843  operands[4] = CONST0_RTX (DFmode);
2844})
2845
2846(define_expand "sminsf3"
2847  [(set (match_dup 3)
2848	(lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
2849	       (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
2850   (set (match_operand:SF 0 "register_operand")
2851	(if_then_else:SF (ne (match_dup 3) (match_dup 4))
2852		      (match_dup 1) (match_dup 2)))]
2853  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2854{
2855  operands[3] = gen_reg_rtx (DFmode);
2856  operands[4] = CONST0_RTX (DFmode);
2857})
2858
2859(define_insn "*fbcc_normal"
2860  [(set (pc)
2861	(if_then_else
2862	 (match_operator 1 "signed_comparison_operator"
2863			 [(match_operand:DF 2 "reg_or_0_operand" "fG")
2864			  (match_operand:DF 3 "const0_operand" "G")])
2865	 (label_ref (match_operand 0))
2866	 (pc)))]
2867  "TARGET_FP"
2868  "fb%C1 %R2,%0"
2869  [(set_attr "type" "fbr")])
2870
2871(define_insn "*fbcc_ext_normal"
2872  [(set (pc)
2873	(if_then_else
2874	 (match_operator 1 "signed_comparison_operator"
2875			 [(float_extend:DF
2876			   (match_operand:SF 2 "reg_or_0_operand" "fG"))
2877			  (match_operand:DF 3 "const0_operand" "G")])
2878	 (label_ref (match_operand 0))
2879	 (pc)))]
2880  "TARGET_FP"
2881  "fb%C1 %R2,%0"
2882  [(set_attr "type" "fbr")])
2883
2884;; These are the main define_expand's used to make conditional branches
2885;; and compares.
2886
2887(define_expand "cbranchdf4"
2888  [(use (match_operator 0 "alpha_cbranch_operator"
2889         [(match_operand:DF 1 "reg_or_0_operand")
2890          (match_operand:DF 2 "reg_or_0_operand")]))
2891   (use (match_operand 3))]
2892  "TARGET_FP"
2893  "alpha_emit_conditional_branch (operands, DFmode); DONE;")
2894
2895(define_expand "cbranchtf4"
2896  [(use (match_operator 0 "alpha_cbranch_operator"
2897         [(match_operand:TF 1 "general_operand")
2898          (match_operand:TF 2 "general_operand")]))
2899   (use (match_operand 3))]
2900  "TARGET_HAS_XFLOATING_LIBS"
2901  "alpha_emit_conditional_branch (operands, TFmode); DONE;")
2902
2903(define_expand "cbranchdi4"
2904  [(use (match_operator 0 "alpha_cbranch_operator"
2905         [(match_operand:DI 1 "general_operand")
2906          (match_operand:DI 2 "general_operand")]))
2907   (use (match_operand 3))]
2908  ""
2909  "alpha_emit_conditional_branch (operands, DImode); DONE;")
2910
2911(define_expand "cstoredf4"
2912  [(use (match_operator:DI 1 "alpha_cbranch_operator"
2913         [(match_operand:DF 2 "reg_or_0_operand")
2914          (match_operand:DF 3 "reg_or_0_operand")]))
2915   (clobber (match_operand:DI 0 "register_operand"))]
2916  "TARGET_FP"
2917{
2918  if (alpha_emit_setcc (operands, DFmode))
2919    DONE;
2920  else
2921    FAIL;
2922})
2923
2924(define_expand "cstoretf4"
2925  [(use (match_operator:DI 1 "alpha_cbranch_operator"
2926         [(match_operand:TF 2 "general_operand")
2927          (match_operand:TF 3 "general_operand")]))
2928   (clobber (match_operand:DI 0 "register_operand"))]
2929  "TARGET_HAS_XFLOATING_LIBS"
2930{
2931  if (alpha_emit_setcc (operands, TFmode))
2932    DONE;
2933  else
2934    FAIL;
2935})
2936
2937(define_expand "cstoredi4"
2938  [(use (match_operator:DI 1 "alpha_cbranch_operator"
2939         [(match_operand:DI 2 "general_operand")
2940          (match_operand:DI 3 "general_operand")]))
2941   (clobber (match_operand:DI 0 "register_operand"))]
2942  ""
2943{
2944  if (alpha_emit_setcc (operands, DImode))
2945    DONE;
2946  else
2947    FAIL;
2948})
2949
2950;; These are the main define_expand's used to make conditional moves.
2951
2952(define_expand "mov<mode>cc"
2953  [(set (match_operand:I48MODE 0 "register_operand")
2954	(if_then_else:I48MODE
2955	  (match_operand 1 "comparison_operator")
2956	  (match_operand:I48MODE 2 "reg_or_8bit_operand")
2957	  (match_operand:I48MODE 3 "reg_or_8bit_operand")))]
2958  ""
2959{
2960  operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
2961  if (operands[1] == 0)
2962    FAIL;
2963})
2964
2965(define_expand "mov<mode>cc"
2966  [(set (match_operand:FMODE 0 "register_operand")
2967	(if_then_else:FMODE
2968	  (match_operand 1 "comparison_operator")
2969	  (match_operand:FMODE 2 "reg_or_8bit_operand")
2970	  (match_operand:FMODE 3 "reg_or_8bit_operand")))]
2971  ""
2972{
2973  operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
2974  if (operands[1] == 0)
2975    FAIL;
2976})
2977
2978;; These define_split definitions are used in cases when comparisons have
2979;; not be stated in the correct way and we need to reverse the second
2980;; comparison.  For example, x >= 7 has to be done as x < 6 with the
2981;; comparison that tests the result being reversed.  We have one define_split
2982;; for each use of a comparison.  They do not match valid insns and need
2983;; not generate valid insns.
2984;;
2985;; We can also handle equality comparisons (and inequality comparisons in
2986;; cases where the resulting add cannot overflow) by doing an add followed by
2987;; a comparison with zero.  This is faster since the addition takes one
2988;; less cycle than a compare when feeding into a conditional move.
2989;; For this case, we also have an SImode pattern since we can merge the add
2990;; and sign extend and the order doesn't matter.
2991;;
2992;; We do not do this for floating-point, since it isn't clear how the "wrong"
2993;; operation could have been generated.
2994
2995(define_split
2996  [(set (match_operand:DI 0 "register_operand")
2997	(if_then_else:DI
2998	 (match_operator 1 "comparison_operator"
2999			 [(match_operand:DI 2 "reg_or_0_operand")
3000			  (match_operand:DI 3 "reg_or_cint_operand")])
3001	 (match_operand:DI 4 "reg_or_cint_operand")
3002	 (match_operand:DI 5 "reg_or_cint_operand")))
3003   (clobber (match_operand:DI 6 "register_operand"))]
3004  "operands[3] != const0_rtx"
3005  [(set (match_dup 6) (match_dup 7))
3006   (set (match_dup 0)
3007	(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3008{
3009  enum rtx_code code = GET_CODE (operands[1]);
3010  int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3011
3012  /* If we are comparing for equality with a constant and that constant
3013     appears in the arm when the register equals the constant, use the
3014     register since that is more likely to match (and to produce better code
3015     if both would).  */
3016
3017  if (code == EQ && CONST_INT_P (operands[3])
3018      && rtx_equal_p (operands[4], operands[3]))
3019    operands[4] = operands[2];
3020
3021  else if (code == NE && CONST_INT_P (operands[3])
3022	   && rtx_equal_p (operands[5], operands[3]))
3023    operands[5] = operands[2];
3024
3025  if (code == NE || code == EQ
3026      || (extended_count (operands[2], DImode, unsignedp) >= 1
3027	  && extended_count (operands[3], DImode, unsignedp) >= 1))
3028    {
3029      if (CONST_INT_P (operands[3]))
3030	operands[7] = gen_rtx_PLUS (DImode, operands[2],
3031				    GEN_INT (- INTVAL (operands[3])));
3032      else
3033	operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3034
3035      operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
3036    }
3037
3038  else if (code == EQ || code == LE || code == LT
3039	   || code == LEU || code == LTU)
3040    {
3041      operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3042      operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
3043    }
3044  else
3045    {
3046      operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3047				    operands[2], operands[3]);
3048      operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
3049    }
3050})
3051
3052(define_split
3053  [(set (match_operand:DI 0 "register_operand")
3054	(if_then_else:DI
3055	 (match_operator 1 "comparison_operator"
3056			 [(match_operand:SI 2 "reg_or_0_operand")
3057			  (match_operand:SI 3 "reg_or_cint_operand")])
3058	 (match_operand:DI 4 "reg_or_8bit_operand")
3059	 (match_operand:DI 5 "reg_or_8bit_operand")))
3060   (clobber (match_operand:DI 6 "register_operand"))]
3061  "operands[3] != const0_rtx
3062   && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3063  [(set (match_dup 6) (match_dup 7))
3064   (set (match_dup 0)
3065	(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3066{
3067  enum rtx_code code = GET_CODE (operands[1]);
3068  int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3069  rtx tem;
3070
3071  if ((code != NE && code != EQ
3072       && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3073	     && extended_count (operands[3], DImode, unsignedp) >= 1)))
3074    FAIL;
3075
3076  if (CONST_INT_P (operands[3]))
3077    tem = gen_rtx_PLUS (SImode, operands[2],
3078			GEN_INT (- INTVAL (operands[3])));
3079  else
3080    tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3081
3082  operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3083  operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3084				operands[6], const0_rtx);
3085})
3086
3087;; Prefer to use cmp and arithmetic when possible instead of a cmove.
3088
3089(define_split
3090  [(set (match_operand 0 "register_operand")
3091	(if_then_else (match_operator 1 "signed_comparison_operator"
3092			   [(match_operand:DI 2 "reg_or_0_operand")
3093			    (const_int 0)])
3094	  (match_operand 3 "const_int_operand")
3095	  (match_operand 4 "const_int_operand")))]
3096  ""
3097  [(const_int 0)]
3098{
3099  if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
3100				    operands[2], operands[3], operands[4]))
3101    DONE;
3102  else
3103    FAIL;
3104})
3105
3106;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
3107;; Oh well, we match it in movcc, so it must be partially our fault.
3108(define_split
3109  [(set (match_operand 0 "register_operand")
3110	(if_then_else (match_operator 1 "signed_comparison_operator"
3111			   [(const_int 0)
3112			    (match_operand:DI 2 "reg_or_0_operand")])
3113	  (match_operand 3 "const_int_operand")
3114	  (match_operand 4 "const_int_operand")))]
3115  ""
3116  [(const_int 0)]
3117{
3118  if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
3119				    operands[0], operands[2], operands[3],
3120				    operands[4]))
3121    DONE;
3122  else
3123    FAIL;
3124})
3125
3126(define_insn_and_split "*cmp_sadd_di"
3127  [(set (match_operand:DI 0 "register_operand" "=r")
3128	(plus:DI (if_then_else:DI
3129		   (match_operator 1 "alpha_zero_comparison_operator"
3130		     [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3131		      (const_int 0)])
3132		   (match_operand:DI 3 "const48_operand" "I")
3133		   (const_int 0))
3134	         (match_operand:DI 4 "sext_add_operand" "rIO")))
3135   (clobber (match_scratch:DI 5 "=r"))]
3136  ""
3137  "#"
3138  ""
3139  [(set (match_dup 5)
3140	(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3141   (set (match_dup 0)
3142	(plus:DI (mult:DI (match_dup 5) (match_dup 3))
3143		 (match_dup 4)))]
3144{
3145  if (can_create_pseudo_p ())
3146    operands[5] = gen_reg_rtx (DImode);
3147  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3148    operands[5] = operands[0];
3149})
3150
3151(define_insn_and_split "*cmp_sadd_si"
3152  [(set (match_operand:SI 0 "register_operand" "=r")
3153	(plus:SI (if_then_else:SI
3154		   (match_operator 1 "alpha_zero_comparison_operator"
3155		     [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3156		      (const_int 0)])
3157		   (match_operand:SI 3 "const48_operand" "I")
3158		   (const_int 0))
3159	         (match_operand:SI 4 "sext_add_operand" "rIO")))
3160   (clobber (match_scratch:DI 5 "=r"))]
3161  ""
3162  "#"
3163  ""
3164  [(set (match_dup 5)
3165	(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3166   (set (match_dup 0)
3167	(plus:SI (mult:SI (match_dup 6) (match_dup 3))
3168		 (match_dup 4)))]
3169{
3170  if (can_create_pseudo_p ())
3171    operands[5] = gen_reg_rtx (DImode);
3172  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3173    operands[5] = gen_lowpart (DImode, operands[0]);
3174
3175  operands[6] = gen_lowpart (SImode, operands[5]);
3176})
3177
3178(define_insn_and_split "*cmp_sadd_sidi"
3179  [(set (match_operand:DI 0 "register_operand" "=r")
3180	(sign_extend:DI
3181	  (plus:SI (if_then_else:SI
3182		     (match_operator 1 "alpha_zero_comparison_operator"
3183		       [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3184		        (const_int 0)])
3185		     (match_operand:SI 3 "const48_operand" "I")
3186		     (const_int 0))
3187	           (match_operand:SI 4 "sext_add_operand" "rIO"))))
3188   (clobber (match_scratch:DI 5 "=r"))]
3189  ""
3190  "#"
3191  ""
3192  [(set (match_dup 5)
3193	(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3194   (set (match_dup 0)
3195	(sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3))
3196				 (match_dup 4))))]
3197{
3198  if (can_create_pseudo_p ())
3199    operands[5] = gen_reg_rtx (DImode);
3200  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3201    operands[5] = operands[0];
3202
3203  operands[6] = gen_lowpart (SImode, operands[5]);
3204})
3205
3206(define_insn_and_split "*cmp_ssub_di"
3207  [(set (match_operand:DI 0 "register_operand" "=r")
3208	(minus:DI (if_then_else:DI
3209		    (match_operator 1 "alpha_zero_comparison_operator"
3210		      [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3211		       (const_int 0)])
3212		    (match_operand:DI 3 "const48_operand" "I")
3213		    (const_int 0))
3214	          (match_operand:DI 4 "reg_or_8bit_operand" "rI")))
3215   (clobber (match_scratch:DI 5 "=r"))]
3216  ""
3217  "#"
3218  ""
3219  [(set (match_dup 5)
3220	(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3221   (set (match_dup 0)
3222	(minus:DI (mult:DI (match_dup 5) (match_dup 3))
3223		  (match_dup 4)))]
3224{
3225  if (can_create_pseudo_p ())
3226    operands[5] = gen_reg_rtx (DImode);
3227  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3228    operands[5] = operands[0];
3229})
3230
3231(define_insn_and_split "*cmp_ssub_si"
3232  [(set (match_operand:SI 0 "register_operand" "=r")
3233	(minus:SI (if_then_else:SI
3234		    (match_operator 1 "alpha_zero_comparison_operator"
3235		      [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3236		       (const_int 0)])
3237		    (match_operand:SI 3 "const48_operand" "I")
3238		    (const_int 0))
3239	          (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
3240   (clobber (match_scratch:DI 5 "=r"))]
3241  ""
3242  "#"
3243  ""
3244  [(set (match_dup 5)
3245	(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3246   (set (match_dup 0)
3247	(minus:SI (mult:SI (match_dup 6) (match_dup 3))
3248		 (match_dup 4)))]
3249{
3250  if (can_create_pseudo_p ())
3251    operands[5] = gen_reg_rtx (DImode);
3252  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3253    operands[5] = gen_lowpart (DImode, operands[0]);
3254
3255  operands[6] = gen_lowpart (SImode, operands[5]);
3256})
3257
3258(define_insn_and_split "*cmp_ssub_sidi"
3259  [(set (match_operand:DI 0 "register_operand" "=r")
3260	(sign_extend:DI
3261	  (minus:SI (if_then_else:SI
3262		      (match_operator 1 "alpha_zero_comparison_operator"
3263		        [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3264		         (const_int 0)])
3265		      (match_operand:SI 3 "const48_operand" "I")
3266		      (const_int 0))
3267	            (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
3268   (clobber (match_scratch:DI 5 "=r"))]
3269  ""
3270  "#"
3271  ""
3272  [(set (match_dup 5)
3273	(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3274   (set (match_dup 0)
3275	(sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3))
3276				  (match_dup 4))))]
3277{
3278  if (can_create_pseudo_p ())
3279    operands[5] = gen_reg_rtx (DImode);
3280  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3281    operands[5] = operands[0];
3282
3283  operands[6] = gen_lowpart (SImode, operands[5]);
3284})
3285
3286;; Here are the CALL and unconditional branch insns.  Calls on NT and OSF
3287;; work differently, so we have different patterns for each.
3288
3289(define_expand "call"
3290  [(use (match_operand:DI 0))
3291   (use (match_operand 1))
3292   (use (match_operand 2))
3293   (use (match_operand 3))]
3294  ""
3295{
3296  if (TARGET_ABI_OPEN_VMS)
3297    emit_call_insn (gen_call_vms (operands[0], operands[2]));
3298  else
3299    emit_call_insn (gen_call_osf (operands[0], operands[1]));
3300  DONE;
3301})
3302
3303(define_expand "sibcall"
3304  [(parallel [(call (mem:DI (match_operand 0))
3305			    (match_operand 1))
3306	      (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
3307  "TARGET_ABI_OSF"
3308{
3309  gcc_assert (MEM_P (operands[0]));
3310  operands[0] = XEXP (operands[0], 0);
3311})
3312
3313(define_expand "call_osf"
3314  [(parallel [(call (mem:DI (match_operand 0))
3315		    (match_operand 1))
3316	      (use (reg:DI 29))
3317	      (clobber (reg:DI 26))])]
3318  ""
3319{
3320  gcc_assert (MEM_P (operands[0]));
3321
3322  operands[0] = XEXP (operands[0], 0);
3323  if (! call_operand (operands[0], Pmode))
3324    operands[0] = copy_to_mode_reg (Pmode, operands[0]);
3325})
3326
3327;;
3328;; call openvms/alpha
3329;; op 0: symbol ref for called function
3330;; op 1: next_arg_reg (argument information value for R25)
3331;;
3332(define_expand "call_vms"
3333  [(parallel [(call (mem:DI (match_operand 0))
3334		    (match_operand 1))
3335	      (use (match_dup 2))
3336	      (use (reg:DI 25))
3337	      (use (reg:DI 26))
3338	      (clobber (reg:DI 27))])]
3339  ""
3340{
3341  gcc_assert (MEM_P (operands[0]));
3342
3343  operands[0] = XEXP (operands[0], 0);
3344
3345  /* Always load AI with argument information, then handle symbolic and
3346     indirect call differently.  Load RA and set operands[2] to PV in
3347     both cases.  */
3348
3349  emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
3350  if (GET_CODE (operands[0]) == SYMBOL_REF)
3351    {
3352      operands[2] = const0_rtx;
3353    }
3354  else
3355    {
3356      emit_move_insn (gen_rtx_REG (Pmode, 26),
3357		      gen_rtx_MEM (Pmode, plus_constant (Pmode,
3358							 operands[0], 8)));
3359      operands[2] = operands[0];
3360    }
3361})
3362
3363(define_expand "call_value"
3364  [(use (match_operand 0))
3365   (use (match_operand:DI 1))
3366   (use (match_operand 2))
3367   (use (match_operand 3))
3368   (use (match_operand 4))]
3369  ""
3370{
3371  if (TARGET_ABI_OPEN_VMS)
3372    emit_call_insn (gen_call_value_vms (operands[0], operands[1],
3373					operands[3]));
3374  else
3375    emit_call_insn (gen_call_value_osf (operands[0], operands[1],
3376					operands[2]));
3377  DONE;
3378})
3379
3380(define_expand "sibcall_value"
3381  [(parallel [(set (match_operand 0)
3382		   (call (mem:DI (match_operand 1))
3383		         (match_operand 2)))
3384	      (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
3385  "TARGET_ABI_OSF"
3386{
3387  gcc_assert (MEM_P (operands[1]));
3388  operands[1] = XEXP (operands[1], 0);
3389})
3390
3391(define_expand "call_value_osf"
3392  [(parallel [(set (match_operand 0)
3393		   (call (mem:DI (match_operand 1))
3394			 (match_operand 2)))
3395	      (use (reg:DI 29))
3396	      (clobber (reg:DI 26))])]
3397  ""
3398{
3399  gcc_assert (MEM_P (operands[1]));
3400
3401  operands[1] = XEXP (operands[1], 0);
3402  if (! call_operand (operands[1], Pmode))
3403    operands[1] = copy_to_mode_reg (Pmode, operands[1]);
3404})
3405
3406(define_expand "call_value_vms"
3407  [(parallel [(set (match_operand 0)
3408		   (call (mem:DI (match_operand:DI 1))
3409			 (match_operand 2)))
3410	      (use (match_dup 3))
3411	      (use (reg:DI 25))
3412	      (use (reg:DI 26))
3413	      (clobber (reg:DI 27))])]
3414  ""
3415{
3416  gcc_assert (MEM_P (operands[1]));
3417
3418  operands[1] = XEXP (operands[1], 0);
3419
3420  /* Always load AI with argument information, then handle symbolic and
3421     indirect call differently.  Load RA and set operands[3] to PV in
3422     both cases.  */
3423
3424  emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
3425  if (GET_CODE (operands[1]) == SYMBOL_REF)
3426    {
3427      operands[3] = const0_rtx;
3428    }
3429  else
3430    {
3431      emit_move_insn (gen_rtx_REG (Pmode, 26),
3432		      gen_rtx_MEM (Pmode, plus_constant (Pmode,
3433							 operands[1], 8)));
3434      operands[3] = operands[1];
3435    }
3436})
3437
3438(define_insn "*call_osf_1_er_noreturn"
3439  [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3440	 (match_operand 1))
3441   (use (reg:DI 29))
3442   (clobber (reg:DI 26))]
3443  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
3444   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
3445  "@
3446   jsr $26,($27),0
3447   bsr $26,%0\t\t!samegp
3448   ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
3449  [(set_attr "type" "jsr")
3450   (set_attr "length" "*,*,8")])
3451
3452(define_insn "*call_osf_1_er"
3453  [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3454	 (match_operand 1))
3455   (use (reg:DI 29))
3456   (clobber (reg:DI 26))]
3457  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3458  "@
3459   jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
3460   bsr $26,%0\t\t!samegp
3461   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!%*"
3462  [(set_attr "type" "jsr")
3463   (set_attr "length" "12,*,16")])
3464
3465;; We must use peep2 instead of a split because we need accurate life
3466;; information for $gp.  Consider the case of { bar(); while (1); }.
3467(define_peephole2
3468  [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
3469		    (match_operand 1))
3470	      (use (reg:DI 29))
3471	      (clobber (reg:DI 26))])]
3472  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
3473   && ! samegp_function_operand (operands[0], Pmode)
3474   && (peep2_regno_dead_p (1, 29)
3475       || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
3476  [(parallel [(call (mem:DI (match_dup 2))
3477		    (match_dup 1))
3478	      (use (reg:DI 29))
3479	      (use (match_dup 0))
3480	      (use (match_dup 3))
3481	      (clobber (reg:DI 26))])]
3482{
3483  if (CONSTANT_P (operands[0]))
3484    {
3485      operands[2] = gen_rtx_REG (Pmode, 27);
3486      operands[3] = GEN_INT (alpha_next_sequence_number++);
3487      emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
3488				      operands[0], operands[3]));
3489    }
3490  else
3491    {
3492      operands[2] = operands[0];
3493      operands[0] = const0_rtx;
3494      operands[3] = const0_rtx;
3495    }
3496})
3497
3498(define_peephole2
3499  [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
3500		    (match_operand 1))
3501	      (use (reg:DI 29))
3502	      (clobber (reg:DI 26))])]
3503  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
3504   && ! samegp_function_operand (operands[0], Pmode)
3505   && ! (peep2_regno_dead_p (1, 29)
3506         || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
3507  [(parallel [(call (mem:DI (match_dup 2))
3508		    (match_dup 1))
3509	      (set (match_dup 5)
3510		   (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1))
3511	      (use (match_dup 0))
3512	      (use (match_dup 4))
3513	      (clobber (reg:DI 26))])
3514   (set (match_dup 5)
3515	(unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))]
3516{
3517  if (CONSTANT_P (operands[0]))
3518    {
3519      operands[2] = gen_rtx_REG (Pmode, 27);
3520      operands[4] = GEN_INT (alpha_next_sequence_number++);
3521      emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
3522				      operands[0], operands[4]));
3523    }
3524  else
3525    {
3526      operands[2] = operands[0];
3527      operands[0] = const0_rtx;
3528      operands[4] = const0_rtx;
3529    }
3530  operands[3] = GEN_INT (alpha_next_sequence_number++);
3531  operands[5] = pic_offset_table_rtx;
3532})
3533
3534(define_insn "*call_osf_2_er_nogp"
3535  [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
3536	 (match_operand 1))
3537   (use (reg:DI 29))
3538   (use (match_operand 2))
3539   (use (match_operand 3 "const_int_operand"))
3540   (clobber (reg:DI 26))]
3541  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3542  "jsr $26,(%0),%2%J3"
3543  [(set_attr "type" "jsr")])
3544
3545(define_insn "*call_osf_2_er"
3546  [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
3547	 (match_operand 1))
3548   (set (reg:DI 29)
3549	(unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand")]
3550		   UNSPEC_LDGP1))
3551   (use (match_operand 2))
3552   (use (match_operand 3 "const_int_operand"))
3553   (clobber (reg:DI 26))]
3554  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3555  "jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
3556  [(set_attr "type" "jsr")
3557   (set_attr "cannot_copy" "true")
3558   (set_attr "length" "8")])
3559
3560(define_insn "*call_osf_1_noreturn"
3561  [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3562	 (match_operand 1))
3563   (use (reg:DI 29))
3564   (clobber (reg:DI 26))]
3565  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
3566   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
3567  "@
3568   jsr $26,($27),0
3569   bsr $26,$%0..ng
3570   jsr $26,%0"
3571  [(set_attr "type" "jsr")
3572   (set_attr "length" "*,*,8")])
3573
3574(define_insn "*call_osf_1"
3575  [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3576	 (match_operand 1))
3577   (use (reg:DI 29))
3578   (clobber (reg:DI 26))]
3579  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3580  "@
3581   jsr $26,($27),0\;ldgp $29,0($26)
3582   bsr $26,$%0..ng
3583   jsr $26,%0\;ldgp $29,0($26)"
3584  [(set_attr "type" "jsr")
3585   (set_attr "length" "12,*,16")])
3586
3587(define_insn "*sibcall_osf_1_er"
3588  [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
3589	 (match_operand 1))
3590   (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
3591  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3592  "@
3593   br $31,%0\t\t!samegp
3594   ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
3595  [(set_attr "type" "jsr")
3596   (set_attr "length" "*,8")])
3597
3598;; Note that the DEC assembler expands "jmp foo" with $at, which
3599;; doesn't do what we want.
3600(define_insn "*sibcall_osf_1"
3601  [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
3602	 (match_operand 1))
3603   (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
3604  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3605  "@
3606   br $31,$%0..ng
3607   lda $27,%0\;jmp $31,($27),%0"
3608  [(set_attr "type" "jsr")
3609   (set_attr "length" "*,8")])
3610
3611; GAS relies on the order and position of instructions output below in order
3612; to generate relocs for VMS link to potentially optimize the call.
3613; Please do not molest.
3614(define_insn "*call_vms_1"
3615  [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
3616	 (match_operand 1))
3617   (use (match_operand:DI 2 "nonmemory_operand" "r,n"))
3618   (use (reg:DI 25))
3619   (use (reg:DI 26))
3620   (clobber (reg:DI 27))]
3621  "TARGET_ABI_OPEN_VMS"
3622{
3623  switch (which_alternative)
3624    {
3625    case 0:
3626   	return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
3627    case 1:
3628	operands [2] = alpha_use_linkage (operands [0], true, false);
3629	operands [3] = alpha_use_linkage (operands [0], false, false);
3630   	return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)";
3631    default:
3632      gcc_unreachable ();
3633    }
3634}
3635  [(set_attr "type" "jsr")
3636   (set_attr "length" "12,16")])
3637
3638;; Call subroutine returning any type.
3639
3640(define_expand "untyped_call"
3641  [(parallel [(call (match_operand 0)
3642		    (const_int 0))
3643	      (match_operand 1)
3644	      (match_operand 2)])]
3645  ""
3646{
3647  int i;
3648
3649  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3650
3651  for (i = 0; i < XVECLEN (operands[2], 0); i++)
3652    {
3653      rtx set = XVECEXP (operands[2], 0, i);
3654      emit_move_insn (SET_DEST (set), SET_SRC (set));
3655    }
3656
3657  /* The optimizer does not know that the call sets the function value
3658     registers we stored in the result block.  We avoid problems by
3659     claiming that all hard registers are used and clobbered at this
3660     point.  */
3661  emit_insn (gen_blockage ());
3662
3663  DONE;
3664})
3665
3666;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3667;; all of memory.  This blocks insns from being moved across this point.
3668
3669(define_insn "blockage"
3670  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
3671  ""
3672  ""
3673  [(set_attr "length" "0")
3674   (set_attr "type" "none")])
3675
3676(define_insn "jump"
3677  [(set (pc)
3678	(label_ref (match_operand 0)))]
3679  ""
3680  "br $31,%l0"
3681  [(set_attr "type" "ibr")])
3682
3683(define_expand "return"
3684  [(return)]
3685  "direct_return ()")
3686
3687(define_insn "*return_internal"
3688  [(return)]
3689  "reload_completed"
3690  "ret $31,($26),1"
3691  [(set_attr "type" "ibr")])
3692
3693(define_insn "indirect_jump"
3694  [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3695  ""
3696  "jmp $31,(%0),0"
3697  [(set_attr "type" "ibr")])
3698
3699(define_expand "tablejump"
3700  [(parallel [(set (pc)
3701		   (match_operand 0 "register_operand"))
3702	      (use (label_ref:DI (match_operand 1)))])]
3703  ""
3704{
3705  if (TARGET_ABI_OSF)
3706    {
3707      rtx dest = gen_reg_rtx (DImode);
3708      emit_insn (gen_extendsidi2 (dest, operands[0]));
3709      emit_insn (gen_adddi3 (dest, pic_offset_table_rtx, dest));
3710      operands[0] = dest;
3711    }
3712})
3713
3714(define_insn "*tablejump_internal"
3715  [(set (pc)
3716	(match_operand:DI 0 "register_operand" "r"))
3717   (use (label_ref (match_operand 1)))]
3718  ""
3719  "jmp $31,(%0),0"
3720  [(set_attr "type" "ibr")])
3721
3722;; Cache flush.  Used by alpha_trampoline_init.  0x86 is PAL_imb, but we don't
3723;; want to have to include pal.h in our .s file.
3724(define_insn "imb"
3725  [(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
3726  ""
3727  "call_pal 0x86"
3728  [(set_attr "type" "callpal")])
3729
3730(define_expand "clear_cache"
3731  [(match_operand:DI 0)		; region start
3732   (match_operand:DI 1)]		; region end
3733  ""
3734{
3735  emit_insn (gen_imb ());
3736  DONE;
3737})
3738
3739;; BUGCHK is documented common to OSF/1 and VMS PALcode.
3740(define_insn "trap"
3741  [(trap_if (const_int 1) (const_int 0))
3742   (use (reg:DI 29))]
3743  ""
3744  "call_pal 0x81"
3745  [(set_attr "type" "callpal")])
3746
3747;; For userland, we load the thread pointer from the TCB.
3748;; For the kernel, we load the per-cpu private value.
3749
3750(define_insn "get_thread_pointerdi"
3751  [(set (match_operand:DI 0 "register_operand" "=v")
3752	(unspec:DI [(const_int 0)] UNSPEC_TP))]
3753  "TARGET_ABI_OSF"
3754{
3755  if (TARGET_TLS_KERNEL)
3756    return "call_pal 0x32";
3757  else
3758    return "call_pal 0x9e";
3759}
3760  [(set_attr "type" "callpal")])
3761
3762;; For completeness, and possibly a __builtin function, here's how to
3763;; set the thread pointer.  Since we don't describe enough of this
3764;; quantity for CSE, we have to use a volatile unspec, and then there's
3765;; not much point in creating an R16_REG register class.
3766
3767(define_expand "set_thread_pointerdi"
3768  [(set (reg:DI 16) (match_operand:DI 0 "input_operand"))
3769   (unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
3770  "TARGET_ABI_OSF")
3771
3772(define_insn "*set_tp"
3773  [(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
3774  "TARGET_ABI_OSF"
3775{
3776  if (TARGET_TLS_KERNEL)
3777    return "call_pal 0x31";
3778  else
3779    return "call_pal 0x9f";
3780}
3781  [(set_attr "type" "callpal")])
3782
3783;; Special builtins for establishing and reverting VMS condition handlers.
3784
3785(define_expand "builtin_establish_vms_condition_handler"
3786  [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))
3787   (use (match_operand:DI 1 "address_operand"))]
3788  "TARGET_ABI_OPEN_VMS"
3789{
3790  alpha_expand_builtin_establish_vms_condition_handler (operands[0],
3791                                                        operands[1]);
3792})
3793
3794(define_expand "builtin_revert_vms_condition_handler"
3795  [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))]
3796  "TARGET_ABI_OPEN_VMS"
3797  "alpha_expand_builtin_revert_vms_condition_handler (operands[0]);")
3798
3799;; Finally, we have the basic data motion insns.  The byte and word insns
3800;; are done via define_expand.  Start with the floating-point insns, since
3801;; they are simpler.
3802
3803(define_expand "movsf"
3804  [(set (match_operand:SF 0 "nonimmediate_operand")
3805	(match_operand:SF 1 "general_operand"))]
3806  ""
3807{
3808  if (MEM_P (operands[0])
3809      && ! reg_or_0_operand (operands[1], SFmode))
3810    operands[1] = force_reg (SFmode, operands[1]);
3811})
3812
3813(define_insn "*movsf"
3814  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
3815	(match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
3816  "register_operand (operands[0], SFmode)
3817   || reg_or_0_operand (operands[1], SFmode)"
3818  "@
3819   cpys %R1,%R1,%0
3820   ld%, %0,%1
3821   bis $31,%r1,%0
3822   ldl %0,%1
3823   st%, %R1,%0
3824   stl %r1,%0
3825   itofs %1,%0
3826   ftois %1,%0"
3827  [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
3828   (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
3829
3830(define_expand "movdf"
3831  [(set (match_operand:DF 0 "nonimmediate_operand")
3832	(match_operand:DF 1 "general_operand"))]
3833  ""
3834{
3835  if (MEM_P (operands[0])
3836      && ! reg_or_0_operand (operands[1], DFmode))
3837    operands[1] = force_reg (DFmode, operands[1]);
3838})
3839
3840(define_insn "*movdf"
3841  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
3842	(match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
3843  "register_operand (operands[0], DFmode)
3844   || reg_or_0_operand (operands[1], DFmode)"
3845  "@
3846   cpys %R1,%R1,%0
3847   ld%- %0,%1
3848   bis $31,%r1,%0
3849   ldq %0,%1
3850   st%- %R1,%0
3851   stq %r1,%0
3852   itoft %1,%0
3853   ftoit %1,%0"
3854  [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
3855   (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
3856
3857;; Subregs suck for register allocation.  Pretend we can move TFmode
3858;; data between general registers until after reload.
3859;; ??? Is this still true now that we have the lower-subreg pass?
3860
3861(define_expand "movtf"
3862  [(set (match_operand:TF 0 "nonimmediate_operand")
3863	(match_operand:TF 1 "general_operand"))]
3864  ""
3865{
3866  if (MEM_P (operands[0])
3867      && ! reg_or_0_operand (operands[1], TFmode))
3868    operands[1] = force_reg (TFmode, operands[1]);
3869})
3870
3871(define_insn_and_split "*movtf_internal"
3872  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3873	(match_operand:TF 1 "input_operand" "roG,rG"))]
3874  "register_operand (operands[0], TFmode)
3875   || reg_or_0_operand (operands[1], TFmode)"
3876  "#"
3877  "reload_completed"
3878  [(set (match_dup 0) (match_dup 2))
3879   (set (match_dup 1) (match_dup 3))]
3880  "alpha_split_tmode_pair (operands, TFmode, true);")
3881
3882;; We do two major things here: handle mem->mem and construct long
3883;; constants.
3884
3885(define_expand "movsi"
3886  [(set (match_operand:SI 0 "nonimmediate_operand")
3887	(match_operand:SI 1 "general_operand"))]
3888  ""
3889{
3890  if (alpha_expand_mov (SImode, operands))
3891    DONE;
3892})
3893
3894(define_insn "*movsi"
3895  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r")
3896	(match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ,s"))]
3897  "register_operand (operands[0], SImode)
3898   || reg_or_0_operand (operands[1], SImode)"
3899  "@
3900   bis $31,%r1,%0
3901   lda %0,%1($31)
3902   ldah %0,%h1($31)
3903   #
3904   ldl %0,%1
3905   stl %r1,%0
3906   lda %0,%1"
3907  [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist,ldsym")
3908   (set_attr "isa" "*,*,*,*,*,*,vms")])
3909
3910;; Split a load of a large constant into the appropriate two-insn
3911;; sequence.
3912
3913(define_split
3914  [(set (match_operand:SI 0 "register_operand")
3915	(match_operand:SI 1 "non_add_const_operand"))]
3916  ""
3917  [(const_int 0)]
3918{
3919  if (alpha_split_const_mov (SImode, operands))
3920    DONE;
3921  else
3922    FAIL;
3923})
3924
3925(define_insn "*movdi_er_low_l"
3926  [(set (match_operand:DI 0 "register_operand" "=r")
3927	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
3928		   (match_operand:DI 2 "local_symbolic_operand")))]
3929  "TARGET_EXPLICIT_RELOCS"
3930{
3931  if (true_regnum (operands[1]) == 29)
3932    return "lda %0,%2(%1)\t\t!gprel";
3933  else
3934    return "lda %0,%2(%1)\t\t!gprellow";
3935}
3936  [(set_attr "usegp" "yes")])
3937
3938(define_split
3939  [(set (match_operand:DI 0 "register_operand")
3940	(match_operand:DI 1 "small_symbolic_operand"))]
3941  "TARGET_EXPLICIT_RELOCS && reload_completed"
3942  [(set (match_dup 0)
3943	(lo_sum:DI (match_dup 2) (match_dup 1)))]
3944  "operands[2] = pic_offset_table_rtx;")
3945
3946(define_split
3947  [(set (match_operand:DI 0 "register_operand")
3948	(match_operand:DI 1 "local_symbolic_operand"))]
3949  "TARGET_EXPLICIT_RELOCS && reload_completed"
3950  [(set (match_dup 0)
3951	(plus:DI (match_dup 2) (high:DI (match_dup 1))))
3952   (set (match_dup 0)
3953	(lo_sum:DI (match_dup 0) (match_dup 1)))]
3954  "operands[2] = pic_offset_table_rtx;")
3955
3956(define_split
3957  [(match_operand 0 "some_small_symbolic_operand")]
3958  ""
3959  [(match_dup 0)]
3960  "operands[0] = split_small_symbolic_operand (operands[0]);")
3961
3962;; Accepts any symbolic, not just global, since function calls that
3963;; don't go via bsr still use !literal in hopes of linker relaxation.
3964(define_insn "movdi_er_high_g"
3965  [(set (match_operand:DI 0 "register_operand" "=r")
3966	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
3967		    (match_operand:DI 2 "symbolic_operand")
3968		    (match_operand 3 "const_int_operand")]
3969		   UNSPEC_LITERAL))]
3970  "TARGET_EXPLICIT_RELOCS"
3971{
3972  if (INTVAL (operands[3]) == 0)
3973    return "ldq %0,%2(%1)\t\t!literal";
3974  else
3975    return "ldq %0,%2(%1)\t\t!literal!%3";
3976}
3977  [(set_attr "type" "ldsym")])
3978
3979(define_split
3980  [(set (match_operand:DI 0 "register_operand")
3981	(match_operand:DI 1 "global_symbolic_operand"))]
3982  "TARGET_EXPLICIT_RELOCS && reload_completed"
3983  [(set (match_dup 0)
3984	(unspec:DI [(match_dup 2)
3985		    (match_dup 1)
3986		    (const_int 0)] UNSPEC_LITERAL))]
3987  "operands[2] = pic_offset_table_rtx;")
3988
3989(define_insn "movdi_er_tlsgd"
3990  [(set (match_operand:DI 0 "register_operand" "=r")
3991	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
3992		    (match_operand:DI 2 "symbolic_operand")
3993		    (match_operand 3 "const_int_operand")]
3994		   UNSPEC_TLSGD))]
3995  "HAVE_AS_TLS"
3996{
3997  if (INTVAL (operands[3]) == 0)
3998    return "lda %0,%2(%1)\t\t!tlsgd";
3999  else
4000    return "lda %0,%2(%1)\t\t!tlsgd!%3";
4001})
4002
4003(define_insn "movdi_er_tlsldm"
4004  [(set (match_operand:DI 0 "register_operand" "=r")
4005	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
4006		    (match_operand 2 "const_int_operand")]
4007		   UNSPEC_TLSLDM))]
4008  "HAVE_AS_TLS"
4009{
4010  if (INTVAL (operands[2]) == 0)
4011    return "lda %0,%&(%1)\t\t!tlsldm";
4012  else
4013    return "lda %0,%&(%1)\t\t!tlsldm!%2";
4014})
4015
4016(define_insn "*movdi_er_gotdtp"
4017  [(set (match_operand:DI 0 "register_operand" "=r")
4018	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
4019		    (match_operand:DI 2 "symbolic_operand")]
4020		   UNSPEC_DTPREL))]
4021  "HAVE_AS_TLS"
4022  "ldq %0,%2(%1)\t\t!gotdtprel"
4023  [(set_attr "type" "ild")
4024   (set_attr "usegp" "yes")])
4025
4026(define_split
4027  [(set (match_operand:DI 0 "register_operand")
4028	(match_operand:DI 1 "gotdtp_symbolic_operand"))]
4029  "HAVE_AS_TLS && reload_completed"
4030  [(set (match_dup 0)
4031	(unspec:DI [(match_dup 2)
4032		    (match_dup 1)] UNSPEC_DTPREL))]
4033{
4034  operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
4035  operands[2] = pic_offset_table_rtx;
4036})
4037
4038(define_insn "*movdi_er_gottp"
4039  [(set (match_operand:DI 0 "register_operand" "=r")
4040	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
4041		    (match_operand:DI 2 "symbolic_operand")]
4042		   UNSPEC_TPREL))]
4043  "HAVE_AS_TLS"
4044  "ldq %0,%2(%1)\t\t!gottprel"
4045  [(set_attr "type" "ild")
4046   (set_attr "usegp" "yes")])
4047
4048(define_split
4049  [(set (match_operand:DI 0 "register_operand")
4050	(match_operand:DI 1 "gottp_symbolic_operand"))]
4051  "HAVE_AS_TLS && reload_completed"
4052  [(set (match_dup 0)
4053	(unspec:DI [(match_dup 2)
4054		    (match_dup 1)] UNSPEC_TPREL))]
4055{
4056  operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
4057  operands[2] = pic_offset_table_rtx;
4058})
4059
4060(define_insn "*movdi"
4061  [(set (match_operand:DI 0 "nonimmediate_operand"
4062				"=r,r,r,r,r,r,r,r, m, *f,*f, Q, r,*f")
4063	(match_operand:DI 1 "input_operand"
4064				"rJ,K,L,T,s,n,s,m,rJ,*fJ, Q,*f,*f, r"))]
4065  "register_operand (operands[0], DImode)
4066   || reg_or_0_operand (operands[1], DImode)"
4067  "@
4068   mov %r1,%0
4069   lda %0,%1($31)
4070   ldah %0,%h1($31)
4071   #
4072   #
4073   #
4074   lda %0,%1
4075   ldq%A1 %0,%1
4076   stq%A0 %r1,%0
4077   fmov %R1,%0
4078   ldt %0,%1
4079   stt %R1,%0
4080   ftoit %1,%0
4081   itoft %1,%0"
4082  [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")
4083   (set_attr "isa" "*,*,*,er,er,*,ner,*,*,*,*,*,fix,fix")
4084   (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*,*")])
4085
4086;; VMS needs to set up "vms_base_regno" for unwinding.  This move
4087;; often appears dead to the life analysis code, at which point we
4088;; die for emitting dead prologue instructions.  Force this live.
4089
4090(define_insn "force_movdi"
4091  [(set (match_operand:DI 0 "register_operand" "=r")
4092	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
4093			    UNSPECV_FORCE_MOV))]
4094  ""
4095  "mov %1,%0"
4096  [(set_attr "type" "ilog")])
4097
4098;; We do three major things here: handle mem->mem, put 64-bit constants in
4099;; memory, and construct long 32-bit constants.
4100
4101(define_expand "movdi"
4102  [(set (match_operand:DI 0 "nonimmediate_operand")
4103	(match_operand:DI 1 "general_operand"))]
4104  ""
4105{
4106  if (alpha_expand_mov (DImode, operands))
4107    DONE;
4108})
4109
4110;; Split a load of a large constant into the appropriate two-insn
4111;; sequence.
4112
4113(define_split
4114  [(set (match_operand:DI 0 "register_operand")
4115	(match_operand:DI 1 "non_add_const_operand"))]
4116  ""
4117  [(const_int 0)]
4118{
4119  if (alpha_split_const_mov (DImode, operands))
4120    DONE;
4121  else
4122    FAIL;
4123})
4124
4125;; We need to prevent reload from splitting TImode moves, because it
4126;; might decide to overwrite a pointer with the value it points to.
4127;; In that case we have to do the loads in the appropriate order so
4128;; that the pointer is not destroyed too early.
4129
4130(define_insn_and_split "*movti_internal"
4131  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4132        (match_operand:TI 1 "input_operand" "roJ,rJ"))]
4133  "(register_operand (operands[0], TImode)
4134    /* Prevent rematerialization of constants.  */
4135    && ! CONSTANT_P (operands[1]))
4136   || reg_or_0_operand (operands[1], TImode)"
4137  "#"
4138  "reload_completed"
4139  [(set (match_dup 0) (match_dup 2))
4140   (set (match_dup 1) (match_dup 3))]
4141  "alpha_split_tmode_pair (operands, TImode, true);")
4142
4143(define_expand "movti"
4144  [(set (match_operand:TI 0 "nonimmediate_operand")
4145        (match_operand:TI 1 "general_operand"))]
4146  ""
4147{
4148  if (MEM_P (operands[0])
4149      && ! reg_or_0_operand (operands[1], TImode))
4150    operands[1] = force_reg (TImode, operands[1]);
4151
4152  if (operands[1] == const0_rtx)
4153    ;
4154  /* We must put 64-bit constants in memory.  We could keep the
4155     32-bit constants in TImode and rely on the splitter, but
4156     this doesn't seem to be worth the pain.  */
4157  else if (CONST_SCALAR_INT_P (operands[1]))
4158    {
4159      rtx in[2], out[2], target;
4160
4161      gcc_assert (can_create_pseudo_p ());
4162
4163      split_double (operands[1], &in[0], &in[1]);
4164
4165      if (in[0] == const0_rtx)
4166	out[0] = const0_rtx;
4167      else
4168	{
4169	  out[0] = gen_reg_rtx (DImode);
4170	  emit_insn (gen_movdi (out[0], in[0]));
4171	}
4172
4173      if (in[1] == const0_rtx)
4174	out[1] = const0_rtx;
4175      else
4176	{
4177	  out[1] = gen_reg_rtx (DImode);
4178	  emit_insn (gen_movdi (out[1], in[1]));
4179	}
4180
4181      if (!REG_P (operands[0]))
4182	target = gen_reg_rtx (TImode);
4183      else
4184	target = operands[0];
4185
4186      emit_insn (gen_movdi (operand_subword (target, 0, 0, TImode), out[0]));
4187      emit_insn (gen_movdi (operand_subword (target, 1, 0, TImode), out[1]));
4188
4189      if (target != operands[0])
4190	emit_insn (gen_rtx_SET (operands[0], target));
4191
4192      DONE;
4193    }
4194})
4195
4196;; These are the partial-word cases.
4197;;
4198;; First we have the code to load an aligned word.  Operand 0 is the register
4199;; in which to place the result.  It's mode is QImode or HImode.  Operand 1
4200;; is an SImode MEM at the low-order byte of the proper word.  Operand 2 is the
4201;; number of bits within the word that the value is.  Operand 3 is an SImode
4202;; scratch register.  If operand 0 is a hard register, operand 3 may be the
4203;; same register.  It is allowed to conflict with operand 1 as well.
4204
4205(define_expand "aligned_loadqi"
4206  [(set (match_operand:SI 3 "register_operand")
4207	(match_operand:SI 1 "memory_operand"))
4208   (set (match_operand:DI 0 "register_operand")
4209	(zero_extract:DI (subreg:DI (match_dup 3) 0)
4210			 (const_int 8)
4211			 (match_operand:DI 2 "const_int_operand")))])
4212
4213(define_expand "aligned_loadhi"
4214  [(set (match_operand:SI 3 "register_operand")
4215	(match_operand:SI 1 "memory_operand"))
4216   (set (match_operand:DI 0 "register_operand")
4217	(zero_extract:DI (subreg:DI (match_dup 3) 0)
4218			 (const_int 16)
4219			 (match_operand:DI 2 "const_int_operand")))])
4220
4221;; Similar for unaligned loads, where we use the sequence from the
4222;; Alpha Architecture manual. We have to distinguish between little-endian
4223;; and big-endian systems as the sequences are different.
4224;;
4225;; Operand 1 is the address.  Operands 2 and 3 are temporaries, where
4226;; operand 3 can overlap the input and output registers.
4227
4228(define_expand "unaligned_loadqi"
4229  [(set (match_operand:DI 2 "register_operand")
4230	(mem:DI (and:DI (match_operand:DI 1 "address_operand")
4231			(const_int -8))))
4232   (set (match_operand:DI 3 "register_operand")
4233	(match_dup 1))
4234   (set (match_operand:DI 0 "register_operand")
4235	(zero_extract:DI (match_dup 2)
4236			 (const_int 8)
4237			 (ashift:DI (match_dup 3) (const_int 3))))])
4238
4239(define_expand "unaligned_loadhi"
4240  [(set (match_operand:DI 2 "register_operand")
4241	(mem:DI (and:DI (match_operand:DI 1 "address_operand")
4242			(const_int -8))))
4243   (set (match_operand:DI 3 "register_operand")
4244	(match_dup 1))
4245   (set (match_operand:DI 0 "register_operand")
4246	(zero_extract:DI (match_dup 2)
4247			 (const_int 16)
4248			 (ashift:DI (match_dup 3) (const_int 3))))])
4249
4250;; Storing an aligned byte or word requires two temporaries.  Operand 0 is the
4251;; aligned SImode MEM.  Operand 1 is the register containing the
4252;; byte or word to store.  Operand 2 is the number of bits within the word that
4253;; the value should be placed.  Operands 3 and 4 are SImode temporaries.
4254
4255(define_expand "aligned_store"
4256  [(set (match_operand:SI 3 "register_operand")
4257	(match_operand:SI 0 "memory_operand"))
4258   (set (subreg:DI (match_dup 3) 0)
4259	(and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4260   (set (subreg:DI (match_operand:SI 4 "register_operand") 0)
4261	(ashift:DI (zero_extend:DI (match_operand 1 "register_operand"))
4262		   (match_operand:DI 2 "const_int_operand")))
4263   (set (subreg:DI (match_dup 4) 0)
4264	(ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4265   (set (match_dup 0) (match_dup 4))]
4266  ""
4267{
4268  operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4269			    << INTVAL (operands[2])));
4270})
4271
4272;; For the unaligned byte and halfword cases, we use code similar to that
4273;; in the ;; Architecture book, but reordered to lower the number of registers
4274;; required.  Operand 0 is the address.  Operand 1 is the data to store.
4275;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
4276;; be the same temporary, if desired.  If the address is in a register,
4277;; operand 2 can be that register.
4278
4279(define_expand "unaligned_store<mode>"
4280  [(set (match_operand:DI 3 "register_operand")
4281	(mem:DI (and:DI (match_operand:DI 0 "address_operand")
4282			(const_int -8))))
4283   (set (match_operand:DI 2 "register_operand")
4284	(match_dup 0))
4285   (set (match_dup 3)
4286	(and:DI (not:DI (ashift:DI (match_dup 5)
4287				   (ashift:DI (match_dup 2) (const_int 3))))
4288		(match_dup 3)))
4289   (set (match_operand:DI 4 "register_operand")
4290	(ashift:DI (zero_extend:DI
4291		     (match_operand:I12MODE 1 "register_operand"))
4292		   (ashift:DI (match_dup 2) (const_int 3))))
4293   (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4294   (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4295	(match_dup 4))]
4296  ""
4297  "operands[5] = GEN_INT (GET_MODE_MASK (<MODE>mode));")
4298
4299;; Here are the define_expand's for QI and HI moves that use the above
4300;; patterns.  We have the normal sets, plus the ones that need scratch
4301;; registers for reload.
4302
4303(define_expand "mov<mode>"
4304  [(set (match_operand:I12MODE 0 "nonimmediate_operand")
4305	(match_operand:I12MODE 1 "general_operand"))]
4306  ""
4307{
4308  if (TARGET_BWX
4309      ? alpha_expand_mov (<MODE>mode, operands)
4310      : alpha_expand_mov_nobwx (<MODE>mode, operands))
4311    DONE;
4312})
4313
4314(define_insn "*movqi"
4315  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4316	(match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
4317  "register_operand (operands[0], QImode)
4318   || reg_or_0_operand (operands[1], QImode)"
4319  "@
4320   bis $31,%r1,%0
4321   lda %0,%L1($31)
4322   ldbu %0,%1
4323   stb %r1,%0"
4324  [(set_attr "type" "ilog,iadd,ild,ist")
4325   (set_attr "isa" "*,*,bwx,bwx")])
4326
4327(define_insn "*movhi"
4328  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
4329	(match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
4330  "register_operand (operands[0], HImode)
4331   || reg_or_0_operand (operands[1], HImode)"
4332  "@
4333   bis $31,%r1,%0
4334   lda %0,%L1($31)
4335   ldwu %0,%1
4336   stw %r1,%0"
4337  [(set_attr "type" "ilog,iadd,ild,ist")
4338   (set_attr "isa" "*,*,bwx,bwx")])
4339
4340;; We need to hook into the extra support that we have for HImode
4341;; reloads when BWX insns are not available.
4342(define_expand "movcqi"
4343  [(set (match_operand:CQI 0 "nonimmediate_operand")
4344	(match_operand:CQI 1 "general_operand"))]
4345  "!TARGET_BWX"
4346{
4347  if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
4348    ;
4349  else if (!any_memory_operand (operands[0], CQImode))
4350    {
4351      if (!any_memory_operand (operands[1], CQImode))
4352	{
4353	  emit_move_insn (gen_lowpart (HImode, operands[0]),
4354			  gen_lowpart (HImode, operands[1]));
4355	  DONE;
4356	}
4357      if (aligned_memory_operand (operands[1], CQImode))
4358	{
4359	  bool done;
4360	do_aligned1:
4361	  operands[1] = gen_lowpart (HImode, operands[1]);
4362	do_aligned2:
4363	  operands[0] = gen_lowpart (HImode, operands[0]);
4364	  done = alpha_expand_mov_nobwx (HImode, operands);
4365	  gcc_assert (done);
4366	  DONE;
4367	}
4368    }
4369  else if (aligned_memory_operand (operands[0], CQImode))
4370    {
4371      if (MEM_P (operands[1]))
4372	{
4373	  rtx x = gen_reg_rtx (HImode);
4374	  emit_move_insn (gen_lowpart (CQImode, x), operands[1]);
4375	  operands[1] = x;
4376	  goto do_aligned2;
4377	}
4378      goto do_aligned1;
4379    }
4380
4381  gcc_assert (!reload_in_progress);
4382  emit_move_complex_parts (operands[0], operands[1]);
4383  DONE;
4384})
4385
4386;; Here are the versions for reload.
4387;;
4388;; The aligned input case is recognized early in alpha_secondary_reload
4389;; in order to avoid allocating an unnecessary scratch register.
4390;;
4391;; Note that in the unaligned cases we know that the operand must not be
4392;; a pseudo-register because stack slots are always aligned references.
4393
4394(define_expand "reload_in<mode>"
4395  [(parallel [(match_operand:RELOAD12 0 "register_operand" "=r")
4396	      (match_operand:RELOAD12 1 "any_memory_operand" "m")
4397	      (match_operand:TI 2 "register_operand" "=&r")])]
4398  "!TARGET_BWX"
4399{
4400  rtx scratch, seq, addr;
4401  unsigned regno = REGNO (operands[2]);
4402
4403  /* It is possible that one of the registers we got for operands[2]
4404     might coincide with that of operands[0] (which is why we made
4405     it TImode).  Pick the other one to use as our scratch.  */
4406  if (regno == REGNO (operands[0]))
4407    regno++;
4408  scratch = gen_rtx_REG (DImode, regno);
4409
4410  addr = get_unaligned_address (operands[1]);
4411  operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
4412  seq = gen_unaligned_load<reloadmode> (operands[0], addr,
4413					scratch, operands[0]);
4414  alpha_set_memflags (seq, operands[1]);
4415
4416  emit_insn (seq);
4417  DONE;
4418})
4419
4420(define_expand "reload_out<mode>"
4421  [(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m")
4422	      (match_operand:RELOAD12 1 "register_operand" "r")
4423	      (match_operand:TI 2 "register_operand" "=&r")])]
4424  "!TARGET_BWX"
4425{
4426  unsigned regno = REGNO (operands[2]);
4427
4428  if (<MODE>mode == CQImode)
4429    {
4430      operands[0] = gen_lowpart (HImode, operands[0]);
4431      operands[1] = gen_lowpart (HImode, operands[1]);
4432    }
4433
4434  if (aligned_memory_operand (operands[0], <MODE>mode))
4435    {
4436      emit_insn (gen_reload_out<reloadmode>_aligned
4437		 (operands[0], operands[1],
4438		  gen_rtx_REG (SImode, regno),
4439		  gen_rtx_REG (SImode, regno + 1)));
4440    }
4441  else
4442    {
4443      rtx addr = get_unaligned_address (operands[0]);
4444      rtx scratch1 = gen_rtx_REG (DImode, regno);
4445      rtx scratch2 = gen_rtx_REG (DImode, regno + 1);
4446      rtx scratch3 = scratch1;
4447      rtx seq;
4448
4449      if (REG_P (addr))
4450	scratch1 = addr;
4451
4452      seq = gen_unaligned_store<reloadmode> (addr, operands[1], scratch1,
4453					     scratch2, scratch3);
4454      alpha_set_memflags (seq, operands[0]);
4455      emit_insn (seq);
4456    }
4457  DONE;
4458})
4459
4460;; Helpers for the above.  The way reload is structured, we can't
4461;; always get a proper address for a stack slot during reload_foo
4462;; expansion, so we must delay our address manipulations until after.
4463
4464(define_insn_and_split "reload_in<mode>_aligned"
4465  [(set (match_operand:I12MODE 0 "register_operand" "=r")
4466        (match_operand:I12MODE 1 "memory_operand" "m"))]
4467  "!TARGET_BWX && (reload_in_progress || reload_completed)"
4468  "#"
4469  "!TARGET_BWX && reload_completed"
4470  [(const_int 0)]
4471{
4472  rtx aligned_mem, bitnum;
4473  get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4474  emit_insn (gen_aligned_load<reloadmode>
4475	     (gen_lowpart (DImode, operands[0]), aligned_mem, bitnum,
4476	      gen_rtx_REG (SImode, REGNO (operands[0]))));
4477  DONE;
4478})
4479
4480(define_insn_and_split "reload_out<mode>_aligned"
4481  [(set (match_operand:I12MODE 0 "memory_operand" "=m")
4482        (match_operand:I12MODE 1 "register_operand" "r"))
4483   (clobber (match_operand:SI 2 "register_operand" "=&r"))
4484   (clobber (match_operand:SI 3 "register_operand" "=&r"))]
4485  "!TARGET_BWX && (reload_in_progress || reload_completed)"
4486  "#"
4487  "!TARGET_BWX && reload_completed"
4488  [(const_int 0)]
4489{
4490  rtx aligned_mem, bitnum;
4491  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4492  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4493				operands[2], operands[3]));
4494  DONE;
4495})
4496
4497;; Vector operations
4498
4499(define_mode_iterator VEC [V8QI V4HI V2SI])
4500(define_mode_iterator VEC12 [V8QI V4HI])
4501
4502(define_expand "mov<mode>"
4503  [(set (match_operand:VEC 0 "nonimmediate_operand")
4504        (match_operand:VEC 1 "general_operand"))]
4505  ""
4506{
4507  if (alpha_expand_mov (<MODE>mode, operands))
4508    DONE;
4509})
4510
4511(define_split
4512  [(set (match_operand:VEC 0 "register_operand")
4513	(match_operand:VEC 1 "non_zero_const_operand"))]
4514  ""
4515  [(const_int 0)]
4516{
4517  if (alpha_split_const_mov (<MODE>mode, operands))
4518    DONE;
4519  else
4520    FAIL;
4521})
4522
4523
4524(define_expand "movmisalign<mode>"
4525  [(set (match_operand:VEC 0 "nonimmediate_operand")
4526        (match_operand:VEC 1 "general_operand"))]
4527  ""
4528{
4529  alpha_expand_movmisalign (<MODE>mode, operands);
4530  DONE;
4531})
4532
4533(define_insn "*mov<mode>_fix"
4534  [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f")
4535	(match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))]
4536  "register_operand (operands[0], <MODE>mode)
4537   || reg_or_0_operand (operands[1], <MODE>mode)"
4538  "@
4539   bis $31,%r1,%0
4540   #
4541   ldq %0,%1
4542   stq %r1,%0
4543   cpys %R1,%R1,%0
4544   ldt %0,%1
4545   stt %R1,%0
4546   ftoit %1,%0
4547   itoft %1,%0"
4548  [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")
4549   (set_attr "isa" "*,*,*,*,*,*,*,fix,fix")])
4550
4551(define_insn "<code><mode>3"
4552  [(set (match_operand:VEC12 0 "register_operand" "=r")
4553	(any_maxmin:VEC12
4554	 (match_operand:VEC12 1 "reg_or_0_operand" "rW")
4555	 (match_operand:VEC12 2 "reg_or_0_operand" "rW")))]
4556  "TARGET_MAX"
4557  "<maxmin><modesuffix> %r1,%r2,%0"
4558  [(set_attr "type" "mvi")])
4559
4560(define_insn "one_cmpl<mode>2"
4561  [(set (match_operand:VEC 0 "register_operand" "=r")
4562	(not:VEC (match_operand:VEC 1 "register_operand" "r")))]
4563  ""
4564  "ornot $31,%1,%0"
4565  [(set_attr "type" "ilog")])
4566
4567(define_insn "and<mode>3"
4568  [(set (match_operand:VEC 0 "register_operand" "=r")
4569	(and:VEC (match_operand:VEC 1 "register_operand" "r")
4570		 (match_operand:VEC 2 "register_operand" "r")))]
4571  ""
4572  "and %1,%2,%0"
4573  [(set_attr "type" "ilog")])
4574
4575(define_insn "*andnot<mode>3"
4576  [(set (match_operand:VEC 0 "register_operand" "=r")
4577	(and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r"))
4578		 (match_operand:VEC 2 "register_operand" "r")))]
4579  ""
4580  "bic %2,%1,%0"
4581  [(set_attr "type" "ilog")])
4582
4583(define_insn "ior<mode>3"
4584  [(set (match_operand:VEC 0 "register_operand" "=r")
4585	(ior:VEC (match_operand:VEC 1 "register_operand" "r")
4586		 (match_operand:VEC 2 "register_operand" "r")))]
4587  ""
4588  "bis %1,%2,%0"
4589  [(set_attr "type" "ilog")])
4590
4591(define_insn "*iornot<mode>3"
4592  [(set (match_operand:VEC 0 "register_operand" "=r")
4593	(ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r"))
4594		 (match_operand:VEC 2 "register_operand" "r")))]
4595  ""
4596  "ornot %2,%1,%0"
4597  [(set_attr "type" "ilog")])
4598
4599(define_insn "xor<mode>3"
4600  [(set (match_operand:VEC 0 "register_operand" "=r")
4601	(xor:VEC (match_operand:VEC 1 "register_operand" "r")
4602		 (match_operand:VEC 2 "register_operand" "r")))]
4603  ""
4604  "xor %1,%2,%0"
4605  [(set_attr "type" "ilog")])
4606
4607(define_insn "*xornot<mode>3"
4608  [(set (match_operand:VEC 0 "register_operand" "=r")
4609	(not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r")
4610			  (match_operand:VEC 2 "register_operand" "r"))))]
4611  ""
4612  "eqv %1,%2,%0"
4613  [(set_attr "type" "ilog")])
4614
4615(define_expand "vec_shl_<mode>"
4616  [(set (match_operand:VEC 0 "register_operand")
4617	(ashift:DI (match_operand:VEC 1 "register_operand")
4618		   (match_operand:DI 2 "reg_or_6bit_operand")))]
4619  ""
4620{
4621  operands[0] = gen_lowpart (DImode, operands[0]);
4622  operands[1] = gen_lowpart (DImode, operands[1]);
4623})
4624
4625(define_expand "vec_shr_<mode>"
4626  [(set (match_operand:VEC 0 "register_operand")
4627        (lshiftrt:DI (match_operand:VEC 1 "register_operand")
4628                     (match_operand:DI 2 "reg_or_6bit_operand")))]
4629  ""
4630{
4631  operands[0] = gen_lowpart (DImode, operands[0]);
4632  operands[1] = gen_lowpart (DImode, operands[1]);
4633})
4634
4635;; Bit field extract patterns which use ext[wlq][lh]
4636
4637(define_expand "extvmisaligndi"
4638  [(set (match_operand:DI 0 "register_operand")
4639	(sign_extract:DI (match_operand:BLK 1 "memory_operand")
4640			 (match_operand:DI 2 "const_int_operand")
4641			 (match_operand:DI 3 "const_int_operand")))]
4642  ""
4643{
4644  /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
4645  if (INTVAL (operands[3]) % 8 != 0
4646      || (INTVAL (operands[2]) != 16
4647	  && INTVAL (operands[2]) != 32
4648	  && INTVAL (operands[2]) != 64))
4649    FAIL;
4650
4651  alpha_expand_unaligned_load (operands[0], operands[1],
4652			       INTVAL (operands[2]) / 8,
4653			       INTVAL (operands[3]) / 8, 1);
4654  DONE;
4655})
4656
4657(define_expand "extzvdi"
4658  [(set (match_operand:DI 0 "register_operand")
4659	(zero_extract:DI (match_operand:DI 1 "register_operand")
4660			 (match_operand:DI 2 "const_int_operand")
4661			 (match_operand:DI 3 "const_int_operand")))]
4662  ""
4663{
4664  /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
4665  if (INTVAL (operands[3]) % 8 != 0
4666      || (INTVAL (operands[2]) != 8
4667          && INTVAL (operands[2]) != 16
4668	  && INTVAL (operands[2]) != 32
4669	  && INTVAL (operands[2]) != 64))
4670    FAIL;
4671})
4672
4673(define_expand "extzvmisaligndi"
4674  [(set (match_operand:DI 0 "register_operand")
4675	(zero_extract:DI (match_operand:BLK 1 "memory_operand")
4676			 (match_operand:DI 2 "const_int_operand")
4677			 (match_operand:DI 3 "const_int_operand")))]
4678  ""
4679{
4680  /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.
4681     We fail 8-bit fields, falling back on a simple byte load.  */
4682  if (INTVAL (operands[3]) % 8 != 0
4683      || (INTVAL (operands[2]) != 16
4684	  && INTVAL (operands[2]) != 32
4685	  && INTVAL (operands[2]) != 64))
4686    FAIL;
4687
4688  alpha_expand_unaligned_load (operands[0], operands[1],
4689			       INTVAL (operands[2]) / 8,
4690			       INTVAL (operands[3]) / 8, 0);
4691  DONE;
4692})
4693
4694(define_expand "insvmisaligndi"
4695  [(set (zero_extract:DI (match_operand:BLK 0 "memory_operand")
4696			 (match_operand:DI 1 "const_int_operand")
4697			 (match_operand:DI 2 "const_int_operand"))
4698	(match_operand:DI 3 "register_operand"))]
4699  ""
4700{
4701  /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
4702  if (INTVAL (operands[2]) % 8 != 0
4703      || (INTVAL (operands[1]) != 16
4704	  && INTVAL (operands[1]) != 32
4705	  && INTVAL (operands[1]) != 64))
4706    FAIL;
4707
4708  alpha_expand_unaligned_store (operands[0], operands[3],
4709				INTVAL (operands[1]) / 8,
4710				INTVAL (operands[2]) / 8);
4711  DONE;
4712})
4713
4714;; Block move/clear, see alpha.c for more details.
4715;; Argument 0 is the destination
4716;; Argument 1 is the source
4717;; Argument 2 is the length
4718;; Argument 3 is the alignment
4719
4720(define_expand "movmemqi"
4721  [(parallel [(set (match_operand:BLK 0 "memory_operand")
4722		   (match_operand:BLK 1 "memory_operand"))
4723	      (use (match_operand:DI 2 "immediate_operand"))
4724	      (use (match_operand:DI 3 "immediate_operand"))])]
4725  ""
4726{
4727  if (alpha_expand_block_move (operands))
4728    DONE;
4729  else
4730    FAIL;
4731})
4732
4733(define_expand "movmemdi"
4734  [(parallel [(set (match_operand:BLK 0 "memory_operand")
4735		   (match_operand:BLK 1 "memory_operand"))
4736	      (use (match_operand:DI 2 "immediate_operand"))
4737	      (use (match_operand:DI 3 "immediate_operand"))
4738	      (use (match_dup 4))
4739	      (clobber (reg:DI 25))
4740	      (clobber (reg:DI 16))
4741	      (clobber (reg:DI 17))
4742	      (clobber (reg:DI 18))
4743	      (clobber (reg:DI 19))
4744	      (clobber (reg:DI 20))
4745	      (clobber (reg:DI 26))
4746	      (clobber (reg:DI 27))])]
4747  "TARGET_ABI_OPEN_VMS"
4748  "operands[4] = gen_rtx_SYMBOL_REF (Pmode, \"OTS$MOVE\");")
4749
4750(define_insn "*movmemdi_1"
4751  [(set (match_operand:BLK 0 "memory_operand" "=m,m")
4752	(match_operand:BLK 1 "memory_operand" "m,m"))
4753   (use (match_operand:DI 2 "nonmemory_operand" "r,i"))
4754   (use (match_operand:DI 3 "immediate_operand"))
4755   (use (match_operand:DI 4 "call_operand" "i,i"))
4756   (clobber (reg:DI 25))
4757   (clobber (reg:DI 16))
4758   (clobber (reg:DI 17))
4759   (clobber (reg:DI 18))
4760   (clobber (reg:DI 19))
4761   (clobber (reg:DI 20))
4762   (clobber (reg:DI 26))
4763   (clobber (reg:DI 27))]
4764  "TARGET_ABI_OPEN_VMS"
4765{
4766  operands [5] = alpha_use_linkage (operands [4], false, true);
4767  switch (which_alternative)
4768    {
4769    case 0:
4770	return "lda $16,%0\;bis $31,%2,$17\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)";
4771    case 1:
4772	return "lda $16,%0\;lda $17,%2($31)\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)";
4773    default:
4774      gcc_unreachable ();
4775    }
4776}
4777  [(set_attr "type" "multi")
4778   (set_attr "length" "28")])
4779
4780(define_expand "setmemqi"
4781  [(parallel [(set (match_operand:BLK 0 "memory_operand")
4782		   (match_operand 2 "const_int_operand"))
4783	      (use (match_operand:DI 1 "immediate_operand"))
4784	      (use (match_operand:DI 3 "immediate_operand"))])]
4785  ""
4786{
4787  /* If value to set is not zero, use the library routine.  */
4788  if (operands[2] != const0_rtx)
4789    FAIL;
4790
4791  if (alpha_expand_block_clear (operands))
4792    DONE;
4793  else
4794    FAIL;
4795})
4796
4797(define_expand "setmemdi"
4798  [(parallel [(set (match_operand:BLK 0 "memory_operand")
4799		   (match_operand 2 "const_int_operand"))
4800	      (use (match_operand:DI 1 "immediate_operand"))
4801	      (use (match_operand:DI 3 "immediate_operand"))
4802	      (use (match_dup 4))
4803	      (clobber (reg:DI 25))
4804	      (clobber (reg:DI 16))
4805	      (clobber (reg:DI 17))
4806	      (clobber (reg:DI 26))
4807	      (clobber (reg:DI 27))])]
4808  "TARGET_ABI_OPEN_VMS"
4809{
4810  /* If value to set is not zero, use the library routine.  */
4811  if (operands[2] != const0_rtx)
4812    FAIL;
4813
4814  operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
4815})
4816
4817(define_insn "*clrmemdi_1"
4818  [(set (match_operand:BLK 0 "memory_operand" "=m,m")
4819		   (const_int 0))
4820   (use (match_operand:DI 1 "nonmemory_operand" "r,i"))
4821   (use (match_operand:DI 2 "immediate_operand"))
4822   (use (match_operand:DI 3 "call_operand" "i,i"))
4823   (clobber (reg:DI 25))
4824   (clobber (reg:DI 16))
4825   (clobber (reg:DI 17))
4826   (clobber (reg:DI 26))
4827   (clobber (reg:DI 27))]
4828  "TARGET_ABI_OPEN_VMS"
4829{
4830  operands [4] = alpha_use_linkage (operands [3], false, true);
4831  switch (which_alternative)
4832    {
4833    case 0:
4834	return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
4835    case 1:
4836	return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
4837    default:
4838      gcc_unreachable ();
4839    }
4840}
4841  [(set_attr "type" "multi")
4842   (set_attr "length" "24")])
4843
4844
4845;; Subroutine of stack space allocation.  Perform a stack probe.
4846(define_expand "stack_probe_internal"
4847  [(set (match_dup 1) (match_operand:DI 0 "const_int_operand"))]
4848  ""
4849{
4850  operands[1] = gen_rtx_MEM (DImode, plus_constant (Pmode, stack_pointer_rtx,
4851						    INTVAL (operands[0])));
4852  MEM_VOLATILE_P (operands[1]) = 1;
4853
4854  operands[0] = const0_rtx;
4855})
4856
4857;; This is how we allocate stack space.  If we are allocating a
4858;; constant amount of space and we know it is less than 4096
4859;; bytes, we need do nothing.
4860;;
4861;; If it is more than 4096 bytes, we need to probe the stack
4862;; periodically.
4863(define_expand "allocate_stack"
4864  [(set (reg:DI 30)
4865	(plus:DI (reg:DI 30)
4866		 (match_operand:DI 1 "reg_or_cint_operand")))
4867   (set (match_operand:DI 0 "register_operand" "=r")
4868	(match_dup 2))]
4869  ""
4870{
4871  if (CONST_INT_P (operands[1])
4872      && INTVAL (operands[1]) < 32768)
4873    {
4874      if (INTVAL (operands[1]) >= 4096)
4875	{
4876	  /* We do this the same way as in the prologue and generate explicit
4877	     probes.  Then we update the stack by the constant.  */
4878
4879	  int probed = 4096;
4880
4881	  emit_insn (gen_stack_probe_internal (GEN_INT (- probed)));
4882	  while (probed + 8192 < INTVAL (operands[1]))
4883	    emit_insn (gen_stack_probe_internal
4884		       (GEN_INT (- (probed += 8192))));
4885
4886	  if (probed + 4096 < INTVAL (operands[1]))
4887	    emit_insn (gen_stack_probe_internal
4888		       (GEN_INT (- INTVAL(operands[1]))));
4889	}
4890
4891      operands[1] = GEN_INT (- INTVAL (operands[1]));
4892      operands[2] = virtual_stack_dynamic_rtx;
4893    }
4894  else
4895    {
4896      rtx_code_label *out_label = 0;
4897      rtx_code_label *loop_label = gen_label_rtx ();
4898      rtx want = gen_reg_rtx (Pmode);
4899      rtx tmp = gen_reg_rtx (Pmode);
4900      rtx memref, test;
4901
4902      emit_insn (gen_subdi3 (want, stack_pointer_rtx,
4903			     force_reg (Pmode, operands[1])));
4904
4905      if (!CONST_INT_P (operands[1]))
4906	{
4907	  rtx limit = GEN_INT (4096);
4908	  out_label = gen_label_rtx ();
4909	  test = gen_rtx_LTU (VOIDmode, operands[1], limit);
4910	  emit_jump_insn
4911	    (gen_cbranchdi4 (test, operands[1], limit, out_label));
4912	}
4913
4914      emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
4915      emit_label (loop_label);
4916      memref = gen_rtx_MEM (DImode, tmp);
4917      MEM_VOLATILE_P (memref) = 1;
4918      emit_move_insn (memref, const0_rtx);
4919      emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
4920      test = gen_rtx_GTU (VOIDmode, tmp, want);
4921      emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
4922
4923      memref = gen_rtx_MEM (DImode, want);
4924      MEM_VOLATILE_P (memref) = 1;
4925      emit_move_insn (memref, const0_rtx);
4926
4927      if (out_label)
4928	emit_label (out_label);
4929
4930      emit_move_insn (stack_pointer_rtx, want);
4931      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
4932      DONE;
4933    }
4934})
4935
4936;; This is used by alpha_expand_prolog to do the same thing as above,
4937;; except we cannot at that time generate new basic blocks, so we hide
4938;; the loop in this one insn.
4939
4940(define_insn "prologue_stack_probe_loop"
4941  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
4942		     (match_operand:DI 1 "register_operand" "r")]
4943		    UNSPECV_PSPL)]
4944  ""
4945{
4946  operands[2] = gen_label_rtx ();
4947  (*targetm.asm_out.internal_label) (asm_out_file, "L",
4948			     CODE_LABEL_NUMBER (operands[2]));
4949
4950  return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
4951}
4952  [(set_attr "length" "16")
4953   (set_attr "type" "multi")])
4954
4955(define_expand "prologue"
4956  [(const_int 0)]
4957  ""
4958{
4959  alpha_expand_prologue ();
4960  DONE;
4961})
4962
4963;; These take care of emitting the ldgp insn in the prologue. This will be
4964;; an lda/ldah pair and we want to align them properly.  So we have two
4965;; unspec_volatile insns, the first of which emits the ldgp assembler macro
4966;; and the second of which emits nothing.  However, both are marked as type
4967;; IADD (the default) so the alignment code in alpha.c does the right thing
4968;; with them.
4969
4970(define_expand "prologue_ldgp"
4971  [(set (match_dup 0)
4972	(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
4973   (set (match_dup 0)
4974	(unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
4975  ""
4976{
4977  operands[0] = pic_offset_table_rtx;
4978  operands[1] = gen_rtx_REG (Pmode, 27);
4979  operands[2] = (TARGET_EXPLICIT_RELOCS
4980		 ? GEN_INT (alpha_next_sequence_number++)
4981		 : const0_rtx);
4982})
4983
4984(define_insn "*ldgp_er_1"
4985  [(set (match_operand:DI 0 "register_operand" "=r")
4986	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
4987			     (match_operand 2 "const_int_operand")]
4988			    UNSPECV_LDGP1))]
4989  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4990  "ldah %0,0(%1)\t\t!gpdisp!%2"
4991  [(set_attr "cannot_copy" "true")])
4992
4993(define_insn "*ldgp_er_2"
4994  [(set (match_operand:DI 0 "register_operand" "=r")
4995	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
4996		    (match_operand 2 "const_int_operand")]
4997		   UNSPEC_LDGP2))]
4998  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4999  "lda %0,0(%1)\t\t!gpdisp!%2"
5000  [(set_attr "cannot_copy" "true")])
5001
5002(define_insn "*prologue_ldgp_er_2"
5003  [(set (match_operand:DI 0 "register_operand" "=r")
5004	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5005			     (match_operand 2 "const_int_operand")]
5006		   	    UNSPECV_PLDGP2))]
5007  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5008  "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
5009  [(set_attr "cannot_copy" "true")])
5010
5011(define_insn "*prologue_ldgp_1"
5012  [(set (match_operand:DI 0 "register_operand" "=r")
5013	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5014			     (match_operand 2 "const_int_operand")]
5015			    UNSPECV_LDGP1))]
5016  ""
5017  "ldgp %0,0(%1)\n$%~..ng:"
5018  [(set_attr "cannot_copy" "true")])
5019
5020(define_insn "*prologue_ldgp_2"
5021  [(set (match_operand:DI 0 "register_operand" "=r")
5022	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5023			     (match_operand 2 "const_int_operand")]
5024		   	    UNSPECV_PLDGP2))]
5025  ""
5026 )
5027
5028;; The _mcount profiling hook has special calling conventions, and
5029;; does not clobber all the registers that a normal call would.  So
5030;; hide the fact this is a call at all.
5031
5032(define_insn "prologue_mcount"
5033  [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
5034  ""
5035{
5036  if (TARGET_EXPLICIT_RELOCS)
5037    /* Note that we cannot use a lituse_jsr reloc, since _mcount
5038       cannot be called via the PLT.  */
5039    return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount";
5040  else
5041    return "lda $28,_mcount\;jsr $28,($28),_mcount";
5042}
5043  [(set_attr "type" "multi")
5044   (set_attr "length" "8")])
5045
5046(define_insn "init_fp"
5047  [(set (match_operand:DI 0 "register_operand" "=r")
5048        (match_operand:DI 1 "register_operand" "r"))
5049   (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
5050  ""
5051  "bis $31,%1,%0")
5052
5053(define_expand "epilogue"
5054  [(return)]
5055  ""
5056  "alpha_expand_epilogue ();")
5057
5058(define_expand "sibcall_epilogue"
5059  [(return)]
5060  "TARGET_ABI_OSF"
5061{
5062  alpha_expand_epilogue ();
5063  DONE;
5064})
5065
5066(define_expand "builtin_longjmp"
5067  [(use (match_operand:DI 0 "register_operand" "r"))]
5068  "TARGET_ABI_OSF"
5069{
5070  /* The elements of the buffer are, in order:  */
5071  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5072  rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 8));
5073  rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 16));
5074  rtx pv = gen_rtx_REG (Pmode, 27);
5075
5076  /* This bit is the same as expand_builtin_longjmp.  */
5077  emit_move_insn (hard_frame_pointer_rtx, fp);
5078  emit_move_insn (pv, lab);
5079  emit_stack_restore (SAVE_NONLOCAL, stack);
5080  emit_use (hard_frame_pointer_rtx);
5081  emit_use (stack_pointer_rtx);
5082
5083  /* Load the label we are jumping through into $27 so that we know
5084     where to look for it when we get back to setjmp's function for
5085     restoring the gp.  */
5086  emit_jump_insn (gen_builtin_longjmp_internal (pv));
5087  emit_barrier ();
5088  DONE;
5089})
5090
5091;; This is effectively a copy of indirect_jump, but constrained such
5092;; that register renaming cannot foil our cunning plan with $27.
5093(define_insn "builtin_longjmp_internal"
5094  [(set (pc)
5095	(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
5096			 UNSPECV_LONGJMP))]
5097  ""
5098  "jmp $31,(%0),0"
5099  [(set_attr "type" "ibr")])
5100
5101(define_expand "builtin_setjmp_receiver"
5102  [(unspec_volatile [(label_ref (match_operand 0))] UNSPECV_SETJMPR)]
5103  "TARGET_ABI_OSF")
5104
5105(define_insn_and_split "*builtin_setjmp_receiver_1"
5106  [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR)]
5107  "TARGET_ABI_OSF"
5108{
5109  if (TARGET_EXPLICIT_RELOCS)
5110    return "#";
5111  else
5112    return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
5113}
5114  "&& TARGET_EXPLICIT_RELOCS && reload_completed"
5115  [(set (match_dup 1)
5116	(unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
5117   (set (match_dup 1)
5118	(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
5119{
5120  if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0))
5121    emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]),
5122					UNSPECV_SETJMPR_ER));
5123  operands[1] = pic_offset_table_rtx;
5124  operands[2] = gen_rtx_REG (Pmode, 27);
5125  operands[3] = GEN_INT (alpha_next_sequence_number++);
5126}
5127  [(set_attr "length" "12")
5128   (set_attr "type" "multi")])
5129
5130(define_insn "*builtin_setjmp_receiver_er_sl_1"
5131  [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR_ER)]
5132  "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
5133  "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
5134
5135;; When flag_reorder_blocks_and_partition is in effect, compiler puts
5136;; exception landing pads in a cold section.  To prevent inter-section offset
5137;; calculation, a jump to original landing pad is emitted in the place of the
5138;; original landing pad.  Since landing pad is moved, RA-relative GP
5139;; calculation in the prologue of landing pad breaks.  To solve this problem,
5140;; we use alternative GP load approach.
5141
5142(define_expand "exception_receiver"
5143  [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
5144  "TARGET_ABI_OSF"
5145{
5146  if (flag_reorder_blocks_and_partition)
5147    operands[0] = alpha_gp_save_rtx ();
5148  else
5149    operands[0] = const0_rtx;
5150})
5151
5152(define_insn "*exception_receiver_2"
5153  [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
5154  "TARGET_ABI_OSF && flag_reorder_blocks_and_partition"
5155  "ldq $29,%0"
5156  [(set_attr "type" "ild")])
5157
5158(define_insn_and_split "*exception_receiver_1"
5159  [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
5160  "TARGET_ABI_OSF"
5161{
5162  if (TARGET_EXPLICIT_RELOCS)
5163    return "#";
5164  else
5165    return "ldgp $29,0($26)";
5166}
5167  "&& TARGET_EXPLICIT_RELOCS && reload_completed"
5168  [(set (match_dup 0)
5169	(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
5170   (set (match_dup 0)
5171	(unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
5172{
5173  operands[0] = pic_offset_table_rtx;
5174  operands[1] = gen_rtx_REG (Pmode, 26);
5175  operands[2] = GEN_INT (alpha_next_sequence_number++);
5176}
5177  [(set_attr "length" "8")
5178   (set_attr "type" "multi")])
5179
5180(define_expand "nonlocal_goto_receiver"
5181  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
5182   (set (reg:DI 27) (mem:DI (reg:DI 29)))
5183   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
5184   (use (reg:DI 27))]
5185  "TARGET_ABI_OPEN_VMS")
5186
5187(define_insn "arg_home"
5188  [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
5189   (use (reg:DI 1))
5190   (use (reg:DI 25))
5191   (use (reg:DI 16))
5192   (use (reg:DI 17))
5193   (use (reg:DI 18))
5194   (use (reg:DI 19))
5195   (use (reg:DI 20))
5196   (use (reg:DI 21))
5197   (use (reg:DI 48))
5198   (use (reg:DI 49))
5199   (use (reg:DI 50))
5200   (use (reg:DI 51))
5201   (use (reg:DI 52))
5202   (use (reg:DI 53))
5203   (clobber (mem:BLK (const_int 0)))
5204   (clobber (reg:DI 24))
5205   (clobber (reg:DI 25))
5206   (clobber (reg:DI 0))]
5207  "TARGET_ABI_OPEN_VMS"
5208  "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5209  [(set_attr "length" "16")
5210   (set_attr "type" "multi")])
5211
5212;; Prefetch data.
5213;;
5214;; On EV4, these instructions are nops -- no load occurs.
5215;;
5216;; On EV5, these instructions act as a normal load, and thus can trap
5217;; if the address is invalid.  The OS may (or may not) handle this in
5218;; the entMM fault handler and suppress the fault.  If so, then this
5219;; has the effect of a read prefetch instruction.
5220;;
5221;; On EV6, these become official prefetch instructions.
5222
5223(define_insn "prefetch"
5224  [(prefetch (match_operand:DI 0 "address_operand" "p")
5225	     (match_operand:DI 1 "const_int_operand" "n")
5226	     (match_operand:DI 2 "const_int_operand" "n"))]
5227  "TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6"
5228{
5229  /* Interpret "no temporal locality" as this data should be evicted once
5230     it is used.  The "evict next" alternatives load the data into the cache
5231     and leave the LRU eviction counter pointing to that block.  */
5232  static const char * const alt[2][2] = {
5233    {
5234      "ldq $31,%a0",		/* read, evict next */
5235      "ldl $31,%a0",		/* read, evict last */
5236    },
5237    {
5238      "ldt $f31,%a0",		/* write, evict next */
5239      "lds $f31,%a0",		/* write, evict last */
5240    }
5241  };
5242
5243  bool write = INTVAL (operands[1]) != 0;
5244  bool lru = INTVAL (operands[2]) != 0;
5245
5246  return alt[write][lru];
5247}
5248  [(set_attr "type" "ild")])
5249
5250;; Close the trap shadow of preceding instructions.  This is generated
5251;; by alpha_reorg.
5252
5253(define_insn "trapb"
5254  [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
5255  ""
5256  "trapb"
5257  [(set_attr "type" "misc")])
5258
5259;; No-op instructions used by machine-dependent reorg to preserve
5260;; alignment for instruction issue.
5261;; The Unicos/Mk assembler does not support these opcodes.
5262
5263(define_insn "nop"
5264  [(const_int 0)]
5265  ""
5266  "bis $31,$31,$31"
5267  [(set_attr "type" "ilog")])
5268
5269(define_insn "fnop"
5270  [(const_int 1)]
5271  "TARGET_FP"
5272  "cpys $f31,$f31,$f31"
5273  [(set_attr "type" "fcpys")])
5274
5275(define_insn "unop"
5276  [(const_int 2)]
5277  ""
5278  "ldq_u $31,0($30)")
5279
5280(define_insn "realign"
5281  [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
5282		    UNSPECV_REALIGN)]
5283  ""
5284  ".align %0 #realign")
5285
5286;; Instructions to be emitted from __builtins.
5287
5288(define_insn "builtin_cmpbge"
5289  [(set (match_operand:DI 0 "register_operand" "=r")
5290	(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ")
5291		    (match_operand:DI 2 "reg_or_8bit_operand" "rI")]
5292		   UNSPEC_CMPBGE))]
5293  ""
5294  "cmpbge %r1,%2,%0"
5295  ;; The EV6 data sheets list this as ILOG.  OTOH, EV6 doesn't
5296  ;; actually differentiate between ILOG and ICMP in the schedule.
5297  [(set_attr "type" "icmp")])
5298
5299(define_expand "extbl"
5300  [(match_operand:DI 0 "register_operand")
5301   (match_operand:DI 1 "reg_or_0_operand")
5302   (match_operand:DI 2 "reg_or_8bit_operand")]
5303  ""
5304{
5305  emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (8), operands[2]));
5306  DONE;
5307})
5308
5309(define_expand "extwl"
5310  [(match_operand:DI 0 "register_operand")
5311   (match_operand:DI 1 "reg_or_0_operand")
5312   (match_operand:DI 2 "reg_or_8bit_operand")]
5313  ""
5314{
5315  emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (16), operands[2]));
5316  DONE;
5317})
5318
5319(define_expand "extll"
5320  [(match_operand:DI 0 "register_operand")
5321   (match_operand:DI 1 "reg_or_0_operand")
5322   (match_operand:DI 2 "reg_or_8bit_operand")]
5323  ""
5324{
5325  emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (32), operands[2]));
5326  DONE;
5327})
5328
5329(define_expand "extql"
5330  [(match_operand:DI 0 "register_operand")
5331   (match_operand:DI 1 "reg_or_0_operand")
5332   (match_operand:DI 2 "reg_or_8bit_operand")]
5333  ""
5334{
5335  emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (64), operands[2]));
5336  DONE;
5337})
5338
5339(define_expand "builtin_insbl"
5340  [(match_operand:DI 0 "register_operand")
5341   (match_operand:DI 1 "register_operand")
5342   (match_operand:DI 2 "reg_or_8bit_operand")]
5343  ""
5344{
5345  operands[1] = gen_lowpart (QImode, operands[1]);
5346  emit_insn (gen_insbl (operands[0], operands[1], operands[2]));
5347  DONE;
5348})
5349
5350(define_expand "builtin_inswl"
5351  [(match_operand:DI 0 "register_operand")
5352   (match_operand:DI 1 "register_operand")
5353   (match_operand:DI 2 "reg_or_8bit_operand")]
5354  ""
5355{
5356  operands[1] = gen_lowpart (HImode, operands[1]);
5357  emit_insn (gen_inswl (operands[0], operands[1], operands[2]));
5358  DONE;
5359})
5360
5361(define_expand "builtin_insll"
5362  [(match_operand:DI 0 "register_operand")
5363   (match_operand:DI 1 "register_operand")
5364   (match_operand:DI 2 "reg_or_8bit_operand")]
5365  ""
5366{
5367  operands[1] = gen_lowpart (SImode, operands[1]);
5368  emit_insn (gen_insll (operands[0], operands[1], operands[2]));
5369  DONE;
5370})
5371
5372(define_expand "inswh"
5373  [(match_operand:DI 0 "register_operand")
5374   (match_operand:DI 1 "register_operand")
5375   (match_operand:DI 2 "reg_or_8bit_operand")]
5376  ""
5377{
5378  emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
5379  DONE;
5380})
5381
5382(define_expand "inslh"
5383  [(match_operand:DI 0 "register_operand")
5384   (match_operand:DI 1 "register_operand")
5385   (match_operand:DI 2 "reg_or_8bit_operand")]
5386  ""
5387{
5388  emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
5389  DONE;
5390})
5391
5392(define_expand "insqh"
5393  [(match_operand:DI 0 "register_operand")
5394   (match_operand:DI 1 "register_operand")
5395   (match_operand:DI 2 "reg_or_8bit_operand")]
5396  ""
5397{
5398  emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
5399  DONE;
5400})
5401
5402(define_expand "mskbl"
5403  [(match_operand:DI 0 "register_operand")
5404   (match_operand:DI 1 "reg_or_0_operand")
5405   (match_operand:DI 2 "reg_or_8bit_operand")]
5406  ""
5407{
5408  rtx mask = GEN_INT (0xff);
5409  emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5410  DONE;
5411})
5412
5413(define_expand "mskwl"
5414  [(match_operand:DI 0 "register_operand")
5415   (match_operand:DI 1 "reg_or_0_operand")
5416   (match_operand:DI 2 "reg_or_8bit_operand")]
5417  ""
5418{
5419  rtx mask = GEN_INT (0xffff);
5420  emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5421  DONE;
5422})
5423
5424(define_expand "mskll"
5425  [(match_operand:DI 0 "register_operand")
5426   (match_operand:DI 1 "reg_or_0_operand")
5427   (match_operand:DI 2 "reg_or_8bit_operand")]
5428  ""
5429{
5430  rtx mask = gen_int_mode (0xffffffff, DImode);
5431  emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5432  DONE;
5433})
5434
5435(define_expand "mskql"
5436  [(match_operand:DI 0 "register_operand")
5437   (match_operand:DI 1 "reg_or_0_operand")
5438   (match_operand:DI 2 "reg_or_8bit_operand")]
5439  ""
5440{
5441  rtx mask = constm1_rtx;
5442  emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5443  DONE;
5444})
5445
5446(define_expand "mskwh"
5447  [(match_operand:DI 0 "register_operand")
5448   (match_operand:DI 1 "register_operand")
5449   (match_operand:DI 2 "reg_or_8bit_operand")]
5450  ""
5451{
5452  emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
5453  DONE;
5454})
5455
5456(define_expand "msklh"
5457  [(match_operand:DI 0 "register_operand")
5458   (match_operand:DI 1 "register_operand")
5459   (match_operand:DI 2 "reg_or_8bit_operand")]
5460  ""
5461{
5462  emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
5463  DONE;
5464})
5465
5466(define_expand "mskqh"
5467  [(match_operand:DI 0 "register_operand")
5468   (match_operand:DI 1 "register_operand")
5469   (match_operand:DI 2 "reg_or_8bit_operand")]
5470  ""
5471{
5472  emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
5473  DONE;
5474})
5475
5476(define_expand "builtin_zap"
5477  [(set (match_operand:DI 0 "register_operand")
5478	(and:DI (unspec:DI
5479		  [(match_operand:DI 2 "reg_or_cint_operand")]
5480		  UNSPEC_ZAP)
5481		(match_operand:DI 1 "reg_or_cint_operand")))]
5482  ""
5483{
5484  if (CONST_INT_P (operands[2]))
5485    {
5486      rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
5487
5488      if (mask == const0_rtx)
5489	{
5490	  emit_move_insn (operands[0], const0_rtx);
5491	  DONE;
5492	}
5493      if (mask == constm1_rtx)
5494	{
5495	  emit_move_insn (operands[0], operands[1]);
5496	  DONE;
5497	}
5498
5499      operands[1] = force_reg (DImode, operands[1]);
5500      emit_insn (gen_anddi3 (operands[0], operands[1], mask));
5501      DONE;
5502    }
5503
5504  operands[1] = force_reg (DImode, operands[1]);
5505  operands[2] = gen_lowpart (QImode, operands[2]);
5506})
5507
5508(define_insn "*builtin_zap_1"
5509  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
5510	(and:DI (unspec:DI
5511		  [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")]
5512		  UNSPEC_ZAP)
5513		(match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))]
5514  ""
5515  "@
5516   #
5517   #
5518   bis $31,$31,%0
5519   zap %r1,%2,%0"
5520  [(set_attr "type" "shift,shift,ilog,shift")])
5521
5522(define_split
5523  [(set (match_operand:DI 0 "register_operand")
5524	(and:DI (unspec:DI
5525		  [(match_operand:QI 2 "const_int_operand")]
5526		  UNSPEC_ZAP)
5527		(match_operand:DI 1 "const_int_operand")))]
5528  ""
5529  [(const_int 0)]
5530{
5531  rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
5532
5533  operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
5534  emit_move_insn (operands[0], operands[1]);
5535  DONE;
5536})
5537
5538(define_split
5539  [(set (match_operand:DI 0 "register_operand")
5540	(and:DI (unspec:DI
5541		  [(match_operand:QI 2 "const_int_operand")]
5542		  UNSPEC_ZAP)
5543		(match_operand:DI 1 "register_operand")))]
5544  ""
5545  [(set (match_dup 0)
5546	(and:DI (match_dup 1) (match_dup 2)))]
5547{
5548  operands[2] = alpha_expand_zap_mask (INTVAL (operands[2]));
5549  if (operands[2] == const0_rtx)
5550    {
5551      emit_move_insn (operands[0], const0_rtx);
5552      DONE;
5553    }
5554  if (operands[2] == constm1_rtx)
5555    {
5556      emit_move_insn (operands[0], operands[1]);
5557      DONE;
5558    }
5559})
5560
5561(define_expand "builtin_zapnot"
5562  [(set (match_operand:DI 0 "register_operand")
5563	(and:DI (unspec:DI
5564		  [(not:QI (match_operand:DI 2 "reg_or_cint_operand"))]
5565		  UNSPEC_ZAP)
5566		(match_operand:DI 1 "reg_or_cint_operand")))]
5567  ""
5568{
5569  if (CONST_INT_P (operands[2]))
5570    {
5571      rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
5572
5573      if (mask == const0_rtx)
5574	{
5575	  emit_move_insn (operands[0], const0_rtx);
5576	  DONE;
5577	}
5578      if (mask == constm1_rtx)
5579	{
5580	  emit_move_insn (operands[0], operands[1]);
5581	  DONE;
5582	}
5583
5584      operands[1] = force_reg (DImode, operands[1]);
5585      emit_insn (gen_anddi3 (operands[0], operands[1], mask));
5586      DONE;
5587    }
5588
5589  operands[1] = force_reg (DImode, operands[1]);
5590  operands[2] = gen_lowpart (QImode, operands[2]);
5591})
5592
5593(define_insn "*builtin_zapnot_1"
5594  [(set (match_operand:DI 0 "register_operand" "=r")
5595	(and:DI (unspec:DI
5596                  [(not:QI (match_operand:QI 2 "register_operand" "r"))]
5597                  UNSPEC_ZAP)
5598		(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
5599  ""
5600  "zapnot %r1,%2,%0"
5601  [(set_attr "type" "shift")])
5602
5603(define_insn "builtin_amask"
5604  [(set (match_operand:DI 0 "register_operand" "=r")
5605	(unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")]
5606		   UNSPEC_AMASK))]
5607  ""
5608  "amask %1,%0"
5609  [(set_attr "type" "ilog")])
5610
5611(define_insn "builtin_implver"
5612  [(set (match_operand:DI 0 "register_operand" "=r")
5613  	(unspec:DI [(const_int 0)] UNSPEC_IMPLVER))]
5614  ""
5615  "implver %0"
5616  [(set_attr "type" "ilog")])
5617
5618(define_insn "builtin_rpcc"
5619  [(set (match_operand:DI 0 "register_operand" "=r")
5620  	(unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))]
5621  ""
5622  "rpcc %0"
5623  [(set_attr "type" "ilog")])
5624
5625(define_expand "builtin_minub8"
5626  [(match_operand:DI 0 "register_operand")
5627   (match_operand:DI 1 "reg_or_0_operand")
5628   (match_operand:DI 2 "reg_or_0_operand")]
5629  "TARGET_MAX"
5630{
5631  alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
5632				     operands[1], operands[2]);
5633  DONE;
5634})
5635
5636(define_expand "builtin_minsb8"
5637  [(match_operand:DI 0 "register_operand")
5638   (match_operand:DI 1 "reg_or_0_operand")
5639   (match_operand:DI 2 "reg_or_0_operand")]
5640  "TARGET_MAX"
5641{
5642  alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
5643				     operands[1], operands[2]);
5644  DONE;
5645})
5646
5647(define_expand "builtin_minuw4"
5648  [(match_operand:DI 0 "register_operand")
5649   (match_operand:DI 1 "reg_or_0_operand")
5650   (match_operand:DI 2 "reg_or_0_operand")]
5651  "TARGET_MAX"
5652{
5653  alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
5654				     operands[1], operands[2]);
5655  DONE;
5656})
5657
5658(define_expand "builtin_minsw4"
5659  [(match_operand:DI 0 "register_operand")
5660   (match_operand:DI 1 "reg_or_0_operand")
5661   (match_operand:DI 2 "reg_or_0_operand")]
5662  "TARGET_MAX"
5663{
5664  alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
5665				     operands[1], operands[2]);
5666  DONE;
5667})
5668
5669(define_expand "builtin_maxub8"
5670  [(match_operand:DI 0 "register_operand")
5671   (match_operand:DI 1 "reg_or_0_operand")
5672   (match_operand:DI 2 "reg_or_0_operand")]
5673  "TARGET_MAX"
5674{
5675  alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
5676				     operands[1], operands[2]);
5677  DONE;
5678})
5679
5680(define_expand "builtin_maxsb8"
5681  [(match_operand:DI 0 "register_operand")
5682   (match_operand:DI 1 "reg_or_0_operand")
5683   (match_operand:DI 2 "reg_or_0_operand")]
5684  "TARGET_MAX"
5685{
5686  alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
5687				     operands[1], operands[2]);
5688  DONE;
5689})
5690
5691(define_expand "builtin_maxuw4"
5692  [(match_operand:DI 0 "register_operand")
5693   (match_operand:DI 1 "reg_or_0_operand")
5694   (match_operand:DI 2 "reg_or_0_operand")]
5695  "TARGET_MAX"
5696{
5697  alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
5698				     operands[1], operands[2]);
5699  DONE;
5700})
5701
5702(define_expand "builtin_maxsw4"
5703  [(match_operand:DI 0 "register_operand")
5704   (match_operand:DI 1 "reg_or_0_operand")
5705   (match_operand:DI 2 "reg_or_0_operand")]
5706  "TARGET_MAX"
5707{
5708  alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
5709				     operands[1], operands[2]);
5710  DONE;
5711})
5712
5713(define_insn "builtin_perr"
5714  [(set (match_operand:DI 0 "register_operand" "=r")
5715	(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ")
5716		    (match_operand:DI 2 "reg_or_8bit_operand" "rJ")]
5717		   UNSPEC_PERR))]
5718  "TARGET_MAX"
5719  "perr %r1,%r2,%0"
5720  [(set_attr "type" "mvi")])
5721
5722(define_expand "builtin_pklb"
5723  [(set (match_operand:DI 0 "register_operand")
5724	(vec_concat:V8QI
5725	  (vec_concat:V4QI
5726	    (truncate:V2QI (match_operand:DI 1 "register_operand"))
5727	    (match_dup 2))
5728	  (match_dup 3)))]
5729  "TARGET_MAX"
5730{
5731  operands[0] = gen_lowpart (V8QImode, operands[0]);
5732  operands[1] = gen_lowpart (V2SImode, operands[1]);
5733  operands[2] = CONST0_RTX (V2QImode);
5734  operands[3] = CONST0_RTX (V4QImode);
5735})
5736
5737(define_insn "*pklb"
5738  [(set (match_operand:V8QI 0 "register_operand" "=r")
5739	(vec_concat:V8QI
5740	  (vec_concat:V4QI
5741	    (truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
5742	    (match_operand:V2QI 2 "const0_operand"))
5743	  (match_operand:V4QI 3 "const0_operand")))]
5744  "TARGET_MAX"
5745  "pklb %r1,%0"
5746  [(set_attr "type" "mvi")])
5747
5748(define_expand "builtin_pkwb"
5749  [(set (match_operand:DI 0 "register_operand")
5750	(vec_concat:V8QI
5751	  (truncate:V4QI (match_operand:DI 1 "register_operand"))
5752	  (match_dup 2)))]
5753  "TARGET_MAX"
5754{
5755  operands[0] = gen_lowpart (V8QImode, operands[0]);
5756  operands[1] = gen_lowpart (V4HImode, operands[1]);
5757  operands[2] = CONST0_RTX (V4QImode);
5758})
5759
5760(define_insn "*pkwb"
5761  [(set (match_operand:V8QI 0 "register_operand" "=r")
5762	(vec_concat:V8QI
5763	  (truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
5764	  (match_operand:V4QI 2 "const0_operand")))]
5765  "TARGET_MAX"
5766  "pkwb %r1,%0"
5767  [(set_attr "type" "mvi")])
5768
5769(define_expand "builtin_unpkbl"
5770  [(set (match_operand:DI 0 "register_operand")
5771	(zero_extend:V2SI
5772	  (vec_select:V2QI (match_operand:DI 1 "register_operand")
5773			   (parallel [(const_int 0) (const_int 1)]))))]
5774  "TARGET_MAX"
5775{
5776  operands[0] = gen_lowpart (V2SImode, operands[0]);
5777  operands[1] = gen_lowpart (V8QImode, operands[1]);
5778})
5779
5780(define_insn "*unpkbl"
5781  [(set (match_operand:V2SI 0 "register_operand" "=r")
5782	(zero_extend:V2SI
5783	  (vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
5784			   (parallel [(const_int 0) (const_int 1)]))))]
5785  "TARGET_MAX"
5786  "unpkbl %r1,%0"
5787  [(set_attr "type" "mvi")])
5788
5789(define_expand "builtin_unpkbw"
5790  [(set (match_operand:DI 0 "register_operand")
5791	(zero_extend:V4HI
5792	  (vec_select:V4QI (match_operand:DI 1 "register_operand")
5793			   (parallel [(const_int 0)
5794				      (const_int 1)
5795				      (const_int 2)
5796				      (const_int 3)]))))]
5797  "TARGET_MAX"
5798{
5799  operands[0] = gen_lowpart (V4HImode, operands[0]);
5800  operands[1] = gen_lowpart (V8QImode, operands[1]);
5801})
5802
5803(define_insn "*unpkbw"
5804  [(set (match_operand:V4HI 0 "register_operand" "=r")
5805	(zero_extend:V4HI
5806	  (vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
5807			   (parallel [(const_int 0)
5808				      (const_int 1)
5809				      (const_int 2)
5810				      (const_int 3)]))))]
5811  "TARGET_MAX"
5812  "unpkbw %r1,%0"
5813  [(set_attr "type" "mvi")])
5814
5815(include "sync.md")
5816
5817;; The call patterns are at the end of the file because their
5818;; wildcard operand0 interferes with nice recognition.
5819
5820(define_insn "*call_value_osf_1_er_noreturn"
5821  [(set (match_operand 0)
5822	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5823	      (match_operand 2)))
5824   (use (reg:DI 29))
5825   (clobber (reg:DI 26))]
5826  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
5827   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5828  "@
5829   jsr $26,($27),0
5830   bsr $26,%1\t\t!samegp
5831   ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#"
5832  [(set_attr "type" "jsr")
5833   (set_attr "length" "*,*,8")])
5834
5835(define_insn "*call_value_osf_1_er"
5836  [(set (match_operand 0)
5837	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5838	      (match_operand 2)))
5839   (use (reg:DI 29))
5840   (clobber (reg:DI 26))]
5841  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5842  "@
5843   jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
5844   bsr $26,%1\t\t!samegp
5845   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!%*"
5846  [(set_attr "type" "jsr")
5847   (set_attr "length" "12,*,16")])
5848
5849;; We must use peep2 instead of a split because we need accurate life
5850;; information for $gp.  Consider the case of { bar(); while (1); }.
5851(define_peephole2
5852  [(parallel [(set (match_operand 0)
5853		   (call (mem:DI (match_operand:DI 1 "call_operand"))
5854		         (match_operand 2)))
5855	      (use (reg:DI 29))
5856	      (clobber (reg:DI 26))])]
5857  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
5858   && ! samegp_function_operand (operands[1], Pmode)
5859   && (peep2_regno_dead_p (1, 29)
5860       || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
5861  [(parallel [(set (match_dup 0)
5862		   (call (mem:DI (match_dup 3))
5863			 (match_dup 2)))
5864	      (use (reg:DI 29))
5865	      (use (match_dup 1))
5866	      (use (match_dup 4))
5867	      (clobber (reg:DI 26))])]
5868{
5869  if (CONSTANT_P (operands[1]))
5870    {
5871      operands[3] = gen_rtx_REG (Pmode, 27);
5872      operands[4] = GEN_INT (alpha_next_sequence_number++);
5873      emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
5874				      operands[1], operands[4]));
5875    }
5876  else
5877    {
5878      operands[3] = operands[1];
5879      operands[1] = const0_rtx;
5880      operands[4] = const0_rtx;
5881    }
5882})
5883
5884(define_peephole2
5885  [(parallel [(set (match_operand 0)
5886		   (call (mem:DI (match_operand:DI 1 "call_operand"))
5887		         (match_operand 2)))
5888	      (use (reg:DI 29))
5889	      (clobber (reg:DI 26))])]
5890  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
5891   && ! samegp_function_operand (operands[1], Pmode)
5892   && ! (peep2_regno_dead_p (1, 29)
5893         || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
5894  [(parallel [(set (match_dup 0)
5895		   (call (mem:DI (match_dup 3))
5896			 (match_dup 2)))
5897	      (set (match_dup 6)
5898		   (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1))
5899	      (use (match_dup 1))
5900	      (use (match_dup 5))
5901	      (clobber (reg:DI 26))])
5902   (set (match_dup 6)
5903	(unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))]
5904{
5905  if (CONSTANT_P (operands[1]))
5906    {
5907      operands[3] = gen_rtx_REG (Pmode, 27);
5908      operands[5] = GEN_INT (alpha_next_sequence_number++);
5909      emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
5910				      operands[1], operands[5]));
5911    }
5912  else
5913    {
5914      operands[3] = operands[1];
5915      operands[1] = const0_rtx;
5916      operands[5] = const0_rtx;
5917    }
5918  operands[4] = GEN_INT (alpha_next_sequence_number++);
5919  operands[6] = pic_offset_table_rtx;
5920})
5921
5922(define_insn "*call_value_osf_2_er_nogp"
5923  [(set (match_operand 0)
5924	(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
5925	      (match_operand 2)))
5926   (use (reg:DI 29))
5927   (use (match_operand 3))
5928   (use (match_operand 4))
5929   (clobber (reg:DI 26))]
5930  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5931  "jsr $26,(%1),%3%J4"
5932  [(set_attr "type" "jsr")])
5933
5934(define_insn "*call_value_osf_2_er"
5935  [(set (match_operand 0)
5936	(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
5937	      (match_operand 2)))
5938   (set (reg:DI 29)
5939	(unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand")]
5940		   UNSPEC_LDGP1))
5941   (use (match_operand 3))
5942   (use (match_operand 4))
5943   (clobber (reg:DI 26))]
5944  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5945  "jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
5946  [(set_attr "type" "jsr")
5947   (set_attr "cannot_copy" "true")
5948   (set_attr "length" "8")])
5949
5950(define_insn "*call_value_osf_1_noreturn"
5951  [(set (match_operand 0)
5952	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5953	      (match_operand 2)))
5954   (use (reg:DI 29))
5955   (clobber (reg:DI 26))]
5956  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
5957   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5958  "@
5959   jsr $26,($27),0
5960   bsr $26,$%1..ng
5961   jsr $26,%1"
5962  [(set_attr "type" "jsr")
5963   (set_attr "length" "*,*,8")])
5964
5965(define_int_iterator TLS_CALL
5966	[UNSPEC_TLSGD_CALL
5967	 UNSPEC_TLSLDM_CALL])
5968
5969(define_int_attr tls
5970	[(UNSPEC_TLSGD_CALL "tlsgd")
5971	 (UNSPEC_TLSLDM_CALL "tlsldm")])
5972
5973(define_insn "call_value_osf_<tls>"
5974  [(set (match_operand 0)
5975	(call (mem:DI (match_operand:DI 1 "symbolic_operand"))
5976	      (const_int 0)))
5977   (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
5978   (use (reg:DI 29))
5979   (clobber (reg:DI 26))]
5980  "HAVE_AS_TLS"
5981  "ldq $27,%1($29)\t\t!literal!%2\;jsr $26,($27),%1\t\t!lituse_<tls>!%2\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
5982  [(set_attr "type" "jsr")
5983   (set_attr "length" "16")])
5984
5985;; We must use peep2 instead of a split because we need accurate life
5986;; information for $gp.
5987(define_peephole2
5988  [(parallel
5989    [(set (match_operand 0)
5990	  (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
5991		(const_int 0)))
5992     (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
5993     (use (reg:DI 29))
5994     (clobber (reg:DI 26))])]
5995  "HAVE_AS_TLS && reload_completed
5996   && peep2_regno_dead_p (1, 29)"
5997  [(set (match_dup 3)
5998	(unspec:DI [(match_dup 5)
5999		    (match_dup 1)
6000		    (match_dup 2)] UNSPEC_LITERAL))
6001   (parallel [(set (match_dup 0)
6002		   (call (mem:DI (match_dup 3))
6003			 (const_int 0)))
6004	      (use (match_dup 5))
6005	      (use (match_dup 1))
6006	      (use (unspec [(match_dup 2)] TLS_CALL))
6007	      (clobber (reg:DI 26))])
6008   (set (match_dup 5)
6009	(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
6010{
6011  operands[3] = gen_rtx_REG (Pmode, 27);
6012  operands[4] = GEN_INT (alpha_next_sequence_number++);
6013  operands[5] = pic_offset_table_rtx;
6014})
6015
6016(define_peephole2
6017  [(parallel
6018    [(set (match_operand 0)
6019	  (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
6020		(const_int 0)))
6021     (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
6022     (use (reg:DI 29))
6023     (clobber (reg:DI 26))])]
6024  "HAVE_AS_TLS && reload_completed
6025   && !peep2_regno_dead_p (1, 29)"
6026  [(set (match_dup 3)
6027	(unspec:DI [(match_dup 5)
6028		    (match_dup 1)
6029		    (match_dup 2)] UNSPEC_LITERAL))
6030   (parallel [(set (match_dup 0)
6031		   (call (mem:DI (match_dup 3))
6032			 (const_int 0)))
6033	      (set (match_dup 5)
6034		   (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
6035	      (use (match_dup 1))
6036	      (use (unspec [(match_dup 2)] TLS_CALL))
6037	      (clobber (reg:DI 26))])
6038   (set (match_dup 5)
6039	(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
6040{
6041  operands[3] = gen_rtx_REG (Pmode, 27);
6042  operands[4] = GEN_INT (alpha_next_sequence_number++);
6043  operands[5] = pic_offset_table_rtx;
6044})
6045
6046(define_insn "*call_value_osf_1"
6047  [(set (match_operand 0)
6048	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6049	      (match_operand 2)))
6050   (use (reg:DI 29))
6051   (clobber (reg:DI 26))]
6052  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6053  "@
6054   jsr $26,($27),0\;ldgp $29,0($26)
6055   bsr $26,$%1..ng
6056   jsr $26,%1\;ldgp $29,0($26)"
6057  [(set_attr "type" "jsr")
6058   (set_attr "length" "12,*,16")])
6059
6060(define_insn "*sibcall_value_osf_1_er"
6061  [(set (match_operand 0)
6062	(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
6063	      (match_operand 2)))
6064   (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
6065  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6066  "@
6067   br $31,%1\t\t!samegp
6068   ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
6069  [(set_attr "type" "jsr")
6070   (set_attr "length" "*,8")])
6071
6072(define_insn "*sibcall_value_osf_1"
6073  [(set (match_operand 0)
6074	(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
6075	      (match_operand 2)))
6076   (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
6077  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6078  "@
6079   br $31,$%1..ng
6080   lda $27,%1\;jmp $31,($27),%1"
6081  [(set_attr "type" "jsr")
6082   (set_attr "length" "*,8")])
6083
6084; GAS relies on the order and position of instructions output below in order
6085; to generate relocs for VMS link to potentially optimize the call.
6086; Please do not molest.
6087(define_insn "*call_value_vms_1"
6088  [(set (match_operand 0)
6089	(call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
6090	      (match_operand 2)))
6091   (use (match_operand:DI 3 "nonmemory_operand" "r,n"))
6092   (use (reg:DI 25))
6093   (use (reg:DI 26))
6094   (clobber (reg:DI 27))]
6095  "TARGET_ABI_OPEN_VMS"
6096{
6097  switch (which_alternative)
6098    {
6099    case 0:
6100   	return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
6101    case 1:
6102	operands [3] = alpha_use_linkage (operands [1], true, false);
6103	operands [4] = alpha_use_linkage (operands [1], false, false);
6104   	return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
6105    default:
6106      gcc_unreachable ();
6107    }
6108}
6109  [(set_attr "type" "jsr")
6110   (set_attr "length" "12,16")])
6111