sparc.md (movdf): Avoid calling validize_mem during or after reload.
[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 /* We are able to build any DF constant in integer registers. */
3138 if (REGNO (operands[0]) < 32
3139 && (reload_completed || reload_in_progress))
3140 goto movdf_is_ok;
3141
3142 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3143 operands[1]));
3144 }
3145
3146 /* Handle MEM cases first. */
3147 if (GET_CODE (operands[0]) == MEM)
3148 {
3149 if (register_operand (operands[1], DFmode)
3150 || fp_zero_operand (operands[1], DFmode))
3151 goto movdf_is_ok;
3152
3153 if (! reload_in_progress)
3154 {
3155 operands[0] = validize_mem (operands[0]);
3156 operands[1] = force_reg (DFmode, operands[1]);
3157 }
3158 }
3159
3160 /* Fixup PIC cases. */
3161 if (flag_pic)
3162 {
3163 if (CONSTANT_P (operands[1])
3164 && pic_address_needs_scratch (operands[1]))
3165 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3166
3167 if (symbolic_operand (operands[1], DFmode))
3168 {
3169 operands[1] = legitimize_pic_address (operands[1],
3170 DFmode,
3171 (reload_in_progress ?
3172 operands[0] :
3173 NULL_RTX));
3174 }
3175 }
3176
3177 movdf_is_ok:
3178 ;
3179 }")
3180
3181 ;; Be careful, fmovd does not exist when !v9.
3182 (define_insn "*movdf_insn_sp32"
3183 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3184 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3185 "TARGET_FPU
3186 && ! TARGET_V9
3187 && (register_operand (operands[0], DFmode)
3188 || register_operand (operands[1], DFmode)
3189 || fp_zero_operand (operands[1], DFmode))"
3190 "@
3191 ldd\\t%1, %0
3192 std\\t%1, %0
3193 ldd\\t%1, %0
3194 std\\t%1, %0
3195 #
3196 #
3197 #
3198 #
3199 #
3200 #"
3201 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3202 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3203
3204 (define_insn "*movdf_no_e_insn_sp32"
3205 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3206 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3207 "! TARGET_FPU
3208 && ! TARGET_V9
3209 && ! TARGET_ARCH64
3210 && (register_operand (operands[0], DFmode)
3211 || register_operand (operands[1], DFmode)
3212 || fp_zero_operand (operands[1], DFmode))"
3213 "@
3214 ldd\\t%1, %0
3215 std\\t%1, %0
3216 #
3217 #
3218 #"
3219 [(set_attr "type" "load,store,*,*,*")
3220 (set_attr "length" "*,*,2,2,2")])
3221
3222 (define_insn "*movdf_no_e_insn_v9_sp32"
3223 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3224 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3225 "! TARGET_FPU
3226 && TARGET_V9
3227 && ! TARGET_ARCH64
3228 && (register_operand (operands[0], DFmode)
3229 || register_operand (operands[1], DFmode)
3230 || fp_zero_operand (operands[1], DFmode))"
3231 "@
3232 ldd\\t%1, %0
3233 std\\t%1, %0
3234 stx\\t%r1, %0
3235 #
3236 #"
3237 [(set_attr "type" "load,store,store,*,*")
3238 (set_attr "length" "*,*,*,2,2")])
3239
3240 ;; We have available v9 double floats but not 64-bit
3241 ;; integer registers and no VIS.
3242 (define_insn "*movdf_insn_v9only_novis"
3243 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3244 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3245 "TARGET_FPU
3246 && TARGET_V9
3247 && ! TARGET_VIS
3248 && ! TARGET_ARCH64
3249 && (register_operand (operands[0], DFmode)
3250 || register_operand (operands[1], DFmode)
3251 || fp_zero_operand (operands[1], DFmode))"
3252 "@
3253 fmovd\\t%1, %0
3254 ldd\\t%1, %0
3255 stx\\t%r1, %0
3256 std\\t%1, %0
3257 ldd\\t%1, %0
3258 std\\t%1, %0
3259 #
3260 #
3261 #"
3262 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3263 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3264 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3265
3266 ;; We have available v9 double floats but not 64-bit
3267 ;; integer registers but we have VIS.
3268 (define_insn "*movdf_insn_v9only_vis"
3269 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3270 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3271 "TARGET_FPU
3272 && TARGET_VIS
3273 && ! TARGET_ARCH64
3274 && (register_operand (operands[0], DFmode)
3275 || register_operand (operands[1], DFmode)
3276 || fp_zero_operand (operands[1], DFmode))"
3277 "@
3278 fzero\\t%0
3279 fmovd\\t%1, %0
3280 ldd\\t%1, %0
3281 stx\\t%r1, %0
3282 std\\t%1, %0
3283 ldd\\t%1, %0
3284 std\\t%1, %0
3285 #
3286 #
3287 #"
3288 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3289 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3290 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3291
3292 ;; We have available both v9 double floats and 64-bit
3293 ;; integer registers. No VIS though.
3294 (define_insn "*movdf_insn_sp64_novis"
3295 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3296 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3297 "TARGET_FPU
3298 && ! TARGET_VIS
3299 && TARGET_ARCH64
3300 && (register_operand (operands[0], DFmode)
3301 || register_operand (operands[1], DFmode)
3302 || fp_zero_operand (operands[1], DFmode))"
3303 "@
3304 fmovd\\t%1, %0
3305 ldd\\t%1, %0
3306 std\\t%1, %0
3307 mov\\t%r1, %0
3308 ldx\\t%1, %0
3309 stx\\t%r1, %0
3310 #"
3311 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3312 (set_attr "length" "*,*,*,*,*,*,2")
3313 (set_attr "fptype" "double,*,*,*,*,*,*")])
3314
3315 ;; We have available both v9 double floats and 64-bit
3316 ;; integer registers. And we have VIS.
3317 (define_insn "*movdf_insn_sp64_vis"
3318 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3319 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3320 "TARGET_FPU
3321 && TARGET_VIS
3322 && TARGET_ARCH64
3323 && (register_operand (operands[0], DFmode)
3324 || register_operand (operands[1], DFmode)
3325 || fp_zero_operand (operands[1], DFmode))"
3326 "@
3327 fzero\\t%0
3328 fmovd\\t%1, %0
3329 ldd\\t%1, %0
3330 std\\t%1, %0
3331 mov\\t%r1, %0
3332 ldx\\t%1, %0
3333 stx\\t%r1, %0
3334 #"
3335 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3336 (set_attr "length" "*,*,*,*,*,*,*,2")
3337 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3338
3339 (define_insn "*movdf_no_e_insn_sp64"
3340 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3341 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3342 "! TARGET_FPU
3343 && TARGET_ARCH64
3344 && (register_operand (operands[0], DFmode)
3345 || register_operand (operands[1], DFmode)
3346 || fp_zero_operand (operands[1], DFmode))"
3347 "@
3348 mov\\t%1, %0
3349 ldx\\t%1, %0
3350 stx\\t%r1, %0"
3351 [(set_attr "type" "*,load,store")])
3352
3353 (define_split
3354 [(set (match_operand:DF 0 "register_operand" "")
3355 (match_operand:DF 1 "const_double_operand" ""))]
3356 "TARGET_FPU
3357 && (GET_CODE (operands[0]) == REG
3358 && REGNO (operands[0]) < 32)
3359 && ! fp_zero_operand(operands[1], DFmode)
3360 && reload_completed"
3361 [(clobber (const_int 0))]
3362 "
3363 {
3364 REAL_VALUE_TYPE r;
3365 long l[2];
3366
3367 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3368 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3369 if (GET_CODE (operands[0]) == SUBREG)
3370 operands[0] = alter_subreg (operands[0]);
3371 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3372
3373 if (TARGET_ARCH64)
3374 {
3375 #if HOST_BITS_PER_WIDE_INT == 64
3376 HOST_WIDE_INT val;
3377
3378 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3379 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3380 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3381 #else
3382 emit_insn (gen_movdi (operands[0],
3383 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3384 #endif
3385 }
3386 else
3387 {
3388 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3389 GEN_INT (l[0])));
3390
3391 /* Slick... but this trick loses if this subreg constant part
3392 can be done in one insn. */
3393 if (l[1] == l[0]
3394 && !(SPARC_SETHI_P (l[0])
3395 || SPARC_SIMM13_P (l[0])))
3396 {
3397 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3398 gen_highpart (SImode, operands[0])));
3399 }
3400 else
3401 {
3402 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3403 GEN_INT (l[1])));
3404 }
3405 }
3406 DONE;
3407 }")
3408
3409 ;; Ok, now the splits to handle all the multi insn and
3410 ;; mis-aligned memory address cases.
3411 ;; In these splits please take note that we must be
3412 ;; careful when V9 but not ARCH64 because the integer
3413 ;; register DFmode cases must be handled.
3414 (define_split
3415 [(set (match_operand:DF 0 "register_operand" "")
3416 (match_operand:DF 1 "register_operand" ""))]
3417 "(! TARGET_V9
3418 || (! TARGET_ARCH64
3419 && ((GET_CODE (operands[0]) == REG
3420 && REGNO (operands[0]) < 32)
3421 || (GET_CODE (operands[0]) == SUBREG
3422 && GET_CODE (SUBREG_REG (operands[0])) == REG
3423 && REGNO (SUBREG_REG (operands[0])) < 32))))
3424 && reload_completed"
3425 [(clobber (const_int 0))]
3426 "
3427 {
3428 rtx set_dest = operands[0];
3429 rtx set_src = operands[1];
3430 rtx dest1, dest2;
3431 rtx src1, src2;
3432
3433 if (GET_CODE (set_dest) == SUBREG)
3434 set_dest = alter_subreg (set_dest);
3435 if (GET_CODE (set_src) == SUBREG)
3436 set_src = alter_subreg (set_src);
3437
3438 dest1 = gen_highpart (SFmode, set_dest);
3439 dest2 = gen_lowpart (SFmode, set_dest);
3440 src1 = gen_highpart (SFmode, set_src);
3441 src2 = gen_lowpart (SFmode, set_src);
3442
3443 /* Now emit using the real source and destination we found, swapping
3444 the order if we detect overlap. */
3445 if (reg_overlap_mentioned_p (dest1, src2))
3446 {
3447 emit_insn (gen_movsf (dest2, src2));
3448 emit_insn (gen_movsf (dest1, src1));
3449 }
3450 else
3451 {
3452 emit_insn (gen_movsf (dest1, src1));
3453 emit_insn (gen_movsf (dest2, src2));
3454 }
3455 DONE;
3456 }")
3457
3458 (define_split
3459 [(set (match_operand:DF 0 "register_operand" "")
3460 (match_operand:DF 1 "memory_operand" ""))]
3461 "reload_completed
3462 && ! TARGET_ARCH64
3463 && (((REGNO (operands[0]) % 2) != 0)
3464 || ! mem_min_alignment (operands[1], 8))
3465 && offsettable_memref_p (operands[1])"
3466 [(clobber (const_int 0))]
3467 "
3468 {
3469 rtx word0 = adjust_address (operands[1], SFmode, 0);
3470 rtx word1 = adjust_address (operands[1], SFmode, 4);
3471
3472 if (GET_CODE (operands[0]) == SUBREG)
3473 operands[0] = alter_subreg (operands[0]);
3474
3475 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3476 {
3477 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3478 word1));
3479 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3480 word0));
3481 }
3482 else
3483 {
3484 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3485 word0));
3486 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3487 word1));
3488 }
3489 DONE;
3490 }")
3491
3492 (define_split
3493 [(set (match_operand:DF 0 "memory_operand" "")
3494 (match_operand:DF 1 "register_operand" ""))]
3495 "reload_completed
3496 && ! TARGET_ARCH64
3497 && (((REGNO (operands[1]) % 2) != 0)
3498 || ! mem_min_alignment (operands[0], 8))
3499 && offsettable_memref_p (operands[0])"
3500 [(clobber (const_int 0))]
3501 "
3502 {
3503 rtx word0 = adjust_address (operands[0], SFmode, 0);
3504 rtx word1 = adjust_address (operands[0], SFmode, 4);
3505
3506 if (GET_CODE (operands[1]) == SUBREG)
3507 operands[1] = alter_subreg (operands[1]);
3508 emit_insn (gen_movsf (word0,
3509 gen_highpart (SFmode, operands[1])));
3510 emit_insn (gen_movsf (word1,
3511 gen_lowpart (SFmode, operands[1])));
3512 DONE;
3513 }")
3514
3515 (define_split
3516 [(set (match_operand:DF 0 "memory_operand" "")
3517 (match_operand:DF 1 "fp_zero_operand" ""))]
3518 "reload_completed
3519 && (! TARGET_V9
3520 || (! TARGET_ARCH64
3521 && ! mem_min_alignment (operands[0], 8)))
3522 && offsettable_memref_p (operands[0])"
3523 [(clobber (const_int 0))]
3524 "
3525 {
3526 rtx dest1, dest2;
3527
3528 dest1 = adjust_address (operands[0], SFmode, 0);
3529 dest2 = adjust_address (operands[0], SFmode, 4);
3530
3531 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3532 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3533 DONE;
3534 }")
3535
3536 (define_split
3537 [(set (match_operand:DF 0 "register_operand" "")
3538 (match_operand:DF 1 "fp_zero_operand" ""))]
3539 "reload_completed
3540 && ! TARGET_ARCH64
3541 && ((GET_CODE (operands[0]) == REG
3542 && REGNO (operands[0]) < 32)
3543 || (GET_CODE (operands[0]) == SUBREG
3544 && GET_CODE (SUBREG_REG (operands[0])) == REG
3545 && REGNO (SUBREG_REG (operands[0])) < 32))"
3546 [(clobber (const_int 0))]
3547 "
3548 {
3549 rtx set_dest = operands[0];
3550 rtx dest1, dest2;
3551
3552 if (GET_CODE (set_dest) == SUBREG)
3553 set_dest = alter_subreg (set_dest);
3554 dest1 = gen_highpart (SFmode, set_dest);
3555 dest2 = gen_lowpart (SFmode, set_dest);
3556 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3557 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3558 DONE;
3559 }")
3560
3561 (define_expand "movtf"
3562 [(set (match_operand:TF 0 "general_operand" "")
3563 (match_operand:TF 1 "general_operand" ""))]
3564 ""
3565 "
3566 {
3567 /* Force TFmode constants into memory. */
3568 if (GET_CODE (operands[0]) == REG
3569 && CONSTANT_P (operands[1]))
3570 {
3571 /* emit_group_store will send such bogosity to us when it is
3572 not storing directly into memory. So fix this up to avoid
3573 crashes in output_constant_pool. */
3574 if (operands [1] == const0_rtx)
3575 operands[1] = CONST0_RTX (TFmode);
3576
3577 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3578 goto movtf_is_ok;
3579
3580 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3581 operands[1]));
3582 }
3583
3584 /* Handle MEM cases first, note that only v9 guarentees
3585 full 16-byte alignment for quads. */
3586 if (GET_CODE (operands[0]) == MEM)
3587 {
3588 if (register_operand (operands[1], TFmode)
3589 || fp_zero_operand (operands[1], TFmode))
3590 goto movtf_is_ok;
3591
3592 if (! reload_in_progress)
3593 {
3594 operands[0] = validize_mem (operands[0]);
3595 operands[1] = force_reg (TFmode, operands[1]);
3596 }
3597 }
3598
3599 /* Fixup PIC cases. */
3600 if (flag_pic)
3601 {
3602 if (CONSTANT_P (operands[1])
3603 && pic_address_needs_scratch (operands[1]))
3604 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3605
3606 if (symbolic_operand (operands[1], TFmode))
3607 {
3608 operands[1] = legitimize_pic_address (operands[1],
3609 TFmode,
3610 (reload_in_progress ?
3611 operands[0] :
3612 NULL_RTX));
3613 }
3614 }
3615
3616 movtf_is_ok:
3617 ;
3618 }")
3619
3620 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3621 ;; we must split them all. :-(
3622 (define_insn "*movtf_insn_sp32"
3623 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3624 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3625 "TARGET_FPU
3626 && ! TARGET_VIS
3627 && ! TARGET_ARCH64
3628 && (register_operand (operands[0], TFmode)
3629 || register_operand (operands[1], TFmode)
3630 || fp_zero_operand (operands[1], TFmode))"
3631 "#"
3632 [(set_attr "length" "4")])
3633
3634 (define_insn "*movtf_insn_vis_sp32"
3635 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3636 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3637 "TARGET_FPU
3638 && TARGET_VIS
3639 && ! TARGET_ARCH64
3640 && (register_operand (operands[0], TFmode)
3641 || register_operand (operands[1], TFmode)
3642 || fp_zero_operand (operands[1], TFmode))"
3643 "#"
3644 [(set_attr "length" "4")])
3645
3646 ;; Exactly the same as above, except that all `e' cases are deleted.
3647 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3648 ;; when -mno-fpu.
3649
3650 (define_insn "*movtf_no_e_insn_sp32"
3651 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3652 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3653 "! TARGET_FPU
3654 && ! TARGET_ARCH64
3655 && (register_operand (operands[0], TFmode)
3656 || register_operand (operands[1], TFmode)
3657 || fp_zero_operand (operands[1], TFmode))"
3658 "#"
3659 [(set_attr "length" "4")])
3660
3661 ;; Now handle the float reg cases directly when arch64,
3662 ;; hard_quad, and proper reg number alignment are all true.
3663 (define_insn "*movtf_insn_hq_sp64"
3664 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3665 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3666 "TARGET_FPU
3667 && ! TARGET_VIS
3668 && TARGET_ARCH64
3669 && TARGET_HARD_QUAD
3670 && (register_operand (operands[0], TFmode)
3671 || register_operand (operands[1], TFmode)
3672 || fp_zero_operand (operands[1], TFmode))"
3673 "@
3674 fmovq\\t%1, %0
3675 ldq\\t%1, %0
3676 stq\\t%1, %0
3677 #
3678 #"
3679 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3680 (set_attr "length" "*,*,*,2,2")])
3681
3682 (define_insn "*movtf_insn_hq_vis_sp64"
3683 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3684 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3685 "TARGET_FPU
3686 && TARGET_VIS
3687 && TARGET_ARCH64
3688 && TARGET_HARD_QUAD
3689 && (register_operand (operands[0], TFmode)
3690 || register_operand (operands[1], TFmode)
3691 || fp_zero_operand (operands[1], TFmode))"
3692 "@
3693 fmovq\\t%1, %0
3694 ldq\\t%1, %0
3695 stq\\t%1, %0
3696 #
3697 #
3698 #"
3699 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3700 (set_attr "length" "*,*,*,2,2,2")])
3701
3702 ;; Now we allow the integer register cases even when
3703 ;; only arch64 is true.
3704 (define_insn "*movtf_insn_sp64"
3705 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3706 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3707 "TARGET_FPU
3708 && ! TARGET_VIS
3709 && TARGET_ARCH64
3710 && ! TARGET_HARD_QUAD
3711 && (register_operand (operands[0], TFmode)
3712 || register_operand (operands[1], TFmode)
3713 || fp_zero_operand (operands[1], TFmode))"
3714 "#"
3715 [(set_attr "length" "2")])
3716
3717 (define_insn "*movtf_insn_vis_sp64"
3718 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3719 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3720 "TARGET_FPU
3721 && TARGET_VIS
3722 && TARGET_ARCH64
3723 && ! TARGET_HARD_QUAD
3724 && (register_operand (operands[0], TFmode)
3725 || register_operand (operands[1], TFmode)
3726 || fp_zero_operand (operands[1], TFmode))"
3727 "#"
3728 [(set_attr "length" "2")])
3729
3730 (define_insn "*movtf_no_e_insn_sp64"
3731 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3732 (match_operand:TF 1 "input_operand" "orG,rG"))]
3733 "! TARGET_FPU
3734 && TARGET_ARCH64
3735 && (register_operand (operands[0], TFmode)
3736 || register_operand (operands[1], TFmode)
3737 || fp_zero_operand (operands[1], TFmode))"
3738 "#"
3739 [(set_attr "length" "2")])
3740
3741 ;; Now all the splits to handle multi-insn TF mode moves.
3742 (define_split
3743 [(set (match_operand:TF 0 "register_operand" "")
3744 (match_operand:TF 1 "register_operand" ""))]
3745 "reload_completed
3746 && (! TARGET_ARCH64
3747 || (TARGET_FPU
3748 && ! TARGET_HARD_QUAD))"
3749 [(clobber (const_int 0))]
3750 "
3751 {
3752 rtx set_dest = operands[0];
3753 rtx set_src = operands[1];
3754 rtx dest1, dest2;
3755 rtx src1, src2;
3756
3757 if (GET_CODE (set_dest) == SUBREG)
3758 set_dest = alter_subreg (set_dest);
3759 if (GET_CODE (set_src) == SUBREG)
3760 set_src = alter_subreg (set_src);
3761
3762 dest1 = gen_df_reg (set_dest, 0);
3763 dest2 = gen_df_reg (set_dest, 1);
3764 src1 = gen_df_reg (set_src, 0);
3765 src2 = gen_df_reg (set_src, 1);
3766
3767 /* Now emit using the real source and destination we found, swapping
3768 the order if we detect overlap. */
3769 if (reg_overlap_mentioned_p (dest1, src2))
3770 {
3771 emit_insn (gen_movdf (dest2, src2));
3772 emit_insn (gen_movdf (dest1, src1));
3773 }
3774 else
3775 {
3776 emit_insn (gen_movdf (dest1, src1));
3777 emit_insn (gen_movdf (dest2, src2));
3778 }
3779 DONE;
3780 }")
3781
3782 (define_split
3783 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3784 (match_operand:TF 1 "fp_zero_operand" ""))]
3785 "reload_completed"
3786 [(clobber (const_int 0))]
3787 "
3788 {
3789 rtx set_dest = operands[0];
3790 rtx dest1, dest2;
3791
3792 switch (GET_CODE (set_dest))
3793 {
3794 case SUBREG:
3795 set_dest = alter_subreg (set_dest);
3796 /* FALLTHROUGH */
3797 case REG:
3798 dest1 = gen_df_reg (set_dest, 0);
3799 dest2 = gen_df_reg (set_dest, 1);
3800 break;
3801 case MEM:
3802 dest1 = adjust_address (set_dest, DFmode, 0);
3803 dest2 = adjust_address (set_dest, DFmode, 8);
3804 break;
3805 default:
3806 abort ();
3807 }
3808
3809 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3810 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3811 DONE;
3812 }")
3813
3814 (define_split
3815 [(set (match_operand:TF 0 "register_operand" "")
3816 (match_operand:TF 1 "memory_operand" ""))]
3817 "(reload_completed
3818 && offsettable_memref_p (operands[1]))"
3819 [(clobber (const_int 0))]
3820 "
3821 {
3822 rtx word0 = adjust_address (operands[1], DFmode, 0);
3823 rtx word1 = adjust_address (operands[1], DFmode, 8);
3824 rtx set_dest, dest1, dest2;
3825
3826 set_dest = operands[0];
3827 if (GET_CODE (set_dest) == SUBREG)
3828 set_dest = alter_subreg (set_dest);
3829
3830 dest1 = gen_df_reg (set_dest, 0);
3831 dest2 = gen_df_reg (set_dest, 1);
3832
3833 /* Now output, ordering such that we don't clobber any registers
3834 mentioned in the address. */
3835 if (reg_overlap_mentioned_p (dest1, word1))
3836
3837 {
3838 emit_insn (gen_movdf (dest2, word1));
3839 emit_insn (gen_movdf (dest1, word0));
3840 }
3841 else
3842 {
3843 emit_insn (gen_movdf (dest1, word0));
3844 emit_insn (gen_movdf (dest2, word1));
3845 }
3846 DONE;
3847 }")
3848
3849 (define_split
3850 [(set (match_operand:TF 0 "memory_operand" "")
3851 (match_operand:TF 1 "register_operand" ""))]
3852 "(reload_completed
3853 && offsettable_memref_p (operands[0]))"
3854 [(clobber (const_int 0))]
3855 "
3856 {
3857 rtx set_src = operands[1];
3858 if (GET_CODE (set_src) == SUBREG)
3859 set_src = alter_subreg (set_src);
3860
3861 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3862 gen_df_reg (set_src, 0)));
3863 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3864 gen_df_reg (set_src, 1)));
3865 DONE;
3866 }")
3867 \f
3868 ;; Sparc V9 conditional move instructions.
3869
3870 ;; We can handle larger constants here for some flavors, but for now we keep
3871 ;; it simple and only allow those constants supported by all flavours.
3872 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3873 ;; 3 contains the constant if one is present, but we handle either for
3874 ;; generality (sparc.c puts a constant in operand 2).
3875
3876 (define_expand "movqicc"
3877 [(set (match_operand:QI 0 "register_operand" "")
3878 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3879 (match_operand:QI 2 "arith10_operand" "")
3880 (match_operand:QI 3 "arith10_operand" "")))]
3881 "TARGET_V9"
3882 "
3883 {
3884 enum rtx_code code = GET_CODE (operands[1]);
3885
3886 if (GET_MODE (sparc_compare_op0) == DImode
3887 && ! TARGET_ARCH64)
3888 FAIL;
3889
3890 if (sparc_compare_op1 == const0_rtx
3891 && GET_CODE (sparc_compare_op0) == REG
3892 && GET_MODE (sparc_compare_op0) == DImode
3893 && v9_regcmp_p (code))
3894 {
3895 operands[1] = gen_rtx_fmt_ee (code, DImode,
3896 sparc_compare_op0, sparc_compare_op1);
3897 }
3898 else
3899 {
3900 rtx cc_reg = gen_compare_reg (code,
3901 sparc_compare_op0, sparc_compare_op1);
3902 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3903 }
3904 }")
3905
3906 (define_expand "movhicc"
3907 [(set (match_operand:HI 0 "register_operand" "")
3908 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3909 (match_operand:HI 2 "arith10_operand" "")
3910 (match_operand:HI 3 "arith10_operand" "")))]
3911 "TARGET_V9"
3912 "
3913 {
3914 enum rtx_code code = GET_CODE (operands[1]);
3915
3916 if (GET_MODE (sparc_compare_op0) == DImode
3917 && ! TARGET_ARCH64)
3918 FAIL;
3919
3920 if (sparc_compare_op1 == const0_rtx
3921 && GET_CODE (sparc_compare_op0) == REG
3922 && GET_MODE (sparc_compare_op0) == DImode
3923 && v9_regcmp_p (code))
3924 {
3925 operands[1] = gen_rtx_fmt_ee (code, DImode,
3926 sparc_compare_op0, sparc_compare_op1);
3927 }
3928 else
3929 {
3930 rtx cc_reg = gen_compare_reg (code,
3931 sparc_compare_op0, sparc_compare_op1);
3932 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3933 }
3934 }")
3935
3936 (define_expand "movsicc"
3937 [(set (match_operand:SI 0 "register_operand" "")
3938 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3939 (match_operand:SI 2 "arith10_operand" "")
3940 (match_operand:SI 3 "arith10_operand" "")))]
3941 "TARGET_V9"
3942 "
3943 {
3944 enum rtx_code code = GET_CODE (operands[1]);
3945 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3946
3947 if (sparc_compare_op1 == const0_rtx
3948 && GET_CODE (sparc_compare_op0) == REG
3949 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3950 {
3951 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3952 sparc_compare_op0, sparc_compare_op1);
3953 }
3954 else
3955 {
3956 rtx cc_reg = gen_compare_reg (code,
3957 sparc_compare_op0, sparc_compare_op1);
3958 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3959 cc_reg, const0_rtx);
3960 }
3961 }")
3962
3963 (define_expand "movdicc"
3964 [(set (match_operand:DI 0 "register_operand" "")
3965 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3966 (match_operand:DI 2 "arith10_double_operand" "")
3967 (match_operand:DI 3 "arith10_double_operand" "")))]
3968 "TARGET_ARCH64"
3969 "
3970 {
3971 enum rtx_code code = GET_CODE (operands[1]);
3972
3973 if (sparc_compare_op1 == const0_rtx
3974 && GET_CODE (sparc_compare_op0) == REG
3975 && GET_MODE (sparc_compare_op0) == DImode
3976 && v9_regcmp_p (code))
3977 {
3978 operands[1] = gen_rtx_fmt_ee (code, DImode,
3979 sparc_compare_op0, sparc_compare_op1);
3980 }
3981 else
3982 {
3983 rtx cc_reg = gen_compare_reg (code,
3984 sparc_compare_op0, sparc_compare_op1);
3985 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3986 cc_reg, const0_rtx);
3987 }
3988 }")
3989
3990 (define_expand "movsfcc"
3991 [(set (match_operand:SF 0 "register_operand" "")
3992 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3993 (match_operand:SF 2 "register_operand" "")
3994 (match_operand:SF 3 "register_operand" "")))]
3995 "TARGET_V9 && TARGET_FPU"
3996 "
3997 {
3998 enum rtx_code code = GET_CODE (operands[1]);
3999
4000 if (GET_MODE (sparc_compare_op0) == DImode
4001 && ! TARGET_ARCH64)
4002 FAIL;
4003
4004 if (sparc_compare_op1 == const0_rtx
4005 && GET_CODE (sparc_compare_op0) == REG
4006 && GET_MODE (sparc_compare_op0) == DImode
4007 && v9_regcmp_p (code))
4008 {
4009 operands[1] = gen_rtx_fmt_ee (code, DImode,
4010 sparc_compare_op0, sparc_compare_op1);
4011 }
4012 else
4013 {
4014 rtx cc_reg = gen_compare_reg (code,
4015 sparc_compare_op0, sparc_compare_op1);
4016 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4017 }
4018 }")
4019
4020 (define_expand "movdfcc"
4021 [(set (match_operand:DF 0 "register_operand" "")
4022 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4023 (match_operand:DF 2 "register_operand" "")
4024 (match_operand:DF 3 "register_operand" "")))]
4025 "TARGET_V9 && TARGET_FPU"
4026 "
4027 {
4028 enum rtx_code code = GET_CODE (operands[1]);
4029
4030 if (GET_MODE (sparc_compare_op0) == DImode
4031 && ! TARGET_ARCH64)
4032 FAIL;
4033
4034 if (sparc_compare_op1 == const0_rtx
4035 && GET_CODE (sparc_compare_op0) == REG
4036 && GET_MODE (sparc_compare_op0) == DImode
4037 && v9_regcmp_p (code))
4038 {
4039 operands[1] = gen_rtx_fmt_ee (code, DImode,
4040 sparc_compare_op0, sparc_compare_op1);
4041 }
4042 else
4043 {
4044 rtx cc_reg = gen_compare_reg (code,
4045 sparc_compare_op0, sparc_compare_op1);
4046 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4047 }
4048 }")
4049
4050 (define_expand "movtfcc"
4051 [(set (match_operand:TF 0 "register_operand" "")
4052 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4053 (match_operand:TF 2 "register_operand" "")
4054 (match_operand:TF 3 "register_operand" "")))]
4055 "TARGET_V9 && TARGET_FPU"
4056 "
4057 {
4058 enum rtx_code code = GET_CODE (operands[1]);
4059
4060 if (GET_MODE (sparc_compare_op0) == DImode
4061 && ! TARGET_ARCH64)
4062 FAIL;
4063
4064 if (sparc_compare_op1 == const0_rtx
4065 && GET_CODE (sparc_compare_op0) == REG
4066 && GET_MODE (sparc_compare_op0) == DImode
4067 && v9_regcmp_p (code))
4068 {
4069 operands[1] = gen_rtx_fmt_ee (code, DImode,
4070 sparc_compare_op0, sparc_compare_op1);
4071 }
4072 else
4073 {
4074 rtx cc_reg = gen_compare_reg (code,
4075 sparc_compare_op0, sparc_compare_op1);
4076 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4077 }
4078 }")
4079
4080 ;; Conditional move define_insns.
4081
4082 (define_insn "*movqi_cc_sp64"
4083 [(set (match_operand:QI 0 "register_operand" "=r,r")
4084 (if_then_else:QI (match_operator 1 "comparison_operator"
4085 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4086 (const_int 0)])
4087 (match_operand:QI 3 "arith11_operand" "rL,0")
4088 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4089 "TARGET_V9"
4090 "@
4091 mov%C1\\t%x2, %3, %0
4092 mov%c1\\t%x2, %4, %0"
4093 [(set_attr "type" "cmove")])
4094
4095 (define_insn "*movhi_cc_sp64"
4096 [(set (match_operand:HI 0 "register_operand" "=r,r")
4097 (if_then_else:HI (match_operator 1 "comparison_operator"
4098 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4099 (const_int 0)])
4100 (match_operand:HI 3 "arith11_operand" "rL,0")
4101 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4102 "TARGET_V9"
4103 "@
4104 mov%C1\\t%x2, %3, %0
4105 mov%c1\\t%x2, %4, %0"
4106 [(set_attr "type" "cmove")])
4107
4108 (define_insn "*movsi_cc_sp64"
4109 [(set (match_operand:SI 0 "register_operand" "=r,r")
4110 (if_then_else:SI (match_operator 1 "comparison_operator"
4111 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4112 (const_int 0)])
4113 (match_operand:SI 3 "arith11_operand" "rL,0")
4114 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4115 "TARGET_V9"
4116 "@
4117 mov%C1\\t%x2, %3, %0
4118 mov%c1\\t%x2, %4, %0"
4119 [(set_attr "type" "cmove")])
4120
4121 ;; ??? The constraints of operands 3,4 need work.
4122 (define_insn "*movdi_cc_sp64"
4123 [(set (match_operand:DI 0 "register_operand" "=r,r")
4124 (if_then_else:DI (match_operator 1 "comparison_operator"
4125 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4126 (const_int 0)])
4127 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4128 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4129 "TARGET_ARCH64"
4130 "@
4131 mov%C1\\t%x2, %3, %0
4132 mov%c1\\t%x2, %4, %0"
4133 [(set_attr "type" "cmove")])
4134
4135 (define_insn "*movdi_cc_sp64_trunc"
4136 [(set (match_operand:SI 0 "register_operand" "=r,r")
4137 (if_then_else:SI (match_operator 1 "comparison_operator"
4138 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4139 (const_int 0)])
4140 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4141 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4142 "TARGET_ARCH64"
4143 "@
4144 mov%C1\\t%x2, %3, %0
4145 mov%c1\\t%x2, %4, %0"
4146 [(set_attr "type" "cmove")])
4147
4148 (define_insn "*movsf_cc_sp64"
4149 [(set (match_operand:SF 0 "register_operand" "=f,f")
4150 (if_then_else:SF (match_operator 1 "comparison_operator"
4151 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4152 (const_int 0)])
4153 (match_operand:SF 3 "register_operand" "f,0")
4154 (match_operand:SF 4 "register_operand" "0,f")))]
4155 "TARGET_V9 && TARGET_FPU"
4156 "@
4157 fmovs%C1\\t%x2, %3, %0
4158 fmovs%c1\\t%x2, %4, %0"
4159 [(set_attr "type" "fpcmove")])
4160
4161 (define_insn "movdf_cc_sp64"
4162 [(set (match_operand:DF 0 "register_operand" "=e,e")
4163 (if_then_else:DF (match_operator 1 "comparison_operator"
4164 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4165 (const_int 0)])
4166 (match_operand:DF 3 "register_operand" "e,0")
4167 (match_operand:DF 4 "register_operand" "0,e")))]
4168 "TARGET_V9 && TARGET_FPU"
4169 "@
4170 fmovd%C1\\t%x2, %3, %0
4171 fmovd%c1\\t%x2, %4, %0"
4172 [(set_attr "type" "fpcmove")
4173 (set_attr "fptype" "double")])
4174
4175 (define_insn "*movtf_cc_hq_sp64"
4176 [(set (match_operand:TF 0 "register_operand" "=e,e")
4177 (if_then_else:TF (match_operator 1 "comparison_operator"
4178 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4179 (const_int 0)])
4180 (match_operand:TF 3 "register_operand" "e,0")
4181 (match_operand:TF 4 "register_operand" "0,e")))]
4182 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4183 "@
4184 fmovq%C1\\t%x2, %3, %0
4185 fmovq%c1\\t%x2, %4, %0"
4186 [(set_attr "type" "fpcmove")])
4187
4188 (define_insn "*movtf_cc_sp64"
4189 [(set (match_operand:TF 0 "register_operand" "=e,e")
4190 (if_then_else:TF (match_operator 1 "comparison_operator"
4191 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4192 (const_int 0)])
4193 (match_operand:TF 3 "register_operand" "e,0")
4194 (match_operand:TF 4 "register_operand" "0,e")))]
4195 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4196 "#"
4197 [(set_attr "length" "2")])
4198
4199 (define_split
4200 [(set (match_operand:TF 0 "register_operand" "")
4201 (if_then_else:TF (match_operator 1 "comparison_operator"
4202 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4203 (const_int 0)])
4204 (match_operand:TF 3 "register_operand" "")
4205 (match_operand:TF 4 "register_operand" "")))]
4206 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4207 [(clobber (const_int 0))]
4208 "
4209 {
4210 rtx set_dest = operands[0];
4211 rtx set_srca = operands[3];
4212 rtx set_srcb = operands[4];
4213 int third = rtx_equal_p (set_dest, set_srca);
4214 rtx dest1, dest2;
4215 rtx srca1, srca2, srcb1, srcb2;
4216
4217 if (GET_CODE (set_dest) == SUBREG)
4218 set_dest = alter_subreg (set_dest);
4219 if (GET_CODE (set_srca) == SUBREG)
4220 set_srca = alter_subreg (set_srca);
4221 if (GET_CODE (set_srcb) == SUBREG)
4222 set_srcb = alter_subreg (set_srcb);
4223
4224 dest1 = gen_df_reg (set_dest, 0);
4225 dest2 = gen_df_reg (set_dest, 1);
4226 srca1 = gen_df_reg (set_srca, 0);
4227 srca2 = gen_df_reg (set_srca, 1);
4228 srcb1 = gen_df_reg (set_srcb, 0);
4229 srcb2 = gen_df_reg (set_srcb, 1);
4230
4231 /* Now emit using the real source and destination we found, swapping
4232 the order if we detect overlap. */
4233 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4234 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4235 {
4236 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4237 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4238 }
4239 else
4240 {
4241 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4242 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4243 }
4244 DONE;
4245 }")
4246
4247 (define_insn "*movqi_cc_reg_sp64"
4248 [(set (match_operand:QI 0 "register_operand" "=r,r")
4249 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4250 [(match_operand:DI 2 "register_operand" "r,r")
4251 (const_int 0)])
4252 (match_operand:QI 3 "arith10_operand" "rM,0")
4253 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4254 "TARGET_ARCH64"
4255 "@
4256 movr%D1\\t%2, %r3, %0
4257 movr%d1\\t%2, %r4, %0"
4258 [(set_attr "type" "cmove")])
4259
4260 (define_insn "*movhi_cc_reg_sp64"
4261 [(set (match_operand:HI 0 "register_operand" "=r,r")
4262 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4263 [(match_operand:DI 2 "register_operand" "r,r")
4264 (const_int 0)])
4265 (match_operand:HI 3 "arith10_operand" "rM,0")
4266 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4267 "TARGET_ARCH64"
4268 "@
4269 movr%D1\\t%2, %r3, %0
4270 movr%d1\\t%2, %r4, %0"
4271 [(set_attr "type" "cmove")])
4272
4273 (define_insn "*movsi_cc_reg_sp64"
4274 [(set (match_operand:SI 0 "register_operand" "=r,r")
4275 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4276 [(match_operand:DI 2 "register_operand" "r,r")
4277 (const_int 0)])
4278 (match_operand:SI 3 "arith10_operand" "rM,0")
4279 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4280 "TARGET_ARCH64"
4281 "@
4282 movr%D1\\t%2, %r3, %0
4283 movr%d1\\t%2, %r4, %0"
4284 [(set_attr "type" "cmove")])
4285
4286 ;; ??? The constraints of operands 3,4 need work.
4287 (define_insn "*movdi_cc_reg_sp64"
4288 [(set (match_operand:DI 0 "register_operand" "=r,r")
4289 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4290 [(match_operand:DI 2 "register_operand" "r,r")
4291 (const_int 0)])
4292 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4293 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4294 "TARGET_ARCH64"
4295 "@
4296 movr%D1\\t%2, %r3, %0
4297 movr%d1\\t%2, %r4, %0"
4298 [(set_attr "type" "cmove")])
4299
4300 (define_insn "*movdi_cc_reg_sp64_trunc"
4301 [(set (match_operand:SI 0 "register_operand" "=r,r")
4302 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4303 [(match_operand:DI 2 "register_operand" "r,r")
4304 (const_int 0)])
4305 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4306 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4307 "TARGET_ARCH64"
4308 "@
4309 movr%D1\\t%2, %r3, %0
4310 movr%d1\\t%2, %r4, %0"
4311 [(set_attr "type" "cmove")])
4312
4313 (define_insn "*movsf_cc_reg_sp64"
4314 [(set (match_operand:SF 0 "register_operand" "=f,f")
4315 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4316 [(match_operand:DI 2 "register_operand" "r,r")
4317 (const_int 0)])
4318 (match_operand:SF 3 "register_operand" "f,0")
4319 (match_operand:SF 4 "register_operand" "0,f")))]
4320 "TARGET_ARCH64 && TARGET_FPU"
4321 "@
4322 fmovrs%D1\\t%2, %3, %0
4323 fmovrs%d1\\t%2, %4, %0"
4324 [(set_attr "type" "fpcmove")])
4325
4326 (define_insn "movdf_cc_reg_sp64"
4327 [(set (match_operand:DF 0 "register_operand" "=e,e")
4328 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4329 [(match_operand:DI 2 "register_operand" "r,r")
4330 (const_int 0)])
4331 (match_operand:DF 3 "register_operand" "e,0")
4332 (match_operand:DF 4 "register_operand" "0,e")))]
4333 "TARGET_ARCH64 && TARGET_FPU"
4334 "@
4335 fmovrd%D1\\t%2, %3, %0
4336 fmovrd%d1\\t%2, %4, %0"
4337 [(set_attr "type" "fpcmove")
4338 (set_attr "fptype" "double")])
4339
4340 (define_insn "*movtf_cc_reg_hq_sp64"
4341 [(set (match_operand:TF 0 "register_operand" "=e,e")
4342 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4343 [(match_operand:DI 2 "register_operand" "r,r")
4344 (const_int 0)])
4345 (match_operand:TF 3 "register_operand" "e,0")
4346 (match_operand:TF 4 "register_operand" "0,e")))]
4347 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4348 "@
4349 fmovrq%D1\\t%2, %3, %0
4350 fmovrq%d1\\t%2, %4, %0"
4351 [(set_attr "type" "fpcmove")])
4352
4353 (define_insn "*movtf_cc_reg_sp64"
4354 [(set (match_operand:TF 0 "register_operand" "=e,e")
4355 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4356 [(match_operand:DI 2 "register_operand" "r,r")
4357 (const_int 0)])
4358 (match_operand:TF 3 "register_operand" "e,0")
4359 (match_operand:TF 4 "register_operand" "0,e")))]
4360 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4361 "#"
4362 [(set_attr "length" "2")])
4363
4364 (define_split
4365 [(set (match_operand:TF 0 "register_operand" "")
4366 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4367 [(match_operand:DI 2 "register_operand" "")
4368 (const_int 0)])
4369 (match_operand:TF 3 "register_operand" "")
4370 (match_operand:TF 4 "register_operand" "")))]
4371 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4372 [(clobber (const_int 0))]
4373 "
4374 {
4375 rtx set_dest = operands[0];
4376 rtx set_srca = operands[3];
4377 rtx set_srcb = operands[4];
4378 int third = rtx_equal_p (set_dest, set_srca);
4379 rtx dest1, dest2;
4380 rtx srca1, srca2, srcb1, srcb2;
4381
4382 if (GET_CODE (set_dest) == SUBREG)
4383 set_dest = alter_subreg (set_dest);
4384 if (GET_CODE (set_srca) == SUBREG)
4385 set_srca = alter_subreg (set_srca);
4386 if (GET_CODE (set_srcb) == SUBREG)
4387 set_srcb = alter_subreg (set_srcb);
4388
4389 dest1 = gen_df_reg (set_dest, 0);
4390 dest2 = gen_df_reg (set_dest, 1);
4391 srca1 = gen_df_reg (set_srca, 0);
4392 srca2 = gen_df_reg (set_srca, 1);
4393 srcb1 = gen_df_reg (set_srcb, 0);
4394 srcb2 = gen_df_reg (set_srcb, 1);
4395
4396 /* Now emit using the real source and destination we found, swapping
4397 the order if we detect overlap. */
4398 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4399 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4400 {
4401 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4402 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4403 }
4404 else
4405 {
4406 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4407 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4408 }
4409 DONE;
4410 }")
4411
4412 \f
4413 ;;- zero extension instructions
4414
4415 ;; These patterns originally accepted general_operands, however, slightly
4416 ;; better code is generated by only accepting register_operands, and then
4417 ;; letting combine generate the ldu[hb] insns.
4418
4419 (define_expand "zero_extendhisi2"
4420 [(set (match_operand:SI 0 "register_operand" "")
4421 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4422 ""
4423 "
4424 {
4425 rtx temp = gen_reg_rtx (SImode);
4426 rtx shift_16 = GEN_INT (16);
4427 int op1_subbyte = 0;
4428
4429 if (GET_CODE (operand1) == SUBREG)
4430 {
4431 op1_subbyte = SUBREG_BYTE (operand1);
4432 op1_subbyte /= GET_MODE_SIZE (SImode);
4433 op1_subbyte *= GET_MODE_SIZE (SImode);
4434 operand1 = XEXP (operand1, 0);
4435 }
4436
4437 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4438 shift_16));
4439 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4440 DONE;
4441 }")
4442
4443 (define_insn "*zero_extendhisi2_insn"
4444 [(set (match_operand:SI 0 "register_operand" "=r")
4445 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4446 ""
4447 "lduh\\t%1, %0"
4448 [(set_attr "type" "load")])
4449
4450 (define_expand "zero_extendqihi2"
4451 [(set (match_operand:HI 0 "register_operand" "")
4452 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4453 ""
4454 "")
4455
4456 (define_insn "*zero_extendqihi2_insn"
4457 [(set (match_operand:HI 0 "register_operand" "=r,r")
4458 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4459 "GET_CODE (operands[1]) != CONST_INT"
4460 "@
4461 and\\t%1, 0xff, %0
4462 ldub\\t%1, %0"
4463 [(set_attr "type" "*,load")])
4464
4465 (define_expand "zero_extendqisi2"
4466 [(set (match_operand:SI 0 "register_operand" "")
4467 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4468 ""
4469 "")
4470
4471 (define_insn "*zero_extendqisi2_insn"
4472 [(set (match_operand:SI 0 "register_operand" "=r,r")
4473 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4474 "GET_CODE (operands[1]) != CONST_INT"
4475 "@
4476 and\\t%1, 0xff, %0
4477 ldub\\t%1, %0"
4478 [(set_attr "type" "*,load")])
4479
4480 (define_expand "zero_extendqidi2"
4481 [(set (match_operand:DI 0 "register_operand" "")
4482 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4483 "TARGET_ARCH64"
4484 "")
4485
4486 (define_insn "*zero_extendqidi2_insn"
4487 [(set (match_operand:DI 0 "register_operand" "=r,r")
4488 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4489 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4490 "@
4491 and\\t%1, 0xff, %0
4492 ldub\\t%1, %0"
4493 [(set_attr "type" "*,load")])
4494
4495 (define_expand "zero_extendhidi2"
4496 [(set (match_operand:DI 0 "register_operand" "")
4497 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4498 "TARGET_ARCH64"
4499 "
4500 {
4501 rtx temp = gen_reg_rtx (DImode);
4502 rtx shift_48 = GEN_INT (48);
4503 int op1_subbyte = 0;
4504
4505 if (GET_CODE (operand1) == SUBREG)
4506 {
4507 op1_subbyte = SUBREG_BYTE (operand1);
4508 op1_subbyte /= GET_MODE_SIZE (DImode);
4509 op1_subbyte *= GET_MODE_SIZE (DImode);
4510 operand1 = XEXP (operand1, 0);
4511 }
4512
4513 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4514 shift_48));
4515 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4516 DONE;
4517 }")
4518
4519 (define_insn "*zero_extendhidi2_insn"
4520 [(set (match_operand:DI 0 "register_operand" "=r")
4521 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4522 "TARGET_ARCH64"
4523 "lduh\\t%1, %0"
4524 [(set_attr "type" "load")])
4525
4526
4527 ;; ??? Write truncdisi pattern using sra?
4528
4529 (define_expand "zero_extendsidi2"
4530 [(set (match_operand:DI 0 "register_operand" "")
4531 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4532 ""
4533 "")
4534
4535 (define_insn "*zero_extendsidi2_insn_sp64"
4536 [(set (match_operand:DI 0 "register_operand" "=r,r")
4537 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4538 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4539 "@
4540 srl\\t%1, 0, %0
4541 lduw\\t%1, %0"
4542 [(set_attr "type" "shift,load")])
4543
4544 (define_insn "*zero_extendsidi2_insn_sp32"
4545 [(set (match_operand:DI 0 "register_operand" "=r")
4546 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4547 "! TARGET_ARCH64"
4548 "#"
4549 [(set_attr "length" "2")])
4550
4551 (define_split
4552 [(set (match_operand:DI 0 "register_operand" "")
4553 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4554 "! TARGET_ARCH64 && reload_completed"
4555 [(set (match_dup 2) (match_dup 3))
4556 (set (match_dup 4) (match_dup 5))]
4557 "
4558 {
4559 rtx dest1, dest2;
4560
4561 if (GET_CODE (operands[0]) == SUBREG)
4562 operands[0] = alter_subreg (operands[0]);
4563
4564 dest1 = gen_highpart (SImode, operands[0]);
4565 dest2 = gen_lowpart (SImode, operands[0]);
4566
4567 /* Swap the order in case of overlap. */
4568 if (REGNO (dest1) == REGNO (operands[1]))
4569 {
4570 operands[2] = dest2;
4571 operands[3] = operands[1];
4572 operands[4] = dest1;
4573 operands[5] = const0_rtx;
4574 }
4575 else
4576 {
4577 operands[2] = dest1;
4578 operands[3] = const0_rtx;
4579 operands[4] = dest2;
4580 operands[5] = operands[1];
4581 }
4582 }")
4583
4584 ;; Simplify comparisons of extended values.
4585
4586 (define_insn "*cmp_zero_extendqisi2"
4587 [(set (reg:CC 100)
4588 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4589 (const_int 0)))]
4590 ""
4591 "andcc\\t%0, 0xff, %%g0"
4592 [(set_attr "type" "compare")])
4593
4594 (define_insn "*cmp_zero_qi"
4595 [(set (reg:CC 100)
4596 (compare:CC (match_operand:QI 0 "register_operand" "r")
4597 (const_int 0)))]
4598 ""
4599 "andcc\\t%0, 0xff, %%g0"
4600 [(set_attr "type" "compare")])
4601
4602 (define_insn "*cmp_zero_extendqisi2_set"
4603 [(set (reg:CC 100)
4604 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4605 (const_int 0)))
4606 (set (match_operand:SI 0 "register_operand" "=r")
4607 (zero_extend:SI (match_dup 1)))]
4608 ""
4609 "andcc\\t%1, 0xff, %0"
4610 [(set_attr "type" "compare")])
4611
4612 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4613 [(set (reg:CC 100)
4614 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4615 (const_int 255))
4616 (const_int 0)))
4617 (set (match_operand:SI 0 "register_operand" "=r")
4618 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4619 ""
4620 "andcc\\t%1, 0xff, %0"
4621 [(set_attr "type" "compare")])
4622
4623 (define_insn "*cmp_zero_extendqidi2"
4624 [(set (reg:CCX 100)
4625 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4626 (const_int 0)))]
4627 "TARGET_ARCH64"
4628 "andcc\\t%0, 0xff, %%g0"
4629 [(set_attr "type" "compare")])
4630
4631 (define_insn "*cmp_zero_qi_sp64"
4632 [(set (reg:CCX 100)
4633 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4634 (const_int 0)))]
4635 "TARGET_ARCH64"
4636 "andcc\\t%0, 0xff, %%g0"
4637 [(set_attr "type" "compare")])
4638
4639 (define_insn "*cmp_zero_extendqidi2_set"
4640 [(set (reg:CCX 100)
4641 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4642 (const_int 0)))
4643 (set (match_operand:DI 0 "register_operand" "=r")
4644 (zero_extend:DI (match_dup 1)))]
4645 "TARGET_ARCH64"
4646 "andcc\\t%1, 0xff, %0"
4647 [(set_attr "type" "compare")])
4648
4649 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4650 [(set (reg:CCX 100)
4651 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4652 (const_int 255))
4653 (const_int 0)))
4654 (set (match_operand:DI 0 "register_operand" "=r")
4655 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4656 "TARGET_ARCH64"
4657 "andcc\\t%1, 0xff, %0"
4658 [(set_attr "type" "compare")])
4659
4660 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4661
4662 (define_insn "*cmp_siqi_trunc"
4663 [(set (reg:CC 100)
4664 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4665 (const_int 0)))]
4666 ""
4667 "andcc\\t%0, 0xff, %%g0"
4668 [(set_attr "type" "compare")])
4669
4670 (define_insn "*cmp_siqi_trunc_set"
4671 [(set (reg:CC 100)
4672 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4673 (const_int 0)))
4674 (set (match_operand:QI 0 "register_operand" "=r")
4675 (subreg:QI (match_dup 1) 3))]
4676 ""
4677 "andcc\\t%1, 0xff, %0"
4678 [(set_attr "type" "compare")])
4679
4680 (define_insn "*cmp_diqi_trunc"
4681 [(set (reg:CC 100)
4682 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4683 (const_int 0)))]
4684 "TARGET_ARCH64"
4685 "andcc\\t%0, 0xff, %%g0"
4686 [(set_attr "type" "compare")])
4687
4688 (define_insn "*cmp_diqi_trunc_set"
4689 [(set (reg:CC 100)
4690 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4691 (const_int 0)))
4692 (set (match_operand:QI 0 "register_operand" "=r")
4693 (subreg:QI (match_dup 1) 7))]
4694 "TARGET_ARCH64"
4695 "andcc\\t%1, 0xff, %0"
4696 [(set_attr "type" "compare")])
4697 \f
4698 ;;- sign extension instructions
4699
4700 ;; These patterns originally accepted general_operands, however, slightly
4701 ;; better code is generated by only accepting register_operands, and then
4702 ;; letting combine generate the lds[hb] insns.
4703
4704 (define_expand "extendhisi2"
4705 [(set (match_operand:SI 0 "register_operand" "")
4706 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4707 ""
4708 "
4709 {
4710 rtx temp = gen_reg_rtx (SImode);
4711 rtx shift_16 = GEN_INT (16);
4712 int op1_subbyte = 0;
4713
4714 if (GET_CODE (operand1) == SUBREG)
4715 {
4716 op1_subbyte = SUBREG_BYTE (operand1);
4717 op1_subbyte /= GET_MODE_SIZE (SImode);
4718 op1_subbyte *= GET_MODE_SIZE (SImode);
4719 operand1 = XEXP (operand1, 0);
4720 }
4721
4722 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4723 shift_16));
4724 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4725 DONE;
4726 }")
4727
4728 (define_insn "*sign_extendhisi2_insn"
4729 [(set (match_operand:SI 0 "register_operand" "=r")
4730 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4731 ""
4732 "ldsh\\t%1, %0"
4733 [(set_attr "type" "sload")])
4734
4735 (define_expand "extendqihi2"
4736 [(set (match_operand:HI 0 "register_operand" "")
4737 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4738 ""
4739 "
4740 {
4741 rtx temp = gen_reg_rtx (SImode);
4742 rtx shift_24 = GEN_INT (24);
4743 int op1_subbyte = 0;
4744 int op0_subbyte = 0;
4745
4746 if (GET_CODE (operand1) == SUBREG)
4747 {
4748 op1_subbyte = SUBREG_BYTE (operand1);
4749 op1_subbyte /= GET_MODE_SIZE (SImode);
4750 op1_subbyte *= GET_MODE_SIZE (SImode);
4751 operand1 = XEXP (operand1, 0);
4752 }
4753 if (GET_CODE (operand0) == SUBREG)
4754 {
4755 op0_subbyte = SUBREG_BYTE (operand0);
4756 op0_subbyte /= GET_MODE_SIZE (SImode);
4757 op0_subbyte *= GET_MODE_SIZE (SImode);
4758 operand0 = XEXP (operand0, 0);
4759 }
4760 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4761 shift_24));
4762 if (GET_MODE (operand0) != SImode)
4763 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4764 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4765 DONE;
4766 }")
4767
4768 (define_insn "*sign_extendqihi2_insn"
4769 [(set (match_operand:HI 0 "register_operand" "=r")
4770 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4771 ""
4772 "ldsb\\t%1, %0"
4773 [(set_attr "type" "sload")])
4774
4775 (define_expand "extendqisi2"
4776 [(set (match_operand:SI 0 "register_operand" "")
4777 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4778 ""
4779 "
4780 {
4781 rtx temp = gen_reg_rtx (SImode);
4782 rtx shift_24 = GEN_INT (24);
4783 int op1_subbyte = 0;
4784
4785 if (GET_CODE (operand1) == SUBREG)
4786 {
4787 op1_subbyte = SUBREG_BYTE (operand1);
4788 op1_subbyte /= GET_MODE_SIZE (SImode);
4789 op1_subbyte *= GET_MODE_SIZE (SImode);
4790 operand1 = XEXP (operand1, 0);
4791 }
4792
4793 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4794 shift_24));
4795 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4796 DONE;
4797 }")
4798
4799 (define_insn "*sign_extendqisi2_insn"
4800 [(set (match_operand:SI 0 "register_operand" "=r")
4801 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4802 ""
4803 "ldsb\\t%1, %0"
4804 [(set_attr "type" "sload")])
4805
4806 (define_expand "extendqidi2"
4807 [(set (match_operand:DI 0 "register_operand" "")
4808 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4809 "TARGET_ARCH64"
4810 "
4811 {
4812 rtx temp = gen_reg_rtx (DImode);
4813 rtx shift_56 = GEN_INT (56);
4814 int op1_subbyte = 0;
4815
4816 if (GET_CODE (operand1) == SUBREG)
4817 {
4818 op1_subbyte = SUBREG_BYTE (operand1);
4819 op1_subbyte /= GET_MODE_SIZE (DImode);
4820 op1_subbyte *= GET_MODE_SIZE (DImode);
4821 operand1 = XEXP (operand1, 0);
4822 }
4823
4824 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4825 shift_56));
4826 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4827 DONE;
4828 }")
4829
4830 (define_insn "*sign_extendqidi2_insn"
4831 [(set (match_operand:DI 0 "register_operand" "=r")
4832 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4833 "TARGET_ARCH64"
4834 "ldsb\\t%1, %0"
4835 [(set_attr "type" "sload")])
4836
4837 (define_expand "extendhidi2"
4838 [(set (match_operand:DI 0 "register_operand" "")
4839 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4840 "TARGET_ARCH64"
4841 "
4842 {
4843 rtx temp = gen_reg_rtx (DImode);
4844 rtx shift_48 = GEN_INT (48);
4845 int op1_subbyte = 0;
4846
4847 if (GET_CODE (operand1) == SUBREG)
4848 {
4849 op1_subbyte = SUBREG_BYTE (operand1);
4850 op1_subbyte /= GET_MODE_SIZE (DImode);
4851 op1_subbyte *= GET_MODE_SIZE (DImode);
4852 operand1 = XEXP (operand1, 0);
4853 }
4854
4855 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4856 shift_48));
4857 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4858 DONE;
4859 }")
4860
4861 (define_insn "*sign_extendhidi2_insn"
4862 [(set (match_operand:DI 0 "register_operand" "=r")
4863 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4864 "TARGET_ARCH64"
4865 "ldsh\\t%1, %0"
4866 [(set_attr "type" "sload")])
4867
4868 (define_expand "extendsidi2"
4869 [(set (match_operand:DI 0 "register_operand" "")
4870 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4871 "TARGET_ARCH64"
4872 "")
4873
4874 (define_insn "*sign_extendsidi2_insn"
4875 [(set (match_operand:DI 0 "register_operand" "=r,r")
4876 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4877 "TARGET_ARCH64"
4878 "@
4879 sra\\t%1, 0, %0
4880 ldsw\\t%1, %0"
4881 [(set_attr "type" "shift,sload")])
4882 \f
4883 ;; Special pattern for optimizing bit-field compares. This is needed
4884 ;; because combine uses this as a canonical form.
4885
4886 (define_insn "*cmp_zero_extract"
4887 [(set (reg:CC 100)
4888 (compare:CC
4889 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4890 (match_operand:SI 1 "small_int_or_double" "n")
4891 (match_operand:SI 2 "small_int_or_double" "n"))
4892 (const_int 0)))]
4893 "(GET_CODE (operands[2]) == CONST_INT
4894 && INTVAL (operands[2]) > 19)
4895 || (GET_CODE (operands[2]) == CONST_DOUBLE
4896 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4897 "*
4898 {
4899 int len = (GET_CODE (operands[1]) == CONST_INT
4900 ? INTVAL (operands[1])
4901 : CONST_DOUBLE_LOW (operands[1]));
4902 int pos = 32 -
4903 (GET_CODE (operands[2]) == CONST_INT
4904 ? INTVAL (operands[2])
4905 : CONST_DOUBLE_LOW (operands[2])) - len;
4906 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4907
4908 operands[1] = GEN_INT (mask);
4909 return \"andcc\\t%0, %1, %%g0\";
4910 }"
4911 [(set_attr "type" "compare")])
4912
4913 (define_insn "*cmp_zero_extract_sp64"
4914 [(set (reg:CCX 100)
4915 (compare:CCX
4916 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4917 (match_operand:SI 1 "small_int_or_double" "n")
4918 (match_operand:SI 2 "small_int_or_double" "n"))
4919 (const_int 0)))]
4920 "TARGET_ARCH64
4921 && ((GET_CODE (operands[2]) == CONST_INT
4922 && INTVAL (operands[2]) > 51)
4923 || (GET_CODE (operands[2]) == CONST_DOUBLE
4924 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4925 "*
4926 {
4927 int len = (GET_CODE (operands[1]) == CONST_INT
4928 ? INTVAL (operands[1])
4929 : CONST_DOUBLE_LOW (operands[1]));
4930 int pos = 64 -
4931 (GET_CODE (operands[2]) == CONST_INT
4932 ? INTVAL (operands[2])
4933 : CONST_DOUBLE_LOW (operands[2])) - len;
4934 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4935
4936 operands[1] = GEN_INT (mask);
4937 return \"andcc\\t%0, %1, %%g0\";
4938 }"
4939 [(set_attr "type" "compare")])
4940 \f
4941 ;; Conversions between float, double and long double.
4942
4943 (define_insn "extendsfdf2"
4944 [(set (match_operand:DF 0 "register_operand" "=e")
4945 (float_extend:DF
4946 (match_operand:SF 1 "register_operand" "f")))]
4947 "TARGET_FPU"
4948 "fstod\\t%1, %0"
4949 [(set_attr "type" "fp")
4950 (set_attr "fptype" "double")])
4951
4952 (define_expand "extendsftf2"
4953 [(set (match_operand:TF 0 "register_operand" "=e")
4954 (float_extend:TF
4955 (match_operand:SF 1 "register_operand" "f")))]
4956 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4957 "
4958 {
4959 if (! TARGET_HARD_QUAD)
4960 {
4961 rtx slot0;
4962
4963 if (GET_CODE (operands[0]) != MEM)
4964 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4965 else
4966 slot0 = operands[0];
4967
4968 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4969 VOIDmode, 2,
4970 XEXP (slot0, 0), Pmode,
4971 operands[1], SFmode);
4972
4973 if (GET_CODE (operands[0]) != MEM)
4974 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4975 DONE;
4976 }
4977 }")
4978
4979 (define_insn "*extendsftf2_hq"
4980 [(set (match_operand:TF 0 "register_operand" "=e")
4981 (float_extend:TF
4982 (match_operand:SF 1 "register_operand" "f")))]
4983 "TARGET_FPU && TARGET_HARD_QUAD"
4984 "fstoq\\t%1, %0"
4985 [(set_attr "type" "fp")])
4986
4987 (define_expand "extenddftf2"
4988 [(set (match_operand:TF 0 "register_operand" "=e")
4989 (float_extend:TF
4990 (match_operand:DF 1 "register_operand" "e")))]
4991 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4992 "
4993 {
4994 if (! TARGET_HARD_QUAD)
4995 {
4996 rtx slot0;
4997
4998 if (GET_CODE (operands[0]) != MEM)
4999 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5000 else
5001 slot0 = operands[0];
5002
5003 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5004 VOIDmode, 2,
5005 XEXP (slot0, 0), Pmode,
5006 operands[1], DFmode);
5007
5008 if (GET_CODE (operands[0]) != MEM)
5009 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5010 DONE;
5011 }
5012 }")
5013
5014 (define_insn "*extenddftf2_hq"
5015 [(set (match_operand:TF 0 "register_operand" "=e")
5016 (float_extend:TF
5017 (match_operand:DF 1 "register_operand" "e")))]
5018 "TARGET_FPU && TARGET_HARD_QUAD"
5019 "fdtoq\\t%1, %0"
5020 [(set_attr "type" "fp")])
5021
5022 (define_insn "truncdfsf2"
5023 [(set (match_operand:SF 0 "register_operand" "=f")
5024 (float_truncate:SF
5025 (match_operand:DF 1 "register_operand" "e")))]
5026 "TARGET_FPU"
5027 "fdtos\\t%1, %0"
5028 [(set_attr "type" "fp")
5029 (set_attr "fptype" "double")])
5030
5031 (define_expand "trunctfsf2"
5032 [(set (match_operand:SF 0 "register_operand" "=f")
5033 (float_truncate:SF
5034 (match_operand:TF 1 "register_operand" "e")))]
5035 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5036 "
5037 {
5038 if (! TARGET_HARD_QUAD)
5039 {
5040 rtx slot0;
5041
5042 if (GET_CODE (operands[1]) != MEM)
5043 {
5044 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5045 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5046 }
5047 else
5048 slot0 = operands[1];
5049
5050 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5051 operands[0], 0, SFmode, 1,
5052 XEXP (slot0, 0), Pmode);
5053 DONE;
5054 }
5055 }")
5056
5057 (define_insn "*trunctfsf2_hq"
5058 [(set (match_operand:SF 0 "register_operand" "=f")
5059 (float_truncate:SF
5060 (match_operand:TF 1 "register_operand" "e")))]
5061 "TARGET_FPU && TARGET_HARD_QUAD"
5062 "fqtos\\t%1, %0"
5063 [(set_attr "type" "fp")])
5064
5065 (define_expand "trunctfdf2"
5066 [(set (match_operand:DF 0 "register_operand" "=f")
5067 (float_truncate:DF
5068 (match_operand:TF 1 "register_operand" "e")))]
5069 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5070 "
5071 {
5072 if (! TARGET_HARD_QUAD)
5073 {
5074 rtx slot0;
5075
5076 if (GET_CODE (operands[1]) != MEM)
5077 {
5078 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5079 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5080 }
5081 else
5082 slot0 = operands[1];
5083
5084 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5085 operands[0], 0, DFmode, 1,
5086 XEXP (slot0, 0), Pmode);
5087 DONE;
5088 }
5089 }")
5090
5091 (define_insn "*trunctfdf2_hq"
5092 [(set (match_operand:DF 0 "register_operand" "=e")
5093 (float_truncate:DF
5094 (match_operand:TF 1 "register_operand" "e")))]
5095 "TARGET_FPU && TARGET_HARD_QUAD"
5096 "fqtod\\t%1, %0"
5097 [(set_attr "type" "fp")])
5098 \f
5099 ;; Conversion between fixed point and floating point.
5100
5101 (define_insn "floatsisf2"
5102 [(set (match_operand:SF 0 "register_operand" "=f")
5103 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5104 "TARGET_FPU"
5105 "fitos\\t%1, %0"
5106 [(set_attr "type" "fp")
5107 (set_attr "fptype" "double")])
5108
5109 (define_insn "floatsidf2"
5110 [(set (match_operand:DF 0 "register_operand" "=e")
5111 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5112 "TARGET_FPU"
5113 "fitod\\t%1, %0"
5114 [(set_attr "type" "fp")
5115 (set_attr "fptype" "double")])
5116
5117 (define_expand "floatsitf2"
5118 [(set (match_operand:TF 0 "register_operand" "=e")
5119 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5120 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5121 "
5122 {
5123 if (! TARGET_HARD_QUAD)
5124 {
5125 rtx slot0;
5126
5127 if (GET_CODE (operands[1]) != MEM)
5128 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5129 else
5130 slot0 = operands[1];
5131
5132 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5133 VOIDmode, 2,
5134 XEXP (slot0, 0), Pmode,
5135 operands[1], SImode);
5136
5137 if (GET_CODE (operands[0]) != MEM)
5138 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5139 DONE;
5140 }
5141 }")
5142
5143 (define_insn "*floatsitf2_hq"
5144 [(set (match_operand:TF 0 "register_operand" "=e")
5145 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5146 "TARGET_FPU && TARGET_HARD_QUAD"
5147 "fitoq\\t%1, %0"
5148 [(set_attr "type" "fp")])
5149
5150 (define_expand "floatunssitf2"
5151 [(set (match_operand:TF 0 "register_operand" "=e")
5152 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5153 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5154 "
5155 {
5156 rtx slot0;
5157
5158 if (GET_CODE (operands[1]) != MEM)
5159 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5160 else
5161 slot0 = operands[1];
5162
5163 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5164 VOIDmode, 2,
5165 XEXP (slot0, 0), Pmode,
5166 operands[1], SImode);
5167
5168 if (GET_CODE (operands[0]) != MEM)
5169 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5170 DONE;
5171 }")
5172
5173 ;; Now the same for 64 bit sources.
5174
5175 (define_insn "floatdisf2"
5176 [(set (match_operand:SF 0 "register_operand" "=f")
5177 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5178 "TARGET_V9 && TARGET_FPU"
5179 "fxtos\\t%1, %0"
5180 [(set_attr "type" "fp")
5181 (set_attr "fptype" "double")])
5182
5183 (define_insn "floatdidf2"
5184 [(set (match_operand:DF 0 "register_operand" "=e")
5185 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5186 "TARGET_V9 && TARGET_FPU"
5187 "fxtod\\t%1, %0"
5188 [(set_attr "type" "fp")
5189 (set_attr "fptype" "double")])
5190
5191 (define_expand "floatditf2"
5192 [(set (match_operand:TF 0 "register_operand" "=e")
5193 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5194 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5195 "
5196 {
5197 if (! TARGET_HARD_QUAD)
5198 {
5199 rtx slot0;
5200
5201 if (GET_CODE (operands[1]) != MEM)
5202 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5203 else
5204 slot0 = operands[1];
5205
5206 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5207 VOIDmode, 2,
5208 XEXP (slot0, 0), Pmode,
5209 operands[1], DImode);
5210
5211 if (GET_CODE (operands[0]) != MEM)
5212 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5213 DONE;
5214 }
5215 }")
5216
5217 (define_insn "*floatditf2_hq"
5218 [(set (match_operand:TF 0 "register_operand" "=e")
5219 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5220 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5221 "fxtoq\\t%1, %0"
5222 [(set_attr "type" "fp")])
5223
5224 (define_expand "floatunsditf2"
5225 [(set (match_operand:TF 0 "register_operand" "=e")
5226 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5227 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5228 "
5229 {
5230 rtx slot0;
5231
5232 if (GET_CODE (operands[1]) != MEM)
5233 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5234 else
5235 slot0 = operands[1];
5236
5237 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5238 VOIDmode, 2,
5239 XEXP (slot0, 0), Pmode,
5240 operands[1], DImode);
5241
5242 if (GET_CODE (operands[0]) != MEM)
5243 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5244 DONE;
5245 }")
5246
5247 ;; Convert a float to an actual integer.
5248 ;; Truncation is performed as part of the conversion.
5249
5250 (define_insn "fix_truncsfsi2"
5251 [(set (match_operand:SI 0 "register_operand" "=f")
5252 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5253 "TARGET_FPU"
5254 "fstoi\\t%1, %0"
5255 [(set_attr "type" "fp")
5256 (set_attr "fptype" "double")])
5257
5258 (define_insn "fix_truncdfsi2"
5259 [(set (match_operand:SI 0 "register_operand" "=f")
5260 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5261 "TARGET_FPU"
5262 "fdtoi\\t%1, %0"
5263 [(set_attr "type" "fp")
5264 (set_attr "fptype" "double")])
5265
5266 (define_expand "fix_trunctfsi2"
5267 [(set (match_operand:SI 0 "register_operand" "=f")
5268 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5269 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5270 "
5271 {
5272 if (! TARGET_HARD_QUAD)
5273 {
5274 rtx slot0;
5275
5276 if (GET_CODE (operands[1]) != MEM)
5277 {
5278 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5279 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5280 }
5281 else
5282 slot0 = operands[1];
5283
5284 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5285 operands[0], 0, SImode, 1,
5286 XEXP (slot0, 0), Pmode);
5287 DONE;
5288 }
5289 }")
5290
5291 (define_insn "*fix_trunctfsi2_hq"
5292 [(set (match_operand:SI 0 "register_operand" "=f")
5293 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5294 "TARGET_FPU && TARGET_HARD_QUAD"
5295 "fqtoi\\t%1, %0"
5296 [(set_attr "type" "fp")])
5297
5298 (define_expand "fixuns_trunctfsi2"
5299 [(set (match_operand:SI 0 "register_operand" "=f")
5300 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5301 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5302 "
5303 {
5304 rtx slot0;
5305
5306 if (GET_CODE (operands[1]) != MEM)
5307 {
5308 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5309 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5310 }
5311 else
5312 slot0 = operands[1];
5313
5314 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5315 operands[0], 0, SImode, 1,
5316 XEXP (slot0, 0), Pmode);
5317 DONE;
5318 }")
5319
5320 ;; Now the same, for V9 targets
5321
5322 (define_insn "fix_truncsfdi2"
5323 [(set (match_operand:DI 0 "register_operand" "=e")
5324 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5325 "TARGET_V9 && TARGET_FPU"
5326 "fstox\\t%1, %0"
5327 [(set_attr "type" "fp")
5328 (set_attr "fptype" "double")])
5329
5330 (define_insn "fix_truncdfdi2"
5331 [(set (match_operand:DI 0 "register_operand" "=e")
5332 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5333 "TARGET_V9 && TARGET_FPU"
5334 "fdtox\\t%1, %0"
5335 [(set_attr "type" "fp")
5336 (set_attr "fptype" "double")])
5337
5338 (define_expand "fix_trunctfdi2"
5339 [(set (match_operand:DI 0 "register_operand" "=e")
5340 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5341 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5342 "
5343 {
5344 if (! TARGET_HARD_QUAD)
5345 {
5346 rtx slot0;
5347
5348 if (GET_CODE (operands[1]) != MEM)
5349 {
5350 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5351 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5352 }
5353 else
5354 slot0 = operands[1];
5355
5356 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5357 operands[0], 0, DImode, 1,
5358 XEXP (slot0, 0), Pmode);
5359 DONE;
5360 }
5361 }")
5362
5363 (define_insn "*fix_trunctfdi2_hq"
5364 [(set (match_operand:DI 0 "register_operand" "=e")
5365 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5366 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5367 "fqtox\\t%1, %0"
5368 [(set_attr "type" "fp")])
5369
5370 (define_expand "fixuns_trunctfdi2"
5371 [(set (match_operand:DI 0 "register_operand" "=f")
5372 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5373 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5374 "
5375 {
5376 rtx slot0;
5377
5378 if (GET_CODE (operands[1]) != MEM)
5379 {
5380 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5381 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5382 }
5383 else
5384 slot0 = operands[1];
5385
5386 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5387 operands[0], 0, DImode, 1,
5388 XEXP (slot0, 0), Pmode);
5389 DONE;
5390 }")
5391
5392 \f
5393 ;;- arithmetic instructions
5394
5395 (define_expand "adddi3"
5396 [(set (match_operand:DI 0 "register_operand" "=r")
5397 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5398 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5399 ""
5400 "
5401 {
5402 HOST_WIDE_INT i;
5403
5404 if (! TARGET_ARCH64)
5405 {
5406 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5407 gen_rtx_SET (VOIDmode, operands[0],
5408 gen_rtx_PLUS (DImode, operands[1],
5409 operands[2])),
5410 gen_rtx_CLOBBER (VOIDmode,
5411 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5412 DONE;
5413 }
5414 if (arith_double_4096_operand(operands[2], DImode))
5415 {
5416 switch (GET_CODE (operands[1]))
5417 {
5418 case CONST_INT: i = INTVAL (operands[1]); break;
5419 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5420 default:
5421 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5422 gen_rtx_MINUS (DImode, operands[1],
5423 GEN_INT(-4096))));
5424 DONE;
5425 }
5426 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5427 DONE;
5428 }
5429 }")
5430
5431 (define_insn "adddi3_insn_sp32"
5432 [(set (match_operand:DI 0 "register_operand" "=r")
5433 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5434 (match_operand:DI 2 "arith_double_operand" "rHI")))
5435 (clobber (reg:CC 100))]
5436 "! TARGET_ARCH64"
5437 "#"
5438 [(set_attr "length" "2")])
5439
5440 (define_split
5441 [(set (match_operand:DI 0 "register_operand" "")
5442 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5443 (match_operand:DI 2 "arith_double_operand" "")))
5444 (clobber (reg:CC 100))]
5445 "! TARGET_ARCH64 && reload_completed"
5446 [(parallel [(set (reg:CC_NOOV 100)
5447 (compare:CC_NOOV (plus:SI (match_dup 4)
5448 (match_dup 5))
5449 (const_int 0)))
5450 (set (match_dup 3)
5451 (plus:SI (match_dup 4) (match_dup 5)))])
5452 (set (match_dup 6)
5453 (plus:SI (plus:SI (match_dup 7)
5454 (match_dup 8))
5455 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5456 "
5457 {
5458 operands[3] = gen_lowpart (SImode, operands[0]);
5459 operands[4] = gen_lowpart (SImode, operands[1]);
5460 operands[5] = gen_lowpart (SImode, operands[2]);
5461 operands[6] = gen_highpart (SImode, operands[0]);
5462 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5463 #if HOST_BITS_PER_WIDE_INT == 32
5464 if (GET_CODE (operands[2]) == CONST_INT)
5465 {
5466 if (INTVAL (operands[2]) < 0)
5467 operands[8] = constm1_rtx;
5468 else
5469 operands[8] = const0_rtx;
5470 }
5471 else
5472 #endif
5473 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5474 }")
5475
5476 (define_split
5477 [(set (match_operand:DI 0 "register_operand" "")
5478 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5479 (match_operand:DI 2 "arith_double_operand" "")))
5480 (clobber (reg:CC 100))]
5481 "! TARGET_ARCH64 && reload_completed"
5482 [(parallel [(set (reg:CC_NOOV 100)
5483 (compare:CC_NOOV (minus:SI (match_dup 4)
5484 (match_dup 5))
5485 (const_int 0)))
5486 (set (match_dup 3)
5487 (minus:SI (match_dup 4) (match_dup 5)))])
5488 (set (match_dup 6)
5489 (minus:SI (minus:SI (match_dup 7)
5490 (match_dup 8))
5491 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5492 "
5493 {
5494 operands[3] = gen_lowpart (SImode, operands[0]);
5495 operands[4] = gen_lowpart (SImode, operands[1]);
5496 operands[5] = gen_lowpart (SImode, operands[2]);
5497 operands[6] = gen_highpart (SImode, operands[0]);
5498 operands[7] = gen_highpart (SImode, operands[1]);
5499 #if HOST_BITS_PER_WIDE_INT == 32
5500 if (GET_CODE (operands[2]) == CONST_INT)
5501 {
5502 if (INTVAL (operands[2]) < 0)
5503 operands[8] = constm1_rtx;
5504 else
5505 operands[8] = const0_rtx;
5506 }
5507 else
5508 #endif
5509 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5510 }")
5511
5512 ;; LTU here means "carry set"
5513 (define_insn "addx"
5514 [(set (match_operand:SI 0 "register_operand" "=r")
5515 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5516 (match_operand:SI 2 "arith_operand" "rI"))
5517 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5518 ""
5519 "addx\\t%1, %2, %0"
5520 [(set_attr "type" "misc")])
5521
5522 (define_insn "*addx_extend_sp32"
5523 [(set (match_operand:DI 0 "register_operand" "=r")
5524 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5525 (match_operand:SI 2 "arith_operand" "rI"))
5526 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5527 "! TARGET_ARCH64"
5528 "#"
5529 [(set_attr "length" "2")])
5530
5531 (define_split
5532 [(set (match_operand:DI 0 "register_operand" "")
5533 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5534 (match_operand:SI 2 "arith_operand" ""))
5535 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5536 "! TARGET_ARCH64 && reload_completed"
5537 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5538 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5539 (set (match_dup 4) (const_int 0))]
5540 "operands[3] = gen_lowpart (SImode, operands[0]);
5541 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5542
5543 (define_insn "*addx_extend_sp64"
5544 [(set (match_operand:DI 0 "register_operand" "=r")
5545 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5546 (match_operand:SI 2 "arith_operand" "rI"))
5547 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5548 "TARGET_ARCH64"
5549 "addx\\t%r1, %2, %0"
5550 [(set_attr "type" "misc")])
5551
5552 (define_insn "subx"
5553 [(set (match_operand:SI 0 "register_operand" "=r")
5554 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5555 (match_operand:SI 2 "arith_operand" "rI"))
5556 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5557 ""
5558 "subx\\t%r1, %2, %0"
5559 [(set_attr "type" "misc")])
5560
5561 (define_insn "*subx_extend_sp64"
5562 [(set (match_operand:DI 0 "register_operand" "=r")
5563 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5564 (match_operand:SI 2 "arith_operand" "rI"))
5565 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5566 "TARGET_ARCH64"
5567 "subx\\t%r1, %2, %0"
5568 [(set_attr "type" "misc")])
5569
5570 (define_insn "*subx_extend"
5571 [(set (match_operand:DI 0 "register_operand" "=r")
5572 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5573 (match_operand:SI 2 "arith_operand" "rI"))
5574 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5575 "! TARGET_ARCH64"
5576 "#"
5577 [(set_attr "length" "2")])
5578
5579 (define_split
5580 [(set (match_operand:DI 0 "register_operand" "")
5581 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5582 (match_operand:SI 2 "arith_operand" ""))
5583 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5584 "! TARGET_ARCH64 && reload_completed"
5585 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5586 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5587 (set (match_dup 4) (const_int 0))]
5588 "operands[3] = gen_lowpart (SImode, operands[0]);
5589 operands[4] = gen_highpart (SImode, operands[0]);")
5590
5591 (define_insn ""
5592 [(set (match_operand:DI 0 "register_operand" "=r")
5593 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5594 (match_operand:DI 2 "register_operand" "r")))
5595 (clobber (reg:CC 100))]
5596 "! TARGET_ARCH64"
5597 "#"
5598 [(set_attr "length" "2")])
5599
5600 (define_split
5601 [(set (match_operand:DI 0 "register_operand" "")
5602 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5603 (match_operand:DI 2 "register_operand" "")))
5604 (clobber (reg:CC 100))]
5605 "! TARGET_ARCH64 && reload_completed"
5606 [(parallel [(set (reg:CC_NOOV 100)
5607 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5608 (const_int 0)))
5609 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5610 (set (match_dup 6)
5611 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5612 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5613 "operands[3] = gen_lowpart (SImode, operands[2]);
5614 operands[4] = gen_highpart (SImode, operands[2]);
5615 operands[5] = gen_lowpart (SImode, operands[0]);
5616 operands[6] = gen_highpart (SImode, operands[0]);")
5617
5618 (define_insn "*adddi3_sp64"
5619 [(set (match_operand:DI 0 "register_operand" "=r")
5620 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5621 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5622 "TARGET_ARCH64"
5623 "add\\t%1, %2, %0")
5624
5625 (define_expand "addsi3"
5626 [(set (match_operand:SI 0 "register_operand" "=r,d")
5627 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5628 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5629 ""
5630 "
5631 {
5632 if (arith_4096_operand(operands[2], SImode))
5633 {
5634 if (GET_CODE (operands[1]) == CONST_INT)
5635 emit_insn (gen_movsi (operands[0],
5636 GEN_INT (INTVAL (operands[1]) + 4096)));
5637 else
5638 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5639 gen_rtx_MINUS (SImode, operands[1],
5640 GEN_INT(-4096))));
5641 DONE;
5642 }
5643 }")
5644
5645 (define_insn "*addsi3"
5646 [(set (match_operand:SI 0 "register_operand" "=r,d")
5647 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5648 (match_operand:SI 2 "arith_operand" "rI,d")))]
5649 ""
5650 "@
5651 add\\t%1, %2, %0
5652 fpadd32s\\t%1, %2, %0"
5653 [(set_attr "type" "*,fp")])
5654
5655 (define_insn "*cmp_cc_plus"
5656 [(set (reg:CC_NOOV 100)
5657 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5658 (match_operand:SI 1 "arith_operand" "rI"))
5659 (const_int 0)))]
5660 ""
5661 "addcc\\t%0, %1, %%g0"
5662 [(set_attr "type" "compare")])
5663
5664 (define_insn "*cmp_ccx_plus"
5665 [(set (reg:CCX_NOOV 100)
5666 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5667 (match_operand:DI 1 "arith_double_operand" "rHI"))
5668 (const_int 0)))]
5669 "TARGET_ARCH64"
5670 "addcc\\t%0, %1, %%g0"
5671 [(set_attr "type" "compare")])
5672
5673 (define_insn "*cmp_cc_plus_set"
5674 [(set (reg:CC_NOOV 100)
5675 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5676 (match_operand:SI 2 "arith_operand" "rI"))
5677 (const_int 0)))
5678 (set (match_operand:SI 0 "register_operand" "=r")
5679 (plus:SI (match_dup 1) (match_dup 2)))]
5680 ""
5681 "addcc\\t%1, %2, %0"
5682 [(set_attr "type" "compare")])
5683
5684 (define_insn "*cmp_ccx_plus_set"
5685 [(set (reg:CCX_NOOV 100)
5686 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5687 (match_operand:DI 2 "arith_double_operand" "rHI"))
5688 (const_int 0)))
5689 (set (match_operand:DI 0 "register_operand" "=r")
5690 (plus:DI (match_dup 1) (match_dup 2)))]
5691 "TARGET_ARCH64"
5692 "addcc\\t%1, %2, %0"
5693 [(set_attr "type" "compare")])
5694
5695 (define_expand "subdi3"
5696 [(set (match_operand:DI 0 "register_operand" "=r")
5697 (minus:DI (match_operand:DI 1 "register_operand" "r")
5698 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5699 ""
5700 "
5701 {
5702 if (! TARGET_ARCH64)
5703 {
5704 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5705 gen_rtx_SET (VOIDmode, operands[0],
5706 gen_rtx_MINUS (DImode, operands[1],
5707 operands[2])),
5708 gen_rtx_CLOBBER (VOIDmode,
5709 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5710 DONE;
5711 }
5712 if (arith_double_4096_operand(operands[2], DImode))
5713 {
5714 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5715 gen_rtx_PLUS (DImode, operands[1],
5716 GEN_INT(-4096))));
5717 DONE;
5718 }
5719 }")
5720
5721 (define_insn "*subdi3_sp32"
5722 [(set (match_operand:DI 0 "register_operand" "=r")
5723 (minus:DI (match_operand:DI 1 "register_operand" "r")
5724 (match_operand:DI 2 "arith_double_operand" "rHI")))
5725 (clobber (reg:CC 100))]
5726 "! TARGET_ARCH64"
5727 "#"
5728 [(set_attr "length" "2")])
5729
5730 (define_split
5731 [(set (match_operand:DI 0 "register_operand" "")
5732 (minus:DI (match_operand:DI 1 "register_operand" "")
5733 (match_operand:DI 2 "arith_double_operand" "")))
5734 (clobber (reg:CC 100))]
5735 "! TARGET_ARCH64
5736 && reload_completed
5737 && (GET_CODE (operands[2]) == CONST_INT
5738 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5739 [(clobber (const_int 0))]
5740 "
5741 {
5742 rtx highp, lowp;
5743
5744 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5745 lowp = gen_lowpart (SImode, operands[2]);
5746 if ((lowp == const0_rtx)
5747 && (operands[0] == operands[1]))
5748 {
5749 emit_insn (gen_rtx_SET (VOIDmode,
5750 gen_highpart (SImode, operands[0]),
5751 gen_rtx_MINUS (SImode,
5752 gen_highpart_mode (SImode, DImode,
5753 operands[1]),
5754 highp)));
5755 }
5756 else
5757 {
5758 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5759 gen_lowpart (SImode, operands[1]),
5760 lowp));
5761 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5762 gen_highpart_mode (SImode, DImode, operands[1]),
5763 highp));
5764 }
5765 DONE;
5766 }")
5767
5768 (define_split
5769 [(set (match_operand:DI 0 "register_operand" "")
5770 (minus:DI (match_operand:DI 1 "register_operand" "")
5771 (match_operand:DI 2 "register_operand" "")))
5772 (clobber (reg:CC 100))]
5773 "! TARGET_ARCH64
5774 && reload_completed"
5775 [(clobber (const_int 0))]
5776 "
5777 {
5778 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5779 gen_lowpart (SImode, operands[1]),
5780 gen_lowpart (SImode, operands[2])));
5781 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5782 gen_highpart (SImode, operands[1]),
5783 gen_highpart (SImode, operands[2])));
5784 DONE;
5785 }")
5786
5787 (define_insn ""
5788 [(set (match_operand:DI 0 "register_operand" "=r")
5789 (minus:DI (match_operand:DI 1 "register_operand" "r")
5790 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5791 (clobber (reg:CC 100))]
5792 "! TARGET_ARCH64"
5793 "#"
5794 [(set_attr "length" "2")])
5795
5796 (define_split
5797 [(set (match_operand:DI 0 "register_operand" "")
5798 (minus:DI (match_operand:DI 1 "register_operand" "")
5799 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5800 (clobber (reg:CC 100))]
5801 "! TARGET_ARCH64 && reload_completed"
5802 [(parallel [(set (reg:CC_NOOV 100)
5803 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5804 (const_int 0)))
5805 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5806 (set (match_dup 6)
5807 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5808 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5809 "operands[3] = gen_lowpart (SImode, operands[1]);
5810 operands[4] = gen_highpart (SImode, operands[1]);
5811 operands[5] = gen_lowpart (SImode, operands[0]);
5812 operands[6] = gen_highpart (SImode, operands[0]);")
5813
5814 (define_insn "*subdi3_sp64"
5815 [(set (match_operand:DI 0 "register_operand" "=r")
5816 (minus:DI (match_operand:DI 1 "register_operand" "r")
5817 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5818 "TARGET_ARCH64"
5819 "sub\\t%1, %2, %0")
5820
5821 (define_expand "subsi3"
5822 [(set (match_operand:SI 0 "register_operand" "=r,d")
5823 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5824 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5825 ""
5826 "
5827 {
5828 if (arith_4096_operand(operands[2], SImode))
5829 {
5830 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5831 gen_rtx_PLUS (SImode, operands[1],
5832 GEN_INT(-4096))));
5833 DONE;
5834 }
5835 }")
5836
5837 (define_insn "*subsi3"
5838 [(set (match_operand:SI 0 "register_operand" "=r,d")
5839 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5840 (match_operand:SI 2 "arith_operand" "rI,d")))]
5841 ""
5842 "@
5843 sub\\t%1, %2, %0
5844 fpsub32s\\t%1, %2, %0"
5845 [(set_attr "type" "*,fp")])
5846
5847 (define_insn "*cmp_minus_cc"
5848 [(set (reg:CC_NOOV 100)
5849 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5850 (match_operand:SI 1 "arith_operand" "rI"))
5851 (const_int 0)))]
5852 ""
5853 "subcc\\t%r0, %1, %%g0"
5854 [(set_attr "type" "compare")])
5855
5856 (define_insn "*cmp_minus_ccx"
5857 [(set (reg:CCX_NOOV 100)
5858 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5859 (match_operand:DI 1 "arith_double_operand" "rHI"))
5860 (const_int 0)))]
5861 "TARGET_ARCH64"
5862 "subcc\\t%0, %1, %%g0"
5863 [(set_attr "type" "compare")])
5864
5865 (define_insn "cmp_minus_cc_set"
5866 [(set (reg:CC_NOOV 100)
5867 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5868 (match_operand:SI 2 "arith_operand" "rI"))
5869 (const_int 0)))
5870 (set (match_operand:SI 0 "register_operand" "=r")
5871 (minus:SI (match_dup 1) (match_dup 2)))]
5872 ""
5873 "subcc\\t%r1, %2, %0"
5874 [(set_attr "type" "compare")])
5875
5876 (define_insn "*cmp_minus_ccx_set"
5877 [(set (reg:CCX_NOOV 100)
5878 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5879 (match_operand:DI 2 "arith_double_operand" "rHI"))
5880 (const_int 0)))
5881 (set (match_operand:DI 0 "register_operand" "=r")
5882 (minus:DI (match_dup 1) (match_dup 2)))]
5883 "TARGET_ARCH64"
5884 "subcc\\t%1, %2, %0"
5885 [(set_attr "type" "compare")])
5886 \f
5887 ;; Integer Multiply/Divide.
5888
5889 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5890 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5891
5892 (define_insn "mulsi3"
5893 [(set (match_operand:SI 0 "register_operand" "=r")
5894 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5895 (match_operand:SI 2 "arith_operand" "rI")))]
5896 "TARGET_HARD_MUL"
5897 "smul\\t%1, %2, %0"
5898 [(set_attr "type" "imul")])
5899
5900 (define_expand "muldi3"
5901 [(set (match_operand:DI 0 "register_operand" "=r")
5902 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5903 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5904 "TARGET_ARCH64 || TARGET_V8PLUS"
5905 "
5906 {
5907 if (TARGET_V8PLUS)
5908 {
5909 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5910 DONE;
5911 }
5912 }")
5913
5914 (define_insn "*muldi3_sp64"
5915 [(set (match_operand:DI 0 "register_operand" "=r")
5916 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5917 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5918 "TARGET_ARCH64"
5919 "mulx\\t%1, %2, %0"
5920 [(set_attr "type" "imul")])
5921
5922 ;; V8plus wide multiply.
5923 ;; XXX
5924 (define_insn "muldi3_v8plus"
5925 [(set (match_operand:DI 0 "register_operand" "=r,h")
5926 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5927 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5928 (clobber (match_scratch:SI 3 "=&h,X"))
5929 (clobber (match_scratch:SI 4 "=&h,X"))]
5930 "TARGET_V8PLUS"
5931 "*
5932 {
5933 if (sparc_check_64 (operands[1], insn) <= 0)
5934 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5935 if (which_alternative == 1)
5936 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5937 if (GET_CODE (operands[2]) == CONST_INT)
5938 {
5939 if (which_alternative == 1)
5940 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5941 else
5942 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\";
5943 }
5944 if (sparc_check_64 (operands[2], insn) <= 0)
5945 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5946 if (which_alternative == 1)
5947 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\";
5948 else
5949 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\";
5950 }"
5951 [(set_attr "type" "multi")
5952 (set_attr "length" "9,8")])
5953
5954 (define_insn "*cmp_mul_set"
5955 [(set (reg:CC 100)
5956 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5957 (match_operand:SI 2 "arith_operand" "rI"))
5958 (const_int 0)))
5959 (set (match_operand:SI 0 "register_operand" "=r")
5960 (mult:SI (match_dup 1) (match_dup 2)))]
5961 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5962 "smulcc\\t%1, %2, %0"
5963 [(set_attr "type" "imul")])
5964
5965 (define_expand "mulsidi3"
5966 [(set (match_operand:DI 0 "register_operand" "")
5967 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5968 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5969 "TARGET_HARD_MUL"
5970 "
5971 {
5972 if (CONSTANT_P (operands[2]))
5973 {
5974 if (TARGET_V8PLUS)
5975 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5976 operands[2]));
5977 else
5978 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5979 operands[2]));
5980 DONE;
5981 }
5982 if (TARGET_V8PLUS)
5983 {
5984 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5985 DONE;
5986 }
5987 }")
5988
5989 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5990 ;; registers can hold 64 bit values in the V8plus environment.
5991 ;; XXX
5992 (define_insn "mulsidi3_v8plus"
5993 [(set (match_operand:DI 0 "register_operand" "=h,r")
5994 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5995 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5996 (clobber (match_scratch:SI 3 "=X,&h"))]
5997 "TARGET_V8PLUS"
5998 "@
5999 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6000 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6001 [(set_attr "type" "multi")
6002 (set_attr "length" "2,3")])
6003
6004 ;; XXX
6005 (define_insn "const_mulsidi3_v8plus"
6006 [(set (match_operand:DI 0 "register_operand" "=h,r")
6007 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6008 (match_operand:SI 2 "small_int" "I,I")))
6009 (clobber (match_scratch:SI 3 "=X,&h"))]
6010 "TARGET_V8PLUS"
6011 "@
6012 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6013 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6014 [(set_attr "type" "multi")
6015 (set_attr "length" "2,3")])
6016
6017 ;; XXX
6018 (define_insn "*mulsidi3_sp32"
6019 [(set (match_operand:DI 0 "register_operand" "=r")
6020 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6021 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6022 "TARGET_HARD_MUL32"
6023 "*
6024 {
6025 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6026 }"
6027 [(set (attr "type")
6028 (if_then_else (eq_attr "isa" "sparclet")
6029 (const_string "imul") (const_string "multi")))
6030 (set (attr "length")
6031 (if_then_else (eq_attr "isa" "sparclet")
6032 (const_int 1) (const_int 2)))])
6033
6034 (define_insn "*mulsidi3_sp64"
6035 [(set (match_operand:DI 0 "register_operand" "=r")
6036 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6037 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6038 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6039 "smul\\t%1, %2, %0"
6040 [(set_attr "type" "imul")])
6041
6042 ;; Extra pattern, because sign_extend of a constant isn't valid.
6043
6044 ;; XXX
6045 (define_insn "const_mulsidi3_sp32"
6046 [(set (match_operand:DI 0 "register_operand" "=r")
6047 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6048 (match_operand:SI 2 "small_int" "I")))]
6049 "TARGET_HARD_MUL32"
6050 "*
6051 {
6052 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6053 }"
6054 [(set (attr "type")
6055 (if_then_else (eq_attr "isa" "sparclet")
6056 (const_string "imul") (const_string "multi")))
6057 (set (attr "length")
6058 (if_then_else (eq_attr "isa" "sparclet")
6059 (const_int 1) (const_int 2)))])
6060
6061 (define_insn "const_mulsidi3_sp64"
6062 [(set (match_operand:DI 0 "register_operand" "=r")
6063 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6064 (match_operand:SI 2 "small_int" "I")))]
6065 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6066 "smul\\t%1, %2, %0"
6067 [(set_attr "type" "imul")])
6068
6069 (define_expand "smulsi3_highpart"
6070 [(set (match_operand:SI 0 "register_operand" "")
6071 (truncate:SI
6072 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6073 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6074 (const_int 32))))]
6075 "TARGET_HARD_MUL && TARGET_ARCH32"
6076 "
6077 {
6078 if (CONSTANT_P (operands[2]))
6079 {
6080 if (TARGET_V8PLUS)
6081 {
6082 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6083 operands[1],
6084 operands[2],
6085 GEN_INT (32)));
6086 DONE;
6087 }
6088 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6089 DONE;
6090 }
6091 if (TARGET_V8PLUS)
6092 {
6093 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6094 operands[2], GEN_INT (32)));
6095 DONE;
6096 }
6097 }")
6098
6099 ;; XXX
6100 (define_insn "smulsi3_highpart_v8plus"
6101 [(set (match_operand:SI 0 "register_operand" "=h,r")
6102 (truncate:SI
6103 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6104 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6105 (match_operand:SI 3 "const_int_operand" "i,i"))))
6106 (clobber (match_scratch:SI 4 "=X,&h"))]
6107 "TARGET_V8PLUS"
6108 "@
6109 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6110 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6111 [(set_attr "type" "multi")
6112 (set_attr "length" "2")])
6113
6114 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6115 ;; XXX
6116 (define_insn ""
6117 [(set (match_operand:SI 0 "register_operand" "=h,r")
6118 (subreg:SI
6119 (lshiftrt:DI
6120 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6121 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6122 (match_operand:SI 3 "const_int_operand" "i,i"))
6123 4))
6124 (clobber (match_scratch:SI 4 "=X,&h"))]
6125 "TARGET_V8PLUS"
6126 "@
6127 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6128 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6129 [(set_attr "type" "multi")
6130 (set_attr "length" "2")])
6131
6132 ;; XXX
6133 (define_insn "const_smulsi3_highpart_v8plus"
6134 [(set (match_operand:SI 0 "register_operand" "=h,r")
6135 (truncate:SI
6136 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6137 (match_operand 2 "small_int" "i,i"))
6138 (match_operand:SI 3 "const_int_operand" "i,i"))))
6139 (clobber (match_scratch:SI 4 "=X,&h"))]
6140 "TARGET_V8PLUS"
6141 "@
6142 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6143 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6144 [(set_attr "type" "multi")
6145 (set_attr "length" "2")])
6146
6147 ;; XXX
6148 (define_insn "*smulsi3_highpart_sp32"
6149 [(set (match_operand:SI 0 "register_operand" "=r")
6150 (truncate:SI
6151 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6152 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6153 (const_int 32))))]
6154 "TARGET_HARD_MUL32"
6155 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6156 [(set_attr "type" "multi")
6157 (set_attr "length" "2")])
6158
6159 ;; XXX
6160 (define_insn "const_smulsi3_highpart"
6161 [(set (match_operand:SI 0 "register_operand" "=r")
6162 (truncate:SI
6163 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6164 (match_operand:SI 2 "register_operand" "r"))
6165 (const_int 32))))]
6166 "TARGET_HARD_MUL32"
6167 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6168 [(set_attr "type" "multi")
6169 (set_attr "length" "2")])
6170
6171 (define_expand "umulsidi3"
6172 [(set (match_operand:DI 0 "register_operand" "")
6173 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6174 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6175 "TARGET_HARD_MUL"
6176 "
6177 {
6178 if (CONSTANT_P (operands[2]))
6179 {
6180 if (TARGET_V8PLUS)
6181 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6182 operands[2]));
6183 else
6184 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6185 operands[2]));
6186 DONE;
6187 }
6188 if (TARGET_V8PLUS)
6189 {
6190 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6191 DONE;
6192 }
6193 }")
6194
6195 ;; XXX
6196 (define_insn "umulsidi3_v8plus"
6197 [(set (match_operand:DI 0 "register_operand" "=h,r")
6198 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6199 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6200 (clobber (match_scratch:SI 3 "=X,&h"))]
6201 "TARGET_V8PLUS"
6202 "@
6203 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6204 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6205 [(set_attr "type" "multi")
6206 (set_attr "length" "2,3")])
6207
6208 ;; XXX
6209 (define_insn "*umulsidi3_sp32"
6210 [(set (match_operand:DI 0 "register_operand" "=r")
6211 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6212 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6213 "TARGET_HARD_MUL32"
6214 "*
6215 {
6216 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6217 }"
6218 [(set (attr "type")
6219 (if_then_else (eq_attr "isa" "sparclet")
6220 (const_string "imul") (const_string "multi")))
6221 (set (attr "length")
6222 (if_then_else (eq_attr "isa" "sparclet")
6223 (const_int 1) (const_int 2)))])
6224
6225 (define_insn "*umulsidi3_sp64"
6226 [(set (match_operand:DI 0 "register_operand" "=r")
6227 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6228 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6229 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6230 "umul\\t%1, %2, %0"
6231 [(set_attr "type" "imul")])
6232
6233 ;; Extra pattern, because sign_extend of a constant isn't valid.
6234
6235 ;; XXX
6236 (define_insn "const_umulsidi3_sp32"
6237 [(set (match_operand:DI 0 "register_operand" "=r")
6238 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6239 (match_operand:SI 2 "uns_small_int" "")))]
6240 "TARGET_HARD_MUL32"
6241 "*
6242 {
6243 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6244 }"
6245 [(set (attr "type")
6246 (if_then_else (eq_attr "isa" "sparclet")
6247 (const_string "imul") (const_string "multi")))
6248 (set (attr "length")
6249 (if_then_else (eq_attr "isa" "sparclet")
6250 (const_int 1) (const_int 2)))])
6251
6252 (define_insn "const_umulsidi3_sp64"
6253 [(set (match_operand:DI 0 "register_operand" "=r")
6254 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6255 (match_operand:SI 2 "uns_small_int" "")))]
6256 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6257 "umul\\t%1, %2, %0"
6258 [(set_attr "type" "imul")])
6259
6260 ;; XXX
6261 (define_insn "const_umulsidi3_v8plus"
6262 [(set (match_operand:DI 0 "register_operand" "=h,r")
6263 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6264 (match_operand:SI 2 "uns_small_int" "")))
6265 (clobber (match_scratch:SI 3 "=X,h"))]
6266 "TARGET_V8PLUS"
6267 "@
6268 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6269 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6270 [(set_attr "type" "multi")
6271 (set_attr "length" "2,3")])
6272
6273 (define_expand "umulsi3_highpart"
6274 [(set (match_operand:SI 0 "register_operand" "")
6275 (truncate:SI
6276 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6277 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6278 (const_int 32))))]
6279 "TARGET_HARD_MUL && TARGET_ARCH32"
6280 "
6281 {
6282 if (CONSTANT_P (operands[2]))
6283 {
6284 if (TARGET_V8PLUS)
6285 {
6286 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6287 operands[1],
6288 operands[2],
6289 GEN_INT (32)));
6290 DONE;
6291 }
6292 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6293 DONE;
6294 }
6295 if (TARGET_V8PLUS)
6296 {
6297 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6298 operands[2], GEN_INT (32)));
6299 DONE;
6300 }
6301 }")
6302
6303 ;; XXX
6304 (define_insn "umulsi3_highpart_v8plus"
6305 [(set (match_operand:SI 0 "register_operand" "=h,r")
6306 (truncate:SI
6307 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6308 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6309 (match_operand:SI 3 "const_int_operand" "i,i"))))
6310 (clobber (match_scratch:SI 4 "=X,h"))]
6311 "TARGET_V8PLUS"
6312 "@
6313 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6314 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6315 [(set_attr "type" "multi")
6316 (set_attr "length" "2")])
6317
6318 ;; XXX
6319 (define_insn "const_umulsi3_highpart_v8plus"
6320 [(set (match_operand:SI 0 "register_operand" "=h,r")
6321 (truncate:SI
6322 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6323 (match_operand:SI 2 "uns_small_int" ""))
6324 (match_operand:SI 3 "const_int_operand" "i,i"))))
6325 (clobber (match_scratch:SI 4 "=X,h"))]
6326 "TARGET_V8PLUS"
6327 "@
6328 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6329 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6330 [(set_attr "type" "multi")
6331 (set_attr "length" "2")])
6332
6333 ;; XXX
6334 (define_insn "*umulsi3_highpart_sp32"
6335 [(set (match_operand:SI 0 "register_operand" "=r")
6336 (truncate:SI
6337 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6338 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6339 (const_int 32))))]
6340 "TARGET_HARD_MUL32"
6341 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6342 [(set_attr "type" "multi")
6343 (set_attr "length" "2")])
6344
6345 ;; XXX
6346 (define_insn "const_umulsi3_highpart"
6347 [(set (match_operand:SI 0 "register_operand" "=r")
6348 (truncate:SI
6349 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6350 (match_operand:SI 2 "uns_small_int" ""))
6351 (const_int 32))))]
6352 "TARGET_HARD_MUL32"
6353 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6354 [(set_attr "type" "multi")
6355 (set_attr "length" "2")])
6356
6357 ;; The v8 architecture specifies that there must be 3 instructions between
6358 ;; a y register write and a use of it for correct results.
6359
6360 (define_expand "divsi3"
6361 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6362 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6363 (match_operand:SI 2 "input_operand" "rI,m")))
6364 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6365 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6366 "
6367 {
6368 if (TARGET_ARCH64)
6369 {
6370 operands[3] = gen_reg_rtx(SImode);
6371 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6372 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6373 operands[3]));
6374 DONE;
6375 }
6376 }")
6377
6378 (define_insn "divsi3_sp32"
6379 [(set (match_operand:SI 0 "register_operand" "=r,r")
6380 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6381 (match_operand:SI 2 "input_operand" "rI,m")))
6382 (clobber (match_scratch:SI 3 "=&r,&r"))]
6383 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6384 && TARGET_ARCH32"
6385 "*
6386 {
6387 if (which_alternative == 0)
6388 if (TARGET_V9)
6389 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6390 else
6391 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6392 else
6393 if (TARGET_V9)
6394 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6395 else
6396 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\";
6397 }"
6398 [(set_attr "type" "multi")
6399 (set (attr "length")
6400 (if_then_else (eq_attr "isa" "v9")
6401 (const_int 4) (const_int 7)))])
6402
6403 (define_insn "divsi3_sp64"
6404 [(set (match_operand:SI 0 "register_operand" "=r")
6405 (div:SI (match_operand:SI 1 "register_operand" "r")
6406 (match_operand:SI 2 "input_operand" "rI")))
6407 (use (match_operand:SI 3 "register_operand" "r"))]
6408 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6409 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6410 [(set_attr "type" "multi")
6411 (set_attr "length" "2")])
6412
6413 (define_insn "divdi3"
6414 [(set (match_operand:DI 0 "register_operand" "=r")
6415 (div:DI (match_operand:DI 1 "register_operand" "r")
6416 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6417 "TARGET_ARCH64"
6418 "sdivx\\t%1, %2, %0"
6419 [(set_attr "type" "idiv")])
6420
6421 (define_insn "*cmp_sdiv_cc_set"
6422 [(set (reg:CC 100)
6423 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6424 (match_operand:SI 2 "arith_operand" "rI"))
6425 (const_int 0)))
6426 (set (match_operand:SI 0 "register_operand" "=r")
6427 (div:SI (match_dup 1) (match_dup 2)))
6428 (clobber (match_scratch:SI 3 "=&r"))]
6429 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6430 "*
6431 {
6432 if (TARGET_V9)
6433 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6434 else
6435 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6436 }"
6437 [(set_attr "type" "multi")
6438 (set (attr "length")
6439 (if_then_else (eq_attr "isa" "v9")
6440 (const_int 3) (const_int 6)))])
6441
6442 ;; XXX
6443 (define_expand "udivsi3"
6444 [(set (match_operand:SI 0 "register_operand" "")
6445 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6446 (match_operand:SI 2 "input_operand" "")))]
6447 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6448 "")
6449
6450 (define_insn "udivsi3_sp32"
6451 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6452 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6453 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6454 "(TARGET_V8
6455 || TARGET_DEPRECATED_V8_INSNS)
6456 && TARGET_ARCH32"
6457 "*
6458 {
6459 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6460 switch (which_alternative)
6461 {
6462 default:
6463 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6464 case 1:
6465 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6466 case 2:
6467 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6468 }
6469 }"
6470 [(set_attr "type" "multi")
6471 (set_attr "length" "5")])
6472
6473 (define_insn "udivsi3_sp64"
6474 [(set (match_operand:SI 0 "register_operand" "=r")
6475 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6476 (match_operand:SI 2 "input_operand" "rI")))]
6477 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6478 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6479 [(set_attr "type" "multi")
6480 (set_attr "length" "2")])
6481
6482 (define_insn "udivdi3"
6483 [(set (match_operand:DI 0 "register_operand" "=r")
6484 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6485 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6486 "TARGET_ARCH64"
6487 "udivx\\t%1, %2, %0"
6488 [(set_attr "type" "idiv")])
6489
6490 (define_insn "*cmp_udiv_cc_set"
6491 [(set (reg:CC 100)
6492 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6493 (match_operand:SI 2 "arith_operand" "rI"))
6494 (const_int 0)))
6495 (set (match_operand:SI 0 "register_operand" "=r")
6496 (udiv:SI (match_dup 1) (match_dup 2)))]
6497 "TARGET_V8
6498 || TARGET_DEPRECATED_V8_INSNS"
6499 "*
6500 {
6501 if (TARGET_V9)
6502 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6503 else
6504 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6505 }"
6506 [(set_attr "type" "multi")
6507 (set (attr "length")
6508 (if_then_else (eq_attr "isa" "v9")
6509 (const_int 2) (const_int 5)))])
6510
6511 ; sparclet multiply/accumulate insns
6512
6513 (define_insn "*smacsi"
6514 [(set (match_operand:SI 0 "register_operand" "=r")
6515 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6516 (match_operand:SI 2 "arith_operand" "rI"))
6517 (match_operand:SI 3 "register_operand" "0")))]
6518 "TARGET_SPARCLET"
6519 "smac\\t%1, %2, %0"
6520 [(set_attr "type" "imul")])
6521
6522 (define_insn "*smacdi"
6523 [(set (match_operand:DI 0 "register_operand" "=r")
6524 (plus:DI (mult:DI (sign_extend:DI
6525 (match_operand:SI 1 "register_operand" "%r"))
6526 (sign_extend:DI
6527 (match_operand:SI 2 "register_operand" "r")))
6528 (match_operand:DI 3 "register_operand" "0")))]
6529 "TARGET_SPARCLET"
6530 "smacd\\t%1, %2, %L0"
6531 [(set_attr "type" "imul")])
6532
6533 (define_insn "*umacdi"
6534 [(set (match_operand:DI 0 "register_operand" "=r")
6535 (plus:DI (mult:DI (zero_extend:DI
6536 (match_operand:SI 1 "register_operand" "%r"))
6537 (zero_extend:DI
6538 (match_operand:SI 2 "register_operand" "r")))
6539 (match_operand:DI 3 "register_operand" "0")))]
6540 "TARGET_SPARCLET"
6541 "umacd\\t%1, %2, %L0"
6542 [(set_attr "type" "imul")])
6543 \f
6544 ;;- Boolean instructions
6545 ;; We define DImode `and' so with DImode `not' we can get
6546 ;; DImode `andn'. Other combinations are possible.
6547
6548 (define_expand "anddi3"
6549 [(set (match_operand:DI 0 "register_operand" "")
6550 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6551 (match_operand:DI 2 "arith_double_operand" "")))]
6552 ""
6553 "")
6554
6555 (define_insn "*anddi3_sp32"
6556 [(set (match_operand:DI 0 "register_operand" "=r,b")
6557 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6558 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6559 "! TARGET_ARCH64"
6560 "@
6561 #
6562 fand\\t%1, %2, %0"
6563 [(set_attr "type" "*,fp")
6564 (set_attr "length" "2,*")
6565 (set_attr "fptype" "double")])
6566
6567 (define_insn "*anddi3_sp64"
6568 [(set (match_operand:DI 0 "register_operand" "=r,b")
6569 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6570 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6571 "TARGET_ARCH64"
6572 "@
6573 and\\t%1, %2, %0
6574 fand\\t%1, %2, %0"
6575 [(set_attr "type" "*,fp")
6576 (set_attr "fptype" "double")])
6577
6578 (define_insn "andsi3"
6579 [(set (match_operand:SI 0 "register_operand" "=r,d")
6580 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6581 (match_operand:SI 2 "arith_operand" "rI,d")))]
6582 ""
6583 "@
6584 and\\t%1, %2, %0
6585 fands\\t%1, %2, %0"
6586 [(set_attr "type" "*,fp")])
6587
6588 (define_split
6589 [(set (match_operand:SI 0 "register_operand" "")
6590 (and:SI (match_operand:SI 1 "register_operand" "")
6591 (match_operand:SI 2 "" "")))
6592 (clobber (match_operand:SI 3 "register_operand" ""))]
6593 "GET_CODE (operands[2]) == CONST_INT
6594 && !SMALL_INT32 (operands[2])
6595 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6596 [(set (match_dup 3) (match_dup 4))
6597 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6598 "
6599 {
6600 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6601 }")
6602
6603 ;; Split DImode logical operations requiring two instructions.
6604 (define_split
6605 [(set (match_operand:DI 0 "register_operand" "")
6606 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6607 [(match_operand:DI 2 "register_operand" "")
6608 (match_operand:DI 3 "arith_double_operand" "")]))]
6609 "! TARGET_ARCH64
6610 && reload_completed
6611 && ((GET_CODE (operands[0]) == REG
6612 && REGNO (operands[0]) < 32)
6613 || (GET_CODE (operands[0]) == SUBREG
6614 && GET_CODE (SUBREG_REG (operands[0])) == REG
6615 && REGNO (SUBREG_REG (operands[0])) < 32))"
6616 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6617 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6618 "
6619 {
6620 if (GET_CODE (operands[0]) == SUBREG)
6621 operands[0] = alter_subreg (operands[0]);
6622 operands[4] = gen_highpart (SImode, operands[0]);
6623 operands[5] = gen_lowpart (SImode, operands[0]);
6624 operands[6] = gen_highpart (SImode, operands[2]);
6625 operands[7] = gen_lowpart (SImode, operands[2]);
6626 #if HOST_BITS_PER_WIDE_INT == 32
6627 if (GET_CODE (operands[3]) == CONST_INT)
6628 {
6629 if (INTVAL (operands[3]) < 0)
6630 operands[8] = constm1_rtx;
6631 else
6632 operands[8] = const0_rtx;
6633 }
6634 else
6635 #endif
6636 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6637 operands[9] = gen_lowpart (SImode, operands[3]);
6638 }")
6639
6640 (define_insn "*and_not_di_sp32"
6641 [(set (match_operand:DI 0 "register_operand" "=r,b")
6642 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6643 (match_operand:DI 2 "register_operand" "r,b")))]
6644 "! TARGET_ARCH64"
6645 "@
6646 #
6647 fandnot1\\t%1, %2, %0"
6648 [(set_attr "type" "*,fp")
6649 (set_attr "length" "2,*")
6650 (set_attr "fptype" "double")])
6651
6652 (define_split
6653 [(set (match_operand:DI 0 "register_operand" "")
6654 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6655 (match_operand:DI 2 "register_operand" "")))]
6656 "! TARGET_ARCH64
6657 && reload_completed
6658 && ((GET_CODE (operands[0]) == REG
6659 && REGNO (operands[0]) < 32)
6660 || (GET_CODE (operands[0]) == SUBREG
6661 && GET_CODE (SUBREG_REG (operands[0])) == REG
6662 && REGNO (SUBREG_REG (operands[0])) < 32))"
6663 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6664 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6665 "if (GET_CODE (operands[0]) == SUBREG)
6666 operands[0] = alter_subreg (operands[0]);
6667 operands[3] = gen_highpart (SImode, operands[0]);
6668 operands[4] = gen_highpart (SImode, operands[1]);
6669 operands[5] = gen_highpart (SImode, operands[2]);
6670 operands[6] = gen_lowpart (SImode, operands[0]);
6671 operands[7] = gen_lowpart (SImode, operands[1]);
6672 operands[8] = gen_lowpart (SImode, operands[2]);")
6673
6674 (define_insn "*and_not_di_sp64"
6675 [(set (match_operand:DI 0 "register_operand" "=r,b")
6676 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6677 (match_operand:DI 2 "register_operand" "r,b")))]
6678 "TARGET_ARCH64"
6679 "@
6680 andn\\t%2, %1, %0
6681 fandnot1\\t%1, %2, %0"
6682 [(set_attr "type" "*,fp")
6683 (set_attr "fptype" "double")])
6684
6685 (define_insn "*and_not_si"
6686 [(set (match_operand:SI 0 "register_operand" "=r,d")
6687 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6688 (match_operand:SI 2 "register_operand" "r,d")))]
6689 ""
6690 "@
6691 andn\\t%2, %1, %0
6692 fandnot1s\\t%1, %2, %0"
6693 [(set_attr "type" "*,fp")])
6694
6695 (define_expand "iordi3"
6696 [(set (match_operand:DI 0 "register_operand" "")
6697 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6698 (match_operand:DI 2 "arith_double_operand" "")))]
6699 ""
6700 "")
6701
6702 (define_insn "*iordi3_sp32"
6703 [(set (match_operand:DI 0 "register_operand" "=r,b")
6704 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6705 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6706 "! TARGET_ARCH64"
6707 "@
6708 #
6709 for\\t%1, %2, %0"
6710 [(set_attr "type" "*,fp")
6711 (set_attr "length" "2,*")
6712 (set_attr "fptype" "double")])
6713
6714 (define_insn "*iordi3_sp64"
6715 [(set (match_operand:DI 0 "register_operand" "=r,b")
6716 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6717 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6718 "TARGET_ARCH64"
6719 "@
6720 or\\t%1, %2, %0
6721 for\\t%1, %2, %0"
6722 [(set_attr "type" "*,fp")
6723 (set_attr "fptype" "double")])
6724
6725 (define_insn "iorsi3"
6726 [(set (match_operand:SI 0 "register_operand" "=r,d")
6727 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6728 (match_operand:SI 2 "arith_operand" "rI,d")))]
6729 ""
6730 "@
6731 or\\t%1, %2, %0
6732 fors\\t%1, %2, %0"
6733 [(set_attr "type" "*,fp")])
6734
6735 (define_split
6736 [(set (match_operand:SI 0 "register_operand" "")
6737 (ior:SI (match_operand:SI 1 "register_operand" "")
6738 (match_operand:SI 2 "" "")))
6739 (clobber (match_operand:SI 3 "register_operand" ""))]
6740 "GET_CODE (operands[2]) == CONST_INT
6741 && !SMALL_INT32 (operands[2])
6742 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6743 [(set (match_dup 3) (match_dup 4))
6744 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6745 "
6746 {
6747 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6748 }")
6749
6750 (define_insn "*or_not_di_sp32"
6751 [(set (match_operand:DI 0 "register_operand" "=r,b")
6752 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6753 (match_operand:DI 2 "register_operand" "r,b")))]
6754 "! TARGET_ARCH64"
6755 "@
6756 #
6757 fornot1\\t%1, %2, %0"
6758 [(set_attr "type" "*,fp")
6759 (set_attr "length" "2,*")
6760 (set_attr "fptype" "double")])
6761
6762 (define_split
6763 [(set (match_operand:DI 0 "register_operand" "")
6764 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6765 (match_operand:DI 2 "register_operand" "")))]
6766 "! TARGET_ARCH64
6767 && reload_completed
6768 && ((GET_CODE (operands[0]) == REG
6769 && REGNO (operands[0]) < 32)
6770 || (GET_CODE (operands[0]) == SUBREG
6771 && GET_CODE (SUBREG_REG (operands[0])) == REG
6772 && REGNO (SUBREG_REG (operands[0])) < 32))"
6773 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6774 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6775 "if (GET_CODE (operands[0]) == SUBREG)
6776 operands[0] = alter_subreg (operands[0]);
6777 operands[3] = gen_highpart (SImode, operands[0]);
6778 operands[4] = gen_highpart (SImode, operands[1]);
6779 operands[5] = gen_highpart (SImode, operands[2]);
6780 operands[6] = gen_lowpart (SImode, operands[0]);
6781 operands[7] = gen_lowpart (SImode, operands[1]);
6782 operands[8] = gen_lowpart (SImode, operands[2]);")
6783
6784 (define_insn "*or_not_di_sp64"
6785 [(set (match_operand:DI 0 "register_operand" "=r,b")
6786 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6787 (match_operand:DI 2 "register_operand" "r,b")))]
6788 "TARGET_ARCH64"
6789 "@
6790 orn\\t%2, %1, %0
6791 fornot1\\t%1, %2, %0"
6792 [(set_attr "type" "*,fp")
6793 (set_attr "fptype" "double")])
6794
6795 (define_insn "*or_not_si"
6796 [(set (match_operand:SI 0 "register_operand" "=r,d")
6797 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6798 (match_operand:SI 2 "register_operand" "r,d")))]
6799 ""
6800 "@
6801 orn\\t%2, %1, %0
6802 fornot1s\\t%1, %2, %0"
6803 [(set_attr "type" "*,fp")])
6804
6805 (define_expand "xordi3"
6806 [(set (match_operand:DI 0 "register_operand" "")
6807 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6808 (match_operand:DI 2 "arith_double_operand" "")))]
6809 ""
6810 "")
6811
6812 (define_insn "*xordi3_sp32"
6813 [(set (match_operand:DI 0 "register_operand" "=r,b")
6814 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6815 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6816 "! TARGET_ARCH64"
6817 "@
6818 #
6819 fxor\\t%1, %2, %0"
6820 [(set_attr "type" "*,fp")
6821 (set_attr "length" "2,*")
6822 (set_attr "fptype" "double")])
6823
6824 (define_insn "*xordi3_sp64"
6825 [(set (match_operand:DI 0 "register_operand" "=r,b")
6826 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6827 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6828 "TARGET_ARCH64"
6829 "@
6830 xor\\t%r1, %2, %0
6831 fxor\\t%1, %2, %0"
6832 [(set_attr "type" "*,fp")
6833 (set_attr "fptype" "double")])
6834
6835 (define_insn "*xordi3_sp64_dbl"
6836 [(set (match_operand:DI 0 "register_operand" "=r")
6837 (xor:DI (match_operand:DI 1 "register_operand" "r")
6838 (match_operand:DI 2 "const64_operand" "")))]
6839 "(TARGET_ARCH64
6840 && HOST_BITS_PER_WIDE_INT != 64)"
6841 "xor\\t%1, %2, %0")
6842
6843 (define_insn "xorsi3"
6844 [(set (match_operand:SI 0 "register_operand" "=r,d")
6845 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6846 (match_operand:SI 2 "arith_operand" "rI,d")))]
6847 ""
6848 "@
6849 xor\\t%r1, %2, %0
6850 fxors\\t%1, %2, %0"
6851 [(set_attr "type" "*,fp")])
6852
6853 (define_split
6854 [(set (match_operand:SI 0 "register_operand" "")
6855 (xor:SI (match_operand:SI 1 "register_operand" "")
6856 (match_operand:SI 2 "" "")))
6857 (clobber (match_operand:SI 3 "register_operand" ""))]
6858 "GET_CODE (operands[2]) == CONST_INT
6859 && !SMALL_INT32 (operands[2])
6860 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6861 [(set (match_dup 3) (match_dup 4))
6862 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6863 "
6864 {
6865 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6866 }")
6867
6868 (define_split
6869 [(set (match_operand:SI 0 "register_operand" "")
6870 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6871 (match_operand:SI 2 "" ""))))
6872 (clobber (match_operand:SI 3 "register_operand" ""))]
6873 "GET_CODE (operands[2]) == CONST_INT
6874 && !SMALL_INT32 (operands[2])
6875 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6876 [(set (match_dup 3) (match_dup 4))
6877 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6878 "
6879 {
6880 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6881 }")
6882
6883 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6884 ;; Combine now canonicalizes to the rightmost expression.
6885 (define_insn "*xor_not_di_sp32"
6886 [(set (match_operand:DI 0 "register_operand" "=r,b")
6887 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6888 (match_operand:DI 2 "register_operand" "r,b"))))]
6889 "! TARGET_ARCH64"
6890 "@
6891 #
6892 fxnor\\t%1, %2, %0"
6893 [(set_attr "type" "*,fp")
6894 (set_attr "length" "2,*")
6895 (set_attr "fptype" "double")])
6896
6897 (define_split
6898 [(set (match_operand:DI 0 "register_operand" "")
6899 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6900 (match_operand:DI 2 "register_operand" ""))))]
6901 "! TARGET_ARCH64
6902 && reload_completed
6903 && ((GET_CODE (operands[0]) == REG
6904 && REGNO (operands[0]) < 32)
6905 || (GET_CODE (operands[0]) == SUBREG
6906 && GET_CODE (SUBREG_REG (operands[0])) == REG
6907 && REGNO (SUBREG_REG (operands[0])) < 32))"
6908 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6909 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6910 "if (GET_CODE (operands[0]) == SUBREG)
6911 operands[0] = alter_subreg (operands[0]);
6912 operands[3] = gen_highpart (SImode, operands[0]);
6913 operands[4] = gen_highpart (SImode, operands[1]);
6914 operands[5] = gen_highpart (SImode, operands[2]);
6915 operands[6] = gen_lowpart (SImode, operands[0]);
6916 operands[7] = gen_lowpart (SImode, operands[1]);
6917 operands[8] = gen_lowpart (SImode, operands[2]);")
6918
6919 (define_insn "*xor_not_di_sp64"
6920 [(set (match_operand:DI 0 "register_operand" "=r,b")
6921 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6922 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6923 "TARGET_ARCH64"
6924 "@
6925 xnor\\t%r1, %2, %0
6926 fxnor\\t%1, %2, %0"
6927 [(set_attr "type" "*,fp")
6928 (set_attr "fptype" "double")])
6929
6930 (define_insn "*xor_not_si"
6931 [(set (match_operand:SI 0 "register_operand" "=r,d")
6932 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6933 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6934 ""
6935 "@
6936 xnor\\t%r1, %2, %0
6937 fxnors\\t%1, %2, %0"
6938 [(set_attr "type" "*,fp")])
6939
6940 ;; These correspond to the above in the case where we also (or only)
6941 ;; want to set the condition code.
6942
6943 (define_insn "*cmp_cc_arith_op"
6944 [(set (reg:CC 100)
6945 (compare:CC
6946 (match_operator:SI 2 "cc_arithop"
6947 [(match_operand:SI 0 "arith_operand" "%r")
6948 (match_operand:SI 1 "arith_operand" "rI")])
6949 (const_int 0)))]
6950 ""
6951 "%A2cc\\t%0, %1, %%g0"
6952 [(set_attr "type" "compare")])
6953
6954 (define_insn "*cmp_ccx_arith_op"
6955 [(set (reg:CCX 100)
6956 (compare:CCX
6957 (match_operator:DI 2 "cc_arithop"
6958 [(match_operand:DI 0 "arith_double_operand" "%r")
6959 (match_operand:DI 1 "arith_double_operand" "rHI")])
6960 (const_int 0)))]
6961 "TARGET_ARCH64"
6962 "%A2cc\\t%0, %1, %%g0"
6963 [(set_attr "type" "compare")])
6964
6965 (define_insn "*cmp_cc_arith_op_set"
6966 [(set (reg:CC 100)
6967 (compare:CC
6968 (match_operator:SI 3 "cc_arithop"
6969 [(match_operand:SI 1 "arith_operand" "%r")
6970 (match_operand:SI 2 "arith_operand" "rI")])
6971 (const_int 0)))
6972 (set (match_operand:SI 0 "register_operand" "=r")
6973 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6974 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6975 "%A3cc\\t%1, %2, %0"
6976 [(set_attr "type" "compare")])
6977
6978 (define_insn "*cmp_ccx_arith_op_set"
6979 [(set (reg:CCX 100)
6980 (compare:CCX
6981 (match_operator:DI 3 "cc_arithop"
6982 [(match_operand:DI 1 "arith_double_operand" "%r")
6983 (match_operand:DI 2 "arith_double_operand" "rHI")])
6984 (const_int 0)))
6985 (set (match_operand:DI 0 "register_operand" "=r")
6986 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6987 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6988 "%A3cc\\t%1, %2, %0"
6989 [(set_attr "type" "compare")])
6990
6991 (define_insn "*cmp_cc_xor_not"
6992 [(set (reg:CC 100)
6993 (compare:CC
6994 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6995 (match_operand:SI 1 "arith_operand" "rI")))
6996 (const_int 0)))]
6997 ""
6998 "xnorcc\\t%r0, %1, %%g0"
6999 [(set_attr "type" "compare")])
7000
7001 (define_insn "*cmp_ccx_xor_not"
7002 [(set (reg:CCX 100)
7003 (compare:CCX
7004 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7005 (match_operand:DI 1 "arith_double_operand" "rHI")))
7006 (const_int 0)))]
7007 "TARGET_ARCH64"
7008 "xnorcc\\t%r0, %1, %%g0"
7009 [(set_attr "type" "compare")])
7010
7011 (define_insn "*cmp_cc_xor_not_set"
7012 [(set (reg:CC 100)
7013 (compare:CC
7014 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7015 (match_operand:SI 2 "arith_operand" "rI")))
7016 (const_int 0)))
7017 (set (match_operand:SI 0 "register_operand" "=r")
7018 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7019 ""
7020 "xnorcc\\t%r1, %2, %0"
7021 [(set_attr "type" "compare")])
7022
7023 (define_insn "*cmp_ccx_xor_not_set"
7024 [(set (reg:CCX 100)
7025 (compare:CCX
7026 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7027 (match_operand:DI 2 "arith_double_operand" "rHI")))
7028 (const_int 0)))
7029 (set (match_operand:DI 0 "register_operand" "=r")
7030 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7031 "TARGET_ARCH64"
7032 "xnorcc\\t%r1, %2, %0"
7033 [(set_attr "type" "compare")])
7034
7035 (define_insn "*cmp_cc_arith_op_not"
7036 [(set (reg:CC 100)
7037 (compare:CC
7038 (match_operator:SI 2 "cc_arithopn"
7039 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7040 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7041 (const_int 0)))]
7042 ""
7043 "%B2cc\\t%r1, %0, %%g0"
7044 [(set_attr "type" "compare")])
7045
7046 (define_insn "*cmp_ccx_arith_op_not"
7047 [(set (reg:CCX 100)
7048 (compare:CCX
7049 (match_operator:DI 2 "cc_arithopn"
7050 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7051 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7052 (const_int 0)))]
7053 "TARGET_ARCH64"
7054 "%B2cc\\t%r1, %0, %%g0"
7055 [(set_attr "type" "compare")])
7056
7057 (define_insn "*cmp_cc_arith_op_not_set"
7058 [(set (reg:CC 100)
7059 (compare:CC
7060 (match_operator:SI 3 "cc_arithopn"
7061 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7062 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7063 (const_int 0)))
7064 (set (match_operand:SI 0 "register_operand" "=r")
7065 (match_operator:SI 4 "cc_arithopn"
7066 [(not:SI (match_dup 1)) (match_dup 2)]))]
7067 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7068 "%B3cc\\t%r2, %1, %0"
7069 [(set_attr "type" "compare")])
7070
7071 (define_insn "*cmp_ccx_arith_op_not_set"
7072 [(set (reg:CCX 100)
7073 (compare:CCX
7074 (match_operator:DI 3 "cc_arithopn"
7075 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7076 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7077 (const_int 0)))
7078 (set (match_operand:DI 0 "register_operand" "=r")
7079 (match_operator:DI 4 "cc_arithopn"
7080 [(not:DI (match_dup 1)) (match_dup 2)]))]
7081 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7082 "%B3cc\\t%r2, %1, %0"
7083 [(set_attr "type" "compare")])
7084
7085 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7086 ;; does not know how to make it work for constants.
7087
7088 (define_expand "negdi2"
7089 [(set (match_operand:DI 0 "register_operand" "=r")
7090 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7091 ""
7092 "
7093 {
7094 if (! TARGET_ARCH64)
7095 {
7096 emit_insn (gen_rtx_PARALLEL
7097 (VOIDmode,
7098 gen_rtvec (2,
7099 gen_rtx_SET (VOIDmode, operand0,
7100 gen_rtx_NEG (DImode, operand1)),
7101 gen_rtx_CLOBBER (VOIDmode,
7102 gen_rtx_REG (CCmode,
7103 SPARC_ICC_REG)))));
7104 DONE;
7105 }
7106 }")
7107
7108 (define_insn "*negdi2_sp32"
7109 [(set (match_operand:DI 0 "register_operand" "=r")
7110 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7111 (clobber (reg:CC 100))]
7112 "TARGET_ARCH32"
7113 "#"
7114 [(set_attr "length" "2")])
7115
7116 (define_split
7117 [(set (match_operand:DI 0 "register_operand" "")
7118 (neg:DI (match_operand:DI 1 "register_operand" "")))
7119 (clobber (reg:CC 100))]
7120 "TARGET_ARCH32
7121 && reload_completed"
7122 [(parallel [(set (reg:CC_NOOV 100)
7123 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7124 (const_int 0)))
7125 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7126 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7127 (ltu:SI (reg:CC 100) (const_int 0))))]
7128 "operands[2] = gen_highpart (SImode, operands[0]);
7129 operands[3] = gen_highpart (SImode, operands[1]);
7130 operands[4] = gen_lowpart (SImode, operands[0]);
7131 operands[5] = gen_lowpart (SImode, operands[1]);")
7132
7133 (define_insn "*negdi2_sp64"
7134 [(set (match_operand:DI 0 "register_operand" "=r")
7135 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7136 "TARGET_ARCH64"
7137 "sub\\t%%g0, %1, %0")
7138
7139 (define_insn "negsi2"
7140 [(set (match_operand:SI 0 "register_operand" "=r")
7141 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7142 ""
7143 "sub\\t%%g0, %1, %0")
7144
7145 (define_insn "*cmp_cc_neg"
7146 [(set (reg:CC_NOOV 100)
7147 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7148 (const_int 0)))]
7149 ""
7150 "subcc\\t%%g0, %0, %%g0"
7151 [(set_attr "type" "compare")])
7152
7153 (define_insn "*cmp_ccx_neg"
7154 [(set (reg:CCX_NOOV 100)
7155 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7156 (const_int 0)))]
7157 "TARGET_ARCH64"
7158 "subcc\\t%%g0, %0, %%g0"
7159 [(set_attr "type" "compare")])
7160
7161 (define_insn "*cmp_cc_set_neg"
7162 [(set (reg:CC_NOOV 100)
7163 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7164 (const_int 0)))
7165 (set (match_operand:SI 0 "register_operand" "=r")
7166 (neg:SI (match_dup 1)))]
7167 ""
7168 "subcc\\t%%g0, %1, %0"
7169 [(set_attr "type" "compare")])
7170
7171 (define_insn "*cmp_ccx_set_neg"
7172 [(set (reg:CCX_NOOV 100)
7173 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7174 (const_int 0)))
7175 (set (match_operand:DI 0 "register_operand" "=r")
7176 (neg:DI (match_dup 1)))]
7177 "TARGET_ARCH64"
7178 "subcc\\t%%g0, %1, %0"
7179 [(set_attr "type" "compare")])
7180
7181 ;; We cannot use the "not" pseudo insn because the Sun assembler
7182 ;; does not know how to make it work for constants.
7183 (define_expand "one_cmpldi2"
7184 [(set (match_operand:DI 0 "register_operand" "")
7185 (not:DI (match_operand:DI 1 "register_operand" "")))]
7186 ""
7187 "")
7188
7189 (define_insn "*one_cmpldi2_sp32"
7190 [(set (match_operand:DI 0 "register_operand" "=r,b")
7191 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7192 "! TARGET_ARCH64"
7193 "@
7194 #
7195 fnot1\\t%1, %0"
7196 [(set_attr "type" "*,fp")
7197 (set_attr "length" "2,*")
7198 (set_attr "fptype" "double")])
7199
7200 (define_split
7201 [(set (match_operand:DI 0 "register_operand" "")
7202 (not:DI (match_operand:DI 1 "register_operand" "")))]
7203 "! TARGET_ARCH64
7204 && reload_completed
7205 && ((GET_CODE (operands[0]) == REG
7206 && REGNO (operands[0]) < 32)
7207 || (GET_CODE (operands[0]) == SUBREG
7208 && GET_CODE (SUBREG_REG (operands[0])) == REG
7209 && REGNO (SUBREG_REG (operands[0])) < 32))"
7210 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7211 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7212 "if (GET_CODE (operands[0]) == SUBREG)
7213 operands[0] = alter_subreg (operands[0]);
7214 operands[2] = gen_highpart (SImode, operands[0]);
7215 operands[3] = gen_highpart (SImode, operands[1]);
7216 operands[4] = gen_lowpart (SImode, operands[0]);
7217 operands[5] = gen_lowpart (SImode, operands[1]);")
7218
7219 (define_insn "*one_cmpldi2_sp64"
7220 [(set (match_operand:DI 0 "register_operand" "=r,b")
7221 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7222 "TARGET_ARCH64"
7223 "@
7224 xnor\\t%%g0, %1, %0
7225 fnot1\\t%1, %0"
7226 [(set_attr "type" "*,fp")
7227 (set_attr "fptype" "double")])
7228
7229 (define_insn "one_cmplsi2"
7230 [(set (match_operand:SI 0 "register_operand" "=r,d")
7231 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7232 ""
7233 "@
7234 xnor\\t%%g0, %1, %0
7235 fnot1s\\t%1, %0"
7236 [(set_attr "type" "*,fp")])
7237
7238 (define_insn "*cmp_cc_not"
7239 [(set (reg:CC 100)
7240 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7241 (const_int 0)))]
7242 ""
7243 "xnorcc\\t%%g0, %0, %%g0"
7244 [(set_attr "type" "compare")])
7245
7246 (define_insn "*cmp_ccx_not"
7247 [(set (reg:CCX 100)
7248 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7249 (const_int 0)))]
7250 "TARGET_ARCH64"
7251 "xnorcc\\t%%g0, %0, %%g0"
7252 [(set_attr "type" "compare")])
7253
7254 (define_insn "*cmp_cc_set_not"
7255 [(set (reg:CC 100)
7256 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7257 (const_int 0)))
7258 (set (match_operand:SI 0 "register_operand" "=r")
7259 (not:SI (match_dup 1)))]
7260 ""
7261 "xnorcc\\t%%g0, %1, %0"
7262 [(set_attr "type" "compare")])
7263
7264 (define_insn "*cmp_ccx_set_not"
7265 [(set (reg:CCX 100)
7266 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7267 (const_int 0)))
7268 (set (match_operand:DI 0 "register_operand" "=r")
7269 (not:DI (match_dup 1)))]
7270 "TARGET_ARCH64"
7271 "xnorcc\\t%%g0, %1, %0"
7272 [(set_attr "type" "compare")])
7273 \f
7274 ;; Floating point arithmetic instructions.
7275
7276 (define_expand "addtf3"
7277 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7278 (plus:TF (match_operand:TF 1 "general_operand" "")
7279 (match_operand:TF 2 "general_operand" "")))]
7280 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7281 "
7282 {
7283 if (! TARGET_HARD_QUAD)
7284 {
7285 rtx slot0, slot1, slot2;
7286
7287 if (GET_CODE (operands[0]) != MEM)
7288 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7289 else
7290 slot0 = operands[0];
7291 if (GET_CODE (operands[1]) != MEM)
7292 {
7293 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7294 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7295 }
7296 else
7297 slot1 = operands[1];
7298 if (GET_CODE (operands[2]) != MEM)
7299 {
7300 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7301 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7302 }
7303 else
7304 slot2 = operands[2];
7305
7306 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7307 VOIDmode, 3,
7308 XEXP (slot0, 0), Pmode,
7309 XEXP (slot1, 0), Pmode,
7310 XEXP (slot2, 0), Pmode);
7311
7312 if (GET_CODE (operands[0]) != MEM)
7313 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7314 DONE;
7315 }
7316 }")
7317
7318 (define_insn "*addtf3_hq"
7319 [(set (match_operand:TF 0 "register_operand" "=e")
7320 (plus:TF (match_operand:TF 1 "register_operand" "e")
7321 (match_operand:TF 2 "register_operand" "e")))]
7322 "TARGET_FPU && TARGET_HARD_QUAD"
7323 "faddq\\t%1, %2, %0"
7324 [(set_attr "type" "fp")])
7325
7326 (define_insn "adddf3"
7327 [(set (match_operand:DF 0 "register_operand" "=e")
7328 (plus:DF (match_operand:DF 1 "register_operand" "e")
7329 (match_operand:DF 2 "register_operand" "e")))]
7330 "TARGET_FPU"
7331 "faddd\\t%1, %2, %0"
7332 [(set_attr "type" "fp")
7333 (set_attr "fptype" "double")])
7334
7335 (define_insn "addsf3"
7336 [(set (match_operand:SF 0 "register_operand" "=f")
7337 (plus:SF (match_operand:SF 1 "register_operand" "f")
7338 (match_operand:SF 2 "register_operand" "f")))]
7339 "TARGET_FPU"
7340 "fadds\\t%1, %2, %0"
7341 [(set_attr "type" "fp")])
7342
7343 (define_expand "subtf3"
7344 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7345 (minus:TF (match_operand:TF 1 "general_operand" "")
7346 (match_operand:TF 2 "general_operand" "")))]
7347 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7348 "
7349 {
7350 if (! TARGET_HARD_QUAD)
7351 {
7352 rtx slot0, slot1, slot2;
7353
7354 if (GET_CODE (operands[0]) != MEM)
7355 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7356 else
7357 slot0 = operands[0];
7358 if (GET_CODE (operands[1]) != MEM)
7359 {
7360 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7361 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7362 }
7363 else
7364 slot1 = operands[1];
7365 if (GET_CODE (operands[2]) != MEM)
7366 {
7367 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7368 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7369 }
7370 else
7371 slot2 = operands[2];
7372
7373 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7374 VOIDmode, 3,
7375 XEXP (slot0, 0), Pmode,
7376 XEXP (slot1, 0), Pmode,
7377 XEXP (slot2, 0), Pmode);
7378
7379 if (GET_CODE (operands[0]) != MEM)
7380 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7381 DONE;
7382 }
7383 }")
7384
7385 (define_insn "*subtf3_hq"
7386 [(set (match_operand:TF 0 "register_operand" "=e")
7387 (minus:TF (match_operand:TF 1 "register_operand" "e")
7388 (match_operand:TF 2 "register_operand" "e")))]
7389 "TARGET_FPU && TARGET_HARD_QUAD"
7390 "fsubq\\t%1, %2, %0"
7391 [(set_attr "type" "fp")])
7392
7393 (define_insn "subdf3"
7394 [(set (match_operand:DF 0 "register_operand" "=e")
7395 (minus:DF (match_operand:DF 1 "register_operand" "e")
7396 (match_operand:DF 2 "register_operand" "e")))]
7397 "TARGET_FPU"
7398 "fsubd\\t%1, %2, %0"
7399 [(set_attr "type" "fp")
7400 (set_attr "fptype" "double")])
7401
7402 (define_insn "subsf3"
7403 [(set (match_operand:SF 0 "register_operand" "=f")
7404 (minus:SF (match_operand:SF 1 "register_operand" "f")
7405 (match_operand:SF 2 "register_operand" "f")))]
7406 "TARGET_FPU"
7407 "fsubs\\t%1, %2, %0"
7408 [(set_attr "type" "fp")])
7409
7410 (define_expand "multf3"
7411 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7412 (mult:TF (match_operand:TF 1 "general_operand" "")
7413 (match_operand:TF 2 "general_operand" "")))]
7414 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7415 "
7416 {
7417 if (! TARGET_HARD_QUAD)
7418 {
7419 rtx slot0, slot1, slot2;
7420
7421 if (GET_CODE (operands[0]) != MEM)
7422 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7423 else
7424 slot0 = operands[0];
7425 if (GET_CODE (operands[1]) != MEM)
7426 {
7427 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7428 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7429 }
7430 else
7431 slot1 = operands[1];
7432 if (GET_CODE (operands[2]) != MEM)
7433 {
7434 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7435 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7436 }
7437 else
7438 slot2 = operands[2];
7439
7440 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7441 VOIDmode, 3,
7442 XEXP (slot0, 0), Pmode,
7443 XEXP (slot1, 0), Pmode,
7444 XEXP (slot2, 0), Pmode);
7445
7446 if (GET_CODE (operands[0]) != MEM)
7447 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7448 DONE;
7449 }
7450 }")
7451
7452 (define_insn "*multf3_hq"
7453 [(set (match_operand:TF 0 "register_operand" "=e")
7454 (mult:TF (match_operand:TF 1 "register_operand" "e")
7455 (match_operand:TF 2 "register_operand" "e")))]
7456 "TARGET_FPU && TARGET_HARD_QUAD"
7457 "fmulq\\t%1, %2, %0"
7458 [(set_attr "type" "fpmul")])
7459
7460 (define_insn "muldf3"
7461 [(set (match_operand:DF 0 "register_operand" "=e")
7462 (mult:DF (match_operand:DF 1 "register_operand" "e")
7463 (match_operand:DF 2 "register_operand" "e")))]
7464 "TARGET_FPU"
7465 "fmuld\\t%1, %2, %0"
7466 [(set_attr "type" "fpmul")
7467 (set_attr "fptype" "double")])
7468
7469 (define_insn "mulsf3"
7470 [(set (match_operand:SF 0 "register_operand" "=f")
7471 (mult:SF (match_operand:SF 1 "register_operand" "f")
7472 (match_operand:SF 2 "register_operand" "f")))]
7473 "TARGET_FPU"
7474 "fmuls\\t%1, %2, %0"
7475 [(set_attr "type" "fpmul")])
7476
7477 (define_insn "*muldf3_extend"
7478 [(set (match_operand:DF 0 "register_operand" "=e")
7479 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7480 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7481 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7482 "fsmuld\\t%1, %2, %0"
7483 [(set_attr "type" "fpmul")
7484 (set_attr "fptype" "double")])
7485
7486 (define_insn "*multf3_extend"
7487 [(set (match_operand:TF 0 "register_operand" "=e")
7488 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7489 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7490 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7491 "fdmulq\\t%1, %2, %0"
7492 [(set_attr "type" "fpmul")])
7493
7494 (define_expand "divtf3"
7495 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7496 (div:TF (match_operand:TF 1 "general_operand" "")
7497 (match_operand:TF 2 "general_operand" "")))]
7498 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7499 "
7500 {
7501 if (! TARGET_HARD_QUAD)
7502 {
7503 rtx slot0, slot1, slot2;
7504
7505 if (GET_CODE (operands[0]) != MEM)
7506 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7507 else
7508 slot0 = operands[0];
7509 if (GET_CODE (operands[1]) != MEM)
7510 {
7511 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7512 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7513 }
7514 else
7515 slot1 = operands[1];
7516 if (GET_CODE (operands[2]) != MEM)
7517 {
7518 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7519 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7520 }
7521 else
7522 slot2 = operands[2];
7523
7524 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7525 VOIDmode, 3,
7526 XEXP (slot0, 0), Pmode,
7527 XEXP (slot1, 0), Pmode,
7528 XEXP (slot2, 0), Pmode);
7529
7530 if (GET_CODE (operands[0]) != MEM)
7531 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7532 DONE;
7533 }
7534 }")
7535
7536 ;; don't have timing for quad-prec. divide.
7537 (define_insn "*divtf3_hq"
7538 [(set (match_operand:TF 0 "register_operand" "=e")
7539 (div:TF (match_operand:TF 1 "register_operand" "e")
7540 (match_operand:TF 2 "register_operand" "e")))]
7541 "TARGET_FPU && TARGET_HARD_QUAD"
7542 "fdivq\\t%1, %2, %0"
7543 [(set_attr "type" "fpdivd")])
7544
7545 (define_insn "divdf3"
7546 [(set (match_operand:DF 0 "register_operand" "=e")
7547 (div:DF (match_operand:DF 1 "register_operand" "e")
7548 (match_operand:DF 2 "register_operand" "e")))]
7549 "TARGET_FPU"
7550 "fdivd\\t%1, %2, %0"
7551 [(set_attr "type" "fpdivd")
7552 (set_attr "fptype" "double")])
7553
7554 (define_insn "divsf3"
7555 [(set (match_operand:SF 0 "register_operand" "=f")
7556 (div:SF (match_operand:SF 1 "register_operand" "f")
7557 (match_operand:SF 2 "register_operand" "f")))]
7558 "TARGET_FPU"
7559 "fdivs\\t%1, %2, %0"
7560 [(set_attr "type" "fpdivs")])
7561
7562 (define_expand "negtf2"
7563 [(set (match_operand:TF 0 "register_operand" "=e,e")
7564 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7565 "TARGET_FPU"
7566 "")
7567
7568 (define_insn "*negtf2_notv9"
7569 [(set (match_operand:TF 0 "register_operand" "=e,e")
7570 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7571 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7572 "TARGET_FPU
7573 && ! TARGET_V9"
7574 "@
7575 fnegs\\t%0, %0
7576 #"
7577 [(set_attr "type" "fpmove,*")
7578 (set_attr "length" "*,2")])
7579
7580 (define_split
7581 [(set (match_operand:TF 0 "register_operand" "")
7582 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7583 "TARGET_FPU
7584 && ! TARGET_V9
7585 && reload_completed
7586 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7587 [(set (match_dup 2) (neg:SF (match_dup 3)))
7588 (set (match_dup 4) (match_dup 5))
7589 (set (match_dup 6) (match_dup 7))]
7590 "if (GET_CODE (operands[0]) == SUBREG)
7591 operands[0] = alter_subreg (operands[0]);
7592 if (GET_CODE (operands[1]) == SUBREG)
7593 operands[1] = alter_subreg (operands[1]);
7594 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7595 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7596 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7597 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7598 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7599 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7600
7601 (define_insn "*negtf2_v9"
7602 [(set (match_operand:TF 0 "register_operand" "=e,e")
7603 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7604 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7605 "TARGET_FPU && TARGET_V9"
7606 "@
7607 fnegd\\t%0, %0
7608 #"
7609 [(set_attr "type" "fpmove,*")
7610 (set_attr "length" "*,2")
7611 (set_attr "fptype" "double")])
7612
7613 (define_split
7614 [(set (match_operand:TF 0 "register_operand" "")
7615 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7616 "TARGET_FPU
7617 && TARGET_V9
7618 && reload_completed
7619 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7620 [(set (match_dup 2) (neg:DF (match_dup 3)))
7621 (set (match_dup 4) (match_dup 5))]
7622 "if (GET_CODE (operands[0]) == SUBREG)
7623 operands[0] = alter_subreg (operands[0]);
7624 if (GET_CODE (operands[1]) == SUBREG)
7625 operands[1] = alter_subreg (operands[1]);
7626 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7627 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7628 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7629 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7630
7631 (define_expand "negdf2"
7632 [(set (match_operand:DF 0 "register_operand" "")
7633 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7634 "TARGET_FPU"
7635 "")
7636
7637 (define_insn "*negdf2_notv9"
7638 [(set (match_operand:DF 0 "register_operand" "=e,e")
7639 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7640 "TARGET_FPU && ! TARGET_V9"
7641 "@
7642 fnegs\\t%0, %0
7643 #"
7644 [(set_attr "type" "fpmove,*")
7645 (set_attr "length" "*,2")])
7646
7647 (define_split
7648 [(set (match_operand:DF 0 "register_operand" "")
7649 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7650 "TARGET_FPU
7651 && ! TARGET_V9
7652 && reload_completed
7653 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7654 [(set (match_dup 2) (neg:SF (match_dup 3)))
7655 (set (match_dup 4) (match_dup 5))]
7656 "if (GET_CODE (operands[0]) == SUBREG)
7657 operands[0] = alter_subreg (operands[0]);
7658 if (GET_CODE (operands[1]) == SUBREG)
7659 operands[1] = alter_subreg (operands[1]);
7660 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7661 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7662 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7663 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7664
7665 (define_insn "*negdf2_v9"
7666 [(set (match_operand:DF 0 "register_operand" "=e")
7667 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7668 "TARGET_FPU && TARGET_V9"
7669 "fnegd\\t%1, %0"
7670 [(set_attr "type" "fpmove")
7671 (set_attr "fptype" "double")])
7672
7673 (define_insn "negsf2"
7674 [(set (match_operand:SF 0 "register_operand" "=f")
7675 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7676 "TARGET_FPU"
7677 "fnegs\\t%1, %0"
7678 [(set_attr "type" "fpmove")])
7679
7680 (define_expand "abstf2"
7681 [(set (match_operand:TF 0 "register_operand" "")
7682 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7683 "TARGET_FPU"
7684 "")
7685
7686 (define_insn "*abstf2_notv9"
7687 [(set (match_operand:TF 0 "register_operand" "=e,e")
7688 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7689 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7690 "TARGET_FPU && ! TARGET_V9"
7691 "@
7692 fabss\\t%0, %0
7693 #"
7694 [(set_attr "type" "fpmove,*")
7695 (set_attr "length" "*,2")])
7696
7697 (define_split
7698 [(set (match_operand:TF 0 "register_operand" "")
7699 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7700 "TARGET_FPU
7701 && ! TARGET_V9
7702 && reload_completed
7703 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7704 [(set (match_dup 2) (abs:SF (match_dup 3)))
7705 (set (match_dup 4) (match_dup 5))
7706 (set (match_dup 6) (match_dup 7))]
7707 "if (GET_CODE (operands[0]) == SUBREG)
7708 operands[0] = alter_subreg (operands[0]);
7709 if (GET_CODE (operands[1]) == SUBREG)
7710 operands[1] = alter_subreg (operands[1]);
7711 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7712 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7713 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7714 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7715 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7716 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7717
7718 (define_insn "*abstf2_hq_v9"
7719 [(set (match_operand:TF 0 "register_operand" "=e,e")
7720 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7721 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7722 "@
7723 fabsd\\t%0, %0
7724 fabsq\\t%1, %0"
7725 [(set_attr "type" "fpmove")
7726 (set_attr "fptype" "double,*")])
7727
7728 (define_insn "*abstf2_v9"
7729 [(set (match_operand:TF 0 "register_operand" "=e,e")
7730 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7731 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7732 "@
7733 fabsd\\t%0, %0
7734 #"
7735 [(set_attr "type" "fpmove,*")
7736 (set_attr "length" "*,2")
7737 (set_attr "fptype" "double,*")])
7738
7739 (define_split
7740 [(set (match_operand:TF 0 "register_operand" "")
7741 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7742 "TARGET_FPU
7743 && TARGET_V9
7744 && reload_completed
7745 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7746 [(set (match_dup 2) (abs:DF (match_dup 3)))
7747 (set (match_dup 4) (match_dup 5))]
7748 "if (GET_CODE (operands[0]) == SUBREG)
7749 operands[0] = alter_subreg (operands[0]);
7750 if (GET_CODE (operands[1]) == SUBREG)
7751 operands[1] = alter_subreg (operands[1]);
7752 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7753 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7754 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7755 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7756
7757 (define_expand "absdf2"
7758 [(set (match_operand:DF 0 "register_operand" "")
7759 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7760 "TARGET_FPU"
7761 "")
7762
7763 (define_insn "*absdf2_notv9"
7764 [(set (match_operand:DF 0 "register_operand" "=e,e")
7765 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7766 "TARGET_FPU && ! TARGET_V9"
7767 "@
7768 fabss\\t%0, %0
7769 #"
7770 [(set_attr "type" "fpmove,*")
7771 (set_attr "length" "*,2")])
7772
7773 (define_split
7774 [(set (match_operand:DF 0 "register_operand" "")
7775 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7776 "TARGET_FPU
7777 && ! TARGET_V9
7778 && reload_completed
7779 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7780 [(set (match_dup 2) (abs:SF (match_dup 3)))
7781 (set (match_dup 4) (match_dup 5))]
7782 "if (GET_CODE (operands[0]) == SUBREG)
7783 operands[0] = alter_subreg (operands[0]);
7784 if (GET_CODE (operands[1]) == SUBREG)
7785 operands[1] = alter_subreg (operands[1]);
7786 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7787 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7788 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7789 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7790
7791 (define_insn "*absdf2_v9"
7792 [(set (match_operand:DF 0 "register_operand" "=e")
7793 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7794 "TARGET_FPU && TARGET_V9"
7795 "fabsd\\t%1, %0"
7796 [(set_attr "type" "fpmove")
7797 (set_attr "fptype" "double")])
7798
7799 (define_insn "abssf2"
7800 [(set (match_operand:SF 0 "register_operand" "=f")
7801 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7802 "TARGET_FPU"
7803 "fabss\\t%1, %0"
7804 [(set_attr "type" "fpmove")])
7805
7806 (define_expand "sqrttf2"
7807 [(set (match_operand:TF 0 "register_operand" "=e")
7808 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7809 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7810 "
7811 {
7812 if (! TARGET_HARD_QUAD)
7813 {
7814 rtx slot0, slot1;
7815
7816 if (GET_CODE (operands[0]) != MEM)
7817 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7818 else
7819 slot0 = operands[0];
7820 if (GET_CODE (operands[1]) != MEM)
7821 {
7822 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7823 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7824 }
7825 else
7826 slot1 = operands[1];
7827
7828 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7829 VOIDmode, 2,
7830 XEXP (slot0, 0), Pmode,
7831 XEXP (slot1, 0), Pmode);
7832
7833 if (GET_CODE (operands[0]) != MEM)
7834 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7835 DONE;
7836 }
7837 }")
7838
7839 (define_insn "*sqrttf2_hq"
7840 [(set (match_operand:TF 0 "register_operand" "=e")
7841 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7842 "TARGET_FPU && TARGET_HARD_QUAD"
7843 "fsqrtq\\t%1, %0"
7844 [(set_attr "type" "fpsqrtd")])
7845
7846 (define_insn "sqrtdf2"
7847 [(set (match_operand:DF 0 "register_operand" "=e")
7848 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7849 "TARGET_FPU"
7850 "fsqrtd\\t%1, %0"
7851 [(set_attr "type" "fpsqrtd")
7852 (set_attr "fptype" "double")])
7853
7854 (define_insn "sqrtsf2"
7855 [(set (match_operand:SF 0 "register_operand" "=f")
7856 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7857 "TARGET_FPU"
7858 "fsqrts\\t%1, %0"
7859 [(set_attr "type" "fpsqrts")])
7860 \f
7861 ;;- arithmetic shift instructions
7862
7863 (define_insn "ashlsi3"
7864 [(set (match_operand:SI 0 "register_operand" "=r")
7865 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7866 (match_operand:SI 2 "arith_operand" "rI")))]
7867 ""
7868 "*
7869 {
7870 if (GET_CODE (operands[2]) == CONST_INT
7871 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7872 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7873
7874 return \"sll\\t%1, %2, %0\";
7875 }"
7876 [(set_attr "type" "shift")])
7877
7878 ;; We special case multiplication by two, as add can be done
7879 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7880 (define_insn "*ashlsi3_const1"
7881 [(set (match_operand:SI 0 "register_operand" "=r")
7882 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7883 (const_int 1)))]
7884 ""
7885 "add\\t%1, %1, %0")
7886
7887 (define_expand "ashldi3"
7888 [(set (match_operand:DI 0 "register_operand" "=r")
7889 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7890 (match_operand:SI 2 "arith_operand" "rI")))]
7891 "TARGET_ARCH64 || TARGET_V8PLUS"
7892 "
7893 {
7894 if (! TARGET_ARCH64)
7895 {
7896 if (GET_CODE (operands[2]) == CONST_INT)
7897 FAIL;
7898 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7899 DONE;
7900 }
7901 }")
7902
7903 ;; We special case multiplication by two, as add can be done
7904 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7905 (define_insn "*ashldi3_const1"
7906 [(set (match_operand:DI 0 "register_operand" "=r")
7907 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7908 (const_int 1)))]
7909 "TARGET_ARCH64"
7910 "add\\t%1, %1, %0")
7911
7912 (define_insn "*ashldi3_sp64"
7913 [(set (match_operand:DI 0 "register_operand" "=r")
7914 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7915 (match_operand:SI 2 "arith_operand" "rI")))]
7916 "TARGET_ARCH64"
7917 "*
7918 {
7919 if (GET_CODE (operands[2]) == CONST_INT
7920 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7921 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7922
7923 return \"sllx\\t%1, %2, %0\";
7924 }"
7925 [(set_attr "type" "shift")])
7926
7927 ;; XXX UGH!
7928 (define_insn "ashldi3_v8plus"
7929 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7930 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7931 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7932 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7933 "TARGET_V8PLUS"
7934 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7935 [(set_attr "type" "multi")
7936 (set_attr "length" "5,5,6")])
7937
7938 ;; Optimize (1LL<<x)-1
7939 ;; XXX this also needs to be fixed to handle equal subregs
7940 ;; XXX first before we could re-enable it.
7941 ;(define_insn ""
7942 ; [(set (match_operand:DI 0 "register_operand" "=h")
7943 ; (plus:DI (ashift:DI (const_int 1)
7944 ; (match_operand:SI 1 "arith_operand" "rI"))
7945 ; (const_int -1)))]
7946 ; "0 && TARGET_V8PLUS"
7947 ; "*
7948 ;{
7949 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7950 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7951 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7952 ;}"
7953 ; [(set_attr "type" "multi")
7954 ; (set_attr "length" "4")])
7955
7956 (define_insn "*cmp_cc_ashift_1"
7957 [(set (reg:CC_NOOV 100)
7958 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7959 (const_int 1))
7960 (const_int 0)))]
7961 ""
7962 "addcc\\t%0, %0, %%g0"
7963 [(set_attr "type" "compare")])
7964
7965 (define_insn "*cmp_cc_set_ashift_1"
7966 [(set (reg:CC_NOOV 100)
7967 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7968 (const_int 1))
7969 (const_int 0)))
7970 (set (match_operand:SI 0 "register_operand" "=r")
7971 (ashift:SI (match_dup 1) (const_int 1)))]
7972 ""
7973 "addcc\\t%1, %1, %0"
7974 [(set_attr "type" "compare")])
7975
7976 (define_insn "ashrsi3"
7977 [(set (match_operand:SI 0 "register_operand" "=r")
7978 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7979 (match_operand:SI 2 "arith_operand" "rI")))]
7980 ""
7981 "*
7982 {
7983 if (GET_CODE (operands[2]) == CONST_INT
7984 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7985 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7986
7987 return \"sra\\t%1, %2, %0\";
7988 }"
7989 [(set_attr "type" "shift")])
7990
7991 (define_insn "*ashrsi3_extend"
7992 [(set (match_operand:DI 0 "register_operand" "=r")
7993 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7994 (match_operand:SI 2 "arith_operand" "r"))))]
7995 "TARGET_ARCH64"
7996 "sra\\t%1, %2, %0"
7997 [(set_attr "type" "shift")])
7998
7999 ;; This handles the case as above, but with constant shift instead of
8000 ;; register. Combiner "simplifies" it for us a little bit though.
8001 (define_insn "*ashrsi3_extend2"
8002 [(set (match_operand:DI 0 "register_operand" "=r")
8003 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8004 (const_int 32))
8005 (match_operand:SI 2 "small_int_or_double" "n")))]
8006 "TARGET_ARCH64
8007 && ((GET_CODE (operands[2]) == CONST_INT
8008 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8009 || (GET_CODE (operands[2]) == CONST_DOUBLE
8010 && !CONST_DOUBLE_HIGH (operands[2])
8011 && CONST_DOUBLE_LOW (operands[2]) >= 32
8012 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8013 "*
8014 {
8015 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8016
8017 return \"sra\\t%1, %2, %0\";
8018 }"
8019 [(set_attr "type" "shift")])
8020
8021 (define_expand "ashrdi3"
8022 [(set (match_operand:DI 0 "register_operand" "=r")
8023 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8024 (match_operand:SI 2 "arith_operand" "rI")))]
8025 "TARGET_ARCH64 || TARGET_V8PLUS"
8026 "
8027 {
8028 if (! TARGET_ARCH64)
8029 {
8030 if (GET_CODE (operands[2]) == CONST_INT)
8031 FAIL; /* prefer generic code in this case */
8032 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8033 DONE;
8034 }
8035 }")
8036
8037 (define_insn ""
8038 [(set (match_operand:DI 0 "register_operand" "=r")
8039 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8040 (match_operand:SI 2 "arith_operand" "rI")))]
8041 "TARGET_ARCH64"
8042 "*
8043 {
8044 if (GET_CODE (operands[2]) == CONST_INT
8045 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8046 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8047
8048 return \"srax\\t%1, %2, %0\";
8049 }"
8050 [(set_attr "type" "shift")])
8051
8052 ;; XXX
8053 (define_insn "ashrdi3_v8plus"
8054 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8055 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8056 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8057 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8058 "TARGET_V8PLUS"
8059 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8060 [(set_attr "type" "multi")
8061 (set_attr "length" "5,5,6")])
8062
8063 (define_insn "lshrsi3"
8064 [(set (match_operand:SI 0 "register_operand" "=r")
8065 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8066 (match_operand:SI 2 "arith_operand" "rI")))]
8067 ""
8068 "*
8069 {
8070 if (GET_CODE (operands[2]) == CONST_INT
8071 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8072 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8073
8074 return \"srl\\t%1, %2, %0\";
8075 }"
8076 [(set_attr "type" "shift")])
8077
8078 ;; This handles the case where
8079 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8080 ;; but combiner "simplifies" it for us.
8081 (define_insn "*lshrsi3_extend"
8082 [(set (match_operand:DI 0 "register_operand" "=r")
8083 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8084 (match_operand:SI 2 "arith_operand" "r")) 0)
8085 (match_operand 3 "" "")))]
8086 "TARGET_ARCH64
8087 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8088 && CONST_DOUBLE_HIGH (operands[3]) == 0
8089 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8090 || (HOST_BITS_PER_WIDE_INT >= 64
8091 && GET_CODE (operands[3]) == CONST_INT
8092 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8093 "srl\\t%1, %2, %0"
8094 [(set_attr "type" "shift")])
8095
8096 ;; This handles the case where
8097 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8098 ;; but combiner "simplifies" it for us.
8099 (define_insn "*lshrsi3_extend2"
8100 [(set (match_operand:DI 0 "register_operand" "=r")
8101 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8102 (match_operand 2 "small_int_or_double" "n")
8103 (const_int 32)))]
8104 "TARGET_ARCH64
8105 && ((GET_CODE (operands[2]) == CONST_INT
8106 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8107 || (GET_CODE (operands[2]) == CONST_DOUBLE
8108 && CONST_DOUBLE_HIGH (operands[2]) == 0
8109 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8110 "*
8111 {
8112 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8113
8114 return \"srl\\t%1, %2, %0\";
8115 }"
8116 [(set_attr "type" "shift")])
8117
8118 (define_expand "lshrdi3"
8119 [(set (match_operand:DI 0 "register_operand" "=r")
8120 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8121 (match_operand:SI 2 "arith_operand" "rI")))]
8122 "TARGET_ARCH64 || TARGET_V8PLUS"
8123 "
8124 {
8125 if (! TARGET_ARCH64)
8126 {
8127 if (GET_CODE (operands[2]) == CONST_INT)
8128 FAIL;
8129 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8130 DONE;
8131 }
8132 }")
8133
8134 (define_insn ""
8135 [(set (match_operand:DI 0 "register_operand" "=r")
8136 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8137 (match_operand:SI 2 "arith_operand" "rI")))]
8138 "TARGET_ARCH64"
8139 "*
8140 {
8141 if (GET_CODE (operands[2]) == CONST_INT
8142 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8143 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8144
8145 return \"srlx\\t%1, %2, %0\";
8146 }"
8147 [(set_attr "type" "shift")])
8148
8149 ;; XXX
8150 (define_insn "lshrdi3_v8plus"
8151 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8152 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8153 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8154 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8155 "TARGET_V8PLUS"
8156 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8157 [(set_attr "type" "multi")
8158 (set_attr "length" "5,5,6")])
8159
8160 (define_insn ""
8161 [(set (match_operand:SI 0 "register_operand" "=r")
8162 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8163 (const_int 32)) 4)
8164 (match_operand:SI 2 "small_int_or_double" "n")))]
8165 "TARGET_ARCH64
8166 && ((GET_CODE (operands[2]) == CONST_INT
8167 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8168 || (GET_CODE (operands[2]) == CONST_DOUBLE
8169 && !CONST_DOUBLE_HIGH (operands[2])
8170 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8171 "*
8172 {
8173 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8174
8175 return \"srax\\t%1, %2, %0\";
8176 }"
8177 [(set_attr "type" "shift")])
8178
8179 (define_insn ""
8180 [(set (match_operand:SI 0 "register_operand" "=r")
8181 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8182 (const_int 32)) 4)
8183 (match_operand:SI 2 "small_int_or_double" "n")))]
8184 "TARGET_ARCH64
8185 && ((GET_CODE (operands[2]) == CONST_INT
8186 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8187 || (GET_CODE (operands[2]) == CONST_DOUBLE
8188 && !CONST_DOUBLE_HIGH (operands[2])
8189 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8190 "*
8191 {
8192 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8193
8194 return \"srlx\\t%1, %2, %0\";
8195 }"
8196 [(set_attr "type" "shift")])
8197
8198 (define_insn ""
8199 [(set (match_operand:SI 0 "register_operand" "=r")
8200 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8201 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8202 (match_operand:SI 3 "small_int_or_double" "n")))]
8203 "TARGET_ARCH64
8204 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8205 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8206 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8207 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8208 "*
8209 {
8210 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8211
8212 return \"srax\\t%1, %2, %0\";
8213 }"
8214 [(set_attr "type" "shift")])
8215
8216 (define_insn ""
8217 [(set (match_operand:SI 0 "register_operand" "=r")
8218 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8219 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8220 (match_operand:SI 3 "small_int_or_double" "n")))]
8221 "TARGET_ARCH64
8222 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8223 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8224 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8225 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8226 "*
8227 {
8228 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8229
8230 return \"srlx\\t%1, %2, %0\";
8231 }"
8232 [(set_attr "type" "shift")])
8233 \f
8234 ;; Unconditional and other jump instructions
8235 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8236 ;; following insn is never executed. This saves us a nop. Dbx does not
8237 ;; handle such branches though, so we only use them when optimizing.
8238 (define_insn "jump"
8239 [(set (pc) (label_ref (match_operand 0 "" "")))]
8240 ""
8241 "*
8242 {
8243 /* TurboSparc is reported to have problems with
8244 with
8245 foo: b,a foo
8246 i.e. an empty loop with the annul bit set. The workaround is to use
8247 foo: b foo; nop
8248 instead. */
8249
8250 if (! TARGET_V9 && flag_delayed_branch
8251 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8252 == INSN_ADDRESSES (INSN_UID (insn))))
8253 return \"b\\t%l0%#\";
8254 else
8255 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8256 }"
8257 [(set_attr "type" "uncond_branch")])
8258
8259 (define_expand "tablejump"
8260 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8261 (use (label_ref (match_operand 1 "" "")))])]
8262 ""
8263 "
8264 {
8265 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8266 abort ();
8267
8268 /* In pic mode, our address differences are against the base of the
8269 table. Add that base value back in; CSE ought to be able to combine
8270 the two address loads. */
8271 if (flag_pic)
8272 {
8273 rtx tmp, tmp2;
8274 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8275 tmp2 = operands[0];
8276 if (CASE_VECTOR_MODE != Pmode)
8277 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8278 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8279 operands[0] = memory_address (Pmode, tmp);
8280 }
8281 }")
8282
8283 (define_insn "*tablejump_sp32"
8284 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8285 (use (label_ref (match_operand 1 "" "")))]
8286 "! TARGET_ARCH64"
8287 "jmp\\t%a0%#"
8288 [(set_attr "type" "uncond_branch")])
8289
8290 (define_insn "*tablejump_sp64"
8291 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8292 (use (label_ref (match_operand 1 "" "")))]
8293 "TARGET_ARCH64"
8294 "jmp\\t%a0%#"
8295 [(set_attr "type" "uncond_branch")])
8296
8297 ;; This pattern recognizes the "instruction" that appears in
8298 ;; a function call that wants a structure value,
8299 ;; to inform the called function if compiled with Sun CC.
8300 ;(define_insn "*unimp_insn"
8301 ; [(match_operand:SI 0 "immediate_operand" "")]
8302 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8303 ; "unimp\\t%0"
8304 ; [(set_attr "type" "marker")])
8305
8306 ;;- jump to subroutine
8307 (define_expand "call"
8308 ;; Note that this expression is not used for generating RTL.
8309 ;; All the RTL is generated explicitly below.
8310 [(call (match_operand 0 "call_operand" "")
8311 (match_operand 3 "" "i"))]
8312 ;; operands[2] is next_arg_register
8313 ;; operands[3] is struct_value_size_rtx.
8314 ""
8315 "
8316 {
8317 rtx fn_rtx, nregs_rtx;
8318
8319 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8320 abort ();
8321
8322 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8323 {
8324 /* This is really a PIC sequence. We want to represent
8325 it as a funny jump so its delay slots can be filled.
8326
8327 ??? But if this really *is* a CALL, will not it clobber the
8328 call-clobbered registers? We lose this if it is a JUMP_INSN.
8329 Why cannot we have delay slots filled if it were a CALL? */
8330
8331 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8332 emit_jump_insn
8333 (gen_rtx_PARALLEL
8334 (VOIDmode,
8335 gen_rtvec (3,
8336 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8337 operands[3],
8338 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8339 else
8340 emit_jump_insn
8341 (gen_rtx_PARALLEL
8342 (VOIDmode,
8343 gen_rtvec (2,
8344 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8345 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8346 goto finish_call;
8347 }
8348
8349 fn_rtx = operands[0];
8350
8351 /* Count the number of parameter registers being used by this call.
8352 if that argument is NULL, it means we are using them all, which
8353 means 6 on the sparc. */
8354 #if 0
8355 if (operands[2])
8356 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8357 else
8358 nregs_rtx = GEN_INT (6);
8359 #else
8360 nregs_rtx = const0_rtx;
8361 #endif
8362
8363 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8364 emit_call_insn
8365 (gen_rtx_PARALLEL
8366 (VOIDmode,
8367 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8368 operands[3],
8369 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8370 else
8371 emit_call_insn
8372 (gen_rtx_PARALLEL
8373 (VOIDmode,
8374 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8375 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8376
8377 finish_call:
8378 #if 0
8379 /* If this call wants a structure value,
8380 emit an unimp insn to let the called function know about this. */
8381 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8382 {
8383 rtx insn = emit_insn (operands[3]);
8384 SCHED_GROUP_P (insn) = 1;
8385 }
8386 #endif
8387
8388 DONE;
8389 }")
8390
8391 ;; We can't use the same pattern for these two insns, because then registers
8392 ;; in the address may not be properly reloaded.
8393
8394 (define_insn "*call_address_sp32"
8395 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8396 (match_operand 1 "" ""))
8397 (clobber (reg:SI 15))]
8398 ;;- Do not use operand 1 for most machines.
8399 "! TARGET_ARCH64"
8400 "call\\t%a0, %1%#"
8401 [(set_attr "type" "call")])
8402
8403 (define_insn "*call_symbolic_sp32"
8404 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8405 (match_operand 1 "" ""))
8406 (clobber (reg:SI 15))]
8407 ;;- Do not use operand 1 for most machines.
8408 "! TARGET_ARCH64"
8409 "call\\t%a0, %1%#"
8410 [(set_attr "type" "call")])
8411
8412 (define_insn "*call_address_sp64"
8413 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8414 (match_operand 1 "" ""))
8415 (clobber (reg:DI 15))]
8416 ;;- Do not use operand 1 for most machines.
8417 "TARGET_ARCH64"
8418 "call\\t%a0, %1%#"
8419 [(set_attr "type" "call")])
8420
8421 (define_insn "*call_symbolic_sp64"
8422 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8423 (match_operand 1 "" ""))
8424 (clobber (reg:DI 15))]
8425 ;;- Do not use operand 1 for most machines.
8426 "TARGET_ARCH64"
8427 "call\\t%a0, %1%#"
8428 [(set_attr "type" "call")])
8429
8430 ;; This is a call that wants a structure value.
8431 ;; There is no such critter for v9 (??? we may need one anyway).
8432 (define_insn "*call_address_struct_value_sp32"
8433 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8434 (match_operand 1 "" ""))
8435 (match_operand 2 "immediate_operand" "")
8436 (clobber (reg:SI 15))]
8437 ;;- Do not use operand 1 for most machines.
8438 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8439 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8440 [(set_attr "type" "call_no_delay_slot")])
8441
8442 ;; This is a call that wants a structure value.
8443 ;; There is no such critter for v9 (??? we may need one anyway).
8444 (define_insn "*call_symbolic_struct_value_sp32"
8445 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8446 (match_operand 1 "" ""))
8447 (match_operand 2 "immediate_operand" "")
8448 (clobber (reg:SI 15))]
8449 ;;- Do not use operand 1 for most machines.
8450 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8451 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8452 [(set_attr "type" "call_no_delay_slot")])
8453
8454 ;; This is a call that may want a structure value. This is used for
8455 ;; untyped_calls.
8456 (define_insn "*call_address_untyped_struct_value_sp32"
8457 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8458 (match_operand 1 "" ""))
8459 (match_operand 2 "immediate_operand" "")
8460 (clobber (reg:SI 15))]
8461 ;;- Do not use operand 1 for most machines.
8462 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8463 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8464 [(set_attr "type" "call_no_delay_slot")])
8465
8466 ;; This is a call that wants a structure value.
8467 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8468 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8469 (match_operand 1 "" ""))
8470 (match_operand 2 "immediate_operand" "")
8471 (clobber (reg:SI 15))]
8472 ;;- Do not use operand 1 for most machines.
8473 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8474 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8475 [(set_attr "type" "call_no_delay_slot")])
8476
8477 (define_expand "call_value"
8478 ;; Note that this expression is not used for generating RTL.
8479 ;; All the RTL is generated explicitly below.
8480 [(set (match_operand 0 "register_operand" "=rf")
8481 (call (match_operand 1 "" "")
8482 (match_operand 4 "" "")))]
8483 ;; operand 2 is stack_size_rtx
8484 ;; operand 3 is next_arg_register
8485 ""
8486 "
8487 {
8488 rtx fn_rtx, nregs_rtx;
8489 rtvec vec;
8490
8491 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8492 abort ();
8493
8494 fn_rtx = operands[1];
8495
8496 #if 0
8497 if (operands[3])
8498 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8499 else
8500 nregs_rtx = GEN_INT (6);
8501 #else
8502 nregs_rtx = const0_rtx;
8503 #endif
8504
8505 vec = gen_rtvec (2,
8506 gen_rtx_SET (VOIDmode, operands[0],
8507 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8508 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8509
8510 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8511
8512 DONE;
8513 }")
8514
8515 (define_insn "*call_value_address_sp32"
8516 [(set (match_operand 0 "" "=rf")
8517 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8518 (match_operand 2 "" "")))
8519 (clobber (reg:SI 15))]
8520 ;;- Do not use operand 2 for most machines.
8521 "! TARGET_ARCH64"
8522 "call\\t%a1, %2%#"
8523 [(set_attr "type" "call")])
8524
8525 (define_insn "*call_value_symbolic_sp32"
8526 [(set (match_operand 0 "" "=rf")
8527 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8528 (match_operand 2 "" "")))
8529 (clobber (reg:SI 15))]
8530 ;;- Do not use operand 2 for most machines.
8531 "! TARGET_ARCH64"
8532 "call\\t%a1, %2%#"
8533 [(set_attr "type" "call")])
8534
8535 (define_insn "*call_value_address_sp64"
8536 [(set (match_operand 0 "" "")
8537 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8538 (match_operand 2 "" "")))
8539 (clobber (reg:DI 15))]
8540 ;;- Do not use operand 2 for most machines.
8541 "TARGET_ARCH64"
8542 "call\\t%a1, %2%#"
8543 [(set_attr "type" "call")])
8544
8545 (define_insn "*call_value_symbolic_sp64"
8546 [(set (match_operand 0 "" "")
8547 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8548 (match_operand 2 "" "")))
8549 (clobber (reg:DI 15))]
8550 ;;- Do not use operand 2 for most machines.
8551 "TARGET_ARCH64"
8552 "call\\t%a1, %2%#"
8553 [(set_attr "type" "call")])
8554
8555 (define_expand "untyped_call"
8556 [(parallel [(call (match_operand 0 "" "")
8557 (const_int 0))
8558 (match_operand 1 "" "")
8559 (match_operand 2 "" "")])]
8560 ""
8561 "
8562 {
8563 int i;
8564
8565 /* Pass constm1 to indicate that it may expect a structure value, but
8566 we don't know what size it is. */
8567 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8568
8569 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8570 {
8571 rtx set = XVECEXP (operands[2], 0, i);
8572 emit_move_insn (SET_DEST (set), SET_SRC (set));
8573 }
8574
8575 /* The optimizer does not know that the call sets the function value
8576 registers we stored in the result block. We avoid problems by
8577 claiming that all hard registers are used and clobbered at this
8578 point. */
8579 emit_insn (gen_blockage ());
8580
8581 DONE;
8582 }")
8583
8584 ;;- tail calls
8585 (define_expand "sibcall"
8586 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8587 (return)])]
8588 ""
8589 "")
8590
8591 (define_insn "*sibcall_symbolic_sp32"
8592 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8593 (match_operand 1 "" ""))
8594 (return)]
8595 "! TARGET_ARCH64"
8596 "* return output_sibcall(insn, operands[0]);"
8597 [(set_attr "type" "sibcall")])
8598
8599 (define_insn "*sibcall_symbolic_sp64"
8600 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8601 (match_operand 1 "" ""))
8602 (return)]
8603 "TARGET_ARCH64"
8604 "* return output_sibcall(insn, operands[0]);"
8605 [(set_attr "type" "sibcall")])
8606
8607 (define_expand "sibcall_value"
8608 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8609 (call (match_operand 1 "" "") (const_int 0)))
8610 (return)])]
8611 ""
8612 "")
8613
8614 (define_insn "*sibcall_value_symbolic_sp32"
8615 [(set (match_operand 0 "" "=rf")
8616 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8617 (match_operand 2 "" "")))
8618 (return)]
8619 "! TARGET_ARCH64"
8620 "* return output_sibcall(insn, operands[1]);"
8621 [(set_attr "type" "sibcall")])
8622
8623 (define_insn "*sibcall_value_symbolic_sp64"
8624 [(set (match_operand 0 "" "")
8625 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8626 (match_operand 2 "" "")))
8627 (return)]
8628 "TARGET_ARCH64"
8629 "* return output_sibcall(insn, operands[1]);"
8630 [(set_attr "type" "sibcall")])
8631
8632 (define_expand "sibcall_epilogue"
8633 [(const_int 0)]
8634 ""
8635 "DONE;")
8636
8637 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8638 ;; all of memory. This blocks insns from being moved across this point.
8639
8640 (define_insn "blockage"
8641 [(unspec_volatile [(const_int 0)] 0)]
8642 ""
8643 ""
8644 [(set_attr "length" "0")])
8645
8646 ;; Prepare to return any type including a structure value.
8647
8648 (define_expand "untyped_return"
8649 [(match_operand:BLK 0 "memory_operand" "")
8650 (match_operand 1 "" "")]
8651 ""
8652 "
8653 {
8654 rtx valreg1 = gen_rtx_REG (DImode, 24);
8655 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8656 rtx result = operands[0];
8657
8658 if (! TARGET_ARCH64)
8659 {
8660 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8661 ? 15 : 31));
8662 rtx value = gen_reg_rtx (SImode);
8663
8664 /* Fetch the instruction where we will return to and see if it's an unimp
8665 instruction (the most significant 10 bits will be zero). If so,
8666 update the return address to skip the unimp instruction. */
8667 emit_move_insn (value,
8668 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8669 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8670 emit_insn (gen_update_return (rtnreg, value));
8671 }
8672
8673 /* Reload the function value registers. */
8674 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8675 emit_move_insn (valreg2,
8676 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8677
8678 /* Put USE insns before the return. */
8679 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8680 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8681
8682 /* Construct the return. */
8683 expand_null_return ();
8684
8685 DONE;
8686 }")
8687
8688 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8689 ;; and parts of the compiler don't want to believe that the add is needed.
8690
8691 (define_insn "update_return"
8692 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8693 (match_operand:SI 1 "register_operand" "r")] 1)]
8694 "! TARGET_ARCH64"
8695 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8696 [(set_attr "type" "multi")
8697 (set_attr "length" "3")])
8698 \f
8699 (define_insn "return"
8700 [(return)
8701 (use (reg:SI 31))]
8702 "! TARGET_EPILOGUE"
8703 "* return output_return (operands);"
8704 [(set_attr "type" "return")])
8705
8706 (define_peephole
8707 [(set (match_operand:SI 0 "register_operand" "=r")
8708 (match_operand:SI 1 "arith_operand" "rI"))
8709 (parallel [(return)
8710 (use (reg:SI 31))])]
8711 "sparc_return_peephole_ok (operands[0], operands[1])"
8712 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8713
8714 (define_insn "nop"
8715 [(const_int 0)]
8716 ""
8717 "nop")
8718
8719 (define_expand "indirect_jump"
8720 [(set (pc) (match_operand 0 "address_operand" "p"))]
8721 ""
8722 "")
8723
8724 (define_insn "*branch_sp32"
8725 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8726 "! TARGET_ARCH64"
8727 "jmp\\t%a0%#"
8728 [(set_attr "type" "uncond_branch")])
8729
8730 (define_insn "*branch_sp64"
8731 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8732 "TARGET_ARCH64"
8733 "jmp\\t%a0%#"
8734 [(set_attr "type" "uncond_branch")])
8735
8736 ;; ??? Doesn't work with -mflat.
8737 (define_expand "nonlocal_goto"
8738 [(match_operand:SI 0 "general_operand" "")
8739 (match_operand:SI 1 "general_operand" "")
8740 (match_operand:SI 2 "general_operand" "")
8741 (match_operand:SI 3 "" "")]
8742 ""
8743 "
8744 {
8745 #if 0
8746 rtx chain = operands[0];
8747 #endif
8748 rtx lab = operands[1];
8749 rtx stack = operands[2];
8750 rtx fp = operands[3];
8751 rtx labreg;
8752
8753 /* Trap instruction to flush all the register windows. */
8754 emit_insn (gen_flush_register_windows ());
8755
8756 /* Load the fp value for the containing fn into %fp. This is needed
8757 because STACK refers to %fp. Note that virtual register instantiation
8758 fails if the virtual %fp isn't set from a register. */
8759 if (GET_CODE (fp) != REG)
8760 fp = force_reg (Pmode, fp);
8761 emit_move_insn (virtual_stack_vars_rtx, fp);
8762
8763 /* Find the containing function's current nonlocal goto handler,
8764 which will do any cleanups and then jump to the label. */
8765 labreg = gen_rtx_REG (Pmode, 8);
8766 emit_move_insn (labreg, lab);
8767
8768 /* Restore %fp from stack pointer value for containing function.
8769 The restore insn that follows will move this to %sp,
8770 and reload the appropriate value into %fp. */
8771 emit_move_insn (frame_pointer_rtx, stack);
8772
8773 /* USE of frame_pointer_rtx added for consistency; not clear if
8774 really needed. */
8775 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8776 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8777
8778 #if 0
8779 /* Return, restoring reg window and jumping to goto handler. */
8780 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8781 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8782 {
8783 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8784 static_chain_rtx,
8785 chain));
8786 emit_barrier ();
8787 DONE;
8788 }
8789 /* Put in the static chain register the nonlocal label address. */
8790 emit_move_insn (static_chain_rtx, chain);
8791 #endif
8792
8793 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8794 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8795 emit_barrier ();
8796 DONE;
8797 }")
8798
8799 ;; Special trap insn to flush register windows.
8800 (define_insn "flush_register_windows"
8801 [(unspec_volatile [(const_int 0)] 1)]
8802 ""
8803 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8804 [(set_attr "type" "misc")])
8805
8806 (define_insn "goto_handler_and_restore"
8807 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8808 "GET_MODE (operands[0]) == Pmode"
8809 "jmp\\t%0+0\\n\\trestore"
8810 [(set_attr "type" "multi")
8811 (set_attr "length" "2")])
8812
8813 ;;(define_insn "goto_handler_and_restore_v9"
8814 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8815 ;; (match_operand:SI 1 "register_operand" "=r,r")
8816 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8817 ;; "TARGET_V9 && ! TARGET_ARCH64"
8818 ;; "@
8819 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8820 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8821 ;; [(set_attr "type" "multi")
8822 ;; (set_attr "length" "2,3")])
8823 ;;
8824 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8825 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8826 ;; (match_operand:DI 1 "register_operand" "=r,r")
8827 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8828 ;; "TARGET_V9 && TARGET_ARCH64"
8829 ;; "@
8830 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8831 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8832 ;; [(set_attr "type" "multi")
8833 ;; (set_attr "length" "2,3")])
8834
8835 ;; For __builtin_setjmp we need to flush register windows iff the function
8836 ;; calls alloca as well, because otherwise the register window might be
8837 ;; saved after %sp adjustement and thus setjmp would crash
8838 (define_expand "builtin_setjmp_setup"
8839 [(match_operand 0 "register_operand" "r")]
8840 ""
8841 "
8842 {
8843 emit_insn (gen_do_builtin_setjmp_setup ());
8844 DONE;
8845 }")
8846
8847 ;; ??? Should set length to zero when !current_function_calls_alloca,
8848 ;; ??? but there is no easy way to get at that definition. It would
8849 ;; ??? require including function.h into sparc-protos.h and that is
8850 ;; ??? likely not a good idea. -DaveM
8851 (define_insn "do_builtin_setjmp_setup"
8852 [(unspec_volatile [(const_int 0)] 5)]
8853 ""
8854 "*
8855 {
8856 if (!current_function_calls_alloca)
8857 return \"\";
8858 if (TARGET_V9)
8859 return \"flushw\";
8860 return \"ta\\t3\";
8861 }"
8862 [(set_attr "type" "misc")])
8863
8864 ;; Pattern for use after a setjmp to store FP and the return register
8865 ;; into the stack area.
8866
8867 (define_expand "setjmp"
8868 [(const_int 0)]
8869 ""
8870 "
8871 {
8872 if (TARGET_ARCH64)
8873 emit_insn (gen_setjmp_64 ());
8874 else
8875 emit_insn (gen_setjmp_32 ());
8876 DONE;
8877 }")
8878
8879 (define_expand "setjmp_32"
8880 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8881 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8882 ""
8883 "
8884 { operands[0] = frame_pointer_rtx; }")
8885
8886 (define_expand "setjmp_64"
8887 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8888 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8889 ""
8890 "
8891 { operands[0] = frame_pointer_rtx; }")
8892
8893 ;; Special pattern for the FLUSH instruction.
8894
8895 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8896 ; of the define_insn otherwise missing a mode. We make "flush", aka
8897 ; gen_flush, the default one since sparc_initialize_trampoline uses
8898 ; it on SImode mem values.
8899
8900 (define_insn "flush"
8901 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8902 ""
8903 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8904 [(set_attr "type" "misc")])
8905
8906 (define_insn "flushdi"
8907 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8908 ""
8909 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8910 [(set_attr "type" "misc")])
8911
8912 \f
8913 ;; find first set.
8914
8915 ;; The scan instruction searches from the most significant bit while ffs
8916 ;; searches from the least significant bit. The bit index and treatment of
8917 ;; zero also differ. It takes at least 7 instructions to get the proper
8918 ;; result. Here is an obvious 8 instruction sequence.
8919
8920 ;; XXX
8921 (define_insn "ffssi2"
8922 [(set (match_operand:SI 0 "register_operand" "=&r")
8923 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8924 (clobber (match_scratch:SI 2 "=&r"))]
8925 "TARGET_SPARCLITE || TARGET_SPARCLET"
8926 "*
8927 {
8928 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\";
8929 }"
8930 [(set_attr "type" "multi")
8931 (set_attr "length" "8")])
8932
8933 ;; ??? This should be a define expand, so that the extra instruction have
8934 ;; a chance of being optimized away.
8935
8936 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8937 ;; does, but no one uses that and we don't have a switch for it.
8938 ;
8939 ;(define_insn "ffsdi2"
8940 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8941 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8942 ; (clobber (match_scratch:DI 2 "=&r"))]
8943 ; "TARGET_ARCH64"
8944 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8945 ; [(set_attr "type" "multi")
8946 ; (set_attr "length" "4")])
8947
8948
8949 \f
8950 ;; Peepholes go at the end.
8951
8952 ;; Optimize consecutive loads or stores into ldd and std when possible.
8953 ;; The conditions in which we do this are very restricted and are
8954 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8955
8956 (define_peephole
8957 [(set (match_operand:SI 0 "memory_operand" "")
8958 (const_int 0))
8959 (set (match_operand:SI 1 "memory_operand" "")
8960 (const_int 0))]
8961 "TARGET_V9
8962 && ! MEM_VOLATILE_P (operands[0])
8963 && ! MEM_VOLATILE_P (operands[1])
8964 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
8965 "stx\\t%%g0, %0")
8966
8967 (define_peephole
8968 [(set (match_operand:SI 0 "memory_operand" "")
8969 (const_int 0))
8970 (set (match_operand:SI 1 "memory_operand" "")
8971 (const_int 0))]
8972 "TARGET_V9
8973 && ! MEM_VOLATILE_P (operands[0])
8974 && ! MEM_VOLATILE_P (operands[1])
8975 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
8976 "stx\\t%%g0, %1")
8977
8978 (define_peephole
8979 [(set (match_operand:SI 0 "register_operand" "=rf")
8980 (match_operand:SI 1 "memory_operand" ""))
8981 (set (match_operand:SI 2 "register_operand" "=rf")
8982 (match_operand:SI 3 "memory_operand" ""))]
8983 "registers_ok_for_ldd_peep (operands[0], operands[2])
8984 && ! MEM_VOLATILE_P (operands[1])
8985 && ! MEM_VOLATILE_P (operands[3])
8986 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8987 "ldd\\t%1, %0")
8988
8989 (define_peephole
8990 [(set (match_operand:SI 0 "memory_operand" "")
8991 (match_operand:SI 1 "register_operand" "rf"))
8992 (set (match_operand:SI 2 "memory_operand" "")
8993 (match_operand:SI 3 "register_operand" "rf"))]
8994 "registers_ok_for_ldd_peep (operands[1], operands[3])
8995 && ! MEM_VOLATILE_P (operands[0])
8996 && ! MEM_VOLATILE_P (operands[2])
8997 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8998 "std\\t%1, %0")
8999
9000 (define_peephole
9001 [(set (match_operand:SF 0 "register_operand" "=fr")
9002 (match_operand:SF 1 "memory_operand" ""))
9003 (set (match_operand:SF 2 "register_operand" "=fr")
9004 (match_operand:SF 3 "memory_operand" ""))]
9005 "registers_ok_for_ldd_peep (operands[0], operands[2])
9006 && ! MEM_VOLATILE_P (operands[1])
9007 && ! MEM_VOLATILE_P (operands[3])
9008 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9009 "ldd\\t%1, %0")
9010
9011 (define_peephole
9012 [(set (match_operand:SF 0 "memory_operand" "")
9013 (match_operand:SF 1 "register_operand" "fr"))
9014 (set (match_operand:SF 2 "memory_operand" "")
9015 (match_operand:SF 3 "register_operand" "fr"))]
9016 "registers_ok_for_ldd_peep (operands[1], operands[3])
9017 && ! MEM_VOLATILE_P (operands[0])
9018 && ! MEM_VOLATILE_P (operands[2])
9019 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9020 "std\\t%1, %0")
9021
9022 (define_peephole
9023 [(set (match_operand:SI 0 "register_operand" "=rf")
9024 (match_operand:SI 1 "memory_operand" ""))
9025 (set (match_operand:SI 2 "register_operand" "=rf")
9026 (match_operand:SI 3 "memory_operand" ""))]
9027 "registers_ok_for_ldd_peep (operands[2], operands[0])
9028 && ! MEM_VOLATILE_P (operands[3])
9029 && ! MEM_VOLATILE_P (operands[1])
9030 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9031 "ldd\\t%3, %2")
9032
9033 (define_peephole
9034 [(set (match_operand:SI 0 "memory_operand" "")
9035 (match_operand:SI 1 "register_operand" "rf"))
9036 (set (match_operand:SI 2 "memory_operand" "")
9037 (match_operand:SI 3 "register_operand" "rf"))]
9038 "registers_ok_for_ldd_peep (operands[3], operands[1])
9039 && ! MEM_VOLATILE_P (operands[2])
9040 && ! MEM_VOLATILE_P (operands[0])
9041 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9042 "std\\t%3, %2")
9043
9044 (define_peephole
9045 [(set (match_operand:SF 0 "register_operand" "=fr")
9046 (match_operand:SF 1 "memory_operand" ""))
9047 (set (match_operand:SF 2 "register_operand" "=fr")
9048 (match_operand:SF 3 "memory_operand" ""))]
9049 "registers_ok_for_ldd_peep (operands[2], operands[0])
9050 && ! MEM_VOLATILE_P (operands[3])
9051 && ! MEM_VOLATILE_P (operands[1])
9052 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9053 "ldd\\t%3, %2")
9054
9055 (define_peephole
9056 [(set (match_operand:SF 0 "memory_operand" "")
9057 (match_operand:SF 1 "register_operand" "fr"))
9058 (set (match_operand:SF 2 "memory_operand" "")
9059 (match_operand:SF 3 "register_operand" "fr"))]
9060 "registers_ok_for_ldd_peep (operands[3], operands[1])
9061 && ! MEM_VOLATILE_P (operands[2])
9062 && ! MEM_VOLATILE_P (operands[0])
9063 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9064 "std\\t%3, %2")
9065
9066 ;; Optimize the case of following a reg-reg move with a test
9067 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9068 ;; This can result from a float to fix conversion.
9069
9070 (define_peephole
9071 [(set (match_operand:SI 0 "register_operand" "=r")
9072 (match_operand:SI 1 "register_operand" "r"))
9073 (set (reg:CC 100)
9074 (compare:CC (match_operand:SI 2 "register_operand" "r")
9075 (const_int 0)))]
9076 "(rtx_equal_p (operands[2], operands[0])
9077 || rtx_equal_p (operands[2], operands[1]))
9078 && ! FP_REG_P (operands[0])
9079 && ! FP_REG_P (operands[1])"
9080 "orcc\\t%1, 0, %0")
9081
9082 (define_peephole
9083 [(set (match_operand:DI 0 "register_operand" "=r")
9084 (match_operand:DI 1 "register_operand" "r"))
9085 (set (reg:CCX 100)
9086 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9087 (const_int 0)))]
9088 "TARGET_ARCH64
9089 && (rtx_equal_p (operands[2], operands[0])
9090 || rtx_equal_p (operands[2], operands[1]))
9091 && ! FP_REG_P (operands[0])
9092 && ! FP_REG_P (operands[1])"
9093 "orcc\\t%1, 0, %0")
9094
9095 ;; Return peepholes. First the "normal" ones.
9096 ;; These are necessary to catch insns ending up in the epilogue delay list.
9097
9098 (define_insn "*return_qi"
9099 [(set (match_operand:QI 0 "restore_operand" "")
9100 (match_operand:QI 1 "arith_operand" "rI"))
9101 (return)]
9102 "! TARGET_EPILOGUE"
9103 "*
9104 {
9105 if (! TARGET_ARCH64 && current_function_returns_struct)
9106 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9107 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9108 || IN_OR_GLOBAL_P (operands[1])))
9109 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9110 else
9111 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9112 }"
9113 [(set_attr "type" "multi")
9114 (set_attr "length" "2")])
9115
9116 (define_insn "*return_hi"
9117 [(set (match_operand:HI 0 "restore_operand" "")
9118 (match_operand:HI 1 "arith_operand" "rI"))
9119 (return)]
9120 "! TARGET_EPILOGUE"
9121 "*
9122 {
9123 if (! TARGET_ARCH64 && current_function_returns_struct)
9124 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9125 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9126 || IN_OR_GLOBAL_P (operands[1])))
9127 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9128 else
9129 return \"ret\;restore %%g0, %1, %Y0\";
9130 }"
9131 [(set_attr "type" "multi")
9132 (set_attr "length" "2")])
9133
9134 (define_insn "*return_si"
9135 [(set (match_operand:SI 0 "restore_operand" "")
9136 (match_operand:SI 1 "arith_operand" "rI"))
9137 (return)]
9138 "! TARGET_EPILOGUE"
9139 "*
9140 {
9141 if (! TARGET_ARCH64 && current_function_returns_struct)
9142 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9143 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9144 || IN_OR_GLOBAL_P (operands[1])))
9145 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9146 else
9147 return \"ret\;restore %%g0, %1, %Y0\";
9148 }"
9149 [(set_attr "type" "multi")
9150 (set_attr "length" "2")])
9151
9152 ;; The following pattern is only generated by delayed-branch scheduling,
9153 ;; when the insn winds up in the epilogue. This can happen not only when
9154 ;; ! TARGET_FPU because we move complex types around by parts using
9155 ;; SF mode SUBREGs.
9156 (define_insn "*return_sf_no_fpu"
9157 [(set (match_operand:SF 0 "restore_operand" "=r")
9158 (match_operand:SF 1 "register_operand" "r"))
9159 (return)]
9160 "! TARGET_EPILOGUE"
9161 "*
9162 {
9163 if (! TARGET_ARCH64 && current_function_returns_struct)
9164 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9165 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9166 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9167 else
9168 return \"ret\;restore %%g0, %1, %Y0\";
9169 }"
9170 [(set_attr "type" "multi")
9171 (set_attr "length" "2")])
9172
9173 (define_insn "*return_df_no_fpu"
9174 [(set (match_operand:DF 0 "restore_operand" "=r")
9175 (match_operand:DF 1 "register_operand" "r"))
9176 (return)]
9177 "! TARGET_EPILOGUE && TARGET_ARCH64"
9178 "*
9179 {
9180 if (IN_OR_GLOBAL_P (operands[1]))
9181 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9182 else
9183 return \"ret\;restore %%g0, %1, %Y0\";
9184 }"
9185 [(set_attr "type" "multi")
9186 (set_attr "length" "2")])
9187
9188 (define_insn "*return_addsi"
9189 [(set (match_operand:SI 0 "restore_operand" "")
9190 (plus:SI (match_operand:SI 1 "register_operand" "r")
9191 (match_operand:SI 2 "arith_operand" "rI")))
9192 (return)]
9193 "! TARGET_EPILOGUE"
9194 "*
9195 {
9196 if (! TARGET_ARCH64 && current_function_returns_struct)
9197 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9198 /* If operands are global or in registers, can use return */
9199 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9200 && (GET_CODE (operands[2]) == CONST_INT
9201 || IN_OR_GLOBAL_P (operands[2])))
9202 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9203 else
9204 return \"ret\;restore %r1, %2, %Y0\";
9205 }"
9206 [(set_attr "type" "multi")
9207 (set_attr "length" "2")])
9208
9209 (define_insn "*return_losum_si"
9210 [(set (match_operand:SI 0 "restore_operand" "")
9211 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9212 (match_operand:SI 2 "immediate_operand" "in")))
9213 (return)]
9214 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9215 "*
9216 {
9217 if (! TARGET_ARCH64 && current_function_returns_struct)
9218 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9219 /* If operands are global or in registers, can use return */
9220 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9221 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9222 else
9223 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9224 }"
9225 [(set_attr "type" "multi")
9226 (set_attr "length" "2")])
9227
9228 (define_insn "*return_di"
9229 [(set (match_operand:DI 0 "restore_operand" "")
9230 (match_operand:DI 1 "arith_double_operand" "rHI"))
9231 (return)]
9232 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9233 "ret\;restore %%g0, %1, %Y0"
9234 [(set_attr "type" "multi")
9235 (set_attr "length" "2")])
9236
9237 (define_insn "*return_adddi"
9238 [(set (match_operand:DI 0 "restore_operand" "")
9239 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9240 (match_operand:DI 2 "arith_double_operand" "rHI")))
9241 (return)]
9242 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9243 "ret\;restore %r1, %2, %Y0"
9244 [(set_attr "type" "multi")
9245 (set_attr "length" "2")])
9246
9247 (define_insn "*return_losum_di"
9248 [(set (match_operand:DI 0 "restore_operand" "")
9249 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9250 (match_operand:DI 2 "immediate_operand" "in")))
9251 (return)]
9252 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9253 "ret\;restore %r1, %%lo(%a2), %Y0"
9254 [(set_attr "type" "multi")
9255 (set_attr "length" "2")])
9256
9257 ;; The following pattern is only generated by delayed-branch scheduling,
9258 ;; when the insn winds up in the epilogue.
9259 (define_insn "*return_sf"
9260 [(set (reg:SF 32)
9261 (match_operand:SF 0 "register_operand" "f"))
9262 (return)]
9263 "! TARGET_EPILOGUE"
9264 "ret\;fmovs\\t%0, %%f0"
9265 [(set_attr "type" "multi")
9266 (set_attr "length" "2")])
9267
9268 ;; Now peepholes to do a call followed by a jump.
9269
9270 (define_peephole
9271 [(parallel [(set (match_operand 0 "" "")
9272 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9273 (match_operand 2 "" "")))
9274 (clobber (reg:SI 15))])
9275 (set (pc) (label_ref (match_operand 3 "" "")))]
9276 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9277 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9278 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9279
9280 (define_peephole
9281 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9282 (match_operand 1 "" ""))
9283 (clobber (reg:SI 15))])
9284 (set (pc) (label_ref (match_operand 2 "" "")))]
9285 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9286 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9287 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9288
9289 (define_peephole
9290 [(parallel [(set (match_operand 0 "" "")
9291 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9292 (match_operand 2 "" "")))
9293 (clobber (reg:DI 15))])
9294 (set (pc) (label_ref (match_operand 3 "" "")))]
9295 "TARGET_ARCH64
9296 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9297 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9298 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9299
9300 (define_peephole
9301 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9302 (match_operand 1 "" ""))
9303 (clobber (reg:DI 15))])
9304 (set (pc) (label_ref (match_operand 2 "" "")))]
9305 "TARGET_ARCH64
9306 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9307 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9308 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9309 \f
9310 (define_expand "prologue"
9311 [(const_int 1)]
9312 "flag_pic && current_function_uses_pic_offset_table"
9313 "
9314 {
9315 load_pic_register ();
9316 DONE;
9317 }")
9318
9319 ;; We need to reload %l7 for -mflat -fpic,
9320 ;; otherwise %l7 should be preserved simply
9321 ;; by loading the function's register window
9322 (define_expand "exception_receiver"
9323 [(const_int 0)]
9324 "TARGET_FLAT && flag_pic"
9325 "
9326 {
9327 load_pic_register ();
9328 DONE;
9329 }")
9330
9331 ;; Likewise
9332 (define_expand "builtin_setjmp_receiver"
9333 [(label_ref (match_operand 0 "" ""))]
9334 "TARGET_FLAT && flag_pic"
9335 "
9336 {
9337 load_pic_register ();
9338 DONE;
9339 }")
9340 \f
9341 (define_insn "trap"
9342 [(trap_if (const_int 1) (const_int 5))]
9343 ""
9344 "ta\\t5"
9345 [(set_attr "type" "misc")])
9346
9347 (define_expand "conditional_trap"
9348 [(trap_if (match_operator 0 "noov_compare_op"
9349 [(match_dup 2) (match_dup 3)])
9350 (match_operand:SI 1 "arith_operand" ""))]
9351 ""
9352 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9353 sparc_compare_op0, sparc_compare_op1);
9354 operands[3] = const0_rtx;")
9355
9356 (define_insn ""
9357 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9358 (match_operand:SI 1 "arith_operand" "rM"))]
9359 ""
9360 "t%C0\\t%1"
9361 [(set_attr "type" "misc")])
9362
9363 (define_insn ""
9364 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9365 (match_operand:SI 1 "arith_operand" "rM"))]
9366 "TARGET_V9"
9367 "t%C0\\t%%xcc, %1"
9368 [(set_attr "type" "misc")])