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