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