]> gcc.gnu.org Git - gcc.git/blame - gcc/config/ia64/ia64.md
ia64.md (reload_inti): Use a TImode scratch.
[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"))
60a3c181 671 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3f622353
RH
672 ""
673 "
674{
60a3c181
RH
675 unsigned int s_regno = REGNO (operands[2]);
676 if (s_regno == REGNO (operands[0]))
677 s_regno += 1;
678 operands[2] = gen_rtx_REG (DImode, s_regno);
3f622353
RH
679}")
680
681(define_expand "reload_outti"
682 [(parallel [(set (match_operand:TI 0 "" "=m")
683 (match_operand:TI 1 "register_operand" "r"))
60a3c181 684 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3f622353
RH
685 ""
686 "
687{
60a3c181
RH
688 unsigned int s_regno = REGNO (operands[2]);
689 if (s_regno == REGNO (operands[1]))
690 s_regno += 1;
691 operands[2] = gen_rtx_REG (DImode, s_regno);
3f622353 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"
0551c32d
RH
934 [(set (match_operand:DI 0 "gr_register_operand" "=r")
935 (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
c65ebc55
JW
936 ""
937 "sxt1 %0 = %1"
938 [(set_attr "type" "I")])
939
940(define_insn "extendhidi2"
0551c32d
RH
941 [(set (match_operand:DI 0 "gr_register_operand" "=r")
942 (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
c65ebc55
JW
943 ""
944 "sxt2 %0 = %1"
945 [(set_attr "type" "I")])
946
947(define_insn "extendsidi2"
0551c32d
RH
948 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
949 (sign_extend:DI (match_operand:SI 1 "grfr_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"
0551c32d
RH
959 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
960 (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
c65ebc55
JW
961 ""
962 "@
963 zxt1 %0 = %1
964 ld1%O1 %0 = %1%P1"
965 [(set_attr "type" "I,M")])
966
967(define_insn "zero_extendhidi2"
0551c32d
RH
968 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
969 (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
c65ebc55
JW
970 ""
971 "@
972 zxt2 %0 = %1
973 ld2%O1 %0 = %1%P1"
974 [(set_attr "type" "I,M")])
975
976(define_insn "zero_extendsidi2"
0551c32d
RH
977 [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,*f")
978 (zero_extend:DI
979 (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,*f")))]
c65ebc55
JW
980 ""
981 "@
982 zxt4 %0 = %1
983 ld4%O1 %0 = %1%P1
984 fsxt.r %0 = f1, %1%B0"
985 [(set_attr "type" "I,M,F")])
986
987;; Convert between floating point types of different sizes.
988
e8e20f18
RH
989;; ??? Optimization opportunity here. Get rid of the insn altogether
990;; when we can. Should probably use a scheme like has been proposed
991;; for ia32 in dealing with operands that match unary operators. This
992;; would let combine merge the thing into adjacent insns.
c65ebc55 993
e8e20f18 994(define_insn_and_split "extendsfdf2"
0551c32d
RH
995 [(set (match_operand:DF 0 "fr_register_operand" "=f,f")
996 (float_extend:DF (match_operand:SF 1 "fr_register_operand" "0,f")))]
c65ebc55 997 ""
e8e20f18 998 "mov %0 = %1"
50798048 999 "reload_completed"
e8e20f18
RH
1000 [(set (match_dup 0) (float_extend:DF (match_dup 1)))]
1001 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1002 [(set_attr "type" "F")])
c65ebc55 1003
3f622353 1004(define_insn_and_split "extendsftf2"
0551c32d
RH
1005 [(set (match_operand:TF 0 "fr_register_operand" "=f,f")
1006 (float_extend:TF (match_operand:SF 1 "fr_register_operand" "0,f")))]
3f622353
RH
1007 ""
1008 "mov %0 = %1"
1009 "reload_completed"
1010 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1011 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1012 [(set_attr "type" "F")])
1013
1014(define_insn_and_split "extenddftf2"
0551c32d
RH
1015 [(set (match_operand:TF 0 "fr_register_operand" "=f,f")
1016 (float_extend:TF (match_operand:DF 1 "fr_register_operand" "0,f")))]
3f622353
RH
1017 ""
1018 "mov %0 = %1"
1019 "reload_completed"
1020 [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
1021 "if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
1022 [(set_attr "type" "F")])
1023
c65ebc55 1024(define_insn "truncdfsf2"
0551c32d
RH
1025 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1026 (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1027 ""
1028 "fnorm.s %0 = %1%B0"
1029 [(set_attr "type" "F")])
1030
3f622353 1031(define_insn "trunctfsf2"
0551c32d
RH
1032 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1033 (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
e5bde68a
RH
1034 ""
1035 "fnorm.s %0 = %1%B0"
1036 [(set_attr "type" "F")])
c65ebc55 1037
3f622353 1038(define_insn "trunctfdf2"
0551c32d
RH
1039 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1040 (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
c65ebc55 1041 ""
e5bde68a
RH
1042 "fnorm.d %0 = %1%B0"
1043 [(set_attr "type" "F")])
1044
1045;; Convert between signed integer types and floating point.
1046
3f622353 1047(define_insn "floatditf2"
0551c32d
RH
1048 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1049 (float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
e5bde68a
RH
1050 ""
1051 "fcvt.xf %0 = %1"
1052 [(set_attr "type" "F")])
c65ebc55
JW
1053
1054(define_insn "fix_truncsfdi2"
0551c32d
RH
1055 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1056 (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1057 ""
1058 "fcvt.fx.trunc %0 = %1%B0"
1059 [(set_attr "type" "F")])
1060
1061(define_insn "fix_truncdfdi2"
0551c32d
RH
1062 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1063 (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1064 ""
1065 "fcvt.fx.trunc %0 = %1%B0"
1066 [(set_attr "type" "F")])
1067
3f622353 1068(define_insn "fix_trunctfdi2"
0551c32d
RH
1069 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1070 (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
3f622353
RH
1071 ""
1072 "fcvt.fx.trunc %0 = %1%B0"
1073 [(set_attr "type" "F")])
1074
c65ebc55
JW
1075;; Convert between unsigned integer types and floating point.
1076
1077(define_insn "floatunsdisf2"
0551c32d
RH
1078 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1079 (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
c65ebc55
JW
1080 ""
1081 "fcvt.xuf.s %0 = %1%B0"
1082 [(set_attr "type" "F")])
1083
1084(define_insn "floatunsdidf2"
0551c32d
RH
1085 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1086 (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
c65ebc55
JW
1087 ""
1088 "fcvt.xuf.d %0 = %1%B0"
1089 [(set_attr "type" "F")])
1090
3f622353 1091(define_insn "floatunsditf2"
0551c32d
RH
1092 [(set (match_operand:TF 0 "fr_register_operand" "=f")
1093 (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
3f622353
RH
1094 ""
1095 "fcvt.xuf %0 = %1%B0"
1096 [(set_attr "type" "F")])
1097
c65ebc55 1098(define_insn "fixuns_truncsfdi2"
0551c32d
RH
1099 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1100 (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1101 ""
1102 "fcvt.fxu.trunc %0 = %1%B0"
1103 [(set_attr "type" "F")])
1104
1105(define_insn "fixuns_truncdfdi2"
0551c32d
RH
1106 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1107 (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1108 ""
1109 "fcvt.fxu.trunc %0 = %1%B0"
1110 [(set_attr "type" "F")])
1111
3f622353 1112(define_insn "fixuns_trunctfdi2"
0551c32d
RH
1113 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1114 (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
3f622353
RH
1115 ""
1116 "fcvt.fxu.trunc %0 = %1%B0"
1117 [(set_attr "type" "F")])
c65ebc55
JW
1118\f
1119;; ::::::::::::::::::::
1120;; ::
1121;; :: Bit field extraction
1122;; ::
1123;; ::::::::::::::::::::
1124
c65ebc55 1125(define_insn "extv"
0551c32d
RH
1126 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1127 (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
1128 (match_operand:DI 2 "const_int_operand" "n")
1129 (match_operand:DI 3 "const_int_operand" "n")))]
1130 ""
1131 "extr %0 = %1, %3, %2"
1132 [(set_attr "type" "I")])
1133
1134(define_insn "extzv"
0551c32d
RH
1135 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1136 (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
1137 (match_operand:DI 2 "const_int_operand" "n")
1138 (match_operand:DI 3 "const_int_operand" "n")))]
1139 ""
1140 "extr.u %0 = %1, %3, %2"
1141 [(set_attr "type" "I")])
1142
1143;; Insert a bit field.
1144;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1145;; Source1 can be 0 or -1.
1146;; Source2 can be 0.
1147
1148;; ??? Actual dep instruction is more powerful than what these insv
1149;; patterns support. Unfortunately, combine is unable to create patterns
1150;; where source2 != dest.
1151
1152(define_expand "insv"
0551c32d 1153 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1154 (match_operand:DI 1 "const_int_operand" "")
1155 (match_operand:DI 2 "const_int_operand" ""))
1156 (match_operand:DI 3 "nonmemory_operand" ""))]
1157 ""
1158 "
1159{
1160 int width = INTVAL (operands[1]);
1161 int shift = INTVAL (operands[2]);
1162
1163 /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1164 pseudo. */
1165 if (! register_operand (operands[3], DImode)
1166 && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1167 operands[3] = force_reg (DImode, operands[3]);
1168
1169 /* If this is a single dep instruction, we have nothing to do. */
1170 if (! ((register_operand (operands[3], DImode) && width <= 16)
1171 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1172 {
1173 /* Check for cases that can be implemented with a mix instruction. */
1174 if (width == 32 && shift == 0)
1175 {
1176 /* Directly generating the mix4left instruction confuses
1177 optimize_bit_field in function.c. Since this is performing
1178 a useful optimization, we defer generation of the complicated
1179 mix4left RTL to the first splitting phase. */
1180 rtx tmp = gen_reg_rtx (DImode);
1181 emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1182 DONE;
1183 }
1184 else if (width == 32 && shift == 32)
1185 {
1186 emit_insn (gen_mix4right (operands[0], operands[3]));
1187 DONE;
1188 }
1189
d2ba6dcf
JW
1190 /* We could handle remaining cases by emitting multiple dep
1191 instructions.
1192
1193 If we need more than two dep instructions then we lose. A 6
1194 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1195 mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles,
1196 the latter is 6 cycles on an Itanium (TM) processor, because there is
1197 only one function unit that can execute dep and shr immed.
1198
1199 If we only need two dep instruction, then we still lose.
1200 mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away
1201 the unnecessary mov, this is still undesirable because it will be
1202 hard to optimize, and it creates unnecessary pressure on the I0
1203 function unit. */
1204
c65ebc55
JW
1205 FAIL;
1206
1207#if 0
1208 /* This code may be useful for other IA-64 processors, so we leave it in
1209 for now. */
1210 while (width > 16)
1211 {
1212 rtx tmp;
1213
1214 emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1215 operands[3]));
1216 shift += 16;
1217 width -= 16;
1218 tmp = gen_reg_rtx (DImode);
1219 emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1220 operands[3] = tmp;
1221 }
1222 operands[1] = GEN_INT (width);
1223 operands[2] = GEN_INT (shift);
1224#endif
1225 }
1226}")
1227
1228(define_insn "*insv_internal"
0551c32d 1229 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55
JW
1230 (match_operand:DI 1 "const_int_operand" "n")
1231 (match_operand:DI 2 "const_int_operand" "n"))
1232 (match_operand:DI 3 "nonmemory_operand" "rP"))]
0551c32d 1233 "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
c65ebc55
JW
1234 || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1235 "dep %0 = %3, %0, %2, %1"
1236 [(set_attr "type" "I")])
1237
041f25e6
RH
1238;; Combine doesn't like to create bitfield insertions into zero.
1239(define_insn "*depz_internal"
0551c32d
RH
1240 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1241 (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
041f25e6
RH
1242 (match_operand:DI 2 "const_int_operand" "n"))
1243 (match_operand:DI 3 "const_int_operand" "n")))]
1244 "CONST_OK_FOR_M (INTVAL (operands[2]))
1245 && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1246 "*
1247{
1248 operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1249 return \"%,dep.z %0 = %1, %2, %3\";
1250}"
1251 [(set_attr "type" "I")])
1252
c65ebc55 1253(define_insn "shift_mix4left"
0551c32d 1254 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55 1255 (const_int 32) (const_int 0))
0551c32d
RH
1256 (match_operand:DI 1 "gr_register_operand" "r"))
1257 (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
c65ebc55
JW
1258 ""
1259 "#"
1260 [(set_attr "type" "unknown")])
1261
c65ebc55
JW
1262(define_split
1263 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1264 (const_int 32) (const_int 0))
1265 (match_operand:DI 1 "register_operand" ""))
1266 (clobber (match_operand:DI 2 "register_operand" ""))]
1267 "reload_completed"
1268 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1269 (unspec_volatile [(const_int 0)] 2)
1270 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1271 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1272 "operands[3] = operands[2];")
1273
1274(define_split
1275 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1276 (const_int 32) (const_int 0))
1277 (match_operand:DI 1 "register_operand" ""))
1278 (clobber (match_operand:DI 2 "register_operand" ""))]
1279 "! reload_completed"
1280 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1281 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1282 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1283 "operands[3] = operands[2];")
1284
1285(define_insn "*mix4left"
0551c32d 1286 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55 1287 (const_int 32) (const_int 0))
0551c32d 1288 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
1289 (const_int 32)))]
1290 ""
1291 "mix4.l %0 = %0, %r1"
1292 [(set_attr "type" "I")])
1293
1294(define_insn "mix4right"
0551c32d 1295 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
c65ebc55 1296 (const_int 32) (const_int 32))
0551c32d 1297 (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
c65ebc55
JW
1298 ""
1299 "mix4.r %0 = %r1, %0"
1300 [(set_attr "type" "I")])
1301
1302;; This is used by the rotrsi3 pattern.
1303
1304(define_insn "*mix4right_3op"
0551c32d
RH
1305 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1306 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1307 (ashift:DI (zero_extend:DI
1308 (match_operand:SI 2 "gr_register_operand" "r"))
c65ebc55
JW
1309 (const_int 32))))]
1310 ""
fa9a44e8 1311 "mix4.r %0 = %2, %1"
c65ebc55
JW
1312 [(set_attr "type" "I")])
1313
1314\f
1315;; ::::::::::::::::::::
1316;; ::
1317;; :: 32 bit Integer arithmetic
1318;; ::
1319;; ::::::::::::::::::::
1320
058557c4 1321(define_insn "addsi3"
0551c32d
RH
1322 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1323 (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1324 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
c65ebc55
JW
1325 ""
1326 "@
1327 add %0 = %1, %2
1328 adds %0 = %2, %1
1329 addl %0 = %2, %1"
1330 [(set_attr "type" "A")])
1331
1332(define_insn "*addsi3_plus1"
0551c32d
RH
1333 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1334 (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1335 (match_operand:SI 2 "gr_register_operand" "r"))
c65ebc55
JW
1336 (const_int 1)))]
1337 ""
1338 "add %0 = %1, %2, 1"
1339 [(set_attr "type" "A")])
1340
5527bf14 1341(define_insn "*addsi3_plus1_alt"
0551c32d
RH
1342 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1343 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
5527bf14
RH
1344 (const_int 2))
1345 (const_int 1)))]
1346 ""
1347 "add %0 = %1, %1, 1"
1348 [(set_attr "type" "A")])
1349
058557c4 1350(define_insn "*addsi3_shladd"
0551c32d
RH
1351 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1352 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
058557c4 1353 (match_operand:SI 2 "shladd_operand" "n"))
0551c32d 1354 (match_operand:SI 3 "gr_register_operand" "r")))]
c65ebc55 1355 ""
058557c4
RH
1356 "shladd %0 = %1, %S2, %3"
1357 [(set_attr "type" "A")])
c65ebc55 1358
058557c4 1359(define_insn "subsi3"
0551c32d
RH
1360 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1361 (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1362 (match_operand:SI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1363 ""
1364 "sub %0 = %1, %2"
1365 [(set_attr "type" "A")])
1366
1367(define_insn "*subsi3_minus1"
0551c32d
RH
1368 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1369 (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1370 (match_operand:SI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1371 ""
1372 "sub %0 = %2, %1, 1"
1373 [(set_attr "type" "A")])
1374
c65ebc55
JW
1375;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
1376
058557c4 1377(define_insn "mulsi3"
0551c32d
RH
1378 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1379 (mult:SI (match_operand:SI 1 "fr_register_operand" "f")
13da91fd 1380 (match_operand:SI 2 "nonmemory_operand" "f")))]
c65ebc55
JW
1381 ""
1382 "xma.l %0 = %1, %2, f0%B0"
1383 [(set_attr "type" "F")])
1384
058557c4 1385(define_insn "negsi2"
0551c32d
RH
1386 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1387 (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
c65ebc55
JW
1388 ""
1389 "sub %0 = r0, %1"
1390 [(set_attr "type" "A")])
1391
1392(define_expand "abssi2"
1393 [(set (match_dup 2)
0551c32d
RH
1394 (ge:CC (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
1395 (set (match_operand:SI 0 "gr_register_operand" "")
e5bde68a
RH
1396 (if_then_else:SI (eq:CC (match_dup 2) (const_int 0))
1397 (neg:SI (match_dup 1))
1398 (match_dup 1)))]
c65ebc55
JW
1399 ""
1400 "
1401{
1402 operands[2] = gen_reg_rtx (CCmode);
1403}")
1404
1405(define_expand "sminsi3"
1406 [(set (match_dup 3)
0551c32d
RH
1407 (ge:CC (match_operand:SI 1 "gr_register_operand" "")
1408 (match_operand:SI 2 "gr_register_operand" "")))
1409 (set (match_operand:SI 0 "gr_register_operand" "")
c65ebc55
JW
1410 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1411 (match_dup 2) (match_dup 1)))]
1412 ""
1413 "
1414{
1415 operands[3] = gen_reg_rtx (CCmode);
1416}")
1417
1418(define_expand "smaxsi3"
1419 [(set (match_dup 3)
0551c32d
RH
1420 (ge:CC (match_operand:SI 1 "gr_register_operand" "")
1421 (match_operand:SI 2 "gr_register_operand" "")))
1422 (set (match_operand:SI 0 "gr_register_operand" "")
c65ebc55
JW
1423 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1424 (match_dup 1) (match_dup 2)))]
1425 ""
1426 "
1427{
1428 operands[3] = gen_reg_rtx (CCmode);
1429}")
1430
1431(define_expand "uminsi3"
1432 [(set (match_dup 3)
0551c32d
RH
1433 (geu:CC (match_operand:SI 1 "gr_register_operand" "")
1434 (match_operand:SI 2 "gr_register_operand" "")))
1435 (set (match_operand:SI 0 "gr_register_operand" "")
c65ebc55
JW
1436 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1437 (match_dup 2) (match_dup 1)))]
1438 ""
1439 "
1440{
1441 operands[3] = gen_reg_rtx (CCmode);
1442}")
1443
1444(define_expand "umaxsi3"
1445 [(set (match_dup 3)
0551c32d
RH
1446 (geu:CC (match_operand:SI 1 "gr_register_operand" "")
1447 (match_operand:SI 2 "gr_register_operand" "")))
1448 (set (match_operand:SI 0 "gr_register_operand" "")
c65ebc55
JW
1449 (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
1450 (match_dup 1) (match_dup 2)))]
1451 ""
1452 "
1453{
1454 operands[3] = gen_reg_rtx (CCmode);
1455}")
1456
1457\f
1458;; ::::::::::::::::::::
1459;; ::
1460;; :: 64 bit Integer arithmetic
1461;; ::
1462;; ::::::::::::::::::::
1463
1464(define_insn "adddi3"
0551c32d
RH
1465 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
1466 (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
1467 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
c65ebc55
JW
1468 ""
1469 "@
1470 add %0 = %1, %2
1471 adds %0 = %2, %1
1472 addl %0 = %2, %1"
1473 [(set_attr "type" "A")])
1474
1475(define_insn "*adddi3_plus1"
0551c32d
RH
1476 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1477 (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
1478 (match_operand:DI 2 "gr_register_operand" "r"))
c65ebc55
JW
1479 (const_int 1)))]
1480 ""
1481 "add %0 = %1, %2, 1"
1482 [(set_attr "type" "A")])
1483
5527bf14
RH
1484;; This has some of the same problems as shladd. We let the shladd
1485;; eliminator hack handle it, which results in the 1 being forced into
1486;; a register, but not more ugliness here.
1487(define_insn "*adddi3_plus1_alt"
0551c32d
RH
1488 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1489 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
5527bf14
RH
1490 (const_int 2))
1491 (const_int 1)))]
1492 ""
1493 "add %0 = %1, %1, 1"
1494 [(set_attr "type" "A")])
1495
c65ebc55 1496(define_insn "subdi3"
0551c32d
RH
1497 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1498 (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
1499 (match_operand:DI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1500 ""
1501 "sub %0 = %1, %2"
1502 [(set_attr "type" "A")])
1503
1504(define_insn "*subdi3_minus1"
0551c32d
RH
1505 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1506 (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
1507 (match_operand:DI 2 "gr_register_operand" "r")))]
c65ebc55
JW
1508 ""
1509 "sub %0 = %2, %1, 1"
1510 [(set_attr "type" "A")])
1511
1512(define_insn "muldi3"
0551c32d
RH
1513 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1514 (mult:DI (match_operand:DI 1 "fr_register_operand" "f")
1515 (match_operand:DI 2 "fr_register_operand" "f")))]
c65ebc55
JW
1516 ""
1517 "xma.l %0 = %1, %2, f0%B0"
1518 [(set_attr "type" "F")])
1519
1520;; ??? If operand 3 is an eliminable reg, then register elimination causes the
1521;; same problem that we have with shladd below. Unfortunately, this case is
1522;; much harder to fix because the multiply puts the result in an FP register,
1523;; but the add needs inputs from a general register. We add a spurious clobber
1524;; here so that it will be present just in case register elimination gives us
1525;; the funny result.
1526
1527;; ??? Maybe validate_changes should try adding match_scratch clobbers?
1528
1529;; ??? Maybe we should change how adds are canonicalized.
1530
1531(define_insn "*madddi3"
0551c32d
RH
1532 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1533 (plus:DI (mult:DI (match_operand:DI 1 "fr_register_operand" "f")
1534 (match_operand:DI 2 "fr_register_operand" "f"))
1535 (match_operand:DI 3 "fr_register_operand" "f")))
c65ebc55
JW
1536 (clobber (match_scratch:DI 4 "=X"))]
1537 ""
1538 "xma.l %0 = %1, %2, %3%B0"
1539 [(set_attr "type" "F")])
1540
1541;; This can be created by register elimination if operand3 of shladd is an
1542;; eliminable register or has reg_equiv_constant set.
1543
1544;; We have to use nonmemory_operand for operand 4, to ensure that the
1545;; validate_changes call inside eliminate_regs will always succeed. If it
1546;; doesn't succeed, then this remain a madddi3 pattern, and will be reloaded
1547;; incorrectly.
1548
1549(define_insn "*madddi3_elim"
1550 [(set (match_operand:DI 0 "register_operand" "=&r")
13da91fd
RH
1551 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
1552 (match_operand:DI 2 "register_operand" "f"))
1553 (match_operand:DI 3 "register_operand" "f"))
c65ebc55 1554 (match_operand:DI 4 "nonmemory_operand" "rI")))
13da91fd 1555 (clobber (match_scratch:DI 5 "=f"))]
c65ebc55
JW
1556 "reload_in_progress"
1557 "#"
1558 [(set_attr "type" "unknown")])
1559
1560;; ??? Need to emit an instruction group barrier here because this gets split
1561;; after md_reorg.
1562
1563(define_split
1564 [(set (match_operand:DI 0 "register_operand" "")
1565 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
1566 (match_operand:DI 2 "register_operand" ""))
1567 (match_operand:DI 3 "register_operand" ""))
0551c32d 1568 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
c65ebc55
JW
1569 (clobber (match_scratch:DI 5 ""))]
1570 "reload_completed"
1571 [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
1572 (match_dup 3)))
1573 (clobber (match_dup 0))])
1574 (unspec_volatile [(const_int 0)] 2)
1575 (set (match_dup 0) (match_dup 5))
1576 (unspec_volatile [(const_int 0)] 2)
1577 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
1578 "")
1579
1580;; ??? There are highpart multiply and add instructions, but we have no way
1581;; to generate them.
1582
1583(define_insn "smuldi3_highpart"
0551c32d 1584 [(set (match_operand:DI 0 "fr_register_operand" "=f")
c65ebc55
JW
1585 (truncate:DI
1586 (lshiftrt:TI
0551c32d
RH
1587 (mult:TI (sign_extend:TI
1588 (match_operand:DI 1 "fr_register_operand" "f"))
1589 (sign_extend:TI
1590 (match_operand:DI 2 "fr_register_operand" "f")))
c65ebc55
JW
1591 (const_int 64))))]
1592 ""
1593 "xma.h %0 = %1, %2, f0%B0"
1594 [(set_attr "type" "F")])
1595
1596(define_insn "umuldi3_highpart"
0551c32d 1597 [(set (match_operand:DI 0 "fr_register_operand" "=f")
c65ebc55
JW
1598 (truncate:DI
1599 (lshiftrt:TI
0551c32d
RH
1600 (mult:TI (zero_extend:TI
1601 (match_operand:DI 1 "fr_register_operand" "f"))
1602 (zero_extend:TI
1603 (match_operand:DI 2 "fr_register_operand" "f")))
c65ebc55
JW
1604 (const_int 64))))]
1605 ""
1606 "xma.hu %0 = %1, %2, f0%B0"
1607 [(set_attr "type" "F")])
1608
1609(define_insn "negdi2"
0551c32d
RH
1610 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1611 (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
c65ebc55
JW
1612 ""
1613 "sub %0 = r0, %1"
1614 [(set_attr "type" "A")])
1615
1616(define_expand "absdi2"
1617 [(set (match_dup 2)
0551c32d
RH
1618 (ge:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
1619 (set (match_operand:DI 0 "gr_register_operand" "")
e5bde68a
RH
1620 (if_then_else:DI (eq:CC (match_dup 2) (const_int 0))
1621 (neg:DI (match_dup 1))
1622 (match_dup 1)))]
c65ebc55
JW
1623 ""
1624 "
1625{
1626 operands[2] = gen_reg_rtx (CCmode);
1627}")
1628
1629(define_expand "smindi3"
1630 [(set (match_dup 3)
0551c32d
RH
1631 (ge:CC (match_operand:DI 1 "gr_register_operand" "")
1632 (match_operand:DI 2 "gr_register_operand" "")))
1633 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1634 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1635 (match_dup 2) (match_dup 1)))]
1636 ""
1637 "
1638{
1639 operands[3] = gen_reg_rtx (CCmode);
1640}")
1641
1642(define_expand "smaxdi3"
1643 [(set (match_dup 3)
0551c32d
RH
1644 (ge:CC (match_operand:DI 1 "gr_register_operand" "")
1645 (match_operand:DI 2 "gr_register_operand" "")))
1646 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1647 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1648 (match_dup 1) (match_dup 2)))]
1649 ""
1650 "
1651{
1652 operands[3] = gen_reg_rtx (CCmode);
1653}")
1654
1655(define_expand "umindi3"
1656 [(set (match_dup 3)
0551c32d
RH
1657 (geu:CC (match_operand:DI 1 "gr_register_operand" "")
1658 (match_operand:DI 2 "gr_register_operand" "")))
1659 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1660 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1661 (match_dup 2) (match_dup 1)))]
1662 ""
1663 "
1664{
1665 operands[3] = gen_reg_rtx (CCmode);
1666}")
1667
1668(define_expand "umaxdi3"
1669 [(set (match_dup 3)
0551c32d
RH
1670 (geu:CC (match_operand:DI 1 "gr_register_operand" "")
1671 (match_operand:DI 2 "gr_register_operand" "")))
1672 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1673 (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
1674 (match_dup 1) (match_dup 2)))]
1675 ""
1676 "
1677{
1678 operands[3] = gen_reg_rtx (CCmode);
1679}")
1680
1681(define_expand "ffsdi2"
1682 [(set (match_dup 6)
0551c32d 1683 (eq:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
c65ebc55
JW
1684 (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
1685 (set (match_dup 5) (const_int 0))
1686 (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
1687 (set (match_dup 4) (unspec:DI [(match_dup 3)] 8))
0551c32d 1688 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
1689 (if_then_else:DI (ne:CC (match_dup 6) (const_int 0))
1690 (match_dup 5) (match_dup 4)))]
1691 ""
1692 "
1693{
1694 operands[2] = gen_reg_rtx (DImode);
1695 operands[3] = gen_reg_rtx (DImode);
1696 operands[4] = gen_reg_rtx (DImode);
1697 operands[5] = gen_reg_rtx (DImode);
1698 operands[6] = gen_reg_rtx (CCmode);
1699}")
1700
1701(define_insn "*popcnt"
0551c32d
RH
1702 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1703 (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")] 8))]
c65ebc55
JW
1704 ""
1705 "popcnt %0 = %1"
1706 [(set_attr "type" "I")])
1707
1708\f
1709;; ::::::::::::::::::::
1710;; ::
1711;; :: 32 bit floating point arithmetic
1712;; ::
1713;; ::::::::::::::::::::
1714
1715(define_insn "addsf3"
0551c32d
RH
1716 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1717 (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
1718 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1719 ""
1720 "fadd.s %0 = %1, %F2%B0"
1721 [(set_attr "type" "F")])
1722
1723(define_insn "subsf3"
0551c32d
RH
1724 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1725 (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
1726 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1727 ""
1728 "fsub.s %0 = %F1, %F2%B0"
1729 [(set_attr "type" "F")])
1730
1731(define_insn "mulsf3"
0551c32d
RH
1732 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1733 (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
1734 (match_operand:SF 2 "fr_register_operand" "f")))]
c65ebc55
JW
1735 ""
1736 "fmpy.s %0 = %1, %2%B0"
1737 [(set_attr "type" "F")])
1738
1739(define_insn "abssf2"
0551c32d
RH
1740 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1741 (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1742 ""
1743 "fabs %0 = %1%B0"
1744 [(set_attr "type" "F")])
1745
1746(define_insn "negsf2"
0551c32d
RH
1747 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1748 (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1749 ""
1750 "fneg %0 = %1%B0"
1751 [(set_attr "type" "F")])
1752
1753(define_insn "*nabssf2"
0551c32d
RH
1754 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1755 (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
c65ebc55
JW
1756 ""
1757 "fnegabs %0 = %1%B0"
1758 [(set_attr "type" "F")])
1759
1760(define_insn "minsf3"
0551c32d
RH
1761 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1762 (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
1763 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1764 ""
1765 "fmin %0 = %1, %F2%B0"
1766 [(set_attr "type" "F")])
1767
1768(define_insn "maxsf3"
0551c32d
RH
1769 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1770 (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
1771 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1772 ""
1773 "fmax %0 = %1, %F2%B0"
1774 [(set_attr "type" "F")])
1775
1776(define_insn "*maddsf3"
0551c32d
RH
1777 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1778 (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1779 (match_operand:SF 2 "fr_register_operand" "f"))
1780 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1781 ""
1782 "fma.s %0 = %1, %2, %F3%B0"
1783 [(set_attr "type" "F")])
1784
1785(define_insn "*msubsf3"
0551c32d
RH
1786 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1787 (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1788 (match_operand:SF 2 "fr_register_operand" "f"))
1789 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1790 ""
1791 "fms.s %0 = %1, %2, %F3%B0"
1792 [(set_attr "type" "F")])
1793
1794(define_insn "*nmulsf3"
0551c32d
RH
1795 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1796 (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1797 (match_operand:SF 2 "fr_register_operand" "f"))))]
c65ebc55
JW
1798 ""
1799 "fnmpy.s %0 = %1, %2%B0"
1800 [(set_attr "type" "F")])
1801
1802;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
1803
1804(define_insn "*nmaddsf3"
0551c32d
RH
1805 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1806 (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
1807 (match_operand:SF 2 "fr_register_operand" "f")))
1808 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1809 ""
1810 "fnma.s %0 = %1, %2, %F3%B0"
1811 [(set_attr "type" "F")])
1812
1813\f
1814;; ::::::::::::::::::::
1815;; ::
1816;; :: 64 bit floating point arithmetic
1817;; ::
1818;; ::::::::::::::::::::
1819
1820(define_insn "adddf3"
0551c32d
RH
1821 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1822 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
1823 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1824 ""
1825 "fadd.d %0 = %1, %F2%B0"
1826 [(set_attr "type" "F")])
1827
1828(define_insn "subdf3"
0551c32d
RH
1829 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1830 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
1831 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1832 ""
1833 "fsub.d %0 = %F1, %F2%B0"
1834 [(set_attr "type" "F")])
1835
1836(define_insn "muldf3"
0551c32d
RH
1837 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1838 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1839 (match_operand:DF 2 "fr_register_operand" "f")))]
c65ebc55
JW
1840 ""
1841 "fmpy.d %0 = %1, %2%B0"
1842 [(set_attr "type" "F")])
1843
1844(define_insn "absdf2"
0551c32d
RH
1845 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1846 (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1847 ""
1848 "fabs %0 = %1%B0"
1849 [(set_attr "type" "F")])
1850
1851(define_insn "negdf2"
0551c32d
RH
1852 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1853 (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
c65ebc55
JW
1854 ""
1855 "fneg %0 = %1%B0"
1856 [(set_attr "type" "F")])
1857
1858(define_insn "*nabsdf2"
0551c32d
RH
1859 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1860 (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
c65ebc55
JW
1861 ""
1862 "fnegabs %0 = %1%B0"
1863 [(set_attr "type" "F")])
1864
1865(define_insn "mindf3"
0551c32d
RH
1866 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1867 (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
1868 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1869 ""
1870 "fmin %0 = %1, %F2%B0"
1871 [(set_attr "type" "F")])
1872
1873(define_insn "maxdf3"
0551c32d
RH
1874 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1875 (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
1876 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1877 ""
1878 "fmax %0 = %1, %F2%B0"
1879 [(set_attr "type" "F")])
1880
1881(define_insn "*madddf3"
0551c32d
RH
1882 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1883 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1884 (match_operand:DF 2 "fr_register_operand" "f"))
1885 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1886 ""
1887 "fma.d %0 = %1, %2, %F3%B0"
1888 [(set_attr "type" "F")])
1889
1890(define_insn "*msubdf3"
0551c32d
RH
1891 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1892 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1893 (match_operand:DF 2 "fr_register_operand" "f"))
1894 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1895 ""
1896 "fms.d %0 = %1, %2, %F3%B0"
1897 [(set_attr "type" "F")])
1898
1899(define_insn "*nmuldf3"
0551c32d
RH
1900 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1901 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1902 (match_operand:DF 2 "fr_register_operand" "f"))))]
c65ebc55
JW
1903 ""
1904 "fnmpy.d %0 = %1, %2%B0"
1905 [(set_attr "type" "F")])
1906
1907;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
1908
1909(define_insn "*nmadddf3"
0551c32d
RH
1910 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1911 (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
1912 (match_operand:DF 2 "fr_register_operand" "f")))
1913 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
c65ebc55
JW
1914 ""
1915 "fnma.d %0 = %1, %2, %F3%B0"
1916 [(set_attr "type" "F")])
3f622353
RH
1917\f
1918;; ::::::::::::::::::::
1919;; ::
1920;; :: 80 bit floating point arithmetic
1921;; ::
1922;; ::::::::::::::::::::
1923
1924(define_insn "addtf3"
0551c32d 1925 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1926 (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1927 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1928 ""
1929 "fadd %0 = %F1, %F2%B0"
1930 [(set_attr "type" "F")])
1931
1932(define_insn "subtf3"
0551c32d 1933 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1934 (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1935 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1936 ""
1937 "fsub %0 = %F1, %F2%B0"
1938 [(set_attr "type" "F")])
1939
1940(define_insn "multf3"
0551c32d 1941 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1942 (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1943 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1944 ""
1945 "fmpy %0 = %F1, %F2%B0"
1946 [(set_attr "type" "F")])
1947
1948(define_insn "abstf2"
0551c32d 1949 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1950 (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
1951 ""
1952 "fabs %0 = %F1%B0"
1953 [(set_attr "type" "F")])
1954
1955(define_insn "negtf2"
0551c32d 1956 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1957 (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
1958 ""
1959 "fneg %0 = %F1%B0"
1960 [(set_attr "type" "F")])
1961
1962(define_insn "*nabstf2"
0551c32d 1963 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1964 (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
1965 ""
1966 "fnegabs %0 = %F1%B0"
1967 [(set_attr "type" "F")])
1968
1969(define_insn "mintf3"
0551c32d 1970 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1971 (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1972 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1973 ""
1974 "fmin %0 = %F1, %F2%B0"
1975 [(set_attr "type" "F")])
1976
1977(define_insn "maxtf3"
0551c32d 1978 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1979 (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1980 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
1981 ""
1982 "fmax %0 = %F1, %F2%B0"
1983 [(set_attr "type" "F")])
1984
1985(define_insn "*maddtf3"
0551c32d 1986 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1987 (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1988 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
1989 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
1990 ""
1991 "fma %0 = %F1, %F2, %F3%B0"
1992 [(set_attr "type" "F")])
1993
1994(define_insn "*msubtf3"
0551c32d 1995 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
1996 (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
1997 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
1998 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
1999 ""
2000 "fms %0 = %F1, %F2, %F3%B0"
2001 [(set_attr "type" "F")])
2002
2003(define_insn "*nmultf3"
0551c32d 2004 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
2005 (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2006 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
2007 ""
2008 "fnmpy %0 = %F1, %F2%B0"
2009 [(set_attr "type" "F")])
c65ebc55 2010
3f622353
RH
2011;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2012
2013(define_insn "*nmaddtf3"
0551c32d 2014 [(set (match_operand:TF 0 "fr_register_operand" "=f")
3f622353
RH
2015 (plus:TF (neg:TF (mult:TF
2016 (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
2017 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
2018 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
2019 ""
2020 "fnma %0 = %F1, %F2, %F3%B0"
2021 [(set_attr "type" "F")])
c65ebc55
JW
2022\f
2023;; ::::::::::::::::::::
2024;; ::
2025;; :: 32 bit Integer Shifts and Rotates
2026;; ::
2027;; ::::::::::::::::::::
2028
9c668921 2029(define_expand "ashlsi3"
0551c32d
RH
2030 [(set (match_operand:SI 0 "gr_register_operand" "")
2031 (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
2032 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
9c668921
RH
2033 ""
2034 "
2035{
2036 if (GET_CODE (operands[2]) != CONST_INT)
2037 {
2038 /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now
2039 we've got to get rid of stray bits outside the SImode register. */
2040 rtx subshift = gen_reg_rtx (DImode);
2041 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2042 operands[2] = subshift;
2043 }
2044}")
2045
2046(define_insn "*ashlsi3_internal"
0551c32d
RH
2047 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
2048 (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
2049 (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
c65ebc55 2050 ""
041f25e6
RH
2051 "@
2052 shladd %0 = %1, %2, r0
2053 dep.z %0 = %1, %2, %E2
2054 shl %0 = %1, %2"
2055 [(set_attr "type" "A,I,I")])
c65ebc55
JW
2056
2057(define_expand "ashrsi3"
0551c32d
RH
2058 [(set (match_operand:SI 0 "gr_register_operand" "")
2059 (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
2060 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
c65ebc55
JW
2061 ""
2062 "
2063{
041f25e6
RH
2064 rtx subtarget = gen_reg_rtx (DImode);
2065 if (GET_CODE (operands[2]) == CONST_INT)
2066 emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
2067 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
2068 else
2069 {
9c668921 2070 rtx subshift = gen_reg_rtx (DImode);
041f25e6 2071 emit_insn (gen_extendsidi2 (subtarget, operands[1]));
9c668921
RH
2072 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2073 emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
041f25e6
RH
2074 }
2075 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
2076 DONE;
c65ebc55
JW
2077}")
2078
c65ebc55 2079(define_expand "lshrsi3"
0551c32d
RH
2080 [(set (match_operand:SI 0 "gr_register_operand" "")
2081 (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
2082 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
c65ebc55
JW
2083 ""
2084 "
2085{
041f25e6
RH
2086 rtx subtarget = gen_reg_rtx (DImode);
2087 if (GET_CODE (operands[2]) == CONST_INT)
2088 emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
2089 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
2090 else
2091 {
9c668921 2092 rtx subshift = gen_reg_rtx (DImode);
041f25e6 2093 emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
9c668921
RH
2094 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
2095 emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
041f25e6
RH
2096 }
2097 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
2098 DONE;
c65ebc55
JW
2099}")
2100
c65ebc55
JW
2101;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
2102;; here, instead of 64 like the patterns above.
2103
2104(define_expand "rotrsi3"
2105 [(set (match_dup 3)
0551c32d 2106 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" ""))
c65ebc55
JW
2107 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
2108 (set (match_dup 3)
2109 (lshiftrt:DI (match_dup 3)
2110 (match_operand:DI 2 "nonmemory_operand" "")))
0551c32d 2111 (set (match_operand:SI 0 "gr_register_operand" "") (match_dup 4))]
c65ebc55
JW
2112 ""
2113 "
2114{
2115 if (! shift_32bit_count_operand (operands[2], SImode))
2116 FAIL;
c65ebc55
JW
2117 operands[3] = gen_reg_rtx (DImode);
2118 operands[4] = gen_lowpart (SImode, operands[3]);
2119}")
c65ebc55
JW
2120\f
2121;; ::::::::::::::::::::
2122;; ::
2123;; :: 64 bit Integer Shifts and Rotates
2124;; ::
2125;; ::::::::::::::::::::
2126
2127(define_insn "ashldi3"
0551c32d
RH
2128 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
2129 (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r")
2130 (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,rM")))]
c65ebc55 2131 ""
041f25e6
RH
2132 "@
2133 shladd %0 = %1, %2, r0
2134 shl %0 = %1, %2"
2135 [(set_attr "type" "A,I")])
c65ebc55
JW
2136
2137;; ??? Maybe combine this with the multiply and add instruction?
2138
2139(define_insn "*shladd"
0551c32d
RH
2140 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2141 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55 2142 (match_operand:DI 2 "shladd_operand" "n"))
0551c32d 2143 (match_operand:DI 3 "gr_register_operand" "r")))]
c65ebc55
JW
2144 ""
2145 "shladd %0 = %1, %S2, %3"
2146 [(set_attr "type" "A")])
2147
2148;; This can be created by register elimination if operand3 of shladd is an
2149;; eliminable register or has reg_equiv_constant set.
2150
2151;; We have to use nonmemory_operand for operand 4, to ensure that the
2152;; validate_changes call inside eliminate_regs will always succeed. If it
2153;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
2154;; incorrectly.
2155
5527bf14 2156(define_insn_and_split "*shladd_elim"
0551c32d
RH
2157 [(set (match_operand:DI 0 "gr_register_operand" "=&r")
2158 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55 2159 (match_operand:DI 2 "shladd_operand" "n"))
5527bf14 2160 (match_operand:DI 3 "nonmemory_operand" "r"))
c65ebc55
JW
2161 (match_operand:DI 4 "nonmemory_operand" "rI")))]
2162 "reload_in_progress"
5527bf14 2163 "* abort ();"
c65ebc55
JW
2164 "reload_completed"
2165 [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2166 (match_dup 3)))
c65ebc55 2167 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
5527bf14
RH
2168 ""
2169 [(set_attr "type" "unknown")])
c65ebc55
JW
2170
2171(define_insn "ashrdi3"
0551c32d
RH
2172 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2173 (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
2174 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
c65ebc55
JW
2175 ""
2176 "shr %0 = %1, %2"
2177 [(set_attr "type" "I")])
2178
2179(define_insn "lshrdi3"
0551c32d
RH
2180 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2181 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
2182 (match_operand:DI 2 "gr_reg_or_6bit_operand" "rM")))]
c65ebc55
JW
2183 ""
2184 "shr.u %0 = %1, %2"
2185 [(set_attr "type" "I")])
2186
2187;; Using a predicate that accepts only constants doesn't work, because optabs
2188;; will load the operand into a register and call the pattern if the predicate
2189;; did not accept it on the first try. So we use nonmemory_operand and then
2190;; verify that we have an appropriate constant in the expander.
2191
2192(define_expand "rotrdi3"
0551c32d
RH
2193 [(set (match_operand:DI 0 "gr_register_operand" "")
2194 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
c65ebc55
JW
2195 (match_operand:DI 2 "nonmemory_operand" "")))]
2196 ""
2197 "
2198{
2199 if (! shift_count_operand (operands[2], DImode))
2200 FAIL;
2201}")
2202
2203(define_insn "*rotrdi3_internal"
0551c32d
RH
2204 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2205 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
2206 (match_operand:DI 2 "shift_count_operand" "M")))]
2207 ""
2208 "shrp %0 = %1, %1, %2"
2209 [(set_attr "type" "I")])
2210
2211\f
2212;; ::::::::::::::::::::
2213;; ::
058557c4 2214;; :: 32 bit Integer Logical operations
c65ebc55
JW
2215;; ::
2216;; ::::::::::::::::::::
2217
2218;; We don't seem to need any other 32-bit logical operations, because gcc
2219;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
2220;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
2221;; This doesn't work for unary logical operations, because we don't call
2222;; apply_distributive_law for them.
2223
2224;; ??? Likewise, this doesn't work for andnot, which isn't handled by
2225;; apply_distributive_law. We get inefficient code for
2226;; int sub4 (int i, int j) { return i & ~j; }
2227;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
2228;; (zero_extend (and (not A) B)) in combine.
2229;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
2230;; one_cmplsi2 pattern.
2231
058557c4 2232(define_insn "one_cmplsi2"
0551c32d
RH
2233 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2234 (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
c65ebc55
JW
2235 ""
2236 "andcm %0 = -1, %1"
2237 [(set_attr "type" "A")])
c65ebc55
JW
2238\f
2239;; ::::::::::::::::::::
2240;; ::
058557c4 2241;; :: 64 bit Integer Logical operations
c65ebc55
JW
2242;; ::
2243;; ::::::::::::::::::::
2244
2245(define_insn "anddi3"
0551c32d
RH
2246 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2247 (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2248 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
2249 ""
2250 "@
2251 and %0 = %2, %1
2252 fand %0 = %2, %1%B0"
2253 [(set_attr "type" "A,F")])
2254
2255(define_insn "*andnot"
0551c32d
RH
2256 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2257 (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
2258 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
2259 ""
2260 "@
2261 andcm %0 = %2, %1
2262 fandcm %0 = %2, %1%B0"
2263 [(set_attr "type" "A,F")])
2264
2265(define_insn "iordi3"
0551c32d
RH
2266 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2267 (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2268 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
2269 ""
2270 "@
2271 or %0 = %2, %1
2272 for %0 = %2, %1%B0"
2273 [(set_attr "type" "A,F")])
2274
2275(define_insn "xordi3"
0551c32d
RH
2276 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
2277 (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
2278 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
c65ebc55
JW
2279 ""
2280 "@
2281 xor %0 = %2, %1
2282 fxor %0 = %2, %1%B0"
2283 [(set_attr "type" "A,F")])
2284
2285(define_insn "one_cmpldi2"
0551c32d
RH
2286 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2287 (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
c65ebc55
JW
2288 ""
2289 "andcm %0 = -1, %1"
2290 [(set_attr "type" "A")])
2291\f
2292;; ::::::::::::::::::::
2293;; ::
2294;; :: Comparisons
2295;; ::
2296;; ::::::::::::::::::::
2297
2298(define_expand "cmpsi"
2299 [(set (cc0)
0551c32d
RH
2300 (compare (match_operand:SI 0 "gr_register_operand" "")
2301 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
c65ebc55
JW
2302 ""
2303 "
2304{
2305 ia64_compare_op0 = operands[0];
2306 ia64_compare_op1 = operands[1];
2307 DONE;
2308}")
2309
2310(define_expand "cmpdi"
2311 [(set (cc0)
0551c32d
RH
2312 (compare (match_operand:DI 0 "gr_register_operand" "")
2313 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
c65ebc55
JW
2314 ""
2315 "
2316{
2317 ia64_compare_op0 = operands[0];
2318 ia64_compare_op1 = operands[1];
2319 DONE;
2320}")
2321
2322(define_expand "cmpsf"
2323 [(set (cc0)
0551c32d
RH
2324 (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
2325 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
c65ebc55
JW
2326 ""
2327 "
2328{
2329 ia64_compare_op0 = operands[0];
2330 ia64_compare_op1 = operands[1];
2331 DONE;
2332}")
2333
2334(define_expand "cmpdf"
2335 [(set (cc0)
0551c32d
RH
2336 (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
2337 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
c65ebc55
JW
2338 ""
2339 "
2340{
2341 ia64_compare_op0 = operands[0];
2342 ia64_compare_op1 = operands[1];
2343 DONE;
2344}")
2345
3f622353 2346(define_expand "cmptf"
c65ebc55 2347 [(set (cc0)
3f622353
RH
2348 (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
2349 (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
2350 ""
c65ebc55
JW
2351 "
2352{
2353 ia64_compare_op0 = operands[0];
2354 ia64_compare_op1 = operands[1];
2355 DONE;
2356}")
2357
2358(define_insn "*cmpsi_normal"
2359 [(set (match_operand:CC 0 "register_operand" "=c")
2360 (match_operator:CC 1 "normal_comparison_operator"
0551c32d
RH
2361 [(match_operand:SI 2 "gr_register_operand" "r")
2362 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
c65ebc55
JW
2363 ""
2364 "cmp4.%C1 %0, %I0 = %3, %2"
2365 [(set_attr "type" "A")])
2366
2367(define_insn "*cmpsi_adjusted"
2368 [(set (match_operand:CC 0 "register_operand" "=c")
2369 (match_operator:CC 1 "adjusted_comparison_operator"
0551c32d
RH
2370 [(match_operand:SI 2 "gr_register_operand" "r")
2371 (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
c65ebc55
JW
2372 ""
2373 "cmp4.%C1 %0, %I0 = %3, %2"
2374 [(set_attr "type" "A")])
2375
2376(define_insn "*cmpdi_normal"
2377 [(set (match_operand:CC 0 "register_operand" "=c")
2378 (match_operator:CC 1 "normal_comparison_operator"
0551c32d
RH
2379 [(match_operand:DI 2 "gr_register_operand" "r")
2380 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
c65ebc55
JW
2381 ""
2382 "cmp.%C1 %0, %I0 = %3, %2"
2383 [(set_attr "type" "A")])
2384
2385(define_insn "*cmpdi_adjusted"
2386 [(set (match_operand:CC 0 "register_operand" "=c")
2387 (match_operator:CC 1 "adjusted_comparison_operator"
0551c32d
RH
2388 [(match_operand:DI 2 "gr_register_operand" "r")
2389 (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
c65ebc55
JW
2390 ""
2391 "cmp.%C1 %0, %I0 = %3, %2"
2392 [(set_attr "type" "A")])
2393
2394(define_insn "*cmpsf_internal"
2395 [(set (match_operand:CC 0 "register_operand" "=c")
2396 (match_operator:CC 1 "comparison_operator"
0551c32d
RH
2397 [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
2398 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
c65ebc55
JW
2399 ""
2400 "fcmp.%D1 %0, %I0 = %F2, %F3"
2401 [(set_attr "type" "F")])
2402
2403(define_insn "*cmpdf_internal"
2404 [(set (match_operand:CC 0 "register_operand" "=c")
2405 (match_operator:CC 1 "comparison_operator"
0551c32d
RH
2406 [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
2407 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
c65ebc55
JW
2408 ""
2409 "fcmp.%D1 %0, %I0 = %F2, %F3"
2410 [(set_attr "type" "F")])
2411
3f622353
RH
2412(define_insn "*cmptf_internal"
2413 [(set (match_operand:CC 0 "register_operand" "=c")
2414 (match_operator:CC 1 "comparison_operator"
2415 [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
2416 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
2417 ""
2418 "fcmp.%D1 %0, %I0 = %F2, %F3"
2419 [(set_attr "type" "F")])
2420
c65ebc55
JW
2421;; ??? Can this pattern be generated?
2422
2423(define_insn "*bit_zero"
2424 [(set (match_operand:CC 0 "register_operand" "=c")
0551c32d 2425 (eq:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
2426 (const_int 1)
2427 (match_operand:DI 2 "immediate_operand" "n"))
2428 (const_int 0)))]
2429 ""
2430 "tbit.z %0, %I0 = %1, %2"
2431 [(set_attr "type" "I")])
2432
2433(define_insn "*bit_one"
2434 [(set (match_operand:CC 0 "register_operand" "=c")
0551c32d 2435 (ne:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
c65ebc55
JW
2436 (const_int 1)
2437 (match_operand:DI 2 "immediate_operand" "n"))
2438 (const_int 0)))]
2439 ""
2440 "tbit.nz %0, %I0 = %1, %2"
2441 [(set_attr "type" "I")])
2442
2443;; ??? We also need this if we run out of PR regs and need to spill some.
2444
2445;; ??? We need this if a CCmode value does not get allocated to a hard
2446;; register. This happens if we cse/gcse a CCmode value across a call, and the
2447;; function has a nonlocal goto. This is because global does not allocate
2448;; call crossing pseudos to hard registers when current_function_has_
2449;; nonlocal_goto is true. This is relatively common for C++ programs that
2450;; use exceptions. See ia64_secondary_reload_class.
2451
2452;; We use a define_expand here so that cse/gcse/combine can't accidentally
2453;; create movcc insns. If this was a named define_insn, we would not be able
2454;; to make it conditional on reload.
2455
2456(define_expand "movcc"
2457 [(set (match_operand:CC 0 "nonimmediate_operand" "")
2458 (match_operand:CC 1 "move_operand" ""))]
2459 ""
2460 "
2461{
2462 if (! reload_in_progress && ! reload_completed)
2463 FAIL;
2464}")
2465
2466(define_insn "*movcc_internal"
2467 [(set (match_operand:CC 0 "nonimmediate_operand" "=r,c,r,m")
2468 (match_operand:CC 1 "move_operand" "c,r,m,r"))]
2469 "reload_in_progress || reload_completed"
2470 "@
2471 #
2472 cmp4.ne %0, %I0 = %1, r0
2473 ld4%O1 %0 = %1%P1
2474 st4%Q0 %0 = %1%P0"
2475 [(set_attr "type" "unknown,A,M,M")])
2476
2477(define_split
2478 [(set (match_operand:CC 0 "register_operand" "")
2479 (match_operand:CC 1 "register_operand" ""))]
2480 "reload_completed
2481 && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
2482 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
2483 [(set (match_dup 2)
2484 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2485 (const_int 1)
2486 (match_dup 2)))
2487 (set (match_dup 2)
2488 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2489 (match_dup 2)
2490 (const_int 0)))]
2491 "operands[2] = gen_rtx_SUBREG (DImode, operands[0], 0);")
2492
2493\f
2494;; ::::::::::::::::::::
2495;; ::
2496;; :: Branches
2497;; ::
2498;; ::::::::::::::::::::
2499
2500(define_expand "beq"
2501 [(set (match_dup 1)
2502 (eq:CC (match_dup 2)
2503 (match_dup 3)))
2504 (set (pc)
2505 (if_then_else (ne:CC (match_dup 1)
2506 (const_int 0))
2507 (label_ref (match_operand 0 "" ""))
2508 (pc)))]
2509 ""
2510 "
2511{
2512 operands[1] = gen_reg_rtx (CCmode);
2513 operands[2] = ia64_compare_op0;
2514 operands[3] = ia64_compare_op1;
2515}")
2516
2517(define_expand "bne"
2518 [(set (match_dup 1)
2519 (ne:CC (match_dup 2)
2520 (match_dup 3)))
2521 (set (pc)
2522 (if_then_else (ne:CC (match_dup 1)
2523 (const_int 0))
2524 (label_ref (match_operand 0 "" ""))
2525 (pc)))]
2526 ""
2527 "
2528{
2529 operands[1] = gen_reg_rtx (CCmode);
2530 operands[2] = ia64_compare_op0;
2531 operands[3] = ia64_compare_op1;
2532}")
2533
2534(define_expand "blt"
2535 [(set (match_dup 1)
2536 (lt:CC (match_dup 2)
2537 (match_dup 3)))
2538 (set (pc)
2539 (if_then_else (ne:CC (match_dup 1)
2540 (const_int 0))
2541 (label_ref (match_operand 0 "" ""))
2542 (pc)))]
2543 ""
2544 "
2545{
2546 operands[1] = gen_reg_rtx (CCmode);
2547 operands[2] = ia64_compare_op0;
2548 operands[3] = ia64_compare_op1;
2549}")
2550
2551(define_expand "ble"
2552 [(set (match_dup 1)
2553 (le:CC (match_dup 2)
2554 (match_dup 3)))
2555 (set (pc)
2556 (if_then_else (ne:CC (match_dup 1)
2557 (const_int 0))
2558 (label_ref (match_operand 0 "" ""))
2559 (pc)))]
2560 ""
2561 "
2562{
2563 operands[1] = gen_reg_rtx (CCmode);
2564 operands[2] = ia64_compare_op0;
2565 operands[3] = ia64_compare_op1;
2566}")
2567
2568(define_expand "bgt"
2569 [(set (match_dup 1)
2570 (gt:CC (match_dup 2)
2571 (match_dup 3)))
2572 (set (pc)
2573 (if_then_else (ne:CC (match_dup 1)
2574 (const_int 0))
2575 (label_ref (match_operand 0 "" ""))
2576 (pc)))]
2577 ""
2578 "
2579{
2580 operands[1] = gen_reg_rtx (CCmode);
2581 operands[2] = ia64_compare_op0;
2582 operands[3] = ia64_compare_op1;
2583}")
2584
2585(define_expand "bge"
2586 [(set (match_dup 1)
2587 (ge:CC (match_dup 2)
2588 (match_dup 3)))
2589 (set (pc)
2590 (if_then_else (ne:CC (match_dup 1)
2591 (const_int 0))
2592 (label_ref (match_operand 0 "" ""))
2593 (pc)))]
2594 ""
2595 "
2596{
2597 operands[1] = gen_reg_rtx (CCmode);
2598 operands[2] = ia64_compare_op0;
2599 operands[3] = ia64_compare_op1;
2600}")
2601
2602(define_expand "bltu"
2603 [(set (match_dup 1)
2604 (ltu:CC (match_dup 2)
2605 (match_dup 3)))
2606 (set (pc)
2607 (if_then_else (ne:CC (match_dup 1)
2608 (const_int 0))
2609 (label_ref (match_operand 0 "" ""))
2610 (pc)))]
2611 ""
2612 "
2613{
2614 operands[1] = gen_reg_rtx (CCmode);
2615 operands[2] = ia64_compare_op0;
2616 operands[3] = ia64_compare_op1;
2617}")
2618
2619(define_expand "bleu"
2620 [(set (match_dup 1)
2621 (leu:CC (match_dup 2)
2622 (match_dup 3)))
2623 (set (pc)
2624 (if_then_else (ne:CC (match_dup 1)
2625 (const_int 0))
2626 (label_ref (match_operand 0 "" ""))
2627 (pc)))]
2628 ""
2629 "
2630{
2631 operands[1] = gen_reg_rtx (CCmode);
2632 operands[2] = ia64_compare_op0;
2633 operands[3] = ia64_compare_op1;
2634}")
2635
2636(define_expand "bgtu"
2637 [(set (match_dup 1)
2638 (gtu:CC (match_dup 2)
2639 (match_dup 3)))
2640 (set (pc)
2641 (if_then_else (ne:CC (match_dup 1)
2642 (const_int 0))
2643 (label_ref (match_operand 0 "" ""))
2644 (pc)))]
2645 ""
2646 "
2647{
2648 operands[1] = gen_reg_rtx (CCmode);
2649 operands[2] = ia64_compare_op0;
2650 operands[3] = ia64_compare_op1;
2651}")
2652
2653(define_expand "bgeu"
2654 [(set (match_dup 1)
2655 (geu:CC (match_dup 2)
2656 (match_dup 3)))
2657 (set (pc)
2658 (if_then_else (ne:CC (match_dup 1)
2659 (const_int 0))
2660 (label_ref (match_operand 0 "" ""))
2661 (pc)))]
2662 ""
2663 "
2664{
2665 operands[1] = gen_reg_rtx (CCmode);
2666 operands[2] = ia64_compare_op0;
2667 operands[3] = ia64_compare_op1;
2668}")
2669
e57b9d65
RH
2670(define_expand "bunordered"
2671 [(set (match_dup 1)
2672 (unordered:CC (match_dup 2)
2673 (match_dup 3)))
2674 (set (pc)
2675 (if_then_else (ne:CC (match_dup 1)
2676 (const_int 0))
2677 (label_ref (match_operand 0 "" ""))
2678 (pc)))]
2679 ""
2680 "
2681{
2682 operands[1] = gen_reg_rtx (CCmode);
2683 operands[2] = ia64_compare_op0;
2684 operands[3] = ia64_compare_op1;
2685}")
2686
2687(define_expand "bordered"
2688 [(set (match_dup 1)
2689 (ordered:CC (match_dup 2)
2690 (match_dup 3)))
2691 (set (pc)
2692 (if_then_else (ne:CC (match_dup 1)
2693 (const_int 0))
2694 (label_ref (match_operand 0 "" ""))
2695 (pc)))]
2696 ""
2697 "
2698{
2699 operands[1] = gen_reg_rtx (CCmode);
2700 operands[2] = ia64_compare_op0;
2701 operands[3] = ia64_compare_op1;
2702}")
2703
6b6c1201 2704(define_insn "*br_true"
c65ebc55 2705 [(set (pc)
6b6c1201
RH
2706 (if_then_else (match_operator 0 "predicate_operator"
2707 [(match_operand:CC 1 "register_operand" "c")
2708 (const_int 0)])
2709 (label_ref (match_operand 2 "" ""))
c65ebc55
JW
2710 (pc)))]
2711 ""
85548039 2712 "(%J0) br.cond%+ %l2"
e5bde68a
RH
2713 [(set_attr "type" "B")
2714 (set_attr "predicable" "no")])
c65ebc55 2715
6b6c1201 2716(define_insn "*br_false"
c65ebc55 2717 [(set (pc)
6b6c1201
RH
2718 (if_then_else (match_operator 0 "predicate_operator"
2719 [(match_operand:CC 1 "register_operand" "c")
2720 (const_int 0)])
c65ebc55 2721 (pc)
6b6c1201 2722 (label_ref (match_operand 2 "" ""))))]
c65ebc55 2723 ""
85548039 2724 "(%j0) br.cond%+ %l2"
e5bde68a
RH
2725 [(set_attr "type" "B")
2726 (set_attr "predicable" "no")])
c65ebc55
JW
2727\f
2728;; ::::::::::::::::::::
2729;; ::
5527bf14
RH
2730;; :: Counted loop operations
2731;; ::
2732;; ::::::::::::::::::::
2733
2734(define_expand "doloop_end"
2735 [(use (match_operand 0 "" "")) ; loop pseudo
2736 (use (match_operand 1 "" "")) ; iterations; zero if unknown
2737 (use (match_operand 2 "" "")) ; max iterations
2738 (use (match_operand 3 "" "")) ; loop level
2739 (use (match_operand 4 "" ""))] ; label
2740 ""
2741 "
2742{
2743 /* Only use cloop on innermost loops. */
2744 if (INTVAL (operands[3]) > 1)
2745 FAIL;
2746 emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
2747 operands[4]));
2748 DONE;
2749}")
2750
2751(define_insn "doloop_end_internal"
2752 [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
2753 (const_int 0))
2754 (label_ref (match_operand 1 "" ""))
2755 (pc)))
2756 (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
2757 (match_dup 0)
2758 (plus:DI (match_dup 0) (const_int -1))))]
2759 ""
2760 "br.cloop.sptk.few %l1"
2761 [(set_attr "type" "B")
2762 (set_attr "predicable" "no")])
2763\f
2764;; ::::::::::::::::::::
2765;; ::
c65ebc55
JW
2766;; :: Set flag operations
2767;; ::
2768;; ::::::::::::::::::::
2769
2770(define_expand "seq"
2771 [(set (match_dup 1)
2772 (eq:CC (match_dup 2)
2773 (match_dup 3)))
0551c32d 2774 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2775 (ne:DI (match_dup 1) (const_int 0)))]
2776 ""
2777 "
2778{
2779 operands[1] = gen_reg_rtx (CCmode);
2780 operands[2] = ia64_compare_op0;
2781 operands[3] = ia64_compare_op1;
2782}")
2783
2784(define_expand "sne"
2785 [(set (match_dup 1)
2786 (ne:CC (match_dup 2)
2787 (match_dup 3)))
0551c32d 2788 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2789 (ne:DI (match_dup 1) (const_int 0)))]
2790 ""
2791 "
2792{
2793 operands[1] = gen_reg_rtx (CCmode);
2794 operands[2] = ia64_compare_op0;
2795 operands[3] = ia64_compare_op1;
2796}")
2797
2798(define_expand "slt"
2799 [(set (match_dup 1)
2800 (lt:CC (match_dup 2)
2801 (match_dup 3)))
0551c32d 2802 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2803 (ne:DI (match_dup 1) (const_int 0)))]
2804 ""
2805 "
2806{
2807 operands[1] = gen_reg_rtx (CCmode);
2808 operands[2] = ia64_compare_op0;
2809 operands[3] = ia64_compare_op1;
2810}")
2811
2812(define_expand "sle"
2813 [(set (match_dup 1)
2814 (le:CC (match_dup 2)
2815 (match_dup 3)))
0551c32d 2816 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2817 (ne:DI (match_dup 1) (const_int 0)))]
2818 ""
2819 "
2820{
2821 operands[1] = gen_reg_rtx (CCmode);
2822 operands[2] = ia64_compare_op0;
2823 operands[3] = ia64_compare_op1;
2824}")
2825
2826(define_expand "sgt"
2827 [(set (match_dup 1)
2828 (gt:CC (match_dup 2)
2829 (match_dup 3)))
0551c32d 2830 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2831 (ne:DI (match_dup 1) (const_int 0)))]
2832 ""
2833 "
2834{
2835 operands[1] = gen_reg_rtx (CCmode);
2836 operands[2] = ia64_compare_op0;
2837 operands[3] = ia64_compare_op1;
2838}")
2839
2840(define_expand "sge"
2841 [(set (match_dup 1)
2842 (ge:CC (match_dup 2)
2843 (match_dup 3)))
0551c32d 2844 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2845 (ne:DI (match_dup 1) (const_int 0)))]
2846 ""
2847 "
2848{
2849 operands[1] = gen_reg_rtx (CCmode);
2850 operands[2] = ia64_compare_op0;
2851 operands[3] = ia64_compare_op1;
2852}")
2853
2854(define_expand "sltu"
2855 [(set (match_dup 1)
2856 (ltu:CC (match_dup 2)
2857 (match_dup 3)))
0551c32d 2858 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2859 (ne:DI (match_dup 1) (const_int 0)))]
2860 ""
2861 "
2862{
2863 operands[1] = gen_reg_rtx (CCmode);
2864 operands[2] = ia64_compare_op0;
2865 operands[3] = ia64_compare_op1;
2866}")
2867
2868(define_expand "sleu"
2869 [(set (match_dup 1)
2870 (leu:CC (match_dup 2)
2871 (match_dup 3)))
0551c32d 2872 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2873 (ne:DI (match_dup 1) (const_int 0)))]
2874 ""
2875 "
2876{
2877 operands[1] = gen_reg_rtx (CCmode);
2878 operands[2] = ia64_compare_op0;
2879 operands[3] = ia64_compare_op1;
2880}")
2881
2882(define_expand "sgtu"
2883 [(set (match_dup 1)
2884 (gtu:CC (match_dup 2)
2885 (match_dup 3)))
0551c32d 2886 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2887 (ne:DI (match_dup 1) (const_int 0)))]
2888 ""
2889 "
2890{
2891 operands[1] = gen_reg_rtx (CCmode);
2892 operands[2] = ia64_compare_op0;
2893 operands[3] = ia64_compare_op1;
2894}")
2895
2896(define_expand "sgeu"
2897 [(set (match_dup 1)
2898 (geu:CC (match_dup 2)
2899 (match_dup 3)))
0551c32d 2900 (set (match_operand:DI 0 "gr_register_operand" "")
c65ebc55
JW
2901 (ne:DI (match_dup 1) (const_int 0)))]
2902 ""
2903 "
2904{
2905 operands[1] = gen_reg_rtx (CCmode);
2906 operands[2] = ia64_compare_op0;
2907 operands[3] = ia64_compare_op1;
2908}")
2909
e57b9d65
RH
2910(define_expand "sunordered"
2911 [(set (match_dup 1)
2912 (unordered:CC (match_dup 2)
2913 (match_dup 3)))
0551c32d 2914 (set (match_operand:DI 0 "gr_register_operand" "")
e57b9d65
RH
2915 (ne:DI (match_dup 1) (const_int 0)))]
2916 ""
2917 "
2918{
2919 operands[1] = gen_reg_rtx (CCmode);
2920 operands[2] = ia64_compare_op0;
2921 operands[3] = ia64_compare_op1;
2922}")
2923
2924(define_expand "sordered"
2925 [(set (match_dup 1)
2926 (ordered:CC (match_dup 2)
2927 (match_dup 3)))
0551c32d 2928 (set (match_operand:DI 0 "gr_register_operand" "")
e57b9d65
RH
2929 (ne:DI (match_dup 1) (const_int 0)))]
2930 ""
2931 "
2932{
2933 operands[1] = gen_reg_rtx (CCmode);
2934 operands[2] = ia64_compare_op0;
2935 operands[3] = ia64_compare_op1;
2936}")
2937
c65ebc55
JW
2938;; Don't allow memory as destination here, because cmov/cmov/st is more
2939;; efficient than mov/mov/cst/cst.
2940
0551c32d
RH
2941(define_insn_and_split "*sne_internal"
2942 [(set (match_operand:DI 0 "gr_register_operand" "=r")
c65ebc55
JW
2943 (ne:DI (match_operand:CC 1 "register_operand" "c")
2944 (const_int 0)))]
2945 ""
2946 "#"
c65ebc55
JW
2947 "reload_completed"
2948 [(set (match_dup 0)
2949 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2950 (const_int 1)
2951 (match_dup 0)))
2952 (set (match_dup 0)
2953 (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
2954 (match_dup 0)
2955 (const_int 0)))]
0551c32d
RH
2956 ""
2957 [(set_attr "type" "unknown")])
c65ebc55
JW
2958
2959;; ??? Unknown if this can be matched.
2960
0551c32d
RH
2961(define_insn_and_split "*seq_internal"
2962 [(set (match_operand:DI 0 "gr_register_operand" "=r")
c65ebc55
JW
2963 (eq:DI (match_operand:CC 1 "register_operand" "c")
2964 (const_int 0)))]
2965 ""
2966 "#"
c65ebc55
JW
2967 "reload_completed"
2968 [(set (match_dup 0)
2969 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
2970 (const_int 1)
2971 (match_dup 0)))
2972 (set (match_dup 0)
2973 (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
2974 (match_dup 0)
2975 (const_int 0)))]
0551c32d
RH
2976 ""
2977 [(set_attr "type" "unknown")])
c65ebc55
JW
2978
2979\f
2980;; ::::::::::::::::::::
2981;; ::
2982;; :: Conditional move instructions.
2983;; ::
2984;; ::::::::::::::::::::
2985
2986;; ??? Add movXXcc patterns?
2987
c65ebc55
JW
2988;;
2989;; DImode if_then_else patterns.
2990;;
2991
75cdbeb8
RH
2992;; Errata 72 workaround.
2993(define_insn "*cmovdi_internal_astep"
2994 [(set (match_operand:DI 0 "nonimmediate_operand"
97e242b0 2995 "=r,*f,Q,*b,r,*f,Q,*b,r,*f,Q,*b")
75cdbeb8
RH
2996 (if_then_else:DI
2997 (match_operator:CC 4 "predicate_operator"
2998 [(match_operand:CC 1 "register_operand"
2999 "c,c,c,c,c,c,c,c,c,c,c,c")
3000 (const_int 0)])
3001 (match_operand:DI 2 "general_operand"
97e242b0 3002 "0,0,0,0,ri*f*b,rO,*f,r,ri*f*b,rO,*f,r")
75cdbeb8 3003 (match_operand:DI 3 "general_operand"
97e242b0 3004 "ri*f*b,rO,*f,r,0,0,0,0,ri*f*b,rO,*f,r")))]
75cdbeb8
RH
3005 "TARGET_A_STEP"
3006 "* abort ();"
3007 [(set_attr "predicable" "no")])
3008
3009(define_insn "*cmovdi_internal"
3b572406 3010 [(set (match_operand:DI 0 "nonimmediate_operand"
5527bf14 3011 "=r,m,*f,Q,*b*d*e,r,m,*f,Q,*b*d*e,r,m,*f,Q,*b*d*e")
e5bde68a
RH
3012 (if_then_else:DI
3013 (match_operator:CC 4 "predicate_operator"
3b572406
RH
3014 [(match_operand:CC 1 "register_operand"
3015 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
e5bde68a 3016 (const_int 0)])
3b572406 3017 (match_operand:DI 2 "general_operand"
5527bf14 3018 "0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,r,rim*f*b*d*e,rO,rOQ,*f,r")
3b572406 3019 (match_operand:DI 3 "general_operand"
5527bf14 3020 "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
3021 "! TARGET_A_STEP"
3022 "* abort ();"
3023 [(set_attr "predicable" "no")])
3024
3025(define_split
3026 [(set (match_operand 0 "nonimmediate_operand" "")
3027 (if_then_else
3028 (match_operator:CC 4 "predicate_operator"
3029 [(match_operand:CC 1 "register_operand" "")
3030 (const_int 0)])
3031 (match_operand 2 "general_operand" "")
3032 (match_operand 3 "general_operand" "")))]
3b572406
RH
3033 "reload_completed"
3034 [(const_int 0)]
e5bde68a
RH
3035 "
3036{
3b572406
RH
3037 rtx tmp;
3038 if (! rtx_equal_p (operands[0], operands[2]))
e5bde68a 3039 {
3b572406
RH
3040 tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
3041 tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
3042 emit_insn (tmp);
e5bde68a 3043 }
3b572406
RH
3044 if (! rtx_equal_p (operands[0], operands[3]))
3045 {
3046 tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3047 CCmode, operands[1], const0_rtx);
3048 tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
3049 gen_rtx_SET (VOIDmode, operands[0],
3050 operands[3]));
3051 emit_insn (tmp);
3052 }
3053 DONE;
75cdbeb8 3054}")
c65ebc55
JW
3055
3056;; Absolute value pattern.
3057
3058(define_insn "*absdi2_internal"
0551c32d 3059 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
e5bde68a
RH
3060 (if_then_else:DI
3061 (match_operator:CC 4 "predicate_operator"
3062 [(match_operand:CC 1 "register_operand" "c,c")
3063 (const_int 0)])
0551c32d
RH
3064 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
3065 (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
c65ebc55 3066 ""
e5bde68a 3067 "#"
3b572406
RH
3068 [(set_attr "type" "A,unknown")
3069 (set_attr "predicable" "no")])
c65ebc55
JW
3070
3071(define_split
3072 [(set (match_operand:DI 0 "register_operand" "")
e5bde68a
RH
3073 (if_then_else:DI
3074 (match_operator:CC 4 "predicate_operator"
3075 [(match_operand:CC 1 "register_operand" "c,c")
3076 (const_int 0)])
0551c32d
RH
3077 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
3078 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
3079 "reload_completed && rtx_equal_p (operands[0], operands[3])"
3080 [(cond_exec
3081 (match_dup 4)
3082 (set (match_dup 0)
3083 (neg:DI (match_dup 2))))]
c65ebc55
JW
3084 "")
3085
e5bde68a
RH
3086(define_split
3087 [(set (match_operand:DI 0 "register_operand" "")
3088 (if_then_else:DI
3089 (match_operator:CC 4 "predicate_operator"
3090 [(match_operand:CC 1 "register_operand" "c,c")
3091 (const_int 0)])
0551c32d
RH
3092 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
3093 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
3094 "reload_completed"
3095 [(cond_exec
3096 (match_dup 4)
3097 (set (match_dup 0) (neg:DI (match_dup 2))))
3098 (cond_exec
3099 (match_dup 5)
3100 (set (match_dup 0) (match_dup 3)))]
3101 "
3102{
3103 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3104 CCmode, operands[1], const0_rtx);
3105}")
c65ebc55
JW
3106
3107;;
3108;; SImode if_then_else patterns.
3109;;
3110
75cdbeb8
RH
3111(define_insn "*cmovsi_internal_astep"
3112 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,*f,r,*f,r,*f")
3113 (if_then_else:SI
3114 (match_operator:CC 4 "predicate_operator"
3115 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c")
3116 (const_int 0)])
3117 (match_operand:SI 2 "general_operand"
3118 "0,0,ri*f,rO,ri*f,rO")
3119 (match_operand:SI 3 "general_operand"
3120 "ri*f,rO,0,0,ri*f,rO")))]
3121 "TARGET_A_STEP"
3122 "* abort ();"
3123 [(set_attr "predicable" "no")])
3124
3125(define_insn "*cmovsi_internal"
3b572406 3126 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,*f,r,m,*f,r,m,*f")
e5bde68a
RH
3127 (if_then_else:SI
3128 (match_operator:CC 4 "predicate_operator"
3b572406 3129 [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c,c,c")
e5bde68a 3130 (const_int 0)])
3b572406
RH
3131 (match_operand:SI 2 "general_operand"
3132 "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
3133 (match_operand:SI 3 "general_operand"
3134 "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
75cdbeb8
RH
3135 "! TARGET_A_STEP"
3136 "* abort ();"
3b572406 3137 [(set_attr "predicable" "no")])
c65ebc55
JW
3138
3139(define_insn "*abssi2_internal"
0551c32d 3140 [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
e5bde68a
RH
3141 (if_then_else:SI
3142 (match_operator:CC 4 "predicate_operator"
3143 [(match_operand:CC 1 "register_operand" "c,c")
3144 (const_int 0)])
0551c32d
RH
3145 (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
3146 (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
c65ebc55 3147 ""
e5bde68a 3148 "#"
3b572406
RH
3149 [(set_attr "type" "A,unknown")
3150 (set_attr "predicable" "no")])
c65ebc55
JW
3151
3152(define_split
3153 [(set (match_operand:SI 0 "register_operand" "")
e5bde68a
RH
3154 (if_then_else:SI
3155 (match_operator:CC 4 "predicate_operator"
3156 [(match_operand:CC 1 "register_operand" "c,c")
3157 (const_int 0)])
0551c32d
RH
3158 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
3159 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
3160 "reload_completed && rtx_equal_p (operands[0], operands[3])"
3161 [(cond_exec
3162 (match_dup 4)
3163 (set (match_dup 0)
3164 (neg:SI (match_dup 2))))]
c65ebc55
JW
3165 "")
3166
e5bde68a
RH
3167(define_split
3168 [(set (match_operand:SI 0 "register_operand" "")
3169 (if_then_else:SI
3170 (match_operator:CC 4 "predicate_operator"
3171 [(match_operand:CC 1 "register_operand" "c,c")
3172 (const_int 0)])
0551c32d
RH
3173 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
3174 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
e5bde68a
RH
3175 "reload_completed"
3176 [(cond_exec
3177 (match_dup 4)
3178 (set (match_dup 0) (neg:SI (match_dup 2))))
3179 (cond_exec
3180 (match_dup 5)
3181 (set (match_dup 0) (match_dup 3)))]
3182 "
3183{
3184 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
3185 CCmode, operands[1], const0_rtx);
3186}")
3187
c65ebc55
JW
3188\f
3189;; ::::::::::::::::::::
3190;; ::
3191;; :: Call and branch instructions
3192;; ::
3193;; ::::::::::::::::::::
3194
3195;; Subroutine call instruction returning no value. Operand 0 is the function
3196;; to call; operand 1 is the number of bytes of arguments pushed (in mode
3197;; `SImode', except it is normally a `const_int'); operand 2 is the number of
3198;; registers used as operands.
3199
3200;; On most machines, operand 2 is not actually stored into the RTL pattern. It
3201;; is supplied for the sake of some RISC machines which need to put this
3202;; information into the assembler code; they can put it in the RTL instead of
3203;; operand 1.
3204
3205(define_expand "call"
3206 [(use (match_operand:DI 0 "" ""))
3207 (use (match_operand 1 "" ""))
3208 (use (match_operand 2 "" ""))
3209 (use (match_operand 3 "" ""))]
3210 ""
3211 "
3212{
3213 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
3214 rtx addr = XEXP (operands[0], 0);
3215 enum machine_mode mode = GET_MODE (addr);
3216
59da9a7d 3217 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
c65ebc55
JW
3218 emit_call_insn (gen_call_internal (addr, operands[1],
3219 gen_rtx_REG (DImode, R_BR (0))));
3220
3221 /* If this is an indirect call, then we have the address of a descriptor. */
3222 else if (! symbolic_operand (addr, mode))
3223 emit_insn (gen_indirect_call_pic (addr, operands[1]));
59da9a7d
JW
3224 else if (TARGET_CONST_GP)
3225 emit_call_insn (gen_call_internal (addr, operands[1],
3226 gen_rtx_REG (DImode, R_BR (0))));
c65ebc55
JW
3227 else
3228 emit_insn (gen_call_pic (addr, operands[1]));
3229
3230 DONE;
3231}")
3232
3233(define_expand "indirect_call_pic"
3234 [(set (match_dup 2) (reg:DI 1))
3235 (set (match_dup 3) (mem:DI (match_operand 0 "" "")))
3236 (set (match_dup 4) (plus:DI (match_dup 0) (const_int 8)))
3237 (set (reg:DI 1) (mem:DI (match_dup 4)))
3238 (parallel [(call (mem:DI (match_dup 3)) (match_operand 1 "" ""))
3239 (use (reg:DI 1))
3240 (clobber (reg:DI 320))])
3241 (set (reg:DI 1) (match_dup 2))]
3242 ""
3243 "
3244{
97e242b0 3245 operands[2] = ia64_gp_save_reg (0);
c65ebc55
JW
3246 operands[3] = gen_reg_rtx (DImode);
3247 operands[4] = gen_reg_rtx (DImode);
3248}")
3249
c65ebc55
JW
3250;; ??? Saving/restoring the GP register is not needed if we are calling
3251;; a function in the same module.
3252
3253(define_expand "call_pic"
3254 [(set (match_dup 2) (reg:DI 1))
3255 (parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" ""))
3256 (use (reg:DI 1))
3257 (clobber (reg:DI 320))])
3258 (set (reg:DI 1) (match_dup 2))]
3259 ""
3260 "
3261{
97e242b0
RH
3262 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
3263 operands[2] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[0], 0),
3264 VOIDmode));
c65ebc55
JW
3265}")
3266
c65ebc55
JW
3267(define_insn "call_internal"
3268 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
3269 (match_operand 1 "" ""))
3270 (clobber (match_operand:DI 2 "register_operand" "=b"))]
3271 ""
85548039 3272 "br.call%+.many %2 = %0"
c65ebc55
JW
3273 [(set_attr "type" "B")])
3274
3275(define_insn "*call_internal1"
3276 [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
3277 (match_operand 1 "" ""))
3278 (use (reg:DI 1))
3279 (clobber (match_operand:DI 2 "register_operand" "=b"))]
3280 ""
85548039 3281 "br.call%+.many %2 = %0"
c65ebc55
JW
3282 [(set_attr "type" "B")])
3283
3284;; Subroutine call instruction returning a value. Operand 0 is the hard
3285;; register in which the value is returned. There are three more operands, the
3286;; same as the three operands of the `call' instruction (but with numbers
3287;; increased by one).
3288
3289;; Subroutines that return `BLKmode' objects use the `call' insn.
3290
3291(define_expand "call_value"
3292 [(use (match_operand 0 "" ""))
3293 (use (match_operand:DI 1 "" ""))
3294 (use (match_operand 2 "" ""))
3295 (use (match_operand 3 "" ""))
3296 (use (match_operand 4 "" ""))]
3297 ""
3298 "
3299{
3300 /* ??? Stripping off the MEM isn't correct. Will lose alias info. */
3301 rtx addr = XEXP (operands[1], 0);
3302 enum machine_mode mode = GET_MODE (addr);
3303
59da9a7d 3304 if (TARGET_NO_PIC || TARGET_AUTO_PIC)
c65ebc55
JW
3305 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
3306 gen_rtx_REG (DImode, R_BR (0))));
3307
3308 /* If this is an indirect call, then we have the address of a descriptor. */
3309 else if (! symbolic_operand (addr, mode))
3310 {
3311 /* This is for HFA returns. */
3312 if (GET_CODE (operands[0]) == PARALLEL)
3313 emit_insn (gen_indirect_call_multiple_values_pic (operands[0], addr,
3314 operands[2]));
3315 else
3316 emit_insn (gen_indirect_call_value_pic (operands[0], addr,
3317 operands[2]));
3318 }
59da9a7d
JW
3319 else if (TARGET_CONST_GP)
3320 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
3321 gen_rtx_REG (DImode, R_BR (0))));
c65ebc55
JW
3322 /* This is for HFA returns. */
3323 else if (GET_CODE (operands[0]) == PARALLEL)
3324 emit_insn (gen_call_multiple_values_pic (operands[0], addr, operands[2]));
3325 else
3326 emit_insn (gen_call_value_pic (operands[0], addr, operands[2]));
3327
3328 DONE;
3329}")
3330
3331(define_expand "indirect_call_value_pic"
3332 [(set (match_dup 3) (reg:DI 1))
3333 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
3334 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
3335 (set (reg:DI 1) (mem:DI (match_dup 5)))
3336 (parallel [(set (match_operand 0 "" "")
3337 (call (mem:DI (match_dup 4)) (match_operand 2 "" "")))
3338 (use (reg:DI 1))
3339 (clobber (reg:DI 320))])
3340 (set (reg:DI 1) (match_dup 3))]
3341 ""
3342 "
3343{
97e242b0 3344 operands[3] = ia64_gp_save_reg (0);
c65ebc55
JW
3345 operands[4] = gen_reg_rtx (DImode);
3346 operands[5] = gen_reg_rtx (DImode);
3347}")
3348
3349(define_expand "indirect_call_multiple_values_pic"
3350 [(set (match_dup 3) (reg:DI 1))
3351 (set (match_dup 4) (mem:DI (match_operand 1 "" "")))
3352 (set (match_dup 5) (plus:DI (match_dup 1) (const_int 8)))
3353 (set (reg:DI 1) (mem:DI (match_dup 5)))
3354 (match_par_dup 6 [(set (match_operand 0 "" "")
3355 (call (mem:DI (match_dup 4))
3356 (match_operand 2 "" "")))
3357 (use (reg:DI 1))
3358 (clobber (reg:DI 320))])
3359 (set (reg:DI 1) (match_dup 3))]
3360 ""
3361 "
3362{
3363 int count;
3364 int i;
3365 rtx call;
3366
97e242b0 3367 operands[3] = ia64_gp_save_reg (0);
c65ebc55
JW
3368 operands[4] = gen_reg_rtx (DImode);
3369 operands[5] = gen_reg_rtx (DImode);
3370
3371 /* This code is the same as the code in call_multiple_values_pic, except
3372 that op3 was replaced with op6 and op1 was replaced with op4. */
3373 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[4]),
3374 operands[2]);
3375
3376 count = XVECLEN (operands[0], 0);
3377 operands[6] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
3378
3379 XVECEXP (operands[6], 0, 0)
3380 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
3381
3382 XVECEXP (operands[6], 0, 1)
3383 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
3384 XVECEXP (operands[6], 0, 2)
3385 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
3386
3387 for (i = 1; i < count; i++)
3388 XVECEXP (operands[6], 0, i + 2)
3389 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
3390
3391}")
3392
c65ebc55
JW
3393;; ??? Saving/restoring the GP register is not needed if we are calling
3394;; a function in the same module.
3395
3396(define_expand "call_value_pic"
3397 [(set (match_dup 3) (reg:DI 1))
3398 (parallel [(set (match_operand 0 "" "")
3399 (call (mem:DI (match_operand 1 "" ""))
3400 (match_operand 2 "" "")))
3401 (use (reg:DI 1))
3402 (clobber (reg:DI 320))])
3403 (set (reg:DI 1) (match_dup 3))]
3404 ""
3405 "
3406{
97e242b0
RH
3407 /* ??? Using setjmp_operand is an unsatisfying solution. Should rethink. */
3408 operands[3] = ia64_gp_save_reg (setjmp_operand (XEXP (operands[1], 0),
3409 VOIDmode));
c65ebc55
JW
3410}")
3411
3412;; ??? Saving/restoring the GP register is not needed if we are calling
3413;; a function in the same module.
3414
3415(define_expand "call_multiple_values_pic"
3416 [(set (match_dup 4) (reg:DI 1))
3417 (match_par_dup 3 [(set (match_operand 0 "" "")
3418 (call (mem:DI (match_operand 1 "" ""))
3419 (match_operand 2 "" "")))
3420 (use (reg:DI 1))
3421 (clobber (reg:DI 320))])
3422 (set (reg:DI 1) (match_dup 4))]
3423 ""
3424 "
3425{
3426 int count;
3427 int i;
3428 rtx call;
3429
97e242b0 3430 operands[4] = ia64_gp_save_reg (0);
c65ebc55
JW
3431
3432 call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (DImode, operands[1]),
3433 operands[2]);
3434
3435 count = XVECLEN (operands[0], 0);
3436 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 2));
3437
3438 XVECEXP (operands[3], 0, 0)
3439 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, 0), 0), call);
3440
3441 XVECEXP (operands[3], 0, 1)
3442 = gen_rtx_USE (DImode, gen_rtx_REG (DImode, GR_REG (1)));
3443 XVECEXP (operands[3], 0, 2)
3444 = gen_rtx_CLOBBER (DImode, gen_rtx_REG (DImode, BR_REG (0)));
3445
3446 for (i = 1; i < count; i++)
3447 XVECEXP (operands[3], 0, i + 2)
3448 = gen_rtx_SET (VOIDmode, XEXP (XVECEXP (operands[0], 0, i), 0), call);
3449}")
3450
c65ebc55
JW
3451(define_insn "call_value_internal"
3452 [(set (match_operand 0 "register_operand" "=rf")
3453 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
3454 (match_operand 2 "" "")))
3455 (clobber (match_operand:DI 3 "register_operand" "=b"))]
3456 ""
85548039 3457 "br.call%+.many %3 = %1"
c65ebc55
JW
3458 [(set_attr "type" "B")])
3459
3460(define_insn "*call_value_internal1"
3461 [(set (match_operand 0 "register_operand" "=rf")
3462 (call (mem:DI (match_operand:DI 1 "call_operand" "bi"))
3463 (match_operand 2 "" "")))
3464 (use (reg:DI 1))
3465 (clobber (match_operand:DI 3 "register_operand" "=b"))]
3466 ""
85548039 3467 "br.call%+.many %3 = %1"
c65ebc55
JW
3468 [(set_attr "type" "B")])
3469
3470(define_insn "*call_multiple_values_internal1"
3471 [(match_parallel 0 "call_multiple_values_operation"
3472 [(set (match_operand 1 "register_operand" "=rf")
3473 (call (mem:DI (match_operand:DI 2 "call_operand" "bi"))
3474 (match_operand 3 "" "")))
3475 (use (reg:DI 1))
3476 (clobber (match_operand:DI 4 "register_operand" "=b"))])]
3477 ""
85548039 3478 "br.call%+.many %4 = %2"
c65ebc55
JW
3479 [(set_attr "type" "B")])
3480
3481;; Call subroutine returning any type.
3482
3483(define_expand "untyped_call"
3484 [(parallel [(call (match_operand 0 "" "")
3485 (const_int 0))
3486 (match_operand 1 "" "")
3487 (match_operand 2 "" "")])]
3488 ""
3489 "
3490{
3491 int i;
3492
3493 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3494
3495 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3496 {
3497 rtx set = XVECEXP (operands[2], 0, i);
3498 emit_move_insn (SET_DEST (set), SET_SRC (set));
3499 }
3500
3501 /* The optimizer does not know that the call sets the function value
3502 registers we stored in the result block. We avoid problems by
3503 claiming that all hard registers are used and clobbered at this
3504 point. */
3505 emit_insn (gen_blockage ());
3506
3507 DONE;
3508}")
3509
3510(define_insn "return_internal"
3511 [(return)
3512 (use (match_operand:DI 0 "register_operand" "b"))]
3513 ""
3514 "br.ret.sptk.many %0"
3515 [(set_attr "type" "B")])
3516
3517(define_insn "return"
3518 [(return)]
3519 "ia64_direct_return ()"
3520 "br.ret.sptk.many rp"
3521 [(set_attr "type" "B")])
3522
6b6c1201 3523(define_insn "*return_true"
c65ebc55 3524 [(set (pc)
6b6c1201
RH
3525 (if_then_else (match_operator 0 "predicate_operator"
3526 [(match_operand:CC 1 "register_operand" "c")
3527 (const_int 0)])
c65ebc55
JW
3528 (return)
3529 (pc)))]
3530 "ia64_direct_return ()"
13da91fd 3531 "(%J0) br.ret%+.many rp"
e5bde68a
RH
3532 [(set_attr "type" "B")
3533 (set_attr "predicable" "no")])
c65ebc55 3534
6b6c1201 3535(define_insn "*return_false"
c65ebc55 3536 [(set (pc)
6b6c1201
RH
3537 (if_then_else (match_operator 0 "predicate_operator"
3538 [(match_operand:CC 1 "register_operand" "c")
3539 (const_int 0)])
c65ebc55
JW
3540 (pc)
3541 (return)))]
3542 "ia64_direct_return ()"
13da91fd 3543 "(%j0) br.ret%+.many rp"
e5bde68a
RH
3544 [(set_attr "type" "B")
3545 (set_attr "predicable" "no")])
c65ebc55
JW
3546
3547(define_insn "jump"
3548 [(set (pc) (label_ref (match_operand 0 "" "")))]
3549 ""
3550 "br %l0"
3551 [(set_attr "type" "B")])
3552
3553(define_insn "indirect_jump"
3554 [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
3555 ""
3556 "br %0"
3557 [(set_attr "type" "B")])
3558
3559(define_expand "tablejump"
3560 [(match_operand:DI 0 "register_operand" "")
3561 (match_operand 1 "" "")]
3562 ""
3563 "
3564{
3565 rtx tmp1 = gen_reg_rtx (DImode);
3566 rtx tmp2 = gen_reg_rtx (DImode);
3567
3568 emit_move_insn (tmp1, gen_rtx_LABEL_REF (Pmode, operands[1]));
3569 emit_insn (gen_adddi3 (tmp2, operands[0], tmp1));
3570 emit_jump_insn (gen_tablejump_internal (tmp2, operands[1]));
3571 DONE;
3572}")
3573
3574(define_insn "tablejump_internal"
3575 [(set (pc) (match_operand:DI 0 "register_operand" "b"))
3576 (use (label_ref (match_operand 1 "" "")))]
3577 ""
3578 "br %0"
3579 [(set_attr "type" "B")])
3580
3581\f
3582;; ::::::::::::::::::::
3583;; ::
3584;; :: Prologue and Epilogue instructions
3585;; ::
3586;; ::::::::::::::::::::
3587
3588(define_expand "prologue"
3589 [(const_int 1)]
3590 ""
3591 "
3592{
3593 ia64_expand_prologue ();
3594 DONE;
3595}")
3596
3597(define_expand "epilogue"
3598 [(const_int 2)]
3599 ""
3600 "
3601{
3602 ia64_expand_epilogue ();
3603 DONE;
3604}")
3605
3606;; This prevents the scheduler from moving the SP decrement past FP-relative
3607;; stack accesses. This is the same as adddi3 plus the extra set.
3608
3609(define_insn "prologue_allocate_stack"
3610 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3611 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
0551c32d 3612 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
c65ebc55
JW
3613 (set (match_operand:DI 3 "register_operand" "=r,r,r")
3614 (match_dup 3))]
3615 ""
3616 "@
3617 add %0 = %1, %2
3618 adds %0 = %2, %1
3619 addl %0 = %2, %1"
3620 [(set_attr "type" "A")])
3621
3622;; This prevents the scheduler from moving the SP restore past FP-relative
3623;; stack accesses. This is similar to movdi plus the extra set.
3624
3625(define_insn "epilogue_deallocate_stack"
3626 [(set (match_operand:DI 0 "register_operand" "=r")
3627 (match_operand:DI 1 "register_operand" "+r"))
3628 (set (match_dup 1) (match_dup 1))]
3629 ""
3630 "mov %0 = %1"
3631 [(set_attr "type" "A")])
3632
3633;; Allocate a new register frame.
3634
3635(define_insn "alloc"
3636 [(set (match_operand:DI 0 "register_operand" "=r")
3637 (unspec_volatile:DI [(const_int 0)] 0))
3638 (use (match_operand:DI 1 "const_int_operand" "i"))
3639 (use (match_operand:DI 2 "const_int_operand" "i"))
3640 (use (match_operand:DI 3 "const_int_operand" "i"))
3641 (use (match_operand:DI 4 "const_int_operand" "i"))]
3642 ""
3643 "alloc %0 = ar.pfs, %1, %2, %3, %4"
e5bde68a
RH
3644 [(set_attr "type" "M")
3645 (set_attr "predicable" "no")])
c65ebc55 3646
97e242b0
RH
3647;; Modifies ar.unat
3648(define_expand "gr_spill"
870f9ec0
RH
3649 [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
3650 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3651 (match_operand:DI 2 "const_int_operand" "")] 1))
3652 (clobber (match_dup 3))])]
97e242b0 3653 ""
870f9ec0 3654 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
97e242b0 3655
870f9ec0 3656(define_insn "gr_spill_internal"
c65ebc55 3657 [(set (match_operand:DI 0 "memory_operand" "=m")
870f9ec0
RH
3658 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3659 (match_operand:DI 2 "const_int_operand" "")] 1))
3660 (clobber (match_operand:DI 3 "register_operand" ""))]
c65ebc55 3661 ""
870f9ec0 3662 ".mem.offset %2, 0\;st8.spill %0 = %1%P0"
c65ebc55
JW
3663 [(set_attr "type" "M")])
3664
97e242b0
RH
3665;; Reads ar.unat
3666(define_expand "gr_restore"
870f9ec0
RH
3667 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3668 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3669 (match_operand:DI 2 "const_int_operand" "")] 2))
3670 (use (match_dup 3))])]
97e242b0 3671 ""
870f9ec0 3672 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
97e242b0 3673
870f9ec0 3674(define_insn "gr_restore_internal"
c65ebc55 3675 [(set (match_operand:DI 0 "register_operand" "=r")
870f9ec0
RH
3676 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
3677 (match_operand:DI 2 "const_int_operand" "")] 2))
3678 (use (match_operand:DI 3 "register_operand" ""))]
c65ebc55 3679 ""
870f9ec0 3680 ".mem.offset %2, 0\;ld8.fill %0 = %1%P1"
c65ebc55
JW
3681 [(set_attr "type" "M")])
3682
3683(define_insn "fr_spill"
3f622353
RH
3684 [(set (match_operand:TF 0 "memory_operand" "=m")
3685 (unspec:TF [(match_operand:TF 1 "register_operand" "f")] 3))]
c65ebc55
JW
3686 ""
3687 "stf.spill %0 = %1%P0"
3688 [(set_attr "type" "M")])
3689
3690(define_insn "fr_restore"
3f622353
RH
3691 [(set (match_operand:TF 0 "register_operand" "=f")
3692 (unspec:TF [(match_operand:TF 1 "memory_operand" "m")] 4))]
c65ebc55
JW
3693 ""
3694 "ldf.fill %0 = %1%P1"
3695 [(set_attr "type" "M")])
3696
0c96007e
AM
3697(define_insn "bsp_value"
3698 [(set (match_operand:DI 0 "register_operand" "=r")
3699 (unspec:DI [(const_int 0)] 20))]
3700 ""
3701 "mov %0 = ar.bsp"
3702 [(set_attr "type" "I")])
3703
3704(define_insn "set_bsp"
3705 [(unspec_volatile [(const_int 0)] 5)
3706 (use (match_operand:DI 0 "register_operand" "r"))]
3707 ""
13da91fd 3708 "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
3709 [(set_attr "type" "unknown")
3710 (set_attr "predicable" "no")])
ce152ef8
AM
3711
3712(define_insn "flushrs"
3713 [(unspec [(const_int 0)] 21)]
3714 ""
13da91fd 3715 ";;\;flushrs"
ce152ef8 3716 [(set_attr "type" "M")])
c65ebc55
JW
3717\f
3718;; ::::::::::::::::::::
3719;; ::
3720;; :: Miscellaneous instructions
3721;; ::
3722;; ::::::::::::::::::::
3723
3724;; ??? Emiting a NOP instruction isn't very useful. This should probably
3725;; be emitting ";;" to force a break in the instruction packing.
3726
3727;; No operation, needed in case the user uses -g but not -O.
3728(define_insn "nop"
3729 [(const_int 0)]
3730 ""
3731 "nop 0"
3732 [(set_attr "type" "unknown")])
3733
3734;; Pseudo instruction that prevents the scheduler from moving code above this
3735;; point.
3736(define_insn "blockage"
3737 [(unspec_volatile [(const_int 0)] 1)]
3738 ""
3739 ""
e5bde68a
RH
3740 [(set_attr "type" "unknown")
3741 (set_attr "predicable" "no")])
c65ebc55
JW
3742
3743(define_insn "insn_group_barrier"
3744 [(unspec_volatile [(const_int 0)] 2)]
3745 ""
3746 ";;"
e5bde68a
RH
3747 [(set_attr "type" "S")
3748 (set_attr "predicable" "no")])
c65ebc55
JW
3749
3750\f
3751;; Non-local goto support.
3752
3753(define_expand "save_stack_nonlocal"
3754 [(use (match_operand:OI 0 "memory_operand" ""))
3755 (use (match_operand:DI 1 "register_operand" ""))]
3756 ""
3757 "
3758{
3759 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
3760 \"__ia64_save_stack_nonlocal\"),
3761 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
3762 operands[1], Pmode);
3763 DONE;
3764}")
3765
3766(define_expand "nonlocal_goto"
3767 [(use (match_operand 0 "general_operand" ""))
3768 (use (match_operand 1 "general_operand" ""))
3769 (use (match_operand 2 "general_operand" ""))
3770 (use (match_operand 3 "general_operand" ""))]
3771 ""
3772 "
3773{
c65ebc55 3774 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
97e242b0
RH
3775 0, VOIDmode, 3,
3776 operands[1], Pmode,
c65ebc55
JW
3777 copy_to_reg (XEXP (operands[2], 0)), Pmode,
3778 operands[3], Pmode);
3779 emit_barrier ();
3780 DONE;
3781}")
3782
97e242b0
RH
3783;; Restore the GP after the exception/longjmp. The preceeding call will
3784;; have tucked it away.
3785(define_expand "exception_receiver"
3786 [(set (reg:DI 1) (match_dup 0))]
3787 ""
3788 "operands[0] = ia64_gp_save_reg (0);")
c65ebc55 3789
97e242b0
RH
3790;; The rest of the setjmp processing happens with the nonlocal_goto expander.
3791;; ??? This is not tested.
3792(define_expand "builtin_setjmp_setup"
3793 [(use (match_operand:DI 0 "" ""))]
c65ebc55
JW
3794 ""
3795 "
3796{
97e242b0
RH
3797 emit_move_insn (ia64_gp_save_reg (0), gen_rtx_REG (DImode, GR_REG (1)));
3798 DONE;
3799}")
3800
3801(define_expand "builtin_setjmp_receiver"
3802 [(use (match_operand:DI 0 "" ""))]
3803 ""
3804 "
3805{
3806 emit_move_insn (gen_rtx_REG (DImode, GR_REG (1)), ia64_gp_save_reg (0));
c65ebc55
JW
3807 DONE;
3808}")
3809
0c96007e
AM
3810(define_expand "eh_epilogue"
3811 [(use (match_operand:DI 0 "register_operand" "r"))
3812 (use (match_operand:DI 1 "register_operand" "r"))
3813 (use (match_operand:DI 2 "register_operand" "r"))]
3814 ""
3815 "
3816{
3817 rtx bsp = gen_rtx_REG (Pmode, 10);
3818 rtx sp = gen_rtx_REG (Pmode, 9);
3819
3820 if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
3821 {
3822 emit_move_insn (bsp, operands[0]);
3823 operands[0] = bsp;
3824 }
3825 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
3826 {
3827 emit_move_insn (sp, operands[2]);
3828 operands[2] = sp;
3829 }
3830 emit_insn (gen_rtx_USE (VOIDmode, sp));
3831 emit_insn (gen_rtx_USE (VOIDmode, bsp));
3832
3833 cfun->machine->ia64_eh_epilogue_sp = sp;
3834 cfun->machine->ia64_eh_epilogue_bsp = bsp;
0c96007e 3835}")
9525c690
JW
3836\f
3837;; Builtin apply support.
3838
3839(define_expand "restore_stack_nonlocal"
3840 [(use (match_operand:DI 0 "register_operand" ""))
3841 (use (match_operand:OI 1 "memory_operand" ""))]
3842 ""
3843 "
3844{
3845 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
3846 \"__ia64_restore_stack_nonlocal\"),
3847 0, VOIDmode, 1,
3848 copy_to_reg (XEXP (operands[1], 0)), Pmode);
3849 DONE;
3850}")
3851
3852\f
3853;;; Intrinsics support.
c65ebc55 3854
0551c32d
RH
3855(define_expand "mf"
3856 [(set (mem:BLK (match_dup 0))
3857 (unspec:BLK [(mem:BLK (match_dup 0))] 12))]
3858 ""
3859 "
3860{
3861 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
3862 MEM_VOLATILE_P (operands[0]) = 1;
3863}")
3864
3865(define_insn "*mf_internal"
3866 [(set (match_operand:BLK 0 "" "")
3867 (unspec:BLK [(match_operand:BLK 1 "" "")] 12))]
c65ebc55
JW
3868 ""
3869 "mf"
3870 [(set_attr "type" "M")])
3871
3872(define_insn "fetchadd_acq_si"
0551c32d
RH
3873 [(set (match_operand:SI 0 "gr_register_operand" "=r")
3874 (match_dup 1))
3875 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
3876 (unspec:SI [(match_dup 1)
3877 (match_operand:SI 2 "fetchadd_operand" "n")] 19))]
c65ebc55
JW
3878 ""
3879 "fetchadd4.acq %0 = %1, %2"
3880 [(set_attr "type" "M")])
3881
3882(define_insn "fetchadd_acq_di"
0551c32d
RH
3883 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3884 (match_dup 1))
3885 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
3886 (unspec:DI [(match_dup 1)
3887 (match_operand:DI 2 "fetchadd_operand" "n")] 19))]
c65ebc55
JW
3888 ""
3889 "fetchadd8.acq %0 = %1, %2"
3890 [(set_attr "type" "M")])
3891
3892(define_insn "cmpxchg_acq_si"
0551c32d
RH
3893 [(set (match_operand:SI 0 "gr_register_operand" "=r")
3894 (match_dup 1))
3895 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
3896 (unspec:SI [(match_dup 1)
3897 (match_operand:SI 2 "gr_register_operand" "r")
97e242b0 3898 (match_operand:SI 3 "ar_ccv_reg_operand" "")] 13))]
c65ebc55 3899 ""
97e242b0 3900 "cmpxchg4.acq %0 = %1, %2, %3"
c65ebc55
JW
3901 [(set_attr "type" "M")])
3902
3903(define_insn "cmpxchg_acq_di"
0551c32d
RH
3904 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3905 (match_dup 1))
3906 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
3907 (unspec:DI [(match_dup 1)
3908 (match_operand:DI 2 "gr_register_operand" "r")
3909 (match_operand:DI 3 "ar_ccv_reg_operand" "")] 13))]
c65ebc55 3910 ""
97e242b0 3911 "cmpxchg8.acq %0 = %1, %2, %3"
c65ebc55
JW
3912 [(set_attr "type" "M")])
3913
c65ebc55 3914(define_insn "xchgsi"
0551c32d
RH
3915 [(set (match_operand:SI 0 "gr_register_operand" "=r")
3916 (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
c65ebc55 3917 (set (match_dup 1)
0551c32d 3918 (match_operand:SI 2 "gr_register_operand" "r"))]
c65ebc55
JW
3919 ""
3920 "xchg4 %0 = %1, %2"
3921 [(set_attr "type" "M")])
3922
3923(define_insn "xchgdi"
0551c32d
RH
3924 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3925 (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
c65ebc55 3926 (set (match_dup 1)
0551c32d 3927 (match_operand:DI 2 "gr_register_operand" "r"))]
c65ebc55
JW
3928 ""
3929 "xchg8 %0 = %1, %2"
3930 [(set_attr "type" "M")])
e5bde68a
RH
3931\f
3932;; Predication.
3933
3934(define_cond_exec
3935 [(match_operator 0 "predicate_operator"
3936 [(match_operand:CC 1 "register_operand" "c")
3937 (const_int 0)])]
3938 ""
3939 "(%J0)")
3b572406
RH
3940
3941(define_insn "pred_rel_mutex"
054451ea 3942 [(unspec_volatile [(match_operand:CC 0 "register_operand" "c")] 7)]
3b572406 3943 ""
054451ea 3944 ".pred.rel.mutex %0, %I0"
3b572406
RH
3945 [(set_attr "type" "unknown")
3946 (set_attr "predicable" "no")])
This page took 0.55049 seconds and 5 git commands to generate.