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