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