]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/ia64/ia64.md
print-rtl.c (debug_call_placeholder_verbose): New variable.
[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
e5bde68a
RH
53;; Unspec usage:
54;;
55;; unspec:
56;; 1 gr_spill
57;; 2 gr_restore
58;; 3 fr_spill
59;; 4 fr_restore
e5bde68a 60;; 8 popcnt
97e242b0 61;; 12 mf
e5bde68a 62;; 13 cmpxchg_acq
e5bde68a
RH
63;; 19 fetchadd_acq
64;; 20 bsp_value
ce152ef8 65;; 21 flushrs
e5bde68a
RH
66;;
67;; unspec_volatile:
68;; 0 alloc
69;; 1 blockage
70;; 2 insn_group_barrier
e5bde68a 71;; 5 set_bsp
3b572406 72;; 7 pred.rel.mutex
ca3920ad
JW
73;; 8 pred.safe_across_calls all
74;; 9 pred.safe_across_calls normal
c65ebc55
JW
75\f
76;; ::::::::::::::::::::
77;; ::
78;; :: Attributes
79;; ::
80;; ::::::::::::::::::::
81
82;; Instruction type. This primarily determines how instructions can be
83;; packed in bundles, and secondarily affects scheduling to function units.
84
85;; A alu, can go in I or M syllable of a bundle
86;; I integer
87;; M memory
88;; F floating-point
89;; B branch
90;; L long immediate, takes two syllables
91;; S stop bit
92
93;; ??? Should not have any pattern with type unknown. Perhaps add code to
94;; check this in md_reorg? Currently use unknown for patterns which emit
95;; multiple instructions, patterns which emit 0 instructions, and patterns
96;; which emit instruction that can go in any slot (e.g. nop).
97
98(define_attr "type" "unknown,A,I,M,F,B,L,S" (const_string "unknown"))
99
e5bde68a
RH
100;; Predication. True iff this instruction can be predicated.
101
102(define_attr "predicable" "no,yes" (const_string "yes"))
103
c65ebc55
JW
104\f
105;; ::::::::::::::::::::
106;; ::
107;; :: Function Units
108;; ::
109;; ::::::::::::::::::::
110
111;; Each usage of a function units by a class of insns is specified with a
112;; `define_function_unit' expression, which looks like this:
113;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
114;; ISSUE-DELAY [CONFLICT-LIST])
115
116;; This default scheduling info seeks to pack instructions into bundles
117;; efficiently to reduce code size, so we just list how many of each
118;; instruction type can go in a bundle. ISSUE_RATE is set to 3.
119
120;; ??? Add scheduler ready-list hook (MD_SCHED_REORDER) that orders
121;; instructions, so that the next instruction can fill the next bundle slot.
122;; This really needs to know where the stop bits are though.
123
124;; ??? Use MD_SCHED_REORDER to put alloc first instead of using an unspec
125;; volatile. Use ADJUST_PRIORITY to set the priority of alloc very high to
126;; make it schedule first.
127
128;; ??? Modify the md_reorg code that emits stop bits so that instead of putting
129;; them in the last possible place, we put them in places where bundles allow
130;; them. This should reduce code size, but may decrease performance if we end
131;; up with more stop bits than the minimum we need.
132
133;; Alu instructions can execute on either the integer or memory function
134;; unit. We indicate this by defining an alu function unit, and then marking
135;; it as busy everytime we issue a integer or memory type instruction.
136
137(define_function_unit "alu" 3 1 (eq_attr "type" "A,I,M") 1 0)
138
139(define_function_unit "integer" 2 1 (eq_attr "type" "I") 1 0)
140
141(define_function_unit "memory" 3 1 (eq_attr "type" "M") 1 0)
142
143(define_function_unit "floating_point" 1 1 (eq_attr "type" "F") 1 0)
144
145(define_function_unit "branch" 3 1 (eq_attr "type" "B") 1 0)
146
147;; ??? This isn't quite right, because we can only fit two insns in a bundle
148;; when using an L type instruction. That isn't modeled currently.
149
150(define_function_unit "long_immediate" 1 1 (eq_attr "type" "L") 1 0)
151
152\f
153;; ::::::::::::::::::::
154;; ::
155;; :: Moves
156;; ::
157;; ::::::::::::::::::::
158
159(define_expand "movqi"
160 [(set (match_operand:QI 0 "general_operand" "")
161 (match_operand:QI 1 "general_operand" ""))]
162 ""
163 "
164{
165 if (! reload_in_progress && ! reload_completed
557b9df5
RH
166 && ! ia64_move_ok (operands[0], operands[1]))
167 operands[1] = force_reg (QImode, operands[1]);
c65ebc55
JW
168}")
169
75cdbeb8
RH
170;; Errata 72 implies that we cannot use predicated loads and stores
171;; on affected systems. Reuse TARGET_A_STEP for convenience.
172
173;; ??? It would be convenient at this point if the cond_exec pattern
174;; expander understood non-constant conditions on attributes. Failing
175;; that we have to replicate patterns.
176
177(define_insn "*movqicc_astep"
178 [(cond_exec
179 (match_operator 2 "predicate_operator"
180 [(match_operand:CC 3 "register_operand" "c,c,c,c,c")
181 (const_int 0)])
182 (set (match_operand:QI 0 "register_operand" "=r,r, r,*f,*f")
183 (match_operand:QI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
184 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
185 "@
186 (%J2) mov %0 = %r1
187 (%J2) addl %0 = %1, r0
188 (%J2) getf.sig %0 = %1
189 (%J2) setf.sig %0 = %r1
190 (%J2) mov %0 = %1"
191 [(set_attr "type" "A,A,M,M,F")
192 (set_attr "predicable" "no")])
193
194(define_insn "*movqi_internal_astep"
4b983fdc
RH
195 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
196 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
75cdbeb8
RH
197 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
198 "@
199 mov %0 = %r1
200 addl %0 = %1, r0
201 ld1%O1 %0 = %1%P1
202 st1%Q0 %0 = %r1%P0
203 getf.sig %0 = %1
204 setf.sig %0 = %r1
205 mov %0 = %1"
206 [(set_attr "type" "A,A,M,M,M,M,F")
207 (set_attr "predicable" "no")])
208
c65ebc55 209(define_insn "*movqi_internal"
4b983fdc
RH
210 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
211 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
75cdbeb8 212 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55 213 "@
13da91fd 214 mov %0 = %r1
c65ebc55
JW
215 addl %0 = %1, r0
216 ld1%O1 %0 = %1%P1
13da91fd 217 st1%Q0 %0 = %r1%P0
c65ebc55 218 getf.sig %0 = %1
13da91fd
RH
219 setf.sig %0 = %r1
220 mov %0 = %1"
221 [(set_attr "type" "A,A,M,M,M,M,F")])
c65ebc55
JW
222
223(define_expand "movhi"
224 [(set (match_operand:HI 0 "general_operand" "")
225 (match_operand:HI 1 "general_operand" ""))]
226 ""
227 "
228{
229 if (! reload_in_progress && ! reload_completed
557b9df5
RH
230 && ! ia64_move_ok (operands[0], operands[1]))
231 operands[1] = force_reg (HImode, operands[1]);
c65ebc55
JW
232}")
233
75cdbeb8
RH
234;; Errata 72 workaround.
235(define_insn "*movhicc_astep"
236 [(cond_exec
237 (match_operator 2 "predicate_operator"
238 [(match_operand:CC 3 "register_operand" "c,c,c,c,c")
239 (const_int 0)])
240 (set (match_operand:HI 0 "register_operand" "=r,r, r,*f,*f")
241 (match_operand:HI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
242 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
243 "@
244 (%J2) mov %0 = %r1
245 (%J2) addl %0 = %1, r0
246 (%J2) getf.sig %0 = %1
247 (%J2) setf.sig %0 = %r1
248 (%J2) mov %0 = %1"
249 [(set_attr "type" "A,A,M,M,F")
250 (set_attr "predicable" "no")])
251
252(define_insn "*movhi_internal_astep"
4b983fdc
RH
253 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
254 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
75cdbeb8
RH
255 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
256 "@
257 mov %0 = %r1
258 addl %0 = %1, r0
259 ld2%O1 %0 = %1%P1
260 st2%Q0 %0 = %r1%P0
261 getf.sig %0 = %1
262 setf.sig %0 = %r1
263 mov %0 = %1"
264 [(set_attr "type" "A,A,M,M,M,M,F")
265 (set_attr "predicable" "no")])
266
c65ebc55 267(define_insn "*movhi_internal"
4b983fdc
RH
268 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
269 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
75cdbeb8 270 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55 271 "@
13da91fd 272 mov %0 = %r1
c65ebc55
JW
273 addl %0 = %1, r0
274 ld2%O1 %0 = %1%P1
13da91fd 275 st2%Q0 %0 = %r1%P0
c65ebc55 276 getf.sig %0 = %1
13da91fd
RH
277 setf.sig %0 = %r1
278 mov %0 = %1"
279 [(set_attr "type" "A,A,M,M,M,M,F")])
c65ebc55
JW
280
281(define_expand "movsi"
282 [(set (match_operand:SI 0 "general_operand" "")
283 (match_operand:SI 1 "general_operand" ""))]
284 ""
285 "
286{
287 if (! reload_in_progress && ! reload_completed
557b9df5
RH
288 && ! ia64_move_ok (operands[0], operands[1]))
289 operands[1] = force_reg (SImode, operands[1]);
c65ebc55
JW
290}")
291
75cdbeb8
RH
292;; Errata 72 workaround.
293(define_insn "*movsicc_astep"
294 [(cond_exec
295 (match_operator 2 "predicate_operator"
97e242b0 296 [(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c")
75cdbeb8 297 (const_int 0)])
97e242b0 298 (set (match_operand:SI 0 "register_operand" "=r,r,r, r,*f,*f, r,*d")
514f96e6 299 (match_operand:SI 1 "nonmemory_operand" "rO,J,i,*f,rO,*f,*d,rK")))]
75cdbeb8
RH
300 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
301 "@
302 (%J2) mov %0 = %r1
303 (%J2) addl %0 = %1, r0
304 (%J2) movl %0 = %1
305 (%J2) getf.sig %0 = %1
306 (%J2) setf.sig %0 = %r1
97e242b0
RH
307 (%J2) mov %0 = %1
308 (%J2) mov %0 = %1
309 (%J2) mov %0 = %r1"
310 [(set_attr "type" "A,A,L,M,M,F,M,M")
75cdbeb8
RH
311 (set_attr "predicable" "no")])
312
313(define_insn "*movsi_internal_astep"
97e242b0 314 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
514f96e6 315 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
75cdbeb8
RH
316 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
317 "@
318 mov %0 = %r1
319 addl %0 = %1, r0
320 movl %0 = %1
321 ld4%O1 %0 = %1%P1
322 st4%Q0 %0 = %r1%P0
323 getf.sig %0 = %1
324 setf.sig %0 = %r1
97e242b0
RH
325 mov %0 = %1
326 mov %0 = %1
327 mov %0 = %r1"
328 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M")
75cdbeb8
RH
329 (set_attr "predicable" "no")])
330
c65ebc55 331(define_insn "*movsi_internal"
97e242b0 332 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
514f96e6 333 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
75cdbeb8 334 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55 335 "@
13da91fd 336 mov %0 = %r1
c65ebc55
JW
337 addl %0 = %1, r0
338 movl %0 = %1
339 ld4%O1 %0 = %1%P1
13da91fd 340 st4%Q0 %0 = %r1%P0
c65ebc55 341 getf.sig %0 = %1
13da91fd 342 setf.sig %0 = %r1
97e242b0
RH
343 mov %0 = %1
344 mov %0 = %1
345 mov %0 = %r1"
346 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M")])
c65ebc55
JW
347
348(define_expand "movdi"
349 [(set (match_operand:DI 0 "general_operand" "")
350 (match_operand:DI 1 "general_operand" ""))]
351 ""
352 "
353{
9a89adb8
RH
354 if (! reload_in_progress && ! reload_completed
355 && ! ia64_move_ok (operands[0], operands[1]))
356 operands[1] = force_reg (DImode, operands[1]);
ec039e3c 357 if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
c65ebc55 358 {
9a89adb8
RH
359 /* Before optimization starts, delay committing to any particular
360 type of PIC address load. If this function gets deferred, we
361 may acquire information that changes the value of the
362 sdata_symbolic_operand predicate. */
7c866fb5
JW
363 /* But don't delay for function pointers. Loading a function address
364 actually loads the address of the descriptor not the function.
365 If we represent these as SYMBOL_REFs, then they get cse'd with
366 calls, and we end up with calls to the descriptor address instead of
367 calls to the function address. Functions are not candidates for
368 sdata anyways. */
369 if (rtx_equal_function_value_matters
370 && ! (GET_CODE (operands[1]) == SYMBOL_REF
371 && SYMBOL_REF_FLAG (operands[1])))
9a89adb8
RH
372 emit_insn (gen_movdi_symbolic (operands[0], operands[1]));
373 else
374 ia64_expand_load_address (operands[0], operands[1]);
9b7bf67d 375 DONE;
c65ebc55 376 }
c65ebc55
JW
377}")
378
75cdbeb8
RH
379;; Errata 72 workaround.
380(define_insn ""
381 [(cond_exec
382 (match_operator 2 "predicate_operator"
514f96e6 383 [(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c,c,c,c")
75cdbeb8 384 (const_int 0)])
5527bf14 385 (set (match_operand:DI 0 "register_operand"
514f96e6 386 "=r,r,r, r,*f,*f, r,*b,*e, r,*d")
5527bf14 387 (match_operand:DI 1 "nonmemory_operand"
514f96e6 388 "rO,J,i,*f,rO,*f,*b*e,rO,rK,*d,rK")))]
75cdbeb8
RH
389 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
390 "*
391{
392 static const char * const alt[] = {
393 \"(%J2) mov %0 = %r1\",
394 \"(%J2) addl %0 = %1, r0\",
395 \"(%J2) movl %0 = %1\",
396 \"(%J2) getf.sig %0 = %1\",
397 \"(%J2) setf.sig %0 = %r1\",
398 \"(%J2) mov %0 = %1\",
399 \"(%J2) mov %0 = %1\",
5527bf14
RH
400 \"(%J2) mov %0 = %r1\",
401 \"(%J2) mov %0 = %1\",
514f96e6
RH
402 \"(%J2) mov %0 = %1\",
403 \"(%J2) mov %0 = %1\"
75cdbeb8
RH
404 };
405
406 /* We use 'i' for alternative 2 despite possible PIC problems.
407
408 If we define LEGITIMATE_CONSTANT_P such that symbols are not
409 allowed, then the compiler dumps the data into constant memory
410 instead of letting us read the values from the GOT. Similarly
411 if we use 'n' instead of 'i'.
412
413 Instead, we allow such insns through reload and then split them
414 afterward (even without optimization). Therefore, we should
415 never get so far with a symbolic operand. */
416
417 if (which_alternative == 2 && ! TARGET_NO_PIC
418 && symbolic_operand (operands[1], VOIDmode))
419 abort ();
420
421 return alt[which_alternative];
422}"
514f96e6 423 [(set_attr "type" "A,A,L,M,M,F,I,I,I,M,M")
75cdbeb8
RH
424 (set_attr "predicable" "no")])
425
9a89adb8
RH
426;; This is used during early compilation to delay the decision on
427;; how to refer to a variable as long as possible. This is especially
428;; important between initial rtl generation and optimization for
429;; deferred functions, since we may acquire additional information
430;; on the variables used in the meantime.
431
432(define_insn_and_split "movdi_symbolic"
433 [(set (match_operand:DI 0 "register_operand" "=r")
434 (match_operand:DI 1 "symbolic_operand" "s"))
435 (use (reg:DI 1))]
436 ""
437 "* abort ();"
438 ""
439 [(const_int 0)]
440 "ia64_expand_load_address (operands[0], operands[1]); DONE;")
441
75cdbeb8 442(define_insn "*movdi_internal_astep"
4b983fdc 443 [(set (match_operand:DI 0 "destination_operand"
514f96e6 444 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b,*e, r,*d, r,*c")
4b983fdc 445 (match_operand:DI 1 "move_operand"
514f96e6 446 "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e,rO,rK,*d,rK,*c,rO"))]
75cdbeb8
RH
447 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
448 "*
449{
450 static const char * const alt[] = {
451 \"mov %0 = %r1\",
452 \"addl %0 = %1, r0\",
453 \"movl %0 = %1\",
454 \"ld8%O1 %0 = %1%P1\",
455 \"st8%Q0 %0 = %r1%P0\",
456 \"getf.sig %0 = %1\",
457 \"setf.sig %0 = %r1\",
458 \"mov %0 = %1\",
459 \"ldf8 %0 = %1%P1\",
460 \"stf8 %0 = %1%P0\",
461 \"mov %0 = %1\",
5527bf14
RH
462 \"mov %0 = %r1\",
463 \"mov %0 = %1\",
514f96e6
RH
464 \"mov %0 = %1\",
465 \"mov %0 = %1\",
97e242b0
RH
466 \"mov %0 = pr\",
467 \"mov pr = %1, -1\"
75cdbeb8
RH
468 };
469
470 if (which_alternative == 2 && ! TARGET_NO_PIC
471 && symbolic_operand (operands[1], VOIDmode))
472 abort ();
473
474 return alt[which_alternative];
475}"
514f96e6 476 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,I,M,M,I,I")
75cdbeb8
RH
477 (set_attr "predicable" "no")])
478
c65ebc55 479(define_insn "*movdi_internal"
4b983fdc 480 [(set (match_operand:DI 0 "destination_operand"
514f96e6 481 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b,*e, r,*d, r,*c")
4b983fdc 482 (match_operand:DI 1 "move_operand"
514f96e6 483 "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e,rO,rK,*d,rK,*c,rO"))]
75cdbeb8 484 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
9b7bf67d
RH
485 "*
486{
487 static const char * const alt[] = {
6f8aa100
RH
488 \"%,mov %0 = %r1\",
489 \"%,addl %0 = %1, r0\",
490 \"%,movl %0 = %1\",
491 \"%,ld8%O1 %0 = %1%P1\",
492 \"%,st8%Q0 %0 = %r1%P0\",
493 \"%,getf.sig %0 = %1\",
494 \"%,setf.sig %0 = %r1\",
495 \"%,mov %0 = %1\",
496 \"%,ldf8 %0 = %1%P1\",
497 \"%,stf8 %0 = %1%P0\",
498 \"%,mov %0 = %1\",
5527bf14
RH
499 \"%,mov %0 = %r1\",
500 \"%,mov %0 = %1\",
514f96e6
RH
501 \"%,mov %0 = %1\",
502 \"%,mov %0 = %1\",
97e242b0
RH
503 \"mov %0 = pr\",
504 \"mov pr = %1, -1\"
9b7bf67d
RH
505 };
506
9b7bf67d
RH
507 if (which_alternative == 2 && ! TARGET_NO_PIC
508 && symbolic_operand (operands[1], VOIDmode))
509 abort ();
510
511 return alt[which_alternative];
512}"
514f96e6 513 [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,I,M,M,I,I")])
c65ebc55 514
9b7bf67d
RH
515(define_split
516 [(set (match_operand:DI 0 "register_operand" "")
517 (match_operand:DI 1 "symbolic_operand" ""))]
518 "reload_completed && ! TARGET_NO_PIC"
519 [(const_int 0)]
520 "
521{
522 ia64_expand_load_address (operands[0], operands[1]);
523 DONE;
524}")
525
c65ebc55
JW
526(define_expand "load_fptr"
527 [(set (match_dup 2)
528 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))
ec039e3c 529 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
c65ebc55
JW
530 ""
531 "
532{
ec039e3c
RH
533 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
534 operands[3] = gen_rtx_MEM (DImode, operands[2]);
535 RTX_UNCHANGING_P (operands[3]) = 1;
c65ebc55
JW
536}")
537
538(define_insn "*load_fptr_internal1"
539 [(set (match_operand:DI 0 "register_operand" "=r")
540 (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "s")))]
541 ""
542 "addl %0 = @ltoff(@fptr(%1)), gp"
543 [(set_attr "type" "A")])
544
545(define_insn "load_gprel"
546 [(set (match_operand:DI 0 "register_operand" "=r")
547 (plus:DI (reg:DI 1) (match_operand:DI 1 "sdata_symbolic_operand" "s")))]
548 ""
549 "addl %0 = @gprel(%1), gp"
550 [(set_attr "type" "A")])
551
59da9a7d
JW
552(define_insn "gprel64_offset"
553 [(set (match_operand:DI 0 "register_operand" "=r")
554 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
555 ""
556 "movl %0 = @gprel(%1)"
557 [(set_attr "type" "L")])
558
559(define_expand "load_gprel64"
560 [(set (match_dup 2)
561 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))
562 (set (match_operand:DI 0 "register_operand" "")
563 (plus:DI (reg:DI 1) (match_dup 2)))]
564 ""
ec039e3c
RH
565 "
566{
567 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
59da9a7d
JW
568}")
569
c65ebc55
JW
570(define_expand "load_symptr"
571 [(set (match_dup 2)
ec039e3c 572 (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "")))
dee4095a 573 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
c65ebc55
JW
574 ""
575 "
576{
ec039e3c 577 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
dee4095a
RH
578 operands[3] = gen_rtx_MEM (DImode, operands[2]);
579 RTX_UNCHANGING_P (operands[3]) = 1;
c65ebc55
JW
580}")
581
582(define_insn "*load_symptr_internal1"
583 [(set (match_operand:DI 0 "register_operand" "=r")
ec039e3c 584 (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "s")))]
c65ebc55
JW
585 ""
586 "addl %0 = @ltoff(%1), gp"
587 [(set_attr "type" "A")])
588
3f622353
RH
589;; With no offsettable memory references, we've got to have a scratch
590;; around to play with the second word.
591(define_expand "movti"
592 [(parallel [(set (match_operand:TI 0 "general_operand" "")
593 (match_operand:TI 1 "general_operand" ""))
594 (clobber (match_scratch:DI 2 ""))])]
595 ""
596 "
597{
598 if (! reload_in_progress && ! reload_completed
599 && ! ia64_move_ok (operands[0], operands[1]))
600 operands[1] = force_reg (TImode, operands[1]);
601}")
602
603(define_insn_and_split "*movti_internal"
604 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
605 (match_operand:TI 1 "general_operand" "ri,m,r"))
606 (clobber (match_scratch:DI 2 "=X,&r,&r"))]
607 "ia64_move_ok (operands[0], operands[1])"
608 "#"
609 "reload_completed"
610 [(const_int 0)]
611 "
612{
613 rtx adj1, adj2, in[2], out[2];
614 int first;
615
616 adj1 = ia64_split_timode (in, operands[1], operands[2]);
617 adj2 = ia64_split_timode (out, operands[0], operands[2]);
618
619 first = 0;
620 if (reg_overlap_mentioned_p (out[0], in[1]))
621 {
622 if (reg_overlap_mentioned_p (out[1], in[0]))
623 abort ();
624 first = 1;
625 }
626
627 if (adj1 && adj2)
628 abort ();
629 if (adj1)
630 emit_insn (adj1);
631 if (adj2)
632 emit_insn (adj2);
633 emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
634 emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
635 DONE;
636}"
637 [(set_attr "type" "unknown")
638 (set_attr "predicable" "no")])
e314e331 639
3f622353
RH
640;; ??? SSA creates these. Can't allow memories since we don't have
641;; the scratch register. Fortunately combine will know how to add
642;; the clobber and scratch.
643(define_insn_and_split "*movti_internal_reg"
644 [(set (match_operand:TI 0 "register_operand" "=r")
645 (match_operand:TI 1 "nonmemory_operand" "ri"))]
646 ""
e314e331 647 "#"
3f622353
RH
648 "reload_completed"
649 [(const_int 0)]
650 "
651{
652 rtx in[2], out[2];
653 int first;
654
655 ia64_split_timode (in, operands[1], NULL_RTX);
656 ia64_split_timode (out, operands[0], NULL_RTX);
657
658 first = 0;
659 if (reg_overlap_mentioned_p (out[0], in[1]))
660 {
661 if (reg_overlap_mentioned_p (out[1], in[0]))
662 abort ();
663 first = 1;
664 }
665
666 emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
667 emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
668 DONE;
669}"
e314e331
JW
670 [(set_attr "type" "unknown")
671 (set_attr "predicable" "no")])
672
3f622353
RH
673(define_expand "reload_inti"
674 [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
675 (match_operand:TI 1 "" "m"))
60a3c181 676 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3f622353
RH
677 ""
678 "
679{
60a3c181
RH
680 unsigned int s_regno = REGNO (operands[2]);
681 if (s_regno == REGNO (operands[0]))
682 s_regno += 1;
683 operands[2] = gen_rtx_REG (DImode, s_regno);
3f622353
RH
684}")
685
686(define_expand "reload_outti"
687 [(parallel [(set (match_operand:TI 0 "" "=m")
688 (match_operand:TI 1 "register_operand" "r"))
60a3c181 689 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3f622353
RH
690 ""
691 "
692{
60a3c181
RH
693 unsigned int s_regno = REGNO (operands[2]);
694 if (s_regno == REGNO (operands[1]))
695 s_regno += 1;
696 operands[2] = gen_rtx_REG (DImode, s_regno);
3f622353 697}")
e314e331 698
c65ebc55
JW
699;; Floating Point Moves
700;;
701;; Note - Patterns for SF mode moves are compulsory, but
702;; patterns for DF are optional, as GCC can synthesise them.
703
704(define_expand "movsf"
705 [(set (match_operand:SF 0 "general_operand" "")
706 (match_operand:SF 1 "general_operand" ""))]
707 ""
708 "
709{
710 if (! reload_in_progress && ! reload_completed
557b9df5
RH
711 && ! ia64_move_ok (operands[0], operands[1]))
712 operands[1] = force_reg (SFmode, operands[1]);
c65ebc55
JW
713}")
714
75cdbeb8
RH
715;; Errata 72 workaround.
716(define_insn "*movsfcc_astep"
717 [(cond_exec
718 (match_operator 2 "predicate_operator"
719 [(match_operand:CC 3 "register_operand" "c,c,c,c")
720 (const_int 0)])
721 (set (match_operand:SF 0 "register_operand" "=f,*r, f,*r")
722 (match_operand:SF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
723 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
724 "@
3f622353
RH
725 (%J2) mov %0 = %F1
726 (%J2) getf.s %0 = %F1
727 (%J2) setf.s %0 = %1
728 (%J2) mov %0 = %1"
75cdbeb8
RH
729 [(set_attr "type" "F,M,M,A")
730 (set_attr "predicable" "no")])
731
732(define_insn "*movsf_internal_astep"
4b983fdc
RH
733 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
734 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
75cdbeb8
RH
735 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
736 "@
737 mov %0 = %F1
738 ldfs %0 = %1%P1
739 stfs %0 = %F1%P0
740 getf.s %0 = %F1
741 setf.s %0 = %1
742 mov %0 = %1
743 ld4%O1 %0 = %1%P1
744 st4%Q0 %0 = %1%P0"
745 [(set_attr "type" "F,M,M,M,M,A,M,M")
746 (set_attr "predicable" "no")])
747
c65ebc55 748(define_insn "*movsf_internal"
4b983fdc
RH
749 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
750 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
75cdbeb8 751 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55
JW
752 "@
753 mov %0 = %F1
754 ldfs %0 = %1%P1
755 stfs %0 = %F1%P0
756 getf.s %0 = %F1
757 setf.s %0 = %1
758 mov %0 = %1
13da91fd
RH
759 ld4%O1 %0 = %1%P1
760 st4%Q0 %0 = %1%P0"
761 [(set_attr "type" "F,M,M,M,M,A,M,M")])
c65ebc55
JW
762
763(define_expand "movdf"
764 [(set (match_operand:DF 0 "general_operand" "")
765 (match_operand:DF 1 "general_operand" ""))]
766 ""
767 "
768{
769 if (! reload_in_progress && ! reload_completed
557b9df5
RH
770 && ! ia64_move_ok (operands[0], operands[1]))
771 operands[1] = force_reg (DFmode, operands[1]);
c65ebc55
JW
772}")
773
75cdbeb8
RH
774;; Errata 72 workaround.
775(define_insn "*movdfcc_astep"
776 [(cond_exec
777 (match_operator 2 "predicate_operator"
778 [(match_operand:CC 3 "register_operand" "c,c,c,c")
779 (const_int 0)])
780 (set (match_operand:DF 0 "register_operand" "=f,*r, f,*r")
781 (match_operand:DF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
782 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
783 "@
3f622353
RH
784 (%J2) mov %0 = %F1
785 (%J2) getf.d %0 = %F1
786 (%J2) setf.d %0 = %1
787 (%J2) mov %0 = %1"
75cdbeb8
RH
788 [(set_attr "type" "F,M,M,A")
789 (set_attr "predicable" "no")])
790
791(define_insn "*movdf_internal_astep"
4b983fdc
RH
792 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
793 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
75cdbeb8
RH
794 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
795 "@
796 mov %0 = %F1
797 ldfd %0 = %1%P1
798 stfd %0 = %F1%P0
799 getf.d %0 = %F1
800 setf.d %0 = %1
801 mov %0 = %1
802 ld8%O1 %0 = %1%P1
803 st8%Q0 %0 = %1%P0"
804 [(set_attr "type" "F,M,M,M,M,A,M,M")
805 (set_attr "predicable" "no")])
806
c65ebc55 807(define_insn "*movdf_internal"
4b983fdc
RH
808 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
809 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
75cdbeb8 810 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
c65ebc55
JW
811 "@
812 mov %0 = %F1
813 ldfd %0 = %1%P1
814 stfd %0 = %F1%P0
815 getf.d %0 = %F1
816 setf.d %0 = %1
13da91fd
RH
817 mov %0 = %1
818 ld8%O1 %0 = %1%P1
819 st8%Q0 %0 = %1%P0"
820 [(set_attr "type" "F,M,M,M,M,A,M,M")])
c65ebc55 821
3f622353
RH
822;; With no offsettable memory references, we've got to have a scratch
823;; around to play with the second word if the variable winds up in GRs.
824(define_expand "movtf"
825 [(set (match_operand:TF 0 "general_operand" "")
826 (match_operand:TF 1 "general_operand" ""))]
e5bde68a
RH
827 ""
828 "
829{
3f622353
RH
830 /* We must support TFmode loads into general registers for stdarg/vararg
831 and unprototyped calls. We split them into DImode loads for convenience.
832 We don't need TFmode stores from general regs, because a stdarg/vararg
833 routine does a block store to memory of unnamed arguments. */
834 if (GET_CODE (operands[0]) == REG
835 && GR_REGNO_P (REGNO (operands[0])))
836 {
837 /* We're hoping to transform everything that deals with TFmode
838 quantities and GR registers early in the compiler. */
839 if (no_new_pseudos)
840 abort ();
841
842 /* Struct to register can just use TImode instead. */
843 if ((GET_CODE (operands[1]) == SUBREG
844 && GET_MODE (SUBREG_REG (operands[1])) == TImode)
845 || (GET_CODE (operands[1]) == REG
846 && GR_REGNO_P (REGNO (operands[1]))))
847 {
848 emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
849 SUBREG_REG (operands[1]));
850 DONE;
851 }
852
853 if (GET_CODE (operands[1]) == CONST_DOUBLE)
854 {
855 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
856 operand_subword (operands[1], 0, 0, DImode));
857 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
858 operand_subword (operands[1], 1, 0, DImode));
859 DONE;
860 }
861
862 /* If the quantity is in a register not known to be GR, spill it. */
863 if (register_operand (operands[1], TFmode))
864 operands[1] = spill_tfmode_operand (operands[1], 1);
865
866 if (GET_CODE (operands[1]) == MEM)
867 {
868 rtx out[2];
869
870 out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
871 out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
872
873 emit_move_insn (out[0], change_address (operands[1], DImode, NULL));
874 emit_move_insn (out[1],
875 change_address (operands[1], DImode,
876 plus_constant (XEXP (operands[1], 0),
877 8)));
878 DONE;
879 }
880
881 abort ();
882 }
883
884 if (! reload_in_progress && ! reload_completed)
885 {
886 operands[0] = spill_tfmode_operand (operands[0], 0);
887 operands[1] = spill_tfmode_operand (operands[1], 0);
888
889 if (! ia64_move_ok (operands[0], operands[1]))
890 operands[1] = force_reg (TFmode, operands[1]);
891 }
e5bde68a
RH
892}")
893
3b572406 894;; ??? There's no easy way to mind volatile acquire/release semantics.
75cdbeb8
RH
895
896;; Errata 72 workaround.
3f622353 897(define_insn "*movtfcc_astep"
75cdbeb8
RH
898 [(cond_exec
899 (match_operator 2 "predicate_operator"
900 [(match_operand:CC 3 "register_operand" "c")
901 (const_int 0)])
3f622353
RH
902 (set (match_operand:TF 0 "register_operand" "=f")
903 (match_operand:TF 1 "nonmemory_operand" "fG")))]
75cdbeb8 904 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
3f622353 905 "(%J2) mov %0 = %F1"
75cdbeb8
RH
906 [(set_attr "type" "F")
907 (set_attr "predicable" "no")])
908
3f622353
RH
909(define_insn "*movtf_internal_astep"
910 [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
911 (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
75cdbeb8
RH
912 "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
913 "@
914 mov %0 = %F1
915 ldfe %0 = %1%P1
916 stfe %0 = %F1%P0"
917 [(set_attr "type" "F,M,M")
918 (set_attr "predicable" "no")])
919
3f622353
RH
920(define_insn "*movtf_internal"
921 [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
922 (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
75cdbeb8 923 "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
e5bde68a
RH
924 "@
925 mov %0 = %F1
46b1ac3f
JW
926 ldfe %0 = %1%P1
927 stfe %0 = %F1%P0"
e5bde68a 928 [(set_attr "type" "F,M,M")])
c65ebc55
JW
929\f
930;; ::::::::::::::::::::
931;; ::
932;; :: Conversions
933;; ::
934;; ::::::::::::::::::::
935
936;; Signed conversions from a smaller integer to a larger integer
937
938(define_insn "extendqidi2"
0551c32d
RH
939 [(set (match_operand:DI 0 "gr_register_operand" "=r")
940 (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
c65ebc55
JW
941 ""
942 "sxt1 %0 = %1"
943 [(set_attr "type" "I")])
944
945(define_insn "extendhidi2"
0551c32d
RH
946 [(set (match_operand:DI 0 "gr_register_operand" "=r")
947 (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
c65ebc55
JW
948 ""
949 "sxt2 %0 = %1"
950 [(set_attr "type" "I")])
951
952(define_insn "extendsidi2"
0551c32d
RH
953 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
954 (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,*f")))]
c65ebc55
JW
955 ""
956 "@
957 sxt4 %0 = %1
958 fsxt.r %0 = %1, %1%B0"
959 [(set_attr "type" "I,F")])
960
961;; Unsigned conversions from a smaller integer to a larger integer
962
963(define_insn "zero_extendqidi2"
0551c32d
RH
964 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
965 (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
c65ebc55
JW
966 ""
967 "@
968 zxt1 %0 = %1
969 ld1%O1 %0 = %1%P1"
970 [(set_attr "type" "I,M")])
971
972(define_insn "zero_extendhidi2"
0551c32d
RH
973 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
974 (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
c65ebc55
JW
975 ""
976 "@
977 zxt2 %0 = %1
978 ld2%O1 %0 = %1%P1"
979 [(set_attr "type" "I,M")])
980
981(define_insn "zero_extendsidi2"
0551c32d
RH
982 [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,*f")
983 (zero_extend:DI
984 (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,*f")))]
c65ebc55
JW
985 ""
986 "@
987 zxt4 %0 = %1
988 ld4%O1 %0 = %1%P1
989 fsxt.r %0 = f1, %1%B0"
990 [(set_attr "type" "I,M,F")])
991
992;; Convert between floating point types of different sizes.
993
e8e20f18
RH
994;; ??? Optimization opportunity here. Get rid of the insn altogether
995;; when we can. Should probably use a scheme like has been proposed
996;; for ia32 in dealing with operands that match unary operators. This
997;; would let combine merge the thing into adjacent insns.
c65ebc55 998
e8e20f18 999(define_insn_and_split "extendsfdf2"
0551c32d
RH
1000 [(set (match_operand:DF 0 "fr_register_operand" "=f,f")
1001 (float_extend:DF (match_operand:SF 1 "fr_register_operand" "0,f")))]
c65ebc55 1002 ""
e8e20f18 1003 "mov %0 = %1"
50798048 1004 "reload_completed"
e8e20f18
RH
1005 [(set (match_dup 0) (float_extend:DF (match_dup 1)))]
1006 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1007 [(set_attr "type" "F")])
c65ebc55 1008
3f622353 1009(define_insn_and_split "extendsftf2"
0551c32d
RH
1010 [(set (match_operand:TF 0 "fr_register_operand" "=f,f")
1011 (float_extend:TF (match_operand:SF 1 "fr_register_operand" "0,f")))]
3f622353
RH
1012 ""
1013 "mov %0 = %1"
1014 "reload_completed"
1015 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1016 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1017 [(set_attr "type" "F")])
1018
1019(define_insn_and_split "extenddftf2"
0551c32d
RH
1020 [(set (match_operand:TF 0 "fr_register_operand" "=f,f")
1021 (float_extend:TF (match_operand:DF 1 "fr_register_operand" "0,f")))]
3f622353
RH
1022 ""
1023 "mov %0 = %1"
1024 "reload_completed"
1025 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1026 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1027 [(set_attr "type" "F")])
1028
c65ebc55 1029(define_insn "truncdfsf2"
0551c32d
RH
1030 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1031 (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1032 ""
1033 "fnorm.s %0 = %1%B0"
1034 [(set_attr "type" "F")])
1035
3f622353 1036(define_insn "trunctfsf2"
0551c32d
RH
1037 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1038 (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
e5bde68a
RH
1039 ""
1040 "fnorm.s %0 = %1%B0"
1041 [(set_attr "type" "F")])
c65ebc55 1042
3f622353 1043(define_insn "trunctfdf2"
0551c32d
RH
1044 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1045 (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
c65ebc55 1046 ""
e5bde68a
RH
1047 "fnorm.d %0 = %1%B0"
1048 [(set_attr "type" "F")])
1049
1050;; Convert between signed integer types and floating point.
1051
3f622353 1052(define_insn "floatditf2"
0551c32d
RH
1053 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1054 (float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
e5bde68a
RH
1055 ""
1056 "fcvt.xf %0 = %1"
1057 [(set_attr "type" "F")])
c65ebc55
JW
1058
1059(define_insn "fix_truncsfdi2"
0551c32d
RH
1060 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1061 (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1062 ""
1063 "fcvt.fx.trunc %0 = %1%B0"
1064 [(set_attr "type" "F")])
1065
1066(define_insn "fix_truncdfdi2"
0551c32d
RH
1067 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1068 (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1069 ""
1070 "fcvt.fx.trunc %0 = %1%B0"
1071 [(set_attr "type" "F")])
1072
3f622353 1073(define_insn "fix_trunctfdi2"
0551c32d
RH
1074 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1075 (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
3f622353
RH
1076 ""
1077 "fcvt.fx.trunc %0 = %1%B0"
1078 [(set_attr "type" "F")])
1079
c65ebc55
JW
1080;; Convert between unsigned integer types and floating point.
1081
1082(define_insn "floatunsdisf2"
0551c32d
RH
1083 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1084 (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
c65ebc55
JW
1085 ""
1086 "fcvt.xuf.s %0 = %1%B0"
1087 [(set_attr "type" "F")])
1088
1089(define_insn "floatunsdidf2"
0551c32d
RH
1090 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1091 (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
c65ebc55
JW
1092 ""
1093 "fcvt.xuf.d %0 = %1%B0"
1094 [(set_attr "type" "F")])
1095
3f622353 1096(define_insn "floatunsditf2"
0551c32d
RH
1097 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1098 (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
3f622353
RH
1099 ""
1100 "fcvt.xuf %0 = %1%B0"
1101 [(set_attr "type" "F")])
1102
c65ebc55 1103(define_insn "fixuns_truncsfdi2"
0551c32d
RH
1104 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1105 (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1106 ""
1107 "fcvt.fxu.trunc %0 = %1%B0"
1108 [(set_attr "type" "F")])
1109
1110(define_insn "fixuns_truncdfdi2"
0551c32d
RH
1111 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1112 (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1113 ""
1114 "fcvt.fxu.trunc %0 = %1%B0"
1115 [(set_attr "type" "F")])
1116
3f622353 1117(define_insn "fixuns_trunctfdi2"
0551c32d
RH
1118 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1119 (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
3f622353
RH
1120 ""
1121 "fcvt.fxu.trunc %0 = %1%B0"
1122 [(set_attr "type" "F")])
c65ebc55
JW
1123\f
1124;; ::::::::::::::::::::
1125;; ::
1126;; :: Bit field extraction
1127;; ::
1128;; ::::::::::::::::::::
1129
c65ebc55 1130(define_insn "extv"
0551c32d
RH
1131 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1132 (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
1133 (match_operand:DI 2 "const_int_operand" "n")
1134 (match_operand:DI 3 "const_int_operand" "n")))]
1135 ""
1136 "extr %0 = %1, %3, %2"
1137 [(set_attr "type" "I")])
1138
1139(define_insn "extzv"
0551c32d
RH
1140 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1141 (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
1142 (match_operand:DI 2 "const_int_operand" "n")
1143 (match_operand:DI 3 "const_int_operand" "n")))]
1144 ""
1145 "extr.u %0 = %1, %3, %2"
1146 [(set_attr "type" "I")])
1147
1148;; Insert a bit field.
1149;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1150;; Source1 can be 0 or -1.
1151;; Source2 can be 0.
1152
1153;; ??? Actual dep instruction is more powerful than what these insv
1154;; patterns support. Unfortunately, combine is unable to create patterns
1155;; where source2 != dest.
1156
1157(define_expand "insv"
0551c32d 1158 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1159 (match_operand:DI 1 "const_int_operand" "")
1160 (match_operand:DI 2 "const_int_operand" ""))
1161 (match_operand:DI 3 "nonmemory_operand" ""))]
1162 ""
1163 "
1164{
1165 int width = INTVAL (operands[1]);
1166 int shift = INTVAL (operands[2]);
1167
1168 /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1169 pseudo. */
1170 if (! register_operand (operands[3], DImode)
1171 && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1172 operands[3] = force_reg (DImode, operands[3]);
1173
1174 /* If this is a single dep instruction, we have nothing to do. */
1175 if (! ((register_operand (operands[3], DImode) && width <= 16)
1176 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1177 {
1178 /* Check for cases that can be implemented with a mix instruction. */
1179 if (width == 32 && shift == 0)
1180 {
1181 /* Directly generating the mix4left instruction confuses
1182 optimize_bit_field in function.c. Since this is performing
1183 a useful optimization, we defer generation of the complicated
1184 mix4left RTL to the first splitting phase. */
1185 rtx tmp = gen_reg_rtx (DImode);
1186 emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1187 DONE;
1188 }
1189 else if (width == 32 && shift == 32)
1190 {
1191 emit_insn (gen_mix4right (operands[0], operands[3]));
1192 DONE;
1193 }
1194
d2ba6dcf
JW
1195 /* We could handle remaining cases by emitting multiple dep
1196 instructions.
1197
1198 If we need more than two dep instructions then we lose. A 6
1199 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1200 mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles,
1201 the latter is 6 cycles on an Itanium (TM) processor, because there is
1202 only one function unit that can execute dep and shr immed.
1203
1204 If we only need two dep instruction, then we still lose.
1205 mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away
1206 the unnecessary mov, this is still undesirable because it will be
1207 hard to optimize, and it creates unnecessary pressure on the I0
1208 function unit. */
1209
c65ebc55
JW
1210 FAIL;
1211
1212#if 0
1213 /* This code may be useful for other IA-64 processors, so we leave it in
1214 for now. */
1215 while (width > 16)
1216 {
1217 rtx tmp;
1218
1219 emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1220 operands[3]));
1221 shift += 16;
1222 width -= 16;
1223 tmp = gen_reg_rtx (DImode);
1224 emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1225 operands[3] = tmp;
1226 }
1227 operands[1] = GEN_INT (width);
1228 operands[2] = GEN_INT (shift);
1229#endif
1230 }
1231}")
1232
1233(define_insn "*insv_internal"
0551c32d 1234 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55
JW
1235 (match_operand:DI 1 "const_int_operand" "n")
1236 (match_operand:DI 2 "const_int_operand" "n"))
1237 (match_operand:DI 3 "nonmemory_operand" "rP"))]
0551c32d 1238 "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
c65ebc55
JW
1239 || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1240 "dep %0 = %3, %0, %2, %1"
1241 [(set_attr "type" "I")])
1242
041f25e6
RH
1243;; Combine doesn't like to create bitfield insertions into zero.
1244(define_insn "*depz_internal"
0551c32d
RH
1245 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1246 (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
041f25e6
RH
1247 (match_operand:DI 2 "const_int_operand" "n"))
1248 (match_operand:DI 3 "const_int_operand" "n")))]
1249 "CONST_OK_FOR_M (INTVAL (operands[2]))
1250 && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1251 "*
1252{
1253 operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1254 return \"%,dep.z %0 = %1, %2, %3\";
1255}"
1256 [(set_attr "type" "I")])
1257
c65ebc55 1258(define_insn "shift_mix4left"
0551c32d 1259 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55 1260 (const_int 32) (const_int 0))
0551c32d
RH
1261 (match_operand:DI 1 "gr_register_operand" "r"))
1262 (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
c65ebc55
JW
1263 ""
1264 "#"
1265 [(set_attr "type" "unknown")])
1266
c65ebc55
JW
1267(define_split
1268 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1269 (const_int 32) (const_int 0))
1270 (match_operand:DI 1 "register_operand" ""))
1271 (clobber (match_operand:DI 2 "register_operand" ""))]
1272 "reload_completed"
1273 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1274 (unspec_volatile [(const_int 0)] 2)
1275 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1276 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1277 "operands[3] = operands[2];")
1278
1279(define_split
1280 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1281 (const_int 32) (const_int 0))
1282 (match_operand:DI 1 "register_operand" ""))
1283 (clobber (match_operand:DI 2 "register_operand" ""))]
1284 "! reload_completed"
1285 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1286 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1287 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1288 "operands[3] = operands[2];")
1289
1290(define_insn "*mix4left"
0551c32d 1291 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55 1292 (const_int 32) (const_int 0))
0551c32d 1293 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
1294 (const_int 32)))]
1295 ""
1296 "mix4.l %0 = %0, %r1"
1297 [(set_attr "type" "I")])
1298
1299(define_insn "mix4right"
0551c32d 1300 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55 1301 (const_int 32) (const_int 32))
0551c32d 1302 (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
c65ebc55
JW
1303 ""
1304 "mix4.r %0 = %r1, %0"
1305 [(set_attr "type" "I")])
1306
1307;; This is used by the rotrsi3 pattern.
1308
1309(define_insn "*mix4right_3op"
0551c32d
RH
1310 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1311 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1312 (ashift:DI (zero_extend:DI
1313 (match_operand:SI 2 "gr_register_operand" "r"))
c65ebc55
JW
1314 (const_int 32))))]
1315 ""
fa9a44e8 1316 "mix4.r %0 = %2, %1"
c65ebc55
JW
1317 [(set_attr "type" "I")])
1318
1319\f
1320;; ::::::::::::::::::::
cf1f6ae3
RH
1321;; ::
1322;; :: 16 bit Integer arithmetic
1323;; ::
1324;; ::::::::::::::::::::
1325
1326(define_insn "mulhi3"
1327 [(set (match_operand:HI 0 "gr_register_operand" "=r")
1328 (mult:HI (match_operand:HI 1 "gr_register_operand" "r")
1329 (match_operand:HI 2 "gr_register_operand" "r")))]
1330 ""
2a7ffc85 1331 "pmpy2.r %0 = %1, %2"
cf1f6ae3
RH
1332 [(set_attr "type" "I")])
1333
1334\f
1335;; ::::::::::::::::::::
c65ebc55
JW
1336;; ::
1337;; :: 32 bit Integer arithmetic
1338;; ::
1339;; ::::::::::::::::::::
1340
058557c4 1341(define_insn "addsi3"
0551c32d
RH
1342 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1343 (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1344 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
c65ebc55
JW
1345 ""
1346 "@
1347 add %0 = %1, %2
1348 adds %0 = %2, %1
1349 addl %0 = %2, %1"
1350 [(set_attr "type" "A")])
1351
1352(define_insn "*addsi3_plus1"
0551c32d
RH
1353 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1354 (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1355 (match_operand:SI 2 "gr_register_operand" "r"))
c65ebc55
JW
1356 (const_int 1)))]
1357 ""
1358 "add %0 = %1, %2, 1"
1359 [(set_attr "type" "A")])
1360
5527bf14 1361(define_insn "*addsi3_plus1_alt"
0551c32d
RH
1362 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1363 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
5527bf14
RH
1364 (const_int 2))
1365 (const_int 1)))]
1366 ""
1367 "add %0 = %1, %1, 1"
1368 [(set_attr "type" "A")])
1369
058557c4 1370(define_insn "*addsi3_shladd"
0551c32d
RH
1371 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1372 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
058557c4 1373 (match_operand:SI 2 "shladd_operand" "n"))
0551c32d 1374 (match_operand:SI 3 "gr_register_operand" "r")))]
c65ebc55 1375 ""
058557c4
RH
1376 "shladd %0 = %1, %S2, %3"
1377 [(set_attr "type" "A")])
c65ebc55 1378
058557c4 1379(define_insn "subsi3"
0551c32d
RH
1380 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1381 (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1382 (match_operand:SI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1383 ""
1384 "sub %0 = %1, %2"
1385 [(set_attr "type" "A")])
1386
1387(define_insn "*subsi3_minus1"
0551c32d
RH
1388 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1389 (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1390 (match_operand:SI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1391 ""
1392 "sub %0 = %2, %1, 1"
1393 [(set_attr "type" "A")])
1394
058557c4 1395(define_insn "mulsi3"
0551c32d 1396 [(set (match_operand:SI 0 "fr_register_operand" "=f")
11a13704
RH
1397 (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1398 (match_operand:SI 2 "grfr_register_operand" "f")))]
c65ebc55
JW
1399 ""
1400 "xma.l %0 = %1, %2, f0%B0"
1401 [(set_attr "type" "F")])
1402
11a13704
RH
1403(define_insn "*maddsi3"
1404 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1405 (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1406 (match_operand:SI 2 "grfr_register_operand" "f"))
1407 (match_operand:SI 3 "grfr_register_operand" "f")))]
1408 ""
1409 "xma.l %0 = %1, %2, %3%B0"
1410 [(set_attr "type" "F")])
1411
058557c4 1412(define_insn "negsi2"
0551c32d
RH
1413 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1414 (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
c65ebc55
JW
1415 ""
1416 "sub %0 = r0, %1"
1417 [(set_attr "type" "A")])
1418
1419(define_expand "abssi2"
1420 [(set (match_dup 2)
0551c32d
RH
1421 (ge:CC (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
1422 (set (match_operand:SI 0 "gr_register_operand" "")
e5bde68a
RH
1423 (if_then_else:SI (eq:CC (match_dup 2) (const_int 0))
1424 (neg:SI (match_dup 1))
1425 (match_dup 1)))]
c65ebc55
JW
1426 ""
1427 "
1428{
1429 operands[2] = gen_reg_rtx (CCmode);
1430}")
1431
1432(define_expand "sminsi3"
1433 [(set (match_dup 3)
0551c32d
RH
1434 (ge:CC (match_operand:SI 1 "gr_register_operand" "")
1435 (match_operand:SI 2 "gr_register_operand" "")))
1436 (set (match_operand:SI 0 "gr_register_operand" "")
c65ebc55
JW
1437 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1438 (match_dup 2) (match_dup 1)))]
1439 ""
1440 "
1441{
1442 operands[3] = gen_reg_rtx (CCmode);
1443}")
1444
1445(define_expand "smaxsi3"
1446 [(set (match_dup 3)
0551c32d
RH
1447 (ge:CC (match_operand:SI 1 "gr_register_operand" "")
1448 (match_operand:SI 2 "gr_register_operand" "")))
1449 (set (match_operand:SI 0 "gr_register_operand" "")
c65ebc55
JW
1450 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1451 (match_dup 1) (match_dup 2)))]
1452 ""
1453 "
1454{
1455 operands[3] = gen_reg_rtx (CCmode);
1456}")
1457
1458(define_expand "uminsi3"
1459 [(set (match_dup 3)
0551c32d
RH
1460 (geu:CC (match_operand:SI 1 "gr_register_operand" "")
1461 (match_operand:SI 2 "gr_register_operand" "")))
1462 (set (match_operand:SI 0 "gr_register_operand" "")
c65ebc55
JW
1463 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1464 (match_dup 2) (match_dup 1)))]
1465 ""
1466 "
1467{
1468 operands[3] = gen_reg_rtx (CCmode);
1469}")
1470
1471(define_expand "umaxsi3"
1472 [(set (match_dup 3)
0551c32d
RH
1473 (geu:CC (match_operand:SI 1 "gr_register_operand" "")
1474 (match_operand:SI 2 "gr_register_operand" "")))
1475 (set (match_operand:SI 0 "gr_register_operand" "")
c65ebc55
JW
1476 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1477 (match_dup 1) (match_dup 2)))]
1478 ""
1479 "
1480{
1481 operands[3] = gen_reg_rtx (CCmode);
1482}")
1483
1484\f
1485;; ::::::::::::::::::::
1486;; ::
1487;; :: 64 bit Integer arithmetic
1488;; ::
1489;; ::::::::::::::::::::
1490
1491(define_insn "adddi3"
0551c32d
RH
1492 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
1493 (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
1494 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
c65ebc55
JW
1495 ""
1496 "@
1497 add %0 = %1, %2
1498 adds %0 = %2, %1
1499 addl %0 = %2, %1"
1500 [(set_attr "type" "A")])
1501
1502(define_insn "*adddi3_plus1"
0551c32d
RH
1503 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1504 (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
1505 (match_operand:DI 2 "gr_register_operand" "r"))
c65ebc55
JW
1506 (const_int 1)))]
1507 ""
1508 "add %0 = %1, %2, 1"
1509 [(set_attr "type" "A")])
1510
5527bf14
RH
1511;; This has some of the same problems as shladd. We let the shladd
1512;; eliminator hack handle it, which results in the 1 being forced into
1513;; a register, but not more ugliness here.
1514(define_insn "*adddi3_plus1_alt"
0551c32d
RH
1515 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1516 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
5527bf14
RH
1517 (const_int 2))
1518 (const_int 1)))]
1519 ""
1520 "add %0 = %1, %1, 1"
1521 [(set_attr "type" "A")])
1522
c65ebc55 1523(define_insn "subdi3"
0551c32d
RH
1524 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1525 (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
1526 (match_operand:DI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1527 ""
1528 "sub %0 = %1, %2"
1529 [(set_attr "type" "A")])
1530
1531(define_insn "*subdi3_minus1"
0551c32d
RH
1532 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1533 (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
1534 (match_operand:DI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1535 ""
1536 "sub %0 = %2, %1, 1"
1537 [(set_attr "type" "A")])
1538
cee58bc0
RH
1539;; ??? Use grfr instead of fr because of virtual register elimination
1540;; and silly test cases multiplying by the frame pointer.
c65ebc55 1541(define_insn "muldi3"
0551c32d 1542 [(set (match_operand:DI 0 "fr_register_operand" "=f")
cee58bc0
RH
1543 (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
1544 (match_operand:DI 2 "grfr_register_operand" "f")))]
c65ebc55
JW
1545 ""
1546 "xma.l %0 = %1, %2, f0%B0"
1547 [(set_attr "type" "F")])
1548
1549;; ??? If operand 3 is an eliminable reg, then register elimination causes the
1550;; same problem that we have with shladd below. Unfortunately, this case is
1551;; much harder to fix because the multiply puts the result in an FP register,
1552;; but the add needs inputs from a general register. We add a spurious clobber
1553;; here so that it will be present just in case register elimination gives us
1554;; the funny result.
1555
1556;; ??? Maybe validate_changes should try adding match_scratch clobbers?
1557
1558;; ??? Maybe we should change how adds are canonicalized.
1559
1560(define_insn "*madddi3"
0551c32d 1561 [(set (match_operand:DI 0 "fr_register_operand" "=f")
11a13704
RH
1562 (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
1563 (match_operand:DI 2 "grfr_register_operand" "f"))
1564 (match_operand:DI 3 "grfr_register_operand" "f")))
c65ebc55
JW
1565 (clobber (match_scratch:DI 4 "=X"))]
1566 ""
1567 "xma.l %0 = %1, %2, %3%B0"
1568 [(set_attr "type" "F")])
1569
1570;; This can be created by register elimination if operand3 of shladd is an
1571;; eliminable register or has reg_equiv_constant set.
1572
1573;; We have to use nonmemory_operand for operand 4, to ensure that the
1574;; validate_changes call inside eliminate_regs will always succeed. If it
1575;; doesn't succeed, then this remain a madddi3 pattern, and will be reloaded
1576;; incorrectly.
1577
1578(define_insn "*madddi3_elim"
1579 [(set (match_operand:DI 0 "register_operand" "=&r")
13da91fd
RH
1580 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
1581 (match_operand:DI 2 "register_operand" "f"))
1582 (match_operand:DI 3 "register_operand" "f"))
c65ebc55 1583 (match_operand:DI 4 "nonmemory_operand" "rI")))
13da91fd 1584 (clobber (match_scratch:DI 5 "=f"))]
c65ebc55
JW
1585 "reload_in_progress"
1586 "#"
1587 [(set_attr "type" "unknown")])
1588
1589;; ??? Need to emit an instruction group barrier here because this gets split
1590;; after md_reorg.
1591
1592(define_split
1593 [(set (match_operand:DI 0 "register_operand" "")
1594 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
1595 (match_operand:DI 2 "register_operand" ""))
1596 (match_operand:DI 3 "register_operand" ""))
0551c32d 1597 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
c65ebc55
JW
1598 (clobber (match_scratch:DI 5 ""))]
1599 "reload_completed"
1600 [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
1601 (match_dup 3)))
1602 (clobber (match_dup 0))])
1603 (unspec_volatile [(const_int 0)] 2)
1604 (set (match_dup 0) (match_dup 5))
1605 (unspec_volatile [(const_int 0)] 2)
1606 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
1607 "")
1608
1609;; ??? There are highpart multiply and add instructions, but we have no way
1610;; to generate them.
1611
1612(define_insn "smuldi3_highpart"
0551c32d 1613 [(set (match_operand:DI 0 "fr_register_operand" "=f")
c65ebc55
JW
1614 (truncate:DI
1615 (lshiftrt:TI
0551c32d
RH
1616 (mult:TI (sign_extend:TI
1617 (match_operand:DI 1 "fr_register_operand" "f"))
1618 (sign_extend:TI
1619 (match_operand:DI 2 "fr_register_operand" "f")))
c65ebc55
JW
1620 (const_int 64))))]
1621 ""
1622 "xma.h %0 = %1, %2, f0%B0"
1623 [(set_attr "type" "F")])
1624
1625(define_insn "umuldi3_highpart"
0551c32d 1626 [(set (match_operand:DI 0 "fr_register_operand" "=f")
c65ebc55
JW
1627 (truncate:DI
1628 (lshiftrt:TI
0551c32d
RH
1629 (mult:TI (zero_extend:TI
1630 (match_operand:DI 1 "fr_register_operand" "f"))
1631 (zero_extend:TI
1632 (match_operand:DI 2 "fr_register_operand" "f")))
c65ebc55
JW
1633 (const_int 64))))]
1634 ""
1635 "xma.hu %0 = %1, %2, f0%B0"
1636 [(set_attr "type" "F")])
1637
1638(define_insn "negdi2"
0551c32d
RH
1639 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1640 (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
c65ebc55
JW
1641 ""
1642 "sub %0 = r0, %1"
1643 [(set_attr "type" "A")])
1644
1645(define_expand "absdi2"
1646 [(set (match_dup 2)
0551c32d
RH
1647 (ge:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
1648 (set (match_operand:DI 0 "gr_register_operand" "")
e5bde68a
RH
1649 (if_then_else:DI (eq:CC (match_dup 2) (const_int 0))
1650 (neg:DI (match_dup 1))
1651 (match_dup 1)))]
c65ebc55
JW
1652 ""
1653 "
1654{
1655 operands[2] = gen_reg_rtx (CCmode);
1656}")
1657
1658(define_expand "smindi3"
1659 [(set (match_dup 3)
0551c32d
RH
1660 (ge:CC (match_operand:DI 1 "gr_register_operand" "")
1661 (match_operand:DI 2 "gr_register_operand" "")))
1662 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1663 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1664 (match_dup 2) (match_dup 1)))]
1665 ""
1666 "
1667{
1668 operands[3] = gen_reg_rtx (CCmode);
1669}")
1670
1671(define_expand "smaxdi3"
1672 [(set (match_dup 3)
0551c32d
RH
1673 (ge:CC (match_operand:DI 1 "gr_register_operand" "")
1674 (match_operand:DI 2 "gr_register_operand" "")))
1675 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1676 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1677 (match_dup 1) (match_dup 2)))]
1678 ""
1679 "
1680{
1681 operands[3] = gen_reg_rtx (CCmode);
1682}")
1683
1684(define_expand "umindi3"
1685 [(set (match_dup 3)
0551c32d
RH
1686 (geu:CC (match_operand:DI 1 "gr_register_operand" "")
1687 (match_operand:DI 2 "gr_register_operand" "")))
1688 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1689 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1690 (match_dup 2) (match_dup 1)))]
1691 ""
1692 "
1693{
1694 operands[3] = gen_reg_rtx (CCmode);
1695}")
1696
1697(define_expand "umaxdi3"
1698 [(set (match_dup 3)
0551c32d
RH
1699 (geu:CC (match_operand:DI 1 "gr_register_operand" "")
1700 (match_operand:DI 2 "gr_register_operand" "")))
1701 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1702 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1703 (match_dup 1) (match_dup 2)))]
1704 ""
1705 "
1706{
1707 operands[3] = gen_reg_rtx (CCmode);
1708}")
1709
1710(define_expand "ffsdi2"
1711 [(set (match_dup 6)
0551c32d 1712 (eq:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
c65ebc55
JW
1713 (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
1714 (set (match_dup 5) (const_int 0))
1715 (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
1716 (set (match_dup 4) (unspec:DI [(match_dup 3)] 8))
0551c32d 1717 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1718 (if_then_else:DI (ne:CC (match_dup 6) (const_int 0))
1719 (match_dup 5) (match_dup 4)))]
1720 ""
1721 "
1722{
1723 operands[2] = gen_reg_rtx (DImode);
1724 operands[3] = gen_reg_rtx (DImode);
1725 operands[4] = gen_reg_rtx (DImode);
1726 operands[5] = gen_reg_rtx (DImode);
1727 operands[6] = gen_reg_rtx (CCmode);
1728}")
1729
1730(define_insn "*popcnt"
0551c32d
RH
1731 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1732 (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")] 8))]
c65ebc55
JW
1733 ""
1734 "popcnt %0 = %1"
1735 [(set_attr "type" "I")])
1736
1737\f
1738;; ::::::::::::::::::::
1739;; ::
1740;; :: 32 bit floating point arithmetic
1741;; ::
1742;; ::::::::::::::::::::
1743
1744(define_insn "addsf3"
0551c32d
RH
1745 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1746 (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
1747 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1748 ""
1749 "fadd.s %0 = %1, %F2%B0"
1750 [(set_attr "type" "F")])
1751
1752(define_insn "subsf3"
0551c32d
RH
1753 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1754 (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
1755 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1756 ""
1757 "fsub.s %0 = %F1, %F2%B0"
1758 [(set_attr "type" "F")])
1759
1760(define_insn "mulsf3"
0551c32d
RH
1761 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1762 (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
1763 (match_operand:SF 2 "fr_register_operand" "f")))]
c65ebc55
JW
1764 ""
1765 "fmpy.s %0 = %1, %2%B0"
1766 [(set_attr "type" "F")])
1767
1768(define_insn "abssf2"
0551c32d
RH
1769 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1770 (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1771 ""
1772 "fabs %0 = %1%B0"
1773 [(set_attr "type" "F")])
1774
1775(define_insn "negsf2"
0551c32d
RH
1776 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1777 (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1778 ""
1779 "fneg %0 = %1%B0"
1780 [(set_attr "type" "F")])
1781
1782(define_insn "*nabssf2"
0551c32d
RH
1783 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1784 (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
c65ebc55
JW
1785 ""
1786 "fnegabs %0 = %1%B0"
1787 [(set_attr "type" "F")])
1788
1789(define_insn "minsf3"
0551c32d
RH
1790 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1791 (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
1792 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1793 ""
1794 "fmin %0 = %1, %F2%B0"
1795 [(set_attr "type" "F")])
1796
1797(define_insn "maxsf3"
0551c32d
RH
1798 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1799 (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
1800 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1801 ""
1802 "fmax %0 = %1, %F2%B0"
1803 [(set_attr "type" "F")])
1804
1805(define_insn "*maddsf3"
0551c32d
RH
1806 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1807 (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1808 (match_operand:SF 2 "fr_register_operand" "f"))
1809 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1810 ""
1811 "fma.s %0 = %1, %2, %F3%B0"
1812 [(set_attr "type" "F")])
1813
1814(define_insn "*msubsf3"
0551c32d
RH
1815 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1816 (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1817 (match_operand:SF 2 "fr_register_operand" "f"))
1818 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1819 ""
1820 "fms.s %0 = %1, %2, %F3%B0"
1821 [(set_attr "type" "F")])
1822
1823(define_insn "*nmulsf3"
0551c32d
RH
1824 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1825 (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1826 (match_operand:SF 2 "fr_register_operand" "f"))))]
c65ebc55
JW
1827 ""
1828 "fnmpy.s %0 = %1, %2%B0"
1829 [(set_attr "type" "F")])
1830
1831;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
1832
1833(define_insn "*nmaddsf3"
0551c32d
RH
1834 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1835 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1836 (match_operand:SF 2 "fr_register_operand" "f")))
1837 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1838 ""
1839 "fnma.s %0 = %1, %2, %F3%B0"
1840 [(set_attr "type" "F")])
1841
1842\f
1843;; ::::::::::::::::::::
1844;; ::
1845;; :: 64 bit floating point arithmetic
1846;; ::
1847;; ::::::::::::::::::::
1848
1849(define_insn "adddf3"
0551c32d
RH
1850 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1851 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
1852 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1853 ""
1854 "fadd.d %0 = %1, %F2%B0"
1855 [(set_attr "type" "F")])
1856
1857(define_insn "subdf3"
0551c32d
RH
1858 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1859 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
1860 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1861 ""
1862 "fsub.d %0 = %F1, %F2%B0"
1863 [(set_attr "type" "F")])
1864
1865(define_insn "muldf3"
0551c32d
RH
1866 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1867 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1868 (match_operand:DF 2 "fr_register_operand" "f")))]
c65ebc55
JW
1869 ""
1870 "fmpy.d %0 = %1, %2%B0"
1871 [(set_attr "type" "F")])
1872
1873(define_insn "absdf2"
0551c32d
RH
1874 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1875 (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1876 ""
1877 "fabs %0 = %1%B0"
1878 [(set_attr "type" "F")])
1879
1880(define_insn "negdf2"
0551c32d
RH
1881 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1882 (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1883 ""
1884 "fneg %0 = %1%B0"
1885 [(set_attr "type" "F")])
1886
1887(define_insn "*nabsdf2"
0551c32d
RH
1888 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1889 (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
c65ebc55
JW
1890 ""
1891 "fnegabs %0 = %1%B0"
1892 [(set_attr "type" "F")])
1893
1894(define_insn "mindf3"
0551c32d
RH
1895 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1896 (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
1897 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1898 ""
1899 "fmin %0 = %1, %F2%B0"
1900 [(set_attr "type" "F")])
1901
1902(define_insn "maxdf3"
0551c32d
RH
1903 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1904 (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
1905 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1906 ""
1907 "fmax %0 = %1, %F2%B0"
1908 [(set_attr "type" "F")])
1909
1910(define_insn "*madddf3"
0551c32d
RH
1911 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1912 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1913 (match_operand:DF 2 "fr_register_operand" "f"))
1914 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1915 ""
1916 "fma.d %0 = %1, %2, %F3%B0"
1917 [(set_attr "type" "F")])
1918
1919(define_insn "*msubdf3"
0551c32d
RH
1920 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1921 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1922 (match_operand:DF 2 "fr_register_operand" "f"))
1923 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1924 ""
1925 "fms.d %0 = %1, %2, %F3%B0"
1926 [(set_attr "type" "F")])
1927
1928(define_insn "*nmuldf3"
0551c32d
RH
1929 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1930 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1931 (match_operand:DF 2 "fr_register_operand" "f"))))]
c65ebc55
JW
1932 ""
1933 "fnmpy.d %0 = %1, %2%B0"
1934 [(set_attr "type" "F")])
1935
1936;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
1937
1938(define_insn "*nmadddf3"
0551c32d
RH
1939 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1940 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1941 (match_operand:DF 2 "fr_register_operand" "f")))
1942 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1943 ""
1944 "fnma.d %0 = %1, %2, %F3%B0"
1945 [(set_attr "type" "F")])
3f622353
RH
1946\f
1947;; ::::::::::::::::::::
1948;; ::
1949;; :: 80 bit floating point arithmetic
1950;; ::
1951;; ::::::::::::::::::::
1952
1953(define_insn "addtf3"
0551c32d 1954 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1955 (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1956 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1957 ""
1958 "fadd %0 = %F1, %F2%B0"
1959 [(set_attr "type" "F")])
1960
1961(define_insn "subtf3"
0551c32d 1962 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1963 (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1964 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1965 ""
1966 "fsub %0 = %F1, %F2%B0"
1967 [(set_attr "type" "F")])
1968
1969(define_insn "multf3"
0551c32d 1970 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1971 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1972 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1973 ""
1974 "fmpy %0 = %F1, %F2%B0"
1975 [(set_attr "type" "F")])
1976
1977(define_insn "abstf2"
0551c32d 1978 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1979 (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
1980 ""
1981 "fabs %0 = %F1%B0"
1982 [(set_attr "type" "F")])
1983
1984(define_insn "negtf2"
0551c32d 1985 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1986 (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
1987 ""
1988 "fneg %0 = %F1%B0"
1989 [(set_attr "type" "F")])
1990
1991(define_insn "*nabstf2"
0551c32d 1992 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1993 (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
1994 ""
1995 "fnegabs %0 = %F1%B0"
1996 [(set_attr "type" "F")])
1997
1998(define_insn "mintf3"
0551c32d 1999 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
2000 (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2001 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
2002 ""
2003 "fmin %0 = %F1, %F2%B0"
2004 [(set_attr "type" "F")])
2005
2006(define_insn "maxtf3"
0551c32d 2007 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
2008 (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2009 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
2010 ""
2011 "fmax %0 = %F1, %F2%B0"
2012 [(set_attr "type" "F")])
2013
2014(define_insn "*maddtf3"
0551c32d 2015 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
2016 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2017 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
2018 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2019 ""
2020 "fma %0 = %F1, %F2, %F3%B0"
2021 [(set_attr "type" "F")])
2022
2023(define_insn "*msubtf3"
0551c32d 2024 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
2025 (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2026 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
2027 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2028 ""
2029 "fms %0 = %F1, %F2, %F3%B0"
2030 [(set_attr "type" "F")])
2031
2032(define_insn "*nmultf3"
0551c32d 2033 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
2034 (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2035 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
2036 ""
2037 "fnmpy %0 = %F1, %F2%B0"
2038 [(set_attr "type" "F")])
c65ebc55 2039
3f622353
RH
2040;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2041
2042(define_insn "*nmaddtf3"
0551c32d 2043 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
2044 (plus:TF (neg:TF (mult:TF
2045 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2046 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
2047 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2048 ""
2049 "fnma %0 = %F1, %F2, %F3%B0"
2050 [(set_attr "type" "F")])
c65ebc55
JW
2051\f
2052;; ::::::::::::::::::::
2053;; ::
2054;; :: 32 bit Integer Shifts and Rotates
2055;; ::
2056;; ::::::::::::::::::::
2057
9c668921 2058(define_expand "ashlsi3"
0551c32d
RH
2059 [(set (match_operand:SI 0 "gr_register_operand" "")
2060 (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
2061 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
9c668921
RH
2062 ""
2063 "
2064{
2065 if (GET_CODE (operands[2]) != CONST_INT)
2066 {
2067 /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now
2068 we've got to get rid of stray bits outside the SImode register. */
2069 rtx subshift = gen_reg_rtx (DImode);
2070 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2071 operands[2] = subshift;
2072 }
2073}")
2074
2075(define_insn "*ashlsi3_internal"
0551c32d
RH
2076 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
2077 (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
2078 (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
c65ebc55 2079 ""
041f25e6
RH
2080 "@
2081 shladd %0 = %1, %2, r0
2082 dep.z %0 = %1, %2, %E2
2083 shl %0 = %1, %2"
2084 [(set_attr "type" "A,I,I")])
c65ebc55
JW
2085
2086(define_expand "ashrsi3"
0551c32d
RH
2087 [(set (match_operand:SI 0 "gr_register_operand" "")
2088 (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
2089 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
c65ebc55
JW
2090 ""
2091 "
2092{
041f25e6
RH
2093 rtx subtarget = gen_reg_rtx (DImode);
2094 if (GET_CODE (operands[2]) == CONST_INT)
2095 emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
2096 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
2097 else
2098 {
9c668921 2099 rtx subshift = gen_reg_rtx (DImode);
041f25e6 2100 emit_insn (gen_extendsidi2 (subtarget, operands[1]));
9c668921
RH
2101 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2102 emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
041f25e6
RH
2103 }
2104 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
2105 DONE;
c65ebc55
JW
2106}")
2107
c65ebc55 2108(define_expand "lshrsi3"
0551c32d
RH
2109 [(set (match_operand:SI 0 "gr_register_operand" "")
2110 (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
2111 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
c65ebc55
JW
2112 ""
2113 "
2114{
041f25e6
RH
2115 rtx subtarget = gen_reg_rtx (DImode);
2116 if (GET_CODE (operands[2]) == CONST_INT)
2117 emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
2118 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
2119 else
2120 {
9c668921 2121 rtx subshift = gen_reg_rtx (DImode);
041f25e6 2122 emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
9c668921
RH
2123 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2124 emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
041f25e6
RH
2125 }
2126 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
2127 DONE;
c65ebc55
JW
2128}")
2129
c65ebc55
JW
2130;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
2131;; here, instead of 64 like the patterns above.
2132
2133(define_expand "rotrsi3"
2134 [(set (match_dup 3)
0551c32d 2135 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" ""))
c65ebc55
JW
2136 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
2137 (set (match_dup 3)
2138 (lshiftrt:DI (match_dup 3)
2139 (match_operand:DI 2 "nonmemory_operand" "")))
0551c32d 2140 (set (match_operand:SI 0 "gr_register_operand" "") (match_dup 4))]
c65ebc55
JW
2141 ""
2142 "
2143{
2144 if (! shift_32bit_count_operand (operands[2], SImode))
2145 FAIL;
c65ebc55
JW
2146 operands[3] = gen_reg_rtx (DImode);
2147 operands[4] = gen_lowpart (SImode, operands[3]);
2148}")
c65ebc55
JW
2149\f
2150;; ::::::::::::::::::::
2151;; ::
2152;; :: 64 bit Integer Shifts and Rotates
2153;; ::
2154;; ::::::::::::::::::::
2155
2156(define_insn "ashldi3"
0551c32d
RH
2157 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
2158 (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r")
2159 (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,rM")))]
c65ebc55 2160 ""
041f25e6
RH
2161 "@
2162 shladd %0 = %1, %2, r0
2163 shl %0 = %1, %2"
2164 [(set_attr "type" "A,I")])
c65ebc55
JW
2165
2166;; ??? Maybe combine this with the multiply and add instruction?
2167
2168(define_insn "*shladd"
0551c32d
RH
2169 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2170 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55 2171 (match_operand:DI 2 "shladd_operand" "n"))
0551c32d 2172 (match_operand:DI 3 "gr_register_operand" "r")))]
c65ebc55
JW
2173 ""
2174 "shladd %0 = %1, %S2, %3"
2175 [(set_attr "type" "A")])
2176
2177;; This can be created by register elimination if operand3 of shladd is an
2178;; eliminable register or has reg_equiv_constant set.
2179
2180;; We have to use nonmemory_operand for operand 4, to ensure that the
2181;; validate_changes call inside eliminate_regs will always succeed. If it
2182;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
2183;; incorrectly.
2184
5527bf14 2185(define_insn_and_split "*shladd_elim"
0551c32d
RH
2186 [(set (match_operand:DI 0 "gr_register_operand" "=&r")
2187 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55 2188 (match_operand:DI 2 "shladd_operand" "n"))
5527bf14 2189 (match_operand:DI 3 "nonmemory_operand" "r"))
c65ebc55
JW
2190 (match_operand:DI 4 "nonmemory_operand" "rI")))]
2191 "reload_in_progress"
5527bf14 2192 "* abort ();"
c65ebc55
JW
2193 "reload_completed"
2194 [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2195 (match_dup 3)))
c65ebc55 2196 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
5527bf14
RH
2197 ""
2198 [(set_attr "type" "unknown")])
c65ebc55
JW
2199
2200(define_insn "ashrdi3"
0551c32d
RH
2201 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2202 (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
2203 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
c65ebc55
JW
2204 ""
2205 "shr %0 = %1, %2"
2206 [(set_attr "type" "I")])
2207
2208(define_insn "lshrdi3"
0551c32d
RH
2209 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2210 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
2211 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
c65ebc55
JW
2212 ""
2213 "shr.u %0 = %1, %2"
2214 [(set_attr "type" "I")])
2215
2216;; Using a predicate that accepts only constants doesn't work, because optabs
2217;; will load the operand into a register and call the pattern if the predicate
2218;; did not accept it on the first try. So we use nonmemory_operand and then
2219;; verify that we have an appropriate constant in the expander.
2220
2221(define_expand "rotrdi3"
0551c32d
RH
2222 [(set (match_operand:DI 0 "gr_register_operand" "")
2223 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
c65ebc55
JW
2224 (match_operand:DI 2 "nonmemory_operand" "")))]
2225 ""
2226 "
2227{
2228 if (! shift_count_operand (operands[2], DImode))
2229 FAIL;
2230}")
2231
2232(define_insn "*rotrdi3_internal"
0551c32d
RH
2233 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2234 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
2235 (match_operand:DI 2 "shift_count_operand" "M")))]
2236 ""
2237 "shrp %0 = %1, %1, %2"
2238 [(set_attr "type" "I")])
2239
2240\f
2241;; ::::::::::::::::::::
2242;; ::
058557c4 2243;; :: 32 bit Integer Logical operations
c65ebc55
JW
2244;; ::
2245;; ::::::::::::::::::::
2246
2247;; We don't seem to need any other 32-bit logical operations, because gcc
2248;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
2249;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
2250;; This doesn't work for unary logical operations, because we don't call
2251;; apply_distributive_law for them.
2252
2253;; ??? Likewise, this doesn't work for andnot, which isn't handled by
2254;; apply_distributive_law. We get inefficient code for
2255;; int sub4 (int i, int j) { return i & ~j; }
2256;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
2257;; (zero_extend (and (not A) B)) in combine.
2258;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
2259;; one_cmplsi2 pattern.
2260
058557c4 2261(define_insn "one_cmplsi2"
0551c32d
RH
2262 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2263 (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
c65ebc55
JW
2264 ""
2265 "andcm %0 = -1, %1"
2266 [(set_attr "type" "A")])
c65ebc55
JW
2267\f
2268;; ::::::::::::::::::::
2269;; ::
058557c4 2270;; :: 64 bit Integer Logical operations
c65ebc55
JW
2271;; ::
2272;; ::::::::::::::::::::
2273
2274(define_insn "anddi3"
0551c32d
RH
2275 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2276 (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2277 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
2278 ""
2279 "@
2280 and %0 = %2, %1
2281 fand %0 = %2, %1%B0"
2282 [(set_attr "type" "A,F")])
2283
2284(define_insn "*andnot"
0551c32d
RH
2285 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2286 (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
2287 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
2288 ""
2289 "@
2290 andcm %0 = %2, %1
2291 fandcm %0 = %2, %1%B0"
2292 [(set_attr "type" "A,F")])
2293
2294(define_insn "iordi3"
0551c32d
RH
2295 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2296 (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2297 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
2298 ""
2299 "@
2300 or %0 = %2, %1
2301 for %0 = %2, %1%B0"
2302 [(set_attr "type" "A,F")])
2303
2304(define_insn "xordi3"
0551c32d
RH
2305 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2306 (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2307 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
2308 ""
2309 "@
2310 xor %0 = %2, %1
2311 fxor %0 = %2, %1%B0"
2312 [(set_attr "type" "A,F")])
2313
2314(define_insn "one_cmpldi2"
0551c32d
RH
2315 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2316 (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
c65ebc55
JW
2317 ""
2318 "andcm %0 = -1, %1"
2319 [(set_attr "type" "A")])
2320\f
2321;; ::::::::::::::::::::
2322;; ::
2323;; :: Comparisons
2324;; ::
2325;; ::::::::::::::::::::
2326
2327(define_expand "cmpsi"
2328 [(set (cc0)
0551c32d
RH
2329 (compare (match_operand:SI 0 "gr_register_operand" "")
2330 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
c65ebc55
JW
2331 ""
2332 "
2333{
2334 ia64_compare_op0 = operands[0];
2335 ia64_compare_op1 = operands[1];
2336 DONE;
2337}")
2338
2339(define_expand "cmpdi"
2340 [(set (cc0)
0551c32d
RH
2341 (compare (match_operand:DI 0 "gr_register_operand" "")
2342 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
c65ebc55
JW
2343 ""
2344 "
2345{
2346 ia64_compare_op0 = operands[0];
2347 ia64_compare_op1 = operands[1];
2348 DONE;
2349}")
2350
2351(define_expand "cmpsf"
2352 [(set (cc0)
0551c32d
RH
2353 (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
2354 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
c65ebc55
JW
2355 ""
2356 "
2357{
2358 ia64_compare_op0 = operands[0];
2359 ia64_compare_op1 = operands[1];
2360 DONE;
2361}")
2362
2363(define_expand "cmpdf"
2364 [(set (cc0)
0551c32d
RH
2365 (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
2366 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
c65ebc55
JW
2367 ""
2368 "
2369{
2370 ia64_compare_op0 = operands[0];
2371 ia64_compare_op1 = operands[1];
2372 DONE;
2373}")
2374
3f622353 2375(define_expand "cmptf"
c65ebc55 2376 [(set (cc0)
3f622353
RH
2377 (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
2378 (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
2379 ""
c65ebc55
JW
2380 "
2381{
2382 ia64_compare_op0 = operands[0];
2383 ia64_compare_op1 = operands[1];
2384 DONE;
2385}")
2386
2387(define_insn "*cmpsi_normal"
2388 [(set (match_operand:CC 0 "register_operand" "=c")
2389 (match_operator:CC 1 "normal_comparison_operator"
0551c32d
RH
2390 [(match_operand:SI 2 "gr_register_operand" "r")
2391 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
c65ebc55
JW
2392 ""
2393 "cmp4.%C1 %0, %I0 = %3, %2"
2394 [(set_attr "type" "A")])
2395
2396(define_insn "*cmpsi_adjusted"
2397 [(set (match_operand:CC 0 "register_operand" "=c")
2398 (match_operator:CC 1 "adjusted_comparison_operator"
0551c32d
RH
2399 [(match_operand:SI 2 "gr_register_operand" "r")
2400 (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
c65ebc55
JW
2401 ""
2402 "cmp4.%C1 %0, %I0 = %3, %2"
2403 [(set_attr "type" "A")])
2404
2405(define_insn "*cmpdi_normal"
2406 [(set (match_operand:CC 0 "register_operand" "=c")
2407 (match_operator:CC 1 "normal_comparison_operator"
0551c32d
RH
2408 [(match_operand:DI 2 "gr_register_operand" "r")
2409 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
c65ebc55
JW
2410 ""
2411 "cmp.%C1 %0, %I0 = %3, %2"
2412 [(set_attr "type" "A")])
2413
2414(define_insn "*cmpdi_adjusted"
2415 [(set (match_operand:CC 0 "register_operand" "=c")
2416 (match_operator:CC 1 "adjusted_comparison_operator"
0551c32d
RH
2417 [(match_operand:DI 2 "gr_register_operand" "r")
2418 (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
c65ebc55
JW
2419 ""
2420 "cmp.%C1 %0, %I0 = %3, %2"
2421 [(set_attr "type" "A")])
2422
2423(define_insn "*cmpsf_internal"
2424 [(set (match_operand:CC 0 "register_operand" "=c")
2425 (match_operator:CC 1 "comparison_operator"
0551c32d
RH
2426 [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
2427 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
c65ebc55
JW
2428 ""
2429 "fcmp.%D1 %0, %I0 = %F2, %F3"
2430 [(set_attr "type" "F")])
2431
2432(define_insn "*cmpdf_internal"
2433 [(set (match_operand:CC 0 "register_operand" "=c")
2434 (match_operator:CC 1 "comparison_operator"
0551c32d
RH
2435 [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
2436 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
c65ebc55
JW
2437 ""
2438 "fcmp.%D1 %0, %I0 = %F2, %F3"
2439 [(set_attr "type" "F")])
2440
3f622353
RH
2441(define_insn "*cmptf_internal"
2442 [(set (match_operand:CC 0 "register_operand" "=c")
2443 (match_operator:CC 1 "comparison_operator"
2444 [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
2445 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
2446 ""
2447 "fcmp.%D1 %0, %I0 = %F2, %F3"
2448 [(set_attr "type" "F")])
2449
c65ebc55
JW
2450;; ??? Can this pattern be generated?
2451
2452(define_insn "*bit_zero"
2453 [(set (match_operand:CC 0 "register_operand" "=c")
0551c32d 2454 (eq:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
2455 (const_int 1)
2456 (match_operand:DI 2 "immediate_operand" "n"))
2457 (const_int 0)))]
2458 ""
2459 "tbit.z %0, %I0 = %1, %2"
2460 [(set_attr "type" "I")])
2461
2462(define_insn "*bit_one"
2463 [(set (match_operand:CC 0 "register_operand" "=c")
0551c32d 2464 (ne:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
2465 (const_int 1)
2466 (match_operand:DI 2 "immediate_operand" "n"))
2467 (const_int 0)))]
2468 ""
2469 "tbit.nz %0, %I0 = %1, %2"
2470 [(set_attr "type" "I")])
2471
2472;; ??? We also need this if we run out of PR regs and need to spill some.
2473
2474;; ??? We need this if a CCmode value does not get allocated to a hard
2475;; register. This happens if we cse/gcse a CCmode value across a call, and the
2476;; function has a nonlocal goto. This is because global does not allocate
2477;; call crossing pseudos to hard registers when current_function_has_
2478;; nonlocal_goto is true. This is relatively common for C++ programs that
2479;; use exceptions. See ia64_secondary_reload_class.
2480
2481;; We use a define_expand here so that cse/gcse/combine can't accidentally
2482;; create movcc insns. If this was a named define_insn, we would not be able
2483;; to make it conditional on reload.
2484
2485(define_expand "movcc"
2486 [(set (match_operand:CC 0 "nonimmediate_operand" "")
2487 (match_operand:CC 1 "move_operand" ""))]
2488 ""
2489 "
2490{
2491 if (! reload_in_progress && ! reload_completed)
2492 FAIL;
2493}")
2494
2495(define_insn "*movcc_internal"
2496 [(set (match_operand:CC 0 "nonimmediate_operand" "=r,c,r,m")
2497 (match_operand:CC 1 "move_operand" "c,r,m,r"))]
2498 "reload_in_progress || reload_completed"
2499 "@
2500 #
2501 cmp4.ne %0, %I0 = %1, r0
2502 ld4%O1 %0 = %1%P1
2503 st4%Q0 %0 = %1%P0"
2504 [(set_attr "type" "unknown,A,M,M")])
2505
2506(define_split
2507 [(set (match_operand:CC 0 "register_operand" "")
2508 (match_operand:CC 1 "register_operand" ""))]
2509 "reload_completed
2510 && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
2511 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
2512 [(set (match_dup 2)
2513 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2514 (const_int 1)
2515 (match_dup 2)))
2516 (set (match_dup 2)
2517 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2518 (match_dup 2)
2519 (const_int 0)))]
2520 "operands[2] = gen_rtx_SUBREG (DImode, operands[0], 0);")
2521
2522\f
2523;; ::::::::::::::::::::
2524;; ::
2525;; :: Branches
2526;; ::
2527;; ::::::::::::::::::::
2528
2529(define_expand "beq"
2530 [(set (match_dup 1)
2531 (eq:CC (match_dup 2)
2532 (match_dup 3)))
2533 (set (pc)
2534 (if_then_else (ne:CC (match_dup 1)
2535 (const_int 0))
2536 (label_ref (match_operand 0 "" ""))
2537 (pc)))]
2538 ""
2539 "
2540{
2541 operands[1] = gen_reg_rtx (CCmode);
2542 operands[2] = ia64_compare_op0;
2543 operands[3] = ia64_compare_op1;
2544}")
2545
2546(define_expand "bne"
2547 [(set (match_dup 1)
2548 (ne:CC (match_dup 2)
2549 (match_dup 3)))
2550 (set (pc)
2551 (if_then_else (ne:CC (match_dup 1)
2552 (const_int 0))
2553 (label_ref (match_operand 0 "" ""))
2554 (pc)))]
2555 ""
2556 "
2557{
2558 operands[1] = gen_reg_rtx (CCmode);
2559 operands[2] = ia64_compare_op0;
2560 operands[3] = ia64_compare_op1;
2561}")
2562
2563(define_expand "blt"
2564 [(set (match_dup 1)
2565 (lt:CC (match_dup 2)
2566 (match_dup 3)))
2567 (set (pc)
2568 (if_then_else (ne:CC (match_dup 1)
2569 (const_int 0))
2570 (label_ref (match_operand 0 "" ""))
2571 (pc)))]
2572 ""
2573 "
2574{
2575 operands[1] = gen_reg_rtx (CCmode);
2576 operands[2] = ia64_compare_op0;
2577 operands[3] = ia64_compare_op1;
2578}")
2579
2580(define_expand "ble"
2581 [(set (match_dup 1)
2582 (le:CC (match_dup 2)
2583 (match_dup 3)))
2584 (set (pc)
2585 (if_then_else (ne:CC (match_dup 1)
2586 (const_int 0))
2587 (label_ref (match_operand 0 "" ""))
2588 (pc)))]
2589 ""
2590 "
2591{
2592 operands[1] = gen_reg_rtx (CCmode);
2593 operands[2] = ia64_compare_op0;
2594 operands[3] = ia64_compare_op1;
2595}")
2596
2597(define_expand "bgt"
2598 [(set (match_dup 1)
2599 (gt:CC (match_dup 2)
2600 (match_dup 3)))
2601 (set (pc)
2602 (if_then_else (ne:CC (match_dup 1)
2603 (const_int 0))
2604 (label_ref (match_operand 0 "" ""))
2605 (pc)))]
2606 ""
2607 "
2608{
2609 operands[1] = gen_reg_rtx (CCmode);
2610 operands[2] = ia64_compare_op0;
2611 operands[3] = ia64_compare_op1;
2612}")
2613
2614(define_expand "bge"
2615 [(set (match_dup 1)
2616 (ge:CC (match_dup 2)
2617 (match_dup 3)))
2618 (set (pc)
2619 (if_then_else (ne:CC (match_dup 1)
2620 (const_int 0))
2621 (label_ref (match_operand 0 "" ""))
2622 (pc)))]
2623 ""
2624 "
2625{
2626 operands[1] = gen_reg_rtx (CCmode);
2627 operands[2] = ia64_compare_op0;
2628 operands[3] = ia64_compare_op1;
2629}")
2630
2631(define_expand "bltu"
2632 [(set (match_dup 1)
2633 (ltu:CC (match_dup 2)
2634 (match_dup 3)))
2635 (set (pc)
2636 (if_then_else (ne:CC (match_dup 1)
2637 (const_int 0))
2638 (label_ref (match_operand 0 "" ""))
2639 (pc)))]
2640 ""
2641 "
2642{
2643 operands[1] = gen_reg_rtx (CCmode);
2644 operands[2] = ia64_compare_op0;
2645 operands[3] = ia64_compare_op1;
2646}")
2647
2648(define_expand "bleu"
2649 [(set (match_dup 1)
2650 (leu:CC (match_dup 2)
2651 (match_dup 3)))
2652 (set (pc)
2653 (if_then_else (ne:CC (match_dup 1)
2654 (const_int 0))
2655 (label_ref (match_operand 0 "" ""))
2656 (pc)))]
2657 ""
2658 "
2659{
2660 operands[1] = gen_reg_rtx (CCmode);
2661 operands[2] = ia64_compare_op0;
2662 operands[3] = ia64_compare_op1;
2663}")
2664
2665(define_expand "bgtu"
2666 [(set (match_dup 1)
2667 (gtu:CC (match_dup 2)
2668 (match_dup 3)))
2669 (set (pc)
2670 (if_then_else (ne:CC (match_dup 1)
2671 (const_int 0))
2672 (label_ref (match_operand 0 "" ""))
2673 (pc)))]
2674 ""
2675 "
2676{
2677 operands[1] = gen_reg_rtx (CCmode);
2678 operands[2] = ia64_compare_op0;
2679 operands[3] = ia64_compare_op1;
2680}")
2681
2682(define_expand "bgeu"
2683 [(set (match_dup 1)
2684 (geu:CC (match_dup 2)
2685 (match_dup 3)))
2686 (set (pc)
2687 (if_then_else (ne:CC (match_dup 1)
2688 (const_int 0))
2689 (label_ref (match_operand 0 "" ""))
2690 (pc)))]
2691 ""
2692 "
2693{
2694 operands[1] = gen_reg_rtx (CCmode);
2695 operands[2] = ia64_compare_op0;
2696 operands[3] = ia64_compare_op1;
2697}")
2698
e57b9d65
RH
2699(define_expand "bunordered"
2700 [(set (match_dup 1)
2701 (unordered:CC (match_dup 2)
2702 (match_dup 3)))
2703 (set (pc)
2704 (if_then_else (ne:CC (match_dup 1)
2705 (const_int 0))
2706 (label_ref (match_operand 0 "" ""))
2707 (pc)))]
2708 ""
2709 "
2710{
2711 operands[1] = gen_reg_rtx (CCmode);
2712 operands[2] = ia64_compare_op0;
2713 operands[3] = ia64_compare_op1;
2714}")
2715
2716(define_expand "bordered"
2717 [(set (match_dup 1)
2718 (ordered:CC (match_dup 2)
2719 (match_dup 3)))
2720 (set (pc)
2721 (if_then_else (ne:CC (match_dup 1)
2722 (const_int 0))
2723 (label_ref (match_operand 0 "" ""))
2724 (pc)))]
2725 ""
2726 "
2727{
2728 operands[1] = gen_reg_rtx (CCmode);
2729 operands[2] = ia64_compare_op0;
2730 operands[3] = ia64_compare_op1;
2731}")
2732
6b6c1201 2733(define_insn "*br_true"
c65ebc55 2734 [(set (pc)
6b6c1201
RH
2735 (if_then_else (match_operator 0 "predicate_operator"
2736 [(match_operand:CC 1 "register_operand" "c")
2737 (const_int 0)])
2738 (label_ref (match_operand 2 "" ""))
c65ebc55
JW
2739 (pc)))]
2740 ""
85548039 2741 "(%J0) br.cond%+ %l2"
e5bde68a
RH
2742 [(set_attr "type" "B")
2743 (set_attr "predicable" "no")])
c65ebc55 2744
6b6c1201 2745(define_insn "*br_false"
c65ebc55 2746 [(set (pc)
6b6c1201
RH
2747 (if_then_else (match_operator 0 "predicate_operator"
2748 [(match_operand:CC 1 "register_operand" "c")
2749 (const_int 0)])
c65ebc55 2750 (pc)
6b6c1201 2751 (label_ref (match_operand 2 "" ""))))]
c65ebc55 2752 ""
85548039 2753 "(%j0) br.cond%+ %l2"
e5bde68a
RH
2754 [(set_attr "type" "B")
2755 (set_attr "predicable" "no")])
c65ebc55
JW
2756\f
2757;; ::::::::::::::::::::
2758;; ::
5527bf14
RH
2759;; :: Counted loop operations
2760;; ::
2761;; ::::::::::::::::::::
2762
2763(define_expand "doloop_end"
2764 [(use (match_operand 0 "" "")) ; loop pseudo
2765 (use (match_operand 1 "" "")) ; iterations; zero if unknown
2766 (use (match_operand 2 "" "")) ; max iterations
2767 (use (match_operand 3 "" "")) ; loop level
2768 (use (match_operand 4 "" ""))] ; label
2769 ""
2770 "
2771{
2772 /* Only use cloop on innermost loops. */
2773 if (INTVAL (operands[3]) > 1)
2774 FAIL;
2775 emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
2776 operands[4]));
2777 DONE;
2778}")
2779
2780(define_insn "doloop_end_internal"
2781 [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
2782 (const_int 0))
2783 (label_ref (match_operand 1 "" ""))
2784 (pc)))
2785 (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
2786 (match_dup 0)
2787 (plus:DI (match_dup 0) (const_int -1))))]
2788 ""
2789 "br.cloop.sptk.few %l1"
2790 [(set_attr "type" "B")
2791 (set_attr "predicable" "no")])
2792\f
2793;; ::::::::::::::::::::
2794;; ::
c65ebc55
JW
2795;; :: Set flag operations
2796;; ::
2797;; ::::::::::::::::::::
2798
2799(define_expand "seq"
2800 [(set (match_dup 1)
2801 (eq:CC (match_dup 2)
2802 (match_dup 3)))
0551c32d 2803 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2804 (ne:DI (match_dup 1) (const_int 0)))]
2805 ""
2806 "
2807{
2808 operands[1] = gen_reg_rtx (CCmode);
2809 operands[2] = ia64_compare_op0;
2810 operands[3] = ia64_compare_op1;
2811}")
2812
2813(define_expand "sne"
2814 [(set (match_dup 1)
2815 (ne:CC (match_dup 2)
2816 (match_dup 3)))
0551c32d 2817 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2818 (ne:DI (match_dup 1) (const_int 0)))]
2819 ""
2820 "
2821{
2822 operands[1] = gen_reg_rtx (CCmode);
2823 operands[2] = ia64_compare_op0;
2824 operands[3] = ia64_compare_op1;
2825}")
2826
2827(define_expand "slt"
2828 [(set (match_dup 1)
2829 (lt:CC (match_dup 2)
2830 (match_dup 3)))
0551c32d 2831 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2832 (ne:DI (match_dup 1) (const_int 0)))]
2833 ""
2834 "
2835{
2836 operands[1] = gen_reg_rtx (CCmode);
2837 operands[2] = ia64_compare_op0;
2838 operands[3] = ia64_compare_op1;
2839}")
2840
2841(define_expand "sle"
2842 [(set (match_dup 1)
2843 (le:CC (match_dup 2)
2844 (match_dup 3)))
0551c32d 2845 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2846 (ne:DI (match_dup 1) (const_int 0)))]
2847 ""
2848 "
2849{
2850 operands[1] = gen_reg_rtx (CCmode);
2851 operands[2] = ia64_compare_op0;
2852 operands[3] = ia64_compare_op1;
2853}")
2854
2855(define_expand "sgt"
2856 [(set (match_dup 1)
2857 (gt:CC (match_dup 2)
2858 (match_dup 3)))
0551c32d 2859 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2860 (ne:DI (match_dup 1) (const_int 0)))]
2861 ""
2862 "
2863{
2864 operands[1] = gen_reg_rtx (CCmode);
2865 operands[2] = ia64_compare_op0;
2866 operands[3] = ia64_compare_op1;
2867}")
2868
2869(define_expand "sge"
2870 [(set (match_dup 1)
2871 (ge:CC (match_dup 2)
2872 (match_dup 3)))
0551c32d 2873 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2874 (ne:DI (match_dup 1) (const_int 0)))]
2875 ""
2876 "
2877{
2878 operands[1] = gen_reg_rtx (CCmode);
2879 operands[2] = ia64_compare_op0;
2880 operands[3] = ia64_compare_op1;
2881}")
2882
2883(define_expand "sltu"
2884 [(set (match_dup 1)
2885 (ltu:CC (match_dup 2)
2886 (match_dup 3)))
0551c32d 2887 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2888 (ne:DI (match_dup 1) (const_int 0)))]
2889 ""
2890 "
2891{
2892 operands[1] = gen_reg_rtx (CCmode);
2893 operands[2] = ia64_compare_op0;
2894 operands[3] = ia64_compare_op1;
2895}")
2896
2897(define_expand "sleu"
2898 [(set (match_dup 1)
2899 (leu:CC (match_dup 2)
2900 (match_dup 3)))
0551c32d 2901 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2902 (ne:DI (match_dup 1) (const_int 0)))]
2903 ""
2904 "
2905{
2906 operands[1] = gen_reg_rtx (CCmode);
2907 operands[2] = ia64_compare_op0;
2908 operands[3] = ia64_compare_op1;
2909}")
2910
2911(define_expand "sgtu"
2912 [(set (match_dup 1)
2913 (gtu:CC (match_dup 2)
2914 (match_dup 3)))
0551c32d 2915 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2916 (ne:DI (match_dup 1) (const_int 0)))]
2917 ""
2918 "
2919{
2920 operands[1] = gen_reg_rtx (CCmode);
2921 operands[2] = ia64_compare_op0;
2922 operands[3] = ia64_compare_op1;
2923}")
2924
2925(define_expand "sgeu"
2926 [(set (match_dup 1)
2927 (geu:CC (match_dup 2)
2928 (match_dup 3)))
0551c32d 2929 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2930 (ne:DI (match_dup 1) (const_int 0)))]
2931 ""
2932 "
2933{
2934 operands[1] = gen_reg_rtx (CCmode);
2935 operands[2] = ia64_compare_op0;
2936 operands[3] = ia64_compare_op1;
2937}")
2938
e57b9d65
RH
2939(define_expand "sunordered"
2940 [(set (match_dup 1)
2941 (unordered:CC (match_dup 2)
2942 (match_dup 3)))
0551c32d 2943 (set (match_operand:DI 0 "gr_register_operand" "")
e57b9d65
RH
2944 (ne:DI (match_dup 1) (const_int 0)))]
2945 ""
2946 "
2947{
2948 operands[1] = gen_reg_rtx (CCmode);
2949 operands[2] = ia64_compare_op0;
2950 operands[3] = ia64_compare_op1;
2951}")
2952
2953(define_expand "sordered"
2954 [(set (match_dup 1)
2955 (ordered:CC (match_dup 2)
2956 (match_dup 3)))
0551c32d 2957 (set (match_operand:DI 0 "gr_register_operand" "")
e57b9d65
RH
2958 (ne:DI (match_dup 1) (const_int 0)))]
2959 ""
2960 "
2961{
2962 operands[1] = gen_reg_rtx (CCmode);
2963 operands[2] = ia64_compare_op0;
2964 operands[3] = ia64_compare_op1;
2965}")
2966
c65ebc55
JW
2967;; Don't allow memory as destination here, because cmov/cmov/st is more
2968;; efficient than mov/mov/cst/cst.
2969
0551c32d
RH
2970(define_insn_and_split "*sne_internal"
2971 [(set (match_operand:DI 0 "gr_register_operand" "=r")
c65ebc55
JW
2972 (ne:DI (match_operand:CC 1 "register_operand" "c")
2973 (const_int 0)))]
2974 ""
2975 "#"
c65ebc55
JW
2976 "reload_completed"
2977 [(set (match_dup 0)
2978 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2979 (const_int 1)
2980 (match_dup 0)))
2981 (set (match_dup 0)
2982 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2983 (match_dup 0)
2984 (const_int 0)))]
0551c32d
RH
2985 ""
2986 [(set_attr "type" "unknown")])
c65ebc55
JW
2987
2988;; ??? Unknown if this can be matched.
2989
0551c32d
RH
2990(define_insn_and_split "*seq_internal"
2991 [(set (match_operand:DI 0 "gr_register_operand" "=r")
c65ebc55
JW
2992 (eq:DI (match_operand:CC 1 "register_operand" "c")
2993 (const_int 0)))]
2994 ""
2995 "#"
c65ebc55
JW
2996 "reload_completed"
2997 [(set (match_dup 0)
2998 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
2999 (const_int 1)
3000 (match_dup 0)))
3001 (set (match_dup 0)
3002 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
3003 (match_dup 0)
3004 (const_int 0)))]
0551c32d
RH
3005 ""
3006 [(set_attr "type" "unknown")])
c65ebc55
JW
3007
3008\f
3009;; ::::::::::::::::::::
3010;; ::
3011;; :: Conditional move instructions.
3012;; ::
3013;; ::::::::::::::::::::
3014
3015;; ??? Add movXXcc patterns?
3016
c65ebc55
JW
3017;;
3018;; DImode if_then_else patterns.
3019;;
3020
75cdbeb8
RH
3021;; Errata 72 workaround.
3022(define_insn "*cmovdi_internal_astep"
3023 [(set (match_operand:DI 0 "nonimmediate_operand"
97e242b0 3024 "=r,*f,Q,*b,r,*f,Q,*b,r,*f,Q,*b")
75cdbeb8
RH
3025 (if_then_else:DI
3026 (match_operator:CC 4 "predicate_operator"
3027 [(match_operand:CC 1 "register_operand"
3028 "c,c,c,c,c,c,c,c,c,c,c,c")
3029 (const_int 0)])
3030 (match_operand:DI 2 "general_operand"
97e242b0 3031 "0,0,0,0,ri*f*b,rO,*f,r,ri*f*b,rO,*f,r")
75cdbeb8 3032 (match_operand:DI 3 "general_operand"
97e242b0 3033 "ri*f*b,rO,*f,r,0,0,0,0,ri*f*b,rO,*f,r")))]
75cdbeb8
RH
3034 "TARGET_A_STEP"
3035 "* abort ();"
3036 [(set_attr "predicable" "no")])
3037
3038(define_insn "*cmovdi_internal"
3b572406 3039 [(set (match_operand:DI 0 "nonimmediate_operand"
514f96e6 3040 "=r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e")
e5bde68a
RH
3041 (if_then_else:DI
3042 (match_operator:CC 4 "predicate_operator"
3b572406 3043 [(match_operand:CC 1 "register_operand"
514f96e6 3044 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
e5bde68a 3045 (const_int 0)])
3b572406 3046 (match_operand:DI 2 "general_operand"
514f96e6 3047 "0,0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,rO,rK,rim*f*b*d*e,rO,rOQ,*f,rO,rK")
3b572406 3048 (match_operand:DI 3 "general_operand"
514f96e6 3049 "rim*f*b*d*e,rO,rOQ,*f,rO,rK,0,0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,rO,rK")))]
75cdbeb8
RH
3050 "! TARGET_A_STEP"
3051 "* abort ();"
3052 [(set_attr "predicable" "no")])
3053
3054(define_split
3055 [(set (match_operand 0 "nonimmediate_operand" "")
3056 (if_then_else
3057 (match_operator:CC 4 "predicate_operator"
3058 [(match_operand:CC 1 "register_operand" "")
3059 (const_int 0)])
3060 (match_operand 2 "general_operand" "")
3061 (match_operand 3 "general_operand" "")))]
3b572406
RH
3062 "reload_completed"
3063 [(const_int 0)]
e5bde68a
RH
3064 "
3065{
3b572406
RH
3066 rtx tmp;
3067 if (! rtx_equal_p (operands[0], operands[2]))
e5bde68a 3068 {
3b572406
RH
3069 tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
3070 tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
3071 emit_insn (tmp);
e5bde68a 3072 }
3b572406
RH
3073 if (! rtx_equal_p (operands[0], operands[3]))
3074 {
3075 tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3076 CCmode, operands[1], const0_rtx);
3077 tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
3078 gen_rtx_SET (VOIDmode, operands[0],
3079 operands[3]));
3080 emit_insn (tmp);
3081 }
3082 DONE;
75cdbeb8 3083}")
c65ebc55
JW
3084
3085;; Absolute value pattern.
3086
3087(define_insn "*absdi2_internal"
0551c32d 3088 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
e5bde68a
RH
3089 (if_then_else:DI
3090 (match_operator:CC 4 "predicate_operator"
3091 [(match_operand:CC 1 "register_operand" "c,c")
3092 (const_int 0)])
0551c32d
RH
3093 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
3094 (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
c65ebc55 3095 ""
e5bde68a 3096 "#"
3b572406
RH
3097 [(set_attr "type" "A,unknown")
3098 (set_attr "predicable" "no")])
c65ebc55
JW
3099
3100(define_split
3101 [(set (match_operand:DI 0 "register_operand" "")
e5bde68a
RH
3102 (if_then_else:DI
3103 (match_operator:CC 4 "predicate_operator"
3104 [(match_operand:CC 1 "register_operand" "c,c")
3105 (const_int 0)])
0551c32d
RH
3106 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
3107 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
3108 "reload_completed && rtx_equal_p (operands[0], operands[3])"
3109 [(cond_exec
3110 (match_dup 4)
3111 (set (match_dup 0)
3112 (neg:DI (match_dup 2))))]
c65ebc55
JW
3113 "")
3114
e5bde68a
RH
3115(define_split
3116 [(set (match_operand:DI 0 "register_operand" "")
3117 (if_then_else:DI
3118 (match_operator:CC 4 "predicate_operator"
3119 [(match_operand:CC 1 "register_operand" "c,c")
3120 (const_int 0)])
0551c32d
RH
3121 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
3122 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
3123 "reload_completed"
3124 [(cond_exec
3125 (match_dup 4)
3126 (set (match_dup 0) (neg:DI (match_dup 2))))
3127 (cond_exec
3128 (match_dup 5)
3129 (set (match_dup 0) (match_dup 3)))]
3130 "
3131{
3132 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3133 CCmode, operands[1], const0_rtx);
3134}")
c65ebc55
JW
3135
3136;;
3137;; SImode if_then_else patterns.
3138;;
3139
75cdbeb8
RH
3140(define_insn "*cmovsi_internal_astep"
3141 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,*f,r,*f,r,*f")
3142 (if_then_else:SI
3143 (match_operator:CC 4 "predicate_operator"
3144 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c")
3145 (const_int 0)])
3146 (match_operand:SI 2 "general_operand"
3147 "0,0,ri*f,rO,ri*f,rO")
3148 (match_operand:SI 3 "general_operand"
3149 "ri*f,rO,0,0,ri*f,rO")))]
3150 "TARGET_A_STEP"
3151 "* abort ();"
3152 [(set_attr "predicable" "no")])
3153
3154(define_insn "*cmovsi_internal"
3b572406 3155 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,*f,r,m,*f,r,m,*f")
e5bde68a
RH
3156 (if_then_else:SI
3157 (match_operator:CC 4 "predicate_operator"
3b572406 3158 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c,c,c")
e5bde68a 3159 (const_int 0)])
3b572406
RH
3160 (match_operand:SI 2 "general_operand"
3161 "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
3162 (match_operand:SI 3 "general_operand"
3163 "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
75cdbeb8
RH
3164 "! TARGET_A_STEP"
3165 "* abort ();"
3b572406 3166 [(set_attr "predicable" "no")])
c65ebc55
JW
3167
3168(define_insn "*abssi2_internal"
0551c32d 3169 [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
e5bde68a
RH
3170 (if_then_else:SI
3171 (match_operator:CC 4 "predicate_operator"
3172 [(match_operand:CC 1 "register_operand" "c,c")
3173 (const_int 0)])
0551c32d
RH
3174 (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
3175 (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
c65ebc55 3176 ""
e5bde68a 3177 "#"
3b572406
RH
3178 [(set_attr "type" "A,unknown")
3179 (set_attr "predicable" "no")])
c65ebc55
JW
3180
3181(define_split
3182 [(set (match_operand:SI 0 "register_operand" "")
e5bde68a
RH
3183 (if_then_else:SI
3184 (match_operator:CC 4 "predicate_operator"
3185 [(match_operand:CC 1 "register_operand" "c,c")
3186 (const_int 0)])
0551c32d
RH
3187 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
3188 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
3189 "reload_completed && rtx_equal_p (operands[0], operands[3])"
3190 [(cond_exec
3191 (match_dup 4)
3192 (set (match_dup 0)
3193 (neg:SI (match_dup 2))))]
c65ebc55
JW
3194 "")
3195
e5bde68a
RH
3196(define_split
3197 [(set (match_operand:SI 0 "register_operand" "")
3198 (if_then_else:SI
3199 (match_operator:CC 4 "predicate_operator"
3200 [(match_operand:CC 1 "register_operand" "c,c")
3201 (const_int 0)])
0551c32d
RH
3202 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
3203 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
3204 "reload_completed"
3205 [(cond_exec
3206 (match_dup 4)
3207 (set (match_dup 0) (neg:SI (match_dup 2))))
3208 (cond_exec
3209 (match_dup 5)
3210 (set (match_dup 0) (match_dup 3)))]
3211 "
3212{
3213 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3214 CCmode, operands[1], const0_rtx);
3215}")
3216
c65ebc55
JW
3217\f
3218;; ::::::::::::::::::::
3219;; ::
3220;; :: Call and branch instructions
3221;; ::
3222;; ::::::::::::::::::::
3223
3224;; Subroutine call instruction returning no value. Operand 0 is the function
3225;; to call; operand 1 is the number of bytes of arguments pushed (in mode
3226;; `SImode', except it is normally a `const_int'); operand 2 is the number of
3227;; registers used as operands.
3228
3229;; On most machines, operand 2 is not actually stored into the RTL pattern. It
3230;; is supplied for the sake of some RISC machines which need to put this
3231;; information into the assembler code; they can put it in the RTL instead of
3232;; operand 1.
3233
3234(define_expand "call"
3235 [(use (match_operand:DI 0 "" ""))
3236 (use (match_operand 1 "" ""))
3237 (use (match_operand 2 "" ""))
3238 (use (match_operand 3 "" ""))]
3239 ""
3240 "
3241{
3242 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
3243 rtx addr = XEXP (operands[0], 0);
3244 enum machine_mode mode = GET_MODE (addr);
3245
59da9a7d 3246 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
c65ebc55
JW
3247 emit_call_insn (gen_call_internal (addr, operands[1],
3248 gen_rtx_REG (DImode, R_BR (0))));
3249
3250 /* If this is an indirect call, then we have the address of a descriptor. */
3251 else if (! symbolic_operand (addr, mode))
3252 emit_insn (gen_indirect_call_pic (addr, operands[1]));
59da9a7d
JW
3253 else if (TARGET_CONST_GP)
3254 emit_call_insn (gen_call_internal (addr, operands[1],
3255 gen_rtx_REG (DImode, R_BR (0))));
c65ebc55
JW
3256 else
3257 emit_insn (gen_call_pic (addr, operands[1]));
3258
3259 DONE;
3260}")
3261
3262(define_expand "indirect_call_pic"
3263 [(set (match_dup 2) (reg:DI 1))
3264 (set (match_dup 3) (mem:DI (match_operand 0 "" "")))
3265 (set (match_dup 4) (plus:DI (match_dup 0) (const_int 8)))
3266 (set (reg:DI 1) (mem:DI (match_dup 4)))
3267 (parallel [(call (mem:DI (match_dup 3)) (match_operand 1 "" ""))
3268 (use (reg:DI 1))
3269 (clobber (reg:DI 320))])
3270 (set (reg:DI 1) (match_dup 2))]
3271 ""
3272 "
3273{
97e242b0 3274 operands[2] = ia64_gp_save_reg (0);
c65ebc55
JW
3275 operands[3] = gen_reg_rtx (DImode);
3276 operands[4] = gen_reg_rtx (DImode);
3277}")
3278
c65ebc55
JW
3279;; ??? Saving/restoring the GP register is not needed if we are calling
3280;; a function in the same module.
3281
3282(define_expand "call_pic"
3283 [(set (match_dup 2) (reg:DI 1))
3284 (parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" ""))
3285 (use (reg:DI 1))
3286 (clobber (reg:DI 320))])
3287 (set (reg:DI 1) (match_dup 2))]
3288 ""
3289 "
3290{
97e242b0
RH
3291 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
3292 operands[2] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[0], 0),
3293 VOIDmode));
c65ebc55
JW
3294}")
3295
c65ebc55
JW
3296(define_insn "call_internal"
3297 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
3298 (match_operand 1 "" ""))
3299 (clobber (match_operand:DI 2 "register_operand" "=b"))]
3300 ""
85548039 3301 "br.call%+.many %2 = %0"
c65ebc55
JW
3302 [(set_attr "type" "B")])
3303
3304(define_insn "*call_internal1"
3305 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
3306 (match_operand 1 "" ""))
3307 (use (reg:DI 1))
3308 (clobber (match_operand:DI 2 "register_operand" "=b"))]
3309 ""
85548039 3310 "br.call%+.many %2 = %0"
c65ebc55
JW
3311 [(set_attr "type" "B")])
3312
3313;; Subroutine call instruction returning a value. Operand 0 is the hard
3314;; register in which the value is returned. There are three more operands, the
3315;; same as the three operands of the `call' instruction (but with numbers
3316;; increased by one).
3317
3318;; Subroutines that return `BLKmode' objects use the `call' insn.
3319
3320(define_expand "call_value"
3321 [(use (match_operand 0 "" ""))
3322 (use (match_operand:DI 1 "" ""))
3323 (use (match_operand 2 "" ""))
3324 (use (match_operand 3 "" ""))
3325 (use (match_operand 4 "" ""))]
3326 ""
3327 "
3328{
3329 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
3330 rtx addr = XEXP (operands[1], 0);
3331 enum machine_mode mode = GET_MODE (addr);
3332
59da9a7d 3333 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
c65ebc55
JW
3334 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
3335 gen_rtx_REG (DImode, R_BR (0))));
3336
3337 /* If this is an indirect call, then we have the address of a descriptor. */
3338 else if (! symbolic_operand (addr, mode))
3339 {
3340 /* This is for HFA returns. */
3341 if (GET_CODE (operands[0]) == PARALLEL)
3342 emit_insn (gen_indirect_call_multiple_values_pic (operands[0], addr,
3343 operands[2]));
3344 else
3345 emit_insn (gen_indirect_call_value_pic (operands[0], addr,
3346 operands[2]));
3347 }
59da9a7d
JW
3348 else if (TARGET_CONST_GP)
3349 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
3350 gen_rtx_REG (DImode, R_BR (0))));
c65ebc55
JW
3351 /* This is for HFA returns. */
3352 else if (GET_CODE (operands[0]) == PARALLEL)
3353 emit_insn (gen_call_multiple_values_pic (operands[0], addr, operands[2]));
3354 else
3355 emit_insn (gen_call_value_pic (operands[0], addr, operands[2]));
3356
3357 DONE;
3358}")
3359
3360(define_expand "indirect_call_value_pic"
3361 [(set (match_dup 3) (reg:DI 1))
3362 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
3363 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
3364 (set (reg:DI 1) (mem:DI (match_dup 5)))
3365 (parallel [(set (match_operand 0 "" "")
3366 (call (mem:DI (match_dup 4)) (match_operand 2 "" "")))
3367 (use (reg:DI 1))
3368 (clobber (reg:DI 320))])
3369 (set (reg:DI 1) (match_dup 3))]
3370 ""
3371 "
3372{
97e242b0 3373 operands[3] = ia64_gp_save_reg (0);
c65ebc55
JW
3374 operands[4] = gen_reg_rtx (DImode);
3375 operands[5] = gen_reg_rtx (DImode);
3376}")
3377
3378(define_expand "indirect_call_multiple_values_pic"
3379 [(set (match_dup 3) (reg:DI 1))
3380 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
3381 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
3382 (set (reg:DI 1) (mem:DI (match_dup 5)))
3383 (match_par_dup 6 [(set (match_operand 0 "" "")
3384 (call (mem:DI (match_dup 4))
3385 (match_operand 2 "" "")))
3386 (use (reg:DI 1))
3387 (clobber (reg:DI 320))])
3388 (set (reg:DI 1) (match_dup 3))]
3389 ""
3390 "
3391{
3392 int count;
3393 int i;
3394 rtx call;
3395
97e242b0 3396 operands[3] = ia64_gp_save_reg (0);
c65ebc55
JW
3397 operands[4] = gen_reg_rtx (DImode);
3398 operands[5] = gen_reg_rtx (DImode);
3399
3400 /* This code is the same as the code in call_multiple_values_pic, except
3401 that op3 was replaced with op6 and op1 was replaced with op4. */
3402 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[4]),
3403 operands[2]);
3404
3405 count = XVECLEN (operands[0], 0);
3406 operands[6] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
3407
3408 XVECEXP (operands[6], 0, 0)
3409 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
3410
3411 XVECEXP (operands[6], 0, 1)
3412 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
3413 XVECEXP (operands[6], 0, 2)
3414 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
3415
3416 for (i = 1; i < count; i++)
3417 XVECEXP (operands[6], 0, i + 2)
3418 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
3419
3420}")
3421
c65ebc55
JW
3422;; ??? Saving/restoring the GP register is not needed if we are calling
3423;; a function in the same module.
3424
3425(define_expand "call_value_pic"
3426 [(set (match_dup 3) (reg:DI 1))
3427 (parallel [(set (match_operand 0 "" "")
3428 (call (mem:DI (match_operand 1 "" ""))
3429 (match_operand 2 "" "")))
3430 (use (reg:DI 1))
3431 (clobber (reg:DI 320))])
3432 (set (reg:DI 1) (match_dup 3))]
3433 ""
3434 "
3435{
97e242b0
RH
3436 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
3437 operands[3] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[1], 0),
3438 VOIDmode));
c65ebc55
JW
3439}")
3440
3441;; ??? Saving/restoring the GP register is not needed if we are calling
3442;; a function in the same module.
3443
3444(define_expand "call_multiple_values_pic"
3445 [(set (match_dup 4) (reg:DI 1))
3446 (match_par_dup 3 [(set (match_operand 0 "" "")
3447 (call (mem:DI (match_operand 1 "" ""))
3448 (match_operand 2 "" "")))
3449 (use (reg:DI 1))
3450 (clobber (reg:DI 320))])
3451 (set (reg:DI 1) (match_dup 4))]
3452 ""
3453 "
3454{
3455 int count;
3456 int i;
3457 rtx call;
3458
97e242b0 3459 operands[4] = ia64_gp_save_reg (0);
c65ebc55
JW
3460
3461 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[1]),
3462 operands[2]);
3463
3464 count = XVECLEN (operands[0], 0);
3465 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
3466
3467 XVECEXP (operands[3], 0, 0)
3468 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
3469
3470 XVECEXP (operands[3], 0, 1)
3471 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
3472 XVECEXP (operands[3], 0, 2)
3473 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
3474
3475 for (i = 1; i < count; i++)
3476 XVECEXP (operands[3], 0, i + 2)
3477 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
3478}")
3479
c65ebc55
JW
3480(define_insn "call_value_internal"
3481 [(set (match_operand 0 "register_operand" "=rf")
3482 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
3483 (match_operand 2 "" "")))
3484 (clobber (match_operand:DI 3 "register_operand" "=b"))]
3485 ""
85548039 3486 "br.call%+.many %3 = %1"
c65ebc55
JW
3487 [(set_attr "type" "B")])
3488
3489(define_insn "*call_value_internal1"
3490 [(set (match_operand 0 "register_operand" "=rf")
3491 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
3492 (match_operand 2 "" "")))
3493 (use (reg:DI 1))
3494 (clobber (match_operand:DI 3 "register_operand" "=b"))]
3495 ""
85548039 3496 "br.call%+.many %3 = %1"
c65ebc55
JW
3497 [(set_attr "type" "B")])
3498
3499(define_insn "*call_multiple_values_internal1"
3500 [(match_parallel 0 "call_multiple_values_operation"
3501 [(set (match_operand 1 "register_operand" "=rf")
3502 (call (mem:DI (match_operand:DI 2 "call_operand" "bi"))
3503 (match_operand 3 "" "")))
3504 (use (reg:DI 1))
3505 (clobber (match_operand:DI 4 "register_operand" "=b"))])]
3506 ""
85548039 3507 "br.call%+.many %4 = %2"
c65ebc55
JW
3508 [(set_attr "type" "B")])
3509
3510;; Call subroutine returning any type.
3511
3512(define_expand "untyped_call"
3513 [(parallel [(call (match_operand 0 "" "")
3514 (const_int 0))
3515 (match_operand 1 "" "")
3516 (match_operand 2 "" "")])]
3517 ""
3518 "
3519{
3520 int i;
3521
3522 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3523
3524 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3525 {
3526 rtx set = XVECEXP (operands[2], 0, i);
3527 emit_move_insn (SET_DEST (set), SET_SRC (set));
3528 }
3529
3530 /* The optimizer does not know that the call sets the function value
3531 registers we stored in the result block. We avoid problems by
3532 claiming that all hard registers are used and clobbered at this
3533 point. */
3534 emit_insn (gen_blockage ());
3535
3536 DONE;
3537}")
3538
3539(define_insn "return_internal"
3540 [(return)
3541 (use (match_operand:DI 0 "register_operand" "b"))]
3542 ""
3543 "br.ret.sptk.many %0"
3544 [(set_attr "type" "B")])
3545
3546(define_insn "return"
3547 [(return)]
3548 "ia64_direct_return ()"
3549 "br.ret.sptk.many rp"
3550 [(set_attr "type" "B")])
3551
6b6c1201 3552(define_insn "*return_true"
c65ebc55 3553 [(set (pc)
6b6c1201
RH
3554 (if_then_else (match_operator 0 "predicate_operator"
3555 [(match_operand:CC 1 "register_operand" "c")
3556 (const_int 0)])
c65ebc55
JW
3557 (return)
3558 (pc)))]
3559 "ia64_direct_return ()"
13da91fd 3560 "(%J0) br.ret%+.many rp"
e5bde68a
RH
3561 [(set_attr "type" "B")
3562 (set_attr "predicable" "no")])
c65ebc55 3563
6b6c1201 3564(define_insn "*return_false"
c65ebc55 3565 [(set (pc)
6b6c1201
RH
3566 (if_then_else (match_operator 0 "predicate_operator"
3567 [(match_operand:CC 1 "register_operand" "c")
3568 (const_int 0)])
c65ebc55
JW
3569 (pc)
3570 (return)))]
3571 "ia64_direct_return ()"
13da91fd 3572 "(%j0) br.ret%+.many rp"
e5bde68a
RH
3573 [(set_attr "type" "B")
3574 (set_attr "predicable" "no")])
c65ebc55
JW
3575
3576(define_insn "jump"
3577 [(set (pc) (label_ref (match_operand 0 "" "")))]
3578 ""
3579 "br %l0"
3580 [(set_attr "type" "B")])
3581
3582(define_insn "indirect_jump"
3583 [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
3584 ""
3585 "br %0"
3586 [(set_attr "type" "B")])
3587
3588(define_expand "tablejump"
3589 [(match_operand:DI 0 "register_operand" "")
3590 (match_operand 1 "" "")]
3591 ""
3592 "
3593{
3594 rtx tmp1 = gen_reg_rtx (DImode);
3595 rtx tmp2 = gen_reg_rtx (DImode);
3596
3597 emit_move_insn (tmp1, gen_rtx_LABEL_REF (Pmode, operands[1]));
3598 emit_insn (gen_adddi3 (tmp2, operands[0], tmp1));
3599 emit_jump_insn (gen_tablejump_internal (tmp2, operands[1]));
3600 DONE;
3601}")
3602
3603(define_insn "tablejump_internal"
3604 [(set (pc) (match_operand:DI 0 "register_operand" "b"))
3605 (use (label_ref (match_operand 1 "" "")))]
3606 ""
3607 "br %0"
3608 [(set_attr "type" "B")])
3609
3610\f
3611;; ::::::::::::::::::::
3612;; ::
3613;; :: Prologue and Epilogue instructions
3614;; ::
3615;; ::::::::::::::::::::
3616
3617(define_expand "prologue"
3618 [(const_int 1)]
3619 ""
3620 "
3621{
3622 ia64_expand_prologue ();
3623 DONE;
3624}")
3625
3626(define_expand "epilogue"
3627 [(const_int 2)]
3628 ""
3629 "
3630{
3631 ia64_expand_epilogue ();
3632 DONE;
3633}")
3634
3635;; This prevents the scheduler from moving the SP decrement past FP-relative
3636;; stack accesses. This is the same as adddi3 plus the extra set.
3637
3638(define_insn "prologue_allocate_stack"
3639 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3640 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
0551c32d 3641 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
c65ebc55
JW
3642 (set (match_operand:DI 3 "register_operand" "=r,r,r")
3643 (match_dup 3))]
3644 ""
3645 "@
3646 add %0 = %1, %2
3647 adds %0 = %2, %1
3648 addl %0 = %2, %1"
3649 [(set_attr "type" "A")])
3650
3651;; This prevents the scheduler from moving the SP restore past FP-relative
3652;; stack accesses. This is similar to movdi plus the extra set.
3653
3654(define_insn "epilogue_deallocate_stack"
3655 [(set (match_operand:DI 0 "register_operand" "=r")
3656 (match_operand:DI 1 "register_operand" "+r"))
3657 (set (match_dup 1) (match_dup 1))]
3658 ""
3659 "mov %0 = %1"
3660 [(set_attr "type" "A")])
3661
3662;; Allocate a new register frame.
3663
3664(define_insn "alloc"
3665 [(set (match_operand:DI 0 "register_operand" "=r")
3666 (unspec_volatile:DI [(const_int 0)] 0))
3667 (use (match_operand:DI 1 "const_int_operand" "i"))
3668 (use (match_operand:DI 2 "const_int_operand" "i"))
3669 (use (match_operand:DI 3 "const_int_operand" "i"))
3670 (use (match_operand:DI 4 "const_int_operand" "i"))]
3671 ""
3672 "alloc %0 = ar.pfs, %1, %2, %3, %4"
e5bde68a
RH
3673 [(set_attr "type" "M")
3674 (set_attr "predicable" "no")])
c65ebc55 3675
97e242b0
RH
3676;; Modifies ar.unat
3677(define_expand "gr_spill"
870f9ec0
RH
3678 [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
3679 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3680 (match_operand:DI 2 "const_int_operand" "")] 1))
3681 (clobber (match_dup 3))])]
97e242b0 3682 ""
870f9ec0 3683 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
97e242b0 3684
870f9ec0 3685(define_insn "gr_spill_internal"
c65ebc55 3686 [(set (match_operand:DI 0 "memory_operand" "=m")
870f9ec0
RH
3687 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3688 (match_operand:DI 2 "const_int_operand" "")] 1))
3689 (clobber (match_operand:DI 3 "register_operand" ""))]
c65ebc55 3690 ""
870f9ec0 3691 ".mem.offset %2, 0\;st8.spill %0 = %1%P0"
c65ebc55
JW
3692 [(set_attr "type" "M")])
3693
97e242b0
RH
3694;; Reads ar.unat
3695(define_expand "gr_restore"
870f9ec0
RH
3696 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3697 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3698 (match_operand:DI 2 "const_int_operand" "")] 2))
3699 (use (match_dup 3))])]
97e242b0 3700 ""
870f9ec0 3701 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
97e242b0 3702
870f9ec0 3703(define_insn "gr_restore_internal"
c65ebc55 3704 [(set (match_operand:DI 0 "register_operand" "=r")
870f9ec0
RH
3705 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3706 (match_operand:DI 2 "const_int_operand" "")] 2))
3707 (use (match_operand:DI 3 "register_operand" ""))]
c65ebc55 3708 ""
870f9ec0 3709 ".mem.offset %2, 0\;ld8.fill %0 = %1%P1"
c65ebc55
JW
3710 [(set_attr "type" "M")])
3711
3712(define_insn "fr_spill"
3f622353
RH
3713 [(set (match_operand:TF 0 "memory_operand" "=m")
3714 (unspec:TF [(match_operand:TF 1 "register_operand" "f")] 3))]
c65ebc55
JW
3715 ""
3716 "stf.spill %0 = %1%P0"
3717 [(set_attr "type" "M")])
3718
3719(define_insn "fr_restore"
3f622353
RH
3720 [(set (match_operand:TF 0 "register_operand" "=f")
3721 (unspec:TF [(match_operand:TF 1 "memory_operand" "m")] 4))]
c65ebc55
JW
3722 ""
3723 "ldf.fill %0 = %1%P1"
3724 [(set_attr "type" "M")])
3725
0c96007e
AM
3726(define_insn "bsp_value"
3727 [(set (match_operand:DI 0 "register_operand" "=r")
3728 (unspec:DI [(const_int 0)] 20))]
3729 ""
3730 "mov %0 = ar.bsp"
3731 [(set_attr "type" "I")])
3732
3733(define_insn "set_bsp"
3734 [(unspec_volatile [(const_int 0)] 5)
3735 (use (match_operand:DI 0 "register_operand" "r"))]
3736 ""
13da91fd 3737 "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
3738 [(set_attr "type" "unknown")
3739 (set_attr "predicable" "no")])
ce152ef8
AM
3740
3741(define_insn "flushrs"
3742 [(unspec [(const_int 0)] 21)]
3743 ""
13da91fd 3744 ";;\;flushrs"
ce152ef8 3745 [(set_attr "type" "M")])
c65ebc55
JW
3746\f
3747;; ::::::::::::::::::::
3748;; ::
3749;; :: Miscellaneous instructions
3750;; ::
3751;; ::::::::::::::::::::
3752
3753;; ??? Emiting a NOP instruction isn't very useful. This should probably
3754;; be emitting ";;" to force a break in the instruction packing.
3755
3756;; No operation, needed in case the user uses -g but not -O.
3757(define_insn "nop"
3758 [(const_int 0)]
3759 ""
3760 "nop 0"
3761 [(set_attr "type" "unknown")])
3762
3763;; Pseudo instruction that prevents the scheduler from moving code above this
3764;; point.
3765(define_insn "blockage"
3766 [(unspec_volatile [(const_int 0)] 1)]
3767 ""
3768 ""
e5bde68a
RH
3769 [(set_attr "type" "unknown")
3770 (set_attr "predicable" "no")])
c65ebc55
JW
3771
3772(define_insn "insn_group_barrier"
3773 [(unspec_volatile [(const_int 0)] 2)]
3774 ""
3775 ";;"
e5bde68a
RH
3776 [(set_attr "type" "S")
3777 (set_attr "predicable" "no")])
c65ebc55
JW
3778
3779\f
3780;; Non-local goto support.
3781
3782(define_expand "save_stack_nonlocal"
3783 [(use (match_operand:OI 0 "memory_operand" ""))
3784 (use (match_operand:DI 1 "register_operand" ""))]
3785 ""
3786 "
3787{
3788 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
3789 \"__ia64_save_stack_nonlocal\"),
3790 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
3791 operands[1], Pmode);
3792 DONE;
3793}")
3794
3795(define_expand "nonlocal_goto"
3796 [(use (match_operand 0 "general_operand" ""))
3797 (use (match_operand 1 "general_operand" ""))
3798 (use (match_operand 2 "general_operand" ""))
3799 (use (match_operand 3 "general_operand" ""))]
3800 ""
3801 "
3802{
c65ebc55 3803 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
97e242b0
RH
3804 0, VOIDmode, 3,
3805 operands[1], Pmode,
c65ebc55
JW
3806 copy_to_reg (XEXP (operands[2], 0)), Pmode,
3807 operands[3], Pmode);
3808 emit_barrier ();
3809 DONE;
3810}")
3811
97e242b0
RH
3812;; Restore the GP after the exception/longjmp. The preceeding call will
3813;; have tucked it away.
3814(define_expand "exception_receiver"
3815 [(set (reg:DI 1) (match_dup 0))]
3816 ""
3817 "operands[0] = ia64_gp_save_reg (0);")
c65ebc55 3818
97e242b0
RH
3819;; The rest of the setjmp processing happens with the nonlocal_goto expander.
3820;; ??? This is not tested.
3821(define_expand "builtin_setjmp_setup"
3822 [(use (match_operand:DI 0 "" ""))]
c65ebc55
JW
3823 ""
3824 "
3825{
97e242b0
RH
3826 emit_move_insn (ia64_gp_save_reg (0), gen_rtx_REG (DImode, GR_REG (1)));
3827 DONE;
3828}")
3829
3830(define_expand "builtin_setjmp_receiver"
3831 [(use (match_operand:DI 0 "" ""))]
3832 ""
3833 "
3834{
3835 emit_move_insn (gen_rtx_REG (DImode, GR_REG (1)), ia64_gp_save_reg (0));
c65ebc55
JW
3836 DONE;
3837}")
3838
0c96007e
AM
3839(define_expand "eh_epilogue"
3840 [(use (match_operand:DI 0 "register_operand" "r"))
3841 (use (match_operand:DI 1 "register_operand" "r"))
3842 (use (match_operand:DI 2 "register_operand" "r"))]
3843 ""
3844 "
3845{
3846 rtx bsp = gen_rtx_REG (Pmode, 10);
3847 rtx sp = gen_rtx_REG (Pmode, 9);
3848
3849 if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
3850 {
3851 emit_move_insn (bsp, operands[0]);
3852 operands[0] = bsp;
3853 }
3854 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
3855 {
3856 emit_move_insn (sp, operands[2]);
3857 operands[2] = sp;
3858 }
3859 emit_insn (gen_rtx_USE (VOIDmode, sp));
3860 emit_insn (gen_rtx_USE (VOIDmode, bsp));
3861
3862 cfun->machine->ia64_eh_epilogue_sp = sp;
3863 cfun->machine->ia64_eh_epilogue_bsp = bsp;
0c96007e 3864}")
9525c690
JW
3865\f
3866;; Builtin apply support.
3867
3868(define_expand "restore_stack_nonlocal"
3869 [(use (match_operand:DI 0 "register_operand" ""))
3870 (use (match_operand:OI 1 "memory_operand" ""))]
3871 ""
3872 "
3873{
3874 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
3875 \"__ia64_restore_stack_nonlocal\"),
3876 0, VOIDmode, 1,
3877 copy_to_reg (XEXP (operands[1], 0)), Pmode);
3878 DONE;
3879}")
3880
3881\f
3882;;; Intrinsics support.
c65ebc55 3883
0551c32d
RH
3884(define_expand "mf"
3885 [(set (mem:BLK (match_dup 0))
3886 (unspec:BLK [(mem:BLK (match_dup 0))] 12))]
3887 ""
3888 "
3889{
3890 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
3891 MEM_VOLATILE_P (operands[0]) = 1;
3892}")
3893
3894(define_insn "*mf_internal"
3895 [(set (match_operand:BLK 0 "" "")
3896 (unspec:BLK [(match_operand:BLK 1 "" "")] 12))]
c65ebc55
JW
3897 ""
3898 "mf"
3899 [(set_attr "type" "M")])
3900
3901(define_insn "fetchadd_acq_si"
0551c32d
RH
3902 [(set (match_operand:SI 0 "gr_register_operand" "=r")
3903 (match_dup 1))
3904 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
3905 (unspec:SI [(match_dup 1)
3906 (match_operand:SI 2 "fetchadd_operand" "n")] 19))]
c65ebc55
JW
3907 ""
3908 "fetchadd4.acq %0 = %1, %2"
3909 [(set_attr "type" "M")])
3910
3911(define_insn "fetchadd_acq_di"
0551c32d
RH
3912 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3913 (match_dup 1))
3914 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
3915 (unspec:DI [(match_dup 1)
3916 (match_operand:DI 2 "fetchadd_operand" "n")] 19))]
c65ebc55
JW
3917 ""
3918 "fetchadd8.acq %0 = %1, %2"
3919 [(set_attr "type" "M")])
3920
3921(define_insn "cmpxchg_acq_si"
0551c32d
RH
3922 [(set (match_operand:SI 0 "gr_register_operand" "=r")
3923 (match_dup 1))
3924 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
3925 (unspec:SI [(match_dup 1)
3926 (match_operand:SI 2 "gr_register_operand" "r")
97e242b0 3927 (match_operand:SI 3 "ar_ccv_reg_operand" "")] 13))]
c65ebc55 3928 ""
97e242b0 3929 "cmpxchg4.acq %0 = %1, %2, %3"
c65ebc55
JW
3930 [(set_attr "type" "M")])
3931
3932(define_insn "cmpxchg_acq_di"
0551c32d
RH
3933 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3934 (match_dup 1))
3935 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
3936 (unspec:DI [(match_dup 1)
3937 (match_operand:DI 2 "gr_register_operand" "r")
3938 (match_operand:DI 3 "ar_ccv_reg_operand" "")] 13))]
c65ebc55 3939 ""
97e242b0 3940 "cmpxchg8.acq %0 = %1, %2, %3"
c65ebc55
JW
3941 [(set_attr "type" "M")])
3942
c65ebc55 3943(define_insn "xchgsi"
0551c32d
RH
3944 [(set (match_operand:SI 0 "gr_register_operand" "=r")
3945 (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
c65ebc55 3946 (set (match_dup 1)
0551c32d 3947 (match_operand:SI 2 "gr_register_operand" "r"))]
c65ebc55
JW
3948 ""
3949 "xchg4 %0 = %1, %2"
3950 [(set_attr "type" "M")])
3951
3952(define_insn "xchgdi"
0551c32d
RH
3953 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3954 (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
c65ebc55 3955 (set (match_dup 1)
0551c32d 3956 (match_operand:DI 2 "gr_register_operand" "r"))]
c65ebc55
JW
3957 ""
3958 "xchg8 %0 = %1, %2"
3959 [(set_attr "type" "M")])
e5bde68a
RH
3960\f
3961;; Predication.
3962
3963(define_cond_exec
3964 [(match_operator 0 "predicate_operator"
3965 [(match_operand:CC 1 "register_operand" "c")
3966 (const_int 0)])]
3967 ""
3968 "(%J0)")
3b572406
RH
3969
3970(define_insn "pred_rel_mutex"
054451ea 3971 [(unspec_volatile [(match_operand:CC 0 "register_operand" "c")] 7)]
3b572406 3972 ""
054451ea 3973 ".pred.rel.mutex %0, %I0"
3b572406
RH
3974 [(set_attr "type" "unknown")
3975 (set_attr "predicable" "no")])
ca3920ad
JW
3976
3977(define_insn "safe_across_calls_all"
3978 [(unspec_volatile [(const_int 0)] 8)]
3979 ""
3980 ".pred.safe_across_calls p1-p63"
3981 [(set_attr "type" "unknown")
3982 (set_attr "predicable" "no")])
3983
3984(define_insn "safe_across_calls_normal"
3985 [(unspec_volatile [(const_int 0)] 9)]
3986 ""
3987 "*
3988{
3989 emit_safe_across_calls (asm_out_file);
3990 return \"\";
3991}"
3992 [(set_attr "type" "unknown")
3993 (set_attr "predicable" "no")])
3994