explow.c (plus_constant_wide, [...]): New case.
[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 (SImode, 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 (SImode, 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 (SImode, 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 (SImode, 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 (SImode, 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 (SImode, operands[1]),
5941 highp)));
5942 }
5943 else
5944 {
5945 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5946 gen_lowpart (SImode, operands[1]),
5947 lowp));
5948 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5949 gen_highpart (SImode, operands[1]),
5950 highp));
5951 }
5952 DONE;
5953 }")
5954
5955 (define_split
5956 [(set (match_operand:DI 0 "register_operand" "")
5957 (minus:DI (match_operand:DI 1 "register_operand" "")
5958 (match_operand:DI 2 "register_operand" "")))
5959 (clobber (reg:CC 100))]
5960 "! TARGET_ARCH64
5961 && reload_completed"
5962 [(clobber (const_int 0))]
5963 "
5964 {
5965 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5966 gen_lowpart (SImode, operands[1]),
5967 gen_lowpart (SImode, operands[2])));
5968 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5969 gen_highpart (SImode, operands[1]),
5970 gen_highpart (SImode, operands[2])));
5971 DONE;
5972 }")
5973
5974 (define_insn ""
5975 [(set (match_operand:DI 0 "register_operand" "=r")
5976 (minus:DI (match_operand:DI 1 "register_operand" "r")
5977 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5978 (clobber (reg:CC 100))]
5979 "! TARGET_ARCH64"
5980 "#"
5981 [(set_attr "type" "multi")
5982 (set_attr "length" "2")])
5983
5984 (define_split
5985 [(set (match_operand:DI 0 "register_operand" "")
5986 (minus:DI (match_operand:DI 1 "register_operand" "")
5987 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5988 (clobber (reg:CC 100))]
5989 "! TARGET_ARCH64 && reload_completed"
5990 [(parallel [(set (reg:CC_NOOV 100)
5991 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5992 (const_int 0)))
5993 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5994 (set (match_dup 6)
5995 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5996 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5997 "operands[3] = gen_lowpart (SImode, operands[1]);
5998 operands[4] = gen_highpart (SImode, operands[1]);
5999 operands[5] = gen_lowpart (SImode, operands[0]);
6000 operands[6] = gen_highpart (SImode, operands[0]);")
6001
6002 (define_insn "*subdi3_sp64"
6003 [(set (match_operand:DI 0 "register_operand" "=r")
6004 (minus:DI (match_operand:DI 1 "register_operand" "r")
6005 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6006 "TARGET_ARCH64"
6007 "sub\\t%1, %2, %0"
6008 [(set_attr "type" "binary")
6009 (set_attr "length" "1")])
6010
6011 (define_expand "subsi3"
6012 [(set (match_operand:SI 0 "register_operand" "=r,d")
6013 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
6014 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
6015 ""
6016 "
6017 {
6018 if (arith_4096_operand(operands[2], SImode))
6019 {
6020 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6021 gen_rtx_PLUS (SImode, operands[1],
6022 GEN_INT(-4096))));
6023 DONE;
6024 }
6025 }")
6026
6027 (define_insn "*subsi3"
6028 [(set (match_operand:SI 0 "register_operand" "=r,d")
6029 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
6030 (match_operand:SI 2 "arith_operand" "rI,d")))]
6031 ""
6032 "@
6033 sub\\t%1, %2, %0
6034 fpsub32s\\t%1, %2, %0"
6035 [(set_attr "type" "ialu,fp")
6036 (set_attr "length" "1")])
6037
6038 (define_insn "*cmp_minus_cc"
6039 [(set (reg:CC_NOOV 100)
6040 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
6041 (match_operand:SI 1 "arith_operand" "rI"))
6042 (const_int 0)))]
6043 ""
6044 "subcc\\t%r0, %1, %%g0"
6045 [(set_attr "type" "compare")
6046 (set_attr "length" "1")])
6047
6048 (define_insn "*cmp_minus_ccx"
6049 [(set (reg:CCX_NOOV 100)
6050 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
6051 (match_operand:DI 1 "arith_double_operand" "rHI"))
6052 (const_int 0)))]
6053 "TARGET_ARCH64"
6054 "subcc\\t%0, %1, %%g0"
6055 [(set_attr "type" "compare")
6056 (set_attr "length" "1")])
6057
6058 (define_insn "cmp_minus_cc_set"
6059 [(set (reg:CC_NOOV 100)
6060 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
6061 (match_operand:SI 2 "arith_operand" "rI"))
6062 (const_int 0)))
6063 (set (match_operand:SI 0 "register_operand" "=r")
6064 (minus:SI (match_dup 1) (match_dup 2)))]
6065 ""
6066 "subcc\\t%r1, %2, %0"
6067 [(set_attr "type" "compare")
6068 (set_attr "length" "1")])
6069
6070 (define_insn "*cmp_minus_ccx_set"
6071 [(set (reg:CCX_NOOV 100)
6072 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
6073 (match_operand:DI 2 "arith_double_operand" "rHI"))
6074 (const_int 0)))
6075 (set (match_operand:DI 0 "register_operand" "=r")
6076 (minus:DI (match_dup 1) (match_dup 2)))]
6077 "TARGET_ARCH64"
6078 "subcc\\t%1, %2, %0"
6079 [(set_attr "type" "compare")
6080 (set_attr "length" "1")])
6081 \f
6082 ;; Integer Multiply/Divide.
6083
6084 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
6085 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
6086
6087 (define_insn "mulsi3"
6088 [(set (match_operand:SI 0 "register_operand" "=r")
6089 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6090 (match_operand:SI 2 "arith_operand" "rI")))]
6091 "TARGET_HARD_MUL"
6092 "smul\\t%1, %2, %0"
6093 [(set_attr "type" "imul")
6094 (set_attr "length" "1")])
6095
6096 (define_expand "muldi3"
6097 [(set (match_operand:DI 0 "register_operand" "=r")
6098 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6099 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6100 "TARGET_ARCH64 || TARGET_V8PLUS"
6101 "
6102 {
6103 if (TARGET_V8PLUS)
6104 {
6105 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
6106 DONE;
6107 }
6108 }")
6109
6110 (define_insn "*muldi3_sp64"
6111 [(set (match_operand:DI 0 "register_operand" "=r")
6112 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6113 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6114 "TARGET_ARCH64"
6115 "mulx\\t%1, %2, %0"
6116 [(set_attr "type" "imul")
6117 (set_attr "length" "1")])
6118
6119 ;; V8plus wide multiply.
6120 ;; XXX
6121 (define_insn "muldi3_v8plus"
6122 [(set (match_operand:DI 0 "register_operand" "=r,h")
6123 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6124 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
6125 (clobber (match_scratch:SI 3 "=&h,X"))
6126 (clobber (match_scratch:SI 4 "=&h,X"))]
6127 "TARGET_V8PLUS"
6128 "*
6129 {
6130 if (sparc_check_64 (operands[1], insn) <= 0)
6131 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6132 if (which_alternative == 1)
6133 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6134 if (GET_CODE (operands[2]) == CONST_INT)
6135 {
6136 if (which_alternative == 1)
6137 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6138 else
6139 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\";
6140 }
6141 if (sparc_check_64 (operands[2], insn) <= 0)
6142 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6143 if (which_alternative == 1)
6144 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\";
6145 else
6146 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\";
6147 }"
6148 [(set_attr "length" "9,8")])
6149
6150 (define_insn "*cmp_mul_set"
6151 [(set (reg:CC 100)
6152 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6153 (match_operand:SI 2 "arith_operand" "rI"))
6154 (const_int 0)))
6155 (set (match_operand:SI 0 "register_operand" "=r")
6156 (mult:SI (match_dup 1) (match_dup 2)))]
6157 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6158 "smulcc\\t%1, %2, %0"
6159 [(set_attr "type" "imul")
6160 (set_attr "length" "1")])
6161
6162 (define_expand "mulsidi3"
6163 [(set (match_operand:DI 0 "register_operand" "")
6164 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6165 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6166 "TARGET_HARD_MUL"
6167 "
6168 {
6169 if (CONSTANT_P (operands[2]))
6170 {
6171 if (TARGET_V8PLUS)
6172 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6173 operands[2]));
6174 else
6175 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6176 operands[2]));
6177 DONE;
6178 }
6179 if (TARGET_V8PLUS)
6180 {
6181 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6182 DONE;
6183 }
6184 }")
6185
6186 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6187 ;; registers can hold 64 bit values in the V8plus environment.
6188 ;; XXX
6189 (define_insn "mulsidi3_v8plus"
6190 [(set (match_operand:DI 0 "register_operand" "=h,r")
6191 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6192 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6193 (clobber (match_scratch:SI 3 "=X,&h"))]
6194 "TARGET_V8PLUS"
6195 "@
6196 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6197 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6198 [(set_attr "length" "2,3")])
6199
6200 ;; XXX
6201 (define_insn "const_mulsidi3_v8plus"
6202 [(set (match_operand:DI 0 "register_operand" "=h,r")
6203 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6204 (match_operand:SI 2 "small_int" "I,I")))
6205 (clobber (match_scratch:SI 3 "=X,&h"))]
6206 "TARGET_V8PLUS"
6207 "@
6208 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6209 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6210 [(set_attr "length" "2,3")])
6211
6212 ;; XXX
6213 (define_insn "*mulsidi3_sp32"
6214 [(set (match_operand:DI 0 "register_operand" "=r")
6215 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6216 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6217 "TARGET_HARD_MUL32"
6218 "*
6219 {
6220 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6221 }"
6222 [(set (attr "length")
6223 (if_then_else (eq_attr "isa" "sparclet")
6224 (const_int 1) (const_int 2)))])
6225
6226 (define_insn "*mulsidi3_sp64"
6227 [(set (match_operand:DI 0 "register_operand" "=r")
6228 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6229 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6230 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6231 "smul\\t%1, %2, %0"
6232 [(set_attr "length" "1")])
6233
6234 ;; Extra pattern, because sign_extend of a constant isn't valid.
6235
6236 ;; XXX
6237 (define_insn "const_mulsidi3_sp32"
6238 [(set (match_operand:DI 0 "register_operand" "=r")
6239 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6240 (match_operand:SI 2 "small_int" "I")))]
6241 "TARGET_HARD_MUL32"
6242 "*
6243 {
6244 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6245 }"
6246 [(set (attr "length")
6247 (if_then_else (eq_attr "isa" "sparclet")
6248 (const_int 1) (const_int 2)))])
6249
6250 (define_insn "const_mulsidi3_sp64"
6251 [(set (match_operand:DI 0 "register_operand" "=r")
6252 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6253 (match_operand:SI 2 "small_int" "I")))]
6254 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6255 "smul\\t%1, %2, %0"
6256 [(set_attr "length" "1")])
6257
6258 (define_expand "smulsi3_highpart"
6259 [(set (match_operand:SI 0 "register_operand" "")
6260 (truncate:SI
6261 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6262 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6263 (const_int 32))))]
6264 "TARGET_HARD_MUL && TARGET_ARCH32"
6265 "
6266 {
6267 if (CONSTANT_P (operands[2]))
6268 {
6269 if (TARGET_V8PLUS)
6270 {
6271 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6272 operands[1],
6273 operands[2],
6274 GEN_INT (32)));
6275 DONE;
6276 }
6277 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6278 DONE;
6279 }
6280 if (TARGET_V8PLUS)
6281 {
6282 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6283 operands[2], GEN_INT (32)));
6284 DONE;
6285 }
6286 }")
6287
6288 ;; XXX
6289 (define_insn "smulsi3_highpart_v8plus"
6290 [(set (match_operand:SI 0 "register_operand" "=h,r")
6291 (truncate:SI
6292 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6293 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6294 (match_operand:SI 3 "const_int_operand" "i,i"))))
6295 (clobber (match_scratch:SI 4 "=X,&h"))]
6296 "TARGET_V8PLUS"
6297 "@
6298 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6299 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6300 [(set_attr "length" "2")])
6301
6302 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6303 ;; XXX
6304 (define_insn ""
6305 [(set (match_operand:SI 0 "register_operand" "=h,r")
6306 (subreg:SI
6307 (lshiftrt:DI
6308 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6309 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6310 (match_operand:SI 3 "const_int_operand" "i,i"))
6311 4))
6312 (clobber (match_scratch:SI 4 "=X,&h"))]
6313 "TARGET_V8PLUS"
6314 "@
6315 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6316 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6317 [(set_attr "length" "2")])
6318
6319 ;; XXX
6320 (define_insn "const_smulsi3_highpart_v8plus"
6321 [(set (match_operand:SI 0 "register_operand" "=h,r")
6322 (truncate:SI
6323 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6324 (match_operand 2 "small_int" "i,i"))
6325 (match_operand:SI 3 "const_int_operand" "i,i"))))
6326 (clobber (match_scratch:SI 4 "=X,&h"))]
6327 "TARGET_V8PLUS"
6328 "@
6329 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6330 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6331 [(set_attr "length" "2")])
6332
6333 ;; XXX
6334 (define_insn "*smulsi3_highpart_sp32"
6335 [(set (match_operand:SI 0 "register_operand" "=r")
6336 (truncate:SI
6337 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6338 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6339 (const_int 32))))]
6340 "TARGET_HARD_MUL32"
6341 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6342 [(set_attr "length" "2")])
6343
6344 ;; XXX
6345 (define_insn "const_smulsi3_highpart"
6346 [(set (match_operand:SI 0 "register_operand" "=r")
6347 (truncate:SI
6348 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6349 (match_operand:SI 2 "register_operand" "r"))
6350 (const_int 32))))]
6351 "TARGET_HARD_MUL32"
6352 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6353 [(set_attr "length" "2")])
6354
6355 (define_expand "umulsidi3"
6356 [(set (match_operand:DI 0 "register_operand" "")
6357 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6358 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6359 "TARGET_HARD_MUL"
6360 "
6361 {
6362 if (CONSTANT_P (operands[2]))
6363 {
6364 if (TARGET_V8PLUS)
6365 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6366 operands[2]));
6367 else
6368 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6369 operands[2]));
6370 DONE;
6371 }
6372 if (TARGET_V8PLUS)
6373 {
6374 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6375 DONE;
6376 }
6377 }")
6378
6379 ;; XXX
6380 (define_insn "umulsidi3_v8plus"
6381 [(set (match_operand:DI 0 "register_operand" "=h,r")
6382 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6383 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6384 (clobber (match_scratch:SI 3 "=X,&h"))]
6385 "TARGET_V8PLUS"
6386 "@
6387 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6388 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6389 [(set_attr "length" "2,3")])
6390
6391 ;; XXX
6392 (define_insn "*umulsidi3_sp32"
6393 [(set (match_operand:DI 0 "register_operand" "=r")
6394 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6395 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6396 "TARGET_HARD_MUL32"
6397 "*
6398 {
6399 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6400 }"
6401 [(set (attr "length")
6402 (if_then_else (eq_attr "isa" "sparclet")
6403 (const_int 1) (const_int 2)))])
6404
6405 (define_insn "*umulsidi3_sp64"
6406 [(set (match_operand:DI 0 "register_operand" "=r")
6407 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6408 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6409 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6410 "umul\\t%1, %2, %0"
6411 [(set_attr "length" "1")])
6412
6413 ;; Extra pattern, because sign_extend of a constant isn't valid.
6414
6415 ;; XXX
6416 (define_insn "const_umulsidi3_sp32"
6417 [(set (match_operand:DI 0 "register_operand" "=r")
6418 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6419 (match_operand:SI 2 "uns_small_int" "")))]
6420 "TARGET_HARD_MUL32"
6421 "*
6422 {
6423 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6424 }"
6425 [(set (attr "length")
6426 (if_then_else (eq_attr "isa" "sparclet")
6427 (const_int 1) (const_int 2)))])
6428
6429 (define_insn "const_umulsidi3_sp64"
6430 [(set (match_operand:DI 0 "register_operand" "=r")
6431 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6432 (match_operand:SI 2 "uns_small_int" "")))]
6433 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6434 "umul\\t%1, %2, %0"
6435 [(set_attr "length" "1")])
6436
6437 ;; XXX
6438 (define_insn "const_umulsidi3_v8plus"
6439 [(set (match_operand:DI 0 "register_operand" "=h,r")
6440 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6441 (match_operand:SI 2 "uns_small_int" "")))
6442 (clobber (match_scratch:SI 3 "=X,h"))]
6443 "TARGET_V8PLUS"
6444 "@
6445 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6446 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6447 [(set_attr "length" "2,3")])
6448
6449 (define_expand "umulsi3_highpart"
6450 [(set (match_operand:SI 0 "register_operand" "")
6451 (truncate:SI
6452 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6453 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6454 (const_int 32))))]
6455 "TARGET_HARD_MUL && TARGET_ARCH32"
6456 "
6457 {
6458 if (CONSTANT_P (operands[2]))
6459 {
6460 if (TARGET_V8PLUS)
6461 {
6462 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6463 operands[1],
6464 operands[2],
6465 GEN_INT (32)));
6466 DONE;
6467 }
6468 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6469 DONE;
6470 }
6471 if (TARGET_V8PLUS)
6472 {
6473 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6474 operands[2], GEN_INT (32)));
6475 DONE;
6476 }
6477 }")
6478
6479 ;; XXX
6480 (define_insn "umulsi3_highpart_v8plus"
6481 [(set (match_operand:SI 0 "register_operand" "=h,r")
6482 (truncate:SI
6483 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6484 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6485 (match_operand:SI 3 "const_int_operand" "i,i"))))
6486 (clobber (match_scratch:SI 4 "=X,h"))]
6487 "TARGET_V8PLUS"
6488 "@
6489 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6490 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6491 [(set_attr "length" "2")])
6492
6493 ;; XXX
6494 (define_insn "const_umulsi3_highpart_v8plus"
6495 [(set (match_operand:SI 0 "register_operand" "=h,r")
6496 (truncate:SI
6497 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6498 (match_operand:SI 2 "uns_small_int" ""))
6499 (match_operand:SI 3 "const_int_operand" "i,i"))))
6500 (clobber (match_scratch:SI 4 "=X,h"))]
6501 "TARGET_V8PLUS"
6502 "@
6503 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6504 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6505 [(set_attr "length" "2")])
6506
6507 ;; XXX
6508 (define_insn "*umulsi3_highpart_sp32"
6509 [(set (match_operand:SI 0 "register_operand" "=r")
6510 (truncate:SI
6511 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6512 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6513 (const_int 32))))]
6514 "TARGET_HARD_MUL32"
6515 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6516 [(set_attr "length" "2")])
6517
6518 ;; XXX
6519 (define_insn "const_umulsi3_highpart"
6520 [(set (match_operand:SI 0 "register_operand" "=r")
6521 (truncate:SI
6522 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6523 (match_operand:SI 2 "uns_small_int" ""))
6524 (const_int 32))))]
6525 "TARGET_HARD_MUL32"
6526 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6527 [(set_attr "length" "2")])
6528
6529 ;; The v8 architecture specifies that there must be 3 instructions between
6530 ;; a y register write and a use of it for correct results.
6531
6532 (define_expand "divsi3"
6533 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6534 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6535 (match_operand:SI 2 "input_operand" "rI,m")))
6536 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6537 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6538 "
6539 {
6540 if (TARGET_ARCH64)
6541 {
6542 operands[3] = gen_reg_rtx(SImode);
6543 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6544 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6545 operands[3]));
6546 DONE;
6547 }
6548 }")
6549
6550 (define_insn "divsi3_sp32"
6551 [(set (match_operand:SI 0 "register_operand" "=r,r")
6552 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6553 (match_operand:SI 2 "input_operand" "rI,m")))
6554 (clobber (match_scratch:SI 3 "=&r,&r"))]
6555 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6556 && TARGET_ARCH32"
6557 "*
6558 {
6559 if (which_alternative == 0)
6560 if (TARGET_V9)
6561 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6562 else
6563 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6564 else
6565 if (TARGET_V9)
6566 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6567 else
6568 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\";
6569 }"
6570 [(set (attr "length")
6571 (if_then_else (eq_attr "isa" "v9")
6572 (const_int 4) (const_int 7)))])
6573
6574 (define_insn "divsi3_sp64"
6575 [(set (match_operand:SI 0 "register_operand" "=r")
6576 (div:SI (match_operand:SI 1 "register_operand" "r")
6577 (match_operand:SI 2 "input_operand" "rI")))
6578 (use (match_operand:SI 3 "register_operand" "r"))]
6579 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6580 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6581 [(set_attr "length" "2")])
6582
6583 (define_insn "divdi3"
6584 [(set (match_operand:DI 0 "register_operand" "=r")
6585 (div:DI (match_operand:DI 1 "register_operand" "r")
6586 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6587 "TARGET_ARCH64"
6588 "sdivx\\t%1, %2, %0")
6589
6590 (define_insn "*cmp_sdiv_cc_set"
6591 [(set (reg:CC 100)
6592 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6593 (match_operand:SI 2 "arith_operand" "rI"))
6594 (const_int 0)))
6595 (set (match_operand:SI 0 "register_operand" "=r")
6596 (div:SI (match_dup 1) (match_dup 2)))
6597 (clobber (match_scratch:SI 3 "=&r"))]
6598 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6599 "*
6600 {
6601 if (TARGET_V9)
6602 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6603 else
6604 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6605 }"
6606 [(set (attr "length")
6607 (if_then_else (eq_attr "isa" "v9")
6608 (const_int 3) (const_int 6)))])
6609
6610 ;; XXX
6611 (define_expand "udivsi3"
6612 [(set (match_operand:SI 0 "register_operand" "")
6613 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6614 (match_operand:SI 2 "input_operand" "")))]
6615 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6616 "")
6617
6618 (define_insn "udivsi3_sp32"
6619 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6620 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6621 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6622 "(TARGET_V8
6623 || TARGET_DEPRECATED_V8_INSNS)
6624 && TARGET_ARCH32"
6625 "*
6626 {
6627 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6628 switch (which_alternative)
6629 {
6630 default:
6631 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6632 case 1:
6633 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6634 case 2:
6635 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6636 }
6637 }"
6638 [(set_attr "length" "5")])
6639
6640 (define_insn "udivsi3_sp64"
6641 [(set (match_operand:SI 0 "register_operand" "=r")
6642 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6643 (match_operand:SI 2 "input_operand" "rI")))]
6644 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6645 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6646 [(set_attr "length" "2")])
6647
6648 (define_insn "udivdi3"
6649 [(set (match_operand:DI 0 "register_operand" "=r")
6650 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6651 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6652 "TARGET_ARCH64"
6653 "udivx\\t%1, %2, %0")
6654
6655 (define_insn "*cmp_udiv_cc_set"
6656 [(set (reg:CC 100)
6657 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6658 (match_operand:SI 2 "arith_operand" "rI"))
6659 (const_int 0)))
6660 (set (match_operand:SI 0 "register_operand" "=r")
6661 (udiv:SI (match_dup 1) (match_dup 2)))]
6662 "TARGET_V8
6663 || TARGET_DEPRECATED_V8_INSNS"
6664 "*
6665 {
6666 if (TARGET_V9)
6667 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6668 else
6669 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6670 }"
6671 [(set (attr "length")
6672 (if_then_else (eq_attr "isa" "v9")
6673 (const_int 2) (const_int 5)))])
6674
6675 ; sparclet multiply/accumulate insns
6676
6677 (define_insn "*smacsi"
6678 [(set (match_operand:SI 0 "register_operand" "=r")
6679 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6680 (match_operand:SI 2 "arith_operand" "rI"))
6681 (match_operand:SI 3 "register_operand" "0")))]
6682 "TARGET_SPARCLET"
6683 "smac\\t%1, %2, %0"
6684 [(set_attr "type" "imul")
6685 (set_attr "length" "1")])
6686
6687 (define_insn "*smacdi"
6688 [(set (match_operand:DI 0 "register_operand" "=r")
6689 (plus:DI (mult:DI (sign_extend:DI
6690 (match_operand:SI 1 "register_operand" "%r"))
6691 (sign_extend:DI
6692 (match_operand:SI 2 "register_operand" "r")))
6693 (match_operand:DI 3 "register_operand" "0")))]
6694 "TARGET_SPARCLET"
6695 "smacd\\t%1, %2, %L0"
6696 [(set_attr "type" "imul")
6697 (set_attr "length" "1")])
6698
6699 (define_insn "*umacdi"
6700 [(set (match_operand:DI 0 "register_operand" "=r")
6701 (plus:DI (mult:DI (zero_extend:DI
6702 (match_operand:SI 1 "register_operand" "%r"))
6703 (zero_extend:DI
6704 (match_operand:SI 2 "register_operand" "r")))
6705 (match_operand:DI 3 "register_operand" "0")))]
6706 "TARGET_SPARCLET"
6707 "umacd\\t%1, %2, %L0"
6708 [(set_attr "type" "imul")
6709 (set_attr "length" "1")])
6710 \f
6711 ;;- Boolean instructions
6712 ;; We define DImode `and' so with DImode `not' we can get
6713 ;; DImode `andn'. Other combinations are possible.
6714
6715 (define_expand "anddi3"
6716 [(set (match_operand:DI 0 "register_operand" "")
6717 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6718 (match_operand:DI 2 "arith_double_operand" "")))]
6719 ""
6720 "")
6721
6722 (define_insn "*anddi3_sp32"
6723 [(set (match_operand:DI 0 "register_operand" "=r,b")
6724 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6725 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6726 "! TARGET_ARCH64"
6727 "@
6728 #
6729 fand\\t%1, %2, %0"
6730 [(set_attr "type" "ialu,fp")
6731 (set_attr "length" "2,1")])
6732
6733 (define_insn "*anddi3_sp64"
6734 [(set (match_operand:DI 0 "register_operand" "=r,b")
6735 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6736 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6737 "TARGET_ARCH64"
6738 "@
6739 and\\t%1, %2, %0
6740 fand\\t%1, %2, %0"
6741 [(set_attr "type" "ialu,fp")
6742 (set_attr "length" "1,1")])
6743
6744 (define_insn "andsi3"
6745 [(set (match_operand:SI 0 "register_operand" "=r,d")
6746 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6747 (match_operand:SI 2 "arith_operand" "rI,d")))]
6748 ""
6749 "@
6750 and\\t%1, %2, %0
6751 fands\\t%1, %2, %0"
6752 [(set_attr "type" "ialu,fp")
6753 (set_attr "length" "1,1")])
6754
6755 (define_split
6756 [(set (match_operand:SI 0 "register_operand" "")
6757 (and:SI (match_operand:SI 1 "register_operand" "")
6758 (match_operand:SI 2 "" "")))
6759 (clobber (match_operand:SI 3 "register_operand" ""))]
6760 "GET_CODE (operands[2]) == CONST_INT
6761 && !SMALL_INT32 (operands[2])
6762 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6763 [(set (match_dup 3) (match_dup 4))
6764 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6765 "
6766 {
6767 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6768 }")
6769
6770 ;; Split DImode logical operations requiring two instructions.
6771 (define_split
6772 [(set (match_operand:DI 0 "register_operand" "")
6773 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6774 [(match_operand:DI 2 "register_operand" "")
6775 (match_operand:DI 3 "arith_double_operand" "")]))]
6776 "! TARGET_ARCH64
6777 && reload_completed
6778 && ((GET_CODE (operands[0]) == REG
6779 && REGNO (operands[0]) < 32)
6780 || (GET_CODE (operands[0]) == SUBREG
6781 && GET_CODE (SUBREG_REG (operands[0])) == REG
6782 && REGNO (SUBREG_REG (operands[0])) < 32))"
6783 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6784 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6785 "
6786 {
6787 if (GET_CODE (operands[0]) == SUBREG)
6788 operands[0] = alter_subreg (operands[0]);
6789 operands[4] = gen_highpart (SImode, operands[0]);
6790 operands[5] = gen_lowpart (SImode, operands[0]);
6791 operands[6] = gen_highpart (SImode, operands[2]);
6792 operands[7] = gen_lowpart (SImode, operands[2]);
6793 #if HOST_BITS_PER_WIDE_INT == 32
6794 if (GET_CODE (operands[3]) == CONST_INT)
6795 {
6796 if (INTVAL (operands[3]) < 0)
6797 operands[8] = constm1_rtx;
6798 else
6799 operands[8] = const0_rtx;
6800 }
6801 else
6802 #endif
6803 operands[8] = gen_highpart (SImode, operands[3]);
6804 operands[9] = gen_lowpart (SImode, operands[3]);
6805 }")
6806
6807 (define_insn "*and_not_di_sp32"
6808 [(set (match_operand:DI 0 "register_operand" "=r,b")
6809 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6810 (match_operand:DI 2 "register_operand" "r,b")))]
6811 "! TARGET_ARCH64"
6812 "@
6813 #
6814 fandnot1\\t%1, %2, %0"
6815 [(set_attr "type" "ialu,fp")
6816 (set_attr "length" "2,1")])
6817
6818 (define_split
6819 [(set (match_operand:DI 0 "register_operand" "")
6820 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6821 (match_operand:DI 2 "register_operand" "")))]
6822 "! TARGET_ARCH64
6823 && reload_completed
6824 && ((GET_CODE (operands[0]) == REG
6825 && REGNO (operands[0]) < 32)
6826 || (GET_CODE (operands[0]) == SUBREG
6827 && GET_CODE (SUBREG_REG (operands[0])) == REG
6828 && REGNO (SUBREG_REG (operands[0])) < 32))"
6829 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6830 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6831 "if (GET_CODE (operands[0]) == SUBREG)
6832 operands[0] = alter_subreg (operands[0]);
6833 operands[3] = gen_highpart (SImode, operands[0]);
6834 operands[4] = gen_highpart (SImode, operands[1]);
6835 operands[5] = gen_highpart (SImode, operands[2]);
6836 operands[6] = gen_lowpart (SImode, operands[0]);
6837 operands[7] = gen_lowpart (SImode, operands[1]);
6838 operands[8] = gen_lowpart (SImode, operands[2]);")
6839
6840 (define_insn "*and_not_di_sp64"
6841 [(set (match_operand:DI 0 "register_operand" "=r,b")
6842 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6843 (match_operand:DI 2 "register_operand" "r,b")))]
6844 "TARGET_ARCH64"
6845 "@
6846 andn\\t%2, %1, %0
6847 fandnot1\\t%1, %2, %0"
6848 [(set_attr "type" "ialu,fp")
6849 (set_attr "length" "1,1")])
6850
6851 (define_insn "*and_not_si"
6852 [(set (match_operand:SI 0 "register_operand" "=r,d")
6853 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6854 (match_operand:SI 2 "register_operand" "r,d")))]
6855 ""
6856 "@
6857 andn\\t%2, %1, %0
6858 fandnot1s\\t%1, %2, %0"
6859 [(set_attr "type" "ialu,fp")
6860 (set_attr "length" "1,1")])
6861
6862 (define_expand "iordi3"
6863 [(set (match_operand:DI 0 "register_operand" "")
6864 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6865 (match_operand:DI 2 "arith_double_operand" "")))]
6866 ""
6867 "")
6868
6869 (define_insn "*iordi3_sp32"
6870 [(set (match_operand:DI 0 "register_operand" "=r,b")
6871 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6872 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6873 "! TARGET_ARCH64"
6874 "@
6875 #
6876 for\\t%1, %2, %0"
6877 [(set_attr "type" "ialu,fp")
6878 (set_attr "length" "2,1")])
6879
6880 (define_insn "*iordi3_sp64"
6881 [(set (match_operand:DI 0 "register_operand" "=r,b")
6882 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6883 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6884 "TARGET_ARCH64"
6885 "@
6886 or\\t%1, %2, %0
6887 for\\t%1, %2, %0"
6888 [(set_attr "type" "ialu,fp")
6889 (set_attr "length" "1,1")])
6890
6891 (define_insn "iorsi3"
6892 [(set (match_operand:SI 0 "register_operand" "=r,d")
6893 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6894 (match_operand:SI 2 "arith_operand" "rI,d")))]
6895 ""
6896 "@
6897 or\\t%1, %2, %0
6898 fors\\t%1, %2, %0"
6899 [(set_attr "type" "ialu,fp")
6900 (set_attr "length" "1,1")])
6901
6902 (define_split
6903 [(set (match_operand:SI 0 "register_operand" "")
6904 (ior:SI (match_operand:SI 1 "register_operand" "")
6905 (match_operand:SI 2 "" "")))
6906 (clobber (match_operand:SI 3 "register_operand" ""))]
6907 "GET_CODE (operands[2]) == CONST_INT
6908 && !SMALL_INT32 (operands[2])
6909 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6910 [(set (match_dup 3) (match_dup 4))
6911 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6912 "
6913 {
6914 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6915 }")
6916
6917 (define_insn "*or_not_di_sp32"
6918 [(set (match_operand:DI 0 "register_operand" "=r,b")
6919 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6920 (match_operand:DI 2 "register_operand" "r,b")))]
6921 "! TARGET_ARCH64"
6922 "@
6923 #
6924 fornot1\\t%1, %2, %0"
6925 [(set_attr "type" "ialu,fp")
6926 (set_attr "length" "2,1")])
6927
6928 (define_split
6929 [(set (match_operand:DI 0 "register_operand" "")
6930 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6931 (match_operand:DI 2 "register_operand" "")))]
6932 "! TARGET_ARCH64
6933 && reload_completed
6934 && ((GET_CODE (operands[0]) == REG
6935 && REGNO (operands[0]) < 32)
6936 || (GET_CODE (operands[0]) == SUBREG
6937 && GET_CODE (SUBREG_REG (operands[0])) == REG
6938 && REGNO (SUBREG_REG (operands[0])) < 32))"
6939 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6940 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6941 "if (GET_CODE (operands[0]) == SUBREG)
6942 operands[0] = alter_subreg (operands[0]);
6943 operands[3] = gen_highpart (SImode, operands[0]);
6944 operands[4] = gen_highpart (SImode, operands[1]);
6945 operands[5] = gen_highpart (SImode, operands[2]);
6946 operands[6] = gen_lowpart (SImode, operands[0]);
6947 operands[7] = gen_lowpart (SImode, operands[1]);
6948 operands[8] = gen_lowpart (SImode, operands[2]);")
6949
6950 (define_insn "*or_not_di_sp64"
6951 [(set (match_operand:DI 0 "register_operand" "=r,b")
6952 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6953 (match_operand:DI 2 "register_operand" "r,b")))]
6954 "TARGET_ARCH64"
6955 "@
6956 orn\\t%2, %1, %0
6957 fornot1\\t%1, %2, %0"
6958 [(set_attr "type" "ialu,fp")
6959 (set_attr "length" "1,1")])
6960
6961 (define_insn "*or_not_si"
6962 [(set (match_operand:SI 0 "register_operand" "=r,d")
6963 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6964 (match_operand:SI 2 "register_operand" "r,d")))]
6965 ""
6966 "@
6967 orn\\t%2, %1, %0
6968 fornot1s\\t%1, %2, %0"
6969 [(set_attr "type" "ialu,fp")
6970 (set_attr "length" "1,1")])
6971
6972 (define_expand "xordi3"
6973 [(set (match_operand:DI 0 "register_operand" "")
6974 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6975 (match_operand:DI 2 "arith_double_operand" "")))]
6976 ""
6977 "")
6978
6979 (define_insn "*xordi3_sp32"
6980 [(set (match_operand:DI 0 "register_operand" "=r,b")
6981 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6982 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6983 "! TARGET_ARCH64"
6984 "@
6985 #
6986 fxor\\t%1, %2, %0"
6987 [(set_attr "length" "2,1")
6988 (set_attr "type" "ialu,fp")])
6989
6990 (define_insn "*xordi3_sp64"
6991 [(set (match_operand:DI 0 "register_operand" "=r,b")
6992 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6993 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6994 "TARGET_ARCH64"
6995 "@
6996 xor\\t%r1, %2, %0
6997 fxor\\t%1, %2, %0"
6998 [(set_attr "type" "ialu,fp")
6999 (set_attr "length" "1,1")])
7000
7001 (define_insn "*xordi3_sp64_dbl"
7002 [(set (match_operand:DI 0 "register_operand" "=r")
7003 (xor:DI (match_operand:DI 1 "register_operand" "r")
7004 (match_operand:DI 2 "const64_operand" "")))]
7005 "(TARGET_ARCH64
7006 && HOST_BITS_PER_WIDE_INT != 64)"
7007 "xor\\t%1, %2, %0"
7008 [(set_attr "type" "ialu")
7009 (set_attr "length" "1")])
7010
7011 (define_insn "xorsi3"
7012 [(set (match_operand:SI 0 "register_operand" "=r,d")
7013 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
7014 (match_operand:SI 2 "arith_operand" "rI,d")))]
7015 ""
7016 "@
7017 xor\\t%r1, %2, %0
7018 fxors\\t%1, %2, %0"
7019 [(set_attr "type" "ialu,fp")
7020 (set_attr "length" "1,1")])
7021
7022 (define_split
7023 [(set (match_operand:SI 0 "register_operand" "")
7024 (xor:SI (match_operand:SI 1 "register_operand" "")
7025 (match_operand:SI 2 "" "")))
7026 (clobber (match_operand:SI 3 "register_operand" ""))]
7027 "GET_CODE (operands[2]) == CONST_INT
7028 && !SMALL_INT32 (operands[2])
7029 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7030 [(set (match_dup 3) (match_dup 4))
7031 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
7032 "
7033 {
7034 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
7035 }")
7036
7037 (define_split
7038 [(set (match_operand:SI 0 "register_operand" "")
7039 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
7040 (match_operand:SI 2 "" ""))))
7041 (clobber (match_operand:SI 3 "register_operand" ""))]
7042 "GET_CODE (operands[2]) == CONST_INT
7043 && !SMALL_INT32 (operands[2])
7044 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7045 [(set (match_dup 3) (match_dup 4))
7046 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
7047 "
7048 {
7049 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
7050 }")
7051
7052 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
7053 ;; Combine now canonicalizes to the rightmost expression.
7054 (define_insn "*xor_not_di_sp32"
7055 [(set (match_operand:DI 0 "register_operand" "=r,b")
7056 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
7057 (match_operand:DI 2 "register_operand" "r,b"))))]
7058 "! TARGET_ARCH64"
7059 "@
7060 #
7061 fxnor\\t%1, %2, %0"
7062 [(set_attr "length" "2,1")
7063 (set_attr "type" "ialu,fp")])
7064
7065 (define_split
7066 [(set (match_operand:DI 0 "register_operand" "")
7067 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
7068 (match_operand:DI 2 "register_operand" ""))))]
7069 "! TARGET_ARCH64
7070 && reload_completed
7071 && ((GET_CODE (operands[0]) == REG
7072 && REGNO (operands[0]) < 32)
7073 || (GET_CODE (operands[0]) == SUBREG
7074 && GET_CODE (SUBREG_REG (operands[0])) == REG
7075 && REGNO (SUBREG_REG (operands[0])) < 32))"
7076 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
7077 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
7078 "if (GET_CODE (operands[0]) == SUBREG)
7079 operands[0] = alter_subreg (operands[0]);
7080 operands[3] = gen_highpart (SImode, operands[0]);
7081 operands[4] = gen_highpart (SImode, operands[1]);
7082 operands[5] = gen_highpart (SImode, operands[2]);
7083 operands[6] = gen_lowpart (SImode, operands[0]);
7084 operands[7] = gen_lowpart (SImode, operands[1]);
7085 operands[8] = gen_lowpart (SImode, operands[2]);")
7086
7087 (define_insn "*xor_not_di_sp64"
7088 [(set (match_operand:DI 0 "register_operand" "=r,b")
7089 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
7090 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
7091 "TARGET_ARCH64"
7092 "@
7093 xnor\\t%r1, %2, %0
7094 fxnor\\t%1, %2, %0"
7095 [(set_attr "type" "ialu,fp")
7096 (set_attr "length" "1,1")])
7097
7098 (define_insn "*xor_not_si"
7099 [(set (match_operand:SI 0 "register_operand" "=r,d")
7100 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7101 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7102 ""
7103 "@
7104 xnor\\t%r1, %2, %0
7105 fxnors\\t%1, %2, %0"
7106 [(set_attr "type" "ialu,fp")
7107 (set_attr "length" "1,1")])
7108
7109 ;; These correspond to the above in the case where we also (or only)
7110 ;; want to set the condition code.
7111
7112 (define_insn "*cmp_cc_arith_op"
7113 [(set (reg:CC 100)
7114 (compare:CC
7115 (match_operator:SI 2 "cc_arithop"
7116 [(match_operand:SI 0 "arith_operand" "%r")
7117 (match_operand:SI 1 "arith_operand" "rI")])
7118 (const_int 0)))]
7119 ""
7120 "%A2cc\\t%0, %1, %%g0"
7121 [(set_attr "type" "compare")
7122 (set_attr "length" "1")])
7123
7124 (define_insn "*cmp_ccx_arith_op"
7125 [(set (reg:CCX 100)
7126 (compare:CCX
7127 (match_operator:DI 2 "cc_arithop"
7128 [(match_operand:DI 0 "arith_double_operand" "%r")
7129 (match_operand:DI 1 "arith_double_operand" "rHI")])
7130 (const_int 0)))]
7131 "TARGET_ARCH64"
7132 "%A2cc\\t%0, %1, %%g0"
7133 [(set_attr "type" "compare")
7134 (set_attr "length" "1")])
7135
7136 (define_insn "*cmp_cc_arith_op_set"
7137 [(set (reg:CC 100)
7138 (compare:CC
7139 (match_operator:SI 3 "cc_arithop"
7140 [(match_operand:SI 1 "arith_operand" "%r")
7141 (match_operand:SI 2 "arith_operand" "rI")])
7142 (const_int 0)))
7143 (set (match_operand:SI 0 "register_operand" "=r")
7144 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7145 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7146 "%A3cc\\t%1, %2, %0"
7147 [(set_attr "type" "compare")
7148 (set_attr "length" "1")])
7149
7150 (define_insn "*cmp_ccx_arith_op_set"
7151 [(set (reg:CCX 100)
7152 (compare:CCX
7153 (match_operator:DI 3 "cc_arithop"
7154 [(match_operand:DI 1 "arith_double_operand" "%r")
7155 (match_operand:DI 2 "arith_double_operand" "rHI")])
7156 (const_int 0)))
7157 (set (match_operand:DI 0 "register_operand" "=r")
7158 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7159 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7160 "%A3cc\\t%1, %2, %0"
7161 [(set_attr "type" "compare")
7162 (set_attr "length" "1")])
7163
7164 (define_insn "*cmp_cc_xor_not"
7165 [(set (reg:CC 100)
7166 (compare:CC
7167 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7168 (match_operand:SI 1 "arith_operand" "rI")))
7169 (const_int 0)))]
7170 ""
7171 "xnorcc\\t%r0, %1, %%g0"
7172 [(set_attr "type" "compare")
7173 (set_attr "length" "1")])
7174
7175 (define_insn "*cmp_ccx_xor_not"
7176 [(set (reg:CCX 100)
7177 (compare:CCX
7178 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7179 (match_operand:DI 1 "arith_double_operand" "rHI")))
7180 (const_int 0)))]
7181 "TARGET_ARCH64"
7182 "xnorcc\\t%r0, %1, %%g0"
7183 [(set_attr "type" "compare")
7184 (set_attr "length" "1")])
7185
7186 (define_insn "*cmp_cc_xor_not_set"
7187 [(set (reg:CC 100)
7188 (compare:CC
7189 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7190 (match_operand:SI 2 "arith_operand" "rI")))
7191 (const_int 0)))
7192 (set (match_operand:SI 0 "register_operand" "=r")
7193 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7194 ""
7195 "xnorcc\\t%r1, %2, %0"
7196 [(set_attr "type" "compare")
7197 (set_attr "length" "1")])
7198
7199 (define_insn "*cmp_ccx_xor_not_set"
7200 [(set (reg:CCX 100)
7201 (compare:CCX
7202 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7203 (match_operand:DI 2 "arith_double_operand" "rHI")))
7204 (const_int 0)))
7205 (set (match_operand:DI 0 "register_operand" "=r")
7206 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7207 "TARGET_ARCH64"
7208 "xnorcc\\t%r1, %2, %0"
7209 [(set_attr "type" "compare")
7210 (set_attr "length" "1")])
7211
7212 (define_insn "*cmp_cc_arith_op_not"
7213 [(set (reg:CC 100)
7214 (compare:CC
7215 (match_operator:SI 2 "cc_arithopn"
7216 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7217 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7218 (const_int 0)))]
7219 ""
7220 "%B2cc\\t%r1, %0, %%g0"
7221 [(set_attr "type" "compare")
7222 (set_attr "length" "1")])
7223
7224 (define_insn "*cmp_ccx_arith_op_not"
7225 [(set (reg:CCX 100)
7226 (compare:CCX
7227 (match_operator:DI 2 "cc_arithopn"
7228 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7229 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7230 (const_int 0)))]
7231 "TARGET_ARCH64"
7232 "%B2cc\\t%r1, %0, %%g0"
7233 [(set_attr "type" "compare")
7234 (set_attr "length" "1")])
7235
7236 (define_insn "*cmp_cc_arith_op_not_set"
7237 [(set (reg:CC 100)
7238 (compare:CC
7239 (match_operator:SI 3 "cc_arithopn"
7240 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7241 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7242 (const_int 0)))
7243 (set (match_operand:SI 0 "register_operand" "=r")
7244 (match_operator:SI 4 "cc_arithopn"
7245 [(not:SI (match_dup 1)) (match_dup 2)]))]
7246 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7247 "%B3cc\\t%r2, %1, %0"
7248 [(set_attr "type" "compare")
7249 (set_attr "length" "1")])
7250
7251 (define_insn "*cmp_ccx_arith_op_not_set"
7252 [(set (reg:CCX 100)
7253 (compare:CCX
7254 (match_operator:DI 3 "cc_arithopn"
7255 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7256 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7257 (const_int 0)))
7258 (set (match_operand:DI 0 "register_operand" "=r")
7259 (match_operator:DI 4 "cc_arithopn"
7260 [(not:DI (match_dup 1)) (match_dup 2)]))]
7261 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7262 "%B3cc\\t%r2, %1, %0"
7263 [(set_attr "type" "compare")
7264 (set_attr "length" "1")])
7265
7266 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7267 ;; does not know how to make it work for constants.
7268
7269 (define_expand "negdi2"
7270 [(set (match_operand:DI 0 "register_operand" "=r")
7271 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7272 ""
7273 "
7274 {
7275 if (! TARGET_ARCH64)
7276 {
7277 emit_insn (gen_rtx_PARALLEL
7278 (VOIDmode,
7279 gen_rtvec (2,
7280 gen_rtx_SET (VOIDmode, operand0,
7281 gen_rtx_NEG (DImode, operand1)),
7282 gen_rtx_CLOBBER (VOIDmode,
7283 gen_rtx_REG (CCmode,
7284 SPARC_ICC_REG)))));
7285 DONE;
7286 }
7287 }")
7288
7289 (define_insn "*negdi2_sp32"
7290 [(set (match_operand:DI 0 "register_operand" "=r")
7291 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7292 (clobber (reg:CC 100))]
7293 "TARGET_ARCH32"
7294 "#"
7295 [(set_attr "type" "unary")
7296 (set_attr "length" "2")])
7297
7298 (define_split
7299 [(set (match_operand:DI 0 "register_operand" "")
7300 (neg:DI (match_operand:DI 1 "register_operand" "")))
7301 (clobber (reg:CC 100))]
7302 "TARGET_ARCH32
7303 && reload_completed"
7304 [(parallel [(set (reg:CC_NOOV 100)
7305 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7306 (const_int 0)))
7307 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7308 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7309 (ltu:SI (reg:CC 100) (const_int 0))))]
7310 "operands[2] = gen_highpart (SImode, operands[0]);
7311 operands[3] = gen_highpart (SImode, operands[1]);
7312 operands[4] = gen_lowpart (SImode, operands[0]);
7313 operands[5] = gen_lowpart (SImode, operands[1]);")
7314
7315 (define_insn "*negdi2_sp64"
7316 [(set (match_operand:DI 0 "register_operand" "=r")
7317 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7318 "TARGET_ARCH64"
7319 "sub\\t%%g0, %1, %0"
7320 [(set_attr "type" "unary")
7321 (set_attr "length" "1")])
7322
7323 (define_insn "negsi2"
7324 [(set (match_operand:SI 0 "register_operand" "=r")
7325 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7326 ""
7327 "sub\\t%%g0, %1, %0"
7328 [(set_attr "type" "unary")
7329 (set_attr "length" "1")])
7330
7331 (define_insn "*cmp_cc_neg"
7332 [(set (reg:CC_NOOV 100)
7333 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7334 (const_int 0)))]
7335 ""
7336 "subcc\\t%%g0, %0, %%g0"
7337 [(set_attr "type" "compare")
7338 (set_attr "length" "1")])
7339
7340 (define_insn "*cmp_ccx_neg"
7341 [(set (reg:CCX_NOOV 100)
7342 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7343 (const_int 0)))]
7344 "TARGET_ARCH64"
7345 "subcc\\t%%g0, %0, %%g0"
7346 [(set_attr "type" "compare")
7347 (set_attr "length" "1")])
7348
7349 (define_insn "*cmp_cc_set_neg"
7350 [(set (reg:CC_NOOV 100)
7351 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7352 (const_int 0)))
7353 (set (match_operand:SI 0 "register_operand" "=r")
7354 (neg:SI (match_dup 1)))]
7355 ""
7356 "subcc\\t%%g0, %1, %0"
7357 [(set_attr "type" "compare")
7358 (set_attr "length" "1")])
7359
7360 (define_insn "*cmp_ccx_set_neg"
7361 [(set (reg:CCX_NOOV 100)
7362 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7363 (const_int 0)))
7364 (set (match_operand:DI 0 "register_operand" "=r")
7365 (neg:DI (match_dup 1)))]
7366 "TARGET_ARCH64"
7367 "subcc\\t%%g0, %1, %0"
7368 [(set_attr "type" "compare")
7369 (set_attr "length" "1")])
7370
7371 ;; We cannot use the "not" pseudo insn because the Sun assembler
7372 ;; does not know how to make it work for constants.
7373 (define_expand "one_cmpldi2"
7374 [(set (match_operand:DI 0 "register_operand" "")
7375 (not:DI (match_operand:DI 1 "register_operand" "")))]
7376 ""
7377 "")
7378
7379 (define_insn "*one_cmpldi2_sp32"
7380 [(set (match_operand:DI 0 "register_operand" "=r,b")
7381 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7382 "! TARGET_ARCH64"
7383 "@
7384 #
7385 fnot1\\t%1, %0"
7386 [(set_attr "type" "unary,fp")
7387 (set_attr "length" "2,1")])
7388
7389 (define_split
7390 [(set (match_operand:DI 0 "register_operand" "")
7391 (not:DI (match_operand:DI 1 "register_operand" "")))]
7392 "! TARGET_ARCH64
7393 && reload_completed
7394 && ((GET_CODE (operands[0]) == REG
7395 && REGNO (operands[0]) < 32)
7396 || (GET_CODE (operands[0]) == SUBREG
7397 && GET_CODE (SUBREG_REG (operands[0])) == REG
7398 && REGNO (SUBREG_REG (operands[0])) < 32))"
7399 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7400 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7401 "if (GET_CODE (operands[0]) == SUBREG)
7402 operands[0] = alter_subreg (operands[0]);
7403 operands[2] = gen_highpart (SImode, operands[0]);
7404 operands[3] = gen_highpart (SImode, operands[1]);
7405 operands[4] = gen_lowpart (SImode, operands[0]);
7406 operands[5] = gen_lowpart (SImode, operands[1]);")
7407
7408 (define_insn "*one_cmpldi2_sp64"
7409 [(set (match_operand:DI 0 "register_operand" "=r,b")
7410 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7411 "TARGET_ARCH64"
7412 "@
7413 xnor\\t%%g0, %1, %0
7414 fnot1\\t%1, %0"
7415 [(set_attr "type" "unary,fp")
7416 (set_attr "length" "1")])
7417
7418 (define_insn "one_cmplsi2"
7419 [(set (match_operand:SI 0 "register_operand" "=r,d")
7420 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7421 ""
7422 "@
7423 xnor\\t%%g0, %1, %0
7424 fnot1s\\t%1, %0"
7425 [(set_attr "type" "unary,fp")
7426 (set_attr "length" "1,1")])
7427
7428 (define_insn "*cmp_cc_not"
7429 [(set (reg:CC 100)
7430 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7431 (const_int 0)))]
7432 ""
7433 "xnorcc\\t%%g0, %0, %%g0"
7434 [(set_attr "type" "compare")
7435 (set_attr "length" "1")])
7436
7437 (define_insn "*cmp_ccx_not"
7438 [(set (reg:CCX 100)
7439 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7440 (const_int 0)))]
7441 "TARGET_ARCH64"
7442 "xnorcc\\t%%g0, %0, %%g0"
7443 [(set_attr "type" "compare")
7444 (set_attr "length" "1")])
7445
7446 (define_insn "*cmp_cc_set_not"
7447 [(set (reg:CC 100)
7448 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7449 (const_int 0)))
7450 (set (match_operand:SI 0 "register_operand" "=r")
7451 (not:SI (match_dup 1)))]
7452 ""
7453 "xnorcc\\t%%g0, %1, %0"
7454 [(set_attr "type" "compare")
7455 (set_attr "length" "1")])
7456
7457 (define_insn "*cmp_ccx_set_not"
7458 [(set (reg:CCX 100)
7459 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7460 (const_int 0)))
7461 (set (match_operand:DI 0 "register_operand" "=r")
7462 (not:DI (match_dup 1)))]
7463 "TARGET_ARCH64"
7464 "xnorcc\\t%%g0, %1, %0"
7465 [(set_attr "type" "compare")
7466 (set_attr "length" "1")])
7467 \f
7468 ;; Floating point arithmetic instructions.
7469
7470 (define_expand "addtf3"
7471 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7472 (plus:TF (match_operand:TF 1 "general_operand" "")
7473 (match_operand:TF 2 "general_operand" "")))]
7474 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7475 "
7476 {
7477 if (! TARGET_HARD_QUAD)
7478 {
7479 rtx slot0, slot1, slot2;
7480
7481 if (GET_CODE (operands[0]) != MEM)
7482 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7483 else
7484 slot0 = operands[0];
7485 if (GET_CODE (operands[1]) != MEM)
7486 {
7487 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7488 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7489 }
7490 else
7491 slot1 = operands[1];
7492 if (GET_CODE (operands[2]) != MEM)
7493 {
7494 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7495 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7496 }
7497 else
7498 slot2 = operands[2];
7499
7500 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7501 VOIDmode, 3,
7502 XEXP (slot0, 0), Pmode,
7503 XEXP (slot1, 0), Pmode,
7504 XEXP (slot2, 0), Pmode);
7505
7506 if (GET_CODE (operands[0]) != MEM)
7507 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7508 DONE;
7509 }
7510 }")
7511
7512 (define_insn "*addtf3_hq"
7513 [(set (match_operand:TF 0 "register_operand" "=e")
7514 (plus:TF (match_operand:TF 1 "register_operand" "e")
7515 (match_operand:TF 2 "register_operand" "e")))]
7516 "TARGET_FPU && TARGET_HARD_QUAD"
7517 "faddq\\t%1, %2, %0"
7518 [(set_attr "type" "fp")
7519 (set_attr "length" "1")])
7520
7521 (define_insn "adddf3"
7522 [(set (match_operand:DF 0 "register_operand" "=e")
7523 (plus:DF (match_operand:DF 1 "register_operand" "e")
7524 (match_operand:DF 2 "register_operand" "e")))]
7525 "TARGET_FPU"
7526 "faddd\\t%1, %2, %0"
7527 [(set_attr "type" "fp")
7528 (set_attr "length" "1")])
7529
7530 (define_insn "addsf3"
7531 [(set (match_operand:SF 0 "register_operand" "=f")
7532 (plus:SF (match_operand:SF 1 "register_operand" "f")
7533 (match_operand:SF 2 "register_operand" "f")))]
7534 "TARGET_FPU"
7535 "fadds\\t%1, %2, %0"
7536 [(set_attr "type" "fp")
7537 (set_attr "length" "1")])
7538
7539 (define_expand "subtf3"
7540 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7541 (minus:TF (match_operand:TF 1 "general_operand" "")
7542 (match_operand:TF 2 "general_operand" "")))]
7543 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7544 "
7545 {
7546 if (! TARGET_HARD_QUAD)
7547 {
7548 rtx slot0, slot1, slot2;
7549
7550 if (GET_CODE (operands[0]) != MEM)
7551 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7552 else
7553 slot0 = operands[0];
7554 if (GET_CODE (operands[1]) != MEM)
7555 {
7556 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7557 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7558 }
7559 else
7560 slot1 = operands[1];
7561 if (GET_CODE (operands[2]) != MEM)
7562 {
7563 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7564 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7565 }
7566 else
7567 slot2 = operands[2];
7568
7569 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7570 VOIDmode, 3,
7571 XEXP (slot0, 0), Pmode,
7572 XEXP (slot1, 0), Pmode,
7573 XEXP (slot2, 0), Pmode);
7574
7575 if (GET_CODE (operands[0]) != MEM)
7576 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7577 DONE;
7578 }
7579 }")
7580
7581 (define_insn "*subtf3_hq"
7582 [(set (match_operand:TF 0 "register_operand" "=e")
7583 (minus:TF (match_operand:TF 1 "register_operand" "e")
7584 (match_operand:TF 2 "register_operand" "e")))]
7585 "TARGET_FPU && TARGET_HARD_QUAD"
7586 "fsubq\\t%1, %2, %0"
7587 [(set_attr "type" "fp")
7588 (set_attr "length" "1")])
7589
7590 (define_insn "subdf3"
7591 [(set (match_operand:DF 0 "register_operand" "=e")
7592 (minus:DF (match_operand:DF 1 "register_operand" "e")
7593 (match_operand:DF 2 "register_operand" "e")))]
7594 "TARGET_FPU"
7595 "fsubd\\t%1, %2, %0"
7596 [(set_attr "type" "fp")
7597 (set_attr "length" "1")])
7598
7599 (define_insn "subsf3"
7600 [(set (match_operand:SF 0 "register_operand" "=f")
7601 (minus:SF (match_operand:SF 1 "register_operand" "f")
7602 (match_operand:SF 2 "register_operand" "f")))]
7603 "TARGET_FPU"
7604 "fsubs\\t%1, %2, %0"
7605 [(set_attr "type" "fp")
7606 (set_attr "length" "1")])
7607
7608 (define_expand "multf3"
7609 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7610 (mult:TF (match_operand:TF 1 "general_operand" "")
7611 (match_operand:TF 2 "general_operand" "")))]
7612 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7613 "
7614 {
7615 if (! TARGET_HARD_QUAD)
7616 {
7617 rtx slot0, slot1, slot2;
7618
7619 if (GET_CODE (operands[0]) != MEM)
7620 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7621 else
7622 slot0 = operands[0];
7623 if (GET_CODE (operands[1]) != MEM)
7624 {
7625 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7626 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7627 }
7628 else
7629 slot1 = operands[1];
7630 if (GET_CODE (operands[2]) != MEM)
7631 {
7632 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7633 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7634 }
7635 else
7636 slot2 = operands[2];
7637
7638 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7639 VOIDmode, 3,
7640 XEXP (slot0, 0), Pmode,
7641 XEXP (slot1, 0), Pmode,
7642 XEXP (slot2, 0), Pmode);
7643
7644 if (GET_CODE (operands[0]) != MEM)
7645 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7646 DONE;
7647 }
7648 }")
7649
7650 (define_insn "*multf3_hq"
7651 [(set (match_operand:TF 0 "register_operand" "=e")
7652 (mult:TF (match_operand:TF 1 "register_operand" "e")
7653 (match_operand:TF 2 "register_operand" "e")))]
7654 "TARGET_FPU && TARGET_HARD_QUAD"
7655 "fmulq\\t%1, %2, %0"
7656 [(set_attr "type" "fpmul")
7657 (set_attr "length" "1")])
7658
7659 (define_insn "muldf3"
7660 [(set (match_operand:DF 0 "register_operand" "=e")
7661 (mult:DF (match_operand:DF 1 "register_operand" "e")
7662 (match_operand:DF 2 "register_operand" "e")))]
7663 "TARGET_FPU"
7664 "fmuld\\t%1, %2, %0"
7665 [(set_attr "type" "fpmul")
7666 (set_attr "length" "1")])
7667
7668 (define_insn "mulsf3"
7669 [(set (match_operand:SF 0 "register_operand" "=f")
7670 (mult:SF (match_operand:SF 1 "register_operand" "f")
7671 (match_operand:SF 2 "register_operand" "f")))]
7672 "TARGET_FPU"
7673 "fmuls\\t%1, %2, %0"
7674 [(set_attr "type" "fpmul")
7675 (set_attr "length" "1")])
7676
7677 (define_insn "*muldf3_extend"
7678 [(set (match_operand:DF 0 "register_operand" "=e")
7679 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7680 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7681 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7682 "fsmuld\\t%1, %2, %0"
7683 [(set_attr "type" "fpmul")
7684 (set_attr "length" "1")])
7685
7686 (define_insn "*multf3_extend"
7687 [(set (match_operand:TF 0 "register_operand" "=e")
7688 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7689 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7690 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7691 "fdmulq\\t%1, %2, %0"
7692 [(set_attr "type" "fpmul")
7693 (set_attr "length" "1")])
7694
7695 (define_expand "divtf3"
7696 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7697 (div:TF (match_operand:TF 1 "general_operand" "")
7698 (match_operand:TF 2 "general_operand" "")))]
7699 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7700 "
7701 {
7702 if (! TARGET_HARD_QUAD)
7703 {
7704 rtx slot0, slot1, slot2;
7705
7706 if (GET_CODE (operands[0]) != MEM)
7707 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7708 else
7709 slot0 = operands[0];
7710 if (GET_CODE (operands[1]) != MEM)
7711 {
7712 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7713 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7714 }
7715 else
7716 slot1 = operands[1];
7717 if (GET_CODE (operands[2]) != MEM)
7718 {
7719 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7720 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7721 }
7722 else
7723 slot2 = operands[2];
7724
7725 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7726 VOIDmode, 3,
7727 XEXP (slot0, 0), Pmode,
7728 XEXP (slot1, 0), Pmode,
7729 XEXP (slot2, 0), Pmode);
7730
7731 if (GET_CODE (operands[0]) != MEM)
7732 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7733 DONE;
7734 }
7735 }")
7736
7737 ;; don't have timing for quad-prec. divide.
7738 (define_insn "*divtf3_hq"
7739 [(set (match_operand:TF 0 "register_operand" "=e")
7740 (div:TF (match_operand:TF 1 "register_operand" "e")
7741 (match_operand:TF 2 "register_operand" "e")))]
7742 "TARGET_FPU && TARGET_HARD_QUAD"
7743 "fdivq\\t%1, %2, %0"
7744 [(set_attr "type" "fpdivd")
7745 (set_attr "length" "1")])
7746
7747 (define_insn "divdf3"
7748 [(set (match_operand:DF 0 "register_operand" "=e")
7749 (div:DF (match_operand:DF 1 "register_operand" "e")
7750 (match_operand:DF 2 "register_operand" "e")))]
7751 "TARGET_FPU"
7752 "fdivd\\t%1, %2, %0"
7753 [(set_attr "type" "fpdivd")
7754 (set_attr "length" "1")])
7755
7756 (define_insn "divsf3"
7757 [(set (match_operand:SF 0 "register_operand" "=f")
7758 (div:SF (match_operand:SF 1 "register_operand" "f")
7759 (match_operand:SF 2 "register_operand" "f")))]
7760 "TARGET_FPU"
7761 "fdivs\\t%1, %2, %0"
7762 [(set_attr "type" "fpdivs")
7763 (set_attr "length" "1")])
7764
7765 (define_expand "negtf2"
7766 [(set (match_operand:TF 0 "register_operand" "=e,e")
7767 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7768 "TARGET_FPU"
7769 "")
7770
7771 (define_insn "*negtf2_notv9"
7772 [(set (match_operand:TF 0 "register_operand" "=e,e")
7773 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7774 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7775 "TARGET_FPU
7776 && ! TARGET_V9"
7777 "@
7778 fnegs\\t%0, %0
7779 #"
7780 [(set_attr "type" "fpmove")
7781 (set_attr "length" "1,2")])
7782
7783 (define_split
7784 [(set (match_operand:TF 0 "register_operand" "")
7785 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7786 "TARGET_FPU
7787 && ! TARGET_V9
7788 && reload_completed
7789 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7790 [(set (match_dup 2) (neg:SF (match_dup 3)))
7791 (set (match_dup 4) (match_dup 5))
7792 (set (match_dup 6) (match_dup 7))]
7793 "if (GET_CODE (operands[0]) == SUBREG)
7794 operands[0] = alter_subreg (operands[0]);
7795 if (GET_CODE (operands[1]) == SUBREG)
7796 operands[1] = alter_subreg (operands[1]);
7797 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7798 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7799 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7800 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7801 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7802 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7803
7804 (define_insn "*negtf2_v9"
7805 [(set (match_operand:TF 0 "register_operand" "=e,e")
7806 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7807 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7808 "TARGET_FPU && TARGET_V9"
7809 "@
7810 fnegd\\t%0, %0
7811 #"
7812 [(set_attr "type" "fpmove")
7813 (set_attr "length" "1,2")])
7814
7815 (define_split
7816 [(set (match_operand:TF 0 "register_operand" "")
7817 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7818 "TARGET_FPU
7819 && TARGET_V9
7820 && reload_completed
7821 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7822 [(set (match_dup 2) (neg:DF (match_dup 3)))
7823 (set (match_dup 4) (match_dup 5))]
7824 "if (GET_CODE (operands[0]) == SUBREG)
7825 operands[0] = alter_subreg (operands[0]);
7826 if (GET_CODE (operands[1]) == SUBREG)
7827 operands[1] = alter_subreg (operands[1]);
7828 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7829 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7830 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7831 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7832
7833 (define_expand "negdf2"
7834 [(set (match_operand:DF 0 "register_operand" "")
7835 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7836 "TARGET_FPU"
7837 "")
7838
7839 (define_insn "*negdf2_notv9"
7840 [(set (match_operand:DF 0 "register_operand" "=e,e")
7841 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7842 "TARGET_FPU && ! TARGET_V9"
7843 "@
7844 fnegs\\t%0, %0
7845 #"
7846 [(set_attr "type" "fpmove")
7847 (set_attr "length" "1,2")])
7848
7849 (define_split
7850 [(set (match_operand:DF 0 "register_operand" "")
7851 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7852 "TARGET_FPU
7853 && ! TARGET_V9
7854 && reload_completed
7855 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7856 [(set (match_dup 2) (neg:SF (match_dup 3)))
7857 (set (match_dup 4) (match_dup 5))]
7858 "if (GET_CODE (operands[0]) == SUBREG)
7859 operands[0] = alter_subreg (operands[0]);
7860 if (GET_CODE (operands[1]) == SUBREG)
7861 operands[1] = alter_subreg (operands[1]);
7862 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7863 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7864 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7865 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7866
7867 (define_insn "*negdf2_v9"
7868 [(set (match_operand:DF 0 "register_operand" "=e")
7869 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7870 "TARGET_FPU && TARGET_V9"
7871 "fnegd\\t%1, %0"
7872 [(set_attr "type" "fpmove")
7873 (set_attr "length" "1")])
7874
7875 (define_insn "negsf2"
7876 [(set (match_operand:SF 0 "register_operand" "=f")
7877 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7878 "TARGET_FPU"
7879 "fnegs\\t%1, %0"
7880 [(set_attr "type" "fpmove")
7881 (set_attr "length" "1")])
7882
7883 (define_expand "abstf2"
7884 [(set (match_operand:TF 0 "register_operand" "")
7885 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7886 "TARGET_FPU"
7887 "")
7888
7889 (define_insn "*abstf2_notv9"
7890 [(set (match_operand:TF 0 "register_operand" "=e,e")
7891 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7892 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7893 "TARGET_FPU && ! TARGET_V9"
7894 "@
7895 fabss\\t%0, %0
7896 #"
7897 [(set_attr "type" "fpmove")
7898 (set_attr "length" "1,2")])
7899
7900 (define_split
7901 [(set (match_operand:TF 0 "register_operand" "=e,e")
7902 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7903 "TARGET_FPU
7904 && ! TARGET_V9
7905 && reload_completed
7906 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7907 [(set (match_dup 2) (abs:SF (match_dup 3)))
7908 (set (match_dup 4) (match_dup 5))
7909 (set (match_dup 6) (match_dup 7))]
7910 "if (GET_CODE (operands[0]) == SUBREG)
7911 operands[0] = alter_subreg (operands[0]);
7912 if (GET_CODE (operands[1]) == SUBREG)
7913 operands[1] = alter_subreg (operands[1]);
7914 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7915 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7916 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7917 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7918 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7919 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7920
7921 (define_insn "*abstf2_hq_v9"
7922 [(set (match_operand:TF 0 "register_operand" "=e,e")
7923 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7924 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7925 "@
7926 fabsd\\t%0, %0
7927 fabsq\\t%1, %0"
7928 [(set_attr "type" "fpmove")
7929 (set_attr "length" "1")])
7930
7931 (define_insn "*abstf2_v9"
7932 [(set (match_operand:TF 0 "register_operand" "=e,e")
7933 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7934 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7935 "@
7936 fabsd\\t%0, %0
7937 #"
7938 [(set_attr "type" "fpmove")
7939 (set_attr "length" "1,2")])
7940
7941 (define_split
7942 [(set (match_operand:TF 0 "register_operand" "=e,e")
7943 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7944 "TARGET_FPU
7945 && TARGET_V9
7946 && reload_completed
7947 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7948 [(set (match_dup 2) (abs:DF (match_dup 3)))
7949 (set (match_dup 4) (match_dup 5))]
7950 "if (GET_CODE (operands[0]) == SUBREG)
7951 operands[0] = alter_subreg (operands[0]);
7952 if (GET_CODE (operands[1]) == SUBREG)
7953 operands[1] = alter_subreg (operands[1]);
7954 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7955 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7956 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7957 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7958
7959 (define_expand "absdf2"
7960 [(set (match_operand:DF 0 "register_operand" "")
7961 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7962 "TARGET_FPU"
7963 "")
7964
7965 (define_insn "*absdf2_notv9"
7966 [(set (match_operand:DF 0 "register_operand" "=e,e")
7967 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7968 "TARGET_FPU && ! TARGET_V9"
7969 "@
7970 fabss\\t%0, %0
7971 #"
7972 [(set_attr "type" "fpmove")
7973 (set_attr "length" "1,2")])
7974
7975 (define_split
7976 [(set (match_operand:DF 0 "register_operand" "=e,e")
7977 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7978 "TARGET_FPU
7979 && ! TARGET_V9
7980 && reload_completed
7981 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7982 [(set (match_dup 2) (abs:SF (match_dup 3)))
7983 (set (match_dup 4) (match_dup 5))]
7984 "if (GET_CODE (operands[0]) == SUBREG)
7985 operands[0] = alter_subreg (operands[0]);
7986 if (GET_CODE (operands[1]) == SUBREG)
7987 operands[1] = alter_subreg (operands[1]);
7988 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7989 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7990 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7991 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7992
7993 (define_insn "*absdf2_v9"
7994 [(set (match_operand:DF 0 "register_operand" "=e")
7995 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7996 "TARGET_FPU && TARGET_V9"
7997 "fabsd\\t%1, %0"
7998 [(set_attr "type" "fpmove")
7999 (set_attr "length" "1")])
8000
8001 (define_insn "abssf2"
8002 [(set (match_operand:SF 0 "register_operand" "=f")
8003 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
8004 "TARGET_FPU"
8005 "fabss\\t%1, %0"
8006 [(set_attr "type" "fpmove")
8007 (set_attr "length" "1")])
8008
8009 (define_expand "sqrttf2"
8010 [(set (match_operand:TF 0 "register_operand" "=e")
8011 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
8012 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
8013 "
8014 {
8015 if (! TARGET_HARD_QUAD)
8016 {
8017 rtx slot0, slot1;
8018
8019 if (GET_CODE (operands[0]) != MEM)
8020 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
8021 else
8022 slot0 = operands[0];
8023 if (GET_CODE (operands[1]) != MEM)
8024 {
8025 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
8026 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
8027 }
8028 else
8029 slot1 = operands[1];
8030
8031 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
8032 VOIDmode, 2,
8033 XEXP (slot0, 0), Pmode,
8034 XEXP (slot1, 0), Pmode);
8035
8036 if (GET_CODE (operands[0]) != MEM)
8037 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
8038 DONE;
8039 }
8040 }")
8041
8042 (define_insn "*sqrttf2_hq"
8043 [(set (match_operand:TF 0 "register_operand" "=e")
8044 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
8045 "TARGET_FPU && TARGET_HARD_QUAD"
8046 "fsqrtq\\t%1, %0"
8047 [(set_attr "type" "fpsqrtd")
8048 (set_attr "length" "1")])
8049
8050 (define_insn "sqrtdf2"
8051 [(set (match_operand:DF 0 "register_operand" "=e")
8052 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
8053 "TARGET_FPU"
8054 "fsqrtd\\t%1, %0"
8055 [(set_attr "type" "fpsqrtd")
8056 (set_attr "length" "1")])
8057
8058 (define_insn "sqrtsf2"
8059 [(set (match_operand:SF 0 "register_operand" "=f")
8060 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
8061 "TARGET_FPU"
8062 "fsqrts\\t%1, %0"
8063 [(set_attr "type" "fpsqrts")
8064 (set_attr "length" "1")])
8065 \f
8066 ;;- arithmetic shift instructions
8067
8068 (define_insn "ashlsi3"
8069 [(set (match_operand:SI 0 "register_operand" "=r")
8070 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8071 (match_operand:SI 2 "arith_operand" "rI")))]
8072 ""
8073 "*
8074 {
8075 if (GET_CODE (operands[2]) == CONST_INT
8076 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8077 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8078
8079 return \"sll\\t%1, %2, %0\";
8080 }"
8081 [(set_attr "type" "shift")
8082 (set_attr "length" "1")])
8083
8084 ;; We special case multiplication by two, as add can be done
8085 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8086 (define_insn "*ashlsi3_const1"
8087 [(set (match_operand:SI 0 "register_operand" "=r")
8088 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8089 (const_int 1)))]
8090 ""
8091 "add\\t%1, %1, %0"
8092 [(set_attr "type" "binary")
8093 (set_attr "length" "1")])
8094
8095 (define_expand "ashldi3"
8096 [(set (match_operand:DI 0 "register_operand" "=r")
8097 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8098 (match_operand:SI 2 "arith_operand" "rI")))]
8099 "TARGET_ARCH64 || TARGET_V8PLUS"
8100 "
8101 {
8102 if (! TARGET_ARCH64)
8103 {
8104 if (GET_CODE (operands[2]) == CONST_INT)
8105 FAIL;
8106 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
8107 DONE;
8108 }
8109 }")
8110
8111 ;; We special case multiplication by two, as add can be done
8112 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8113 (define_insn "*ashldi3_const1"
8114 [(set (match_operand:DI 0 "register_operand" "=r")
8115 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8116 (const_int 1)))]
8117 "TARGET_ARCH64"
8118 "add\\t%1, %1, %0"
8119 [(set_attr "type" "binary")
8120 (set_attr "length" "1")])
8121
8122 (define_insn "*ashldi3_sp64"
8123 [(set (match_operand:DI 0 "register_operand" "=r")
8124 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8125 (match_operand:SI 2 "arith_operand" "rI")))]
8126 "TARGET_ARCH64"
8127 "*
8128 {
8129 if (GET_CODE (operands[2]) == CONST_INT
8130 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8131 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8132
8133 return \"sllx\\t%1, %2, %0\";
8134 }"
8135 [(set_attr "type" "shift")
8136 (set_attr "length" "1")])
8137
8138 ;; XXX UGH!
8139 (define_insn "ashldi3_v8plus"
8140 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8141 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8142 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8143 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8144 "TARGET_V8PLUS"
8145 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8146 [(set_attr "length" "5,5,6")])
8147
8148 ;; Optimize (1LL<<x)-1
8149 ;; XXX this also needs to be fixed to handle equal subregs
8150 ;; XXX first before we could re-enable it.
8151 ;(define_insn ""
8152 ; [(set (match_operand:DI 0 "register_operand" "=h")
8153 ; (plus:DI (ashift:DI (const_int 1)
8154 ; (match_operand:SI 1 "arith_operand" "rI"))
8155 ; (const_int -1)))]
8156 ; "0 && TARGET_V8PLUS"
8157 ; "*
8158 ;{
8159 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
8160 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8161 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8162 ;}"
8163 ; [(set_attr "length" "4")])
8164
8165 (define_insn "*cmp_cc_ashift_1"
8166 [(set (reg:CC_NOOV 100)
8167 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8168 (const_int 1))
8169 (const_int 0)))]
8170 ""
8171 "addcc\\t%0, %0, %%g0"
8172 [(set_attr "type" "compare")
8173 (set_attr "length" "1")])
8174
8175 (define_insn "*cmp_cc_set_ashift_1"
8176 [(set (reg:CC_NOOV 100)
8177 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8178 (const_int 1))
8179 (const_int 0)))
8180 (set (match_operand:SI 0 "register_operand" "=r")
8181 (ashift:SI (match_dup 1) (const_int 1)))]
8182 ""
8183 "addcc\\t%1, %1, %0"
8184 [(set_attr "type" "compare")
8185 (set_attr "length" "1")])
8186
8187 (define_insn "ashrsi3"
8188 [(set (match_operand:SI 0 "register_operand" "=r")
8189 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8190 (match_operand:SI 2 "arith_operand" "rI")))]
8191 ""
8192 "*
8193 {
8194 if (GET_CODE (operands[2]) == CONST_INT
8195 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8196 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8197
8198 return \"sra\\t%1, %2, %0\";
8199 }"
8200 [(set_attr "type" "shift")
8201 (set_attr "length" "1")])
8202
8203 (define_insn "*ashrsi3_extend"
8204 [(set (match_operand:DI 0 "register_operand" "=r")
8205 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8206 (match_operand:SI 2 "arith_operand" "r"))))]
8207 "TARGET_ARCH64"
8208 "sra\\t%1, %2, %0"
8209 [(set_attr "type" "shift")
8210 (set_attr "length" "1")])
8211
8212 ;; This handles the case as above, but with constant shift instead of
8213 ;; register. Combiner "simplifies" it for us a little bit though.
8214 (define_insn "*ashrsi3_extend2"
8215 [(set (match_operand:DI 0 "register_operand" "=r")
8216 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8217 (const_int 32))
8218 (match_operand:SI 2 "small_int_or_double" "n")))]
8219 "TARGET_ARCH64
8220 && ((GET_CODE (operands[2]) == CONST_INT
8221 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8222 || (GET_CODE (operands[2]) == CONST_DOUBLE
8223 && !CONST_DOUBLE_HIGH (operands[2])
8224 && CONST_DOUBLE_LOW (operands[2]) >= 32
8225 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8226 "*
8227 {
8228 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8229
8230 return \"sra\\t%1, %2, %0\";
8231 }"
8232 [(set_attr "type" "shift")
8233 (set_attr "length" "1")])
8234
8235 (define_expand "ashrdi3"
8236 [(set (match_operand:DI 0 "register_operand" "=r")
8237 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8238 (match_operand:SI 2 "arith_operand" "rI")))]
8239 "TARGET_ARCH64 || TARGET_V8PLUS"
8240 "
8241 {
8242 if (! TARGET_ARCH64)
8243 {
8244 if (GET_CODE (operands[2]) == CONST_INT)
8245 FAIL; /* prefer generic code in this case */
8246 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8247 DONE;
8248 }
8249 }")
8250
8251 (define_insn ""
8252 [(set (match_operand:DI 0 "register_operand" "=r")
8253 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8254 (match_operand:SI 2 "arith_operand" "rI")))]
8255 "TARGET_ARCH64"
8256 "*
8257 {
8258 if (GET_CODE (operands[2]) == CONST_INT
8259 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8260 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8261
8262 return \"srax\\t%1, %2, %0\";
8263 }"
8264 [(set_attr "type" "shift")
8265 (set_attr "length" "1")])
8266
8267 ;; XXX
8268 (define_insn "ashrdi3_v8plus"
8269 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8270 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8271 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8272 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8273 "TARGET_V8PLUS"
8274 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8275 [(set_attr "length" "5,5,6")])
8276
8277 (define_insn "lshrsi3"
8278 [(set (match_operand:SI 0 "register_operand" "=r")
8279 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8280 (match_operand:SI 2 "arith_operand" "rI")))]
8281 ""
8282 "*
8283 {
8284 if (GET_CODE (operands[2]) == CONST_INT
8285 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8286 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8287
8288 return \"srl\\t%1, %2, %0\";
8289 }"
8290 [(set_attr "type" "shift")
8291 (set_attr "length" "1")])
8292
8293 ;; This handles the case where
8294 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8295 ;; but combiner "simplifies" it for us.
8296 (define_insn "*lshrsi3_extend"
8297 [(set (match_operand:DI 0 "register_operand" "=r")
8298 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8299 (match_operand:SI 2 "arith_operand" "r")) 0)
8300 (match_operand 3 "" "")))]
8301 "TARGET_ARCH64
8302 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8303 && CONST_DOUBLE_HIGH (operands[3]) == 0
8304 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8305 #if HOST_BITS_PER_WIDE_INT >= 64
8306 || (GET_CODE (operands[3]) == CONST_INT
8307 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
8308 #endif
8309 )"
8310 "srl\\t%1, %2, %0"
8311 [(set_attr "type" "shift")
8312 (set_attr "length" "1")])
8313
8314 ;; This handles the case where
8315 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8316 ;; but combiner "simplifies" it for us.
8317 (define_insn "*lshrsi3_extend2"
8318 [(set (match_operand:DI 0 "register_operand" "=r")
8319 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8320 (match_operand 2 "small_int_or_double" "n")
8321 (const_int 32)))]
8322 "TARGET_ARCH64
8323 && ((GET_CODE (operands[2]) == CONST_INT
8324 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8325 || (GET_CODE (operands[2]) == CONST_DOUBLE
8326 && CONST_DOUBLE_HIGH (operands[2]) == 0
8327 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8328 "*
8329 {
8330 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8331
8332 return \"srl\\t%1, %2, %0\";
8333 }"
8334 [(set_attr "type" "shift")
8335 (set_attr "length" "1")])
8336
8337 (define_expand "lshrdi3"
8338 [(set (match_operand:DI 0 "register_operand" "=r")
8339 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8340 (match_operand:SI 2 "arith_operand" "rI")))]
8341 "TARGET_ARCH64 || TARGET_V8PLUS"
8342 "
8343 {
8344 if (! TARGET_ARCH64)
8345 {
8346 if (GET_CODE (operands[2]) == CONST_INT)
8347 FAIL;
8348 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8349 DONE;
8350 }
8351 }")
8352
8353 (define_insn ""
8354 [(set (match_operand:DI 0 "register_operand" "=r")
8355 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8356 (match_operand:SI 2 "arith_operand" "rI")))]
8357 "TARGET_ARCH64"
8358 "*
8359 {
8360 if (GET_CODE (operands[2]) == CONST_INT
8361 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8362 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8363
8364 return \"srlx\\t%1, %2, %0\";
8365 }"
8366 [(set_attr "type" "shift")
8367 (set_attr "length" "1")])
8368
8369 ;; XXX
8370 (define_insn "lshrdi3_v8plus"
8371 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8372 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8373 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8374 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8375 "TARGET_V8PLUS"
8376 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8377 [(set_attr "length" "5,5,6")])
8378
8379 (define_insn ""
8380 [(set (match_operand:SI 0 "register_operand" "=r")
8381 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8382 (const_int 32)) 4)
8383 (match_operand:SI 2 "small_int_or_double" "n")))]
8384 "TARGET_ARCH64
8385 && ((GET_CODE (operands[2]) == CONST_INT
8386 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8387 || (GET_CODE (operands[2]) == CONST_DOUBLE
8388 && !CONST_DOUBLE_HIGH (operands[2])
8389 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8390 "*
8391 {
8392 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8393
8394 return \"srax\\t%1, %2, %0\";
8395 }"
8396 [(set_attr "type" "shift")
8397 (set_attr "length" "1")])
8398
8399 (define_insn ""
8400 [(set (match_operand:SI 0 "register_operand" "=r")
8401 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8402 (const_int 32)) 4)
8403 (match_operand:SI 2 "small_int_or_double" "n")))]
8404 "TARGET_ARCH64
8405 && ((GET_CODE (operands[2]) == CONST_INT
8406 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8407 || (GET_CODE (operands[2]) == CONST_DOUBLE
8408 && !CONST_DOUBLE_HIGH (operands[2])
8409 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8410 "*
8411 {
8412 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8413
8414 return \"srlx\\t%1, %2, %0\";
8415 }"
8416 [(set_attr "type" "shift")
8417 (set_attr "length" "1")])
8418
8419 (define_insn ""
8420 [(set (match_operand:SI 0 "register_operand" "=r")
8421 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8422 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8423 (match_operand:SI 3 "small_int_or_double" "n")))]
8424 "TARGET_ARCH64
8425 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8426 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8427 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8428 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8429 "*
8430 {
8431 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8432
8433 return \"srax\\t%1, %2, %0\";
8434 }"
8435 [(set_attr "type" "shift")
8436 (set_attr "length" "1")])
8437
8438 (define_insn ""
8439 [(set (match_operand:SI 0 "register_operand" "=r")
8440 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8441 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8442 (match_operand:SI 3 "small_int_or_double" "n")))]
8443 "TARGET_ARCH64
8444 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8445 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8446 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8447 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8448 "*
8449 {
8450 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8451
8452 return \"srlx\\t%1, %2, %0\";
8453 }"
8454 [(set_attr "type" "shift")
8455 (set_attr "length" "1")])
8456 \f
8457 ;; Unconditional and other jump instructions
8458 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8459 ;; following insn is never executed. This saves us a nop. Dbx does not
8460 ;; handle such branches though, so we only use them when optimizing.
8461 (define_insn "jump"
8462 [(set (pc) (label_ref (match_operand 0 "" "")))]
8463 ""
8464 "*
8465 {
8466 /* TurboSparc is reported to have problems with
8467 with
8468 foo: b,a foo
8469 i.e. an empty loop with the annul bit set. The workaround is to use
8470 foo: b foo; nop
8471 instead. */
8472
8473 if (! TARGET_V9 && flag_delayed_branch
8474 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8475 == INSN_ADDRESSES (INSN_UID (insn))))
8476 return \"b\\t%l0%#\";
8477 else
8478 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8479 }"
8480 [(set_attr "type" "uncond_branch")])
8481
8482 (define_expand "tablejump"
8483 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8484 (use (label_ref (match_operand 1 "" "")))])]
8485 ""
8486 "
8487 {
8488 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8489 abort ();
8490
8491 /* In pic mode, our address differences are against the base of the
8492 table. Add that base value back in; CSE ought to be able to combine
8493 the two address loads. */
8494 if (flag_pic)
8495 {
8496 rtx tmp, tmp2;
8497 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8498 tmp2 = operands[0];
8499 if (CASE_VECTOR_MODE != Pmode)
8500 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8501 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8502 operands[0] = memory_address (Pmode, tmp);
8503 }
8504 }")
8505
8506 (define_insn "*tablejump_sp32"
8507 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8508 (use (label_ref (match_operand 1 "" "")))]
8509 "! TARGET_ARCH64"
8510 "jmp\\t%a0%#"
8511 [(set_attr "type" "uncond_branch")])
8512
8513 (define_insn "*tablejump_sp64"
8514 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8515 (use (label_ref (match_operand 1 "" "")))]
8516 "TARGET_ARCH64"
8517 "jmp\\t%a0%#"
8518 [(set_attr "type" "uncond_branch")])
8519
8520 ;; This pattern recognizes the "instruction" that appears in
8521 ;; a function call that wants a structure value,
8522 ;; to inform the called function if compiled with Sun CC.
8523 ;(define_insn "*unimp_insn"
8524 ; [(match_operand:SI 0 "immediate_operand" "")]
8525 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8526 ; "unimp\\t%0"
8527 ; [(set_attr "type" "marker")])
8528
8529 ;;- jump to subroutine
8530 (define_expand "call"
8531 ;; Note that this expression is not used for generating RTL.
8532 ;; All the RTL is generated explicitly below.
8533 [(call (match_operand 0 "call_operand" "")
8534 (match_operand 3 "" "i"))]
8535 ;; operands[2] is next_arg_register
8536 ;; operands[3] is struct_value_size_rtx.
8537 ""
8538 "
8539 {
8540 rtx fn_rtx, nregs_rtx;
8541
8542 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8543 abort ();
8544
8545 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8546 {
8547 /* This is really a PIC sequence. We want to represent
8548 it as a funny jump so its delay slots can be filled.
8549
8550 ??? But if this really *is* a CALL, will not it clobber the
8551 call-clobbered registers? We lose this if it is a JUMP_INSN.
8552 Why cannot we have delay slots filled if it were a CALL? */
8553
8554 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8555 emit_jump_insn
8556 (gen_rtx_PARALLEL
8557 (VOIDmode,
8558 gen_rtvec (3,
8559 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8560 operands[3],
8561 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8562 else
8563 emit_jump_insn
8564 (gen_rtx_PARALLEL
8565 (VOIDmode,
8566 gen_rtvec (2,
8567 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8568 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8569 goto finish_call;
8570 }
8571
8572 fn_rtx = operands[0];
8573
8574 /* Count the number of parameter registers being used by this call.
8575 if that argument is NULL, it means we are using them all, which
8576 means 6 on the sparc. */
8577 #if 0
8578 if (operands[2])
8579 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8580 else
8581 nregs_rtx = GEN_INT (6);
8582 #else
8583 nregs_rtx = const0_rtx;
8584 #endif
8585
8586 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8587 emit_call_insn
8588 (gen_rtx_PARALLEL
8589 (VOIDmode,
8590 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8591 operands[3],
8592 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8593 else
8594 emit_call_insn
8595 (gen_rtx_PARALLEL
8596 (VOIDmode,
8597 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8598 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8599
8600 finish_call:
8601 #if 0
8602 /* If this call wants a structure value,
8603 emit an unimp insn to let the called function know about this. */
8604 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8605 {
8606 rtx insn = emit_insn (operands[3]);
8607 SCHED_GROUP_P (insn) = 1;
8608 }
8609 #endif
8610
8611 DONE;
8612 }")
8613
8614 ;; We can't use the same pattern for these two insns, because then registers
8615 ;; in the address may not be properly reloaded.
8616
8617 (define_insn "*call_address_sp32"
8618 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8619 (match_operand 1 "" ""))
8620 (clobber (reg:SI 15))]
8621 ;;- Do not use operand 1 for most machines.
8622 "! TARGET_ARCH64"
8623 "call\\t%a0, %1%#"
8624 [(set_attr "type" "call")])
8625
8626 (define_insn "*call_symbolic_sp32"
8627 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8628 (match_operand 1 "" ""))
8629 (clobber (reg:SI 15))]
8630 ;;- Do not use operand 1 for most machines.
8631 "! TARGET_ARCH64"
8632 "call\\t%a0, %1%#"
8633 [(set_attr "type" "call")])
8634
8635 (define_insn "*call_address_sp64"
8636 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8637 (match_operand 1 "" ""))
8638 (clobber (reg:DI 15))]
8639 ;;- Do not use operand 1 for most machines.
8640 "TARGET_ARCH64"
8641 "call\\t%a0, %1%#"
8642 [(set_attr "type" "call")])
8643
8644 (define_insn "*call_symbolic_sp64"
8645 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8646 (match_operand 1 "" ""))
8647 (clobber (reg:DI 15))]
8648 ;;- Do not use operand 1 for most machines.
8649 "TARGET_ARCH64"
8650 "call\\t%a0, %1%#"
8651 [(set_attr "type" "call")])
8652
8653 ;; This is a call that wants a structure value.
8654 ;; There is no such critter for v9 (??? we may need one anyway).
8655 (define_insn "*call_address_struct_value_sp32"
8656 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8657 (match_operand 1 "" ""))
8658 (match_operand 2 "immediate_operand" "")
8659 (clobber (reg:SI 15))]
8660 ;;- Do not use operand 1 for most machines.
8661 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8662 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8663 [(set_attr "type" "call_no_delay_slot")])
8664
8665 ;; This is a call that wants a structure value.
8666 ;; There is no such critter for v9 (??? we may need one anyway).
8667 (define_insn "*call_symbolic_struct_value_sp32"
8668 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8669 (match_operand 1 "" ""))
8670 (match_operand 2 "immediate_operand" "")
8671 (clobber (reg:SI 15))]
8672 ;;- Do not use operand 1 for most machines.
8673 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8674 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8675 [(set_attr "type" "call_no_delay_slot")])
8676
8677 ;; This is a call that may want a structure value. This is used for
8678 ;; untyped_calls.
8679 (define_insn "*call_address_untyped_struct_value_sp32"
8680 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8681 (match_operand 1 "" ""))
8682 (match_operand 2 "immediate_operand" "")
8683 (clobber (reg:SI 15))]
8684 ;;- Do not use operand 1 for most machines.
8685 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8686 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8687 [(set_attr "type" "call_no_delay_slot")])
8688
8689 ;; This is a call that wants a structure value.
8690 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8691 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8692 (match_operand 1 "" ""))
8693 (match_operand 2 "immediate_operand" "")
8694 (clobber (reg:SI 15))]
8695 ;;- Do not use operand 1 for most machines.
8696 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8697 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8698 [(set_attr "type" "call_no_delay_slot")])
8699
8700 (define_expand "call_value"
8701 ;; Note that this expression is not used for generating RTL.
8702 ;; All the RTL is generated explicitly below.
8703 [(set (match_operand 0 "register_operand" "=rf")
8704 (call (match_operand 1 "" "")
8705 (match_operand 4 "" "")))]
8706 ;; operand 2 is stack_size_rtx
8707 ;; operand 3 is next_arg_register
8708 ""
8709 "
8710 {
8711 rtx fn_rtx, nregs_rtx;
8712 rtvec vec;
8713
8714 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8715 abort ();
8716
8717 fn_rtx = operands[1];
8718
8719 #if 0
8720 if (operands[3])
8721 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8722 else
8723 nregs_rtx = GEN_INT (6);
8724 #else
8725 nregs_rtx = const0_rtx;
8726 #endif
8727
8728 vec = gen_rtvec (2,
8729 gen_rtx_SET (VOIDmode, operands[0],
8730 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8731 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8732
8733 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8734
8735 DONE;
8736 }")
8737
8738 (define_insn "*call_value_address_sp32"
8739 [(set (match_operand 0 "" "=rf")
8740 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8741 (match_operand 2 "" "")))
8742 (clobber (reg:SI 15))]
8743 ;;- Do not use operand 2 for most machines.
8744 "! TARGET_ARCH64"
8745 "call\\t%a1, %2%#"
8746 [(set_attr "type" "call")])
8747
8748 (define_insn "*call_value_symbolic_sp32"
8749 [(set (match_operand 0 "" "=rf")
8750 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8751 (match_operand 2 "" "")))
8752 (clobber (reg:SI 15))]
8753 ;;- Do not use operand 2 for most machines.
8754 "! TARGET_ARCH64"
8755 "call\\t%a1, %2%#"
8756 [(set_attr "type" "call")])
8757
8758 (define_insn "*call_value_address_sp64"
8759 [(set (match_operand 0 "" "")
8760 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8761 (match_operand 2 "" "")))
8762 (clobber (reg:DI 15))]
8763 ;;- Do not use operand 2 for most machines.
8764 "TARGET_ARCH64"
8765 "call\\t%a1, %2%#"
8766 [(set_attr "type" "call")])
8767
8768 (define_insn "*call_value_symbolic_sp64"
8769 [(set (match_operand 0 "" "")
8770 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8771 (match_operand 2 "" "")))
8772 (clobber (reg:DI 15))]
8773 ;;- Do not use operand 2 for most machines.
8774 "TARGET_ARCH64"
8775 "call\\t%a1, %2%#"
8776 [(set_attr "type" "call")])
8777
8778 (define_expand "untyped_call"
8779 [(parallel [(call (match_operand 0 "" "")
8780 (const_int 0))
8781 (match_operand 1 "" "")
8782 (match_operand 2 "" "")])]
8783 ""
8784 "
8785 {
8786 int i;
8787
8788 /* Pass constm1 to indicate that it may expect a structure value, but
8789 we don't know what size it is. */
8790 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8791
8792 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8793 {
8794 rtx set = XVECEXP (operands[2], 0, i);
8795 emit_move_insn (SET_DEST (set), SET_SRC (set));
8796 }
8797
8798 /* The optimizer does not know that the call sets the function value
8799 registers we stored in the result block. We avoid problems by
8800 claiming that all hard registers are used and clobbered at this
8801 point. */
8802 emit_insn (gen_blockage ());
8803
8804 DONE;
8805 }")
8806
8807 ;;- tail calls
8808 (define_expand "sibcall"
8809 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8810 (return)])]
8811 ""
8812 "")
8813
8814 (define_insn "*sibcall_symbolic_sp32"
8815 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8816 (match_operand 1 "" ""))
8817 (return)]
8818 "! TARGET_ARCH64"
8819 "* return output_sibcall(insn, operands[0]);"
8820 [(set_attr "type" "sibcall")])
8821
8822 (define_insn "*sibcall_symbolic_sp64"
8823 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8824 (match_operand 1 "" ""))
8825 (return)]
8826 "TARGET_ARCH64"
8827 "* return output_sibcall(insn, operands[0]);"
8828 [(set_attr "type" "sibcall")])
8829
8830 (define_expand "sibcall_value"
8831 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8832 (call (match_operand 1 "" "") (const_int 0)))
8833 (return)])]
8834 ""
8835 "")
8836
8837 (define_insn "*sibcall_value_symbolic_sp32"
8838 [(set (match_operand 0 "" "=rf")
8839 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8840 (match_operand 2 "" "")))
8841 (return)]
8842 "! TARGET_ARCH64"
8843 "* return output_sibcall(insn, operands[1]);"
8844 [(set_attr "type" "sibcall")])
8845
8846 (define_insn "*sibcall_value_symbolic_sp64"
8847 [(set (match_operand 0 "" "")
8848 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8849 (match_operand 2 "" "")))
8850 (return)]
8851 "TARGET_ARCH64"
8852 "* return output_sibcall(insn, operands[1]);"
8853 [(set_attr "type" "sibcall")])
8854
8855 (define_expand "sibcall_epilogue"
8856 [(const_int 0)]
8857 ""
8858 "DONE;")
8859
8860 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8861 ;; all of memory. This blocks insns from being moved across this point.
8862
8863 (define_insn "blockage"
8864 [(unspec_volatile [(const_int 0)] 0)]
8865 ""
8866 ""
8867 [(set_attr "length" "0")])
8868
8869 ;; Prepare to return any type including a structure value.
8870
8871 (define_expand "untyped_return"
8872 [(match_operand:BLK 0 "memory_operand" "")
8873 (match_operand 1 "" "")]
8874 ""
8875 "
8876 {
8877 rtx valreg1 = gen_rtx_REG (DImode, 24);
8878 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8879 rtx result = operands[0];
8880
8881 if (! TARGET_ARCH64)
8882 {
8883 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8884 ? 15 : 31));
8885 rtx value = gen_reg_rtx (SImode);
8886
8887 /* Fetch the instruction where we will return to and see if it's an unimp
8888 instruction (the most significant 10 bits will be zero). If so,
8889 update the return address to skip the unimp instruction. */
8890 emit_move_insn (value,
8891 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8892 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8893 emit_insn (gen_update_return (rtnreg, value));
8894 }
8895
8896 /* Reload the function value registers. */
8897 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8898 emit_move_insn (valreg2,
8899 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8900
8901 /* Put USE insns before the return. */
8902 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8903 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8904
8905 /* Construct the return. */
8906 expand_null_return ();
8907
8908 DONE;
8909 }")
8910
8911 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8912 ;; and parts of the compiler don't want to believe that the add is needed.
8913
8914 (define_insn "update_return"
8915 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8916 (match_operand:SI 1 "register_operand" "r")] 1)]
8917 "! TARGET_ARCH64"
8918 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8919 [(set_attr "type" "multi")])
8920 \f
8921 (define_insn "return"
8922 [(return)
8923 (use (reg:SI 31))]
8924 "! TARGET_EPILOGUE"
8925 "* return output_return (operands);"
8926 [(set_attr "type" "return")])
8927
8928 (define_peephole
8929 [(set (match_operand:SI 0 "register_operand" "=r")
8930 (match_operand:SI 1 "arith_operand" "rI"))
8931 (parallel [(return)
8932 (use (reg:SI 31))])]
8933 "sparc_return_peephole_ok (operands[0], operands[1])"
8934 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8935
8936 (define_insn "nop"
8937 [(const_int 0)]
8938 ""
8939 "nop"
8940 [(set_attr "type" "ialu")
8941 (set_attr "length" "1")])
8942
8943 (define_expand "indirect_jump"
8944 [(set (pc) (match_operand 0 "address_operand" "p"))]
8945 ""
8946 "")
8947
8948 (define_insn "*branch_sp32"
8949 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8950 "! TARGET_ARCH64"
8951 "jmp\\t%a0%#"
8952 [(set_attr "type" "uncond_branch")])
8953
8954 (define_insn "*branch_sp64"
8955 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8956 "TARGET_ARCH64"
8957 "jmp\\t%a0%#"
8958 [(set_attr "type" "uncond_branch")])
8959
8960 ;; ??? Doesn't work with -mflat.
8961 (define_expand "nonlocal_goto"
8962 [(match_operand:SI 0 "general_operand" "")
8963 (match_operand:SI 1 "general_operand" "")
8964 (match_operand:SI 2 "general_operand" "")
8965 (match_operand:SI 3 "" "")]
8966 ""
8967 "
8968 {
8969 #if 0
8970 rtx chain = operands[0];
8971 #endif
8972 rtx fp = operands[1];
8973 rtx stack = operands[2];
8974 rtx lab = operands[3];
8975 rtx labreg;
8976
8977 /* Trap instruction to flush all the register windows. */
8978 emit_insn (gen_flush_register_windows ());
8979
8980 /* Load the fp value for the containing fn into %fp. This is needed
8981 because STACK refers to %fp. Note that virtual register instantiation
8982 fails if the virtual %fp isn't set from a register. */
8983 if (GET_CODE (fp) != REG)
8984 fp = force_reg (Pmode, fp);
8985 emit_move_insn (virtual_stack_vars_rtx, fp);
8986
8987 /* Find the containing function's current nonlocal goto handler,
8988 which will do any cleanups and then jump to the label. */
8989 labreg = gen_rtx_REG (Pmode, 8);
8990 emit_move_insn (labreg, lab);
8991
8992 /* Restore %fp from stack pointer value for containing function.
8993 The restore insn that follows will move this to %sp,
8994 and reload the appropriate value into %fp. */
8995 emit_move_insn (frame_pointer_rtx, stack);
8996
8997 /* USE of frame_pointer_rtx added for consistency; not clear if
8998 really needed. */
8999 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
9000 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9001
9002 #if 0
9003 /* Return, restoring reg window and jumping to goto handler. */
9004 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
9005 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
9006 {
9007 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
9008 static_chain_rtx,
9009 chain));
9010 emit_barrier ();
9011 DONE;
9012 }
9013 /* Put in the static chain register the nonlocal label address. */
9014 emit_move_insn (static_chain_rtx, chain);
9015 #endif
9016
9017 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
9018 emit_jump_insn (gen_goto_handler_and_restore (labreg));
9019 emit_barrier ();
9020 DONE;
9021 }")
9022
9023 ;; Special trap insn to flush register windows.
9024 (define_insn "flush_register_windows"
9025 [(unspec_volatile [(const_int 0)] 1)]
9026 ""
9027 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
9028 [(set_attr "type" "misc")
9029 (set_attr "length" "1")])
9030
9031 (define_insn "goto_handler_and_restore"
9032 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
9033 "GET_MODE (operands[0]) == Pmode"
9034 "jmp\\t%0+0\\n\\trestore"
9035 [(set_attr "type" "misc")
9036 (set_attr "length" "2")])
9037
9038 ;;(define_insn "goto_handler_and_restore_v9"
9039 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
9040 ;; (match_operand:SI 1 "register_operand" "=r,r")
9041 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9042 ;; "TARGET_V9 && ! TARGET_ARCH64"
9043 ;; "@
9044 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9045 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9046 ;; [(set_attr "type" "misc")
9047 ;; (set_attr "length" "2,3")])
9048 ;;
9049 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
9050 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
9051 ;; (match_operand:DI 1 "register_operand" "=r,r")
9052 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9053 ;; "TARGET_V9 && TARGET_ARCH64"
9054 ;; "@
9055 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9056 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9057 ;; [(set_attr "type" "misc")
9058 ;; (set_attr "length" "2,3")])
9059
9060 ;; For __builtin_setjmp we need to flush register windows iff the function
9061 ;; calls alloca as well, because otherwise the register window might be
9062 ;; saved after %sp adjustement and thus setjmp would crash
9063 (define_expand "builtin_setjmp_setup"
9064 [(match_operand 0 "register_operand" "r")]
9065 ""
9066 "
9067 {
9068 emit_insn (gen_do_builtin_setjmp_setup ());
9069 DONE;
9070 }")
9071
9072 (define_insn "do_builtin_setjmp_setup"
9073 [(unspec_volatile [(const_int 0)] 5)]
9074 ""
9075 "*
9076 {
9077 if (!current_function_calls_alloca)
9078 return \"\";
9079 if (TARGET_V9)
9080 return \"flushw\";
9081 return \"ta\\t3\";
9082 }"
9083 [(set_attr "type" "misc")
9084 (set_attr "length" "1")])
9085
9086 ;; Pattern for use after a setjmp to store FP and the return register
9087 ;; into the stack area.
9088
9089 (define_expand "setjmp"
9090 [(const_int 0)]
9091 ""
9092 "
9093 {
9094 if (TARGET_ARCH64)
9095 emit_insn (gen_setjmp_64 ());
9096 else
9097 emit_insn (gen_setjmp_32 ());
9098 DONE;
9099 }")
9100
9101 (define_expand "setjmp_32"
9102 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
9103 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
9104 ""
9105 "
9106 { operands[0] = frame_pointer_rtx; }")
9107
9108 (define_expand "setjmp_64"
9109 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
9110 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
9111 ""
9112 "
9113 { operands[0] = frame_pointer_rtx; }")
9114
9115 ;; Special pattern for the FLUSH instruction.
9116
9117 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
9118 ; of the define_insn otherwise missing a mode. We make "flush", aka
9119 ; gen_flush, the default one since sparc_initialize_trampoline uses
9120 ; it on SImode mem values.
9121
9122 (define_insn "flush"
9123 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
9124 ""
9125 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9126 [(set_attr "type" "misc")])
9127
9128 (define_insn "flushdi"
9129 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
9130 ""
9131 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9132 [(set_attr "type" "misc")])
9133
9134 \f
9135 ;; find first set.
9136
9137 ;; The scan instruction searches from the most significant bit while ffs
9138 ;; searches from the least significant bit. The bit index and treatment of
9139 ;; zero also differ. It takes at least 7 instructions to get the proper
9140 ;; result. Here is an obvious 8 instruction sequence.
9141
9142 ;; XXX
9143 (define_insn "ffssi2"
9144 [(set (match_operand:SI 0 "register_operand" "=&r")
9145 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
9146 (clobber (match_scratch:SI 2 "=&r"))]
9147 "TARGET_SPARCLITE || TARGET_SPARCLET"
9148 "*
9149 {
9150 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\";
9151 }"
9152 [(set_attr "type" "multi")
9153 (set_attr "length" "8")])
9154
9155 ;; ??? This should be a define expand, so that the extra instruction have
9156 ;; a chance of being optimized away.
9157
9158 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9159 ;; does, but no one uses that and we don't have a switch for it.
9160 ;
9161 ;(define_insn "ffsdi2"
9162 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9163 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9164 ; (clobber (match_scratch:DI 2 "=&r"))]
9165 ; "TARGET_ARCH64"
9166 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9167 ; [(set_attr "type" "multi")
9168 ; (set_attr "length" "4")])
9169
9170
9171 \f
9172 ;; Peepholes go at the end.
9173
9174 ;; Optimize consecutive loads or stores into ldd and std when possible.
9175 ;; The conditions in which we do this are very restricted and are
9176 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9177
9178 (define_peephole
9179 [(set (match_operand:SI 0 "memory_operand" "")
9180 (const_int 0))
9181 (set (match_operand:SI 1 "memory_operand" "")
9182 (const_int 0))]
9183 "TARGET_V9
9184 && ! MEM_VOLATILE_P (operands[0])
9185 && ! MEM_VOLATILE_P (operands[1])
9186 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
9187 "stx\\t%%g0, %0")
9188
9189 (define_peephole
9190 [(set (match_operand:SI 0 "memory_operand" "")
9191 (const_int 0))
9192 (set (match_operand:SI 1 "memory_operand" "")
9193 (const_int 0))]
9194 "TARGET_V9
9195 && ! MEM_VOLATILE_P (operands[0])
9196 && ! MEM_VOLATILE_P (operands[1])
9197 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
9198 "stx\\t%%g0, %1")
9199
9200 (define_peephole
9201 [(set (match_operand:SI 0 "register_operand" "=rf")
9202 (match_operand:SI 1 "memory_operand" ""))
9203 (set (match_operand:SI 2 "register_operand" "=rf")
9204 (match_operand:SI 3 "memory_operand" ""))]
9205 "registers_ok_for_ldd_peep (operands[0], operands[2])
9206 && ! MEM_VOLATILE_P (operands[1])
9207 && ! MEM_VOLATILE_P (operands[3])
9208 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9209 "ldd\\t%1, %0")
9210
9211 (define_peephole
9212 [(set (match_operand:SI 0 "memory_operand" "")
9213 (match_operand:SI 1 "register_operand" "rf"))
9214 (set (match_operand:SI 2 "memory_operand" "")
9215 (match_operand:SI 3 "register_operand" "rf"))]
9216 "registers_ok_for_ldd_peep (operands[1], operands[3])
9217 && ! MEM_VOLATILE_P (operands[0])
9218 && ! MEM_VOLATILE_P (operands[2])
9219 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9220 "std\\t%1, %0")
9221
9222 (define_peephole
9223 [(set (match_operand:SF 0 "register_operand" "=fr")
9224 (match_operand:SF 1 "memory_operand" ""))
9225 (set (match_operand:SF 2 "register_operand" "=fr")
9226 (match_operand:SF 3 "memory_operand" ""))]
9227 "registers_ok_for_ldd_peep (operands[0], operands[2])
9228 && ! MEM_VOLATILE_P (operands[1])
9229 && ! MEM_VOLATILE_P (operands[3])
9230 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9231 "ldd\\t%1, %0")
9232
9233 (define_peephole
9234 [(set (match_operand:SF 0 "memory_operand" "")
9235 (match_operand:SF 1 "register_operand" "fr"))
9236 (set (match_operand:SF 2 "memory_operand" "")
9237 (match_operand:SF 3 "register_operand" "fr"))]
9238 "registers_ok_for_ldd_peep (operands[1], operands[3])
9239 && ! MEM_VOLATILE_P (operands[0])
9240 && ! MEM_VOLATILE_P (operands[2])
9241 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9242 "std\\t%1, %0")
9243
9244 (define_peephole
9245 [(set (match_operand:SI 0 "register_operand" "=rf")
9246 (match_operand:SI 1 "memory_operand" ""))
9247 (set (match_operand:SI 2 "register_operand" "=rf")
9248 (match_operand:SI 3 "memory_operand" ""))]
9249 "registers_ok_for_ldd_peep (operands[2], operands[0])
9250 && ! MEM_VOLATILE_P (operands[3])
9251 && ! MEM_VOLATILE_P (operands[1])
9252 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9253 "ldd\\t%3, %2")
9254
9255 (define_peephole
9256 [(set (match_operand:SI 0 "memory_operand" "")
9257 (match_operand:SI 1 "register_operand" "rf"))
9258 (set (match_operand:SI 2 "memory_operand" "")
9259 (match_operand:SI 3 "register_operand" "rf"))]
9260 "registers_ok_for_ldd_peep (operands[3], operands[1])
9261 && ! MEM_VOLATILE_P (operands[2])
9262 && ! MEM_VOLATILE_P (operands[0])
9263 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9264 "std\\t%3, %2")
9265
9266 (define_peephole
9267 [(set (match_operand:SF 0 "register_operand" "=fr")
9268 (match_operand:SF 1 "memory_operand" ""))
9269 (set (match_operand:SF 2 "register_operand" "=fr")
9270 (match_operand:SF 3 "memory_operand" ""))]
9271 "registers_ok_for_ldd_peep (operands[2], operands[0])
9272 && ! MEM_VOLATILE_P (operands[3])
9273 && ! MEM_VOLATILE_P (operands[1])
9274 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9275 "ldd\\t%3, %2")
9276
9277 (define_peephole
9278 [(set (match_operand:SF 0 "memory_operand" "")
9279 (match_operand:SF 1 "register_operand" "fr"))
9280 (set (match_operand:SF 2 "memory_operand" "")
9281 (match_operand:SF 3 "register_operand" "fr"))]
9282 "registers_ok_for_ldd_peep (operands[3], operands[1])
9283 && ! MEM_VOLATILE_P (operands[2])
9284 && ! MEM_VOLATILE_P (operands[0])
9285 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9286 "std\\t%3, %2")
9287
9288 ;; Optimize the case of following a reg-reg move with a test
9289 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9290 ;; This can result from a float to fix conversion.
9291
9292 (define_peephole
9293 [(set (match_operand:SI 0 "register_operand" "=r")
9294 (match_operand:SI 1 "register_operand" "r"))
9295 (set (reg:CC 100)
9296 (compare:CC (match_operand:SI 2 "register_operand" "r")
9297 (const_int 0)))]
9298 "(rtx_equal_p (operands[2], operands[0])
9299 || rtx_equal_p (operands[2], operands[1]))
9300 && ! FP_REG_P (operands[0])
9301 && ! FP_REG_P (operands[1])"
9302 "orcc\\t%1, 0, %0")
9303
9304 (define_peephole
9305 [(set (match_operand:DI 0 "register_operand" "=r")
9306 (match_operand:DI 1 "register_operand" "r"))
9307 (set (reg:CCX 100)
9308 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9309 (const_int 0)))]
9310 "TARGET_ARCH64
9311 && (rtx_equal_p (operands[2], operands[0])
9312 || rtx_equal_p (operands[2], operands[1]))
9313 && ! FP_REG_P (operands[0])
9314 && ! FP_REG_P (operands[1])"
9315 "orcc\\t%1, 0, %0")
9316
9317 ;; Return peepholes. First the "normal" ones.
9318 ;; These are necessary to catch insns ending up in the epilogue delay list.
9319
9320 (define_insn "*return_qi"
9321 [(set (match_operand:QI 0 "restore_operand" "")
9322 (match_operand:QI 1 "arith_operand" "rI"))
9323 (return)]
9324 "! TARGET_EPILOGUE"
9325 "*
9326 {
9327 if (! TARGET_ARCH64 && current_function_returns_struct)
9328 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9329 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9330 || IN_OR_GLOBAL_P (operands[1])))
9331 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9332 else
9333 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9334 }"
9335 [(set_attr "type" "multi")])
9336
9337 (define_insn "*return_hi"
9338 [(set (match_operand:HI 0 "restore_operand" "")
9339 (match_operand:HI 1 "arith_operand" "rI"))
9340 (return)]
9341 "! TARGET_EPILOGUE"
9342 "*
9343 {
9344 if (! TARGET_ARCH64 && current_function_returns_struct)
9345 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9346 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9347 || IN_OR_GLOBAL_P (operands[1])))
9348 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9349 else
9350 return \"ret\;restore %%g0, %1, %Y0\";
9351 }"
9352 [(set_attr "type" "multi")])
9353
9354 (define_insn "*return_si"
9355 [(set (match_operand:SI 0 "restore_operand" "")
9356 (match_operand:SI 1 "arith_operand" "rI"))
9357 (return)]
9358 "! TARGET_EPILOGUE"
9359 "*
9360 {
9361 if (! TARGET_ARCH64 && current_function_returns_struct)
9362 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9363 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9364 || IN_OR_GLOBAL_P (operands[1])))
9365 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9366 else
9367 return \"ret\;restore %%g0, %1, %Y0\";
9368 }"
9369 [(set_attr "type" "multi")])
9370
9371 ;; The following pattern is only generated by delayed-branch scheduling,
9372 ;; when the insn winds up in the epilogue. This can happen not only when
9373 ;; ! TARGET_FPU because we move complex types around by parts using
9374 ;; SF mode SUBREGs.
9375 (define_insn "*return_sf_no_fpu"
9376 [(set (match_operand:SF 0 "restore_operand" "=r")
9377 (match_operand:SF 1 "register_operand" "r"))
9378 (return)]
9379 "! TARGET_EPILOGUE"
9380 "*
9381 {
9382 if (! TARGET_ARCH64 && current_function_returns_struct)
9383 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9384 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9385 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9386 else
9387 return \"ret\;restore %%g0, %1, %Y0\";
9388 }"
9389 [(set_attr "type" "multi")])
9390
9391 (define_insn "*return_df_no_fpu"
9392 [(set (match_operand:DF 0 "restore_operand" "=r")
9393 (match_operand:DF 1 "register_operand" "r"))
9394 (return)]
9395 "! TARGET_EPILOGUE && TARGET_ARCH64"
9396 "*
9397 {
9398 if (IN_OR_GLOBAL_P (operands[1]))
9399 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9400 else
9401 return \"ret\;restore %%g0, %1, %Y0\";
9402 }"
9403 [(set_attr "type" "multi")])
9404
9405 (define_insn "*return_addsi"
9406 [(set (match_operand:SI 0 "restore_operand" "")
9407 (plus:SI (match_operand:SI 1 "register_operand" "r")
9408 (match_operand:SI 2 "arith_operand" "rI")))
9409 (return)]
9410 "! TARGET_EPILOGUE"
9411 "*
9412 {
9413 if (! TARGET_ARCH64 && current_function_returns_struct)
9414 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9415 /* If operands are global or in registers, can use return */
9416 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9417 && (GET_CODE (operands[2]) == CONST_INT
9418 || IN_OR_GLOBAL_P (operands[2])))
9419 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9420 else
9421 return \"ret\;restore %r1, %2, %Y0\";
9422 }"
9423 [(set_attr "type" "multi")])
9424
9425 (define_insn "*return_losum_si"
9426 [(set (match_operand:SI 0 "restore_operand" "")
9427 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9428 (match_operand:SI 2 "immediate_operand" "in")))
9429 (return)]
9430 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9431 "*
9432 {
9433 if (! TARGET_ARCH64 && current_function_returns_struct)
9434 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9435 /* If operands are global or in registers, can use return */
9436 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9437 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9438 else
9439 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9440 }"
9441 [(set_attr "type" "multi")])
9442
9443 (define_insn "*return_di"
9444 [(set (match_operand:DI 0 "restore_operand" "")
9445 (match_operand:DI 1 "arith_double_operand" "rHI"))
9446 (return)]
9447 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9448 "ret\;restore %%g0, %1, %Y0"
9449 [(set_attr "type" "multi")])
9450
9451 (define_insn "*return_adddi"
9452 [(set (match_operand:DI 0 "restore_operand" "")
9453 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9454 (match_operand:DI 2 "arith_double_operand" "rHI")))
9455 (return)]
9456 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9457 "ret\;restore %r1, %2, %Y0"
9458 [(set_attr "type" "multi")])
9459
9460 (define_insn "*return_losum_di"
9461 [(set (match_operand:DI 0 "restore_operand" "")
9462 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9463 (match_operand:DI 2 "immediate_operand" "in")))
9464 (return)]
9465 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9466 "ret\;restore %r1, %%lo(%a2), %Y0"
9467 [(set_attr "type" "multi")])
9468
9469 ;; The following pattern is only generated by delayed-branch scheduling,
9470 ;; when the insn winds up in the epilogue.
9471 (define_insn "*return_sf"
9472 [(set (reg:SF 32)
9473 (match_operand:SF 0 "register_operand" "f"))
9474 (return)]
9475 "! TARGET_EPILOGUE"
9476 "ret\;fmovs\\t%0, %%f0"
9477 [(set_attr "type" "multi")])
9478
9479 ;; Now peepholes to do a call followed by a jump.
9480
9481 (define_peephole
9482 [(parallel [(set (match_operand 0 "" "")
9483 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9484 (match_operand 2 "" "")))
9485 (clobber (reg:SI 15))])
9486 (set (pc) (label_ref (match_operand 3 "" "")))]
9487 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9488 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9489 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9490
9491 (define_peephole
9492 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9493 (match_operand 1 "" ""))
9494 (clobber (reg:SI 15))])
9495 (set (pc) (label_ref (match_operand 2 "" "")))]
9496 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9497 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9498 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9499
9500 (define_peephole
9501 [(parallel [(set (match_operand 0 "" "")
9502 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9503 (match_operand 2 "" "")))
9504 (clobber (reg:DI 15))])
9505 (set (pc) (label_ref (match_operand 3 "" "")))]
9506 "TARGET_ARCH64
9507 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9508 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9509 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9510
9511 (define_peephole
9512 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9513 (match_operand 1 "" ""))
9514 (clobber (reg:DI 15))])
9515 (set (pc) (label_ref (match_operand 2 "" "")))]
9516 "TARGET_ARCH64
9517 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9518 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9519 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9520 \f
9521 (define_expand "prologue"
9522 [(const_int 1)]
9523 "flag_pic && current_function_uses_pic_offset_table"
9524 "
9525 {
9526 load_pic_register ();
9527 DONE;
9528 }")
9529
9530 ;; We need to reload %l7 for -mflat -fpic,
9531 ;; otherwise %l7 should be preserved simply
9532 ;; by loading the function's register window
9533 (define_expand "exception_receiver"
9534 [(const_int 0)]
9535 "TARGET_FLAT && flag_pic"
9536 "
9537 {
9538 load_pic_register ();
9539 DONE;
9540 }")
9541
9542 ;; Likewise
9543 (define_expand "builtin_setjmp_receiver"
9544 [(label_ref (match_operand 0 "" ""))]
9545 "TARGET_FLAT && flag_pic"
9546 "
9547 {
9548 load_pic_register ();
9549 DONE;
9550 }")
9551 \f
9552 (define_insn "trap"
9553 [(trap_if (const_int 1) (const_int 5))]
9554 ""
9555 "ta\\t5"
9556 [(set_attr "type" "misc")
9557 (set_attr "length" "1")])
9558
9559 (define_expand "conditional_trap"
9560 [(trap_if (match_operator 0 "noov_compare_op"
9561 [(match_dup 2) (match_dup 3)])
9562 (match_operand:SI 1 "arith_operand" ""))]
9563 ""
9564 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9565 sparc_compare_op0, sparc_compare_op1);
9566 operands[3] = const0_rtx;")
9567
9568 (define_insn ""
9569 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9570 (match_operand:SI 1 "arith_operand" "rM"))]
9571 ""
9572 "t%C0\\t%1"
9573 [(set_attr "type" "misc")
9574 (set_attr "length" "1")])
9575
9576 (define_insn ""
9577 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9578 (match_operand:SI 1 "arith_operand" "rM"))]
9579 "TARGET_V9"
9580 "t%C0\\t%%xcc, %1"
9581 [(set_attr "type" "misc")
9582 (set_attr "length" "1")])