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