OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [alpha/] [alpha.md] - Blame information for rev 154

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

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

powered by: WebSVN 2.1.0

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