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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [alpha/] [alpha.md] - Blame information for rev 709

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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