]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/alpha/alpha.md
Merge in gcc2-ss-010999
[thirdparty/gcc.git] / gcc / config / alpha / alpha.md
CommitLineData
1c2bdc60 1;; Machine description for DEC Alpha for GNU C compiler
34627ce6 2;; Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
1c2bdc60 3;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
36f8f642
RK
4
5;; This file is part of GNU CC.
6
7;; GNU CC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; GNU CC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU CC; see the file COPYING. If not, write to
c15c9075
RK
19;; the Free Software Foundation, 59 Temple Place - Suite 330,
20;; Boston, MA 02111-1307, USA.
36f8f642
RK
21
22;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
4ed43ff8
RH
23
24;; Uses of UNSPEC in this file:
25;;
26;; 0 arg_home
27;; 1 cttz
28;; 2 insxh
29;; 3 mskxh
30;; 4 cvtlq
e83015a9 31;; 5 cvtql
37679e06 32;; 6 nt_lda
4ed43ff8
RH
33;;
34;; UNSPEC_VOLATILE:
35;;
36;; 0 imb
37;; 1 blockage
38;; 2 builtin_setjmp_receiver
39;; 3 builtin_longjmp
40;; 4 trapb
9c0e94a5 41;; 5 prologue_stack_probe_loop
68aed21b 42;; 6 realign
6abc6f40 43;; 7 exception_receiver
36f8f642 44\f
745466f2
RK
45;; Processor type -- this attribute must exactly match the processor_type
46;; enumeration in alpha.h.
47
71d9b493 48(define_attr "cpu" "ev4,ev5,ev6"
745466f2
RK
49 (const (symbol_ref "alpha_cpu")))
50
36f8f642
RK
51;; Define an insn type attribute. This is used in function unit delay
52;; computations, among other purposes. For the most part, we use the names
53;; defined in the EV4 documentation, but add a few that we have to know about
54;; separately.
55
56(define_attr "type"
68aed21b 57 "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
745466f2 58 (const_string "iadd"))
36f8f642 59
68aed21b
RH
60;; Describe a user's asm statement.
61(define_asm_attributes
62 [(set_attr "type" "multi")])
63
9c0e94a5
RH
64;; Define the operand size an insn operates on. Used primarily by mul
65;; and div operations that have size dependant timings.
66
71d9b493
RH
67(define_attr "opsize" "si,di,udi" (const_string "di"))
68
0d4ae18a 69;; The TRAP_TYPE attribute marks instructions that may generate traps
956d6950 70;; (which are imprecise and may need a trapb if software completion
0d4ae18a 71;; is desired).
9c0e94a5 72
f4e31cf5 73(define_attr "trap" "no,yes" (const_string "no"))
0d4ae18a 74
9c0e94a5
RH
75;; The length of an instruction sequence in bytes.
76
77(define_attr "length" "" (const_int 4))
71d9b493
RH
78\f
79;; On EV4 there are two classes of resources to consider: resources needed
80;; to issue, and resources needed to execute. IBUS[01] are in the first
81;; category. ABOX, BBOX, EBOX, FBOX, IMUL & FDIV make up the second.
38e01259 82;; (There are a few other register-like resources, but ...)
71d9b493
RH
83
84; First, describe all of the issue constraints with single cycle delays.
85; All insns need a bus, but all except loads require one or the other.
86(define_function_unit "ev4_ibus0" 1 0
87 (and (eq_attr "cpu" "ev4")
88 (eq_attr "type" "fst,fbr,iadd,imul,ilog,shift,icmov,icmp"))
89 1 1)
90
91(define_function_unit "ev4_ibus1" 1 0
92 (and (eq_attr "cpu" "ev4")
93 (eq_attr "type" "ist,ibr,jsr,fadd,fcmov,fcpys,fmul,fdiv,misc"))
94 1 1)
36f8f642 95
71d9b493
RH
96; Memory delivers its result in three cycles. Actually return one and
97; take care of this in adjust_cost, since we want to handle user-defined
98; memory latencies.
745466f2
RK
99(define_function_unit "ev4_abox" 1 0
100 (and (eq_attr "cpu" "ev4")
71d9b493 101 (eq_attr "type" "ild,fld,ldsym,ist,fst"))
bcbbac26 102 1 1)
36f8f642 103
71d9b493 104; Branches have no delay cost, but do tie up the unit for two cycles.
745466f2
RK
105(define_function_unit "ev4_bbox" 1 1
106 (and (eq_attr "cpu" "ev4")
107 (eq_attr "type" "ibr,fbr,jsr"))
74835ed8 108 2 2)
36f8f642 109
71d9b493
RH
110; Arithmetic insns are normally have their results available after
111; two cycles. There are a number of exceptions. They are encoded in
112; ADJUST_COST. Some of the other insns have similar exceptions.
745466f2
RK
113(define_function_unit "ev4_ebox" 1 0
114 (and (eq_attr "cpu" "ev4")
71d9b493 115 (eq_attr "type" "iadd,ilog,shift,icmov,icmp,misc"))
74835ed8 116 2 1)
36f8f642 117
71d9b493 118(define_function_unit "imul" 1 0
745466f2 119 (and (eq_attr "cpu" "ev4")
71d9b493
RH
120 (and (eq_attr "type" "imul")
121 (eq_attr "opsize" "si")))
74835ed8 122 21 19)
745466f2 123
71d9b493 124(define_function_unit "imul" 1 0
745466f2 125 (and (eq_attr "cpu" "ev4")
71d9b493
RH
126 (and (eq_attr "type" "imul")
127 (eq_attr "opsize" "!si")))
74835ed8 128 23 21)
745466f2
RK
129
130(define_function_unit "ev4_fbox" 1 0
131 (and (eq_attr "cpu" "ev4")
71d9b493 132 (eq_attr "type" "fadd,fmul,fcpys,fcmov"))
74835ed8 133 6 1)
745466f2 134
71d9b493 135(define_function_unit "fdiv" 1 0
745466f2 136 (and (eq_attr "cpu" "ev4")
71d9b493
RH
137 (and (eq_attr "type" "fdiv")
138 (eq_attr "opsize" "si")))
74835ed8 139 34 30)
745466f2 140
71d9b493 141(define_function_unit "fdiv" 1 0
745466f2 142 (and (eq_attr "cpu" "ev4")
71d9b493
RH
143 (and (eq_attr "type" "fdiv")
144 (eq_attr "opsize" "di")))
145 63 59)
745466f2
RK
146\f
147;; EV5 scheduling. EV5 can issue 4 insns per clock.
71d9b493
RH
148;;
149;; EV5 has two asymetric integer units. Model this with E0 & E1 along
150;; with the combined resource EBOX.
74835ed8 151
745466f2 152(define_function_unit "ev5_ebox" 2 0
26250081 153 (and (eq_attr "cpu" "ev5")
71d9b493 154 (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv"))
74835ed8 155 1 1)
745466f2 156
71d9b493
RH
157; Memory takes at least 2 clocks. Return one from here and fix up with
158; user-defined latencies in adjust_cost.
745466f2 159(define_function_unit "ev5_ebox" 2 0
26250081 160 (and (eq_attr "cpu" "ev5")
71d9b493 161 (eq_attr "type" "ild,fld,ldsym"))
bcbbac26 162 1 1)
745466f2 163
827e80cc
RH
164; Loads can dual issue with one another, but loads and stores do not mix.
165(define_function_unit "ev5_e0" 1 0
166 (and (eq_attr "cpu" "ev5")
167 (eq_attr "type" "ild,fld,ldsym"))
168 1 1
169 [(eq_attr "type" "ist,fst")])
170
71d9b493 171; Stores, shifts, multiplies can only issue to E0
74835ed8 172(define_function_unit "ev5_e0" 1 0
26250081 173 (and (eq_attr "cpu" "ev5")
71d9b493 174 (eq_attr "type" "ist,fst,shift,imul"))
74835ed8 175 1 1)
745466f2 176
71d9b493 177; Motion video insns also issue only to E0, and take two ticks.
26250081
RH
178(define_function_unit "ev5_e0" 1 0
179 (and (eq_attr "cpu" "ev5")
180 (eq_attr "type" "mvi"))
181 2 1)
182
71d9b493
RH
183; Conditional moves always take 2 ticks.
184(define_function_unit "ev5_ebox" 2 0
26250081 185 (and (eq_attr "cpu" "ev5")
71d9b493
RH
186 (eq_attr "type" "icmov"))
187 2 1)
745466f2 188
71d9b493 189; Branches can only issue to E1
74835ed8 190(define_function_unit "ev5_e1" 1 0
26250081 191 (and (eq_attr "cpu" "ev5")
74835ed8
RH
192 (eq_attr "type" "ibr,jsr"))
193 1 1)
745466f2 194
71d9b493
RH
195; Multiplies also use the integer multiplier.
196; ??? How to: "No instruction can be issued to pipe E0 exactly two
197; cycles before an integer multiplication completes."
198(define_function_unit "imul" 1 0
26250081 199 (and (eq_attr "cpu" "ev5")
71d9b493
RH
200 (and (eq_attr "type" "imul")
201 (eq_attr "opsize" "si")))
74835ed8 202 8 4)
745466f2 203
71d9b493 204(define_function_unit "imul" 1 0
26250081 205 (and (eq_attr "cpu" "ev5")
71d9b493
RH
206 (and (eq_attr "type" "imul")
207 (eq_attr "opsize" "di")))
74835ed8 208 12 8)
745466f2 209
71d9b493 210(define_function_unit "imul" 1 0
26250081 211 (and (eq_attr "cpu" "ev5")
71d9b493
RH
212 (and (eq_attr "type" "imul")
213 (eq_attr "opsize" "udi")))
74835ed8
RH
214 14 8)
215
216;; Similarly for the FPU we have two asymetric units. But fcpys can issue
217;; on either so we have to play the game again.
745466f2 218
71d9b493 219(define_function_unit "ev5_fbox" 2 0
26250081 220 (and (eq_attr "cpu" "ev5")
71d9b493 221 (eq_attr "type" "fadd,fcmov,fmul,fcpys,fbr,fdiv"))
74835ed8 222 4 1)
745466f2 223
74835ed8 224(define_function_unit "ev5_fm" 1 0
26250081 225 (and (eq_attr "cpu" "ev5")
745466f2 226 (eq_attr "type" "fmul"))
74835ed8 227 4 1)
745466f2 228
71d9b493
RH
229; Add and cmov as you would expect; fbr never produces a result;
230; fdiv issues through fa to the divider,
74835ed8 231(define_function_unit "ev5_fa" 1 0
26250081 232 (and (eq_attr "cpu" "ev5")
71d9b493 233 (eq_attr "type" "fadd,fcmov,fbr,fdiv"))
74835ed8 234 4 1)
745466f2 235
71d9b493
RH
236; ??? How to: "No instruction can be issued to pipe FA exactly five
237; cycles before a floating point divide completes."
238(define_function_unit "fdiv" 1 0
26250081 239 (and (eq_attr "cpu" "ev5")
71d9b493
RH
240 (and (eq_attr "type" "fdiv")
241 (eq_attr "opsize" "si")))
242 15 15) ; 15 to 31 data dependant
745466f2 243
71d9b493 244(define_function_unit "fdiv" 1 0
26250081 245 (and (eq_attr "cpu" "ev5")
71d9b493
RH
246 (and (eq_attr "type" "fdiv")
247 (eq_attr "opsize" "di")))
248 22 22) ; 22 to 60 data dependant
249\f
250;; EV6 scheduling. EV6 can issue 4 insns per clock.
251;;
252;; EV6 has two symmetric pairs ("clusters") of two asymetric integer units
253;; ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
254
255;; Conditional moves decompose into two independant primitives, each
256;; taking one cycle. Since ev6 is out-of-order, we can't see anything
257;; but two cycles.
258(define_function_unit "ev6_ebox" 4 0
259 (and (eq_attr "cpu" "ev6")
260 (eq_attr "type" "icmov"))
261 2 1)
262
263(define_function_unit "ev6_ebox" 4 0
264 (and (eq_attr "cpu" "ev6")
265 (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv,fsqrt"))
266 1 1)
267
268;; Integer loads take at least 3 clocks, and only issue to lower units.
269;; Return one from here and fix up with user-defined latencies in adjust_cost.
270(define_function_unit "ev6_l" 2 0
271 (and (eq_attr "cpu" "ev6")
272 (eq_attr "type" "ild,ldsym,ist,fst"))
273 1 1)
274
275;; FP loads take at least 4 clocks. Return two from here...
276(define_function_unit "ev6_l" 2 0
277 (and (eq_attr "cpu" "ev6")
278 (eq_attr "type" "fld"))
279 2 1)
280
281;; Motion video insns also issue only to U0, and take three ticks.
282(define_function_unit "ev6_u0" 1 0
283 (and (eq_attr "cpu" "ev6")
284 (eq_attr "type" "mvi"))
285 3 1)
286
287(define_function_unit "ev6_u" 2 0
288 (and (eq_attr "cpu" "ev6")
289 (eq_attr "type" "mvi"))
290 3 1)
291
292;; Shifts issue to either upper pipe.
293(define_function_unit "ev6_u" 2 0
294 (and (eq_attr "cpu" "ev6")
295 (eq_attr "type" "shift"))
296 1 1)
297
298;; Multiplies issue only to U1, and all take 7 ticks.
299;; Rather than create a new function unit just for U1, reuse IMUL
300(define_function_unit "imul" 1 0
301 (and (eq_attr "cpu" "ev6")
302 (eq_attr "type" "imul"))
303 7 1)
304
305(define_function_unit "ev6_u" 2 0
306 (and (eq_attr "cpu" "ev6")
307 (eq_attr "type" "imul"))
308 7 1)
309
310;; Branches issue to either upper pipe
311(define_function_unit "ev6_u" 2 0
312 (and (eq_attr "cpu" "ev6")
313 (eq_attr "type" "ibr"))
314 3 1)
315
316;; Calls only issue to L0.
317(define_function_unit "ev6_l0" 1 0
318 (and (eq_attr "cpu" "ev6")
319 (eq_attr "type" "jsr"))
320 1 1)
321
322(define_function_unit "ev6_l" 2 0
323 (and (eq_attr "cpu" "ev6")
324 (eq_attr "type" "jsr"))
325 1 1)
326
327;; Ftoi/itof only issue to lower pipes
328(define_function_unit "ev6_l" 2 0
329 (and (eq_attr "cpu" "ev6")
330 (eq_attr "type" "ftoi"))
331 3 1)
332
333(define_function_unit "ev6_l" 2 0
334 (and (eq_attr "cpu" "ev6")
335 (eq_attr "type" "itof"))
336 4 1)
337
338;; For the FPU we are very similar to EV5, except there's no insn that
339;; can issue to fm & fa, so we get to leave that out.
340
341(define_function_unit "ev6_fm" 1 0
342 (and (eq_attr "cpu" "ev6")
343 (eq_attr "type" "fmul"))
344 4 1)
345
346(define_function_unit "ev6_fa" 1 0
347 (and (eq_attr "cpu" "ev6")
348 (eq_attr "type" "fadd,fcpys,fbr,fdiv,fsqrt"))
349 4 1)
350
351(define_function_unit "ev6_fa" 1 0
352 (and (eq_attr "cpu" "ev6")
353 (eq_attr "type" "fcmov"))
354 8 1)
355
356(define_function_unit "fdiv" 1 0
357 (and (eq_attr "cpu" "ev6")
358 (and (eq_attr "type" "fdiv")
359 (eq_attr "opsize" "si")))
360 12 10)
361
362(define_function_unit "fdiv" 1 0
363 (and (eq_attr "cpu" "ev6")
364 (and (eq_attr "type" "fdiv")
365 (eq_attr "opsize" "di")))
366 15 13)
367
368(define_function_unit "fsqrt" 1 0
369 (and (eq_attr "cpu" "ev6")
370 (and (eq_attr "type" "fsqrt")
371 (eq_attr "opsize" "si")))
372 16 14)
373
374(define_function_unit "fsqrt" 1 0
375 (and (eq_attr "cpu" "ev6")
376 (and (eq_attr "type" "fsqrt")
377 (eq_attr "opsize" "di")))
378 32 30)
379
380; ??? The FPU communicates with memory and the integer register file
381; via two fp store units. We need a slot in the fst immediately, and
382; a slot in LOW after the operand data is ready. At which point the
4ed43ff8 383; data may be moved either to the store queue or the integer register
71d9b493 384; file and the insn retired.
745466f2 385
36f8f642
RK
386\f
387;; First define the arithmetic insns. Note that the 32-bit forms also
388;; sign-extend.
389
4ed43ff8
RH
390;; Handle 32-64 bit extension from memory to a floating point register
391;; specially, since this ocurrs frequently in int->double conversions.
392;; This is done with a define_split after reload converting the plain
393;; sign-extension into a load+unspec, which of course results in lds+cvtlq.
394;;
395;; Note that while we must retain the =f case in the insn for reload's
396;; benefit, it should be eliminated after reload, so we should never emit
397;; code for that case. But we don't reject the possibility.
398
36f8f642 399(define_insn "extendsidi2"
4ed43ff8
RH
400 [(set (match_operand:DI 0 "register_operand" "=r,r,?f")
401 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
36f8f642
RK
402 ""
403 "@
404 addl %1,$31,%0
405 ldl %0,%1
4ed43ff8 406 lds %0,%1\;cvtlq %0,%0"
9c0e94a5
RH
407 [(set_attr "type" "iadd,ild,fld")
408 (set_attr "length" "*,*,8")])
4ed43ff8
RH
409
410;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
411(define_split
412 [(set (match_operand:DI 0 "hard_fp_register_operand" "")
413 (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
414 "reload_completed"
415 [(set (match_dup 2) (match_dup 1))
416 (set (match_dup 0) (unspec:DI [(match_dup 2)] 4))]
417 "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
418
419(define_insn ""
420 [(set (match_operand:DI 0 "register_operand" "=f")
421 (unspec:DI [(match_operand:SI 1 "register_operand" "f")] 4))]
422 ""
423 "cvtlq %1,%0"
424 [(set_attr "type" "fadd")])
36f8f642 425
c9325fd6
RK
426;; Do addsi3 the way expand_binop would do if we didn't have one. This
427;; generates better code. We have the anonymous addsi3 pattern below in
428;; case combine wants to make it.
429(define_expand "addsi3"
430 [(set (match_operand:SI 0 "register_operand" "")
431 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
432 (match_operand:SI 2 "add_operand" "")))]
433 ""
434 "
8f5d6855 435{
bd8dc165 436 if (optimize)
6c61c2bb 437 {
bd8dc165
RH
438 rtx op1 = gen_lowpart (DImode, operands[1]);
439 rtx op2 = gen_lowpart (DImode, operands[2]);
440
441 if (! cse_not_expected)
442 {
443 rtx tmp = gen_reg_rtx (DImode);
444 emit_insn (gen_adddi3 (tmp, op1, op2));
445 emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
446 }
447 else
448 emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
449 DONE;
6c61c2bb 450 }
bd8dc165 451}")
c9325fd6
RK
452
453(define_insn ""
26958509 454 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
55ff92b8 455 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
26958509 456 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
36f8f642
RK
457 ""
458 "@
459 addl %r1,%2,%0
26958509 460 subl %r1,%n2,%0
36f8f642 461 lda %0,%2(%r1)
745466f2 462 ldah %0,%h2(%r1)")
36f8f642
RK
463
464(define_split
465 [(set (match_operand:SI 0 "register_operand" "")
466 (plus:SI (match_operand:SI 1 "register_operand" "")
467 (match_operand:SI 2 "const_int_operand" "")))]
468 "! add_operand (operands[2], SImode)"
469 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
470 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
471 "
472{
473 HOST_WIDE_INT val = INTVAL (operands[2]);
474 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
475 HOST_WIDE_INT rest = val - low;
476
477 operands[3] = GEN_INT (rest);
478 operands[4] = GEN_INT (low);
479}")
480
481(define_insn ""
482 [(set (match_operand:DI 0 "register_operand" "=r,r")
483 (sign_extend:DI
484 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
485 (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
486 ""
487 "@
488 addl %r1,%2,%0
745466f2 489 subl %r1,%n2,%0")
36f8f642 490
9cea6503
RK
491(define_split
492 [(set (match_operand:DI 0 "register_operand" "")
493 (sign_extend:DI
c5c76735 494 (plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
9cea6503 495 (match_operand:SI 2 "const_int_operand" ""))))
40b80dad 496 (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
26958509 497 "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
9cea6503
RK
498 && INTVAL (operands[2]) % 4 == 0"
499 [(set (match_dup 3) (match_dup 4))
500 (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
501 (match_dup 5))
502 (match_dup 1))))]
503 "
504{
505 HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
506 int mult = 4;
507
508 if (val % 2 == 0)
509 val /= 2, mult = 8;
510
511 operands[4] = GEN_INT (val);
512 operands[5] = GEN_INT (mult);
513}")
514
5c72c15e
RK
515(define_split
516 [(set (match_operand:DI 0 "register_operand" "")
517 (sign_extend:DI
518 (plus:SI (match_operator:SI 1 "comparison_operator"
519 [(match_operand 2 "" "")
520 (match_operand 3 "" "")])
521 (match_operand:SI 4 "add_operand" ""))))
522 (clobber (match_operand:DI 5 "register_operand" ""))]
523 ""
524 [(set (match_dup 5) (match_dup 6))
525 (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
526 "
527{
38a448ca
RH
528 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
529 operands[2], operands[3]);
5c72c15e
RK
530 operands[7] = gen_lowpart (SImode, operands[5]);
531}")
532
36f8f642 533(define_insn "adddi3"
26958509 534 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
55ff92b8 535 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
26958509 536 (match_operand:DI 2 "add_operand" "rI,O,K,L")))]
36f8f642 537 ""
f9d7e5cd
RH
538 "*
539{
540 const char * const pattern[4] = {
541 \"addq %r1,%2,%0\",
542 \"subq %r1,%n2,%0\",
543 \"lda %0,%2(%r1)\",
544 \"ldah %0,%h2(%r1)\"
545 };
546
547 /* The NT stack unwind code can't handle a subq to adjust the stack
548 (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
549 the exception handling code will loop if a subq is used and an
550 exception occurs.
551
552 The 19980616 change to emit prologues as RTL also confused some
553 versions of GDB, which also interprets prologues. This has been
554 fixed as of GDB 4.18, but it does not harm to unconditionally
555 use lda here. */
556
557 int which = which_alternative;
558
559 if (operands[0] == stack_pointer_rtx
560 && GET_CODE (operands[2]) == CONST_INT
561 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))
562 which = 2;
563
564 return pattern[which];
565}")
36f8f642 566
5d02b6c2
RH
567;; ??? Allow large constants when basing off the frame pointer or some
568;; virtual register that may eliminate to the frame pointer. This is
569;; done because register elimination offsets will change the hi/lo split,
570;; and if we split before reload, we will require additional instructions.
571
572(define_insn ""
573 [(set (match_operand:DI 0 "register_operand" "=r")
574 (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
575 (match_operand:DI 2 "const_int_operand" "n")))]
576 "REG_OK_FP_BASE_P (operands[1])"
577 "#")
578
579;; Don't do this if we are adjusting SP since we don't want to do it
580;; in two steps. Don't split FP sources for the reason listed above.
36f8f642
RK
581(define_split
582 [(set (match_operand:DI 0 "register_operand" "")
583 (plus:DI (match_operand:DI 1 "register_operand" "")
584 (match_operand:DI 2 "const_int_operand" "")))]
26958509 585 "! add_operand (operands[2], DImode)
5d02b6c2
RH
586 && operands[0] != stack_pointer_rtx
587 && operands[1] != frame_pointer_rtx
588 && operands[1] != arg_pointer_rtx"
36f8f642
RK
589 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
590 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
591 "
592{
593 HOST_WIDE_INT val = INTVAL (operands[2]);
594 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
595 HOST_WIDE_INT rest = val - low;
596
597 operands[3] = GEN_INT (rest);
598 operands[4] = GEN_INT (low);
599}")
600
601(define_insn ""
26958509 602 [(set (match_operand:SI 0 "register_operand" "=r,r")
40b80dad 603 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
26958509
RK
604 (match_operand:SI 2 "const48_operand" "I,I"))
605 (match_operand:SI 3 "sext_add_operand" "rI,O")))]
36f8f642 606 ""
26958509 607 "@
40b80dad
RH
608 s%2addl %1,%3,%0
609 s%2subl %1,%n3,%0")
36f8f642
RK
610
611(define_insn ""
26958509 612 [(set (match_operand:DI 0 "register_operand" "=r,r")
36f8f642 613 (sign_extend:DI
40b80dad 614 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
26958509
RK
615 (match_operand:SI 2 "const48_operand" "I,I"))
616 (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
36f8f642 617 ""
26958509 618 "@
40b80dad
RH
619 s%2addl %1,%3,%0
620 s%2subl %1,%n3,%0")
36f8f642 621
d0c84fda
RK
622(define_split
623 [(set (match_operand:DI 0 "register_operand" "")
624 (sign_extend:DI
625 (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
626 [(match_operand 2 "" "")
627 (match_operand 3 "" "")])
628 (match_operand:SI 4 "const48_operand" ""))
c5c76735 629 (match_operand:SI 5 "sext_add_operand" ""))))
40b80dad 630 (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
d0c84fda
RK
631 ""
632 [(set (match_dup 6) (match_dup 7))
633 (set (match_dup 0)
634 (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
635 (match_dup 5))))]
636 "
637{
38a448ca
RH
638 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
639 operands[2], operands[3]);
d0c84fda
RK
640 operands[8] = gen_lowpart (SImode, operands[6]);
641}")
642
36f8f642 643(define_insn ""
26958509 644 [(set (match_operand:DI 0 "register_operand" "=r,r")
40b80dad 645 (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
26958509 646 (match_operand:DI 2 "const48_operand" "I,I"))
80df65c9 647 (match_operand:DI 3 "sext_add_operand" "rI,O")))]
36f8f642 648 ""
26958509 649 "@
40b80dad 650 s%2addq %1,%3,%0
745466f2 651 s%2subq %1,%n3,%0")
36f8f642 652
36f8f642
RK
653(define_insn "negsi2"
654 [(set (match_operand:SI 0 "register_operand" "=r")
655 (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
656 ""
745466f2 657 "subl $31,%1,%0")
36f8f642
RK
658
659(define_insn ""
660 [(set (match_operand:DI 0 "register_operand" "=r")
661 (sign_extend:DI (neg:SI
662 (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
663 ""
745466f2 664 "subl $31,%1,%0")
36f8f642
RK
665
666(define_insn "negdi2"
667 [(set (match_operand:DI 0 "register_operand" "=r")
668 (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
669 ""
745466f2 670 "subq $31,%1,%0")
36f8f642 671
c9325fd6
RK
672(define_expand "subsi3"
673 [(set (match_operand:SI 0 "register_operand" "")
674 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
675 (match_operand:SI 2 "reg_or_8bit_operand" "")))]
676 ""
677 "
8f5d6855 678{
bd8dc165 679 if (optimize)
6c61c2bb 680 {
bd8dc165
RH
681 rtx op1 = gen_lowpart (DImode, operands[1]);
682 rtx op2 = gen_lowpart (DImode, operands[2]);
683
684 if (! cse_not_expected)
685 {
686 rtx tmp = gen_reg_rtx (DImode);
687 emit_insn (gen_subdi3 (tmp, op1, op2));
688 emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
689 }
690 else
691 emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
692 DONE;
6c61c2bb 693 }
c9325fd6
RK
694} ")
695
696(define_insn ""
36f8f642
RK
697 [(set (match_operand:SI 0 "register_operand" "=r")
698 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
699 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
700 ""
745466f2 701 "subl %r1,%2,%0")
36f8f642
RK
702
703(define_insn ""
704 [(set (match_operand:DI 0 "register_operand" "=r")
705 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
706 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
707 ""
745466f2 708 "subl %r1,%2,%0")
36f8f642
RK
709
710(define_insn "subdi3"
711 [(set (match_operand:DI 0 "register_operand" "=r")
712 (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
713 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
714 ""
745466f2 715 "subq %r1,%2,%0")
36f8f642
RK
716
717(define_insn ""
718 [(set (match_operand:SI 0 "register_operand" "=r")
40b80dad 719 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
36f8f642
RK
720 (match_operand:SI 2 "const48_operand" "I"))
721 (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
722 ""
40b80dad 723 "s%2subl %1,%3,%0")
36f8f642
RK
724
725(define_insn ""
726 [(set (match_operand:DI 0 "register_operand" "=r")
727 (sign_extend:DI
40b80dad 728 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
36f8f642
RK
729 (match_operand:SI 2 "const48_operand" "I"))
730 (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
731 ""
40b80dad 732 "s%2subl %1,%3,%0")
36f8f642
RK
733
734(define_insn ""
735 [(set (match_operand:DI 0 "register_operand" "=r")
40b80dad 736 (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
36f8f642
RK
737 (match_operand:DI 2 "const48_operand" "I"))
738 (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
739 ""
40b80dad 740 "s%2subq %1,%3,%0")
36f8f642
RK
741
742(define_insn "mulsi3"
743 [(set (match_operand:SI 0 "register_operand" "=r")
744 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
80df65c9 745 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
36f8f642 746 ""
80df65c9 747 "mull %r1,%2,%0"
71d9b493
RH
748 [(set_attr "type" "imul")
749 (set_attr "opsize" "si")])
36f8f642
RK
750
751(define_insn ""
752 [(set (match_operand:DI 0 "register_operand" "=r")
80df65c9
RH
753 (sign_extend:DI
754 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
755 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
36f8f642 756 ""
80df65c9 757 "mull %r1,%2,%0"
71d9b493
RH
758 [(set_attr "type" "imul")
759 (set_attr "opsize" "si")])
36f8f642
RK
760
761(define_insn "muldi3"
762 [(set (match_operand:DI 0 "register_operand" "=r")
763 (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
80df65c9 764 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
36f8f642 765 ""
80df65c9 766 "mulq %r1,%2,%0"
71d9b493 767 [(set_attr "type" "imul")])
74a61069
TG
768
769(define_insn "umuldi3_highpart"
770 [(set (match_operand:DI 0 "register_operand" "=r")
771 (truncate:DI
772 (lshiftrt:TI
80df65c9
RH
773 (mult:TI (zero_extend:TI
774 (match_operand:DI 1 "reg_or_0_operand" "%rJ"))
775 (zero_extend:TI
776 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
74a61069
TG
777 (const_int 64))))]
778 ""
80df65c9 779 "umulh %r1,%2,%0"
71d9b493
RH
780 [(set_attr "type" "imul")
781 (set_attr "opsize" "udi")])
74a61069
TG
782
783(define_insn ""
784 [(set (match_operand:DI 0 "register_operand" "=r")
785 (truncate:DI
786 (lshiftrt:TI
787 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
788 (match_operand:TI 2 "cint8_operand" "I"))
789 (const_int 64))))]
790 ""
791 "umulh %1,%2,%0"
71d9b493
RH
792 [(set_attr "type" "imul")
793 (set_attr "opsize" "udi")])
36f8f642
RK
794\f
795;; The divide and remainder operations always take their inputs from
df065f1d 796;; r24 and r25, put their output in r27, and clobber r23 and r28.
36f8f642 797
d46f7484
RH
798;; ??? Force sign-extension here because some versions of OSF/1 don't
799;; do the right thing if the inputs are not properly sign-extended.
800;; But Linux, for instance, does not have this problem. Is it worth
801;; the complication here to eliminate the sign extension?
615c8231 802;; Interix/NT has the same sign-extension problem.
d46f7484
RH
803
804(define_expand "divsi3"
805 [(set (reg:DI 24)
806 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
807 (set (reg:DI 25)
808 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
809 (parallel [(set (reg:DI 27)
810 (sign_extend:DI (div:SI (reg:DI 24) (reg:DI 25))))
811 (clobber (reg:DI 23))
812 (clobber (reg:DI 28))])
813 (set (match_operand:SI 0 "general_operand" "")
814 (subreg:SI (reg:DI 27) 0))]
815 "!TARGET_OPEN_VMS"
816 "")
817
818(define_expand "udivsi3"
819 [(set (reg:DI 24)
820 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
821 (set (reg:DI 25)
822 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
823 (parallel [(set (reg:DI 27)
824 (sign_extend:DI (udiv:SI (reg:DI 24) (reg:DI 25))))
825 (clobber (reg:DI 23))
826 (clobber (reg:DI 28))])
827 (set (match_operand:SI 0 "general_operand" "")
828 (subreg:SI (reg:DI 27) 0))]
829 "!TARGET_OPEN_VMS"
830 "")
831
832(define_expand "modsi3"
833 [(set (reg:DI 24)
834 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
835 (set (reg:DI 25)
836 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
837 (parallel [(set (reg:DI 27)
838 (sign_extend:DI (mod:SI (reg:DI 24) (reg:DI 25))))
839 (clobber (reg:DI 23))
840 (clobber (reg:DI 28))])
841 (set (match_operand:SI 0 "general_operand" "")
842 (subreg:SI (reg:DI 27) 0))]
843 "!TARGET_OPEN_VMS"
844 "")
845
846(define_expand "umodsi3"
847 [(set (reg:DI 24)
848 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
849 (set (reg:DI 25)
850 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
851 (parallel [(set (reg:DI 27)
852 (sign_extend:DI (umod:SI (reg:DI 24) (reg:DI 25))))
853 (clobber (reg:DI 23))
854 (clobber (reg:DI 28))])
855 (set (match_operand:SI 0 "general_operand" "")
856 (subreg:SI (reg:DI 27) 0))]
857 "!TARGET_OPEN_VMS"
858 "")
36f8f642
RK
859
860(define_expand "divdi3"
98ff4808
TG
861 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
862 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
863 (parallel [(set (reg:DI 27)
864 (div:DI (reg:DI 24)
865 (reg:DI 25)))
5ce6bbdb
BK
866 (clobber (reg:DI 23))
867 (clobber (reg:DI 28))])
36f8f642
RK
868 (set (match_operand:DI 0 "general_operand" "")
869 (reg:DI 27))]
477c16e3 870 "!TARGET_OPEN_VMS"
98ff4808 871 "")
36f8f642
RK
872
873(define_expand "udivdi3"
98ff4808
TG
874 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
875 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
876 (parallel [(set (reg:DI 27)
877 (udiv:DI (reg:DI 24)
878 (reg:DI 25)))
5ce6bbdb
BK
879 (clobber (reg:DI 23))
880 (clobber (reg:DI 28))])
36f8f642
RK
881 (set (match_operand:DI 0 "general_operand" "")
882 (reg:DI 27))]
477c16e3 883 "!TARGET_OPEN_VMS"
98ff4808 884 "")
36f8f642
RK
885
886(define_expand "moddi3"
98ff4808
TG
887 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
888 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
889 (parallel [(set (reg:DI 27)
890 (mod:DI (reg:DI 24)
891 (reg:DI 25)))
5ce6bbdb
BK
892 (clobber (reg:DI 23))
893 (clobber (reg:DI 28))])
36f8f642
RK
894 (set (match_operand:DI 0 "general_operand" "")
895 (reg:DI 27))]
477c16e3 896 "!TARGET_OPEN_VMS"
98ff4808 897 "")
36f8f642
RK
898
899(define_expand "umoddi3"
98ff4808
TG
900 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
901 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
902 (parallel [(set (reg:DI 27)
903 (umod:DI (reg:DI 24)
904 (reg:DI 25)))
5ce6bbdb
BK
905 (clobber (reg:DI 23))
906 (clobber (reg:DI 28))])
36f8f642
RK
907 (set (match_operand:DI 0 "general_operand" "")
908 (reg:DI 27))]
477c16e3 909 "!TARGET_OPEN_VMS"
98ff4808 910 "")
36f8f642 911
9c0e94a5
RH
912;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
913;; expanded by the assembler.
d46f7484
RH
914(define_insn ""
915 [(set (reg:DI 27)
916 (sign_extend:DI (match_operator:SI 1 "divmod_operator"
917 [(reg:DI 24) (reg:DI 25)])))
918 (clobber (reg:DI 23))
919 (clobber (reg:DI 28))]
920 "!TARGET_OPEN_VMS"
921 "%E1 $24,$25,$27"
9c0e94a5
RH
922 [(set_attr "type" "jsr")
923 (set_attr "length" "8")])
36f8f642
RK
924
925(define_insn ""
926 [(set (reg:DI 27)
927 (match_operator:DI 1 "divmod_operator"
928 [(reg:DI 24) (reg:DI 25)]))
df065f1d
BK
929 (clobber (reg:DI 23))
930 (clobber (reg:DI 28))]
477c16e3 931 "!TARGET_OPEN_VMS"
454f33b9 932 "%E1 $24,$25,$27"
9c0e94a5
RH
933 [(set_attr "type" "jsr")
934 (set_attr "length" "8")])
36f8f642
RK
935\f
936;; Next are the basic logical operations. These only exist in DImode.
937
938(define_insn "anddi3"
939 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
940 (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
941 (match_operand:DI 2 "and_operand" "rI,N,MH")))]
942 ""
943 "@
944 and %r1,%2,%0
945 bic %r1,%N2,%0
946 zapnot %r1,%m2,%0"
745466f2 947 [(set_attr "type" "ilog,ilog,shift")])
36f8f642 948
11e87727 949;; There are times when we can split an AND into two AND insns. This occurs
36f8f642
RK
950;; when we can first clear any bytes and then clear anything else. For
951;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
11e87727 952;; Only do this when running on 64-bit host since the computations are
36f8f642
RK
953;; too messy otherwise.
954
955(define_split
956 [(set (match_operand:DI 0 "register_operand" "")
957 (and:DI (match_operand:DI 1 "register_operand" "")
958 (match_operand:DI 2 "const_int_operand" "")))]
959 "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
960 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
961 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
962 "
963{
964 unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
965 unsigned HOST_WIDE_INT mask2 = mask1;
966 int i;
967
968 /* For each byte that isn't all zeros, make it all ones. */
969 for (i = 0; i < 64; i += 8)
970 if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
971 mask1 |= (HOST_WIDE_INT) 0xff << i;
972
973 /* Now turn on any bits we've just turned off. */
974 mask2 |= ~ mask1;
975
976 operands[3] = GEN_INT (mask1);
977 operands[4] = GEN_INT (mask2);
978}")
979
980(define_insn "zero_extendqihi2"
981 [(set (match_operand:HI 0 "register_operand" "=r")
982 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
983 ""
55a9eb72 984 "and %1,0xff,%0"
5e21ac7a 985 [(set_attr "type" "ilog")])
36f8f642 986
ec0fb163
TG
987(define_insn ""
988 [(set (match_operand:SI 0 "register_operand" "=r,r")
989 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
e9a25f70 990 "TARGET_BWX"
ec0fb163 991 "@
55a9eb72 992 and %1,0xff,%0
ec0fb163 993 ldbu %0,%1"
71d9b493 994 [(set_attr "type" "ilog,ild")])
ec0fb163 995
b9a2d591 996(define_insn ""
36f8f642
RK
997 [(set (match_operand:SI 0 "register_operand" "=r")
998 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
e9a25f70 999 "! TARGET_BWX"
55a9eb72 1000 "and %1,0xff,%0"
5e21ac7a 1001 [(set_attr "type" "ilog")])
36f8f642 1002
b9a2d591
RK
1003(define_expand "zero_extendqisi2"
1004 [(set (match_operand:SI 0 "register_operand" "")
1005 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1006 ""
1007 "")
1008
ec0fb163
TG
1009(define_insn ""
1010 [(set (match_operand:DI 0 "register_operand" "=r,r")
1011 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
e9a25f70 1012 "TARGET_BWX"
ec0fb163 1013 "@
55a9eb72 1014 and %1,0xff,%0
ec0fb163 1015 ldbu %0,%1"
71d9b493 1016 [(set_attr "type" "ilog,ild")])
ec0fb163 1017
b9a2d591 1018(define_insn ""
36f8f642
RK
1019 [(set (match_operand:DI 0 "register_operand" "=r")
1020 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
e9a25f70 1021 "! TARGET_BWX"
55a9eb72 1022 "and %1,0xff,%0"
5e21ac7a 1023 [(set_attr "type" "ilog")])
ec0fb163 1024
b9a2d591
RK
1025(define_expand "zero_extendqidi2"
1026 [(set (match_operand:DI 0 "register_operand" "")
1027 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
1028 ""
1029 "")
1030
ec0fb163
TG
1031(define_insn ""
1032 [(set (match_operand:SI 0 "register_operand" "=r,r")
1033 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
e9a25f70 1034 "TARGET_BWX"
ec0fb163
TG
1035 "@
1036 zapnot %1,3,%0
1037 ldwu %0,%1"
71d9b493 1038 [(set_attr "type" "shift,ild")])
36f8f642 1039
b9a2d591 1040(define_insn ""
36f8f642
RK
1041 [(set (match_operand:SI 0 "register_operand" "=r")
1042 (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
e9a25f70 1043 "! TARGET_BWX"
36f8f642 1044 "zapnot %1,3,%0"
745466f2 1045 [(set_attr "type" "shift")])
36f8f642 1046
b9a2d591
RK
1047(define_expand "zero_extendhisi2"
1048 [(set (match_operand:SI 0 "register_operand" "")
1049 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1050 ""
1051 "")
1052
ec0fb163
TG
1053(define_insn ""
1054 [(set (match_operand:DI 0 "register_operand" "=r,r")
1055 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
e9a25f70 1056 "TARGET_BWX"
ec0fb163
TG
1057 "@
1058 zapnot %1,3,%0
1059 ldwu %0,%1"
71d9b493 1060 [(set_attr "type" "shift,ild")])
ec0fb163 1061
b9a2d591 1062(define_insn ""
36f8f642
RK
1063 [(set (match_operand:DI 0 "register_operand" "=r")
1064 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1065 ""
1066 "zapnot %1,3,%0"
745466f2 1067 [(set_attr "type" "shift")])
36f8f642 1068
b9a2d591
RK
1069(define_expand "zero_extendhidi2"
1070 [(set (match_operand:DI 0 "register_operand" "")
1071 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
1072 ""
1073 "")
1074
36f8f642
RK
1075(define_insn "zero_extendsidi2"
1076 [(set (match_operand:DI 0 "register_operand" "=r")
1077 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1078 ""
1079 "zapnot %1,15,%0"
745466f2 1080 [(set_attr "type" "shift")])
36f8f642
RK
1081
1082(define_insn ""
1083 [(set (match_operand:DI 0 "register_operand" "=r")
1084 (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1085 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1086 ""
1087 "bic %r2,%1,%0"
745466f2 1088 [(set_attr "type" "ilog")])
36f8f642
RK
1089
1090(define_insn "iordi3"
60614fdd
RK
1091 [(set (match_operand:DI 0 "register_operand" "=r,r")
1092 (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
d46f42a5 1093 (match_operand:DI 2 "or_operand" "rI,N")))]
36f8f642 1094 ""
60614fdd
RK
1095 "@
1096 bis %r1,%2,%0
1097 ornot %r1,%N2,%0"
745466f2 1098 [(set_attr "type" "ilog")])
36f8f642
RK
1099
1100(define_insn "one_cmpldi2"
1101 [(set (match_operand:DI 0 "register_operand" "=r")
1102 (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
1103 ""
1104 "ornot $31,%1,%0"
745466f2 1105 [(set_attr "type" "ilog")])
36f8f642
RK
1106
1107(define_insn ""
1108 [(set (match_operand:DI 0 "register_operand" "=r")
1109 (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1110 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1111 ""
1112 "ornot %r2,%1,%0"
745466f2 1113 [(set_attr "type" "ilog")])
36f8f642
RK
1114
1115(define_insn "xordi3"
d46f42a5
RK
1116 [(set (match_operand:DI 0 "register_operand" "=r,r")
1117 (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1118 (match_operand:DI 2 "or_operand" "rI,N")))]
36f8f642 1119 ""
d46f42a5
RK
1120 "@
1121 xor %r1,%2,%0
1122 eqv %r1,%N2,%0"
745466f2 1123 [(set_attr "type" "ilog")])
36f8f642
RK
1124
1125(define_insn ""
1126 [(set (match_operand:DI 0 "register_operand" "=r")
d46f42a5
RK
1127 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
1128 (match_operand:DI 2 "register_operand" "rI"))))]
36f8f642
RK
1129 ""
1130 "eqv %r1,%2,%0"
745466f2 1131 [(set_attr "type" "ilog")])
36f8f642 1132\f
de4abb91
RH
1133;; Handle the FFS insn iff we support CIX.
1134;;
1135;; These didn't make it into EV6 pass 2 as planned. Instead they
1136;; cropped cttz/ctlz/ctpop from the old CIX and renamed it FIX for
1137;; "Square Root and Floating Point Convert Extension".
1138;;
1139;; I'm assured that these insns will make it into EV67 (first pass
1140;; due Summer 1999), presumably with a new AMASK bit, and presumably
1141;; will still be named CIX.
e9a25f70
JL
1142
1143(define_expand "ffsdi2"
1144 [(set (match_dup 2)
1145 (unspec [(match_operand:DI 1 "register_operand" "")] 1))
1146 (set (match_dup 3)
1147 (plus:DI (match_dup 2) (const_int 1)))
1148 (set (match_operand:DI 0 "register_operand" "")
1149 (if_then_else:DI (eq (match_dup 1) (const_int 0))
1150 (const_int 0) (match_dup 3)))]
1151 "TARGET_CIX"
1152 "
1153{
1154 operands[2] = gen_reg_rtx (DImode);
1155 operands[3] = gen_reg_rtx (DImode);
1156}")
1157
1158(define_insn ""
1159 [(set (match_operand:DI 0 "register_operand" "=r")
1160 (unspec [(match_operand:DI 1 "register_operand" "r")] 1))]
1161 "TARGET_CIX"
1162 "cttz %1,%0"
de4abb91 1163 ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
71d9b493
RH
1164 ; reuse the existing type name.
1165 [(set_attr "type" "mvi")])
e9a25f70 1166\f
36f8f642
RK
1167;; Next come the shifts and the various extract and insert operations.
1168
1169(define_insn "ashldi3"
1170 [(set (match_operand:DI 0 "register_operand" "=r,r")
1171 (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
9ec36da5 1172 (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
36f8f642
RK
1173 ""
1174 "*
1175{
1176 switch (which_alternative)
1177 {
1178 case 0:
1179 if (operands[2] == const1_rtx)
1180 return \"addq %r1,%r1,%0\";
1181 else
1182 return \"s%P2addq %r1,0,%0\";
1183 case 1:
1184 return \"sll %r1,%2,%0\";
3c303f52
KG
1185 default:
1186 abort();
36f8f642
RK
1187 }
1188}"
745466f2 1189 [(set_attr "type" "iadd,shift")])
36f8f642 1190
03af65c4
RK
1191;; ??? The following pattern is made by combine, but earlier phases
1192;; (specifically flow) can't handle it. This occurs in jump.c. Deal
1193;; with this in a better way at some point.
1194;;(define_insn ""
1195;; [(set (match_operand:DI 0 "register_operand" "=r")
1196;; (sign_extend:DI
1197;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1198;; (match_operand:DI 2 "const_int_operand" "P"))
1199;; 0)))]
1200;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
1201;; "*
1202;;{
1203;; if (operands[2] == const1_rtx)
1204;; return \"addl %r1,%r1,%0\";
1205;; else
1206;; return \"s%P2addl %r1,0,%0\";
1207;; }"
745466f2 1208;; [(set_attr "type" "iadd")])
36f8f642
RK
1209
1210(define_insn "lshrdi3"
1211 [(set (match_operand:DI 0 "register_operand" "=r")
1212 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
9ec36da5 1213 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
36f8f642 1214 ""
745466f2
RK
1215 "srl %r1,%2,%0"
1216 [(set_attr "type" "shift")])
36f8f642
RK
1217
1218(define_insn "ashrdi3"
1219 [(set (match_operand:DI 0 "register_operand" "=r")
1220 (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
9ec36da5 1221 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
36f8f642 1222 ""
745466f2
RK
1223 "sra %r1,%2,%0"
1224 [(set_attr "type" "shift")])
36f8f642
RK
1225
1226(define_expand "extendqihi2"
1227 [(set (match_dup 2)
b9a2d591 1228 (ashift:DI (match_operand:QI 1 "some_operand" "")
36f8f642
RK
1229 (const_int 56)))
1230 (set (match_operand:HI 0 "register_operand" "")
1231 (ashiftrt:DI (match_dup 2)
1232 (const_int 56)))]
1233 ""
1234 "
2206e904 1235{
e9a25f70 1236 if (TARGET_BWX)
b9a2d591
RK
1237 {
1238 emit_insn (gen_extendqihi2x (operands[0],
1239 force_reg (QImode, operands[1])));
1240 DONE;
1241 }
1242
1243 /* If we have an unaligned MEM, extend to DImode (which we do
ec0fb163 1244 specially) and then copy to the result. */
b9a2d591 1245 if (unaligned_memory_operand (operands[1], HImode))
2206e904
RK
1246 {
1247 rtx temp = gen_reg_rtx (DImode);
1248
1249 emit_insn (gen_extendqidi2 (temp, operands[1]));
1250 emit_move_insn (operands[0], gen_lowpart (HImode, temp));
1251 DONE;
1252 }
1253
1254 operands[0] = gen_lowpart (DImode, operands[0]);
5d38efae 1255 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
36f8f642
RK
1256 operands[2] = gen_reg_rtx (DImode);
1257}")
1258
ec0fb163 1259(define_insn "extendqidi2x"
b9a2d591 1260 [(set (match_operand:DI 0 "register_operand" "=r")
ec0fb163 1261 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
e9a25f70 1262 "TARGET_BWX"
ec0fb163 1263 "sextb %1,%0"
b9a2d591 1264 [(set_attr "type" "shift")])
ec0fb163
TG
1265
1266(define_insn "extendhidi2x"
b9a2d591 1267 [(set (match_operand:DI 0 "register_operand" "=r")
ec0fb163 1268 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
e9a25f70 1269 "TARGET_BWX"
ec0fb163
TG
1270 "sextw %1,%0"
1271 [(set_attr "type" "shift")])
1272
b9a2d591
RK
1273(define_insn "extendqisi2x"
1274 [(set (match_operand:SI 0 "register_operand" "=r")
1275 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
e9a25f70 1276 "TARGET_BWX"
b9a2d591
RK
1277 "sextb %1,%0"
1278 [(set_attr "type" "shift")])
1279
1280(define_insn "extendhisi2x"
1281 [(set (match_operand:SI 0 "register_operand" "=r")
1282 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
e9a25f70 1283 "TARGET_BWX"
b9a2d591
RK
1284 "sextw %1,%0"
1285 [(set_attr "type" "shift")])
1286
1287(define_insn "extendqihi2x"
1288 [(set (match_operand:HI 0 "register_operand" "=r")
1289 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
e9a25f70 1290 "TARGET_BWX"
b9a2d591
RK
1291 "sextb %1,%0"
1292 [(set_attr "type" "shift")])
1293
36f8f642
RK
1294(define_expand "extendqisi2"
1295 [(set (match_dup 2)
b9a2d591 1296 (ashift:DI (match_operand:QI 1 "some_operand" "")
36f8f642
RK
1297 (const_int 56)))
1298 (set (match_operand:SI 0 "register_operand" "")
1299 (ashiftrt:DI (match_dup 2)
1300 (const_int 56)))]
1301 ""
1302 "
2206e904 1303{
e9a25f70 1304 if (TARGET_BWX)
b9a2d591
RK
1305 {
1306 emit_insn (gen_extendqisi2x (operands[0],
1307 force_reg (QImode, operands[1])));
1308 DONE;
1309 }
1310
1311 /* If we have an unaligned MEM, extend to a DImode form of
2206e904 1312 the result (which we do specially). */
b9a2d591 1313 if (unaligned_memory_operand (operands[1], QImode))
2206e904
RK
1314 {
1315 rtx temp = gen_reg_rtx (DImode);
1316
1317 emit_insn (gen_extendqidi2 (temp, operands[1]));
1318 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1319 DONE;
1320 }
1321
1322 operands[0] = gen_lowpart (DImode, operands[0]);
b9a2d591 1323 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
36f8f642
RK
1324 operands[2] = gen_reg_rtx (DImode);
1325}")
1326
1327(define_expand "extendqidi2"
1328 [(set (match_dup 2)
b9a2d591 1329 (ashift:DI (match_operand:QI 1 "some_operand" "")
36f8f642
RK
1330 (const_int 56)))
1331 (set (match_operand:DI 0 "register_operand" "")
1332 (ashiftrt:DI (match_dup 2)
1333 (const_int 56)))]
1334 ""
1335 "
47747e53 1336{
e9a25f70 1337 if (TARGET_BWX)
ec0fb163 1338 {
b9a2d591
RK
1339 emit_insn (gen_extendqidi2x (operands[0],
1340 force_reg (QImode, operands[1])));
ec0fb163
TG
1341 DONE;
1342 }
1343
b9a2d591 1344 if (unaligned_memory_operand (operands[1], QImode))
2206e904
RK
1345 {
1346 rtx seq
1347 = gen_unaligned_extendqidi (operands[0],
1348 get_unaligned_address (operands[1], 1));
1349
1350 alpha_set_memflags (seq, operands[1]);
1351 emit_insn (seq);
1352 DONE;
1353 }
1354
b9a2d591 1355 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
36f8f642
RK
1356 operands[2] = gen_reg_rtx (DImode);
1357}")
1358
1359(define_expand "extendhisi2"
1360 [(set (match_dup 2)
b9a2d591 1361 (ashift:DI (match_operand:HI 1 "some_operand" "")
36f8f642
RK
1362 (const_int 48)))
1363 (set (match_operand:SI 0 "register_operand" "")
1364 (ashiftrt:DI (match_dup 2)
1365 (const_int 48)))]
1366 ""
1367 "
2206e904 1368{
e9a25f70 1369 if (TARGET_BWX)
b9a2d591
RK
1370 {
1371 emit_insn (gen_extendhisi2x (operands[0],
1372 force_reg (HImode, operands[1])));
1373 DONE;
1374 }
1375
1376 /* If we have an unaligned MEM, extend to a DImode form of
2206e904 1377 the result (which we do specially). */
b9a2d591 1378 if (unaligned_memory_operand (operands[1], HImode))
2206e904
RK
1379 {
1380 rtx temp = gen_reg_rtx (DImode);
1381
1382 emit_insn (gen_extendhidi2 (temp, operands[1]));
1383 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1384 DONE;
1385 }
1386
1387 operands[0] = gen_lowpart (DImode, operands[0]);
b9a2d591 1388 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
36f8f642
RK
1389 operands[2] = gen_reg_rtx (DImode);
1390}")
1391
1392(define_expand "extendhidi2"
1393 [(set (match_dup 2)
b9a2d591 1394 (ashift:DI (match_operand:HI 1 "some_operand" "")
36f8f642
RK
1395 (const_int 48)))
1396 (set (match_operand:DI 0 "register_operand" "")
1397 (ashiftrt:DI (match_dup 2)
1398 (const_int 48)))]
1399 ""
1400 "
47747e53 1401{
e9a25f70 1402 if (TARGET_BWX)
ec0fb163 1403 {
b9a2d591
RK
1404 emit_insn (gen_extendhidi2x (operands[0],
1405 force_reg (HImode, operands[1])));
ec0fb163
TG
1406 DONE;
1407 }
1408
b9a2d591 1409 if (unaligned_memory_operand (operands[1], HImode))
2206e904
RK
1410 {
1411 rtx seq
1412 = gen_unaligned_extendhidi (operands[0],
1413 get_unaligned_address (operands[1], 2));
1414
1415 alpha_set_memflags (seq, operands[1]);
1416 emit_insn (seq);
1417 DONE;
1418 }
1419
b9a2d591 1420 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
36f8f642
RK
1421 operands[2] = gen_reg_rtx (DImode);
1422}")
1423
2206e904
RK
1424;; Here's how we sign extend an unaligned byte and halfword. Doing this
1425;; as a pattern saves one instruction. The code is similar to that for
1426;; the unaligned loads (see below).
1427;;
1428;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
1429(define_expand "unaligned_extendqidi"
1430 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1431 (set (match_dup 3)
1432 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
1433 (const_int -8))))
1434 (set (match_dup 4)
1435 (ashift:DI (match_dup 3)
786d6092 1436 (minus:DI (const_int 64)
2206e904 1437 (ashift:DI
786d6092 1438 (and:DI (match_dup 2) (const_int 7))
2206e904
RK
1439 (const_int 3)))))
1440 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1441 (ashiftrt:DI (match_dup 4) (const_int 56)))]
1442 ""
1443 "
1444{ operands[2] = gen_reg_rtx (DImode);
1445 operands[3] = gen_reg_rtx (DImode);
1446 operands[4] = gen_reg_rtx (DImode);
1447}")
1448
1449(define_expand "unaligned_extendhidi"
1450 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1451 (set (match_dup 3)
1452 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
1453 (const_int -8))))
1454 (set (match_dup 4)
1455 (ashift:DI (match_dup 3)
786d6092 1456 (minus:DI (const_int 64)
2206e904 1457 (ashift:DI
786d6092 1458 (and:DI (match_dup 2) (const_int 7))
2206e904
RK
1459 (const_int 3)))))
1460 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1461 (ashiftrt:DI (match_dup 4) (const_int 48)))]
1462 ""
1463 "
1464{ operands[2] = gen_reg_rtx (DImode);
1465 operands[3] = gen_reg_rtx (DImode);
1466 operands[4] = gen_reg_rtx (DImode);
1467}")
1468
36f8f642
RK
1469(define_insn ""
1470 [(set (match_operand:DI 0 "register_operand" "=r")
1471 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1472 (match_operand:DI 2 "mode_width_operand" "n")
1473 (match_operand:DI 3 "mul8_operand" "I")))]
1474 ""
745466f2
RK
1475 "ext%M2l %r1,%s3,%0"
1476 [(set_attr "type" "shift")])
36f8f642 1477
6c174fc0 1478(define_insn "extxl"
36f8f642
RK
1479 [(set (match_operand:DI 0 "register_operand" "=r")
1480 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1481 (match_operand:DI 2 "mode_width_operand" "n")
1482 (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1483 (const_int 3))))]
1484 ""
745466f2
RK
1485 "ext%M2l %r1,%3,%0"
1486 [(set_attr "type" "shift")])
36f8f642 1487
b08b85c4
RH
1488;; Combine has some strange notion of preserving existing undefined behaviour
1489;; in shifts larger than a word size. So capture these patterns that it
1490;; should have turned into zero_extracts.
1491
1492(define_insn ""
1493 [(set (match_operand:DI 0 "register_operand" "=r")
1494 (and (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1495 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1496 (const_int 3)))
1497 (match_operand:DI 3 "mode_mask_operand" "n")))]
1498 ""
1499 "ext%U3l %1,%2,%0"
1500 [(set_attr "type" "shift")])
1501
1502(define_insn ""
1503 [(set (match_operand:DI 0 "register_operand" "=r")
1504 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1505 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1506 (const_int 3))))]
1507 ""
1508 "extql %1,%2,%0"
1509 [(set_attr "type" "shift")])
1510
6c174fc0 1511(define_insn "extqh"
36f8f642
RK
1512 [(set (match_operand:DI 0 "register_operand" "=r")
1513 (ashift:DI
2206e904 1514 (match_operand:DI 1 "reg_or_0_operand" "rJ")
786d6092 1515 (minus:DI (const_int 64)
2206e904
RK
1516 (ashift:DI
1517 (and:DI
786d6092 1518 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2206e904
RK
1519 (const_int 7))
1520 (const_int 3)))))]
36f8f642 1521 ""
745466f2
RK
1522 "extqh %r1,%2,%0"
1523 [(set_attr "type" "shift")])
36f8f642 1524
6c174fc0 1525(define_insn "extlh"
36f8f642
RK
1526 [(set (match_operand:DI 0 "register_operand" "=r")
1527 (ashift:DI
2206e904
RK
1528 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1529 (const_int 2147483647))
786d6092 1530 (minus:DI (const_int 64)
2206e904
RK
1531 (ashift:DI
1532 (and:DI
786d6092 1533 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2206e904
RK
1534 (const_int 7))
1535 (const_int 3)))))]
36f8f642 1536 ""
745466f2
RK
1537 "extlh %r1,%2,%0"
1538 [(set_attr "type" "shift")])
36f8f642 1539
6c174fc0 1540(define_insn "extwh"
36f8f642
RK
1541 [(set (match_operand:DI 0 "register_operand" "=r")
1542 (ashift:DI
2206e904
RK
1543 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1544 (const_int 65535))
786d6092 1545 (minus:DI (const_int 64)
2206e904
RK
1546 (ashift:DI
1547 (and:DI
786d6092 1548 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2206e904
RK
1549 (const_int 7))
1550 (const_int 3)))))]
36f8f642 1551 ""
745466f2
RK
1552 "extwh %r1,%2,%0"
1553 [(set_attr "type" "shift")])
2206e904 1554
36f8f642
RK
1555;; This converts an extXl into an extXh with an appropriate adjustment
1556;; to the address calculation.
1557
2206e904
RK
1558;;(define_split
1559;; [(set (match_operand:DI 0 "register_operand" "")
1560;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
1561;; (match_operand:DI 2 "mode_width_operand" "")
1562;; (ashift:DI (match_operand:DI 3 "" "")
1563;; (const_int 3)))
1564;; (match_operand:DI 4 "const_int_operand" "")))
1565;; (clobber (match_operand:DI 5 "register_operand" ""))]
1566;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1567;; [(set (match_dup 5) (match_dup 6))
1568;; (set (match_dup 0)
1569;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1570;; (ashift:DI (plus:DI (match_dup 5)
1571;; (match_dup 7))
1572;; (const_int 3)))
1573;; (match_dup 4)))]
1574;; "
1575;;{
1576;; operands[6] = plus_constant (operands[3],
1577;; INTVAL (operands[2]) / BITS_PER_UNIT);
1578;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1579;;}")
36f8f642
RK
1580
1581(define_insn ""
1582 [(set (match_operand:DI 0 "register_operand" "=r")
1583 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1584 (match_operand:DI 2 "mul8_operand" "I")))]
1585 ""
745466f2
RK
1586 "insbl %1,%s2,%0"
1587 [(set_attr "type" "shift")])
36f8f642
RK
1588
1589(define_insn ""
1590 [(set (match_operand:DI 0 "register_operand" "=r")
1591 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1592 (match_operand:DI 2 "mul8_operand" "I")))]
1593 ""
745466f2
RK
1594 "inswl %1,%s2,%0"
1595 [(set_attr "type" "shift")])
36f8f642
RK
1596
1597(define_insn ""
1598 [(set (match_operand:DI 0 "register_operand" "=r")
1599 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1600 (match_operand:DI 2 "mul8_operand" "I")))]
1601 ""
745466f2
RK
1602 "insll %1,%s2,%0"
1603 [(set_attr "type" "shift")])
36f8f642 1604
6c174fc0 1605(define_insn "insbl"
36f8f642
RK
1606 [(set (match_operand:DI 0 "register_operand" "=r")
1607 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1608 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1609 (const_int 3))))]
1610 ""
745466f2
RK
1611 "insbl %1,%2,%0"
1612 [(set_attr "type" "shift")])
36f8f642 1613
6c174fc0 1614(define_insn "inswl"
36f8f642
RK
1615 [(set (match_operand:DI 0 "register_operand" "=r")
1616 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1617 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1618 (const_int 3))))]
1619 ""
745466f2
RK
1620 "inswl %1,%2,%0"
1621 [(set_attr "type" "shift")])
36f8f642 1622
6c174fc0 1623(define_insn "insll"
36f8f642
RK
1624 [(set (match_operand:DI 0 "register_operand" "=r")
1625 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1626 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1627 (const_int 3))))]
1628 ""
745466f2
RK
1629 "insll %1,%2,%0"
1630 [(set_attr "type" "shift")])
36f8f642 1631
6c174fc0
RH
1632(define_insn "insql"
1633 [(set (match_operand:DI 0 "register_operand" "=r")
1634 (ashift:DI (match_operand:DI 1 "register_operand" "r")
1635 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1636 (const_int 3))))]
1637 ""
1638 "insql %1,%2,%0"
1639 [(set_attr "type" "shift")])
1640
989f090c
RH
1641;; Combine has this sometimes habit of moving the and outside of the
1642;; shift, making life more interesting.
1643
1644(define_insn ""
1645 [(set (match_operand:DI 0 "register_operand" "=r")
1646 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
1647 (match_operand:DI 2 "mul8_operand" "I"))
1648 (match_operand:DI 3 "immediate_operand" "i")))]
1649 "HOST_BITS_PER_WIDE_INT == 64
1650 && GET_CODE (operands[3]) == CONST_INT
1651 && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
df45c7ea 1652 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
989f090c 1653 || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
df45c7ea 1654 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
989f090c 1655 || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
df45c7ea 1656 == (unsigned HOST_WIDE_INT) INTVAL (operands[3])))"
989f090c
RH
1657 "*
1658{
1659#if HOST_BITS_PER_WIDE_INT == 64
1660 if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
df45c7ea 1661 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
989f090c
RH
1662 return \"insbl %1,%s2,%0\";
1663 if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
df45c7ea 1664 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
989f090c
RH
1665 return \"inswl %1,%s2,%0\";
1666 if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
df45c7ea 1667 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
989f090c
RH
1668 return \"insll %1,%s2,%0\";
1669#endif
1670 abort();
1671}"
1672 [(set_attr "type" "shift")])
1673
36f8f642
RK
1674;; We do not include the insXh insns because they are complex to express
1675;; and it does not appear that we would ever want to generate them.
6c174fc0
RH
1676;;
1677;; Since we need them for block moves, though, cop out and use unspec.
36f8f642 1678
6c174fc0
RH
1679(define_insn "insxh"
1680 [(set (match_operand:DI 0 "register_operand" "=r")
1681 (unspec [(match_operand:DI 1 "register_operand" "r")
1682 (match_operand:DI 2 "mode_width_operand" "n")
1683 (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2))]
1684 ""
1685 "ins%M2h %1,%3,%0"
1686 [(set_attr "type" "shift")])
1687
1688(define_insn "mskxl"
36f8f642 1689 [(set (match_operand:DI 0 "register_operand" "=r")
027b95a6
RK
1690 (and:DI (not:DI (ashift:DI
1691 (match_operand:DI 2 "mode_mask_operand" "n")
1692 (ashift:DI
1693 (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1694 (const_int 3))))
36f8f642
RK
1695 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1696 ""
745466f2
RK
1697 "msk%U2l %r1,%3,%0"
1698 [(set_attr "type" "shift")])
36f8f642 1699
6c174fc0
RH
1700;; We do not include the mskXh insns because it does not appear we would
1701;; ever generate one.
1702;;
1703;; Again, we do for block moves and we use unspec again.
1704
1705(define_insn "mskxh"
1706 [(set (match_operand:DI 0 "register_operand" "=r")
1707 (unspec [(match_operand:DI 1 "register_operand" "r")
1708 (match_operand:DI 2 "mode_width_operand" "n")
1709 (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 3))]
1710 ""
1711 "msk%M2h %1,%3,%0"
1712 [(set_attr "type" "shift")])
36f8f642
RK
1713\f
1714;; Floating-point operations. All the double-precision insns can extend
1715;; from single, so indicate that. The exception are the ones that simply
1716;; play with the sign bits; it's not clear what to do there.
1717
1718(define_insn "abssf2"
1719 [(set (match_operand:SF 0 "register_operand" "=f")
1720 (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
5e4aab97 1721 "TARGET_FP"
36f8f642 1722 "cpys $f31,%R1,%0"
745466f2 1723 [(set_attr "type" "fcpys")])
36f8f642
RK
1724
1725(define_insn "absdf2"
1726 [(set (match_operand:DF 0 "register_operand" "=f")
1727 (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
5e4aab97 1728 "TARGET_FP"
36f8f642 1729 "cpys $f31,%R1,%0"
745466f2 1730 [(set_attr "type" "fcpys")])
36f8f642
RK
1731
1732(define_insn "negsf2"
1733 [(set (match_operand:SF 0 "register_operand" "=f")
1734 (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
ea56ab2a 1735 "TARGET_FP"
59e60927 1736 "cpysn %R1,%R1,%0"
745466f2 1737 [(set_attr "type" "fadd")])
36f8f642
RK
1738
1739(define_insn "negdf2"
1740 [(set (match_operand:DF 0 "register_operand" "=f")
1741 (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1742 "TARGET_FP"
59e60927 1743 "cpysn %R1,%R1,%0"
745466f2 1744 [(set_attr "type" "fadd")])
36f8f642 1745
0d4ae18a
RK
1746(define_insn ""
1747 [(set (match_operand:SF 0 "register_operand" "=&f")
1748 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1749 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
981a828e 1750 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 1751 "add%,%)%& %R1,%R2,%0"
745466f2 1752 [(set_attr "type" "fadd")
0d4ae18a
RK
1753 (set_attr "trap" "yes")])
1754
36f8f642
RK
1755(define_insn "addsf3"
1756 [(set (match_operand:SF 0 "register_operand" "=f")
1757 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1758 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1759 "TARGET_FP"
477c16e3 1760 "add%,%)%& %R1,%R2,%0"
745466f2 1761 [(set_attr "type" "fadd")
0d4ae18a
RK
1762 (set_attr "trap" "yes")])
1763
1764(define_insn ""
1765 [(set (match_operand:DF 0 "register_operand" "=&f")
1766 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1767 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
981a828e 1768 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 1769 "add%-%)%& %R1,%R2,%0"
745466f2 1770 [(set_attr "type" "fadd")
0d4ae18a 1771 (set_attr "trap" "yes")])
36f8f642
RK
1772
1773(define_insn "adddf3"
1774 [(set (match_operand:DF 0 "register_operand" "=f")
1775 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1776 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1777 "TARGET_FP"
477c16e3 1778 "add%-%)%& %R1,%R2,%0"
745466f2 1779 [(set_attr "type" "fadd")
0d4ae18a
RK
1780 (set_attr "trap" "yes")])
1781
36f8f642
RK
1782(define_insn ""
1783 [(set (match_operand:DF 0 "register_operand" "=f")
1784 (plus:DF (float_extend:DF
55ff92b8 1785 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
36f8f642 1786 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
981a828e 1787 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 1788 "add%-%)%& %R1,%R2,%0"
745466f2 1789 [(set_attr "type" "fadd")
0d4ae18a 1790 (set_attr "trap" "yes")])
36f8f642
RK
1791
1792(define_insn ""
1793 [(set (match_operand:DF 0 "register_operand" "=f")
1794 (plus:DF (float_extend:DF
1795 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1796 (float_extend:DF
1797 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
981a828e 1798 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 1799 "add%-%)%& %R1,%R2,%0"
745466f2 1800 [(set_attr "type" "fadd")
0d4ae18a 1801 (set_attr "trap" "yes")])
36f8f642 1802
e83015a9
RH
1803;; Define conversion operators between DFmode and SImode, using the cvtql
1804;; instruction. To allow combine et al to do useful things, we keep the
1805;; operation as a unit until after reload, at which point we split the
1806;; instructions.
1ca2e73f
RH
1807;;
1808;; Note that we (attempt to) only consider this optimization when the
1809;; ultimate destination is memory. If we will be doing further integer
1810;; processing, it is cheaper to do the truncation in the int regs.
1811
1812(define_insn "*cvtql"
1813 [(set (match_operand:SI 0 "register_operand" "=f")
1814 (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] 5))]
1815 "TARGET_FP"
1816 "cvtql%` %R1,%0"
1817 [(set_attr "type" "fadd")
1818 (set_attr "trap" "yes")])
e83015a9
RH
1819
1820(define_split
1ca2e73f
RH
1821 [(set (match_operand:SI 0 "memory_operand" "")
1822 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
1823 (clobber (match_scratch:DI 2 ""))
1824 (clobber (match_scratch:SI 3 ""))]
e83015a9
RH
1825 "TARGET_FP && reload_completed"
1826 [(set (match_dup 2) (fix:DI (match_dup 1)))
1ca2e73f
RH
1827 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1828 (set (match_dup 0) (match_dup 3))]
e83015a9
RH
1829 "")
1830
e83015a9 1831(define_split
1ca2e73f
RH
1832 [(set (match_operand:SI 0 "memory_operand" "")
1833 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
1834 (clobber (match_scratch:DI 2 ""))]
e83015a9
RH
1835 "TARGET_FP && reload_completed"
1836 [(set (match_dup 2) (fix:DI (match_dup 1)))
1ca2e73f
RH
1837 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1838 (set (match_dup 0) (match_dup 3))]
1839 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
1840 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
e83015a9
RH
1841
1842(define_insn ""
1ca2e73f
RH
1843 [(set (match_operand:SI 0 "memory_operand" "=m")
1844 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
1845 (clobber (match_scratch:DI 2 "=&f"))
1846 (clobber (match_scratch:SI 3 "=&f"))]
981a828e 1847 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
e83015a9
RH
1848 "#"
1849 [(set_attr "type" "fadd")
1850 (set_attr "trap" "yes")])
1851
1852(define_insn ""
1ca2e73f
RH
1853 [(set (match_operand:SI 0 "memory_operand" "=m")
1854 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
1855 (clobber (match_scratch:DI 2 "=f"))]
981a828e 1856 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
e83015a9
RH
1857 "#"
1858 [(set_attr "type" "fadd")
1859 (set_attr "trap" "yes")])
1860
0022a940 1861(define_insn ""
be5090b0 1862 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
0022a940 1863 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
981a828e 1864 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
0022a940
DMT
1865 "cvt%-q%(c %R1,%0"
1866 [(set_attr "type" "fadd")
1867 (set_attr "trap" "yes")])
1868
36f8f642 1869(define_insn "fix_truncdfdi2"
be5090b0 1870 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
36f8f642
RK
1871 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1872 "TARGET_FP"
0022a940
DMT
1873 "cvt%-q%(c %R1,%0"
1874 [(set_attr "type" "fadd")
1875 (set_attr "trap" "yes")])
1876
e83015a9
RH
1877;; Likewise between SFmode and SImode.
1878
1879(define_split
1ca2e73f
RH
1880 [(set (match_operand:SI 0 "memory_operand" "")
1881 (subreg:SI (fix:DI (float_extend:DF
1882 (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
1883 (clobber (match_scratch:DI 2 ""))
1884 (clobber (match_scratch:SI 3 ""))]
e83015a9
RH
1885 "TARGET_FP && reload_completed"
1886 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
1ca2e73f
RH
1887 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1888 (set (match_dup 0) (match_dup 3))]
e83015a9
RH
1889 "")
1890
e83015a9 1891(define_split
1ca2e73f
RH
1892 [(set (match_operand:SI 0 "memory_operand" "")
1893 (subreg:SI (fix:DI (float_extend:DF
1894 (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
1895 (clobber (match_scratch:DI 2 ""))]
e83015a9
RH
1896 "TARGET_FP && reload_completed"
1897 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
1ca2e73f
RH
1898 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1899 (set (match_dup 0) (match_dup 3))]
1900 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
1901 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
1902
1903(define_insn ""
1904 [(set (match_operand:SI 0 "memory_operand" "=m")
1905 (subreg:SI (fix:DI (float_extend:DF
1906 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
1907 (clobber (match_scratch:DI 2 "=&f"))
1908 (clobber (match_scratch:SI 3 "=&f"))]
981a828e 1909 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
e83015a9
RH
1910 "#"
1911 [(set_attr "type" "fadd")
1912 (set_attr "trap" "yes")])
1913
1914(define_insn ""
1ca2e73f
RH
1915 [(set (match_operand:SI 0 "memory_operand" "=m")
1916 (subreg:SI (fix:DI (float_extend:DF
1917 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
1918 (clobber (match_scratch:DI 2 "=f"))]
981a828e 1919 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
e83015a9
RH
1920 "#"
1921 [(set_attr "type" "fadd")
1922 (set_attr "trap" "yes")])
1923
0022a940 1924(define_insn ""
be5090b0 1925 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
0022a940
DMT
1926 (fix:DI (float_extend:DF
1927 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
981a828e 1928 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
0022a940
DMT
1929 "cvt%-q%(c %R1,%0"
1930 [(set_attr "type" "fadd")
1931 (set_attr "trap" "yes")])
36f8f642
RK
1932
1933(define_insn "fix_truncsfdi2"
be5090b0 1934 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
36f8f642
RK
1935 (fix:DI (float_extend:DF
1936 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1937 "TARGET_FP"
0022a940
DMT
1938 "cvt%-q%(c %R1,%0"
1939 [(set_attr "type" "fadd")
1940 (set_attr "trap" "yes")])
36f8f642 1941
8cf02b47
JW
1942(define_insn ""
1943 [(set (match_operand:SF 0 "register_operand" "=&f")
67070f5c 1944 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
981a828e 1945 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
8cf02b47
JW
1946 "cvtq%,%+%& %1,%0"
1947 [(set_attr "type" "fadd")
1948 (set_attr "trap" "yes")])
1949
36f8f642
RK
1950(define_insn "floatdisf2"
1951 [(set (match_operand:SF 0 "register_operand" "=f")
67070f5c 1952 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
36f8f642 1953 "TARGET_FP"
477c16e3 1954 "cvtq%,%+%& %1,%0"
745466f2 1955 [(set_attr "type" "fadd")
0d4ae18a
RK
1956 (set_attr "trap" "yes")])
1957
1958(define_insn ""
1959 [(set (match_operand:DF 0 "register_operand" "=&f")
67070f5c 1960 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
981a828e 1961 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 1962 "cvtq%-%+%& %1,%0"
745466f2 1963 [(set_attr "type" "fadd")
0d4ae18a 1964 (set_attr "trap" "yes")])
36f8f642
RK
1965
1966(define_insn "floatdidf2"
1967 [(set (match_operand:DF 0 "register_operand" "=f")
67070f5c 1968 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
36f8f642 1969 "TARGET_FP"
477c16e3 1970 "cvtq%-%+%& %1,%0"
745466f2 1971 [(set_attr "type" "fadd")
0d4ae18a
RK
1972 (set_attr "trap" "yes")])
1973
5556bc5b
RK
1974(define_expand "extendsfdf2"
1975 [(use (match_operand:DF 0 "register_operand" ""))
1976 (use (match_operand:SF 1 "nonimmediate_operand" ""))]
1977 "TARGET_FP"
1978"
1979{
981a828e 1980 if (alpha_fptm >= ALPHA_FPTM_SU)
5556bc5b
RK
1981 emit_insn (gen_extendsfdf2_tp (operands[0],
1982 force_reg (SFmode, operands[1])));
1983 else
1984 emit_insn (gen_extendsfdf2_no_tp (operands[0], operands[1]));
1985
1986 DONE;
1987}")
477c16e3 1988;; FIXME
5556bc5b
RK
1989(define_insn "extendsfdf2_tp"
1990 [(set (match_operand:DF 0 "register_operand" "=&f")
1991 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
981a828e 1992 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
5556bc5b
RK
1993 "cvtsts %1,%0"
1994 [(set_attr "type" "fadd")
0d4ae18a 1995 (set_attr "trap" "yes")])
36f8f642 1996
5556bc5b 1997(define_insn "extendsfdf2_no_tp"
70ee78ec
RK
1998 [(set (match_operand:DF 0 "register_operand" "=f,f,m")
1999 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
981a828e 2000 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
36f8f642 2001 "@
6ce652e0 2002 fmov %1,%0
70ee78ec
RK
2003 ld%, %0,%1
2004 st%- %1,%0"
71d9b493 2005 [(set_attr "type" "fcpys,fld,fst")
0d4ae18a
RK
2006 (set_attr "trap" "yes")])
2007
2008(define_insn ""
2009 [(set (match_operand:SF 0 "register_operand" "=&f")
2010 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
981a828e 2011 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 2012 "cvt%-%,%)%& %R1,%0"
745466f2 2013 [(set_attr "type" "fadd")
0d4ae18a 2014 (set_attr "trap" "yes")])
36f8f642
RK
2015
2016(define_insn "truncdfsf2"
2017 [(set (match_operand:SF 0 "register_operand" "=f")
2018 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2019 "TARGET_FP"
477c16e3 2020 "cvt%-%,%)%& %R1,%0"
745466f2 2021 [(set_attr "type" "fadd")
0d4ae18a
RK
2022 (set_attr "trap" "yes")])
2023
2024(define_insn ""
2025 [(set (match_operand:SF 0 "register_operand" "=&f")
2026 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2027 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
981a828e 2028 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 2029 "div%,%)%& %R1,%R2,%0"
71d9b493
RH
2030 [(set_attr "type" "fdiv")
2031 (set_attr "opsize" "si")
0d4ae18a 2032 (set_attr "trap" "yes")])
36f8f642
RK
2033
2034(define_insn "divsf3"
2035 [(set (match_operand:SF 0 "register_operand" "=f")
2036 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2037 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2038 "TARGET_FP"
477c16e3 2039 "div%,%)%& %R1,%R2,%0"
71d9b493
RH
2040 [(set_attr "type" "fdiv")
2041 (set_attr "opsize" "si")
0d4ae18a
RK
2042 (set_attr "trap" "yes")])
2043
2044(define_insn ""
2045 [(set (match_operand:DF 0 "register_operand" "=&f")
2046 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2047 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
981a828e 2048 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 2049 "div%-%)%& %R1,%R2,%0"
71d9b493 2050 [(set_attr "type" "fdiv")
0d4ae18a 2051 (set_attr "trap" "yes")])
36f8f642
RK
2052
2053(define_insn "divdf3"
2054 [(set (match_operand:DF 0 "register_operand" "=f")
2055 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2056 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2057 "TARGET_FP"
477c16e3 2058 "div%-%)%& %R1,%R2,%0"
71d9b493 2059 [(set_attr "type" "fdiv")
0d4ae18a
RK
2060 (set_attr "trap" "yes")])
2061
36f8f642
RK
2062(define_insn ""
2063 [(set (match_operand:DF 0 "register_operand" "=f")
2064 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2065 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
981a828e 2066 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2067 "div%-%)%& %R1,%R2,%0"
71d9b493 2068 [(set_attr "type" "fdiv")
0d4ae18a 2069 (set_attr "trap" "yes")])
36f8f642
RK
2070
2071(define_insn ""
2072 [(set (match_operand:DF 0 "register_operand" "=f")
2073 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2074 (float_extend:DF
2075 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
981a828e 2076 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2077 "div%-%)%& %R1,%R2,%0"
71d9b493 2078 [(set_attr "type" "fdiv")
0d4ae18a 2079 (set_attr "trap" "yes")])
36f8f642
RK
2080
2081(define_insn ""
2082 [(set (match_operand:DF 0 "register_operand" "=f")
2083 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2084 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
981a828e 2085 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2086 "div%-%)%& %R1,%R2,%0"
71d9b493 2087 [(set_attr "type" "fdiv")
0d4ae18a
RK
2088 (set_attr "trap" "yes")])
2089
2090(define_insn ""
2091 [(set (match_operand:SF 0 "register_operand" "=&f")
2092 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2093 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
981a828e 2094 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 2095 "mul%,%)%& %R1,%R2,%0"
745466f2 2096 [(set_attr "type" "fmul")
0d4ae18a 2097 (set_attr "trap" "yes")])
36f8f642
RK
2098
2099(define_insn "mulsf3"
2100 [(set (match_operand:SF 0 "register_operand" "=f")
55ff92b8 2101 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
36f8f642
RK
2102 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2103 "TARGET_FP"
477c16e3 2104 "mul%,%)%& %R1,%R2,%0"
745466f2 2105 [(set_attr "type" "fmul")
0d4ae18a
RK
2106 (set_attr "trap" "yes")])
2107
2108(define_insn ""
2109 [(set (match_operand:DF 0 "register_operand" "=&f")
2110 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2111 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
981a828e 2112 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 2113 "mul%-%)%& %R1,%R2,%0"
745466f2 2114 [(set_attr "type" "fmul")
0d4ae18a 2115 (set_attr "trap" "yes")])
36f8f642
RK
2116
2117(define_insn "muldf3"
2118 [(set (match_operand:DF 0 "register_operand" "=f")
55ff92b8 2119 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
36f8f642
RK
2120 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2121 "TARGET_FP"
477c16e3 2122 "mul%-%)%& %R1,%R2,%0"
745466f2 2123 [(set_attr "type" "fmul")
0d4ae18a
RK
2124 (set_attr "trap" "yes")])
2125
36f8f642
RK
2126(define_insn ""
2127 [(set (match_operand:DF 0 "register_operand" "=f")
2128 (mult:DF (float_extend:DF
2129 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2130 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
981a828e 2131 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2132 "mul%-%)%& %R1,%R2,%0"
745466f2 2133 [(set_attr "type" "fmul")
0d4ae18a 2134 (set_attr "trap" "yes")])
36f8f642
RK
2135
2136(define_insn ""
2137 [(set (match_operand:DF 0 "register_operand" "=f")
2138 (mult:DF (float_extend:DF
55ff92b8 2139 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
36f8f642
RK
2140 (float_extend:DF
2141 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
981a828e 2142 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2143 "mul%-%)%& %R1,%R2,%0"
745466f2 2144 [(set_attr "type" "fmul")
0d4ae18a
RK
2145 (set_attr "trap" "yes")])
2146
2147(define_insn ""
2148 [(set (match_operand:SF 0 "register_operand" "=&f")
2149 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2150 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
981a828e 2151 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 2152 "sub%,%)%& %R1,%R2,%0"
745466f2 2153 [(set_attr "type" "fadd")
0d4ae18a 2154 (set_attr "trap" "yes")])
36f8f642
RK
2155
2156(define_insn "subsf3"
2157 [(set (match_operand:SF 0 "register_operand" "=f")
55ff92b8 2158 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
36f8f642
RK
2159 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2160 "TARGET_FP"
477c16e3 2161 "sub%,%)%& %R1,%R2,%0"
745466f2 2162 [(set_attr "type" "fadd")
0d4ae18a
RK
2163 (set_attr "trap" "yes")])
2164
2165(define_insn ""
2166 [(set (match_operand:DF 0 "register_operand" "=&f")
2167 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2168 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
981a828e 2169 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 2170 "sub%-%)%& %R1,%R2,%0"
745466f2 2171 [(set_attr "type" "fadd")
0d4ae18a 2172 (set_attr "trap" "yes")])
36f8f642
RK
2173
2174(define_insn "subdf3"
2175 [(set (match_operand:DF 0 "register_operand" "=f")
55ff92b8 2176 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
36f8f642
RK
2177 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2178 "TARGET_FP"
477c16e3 2179 "sub%-%)%& %R1,%R2,%0"
745466f2 2180 [(set_attr "type" "fadd")
0d4ae18a
RK
2181 (set_attr "trap" "yes")])
2182
36f8f642
RK
2183(define_insn ""
2184 [(set (match_operand:DF 0 "register_operand" "=f")
2185 (minus:DF (float_extend:DF
55ff92b8 2186 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
36f8f642 2187 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
981a828e 2188 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2189 "sub%-%)%& %R1,%R2,%0"
745466f2 2190 [(set_attr "type" "fadd")
0d4ae18a 2191 (set_attr "trap" "yes")])
36f8f642
RK
2192
2193(define_insn ""
2194 [(set (match_operand:DF 0 "register_operand" "=f")
55ff92b8 2195 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
36f8f642
RK
2196 (float_extend:DF
2197 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
981a828e 2198 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2199 "sub%-%)%& %R1,%R2,%0"
745466f2 2200 [(set_attr "type" "fadd")
0d4ae18a 2201 (set_attr "trap" "yes")])
36f8f642
RK
2202
2203(define_insn ""
2204 [(set (match_operand:DF 0 "register_operand" "=f")
2205 (minus:DF (float_extend:DF
55ff92b8 2206 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
36f8f642
RK
2207 (float_extend:DF
2208 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
981a828e 2209 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2210 "sub%-%)%& %R1,%R2,%0"
745466f2 2211 [(set_attr "type" "fadd")
0d4ae18a 2212 (set_attr "trap" "yes")])
e9a25f70 2213
71d9b493
RH
2214(define_insn ""
2215 [(set (match_operand:SF 0 "register_operand" "=&f")
2216 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
981a828e 2217 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
71d9b493
RH
2218 "sqrt%,%)%& %R1,%0"
2219 [(set_attr "type" "fsqrt")
2220 (set_attr "opsize" "si")
2221 (set_attr "trap" "yes")])
2222
e9a25f70
JL
2223(define_insn "sqrtsf2"
2224 [(set (match_operand:SF 0 "register_operand" "=f")
2225 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
de4abb91 2226 "TARGET_FP && TARGET_FIX"
71d9b493
RH
2227 "sqrt%,%)%& %R1,%0"
2228 [(set_attr "type" "fsqrt")
2229 (set_attr "opsize" "si")
e9a25f70
JL
2230 (set_attr "trap" "yes")])
2231
71d9b493
RH
2232(define_insn ""
2233 [(set (match_operand:DF 0 "register_operand" "=&f")
e9a25f70 2234 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
981a828e 2235 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
71d9b493
RH
2236 "sqrt%-%)%& %R1,%0"
2237 [(set_attr "type" "fsqrt")
e9a25f70
JL
2238 (set_attr "trap" "yes")])
2239
71d9b493 2240(define_insn "sqrtdf2"
e9a25f70 2241 [(set (match_operand:DF 0 "register_operand" "=f")
71d9b493 2242 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
de4abb91 2243 "TARGET_FP && TARGET_FIX"
71d9b493
RH
2244 "sqrt%-%)%& %1,%0"
2245 [(set_attr "type" "fsqrt")
e9a25f70 2246 (set_attr "trap" "yes")])
36f8f642
RK
2247\f
2248;; Next are all the integer comparisons, and conditional moves and branches
2249;; and some of the related define_expand's and define_split's.
2250
2251(define_insn ""
2252 [(set (match_operand:DI 0 "register_operand" "=r")
2253 (match_operator:DI 1 "alpha_comparison_operator"
2254 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2255 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
2256 ""
2257 "cmp%C1 %r2,%3,%0"
2258 [(set_attr "type" "icmp")])
2259
5e2a751a
RK
2260(define_insn ""
2261 [(set (match_operand:DI 0 "register_operand" "=r")
86ff8230
RK
2262 (match_operator:DI 1 "alpha_swapped_comparison_operator"
2263 [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
2264 (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
5e2a751a 2265 ""
5148abe9 2266 "cmp%c1 %r3,%2,%0"
5e2a751a
RK
2267 [(set_attr "type" "icmp")])
2268
2ee5c7a8
DE
2269;; This pattern exists so conditional moves of SImode values are handled.
2270;; Comparisons are still done in DImode though.
2271
2272(define_insn ""
2273 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
141dba98 2274 (if_then_else:SI
2ee5c7a8
DE
2275 (match_operator 2 "signed_comparison_operator"
2276 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2277 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2278 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0")
2279 (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
2280 "operands[3] == const0_rtx || operands[4] == const0_rtx"
2281 "@
2282 cmov%C2 %r3,%1,%0
2283 cmov%D2 %r3,%5,%0
2284 cmov%c2 %r4,%1,%0
745466f2 2285 cmov%d2 %r4,%5,%0"
71d9b493 2286 [(set_attr "type" "icmov")])
2ee5c7a8 2287
36f8f642 2288(define_insn ""
03af65c4 2289 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
36f8f642
RK
2290 (if_then_else:DI
2291 (match_operator 2 "signed_comparison_operator"
03af65c4
RK
2292 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2293 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2294 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0,rI,0")
2295 (match_operand:DI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
2296 "operands[3] == const0_rtx || operands[4] == const0_rtx"
36f8f642
RK
2297 "@
2298 cmov%C2 %r3,%1,%0
03af65c4
RK
2299 cmov%D2 %r3,%5,%0
2300 cmov%c2 %r4,%1,%0
745466f2 2301 cmov%d2 %r4,%5,%0"
71d9b493 2302 [(set_attr "type" "icmov")])
36f8f642
RK
2303
2304(define_insn ""
2305 [(set (match_operand:DI 0 "register_operand" "=r,r")
2306 (if_then_else:DI
2307 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2308 (const_int 1)
2309 (const_int 0))
2310 (const_int 0))
2311 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2312 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2313 ""
2314 "@
2315 cmovlbc %r2,%1,%0
745466f2 2316 cmovlbs %r2,%3,%0"
71d9b493 2317 [(set_attr "type" "icmov")])
36f8f642
RK
2318
2319(define_insn ""
2320 [(set (match_operand:DI 0 "register_operand" "=r,r")
2321 (if_then_else:DI
2322 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2323 (const_int 1)
2324 (const_int 0))
2325 (const_int 0))
2326 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2327 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2328 ""
2329 "@
2330 cmovlbs %r2,%1,%0
745466f2 2331 cmovlbc %r2,%3,%0"
71d9b493 2332 [(set_attr "type" "icmov")])
36f8f642 2333
36f8f642
RK
2334;; For ABS, we have two choices, depending on whether the input and output
2335;; registers are the same or not.
2336(define_expand "absdi2"
2337 [(set (match_operand:DI 0 "register_operand" "")
2338 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2339 ""
2340 "
2341{ if (rtx_equal_p (operands[0], operands[1]))
2342 emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
2343 else
2344 emit_insn (gen_absdi2_diff (operands[0], operands[1]));
2345
2346 DONE;
2347}")
2348
2349(define_expand "absdi2_same"
2350 [(set (match_operand:DI 1 "register_operand" "")
2351 (neg:DI (match_operand:DI 0 "register_operand" "")))
2352 (set (match_dup 0)
2353 (if_then_else:DI (ge (match_dup 0) (const_int 0))
2354 (match_dup 0)
2355 (match_dup 1)))]
2356 ""
2357 "")
2358
2359(define_expand "absdi2_diff"
2360 [(set (match_operand:DI 0 "register_operand" "")
2361 (neg:DI (match_operand:DI 1 "register_operand" "")))
2362 (set (match_dup 0)
2363 (if_then_else:DI (lt (match_dup 1) (const_int 0))
2364 (match_dup 0)
2365 (match_dup 1)))]
2366 ""
2367 "")
2368
2369(define_split
2370 [(set (match_operand:DI 0 "register_operand" "")
2371 (abs:DI (match_dup 0)))
2372 (clobber (match_operand:DI 2 "register_operand" ""))]
2373 ""
2374 [(set (match_dup 1) (neg:DI (match_dup 0)))
2375 (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2376 (match_dup 0) (match_dup 1)))]
2377 "")
2378
2379(define_split
2380 [(set (match_operand:DI 0 "register_operand" "")
2381 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2382 "! rtx_equal_p (operands[0], operands[1])"
2383 [(set (match_dup 0) (neg:DI (match_dup 1)))
2384 (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2385 (match_dup 0) (match_dup 1)))]
2386 "")
2387
2388(define_split
2389 [(set (match_operand:DI 0 "register_operand" "")
2390 (neg:DI (abs:DI (match_dup 0))))
2391 (clobber (match_operand:DI 2 "register_operand" ""))]
2392 ""
2393 [(set (match_dup 1) (neg:DI (match_dup 0)))
2394 (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2395 (match_dup 0) (match_dup 1)))]
2396 "")
2397
2398(define_split
2399 [(set (match_operand:DI 0 "register_operand" "")
2400 (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
2401 "! rtx_equal_p (operands[0], operands[1])"
2402 [(set (match_dup 0) (neg:DI (match_dup 1)))
2403 (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2404 (match_dup 0) (match_dup 1)))]
2405 "")
2406
e9a25f70
JL
2407(define_insn "sminqi3"
2408 [(set (match_operand:QI 0 "register_operand" "=r")
141dba98 2409 (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
e9a25f70
JL
2410 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2411 "TARGET_MAX"
2412 "minsb8 %r1,%2,%0"
26250081 2413 [(set_attr "type" "mvi")])
e9a25f70
JL
2414
2415(define_insn "uminqi3"
2416 [(set (match_operand:QI 0 "register_operand" "=r")
141dba98 2417 (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
e9a25f70
JL
2418 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2419 "TARGET_MAX"
2420 "minub8 %r1,%2,%0"
26250081 2421 [(set_attr "type" "mvi")])
e9a25f70
JL
2422
2423(define_insn "smaxqi3"
2424 [(set (match_operand:QI 0 "register_operand" "=r")
141dba98 2425 (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
e9a25f70
JL
2426 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2427 "TARGET_MAX"
2428 "maxsb8 %r1,%2,%0"
26250081 2429 [(set_attr "type" "mvi")])
e9a25f70
JL
2430
2431(define_insn "umaxqi3"
2432 [(set (match_operand:QI 0 "register_operand" "=r")
141dba98 2433 (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
e9a25f70
JL
2434 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2435 "TARGET_MAX"
2436 "maxub8 %r1,%2,%0"
26250081 2437 [(set_attr "type" "mvi")])
e9a25f70
JL
2438
2439(define_insn "sminhi3"
2440 [(set (match_operand:HI 0 "register_operand" "=r")
141dba98 2441 (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
e9a25f70
JL
2442 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2443 "TARGET_MAX"
2444 "minsw4 %r1,%2,%0"
26250081 2445 [(set_attr "type" "mvi")])
e9a25f70
JL
2446
2447(define_insn "uminhi3"
2448 [(set (match_operand:HI 0 "register_operand" "=r")
141dba98 2449 (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
e9a25f70
JL
2450 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2451 "TARGET_MAX"
2452 "minuw4 %r1,%2,%0"
26250081 2453 [(set_attr "type" "mvi")])
e9a25f70
JL
2454
2455(define_insn "smaxhi3"
2456 [(set (match_operand:HI 0 "register_operand" "=r")
141dba98 2457 (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
e9a25f70
JL
2458 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2459 "TARGET_MAX"
2460 "maxsw4 %r1,%2,%0"
26250081 2461 [(set_attr "type" "mvi")])
e9a25f70
JL
2462
2463(define_insn "umaxhi3"
2464 [(set (match_operand:HI 0 "register_operand" "=r")
141dba98 2465 (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
e9a25f70
JL
2466 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2467 "TARGET_MAX"
2468 "maxuw4 %r1,%2,%0"
2469 [(set_attr "type" "shift")])
2470
6412a77e 2471(define_expand "smaxdi3"
36f8f642
RK
2472 [(set (match_dup 3)
2473 (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
2474 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2475 (set (match_operand:DI 0 "register_operand" "")
2476 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2477 (match_dup 1) (match_dup 2)))]
2478 ""
2479 "
2480{ operands[3] = gen_reg_rtx (DImode);
2481}")
2482
2483(define_split
2484 [(set (match_operand:DI 0 "register_operand" "")
2485 (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2486 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2487 (clobber (match_operand:DI 3 "register_operand" ""))]
2488 "operands[2] != const0_rtx"
2489 [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2490 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2491 (match_dup 1) (match_dup 2)))]
2492 "")
2493
2494(define_insn ""
2495 [(set (match_operand:DI 0 "register_operand" "=r")
2496 (smax:DI (match_operand:DI 1 "register_operand" "0")
2497 (const_int 0)))]
2498 ""
745466f2 2499 "cmovlt %0,0,%0"
71d9b493 2500 [(set_attr "type" "icmov")])
36f8f642
RK
2501
2502(define_expand "smindi3"
2503 [(set (match_dup 3)
2504 (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
2505 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2506 (set (match_operand:DI 0 "register_operand" "")
2507 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2508 (match_dup 1) (match_dup 2)))]
2509 ""
2510 "
2511{ operands[3] = gen_reg_rtx (DImode);
2512}")
2513
2514(define_split
2515 [(set (match_operand:DI 0 "register_operand" "")
2516 (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2517 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2518 (clobber (match_operand:DI 3 "register_operand" ""))]
2519 "operands[2] != const0_rtx"
2520 [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2521 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2522 (match_dup 1) (match_dup 2)))]
2523 "")
2524
2525(define_insn ""
2526 [(set (match_operand:DI 0 "register_operand" "=r")
2527 (smin:DI (match_operand:DI 1 "register_operand" "0")
2528 (const_int 0)))]
2529 ""
745466f2 2530 "cmovgt %0,0,%0"
71d9b493 2531 [(set_attr "type" "icmov")])
36f8f642
RK
2532
2533(define_expand "umaxdi3"
2534 [(set (match_dup 3)
2535 (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2536 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2537 (set (match_operand:DI 0 "register_operand" "")
2538 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2539 (match_dup 1) (match_dup 2)))]
2540 ""
2541 "
2542{ operands[3] = gen_reg_rtx (DImode);
2543}")
2544
2545(define_split
2546 [(set (match_operand:DI 0 "register_operand" "")
2547 (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2548 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2549 (clobber (match_operand:DI 3 "register_operand" ""))]
2550 "operands[2] != const0_rtx"
2551 [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2552 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2553 (match_dup 1) (match_dup 2)))]
2554 "")
2555
2556(define_expand "umindi3"
2557 [(set (match_dup 3)
2558 (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2559 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2560 (set (match_operand:DI 0 "register_operand" "")
2561 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2562 (match_dup 1) (match_dup 2)))]
2563 ""
2564 "
2565{ operands[3] = gen_reg_rtx (DImode);
2566}")
2567
2568(define_split
2569 [(set (match_operand:DI 0 "register_operand" "")
2570 (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2571 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2572 (clobber (match_operand:DI 3 "register_operand" ""))]
2573 "operands[2] != const0_rtx"
2574 [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2575 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2576 (match_dup 1) (match_dup 2)))]
2577 "")
2578
2579(define_insn ""
2580 [(set (pc)
2581 (if_then_else
2582 (match_operator 1 "signed_comparison_operator"
2583 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2584 (const_int 0)])
2585 (label_ref (match_operand 0 "" ""))
2586 (pc)))]
2587 ""
2588 "b%C1 %r2,%0"
2589 [(set_attr "type" "ibr")])
2590
86ff8230
RK
2591(define_insn ""
2592 [(set (pc)
2593 (if_then_else
2594 (match_operator 1 "signed_comparison_operator"
2595 [(const_int 0)
2596 (match_operand:DI 2 "register_operand" "r")])
2597 (label_ref (match_operand 0 "" ""))
2598 (pc)))]
2599 ""
2600 "b%c1 %2,%0"
2601 [(set_attr "type" "ibr")])
2602
36f8f642
RK
2603(define_insn ""
2604 [(set (pc)
2605 (if_then_else
2606 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2607 (const_int 1)
2608 (const_int 0))
2609 (const_int 0))
2610 (label_ref (match_operand 0 "" ""))
2611 (pc)))]
2612 ""
2613 "blbs %r1,%0"
2614 [(set_attr "type" "ibr")])
2615
2616(define_insn ""
2617 [(set (pc)
2618 (if_then_else
2619 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2620 (const_int 1)
2621 (const_int 0))
2622 (const_int 0))
2623 (label_ref (match_operand 0 "" ""))
2624 (pc)))]
2625 ""
2626 "blbc %r1,%0"
2627 [(set_attr "type" "ibr")])
2628
2629(define_split
2630 [(parallel
2631 [(set (pc)
2632 (if_then_else
2633 (match_operator 1 "comparison_operator"
2634 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
2635 (const_int 1)
2636 (match_operand:DI 3 "const_int_operand" ""))
2637 (const_int 0)])
2638 (label_ref (match_operand 0 "" ""))
2639 (pc)))
2640 (clobber (match_operand:DI 4 "register_operand" ""))])]
2641 "INTVAL (operands[3]) != 0"
2642 [(set (match_dup 4)
2643 (lshiftrt:DI (match_dup 2) (match_dup 3)))
2644 (set (pc)
2645 (if_then_else (match_op_dup 1
2646 [(zero_extract:DI (match_dup 4)
2647 (const_int 1)
2648 (const_int 0))
2649 (const_int 0)])
2650 (label_ref (match_dup 0))
2651 (pc)))]
2652 "")
2653\f
2654;; The following are the corresponding floating-point insns. Recall
2655;; we need to have variants that expand the arguments from SF mode
2656;; to DFmode.
2657
0d4ae18a
RK
2658(define_insn ""
2659 [(set (match_operand:DF 0 "register_operand" "=&f")
2660 (match_operator:DF 1 "alpha_comparison_operator"
2661 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2662 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
981a828e 2663 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 2664 "cmp%-%C1%' %R2,%R3,%0"
745466f2 2665 [(set_attr "type" "fadd")
0d4ae18a
RK
2666 (set_attr "trap" "yes")])
2667
36f8f642
RK
2668(define_insn ""
2669 [(set (match_operand:DF 0 "register_operand" "=f")
2670 (match_operator:DF 1 "alpha_comparison_operator"
2671 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2672 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
981a828e 2673 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2674 "cmp%-%C1%' %R2,%R3,%0"
745466f2 2675 [(set_attr "type" "fadd")
0d4ae18a 2676 (set_attr "trap" "yes")])
36f8f642 2677
30e2dcbf
RH
2678(define_insn ""
2679 [(set (match_operand:DF 0 "register_operand" "=&f")
2680 (match_operator:DF 1 "alpha_comparison_operator"
2681 [(float_extend:DF
2682 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2683 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
981a828e 2684 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
30e2dcbf
RH
2685 "cmp%-%C1%' %R2,%R3,%0"
2686 [(set_attr "type" "fadd")
2687 (set_attr "trap" "yes")])
2688
36f8f642
RK
2689(define_insn ""
2690 [(set (match_operand:DF 0 "register_operand" "=f")
2691 (match_operator:DF 1 "alpha_comparison_operator"
2692 [(float_extend:DF
2693 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2694 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
981a828e 2695 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2696 "cmp%-%C1%' %R2,%R3,%0"
745466f2 2697 [(set_attr "type" "fadd")
0d4ae18a 2698 (set_attr "trap" "yes")])
36f8f642 2699
30e2dcbf
RH
2700(define_insn ""
2701 [(set (match_operand:DF 0 "register_operand" "=&f")
2702 (match_operator:DF 1 "alpha_comparison_operator"
2703 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2704 (float_extend:DF
2705 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
981a828e 2706 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
30e2dcbf
RH
2707 "cmp%-%C1%' %R2,%R3,%0"
2708 [(set_attr "type" "fadd")
2709 (set_attr "trap" "yes")])
2710
36f8f642
RK
2711(define_insn ""
2712 [(set (match_operand:DF 0 "register_operand" "=f")
2713 (match_operator:DF 1 "alpha_comparison_operator"
2714 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2715 (float_extend:DF
2716 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
981a828e 2717 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
477c16e3 2718 "cmp%-%C1%' %R2,%R3,%0"
745466f2 2719 [(set_attr "type" "fadd")
0d4ae18a 2720 (set_attr "trap" "yes")])
36f8f642
RK
2721
2722(define_insn ""
30e2dcbf 2723 [(set (match_operand:DF 0 "register_operand" "=&f")
36f8f642
RK
2724 (match_operator:DF 1 "alpha_comparison_operator"
2725 [(float_extend:DF
2726 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2727 (float_extend:DF
2728 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
981a828e 2729 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
477c16e3 2730 "cmp%-%C1%' %R2,%R3,%0"
745466f2 2731 [(set_attr "type" "fadd")
0d4ae18a
RK
2732 (set_attr "trap" "yes")])
2733
2734(define_insn ""
30e2dcbf
RH
2735 [(set (match_operand:DF 0 "register_operand" "=f")
2736 (match_operator:DF 1 "alpha_comparison_operator"
2737 [(float_extend:DF
2738 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2739 (float_extend:DF
2740 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
981a828e 2741 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
30e2dcbf
RH
2742 "cmp%-%C1%' %R2,%R3,%0"
2743 [(set_attr "type" "fadd")
2744 (set_attr "trap" "yes")])
36f8f642
RK
2745
2746(define_insn ""
2747 [(set (match_operand:DF 0 "register_operand" "=f,f")
2748 (if_then_else:DF
2749 (match_operator 3 "signed_comparison_operator"
2750 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2751 (match_operand:DF 2 "fp0_operand" "G,G")])
2752 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2753 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
30e2dcbf 2754 "TARGET_FP"
0d4ae18a
RK
2755 "@
2756 fcmov%C3 %R4,%R1,%0
2757 fcmov%D3 %R4,%R5,%0"
71d9b493 2758 [(set_attr "type" "fcmov")])
0d4ae18a 2759
36f8f642
RK
2760(define_insn ""
2761 [(set (match_operand:SF 0 "register_operand" "=f,f")
2762 (if_then_else:SF
2763 (match_operator 3 "signed_comparison_operator"
2764 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2765 (match_operand:DF 2 "fp0_operand" "G,G")])
2766 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2767 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
30e2dcbf 2768 "TARGET_FP"
0d4ae18a
RK
2769 "@
2770 fcmov%C3 %R4,%R1,%0
2771 fcmov%D3 %R4,%R5,%0"
71d9b493 2772 [(set_attr "type" "fcmov")])
0d4ae18a 2773
36f8f642
RK
2774(define_insn ""
2775 [(set (match_operand:DF 0 "register_operand" "=f,f")
2776 (if_then_else:DF
2777 (match_operator 3 "signed_comparison_operator"
161cca9a 2778 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
36f8f642 2779 (match_operand:DF 2 "fp0_operand" "G,G")])
161cca9a 2780 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
36f8f642 2781 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
30e2dcbf 2782 "TARGET_FP"
36f8f642
RK
2783 "@
2784 fcmov%C3 %R4,%R1,%0
2785 fcmov%D3 %R4,%R5,%0"
71d9b493 2786 [(set_attr "type" "fcmov")])
36f8f642
RK
2787
2788(define_insn ""
2789 [(set (match_operand:DF 0 "register_operand" "=f,f")
2790 (if_then_else:DF
2791 (match_operator 3 "signed_comparison_operator"
2792 [(float_extend:DF
2793 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2794 (match_operand:DF 2 "fp0_operand" "G,G")])
2795 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2796 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
30e2dcbf 2797 "TARGET_FP"
0d4ae18a
RK
2798 "@
2799 fcmov%C3 %R4,%R1,%0
2800 fcmov%D3 %R4,%R5,%0"
71d9b493 2801 [(set_attr "type" "fcmov")])
0d4ae18a 2802
36f8f642
RK
2803(define_insn ""
2804 [(set (match_operand:SF 0 "register_operand" "=f,f")
2805 (if_then_else:SF
2806 (match_operator 3 "signed_comparison_operator"
2807 [(float_extend:DF
2808 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2809 (match_operand:DF 2 "fp0_operand" "G,G")])
2810 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2811 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
30e2dcbf 2812 "TARGET_FP"
0d4ae18a
RK
2813 "@
2814 fcmov%C3 %R4,%R1,%0
2815 fcmov%D3 %R4,%R5,%0"
71d9b493 2816 [(set_attr "type" "fcmov")])
0d4ae18a 2817
36f8f642
RK
2818(define_insn ""
2819 [(set (match_operand:DF 0 "register_operand" "=f,f")
2820 (if_then_else:DF
2821 (match_operator 3 "signed_comparison_operator"
2822 [(float_extend:DF
2823 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2824 (match_operand:DF 2 "fp0_operand" "G,G")])
2825 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2826 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
30e2dcbf 2827 "TARGET_FP"
36f8f642
RK
2828 "@
2829 fcmov%C3 %R4,%R1,%0
2830 fcmov%D3 %R4,%R5,%0"
71d9b493 2831 [(set_attr "type" "fcmov")])
36f8f642 2832
f1644e9a 2833(define_expand "maxdf3"
36f8f642
RK
2834 [(set (match_dup 3)
2835 (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2836 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2837 (set (match_operand:DF 0 "register_operand" "")
6db77abd 2838 (if_then_else:DF (eq (match_dup 3) (match_dup 4))
36f8f642
RK
2839 (match_dup 1) (match_dup 2)))]
2840 "TARGET_FP"
2841 "
2842{ operands[3] = gen_reg_rtx (DFmode);
6db77abd 2843 operands[4] = CONST0_RTX (DFmode);
36f8f642
RK
2844}")
2845
f1644e9a 2846(define_expand "mindf3"
36f8f642
RK
2847 [(set (match_dup 3)
2848 (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2849 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2850 (set (match_operand:DF 0 "register_operand" "")
6db77abd 2851 (if_then_else:DF (ne (match_dup 3) (match_dup 4))
36f8f642
RK
2852 (match_dup 1) (match_dup 2)))]
2853 "TARGET_FP"
2854 "
2855{ operands[3] = gen_reg_rtx (DFmode);
6db77abd 2856 operands[4] = CONST0_RTX (DFmode);
36f8f642
RK
2857}")
2858
f1644e9a 2859(define_expand "maxsf3"
36f8f642 2860 [(set (match_dup 3)
2bbc163f 2861 (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
36f8f642
RK
2862 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2863 (set (match_operand:SF 0 "register_operand" "")
2bbc163f 2864 (if_then_else:SF (eq (match_dup 3) (match_dup 4))
36f8f642
RK
2865 (match_dup 1) (match_dup 2)))]
2866 "TARGET_FP"
2867 "
2bbc163f
RK
2868{ operands[3] = gen_reg_rtx (DFmode);
2869 operands[4] = CONST0_RTX (DFmode);
36f8f642
RK
2870}")
2871
f1644e9a 2872(define_expand "minsf3"
36f8f642 2873 [(set (match_dup 3)
2bbc163f 2874 (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
36f8f642
RK
2875 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2876 (set (match_operand:SF 0 "register_operand" "")
6db77abd 2877 (if_then_else:SF (ne (match_dup 3) (match_dup 4))
36f8f642
RK
2878 (match_dup 1) (match_dup 2)))]
2879 "TARGET_FP"
2880 "
2bbc163f
RK
2881{ operands[3] = gen_reg_rtx (DFmode);
2882 operands[4] = CONST0_RTX (DFmode);
36f8f642
RK
2883}")
2884
2885(define_insn ""
2886 [(set (pc)
2887 (if_then_else
2888 (match_operator 1 "signed_comparison_operator"
2889 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2890 (match_operand:DF 3 "fp0_operand" "G")])
2891 (label_ref (match_operand 0 "" ""))
2892 (pc)))]
2893 "TARGET_FP"
2894 "fb%C1 %R2,%0"
2895 [(set_attr "type" "fbr")])
2896
2897(define_insn ""
2898 [(set (pc)
2899 (if_then_else
2900 (match_operator 1 "signed_comparison_operator"
2901 [(float_extend:DF
2902 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2903 (match_operand:DF 3 "fp0_operand" "G")])
2904 (label_ref (match_operand 0 "" ""))
2905 (pc)))]
2906 "TARGET_FP"
2907 "fb%C1 %R2,%0"
2908 [(set_attr "type" "fbr")])
2909\f
2910;; These are the main define_expand's used to make conditional branches
2911;; and compares.
2912
2913(define_expand "cmpdf"
2914 [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
2915 (match_operand:DF 1 "reg_or_fp0_operand" "")))]
0331e642 2916 "TARGET_FP"
36f8f642
RK
2917 "
2918{
2919 alpha_compare_op0 = operands[0];
2920 alpha_compare_op1 = operands[1];
2921 alpha_compare_fp_p = 1;
2922 DONE;
2923}")
2924
2925(define_expand "cmpdi"
2926 [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
2927 (match_operand:DI 1 "reg_or_8bit_operand" "")))]
2928 ""
2929 "
2930{
2931 alpha_compare_op0 = operands[0];
2932 alpha_compare_op1 = operands[1];
2933 alpha_compare_fp_p = 0;
2934 DONE;
2935}")
2936
2937(define_expand "beq"
f283421d
RH
2938 [(set (pc)
2939 (if_then_else (match_dup 1)
36f8f642
RK
2940 (label_ref (match_operand 0 "" ""))
2941 (pc)))]
2942 ""
f283421d 2943 "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
36f8f642
RK
2944
2945(define_expand "bne"
f283421d
RH
2946 [(set (pc)
2947 (if_then_else (match_dup 1)
36f8f642
RK
2948 (label_ref (match_operand 0 "" ""))
2949 (pc)))]
2950 ""
f283421d 2951 "{ operands[1] = alpha_emit_conditional_branch (NE); }")
36f8f642
RK
2952
2953(define_expand "blt"
f283421d
RH
2954 [(set (pc)
2955 (if_then_else (match_dup 1)
36f8f642
RK
2956 (label_ref (match_operand 0 "" ""))
2957 (pc)))]
2958 ""
f283421d 2959 "{ operands[1] = alpha_emit_conditional_branch (LT); }")
36f8f642
RK
2960
2961(define_expand "ble"
f283421d
RH
2962 [(set (pc)
2963 (if_then_else (match_dup 1)
36f8f642
RK
2964 (label_ref (match_operand 0 "" ""))
2965 (pc)))]
2966 ""
f283421d 2967 "{ operands[1] = alpha_emit_conditional_branch (LE); }")
36f8f642
RK
2968
2969(define_expand "bgt"
f283421d
RH
2970 [(set (pc)
2971 (if_then_else (match_dup 1)
36f8f642
RK
2972 (label_ref (match_operand 0 "" ""))
2973 (pc)))]
2974 ""
f283421d 2975 "{ operands[1] = alpha_emit_conditional_branch (GT); }")
36f8f642
RK
2976
2977(define_expand "bge"
f283421d
RH
2978 [(set (pc)
2979 (if_then_else (match_dup 1)
36f8f642
RK
2980 (label_ref (match_operand 0 "" ""))
2981 (pc)))]
2982 ""
f283421d 2983 "{ operands[1] = alpha_emit_conditional_branch (GE); }")
36f8f642
RK
2984
2985(define_expand "bltu"
f283421d
RH
2986 [(set (pc)
2987 (if_then_else (match_dup 1)
36f8f642
RK
2988 (label_ref (match_operand 0 "" ""))
2989 (pc)))]
2990 ""
f283421d 2991 "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
36f8f642
RK
2992
2993(define_expand "bleu"
f283421d
RH
2994 [(set (pc)
2995 (if_then_else (match_dup 1)
36f8f642
RK
2996 (label_ref (match_operand 0 "" ""))
2997 (pc)))]
2998 ""
f283421d 2999 "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
36f8f642
RK
3000
3001(define_expand "bgtu"
f283421d
RH
3002 [(set (pc)
3003 (if_then_else (match_dup 1)
36f8f642
RK
3004 (label_ref (match_operand 0 "" ""))
3005 (pc)))]
3006 ""
f283421d 3007 "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
36f8f642
RK
3008
3009(define_expand "bgeu"
f283421d
RH
3010 [(set (pc)
3011 (if_then_else (match_dup 1)
36f8f642
RK
3012 (label_ref (match_operand 0 "" ""))
3013 (pc)))]
3014 ""
f283421d 3015 "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
36f8f642
RK
3016
3017(define_expand "seq"
3018 [(set (match_operand:DI 0 "register_operand" "")
3019 (match_dup 1))]
3020 ""
3021 "
3022{
3023 if (alpha_compare_fp_p)
3024 FAIL;
3025
38a448ca 3026 operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
36f8f642
RK
3027}")
3028
3029(define_expand "sne"
3030 [(set (match_operand:DI 0 "register_operand" "")
3031 (match_dup 1))
3032 (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
3033 ""
3034 "
3035{
3036 if (alpha_compare_fp_p)
3037 FAIL;
3038
38a448ca 3039 operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
36f8f642
RK
3040}")
3041
3042(define_expand "slt"
3043 [(set (match_operand:DI 0 "register_operand" "")
3044 (match_dup 1))]
3045 ""
3046 "
3047{
3048 if (alpha_compare_fp_p)
3049 FAIL;
3050
38a448ca 3051 operands[1] = gen_rtx_LT (DImode, alpha_compare_op0, alpha_compare_op1);
36f8f642
RK
3052}")
3053
3054(define_expand "sle"
3055 [(set (match_operand:DI 0 "register_operand" "")
3056 (match_dup 1))]
3057 ""
3058 "
3059{
3060 if (alpha_compare_fp_p)
3061 FAIL;
3062
38a448ca 3063 operands[1] = gen_rtx_LE (DImode, alpha_compare_op0, alpha_compare_op1);
36f8f642
RK
3064}")
3065
3066(define_expand "sgt"
3067 [(set (match_operand:DI 0 "register_operand" "")
3068 (match_dup 1))]
3069 ""
3070 "
3071{
3072 if (alpha_compare_fp_p)
3073 FAIL;
3074
38a448ca
RH
3075 operands[1] = gen_rtx_LT (DImode, force_reg (DImode, alpha_compare_op1),
3076 alpha_compare_op0);
36f8f642
RK
3077}")
3078
3079(define_expand "sge"
3080 [(set (match_operand:DI 0 "register_operand" "")
3081 (match_dup 1))]
3082 ""
3083 "
3084{
3085 if (alpha_compare_fp_p)
3086 FAIL;
3087
38a448ca
RH
3088 operands[1] = gen_rtx_LE (DImode, force_reg (DImode, alpha_compare_op1),
3089 alpha_compare_op0);
36f8f642
RK
3090}")
3091
3092(define_expand "sltu"
3093 [(set (match_operand:DI 0 "register_operand" "")
3094 (match_dup 1))]
3095 ""
3096 "
3097{
3098 if (alpha_compare_fp_p)
3099 FAIL;
3100
38a448ca 3101 operands[1] = gen_rtx_LTU (DImode, alpha_compare_op0, alpha_compare_op1);
36f8f642
RK
3102}")
3103
3104(define_expand "sleu"
3105 [(set (match_operand:DI 0 "register_operand" "")
3106 (match_dup 1))]
3107 ""
3108 "
3109{
3110 if (alpha_compare_fp_p)
3111 FAIL;
3112
38a448ca 3113 operands[1] = gen_rtx_LEU (DImode, alpha_compare_op0, alpha_compare_op1);
36f8f642
RK
3114}")
3115
3116(define_expand "sgtu"
3117 [(set (match_operand:DI 0 "register_operand" "")
3118 (match_dup 1))]
3119 ""
3120 "
3121{
3122 if (alpha_compare_fp_p)
3123 FAIL;
3124
38a448ca
RH
3125 operands[1] = gen_rtx_LTU (DImode, force_reg (DImode, alpha_compare_op1),
3126 alpha_compare_op0);
36f8f642
RK
3127}")
3128
3129(define_expand "sgeu"
3130 [(set (match_operand:DI 0 "register_operand" "")
3131 (match_dup 1))]
3132 ""
3133 "
3134{
3135 if (alpha_compare_fp_p)
3136 FAIL;
3137
38a448ca
RH
3138 operands[1] = gen_rtx_LEU (DImode, force_reg (DImode, alpha_compare_op1),
3139 alpha_compare_op0);
36f8f642
RK
3140}")
3141\f
2ee5c7a8
DE
3142;; These are the main define_expand's used to make conditional moves.
3143
3144(define_expand "movsicc"
3cabb540 3145 [(set (match_operand:SI 0 "register_operand" "")
c7dec7c2 3146 (if_then_else:SI (match_operand 1 "comparison_operator" "")
2ee5c7a8
DE
3147 (match_operand:SI 2 "reg_or_8bit_operand" "")
3148 (match_operand:SI 3 "reg_or_8bit_operand" "")))]
3149 ""
3150 "
3151{
3cabb540 3152 if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
2ee5c7a8 3153 FAIL;
2ee5c7a8
DE
3154}")
3155
3156(define_expand "movdicc"
3cabb540
RK
3157 [(set (match_operand:DI 0 "register_operand" "")
3158 (if_then_else:DI (match_operand 1 "comparison_operator" "")
2ee5c7a8
DE
3159 (match_operand:DI 2 "reg_or_8bit_operand" "")
3160 (match_operand:DI 3 "reg_or_8bit_operand" "")))]
3161 ""
3162 "
3163{
3cabb540 3164 if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
2ee5c7a8 3165 FAIL;
2ee5c7a8
DE
3166}")
3167
3168(define_expand "movsfcc"
3cabb540
RK
3169 [(set (match_operand:SF 0 "register_operand" "")
3170 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3171 (match_operand:SF 2 "reg_or_8bit_operand" "")
3172 (match_operand:SF 3 "reg_or_8bit_operand" "")))]
2ee5c7a8
DE
3173 ""
3174 "
3175{
3cabb540 3176 if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
2ee5c7a8 3177 FAIL;
2ee5c7a8
DE
3178}")
3179
3180(define_expand "movdfcc"
3cabb540
RK
3181 [(set (match_operand:DF 0 "register_operand" "")
3182 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3183 (match_operand:DF 2 "reg_or_8bit_operand" "")
3184 (match_operand:DF 3 "reg_or_8bit_operand" "")))]
2ee5c7a8
DE
3185 ""
3186 "
3187{
3cabb540 3188 if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
2ee5c7a8 3189 FAIL;
2ee5c7a8
DE
3190}")
3191\f
36f8f642
RK
3192;; These define_split definitions are used in cases when comparisons have
3193;; not be stated in the correct way and we need to reverse the second
3194;; comparison. For example, x >= 7 has to be done as x < 6 with the
3195;; comparison that tests the result being reversed. We have one define_split
3196;; for each use of a comparison. They do not match valid insns and need
3197;; not generate valid insns.
3198;;
3199;; We can also handle equality comparisons (and inequality comparisons in
26958509
RK
3200;; cases where the resulting add cannot overflow) by doing an add followed by
3201;; a comparison with zero. This is faster since the addition takes one
3202;; less cycle than a compare when feeding into a conditional move.
3203;; For this case, we also have an SImode pattern since we can merge the add
3204;; and sign extend and the order doesn't matter.
36f8f642
RK
3205;;
3206;; We do not do this for floating-point, since it isn't clear how the "wrong"
3207;; operation could have been generated.
3208
3209(define_split
3210 [(set (match_operand:DI 0 "register_operand" "")
3211 (if_then_else:DI
3212 (match_operator 1 "comparison_operator"
3213 [(match_operand:DI 2 "reg_or_0_operand" "")
3214 (match_operand:DI 3 "reg_or_cint_operand" "")])
3215 (match_operand:DI 4 "reg_or_cint_operand" "")
3216 (match_operand:DI 5 "reg_or_cint_operand" "")))
3217 (clobber (match_operand:DI 6 "register_operand" ""))]
3218 "operands[3] != const0_rtx"
3219 [(set (match_dup 6) (match_dup 7))
3220 (set (match_dup 0)
3221 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3222 "
3223{ enum rtx_code code = GET_CODE (operands[1]);
3224 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3225
3226 /* If we are comparing for equality with a constant and that constant
3227 appears in the arm when the register equals the constant, use the
3228 register since that is more likely to match (and to produce better code
3229 if both would). */
3230
3231 if (code == EQ && GET_CODE (operands[3]) == CONST_INT
3232 && rtx_equal_p (operands[4], operands[3]))
3233 operands[4] = operands[2];
3234
3235 else if (code == NE && GET_CODE (operands[3]) == CONST_INT
3236 && rtx_equal_p (operands[5], operands[3]))
3237 operands[5] = operands[2];
3238
26958509
RK
3239 if (code == NE || code == EQ
3240 || (extended_count (operands[2], DImode, unsignedp) >= 1
3241 && extended_count (operands[3], DImode, unsignedp) >= 1))
36f8f642 3242 {
26958509 3243 if (GET_CODE (operands[3]) == CONST_INT)
38a448ca
RH
3244 operands[7] = gen_rtx_PLUS (DImode, operands[2],
3245 GEN_INT (- INTVAL (operands[3])));
26958509 3246 else
38a448ca 3247 operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
26958509 3248
38a448ca 3249 operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
36f8f642
RK
3250 }
3251
3252 else if (code == EQ || code == LE || code == LT
3253 || code == LEU || code == LTU)
3254 {
38a448ca
RH
3255 operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3256 operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
36f8f642
RK
3257 }
3258 else
3259 {
38a448ca
RH
3260 operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3261 operands[2], operands[3]);
3262 operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
36f8f642
RK
3263 }
3264}")
3265
3266(define_split
3267 [(set (match_operand:DI 0 "register_operand" "")
3268 (if_then_else:DI
3269 (match_operator 1 "comparison_operator"
3270 [(match_operand:SI 2 "reg_or_0_operand" "")
26958509 3271 (match_operand:SI 3 "reg_or_cint_operand" "")])
36f8f642
RK
3272 (match_operand:DI 4 "reg_or_8bit_operand" "")
3273 (match_operand:DI 5 "reg_or_8bit_operand" "")))
3274 (clobber (match_operand:DI 6 "register_operand" ""))]
26958509
RK
3275 "operands[3] != const0_rtx
3276 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
36f8f642
RK
3277 [(set (match_dup 6) (match_dup 7))
3278 (set (match_dup 0)
3279 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3280 "
3281{ enum rtx_code code = GET_CODE (operands[1]);
3282 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
26958509 3283 rtx tem;
36f8f642
RK
3284
3285 if ((code != NE && code != EQ
3286 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3287 && extended_count (operands[3], DImode, unsignedp) >= 1)))
3288 FAIL;
3289
26958509 3290 if (GET_CODE (operands[3]) == CONST_INT)
38a448ca
RH
3291 tem = gen_rtx_PLUS (SImode, operands[2],
3292 GEN_INT (- INTVAL (operands[3])));
26958509 3293 else
38a448ca 3294 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
26958509 3295
38a448ca
RH
3296 operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3297 operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3298 operands[6], const0_rtx);
36f8f642
RK
3299}")
3300
3301(define_split
3302 [(set (pc)
3303 (if_then_else
3304 (match_operator 1 "comparison_operator"
3305 [(match_operand:DI 2 "reg_or_0_operand" "")
3306 (match_operand:DI 3 "reg_or_cint_operand" "")])
3307 (label_ref (match_operand 0 "" ""))
3308 (pc)))
3309 (clobber (match_operand:DI 4 "register_operand" ""))]
3310 "operands[3] != const0_rtx"
3311 [(set (match_dup 4) (match_dup 5))
3312 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3313 "
3314{ enum rtx_code code = GET_CODE (operands[1]);
3315 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3316
26958509
RK
3317 if (code == NE || code == EQ
3318 || (extended_count (operands[2], DImode, unsignedp) >= 1
3319 && extended_count (operands[3], DImode, unsignedp) >= 1))
36f8f642 3320 {
26958509 3321 if (GET_CODE (operands[3]) == CONST_INT)
38a448ca
RH
3322 operands[5] = gen_rtx_PLUS (DImode, operands[2],
3323 GEN_INT (- INTVAL (operands[3])));
26958509 3324 else
38a448ca 3325 operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
26958509 3326
38a448ca 3327 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
36f8f642
RK
3328 }
3329
3330 else if (code == EQ || code == LE || code == LT
3331 || code == LEU || code == LTU)
3332 {
38a448ca
RH
3333 operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3334 operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
36f8f642
RK
3335 }
3336 else
3337 {
38a448ca
RH
3338 operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3339 operands[2], operands[3]);
3340 operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
36f8f642
RK
3341 }
3342}")
3343
3344(define_split
3345 [(set (pc)
3346 (if_then_else
3347 (match_operator 1 "comparison_operator"
3348 [(match_operand:SI 2 "reg_or_0_operand" "")
3349 (match_operand:SI 3 "const_int_operand" "")])
3350 (label_ref (match_operand 0 "" ""))
3351 (pc)))
3352 (clobber (match_operand:DI 4 "register_operand" ""))]
26958509 3353 "operands[3] != const0_rtx
36f8f642
RK
3354 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3355 [(set (match_dup 4) (match_dup 5))
3356 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3357 "
26958509
RK
3358{ rtx tem;
3359
3360 if (GET_CODE (operands[3]) == CONST_INT)
38a448ca
RH
3361 tem = gen_rtx_PLUS (SImode, operands[2],
3362 GEN_INT (- INTVAL (operands[3])));
26958509 3363 else
38a448ca 3364 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
26958509 3365
38a448ca
RH
3366 operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
3367 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3368 operands[4], const0_rtx);
36f8f642 3369}")
3797f4d4 3370
1c2bdc60 3371;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
3797f4d4
RK
3372;; This eliminates one, and sometimes two, insns when the AND can be done
3373;; with a ZAP.
3374(define_split
3375 [(set (match_operand:DI 0 "register_operand" "")
3376 (match_operator 1 "comparison_operator"
3377 [(match_operand:DI 2 "register_operand" "")
3378 (match_operand:DI 3 "const_int_operand" "")]))
3379 (clobber (match_operand:DI 4 "register_operand" ""))]
3380 "exact_log2 (INTVAL (operands[3]) + 1) >= 0
3381 && (GET_CODE (operands[1]) == GTU
3382 || GET_CODE (operands[1]) == LEU
3383 || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
3384 && extended_count (operands[2], DImode, 1) > 0))"
1c2bdc60
RK
3385 [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
3386 (set (match_dup 0) (match_dup 6))]
3797f4d4
RK
3387 "
3388{
1c2bdc60 3389 operands[5] = GEN_INT (~ INTVAL (operands[3]));
38a448ca
RH
3390 operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
3391 || GET_CODE (operands[1]) == GT)
3392 ? NE : EQ),
3393 DImode, operands[4], const0_rtx);
3797f4d4 3394}")
36f8f642 3395\f
55e70146
RK
3396;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
3397;; work differently, so we have different patterns for each.
36f8f642
RK
3398
3399(define_expand "call"
55e70146 3400 [(use (match_operand:DI 0 "" ""))
477c16e3
RK
3401 (use (match_operand 1 "" ""))
3402 (use (match_operand 2 "" ""))
3403 (use (match_operand 3 "" ""))]
55e70146
RK
3404 ""
3405 "
5421b3d0 3406{ if (TARGET_WINDOWS_NT)
55e70146 3407 emit_call_insn (gen_call_nt (operands[0], operands[1]));
477c16e3
RK
3408 else if (TARGET_OPEN_VMS)
3409 emit_call_insn (gen_call_vms (operands[0], operands[2]));
55e70146
RK
3410 else
3411 emit_call_insn (gen_call_osf (operands[0], operands[1]));
3412
3413 DONE;
3414}")
3415
3416(define_expand "call_osf"
cc2394a4 3417 [(parallel [(call (mem:DI (match_operand 0 "" ""))
36f8f642 3418 (match_operand 1 "" ""))
cc2394a4 3419 (clobber (reg:DI 27))
36f8f642
RK
3420 (clobber (reg:DI 26))])]
3421 ""
3422 "
3423{ if (GET_CODE (operands[0]) != MEM)
3424 abort ();
36f8f642 3425
cc2394a4 3426 operands[0] = XEXP (operands[0], 0);
36f8f642 3427
cc2394a4
RK
3428 if (GET_CODE (operands[0]) != SYMBOL_REF
3429 && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
3430 {
38a448ca 3431 rtx tem = gen_rtx_REG (DImode, 27);
cc2394a4
RK
3432 emit_move_insn (tem, operands[0]);
3433 operands[0] = tem;
3434 }
36f8f642
RK
3435}")
3436
55e70146 3437(define_expand "call_nt"
202f590e 3438 [(parallel [(call (mem:DI (match_operand 0 "" ""))
55e70146
RK
3439 (match_operand 1 "" ""))
3440 (clobber (reg:DI 26))])]
3441 ""
3442 "
3443{ if (GET_CODE (operands[0]) != MEM)
3444 abort ();
55e70146 3445
202f590e
RH
3446 operands[0] = XEXP (operands[0], 0);
3447 if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
3448 operands[0] = force_reg (DImode, operands[0]);
55e70146
RK
3449}")
3450
477c16e3
RK
3451;;
3452;; call openvms/alpha
3453;; op 0: symbol ref for called function
3454;; op 1: next_arg_reg (argument information value for R25)
3455;;
3456(define_expand "call_vms"
3457 [(parallel [(call (mem:DI (match_operand 0 "" ""))
3458 (match_operand 1 "" ""))
3459 (use (match_dup 2))
3460 (use (reg:DI 25))
3461 (use (reg:DI 26))
3462 (clobber (reg:DI 27))])]
3463 ""
3464 "
3465{ if (GET_CODE (operands[0]) != MEM)
3466 abort ();
3467
3468 operands[0] = XEXP (operands[0], 0);
3469
3470 /* Always load AI with argument information, then handle symbolic and
3471 indirect call differently. Load RA and set operands[2] to PV in
3472 both cases. */
3473
38a448ca 3474 emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
477c16e3
RK
3475 if (GET_CODE (operands[0]) == SYMBOL_REF)
3476 {
3477 extern char *savealloc ();
a59fb797 3478 char *linksym, *symbol = XSTR (operands[0], 0);
477c16e3
RK
3479 rtx linkage;
3480
a59fb797
KK
3481 if (*symbol == '*')
3482 symbol++;
3483 linksym = savealloc (strlen (symbol) + 6);
3484
477c16e3
RK
3485 alpha_need_linkage (symbol, 0);
3486
531ea24e
RH
3487 linksym[0] = '$';
3488 strcpy (linksym+1, symbol);
477c16e3 3489 strcat (linksym, \"..lk\");
38a448ca 3490 linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
477c16e3 3491
38a448ca 3492 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
477c16e3
RK
3493
3494 operands[2]
38a448ca 3495 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
477c16e3
RK
3496 }
3497 else
3498 {
38a448ca
RH
3499 emit_move_insn (gen_rtx_REG (Pmode, 26),
3500 gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
477c16e3
RK
3501
3502 operands[2] = operands[0];
3503 }
3504
3505}")
3506
36f8f642 3507(define_expand "call_value"
55e70146
RK
3508 [(use (match_operand 0 "" ""))
3509 (use (match_operand:DI 1 "" ""))
477c16e3
RK
3510 (use (match_operand 2 "" ""))
3511 (use (match_operand 3 "" ""))
3512 (use (match_operand 4 "" ""))]
55e70146
RK
3513 ""
3514 "
5421b3d0 3515{ if (TARGET_WINDOWS_NT)
55e70146 3516 emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
477c16e3
RK
3517 else if (TARGET_OPEN_VMS)
3518 emit_call_insn (gen_call_value_vms (operands[0], operands[1],
3519 operands[3]));
55e70146
RK
3520 else
3521 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
3522 operands[2]));
3523 DONE;
3524}")
3525
3526(define_expand "call_value_osf"
36f8f642 3527 [(parallel [(set (match_operand 0 "" "")
cc2394a4 3528 (call (mem:DI (match_operand 1 "" ""))
36f8f642 3529 (match_operand 2 "" "")))
cc2394a4 3530 (clobber (reg:DI 27))
36f8f642
RK
3531 (clobber (reg:DI 26))])]
3532 ""
3533 "
3534{ if (GET_CODE (operands[1]) != MEM)
3535 abort ();
3536
3537 operands[1] = XEXP (operands[1], 0);
3538
cc2394a4
RK
3539 if (GET_CODE (operands[1]) != SYMBOL_REF
3540 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3541 {
38a448ca 3542 rtx tem = gen_rtx_REG (DImode, 27);
cc2394a4
RK
3543 emit_move_insn (tem, operands[1]);
3544 operands[1] = tem;
3545 }
36f8f642
RK
3546}")
3547
55e70146
RK
3548(define_expand "call_value_nt"
3549 [(parallel [(set (match_operand 0 "" "")
202f590e 3550 (call (mem:DI (match_operand 1 "" ""))
55e70146
RK
3551 (match_operand 2 "" "")))
3552 (clobber (reg:DI 26))])]
3553 ""
3554 "
3555{ if (GET_CODE (operands[1]) != MEM)
3556 abort ();
3557
3558 operands[1] = XEXP (operands[1], 0);
5b9ba539 3559 if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
202f590e 3560 operands[1] = force_reg (DImode, operands[1]);
55e70146
RK
3561}")
3562
477c16e3
RK
3563(define_expand "call_value_vms"
3564 [(parallel [(set (match_operand 0 "" "")
3565 (call (mem:DI (match_operand:DI 1 "" ""))
3566 (match_operand 2 "" "")))
3567 (use (match_dup 3))
3568 (use (reg:DI 25))
3569 (use (reg:DI 26))
3570 (clobber (reg:DI 27))])]
3571 ""
3572 "
3573{ if (GET_CODE (operands[1]) != MEM)
3574 abort ();
3575
3576 operands[1] = XEXP (operands[1], 0);
3577
3578 /* Always load AI with argument information, then handle symbolic and
3579 indirect call differently. Load RA and set operands[3] to PV in
3580 both cases. */
3581
38a448ca 3582 emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
477c16e3
RK
3583 if (GET_CODE (operands[1]) == SYMBOL_REF)
3584 {
3585 extern char *savealloc ();
a59fb797 3586 char *linksym, *symbol = XSTR (operands[1], 0);
477c16e3
RK
3587 rtx linkage;
3588
a59fb797
KK
3589 if (*symbol == '*')
3590 symbol++;
3591 linksym = savealloc (strlen (symbol) + 6);
3592
477c16e3 3593 alpha_need_linkage (symbol, 0);
531ea24e
RH
3594 linksym[0] = '$';
3595 strcpy (linksym+1, symbol);
477c16e3 3596 strcat (linksym, \"..lk\");
38a448ca 3597 linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
477c16e3 3598
38a448ca 3599 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
477c16e3
RK
3600
3601 operands[3]
38a448ca 3602 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
477c16e3
RK
3603 }
3604 else
3605 {
38a448ca
RH
3606 emit_move_insn (gen_rtx_REG (Pmode, 26),
3607 gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
477c16e3
RK
3608
3609 operands[3] = operands[1];
3610 }
3611}")
3612
36f8f642 3613(define_insn ""
cc2394a4
RK
3614 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3615 (match_operand 1 "" ""))
3616 (clobber (reg:DI 27))
36f8f642 3617 (clobber (reg:DI 26))]
477c16e3 3618 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
cc2394a4
RK
3619 "@
3620 jsr $26,($27),0\;ldgp $29,0($26)
531ea24e 3621 bsr $26,$%0..ng
cc2394a4 3622 jsr $26,%0\;ldgp $29,0($26)"
9c0e94a5 3623 [(set_attr "type" "jsr")
8cad673c 3624 (set_attr "length" "12,*,16")])
36f8f642 3625
55e70146 3626(define_insn ""
202f590e 3627 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
55e70146
RK
3628 (match_operand 1 "" ""))
3629 (clobber (reg:DI 26))]
5421b3d0 3630 "TARGET_WINDOWS_NT"
55e70146
RK
3631 "@
3632 jsr $26,(%0)
202f590e
RH
3633 bsr $26,%0
3634 jsr $26,%0"
9c0e94a5
RH
3635 [(set_attr "type" "jsr")
3636 (set_attr "length" "*,*,12")])
55e70146 3637
477c16e3
RK
3638(define_insn ""
3639 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
3640 (match_operand 1 "" ""))
3641 (use (match_operand:DI 2 "general_operand" "r,m"))
3642 (use (reg:DI 25))
3643 (use (reg:DI 26))
3644 (clobber (reg:DI 27))]
3645 "TARGET_OPEN_VMS"
3646 "@
6ce652e0 3647 mov %2,$27\;jsr $26,0\;ldq $27,0($29)
477c16e3 3648 ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
9c0e94a5
RH
3649 [(set_attr "type" "jsr")
3650 (set_attr "length" "12,16")])
477c16e3 3651
36f8f642 3652(define_insn ""
cc2394a4
RK
3653 [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3654 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
36f8f642 3655 (match_operand 2 "" "")))
cc2394a4 3656 (clobber (reg:DI 27))
36f8f642 3657 (clobber (reg:DI 26))]
477c16e3 3658 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
cc2394a4
RK
3659 "@
3660 jsr $26,($27),0\;ldgp $29,0($26)
531ea24e 3661 bsr $26,$%1..ng
cc2394a4 3662 jsr $26,%1\;ldgp $29,0($26)"
9c0e94a5 3663 [(set_attr "type" "jsr")
8cad673c 3664 (set_attr "length" "12,*,16")])
36f8f642 3665
55e70146 3666(define_insn ""
202f590e
RH
3667 [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3668 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
55e70146
RK
3669 (match_operand 2 "" "")))
3670 (clobber (reg:DI 26))]
5421b3d0 3671 "TARGET_WINDOWS_NT"
55e70146
RK
3672 "@
3673 jsr $26,(%1)
202f590e
RH
3674 bsr $26,%1
3675 jsr $26,%1"
9c0e94a5
RH
3676 [(set_attr "type" "jsr")
3677 (set_attr "length" "*,*,12")])
55e70146 3678
477c16e3
RK
3679(define_insn ""
3680 [(set (match_operand 0 "register_operand" "")
3681 (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
3682 (match_operand 2 "" "")))
3683 (use (match_operand:DI 3 "general_operand" "r,m"))
3684 (use (reg:DI 25))
3685 (use (reg:DI 26))
3686 (clobber (reg:DI 27))]
3687 "TARGET_OPEN_VMS"
3688 "@
6ce652e0 3689 mov %3,$27\;jsr $26,0\;ldq $27,0($29)
477c16e3 3690 ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
9c0e94a5
RH
3691 [(set_attr "type" "jsr")
3692 (set_attr "length" "12,16")])
477c16e3 3693
e6f948e3
RK
3694;; Call subroutine returning any type.
3695
3696(define_expand "untyped_call"
3697 [(parallel [(call (match_operand 0 "" "")
3698 (const_int 0))
3699 (match_operand 1 "" "")
3700 (match_operand 2 "" "")])]
3701 ""
3702 "
3703{
3704 int i;
3705
3706 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3707
3708 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3709 {
3710 rtx set = XVECEXP (operands[2], 0, i);
3711 emit_move_insn (SET_DEST (set), SET_SRC (set));
3712 }
3713
3714 /* The optimizer does not know that the call sets the function value
3715 registers we stored in the result block. We avoid problems by
3716 claiming that all hard registers are used and clobbered at this
3717 point. */
3718 emit_insn (gen_blockage ());
3719
3720 DONE;
3721}")
3722
3723;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3724;; all of memory. This blocks insns from being moved across this point.
3725
3726(define_insn "blockage"
818913ea 3727 [(unspec_volatile [(const_int 0)] 1)]
e6f948e3 3728 ""
9c0e94a5
RH
3729 ""
3730 [(set_attr "length" "0")])
e6f948e3 3731
36f8f642
RK
3732(define_insn "jump"
3733 [(set (pc)
3734 (label_ref (match_operand 0 "" "")))]
3735 ""
3736 "br $31,%l0"
3737 [(set_attr "type" "ibr")])
3738
3739(define_insn "return"
3740 [(return)]
3741 "direct_return ()"
3742 "ret $31,($26),1"
3743 [(set_attr "type" "ibr")])
3744
9c0e94a5
RH
3745;; Use a different pattern for functions which have non-trivial
3746;; epilogues so as not to confuse jump and reorg.
3747(define_insn "return_internal"
3748 [(use (reg:DI 26))
3749 (return)]
3750 ""
3751 "ret $31,($26),1"
3752 [(set_attr "type" "ibr")])
3753
36f8f642
RK
3754(define_insn "indirect_jump"
3755 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3756 ""
3757 "jmp $31,(%0),0"
3758 [(set_attr "type" "ibr")])
3759
36f8f642 3760(define_expand "tablejump"
55e70146
RK
3761 [(use (match_operand:SI 0 "register_operand" ""))
3762 (use (match_operand:SI 1 "" ""))]
3763 ""
3764 "
3765{
5421b3d0 3766 if (TARGET_WINDOWS_NT)
55e70146 3767 emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
477c16e3
RK
3768 else if (TARGET_OPEN_VMS)
3769 emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
55e70146
RK
3770 else
3771 emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
3772
3773 DONE;
3774}")
3775
3776(define_expand "tablejump_osf"
36f8f642
RK
3777 [(set (match_dup 3)
3778 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
96c9d70d
RK
3779 (parallel [(set (pc)
3780 (plus:DI (match_dup 3)
3781 (label_ref:DI (match_operand 1 "" ""))))
36f8f642
RK
3782 (clobber (match_scratch:DI 2 "=r"))])]
3783 ""
3784 "
3785{ operands[3] = gen_reg_rtx (DImode); }")
3786
55e70146
RK
3787(define_expand "tablejump_nt"
3788 [(set (match_dup 3)
3789 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3790 (parallel [(set (pc)
3791 (match_dup 3))
3792 (use (label_ref (match_operand 1 "" "")))])]
3793 ""
3794 "
3795{ operands[3] = gen_reg_rtx (DImode); }")
3796
477c16e3
RK
3797;;
3798;; tablejump, openVMS way
3799;; op 0: offset
3800;; op 1: label preceding jump-table
3801;;
3802(define_expand "tablejump_vms"
3803 [(set (match_dup 2)
3804 (match_operand:DI 0 "register_operand" ""))
3805 (set (pc)
3806 (plus:DI (match_dup 2)
3807 (label_ref:DI (match_operand 1 "" ""))))]
3808 ""
3809 "
3810{ operands[2] = gen_reg_rtx (DImode); }")
3811
36f8f642
RK
3812(define_insn ""
3813 [(set (pc)
3814 (plus:DI (match_operand:DI 0 "register_operand" "r")
96c9d70d 3815 (label_ref:DI (match_operand 1 "" ""))))
36f8f642 3816 (clobber (match_scratch:DI 2 "=r"))]
477c16e3 3817 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
96c9d70d
RK
3818 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3819 && PREV_INSN (next_active_insn (insn)) == operands[1]"
36f8f642
RK
3820 "*
3821{ rtx best_label = 0;
3822 rtx jump_table_insn = next_active_insn (operands[1]);
3823
3824 if (GET_CODE (jump_table_insn) == JUMP_INSN
96c9d70d 3825 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
36f8f642
RK
3826 {
3827 rtx jump_table = PATTERN (jump_table_insn);
96c9d70d 3828 int n_labels = XVECLEN (jump_table, 1);
36f8f642
RK
3829 int best_count = -1;
3830 int i, j;
3831
3832 for (i = 0; i < n_labels; i++)
3833 {
3834 int count = 1;
3835
3836 for (j = i + 1; j < n_labels; j++)
96c9d70d
RK
3837 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3838 == XEXP (XVECEXP (jump_table, 1, j), 0))
36f8f642
RK
3839 count++;
3840
3841 if (count > best_count)
96c9d70d 3842 best_count = count, best_label = XVECEXP (jump_table, 1, i);
36f8f642
RK
3843 }
3844 }
3845
3846 if (best_label)
3847 {
3848 operands[3] = best_label;
3849 return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
3850 }
3851 else
3852 return \"addq %0,$29,%2\;jmp $31,(%2),0\";
3853}"
9c0e94a5
RH
3854 [(set_attr "type" "ibr")
3855 (set_attr "length" "8")])
190315a7 3856
55e70146
RK
3857(define_insn ""
3858 [(set (pc)
3859 (match_operand:DI 0 "register_operand" "r"))
3860 (use (label_ref (match_operand 1 "" "")))]
5421b3d0 3861 "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
55e70146
RK
3862 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3863 && PREV_INSN (next_active_insn (insn)) == operands[1]"
3864 "*
3865{ rtx best_label = 0;
3866 rtx jump_table_insn = next_active_insn (operands[1]);
3867
3868 if (GET_CODE (jump_table_insn) == JUMP_INSN
3869 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3870 {
3871 rtx jump_table = PATTERN (jump_table_insn);
3872 int n_labels = XVECLEN (jump_table, 1);
3873 int best_count = -1;
3874 int i, j;
3875
3876 for (i = 0; i < n_labels; i++)
3877 {
3878 int count = 1;
3879
3880 for (j = i + 1; j < n_labels; j++)
3881 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3882 == XEXP (XVECEXP (jump_table, 1, j), 0))
3883 count++;
3884
3885 if (count > best_count)
3886 best_count = count, best_label = XVECEXP (jump_table, 1, i);
3887 }
3888 }
3889
3890 if (best_label)
3891 {
3892 operands[2] = best_label;
3893 return \"jmp $31,(%0),%2\";
3894 }
3895 else
3896 return \"jmp $31,(%0),0\";
3897}"
3898 [(set_attr "type" "ibr")])
3899
477c16e3
RK
3900;;
3901;; op 0 is table offset
3902;; op 1 is table label
3903;;
3904
3905(define_insn ""
3906 [(set (pc)
3907 (plus:DI (match_operand 0 "register_operand" "r")
3908 (label_ref (match_operand 1 "" ""))))]
3909 "TARGET_OPEN_VMS"
3910 "jmp $31,(%0),0"
3911 [(set_attr "type" "ibr")])
3912
190315a7
RK
3913;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't
3914;; want to have to include pal.h in our .s file.
9ecc37f0
RH
3915;;
3916;; Technically the type for call_pal is jsr, but we use that for determining
71d9b493 3917;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
9ecc37f0 3918;; characteristics.
c714f03d 3919(define_insn "imb"
190315a7
RK
3920 [(unspec_volatile [(const_int 0)] 0)]
3921 ""
745466f2 3922 "call_pal 0x86"
9ecc37f0 3923 [(set_attr "type" "ibr")])
36f8f642
RK
3924\f
3925;; Finally, we have the basic data motion insns. The byte and word insns
3926;; are done via define_expand. Start with the floating-point insns, since
3927;; they are simpler.
3928
3929(define_insn ""
be5090b0
RH
3930 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m")
3931 (match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r"))]
de4abb91 3932 "! TARGET_FIX
71d9b493
RH
3933 && (register_operand (operands[0], SFmode)
3934 || reg_or_fp0_operand (operands[1], SFmode))"
36f8f642 3935 "@
6ce652e0 3936 fmov %R1,%0
477c16e3 3937 ld%, %0,%1
be5090b0
RH
3938 mov %r1,%0
3939 ldl %0,%1
3940 st%, %R1,%0
3941 stl %r1,%0"
3942 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
71d9b493
RH
3943
3944(define_insn ""
be5090b0
RH
3945 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r")
3946 (match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))]
de4abb91 3947 "TARGET_FIX
71d9b493
RH
3948 && (register_operand (operands[0], SFmode)
3949 || reg_or_fp0_operand (operands[1], SFmode))"
3950 "@
6ce652e0 3951 fmov %R1,%0
71d9b493 3952 ld%, %0,%1
be5090b0
RH
3953 mov %r1,%0
3954 ldl %0,%1
71d9b493 3955 st%, %R1,%0
be5090b0 3956 stl %r1,%0
71d9b493
RH
3957 itofs %1,%0
3958 ftois %1,%0"
be5090b0 3959 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
36f8f642
RK
3960
3961(define_insn ""
be5090b0
RH
3962 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m")
3963 (match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r"))]
de4abb91 3964 "! TARGET_FIX
71d9b493
RH
3965 && (register_operand (operands[0], DFmode)
3966 || reg_or_fp0_operand (operands[1], DFmode))"
36f8f642 3967 "@
6ce652e0 3968 fmov %R1,%0
477c16e3 3969 ld%- %0,%1
be5090b0
RH
3970 mov %r1,%0
3971 ldq %0,%1
3972 st%- %R1,%0
3973 stq %r1,%0"
3974 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
71d9b493
RH
3975
3976(define_insn ""
be5090b0
RH
3977 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r")
3978 (match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))]
de4abb91 3979 "TARGET_FIX
71d9b493
RH
3980 && (register_operand (operands[0], DFmode)
3981 || reg_or_fp0_operand (operands[1], DFmode))"
3982 "@
6ce652e0 3983 fmov %R1,%0
71d9b493 3984 ld%- %0,%1
be5090b0
RH
3985 mov %r1,%0
3986 ldq %0,%1
71d9b493 3987 st%- %R1,%0
be5090b0 3988 stq %r1,%0
71d9b493
RH
3989 itoft %1,%0
3990 ftoit %1,%0"
be5090b0 3991 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
36f8f642
RK
3992
3993(define_expand "movsf"
3994 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3995 (match_operand:SF 1 "general_operand" ""))]
3996 ""
3997 "
3998{
3999 if (GET_CODE (operands[0]) == MEM
4000 && ! reg_or_fp0_operand (operands[1], SFmode))
4001 operands[1] = force_reg (SFmode, operands[1]);
4002}")
4003
4004(define_expand "movdf"
4005 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4006 (match_operand:DF 1 "general_operand" ""))]
4007 ""
4008 "
4009{
4010 if (GET_CODE (operands[0]) == MEM
4011 && ! reg_or_fp0_operand (operands[1], DFmode))
4012 operands[1] = force_reg (DFmode, operands[1]);
4013}")
4014
36f8f642 4015(define_insn ""
6ce652e0
RH
4016 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m")
4017 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f"))]
de4abb91 4018 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX
477c16e3
RK
4019 && (register_operand (operands[0], SImode)
4020 || reg_or_0_operand (operands[1], SImode))"
36f8f642 4021 "@
6ce652e0 4022 mov %r1,%0
36f8f642
RK
4023 lda %0,%1
4024 ldah %0,%h1
4025 ldl %0,%1
4026 stl %r1,%0
6ce652e0 4027 fmov %R1,%0
e9a25f70
JL
4028 ld%, %0,%1
4029 st%, %R1,%0"
6ce652e0 4030 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
36f8f642 4031
e9a25f70 4032(define_insn ""
6ce652e0
RH
4033 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m,r,*f")
4034 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f,f,*r"))]
de4abb91 4035 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
e9a25f70
JL
4036 && (register_operand (operands[0], SImode)
4037 || reg_or_0_operand (operands[1], SImode))"
4038 "@
6ce652e0 4039 mov %r1,%0
e9a25f70
JL
4040 lda %0,%1
4041 ldah %0,%h1
4042 ldl %0,%1
4043 stl %r1,%0
6ce652e0 4044 fmov %R1,%0
e9a25f70
JL
4045 ld%, %0,%1
4046 st%, %R1,%0
4047 ftois %1,%0
71d9b493 4048 itofs %1,%0"
6ce652e0 4049 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
e9a25f70 4050
55e70146 4051(define_insn ""
6ce652e0
RH
4052 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,m")
4053 (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,m,f"))]
477c16e3 4054 "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
e9a25f70
JL
4055 && (register_operand (operands[0], SImode)
4056 || reg_or_0_operand (operands[1], SImode))"
55e70146 4057 "@
6ce652e0 4058 mov %1,%0
55e70146
RK
4059 lda %0,%1
4060 ldah %0,%h1
4061 lda %0,%1
4062 ldl %0,%1
4063 stl %r1,%0
6ce652e0 4064 fmov %R1,%0
e9a25f70
JL
4065 ld%, %0,%1
4066 st%, %R1,%0"
6ce652e0 4067 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
55e70146 4068
555919ac 4069(define_insn ""
8608bd56
RH
4070 [(set (match_operand:HI 0 "register_operand" "=r,r")
4071 (match_operand:HI 1 "input_operand" "rJ,n"))]
e9a25f70 4072 "! TARGET_BWX
555919ac
RK
4073 && (register_operand (operands[0], HImode)
4074 || register_operand (operands[1], HImode))"
4075 "@
6ce652e0 4076 mov %r1,%0
8608bd56
RH
4077 lda %0,%L1"
4078 [(set_attr "type" "ilog,iadd")])
555919ac 4079
36f8f642 4080(define_insn ""
8608bd56
RH
4081 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
4082 (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
e9a25f70 4083 "TARGET_BWX
555919ac
RK
4084 && (register_operand (operands[0], HImode)
4085 || reg_or_0_operand (operands[1], HImode))"
36f8f642 4086 "@
6ce652e0 4087 mov %r1,%0
6181e18d 4088 lda %0,%L1
ec0fb163 4089 ldwu %0,%1
8608bd56
RH
4090 stw %r1,%0"
4091 [(set_attr "type" "ilog,iadd,ild,ist")])
36f8f642 4092
555919ac 4093(define_insn ""
8608bd56
RH
4094 [(set (match_operand:QI 0 "register_operand" "=r,r")
4095 (match_operand:QI 1 "input_operand" "rJ,n"))]
e9a25f70 4096 "! TARGET_BWX
555919ac
RK
4097 && (register_operand (operands[0], QImode)
4098 || register_operand (operands[1], QImode))"
4099 "@
6ce652e0 4100 mov %r1,%0
8608bd56
RH
4101 lda %0,%L1"
4102 [(set_attr "type" "ilog,iadd")])
555919ac 4103
36f8f642 4104(define_insn ""
8608bd56
RH
4105 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4106 (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
e9a25f70 4107 "TARGET_BWX
555919ac
RK
4108 && (register_operand (operands[0], QImode)
4109 || reg_or_0_operand (operands[1], QImode))"
36f8f642 4110 "@
6ce652e0 4111 mov %r1,%0
6181e18d 4112 lda %0,%L1
ec0fb163 4113 ldbu %0,%1
8608bd56
RH
4114 stb %r1,%0"
4115 [(set_attr "type" "ilog,iadd,ild,ist")])
36f8f642
RK
4116
4117;; We do two major things here: handle mem->mem and construct long
4118;; constants.
4119
4120(define_expand "movsi"
4121 [(set (match_operand:SI 0 "general_operand" "")
4122 (match_operand:SI 1 "general_operand" ""))]
4123 ""
4124 "
4125{
4126 if (GET_CODE (operands[0]) == MEM
4127 && ! reg_or_0_operand (operands[1], SImode))
4128 operands[1] = force_reg (SImode, operands[1]);
4129
4130 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
4131 ;
4132 else if (GET_CODE (operands[1]) == CONST_INT)
4133 {
7ac18cf6
RK
4134 operands[1]
4135 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
4136 if (rtx_equal_p (operands[0], operands[1]))
36f8f642 4137 DONE;
36f8f642
RK
4138 }
4139}")
4140
4141;; Split a load of a large constant into the appropriate two-insn
4142;; sequence.
4143
4144(define_split
4145 [(set (match_operand:SI 0 "register_operand" "")
4146 (match_operand:SI 1 "const_int_operand" ""))]
4147 "! add_operand (operands[1], SImode)"
4148 [(set (match_dup 0) (match_dup 2))
4149 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4150 "
7ac18cf6
RK
4151{ rtx tem
4152 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
4153
4154 if (tem == operands[0])
36f8f642
RK
4155 DONE;
4156 else
4157 FAIL;
4158}")
4159
4160(define_insn ""
6ce652e0
RH
4161 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q")
4162 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f"))]
de4abb91 4163 "! TARGET_FIX
e9a25f70
JL
4164 && (register_operand (operands[0], DImode)
4165 || reg_or_0_operand (operands[1], DImode))"
36f8f642 4166 "@
6ce652e0 4167 mov %r1,%0
36f8f642
RK
4168 lda %0,%1
4169 ldah %0,%h1
4170 lda %0,%1
4171 ldq%A1 %0,%1
4172 stq%A0 %r1,%0
6ce652e0 4173 fmov %R1,%0
36f8f642
RK
4174 ldt %0,%1
4175 stt %R1,%0"
6ce652e0 4176 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
36f8f642 4177
e9a25f70 4178(define_insn ""
6ce652e0
RH
4179 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q,r,*f")
4180 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f,f,*r"))]
de4abb91 4181 "TARGET_FIX
e9a25f70
JL
4182 && (register_operand (operands[0], DImode)
4183 || reg_or_0_operand (operands[1], DImode))"
4184 "@
6ce652e0 4185 mov %r1,%0
e9a25f70
JL
4186 lda %0,%1
4187 ldah %0,%h1
4188 lda %0,%1
4189 ldq%A1 %0,%1
4190 stq%A0 %r1,%0
6ce652e0 4191 fmov %R1,%0
e9a25f70
JL
4192 ldt %0,%1
4193 stt %R1,%0
4194 ftoit %1,%0
4195 itoft %1,%0"
6ce652e0 4196 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
e9a25f70 4197
36f8f642
RK
4198;; We do three major things here: handle mem->mem, put 64-bit constants in
4199;; memory, and construct long 32-bit constants.
4200
4201(define_expand "movdi"
4202 [(set (match_operand:DI 0 "general_operand" "")
4203 (match_operand:DI 1 "general_operand" ""))]
4204 ""
4205 "
4206{
7ac18cf6
RK
4207 rtx tem;
4208
36f8f642
RK
4209 if (GET_CODE (operands[0]) == MEM
4210 && ! reg_or_0_operand (operands[1], DImode))
4211 operands[1] = force_reg (DImode, operands[1]);
4212
4213 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
4214 ;
4215 else if (GET_CODE (operands[1]) == CONST_INT
7ac18cf6
RK
4216 && (tem = alpha_emit_set_const (operands[0], DImode,
4217 INTVAL (operands[1]), 3)) != 0)
4218 {
4219 if (rtx_equal_p (tem, operands[0]))
4220 DONE;
4221 else
4222 operands[1] = tem;
4223 }
4bb43724 4224 else if (CONSTANT_P (operands[1]))
9e6c9f59 4225 {
4bb43724
RH
4226 if (TARGET_BUILD_CONSTANTS)
4227 {
3fe5612d 4228 HOST_WIDE_INT i0, i1;
4bb43724
RH
4229
4230 if (GET_CODE (operands[1]) == CONST_INT)
3fe5612d
RH
4231 {
4232 i0 = INTVAL (operands[1]);
4233 i1 = -(i0 < 0);
4234 }
4bb43724 4235 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
3fe5612d
RH
4236 {
4237#if HOST_BITS_PER_WIDE_INT >= 64
4238 i0 = CONST_DOUBLE_LOW (operands[1]);
4239 i1 = -(i0 < 0);
4240#else
4241 i0 = CONST_DOUBLE_LOW (operands[1]);
4242 i1 = CONST_DOUBLE_HIGH (operands[1]);
4243#endif
4244 }
4bb43724
RH
4245 else
4246 abort();
4247
3fe5612d 4248 tem = alpha_emit_set_long_const (operands[0], i0, i1);
4bb43724
RH
4249 if (rtx_equal_p (tem, operands[0]))
4250 DONE;
4251 else
4252 operands[1] = tem;
36f8f642
RK
4253 }
4254 else
4bb43724
RH
4255 {
4256 operands[1] = force_const_mem (DImode, operands[1]);
4257 if (reload_in_progress)
4258 {
4259 emit_move_insn (operands[0], XEXP (operands[1], 0));
4260 operands[1] = copy_rtx (operands[1]);
4261 XEXP (operands[1], 0) = operands[0];
4262 }
4263 else
4264 operands[1] = validize_mem (operands[1]);
4265 }
36f8f642
RK
4266 }
4267 else
4268 abort ();
4269}")
4270
4271;; Split a load of a large constant into the appropriate two-insn
4272;; sequence.
4273
4274(define_split
4275 [(set (match_operand:DI 0 "register_operand" "")
4276 (match_operand:DI 1 "const_int_operand" ""))]
4277 "! add_operand (operands[1], DImode)"
4278 [(set (match_dup 0) (match_dup 2))
4279 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4280 "
7ac18cf6
RK
4281{ rtx tem
4282 = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
4283
4284 if (tem == operands[0])
36f8f642
RK
4285 DONE;
4286 else
4287 FAIL;
4288}")
4289
4290;; These are the partial-word cases.
4291;;
4292;; First we have the code to load an aligned word. Operand 0 is the register
4293;; in which to place the result. It's mode is QImode or HImode. Operand 1
4294;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
4295;; number of bits within the word that the value is. Operand 3 is an SImode
4296;; scratch register. If operand 0 is a hard register, operand 3 may be the
4297;; same register. It is allowed to conflict with operand 1 as well.
4298
4299(define_expand "aligned_loadqi"
4300 [(set (match_operand:SI 3 "register_operand" "")
4301 (match_operand:SI 1 "memory_operand" ""))
4302 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4303 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4304 (const_int 8)
4305 (match_operand:DI 2 "const_int_operand" "")))]
4306
4307 ""
4308 "")
4309
4310(define_expand "aligned_loadhi"
4311 [(set (match_operand:SI 3 "register_operand" "")
4312 (match_operand:SI 1 "memory_operand" ""))
4313 (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
4314 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4315 (const_int 16)
4316 (match_operand:DI 2 "const_int_operand" "")))]
4317
4318 ""
4319 "")
4320
2206e904
RK
4321;; Similar for unaligned loads, where we use the sequence from the
4322;; Alpha Architecture manual.
36f8f642 4323;;
2206e904 4324;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
36f8f642
RK
4325;; operand 3 can overlap the input and output registers.
4326
4327(define_expand "unaligned_loadqi"
4328 [(set (match_operand:DI 2 "register_operand" "")
4329 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4330 (const_int -8))))
4331 (set (match_operand:DI 3 "register_operand" "")
4332 (match_dup 1))
4333 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4334 (zero_extract:DI (match_dup 2)
4335 (const_int 8)
4336 (ashift:DI (match_dup 3) (const_int 3))))]
4337 ""
4338 "")
4339
36f8f642
RK
4340(define_expand "unaligned_loadhi"
4341 [(set (match_operand:DI 2 "register_operand" "")
2206e904
RK
4342 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4343 (const_int -8))))
36f8f642 4344 (set (match_operand:DI 3 "register_operand" "")
2206e904
RK
4345 (match_dup 1))
4346 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4347 (zero_extract:DI (match_dup 2)
36f8f642 4348 (const_int 16)
2206e904 4349 (ashift:DI (match_dup 3) (const_int 3))))]
36f8f642
RK
4350 ""
4351 "")
2206e904 4352
36f8f642
RK
4353;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
4354;; aligned SImode MEM. Operand 1 is the register containing the
4355;; byte or word to store. Operand 2 is the number of bits within the word that
4356;; the value should be placed. Operands 3 and 4 are SImode temporaries.
4357
4358(define_expand "aligned_store"
4359 [(set (match_operand:SI 3 "register_operand" "")
4360 (match_operand:SI 0 "memory_operand" ""))
4361 (set (subreg:DI (match_dup 3) 0)
4362 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4363 (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
4364 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
4365 (match_operand:DI 2 "const_int_operand" "")))
4366 (set (subreg:DI (match_dup 4) 0)
4367 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4368 (set (match_dup 0) (match_dup 4))]
4369 ""
4370 "
4371{ operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4372 << INTVAL (operands[2])));
4373}")
4374
2206e904
RK
4375;; For the unaligned byte and halfword cases, we use code similar to that
4376;; in the ;; Architecture book, but reordered to lower the number of registers
36f8f642 4377;; required. Operand 0 is the address. Operand 1 is the data to store.
53693fe5 4378;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
36f8f642
RK
4379;; be the same temporary, if desired. If the address is in a register,
4380;; operand 2 can be that register.
4381
4382(define_expand "unaligned_storeqi"
4383 [(set (match_operand:DI 3 "register_operand" "")
4384 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4385 (const_int -8))))
4386 (set (match_operand:DI 2 "register_operand" "")
4387 (match_dup 0))
4388 (set (match_dup 3)
027b95a6
RK
4389 (and:DI (not:DI (ashift:DI (const_int 255)
4390 (ashift:DI (match_dup 2) (const_int 3))))
36f8f642
RK
4391 (match_dup 3)))
4392 (set (match_operand:DI 4 "register_operand" "")
4393 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
4394 (ashift:DI (match_dup 2) (const_int 3))))
4395 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4396 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4397 (match_dup 4))]
4398 ""
4399 "")
4400
36f8f642 4401(define_expand "unaligned_storehi"
2206e904
RK
4402 [(set (match_operand:DI 3 "register_operand" "")
4403 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4404 (const_int -8))))
4405 (set (match_operand:DI 2 "register_operand" "")
4406 (match_dup 0))
4407 (set (match_dup 3)
027b95a6 4408 (and:DI (not:DI (ashift:DI (const_int 65535)
2206e904
RK
4409 (ashift:DI (match_dup 2) (const_int 3))))
4410 (match_dup 3)))
4411 (set (match_operand:DI 4 "register_operand" "")
36f8f642 4412 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
2206e904
RK
4413 (ashift:DI (match_dup 2) (const_int 3))))
4414 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4415 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4416 (match_dup 4))]
36f8f642
RK
4417 ""
4418 "")
4419\f
4420;; Here are the define_expand's for QI and HI moves that use the above
4421;; patterns. We have the normal sets, plus the ones that need scratch
4422;; registers for reload.
4423
4424(define_expand "movqi"
4425 [(set (match_operand:QI 0 "general_operand" "")
4426 (match_operand:QI 1 "general_operand" ""))]
4427 ""
4428 "
47747e53 4429{
e9a25f70 4430 if (TARGET_BWX)
ec0fb163
TG
4431 {
4432 if (GET_CODE (operands[0]) == MEM
4433 && ! reg_or_0_operand (operands[1], QImode))
4434 operands[1] = force_reg (QImode, operands[1]);
4435
b9a2d591
RK
4436 if (GET_CODE (operands[1]) == CONST_INT
4437 && ! input_operand (operands[1], QImode))
ec0fb163 4438 {
b9a2d591
RK
4439 operands[1] = alpha_emit_set_const (operands[0], QImode,
4440 INTVAL (operands[1]), 3);
4441
ec0fb163
TG
4442 if (rtx_equal_p (operands[0], operands[1]))
4443 DONE;
4444 }
b9a2d591 4445
ec0fb163
TG
4446 goto def;
4447 }
4448
36f8f642
RK
4449 /* If the output is not a register, the input must be. */
4450 if (GET_CODE (operands[0]) == MEM)
4451 operands[1] = force_reg (QImode, operands[1]);
4452
4453 /* Handle four memory cases, unaligned and aligned for either the input
4454 or the output. The only case where we can be called during reload is
4455 for aligned loads; all other cases require temporaries. */
4456
4457 if (GET_CODE (operands[1]) == MEM
4458 || (GET_CODE (operands[1]) == SUBREG
4459 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4460 || (reload_in_progress && GET_CODE (operands[1]) == REG
4461 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4462 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4463 && GET_CODE (SUBREG_REG (operands[1])) == REG
4464 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4465 {
4466 if (aligned_memory_operand (operands[1], QImode))
4467 {
e221c183
RH
4468 if (reload_in_progress)
4469 {
4470 emit_insn (gen_reload_inqi_help
4471 (operands[0], operands[1],
4472 gen_rtx_REG (SImode, REGNO (operands[0]))));
4473 }
4474 else
4475 {
4476 rtx aligned_mem, bitnum;
4477 rtx scratch = gen_reg_rtx (SImode);
36f8f642 4478
e221c183 4479 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
36f8f642 4480
e221c183
RH
4481 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
4482 scratch));
4483 }
36f8f642
RK
4484 }
4485 else
4486 {
4487 /* Don't pass these as parameters since that makes the generated
4488 code depend on parameter evaluation order which will cause
4489 bootstrap failures. */
4490
4491 rtx temp1 = gen_reg_rtx (DImode);
4492 rtx temp2 = gen_reg_rtx (DImode);
2206e904
RK
4493 rtx seq
4494 = gen_unaligned_loadqi (operands[0],
4495 get_unaligned_address (operands[1], 0),
4496 temp1, temp2);
36f8f642
RK
4497
4498 alpha_set_memflags (seq, operands[1]);
4499 emit_insn (seq);
4500 }
4501
4502 DONE;
4503 }
4504
4505 else if (GET_CODE (operands[0]) == MEM
4506 || (GET_CODE (operands[0]) == SUBREG
4507 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4508 || (reload_in_progress && GET_CODE (operands[0]) == REG
4509 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4510 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4511 && GET_CODE (SUBREG_REG (operands[0])) == REG
4512 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4513 {
4514 if (aligned_memory_operand (operands[0], QImode))
4515 {
4516 rtx aligned_mem, bitnum;
4517 rtx temp1 = gen_reg_rtx (SImode);
4518 rtx temp2 = gen_reg_rtx (SImode);
4519
4e46365b 4520 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
36f8f642
RK
4521
4522 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4523 temp1, temp2));
4524 }
4525 else
4526 {
4527 rtx temp1 = gen_reg_rtx (DImode);
4528 rtx temp2 = gen_reg_rtx (DImode);
4529 rtx temp3 = gen_reg_rtx (DImode);
2206e904
RK
4530 rtx seq
4531 = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
4e46365b 4532 operands[1], temp1, temp2, temp3);
36f8f642
RK
4533
4534 alpha_set_memflags (seq, operands[0]);
4535 emit_insn (seq);
4536 }
4537 DONE;
4538 }
ec0fb163 4539 def:;
36f8f642
RK
4540}")
4541
4542(define_expand "movhi"
4543 [(set (match_operand:HI 0 "general_operand" "")
4544 (match_operand:HI 1 "general_operand" ""))]
4545 ""
4546 "
47747e53 4547{
e9a25f70 4548 if (TARGET_BWX)
ec0fb163
TG
4549 {
4550 if (GET_CODE (operands[0]) == MEM
4551 && ! reg_or_0_operand (operands[1], HImode))
4552 operands[1] = force_reg (HImode, operands[1]);
4553
b9a2d591
RK
4554 if (GET_CODE (operands[1]) == CONST_INT
4555 && ! input_operand (operands[1], HImode))
ec0fb163 4556 {
b9a2d591
RK
4557 operands[1] = alpha_emit_set_const (operands[0], HImode,
4558 INTVAL (operands[1]), 3);
4559
ec0fb163
TG
4560 if (rtx_equal_p (operands[0], operands[1]))
4561 DONE;
4562 }
b9a2d591 4563
ec0fb163
TG
4564 goto def;
4565 }
4566
36f8f642
RK
4567 /* If the output is not a register, the input must be. */
4568 if (GET_CODE (operands[0]) == MEM)
4569 operands[1] = force_reg (HImode, operands[1]);
4570
4571 /* Handle four memory cases, unaligned and aligned for either the input
4572 or the output. The only case where we can be called during reload is
4573 for aligned loads; all other cases require temporaries. */
4574
4575 if (GET_CODE (operands[1]) == MEM
4576 || (GET_CODE (operands[1]) == SUBREG
4577 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4578 || (reload_in_progress && GET_CODE (operands[1]) == REG
4579 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4580 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4581 && GET_CODE (SUBREG_REG (operands[1])) == REG
4582 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4583 {
4584 if (aligned_memory_operand (operands[1], HImode))
4585 {
e221c183
RH
4586 if (reload_in_progress)
4587 {
4588 emit_insn (gen_reload_inhi_help
4589 (operands[0], operands[1],
4590 gen_rtx_REG (SImode, REGNO (operands[0]))));
4591 }
4592 else
4593 {
4594 rtx aligned_mem, bitnum;
4595 rtx scratch = gen_reg_rtx (SImode);
36f8f642 4596
e221c183 4597 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
36f8f642 4598
e221c183
RH
4599 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
4600 scratch));
4601 }
36f8f642
RK
4602 }
4603 else
4604 {
2206e904
RK
4605 /* Don't pass these as parameters since that makes the generated
4606 code depend on parameter evaluation order which will cause
4607 bootstrap failures. */
26967318 4608
2206e904
RK
4609 rtx temp1 = gen_reg_rtx (DImode);
4610 rtx temp2 = gen_reg_rtx (DImode);
4611 rtx seq
4612 = gen_unaligned_loadhi (operands[0],
4613 get_unaligned_address (operands[1], 0),
4614 temp1, temp2);
36f8f642
RK
4615
4616 alpha_set_memflags (seq, operands[1]);
4617 emit_insn (seq);
4618 }
4619
4620 DONE;
4621 }
4622
4623 else if (GET_CODE (operands[0]) == MEM
4624 || (GET_CODE (operands[0]) == SUBREG
4625 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4626 || (reload_in_progress && GET_CODE (operands[0]) == REG
4627 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4628 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4629 && GET_CODE (SUBREG_REG (operands[0])) == REG
4630 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4631 {
4632 if (aligned_memory_operand (operands[0], HImode))
4633 {
4634 rtx aligned_mem, bitnum;
4635 rtx temp1 = gen_reg_rtx (SImode);
4636 rtx temp2 = gen_reg_rtx (SImode);
4637
4e46365b 4638 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
36f8f642
RK
4639
4640 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4641 temp1, temp2));
4642 }
4643 else
4644 {
4645 rtx temp1 = gen_reg_rtx (DImode);
4646 rtx temp2 = gen_reg_rtx (DImode);
4647 rtx temp3 = gen_reg_rtx (DImode);
2206e904
RK
4648 rtx seq
4649 = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
4650 operands[1], temp1, temp2, temp3);
36f8f642
RK
4651
4652 alpha_set_memflags (seq, operands[0]);
4653 emit_insn (seq);
4654 }
4655
4656 DONE;
4657 }
ec0fb163 4658 def:;
36f8f642
RK
4659}")
4660
4661;; Here are the versions for reload. Note that in the unaligned cases
4662;; we know that the operand must not be a pseudo-register because stack
4663;; slots are always aligned references.
4664
4665(define_expand "reload_inqi"
4666 [(parallel [(match_operand:QI 0 "register_operand" "=r")
4e46365b 4667 (match_operand:QI 1 "any_memory_operand" "m")
53693fe5 4668 (match_operand:TI 2 "register_operand" "=&r")])]
e9a25f70 4669 "! TARGET_BWX"
36f8f642 4670 "
47747e53 4671{
96043e7e 4672 rtx scratch, seq;
f3352b9e 4673
4e46365b
RH
4674 if (GET_CODE (operands[1]) != MEM)
4675 abort ();
4676
96043e7e
RH
4677 if (aligned_memory_operand (operands[1], QImode))
4678 {
e221c183
RH
4679 seq = gen_reload_inqi_help (operands[0], operands[1],
4680 gen_rtx_REG (SImode, REGNO (operands[2])));
96043e7e
RH
4681 }
4682 else
4683 {
4684 rtx addr;
4685
4686 /* It is possible that one of the registers we got for operands[2]
4e46365b
RH
4687 might coincide with that of operands[0] (which is why we made
4688 it TImode). Pick the other one to use as our scratch. */
96043e7e
RH
4689 if (REGNO (operands[0]) == REGNO (operands[2]))
4690 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4691 else
4692 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
36f8f642 4693
96043e7e
RH
4694 addr = get_unaligned_address (operands[1], 0);
4695 seq = gen_unaligned_loadqi (operands[0], addr, scratch,
4e46365b
RH
4696 gen_rtx_REG (DImode, REGNO (operands[0])));
4697 alpha_set_memflags (seq, operands[1]);
96043e7e 4698 }
36f8f642
RK
4699 emit_insn (seq);
4700 DONE;
4701}")
4702
4703(define_expand "reload_inhi"
4704 [(parallel [(match_operand:HI 0 "register_operand" "=r")
96043e7e 4705 (match_operand:HI 1 "any_memory_operand" "m")
36f8f642 4706 (match_operand:TI 2 "register_operand" "=&r")])]
e9a25f70 4707 "! TARGET_BWX"
36f8f642 4708 "
47747e53 4709{
96043e7e 4710 rtx scratch, seq;
f3352b9e 4711
4e46365b
RH
4712 if (GET_CODE (operands[1]) != MEM)
4713 abort ();
4714
96043e7e
RH
4715 if (aligned_memory_operand (operands[1], HImode))
4716 {
e221c183
RH
4717 seq = gen_reload_inhi_help (operands[0], operands[1],
4718 gen_rtx_REG (SImode, REGNO (operands[2])));
96043e7e
RH
4719 }
4720 else
4721 {
4722 rtx addr;
4723
4724 /* It is possible that one of the registers we got for operands[2]
4e46365b
RH
4725 might coincide with that of operands[0] (which is why we made
4726 it TImode). Pick the other one to use as our scratch. */
96043e7e
RH
4727 if (REGNO (operands[0]) == REGNO (operands[2]))
4728 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4729 else
4730 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
36f8f642 4731
96043e7e
RH
4732 addr = get_unaligned_address (operands[1], 0);
4733 seq = gen_unaligned_loadhi (operands[0], addr, scratch,
4e46365b
RH
4734 gen_rtx_REG (DImode, REGNO (operands[0])));
4735 alpha_set_memflags (seq, operands[1]);
96043e7e 4736 }
36f8f642
RK
4737 emit_insn (seq);
4738 DONE;
4739}")
4740
4741(define_expand "reload_outqi"
4742 [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
4743 (match_operand:QI 1 "register_operand" "r")
4744 (match_operand:TI 2 "register_operand" "=&r")])]
e9a25f70 4745 "! TARGET_BWX"
36f8f642 4746 "
47747e53 4747{
4e46365b
RH
4748 if (GET_CODE (operands[0]) != MEM)
4749 abort ();
4750
36f8f642
RK
4751 if (aligned_memory_operand (operands[0], QImode))
4752 {
e221c183
RH
4753 emit_insn (gen_reload_outqi_help
4754 (operands[0], operands[1],
4755 gen_rtx_REG (SImode, REGNO (operands[2])),
4756 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
36f8f642
RK
4757 }
4758 else
4759 {
2206e904 4760 rtx addr = get_unaligned_address (operands[0], 0);
38a448ca
RH
4761 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
4762 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
99d13c40 4763 rtx scratch3 = scratch1;
36f8f642
RK
4764 rtx seq;
4765
4766 if (GET_CODE (addr) == REG)
4767 scratch1 = addr;
4768
4769 seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
99d13c40 4770 scratch2, scratch3);
36f8f642
RK
4771 alpha_set_memflags (seq, operands[0]);
4772 emit_insn (seq);
4773 }
36f8f642
RK
4774 DONE;
4775}")
4776
4777(define_expand "reload_outhi"
4778 [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
4779 (match_operand:HI 1 "register_operand" "r")
4780 (match_operand:TI 2 "register_operand" "=&r")])]
e9a25f70 4781 "! TARGET_BWX"
36f8f642 4782 "
47747e53 4783{
4e46365b
RH
4784 if (GET_CODE (operands[0]) != MEM)
4785 abort ();
4786
36f8f642
RK
4787 if (aligned_memory_operand (operands[0], HImode))
4788 {
e221c183
RH
4789 emit_insn (gen_reload_outhi_help
4790 (operands[0], operands[1],
4791 gen_rtx_REG (SImode, REGNO (operands[2])),
4792 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
36f8f642
RK
4793 }
4794 else
4795 {
2206e904 4796 rtx addr = get_unaligned_address (operands[0], 0);
38a448ca
RH
4797 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
4798 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
2206e904 4799 rtx scratch3 = scratch1;
36f8f642
RK
4800 rtx seq;
4801
2206e904
RK
4802 if (GET_CODE (addr) == REG)
4803 scratch1 = addr;
4804
4805 seq = gen_unaligned_storehi (addr, operands[1], scratch1,
4806 scratch2, scratch3);
36f8f642
RK
4807 alpha_set_memflags (seq, operands[0]);
4808 emit_insn (seq);
4809 }
36f8f642
RK
4810 DONE;
4811}")
e221c183
RH
4812
4813;; Helpers for the above. The way reload is structured, we can't
4814;; always get a proper address for a stack slot during reload_foo
4815;; expansion, so we must delay our address manipulations until after.
4816
4817(define_insn "reload_inqi_help"
4818 [(set (match_operand:QI 0 "register_operand" "r")
4819 (match_operand:QI 1 "memory_operand" "m"))
4820 (clobber (match_operand:SI 2 "register_operand" "r"))]
4821 "! TARGET_BWX && (reload_in_progress || reload_completed)"
4822 "#")
4823
4824(define_insn "reload_inhi_help"
4825 [(set (match_operand:HI 0 "register_operand" "r")
4826 (match_operand:HI 1 "memory_operand" "m"))
4827 (clobber (match_operand:SI 2 "register_operand" "r"))]
4828 "! TARGET_BWX && (reload_in_progress || reload_completed)"
4829 "#")
4830
4831(define_insn "reload_outqi_help"
4832 [(set (match_operand:QI 0 "memory_operand" "m")
4833 (match_operand:QI 1 "register_operand" "r"))
4834 (clobber (match_operand:SI 2 "register_operand" "r"))
4835 (clobber (match_operand:SI 3 "register_operand" "r"))]
4836 "! TARGET_BWX && (reload_in_progress || reload_completed)"
4837 "#")
4838
4839(define_insn "reload_outhi_help"
4840 [(set (match_operand:HI 0 "memory_operand" "m")
4841 (match_operand:HI 1 "register_operand" "r"))
4842 (clobber (match_operand:SI 2 "register_operand" "r"))
4843 (clobber (match_operand:SI 3 "register_operand" "r"))]
4844 "! TARGET_BWX && (reload_in_progress || reload_completed)"
4845 "#")
4846
4847(define_split
4848 [(set (match_operand:QI 0 "register_operand" "r")
4849 (match_operand:QI 1 "memory_operand" "m"))
4850 (clobber (match_operand:SI 2 "register_operand" "r"))]
4851 "! TARGET_BWX && reload_completed"
4852 [(const_int 0)]
4853 "
4854{
4855 rtx aligned_mem, bitnum;
4856 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4857 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
4858 operands[2]));
4859 DONE;
4860}")
4861
4862(define_split
4863 [(set (match_operand:HI 0 "register_operand" "r")
4864 (match_operand:HI 1 "memory_operand" "m"))
4865 (clobber (match_operand:SI 2 "register_operand" "r"))]
4866 "! TARGET_BWX && reload_completed"
4867 [(const_int 0)]
4868 "
4869{
4870 rtx aligned_mem, bitnum;
4871 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4872 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
4873 operands[2]));
4874 DONE;
4875}")
4876
4877(define_split
4878 [(set (match_operand:QI 0 "memory_operand" "m")
4879 (match_operand:QI 1 "register_operand" "r"))
4880 (clobber (match_operand:SI 2 "register_operand" "r"))
4881 (clobber (match_operand:SI 3 "register_operand" "r"))]
4882 "! TARGET_BWX && reload_completed"
4883 [(const_int 0)]
4884 "
4885{
4886 rtx aligned_mem, bitnum;
4887 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4888 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4889 operands[2], operands[3]));
4890 DONE;
4891}")
4892
4893(define_split
4894 [(set (match_operand:HI 0 "memory_operand" "m")
4895 (match_operand:HI 1 "register_operand" "r"))
4896 (clobber (match_operand:SI 2 "register_operand" "r"))
4897 (clobber (match_operand:SI 3 "register_operand" "r"))]
4898 "! TARGET_BWX && reload_completed"
4899 [(const_int 0)]
4900 "
4901{
4902 rtx aligned_mem, bitnum;
4903 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4904 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4905 operands[2], operands[3]));
4906 DONE;
4907}")
26958509 4908\f
6c174fc0
RH
4909;; Bit field extract patterns which use ext[wlq][lh]
4910
4911(define_expand "extv"
4912 [(set (match_operand:DI 0 "register_operand" "")
4913 (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
4914 (match_operand:DI 2 "immediate_operand" "")
4915 (match_operand:DI 3 "immediate_operand" "")))]
4916 ""
4917 "
4918{
4919 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4920 if (INTVAL (operands[3]) % 8 != 0
4921 || (INTVAL (operands[2]) != 16
4922 && INTVAL (operands[2]) != 32
4923 && INTVAL (operands[2]) != 64))
4924 FAIL;
4925
4926 /* From mips.md: extract_bit_field doesn't verify that our source
4927 matches the predicate, so we force it to be a MEM here. */
4928 if (GET_CODE (operands[1]) != MEM)
4929 FAIL;
4930
4931 alpha_expand_unaligned_load (operands[0], operands[1],
4932 INTVAL (operands[2]) / 8,
4933 INTVAL (operands[3]) / 8, 1);
4934 DONE;
4935}")
4936
4937(define_expand "extzv"
4938 [(set (match_operand:DI 0 "register_operand" "")
6ad90d66 4939 (zero_extract:DI (match_operand:DI 1 "general_operand" "")
6c174fc0
RH
4940 (match_operand:DI 2 "immediate_operand" "")
4941 (match_operand:DI 3 "immediate_operand" "")))]
4942 ""
4943 "
4944{
10a25232 4945 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
221a9f65
JW
4946 if (INTVAL (operands[3]) % 8 != 0
4947 || (INTVAL (operands[2]) != 8
4948 && INTVAL (operands[2]) != 16
4949 && INTVAL (operands[2]) != 32
4950 && INTVAL (operands[2]) != 64))
6c174fc0
RH
4951 FAIL;
4952
10a25232
RH
4953 if (GET_CODE (operands[1]) == MEM)
4954 {
4955 /* Fail 8 bit fields, falling back on a simple byte load. */
4956 if (INTVAL (operands[2]) == 8)
4957 FAIL;
6c174fc0 4958
10a25232
RH
4959 alpha_expand_unaligned_load (operands[0], operands[1],
4960 INTVAL (operands[2]) / 8,
4961 INTVAL (operands[3]) / 8, 0);
4962 DONE;
4963 }
6c174fc0
RH
4964}")
4965
4966(define_expand "insv"
4967 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
4968 (match_operand:DI 1 "immediate_operand" "")
4969 (match_operand:DI 2 "immediate_operand" ""))
4970 (match_operand:DI 3 "register_operand" ""))]
4971 ""
4972 "
4973{
4974 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4975 if (INTVAL (operands[2]) % 8 != 0
4976 || (INTVAL (operands[1]) != 16
4977 && INTVAL (operands[1]) != 32
4978 && INTVAL (operands[1]) != 64))
4979 FAIL;
4980
4981 /* From mips.md: store_bit_field doesn't verify that our source
4982 matches the predicate, so we force it to be a MEM here. */
4983 if (GET_CODE (operands[0]) != MEM)
4984 FAIL;
4985
4986 alpha_expand_unaligned_store (operands[0], operands[3],
4987 INTVAL (operands[1]) / 8,
4988 INTVAL (operands[2]) / 8);
4989 DONE;
4990}")
4991
4992
4993
4994;; Block move/clear, see alpha.c for more details.
4995;; Argument 0 is the destination
4996;; Argument 1 is the source
4997;; Argument 2 is the length
4998;; Argument 3 is the alignment
4999
5000(define_expand "movstrqi"
5001 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
5002 (match_operand:BLK 1 "general_operand" ""))
5003 (use (match_operand:DI 2 "immediate_operand" ""))
5004 (use (match_operand:DI 3 "immediate_operand" ""))])]
5005 ""
5006 "
5007{
5008 if (alpha_expand_block_move (operands))
5009 DONE;
5010 else
5011 FAIL;
5012}")
5013
5014(define_expand "clrstrqi"
5015 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
5016 (const_int 0))
5017 (use (match_operand:DI 1 "immediate_operand" ""))
5018 (use (match_operand:DI 2 "immediate_operand" ""))])]
5019 ""
5020 "
5021{
5022 if (alpha_expand_block_clear (operands))
5023 DONE;
5024 else
5025 FAIL;
5026}")
5027\f
26958509
RK
5028;; Subroutine of stack space allocation. Perform a stack probe.
5029(define_expand "probe_stack"
5030 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
5031 ""
5032 "
5033{
38a448ca
RH
5034 operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
5035 INTVAL (operands[0])));
13aa593c 5036 MEM_VOLATILE_P (operands[1]) = 1;
26958509 5037
13aa593c 5038 operands[0] = const0_rtx;
26958509
RK
5039}")
5040
5041;; This is how we allocate stack space. If we are allocating a
5042;; constant amount of space and we know it is less than 4096
5043;; bytes, we need do nothing.
5044;;
5045;; If it is more than 4096 bytes, we need to probe the stack
5046;; periodically.
5047(define_expand "allocate_stack"
5048 [(set (reg:DI 30)
5049 (plus:DI (reg:DI 30)
e9a25f70
JL
5050 (match_operand:DI 1 "reg_or_cint_operand" "")))
5051 (set (match_operand:DI 0 "register_operand" "=r")
5052 (match_dup 2))]
26958509
RK
5053 ""
5054 "
5055{
e9a25f70
JL
5056 if (GET_CODE (operands[1]) == CONST_INT
5057 && INTVAL (operands[1]) < 32768)
26958509 5058 {
e9a25f70 5059 if (INTVAL (operands[1]) >= 4096)
26958509
RK
5060 {
5061 /* We do this the same way as in the prologue and generate explicit
5062 probes. Then we update the stack by the constant. */
5063
5064 int probed = 4096;
5065
5066 emit_insn (gen_probe_stack (GEN_INT (- probed)));
e9a25f70 5067 while (probed + 8192 < INTVAL (operands[1]))
26958509
RK
5068 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
5069
e9a25f70
JL
5070 if (probed + 4096 < INTVAL (operands[1]))
5071 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
26958509
RK
5072 }
5073
e9a25f70
JL
5074 operands[1] = GEN_INT (- INTVAL (operands[1]));
5075 operands[2] = virtual_stack_dynamic_rtx;
26958509
RK
5076 }
5077 else
5078 {
5079 rtx out_label = 0;
5080 rtx loop_label = gen_label_rtx ();
13aa593c
RK
5081 rtx want = gen_reg_rtx (Pmode);
5082 rtx tmp = gen_reg_rtx (Pmode);
5083 rtx memref;
26958509 5084
13aa593c 5085 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
e9a25f70 5086 force_reg (Pmode, operands[1])));
13aa593c 5087 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
26958509 5088
e9a25f70 5089 if (GET_CODE (operands[1]) != CONST_INT)
26958509 5090 {
26958509 5091 out_label = gen_label_rtx ();
13aa593c
RK
5092 emit_insn (gen_cmpdi (want, tmp));
5093 emit_jump_insn (gen_bgeu (out_label));
26958509 5094 }
26958509 5095
26958509 5096 emit_label (loop_label);
38a448ca 5097 memref = gen_rtx_MEM (DImode, tmp);
13aa593c
RK
5098 MEM_VOLATILE_P (memref) = 1;
5099 emit_move_insn (memref, const0_rtx);
5100 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
5101 emit_insn (gen_cmpdi (tmp, want));
5102 emit_jump_insn (gen_bgtu (loop_label));
e9a25f70 5103 if (obey_regdecls)
38a448ca 5104 gen_rtx_USE (VOIDmode, tmp);
e9a25f70 5105
38a448ca 5106 memref = gen_rtx_MEM (DImode, want);
13aa593c
RK
5107 MEM_VOLATILE_P (memref) = 1;
5108 emit_move_insn (memref, const0_rtx);
26958509
RK
5109
5110 if (out_label)
5111 emit_label (out_label);
5112
13aa593c 5113 emit_move_insn (stack_pointer_rtx, want);
e9a25f70 5114 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
26958509
RK
5115 DONE;
5116 }
5117}")
477c16e3 5118
9c0e94a5
RH
5119;; This is used by alpha_expand_prolog to do the same thing as above,
5120;; except we cannot at that time generate new basic blocks, so we hide
5121;; the loop in this one insn.
5122
5123(define_insn "prologue_stack_probe_loop"
5124 [(unspec_volatile [(match_operand 0 "register_operand" "r")
5125 (match_operand 1 "register_operand" "r")] 5)]
5126 ""
5127 "*
5128{
73d288ba
RH
5129 operands[2] = gen_label_rtx ();
5130 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5131 CODE_LABEL_NUMBER (operands[2]));
5132
5133 return \"stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2\";
9c0e94a5 5134}"
68aed21b
RH
5135 [(set_attr "length" "16")
5136 (set_attr "type" "multi")])
9c0e94a5
RH
5137
5138(define_expand "prologue"
5139 [(clobber (const_int 0))]
5140 ""
5141 "alpha_expand_prologue (); DONE;")
5142
5143(define_insn "init_fp"
5144 [(set (match_operand:DI 0 "register_operand" "r")
5145 (match_operand:DI 1 "register_operand" "r"))
5146 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "r")))]
5147 ""
6ce652e0 5148 "mov %1,%0")
9c0e94a5
RH
5149
5150(define_expand "epilogue"
5151 [(clobber (const_int 0))]
5152 ""
5153 "alpha_expand_epilogue (); DONE;")
5154
71038426
RH
5155(define_expand "eh_epilogue"
5156 [(use (match_operand:DI 0 "register_operand" "r"))
5157 (use (match_operand:DI 1 "register_operand" "r"))
5158 (use (match_operand:DI 2 "register_operand" "r"))]
5159 "! TARGET_OPEN_VMS"
5160 "
5161{
5162 alpha_eh_epilogue_sp_ofs = operands[1];
5163 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
5164 {
5165 rtx ra = gen_rtx_REG (Pmode, 26);
5166 emit_move_insn (ra, operands[2]);
5167 operands[2] = ra;
5168 }
5169}")
5170
37679e06
RH
5171;; In creating a large stack frame, NT _must_ use ldah+lda to load
5172;; the frame size into a register. We use this pattern to ensure
5173;; we get lda instead of addq.
5174(define_insn "nt_lda"
5175 [(set (match_operand:DI 0 "register_operand" "r")
5176 (unspec:DI [(match_dup 0)
5177 (match_operand:DI 1 "const_int_operand" "n")] 6))]
5178 ""
5179 "lda %0,%1(%0)")
5180
6fd1c67b
RH
5181(define_expand "builtin_longjmp"
5182 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
c133e33c 5183 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
6fd1c67b
RH
5184 "
5185{
5186 /* The elements of the buffer are, in order: */
5187 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5188 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
5189 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
5190 rtx pv = gen_rtx_REG (Pmode, 27);
5191
5192 /* This bit is the same as expand_builtin_longjmp. */
5193 emit_move_insn (hard_frame_pointer_rtx, fp);
5194 emit_move_insn (pv, lab);
5195 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5196 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5197 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5198
5199 /* Load the label we are jumping through into $27 so that we know
5200 where to look for it when we get back to setjmp's function for
5201 restoring the gp. */
5202 emit_indirect_jump (pv);
4b855767 5203 DONE;
6fd1c67b 5204}")
c133e33c 5205
6fd1c67b 5206(define_insn "builtin_setjmp_receiver"
039d4bce 5207 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
9ba3994a 5208 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
9c0e94a5 5209 "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
68aed21b
RH
5210 [(set_attr "length" "8")
5211 (set_attr "type" "multi")])
6fd1c67b 5212
9ba3994a 5213(define_insn ""
039d4bce 5214 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
9ba3994a 5215 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
6abc6f40
RH
5216 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5217 [(set_attr "length" "12")
5218 (set_attr "type" "multi")])
5219
5220(define_insn "exception_receiver"
5221 [(unspec_volatile [(const_int 0)] 7)]
5222 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5223 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
68aed21b
RH
5224 [(set_attr "length" "12")
5225 (set_attr "type" "multi")])
9ba3994a 5226
6fd1c67b 5227(define_expand "nonlocal_goto_receiver"
477c16e3
RK
5228 [(unspec_volatile [(const_int 0)] 1)
5229 (set (reg:DI 27) (mem:DI (reg:DI 29)))
5230 (unspec_volatile [(const_int 0)] 1)
5231 (use (reg:DI 27))]
5232 "TARGET_OPEN_VMS"
5233 "")
5234
5235(define_insn "arg_home"
5236 [(unspec [(const_int 0)] 0)
5237 (use (reg:DI 1))
5238 (use (reg:DI 25))
9b80d951
RK
5239 (use (reg:DI 16))
5240 (use (reg:DI 17))
5241 (use (reg:DI 18))
5242 (use (reg:DI 19))
5243 (use (reg:DI 20))
5244 (use (reg:DI 21))
5245 (use (reg:DI 48))
5246 (use (reg:DI 49))
5247 (use (reg:DI 50))
5248 (use (reg:DI 51))
5249 (use (reg:DI 52))
5250 (use (reg:DI 53))
5251 (clobber (mem:BLK (const_int 0)))
477c16e3
RK
5252 (clobber (reg:DI 24))
5253 (clobber (reg:DI 25))
5254 (clobber (reg:DI 0))]
5255 "TARGET_OPEN_VMS"
9c0e94a5 5256 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
68aed21b
RH
5257 [(set_attr "length" "16")
5258 (set_attr "type" "multi")])
2ea844d3
RH
5259
5260;; Close the trap shadow of preceeding instructions. This is generated
5261;; by alpha_reorg.
5262
5263(define_insn "trapb"
4ed43ff8 5264 [(unspec_volatile [(const_int 0)] 4)]
2ea844d3
RH
5265 ""
5266 "trapb"
5267 [(set_attr "type" "misc")])
68aed21b
RH
5268
5269;; No-op instructions used by machine-dependant reorg to preserve
5270;; alignment for instruction issue.
5271
5272(define_insn "nop"
5273 [(const_int 0)]
5274 ""
5275 "nop"
5276 [(set_attr "type" "ilog")])
5277
5278(define_insn "fnop"
5279 [(const_int 1)]
5280 "TARGET_FP"
5281 "fnop"
5282 [(set_attr "type" "fcpys")])
5283
5284(define_insn "unop"
5285 [(const_int 2)]
5286 ""
5287 "unop")
5288
5289(define_insn "realign"
5290 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
5291 ""
5292 ".align %0 #realign")
e83015a9
RH
5293\f
5294;; Peepholes go at the end.
5295
5296;; Optimize sign-extension of SImode loads. This shows up in the wake of
5297;; reload when converting fp->int.
5298;;
9c0e94a5 5299;; ??? What to do now that we actually care about the packing and
e83015a9 5300;; alignment of instructions? Perhaps reload can be enlightened, or
9c0e94a5
RH
5301;; the peephole pass moved up after reload but before sched2?
5302;
5303;(define_peephole
5304; [(set (match_operand:SI 0 "register_operand" "=r")
5305; (match_operand:SI 1 "memory_operand" "m"))
5306; (set (match_operand:DI 2 "register_operand" "=r")
5307; (sign_extend:DI (match_dup 0)))]
5308; "dead_or_set_p (insn, operands[0])"
5309; "ldl %2,%1")
5310;
5311;(define_peephole
5312; [(set (match_operand:SI 0 "register_operand" "=r")
5313; (match_operand:SI 1 "hard_fp_register_operand" "f"))
5314; (set (match_operand:DI 2 "register_operand" "=r")
5315; (sign_extend:DI (match_dup 0)))]
de4abb91 5316; "TARGET_FIX && dead_or_set_p (insn, operands[0])"
9c0e94a5 5317; "ftois %1,%2")