]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/ia64/ia64.md
sibcall.c (skip_pic_restore): New.
[thirdparty/gcc.git] / gcc / config / ia64 / ia64.md
CommitLineData
c65ebc55 1;; IA-64 Machine description template
e65271be 2;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
c65ebc55
JW
3;; Contributed by James E. Wilson <wilson@cygnus.com> and
4;; David Mosberger <davidm@hpl.hp.com>.
5
6;; This file is part of GNU CC.
7
8;; GNU CC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 2, or (at your option)
11;; any later version.
12
13;; GNU CC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
19;; along with GNU CC; see the file COPYING. If not, write to
20;; the Free Software Foundation, 59 Temple Place - Suite 330,
21;; Boston, MA 02111-1307, USA.
22
23;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
c65ebc55
JW
25;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
26;; reload. This will be fixed once scheduling support is turned on.
27
28;; ??? Optimize for post-increment addressing modes.
29
30;; ??? fselect is not supported, because there is no integer register
31;; equivalent.
32
33;; ??? fp abs/min/max instructions may also work for integer values.
34
35;; ??? Would a predicate_reg_operand predicate be useful? The HP one is buggy,
36;; it assumes the operand is a register and takes REGNO of it without checking.
37
38;; ??? Would a branch_reg_operand predicate be useful? The HP one is buggy,
39;; it assumes the operand is a register and takes REGNO of it without checking.
40
41;; ??? Go through list of documented named patterns and look for more to
42;; implement.
43
44;; ??? Go through instruction manual and look for more instructions that
45;; can be emitted.
46
47;; ??? Add function unit scheduling info for Itanium (TM) processor.
48
ce152ef8
AM
49;; ??? The explicit stop in the flushrs pattern is not ideal. It
50;; would be better if rtx_needs_barrier took care of this, but this is
51;; something that can be fixed later.
52
26102535
RH
53;; ??? Need a better way to describe alternate fp status registers.
54
e5bde68a
RH
55;; Unspec usage:
56;;
57;; unspec:
58;; 1 gr_spill
59;; 2 gr_restore
60;; 3 fr_spill
61;; 4 fr_restore
655f2eb9 62;; 5 recip_approx
f2f90c63 63;; 7 pred_rel_mutex
e5bde68a 64;; 8 popcnt
97e242b0 65;; 12 mf
e5bde68a 66;; 13 cmpxchg_acq
e5bde68a
RH
67;; 19 fetchadd_acq
68;; 20 bsp_value
ce152ef8 69;; 21 flushrs
e5bde68a
RH
70;;
71;; unspec_volatile:
72;; 0 alloc
73;; 1 blockage
74;; 2 insn_group_barrier
e5bde68a 75;; 5 set_bsp
ca3920ad
JW
76;; 8 pred.safe_across_calls all
77;; 9 pred.safe_across_calls normal
c65ebc55
JW
78\f
79;; ::::::::::::::::::::
80;; ::
81;; :: Attributes
82;; ::
83;; ::::::::::::::::::::
84
85;; Instruction type. This primarily determines how instructions can be
86;; packed in bundles, and secondarily affects scheduling to function units.
87
88;; A alu, can go in I or M syllable of a bundle
89;; I integer
90;; M memory
91;; F floating-point
92;; B branch
93;; L long immediate, takes two syllables
94;; S stop bit
95
96;; ??? Should not have any pattern with type unknown. Perhaps add code to
97;; check this in md_reorg? Currently use unknown for patterns which emit
98;; multiple instructions, patterns which emit 0 instructions, and patterns
99;; which emit instruction that can go in any slot (e.g. nop).
100
101(define_attr "type" "unknown,A,I,M,F,B,L,S" (const_string "unknown"))
102
e5bde68a
RH
103;; Predication. True iff this instruction can be predicated.
104
105(define_attr "predicable" "no,yes" (const_string "yes"))
106
c65ebc55
JW
107\f
108;; ::::::::::::::::::::
109;; ::
110;; :: Function Units
111;; ::
112;; ::::::::::::::::::::
113
114;; Each usage of a function units by a class of insns is specified with a
115;; `define_function_unit' expression, which looks like this:
116;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
117;; ISSUE-DELAY [CONFLICT-LIST])
118
119;; This default scheduling info seeks to pack instructions into bundles
120;; efficiently to reduce code size, so we just list how many of each
121;; instruction type can go in a bundle. ISSUE_RATE is set to 3.
122
123;; ??? Add scheduler ready-list hook (MD_SCHED_REORDER) that orders
124;; instructions, so that the next instruction can fill the next bundle slot.
125;; This really needs to know where the stop bits are though.
126
127;; ??? Use MD_SCHED_REORDER to put alloc first instead of using an unspec
128;; volatile. Use ADJUST_PRIORITY to set the priority of alloc very high to
129;; make it schedule first.
130
131;; ??? Modify the md_reorg code that emits stop bits so that instead of putting
132;; them in the last possible place, we put them in places where bundles allow
133;; them. This should reduce code size, but may decrease performance if we end
134;; up with more stop bits than the minimum we need.
135
136;; Alu instructions can execute on either the integer or memory function
137;; unit. We indicate this by defining an alu function unit, and then marking
138;; it as busy everytime we issue a integer or memory type instruction.
139
140(define_function_unit "alu" 3 1 (eq_attr "type" "A,I,M") 1 0)
141
142(define_function_unit "integer" 2 1 (eq_attr "type" "I") 1 0)
143
144(define_function_unit "memory" 3 1 (eq_attr "type" "M") 1 0)
145
146(define_function_unit "floating_point" 1 1 (eq_attr "type" "F") 1 0)
147
148(define_function_unit "branch" 3 1 (eq_attr "type" "B") 1 0)
149
150;; ??? This isn't quite right, because we can only fit two insns in a bundle
151;; when using an L type instruction. That isn't modeled currently.
152
153(define_function_unit "long_immediate" 1 1 (eq_attr "type" "L") 1 0)
154
155\f
156;; ::::::::::::::::::::
157;; ::
158;; :: Moves
159;; ::
160;; ::::::::::::::::::::
161
f2f90c63
RH
162;; Set of a single predicate register. This is only used to implement
163;; pr-to-pr move and complement.
164
165(define_insn "*movcci"
166 [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
167 (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
168 ""
169 "@
170 cmp.ne %0, p0 = r0, r0
171 cmp.eq %0, p0 = r0, r0
172 (%1) cmp.eq.unc %0, p0 = r0, r0"
173 [(set_attr "type" "A")
174 (set_attr "predicable" "no")])
175
176(define_insn "movbi"
177 [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m")
178 (match_operand:BI 1 "move_operand" " O,n, c, c,*r, n,*m,*r"))]
179 ""
180 "@
181 cmp.ne %0, %I0 = r0, r0
182 cmp.eq %0, %I0 = r0, r0
183 #
184 #
185 tbit.nz %0, %I0 = %1, 0
186 adds %0 = %1, r0
187 ld1%O1 %0 = %1%P1
188 st1%Q0 %0 = %1%P0"
189 [(set_attr "type" "A,A,unknown,unknown,I,A,M,M")])
190
191(define_split
192 [(set (match_operand:BI 0 "register_operand" "")
193 (match_operand:BI 1 "register_operand" ""))]
194 "reload_completed
195 && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
196 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
197 [(cond_exec (ne (match_dup 1) (const_int 0))
198 (set (match_dup 0) (const_int 1)))
199 (cond_exec (eq (match_dup 1) (const_int 0))
200 (set (match_dup 0) (const_int 0)))]
201 "")
202
203(define_split
204 [(set (match_operand:BI 0 "register_operand" "")
205 (match_operand:BI 1 "register_operand" ""))]
206 "reload_completed
207 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
208 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
209 [(set (match_dup 2) (match_dup 4))
210 (set (match_dup 3) (match_dup 5))
211 (set (match_dup 0) (unspec:BI [(match_dup 0)] 7))]
212 "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
213 operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
214 operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
215 operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
216
c65ebc55
JW
217(define_expand "movqi"
218 [(set (match_operand:QI 0 "general_operand" "")
219 (match_operand:QI 1 "general_operand" ""))]
220 ""
221 "
222{
223 if (! reload_in_progress && ! reload_completed
557b9df5
RH
224 && ! ia64_move_ok (operands[0], operands[1]))
225 operands[1] = force_reg (QImode, operands[1]);
c65ebc55
JW
226}")
227
75cdbeb8
RH
228;; Errata 72 implies that we cannot use predicated loads and stores
229;; on affected systems. Reuse TARGET_A_STEP for convenience.
230
231;; ??? It would be convenient at this point if the cond_exec pattern
232;; expander understood non-constant conditions on attributes. Failing
233;; that we have to replicate patterns.
234
235(define_insn "*movqicc_astep"
236 [(cond_exec
237 (match_operator 2 "predicate_operator"
f2f90c63 238 [(match_operand:BI 3 "register_operand" "c,c,c,c,c")
75cdbeb8
RH
239 (const_int 0)])
240 (set (match_operand:QI 0 "register_operand" "=r,r, r,*f,*f")
241 (match_operand:QI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
242 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
243 "@
244 (%J2) mov %0 = %r1
245 (%J2) addl %0 = %1, r0
246 (%J2) getf.sig %0 = %1
247 (%J2) setf.sig %0 = %r1
248 (%J2) mov %0 = %1"
249 [(set_attr "type" "A,A,M,M,F")
250 (set_attr "predicable" "no")])
251
252(define_insn "*movqi_internal_astep"
4b983fdc
RH
253 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
254 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
75cdbeb8
RH
255 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
256 "@
257 mov %0 = %r1
258 addl %0 = %1, r0
259 ld1%O1 %0 = %1%P1
260 st1%Q0 %0 = %r1%P0
261 getf.sig %0 = %1
262 setf.sig %0 = %r1
263 mov %0 = %1"
264 [(set_attr "type" "A,A,M,M,M,M,F")
265 (set_attr "predicable" "no")])
266
c65ebc55 267(define_insn "*movqi_internal"
4b983fdc
RH
268 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
269 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
75cdbeb8 270 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55 271 "@
13da91fd 272 mov %0 = %r1
c65ebc55
JW
273 addl %0 = %1, r0
274 ld1%O1 %0 = %1%P1
13da91fd 275 st1%Q0 %0 = %r1%P0
c65ebc55 276 getf.sig %0 = %1
13da91fd
RH
277 setf.sig %0 = %r1
278 mov %0 = %1"
279 [(set_attr "type" "A,A,M,M,M,M,F")])
c65ebc55
JW
280
281(define_expand "movhi"
282 [(set (match_operand:HI 0 "general_operand" "")
283 (match_operand:HI 1 "general_operand" ""))]
284 ""
285 "
286{
287 if (! reload_in_progress && ! reload_completed
557b9df5
RH
288 && ! ia64_move_ok (operands[0], operands[1]))
289 operands[1] = force_reg (HImode, operands[1]);
c65ebc55
JW
290}")
291
75cdbeb8
RH
292;; Errata 72 workaround.
293(define_insn "*movhicc_astep"
294 [(cond_exec
295 (match_operator 2 "predicate_operator"
f2f90c63 296 [(match_operand:BI 3 "register_operand" "c,c,c,c,c")
75cdbeb8
RH
297 (const_int 0)])
298 (set (match_operand:HI 0 "register_operand" "=r,r, r,*f,*f")
299 (match_operand:HI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
300 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
301 "@
302 (%J2) mov %0 = %r1
303 (%J2) addl %0 = %1, r0
304 (%J2) getf.sig %0 = %1
305 (%J2) setf.sig %0 = %r1
306 (%J2) mov %0 = %1"
307 [(set_attr "type" "A,A,M,M,F")
308 (set_attr "predicable" "no")])
309
310(define_insn "*movhi_internal_astep"
4b983fdc
RH
311 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
312 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
75cdbeb8
RH
313 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
314 "@
315 mov %0 = %r1
316 addl %0 = %1, r0
317 ld2%O1 %0 = %1%P1
318 st2%Q0 %0 = %r1%P0
319 getf.sig %0 = %1
320 setf.sig %0 = %r1
321 mov %0 = %1"
322 [(set_attr "type" "A,A,M,M,M,M,F")
323 (set_attr "predicable" "no")])
324
c65ebc55 325(define_insn "*movhi_internal"
4b983fdc
RH
326 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
327 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
75cdbeb8 328 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55 329 "@
13da91fd 330 mov %0 = %r1
c65ebc55
JW
331 addl %0 = %1, r0
332 ld2%O1 %0 = %1%P1
13da91fd 333 st2%Q0 %0 = %r1%P0
c65ebc55 334 getf.sig %0 = %1
13da91fd
RH
335 setf.sig %0 = %r1
336 mov %0 = %1"
337 [(set_attr "type" "A,A,M,M,M,M,F")])
c65ebc55
JW
338
339(define_expand "movsi"
340 [(set (match_operand:SI 0 "general_operand" "")
341 (match_operand:SI 1 "general_operand" ""))]
342 ""
343 "
344{
345 if (! reload_in_progress && ! reload_completed
557b9df5
RH
346 && ! ia64_move_ok (operands[0], operands[1]))
347 operands[1] = force_reg (SImode, operands[1]);
c65ebc55
JW
348}")
349
75cdbeb8
RH
350;; Errata 72 workaround.
351(define_insn "*movsicc_astep"
352 [(cond_exec
353 (match_operator 2 "predicate_operator"
f2f90c63 354 [(match_operand:BI 3 "register_operand" "c,c,c,c,c,c,c,c")
75cdbeb8 355 (const_int 0)])
97e242b0 356 (set (match_operand:SI 0 "register_operand" "=r,r,r, r,*f,*f, r,*d")
514f96e6 357 (match_operand:SI 1 "nonmemory_operand" "rO,J,i,*f,rO,*f,*d,rK")))]
75cdbeb8
RH
358 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
359 "@
360 (%J2) mov %0 = %r1
361 (%J2) addl %0 = %1, r0
362 (%J2) movl %0 = %1
363 (%J2) getf.sig %0 = %1
364 (%J2) setf.sig %0 = %r1
97e242b0
RH
365 (%J2) mov %0 = %1
366 (%J2) mov %0 = %1
367 (%J2) mov %0 = %r1"
368 [(set_attr "type" "A,A,L,M,M,F,M,M")
75cdbeb8
RH
369 (set_attr "predicable" "no")])
370
371(define_insn "*movsi_internal_astep"
97e242b0 372 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
514f96e6 373 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
75cdbeb8
RH
374 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
375 "@
376 mov %0 = %r1
377 addl %0 = %1, r0
378 movl %0 = %1
379 ld4%O1 %0 = %1%P1
380 st4%Q0 %0 = %r1%P0
381 getf.sig %0 = %1
382 setf.sig %0 = %r1
97e242b0
RH
383 mov %0 = %1
384 mov %0 = %1
385 mov %0 = %r1"
386 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M")
75cdbeb8
RH
387 (set_attr "predicable" "no")])
388
c65ebc55 389(define_insn "*movsi_internal"
97e242b0 390 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
514f96e6 391 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
75cdbeb8 392 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55 393 "@
13da91fd 394 mov %0 = %r1
c65ebc55
JW
395 addl %0 = %1, r0
396 movl %0 = %1
397 ld4%O1 %0 = %1%P1
13da91fd 398 st4%Q0 %0 = %r1%P0
c65ebc55 399 getf.sig %0 = %1
13da91fd 400 setf.sig %0 = %r1
97e242b0
RH
401 mov %0 = %1
402 mov %0 = %1
403 mov %0 = %r1"
404 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M")])
c65ebc55
JW
405
406(define_expand "movdi"
407 [(set (match_operand:DI 0 "general_operand" "")
408 (match_operand:DI 1 "general_operand" ""))]
409 ""
410 "
411{
9a89adb8
RH
412 if (! reload_in_progress && ! reload_completed
413 && ! ia64_move_ok (operands[0], operands[1]))
414 operands[1] = force_reg (DImode, operands[1]);
ec039e3c 415 if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
c65ebc55 416 {
9a89adb8
RH
417 /* Before optimization starts, delay committing to any particular
418 type of PIC address load. If this function gets deferred, we
419 may acquire information that changes the value of the
420 sdata_symbolic_operand predicate. */
7c866fb5
JW
421 /* But don't delay for function pointers. Loading a function address
422 actually loads the address of the descriptor not the function.
423 If we represent these as SYMBOL_REFs, then they get cse'd with
424 calls, and we end up with calls to the descriptor address instead of
425 calls to the function address. Functions are not candidates for
426 sdata anyways. */
427 if (rtx_equal_function_value_matters
428 && ! (GET_CODE (operands[1]) == SYMBOL_REF
429 && SYMBOL_REF_FLAG (operands[1])))
9a89adb8
RH
430 emit_insn (gen_movdi_symbolic (operands[0], operands[1]));
431 else
432 ia64_expand_load_address (operands[0], operands[1]);
9b7bf67d 433 DONE;
c65ebc55 434 }
c65ebc55
JW
435}")
436
75cdbeb8
RH
437;; Errata 72 workaround.
438(define_insn ""
439 [(cond_exec
440 (match_operator 2 "predicate_operator"
f2f90c63 441 [(match_operand:BI 3 "register_operand" "c,c,c,c,c,c,c,c,c,c,c")
75cdbeb8 442 (const_int 0)])
5527bf14 443 (set (match_operand:DI 0 "register_operand"
514f96e6 444 "=r,r,r, r,*f,*f, r,*b,*e, r,*d")
5527bf14 445 (match_operand:DI 1 "nonmemory_operand"
514f96e6 446 "rO,J,i,*f,rO,*f,*b*e,rO,rK,*d,rK")))]
75cdbeb8
RH
447 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
448 "*
449{
450 static const char * const alt[] = {
451 \"(%J2) mov %0 = %r1\",
452 \"(%J2) addl %0 = %1, r0\",
453 \"(%J2) movl %0 = %1\",
454 \"(%J2) getf.sig %0 = %1\",
455 \"(%J2) setf.sig %0 = %r1\",
456 \"(%J2) mov %0 = %1\",
457 \"(%J2) mov %0 = %1\",
5527bf14
RH
458 \"(%J2) mov %0 = %r1\",
459 \"(%J2) mov %0 = %1\",
514f96e6
RH
460 \"(%J2) mov %0 = %1\",
461 \"(%J2) mov %0 = %1\"
75cdbeb8
RH
462 };
463
464 /* We use 'i' for alternative 2 despite possible PIC problems.
465
466 If we define LEGITIMATE_CONSTANT_P such that symbols are not
467 allowed, then the compiler dumps the data into constant memory
468 instead of letting us read the values from the GOT. Similarly
469 if we use 'n' instead of 'i'.
470
471 Instead, we allow such insns through reload and then split them
472 afterward (even without optimization). Therefore, we should
473 never get so far with a symbolic operand. */
474
475 if (which_alternative == 2 && ! TARGET_NO_PIC
476 && symbolic_operand (operands[1], VOIDmode))
477 abort ();
478
479 return alt[which_alternative];
480}"
514f96e6 481 [(set_attr "type" "A,A,L,M,M,F,I,I,I,M,M")
75cdbeb8
RH
482 (set_attr "predicable" "no")])
483
9a89adb8
RH
484;; This is used during early compilation to delay the decision on
485;; how to refer to a variable as long as possible. This is especially
486;; important between initial rtl generation and optimization for
487;; deferred functions, since we may acquire additional information
488;; on the variables used in the meantime.
489
490(define_insn_and_split "movdi_symbolic"
491 [(set (match_operand:DI 0 "register_operand" "=r")
492 (match_operand:DI 1 "symbolic_operand" "s"))
493 (use (reg:DI 1))]
494 ""
495 "* abort ();"
496 ""
497 [(const_int 0)]
498 "ia64_expand_load_address (operands[0], operands[1]); DONE;")
499
75cdbeb8 500(define_insn "*movdi_internal_astep"
4b983fdc 501 [(set (match_operand:DI 0 "destination_operand"
514f96e6 502 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b,*e, r,*d, r,*c")
4b983fdc 503 (match_operand:DI 1 "move_operand"
514f96e6 504 "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e,rO,rK,*d,rK,*c,rO"))]
75cdbeb8
RH
505 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
506 "*
507{
508 static const char * const alt[] = {
509 \"mov %0 = %r1\",
510 \"addl %0 = %1, r0\",
511 \"movl %0 = %1\",
512 \"ld8%O1 %0 = %1%P1\",
513 \"st8%Q0 %0 = %r1%P0\",
514 \"getf.sig %0 = %1\",
515 \"setf.sig %0 = %r1\",
516 \"mov %0 = %1\",
517 \"ldf8 %0 = %1%P1\",
518 \"stf8 %0 = %1%P0\",
519 \"mov %0 = %1\",
5527bf14
RH
520 \"mov %0 = %r1\",
521 \"mov %0 = %1\",
514f96e6
RH
522 \"mov %0 = %1\",
523 \"mov %0 = %1\",
97e242b0
RH
524 \"mov %0 = pr\",
525 \"mov pr = %1, -1\"
75cdbeb8
RH
526 };
527
528 if (which_alternative == 2 && ! TARGET_NO_PIC
529 && symbolic_operand (operands[1], VOIDmode))
530 abort ();
531
532 return alt[which_alternative];
533}"
514f96e6 534 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,I,M,M,I,I")
75cdbeb8
RH
535 (set_attr "predicable" "no")])
536
c65ebc55 537(define_insn "*movdi_internal"
4b983fdc 538 [(set (match_operand:DI 0 "destination_operand"
514f96e6 539 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b,*e, r,*d, r,*c")
4b983fdc 540 (match_operand:DI 1 "move_operand"
514f96e6 541 "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e,rO,rK,*d,rK,*c,rO"))]
75cdbeb8 542 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
9b7bf67d
RH
543 "*
544{
545 static const char * const alt[] = {
6f8aa100
RH
546 \"%,mov %0 = %r1\",
547 \"%,addl %0 = %1, r0\",
548 \"%,movl %0 = %1\",
549 \"%,ld8%O1 %0 = %1%P1\",
550 \"%,st8%Q0 %0 = %r1%P0\",
551 \"%,getf.sig %0 = %1\",
552 \"%,setf.sig %0 = %r1\",
553 \"%,mov %0 = %1\",
554 \"%,ldf8 %0 = %1%P1\",
555 \"%,stf8 %0 = %1%P0\",
556 \"%,mov %0 = %1\",
5527bf14
RH
557 \"%,mov %0 = %r1\",
558 \"%,mov %0 = %1\",
514f96e6
RH
559 \"%,mov %0 = %1\",
560 \"%,mov %0 = %1\",
97e242b0
RH
561 \"mov %0 = pr\",
562 \"mov pr = %1, -1\"
9b7bf67d
RH
563 };
564
9b7bf67d
RH
565 if (which_alternative == 2 && ! TARGET_NO_PIC
566 && symbolic_operand (operands[1], VOIDmode))
567 abort ();
568
569 return alt[which_alternative];
570}"
514f96e6 571 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,I,M,M,I,I")])
c65ebc55 572
9b7bf67d
RH
573(define_split
574 [(set (match_operand:DI 0 "register_operand" "")
575 (match_operand:DI 1 "symbolic_operand" ""))]
576 "reload_completed && ! TARGET_NO_PIC"
577 [(const_int 0)]
578 "
579{
580 ia64_expand_load_address (operands[0], operands[1]);
581 DONE;
582}")
583
c65ebc55
JW
584(define_expand "load_fptr"
585 [(set (match_dup 2)
586 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))
ec039e3c 587 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
c65ebc55
JW
588 ""
589 "
590{
ec039e3c
RH
591 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
592 operands[3] = gen_rtx_MEM (DImode, operands[2]);
593 RTX_UNCHANGING_P (operands[3]) = 1;
c65ebc55
JW
594}")
595
596(define_insn "*load_fptr_internal1"
597 [(set (match_operand:DI 0 "register_operand" "=r")
598 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "s")))]
599 ""
600 "addl %0 = @ltoff(@fptr(%1)), gp"
601 [(set_attr "type" "A")])
602
603(define_insn "load_gprel"
604 [(set (match_operand:DI 0 "register_operand" "=r")
605 (plus:DI (reg:DI 1) (match_operand:DI 1 "sdata_symbolic_operand" "s")))]
606 ""
607 "addl %0 = @gprel(%1), gp"
608 [(set_attr "type" "A")])
609
59da9a7d
JW
610(define_insn "gprel64_offset"
611 [(set (match_operand:DI 0 "register_operand" "=r")
612 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
613 ""
614 "movl %0 = @gprel(%1)"
615 [(set_attr "type" "L")])
616
617(define_expand "load_gprel64"
618 [(set (match_dup 2)
619 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))
620 (set (match_operand:DI 0 "register_operand" "")
621 (plus:DI (reg:DI 1) (match_dup 2)))]
622 ""
ec039e3c
RH
623 "
624{
625 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
59da9a7d
JW
626}")
627
c65ebc55
JW
628(define_expand "load_symptr"
629 [(set (match_dup 2)
ec039e3c 630 (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "")))
dee4095a 631 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
c65ebc55
JW
632 ""
633 "
634{
ec039e3c 635 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
dee4095a
RH
636 operands[3] = gen_rtx_MEM (DImode, operands[2]);
637 RTX_UNCHANGING_P (operands[3]) = 1;
c65ebc55
JW
638}")
639
640(define_insn "*load_symptr_internal1"
641 [(set (match_operand:DI 0 "register_operand" "=r")
ec039e3c 642 (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "s")))]
c65ebc55
JW
643 ""
644 "addl %0 = @ltoff(%1), gp"
645 [(set_attr "type" "A")])
646
3f622353
RH
647;; With no offsettable memory references, we've got to have a scratch
648;; around to play with the second word.
649(define_expand "movti"
650 [(parallel [(set (match_operand:TI 0 "general_operand" "")
651 (match_operand:TI 1 "general_operand" ""))
652 (clobber (match_scratch:DI 2 ""))])]
653 ""
654 "
655{
656 if (! reload_in_progress && ! reload_completed
657 && ! ia64_move_ok (operands[0], operands[1]))
658 operands[1] = force_reg (TImode, operands[1]);
659}")
660
661(define_insn_and_split "*movti_internal"
662 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
663 (match_operand:TI 1 "general_operand" "ri,m,r"))
664 (clobber (match_scratch:DI 2 "=X,&r,&r"))]
665 "ia64_move_ok (operands[0], operands[1])"
666 "#"
667 "reload_completed"
668 [(const_int 0)]
669 "
670{
671 rtx adj1, adj2, in[2], out[2];
672 int first;
673
674 adj1 = ia64_split_timode (in, operands[1], operands[2]);
675 adj2 = ia64_split_timode (out, operands[0], operands[2]);
676
677 first = 0;
678 if (reg_overlap_mentioned_p (out[0], in[1]))
679 {
680 if (reg_overlap_mentioned_p (out[1], in[0]))
681 abort ();
682 first = 1;
683 }
684
685 if (adj1 && adj2)
686 abort ();
687 if (adj1)
688 emit_insn (adj1);
689 if (adj2)
690 emit_insn (adj2);
691 emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
692 emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
693 DONE;
694}"
695 [(set_attr "type" "unknown")
696 (set_attr "predicable" "no")])
e314e331 697
3f622353
RH
698;; ??? SSA creates these. Can't allow memories since we don't have
699;; the scratch register. Fortunately combine will know how to add
700;; the clobber and scratch.
701(define_insn_and_split "*movti_internal_reg"
702 [(set (match_operand:TI 0 "register_operand" "=r")
703 (match_operand:TI 1 "nonmemory_operand" "ri"))]
704 ""
e314e331 705 "#"
3f622353
RH
706 "reload_completed"
707 [(const_int 0)]
708 "
709{
710 rtx in[2], out[2];
711 int first;
712
713 ia64_split_timode (in, operands[1], NULL_RTX);
714 ia64_split_timode (out, operands[0], NULL_RTX);
715
716 first = 0;
717 if (reg_overlap_mentioned_p (out[0], in[1]))
718 {
719 if (reg_overlap_mentioned_p (out[1], in[0]))
720 abort ();
721 first = 1;
722 }
723
724 emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
725 emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
726 DONE;
727}"
e314e331
JW
728 [(set_attr "type" "unknown")
729 (set_attr "predicable" "no")])
730
3f622353
RH
731(define_expand "reload_inti"
732 [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
733 (match_operand:TI 1 "" "m"))
60a3c181 734 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3f622353
RH
735 ""
736 "
737{
60a3c181
RH
738 unsigned int s_regno = REGNO (operands[2]);
739 if (s_regno == REGNO (operands[0]))
740 s_regno += 1;
741 operands[2] = gen_rtx_REG (DImode, s_regno);
3f622353
RH
742}")
743
744(define_expand "reload_outti"
745 [(parallel [(set (match_operand:TI 0 "" "=m")
746 (match_operand:TI 1 "register_operand" "r"))
60a3c181 747 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3f622353
RH
748 ""
749 "
750{
60a3c181
RH
751 unsigned int s_regno = REGNO (operands[2]);
752 if (s_regno == REGNO (operands[1]))
753 s_regno += 1;
754 operands[2] = gen_rtx_REG (DImode, s_regno);
3f622353 755}")
e314e331 756
c65ebc55
JW
757;; Floating Point Moves
758;;
759;; Note - Patterns for SF mode moves are compulsory, but
760;; patterns for DF are optional, as GCC can synthesise them.
761
762(define_expand "movsf"
763 [(set (match_operand:SF 0 "general_operand" "")
764 (match_operand:SF 1 "general_operand" ""))]
765 ""
766 "
767{
768 if (! reload_in_progress && ! reload_completed
557b9df5
RH
769 && ! ia64_move_ok (operands[0], operands[1]))
770 operands[1] = force_reg (SFmode, operands[1]);
c65ebc55
JW
771}")
772
75cdbeb8
RH
773;; Errata 72 workaround.
774(define_insn "*movsfcc_astep"
775 [(cond_exec
776 (match_operator 2 "predicate_operator"
f2f90c63 777 [(match_operand:BI 3 "register_operand" "c,c,c,c")
75cdbeb8
RH
778 (const_int 0)])
779 (set (match_operand:SF 0 "register_operand" "=f,*r, f,*r")
780 (match_operand:SF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
781 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
782 "@
3f622353
RH
783 (%J2) mov %0 = %F1
784 (%J2) getf.s %0 = %F1
785 (%J2) setf.s %0 = %1
786 (%J2) mov %0 = %1"
75cdbeb8
RH
787 [(set_attr "type" "F,M,M,A")
788 (set_attr "predicable" "no")])
789
790(define_insn "*movsf_internal_astep"
4b983fdc
RH
791 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
792 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
75cdbeb8
RH
793 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
794 "@
795 mov %0 = %F1
796 ldfs %0 = %1%P1
797 stfs %0 = %F1%P0
798 getf.s %0 = %F1
799 setf.s %0 = %1
800 mov %0 = %1
801 ld4%O1 %0 = %1%P1
802 st4%Q0 %0 = %1%P0"
803 [(set_attr "type" "F,M,M,M,M,A,M,M")
804 (set_attr "predicable" "no")])
805
c65ebc55 806(define_insn "*movsf_internal"
4b983fdc
RH
807 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
808 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
75cdbeb8 809 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55
JW
810 "@
811 mov %0 = %F1
812 ldfs %0 = %1%P1
813 stfs %0 = %F1%P0
814 getf.s %0 = %F1
815 setf.s %0 = %1
816 mov %0 = %1
13da91fd
RH
817 ld4%O1 %0 = %1%P1
818 st4%Q0 %0 = %1%P0"
819 [(set_attr "type" "F,M,M,M,M,A,M,M")])
c65ebc55
JW
820
821(define_expand "movdf"
822 [(set (match_operand:DF 0 "general_operand" "")
823 (match_operand:DF 1 "general_operand" ""))]
824 ""
825 "
826{
827 if (! reload_in_progress && ! reload_completed
557b9df5
RH
828 && ! ia64_move_ok (operands[0], operands[1]))
829 operands[1] = force_reg (DFmode, operands[1]);
c65ebc55
JW
830}")
831
75cdbeb8
RH
832;; Errata 72 workaround.
833(define_insn "*movdfcc_astep"
834 [(cond_exec
835 (match_operator 2 "predicate_operator"
f2f90c63 836 [(match_operand:BI 3 "register_operand" "c,c,c,c")
75cdbeb8
RH
837 (const_int 0)])
838 (set (match_operand:DF 0 "register_operand" "=f,*r, f,*r")
839 (match_operand:DF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
840 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
841 "@
3f622353
RH
842 (%J2) mov %0 = %F1
843 (%J2) getf.d %0 = %F1
844 (%J2) setf.d %0 = %1
845 (%J2) mov %0 = %1"
75cdbeb8
RH
846 [(set_attr "type" "F,M,M,A")
847 (set_attr "predicable" "no")])
848
849(define_insn "*movdf_internal_astep"
4b983fdc
RH
850 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
851 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
75cdbeb8
RH
852 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
853 "@
854 mov %0 = %F1
855 ldfd %0 = %1%P1
856 stfd %0 = %F1%P0
857 getf.d %0 = %F1
858 setf.d %0 = %1
859 mov %0 = %1
860 ld8%O1 %0 = %1%P1
861 st8%Q0 %0 = %1%P0"
862 [(set_attr "type" "F,M,M,M,M,A,M,M")
863 (set_attr "predicable" "no")])
864
c65ebc55 865(define_insn "*movdf_internal"
4b983fdc
RH
866 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
867 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
75cdbeb8 868 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55
JW
869 "@
870 mov %0 = %F1
871 ldfd %0 = %1%P1
872 stfd %0 = %F1%P0
873 getf.d %0 = %F1
874 setf.d %0 = %1
13da91fd
RH
875 mov %0 = %1
876 ld8%O1 %0 = %1%P1
877 st8%Q0 %0 = %1%P0"
878 [(set_attr "type" "F,M,M,M,M,A,M,M")])
c65ebc55 879
3f622353
RH
880;; With no offsettable memory references, we've got to have a scratch
881;; around to play with the second word if the variable winds up in GRs.
882(define_expand "movtf"
883 [(set (match_operand:TF 0 "general_operand" "")
884 (match_operand:TF 1 "general_operand" ""))]
e5bde68a
RH
885 ""
886 "
887{
3f622353
RH
888 /* We must support TFmode loads into general registers for stdarg/vararg
889 and unprototyped calls. We split them into DImode loads for convenience.
890 We don't need TFmode stores from general regs, because a stdarg/vararg
891 routine does a block store to memory of unnamed arguments. */
892 if (GET_CODE (operands[0]) == REG
893 && GR_REGNO_P (REGNO (operands[0])))
894 {
895 /* We're hoping to transform everything that deals with TFmode
896 quantities and GR registers early in the compiler. */
897 if (no_new_pseudos)
898 abort ();
899
900 /* Struct to register can just use TImode instead. */
901 if ((GET_CODE (operands[1]) == SUBREG
902 && GET_MODE (SUBREG_REG (operands[1])) == TImode)
903 || (GET_CODE (operands[1]) == REG
904 && GR_REGNO_P (REGNO (operands[1]))))
905 {
906 emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
907 SUBREG_REG (operands[1]));
908 DONE;
909 }
910
911 if (GET_CODE (operands[1]) == CONST_DOUBLE)
912 {
913 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
914 operand_subword (operands[1], 0, 0, DImode));
915 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
916 operand_subword (operands[1], 1, 0, DImode));
917 DONE;
918 }
919
920 /* If the quantity is in a register not known to be GR, spill it. */
921 if (register_operand (operands[1], TFmode))
922 operands[1] = spill_tfmode_operand (operands[1], 1);
923
924 if (GET_CODE (operands[1]) == MEM)
925 {
926 rtx out[2];
927
928 out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
929 out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
930
931 emit_move_insn (out[0], change_address (operands[1], DImode, NULL));
932 emit_move_insn (out[1],
933 change_address (operands[1], DImode,
934 plus_constant (XEXP (operands[1], 0),
935 8)));
936 DONE;
937 }
938
939 abort ();
940 }
941
942 if (! reload_in_progress && ! reload_completed)
943 {
944 operands[0] = spill_tfmode_operand (operands[0], 0);
945 operands[1] = spill_tfmode_operand (operands[1], 0);
946
947 if (! ia64_move_ok (operands[0], operands[1]))
948 operands[1] = force_reg (TFmode, operands[1]);
949 }
e5bde68a
RH
950}")
951
3b572406 952;; ??? There's no easy way to mind volatile acquire/release semantics.
75cdbeb8
RH
953
954;; Errata 72 workaround.
3f622353 955(define_insn "*movtfcc_astep"
75cdbeb8
RH
956 [(cond_exec
957 (match_operator 2 "predicate_operator"
f2f90c63 958 [(match_operand:BI 3 "register_operand" "c")
75cdbeb8 959 (const_int 0)])
3f622353
RH
960 (set (match_operand:TF 0 "register_operand" "=f")
961 (match_operand:TF 1 "nonmemory_operand" "fG")))]
75cdbeb8 962 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
3f622353 963 "(%J2) mov %0 = %F1"
75cdbeb8
RH
964 [(set_attr "type" "F")
965 (set_attr "predicable" "no")])
966
3f622353
RH
967(define_insn "*movtf_internal_astep"
968 [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
969 (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
75cdbeb8
RH
970 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
971 "@
972 mov %0 = %F1
973 ldfe %0 = %1%P1
974 stfe %0 = %F1%P0"
975 [(set_attr "type" "F,M,M")
976 (set_attr "predicable" "no")])
977
3f622353
RH
978(define_insn "*movtf_internal"
979 [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
980 (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
75cdbeb8 981 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
e5bde68a
RH
982 "@
983 mov %0 = %F1
46b1ac3f
JW
984 ldfe %0 = %1%P1
985 stfe %0 = %F1%P0"
e5bde68a 986 [(set_attr "type" "F,M,M")])
c65ebc55
JW
987\f
988;; ::::::::::::::::::::
989;; ::
990;; :: Conversions
991;; ::
992;; ::::::::::::::::::::
993
994;; Signed conversions from a smaller integer to a larger integer
995
996(define_insn "extendqidi2"
0551c32d
RH
997 [(set (match_operand:DI 0 "gr_register_operand" "=r")
998 (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
c65ebc55
JW
999 ""
1000 "sxt1 %0 = %1"
1001 [(set_attr "type" "I")])
1002
1003(define_insn "extendhidi2"
0551c32d
RH
1004 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1005 (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
c65ebc55
JW
1006 ""
1007 "sxt2 %0 = %1"
1008 [(set_attr "type" "I")])
1009
1010(define_insn "extendsidi2"
655f2eb9
RH
1011 [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
1012 (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
c65ebc55
JW
1013 ""
1014 "@
1015 sxt4 %0 = %1
1016 fsxt.r %0 = %1, %1%B0"
1017 [(set_attr "type" "I,F")])
1018
1019;; Unsigned conversions from a smaller integer to a larger integer
1020
1021(define_insn "zero_extendqidi2"
0551c32d
RH
1022 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
1023 (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
c65ebc55
JW
1024 ""
1025 "@
1026 zxt1 %0 = %1
1027 ld1%O1 %0 = %1%P1"
1028 [(set_attr "type" "I,M")])
1029
1030(define_insn "zero_extendhidi2"
0551c32d
RH
1031 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
1032 (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
c65ebc55
JW
1033 ""
1034 "@
1035 zxt2 %0 = %1
1036 ld2%O1 %0 = %1%P1"
1037 [(set_attr "type" "I,M")])
1038
1039(define_insn "zero_extendsidi2"
655f2eb9 1040 [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
0551c32d 1041 (zero_extend:DI
655f2eb9 1042 (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
c65ebc55
JW
1043 ""
1044 "@
1045 zxt4 %0 = %1
1046 ld4%O1 %0 = %1%P1
655f2eb9 1047 fmix.r %0 = f0, %1%B0"
c65ebc55
JW
1048 [(set_attr "type" "I,M,F")])
1049
1050;; Convert between floating point types of different sizes.
1051
e8e20f18
RH
1052;; ??? Optimization opportunity here. Get rid of the insn altogether
1053;; when we can. Should probably use a scheme like has been proposed
1054;; for ia32 in dealing with operands that match unary operators. This
1055;; would let combine merge the thing into adjacent insns.
c65ebc55 1056
e8e20f18 1057(define_insn_and_split "extendsfdf2"
655f2eb9
RH
1058 [(set (match_operand:DF 0 "grfr_nonimmediate_operand" "=f,f,f,f,m,*r")
1059 (float_extend:DF
1060 (match_operand:SF 1 "grfr_nonimmediate_operand" "0,f,m,*r,f,f")))]
c65ebc55 1061 ""
655f2eb9
RH
1062 "@
1063 mov %0 = %1
1064 mov %0 = %1
1065 ldfs %0 = %1%P1
1066 setf.s %0 = %1
1067 stfd %0 = %1%P0
1068 getf.d %0 = %1"
50798048 1069 "reload_completed"
e8e20f18
RH
1070 [(set (match_dup 0) (float_extend:DF (match_dup 1)))]
1071 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
655f2eb9 1072 [(set_attr "type" "F,F,M,M,M,M")])
c65ebc55 1073
3f622353 1074(define_insn_and_split "extendsftf2"
655f2eb9
RH
1075 [(set (match_operand:TF 0 "fr_nonimmediate_operand" "=f,f,f,f,Q")
1076 (float_extend:TF
1077 (match_operand:SF 1 "grfr_nonimmediate_operand" "0,f,Q,*r,f")))]
3f622353 1078 ""
655f2eb9
RH
1079 "@
1080 mov %0 = %1
1081 mov %0 = %1
1082 ldfs %0 = %1%P1
1083 setf.s %0 = %1
1084 stfe %0 = %1%P0"
3f622353
RH
1085 "reload_completed"
1086 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1087 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
655f2eb9 1088 [(set_attr "type" "F,F,M,M,M")])
3f622353
RH
1089
1090(define_insn_and_split "extenddftf2"
655f2eb9
RH
1091 [(set (match_operand:TF 0 "fr_nonimmediate_operand" "=f,f,f,f,Q")
1092 (float_extend:TF
1093 (match_operand:DF 1 "grfr_nonimmediate_operand" "0,f,Q,*r,f")))]
3f622353 1094 ""
655f2eb9
RH
1095 "@
1096 mov %0 = %1
1097 mov %0 = %1
1098 ldfd %0 = %1%P1
1099 setf.d %0 = %1
1100 stfe %0 = %1%P0"
3f622353
RH
1101 "reload_completed"
1102 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1103 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
655f2eb9 1104 [(set_attr "type" "F,F,M,M,M")])
3f622353 1105
c65ebc55 1106(define_insn "truncdfsf2"
0551c32d
RH
1107 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1108 (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1109 ""
1110 "fnorm.s %0 = %1%B0"
1111 [(set_attr "type" "F")])
1112
3f622353 1113(define_insn "trunctfsf2"
0551c32d
RH
1114 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1115 (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
e5bde68a
RH
1116 ""
1117 "fnorm.s %0 = %1%B0"
1118 [(set_attr "type" "F")])
c65ebc55 1119
3f622353 1120(define_insn "trunctfdf2"
0551c32d
RH
1121 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1122 (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
c65ebc55 1123 ""
e5bde68a
RH
1124 "fnorm.d %0 = %1%B0"
1125 [(set_attr "type" "F")])
1126
1127;; Convert between signed integer types and floating point.
1128
3f622353 1129(define_insn "floatditf2"
0551c32d
RH
1130 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1131 (float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
e5bde68a
RH
1132 ""
1133 "fcvt.xf %0 = %1"
1134 [(set_attr "type" "F")])
c65ebc55
JW
1135
1136(define_insn "fix_truncsfdi2"
0551c32d
RH
1137 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1138 (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1139 ""
1140 "fcvt.fx.trunc %0 = %1%B0"
1141 [(set_attr "type" "F")])
1142
1143(define_insn "fix_truncdfdi2"
0551c32d
RH
1144 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1145 (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1146 ""
1147 "fcvt.fx.trunc %0 = %1%B0"
1148 [(set_attr "type" "F")])
1149
3f622353 1150(define_insn "fix_trunctfdi2"
0551c32d
RH
1151 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1152 (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
3f622353
RH
1153 ""
1154 "fcvt.fx.trunc %0 = %1%B0"
1155 [(set_attr "type" "F")])
1156
655f2eb9
RH
1157(define_insn "fix_trunctfdi2_alts"
1158 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1159 (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
1160 (use (match_operand:SI 2 "const_int_operand" ""))]
1161 ""
1162 "fcvt.fx.trunc.s%2 %0 = %1%B0"
1163 [(set_attr "type" "F")])
1164
c65ebc55
JW
1165;; Convert between unsigned integer types and floating point.
1166
1167(define_insn "floatunsdisf2"
0551c32d
RH
1168 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1169 (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
c65ebc55
JW
1170 ""
1171 "fcvt.xuf.s %0 = %1%B0"
1172 [(set_attr "type" "F")])
1173
1174(define_insn "floatunsdidf2"
0551c32d
RH
1175 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1176 (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
c65ebc55
JW
1177 ""
1178 "fcvt.xuf.d %0 = %1%B0"
1179 [(set_attr "type" "F")])
1180
3f622353 1181(define_insn "floatunsditf2"
0551c32d
RH
1182 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1183 (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
3f622353
RH
1184 ""
1185 "fcvt.xuf %0 = %1%B0"
1186 [(set_attr "type" "F")])
1187
c65ebc55 1188(define_insn "fixuns_truncsfdi2"
0551c32d
RH
1189 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1190 (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1191 ""
1192 "fcvt.fxu.trunc %0 = %1%B0"
1193 [(set_attr "type" "F")])
1194
1195(define_insn "fixuns_truncdfdi2"
0551c32d
RH
1196 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1197 (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1198 ""
1199 "fcvt.fxu.trunc %0 = %1%B0"
1200 [(set_attr "type" "F")])
1201
3f622353 1202(define_insn "fixuns_trunctfdi2"
0551c32d
RH
1203 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1204 (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
3f622353
RH
1205 ""
1206 "fcvt.fxu.trunc %0 = %1%B0"
1207 [(set_attr "type" "F")])
655f2eb9
RH
1208
1209(define_insn "fixuns_trunctfdi2_alts"
1210 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1211 (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
1212 (use (match_operand:SI 2 "const_int_operand" ""))]
1213 ""
1214 "fcvt.fxu.trunc.s%2 %0 = %1%B0"
1215 [(set_attr "type" "F")])
c65ebc55
JW
1216\f
1217;; ::::::::::::::::::::
1218;; ::
1219;; :: Bit field extraction
1220;; ::
1221;; ::::::::::::::::::::
1222
c65ebc55 1223(define_insn "extv"
0551c32d
RH
1224 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1225 (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
1226 (match_operand:DI 2 "const_int_operand" "n")
1227 (match_operand:DI 3 "const_int_operand" "n")))]
1228 ""
1229 "extr %0 = %1, %3, %2"
1230 [(set_attr "type" "I")])
1231
1232(define_insn "extzv"
0551c32d
RH
1233 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1234 (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
1235 (match_operand:DI 2 "const_int_operand" "n")
1236 (match_operand:DI 3 "const_int_operand" "n")))]
1237 ""
1238 "extr.u %0 = %1, %3, %2"
1239 [(set_attr "type" "I")])
1240
1241;; Insert a bit field.
1242;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1243;; Source1 can be 0 or -1.
1244;; Source2 can be 0.
1245
1246;; ??? Actual dep instruction is more powerful than what these insv
1247;; patterns support. Unfortunately, combine is unable to create patterns
1248;; where source2 != dest.
1249
1250(define_expand "insv"
0551c32d 1251 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1252 (match_operand:DI 1 "const_int_operand" "")
1253 (match_operand:DI 2 "const_int_operand" ""))
1254 (match_operand:DI 3 "nonmemory_operand" ""))]
1255 ""
1256 "
1257{
1258 int width = INTVAL (operands[1]);
1259 int shift = INTVAL (operands[2]);
1260
1261 /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1262 pseudo. */
1263 if (! register_operand (operands[3], DImode)
1264 && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1265 operands[3] = force_reg (DImode, operands[3]);
1266
1267 /* If this is a single dep instruction, we have nothing to do. */
1268 if (! ((register_operand (operands[3], DImode) && width <= 16)
1269 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1270 {
1271 /* Check for cases that can be implemented with a mix instruction. */
1272 if (width == 32 && shift == 0)
1273 {
1274 /* Directly generating the mix4left instruction confuses
1275 optimize_bit_field in function.c. Since this is performing
1276 a useful optimization, we defer generation of the complicated
1277 mix4left RTL to the first splitting phase. */
1278 rtx tmp = gen_reg_rtx (DImode);
1279 emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1280 DONE;
1281 }
1282 else if (width == 32 && shift == 32)
1283 {
1284 emit_insn (gen_mix4right (operands[0], operands[3]));
1285 DONE;
1286 }
1287
d2ba6dcf
JW
1288 /* We could handle remaining cases by emitting multiple dep
1289 instructions.
1290
1291 If we need more than two dep instructions then we lose. A 6
1292 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1293 mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles,
1294 the latter is 6 cycles on an Itanium (TM) processor, because there is
1295 only one function unit that can execute dep and shr immed.
1296
1297 If we only need two dep instruction, then we still lose.
1298 mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away
1299 the unnecessary mov, this is still undesirable because it will be
1300 hard to optimize, and it creates unnecessary pressure on the I0
1301 function unit. */
1302
c65ebc55
JW
1303 FAIL;
1304
1305#if 0
1306 /* This code may be useful for other IA-64 processors, so we leave it in
1307 for now. */
1308 while (width > 16)
1309 {
1310 rtx tmp;
1311
1312 emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1313 operands[3]));
1314 shift += 16;
1315 width -= 16;
1316 tmp = gen_reg_rtx (DImode);
1317 emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1318 operands[3] = tmp;
1319 }
1320 operands[1] = GEN_INT (width);
1321 operands[2] = GEN_INT (shift);
1322#endif
1323 }
1324}")
1325
1326(define_insn "*insv_internal"
0551c32d 1327 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55
JW
1328 (match_operand:DI 1 "const_int_operand" "n")
1329 (match_operand:DI 2 "const_int_operand" "n"))
1330 (match_operand:DI 3 "nonmemory_operand" "rP"))]
0551c32d 1331 "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
c65ebc55
JW
1332 || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1333 "dep %0 = %3, %0, %2, %1"
1334 [(set_attr "type" "I")])
1335
041f25e6
RH
1336;; Combine doesn't like to create bitfield insertions into zero.
1337(define_insn "*depz_internal"
0551c32d
RH
1338 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1339 (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
041f25e6
RH
1340 (match_operand:DI 2 "const_int_operand" "n"))
1341 (match_operand:DI 3 "const_int_operand" "n")))]
1342 "CONST_OK_FOR_M (INTVAL (operands[2]))
1343 && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1344 "*
1345{
1346 operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1347 return \"%,dep.z %0 = %1, %2, %3\";
1348}"
1349 [(set_attr "type" "I")])
1350
c65ebc55 1351(define_insn "shift_mix4left"
0551c32d 1352 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55 1353 (const_int 32) (const_int 0))
0551c32d
RH
1354 (match_operand:DI 1 "gr_register_operand" "r"))
1355 (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
c65ebc55
JW
1356 ""
1357 "#"
1358 [(set_attr "type" "unknown")])
1359
c65ebc55
JW
1360(define_split
1361 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1362 (const_int 32) (const_int 0))
1363 (match_operand:DI 1 "register_operand" ""))
1364 (clobber (match_operand:DI 2 "register_operand" ""))]
1365 "reload_completed"
1366 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1367 (unspec_volatile [(const_int 0)] 2)
1368 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1369 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1370 "operands[3] = operands[2];")
1371
1372(define_split
1373 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1374 (const_int 32) (const_int 0))
1375 (match_operand:DI 1 "register_operand" ""))
1376 (clobber (match_operand:DI 2 "register_operand" ""))]
1377 "! reload_completed"
1378 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1379 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1380 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1381 "operands[3] = operands[2];")
1382
1383(define_insn "*mix4left"
0551c32d 1384 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55 1385 (const_int 32) (const_int 0))
0551c32d 1386 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
1387 (const_int 32)))]
1388 ""
1389 "mix4.l %0 = %0, %r1"
1390 [(set_attr "type" "I")])
1391
1392(define_insn "mix4right"
0551c32d 1393 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55 1394 (const_int 32) (const_int 32))
0551c32d 1395 (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
c65ebc55
JW
1396 ""
1397 "mix4.r %0 = %r1, %0"
1398 [(set_attr "type" "I")])
1399
1400;; This is used by the rotrsi3 pattern.
1401
1402(define_insn "*mix4right_3op"
0551c32d
RH
1403 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1404 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1405 (ashift:DI (zero_extend:DI
1406 (match_operand:SI 2 "gr_register_operand" "r"))
c65ebc55
JW
1407 (const_int 32))))]
1408 ""
fa9a44e8 1409 "mix4.r %0 = %2, %1"
c65ebc55
JW
1410 [(set_attr "type" "I")])
1411
1412\f
1413;; ::::::::::::::::::::
cf1f6ae3 1414;; ::
f2f90c63
RH
1415;; :: 1 bit Integer arithmetic
1416;; ::
1417;; ::::::::::::::::::::
1418
1419(define_insn_and_split "andbi3"
1420 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1421 (and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1422 (match_operand:BI 2 "register_operand" "c,r,r")))]
1423 ""
1424 "@
1425 #
1426 tbit.nz.and.orcm %0, %I0 = %2, 0
1427 and %0 = %2, %1"
1428 "reload_completed
1429 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1430 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1431 [(cond_exec (eq (match_dup 2) (const_int 0))
1432 (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1433 (match_dup 0))))]
1434 ""
1435 [(set_attr "type" "unknown,I,A")])
1436
1437(define_insn_and_split "*andcmbi3"
1438 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1439 (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
1440 (match_operand:BI 2 "register_operand" "0,0,r")))]
1441 ""
1442 "@
1443 #
1444 tbit.z.and.orcm %0, %I0 = %2, 0
1445 andcm %0 = %2, %1"
1446 "reload_completed
1447 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1448 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1449 [(cond_exec (ne (match_dup 1) (const_int 0))
1450 (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1451 (match_dup 0))))]
1452 ""
1453 [(set_attr "type" "unknown,I,A")])
1454
1455(define_insn_and_split "iorbi3"
1456 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1457 (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1458 (match_operand:BI 2 "register_operand" "c,r,r")))]
1459 ""
1460 "@
1461 #
1462 tbit.nz.or.andcm %0, %I0 = %2, 0
1463 or %0 = %2, %1"
1464 "reload_completed
1465 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1466 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1467 [(cond_exec (ne (match_dup 2) (const_int 0))
1468 (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1469 (match_dup 0))))]
1470 ""
1471 [(set_attr "type" "unknown,I,A")])
1472
1473(define_insn_and_split "*iorcmbi3"
1474 [(set (match_operand:BI 0 "register_operand" "=c,c")
1475 (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
1476 (match_operand:BI 2 "register_operand" "0,0")))]
1477 ""
1478 "@
1479 #
1480 tbit.z.or.andcm %0, %I0 = %2, 0"
1481 "reload_completed
1482 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1483 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1484 [(cond_exec (eq (match_dup 1) (const_int 0))
1485 (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1486 (match_dup 0))))]
1487 ""
1488 [(set_attr "type" "unknown,I")])
1489
1490(define_insn "one_cmplbi2"
1491 [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
1492 (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
1493 (clobber (match_scratch:BI 2 "=X,X,c,X"))]
1494 ""
1495 "@
1496 tbit.z %0, %I0 = %1, 0
1497 xor %0 = 1, %1
1498 #
1499 #"
1500 [(set_attr "type" "I,A,unknown,unknown")])
1501
1502(define_split
1503 [(set (match_operand:BI 0 "register_operand" "")
1504 (not:BI (match_operand:BI 1 "register_operand" "")))
1505 (clobber (match_scratch:BI 2 ""))]
1506 "reload_completed
1507 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1508 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
1509 && rtx_equal_p (operands[0], operands[1])"
1510 [(set (match_dup 4) (match_dup 3))
1511 (set (match_dup 0) (const_int 1))
1512 (cond_exec (ne (match_dup 2) (const_int 0))
1513 (set (match_dup 0) (const_int 0)))
1514 (set (match_dup 0) (unspec:BI [(match_dup 0)] 7))]
1515 "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
1516 operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
1517
1518(define_split
1519 [(set (match_operand:BI 0 "register_operand" "")
1520 (not:BI (match_operand:BI 1 "register_operand" "")))
1521 (clobber (match_scratch:BI 2 ""))]
1522 "reload_completed
1523 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1524 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
1525 && ! rtx_equal_p (operands[0], operands[1])"
1526 [(cond_exec (ne (match_dup 1) (const_int 0))
1527 (set (match_dup 0) (const_int 0)))
1528 (cond_exec (eq (match_dup 1) (const_int 0))
1529 (set (match_dup 0) (const_int 1)))
1530 (set (match_dup 0) (unspec:BI [(match_dup 0)] 7))]
1531 "")
1532
1533(define_insn "*cmpsi_and_0"
1534 [(set (match_operand:BI 0 "register_operand" "=c")
1535 (and:BI (match_operator:BI 4 "predicate_operator"
1536 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1537 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1538 (match_operand:BI 1 "register_operand" "0")))]
1539 ""
1540 "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
1541 [(set_attr "type" "A")])
1542
1543(define_insn "*cmpsi_and_1"
1544 [(set (match_operand:BI 0 "register_operand" "=c")
1545 (and:BI (match_operator:BI 3 "signed_inequality_operator"
1546 [(match_operand:SI 2 "gr_register_operand" "r")
1547 (const_int 0)])
1548 (match_operand:BI 1 "register_operand" "0")))]
1549 ""
1550 "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
1551 [(set_attr "type" "A")])
1552
1553(define_insn "*cmpsi_andnot_0"
1554 [(set (match_operand:BI 0 "register_operand" "=c")
1555 (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1556 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1557 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1558 (match_operand:BI 1 "register_operand" "0")))]
1559 ""
1560 "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
1561 [(set_attr "type" "A")])
1562
1563(define_insn "*cmpsi_andnot_1"
1564 [(set (match_operand:BI 0 "register_operand" "=c")
1565 (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1566 [(match_operand:SI 2 "gr_register_operand" "r")
1567 (const_int 0)]))
1568 (match_operand:BI 1 "register_operand" "0")))]
1569 ""
1570 "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
1571 [(set_attr "type" "A")])
1572
1573(define_insn "*cmpdi_and_0"
1574 [(set (match_operand:BI 0 "register_operand" "=c")
1575 (and:BI (match_operator:BI 4 "predicate_operator"
1576 [(match_operand:DI 2 "gr_register_operand" "r")
1577 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1578 (match_operand:BI 1 "register_operand" "0")))]
1579 ""
1580 "cmp.%C4.and.orcm %0, %I0 = %3, %2"
1581 [(set_attr "type" "A")])
1582
1583(define_insn "*cmpdi_and_1"
1584 [(set (match_operand:BI 0 "register_operand" "=c")
1585 (and:BI (match_operator:BI 3 "signed_inequality_operator"
1586 [(match_operand:DI 2 "gr_register_operand" "r")
1587 (const_int 0)])
1588 (match_operand:BI 1 "register_operand" "0")))]
1589 ""
1590 "cmp.%C3.and.orcm %0, %I0 = r0, %2"
1591 [(set_attr "type" "A")])
1592
1593(define_insn "*cmpdi_andnot_0"
1594 [(set (match_operand:BI 0 "register_operand" "=c")
1595 (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1596 [(match_operand:DI 2 "gr_register_operand" "r")
1597 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1598 (match_operand:BI 1 "register_operand" "0")))]
1599 ""
1600 "cmp.%C4.or.andcm %I0, %0 = %3, %2"
1601 [(set_attr "type" "A")])
1602
1603(define_insn "*cmpdi_andnot_1"
1604 [(set (match_operand:BI 0 "register_operand" "=c")
1605 (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1606 [(match_operand:DI 2 "gr_register_operand" "r")
1607 (const_int 0)]))
1608 (match_operand:BI 1 "register_operand" "0")))]
1609 ""
1610 "cmp.%C3.or.andcm %I0, %0 = r0, %2"
1611 [(set_attr "type" "A")])
1612
1613(define_insn "*tbit_and_0"
1614 [(set (match_operand:BI 0 "register_operand" "=c")
1615 (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1616 (const_int 1))
1617 (const_int 0))
1618 (match_operand:BI 3 "register_operand" "0")))]
1619 ""
1620 "tbit.nz.and.orcm %0, %I0 = %1, 0"
1621 [(set_attr "type" "I")])
1622
1623(define_insn "*tbit_and_1"
1624 [(set (match_operand:BI 0 "register_operand" "=c")
1625 (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1626 (const_int 1))
1627 (const_int 0))
1628 (match_operand:BI 3 "register_operand" "0")))]
1629 ""
1630 "tbit.z.and.orcm %0, %I0 = %1, 0"
1631 [(set_attr "type" "I")])
1632
1633(define_insn "*tbit_and_2"
1634 [(set (match_operand:BI 0 "register_operand" "=c")
1635 (and:BI (ne:BI (zero_extract:DI
1636 (match_operand:DI 1 "gr_register_operand" "r")
1637 (const_int 1)
1638 (match_operand:DI 2 "const_int_operand" "n"))
1639 (const_int 0))
1640 (match_operand:BI 3 "register_operand" "0")))]
1641 ""
1642 "tbit.nz.and.orcm %0, %I0 = %1, %2"
1643 [(set_attr "type" "I")])
1644
1645(define_insn "*tbit_and_3"
1646 [(set (match_operand:BI 0 "register_operand" "=c")
1647 (and:BI (eq:BI (zero_extract:DI
1648 (match_operand:DI 1 "gr_register_operand" "r")
1649 (const_int 1)
1650 (match_operand:DI 2 "const_int_operand" "n"))
1651 (const_int 0))
1652 (match_operand:BI 3 "register_operand" "0")))]
1653 ""
1654 "tbit.z.and.orcm %0, %I0 = %1, %2"
1655 [(set_attr "type" "I")])
1656
1657(define_insn "*cmpsi_or_0"
1658 [(set (match_operand:BI 0 "register_operand" "=c")
1659 (ior:BI (match_operator:BI 4 "predicate_operator"
1660 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1661 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1662 (match_operand:BI 1 "register_operand" "0")))]
1663 ""
1664 "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
1665 [(set_attr "type" "A")])
1666
1667(define_insn "*cmpsi_or_1"
1668 [(set (match_operand:BI 0 "register_operand" "=c")
1669 (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1670 [(match_operand:SI 2 "gr_register_operand" "r")
1671 (const_int 0)])
1672 (match_operand:BI 1 "register_operand" "0")))]
1673 ""
1674 "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
1675 [(set_attr "type" "A")])
1676
1677(define_insn "*cmpsi_orcm_0"
1678 [(set (match_operand:BI 0 "register_operand" "=c")
1679 (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1680 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1681 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1682 (match_operand:BI 1 "register_operand" "0")))]
1683 ""
1684 "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
1685 [(set_attr "type" "A")])
1686
1687(define_insn "*cmpsi_orcm_1"
1688 [(set (match_operand:BI 0 "register_operand" "=c")
1689 (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1690 [(match_operand:SI 2 "gr_register_operand" "r")
1691 (const_int 0)]))
1692 (match_operand:BI 1 "register_operand" "0")))]
1693 ""
1694 "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
1695 [(set_attr "type" "A")])
1696
1697(define_insn "*cmpdi_or_0"
1698 [(set (match_operand:BI 0 "register_operand" "=c")
1699 (ior:BI (match_operator:BI 4 "predicate_operator"
1700 [(match_operand:DI 2 "gr_register_operand" "r")
1701 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1702 (match_operand:BI 1 "register_operand" "0")))]
1703 ""
1704 "cmp.%C4.or.andcm %0, %I0 = %3, %2"
1705 [(set_attr "type" "A")])
1706
1707(define_insn "*cmpdi_or_1"
1708 [(set (match_operand:BI 0 "register_operand" "=c")
1709 (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1710 [(match_operand:DI 2 "gr_register_operand" "r")
1711 (const_int 0)])
1712 (match_operand:BI 1 "register_operand" "0")))]
1713 ""
1714 "cmp.%C3.or.andcm %0, %I0 = r0, %2"
1715 [(set_attr "type" "A")])
1716
1717(define_insn "*cmpdi_orcm_0"
1718 [(set (match_operand:BI 0 "register_operand" "=c")
1719 (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1720 [(match_operand:DI 2 "gr_register_operand" "r")
1721 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1722 (match_operand:BI 1 "register_operand" "0")))]
1723 ""
1724 "cmp.%C4.and.orcm %I0, %0 = %3, %2"
1725 [(set_attr "type" "A")])
1726
1727(define_insn "*cmpdi_orcm_1"
1728 [(set (match_operand:BI 0 "register_operand" "=c")
1729 (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1730 [(match_operand:DI 2 "gr_register_operand" "r")
1731 (const_int 0)]))
1732 (match_operand:BI 1 "register_operand" "0")))]
1733 ""
1734 "cmp.%C3.and.orcm %I0, %0 = r0, %2"
1735 [(set_attr "type" "A")])
1736
1737(define_insn "*tbit_or_0"
1738 [(set (match_operand:BI 0 "register_operand" "=c")
1739 (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1740 (const_int 1))
1741 (const_int 0))
1742 (match_operand:BI 3 "register_operand" "0")))]
1743 ""
1744 "tbit.nz.or.andcm %0, %I0 = %1, 0"
1745 [(set_attr "type" "I")])
1746
1747(define_insn "*tbit_or_1"
1748 [(set (match_operand:BI 0 "register_operand" "=c")
1749 (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1750 (const_int 1))
1751 (const_int 0))
1752 (match_operand:BI 3 "register_operand" "0")))]
1753 ""
1754 "tbit.z.or.andcm %0, %I0 = %1, 0"
1755 [(set_attr "type" "I")])
1756
1757(define_insn "*tbit_or_2"
1758 [(set (match_operand:BI 0 "register_operand" "=c")
1759 (ior:BI (ne:BI (zero_extract:DI
1760 (match_operand:DI 1 "gr_register_operand" "r")
1761 (const_int 1)
1762 (match_operand:DI 2 "const_int_operand" "n"))
1763 (const_int 0))
1764 (match_operand:BI 3 "register_operand" "0")))]
1765 ""
1766 "tbit.nz.or.andcm %0, %I0 = %1, %2"
1767 [(set_attr "type" "I")])
1768
1769(define_insn "*tbit_or_3"
1770 [(set (match_operand:BI 0 "register_operand" "=c")
1771 (ior:BI (eq:BI (zero_extract:DI
1772 (match_operand:DI 1 "gr_register_operand" "r")
1773 (const_int 1)
1774 (match_operand:DI 2 "const_int_operand" "n"))
1775 (const_int 0))
1776 (match_operand:BI 3 "register_operand" "0")))]
1777 ""
1778 "tbit.z.or.andcm %0, %I0 = %1, %2"
1779 [(set_attr "type" "I")])
1780
1781;; Transform test of and/or of setcc into parallel comparisons.
1782
1783(define_split
1784 [(set (match_operand:BI 0 "register_operand" "")
1785 (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1786 (const_int 0))
1787 (match_operand:DI 3 "register_operand" ""))
1788 (const_int 0)))]
1789 ""
1790 [(set (match_dup 0)
1791 (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1792 (match_dup 2)))]
1793 "")
1794
1795(define_split
1796 [(set (match_operand:BI 0 "register_operand" "")
1797 (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1798 (const_int 0))
1799 (match_operand:DI 3 "register_operand" ""))
1800 (const_int 0)))]
1801 ""
1802 [(set (match_dup 0)
1803 (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1804 (match_dup 2)))
1805 (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1806 (clobber (scratch))])]
1807 "")
1808
1809(define_split
1810 [(set (match_operand:BI 0 "register_operand" "")
1811 (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1812 (const_int 0))
1813 (match_operand:DI 3 "register_operand" ""))
1814 (const_int 0)))]
1815 ""
1816 [(set (match_dup 0)
1817 (ior:BI (ne:BI (match_dup 3) (const_int 0))
1818 (match_dup 2)))]
1819 "")
1820
1821(define_split
1822 [(set (match_operand:BI 0 "register_operand" "")
1823 (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1824 (const_int 0))
1825 (match_operand:DI 3 "register_operand" ""))
1826 (const_int 0)))]
1827 ""
1828 [(set (match_dup 0)
1829 (ior:BI (ne:BI (match_dup 3) (const_int 0))
1830 (match_dup 2)))
1831 (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1832 (clobber (scratch))])]
1833 "")
1834
1835;; ??? Incredibly hackish. Either need four proper patterns with all
1836;; the alternatives, or rely on sched1 to split the insn and hope that
1837;; nothing bad happens to the comparisons in the meantime.
1838;;
1839;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
1840;; that we're doing height reduction.
1841;
1842;(define_insn_and_split ""
1843; [(set (match_operand:BI 0 "register_operand" "=c")
1844; (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1845; [(match_operand 2 "" "")
1846; (match_operand 3 "" "")])
1847; (match_operator:BI 4 "comparison_operator"
1848; [(match_operand 5 "" "")
1849; (match_operand 6 "" "")]))
1850; (match_dup 0)))]
1851; "flag_schedule_insns"
1852; "#"
1853; ""
1854; [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
1855; (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
1856; "")
1857;
1858;(define_insn_and_split ""
1859; [(set (match_operand:BI 0 "register_operand" "=c")
1860; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1861; [(match_operand 2 "" "")
1862; (match_operand 3 "" "")])
1863; (match_operator:BI 4 "comparison_operator"
1864; [(match_operand 5 "" "")
1865; (match_operand 6 "" "")]))
1866; (match_dup 0)))]
1867; "flag_schedule_insns"
1868; "#"
1869; ""
1870; [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
1871; (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
1872; "")
1873;
1874;(define_split
1875; [(set (match_operand:BI 0 "register_operand" "")
1876; (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1877; [(match_operand 2 "" "")
1878; (match_operand 3 "" "")])
1879; (match_operand:BI 7 "register_operand" ""))
1880; (and:BI (match_operator:BI 4 "comparison_operator"
1881; [(match_operand 5 "" "")
1882; (match_operand 6 "" "")])
1883; (match_operand:BI 8 "register_operand" ""))))]
1884; ""
1885; [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
1886; (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
1887; (match_dup 0)))]
1888; "")
1889;
1890;(define_split
1891; [(set (match_operand:BI 0 "register_operand" "")
1892; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1893; [(match_operand 2 "" "")
1894; (match_operand 3 "" "")])
1895; (match_operand:BI 7 "register_operand" ""))
1896; (ior:BI (match_operator:BI 4 "comparison_operator"
1897; [(match_operand 5 "" "")
1898; (match_operand 6 "" "")])
1899; (match_operand:BI 8 "register_operand" ""))))]
1900; ""
1901; [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
1902; (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
1903; (match_dup 0)))]
1904; "")
1905
1906;; Try harder to avoid predicate copies by duplicating compares.
1907;; Note that we'll have already split the predicate copy, which
1908;; is kind of a pain, but oh well.
1909
1910(define_peephole2
1911 [(set (match_operand:BI 0 "register_operand" "")
1912 (match_operand:BI 1 "comparison_operator" ""))
1913 (set (match_operand:CCI 2 "register_operand" "")
1914 (match_operand:CCI 3 "register_operand" ""))
1915 (set (match_operand:CCI 4 "register_operand" "")
1916 (match_operand:CCI 5 "register_operand" ""))
1917 (set (match_operand:BI 6 "register_operand" "")
1918 (unspec:BI [(match_dup 6)] 7))]
1919 "REGNO (operands[3]) == REGNO (operands[0])
1920 && REGNO (operands[4]) == REGNO (operands[0]) + 1
1921 && REGNO (operands[4]) == REGNO (operands[2]) + 1
1922 && REGNO (operands[6]) == REGNO (operands[2])"
1923 [(set (match_dup 0) (match_dup 1))
1924 (set (match_dup 6) (match_dup 7))]
1925 "operands[7] = copy_rtx (operands[1]);")
1926\f
1927;; ::::::::::::::::::::
1928;; ::
cf1f6ae3
RH
1929;; :: 16 bit Integer arithmetic
1930;; ::
1931;; ::::::::::::::::::::
1932
1933(define_insn "mulhi3"
1934 [(set (match_operand:HI 0 "gr_register_operand" "=r")
1935 (mult:HI (match_operand:HI 1 "gr_register_operand" "r")
1936 (match_operand:HI 2 "gr_register_operand" "r")))]
1937 ""
2a7ffc85 1938 "pmpy2.r %0 = %1, %2"
cf1f6ae3
RH
1939 [(set_attr "type" "I")])
1940
1941\f
1942;; ::::::::::::::::::::
c65ebc55
JW
1943;; ::
1944;; :: 32 bit Integer arithmetic
1945;; ::
1946;; ::::::::::::::::::::
1947
058557c4 1948(define_insn "addsi3"
0551c32d
RH
1949 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1950 (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1951 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
c65ebc55
JW
1952 ""
1953 "@
1954 add %0 = %1, %2
1955 adds %0 = %2, %1
1956 addl %0 = %2, %1"
1957 [(set_attr "type" "A")])
1958
1959(define_insn "*addsi3_plus1"
0551c32d
RH
1960 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1961 (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1962 (match_operand:SI 2 "gr_register_operand" "r"))
c65ebc55
JW
1963 (const_int 1)))]
1964 ""
1965 "add %0 = %1, %2, 1"
1966 [(set_attr "type" "A")])
1967
5527bf14 1968(define_insn "*addsi3_plus1_alt"
0551c32d
RH
1969 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1970 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
5527bf14
RH
1971 (const_int 2))
1972 (const_int 1)))]
1973 ""
1974 "add %0 = %1, %1, 1"
1975 [(set_attr "type" "A")])
1976
058557c4 1977(define_insn "*addsi3_shladd"
0551c32d
RH
1978 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1979 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
058557c4 1980 (match_operand:SI 2 "shladd_operand" "n"))
0551c32d 1981 (match_operand:SI 3 "gr_register_operand" "r")))]
c65ebc55 1982 ""
058557c4
RH
1983 "shladd %0 = %1, %S2, %3"
1984 [(set_attr "type" "A")])
c65ebc55 1985
058557c4 1986(define_insn "subsi3"
0551c32d
RH
1987 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1988 (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1989 (match_operand:SI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1990 ""
1991 "sub %0 = %1, %2"
1992 [(set_attr "type" "A")])
1993
1994(define_insn "*subsi3_minus1"
0551c32d
RH
1995 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1996 (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1997 (match_operand:SI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1998 ""
1999 "sub %0 = %2, %1, 1"
2000 [(set_attr "type" "A")])
2001
058557c4 2002(define_insn "mulsi3"
0551c32d 2003 [(set (match_operand:SI 0 "fr_register_operand" "=f")
11a13704
RH
2004 (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
2005 (match_operand:SI 2 "grfr_register_operand" "f")))]
c65ebc55 2006 ""
f2f90c63 2007 "xmpy.l %0 = %1, %2%B0"
c65ebc55
JW
2008 [(set_attr "type" "F")])
2009
655f2eb9 2010(define_insn "maddsi4"
11a13704
RH
2011 [(set (match_operand:SI 0 "fr_register_operand" "=f")
2012 (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
2013 (match_operand:SI 2 "grfr_register_operand" "f"))
2014 (match_operand:SI 3 "grfr_register_operand" "f")))]
2015 ""
2016 "xma.l %0 = %1, %2, %3%B0"
2017 [(set_attr "type" "F")])
2018
058557c4 2019(define_insn "negsi2"
0551c32d
RH
2020 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2021 (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
c65ebc55
JW
2022 ""
2023 "sub %0 = r0, %1"
2024 [(set_attr "type" "A")])
2025
2026(define_expand "abssi2"
2027 [(set (match_dup 2)
f2f90c63 2028 (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
0551c32d 2029 (set (match_operand:SI 0 "gr_register_operand" "")
f2f90c63 2030 (if_then_else:SI (eq (match_dup 2) (const_int 0))
e5bde68a
RH
2031 (neg:SI (match_dup 1))
2032 (match_dup 1)))]
c65ebc55
JW
2033 ""
2034 "
2035{
f2f90c63 2036 operands[2] = gen_reg_rtx (BImode);
c65ebc55
JW
2037}")
2038
2039(define_expand "sminsi3"
2040 [(set (match_dup 3)
f2f90c63 2041 (ge:BI (match_operand:SI 1 "gr_register_operand" "")
0551c32d
RH
2042 (match_operand:SI 2 "gr_register_operand" "")))
2043 (set (match_operand:SI 0 "gr_register_operand" "")
f2f90c63 2044 (if_then_else:SI (ne (match_dup 3) (const_int 0))
c65ebc55
JW
2045 (match_dup 2) (match_dup 1)))]
2046 ""
2047 "
2048{
f2f90c63 2049 operands[3] = gen_reg_rtx (BImode);
c65ebc55
JW
2050}")
2051
2052(define_expand "smaxsi3"
2053 [(set (match_dup 3)
f2f90c63 2054 (ge:BI (match_operand:SI 1 "gr_register_operand" "")
0551c32d
RH
2055 (match_operand:SI 2 "gr_register_operand" "")))
2056 (set (match_operand:SI 0 "gr_register_operand" "")
f2f90c63 2057 (if_then_else:SI (ne (match_dup 3) (const_int 0))
c65ebc55
JW
2058 (match_dup 1) (match_dup 2)))]
2059 ""
2060 "
2061{
f2f90c63 2062 operands[3] = gen_reg_rtx (BImode);
c65ebc55
JW
2063}")
2064
2065(define_expand "uminsi3"
2066 [(set (match_dup 3)
f2f90c63 2067 (geu:BI (match_operand:SI 1 "gr_register_operand" "")
0551c32d
RH
2068 (match_operand:SI 2 "gr_register_operand" "")))
2069 (set (match_operand:SI 0 "gr_register_operand" "")
f2f90c63 2070 (if_then_else:SI (ne (match_dup 3) (const_int 0))
c65ebc55
JW
2071 (match_dup 2) (match_dup 1)))]
2072 ""
2073 "
2074{
f2f90c63 2075 operands[3] = gen_reg_rtx (BImode);
c65ebc55
JW
2076}")
2077
2078(define_expand "umaxsi3"
2079 [(set (match_dup 3)
f2f90c63 2080 (geu:BI (match_operand:SI 1 "gr_register_operand" "")
0551c32d
RH
2081 (match_operand:SI 2 "gr_register_operand" "")))
2082 (set (match_operand:SI 0 "gr_register_operand" "")
f2f90c63 2083 (if_then_else:SI (ne (match_dup 3) (const_int 0))
c65ebc55
JW
2084 (match_dup 1) (match_dup 2)))]
2085 ""
2086 "
2087{
f2f90c63 2088 operands[3] = gen_reg_rtx (BImode);
c65ebc55
JW
2089}")
2090
655f2eb9
RH
2091(define_expand "divsi3"
2092 [(set (match_operand:SI 0 "register_operand" "")
2093 (div:SI (match_operand:SI 1 "general_operand" "")
2094 (match_operand:SI 2 "general_operand" "")))]
2095 "TARGET_INLINE_DIV"
2096 "
2097{
2098 rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
2099
2100 op0_tf = gen_reg_rtx (TFmode);
2101 op0_di = gen_reg_rtx (DImode);
2102
2103 if (CONSTANT_P (operands[1]))
2104 operands[1] = force_reg (SImode, operands[1]);
2105 op1_tf = gen_reg_rtx (TFmode);
2106 expand_float (op1_tf, operands[1], 0);
2107
2108 if (CONSTANT_P (operands[2]))
2109 operands[2] = force_reg (SImode, operands[2]);
2110 op2_tf = gen_reg_rtx (TFmode);
2111 expand_float (op2_tf, operands[2], 0);
2112
2113 /* 2^-34 */
2114#if 0
2115 twon34 = (CONST_DOUBLE_FROM_REAL_VALUE
2116 (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), TFmode));
2117 twon34 = force_reg (TFmode, twon34);
2118#else
2119 twon34 = gen_reg_rtx (TFmode);
2120 convert_move (twon34, force_const_mem (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), SFmode)), 0);
2121#endif
2122
2123 emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
2124
2125 emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
2126 emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
2127 DONE;
2128}")
2129
2130(define_expand "modsi3"
2131 [(set (match_operand:SI 0 "register_operand" "")
2132 (mod:SI (match_operand:SI 1 "general_operand" "")
2133 (match_operand:SI 2 "general_operand" "")))]
2134 "TARGET_INLINE_DIV"
2135 "
2136{
2137 rtx op2_neg, op1_di, div;
2138
2139 div = gen_reg_rtx (SImode);
2140 emit_insn (gen_divsi3 (div, operands[1], operands[2]));
2141
2142 op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2143
2144 /* This is a trick to get us to reuse the value that we're sure to
2145 have already copied to the FP regs. */
2146 op1_di = gen_reg_rtx (DImode);
2147 convert_move (op1_di, operands[1], 0);
2148
2149 emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2150 gen_lowpart (SImode, op1_di)));
2151 DONE;
2152}")
2153
2154(define_expand "udivsi3"
2155 [(set (match_operand:SI 0 "register_operand" "")
2156 (udiv:SI (match_operand:SI 1 "general_operand" "")
2157 (match_operand:SI 2 "general_operand" "")))]
2158 "TARGET_INLINE_DIV"
2159 "
2160{
2161 rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
2162
2163 op0_tf = gen_reg_rtx (TFmode);
2164 op0_di = gen_reg_rtx (DImode);
2165
2166 if (CONSTANT_P (operands[1]))
2167 operands[1] = force_reg (SImode, operands[1]);
2168 op1_tf = gen_reg_rtx (TFmode);
2169 expand_float (op1_tf, operands[1], 1);
2170
2171 if (CONSTANT_P (operands[2]))
2172 operands[2] = force_reg (SImode, operands[2]);
2173 op2_tf = gen_reg_rtx (TFmode);
2174 expand_float (op2_tf, operands[2], 1);
2175
2176 /* 2^-34 */
2177#if 0
2178 twon34 = (CONST_DOUBLE_FROM_REAL_VALUE
2179 (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), TFmode));
2180 twon34 = force_reg (TFmode, twon34);
2181#else
2182 twon34 = gen_reg_rtx (TFmode);
2183 convert_move (twon34, force_const_mem (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), SFmode)), 0);
2184#endif
2185
2186 emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
2187
2188 emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
2189 emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
2190 DONE;
2191}")
2192
2193(define_expand "umodsi3"
2194 [(set (match_operand:SI 0 "register_operand" "")
2195 (umod:SI (match_operand:SI 1 "general_operand" "")
2196 (match_operand:SI 2 "general_operand" "")))]
2197 "TARGET_INLINE_DIV"
2198 "
2199{
2200 rtx op2_neg, op1_di, div;
2201
2202 div = gen_reg_rtx (SImode);
2203 emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
2204
2205 op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2206
2207 /* This is a trick to get us to reuse the value that we're sure to
2208 have already copied to the FP regs. */
2209 op1_di = gen_reg_rtx (DImode);
2210 convert_move (op1_di, operands[1], 1);
2211
2212 emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2213 gen_lowpart (SImode, op1_di)));
2214 DONE;
2215}")
2216
2217(define_insn_and_split "divsi3_internal"
2218 [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2219 (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2220 (match_operand:TF 2 "fr_register_operand" "f"))))
2221 (clobber (match_scratch:TF 4 "=&f"))
2222 (clobber (match_scratch:TF 5 "=&f"))
f2f90c63 2223 (clobber (match_scratch:BI 6 "=c"))
655f2eb9
RH
2224 (use (match_operand:TF 3 "fr_register_operand" "f"))]
2225 "TARGET_INLINE_DIV"
2226 "#"
2227 "&& reload_completed"
2228 [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
f2f90c63 2229 (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
655f2eb9
RH
2230 (use (const_int 1))])
2231 (cond_exec (ne (match_dup 6) (const_int 0))
2232 (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
2233 (use (const_int 1))]))
2234 (cond_exec (ne (match_dup 6) (const_int 0))
2235 (parallel [(set (match_dup 5)
2236 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2237 (match_dup 7)))
2238 (use (const_int 1))]))
2239 (cond_exec (ne (match_dup 6) (const_int 0))
2240 (parallel [(set (match_dup 4)
2241 (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2242 (match_dup 4)))
2243 (use (const_int 1))]))
2244 (cond_exec (ne (match_dup 6) (const_int 0))
2245 (parallel [(set (match_dup 5)
2246 (plus:TF (mult:TF (match_dup 5) (match_dup 5))
2247 (match_dup 3)))
2248 (use (const_int 1))]))
2249 (cond_exec (ne (match_dup 6) (const_int 0))
2250 (parallel [(set (match_dup 0)
2251 (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2252 (match_dup 4)))
2253 (use (const_int 1))]))
2254 ]
2255 "operands[7] = CONST1_RTX (TFmode);"
2256 [(set_attr "predicable" "no")])
c65ebc55
JW
2257\f
2258;; ::::::::::::::::::::
2259;; ::
2260;; :: 64 bit Integer arithmetic
2261;; ::
2262;; ::::::::::::::::::::
2263
2264(define_insn "adddi3"
0551c32d
RH
2265 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
2266 (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
2267 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
c65ebc55
JW
2268 ""
2269 "@
2270 add %0 = %1, %2
2271 adds %0 = %2, %1
2272 addl %0 = %2, %1"
2273 [(set_attr "type" "A")])
2274
2275(define_insn "*adddi3_plus1"
0551c32d
RH
2276 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2277 (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
2278 (match_operand:DI 2 "gr_register_operand" "r"))
c65ebc55
JW
2279 (const_int 1)))]
2280 ""
2281 "add %0 = %1, %2, 1"
2282 [(set_attr "type" "A")])
2283
5527bf14
RH
2284;; This has some of the same problems as shladd. We let the shladd
2285;; eliminator hack handle it, which results in the 1 being forced into
2286;; a register, but not more ugliness here.
2287(define_insn "*adddi3_plus1_alt"
0551c32d
RH
2288 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2289 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
5527bf14
RH
2290 (const_int 2))
2291 (const_int 1)))]
2292 ""
2293 "add %0 = %1, %1, 1"
2294 [(set_attr "type" "A")])
2295
c65ebc55 2296(define_insn "subdi3"
0551c32d
RH
2297 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2298 (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
2299 (match_operand:DI 2 "gr_register_operand" "r")))]
c65ebc55
JW
2300 ""
2301 "sub %0 = %1, %2"
2302 [(set_attr "type" "A")])
2303
2304(define_insn "*subdi3_minus1"
0551c32d
RH
2305 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2306 (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
2307 (match_operand:DI 2 "gr_register_operand" "r")))]
c65ebc55
JW
2308 ""
2309 "sub %0 = %2, %1, 1"
2310 [(set_attr "type" "A")])
2311
cee58bc0
RH
2312;; ??? Use grfr instead of fr because of virtual register elimination
2313;; and silly test cases multiplying by the frame pointer.
c65ebc55 2314(define_insn "muldi3"
0551c32d 2315 [(set (match_operand:DI 0 "fr_register_operand" "=f")
cee58bc0
RH
2316 (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2317 (match_operand:DI 2 "grfr_register_operand" "f")))]
c65ebc55 2318 ""
f2f90c63 2319 "xmpy.l %0 = %1, %2%B0"
c65ebc55
JW
2320 [(set_attr "type" "F")])
2321
2322;; ??? If operand 3 is an eliminable reg, then register elimination causes the
2323;; same problem that we have with shladd below. Unfortunately, this case is
2324;; much harder to fix because the multiply puts the result in an FP register,
2325;; but the add needs inputs from a general register. We add a spurious clobber
2326;; here so that it will be present just in case register elimination gives us
2327;; the funny result.
2328
2329;; ??? Maybe validate_changes should try adding match_scratch clobbers?
2330
2331;; ??? Maybe we should change how adds are canonicalized.
2332
655f2eb9 2333(define_insn "madddi4"
0551c32d 2334 [(set (match_operand:DI 0 "fr_register_operand" "=f")
11a13704
RH
2335 (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2336 (match_operand:DI 2 "grfr_register_operand" "f"))
2337 (match_operand:DI 3 "grfr_register_operand" "f")))
c65ebc55
JW
2338 (clobber (match_scratch:DI 4 "=X"))]
2339 ""
2340 "xma.l %0 = %1, %2, %3%B0"
2341 [(set_attr "type" "F")])
2342
2343;; This can be created by register elimination if operand3 of shladd is an
2344;; eliminable register or has reg_equiv_constant set.
2345
2346;; We have to use nonmemory_operand for operand 4, to ensure that the
2347;; validate_changes call inside eliminate_regs will always succeed. If it
655f2eb9 2348;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
c65ebc55
JW
2349;; incorrectly.
2350
655f2eb9 2351(define_insn "*madddi4_elim"
c65ebc55 2352 [(set (match_operand:DI 0 "register_operand" "=&r")
13da91fd
RH
2353 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
2354 (match_operand:DI 2 "register_operand" "f"))
2355 (match_operand:DI 3 "register_operand" "f"))
c65ebc55 2356 (match_operand:DI 4 "nonmemory_operand" "rI")))
13da91fd 2357 (clobber (match_scratch:DI 5 "=f"))]
c65ebc55
JW
2358 "reload_in_progress"
2359 "#"
2360 [(set_attr "type" "unknown")])
2361
2362;; ??? Need to emit an instruction group barrier here because this gets split
2363;; after md_reorg.
2364
2365(define_split
2366 [(set (match_operand:DI 0 "register_operand" "")
2367 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2368 (match_operand:DI 2 "register_operand" ""))
2369 (match_operand:DI 3 "register_operand" ""))
0551c32d 2370 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
c65ebc55
JW
2371 (clobber (match_scratch:DI 5 ""))]
2372 "reload_completed"
2373 [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2374 (match_dup 3)))
2375 (clobber (match_dup 0))])
2376 (unspec_volatile [(const_int 0)] 2)
2377 (set (match_dup 0) (match_dup 5))
2378 (unspec_volatile [(const_int 0)] 2)
2379 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
2380 "")
2381
2382;; ??? There are highpart multiply and add instructions, but we have no way
2383;; to generate them.
2384
2385(define_insn "smuldi3_highpart"
0551c32d 2386 [(set (match_operand:DI 0 "fr_register_operand" "=f")
c65ebc55
JW
2387 (truncate:DI
2388 (lshiftrt:TI
0551c32d
RH
2389 (mult:TI (sign_extend:TI
2390 (match_operand:DI 1 "fr_register_operand" "f"))
2391 (sign_extend:TI
2392 (match_operand:DI 2 "fr_register_operand" "f")))
c65ebc55
JW
2393 (const_int 64))))]
2394 ""
f2f90c63 2395 "xmpy.h %0 = %1, %2%B0"
c65ebc55
JW
2396 [(set_attr "type" "F")])
2397
2398(define_insn "umuldi3_highpart"
0551c32d 2399 [(set (match_operand:DI 0 "fr_register_operand" "=f")
c65ebc55
JW
2400 (truncate:DI
2401 (lshiftrt:TI
0551c32d
RH
2402 (mult:TI (zero_extend:TI
2403 (match_operand:DI 1 "fr_register_operand" "f"))
2404 (zero_extend:TI
2405 (match_operand:DI 2 "fr_register_operand" "f")))
c65ebc55
JW
2406 (const_int 64))))]
2407 ""
f2f90c63 2408 "xmpy.hu %0 = %1, %2%B0"
c65ebc55
JW
2409 [(set_attr "type" "F")])
2410
2411(define_insn "negdi2"
0551c32d
RH
2412 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2413 (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
c65ebc55
JW
2414 ""
2415 "sub %0 = r0, %1"
2416 [(set_attr "type" "A")])
2417
2418(define_expand "absdi2"
2419 [(set (match_dup 2)
f2f90c63 2420 (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
0551c32d 2421 (set (match_operand:DI 0 "gr_register_operand" "")
f2f90c63 2422 (if_then_else:DI (eq (match_dup 2) (const_int 0))
e5bde68a
RH
2423 (neg:DI (match_dup 1))
2424 (match_dup 1)))]
c65ebc55
JW
2425 ""
2426 "
2427{
f2f90c63 2428 operands[2] = gen_reg_rtx (BImode);
c65ebc55
JW
2429}")
2430
2431(define_expand "smindi3"
2432 [(set (match_dup 3)
f2f90c63 2433 (ge:BI (match_operand:DI 1 "gr_register_operand" "")
0551c32d
RH
2434 (match_operand:DI 2 "gr_register_operand" "")))
2435 (set (match_operand:DI 0 "gr_register_operand" "")
f2f90c63 2436 (if_then_else:DI (ne (match_dup 3) (const_int 0))
c65ebc55
JW
2437 (match_dup 2) (match_dup 1)))]
2438 ""
2439 "
2440{
f2f90c63 2441 operands[3] = gen_reg_rtx (BImode);
c65ebc55
JW
2442}")
2443
2444(define_expand "smaxdi3"
2445 [(set (match_dup 3)
f2f90c63 2446 (ge:BI (match_operand:DI 1 "gr_register_operand" "")
0551c32d
RH
2447 (match_operand:DI 2 "gr_register_operand" "")))
2448 (set (match_operand:DI 0 "gr_register_operand" "")
f2f90c63 2449 (if_then_else:DI (ne (match_dup 3) (const_int 0))
c65ebc55
JW
2450 (match_dup 1) (match_dup 2)))]
2451 ""
2452 "
2453{
f2f90c63 2454 operands[3] = gen_reg_rtx (BImode);
c65ebc55
JW
2455}")
2456
2457(define_expand "umindi3"
2458 [(set (match_dup 3)
f2f90c63 2459 (geu:BI (match_operand:DI 1 "gr_register_operand" "")
0551c32d
RH
2460 (match_operand:DI 2 "gr_register_operand" "")))
2461 (set (match_operand:DI 0 "gr_register_operand" "")
f2f90c63 2462 (if_then_else:DI (ne (match_dup 3) (const_int 0))
c65ebc55
JW
2463 (match_dup 2) (match_dup 1)))]
2464 ""
2465 "
2466{
f2f90c63 2467 operands[3] = gen_reg_rtx (BImode);
c65ebc55
JW
2468}")
2469
2470(define_expand "umaxdi3"
2471 [(set (match_dup 3)
f2f90c63 2472 (geu:BI (match_operand:DI 1 "gr_register_operand" "")
0551c32d
RH
2473 (match_operand:DI 2 "gr_register_operand" "")))
2474 (set (match_operand:DI 0 "gr_register_operand" "")
f2f90c63 2475 (if_then_else:DI (ne (match_dup 3) (const_int 0))
c65ebc55
JW
2476 (match_dup 1) (match_dup 2)))]
2477 ""
2478 "
2479{
f2f90c63 2480 operands[3] = gen_reg_rtx (BImode);
c65ebc55
JW
2481}")
2482
2483(define_expand "ffsdi2"
2484 [(set (match_dup 6)
f2f90c63 2485 (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
c65ebc55
JW
2486 (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
2487 (set (match_dup 5) (const_int 0))
2488 (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2489 (set (match_dup 4) (unspec:DI [(match_dup 3)] 8))
0551c32d 2490 (set (match_operand:DI 0 "gr_register_operand" "")
f2f90c63 2491 (if_then_else:DI (ne (match_dup 6) (const_int 0))
c65ebc55
JW
2492 (match_dup 5) (match_dup 4)))]
2493 ""
2494 "
2495{
2496 operands[2] = gen_reg_rtx (DImode);
2497 operands[3] = gen_reg_rtx (DImode);
2498 operands[4] = gen_reg_rtx (DImode);
2499 operands[5] = gen_reg_rtx (DImode);
f2f90c63 2500 operands[6] = gen_reg_rtx (BImode);
c65ebc55
JW
2501}")
2502
2503(define_insn "*popcnt"
0551c32d
RH
2504 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2505 (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")] 8))]
c65ebc55
JW
2506 ""
2507 "popcnt %0 = %1"
2508 [(set_attr "type" "I")])
2509
655f2eb9
RH
2510(define_expand "divdi3"
2511 [(set (match_operand:DI 0 "register_operand" "")
2512 (div:DI (match_operand:DI 1 "general_operand" "")
2513 (match_operand:DI 2 "general_operand" "")))]
2514 "TARGET_INLINE_DIV"
2515 "
2516{
2517 rtx op1_tf, op2_tf, op0_tf;
2518
2519 op0_tf = gen_reg_rtx (TFmode);
2520
2521 if (CONSTANT_P (operands[1]))
2522 operands[1] = force_reg (DImode, operands[1]);
2523 op1_tf = gen_reg_rtx (TFmode);
2524 expand_float (op1_tf, operands[1], 0);
2525
2526 if (CONSTANT_P (operands[2]))
2527 operands[2] = force_reg (DImode, operands[2]);
2528 op2_tf = gen_reg_rtx (TFmode);
2529 expand_float (op2_tf, operands[2], 0);
2530
2531 if (TARGET_INLINE_DIV_LAT)
2532 emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
2533 else
2534 emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
2535
2536 emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
2537 DONE;
2538}")
2539
2540(define_expand "moddi3"
2541 [(set (match_operand:DI 0 "register_operand" "")
2542 (mod:SI (match_operand:DI 1 "general_operand" "")
2543 (match_operand:DI 2 "general_operand" "")))]
2544 "TARGET_INLINE_DIV"
2545 "
2546{
2547 rtx op2_neg, div;
2548
2549 div = gen_reg_rtx (DImode);
2550 emit_insn (gen_divdi3 (div, operands[1], operands[2]));
2551
2552 op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2553
2554 emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2555 DONE;
2556}")
2557
2558(define_expand "udivdi3"
2559 [(set (match_operand:DI 0 "register_operand" "")
2560 (udiv:DI (match_operand:DI 1 "general_operand" "")
2561 (match_operand:DI 2 "general_operand" "")))]
2562 "TARGET_INLINE_DIV"
2563 "
2564{
2565 rtx op1_tf, op2_tf, op0_tf;
2566
2567 op0_tf = gen_reg_rtx (TFmode);
2568
2569 if (CONSTANT_P (operands[1]))
2570 operands[1] = force_reg (DImode, operands[1]);
2571 op1_tf = gen_reg_rtx (TFmode);
2572 expand_float (op1_tf, operands[1], 1);
2573
2574 if (CONSTANT_P (operands[2]))
2575 operands[2] = force_reg (DImode, operands[2]);
2576 op2_tf = gen_reg_rtx (TFmode);
2577 expand_float (op2_tf, operands[2], 1);
2578
2579 if (TARGET_INLINE_DIV_LAT)
2580 emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
2581 else
2582 emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
2583
2584 emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
2585 DONE;
2586}")
2587
2588(define_expand "umoddi3"
2589 [(set (match_operand:DI 0 "register_operand" "")
2590 (umod:DI (match_operand:DI 1 "general_operand" "")
2591 (match_operand:DI 2 "general_operand" "")))]
2592 "TARGET_INLINE_DIV"
2593 "
2594{
2595 rtx op2_neg, div;
2596
2597 div = gen_reg_rtx (DImode);
2598 emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2599
2600 op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2601
2602 emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2603 DONE;
2604}")
2605
2606(define_insn_and_split "divdi3_internal_lat"
2607 [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2608 (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2609 (match_operand:TF 2 "fr_register_operand" "f"))))
2610 (clobber (match_scratch:TF 3 "=&f"))
2611 (clobber (match_scratch:TF 4 "=&f"))
2612 (clobber (match_scratch:TF 5 "=&f"))
f2f90c63 2613 (clobber (match_scratch:BI 6 "=c"))]
655f2eb9
RH
2614 "TARGET_INLINE_DIV_LAT"
2615 "#"
2616 "&& reload_completed"
2617 [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
f2f90c63 2618 (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
655f2eb9
RH
2619 (use (const_int 1))])
2620 (cond_exec (ne (match_dup 6) (const_int 0))
2621 (parallel [(set (match_dup 3)
2622 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2623 (match_dup 7)))
2624 (use (const_int 1))]))
2625 (cond_exec (ne (match_dup 6) (const_int 0))
2626 (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
2627 (use (const_int 1))]))
2628 (cond_exec (ne (match_dup 6) (const_int 0))
2629 (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
2630 (use (const_int 1))]))
2631 (cond_exec (ne (match_dup 6) (const_int 0))
2632 (parallel [(set (match_dup 4)
2633 (plus:TF (mult:TF (match_dup 3) (match_dup 4))
2634 (match_dup 4)))
2635 (use (const_int 1))]))
2636 (cond_exec (ne (match_dup 6) (const_int 0))
2637 (parallel [(set (match_dup 0)
2638 (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2639 (match_dup 0)))
2640 (use (const_int 1))]))
2641 (cond_exec (ne (match_dup 6) (const_int 0))
2642 (parallel [(set (match_dup 3)
2643 (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2644 (match_dup 4)))
2645 (use (const_int 1))]))
2646 (cond_exec (ne (match_dup 6) (const_int 0))
2647 (parallel [(set (match_dup 0)
2648 (plus:TF (mult:TF (match_dup 5) (match_dup 0))
2649 (match_dup 0)))
2650 (use (const_int 1))]))
2651 (cond_exec (ne (match_dup 6) (const_int 0))
2652 (parallel [(set (match_dup 4)
2653 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
2654 (match_dup 1)))
2655 (use (const_int 1))]))
2656 (cond_exec (ne (match_dup 6) (const_int 0))
2657 (parallel [(set (match_dup 0)
2658 (plus:TF (mult:TF (match_dup 4) (match_dup 0))
2659 (match_dup 3)))
2660 (use (const_int 1))]))
2661 ]
2662 "operands[7] = CONST1_RTX (TFmode);"
2663 [(set_attr "predicable" "no")])
2664
2665(define_insn_and_split "divdi3_internal_thr"
2666 [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2667 (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2668 (match_operand:TF 2 "fr_register_operand" "f"))))
2669 (clobber (match_scratch:TF 3 "=&f"))
2670 (clobber (match_scratch:TF 4 "=f"))
f2f90c63 2671 (clobber (match_scratch:BI 5 "=c"))]
655f2eb9
RH
2672 "TARGET_INLINE_DIV_THR"
2673 "#"
2674 "&& reload_completed"
2675 [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
f2f90c63 2676 (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
655f2eb9
RH
2677 (use (const_int 1))])
2678 (cond_exec (ne (match_dup 5) (const_int 0))
2679 (parallel [(set (match_dup 3)
2680 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2681 (match_dup 6)))
2682 (use (const_int 1))]))
2683 (cond_exec (ne (match_dup 5) (const_int 0))
2684 (parallel [(set (match_dup 0)
2685 (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2686 (match_dup 0)))
2687 (use (const_int 1))]))
2688 (cond_exec (ne (match_dup 5) (const_int 0))
2689 (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
2690 (use (const_int 1))]))
2691 (cond_exec (ne (match_dup 5) (const_int 0))
2692 (parallel [(set (match_dup 0)
2693 (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2694 (match_dup 0)))
2695 (use (const_int 1))]))
2696 (cond_exec (ne (match_dup 5) (const_int 0))
2697 (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1)))
2698 (use (const_int 1))]))
2699 (cond_exec (ne (match_dup 5) (const_int 0))
2700 (parallel [(set (match_dup 4)
2701 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
2702 (match_dup 1)))
2703 (use (const_int 1))]))
2704 (cond_exec (ne (match_dup 5) (const_int 0))
2705 (parallel [(set (match_dup 0)
2706 (plus:TF (mult:TF (match_dup 4) (match_dup 0))
2707 (match_dup 3)))
2708 (use (const_int 1))]))
2709 ]
2710 "operands[6] = CONST1_RTX (TFmode);"
2711 [(set_attr "predicable" "no")])
c65ebc55
JW
2712\f
2713;; ::::::::::::::::::::
2714;; ::
2715;; :: 32 bit floating point arithmetic
2716;; ::
2717;; ::::::::::::::::::::
2718
2719(define_insn "addsf3"
0551c32d
RH
2720 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2721 (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
2722 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
2723 ""
2724 "fadd.s %0 = %1, %F2%B0"
2725 [(set_attr "type" "F")])
2726
2727(define_insn "subsf3"
0551c32d
RH
2728 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2729 (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2730 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
2731 ""
2732 "fsub.s %0 = %F1, %F2%B0"
2733 [(set_attr "type" "F")])
2734
2735(define_insn "mulsf3"
0551c32d
RH
2736 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2737 (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
2738 (match_operand:SF 2 "fr_register_operand" "f")))]
c65ebc55
JW
2739 ""
2740 "fmpy.s %0 = %1, %2%B0"
2741 [(set_attr "type" "F")])
2742
2743(define_insn "abssf2"
0551c32d
RH
2744 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2745 (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
2746 ""
2747 "fabs %0 = %1%B0"
2748 [(set_attr "type" "F")])
2749
2750(define_insn "negsf2"
0551c32d
RH
2751 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2752 (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
2753 ""
2754 "fneg %0 = %1%B0"
2755 [(set_attr "type" "F")])
2756
2757(define_insn "*nabssf2"
0551c32d
RH
2758 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2759 (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
c65ebc55
JW
2760 ""
2761 "fnegabs %0 = %1%B0"
2762 [(set_attr "type" "F")])
2763
2764(define_insn "minsf3"
0551c32d
RH
2765 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2766 (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
2767 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
2768 ""
2769 "fmin %0 = %1, %F2%B0"
2770 [(set_attr "type" "F")])
2771
2772(define_insn "maxsf3"
0551c32d
RH
2773 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2774 (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
2775 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
2776 ""
2777 "fmax %0 = %1, %F2%B0"
2778 [(set_attr "type" "F")])
2779
655f2eb9 2780(define_insn "*maddsf4"
0551c32d
RH
2781 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2782 (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2783 (match_operand:SF 2 "fr_register_operand" "f"))
2784 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
2785 ""
2786 "fma.s %0 = %1, %2, %F3%B0"
2787 [(set_attr "type" "F")])
2788
655f2eb9 2789(define_insn "*msubsf4"
0551c32d
RH
2790 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2791 (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2792 (match_operand:SF 2 "fr_register_operand" "f"))
2793 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
2794 ""
2795 "fms.s %0 = %1, %2, %F3%B0"
2796 [(set_attr "type" "F")])
2797
2798(define_insn "*nmulsf3"
0551c32d
RH
2799 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2800 (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2801 (match_operand:SF 2 "fr_register_operand" "f"))))]
c65ebc55
JW
2802 ""
2803 "fnmpy.s %0 = %1, %2%B0"
2804 [(set_attr "type" "F")])
2805
2806;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2807
655f2eb9 2808(define_insn "*nmaddsf4"
0551c32d 2809 [(set (match_operand:SF 0 "fr_register_operand" "=f")
26102535
RH
2810 (plus:SF (neg:SF (mult:SF
2811 (match_operand:SF 1 "fr_register_operand" "f")
2812 (match_operand:SF 2 "fr_register_operand" "f")))
0551c32d 2813 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
2814 ""
2815 "fnma.s %0 = %1, %2, %F3%B0"
2816 [(set_attr "type" "F")])
2817
26102535
RH
2818(define_expand "divsf3"
2819 [(set (match_operand:SF 0 "fr_register_operand" "")
2820 (div:SF (match_operand:SF 1 "fr_register_operand" "")
2821 (match_operand:SF 2 "fr_register_operand" "")))]
2822 "TARGET_INLINE_DIV"
2823 "
2824{
2825 rtx insn;
2826 if (TARGET_INLINE_DIV_LAT)
2827 insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
2828 else
2829 insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
2830 emit_insn (insn);
2831 DONE;
2832}")
2833
2834(define_insn_and_split "divsf3_internal_lat"
2835 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2836 (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2837 (match_operand:SF 2 "fr_register_operand" "f")))
2838 (clobber (match_scratch:TF 3 "=&f"))
2839 (clobber (match_scratch:TF 4 "=f"))
f2f90c63 2840 (clobber (match_scratch:BI 5 "=c"))]
26102535
RH
2841 "TARGET_INLINE_DIV_LAT"
2842 "#"
2843 "&& reload_completed"
2844 [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
f2f90c63 2845 (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 5))
26102535
RH
2846 (use (const_int 1))])
2847 (cond_exec (ne (match_dup 5) (const_int 0))
2848 (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6)))
2849 (use (const_int 1))]))
2850 (cond_exec (ne (match_dup 5) (const_int 0))
2851 (parallel [(set (match_dup 4)
2852 (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
2853 (match_dup 10)))
2854 (use (const_int 1))]))
2855 (cond_exec (ne (match_dup 5) (const_int 0))
2856 (parallel [(set (match_dup 3)
2857 (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2858 (match_dup 3)))
2859 (use (const_int 1))]))
2860 (cond_exec (ne (match_dup 5) (const_int 0))
2861 (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
2862 (use (const_int 1))]))
2863 (cond_exec (ne (match_dup 5) (const_int 0))
2864 (parallel [(set (match_dup 3)
2865 (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2866 (match_dup 3)))
2867 (use (const_int 1))]))
2868 (cond_exec (ne (match_dup 5) (const_int 0))
2869 (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
2870 (use (const_int 1))]))
2871 (cond_exec (ne (match_dup 5) (const_int 0))
2872 (parallel [(set (match_dup 9)
2873 (float_truncate:DF
2874 (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2875 (match_dup 3))))
2876 (use (const_int 1))]))
2877 (cond_exec (ne (match_dup 5) (const_int 0))
2878 (set (match_dup 0)
2879 (float_truncate:SF (match_dup 6))))
2880 ]
2881 "operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
2882 operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
2883 operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
2884 operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
2885 operands[10] = CONST1_RTX (TFmode);"
2886 [(set_attr "predicable" "no")])
2887
2888(define_insn_and_split "divsf3_internal_thr"
2889 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2890 (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2891 (match_operand:SF 2 "fr_register_operand" "f")))
2892 (clobber (match_scratch:TF 3 "=&f"))
2893 (clobber (match_scratch:TF 4 "=f"))
f2f90c63 2894 (clobber (match_scratch:BI 5 "=c"))]
26102535
RH
2895 "TARGET_INLINE_DIV_THR"
2896 "#"
2897 "&& reload_completed"
2898 [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
f2f90c63 2899 (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 5))
26102535
RH
2900 (use (const_int 1))])
2901 (cond_exec (ne (match_dup 5) (const_int 0))
2902 (parallel [(set (match_dup 3)
2903 (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
2904 (match_dup 10)))
2905 (use (const_int 1))]))
2906 (cond_exec (ne (match_dup 5) (const_int 0))
2907 (parallel [(set (match_dup 3)
2908 (plus:TF (mult:TF (match_dup 3) (match_dup 3))
2909 (match_dup 3)))
2910 (use (const_int 1))]))
2911 (cond_exec (ne (match_dup 5) (const_int 0))
2912 (parallel [(set (match_dup 6)
2913 (plus:TF (mult:TF (match_dup 3) (match_dup 6))
2914 (match_dup 6)))
2915 (use (const_int 1))]))
2916 (cond_exec (ne (match_dup 5) (const_int 0))
2917 (parallel [(set (match_dup 9)
2918 (float_truncate:SF
2919 (mult:TF (match_dup 7) (match_dup 6))))
2920 (use (const_int 1))]))
2921 (cond_exec (ne (match_dup 5) (const_int 0))
2922 (parallel [(set (match_dup 4)
2923 (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 3)))
2924 (match_dup 7)))
2925 (use (const_int 1))]))
2926 (cond_exec (ne (match_dup 5) (const_int 0))
2927 (set (match_dup 0)
2928 (float_truncate:SF
2929 (plus:TF (mult:TF (match_dup 4) (match_dup 6))
2930 (match_dup 3)))))
2931 ]
2932 "operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
2933 operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
2934 operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
2935 operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
2936 operands[10] = CONST1_RTX (TFmode);"
2937 [(set_attr "predicable" "no")])
c65ebc55
JW
2938\f
2939;; ::::::::::::::::::::
2940;; ::
2941;; :: 64 bit floating point arithmetic
2942;; ::
2943;; ::::::::::::::::::::
2944
2945(define_insn "adddf3"
0551c32d
RH
2946 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2947 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2948 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
2949 ""
2950 "fadd.d %0 = %1, %F2%B0"
2951 [(set_attr "type" "F")])
2952
26102535
RH
2953(define_insn "*adddf3_trunc"
2954 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2955 (float_truncate:SF
2956 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2957 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2958 ""
2959 "fadd.s %0 = %1, %F2%B0"
2960 [(set_attr "type" "F")])
2961
c65ebc55 2962(define_insn "subdf3"
0551c32d
RH
2963 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2964 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2965 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
2966 ""
2967 "fsub.d %0 = %F1, %F2%B0"
2968 [(set_attr "type" "F")])
2969
26102535
RH
2970(define_insn "*subdf3_trunc"
2971 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2972 (float_truncate:SF
2973 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2974 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2975 ""
2976 "fsub.s %0 = %F1, %F2%B0"
2977 [(set_attr "type" "F")])
2978
c65ebc55 2979(define_insn "muldf3"
0551c32d
RH
2980 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2981 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2982 (match_operand:DF 2 "fr_register_operand" "f")))]
c65ebc55
JW
2983 ""
2984 "fmpy.d %0 = %1, %2%B0"
2985 [(set_attr "type" "F")])
2986
26102535
RH
2987(define_insn "*muldf3_trunc"
2988 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2989 (float_truncate:SF
2990 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2991 (match_operand:DF 2 "fr_register_operand" "f"))))]
2992 ""
2993 "fmpy.s %0 = %1, %2%B0"
2994 [(set_attr "type" "F")])
2995
c65ebc55 2996(define_insn "absdf2"
0551c32d
RH
2997 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2998 (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
2999 ""
3000 "fabs %0 = %1%B0"
3001 [(set_attr "type" "F")])
3002
3003(define_insn "negdf2"
0551c32d
RH
3004 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3005 (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
3006 ""
3007 "fneg %0 = %1%B0"
3008 [(set_attr "type" "F")])
3009
3010(define_insn "*nabsdf2"
0551c32d
RH
3011 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3012 (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
c65ebc55
JW
3013 ""
3014 "fnegabs %0 = %1%B0"
3015 [(set_attr "type" "F")])
3016
3017(define_insn "mindf3"
0551c32d
RH
3018 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3019 (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
3020 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
3021 ""
3022 "fmin %0 = %1, %F2%B0"
3023 [(set_attr "type" "F")])
3024
3025(define_insn "maxdf3"
0551c32d
RH
3026 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3027 (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
3028 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
3029 ""
3030 "fmax %0 = %1, %F2%B0"
3031 [(set_attr "type" "F")])
3032
655f2eb9 3033(define_insn "*madddf4"
0551c32d
RH
3034 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3035 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3036 (match_operand:DF 2 "fr_register_operand" "f"))
3037 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
3038 ""
3039 "fma.d %0 = %1, %2, %F3%B0"
3040 [(set_attr "type" "F")])
3041
26102535
RH
3042(define_insn "*madddf4_trunc"
3043 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3044 (float_truncate:SF
3045 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3046 (match_operand:DF 2 "fr_register_operand" "f"))
3047 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3048 ""
3049 "fma.s %0 = %1, %2, %F3%B0"
3050 [(set_attr "type" "F")])
3051
655f2eb9 3052(define_insn "*msubdf4"
0551c32d
RH
3053 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3054 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3055 (match_operand:DF 2 "fr_register_operand" "f"))
3056 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
3057 ""
3058 "fms.d %0 = %1, %2, %F3%B0"
3059 [(set_attr "type" "F")])
3060
26102535
RH
3061(define_insn "*msubdf4_trunc"
3062 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3063 (float_truncate:SF
3064 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3065 (match_operand:DF 2 "fr_register_operand" "f"))
3066 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3067 ""
3068 "fms.s %0 = %1, %2, %F3%B0"
3069 [(set_attr "type" "F")])
3070
c65ebc55 3071(define_insn "*nmuldf3"
0551c32d
RH
3072 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3073 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3074 (match_operand:DF 2 "fr_register_operand" "f"))))]
c65ebc55
JW
3075 ""
3076 "fnmpy.d %0 = %1, %2%B0"
3077 [(set_attr "type" "F")])
3078
26102535
RH
3079(define_insn "*nmuldf3_trunc"
3080 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3081 (float_truncate:SF
3082 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3083 (match_operand:DF 2 "fr_register_operand" "f")))))]
3084 ""
3085 "fnmpy.s %0 = %1, %2%B0"
3086 [(set_attr "type" "F")])
3087
c65ebc55
JW
3088;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3089
655f2eb9 3090(define_insn "*nmadddf4"
0551c32d 3091 [(set (match_operand:DF 0 "fr_register_operand" "=f")
26102535
RH
3092 (plus:DF (neg:DF (mult:DF
3093 (match_operand:DF 1 "fr_register_operand" "f")
3094 (match_operand:DF 2 "fr_register_operand" "f")))
0551c32d 3095 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
3096 ""
3097 "fnma.d %0 = %1, %2, %F3%B0"
3098 [(set_attr "type" "F")])
26102535
RH
3099
3100(define_insn "*nmadddf4_alts"
3101 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3102 (plus:DF (neg:DF (mult:DF
3103 (match_operand:DF 1 "fr_register_operand" "f")
3104 (match_operand:DF 2 "fr_register_operand" "f")))
3105 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))
3106 (use (match_operand:SI 4 "const_int_operand" ""))]
3107 ""
3108 "fnma.d.s%4 %0 = %1, %2, %F3%B0"
3109 [(set_attr "type" "F")])
3110
3111(define_insn "*nmadddf4_trunc"
3112 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3113 (float_truncate:SF
3114 (plus:DF (neg:DF (mult:DF
3115 (match_operand:DF 1 "fr_register_operand" "f")
3116 (match_operand:DF 2 "fr_register_operand" "f")))
3117 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3118 ""
3119 "fnma.s %0 = %1, %2, %F3%B0"
3120 [(set_attr "type" "F")])
3121
3122(define_expand "divdf3"
3123 [(set (match_operand:DF 0 "fr_register_operand" "")
3124 (div:DF (match_operand:DF 1 "fr_register_operand" "")
3125 (match_operand:DF 2 "fr_register_operand" "")))]
3126 "TARGET_INLINE_DIV"
3127 "
3128{
3129 rtx insn;
3130 if (TARGET_INLINE_DIV_LAT)
3131 insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
3132 else
3133 insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
3134 emit_insn (insn);
3135 DONE;
3136}")
3137
3138(define_insn_and_split "divdf3_internal_lat"
3139 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3140 (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3141 (match_operand:DF 2 "fr_register_operand" "f")))
3142 (clobber (match_scratch:TF 3 "=&f"))
3143 (clobber (match_scratch:TF 4 "=&f"))
3144 (clobber (match_scratch:TF 5 "=&f"))
f2f90c63 3145 (clobber (match_scratch:BI 6 "=c"))]
26102535
RH
3146 "TARGET_INLINE_DIV_LAT"
3147 "#"
3148 "&& reload_completed"
3149 [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9)))
f2f90c63 3150 (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)] 5))
26102535
RH
3151 (use (const_int 1))])
3152 (cond_exec (ne (match_dup 6) (const_int 0))
3153 (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7)))
3154 (use (const_int 1))]))
3155 (cond_exec (ne (match_dup 6) (const_int 0))
3156 (parallel [(set (match_dup 4)
3157 (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 7)))
3158 (match_dup 12)))
3159 (use (const_int 1))]))
3160 (cond_exec (ne (match_dup 6) (const_int 0))
3161 (parallel [(set (match_dup 3)
3162 (plus:TF (mult:TF (match_dup 4) (match_dup 3))
3163 (match_dup 3)))
3164 (use (const_int 1))]))
3165 (cond_exec (ne (match_dup 6) (const_int 0))
3166 (parallel [(set (match_dup 5) (mult:TF (match_dup 4) (match_dup 4)))
3167 (use (const_int 1))]))
3168 (cond_exec (ne (match_dup 6) (const_int 0))
3169 (parallel [(set (match_dup 7)
3170 (plus:TF (mult:TF (match_dup 4) (match_dup 7))
3171 (match_dup 7)))
3172 (use (const_int 1))]))
3173 (cond_exec (ne (match_dup 6) (const_int 0))
3174 (parallel [(set (match_dup 3)
3175 (plus:TF (mult:TF (match_dup 5) (match_dup 3))
3176 (match_dup 3)))
3177 (use (const_int 1))]))
3178 (cond_exec (ne (match_dup 6) (const_int 0))
3179 (parallel [(set (match_dup 4) (mult:TF (match_dup 5) (match_dup 5)))
3180 (use (const_int 1))]))
3181 (cond_exec (ne (match_dup 6) (const_int 0))
3182 (parallel [(set (match_dup 7)
3183 (plus:TF (mult:TF (match_dup 5) (match_dup 7))
3184 (match_dup 7)))
3185 (use (const_int 1))]))
3186 (cond_exec (ne (match_dup 6) (const_int 0))
3187 (parallel [(set (match_dup 10)
3188 (float_truncate:DF
3189 (plus:TF (mult:TF (match_dup 4) (match_dup 3))
3190 (match_dup 3))))
3191 (use (const_int 1))]))
3192 (cond_exec (ne (match_dup 6) (const_int 0))
3193 (parallel [(set (match_dup 7)
3194 (plus:TF (mult:TF (match_dup 4) (match_dup 7))
3195 (match_dup 7)))
3196 (use (const_int 1))]))
3197 (cond_exec (ne (match_dup 6) (const_int 0))
3198 (parallel [(set (match_dup 11)
3199 (float_truncate:DF
3200 (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 3)))
3201 (match_dup 8))))
3202 (use (const_int 1))]))
3203 (cond_exec (ne (match_dup 6) (const_int 0))
3204 (set (match_dup 0)
3205 (float_truncate:DF (plus:TF (mult:TF (match_dup 5) (match_dup 7))
3206 (match_dup 3)))))
3207 ]
3208 "operands[7] = gen_rtx_REG (TFmode, REGNO (operands[0]));
3209 operands[8] = gen_rtx_REG (TFmode, REGNO (operands[1]));
3210 operands[9] = gen_rtx_REG (TFmode, REGNO (operands[2]));
3211 operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3212 operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3213 operands[12] = CONST1_RTX (TFmode);"
3214 [(set_attr "predicable" "no")])
3215
3216(define_insn_and_split "divdf3_internal_thr"
3217 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3218 (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3219 (match_operand:DF 2 "fr_register_operand" "f")))
3220 (clobber (match_scratch:TF 3 "=&f"))
3221 (clobber (match_scratch:DF 4 "=f"))
f2f90c63 3222 (clobber (match_scratch:BI 5 "=c"))]
26102535
RH
3223 "TARGET_INLINE_DIV_THR"
3224 "#"
3225 "&& reload_completed"
3226 [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
f2f90c63 3227 (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 5))
26102535
RH
3228 (use (const_int 1))])
3229 (cond_exec (ne (match_dup 5) (const_int 0))
3230 (parallel [(set (match_dup 3)
3231 (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
3232 (match_dup 10)))
3233 (use (const_int 1))]))
3234 (cond_exec (ne (match_dup 5) (const_int 0))
3235 (parallel [(set (match_dup 6)
3236 (plus:TF (mult:TF (match_dup 3) (match_dup 6))
3237 (match_dup 6)))
3238 (use (const_int 1))]))
3239 (cond_exec (ne (match_dup 5) (const_int 0))
3240 (parallel [(set (match_dup 3)
3241 (mult:TF (match_dup 3) (match_dup 3)))
3242 (use (const_int 1))]))
3243 (cond_exec (ne (match_dup 5) (const_int 0))
3244 (parallel [(set (match_dup 6)
3245 (plus:TF (mult:TF (match_dup 3) (match_dup 6))
3246 (match_dup 6)))
3247 (use (const_int 1))]))
3248 (cond_exec (ne (match_dup 5) (const_int 0))
3249 (parallel [(set (match_dup 3)
3250 (mult:TF (match_dup 3) (match_dup 3)))
3251 (use (const_int 1))]))
3252 (cond_exec (ne (match_dup 5) (const_int 0))
3253 (parallel [(set (match_dup 6)
3254 (plus:TF (mult:TF (match_dup 3) (match_dup 6))
3255 (match_dup 6)))
3256 (use (const_int 1))]))
3257 (cond_exec (ne (match_dup 5) (const_int 0))
3258 (parallel [(set (match_dup 9)
3259 (float_truncate:DF
3260 (mult:TF (match_dup 7) (match_dup 3))))
3261 (use (const_int 1))]))
3262 (cond_exec (ne (match_dup 5) (const_int 0))
3263 (parallel [(set (match_dup 4)
3264 (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9)))
3265 (match_dup 1)))
3266 (use (const_int 1))]))
3267 (cond_exec (ne (match_dup 5) (const_int 0))
3268 (set (match_dup 0)
3269 (plus:DF (mult:DF (match_dup 4) (match_dup 0))
3270 (match_dup 9))))
3271 ]
3272 "operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
3273 operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
3274 operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
3275 operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3276 operands[10] = CONST1_RTX (TFmode);"
3277 [(set_attr "predicable" "no")])
3f622353
RH
3278\f
3279;; ::::::::::::::::::::
3280;; ::
3281;; :: 80 bit floating point arithmetic
3282;; ::
3283;; ::::::::::::::::::::
3284
3285(define_insn "addtf3"
0551c32d 3286 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3287 (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3288 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3289 ""
3290 "fadd %0 = %F1, %F2%B0"
3291 [(set_attr "type" "F")])
3292
26102535
RH
3293(define_insn "*addtf3_truncsf"
3294 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3295 (float_truncate:SF
3296 (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3297 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3298 ""
3299 "fadd.s %0 = %F1, %F2%B0"
3300 [(set_attr "type" "F")])
3301
3302(define_insn "*addtf3_truncdf"
3303 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3304 (float_truncate:DF
3305 (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3306 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3307 ""
3308 "fadd.d %0 = %F1, %F2%B0"
3309 [(set_attr "type" "F")])
3310
3f622353 3311(define_insn "subtf3"
0551c32d 3312 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3313 (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3314 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3315 ""
3316 "fsub %0 = %F1, %F2%B0"
3317 [(set_attr "type" "F")])
3318
26102535
RH
3319(define_insn "*subtf3_truncsf"
3320 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3321 (float_truncate:SF
3322 (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3323 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3324 ""
3325 "fsub.s %0 = %F1, %F2%B0"
3326 [(set_attr "type" "F")])
3327
3328(define_insn "*subtf3_truncdf"
3329 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3330 (float_truncate:DF
3331 (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3332 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3333 ""
3334 "fsub.d %0 = %F1, %F2%B0"
3335 [(set_attr "type" "F")])
3336
3f622353 3337(define_insn "multf3"
0551c32d 3338 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3339 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3340 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3341 ""
3342 "fmpy %0 = %F1, %F2%B0"
3343 [(set_attr "type" "F")])
3344
26102535
RH
3345(define_insn "*multf3_truncsf"
3346 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3347 (float_truncate:SF
3348 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3349 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3350 ""
3351 "fmpy.s %0 = %F1, %F2%B0"
3352 [(set_attr "type" "F")])
3353
3354(define_insn "*multf3_truncdf"
3355 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3356 (float_truncate:DF
3357 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3358 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3359 ""
3360 "fmpy.d %0 = %F1, %F2%B0"
3361 [(set_attr "type" "F")])
3362
655f2eb9
RH
3363(define_insn "*multf3_alts"
3364 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3365 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3366 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3367 (use (match_operand:SI 3 "const_int_operand" ""))]
3368 ""
3369 "fmpy.s%3 %0 = %F1, %F2%B0"
3370 [(set_attr "type" "F")])
3371
26102535
RH
3372(define_insn "*multf3_truncsf_alts"
3373 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3374 (float_truncate:SF
3375 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3376 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
3377 (use (match_operand:SI 3 "const_int_operand" ""))]
3378 ""
3379 "fmpy.s.s%3 %0 = %F1, %F2%B0"
3380 [(set_attr "type" "F")])
3381
3382(define_insn "*multf3_truncdf_alts"
3383 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3384 (float_truncate:DF
3385 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3386 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
3387 (use (match_operand:SI 3 "const_int_operand" ""))]
3388 ""
3389 "fmpy.d.s%3 %0 = %F1, %F2%B0"
3390 [(set_attr "type" "F")])
3391
3f622353 3392(define_insn "abstf2"
0551c32d 3393 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3394 (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
3395 ""
3396 "fabs %0 = %F1%B0"
3397 [(set_attr "type" "F")])
3398
3399(define_insn "negtf2"
0551c32d 3400 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3401 (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
3402 ""
3403 "fneg %0 = %F1%B0"
3404 [(set_attr "type" "F")])
3405
3406(define_insn "*nabstf2"
0551c32d 3407 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3408 (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
3409 ""
3410 "fnegabs %0 = %F1%B0"
3411 [(set_attr "type" "F")])
3412
3413(define_insn "mintf3"
0551c32d 3414 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3415 (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3416 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3417 ""
3418 "fmin %0 = %F1, %F2%B0"
3419 [(set_attr "type" "F")])
3420
3421(define_insn "maxtf3"
0551c32d 3422 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3423 (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3424 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3425 ""
3426 "fmax %0 = %F1, %F2%B0"
3427 [(set_attr "type" "F")])
3428
655f2eb9 3429(define_insn "*maddtf4"
0551c32d 3430 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3431 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3432 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3433 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
3434 ""
3435 "fma %0 = %F1, %F2, %F3%B0"
3436 [(set_attr "type" "F")])
3437
26102535
RH
3438(define_insn "*maddtf4_truncsf"
3439 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3440 (float_truncate:SF
3441 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3442 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3443 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3444 ""
3445 "fma.s %0 = %F1, %F2, %F3%B0"
3446 [(set_attr "type" "F")])
3447
3448(define_insn "*maddtf4_truncdf"
3449 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3450 (float_truncate:DF
3451 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3452 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3453 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3454 ""
3455 "fma.d %0 = %F1, %F2, %F3%B0"
3456 [(set_attr "type" "F")])
3457
655f2eb9
RH
3458(define_insn "*maddtf4_alts"
3459 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3460 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3461 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3462 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
3463 (use (match_operand:SI 4 "const_int_operand" ""))]
3464 ""
3465 "fma.s%4 %0 = %F1, %F2, %F3%B0"
3466 [(set_attr "type" "F")])
3467
26102535
RH
3468(define_insn "*maddtf4_alts_truncdf"
3469 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3470 (float_truncate:DF
3471 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3472 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3473 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
3474 (use (match_operand:SI 4 "const_int_operand" ""))]
3475 ""
3476 "fma.d.s%4 %0 = %F1, %F2, %F3%B0"
3477 [(set_attr "type" "F")])
3478
655f2eb9 3479(define_insn "*msubtf4"
0551c32d 3480 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3481 (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3482 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3483 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
3484 ""
3485 "fms %0 = %F1, %F2, %F3%B0"
3486 [(set_attr "type" "F")])
3487
26102535
RH
3488(define_insn "*msubtf4_truncsf"
3489 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3490 (float_truncate:SF
3491 (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3492 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3493 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3494 ""
3495 "fms.s %0 = %F1, %F2, %F3%B0"
3496 [(set_attr "type" "F")])
3497
3498(define_insn "*msubtf4_truncdf"
3499 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3500 (float_truncate:DF
3501 (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3502 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3503 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3504 ""
3505 "fms.d %0 = %F1, %F2, %F3%B0"
3506 [(set_attr "type" "F")])
3507
3f622353 3508(define_insn "*nmultf3"
0551c32d 3509 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3510 (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3511 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3512 ""
3513 "fnmpy %0 = %F1, %F2%B0"
3514 [(set_attr "type" "F")])
c65ebc55 3515
26102535
RH
3516(define_insn "*nmultf3_truncsf"
3517 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3518 (float_truncate:SF
3519 (neg:TF (mult:TF
3520 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3521 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
3522 ""
3523 "fnmpy.s %0 = %F1, %F2%B0"
3524 [(set_attr "type" "F")])
3525
3526(define_insn "*nmultf3_truncdf"
3527 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3528 (float_truncate:DF
3529 (neg:TF (mult:TF
3530 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3531 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
3532 ""
3533 "fnmpy.d %0 = %F1, %F2%B0"
3534 [(set_attr "type" "F")])
3535
3f622353
RH
3536;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3537
655f2eb9 3538(define_insn "*nmaddtf4"
0551c32d 3539 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
3540 (plus:TF (neg:TF (mult:TF
3541 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3542 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3543 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
3544 ""
3545 "fnma %0 = %F1, %F2, %F3%B0"
3546 [(set_attr "type" "F")])
655f2eb9 3547
26102535
RH
3548(define_insn "*nmaddtf4_truncsf"
3549 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3550 (float_truncate:SF
3551 (plus:TF (neg:TF (mult:TF
3552 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3553 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3554 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3555 ""
3556 "fnma.s %0 = %F1, %F2, %F3%B0"
3557 [(set_attr "type" "F")])
3558
3559(define_insn "*nmaddtf4_truncdf"
3560 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3561 (float_truncate:DF
3562 (plus:TF (neg:TF (mult:TF
3563 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3564 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3565 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3566 ""
3567 "fnma.d %0 = %F1, %F2, %F3%B0"
3568 [(set_attr "type" "F")])
3569
655f2eb9
RH
3570(define_insn "*nmaddtf4_alts"
3571 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3572 (plus:TF (neg:TF (mult:TF
3573 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3574 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3575 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
3576 (use (match_operand:SI 4 "const_int_operand" ""))]
3577 ""
3578 "fnma.s%4 %0 = %F1, %F2, %F3%B0"
3579 [(set_attr "type" "F")])
3580
26102535
RH
3581(define_insn "*nmaddtf4_truncdf_alts"
3582 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3583 (float_truncate:DF
3584 (plus:TF (neg:TF
3585 (mult:TF
3586 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3587 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3588 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
3589 (use (match_operand:SI 4 "const_int_operand" ""))]
3590 ""
3591 "fnma.d.s%4 %0 = %F1, %F2, %F3%B0"
3592 [(set_attr "type" "F")])
3593
3594(define_expand "divtf3"
3595 [(set (match_operand:TF 0 "fr_register_operand" "")
3596 (div:TF (match_operand:TF 1 "fr_register_operand" "")
3597 (match_operand:TF 2 "fr_register_operand" "")))]
3598 "TARGET_INLINE_DIV"
3599 "
3600{
3601 rtx insn;
3602 if (TARGET_INLINE_DIV_LAT)
3603 insn = gen_divtf3_internal_lat (operands[0], operands[1], operands[2]);
3604 else
3605 insn = gen_divtf3_internal_thr (operands[0], operands[1], operands[2]);
3606 emit_insn (insn);
3607 DONE;
3608}")
3609
3610(define_insn_and_split "divtf3_internal_lat"
3611 [(set (match_operand:TF 0 "fr_register_operand" "=&f")
3612 (div:TF (match_operand:TF 1 "fr_register_operand" "f")
3613 (match_operand:TF 2 "fr_register_operand" "f")))
3614 (clobber (match_scratch:TF 3 "=&f"))
3615 (clobber (match_scratch:TF 4 "=&f"))
3616 (clobber (match_scratch:TF 5 "=&f"))
3617 (clobber (match_scratch:TF 6 "=&f"))
f2f90c63 3618 (clobber (match_scratch:BI 7 "=c"))]
26102535
RH
3619 "TARGET_INLINE_DIV_LAT"
3620 "#"
3621 "&& reload_completed"
3622 [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
f2f90c63 3623 (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
26102535
RH
3624 (use (const_int 1))])
3625 (cond_exec (ne (match_dup 7) (const_int 0))
3626 (parallel [(set (match_dup 3)
3627 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3628 (match_dup 8)))
3629 (use (const_int 1))]))
3630 (cond_exec (ne (match_dup 7) (const_int 0))
3631 (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
3632 (use (const_int 1))]))
3633 (cond_exec (ne (match_dup 7) (const_int 0))
3634 (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
3635 (use (const_int 1))]))
3636 (cond_exec (ne (match_dup 7) (const_int 0))
3637 (parallel [(set (match_dup 6)
3638 (plus:TF (mult:TF (match_dup 3) (match_dup 3))
3639 (match_dup 3)))
3640 (use (const_int 1))]))
3641 (cond_exec (ne (match_dup 7) (const_int 0))
3642 (parallel [(set (match_dup 3)
3643 (plus:TF (mult:TF (match_dup 5) (match_dup 5))
3644 (match_dup 3)))
3645 (use (const_int 1))]))
3646 (cond_exec (ne (match_dup 7) (const_int 0))
3647 (parallel [(set (match_dup 5)
3648 (plus:TF (mult:TF (match_dup 6) (match_dup 0))
3649 (match_dup 0)))
3650 (use (const_int 1))]))
3651 (cond_exec (ne (match_dup 7) (const_int 0))
3652 (parallel [(set (match_dup 0)
3653 (plus:TF (mult:TF (match_dup 5) (match_dup 3))
3654 (match_dup 0)))
3655 (use (const_int 1))]))
3656 (cond_exec (ne (match_dup 7) (const_int 0))
3657 (parallel [(set (match_dup 4)
3658 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
3659 (match_dup 1)))
3660 (use (const_int 1))]))
3661 (cond_exec (ne (match_dup 7) (const_int 0))
3662 (parallel [(set (match_dup 3)
3663 (plus:TF (mult:TF (match_dup 3) (match_dup 0))
3664 (match_dup 4)))
3665 (use (const_int 1))]))
3666 (cond_exec (ne (match_dup 7) (const_int 0))
3667 (parallel [(set (match_dup 5)
3668 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3669 (match_dup 8)))
3670 (use (const_int 1))]))
3671 (cond_exec (ne (match_dup 7) (const_int 0))
3672 (parallel [(set (match_dup 0)
3673 (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3674 (match_dup 0)))
3675 (use (const_int 1))]))
3676 (cond_exec (ne (match_dup 7) (const_int 0))
3677 (parallel [(set (match_dup 4)
3678 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
3679 (match_dup 1)))
3680 (use (const_int 1))]))
3681 (cond_exec (ne (match_dup 7) (const_int 0))
3682 (set (match_dup 0)
3683 (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3684 (match_dup 3))))
3685 ]
3686 "operands[8] = CONST1_RTX (TFmode);"
3687 [(set_attr "predicable" "no")])
3688
3689(define_insn_and_split "divtf3_internal_thr"
3690 [(set (match_operand:TF 0 "fr_register_operand" "=&f")
3691 (div:TF (match_operand:TF 1 "fr_register_operand" "f")
3692 (match_operand:TF 2 "fr_register_operand" "f")))
3693 (clobber (match_scratch:TF 3 "=&f"))
3694 (clobber (match_scratch:TF 4 "=&f"))
f2f90c63 3695 (clobber (match_scratch:BI 5 "=c"))]
26102535
RH
3696 "TARGET_INLINE_DIV_THR"
3697 "#"
3698 "&& reload_completed"
3699 [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
f2f90c63 3700 (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
26102535
RH
3701 (use (const_int 1))])
3702 (cond_exec (ne (match_dup 5) (const_int 0))
3703 (parallel [(set (match_dup 3)
3704 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3705 (match_dup 6)))
3706 (use (const_int 1))]))
3707 (cond_exec (ne (match_dup 5) (const_int 0))
3708 (parallel [(set (match_dup 4)
3709 (plus:TF (mult:TF (match_dup 3) (match_dup 0))
3710 (match_dup 0)))
3711 (use (const_int 1))]))
3712 (cond_exec (ne (match_dup 5) (const_int 0))
3713 (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
3714 (use (const_int 1))]))
3715 (cond_exec (ne (match_dup 5) (const_int 0))
3716 (parallel [(set (match_dup 3)
3717 (plus:TF (mult:TF (match_dup 3) (match_dup 4))
3718 (match_dup 4)))
3719 (use (const_int 1))]))
3720 (cond_exec (ne (match_dup 5) (const_int 0))
3721 (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
3722 (use (const_int 1))]))
3723 (cond_exec (ne (match_dup 5) (const_int 0))
3724 (parallel [(set (match_dup 0)
3725 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
3726 (match_dup 6)))
3727 (use (const_int 1))]))
3728 (cond_exec (ne (match_dup 5) (const_int 0))
3729 (parallel [(set (match_dup 0)
3730 (plus:TF (mult:TF (match_dup 0) (match_dup 3))
3731 (match_dup 3)))
3732 (use (const_int 1))]))
3733 (cond_exec (ne (match_dup 5) (const_int 0))
3734 (parallel [(set (match_dup 3)
3735 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
3736 (match_dup 1)))
3737 (use (const_int 1))]))
3738 (cond_exec (ne (match_dup 5) (const_int 0))
3739 (parallel [(set (match_dup 3)
3740 (plus:TF (mult:TF (match_dup 3) (match_dup 0))
3741 (match_dup 4)))
3742 (use (const_int 1))]))
3743 (cond_exec (ne (match_dup 5) (const_int 0))
3744 (parallel [(set (match_dup 4)
3745 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3746 (match_dup 6)))
3747 (use (const_int 1))]))
3748 (cond_exec (ne (match_dup 5) (const_int 0))
3749 (parallel [(set (match_dup 0)
3750 (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3751 (match_dup 0)))
3752 (use (const_int 1))]))
3753 (cond_exec (ne (match_dup 5) (const_int 0))
3754 (parallel [(set (match_dup 4)
3755 (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
3756 (match_dup 1)))
3757 (use (const_int 1))]))
3758 (cond_exec (ne (match_dup 5) (const_int 0))
3759 (set (match_dup 0)
3760 (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3761 (match_dup 3))))
3762 ]
3763 "operands[6] = CONST1_RTX (TFmode);"
3764 [(set_attr "predicable" "no")])
3765
3766;; ??? frcpa works like cmp.foo.unc.
3767
655f2eb9
RH
3768(define_insn "*recip_approx"
3769 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3770 (div:TF (const_int 1)
3771 (match_operand:TF 3 "fr_register_operand" "f")))
f2f90c63
RH
3772 (set (match_operand:BI 1 "register_operand" "=c")
3773 (unspec:BI [(match_operand:TF 2 "fr_register_operand" "f")
655f2eb9
RH
3774 (match_dup 3)] 5))
3775 (use (match_operand:SI 4 "const_int_operand" ""))]
3776 ""
3777 "frcpa.s%4 %0, %1 = %2, %3"
26102535
RH
3778 [(set_attr "type" "F")
3779 (set_attr "predicable" "no")])
c65ebc55
JW
3780\f
3781;; ::::::::::::::::::::
3782;; ::
3783;; :: 32 bit Integer Shifts and Rotates
3784;; ::
3785;; ::::::::::::::::::::
3786
9c668921 3787(define_expand "ashlsi3"
0551c32d
RH
3788 [(set (match_operand:SI 0 "gr_register_operand" "")
3789 (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
3790 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
9c668921
RH
3791 ""
3792 "
3793{
3794 if (GET_CODE (operands[2]) != CONST_INT)
3795 {
3796 /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now
3797 we've got to get rid of stray bits outside the SImode register. */
3798 rtx subshift = gen_reg_rtx (DImode);
3799 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3800 operands[2] = subshift;
3801 }
3802}")
3803
3804(define_insn "*ashlsi3_internal"
0551c32d
RH
3805 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
3806 (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
3807 (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
c65ebc55 3808 ""
041f25e6
RH
3809 "@
3810 shladd %0 = %1, %2, r0
3811 dep.z %0 = %1, %2, %E2
3812 shl %0 = %1, %2"
3813 [(set_attr "type" "A,I,I")])
c65ebc55
JW
3814
3815(define_expand "ashrsi3"
0551c32d
RH
3816 [(set (match_operand:SI 0 "gr_register_operand" "")
3817 (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
3818 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
c65ebc55
JW
3819 ""
3820 "
3821{
041f25e6
RH
3822 rtx subtarget = gen_reg_rtx (DImode);
3823 if (GET_CODE (operands[2]) == CONST_INT)
3824 emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
3825 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
3826 else
3827 {
9c668921 3828 rtx subshift = gen_reg_rtx (DImode);
041f25e6 3829 emit_insn (gen_extendsidi2 (subtarget, operands[1]));
9c668921
RH
3830 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3831 emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
041f25e6
RH
3832 }
3833 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
3834 DONE;
c65ebc55
JW
3835}")
3836
c65ebc55 3837(define_expand "lshrsi3"
0551c32d
RH
3838 [(set (match_operand:SI 0 "gr_register_operand" "")
3839 (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
3840 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
c65ebc55
JW
3841 ""
3842 "
3843{
041f25e6
RH
3844 rtx subtarget = gen_reg_rtx (DImode);
3845 if (GET_CODE (operands[2]) == CONST_INT)
3846 emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
3847 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
3848 else
3849 {
9c668921 3850 rtx subshift = gen_reg_rtx (DImode);
041f25e6 3851 emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
9c668921
RH
3852 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3853 emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
041f25e6
RH
3854 }
3855 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
3856 DONE;
c65ebc55
JW
3857}")
3858
c65ebc55
JW
3859;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
3860;; here, instead of 64 like the patterns above.
3861
3862(define_expand "rotrsi3"
3863 [(set (match_dup 3)
0551c32d 3864 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" ""))
c65ebc55
JW
3865 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
3866 (set (match_dup 3)
3867 (lshiftrt:DI (match_dup 3)
3868 (match_operand:DI 2 "nonmemory_operand" "")))
0551c32d 3869 (set (match_operand:SI 0 "gr_register_operand" "") (match_dup 4))]
c65ebc55
JW
3870 ""
3871 "
3872{
3873 if (! shift_32bit_count_operand (operands[2], SImode))
3874 FAIL;
c65ebc55
JW
3875 operands[3] = gen_reg_rtx (DImode);
3876 operands[4] = gen_lowpart (SImode, operands[3]);
3877}")
c65ebc55
JW
3878\f
3879;; ::::::::::::::::::::
3880;; ::
3881;; :: 64 bit Integer Shifts and Rotates
3882;; ::
3883;; ::::::::::::::::::::
3884
3885(define_insn "ashldi3"
0551c32d
RH
3886 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
3887 (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r")
3888 (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,rM")))]
c65ebc55 3889 ""
041f25e6
RH
3890 "@
3891 shladd %0 = %1, %2, r0
3892 shl %0 = %1, %2"
3893 [(set_attr "type" "A,I")])
c65ebc55
JW
3894
3895;; ??? Maybe combine this with the multiply and add instruction?
3896
3897(define_insn "*shladd"
0551c32d
RH
3898 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3899 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55 3900 (match_operand:DI 2 "shladd_operand" "n"))
0551c32d 3901 (match_operand:DI 3 "gr_register_operand" "r")))]
c65ebc55
JW
3902 ""
3903 "shladd %0 = %1, %S2, %3"
3904 [(set_attr "type" "A")])
3905
3906;; This can be created by register elimination if operand3 of shladd is an
3907;; eliminable register or has reg_equiv_constant set.
3908
3909;; We have to use nonmemory_operand for operand 4, to ensure that the
3910;; validate_changes call inside eliminate_regs will always succeed. If it
3911;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
3912;; incorrectly.
3913
5527bf14 3914(define_insn_and_split "*shladd_elim"
0551c32d
RH
3915 [(set (match_operand:DI 0 "gr_register_operand" "=&r")
3916 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55 3917 (match_operand:DI 2 "shladd_operand" "n"))
5527bf14 3918 (match_operand:DI 3 "nonmemory_operand" "r"))
c65ebc55
JW
3919 (match_operand:DI 4 "nonmemory_operand" "rI")))]
3920 "reload_in_progress"
5527bf14 3921 "* abort ();"
c65ebc55
JW
3922 "reload_completed"
3923 [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
3924 (match_dup 3)))
c65ebc55 3925 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
5527bf14
RH
3926 ""
3927 [(set_attr "type" "unknown")])
c65ebc55
JW
3928
3929(define_insn "ashrdi3"
0551c32d
RH
3930 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3931 (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
3932 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
c65ebc55
JW
3933 ""
3934 "shr %0 = %1, %2"
3935 [(set_attr "type" "I")])
3936
3937(define_insn "lshrdi3"
0551c32d
RH
3938 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3939 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
3940 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
c65ebc55
JW
3941 ""
3942 "shr.u %0 = %1, %2"
3943 [(set_attr "type" "I")])
3944
3945;; Using a predicate that accepts only constants doesn't work, because optabs
3946;; will load the operand into a register and call the pattern if the predicate
3947;; did not accept it on the first try. So we use nonmemory_operand and then
3948;; verify that we have an appropriate constant in the expander.
3949
3950(define_expand "rotrdi3"
0551c32d
RH
3951 [(set (match_operand:DI 0 "gr_register_operand" "")
3952 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
c65ebc55
JW
3953 (match_operand:DI 2 "nonmemory_operand" "")))]
3954 ""
3955 "
3956{
3957 if (! shift_count_operand (operands[2], DImode))
3958 FAIL;
3959}")
3960
3961(define_insn "*rotrdi3_internal"
0551c32d
RH
3962 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3963 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
3964 (match_operand:DI 2 "shift_count_operand" "M")))]
3965 ""
3966 "shrp %0 = %1, %1, %2"
3967 [(set_attr "type" "I")])
3968
3969\f
3970;; ::::::::::::::::::::
3971;; ::
058557c4 3972;; :: 32 bit Integer Logical operations
c65ebc55
JW
3973;; ::
3974;; ::::::::::::::::::::
3975
3976;; We don't seem to need any other 32-bit logical operations, because gcc
3977;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
3978;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
3979;; This doesn't work for unary logical operations, because we don't call
3980;; apply_distributive_law for them.
3981
3982;; ??? Likewise, this doesn't work for andnot, which isn't handled by
3983;; apply_distributive_law. We get inefficient code for
3984;; int sub4 (int i, int j) { return i & ~j; }
3985;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
3986;; (zero_extend (and (not A) B)) in combine.
3987;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
3988;; one_cmplsi2 pattern.
3989
058557c4 3990(define_insn "one_cmplsi2"
0551c32d
RH
3991 [(set (match_operand:SI 0 "gr_register_operand" "=r")
3992 (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
c65ebc55
JW
3993 ""
3994 "andcm %0 = -1, %1"
3995 [(set_attr "type" "A")])
c65ebc55
JW
3996\f
3997;; ::::::::::::::::::::
3998;; ::
058557c4 3999;; :: 64 bit Integer Logical operations
c65ebc55
JW
4000;; ::
4001;; ::::::::::::::::::::
4002
4003(define_insn "anddi3"
0551c32d
RH
4004 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4005 (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
4006 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
4007 ""
4008 "@
4009 and %0 = %2, %1
4010 fand %0 = %2, %1%B0"
4011 [(set_attr "type" "A,F")])
4012
4013(define_insn "*andnot"
0551c32d
RH
4014 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4015 (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
4016 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
4017 ""
4018 "@
4019 andcm %0 = %2, %1
4020 fandcm %0 = %2, %1%B0"
4021 [(set_attr "type" "A,F")])
4022
4023(define_insn "iordi3"
0551c32d
RH
4024 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4025 (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
4026 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
4027 ""
4028 "@
4029 or %0 = %2, %1
4030 for %0 = %2, %1%B0"
4031 [(set_attr "type" "A,F")])
4032
4033(define_insn "xordi3"
0551c32d
RH
4034 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4035 (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
4036 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
4037 ""
4038 "@
4039 xor %0 = %2, %1
4040 fxor %0 = %2, %1%B0"
4041 [(set_attr "type" "A,F")])
4042
4043(define_insn "one_cmpldi2"
0551c32d
RH
4044 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4045 (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
c65ebc55
JW
4046 ""
4047 "andcm %0 = -1, %1"
4048 [(set_attr "type" "A")])
4049\f
4050;; ::::::::::::::::::::
4051;; ::
4052;; :: Comparisons
4053;; ::
4054;; ::::::::::::::::::::
4055
f2f90c63
RH
4056(define_expand "cmpbi"
4057 [(set (cc0)
4058 (compare (match_operand:BI 0 "register_operand" "")
4059 (match_operand:BI 1 "const_int_operand" "")))]
4060 ""
4061 "
4062{
4063 ia64_compare_op0 = operands[0];
4064 ia64_compare_op1 = operands[1];
4065 DONE;
4066}")
4067
c65ebc55
JW
4068(define_expand "cmpsi"
4069 [(set (cc0)
0551c32d
RH
4070 (compare (match_operand:SI 0 "gr_register_operand" "")
4071 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
c65ebc55
JW
4072 ""
4073 "
4074{
4075 ia64_compare_op0 = operands[0];
4076 ia64_compare_op1 = operands[1];
4077 DONE;
4078}")
4079
4080(define_expand "cmpdi"
4081 [(set (cc0)
0551c32d
RH
4082 (compare (match_operand:DI 0 "gr_register_operand" "")
4083 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
c65ebc55
JW
4084 ""
4085 "
4086{
4087 ia64_compare_op0 = operands[0];
4088 ia64_compare_op1 = operands[1];
4089 DONE;
4090}")
4091
4092(define_expand "cmpsf"
4093 [(set (cc0)
0551c32d
RH
4094 (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
4095 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
c65ebc55
JW
4096 ""
4097 "
4098{
4099 ia64_compare_op0 = operands[0];
4100 ia64_compare_op1 = operands[1];
4101 DONE;
4102}")
4103
4104(define_expand "cmpdf"
4105 [(set (cc0)
0551c32d
RH
4106 (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
4107 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
c65ebc55
JW
4108 ""
4109 "
4110{
4111 ia64_compare_op0 = operands[0];
4112 ia64_compare_op1 = operands[1];
4113 DONE;
4114}")
4115
3f622353 4116(define_expand "cmptf"
c65ebc55 4117 [(set (cc0)
3f622353
RH
4118 (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
4119 (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
4120 ""
c65ebc55
JW
4121 "
4122{
4123 ia64_compare_op0 = operands[0];
4124 ia64_compare_op1 = operands[1];
4125 DONE;
4126}")
4127
4128(define_insn "*cmpsi_normal"
f2f90c63
RH
4129 [(set (match_operand:BI 0 "register_operand" "=c")
4130 (match_operator:BI 1 "normal_comparison_operator"
0551c32d
RH
4131 [(match_operand:SI 2 "gr_register_operand" "r")
4132 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
c65ebc55
JW
4133 ""
4134 "cmp4.%C1 %0, %I0 = %3, %2"
4135 [(set_attr "type" "A")])
4136
4137(define_insn "*cmpsi_adjusted"
f2f90c63
RH
4138 [(set (match_operand:BI 0 "register_operand" "=c")
4139 (match_operator:BI 1 "adjusted_comparison_operator"
0551c32d
RH
4140 [(match_operand:SI 2 "gr_register_operand" "r")
4141 (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
c65ebc55
JW
4142 ""
4143 "cmp4.%C1 %0, %I0 = %3, %2"
4144 [(set_attr "type" "A")])
4145
4146(define_insn "*cmpdi_normal"
f2f90c63
RH
4147 [(set (match_operand:BI 0 "register_operand" "=c")
4148 (match_operator:BI 1 "normal_comparison_operator"
4149 [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
0551c32d 4150 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
c65ebc55 4151 ""
f2f90c63 4152 "cmp.%C1 %0, %I0 = %3, %r2"
c65ebc55
JW
4153 [(set_attr "type" "A")])
4154
4155(define_insn "*cmpdi_adjusted"
f2f90c63
RH
4156 [(set (match_operand:BI 0 "register_operand" "=c")
4157 (match_operator:BI 1 "adjusted_comparison_operator"
0551c32d
RH
4158 [(match_operand:DI 2 "gr_register_operand" "r")
4159 (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
c65ebc55
JW
4160 ""
4161 "cmp.%C1 %0, %I0 = %3, %2"
4162 [(set_attr "type" "A")])
4163
4164(define_insn "*cmpsf_internal"
f2f90c63
RH
4165 [(set (match_operand:BI 0 "register_operand" "=c")
4166 (match_operator:BI 1 "comparison_operator"
0551c32d
RH
4167 [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
4168 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
c65ebc55
JW
4169 ""
4170 "fcmp.%D1 %0, %I0 = %F2, %F3"
4171 [(set_attr "type" "F")])
4172
4173(define_insn "*cmpdf_internal"
f2f90c63
RH
4174 [(set (match_operand:BI 0 "register_operand" "=c")
4175 (match_operator:BI 1 "comparison_operator"
0551c32d
RH
4176 [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
4177 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
c65ebc55
JW
4178 ""
4179 "fcmp.%D1 %0, %I0 = %F2, %F3"
4180 [(set_attr "type" "F")])
4181
3f622353 4182(define_insn "*cmptf_internal"
f2f90c63
RH
4183 [(set (match_operand:BI 0 "register_operand" "=c")
4184 (match_operator:BI 1 "comparison_operator"
3f622353
RH
4185 [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
4186 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
4187 ""
4188 "fcmp.%D1 %0, %I0 = %F2, %F3"
4189 [(set_attr "type" "F")])
4190
c65ebc55
JW
4191;; ??? Can this pattern be generated?
4192
4193(define_insn "*bit_zero"
f2f90c63
RH
4194 [(set (match_operand:BI 0 "register_operand" "=c")
4195 (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
4196 (const_int 1)
4197 (match_operand:DI 2 "immediate_operand" "n"))
4198 (const_int 0)))]
4199 ""
4200 "tbit.z %0, %I0 = %1, %2"
4201 [(set_attr "type" "I")])
4202
4203(define_insn "*bit_one"
f2f90c63
RH
4204 [(set (match_operand:BI 0 "register_operand" "=c")
4205 (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
4206 (const_int 1)
4207 (match_operand:DI 2 "immediate_operand" "n"))
4208 (const_int 0)))]
4209 ""
4210 "tbit.nz %0, %I0 = %1, %2"
4211 [(set_attr "type" "I")])
c65ebc55
JW
4212\f
4213;; ::::::::::::::::::::
4214;; ::
4215;; :: Branches
4216;; ::
4217;; ::::::::::::::::::::
4218
4219(define_expand "beq"
f2f90c63
RH
4220 [(set (pc)
4221 (if_then_else (match_dup 1)
c65ebc55
JW
4222 (label_ref (match_operand 0 "" ""))
4223 (pc)))]
4224 ""
f2f90c63 4225 "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
c65ebc55
JW
4226
4227(define_expand "bne"
f2f90c63
RH
4228 [(set (pc)
4229 (if_then_else (match_dup 1)
c65ebc55
JW
4230 (label_ref (match_operand 0 "" ""))
4231 (pc)))]
4232 ""
f2f90c63 4233 "operands[1] = ia64_expand_compare (NE, VOIDmode);")
c65ebc55
JW
4234
4235(define_expand "blt"
f2f90c63
RH
4236 [(set (pc)
4237 (if_then_else (match_dup 1)
c65ebc55
JW
4238 (label_ref (match_operand 0 "" ""))
4239 (pc)))]
4240 ""
f2f90c63 4241 "operands[1] = ia64_expand_compare (LT, VOIDmode);")
c65ebc55
JW
4242
4243(define_expand "ble"
f2f90c63
RH
4244 [(set (pc)
4245 (if_then_else (match_dup 1)
c65ebc55
JW
4246 (label_ref (match_operand 0 "" ""))
4247 (pc)))]
4248 ""
f2f90c63 4249 "operands[1] = ia64_expand_compare (LE, VOIDmode);")
c65ebc55
JW
4250
4251(define_expand "bgt"
f2f90c63
RH
4252 [(set (pc)
4253 (if_then_else (match_dup 1)
c65ebc55
JW
4254 (label_ref (match_operand 0 "" ""))
4255 (pc)))]
4256 ""
f2f90c63 4257 "operands[1] = ia64_expand_compare (GT, VOIDmode);")
c65ebc55
JW
4258
4259(define_expand "bge"
f2f90c63
RH
4260 [(set (pc)
4261 (if_then_else (match_dup 1)
c65ebc55
JW
4262 (label_ref (match_operand 0 "" ""))
4263 (pc)))]
4264 ""
f2f90c63 4265 "operands[1] = ia64_expand_compare (GE, VOIDmode);")
c65ebc55
JW
4266
4267(define_expand "bltu"
f2f90c63
RH
4268 [(set (pc)
4269 (if_then_else (match_dup 1)
c65ebc55
JW
4270 (label_ref (match_operand 0 "" ""))
4271 (pc)))]
4272 ""
f2f90c63 4273 "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
c65ebc55
JW
4274
4275(define_expand "bleu"
f2f90c63
RH
4276 [(set (pc)
4277 (if_then_else (match_dup 1)
c65ebc55
JW
4278 (label_ref (match_operand 0 "" ""))
4279 (pc)))]
4280 ""
f2f90c63 4281 "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
c65ebc55
JW
4282
4283(define_expand "bgtu"
f2f90c63
RH
4284 [(set (pc)
4285 (if_then_else (match_dup 1)
c65ebc55
JW
4286 (label_ref (match_operand 0 "" ""))
4287 (pc)))]
4288 ""
f2f90c63 4289 "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
c65ebc55
JW
4290
4291(define_expand "bgeu"
f2f90c63
RH
4292 [(set (pc)
4293 (if_then_else (match_dup 1)
c65ebc55
JW
4294 (label_ref (match_operand 0 "" ""))
4295 (pc)))]
4296 ""
f2f90c63 4297 "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
c65ebc55 4298
e57b9d65 4299(define_expand "bunordered"
f2f90c63
RH
4300 [(set (pc)
4301 (if_then_else (match_dup 1)
e57b9d65
RH
4302 (label_ref (match_operand 0 "" ""))
4303 (pc)))]
4304 ""
f2f90c63 4305 "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
e57b9d65
RH
4306
4307(define_expand "bordered"
f2f90c63
RH
4308 [(set (pc)
4309 (if_then_else (match_dup 1)
e57b9d65
RH
4310 (label_ref (match_operand 0 "" ""))
4311 (pc)))]
4312 ""
f2f90c63 4313 "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
e57b9d65 4314
6b6c1201 4315(define_insn "*br_true"
c65ebc55 4316 [(set (pc)
6b6c1201 4317 (if_then_else (match_operator 0 "predicate_operator"
f2f90c63 4318 [(match_operand:BI 1 "register_operand" "c")
6b6c1201
RH
4319 (const_int 0)])
4320 (label_ref (match_operand 2 "" ""))
c65ebc55
JW
4321 (pc)))]
4322 ""
85548039 4323 "(%J0) br.cond%+ %l2"
e5bde68a
RH
4324 [(set_attr "type" "B")
4325 (set_attr "predicable" "no")])
c65ebc55 4326
6b6c1201 4327(define_insn "*br_false"
c65ebc55 4328 [(set (pc)
6b6c1201 4329 (if_then_else (match_operator 0 "predicate_operator"
f2f90c63 4330 [(match_operand:BI 1 "register_operand" "c")
6b6c1201 4331 (const_int 0)])
c65ebc55 4332 (pc)
6b6c1201 4333 (label_ref (match_operand 2 "" ""))))]
c65ebc55 4334 ""
85548039 4335 "(%j0) br.cond%+ %l2"
e5bde68a
RH
4336 [(set_attr "type" "B")
4337 (set_attr "predicable" "no")])
c65ebc55
JW
4338\f
4339;; ::::::::::::::::::::
4340;; ::
5527bf14
RH
4341;; :: Counted loop operations
4342;; ::
4343;; ::::::::::::::::::::
4344
4345(define_expand "doloop_end"
4346 [(use (match_operand 0 "" "")) ; loop pseudo
4347 (use (match_operand 1 "" "")) ; iterations; zero if unknown
4348 (use (match_operand 2 "" "")) ; max iterations
4349 (use (match_operand 3 "" "")) ; loop level
4350 (use (match_operand 4 "" ""))] ; label
4351 ""
4352 "
4353{
4354 /* Only use cloop on innermost loops. */
4355 if (INTVAL (operands[3]) > 1)
4356 FAIL;
4357 emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
4358 operands[4]));
4359 DONE;
4360}")
4361
4362(define_insn "doloop_end_internal"
4363 [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
4364 (const_int 0))
4365 (label_ref (match_operand 1 "" ""))
4366 (pc)))
4367 (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
4368 (match_dup 0)
4369 (plus:DI (match_dup 0) (const_int -1))))]
4370 ""
4371 "br.cloop.sptk.few %l1"
4372 [(set_attr "type" "B")
4373 (set_attr "predicable" "no")])
4374\f
4375;; ::::::::::::::::::::
4376;; ::
c65ebc55
JW
4377;; :: Set flag operations
4378;; ::
4379;; ::::::::::::::::::::
4380
4381(define_expand "seq"
f2f90c63 4382 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4383 ""
f2f90c63 4384 "operands[1] = ia64_expand_compare (EQ, DImode);")
c65ebc55
JW
4385
4386(define_expand "sne"
f2f90c63 4387 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4388 ""
f2f90c63 4389 "operands[1] = ia64_expand_compare (NE, DImode);")
c65ebc55
JW
4390
4391(define_expand "slt"
f2f90c63 4392 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4393 ""
f2f90c63 4394 "operands[1] = ia64_expand_compare (LT, DImode);")
c65ebc55
JW
4395
4396(define_expand "sle"
f2f90c63 4397 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4398 ""
f2f90c63 4399 "operands[1] = ia64_expand_compare (LE, DImode);")
c65ebc55
JW
4400
4401(define_expand "sgt"
f2f90c63 4402 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4403 ""
f2f90c63 4404 "operands[1] = ia64_expand_compare (GT, DImode);")
c65ebc55
JW
4405
4406(define_expand "sge"
f2f90c63 4407 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4408 ""
f2f90c63 4409 "operands[1] = ia64_expand_compare (GE, DImode);")
c65ebc55
JW
4410
4411(define_expand "sltu"
f2f90c63 4412 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4413 ""
f2f90c63 4414 "operands[1] = ia64_expand_compare (LTU, DImode);")
c65ebc55
JW
4415
4416(define_expand "sleu"
f2f90c63 4417 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4418 ""
f2f90c63 4419 "operands[1] = ia64_expand_compare (LEU, DImode);")
c65ebc55
JW
4420
4421(define_expand "sgtu"
f2f90c63 4422 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4423 ""
f2f90c63 4424 "operands[1] = ia64_expand_compare (GTU, DImode);")
c65ebc55
JW
4425
4426(define_expand "sgeu"
f2f90c63 4427 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
c65ebc55 4428 ""
f2f90c63 4429 "operands[1] = ia64_expand_compare (GEU, DImode);")
c65ebc55 4430
e57b9d65 4431(define_expand "sunordered"
f2f90c63 4432 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
e57b9d65 4433 ""
f2f90c63 4434 "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
e57b9d65
RH
4435
4436(define_expand "sordered"
f2f90c63 4437 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
e57b9d65 4438 ""
f2f90c63 4439 "operands[1] = ia64_expand_compare (ORDERED, DImode);")
e57b9d65 4440
c65ebc55
JW
4441;; Don't allow memory as destination here, because cmov/cmov/st is more
4442;; efficient than mov/mov/cst/cst.
4443
0551c32d
RH
4444(define_insn_and_split "*sne_internal"
4445 [(set (match_operand:DI 0 "gr_register_operand" "=r")
f2f90c63 4446 (ne:DI (match_operand:BI 1 "register_operand" "c")
c65ebc55
JW
4447 (const_int 0)))]
4448 ""
4449 "#"
c65ebc55 4450 "reload_completed"
f2f90c63
RH
4451 [(cond_exec (ne (match_dup 1) (const_int 0))
4452 (set (match_dup 0) (const_int 1)))
4453 (cond_exec (eq (match_dup 1) (const_int 0))
4454 (set (match_dup 0) (const_int 0)))]
0551c32d
RH
4455 ""
4456 [(set_attr "type" "unknown")])
c65ebc55 4457
0551c32d
RH
4458(define_insn_and_split "*seq_internal"
4459 [(set (match_operand:DI 0 "gr_register_operand" "=r")
f2f90c63 4460 (eq:DI (match_operand:BI 1 "register_operand" "c")
c65ebc55
JW
4461 (const_int 0)))]
4462 ""
4463 "#"
c65ebc55 4464 "reload_completed"
f2f90c63
RH
4465 [(cond_exec (ne (match_dup 1) (const_int 0))
4466 (set (match_dup 0) (const_int 0)))
4467 (cond_exec (eq (match_dup 1) (const_int 0))
4468 (set (match_dup 0) (const_int 1)))]
0551c32d
RH
4469 ""
4470 [(set_attr "type" "unknown")])
c65ebc55
JW
4471\f
4472;; ::::::::::::::::::::
4473;; ::
4474;; :: Conditional move instructions.
4475;; ::
4476;; ::::::::::::::::::::
4477
4478;; ??? Add movXXcc patterns?
4479
c65ebc55
JW
4480;;
4481;; DImode if_then_else patterns.
4482;;
4483
75cdbeb8
RH
4484;; Errata 72 workaround.
4485(define_insn "*cmovdi_internal_astep"
f2f90c63
RH
4486 [(set (match_operand:DI 0 "register_operand"
4487 "=r,*f,*b,r,*f,*b,r,*f,*b")
75cdbeb8 4488 (if_then_else:DI
f2f90c63
RH
4489 (match_operator 4 "predicate_operator"
4490 [(match_operand:BI 1 "register_operand"
4491 "c,c,c,c,c,c,c,c,c")
75cdbeb8 4492 (const_int 0)])
f2f90c63
RH
4493 (match_operand:DI 2 "move_operand"
4494 "0,0,0,ri*f*b,rO,r,ri*f*b,rO,r")
4495 (match_operand:DI 3 "move_operand"
4496 "ri*f*b,rO,r,0,0,0,ri*f*b,rO,r")))]
4497 "TARGET_A_STEP
4498 && ia64_move_ok (operands[0], operands[2])
4499 && ia64_move_ok (operands[0], operands[3])"
75cdbeb8
RH
4500 "* abort ();"
4501 [(set_attr "predicable" "no")])
4502
4503(define_insn "*cmovdi_internal"
f2f90c63 4504 [(set (match_operand:DI 0 "destination_operand"
514f96e6 4505 "=r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e")
e5bde68a 4506 (if_then_else:DI
f2f90c63
RH
4507 (match_operator 4 "predicate_operator"
4508 [(match_operand:BI 1 "register_operand"
514f96e6 4509 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
e5bde68a 4510 (const_int 0)])
f2f90c63 4511 (match_operand:DI 2 "move_operand"
514f96e6 4512 "0,0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,rO,rK,rim*f*b*d*e,rO,rOQ,*f,rO,rK")
f2f90c63 4513 (match_operand:DI 3 "move_operand"
514f96e6 4514 "rim*f*b*d*e,rO,rOQ,*f,rO,rK,0,0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,rO,rK")))]
f2f90c63
RH
4515 "! TARGET_A_STEP
4516 && ia64_move_ok (operands[0], operands[2])
4517 && ia64_move_ok (operands[0], operands[3])"
75cdbeb8
RH
4518 "* abort ();"
4519 [(set_attr "predicable" "no")])
4520
4521(define_split
f2f90c63 4522 [(set (match_operand 0 "destination_operand" "")
75cdbeb8 4523 (if_then_else
f2f90c63
RH
4524 (match_operator 4 "predicate_operator"
4525 [(match_operand:BI 1 "register_operand" "")
75cdbeb8 4526 (const_int 0)])
f2f90c63
RH
4527 (match_operand 2 "move_operand" "")
4528 (match_operand 3 "move_operand" "")))]
3b572406
RH
4529 "reload_completed"
4530 [(const_int 0)]
e5bde68a
RH
4531 "
4532{
3b572406
RH
4533 rtx tmp;
4534 if (! rtx_equal_p (operands[0], operands[2]))
e5bde68a 4535 {
3b572406
RH
4536 tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
4537 tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
4538 emit_insn (tmp);
e5bde68a 4539 }
3b572406
RH
4540 if (! rtx_equal_p (operands[0], operands[3]))
4541 {
4542 tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
f2f90c63 4543 VOIDmode, operands[1], const0_rtx);
3b572406
RH
4544 tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
4545 gen_rtx_SET (VOIDmode, operands[0],
4546 operands[3]));
4547 emit_insn (tmp);
4548 }
4549 DONE;
75cdbeb8 4550}")
c65ebc55
JW
4551
4552;; Absolute value pattern.
4553
4554(define_insn "*absdi2_internal"
0551c32d 4555 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
e5bde68a 4556 (if_then_else:DI
f2f90c63
RH
4557 (match_operator 4 "predicate_operator"
4558 [(match_operand:BI 1 "register_operand" "c,c")
e5bde68a 4559 (const_int 0)])
0551c32d
RH
4560 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
4561 (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
c65ebc55 4562 ""
e5bde68a 4563 "#"
3b572406
RH
4564 [(set_attr "type" "A,unknown")
4565 (set_attr "predicable" "no")])
c65ebc55
JW
4566
4567(define_split
4568 [(set (match_operand:DI 0 "register_operand" "")
e5bde68a 4569 (if_then_else:DI
f2f90c63
RH
4570 (match_operator 4 "predicate_operator"
4571 [(match_operand:BI 1 "register_operand" "c,c")
e5bde68a 4572 (const_int 0)])
0551c32d
RH
4573 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4574 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
4575 "reload_completed && rtx_equal_p (operands[0], operands[3])"
4576 [(cond_exec
4577 (match_dup 4)
4578 (set (match_dup 0)
4579 (neg:DI (match_dup 2))))]
c65ebc55
JW
4580 "")
4581
e5bde68a
RH
4582(define_split
4583 [(set (match_operand:DI 0 "register_operand" "")
4584 (if_then_else:DI
f2f90c63
RH
4585 (match_operator 4 "predicate_operator"
4586 [(match_operand:BI 1 "register_operand" "c,c")
e5bde68a 4587 (const_int 0)])
0551c32d
RH
4588 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4589 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
4590 "reload_completed"
4591 [(cond_exec
4592 (match_dup 4)
4593 (set (match_dup 0) (neg:DI (match_dup 2))))
4594 (cond_exec
4595 (match_dup 5)
4596 (set (match_dup 0) (match_dup 3)))]
4597 "
4598{
4599 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
f2f90c63 4600 VOIDmode, operands[1], const0_rtx);
e5bde68a 4601}")
c65ebc55
JW
4602
4603;;
4604;; SImode if_then_else patterns.
4605;;
4606
75cdbeb8 4607(define_insn "*cmovsi_internal_astep"
f2f90c63 4608 [(set (match_operand:SI 0 "register_operand" "=r,*f,r,*f,r,*f")
75cdbeb8 4609 (if_then_else:SI
f2f90c63
RH
4610 (match_operator 4 "predicate_operator"
4611 [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c")
75cdbeb8 4612 (const_int 0)])
f2f90c63
RH
4613 (match_operand:SI 2 "move_operand" "0,0,ri*f,rO,ri*f,rO")
4614 (match_operand:SI 3 "move_operand" "ri*f,rO,0,0,ri*f,rO")))]
4615 "TARGET_A_STEP
4616 && ia64_move_ok (operands[0], operands[2])
4617 && ia64_move_ok (operands[0], operands[3])"
75cdbeb8
RH
4618 "* abort ();"
4619 [(set_attr "predicable" "no")])
4620
4621(define_insn "*cmovsi_internal"
f2f90c63 4622 [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
e5bde68a 4623 (if_then_else:SI
f2f90c63
RH
4624 (match_operator 4 "predicate_operator"
4625 [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
e5bde68a 4626 (const_int 0)])
f2f90c63 4627 (match_operand:SI 2 "move_operand"
3b572406 4628 "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
f2f90c63 4629 (match_operand:SI 3 "move_operand"
3b572406 4630 "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
f2f90c63
RH
4631 "! TARGET_A_STEP
4632 && ia64_move_ok (operands[0], operands[2])
4633 && ia64_move_ok (operands[0], operands[3])"
75cdbeb8 4634 "* abort ();"
3b572406 4635 [(set_attr "predicable" "no")])
c65ebc55
JW
4636
4637(define_insn "*abssi2_internal"
0551c32d 4638 [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
e5bde68a 4639 (if_then_else:SI
f2f90c63
RH
4640 (match_operator 4 "predicate_operator"
4641 [(match_operand:BI 1 "register_operand" "c,c")
e5bde68a 4642 (const_int 0)])
0551c32d
RH
4643 (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
4644 (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
c65ebc55 4645 ""
e5bde68a 4646 "#"
3b572406
RH
4647 [(set_attr "type" "A,unknown")
4648 (set_attr "predicable" "no")])
c65ebc55
JW
4649
4650(define_split
4651 [(set (match_operand:SI 0 "register_operand" "")
e5bde68a 4652 (if_then_else:SI
f2f90c63
RH
4653 (match_operator 4 "predicate_operator"
4654 [(match_operand:BI 1 "register_operand" "c,c")
e5bde68a 4655 (const_int 0)])
0551c32d
RH
4656 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4657 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
4658 "reload_completed && rtx_equal_p (operands[0], operands[3])"
4659 [(cond_exec
4660 (match_dup 4)
4661 (set (match_dup 0)
4662 (neg:SI (match_dup 2))))]
c65ebc55
JW
4663 "")
4664
e5bde68a
RH
4665(define_split
4666 [(set (match_operand:SI 0 "register_operand" "")
4667 (if_then_else:SI
f2f90c63
RH
4668 (match_operator 4 "predicate_operator"
4669 [(match_operand:BI 1 "register_operand" "c,c")
e5bde68a 4670 (const_int 0)])
0551c32d
RH
4671 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4672 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
4673 "reload_completed"
4674 [(cond_exec
4675 (match_dup 4)
4676 (set (match_dup 0) (neg:SI (match_dup 2))))
4677 (cond_exec
4678 (match_dup 5)
4679 (set (match_dup 0) (match_dup 3)))]
4680 "
4681{
4682 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
f2f90c63 4683 VOIDmode, operands[1], const0_rtx);
e5bde68a
RH
4684}")
4685
c65ebc55
JW
4686\f
4687;; ::::::::::::::::::::
4688;; ::
4689;; :: Call and branch instructions
4690;; ::
4691;; ::::::::::::::::::::
4692
4693;; Subroutine call instruction returning no value. Operand 0 is the function
4694;; to call; operand 1 is the number of bytes of arguments pushed (in mode
4695;; `SImode', except it is normally a `const_int'); operand 2 is the number of
4696;; registers used as operands.
4697
4698;; On most machines, operand 2 is not actually stored into the RTL pattern. It
4699;; is supplied for the sake of some RISC machines which need to put this
4700;; information into the assembler code; they can put it in the RTL instead of
4701;; operand 1.
4702
4703(define_expand "call"
4704 [(use (match_operand:DI 0 "" ""))
4705 (use (match_operand 1 "" ""))
4706 (use (match_operand 2 "" ""))
4707 (use (match_operand 3 "" ""))]
4708 ""
4709 "
4710{
4711 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
4712 rtx addr = XEXP (operands[0], 0);
4713 enum machine_mode mode = GET_MODE (addr);
4714
59da9a7d 4715 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
c65ebc55
JW
4716 emit_call_insn (gen_call_internal (addr, operands[1],
4717 gen_rtx_REG (DImode, R_BR (0))));
4718
4719 /* If this is an indirect call, then we have the address of a descriptor. */
4720 else if (! symbolic_operand (addr, mode))
4721 emit_insn (gen_indirect_call_pic (addr, operands[1]));
59da9a7d
JW
4722 else if (TARGET_CONST_GP)
4723 emit_call_insn (gen_call_internal (addr, operands[1],
4724 gen_rtx_REG (DImode, R_BR (0))));
c65ebc55
JW
4725 else
4726 emit_insn (gen_call_pic (addr, operands[1]));
4727
4728 DONE;
4729}")
4730
4731(define_expand "indirect_call_pic"
4732 [(set (match_dup 2) (reg:DI 1))
4733 (set (match_dup 3) (mem:DI (match_operand 0 "" "")))
4734 (set (match_dup 4) (plus:DI (match_dup 0) (const_int 8)))
4735 (set (reg:DI 1) (mem:DI (match_dup 4)))
4736 (parallel [(call (mem:DI (match_dup 3)) (match_operand 1 "" ""))
4737 (use (reg:DI 1))
4738 (clobber (reg:DI 320))])
4739 (set (reg:DI 1) (match_dup 2))]
4740 ""
4741 "
4742{
97e242b0 4743 operands[2] = ia64_gp_save_reg (0);
c65ebc55
JW
4744 operands[3] = gen_reg_rtx (DImode);
4745 operands[4] = gen_reg_rtx (DImode);
4746}")
4747
c65ebc55
JW
4748;; ??? Saving/restoring the GP register is not needed if we are calling
4749;; a function in the same module.
4750
4751(define_expand "call_pic"
4752 [(set (match_dup 2) (reg:DI 1))
4753 (parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" ""))
4754 (use (reg:DI 1))
4755 (clobber (reg:DI 320))])
4756 (set (reg:DI 1) (match_dup 2))]
4757 ""
4758 "
4759{
97e242b0
RH
4760 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
4761 operands[2] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[0], 0),
4762 VOIDmode));
c65ebc55
JW
4763}")
4764
c65ebc55
JW
4765(define_insn "call_internal"
4766 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
4767 (match_operand 1 "" ""))
4768 (clobber (match_operand:DI 2 "register_operand" "=b"))]
4769 ""
85548039 4770 "br.call%+.many %2 = %0"
c65ebc55
JW
4771 [(set_attr "type" "B")])
4772
4773(define_insn "*call_internal1"
4774 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
4775 (match_operand 1 "" ""))
4776 (use (reg:DI 1))
4777 (clobber (match_operand:DI 2 "register_operand" "=b"))]
4778 ""
85548039 4779 "br.call%+.many %2 = %0"
c65ebc55
JW
4780 [(set_attr "type" "B")])
4781
4782;; Subroutine call instruction returning a value. Operand 0 is the hard
4783;; register in which the value is returned. There are three more operands, the
4784;; same as the three operands of the `call' instruction (but with numbers
4785;; increased by one).
4786
4787;; Subroutines that return `BLKmode' objects use the `call' insn.
4788
4789(define_expand "call_value"
4790 [(use (match_operand 0 "" ""))
4791 (use (match_operand:DI 1 "" ""))
4792 (use (match_operand 2 "" ""))
4793 (use (match_operand 3 "" ""))
4794 (use (match_operand 4 "" ""))]
4795 ""
4796 "
4797{
4798 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
4799 rtx addr = XEXP (operands[1], 0);
4800 enum machine_mode mode = GET_MODE (addr);
4801
59da9a7d 4802 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
c65ebc55
JW
4803 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
4804 gen_rtx_REG (DImode, R_BR (0))));
4805
4806 /* If this is an indirect call, then we have the address of a descriptor. */
4807 else if (! symbolic_operand (addr, mode))
4808 {
4809 /* This is for HFA returns. */
4810 if (GET_CODE (operands[0]) == PARALLEL)
4811 emit_insn (gen_indirect_call_multiple_values_pic (operands[0], addr,
4812 operands[2]));
4813 else
4814 emit_insn (gen_indirect_call_value_pic (operands[0], addr,
4815 operands[2]));
4816 }
59da9a7d
JW
4817 else if (TARGET_CONST_GP)
4818 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
4819 gen_rtx_REG (DImode, R_BR (0))));
c65ebc55
JW
4820 /* This is for HFA returns. */
4821 else if (GET_CODE (operands[0]) == PARALLEL)
4822 emit_insn (gen_call_multiple_values_pic (operands[0], addr, operands[2]));
4823 else
4824 emit_insn (gen_call_value_pic (operands[0], addr, operands[2]));
4825
4826 DONE;
4827}")
4828
4829(define_expand "indirect_call_value_pic"
4830 [(set (match_dup 3) (reg:DI 1))
4831 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
4832 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
4833 (set (reg:DI 1) (mem:DI (match_dup 5)))
4834 (parallel [(set (match_operand 0 "" "")
4835 (call (mem:DI (match_dup 4)) (match_operand 2 "" "")))
4836 (use (reg:DI 1))
4837 (clobber (reg:DI 320))])
4838 (set (reg:DI 1) (match_dup 3))]
4839 ""
4840 "
4841{
97e242b0 4842 operands[3] = ia64_gp_save_reg (0);
c65ebc55
JW
4843 operands[4] = gen_reg_rtx (DImode);
4844 operands[5] = gen_reg_rtx (DImode);
4845}")
4846
4847(define_expand "indirect_call_multiple_values_pic"
4848 [(set (match_dup 3) (reg:DI 1))
4849 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
4850 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
4851 (set (reg:DI 1) (mem:DI (match_dup 5)))
4852 (match_par_dup 6 [(set (match_operand 0 "" "")
4853 (call (mem:DI (match_dup 4))
4854 (match_operand 2 "" "")))
4855 (use (reg:DI 1))
4856 (clobber (reg:DI 320))])
4857 (set (reg:DI 1) (match_dup 3))]
4858 ""
4859 "
4860{
4861 int count;
4862 int i;
4863 rtx call;
4864
97e242b0 4865 operands[3] = ia64_gp_save_reg (0);
c65ebc55
JW
4866 operands[4] = gen_reg_rtx (DImode);
4867 operands[5] = gen_reg_rtx (DImode);
4868
4869 /* This code is the same as the code in call_multiple_values_pic, except
4870 that op3 was replaced with op6 and op1 was replaced with op4. */
4871 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[4]),
4872 operands[2]);
4873
4874 count = XVECLEN (operands[0], 0);
4875 operands[6] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
4876
4877 XVECEXP (operands[6], 0, 0)
4878 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
4879
4880 XVECEXP (operands[6], 0, 1)
4881 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
4882 XVECEXP (operands[6], 0, 2)
4883 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
4884
4885 for (i = 1; i < count; i++)
4886 XVECEXP (operands[6], 0, i + 2)
4887 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
4888
4889}")
4890
c65ebc55
JW
4891;; ??? Saving/restoring the GP register is not needed if we are calling
4892;; a function in the same module.
4893
4894(define_expand "call_value_pic"
4895 [(set (match_dup 3) (reg:DI 1))
4896 (parallel [(set (match_operand 0 "" "")
4897 (call (mem:DI (match_operand 1 "" ""))
4898 (match_operand 2 "" "")))
4899 (use (reg:DI 1))
4900 (clobber (reg:DI 320))])
4901 (set (reg:DI 1) (match_dup 3))]
4902 ""
4903 "
4904{
97e242b0
RH
4905 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
4906 operands[3] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[1], 0),
4907 VOIDmode));
c65ebc55
JW
4908}")
4909
4910;; ??? Saving/restoring the GP register is not needed if we are calling
4911;; a function in the same module.
4912
4913(define_expand "call_multiple_values_pic"
4914 [(set (match_dup 4) (reg:DI 1))
4915 (match_par_dup 3 [(set (match_operand 0 "" "")
4916 (call (mem:DI (match_operand 1 "" ""))
4917 (match_operand 2 "" "")))
4918 (use (reg:DI 1))
4919 (clobber (reg:DI 320))])
4920 (set (reg:DI 1) (match_dup 4))]
4921 ""
4922 "
4923{
4924 int count;
4925 int i;
4926 rtx call;
4927
97e242b0 4928 operands[4] = ia64_gp_save_reg (0);
c65ebc55
JW
4929
4930 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[1]),
4931 operands[2]);
4932
4933 count = XVECLEN (operands[0], 0);
4934 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
4935
4936 XVECEXP (operands[3], 0, 0)
4937 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
4938
4939 XVECEXP (operands[3], 0, 1)
4940 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
4941 XVECEXP (operands[3], 0, 2)
4942 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
4943
4944 for (i = 1; i < count; i++)
4945 XVECEXP (operands[3], 0, i + 2)
4946 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
4947}")
4948
c65ebc55
JW
4949(define_insn "call_value_internal"
4950 [(set (match_operand 0 "register_operand" "=rf")
4951 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
4952 (match_operand 2 "" "")))
4953 (clobber (match_operand:DI 3 "register_operand" "=b"))]
4954 ""
85548039 4955 "br.call%+.many %3 = %1"
c65ebc55
JW
4956 [(set_attr "type" "B")])
4957
4958(define_insn "*call_value_internal1"
4959 [(set (match_operand 0 "register_operand" "=rf")
4960 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
4961 (match_operand 2 "" "")))
4962 (use (reg:DI 1))
4963 (clobber (match_operand:DI 3 "register_operand" "=b"))]
4964 ""
85548039 4965 "br.call%+.many %3 = %1"
c65ebc55
JW
4966 [(set_attr "type" "B")])
4967
4968(define_insn "*call_multiple_values_internal1"
4969 [(match_parallel 0 "call_multiple_values_operation"
4970 [(set (match_operand 1 "register_operand" "=rf")
4971 (call (mem:DI (match_operand:DI 2 "call_operand" "bi"))
4972 (match_operand 3 "" "")))
4973 (use (reg:DI 1))
4974 (clobber (match_operand:DI 4 "register_operand" "=b"))])]
4975 ""
85548039 4976 "br.call%+.many %4 = %2"
c65ebc55
JW
4977 [(set_attr "type" "B")])
4978
4979;; Call subroutine returning any type.
4980
4981(define_expand "untyped_call"
4982 [(parallel [(call (match_operand 0 "" "")
4983 (const_int 0))
4984 (match_operand 1 "" "")
4985 (match_operand 2 "" "")])]
4986 ""
4987 "
4988{
4989 int i;
4990
4991 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
4992
4993 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4994 {
4995 rtx set = XVECEXP (operands[2], 0, i);
4996 emit_move_insn (SET_DEST (set), SET_SRC (set));
4997 }
4998
4999 /* The optimizer does not know that the call sets the function value
5000 registers we stored in the result block. We avoid problems by
5001 claiming that all hard registers are used and clobbered at this
5002 point. */
5003 emit_insn (gen_blockage ());
5004
5005 DONE;
5006}")
5007
5008(define_insn "return_internal"
5009 [(return)
5010 (use (match_operand:DI 0 "register_operand" "b"))]
5011 ""
5012 "br.ret.sptk.many %0"
5013 [(set_attr "type" "B")])
5014
5015(define_insn "return"
5016 [(return)]
5017 "ia64_direct_return ()"
5018 "br.ret.sptk.many rp"
5019 [(set_attr "type" "B")])
5020
6b6c1201 5021(define_insn "*return_true"
c65ebc55 5022 [(set (pc)
6b6c1201 5023 (if_then_else (match_operator 0 "predicate_operator"
f2f90c63 5024 [(match_operand:BI 1 "register_operand" "c")
6b6c1201 5025 (const_int 0)])
c65ebc55
JW
5026 (return)
5027 (pc)))]
5028 "ia64_direct_return ()"
13da91fd 5029 "(%J0) br.ret%+.many rp"
e5bde68a
RH
5030 [(set_attr "type" "B")
5031 (set_attr "predicable" "no")])
c65ebc55 5032
6b6c1201 5033(define_insn "*return_false"
c65ebc55 5034 [(set (pc)
6b6c1201 5035 (if_then_else (match_operator 0 "predicate_operator"
f2f90c63 5036 [(match_operand:BI 1 "register_operand" "c")
6b6c1201 5037 (const_int 0)])
c65ebc55
JW
5038 (pc)
5039 (return)))]
5040 "ia64_direct_return ()"
13da91fd 5041 "(%j0) br.ret%+.many rp"
e5bde68a
RH
5042 [(set_attr "type" "B")
5043 (set_attr "predicable" "no")])
c65ebc55
JW
5044
5045(define_insn "jump"
5046 [(set (pc) (label_ref (match_operand 0 "" "")))]
5047 ""
5048 "br %l0"
5049 [(set_attr "type" "B")])
5050
5051(define_insn "indirect_jump"
5052 [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
5053 ""
5054 "br %0"
5055 [(set_attr "type" "B")])
5056
5057(define_expand "tablejump"
5058 [(match_operand:DI 0 "register_operand" "")
5059 (match_operand 1 "" "")]
5060 ""
5061 "
5062{
5063 rtx tmp1 = gen_reg_rtx (DImode);
5064 rtx tmp2 = gen_reg_rtx (DImode);
5065
5066 emit_move_insn (tmp1, gen_rtx_LABEL_REF (Pmode, operands[1]));
5067 emit_insn (gen_adddi3 (tmp2, operands[0], tmp1));
5068 emit_jump_insn (gen_tablejump_internal (tmp2, operands[1]));
5069 DONE;
5070}")
5071
5072(define_insn "tablejump_internal"
5073 [(set (pc) (match_operand:DI 0 "register_operand" "b"))
5074 (use (label_ref (match_operand 1 "" "")))]
5075 ""
5076 "br %0"
5077 [(set_attr "type" "B")])
5078
5079\f
5080;; ::::::::::::::::::::
5081;; ::
5082;; :: Prologue and Epilogue instructions
5083;; ::
5084;; ::::::::::::::::::::
5085
5086(define_expand "prologue"
5087 [(const_int 1)]
5088 ""
5089 "
5090{
5091 ia64_expand_prologue ();
5092 DONE;
5093}")
5094
5095(define_expand "epilogue"
5096 [(const_int 2)]
5097 ""
5098 "
5099{
5100 ia64_expand_epilogue ();
5101 DONE;
5102}")
5103
5104;; This prevents the scheduler from moving the SP decrement past FP-relative
5105;; stack accesses. This is the same as adddi3 plus the extra set.
5106
5107(define_insn "prologue_allocate_stack"
5108 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5109 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
0551c32d 5110 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
c65ebc55
JW
5111 (set (match_operand:DI 3 "register_operand" "=r,r,r")
5112 (match_dup 3))]
5113 ""
5114 "@
5115 add %0 = %1, %2
5116 adds %0 = %2, %1
5117 addl %0 = %2, %1"
5118 [(set_attr "type" "A")])
5119
5120;; This prevents the scheduler from moving the SP restore past FP-relative
5121;; stack accesses. This is similar to movdi plus the extra set.
5122
5123(define_insn "epilogue_deallocate_stack"
5124 [(set (match_operand:DI 0 "register_operand" "=r")
5125 (match_operand:DI 1 "register_operand" "+r"))
5126 (set (match_dup 1) (match_dup 1))]
5127 ""
5128 "mov %0 = %1"
5129 [(set_attr "type" "A")])
5130
5131;; Allocate a new register frame.
5132
5133(define_insn "alloc"
5134 [(set (match_operand:DI 0 "register_operand" "=r")
5135 (unspec_volatile:DI [(const_int 0)] 0))
5136 (use (match_operand:DI 1 "const_int_operand" "i"))
5137 (use (match_operand:DI 2 "const_int_operand" "i"))
5138 (use (match_operand:DI 3 "const_int_operand" "i"))
5139 (use (match_operand:DI 4 "const_int_operand" "i"))]
5140 ""
5141 "alloc %0 = ar.pfs, %1, %2, %3, %4"
e5bde68a
RH
5142 [(set_attr "type" "M")
5143 (set_attr "predicable" "no")])
c65ebc55 5144
97e242b0
RH
5145;; Modifies ar.unat
5146(define_expand "gr_spill"
870f9ec0
RH
5147 [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
5148 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5149 (match_operand:DI 2 "const_int_operand" "")] 1))
5150 (clobber (match_dup 3))])]
97e242b0 5151 ""
870f9ec0 5152 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
97e242b0 5153
870f9ec0 5154(define_insn "gr_spill_internal"
c65ebc55 5155 [(set (match_operand:DI 0 "memory_operand" "=m")
870f9ec0
RH
5156 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5157 (match_operand:DI 2 "const_int_operand" "")] 1))
5158 (clobber (match_operand:DI 3 "register_operand" ""))]
c65ebc55 5159 ""
870f9ec0 5160 ".mem.offset %2, 0\;st8.spill %0 = %1%P0"
c65ebc55
JW
5161 [(set_attr "type" "M")])
5162
97e242b0
RH
5163;; Reads ar.unat
5164(define_expand "gr_restore"
870f9ec0
RH
5165 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
5166 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5167 (match_operand:DI 2 "const_int_operand" "")] 2))
5168 (use (match_dup 3))])]
97e242b0 5169 ""
870f9ec0 5170 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
97e242b0 5171
870f9ec0 5172(define_insn "gr_restore_internal"
c65ebc55 5173 [(set (match_operand:DI 0 "register_operand" "=r")
870f9ec0
RH
5174 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5175 (match_operand:DI 2 "const_int_operand" "")] 2))
5176 (use (match_operand:DI 3 "register_operand" ""))]
c65ebc55 5177 ""
870f9ec0 5178 ".mem.offset %2, 0\;ld8.fill %0 = %1%P1"
c65ebc55
JW
5179 [(set_attr "type" "M")])
5180
5181(define_insn "fr_spill"
3f622353
RH
5182 [(set (match_operand:TF 0 "memory_operand" "=m")
5183 (unspec:TF [(match_operand:TF 1 "register_operand" "f")] 3))]
c65ebc55
JW
5184 ""
5185 "stf.spill %0 = %1%P0"
5186 [(set_attr "type" "M")])
5187
5188(define_insn "fr_restore"
3f622353
RH
5189 [(set (match_operand:TF 0 "register_operand" "=f")
5190 (unspec:TF [(match_operand:TF 1 "memory_operand" "m")] 4))]
c65ebc55
JW
5191 ""
5192 "ldf.fill %0 = %1%P1"
5193 [(set_attr "type" "M")])
5194
0c96007e
AM
5195(define_insn "bsp_value"
5196 [(set (match_operand:DI 0 "register_operand" "=r")
5197 (unspec:DI [(const_int 0)] 20))]
5198 ""
5199 "mov %0 = ar.bsp"
5200 [(set_attr "type" "I")])
5201
5202(define_insn "set_bsp"
5203 [(unspec_volatile [(const_int 0)] 5)
5204 (use (match_operand:DI 0 "register_operand" "r"))]
5205 ""
13da91fd 5206 "flushrs\;mov r19=ar.rsc\;;;\;and r19=0x1c,r19\;;;\;mov ar.rsc=r19\;;;\;mov ar.bspstore=%0\;;;\;or r19=0x3,r19\;;;\;loadrs\;invala\;;;\;mov ar.rsc=r19"
e5bde68a
RH
5207 [(set_attr "type" "unknown")
5208 (set_attr "predicable" "no")])
ce152ef8
AM
5209
5210(define_insn "flushrs"
5211 [(unspec [(const_int 0)] 21)]
5212 ""
13da91fd 5213 ";;\;flushrs"
ce152ef8 5214 [(set_attr "type" "M")])
c65ebc55
JW
5215\f
5216;; ::::::::::::::::::::
5217;; ::
5218;; :: Miscellaneous instructions
5219;; ::
5220;; ::::::::::::::::::::
5221
5222;; ??? Emiting a NOP instruction isn't very useful. This should probably
5223;; be emitting ";;" to force a break in the instruction packing.
5224
5225;; No operation, needed in case the user uses -g but not -O.
5226(define_insn "nop"
5227 [(const_int 0)]
5228 ""
5229 "nop 0"
5230 [(set_attr "type" "unknown")])
5231
5232;; Pseudo instruction that prevents the scheduler from moving code above this
5233;; point.
5234(define_insn "blockage"
5235 [(unspec_volatile [(const_int 0)] 1)]
5236 ""
5237 ""
e5bde68a
RH
5238 [(set_attr "type" "unknown")
5239 (set_attr "predicable" "no")])
c65ebc55
JW
5240
5241(define_insn "insn_group_barrier"
5242 [(unspec_volatile [(const_int 0)] 2)]
5243 ""
5244 ";;"
e5bde68a
RH
5245 [(set_attr "type" "S")
5246 (set_attr "predicable" "no")])
c65ebc55
JW
5247
5248\f
5249;; Non-local goto support.
5250
5251(define_expand "save_stack_nonlocal"
5252 [(use (match_operand:OI 0 "memory_operand" ""))
5253 (use (match_operand:DI 1 "register_operand" ""))]
5254 ""
5255 "
5256{
5257 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5258 \"__ia64_save_stack_nonlocal\"),
5259 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
5260 operands[1], Pmode);
5261 DONE;
5262}")
5263
5264(define_expand "nonlocal_goto"
5265 [(use (match_operand 0 "general_operand" ""))
5266 (use (match_operand 1 "general_operand" ""))
5267 (use (match_operand 2 "general_operand" ""))
5268 (use (match_operand 3 "general_operand" ""))]
5269 ""
5270 "
5271{
c65ebc55 5272 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
97e242b0
RH
5273 0, VOIDmode, 3,
5274 operands[1], Pmode,
c65ebc55
JW
5275 copy_to_reg (XEXP (operands[2], 0)), Pmode,
5276 operands[3], Pmode);
5277 emit_barrier ();
5278 DONE;
5279}")
5280
97e242b0
RH
5281;; Restore the GP after the exception/longjmp. The preceeding call will
5282;; have tucked it away.
5283(define_expand "exception_receiver"
5284 [(set (reg:DI 1) (match_dup 0))]
5285 ""
5286 "operands[0] = ia64_gp_save_reg (0);")
c65ebc55 5287
97e242b0
RH
5288;; The rest of the setjmp processing happens with the nonlocal_goto expander.
5289;; ??? This is not tested.
5290(define_expand "builtin_setjmp_setup"
5291 [(use (match_operand:DI 0 "" ""))]
c65ebc55
JW
5292 ""
5293 "
5294{
97e242b0
RH
5295 emit_move_insn (ia64_gp_save_reg (0), gen_rtx_REG (DImode, GR_REG (1)));
5296 DONE;
5297}")
5298
5299(define_expand "builtin_setjmp_receiver"
5300 [(use (match_operand:DI 0 "" ""))]
5301 ""
5302 "
5303{
5304 emit_move_insn (gen_rtx_REG (DImode, GR_REG (1)), ia64_gp_save_reg (0));
c65ebc55
JW
5305 DONE;
5306}")
5307
0c96007e
AM
5308(define_expand "eh_epilogue"
5309 [(use (match_operand:DI 0 "register_operand" "r"))
5310 (use (match_operand:DI 1 "register_operand" "r"))
5311 (use (match_operand:DI 2 "register_operand" "r"))]
5312 ""
5313 "
5314{
5315 rtx bsp = gen_rtx_REG (Pmode, 10);
5316 rtx sp = gen_rtx_REG (Pmode, 9);
5317
5318 if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
5319 {
5320 emit_move_insn (bsp, operands[0]);
5321 operands[0] = bsp;
5322 }
5323 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
5324 {
5325 emit_move_insn (sp, operands[2]);
5326 operands[2] = sp;
5327 }
5328 emit_insn (gen_rtx_USE (VOIDmode, sp));
5329 emit_insn (gen_rtx_USE (VOIDmode, bsp));
5330
5331 cfun->machine->ia64_eh_epilogue_sp = sp;
5332 cfun->machine->ia64_eh_epilogue_bsp = bsp;
0c96007e 5333}")
9525c690
JW
5334\f
5335;; Builtin apply support.
5336
5337(define_expand "restore_stack_nonlocal"
5338 [(use (match_operand:DI 0 "register_operand" ""))
5339 (use (match_operand:OI 1 "memory_operand" ""))]
5340 ""
5341 "
5342{
5343 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5344 \"__ia64_restore_stack_nonlocal\"),
5345 0, VOIDmode, 1,
5346 copy_to_reg (XEXP (operands[1], 0)), Pmode);
5347 DONE;
5348}")
5349
5350\f
5351;;; Intrinsics support.
c65ebc55 5352
0551c32d
RH
5353(define_expand "mf"
5354 [(set (mem:BLK (match_dup 0))
5355 (unspec:BLK [(mem:BLK (match_dup 0))] 12))]
5356 ""
5357 "
5358{
5359 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
5360 MEM_VOLATILE_P (operands[0]) = 1;
5361}")
5362
5363(define_insn "*mf_internal"
5364 [(set (match_operand:BLK 0 "" "")
5365 (unspec:BLK [(match_operand:BLK 1 "" "")] 12))]
c65ebc55
JW
5366 ""
5367 "mf"
5368 [(set_attr "type" "M")])
5369
5370(define_insn "fetchadd_acq_si"
0551c32d
RH
5371 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5372 (match_dup 1))
5373 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
5374 (unspec:SI [(match_dup 1)
5375 (match_operand:SI 2 "fetchadd_operand" "n")] 19))]
c65ebc55
JW
5376 ""
5377 "fetchadd4.acq %0 = %1, %2"
5378 [(set_attr "type" "M")])
5379
5380(define_insn "fetchadd_acq_di"
0551c32d
RH
5381 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5382 (match_dup 1))
5383 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
5384 (unspec:DI [(match_dup 1)
5385 (match_operand:DI 2 "fetchadd_operand" "n")] 19))]
c65ebc55
JW
5386 ""
5387 "fetchadd8.acq %0 = %1, %2"
5388 [(set_attr "type" "M")])
5389
5390(define_insn "cmpxchg_acq_si"
0551c32d
RH
5391 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5392 (match_dup 1))
5393 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
5394 (unspec:SI [(match_dup 1)
5395 (match_operand:SI 2 "gr_register_operand" "r")
97e242b0 5396 (match_operand:SI 3 "ar_ccv_reg_operand" "")] 13))]
c65ebc55 5397 ""
97e242b0 5398 "cmpxchg4.acq %0 = %1, %2, %3"
c65ebc55
JW
5399 [(set_attr "type" "M")])
5400
5401(define_insn "cmpxchg_acq_di"
0551c32d
RH
5402 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5403 (match_dup 1))
5404 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
5405 (unspec:DI [(match_dup 1)
5406 (match_operand:DI 2 "gr_register_operand" "r")
5407 (match_operand:DI 3 "ar_ccv_reg_operand" "")] 13))]
c65ebc55 5408 ""
97e242b0 5409 "cmpxchg8.acq %0 = %1, %2, %3"
c65ebc55
JW
5410 [(set_attr "type" "M")])
5411
c65ebc55 5412(define_insn "xchgsi"
0551c32d
RH
5413 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5414 (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
c65ebc55 5415 (set (match_dup 1)
0551c32d 5416 (match_operand:SI 2 "gr_register_operand" "r"))]
c65ebc55
JW
5417 ""
5418 "xchg4 %0 = %1, %2"
5419 [(set_attr "type" "M")])
5420
5421(define_insn "xchgdi"
0551c32d
RH
5422 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5423 (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
c65ebc55 5424 (set (match_dup 1)
0551c32d 5425 (match_operand:DI 2 "gr_register_operand" "r"))]
c65ebc55
JW
5426 ""
5427 "xchg8 %0 = %1, %2"
5428 [(set_attr "type" "M")])
e5bde68a
RH
5429\f
5430;; Predication.
5431
5432(define_cond_exec
5433 [(match_operator 0 "predicate_operator"
f2f90c63 5434 [(match_operand:BI 1 "register_operand" "c")
e5bde68a
RH
5435 (const_int 0)])]
5436 ""
5437 "(%J0)")
3b572406
RH
5438
5439(define_insn "pred_rel_mutex"
f2f90c63
RH
5440 [(set (match_operand:BI 0 "register_operand" "+c")
5441 (unspec:BI [(match_dup 0)] 7))]
3b572406 5442 ""
054451ea 5443 ".pred.rel.mutex %0, %I0"
3b572406
RH
5444 [(set_attr "type" "unknown")
5445 (set_attr "predicable" "no")])
ca3920ad
JW
5446
5447(define_insn "safe_across_calls_all"
5448 [(unspec_volatile [(const_int 0)] 8)]
5449 ""
5450 ".pred.safe_across_calls p1-p63"
5451 [(set_attr "type" "unknown")
5452 (set_attr "predicable" "no")])
5453
5454(define_insn "safe_across_calls_normal"
5455 [(unspec_volatile [(const_int 0)] 9)]
5456 ""
5457 "*
5458{
5459 emit_safe_across_calls (asm_out_file);
5460 return \"\";
5461}"
5462 [(set_attr "type" "unknown")
5463 (set_attr "predicable" "no")])
5464