linux-aout.h: Fix comment formatting.
[gcc.git] / gcc / config / sparc / sparc.md
1 ;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
6 ;; at Cygnus Support.
7
8 ;; This file is part of GNU CC.
9
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
28 ;;
29 ;; UNSPEC: 0 movsi_{lo_sum,high}_pic
30 ;; pic_lo_sum_di
31 ;; pic_sethi_di
32 ;; 1 update_return
33 ;; 2 get_pc
34 ;; 5 movsi_{,lo_sum_,high_}pic_label_ref
35 ;; 6 seth44
36 ;; 7 setm44
37 ;; 8 setl44
38 ;; 9 sethh
39 ;; 10 setlm
40 ;; 11 embmedany_sethi, embmedany_brsum
41 ;; 13 embmedany_textuhi
42 ;; 14 embmedany_texthi
43 ;; 15 embmedany_textulo
44 ;; 16 embmedany_textlo
45 ;; 18 sethm
46 ;; 19 setlo
47 ;;
48 ;; UNSPEC_VOLATILE: 0 blockage
49 ;; 1 flush_register_windows
50 ;; 2 goto_handler_and_restore
51 ;; 3 goto_handler_and_restore_v9*
52 ;; 4 flush
53 ;; 5 do_builtin_setjmp_setup
54 ;;
55
56 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
57 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
58 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
59 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
60 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
61
62 ;; Attribute for cpu type.
63 ;; These must match the values for enum processor_type in sparc.h.
64 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc"
65 (const (symbol_ref "sparc_cpu_attr")))
66
67 ;; Attribute for the instruction set.
68 ;; At present we only need to distinguish v9/!v9, but for clarity we
69 ;; test TARGET_V8 too.
70 (define_attr "isa" "v6,v8,v9,sparclet"
71 (const
72 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
73 (symbol_ref "TARGET_V8") (const_string "v8")
74 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
75 (const_string "v6"))))
76
77 ;; Architecture size.
78 (define_attr "arch" "arch32bit,arch64bit"
79 (const
80 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
81 (const_string "arch32bit"))))
82
83 ;; Insn type.
84
85 (define_attr "type"
86 "ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,idiv,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
87 (const_string "ialu"))
88
89 ;; Length (in # of insns).
90 (define_attr "length" "" (const_int 1))
91
92 ;; FP precision.
93 (define_attr "fptype" "single,double" (const_string "single"))
94
95 (define_asm_attributes
96 [(set_attr "length" "2")
97 (set_attr "type" "multi")])
98
99 ;; Attributes for instruction and branch scheduling
100
101 (define_attr "in_call_delay" "false,true"
102 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
103 (const_string "false")
104 (eq_attr "type" "load,fpload,store,fpstore")
105 (if_then_else (eq_attr "length" "1")
106 (const_string "true")
107 (const_string "false"))]
108 (if_then_else (eq_attr "length" "1")
109 (const_string "true")
110 (const_string "false"))))
111
112 (define_delay (eq_attr "type" "call")
113 [(eq_attr "in_call_delay" "true") (nil) (nil)])
114
115 (define_attr "eligible_for_sibcall_delay" "false,true"
116 (symbol_ref "eligible_for_sibcall_delay (insn)"))
117
118 (define_delay (eq_attr "type" "sibcall")
119 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
120
121 (define_attr "leaf_function" "false,true"
122 (const (symbol_ref "current_function_uses_only_leaf_regs")))
123
124 (define_attr "eligible_for_return_delay" "false,true"
125 (symbol_ref "eligible_for_return_delay (insn)"))
126
127 (define_attr "in_return_delay" "false,true"
128 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
129 (eq_attr "length" "1"))
130 (eq_attr "leaf_function" "false"))
131 (eq_attr "eligible_for_return_delay" "false"))
132 (const_string "true")
133 (const_string "false")))
134
135 (define_delay (and (eq_attr "type" "return")
136 (eq_attr "isa" "v9"))
137 [(eq_attr "in_return_delay" "true") (nil) (nil)])
138
139 ;; ??? Should implement the notion of predelay slots for floating point
140 ;; branches. This would allow us to remove the nop always inserted before
141 ;; a floating point branch.
142
143 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
144 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
145 ;; This is because doing so will add several pipeline stalls to the path
146 ;; that the load/store did not come from. Unfortunately, there is no way
147 ;; to prevent fill_eager_delay_slots from using load/store without completely
148 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
149 ;; because it prevents us from moving back the final store of inner loops.
150
151 (define_attr "in_branch_delay" "false,true"
152 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
153 (eq_attr "length" "1"))
154 (const_string "true")
155 (const_string "false")))
156
157 (define_attr "in_uncond_branch_delay" "false,true"
158 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
159 (eq_attr "length" "1"))
160 (const_string "true")
161 (const_string "false")))
162
163 (define_attr "in_annul_branch_delay" "false,true"
164 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
165 (eq_attr "length" "1"))
166 (const_string "true")
167 (const_string "false")))
168
169 (define_delay (eq_attr "type" "branch")
170 [(eq_attr "in_branch_delay" "true")
171 (nil) (eq_attr "in_annul_branch_delay" "true")])
172
173 (define_delay (eq_attr "type" "uncond_branch")
174 [(eq_attr "in_uncond_branch_delay" "true")
175 (nil) (nil)])
176
177 ;; Function units of the SPARC
178
179 ;; (define_function_unit {name} {num-units} {n-users} {test}
180 ;; {ready-delay} {issue-delay} [{conflict-list}])
181
182 ;; The integer ALU.
183 ;; (Noted only for documentation; units that take one cycle do not need to
184 ;; be specified.)
185
186 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
187 ;; the inputs.
188
189 ;; ---- cypress CY7C602 scheduling:
190 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
191
192 (define_function_unit "memory" 1 0
193 (and (eq_attr "cpu" "cypress")
194 (eq_attr "type" "load,sload,fpload"))
195 2 2)
196
197 ;; SPARC has two floating-point units: the FP ALU,
198 ;; and the FP MUL/DIV/SQRT unit.
199 ;; Instruction timings on the CY7C602 are as follows
200 ;; FABSs 4
201 ;; FADDs/d 5/5
202 ;; FCMPs/d 4/4
203 ;; FDIVs/d 23/37
204 ;; FMOVs 4
205 ;; FMULs/d 5/7
206 ;; FNEGs 4
207 ;; FSQRTs/d 34/63
208 ;; FSUBs/d 5/5
209 ;; FdTOi/s 5/5
210 ;; FsTOi/d 5/5
211 ;; FiTOs/d 9/5
212
213 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
214 ;; More insns cause the chip to stall.
215
216 (define_function_unit "fp_alu" 1 0
217 (and (eq_attr "cpu" "cypress")
218 (eq_attr "type" "fp,fpmove"))
219 5 5)
220
221 (define_function_unit "fp_mds" 1 0
222 (and (eq_attr "cpu" "cypress")
223 (eq_attr "type" "fpmul"))
224 7 7)
225
226 (define_function_unit "fp_mds" 1 0
227 (and (eq_attr "cpu" "cypress")
228 (eq_attr "type" "fpdivs,fpdivd"))
229 37 37)
230
231 (define_function_unit "fp_mds" 1 0
232 (and (eq_attr "cpu" "cypress")
233 (eq_attr "type" "fpsqrts,fpsqrtd"))
234 63 63)
235
236 ;; ----- The TMS390Z55 scheduling
237 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
238 ;; one ld/st, one fp.
239 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
240
241 (define_function_unit "memory" 1 0
242 (and (eq_attr "cpu" "supersparc")
243 (eq_attr "type" "load,sload"))
244 1 1)
245
246 (define_function_unit "memory" 1 0
247 (and (eq_attr "cpu" "supersparc")
248 (eq_attr "type" "fpload"))
249 0 1)
250
251 (define_function_unit "memory" 1 0
252 (and (eq_attr "cpu" "supersparc")
253 (eq_attr "type" "store,fpstore"))
254 1 1)
255
256 (define_function_unit "shift" 1 0
257 (and (eq_attr "cpu" "supersparc")
258 (eq_attr "type" "shift"))
259 1 1)
260
261 ;; There are only two write ports to the integer register file
262 ;; A store also uses a write port
263
264 (define_function_unit "iwport" 2 0
265 (and (eq_attr "cpu" "supersparc")
266 (eq_attr "type" "load,sload,store,shift,ialu"))
267 1 1)
268
269 ;; Timings; throughput/latency
270 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
271 ;; FMUL 1/3
272 ;; FDIVs 4/6
273 ;; FDIVd 7/9
274 ;; FSQRTs 6/8
275 ;; FSQRTd 10/12
276 ;; IMUL 4/4
277
278 (define_function_unit "fp_alu" 1 0
279 (and (eq_attr "cpu" "supersparc")
280 (eq_attr "type" "fp,fpmove,fpcmp"))
281 3 1)
282
283 (define_function_unit "fp_mds" 1 0
284 (and (eq_attr "cpu" "supersparc")
285 (eq_attr "type" "fpmul"))
286 3 1)
287
288 (define_function_unit "fp_mds" 1 0
289 (and (eq_attr "cpu" "supersparc")
290 (eq_attr "type" "fpdivs"))
291 6 4)
292
293 (define_function_unit "fp_mds" 1 0
294 (and (eq_attr "cpu" "supersparc")
295 (eq_attr "type" "fpdivd"))
296 9 7)
297
298 (define_function_unit "fp_mds" 1 0
299 (and (eq_attr "cpu" "supersparc")
300 (eq_attr "type" "fpsqrts,fpsqrtd"))
301 12 10)
302
303 (define_function_unit "fp_mds" 1 0
304 (and (eq_attr "cpu" "supersparc")
305 (eq_attr "type" "imul"))
306 4 4)
307
308 ;; ----- hypersparc/sparclite86x scheduling
309 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
310 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
311 ;; II/FF case is only when loading a 32 bit hi/lo constant
312 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
313 ;; Memory delivers its result in one cycle to IU
314
315 (define_function_unit "memory" 1 0
316 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
317 (eq_attr "type" "load,sload,fpload"))
318 1 1)
319
320 (define_function_unit "memory" 1 0
321 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
322 (eq_attr "type" "store,fpstore"))
323 2 1)
324
325 (define_function_unit "sparclite86x_branch" 1 0
326 (and (eq_attr "cpu" "sparclite86x")
327 (eq_attr "type" "branch"))
328 1 1)
329
330 ;; integer multiply insns
331 (define_function_unit "sparclite86x_shift" 1 0
332 (and (eq_attr "cpu" "sparclite86x")
333 (eq_attr "type" "shift"))
334 1 1)
335
336 (define_function_unit "fp_alu" 1 0
337 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
338 (eq_attr "type" "fp,fpmove,fpcmp"))
339 1 1)
340
341 (define_function_unit "fp_mds" 1 0
342 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
343 (eq_attr "type" "fpmul"))
344 1 1)
345
346 (define_function_unit "fp_mds" 1 0
347 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
348 (eq_attr "type" "fpdivs"))
349 8 6)
350
351 (define_function_unit "fp_mds" 1 0
352 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
353 (eq_attr "type" "fpdivd"))
354 12 10)
355
356 (define_function_unit "fp_mds" 1 0
357 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
358 (eq_attr "type" "fpsqrts,fpsqrtd"))
359 17 15)
360
361 (define_function_unit "fp_mds" 1 0
362 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
363 (eq_attr "type" "imul"))
364 17 15)
365
366 ;; ----- sparclet tsc701 scheduling
367 ;; The tsc701 issues 1 insn per cycle.
368 ;; Results may be written back out of order.
369
370 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
371
372 (define_function_unit "tsc701_load" 4 1
373 (and (eq_attr "cpu" "tsc701")
374 (eq_attr "type" "load,sload"))
375 3 1)
376
377 ;; Stores take 2(?) extra cycles to complete.
378 ;; It is desirable to not have any memory operation in the following 2 cycles.
379 ;; (??? or 2 memory ops in the case of std).
380
381 (define_function_unit "tsc701_store" 1 0
382 (and (eq_attr "cpu" "tsc701")
383 (eq_attr "type" "store"))
384 3 3
385 [(eq_attr "type" "load,sload,store")])
386
387 ;; The multiply unit has a latency of 5.
388 (define_function_unit "tsc701_mul" 1 0
389 (and (eq_attr "cpu" "tsc701")
390 (eq_attr "type" "imul"))
391 5 5)
392
393 ;; ----- The UltraSPARC-1 scheduling
394 ;; UltraSPARC has two integer units. Shift instructions can only execute
395 ;; on IE0. Condition code setting instructions, call, and jmpl (including
396 ;; the ret and retl pseudo-instructions) can only execute on IE1.
397 ;; Branch on register uses IE1, but branch on condition code does not.
398 ;; Conditional moves take 2 cycles. No other instruction can issue in the
399 ;; same cycle as a conditional move.
400 ;; Multiply and divide take many cycles during which no other instructions
401 ;; can issue.
402 ;; Memory delivers its result in two cycles (except for signed loads,
403 ;; which take one cycle more). One memory instruction can be issued per
404 ;; cycle.
405
406 (define_function_unit "memory" 1 0
407 (and (eq_attr "cpu" "ultrasparc")
408 (eq_attr "type" "load,fpload"))
409 2 1)
410
411 (define_function_unit "memory" 1 0
412 (and (eq_attr "cpu" "ultrasparc")
413 (eq_attr "type" "sload"))
414 3 1)
415
416 (define_function_unit "memory" 1 0
417 (and (eq_attr "cpu" "ultrasparc")
418 (eq_attr "type" "store,fpstore"))
419 1 1)
420
421 (define_function_unit "ieuN" 2 0
422 (and (eq_attr "cpu" "ultrasparc")
423 (eq_attr "type" "ialu,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch"))
424 1 1)
425
426 (define_function_unit "ieu0" 1 0
427 (and (eq_attr "cpu" "ultrasparc")
428 (eq_attr "type" "shift"))
429 1 1)
430
431 (define_function_unit "ieu0" 1 0
432 (and (eq_attr "cpu" "ultrasparc")
433 (eq_attr "type" "cmove"))
434 2 1)
435
436 (define_function_unit "ieu1" 1 0
437 (and (eq_attr "cpu" "ultrasparc")
438 (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch"))
439 1 1)
440
441 (define_function_unit "cti" 1 0
442 (and (eq_attr "cpu" "ultrasparc")
443 (eq_attr "type" "branch"))
444 1 1)
445
446 ;; Timings; throughput/latency
447 ;; FMOV 1/1 fmov, fabs, fneg
448 ;; FMOVcc 1/2
449 ;; FADD 1/3 add/sub, format conv, compar
450 ;; FMUL 1/3
451 ;; FDIVs 12/12
452 ;; FDIVd 22/22
453 ;; FSQRTs 12/12
454 ;; FSQRTd 22/22
455 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
456 ;;
457 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
458 ;; use the FPM multiplier for final rounding 3 cycles before the
459 ;; end of their latency and we have no real way to model that.
460 ;;
461 ;; ??? This is really bogus because the timings really depend upon
462 ;; who uses the result. We should record who the user is with
463 ;; more descriptive 'type' attribute names and account for these
464 ;; issues in ultrasparc_adjust_cost.
465
466 (define_function_unit "fadd" 1 0
467 (and (eq_attr "cpu" "ultrasparc")
468 (eq_attr "type" "fpmove"))
469 1 1)
470
471 (define_function_unit "fadd" 1 0
472 (and (eq_attr "cpu" "ultrasparc")
473 (eq_attr "type" "fpcmove"))
474 2 1)
475
476 (define_function_unit "fadd" 1 0
477 (and (eq_attr "cpu" "ultrasparc")
478 (eq_attr "type" "fp"))
479 3 1)
480
481 (define_function_unit "fadd" 1 0
482 (and (eq_attr "cpu" "ultrasparc")
483 (eq_attr "type" "fpcmp"))
484 2 1)
485
486 (define_function_unit "fmul" 1 0
487 (and (eq_attr "cpu" "ultrasparc")
488 (eq_attr "type" "fpmul"))
489 3 1)
490
491 (define_function_unit "fadd" 1 0
492 (and (eq_attr "cpu" "ultrasparc")
493 (eq_attr "type" "fpcmove"))
494 2 1)
495
496 (define_function_unit "fdiv" 1 0
497 (and (eq_attr "cpu" "ultrasparc")
498 (eq_attr "type" "fpdivs"))
499 12 12)
500
501 (define_function_unit "fdiv" 1 0
502 (and (eq_attr "cpu" "ultrasparc")
503 (eq_attr "type" "fpdivd"))
504 22 22)
505
506 (define_function_unit "fdiv" 1 0
507 (and (eq_attr "cpu" "ultrasparc")
508 (eq_attr "type" "fpsqrts"))
509 12 12)
510
511 (define_function_unit "fdiv" 1 0
512 (and (eq_attr "cpu" "ultrasparc")
513 (eq_attr "type" "fpsqrtd"))
514 22 22)
515 \f
516 ;; Compare instructions.
517 ;; This controls RTL generation and register allocation.
518
519 ;; We generate RTL for comparisons and branches by having the cmpxx
520 ;; patterns store away the operands. Then, the scc and bcc patterns
521 ;; emit RTL for both the compare and the branch.
522 ;;
523 ;; We do this because we want to generate different code for an sne and
524 ;; seq insn. In those cases, if the second operand of the compare is not
525 ;; const0_rtx, we want to compute the xor of the two operands and test
526 ;; it against zero.
527 ;;
528 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
529 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
530 ;; insns that actually require more than one machine instruction.
531
532 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
533
534 (define_expand "cmpsi"
535 [(set (reg:CC 100)
536 (compare:CC (match_operand:SI 0 "register_operand" "")
537 (match_operand:SI 1 "arith_operand" "")))]
538 ""
539 "
540 {
541 sparc_compare_op0 = operands[0];
542 sparc_compare_op1 = operands[1];
543 DONE;
544 }")
545
546 (define_expand "cmpdi"
547 [(set (reg:CCX 100)
548 (compare:CCX (match_operand:DI 0 "register_operand" "")
549 (match_operand:DI 1 "arith_double_operand" "")))]
550 "TARGET_ARCH64"
551 "
552 {
553 sparc_compare_op0 = operands[0];
554 sparc_compare_op1 = operands[1];
555 DONE;
556 }")
557
558 (define_expand "cmpsf"
559 ;; The 96 here isn't ever used by anyone.
560 [(set (reg:CCFP 96)
561 (compare:CCFP (match_operand:SF 0 "register_operand" "")
562 (match_operand:SF 1 "register_operand" "")))]
563 "TARGET_FPU"
564 "
565 {
566 sparc_compare_op0 = operands[0];
567 sparc_compare_op1 = operands[1];
568 DONE;
569 }")
570
571 (define_expand "cmpdf"
572 ;; The 96 here isn't ever used by anyone.
573 [(set (reg:CCFP 96)
574 (compare:CCFP (match_operand:DF 0 "register_operand" "")
575 (match_operand:DF 1 "register_operand" "")))]
576 "TARGET_FPU"
577 "
578 {
579 sparc_compare_op0 = operands[0];
580 sparc_compare_op1 = operands[1];
581 DONE;
582 }")
583
584 (define_expand "cmptf"
585 ;; The 96 here isn't ever used by anyone.
586 [(set (reg:CCFP 96)
587 (compare:CCFP (match_operand:TF 0 "register_operand" "")
588 (match_operand:TF 1 "register_operand" "")))]
589 "TARGET_FPU"
590 "
591 {
592 sparc_compare_op0 = operands[0];
593 sparc_compare_op1 = operands[1];
594 DONE;
595 }")
596
597 ;; Now the compare DEFINE_INSNs.
598
599 (define_insn "*cmpsi_insn"
600 [(set (reg:CC 100)
601 (compare:CC (match_operand:SI 0 "register_operand" "r")
602 (match_operand:SI 1 "arith_operand" "rI")))]
603 ""
604 "cmp\\t%0, %1"
605 [(set_attr "type" "compare")])
606
607 (define_insn "*cmpdi_sp64"
608 [(set (reg:CCX 100)
609 (compare:CCX (match_operand:DI 0 "register_operand" "r")
610 (match_operand:DI 1 "arith_double_operand" "rHI")))]
611 "TARGET_ARCH64"
612 "cmp\\t%0, %1"
613 [(set_attr "type" "compare")])
614
615 (define_insn "*cmpsf_fpe"
616 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
617 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
618 (match_operand:SF 2 "register_operand" "f")))]
619 "TARGET_FPU"
620 "*
621 {
622 if (TARGET_V9)
623 return \"fcmpes\\t%0, %1, %2\";
624 return \"fcmpes\\t%1, %2\";
625 }"
626 [(set_attr "type" "fpcmp")])
627
628 (define_insn "*cmpdf_fpe"
629 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
630 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
631 (match_operand:DF 2 "register_operand" "e")))]
632 "TARGET_FPU"
633 "*
634 {
635 if (TARGET_V9)
636 return \"fcmped\\t%0, %1, %2\";
637 return \"fcmped\\t%1, %2\";
638 }"
639 [(set_attr "type" "fpcmp")
640 (set_attr "fptype" "double")])
641
642 (define_insn "*cmptf_fpe"
643 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
644 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
645 (match_operand:TF 2 "register_operand" "e")))]
646 "TARGET_FPU && TARGET_HARD_QUAD"
647 "*
648 {
649 if (TARGET_V9)
650 return \"fcmpeq\\t%0, %1, %2\";
651 return \"fcmpeq\\t%1, %2\";
652 }"
653 [(set_attr "type" "fpcmp")])
654
655 (define_insn "*cmpsf_fp"
656 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
657 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
658 (match_operand:SF 2 "register_operand" "f")))]
659 "TARGET_FPU"
660 "*
661 {
662 if (TARGET_V9)
663 return \"fcmps\\t%0, %1, %2\";
664 return \"fcmps\\t%1, %2\";
665 }"
666 [(set_attr "type" "fpcmp")])
667
668 (define_insn "*cmpdf_fp"
669 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
670 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
671 (match_operand:DF 2 "register_operand" "e")))]
672 "TARGET_FPU"
673 "*
674 {
675 if (TARGET_V9)
676 return \"fcmpd\\t%0, %1, %2\";
677 return \"fcmpd\\t%1, %2\";
678 }"
679 [(set_attr "type" "fpcmp")
680 (set_attr "fptype" "double")])
681
682 (define_insn "*cmptf_fp"
683 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
684 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
685 (match_operand:TF 2 "register_operand" "e")))]
686 "TARGET_FPU && TARGET_HARD_QUAD"
687 "*
688 {
689 if (TARGET_V9)
690 return \"fcmpq\\t%0, %1, %2\";
691 return \"fcmpq\\t%1, %2\";
692 }"
693 [(set_attr "type" "fpcmp")])
694 \f
695 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
696 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
697 ;; the same code as v8 (the addx/subx method has more applications). The
698 ;; exception to this is "reg != 0" which can be done in one instruction on v9
699 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
700 ;; branches.
701
702 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
703 ;; generate addcc/subcc instructions.
704
705 (define_expand "seqsi_special"
706 [(set (match_dup 3)
707 (xor:SI (match_operand:SI 1 "register_operand" "")
708 (match_operand:SI 2 "register_operand" "")))
709 (parallel [(set (match_operand:SI 0 "register_operand" "")
710 (eq:SI (match_dup 3) (const_int 0)))
711 (clobber (reg:CC 100))])]
712 ""
713 "{ operands[3] = gen_reg_rtx (SImode); }")
714
715 (define_expand "seqdi_special"
716 [(set (match_dup 3)
717 (xor:DI (match_operand:DI 1 "register_operand" "")
718 (match_operand:DI 2 "register_operand" "")))
719 (set (match_operand:DI 0 "register_operand" "")
720 (eq:DI (match_dup 3) (const_int 0)))]
721 "TARGET_ARCH64"
722 "{ operands[3] = gen_reg_rtx (DImode); }")
723
724 (define_expand "snesi_special"
725 [(set (match_dup 3)
726 (xor:SI (match_operand:SI 1 "register_operand" "")
727 (match_operand:SI 2 "register_operand" "")))
728 (parallel [(set (match_operand:SI 0 "register_operand" "")
729 (ne:SI (match_dup 3) (const_int 0)))
730 (clobber (reg:CC 100))])]
731 ""
732 "{ operands[3] = gen_reg_rtx (SImode); }")
733
734 (define_expand "snedi_special"
735 [(set (match_dup 3)
736 (xor:DI (match_operand:DI 1 "register_operand" "")
737 (match_operand:DI 2 "register_operand" "")))
738 (set (match_operand:DI 0 "register_operand" "")
739 (ne:DI (match_dup 3) (const_int 0)))]
740 "TARGET_ARCH64"
741 "{ operands[3] = gen_reg_rtx (DImode); }")
742
743 (define_expand "seqdi_special_trunc"
744 [(set (match_dup 3)
745 (xor:DI (match_operand:DI 1 "register_operand" "")
746 (match_operand:DI 2 "register_operand" "")))
747 (set (match_operand:SI 0 "register_operand" "")
748 (eq:SI (match_dup 3) (const_int 0)))]
749 "TARGET_ARCH64"
750 "{ operands[3] = gen_reg_rtx (DImode); }")
751
752 (define_expand "snedi_special_trunc"
753 [(set (match_dup 3)
754 (xor:DI (match_operand:DI 1 "register_operand" "")
755 (match_operand:DI 2 "register_operand" "")))
756 (set (match_operand:SI 0 "register_operand" "")
757 (ne:SI (match_dup 3) (const_int 0)))]
758 "TARGET_ARCH64"
759 "{ operands[3] = gen_reg_rtx (DImode); }")
760
761 (define_expand "seqsi_special_extend"
762 [(set (match_dup 3)
763 (xor:SI (match_operand:SI 1 "register_operand" "")
764 (match_operand:SI 2 "register_operand" "")))
765 (parallel [(set (match_operand:DI 0 "register_operand" "")
766 (eq:DI (match_dup 3) (const_int 0)))
767 (clobber (reg:CC 100))])]
768 "TARGET_ARCH64"
769 "{ operands[3] = gen_reg_rtx (SImode); }")
770
771 (define_expand "snesi_special_extend"
772 [(set (match_dup 3)
773 (xor:SI (match_operand:SI 1 "register_operand" "")
774 (match_operand:SI 2 "register_operand" "")))
775 (parallel [(set (match_operand:DI 0 "register_operand" "")
776 (ne:DI (match_dup 3) (const_int 0)))
777 (clobber (reg:CC 100))])]
778 "TARGET_ARCH64"
779 "{ operands[3] = gen_reg_rtx (SImode); }")
780
781 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
782 ;; However, the code handles both SImode and DImode.
783 (define_expand "seq"
784 [(set (match_operand:SI 0 "intreg_operand" "")
785 (eq:SI (match_dup 1) (const_int 0)))]
786 ""
787 "
788 {
789 if (GET_MODE (sparc_compare_op0) == SImode)
790 {
791 rtx pat;
792
793 if (GET_MODE (operands[0]) == SImode)
794 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
795 sparc_compare_op1);
796 else if (! TARGET_ARCH64)
797 FAIL;
798 else
799 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
800 sparc_compare_op1);
801 emit_insn (pat);
802 DONE;
803 }
804 else if (GET_MODE (sparc_compare_op0) == DImode)
805 {
806 rtx pat;
807
808 if (! TARGET_ARCH64)
809 FAIL;
810 else if (GET_MODE (operands[0]) == SImode)
811 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
812 sparc_compare_op1);
813 else
814 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
815 sparc_compare_op1);
816 emit_insn (pat);
817 DONE;
818 }
819 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
820 {
821 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
822 emit_jump_insn (gen_sne (operands[0]));
823 DONE;
824 }
825 else if (TARGET_V9)
826 {
827 if (gen_v9_scc (EQ, operands))
828 DONE;
829 /* fall through */
830 }
831 FAIL;
832 }")
833
834 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
835 ;; However, the code handles both SImode and DImode.
836 (define_expand "sne"
837 [(set (match_operand:SI 0 "intreg_operand" "")
838 (ne:SI (match_dup 1) (const_int 0)))]
839 ""
840 "
841 {
842 if (GET_MODE (sparc_compare_op0) == SImode)
843 {
844 rtx pat;
845
846 if (GET_MODE (operands[0]) == SImode)
847 pat = gen_snesi_special (operands[0], sparc_compare_op0,
848 sparc_compare_op1);
849 else if (! TARGET_ARCH64)
850 FAIL;
851 else
852 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
853 sparc_compare_op1);
854 emit_insn (pat);
855 DONE;
856 }
857 else if (GET_MODE (sparc_compare_op0) == DImode)
858 {
859 rtx pat;
860
861 if (! TARGET_ARCH64)
862 FAIL;
863 else if (GET_MODE (operands[0]) == SImode)
864 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
865 sparc_compare_op1);
866 else
867 pat = gen_snedi_special (operands[0], sparc_compare_op0,
868 sparc_compare_op1);
869 emit_insn (pat);
870 DONE;
871 }
872 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
873 {
874 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
875 emit_jump_insn (gen_sne (operands[0]));
876 DONE;
877 }
878 else if (TARGET_V9)
879 {
880 if (gen_v9_scc (NE, operands))
881 DONE;
882 /* fall through */
883 }
884 FAIL;
885 }")
886
887 (define_expand "sgt"
888 [(set (match_operand:SI 0 "intreg_operand" "")
889 (gt:SI (match_dup 1) (const_int 0)))]
890 ""
891 "
892 {
893 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
894 {
895 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
896 emit_jump_insn (gen_sne (operands[0]));
897 DONE;
898 }
899 else if (TARGET_V9)
900 {
901 if (gen_v9_scc (GT, operands))
902 DONE;
903 /* fall through */
904 }
905 FAIL;
906 }")
907
908 (define_expand "slt"
909 [(set (match_operand:SI 0 "intreg_operand" "")
910 (lt:SI (match_dup 1) (const_int 0)))]
911 ""
912 "
913 {
914 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
915 {
916 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
917 emit_jump_insn (gen_sne (operands[0]));
918 DONE;
919 }
920 else if (TARGET_V9)
921 {
922 if (gen_v9_scc (LT, operands))
923 DONE;
924 /* fall through */
925 }
926 FAIL;
927 }")
928
929 (define_expand "sge"
930 [(set (match_operand:SI 0 "intreg_operand" "")
931 (ge:SI (match_dup 1) (const_int 0)))]
932 ""
933 "
934 {
935 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
936 {
937 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
938 emit_jump_insn (gen_sne (operands[0]));
939 DONE;
940 }
941 else if (TARGET_V9)
942 {
943 if (gen_v9_scc (GE, operands))
944 DONE;
945 /* fall through */
946 }
947 FAIL;
948 }")
949
950 (define_expand "sle"
951 [(set (match_operand:SI 0 "intreg_operand" "")
952 (le:SI (match_dup 1) (const_int 0)))]
953 ""
954 "
955 {
956 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
957 {
958 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
959 emit_jump_insn (gen_sne (operands[0]));
960 DONE;
961 }
962 else if (TARGET_V9)
963 {
964 if (gen_v9_scc (LE, operands))
965 DONE;
966 /* fall through */
967 }
968 FAIL;
969 }")
970
971 (define_expand "sgtu"
972 [(set (match_operand:SI 0 "intreg_operand" "")
973 (gtu:SI (match_dup 1) (const_int 0)))]
974 ""
975 "
976 {
977 if (! TARGET_V9)
978 {
979 rtx tem, pat;
980
981 /* We can do ltu easily, so if both operands are registers, swap them and
982 do a LTU. */
983 if ((GET_CODE (sparc_compare_op0) == REG
984 || GET_CODE (sparc_compare_op0) == SUBREG)
985 && (GET_CODE (sparc_compare_op1) == REG
986 || GET_CODE (sparc_compare_op1) == SUBREG))
987 {
988 tem = sparc_compare_op0;
989 sparc_compare_op0 = sparc_compare_op1;
990 sparc_compare_op1 = tem;
991 pat = gen_sltu (operands[0]);
992 if (pat == NULL_RTX)
993 FAIL;
994 emit_insn (pat);
995 DONE;
996 }
997 }
998 else
999 {
1000 if (gen_v9_scc (GTU, operands))
1001 DONE;
1002 }
1003 FAIL;
1004 }")
1005
1006 (define_expand "sltu"
1007 [(set (match_operand:SI 0 "intreg_operand" "")
1008 (ltu:SI (match_dup 1) (const_int 0)))]
1009 ""
1010 "
1011 {
1012 if (TARGET_V9)
1013 {
1014 if (gen_v9_scc (LTU, operands))
1015 DONE;
1016 }
1017 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1018 }")
1019
1020 (define_expand "sgeu"
1021 [(set (match_operand:SI 0 "intreg_operand" "")
1022 (geu:SI (match_dup 1) (const_int 0)))]
1023 ""
1024 "
1025 {
1026 if (TARGET_V9)
1027 {
1028 if (gen_v9_scc (GEU, operands))
1029 DONE;
1030 }
1031 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1032 }")
1033
1034 (define_expand "sleu"
1035 [(set (match_operand:SI 0 "intreg_operand" "")
1036 (leu:SI (match_dup 1) (const_int 0)))]
1037 ""
1038 "
1039 {
1040 if (! TARGET_V9)
1041 {
1042 rtx tem, pat;
1043
1044 /* We can do geu easily, so if both operands are registers, swap them and
1045 do a GEU. */
1046 if ((GET_CODE (sparc_compare_op0) == REG
1047 || GET_CODE (sparc_compare_op0) == SUBREG)
1048 && (GET_CODE (sparc_compare_op1) == REG
1049 || GET_CODE (sparc_compare_op1) == SUBREG))
1050 {
1051 tem = sparc_compare_op0;
1052 sparc_compare_op0 = sparc_compare_op1;
1053 sparc_compare_op1 = tem;
1054 pat = gen_sgeu (operands[0]);
1055 if (pat == NULL_RTX)
1056 FAIL;
1057 emit_insn (pat);
1058 DONE;
1059 }
1060 }
1061 else
1062 {
1063 if (gen_v9_scc (LEU, operands))
1064 DONE;
1065 }
1066 FAIL;
1067 }")
1068
1069 ;; Now the DEFINE_INSNs for the scc cases.
1070
1071 ;; The SEQ and SNE patterns are special because they can be done
1072 ;; without any branching and do not involve a COMPARE. We want
1073 ;; them to always use the splitz below so the results can be
1074 ;; scheduled.
1075
1076 (define_insn "*snesi_zero"
1077 [(set (match_operand:SI 0 "register_operand" "=r")
1078 (ne:SI (match_operand:SI 1 "register_operand" "r")
1079 (const_int 0)))
1080 (clobber (reg:CC 100))]
1081 ""
1082 "#"
1083 [(set_attr "length" "2")])
1084
1085 (define_split
1086 [(set (match_operand:SI 0 "register_operand" "")
1087 (ne:SI (match_operand:SI 1 "register_operand" "")
1088 (const_int 0)))
1089 (clobber (reg:CC 100))]
1090 ""
1091 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1092 (const_int 0)))
1093 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1094 "")
1095
1096 (define_insn "*neg_snesi_zero"
1097 [(set (match_operand:SI 0 "register_operand" "=r")
1098 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1099 (const_int 0))))
1100 (clobber (reg:CC 100))]
1101 ""
1102 "#"
1103 [(set_attr "length" "2")])
1104
1105 (define_split
1106 [(set (match_operand:SI 0 "register_operand" "")
1107 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1108 (const_int 0))))
1109 (clobber (reg:CC 100))]
1110 ""
1111 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1112 (const_int 0)))
1113 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1114 "")
1115
1116 (define_insn "*snesi_zero_extend"
1117 [(set (match_operand:DI 0 "register_operand" "=r")
1118 (ne:DI (match_operand:SI 1 "register_operand" "r")
1119 (const_int 0)))
1120 (clobber (reg:CC 100))]
1121 "TARGET_ARCH64"
1122 "#"
1123 [(set_attr "length" "2")])
1124
1125 (define_split
1126 [(set (match_operand:DI 0 "register_operand" "")
1127 (ne:DI (match_operand:SI 1 "register_operand" "")
1128 (const_int 0)))
1129 (clobber (reg:CC 100))]
1130 "TARGET_ARCH64"
1131 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1132 (const_int 0)))
1133 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1134 (const_int 0))
1135 (ltu:SI (reg:CC_NOOV 100)
1136 (const_int 0)))))]
1137 "")
1138
1139 (define_insn "*snedi_zero"
1140 [(set (match_operand:DI 0 "register_operand" "=&r")
1141 (ne:DI (match_operand:DI 1 "register_operand" "r")
1142 (const_int 0)))]
1143 "TARGET_ARCH64"
1144 "#"
1145 [(set_attr "length" "2")])
1146
1147 (define_split
1148 [(set (match_operand:DI 0 "register_operand" "")
1149 (ne:DI (match_operand:DI 1 "register_operand" "")
1150 (const_int 0)))]
1151 "TARGET_ARCH64
1152 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1153 [(set (match_dup 0) (const_int 0))
1154 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1155 (const_int 0))
1156 (const_int 1)
1157 (match_dup 0)))]
1158 "")
1159
1160 (define_insn "*neg_snedi_zero"
1161 [(set (match_operand:DI 0 "register_operand" "=&r")
1162 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1163 (const_int 0))))]
1164 "TARGET_ARCH64"
1165 "#"
1166 [(set_attr "length" "2")])
1167
1168 (define_split
1169 [(set (match_operand:DI 0 "register_operand" "")
1170 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1171 (const_int 0))))]
1172 "TARGET_ARCH64
1173 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1174 [(set (match_dup 0) (const_int 0))
1175 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1176 (const_int 0))
1177 (const_int -1)
1178 (match_dup 0)))]
1179 "")
1180
1181 (define_insn "*snedi_zero_trunc"
1182 [(set (match_operand:SI 0 "register_operand" "=&r")
1183 (ne:SI (match_operand:DI 1 "register_operand" "r")
1184 (const_int 0)))]
1185 "TARGET_ARCH64"
1186 "#"
1187 [(set_attr "length" "2")])
1188
1189 (define_split
1190 [(set (match_operand:SI 0 "register_operand" "")
1191 (ne:SI (match_operand:DI 1 "register_operand" "")
1192 (const_int 0)))]
1193 "TARGET_ARCH64
1194 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1195 [(set (match_dup 0) (const_int 0))
1196 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1197 (const_int 0))
1198 (const_int 1)
1199 (match_dup 0)))]
1200 "")
1201
1202 (define_insn "*seqsi_zero"
1203 [(set (match_operand:SI 0 "register_operand" "=r")
1204 (eq:SI (match_operand:SI 1 "register_operand" "r")
1205 (const_int 0)))
1206 (clobber (reg:CC 100))]
1207 ""
1208 "#"
1209 [(set_attr "length" "2")])
1210
1211 (define_split
1212 [(set (match_operand:SI 0 "register_operand" "")
1213 (eq:SI (match_operand:SI 1 "register_operand" "")
1214 (const_int 0)))
1215 (clobber (reg:CC 100))]
1216 ""
1217 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1218 (const_int 0)))
1219 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1220 "")
1221
1222 (define_insn "*neg_seqsi_zero"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1224 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1225 (const_int 0))))
1226 (clobber (reg:CC 100))]
1227 ""
1228 "#"
1229 [(set_attr "length" "2")])
1230
1231 (define_split
1232 [(set (match_operand:SI 0 "register_operand" "")
1233 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1234 (const_int 0))))
1235 (clobber (reg:CC 100))]
1236 ""
1237 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1238 (const_int 0)))
1239 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1240 "")
1241
1242 (define_insn "*seqsi_zero_extend"
1243 [(set (match_operand:DI 0 "register_operand" "=r")
1244 (eq:DI (match_operand:SI 1 "register_operand" "r")
1245 (const_int 0)))
1246 (clobber (reg:CC 100))]
1247 "TARGET_ARCH64"
1248 "#"
1249 [(set_attr "length" "2")])
1250
1251 (define_split
1252 [(set (match_operand:DI 0 "register_operand" "")
1253 (eq:DI (match_operand:SI 1 "register_operand" "")
1254 (const_int 0)))
1255 (clobber (reg:CC 100))]
1256 "TARGET_ARCH64"
1257 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1258 (const_int 0)))
1259 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1260 (const_int -1))
1261 (ltu:SI (reg:CC_NOOV 100)
1262 (const_int 0)))))]
1263 "")
1264
1265 (define_insn "*seqdi_zero"
1266 [(set (match_operand:DI 0 "register_operand" "=&r")
1267 (eq:DI (match_operand:DI 1 "register_operand" "r")
1268 (const_int 0)))]
1269 "TARGET_ARCH64"
1270 "#"
1271 [(set_attr "length" "2")])
1272
1273 (define_split
1274 [(set (match_operand:DI 0 "register_operand" "")
1275 (eq:DI (match_operand:DI 1 "register_operand" "")
1276 (const_int 0)))]
1277 "TARGET_ARCH64
1278 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1279 [(set (match_dup 0) (const_int 0))
1280 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1281 (const_int 0))
1282 (const_int 1)
1283 (match_dup 0)))]
1284 "")
1285
1286 (define_insn "*neg_seqdi_zero"
1287 [(set (match_operand:DI 0 "register_operand" "=&r")
1288 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1289 (const_int 0))))]
1290 "TARGET_ARCH64"
1291 "#"
1292 [(set_attr "length" "2")])
1293
1294 (define_split
1295 [(set (match_operand:DI 0 "register_operand" "")
1296 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1297 (const_int 0))))]
1298 "TARGET_ARCH64
1299 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1300 [(set (match_dup 0) (const_int 0))
1301 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1302 (const_int 0))
1303 (const_int -1)
1304 (match_dup 0)))]
1305 "")
1306
1307 (define_insn "*seqdi_zero_trunc"
1308 [(set (match_operand:SI 0 "register_operand" "=&r")
1309 (eq:SI (match_operand:DI 1 "register_operand" "r")
1310 (const_int 0)))]
1311 "TARGET_ARCH64"
1312 "#"
1313 [(set_attr "length" "2")])
1314
1315 (define_split
1316 [(set (match_operand:SI 0 "register_operand" "")
1317 (eq:SI (match_operand:DI 1 "register_operand" "")
1318 (const_int 0)))]
1319 "TARGET_ARCH64
1320 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1321 [(set (match_dup 0) (const_int 0))
1322 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1323 (const_int 0))
1324 (const_int 1)
1325 (match_dup 0)))]
1326 "")
1327
1328 ;; We can also do (x + (i == 0)) and related, so put them in.
1329 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1330 ;; versions for v9.
1331
1332 (define_insn "*x_plus_i_ne_0"
1333 [(set (match_operand:SI 0 "register_operand" "=r")
1334 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1335 (const_int 0))
1336 (match_operand:SI 2 "register_operand" "r")))
1337 (clobber (reg:CC 100))]
1338 ""
1339 "#"
1340 [(set_attr "length" "2")])
1341
1342 (define_split
1343 [(set (match_operand:SI 0 "register_operand" "")
1344 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1345 (const_int 0))
1346 (match_operand:SI 2 "register_operand" "")))
1347 (clobber (reg:CC 100))]
1348 ""
1349 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1350 (const_int 0)))
1351 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1352 (match_dup 2)))]
1353 "")
1354
1355 (define_insn "*x_minus_i_ne_0"
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (minus:SI (match_operand:SI 2 "register_operand" "r")
1358 (ne:SI (match_operand:SI 1 "register_operand" "r")
1359 (const_int 0))))
1360 (clobber (reg:CC 100))]
1361 ""
1362 "#"
1363 [(set_attr "length" "2")])
1364
1365 (define_split
1366 [(set (match_operand:SI 0 "register_operand" "")
1367 (minus:SI (match_operand:SI 2 "register_operand" "")
1368 (ne:SI (match_operand:SI 1 "register_operand" "")
1369 (const_int 0))))
1370 (clobber (reg:CC 100))]
1371 ""
1372 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1373 (const_int 0)))
1374 (set (match_dup 0) (minus:SI (match_dup 2)
1375 (ltu:SI (reg:CC 100) (const_int 0))))]
1376 "")
1377
1378 (define_insn "*x_plus_i_eq_0"
1379 [(set (match_operand:SI 0 "register_operand" "=r")
1380 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1381 (const_int 0))
1382 (match_operand:SI 2 "register_operand" "r")))
1383 (clobber (reg:CC 100))]
1384 ""
1385 "#"
1386 [(set_attr "length" "2")])
1387
1388 (define_split
1389 [(set (match_operand:SI 0 "register_operand" "")
1390 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1391 (const_int 0))
1392 (match_operand:SI 2 "register_operand" "")))
1393 (clobber (reg:CC 100))]
1394 ""
1395 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1396 (const_int 0)))
1397 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1398 (match_dup 2)))]
1399 "")
1400
1401 (define_insn "*x_minus_i_eq_0"
1402 [(set (match_operand:SI 0 "register_operand" "=r")
1403 (minus:SI (match_operand:SI 2 "register_operand" "r")
1404 (eq:SI (match_operand:SI 1 "register_operand" "r")
1405 (const_int 0))))
1406 (clobber (reg:CC 100))]
1407 ""
1408 "#"
1409 [(set_attr "length" "2")])
1410
1411 (define_split
1412 [(set (match_operand:SI 0 "register_operand" "")
1413 (minus:SI (match_operand:SI 2 "register_operand" "")
1414 (eq:SI (match_operand:SI 1 "register_operand" "")
1415 (const_int 0))))
1416 (clobber (reg:CC 100))]
1417 ""
1418 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1419 (const_int 0)))
1420 (set (match_dup 0) (minus:SI (match_dup 2)
1421 (geu:SI (reg:CC 100) (const_int 0))))]
1422 "")
1423
1424 ;; We can also do GEU and LTU directly, but these operate after a compare.
1425 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1426 ;; versions for v9.
1427
1428 (define_insn "*sltu_insn"
1429 [(set (match_operand:SI 0 "register_operand" "=r")
1430 (ltu:SI (reg:CC 100) (const_int 0)))]
1431 ""
1432 "addx\\t%%g0, 0, %0"
1433 [(set_attr "type" "misc")])
1434
1435 (define_insn "*neg_sltu_insn"
1436 [(set (match_operand:SI 0 "register_operand" "=r")
1437 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1438 ""
1439 "subx\\t%%g0, 0, %0"
1440 [(set_attr "type" "misc")])
1441
1442 ;; ??? Combine should canonicalize these next two to the same pattern.
1443 (define_insn "*neg_sltu_minus_x"
1444 [(set (match_operand:SI 0 "register_operand" "=r")
1445 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1446 (match_operand:SI 1 "arith_operand" "rI")))]
1447 ""
1448 "subx\\t%%g0, %1, %0"
1449 [(set_attr "type" "misc")])
1450
1451 (define_insn "*neg_sltu_plus_x"
1452 [(set (match_operand:SI 0 "register_operand" "=r")
1453 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1454 (match_operand:SI 1 "arith_operand" "rI"))))]
1455 ""
1456 "subx\\t%%g0, %1, %0"
1457 [(set_attr "type" "misc")])
1458
1459 (define_insn "*sgeu_insn"
1460 [(set (match_operand:SI 0 "register_operand" "=r")
1461 (geu:SI (reg:CC 100) (const_int 0)))]
1462 ""
1463 "subx\\t%%g0, -1, %0"
1464 [(set_attr "type" "misc")])
1465
1466 (define_insn "*neg_sgeu_insn"
1467 [(set (match_operand:SI 0 "register_operand" "=r")
1468 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1469 ""
1470 "addx\\t%%g0, -1, %0"
1471 [(set_attr "type" "misc")])
1472
1473 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1474 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1475 ;; versions for v9.
1476
1477 (define_insn "*sltu_plus_x"
1478 [(set (match_operand:SI 0 "register_operand" "=r")
1479 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1480 (match_operand:SI 1 "arith_operand" "rI")))]
1481 ""
1482 "addx\\t%%g0, %1, %0"
1483 [(set_attr "type" "misc")])
1484
1485 (define_insn "*sltu_plus_x_plus_y"
1486 [(set (match_operand:SI 0 "register_operand" "=r")
1487 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1488 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1489 (match_operand:SI 2 "arith_operand" "rI"))))]
1490 ""
1491 "addx\\t%1, %2, %0"
1492 [(set_attr "type" "misc")])
1493
1494 (define_insn "*x_minus_sltu"
1495 [(set (match_operand:SI 0 "register_operand" "=r")
1496 (minus:SI (match_operand:SI 1 "register_operand" "r")
1497 (ltu:SI (reg:CC 100) (const_int 0))))]
1498 ""
1499 "subx\\t%1, 0, %0"
1500 [(set_attr "type" "misc")])
1501
1502 ;; ??? Combine should canonicalize these next two to the same pattern.
1503 (define_insn "*x_minus_y_minus_sltu"
1504 [(set (match_operand:SI 0 "register_operand" "=r")
1505 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1506 (match_operand:SI 2 "arith_operand" "rI"))
1507 (ltu:SI (reg:CC 100) (const_int 0))))]
1508 ""
1509 "subx\\t%r1, %2, %0"
1510 [(set_attr "type" "misc")])
1511
1512 (define_insn "*x_minus_sltu_plus_y"
1513 [(set (match_operand:SI 0 "register_operand" "=r")
1514 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1515 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1516 (match_operand:SI 2 "arith_operand" "rI"))))]
1517 ""
1518 "subx\\t%r1, %2, %0"
1519 [(set_attr "type" "misc")])
1520
1521 (define_insn "*sgeu_plus_x"
1522 [(set (match_operand:SI 0 "register_operand" "=r")
1523 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1524 (match_operand:SI 1 "register_operand" "r")))]
1525 ""
1526 "subx\\t%1, -1, %0"
1527 [(set_attr "type" "misc")])
1528
1529 (define_insn "*x_minus_sgeu"
1530 [(set (match_operand:SI 0 "register_operand" "=r")
1531 (minus:SI (match_operand:SI 1 "register_operand" "r")
1532 (geu:SI (reg:CC 100) (const_int 0))))]
1533 ""
1534 "addx\\t%1, -1, %0"
1535 [(set_attr "type" "misc")])
1536
1537 (define_split
1538 [(set (match_operand:SI 0 "register_operand" "")
1539 (match_operator:SI 2 "noov_compare_op"
1540 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1541 (const_int 0)]))]
1542 ;; 32 bit LTU/GEU are better implemented using addx/subx
1543 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1544 && (GET_MODE (operands[1]) == CCXmode
1545 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1546 [(set (match_dup 0) (const_int 0))
1547 (set (match_dup 0)
1548 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1549 (const_int 1)
1550 (match_dup 0)))]
1551 "")
1552
1553 \f
1554 ;; These control RTL generation for conditional jump insns
1555
1556 ;; The quad-word fp compare library routines all return nonzero to indicate
1557 ;; true, which is different from the equivalent libgcc routines, so we must
1558 ;; handle them specially here.
1559
1560 (define_expand "beq"
1561 [(set (pc)
1562 (if_then_else (eq (match_dup 1) (const_int 0))
1563 (label_ref (match_operand 0 "" ""))
1564 (pc)))]
1565 ""
1566 "
1567 {
1568 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1569 && GET_CODE (sparc_compare_op0) == REG
1570 && GET_MODE (sparc_compare_op0) == DImode)
1571 {
1572 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1573 DONE;
1574 }
1575 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1576 {
1577 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1578 emit_jump_insn (gen_bne (operands[0]));
1579 DONE;
1580 }
1581 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1582 }")
1583
1584 (define_expand "bne"
1585 [(set (pc)
1586 (if_then_else (ne (match_dup 1) (const_int 0))
1587 (label_ref (match_operand 0 "" ""))
1588 (pc)))]
1589 ""
1590 "
1591 {
1592 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1593 && GET_CODE (sparc_compare_op0) == REG
1594 && GET_MODE (sparc_compare_op0) == DImode)
1595 {
1596 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1597 DONE;
1598 }
1599 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1600 {
1601 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1602 emit_jump_insn (gen_bne (operands[0]));
1603 DONE;
1604 }
1605 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1606 }")
1607
1608 (define_expand "bgt"
1609 [(set (pc)
1610 (if_then_else (gt (match_dup 1) (const_int 0))
1611 (label_ref (match_operand 0 "" ""))
1612 (pc)))]
1613 ""
1614 "
1615 {
1616 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1617 && GET_CODE (sparc_compare_op0) == REG
1618 && GET_MODE (sparc_compare_op0) == DImode)
1619 {
1620 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1621 DONE;
1622 }
1623 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1624 {
1625 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1626 emit_jump_insn (gen_bne (operands[0]));
1627 DONE;
1628 }
1629 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1630 }")
1631
1632 (define_expand "bgtu"
1633 [(set (pc)
1634 (if_then_else (gtu (match_dup 1) (const_int 0))
1635 (label_ref (match_operand 0 "" ""))
1636 (pc)))]
1637 ""
1638 "
1639 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1640 }")
1641
1642 (define_expand "blt"
1643 [(set (pc)
1644 (if_then_else (lt (match_dup 1) (const_int 0))
1645 (label_ref (match_operand 0 "" ""))
1646 (pc)))]
1647 ""
1648 "
1649 {
1650 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1651 && GET_CODE (sparc_compare_op0) == REG
1652 && GET_MODE (sparc_compare_op0) == DImode)
1653 {
1654 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1655 DONE;
1656 }
1657 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1658 {
1659 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1660 emit_jump_insn (gen_bne (operands[0]));
1661 DONE;
1662 }
1663 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1664 }")
1665
1666 (define_expand "bltu"
1667 [(set (pc)
1668 (if_then_else (ltu (match_dup 1) (const_int 0))
1669 (label_ref (match_operand 0 "" ""))
1670 (pc)))]
1671 ""
1672 "
1673 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1674 }")
1675
1676 (define_expand "bge"
1677 [(set (pc)
1678 (if_then_else (ge (match_dup 1) (const_int 0))
1679 (label_ref (match_operand 0 "" ""))
1680 (pc)))]
1681 ""
1682 "
1683 {
1684 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1685 && GET_CODE (sparc_compare_op0) == REG
1686 && GET_MODE (sparc_compare_op0) == DImode)
1687 {
1688 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1689 DONE;
1690 }
1691 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1692 {
1693 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1694 emit_jump_insn (gen_bne (operands[0]));
1695 DONE;
1696 }
1697 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1698 }")
1699
1700 (define_expand "bgeu"
1701 [(set (pc)
1702 (if_then_else (geu (match_dup 1) (const_int 0))
1703 (label_ref (match_operand 0 "" ""))
1704 (pc)))]
1705 ""
1706 "
1707 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1708 }")
1709
1710 (define_expand "ble"
1711 [(set (pc)
1712 (if_then_else (le (match_dup 1) (const_int 0))
1713 (label_ref (match_operand 0 "" ""))
1714 (pc)))]
1715 ""
1716 "
1717 {
1718 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1719 && GET_CODE (sparc_compare_op0) == REG
1720 && GET_MODE (sparc_compare_op0) == DImode)
1721 {
1722 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1723 DONE;
1724 }
1725 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1726 {
1727 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1728 emit_jump_insn (gen_bne (operands[0]));
1729 DONE;
1730 }
1731 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1732 }")
1733
1734 (define_expand "bleu"
1735 [(set (pc)
1736 (if_then_else (leu (match_dup 1) (const_int 0))
1737 (label_ref (match_operand 0 "" ""))
1738 (pc)))]
1739 ""
1740 "
1741 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1742 }")
1743
1744 (define_expand "bunordered"
1745 [(set (pc)
1746 (if_then_else (unordered (match_dup 1) (const_int 0))
1747 (label_ref (match_operand 0 "" ""))
1748 (pc)))]
1749 ""
1750 "
1751 {
1752 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1753 {
1754 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1755 UNORDERED);
1756 emit_jump_insn (gen_beq (operands[0]));
1757 DONE;
1758 }
1759 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1760 sparc_compare_op1);
1761 }")
1762
1763 (define_expand "bordered"
1764 [(set (pc)
1765 (if_then_else (ordered (match_dup 1) (const_int 0))
1766 (label_ref (match_operand 0 "" ""))
1767 (pc)))]
1768 ""
1769 "
1770 {
1771 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1772 {
1773 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1774 emit_jump_insn (gen_bne (operands[0]));
1775 DONE;
1776 }
1777 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1778 sparc_compare_op1);
1779 }")
1780
1781 (define_expand "bungt"
1782 [(set (pc)
1783 (if_then_else (ungt (match_dup 1) (const_int 0))
1784 (label_ref (match_operand 0 "" ""))
1785 (pc)))]
1786 ""
1787 "
1788 {
1789 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1790 {
1791 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1792 emit_jump_insn (gen_bgt (operands[0]));
1793 DONE;
1794 }
1795 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1796 }")
1797
1798 (define_expand "bunlt"
1799 [(set (pc)
1800 (if_then_else (unlt (match_dup 1) (const_int 0))
1801 (label_ref (match_operand 0 "" ""))
1802 (pc)))]
1803 ""
1804 "
1805 {
1806 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1807 {
1808 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1809 emit_jump_insn (gen_bne (operands[0]));
1810 DONE;
1811 }
1812 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1813 }")
1814
1815 (define_expand "buneq"
1816 [(set (pc)
1817 (if_then_else (uneq (match_dup 1) (const_int 0))
1818 (label_ref (match_operand 0 "" ""))
1819 (pc)))]
1820 ""
1821 "
1822 {
1823 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1824 {
1825 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1826 emit_jump_insn (gen_beq (operands[0]));
1827 DONE;
1828 }
1829 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1830 }")
1831
1832 (define_expand "bunge"
1833 [(set (pc)
1834 (if_then_else (unge (match_dup 1) (const_int 0))
1835 (label_ref (match_operand 0 "" ""))
1836 (pc)))]
1837 ""
1838 "
1839 {
1840 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1841 {
1842 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1843 emit_jump_insn (gen_bne (operands[0]));
1844 DONE;
1845 }
1846 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1847 }")
1848
1849 (define_expand "bunle"
1850 [(set (pc)
1851 (if_then_else (unle (match_dup 1) (const_int 0))
1852 (label_ref (match_operand 0 "" ""))
1853 (pc)))]
1854 ""
1855 "
1856 {
1857 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1858 {
1859 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1860 emit_jump_insn (gen_bne (operands[0]));
1861 DONE;
1862 }
1863 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1864 }")
1865
1866 (define_expand "bltgt"
1867 [(set (pc)
1868 (if_then_else (ltgt (match_dup 1) (const_int 0))
1869 (label_ref (match_operand 0 "" ""))
1870 (pc)))]
1871 ""
1872 "
1873 {
1874 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1875 {
1876 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1877 emit_jump_insn (gen_bne (operands[0]));
1878 DONE;
1879 }
1880 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1881 }")
1882 \f
1883 ;; Now match both normal and inverted jump.
1884
1885 ;; XXX fpcmp nop braindamage
1886 (define_insn "*normal_branch"
1887 [(set (pc)
1888 (if_then_else (match_operator 0 "noov_compare_op"
1889 [(reg 100) (const_int 0)])
1890 (label_ref (match_operand 1 "" ""))
1891 (pc)))]
1892 ""
1893 "*
1894 {
1895 return output_cbranch (operands[0], 1, 0,
1896 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1897 ! final_sequence, insn);
1898 }"
1899 [(set_attr "type" "branch")])
1900
1901 ;; XXX fpcmp nop braindamage
1902 (define_insn "*inverted_branch"
1903 [(set (pc)
1904 (if_then_else (match_operator 0 "noov_compare_op"
1905 [(reg 100) (const_int 0)])
1906 (pc)
1907 (label_ref (match_operand 1 "" ""))))]
1908 ""
1909 "*
1910 {
1911 return output_cbranch (operands[0], 1, 1,
1912 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1913 ! final_sequence, insn);
1914 }"
1915 [(set_attr "type" "branch")])
1916
1917 ;; XXX fpcmp nop braindamage
1918 (define_insn "*normal_fp_branch"
1919 [(set (pc)
1920 (if_then_else (match_operator 1 "comparison_operator"
1921 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1922 (const_int 0)])
1923 (label_ref (match_operand 2 "" ""))
1924 (pc)))]
1925 ""
1926 "*
1927 {
1928 return output_cbranch (operands[1], 2, 0,
1929 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1930 ! final_sequence, insn);
1931 }"
1932 [(set_attr "type" "branch")])
1933
1934 ;; XXX fpcmp nop braindamage
1935 (define_insn "*inverted_fp_branch"
1936 [(set (pc)
1937 (if_then_else (match_operator 1 "comparison_operator"
1938 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1939 (const_int 0)])
1940 (pc)
1941 (label_ref (match_operand 2 "" ""))))]
1942 ""
1943 "*
1944 {
1945 return output_cbranch (operands[1], 2, 1,
1946 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1947 ! final_sequence, insn);
1948 }"
1949 [(set_attr "type" "branch")])
1950
1951 ;; XXX fpcmp nop braindamage
1952 (define_insn "*normal_fpe_branch"
1953 [(set (pc)
1954 (if_then_else (match_operator 1 "comparison_operator"
1955 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1956 (const_int 0)])
1957 (label_ref (match_operand 2 "" ""))
1958 (pc)))]
1959 ""
1960 "*
1961 {
1962 return output_cbranch (operands[1], 2, 0,
1963 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1964 ! final_sequence, insn);
1965 }"
1966 [(set_attr "type" "branch")])
1967
1968 ;; XXX fpcmp nop braindamage
1969 (define_insn "*inverted_fpe_branch"
1970 [(set (pc)
1971 (if_then_else (match_operator 1 "comparison_operator"
1972 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1973 (const_int 0)])
1974 (pc)
1975 (label_ref (match_operand 2 "" ""))))]
1976 ""
1977 "*
1978 {
1979 return output_cbranch (operands[1], 2, 1,
1980 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1981 ! final_sequence, insn);
1982 }"
1983 [(set_attr "type" "branch")])
1984
1985 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1986 ;; in the architecture.
1987
1988 ;; There are no 32 bit brreg insns.
1989
1990 ;; XXX
1991 (define_insn "*normal_int_branch_sp64"
1992 [(set (pc)
1993 (if_then_else (match_operator 0 "v9_regcmp_op"
1994 [(match_operand:DI 1 "register_operand" "r")
1995 (const_int 0)])
1996 (label_ref (match_operand 2 "" ""))
1997 (pc)))]
1998 "TARGET_ARCH64"
1999 "*
2000 {
2001 return output_v9branch (operands[0], 1, 2, 0,
2002 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2003 ! final_sequence, insn);
2004 }"
2005 [(set_attr "type" "branch")])
2006
2007 ;; XXX
2008 (define_insn "*inverted_int_branch_sp64"
2009 [(set (pc)
2010 (if_then_else (match_operator 0 "v9_regcmp_op"
2011 [(match_operand:DI 1 "register_operand" "r")
2012 (const_int 0)])
2013 (pc)
2014 (label_ref (match_operand 2 "" ""))))]
2015 "TARGET_ARCH64"
2016 "*
2017 {
2018 return output_v9branch (operands[0], 1, 2, 1,
2019 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2020 ! final_sequence, insn);
2021 }"
2022 [(set_attr "type" "branch")])
2023 \f
2024 ;; Load program counter insns.
2025
2026 (define_insn "get_pc"
2027 [(clobber (reg:SI 15))
2028 (set (match_operand 0 "register_operand" "=r")
2029 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2030 "flag_pic && REGNO (operands[0]) == 23"
2031 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2032 [(set_attr "type" "multi")
2033 (set_attr "length" "3")])
2034
2035 ;; Currently unused...
2036 ;; (define_insn "get_pc_via_rdpc"
2037 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2038 ;; "TARGET_V9"
2039 ;; "rd\\t%%pc, %0"
2040 ;; [(set_attr "type" "misc")])
2041
2042 \f
2043 ;; Move instructions
2044
2045 (define_expand "movqi"
2046 [(set (match_operand:QI 0 "general_operand" "")
2047 (match_operand:QI 1 "general_operand" ""))]
2048 ""
2049 "
2050 {
2051 /* Working with CONST_INTs is easier, so convert
2052 a double if needed. */
2053 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2054 {
2055 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2056 }
2057 else if (GET_CODE (operands[1]) == CONST_INT)
2058 {
2059 /* And further, we know for all QI cases that only the
2060 low byte is significant, which we can always process
2061 in a single insn. So mask it now. */
2062 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2063 }
2064
2065 /* Handle sets of MEM first. */
2066 if (GET_CODE (operands[0]) == MEM)
2067 {
2068 if (reg_or_0_operand (operands[1], QImode))
2069 goto movqi_is_ok;
2070
2071 if (! reload_in_progress)
2072 {
2073 operands[0] = validize_mem (operands[0]);
2074 operands[1] = force_reg (QImode, operands[1]);
2075 }
2076 }
2077
2078 /* Fixup PIC cases. */
2079 if (flag_pic)
2080 {
2081 if (CONSTANT_P (operands[1])
2082 && pic_address_needs_scratch (operands[1]))
2083 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2084
2085 if (symbolic_operand (operands[1], QImode))
2086 {
2087 operands[1] = legitimize_pic_address (operands[1],
2088 QImode,
2089 (reload_in_progress ?
2090 operands[0] :
2091 NULL_RTX));
2092 goto movqi_is_ok;
2093 }
2094 }
2095
2096 /* All QI constants require only one insn, so proceed. */
2097
2098 movqi_is_ok:
2099 ;
2100 }")
2101
2102 (define_insn "*movqi_insn"
2103 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2104 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2105 "(register_operand (operands[0], QImode)
2106 || reg_or_0_operand (operands[1], QImode))"
2107 "@
2108 mov\\t%1, %0
2109 ldub\\t%1, %0
2110 stb\\t%r1, %0"
2111 [(set_attr "type" "*,load,store")])
2112
2113 (define_expand "movhi"
2114 [(set (match_operand:HI 0 "general_operand" "")
2115 (match_operand:HI 1 "general_operand" ""))]
2116 ""
2117 "
2118 {
2119 /* Working with CONST_INTs is easier, so convert
2120 a double if needed. */
2121 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2122 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2123
2124 /* Handle sets of MEM first. */
2125 if (GET_CODE (operands[0]) == MEM)
2126 {
2127 if (reg_or_0_operand (operands[1], HImode))
2128 goto movhi_is_ok;
2129
2130 if (! reload_in_progress)
2131 {
2132 operands[0] = validize_mem (operands[0]);
2133 operands[1] = force_reg (HImode, operands[1]);
2134 }
2135 }
2136
2137 /* Fixup PIC cases. */
2138 if (flag_pic)
2139 {
2140 if (CONSTANT_P (operands[1])
2141 && pic_address_needs_scratch (operands[1]))
2142 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2143
2144 if (symbolic_operand (operands[1], HImode))
2145 {
2146 operands[1] = legitimize_pic_address (operands[1],
2147 HImode,
2148 (reload_in_progress ?
2149 operands[0] :
2150 NULL_RTX));
2151 goto movhi_is_ok;
2152 }
2153 }
2154
2155 /* This makes sure we will not get rematched due to splittage. */
2156 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2157 ;
2158 else if (CONSTANT_P (operands[1])
2159 && GET_CODE (operands[1]) != HIGH
2160 && GET_CODE (operands[1]) != LO_SUM)
2161 {
2162 sparc_emit_set_const32 (operands[0], operands[1]);
2163 DONE;
2164 }
2165 movhi_is_ok:
2166 ;
2167 }")
2168
2169 (define_insn "*movhi_const64_special"
2170 [(set (match_operand:HI 0 "register_operand" "=r")
2171 (match_operand:HI 1 "const64_high_operand" ""))]
2172 "TARGET_ARCH64"
2173 "sethi\\t%%hi(%a1), %0")
2174
2175 (define_insn "*movhi_insn"
2176 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2177 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2178 "(register_operand (operands[0], HImode)
2179 || reg_or_0_operand (operands[1], HImode))"
2180 "@
2181 mov\\t%1, %0
2182 sethi\\t%%hi(%a1), %0
2183 lduh\\t%1, %0
2184 sth\\t%r1, %0"
2185 [(set_attr "type" "*,*,load,store")])
2186
2187 ;; We always work with constants here.
2188 (define_insn "*movhi_lo_sum"
2189 [(set (match_operand:HI 0 "register_operand" "=r")
2190 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2191 (match_operand:HI 2 "arith_operand" "I")))]
2192 ""
2193 "or\\t%1, %2, %0")
2194
2195 (define_expand "movsi"
2196 [(set (match_operand:SI 0 "general_operand" "")
2197 (match_operand:SI 1 "general_operand" ""))]
2198 ""
2199 "
2200 {
2201 /* Working with CONST_INTs is easier, so convert
2202 a double if needed. */
2203 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2204 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2205
2206 /* Handle sets of MEM first. */
2207 if (GET_CODE (operands[0]) == MEM)
2208 {
2209 if (reg_or_0_operand (operands[1], SImode))
2210 goto movsi_is_ok;
2211
2212 if (! reload_in_progress)
2213 {
2214 operands[0] = validize_mem (operands[0]);
2215 operands[1] = force_reg (SImode, operands[1]);
2216 }
2217 }
2218
2219 /* Fixup PIC cases. */
2220 if (flag_pic)
2221 {
2222 if (CONSTANT_P (operands[1])
2223 && pic_address_needs_scratch (operands[1]))
2224 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2225
2226 if (GET_CODE (operands[1]) == LABEL_REF)
2227 {
2228 /* shit */
2229 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2230 DONE;
2231 }
2232
2233 if (symbolic_operand (operands[1], SImode))
2234 {
2235 operands[1] = legitimize_pic_address (operands[1],
2236 SImode,
2237 (reload_in_progress ?
2238 operands[0] :
2239 NULL_RTX));
2240 goto movsi_is_ok;
2241 }
2242 }
2243
2244 /* If we are trying to toss an integer constant into the
2245 FPU registers, force it into memory. */
2246 if (GET_CODE (operands[0]) == REG
2247 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2248 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2249 && CONSTANT_P (operands[1]))
2250 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2251 operands[1]));
2252
2253 /* This makes sure we will not get rematched due to splittage. */
2254 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2255 ;
2256 else if (CONSTANT_P (operands[1])
2257 && GET_CODE (operands[1]) != HIGH
2258 && GET_CODE (operands[1]) != LO_SUM)
2259 {
2260 sparc_emit_set_const32 (operands[0], operands[1]);
2261 DONE;
2262 }
2263 movsi_is_ok:
2264 ;
2265 }")
2266
2267 ;; This is needed to show CSE exactly which bits are set
2268 ;; in a 64-bit register by sethi instructions.
2269 (define_insn "*movsi_const64_special"
2270 [(set (match_operand:SI 0 "register_operand" "=r")
2271 (match_operand:SI 1 "const64_high_operand" ""))]
2272 "TARGET_ARCH64"
2273 "sethi\\t%%hi(%a1), %0")
2274
2275 (define_insn "*movsi_insn"
2276 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2277 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2278 "(register_operand (operands[0], SImode)
2279 || reg_or_0_operand (operands[1], SImode))"
2280 "@
2281 mov\\t%1, %0
2282 fmovs\\t%1, %0
2283 sethi\\t%%hi(%a1), %0
2284 clr\\t%0
2285 ld\\t%1, %0
2286 ld\\t%1, %0
2287 st\\t%r1, %0
2288 st\\t%1, %0
2289 fzeros\\t%0"
2290 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2291
2292 (define_insn "*movsi_lo_sum"
2293 [(set (match_operand:SI 0 "register_operand" "=r")
2294 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2295 (match_operand:SI 2 "immediate_operand" "in")))]
2296 ""
2297 "or\\t%1, %%lo(%a2), %0")
2298
2299 (define_insn "*movsi_high"
2300 [(set (match_operand:SI 0 "register_operand" "=r")
2301 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2302 ""
2303 "sethi\\t%%hi(%a1), %0")
2304
2305 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2306 ;; so that CSE won't optimize the address computation away.
2307 (define_insn "movsi_lo_sum_pic"
2308 [(set (match_operand:SI 0 "register_operand" "=r")
2309 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2310 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2311 "flag_pic"
2312 "or\\t%1, %%lo(%a2), %0")
2313
2314 (define_insn "movsi_high_pic"
2315 [(set (match_operand:SI 0 "register_operand" "=r")
2316 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2317 "flag_pic && check_pic (1)"
2318 "sethi\\t%%hi(%a1), %0")
2319
2320 (define_expand "movsi_pic_label_ref"
2321 [(set (match_dup 3) (high:SI
2322 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2323 (match_dup 2)] 5)))
2324 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2325 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2326 (set (match_operand:SI 0 "register_operand" "=r")
2327 (minus:SI (match_dup 5) (match_dup 4)))]
2328 "flag_pic"
2329 "
2330 {
2331 current_function_uses_pic_offset_table = 1;
2332 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2333 if (no_new_pseudos)
2334 {
2335 operands[3] = operands[0];
2336 operands[4] = operands[0];
2337 }
2338 else
2339 {
2340 operands[3] = gen_reg_rtx (SImode);
2341 operands[4] = gen_reg_rtx (SImode);
2342 }
2343 operands[5] = pic_offset_table_rtx;
2344 }")
2345
2346 (define_insn "*movsi_high_pic_label_ref"
2347 [(set (match_operand:SI 0 "register_operand" "=r")
2348 (high:SI
2349 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2350 (match_operand:SI 2 "" "")] 5)))]
2351 "flag_pic"
2352 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2353
2354 (define_insn "*movsi_lo_sum_pic_label_ref"
2355 [(set (match_operand:SI 0 "register_operand" "=r")
2356 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2357 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2358 (match_operand:SI 3 "" "")] 5)))]
2359 "flag_pic"
2360 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2361
2362 (define_expand "movdi"
2363 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2364 (match_operand:DI 1 "general_operand" ""))]
2365 ""
2366 "
2367 {
2368 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2369 if (GET_CODE (operands[1]) == CONST_DOUBLE
2370 #if HOST_BITS_PER_WIDE_INT == 32
2371 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2372 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2373 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2374 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2375 #endif
2376 )
2377 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2378
2379 /* Handle MEM cases first. */
2380 if (GET_CODE (operands[0]) == MEM)
2381 {
2382 /* If it's a REG, we can always do it.
2383 The const zero case is more complex, on v9
2384 we can always perform it. */
2385 if (register_operand (operands[1], DImode)
2386 || (TARGET_ARCH64
2387 && (operands[1] == const0_rtx)))
2388 goto movdi_is_ok;
2389
2390 if (! reload_in_progress)
2391 {
2392 operands[0] = validize_mem (operands[0]);
2393 operands[1] = force_reg (DImode, operands[1]);
2394 }
2395 }
2396
2397 if (flag_pic)
2398 {
2399 if (CONSTANT_P (operands[1])
2400 && pic_address_needs_scratch (operands[1]))
2401 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2402
2403 if (GET_CODE (operands[1]) == LABEL_REF)
2404 {
2405 if (! TARGET_ARCH64)
2406 abort ();
2407 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2408 DONE;
2409 }
2410
2411 if (symbolic_operand (operands[1], DImode))
2412 {
2413 operands[1] = legitimize_pic_address (operands[1],
2414 DImode,
2415 (reload_in_progress ?
2416 operands[0] :
2417 NULL_RTX));
2418 goto movdi_is_ok;
2419 }
2420 }
2421
2422 /* If we are trying to toss an integer constant into the
2423 FPU registers, force it into memory. */
2424 if (GET_CODE (operands[0]) == REG
2425 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2426 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2427 && CONSTANT_P (operands[1]))
2428 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2429 operands[1]));
2430
2431 /* This makes sure we will not get rematched due to splittage. */
2432 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2433 ;
2434 else if (TARGET_ARCH64
2435 && CONSTANT_P (operands[1])
2436 && GET_CODE (operands[1]) != HIGH
2437 && GET_CODE (operands[1]) != LO_SUM)
2438 {
2439 sparc_emit_set_const64 (operands[0], operands[1]);
2440 DONE;
2441 }
2442
2443 movdi_is_ok:
2444 ;
2445 }")
2446
2447 ;; Be careful, fmovd does not exist when !arch64.
2448 ;; We match MEM moves directly when we have correct even
2449 ;; numbered registers, but fall into splits otherwise.
2450 ;; The constraint ordering here is really important to
2451 ;; avoid insane problems in reload, especially for patterns
2452 ;; of the form:
2453 ;;
2454 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2455 ;; (const_int -5016)))
2456 ;; (reg:DI 2 %g2))
2457 ;;
2458 (define_insn "*movdi_insn_sp32"
2459 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2460 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2461 "! TARGET_ARCH64 &&
2462 (register_operand (operands[0], DImode)
2463 || register_operand (operands[1], DImode))"
2464 "@
2465 std\\t%1, %0
2466 ldd\\t%1, %0
2467 #
2468 #
2469 #
2470 #
2471 std\\t%1, %0
2472 ldd\\t%1, %0
2473 #
2474 #
2475 #"
2476 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2477 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2478
2479 ;; The following are generated by sparc_emit_set_const64
2480 (define_insn "*movdi_sp64_dbl"
2481 [(set (match_operand:DI 0 "register_operand" "=r")
2482 (match_operand:DI 1 "const64_operand" ""))]
2483 "(TARGET_ARCH64
2484 && HOST_BITS_PER_WIDE_INT != 64)"
2485 "mov\\t%1, %0")
2486
2487 ;; This is needed to show CSE exactly which bits are set
2488 ;; in a 64-bit register by sethi instructions.
2489 (define_insn "*movdi_const64_special"
2490 [(set (match_operand:DI 0 "register_operand" "=r")
2491 (match_operand:DI 1 "const64_high_operand" ""))]
2492 "TARGET_ARCH64"
2493 "sethi\\t%%hi(%a1), %0")
2494
2495 (define_insn "*movdi_insn_sp64_novis"
2496 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2497 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
2498 "TARGET_ARCH64 && ! TARGET_VIS
2499 && (register_operand (operands[0], DImode)
2500 || reg_or_0_operand (operands[1], DImode))"
2501 "@
2502 mov\\t%1, %0
2503 sethi\\t%%hi(%a1), %0
2504 clr\\t%0
2505 ldx\\t%1, %0
2506 stx\\t%r1, %0
2507 fmovd\\t%1, %0
2508 ldd\\t%1, %0
2509 std\\t%1, %0"
2510 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2511 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2512
2513 (define_insn "*movdi_insn_sp64_vis"
2514 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2515 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2516 "TARGET_ARCH64 && TARGET_VIS &&
2517 (register_operand (operands[0], DImode)
2518 || reg_or_0_operand (operands[1], DImode))"
2519 "@
2520 mov\\t%1, %0
2521 sethi\\t%%hi(%a1), %0
2522 clr\\t%0
2523 ldx\\t%1, %0
2524 stx\\t%r1, %0
2525 fmovd\\t%1, %0
2526 ldd\\t%1, %0
2527 std\\t%1, %0
2528 fzero\\t%0"
2529 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2530 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2531
2532 (define_expand "movdi_pic_label_ref"
2533 [(set (match_dup 3) (high:DI
2534 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2535 (match_dup 2)] 5)))
2536 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2537 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2538 (set (match_operand:DI 0 "register_operand" "=r")
2539 (minus:DI (match_dup 5) (match_dup 4)))]
2540 "TARGET_ARCH64 && flag_pic"
2541 "
2542 {
2543 current_function_uses_pic_offset_table = 1;
2544 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2545 if (no_new_pseudos)
2546 {
2547 operands[3] = operands[0];
2548 operands[4] = operands[0];
2549 }
2550 else
2551 {
2552 operands[3] = gen_reg_rtx (DImode);
2553 operands[4] = gen_reg_rtx (DImode);
2554 }
2555 operands[5] = pic_offset_table_rtx;
2556 }")
2557
2558 (define_insn "*movdi_high_pic_label_ref"
2559 [(set (match_operand:DI 0 "register_operand" "=r")
2560 (high:DI
2561 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2562 (match_operand:DI 2 "" "")] 5)))]
2563 "TARGET_ARCH64 && flag_pic"
2564 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2565
2566 (define_insn "*movdi_lo_sum_pic_label_ref"
2567 [(set (match_operand:DI 0 "register_operand" "=r")
2568 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2569 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2570 (match_operand:DI 3 "" "")] 5)))]
2571 "TARGET_ARCH64 && flag_pic"
2572 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2573
2574 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2575 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2576
2577 (define_insn "movdi_lo_sum_pic"
2578 [(set (match_operand:DI 0 "register_operand" "=r")
2579 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2580 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2581 "TARGET_ARCH64 && flag_pic"
2582 "or\\t%1, %%lo(%a2), %0")
2583
2584 (define_insn "movdi_high_pic"
2585 [(set (match_operand:DI 0 "register_operand" "=r")
2586 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2587 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2588 "sethi\\t%%hi(%a1), %0")
2589
2590 (define_insn "*sethi_di_medlow_embmedany_pic"
2591 [(set (match_operand:DI 0 "register_operand" "=r")
2592 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2593 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2594 "sethi\\t%%hi(%a1), %0")
2595
2596 (define_insn "*sethi_di_medlow"
2597 [(set (match_operand:DI 0 "register_operand" "=r")
2598 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2599 "TARGET_CM_MEDLOW && check_pic (1)"
2600 "sethi\\t%%hi(%a1), %0")
2601
2602 (define_insn "*losum_di_medlow"
2603 [(set (match_operand:DI 0 "register_operand" "=r")
2604 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2605 (match_operand:DI 2 "symbolic_operand" "")))]
2606 "TARGET_CM_MEDLOW"
2607 "or\\t%1, %%lo(%a2), %0")
2608
2609 (define_insn "seth44"
2610 [(set (match_operand:DI 0 "register_operand" "=r")
2611 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2612 "TARGET_CM_MEDMID"
2613 "sethi\\t%%h44(%a1), %0")
2614
2615 (define_insn "setm44"
2616 [(set (match_operand:DI 0 "register_operand" "=r")
2617 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2618 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2619 "TARGET_CM_MEDMID"
2620 "or\\t%1, %%m44(%a2), %0")
2621
2622 (define_insn "setl44"
2623 [(set (match_operand:DI 0 "register_operand" "=r")
2624 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2625 (match_operand:DI 2 "symbolic_operand" "")))]
2626 "TARGET_CM_MEDMID"
2627 "or\\t%1, %%l44(%a2), %0")
2628
2629 (define_insn "sethh"
2630 [(set (match_operand:DI 0 "register_operand" "=r")
2631 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2632 "TARGET_CM_MEDANY"
2633 "sethi\\t%%hh(%a1), %0")
2634
2635 (define_insn "setlm"
2636 [(set (match_operand:DI 0 "register_operand" "=r")
2637 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2638 "TARGET_CM_MEDANY"
2639 "sethi\\t%%lm(%a1), %0")
2640
2641 (define_insn "sethm"
2642 [(set (match_operand:DI 0 "register_operand" "=r")
2643 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2644 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2645 "TARGET_CM_MEDANY"
2646 "or\\t%1, %%hm(%a2), %0")
2647
2648 (define_insn "setlo"
2649 [(set (match_operand:DI 0 "register_operand" "=r")
2650 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2651 (match_operand:DI 2 "symbolic_operand" "")))]
2652 "TARGET_CM_MEDANY"
2653 "or\\t%1, %%lo(%a2), %0")
2654
2655 (define_insn "embmedany_sethi"
2656 [(set (match_operand:DI 0 "register_operand" "=r")
2657 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2658 "TARGET_CM_EMBMEDANY && check_pic (1)"
2659 "sethi\\t%%hi(%a1), %0")
2660
2661 (define_insn "embmedany_losum"
2662 [(set (match_operand:DI 0 "register_operand" "=r")
2663 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2664 (match_operand:DI 2 "data_segment_operand" "")))]
2665 "TARGET_CM_EMBMEDANY"
2666 "add\\t%1, %%lo(%a2), %0")
2667
2668 (define_insn "embmedany_brsum"
2669 [(set (match_operand:DI 0 "register_operand" "=r")
2670 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2671 "TARGET_CM_EMBMEDANY"
2672 "add\\t%1, %_, %0")
2673
2674 (define_insn "embmedany_textuhi"
2675 [(set (match_operand:DI 0 "register_operand" "=r")
2676 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2677 "TARGET_CM_EMBMEDANY && check_pic (1)"
2678 "sethi\\t%%uhi(%a1), %0")
2679
2680 (define_insn "embmedany_texthi"
2681 [(set (match_operand:DI 0 "register_operand" "=r")
2682 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2683 "TARGET_CM_EMBMEDANY && check_pic (1)"
2684 "sethi\\t%%hi(%a1), %0")
2685
2686 (define_insn "embmedany_textulo"
2687 [(set (match_operand:DI 0 "register_operand" "=r")
2688 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2689 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2690 "TARGET_CM_EMBMEDANY"
2691 "or\\t%1, %%ulo(%a2), %0")
2692
2693 (define_insn "embmedany_textlo"
2694 [(set (match_operand:DI 0 "register_operand" "=r")
2695 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2696 (match_operand:DI 2 "text_segment_operand" "")))]
2697 "TARGET_CM_EMBMEDANY"
2698 "or\\t%1, %%lo(%a2), %0")
2699
2700 ;; Now some patterns to help reload out a bit.
2701 (define_expand "reload_indi"
2702 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2703 (match_operand:DI 1 "immediate_operand" "")
2704 (match_operand:TI 2 "register_operand" "=&r")])]
2705 "(TARGET_CM_MEDANY
2706 || TARGET_CM_EMBMEDANY)
2707 && ! flag_pic"
2708 "
2709 {
2710 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2711 gen_rtx_REG (DImode, REGNO (operands[2])));
2712 DONE;
2713 }")
2714
2715 (define_expand "reload_outdi"
2716 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2717 (match_operand:DI 1 "immediate_operand" "")
2718 (match_operand:TI 2 "register_operand" "=&r")])]
2719 "(TARGET_CM_MEDANY
2720 || TARGET_CM_EMBMEDANY)
2721 && ! flag_pic"
2722 "
2723 {
2724 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2725 gen_rtx_REG (DImode, REGNO (operands[2])));
2726 DONE;
2727 }")
2728
2729 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2730 (define_split
2731 [(set (match_operand:DI 0 "register_operand" "")
2732 (match_operand:DI 1 "const_int_operand" ""))]
2733 "! TARGET_ARCH64 && reload_completed"
2734 [(clobber (const_int 0))]
2735 "
2736 {
2737 #if HOST_BITS_PER_WIDE_INT == 32
2738 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2739 (INTVAL (operands[1]) < 0) ?
2740 constm1_rtx :
2741 const0_rtx));
2742 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2743 operands[1]));
2744 #else
2745 unsigned int low, high;
2746
2747 low = INTVAL (operands[1]) & 0xffffffff;
2748 high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
2749 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2750
2751 /* Slick... but this trick loses if this subreg constant part
2752 can be done in one insn. */
2753 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2754 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2755 gen_highpart (SImode, operands[0])));
2756 else
2757 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2758 #endif
2759 DONE;
2760 }")
2761
2762 (define_split
2763 [(set (match_operand:DI 0 "register_operand" "")
2764 (match_operand:DI 1 "const_double_operand" ""))]
2765 "! TARGET_ARCH64 && reload_completed"
2766 [(clobber (const_int 0))]
2767 "
2768 {
2769 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2770 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2771
2772 /* Slick... but this trick loses if this subreg constant part
2773 can be done in one insn. */
2774 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2775 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2776 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2777 {
2778 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2779 gen_highpart (SImode, operands[0])));
2780 }
2781 else
2782 {
2783 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2784 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2785 }
2786 DONE;
2787 }")
2788
2789 (define_split
2790 [(set (match_operand:DI 0 "register_operand" "")
2791 (match_operand:DI 1 "register_operand" ""))]
2792 "! TARGET_ARCH64 && reload_completed"
2793 [(clobber (const_int 0))]
2794 "
2795 {
2796 rtx set_dest = operands[0];
2797 rtx set_src = operands[1];
2798 rtx dest1, dest2;
2799 rtx src1, src2;
2800
2801 if (GET_CODE (set_dest) == SUBREG)
2802 set_dest = alter_subreg (set_dest);
2803 if (GET_CODE (set_src) == SUBREG)
2804 set_src = alter_subreg (set_src);
2805
2806 dest1 = gen_highpart (SImode, set_dest);
2807 dest2 = gen_lowpart (SImode, set_dest);
2808 src1 = gen_highpart (SImode, set_src);
2809 src2 = gen_lowpart (SImode, set_src);
2810
2811 /* Now emit using the real source and destination we found, swapping
2812 the order if we detect overlap. */
2813 if (reg_overlap_mentioned_p (dest1, src2))
2814 {
2815 emit_insn (gen_movsi (dest2, src2));
2816 emit_insn (gen_movsi (dest1, src1));
2817 }
2818 else
2819 {
2820 emit_insn (gen_movsi (dest1, src1));
2821 emit_insn (gen_movsi (dest2, src2));
2822 }
2823 DONE;
2824 }")
2825
2826 ;; Now handle the cases of memory moves from/to non-even
2827 ;; DI mode register pairs.
2828 (define_split
2829 [(set (match_operand:DI 0 "register_operand" "")
2830 (match_operand:DI 1 "memory_operand" ""))]
2831 "(! TARGET_ARCH64
2832 && reload_completed
2833 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2834 [(clobber (const_int 0))]
2835 "
2836 {
2837 rtx word0 = adjust_address (operands[1], SImode, 0);
2838 rtx word1 = adjust_address (operands[1], SImode, 4);
2839 rtx high_part = gen_highpart (SImode, operands[0]);
2840 rtx low_part = gen_lowpart (SImode, operands[0]);
2841
2842 if (reg_overlap_mentioned_p (high_part, word1))
2843 {
2844 emit_insn (gen_movsi (low_part, word1));
2845 emit_insn (gen_movsi (high_part, word0));
2846 }
2847 else
2848 {
2849 emit_insn (gen_movsi (high_part, word0));
2850 emit_insn (gen_movsi (low_part, word1));
2851 }
2852 DONE;
2853 }")
2854
2855 (define_split
2856 [(set (match_operand:DI 0 "memory_operand" "")
2857 (match_operand:DI 1 "register_operand" ""))]
2858 "(! TARGET_ARCH64
2859 && reload_completed
2860 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2861 [(clobber (const_int 0))]
2862 "
2863 {
2864 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2865 gen_highpart (SImode, operands[1])));
2866 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2867 gen_lowpart (SImode, operands[1])));
2868 DONE;
2869 }")
2870
2871 \f
2872 ;; Floating point move insns
2873
2874 (define_insn "*movsf_insn_novis"
2875 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2876 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2877 "(TARGET_FPU && ! TARGET_VIS)
2878 && (register_operand (operands[0], SFmode)
2879 || register_operand (operands[1], SFmode)
2880 || fp_zero_operand (operands[1], SFmode))"
2881 "*
2882 {
2883 if (GET_CODE (operands[1]) == CONST_DOUBLE
2884 && (which_alternative == 2
2885 || which_alternative == 3
2886 || which_alternative == 4))
2887 {
2888 REAL_VALUE_TYPE r;
2889 long i;
2890
2891 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2892 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2893 operands[1] = GEN_INT (i);
2894 }
2895
2896 switch (which_alternative)
2897 {
2898 case 0:
2899 return \"fmovs\\t%1, %0\";
2900 case 1:
2901 return \"clr\\t%0\";
2902 case 2:
2903 return \"sethi\\t%%hi(%a1), %0\";
2904 case 3:
2905 return \"mov\\t%1, %0\";
2906 case 4:
2907 return \"#\";
2908 case 5:
2909 case 6:
2910 return \"ld\\t%1, %0\";
2911 case 7:
2912 case 8:
2913 return \"st\\t%r1, %0\";
2914 default:
2915 abort();
2916 }
2917 }"
2918 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2919
2920 (define_insn "*movsf_insn_vis"
2921 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2922 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2923 "(TARGET_FPU && TARGET_VIS)
2924 && (register_operand (operands[0], SFmode)
2925 || register_operand (operands[1], SFmode)
2926 || fp_zero_operand (operands[1], SFmode))"
2927 "*
2928 {
2929 if (GET_CODE (operands[1]) == CONST_DOUBLE
2930 && (which_alternative == 3
2931 || which_alternative == 4
2932 || which_alternative == 5))
2933 {
2934 REAL_VALUE_TYPE r;
2935 long i;
2936
2937 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2938 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2939 operands[1] = GEN_INT (i);
2940 }
2941
2942 switch (which_alternative)
2943 {
2944 case 0:
2945 return \"fmovs\\t%1, %0\";
2946 case 1:
2947 return \"fzeros\\t%0\";
2948 case 2:
2949 return \"clr\\t%0\";
2950 case 3:
2951 return \"sethi\\t%%hi(%a1), %0\";
2952 case 4:
2953 return \"mov\\t%1, %0\";
2954 case 5:
2955 return \"#\";
2956 case 6:
2957 case 7:
2958 return \"ld\\t%1, %0\";
2959 case 8:
2960 case 9:
2961 return \"st\\t%r1, %0\";
2962 default:
2963 abort();
2964 }
2965 }"
2966 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2967
2968 ;; Exactly the same as above, except that all `f' cases are deleted.
2969 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2970 ;; when -mno-fpu.
2971
2972 (define_insn "*movsf_no_f_insn"
2973 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2974 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2975 "! TARGET_FPU
2976 && (register_operand (operands[0], SFmode)
2977 || register_operand (operands[1], SFmode)
2978 || fp_zero_operand (operands[1], SFmode))"
2979 "*
2980 {
2981 if (GET_CODE (operands[1]) == CONST_DOUBLE
2982 && (which_alternative == 1
2983 || which_alternative == 2
2984 || which_alternative == 3))
2985 {
2986 REAL_VALUE_TYPE r;
2987 long i;
2988
2989 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2990 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2991 operands[1] = GEN_INT (i);
2992 }
2993
2994 switch (which_alternative)
2995 {
2996 case 0:
2997 return \"clr\\t%0\";
2998 case 1:
2999 return \"sethi\\t%%hi(%a1), %0\";
3000 case 2:
3001 return \"mov\\t%1, %0\";
3002 case 3:
3003 return \"#\";
3004 case 4:
3005 return \"ld\\t%1, %0\";
3006 case 5:
3007 return \"st\\t%r1, %0\";
3008 default:
3009 abort();
3010 }
3011 }"
3012 [(set_attr "type" "*,*,*,*,load,store")])
3013
3014 (define_insn "*movsf_lo_sum"
3015 [(set (match_operand:SF 0 "register_operand" "=r")
3016 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3017 (match_operand:SF 2 "const_double_operand" "S")))]
3018 "fp_high_losum_p (operands[2])"
3019 "*
3020 {
3021 REAL_VALUE_TYPE r;
3022 long i;
3023
3024 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3025 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3026 operands[2] = GEN_INT (i);
3027 return \"or\\t%1, %%lo(%a2), %0\";
3028 }")
3029
3030 (define_insn "*movsf_high"
3031 [(set (match_operand:SF 0 "register_operand" "=r")
3032 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3033 "fp_high_losum_p (operands[1])"
3034 "*
3035 {
3036 REAL_VALUE_TYPE r;
3037 long i;
3038
3039 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3040 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3041 operands[1] = GEN_INT (i);
3042 return \"sethi\\t%%hi(%1), %0\";
3043 }")
3044
3045 (define_split
3046 [(set (match_operand:SF 0 "register_operand" "")
3047 (match_operand:SF 1 "const_double_operand" ""))]
3048 "fp_high_losum_p (operands[1])
3049 && (GET_CODE (operands[0]) == REG
3050 && REGNO (operands[0]) < 32)"
3051 [(set (match_dup 0) (high:SF (match_dup 1)))
3052 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3053
3054 (define_expand "movsf"
3055 [(set (match_operand:SF 0 "general_operand" "")
3056 (match_operand:SF 1 "general_operand" ""))]
3057 ""
3058 "
3059 {
3060 /* Force SFmode constants into memory. */
3061 if (GET_CODE (operands[0]) == REG
3062 && CONSTANT_P (operands[1]))
3063 {
3064 /* emit_group_store will send such bogosity to us when it is
3065 not storing directly into memory. So fix this up to avoid
3066 crashes in output_constant_pool. */
3067 if (operands [1] == const0_rtx)
3068 operands[1] = CONST0_RTX (SFmode);
3069
3070 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3071 goto movsf_is_ok;
3072
3073 /* We are able to build any SF constant in integer registers
3074 with at most 2 instructions. */
3075 if (REGNO (operands[0]) < 32)
3076 goto movsf_is_ok;
3077
3078 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3079 operands[1]));
3080 }
3081
3082 /* Handle sets of MEM first. */
3083 if (GET_CODE (operands[0]) == MEM)
3084 {
3085 if (register_operand (operands[1], SFmode)
3086 || fp_zero_operand (operands[1], SFmode))
3087 goto movsf_is_ok;
3088
3089 if (! reload_in_progress)
3090 {
3091 operands[0] = validize_mem (operands[0]);
3092 operands[1] = force_reg (SFmode, operands[1]);
3093 }
3094 }
3095
3096 /* Fixup PIC cases. */
3097 if (flag_pic)
3098 {
3099 if (CONSTANT_P (operands[1])
3100 && pic_address_needs_scratch (operands[1]))
3101 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3102
3103 if (symbolic_operand (operands[1], SFmode))
3104 {
3105 operands[1] = legitimize_pic_address (operands[1],
3106 SFmode,
3107 (reload_in_progress ?
3108 operands[0] :
3109 NULL_RTX));
3110 }
3111 }
3112
3113 movsf_is_ok:
3114 ;
3115 }")
3116
3117 (define_expand "movdf"
3118 [(set (match_operand:DF 0 "general_operand" "")
3119 (match_operand:DF 1 "general_operand" ""))]
3120 ""
3121 "
3122 {
3123 /* Force DFmode constants into memory. */
3124 if (GET_CODE (operands[0]) == REG
3125 && CONSTANT_P (operands[1]))
3126 {
3127 /* emit_group_store will send such bogosity to us when it is
3128 not storing directly into memory. So fix this up to avoid
3129 crashes in output_constant_pool. */
3130 if (operands [1] == const0_rtx)
3131 operands[1] = CONST0_RTX (DFmode);
3132
3133 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3134 && fp_zero_operand (operands[1], DFmode))
3135 goto movdf_is_ok;
3136
3137 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3138 operands[1]));
3139 }
3140
3141 /* Handle MEM cases first. */
3142 if (GET_CODE (operands[0]) == MEM)
3143 {
3144 if (register_operand (operands[1], DFmode)
3145 || fp_zero_operand (operands[1], DFmode))
3146 goto movdf_is_ok;
3147
3148 if (! reload_in_progress)
3149 {
3150 operands[0] = validize_mem (operands[0]);
3151 operands[1] = force_reg (DFmode, operands[1]);
3152 }
3153 }
3154
3155 /* Fixup PIC cases. */
3156 if (flag_pic)
3157 {
3158 if (CONSTANT_P (operands[1])
3159 && pic_address_needs_scratch (operands[1]))
3160 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3161
3162 if (symbolic_operand (operands[1], DFmode))
3163 {
3164 operands[1] = legitimize_pic_address (operands[1],
3165 DFmode,
3166 (reload_in_progress ?
3167 operands[0] :
3168 NULL_RTX));
3169 }
3170 }
3171
3172 movdf_is_ok:
3173 ;
3174 }")
3175
3176 ;; Be careful, fmovd does not exist when !v9.
3177 (define_insn "*movdf_insn_sp32"
3178 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3179 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3180 "TARGET_FPU
3181 && ! TARGET_V9
3182 && (register_operand (operands[0], DFmode)
3183 || register_operand (operands[1], DFmode)
3184 || fp_zero_operand (operands[1], DFmode))"
3185 "@
3186 ldd\\t%1, %0
3187 std\\t%1, %0
3188 ldd\\t%1, %0
3189 std\\t%1, %0
3190 #
3191 #
3192 #
3193 #
3194 #
3195 #"
3196 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3197 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3198
3199 (define_insn "*movdf_no_e_insn_sp32"
3200 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3201 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3202 "! TARGET_FPU
3203 && ! TARGET_V9
3204 && ! TARGET_ARCH64
3205 && (register_operand (operands[0], DFmode)
3206 || register_operand (operands[1], DFmode)
3207 || fp_zero_operand (operands[1], DFmode))"
3208 "@
3209 ldd\\t%1, %0
3210 std\\t%1, %0
3211 #
3212 #
3213 #"
3214 [(set_attr "type" "load,store,*,*,*")
3215 (set_attr "length" "*,*,2,2,2")])
3216
3217 (define_insn "*movdf_no_e_insn_v9_sp32"
3218 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3219 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3220 "! TARGET_FPU
3221 && TARGET_V9
3222 && ! TARGET_ARCH64
3223 && (register_operand (operands[0], DFmode)
3224 || register_operand (operands[1], DFmode)
3225 || fp_zero_operand (operands[1], DFmode))"
3226 "@
3227 ldd\\t%1, %0
3228 std\\t%1, %0
3229 stx\\t%r1, %0
3230 #
3231 #"
3232 [(set_attr "type" "load,store,store,*,*")
3233 (set_attr "length" "*,*,*,2,2")])
3234
3235 ;; We have available v9 double floats but not 64-bit
3236 ;; integer registers and no VIS.
3237 (define_insn "*movdf_insn_v9only_novis"
3238 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3239 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3240 "TARGET_FPU
3241 && TARGET_V9
3242 && ! TARGET_VIS
3243 && ! TARGET_ARCH64
3244 && (register_operand (operands[0], DFmode)
3245 || register_operand (operands[1], DFmode)
3246 || fp_zero_operand (operands[1], DFmode))"
3247 "@
3248 fmovd\\t%1, %0
3249 ldd\\t%1, %0
3250 stx\\t%r1, %0
3251 std\\t%1, %0
3252 ldd\\t%1, %0
3253 std\\t%1, %0
3254 #
3255 #
3256 #"
3257 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3258 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3259 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3260
3261 ;; We have available v9 double floats but not 64-bit
3262 ;; integer registers but we have VIS.
3263 (define_insn "*movdf_insn_v9only_vis"
3264 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3265 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3266 "TARGET_FPU
3267 && TARGET_VIS
3268 && ! TARGET_ARCH64
3269 && (register_operand (operands[0], DFmode)
3270 || register_operand (operands[1], DFmode)
3271 || fp_zero_operand (operands[1], DFmode))"
3272 "@
3273 fzero\\t%0
3274 fmovd\\t%1, %0
3275 ldd\\t%1, %0
3276 stx\\t%r1, %0
3277 std\\t%1, %0
3278 ldd\\t%1, %0
3279 std\\t%1, %0
3280 #
3281 #
3282 #"
3283 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3284 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3285 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3286
3287 ;; We have available both v9 double floats and 64-bit
3288 ;; integer registers. No VIS though.
3289 (define_insn "*movdf_insn_sp64_novis"
3290 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3291 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3292 "TARGET_FPU
3293 && ! TARGET_VIS
3294 && TARGET_ARCH64
3295 && (register_operand (operands[0], DFmode)
3296 || register_operand (operands[1], DFmode)
3297 || fp_zero_operand (operands[1], DFmode))"
3298 "@
3299 fmovd\\t%1, %0
3300 ldd\\t%1, %0
3301 std\\t%1, %0
3302 mov\\t%r1, %0
3303 ldx\\t%1, %0
3304 stx\\t%r1, %0
3305 #"
3306 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3307 (set_attr "length" "*,*,*,*,*,*,2")
3308 (set_attr "fptype" "double,*,*,*,*,*,*")])
3309
3310 ;; We have available both v9 double floats and 64-bit
3311 ;; integer registers. And we have VIS.
3312 (define_insn "*movdf_insn_sp64_vis"
3313 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3314 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3315 "TARGET_FPU
3316 && TARGET_VIS
3317 && TARGET_ARCH64
3318 && (register_operand (operands[0], DFmode)
3319 || register_operand (operands[1], DFmode)
3320 || fp_zero_operand (operands[1], DFmode))"
3321 "@
3322 fzero\\t%0
3323 fmovd\\t%1, %0
3324 ldd\\t%1, %0
3325 std\\t%1, %0
3326 mov\\t%r1, %0
3327 ldx\\t%1, %0
3328 stx\\t%r1, %0
3329 #"
3330 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3331 (set_attr "length" "*,*,*,*,*,*,*,2")
3332 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3333
3334 (define_insn "*movdf_no_e_insn_sp64"
3335 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3336 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3337 "! TARGET_FPU
3338 && TARGET_ARCH64
3339 && (register_operand (operands[0], DFmode)
3340 || register_operand (operands[1], DFmode)
3341 || fp_zero_operand (operands[1], DFmode))"
3342 "@
3343 mov\\t%1, %0
3344 ldx\\t%1, %0
3345 stx\\t%r1, %0"
3346 [(set_attr "type" "*,load,store")])
3347
3348 (define_split
3349 [(set (match_operand:DF 0 "register_operand" "")
3350 (match_operand:DF 1 "const_double_operand" ""))]
3351 "TARGET_FPU
3352 && (GET_CODE (operands[0]) == REG
3353 && REGNO (operands[0]) < 32)
3354 && ! fp_zero_operand(operands[1], DFmode)
3355 && reload_completed"
3356 [(clobber (const_int 0))]
3357 "
3358 {
3359 REAL_VALUE_TYPE r;
3360 long l[2];
3361
3362 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3363 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3364 if (GET_CODE (operands[0]) == SUBREG)
3365 operands[0] = alter_subreg (operands[0]);
3366 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3367
3368 if (TARGET_ARCH64)
3369 {
3370 #if HOST_BITS_PER_WIDE_INT == 64
3371 HOST_WIDE_INT val;
3372
3373 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3374 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3375 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3376 #else
3377 emit_insn (gen_movdi (operands[0],
3378 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3379 l[1], l[0])));
3380 #endif
3381 }
3382 else
3383 {
3384 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3385 GEN_INT (l[0])));
3386
3387 /* Slick... but this trick loses if this subreg constant part
3388 can be done in one insn. */
3389 if (l[1] == l[0]
3390 && !(SPARC_SETHI_P (l[0])
3391 || SPARC_SIMM13_P (l[0])))
3392 {
3393 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3394 gen_highpart (SImode, operands[0])));
3395 }
3396 else
3397 {
3398 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3399 GEN_INT (l[1])));
3400 }
3401 }
3402 DONE;
3403 }")
3404
3405 ;; Ok, now the splits to handle all the multi insn and
3406 ;; mis-aligned memory address cases.
3407 ;; In these splits please take note that we must be
3408 ;; careful when V9 but not ARCH64 because the integer
3409 ;; register DFmode cases must be handled.
3410 (define_split
3411 [(set (match_operand:DF 0 "register_operand" "")
3412 (match_operand:DF 1 "register_operand" ""))]
3413 "(! TARGET_V9
3414 || (! TARGET_ARCH64
3415 && ((GET_CODE (operands[0]) == REG
3416 && REGNO (operands[0]) < 32)
3417 || (GET_CODE (operands[0]) == SUBREG
3418 && GET_CODE (SUBREG_REG (operands[0])) == REG
3419 && REGNO (SUBREG_REG (operands[0])) < 32))))
3420 && reload_completed"
3421 [(clobber (const_int 0))]
3422 "
3423 {
3424 rtx set_dest = operands[0];
3425 rtx set_src = operands[1];
3426 rtx dest1, dest2;
3427 rtx src1, src2;
3428
3429 if (GET_CODE (set_dest) == SUBREG)
3430 set_dest = alter_subreg (set_dest);
3431 if (GET_CODE (set_src) == SUBREG)
3432 set_src = alter_subreg (set_src);
3433
3434 dest1 = gen_highpart (SFmode, set_dest);
3435 dest2 = gen_lowpart (SFmode, set_dest);
3436 src1 = gen_highpart (SFmode, set_src);
3437 src2 = gen_lowpart (SFmode, set_src);
3438
3439 /* Now emit using the real source and destination we found, swapping
3440 the order if we detect overlap. */
3441 if (reg_overlap_mentioned_p (dest1, src2))
3442 {
3443 emit_insn (gen_movsf (dest2, src2));
3444 emit_insn (gen_movsf (dest1, src1));
3445 }
3446 else
3447 {
3448 emit_insn (gen_movsf (dest1, src1));
3449 emit_insn (gen_movsf (dest2, src2));
3450 }
3451 DONE;
3452 }")
3453
3454 (define_split
3455 [(set (match_operand:DF 0 "register_operand" "")
3456 (match_operand:DF 1 "memory_operand" ""))]
3457 "reload_completed
3458 && ! TARGET_ARCH64
3459 && (((REGNO (operands[0]) % 2) != 0)
3460 || ! mem_min_alignment (operands[1], 8))
3461 && offsettable_memref_p (operands[1])"
3462 [(clobber (const_int 0))]
3463 "
3464 {
3465 rtx word0 = adjust_address (operands[1], SFmode, 0);
3466 rtx word1 = adjust_address (operands[1], SFmode, 4);
3467
3468 if (GET_CODE (operands[0]) == SUBREG)
3469 operands[0] = alter_subreg (operands[0]);
3470
3471 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3472 {
3473 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3474 word1));
3475 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3476 word0));
3477 }
3478 else
3479 {
3480 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3481 word0));
3482 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3483 word1));
3484 }
3485 DONE;
3486 }")
3487
3488 (define_split
3489 [(set (match_operand:DF 0 "memory_operand" "")
3490 (match_operand:DF 1 "register_operand" ""))]
3491 "reload_completed
3492 && ! TARGET_ARCH64
3493 && (((REGNO (operands[1]) % 2) != 0)
3494 || ! mem_min_alignment (operands[0], 8))
3495 && offsettable_memref_p (operands[0])"
3496 [(clobber (const_int 0))]
3497 "
3498 {
3499 rtx word0 = adjust_address (operands[0], SFmode, 0);
3500 rtx word1 = adjust_address (operands[0], SFmode, 4);
3501
3502 if (GET_CODE (operands[1]) == SUBREG)
3503 operands[1] = alter_subreg (operands[1]);
3504 emit_insn (gen_movsf (word0,
3505 gen_highpart (SFmode, operands[1])));
3506 emit_insn (gen_movsf (word1,
3507 gen_lowpart (SFmode, operands[1])));
3508 DONE;
3509 }")
3510
3511 (define_split
3512 [(set (match_operand:DF 0 "memory_operand" "")
3513 (match_operand:DF 1 "fp_zero_operand" ""))]
3514 "reload_completed
3515 && (! TARGET_V9
3516 || (! TARGET_ARCH64
3517 && ! mem_min_alignment (operands[0], 8)))
3518 && offsettable_memref_p (operands[0])"
3519 [(clobber (const_int 0))]
3520 "
3521 {
3522 rtx dest1, dest2;
3523
3524 dest1 = adjust_address (operands[0], SFmode, 0);
3525 dest2 = adjust_address (operands[0], SFmode, 4);
3526
3527 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3528 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3529 DONE;
3530 }")
3531
3532 (define_split
3533 [(set (match_operand:DF 0 "register_operand" "")
3534 (match_operand:DF 1 "fp_zero_operand" ""))]
3535 "reload_completed
3536 && ! TARGET_ARCH64
3537 && ((GET_CODE (operands[0]) == REG
3538 && REGNO (operands[0]) < 32)
3539 || (GET_CODE (operands[0]) == SUBREG
3540 && GET_CODE (SUBREG_REG (operands[0])) == REG
3541 && REGNO (SUBREG_REG (operands[0])) < 32))"
3542 [(clobber (const_int 0))]
3543 "
3544 {
3545 rtx set_dest = operands[0];
3546 rtx dest1, dest2;
3547
3548 if (GET_CODE (set_dest) == SUBREG)
3549 set_dest = alter_subreg (set_dest);
3550 dest1 = gen_highpart (SFmode, set_dest);
3551 dest2 = gen_lowpart (SFmode, set_dest);
3552 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3553 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3554 DONE;
3555 }")
3556
3557 (define_expand "movtf"
3558 [(set (match_operand:TF 0 "general_operand" "")
3559 (match_operand:TF 1 "general_operand" ""))]
3560 ""
3561 "
3562 {
3563 /* Force TFmode constants into memory. */
3564 if (GET_CODE (operands[0]) == REG
3565 && CONSTANT_P (operands[1]))
3566 {
3567 /* emit_group_store will send such bogosity to us when it is
3568 not storing directly into memory. So fix this up to avoid
3569 crashes in output_constant_pool. */
3570 if (operands [1] == const0_rtx)
3571 operands[1] = CONST0_RTX (TFmode);
3572
3573 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3574 goto movtf_is_ok;
3575
3576 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3577 operands[1]));
3578 }
3579
3580 /* Handle MEM cases first, note that only v9 guarentees
3581 full 16-byte alignment for quads. */
3582 if (GET_CODE (operands[0]) == MEM)
3583 {
3584 if (register_operand (operands[1], TFmode)
3585 || fp_zero_operand (operands[1], TFmode))
3586 goto movtf_is_ok;
3587
3588 if (! reload_in_progress)
3589 {
3590 operands[0] = validize_mem (operands[0]);
3591 operands[1] = force_reg (TFmode, operands[1]);
3592 }
3593 }
3594
3595 /* Fixup PIC cases. */
3596 if (flag_pic)
3597 {
3598 if (CONSTANT_P (operands[1])
3599 && pic_address_needs_scratch (operands[1]))
3600 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3601
3602 if (symbolic_operand (operands[1], TFmode))
3603 {
3604 operands[1] = legitimize_pic_address (operands[1],
3605 TFmode,
3606 (reload_in_progress ?
3607 operands[0] :
3608 NULL_RTX));
3609 }
3610 }
3611
3612 movtf_is_ok:
3613 ;
3614 }")
3615
3616 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3617 ;; we must split them all. :-(
3618 (define_insn "*movtf_insn_sp32"
3619 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3620 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3621 "TARGET_FPU
3622 && ! TARGET_VIS
3623 && ! TARGET_ARCH64
3624 && (register_operand (operands[0], TFmode)
3625 || register_operand (operands[1], TFmode)
3626 || fp_zero_operand (operands[1], TFmode))"
3627 "#"
3628 [(set_attr "length" "4")])
3629
3630 (define_insn "*movtf_insn_vis_sp32"
3631 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3632 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3633 "TARGET_FPU
3634 && TARGET_VIS
3635 && ! TARGET_ARCH64
3636 && (register_operand (operands[0], TFmode)
3637 || register_operand (operands[1], TFmode)
3638 || fp_zero_operand (operands[1], TFmode))"
3639 "#"
3640 [(set_attr "length" "4")])
3641
3642 ;; Exactly the same as above, except that all `e' cases are deleted.
3643 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3644 ;; when -mno-fpu.
3645
3646 (define_insn "*movtf_no_e_insn_sp32"
3647 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3648 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3649 "! TARGET_FPU
3650 && ! TARGET_ARCH64
3651 && (register_operand (operands[0], TFmode)
3652 || register_operand (operands[1], TFmode)
3653 || fp_zero_operand (operands[1], TFmode))"
3654 "#"
3655 [(set_attr "length" "4")])
3656
3657 ;; Now handle the float reg cases directly when arch64,
3658 ;; hard_quad, and proper reg number alignment are all true.
3659 (define_insn "*movtf_insn_hq_sp64"
3660 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3661 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3662 "TARGET_FPU
3663 && ! TARGET_VIS
3664 && TARGET_ARCH64
3665 && TARGET_HARD_QUAD
3666 && (register_operand (operands[0], TFmode)
3667 || register_operand (operands[1], TFmode)
3668 || fp_zero_operand (operands[1], TFmode))"
3669 "@
3670 fmovq\\t%1, %0
3671 ldq\\t%1, %0
3672 stq\\t%1, %0
3673 #
3674 #"
3675 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3676 (set_attr "length" "*,*,*,2,2")])
3677
3678 (define_insn "*movtf_insn_hq_vis_sp64"
3679 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3680 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3681 "TARGET_FPU
3682 && TARGET_VIS
3683 && TARGET_ARCH64
3684 && TARGET_HARD_QUAD
3685 && (register_operand (operands[0], TFmode)
3686 || register_operand (operands[1], TFmode)
3687 || fp_zero_operand (operands[1], TFmode))"
3688 "@
3689 fmovq\\t%1, %0
3690 ldq\\t%1, %0
3691 stq\\t%1, %0
3692 #
3693 #
3694 #"
3695 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3696 (set_attr "length" "*,*,*,2,2,2")])
3697
3698 ;; Now we allow the integer register cases even when
3699 ;; only arch64 is true.
3700 (define_insn "*movtf_insn_sp64"
3701 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3702 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3703 "TARGET_FPU
3704 && ! TARGET_VIS
3705 && TARGET_ARCH64
3706 && ! TARGET_HARD_QUAD
3707 && (register_operand (operands[0], TFmode)
3708 || register_operand (operands[1], TFmode)
3709 || fp_zero_operand (operands[1], TFmode))"
3710 "#"
3711 [(set_attr "length" "2")])
3712
3713 (define_insn "*movtf_insn_vis_sp64"
3714 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3715 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3716 "TARGET_FPU
3717 && TARGET_VIS
3718 && TARGET_ARCH64
3719 && ! TARGET_HARD_QUAD
3720 && (register_operand (operands[0], TFmode)
3721 || register_operand (operands[1], TFmode)
3722 || fp_zero_operand (operands[1], TFmode))"
3723 "#"
3724 [(set_attr "length" "2")])
3725
3726 (define_insn "*movtf_no_e_insn_sp64"
3727 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3728 (match_operand:TF 1 "input_operand" "orG,rG"))]
3729 "! TARGET_FPU
3730 && TARGET_ARCH64
3731 && (register_operand (operands[0], TFmode)
3732 || register_operand (operands[1], TFmode)
3733 || fp_zero_operand (operands[1], TFmode))"
3734 "#"
3735 [(set_attr "length" "2")])
3736
3737 ;; Now all the splits to handle multi-insn TF mode moves.
3738 (define_split
3739 [(set (match_operand:TF 0 "register_operand" "")
3740 (match_operand:TF 1 "register_operand" ""))]
3741 "reload_completed
3742 && (! TARGET_ARCH64
3743 || (TARGET_FPU
3744 && ! TARGET_HARD_QUAD))"
3745 [(clobber (const_int 0))]
3746 "
3747 {
3748 rtx set_dest = operands[0];
3749 rtx set_src = operands[1];
3750 rtx dest1, dest2;
3751 rtx src1, src2;
3752
3753 if (GET_CODE (set_dest) == SUBREG)
3754 set_dest = alter_subreg (set_dest);
3755 if (GET_CODE (set_src) == SUBREG)
3756 set_src = alter_subreg (set_src);
3757
3758 dest1 = gen_df_reg (set_dest, 0);
3759 dest2 = gen_df_reg (set_dest, 1);
3760 src1 = gen_df_reg (set_src, 0);
3761 src2 = gen_df_reg (set_src, 1);
3762
3763 /* Now emit using the real source and destination we found, swapping
3764 the order if we detect overlap. */
3765 if (reg_overlap_mentioned_p (dest1, src2))
3766 {
3767 emit_insn (gen_movdf (dest2, src2));
3768 emit_insn (gen_movdf (dest1, src1));
3769 }
3770 else
3771 {
3772 emit_insn (gen_movdf (dest1, src1));
3773 emit_insn (gen_movdf (dest2, src2));
3774 }
3775 DONE;
3776 }")
3777
3778 (define_split
3779 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3780 (match_operand:TF 1 "fp_zero_operand" ""))]
3781 "reload_completed"
3782 [(clobber (const_int 0))]
3783 "
3784 {
3785 rtx set_dest = operands[0];
3786 rtx dest1, dest2;
3787
3788 switch (GET_CODE (set_dest))
3789 {
3790 case SUBREG:
3791 set_dest = alter_subreg (set_dest);
3792 /* FALLTHROUGH */
3793 case REG:
3794 dest1 = gen_df_reg (set_dest, 0);
3795 dest2 = gen_df_reg (set_dest, 1);
3796 break;
3797 case MEM:
3798 dest1 = adjust_address (set_dest, DFmode, 0);
3799 dest2 = adjust_address (set_dest, DFmode, 8);
3800 break;
3801 default:
3802 abort ();
3803 }
3804
3805 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3806 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3807 DONE;
3808 }")
3809
3810 (define_split
3811 [(set (match_operand:TF 0 "register_operand" "")
3812 (match_operand:TF 1 "memory_operand" ""))]
3813 "(reload_completed
3814 && offsettable_memref_p (operands[1]))"
3815 [(clobber (const_int 0))]
3816 "
3817 {
3818 rtx word0 = adjust_address (operands[1], DFmode, 0);
3819 rtx word1 = adjust_address (operands[1], DFmode, 8);
3820 rtx set_dest, dest1, dest2;
3821
3822 set_dest = operands[0];
3823 if (GET_CODE (set_dest) == SUBREG)
3824 set_dest = alter_subreg (set_dest);
3825
3826 dest1 = gen_df_reg (set_dest, 0);
3827 dest2 = gen_df_reg (set_dest, 1);
3828
3829 /* Now output, ordering such that we don't clobber any registers
3830 mentioned in the address. */
3831 if (reg_overlap_mentioned_p (dest1, word1))
3832
3833 {
3834 emit_insn (gen_movdf (dest2, word1));
3835 emit_insn (gen_movdf (dest1, word0));
3836 }
3837 else
3838 {
3839 emit_insn (gen_movdf (dest1, word0));
3840 emit_insn (gen_movdf (dest2, word1));
3841 }
3842 DONE;
3843 }")
3844
3845 (define_split
3846 [(set (match_operand:TF 0 "memory_operand" "")
3847 (match_operand:TF 1 "register_operand" ""))]
3848 "(reload_completed
3849 && offsettable_memref_p (operands[0]))"
3850 [(clobber (const_int 0))]
3851 "
3852 {
3853 rtx set_src = operands[1];
3854 if (GET_CODE (set_src) == SUBREG)
3855 set_src = alter_subreg (set_src);
3856
3857 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3858 gen_df_reg (set_src, 0)));
3859 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3860 gen_df_reg (set_src, 1)));
3861 DONE;
3862 }")
3863 \f
3864 ;; Sparc V9 conditional move instructions.
3865
3866 ;; We can handle larger constants here for some flavors, but for now we keep
3867 ;; it simple and only allow those constants supported by all flavours.
3868 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3869 ;; 3 contains the constant if one is present, but we handle either for
3870 ;; generality (sparc.c puts a constant in operand 2).
3871
3872 (define_expand "movqicc"
3873 [(set (match_operand:QI 0 "register_operand" "")
3874 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3875 (match_operand:QI 2 "arith10_operand" "")
3876 (match_operand:QI 3 "arith10_operand" "")))]
3877 "TARGET_V9"
3878 "
3879 {
3880 enum rtx_code code = GET_CODE (operands[1]);
3881
3882 if (GET_MODE (sparc_compare_op0) == DImode
3883 && ! TARGET_ARCH64)
3884 FAIL;
3885
3886 if (sparc_compare_op1 == const0_rtx
3887 && GET_CODE (sparc_compare_op0) == REG
3888 && GET_MODE (sparc_compare_op0) == DImode
3889 && v9_regcmp_p (code))
3890 {
3891 operands[1] = gen_rtx_fmt_ee (code, DImode,
3892 sparc_compare_op0, sparc_compare_op1);
3893 }
3894 else
3895 {
3896 rtx cc_reg = gen_compare_reg (code,
3897 sparc_compare_op0, sparc_compare_op1);
3898 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3899 }
3900 }")
3901
3902 (define_expand "movhicc"
3903 [(set (match_operand:HI 0 "register_operand" "")
3904 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3905 (match_operand:HI 2 "arith10_operand" "")
3906 (match_operand:HI 3 "arith10_operand" "")))]
3907 "TARGET_V9"
3908 "
3909 {
3910 enum rtx_code code = GET_CODE (operands[1]);
3911
3912 if (GET_MODE (sparc_compare_op0) == DImode
3913 && ! TARGET_ARCH64)
3914 FAIL;
3915
3916 if (sparc_compare_op1 == const0_rtx
3917 && GET_CODE (sparc_compare_op0) == REG
3918 && GET_MODE (sparc_compare_op0) == DImode
3919 && v9_regcmp_p (code))
3920 {
3921 operands[1] = gen_rtx_fmt_ee (code, DImode,
3922 sparc_compare_op0, sparc_compare_op1);
3923 }
3924 else
3925 {
3926 rtx cc_reg = gen_compare_reg (code,
3927 sparc_compare_op0, sparc_compare_op1);
3928 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3929 }
3930 }")
3931
3932 (define_expand "movsicc"
3933 [(set (match_operand:SI 0 "register_operand" "")
3934 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3935 (match_operand:SI 2 "arith10_operand" "")
3936 (match_operand:SI 3 "arith10_operand" "")))]
3937 "TARGET_V9"
3938 "
3939 {
3940 enum rtx_code code = GET_CODE (operands[1]);
3941 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3942
3943 if (sparc_compare_op1 == const0_rtx
3944 && GET_CODE (sparc_compare_op0) == REG
3945 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3946 {
3947 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3948 sparc_compare_op0, sparc_compare_op1);
3949 }
3950 else
3951 {
3952 rtx cc_reg = gen_compare_reg (code,
3953 sparc_compare_op0, sparc_compare_op1);
3954 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3955 cc_reg, const0_rtx);
3956 }
3957 }")
3958
3959 (define_expand "movdicc"
3960 [(set (match_operand:DI 0 "register_operand" "")
3961 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3962 (match_operand:DI 2 "arith10_double_operand" "")
3963 (match_operand:DI 3 "arith10_double_operand" "")))]
3964 "TARGET_ARCH64"
3965 "
3966 {
3967 enum rtx_code code = GET_CODE (operands[1]);
3968
3969 if (sparc_compare_op1 == const0_rtx
3970 && GET_CODE (sparc_compare_op0) == REG
3971 && GET_MODE (sparc_compare_op0) == DImode
3972 && v9_regcmp_p (code))
3973 {
3974 operands[1] = gen_rtx_fmt_ee (code, DImode,
3975 sparc_compare_op0, sparc_compare_op1);
3976 }
3977 else
3978 {
3979 rtx cc_reg = gen_compare_reg (code,
3980 sparc_compare_op0, sparc_compare_op1);
3981 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3982 cc_reg, const0_rtx);
3983 }
3984 }")
3985
3986 (define_expand "movsfcc"
3987 [(set (match_operand:SF 0 "register_operand" "")
3988 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3989 (match_operand:SF 2 "register_operand" "")
3990 (match_operand:SF 3 "register_operand" "")))]
3991 "TARGET_V9 && TARGET_FPU"
3992 "
3993 {
3994 enum rtx_code code = GET_CODE (operands[1]);
3995
3996 if (GET_MODE (sparc_compare_op0) == DImode
3997 && ! TARGET_ARCH64)
3998 FAIL;
3999
4000 if (sparc_compare_op1 == const0_rtx
4001 && GET_CODE (sparc_compare_op0) == REG
4002 && GET_MODE (sparc_compare_op0) == DImode
4003 && v9_regcmp_p (code))
4004 {
4005 operands[1] = gen_rtx_fmt_ee (code, DImode,
4006 sparc_compare_op0, sparc_compare_op1);
4007 }
4008 else
4009 {
4010 rtx cc_reg = gen_compare_reg (code,
4011 sparc_compare_op0, sparc_compare_op1);
4012 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4013 }
4014 }")
4015
4016 (define_expand "movdfcc"
4017 [(set (match_operand:DF 0 "register_operand" "")
4018 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4019 (match_operand:DF 2 "register_operand" "")
4020 (match_operand:DF 3 "register_operand" "")))]
4021 "TARGET_V9 && TARGET_FPU"
4022 "
4023 {
4024 enum rtx_code code = GET_CODE (operands[1]);
4025
4026 if (GET_MODE (sparc_compare_op0) == DImode
4027 && ! TARGET_ARCH64)
4028 FAIL;
4029
4030 if (sparc_compare_op1 == const0_rtx
4031 && GET_CODE (sparc_compare_op0) == REG
4032 && GET_MODE (sparc_compare_op0) == DImode
4033 && v9_regcmp_p (code))
4034 {
4035 operands[1] = gen_rtx_fmt_ee (code, DImode,
4036 sparc_compare_op0, sparc_compare_op1);
4037 }
4038 else
4039 {
4040 rtx cc_reg = gen_compare_reg (code,
4041 sparc_compare_op0, sparc_compare_op1);
4042 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4043 }
4044 }")
4045
4046 (define_expand "movtfcc"
4047 [(set (match_operand:TF 0 "register_operand" "")
4048 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4049 (match_operand:TF 2 "register_operand" "")
4050 (match_operand:TF 3 "register_operand" "")))]
4051 "TARGET_V9 && TARGET_FPU"
4052 "
4053 {
4054 enum rtx_code code = GET_CODE (operands[1]);
4055
4056 if (GET_MODE (sparc_compare_op0) == DImode
4057 && ! TARGET_ARCH64)
4058 FAIL;
4059
4060 if (sparc_compare_op1 == const0_rtx
4061 && GET_CODE (sparc_compare_op0) == REG
4062 && GET_MODE (sparc_compare_op0) == DImode
4063 && v9_regcmp_p (code))
4064 {
4065 operands[1] = gen_rtx_fmt_ee (code, DImode,
4066 sparc_compare_op0, sparc_compare_op1);
4067 }
4068 else
4069 {
4070 rtx cc_reg = gen_compare_reg (code,
4071 sparc_compare_op0, sparc_compare_op1);
4072 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4073 }
4074 }")
4075
4076 ;; Conditional move define_insns.
4077
4078 (define_insn "*movqi_cc_sp64"
4079 [(set (match_operand:QI 0 "register_operand" "=r,r")
4080 (if_then_else:QI (match_operator 1 "comparison_operator"
4081 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4082 (const_int 0)])
4083 (match_operand:QI 3 "arith11_operand" "rL,0")
4084 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4085 "TARGET_V9"
4086 "@
4087 mov%C1\\t%x2, %3, %0
4088 mov%c1\\t%x2, %4, %0"
4089 [(set_attr "type" "cmove")])
4090
4091 (define_insn "*movhi_cc_sp64"
4092 [(set (match_operand:HI 0 "register_operand" "=r,r")
4093 (if_then_else:HI (match_operator 1 "comparison_operator"
4094 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4095 (const_int 0)])
4096 (match_operand:HI 3 "arith11_operand" "rL,0")
4097 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4098 "TARGET_V9"
4099 "@
4100 mov%C1\\t%x2, %3, %0
4101 mov%c1\\t%x2, %4, %0"
4102 [(set_attr "type" "cmove")])
4103
4104 (define_insn "*movsi_cc_sp64"
4105 [(set (match_operand:SI 0 "register_operand" "=r,r")
4106 (if_then_else:SI (match_operator 1 "comparison_operator"
4107 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4108 (const_int 0)])
4109 (match_operand:SI 3 "arith11_operand" "rL,0")
4110 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4111 "TARGET_V9"
4112 "@
4113 mov%C1\\t%x2, %3, %0
4114 mov%c1\\t%x2, %4, %0"
4115 [(set_attr "type" "cmove")])
4116
4117 ;; ??? The constraints of operands 3,4 need work.
4118 (define_insn "*movdi_cc_sp64"
4119 [(set (match_operand:DI 0 "register_operand" "=r,r")
4120 (if_then_else:DI (match_operator 1 "comparison_operator"
4121 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4122 (const_int 0)])
4123 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4124 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4125 "TARGET_ARCH64"
4126 "@
4127 mov%C1\\t%x2, %3, %0
4128 mov%c1\\t%x2, %4, %0"
4129 [(set_attr "type" "cmove")])
4130
4131 (define_insn "*movdi_cc_sp64_trunc"
4132 [(set (match_operand:SI 0 "register_operand" "=r,r")
4133 (if_then_else:SI (match_operator 1 "comparison_operator"
4134 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4135 (const_int 0)])
4136 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4137 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4138 "TARGET_ARCH64"
4139 "@
4140 mov%C1\\t%x2, %3, %0
4141 mov%c1\\t%x2, %4, %0"
4142 [(set_attr "type" "cmove")])
4143
4144 (define_insn "*movsf_cc_sp64"
4145 [(set (match_operand:SF 0 "register_operand" "=f,f")
4146 (if_then_else:SF (match_operator 1 "comparison_operator"
4147 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4148 (const_int 0)])
4149 (match_operand:SF 3 "register_operand" "f,0")
4150 (match_operand:SF 4 "register_operand" "0,f")))]
4151 "TARGET_V9 && TARGET_FPU"
4152 "@
4153 fmovs%C1\\t%x2, %3, %0
4154 fmovs%c1\\t%x2, %4, %0"
4155 [(set_attr "type" "fpcmove")])
4156
4157 (define_insn "movdf_cc_sp64"
4158 [(set (match_operand:DF 0 "register_operand" "=e,e")
4159 (if_then_else:DF (match_operator 1 "comparison_operator"
4160 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4161 (const_int 0)])
4162 (match_operand:DF 3 "register_operand" "e,0")
4163 (match_operand:DF 4 "register_operand" "0,e")))]
4164 "TARGET_V9 && TARGET_FPU"
4165 "@
4166 fmovd%C1\\t%x2, %3, %0
4167 fmovd%c1\\t%x2, %4, %0"
4168 [(set_attr "type" "fpcmove")
4169 (set_attr "fptype" "double")])
4170
4171 (define_insn "*movtf_cc_hq_sp64"
4172 [(set (match_operand:TF 0 "register_operand" "=e,e")
4173 (if_then_else:TF (match_operator 1 "comparison_operator"
4174 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4175 (const_int 0)])
4176 (match_operand:TF 3 "register_operand" "e,0")
4177 (match_operand:TF 4 "register_operand" "0,e")))]
4178 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4179 "@
4180 fmovq%C1\\t%x2, %3, %0
4181 fmovq%c1\\t%x2, %4, %0"
4182 [(set_attr "type" "fpcmove")])
4183
4184 (define_insn "*movtf_cc_sp64"
4185 [(set (match_operand:TF 0 "register_operand" "=e,e")
4186 (if_then_else:TF (match_operator 1 "comparison_operator"
4187 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4188 (const_int 0)])
4189 (match_operand:TF 3 "register_operand" "e,0")
4190 (match_operand:TF 4 "register_operand" "0,e")))]
4191 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4192 "#"
4193 [(set_attr "length" "2")])
4194
4195 (define_split
4196 [(set (match_operand:TF 0 "register_operand" "")
4197 (if_then_else:TF (match_operator 1 "comparison_operator"
4198 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4199 (const_int 0)])
4200 (match_operand:TF 3 "register_operand" "")
4201 (match_operand:TF 4 "register_operand" "")))]
4202 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4203 [(clobber (const_int 0))]
4204 "
4205 {
4206 rtx set_dest = operands[0];
4207 rtx set_srca = operands[3];
4208 rtx set_srcb = operands[4];
4209 int third = rtx_equal_p (set_dest, set_srca);
4210 rtx dest1, dest2;
4211 rtx srca1, srca2, srcb1, srcb2;
4212
4213 if (GET_CODE (set_dest) == SUBREG)
4214 set_dest = alter_subreg (set_dest);
4215 if (GET_CODE (set_srca) == SUBREG)
4216 set_srca = alter_subreg (set_srca);
4217 if (GET_CODE (set_srcb) == SUBREG)
4218 set_srcb = alter_subreg (set_srcb);
4219
4220 dest1 = gen_df_reg (set_dest, 0);
4221 dest2 = gen_df_reg (set_dest, 1);
4222 srca1 = gen_df_reg (set_srca, 0);
4223 srca2 = gen_df_reg (set_srca, 1);
4224 srcb1 = gen_df_reg (set_srcb, 0);
4225 srcb2 = gen_df_reg (set_srcb, 1);
4226
4227 /* Now emit using the real source and destination we found, swapping
4228 the order if we detect overlap. */
4229 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4230 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4231 {
4232 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4233 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4234 }
4235 else
4236 {
4237 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4238 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4239 }
4240 DONE;
4241 }")
4242
4243 (define_insn "*movqi_cc_reg_sp64"
4244 [(set (match_operand:QI 0 "register_operand" "=r,r")
4245 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4246 [(match_operand:DI 2 "register_operand" "r,r")
4247 (const_int 0)])
4248 (match_operand:QI 3 "arith10_operand" "rM,0")
4249 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4250 "TARGET_ARCH64"
4251 "@
4252 movr%D1\\t%2, %r3, %0
4253 movr%d1\\t%2, %r4, %0"
4254 [(set_attr "type" "cmove")])
4255
4256 (define_insn "*movhi_cc_reg_sp64"
4257 [(set (match_operand:HI 0 "register_operand" "=r,r")
4258 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4259 [(match_operand:DI 2 "register_operand" "r,r")
4260 (const_int 0)])
4261 (match_operand:HI 3 "arith10_operand" "rM,0")
4262 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4263 "TARGET_ARCH64"
4264 "@
4265 movr%D1\\t%2, %r3, %0
4266 movr%d1\\t%2, %r4, %0"
4267 [(set_attr "type" "cmove")])
4268
4269 (define_insn "*movsi_cc_reg_sp64"
4270 [(set (match_operand:SI 0 "register_operand" "=r,r")
4271 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4272 [(match_operand:DI 2 "register_operand" "r,r")
4273 (const_int 0)])
4274 (match_operand:SI 3 "arith10_operand" "rM,0")
4275 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4276 "TARGET_ARCH64"
4277 "@
4278 movr%D1\\t%2, %r3, %0
4279 movr%d1\\t%2, %r4, %0"
4280 [(set_attr "type" "cmove")])
4281
4282 ;; ??? The constraints of operands 3,4 need work.
4283 (define_insn "*movdi_cc_reg_sp64"
4284 [(set (match_operand:DI 0 "register_operand" "=r,r")
4285 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4286 [(match_operand:DI 2 "register_operand" "r,r")
4287 (const_int 0)])
4288 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4289 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4290 "TARGET_ARCH64"
4291 "@
4292 movr%D1\\t%2, %r3, %0
4293 movr%d1\\t%2, %r4, %0"
4294 [(set_attr "type" "cmove")])
4295
4296 (define_insn "*movdi_cc_reg_sp64_trunc"
4297 [(set (match_operand:SI 0 "register_operand" "=r,r")
4298 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4299 [(match_operand:DI 2 "register_operand" "r,r")
4300 (const_int 0)])
4301 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4302 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4303 "TARGET_ARCH64"
4304 "@
4305 movr%D1\\t%2, %r3, %0
4306 movr%d1\\t%2, %r4, %0"
4307 [(set_attr "type" "cmove")])
4308
4309 (define_insn "*movsf_cc_reg_sp64"
4310 [(set (match_operand:SF 0 "register_operand" "=f,f")
4311 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4312 [(match_operand:DI 2 "register_operand" "r,r")
4313 (const_int 0)])
4314 (match_operand:SF 3 "register_operand" "f,0")
4315 (match_operand:SF 4 "register_operand" "0,f")))]
4316 "TARGET_ARCH64 && TARGET_FPU"
4317 "@
4318 fmovrs%D1\\t%2, %3, %0
4319 fmovrs%d1\\t%2, %4, %0"
4320 [(set_attr "type" "fpcmove")])
4321
4322 (define_insn "movdf_cc_reg_sp64"
4323 [(set (match_operand:DF 0 "register_operand" "=e,e")
4324 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4325 [(match_operand:DI 2 "register_operand" "r,r")
4326 (const_int 0)])
4327 (match_operand:DF 3 "register_operand" "e,0")
4328 (match_operand:DF 4 "register_operand" "0,e")))]
4329 "TARGET_ARCH64 && TARGET_FPU"
4330 "@
4331 fmovrd%D1\\t%2, %3, %0
4332 fmovrd%d1\\t%2, %4, %0"
4333 [(set_attr "type" "fpcmove")
4334 (set_attr "fptype" "double")])
4335
4336 (define_insn "*movtf_cc_reg_hq_sp64"
4337 [(set (match_operand:TF 0 "register_operand" "=e,e")
4338 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4339 [(match_operand:DI 2 "register_operand" "r,r")
4340 (const_int 0)])
4341 (match_operand:TF 3 "register_operand" "e,0")
4342 (match_operand:TF 4 "register_operand" "0,e")))]
4343 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4344 "@
4345 fmovrq%D1\\t%2, %3, %0
4346 fmovrq%d1\\t%2, %4, %0"
4347 [(set_attr "type" "fpcmove")])
4348
4349 (define_insn "*movtf_cc_reg_sp64"
4350 [(set (match_operand:TF 0 "register_operand" "=e,e")
4351 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4352 [(match_operand:DI 2 "register_operand" "r,r")
4353 (const_int 0)])
4354 (match_operand:TF 3 "register_operand" "e,0")
4355 (match_operand:TF 4 "register_operand" "0,e")))]
4356 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4357 "#"
4358 [(set_attr "length" "2")])
4359
4360 (define_split
4361 [(set (match_operand:TF 0 "register_operand" "")
4362 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4363 [(match_operand:DI 2 "register_operand" "")
4364 (const_int 0)])
4365 (match_operand:TF 3 "register_operand" "")
4366 (match_operand:TF 4 "register_operand" "")))]
4367 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4368 [(clobber (const_int 0))]
4369 "
4370 {
4371 rtx set_dest = operands[0];
4372 rtx set_srca = operands[3];
4373 rtx set_srcb = operands[4];
4374 int third = rtx_equal_p (set_dest, set_srca);
4375 rtx dest1, dest2;
4376 rtx srca1, srca2, srcb1, srcb2;
4377
4378 if (GET_CODE (set_dest) == SUBREG)
4379 set_dest = alter_subreg (set_dest);
4380 if (GET_CODE (set_srca) == SUBREG)
4381 set_srca = alter_subreg (set_srca);
4382 if (GET_CODE (set_srcb) == SUBREG)
4383 set_srcb = alter_subreg (set_srcb);
4384
4385 dest1 = gen_df_reg (set_dest, 0);
4386 dest2 = gen_df_reg (set_dest, 1);
4387 srca1 = gen_df_reg (set_srca, 0);
4388 srca2 = gen_df_reg (set_srca, 1);
4389 srcb1 = gen_df_reg (set_srcb, 0);
4390 srcb2 = gen_df_reg (set_srcb, 1);
4391
4392 /* Now emit using the real source and destination we found, swapping
4393 the order if we detect overlap. */
4394 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4395 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4396 {
4397 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4398 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4399 }
4400 else
4401 {
4402 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4403 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4404 }
4405 DONE;
4406 }")
4407
4408 \f
4409 ;;- zero extension instructions
4410
4411 ;; These patterns originally accepted general_operands, however, slightly
4412 ;; better code is generated by only accepting register_operands, and then
4413 ;; letting combine generate the ldu[hb] insns.
4414
4415 (define_expand "zero_extendhisi2"
4416 [(set (match_operand:SI 0 "register_operand" "")
4417 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4418 ""
4419 "
4420 {
4421 rtx temp = gen_reg_rtx (SImode);
4422 rtx shift_16 = GEN_INT (16);
4423 int op1_subbyte = 0;
4424
4425 if (GET_CODE (operand1) == SUBREG)
4426 {
4427 op1_subbyte = SUBREG_BYTE (operand1);
4428 op1_subbyte /= GET_MODE_SIZE (SImode);
4429 op1_subbyte *= GET_MODE_SIZE (SImode);
4430 operand1 = XEXP (operand1, 0);
4431 }
4432
4433 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4434 shift_16));
4435 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4436 DONE;
4437 }")
4438
4439 (define_insn "*zero_extendhisi2_insn"
4440 [(set (match_operand:SI 0 "register_operand" "=r")
4441 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4442 ""
4443 "lduh\\t%1, %0"
4444 [(set_attr "type" "load")])
4445
4446 (define_expand "zero_extendqihi2"
4447 [(set (match_operand:HI 0 "register_operand" "")
4448 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4449 ""
4450 "")
4451
4452 (define_insn "*zero_extendqihi2_insn"
4453 [(set (match_operand:HI 0 "register_operand" "=r,r")
4454 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4455 "GET_CODE (operands[1]) != CONST_INT"
4456 "@
4457 and\\t%1, 0xff, %0
4458 ldub\\t%1, %0"
4459 [(set_attr "type" "*,load")])
4460
4461 (define_expand "zero_extendqisi2"
4462 [(set (match_operand:SI 0 "register_operand" "")
4463 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4464 ""
4465 "")
4466
4467 (define_insn "*zero_extendqisi2_insn"
4468 [(set (match_operand:SI 0 "register_operand" "=r,r")
4469 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4470 "GET_CODE (operands[1]) != CONST_INT"
4471 "@
4472 and\\t%1, 0xff, %0
4473 ldub\\t%1, %0"
4474 [(set_attr "type" "*,load")])
4475
4476 (define_expand "zero_extendqidi2"
4477 [(set (match_operand:DI 0 "register_operand" "")
4478 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4479 "TARGET_ARCH64"
4480 "")
4481
4482 (define_insn "*zero_extendqidi2_insn"
4483 [(set (match_operand:DI 0 "register_operand" "=r,r")
4484 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4485 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4486 "@
4487 and\\t%1, 0xff, %0
4488 ldub\\t%1, %0"
4489 [(set_attr "type" "*,load")])
4490
4491 (define_expand "zero_extendhidi2"
4492 [(set (match_operand:DI 0 "register_operand" "")
4493 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4494 "TARGET_ARCH64"
4495 "
4496 {
4497 rtx temp = gen_reg_rtx (DImode);
4498 rtx shift_48 = GEN_INT (48);
4499 int op1_subbyte = 0;
4500
4501 if (GET_CODE (operand1) == SUBREG)
4502 {
4503 op1_subbyte = SUBREG_BYTE (operand1);
4504 op1_subbyte /= GET_MODE_SIZE (DImode);
4505 op1_subbyte *= GET_MODE_SIZE (DImode);
4506 operand1 = XEXP (operand1, 0);
4507 }
4508
4509 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4510 shift_48));
4511 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4512 DONE;
4513 }")
4514
4515 (define_insn "*zero_extendhidi2_insn"
4516 [(set (match_operand:DI 0 "register_operand" "=r")
4517 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4518 "TARGET_ARCH64"
4519 "lduh\\t%1, %0"
4520 [(set_attr "type" "load")])
4521
4522
4523 ;; ??? Write truncdisi pattern using sra?
4524
4525 (define_expand "zero_extendsidi2"
4526 [(set (match_operand:DI 0 "register_operand" "")
4527 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4528 ""
4529 "")
4530
4531 (define_insn "*zero_extendsidi2_insn_sp64"
4532 [(set (match_operand:DI 0 "register_operand" "=r,r")
4533 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4534 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4535 "@
4536 srl\\t%1, 0, %0
4537 lduw\\t%1, %0"
4538 [(set_attr "type" "shift,load")])
4539
4540 (define_insn "*zero_extendsidi2_insn_sp32"
4541 [(set (match_operand:DI 0 "register_operand" "=r")
4542 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4543 "! TARGET_ARCH64"
4544 "#"
4545 [(set_attr "length" "2")])
4546
4547 (define_split
4548 [(set (match_operand:DI 0 "register_operand" "")
4549 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4550 "! TARGET_ARCH64 && reload_completed"
4551 [(set (match_dup 2) (match_dup 3))
4552 (set (match_dup 4) (match_dup 5))]
4553 "
4554 {
4555 rtx dest1, dest2;
4556
4557 if (GET_CODE (operands[0]) == SUBREG)
4558 operands[0] = alter_subreg (operands[0]);
4559
4560 dest1 = gen_highpart (SImode, operands[0]);
4561 dest2 = gen_lowpart (SImode, operands[0]);
4562
4563 /* Swap the order in case of overlap. */
4564 if (REGNO (dest1) == REGNO (operands[1]))
4565 {
4566 operands[2] = dest2;
4567 operands[3] = operands[1];
4568 operands[4] = dest1;
4569 operands[5] = const0_rtx;
4570 }
4571 else
4572 {
4573 operands[2] = dest1;
4574 operands[3] = const0_rtx;
4575 operands[4] = dest2;
4576 operands[5] = operands[1];
4577 }
4578 }")
4579
4580 ;; Simplify comparisons of extended values.
4581
4582 (define_insn "*cmp_zero_extendqisi2"
4583 [(set (reg:CC 100)
4584 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4585 (const_int 0)))]
4586 ""
4587 "andcc\\t%0, 0xff, %%g0"
4588 [(set_attr "type" "compare")])
4589
4590 (define_insn "*cmp_zero_qi"
4591 [(set (reg:CC 100)
4592 (compare:CC (match_operand:QI 0 "register_operand" "r")
4593 (const_int 0)))]
4594 ""
4595 "andcc\\t%0, 0xff, %%g0"
4596 [(set_attr "type" "compare")])
4597
4598 (define_insn "*cmp_zero_extendqisi2_set"
4599 [(set (reg:CC 100)
4600 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4601 (const_int 0)))
4602 (set (match_operand:SI 0 "register_operand" "=r")
4603 (zero_extend:SI (match_dup 1)))]
4604 ""
4605 "andcc\\t%1, 0xff, %0"
4606 [(set_attr "type" "compare")])
4607
4608 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4609 [(set (reg:CC 100)
4610 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4611 (const_int 255))
4612 (const_int 0)))
4613 (set (match_operand:SI 0 "register_operand" "=r")
4614 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4615 ""
4616 "andcc\\t%1, 0xff, %0"
4617 [(set_attr "type" "compare")])
4618
4619 (define_insn "*cmp_zero_extendqidi2"
4620 [(set (reg:CCX 100)
4621 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4622 (const_int 0)))]
4623 "TARGET_ARCH64"
4624 "andcc\\t%0, 0xff, %%g0"
4625 [(set_attr "type" "compare")])
4626
4627 (define_insn "*cmp_zero_qi_sp64"
4628 [(set (reg:CCX 100)
4629 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4630 (const_int 0)))]
4631 "TARGET_ARCH64"
4632 "andcc\\t%0, 0xff, %%g0"
4633 [(set_attr "type" "compare")])
4634
4635 (define_insn "*cmp_zero_extendqidi2_set"
4636 [(set (reg:CCX 100)
4637 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4638 (const_int 0)))
4639 (set (match_operand:DI 0 "register_operand" "=r")
4640 (zero_extend:DI (match_dup 1)))]
4641 "TARGET_ARCH64"
4642 "andcc\\t%1, 0xff, %0"
4643 [(set_attr "type" "compare")])
4644
4645 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4646 [(set (reg:CCX 100)
4647 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4648 (const_int 255))
4649 (const_int 0)))
4650 (set (match_operand:DI 0 "register_operand" "=r")
4651 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4652 "TARGET_ARCH64"
4653 "andcc\\t%1, 0xff, %0"
4654 [(set_attr "type" "compare")])
4655
4656 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4657
4658 (define_insn "*cmp_siqi_trunc"
4659 [(set (reg:CC 100)
4660 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4661 (const_int 0)))]
4662 ""
4663 "andcc\\t%0, 0xff, %%g0"
4664 [(set_attr "type" "compare")])
4665
4666 (define_insn "*cmp_siqi_trunc_set"
4667 [(set (reg:CC 100)
4668 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4669 (const_int 0)))
4670 (set (match_operand:QI 0 "register_operand" "=r")
4671 (subreg:QI (match_dup 1) 3))]
4672 ""
4673 "andcc\\t%1, 0xff, %0"
4674 [(set_attr "type" "compare")])
4675
4676 (define_insn "*cmp_diqi_trunc"
4677 [(set (reg:CC 100)
4678 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4679 (const_int 0)))]
4680 "TARGET_ARCH64"
4681 "andcc\\t%0, 0xff, %%g0"
4682 [(set_attr "type" "compare")])
4683
4684 (define_insn "*cmp_diqi_trunc_set"
4685 [(set (reg:CC 100)
4686 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4687 (const_int 0)))
4688 (set (match_operand:QI 0 "register_operand" "=r")
4689 (subreg:QI (match_dup 1) 7))]
4690 "TARGET_ARCH64"
4691 "andcc\\t%1, 0xff, %0"
4692 [(set_attr "type" "compare")])
4693 \f
4694 ;;- sign extension instructions
4695
4696 ;; These patterns originally accepted general_operands, however, slightly
4697 ;; better code is generated by only accepting register_operands, and then
4698 ;; letting combine generate the lds[hb] insns.
4699
4700 (define_expand "extendhisi2"
4701 [(set (match_operand:SI 0 "register_operand" "")
4702 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4703 ""
4704 "
4705 {
4706 rtx temp = gen_reg_rtx (SImode);
4707 rtx shift_16 = GEN_INT (16);
4708 int op1_subbyte = 0;
4709
4710 if (GET_CODE (operand1) == SUBREG)
4711 {
4712 op1_subbyte = SUBREG_BYTE (operand1);
4713 op1_subbyte /= GET_MODE_SIZE (SImode);
4714 op1_subbyte *= GET_MODE_SIZE (SImode);
4715 operand1 = XEXP (operand1, 0);
4716 }
4717
4718 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4719 shift_16));
4720 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4721 DONE;
4722 }")
4723
4724 (define_insn "*sign_extendhisi2_insn"
4725 [(set (match_operand:SI 0 "register_operand" "=r")
4726 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4727 ""
4728 "ldsh\\t%1, %0"
4729 [(set_attr "type" "sload")])
4730
4731 (define_expand "extendqihi2"
4732 [(set (match_operand:HI 0 "register_operand" "")
4733 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4734 ""
4735 "
4736 {
4737 rtx temp = gen_reg_rtx (SImode);
4738 rtx shift_24 = GEN_INT (24);
4739 int op1_subbyte = 0;
4740 int op0_subbyte = 0;
4741
4742 if (GET_CODE (operand1) == SUBREG)
4743 {
4744 op1_subbyte = SUBREG_BYTE (operand1);
4745 op1_subbyte /= GET_MODE_SIZE (SImode);
4746 op1_subbyte *= GET_MODE_SIZE (SImode);
4747 operand1 = XEXP (operand1, 0);
4748 }
4749 if (GET_CODE (operand0) == SUBREG)
4750 {
4751 op0_subbyte = SUBREG_BYTE (operand0);
4752 op0_subbyte /= GET_MODE_SIZE (SImode);
4753 op0_subbyte *= GET_MODE_SIZE (SImode);
4754 operand0 = XEXP (operand0, 0);
4755 }
4756 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4757 shift_24));
4758 if (GET_MODE (operand0) != SImode)
4759 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4760 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4761 DONE;
4762 }")
4763
4764 (define_insn "*sign_extendqihi2_insn"
4765 [(set (match_operand:HI 0 "register_operand" "=r")
4766 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4767 ""
4768 "ldsb\\t%1, %0"
4769 [(set_attr "type" "sload")])
4770
4771 (define_expand "extendqisi2"
4772 [(set (match_operand:SI 0 "register_operand" "")
4773 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4774 ""
4775 "
4776 {
4777 rtx temp = gen_reg_rtx (SImode);
4778 rtx shift_24 = GEN_INT (24);
4779 int op1_subbyte = 0;
4780
4781 if (GET_CODE (operand1) == SUBREG)
4782 {
4783 op1_subbyte = SUBREG_BYTE (operand1);
4784 op1_subbyte /= GET_MODE_SIZE (SImode);
4785 op1_subbyte *= GET_MODE_SIZE (SImode);
4786 operand1 = XEXP (operand1, 0);
4787 }
4788
4789 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4790 shift_24));
4791 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4792 DONE;
4793 }")
4794
4795 (define_insn "*sign_extendqisi2_insn"
4796 [(set (match_operand:SI 0 "register_operand" "=r")
4797 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4798 ""
4799 "ldsb\\t%1, %0"
4800 [(set_attr "type" "sload")])
4801
4802 (define_expand "extendqidi2"
4803 [(set (match_operand:DI 0 "register_operand" "")
4804 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4805 "TARGET_ARCH64"
4806 "
4807 {
4808 rtx temp = gen_reg_rtx (DImode);
4809 rtx shift_56 = GEN_INT (56);
4810 int op1_subbyte = 0;
4811
4812 if (GET_CODE (operand1) == SUBREG)
4813 {
4814 op1_subbyte = SUBREG_BYTE (operand1);
4815 op1_subbyte /= GET_MODE_SIZE (DImode);
4816 op1_subbyte *= GET_MODE_SIZE (DImode);
4817 operand1 = XEXP (operand1, 0);
4818 }
4819
4820 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4821 shift_56));
4822 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4823 DONE;
4824 }")
4825
4826 (define_insn "*sign_extendqidi2_insn"
4827 [(set (match_operand:DI 0 "register_operand" "=r")
4828 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4829 "TARGET_ARCH64"
4830 "ldsb\\t%1, %0"
4831 [(set_attr "type" "sload")])
4832
4833 (define_expand "extendhidi2"
4834 [(set (match_operand:DI 0 "register_operand" "")
4835 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4836 "TARGET_ARCH64"
4837 "
4838 {
4839 rtx temp = gen_reg_rtx (DImode);
4840 rtx shift_48 = GEN_INT (48);
4841 int op1_subbyte = 0;
4842
4843 if (GET_CODE (operand1) == SUBREG)
4844 {
4845 op1_subbyte = SUBREG_BYTE (operand1);
4846 op1_subbyte /= GET_MODE_SIZE (DImode);
4847 op1_subbyte *= GET_MODE_SIZE (DImode);
4848 operand1 = XEXP (operand1, 0);
4849 }
4850
4851 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4852 shift_48));
4853 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4854 DONE;
4855 }")
4856
4857 (define_insn "*sign_extendhidi2_insn"
4858 [(set (match_operand:DI 0 "register_operand" "=r")
4859 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4860 "TARGET_ARCH64"
4861 "ldsh\\t%1, %0"
4862 [(set_attr "type" "sload")])
4863
4864 (define_expand "extendsidi2"
4865 [(set (match_operand:DI 0 "register_operand" "")
4866 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4867 "TARGET_ARCH64"
4868 "")
4869
4870 (define_insn "*sign_extendsidi2_insn"
4871 [(set (match_operand:DI 0 "register_operand" "=r,r")
4872 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4873 "TARGET_ARCH64"
4874 "@
4875 sra\\t%1, 0, %0
4876 ldsw\\t%1, %0"
4877 [(set_attr "type" "shift,sload")])
4878 \f
4879 ;; Special pattern for optimizing bit-field compares. This is needed
4880 ;; because combine uses this as a canonical form.
4881
4882 (define_insn "*cmp_zero_extract"
4883 [(set (reg:CC 100)
4884 (compare:CC
4885 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4886 (match_operand:SI 1 "small_int_or_double" "n")
4887 (match_operand:SI 2 "small_int_or_double" "n"))
4888 (const_int 0)))]
4889 "(GET_CODE (operands[2]) == CONST_INT
4890 && INTVAL (operands[2]) > 19)
4891 || (GET_CODE (operands[2]) == CONST_DOUBLE
4892 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4893 "*
4894 {
4895 int len = (GET_CODE (operands[1]) == CONST_INT
4896 ? INTVAL (operands[1])
4897 : CONST_DOUBLE_LOW (operands[1]));
4898 int pos = 32 -
4899 (GET_CODE (operands[2]) == CONST_INT
4900 ? INTVAL (operands[2])
4901 : CONST_DOUBLE_LOW (operands[2])) - len;
4902 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4903
4904 operands[1] = GEN_INT (mask);
4905 return \"andcc\\t%0, %1, %%g0\";
4906 }"
4907 [(set_attr "type" "compare")])
4908
4909 (define_insn "*cmp_zero_extract_sp64"
4910 [(set (reg:CCX 100)
4911 (compare:CCX
4912 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4913 (match_operand:SI 1 "small_int_or_double" "n")
4914 (match_operand:SI 2 "small_int_or_double" "n"))
4915 (const_int 0)))]
4916 "TARGET_ARCH64
4917 && ((GET_CODE (operands[2]) == CONST_INT
4918 && INTVAL (operands[2]) > 51)
4919 || (GET_CODE (operands[2]) == CONST_DOUBLE
4920 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4921 "*
4922 {
4923 int len = (GET_CODE (operands[1]) == CONST_INT
4924 ? INTVAL (operands[1])
4925 : CONST_DOUBLE_LOW (operands[1]));
4926 int pos = 64 -
4927 (GET_CODE (operands[2]) == CONST_INT
4928 ? INTVAL (operands[2])
4929 : CONST_DOUBLE_LOW (operands[2])) - len;
4930 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4931
4932 operands[1] = GEN_INT (mask);
4933 return \"andcc\\t%0, %1, %%g0\";
4934 }"
4935 [(set_attr "type" "compare")])
4936 \f
4937 ;; Conversions between float, double and long double.
4938
4939 (define_insn "extendsfdf2"
4940 [(set (match_operand:DF 0 "register_operand" "=e")
4941 (float_extend:DF
4942 (match_operand:SF 1 "register_operand" "f")))]
4943 "TARGET_FPU"
4944 "fstod\\t%1, %0"
4945 [(set_attr "type" "fp")
4946 (set_attr "fptype" "double")])
4947
4948 (define_expand "extendsftf2"
4949 [(set (match_operand:TF 0 "register_operand" "=e")
4950 (float_extend:TF
4951 (match_operand:SF 1 "register_operand" "f")))]
4952 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4953 "
4954 {
4955 if (! TARGET_HARD_QUAD)
4956 {
4957 rtx slot0;
4958
4959 if (GET_CODE (operands[0]) != MEM)
4960 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4961 else
4962 slot0 = operands[0];
4963
4964 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4965 VOIDmode, 2,
4966 XEXP (slot0, 0), Pmode,
4967 operands[1], SFmode);
4968
4969 if (GET_CODE (operands[0]) != MEM)
4970 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4971 DONE;
4972 }
4973 }")
4974
4975 (define_insn "*extendsftf2_hq"
4976 [(set (match_operand:TF 0 "register_operand" "=e")
4977 (float_extend:TF
4978 (match_operand:SF 1 "register_operand" "f")))]
4979 "TARGET_FPU && TARGET_HARD_QUAD"
4980 "fstoq\\t%1, %0"
4981 [(set_attr "type" "fp")])
4982
4983 (define_expand "extenddftf2"
4984 [(set (match_operand:TF 0 "register_operand" "=e")
4985 (float_extend:TF
4986 (match_operand:DF 1 "register_operand" "e")))]
4987 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4988 "
4989 {
4990 if (! TARGET_HARD_QUAD)
4991 {
4992 rtx slot0;
4993
4994 if (GET_CODE (operands[0]) != MEM)
4995 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4996 else
4997 slot0 = operands[0];
4998
4999 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5000 VOIDmode, 2,
5001 XEXP (slot0, 0), Pmode,
5002 operands[1], DFmode);
5003
5004 if (GET_CODE (operands[0]) != MEM)
5005 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5006 DONE;
5007 }
5008 }")
5009
5010 (define_insn "*extenddftf2_hq"
5011 [(set (match_operand:TF 0 "register_operand" "=e")
5012 (float_extend:TF
5013 (match_operand:DF 1 "register_operand" "e")))]
5014 "TARGET_FPU && TARGET_HARD_QUAD"
5015 "fdtoq\\t%1, %0"
5016 [(set_attr "type" "fp")])
5017
5018 (define_insn "truncdfsf2"
5019 [(set (match_operand:SF 0 "register_operand" "=f")
5020 (float_truncate:SF
5021 (match_operand:DF 1 "register_operand" "e")))]
5022 "TARGET_FPU"
5023 "fdtos\\t%1, %0"
5024 [(set_attr "type" "fp")
5025 (set_attr "fptype" "double")])
5026
5027 (define_expand "trunctfsf2"
5028 [(set (match_operand:SF 0 "register_operand" "=f")
5029 (float_truncate:SF
5030 (match_operand:TF 1 "register_operand" "e")))]
5031 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5032 "
5033 {
5034 if (! TARGET_HARD_QUAD)
5035 {
5036 rtx slot0;
5037
5038 if (GET_CODE (operands[1]) != MEM)
5039 {
5040 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5041 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5042 }
5043 else
5044 slot0 = operands[1];
5045
5046 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5047 operands[0], 0, SFmode, 1,
5048 XEXP (slot0, 0), Pmode);
5049 DONE;
5050 }
5051 }")
5052
5053 (define_insn "*trunctfsf2_hq"
5054 [(set (match_operand:SF 0 "register_operand" "=f")
5055 (float_truncate:SF
5056 (match_operand:TF 1 "register_operand" "e")))]
5057 "TARGET_FPU && TARGET_HARD_QUAD"
5058 "fqtos\\t%1, %0"
5059 [(set_attr "type" "fp")])
5060
5061 (define_expand "trunctfdf2"
5062 [(set (match_operand:DF 0 "register_operand" "=f")
5063 (float_truncate:DF
5064 (match_operand:TF 1 "register_operand" "e")))]
5065 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5066 "
5067 {
5068 if (! TARGET_HARD_QUAD)
5069 {
5070 rtx slot0;
5071
5072 if (GET_CODE (operands[1]) != MEM)
5073 {
5074 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5075 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5076 }
5077 else
5078 slot0 = operands[1];
5079
5080 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5081 operands[0], 0, DFmode, 1,
5082 XEXP (slot0, 0), Pmode);
5083 DONE;
5084 }
5085 }")
5086
5087 (define_insn "*trunctfdf2_hq"
5088 [(set (match_operand:DF 0 "register_operand" "=e")
5089 (float_truncate:DF
5090 (match_operand:TF 1 "register_operand" "e")))]
5091 "TARGET_FPU && TARGET_HARD_QUAD"
5092 "fqtod\\t%1, %0"
5093 [(set_attr "type" "fp")])
5094 \f
5095 ;; Conversion between fixed point and floating point.
5096
5097 (define_insn "floatsisf2"
5098 [(set (match_operand:SF 0 "register_operand" "=f")
5099 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5100 "TARGET_FPU"
5101 "fitos\\t%1, %0"
5102 [(set_attr "type" "fp")
5103 (set_attr "fptype" "double")])
5104
5105 (define_insn "floatsidf2"
5106 [(set (match_operand:DF 0 "register_operand" "=e")
5107 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5108 "TARGET_FPU"
5109 "fitod\\t%1, %0"
5110 [(set_attr "type" "fp")
5111 (set_attr "fptype" "double")])
5112
5113 (define_expand "floatsitf2"
5114 [(set (match_operand:TF 0 "register_operand" "=e")
5115 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5116 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5117 "
5118 {
5119 if (! TARGET_HARD_QUAD)
5120 {
5121 rtx slot0;
5122
5123 if (GET_CODE (operands[1]) != MEM)
5124 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5125 else
5126 slot0 = operands[1];
5127
5128 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5129 VOIDmode, 2,
5130 XEXP (slot0, 0), Pmode,
5131 operands[1], SImode);
5132
5133 if (GET_CODE (operands[0]) != MEM)
5134 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5135 DONE;
5136 }
5137 }")
5138
5139 (define_insn "*floatsitf2_hq"
5140 [(set (match_operand:TF 0 "register_operand" "=e")
5141 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5142 "TARGET_FPU && TARGET_HARD_QUAD"
5143 "fitoq\\t%1, %0"
5144 [(set_attr "type" "fp")])
5145
5146 (define_expand "floatunssitf2"
5147 [(set (match_operand:TF 0 "register_operand" "=e")
5148 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5149 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5150 "
5151 {
5152 rtx slot0;
5153
5154 if (GET_CODE (operands[1]) != MEM)
5155 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5156 else
5157 slot0 = operands[1];
5158
5159 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5160 VOIDmode, 2,
5161 XEXP (slot0, 0), Pmode,
5162 operands[1], SImode);
5163
5164 if (GET_CODE (operands[0]) != MEM)
5165 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5166 DONE;
5167 }")
5168
5169 ;; Now the same for 64 bit sources.
5170
5171 (define_insn "floatdisf2"
5172 [(set (match_operand:SF 0 "register_operand" "=f")
5173 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5174 "TARGET_V9 && TARGET_FPU"
5175 "fxtos\\t%1, %0"
5176 [(set_attr "type" "fp")
5177 (set_attr "fptype" "double")])
5178
5179 (define_insn "floatdidf2"
5180 [(set (match_operand:DF 0 "register_operand" "=e")
5181 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5182 "TARGET_V9 && TARGET_FPU"
5183 "fxtod\\t%1, %0"
5184 [(set_attr "type" "fp")
5185 (set_attr "fptype" "double")])
5186
5187 (define_expand "floatditf2"
5188 [(set (match_operand:TF 0 "register_operand" "=e")
5189 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5190 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5191 "
5192 {
5193 if (! TARGET_HARD_QUAD)
5194 {
5195 rtx slot0;
5196
5197 if (GET_CODE (operands[1]) != MEM)
5198 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5199 else
5200 slot0 = operands[1];
5201
5202 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5203 VOIDmode, 2,
5204 XEXP (slot0, 0), Pmode,
5205 operands[1], DImode);
5206
5207 if (GET_CODE (operands[0]) != MEM)
5208 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5209 DONE;
5210 }
5211 }")
5212
5213 (define_insn "*floatditf2_hq"
5214 [(set (match_operand:TF 0 "register_operand" "=e")
5215 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5216 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5217 "fxtoq\\t%1, %0"
5218 [(set_attr "type" "fp")])
5219
5220 (define_expand "floatunsditf2"
5221 [(set (match_operand:TF 0 "register_operand" "=e")
5222 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5223 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5224 "
5225 {
5226 rtx slot0;
5227
5228 if (GET_CODE (operands[1]) != MEM)
5229 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5230 else
5231 slot0 = operands[1];
5232
5233 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5234 VOIDmode, 2,
5235 XEXP (slot0, 0), Pmode,
5236 operands[1], DImode);
5237
5238 if (GET_CODE (operands[0]) != MEM)
5239 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5240 DONE;
5241 }")
5242
5243 ;; Convert a float to an actual integer.
5244 ;; Truncation is performed as part of the conversion.
5245
5246 (define_insn "fix_truncsfsi2"
5247 [(set (match_operand:SI 0 "register_operand" "=f")
5248 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5249 "TARGET_FPU"
5250 "fstoi\\t%1, %0"
5251 [(set_attr "type" "fp")
5252 (set_attr "fptype" "double")])
5253
5254 (define_insn "fix_truncdfsi2"
5255 [(set (match_operand:SI 0 "register_operand" "=f")
5256 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5257 "TARGET_FPU"
5258 "fdtoi\\t%1, %0"
5259 [(set_attr "type" "fp")
5260 (set_attr "fptype" "double")])
5261
5262 (define_expand "fix_trunctfsi2"
5263 [(set (match_operand:SI 0 "register_operand" "=f")
5264 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5265 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5266 "
5267 {
5268 if (! TARGET_HARD_QUAD)
5269 {
5270 rtx slot0;
5271
5272 if (GET_CODE (operands[1]) != MEM)
5273 {
5274 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5275 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5276 }
5277 else
5278 slot0 = operands[1];
5279
5280 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5281 operands[0], 0, SImode, 1,
5282 XEXP (slot0, 0), Pmode);
5283 DONE;
5284 }
5285 }")
5286
5287 (define_insn "*fix_trunctfsi2_hq"
5288 [(set (match_operand:SI 0 "register_operand" "=f")
5289 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5290 "TARGET_FPU && TARGET_HARD_QUAD"
5291 "fqtoi\\t%1, %0"
5292 [(set_attr "type" "fp")])
5293
5294 (define_expand "fixuns_trunctfsi2"
5295 [(set (match_operand:SI 0 "register_operand" "=f")
5296 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5297 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5298 "
5299 {
5300 rtx slot0;
5301
5302 if (GET_CODE (operands[1]) != MEM)
5303 {
5304 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5305 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5306 }
5307 else
5308 slot0 = operands[1];
5309
5310 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5311 operands[0], 0, SImode, 1,
5312 XEXP (slot0, 0), Pmode);
5313 DONE;
5314 }")
5315
5316 ;; Now the same, for V9 targets
5317
5318 (define_insn "fix_truncsfdi2"
5319 [(set (match_operand:DI 0 "register_operand" "=e")
5320 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5321 "TARGET_V9 && TARGET_FPU"
5322 "fstox\\t%1, %0"
5323 [(set_attr "type" "fp")
5324 (set_attr "fptype" "double")])
5325
5326 (define_insn "fix_truncdfdi2"
5327 [(set (match_operand:DI 0 "register_operand" "=e")
5328 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5329 "TARGET_V9 && TARGET_FPU"
5330 "fdtox\\t%1, %0"
5331 [(set_attr "type" "fp")
5332 (set_attr "fptype" "double")])
5333
5334 (define_expand "fix_trunctfdi2"
5335 [(set (match_operand:DI 0 "register_operand" "=e")
5336 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5337 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5338 "
5339 {
5340 if (! TARGET_HARD_QUAD)
5341 {
5342 rtx slot0;
5343
5344 if (GET_CODE (operands[1]) != MEM)
5345 {
5346 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5347 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5348 }
5349 else
5350 slot0 = operands[1];
5351
5352 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5353 operands[0], 0, DImode, 1,
5354 XEXP (slot0, 0), Pmode);
5355 DONE;
5356 }
5357 }")
5358
5359 (define_insn "*fix_trunctfdi2_hq"
5360 [(set (match_operand:DI 0 "register_operand" "=e")
5361 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5362 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5363 "fqtox\\t%1, %0"
5364 [(set_attr "type" "fp")])
5365
5366 (define_expand "fixuns_trunctfdi2"
5367 [(set (match_operand:DI 0 "register_operand" "=f")
5368 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5369 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5370 "
5371 {
5372 rtx slot0;
5373
5374 if (GET_CODE (operands[1]) != MEM)
5375 {
5376 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5377 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5378 }
5379 else
5380 slot0 = operands[1];
5381
5382 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5383 operands[0], 0, DImode, 1,
5384 XEXP (slot0, 0), Pmode);
5385 DONE;
5386 }")
5387
5388 \f
5389 ;;- arithmetic instructions
5390
5391 (define_expand "adddi3"
5392 [(set (match_operand:DI 0 "register_operand" "=r")
5393 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5394 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5395 ""
5396 "
5397 {
5398 HOST_WIDE_INT i;
5399
5400 if (! TARGET_ARCH64)
5401 {
5402 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5403 gen_rtx_SET (VOIDmode, operands[0],
5404 gen_rtx_PLUS (DImode, operands[1],
5405 operands[2])),
5406 gen_rtx_CLOBBER (VOIDmode,
5407 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5408 DONE;
5409 }
5410 if (arith_double_4096_operand(operands[2], DImode))
5411 {
5412 switch (GET_CODE (operands[1]))
5413 {
5414 case CONST_INT: i = INTVAL (operands[1]); break;
5415 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5416 default:
5417 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5418 gen_rtx_MINUS (DImode, operands[1],
5419 GEN_INT(-4096))));
5420 DONE;
5421 }
5422 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5423 DONE;
5424 }
5425 }")
5426
5427 (define_insn "adddi3_insn_sp32"
5428 [(set (match_operand:DI 0 "register_operand" "=r")
5429 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5430 (match_operand:DI 2 "arith_double_operand" "rHI")))
5431 (clobber (reg:CC 100))]
5432 "! TARGET_ARCH64"
5433 "#"
5434 [(set_attr "length" "2")])
5435
5436 (define_split
5437 [(set (match_operand:DI 0 "register_operand" "")
5438 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5439 (match_operand:DI 2 "arith_double_operand" "")))
5440 (clobber (reg:CC 100))]
5441 "! TARGET_ARCH64 && reload_completed"
5442 [(parallel [(set (reg:CC_NOOV 100)
5443 (compare:CC_NOOV (plus:SI (match_dup 4)
5444 (match_dup 5))
5445 (const_int 0)))
5446 (set (match_dup 3)
5447 (plus:SI (match_dup 4) (match_dup 5)))])
5448 (set (match_dup 6)
5449 (plus:SI (plus:SI (match_dup 7)
5450 (match_dup 8))
5451 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5452 "
5453 {
5454 operands[3] = gen_lowpart (SImode, operands[0]);
5455 operands[4] = gen_lowpart (SImode, operands[1]);
5456 operands[5] = gen_lowpart (SImode, operands[2]);
5457 operands[6] = gen_highpart (SImode, operands[0]);
5458 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5459 #if HOST_BITS_PER_WIDE_INT == 32
5460 if (GET_CODE (operands[2]) == CONST_INT)
5461 {
5462 if (INTVAL (operands[2]) < 0)
5463 operands[8] = constm1_rtx;
5464 else
5465 operands[8] = const0_rtx;
5466 }
5467 else
5468 #endif
5469 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5470 }")
5471
5472 (define_split
5473 [(set (match_operand:DI 0 "register_operand" "")
5474 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5475 (match_operand:DI 2 "arith_double_operand" "")))
5476 (clobber (reg:CC 100))]
5477 "! TARGET_ARCH64 && reload_completed"
5478 [(parallel [(set (reg:CC_NOOV 100)
5479 (compare:CC_NOOV (minus:SI (match_dup 4)
5480 (match_dup 5))
5481 (const_int 0)))
5482 (set (match_dup 3)
5483 (minus:SI (match_dup 4) (match_dup 5)))])
5484 (set (match_dup 6)
5485 (minus:SI (minus:SI (match_dup 7)
5486 (match_dup 8))
5487 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5488 "
5489 {
5490 operands[3] = gen_lowpart (SImode, operands[0]);
5491 operands[4] = gen_lowpart (SImode, operands[1]);
5492 operands[5] = gen_lowpart (SImode, operands[2]);
5493 operands[6] = gen_highpart (SImode, operands[0]);
5494 operands[7] = gen_highpart (SImode, operands[1]);
5495 #if HOST_BITS_PER_WIDE_INT == 32
5496 if (GET_CODE (operands[2]) == CONST_INT)
5497 {
5498 if (INTVAL (operands[2]) < 0)
5499 operands[8] = constm1_rtx;
5500 else
5501 operands[8] = const0_rtx;
5502 }
5503 else
5504 #endif
5505 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5506 }")
5507
5508 ;; LTU here means "carry set"
5509 (define_insn "addx"
5510 [(set (match_operand:SI 0 "register_operand" "=r")
5511 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5512 (match_operand:SI 2 "arith_operand" "rI"))
5513 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5514 ""
5515 "addx\\t%1, %2, %0"
5516 [(set_attr "type" "misc")])
5517
5518 (define_insn "*addx_extend_sp32"
5519 [(set (match_operand:DI 0 "register_operand" "=r")
5520 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5521 (match_operand:SI 2 "arith_operand" "rI"))
5522 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5523 "! TARGET_ARCH64"
5524 "#"
5525 [(set_attr "length" "2")])
5526
5527 (define_split
5528 [(set (match_operand:DI 0 "register_operand" "")
5529 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5530 (match_operand:SI 2 "arith_operand" ""))
5531 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5532 "! TARGET_ARCH64 && reload_completed"
5533 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5534 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5535 (set (match_dup 4) (const_int 0))]
5536 "operands[3] = gen_lowpart (SImode, operands[0]);
5537 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5538
5539 (define_insn "*addx_extend_sp64"
5540 [(set (match_operand:DI 0 "register_operand" "=r")
5541 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5542 (match_operand:SI 2 "arith_operand" "rI"))
5543 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5544 "TARGET_ARCH64"
5545 "addx\\t%r1, %2, %0"
5546 [(set_attr "type" "misc")])
5547
5548 (define_insn "subx"
5549 [(set (match_operand:SI 0 "register_operand" "=r")
5550 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5551 (match_operand:SI 2 "arith_operand" "rI"))
5552 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5553 ""
5554 "subx\\t%r1, %2, %0"
5555 [(set_attr "type" "misc")])
5556
5557 (define_insn "*subx_extend_sp64"
5558 [(set (match_operand:DI 0 "register_operand" "=r")
5559 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5560 (match_operand:SI 2 "arith_operand" "rI"))
5561 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5562 "TARGET_ARCH64"
5563 "subx\\t%r1, %2, %0"
5564 [(set_attr "type" "misc")])
5565
5566 (define_insn "*subx_extend"
5567 [(set (match_operand:DI 0 "register_operand" "=r")
5568 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5569 (match_operand:SI 2 "arith_operand" "rI"))
5570 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5571 "! TARGET_ARCH64"
5572 "#"
5573 [(set_attr "length" "2")])
5574
5575 (define_split
5576 [(set (match_operand:DI 0 "register_operand" "")
5577 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5578 (match_operand:SI 2 "arith_operand" ""))
5579 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5580 "! TARGET_ARCH64 && reload_completed"
5581 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5582 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5583 (set (match_dup 4) (const_int 0))]
5584 "operands[3] = gen_lowpart (SImode, operands[0]);
5585 operands[4] = gen_highpart (SImode, operands[0]);")
5586
5587 (define_insn ""
5588 [(set (match_operand:DI 0 "register_operand" "=r")
5589 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5590 (match_operand:DI 2 "register_operand" "r")))
5591 (clobber (reg:CC 100))]
5592 "! TARGET_ARCH64"
5593 "#"
5594 [(set_attr "length" "2")])
5595
5596 (define_split
5597 [(set (match_operand:DI 0 "register_operand" "")
5598 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5599 (match_operand:DI 2 "register_operand" "")))
5600 (clobber (reg:CC 100))]
5601 "! TARGET_ARCH64 && reload_completed"
5602 [(parallel [(set (reg:CC_NOOV 100)
5603 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5604 (const_int 0)))
5605 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5606 (set (match_dup 6)
5607 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5608 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5609 "operands[3] = gen_lowpart (SImode, operands[2]);
5610 operands[4] = gen_highpart (SImode, operands[2]);
5611 operands[5] = gen_lowpart (SImode, operands[0]);
5612 operands[6] = gen_highpart (SImode, operands[0]);")
5613
5614 (define_insn "*adddi3_sp64"
5615 [(set (match_operand:DI 0 "register_operand" "=r")
5616 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5617 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5618 "TARGET_ARCH64"
5619 "add\\t%1, %2, %0")
5620
5621 (define_expand "addsi3"
5622 [(set (match_operand:SI 0 "register_operand" "=r,d")
5623 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5624 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5625 ""
5626 "
5627 {
5628 if (arith_4096_operand(operands[2], SImode))
5629 {
5630 if (GET_CODE (operands[1]) == CONST_INT)
5631 emit_insn (gen_movsi (operands[0],
5632 GEN_INT (INTVAL (operands[1]) + 4096)));
5633 else
5634 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5635 gen_rtx_MINUS (SImode, operands[1],
5636 GEN_INT(-4096))));
5637 DONE;
5638 }
5639 }")
5640
5641 (define_insn "*addsi3"
5642 [(set (match_operand:SI 0 "register_operand" "=r,d")
5643 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5644 (match_operand:SI 2 "arith_operand" "rI,d")))]
5645 ""
5646 "@
5647 add\\t%1, %2, %0
5648 fpadd32s\\t%1, %2, %0"
5649 [(set_attr "type" "*,fp")])
5650
5651 (define_insn "*cmp_cc_plus"
5652 [(set (reg:CC_NOOV 100)
5653 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5654 (match_operand:SI 1 "arith_operand" "rI"))
5655 (const_int 0)))]
5656 ""
5657 "addcc\\t%0, %1, %%g0"
5658 [(set_attr "type" "compare")])
5659
5660 (define_insn "*cmp_ccx_plus"
5661 [(set (reg:CCX_NOOV 100)
5662 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5663 (match_operand:DI 1 "arith_double_operand" "rHI"))
5664 (const_int 0)))]
5665 "TARGET_ARCH64"
5666 "addcc\\t%0, %1, %%g0"
5667 [(set_attr "type" "compare")])
5668
5669 (define_insn "*cmp_cc_plus_set"
5670 [(set (reg:CC_NOOV 100)
5671 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5672 (match_operand:SI 2 "arith_operand" "rI"))
5673 (const_int 0)))
5674 (set (match_operand:SI 0 "register_operand" "=r")
5675 (plus:SI (match_dup 1) (match_dup 2)))]
5676 ""
5677 "addcc\\t%1, %2, %0"
5678 [(set_attr "type" "compare")])
5679
5680 (define_insn "*cmp_ccx_plus_set"
5681 [(set (reg:CCX_NOOV 100)
5682 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5683 (match_operand:DI 2 "arith_double_operand" "rHI"))
5684 (const_int 0)))
5685 (set (match_operand:DI 0 "register_operand" "=r")
5686 (plus:DI (match_dup 1) (match_dup 2)))]
5687 "TARGET_ARCH64"
5688 "addcc\\t%1, %2, %0"
5689 [(set_attr "type" "compare")])
5690
5691 (define_expand "subdi3"
5692 [(set (match_operand:DI 0 "register_operand" "=r")
5693 (minus:DI (match_operand:DI 1 "register_operand" "r")
5694 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5695 ""
5696 "
5697 {
5698 if (! TARGET_ARCH64)
5699 {
5700 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5701 gen_rtx_SET (VOIDmode, operands[0],
5702 gen_rtx_MINUS (DImode, operands[1],
5703 operands[2])),
5704 gen_rtx_CLOBBER (VOIDmode,
5705 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5706 DONE;
5707 }
5708 if (arith_double_4096_operand(operands[2], DImode))
5709 {
5710 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5711 gen_rtx_PLUS (DImode, operands[1],
5712 GEN_INT(-4096))));
5713 DONE;
5714 }
5715 }")
5716
5717 (define_insn "*subdi3_sp32"
5718 [(set (match_operand:DI 0 "register_operand" "=r")
5719 (minus:DI (match_operand:DI 1 "register_operand" "r")
5720 (match_operand:DI 2 "arith_double_operand" "rHI")))
5721 (clobber (reg:CC 100))]
5722 "! TARGET_ARCH64"
5723 "#"
5724 [(set_attr "length" "2")])
5725
5726 (define_split
5727 [(set (match_operand:DI 0 "register_operand" "")
5728 (minus:DI (match_operand:DI 1 "register_operand" "")
5729 (match_operand:DI 2 "arith_double_operand" "")))
5730 (clobber (reg:CC 100))]
5731 "! TARGET_ARCH64
5732 && reload_completed
5733 && (GET_CODE (operands[2]) == CONST_INT
5734 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5735 [(clobber (const_int 0))]
5736 "
5737 {
5738 rtx highp, lowp;
5739
5740 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5741 lowp = gen_lowpart (SImode, operands[2]);
5742 if ((lowp == const0_rtx)
5743 && (operands[0] == operands[1]))
5744 {
5745 emit_insn (gen_rtx_SET (VOIDmode,
5746 gen_highpart (SImode, operands[0]),
5747 gen_rtx_MINUS (SImode,
5748 gen_highpart_mode (SImode, DImode,
5749 operands[1]),
5750 highp)));
5751 }
5752 else
5753 {
5754 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5755 gen_lowpart (SImode, operands[1]),
5756 lowp));
5757 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5758 gen_highpart_mode (SImode, DImode, operands[1]),
5759 highp));
5760 }
5761 DONE;
5762 }")
5763
5764 (define_split
5765 [(set (match_operand:DI 0 "register_operand" "")
5766 (minus:DI (match_operand:DI 1 "register_operand" "")
5767 (match_operand:DI 2 "register_operand" "")))
5768 (clobber (reg:CC 100))]
5769 "! TARGET_ARCH64
5770 && reload_completed"
5771 [(clobber (const_int 0))]
5772 "
5773 {
5774 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5775 gen_lowpart (SImode, operands[1]),
5776 gen_lowpart (SImode, operands[2])));
5777 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5778 gen_highpart (SImode, operands[1]),
5779 gen_highpart (SImode, operands[2])));
5780 DONE;
5781 }")
5782
5783 (define_insn ""
5784 [(set (match_operand:DI 0 "register_operand" "=r")
5785 (minus:DI (match_operand:DI 1 "register_operand" "r")
5786 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5787 (clobber (reg:CC 100))]
5788 "! TARGET_ARCH64"
5789 "#"
5790 [(set_attr "length" "2")])
5791
5792 (define_split
5793 [(set (match_operand:DI 0 "register_operand" "")
5794 (minus:DI (match_operand:DI 1 "register_operand" "")
5795 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5796 (clobber (reg:CC 100))]
5797 "! TARGET_ARCH64 && reload_completed"
5798 [(parallel [(set (reg:CC_NOOV 100)
5799 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5800 (const_int 0)))
5801 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5802 (set (match_dup 6)
5803 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5804 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5805 "operands[3] = gen_lowpart (SImode, operands[1]);
5806 operands[4] = gen_highpart (SImode, operands[1]);
5807 operands[5] = gen_lowpart (SImode, operands[0]);
5808 operands[6] = gen_highpart (SImode, operands[0]);")
5809
5810 (define_insn "*subdi3_sp64"
5811 [(set (match_operand:DI 0 "register_operand" "=r")
5812 (minus:DI (match_operand:DI 1 "register_operand" "r")
5813 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5814 "TARGET_ARCH64"
5815 "sub\\t%1, %2, %0")
5816
5817 (define_expand "subsi3"
5818 [(set (match_operand:SI 0 "register_operand" "=r,d")
5819 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5820 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5821 ""
5822 "
5823 {
5824 if (arith_4096_operand(operands[2], SImode))
5825 {
5826 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5827 gen_rtx_PLUS (SImode, operands[1],
5828 GEN_INT(-4096))));
5829 DONE;
5830 }
5831 }")
5832
5833 (define_insn "*subsi3"
5834 [(set (match_operand:SI 0 "register_operand" "=r,d")
5835 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5836 (match_operand:SI 2 "arith_operand" "rI,d")))]
5837 ""
5838 "@
5839 sub\\t%1, %2, %0
5840 fpsub32s\\t%1, %2, %0"
5841 [(set_attr "type" "*,fp")])
5842
5843 (define_insn "*cmp_minus_cc"
5844 [(set (reg:CC_NOOV 100)
5845 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5846 (match_operand:SI 1 "arith_operand" "rI"))
5847 (const_int 0)))]
5848 ""
5849 "subcc\\t%r0, %1, %%g0"
5850 [(set_attr "type" "compare")])
5851
5852 (define_insn "*cmp_minus_ccx"
5853 [(set (reg:CCX_NOOV 100)
5854 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5855 (match_operand:DI 1 "arith_double_operand" "rHI"))
5856 (const_int 0)))]
5857 "TARGET_ARCH64"
5858 "subcc\\t%0, %1, %%g0"
5859 [(set_attr "type" "compare")])
5860
5861 (define_insn "cmp_minus_cc_set"
5862 [(set (reg:CC_NOOV 100)
5863 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5864 (match_operand:SI 2 "arith_operand" "rI"))
5865 (const_int 0)))
5866 (set (match_operand:SI 0 "register_operand" "=r")
5867 (minus:SI (match_dup 1) (match_dup 2)))]
5868 ""
5869 "subcc\\t%r1, %2, %0"
5870 [(set_attr "type" "compare")])
5871
5872 (define_insn "*cmp_minus_ccx_set"
5873 [(set (reg:CCX_NOOV 100)
5874 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5875 (match_operand:DI 2 "arith_double_operand" "rHI"))
5876 (const_int 0)))
5877 (set (match_operand:DI 0 "register_operand" "=r")
5878 (minus:DI (match_dup 1) (match_dup 2)))]
5879 "TARGET_ARCH64"
5880 "subcc\\t%1, %2, %0"
5881 [(set_attr "type" "compare")])
5882 \f
5883 ;; Integer Multiply/Divide.
5884
5885 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5886 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5887
5888 (define_insn "mulsi3"
5889 [(set (match_operand:SI 0 "register_operand" "=r")
5890 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5891 (match_operand:SI 2 "arith_operand" "rI")))]
5892 "TARGET_HARD_MUL"
5893 "smul\\t%1, %2, %0"
5894 [(set_attr "type" "imul")])
5895
5896 (define_expand "muldi3"
5897 [(set (match_operand:DI 0 "register_operand" "=r")
5898 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5899 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5900 "TARGET_ARCH64 || TARGET_V8PLUS"
5901 "
5902 {
5903 if (TARGET_V8PLUS)
5904 {
5905 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5906 DONE;
5907 }
5908 }")
5909
5910 (define_insn "*muldi3_sp64"
5911 [(set (match_operand:DI 0 "register_operand" "=r")
5912 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5913 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5914 "TARGET_ARCH64"
5915 "mulx\\t%1, %2, %0"
5916 [(set_attr "type" "imul")])
5917
5918 ;; V8plus wide multiply.
5919 ;; XXX
5920 (define_insn "muldi3_v8plus"
5921 [(set (match_operand:DI 0 "register_operand" "=r,h")
5922 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5923 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5924 (clobber (match_scratch:SI 3 "=&h,X"))
5925 (clobber (match_scratch:SI 4 "=&h,X"))]
5926 "TARGET_V8PLUS"
5927 "*
5928 {
5929 if (sparc_check_64 (operands[1], insn) <= 0)
5930 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5931 if (which_alternative == 1)
5932 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5933 if (GET_CODE (operands[2]) == CONST_INT)
5934 {
5935 if (which_alternative == 1)
5936 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5937 else
5938 return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
5939 }
5940 if (sparc_check_64 (operands[2], insn) <= 0)
5941 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5942 if (which_alternative == 1)
5943 return \"or\\t%L1, %H1, %H1\\n\\tsllx\\t%H2, 32, %L1\\n\\tor\\t%L2, %L1, %L1\\n\\tmulx\\t%H1, %L1, %L0\;srlx\\t%L0, 32, %H0\";
5944 else
5945 return \"sllx\\t%H1, 32, %3\\n\\tsllx\\t%H2, 32, %4\\n\\tor\\t%L1, %3, %3\\n\\tor\\t%L2, %4, %4\\n\\tmulx\\t%3, %4, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
5946 }"
5947 [(set_attr "type" "multi")
5948 (set_attr "length" "9,8")])
5949
5950 (define_insn "*cmp_mul_set"
5951 [(set (reg:CC 100)
5952 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5953 (match_operand:SI 2 "arith_operand" "rI"))
5954 (const_int 0)))
5955 (set (match_operand:SI 0 "register_operand" "=r")
5956 (mult:SI (match_dup 1) (match_dup 2)))]
5957 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5958 "smulcc\\t%1, %2, %0"
5959 [(set_attr "type" "imul")])
5960
5961 (define_expand "mulsidi3"
5962 [(set (match_operand:DI 0 "register_operand" "")
5963 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5964 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5965 "TARGET_HARD_MUL"
5966 "
5967 {
5968 if (CONSTANT_P (operands[2]))
5969 {
5970 if (TARGET_V8PLUS)
5971 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5972 operands[2]));
5973 else
5974 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5975 operands[2]));
5976 DONE;
5977 }
5978 if (TARGET_V8PLUS)
5979 {
5980 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5981 DONE;
5982 }
5983 }")
5984
5985 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5986 ;; registers can hold 64 bit values in the V8plus environment.
5987 ;; XXX
5988 (define_insn "mulsidi3_v8plus"
5989 [(set (match_operand:DI 0 "register_operand" "=h,r")
5990 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5991 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5992 (clobber (match_scratch:SI 3 "=X,&h"))]
5993 "TARGET_V8PLUS"
5994 "@
5995 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5996 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5997 [(set_attr "type" "multi")
5998 (set_attr "length" "2,3")])
5999
6000 ;; XXX
6001 (define_insn "const_mulsidi3_v8plus"
6002 [(set (match_operand:DI 0 "register_operand" "=h,r")
6003 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6004 (match_operand:SI 2 "small_int" "I,I")))
6005 (clobber (match_scratch:SI 3 "=X,&h"))]
6006 "TARGET_V8PLUS"
6007 "@
6008 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6009 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6010 [(set_attr "type" "multi")
6011 (set_attr "length" "2,3")])
6012
6013 ;; XXX
6014 (define_insn "*mulsidi3_sp32"
6015 [(set (match_operand:DI 0 "register_operand" "=r")
6016 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6017 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6018 "TARGET_HARD_MUL32"
6019 "*
6020 {
6021 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6022 }"
6023 [(set (attr "type")
6024 (if_then_else (eq_attr "isa" "sparclet")
6025 (const_string "imul") (const_string "multi")))
6026 (set (attr "length")
6027 (if_then_else (eq_attr "isa" "sparclet")
6028 (const_int 1) (const_int 2)))])
6029
6030 (define_insn "*mulsidi3_sp64"
6031 [(set (match_operand:DI 0 "register_operand" "=r")
6032 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6033 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6034 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6035 "smul\\t%1, %2, %0"
6036 [(set_attr "type" "imul")])
6037
6038 ;; Extra pattern, because sign_extend of a constant isn't valid.
6039
6040 ;; XXX
6041 (define_insn "const_mulsidi3_sp32"
6042 [(set (match_operand:DI 0 "register_operand" "=r")
6043 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6044 (match_operand:SI 2 "small_int" "I")))]
6045 "TARGET_HARD_MUL32"
6046 "*
6047 {
6048 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6049 }"
6050 [(set (attr "type")
6051 (if_then_else (eq_attr "isa" "sparclet")
6052 (const_string "imul") (const_string "multi")))
6053 (set (attr "length")
6054 (if_then_else (eq_attr "isa" "sparclet")
6055 (const_int 1) (const_int 2)))])
6056
6057 (define_insn "const_mulsidi3_sp64"
6058 [(set (match_operand:DI 0 "register_operand" "=r")
6059 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6060 (match_operand:SI 2 "small_int" "I")))]
6061 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6062 "smul\\t%1, %2, %0"
6063 [(set_attr "type" "imul")])
6064
6065 (define_expand "smulsi3_highpart"
6066 [(set (match_operand:SI 0 "register_operand" "")
6067 (truncate:SI
6068 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6069 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6070 (const_int 32))))]
6071 "TARGET_HARD_MUL && TARGET_ARCH32"
6072 "
6073 {
6074 if (CONSTANT_P (operands[2]))
6075 {
6076 if (TARGET_V8PLUS)
6077 {
6078 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6079 operands[1],
6080 operands[2],
6081 GEN_INT (32)));
6082 DONE;
6083 }
6084 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6085 DONE;
6086 }
6087 if (TARGET_V8PLUS)
6088 {
6089 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6090 operands[2], GEN_INT (32)));
6091 DONE;
6092 }
6093 }")
6094
6095 ;; XXX
6096 (define_insn "smulsi3_highpart_v8plus"
6097 [(set (match_operand:SI 0 "register_operand" "=h,r")
6098 (truncate:SI
6099 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6100 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6101 (match_operand:SI 3 "const_int_operand" "i,i"))))
6102 (clobber (match_scratch:SI 4 "=X,&h"))]
6103 "TARGET_V8PLUS"
6104 "@
6105 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6106 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6107 [(set_attr "type" "multi")
6108 (set_attr "length" "2")])
6109
6110 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6111 ;; XXX
6112 (define_insn ""
6113 [(set (match_operand:SI 0 "register_operand" "=h,r")
6114 (subreg:SI
6115 (lshiftrt:DI
6116 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6117 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6118 (match_operand:SI 3 "const_int_operand" "i,i"))
6119 4))
6120 (clobber (match_scratch:SI 4 "=X,&h"))]
6121 "TARGET_V8PLUS"
6122 "@
6123 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6124 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6125 [(set_attr "type" "multi")
6126 (set_attr "length" "2")])
6127
6128 ;; XXX
6129 (define_insn "const_smulsi3_highpart_v8plus"
6130 [(set (match_operand:SI 0 "register_operand" "=h,r")
6131 (truncate:SI
6132 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6133 (match_operand 2 "small_int" "i,i"))
6134 (match_operand:SI 3 "const_int_operand" "i,i"))))
6135 (clobber (match_scratch:SI 4 "=X,&h"))]
6136 "TARGET_V8PLUS"
6137 "@
6138 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6139 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6140 [(set_attr "type" "multi")
6141 (set_attr "length" "2")])
6142
6143 ;; XXX
6144 (define_insn "*smulsi3_highpart_sp32"
6145 [(set (match_operand:SI 0 "register_operand" "=r")
6146 (truncate:SI
6147 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6148 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6149 (const_int 32))))]
6150 "TARGET_HARD_MUL32"
6151 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6152 [(set_attr "type" "multi")
6153 (set_attr "length" "2")])
6154
6155 ;; XXX
6156 (define_insn "const_smulsi3_highpart"
6157 [(set (match_operand:SI 0 "register_operand" "=r")
6158 (truncate:SI
6159 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6160 (match_operand:SI 2 "register_operand" "r"))
6161 (const_int 32))))]
6162 "TARGET_HARD_MUL32"
6163 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6164 [(set_attr "type" "multi")
6165 (set_attr "length" "2")])
6166
6167 (define_expand "umulsidi3"
6168 [(set (match_operand:DI 0 "register_operand" "")
6169 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6170 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6171 "TARGET_HARD_MUL"
6172 "
6173 {
6174 if (CONSTANT_P (operands[2]))
6175 {
6176 if (TARGET_V8PLUS)
6177 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6178 operands[2]));
6179 else
6180 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6181 operands[2]));
6182 DONE;
6183 }
6184 if (TARGET_V8PLUS)
6185 {
6186 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6187 DONE;
6188 }
6189 }")
6190
6191 ;; XXX
6192 (define_insn "umulsidi3_v8plus"
6193 [(set (match_operand:DI 0 "register_operand" "=h,r")
6194 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6195 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6196 (clobber (match_scratch:SI 3 "=X,&h"))]
6197 "TARGET_V8PLUS"
6198 "@
6199 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6200 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6201 [(set_attr "type" "multi")
6202 (set_attr "length" "2,3")])
6203
6204 ;; XXX
6205 (define_insn "*umulsidi3_sp32"
6206 [(set (match_operand:DI 0 "register_operand" "=r")
6207 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6208 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6209 "TARGET_HARD_MUL32"
6210 "*
6211 {
6212 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6213 }"
6214 [(set (attr "type")
6215 (if_then_else (eq_attr "isa" "sparclet")
6216 (const_string "imul") (const_string "multi")))
6217 (set (attr "length")
6218 (if_then_else (eq_attr "isa" "sparclet")
6219 (const_int 1) (const_int 2)))])
6220
6221 (define_insn "*umulsidi3_sp64"
6222 [(set (match_operand:DI 0 "register_operand" "=r")
6223 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6224 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6225 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6226 "umul\\t%1, %2, %0"
6227 [(set_attr "type" "imul")])
6228
6229 ;; Extra pattern, because sign_extend of a constant isn't valid.
6230
6231 ;; XXX
6232 (define_insn "const_umulsidi3_sp32"
6233 [(set (match_operand:DI 0 "register_operand" "=r")
6234 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6235 (match_operand:SI 2 "uns_small_int" "")))]
6236 "TARGET_HARD_MUL32"
6237 "*
6238 {
6239 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6240 }"
6241 [(set (attr "type")
6242 (if_then_else (eq_attr "isa" "sparclet")
6243 (const_string "imul") (const_string "multi")))
6244 (set (attr "length")
6245 (if_then_else (eq_attr "isa" "sparclet")
6246 (const_int 1) (const_int 2)))])
6247
6248 (define_insn "const_umulsidi3_sp64"
6249 [(set (match_operand:DI 0 "register_operand" "=r")
6250 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6251 (match_operand:SI 2 "uns_small_int" "")))]
6252 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6253 "umul\\t%1, %2, %0"
6254 [(set_attr "type" "imul")])
6255
6256 ;; XXX
6257 (define_insn "const_umulsidi3_v8plus"
6258 [(set (match_operand:DI 0 "register_operand" "=h,r")
6259 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6260 (match_operand:SI 2 "uns_small_int" "")))
6261 (clobber (match_scratch:SI 3 "=X,h"))]
6262 "TARGET_V8PLUS"
6263 "@
6264 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6265 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6266 [(set_attr "type" "multi")
6267 (set_attr "length" "2,3")])
6268
6269 (define_expand "umulsi3_highpart"
6270 [(set (match_operand:SI 0 "register_operand" "")
6271 (truncate:SI
6272 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6273 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6274 (const_int 32))))]
6275 "TARGET_HARD_MUL && TARGET_ARCH32"
6276 "
6277 {
6278 if (CONSTANT_P (operands[2]))
6279 {
6280 if (TARGET_V8PLUS)
6281 {
6282 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6283 operands[1],
6284 operands[2],
6285 GEN_INT (32)));
6286 DONE;
6287 }
6288 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6289 DONE;
6290 }
6291 if (TARGET_V8PLUS)
6292 {
6293 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6294 operands[2], GEN_INT (32)));
6295 DONE;
6296 }
6297 }")
6298
6299 ;; XXX
6300 (define_insn "umulsi3_highpart_v8plus"
6301 [(set (match_operand:SI 0 "register_operand" "=h,r")
6302 (truncate:SI
6303 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6304 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6305 (match_operand:SI 3 "const_int_operand" "i,i"))))
6306 (clobber (match_scratch:SI 4 "=X,h"))]
6307 "TARGET_V8PLUS"
6308 "@
6309 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6310 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6311 [(set_attr "type" "multi")
6312 (set_attr "length" "2")])
6313
6314 ;; XXX
6315 (define_insn "const_umulsi3_highpart_v8plus"
6316 [(set (match_operand:SI 0 "register_operand" "=h,r")
6317 (truncate:SI
6318 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6319 (match_operand:SI 2 "uns_small_int" ""))
6320 (match_operand:SI 3 "const_int_operand" "i,i"))))
6321 (clobber (match_scratch:SI 4 "=X,h"))]
6322 "TARGET_V8PLUS"
6323 "@
6324 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6325 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6326 [(set_attr "type" "multi")
6327 (set_attr "length" "2")])
6328
6329 ;; XXX
6330 (define_insn "*umulsi3_highpart_sp32"
6331 [(set (match_operand:SI 0 "register_operand" "=r")
6332 (truncate:SI
6333 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6334 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6335 (const_int 32))))]
6336 "TARGET_HARD_MUL32"
6337 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6338 [(set_attr "type" "multi")
6339 (set_attr "length" "2")])
6340
6341 ;; XXX
6342 (define_insn "const_umulsi3_highpart"
6343 [(set (match_operand:SI 0 "register_operand" "=r")
6344 (truncate:SI
6345 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6346 (match_operand:SI 2 "uns_small_int" ""))
6347 (const_int 32))))]
6348 "TARGET_HARD_MUL32"
6349 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6350 [(set_attr "type" "multi")
6351 (set_attr "length" "2")])
6352
6353 ;; The v8 architecture specifies that there must be 3 instructions between
6354 ;; a y register write and a use of it for correct results.
6355
6356 (define_expand "divsi3"
6357 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6358 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6359 (match_operand:SI 2 "input_operand" "rI,m")))
6360 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6361 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6362 "
6363 {
6364 if (TARGET_ARCH64)
6365 {
6366 operands[3] = gen_reg_rtx(SImode);
6367 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6368 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6369 operands[3]));
6370 DONE;
6371 }
6372 }")
6373
6374 (define_insn "divsi3_sp32"
6375 [(set (match_operand:SI 0 "register_operand" "=r,r")
6376 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6377 (match_operand:SI 2 "input_operand" "rI,m")))
6378 (clobber (match_scratch:SI 3 "=&r,&r"))]
6379 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6380 && TARGET_ARCH32"
6381 "*
6382 {
6383 if (which_alternative == 0)
6384 if (TARGET_V9)
6385 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6386 else
6387 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6388 else
6389 if (TARGET_V9)
6390 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6391 else
6392 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
6393 }"
6394 [(set_attr "type" "multi")
6395 (set (attr "length")
6396 (if_then_else (eq_attr "isa" "v9")
6397 (const_int 4) (const_int 7)))])
6398
6399 (define_insn "divsi3_sp64"
6400 [(set (match_operand:SI 0 "register_operand" "=r")
6401 (div:SI (match_operand:SI 1 "register_operand" "r")
6402 (match_operand:SI 2 "input_operand" "rI")))
6403 (use (match_operand:SI 3 "register_operand" "r"))]
6404 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6405 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6406 [(set_attr "type" "multi")
6407 (set_attr "length" "2")])
6408
6409 (define_insn "divdi3"
6410 [(set (match_operand:DI 0 "register_operand" "=r")
6411 (div:DI (match_operand:DI 1 "register_operand" "r")
6412 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6413 "TARGET_ARCH64"
6414 "sdivx\\t%1, %2, %0"
6415 [(set_attr "type" "idiv")])
6416
6417 (define_insn "*cmp_sdiv_cc_set"
6418 [(set (reg:CC 100)
6419 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6420 (match_operand:SI 2 "arith_operand" "rI"))
6421 (const_int 0)))
6422 (set (match_operand:SI 0 "register_operand" "=r")
6423 (div:SI (match_dup 1) (match_dup 2)))
6424 (clobber (match_scratch:SI 3 "=&r"))]
6425 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6426 "*
6427 {
6428 if (TARGET_V9)
6429 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6430 else
6431 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6432 }"
6433 [(set_attr "type" "multi")
6434 (set (attr "length")
6435 (if_then_else (eq_attr "isa" "v9")
6436 (const_int 3) (const_int 6)))])
6437
6438 ;; XXX
6439 (define_expand "udivsi3"
6440 [(set (match_operand:SI 0 "register_operand" "")
6441 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6442 (match_operand:SI 2 "input_operand" "")))]
6443 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6444 "")
6445
6446 (define_insn "udivsi3_sp32"
6447 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6448 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6449 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6450 "(TARGET_V8
6451 || TARGET_DEPRECATED_V8_INSNS)
6452 && TARGET_ARCH32"
6453 "*
6454 {
6455 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6456 switch (which_alternative)
6457 {
6458 default:
6459 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6460 case 1:
6461 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6462 case 2:
6463 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6464 }
6465 }"
6466 [(set_attr "type" "multi")
6467 (set_attr "length" "5")])
6468
6469 (define_insn "udivsi3_sp64"
6470 [(set (match_operand:SI 0 "register_operand" "=r")
6471 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6472 (match_operand:SI 2 "input_operand" "rI")))]
6473 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6474 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6475 [(set_attr "type" "multi")
6476 (set_attr "length" "2")])
6477
6478 (define_insn "udivdi3"
6479 [(set (match_operand:DI 0 "register_operand" "=r")
6480 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6481 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6482 "TARGET_ARCH64"
6483 "udivx\\t%1, %2, %0"
6484 [(set_attr "type" "idiv")])
6485
6486 (define_insn "*cmp_udiv_cc_set"
6487 [(set (reg:CC 100)
6488 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6489 (match_operand:SI 2 "arith_operand" "rI"))
6490 (const_int 0)))
6491 (set (match_operand:SI 0 "register_operand" "=r")
6492 (udiv:SI (match_dup 1) (match_dup 2)))]
6493 "TARGET_V8
6494 || TARGET_DEPRECATED_V8_INSNS"
6495 "*
6496 {
6497 if (TARGET_V9)
6498 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6499 else
6500 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6501 }"
6502 [(set_attr "type" "multi")
6503 (set (attr "length")
6504 (if_then_else (eq_attr "isa" "v9")
6505 (const_int 2) (const_int 5)))])
6506
6507 ; sparclet multiply/accumulate insns
6508
6509 (define_insn "*smacsi"
6510 [(set (match_operand:SI 0 "register_operand" "=r")
6511 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6512 (match_operand:SI 2 "arith_operand" "rI"))
6513 (match_operand:SI 3 "register_operand" "0")))]
6514 "TARGET_SPARCLET"
6515 "smac\\t%1, %2, %0"
6516 [(set_attr "type" "imul")])
6517
6518 (define_insn "*smacdi"
6519 [(set (match_operand:DI 0 "register_operand" "=r")
6520 (plus:DI (mult:DI (sign_extend:DI
6521 (match_operand:SI 1 "register_operand" "%r"))
6522 (sign_extend:DI
6523 (match_operand:SI 2 "register_operand" "r")))
6524 (match_operand:DI 3 "register_operand" "0")))]
6525 "TARGET_SPARCLET"
6526 "smacd\\t%1, %2, %L0"
6527 [(set_attr "type" "imul")])
6528
6529 (define_insn "*umacdi"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6531 (plus:DI (mult:DI (zero_extend:DI
6532 (match_operand:SI 1 "register_operand" "%r"))
6533 (zero_extend:DI
6534 (match_operand:SI 2 "register_operand" "r")))
6535 (match_operand:DI 3 "register_operand" "0")))]
6536 "TARGET_SPARCLET"
6537 "umacd\\t%1, %2, %L0"
6538 [(set_attr "type" "imul")])
6539 \f
6540 ;;- Boolean instructions
6541 ;; We define DImode `and' so with DImode `not' we can get
6542 ;; DImode `andn'. Other combinations are possible.
6543
6544 (define_expand "anddi3"
6545 [(set (match_operand:DI 0 "register_operand" "")
6546 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6547 (match_operand:DI 2 "arith_double_operand" "")))]
6548 ""
6549 "")
6550
6551 (define_insn "*anddi3_sp32"
6552 [(set (match_operand:DI 0 "register_operand" "=r,b")
6553 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6554 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6555 "! TARGET_ARCH64"
6556 "@
6557 #
6558 fand\\t%1, %2, %0"
6559 [(set_attr "type" "*,fp")
6560 (set_attr "length" "2,*")
6561 (set_attr "fptype" "double")])
6562
6563 (define_insn "*anddi3_sp64"
6564 [(set (match_operand:DI 0 "register_operand" "=r,b")
6565 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6566 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6567 "TARGET_ARCH64"
6568 "@
6569 and\\t%1, %2, %0
6570 fand\\t%1, %2, %0"
6571 [(set_attr "type" "*,fp")
6572 (set_attr "fptype" "double")])
6573
6574 (define_insn "andsi3"
6575 [(set (match_operand:SI 0 "register_operand" "=r,d")
6576 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6577 (match_operand:SI 2 "arith_operand" "rI,d")))]
6578 ""
6579 "@
6580 and\\t%1, %2, %0
6581 fands\\t%1, %2, %0"
6582 [(set_attr "type" "*,fp")])
6583
6584 (define_split
6585 [(set (match_operand:SI 0 "register_operand" "")
6586 (and:SI (match_operand:SI 1 "register_operand" "")
6587 (match_operand:SI 2 "" "")))
6588 (clobber (match_operand:SI 3 "register_operand" ""))]
6589 "GET_CODE (operands[2]) == CONST_INT
6590 && !SMALL_INT32 (operands[2])
6591 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6592 [(set (match_dup 3) (match_dup 4))
6593 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6594 "
6595 {
6596 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6597 }")
6598
6599 ;; Split DImode logical operations requiring two instructions.
6600 (define_split
6601 [(set (match_operand:DI 0 "register_operand" "")
6602 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6603 [(match_operand:DI 2 "register_operand" "")
6604 (match_operand:DI 3 "arith_double_operand" "")]))]
6605 "! TARGET_ARCH64
6606 && reload_completed
6607 && ((GET_CODE (operands[0]) == REG
6608 && REGNO (operands[0]) < 32)
6609 || (GET_CODE (operands[0]) == SUBREG
6610 && GET_CODE (SUBREG_REG (operands[0])) == REG
6611 && REGNO (SUBREG_REG (operands[0])) < 32))"
6612 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6613 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6614 "
6615 {
6616 if (GET_CODE (operands[0]) == SUBREG)
6617 operands[0] = alter_subreg (operands[0]);
6618 operands[4] = gen_highpart (SImode, operands[0]);
6619 operands[5] = gen_lowpart (SImode, operands[0]);
6620 operands[6] = gen_highpart (SImode, operands[2]);
6621 operands[7] = gen_lowpart (SImode, operands[2]);
6622 #if HOST_BITS_PER_WIDE_INT == 32
6623 if (GET_CODE (operands[3]) == CONST_INT)
6624 {
6625 if (INTVAL (operands[3]) < 0)
6626 operands[8] = constm1_rtx;
6627 else
6628 operands[8] = const0_rtx;
6629 }
6630 else
6631 #endif
6632 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6633 operands[9] = gen_lowpart (SImode, operands[3]);
6634 }")
6635
6636 (define_insn "*and_not_di_sp32"
6637 [(set (match_operand:DI 0 "register_operand" "=r,b")
6638 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6639 (match_operand:DI 2 "register_operand" "r,b")))]
6640 "! TARGET_ARCH64"
6641 "@
6642 #
6643 fandnot1\\t%1, %2, %0"
6644 [(set_attr "type" "*,fp")
6645 (set_attr "length" "2,*")
6646 (set_attr "fptype" "double")])
6647
6648 (define_split
6649 [(set (match_operand:DI 0 "register_operand" "")
6650 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6651 (match_operand:DI 2 "register_operand" "")))]
6652 "! TARGET_ARCH64
6653 && reload_completed
6654 && ((GET_CODE (operands[0]) == REG
6655 && REGNO (operands[0]) < 32)
6656 || (GET_CODE (operands[0]) == SUBREG
6657 && GET_CODE (SUBREG_REG (operands[0])) == REG
6658 && REGNO (SUBREG_REG (operands[0])) < 32))"
6659 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6660 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6661 "if (GET_CODE (operands[0]) == SUBREG)
6662 operands[0] = alter_subreg (operands[0]);
6663 operands[3] = gen_highpart (SImode, operands[0]);
6664 operands[4] = gen_highpart (SImode, operands[1]);
6665 operands[5] = gen_highpart (SImode, operands[2]);
6666 operands[6] = gen_lowpart (SImode, operands[0]);
6667 operands[7] = gen_lowpart (SImode, operands[1]);
6668 operands[8] = gen_lowpart (SImode, operands[2]);")
6669
6670 (define_insn "*and_not_di_sp64"
6671 [(set (match_operand:DI 0 "register_operand" "=r,b")
6672 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6673 (match_operand:DI 2 "register_operand" "r,b")))]
6674 "TARGET_ARCH64"
6675 "@
6676 andn\\t%2, %1, %0
6677 fandnot1\\t%1, %2, %0"
6678 [(set_attr "type" "*,fp")
6679 (set_attr "fptype" "double")])
6680
6681 (define_insn "*and_not_si"
6682 [(set (match_operand:SI 0 "register_operand" "=r,d")
6683 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6684 (match_operand:SI 2 "register_operand" "r,d")))]
6685 ""
6686 "@
6687 andn\\t%2, %1, %0
6688 fandnot1s\\t%1, %2, %0"
6689 [(set_attr "type" "*,fp")])
6690
6691 (define_expand "iordi3"
6692 [(set (match_operand:DI 0 "register_operand" "")
6693 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6694 (match_operand:DI 2 "arith_double_operand" "")))]
6695 ""
6696 "")
6697
6698 (define_insn "*iordi3_sp32"
6699 [(set (match_operand:DI 0 "register_operand" "=r,b")
6700 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6701 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6702 "! TARGET_ARCH64"
6703 "@
6704 #
6705 for\\t%1, %2, %0"
6706 [(set_attr "type" "*,fp")
6707 (set_attr "length" "2,*")
6708 (set_attr "fptype" "double")])
6709
6710 (define_insn "*iordi3_sp64"
6711 [(set (match_operand:DI 0 "register_operand" "=r,b")
6712 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6713 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6714 "TARGET_ARCH64"
6715 "@
6716 or\\t%1, %2, %0
6717 for\\t%1, %2, %0"
6718 [(set_attr "type" "*,fp")
6719 (set_attr "fptype" "double")])
6720
6721 (define_insn "iorsi3"
6722 [(set (match_operand:SI 0 "register_operand" "=r,d")
6723 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6724 (match_operand:SI 2 "arith_operand" "rI,d")))]
6725 ""
6726 "@
6727 or\\t%1, %2, %0
6728 fors\\t%1, %2, %0"
6729 [(set_attr "type" "*,fp")])
6730
6731 (define_split
6732 [(set (match_operand:SI 0 "register_operand" "")
6733 (ior:SI (match_operand:SI 1 "register_operand" "")
6734 (match_operand:SI 2 "" "")))
6735 (clobber (match_operand:SI 3 "register_operand" ""))]
6736 "GET_CODE (operands[2]) == CONST_INT
6737 && !SMALL_INT32 (operands[2])
6738 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6739 [(set (match_dup 3) (match_dup 4))
6740 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6741 "
6742 {
6743 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6744 }")
6745
6746 (define_insn "*or_not_di_sp32"
6747 [(set (match_operand:DI 0 "register_operand" "=r,b")
6748 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6749 (match_operand:DI 2 "register_operand" "r,b")))]
6750 "! TARGET_ARCH64"
6751 "@
6752 #
6753 fornot1\\t%1, %2, %0"
6754 [(set_attr "type" "*,fp")
6755 (set_attr "length" "2,*")
6756 (set_attr "fptype" "double")])
6757
6758 (define_split
6759 [(set (match_operand:DI 0 "register_operand" "")
6760 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6761 (match_operand:DI 2 "register_operand" "")))]
6762 "! TARGET_ARCH64
6763 && reload_completed
6764 && ((GET_CODE (operands[0]) == REG
6765 && REGNO (operands[0]) < 32)
6766 || (GET_CODE (operands[0]) == SUBREG
6767 && GET_CODE (SUBREG_REG (operands[0])) == REG
6768 && REGNO (SUBREG_REG (operands[0])) < 32))"
6769 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6770 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6771 "if (GET_CODE (operands[0]) == SUBREG)
6772 operands[0] = alter_subreg (operands[0]);
6773 operands[3] = gen_highpart (SImode, operands[0]);
6774 operands[4] = gen_highpart (SImode, operands[1]);
6775 operands[5] = gen_highpart (SImode, operands[2]);
6776 operands[6] = gen_lowpart (SImode, operands[0]);
6777 operands[7] = gen_lowpart (SImode, operands[1]);
6778 operands[8] = gen_lowpart (SImode, operands[2]);")
6779
6780 (define_insn "*or_not_di_sp64"
6781 [(set (match_operand:DI 0 "register_operand" "=r,b")
6782 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6783 (match_operand:DI 2 "register_operand" "r,b")))]
6784 "TARGET_ARCH64"
6785 "@
6786 orn\\t%2, %1, %0
6787 fornot1\\t%1, %2, %0"
6788 [(set_attr "type" "*,fp")
6789 (set_attr "fptype" "double")])
6790
6791 (define_insn "*or_not_si"
6792 [(set (match_operand:SI 0 "register_operand" "=r,d")
6793 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6794 (match_operand:SI 2 "register_operand" "r,d")))]
6795 ""
6796 "@
6797 orn\\t%2, %1, %0
6798 fornot1s\\t%1, %2, %0"
6799 [(set_attr "type" "*,fp")])
6800
6801 (define_expand "xordi3"
6802 [(set (match_operand:DI 0 "register_operand" "")
6803 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6804 (match_operand:DI 2 "arith_double_operand" "")))]
6805 ""
6806 "")
6807
6808 (define_insn "*xordi3_sp32"
6809 [(set (match_operand:DI 0 "register_operand" "=r,b")
6810 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6811 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6812 "! TARGET_ARCH64"
6813 "@
6814 #
6815 fxor\\t%1, %2, %0"
6816 [(set_attr "type" "*,fp")
6817 (set_attr "length" "2,*")
6818 (set_attr "fptype" "double")])
6819
6820 (define_insn "*xordi3_sp64"
6821 [(set (match_operand:DI 0 "register_operand" "=r,b")
6822 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6823 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6824 "TARGET_ARCH64"
6825 "@
6826 xor\\t%r1, %2, %0
6827 fxor\\t%1, %2, %0"
6828 [(set_attr "type" "*,fp")
6829 (set_attr "fptype" "double")])
6830
6831 (define_insn "*xordi3_sp64_dbl"
6832 [(set (match_operand:DI 0 "register_operand" "=r")
6833 (xor:DI (match_operand:DI 1 "register_operand" "r")
6834 (match_operand:DI 2 "const64_operand" "")))]
6835 "(TARGET_ARCH64
6836 && HOST_BITS_PER_WIDE_INT != 64)"
6837 "xor\\t%1, %2, %0")
6838
6839 (define_insn "xorsi3"
6840 [(set (match_operand:SI 0 "register_operand" "=r,d")
6841 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6842 (match_operand:SI 2 "arith_operand" "rI,d")))]
6843 ""
6844 "@
6845 xor\\t%r1, %2, %0
6846 fxors\\t%1, %2, %0"
6847 [(set_attr "type" "*,fp")])
6848
6849 (define_split
6850 [(set (match_operand:SI 0 "register_operand" "")
6851 (xor:SI (match_operand:SI 1 "register_operand" "")
6852 (match_operand:SI 2 "" "")))
6853 (clobber (match_operand:SI 3 "register_operand" ""))]
6854 "GET_CODE (operands[2]) == CONST_INT
6855 && !SMALL_INT32 (operands[2])
6856 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6857 [(set (match_dup 3) (match_dup 4))
6858 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6859 "
6860 {
6861 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6862 }")
6863
6864 (define_split
6865 [(set (match_operand:SI 0 "register_operand" "")
6866 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6867 (match_operand:SI 2 "" ""))))
6868 (clobber (match_operand:SI 3 "register_operand" ""))]
6869 "GET_CODE (operands[2]) == CONST_INT
6870 && !SMALL_INT32 (operands[2])
6871 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6872 [(set (match_dup 3) (match_dup 4))
6873 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6874 "
6875 {
6876 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6877 }")
6878
6879 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6880 ;; Combine now canonicalizes to the rightmost expression.
6881 (define_insn "*xor_not_di_sp32"
6882 [(set (match_operand:DI 0 "register_operand" "=r,b")
6883 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6884 (match_operand:DI 2 "register_operand" "r,b"))))]
6885 "! TARGET_ARCH64"
6886 "@
6887 #
6888 fxnor\\t%1, %2, %0"
6889 [(set_attr "type" "*,fp")
6890 (set_attr "length" "2,*")
6891 (set_attr "fptype" "double")])
6892
6893 (define_split
6894 [(set (match_operand:DI 0 "register_operand" "")
6895 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6896 (match_operand:DI 2 "register_operand" ""))))]
6897 "! TARGET_ARCH64
6898 && reload_completed
6899 && ((GET_CODE (operands[0]) == REG
6900 && REGNO (operands[0]) < 32)
6901 || (GET_CODE (operands[0]) == SUBREG
6902 && GET_CODE (SUBREG_REG (operands[0])) == REG
6903 && REGNO (SUBREG_REG (operands[0])) < 32))"
6904 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6905 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6906 "if (GET_CODE (operands[0]) == SUBREG)
6907 operands[0] = alter_subreg (operands[0]);
6908 operands[3] = gen_highpart (SImode, operands[0]);
6909 operands[4] = gen_highpart (SImode, operands[1]);
6910 operands[5] = gen_highpart (SImode, operands[2]);
6911 operands[6] = gen_lowpart (SImode, operands[0]);
6912 operands[7] = gen_lowpart (SImode, operands[1]);
6913 operands[8] = gen_lowpart (SImode, operands[2]);")
6914
6915 (define_insn "*xor_not_di_sp64"
6916 [(set (match_operand:DI 0 "register_operand" "=r,b")
6917 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6918 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6919 "TARGET_ARCH64"
6920 "@
6921 xnor\\t%r1, %2, %0
6922 fxnor\\t%1, %2, %0"
6923 [(set_attr "type" "*,fp")
6924 (set_attr "fptype" "double")])
6925
6926 (define_insn "*xor_not_si"
6927 [(set (match_operand:SI 0 "register_operand" "=r,d")
6928 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6929 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6930 ""
6931 "@
6932 xnor\\t%r1, %2, %0
6933 fxnors\\t%1, %2, %0"
6934 [(set_attr "type" "*,fp")])
6935
6936 ;; These correspond to the above in the case where we also (or only)
6937 ;; want to set the condition code.
6938
6939 (define_insn "*cmp_cc_arith_op"
6940 [(set (reg:CC 100)
6941 (compare:CC
6942 (match_operator:SI 2 "cc_arithop"
6943 [(match_operand:SI 0 "arith_operand" "%r")
6944 (match_operand:SI 1 "arith_operand" "rI")])
6945 (const_int 0)))]
6946 ""
6947 "%A2cc\\t%0, %1, %%g0"
6948 [(set_attr "type" "compare")])
6949
6950 (define_insn "*cmp_ccx_arith_op"
6951 [(set (reg:CCX 100)
6952 (compare:CCX
6953 (match_operator:DI 2 "cc_arithop"
6954 [(match_operand:DI 0 "arith_double_operand" "%r")
6955 (match_operand:DI 1 "arith_double_operand" "rHI")])
6956 (const_int 0)))]
6957 "TARGET_ARCH64"
6958 "%A2cc\\t%0, %1, %%g0"
6959 [(set_attr "type" "compare")])
6960
6961 (define_insn "*cmp_cc_arith_op_set"
6962 [(set (reg:CC 100)
6963 (compare:CC
6964 (match_operator:SI 3 "cc_arithop"
6965 [(match_operand:SI 1 "arith_operand" "%r")
6966 (match_operand:SI 2 "arith_operand" "rI")])
6967 (const_int 0)))
6968 (set (match_operand:SI 0 "register_operand" "=r")
6969 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6970 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6971 "%A3cc\\t%1, %2, %0"
6972 [(set_attr "type" "compare")])
6973
6974 (define_insn "*cmp_ccx_arith_op_set"
6975 [(set (reg:CCX 100)
6976 (compare:CCX
6977 (match_operator:DI 3 "cc_arithop"
6978 [(match_operand:DI 1 "arith_double_operand" "%r")
6979 (match_operand:DI 2 "arith_double_operand" "rHI")])
6980 (const_int 0)))
6981 (set (match_operand:DI 0 "register_operand" "=r")
6982 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6983 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6984 "%A3cc\\t%1, %2, %0"
6985 [(set_attr "type" "compare")])
6986
6987 (define_insn "*cmp_cc_xor_not"
6988 [(set (reg:CC 100)
6989 (compare:CC
6990 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6991 (match_operand:SI 1 "arith_operand" "rI")))
6992 (const_int 0)))]
6993 ""
6994 "xnorcc\\t%r0, %1, %%g0"
6995 [(set_attr "type" "compare")])
6996
6997 (define_insn "*cmp_ccx_xor_not"
6998 [(set (reg:CCX 100)
6999 (compare:CCX
7000 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7001 (match_operand:DI 1 "arith_double_operand" "rHI")))
7002 (const_int 0)))]
7003 "TARGET_ARCH64"
7004 "xnorcc\\t%r0, %1, %%g0"
7005 [(set_attr "type" "compare")])
7006
7007 (define_insn "*cmp_cc_xor_not_set"
7008 [(set (reg:CC 100)
7009 (compare:CC
7010 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7011 (match_operand:SI 2 "arith_operand" "rI")))
7012 (const_int 0)))
7013 (set (match_operand:SI 0 "register_operand" "=r")
7014 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7015 ""
7016 "xnorcc\\t%r1, %2, %0"
7017 [(set_attr "type" "compare")])
7018
7019 (define_insn "*cmp_ccx_xor_not_set"
7020 [(set (reg:CCX 100)
7021 (compare:CCX
7022 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7023 (match_operand:DI 2 "arith_double_operand" "rHI")))
7024 (const_int 0)))
7025 (set (match_operand:DI 0 "register_operand" "=r")
7026 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7027 "TARGET_ARCH64"
7028 "xnorcc\\t%r1, %2, %0"
7029 [(set_attr "type" "compare")])
7030
7031 (define_insn "*cmp_cc_arith_op_not"
7032 [(set (reg:CC 100)
7033 (compare:CC
7034 (match_operator:SI 2 "cc_arithopn"
7035 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7036 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7037 (const_int 0)))]
7038 ""
7039 "%B2cc\\t%r1, %0, %%g0"
7040 [(set_attr "type" "compare")])
7041
7042 (define_insn "*cmp_ccx_arith_op_not"
7043 [(set (reg:CCX 100)
7044 (compare:CCX
7045 (match_operator:DI 2 "cc_arithopn"
7046 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7047 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7048 (const_int 0)))]
7049 "TARGET_ARCH64"
7050 "%B2cc\\t%r1, %0, %%g0"
7051 [(set_attr "type" "compare")])
7052
7053 (define_insn "*cmp_cc_arith_op_not_set"
7054 [(set (reg:CC 100)
7055 (compare:CC
7056 (match_operator:SI 3 "cc_arithopn"
7057 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7058 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7059 (const_int 0)))
7060 (set (match_operand:SI 0 "register_operand" "=r")
7061 (match_operator:SI 4 "cc_arithopn"
7062 [(not:SI (match_dup 1)) (match_dup 2)]))]
7063 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7064 "%B3cc\\t%r2, %1, %0"
7065 [(set_attr "type" "compare")])
7066
7067 (define_insn "*cmp_ccx_arith_op_not_set"
7068 [(set (reg:CCX 100)
7069 (compare:CCX
7070 (match_operator:DI 3 "cc_arithopn"
7071 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7072 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7073 (const_int 0)))
7074 (set (match_operand:DI 0 "register_operand" "=r")
7075 (match_operator:DI 4 "cc_arithopn"
7076 [(not:DI (match_dup 1)) (match_dup 2)]))]
7077 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7078 "%B3cc\\t%r2, %1, %0"
7079 [(set_attr "type" "compare")])
7080
7081 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7082 ;; does not know how to make it work for constants.
7083
7084 (define_expand "negdi2"
7085 [(set (match_operand:DI 0 "register_operand" "=r")
7086 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7087 ""
7088 "
7089 {
7090 if (! TARGET_ARCH64)
7091 {
7092 emit_insn (gen_rtx_PARALLEL
7093 (VOIDmode,
7094 gen_rtvec (2,
7095 gen_rtx_SET (VOIDmode, operand0,
7096 gen_rtx_NEG (DImode, operand1)),
7097 gen_rtx_CLOBBER (VOIDmode,
7098 gen_rtx_REG (CCmode,
7099 SPARC_ICC_REG)))));
7100 DONE;
7101 }
7102 }")
7103
7104 (define_insn "*negdi2_sp32"
7105 [(set (match_operand:DI 0 "register_operand" "=r")
7106 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7107 (clobber (reg:CC 100))]
7108 "TARGET_ARCH32"
7109 "#"
7110 [(set_attr "length" "2")])
7111
7112 (define_split
7113 [(set (match_operand:DI 0 "register_operand" "")
7114 (neg:DI (match_operand:DI 1 "register_operand" "")))
7115 (clobber (reg:CC 100))]
7116 "TARGET_ARCH32
7117 && reload_completed"
7118 [(parallel [(set (reg:CC_NOOV 100)
7119 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7120 (const_int 0)))
7121 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7122 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7123 (ltu:SI (reg:CC 100) (const_int 0))))]
7124 "operands[2] = gen_highpart (SImode, operands[0]);
7125 operands[3] = gen_highpart (SImode, operands[1]);
7126 operands[4] = gen_lowpart (SImode, operands[0]);
7127 operands[5] = gen_lowpart (SImode, operands[1]);")
7128
7129 (define_insn "*negdi2_sp64"
7130 [(set (match_operand:DI 0 "register_operand" "=r")
7131 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7132 "TARGET_ARCH64"
7133 "sub\\t%%g0, %1, %0")
7134
7135 (define_insn "negsi2"
7136 [(set (match_operand:SI 0 "register_operand" "=r")
7137 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7138 ""
7139 "sub\\t%%g0, %1, %0")
7140
7141 (define_insn "*cmp_cc_neg"
7142 [(set (reg:CC_NOOV 100)
7143 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7144 (const_int 0)))]
7145 ""
7146 "subcc\\t%%g0, %0, %%g0"
7147 [(set_attr "type" "compare")])
7148
7149 (define_insn "*cmp_ccx_neg"
7150 [(set (reg:CCX_NOOV 100)
7151 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7152 (const_int 0)))]
7153 "TARGET_ARCH64"
7154 "subcc\\t%%g0, %0, %%g0"
7155 [(set_attr "type" "compare")])
7156
7157 (define_insn "*cmp_cc_set_neg"
7158 [(set (reg:CC_NOOV 100)
7159 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7160 (const_int 0)))
7161 (set (match_operand:SI 0 "register_operand" "=r")
7162 (neg:SI (match_dup 1)))]
7163 ""
7164 "subcc\\t%%g0, %1, %0"
7165 [(set_attr "type" "compare")])
7166
7167 (define_insn "*cmp_ccx_set_neg"
7168 [(set (reg:CCX_NOOV 100)
7169 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7170 (const_int 0)))
7171 (set (match_operand:DI 0 "register_operand" "=r")
7172 (neg:DI (match_dup 1)))]
7173 "TARGET_ARCH64"
7174 "subcc\\t%%g0, %1, %0"
7175 [(set_attr "type" "compare")])
7176
7177 ;; We cannot use the "not" pseudo insn because the Sun assembler
7178 ;; does not know how to make it work for constants.
7179 (define_expand "one_cmpldi2"
7180 [(set (match_operand:DI 0 "register_operand" "")
7181 (not:DI (match_operand:DI 1 "register_operand" "")))]
7182 ""
7183 "")
7184
7185 (define_insn "*one_cmpldi2_sp32"
7186 [(set (match_operand:DI 0 "register_operand" "=r,b")
7187 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7188 "! TARGET_ARCH64"
7189 "@
7190 #
7191 fnot1\\t%1, %0"
7192 [(set_attr "type" "*,fp")
7193 (set_attr "length" "2,*")
7194 (set_attr "fptype" "double")])
7195
7196 (define_split
7197 [(set (match_operand:DI 0 "register_operand" "")
7198 (not:DI (match_operand:DI 1 "register_operand" "")))]
7199 "! TARGET_ARCH64
7200 && reload_completed
7201 && ((GET_CODE (operands[0]) == REG
7202 && REGNO (operands[0]) < 32)
7203 || (GET_CODE (operands[0]) == SUBREG
7204 && GET_CODE (SUBREG_REG (operands[0])) == REG
7205 && REGNO (SUBREG_REG (operands[0])) < 32))"
7206 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7207 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7208 "if (GET_CODE (operands[0]) == SUBREG)
7209 operands[0] = alter_subreg (operands[0]);
7210 operands[2] = gen_highpart (SImode, operands[0]);
7211 operands[3] = gen_highpart (SImode, operands[1]);
7212 operands[4] = gen_lowpart (SImode, operands[0]);
7213 operands[5] = gen_lowpart (SImode, operands[1]);")
7214
7215 (define_insn "*one_cmpldi2_sp64"
7216 [(set (match_operand:DI 0 "register_operand" "=r,b")
7217 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7218 "TARGET_ARCH64"
7219 "@
7220 xnor\\t%%g0, %1, %0
7221 fnot1\\t%1, %0"
7222 [(set_attr "type" "*,fp")
7223 (set_attr "fptype" "double")])
7224
7225 (define_insn "one_cmplsi2"
7226 [(set (match_operand:SI 0 "register_operand" "=r,d")
7227 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7228 ""
7229 "@
7230 xnor\\t%%g0, %1, %0
7231 fnot1s\\t%1, %0"
7232 [(set_attr "type" "*,fp")])
7233
7234 (define_insn "*cmp_cc_not"
7235 [(set (reg:CC 100)
7236 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7237 (const_int 0)))]
7238 ""
7239 "xnorcc\\t%%g0, %0, %%g0"
7240 [(set_attr "type" "compare")])
7241
7242 (define_insn "*cmp_ccx_not"
7243 [(set (reg:CCX 100)
7244 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7245 (const_int 0)))]
7246 "TARGET_ARCH64"
7247 "xnorcc\\t%%g0, %0, %%g0"
7248 [(set_attr "type" "compare")])
7249
7250 (define_insn "*cmp_cc_set_not"
7251 [(set (reg:CC 100)
7252 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7253 (const_int 0)))
7254 (set (match_operand:SI 0 "register_operand" "=r")
7255 (not:SI (match_dup 1)))]
7256 ""
7257 "xnorcc\\t%%g0, %1, %0"
7258 [(set_attr "type" "compare")])
7259
7260 (define_insn "*cmp_ccx_set_not"
7261 [(set (reg:CCX 100)
7262 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7263 (const_int 0)))
7264 (set (match_operand:DI 0 "register_operand" "=r")
7265 (not:DI (match_dup 1)))]
7266 "TARGET_ARCH64"
7267 "xnorcc\\t%%g0, %1, %0"
7268 [(set_attr "type" "compare")])
7269 \f
7270 ;; Floating point arithmetic instructions.
7271
7272 (define_expand "addtf3"
7273 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7274 (plus:TF (match_operand:TF 1 "general_operand" "")
7275 (match_operand:TF 2 "general_operand" "")))]
7276 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7277 "
7278 {
7279 if (! TARGET_HARD_QUAD)
7280 {
7281 rtx slot0, slot1, slot2;
7282
7283 if (GET_CODE (operands[0]) != MEM)
7284 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7285 else
7286 slot0 = operands[0];
7287 if (GET_CODE (operands[1]) != MEM)
7288 {
7289 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7290 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7291 }
7292 else
7293 slot1 = operands[1];
7294 if (GET_CODE (operands[2]) != MEM)
7295 {
7296 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7297 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7298 }
7299 else
7300 slot2 = operands[2];
7301
7302 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7303 VOIDmode, 3,
7304 XEXP (slot0, 0), Pmode,
7305 XEXP (slot1, 0), Pmode,
7306 XEXP (slot2, 0), Pmode);
7307
7308 if (GET_CODE (operands[0]) != MEM)
7309 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7310 DONE;
7311 }
7312 }")
7313
7314 (define_insn "*addtf3_hq"
7315 [(set (match_operand:TF 0 "register_operand" "=e")
7316 (plus:TF (match_operand:TF 1 "register_operand" "e")
7317 (match_operand:TF 2 "register_operand" "e")))]
7318 "TARGET_FPU && TARGET_HARD_QUAD"
7319 "faddq\\t%1, %2, %0"
7320 [(set_attr "type" "fp")])
7321
7322 (define_insn "adddf3"
7323 [(set (match_operand:DF 0 "register_operand" "=e")
7324 (plus:DF (match_operand:DF 1 "register_operand" "e")
7325 (match_operand:DF 2 "register_operand" "e")))]
7326 "TARGET_FPU"
7327 "faddd\\t%1, %2, %0"
7328 [(set_attr "type" "fp")
7329 (set_attr "fptype" "double")])
7330
7331 (define_insn "addsf3"
7332 [(set (match_operand:SF 0 "register_operand" "=f")
7333 (plus:SF (match_operand:SF 1 "register_operand" "f")
7334 (match_operand:SF 2 "register_operand" "f")))]
7335 "TARGET_FPU"
7336 "fadds\\t%1, %2, %0"
7337 [(set_attr "type" "fp")])
7338
7339 (define_expand "subtf3"
7340 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7341 (minus:TF (match_operand:TF 1 "general_operand" "")
7342 (match_operand:TF 2 "general_operand" "")))]
7343 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7344 "
7345 {
7346 if (! TARGET_HARD_QUAD)
7347 {
7348 rtx slot0, slot1, slot2;
7349
7350 if (GET_CODE (operands[0]) != MEM)
7351 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7352 else
7353 slot0 = operands[0];
7354 if (GET_CODE (operands[1]) != MEM)
7355 {
7356 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7357 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7358 }
7359 else
7360 slot1 = operands[1];
7361 if (GET_CODE (operands[2]) != MEM)
7362 {
7363 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7364 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7365 }
7366 else
7367 slot2 = operands[2];
7368
7369 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7370 VOIDmode, 3,
7371 XEXP (slot0, 0), Pmode,
7372 XEXP (slot1, 0), Pmode,
7373 XEXP (slot2, 0), Pmode);
7374
7375 if (GET_CODE (operands[0]) != MEM)
7376 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7377 DONE;
7378 }
7379 }")
7380
7381 (define_insn "*subtf3_hq"
7382 [(set (match_operand:TF 0 "register_operand" "=e")
7383 (minus:TF (match_operand:TF 1 "register_operand" "e")
7384 (match_operand:TF 2 "register_operand" "e")))]
7385 "TARGET_FPU && TARGET_HARD_QUAD"
7386 "fsubq\\t%1, %2, %0"
7387 [(set_attr "type" "fp")])
7388
7389 (define_insn "subdf3"
7390 [(set (match_operand:DF 0 "register_operand" "=e")
7391 (minus:DF (match_operand:DF 1 "register_operand" "e")
7392 (match_operand:DF 2 "register_operand" "e")))]
7393 "TARGET_FPU"
7394 "fsubd\\t%1, %2, %0"
7395 [(set_attr "type" "fp")
7396 (set_attr "fptype" "double")])
7397
7398 (define_insn "subsf3"
7399 [(set (match_operand:SF 0 "register_operand" "=f")
7400 (minus:SF (match_operand:SF 1 "register_operand" "f")
7401 (match_operand:SF 2 "register_operand" "f")))]
7402 "TARGET_FPU"
7403 "fsubs\\t%1, %2, %0"
7404 [(set_attr "type" "fp")])
7405
7406 (define_expand "multf3"
7407 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7408 (mult:TF (match_operand:TF 1 "general_operand" "")
7409 (match_operand:TF 2 "general_operand" "")))]
7410 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7411 "
7412 {
7413 if (! TARGET_HARD_QUAD)
7414 {
7415 rtx slot0, slot1, slot2;
7416
7417 if (GET_CODE (operands[0]) != MEM)
7418 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7419 else
7420 slot0 = operands[0];
7421 if (GET_CODE (operands[1]) != MEM)
7422 {
7423 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7424 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7425 }
7426 else
7427 slot1 = operands[1];
7428 if (GET_CODE (operands[2]) != MEM)
7429 {
7430 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7431 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7432 }
7433 else
7434 slot2 = operands[2];
7435
7436 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7437 VOIDmode, 3,
7438 XEXP (slot0, 0), Pmode,
7439 XEXP (slot1, 0), Pmode,
7440 XEXP (slot2, 0), Pmode);
7441
7442 if (GET_CODE (operands[0]) != MEM)
7443 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7444 DONE;
7445 }
7446 }")
7447
7448 (define_insn "*multf3_hq"
7449 [(set (match_operand:TF 0 "register_operand" "=e")
7450 (mult:TF (match_operand:TF 1 "register_operand" "e")
7451 (match_operand:TF 2 "register_operand" "e")))]
7452 "TARGET_FPU && TARGET_HARD_QUAD"
7453 "fmulq\\t%1, %2, %0"
7454 [(set_attr "type" "fpmul")])
7455
7456 (define_insn "muldf3"
7457 [(set (match_operand:DF 0 "register_operand" "=e")
7458 (mult:DF (match_operand:DF 1 "register_operand" "e")
7459 (match_operand:DF 2 "register_operand" "e")))]
7460 "TARGET_FPU"
7461 "fmuld\\t%1, %2, %0"
7462 [(set_attr "type" "fpmul")
7463 (set_attr "fptype" "double")])
7464
7465 (define_insn "mulsf3"
7466 [(set (match_operand:SF 0 "register_operand" "=f")
7467 (mult:SF (match_operand:SF 1 "register_operand" "f")
7468 (match_operand:SF 2 "register_operand" "f")))]
7469 "TARGET_FPU"
7470 "fmuls\\t%1, %2, %0"
7471 [(set_attr "type" "fpmul")])
7472
7473 (define_insn "*muldf3_extend"
7474 [(set (match_operand:DF 0 "register_operand" "=e")
7475 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7476 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7477 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7478 "fsmuld\\t%1, %2, %0"
7479 [(set_attr "type" "fpmul")
7480 (set_attr "fptype" "double")])
7481
7482 (define_insn "*multf3_extend"
7483 [(set (match_operand:TF 0 "register_operand" "=e")
7484 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7485 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7486 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7487 "fdmulq\\t%1, %2, %0"
7488 [(set_attr "type" "fpmul")])
7489
7490 (define_expand "divtf3"
7491 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7492 (div:TF (match_operand:TF 1 "general_operand" "")
7493 (match_operand:TF 2 "general_operand" "")))]
7494 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7495 "
7496 {
7497 if (! TARGET_HARD_QUAD)
7498 {
7499 rtx slot0, slot1, slot2;
7500
7501 if (GET_CODE (operands[0]) != MEM)
7502 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7503 else
7504 slot0 = operands[0];
7505 if (GET_CODE (operands[1]) != MEM)
7506 {
7507 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7508 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7509 }
7510 else
7511 slot1 = operands[1];
7512 if (GET_CODE (operands[2]) != MEM)
7513 {
7514 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7515 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7516 }
7517 else
7518 slot2 = operands[2];
7519
7520 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7521 VOIDmode, 3,
7522 XEXP (slot0, 0), Pmode,
7523 XEXP (slot1, 0), Pmode,
7524 XEXP (slot2, 0), Pmode);
7525
7526 if (GET_CODE (operands[0]) != MEM)
7527 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7528 DONE;
7529 }
7530 }")
7531
7532 ;; don't have timing for quad-prec. divide.
7533 (define_insn "*divtf3_hq"
7534 [(set (match_operand:TF 0 "register_operand" "=e")
7535 (div:TF (match_operand:TF 1 "register_operand" "e")
7536 (match_operand:TF 2 "register_operand" "e")))]
7537 "TARGET_FPU && TARGET_HARD_QUAD"
7538 "fdivq\\t%1, %2, %0"
7539 [(set_attr "type" "fpdivd")])
7540
7541 (define_insn "divdf3"
7542 [(set (match_operand:DF 0 "register_operand" "=e")
7543 (div:DF (match_operand:DF 1 "register_operand" "e")
7544 (match_operand:DF 2 "register_operand" "e")))]
7545 "TARGET_FPU"
7546 "fdivd\\t%1, %2, %0"
7547 [(set_attr "type" "fpdivd")
7548 (set_attr "fptype" "double")])
7549
7550 (define_insn "divsf3"
7551 [(set (match_operand:SF 0 "register_operand" "=f")
7552 (div:SF (match_operand:SF 1 "register_operand" "f")
7553 (match_operand:SF 2 "register_operand" "f")))]
7554 "TARGET_FPU"
7555 "fdivs\\t%1, %2, %0"
7556 [(set_attr "type" "fpdivs")])
7557
7558 (define_expand "negtf2"
7559 [(set (match_operand:TF 0 "register_operand" "=e,e")
7560 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7561 "TARGET_FPU"
7562 "")
7563
7564 (define_insn "*negtf2_notv9"
7565 [(set (match_operand:TF 0 "register_operand" "=e,e")
7566 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7567 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7568 "TARGET_FPU
7569 && ! TARGET_V9"
7570 "@
7571 fnegs\\t%0, %0
7572 #"
7573 [(set_attr "type" "fpmove,*")
7574 (set_attr "length" "*,2")])
7575
7576 (define_split
7577 [(set (match_operand:TF 0 "register_operand" "")
7578 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7579 "TARGET_FPU
7580 && ! TARGET_V9
7581 && reload_completed
7582 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7583 [(set (match_dup 2) (neg:SF (match_dup 3)))
7584 (set (match_dup 4) (match_dup 5))
7585 (set (match_dup 6) (match_dup 7))]
7586 "if (GET_CODE (operands[0]) == SUBREG)
7587 operands[0] = alter_subreg (operands[0]);
7588 if (GET_CODE (operands[1]) == SUBREG)
7589 operands[1] = alter_subreg (operands[1]);
7590 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7591 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7592 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7593 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7594 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7595 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7596
7597 (define_insn "*negtf2_v9"
7598 [(set (match_operand:TF 0 "register_operand" "=e,e")
7599 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7600 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7601 "TARGET_FPU && TARGET_V9"
7602 "@
7603 fnegd\\t%0, %0
7604 #"
7605 [(set_attr "type" "fpmove,*")
7606 (set_attr "length" "*,2")
7607 (set_attr "fptype" "double")])
7608
7609 (define_split
7610 [(set (match_operand:TF 0 "register_operand" "")
7611 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7612 "TARGET_FPU
7613 && TARGET_V9
7614 && reload_completed
7615 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7616 [(set (match_dup 2) (neg:DF (match_dup 3)))
7617 (set (match_dup 4) (match_dup 5))]
7618 "if (GET_CODE (operands[0]) == SUBREG)
7619 operands[0] = alter_subreg (operands[0]);
7620 if (GET_CODE (operands[1]) == SUBREG)
7621 operands[1] = alter_subreg (operands[1]);
7622 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7623 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7624 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7625 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7626
7627 (define_expand "negdf2"
7628 [(set (match_operand:DF 0 "register_operand" "")
7629 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7630 "TARGET_FPU"
7631 "")
7632
7633 (define_insn "*negdf2_notv9"
7634 [(set (match_operand:DF 0 "register_operand" "=e,e")
7635 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7636 "TARGET_FPU && ! TARGET_V9"
7637 "@
7638 fnegs\\t%0, %0
7639 #"
7640 [(set_attr "type" "fpmove,*")
7641 (set_attr "length" "*,2")])
7642
7643 (define_split
7644 [(set (match_operand:DF 0 "register_operand" "")
7645 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7646 "TARGET_FPU
7647 && ! TARGET_V9
7648 && reload_completed
7649 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7650 [(set (match_dup 2) (neg:SF (match_dup 3)))
7651 (set (match_dup 4) (match_dup 5))]
7652 "if (GET_CODE (operands[0]) == SUBREG)
7653 operands[0] = alter_subreg (operands[0]);
7654 if (GET_CODE (operands[1]) == SUBREG)
7655 operands[1] = alter_subreg (operands[1]);
7656 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7657 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7658 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7659 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7660
7661 (define_insn "*negdf2_v9"
7662 [(set (match_operand:DF 0 "register_operand" "=e")
7663 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7664 "TARGET_FPU && TARGET_V9"
7665 "fnegd\\t%1, %0"
7666 [(set_attr "type" "fpmove")
7667 (set_attr "fptype" "double")])
7668
7669 (define_insn "negsf2"
7670 [(set (match_operand:SF 0 "register_operand" "=f")
7671 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7672 "TARGET_FPU"
7673 "fnegs\\t%1, %0"
7674 [(set_attr "type" "fpmove")])
7675
7676 (define_expand "abstf2"
7677 [(set (match_operand:TF 0 "register_operand" "")
7678 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7679 "TARGET_FPU"
7680 "")
7681
7682 (define_insn "*abstf2_notv9"
7683 [(set (match_operand:TF 0 "register_operand" "=e,e")
7684 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7685 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7686 "TARGET_FPU && ! TARGET_V9"
7687 "@
7688 fabss\\t%0, %0
7689 #"
7690 [(set_attr "type" "fpmove,*")
7691 (set_attr "length" "*,2")])
7692
7693 (define_split
7694 [(set (match_operand:TF 0 "register_operand" "")
7695 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7696 "TARGET_FPU
7697 && ! TARGET_V9
7698 && reload_completed
7699 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7700 [(set (match_dup 2) (abs:SF (match_dup 3)))
7701 (set (match_dup 4) (match_dup 5))
7702 (set (match_dup 6) (match_dup 7))]
7703 "if (GET_CODE (operands[0]) == SUBREG)
7704 operands[0] = alter_subreg (operands[0]);
7705 if (GET_CODE (operands[1]) == SUBREG)
7706 operands[1] = alter_subreg (operands[1]);
7707 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7708 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7709 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7710 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7711 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7712 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7713
7714 (define_insn "*abstf2_hq_v9"
7715 [(set (match_operand:TF 0 "register_operand" "=e,e")
7716 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7717 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7718 "@
7719 fabsd\\t%0, %0
7720 fabsq\\t%1, %0"
7721 [(set_attr "type" "fpmove")
7722 (set_attr "fptype" "double,*")])
7723
7724 (define_insn "*abstf2_v9"
7725 [(set (match_operand:TF 0 "register_operand" "=e,e")
7726 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7727 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7728 "@
7729 fabsd\\t%0, %0
7730 #"
7731 [(set_attr "type" "fpmove,*")
7732 (set_attr "length" "*,2")
7733 (set_attr "fptype" "double,*")])
7734
7735 (define_split
7736 [(set (match_operand:TF 0 "register_operand" "")
7737 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7738 "TARGET_FPU
7739 && TARGET_V9
7740 && reload_completed
7741 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7742 [(set (match_dup 2) (abs:DF (match_dup 3)))
7743 (set (match_dup 4) (match_dup 5))]
7744 "if (GET_CODE (operands[0]) == SUBREG)
7745 operands[0] = alter_subreg (operands[0]);
7746 if (GET_CODE (operands[1]) == SUBREG)
7747 operands[1] = alter_subreg (operands[1]);
7748 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7749 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7750 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7751 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7752
7753 (define_expand "absdf2"
7754 [(set (match_operand:DF 0 "register_operand" "")
7755 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7756 "TARGET_FPU"
7757 "")
7758
7759 (define_insn "*absdf2_notv9"
7760 [(set (match_operand:DF 0 "register_operand" "=e,e")
7761 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7762 "TARGET_FPU && ! TARGET_V9"
7763 "@
7764 fabss\\t%0, %0
7765 #"
7766 [(set_attr "type" "fpmove,*")
7767 (set_attr "length" "*,2")])
7768
7769 (define_split
7770 [(set (match_operand:DF 0 "register_operand" "")
7771 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7772 "TARGET_FPU
7773 && ! TARGET_V9
7774 && reload_completed
7775 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7776 [(set (match_dup 2) (abs:SF (match_dup 3)))
7777 (set (match_dup 4) (match_dup 5))]
7778 "if (GET_CODE (operands[0]) == SUBREG)
7779 operands[0] = alter_subreg (operands[0]);
7780 if (GET_CODE (operands[1]) == SUBREG)
7781 operands[1] = alter_subreg (operands[1]);
7782 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7783 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7784 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7785 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7786
7787 (define_insn "*absdf2_v9"
7788 [(set (match_operand:DF 0 "register_operand" "=e")
7789 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7790 "TARGET_FPU && TARGET_V9"
7791 "fabsd\\t%1, %0"
7792 [(set_attr "type" "fpmove")
7793 (set_attr "fptype" "double")])
7794
7795 (define_insn "abssf2"
7796 [(set (match_operand:SF 0 "register_operand" "=f")
7797 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7798 "TARGET_FPU"
7799 "fabss\\t%1, %0"
7800 [(set_attr "type" "fpmove")])
7801
7802 (define_expand "sqrttf2"
7803 [(set (match_operand:TF 0 "register_operand" "=e")
7804 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7805 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7806 "
7807 {
7808 if (! TARGET_HARD_QUAD)
7809 {
7810 rtx slot0, slot1;
7811
7812 if (GET_CODE (operands[0]) != MEM)
7813 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7814 else
7815 slot0 = operands[0];
7816 if (GET_CODE (operands[1]) != MEM)
7817 {
7818 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7819 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7820 }
7821 else
7822 slot1 = operands[1];
7823
7824 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7825 VOIDmode, 2,
7826 XEXP (slot0, 0), Pmode,
7827 XEXP (slot1, 0), Pmode);
7828
7829 if (GET_CODE (operands[0]) != MEM)
7830 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7831 DONE;
7832 }
7833 }")
7834
7835 (define_insn "*sqrttf2_hq"
7836 [(set (match_operand:TF 0 "register_operand" "=e")
7837 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7838 "TARGET_FPU && TARGET_HARD_QUAD"
7839 "fsqrtq\\t%1, %0"
7840 [(set_attr "type" "fpsqrtd")])
7841
7842 (define_insn "sqrtdf2"
7843 [(set (match_operand:DF 0 "register_operand" "=e")
7844 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7845 "TARGET_FPU"
7846 "fsqrtd\\t%1, %0"
7847 [(set_attr "type" "fpsqrtd")
7848 (set_attr "fptype" "double")])
7849
7850 (define_insn "sqrtsf2"
7851 [(set (match_operand:SF 0 "register_operand" "=f")
7852 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7853 "TARGET_FPU"
7854 "fsqrts\\t%1, %0"
7855 [(set_attr "type" "fpsqrts")])
7856 \f
7857 ;;- arithmetic shift instructions
7858
7859 (define_insn "ashlsi3"
7860 [(set (match_operand:SI 0 "register_operand" "=r")
7861 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7862 (match_operand:SI 2 "arith_operand" "rI")))]
7863 ""
7864 "*
7865 {
7866 if (GET_CODE (operands[2]) == CONST_INT
7867 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7868 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7869
7870 return \"sll\\t%1, %2, %0\";
7871 }"
7872 [(set_attr "type" "shift")])
7873
7874 ;; We special case multiplication by two, as add can be done
7875 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7876 (define_insn "*ashlsi3_const1"
7877 [(set (match_operand:SI 0 "register_operand" "=r")
7878 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7879 (const_int 1)))]
7880 ""
7881 "add\\t%1, %1, %0")
7882
7883 (define_expand "ashldi3"
7884 [(set (match_operand:DI 0 "register_operand" "=r")
7885 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7886 (match_operand:SI 2 "arith_operand" "rI")))]
7887 "TARGET_ARCH64 || TARGET_V8PLUS"
7888 "
7889 {
7890 if (! TARGET_ARCH64)
7891 {
7892 if (GET_CODE (operands[2]) == CONST_INT)
7893 FAIL;
7894 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7895 DONE;
7896 }
7897 }")
7898
7899 ;; We special case multiplication by two, as add can be done
7900 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7901 (define_insn "*ashldi3_const1"
7902 [(set (match_operand:DI 0 "register_operand" "=r")
7903 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7904 (const_int 1)))]
7905 "TARGET_ARCH64"
7906 "add\\t%1, %1, %0")
7907
7908 (define_insn "*ashldi3_sp64"
7909 [(set (match_operand:DI 0 "register_operand" "=r")
7910 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7911 (match_operand:SI 2 "arith_operand" "rI")))]
7912 "TARGET_ARCH64"
7913 "*
7914 {
7915 if (GET_CODE (operands[2]) == CONST_INT
7916 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7917 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7918
7919 return \"sllx\\t%1, %2, %0\";
7920 }"
7921 [(set_attr "type" "shift")])
7922
7923 ;; XXX UGH!
7924 (define_insn "ashldi3_v8plus"
7925 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7926 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7927 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7928 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7929 "TARGET_V8PLUS"
7930 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7931 [(set_attr "type" "multi")
7932 (set_attr "length" "5,5,6")])
7933
7934 ;; Optimize (1LL<<x)-1
7935 ;; XXX this also needs to be fixed to handle equal subregs
7936 ;; XXX first before we could re-enable it.
7937 ;(define_insn ""
7938 ; [(set (match_operand:DI 0 "register_operand" "=h")
7939 ; (plus:DI (ashift:DI (const_int 1)
7940 ; (match_operand:SI 1 "arith_operand" "rI"))
7941 ; (const_int -1)))]
7942 ; "0 && TARGET_V8PLUS"
7943 ; "*
7944 ;{
7945 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7946 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7947 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7948 ;}"
7949 ; [(set_attr "type" "multi")
7950 ; (set_attr "length" "4")])
7951
7952 (define_insn "*cmp_cc_ashift_1"
7953 [(set (reg:CC_NOOV 100)
7954 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7955 (const_int 1))
7956 (const_int 0)))]
7957 ""
7958 "addcc\\t%0, %0, %%g0"
7959 [(set_attr "type" "compare")])
7960
7961 (define_insn "*cmp_cc_set_ashift_1"
7962 [(set (reg:CC_NOOV 100)
7963 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7964 (const_int 1))
7965 (const_int 0)))
7966 (set (match_operand:SI 0 "register_operand" "=r")
7967 (ashift:SI (match_dup 1) (const_int 1)))]
7968 ""
7969 "addcc\\t%1, %1, %0"
7970 [(set_attr "type" "compare")])
7971
7972 (define_insn "ashrsi3"
7973 [(set (match_operand:SI 0 "register_operand" "=r")
7974 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7975 (match_operand:SI 2 "arith_operand" "rI")))]
7976 ""
7977 "*
7978 {
7979 if (GET_CODE (operands[2]) == CONST_INT
7980 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7981 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7982
7983 return \"sra\\t%1, %2, %0\";
7984 }"
7985 [(set_attr "type" "shift")])
7986
7987 (define_insn "*ashrsi3_extend"
7988 [(set (match_operand:DI 0 "register_operand" "=r")
7989 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7990 (match_operand:SI 2 "arith_operand" "r"))))]
7991 "TARGET_ARCH64"
7992 "sra\\t%1, %2, %0"
7993 [(set_attr "type" "shift")])
7994
7995 ;; This handles the case as above, but with constant shift instead of
7996 ;; register. Combiner "simplifies" it for us a little bit though.
7997 (define_insn "*ashrsi3_extend2"
7998 [(set (match_operand:DI 0 "register_operand" "=r")
7999 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8000 (const_int 32))
8001 (match_operand:SI 2 "small_int_or_double" "n")))]
8002 "TARGET_ARCH64
8003 && ((GET_CODE (operands[2]) == CONST_INT
8004 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8005 || (GET_CODE (operands[2]) == CONST_DOUBLE
8006 && !CONST_DOUBLE_HIGH (operands[2])
8007 && CONST_DOUBLE_LOW (operands[2]) >= 32
8008 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8009 "*
8010 {
8011 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8012
8013 return \"sra\\t%1, %2, %0\";
8014 }"
8015 [(set_attr "type" "shift")])
8016
8017 (define_expand "ashrdi3"
8018 [(set (match_operand:DI 0 "register_operand" "=r")
8019 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8020 (match_operand:SI 2 "arith_operand" "rI")))]
8021 "TARGET_ARCH64 || TARGET_V8PLUS"
8022 "
8023 {
8024 if (! TARGET_ARCH64)
8025 {
8026 if (GET_CODE (operands[2]) == CONST_INT)
8027 FAIL; /* prefer generic code in this case */
8028 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8029 DONE;
8030 }
8031 }")
8032
8033 (define_insn ""
8034 [(set (match_operand:DI 0 "register_operand" "=r")
8035 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8036 (match_operand:SI 2 "arith_operand" "rI")))]
8037 "TARGET_ARCH64"
8038 "*
8039 {
8040 if (GET_CODE (operands[2]) == CONST_INT
8041 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8042 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8043
8044 return \"srax\\t%1, %2, %0\";
8045 }"
8046 [(set_attr "type" "shift")])
8047
8048 ;; XXX
8049 (define_insn "ashrdi3_v8plus"
8050 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8051 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8052 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8053 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8054 "TARGET_V8PLUS"
8055 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8056 [(set_attr "type" "multi")
8057 (set_attr "length" "5,5,6")])
8058
8059 (define_insn "lshrsi3"
8060 [(set (match_operand:SI 0 "register_operand" "=r")
8061 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8062 (match_operand:SI 2 "arith_operand" "rI")))]
8063 ""
8064 "*
8065 {
8066 if (GET_CODE (operands[2]) == CONST_INT
8067 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8068 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8069
8070 return \"srl\\t%1, %2, %0\";
8071 }"
8072 [(set_attr "type" "shift")])
8073
8074 ;; This handles the case where
8075 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8076 ;; but combiner "simplifies" it for us.
8077 (define_insn "*lshrsi3_extend"
8078 [(set (match_operand:DI 0 "register_operand" "=r")
8079 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8080 (match_operand:SI 2 "arith_operand" "r")) 0)
8081 (match_operand 3 "" "")))]
8082 "TARGET_ARCH64
8083 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8084 && CONST_DOUBLE_HIGH (operands[3]) == 0
8085 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8086 || (HOST_BITS_PER_WIDE_INT >= 64
8087 && GET_CODE (operands[3]) == CONST_INT
8088 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8089 "srl\\t%1, %2, %0"
8090 [(set_attr "type" "shift")])
8091
8092 ;; This handles the case where
8093 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8094 ;; but combiner "simplifies" it for us.
8095 (define_insn "*lshrsi3_extend2"
8096 [(set (match_operand:DI 0 "register_operand" "=r")
8097 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8098 (match_operand 2 "small_int_or_double" "n")
8099 (const_int 32)))]
8100 "TARGET_ARCH64
8101 && ((GET_CODE (operands[2]) == CONST_INT
8102 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8103 || (GET_CODE (operands[2]) == CONST_DOUBLE
8104 && CONST_DOUBLE_HIGH (operands[2]) == 0
8105 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8106 "*
8107 {
8108 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8109
8110 return \"srl\\t%1, %2, %0\";
8111 }"
8112 [(set_attr "type" "shift")])
8113
8114 (define_expand "lshrdi3"
8115 [(set (match_operand:DI 0 "register_operand" "=r")
8116 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8117 (match_operand:SI 2 "arith_operand" "rI")))]
8118 "TARGET_ARCH64 || TARGET_V8PLUS"
8119 "
8120 {
8121 if (! TARGET_ARCH64)
8122 {
8123 if (GET_CODE (operands[2]) == CONST_INT)
8124 FAIL;
8125 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8126 DONE;
8127 }
8128 }")
8129
8130 (define_insn ""
8131 [(set (match_operand:DI 0 "register_operand" "=r")
8132 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8133 (match_operand:SI 2 "arith_operand" "rI")))]
8134 "TARGET_ARCH64"
8135 "*
8136 {
8137 if (GET_CODE (operands[2]) == CONST_INT
8138 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8139 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8140
8141 return \"srlx\\t%1, %2, %0\";
8142 }"
8143 [(set_attr "type" "shift")])
8144
8145 ;; XXX
8146 (define_insn "lshrdi3_v8plus"
8147 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8148 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8149 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8150 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8151 "TARGET_V8PLUS"
8152 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8153 [(set_attr "type" "multi")
8154 (set_attr "length" "5,5,6")])
8155
8156 (define_insn ""
8157 [(set (match_operand:SI 0 "register_operand" "=r")
8158 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8159 (const_int 32)) 4)
8160 (match_operand:SI 2 "small_int_or_double" "n")))]
8161 "TARGET_ARCH64
8162 && ((GET_CODE (operands[2]) == CONST_INT
8163 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8164 || (GET_CODE (operands[2]) == CONST_DOUBLE
8165 && !CONST_DOUBLE_HIGH (operands[2])
8166 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8167 "*
8168 {
8169 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8170
8171 return \"srax\\t%1, %2, %0\";
8172 }"
8173 [(set_attr "type" "shift")])
8174
8175 (define_insn ""
8176 [(set (match_operand:SI 0 "register_operand" "=r")
8177 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8178 (const_int 32)) 4)
8179 (match_operand:SI 2 "small_int_or_double" "n")))]
8180 "TARGET_ARCH64
8181 && ((GET_CODE (operands[2]) == CONST_INT
8182 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8183 || (GET_CODE (operands[2]) == CONST_DOUBLE
8184 && !CONST_DOUBLE_HIGH (operands[2])
8185 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8186 "*
8187 {
8188 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8189
8190 return \"srlx\\t%1, %2, %0\";
8191 }"
8192 [(set_attr "type" "shift")])
8193
8194 (define_insn ""
8195 [(set (match_operand:SI 0 "register_operand" "=r")
8196 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8197 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8198 (match_operand:SI 3 "small_int_or_double" "n")))]
8199 "TARGET_ARCH64
8200 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8201 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8202 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8203 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8204 "*
8205 {
8206 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8207
8208 return \"srax\\t%1, %2, %0\";
8209 }"
8210 [(set_attr "type" "shift")])
8211
8212 (define_insn ""
8213 [(set (match_operand:SI 0 "register_operand" "=r")
8214 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8215 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8216 (match_operand:SI 3 "small_int_or_double" "n")))]
8217 "TARGET_ARCH64
8218 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8219 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8220 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8221 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8222 "*
8223 {
8224 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8225
8226 return \"srlx\\t%1, %2, %0\";
8227 }"
8228 [(set_attr "type" "shift")])
8229 \f
8230 ;; Unconditional and other jump instructions
8231 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8232 ;; following insn is never executed. This saves us a nop. Dbx does not
8233 ;; handle such branches though, so we only use them when optimizing.
8234 (define_insn "jump"
8235 [(set (pc) (label_ref (match_operand 0 "" "")))]
8236 ""
8237 "*
8238 {
8239 /* TurboSparc is reported to have problems with
8240 with
8241 foo: b,a foo
8242 i.e. an empty loop with the annul bit set. The workaround is to use
8243 foo: b foo; nop
8244 instead. */
8245
8246 if (! TARGET_V9 && flag_delayed_branch
8247 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8248 == INSN_ADDRESSES (INSN_UID (insn))))
8249 return \"b\\t%l0%#\";
8250 else
8251 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8252 }"
8253 [(set_attr "type" "uncond_branch")])
8254
8255 (define_expand "tablejump"
8256 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8257 (use (label_ref (match_operand 1 "" "")))])]
8258 ""
8259 "
8260 {
8261 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8262 abort ();
8263
8264 /* In pic mode, our address differences are against the base of the
8265 table. Add that base value back in; CSE ought to be able to combine
8266 the two address loads. */
8267 if (flag_pic)
8268 {
8269 rtx tmp, tmp2;
8270 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8271 tmp2 = operands[0];
8272 if (CASE_VECTOR_MODE != Pmode)
8273 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8274 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8275 operands[0] = memory_address (Pmode, tmp);
8276 }
8277 }")
8278
8279 (define_insn "*tablejump_sp32"
8280 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8281 (use (label_ref (match_operand 1 "" "")))]
8282 "! TARGET_ARCH64"
8283 "jmp\\t%a0%#"
8284 [(set_attr "type" "uncond_branch")])
8285
8286 (define_insn "*tablejump_sp64"
8287 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8288 (use (label_ref (match_operand 1 "" "")))]
8289 "TARGET_ARCH64"
8290 "jmp\\t%a0%#"
8291 [(set_attr "type" "uncond_branch")])
8292
8293 ;; This pattern recognizes the "instruction" that appears in
8294 ;; a function call that wants a structure value,
8295 ;; to inform the called function if compiled with Sun CC.
8296 ;(define_insn "*unimp_insn"
8297 ; [(match_operand:SI 0 "immediate_operand" "")]
8298 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8299 ; "unimp\\t%0"
8300 ; [(set_attr "type" "marker")])
8301
8302 ;;- jump to subroutine
8303 (define_expand "call"
8304 ;; Note that this expression is not used for generating RTL.
8305 ;; All the RTL is generated explicitly below.
8306 [(call (match_operand 0 "call_operand" "")
8307 (match_operand 3 "" "i"))]
8308 ;; operands[2] is next_arg_register
8309 ;; operands[3] is struct_value_size_rtx.
8310 ""
8311 "
8312 {
8313 rtx fn_rtx, nregs_rtx;
8314
8315 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8316 abort ();
8317
8318 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8319 {
8320 /* This is really a PIC sequence. We want to represent
8321 it as a funny jump so its delay slots can be filled.
8322
8323 ??? But if this really *is* a CALL, will not it clobber the
8324 call-clobbered registers? We lose this if it is a JUMP_INSN.
8325 Why cannot we have delay slots filled if it were a CALL? */
8326
8327 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8328 emit_jump_insn
8329 (gen_rtx_PARALLEL
8330 (VOIDmode,
8331 gen_rtvec (3,
8332 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8333 operands[3],
8334 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8335 else
8336 emit_jump_insn
8337 (gen_rtx_PARALLEL
8338 (VOIDmode,
8339 gen_rtvec (2,
8340 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8341 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8342 goto finish_call;
8343 }
8344
8345 fn_rtx = operands[0];
8346
8347 /* Count the number of parameter registers being used by this call.
8348 if that argument is NULL, it means we are using them all, which
8349 means 6 on the sparc. */
8350 #if 0
8351 if (operands[2])
8352 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8353 else
8354 nregs_rtx = GEN_INT (6);
8355 #else
8356 nregs_rtx = const0_rtx;
8357 #endif
8358
8359 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8360 emit_call_insn
8361 (gen_rtx_PARALLEL
8362 (VOIDmode,
8363 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8364 operands[3],
8365 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8366 else
8367 emit_call_insn
8368 (gen_rtx_PARALLEL
8369 (VOIDmode,
8370 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8371 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8372
8373 finish_call:
8374 #if 0
8375 /* If this call wants a structure value,
8376 emit an unimp insn to let the called function know about this. */
8377 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8378 {
8379 rtx insn = emit_insn (operands[3]);
8380 SCHED_GROUP_P (insn) = 1;
8381 }
8382 #endif
8383
8384 DONE;
8385 }")
8386
8387 ;; We can't use the same pattern for these two insns, because then registers
8388 ;; in the address may not be properly reloaded.
8389
8390 (define_insn "*call_address_sp32"
8391 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8392 (match_operand 1 "" ""))
8393 (clobber (reg:SI 15))]
8394 ;;- Do not use operand 1 for most machines.
8395 "! TARGET_ARCH64"
8396 "call\\t%a0, %1%#"
8397 [(set_attr "type" "call")])
8398
8399 (define_insn "*call_symbolic_sp32"
8400 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8401 (match_operand 1 "" ""))
8402 (clobber (reg:SI 15))]
8403 ;;- Do not use operand 1 for most machines.
8404 "! TARGET_ARCH64"
8405 "call\\t%a0, %1%#"
8406 [(set_attr "type" "call")])
8407
8408 (define_insn "*call_address_sp64"
8409 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8410 (match_operand 1 "" ""))
8411 (clobber (reg:DI 15))]
8412 ;;- Do not use operand 1 for most machines.
8413 "TARGET_ARCH64"
8414 "call\\t%a0, %1%#"
8415 [(set_attr "type" "call")])
8416
8417 (define_insn "*call_symbolic_sp64"
8418 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8419 (match_operand 1 "" ""))
8420 (clobber (reg:DI 15))]
8421 ;;- Do not use operand 1 for most machines.
8422 "TARGET_ARCH64"
8423 "call\\t%a0, %1%#"
8424 [(set_attr "type" "call")])
8425
8426 ;; This is a call that wants a structure value.
8427 ;; There is no such critter for v9 (??? we may need one anyway).
8428 (define_insn "*call_address_struct_value_sp32"
8429 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8430 (match_operand 1 "" ""))
8431 (match_operand 2 "immediate_operand" "")
8432 (clobber (reg:SI 15))]
8433 ;;- Do not use operand 1 for most machines.
8434 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8435 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8436 [(set_attr "type" "call_no_delay_slot")])
8437
8438 ;; This is a call that wants a structure value.
8439 ;; There is no such critter for v9 (??? we may need one anyway).
8440 (define_insn "*call_symbolic_struct_value_sp32"
8441 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8442 (match_operand 1 "" ""))
8443 (match_operand 2 "immediate_operand" "")
8444 (clobber (reg:SI 15))]
8445 ;;- Do not use operand 1 for most machines.
8446 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8447 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8448 [(set_attr "type" "call_no_delay_slot")])
8449
8450 ;; This is a call that may want a structure value. This is used for
8451 ;; untyped_calls.
8452 (define_insn "*call_address_untyped_struct_value_sp32"
8453 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8454 (match_operand 1 "" ""))
8455 (match_operand 2 "immediate_operand" "")
8456 (clobber (reg:SI 15))]
8457 ;;- Do not use operand 1 for most machines.
8458 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8459 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8460 [(set_attr "type" "call_no_delay_slot")])
8461
8462 ;; This is a call that wants a structure value.
8463 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8464 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8465 (match_operand 1 "" ""))
8466 (match_operand 2 "immediate_operand" "")
8467 (clobber (reg:SI 15))]
8468 ;;- Do not use operand 1 for most machines.
8469 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8470 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8471 [(set_attr "type" "call_no_delay_slot")])
8472
8473 (define_expand "call_value"
8474 ;; Note that this expression is not used for generating RTL.
8475 ;; All the RTL is generated explicitly below.
8476 [(set (match_operand 0 "register_operand" "=rf")
8477 (call (match_operand 1 "" "")
8478 (match_operand 4 "" "")))]
8479 ;; operand 2 is stack_size_rtx
8480 ;; operand 3 is next_arg_register
8481 ""
8482 "
8483 {
8484 rtx fn_rtx, nregs_rtx;
8485 rtvec vec;
8486
8487 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8488 abort ();
8489
8490 fn_rtx = operands[1];
8491
8492 #if 0
8493 if (operands[3])
8494 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8495 else
8496 nregs_rtx = GEN_INT (6);
8497 #else
8498 nregs_rtx = const0_rtx;
8499 #endif
8500
8501 vec = gen_rtvec (2,
8502 gen_rtx_SET (VOIDmode, operands[0],
8503 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8504 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8505
8506 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8507
8508 DONE;
8509 }")
8510
8511 (define_insn "*call_value_address_sp32"
8512 [(set (match_operand 0 "" "=rf")
8513 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8514 (match_operand 2 "" "")))
8515 (clobber (reg:SI 15))]
8516 ;;- Do not use operand 2 for most machines.
8517 "! TARGET_ARCH64"
8518 "call\\t%a1, %2%#"
8519 [(set_attr "type" "call")])
8520
8521 (define_insn "*call_value_symbolic_sp32"
8522 [(set (match_operand 0 "" "=rf")
8523 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8524 (match_operand 2 "" "")))
8525 (clobber (reg:SI 15))]
8526 ;;- Do not use operand 2 for most machines.
8527 "! TARGET_ARCH64"
8528 "call\\t%a1, %2%#"
8529 [(set_attr "type" "call")])
8530
8531 (define_insn "*call_value_address_sp64"
8532 [(set (match_operand 0 "" "")
8533 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8534 (match_operand 2 "" "")))
8535 (clobber (reg:DI 15))]
8536 ;;- Do not use operand 2 for most machines.
8537 "TARGET_ARCH64"
8538 "call\\t%a1, %2%#"
8539 [(set_attr "type" "call")])
8540
8541 (define_insn "*call_value_symbolic_sp64"
8542 [(set (match_operand 0 "" "")
8543 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8544 (match_operand 2 "" "")))
8545 (clobber (reg:DI 15))]
8546 ;;- Do not use operand 2 for most machines.
8547 "TARGET_ARCH64"
8548 "call\\t%a1, %2%#"
8549 [(set_attr "type" "call")])
8550
8551 (define_expand "untyped_call"
8552 [(parallel [(call (match_operand 0 "" "")
8553 (const_int 0))
8554 (match_operand 1 "" "")
8555 (match_operand 2 "" "")])]
8556 ""
8557 "
8558 {
8559 int i;
8560
8561 /* Pass constm1 to indicate that it may expect a structure value, but
8562 we don't know what size it is. */
8563 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8564
8565 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8566 {
8567 rtx set = XVECEXP (operands[2], 0, i);
8568 emit_move_insn (SET_DEST (set), SET_SRC (set));
8569 }
8570
8571 /* The optimizer does not know that the call sets the function value
8572 registers we stored in the result block. We avoid problems by
8573 claiming that all hard registers are used and clobbered at this
8574 point. */
8575 emit_insn (gen_blockage ());
8576
8577 DONE;
8578 }")
8579
8580 ;;- tail calls
8581 (define_expand "sibcall"
8582 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8583 (return)])]
8584 ""
8585 "")
8586
8587 (define_insn "*sibcall_symbolic_sp32"
8588 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8589 (match_operand 1 "" ""))
8590 (return)]
8591 "! TARGET_ARCH64"
8592 "* return output_sibcall(insn, operands[0]);"
8593 [(set_attr "type" "sibcall")])
8594
8595 (define_insn "*sibcall_symbolic_sp64"
8596 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8597 (match_operand 1 "" ""))
8598 (return)]
8599 "TARGET_ARCH64"
8600 "* return output_sibcall(insn, operands[0]);"
8601 [(set_attr "type" "sibcall")])
8602
8603 (define_expand "sibcall_value"
8604 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8605 (call (match_operand 1 "" "") (const_int 0)))
8606 (return)])]
8607 ""
8608 "")
8609
8610 (define_insn "*sibcall_value_symbolic_sp32"
8611 [(set (match_operand 0 "" "=rf")
8612 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8613 (match_operand 2 "" "")))
8614 (return)]
8615 "! TARGET_ARCH64"
8616 "* return output_sibcall(insn, operands[1]);"
8617 [(set_attr "type" "sibcall")])
8618
8619 (define_insn "*sibcall_value_symbolic_sp64"
8620 [(set (match_operand 0 "" "")
8621 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8622 (match_operand 2 "" "")))
8623 (return)]
8624 "TARGET_ARCH64"
8625 "* return output_sibcall(insn, operands[1]);"
8626 [(set_attr "type" "sibcall")])
8627
8628 (define_expand "sibcall_epilogue"
8629 [(const_int 0)]
8630 ""
8631 "DONE;")
8632
8633 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8634 ;; all of memory. This blocks insns from being moved across this point.
8635
8636 (define_insn "blockage"
8637 [(unspec_volatile [(const_int 0)] 0)]
8638 ""
8639 ""
8640 [(set_attr "length" "0")])
8641
8642 ;; Prepare to return any type including a structure value.
8643
8644 (define_expand "untyped_return"
8645 [(match_operand:BLK 0 "memory_operand" "")
8646 (match_operand 1 "" "")]
8647 ""
8648 "
8649 {
8650 rtx valreg1 = gen_rtx_REG (DImode, 24);
8651 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8652 rtx result = operands[0];
8653
8654 if (! TARGET_ARCH64)
8655 {
8656 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8657 ? 15 : 31));
8658 rtx value = gen_reg_rtx (SImode);
8659
8660 /* Fetch the instruction where we will return to and see if it's an unimp
8661 instruction (the most significant 10 bits will be zero). If so,
8662 update the return address to skip the unimp instruction. */
8663 emit_move_insn (value,
8664 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8665 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8666 emit_insn (gen_update_return (rtnreg, value));
8667 }
8668
8669 /* Reload the function value registers. */
8670 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8671 emit_move_insn (valreg2,
8672 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8673
8674 /* Put USE insns before the return. */
8675 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8676 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8677
8678 /* Construct the return. */
8679 expand_null_return ();
8680
8681 DONE;
8682 }")
8683
8684 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8685 ;; and parts of the compiler don't want to believe that the add is needed.
8686
8687 (define_insn "update_return"
8688 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8689 (match_operand:SI 1 "register_operand" "r")] 1)]
8690 "! TARGET_ARCH64"
8691 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8692 [(set_attr "type" "multi")
8693 (set_attr "length" "3")])
8694 \f
8695 (define_insn "return"
8696 [(return)
8697 (use (reg:SI 31))]
8698 "! TARGET_EPILOGUE"
8699 "* return output_return (operands);"
8700 [(set_attr "type" "return")])
8701
8702 (define_peephole
8703 [(set (match_operand:SI 0 "register_operand" "=r")
8704 (match_operand:SI 1 "arith_operand" "rI"))
8705 (parallel [(return)
8706 (use (reg:SI 31))])]
8707 "sparc_return_peephole_ok (operands[0], operands[1])"
8708 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8709
8710 (define_insn "nop"
8711 [(const_int 0)]
8712 ""
8713 "nop")
8714
8715 (define_expand "indirect_jump"
8716 [(set (pc) (match_operand 0 "address_operand" "p"))]
8717 ""
8718 "")
8719
8720 (define_insn "*branch_sp32"
8721 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8722 "! TARGET_ARCH64"
8723 "jmp\\t%a0%#"
8724 [(set_attr "type" "uncond_branch")])
8725
8726 (define_insn "*branch_sp64"
8727 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8728 "TARGET_ARCH64"
8729 "jmp\\t%a0%#"
8730 [(set_attr "type" "uncond_branch")])
8731
8732 ;; ??? Doesn't work with -mflat.
8733 (define_expand "nonlocal_goto"
8734 [(match_operand:SI 0 "general_operand" "")
8735 (match_operand:SI 1 "general_operand" "")
8736 (match_operand:SI 2 "general_operand" "")
8737 (match_operand:SI 3 "" "")]
8738 ""
8739 "
8740 {
8741 #if 0
8742 rtx chain = operands[0];
8743 #endif
8744 rtx lab = operands[1];
8745 rtx stack = operands[2];
8746 rtx fp = operands[3];
8747 rtx labreg;
8748
8749 /* Trap instruction to flush all the register windows. */
8750 emit_insn (gen_flush_register_windows ());
8751
8752 /* Load the fp value for the containing fn into %fp. This is needed
8753 because STACK refers to %fp. Note that virtual register instantiation
8754 fails if the virtual %fp isn't set from a register. */
8755 if (GET_CODE (fp) != REG)
8756 fp = force_reg (Pmode, fp);
8757 emit_move_insn (virtual_stack_vars_rtx, fp);
8758
8759 /* Find the containing function's current nonlocal goto handler,
8760 which will do any cleanups and then jump to the label. */
8761 labreg = gen_rtx_REG (Pmode, 8);
8762 emit_move_insn (labreg, lab);
8763
8764 /* Restore %fp from stack pointer value for containing function.
8765 The restore insn that follows will move this to %sp,
8766 and reload the appropriate value into %fp. */
8767 emit_move_insn (frame_pointer_rtx, stack);
8768
8769 /* USE of frame_pointer_rtx added for consistency; not clear if
8770 really needed. */
8771 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8772 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8773
8774 #if 0
8775 /* Return, restoring reg window and jumping to goto handler. */
8776 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8777 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8778 {
8779 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8780 static_chain_rtx,
8781 chain));
8782 emit_barrier ();
8783 DONE;
8784 }
8785 /* Put in the static chain register the nonlocal label address. */
8786 emit_move_insn (static_chain_rtx, chain);
8787 #endif
8788
8789 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8790 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8791 emit_barrier ();
8792 DONE;
8793 }")
8794
8795 ;; Special trap insn to flush register windows.
8796 (define_insn "flush_register_windows"
8797 [(unspec_volatile [(const_int 0)] 1)]
8798 ""
8799 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8800 [(set_attr "type" "misc")])
8801
8802 (define_insn "goto_handler_and_restore"
8803 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8804 "GET_MODE (operands[0]) == Pmode"
8805 "jmp\\t%0+0\\n\\trestore"
8806 [(set_attr "type" "multi")
8807 (set_attr "length" "2")])
8808
8809 ;;(define_insn "goto_handler_and_restore_v9"
8810 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8811 ;; (match_operand:SI 1 "register_operand" "=r,r")
8812 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8813 ;; "TARGET_V9 && ! TARGET_ARCH64"
8814 ;; "@
8815 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8816 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8817 ;; [(set_attr "type" "multi")
8818 ;; (set_attr "length" "2,3")])
8819 ;;
8820 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8821 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8822 ;; (match_operand:DI 1 "register_operand" "=r,r")
8823 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8824 ;; "TARGET_V9 && TARGET_ARCH64"
8825 ;; "@
8826 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8827 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8828 ;; [(set_attr "type" "multi")
8829 ;; (set_attr "length" "2,3")])
8830
8831 ;; For __builtin_setjmp we need to flush register windows iff the function
8832 ;; calls alloca as well, because otherwise the register window might be
8833 ;; saved after %sp adjustement and thus setjmp would crash
8834 (define_expand "builtin_setjmp_setup"
8835 [(match_operand 0 "register_operand" "r")]
8836 ""
8837 "
8838 {
8839 emit_insn (gen_do_builtin_setjmp_setup ());
8840 DONE;
8841 }")
8842
8843 ;; ??? Should set length to zero when !current_function_calls_alloca,
8844 ;; ??? but there is no easy way to get at that definition. It would
8845 ;; ??? require including function.h into sparc-protos.h and that is
8846 ;; ??? likely not a good idea. -DaveM
8847 (define_insn "do_builtin_setjmp_setup"
8848 [(unspec_volatile [(const_int 0)] 5)]
8849 ""
8850 "*
8851 {
8852 if (!current_function_calls_alloca)
8853 return \"\";
8854 if (TARGET_V9)
8855 return \"flushw\";
8856 return \"ta\\t3\";
8857 }"
8858 [(set_attr "type" "misc")])
8859
8860 ;; Pattern for use after a setjmp to store FP and the return register
8861 ;; into the stack area.
8862
8863 (define_expand "setjmp"
8864 [(const_int 0)]
8865 ""
8866 "
8867 {
8868 if (TARGET_ARCH64)
8869 emit_insn (gen_setjmp_64 ());
8870 else
8871 emit_insn (gen_setjmp_32 ());
8872 DONE;
8873 }")
8874
8875 (define_expand "setjmp_32"
8876 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8877 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8878 ""
8879 "
8880 { operands[0] = frame_pointer_rtx; }")
8881
8882 (define_expand "setjmp_64"
8883 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8884 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8885 ""
8886 "
8887 { operands[0] = frame_pointer_rtx; }")
8888
8889 ;; Special pattern for the FLUSH instruction.
8890
8891 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8892 ; of the define_insn otherwise missing a mode. We make "flush", aka
8893 ; gen_flush, the default one since sparc_initialize_trampoline uses
8894 ; it on SImode mem values.
8895
8896 (define_insn "flush"
8897 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8898 ""
8899 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8900 [(set_attr "type" "misc")])
8901
8902 (define_insn "flushdi"
8903 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8904 ""
8905 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8906 [(set_attr "type" "misc")])
8907
8908 \f
8909 ;; find first set.
8910
8911 ;; The scan instruction searches from the most significant bit while ffs
8912 ;; searches from the least significant bit. The bit index and treatment of
8913 ;; zero also differ. It takes at least 7 instructions to get the proper
8914 ;; result. Here is an obvious 8 instruction sequence.
8915
8916 ;; XXX
8917 (define_insn "ffssi2"
8918 [(set (match_operand:SI 0 "register_operand" "=&r")
8919 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8920 (clobber (match_scratch:SI 2 "=&r"))]
8921 "TARGET_SPARCLITE || TARGET_SPARCLET"
8922 "*
8923 {
8924 return \"sub\\t%%g0, %1, %0\;and\\t%0, %1, %0\;scan\\t%0, 0, %0\;mov\\t32, %2\;sub\\t%2, %0, %0\;sra\\t%0, 31, %2\;and\\t%2, 31, %2\;add\\t%2, %0, %0\";
8925 }"
8926 [(set_attr "type" "multi")
8927 (set_attr "length" "8")])
8928
8929 ;; ??? This should be a define expand, so that the extra instruction have
8930 ;; a chance of being optimized away.
8931
8932 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8933 ;; does, but no one uses that and we don't have a switch for it.
8934 ;
8935 ;(define_insn "ffsdi2"
8936 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8937 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8938 ; (clobber (match_scratch:DI 2 "=&r"))]
8939 ; "TARGET_ARCH64"
8940 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8941 ; [(set_attr "type" "multi")
8942 ; (set_attr "length" "4")])
8943
8944
8945 \f
8946 ;; Peepholes go at the end.
8947
8948 ;; Optimize consecutive loads or stores into ldd and std when possible.
8949 ;; The conditions in which we do this are very restricted and are
8950 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8951
8952 (define_peephole
8953 [(set (match_operand:SI 0 "memory_operand" "")
8954 (const_int 0))
8955 (set (match_operand:SI 1 "memory_operand" "")
8956 (const_int 0))]
8957 "TARGET_V9
8958 && ! MEM_VOLATILE_P (operands[0])
8959 && ! MEM_VOLATILE_P (operands[1])
8960 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
8961 "stx\\t%%g0, %0")
8962
8963 (define_peephole
8964 [(set (match_operand:SI 0 "memory_operand" "")
8965 (const_int 0))
8966 (set (match_operand:SI 1 "memory_operand" "")
8967 (const_int 0))]
8968 "TARGET_V9
8969 && ! MEM_VOLATILE_P (operands[0])
8970 && ! MEM_VOLATILE_P (operands[1])
8971 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
8972 "stx\\t%%g0, %1")
8973
8974 (define_peephole
8975 [(set (match_operand:SI 0 "register_operand" "=rf")
8976 (match_operand:SI 1 "memory_operand" ""))
8977 (set (match_operand:SI 2 "register_operand" "=rf")
8978 (match_operand:SI 3 "memory_operand" ""))]
8979 "registers_ok_for_ldd_peep (operands[0], operands[2])
8980 && ! MEM_VOLATILE_P (operands[1])
8981 && ! MEM_VOLATILE_P (operands[3])
8982 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8983 "ldd\\t%1, %0")
8984
8985 (define_peephole
8986 [(set (match_operand:SI 0 "memory_operand" "")
8987 (match_operand:SI 1 "register_operand" "rf"))
8988 (set (match_operand:SI 2 "memory_operand" "")
8989 (match_operand:SI 3 "register_operand" "rf"))]
8990 "registers_ok_for_ldd_peep (operands[1], operands[3])
8991 && ! MEM_VOLATILE_P (operands[0])
8992 && ! MEM_VOLATILE_P (operands[2])
8993 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8994 "std\\t%1, %0")
8995
8996 (define_peephole
8997 [(set (match_operand:SF 0 "register_operand" "=fr")
8998 (match_operand:SF 1 "memory_operand" ""))
8999 (set (match_operand:SF 2 "register_operand" "=fr")
9000 (match_operand:SF 3 "memory_operand" ""))]
9001 "registers_ok_for_ldd_peep (operands[0], operands[2])
9002 && ! MEM_VOLATILE_P (operands[1])
9003 && ! MEM_VOLATILE_P (operands[3])
9004 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9005 "ldd\\t%1, %0")
9006
9007 (define_peephole
9008 [(set (match_operand:SF 0 "memory_operand" "")
9009 (match_operand:SF 1 "register_operand" "fr"))
9010 (set (match_operand:SF 2 "memory_operand" "")
9011 (match_operand:SF 3 "register_operand" "fr"))]
9012 "registers_ok_for_ldd_peep (operands[1], operands[3])
9013 && ! MEM_VOLATILE_P (operands[0])
9014 && ! MEM_VOLATILE_P (operands[2])
9015 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9016 "std\\t%1, %0")
9017
9018 (define_peephole
9019 [(set (match_operand:SI 0 "register_operand" "=rf")
9020 (match_operand:SI 1 "memory_operand" ""))
9021 (set (match_operand:SI 2 "register_operand" "=rf")
9022 (match_operand:SI 3 "memory_operand" ""))]
9023 "registers_ok_for_ldd_peep (operands[2], operands[0])
9024 && ! MEM_VOLATILE_P (operands[3])
9025 && ! MEM_VOLATILE_P (operands[1])
9026 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9027 "ldd\\t%3, %2")
9028
9029 (define_peephole
9030 [(set (match_operand:SI 0 "memory_operand" "")
9031 (match_operand:SI 1 "register_operand" "rf"))
9032 (set (match_operand:SI 2 "memory_operand" "")
9033 (match_operand:SI 3 "register_operand" "rf"))]
9034 "registers_ok_for_ldd_peep (operands[3], operands[1])
9035 && ! MEM_VOLATILE_P (operands[2])
9036 && ! MEM_VOLATILE_P (operands[0])
9037 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9038 "std\\t%3, %2")
9039
9040 (define_peephole
9041 [(set (match_operand:SF 0 "register_operand" "=fr")
9042 (match_operand:SF 1 "memory_operand" ""))
9043 (set (match_operand:SF 2 "register_operand" "=fr")
9044 (match_operand:SF 3 "memory_operand" ""))]
9045 "registers_ok_for_ldd_peep (operands[2], operands[0])
9046 && ! MEM_VOLATILE_P (operands[3])
9047 && ! MEM_VOLATILE_P (operands[1])
9048 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9049 "ldd\\t%3, %2")
9050
9051 (define_peephole
9052 [(set (match_operand:SF 0 "memory_operand" "")
9053 (match_operand:SF 1 "register_operand" "fr"))
9054 (set (match_operand:SF 2 "memory_operand" "")
9055 (match_operand:SF 3 "register_operand" "fr"))]
9056 "registers_ok_for_ldd_peep (operands[3], operands[1])
9057 && ! MEM_VOLATILE_P (operands[2])
9058 && ! MEM_VOLATILE_P (operands[0])
9059 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9060 "std\\t%3, %2")
9061
9062 ;; Optimize the case of following a reg-reg move with a test
9063 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9064 ;; This can result from a float to fix conversion.
9065
9066 (define_peephole
9067 [(set (match_operand:SI 0 "register_operand" "=r")
9068 (match_operand:SI 1 "register_operand" "r"))
9069 (set (reg:CC 100)
9070 (compare:CC (match_operand:SI 2 "register_operand" "r")
9071 (const_int 0)))]
9072 "(rtx_equal_p (operands[2], operands[0])
9073 || rtx_equal_p (operands[2], operands[1]))
9074 && ! FP_REG_P (operands[0])
9075 && ! FP_REG_P (operands[1])"
9076 "orcc\\t%1, 0, %0")
9077
9078 (define_peephole
9079 [(set (match_operand:DI 0 "register_operand" "=r")
9080 (match_operand:DI 1 "register_operand" "r"))
9081 (set (reg:CCX 100)
9082 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9083 (const_int 0)))]
9084 "TARGET_ARCH64
9085 && (rtx_equal_p (operands[2], operands[0])
9086 || rtx_equal_p (operands[2], operands[1]))
9087 && ! FP_REG_P (operands[0])
9088 && ! FP_REG_P (operands[1])"
9089 "orcc\\t%1, 0, %0")
9090
9091 ;; Return peepholes. First the "normal" ones.
9092 ;; These are necessary to catch insns ending up in the epilogue delay list.
9093
9094 (define_insn "*return_qi"
9095 [(set (match_operand:QI 0 "restore_operand" "")
9096 (match_operand:QI 1 "arith_operand" "rI"))
9097 (return)]
9098 "! TARGET_EPILOGUE"
9099 "*
9100 {
9101 if (! TARGET_ARCH64 && current_function_returns_struct)
9102 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9103 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9104 || IN_OR_GLOBAL_P (operands[1])))
9105 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9106 else
9107 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9108 }"
9109 [(set_attr "type" "multi")
9110 (set_attr "length" "2")])
9111
9112 (define_insn "*return_hi"
9113 [(set (match_operand:HI 0 "restore_operand" "")
9114 (match_operand:HI 1 "arith_operand" "rI"))
9115 (return)]
9116 "! TARGET_EPILOGUE"
9117 "*
9118 {
9119 if (! TARGET_ARCH64 && current_function_returns_struct)
9120 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9121 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9122 || IN_OR_GLOBAL_P (operands[1])))
9123 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9124 else
9125 return \"ret\;restore %%g0, %1, %Y0\";
9126 }"
9127 [(set_attr "type" "multi")
9128 (set_attr "length" "2")])
9129
9130 (define_insn "*return_si"
9131 [(set (match_operand:SI 0 "restore_operand" "")
9132 (match_operand:SI 1 "arith_operand" "rI"))
9133 (return)]
9134 "! TARGET_EPILOGUE"
9135 "*
9136 {
9137 if (! TARGET_ARCH64 && current_function_returns_struct)
9138 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9139 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9140 || IN_OR_GLOBAL_P (operands[1])))
9141 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9142 else
9143 return \"ret\;restore %%g0, %1, %Y0\";
9144 }"
9145 [(set_attr "type" "multi")
9146 (set_attr "length" "2")])
9147
9148 ;; The following pattern is only generated by delayed-branch scheduling,
9149 ;; when the insn winds up in the epilogue. This can happen not only when
9150 ;; ! TARGET_FPU because we move complex types around by parts using
9151 ;; SF mode SUBREGs.
9152 (define_insn "*return_sf_no_fpu"
9153 [(set (match_operand:SF 0 "restore_operand" "=r")
9154 (match_operand:SF 1 "register_operand" "r"))
9155 (return)]
9156 "! TARGET_EPILOGUE"
9157 "*
9158 {
9159 if (! TARGET_ARCH64 && current_function_returns_struct)
9160 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9161 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9162 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9163 else
9164 return \"ret\;restore %%g0, %1, %Y0\";
9165 }"
9166 [(set_attr "type" "multi")
9167 (set_attr "length" "2")])
9168
9169 (define_insn "*return_df_no_fpu"
9170 [(set (match_operand:DF 0 "restore_operand" "=r")
9171 (match_operand:DF 1 "register_operand" "r"))
9172 (return)]
9173 "! TARGET_EPILOGUE && TARGET_ARCH64"
9174 "*
9175 {
9176 if (IN_OR_GLOBAL_P (operands[1]))
9177 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9178 else
9179 return \"ret\;restore %%g0, %1, %Y0\";
9180 }"
9181 [(set_attr "type" "multi")
9182 (set_attr "length" "2")])
9183
9184 (define_insn "*return_addsi"
9185 [(set (match_operand:SI 0 "restore_operand" "")
9186 (plus:SI (match_operand:SI 1 "register_operand" "r")
9187 (match_operand:SI 2 "arith_operand" "rI")))
9188 (return)]
9189 "! TARGET_EPILOGUE"
9190 "*
9191 {
9192 if (! TARGET_ARCH64 && current_function_returns_struct)
9193 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9194 /* If operands are global or in registers, can use return */
9195 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9196 && (GET_CODE (operands[2]) == CONST_INT
9197 || IN_OR_GLOBAL_P (operands[2])))
9198 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9199 else
9200 return \"ret\;restore %r1, %2, %Y0\";
9201 }"
9202 [(set_attr "type" "multi")
9203 (set_attr "length" "2")])
9204
9205 (define_insn "*return_losum_si"
9206 [(set (match_operand:SI 0 "restore_operand" "")
9207 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9208 (match_operand:SI 2 "immediate_operand" "in")))
9209 (return)]
9210 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9211 "*
9212 {
9213 if (! TARGET_ARCH64 && current_function_returns_struct)
9214 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9215 /* If operands are global or in registers, can use return */
9216 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9217 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9218 else
9219 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9220 }"
9221 [(set_attr "type" "multi")
9222 (set_attr "length" "2")])
9223
9224 (define_insn "*return_di"
9225 [(set (match_operand:DI 0 "restore_operand" "")
9226 (match_operand:DI 1 "arith_double_operand" "rHI"))
9227 (return)]
9228 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9229 "ret\;restore %%g0, %1, %Y0"
9230 [(set_attr "type" "multi")
9231 (set_attr "length" "2")])
9232
9233 (define_insn "*return_adddi"
9234 [(set (match_operand:DI 0 "restore_operand" "")
9235 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9236 (match_operand:DI 2 "arith_double_operand" "rHI")))
9237 (return)]
9238 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9239 "ret\;restore %r1, %2, %Y0"
9240 [(set_attr "type" "multi")
9241 (set_attr "length" "2")])
9242
9243 (define_insn "*return_losum_di"
9244 [(set (match_operand:DI 0 "restore_operand" "")
9245 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9246 (match_operand:DI 2 "immediate_operand" "in")))
9247 (return)]
9248 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9249 "ret\;restore %r1, %%lo(%a2), %Y0"
9250 [(set_attr "type" "multi")
9251 (set_attr "length" "2")])
9252
9253 ;; The following pattern is only generated by delayed-branch scheduling,
9254 ;; when the insn winds up in the epilogue.
9255 (define_insn "*return_sf"
9256 [(set (reg:SF 32)
9257 (match_operand:SF 0 "register_operand" "f"))
9258 (return)]
9259 "! TARGET_EPILOGUE"
9260 "ret\;fmovs\\t%0, %%f0"
9261 [(set_attr "type" "multi")
9262 (set_attr "length" "2")])
9263
9264 ;; Now peepholes to do a call followed by a jump.
9265
9266 (define_peephole
9267 [(parallel [(set (match_operand 0 "" "")
9268 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9269 (match_operand 2 "" "")))
9270 (clobber (reg:SI 15))])
9271 (set (pc) (label_ref (match_operand 3 "" "")))]
9272 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9273 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9274 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9275
9276 (define_peephole
9277 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9278 (match_operand 1 "" ""))
9279 (clobber (reg:SI 15))])
9280 (set (pc) (label_ref (match_operand 2 "" "")))]
9281 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9282 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9283 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9284
9285 (define_peephole
9286 [(parallel [(set (match_operand 0 "" "")
9287 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9288 (match_operand 2 "" "")))
9289 (clobber (reg:DI 15))])
9290 (set (pc) (label_ref (match_operand 3 "" "")))]
9291 "TARGET_ARCH64
9292 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9293 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9294 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9295
9296 (define_peephole
9297 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9298 (match_operand 1 "" ""))
9299 (clobber (reg:DI 15))])
9300 (set (pc) (label_ref (match_operand 2 "" "")))]
9301 "TARGET_ARCH64
9302 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9303 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9304 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9305 \f
9306 (define_expand "prologue"
9307 [(const_int 1)]
9308 "flag_pic && current_function_uses_pic_offset_table"
9309 "
9310 {
9311 load_pic_register ();
9312 DONE;
9313 }")
9314
9315 ;; We need to reload %l7 for -mflat -fpic,
9316 ;; otherwise %l7 should be preserved simply
9317 ;; by loading the function's register window
9318 (define_expand "exception_receiver"
9319 [(const_int 0)]
9320 "TARGET_FLAT && flag_pic"
9321 "
9322 {
9323 load_pic_register ();
9324 DONE;
9325 }")
9326
9327 ;; Likewise
9328 (define_expand "builtin_setjmp_receiver"
9329 [(label_ref (match_operand 0 "" ""))]
9330 "TARGET_FLAT && flag_pic"
9331 "
9332 {
9333 load_pic_register ();
9334 DONE;
9335 }")
9336 \f
9337 (define_insn "trap"
9338 [(trap_if (const_int 1) (const_int 5))]
9339 ""
9340 "ta\\t5"
9341 [(set_attr "type" "misc")])
9342
9343 (define_expand "conditional_trap"
9344 [(trap_if (match_operator 0 "noov_compare_op"
9345 [(match_dup 2) (match_dup 3)])
9346 (match_operand:SI 1 "arith_operand" ""))]
9347 ""
9348 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9349 sparc_compare_op0, sparc_compare_op1);
9350 operands[3] = const0_rtx;")
9351
9352 (define_insn ""
9353 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9354 (match_operand:SI 1 "arith_operand" "rM"))]
9355 ""
9356 "t%C0\\t%1"
9357 [(set_attr "type" "misc")])
9358
9359 (define_insn ""
9360 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9361 (match_operand:SI 1 "arith_operand" "rM"))]
9362 "TARGET_V9"
9363 "t%C0\\t%%xcc, %1"
9364 [(set_attr "type" "misc")])