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