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