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