]> gcc.gnu.org Git - gcc.git/blame_incremental - gcc/config/ia64/ia64.md
re PR c++/44991 (default argument with '<' cause compilation error)
[gcc.git] / gcc / config / ia64 / ia64.md
... / ...
CommitLineData
1;; IA-64 Machine description template
2;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3;; 2009, 2010 Free Software Foundation, Inc.
4;; Contributed by James E. Wilson <wilson@cygnus.com> and
5;; David Mosberger <davidm@hpl.hp.com>.
6
7;; This file is part of GCC.
8
9;; GCC is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 3, or (at your option)
12;; any later version.
13
14;; GCC is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with GCC; see the file COPYING3. If not see
21;; <http://www.gnu.org/licenses/>.
22
23;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
26;; reload. This will be fixed once scheduling support is turned on.
27
28;; ??? Optimize for post-increment addressing modes.
29
30;; ??? fselect is not supported, because there is no integer register
31;; equivalent.
32
33;; ??? fp abs/min/max instructions may also work for integer values.
34
35;; ??? Would a predicate_reg_operand predicate be useful? The HP one is buggy,
36;; it assumes the operand is a register and takes REGNO of it without checking.
37
38;; ??? Would a branch_reg_operand predicate be useful? The HP one is buggy,
39;; it assumes the operand is a register and takes REGNO of it without checking.
40
41;; ??? Go through list of documented named patterns and look for more to
42;; implement.
43
44;; ??? Go through instruction manual and look for more instructions that
45;; can be emitted.
46
47;; ??? Add function unit scheduling info for Itanium (TM) processor.
48
49;; ??? Need a better way to describe alternate fp status registers.
50
51(define_constants
52 [; Relocations
53 (UNSPEC_LTOFF_DTPMOD 0)
54 (UNSPEC_LTOFF_DTPREL 1)
55 (UNSPEC_DTPREL 2)
56 (UNSPEC_LTOFF_TPREL 3)
57 (UNSPEC_TPREL 4)
58 (UNSPEC_DTPMOD 5)
59
60 (UNSPEC_LD_BASE 9)
61 (UNSPEC_GR_SPILL 10)
62 (UNSPEC_GR_RESTORE 11)
63 (UNSPEC_FR_SPILL 12)
64 (UNSPEC_FR_RESTORE 13)
65 (UNSPEC_FR_RECIP_APPROX 14)
66 (UNSPEC_PRED_REL_MUTEX 15)
67 (UNSPEC_GETF_EXP 16)
68 (UNSPEC_PIC_CALL 17)
69 (UNSPEC_MF 18)
70 (UNSPEC_CMPXCHG_ACQ 19)
71 (UNSPEC_FETCHADD_ACQ 20)
72 (UNSPEC_BSP_VALUE 21)
73 (UNSPEC_FLUSHRS 22)
74 (UNSPEC_BUNDLE_SELECTOR 23)
75 (UNSPEC_ADDP4 24)
76 (UNSPEC_PROLOGUE_USE 25)
77 (UNSPEC_RET_ADDR 26)
78 (UNSPEC_SETF_EXP 27)
79 (UNSPEC_FR_SQRT_RECIP_APPROX 28)
80 (UNSPEC_SHRP 29)
81 (UNSPEC_COPYSIGN 30)
82 (UNSPEC_VECT_EXTR 31)
83 (UNSPEC_LDA 40)
84 (UNSPEC_LDS 41)
85 (UNSPEC_LDS_A 42)
86 (UNSPEC_LDSA 43)
87 (UNSPEC_LDCCLR 44)
88 (UNSPEC_LDCNC 45)
89 (UNSPEC_CHKACLR 46)
90 (UNSPEC_CHKANC 47)
91 (UNSPEC_CHKS 48)
92 (UNSPEC_FR_RECIP_APPROX_RES 49)
93 (UNSPEC_FR_SQRT_RECIP_APPROX_RES 50)
94 ])
95
96(define_constants
97 [(UNSPECV_ALLOC 0)
98 (UNSPECV_BLOCKAGE 1)
99 (UNSPECV_INSN_GROUP_BARRIER 2)
100 (UNSPECV_BREAK 3)
101 (UNSPECV_SET_BSP 4)
102 (UNSPECV_PSAC_ALL 5) ; pred.safe_across_calls
103 (UNSPECV_PSAC_NORMAL 6)
104 (UNSPECV_SETJMP_RECEIVER 7)
105 (UNSPECV_GOTO_RECEIVER 8)
106 ])
107
108(include "predicates.md")
109(include "constraints.md")
110\f
111;; ::::::::::::::::::::
112;; ::
113;; :: Attributes
114;; ::
115;; ::::::::::::::::::::
116
117;; Processor type. This attribute must exactly match the processor_type
118;; enumeration in ia64.h.
119(define_attr "cpu" "itanium,itanium2"
120 (const (symbol_ref "((enum attr_cpu) ia64_tune)")))
121
122;; Instruction type. This primarily determines how instructions can be
123;; packed in bundles, and secondarily affects scheduling to function units.
124
125;; A alu, can go in I or M syllable of a bundle
126;; I integer
127;; M memory
128;; F floating-point
129;; B branch
130;; L long immediate, takes two syllables
131;; S stop bit
132
133;; ??? Should not have any pattern with type unknown. Perhaps add code to
134;; check this in md_reorg? Currently use unknown for patterns which emit
135;; multiple instructions, patterns which emit 0 instructions, and patterns
136;; which emit instruction that can go in any slot (e.g. nop).
137
138(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
139 fldp,fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,
140 ld,chk_s_i,chk_s_f,chk_a,long_i,mmalua,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,
141 st,syst_m0, syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,
142 nop_b,nop_f,nop_i,nop_m,nop_x,lfetch,pre_cycle"
143 (const_string "unknown"))
144
145;; chk_s_i has an I and an M form; use type A for convenience.
146(define_attr "type" "unknown,A,I,M,F,B,L,X,S"
147 (cond [(eq_attr "itanium_class" "ld,st,fld,fldp,stf,sem,nop_m") (const_string "M")
148 (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
149 (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
150 (eq_attr "itanium_class" "lfetch") (const_string "M")
151 (eq_attr "itanium_class" "chk_s_f,chk_a") (const_string "M")
152 (eq_attr "itanium_class" "chk_s_i,ialu,icmp,ilog,mmalua")
153 (const_string "A")
154 (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
155 (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
156 (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
157 (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
158 (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
159 (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
160 (eq_attr "itanium_class" "stop_bit") (const_string "S")
161 (eq_attr "itanium_class" "nop_x") (const_string "X")
162 (eq_attr "itanium_class" "long_i") (const_string "L")]
163 (const_string "unknown")))
164
165(define_attr "itanium_requires_unit0" "no,yes"
166 (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
167 (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
168 (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
169 (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
170 (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
171 (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
172 (const_string "no")))
173
174;; Predication. True iff this instruction can be predicated.
175
176(define_attr "predicable" "no,yes" (const_string "yes"))
177
178;; Empty. True iff this insn does not generate any code.
179
180(define_attr "empty" "no,yes" (const_string "no"))
181
182;; True iff this insn must be the first insn of an instruction group.
183;; This is true for the alloc instruction, and will also be true of others
184;; when we have full intrinsics support.
185
186(define_attr "first_insn" "no,yes" (const_string "no"))
187
188(define_attr "data_speculative" "no,yes" (const_string "no"))
189
190(define_attr "control_speculative" "no,yes" (const_string "no"))
191
192(define_attr "check_load" "no,yes" (const_string "no"))
193
194(define_attr "speculable1" "no,yes" (const_string "no"))
195
196(define_attr "speculable2" "no,yes" (const_string "no"))
197\f
198;; DFA descriptions of ia64 processors used for insn scheduling and
199;; bundling.
200
201(automata_option "ndfa")
202
203;; Uncomment the following line to output automata for debugging.
204;; (automata_option "v")
205
206(automata_option "w")
207
208(include "itanium2.md")
209
210\f
211;; ::::::::::::::::::::
212;; ::
213;; :: Moves
214;; ::
215;; ::::::::::::::::::::
216
217;; Set of a single predicate register. This is only used to implement
218;; pr-to-pr move and complement.
219
220(define_insn "*movcci"
221 [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
222 (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
223 ""
224 "@
225 cmp.ne %0, p0 = r0, r0
226 cmp.eq %0, p0 = r0, r0
227 (%1) cmp.eq.unc %0, p0 = r0, r0"
228 [(set_attr "itanium_class" "icmp")
229 (set_attr "predicable" "no")])
230
231(define_insn "movbi"
232 [(set (match_operand:BI 0 "destination_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
233 (match_operand:BI 1 "move_operand" " O,n, c, c,*r, n,*m,*r,*r"))]
234 ""
235 "@
236 cmp.ne %0, %I0 = r0, r0
237 cmp.eq %0, %I0 = r0, r0
238 #
239 #
240 tbit.nz %0, %I0 = %1, 0
241 adds %0 = %1, r0
242 ld1%O1 %0 = %1%P1
243 st1%Q0 %0 = %1%P0
244 mov %0 = %1"
245 [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")
246 (set_attr "speculable1" "yes")
247 (set_attr "speculable2" "no, no, no, no, no, no, yes,no,no")])
248
249(define_split
250 [(set (match_operand:BI 0 "register_operand" "")
251 (match_operand:BI 1 "register_operand" ""))]
252 "reload_completed
253 && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
254 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
255 [(cond_exec (ne (match_dup 1) (const_int 0))
256 (set (match_dup 0) (const_int 1)))
257 (cond_exec (eq (match_dup 1) (const_int 0))
258 (set (match_dup 0) (const_int 0)))]
259 "")
260
261(define_split
262 [(set (match_operand:BI 0 "register_operand" "")
263 (match_operand:BI 1 "register_operand" ""))]
264 "reload_completed
265 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
266 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
267 [(set (match_dup 2) (match_dup 4))
268 (set (match_dup 3) (match_dup 5))
269 (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
270 "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
271 operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
272 operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
273 operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
274
275(define_expand "movqi"
276 [(set (match_operand:QI 0 "general_operand" "")
277 (match_operand:QI 1 "general_operand" ""))]
278 ""
279{
280 rtx op1 = ia64_expand_move (operands[0], operands[1]);
281 if (!op1)
282 DONE;
283 operands[1] = op1;
284})
285
286(define_insn "movqi_internal"
287 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
288 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
289 "ia64_move_ok (operands[0], operands[1])"
290 "@
291 mov %0 = %r1
292 addl %0 = %1, r0
293 ld1%O1 %0 = %1%P1
294 st1%Q0 %0 = %r1%P0
295 getf.sig %0 = %1
296 setf.sig %0 = %r1
297 mov %0 = %1"
298 [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")
299 (set_attr "speculable1" "yes")
300 (set_attr "speculable2" "no, no, yes,no,no, no, no")])
301
302(define_expand "movhi"
303 [(set (match_operand:HI 0 "general_operand" "")
304 (match_operand:HI 1 "general_operand" ""))]
305 ""
306{
307 rtx op1 = ia64_expand_move (operands[0], operands[1]);
308 if (!op1)
309 DONE;
310 operands[1] = op1;
311})
312
313(define_insn "movhi_internal"
314 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
315 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
316 "ia64_move_ok (operands[0], operands[1])"
317 "@
318 mov %0 = %r1
319 addl %0 = %1, r0
320 ld2%O1 %0 = %1%P1
321 st2%Q0 %0 = %r1%P0
322 getf.sig %0 = %1
323 setf.sig %0 = %r1
324 mov %0 = %1"
325 [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")
326 (set_attr "speculable1" "yes")
327 (set_attr "speculable2" "no, no, yes,no,no, no, no")])
328
329(define_expand "movsi"
330 [(set (match_operand:SI 0 "general_operand" "")
331 (match_operand:SI 1 "general_operand" ""))]
332 ""
333{
334 rtx op1 = ia64_expand_move (operands[0], operands[1]);
335 if (!op1)
336 DONE;
337 operands[1] = op1;
338})
339
340(define_insn "movsi_internal"
341 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r,r, m, r,*f,*f, r,*d")
342 (match_operand:SI 1 "move_operand" "rO,J,j,i,m,rO,*f,rO,*f,*d,rK"))]
343 "ia64_move_ok (operands[0], operands[1])"
344 "@
345 mov %0 = %r1
346 addl %0 = %1, r0
347 addp4 %0 = %1 - 0x100000000, r0
348 movl %0 = %1
349 ld4%O1 %0 = %1%P1
350 st4%Q0 %0 = %r1%P0
351 getf.sig %0 = %1
352 setf.sig %0 = %r1
353 mov %0 = %1
354 mov %0 = %1
355 mov %0 = %r1"
356 ;; frar_m, toar_m ??? why not frar_i and toar_i
357 [(set_attr "itanium_class" "ialu,ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")
358 (set_attr "speculable1" "yes")
359 (set_attr "speculable2" "no, no, no, no, yes,no,no, no, no, no, no")])
360
361(define_expand "movdi"
362 [(set (match_operand:DI 0 "general_operand" "")
363 (match_operand:DI 1 "general_operand" ""))]
364 ""
365{
366 rtx op1 = ia64_expand_move (operands[0], operands[1]);
367 if (!op1)
368 DONE;
369 operands[1] = op1;
370})
371
372(define_insn "movdi_internal"
373 [(set (match_operand:DI 0 "destination_operand"
374 "=r,r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
375 (match_operand:DI 1 "move_operand"
376 "rO,JT,j,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
377 "ia64_move_ok (operands[0], operands[1])"
378{
379 static const char * const alt[] = {
380 "%,mov %0 = %r1",
381 "%,addl %0 = %1, r0",
382 "%,addp4 %0 = %1 - 0x100000000, r0",
383 "%,movl %0 = %1",
384 "%,ld8%O1 %0 = %1%P1",
385 "%,st8%Q0 %0 = %r1%P0",
386 "%,getf.sig %0 = %1",
387 "%,setf.sig %0 = %r1",
388 "%,mov %0 = %1",
389 "%,ldf8 %0 = %1%P1",
390 "%,stf8 %0 = %1%P0",
391 "%,mov %0 = %1",
392 "%,mov %0 = %r1",
393 "%,mov %0 = %1",
394 "%,mov %0 = %1",
395 "%,mov %0 = %1",
396 "%,mov %0 = %1",
397 "mov %0 = pr",
398 "mov pr = %1, -1"
399 };
400
401 gcc_assert (which_alternative != 2 || TARGET_NO_PIC
402 || !symbolic_operand (operands[1], VOIDmode));
403
404 return alt[which_alternative];
405}
406 [(set_attr "itanium_class" "ialu,ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,fld,stf,frbr,tobr,frar_i,toar_i,frar_m,toar_m,frpr,topr")
407 (set_attr "speculable1" "yes")
408 (set_attr "speculable2" "no, no, no, no, yes,no,no, no, no, yes,no, no, no, no, no, no, no, no, no")])
409
410(define_mode_iterator MODE [BI QI HI SI DI SF DF XF TI])
411(define_mode_iterator MODE_FOR_CMP [BI SI DI SF DF XF (TF "TARGET_HPUX")])
412(define_mode_iterator MODE_FOR_EXTEND [QI HI SI])
413
414(define_mode_attr output_a [
415 (BI "ld1.a %0 = %1%P1")
416 (QI "ld1.a %0 = %1%P1")
417 (HI "ld2.a %0 = %1%P1")
418 (SI "ld4.a %0 = %1%P1")
419 (DI
420 "@
421 ld8.a %0 = %1%P1
422 ldf8.a %0 = %1%P1")
423 (SF
424 "@
425 ldfs.a %0 = %1%P1
426 ld4.a %0 = %1%P1")
427 (DF
428 "@
429 ldfd.a %0 = %1%P1
430 ld8.a %0 = %1%P1")
431 (XF "ldfe.a %0 = %1%P1")
432 (TI "ldfp8.a %X0 = %1%P1")])
433
434(define_mode_attr output_s [
435 (BI "ld1.s %0 = %1%P1")
436 (QI "ld1.s %0 = %1%P1")
437 (HI "ld2.s %0 = %1%P1")
438 (SI "ld4.s %0 = %1%P1")
439 (DI
440 "@
441 ld8.s %0 = %1%P1
442 ldf8.s %0 = %1%P1")
443 (SF
444 "@
445 ldfs.s %0 = %1%P1
446 ld4.s %0 = %1%P1")
447 (DF
448 "@
449 ldfd.s %0 = %1%P1
450 ld8.s %0 = %1%P1")
451 (XF "ldfe.s %0 = %1%P1")
452 (TI "ldfp8.s %X0 = %1%P1")])
453
454(define_mode_attr output_sa [
455 (BI "ld1.sa %0 = %1%P1")
456 (QI "ld1.sa %0 = %1%P1")
457 (HI "ld2.sa %0 = %1%P1")
458 (SI "ld4.sa %0 = %1%P1")
459 (DI
460 "@
461 ld8.sa %0 = %1%P1
462 ldf8.sa %0 = %1%P1")
463 (SF
464 "@
465 ldfs.sa %0 = %1%P1
466 ld4.sa %0 = %1%P1")
467 (DF
468 "@
469 ldfd.sa %0 = %1%P1
470 ld8.sa %0 = %1%P1")
471 (XF "ldfe.sa %0 = %1%P1")
472 (TI "ldfp8.sa %X0 = %1%P1")])
473
474(define_mode_attr output_c_clr [
475 (BI "ld1.c.clr%O1 %0 = %1%P1")
476 (QI "ld1.c.clr%O1 %0 = %1%P1")
477 (HI "ld2.c.clr%O1 %0 = %1%P1")
478 (SI "ld4.c.clr%O1 %0 = %1%P1")
479 (DI
480 "@
481 ld8.c.clr%O1 %0 = %1%P1
482 ldf8.c.clr %0 = %1%P1")
483 (SF
484 "@
485 ldfs.c.clr %0 = %1%P1
486 ld4.c.clr%O1 %0 = %1%P1")
487 (DF
488 "@
489 ldfd.c.clr %0 = %1%P1
490 ld8.c.clr%O1 %0 = %1%P1")
491 (XF "ldfe.c.clr %0 = %1%P1")
492 (TI "ldfp8.c.clr %X0 = %1%P1")])
493
494(define_mode_attr output_c_nc [
495 (BI "ld1.c.nc%O1 %0 = %1%P1")
496 (QI "ld1.c.nc%O1 %0 = %1%P1")
497 (HI "ld2.c.nc%O1 %0 = %1%P1")
498 (SI "ld4.c.nc%O1 %0 = %1%P1")
499 (DI
500 "@
501 ld8.c.nc%O1 %0 = %1%P1
502 ldf8.c.nc %0 = %1%P1")
503 (SF
504 "@
505 ldfs.c.nc %0 = %1%P1
506 ld4.c.nc%O1 %0 = %1%P1")
507 (DF
508 "@
509 ldfd.c.nc %0 = %1%P1
510 ld8.c.nc%O1 %0 = %1%P1")
511 (XF "ldfe.c.nc %0 = %1%P1")
512 (TI "ldfp8.c.nc %X0 = %1%P1")])
513
514(define_mode_attr ld_reg_constr [(BI "=*r") (QI "=r") (HI "=r") (SI "=r") (DI "=r,*f") (SF "=f,*r") (DF "=f,*r") (XF "=f") (TI "=*x")])
515(define_mode_attr ldc_reg_constr [(BI "+*r") (QI "+r") (HI "+r") (SI "+r") (DI "+r,*f") (SF "+f,*r") (DF "+f,*r") (XF "+f") (TI "+*x")])
516(define_mode_attr chk_reg_constr [(BI "*r") (QI "r") (HI "r") (SI "r") (DI "r,*f") (SF "f,*r") (DF "f,*r") (XF "f") (TI "*x")])
517
518(define_mode_attr mem_constr [(BI "*m") (QI "m") (HI "m") (SI "m") (DI "m,Q") (SF "Q,m") (DF "Q,m") (XF "m") (TI "Q")])
519
520;; Define register predicate prefix.
521;; We can generate speculative loads only for general and fp registers - this
522;; is constrained in ia64.c: ia64_speculate_insn ().
523(define_mode_attr reg_pred_prefix [(BI "gr") (QI "gr") (HI "gr") (SI "gr") (DI "grfr") (SF "grfr") (DF "grfr") (XF "fr") (TI "fr")])
524
525(define_mode_attr ld_class [(BI "ld") (QI "ld") (HI "ld") (SI "ld") (DI "ld,fld") (SF "fld,ld") (DF "fld,ld") (XF "fld") (TI "fldp")])
526(define_mode_attr chka_class [(BI "chk_a") (QI "chk_a") (HI "chk_a") (SI "chk_a") (DI "chk_a,chk_a") (SF "chk_a,chk_a") (DF "chk_a,chk_a") (XF "chk_a") (TI "chk_a")])
527(define_mode_attr chks_class [(BI "chk_s_i") (QI "chk_s_i") (HI "chk_s_i") (SI "chk_s_i") (DI "chk_s_i,chk_s_f") (SF "chk_s_f,chk_s_i") (DF "chk_s_f,chk_s_i") (XF "chk_s_f") (TI "chk_s_i")])
528
529(define_mode_attr attr_yes [(BI "yes") (QI "yes") (HI "yes") (SI "yes") (DI "yes,yes") (SF "yes,yes") (DF "yes,yes") (XF "yes") (TI "yes")])
530
531(define_insn "mov<mode>_advanced"
532 [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>")
533 (unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDA))]
534 "ia64_move_ok (operands[0], operands[1])"
535 "<output_a>"
536 [(set_attr "itanium_class" "<ld_class>")
537 (set_attr "data_speculative" "<attr_yes>")])
538
539(define_insn "zero_extend<mode>di2_advanced"
540 [(set (match_operand:DI 0 "gr_register_operand" "=r")
541 (zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDA)))]
542 ""
543 "<output_a>"
544 [(set_attr "itanium_class" "<ld_class>")
545 (set_attr "data_speculative" "<attr_yes>")])
546
547(define_insn "mov<mode>_speculative"
548 [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>")
549 (unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDS))]
550 "ia64_move_ok (operands[0], operands[1])"
551 "<output_s>"
552 [(set_attr "itanium_class" "<ld_class>")
553 (set_attr "control_speculative" "<attr_yes>")])
554
555(define_insn "zero_extend<mode>di2_speculative"
556 [(set (match_operand:DI 0 "gr_register_operand" "=r")
557 (zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDS)))]
558 ""
559 "<output_s>"
560 [(set_attr "itanium_class" "<ld_class>")
561 (set_attr "control_speculative" "<attr_yes>")])
562
563(define_insn "mov<mode>_speculative_advanced"
564 [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>")
565 (unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDSA))]
566 "ia64_move_ok (operands[0], operands[1])"
567 "<output_sa>"
568 [(set_attr "itanium_class" "<ld_class>")
569 (set_attr "data_speculative" "<attr_yes>")
570 (set_attr "control_speculative" "<attr_yes>")])
571
572(define_insn "mov<mode>_speculative_a"
573 [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>")
574 (unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDS_A))]
575 "ia64_move_ok (operands[0], operands[1])"
576 "<output_sa>"
577 [(set_attr "itanium_class" "<ld_class>")
578 (set_attr "data_speculative" "<attr_yes>")
579 (set_attr "control_speculative" "<attr_yes>")])
580
581(define_insn "zero_extend<mode>di2_speculative_advanced"
582 [(set (match_operand:DI 0 "gr_register_operand" "=r")
583 (zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDSA)))]
584 ""
585 "<output_sa>"
586 [(set_attr "itanium_class" "<ld_class>")
587 (set_attr "data_speculative" "<attr_yes>")
588 (set_attr "control_speculative" "<attr_yes>")])
589
590(define_insn "zero_extend<mode>di2_speculative_a"
591 [(set (match_operand:DI 0 "gr_register_operand" "=r")
592 (zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDS_A)))]
593 ""
594 "<output_sa>"
595 [(set_attr "itanium_class" "<ld_class>")
596 (set_attr "data_speculative" "<attr_yes>")
597 (set_attr "control_speculative" "<attr_yes>")])
598
599(define_insn "mov<mode>_clr"
600 [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ldc_reg_constr>")
601 (if_then_else:MODE (ne (unspec [(match_dup 0)] UNSPEC_LDCCLR) (const_int 0))
602 (match_operand:MODE 1 "memory_operand" "<mem_constr>")
603 (match_dup 0)))]
604 "ia64_move_ok (operands[0], operands[1])"
605 "<output_c_clr>"
606 [(set_attr "itanium_class" "<ld_class>")
607 (set_attr "check_load" "<attr_yes>")])
608
609(define_insn "mov<mode>_nc"
610 [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ldc_reg_constr>")
611 (if_then_else:MODE (ne (unspec [(match_dup 0)] UNSPEC_LDCNC) (const_int 0))
612 (match_operand:MODE 1 "memory_operand" "<mem_constr>")
613 (match_dup 0)))]
614 "ia64_move_ok (operands[0], operands[1])"
615 "<output_c_nc>"
616 [(set_attr "itanium_class" "<ld_class>")
617 (set_attr "check_load" "<attr_yes>")])
618
619(define_insn "zero_extend<mode>di2_clr"
620 [(set (match_operand:DI 0 "gr_register_operand" "+r")
621 (if_then_else:DI (ne (unspec [(match_dup 0)] UNSPEC_LDCCLR) (const_int 0))
622 (zero_extend:DI (match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>"))
623 (match_dup 0)))]
624 ""
625 "<output_c_clr>"
626 [(set_attr "itanium_class" "<ld_class>")
627 (set_attr "check_load" "<attr_yes>")])
628
629(define_insn "zero_extend<mode>di2_nc"
630 [(set (match_operand:DI 0 "gr_register_operand" "+r")
631 (if_then_else:DI (ne (unspec [(match_dup 0)] UNSPEC_LDCNC) (const_int 0))
632 (zero_extend:DI (match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>"))
633 (match_dup 0)))]
634 ""
635 "<output_c_nc>"
636 [(set_attr "itanium_class" "<ld_class>")
637 (set_attr "check_load" "<attr_yes>")])
638
639(define_insn "advanced_load_check_clr_<mode>"
640 [(set (pc)
641 (if_then_else (ne (unspec [(match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<chk_reg_constr>")] UNSPEC_CHKACLR) (const_int 0))
642 (pc)
643 (label_ref (match_operand 1 "" ""))))]
644 ""
645 "chk.a.clr %0, %l1"
646 [(set_attr "itanium_class" "<chka_class>")])
647
648(define_insn "advanced_load_check_nc_<mode>"
649 [(set (pc)
650 (if_then_else (ne (unspec [(match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<chk_reg_constr>")] UNSPEC_CHKANC) (const_int 0))
651 (pc)
652 (label_ref (match_operand 1 "" ""))))]
653 ""
654 "chk.a.clr %0, %l1"
655 [(set_attr "itanium_class" "<chka_class>")])
656
657(define_insn "speculation_check_<mode>"
658 [(set (pc)
659 (if_then_else (ne (unspec [(match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<chk_reg_constr>")] UNSPEC_CHKS) (const_int 0))
660 (pc)
661 (label_ref (match_operand 1 "" ""))))]
662 ""
663 "chk.s %0, %l1"
664 [(set_attr "itanium_class" "<chks_class>")])
665
666(define_split
667 [(set (match_operand 0 "register_operand" "")
668 (match_operand 1 "symbolic_operand" ""))]
669 "reload_completed"
670 [(const_int 0)]
671{
672 if (ia64_expand_load_address (operands[0], operands[1]))
673 DONE;
674 else
675 FAIL;
676})
677
678(define_expand "load_fptr"
679 [(set (match_operand:DI 0 "register_operand" "")
680 (plus:DI (match_dup 2) (match_operand 1 "function_operand" "")))
681 (set (match_dup 0) (match_dup 3))]
682 "reload_completed"
683{
684 operands[2] = pic_offset_table_rtx;
685 operands[3] = gen_const_mem (DImode, operands[0]);
686})
687
688(define_insn "*load_fptr_internal1"
689 [(set (match_operand:DI 0 "register_operand" "=r")
690 (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
691 "reload_completed"
692 "addl %0 = @ltoff(@fptr(%1)), gp"
693 [(set_attr "itanium_class" "ialu")])
694
695(define_insn "load_gprel"
696 [(set (match_operand:DI 0 "register_operand" "=r")
697 (plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
698 "reload_completed"
699 "addl %0 = @gprel(%1), gp"
700 [(set_attr "itanium_class" "ialu")])
701
702(define_insn "*gprel64_offset"
703 [(set (match_operand:DI 0 "register_operand" "=r")
704 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
705 "reload_completed"
706 "movl %0 = @gprel(%1)"
707 [(set_attr "itanium_class" "long_i")])
708
709(define_expand "load_gprel64"
710 [(set (match_operand:DI 0 "register_operand" "")
711 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 2)))
712 (set (match_dup 0)
713 (plus:DI (match_dup 2) (match_dup 0)))]
714 "reload_completed"
715{
716 operands[2] = pic_offset_table_rtx;
717})
718
719;; This is used as a placeholder for the return address during early
720;; compilation. We won't know where we've placed this until during
721;; reload, at which point it can wind up in b0, a general register,
722;; or memory. The only safe destination under these conditions is a
723;; general register.
724
725(define_insn_and_split "*movdi_ret_addr"
726 [(set (match_operand:DI 0 "register_operand" "=r")
727 (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
728 ""
729 "#"
730 "reload_completed"
731 [(const_int 0)]
732{
733 ia64_split_return_addr_rtx (operands[0]);
734 DONE;
735}
736 [(set_attr "itanium_class" "ialu")])
737
738(define_insn "*load_symptr_high"
739 [(set (match_operand:DI 0 "register_operand" "=r")
740 (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
741 (match_operand:DI 2 "register_operand" "a")))]
742 "reload_completed"
743{
744 if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
745 return "%,addl %0 = @ltoffx(%1), %2";
746 else
747 return "%,addl %0 = @ltoff(%1), %2";
748}
749 [(set_attr "itanium_class" "ialu")])
750
751(define_insn "*load_symptr_low"
752 [(set (match_operand:DI 0 "register_operand" "=r")
753 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
754 (match_operand 2 "got_symbolic_operand" "s")))]
755 "reload_completed"
756{
757 if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
758 return "%,ld8.mov %0 = [%1], %2";
759 else
760 return "%,ld8 %0 = [%1]";
761}
762 [(set_attr "itanium_class" "ld")])
763
764(define_insn_and_split "load_dtpmod"
765 [(set (match_operand:DI 0 "register_operand" "=r")
766 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
767 UNSPEC_DTPMOD))]
768 ""
769 "#"
770 "reload_completed"
771 [(set (match_dup 0)
772 (plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_DTPMOD)
773 (match_dup 2)))
774 (set (match_dup 0) (match_dup 3))]
775{
776 operands[2] = pic_offset_table_rtx;
777 operands[3] = gen_const_mem (DImode, operands[0]);
778})
779
780(define_insn "*load_ltoff_dtpmod"
781 [(set (match_operand:DI 0 "register_operand" "=r")
782 (plus:DI (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
783 UNSPEC_LTOFF_DTPMOD)
784 (match_operand:DI 2 "register_operand" "a")))]
785 "reload_completed"
786 "addl %0 = @ltoff(@dtpmod(%1)), %2"
787 [(set_attr "itanium_class" "ialu")])
788
789(define_expand "load_dtprel"
790 [(set (match_operand:DI 0 "register_operand" "")
791 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
792 UNSPEC_DTPREL))]
793 ""
794 "")
795
796(define_insn "*load_dtprel64"
797 [(set (match_operand:DI 0 "register_operand" "=r")
798 (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
799 UNSPEC_DTPREL))]
800 "TARGET_TLS64"
801 "movl %0 = @dtprel(%1)"
802 [(set_attr "itanium_class" "long_i")])
803
804(define_insn "*load_dtprel22"
805 [(set (match_operand:DI 0 "register_operand" "=r")
806 (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
807 UNSPEC_DTPREL))]
808 ""
809 "addl %0 = @dtprel(%1), r0"
810 [(set_attr "itanium_class" "ialu")])
811
812(define_insn_and_split "*load_dtprel_gd"
813 [(set (match_operand:DI 0 "register_operand" "=r")
814 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
815 UNSPEC_DTPREL))]
816 ""
817 "#"
818 "reload_completed"
819 [(set (match_dup 0)
820 (plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_DTPREL)
821 (match_dup 2)))
822 (set (match_dup 0) (match_dup 3))]
823{
824 operands[2] = pic_offset_table_rtx;
825 operands[3] = gen_const_mem (DImode, operands[0]);
826})
827
828(define_insn "*load_ltoff_dtprel"
829 [(set (match_operand:DI 0 "register_operand" "=r")
830 (plus:DI (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
831 UNSPEC_LTOFF_DTPREL)
832 (match_operand:DI 2 "register_operand" "a")))]
833 ""
834 "addl %0 = @ltoff(@dtprel(%1)), %2"
835 [(set_attr "itanium_class" "ialu")])
836
837(define_expand "add_dtprel"
838 [(set (match_operand:DI 0 "register_operand" "")
839 (plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
840 UNSPEC_DTPREL)
841 (match_operand:DI 2 "register_operand" "")))]
842 "!TARGET_TLS64"
843 "")
844
845(define_insn "*add_dtprel14"
846 [(set (match_operand:DI 0 "register_operand" "=r")
847 (plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
848 UNSPEC_DTPREL)
849 (match_operand:DI 2 "register_operand" "r")))]
850 "TARGET_TLS14"
851 "adds %0 = @dtprel(%1), %2"
852 [(set_attr "itanium_class" "ialu")])
853
854(define_insn "*add_dtprel22"
855 [(set (match_operand:DI 0 "register_operand" "=r")
856 (plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
857 UNSPEC_DTPREL)
858 (match_operand:DI 2 "register_operand" "a")))]
859 "TARGET_TLS22"
860 "addl %0 = @dtprel(%1), %2"
861 [(set_attr "itanium_class" "ialu")])
862
863(define_expand "load_tprel"
864 [(set (match_operand:DI 0 "register_operand" "")
865 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
866 UNSPEC_TPREL))]
867 ""
868 "")
869
870(define_insn "*load_tprel64"
871 [(set (match_operand:DI 0 "register_operand" "=r")
872 (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
873 UNSPEC_TPREL))]
874 "TARGET_TLS64"
875 "movl %0 = @tprel(%1)"
876 [(set_attr "itanium_class" "long_i")])
877
878(define_insn "*load_tprel22"
879 [(set (match_operand:DI 0 "register_operand" "=r")
880 (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
881 UNSPEC_TPREL))]
882 ""
883 "addl %0 = @tprel(%1), r0"
884 [(set_attr "itanium_class" "ialu")])
885
886(define_insn_and_split "*load_tprel_ie"
887 [(set (match_operand:DI 0 "register_operand" "=r")
888 (unspec:DI [(match_operand 1 "ie_tls_symbolic_operand" "")]
889 UNSPEC_TPREL))]
890 ""
891 "#"
892 "reload_completed"
893 [(set (match_dup 0)
894 (plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_TPREL)
895 (match_dup 2)))
896 (set (match_dup 0) (match_dup 3))]
897{
898 operands[2] = pic_offset_table_rtx;
899 operands[3] = gen_const_mem (DImode, operands[0]);
900})
901
902(define_insn "*load_ltoff_tprel"
903 [(set (match_operand:DI 0 "register_operand" "=r")
904 (plus:DI (unspec:DI [(match_operand 1 "ie_tls_symbolic_operand" "")]
905 UNSPEC_LTOFF_TPREL)
906 (match_operand:DI 2 "register_operand" "a")))]
907 ""
908 "addl %0 = @ltoff(@tprel(%1)), %2"
909 [(set_attr "itanium_class" "ialu")])
910
911(define_expand "add_tprel"
912 [(set (match_operand:DI 0 "register_operand" "")
913 (plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
914 UNSPEC_TPREL)
915 (match_operand:DI 2 "register_operand" "")))]
916 "!TARGET_TLS64"
917 "")
918
919(define_insn "*add_tprel14"
920 [(set (match_operand:DI 0 "register_operand" "=r")
921 (plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
922 UNSPEC_TPREL)
923 (match_operand:DI 2 "register_operand" "r")))]
924 "TARGET_TLS14"
925 "adds %0 = @tprel(%1), %2"
926 [(set_attr "itanium_class" "ialu")])
927
928(define_insn "*add_tprel22"
929 [(set (match_operand:DI 0 "register_operand" "=r")
930 (plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
931 UNSPEC_TPREL)
932 (match_operand:DI 2 "register_operand" "a")))]
933 "TARGET_TLS22"
934 "addl %0 = @tprel(%1), %2"
935 [(set_attr "itanium_class" "ialu")])
936
937;; With no offsettable memory references, we've got to have a scratch
938;; around to play with the second word. However, in order to avoid a
939;; reload nightmare we lie, claim we don't need one, and fix it up
940;; in ia64_split_tmode_move.
941(define_expand "movti"
942 [(set (match_operand:TI 0 "general_operand" "")
943 (match_operand:TI 1 "general_operand" ""))]
944 ""
945{
946 rtx op1 = ia64_expand_move (operands[0], operands[1]);
947 if (!op1)
948 DONE;
949 operands[1] = op1;
950})
951
952(define_insn_and_split "movti_internal"
953 [(set (match_operand:TI 0 "destination_operand" "=r, *fm,*x,*f, Q")
954 (match_operand:TI 1 "general_operand" "r*fim,r, Q, *fOQ,*f"))]
955 "ia64_move_ok (operands[0], operands[1])"
956 "@
957 #
958 #
959 ldfp8 %X0 = %1%P1
960 #
961 #"
962 "reload_completed && !ia64_load_pair_ok(operands[0], operands[1])"
963 [(const_int 0)]
964{
965 ia64_split_tmode_move (operands);
966 DONE;
967}
968 [(set_attr "itanium_class" "unknown,unknown,fldp,unknown,unknown")
969 (set_attr "speculable1" "yes")
970 (set_attr "speculable2" "no, no, yes, no, no")])
971
972;; Floating Point Moves
973;;
974;; Note - Patterns for SF mode moves are compulsory, but
975;; patterns for DF are optional, as GCC can synthesize them.
976
977(define_expand "movsf"
978 [(set (match_operand:SF 0 "general_operand" "")
979 (match_operand:SF 1 "general_operand" ""))]
980 ""
981{
982 rtx op1 = ia64_expand_move (operands[0], operands[1]);
983 if (!op1)
984 DONE;
985 operands[1] = op1;
986})
987
988(define_insn "movsf_internal"
989 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
990 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r, F"))]
991 "ia64_move_ok (operands[0], operands[1])"
992 "@
993 mov %0 = %F1
994 ldfs %0 = %1%P1
995 stfs %0 = %F1%P0
996 getf.s %0 = %F1
997 setf.s %0 = %1
998 mov %0 = %1
999 ld4%O1 %0 = %1%P1
1000 st4%Q0 %0 = %1%P0
1001 movl %0 = %G1"
1002 [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st,long_i")
1003 (set_attr "speculable1" "yes")
1004 (set_attr "speculable2" "no, yes,no, no, no, no, yes,no,no")])
1005
1006(define_expand "movdf"
1007 [(set (match_operand:DF 0 "general_operand" "")
1008 (match_operand:DF 1 "general_operand" ""))]
1009 ""
1010{
1011 rtx op1 = ia64_expand_move (operands[0], operands[1]);
1012 if (!op1)
1013 DONE;
1014 operands[1] = op1;
1015})
1016
1017(define_insn "movdf_internal"
1018 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
1019 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r, F"))]
1020 "ia64_move_ok (operands[0], operands[1])"
1021 "@
1022 mov %0 = %F1
1023 ldfd %0 = %1%P1
1024 stfd %0 = %F1%P0
1025 getf.d %0 = %F1
1026 setf.d %0 = %1
1027 mov %0 = %1
1028 ld8%O1 %0 = %1%P1
1029 st8%Q0 %0 = %1%P0
1030 movl %0 = %G1"
1031 [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st,long_i")
1032 (set_attr "speculable1" "yes")
1033 (set_attr "speculable2" "no, yes,no, no, no, no, yes,no,no")])
1034
1035;; With no offsettable memory references, we've got to have a scratch
1036;; around to play with the second word if the variable winds up in GRs.
1037(define_expand "movxf"
1038 [(set (match_operand:XF 0 "general_operand" "")
1039 (match_operand:XF 1 "general_operand" ""))]
1040 ""
1041{
1042 if (ia64_expand_movxf_movrf (XFmode, operands))
1043 DONE;
1044})
1045
1046;; ??? There's no easy way to mind volatile acquire/release semantics.
1047
1048(define_insn "movxf_internal"
1049 [(set (match_operand:XF 0 "destination_operand" "=f,f, m")
1050 (match_operand:XF 1 "general_operand" "fG,m,fG"))]
1051 "ia64_move_ok (operands[0], operands[1])"
1052 "@
1053 mov %0 = %F1
1054 ldfe %0 = %1%P1
1055 stfe %0 = %F1%P0"
1056 [(set_attr "itanium_class" "fmisc,fld,stf")
1057 (set_attr "speculable1" "yes")
1058 (set_attr "speculable2" "no, yes,no")])
1059
1060;; Same as for movxf, but for RFmode.
1061(define_expand "movrf"
1062 [(set (match_operand:RF 0 "general_operand" "")
1063 (match_operand:RF 1 "general_operand" ""))]
1064 ""
1065{
1066 if (ia64_expand_movxf_movrf (RFmode, operands))
1067 DONE;
1068})
1069
1070(define_insn "*movrf_internal"
1071 [(set (match_operand:RF 0 "destination_operand" "=f,f, m")
1072 (match_operand:RF 1 "general_operand" "fG,m,fG"))]
1073 "ia64_move_ok (operands[0], operands[1])"
1074 "@
1075 mov %0 = %F1
1076 ldf.fill %0 = %1%P1
1077 stf.spill %0 = %F1%P0"
1078 [(set_attr "itanium_class" "fmisc,fld,stf")])
1079
1080;; Better code generation via insns that deal with TFmode register pairs
1081;; directly. Same concerns apply as for TImode.
1082(define_expand "movtf"
1083 [(set (match_operand:TF 0 "general_operand" "")
1084 (match_operand:TF 1 "general_operand" ""))]
1085 ""
1086{
1087 rtx op1 = ia64_expand_move (operands[0], operands[1]);
1088 if (!op1)
1089 DONE;
1090 operands[1] = op1;
1091})
1092
1093(define_insn_and_split "*movtf_internal"
1094 [(set (match_operand:TF 0 "destination_operand" "=r,r,m")
1095 (match_operand:TF 1 "general_operand" "ri,m,r"))]
1096 "ia64_move_ok (operands[0], operands[1])"
1097 "#"
1098 "reload_completed"
1099 [(const_int 0)]
1100{
1101 ia64_split_tmode_move (operands);
1102 DONE;
1103}
1104 [(set_attr "itanium_class" "unknown")
1105 (set_attr "predicable" "no")])
1106
1107\f
1108;; ::::::::::::::::::::
1109;; ::
1110;; :: Conversions
1111;; ::
1112;; ::::::::::::::::::::
1113
1114;; Signed conversions from a smaller integer to a larger integer
1115
1116(define_insn "extendqidi2"
1117 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1118 (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
1119 ""
1120 "sxt1 %0 = %1"
1121 [(set_attr "itanium_class" "xtd")])
1122
1123(define_insn "extendhidi2"
1124 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1125 (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
1126 ""
1127 "sxt2 %0 = %1"
1128 [(set_attr "itanium_class" "xtd")])
1129
1130(define_insn "extendsidi2"
1131 [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
1132 (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
1133 ""
1134 "@
1135 sxt4 %0 = %1
1136 fsxt.r %0 = %1, %1"
1137 [(set_attr "itanium_class" "xtd,fmisc")])
1138
1139;; Unsigned conversions from a smaller integer to a larger integer
1140
1141(define_insn "zero_extendqidi2"
1142 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
1143 (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
1144 ""
1145 "@
1146 zxt1 %0 = %1
1147 ld1%O1 %0 = %1%P1"
1148 [(set_attr "itanium_class" "xtd,ld")
1149 (set_attr "speculable1" "yes")
1150 (set_attr "speculable2" "no, yes")])
1151
1152(define_insn "zero_extendhidi2"
1153 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
1154 (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
1155 ""
1156 "@
1157 zxt2 %0 = %1
1158 ld2%O1 %0 = %1%P1"
1159 [(set_attr "itanium_class" "xtd,ld")
1160 (set_attr "speculable1" "yes")
1161 (set_attr "speculable2" "no, yes")])
1162
1163(define_insn "zero_extendsidi2"
1164 [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
1165 (zero_extend:DI
1166 (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
1167 ""
1168 "@
1169 addp4 %0 = %1, r0
1170 ld4%O1 %0 = %1%P1
1171 fmix.r %0 = f0, %1"
1172 [(set_attr "itanium_class" "ialu,ld,fmisc")
1173 (set_attr "speculable1" "yes")
1174 (set_attr "speculable2" "no, yes,no")])
1175
1176;; Convert between floating point types of different sizes.
1177
1178;; At first glance, it would appear that emitting fnorm for an extending
1179;; conversion is unnecessary. However, the stf and getf instructions work
1180;; correctly only if the input is properly rounded for its type. In
1181;; particular, we get the wrong result for getf.d/stfd if the input is a
1182;; denorm single. Since we don't know what the next instruction will be, we
1183;; have to emit an fnorm.
1184
1185;; ??? Optimization opportunity here. Get rid of the insn altogether
1186;; when we can. Should probably use a scheme like has been proposed
1187;; for ia32 in dealing with operands that match unary operators. This
1188;; would let combine merge the thing into adjacent insns. See also how the
1189;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
1190;; se_register_operand.
1191
1192(define_insn "extendsfdf2"
1193 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1194 (float_extend:DF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))]
1195 ""
1196 "fnorm.d %0 = %F1"
1197 [(set_attr "itanium_class" "fmac")])
1198
1199(define_insn "extendsfxf2"
1200 [(set (match_operand:XF 0 "fr_register_operand" "=f")
1201 (float_extend:XF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))]
1202 ""
1203 "fnorm %0 = %F1"
1204 [(set_attr "itanium_class" "fmac")])
1205
1206(define_insn "extenddfxf2"
1207 [(set (match_operand:XF 0 "fr_register_operand" "=f")
1208 (float_extend:XF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")))]
1209 ""
1210 "fnorm %0 = %F1"
1211 [(set_attr "itanium_class" "fmac")])
1212
1213(define_insn "truncdfsf2"
1214 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1215 (float_truncate:SF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")))]
1216 ""
1217 "fnorm.s %0 = %F1"
1218 [(set_attr "itanium_class" "fmac")])
1219
1220(define_insn "truncxfsf2"
1221 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1222 (float_truncate:SF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")))]
1223 ""
1224 "fnorm.s %0 = %F1"
1225 [(set_attr "itanium_class" "fmac")])
1226
1227(define_insn "truncxfdf2"
1228 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1229 (float_truncate:DF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")))]
1230 ""
1231 "fnorm.d %0 = %F1"
1232 [(set_attr "itanium_class" "fmac")])
1233
1234;; Convert between signed integer types and floating point.
1235
1236(define_insn "floatdirf2"
1237 [(set (match_operand:RF 0 "fr_register_operand" "=f")
1238 (float:RF (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG")))]
1239 ""
1240 "fcvt.xf %0 = %F1"
1241 [(set_attr "itanium_class" "fcvtfx")])
1242
1243(define_insn "floatdixf2"
1244 [(set (match_operand:XF 0 "fr_register_operand" "=f")
1245 (float:XF (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG")))]
1246 ""
1247 "fcvt.xf %0 = %F1"
1248 [(set_attr "itanium_class" "fcvtfx")])
1249
1250(define_insn "fix_truncsfdi2"
1251 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1252 (fix:DI (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))]
1253 ""
1254 "fcvt.fx.trunc %0 = %F1"
1255 [(set_attr "itanium_class" "fcvtfx")])
1256
1257(define_insn "fix_truncdfdi2"
1258 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1259 (fix:DI (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")))]
1260 ""
1261 "fcvt.fx.trunc %0 = %F1"
1262 [(set_attr "itanium_class" "fcvtfx")])
1263
1264(define_insn "fix_truncxfdi2"
1265 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1266 (fix:DI (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")))]
1267 ""
1268 "fcvt.fx.trunc %0 = %F1"
1269 [(set_attr "itanium_class" "fcvtfx")])
1270
1271(define_insn "fix_truncrfdi2"
1272 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1273 (fix:DI (match_operand:RF 1 "fr_reg_or_fp01_operand" "fG")))]
1274 ""
1275 "fcvt.fx.trunc %0 = %F1"
1276 [(set_attr "itanium_class" "fcvtfx")])
1277
1278;; Convert between unsigned integer types and floating point.
1279
1280(define_insn "floatunsdisf2"
1281 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1282 (unsigned_float:SF (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG")))]
1283 ""
1284 "fcvt.xuf.s %0 = %F1"
1285 [(set_attr "itanium_class" "fcvtfx")])
1286
1287(define_insn "floatunsdidf2"
1288 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1289 (unsigned_float:DF (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG")))]
1290 ""
1291 "fcvt.xuf.d %0 = %F1"
1292 [(set_attr "itanium_class" "fcvtfx")])
1293
1294(define_insn "floatunsdixf2"
1295 [(set (match_operand:XF 0 "fr_register_operand" "=f")
1296 (unsigned_float:XF (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG")))]
1297 ""
1298 "fcvt.xuf %0 = %F1"
1299 [(set_attr "itanium_class" "fcvtfx")])
1300
1301(define_insn "floatunsdirf2"
1302 [(set (match_operand:RF 0 "fr_register_operand" "=f")
1303 (unsigned_float:RF (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG")))]
1304 ""
1305 "fcvt.xuf %0 = %F1"
1306 [(set_attr "itanium_class" "fcvtfx")])
1307
1308(define_insn "fixuns_truncsfdi2"
1309 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1310 (unsigned_fix:DI (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))]
1311 ""
1312 "fcvt.fxu.trunc %0 = %F1"
1313 [(set_attr "itanium_class" "fcvtfx")])
1314
1315(define_insn "fixuns_truncdfdi2"
1316 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1317 (unsigned_fix:DI (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")))]
1318 ""
1319 "fcvt.fxu.trunc %0 = %F1"
1320 [(set_attr "itanium_class" "fcvtfx")])
1321
1322(define_insn "fixuns_truncxfdi2"
1323 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1324 (unsigned_fix:DI (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")))]
1325 ""
1326 "fcvt.fxu.trunc %0 = %F1"
1327 [(set_attr "itanium_class" "fcvtfx")])
1328
1329(define_insn "fixuns_truncrfdi2"
1330 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1331 (unsigned_fix:DI (match_operand:RF 1 "fr_reg_or_fp01_operand" "fG")))]
1332 ""
1333 "fcvt.fxu.trunc %0 = %F1"
1334 [(set_attr "itanium_class" "fcvtfx")])
1335\f
1336;; ::::::::::::::::::::
1337;; ::
1338;; :: Bit field extraction
1339;; ::
1340;; ::::::::::::::::::::
1341
1342(define_insn "extv"
1343 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1344 (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1345 (match_operand:DI 2 "extr_len_operand" "n")
1346 (match_operand:DI 3 "shift_count_operand" "M")))]
1347 ""
1348 "extr %0 = %1, %3, %2"
1349 [(set_attr "itanium_class" "ishf")])
1350
1351(define_insn "extzv"
1352 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1353 (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1354 (match_operand:DI 2 "extr_len_operand" "n")
1355 (match_operand:DI 3 "shift_count_operand" "M")))]
1356 ""
1357 "extr.u %0 = %1, %3, %2"
1358 [(set_attr "itanium_class" "ishf")])
1359
1360;; Insert a bit field.
1361;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1362;; Source1 can be 0 or -1.
1363;; Source2 can be 0.
1364
1365;; ??? Actual dep instruction is more powerful than what these insv
1366;; patterns support. Unfortunately, combine is unable to create patterns
1367;; where source2 != dest.
1368
1369(define_expand "insv"
1370 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
1371 (match_operand:DI 1 "const_int_operand" "")
1372 (match_operand:DI 2 "const_int_operand" ""))
1373 (match_operand:DI 3 "nonmemory_operand" ""))]
1374 ""
1375{
1376 int width = INTVAL (operands[1]);
1377 int shift = INTVAL (operands[2]);
1378
1379 /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1380 pseudo. */
1381 if (! register_operand (operands[3], DImode)
1382 && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1383 operands[3] = force_reg (DImode, operands[3]);
1384
1385 /* If this is a single dep instruction, we have nothing to do. */
1386 if (! ((register_operand (operands[3], DImode) && width <= 16)
1387 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1388 {
1389 /* Check for cases that can be implemented with a mix instruction. */
1390 if (width == 32 && shift == 0)
1391 {
1392 /* Directly generating the mix4left instruction confuses
1393 optimize_bit_field in function.c. Since this is performing
1394 a useful optimization, we defer generation of the complicated
1395 mix4left RTL to the first splitting phase. */
1396 rtx tmp = gen_reg_rtx (DImode);
1397 emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1398 DONE;
1399 }
1400 else if (width == 32 && shift == 32)
1401 {
1402 emit_insn (gen_mix4right (operands[0], operands[3]));
1403 DONE;
1404 }
1405
1406 /* We could handle remaining cases by emitting multiple dep
1407 instructions.
1408
1409 If we need more than two dep instructions then we lose. A 6
1410 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1411 mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles,
1412 the latter is 6 cycles on an Itanium (TM) processor, because there is
1413 only one function unit that can execute dep and shr immed.
1414
1415 If we only need two dep instruction, then we still lose.
1416 mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away
1417 the unnecessary mov, this is still undesirable because it will be
1418 hard to optimize, and it creates unnecessary pressure on the I0
1419 function unit. */
1420
1421 FAIL;
1422
1423#if 0
1424 /* This code may be useful for other IA-64 processors, so we leave it in
1425 for now. */
1426 while (width > 16)
1427 {
1428 rtx tmp;
1429
1430 emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1431 operands[3]));
1432 shift += 16;
1433 width -= 16;
1434 tmp = gen_reg_rtx (DImode);
1435 emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1436 operands[3] = tmp;
1437 }
1438 operands[1] = GEN_INT (width);
1439 operands[2] = GEN_INT (shift);
1440#endif
1441 }
1442})
1443
1444(define_insn "*insv_internal"
1445 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1446 (match_operand:DI 1 "const_int_operand" "n")
1447 (match_operand:DI 2 "const_int_operand" "n"))
1448 (match_operand:DI 3 "nonmemory_operand" "rP"))]
1449 "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
1450 || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1451 "dep %0 = %3, %0, %2, %1"
1452 [(set_attr "itanium_class" "ishf")])
1453
1454;; Combine doesn't like to create bit-field insertions into zero.
1455(define_insn "*shladdp4_internal"
1456 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1457 (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1458 (match_operand:DI 2 "shladd_log2_operand" "n"))
1459 (match_operand:DI 3 "const_int_operand" "n")))]
1460 "ia64_depz_field_mask (operands[3], operands[2]) + INTVAL (operands[2]) == 32"
1461 "shladdp4 %0 = %1, %2, r0"
1462 [(set_attr "itanium_class" "ialu")])
1463
1464(define_insn "*depz_internal"
1465 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1466 (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1467 (match_operand:DI 2 "const_int_operand" "M"))
1468 (match_operand:DI 3 "const_int_operand" "n")))]
1469 "satisfies_constraint_M (operands[2])
1470 && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1471{
1472 operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1473 return "%,dep.z %0 = %1, %2, %3";
1474}
1475 [(set_attr "itanium_class" "ishf")])
1476
1477(define_insn "shift_mix4left"
1478 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1479 (const_int 32) (const_int 0))
1480 (match_operand:DI 1 "gr_register_operand" "r"))
1481 (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
1482 ""
1483 "#"
1484 [(set_attr "itanium_class" "unknown")])
1485
1486(define_split
1487 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1488 (const_int 32) (const_int 0))
1489 (match_operand:DI 1 "register_operand" ""))
1490 (clobber (match_operand:DI 2 "register_operand" ""))]
1491 ""
1492 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1493 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1494 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1495 "operands[3] = operands[2];")
1496
1497(define_insn "*mix4left"
1498 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1499 (const_int 32) (const_int 0))
1500 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
1501 (const_int 32)))]
1502 ""
1503 "mix4.l %0 = %0, %r1"
1504 [(set_attr "itanium_class" "mmshf")])
1505
1506(define_insn "mix4right"
1507 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1508 (const_int 32) (const_int 32))
1509 (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
1510 ""
1511 "mix4.r %0 = %r1, %0"
1512 [(set_attr "itanium_class" "mmshf")])
1513
1514;; This is used by the rotrsi3 pattern.
1515
1516(define_insn "*mix4right_3op"
1517 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1518 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1519 (ashift:DI (zero_extend:DI
1520 (match_operand:SI 2 "gr_register_operand" "r"))
1521 (const_int 32))))]
1522 ""
1523 "mix4.r %0 = %2, %1"
1524 [(set_attr "itanium_class" "mmshf")])
1525
1526\f
1527;; ::::::::::::::::::::
1528;; ::
1529;; :: 1-bit Integer arithmetic
1530;; ::
1531;; ::::::::::::::::::::
1532
1533(define_insn_and_split "andbi3"
1534 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1535 (and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1536 (match_operand:BI 2 "register_operand" "c,r,r")))]
1537 ""
1538 "@
1539 #
1540 tbit.nz.and.orcm %0, %I0 = %2, 0
1541 and %0 = %2, %1"
1542 "reload_completed
1543 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1544 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1545 [(cond_exec (eq (match_dup 2) (const_int 0))
1546 (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1547 (match_dup 0))))]
1548 ""
1549 [(set_attr "itanium_class" "unknown,tbit,ilog")])
1550
1551(define_insn_and_split "*andcmbi3"
1552 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1553 (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
1554 (match_operand:BI 2 "register_operand" "0,0,r")))]
1555 ""
1556 "@
1557 #
1558 tbit.z.and.orcm %0, %I0 = %1, 0
1559 andcm %0 = %2, %1"
1560 "reload_completed
1561 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1562 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1563 [(cond_exec (ne (match_dup 1) (const_int 0))
1564 (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1565 (match_dup 0))))]
1566 ""
1567 [(set_attr "itanium_class" "unknown,tbit,ilog")])
1568
1569(define_insn_and_split "iorbi3"
1570 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1571 (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1572 (match_operand:BI 2 "register_operand" "c,r,r")))]
1573 ""
1574 "@
1575 #
1576 tbit.nz.or.andcm %0, %I0 = %2, 0
1577 or %0 = %2, %1"
1578 "reload_completed
1579 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1580 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1581 [(cond_exec (ne (match_dup 2) (const_int 0))
1582 (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1583 (match_dup 0))))]
1584 ""
1585 [(set_attr "itanium_class" "unknown,tbit,ilog")])
1586
1587(define_insn_and_split "*iorcmbi3"
1588 [(set (match_operand:BI 0 "register_operand" "=c,c")
1589 (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
1590 (match_operand:BI 2 "register_operand" "0,0")))]
1591 ""
1592 "@
1593 #
1594 tbit.z.or.andcm %0, %I0 = %1, 0"
1595 "reload_completed
1596 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1597 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1598 [(cond_exec (eq (match_dup 1) (const_int 0))
1599 (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1600 (match_dup 0))))]
1601 ""
1602 [(set_attr "itanium_class" "unknown,tbit")])
1603
1604(define_insn "one_cmplbi2"
1605 [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
1606 (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
1607 (clobber (match_scratch:BI 2 "=X,X,c,X"))]
1608 ""
1609 "@
1610 tbit.z %0, %I0 = %1, 0
1611 xor %0 = 1, %1
1612 #
1613 #"
1614 [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
1615
1616(define_split
1617 [(set (match_operand:BI 0 "register_operand" "")
1618 (not:BI (match_operand:BI 1 "register_operand" "")))
1619 (clobber (match_scratch:BI 2 ""))]
1620 "reload_completed
1621 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1622 && rtx_equal_p (operands[0], operands[1])"
1623 [(set (match_dup 4) (match_dup 3))
1624 (set (match_dup 0) (const_int 1))
1625 (cond_exec (ne (match_dup 2) (const_int 0))
1626 (set (match_dup 0) (const_int 0)))
1627 (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1628 "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
1629 operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
1630
1631(define_split
1632 [(set (match_operand:BI 0 "register_operand" "")
1633 (not:BI (match_operand:BI 1 "register_operand" "")))
1634 (clobber (match_scratch:BI 2 ""))]
1635 "reload_completed
1636 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1637 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
1638 && ! rtx_equal_p (operands[0], operands[1])"
1639 [(cond_exec (ne (match_dup 1) (const_int 0))
1640 (set (match_dup 0) (const_int 0)))
1641 (cond_exec (eq (match_dup 1) (const_int 0))
1642 (set (match_dup 0) (const_int 1)))
1643 (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1644 "")
1645
1646(define_insn "*cmpsi_and_0"
1647 [(set (match_operand:BI 0 "register_operand" "=c")
1648 (and:BI (match_operator:BI 4 "predicate_operator"
1649 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1650 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1651 (match_operand:BI 1 "register_operand" "0")))]
1652 ""
1653 "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
1654 [(set_attr "itanium_class" "icmp")])
1655
1656(define_insn "*cmpsi_and_1"
1657 [(set (match_operand:BI 0 "register_operand" "=c")
1658 (and:BI (match_operator:BI 3 "signed_inequality_operator"
1659 [(match_operand:SI 2 "gr_register_operand" "r")
1660 (const_int 0)])
1661 (match_operand:BI 1 "register_operand" "0")))]
1662 ""
1663 "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
1664 [(set_attr "itanium_class" "icmp")])
1665
1666(define_insn "*cmpsi_andnot_0"
1667 [(set (match_operand:BI 0 "register_operand" "=c")
1668 (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1669 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1670 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1671 (match_operand:BI 1 "register_operand" "0")))]
1672 ""
1673 "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
1674 [(set_attr "itanium_class" "icmp")])
1675
1676(define_insn "*cmpsi_andnot_1"
1677 [(set (match_operand:BI 0 "register_operand" "=c")
1678 (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1679 [(match_operand:SI 2 "gr_register_operand" "r")
1680 (const_int 0)]))
1681 (match_operand:BI 1 "register_operand" "0")))]
1682 ""
1683 "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
1684 [(set_attr "itanium_class" "icmp")])
1685
1686(define_insn "*cmpdi_and_0"
1687 [(set (match_operand:BI 0 "register_operand" "=c")
1688 (and:BI (match_operator:BI 4 "predicate_operator"
1689 [(match_operand:DI 2 "gr_register_operand" "r")
1690 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1691 (match_operand:BI 1 "register_operand" "0")))]
1692 ""
1693 "cmp.%C4.and.orcm %0, %I0 = %3, %2"
1694 [(set_attr "itanium_class" "icmp")])
1695
1696(define_insn "*cmpdi_and_1"
1697 [(set (match_operand:BI 0 "register_operand" "=c")
1698 (and:BI (match_operator:BI 3 "signed_inequality_operator"
1699 [(match_operand:DI 2 "gr_register_operand" "r")
1700 (const_int 0)])
1701 (match_operand:BI 1 "register_operand" "0")))]
1702 ""
1703 "cmp.%C3.and.orcm %0, %I0 = r0, %2"
1704 [(set_attr "itanium_class" "icmp")])
1705
1706(define_insn "*cmpdi_andnot_0"
1707 [(set (match_operand:BI 0 "register_operand" "=c")
1708 (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1709 [(match_operand:DI 2 "gr_register_operand" "r")
1710 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1711 (match_operand:BI 1 "register_operand" "0")))]
1712 ""
1713 "cmp.%C4.or.andcm %I0, %0 = %3, %2"
1714 [(set_attr "itanium_class" "icmp")])
1715
1716(define_insn "*cmpdi_andnot_1"
1717 [(set (match_operand:BI 0 "register_operand" "=c")
1718 (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1719 [(match_operand:DI 2 "gr_register_operand" "r")
1720 (const_int 0)]))
1721 (match_operand:BI 1 "register_operand" "0")))]
1722 ""
1723 "cmp.%C3.or.andcm %I0, %0 = r0, %2"
1724 [(set_attr "itanium_class" "icmp")])
1725
1726(define_insn "*tbit_and_0"
1727 [(set (match_operand:BI 0 "register_operand" "=c")
1728 (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1729 (const_int 1))
1730 (const_int 0))
1731 (match_operand:BI 2 "register_operand" "0")))]
1732 ""
1733 "tbit.nz.and.orcm %0, %I0 = %1, 0"
1734 [(set_attr "itanium_class" "tbit")])
1735
1736(define_insn "*tbit_and_1"
1737 [(set (match_operand:BI 0 "register_operand" "=c")
1738 (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1739 (const_int 1))
1740 (const_int 0))
1741 (match_operand:BI 2 "register_operand" "0")))]
1742 ""
1743 "tbit.z.and.orcm %0, %I0 = %1, 0"
1744 [(set_attr "itanium_class" "tbit")])
1745
1746(define_insn "*tbit_and_2"
1747 [(set (match_operand:BI 0 "register_operand" "=c")
1748 (and:BI (ne:BI (zero_extract:DI
1749 (match_operand:DI 1 "gr_register_operand" "r")
1750 (const_int 1)
1751 (match_operand:DI 2 "shift_count_operand" "M"))
1752 (const_int 0))
1753 (match_operand:BI 3 "register_operand" "0")))]
1754 ""
1755 "tbit.nz.and.orcm %0, %I0 = %1, %2"
1756 [(set_attr "itanium_class" "tbit")])
1757
1758(define_insn "*tbit_and_3"
1759 [(set (match_operand:BI 0 "register_operand" "=c")
1760 (and:BI (eq:BI (zero_extract:DI
1761 (match_operand:DI 1 "gr_register_operand" "r")
1762 (const_int 1)
1763 (match_operand:DI 2 "shift_count_operand" "M"))
1764 (const_int 0))
1765 (match_operand:BI 3 "register_operand" "0")))]
1766 ""
1767 "tbit.z.and.orcm %0, %I0 = %1, %2"
1768 [(set_attr "itanium_class" "tbit")])
1769
1770(define_insn "*cmpsi_or_0"
1771 [(set (match_operand:BI 0 "register_operand" "=c")
1772 (ior:BI (match_operator:BI 4 "predicate_operator"
1773 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1774 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1775 (match_operand:BI 1 "register_operand" "0")))]
1776 ""
1777 "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
1778 [(set_attr "itanium_class" "icmp")])
1779
1780(define_insn "*cmpsi_or_1"
1781 [(set (match_operand:BI 0 "register_operand" "=c")
1782 (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1783 [(match_operand:SI 2 "gr_register_operand" "r")
1784 (const_int 0)])
1785 (match_operand:BI 1 "register_operand" "0")))]
1786 ""
1787 "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
1788 [(set_attr "itanium_class" "icmp")])
1789
1790(define_insn "*cmpsi_orcm_0"
1791 [(set (match_operand:BI 0 "register_operand" "=c")
1792 (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1793 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1794 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1795 (match_operand:BI 1 "register_operand" "0")))]
1796 ""
1797 "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
1798 [(set_attr "itanium_class" "icmp")])
1799
1800(define_insn "*cmpsi_orcm_1"
1801 [(set (match_operand:BI 0 "register_operand" "=c")
1802 (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1803 [(match_operand:SI 2 "gr_register_operand" "r")
1804 (const_int 0)]))
1805 (match_operand:BI 1 "register_operand" "0")))]
1806 ""
1807 "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
1808 [(set_attr "itanium_class" "icmp")])
1809
1810(define_insn "*cmpdi_or_0"
1811 [(set (match_operand:BI 0 "register_operand" "=c")
1812 (ior:BI (match_operator:BI 4 "predicate_operator"
1813 [(match_operand:DI 2 "gr_register_operand" "r")
1814 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1815 (match_operand:BI 1 "register_operand" "0")))]
1816 ""
1817 "cmp.%C4.or.andcm %0, %I0 = %3, %2"
1818 [(set_attr "itanium_class" "icmp")])
1819
1820(define_insn "*cmpdi_or_1"
1821 [(set (match_operand:BI 0 "register_operand" "=c")
1822 (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1823 [(match_operand:DI 2 "gr_register_operand" "r")
1824 (const_int 0)])
1825 (match_operand:BI 1 "register_operand" "0")))]
1826 ""
1827 "cmp.%C3.or.andcm %0, %I0 = r0, %2"
1828 [(set_attr "itanium_class" "icmp")])
1829
1830(define_insn "*cmpdi_orcm_0"
1831 [(set (match_operand:BI 0 "register_operand" "=c")
1832 (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1833 [(match_operand:DI 2 "gr_register_operand" "r")
1834 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1835 (match_operand:BI 1 "register_operand" "0")))]
1836 ""
1837 "cmp.%C4.and.orcm %I0, %0 = %3, %2"
1838 [(set_attr "itanium_class" "icmp")])
1839
1840(define_insn "*cmpdi_orcm_1"
1841 [(set (match_operand:BI 0 "register_operand" "=c")
1842 (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1843 [(match_operand:DI 2 "gr_register_operand" "r")
1844 (const_int 0)]))
1845 (match_operand:BI 1 "register_operand" "0")))]
1846 ""
1847 "cmp.%C3.and.orcm %I0, %0 = r0, %2"
1848 [(set_attr "itanium_class" "icmp")])
1849
1850(define_insn "*tbit_or_0"
1851 [(set (match_operand:BI 0 "register_operand" "=c")
1852 (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1853 (const_int 1))
1854 (const_int 0))
1855 (match_operand:BI 2 "register_operand" "0")))]
1856 ""
1857 "tbit.nz.or.andcm %0, %I0 = %1, 0"
1858 [(set_attr "itanium_class" "tbit")])
1859
1860(define_insn "*tbit_or_1"
1861 [(set (match_operand:BI 0 "register_operand" "=c")
1862 (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1863 (const_int 1))
1864 (const_int 0))
1865 (match_operand:BI 2 "register_operand" "0")))]
1866 ""
1867 "tbit.z.or.andcm %0, %I0 = %1, 0"
1868 [(set_attr "itanium_class" "tbit")])
1869
1870(define_insn "*tbit_or_2"
1871 [(set (match_operand:BI 0 "register_operand" "=c")
1872 (ior:BI (ne:BI (zero_extract:DI
1873 (match_operand:DI 1 "gr_register_operand" "r")
1874 (const_int 1)
1875 (match_operand:DI 2 "shift_count_operand" "M"))
1876 (const_int 0))
1877 (match_operand:BI 3 "register_operand" "0")))]
1878 ""
1879 "tbit.nz.or.andcm %0, %I0 = %1, %2"
1880 [(set_attr "itanium_class" "tbit")])
1881
1882(define_insn "*tbit_or_3"
1883 [(set (match_operand:BI 0 "register_operand" "=c")
1884 (ior:BI (eq:BI (zero_extract:DI
1885 (match_operand:DI 1 "gr_register_operand" "r")
1886 (const_int 1)
1887 (match_operand:DI 2 "shift_count_operand" "M"))
1888 (const_int 0))
1889 (match_operand:BI 3 "register_operand" "0")))]
1890 ""
1891 "tbit.z.or.andcm %0, %I0 = %1, %2"
1892 [(set_attr "itanium_class" "tbit")])
1893
1894;; Transform test of and/or of setcc into parallel comparisons.
1895
1896(define_split
1897 [(set (match_operand:BI 0 "register_operand" "")
1898 (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1899 (const_int 0))
1900 (match_operand:DI 3 "register_operand" ""))
1901 (const_int 0)))]
1902 ""
1903 [(set (match_dup 0)
1904 (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1905 (match_dup 2)))]
1906 "")
1907
1908(define_split
1909 [(set (match_operand:BI 0 "register_operand" "")
1910 (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1911 (const_int 0))
1912 (match_operand:DI 3 "register_operand" ""))
1913 (const_int 0)))]
1914 ""
1915 [(set (match_dup 0)
1916 (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1917 (match_dup 2)))
1918 (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1919 (clobber (scratch))])]
1920 "")
1921
1922(define_split
1923 [(set (match_operand:BI 0 "register_operand" "")
1924 (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1925 (const_int 0))
1926 (match_operand:DI 3 "register_operand" ""))
1927 (const_int 0)))]
1928 ""
1929 [(set (match_dup 0)
1930 (ior:BI (ne:BI (match_dup 3) (const_int 0))
1931 (match_dup 2)))]
1932 "")
1933
1934(define_split
1935 [(set (match_operand:BI 0 "register_operand" "")
1936 (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1937 (const_int 0))
1938 (match_operand:DI 3 "register_operand" ""))
1939 (const_int 0)))]
1940 ""
1941 [(set (match_dup 0)
1942 (ior:BI (ne:BI (match_dup 3) (const_int 0))
1943 (match_dup 2)))
1944 (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1945 (clobber (scratch))])]
1946 "")
1947
1948;; ??? Incredibly hackish. Either need four proper patterns with all
1949;; the alternatives, or rely on sched1 to split the insn and hope that
1950;; nothing bad happens to the comparisons in the meantime.
1951;;
1952;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
1953;; that we're doing height reduction.
1954;
1955;(define_insn_and_split ""
1956; [(set (match_operand:BI 0 "register_operand" "=c")
1957; (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1958; [(match_operand 2 "" "")
1959; (match_operand 3 "" "")])
1960; (match_operator:BI 4 "comparison_operator"
1961; [(match_operand 5 "" "")
1962; (match_operand 6 "" "")]))
1963; (match_dup 0)))]
1964; "flag_schedule_insns"
1965; "#"
1966; ""
1967; [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
1968; (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
1969; "")
1970;
1971;(define_insn_and_split ""
1972; [(set (match_operand:BI 0 "register_operand" "=c")
1973; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1974; [(match_operand 2 "" "")
1975; (match_operand 3 "" "")])
1976; (match_operator:BI 4 "comparison_operator"
1977; [(match_operand 5 "" "")
1978; (match_operand 6 "" "")]))
1979; (match_dup 0)))]
1980; "flag_schedule_insns"
1981; "#"
1982; ""
1983; [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
1984; (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
1985; "")
1986;
1987;(define_split
1988; [(set (match_operand:BI 0 "register_operand" "")
1989; (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1990; [(match_operand 2 "" "")
1991; (match_operand 3 "" "")])
1992; (match_operand:BI 7 "register_operand" ""))
1993; (and:BI (match_operator:BI 4 "comparison_operator"
1994; [(match_operand 5 "" "")
1995; (match_operand 6 "" "")])
1996; (match_operand:BI 8 "register_operand" ""))))]
1997; ""
1998; [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
1999; (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
2000; (match_dup 0)))]
2001; "")
2002;
2003;(define_split
2004; [(set (match_operand:BI 0 "register_operand" "")
2005; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
2006; [(match_operand 2 "" "")
2007; (match_operand 3 "" "")])
2008; (match_operand:BI 7 "register_operand" ""))
2009; (ior:BI (match_operator:BI 4 "comparison_operator"
2010; [(match_operand 5 "" "")
2011; (match_operand 6 "" "")])
2012; (match_operand:BI 8 "register_operand" ""))))]
2013; ""
2014; [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
2015; (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
2016; (match_dup 0)))]
2017; "")
2018
2019;; Try harder to avoid predicate copies by duplicating compares.
2020;; Note that we'll have already split the predicate copy, which
2021;; is kind of a pain, but oh well.
2022
2023(define_peephole2
2024 [(set (match_operand:BI 0 "register_operand" "")
2025 (match_operand:BI 1 "comparison_operator" ""))
2026 (set (match_operand:CCI 2 "register_operand" "")
2027 (match_operand:CCI 3 "register_operand" ""))
2028 (set (match_operand:CCI 4 "register_operand" "")
2029 (match_operand:CCI 5 "register_operand" ""))
2030 (set (match_operand:BI 6 "register_operand" "")
2031 (unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))]
2032 "REGNO (operands[3]) == REGNO (operands[0])
2033 && REGNO (operands[4]) == REGNO (operands[0]) + 1
2034 && REGNO (operands[4]) == REGNO (operands[2]) + 1
2035 && REGNO (operands[6]) == REGNO (operands[2])"
2036 [(set (match_dup 0) (match_dup 1))
2037 (set (match_dup 6) (match_dup 7))]
2038 "operands[7] = copy_rtx (operands[1]);")
2039\f
2040;; ::::::::::::::::::::
2041;; ::
2042;; :: 16-bit Integer arithmetic
2043;; ::
2044;; ::::::::::::::::::::
2045
2046(define_insn "mulhi3"
2047 [(set (match_operand:HI 0 "gr_register_operand" "=r")
2048 (mult:HI (match_operand:HI 1 "gr_register_operand" "r")
2049 (match_operand:HI 2 "gr_register_operand" "r")))]
2050 ""
2051 "pmpy2.r %0 = %1, %2"
2052 [(set_attr "itanium_class" "mmmul")])
2053
2054\f
2055;; ::::::::::::::::::::
2056;; ::
2057;; :: 32-bit Integer arithmetic
2058;; ::
2059;; ::::::::::::::::::::
2060
2061(define_insn "addsi3"
2062 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
2063 (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
2064 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
2065 ""
2066 "@
2067 add %0 = %1, %2
2068 adds %0 = %2, %1
2069 addl %0 = %2, %1"
2070 [(set_attr "itanium_class" "ialu")])
2071
2072(define_insn "*addsi3_plus1"
2073 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2074 (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
2075 (match_operand:SI 2 "gr_register_operand" "r"))
2076 (const_int 1)))]
2077 ""
2078 "add %0 = %1, %2, 1"
2079 [(set_attr "itanium_class" "ialu")])
2080
2081(define_insn "*addsi3_plus1_alt"
2082 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2083 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
2084 (const_int 2))
2085 (const_int 1)))]
2086 ""
2087 "add %0 = %1, %1, 1"
2088 [(set_attr "itanium_class" "ialu")])
2089
2090(define_insn "*addsi3_shladd"
2091 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2092 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
2093 (match_operand:SI 2 "shladd_operand" "n"))
2094 (match_operand:SI 3 "gr_register_operand" "r")))]
2095 ""
2096 "shladd %0 = %1, %S2, %3"
2097 [(set_attr "itanium_class" "ialu")])
2098
2099(define_insn "subsi3"
2100 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2101 (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
2102 (match_operand:SI 2 "gr_register_operand" "r")))]
2103 ""
2104 "sub %0 = %1, %2"
2105 [(set_attr "itanium_class" "ialu")])
2106
2107(define_insn "*subsi3_minus1"
2108 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2109 (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
2110 (match_operand:SI 2 "gr_register_operand" "r")))]
2111 ""
2112 "sub %0 = %2, %1, 1"
2113 [(set_attr "itanium_class" "ialu")])
2114
2115;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
2116
2117(define_insn "mulsi3"
2118 [(set (match_operand:SI 0 "fr_register_operand" "=f")
2119 (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
2120 (match_operand:SI 2 "grfr_register_operand" "f")))]
2121 ""
2122 "xmpy.l %0 = %1, %2"
2123 [(set_attr "itanium_class" "xmpy")])
2124
2125(define_insn "maddsi4"
2126 [(set (match_operand:SI 0 "fr_register_operand" "=f")
2127 (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
2128 (match_operand:SI 2 "grfr_register_operand" "f"))
2129 (match_operand:SI 3 "grfr_register_operand" "f")))]
2130 ""
2131 "xma.l %0 = %1, %2, %3"
2132 [(set_attr "itanium_class" "xmpy")])
2133
2134(define_insn "negsi2"
2135 [(set (match_operand:SI 0 "gr_register_operand" "=r")
2136 (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
2137 ""
2138 "sub %0 = r0, %1"
2139 [(set_attr "itanium_class" "ialu")])
2140
2141(define_expand "abssi2"
2142 [(set (match_dup 2)
2143 (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
2144 (set (match_operand:SI 0 "gr_register_operand" "")
2145 (if_then_else:SI (eq (match_dup 2) (const_int 0))
2146 (neg:SI (match_dup 1))
2147 (match_dup 1)))]
2148 ""
2149 { operands[2] = gen_reg_rtx (BImode); })
2150
2151(define_expand "sminsi3"
2152 [(set (match_dup 3)
2153 (ge:BI (match_operand:SI 1 "gr_register_operand" "")
2154 (match_operand:SI 2 "gr_register_operand" "")))
2155 (set (match_operand:SI 0 "gr_register_operand" "")
2156 (if_then_else:SI (ne (match_dup 3) (const_int 0))
2157 (match_dup 2) (match_dup 1)))]
2158 ""
2159 { operands[3] = gen_reg_rtx (BImode); })
2160
2161(define_expand "smaxsi3"
2162 [(set (match_dup 3)
2163 (ge:BI (match_operand:SI 1 "gr_register_operand" "")
2164 (match_operand:SI 2 "gr_register_operand" "")))
2165 (set (match_operand:SI 0 "gr_register_operand" "")
2166 (if_then_else:SI (ne (match_dup 3) (const_int 0))
2167 (match_dup 1) (match_dup 2)))]
2168 ""
2169 { operands[3] = gen_reg_rtx (BImode); })
2170
2171(define_expand "uminsi3"
2172 [(set (match_dup 3)
2173 (geu:BI (match_operand:SI 1 "gr_register_operand" "")
2174 (match_operand:SI 2 "gr_register_operand" "")))
2175 (set (match_operand:SI 0 "gr_register_operand" "")
2176 (if_then_else:SI (ne (match_dup 3) (const_int 0))
2177 (match_dup 2) (match_dup 1)))]
2178 ""
2179 { operands[3] = gen_reg_rtx (BImode); })
2180
2181(define_expand "umaxsi3"
2182 [(set (match_dup 3)
2183 (geu:BI (match_operand:SI 1 "gr_register_operand" "")
2184 (match_operand:SI 2 "gr_register_operand" "")))
2185 (set (match_operand:SI 0 "gr_register_operand" "")
2186 (if_then_else:SI (ne (match_dup 3) (const_int 0))
2187 (match_dup 1) (match_dup 2)))]
2188 ""
2189 { operands[3] = gen_reg_rtx (BImode); })
2190\f
2191;; ::::::::::::::::::::
2192;; ::
2193;; :: 64-bit Integer arithmetic
2194;; ::
2195;; ::::::::::::::::::::
2196
2197(define_insn "adddi3"
2198 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
2199 (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
2200 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
2201 ""
2202 "@
2203 add %0 = %1, %2
2204 adds %0 = %2, %1
2205 addl %0 = %2, %1"
2206 [(set_attr "itanium_class" "ialu")])
2207
2208(define_insn "*adddi3_plus1"
2209 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2210 (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
2211 (match_operand:DI 2 "gr_register_operand" "r"))
2212 (const_int 1)))]
2213 ""
2214 "add %0 = %1, %2, 1"
2215 [(set_attr "itanium_class" "ialu")])
2216
2217;; This has some of the same problems as shladd. We let the shladd
2218;; eliminator hack handle it, which results in the 1 being forced into
2219;; a register, but not more ugliness here.
2220(define_insn "*adddi3_plus1_alt"
2221 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2222 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2223 (const_int 2))
2224 (const_int 1)))]
2225 ""
2226 "add %0 = %1, %1, 1"
2227 [(set_attr "itanium_class" "ialu")])
2228
2229(define_insn "subdi3"
2230 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2231 (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
2232 (match_operand:DI 2 "gr_register_operand" "r")))]
2233 ""
2234 "sub %0 = %1, %2"
2235 [(set_attr "itanium_class" "ialu")])
2236
2237(define_insn "*subdi3_minus1"
2238 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2239 (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
2240 (match_operand:DI 2 "gr_register_operand" "r")))]
2241 ""
2242 "sub %0 = %2, %1, 1"
2243 [(set_attr "itanium_class" "ialu")])
2244
2245;; ??? Use grfr instead of fr because of virtual register elimination
2246;; and silly test cases multiplying by the frame pointer.
2247(define_insn "muldi3"
2248 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2249 (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2250 (match_operand:DI 2 "grfr_register_operand" "f")))]
2251 ""
2252 "xmpy.l %0 = %1, %2"
2253 [(set_attr "itanium_class" "xmpy")])
2254
2255;; ??? If operand 3 is an eliminable reg, then register elimination causes the
2256;; same problem that we have with shladd below. Unfortunately, this case is
2257;; much harder to fix because the multiply puts the result in an FP register,
2258;; but the add needs inputs from a general register. We add a spurious clobber
2259;; here so that it will be present just in case register elimination gives us
2260;; the funny result.
2261
2262;; ??? Maybe validate_changes should try adding match_scratch clobbers?
2263
2264;; ??? Maybe we should change how adds are canonicalized.
2265
2266(define_insn "madddi4"
2267 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2268 (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2269 (match_operand:DI 2 "grfr_register_operand" "f"))
2270 (match_operand:DI 3 "grfr_register_operand" "f")))
2271 (clobber (match_scratch:DI 4 "=X"))]
2272 ""
2273 "xma.l %0 = %1, %2, %3"
2274 [(set_attr "itanium_class" "xmpy")])
2275
2276;; This can be created by register elimination if operand3 of shladd is an
2277;; eliminable register or has reg_equiv_constant set.
2278
2279;; We have to use nonmemory_operand for operand 4, to ensure that the
2280;; validate_changes call inside eliminate_regs will always succeed. If it
2281;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
2282;; incorrectly.
2283
2284(define_insn "*madddi4_elim"
2285 [(set (match_operand:DI 0 "register_operand" "=&r")
2286 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
2287 (match_operand:DI 2 "register_operand" "f"))
2288 (match_operand:DI 3 "register_operand" "f"))
2289 (match_operand:DI 4 "nonmemory_operand" "rI")))
2290 (clobber (match_scratch:DI 5 "=f"))]
2291 "reload_in_progress"
2292 "#"
2293 [(set_attr "itanium_class" "unknown")])
2294
2295(define_split
2296 [(set (match_operand:DI 0 "register_operand" "")
2297 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2298 (match_operand:DI 2 "register_operand" ""))
2299 (match_operand:DI 3 "register_operand" ""))
2300 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
2301 (clobber (match_scratch:DI 5 ""))]
2302 "reload_completed"
2303 [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2304 (match_dup 3)))
2305 (clobber (match_dup 0))])
2306 (set (match_dup 0) (match_dup 5))
2307 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
2308 "")
2309
2310(define_insn "smuldi3_highpart"
2311 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2312 (truncate:DI
2313 (lshiftrt:TI
2314 (mult:TI (sign_extend:TI
2315 (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG"))
2316 (sign_extend:TI
2317 (match_operand:DI 2 "fr_reg_or_fp01_operand" "fG")))
2318 (const_int 64))))]
2319 ""
2320 "xmpy.h %0 = %F1, %F2"
2321 [(set_attr "itanium_class" "xmpy")])
2322
2323(define_insn "umuldi3_highpart"
2324 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2325 (truncate:DI
2326 (lshiftrt:TI
2327 (mult:TI (zero_extend:TI
2328 (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG"))
2329 (zero_extend:TI
2330 (match_operand:DI 2 "fr_reg_or_fp01_operand" "fG")))
2331 (const_int 64))))]
2332 ""
2333 "xmpy.hu %0 = %F1, %F2"
2334 [(set_attr "itanium_class" "xmpy")])
2335
2336(define_insn "negdi2"
2337 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2338 (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2339 ""
2340 "sub %0 = r0, %1"
2341 [(set_attr "itanium_class" "ialu")])
2342
2343(define_expand "absdi2"
2344 [(set (match_dup 2)
2345 (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2346 (set (match_operand:DI 0 "gr_register_operand" "")
2347 (if_then_else:DI (eq (match_dup 2) (const_int 0))
2348 (neg:DI (match_dup 1))
2349 (match_dup 1)))]
2350 ""
2351 { operands[2] = gen_reg_rtx (BImode); })
2352
2353(define_expand "smindi3"
2354 [(set (match_dup 3)
2355 (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2356 (match_operand:DI 2 "gr_register_operand" "")))
2357 (set (match_operand:DI 0 "gr_register_operand" "")
2358 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2359 (match_dup 2) (match_dup 1)))]
2360 ""
2361 { operands[3] = gen_reg_rtx (BImode); })
2362
2363(define_expand "smaxdi3"
2364 [(set (match_dup 3)
2365 (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2366 (match_operand:DI 2 "gr_register_operand" "")))
2367 (set (match_operand:DI 0 "gr_register_operand" "")
2368 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2369 (match_dup 1) (match_dup 2)))]
2370 ""
2371 { operands[3] = gen_reg_rtx (BImode); })
2372
2373(define_expand "umindi3"
2374 [(set (match_dup 3)
2375 (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2376 (match_operand:DI 2 "gr_register_operand" "")))
2377 (set (match_operand:DI 0 "gr_register_operand" "")
2378 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2379 (match_dup 2) (match_dup 1)))]
2380 ""
2381 { operands[3] = gen_reg_rtx (BImode); })
2382
2383(define_expand "umaxdi3"
2384 [(set (match_dup 3)
2385 (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2386 (match_operand:DI 2 "gr_register_operand" "")))
2387 (set (match_operand:DI 0 "gr_register_operand" "")
2388 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2389 (match_dup 1) (match_dup 2)))]
2390 ""
2391 { operands[3] = gen_reg_rtx (BImode); })
2392
2393(define_expand "ffsdi2"
2394 [(set (match_dup 6)
2395 (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2396 (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
2397 (set (match_dup 5) (const_int 0))
2398 (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2399 (set (match_dup 4) (popcount:DI (match_dup 3)))
2400 (set (match_operand:DI 0 "gr_register_operand" "")
2401 (if_then_else:DI (ne (match_dup 6) (const_int 0))
2402 (match_dup 5) (match_dup 4)))]
2403 ""
2404{
2405 operands[2] = gen_reg_rtx (DImode);
2406 operands[3] = gen_reg_rtx (DImode);
2407 operands[4] = gen_reg_rtx (DImode);
2408 operands[5] = gen_reg_rtx (DImode);
2409 operands[6] = gen_reg_rtx (BImode);
2410})
2411
2412(define_expand "ctzdi2"
2413 [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "")
2414 (const_int -1)))
2415 (set (match_dup 3) (not:DI (match_dup 1)))
2416 (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3)))
2417 (set (match_operand:DI 0 "gr_register_operand" "")
2418 (popcount:DI (match_dup 4)))]
2419 ""
2420{
2421 operands[2] = gen_reg_rtx (DImode);
2422 operands[3] = gen_reg_rtx (DImode);
2423 operands[4] = gen_reg_rtx (DImode);
2424})
2425
2426;; Note the computation here is op0 = 63 - (exp - 0xffff).
2427(define_expand "clzdi2"
2428 [(set (match_dup 2)
2429 (unsigned_float:XF (match_operand:DI 1 "fr_reg_or_fp01_operand" "")))
2430 (set (match_dup 3)
2431 (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP))
2432 (set (match_dup 4) (const_int 65598))
2433 (set (match_operand:DI 0 "gr_register_operand" "")
2434 (minus:DI (match_dup 4) (match_dup 3)))]
2435 ""
2436{
2437 operands[2] = gen_reg_rtx (XFmode);
2438 operands[3] = gen_reg_rtx (DImode);
2439 operands[4] = gen_reg_rtx (DImode);
2440})
2441
2442(define_insn "popcountdi2"
2443 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2444 (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2445 ""
2446 "popcnt %0 = %1"
2447 [(set_attr "itanium_class" "mmmul")])
2448
2449(define_insn "bswapdi2"
2450 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2451 (bswap:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2452 ""
2453 "mux1 %0 = %1, @rev"
2454 [(set_attr "itanium_class" "mmshf")])
2455
2456(define_insn "*getf_exp_xf"
2457 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2458 (unspec:DI [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")]
2459 UNSPEC_GETF_EXP))]
2460 ""
2461 "getf.exp %0 = %F1"
2462 [(set_attr "itanium_class" "frfr")])
2463\f
2464;; ::::::::::::::::::::
2465;; ::
2466;; :: 128-bit Integer arithmetic
2467;; ::
2468;; ::::::::::::::::::::
2469
2470(define_insn "addti3"
2471 [(set (match_operand:TI 0 "gr_register_operand" "=&r")
2472 (plus:TI (match_operand:TI 1 "gr_register_operand" "%r")
2473 (match_operand:TI 2 "gr_reg_or_14bit_operand" "rI")))
2474 (clobber (match_scratch:BI 3 "=&c"))]
2475 ""
2476 "#"
2477 [(set_attr "itanium_class" "unknown")])
2478
2479(define_split
2480 [(set (match_operand:TI 0 "register_operand" "")
2481 (plus:TI (match_operand:TI 1 "register_operand" "")
2482 (match_operand:TI 2 "register_operand" "")))
2483 (clobber (match_scratch:BI 3 ""))]
2484 "reload_completed"
2485 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
2486 (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1)))
2487 (cond_exec (eq (match_dup 3) (const_int 0))
2488 (set (match_dup 4) (plus:DI (match_dup 5) (match_dup 6))))
2489 (cond_exec (ne (match_dup 3) (const_int 0))
2490 (set (match_dup 4)
2491 (plus:DI (plus:DI (match_dup 5) (match_dup 6))
2492 (const_int 1))))]
2493{
2494 operands[4] = gen_highpart (DImode, operands[0]);
2495 operands[0] = gen_lowpart (DImode, operands[0]);
2496 operands[5] = gen_highpart (DImode, operands[1]);
2497 operands[1] = gen_lowpart (DImode, operands[1]);
2498 operands[6] = gen_highpart (DImode, operands[2]);
2499 operands[2] = gen_lowpart (DImode, operands[2]);
2500})
2501
2502(define_split
2503 [(set (match_operand:TI 0 "register_operand" "")
2504 (plus:TI (match_operand:TI 1 "register_operand" "")
2505 (match_operand:TI 2 "immediate_operand" "")))
2506 (clobber (match_scratch:BI 3 ""))]
2507 "reload_completed"
2508 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
2509 (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1)))
2510 (cond_exec (eq (match_dup 3) (const_int 0))
2511 (set (match_dup 4)
2512 (plus:DI (match_dup 5) (match_dup 6))))
2513 (cond_exec (ne (match_dup 3) (const_int 0))
2514 (set (match_dup 4)
2515 (plus:DI (match_dup 5) (match_dup 7))))]
2516{
2517 operands[4] = gen_highpart (DImode, operands[0]);
2518 operands[0] = gen_lowpart (DImode, operands[0]);
2519 operands[5] = gen_highpart (DImode, operands[1]);
2520 operands[1] = gen_lowpart (DImode, operands[1]);
2521 operands[6] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
2522 operands[7] = INTVAL (operands[2]) < 0 ? const0_rtx : const1_rtx;
2523})
2524
2525(define_insn "subti3"
2526 [(set (match_operand:TI 0 "gr_register_operand" "=&r")
2527 (minus:TI (match_operand:TI 1 "gr_reg_or_8bit_operand" "rK")
2528 (match_operand:TI 2 "gr_register_operand" "r")))
2529 (clobber (match_scratch:BI 3 "=&c"))]
2530 ""
2531 "#"
2532 [(set_attr "itanium_class" "unknown")])
2533
2534(define_split
2535 [(set (match_operand:TI 0 "register_operand" "")
2536 (minus:TI (match_operand:TI 1 "register_operand" "")
2537 (match_operand:TI 2 "register_operand" "")))
2538 (clobber (match_scratch:BI 3 "=&c"))]
2539 "reload_completed"
2540 [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
2541 (set (match_dup 3) (ltu:BI (match_dup 1) (match_dup 0)))
2542 (cond_exec (eq (match_dup 3) (const_int 0))
2543 (set (match_dup 4) (minus:DI (match_dup 5) (match_dup 6))))
2544 (cond_exec (ne (match_dup 3) (const_int 0))
2545 (set (match_dup 4)
2546 (plus:DI (not:DI (match_dup 6)) (match_dup 5))))]
2547{
2548 operands[4] = gen_highpart (DImode, operands[0]);
2549 operands[0] = gen_lowpart (DImode, operands[0]);
2550 operands[5] = gen_highpart (DImode, operands[1]);
2551 operands[1] = gen_lowpart (DImode, operands[1]);
2552 operands[6] = gen_highpart (DImode, operands[2]);
2553 operands[2] = gen_lowpart (DImode, operands[2]);
2554})
2555
2556(define_split
2557 [(set (match_operand:TI 0 "register_operand" "")
2558 (minus:TI (match_operand:TI 1 "immediate_operand" "")
2559 (match_operand:TI 2 "register_operand" "")))
2560 (clobber (match_scratch:BI 3 "=&c"))]
2561 "reload_completed && satisfies_constraint_K (operands[1])"
2562 [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
2563 (set (match_dup 3) (gtu:BI (match_dup 0) (match_dup 1)))
2564 (cond_exec (ne (match_dup 3) (const_int 0))
2565 (set (match_dup 4) (minus:DI (match_dup 6) (match_dup 5))))
2566 (cond_exec (eq (match_dup 3) (const_int 0))
2567 (set (match_dup 4) (minus:DI (match_dup 7) (match_dup 5))))]
2568{
2569 operands[4] = gen_highpart (DImode, operands[0]);
2570 operands[0] = gen_lowpart (DImode, operands[0]);
2571 operands[5] = gen_highpart (DImode, operands[2]);
2572 operands[2] = gen_lowpart (DImode, operands[2]);
2573 operands[6] = INTVAL (operands[1]) < 0 ? GEN_INT (-2) : constm1_rtx;
2574 operands[7] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
2575})
2576
2577(define_expand "mulditi3"
2578 [(set (match_operand:TI 0 "fr_register_operand" "")
2579 (mult:TI (sign_extend:TI
2580 (match_operand:DI 1 "fr_reg_or_fp01_operand" ""))
2581 (sign_extend:TI
2582 (match_operand:DI 2 "fr_reg_or_fp01_operand" ""))))]
2583 ""
2584 "")
2585
2586(define_insn_and_split "*mulditi3_internal"
2587 [(set (match_operand:TI 0 "fr_register_operand" "=&f")
2588 (mult:TI (sign_extend:TI
2589 (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG"))
2590 (sign_extend:TI
2591 (match_operand:DI 2 "fr_reg_or_fp01_operand" "fG"))))]
2592 ""
2593 "#"
2594 "reload_completed"
2595 [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2)))
2596 (set (match_dup 3) (truncate:DI
2597 (lshiftrt:TI
2598 (mult:TI (sign_extend:TI (match_dup 1))
2599 (sign_extend:TI (match_dup 2)))
2600 (const_int 64))))]
2601{
2602 operands[3] = gen_highpart (DImode, operands[0]);
2603 operands[0] = gen_lowpart (DImode, operands[0]);
2604}
2605 [(set_attr "itanium_class" "unknown")])
2606
2607(define_expand "umulditi3"
2608 [(set (match_operand:TI 0 "fr_register_operand" "")
2609 (mult:TI (zero_extend:TI
2610 (match_operand:DI 1 "fr_reg_or_fp01_operand" ""))
2611 (zero_extend:TI
2612 (match_operand:DI 2 "fr_reg_or_fp01_operand" ""))))]
2613 ""
2614 "")
2615
2616(define_insn_and_split "*umulditi3_internal"
2617 [(set (match_operand:TI 0 "fr_register_operand" "=&f")
2618 (mult:TI (zero_extend:TI
2619 (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG"))
2620 (zero_extend:TI
2621 (match_operand:DI 2 "fr_reg_or_fp01_operand" "fG"))))]
2622 ""
2623 "#"
2624 "reload_completed"
2625 [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2)))
2626 (set (match_dup 3) (truncate:DI
2627 (lshiftrt:TI
2628 (mult:TI (zero_extend:TI (match_dup 1))
2629 (zero_extend:TI (match_dup 2)))
2630 (const_int 64))))]
2631{
2632 operands[3] = gen_highpart (DImode, operands[0]);
2633 operands[0] = gen_lowpart (DImode, operands[0]);
2634}
2635 [(set_attr "itanium_class" "unknown")])
2636
2637(define_insn_and_split "negti2"
2638 [(set (match_operand:TI 0 "gr_register_operand" "=&r")
2639 (neg:TI (match_operand:TI 1 "gr_register_operand" "r")))
2640 (clobber (match_scratch:BI 2 "=&c"))]
2641 ""
2642 "#"
2643 "reload_completed"
2644 [(set (match_dup 2) (eq:BI (match_dup 1) (const_int 0)))
2645 (set (match_dup 0) (minus:DI (const_int 0) (match_dup 1)))
2646 (cond_exec (eq (match_dup 2) (const_int 0))
2647 (set (match_dup 3) (minus:DI (const_int -1) (match_dup 4))))
2648 (cond_exec (ne (match_dup 2) (const_int 0))
2649 (set (match_dup 3) (minus:DI (const_int 0) (match_dup 4))))]
2650{
2651 operands[3] = gen_highpart (DImode, operands[0]);
2652 operands[0] = gen_lowpart (DImode, operands[0]);
2653 operands[4] = gen_highpart (DImode, operands[1]);
2654 operands[1] = gen_lowpart (DImode, operands[1]);
2655}
2656 [(set_attr "itanium_class" "unknown")])
2657\f
2658;; ::::::::::::::::::::
2659;; ::
2660;; :: 32-bit floating point arithmetic
2661;; ::
2662;; ::::::::::::::::::::
2663
2664(define_insn "addsf3"
2665 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2666 (plus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "%fG")
2667 (match_operand:SF 2 "fr_reg_or_signed_fp01_operand" "fZ")))]
2668 ""
2669 "fadd.s %0 = %F1, %F2"
2670 [(set_attr "itanium_class" "fmac")])
2671
2672(define_insn "subsf3"
2673 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2674 (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2675 (match_operand:SF 2 "fr_reg_or_signed_fp01_operand" "fZ")))]
2676 ""
2677 "fsub.s %0 = %F1, %F2"
2678 [(set_attr "itanium_class" "fmac")])
2679
2680(define_insn "mulsf3"
2681 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2682 (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2683 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2684 ""
2685 "fmpy.s %0 = %F1, %F2"
2686 [(set_attr "itanium_class" "fmac")])
2687
2688(define_insn "abssf2"
2689 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2690 (abs:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))]
2691 ""
2692 "fabs %0 = %F1"
2693 [(set_attr "itanium_class" "fmisc")])
2694
2695(define_insn "negsf2"
2696 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2697 (neg:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))]
2698 ""
2699 "fneg %0 = %F1"
2700 [(set_attr "itanium_class" "fmisc")])
2701
2702(define_insn "*nabssf2"
2703 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2704 (neg:SF (abs:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG"))))]
2705 ""
2706 "fnegabs %0 = %F1"
2707 [(set_attr "itanium_class" "fmisc")])
2708
2709(define_insn "copysignsf3"
2710 [(set (match_operand:SF 0 "register_operand" "=f")
2711 (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2712 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")]
2713 UNSPEC_COPYSIGN))]
2714 ""
2715 "fmerge.s %0 = %F2, %F1"
2716 [(set_attr "itanium_class" "fmisc")])
2717
2718(define_insn "*ncopysignsf3"
2719 [(set (match_operand:SF 0 "register_operand" "=f")
2720 (neg:SF (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2721 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")]
2722 UNSPEC_COPYSIGN)))]
2723 ""
2724 "fmerge.ns %0 = %F2, %F1"
2725 [(set_attr "itanium_class" "fmisc")])
2726
2727(define_insn "sminsf3"
2728 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2729 (smin:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2730 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2731 ""
2732 "fmin %0 = %F1, %F2"
2733 [(set_attr "itanium_class" "fmisc")])
2734
2735(define_insn "smaxsf3"
2736 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2737 (smax:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2738 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2739 ""
2740 "fmax %0 = %F1, %F2"
2741 [(set_attr "itanium_class" "fmisc")])
2742
2743(define_insn "*maddsf4"
2744 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2745 (plus:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2746 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))
2747 (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
2748 "TARGET_FUSED_MADD"
2749 "fma.s %0 = %F1, %F2, %F3"
2750 [(set_attr "itanium_class" "fmac")])
2751
2752(define_insn "*msubsf4"
2753 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2754 (minus:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2755 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))
2756 (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
2757 "TARGET_FUSED_MADD"
2758 "fms.s %0 = %F1, %F2, %F3"
2759 [(set_attr "itanium_class" "fmac")])
2760
2761(define_insn "*nmulsf3"
2762 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2763 (neg:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2764 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))))]
2765 ""
2766 "fnmpy.s %0 = %F1, %F2"
2767 [(set_attr "itanium_class" "fmac")])
2768
2769(define_insn "*nmaddsf4"
2770 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2771 (minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")
2772 (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2773 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))))]
2774 "TARGET_FUSED_MADD"
2775 "fnma.s %0 = %F1, %F2, %F3"
2776 [(set_attr "itanium_class" "fmac")])
2777\f
2778;; ::::::::::::::::::::
2779;; ::
2780;; :: 64-bit floating point arithmetic
2781;; ::
2782;; ::::::::::::::::::::
2783
2784(define_insn "adddf3"
2785 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2786 (plus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "%fG")
2787 (match_operand:DF 2 "fr_reg_or_signed_fp01_operand" "fZ")))]
2788 ""
2789 "fadd.d %0 = %F1, %F2"
2790 [(set_attr "itanium_class" "fmac")])
2791
2792(define_insn "*adddf3_trunc"
2793 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2794 (float_truncate:SF
2795 (plus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "%fG")
2796 (match_operand:DF 2 "fr_reg_or_signed_fp01_operand" "fZ"))))]
2797 ""
2798 "fadd.s %0 = %F1, %F2"
2799 [(set_attr "itanium_class" "fmac")])
2800
2801(define_insn "subdf3"
2802 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2803 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2804 (match_operand:DF 2 "fr_reg_or_signed_fp01_operand" "fZ")))]
2805 ""
2806 "fsub.d %0 = %F1, %F2"
2807 [(set_attr "itanium_class" "fmac")])
2808
2809(define_insn "*subdf3_trunc"
2810 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2811 (float_truncate:SF
2812 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2813 (match_operand:DF 2 "fr_reg_or_signed_fp01_operand" "fZ"))))]
2814 ""
2815 "fsub.s %0 = %F1, %F2"
2816 [(set_attr "itanium_class" "fmac")])
2817
2818(define_insn "muldf3"
2819 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2820 (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2821 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2822 ""
2823 "fmpy.d %0 = %F1, %F2"
2824 [(set_attr "itanium_class" "fmac")])
2825
2826(define_insn "*muldf3_trunc"
2827 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2828 (float_truncate:SF
2829 (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2830 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2831 ""
2832 "fmpy.s %0 = %F1, %F2"
2833 [(set_attr "itanium_class" "fmac")])
2834
2835(define_insn "absdf2"
2836 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2837 (abs:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")))]
2838 ""
2839 "fabs %0 = %F1"
2840 [(set_attr "itanium_class" "fmisc")])
2841
2842(define_insn "negdf2"
2843 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2844 (neg:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")))]
2845 ""
2846 "fneg %0 = %F1"
2847 [(set_attr "itanium_class" "fmisc")])
2848
2849(define_insn "*nabsdf2"
2850 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2851 (neg:DF (abs:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG"))))]
2852 ""
2853 "fnegabs %0 = %F1"
2854 [(set_attr "itanium_class" "fmisc")])
2855
2856(define_insn "copysigndf3"
2857 [(set (match_operand:DF 0 "register_operand" "=f")
2858 (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2859 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")]
2860 UNSPEC_COPYSIGN))]
2861 ""
2862 "fmerge.s %0 = %F2, %F1"
2863 [(set_attr "itanium_class" "fmisc")])
2864
2865(define_insn "*ncopysigndf3"
2866 [(set (match_operand:DF 0 "register_operand" "=f")
2867 (neg:DF (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2868 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")]
2869 UNSPEC_COPYSIGN)))]
2870 ""
2871 "fmerge.ns %0 = %F2, %F1"
2872 [(set_attr "itanium_class" "fmisc")])
2873
2874(define_insn "smindf3"
2875 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2876 (smin:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2877 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2878 ""
2879 "fmin %0 = %F1, %F2"
2880 [(set_attr "itanium_class" "fmisc")])
2881
2882(define_insn "smaxdf3"
2883 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2884 (smax:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2885 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2886 ""
2887 "fmax %0 = %F1, %F2"
2888 [(set_attr "itanium_class" "fmisc")])
2889
2890(define_insn "*madddf4"
2891 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2892 (plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2893 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
2894 (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
2895 "TARGET_FUSED_MADD"
2896 "fma.d %0 = %F1, %F2, %F3"
2897 [(set_attr "itanium_class" "fmac")])
2898
2899(define_insn "*madddf4_trunc"
2900 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2901 (float_truncate:SF
2902 (plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2903 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
2904 (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
2905 "TARGET_FUSED_MADD"
2906 "fma.s %0 = %F1, %F2, %F3"
2907 [(set_attr "itanium_class" "fmac")])
2908
2909(define_insn "*msubdf4"
2910 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2911 (minus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2912 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
2913 (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
2914 "TARGET_FUSED_MADD"
2915 "fms.d %0 = %F1, %F2, %F3"
2916 [(set_attr "itanium_class" "fmac")])
2917
2918(define_insn "*msubdf4_trunc"
2919 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2920 (float_truncate:SF
2921 (minus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2922 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
2923 (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
2924 "TARGET_FUSED_MADD"
2925 "fms.s %0 = %F1, %F2, %F3"
2926 [(set_attr "itanium_class" "fmac")])
2927
2928(define_insn "*nmuldf3"
2929 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2930 (neg:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2931 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2932 ""
2933 "fnmpy.d %0 = %F1, %F2"
2934 [(set_attr "itanium_class" "fmac")])
2935
2936(define_insn "*nmuldf3_trunc"
2937 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2938 (float_truncate:SF
2939 (neg:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2940 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))))]
2941 ""
2942 "fnmpy.s %0 = %F1, %F2"
2943 [(set_attr "itanium_class" "fmac")])
2944
2945(define_insn "*nmadddf4"
2946 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2947 (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
2948 (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2949 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2950 "TARGET_FUSED_MADD"
2951 "fnma.d %0 = %F1, %F2, %F3"
2952 [(set_attr "itanium_class" "fmac")])
2953
2954(define_insn "*nmadddf4_truncsf"
2955 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2956 (float_truncate:SF
2957 (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
2958 (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2959 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))))]
2960 "TARGET_FUSED_MADD"
2961 "fnma.s %0 = %F1, %F2, %F3"
2962 [(set_attr "itanium_class" "fmac")])
2963\f
2964;; ::::::::::::::::::::
2965;; ::
2966;; :: 80-bit floating point arithmetic
2967;; ::
2968;; ::::::::::::::::::::
2969
2970(define_insn "addxf3"
2971 [(set (match_operand:XF 0 "fr_register_operand" "=f")
2972 (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "%fG")
2973 (match_operand:XF 2 "xfreg_or_signed_fp01_operand" "fZ")))]
2974 ""
2975 "fadd %0 = %F1, %F2"
2976 [(set_attr "itanium_class" "fmac")])
2977
2978(define_insn "*addxf3_truncsf"
2979 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2980 (float_truncate:SF
2981 (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "%fG")
2982 (match_operand:XF 2 "xfreg_or_signed_fp01_operand" "fZ"))))]
2983 ""
2984 "fadd.s %0 = %F1, %F2"
2985 [(set_attr "itanium_class" "fmac")])
2986
2987(define_insn "*addxf3_truncdf"
2988 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2989 (float_truncate:DF
2990 (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "%fG")
2991 (match_operand:XF 2 "xfreg_or_signed_fp01_operand" "fZ"))))]
2992 ""
2993 "fadd.d %0 = %F1, %F2"
2994 [(set_attr "itanium_class" "fmac")])
2995
2996(define_insn "subxf3"
2997 [(set (match_operand:XF 0 "fr_register_operand" "=f")
2998 (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
2999 (match_operand:XF 2 "xfreg_or_signed_fp01_operand" "fZ")))]
3000 ""
3001 "fsub %0 = %F1, %F2"
3002 [(set_attr "itanium_class" "fmac")])
3003
3004(define_insn "*subxf3_truncsf"
3005 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3006 (float_truncate:SF
3007 (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3008 (match_operand:XF 2 "xfreg_or_signed_fp01_operand" "fZ"))))]
3009 ""
3010 "fsub.s %0 = %F1, %F2"
3011 [(set_attr "itanium_class" "fmac")])
3012
3013(define_insn "*subxf3_truncdf"
3014 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3015 (float_truncate:DF
3016 (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3017 (match_operand:XF 2 "xfreg_or_signed_fp01_operand" "fZ"))))]
3018 ""
3019 "fsub.d %0 = %F1, %F2"
3020 [(set_attr "itanium_class" "fmac")])
3021
3022(define_insn "mulxf3"
3023 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3024 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3025 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3026 ""
3027 "fmpy %0 = %F1, %F2"
3028 [(set_attr "itanium_class" "fmac")])
3029
3030(define_insn "*mulxf3_truncsf"
3031 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3032 (float_truncate:SF
3033 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3034 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3035 ""
3036 "fmpy.s %0 = %F1, %F2"
3037 [(set_attr "itanium_class" "fmac")])
3038
3039(define_insn "*mulxf3_truncdf"
3040 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3041 (float_truncate:DF
3042 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3043 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3044 ""
3045 "fmpy.d %0 = %F1, %F2"
3046 [(set_attr "itanium_class" "fmac")])
3047
3048(define_insn "absxf2"
3049 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3050 (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3051 ""
3052 "fabs %0 = %F1"
3053 [(set_attr "itanium_class" "fmisc")])
3054
3055(define_insn "negxf2"
3056 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3057 (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3058 ""
3059 "fneg %0 = %F1"
3060 [(set_attr "itanium_class" "fmisc")])
3061
3062(define_insn "*nabsxf2"
3063 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3064 (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))]
3065 ""
3066 "fnegabs %0 = %F1"
3067 [(set_attr "itanium_class" "fmisc")])
3068
3069(define_insn "copysignxf3"
3070 [(set (match_operand:XF 0 "register_operand" "=f")
3071 (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
3072 (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")]
3073 UNSPEC_COPYSIGN))]
3074 ""
3075 "fmerge.s %0 = %F2, %F1"
3076 [(set_attr "itanium_class" "fmisc")])
3077
3078(define_insn "*ncopysignxf3"
3079 [(set (match_operand:XF 0 "register_operand" "=f")
3080 (neg:XF (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
3081 (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")]
3082 UNSPEC_COPYSIGN)))]
3083 ""
3084 "fmerge.ns %0 = %F2, %F1"
3085 [(set_attr "itanium_class" "fmisc")])
3086
3087(define_insn "sminxf3"
3088 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3089 (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3090 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3091 ""
3092 "fmin %0 = %F1, %F2"
3093 [(set_attr "itanium_class" "fmisc")])
3094
3095(define_insn "smaxxf3"
3096 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3097 (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3098 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3099 ""
3100 "fmax %0 = %F1, %F2"
3101 [(set_attr "itanium_class" "fmisc")])
3102
3103(define_insn "*maddxf4"
3104 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3105 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3106 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3107 (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ")))]
3108 "TARGET_FUSED_MADD"
3109 "fma %0 = %F1, %F2, %F3"
3110 [(set_attr "itanium_class" "fmac")])
3111
3112(define_insn "*maddxf4_truncsf"
3113 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3114 (float_truncate:SF
3115 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3116 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3117 (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
3118 "TARGET_FUSED_MADD"
3119 "fma.s %0 = %F1, %F2, %F3"
3120 [(set_attr "itanium_class" "fmac")])
3121
3122(define_insn "*maddxf4_truncdf"
3123 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3124 (float_truncate:DF
3125 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3126 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3127 (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
3128 "TARGET_FUSED_MADD"
3129 "fma.d %0 = %F1, %F2, %F3"
3130 [(set_attr "itanium_class" "fmac")])
3131
3132(define_insn "*msubxf4"
3133 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3134 (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3135 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3136 (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ")))]
3137 "TARGET_FUSED_MADD"
3138 "fms %0 = %F1, %F2, %F3"
3139 [(set_attr "itanium_class" "fmac")])
3140
3141(define_insn "*msubxf4_truncsf"
3142 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3143 (float_truncate:SF
3144 (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3145 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3146 (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
3147 "TARGET_FUSED_MADD"
3148 "fms.s %0 = %F1, %F2, %F3"
3149 [(set_attr "itanium_class" "fmac")])
3150
3151(define_insn "*msubxf4_truncdf"
3152 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3153 (float_truncate:DF
3154 (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3155 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3156 (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
3157 "TARGET_FUSED_MADD"
3158 "fms.d %0 = %F1, %F2, %F3"
3159 [(set_attr "itanium_class" "fmac")])
3160
3161(define_insn "*nmulxf3"
3162 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3163 (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3164 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3165 ""
3166 "fnmpy %0 = %F1, %F2"
3167 [(set_attr "itanium_class" "fmac")])
3168
3169(define_insn "*nmulxf3_truncsf"
3170 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3171 (float_truncate:SF
3172 (neg:XF (mult:XF
3173 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3174 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3175 ""
3176 "fnmpy.s %0 = %F1, %F2"
3177 [(set_attr "itanium_class" "fmac")])
3178
3179(define_insn "*nmulxf3_truncdf"
3180 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3181 (float_truncate:DF
3182 (neg:XF (mult:XF
3183 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3184 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3185 ""
3186 "fnmpy.d %0 = %F1, %F2"
3187 [(set_attr "itanium_class" "fmac")])
3188
3189(define_insn "*nmaddxf4"
3190 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3191 (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
3192 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3193 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3194 )))]
3195 "TARGET_FUSED_MADD"
3196 "fnma %0 = %F1, %F2, %F3"
3197 [(set_attr "itanium_class" "fmac")])
3198
3199(define_insn "*nmaddxf4_truncsf"
3200 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3201 (float_truncate:SF
3202 (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
3203 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3204 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3205 ))))]
3206 "TARGET_FUSED_MADD"
3207 "fnma.s %0 = %F1, %F2, %F3"
3208 [(set_attr "itanium_class" "fmac")])
3209
3210(define_insn "*nmaddxf4_truncdf"
3211 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3212 (float_truncate:DF
3213 (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
3214 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3215 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3216 ))))]
3217 "TARGET_FUSED_MADD"
3218 "fnma.d %0 = %F1, %F2, %F3"
3219 [(set_attr "itanium_class" "fmac")])
3220\f
3221;; ::::::::::::::::::::
3222;; ::
3223;; :: 32-bit Integer Shifts and Rotates
3224;; ::
3225;; ::::::::::::::::::::
3226
3227(define_expand "ashlsi3"
3228 [(set (match_operand:SI 0 "gr_register_operand" "")
3229 (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
3230 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3231 ""
3232{
3233 if (GET_CODE (operands[2]) != CONST_INT)
3234 {
3235 /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now
3236 we've got to get rid of stray bits outside the SImode register. */
3237 rtx subshift = gen_reg_rtx (DImode);
3238 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3239 operands[2] = subshift;
3240 }
3241})
3242
3243(define_insn "*ashlsi3_internal"
3244 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
3245 (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
3246 (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
3247 ""
3248 "@
3249 shladd %0 = %1, %2, r0
3250 dep.z %0 = %1, %2, %E2
3251 shl %0 = %1, %2"
3252 [(set_attr "itanium_class" "ialu,ishf,mmshf")])
3253
3254(define_expand "ashrsi3"
3255 [(set (match_operand:SI 0 "gr_register_operand" "")
3256 (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
3257 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3258 ""
3259{
3260 rtx subtarget = gen_reg_rtx (DImode);
3261 if (GET_CODE (operands[2]) == CONST_INT)
3262 emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
3263 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
3264 else
3265 {
3266 rtx subshift = gen_reg_rtx (DImode);
3267 emit_insn (gen_extendsidi2 (subtarget, operands[1]));
3268 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3269 emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
3270 }
3271 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
3272 DONE;
3273})
3274
3275(define_expand "lshrsi3"
3276 [(set (match_operand:SI 0 "gr_register_operand" "")
3277 (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
3278 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3279 ""
3280{
3281 rtx subtarget = gen_reg_rtx (DImode);
3282 if (GET_CODE (operands[2]) == CONST_INT)
3283 emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
3284 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
3285 else
3286 {
3287 rtx subshift = gen_reg_rtx (DImode);
3288 emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
3289 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3290 emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
3291 }
3292 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
3293 DONE;
3294})
3295
3296;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
3297;; here, instead of 64 like the patterns above. Keep the pattern together
3298;; until after combine; otherwise it won't get matched often.
3299
3300(define_expand "rotrsi3"
3301 [(set (match_operand:SI 0 "gr_register_operand" "")
3302 (rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
3303 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3304 ""
3305{
3306 if (GET_MODE (operands[2]) != VOIDmode)
3307 {
3308 rtx tmp = gen_reg_rtx (DImode);
3309 emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
3310 operands[2] = tmp;
3311 }
3312})
3313
3314(define_insn_and_split "*rotrsi3_internal"
3315 [(set (match_operand:SI 0 "gr_register_operand" "=&r")
3316 (rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
3317 (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
3318 ""
3319 "#"
3320 "reload_completed"
3321 [(set (match_dup 3)
3322 (ior:DI (zero_extend:DI (match_dup 1))
3323 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
3324 (set (match_dup 3)
3325 (lshiftrt:DI (match_dup 3) (match_dup 2)))]
3326 "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
3327
3328(define_expand "rotlsi3"
3329 [(set (match_operand:SI 0 "gr_register_operand" "")
3330 (rotate:SI (match_operand:SI 1 "gr_register_operand" "")
3331 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3332 ""
3333{
3334 if (! shift_32bit_count_operand (operands[2], SImode))
3335 {
3336 rtx tmp = gen_reg_rtx (SImode);
3337 emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
3338 emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
3339 DONE;
3340 }
3341})
3342
3343(define_insn_and_split "*rotlsi3_internal"
3344 [(set (match_operand:SI 0 "gr_register_operand" "=r")
3345 (rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
3346 (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
3347 ""
3348 "mux2 %0 = %1, 0xe1"
3349 "reload_completed && INTVAL (operands[2]) != 16"
3350 [(set (match_dup 3)
3351 (ior:DI (zero_extend:DI (match_dup 1))
3352 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
3353 (set (match_dup 3)
3354 (lshiftrt:DI (match_dup 3) (match_dup 2)))]
3355{
3356 operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
3357 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
3358}
3359 [(set_attr "itanium_class" "mmshf")])
3360\f
3361;; ::::::::::::::::::::
3362;; ::
3363;; :: 64-bit Integer Shifts and Rotates
3364;; ::
3365;; ::::::::::::::::::::
3366
3367(define_insn "ashldi3"
3368 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
3369 (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
3370 (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
3371 ""
3372 "@
3373 shladd %0 = %1, %2, r0
3374 shl %0 = %1, %2
3375 shl %0 = %1, %2"
3376 [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
3377
3378;; ??? Maybe combine this with the multiply and add instruction?
3379
3380(define_insn "*shladd"
3381 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3382 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
3383 (match_operand:DI 2 "shladd_operand" "n"))
3384 (match_operand:DI 3 "gr_register_operand" "r")))]
3385 ""
3386 "shladd %0 = %1, %S2, %3"
3387 [(set_attr "itanium_class" "ialu")])
3388
3389;; This can be created by register elimination if operand3 of shladd is an
3390;; eliminable register or has reg_equiv_constant set.
3391
3392;; We have to use nonmemory_operand for operand 4, to ensure that the
3393;; validate_changes call inside eliminate_regs will always succeed. If it
3394;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
3395;; incorrectly.
3396
3397(define_insn_and_split "*shladd_elim"
3398 [(set (match_operand:DI 0 "gr_register_operand" "=&r")
3399 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
3400 (match_operand:DI 2 "shladd_operand" "n"))
3401 (match_operand:DI 3 "nonmemory_operand" "r"))
3402 (match_operand:DI 4 "nonmemory_operand" "rI")))]
3403 "reload_in_progress"
3404 "* gcc_unreachable ();"
3405 "reload_completed"
3406 [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
3407 (match_dup 3)))
3408 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
3409 ""
3410 [(set_attr "itanium_class" "unknown")])
3411
3412(define_insn "ashrdi3"
3413 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
3414 (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
3415 (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
3416 ""
3417 "@
3418 shr %0 = %1, %2
3419 shr %0 = %1, %2"
3420 [(set_attr "itanium_class" "mmshf,mmshfi")])
3421
3422(define_insn "lshrdi3"
3423 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
3424 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
3425 (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
3426 ""
3427 "@
3428 shr.u %0 = %1, %2
3429 shr.u %0 = %1, %2"
3430 [(set_attr "itanium_class" "mmshf,mmshfi")])
3431
3432;; Using a predicate that accepts only constants doesn't work, because optabs
3433;; will load the operand into a register and call the pattern if the predicate
3434;; did not accept it on the first try. So we use nonmemory_operand and then
3435;; verify that we have an appropriate constant in the expander.
3436
3437(define_expand "rotrdi3"
3438 [(set (match_operand:DI 0 "gr_register_operand" "")
3439 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
3440 (match_operand:DI 2 "nonmemory_operand" "")))]
3441 ""
3442{
3443 if (! shift_count_operand (operands[2], DImode))
3444 FAIL;
3445})
3446
3447(define_insn "*rotrdi3_internal"
3448 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3449 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
3450 (match_operand:DI 2 "shift_count_operand" "M")))]
3451 ""
3452 "shrp %0 = %1, %1, %2"
3453 [(set_attr "itanium_class" "ishf")])
3454
3455(define_expand "rotldi3"
3456 [(set (match_operand:DI 0 "gr_register_operand" "")
3457 (rotate:DI (match_operand:DI 1 "gr_register_operand" "")
3458 (match_operand:DI 2 "nonmemory_operand" "")))]
3459 ""
3460{
3461 if (! shift_count_operand (operands[2], DImode))
3462 FAIL;
3463})
3464
3465(define_insn "*rotldi3_internal"
3466 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3467 (rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
3468 (match_operand:DI 2 "shift_count_operand" "M")))]
3469 ""
3470 "shrp %0 = %1, %1, %e2"
3471 [(set_attr "itanium_class" "ishf")])
3472\f
3473;; ::::::::::::::::::::
3474;; ::
3475;; :: 128-bit Integer Shifts and Rotates
3476;; ::
3477;; ::::::::::::::::::::
3478
3479(define_expand "ashlti3"
3480 [(set (match_operand:TI 0 "gr_register_operand" "")
3481 (ashift:TI (match_operand:TI 1 "gr_register_operand" "")
3482 (match_operand:DI 2 "nonmemory_operand" "")))]
3483 ""
3484{
3485 if (!dshift_count_operand (operands[2], DImode))
3486 FAIL;
3487})
3488
3489(define_insn_and_split "*ashlti3_internal"
3490 [(set (match_operand:TI 0 "gr_register_operand" "=&r")
3491 (ashift:TI (match_operand:TI 1 "gr_register_operand" "r")
3492 (match_operand:DI 2 "dshift_count_operand" "n")))]
3493 ""
3494 "#"
3495 "reload_completed"
3496 [(const_int 0)]
3497{
3498 HOST_WIDE_INT shift = INTVAL (operands[2]);
3499 rtx rl = gen_lowpart (DImode, operands[0]);
3500 rtx rh = gen_highpart (DImode, operands[0]);
3501 rtx lo = gen_lowpart (DImode, operands[1]);
3502 rtx shiftlo = GEN_INT (shift & 63);
3503
3504 if (shift & 64)
3505 {
3506 emit_move_insn (rl, const0_rtx);
3507 if (shift & 63)
3508 emit_insn (gen_ashldi3 (rh, lo, shiftlo));
3509 else
3510 emit_move_insn (rh, lo);
3511 }
3512 else
3513 {
3514 rtx hi = gen_highpart (DImode, operands[1]);
3515
3516 emit_insn (gen_shrp (rh, hi, lo, GEN_INT (-shift & 63)));
3517 emit_insn (gen_ashldi3 (rl, lo, shiftlo));
3518 }
3519 DONE;
3520})
3521
3522(define_expand "ashrti3"
3523 [(set (match_operand:TI 0 "gr_register_operand" "")
3524 (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "")
3525 (match_operand:DI 2 "nonmemory_operand" "")))]
3526 ""
3527{
3528 if (!dshift_count_operand (operands[2], DImode))
3529 FAIL;
3530})
3531
3532(define_insn_and_split "*ashrti3_internal"
3533 [(set (match_operand:TI 0 "gr_register_operand" "=&r")
3534 (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "r")
3535 (match_operand:DI 2 "dshift_count_operand" "n")))]
3536 ""
3537 "#"
3538 "reload_completed"
3539 [(const_int 0)]
3540{
3541 HOST_WIDE_INT shift = INTVAL (operands[2]);
3542 rtx rl = gen_lowpart (DImode, operands[0]);
3543 rtx rh = gen_highpart (DImode, operands[0]);
3544 rtx hi = gen_highpart (DImode, operands[1]);
3545 rtx shiftlo = GEN_INT (shift & 63);
3546
3547 if (shift & 64)
3548 {
3549 if (shift & 63)
3550 emit_insn (gen_ashrdi3 (rl, hi, shiftlo));
3551 else
3552 emit_move_insn (rl, hi);
3553 emit_insn (gen_ashrdi3 (rh, hi, GEN_INT (63)));
3554 }
3555 else
3556 {
3557 rtx lo = gen_lowpart (DImode, operands[1]);
3558
3559 emit_insn (gen_shrp (rl, hi, lo, shiftlo));
3560 emit_insn (gen_ashrdi3 (rh, hi, shiftlo));
3561 }
3562 DONE;
3563})
3564
3565(define_expand "lshrti3"
3566 [(set (match_operand:TI 0 "gr_register_operand" "")
3567 (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "")
3568 (match_operand:DI 2 "nonmemory_operand" "")))]
3569 ""
3570{
3571 if (!dshift_count_operand (operands[2], DImode))
3572 FAIL;
3573})
3574
3575(define_insn_and_split "*lshrti3_internal"
3576 [(set (match_operand:TI 0 "gr_register_operand" "=&r")
3577 (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "r")
3578 (match_operand:DI 2 "dshift_count_operand" "n")))]
3579 ""
3580 "#"
3581 "reload_completed"
3582 [(const_int 0)]
3583{
3584 HOST_WIDE_INT shift = INTVAL (operands[2]);
3585 rtx rl = gen_lowpart (DImode, operands[0]);
3586 rtx rh = gen_highpart (DImode, operands[0]);
3587 rtx hi = gen_highpart (DImode, operands[1]);
3588 rtx shiftlo = GEN_INT (shift & 63);
3589
3590 if (shift & 64)
3591 {
3592 if (shift & 63)
3593 emit_insn (gen_lshrdi3 (rl, hi, shiftlo));
3594 else
3595 emit_move_insn (rl, hi);
3596 emit_move_insn (rh, const0_rtx);
3597 }
3598 else
3599 {
3600 rtx lo = gen_lowpart (DImode, operands[1]);
3601
3602 emit_insn (gen_shrp (rl, hi, lo, shiftlo));
3603 emit_insn (gen_lshrdi3 (rh, hi, shiftlo));
3604 }
3605 DONE;
3606})
3607
3608(define_expand "rotlti3"
3609 [(set (match_operand:TI 0 "gr_register_operand" "")
3610 (rotate:TI (match_operand:TI 1 "gr_register_operand" "")
3611 (match_operand:DI 2 "nonmemory_operand" "")))]
3612 ""
3613{
3614 if (! dshift_count_operand (operands[2], DImode))
3615 FAIL;
3616})
3617
3618(define_insn_and_split "*rotlti3_internal"
3619 [(set (match_operand:TI 0 "gr_register_operand" "=&r")
3620 (rotate:TI (match_operand:TI 1 "gr_register_operand" "r")
3621 (match_operand:DI 2 "dshift_count_operand" "n")))]
3622 ""
3623 "#"
3624 "reload_completed"
3625 [(const_int 0)]
3626{
3627 HOST_WIDE_INT count = INTVAL (operands[2]);
3628 rtx rl = gen_lowpart (DImode, operands[0]);
3629 rtx rh = gen_highpart (DImode, operands[0]);
3630 rtx lo = gen_lowpart (DImode, operands[1]);
3631 rtx hi = gen_highpart (DImode, operands[1]);
3632 rtx countlo = GEN_INT (-count & 63);
3633
3634 if (count & 64)
3635 {
3636 if (count & 63)
3637 {
3638 emit_insn (gen_shrp (rl, hi, lo, countlo));
3639 emit_insn (gen_shrp (rh, lo, hi, countlo));
3640 }
3641 else
3642 {
3643 emit_move_insn (rl, hi);
3644 emit_move_insn (rh, lo);
3645 }
3646 }
3647 else
3648 {
3649 emit_insn (gen_shrp (rl, lo, hi, countlo));
3650 emit_insn (gen_shrp (rh, hi, lo, countlo));
3651 }
3652 DONE;
3653}
3654 [(set_attr "itanium_class" "unknown")])
3655
3656(define_insn "shrp"
3657 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3658 (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")
3659 (match_operand:DI 2 "gr_register_operand" "r")
3660 (match_operand:DI 3 "shift_count_operand" "M")]
3661 UNSPEC_SHRP))]
3662 ""
3663 "shrp %0 = %1, %2, %3"
3664 [(set_attr "itanium_class" "ishf")])
3665\f
3666;; ::::::::::::::::::::
3667;; ::
3668;; :: 32-bit Integer Logical operations
3669;; ::
3670;; ::::::::::::::::::::
3671
3672;; We don't seem to need any other 32-bit logical operations, because gcc
3673;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
3674;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
3675;; This doesn't work for unary logical operations, because we don't call
3676;; apply_distributive_law for them.
3677
3678;; ??? Likewise, this doesn't work for andnot, which isn't handled by
3679;; apply_distributive_law. We get inefficient code for
3680;; int sub4 (int i, int j) { return i & ~j; }
3681;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
3682;; (zero_extend (and (not A) B)) in combine.
3683;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
3684;; one_cmplsi2 pattern.
3685
3686(define_insn "one_cmplsi2"
3687 [(set (match_operand:SI 0 "gr_register_operand" "=r")
3688 (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
3689 ""
3690 "andcm %0 = -1, %1"
3691 [(set_attr "itanium_class" "ilog")])
3692\f
3693;; ::::::::::::::::::::
3694;; ::
3695;; :: 64-bit Integer Logical operations
3696;; ::
3697;; ::::::::::::::::::::
3698
3699(define_insn "anddi3"
3700 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3701 (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
3702 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3703 ""
3704 "@
3705 and %0 = %2, %1
3706 fand %0 = %2, %1"
3707 [(set_attr "itanium_class" "ilog,fmisc")])
3708
3709(define_insn "*andnot"
3710 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3711 (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
3712 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3713 ""
3714 "@
3715 andcm %0 = %2, %1
3716 fandcm %0 = %2, %1"
3717 [(set_attr "itanium_class" "ilog,fmisc")])
3718
3719(define_insn "iordi3"
3720 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3721 (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
3722 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3723 ""
3724 "@
3725 or %0 = %2, %1
3726 for %0 = %2, %1"
3727 [(set_attr "itanium_class" "ilog,fmisc")])
3728
3729(define_insn "xordi3"
3730 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3731 (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
3732 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3733 ""
3734 "@
3735 xor %0 = %2, %1
3736 fxor %0 = %2, %1"
3737 [(set_attr "itanium_class" "ilog,fmisc")])
3738
3739(define_insn "one_cmpldi2"
3740 [(set (match_operand:DI 0 "gr_register_operand" "=r")
3741 (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
3742 ""
3743 "andcm %0 = -1, %1"
3744 [(set_attr "itanium_class" "ilog")])
3745\f
3746;; ::::::::::::::::::::
3747;; ::
3748;; :: Comparisons
3749;; ::
3750;; ::::::::::::::::::::
3751
3752(define_expand "cbranchbi4"
3753 [(set (pc)
3754 (if_then_else (match_operator 0 "ia64_cbranch_operator"
3755 [(match_operand:BI 1 "register_operand" "")
3756 (match_operand:BI 2 "const_int_operand" "")])
3757 (label_ref (match_operand 3 "" ""))
3758 (pc)))]
3759 ""
3760 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
3761
3762(define_expand "cbranchsi4"
3763 [(set (pc)
3764 (if_then_else (match_operator 0 "ia64_cbranch_operator"
3765 [(match_operand:SI 1 "gr_register_operand" "")
3766 (match_operand:SI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
3767 (label_ref (match_operand 3 "" ""))
3768 (pc)))]
3769 ""
3770 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
3771
3772(define_expand "cbranchdi4"
3773 [(set (pc)
3774 (if_then_else (match_operator 0 "ia64_cbranch_operator"
3775 [(match_operand:DI 1 "gr_register_operand" "")
3776 (match_operand:DI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
3777 (label_ref (match_operand 3 "" ""))
3778 (pc)))]
3779 ""
3780 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
3781
3782(define_expand "cbranchsf4"
3783 [(set (pc)
3784 (if_then_else (match_operator 0 "ia64_cbranch_operator"
3785 [(match_operand:SF 1 "fr_reg_or_fp01_operand" "")
3786 (match_operand:SF 2 "fr_reg_or_fp01_operand" "")])
3787 (label_ref (match_operand 3 "" ""))
3788 (pc)))]
3789 ""
3790 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
3791
3792(define_expand "cbranchdf4"
3793 [(set (pc)
3794 (if_then_else (match_operator 0 "ia64_cbranch_operator"
3795 [(match_operand:DF 1 "fr_reg_or_fp01_operand" "")
3796 (match_operand:DF 2 "fr_reg_or_fp01_operand" "")])
3797 (label_ref (match_operand 3 "" ""))
3798 (pc)))]
3799 ""
3800 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
3801
3802(define_expand "cbranchxf4"
3803 [(set (pc)
3804 (if_then_else (match_operator 0 "ia64_cbranch_operator"
3805 [(match_operand:XF 1 "xfreg_or_fp01_operand" "")
3806 (match_operand:XF 2 "xfreg_or_fp01_operand" "")])
3807 (label_ref (match_operand 3 "" ""))
3808 (pc)))]
3809 ""
3810 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
3811
3812(define_expand "cbranchtf4"
3813 [(set (pc)
3814 (if_then_else (match_operator 0 "ia64_cbranch_operator"
3815 [(match_operand:TF 1 "gr_register_operand" "")
3816 (match_operand:TF 2 "gr_register_operand" "")])
3817 (label_ref (match_operand 3 "" ""))
3818 (pc)))]
3819 "TARGET_HPUX"
3820 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
3821
3822
3823(define_insn "*cmpsi_normal"
3824 [(set (match_operand:BI 0 "register_operand" "=c")
3825 (match_operator:BI 1 "normal_comparison_operator"
3826 [(match_operand:SI 2 "gr_register_operand" "r")
3827 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
3828 ""
3829 "cmp4.%C1 %0, %I0 = %3, %2"
3830 [(set_attr "itanium_class" "icmp")])
3831
3832;; We use %r3 because it is possible for us to match a 0, and two of the
3833;; unsigned comparisons don't accept immediate operands of zero.
3834
3835(define_insn "*cmpsi_adjusted"
3836 [(set (match_operand:BI 0 "register_operand" "=c")
3837 (match_operator:BI 1 "adjusted_comparison_operator"
3838 [(match_operand:SI 2 "gr_register_operand" "r")
3839 (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
3840 ""
3841 "cmp4.%C1 %0, %I0 = %r3, %2"
3842 [(set_attr "itanium_class" "icmp")])
3843
3844(define_insn "*cmpdi_normal"
3845 [(set (match_operand:BI 0 "register_operand" "=c")
3846 (match_operator:BI 1 "normal_comparison_operator"
3847 [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
3848 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
3849 ""
3850 "cmp.%C1 %0, %I0 = %3, %r2"
3851 [(set_attr "itanium_class" "icmp")])
3852
3853;; We use %r3 because it is possible for us to match a 0, and two of the
3854;; unsigned comparisons don't accept immediate operands of zero.
3855
3856(define_insn "*cmpdi_adjusted"
3857 [(set (match_operand:BI 0 "register_operand" "=c")
3858 (match_operator:BI 1 "adjusted_comparison_operator"
3859 [(match_operand:DI 2 "gr_register_operand" "r")
3860 (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
3861 ""
3862 "cmp.%C1 %0, %I0 = %r3, %2"
3863 [(set_attr "itanium_class" "icmp")])
3864
3865(define_insn "*cmpsf_internal"
3866 [(set (match_operand:BI 0 "register_operand" "=c")
3867 (match_operator:BI 1 "comparison_operator"
3868 [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
3869 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
3870 ""
3871 "fcmp.%D1 %0, %I0 = %F2, %F3"
3872 [(set_attr "itanium_class" "fcmp")])
3873
3874(define_insn "*cmpdf_internal"
3875 [(set (match_operand:BI 0 "register_operand" "=c")
3876 (match_operator:BI 1 "comparison_operator"
3877 [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
3878 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
3879 ""
3880 "fcmp.%D1 %0, %I0 = %F2, %F3"
3881 [(set_attr "itanium_class" "fcmp")])
3882
3883(define_insn "*cmpxf_internal"
3884 [(set (match_operand:BI 0 "register_operand" "=c")
3885 (match_operator:BI 1 "comparison_operator"
3886 [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3887 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))]
3888 ""
3889 "fcmp.%D1 %0, %I0 = %F2, %F3"
3890 [(set_attr "itanium_class" "fcmp")])
3891
3892;; ??? Can this pattern be generated?
3893
3894(define_insn "*bit_zero"
3895 [(set (match_operand:BI 0 "register_operand" "=c")
3896 (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
3897 (const_int 1)
3898 (match_operand:DI 2 "shift_count_operand" "M"))
3899 (const_int 0)))]
3900 ""
3901 "tbit.z %0, %I0 = %1, %2"
3902 [(set_attr "itanium_class" "tbit")])
3903
3904(define_insn "*bit_one"
3905 [(set (match_operand:BI 0 "register_operand" "=c")
3906 (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
3907 (const_int 1)
3908 (match_operand:DI 2 "shift_count_operand" "M"))
3909 (const_int 0)))]
3910 ""
3911 "tbit.nz %0, %I0 = %1, %2"
3912 [(set_attr "itanium_class" "tbit")])
3913\f
3914;; ::::::::::::::::::::
3915;; ::
3916;; :: Branches
3917;; ::
3918;; ::::::::::::::::::::
3919
3920(define_insn "*br_true"
3921 [(set (pc)
3922 (if_then_else (match_operator 0 "predicate_operator"
3923 [(match_operand:BI 1 "register_operand" "c")
3924 (const_int 0)])
3925 (label_ref (match_operand 2 "" ""))
3926 (pc)))]
3927 ""
3928 "(%J0) br.cond%+ %l2"
3929 [(set_attr "itanium_class" "br")
3930 (set_attr "predicable" "no")])
3931
3932(define_insn "*br_false"
3933 [(set (pc)
3934 (if_then_else (match_operator 0 "predicate_operator"
3935 [(match_operand:BI 1 "register_operand" "c")
3936 (const_int 0)])
3937 (pc)
3938 (label_ref (match_operand 2 "" ""))))]
3939 ""
3940 "(%j0) br.cond%+ %l2"
3941 [(set_attr "itanium_class" "br")
3942 (set_attr "predicable" "no")])
3943\f
3944;; ::::::::::::::::::::
3945;; ::
3946;; :: Counted loop operations
3947;; ::
3948;; ::::::::::::::::::::
3949
3950(define_expand "doloop_end"
3951 [(use (match_operand 0 "" "")) ; loop pseudo
3952 (use (match_operand 1 "" "")) ; iterations; zero if unknown
3953 (use (match_operand 2 "" "")) ; max iterations
3954 (use (match_operand 3 "" "")) ; loop level
3955 (use (match_operand 4 "" ""))] ; label
3956 ""
3957{
3958 /* Only use cloop on innermost loops. */
3959 if (INTVAL (operands[3]) > 1)
3960 FAIL;
3961 emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
3962 operands[4]));
3963 DONE;
3964})
3965
3966(define_insn "doloop_end_internal"
3967 [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
3968 (const_int 0))
3969 (label_ref (match_operand 1 "" ""))
3970 (pc)))
3971 (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
3972 (plus:DI (match_dup 0) (const_int -1))
3973 (match_dup 0)))]
3974 ""
3975 "br.cloop.sptk.few %l1"
3976 [(set_attr "itanium_class" "br")
3977 (set_attr "predicable" "no")])
3978\f
3979;; ::::::::::::::::::::
3980;; ::
3981;; :: Set flag operations
3982;; ::
3983;; ::::::::::::::::::::
3984
3985(define_expand "cstorebi4"
3986 [(set (match_operand:DI 0 "gr_register_operand" "")
3987 (match_operator:DI 1 "ia64_cbranch_operator"
3988 [(match_operand:BI 2 "register_operand" "")
3989 (match_operand:BI 3 "const_int_operand" "")]))]
3990 ""
3991 "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
3992
3993(define_expand "cstoresi4"
3994 [(set (match_operand:DI 0 "gr_register_operand" "")
3995 (match_operator:DI 1 "ia64_cbranch_operator"
3996 [(match_operand:SI 2 "gr_register_operand" "")
3997 (match_operand:SI 3 "gr_reg_or_8bit_and_adjusted_operand" "")]))]
3998 ""
3999 "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
4000
4001(define_expand "cstoredi4"
4002 [(set (match_operand:DI 0 "gr_register_operand" "")
4003 (match_operator:DI 1 "ia64_cbranch_operator"
4004 [(match_operand:DI 2 "gr_register_operand" "")
4005 (match_operand:DI 3 "gr_reg_or_8bit_and_adjusted_operand" "")]))]
4006 ""
4007 "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
4008
4009(define_expand "cstoresf4"
4010 [(set (match_operand:DI 0 "gr_register_operand" "")
4011 (match_operator:DI 1 "ia64_cbranch_operator"
4012 [(match_operand:SF 2 "fr_reg_or_fp01_operand" "")
4013 (match_operand:SF 3 "fr_reg_or_fp01_operand" "")]))]
4014 ""
4015 "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
4016
4017(define_expand "cstoredf4"
4018 [(set (match_operand:DI 0 "gr_register_operand" "")
4019 (match_operator:DI 1 "ia64_cbranch_operator"
4020 [(match_operand:DF 2 "fr_reg_or_fp01_operand" "")
4021 (match_operand:DF 3 "fr_reg_or_fp01_operand" "")]))]
4022 ""
4023 "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
4024
4025(define_expand "cstorexf4"
4026 [(set (match_operand:DI 0 "gr_register_operand" "")
4027 (match_operator:DI 1 "ia64_cbranch_operator"
4028 [(match_operand:XF 2 "xfreg_or_fp01_operand" "")
4029 (match_operand:XF 3 "xfreg_or_fp01_operand" "")]))]
4030 ""
4031 "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
4032
4033(define_expand "cstoretf4"
4034 [(set (match_operand:DI 0 "gr_register_operand" "")
4035 (match_operator:DI 1 "ia64_cbranch_operator"
4036 [(match_operand:TF 2 "gr_register_operand" "")
4037 (match_operand:TF 3 "gr_register_operand" "")]))]
4038 "TARGET_HPUX"
4039 "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
4040
4041;; Don't allow memory as destination here, because cmov/cmov/st is more
4042;; efficient than mov/mov/cst/cst.
4043
4044(define_insn_and_split "*sne_internal"
4045 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4046 (ne:DI (match_operand:BI 1 "register_operand" "c")
4047 (const_int 0)))]
4048 ""
4049 "#"
4050 "reload_completed"
4051 [(cond_exec (ne (match_dup 1) (const_int 0))
4052 (set (match_dup 0) (const_int 1)))
4053 (cond_exec (eq (match_dup 1) (const_int 0))
4054 (set (match_dup 0) (const_int 0)))]
4055 ""
4056 [(set_attr "itanium_class" "unknown")])
4057
4058(define_insn_and_split "*seq_internal"
4059 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4060 (eq:DI (match_operand:BI 1 "register_operand" "c")
4061 (const_int 0)))]
4062 ""
4063 "#"
4064 "reload_completed"
4065 [(cond_exec (ne (match_dup 1) (const_int 0))
4066 (set (match_dup 0) (const_int 0)))
4067 (cond_exec (eq (match_dup 1) (const_int 0))
4068 (set (match_dup 0) (const_int 1)))]
4069 ""
4070 [(set_attr "itanium_class" "unknown")])
4071\f
4072;; ::::::::::::::::::::
4073;; ::
4074;; :: Conditional move instructions.
4075;; ::
4076;; ::::::::::::::::::::
4077
4078;; ??? Add movXXcc patterns?
4079
4080;;
4081;; DImode if_then_else patterns.
4082;;
4083
4084(define_insn "*cmovdi_internal"
4085 [(set (match_operand:DI 0 "not_postinc_destination_operand"
4086 "= r, r, r, r, r, r, r, r, r, r, m, Q, *f,*b,*d*e")
4087 (if_then_else:DI
4088 (match_operator 4 "predicate_operator"
4089 [(match_operand:BI 1 "register_operand"
4090 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
4091 (const_int 0)])
4092 (match_operand:DI 2 "not_postinc_move_operand"
4093 "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
4094 (match_operand:DI 3 "not_postinc_move_operand"
4095 "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
4096 "ia64_move_ok (operands[0], operands[2])
4097 && ia64_move_ok (operands[0], operands[3])"
4098 { gcc_unreachable (); }
4099 [(set_attr "predicable" "no")])
4100
4101(define_split
4102 [(set (match_operand 0 "not_postinc_destination_operand" "")
4103 (if_then_else
4104 (match_operator 4 "predicate_operator"
4105 [(match_operand:BI 1 "register_operand" "")
4106 (const_int 0)])
4107 (match_operand 2 "not_postinc_move_operand" "")
4108 (match_operand 3 "not_postinc_move_operand" "")))]
4109 "reload_completed"
4110 [(const_int 0)]
4111{
4112 bool emitted_something = false;
4113 rtx dest = operands[0];
4114 rtx srct = operands[2];
4115 rtx srcf = operands[3];
4116 rtx cond = operands[4];
4117
4118 if (! rtx_equal_p (dest, srct))
4119 {
4120 ia64_emit_cond_move (dest, srct, cond);
4121 emitted_something = true;
4122 }
4123 if (! rtx_equal_p (dest, srcf))
4124 {
4125 cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE,
4126 VOIDmode, operands[1], const0_rtx);
4127 ia64_emit_cond_move (dest, srcf, cond);
4128 emitted_something = true;
4129 }
4130 if (! emitted_something)
4131 emit_note (NOTE_INSN_DELETED);
4132 DONE;
4133})
4134
4135;; Absolute value pattern.
4136
4137(define_insn "*absdi2_internal"
4138 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4139 (if_then_else:DI
4140 (match_operator 4 "predicate_operator"
4141 [(match_operand:BI 1 "register_operand" "c,c")
4142 (const_int 0)])
4143 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
4144 (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
4145 ""
4146 "#"
4147 [(set_attr "itanium_class" "ialu,unknown")
4148 (set_attr "predicable" "no")])
4149
4150(define_split
4151 [(set (match_operand:DI 0 "register_operand" "")
4152 (if_then_else:DI
4153 (match_operator 4 "predicate_operator"
4154 [(match_operand:BI 1 "register_operand" "c,c")
4155 (const_int 0)])
4156 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4157 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4158 "reload_completed && rtx_equal_p (operands[0], operands[3])"
4159 [(cond_exec
4160 (match_dup 4)
4161 (set (match_dup 0)
4162 (neg:DI (match_dup 2))))]
4163 "")
4164
4165(define_split
4166 [(set (match_operand:DI 0 "register_operand" "")
4167 (if_then_else:DI
4168 (match_operator 4 "predicate_operator"
4169 [(match_operand:BI 1 "register_operand" "c,c")
4170 (const_int 0)])
4171 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4172 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4173 "reload_completed"
4174 [(cond_exec
4175 (match_dup 4)
4176 (set (match_dup 0) (neg:DI (match_dup 2))))
4177 (cond_exec
4178 (match_dup 5)
4179 (set (match_dup 0) (match_dup 3)))]
4180{
4181 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4182 VOIDmode, operands[1], const0_rtx);
4183})
4184
4185;;
4186;; SImode if_then_else patterns.
4187;;
4188
4189(define_insn "*cmovsi_internal"
4190 [(set (match_operand:SI 0 "not_postinc_destination_operand"
4191 "=r,m,*f,r,m,*f,r,m,*f")
4192 (if_then_else:SI
4193 (match_operator 4 "predicate_operator"
4194 [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
4195 (const_int 0)])
4196 (match_operand:SI 2 "not_postinc_move_operand"
4197 "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
4198 (match_operand:SI 3 "not_postinc_move_operand"
4199 "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
4200 "ia64_move_ok (operands[0], operands[2])
4201 && ia64_move_ok (operands[0], operands[3])"
4202 { gcc_unreachable (); }
4203 [(set_attr "predicable" "no")])
4204
4205(define_insn "*abssi2_internal"
4206 [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
4207 (if_then_else:SI
4208 (match_operator 4 "predicate_operator"
4209 [(match_operand:BI 1 "register_operand" "c,c")
4210 (const_int 0)])
4211 (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
4212 (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
4213 ""
4214 "#"
4215 [(set_attr "itanium_class" "ialu,unknown")
4216 (set_attr "predicable" "no")])
4217
4218(define_split
4219 [(set (match_operand:SI 0 "register_operand" "")
4220 (if_then_else:SI
4221 (match_operator 4 "predicate_operator"
4222 [(match_operand:BI 1 "register_operand" "c,c")
4223 (const_int 0)])
4224 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4225 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
4226 "reload_completed && rtx_equal_p (operands[0], operands[3])"
4227 [(cond_exec
4228 (match_dup 4)
4229 (set (match_dup 0)
4230 (neg:SI (match_dup 2))))]
4231 "")
4232
4233(define_split
4234 [(set (match_operand:SI 0 "register_operand" "")
4235 (if_then_else:SI
4236 (match_operator 4 "predicate_operator"
4237 [(match_operand:BI 1 "register_operand" "c,c")
4238 (const_int 0)])
4239 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4240 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
4241 "reload_completed"
4242 [(cond_exec
4243 (match_dup 4)
4244 (set (match_dup 0) (neg:SI (match_dup 2))))
4245 (cond_exec
4246 (match_dup 5)
4247 (set (match_dup 0) (match_dup 3)))]
4248{
4249 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4250 VOIDmode, operands[1], const0_rtx);
4251})
4252
4253(define_insn_and_split "*cond_opsi2_internal"
4254 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4255 (match_operator:SI 5 "condop_operator"
4256 [(if_then_else:SI
4257 (match_operator 6 "predicate_operator"
4258 [(match_operand:BI 1 "register_operand" "c")
4259 (const_int 0)])
4260 (match_operand:SI 2 "gr_register_operand" "r")
4261 (match_operand:SI 3 "gr_register_operand" "r"))
4262 (match_operand:SI 4 "gr_register_operand" "r")]))]
4263 ""
4264 "#"
4265 "reload_completed"
4266 [(cond_exec
4267 (match_dup 6)
4268 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
4269 (cond_exec
4270 (match_dup 7)
4271 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
4272{
4273 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
4274 VOIDmode, operands[1], const0_rtx);
4275}
4276 [(set_attr "itanium_class" "ialu")
4277 (set_attr "predicable" "no")])
4278
4279
4280(define_insn_and_split "*cond_opsi2_internal_b"
4281 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4282 (match_operator:SI 5 "condop_operator"
4283 [(match_operand:SI 4 "gr_register_operand" "r")
4284 (if_then_else:SI
4285 (match_operator 6 "predicate_operator"
4286 [(match_operand:BI 1 "register_operand" "c")
4287 (const_int 0)])
4288 (match_operand:SI 2 "gr_register_operand" "r")
4289 (match_operand:SI 3 "gr_register_operand" "r"))]))]
4290 ""
4291 "#"
4292 "reload_completed"
4293 [(cond_exec
4294 (match_dup 6)
4295 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
4296 (cond_exec
4297 (match_dup 7)
4298 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
4299{
4300 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
4301 VOIDmode, operands[1], const0_rtx);
4302}
4303 [(set_attr "itanium_class" "ialu")
4304 (set_attr "predicable" "no")])
4305
4306\f
4307;; ::::::::::::::::::::
4308;; ::
4309;; :: Call and branch instructions
4310;; ::
4311;; ::::::::::::::::::::
4312
4313;; Subroutine call instruction returning no value. Operand 0 is the function
4314;; to call; operand 1 is the number of bytes of arguments pushed (in mode
4315;; `SImode', except it is normally a `const_int'); operand 2 is the number of
4316;; registers used as operands.
4317
4318;; On most machines, operand 2 is not actually stored into the RTL pattern. It
4319;; is supplied for the sake of some RISC machines which need to put this
4320;; information into the assembler code; they can put it in the RTL instead of
4321;; operand 1.
4322
4323(define_expand "call"
4324 [(use (match_operand:DI 0 "" ""))
4325 (use (match_operand 1 "" ""))
4326 (use (match_operand 2 "" ""))
4327 (use (match_operand 3 "" ""))]
4328 ""
4329{
4330 ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
4331 DONE;
4332})
4333
4334(define_expand "sibcall"
4335 [(use (match_operand:DI 0 "" ""))
4336 (use (match_operand 1 "" ""))
4337 (use (match_operand 2 "" ""))
4338 (use (match_operand 3 "" ""))]
4339 ""
4340{
4341 ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
4342 DONE;
4343})
4344
4345;; Subroutine call instruction returning a value. Operand 0 is the hard
4346;; register in which the value is returned. There are three more operands,
4347;; the same as the three operands of the `call' instruction (but with numbers
4348;; increased by one).
4349;;
4350;; Subroutines that return `BLKmode' objects use the `call' insn.
4351
4352(define_expand "call_value"
4353 [(use (match_operand 0 "" ""))
4354 (use (match_operand:DI 1 "" ""))
4355 (use (match_operand 2 "" ""))
4356 (use (match_operand 3 "" ""))
4357 (use (match_operand 4 "" ""))]
4358 ""
4359{
4360 ia64_expand_call (operands[0], operands[1], operands[3], false);
4361 DONE;
4362})
4363
4364(define_expand "sibcall_value"
4365 [(use (match_operand 0 "" ""))
4366 (use (match_operand:DI 1 "" ""))
4367 (use (match_operand 2 "" ""))
4368 (use (match_operand 3 "" ""))
4369 (use (match_operand 4 "" ""))]
4370 ""
4371{
4372 ia64_expand_call (operands[0], operands[1], operands[3], true);
4373 DONE;
4374})
4375
4376;; Call subroutine returning any type.
4377
4378(define_expand "untyped_call"
4379 [(parallel [(call (match_operand 0 "" "")
4380 (const_int 0))
4381 (match_operand 1 "" "")
4382 (match_operand 2 "" "")])]
4383 ""
4384{
4385 int i;
4386
4387 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
4388
4389 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4390 {
4391 rtx set = XVECEXP (operands[2], 0, i);
4392 emit_move_insn (SET_DEST (set), SET_SRC (set));
4393 }
4394
4395 /* The optimizer does not know that the call sets the function value
4396 registers we stored in the result block. We avoid problems by
4397 claiming that all hard registers are used and clobbered at this
4398 point. */
4399 emit_insn (gen_blockage ());
4400
4401 DONE;
4402})
4403
4404(define_insn "call_nogp"
4405 [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,s"))
4406 (const_int 0))
4407 (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
4408 ""
4409 "br.call%+.many %1 = %0"
4410 [(set_attr "itanium_class" "br,scall")])
4411
4412(define_insn "call_value_nogp"
4413 [(set (match_operand 0 "" "=X,X")
4414 (call (mem:DI (match_operand:DI 1 "call_operand" "?b,s"))
4415 (const_int 0)))
4416 (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
4417 ""
4418 "br.call%+.many %2 = %1"
4419 [(set_attr "itanium_class" "br,scall")])
4420
4421(define_insn "sibcall_nogp"
4422 [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,s"))
4423 (const_int 0))]
4424 ""
4425 "br%+.many %0"
4426 [(set_attr "itanium_class" "br,scall")])
4427
4428(define_insn "call_gp"
4429 [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,s"))
4430 (const_int 1))
4431 (clobber (match_operand:DI 1 "register_operand" "=b,b"))
4432 (clobber (match_scratch:DI 2 "=&r,X"))
4433 (clobber (match_scratch:DI 3 "=b,X"))]
4434 ""
4435 "#"
4436 [(set_attr "itanium_class" "br,scall")])
4437
4438;; Irritatingly, we don't have access to INSN within the split body.
4439;; See commentary in ia64_split_call as to why these aren't peep2.
4440(define_split
4441 [(call (mem (match_operand 0 "call_operand" ""))
4442 (const_int 1))
4443 (clobber (match_operand:DI 1 "register_operand" ""))
4444 (clobber (match_scratch:DI 2 ""))
4445 (clobber (match_scratch:DI 3 ""))]
4446 "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4447 [(const_int 0)]
4448{
4449 ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
4450 operands[3], true, false);
4451 DONE;
4452})
4453
4454(define_split
4455 [(call (mem (match_operand 0 "call_operand" ""))
4456 (const_int 1))
4457 (clobber (match_operand:DI 1 "register_operand" ""))
4458 (clobber (match_scratch:DI 2 ""))
4459 (clobber (match_scratch:DI 3 ""))]
4460 "reload_completed"
4461 [(const_int 0)]
4462{
4463 ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
4464 operands[3], false, false);
4465 DONE;
4466})
4467
4468(define_insn "call_value_gp"
4469 [(set (match_operand 0 "" "=X,X")
4470 (call (mem:DI (match_operand:DI 1 "call_operand" "?r,s"))
4471 (const_int 1)))
4472 (clobber (match_operand:DI 2 "register_operand" "=b,b"))
4473 (clobber (match_scratch:DI 3 "=&r,X"))
4474 (clobber (match_scratch:DI 4 "=b,X"))]
4475 ""
4476 "#"
4477 [(set_attr "itanium_class" "br,scall")])
4478
4479(define_split
4480 [(set (match_operand 0 "" "")
4481 (call (mem:DI (match_operand:DI 1 "call_operand" ""))
4482 (const_int 1)))
4483 (clobber (match_operand:DI 2 "register_operand" ""))
4484 (clobber (match_scratch:DI 3 ""))
4485 (clobber (match_scratch:DI 4 ""))]
4486 "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4487 [(const_int 0)]
4488{
4489 ia64_split_call (operands[0], operands[1], operands[2], operands[3],
4490 operands[4], true, false);
4491 DONE;
4492})
4493
4494(define_split
4495 [(set (match_operand 0 "" "")
4496 (call (mem:DI (match_operand:DI 1 "call_operand" ""))
4497 (const_int 1)))
4498 (clobber (match_operand:DI 2 "register_operand" ""))
4499 (clobber (match_scratch:DI 3 ""))
4500 (clobber (match_scratch:DI 4 ""))]
4501 "reload_completed"
4502 [(const_int 0)]
4503{
4504 ia64_split_call (operands[0], operands[1], operands[2], operands[3],
4505 operands[4], false, false);
4506 DONE;
4507})
4508
4509(define_insn_and_split "sibcall_gp"
4510 [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,s"))
4511 (const_int 1))
4512 (clobber (match_scratch:DI 1 "=&r,X"))
4513 (clobber (match_scratch:DI 2 "=b,X"))]
4514 ""
4515 "#"
4516 "reload_completed"
4517 [(const_int 0)]
4518{
4519 ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
4520 operands[2], true, true);
4521 DONE;
4522}
4523 [(set_attr "itanium_class" "br")])
4524
4525(define_insn "return_internal"
4526 [(return)
4527 (use (match_operand:DI 0 "register_operand" "b"))]
4528 ""
4529 "br.ret.sptk.many %0"
4530 [(set_attr "itanium_class" "br")])
4531
4532(define_insn "return"
4533 [(return)]
4534 "ia64_direct_return ()"
4535 "br.ret.sptk.many rp"
4536 [(set_attr "itanium_class" "br")])
4537
4538(define_insn "*return_true"
4539 [(set (pc)
4540 (if_then_else (match_operator 0 "predicate_operator"
4541 [(match_operand:BI 1 "register_operand" "c")
4542 (const_int 0)])
4543 (return)
4544 (pc)))]
4545 "ia64_direct_return ()"
4546 "(%J0) br.ret%+.many rp"
4547 [(set_attr "itanium_class" "br")
4548 (set_attr "predicable" "no")])
4549
4550(define_insn "*return_false"
4551 [(set (pc)
4552 (if_then_else (match_operator 0 "predicate_operator"
4553 [(match_operand:BI 1 "register_operand" "c")
4554 (const_int 0)])
4555 (pc)
4556 (return)))]
4557 "ia64_direct_return ()"
4558 "(%j0) br.ret%+.many rp"
4559 [(set_attr "itanium_class" "br")
4560 (set_attr "predicable" "no")])
4561
4562(define_insn "jump"
4563 [(set (pc) (label_ref (match_operand 0 "" "")))]
4564 ""
4565 "br %l0"
4566 [(set_attr "itanium_class" "br")])
4567
4568(define_insn "indirect_jump"
4569 [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
4570 ""
4571 "br %0"
4572 [(set_attr "itanium_class" "br")])
4573
4574(define_expand "tablejump"
4575 [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
4576 (use (label_ref (match_operand 1 "" "")))])]
4577 ""
4578{
4579 rtx op0 = operands[0];
4580 rtx addr;
4581
4582 /* ??? Bother -- do_tablejump is "helpful" and pulls the table
4583 element into a register without bothering to see whether that
4584 is necessary given the operand predicate. Check for MEM just
4585 in case someone fixes this. */
4586 if (GET_CODE (op0) == MEM)
4587 addr = XEXP (op0, 0);
4588 else
4589 {
4590 /* Otherwise, cheat and guess that the previous insn in the
4591 stream was the memory load. Grab the address from that.
4592 Note we have to momentarily pop out of the sequence started
4593 by the insn-emit wrapper in order to grab the last insn. */
4594 rtx last, set;
4595
4596 end_sequence ();
4597 last = get_last_insn ();
4598 start_sequence ();
4599 set = single_set (last);
4600
4601 gcc_assert (rtx_equal_p (SET_DEST (set), op0)
4602 && GET_CODE (SET_SRC (set)) == MEM);
4603 addr = XEXP (SET_SRC (set), 0);
4604 gcc_assert (!rtx_equal_p (addr, op0));
4605 }
4606
4607 /* Jump table elements are stored pc-relative. That is, a displacement
4608 from the entry to the label. Thus to convert to an absolute address
4609 we add the address of the memory from which the value is loaded. */
4610 operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
4611 NULL_RTX, 1, OPTAB_DIRECT);
4612})
4613
4614(define_insn "*tablejump_internal"
4615 [(set (pc) (match_operand:DI 0 "register_operand" "b"))
4616 (use (label_ref (match_operand 1 "" "")))]
4617 ""
4618 "br %0"
4619 [(set_attr "itanium_class" "br")])
4620
4621\f
4622;; ::::::::::::::::::::
4623;; ::
4624;; :: Prologue and Epilogue instructions
4625;; ::
4626;; ::::::::::::::::::::
4627
4628(define_expand "prologue"
4629 [(const_int 1)]
4630 ""
4631{
4632 ia64_expand_prologue ();
4633 DONE;
4634})
4635
4636(define_expand "epilogue"
4637 [(return)]
4638 ""
4639{
4640 ia64_expand_epilogue (0);
4641 DONE;
4642})
4643
4644(define_expand "sibcall_epilogue"
4645 [(return)]
4646 ""
4647{
4648 ia64_expand_epilogue (1);
4649 DONE;
4650})
4651
4652;; This prevents the scheduler from moving the SP decrement past FP-relative
4653;; stack accesses. This is the same as adddi3 plus the extra set.
4654
4655(define_insn "prologue_allocate_stack"
4656 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4657 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
4658 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
4659 (set (match_operand:DI 3 "register_operand" "+r,r,r")
4660 (match_dup 3))]
4661 ""
4662 "@
4663 add %0 = %1, %2
4664 adds %0 = %2, %1
4665 addl %0 = %2, %1"
4666 [(set_attr "itanium_class" "ialu")])
4667
4668;; This prevents the scheduler from moving the SP restore past FP-relative
4669;; stack accesses. This is similar to movdi plus the extra set.
4670
4671(define_insn "epilogue_deallocate_stack"
4672 [(set (match_operand:DI 0 "register_operand" "=r")
4673 (match_operand:DI 1 "register_operand" "+r"))
4674 (set (match_dup 1) (match_dup 1))]
4675 ""
4676 "mov %0 = %1"
4677 [(set_attr "itanium_class" "ialu")])
4678
4679;; As USE insns aren't meaningful after reload, this is used instead
4680;; to prevent deleting instructions setting registers for EH handling
4681(define_insn "prologue_use"
4682 [(unspec:DI [(match_operand:DI 0 "register_operand" "")]
4683 UNSPEC_PROLOGUE_USE)]
4684 ""
4685 ""
4686 [(set_attr "itanium_class" "ignore")
4687 (set_attr "predicable" "no")
4688 (set_attr "empty" "yes")])
4689
4690;; Allocate a new register frame.
4691
4692(define_insn "alloc"
4693 [(set (match_operand:DI 0 "register_operand" "=r")
4694 (unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC))
4695 (use (match_operand:DI 1 "const_int_operand" "i"))
4696 (use (match_operand:DI 2 "const_int_operand" "i"))
4697 (use (match_operand:DI 3 "const_int_operand" "i"))
4698 (use (match_operand:DI 4 "const_int_operand" "i"))]
4699 ""
4700 "alloc %0 = ar.pfs, %1, %2, %3, %4"
4701 [(set_attr "itanium_class" "syst_m0")
4702 (set_attr "predicable" "no")
4703 (set_attr "first_insn" "yes")])
4704
4705;; Modifies ar.unat
4706(define_expand "gr_spill"
4707 [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
4708 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4709 (match_operand:DI 2 "const_int_operand" "")]
4710 UNSPEC_GR_SPILL))
4711 (clobber (match_dup 3))])]
4712 ""
4713 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
4714
4715(define_insn "gr_spill_internal"
4716 [(set (match_operand:DI 0 "destination_operand" "=m")
4717 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4718 (match_operand:DI 2 "const_int_operand" "")]
4719 UNSPEC_GR_SPILL))
4720 (clobber (match_operand:DI 3 "register_operand" ""))]
4721 ""
4722{
4723 /* Note that we use a C output pattern here to avoid the predicate
4724 being automatically added before the .mem.offset directive. */
4725 return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
4726}
4727 [(set_attr "itanium_class" "st")])
4728
4729;; Reads ar.unat
4730(define_expand "gr_restore"
4731 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
4732 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
4733 (match_operand:DI 2 "const_int_operand" "")]
4734 UNSPEC_GR_RESTORE))
4735 (use (match_dup 3))])]
4736 ""
4737 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
4738
4739(define_insn "gr_restore_internal"
4740 [(set (match_operand:DI 0 "register_operand" "=r")
4741 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
4742 (match_operand:DI 2 "const_int_operand" "")]
4743 UNSPEC_GR_RESTORE))
4744 (use (match_operand:DI 3 "register_operand" ""))]
4745 ""
4746 { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
4747 [(set_attr "itanium_class" "ld")])
4748
4749(define_insn "fr_spill"
4750 [(set (match_operand:XF 0 "destination_operand" "=m")
4751 (unspec:XF [(match_operand:XF 1 "register_operand" "f")]
4752 UNSPEC_FR_SPILL))]
4753 ""
4754 "stf.spill %0 = %1%P0"
4755 [(set_attr "itanium_class" "stf")])
4756
4757(define_insn "fr_restore"
4758 [(set (match_operand:XF 0 "register_operand" "=f")
4759 (unspec:XF [(match_operand:XF 1 "memory_operand" "m")]
4760 UNSPEC_FR_RESTORE))]
4761 ""
4762 "ldf.fill %0 = %1%P1"
4763 [(set_attr "itanium_class" "fld")])
4764
4765;; ??? The explicit stop is not ideal. It would be better if
4766;; rtx_needs_barrier took care of this, but this is something that can be
4767;; fixed later. This avoids an RSE DV.
4768
4769(define_insn "bsp_value"
4770 [(set (match_operand:DI 0 "register_operand" "=r")
4771 (unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
4772 ""
4773 "*
4774{
4775 return \";;\;%,mov %0 = ar.bsp\";
4776}"
4777 [(set_attr "itanium_class" "frar_i")])
4778
4779(define_insn "set_bsp"
4780 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
4781 UNSPECV_SET_BSP)]
4782 ""
4783 "flushrs
4784 mov r19=ar.rsc
4785 ;;
4786 and r19=0x1c,r19
4787 ;;
4788 mov ar.rsc=r19
4789 ;;
4790 mov ar.bspstore=%0
4791 ;;
4792 or r19=0x3,r19
4793 ;;
4794 loadrs
4795 invala
4796 ;;
4797 mov ar.rsc=r19"
4798 [(set_attr "itanium_class" "unknown")
4799 (set_attr "predicable" "no")])
4800
4801;; ??? The explicit stops are not ideal. It would be better if
4802;; rtx_needs_barrier took care of this, but this is something that can be
4803;; fixed later. This avoids an RSE DV.
4804
4805(define_insn "flushrs"
4806 [(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
4807 ""
4808 ";;\;flushrs\;;;"
4809 [(set_attr "itanium_class" "rse_m")
4810 (set_attr "predicable" "no")])
4811\f
4812;; ::::::::::::::::::::
4813;; ::
4814;; :: Miscellaneous instructions
4815;; ::
4816;; ::::::::::::::::::::
4817
4818;; ??? Emitting a NOP instruction isn't very useful. This should probably
4819;; be emitting ";;" to force a break in the instruction packing.
4820
4821;; No operation, needed in case the user uses -g but not -O.
4822(define_insn "nop"
4823 [(const_int 0)]
4824 ""
4825 "nop 0"
4826 [(set_attr "itanium_class" "nop")])
4827
4828(define_insn "nop_m"
4829 [(const_int 1)]
4830 ""
4831 "nop.m 0"
4832 [(set_attr "itanium_class" "nop_m")])
4833
4834(define_insn "nop_i"
4835 [(const_int 2)]
4836 ""
4837 "nop.i 0"
4838 [(set_attr "itanium_class" "nop_i")])
4839
4840(define_insn "nop_f"
4841 [(const_int 3)]
4842 ""
4843 "nop.f 0"
4844 [(set_attr "itanium_class" "nop_f")])
4845
4846(define_insn "nop_b"
4847 [(const_int 4)]
4848 ""
4849 "nop.b 0"
4850 [(set_attr "itanium_class" "nop_b")])
4851
4852(define_insn "nop_x"
4853 [(const_int 5)]
4854 ""
4855 ""
4856 [(set_attr "itanium_class" "nop_x")
4857 (set_attr "empty" "yes")])
4858
4859;; The following insn will be never generated. It is used only by
4860;; insn scheduler to change state before advancing cycle.
4861(define_insn "pre_cycle"
4862 [(const_int 6)]
4863 ""
4864 ""
4865 [(set_attr "itanium_class" "pre_cycle")])
4866
4867(define_insn "bundle_selector"
4868 [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
4869 ""
4870 { return get_bundle_name (INTVAL (operands[0])); }
4871 [(set_attr "itanium_class" "ignore")
4872 (set_attr "predicable" "no")])
4873
4874;; Pseudo instruction that prevents the scheduler from moving code above this
4875;; point.
4876(define_insn "blockage"
4877 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
4878 ""
4879 ""
4880 [(set_attr "itanium_class" "ignore")
4881 (set_attr "predicable" "no")])
4882
4883(define_insn "insn_group_barrier"
4884 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
4885 UNSPECV_INSN_GROUP_BARRIER)]
4886 ""
4887 ";;"
4888 [(set_attr "itanium_class" "stop_bit")
4889 (set_attr "predicable" "no")
4890 (set_attr "empty" "yes")])
4891
4892(define_expand "trap"
4893 [(trap_if (const_int 1) (const_int 0))]
4894 ""
4895 "")
4896
4897;; ??? We don't have a match-any slot type. Setting the type to unknown
4898;; produces worse code that setting the slot type to A.
4899
4900(define_insn "*trap"
4901 [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
4902 ""
4903 "break %0"
4904 [(set_attr "itanium_class" "chk_s_i")])
4905
4906(define_expand "ctrapbi4"
4907 [(trap_if (match_operator 0 "ia64_cbranch_operator"
4908 [(match_operand:BI 1 "register_operand" "")
4909 (match_operand:BI 2 "const_int_operand" "")])
4910 (match_operand 3 "" ""))]
4911 ""
4912 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
4913
4914(define_expand "ctrapsi4"
4915 [(trap_if (match_operator 0 "ia64_cbranch_operator"
4916 [(match_operand:SI 1 "gr_register_operand" "")
4917 (match_operand:SI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
4918 (match_operand 3 "" ""))]
4919 ""
4920 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
4921
4922(define_expand "ctrapdi4"
4923 [(trap_if (match_operator 0 "ia64_cbranch_operator"
4924 [(match_operand:DI 1 "gr_register_operand" "")
4925 (match_operand:DI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
4926 (match_operand 3 "" ""))]
4927 ""
4928 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
4929
4930(define_expand "ctrapsf4"
4931 [(trap_if (match_operator 0 "ia64_cbranch_operator"
4932 [(match_operand:SF 1 "fr_reg_or_fp01_operand" "")
4933 (match_operand:SF 2 "fr_reg_or_fp01_operand" "")])
4934 (match_operand 3 "" ""))]
4935 ""
4936 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
4937
4938(define_expand "ctrapdf4"
4939 [(trap_if (match_operator 0 "ia64_cbranch_operator"
4940 [(match_operand:DF 1 "fr_reg_or_fp01_operand" "")
4941 (match_operand:DF 2 "fr_reg_or_fp01_operand" "")])
4942 (match_operand 3 "" ""))]
4943 ""
4944 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
4945
4946(define_expand "ctrapxf4"
4947 [(trap_if (match_operator 0 "ia64_cbranch_operator"
4948 [(match_operand:XF 1 "xfreg_or_fp01_operand" "")
4949 (match_operand:XF 2 "xfreg_or_fp01_operand" "")])
4950 (match_operand 3 "" ""))]
4951 ""
4952 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
4953
4954(define_expand "ctraptf4"
4955 [(trap_if (match_operator 0 "ia64_cbranch_operator"
4956 [(match_operand:TF 1 "gr_register_operand" "")
4957 (match_operand:TF 2 "gr_register_operand" "")])
4958 (match_operand 3 "" ""))]
4959 "TARGET_HPUX"
4960 "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
4961
4962
4963(define_insn "*conditional_trap"
4964 [(trap_if (match_operator 0 "predicate_operator"
4965 [(match_operand:BI 1 "register_operand" "c")
4966 (const_int 0)])
4967 (match_operand 2 "const_int_operand" ""))]
4968 ""
4969 "(%J0) break %2"
4970 [(set_attr "itanium_class" "chk_s_i")
4971 (set_attr "predicable" "no")])
4972
4973(define_insn "break_f"
4974 [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)]
4975 ""
4976 "break.f 0"
4977 [(set_attr "itanium_class" "nop_f")])
4978
4979(define_insn "prefetch"
4980 [(prefetch (match_operand:DI 0 "address_operand" "p")
4981 (match_operand:DI 1 "const_int_operand" "n")
4982 (match_operand:DI 2 "const_int_operand" "n"))]
4983 ""
4984{
4985 static const char * const alt[2][4] = {
4986 {
4987 "%,lfetch.nta [%0]",
4988 "%,lfetch.nt1 [%0]",
4989 "%,lfetch.nt2 [%0]",
4990 "%,lfetch [%0]"
4991 },
4992 {
4993 "%,lfetch.excl.nta [%0]",
4994 "%,lfetch.excl.nt1 [%0]",
4995 "%,lfetch.excl.nt2 [%0]",
4996 "%,lfetch.excl [%0]"
4997 }
4998 };
4999 int i = (INTVAL (operands[1]));
5000 int j = (INTVAL (operands[2]));
5001
5002 gcc_assert (i == 0 || i == 1);
5003 gcc_assert (j >= 0 && j <= 3);
5004 return alt[i][j];
5005}
5006 [(set_attr "itanium_class" "lfetch")])
5007\f
5008;; Non-local goto support.
5009
5010(define_expand "save_stack_nonlocal"
5011 [(use (match_operand:OI 0 "memory_operand" ""))
5012 (use (match_operand:DI 1 "register_operand" ""))]
5013 ""
5014{
5015 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5016 \"__ia64_save_stack_nonlocal\"),
5017 LCT_NORMAL, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
5018 operands[1], Pmode);
5019 DONE;
5020})
5021
5022(define_expand "nonlocal_goto"
5023 [(use (match_operand 0 "general_operand" ""))
5024 (use (match_operand 1 "general_operand" ""))
5025 (use (match_operand 2 "general_operand" ""))
5026 (use (match_operand 3 "general_operand" ""))]
5027 ""
5028{
5029 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
5030 LCT_NORETURN, VOIDmode, 3,
5031 operands[1], Pmode,
5032 copy_to_reg (XEXP (operands[2], 0)), Pmode,
5033 operands[3], Pmode);
5034 emit_barrier ();
5035 DONE;
5036})
5037
5038(define_insn_and_split "nonlocal_goto_receiver"
5039 [(unspec_volatile [(const_int 0)] UNSPECV_GOTO_RECEIVER)]
5040 ""
5041 "#"
5042 "reload_completed"
5043 [(const_int 0)]
5044{
5045 ia64_reload_gp ();
5046 DONE;
5047})
5048
5049(define_insn_and_split "builtin_setjmp_receiver"
5050 [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
5051 ""
5052 "#"
5053 "reload_completed"
5054 [(const_int 0)]
5055{
5056 ia64_reload_gp ();
5057 DONE;
5058})
5059
5060(define_expand "eh_epilogue"
5061 [(use (match_operand:DI 0 "register_operand" "r"))
5062 (use (match_operand:DI 1 "register_operand" "r"))
5063 (use (match_operand:DI 2 "register_operand" "r"))]
5064 ""
5065{
5066 rtx bsp = gen_rtx_REG (Pmode, 10);
5067 rtx sp = gen_rtx_REG (Pmode, 9);
5068
5069 if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
5070 {
5071 emit_move_insn (bsp, operands[0]);
5072 operands[0] = bsp;
5073 }
5074 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
5075 {
5076 emit_move_insn (sp, operands[2]);
5077 operands[2] = sp;
5078 }
5079 emit_use (sp);
5080 emit_use (bsp);
5081
5082 cfun->machine->ia64_eh_epilogue_sp = sp;
5083 cfun->machine->ia64_eh_epilogue_bsp = bsp;
5084})
5085\f
5086;; Builtin apply support.
5087
5088(define_expand "restore_stack_nonlocal"
5089 [(use (match_operand:DI 0 "register_operand" ""))
5090 (use (match_operand:OI 1 "memory_operand" ""))]
5091 ""
5092{
5093 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5094 "__ia64_restore_stack_nonlocal"),
5095 LCT_NORMAL, VOIDmode, 1,
5096 copy_to_reg (XEXP (operands[1], 0)), Pmode);
5097 DONE;
5098})
5099
5100\f
5101;; Predication.
5102
5103(define_cond_exec
5104 [(match_operator 0 "predicate_operator"
5105 [(match_operand:BI 1 "register_operand" "c")
5106 (const_int 0)])]
5107 ""
5108 "(%J0)")
5109
5110(define_insn "pred_rel_mutex"
5111 [(set (match_operand:BI 0 "register_operand" "+c")
5112 (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
5113 ""
5114 ".pred.rel.mutex %0, %I0"
5115 [(set_attr "itanium_class" "ignore")
5116 (set_attr "predicable" "no")])
5117
5118(define_insn "safe_across_calls_all"
5119 [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)]
5120 ""
5121 ".pred.safe_across_calls p1-p63"
5122 [(set_attr "itanium_class" "ignore")
5123 (set_attr "predicable" "no")])
5124
5125(define_insn "safe_across_calls_normal"
5126 [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
5127 ""
5128{
5129 emit_safe_across_calls ();
5130 return "";
5131}
5132 [(set_attr "itanium_class" "ignore")
5133 (set_attr "predicable" "no")])
5134
5135;; UNSPEC instruction definition to "swizzle" 32-bit pointer into 64-bit
5136;; pointer. This is used by the HP-UX 32 bit mode.
5137
5138(define_insn "ptr_extend"
5139 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5140 (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")]
5141 UNSPEC_ADDP4))]
5142 ""
5143 "addp4 %0 = 0,%1"
5144 [(set_attr "itanium_class" "ialu")])
5145
5146;;
5147;; Optimizations for ptr_extend
5148
5149(define_insn "ptr_extend_plus_imm"
5150 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5151 (unspec:DI
5152 [(plus:SI (match_operand:SI 1 "basereg_operand" "r")
5153 (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
5154 UNSPEC_ADDP4))]
5155 "addp4_optimize_ok (operands[1], operands[2])"
5156 "addp4 %0 = %2, %1"
5157 [(set_attr "itanium_class" "ialu")])
5158
5159(define_insn "*ptr_extend_plus_2"
5160 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5161 (unspec:DI
5162 [(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
5163 (match_operand:SI 2 "basereg_operand" "r"))]
5164 UNSPEC_ADDP4))]
5165 "addp4_optimize_ok (operands[1], operands[2])"
5166 "addp4 %0 = %1, %2"
5167 [(set_attr "itanium_class" "ialu")])
5168
5169;;
5170;; Get instruction pointer
5171
5172(define_insn "ip_value"
5173 [(set (match_operand:DI 0 "register_operand" "=r")
5174 (pc))]
5175 ""
5176 "mov %0 = ip"
5177 [(set_attr "itanium_class" "frbr")])
5178
5179;; Vector operations
5180(include "vect.md")
5181;; Atomic operations
5182(include "sync.md")
5183;; New division operations
5184(include "div.md")
This page took 0.067025 seconds and 5 git commands to generate.