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