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