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