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