OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc2/] [gcc/] [config/] [alpha/] [alpha.md] - Blame information for rev 437

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.