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