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