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