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