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