sparc.h (LEGITIMATE_CONSTANT_P): Consider TFmode 0.0L as legitimate constant if ...
[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 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2449 "sethi\\t%%hi(%a1), %0"
2450 [(set_attr "type" "move")
2451 (set_attr "length" "1")])
2452
2453 (define_insn "*sethi_di_medlow"
2454 [(set (match_operand:DI 0 "register_operand" "=r")
2455 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2456 "TARGET_CM_MEDLOW && check_pic (1)"
2457 "sethi\\t%%hi(%a1), %0"
2458 [(set_attr "type" "move")
2459 (set_attr "length" "1")])
2460
2461 (define_insn "*losum_di_medlow"
2462 [(set (match_operand:DI 0 "register_operand" "=r")
2463 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2464 (match_operand:DI 2 "symbolic_operand" "")))]
2465 "TARGET_CM_MEDLOW"
2466 "or\\t%1, %%lo(%a2), %0"
2467 [(set_attr "type" "ialu")
2468 (set_attr "length" "1")])
2469
2470 (define_insn "seth44"
2471 [(set (match_operand:DI 0 "register_operand" "=r")
2472 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2473 "TARGET_CM_MEDMID"
2474 "sethi\\t%%h44(%a1), %0"
2475 [(set_attr "type" "move")
2476 (set_attr "length" "1")])
2477
2478 (define_insn "setm44"
2479 [(set (match_operand:DI 0 "register_operand" "=r")
2480 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2481 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2482 "TARGET_CM_MEDMID"
2483 "or\\t%1, %%m44(%a2), %0"
2484 [(set_attr "type" "move")
2485 (set_attr "length" "1")])
2486
2487 (define_insn "setl44"
2488 [(set (match_operand:DI 0 "register_operand" "=r")
2489 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2490 (match_operand:DI 2 "symbolic_operand" "")))]
2491 "TARGET_CM_MEDMID"
2492 "or\\t%1, %%l44(%a2), %0"
2493 [(set_attr "type" "ialu")
2494 (set_attr "length" "1")])
2495
2496 (define_insn "sethh"
2497 [(set (match_operand:DI 0 "register_operand" "=r")
2498 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2499 "TARGET_CM_MEDANY"
2500 "sethi\\t%%hh(%a1), %0"
2501 [(set_attr "type" "move")
2502 (set_attr "length" "1")])
2503
2504 (define_insn "setlm"
2505 [(set (match_operand:DI 0 "register_operand" "=r")
2506 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2507 "TARGET_CM_MEDANY"
2508 "sethi\\t%%lm(%a1), %0"
2509 [(set_attr "type" "move")
2510 (set_attr "length" "1")])
2511
2512 (define_insn "sethm"
2513 [(set (match_operand:DI 0 "register_operand" "=r")
2514 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2515 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2516 "TARGET_CM_MEDANY"
2517 "or\\t%1, %%hm(%a2), %0"
2518 [(set_attr "type" "ialu")
2519 (set_attr "length" "1")])
2520
2521 (define_insn "setlo"
2522 [(set (match_operand:DI 0 "register_operand" "=r")
2523 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2524 (match_operand:DI 2 "symbolic_operand" "")))]
2525 "TARGET_CM_MEDANY"
2526 "or\\t%1, %%lo(%a2), %0"
2527 [(set_attr "type" "ialu")
2528 (set_attr "length" "1")])
2529
2530 (define_insn "embmedany_sethi"
2531 [(set (match_operand:DI 0 "register_operand" "=r")
2532 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2533 "TARGET_CM_EMBMEDANY && check_pic (1)"
2534 "sethi\\t%%hi(%a1), %0"
2535 [(set_attr "type" "move")
2536 (set_attr "length" "1")])
2537
2538 (define_insn "embmedany_losum"
2539 [(set (match_operand:DI 0 "register_operand" "=r")
2540 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2541 (match_operand:DI 2 "data_segment_operand" "")))]
2542 "TARGET_CM_EMBMEDANY"
2543 "add\\t%1, %%lo(%a2), %0"
2544 [(set_attr "type" "ialu")
2545 (set_attr "length" "1")])
2546
2547 (define_insn "embmedany_brsum"
2548 [(set (match_operand:DI 0 "register_operand" "=r")
2549 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2550 "TARGET_CM_EMBMEDANY"
2551 "add\\t%1, %_, %0"
2552 [(set_attr "length" "1")])
2553
2554 (define_insn "embmedany_textuhi"
2555 [(set (match_operand:DI 0 "register_operand" "=r")
2556 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2557 "TARGET_CM_EMBMEDANY && check_pic (1)"
2558 "sethi\\t%%uhi(%a1), %0"
2559 [(set_attr "type" "move")
2560 (set_attr "length" "1")])
2561
2562 (define_insn "embmedany_texthi"
2563 [(set (match_operand:DI 0 "register_operand" "=r")
2564 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2565 "TARGET_CM_EMBMEDANY && check_pic (1)"
2566 "sethi\\t%%hi(%a1), %0"
2567 [(set_attr "type" "move")
2568 (set_attr "length" "1")])
2569
2570 (define_insn "embmedany_textulo"
2571 [(set (match_operand:DI 0 "register_operand" "=r")
2572 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2573 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2574 "TARGET_CM_EMBMEDANY"
2575 "or\\t%1, %%ulo(%a2), %0"
2576 [(set_attr "type" "ialu")
2577 (set_attr "length" "1")])
2578
2579 (define_insn "embmedany_textlo"
2580 [(set (match_operand:DI 0 "register_operand" "=r")
2581 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2582 (match_operand:DI 2 "text_segment_operand" "")))]
2583 "TARGET_CM_EMBMEDANY"
2584 "or\\t%1, %%lo(%a2), %0"
2585 [(set_attr "type" "ialu")
2586 (set_attr "length" "1")])
2587
2588 ;; Now some patterns to help reload out a bit.
2589 (define_expand "reload_indi"
2590 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2591 (match_operand:DI 1 "immediate_operand" "")
2592 (match_operand:TI 2 "register_operand" "=&r")])]
2593 "(TARGET_CM_MEDANY
2594 || TARGET_CM_EMBMEDANY)
2595 && ! flag_pic"
2596 "
2597 {
2598 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2599 gen_rtx_REG (DImode, REGNO (operands[2])));
2600 DONE;
2601 }")
2602
2603 (define_expand "reload_outdi"
2604 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2605 (match_operand:DI 1 "immediate_operand" "")
2606 (match_operand:TI 2 "register_operand" "=&r")])]
2607 "(TARGET_CM_MEDANY
2608 || TARGET_CM_EMBMEDANY)
2609 && ! flag_pic"
2610 "
2611 {
2612 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2613 gen_rtx_REG (DImode, REGNO (operands[2])));
2614 DONE;
2615 }")
2616
2617 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2618 (define_split
2619 [(set (match_operand:DI 0 "register_operand" "")
2620 (match_operand:DI 1 "const_int_operand" ""))]
2621 "! TARGET_ARCH64 && reload_completed"
2622 [(clobber (const_int 0))]
2623 "
2624 {
2625 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2626 (INTVAL (operands[1]) < 0) ?
2627 constm1_rtx :
2628 const0_rtx));
2629 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2630 operands[1]));
2631 DONE;
2632 }")
2633
2634 (define_split
2635 [(set (match_operand:DI 0 "register_operand" "")
2636 (match_operand:DI 1 "const_double_operand" ""))]
2637 "! TARGET_ARCH64 && reload_completed"
2638 [(clobber (const_int 0))]
2639 "
2640 {
2641 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2642 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2643
2644 /* Slick... but this trick loses if this subreg constant part
2645 can be done in one insn. */
2646 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2647 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2648 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2649 {
2650 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2651 gen_highpart (SImode, operands[0])));
2652 }
2653 else
2654 {
2655 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2656 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2657 }
2658 DONE;
2659 }")
2660
2661 (define_split
2662 [(set (match_operand:DI 0 "register_operand" "")
2663 (match_operand:DI 1 "register_operand" ""))]
2664 "! TARGET_ARCH64 && reload_completed"
2665 [(clobber (const_int 0))]
2666 "
2667 {
2668 rtx set_dest = operands[0];
2669 rtx set_src = operands[1];
2670 rtx dest1, dest2;
2671 rtx src1, src2;
2672
2673 if (GET_CODE (set_dest) == SUBREG)
2674 set_dest = alter_subreg (set_dest);
2675 if (GET_CODE (set_src) == SUBREG)
2676 set_src = alter_subreg (set_src);
2677
2678 dest1 = gen_highpart (SImode, set_dest);
2679 dest2 = gen_lowpart (SImode, set_dest);
2680 src1 = gen_highpart (SImode, set_src);
2681 src2 = gen_lowpart (SImode, set_src);
2682
2683 /* Now emit using the real source and destination we found, swapping
2684 the order if we detect overlap. */
2685 if (reg_overlap_mentioned_p (dest1, src2))
2686 {
2687 emit_insn (gen_movsi (dest2, src2));
2688 emit_insn (gen_movsi (dest1, src1));
2689 }
2690 else
2691 {
2692 emit_insn (gen_movsi (dest1, src1));
2693 emit_insn (gen_movsi (dest2, src2));
2694 }
2695 DONE;
2696 }")
2697
2698 ;; Now handle the cases of memory moves from/to non-even
2699 ;; DI mode register pairs.
2700 (define_split
2701 [(set (match_operand:DI 0 "register_operand" "")
2702 (match_operand:DI 1 "memory_operand" ""))]
2703 "(! TARGET_ARCH64
2704 && reload_completed
2705 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2706 [(clobber (const_int 0))]
2707 "
2708 {
2709 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2710 rtx word1 = change_address (operands[1], SImode,
2711 plus_constant_for_output (XEXP (word0, 0), 4));
2712 rtx high_part = gen_highpart (SImode, operands[0]);
2713 rtx low_part = gen_lowpart (SImode, operands[0]);
2714
2715 if (reg_overlap_mentioned_p (high_part, word1))
2716 {
2717 emit_insn (gen_movsi (low_part, word1));
2718 emit_insn (gen_movsi (high_part, word0));
2719 }
2720 else
2721 {
2722 emit_insn (gen_movsi (high_part, word0));
2723 emit_insn (gen_movsi (low_part, word1));
2724 }
2725 DONE;
2726 }")
2727
2728 (define_split
2729 [(set (match_operand:DI 0 "memory_operand" "")
2730 (match_operand:DI 1 "register_operand" ""))]
2731 "(! TARGET_ARCH64
2732 && reload_completed
2733 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2734 [(clobber (const_int 0))]
2735 "
2736 {
2737 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2738 rtx word1 = change_address (operands[0], SImode,
2739 plus_constant_for_output (XEXP (word0, 0), 4));
2740 rtx high_part = gen_highpart (SImode, operands[1]);
2741 rtx low_part = gen_lowpart (SImode, operands[1]);
2742
2743 emit_insn (gen_movsi (word0, high_part));
2744 emit_insn (gen_movsi (word1, low_part));
2745 DONE;
2746 }")
2747
2748 \f
2749 ;; Floating point move insns
2750
2751 (define_insn "*clear_sf"
2752 [(set (match_operand:SF 0 "register_operand" "=f")
2753 (match_operand:SF 1 "const_double_operand" ""))]
2754 "TARGET_VIS
2755 && fp_zero_operand (operands[1])"
2756 "fzeros\\t%0"
2757 [(set_attr "type" "fpmove")
2758 (set_attr "length" "1")])
2759
2760 (define_insn "*clear_sfp"
2761 [(set (match_operand:SF 0 "memory_operand" "=m")
2762 (match_operand:SF 1 "const_double_operand" ""))]
2763 "! TARGET_LIVE_G0
2764 && fp_zero_operand (operands[1])"
2765 "st\\t%%g0, %0"
2766 [(set_attr "type" "store")
2767 (set_attr "length" "1")])
2768
2769 (define_insn "*movsf_const_intreg"
2770 [(set (match_operand:SF 0 "register_operand" "=f,r")
2771 (match_operand:SF 1 "const_double_operand" "m#F,F"))]
2772 "TARGET_FPU"
2773 "*
2774 {
2775 REAL_VALUE_TYPE r;
2776 long i;
2777
2778 if (which_alternative == 0)
2779 return \"ld\\t%1, %0\";
2780
2781 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2782 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2783 if (SPARC_SIMM13_P (i) || SPARC_SETHI_P (i))
2784 {
2785 operands[1] = GEN_INT (i);
2786 if (SPARC_SIMM13_P (INTVAL (operands[1])))
2787 return \"mov\\t%1, %0\";
2788 else if (SPARC_SETHI_P (INTVAL (operands[1])))
2789 return \"sethi\\t%%hi(%a1), %0\";
2790 else
2791 abort ();
2792 }
2793 else
2794 return \"#\";
2795 }"
2796 [(set_attr "type" "move")
2797 (set_attr "length" "1,2")])
2798
2799 ;; There isn't much I can do about this, if I change the
2800 ;; mode then flow info gets really confused because the
2801 ;; destination no longer looks the same. Ho hum...
2802 (define_insn "*movsf_const_high"
2803 [(set (match_operand:SF 0 "register_operand" "=r")
2804 (unspec:SF [(match_operand 1 "const_int_operand" "")] 12))]
2805 ""
2806 "sethi\\t%%hi(%a1), %0"
2807 [(set_attr "type" "move")
2808 (set_attr "length" "1")])
2809
2810 (define_insn "*movsf_const_lo"
2811 [(set (match_operand:SF 0 "register_operand" "=r")
2812 (unspec:SF [(match_operand:SF 1 "register_operand" "r")
2813 (match_operand 2 "const_int_operand" "")] 17))]
2814 ""
2815 "or\\t%1, %%lo(%a2), %0"
2816 [(set_attr "type" "move")
2817 (set_attr "length" "1")])
2818
2819 (define_split
2820 [(set (match_operand:SF 0 "register_operand" "")
2821 (match_operand:SF 1 "const_double_operand" ""))]
2822 "TARGET_FPU
2823 && (GET_CODE (operands[0]) == REG
2824 && REGNO (operands[0]) < 32)"
2825 [(set (match_dup 0) (unspec:SF [(match_dup 1)] 12))
2826 (set (match_dup 0) (unspec:SF [(match_dup 0) (match_dup 1)] 17))]
2827 "
2828 {
2829 REAL_VALUE_TYPE r;
2830 long i;
2831
2832 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2833 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2834 operands[1] = GEN_INT (i);
2835 }")
2836
2837 (define_expand "movsf"
2838 [(set (match_operand:SF 0 "general_operand" "")
2839 (match_operand:SF 1 "general_operand" ""))]
2840 ""
2841 "
2842 {
2843 /* Force SFmode constants into memory. */
2844 if (GET_CODE (operands[0]) == REG
2845 && CONSTANT_P (operands[1]))
2846 {
2847 if (TARGET_VIS
2848 && GET_CODE (operands[1]) == CONST_DOUBLE
2849 && fp_zero_operand (operands[1]))
2850 goto movsf_is_ok;
2851
2852 /* emit_group_store will send such bogosity to us when it is
2853 not storing directly into memory. So fix this up to avoid
2854 crashes in output_constant_pool. */
2855 if (operands [1] == const0_rtx)
2856 operands[1] = CONST0_RTX (SFmode);
2857 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2858 operands[1]));
2859 }
2860
2861 /* Handle sets of MEM first. */
2862 if (GET_CODE (operands[0]) == MEM)
2863 {
2864 if (register_operand (operands[1], SFmode))
2865 goto movsf_is_ok;
2866
2867 if (! reload_in_progress)
2868 {
2869 operands[0] = validize_mem (operands[0]);
2870 operands[1] = force_reg (SFmode, operands[1]);
2871 }
2872 }
2873
2874 /* Fixup PIC cases. */
2875 if (flag_pic)
2876 {
2877 if (CONSTANT_P (operands[1])
2878 && pic_address_needs_scratch (operands[1]))
2879 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2880
2881 if (symbolic_operand (operands[1], SFmode))
2882 {
2883 operands[1] = legitimize_pic_address (operands[1],
2884 SFmode,
2885 (reload_in_progress ?
2886 operands[0] :
2887 NULL_RTX));
2888 }
2889 }
2890
2891 movsf_is_ok:
2892 ;
2893 }")
2894
2895 (define_insn "*movsf_insn"
2896 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,r,r,m")
2897 (match_operand:SF 1 "input_operand" "f,m,f,r,m,r"))]
2898 "TARGET_FPU
2899 && (register_operand (operands[0], SFmode)
2900 || register_operand (operands[1], SFmode))"
2901 "@
2902 fmovs\\t%1, %0
2903 ld\\t%1, %0
2904 st\\t%1, %0
2905 mov\\t%1, %0
2906 ld\\t%1, %0
2907 st\\t%1, %0"
2908 [(set_attr "type" "fpmove,fpload,fpstore,move,load,store")
2909 (set_attr "length" "1")])
2910
2911 ;; Exactly the same as above, except that all `f' cases are deleted.
2912 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2913 ;; when -mno-fpu.
2914
2915 (define_insn "*movsf_no_f_insn"
2916 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
2917 (match_operand:SF 1 "input_operand" "r,m,r"))]
2918 "! TARGET_FPU
2919 && (register_operand (operands[0], SFmode)
2920 || register_operand (operands[1], SFmode))"
2921 "@
2922 mov\\t%1, %0
2923 ld\\t%1, %0
2924 st\\t%1, %0"
2925 [(set_attr "type" "move,load,store")
2926 (set_attr "length" "1")])
2927
2928 (define_insn "*clear_df"
2929 [(set (match_operand:DF 0 "register_operand" "=e")
2930 (match_operand:DF 1 "const_double_operand" ""))]
2931 "TARGET_VIS
2932 && fp_zero_operand (operands[1])"
2933 "fzero\\t%0"
2934 [(set_attr "type" "fpmove")
2935 (set_attr "length" "1")])
2936
2937 (define_insn "*clear_dfp"
2938 [(set (match_operand:DF 0 "memory_operand" "=m")
2939 (match_operand:DF 1 "const_double_operand" ""))]
2940 "! TARGET_LIVE_G0
2941 && TARGET_V9
2942 && fp_zero_operand (operands[1])"
2943 "stx\\t%%g0, %0"
2944 [(set_attr "type" "store")
2945 (set_attr "length" "1")])
2946
2947 (define_insn "*movdf_const_intreg_sp32"
2948 [(set (match_operand:DF 0 "register_operand" "=e,e,?r")
2949 (match_operand:DF 1 "const_double_operand" "T#F,o#F,F"))]
2950 "TARGET_FPU && ! TARGET_ARCH64"
2951 "@
2952 ldd\\t%1, %0
2953 #
2954 #"
2955 [(set_attr "type" "move")
2956 (set_attr "length" "1,2,2")])
2957
2958 ;; Now that we redo life analysis with a clean slate after
2959 ;; instruction splitting for sched2 this can work.
2960 (define_insn "*movdf_const_intreg_sp64"
2961 [(set (match_operand:DF 0 "register_operand" "=e,?r")
2962 (match_operand:DF 1 "const_double_operand" "m#F,F"))]
2963 "TARGET_FPU && TARGET_ARCH64"
2964 "@
2965 ldd\\t%1, %0
2966 #"
2967 [(set_attr "type" "move")
2968 (set_attr "length" "1,2")])
2969
2970 (define_split
2971 [(set (match_operand:DF 0 "register_operand" "")
2972 (match_operand:DF 1 "const_double_operand" ""))]
2973 "TARGET_FPU
2974 && (GET_CODE (operands[0]) == REG
2975 && REGNO (operands[0]) < 32)
2976 && reload_completed"
2977 [(clobber (const_int 0))]
2978 "
2979 {
2980 REAL_VALUE_TYPE r;
2981 long l[2];
2982
2983 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2984 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2985 if (GET_CODE (operands[0]) == SUBREG)
2986 operands[0] = alter_subreg (operands[0]);
2987 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2988
2989 if (TARGET_ARCH64)
2990 {
2991 #if HOST_BITS_PER_WIDE_INT == 64
2992 HOST_WIDE_INT val;
2993
2994 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2995 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2996 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
2997 #else
2998 emit_insn (gen_movdi (operands[0],
2999 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3000 l[1], l[0])));
3001 #endif
3002 }
3003 else
3004 {
3005 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3006 GEN_INT (l[0])));
3007
3008 /* Slick... but this trick loses if this subreg constant part
3009 can be done in one insn. */
3010 if (l[1] == l[0]
3011 && !(SPARC_SETHI_P (l[0])
3012 || SPARC_SIMM13_P (l[0])))
3013 {
3014 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3015 gen_highpart (SImode, operands[0])));
3016 }
3017 else
3018 {
3019 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3020 GEN_INT (l[1])));
3021 }
3022 }
3023 DONE;
3024 }")
3025
3026 (define_expand "movdf"
3027 [(set (match_operand:DF 0 "general_operand" "")
3028 (match_operand:DF 1 "general_operand" ""))]
3029 ""
3030 "
3031 {
3032 /* Force DFmode constants into memory. */
3033 if (GET_CODE (operands[0]) == REG
3034 && CONSTANT_P (operands[1]))
3035 {
3036 if (TARGET_VIS
3037 && GET_CODE (operands[1]) == CONST_DOUBLE
3038 && fp_zero_operand (operands[1]))
3039 goto movdf_is_ok;
3040
3041 /* emit_group_store will send such bogosity to us when it is
3042 not storing directly into memory. So fix this up to avoid
3043 crashes in output_constant_pool. */
3044 if (operands [1] == const0_rtx)
3045 operands[1] = CONST0_RTX (DFmode);
3046 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3047 operands[1]));
3048 }
3049
3050 /* Handle MEM cases first. */
3051 if (GET_CODE (operands[0]) == MEM)
3052 {
3053 if (register_operand (operands[1], DFmode))
3054 goto movdf_is_ok;
3055
3056 if (! reload_in_progress)
3057 {
3058 operands[0] = validize_mem (operands[0]);
3059 operands[1] = force_reg (DFmode, operands[1]);
3060 }
3061 }
3062
3063 /* Fixup PIC cases. */
3064 if (flag_pic)
3065 {
3066 if (CONSTANT_P (operands[1])
3067 && pic_address_needs_scratch (operands[1]))
3068 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3069
3070 if (symbolic_operand (operands[1], DFmode))
3071 {
3072 operands[1] = legitimize_pic_address (operands[1],
3073 DFmode,
3074 (reload_in_progress ?
3075 operands[0] :
3076 NULL_RTX));
3077 }
3078 }
3079
3080 movdf_is_ok:
3081 ;
3082 }")
3083
3084 ;; Be careful, fmovd does not exist when !v9.
3085 (define_insn "*movdf_insn_sp32"
3086 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,e,r,r,o,e,o")
3087 (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))]
3088 "TARGET_FPU
3089 && ! TARGET_V9
3090 && (register_operand (operands[0], DFmode)
3091 || register_operand (operands[1], DFmode))"
3092 "@
3093 ldd\\t%1, %0
3094 std\\t%1, %0
3095 ldd\\t%1, %0
3096 std\\t%1, %0
3097 #
3098 #
3099 #
3100 #
3101 #
3102 #"
3103 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3104 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3105
3106 (define_insn "*movdf_no_e_insn_sp32"
3107 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,r,r,o")
3108 (match_operand:DF 1 "input_operand" "T,U,r,o,r"))]
3109 "! TARGET_FPU
3110 && ! TARGET_ARCH64
3111 && (register_operand (operands[0], DFmode)
3112 || register_operand (operands[1], DFmode))"
3113 "@
3114 ldd\\t%1, %0
3115 std\\t%1, %0
3116 #
3117 #
3118 #"
3119 [(set_attr "type" "load,store,*,*,*")
3120 (set_attr "length" "1,1,2,2,2")])
3121
3122 ;; We have available v9 double floats but not 64-bit
3123 ;; integer registers.
3124 (define_insn "*movdf_insn_v9only"
3125 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,U,T,r,r,o")
3126 (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))]
3127 "TARGET_FPU
3128 && TARGET_V9
3129 && ! TARGET_ARCH64
3130 && (register_operand (operands[0], DFmode)
3131 || register_operand (operands[1], DFmode))"
3132 "@
3133 fmovd\\t%1, %0
3134 ldd\\t%1, %0
3135 std\\t%1, %0
3136 ldd\\t%1, %0
3137 std\\t%1, %0
3138 #
3139 #
3140 #"
3141 [(set_attr "type" "fpmove,load,store,load,store,*,*,*")
3142 (set_attr "length" "1,1,1,1,1,2,2,2")])
3143
3144 ;; We have available both v9 double floats and 64-bit
3145 ;; integer registers.
3146 (define_insn "*movdf_insn_sp64"
3147 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,r,r,m")
3148 (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))]
3149 "TARGET_FPU
3150 && TARGET_V9
3151 && TARGET_ARCH64
3152 && (register_operand (operands[0], DFmode)
3153 || register_operand (operands[1], DFmode))"
3154 "@
3155 fmovd\\t%1, %0
3156 ldd\\t%1, %0
3157 std\\t%1, %0
3158 mov\\t%1, %0
3159 ldx\\t%1, %0
3160 stx\\t%1, %0"
3161 [(set_attr "type" "fpmove,load,store,move,load,store")
3162 (set_attr "length" "1")])
3163
3164 (define_insn "*movdf_no_e_insn_sp64"
3165 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3166 (match_operand:DF 1 "input_operand" "r,m,r"))]
3167 "! TARGET_FPU
3168 && TARGET_ARCH64
3169 && (register_operand (operands[0], DFmode)
3170 || register_operand (operands[1], DFmode))"
3171 "@
3172 mov\\t%1, %0
3173 ldx\\t%1, %0
3174 stx\\t%1, %0"
3175 [(set_attr "type" "move,load,store")
3176 (set_attr "length" "1")])
3177
3178 ;; Ok, now the splits to handle all the multi insn and
3179 ;; mis-aligned memory address cases.
3180 ;; In these splits please take note that we must be
3181 ;; careful when V9 but not ARCH64 because the integer
3182 ;; register DFmode cases must be handled.
3183 (define_split
3184 [(set (match_operand:DF 0 "register_operand" "")
3185 (match_operand:DF 1 "register_operand" ""))]
3186 "(! TARGET_V9
3187 || (! TARGET_ARCH64
3188 && ((GET_CODE (operands[0]) == REG
3189 && REGNO (operands[0]) < 32)
3190 || (GET_CODE (operands[0]) == SUBREG
3191 && GET_CODE (SUBREG_REG (operands[0])) == REG
3192 && REGNO (SUBREG_REG (operands[0])) < 32))))
3193 && reload_completed"
3194 [(clobber (const_int 0))]
3195 "
3196 {
3197 rtx set_dest = operands[0];
3198 rtx set_src = operands[1];
3199 rtx dest1, dest2;
3200 rtx src1, src2;
3201
3202 if (GET_CODE (set_dest) == SUBREG)
3203 set_dest = alter_subreg (set_dest);
3204 if (GET_CODE (set_src) == SUBREG)
3205 set_src = alter_subreg (set_src);
3206
3207 dest1 = gen_highpart (SFmode, set_dest);
3208 dest2 = gen_lowpart (SFmode, set_dest);
3209 src1 = gen_highpart (SFmode, set_src);
3210 src2 = gen_lowpart (SFmode, set_src);
3211
3212 /* Now emit using the real source and destination we found, swapping
3213 the order if we detect overlap. */
3214 if (reg_overlap_mentioned_p (dest1, src2))
3215 {
3216 emit_insn (gen_movsf (dest2, src2));
3217 emit_insn (gen_movsf (dest1, src1));
3218 }
3219 else
3220 {
3221 emit_insn (gen_movsf (dest1, src1));
3222 emit_insn (gen_movsf (dest2, src2));
3223 }
3224 DONE;
3225 }")
3226
3227 (define_split
3228 [(set (match_operand:DF 0 "register_operand" "")
3229 (match_operand:DF 1 "memory_operand" ""))]
3230 "((! TARGET_V9
3231 || (! TARGET_ARCH64
3232 && ((GET_CODE (operands[0]) == REG
3233 && REGNO (operands[0]) < 32)
3234 || (GET_CODE (operands[0]) == SUBREG
3235 && GET_CODE (SUBREG_REG (operands[0])) == REG
3236 && REGNO (SUBREG_REG (operands[0])) < 32))))
3237 && (reload_completed
3238 && (((REGNO (operands[0])) % 2) != 0
3239 || ! mem_min_alignment (operands[1], 8))
3240 && offsettable_memref_p (operands[1])))"
3241 [(clobber (const_int 0))]
3242 "
3243 {
3244 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3245 rtx word1 = change_address (operands[1], SFmode,
3246 plus_constant_for_output (XEXP (word0, 0), 4));
3247
3248 if (GET_CODE (operands[0]) == SUBREG)
3249 operands[0] = alter_subreg (operands[0]);
3250
3251 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3252 {
3253 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3254 word1));
3255 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3256 word0));
3257 }
3258 else
3259 {
3260 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3261 word0));
3262 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3263 word1));
3264 }
3265 DONE;
3266 }")
3267
3268 (define_split
3269 [(set (match_operand:DF 0 "memory_operand" "")
3270 (match_operand:DF 1 "register_operand" ""))]
3271 "((! TARGET_V9
3272 || (! TARGET_ARCH64
3273 && ((GET_CODE (operands[1]) == REG
3274 && REGNO (operands[1]) < 32)
3275 || (GET_CODE (operands[1]) == SUBREG
3276 && GET_CODE (SUBREG_REG (operands[1])) == REG
3277 && REGNO (SUBREG_REG (operands[1])) < 32))))
3278 && (reload_completed
3279 && (((REGNO (operands[1])) % 2) != 0
3280 || ! mem_min_alignment (operands[0], 8))
3281 && offsettable_memref_p (operands[0])))"
3282 [(clobber (const_int 0))]
3283 "
3284 {
3285 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3286 rtx word1 = change_address (operands[0], SFmode,
3287 plus_constant_for_output (XEXP (word0, 0), 4));
3288
3289 if (GET_CODE (operands[1]) == SUBREG)
3290 operands[1] = alter_subreg (operands[1]);
3291 emit_insn (gen_movsf (word0,
3292 gen_highpart (SFmode, operands[1])));
3293 emit_insn (gen_movsf (word1,
3294 gen_lowpart (SFmode, operands[1])));
3295 DONE;
3296 }")
3297
3298 (define_insn "*clear_tf"
3299 [(set (match_operand:TF 0 "register_operand" "=e")
3300 (match_operand:TF 1 "const_double_operand" ""))]
3301 "TARGET_VIS
3302 && fp_zero_operand (operands[1])"
3303 "#"
3304 [(set_attr "type" "fpmove")
3305 (set_attr "length" "2")])
3306
3307 (define_split
3308 [(set (match_operand:TF 0 "register_operand" "")
3309 (match_operand:TF 1 "const_double_operand" ""))]
3310 "TARGET_VIS && reload_completed
3311 && fp_zero_operand (operands[1])"
3312 [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
3313 (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
3314 "
3315 {
3316 operands[1] = CONST0_RTX (DFmode);
3317 }
3318 ")
3319
3320 (define_insn "*clear_tfp"
3321 [(set (match_operand:TF 0 "memory_operand" "=m")
3322 (match_operand:TF 1 "const_double_operand" ""))]
3323 "! TARGET_LIVE_G0
3324 && TARGET_V9
3325 && fp_zero_operand (operands[1])"
3326 "#"
3327 [(set_attr "type" "fpmove")
3328 (set_attr "length" "2")])
3329
3330 (define_split
3331 [(set (match_operand:TF 0 "memory_operand" "=m")
3332 (match_operand:TF 1 "const_double_operand" ""))]
3333 "! TARGET_LIVE_G0
3334 && TARGET_V9 && reload_completed
3335 && fp_zero_operand (operands[1])"
3336 [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
3337 (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
3338 "
3339 {
3340 operands[1] = CONST0_RTX (DFmode);
3341 }
3342 ")
3343
3344 (define_expand "movtf"
3345 [(set (match_operand:TF 0 "general_operand" "")
3346 (match_operand:TF 1 "general_operand" ""))]
3347 ""
3348 "
3349 {
3350 /* Force TFmode constants into memory. */
3351 if (GET_CODE (operands[0]) == REG
3352 && CONSTANT_P (operands[1]))
3353 {
3354 if (TARGET_VIS
3355 && GET_CODE (operands[1]) == CONST_DOUBLE
3356 && fp_zero_operand (operands[1]))
3357 goto movtf_is_ok;
3358
3359 /* emit_group_store will send such bogosity to us when it is
3360 not storing directly into memory. So fix this up to avoid
3361 crashes in output_constant_pool. */
3362 if (operands [1] == const0_rtx)
3363 operands[1] = CONST0_RTX (TFmode);
3364 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3365 operands[1]));
3366 }
3367
3368 /* Handle MEM cases first, note that only v9 guarentees
3369 full 16-byte alignment for quads. */
3370 if (GET_CODE (operands[0]) == MEM)
3371 {
3372 if (register_operand (operands[1], TFmode))
3373 goto movtf_is_ok;
3374
3375 if (! reload_in_progress)
3376 {
3377 operands[0] = validize_mem (operands[0]);
3378 operands[1] = force_reg (TFmode, operands[1]);
3379 }
3380 }
3381
3382 /* Fixup PIC cases. */
3383 if (flag_pic)
3384 {
3385 if (CONSTANT_P (operands[1])
3386 && pic_address_needs_scratch (operands[1]))
3387 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3388
3389 if (symbolic_operand (operands[1], TFmode))
3390 {
3391 operands[1] = legitimize_pic_address (operands[1],
3392 TFmode,
3393 (reload_in_progress ?
3394 operands[0] :
3395 NULL_RTX));
3396 }
3397 }
3398
3399 movtf_is_ok:
3400 ;
3401 }")
3402
3403 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3404 ;; we must split them all. :-(
3405 (define_insn "*movtf_insn_sp32"
3406 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,e,r,r,o")
3407 (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))]
3408 "TARGET_FPU
3409 && ! TARGET_ARCH64
3410 && (register_operand (operands[0], TFmode)
3411 || register_operand (operands[1], TFmode))"
3412 "#"
3413 [(set_attr "length" "4")])
3414
3415 ;; Exactly the same as above, except that all `e' cases are deleted.
3416 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3417 ;; when -mno-fpu.
3418
3419 (define_insn "*movtf_no_e_insn_sp32"
3420 [(set (match_operand:TF 0 "nonimmediate_operand" "=U,o,r,r,o")
3421 (match_operand:TF 1 "input_operand" "o,U,r,o,r"))]
3422 "! TARGET_FPU
3423 && ! TARGET_ARCH64
3424 && (register_operand (operands[0], TFmode)
3425 || register_operand (operands[1], TFmode))"
3426 "#"
3427 [(set_attr "length" "4")])
3428
3429 ;; Now handle the float reg cases directly when arch64,
3430 ;; hard_quad, and proper reg number alignment are all true.
3431 (define_insn "*movtf_insn_hq_sp64"
3432 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,r,r,o")
3433 (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))]
3434 "TARGET_FPU
3435 && TARGET_ARCH64
3436 && TARGET_V9
3437 && TARGET_HARD_QUAD
3438 && (register_operand (operands[0], TFmode)
3439 || register_operand (operands[1], TFmode))"
3440 "@
3441 fmovq\\t%1, %0
3442 ldq\\t%1, %0
3443 stq\\t%1, %0
3444 #
3445 #
3446 #"
3447 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3448 (set_attr "length" "1,1,1,2,2,2")])
3449
3450 ;; Now we allow the integer register cases even when
3451 ;; only arch64 is true.
3452 (define_insn "*movtf_insn_sp64"
3453 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r,o,e,r")
3454 (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))]
3455 "TARGET_FPU
3456 && TARGET_ARCH64
3457 && ! TARGET_HARD_QUAD
3458 && (register_operand (operands[0], TFmode)
3459 || register_operand (operands[1], TFmode))"
3460 "#"
3461 [(set_attr "length" "2")])
3462
3463 (define_insn "*movtf_no_e_insn_sp64"
3464 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,r")
3465 (match_operand:TF 1 "input_operand" "o,r,r"))]
3466 "! TARGET_FPU
3467 && TARGET_ARCH64
3468 && (register_operand (operands[0], TFmode)
3469 || register_operand (operands[1], TFmode))"
3470 "#"
3471 [(set_attr "length" "2")])
3472
3473 ;; Now all the splits to handle multi-insn TF mode moves.
3474 (define_split
3475 [(set (match_operand:TF 0 "register_operand" "")
3476 (match_operand:TF 1 "register_operand" ""))]
3477 "reload_completed
3478 && (! TARGET_ARCH64
3479 || (TARGET_FPU
3480 && ! TARGET_HARD_QUAD))"
3481 [(clobber (const_int 0))]
3482 "
3483 {
3484 rtx set_dest = operands[0];
3485 rtx set_src = operands[1];
3486 rtx dest1, dest2;
3487 rtx src1, src2;
3488
3489 if (GET_CODE (set_dest) == SUBREG)
3490 set_dest = alter_subreg (set_dest);
3491 if (GET_CODE (set_src) == SUBREG)
3492 set_src = alter_subreg (set_src);
3493
3494 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3495 dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0);
3496 dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0);
3497 src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0);
3498 src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0);
3499
3500 /* Now emit using the real source and destination we found, swapping
3501 the order if we detect overlap. */
3502 if (reg_overlap_mentioned_p (dest1, src2))
3503 {
3504 emit_insn (gen_movdf (dest2, src2));
3505 emit_insn (gen_movdf (dest1, src1));
3506 }
3507 else
3508 {
3509 emit_insn (gen_movdf (dest1, src1));
3510 emit_insn (gen_movdf (dest2, src2));
3511 }
3512 DONE;
3513 }")
3514
3515 (define_split
3516 [(set (match_operand:TF 0 "register_operand" "")
3517 (match_operand:TF 1 "memory_operand" ""))]
3518 "(reload_completed
3519 && offsettable_memref_p (operands[1]))"
3520 [(clobber (const_int 0))]
3521 "
3522 {
3523 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3524 rtx word1 = change_address (operands[1], DFmode,
3525 plus_constant_for_output (XEXP (word0, 0), 8));
3526 rtx dest1, dest2;
3527
3528 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3529 dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0);
3530 dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0);
3531
3532 /* Now output, ordering such that we don't clobber any registers
3533 mentioned in the address. */
3534 if (reg_overlap_mentioned_p (dest1, word1))
3535
3536 {
3537 emit_insn (gen_movdf (dest2, word1));
3538 emit_insn (gen_movdf (dest1, word0));
3539 }
3540 else
3541 {
3542 emit_insn (gen_movdf (dest1, word0));
3543 emit_insn (gen_movdf (dest2, word1));
3544 }
3545 DONE;
3546 }")
3547
3548 (define_split
3549 [(set (match_operand:TF 0 "memory_operand" "")
3550 (match_operand:TF 1 "register_operand" ""))]
3551 "(reload_completed
3552 && offsettable_memref_p (operands[0]))"
3553 [(clobber (const_int 0))]
3554 "
3555 {
3556 rtx word0 = change_address (operands[0], DFmode, NULL_RTX);
3557 rtx word1 = change_address (operands[0], DFmode,
3558 plus_constant_for_output (XEXP (word0, 0), 8));
3559 rtx src1, src2;
3560
3561 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3562 src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0);
3563 src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0);
3564 emit_insn (gen_movdf (word0, src1));
3565 emit_insn (gen_movdf (word1, src2));
3566 DONE;
3567 }")
3568 \f
3569 ;; Sparc V9 conditional move instructions.
3570
3571 ;; We can handle larger constants here for some flavors, but for now we keep
3572 ;; it simple and only allow those constants supported by all flavours.
3573 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3574 ;; 3 contains the constant if one is present, but we handle either for
3575 ;; generality (sparc.c puts a constant in operand 2).
3576
3577 (define_expand "movqicc"
3578 [(set (match_operand:QI 0 "register_operand" "")
3579 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3580 (match_operand:QI 2 "arith10_operand" "")
3581 (match_operand:QI 3 "arith10_operand" "")))]
3582 "TARGET_V9"
3583 "
3584 {
3585 enum rtx_code code = GET_CODE (operands[1]);
3586
3587 if (GET_MODE (sparc_compare_op0) == DImode
3588 && ! TARGET_ARCH64)
3589 FAIL;
3590
3591 if (sparc_compare_op1 == const0_rtx
3592 && GET_CODE (sparc_compare_op0) == REG
3593 && GET_MODE (sparc_compare_op0) == DImode
3594 && v9_regcmp_p (code))
3595 {
3596 operands[1] = gen_rtx_fmt_ee (code, DImode,
3597 sparc_compare_op0, sparc_compare_op1);
3598 }
3599 else
3600 {
3601 rtx cc_reg = gen_compare_reg (code,
3602 sparc_compare_op0, sparc_compare_op1);
3603 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3604 }
3605 }")
3606
3607 (define_expand "movhicc"
3608 [(set (match_operand:HI 0 "register_operand" "")
3609 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3610 (match_operand:HI 2 "arith10_operand" "")
3611 (match_operand:HI 3 "arith10_operand" "")))]
3612 "TARGET_V9"
3613 "
3614 {
3615 enum rtx_code code = GET_CODE (operands[1]);
3616
3617 if (GET_MODE (sparc_compare_op0) == DImode
3618 && ! TARGET_ARCH64)
3619 FAIL;
3620
3621 if (sparc_compare_op1 == const0_rtx
3622 && GET_CODE (sparc_compare_op0) == REG
3623 && GET_MODE (sparc_compare_op0) == DImode
3624 && v9_regcmp_p (code))
3625 {
3626 operands[1] = gen_rtx_fmt_ee (code, DImode,
3627 sparc_compare_op0, sparc_compare_op1);
3628 }
3629 else
3630 {
3631 rtx cc_reg = gen_compare_reg (code,
3632 sparc_compare_op0, sparc_compare_op1);
3633 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3634 }
3635 }")
3636
3637 (define_expand "movsicc"
3638 [(set (match_operand:SI 0 "register_operand" "")
3639 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3640 (match_operand:SI 2 "arith10_operand" "")
3641 (match_operand:SI 3 "arith10_operand" "")))]
3642 "TARGET_V9"
3643 "
3644 {
3645 enum rtx_code code = GET_CODE (operands[1]);
3646 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3647
3648 if (sparc_compare_op1 == const0_rtx
3649 && GET_CODE (sparc_compare_op0) == REG
3650 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3651 {
3652 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3653 sparc_compare_op0, sparc_compare_op1);
3654 }
3655 else
3656 {
3657 rtx cc_reg = gen_compare_reg (code,
3658 sparc_compare_op0, sparc_compare_op1);
3659 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3660 cc_reg, const0_rtx);
3661 }
3662 }")
3663
3664 (define_expand "movdicc"
3665 [(set (match_operand:DI 0 "register_operand" "")
3666 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3667 (match_operand:DI 2 "arith10_double_operand" "")
3668 (match_operand:DI 3 "arith10_double_operand" "")))]
3669 "TARGET_ARCH64"
3670 "
3671 {
3672 enum rtx_code code = GET_CODE (operands[1]);
3673
3674 if (sparc_compare_op1 == const0_rtx
3675 && GET_CODE (sparc_compare_op0) == REG
3676 && GET_MODE (sparc_compare_op0) == DImode
3677 && v9_regcmp_p (code))
3678 {
3679 operands[1] = gen_rtx_fmt_ee (code, DImode,
3680 sparc_compare_op0, sparc_compare_op1);
3681 }
3682 else
3683 {
3684 rtx cc_reg = gen_compare_reg (code,
3685 sparc_compare_op0, sparc_compare_op1);
3686 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3687 cc_reg, const0_rtx);
3688 }
3689 }")
3690
3691 (define_expand "movsfcc"
3692 [(set (match_operand:SF 0 "register_operand" "")
3693 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3694 (match_operand:SF 2 "register_operand" "")
3695 (match_operand:SF 3 "register_operand" "")))]
3696 "TARGET_V9 && TARGET_FPU"
3697 "
3698 {
3699 enum rtx_code code = GET_CODE (operands[1]);
3700
3701 if (GET_MODE (sparc_compare_op0) == DImode
3702 && ! TARGET_ARCH64)
3703 FAIL;
3704
3705 if (sparc_compare_op1 == const0_rtx
3706 && GET_CODE (sparc_compare_op0) == REG
3707 && GET_MODE (sparc_compare_op0) == DImode
3708 && v9_regcmp_p (code))
3709 {
3710 operands[1] = gen_rtx_fmt_ee (code, DImode,
3711 sparc_compare_op0, sparc_compare_op1);
3712 }
3713 else
3714 {
3715 rtx cc_reg = gen_compare_reg (code,
3716 sparc_compare_op0, sparc_compare_op1);
3717 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3718 }
3719 }")
3720
3721 (define_expand "movdfcc"
3722 [(set (match_operand:DF 0 "register_operand" "")
3723 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3724 (match_operand:DF 2 "register_operand" "")
3725 (match_operand:DF 3 "register_operand" "")))]
3726 "TARGET_V9 && TARGET_FPU"
3727 "
3728 {
3729 enum rtx_code code = GET_CODE (operands[1]);
3730
3731 if (GET_MODE (sparc_compare_op0) == DImode
3732 && ! TARGET_ARCH64)
3733 FAIL;
3734
3735 if (sparc_compare_op1 == const0_rtx
3736 && GET_CODE (sparc_compare_op0) == REG
3737 && GET_MODE (sparc_compare_op0) == DImode
3738 && v9_regcmp_p (code))
3739 {
3740 operands[1] = gen_rtx_fmt_ee (code, DImode,
3741 sparc_compare_op0, sparc_compare_op1);
3742 }
3743 else
3744 {
3745 rtx cc_reg = gen_compare_reg (code,
3746 sparc_compare_op0, sparc_compare_op1);
3747 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3748 }
3749 }")
3750
3751 (define_expand "movtfcc"
3752 [(set (match_operand:TF 0 "register_operand" "")
3753 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3754 (match_operand:TF 2 "register_operand" "")
3755 (match_operand:TF 3 "register_operand" "")))]
3756 "TARGET_V9 && TARGET_FPU"
3757 "
3758 {
3759 enum rtx_code code = GET_CODE (operands[1]);
3760
3761 if (GET_MODE (sparc_compare_op0) == DImode
3762 && ! TARGET_ARCH64)
3763 FAIL;
3764
3765 if (sparc_compare_op1 == const0_rtx
3766 && GET_CODE (sparc_compare_op0) == REG
3767 && GET_MODE (sparc_compare_op0) == DImode
3768 && v9_regcmp_p (code))
3769 {
3770 operands[1] = gen_rtx_fmt_ee (code, DImode,
3771 sparc_compare_op0, sparc_compare_op1);
3772 }
3773 else
3774 {
3775 rtx cc_reg = gen_compare_reg (code,
3776 sparc_compare_op0, sparc_compare_op1);
3777 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3778 }
3779 }")
3780
3781 ;; Conditional move define_insns.
3782
3783 (define_insn "*movqi_cc_sp64"
3784 [(set (match_operand:QI 0 "register_operand" "=r,r")
3785 (if_then_else:QI (match_operator 1 "comparison_operator"
3786 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3787 (const_int 0)])
3788 (match_operand:QI 3 "arith11_operand" "rL,0")
3789 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3790 "TARGET_V9"
3791 "@
3792 mov%C1\\t%x2, %3, %0
3793 mov%c1\\t%x2, %4, %0"
3794 [(set_attr "type" "cmove")
3795 (set_attr "length" "1")])
3796
3797 (define_insn "*movhi_cc_sp64"
3798 [(set (match_operand:HI 0 "register_operand" "=r,r")
3799 (if_then_else:HI (match_operator 1 "comparison_operator"
3800 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3801 (const_int 0)])
3802 (match_operand:HI 3 "arith11_operand" "rL,0")
3803 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3804 "TARGET_V9"
3805 "@
3806 mov%C1\\t%x2, %3, %0
3807 mov%c1\\t%x2, %4, %0"
3808 [(set_attr "type" "cmove")
3809 (set_attr "length" "1")])
3810
3811 (define_insn "*movsi_cc_sp64"
3812 [(set (match_operand:SI 0 "register_operand" "=r,r")
3813 (if_then_else:SI (match_operator 1 "comparison_operator"
3814 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3815 (const_int 0)])
3816 (match_operand:SI 3 "arith11_operand" "rL,0")
3817 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3818 "TARGET_V9"
3819 "@
3820 mov%C1\\t%x2, %3, %0
3821 mov%c1\\t%x2, %4, %0"
3822 [(set_attr "type" "cmove")
3823 (set_attr "length" "1")])
3824
3825 ;; ??? The constraints of operands 3,4 need work.
3826 (define_insn "*movdi_cc_sp64"
3827 [(set (match_operand:DI 0 "register_operand" "=r,r")
3828 (if_then_else:DI (match_operator 1 "comparison_operator"
3829 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3830 (const_int 0)])
3831 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3832 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3833 "TARGET_ARCH64"
3834 "@
3835 mov%C1\\t%x2, %3, %0
3836 mov%c1\\t%x2, %4, %0"
3837 [(set_attr "type" "cmove")
3838 (set_attr "length" "1")])
3839
3840 (define_insn "*movdi_cc_sp64_trunc"
3841 [(set (match_operand:SI 0 "register_operand" "=r,r")
3842 (if_then_else:SI (match_operator 1 "comparison_operator"
3843 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3844 (const_int 0)])
3845 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3846 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3847 "TARGET_ARCH64"
3848 "@
3849 mov%C1\\t%x2, %3, %0
3850 mov%c1\\t%x2, %4, %0"
3851 [(set_attr "type" "cmove")
3852 (set_attr "length" "1")])
3853
3854 (define_insn "*movsf_cc_sp64"
3855 [(set (match_operand:SF 0 "register_operand" "=f,f")
3856 (if_then_else:SF (match_operator 1 "comparison_operator"
3857 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3858 (const_int 0)])
3859 (match_operand:SF 3 "register_operand" "f,0")
3860 (match_operand:SF 4 "register_operand" "0,f")))]
3861 "TARGET_V9 && TARGET_FPU"
3862 "@
3863 fmovs%C1\\t%x2, %3, %0
3864 fmovs%c1\\t%x2, %4, %0"
3865 [(set_attr "type" "fpcmove")
3866 (set_attr "length" "1")])
3867
3868 (define_insn "*movdf_cc_sp64"
3869 [(set (match_operand:DF 0 "register_operand" "=e,e")
3870 (if_then_else:DF (match_operator 1 "comparison_operator"
3871 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3872 (const_int 0)])
3873 (match_operand:DF 3 "register_operand" "e,0")
3874 (match_operand:DF 4 "register_operand" "0,e")))]
3875 "TARGET_V9 && TARGET_FPU"
3876 "@
3877 fmovd%C1\\t%x2, %3, %0
3878 fmovd%c1\\t%x2, %4, %0"
3879 [(set_attr "type" "fpcmove")
3880 (set_attr "length" "1")])
3881
3882 (define_insn "*movtf_cc_sp64"
3883 [(set (match_operand:TF 0 "register_operand" "=e,e")
3884 (if_then_else:TF (match_operator 1 "comparison_operator"
3885 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3886 (const_int 0)])
3887 (match_operand:TF 3 "register_operand" "e,0")
3888 (match_operand:TF 4 "register_operand" "0,e")))]
3889 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3890 "@
3891 fmovq%C1\\t%x2, %3, %0
3892 fmovq%c1\\t%x2, %4, %0"
3893 [(set_attr "type" "fpcmove")
3894 (set_attr "length" "1")])
3895
3896 (define_insn "*movqi_cc_reg_sp64"
3897 [(set (match_operand:QI 0 "register_operand" "=r,r")
3898 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3899 [(match_operand:DI 2 "register_operand" "r,r")
3900 (const_int 0)])
3901 (match_operand:QI 3 "arith10_operand" "rM,0")
3902 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3903 "TARGET_ARCH64"
3904 "@
3905 movr%D1\\t%2, %r3, %0
3906 movr%d1\\t%2, %r4, %0"
3907 [(set_attr "type" "cmove")
3908 (set_attr "length" "1")])
3909
3910 (define_insn "*movhi_cc_reg_sp64"
3911 [(set (match_operand:HI 0 "register_operand" "=r,r")
3912 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3913 [(match_operand:DI 2 "register_operand" "r,r")
3914 (const_int 0)])
3915 (match_operand:HI 3 "arith10_operand" "rM,0")
3916 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3917 "TARGET_ARCH64"
3918 "@
3919 movr%D1\\t%2, %r3, %0
3920 movr%d1\\t%2, %r4, %0"
3921 [(set_attr "type" "cmove")
3922 (set_attr "length" "1")])
3923
3924 (define_insn "*movsi_cc_reg_sp64"
3925 [(set (match_operand:SI 0 "register_operand" "=r,r")
3926 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3927 [(match_operand:DI 2 "register_operand" "r,r")
3928 (const_int 0)])
3929 (match_operand:SI 3 "arith10_operand" "rM,0")
3930 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3931 "TARGET_ARCH64"
3932 "@
3933 movr%D1\\t%2, %r3, %0
3934 movr%d1\\t%2, %r4, %0"
3935 [(set_attr "type" "cmove")
3936 (set_attr "length" "1")])
3937
3938 ;; ??? The constraints of operands 3,4 need work.
3939 (define_insn "*movdi_cc_reg_sp64"
3940 [(set (match_operand:DI 0 "register_operand" "=r,r")
3941 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3942 [(match_operand:DI 2 "register_operand" "r,r")
3943 (const_int 0)])
3944 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3945 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3946 "TARGET_ARCH64"
3947 "@
3948 movr%D1\\t%2, %r3, %0
3949 movr%d1\\t%2, %r4, %0"
3950 [(set_attr "type" "cmove")
3951 (set_attr "length" "1")])
3952
3953 (define_insn "*movdi_cc_reg_sp64_trunc"
3954 [(set (match_operand:SI 0 "register_operand" "=r,r")
3955 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3956 [(match_operand:DI 2 "register_operand" "r,r")
3957 (const_int 0)])
3958 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3959 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3960 "TARGET_ARCH64"
3961 "@
3962 movr%D1\\t%2, %r3, %0
3963 movr%d1\\t%2, %r4, %0"
3964 [(set_attr "type" "cmove")
3965 (set_attr "length" "1")])
3966
3967 (define_insn "*movsf_cc_reg_sp64"
3968 [(set (match_operand:SF 0 "register_operand" "=f,f")
3969 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3970 [(match_operand:DI 2 "register_operand" "r,r")
3971 (const_int 0)])
3972 (match_operand:SF 3 "register_operand" "f,0")
3973 (match_operand:SF 4 "register_operand" "0,f")))]
3974 "TARGET_ARCH64 && TARGET_FPU"
3975 "@
3976 fmovrs%D1\\t%2, %3, %0
3977 fmovrs%d1\\t%2, %4, %0"
3978 [(set_attr "type" "fpcmove")
3979 (set_attr "length" "1")])
3980
3981 (define_insn "*movdf_cc_reg_sp64"
3982 [(set (match_operand:DF 0 "register_operand" "=e,e")
3983 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3984 [(match_operand:DI 2 "register_operand" "r,r")
3985 (const_int 0)])
3986 (match_operand:DF 3 "register_operand" "e,0")
3987 (match_operand:DF 4 "register_operand" "0,e")))]
3988 "TARGET_ARCH64 && TARGET_FPU"
3989 "@
3990 fmovrd%D1\\t%2, %3, %0
3991 fmovrd%d1\\t%2, %4, %0"
3992 [(set_attr "type" "fpcmove")
3993 (set_attr "length" "1")])
3994
3995 (define_insn "*movtf_cc_reg_sp64"
3996 [(set (match_operand:TF 0 "register_operand" "=e,e")
3997 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3998 [(match_operand:DI 2 "register_operand" "r,r")
3999 (const_int 0)])
4000 (match_operand:TF 3 "register_operand" "e,0")
4001 (match_operand:TF 4 "register_operand" "0,e")))]
4002 "TARGET_ARCH64 && TARGET_FPU"
4003 "@
4004 fmovrq%D1\\t%2, %3, %0
4005 fmovrq%d1\\t%2, %4, %0"
4006 [(set_attr "type" "fpcmove")
4007 (set_attr "length" "1")])
4008 \f
4009 ;;- zero extension instructions
4010
4011 ;; These patterns originally accepted general_operands, however, slightly
4012 ;; better code is generated by only accepting register_operands, and then
4013 ;; letting combine generate the ldu[hb] insns.
4014
4015 (define_expand "zero_extendhisi2"
4016 [(set (match_operand:SI 0 "register_operand" "")
4017 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4018 ""
4019 "
4020 {
4021 rtx temp = gen_reg_rtx (SImode);
4022 rtx shift_16 = GEN_INT (16);
4023 int op1_subword = 0;
4024
4025 if (GET_CODE (operand1) == SUBREG)
4026 {
4027 op1_subword = SUBREG_WORD (operand1);
4028 operand1 = XEXP (operand1, 0);
4029 }
4030
4031 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4032 shift_16));
4033 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4034 DONE;
4035 }")
4036
4037 (define_insn "*zero_extendhisi2_insn"
4038 [(set (match_operand:SI 0 "register_operand" "=r")
4039 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4040 ""
4041 "lduh\\t%1, %0"
4042 [(set_attr "type" "load")
4043 (set_attr "length" "1")])
4044
4045 (define_expand "zero_extendqihi2"
4046 [(set (match_operand:HI 0 "register_operand" "")
4047 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4048 ""
4049 "")
4050
4051 (define_insn "*zero_extendqihi2_insn"
4052 [(set (match_operand:HI 0 "register_operand" "=r,r")
4053 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4054 "GET_CODE (operands[1]) != CONST_INT"
4055 "@
4056 and\\t%1, 0xff, %0
4057 ldub\\t%1, %0"
4058 [(set_attr "type" "unary,load")
4059 (set_attr "length" "1")])
4060
4061 (define_expand "zero_extendqisi2"
4062 [(set (match_operand:SI 0 "register_operand" "")
4063 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4064 ""
4065 "")
4066
4067 (define_insn "*zero_extendqisi2_insn"
4068 [(set (match_operand:SI 0 "register_operand" "=r,r")
4069 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4070 "GET_CODE (operands[1]) != CONST_INT"
4071 "@
4072 and\\t%1, 0xff, %0
4073 ldub\\t%1, %0"
4074 [(set_attr "type" "unary,load")
4075 (set_attr "length" "1")])
4076
4077 (define_expand "zero_extendqidi2"
4078 [(set (match_operand:DI 0 "register_operand" "")
4079 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4080 "TARGET_ARCH64"
4081 "")
4082
4083 (define_insn "*zero_extendqidi2_insn"
4084 [(set (match_operand:DI 0 "register_operand" "=r,r")
4085 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4086 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4087 "@
4088 and\\t%1, 0xff, %0
4089 ldub\\t%1, %0"
4090 [(set_attr "type" "unary,load")
4091 (set_attr "length" "1")])
4092
4093 (define_expand "zero_extendhidi2"
4094 [(set (match_operand:DI 0 "register_operand" "")
4095 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4096 "TARGET_ARCH64"
4097 "
4098 {
4099 rtx temp = gen_reg_rtx (DImode);
4100 rtx shift_48 = GEN_INT (48);
4101 int op1_subword = 0;
4102
4103 if (GET_CODE (operand1) == SUBREG)
4104 {
4105 op1_subword = SUBREG_WORD (operand1);
4106 operand1 = XEXP (operand1, 0);
4107 }
4108
4109 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4110 shift_48));
4111 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4112 DONE;
4113 }")
4114
4115 (define_insn "*zero_extendhidi2_insn"
4116 [(set (match_operand:DI 0 "register_operand" "=r")
4117 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4118 "TARGET_ARCH64"
4119 "lduh\\t%1, %0"
4120 [(set_attr "type" "load")
4121 (set_attr "length" "1")])
4122
4123
4124 ;; ??? Write truncdisi pattern using sra?
4125
4126 (define_expand "zero_extendsidi2"
4127 [(set (match_operand:DI 0 "register_operand" "")
4128 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4129 ""
4130 "")
4131
4132 (define_insn "*zero_extendsidi2_insn_sp64"
4133 [(set (match_operand:DI 0 "register_operand" "=r,r")
4134 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4135 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4136 "@
4137 srl\\t%1, 0, %0
4138 lduw\\t%1, %0"
4139 [(set_attr "type" "shift,load")
4140 (set_attr "length" "1")])
4141
4142 (define_insn "*zero_extendsidi2_insn_sp32"
4143 [(set (match_operand:DI 0 "register_operand" "=r")
4144 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4145 "! TARGET_ARCH64"
4146 "#"
4147 [(set_attr "type" "unary")
4148 (set_attr "length" "2")])
4149
4150 (define_split
4151 [(set (match_operand:DI 0 "register_operand" "")
4152 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4153 "! TARGET_ARCH64 && reload_completed"
4154 [(set (match_dup 2) (match_dup 3))
4155 (set (match_dup 4) (match_dup 5))]
4156 "
4157 {
4158 rtx dest1, dest2;
4159
4160 if (GET_CODE (operands[0]) == SUBREG)
4161 operands[0] = alter_subreg (operands[0]);
4162
4163 dest1 = gen_highpart (SImode, operands[0]);
4164 dest2 = gen_lowpart (SImode, operands[0]);
4165
4166 /* Swap the order in case of overlap. */
4167 if (REGNO (dest1) == REGNO (operands[1]))
4168 {
4169 operands[2] = dest2;
4170 operands[3] = operands[1];
4171 operands[4] = dest1;
4172 operands[5] = const0_rtx;
4173 }
4174 else
4175 {
4176 operands[2] = dest1;
4177 operands[3] = const0_rtx;
4178 operands[4] = dest2;
4179 operands[5] = operands[1];
4180 }
4181 }")
4182
4183 ;; Simplify comparisons of extended values.
4184
4185 (define_insn "*cmp_zero_extendqisi2"
4186 [(set (reg:CC 100)
4187 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4188 (const_int 0)))]
4189 "! TARGET_LIVE_G0"
4190 "andcc\\t%0, 0xff, %%g0"
4191 [(set_attr "type" "compare")
4192 (set_attr "length" "1")])
4193
4194 (define_insn "*cmp_zero_extendqisi2_set"
4195 [(set (reg:CC 100)
4196 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4197 (const_int 0)))
4198 (set (match_operand:SI 0 "register_operand" "=r")
4199 (zero_extend:SI (match_dup 1)))]
4200 ""
4201 "andcc\\t%1, 0xff, %0"
4202 [(set_attr "type" "compare")
4203 (set_attr "length" "1")])
4204
4205 (define_insn "*cmp_zero_extendqidi2"
4206 [(set (reg:CCX 100)
4207 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4208 (const_int 0)))]
4209 "TARGET_ARCH64"
4210 "andcc\\t%0, 0xff, %%g0"
4211 [(set_attr "type" "compare")
4212 (set_attr "length" "1")])
4213
4214 (define_insn "*cmp_zero_extendqidi2_set"
4215 [(set (reg:CCX 100)
4216 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4217 (const_int 0)))
4218 (set (match_operand:DI 0 "register_operand" "=r")
4219 (zero_extend:DI (match_dup 1)))]
4220 "TARGET_ARCH64"
4221 "andcc\\t%1, 0xff, %0"
4222 [(set_attr "type" "compare")
4223 (set_attr "length" "1")])
4224
4225 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4226
4227 (define_insn "*cmp_siqi_trunc"
4228 [(set (reg:CC 100)
4229 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4230 (const_int 0)))]
4231 "! TARGET_LIVE_G0"
4232 "andcc\\t%0, 0xff, %%g0"
4233 [(set_attr "type" "compare")
4234 (set_attr "length" "1")])
4235
4236 (define_insn "*cmp_siqi_trunc_set"
4237 [(set (reg:CC 100)
4238 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4239 (const_int 0)))
4240 (set (match_operand:QI 0 "register_operand" "=r")
4241 (subreg:QI (match_dup 1) 0))]
4242 ""
4243 "andcc\\t%1, 0xff, %0"
4244 [(set_attr "type" "compare")
4245 (set_attr "length" "1")])
4246
4247 (define_insn "*cmp_diqi_trunc"
4248 [(set (reg:CC 100)
4249 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4250 (const_int 0)))]
4251 "TARGET_ARCH64"
4252 "andcc\\t%0, 0xff, %%g0"
4253 [(set_attr "type" "compare")
4254 (set_attr "length" "1")])
4255
4256 (define_insn "*cmp_diqi_trunc_set"
4257 [(set (reg:CC 100)
4258 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4259 (const_int 0)))
4260 (set (match_operand:QI 0 "register_operand" "=r")
4261 (subreg:QI (match_dup 1) 0))]
4262 "TARGET_ARCH64"
4263 "andcc\\t%1, 0xff, %0"
4264 [(set_attr "type" "compare")
4265 (set_attr "length" "1")])
4266 \f
4267 ;;- sign extension instructions
4268
4269 ;; These patterns originally accepted general_operands, however, slightly
4270 ;; better code is generated by only accepting register_operands, and then
4271 ;; letting combine generate the lds[hb] insns.
4272
4273 (define_expand "extendhisi2"
4274 [(set (match_operand:SI 0 "register_operand" "")
4275 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4276 ""
4277 "
4278 {
4279 rtx temp = gen_reg_rtx (SImode);
4280 rtx shift_16 = GEN_INT (16);
4281 int op1_subword = 0;
4282
4283 if (GET_CODE (operand1) == SUBREG)
4284 {
4285 op1_subword = SUBREG_WORD (operand1);
4286 operand1 = XEXP (operand1, 0);
4287 }
4288
4289 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4290 shift_16));
4291 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4292 DONE;
4293 }")
4294
4295 (define_insn "*sign_extendhisi2_insn"
4296 [(set (match_operand:SI 0 "register_operand" "=r")
4297 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4298 ""
4299 "ldsh\\t%1, %0"
4300 [(set_attr "type" "sload")
4301 (set_attr "length" "1")])
4302
4303 (define_expand "extendqihi2"
4304 [(set (match_operand:HI 0 "register_operand" "")
4305 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4306 ""
4307 "
4308 {
4309 rtx temp = gen_reg_rtx (SImode);
4310 rtx shift_24 = GEN_INT (24);
4311 int op1_subword = 0;
4312 int op0_subword = 0;
4313
4314 if (GET_CODE (operand1) == SUBREG)
4315 {
4316 op1_subword = SUBREG_WORD (operand1);
4317 operand1 = XEXP (operand1, 0);
4318 }
4319 if (GET_CODE (operand0) == SUBREG)
4320 {
4321 op0_subword = SUBREG_WORD (operand0);
4322 operand0 = XEXP (operand0, 0);
4323 }
4324 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4325 shift_24));
4326 if (GET_MODE (operand0) != SImode)
4327 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4328 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4329 DONE;
4330 }")
4331
4332 (define_insn "*sign_extendqihi2_insn"
4333 [(set (match_operand:HI 0 "register_operand" "=r")
4334 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4335 ""
4336 "ldsb\\t%1, %0"
4337 [(set_attr "type" "sload")
4338 (set_attr "length" "1")])
4339
4340 (define_expand "extendqisi2"
4341 [(set (match_operand:SI 0 "register_operand" "")
4342 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4343 ""
4344 "
4345 {
4346 rtx temp = gen_reg_rtx (SImode);
4347 rtx shift_24 = GEN_INT (24);
4348 int op1_subword = 0;
4349
4350 if (GET_CODE (operand1) == SUBREG)
4351 {
4352 op1_subword = SUBREG_WORD (operand1);
4353 operand1 = XEXP (operand1, 0);
4354 }
4355
4356 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4357 shift_24));
4358 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4359 DONE;
4360 }")
4361
4362 (define_insn "*sign_extendqisi2_insn"
4363 [(set (match_operand:SI 0 "register_operand" "=r")
4364 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4365 ""
4366 "ldsb\\t%1, %0"
4367 [(set_attr "type" "sload")
4368 (set_attr "length" "1")])
4369
4370 (define_expand "extendqidi2"
4371 [(set (match_operand:DI 0 "register_operand" "")
4372 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4373 "TARGET_ARCH64"
4374 "
4375 {
4376 rtx temp = gen_reg_rtx (DImode);
4377 rtx shift_56 = GEN_INT (56);
4378 int op1_subword = 0;
4379
4380 if (GET_CODE (operand1) == SUBREG)
4381 {
4382 op1_subword = SUBREG_WORD (operand1);
4383 operand1 = XEXP (operand1, 0);
4384 }
4385
4386 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4387 shift_56));
4388 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4389 DONE;
4390 }")
4391
4392 (define_insn "*sign_extendqidi2_insn"
4393 [(set (match_operand:DI 0 "register_operand" "=r")
4394 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4395 "TARGET_ARCH64"
4396 "ldsb\\t%1, %0"
4397 [(set_attr "type" "sload")
4398 (set_attr "length" "1")])
4399
4400 (define_expand "extendhidi2"
4401 [(set (match_operand:DI 0 "register_operand" "")
4402 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4403 "TARGET_ARCH64"
4404 "
4405 {
4406 rtx temp = gen_reg_rtx (DImode);
4407 rtx shift_48 = GEN_INT (48);
4408 int op1_subword = 0;
4409
4410 if (GET_CODE (operand1) == SUBREG)
4411 {
4412 op1_subword = SUBREG_WORD (operand1);
4413 operand1 = XEXP (operand1, 0);
4414 }
4415
4416 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4417 shift_48));
4418 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4419 DONE;
4420 }")
4421
4422 (define_insn "*sign_extendhidi2_insn"
4423 [(set (match_operand:DI 0 "register_operand" "=r")
4424 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4425 "TARGET_ARCH64"
4426 "ldsh\\t%1, %0"
4427 [(set_attr "type" "sload")
4428 (set_attr "length" "1")])
4429
4430 (define_expand "extendsidi2"
4431 [(set (match_operand:DI 0 "register_operand" "")
4432 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4433 "TARGET_ARCH64"
4434 "")
4435
4436 (define_insn "*sign_extendsidi2_insn"
4437 [(set (match_operand:DI 0 "register_operand" "=r,r")
4438 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4439 "TARGET_ARCH64"
4440 "@
4441 sra\\t%1, 0, %0
4442 ldsw\\t%1, %0"
4443 [(set_attr "type" "shift,sload")
4444 (set_attr "length" "1")])
4445 \f
4446 ;; Special pattern for optimizing bit-field compares. This is needed
4447 ;; because combine uses this as a canonical form.
4448
4449 (define_insn "*cmp_zero_extract"
4450 [(set (reg:CC 100)
4451 (compare:CC
4452 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4453 (match_operand:SI 1 "small_int_or_double" "n")
4454 (match_operand:SI 2 "small_int_or_double" "n"))
4455 (const_int 0)))]
4456 "! TARGET_LIVE_G0
4457 && ((GET_CODE (operands[2]) == CONST_INT
4458 && INTVAL (operands[2]) > 19)
4459 || (GET_CODE (operands[2]) == CONST_DOUBLE
4460 && CONST_DOUBLE_LOW (operands[2]) > 19))"
4461 "*
4462 {
4463 int len = (GET_CODE (operands[1]) == CONST_INT
4464 ? INTVAL (operands[1])
4465 : CONST_DOUBLE_LOW (operands[1]));
4466 int pos = 32 -
4467 (GET_CODE (operands[2]) == CONST_INT
4468 ? INTVAL (operands[2])
4469 : CONST_DOUBLE_LOW (operands[2])) - len;
4470 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4471
4472 operands[1] = GEN_INT (mask);
4473 return \"andcc\\t%0, %1, %%g0\";
4474 }"
4475 [(set_attr "type" "compare")
4476 (set_attr "length" "1")])
4477
4478 (define_insn "*cmp_zero_extract_sp64"
4479 [(set (reg:CCX 100)
4480 (compare:CCX
4481 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4482 (match_operand:SI 1 "small_int_or_double" "n")
4483 (match_operand:SI 2 "small_int_or_double" "n"))
4484 (const_int 0)))]
4485 "TARGET_ARCH64
4486 && ((GET_CODE (operands[2]) == CONST_INT
4487 && INTVAL (operands[2]) > 51)
4488 || (GET_CODE (operands[2]) == CONST_DOUBLE
4489 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4490 "*
4491 {
4492 int len = (GET_CODE (operands[1]) == CONST_INT
4493 ? INTVAL (operands[1])
4494 : CONST_DOUBLE_LOW (operands[1]));
4495 int pos = 64 -
4496 (GET_CODE (operands[2]) == CONST_INT
4497 ? INTVAL (operands[2])
4498 : CONST_DOUBLE_LOW (operands[2])) - len;
4499 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4500
4501 operands[1] = GEN_INT (mask);
4502 return \"andcc\\t%0, %1, %%g0\";
4503 }"
4504 [(set_attr "type" "compare")
4505 (set_attr "length" "1")])
4506 \f
4507 ;; Conversions between float, double and long double.
4508
4509 (define_insn "extendsfdf2"
4510 [(set (match_operand:DF 0 "register_operand" "=e")
4511 (float_extend:DF
4512 (match_operand:SF 1 "register_operand" "f")))]
4513 "TARGET_FPU"
4514 "fstod\\t%1, %0"
4515 [(set_attr "type" "fp")
4516 (set_attr "length" "1")])
4517
4518 (define_insn "extendsftf2"
4519 [(set (match_operand:TF 0 "register_operand" "=e")
4520 (float_extend:TF
4521 (match_operand:SF 1 "register_operand" "f")))]
4522 "TARGET_FPU && TARGET_HARD_QUAD"
4523 "fstoq\\t%1, %0"
4524 [(set_attr "type" "fp")
4525 (set_attr "length" "1")])
4526
4527 (define_insn "extenddftf2"
4528 [(set (match_operand:TF 0 "register_operand" "=e")
4529 (float_extend:TF
4530 (match_operand:DF 1 "register_operand" "e")))]
4531 "TARGET_FPU && TARGET_HARD_QUAD"
4532 "fdtoq\\t%1, %0"
4533 [(set_attr "type" "fp")
4534 (set_attr "length" "1")])
4535
4536 (define_insn "truncdfsf2"
4537 [(set (match_operand:SF 0 "register_operand" "=f")
4538 (float_truncate:SF
4539 (match_operand:DF 1 "register_operand" "e")))]
4540 "TARGET_FPU"
4541 "fdtos\\t%1, %0"
4542 [(set_attr "type" "fp")
4543 (set_attr "length" "1")])
4544
4545 (define_insn "trunctfsf2"
4546 [(set (match_operand:SF 0 "register_operand" "=f")
4547 (float_truncate:SF
4548 (match_operand:TF 1 "register_operand" "e")))]
4549 "TARGET_FPU && TARGET_HARD_QUAD"
4550 "fqtos\\t%1, %0"
4551 [(set_attr "type" "fp")
4552 (set_attr "length" "1")])
4553
4554 (define_insn "trunctfdf2"
4555 [(set (match_operand:DF 0 "register_operand" "=e")
4556 (float_truncate:DF
4557 (match_operand:TF 1 "register_operand" "e")))]
4558 "TARGET_FPU && TARGET_HARD_QUAD"
4559 "fqtod\\t%1, %0"
4560 [(set_attr "type" "fp")
4561 (set_attr "length" "1")])
4562 \f
4563 ;; Conversion between fixed point and floating point.
4564
4565 (define_insn "floatsisf2"
4566 [(set (match_operand:SF 0 "register_operand" "=f")
4567 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4568 "TARGET_FPU"
4569 "fitos\\t%1, %0"
4570 [(set_attr "type" "fp")
4571 (set_attr "length" "1")])
4572
4573 (define_insn "floatsidf2"
4574 [(set (match_operand:DF 0 "register_operand" "=e")
4575 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4576 "TARGET_FPU"
4577 "fitod\\t%1, %0"
4578 [(set_attr "type" "fp")
4579 (set_attr "length" "1")])
4580
4581 (define_insn "floatsitf2"
4582 [(set (match_operand:TF 0 "register_operand" "=e")
4583 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4584 "TARGET_FPU && TARGET_HARD_QUAD"
4585 "fitoq\\t%1, %0"
4586 [(set_attr "type" "fp")
4587 (set_attr "length" "1")])
4588
4589 ;; Now the same for 64 bit sources.
4590
4591 (define_insn "floatdisf2"
4592 [(set (match_operand:SF 0 "register_operand" "=f")
4593 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4594 "TARGET_V9 && TARGET_FPU"
4595 "fxtos\\t%1, %0"
4596 [(set_attr "type" "fp")
4597 (set_attr "length" "1")])
4598
4599 (define_insn "floatdidf2"
4600 [(set (match_operand:DF 0 "register_operand" "=e")
4601 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4602 "TARGET_V9 && TARGET_FPU"
4603 "fxtod\\t%1, %0"
4604 [(set_attr "type" "fp")
4605 (set_attr "length" "1")])
4606
4607 (define_insn "floatditf2"
4608 [(set (match_operand:TF 0 "register_operand" "=e")
4609 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4610 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4611 "fxtoq\\t%1, %0"
4612 [(set_attr "type" "fp")
4613 (set_attr "length" "1")])
4614
4615 ;; Convert a float to an actual integer.
4616 ;; Truncation is performed as part of the conversion.
4617
4618 (define_insn "fix_truncsfsi2"
4619 [(set (match_operand:SI 0 "register_operand" "=f")
4620 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4621 "TARGET_FPU"
4622 "fstoi\\t%1, %0"
4623 [(set_attr "type" "fp")
4624 (set_attr "length" "1")])
4625
4626 (define_insn "fix_truncdfsi2"
4627 [(set (match_operand:SI 0 "register_operand" "=f")
4628 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4629 "TARGET_FPU"
4630 "fdtoi\\t%1, %0"
4631 [(set_attr "type" "fp")
4632 (set_attr "length" "1")])
4633
4634 (define_insn "fix_trunctfsi2"
4635 [(set (match_operand:SI 0 "register_operand" "=f")
4636 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4637 "TARGET_FPU && TARGET_HARD_QUAD"
4638 "fqtoi\\t%1, %0"
4639 [(set_attr "type" "fp")
4640 (set_attr "length" "1")])
4641
4642 ;; Now the same, for V9 targets
4643
4644 (define_insn "fix_truncsfdi2"
4645 [(set (match_operand:DI 0 "register_operand" "=e")
4646 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4647 "TARGET_V9 && TARGET_FPU"
4648 "fstox\\t%1, %0"
4649 [(set_attr "type" "fp")
4650 (set_attr "length" "1")])
4651
4652 (define_insn "fix_truncdfdi2"
4653 [(set (match_operand:DI 0 "register_operand" "=e")
4654 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4655 "TARGET_V9 && TARGET_FPU"
4656 "fdtox\\t%1, %0"
4657 [(set_attr "type" "fp")
4658 (set_attr "length" "1")])
4659
4660 (define_insn "fix_trunctfdi2"
4661 [(set (match_operand:DI 0 "register_operand" "=e")
4662 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4663 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4664 "fqtox\\t%1, %0"
4665 [(set_attr "type" "fp")
4666 (set_attr "length" "1")])
4667 \f
4668 ;;- arithmetic instructions
4669
4670 (define_expand "adddi3"
4671 [(set (match_operand:DI 0 "register_operand" "=r")
4672 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4673 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4674 ""
4675 "
4676 {
4677 if (! TARGET_ARCH64)
4678 {
4679 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4680 gen_rtx_SET (VOIDmode, operands[0],
4681 gen_rtx_PLUS (DImode, operands[1],
4682 operands[2])),
4683 gen_rtx_CLOBBER (VOIDmode,
4684 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4685 DONE;
4686 }
4687 if (arith_double_4096_operand(operands[2], DImode))
4688 {
4689 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4690 gen_rtx_MINUS (DImode, operands[1],
4691 GEN_INT(-4096))));
4692 DONE;
4693 }
4694 }")
4695
4696 (define_insn "adddi3_insn_sp32"
4697 [(set (match_operand:DI 0 "register_operand" "=r")
4698 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4699 (match_operand:DI 2 "arith_double_operand" "rHI")))
4700 (clobber (reg:CC 100))]
4701 "! TARGET_ARCH64"
4702 "#"
4703 [(set_attr "length" "2")])
4704
4705 (define_split
4706 [(set (match_operand:DI 0 "register_operand" "=r")
4707 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4708 (match_operand:DI 2 "arith_double_operand" "rHI")))
4709 (clobber (reg:CC 100))]
4710 "! TARGET_ARCH64 && reload_completed"
4711 [(parallel [(set (reg:CC_NOOV 100)
4712 (compare:CC_NOOV (plus:SI (match_dup 4)
4713 (match_dup 5))
4714 (const_int 0)))
4715 (set (match_dup 3)
4716 (plus:SI (match_dup 4) (match_dup 5)))])
4717 (set (match_dup 6)
4718 (plus:SI (plus:SI (match_dup 7)
4719 (match_dup 8))
4720 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4721 "
4722 {
4723 operands[3] = gen_lowpart (SImode, operands[0]);
4724 operands[4] = gen_lowpart (SImode, operands[1]);
4725 operands[5] = gen_lowpart (SImode, operands[2]);
4726 operands[6] = gen_highpart (SImode, operands[0]);
4727 operands[7] = gen_highpart (SImode, operands[1]);
4728 if (GET_CODE (operands[2]) == CONST_INT)
4729 {
4730 if (INTVAL (operands[2]) < 0)
4731 operands[8] = constm1_rtx;
4732 else
4733 operands[8] = const0_rtx;
4734 }
4735 else
4736 operands[8] = gen_highpart (SImode, operands[2]);
4737 }")
4738
4739 (define_split
4740 [(set (match_operand:DI 0 "register_operand" "=r")
4741 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
4742 (match_operand:DI 2 "arith_double_operand" "rHI")))
4743 (clobber (reg:CC 100))]
4744 "! TARGET_ARCH64 && reload_completed"
4745 [(parallel [(set (reg:CC_NOOV 100)
4746 (compare:CC_NOOV (minus:SI (match_dup 4)
4747 (match_dup 5))
4748 (const_int 0)))
4749 (set (match_dup 3)
4750 (minus:SI (match_dup 4) (match_dup 5)))])
4751 (set (match_dup 6)
4752 (minus:SI (minus:SI (match_dup 7)
4753 (match_dup 8))
4754 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4755 "
4756 {
4757 operands[3] = gen_lowpart (SImode, operands[0]);
4758 operands[4] = gen_lowpart (SImode, operands[1]);
4759 operands[5] = gen_lowpart (SImode, operands[2]);
4760 operands[6] = gen_highpart (SImode, operands[0]);
4761 operands[7] = gen_highpart (SImode, operands[1]);
4762 if (GET_CODE (operands[2]) == CONST_INT)
4763 {
4764 if (INTVAL (operands[2]) < 0)
4765 operands[8] = constm1_rtx;
4766 else
4767 operands[8] = const0_rtx;
4768 }
4769 else
4770 operands[8] = gen_highpart (SImode, operands[2]);
4771 }")
4772
4773 ;; LTU here means "carry set"
4774 (define_insn "addx"
4775 [(set (match_operand:SI 0 "register_operand" "=r")
4776 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4777 (match_operand:SI 2 "arith_operand" "rI"))
4778 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4779 ""
4780 "addx\\t%1, %2, %0"
4781 [(set_attr "type" "unary")
4782 (set_attr "length" "1")])
4783
4784 (define_insn "*addx_extend_sp32"
4785 [(set (match_operand:DI 0 "register_operand" "=r")
4786 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4787 (match_operand:SI 2 "arith_operand" "rI"))
4788 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4789 "! TARGET_ARCH64"
4790 "#"
4791 [(set_attr "type" "unary")
4792 (set_attr "length" "2")])
4793
4794 (define_split
4795 [(set (match_operand:DI 0 "register_operand" "")
4796 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
4797 (match_operand:SI 2 "arith_operand" ""))
4798 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4799 "! TARGET_ARCH64 && reload_completed"
4800 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4801 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4802 (set (match_dup 4) (const_int 0))]
4803 "operands[3] = gen_lowpart (SImode, operands[0]);
4804 operands[4] = gen_highpart (SImode, operands[1]);")
4805
4806 (define_insn "*addx_extend_sp64"
4807 [(set (match_operand:DI 0 "register_operand" "=r")
4808 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4809 (match_operand:SI 2 "arith_operand" "rI"))
4810 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4811 "TARGET_ARCH64"
4812 "addx\\t%r1, %2, %0"
4813 [(set_attr "type" "misc")
4814 (set_attr "length" "1")])
4815
4816 (define_insn "subx"
4817 [(set (match_operand:SI 0 "register_operand" "=r")
4818 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4819 (match_operand:SI 2 "arith_operand" "rI"))
4820 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4821 ""
4822 "subx\\t%r1, %2, %0"
4823 [(set_attr "type" "misc")
4824 (set_attr "length" "1")])
4825
4826 (define_insn "*subx_extend_sp64"
4827 [(set (match_operand:DI 0 "register_operand" "=r")
4828 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4829 (match_operand:SI 2 "arith_operand" "rI"))
4830 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4831 "TARGET_ARCH64"
4832 "subx\\t%r1, %2, %0"
4833 [(set_attr "type" "misc")
4834 (set_attr "length" "1")])
4835
4836 (define_insn "*subx_extend"
4837 [(set (match_operand:DI 0 "register_operand" "=r")
4838 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4839 (match_operand:SI 2 "arith_operand" "rI"))
4840 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4841 "! TARGET_ARCH64"
4842 "#"
4843 [(set_attr "type" "unary")
4844 (set_attr "length" "2")])
4845
4846 (define_split
4847 [(set (match_operand:DI 0 "register_operand" "=r")
4848 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4849 (match_operand:SI 2 "arith_operand" "rI"))
4850 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4851 "! TARGET_ARCH64 && reload_completed"
4852 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4853 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4854 (set (match_dup 4) (const_int 0))]
4855 "operands[3] = gen_lowpart (SImode, operands[0]);
4856 operands[4] = gen_highpart (SImode, operands[0]);")
4857
4858 (define_insn ""
4859 [(set (match_operand:DI 0 "register_operand" "=r")
4860 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4861 (match_operand:DI 2 "register_operand" "r")))
4862 (clobber (reg:CC 100))]
4863 "! TARGET_ARCH64"
4864 "#"
4865 [(set_attr "type" "multi")
4866 (set_attr "length" "2")])
4867
4868 (define_split
4869 [(set (match_operand:DI 0 "register_operand" "")
4870 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4871 (match_operand:DI 2 "register_operand" "")))
4872 (clobber (reg:CC 100))]
4873 "! TARGET_ARCH64 && reload_completed"
4874 [(parallel [(set (reg:CC_NOOV 100)
4875 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4876 (const_int 0)))
4877 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4878 (set (match_dup 6)
4879 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4880 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4881 "operands[3] = gen_lowpart (SImode, operands[2]);
4882 operands[4] = gen_highpart (SImode, operands[2]);
4883 operands[5] = gen_lowpart (SImode, operands[0]);
4884 operands[6] = gen_highpart (SImode, operands[0]);")
4885
4886 (define_insn "*adddi3_sp64"
4887 [(set (match_operand:DI 0 "register_operand" "=r")
4888 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4889 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4890 "TARGET_ARCH64"
4891 "add\\t%1, %2, %0"
4892 [(set_attr "type" "binary")
4893 (set_attr "length" "1")])
4894
4895 (define_expand "addsi3"
4896 [(set (match_operand:SI 0 "register_operand" "=r,d")
4897 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4898 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
4899 ""
4900 "
4901 {
4902 if (arith_4096_operand(operands[2], DImode))
4903 {
4904 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4905 gen_rtx_MINUS (SImode, operands[1],
4906 GEN_INT(-4096))));
4907 DONE;
4908 }
4909 }")
4910
4911 (define_insn "*addsi3"
4912 [(set (match_operand:SI 0 "register_operand" "=r,d")
4913 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4914 (match_operand:SI 2 "arith_operand" "rI,d")))]
4915 ""
4916 "@
4917 add\\t%1, %2, %0
4918 fpadd32s\\t%1, %2, %0"
4919 [(set_attr "type" "ialu,fp")
4920 (set_attr "length" "1")])
4921
4922 (define_insn "*cmp_cc_plus"
4923 [(set (reg:CC_NOOV 100)
4924 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4925 (match_operand:SI 1 "arith_operand" "rI"))
4926 (const_int 0)))]
4927 "! TARGET_LIVE_G0"
4928 "addcc\\t%0, %1, %%g0"
4929 [(set_attr "type" "compare")
4930 (set_attr "length" "1")])
4931
4932 (define_insn "*cmp_ccx_plus"
4933 [(set (reg:CCX_NOOV 100)
4934 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4935 (match_operand:DI 1 "arith_double_operand" "rHI"))
4936 (const_int 0)))]
4937 "TARGET_ARCH64"
4938 "addcc\\t%0, %1, %%g0"
4939 [(set_attr "type" "compare")
4940 (set_attr "length" "1")])
4941
4942 (define_insn "*cmp_cc_plus_set"
4943 [(set (reg:CC_NOOV 100)
4944 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4945 (match_operand:SI 2 "arith_operand" "rI"))
4946 (const_int 0)))
4947 (set (match_operand:SI 0 "register_operand" "=r")
4948 (plus:SI (match_dup 1) (match_dup 2)))]
4949 ""
4950 "addcc\\t%1, %2, %0"
4951 [(set_attr "type" "compare")
4952 (set_attr "length" "1")])
4953
4954 (define_insn "*cmp_ccx_plus_set"
4955 [(set (reg:CCX_NOOV 100)
4956 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4957 (match_operand:DI 2 "arith_double_operand" "rHI"))
4958 (const_int 0)))
4959 (set (match_operand:DI 0 "register_operand" "=r")
4960 (plus:DI (match_dup 1) (match_dup 2)))]
4961 "TARGET_ARCH64"
4962 "addcc\\t%1, %2, %0"
4963 [(set_attr "type" "compare")
4964 (set_attr "length" "1")])
4965
4966 (define_expand "subdi3"
4967 [(set (match_operand:DI 0 "register_operand" "=r")
4968 (minus:DI (match_operand:DI 1 "register_operand" "r")
4969 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4970 ""
4971 "
4972 {
4973 if (! TARGET_ARCH64)
4974 {
4975 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4976 gen_rtx_SET (VOIDmode, operands[0],
4977 gen_rtx_MINUS (DImode, operands[1],
4978 operands[2])),
4979 gen_rtx_CLOBBER (VOIDmode,
4980 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4981 DONE;
4982 }
4983 if (arith_double_4096_operand(operands[2], DImode))
4984 {
4985 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4986 gen_rtx_PLUS (DImode, operands[1],
4987 GEN_INT(-4096))));
4988 DONE;
4989 }
4990 }")
4991
4992 (define_insn "*subdi3_sp32"
4993 [(set (match_operand:DI 0 "register_operand" "=r")
4994 (minus:DI (match_operand:DI 1 "register_operand" "r")
4995 (match_operand:DI 2 "arith_double_operand" "rHI")))
4996 (clobber (reg:CC 100))]
4997 "! TARGET_ARCH64"
4998 "#"
4999 [(set_attr "length" "2")])
5000
5001 (define_split
5002 [(set (match_operand:DI 0 "register_operand" "")
5003 (minus:DI (match_operand:DI 1 "register_operand" "")
5004 (match_operand:DI 2 "arith_double_operand" "")))
5005 (clobber (reg:CC 100))]
5006 "! TARGET_ARCH64
5007 && reload_completed
5008 && (GET_CODE (operands[2]) == CONST_INT
5009 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5010 [(clobber (const_int 0))]
5011 "
5012 {
5013 rtx highp, lowp;
5014
5015 highp = gen_highpart (SImode, operands[2]);
5016 lowp = gen_lowpart (SImode, operands[2]);
5017 if ((lowp == const0_rtx)
5018 && (operands[0] == operands[1]))
5019 {
5020 emit_insn (gen_rtx_SET (VOIDmode,
5021 gen_highpart (SImode, operands[0]),
5022 gen_rtx_MINUS (SImode,
5023 gen_highpart (SImode, operands[1]),
5024 highp)));
5025 }
5026 else
5027 {
5028 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5029 gen_lowpart (SImode, operands[1]),
5030 lowp));
5031 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5032 gen_highpart (SImode, operands[1]),
5033 highp));
5034 }
5035 DONE;
5036 }")
5037
5038 (define_split
5039 [(set (match_operand:DI 0 "register_operand" "")
5040 (minus:DI (match_operand:DI 1 "register_operand" "")
5041 (match_operand:DI 2 "register_operand" "")))
5042 (clobber (reg:CC 100))]
5043 "! TARGET_ARCH64
5044 && reload_completed"
5045 [(clobber (const_int 0))]
5046 "
5047 {
5048 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5049 gen_lowpart (SImode, operands[1]),
5050 gen_lowpart (SImode, operands[2])));
5051 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5052 gen_highpart (SImode, operands[1]),
5053 gen_highpart (SImode, operands[2])));
5054 DONE;
5055 }")
5056
5057 (define_insn ""
5058 [(set (match_operand:DI 0 "register_operand" "=r")
5059 (minus:DI (match_operand:DI 1 "register_operand" "r")
5060 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5061 (clobber (reg:CC 100))]
5062 "! TARGET_ARCH64"
5063 "#"
5064 [(set_attr "type" "multi")
5065 (set_attr "length" "2")])
5066
5067 (define_split
5068 [(set (match_operand:DI 0 "register_operand" "")
5069 (minus:DI (match_operand:DI 1 "register_operand" "")
5070 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5071 (clobber (reg:CC 100))]
5072 "! TARGET_ARCH64 && reload_completed"
5073 [(parallel [(set (reg:CC_NOOV 100)
5074 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5075 (const_int 0)))
5076 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5077 (set (match_dup 6)
5078 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5079 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5080 "operands[3] = gen_lowpart (SImode, operands[1]);
5081 operands[4] = gen_highpart (SImode, operands[1]);
5082 operands[5] = gen_lowpart (SImode, operands[0]);
5083 operands[6] = gen_highpart (SImode, operands[0]);")
5084
5085 (define_insn "*subdi3_sp64"
5086 [(set (match_operand:DI 0 "register_operand" "=r")
5087 (minus:DI (match_operand:DI 1 "register_operand" "r")
5088 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5089 "TARGET_ARCH64"
5090 "sub\\t%1, %2, %0"
5091 [(set_attr "type" "binary")
5092 (set_attr "length" "1")])
5093
5094 (define_expand "subsi3"
5095 [(set (match_operand:SI 0 "register_operand" "=r,d")
5096 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5097 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5098 ""
5099 "
5100 {
5101 if (arith_4096_operand(operands[2], DImode))
5102 {
5103 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5104 gen_rtx_PLUS (SImode, operands[1],
5105 GEN_INT(-4096))));
5106 DONE;
5107 }
5108 }")
5109
5110 (define_insn "*subsi3"
5111 [(set (match_operand:SI 0 "register_operand" "=r,d")
5112 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5113 (match_operand:SI 2 "arith_operand" "rI,d")))]
5114 ""
5115 "@
5116 sub\\t%1, %2, %0
5117 fpsub32s\\t%1, %2, %0"
5118 [(set_attr "type" "ialu,fp")
5119 (set_attr "length" "1")])
5120
5121 (define_insn "*cmp_minus_cc"
5122 [(set (reg:CC_NOOV 100)
5123 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5124 (match_operand:SI 1 "arith_operand" "rI"))
5125 (const_int 0)))]
5126 "! TARGET_LIVE_G0"
5127 "subcc\\t%r0, %1, %%g0"
5128 [(set_attr "type" "compare")
5129 (set_attr "length" "1")])
5130
5131 (define_insn "*cmp_minus_ccx"
5132 [(set (reg:CCX_NOOV 100)
5133 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5134 (match_operand:DI 1 "arith_double_operand" "rHI"))
5135 (const_int 0)))]
5136 "TARGET_ARCH64"
5137 "subcc\\t%0, %1, %%g0"
5138 [(set_attr "type" "compare")
5139 (set_attr "length" "1")])
5140
5141 (define_insn "cmp_minus_cc_set"
5142 [(set (reg:CC_NOOV 100)
5143 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5144 (match_operand:SI 2 "arith_operand" "rI"))
5145 (const_int 0)))
5146 (set (match_operand:SI 0 "register_operand" "=r")
5147 (minus:SI (match_dup 1) (match_dup 2)))]
5148 ""
5149 "subcc\\t%r1, %2, %0"
5150 [(set_attr "type" "compare")
5151 (set_attr "length" "1")])
5152
5153 (define_insn "*cmp_minus_ccx_set"
5154 [(set (reg:CCX_NOOV 100)
5155 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5156 (match_operand:DI 2 "arith_double_operand" "rHI"))
5157 (const_int 0)))
5158 (set (match_operand:DI 0 "register_operand" "=r")
5159 (minus:DI (match_dup 1) (match_dup 2)))]
5160 "TARGET_ARCH64"
5161 "subcc\\t%1, %2, %0"
5162 [(set_attr "type" "compare")
5163 (set_attr "length" "1")])
5164 \f
5165 ;; Integer Multiply/Divide.
5166
5167 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5168 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5169
5170 (define_insn "mulsi3"
5171 [(set (match_operand:SI 0 "register_operand" "=r")
5172 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5173 (match_operand:SI 2 "arith_operand" "rI")))]
5174 "TARGET_HARD_MUL"
5175 "smul\\t%1, %2, %0"
5176 [(set_attr "type" "imul")
5177 (set_attr "length" "1")])
5178
5179 (define_expand "muldi3"
5180 [(set (match_operand:DI 0 "register_operand" "=r")
5181 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5182 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5183 "TARGET_ARCH64 || TARGET_V8PLUS"
5184 "
5185 {
5186 if (TARGET_V8PLUS)
5187 {
5188 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5189 DONE;
5190 }
5191 }")
5192
5193 (define_insn "*muldi3_sp64"
5194 [(set (match_operand:DI 0 "register_operand" "=r")
5195 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5196 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5197 "TARGET_ARCH64"
5198 "mulx\\t%1, %2, %0"
5199 [(set_attr "type" "imul")
5200 (set_attr "length" "1")])
5201
5202 ;; V8plus wide multiply.
5203 ;; XXX
5204 (define_insn "muldi3_v8plus"
5205 [(set (match_operand:DI 0 "register_operand" "=r,h")
5206 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5207 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
5208 (clobber (match_scratch:SI 3 "=&h,X"))
5209 (clobber (match_scratch:SI 4 "=&h,X"))]
5210 "TARGET_V8PLUS"
5211 "*
5212 {
5213 if (sparc_check_64 (operands[1], insn) <= 0)
5214 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5215 if (which_alternative == 1)
5216 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5217 if (sparc_check_64 (operands[2], insn) <= 0)
5218 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5219 if (which_alternative == 1)
5220 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\";
5221 else
5222 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\";
5223 }"
5224 [(set_attr "length" "9,8")])
5225
5226 (define_insn "*cmp_mul_set"
5227 [(set (reg:CC 100)
5228 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5229 (match_operand:SI 2 "arith_operand" "rI"))
5230 (const_int 0)))
5231 (set (match_operand:SI 0 "register_operand" "=r")
5232 (mult:SI (match_dup 1) (match_dup 2)))]
5233 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5234 "smulcc\\t%1, %2, %0"
5235 [(set_attr "type" "imul")
5236 (set_attr "length" "1")])
5237
5238 (define_expand "mulsidi3"
5239 [(set (match_operand:DI 0 "register_operand" "")
5240 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5241 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5242 "TARGET_HARD_MUL"
5243 "
5244 {
5245 if (CONSTANT_P (operands[2]))
5246 {
5247 if (TARGET_V8PLUS)
5248 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5249 operands[2]));
5250 else
5251 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5252 operands[2]));
5253 DONE;
5254 }
5255 if (TARGET_V8PLUS)
5256 {
5257 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5258 DONE;
5259 }
5260 }")
5261
5262 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5263 ;; registers can hold 64 bit values in the V8plus environment.
5264 ;; XXX
5265 (define_insn "mulsidi3_v8plus"
5266 [(set (match_operand:DI 0 "register_operand" "=h,r")
5267 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5268 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5269 (clobber (match_scratch:SI 3 "=X,&h"))]
5270 "TARGET_V8PLUS"
5271 "@
5272 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5273 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5274 [(set_attr "length" "2,3")])
5275
5276 ;; XXX
5277 (define_insn "const_mulsidi3_v8plus"
5278 [(set (match_operand:DI 0 "register_operand" "=h,r")
5279 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5280 (match_operand:SI 2 "small_int" "I,I")))
5281 (clobber (match_scratch:SI 3 "=X,&h"))]
5282 "TARGET_V8PLUS"
5283 "@
5284 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5285 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5286 [(set_attr "length" "2,3")])
5287
5288 ;; XXX
5289 (define_insn "*mulsidi3_sp32"
5290 [(set (match_operand:DI 0 "register_operand" "=r")
5291 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5292 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5293 "TARGET_HARD_MUL32"
5294 "*
5295 {
5296 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5297 }"
5298 [(set (attr "length")
5299 (if_then_else (eq_attr "isa" "sparclet")
5300 (const_int 1) (const_int 2)))])
5301
5302 (define_insn "*mulsidi3_sp64"
5303 [(set (match_operand:DI 0 "register_operand" "=r")
5304 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5305 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5306 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5307 "smul\\t%1, %2, %0"
5308 [(set_attr "length" "1")])
5309
5310 ;; Extra pattern, because sign_extend of a constant isn't valid.
5311
5312 ;; XXX
5313 (define_insn "const_mulsidi3_sp32"
5314 [(set (match_operand:DI 0 "register_operand" "=r")
5315 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5316 (match_operand:SI 2 "small_int" "I")))]
5317 "TARGET_HARD_MUL32"
5318 "*
5319 {
5320 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5321 }"
5322 [(set (attr "length")
5323 (if_then_else (eq_attr "isa" "sparclet")
5324 (const_int 1) (const_int 2)))])
5325
5326 (define_insn "const_mulsidi3_sp64"
5327 [(set (match_operand:DI 0 "register_operand" "=r")
5328 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5329 (match_operand:SI 2 "small_int" "I")))]
5330 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5331 "smul\\t%1, %2, %0"
5332 [(set_attr "length" "1")])
5333
5334 (define_expand "smulsi3_highpart"
5335 [(set (match_operand:SI 0 "register_operand" "")
5336 (truncate:SI
5337 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5338 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5339 (const_int 32))))]
5340 "TARGET_HARD_MUL && TARGET_ARCH32"
5341 "
5342 {
5343 if (CONSTANT_P (operands[2]))
5344 {
5345 if (TARGET_V8PLUS)
5346 {
5347 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5348 operands[1],
5349 operands[2],
5350 GEN_INT (32)));
5351 DONE;
5352 }
5353 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5354 DONE;
5355 }
5356 if (TARGET_V8PLUS)
5357 {
5358 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5359 operands[2], GEN_INT (32)));
5360 DONE;
5361 }
5362 }")
5363
5364 ;; XXX
5365 (define_insn "smulsi3_highpart_v8plus"
5366 [(set (match_operand:SI 0 "register_operand" "=h,r")
5367 (truncate:SI
5368 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5369 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5370 (match_operand:SI 3 "const_int_operand" "i,i"))))
5371 (clobber (match_scratch:SI 4 "=X,&h"))]
5372 "TARGET_V8PLUS"
5373 "@
5374 smul %1,%2,%0\;srlx %0,%3,%0
5375 smul %1,%2,%4\;srlx %4,%3,%0"
5376 [(set_attr "length" "2")])
5377
5378 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5379 ;; XXX
5380 (define_insn ""
5381 [(set (match_operand:SI 0 "register_operand" "=h,r")
5382 (subreg:SI
5383 (lshiftrt:DI
5384 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5385 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5386 (match_operand:SI 3 "const_int_operand" "i,i"))
5387 1))
5388 (clobber (match_scratch:SI 4 "=X,&h"))]
5389 "TARGET_V8PLUS"
5390 "@
5391 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5392 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5393 [(set_attr "length" "2")])
5394
5395 ;; XXX
5396 (define_insn "const_smulsi3_highpart_v8plus"
5397 [(set (match_operand:SI 0 "register_operand" "=h,r")
5398 (truncate:SI
5399 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5400 (match_operand 2 "small_int" "i,i"))
5401 (match_operand:SI 3 "const_int_operand" "i,i"))))
5402 (clobber (match_scratch:SI 4 "=X,&h"))]
5403 "TARGET_V8PLUS"
5404 "@
5405 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5406 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5407 [(set_attr "length" "2")])
5408
5409 ;; XXX
5410 (define_insn "*smulsi3_highpart_sp32"
5411 [(set (match_operand:SI 0 "register_operand" "=r")
5412 (truncate:SI
5413 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5414 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5415 (const_int 32))))]
5416 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5417 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5418 [(set_attr "length" "2")])
5419
5420 ;; XXX
5421 (define_insn "const_smulsi3_highpart"
5422 [(set (match_operand:SI 0 "register_operand" "=r")
5423 (truncate:SI
5424 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5425 (match_operand:SI 2 "register_operand" "r"))
5426 (const_int 32))))]
5427 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5428 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5429 [(set_attr "length" "2")])
5430
5431 (define_expand "umulsidi3"
5432 [(set (match_operand:DI 0 "register_operand" "")
5433 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5434 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5435 "TARGET_HARD_MUL"
5436 "
5437 {
5438 if (CONSTANT_P (operands[2]))
5439 {
5440 if (TARGET_V8PLUS)
5441 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5442 operands[2]));
5443 else
5444 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5445 operands[2]));
5446 DONE;
5447 }
5448 if (TARGET_V8PLUS)
5449 {
5450 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5451 DONE;
5452 }
5453 }")
5454
5455 ;; XXX
5456 (define_insn "umulsidi3_v8plus"
5457 [(set (match_operand:DI 0 "register_operand" "=h,r")
5458 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5459 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5460 (clobber (match_scratch:SI 3 "=X,&h"))]
5461 "TARGET_V8PLUS"
5462 "@
5463 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5464 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5465 [(set_attr "length" "2,3")])
5466
5467 ;; XXX
5468 (define_insn "*umulsidi3_sp32"
5469 [(set (match_operand:DI 0 "register_operand" "=r")
5470 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5471 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5472 "TARGET_HARD_MUL32"
5473 "*
5474 {
5475 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5476 }"
5477 [(set (attr "length")
5478 (if_then_else (eq_attr "isa" "sparclet")
5479 (const_int 1) (const_int 2)))])
5480
5481 (define_insn "*umulsidi3_sp64"
5482 [(set (match_operand:DI 0 "register_operand" "=r")
5483 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5484 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5485 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5486 "umul\\t%1, %2, %0"
5487 [(set_attr "length" "1")])
5488
5489 ;; Extra pattern, because sign_extend of a constant isn't valid.
5490
5491 ;; XXX
5492 (define_insn "const_umulsidi3_sp32"
5493 [(set (match_operand:DI 0 "register_operand" "=r")
5494 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5495 (match_operand:SI 2 "uns_small_int" "")))]
5496 "TARGET_HARD_MUL32"
5497 "*
5498 {
5499 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5500 }"
5501 [(set (attr "length")
5502 (if_then_else (eq_attr "isa" "sparclet")
5503 (const_int 1) (const_int 2)))])
5504
5505 (define_insn "const_umulsidi3_sp64"
5506 [(set (match_operand:DI 0 "register_operand" "=r")
5507 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5508 (match_operand:SI 2 "uns_small_int" "")))]
5509 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5510 "umul\\t%1, %2, %0"
5511 [(set_attr "length" "1")])
5512
5513 ;; XXX
5514 (define_insn "const_umulsidi3_v8plus"
5515 [(set (match_operand:DI 0 "register_operand" "=h,r")
5516 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5517 (match_operand:SI 2 "uns_small_int" "")))
5518 (clobber (match_scratch:SI 3 "=X,h"))]
5519 "TARGET_V8PLUS"
5520 "@
5521 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5522 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5523 [(set_attr "length" "2,3")])
5524
5525 (define_expand "umulsi3_highpart"
5526 [(set (match_operand:SI 0 "register_operand" "")
5527 (truncate:SI
5528 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5529 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5530 (const_int 32))))]
5531 "TARGET_HARD_MUL && TARGET_ARCH32"
5532 "
5533 {
5534 if (CONSTANT_P (operands[2]))
5535 {
5536 if (TARGET_V8PLUS)
5537 {
5538 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5539 operands[1],
5540 operands[2],
5541 GEN_INT (32)));
5542 DONE;
5543 }
5544 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5545 DONE;
5546 }
5547 if (TARGET_V8PLUS)
5548 {
5549 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5550 operands[2], GEN_INT (32)));
5551 DONE;
5552 }
5553 }")
5554
5555 ;; XXX
5556 (define_insn "umulsi3_highpart_v8plus"
5557 [(set (match_operand:SI 0 "register_operand" "=h,r")
5558 (truncate:SI
5559 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5560 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5561 (match_operand:SI 3 "const_int_operand" "i,i"))))
5562 (clobber (match_scratch:SI 4 "=X,h"))]
5563 "TARGET_V8PLUS"
5564 "@
5565 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5566 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5567 [(set_attr "length" "2")])
5568
5569 ;; XXX
5570 (define_insn "const_umulsi3_highpart_v8plus"
5571 [(set (match_operand:SI 0 "register_operand" "=h,r")
5572 (truncate:SI
5573 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5574 (match_operand:SI 2 "uns_small_int" ""))
5575 (match_operand:SI 3 "const_int_operand" "i,i"))))
5576 (clobber (match_scratch:SI 4 "=X,h"))]
5577 "TARGET_V8PLUS"
5578 "@
5579 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5580 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5581 [(set_attr "length" "2")])
5582
5583 ;; XXX
5584 (define_insn "*umulsi3_highpart_sp32"
5585 [(set (match_operand:SI 0 "register_operand" "=r")
5586 (truncate:SI
5587 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5588 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5589 (const_int 32))))]
5590 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5591 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5592 [(set_attr "length" "2")])
5593
5594 ;; XXX
5595 (define_insn "const_umulsi3_highpart"
5596 [(set (match_operand:SI 0 "register_operand" "=r")
5597 (truncate:SI
5598 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5599 (match_operand:SI 2 "uns_small_int" ""))
5600 (const_int 32))))]
5601 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5602 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5603 [(set_attr "length" "2")])
5604
5605 ;; The v8 architecture specifies that there must be 3 instructions between
5606 ;; a y register write and a use of it for correct results.
5607
5608 (define_expand "divsi3"
5609 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5610 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5611 (match_operand:SI 2 "input_operand" "rI,m")))
5612 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5613 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5614 "
5615 {
5616 if (TARGET_ARCH64)
5617 {
5618 operands[3] = gen_reg_rtx(SImode);
5619 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5620 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5621 operands[3]));
5622 DONE;
5623 }
5624 }")
5625
5626 (define_insn "divsi3_sp32"
5627 [(set (match_operand:SI 0 "register_operand" "=r,r")
5628 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5629 (match_operand:SI 2 "input_operand" "rI,m")))
5630 (clobber (match_scratch:SI 3 "=&r,&r"))]
5631 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5632 && TARGET_ARCH32"
5633 "*
5634 {
5635 if (which_alternative == 0)
5636 if (TARGET_V9)
5637 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
5638 else
5639 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5640 else
5641 if (TARGET_V9)
5642 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5643 else
5644 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\";
5645 }"
5646 [(set (attr "length")
5647 (if_then_else (eq_attr "isa" "v9")
5648 (const_int 4) (const_int 7)))])
5649
5650 (define_insn "divsi3_sp64"
5651 [(set (match_operand:SI 0 "register_operand" "=r")
5652 (div:SI (match_operand:SI 1 "register_operand" "r")
5653 (match_operand:SI 2 "input_operand" "rI")))
5654 (use (match_operand:SI 3 "register_operand" "r"))]
5655 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5656 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
5657 [(set_attr "length" "2")])
5658
5659 (define_insn "divdi3"
5660 [(set (match_operand:DI 0 "register_operand" "=r")
5661 (div:DI (match_operand:DI 1 "register_operand" "r")
5662 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5663 "TARGET_ARCH64"
5664 "sdivx\\t%1, %2, %0")
5665
5666 (define_insn "*cmp_sdiv_cc_set"
5667 [(set (reg:CC 100)
5668 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5669 (match_operand:SI 2 "arith_operand" "rI"))
5670 (const_int 0)))
5671 (set (match_operand:SI 0 "register_operand" "=r")
5672 (div:SI (match_dup 1) (match_dup 2)))
5673 (clobber (match_scratch:SI 3 "=&r"))]
5674 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5675 "*
5676 {
5677 if (TARGET_V9)
5678 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5679 else
5680 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5681 }"
5682 [(set (attr "length")
5683 (if_then_else (eq_attr "isa" "v9")
5684 (const_int 3) (const_int 6)))])
5685
5686 ;; XXX
5687 (define_expand "udivsi3"
5688 [(set (match_operand:SI 0 "register_operand" "")
5689 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5690 (match_operand:SI 2 "input_operand" "")))]
5691 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && ! TARGET_LIVE_G0"
5692 "")
5693
5694 (define_insn "udivsi3_sp32"
5695 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5696 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5697 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5698 "(TARGET_V8
5699 || TARGET_DEPRECATED_V8_INSNS)
5700 && TARGET_ARCH32 && ! TARGET_LIVE_G0"
5701 "*
5702 {
5703 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
5704 switch (which_alternative)
5705 {
5706 default:
5707 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
5708 case 1:
5709 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
5710 case 2:
5711 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
5712 }
5713 }"
5714 [(set_attr "length" "5")])
5715
5716 (define_insn "udivsi3_sp64"
5717 [(set (match_operand:SI 0 "register_operand" "=r")
5718 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5719 (match_operand:SI 2 "input_operand" "rI")))]
5720 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5721 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
5722 [(set_attr "length" "2")])
5723
5724 (define_insn "udivdi3"
5725 [(set (match_operand:DI 0 "register_operand" "=r")
5726 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5727 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5728 "TARGET_ARCH64"
5729 "udivx\\t%1, %2, %0")
5730
5731 (define_insn "*cmp_udiv_cc_set"
5732 [(set (reg:CC 100)
5733 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5734 (match_operand:SI 2 "arith_operand" "rI"))
5735 (const_int 0)))
5736 (set (match_operand:SI 0 "register_operand" "=r")
5737 (udiv:SI (match_dup 1) (match_dup 2)))]
5738 "(TARGET_V8
5739 || TARGET_DEPRECATED_V8_INSNS)
5740 && ! TARGET_LIVE_G0"
5741 "*
5742 {
5743 if (TARGET_V9)
5744 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
5745 else
5746 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
5747 }"
5748 [(set (attr "length")
5749 (if_then_else (eq_attr "isa" "v9")
5750 (const_int 2) (const_int 5)))])
5751
5752 ; sparclet multiply/accumulate insns
5753
5754 (define_insn "*smacsi"
5755 [(set (match_operand:SI 0 "register_operand" "=r")
5756 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5757 (match_operand:SI 2 "arith_operand" "rI"))
5758 (match_operand:SI 3 "register_operand" "0")))]
5759 "TARGET_SPARCLET"
5760 "smac\\t%1, %2, %0"
5761 [(set_attr "type" "imul")
5762 (set_attr "length" "1")])
5763
5764 (define_insn "*smacdi"
5765 [(set (match_operand:DI 0 "register_operand" "=r")
5766 (plus:DI (mult:DI (sign_extend:DI
5767 (match_operand:SI 1 "register_operand" "%r"))
5768 (sign_extend:DI
5769 (match_operand:SI 2 "register_operand" "r")))
5770 (match_operand:DI 3 "register_operand" "0")))]
5771 "TARGET_SPARCLET"
5772 "smacd\\t%1, %2, %L0"
5773 [(set_attr "type" "imul")
5774 (set_attr "length" "1")])
5775
5776 (define_insn "*umacdi"
5777 [(set (match_operand:DI 0 "register_operand" "=r")
5778 (plus:DI (mult:DI (zero_extend:DI
5779 (match_operand:SI 1 "register_operand" "%r"))
5780 (zero_extend:DI
5781 (match_operand:SI 2 "register_operand" "r")))
5782 (match_operand:DI 3 "register_operand" "0")))]
5783 "TARGET_SPARCLET"
5784 "umacd\\t%1, %2, %L0"
5785 [(set_attr "type" "imul")
5786 (set_attr "length" "1")])
5787 \f
5788 ;;- Boolean instructions
5789 ;; We define DImode `and' so with DImode `not' we can get
5790 ;; DImode `andn'. Other combinations are possible.
5791
5792 (define_expand "anddi3"
5793 [(set (match_operand:DI 0 "register_operand" "")
5794 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5795 (match_operand:DI 2 "arith_double_operand" "")))]
5796 ""
5797 "")
5798
5799 (define_insn "*anddi3_sp32"
5800 [(set (match_operand:DI 0 "register_operand" "=r,b")
5801 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5802 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5803 "! TARGET_ARCH64"
5804 "@
5805 #
5806 fand\\t%1, %2, %0"
5807 [(set_attr "type" "ialu,fp")
5808 (set_attr "length" "2,1")])
5809
5810 (define_insn "*anddi3_sp64"
5811 [(set (match_operand:DI 0 "register_operand" "=r,b")
5812 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5813 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5814 "TARGET_ARCH64"
5815 "@
5816 and\\t%1, %2, %0
5817 fand\\t%1, %2, %0"
5818 [(set_attr "type" "ialu,fp")
5819 (set_attr "length" "1,1")])
5820
5821 (define_insn "andsi3"
5822 [(set (match_operand:SI 0 "register_operand" "=r,d")
5823 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5824 (match_operand:SI 2 "arith_operand" "rI,d")))]
5825 ""
5826 "@
5827 and\\t%1, %2, %0
5828 fands\\t%1, %2, %0"
5829 [(set_attr "type" "ialu,fp")
5830 (set_attr "length" "1,1")])
5831
5832 (define_split
5833 [(set (match_operand:SI 0 "register_operand" "")
5834 (and:SI (match_operand:SI 1 "register_operand" "")
5835 (match_operand:SI 2 "" "")))
5836 (clobber (match_operand:SI 3 "register_operand" ""))]
5837 "GET_CODE (operands[2]) == CONST_INT
5838 && !SMALL_INT32 (operands[2])
5839 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5840 [(set (match_dup 3) (match_dup 4))
5841 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5842 "
5843 {
5844 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5845 }")
5846
5847 ;; Split DImode logical operations requiring two instructions.
5848 (define_split
5849 [(set (match_operand:DI 0 "register_operand" "")
5850 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5851 [(match_operand:DI 2 "register_operand" "")
5852 (match_operand:DI 3 "arith_double_operand" "")]))]
5853 "! TARGET_ARCH64
5854 && reload_completed
5855 && ((GET_CODE (operands[0]) == REG
5856 && REGNO (operands[0]) < 32)
5857 || (GET_CODE (operands[0]) == SUBREG
5858 && GET_CODE (SUBREG_REG (operands[0])) == REG
5859 && REGNO (SUBREG_REG (operands[0])) < 32))"
5860 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5861 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5862 "
5863 {
5864 if (GET_CODE (operands[0]) == SUBREG)
5865 operands[0] = alter_subreg (operands[0]);
5866 operands[4] = gen_highpart (SImode, operands[0]);
5867 operands[5] = gen_lowpart (SImode, operands[0]);
5868 operands[6] = gen_highpart (SImode, operands[2]);
5869 operands[7] = gen_lowpart (SImode, operands[2]);
5870 if (GET_CODE (operands[3]) == CONST_INT)
5871 {
5872 if (INTVAL (operands[3]) < 0)
5873 operands[8] = constm1_rtx;
5874 else
5875 operands[8] = const0_rtx;
5876 }
5877 else
5878 operands[8] = gen_highpart (SImode, operands[3]);
5879 operands[9] = gen_lowpart (SImode, operands[3]);
5880 }")
5881
5882 (define_insn "*and_not_di_sp32"
5883 [(set (match_operand:DI 0 "register_operand" "=r,b")
5884 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5885 (match_operand:DI 2 "register_operand" "r,b")))]
5886 "! TARGET_ARCH64"
5887 "@
5888 #
5889 fandnot1\\t%1, %2, %0"
5890 [(set_attr "type" "ialu,fp")
5891 (set_attr "length" "2,1")])
5892
5893 (define_split
5894 [(set (match_operand:DI 0 "register_operand" "")
5895 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5896 (match_operand:DI 2 "register_operand" "")))]
5897 "! TARGET_ARCH64
5898 && reload_completed
5899 && ((GET_CODE (operands[0]) == REG
5900 && REGNO (operands[0]) < 32)
5901 || (GET_CODE (operands[0]) == SUBREG
5902 && GET_CODE (SUBREG_REG (operands[0])) == REG
5903 && REGNO (SUBREG_REG (operands[0])) < 32))"
5904 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5905 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5906 "if (GET_CODE (operands[0]) == SUBREG)
5907 operands[0] = alter_subreg (operands[0]);
5908 operands[3] = gen_highpart (SImode, operands[0]);
5909 operands[4] = gen_highpart (SImode, operands[1]);
5910 operands[5] = gen_highpart (SImode, operands[2]);
5911 operands[6] = gen_lowpart (SImode, operands[0]);
5912 operands[7] = gen_lowpart (SImode, operands[1]);
5913 operands[8] = gen_lowpart (SImode, operands[2]);")
5914
5915 (define_insn "*and_not_di_sp64"
5916 [(set (match_operand:DI 0 "register_operand" "=r,b")
5917 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5918 (match_operand:DI 2 "register_operand" "r,b")))]
5919 "TARGET_ARCH64"
5920 "@
5921 andn\\t%2, %1, %0
5922 fandnot1\\t%1, %2, %0"
5923 [(set_attr "type" "ialu,fp")
5924 (set_attr "length" "1,1")])
5925
5926 (define_insn "*and_not_si"
5927 [(set (match_operand:SI 0 "register_operand" "=r,d")
5928 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5929 (match_operand:SI 2 "register_operand" "r,d")))]
5930 ""
5931 "@
5932 andn\\t%2, %1, %0
5933 fandnot1s\\t%1, %2, %0"
5934 [(set_attr "type" "ialu,fp")
5935 (set_attr "length" "1,1")])
5936
5937 (define_expand "iordi3"
5938 [(set (match_operand:DI 0 "register_operand" "")
5939 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5940 (match_operand:DI 2 "arith_double_operand" "")))]
5941 ""
5942 "")
5943
5944 (define_insn "*iordi3_sp32"
5945 [(set (match_operand:DI 0 "register_operand" "=r,b")
5946 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5947 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5948 "! TARGET_ARCH64"
5949 "@
5950 #
5951 for\\t%1, %2, %0"
5952 [(set_attr "type" "ialu,fp")
5953 (set_attr "length" "2,1")])
5954
5955 (define_insn "*iordi3_sp64"
5956 [(set (match_operand:DI 0 "register_operand" "=r,b")
5957 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5958 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5959 "TARGET_ARCH64"
5960 "@
5961 or\\t%1, %2, %0
5962 for\\t%1, %2, %0"
5963 [(set_attr "type" "ialu,fp")
5964 (set_attr "length" "1,1")])
5965
5966 (define_insn "iorsi3"
5967 [(set (match_operand:SI 0 "register_operand" "=r,d")
5968 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
5969 (match_operand:SI 2 "arith_operand" "rI,d")))]
5970 ""
5971 "@
5972 or\\t%1, %2, %0
5973 fors\\t%1, %2, %0"
5974 [(set_attr "type" "ialu,fp")
5975 (set_attr "length" "1,1")])
5976
5977 (define_split
5978 [(set (match_operand:SI 0 "register_operand" "")
5979 (ior:SI (match_operand:SI 1 "register_operand" "")
5980 (match_operand:SI 2 "" "")))
5981 (clobber (match_operand:SI 3 "register_operand" ""))]
5982 "GET_CODE (operands[2]) == CONST_INT
5983 && !SMALL_INT32 (operands[2])
5984 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5985 [(set (match_dup 3) (match_dup 4))
5986 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5987 "
5988 {
5989 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5990 }")
5991
5992 (define_insn "*or_not_di_sp32"
5993 [(set (match_operand:DI 0 "register_operand" "=r,b")
5994 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5995 (match_operand:DI 2 "register_operand" "r,b")))]
5996 "! TARGET_ARCH64"
5997 "@
5998 #
5999 fornot1\\t%1, %2, %0"
6000 [(set_attr "type" "ialu,fp")
6001 (set_attr "length" "2,1")])
6002
6003 (define_split
6004 [(set (match_operand:DI 0 "register_operand" "")
6005 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6006 (match_operand:DI 2 "register_operand" "")))]
6007 "! TARGET_ARCH64
6008 && reload_completed
6009 && ((GET_CODE (operands[0]) == REG
6010 && REGNO (operands[0]) < 32)
6011 || (GET_CODE (operands[0]) == SUBREG
6012 && GET_CODE (SUBREG_REG (operands[0])) == REG
6013 && REGNO (SUBREG_REG (operands[0])) < 32))"
6014 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6015 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6016 "if (GET_CODE (operands[0]) == SUBREG)
6017 operands[0] = alter_subreg (operands[0]);
6018 operands[3] = gen_highpart (SImode, operands[0]);
6019 operands[4] = gen_highpart (SImode, operands[1]);
6020 operands[5] = gen_highpart (SImode, operands[2]);
6021 operands[6] = gen_lowpart (SImode, operands[0]);
6022 operands[7] = gen_lowpart (SImode, operands[1]);
6023 operands[8] = gen_lowpart (SImode, operands[2]);")
6024
6025 (define_insn "*or_not_di_sp64"
6026 [(set (match_operand:DI 0 "register_operand" "=r,b")
6027 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6028 (match_operand:DI 2 "register_operand" "r,b")))]
6029 "TARGET_ARCH64"
6030 "@
6031 orn\\t%2, %1, %0
6032 fornot1\\t%1, %2, %0"
6033 [(set_attr "type" "ialu,fp")
6034 (set_attr "length" "1,1")])
6035
6036 (define_insn "*or_not_si"
6037 [(set (match_operand:SI 0 "register_operand" "=r,d")
6038 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6039 (match_operand:SI 2 "register_operand" "r,d")))]
6040 ""
6041 "@
6042 orn\\t%2, %1, %0
6043 fornot1s\\t%1, %2, %0"
6044 [(set_attr "type" "ialu,fp")
6045 (set_attr "length" "1,1")])
6046
6047 (define_expand "xordi3"
6048 [(set (match_operand:DI 0 "register_operand" "")
6049 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6050 (match_operand:DI 2 "arith_double_operand" "")))]
6051 ""
6052 "")
6053
6054 (define_insn "*xordi3_sp32"
6055 [(set (match_operand:DI 0 "register_operand" "=r,b")
6056 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6057 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6058 "! TARGET_ARCH64"
6059 "@
6060 #
6061 fxor\\t%1, %2, %0"
6062 [(set_attr "length" "2,1")
6063 (set_attr "type" "ialu,fp")])
6064
6065 (define_insn "*xordi3_sp64"
6066 [(set (match_operand:DI 0 "register_operand" "=r,b")
6067 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6068 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6069 "TARGET_ARCH64"
6070 "@
6071 xor\\t%r1, %2, %0
6072 fxor\\t%1, %2, %0"
6073 [(set_attr "type" "ialu,fp")
6074 (set_attr "length" "1,1")])
6075
6076 (define_insn "*xordi3_sp64_dbl"
6077 [(set (match_operand:DI 0 "register_operand" "=r")
6078 (xor:DI (match_operand:DI 1 "register_operand" "r")
6079 (match_operand:DI 2 "const64_operand" "")))]
6080 "(TARGET_ARCH64
6081 && HOST_BITS_PER_WIDE_INT != 64)"
6082 "xor\\t%1, %2, %0"
6083 [(set_attr "type" "ialu")
6084 (set_attr "length" "1")])
6085
6086 (define_insn "xorsi3"
6087 [(set (match_operand:SI 0 "register_operand" "=r,d")
6088 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6089 (match_operand:SI 2 "arith_operand" "rI,d")))]
6090 ""
6091 "@
6092 xor\\t%r1, %2, %0
6093 fxors\\t%1, %2, %0"
6094 [(set_attr "type" "ialu,fp")
6095 (set_attr "length" "1,1")])
6096
6097 (define_split
6098 [(set (match_operand:SI 0 "register_operand" "")
6099 (xor:SI (match_operand:SI 1 "register_operand" "")
6100 (match_operand:SI 2 "" "")))
6101 (clobber (match_operand:SI 3 "register_operand" ""))]
6102 "GET_CODE (operands[2]) == CONST_INT
6103 && !SMALL_INT32 (operands[2])
6104 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6105 [(set (match_dup 3) (match_dup 4))
6106 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6107 "
6108 {
6109 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6110 }")
6111
6112 (define_split
6113 [(set (match_operand:SI 0 "register_operand" "")
6114 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6115 (match_operand:SI 2 "" ""))))
6116 (clobber (match_operand:SI 3 "register_operand" ""))]
6117 "GET_CODE (operands[2]) == CONST_INT
6118 && !SMALL_INT32 (operands[2])
6119 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6120 [(set (match_dup 3) (match_dup 4))
6121 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6122 "
6123 {
6124 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6125 }")
6126
6127 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6128 ;; Combine now canonicalizes to the rightmost expression.
6129 (define_insn "*xor_not_di_sp32"
6130 [(set (match_operand:DI 0 "register_operand" "=r,b")
6131 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6132 (match_operand:DI 2 "register_operand" "r,b"))))]
6133 "! TARGET_ARCH64"
6134 "@
6135 #
6136 fxnor\\t%1, %2, %0"
6137 [(set_attr "length" "2,1")
6138 (set_attr "type" "ialu,fp")])
6139
6140 (define_split
6141 [(set (match_operand:DI 0 "register_operand" "")
6142 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6143 (match_operand:DI 2 "register_operand" ""))))]
6144 "! TARGET_ARCH64
6145 && reload_completed
6146 && ((GET_CODE (operands[0]) == REG
6147 && REGNO (operands[0]) < 32)
6148 || (GET_CODE (operands[0]) == SUBREG
6149 && GET_CODE (SUBREG_REG (operands[0])) == REG
6150 && REGNO (SUBREG_REG (operands[0])) < 32))"
6151 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6152 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6153 "if (GET_CODE (operands[0]) == SUBREG)
6154 operands[0] = alter_subreg (operands[0]);
6155 operands[3] = gen_highpart (SImode, operands[0]);
6156 operands[4] = gen_highpart (SImode, operands[1]);
6157 operands[5] = gen_highpart (SImode, operands[2]);
6158 operands[6] = gen_lowpart (SImode, operands[0]);
6159 operands[7] = gen_lowpart (SImode, operands[1]);
6160 operands[8] = gen_lowpart (SImode, operands[2]);")
6161
6162 (define_insn "*xor_not_di_sp64"
6163 [(set (match_operand:DI 0 "register_operand" "=r,b")
6164 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6165 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6166 "TARGET_ARCH64"
6167 "@
6168 xnor\\t%r1, %2, %0
6169 fxnor\\t%1, %2, %0"
6170 [(set_attr "type" "ialu,fp")
6171 (set_attr "length" "1,1")])
6172
6173 (define_insn "*xor_not_si"
6174 [(set (match_operand:SI 0 "register_operand" "=r,d")
6175 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6176 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6177 ""
6178 "@
6179 xnor\\t%r1, %2, %0
6180 fxnors\\t%1, %2, %0"
6181 [(set_attr "type" "ialu,fp")
6182 (set_attr "length" "1,1")])
6183
6184 ;; These correspond to the above in the case where we also (or only)
6185 ;; want to set the condition code.
6186
6187 (define_insn "*cmp_cc_arith_op"
6188 [(set (reg:CC 100)
6189 (compare:CC
6190 (match_operator:SI 2 "cc_arithop"
6191 [(match_operand:SI 0 "arith_operand" "%r")
6192 (match_operand:SI 1 "arith_operand" "rI")])
6193 (const_int 0)))]
6194 "! TARGET_LIVE_G0"
6195 "%A2cc\\t%0, %1, %%g0"
6196 [(set_attr "type" "compare")
6197 (set_attr "length" "1")])
6198
6199 (define_insn "*cmp_ccx_arith_op"
6200 [(set (reg:CCX 100)
6201 (compare:CCX
6202 (match_operator:DI 2 "cc_arithop"
6203 [(match_operand:DI 0 "arith_double_operand" "%r")
6204 (match_operand:DI 1 "arith_double_operand" "rHI")])
6205 (const_int 0)))]
6206 "TARGET_ARCH64"
6207 "%A2cc\\t%0, %1, %%g0"
6208 [(set_attr "type" "compare")
6209 (set_attr "length" "1")])
6210
6211 (define_insn "*cmp_cc_arith_op_set"
6212 [(set (reg:CC 100)
6213 (compare:CC
6214 (match_operator:SI 3 "cc_arithop"
6215 [(match_operand:SI 1 "arith_operand" "%r")
6216 (match_operand:SI 2 "arith_operand" "rI")])
6217 (const_int 0)))
6218 (set (match_operand:SI 0 "register_operand" "=r")
6219 (match_dup 3))]
6220 ""
6221 "%A3cc\\t%1, %2, %0"
6222 [(set_attr "type" "compare")
6223 (set_attr "length" "1")])
6224
6225 (define_insn "*cmp_ccx_arith_op_set"
6226 [(set (reg:CCX 100)
6227 (compare:CCX
6228 (match_operator:DI 3 "cc_arithop"
6229 [(match_operand:DI 1 "arith_double_operand" "%r")
6230 (match_operand:DI 2 "arith_double_operand" "rHI")])
6231 (const_int 0)))
6232 (set (match_operand:DI 0 "register_operand" "=r")
6233 (match_dup 3))]
6234 "TARGET_ARCH64"
6235 "%A3cc\\t%1, %2, %0"
6236 [(set_attr "type" "compare")
6237 (set_attr "length" "1")])
6238
6239 (define_insn "*cmp_cc_xor_not"
6240 [(set (reg:CC 100)
6241 (compare:CC
6242 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6243 (match_operand:SI 1 "arith_operand" "rI")))
6244 (const_int 0)))]
6245 "! TARGET_LIVE_G0"
6246 "xnorcc\\t%r0, %1, %%g0"
6247 [(set_attr "type" "compare")
6248 (set_attr "length" "1")])
6249
6250 (define_insn "*cmp_ccx_xor_not"
6251 [(set (reg:CCX 100)
6252 (compare:CCX
6253 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6254 (match_operand:DI 1 "arith_double_operand" "rHI")))
6255 (const_int 0)))]
6256 "TARGET_ARCH64"
6257 "xnorcc\\t%r0, %1, %%g0"
6258 [(set_attr "type" "compare")
6259 (set_attr "length" "1")])
6260
6261 (define_insn "*cmp_cc_xor_not_set"
6262 [(set (reg:CC 100)
6263 (compare:CC
6264 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6265 (match_operand:SI 2 "arith_operand" "rI")))
6266 (const_int 0)))
6267 (set (match_operand:SI 0 "register_operand" "=r")
6268 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6269 ""
6270 "xnorcc\\t%r1, %2, %0"
6271 [(set_attr "type" "compare")
6272 (set_attr "length" "1")])
6273
6274 (define_insn "*cmp_ccx_xor_not_set"
6275 [(set (reg:CCX 100)
6276 (compare:CCX
6277 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6278 (match_operand:DI 2 "arith_double_operand" "rHI")))
6279 (const_int 0)))
6280 (set (match_operand:DI 0 "register_operand" "=r")
6281 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6282 "TARGET_ARCH64"
6283 "xnorcc\\t%r1, %2, %0"
6284 [(set_attr "type" "compare")
6285 (set_attr "length" "1")])
6286
6287 (define_insn "*cmp_cc_arith_op_not"
6288 [(set (reg:CC 100)
6289 (compare:CC
6290 (match_operator:SI 2 "cc_arithopn"
6291 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6292 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6293 (const_int 0)))]
6294 "! TARGET_LIVE_G0"
6295 "%B2cc\\t%r1, %0, %%g0"
6296 [(set_attr "type" "compare")
6297 (set_attr "length" "1")])
6298
6299 (define_insn "*cmp_ccx_arith_op_not"
6300 [(set (reg:CCX 100)
6301 (compare:CCX
6302 (match_operator:DI 2 "cc_arithopn"
6303 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6304 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6305 (const_int 0)))]
6306 "TARGET_ARCH64"
6307 "%B2cc\\t%r1, %0, %%g0"
6308 [(set_attr "type" "compare")
6309 (set_attr "length" "1")])
6310
6311 (define_insn "*cmp_cc_arith_op_not_set"
6312 [(set (reg:CC 100)
6313 (compare:CC
6314 (match_operator:SI 3 "cc_arithopn"
6315 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6316 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6317 (const_int 0)))
6318 (set (match_operand:SI 0 "register_operand" "=r")
6319 (match_dup 3))]
6320 ""
6321 "%B3cc\\t%r2, %1, %0"
6322 [(set_attr "type" "compare")
6323 (set_attr "length" "1")])
6324
6325 (define_insn "*cmp_ccx_arith_op_not_set"
6326 [(set (reg:CCX 100)
6327 (compare:CCX
6328 (match_operator:DI 3 "cc_arithopn"
6329 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6330 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6331 (const_int 0)))
6332 (set (match_operand:DI 0 "register_operand" "=r")
6333 (match_dup 3))]
6334 "TARGET_ARCH64"
6335 "%B3cc\\t%r2, %1, %0"
6336 [(set_attr "type" "compare")
6337 (set_attr "length" "1")])
6338
6339 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6340 ;; does not know how to make it work for constants.
6341
6342 (define_expand "negdi2"
6343 [(set (match_operand:DI 0 "register_operand" "=r")
6344 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6345 ""
6346 "
6347 {
6348 if (! TARGET_ARCH64)
6349 {
6350 emit_insn (gen_rtx_PARALLEL
6351 (VOIDmode,
6352 gen_rtvec (2,
6353 gen_rtx_SET (VOIDmode, operand0,
6354 gen_rtx_NEG (DImode, operand1)),
6355 gen_rtx_CLOBBER (VOIDmode,
6356 gen_rtx_REG (CCmode,
6357 SPARC_ICC_REG)))));
6358 DONE;
6359 }
6360 }")
6361
6362 (define_insn "*negdi2_sp32"
6363 [(set (match_operand:DI 0 "register_operand" "=r")
6364 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6365 (clobber (reg:CC 100))]
6366 "! TARGET_ARCH64
6367 && ! TARGET_LIVE_G0"
6368 "#"
6369 [(set_attr "type" "unary")
6370 (set_attr "length" "2")])
6371
6372 (define_split
6373 [(set (match_operand:DI 0 "register_operand" "")
6374 (neg:DI (match_operand:DI 1 "register_operand" "")))
6375 (clobber (reg:CC 100))]
6376 "! TARGET_ARCH64
6377 && ! TARGET_LIVE_G0
6378 && reload_completed"
6379 [(parallel [(set (reg:CC_NOOV 100)
6380 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6381 (const_int 0)))
6382 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6383 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6384 (ltu:SI (reg:CC 100) (const_int 0))))]
6385 "operands[2] = gen_highpart (SImode, operands[0]);
6386 operands[3] = gen_highpart (SImode, operands[1]);
6387 operands[4] = gen_lowpart (SImode, operands[0]);
6388 operands[5] = gen_lowpart (SImode, operands[1]);")
6389
6390 (define_insn "*negdi2_sp64"
6391 [(set (match_operand:DI 0 "register_operand" "=r")
6392 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6393 "TARGET_ARCH64"
6394 "sub\\t%%g0, %1, %0"
6395 [(set_attr "type" "unary")
6396 (set_attr "length" "1")])
6397
6398 (define_expand "negsi2"
6399 [(set (match_operand:SI 0 "register_operand" "")
6400 (neg:SI (match_operand:SI 1 "arith_operand" "")))]
6401 ""
6402 "
6403 {
6404 if (TARGET_LIVE_G0)
6405 {
6406 rtx zero_reg = gen_reg_rtx (SImode);
6407
6408 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6409 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6410 gen_rtx_MINUS (SImode, zero_reg,
6411 operands[1])));
6412 DONE;
6413 }
6414 }")
6415
6416 (define_insn "*negsi2_not_liveg0"
6417 [(set (match_operand:SI 0 "register_operand" "=r")
6418 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6419 "! TARGET_LIVE_G0"
6420 "sub\\t%%g0, %1, %0"
6421 [(set_attr "type" "unary")
6422 (set_attr "length" "1")])
6423
6424 (define_insn "*cmp_cc_neg"
6425 [(set (reg:CC_NOOV 100)
6426 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6427 (const_int 0)))]
6428 "! TARGET_LIVE_G0"
6429 "subcc\\t%%g0, %0, %%g0"
6430 [(set_attr "type" "compare")
6431 (set_attr "length" "1")])
6432
6433 (define_insn "*cmp_ccx_neg"
6434 [(set (reg:CCX_NOOV 100)
6435 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6436 (const_int 0)))]
6437 "TARGET_ARCH64"
6438 "subcc\\t%%g0, %0, %%g0"
6439 [(set_attr "type" "compare")
6440 (set_attr "length" "1")])
6441
6442 (define_insn "*cmp_cc_set_neg"
6443 [(set (reg:CC_NOOV 100)
6444 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6445 (const_int 0)))
6446 (set (match_operand:SI 0 "register_operand" "=r")
6447 (neg:SI (match_dup 1)))]
6448 "! TARGET_LIVE_G0"
6449 "subcc\\t%%g0, %1, %0"
6450 [(set_attr "type" "compare")
6451 (set_attr "length" "1")])
6452
6453 (define_insn "*cmp_ccx_set_neg"
6454 [(set (reg:CCX_NOOV 100)
6455 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6456 (const_int 0)))
6457 (set (match_operand:DI 0 "register_operand" "=r")
6458 (neg:DI (match_dup 1)))]
6459 "TARGET_ARCH64"
6460 "subcc\\t%%g0, %1, %0"
6461 [(set_attr "type" "compare")
6462 (set_attr "length" "1")])
6463
6464 ;; We cannot use the "not" pseudo insn because the Sun assembler
6465 ;; does not know how to make it work for constants.
6466 (define_expand "one_cmpldi2"
6467 [(set (match_operand:DI 0 "register_operand" "")
6468 (not:DI (match_operand:DI 1 "register_operand" "")))]
6469 ""
6470 "")
6471
6472 (define_insn "*one_cmpldi2_sp32"
6473 [(set (match_operand:DI 0 "register_operand" "=r,b")
6474 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6475 "! TARGET_ARCH64"
6476 "@
6477 #
6478 fnot1\\t%1, %0"
6479 [(set_attr "type" "unary,fp")
6480 (set_attr "length" "2,1")])
6481
6482 (define_split
6483 [(set (match_operand:DI 0 "register_operand" "")
6484 (not:DI (match_operand:DI 1 "register_operand" "")))]
6485 "! TARGET_ARCH64
6486 && reload_completed
6487 && ((GET_CODE (operands[0]) == REG
6488 && REGNO (operands[0]) < 32)
6489 || (GET_CODE (operands[0]) == SUBREG
6490 && GET_CODE (SUBREG_REG (operands[0])) == REG
6491 && REGNO (SUBREG_REG (operands[0])) < 32))"
6492 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6493 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6494 "if (GET_CODE (operands[0]) == SUBREG)
6495 operands[0] = alter_subreg (operands[0]);
6496 operands[2] = gen_highpart (SImode, operands[0]);
6497 operands[3] = gen_highpart (SImode, operands[1]);
6498 operands[4] = gen_lowpart (SImode, operands[0]);
6499 operands[5] = gen_lowpart (SImode, operands[1]);")
6500
6501 (define_insn "*one_cmpldi2_sp64"
6502 [(set (match_operand:DI 0 "register_operand" "=r,b")
6503 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6504 "TARGET_ARCH64"
6505 "@
6506 xnor\\t%%g0, %1, %0
6507 fnot1\\t%1, %0"
6508 [(set_attr "type" "unary,fp")
6509 (set_attr "length" "1")])
6510
6511 (define_expand "one_cmplsi2"
6512 [(set (match_operand:SI 0 "register_operand" "")
6513 (not:SI (match_operand:SI 1 "arith_operand" "")))]
6514 ""
6515 "
6516 {
6517 if (TARGET_LIVE_G0
6518 && GET_CODE (operands[1]) == CONST_INT)
6519 {
6520 rtx zero_reg = gen_reg_rtx (SImode);
6521
6522 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6523 emit_insn (gen_rtx_SET (VOIDmode,
6524 operands[0],
6525 gen_rtx_NOT (SImode,
6526 gen_rtx_XOR (SImode,
6527 zero_reg,
6528 operands[1]))));
6529 DONE;
6530 }
6531 }")
6532
6533 (define_insn "*one_cmplsi2_not_liveg0"
6534 [(set (match_operand:SI 0 "register_operand" "=r,d")
6535 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6536 "! TARGET_LIVE_G0"
6537 "@
6538 xnor\\t%%g0, %1, %0
6539 fnot1s\\t%1, %0"
6540 [(set_attr "type" "unary,fp")
6541 (set_attr "length" "1,1")])
6542
6543 (define_insn "*one_cmplsi2_liveg0"
6544 [(set (match_operand:SI 0 "register_operand" "=r,d")
6545 (not:SI (match_operand:SI 1 "arith_operand" "r,d")))]
6546 "TARGET_LIVE_G0"
6547 "@
6548 xnor\\t%1, 0, %0
6549 fnot1s\\t%1, %0"
6550 [(set_attr "type" "unary,fp")
6551 (set_attr "length" "1,1")])
6552
6553 (define_insn "*cmp_cc_not"
6554 [(set (reg:CC 100)
6555 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6556 (const_int 0)))]
6557 "! TARGET_LIVE_G0"
6558 "xnorcc\\t%%g0, %0, %%g0"
6559 [(set_attr "type" "compare")
6560 (set_attr "length" "1")])
6561
6562 (define_insn "*cmp_ccx_not"
6563 [(set (reg:CCX 100)
6564 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6565 (const_int 0)))]
6566 "TARGET_ARCH64"
6567 "xnorcc\\t%%g0, %0, %%g0"
6568 [(set_attr "type" "compare")
6569 (set_attr "length" "1")])
6570
6571 (define_insn "*cmp_cc_set_not"
6572 [(set (reg:CC 100)
6573 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6574 (const_int 0)))
6575 (set (match_operand:SI 0 "register_operand" "=r")
6576 (not:SI (match_dup 1)))]
6577 "! TARGET_LIVE_G0"
6578 "xnorcc\\t%%g0, %1, %0"
6579 [(set_attr "type" "compare")
6580 (set_attr "length" "1")])
6581
6582 (define_insn "*cmp_ccx_set_not"
6583 [(set (reg:CCX 100)
6584 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6585 (const_int 0)))
6586 (set (match_operand:DI 0 "register_operand" "=r")
6587 (not:DI (match_dup 1)))]
6588 "TARGET_ARCH64"
6589 "xnorcc\\t%%g0, %1, %0"
6590 [(set_attr "type" "compare")
6591 (set_attr "length" "1")])
6592 \f
6593 ;; Floating point arithmetic instructions.
6594
6595 (define_insn "addtf3"
6596 [(set (match_operand:TF 0 "register_operand" "=e")
6597 (plus:TF (match_operand:TF 1 "register_operand" "e")
6598 (match_operand:TF 2 "register_operand" "e")))]
6599 "TARGET_FPU && TARGET_HARD_QUAD"
6600 "faddq\\t%1, %2, %0"
6601 [(set_attr "type" "fp")
6602 (set_attr "length" "1")])
6603
6604 (define_insn "adddf3"
6605 [(set (match_operand:DF 0 "register_operand" "=e")
6606 (plus:DF (match_operand:DF 1 "register_operand" "e")
6607 (match_operand:DF 2 "register_operand" "e")))]
6608 "TARGET_FPU"
6609 "faddd\\t%1, %2, %0"
6610 [(set_attr "type" "fp")
6611 (set_attr "length" "1")])
6612
6613 (define_insn "addsf3"
6614 [(set (match_operand:SF 0 "register_operand" "=f")
6615 (plus:SF (match_operand:SF 1 "register_operand" "f")
6616 (match_operand:SF 2 "register_operand" "f")))]
6617 "TARGET_FPU"
6618 "fadds\\t%1, %2, %0"
6619 [(set_attr "type" "fp")
6620 (set_attr "length" "1")])
6621
6622 (define_insn "subtf3"
6623 [(set (match_operand:TF 0 "register_operand" "=e")
6624 (minus:TF (match_operand:TF 1 "register_operand" "e")
6625 (match_operand:TF 2 "register_operand" "e")))]
6626 "TARGET_FPU && TARGET_HARD_QUAD"
6627 "fsubq\\t%1, %2, %0"
6628 [(set_attr "type" "fp")
6629 (set_attr "length" "1")])
6630
6631 (define_insn "subdf3"
6632 [(set (match_operand:DF 0 "register_operand" "=e")
6633 (minus:DF (match_operand:DF 1 "register_operand" "e")
6634 (match_operand:DF 2 "register_operand" "e")))]
6635 "TARGET_FPU"
6636 "fsubd\\t%1, %2, %0"
6637 [(set_attr "type" "fp")
6638 (set_attr "length" "1")])
6639
6640 (define_insn "subsf3"
6641 [(set (match_operand:SF 0 "register_operand" "=f")
6642 (minus:SF (match_operand:SF 1 "register_operand" "f")
6643 (match_operand:SF 2 "register_operand" "f")))]
6644 "TARGET_FPU"
6645 "fsubs\\t%1, %2, %0"
6646 [(set_attr "type" "fp")
6647 (set_attr "length" "1")])
6648
6649 (define_insn "multf3"
6650 [(set (match_operand:TF 0 "register_operand" "=e")
6651 (mult:TF (match_operand:TF 1 "register_operand" "e")
6652 (match_operand:TF 2 "register_operand" "e")))]
6653 "TARGET_FPU && TARGET_HARD_QUAD"
6654 "fmulq\\t%1, %2, %0"
6655 [(set_attr "type" "fpmul")
6656 (set_attr "length" "1")])
6657
6658 (define_insn "muldf3"
6659 [(set (match_operand:DF 0 "register_operand" "=e")
6660 (mult:DF (match_operand:DF 1 "register_operand" "e")
6661 (match_operand:DF 2 "register_operand" "e")))]
6662 "TARGET_FPU"
6663 "fmuld\\t%1, %2, %0"
6664 [(set_attr "type" "fpmul")
6665 (set_attr "length" "1")])
6666
6667 (define_insn "mulsf3"
6668 [(set (match_operand:SF 0 "register_operand" "=f")
6669 (mult:SF (match_operand:SF 1 "register_operand" "f")
6670 (match_operand:SF 2 "register_operand" "f")))]
6671 "TARGET_FPU"
6672 "fmuls\\t%1, %2, %0"
6673 [(set_attr "type" "fpmul")
6674 (set_attr "length" "1")])
6675
6676 (define_insn "*muldf3_extend"
6677 [(set (match_operand:DF 0 "register_operand" "=e")
6678 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6679 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6680 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6681 "fsmuld\\t%1, %2, %0"
6682 [(set_attr "type" "fpmul")
6683 (set_attr "length" "1")])
6684
6685 (define_insn "*multf3_extend"
6686 [(set (match_operand:TF 0 "register_operand" "=e")
6687 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6688 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6689 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6690 "fdmulq\\t%1, %2, %0"
6691 [(set_attr "type" "fpmul")
6692 (set_attr "length" "1")])
6693
6694 ;; don't have timing for quad-prec. divide.
6695 (define_insn "divtf3"
6696 [(set (match_operand:TF 0 "register_operand" "=e")
6697 (div:TF (match_operand:TF 1 "register_operand" "e")
6698 (match_operand:TF 2 "register_operand" "e")))]
6699 "TARGET_FPU && TARGET_HARD_QUAD"
6700 "fdivq\\t%1, %2, %0"
6701 [(set_attr "type" "fpdivd")
6702 (set_attr "length" "1")])
6703
6704 (define_insn "divdf3"
6705 [(set (match_operand:DF 0 "register_operand" "=e")
6706 (div:DF (match_operand:DF 1 "register_operand" "e")
6707 (match_operand:DF 2 "register_operand" "e")))]
6708 "TARGET_FPU"
6709 "fdivd\\t%1, %2, %0"
6710 [(set_attr "type" "fpdivd")
6711 (set_attr "length" "1")])
6712
6713 (define_insn "divsf3"
6714 [(set (match_operand:SF 0 "register_operand" "=f")
6715 (div:SF (match_operand:SF 1 "register_operand" "f")
6716 (match_operand:SF 2 "register_operand" "f")))]
6717 "TARGET_FPU"
6718 "fdivs\\t%1, %2, %0"
6719 [(set_attr "type" "fpdivs")
6720 (set_attr "length" "1")])
6721
6722 (define_expand "negtf2"
6723 [(set (match_operand:TF 0 "register_operand" "=e,e")
6724 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6725 "TARGET_FPU"
6726 "")
6727
6728 (define_insn "*negtf2_notv9"
6729 [(set (match_operand:TF 0 "register_operand" "=e,e")
6730 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6731 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6732 "TARGET_FPU
6733 && ! TARGET_V9"
6734 "@
6735 fnegs\\t%0, %0
6736 #"
6737 [(set_attr "type" "fpmove")
6738 (set_attr "length" "1,2")])
6739
6740 (define_split
6741 [(set (match_operand:TF 0 "register_operand" "")
6742 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6743 "TARGET_FPU
6744 && ! TARGET_V9
6745 && reload_completed
6746 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6747 [(set (match_dup 2) (neg:SF (match_dup 3)))
6748 (set (match_dup 4) (match_dup 5))
6749 (set (match_dup 6) (match_dup 7))]
6750 "if (GET_CODE (operands[0]) == SUBREG)
6751 operands[0] = alter_subreg (operands[0]);
6752 if (GET_CODE (operands[1]) == SUBREG)
6753 operands[1] = alter_subreg (operands[1]);
6754 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6755 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6756 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6757 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6758 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6759 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6760
6761 (define_insn "*negtf2_v9"
6762 [(set (match_operand:TF 0 "register_operand" "=e,e")
6763 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6764 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6765 "TARGET_FPU && TARGET_V9"
6766 "@
6767 fnegd\\t%0, %0
6768 #"
6769 [(set_attr "type" "fpmove")
6770 (set_attr "length" "1,2")])
6771
6772 (define_split
6773 [(set (match_operand:TF 0 "register_operand" "")
6774 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6775 "TARGET_FPU
6776 && TARGET_V9
6777 && reload_completed
6778 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6779 [(set (match_dup 2) (neg:DF (match_dup 3)))
6780 (set (match_dup 4) (match_dup 5))]
6781 "if (GET_CODE (operands[0]) == SUBREG)
6782 operands[0] = alter_subreg (operands[0]);
6783 if (GET_CODE (operands[1]) == SUBREG)
6784 operands[1] = alter_subreg (operands[1]);
6785 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6786 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6787 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6788 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6789
6790 (define_expand "negdf2"
6791 [(set (match_operand:DF 0 "register_operand" "")
6792 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6793 "TARGET_FPU"
6794 "")
6795
6796 (define_insn "*negdf2_notv9"
6797 [(set (match_operand:DF 0 "register_operand" "=e,e")
6798 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6799 "TARGET_FPU && ! TARGET_V9"
6800 "@
6801 fnegs\\t%0, %0
6802 #"
6803 [(set_attr "type" "fpmove")
6804 (set_attr "length" "1,2")])
6805
6806 (define_split
6807 [(set (match_operand:DF 0 "register_operand" "")
6808 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6809 "TARGET_FPU
6810 && ! TARGET_V9
6811 && reload_completed
6812 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6813 [(set (match_dup 2) (neg:SF (match_dup 3)))
6814 (set (match_dup 4) (match_dup 5))]
6815 "if (GET_CODE (operands[0]) == SUBREG)
6816 operands[0] = alter_subreg (operands[0]);
6817 if (GET_CODE (operands[1]) == SUBREG)
6818 operands[1] = alter_subreg (operands[1]);
6819 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6820 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6821 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6822 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6823
6824 (define_insn "*negdf2_v9"
6825 [(set (match_operand:DF 0 "register_operand" "=e")
6826 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6827 "TARGET_FPU && TARGET_V9"
6828 "fnegd\\t%1, %0"
6829 [(set_attr "type" "fpmove")
6830 (set_attr "length" "1")])
6831
6832 (define_insn "negsf2"
6833 [(set (match_operand:SF 0 "register_operand" "=f")
6834 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6835 "TARGET_FPU"
6836 "fnegs\\t%1, %0"
6837 [(set_attr "type" "fpmove")
6838 (set_attr "length" "1")])
6839
6840 (define_expand "abstf2"
6841 [(set (match_operand:TF 0 "register_operand" "")
6842 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6843 "TARGET_FPU"
6844 "")
6845
6846 (define_insn "*abstf2_notv9"
6847 [(set (match_operand:TF 0 "register_operand" "=e,e")
6848 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6849 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6850 "TARGET_FPU && ! TARGET_V9"
6851 "@
6852 fabss\\t%0, %0
6853 #"
6854 [(set_attr "type" "fpmove")
6855 (set_attr "length" "1,2")])
6856
6857 (define_split
6858 [(set (match_operand:TF 0 "register_operand" "=e,e")
6859 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6860 "TARGET_FPU
6861 && ! TARGET_V9
6862 && reload_completed
6863 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6864 [(set (match_dup 2) (abs:SF (match_dup 3)))
6865 (set (match_dup 4) (match_dup 5))
6866 (set (match_dup 6) (match_dup 7))]
6867 "if (GET_CODE (operands[0]) == SUBREG)
6868 operands[0] = alter_subreg (operands[0]);
6869 if (GET_CODE (operands[1]) == SUBREG)
6870 operands[1] = alter_subreg (operands[1]);
6871 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6872 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6873 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6874 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6875 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6876 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6877
6878 (define_insn "*abstf2_hq_v9"
6879 [(set (match_operand:TF 0 "register_operand" "=e,e")
6880 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6881 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6882 "@
6883 fabsd\\t%0, %0
6884 fabsq\\t%1, %0"
6885 [(set_attr "type" "fpmove")
6886 (set_attr "length" "1")])
6887
6888 (define_insn "*abstf2_v9"
6889 [(set (match_operand:TF 0 "register_operand" "=e,e")
6890 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6891 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6892 "@
6893 fabsd\\t%0, %0
6894 #"
6895 [(set_attr "type" "fpmove")
6896 (set_attr "length" "1,2")])
6897
6898 (define_split
6899 [(set (match_operand:TF 0 "register_operand" "=e,e")
6900 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6901 "TARGET_FPU
6902 && TARGET_V9
6903 && reload_completed
6904 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6905 [(set (match_dup 2) (abs:DF (match_dup 3)))
6906 (set (match_dup 4) (match_dup 5))]
6907 "if (GET_CODE (operands[0]) == SUBREG)
6908 operands[0] = alter_subreg (operands[0]);
6909 if (GET_CODE (operands[1]) == SUBREG)
6910 operands[1] = alter_subreg (operands[1]);
6911 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6912 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6913 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6914 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6915
6916 (define_expand "absdf2"
6917 [(set (match_operand:DF 0 "register_operand" "")
6918 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6919 "TARGET_FPU"
6920 "")
6921
6922 (define_insn "*absdf2_notv9"
6923 [(set (match_operand:DF 0 "register_operand" "=e,e")
6924 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6925 "TARGET_FPU && ! TARGET_V9"
6926 "@
6927 fabss\\t%0, %0
6928 #"
6929 [(set_attr "type" "fpmove")
6930 (set_attr "length" "1,2")])
6931
6932 (define_split
6933 [(set (match_operand:DF 0 "register_operand" "=e,e")
6934 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6935 "TARGET_FPU
6936 && ! TARGET_V9
6937 && reload_completed
6938 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6939 [(set (match_dup 2) (abs:SF (match_dup 3)))
6940 (set (match_dup 4) (match_dup 5))]
6941 "if (GET_CODE (operands[0]) == SUBREG)
6942 operands[0] = alter_subreg (operands[0]);
6943 if (GET_CODE (operands[1]) == SUBREG)
6944 operands[1] = alter_subreg (operands[1]);
6945 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6946 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6947 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6948 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6949
6950 (define_insn "*absdf2_v9"
6951 [(set (match_operand:DF 0 "register_operand" "=e")
6952 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6953 "TARGET_FPU && TARGET_V9"
6954 "fabsd\\t%1, %0"
6955 [(set_attr "type" "fpmove")
6956 (set_attr "length" "1")])
6957
6958 (define_insn "abssf2"
6959 [(set (match_operand:SF 0 "register_operand" "=f")
6960 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6961 "TARGET_FPU"
6962 "fabss\\t%1, %0"
6963 [(set_attr "type" "fpmove")
6964 (set_attr "length" "1")])
6965
6966 (define_insn "sqrttf2"
6967 [(set (match_operand:TF 0 "register_operand" "=e")
6968 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6969 "TARGET_FPU && TARGET_HARD_QUAD"
6970 "fsqrtq\\t%1, %0"
6971 [(set_attr "type" "fpsqrtd")
6972 (set_attr "length" "1")])
6973
6974 (define_insn "sqrtdf2"
6975 [(set (match_operand:DF 0 "register_operand" "=e")
6976 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6977 "TARGET_FPU"
6978 "fsqrtd\\t%1, %0"
6979 [(set_attr "type" "fpsqrtd")
6980 (set_attr "length" "1")])
6981
6982 (define_insn "sqrtsf2"
6983 [(set (match_operand:SF 0 "register_operand" "=f")
6984 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6985 "TARGET_FPU"
6986 "fsqrts\\t%1, %0"
6987 [(set_attr "type" "fpsqrts")
6988 (set_attr "length" "1")])
6989 \f
6990 ;;- arithmetic shift instructions
6991
6992 (define_insn "ashlsi3"
6993 [(set (match_operand:SI 0 "register_operand" "=r")
6994 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6995 (match_operand:SI 2 "arith_operand" "rI")))]
6996 ""
6997 "*
6998 {
6999 if (GET_CODE (operands[2]) == CONST_INT
7000 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7001 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7002
7003 return \"sll\\t%1, %2, %0\";
7004 }"
7005 [(set_attr "type" "shift")
7006 (set_attr "length" "1")])
7007
7008 ;; We special case multiplication by two, as add can be done
7009 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7010 (define_insn "*ashlsi3_const1"
7011 [(set (match_operand:SI 0 "register_operand" "=r")
7012 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7013 (const_int 1)))]
7014 ""
7015 "add\\t%1, %1, %0"
7016 [(set_attr "type" "binary")
7017 (set_attr "length" "1")])
7018
7019 (define_expand "ashldi3"
7020 [(set (match_operand:DI 0 "register_operand" "=r")
7021 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7022 (match_operand:SI 2 "arith_operand" "rI")))]
7023 "TARGET_ARCH64 || TARGET_V8PLUS"
7024 "
7025 {
7026 if (! TARGET_ARCH64)
7027 {
7028 if (GET_CODE (operands[2]) == CONST_INT)
7029 FAIL;
7030 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7031 DONE;
7032 }
7033 }")
7034
7035 ;; We special case multiplication by two, as add can be done
7036 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7037 (define_insn "*ashldi3_const1"
7038 [(set (match_operand:DI 0 "register_operand" "=r")
7039 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7040 (const_int 1)))]
7041 "TARGET_ARCH64"
7042 "add\\t%1, %1, %0"
7043 [(set_attr "type" "binary")
7044 (set_attr "length" "1")])
7045
7046 (define_insn "*ashldi3_sp64"
7047 [(set (match_operand:DI 0 "register_operand" "=r")
7048 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7049 (match_operand:SI 2 "arith_operand" "rI")))]
7050 "TARGET_ARCH64"
7051 "*
7052 {
7053 if (GET_CODE (operands[2]) == CONST_INT
7054 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7055 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7056
7057 return \"sllx\\t%1, %2, %0\";
7058 }"
7059 [(set_attr "type" "shift")
7060 (set_attr "length" "1")])
7061
7062 ;; XXX UGH!
7063 (define_insn "ashldi3_v8plus"
7064 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7065 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7066 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7067 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7068 "TARGET_V8PLUS"
7069 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7070 [(set_attr "length" "5,5,6")])
7071
7072 ;; Optimize (1LL<<x)-1
7073 ;; XXX this also needs to be fixed to handle equal subregs
7074 ;; XXX first before we could re-enable it.
7075 (define_insn ""
7076 [(set (match_operand:DI 0 "register_operand" "=h")
7077 (plus:DI (ashift:DI (const_int 1)
7078 (match_operand:SI 2 "arith_operand" "rI"))
7079 (const_int -1)))]
7080 "0 && TARGET_V8PLUS"
7081 "*
7082 {
7083 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
7084 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7085 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7086 }"
7087 [(set_attr "length" "4")])
7088
7089 (define_insn "*cmp_cc_ashift_1"
7090 [(set (reg:CC_NOOV 100)
7091 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7092 (const_int 1))
7093 (const_int 0)))]
7094 "! TARGET_LIVE_G0"
7095 "addcc\\t%0, %0, %%g0"
7096 [(set_attr "type" "compare")
7097 (set_attr "length" "1")])
7098
7099 (define_insn "*cmp_cc_set_ashift_1"
7100 [(set (reg:CC_NOOV 100)
7101 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7102 (const_int 1))
7103 (const_int 0)))
7104 (set (match_operand:SI 0 "register_operand" "=r")
7105 (ashift:SI (match_dup 1) (const_int 1)))]
7106 ""
7107 "addcc\\t%1, %1, %0"
7108 [(set_attr "type" "compare")
7109 (set_attr "length" "1")])
7110
7111 (define_insn "ashrsi3"
7112 [(set (match_operand:SI 0 "register_operand" "=r")
7113 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7114 (match_operand:SI 2 "arith_operand" "rI")))]
7115 ""
7116 "*
7117 {
7118 if (GET_CODE (operands[2]) == CONST_INT
7119 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7120 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7121
7122 return \"sra\\t%1, %2, %0\";
7123 }"
7124 [(set_attr "type" "shift")
7125 (set_attr "length" "1")])
7126
7127 (define_insn "*ashrsi3_extend"
7128 [(set (match_operand:DI 0 "register_operand" "=r")
7129 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7130 (match_operand:SI 2 "arith_operand" "r"))))]
7131 "TARGET_ARCH64"
7132 "sra\\t%1, %2, %0"
7133 [(set_attr "type" "shift")
7134 (set_attr "length" "1")])
7135
7136 ;; This handles the case as above, but with constant shift instead of
7137 ;; register. Combiner "simplifies" it for us a little bit though.
7138 (define_insn "*ashrsi3_extend2"
7139 [(set (match_operand:DI 0 "register_operand" "=r")
7140 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7141 (const_int 32))
7142 (match_operand:SI 2 "small_int_or_double" "n")))]
7143 "TARGET_ARCH64
7144 && ((GET_CODE (operands[2]) == CONST_INT
7145 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7146 || (GET_CODE (operands[2]) == CONST_DOUBLE
7147 && !CONST_DOUBLE_HIGH (operands[2])
7148 && CONST_DOUBLE_LOW (operands[2]) >= 32
7149 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7150 "*
7151 {
7152 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7153
7154 return \"sra\\t%1, %2, %0\";
7155 }"
7156 [(set_attr "type" "shift")
7157 (set_attr "length" "1")])
7158
7159 (define_expand "ashrdi3"
7160 [(set (match_operand:DI 0 "register_operand" "=r")
7161 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7162 (match_operand:SI 2 "arith_operand" "rI")))]
7163 "TARGET_ARCH64 || TARGET_V8PLUS"
7164 "
7165 {
7166 if (! TARGET_ARCH64)
7167 {
7168 if (GET_CODE (operands[2]) == CONST_INT)
7169 FAIL; /* prefer generic code in this case */
7170 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7171 DONE;
7172 }
7173 }")
7174
7175 (define_insn ""
7176 [(set (match_operand:DI 0 "register_operand" "=r")
7177 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7178 (match_operand:SI 2 "arith_operand" "rI")))]
7179 "TARGET_ARCH64"
7180 "*
7181 {
7182 if (GET_CODE (operands[2]) == CONST_INT
7183 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7184 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7185
7186 return \"srax\\t%1, %2, %0\";
7187 }"
7188 [(set_attr "type" "shift")
7189 (set_attr "length" "1")])
7190
7191 ;; XXX
7192 (define_insn "ashrdi3_v8plus"
7193 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7194 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7195 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7196 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7197 "TARGET_V8PLUS"
7198 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7199 [(set_attr "length" "5,5,6")])
7200
7201 (define_insn "lshrsi3"
7202 [(set (match_operand:SI 0 "register_operand" "=r")
7203 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7204 (match_operand:SI 2 "arith_operand" "rI")))]
7205 ""
7206 "*
7207 {
7208 if (GET_CODE (operands[2]) == CONST_INT
7209 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7210 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7211
7212 return \"srl\\t%1, %2, %0\";
7213 }"
7214 [(set_attr "type" "shift")
7215 (set_attr "length" "1")])
7216
7217 ;; This handles the case where
7218 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7219 ;; but combiner "simplifies" it for us.
7220 (define_insn "*lshrsi3_extend"
7221 [(set (match_operand:DI 0 "register_operand" "=r")
7222 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7223 (match_operand:SI 2 "arith_operand" "r")) 0)
7224 (match_operand 3 "" "")))]
7225 "TARGET_ARCH64
7226 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7227 && CONST_DOUBLE_HIGH (operands[3]) == 0
7228 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7229 #if HOST_BITS_PER_WIDE_INT >= 64
7230 || (GET_CODE (operands[3]) == CONST_INT
7231 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
7232 #endif
7233 )"
7234 "srl\\t%1, %2, %0"
7235 [(set_attr "type" "shift")
7236 (set_attr "length" "1")])
7237
7238 ;; This handles the case where
7239 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7240 ;; but combiner "simplifies" it for us.
7241 (define_insn "*lshrsi3_extend2"
7242 [(set (match_operand:DI 0 "register_operand" "=r")
7243 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7244 (match_operand 2 "small_int_or_double" "n")
7245 (const_int 32)))]
7246 "TARGET_ARCH64
7247 && ((GET_CODE (operands[2]) == CONST_INT
7248 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7249 || (GET_CODE (operands[2]) == CONST_DOUBLE
7250 && CONST_DOUBLE_HIGH (operands[2]) == 0
7251 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7252 "*
7253 {
7254 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7255
7256 return \"srl\\t%1, %2, %0\";
7257 }"
7258 [(set_attr "type" "shift")
7259 (set_attr "length" "1")])
7260
7261 (define_expand "lshrdi3"
7262 [(set (match_operand:DI 0 "register_operand" "=r")
7263 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7264 (match_operand:SI 2 "arith_operand" "rI")))]
7265 "TARGET_ARCH64 || TARGET_V8PLUS"
7266 "
7267 {
7268 if (! TARGET_ARCH64)
7269 {
7270 if (GET_CODE (operands[2]) == CONST_INT)
7271 FAIL;
7272 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7273 DONE;
7274 }
7275 }")
7276
7277 (define_insn ""
7278 [(set (match_operand:DI 0 "register_operand" "=r")
7279 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7280 (match_operand:SI 2 "arith_operand" "rI")))]
7281 "TARGET_ARCH64"
7282 "*
7283 {
7284 if (GET_CODE (operands[2]) == CONST_INT
7285 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7286 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7287
7288 return \"srlx\\t%1, %2, %0\";
7289 }"
7290 [(set_attr "type" "shift")
7291 (set_attr "length" "1")])
7292
7293 ;; XXX
7294 (define_insn "lshrdi3_v8plus"
7295 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7296 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7297 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7298 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7299 "TARGET_V8PLUS"
7300 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7301 [(set_attr "length" "5,5,6")])
7302
7303 (define_insn ""
7304 [(set (match_operand:SI 0 "register_operand" "=r")
7305 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7306 (const_int 32)) 0)
7307 (match_operand:SI 2 "small_int_or_double" "n")))]
7308 "TARGET_ARCH64
7309 && ((GET_CODE (operands[2]) == CONST_INT
7310 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7311 || (GET_CODE (operands[2]) == CONST_DOUBLE
7312 && !CONST_DOUBLE_HIGH (operands[2])
7313 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7314 "*
7315 {
7316 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7317
7318 return \"srax\\t%1, %2, %0\";
7319 }"
7320 [(set_attr "type" "shift")
7321 (set_attr "length" "1")])
7322
7323 (define_insn ""
7324 [(set (match_operand:SI 0 "register_operand" "=r")
7325 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7326 (const_int 32)) 0)
7327 (match_operand:SI 2 "small_int_or_double" "n")))]
7328 "TARGET_ARCH64
7329 && ((GET_CODE (operands[2]) == CONST_INT
7330 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7331 || (GET_CODE (operands[2]) == CONST_DOUBLE
7332 && !CONST_DOUBLE_HIGH (operands[2])
7333 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7334 "*
7335 {
7336 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7337
7338 return \"srlx\\t%1, %2, %0\";
7339 }"
7340 [(set_attr "type" "shift")
7341 (set_attr "length" "1")])
7342
7343 (define_insn ""
7344 [(set (match_operand:SI 0 "register_operand" "=r")
7345 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7346 (match_operand:SI 2 "small_int_or_double" "n")) 0)
7347 (match_operand:SI 3 "small_int_or_double" "n")))]
7348 "TARGET_ARCH64
7349 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7350 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7351 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7352 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7353 "*
7354 {
7355 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7356
7357 return \"srax\\t%1, %2, %0\";
7358 }"
7359 [(set_attr "type" "shift")
7360 (set_attr "length" "1")])
7361
7362 (define_insn ""
7363 [(set (match_operand:SI 0 "register_operand" "=r")
7364 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7365 (match_operand:SI 2 "small_int_or_double" "n")) 0)
7366 (match_operand:SI 3 "small_int_or_double" "n")))]
7367 "TARGET_ARCH64
7368 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7369 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7370 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7371 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7372 "*
7373 {
7374 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7375
7376 return \"srlx\\t%1, %2, %0\";
7377 }"
7378 [(set_attr "type" "shift")
7379 (set_attr "length" "1")])
7380 \f
7381 ;; Unconditional and other jump instructions
7382 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7383 ;; following insn is never executed. This saves us a nop. Dbx does not
7384 ;; handle such branches though, so we only use them when optimizing.
7385 (define_insn "jump"
7386 [(set (pc) (label_ref (match_operand 0 "" "")))]
7387 ""
7388 "*
7389 {
7390 /* TurboSparc is reported to have problems with
7391 with
7392 foo: b,a foo
7393 i.e. an empty loop with the annul bit set. The workaround is to use
7394 foo: b foo; nop
7395 instead. */
7396
7397 if (! TARGET_V9 && flag_delayed_branch
7398 && (insn_addresses[INSN_UID (operands[0])]
7399 == insn_addresses[INSN_UID (insn)]))
7400 return \"b\\t%l0%#\";
7401 else
7402 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7403 }"
7404 [(set_attr "type" "uncond_branch")])
7405
7406 (define_expand "tablejump"
7407 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7408 (use (label_ref (match_operand 1 "" "")))])]
7409 ""
7410 "
7411 {
7412 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7413 abort ();
7414
7415 /* In pic mode, our address differences are against the base of the
7416 table. Add that base value back in; CSE ought to be able to combine
7417 the two address loads. */
7418 if (flag_pic)
7419 {
7420 rtx tmp, tmp2;
7421 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7422 tmp2 = operands[0];
7423 if (CASE_VECTOR_MODE != Pmode)
7424 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7425 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7426 operands[0] = memory_address (Pmode, tmp);
7427 }
7428 }")
7429
7430 (define_insn "*tablejump_sp32"
7431 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7432 (use (label_ref (match_operand 1 "" "")))]
7433 "! TARGET_PTR64"
7434 "jmp\\t%a0%#"
7435 [(set_attr "type" "uncond_branch")])
7436
7437 (define_insn "*tablejump_sp64"
7438 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7439 (use (label_ref (match_operand 1 "" "")))]
7440 "TARGET_PTR64"
7441 "jmp\\t%a0%#"
7442 [(set_attr "type" "uncond_branch")])
7443
7444 ;; This pattern recognizes the "instruction" that appears in
7445 ;; a function call that wants a structure value,
7446 ;; to inform the called function if compiled with Sun CC.
7447 ;(define_insn "*unimp_insn"
7448 ; [(match_operand:SI 0 "immediate_operand" "")]
7449 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7450 ; "unimp\\t%0"
7451 ; [(set_attr "type" "marker")])
7452
7453 ;;- jump to subroutine
7454 (define_expand "call"
7455 ;; Note that this expression is not used for generating RTL.
7456 ;; All the RTL is generated explicitly below.
7457 [(call (match_operand 0 "call_operand" "")
7458 (match_operand 3 "" "i"))]
7459 ;; operands[2] is next_arg_register
7460 ;; operands[3] is struct_value_size_rtx.
7461 ""
7462 "
7463 {
7464 rtx fn_rtx, nregs_rtx;
7465
7466 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7467 abort ();
7468
7469 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7470 {
7471 /* This is really a PIC sequence. We want to represent
7472 it as a funny jump so its delay slots can be filled.
7473
7474 ??? But if this really *is* a CALL, will not it clobber the
7475 call-clobbered registers? We lose this if it is a JUMP_INSN.
7476 Why cannot we have delay slots filled if it were a CALL? */
7477
7478 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7479 emit_jump_insn
7480 (gen_rtx_PARALLEL
7481 (VOIDmode,
7482 gen_rtvec (3,
7483 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7484 operands[3],
7485 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7486 else
7487 emit_jump_insn
7488 (gen_rtx_PARALLEL
7489 (VOIDmode,
7490 gen_rtvec (2,
7491 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7492 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7493 goto finish_call;
7494 }
7495
7496 fn_rtx = operands[0];
7497
7498 /* Count the number of parameter registers being used by this call.
7499 if that argument is NULL, it means we are using them all, which
7500 means 6 on the sparc. */
7501 #if 0
7502 if (operands[2])
7503 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7504 else
7505 nregs_rtx = GEN_INT (6);
7506 #else
7507 nregs_rtx = const0_rtx;
7508 #endif
7509
7510 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7511 emit_call_insn
7512 (gen_rtx_PARALLEL
7513 (VOIDmode,
7514 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7515 operands[3],
7516 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7517 else
7518 emit_call_insn
7519 (gen_rtx_PARALLEL
7520 (VOIDmode,
7521 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7522 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7523
7524 finish_call:
7525 #if 0
7526 /* If this call wants a structure value,
7527 emit an unimp insn to let the called function know about this. */
7528 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7529 {
7530 rtx insn = emit_insn (operands[3]);
7531 SCHED_GROUP_P (insn) = 1;
7532 }
7533 #endif
7534
7535 DONE;
7536 }")
7537
7538 ;; We can't use the same pattern for these two insns, because then registers
7539 ;; in the address may not be properly reloaded.
7540
7541 (define_insn "*call_address_sp32"
7542 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7543 (match_operand 1 "" ""))
7544 (clobber (reg:SI 15))]
7545 ;;- Do not use operand 1 for most machines.
7546 "! TARGET_PTR64"
7547 "call\\t%a0, %1%#"
7548 [(set_attr "type" "call")])
7549
7550 (define_insn "*call_symbolic_sp32"
7551 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7552 (match_operand 1 "" ""))
7553 (clobber (reg:SI 15))]
7554 ;;- Do not use operand 1 for most machines.
7555 "! TARGET_PTR64"
7556 "call\\t%a0, %1%#"
7557 [(set_attr "type" "call")])
7558
7559 (define_insn "*call_address_sp64"
7560 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
7561 (match_operand 1 "" ""))
7562 (clobber (reg:DI 15))]
7563 ;;- Do not use operand 1 for most machines.
7564 "TARGET_PTR64"
7565 "call\\t%a0, %1%#"
7566 [(set_attr "type" "call")])
7567
7568 (define_insn "*call_symbolic_sp64"
7569 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
7570 (match_operand 1 "" ""))
7571 (clobber (reg:DI 15))]
7572 ;;- Do not use operand 1 for most machines.
7573 "TARGET_PTR64"
7574 "call\\t%a0, %1%#"
7575 [(set_attr "type" "call")])
7576
7577 ;; This is a call that wants a structure value.
7578 ;; There is no such critter for v9 (??? we may need one anyway).
7579 (define_insn "*call_address_struct_value_sp32"
7580 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7581 (match_operand 1 "" ""))
7582 (match_operand 2 "immediate_operand" "")
7583 (clobber (reg:SI 15))]
7584 ;;- Do not use operand 1 for most machines.
7585 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7586 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7587 [(set_attr "type" "call_no_delay_slot")])
7588
7589 ;; This is a call that wants a structure value.
7590 ;; There is no such critter for v9 (??? we may need one anyway).
7591 (define_insn "*call_symbolic_struct_value_sp32"
7592 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7593 (match_operand 1 "" ""))
7594 (match_operand 2 "immediate_operand" "")
7595 (clobber (reg:SI 15))]
7596 ;;- Do not use operand 1 for most machines.
7597 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7598 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7599 [(set_attr "type" "call_no_delay_slot")])
7600
7601 ;; This is a call that may want a structure value. This is used for
7602 ;; untyped_calls.
7603 (define_insn "*call_address_untyped_struct_value_sp32"
7604 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7605 (match_operand 1 "" ""))
7606 (match_operand 2 "immediate_operand" "")
7607 (clobber (reg:SI 15))]
7608 ;;- Do not use operand 1 for most machines.
7609 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7610 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7611 [(set_attr "type" "call_no_delay_slot")])
7612
7613 ;; This is a call that wants a structure value.
7614 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7615 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7616 (match_operand 1 "" ""))
7617 (match_operand 2 "immediate_operand" "")
7618 (clobber (reg:SI 15))]
7619 ;;- Do not use operand 1 for most machines.
7620 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7621 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7622 [(set_attr "type" "call_no_delay_slot")])
7623
7624 (define_expand "call_value"
7625 ;; Note that this expression is not used for generating RTL.
7626 ;; All the RTL is generated explicitly below.
7627 [(set (match_operand 0 "register_operand" "=rf")
7628 (call (match_operand:SI 1 "" "")
7629 (match_operand 4 "" "")))]
7630 ;; operand 2 is stack_size_rtx
7631 ;; operand 3 is next_arg_register
7632 ""
7633 "
7634 {
7635 rtx fn_rtx, nregs_rtx;
7636 rtvec vec;
7637
7638 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7639 abort ();
7640
7641 fn_rtx = operands[1];
7642
7643 #if 0
7644 if (operands[3])
7645 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7646 else
7647 nregs_rtx = GEN_INT (6);
7648 #else
7649 nregs_rtx = const0_rtx;
7650 #endif
7651
7652 vec = gen_rtvec (2,
7653 gen_rtx_SET (VOIDmode, operands[0],
7654 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7655 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7656
7657 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7658
7659 DONE;
7660 }")
7661
7662 (define_insn "*call_value_address_sp32"
7663 [(set (match_operand 0 "" "=rf")
7664 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7665 (match_operand 2 "" "")))
7666 (clobber (reg:SI 15))]
7667 ;;- Do not use operand 2 for most machines.
7668 "! TARGET_PTR64"
7669 "call\\t%a1, %2%#"
7670 [(set_attr "type" "call")])
7671
7672 (define_insn "*call_value_symbolic_sp32"
7673 [(set (match_operand 0 "" "=rf")
7674 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7675 (match_operand 2 "" "")))
7676 (clobber (reg:SI 15))]
7677 ;;- Do not use operand 2 for most machines.
7678 "! TARGET_PTR64"
7679 "call\\t%a1, %2%#"
7680 [(set_attr "type" "call")])
7681
7682 (define_insn "*call_value_address_sp64"
7683 [(set (match_operand 0 "" "")
7684 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
7685 (match_operand 2 "" "")))
7686 (clobber (reg:DI 15))]
7687 ;;- Do not use operand 2 for most machines.
7688 "TARGET_PTR64"
7689 "call\\t%a1, %2%#"
7690 [(set_attr "type" "call")])
7691
7692 (define_insn "*call_value_symbolic_sp64"
7693 [(set (match_operand 0 "" "")
7694 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
7695 (match_operand 2 "" "")))
7696 (clobber (reg:DI 15))]
7697 ;;- Do not use operand 2 for most machines.
7698 "TARGET_PTR64"
7699 "call\\t%a1, %2%#"
7700 [(set_attr "type" "call")])
7701
7702 (define_expand "untyped_call"
7703 [(parallel [(call (match_operand 0 "" "")
7704 (const_int 0))
7705 (match_operand 1 "" "")
7706 (match_operand 2 "" "")])]
7707 ""
7708 "
7709 {
7710 int i;
7711
7712 /* Pass constm1 to indicate that it may expect a structure value, but
7713 we don't know what size it is. */
7714 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
7715
7716 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7717 {
7718 rtx set = XVECEXP (operands[2], 0, i);
7719 emit_move_insn (SET_DEST (set), SET_SRC (set));
7720 }
7721
7722 /* The optimizer does not know that the call sets the function value
7723 registers we stored in the result block. We avoid problems by
7724 claiming that all hard registers are used and clobbered at this
7725 point. */
7726 emit_insn (gen_blockage ());
7727
7728 DONE;
7729 }")
7730
7731 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7732 ;; all of memory. This blocks insns from being moved across this point.
7733
7734 (define_insn "blockage"
7735 [(unspec_volatile [(const_int 0)] 0)]
7736 ""
7737 ""
7738 [(set_attr "length" "0")])
7739
7740 ;; Prepare to return any type including a structure value.
7741
7742 (define_expand "untyped_return"
7743 [(match_operand:BLK 0 "memory_operand" "")
7744 (match_operand 1 "" "")]
7745 ""
7746 "
7747 {
7748 rtx valreg1 = gen_rtx_REG (DImode, 24);
7749 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7750 rtx result = operands[0];
7751
7752 if (! TARGET_ARCH64)
7753 {
7754 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7755 ? 15 : 31));
7756 rtx value = gen_reg_rtx (SImode);
7757
7758 /* Fetch the instruction where we will return to and see if it's an unimp
7759 instruction (the most significant 10 bits will be zero). If so,
7760 update the return address to skip the unimp instruction. */
7761 emit_move_insn (value,
7762 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7763 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7764 emit_insn (gen_update_return (rtnreg, value));
7765 }
7766
7767 /* Reload the function value registers. */
7768 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
7769 emit_move_insn (valreg2,
7770 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
7771 plus_constant (XEXP (result, 0), 8)));
7772
7773 /* Put USE insns before the return. */
7774 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7775 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7776
7777 /* Construct the return. */
7778 expand_null_return ();
7779
7780 DONE;
7781 }")
7782
7783 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7784 ;; and parts of the compiler don't want to believe that the add is needed.
7785
7786 (define_insn "update_return"
7787 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7788 (match_operand:SI 1 "register_operand" "r")] 1)]
7789 "! TARGET_ARCH64"
7790 "cmp %1,0\;be,a .+8\;add %0,4,%0"
7791 [(set_attr "type" "multi")])
7792 \f
7793 (define_insn "return"
7794 [(return)
7795 (use (reg:SI 31))]
7796 "! TARGET_EPILOGUE"
7797 "* return output_return (operands);"
7798 [(set_attr "type" "return")])
7799
7800 (define_peephole
7801 [(set (match_operand:SI 0 "register_operand" "=r")
7802 (match_operand:SI 1 "arith_operand" "rI"))
7803 (parallel [(return)
7804 (use (reg:SI 31))])]
7805 "sparc_return_peephole_ok (operands[0], operands[1])"
7806 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
7807
7808 (define_insn "nop"
7809 [(const_int 0)]
7810 ""
7811 "nop"
7812 [(set_attr "type" "ialu")
7813 (set_attr "length" "1")])
7814
7815 (define_expand "indirect_jump"
7816 [(set (pc) (match_operand 0 "address_operand" "p"))]
7817 ""
7818 "")
7819
7820 (define_insn "*branch_sp32"
7821 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7822 "! TARGET_PTR64"
7823 "jmp\\t%a0%#"
7824 [(set_attr "type" "uncond_branch")])
7825
7826 (define_insn "*branch_sp64"
7827 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7828 "TARGET_PTR64"
7829 "jmp\\t%a0%#"
7830 [(set_attr "type" "uncond_branch")])
7831
7832 ;; ??? Doesn't work with -mflat.
7833 (define_expand "nonlocal_goto"
7834 [(match_operand:SI 0 "general_operand" "")
7835 (match_operand:SI 1 "general_operand" "")
7836 (match_operand:SI 2 "general_operand" "")
7837 (match_operand:SI 3 "" "")]
7838 ""
7839 "
7840 {
7841 #if 0
7842 rtx chain = operands[0];
7843 #endif
7844 rtx fp = operands[1];
7845 rtx stack = operands[2];
7846 rtx lab = operands[3];
7847 rtx labreg;
7848
7849 /* Trap instruction to flush all the register windows. */
7850 emit_insn (gen_flush_register_windows ());
7851
7852 /* Load the fp value for the containing fn into %fp. This is needed
7853 because STACK refers to %fp. Note that virtual register instantiation
7854 fails if the virtual %fp isn't set from a register. */
7855 if (GET_CODE (fp) != REG)
7856 fp = force_reg (Pmode, fp);
7857 emit_move_insn (virtual_stack_vars_rtx, fp);
7858
7859 /* Find the containing function's current nonlocal goto handler,
7860 which will do any cleanups and then jump to the label. */
7861 labreg = gen_rtx_REG (Pmode, 8);
7862 emit_move_insn (labreg, lab);
7863
7864 /* Restore %fp from stack pointer value for containing function.
7865 The restore insn that follows will move this to %sp,
7866 and reload the appropriate value into %fp. */
7867 emit_move_insn (frame_pointer_rtx, stack);
7868
7869 /* USE of frame_pointer_rtx added for consistency; not clear if
7870 really needed. */
7871 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7872 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7873
7874 #if 0
7875 /* Return, restoring reg window and jumping to goto handler. */
7876 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7877 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7878 {
7879 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
7880 chain));
7881 emit_barrier ();
7882 DONE;
7883 }
7884 /* Put in the static chain register the nonlocal label address. */
7885 emit_move_insn (static_chain_rtx, chain);
7886 #endif
7887
7888 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7889 emit_insn (gen_goto_handler_and_restore (labreg));
7890 emit_barrier ();
7891 DONE;
7892 }")
7893
7894 ;; Special trap insn to flush register windows.
7895 (define_insn "flush_register_windows"
7896 [(unspec_volatile [(const_int 0)] 1)]
7897 ""
7898 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
7899 [(set_attr "type" "misc")
7900 (set_attr "length" "1")])
7901
7902 (define_insn "goto_handler_and_restore"
7903 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
7904 "GET_MODE (operands[0]) == Pmode"
7905 "jmp\\t%0+0\\n\\trestore"
7906 [(set_attr "type" "misc")
7907 (set_attr "length" "2")])
7908
7909 ;;(define_insn "goto_handler_and_restore_v9"
7910 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7911 ;; (match_operand:SI 1 "register_operand" "=r,r")
7912 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7913 ;; "TARGET_V9 && ! TARGET_ARCH64"
7914 ;; "@
7915 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7916 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7917 ;; [(set_attr "type" "misc")
7918 ;; (set_attr "length" "2,3")])
7919 ;;
7920 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7921 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7922 ;; (match_operand:DI 1 "register_operand" "=r,r")
7923 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7924 ;; "TARGET_V9 && TARGET_ARCH64"
7925 ;; "@
7926 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7927 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7928 ;; [(set_attr "type" "misc")
7929 ;; (set_attr "length" "2,3")])
7930
7931 ;; Pattern for use after a setjmp to store FP and the return register
7932 ;; into the stack area.
7933
7934 (define_expand "setjmp"
7935 [(const_int 0)]
7936 ""
7937 "
7938 {
7939 if (TARGET_ARCH64)
7940 emit_insn (gen_setjmp_64 ());
7941 else
7942 emit_insn (gen_setjmp_32 ());
7943 DONE;
7944 }")
7945
7946 (define_expand "setjmp_32"
7947 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7948 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7949 ""
7950 "
7951 { operands[0] = frame_pointer_rtx; }")
7952
7953 (define_expand "setjmp_64"
7954 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7955 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7956 ""
7957 "
7958 { operands[0] = frame_pointer_rtx; }")
7959
7960 ;; Special pattern for the FLUSH instruction.
7961
7962 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7963 ; of the define_insn otherwise missing a mode. We make "flush", aka
7964 ; gen_flush, the default one since sparc_initialize_trampoline uses
7965 ; it on SImode mem values.
7966
7967 (define_insn "flush"
7968 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
7969 ""
7970 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
7971 [(set_attr "type" "misc")])
7972
7973 (define_insn "flushdi"
7974 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
7975 ""
7976 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
7977 [(set_attr "type" "misc")])
7978
7979 \f
7980 ;; find first set.
7981
7982 ;; The scan instruction searches from the most significant bit while ffs
7983 ;; searches from the least significant bit. The bit index and treatment of
7984 ;; zero also differ. It takes at least 7 instructions to get the proper
7985 ;; result. Here is an obvious 8 instruction sequence.
7986
7987 ;; XXX
7988 (define_insn "ffssi2"
7989 [(set (match_operand:SI 0 "register_operand" "=&r")
7990 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7991 (clobber (match_scratch:SI 2 "=&r"))]
7992 "TARGET_SPARCLITE || TARGET_SPARCLET"
7993 "*
7994 {
7995 if (TARGET_LIVE_G0)
7996 output_asm_insn (\"and %%g0,0,%%g0\", operands);
7997 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\";
7998 }"
7999 [(set_attr "type" "multi")
8000 (set_attr "length" "8")])
8001
8002 ;; ??? This should be a define expand, so that the extra instruction have
8003 ;; a chance of being optimized away.
8004
8005 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8006 ;; does, but no one uses that and we don't have a switch for it.
8007 ;
8008 ;(define_insn "ffsdi2"
8009 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8010 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8011 ; (clobber (match_scratch:DI 2 "=&r"))]
8012 ; "TARGET_ARCH64"
8013 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
8014 ; [(set_attr "type" "multi")
8015 ; (set_attr "length" "4")])
8016
8017
8018 \f
8019 ;; Peepholes go at the end.
8020
8021 ;; Optimize consecutive loads or stores into ldd and std when possible.
8022 ;; The conditions in which we do this are very restricted and are
8023 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8024
8025 (define_peephole
8026 [(set (match_operand:SI 0 "memory_operand" "")
8027 (const_int 0))
8028 (set (match_operand:SI 1 "memory_operand" "")
8029 (const_int 0))]
8030 "TARGET_V9
8031 && ! MEM_VOLATILE_P (operands[0])
8032 && ! MEM_VOLATILE_P (operands[1])
8033 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
8034 "stx\\t%%g0, %0")
8035
8036 (define_peephole
8037 [(set (match_operand:SI 0 "memory_operand" "")
8038 (const_int 0))
8039 (set (match_operand:SI 1 "memory_operand" "")
8040 (const_int 0))]
8041 "TARGET_V9
8042 && ! MEM_VOLATILE_P (operands[0])
8043 && ! MEM_VOLATILE_P (operands[1])
8044 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
8045 "stx\\t%%g0, %1")
8046
8047 (define_peephole
8048 [(set (match_operand:SI 0 "register_operand" "=rf")
8049 (match_operand:SI 1 "memory_operand" ""))
8050 (set (match_operand:SI 2 "register_operand" "=rf")
8051 (match_operand:SI 3 "memory_operand" ""))]
8052 "registers_ok_for_ldd_peep (operands[0], operands[2])
8053 && ! MEM_VOLATILE_P (operands[1])
8054 && ! MEM_VOLATILE_P (operands[3])
8055 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8056 "ldd\\t%1, %0")
8057
8058 (define_peephole
8059 [(set (match_operand:SI 0 "memory_operand" "")
8060 (match_operand:SI 1 "register_operand" "rf"))
8061 (set (match_operand:SI 2 "memory_operand" "")
8062 (match_operand:SI 3 "register_operand" "rf"))]
8063 "registers_ok_for_ldd_peep (operands[1], operands[3])
8064 && ! MEM_VOLATILE_P (operands[0])
8065 && ! MEM_VOLATILE_P (operands[2])
8066 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8067 "std\\t%1, %0")
8068
8069 (define_peephole
8070 [(set (match_operand:SF 0 "register_operand" "=fr")
8071 (match_operand:SF 1 "memory_operand" ""))
8072 (set (match_operand:SF 2 "register_operand" "=fr")
8073 (match_operand:SF 3 "memory_operand" ""))]
8074 "registers_ok_for_ldd_peep (operands[0], operands[2])
8075 && ! MEM_VOLATILE_P (operands[1])
8076 && ! MEM_VOLATILE_P (operands[3])
8077 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8078 "ldd\\t%1, %0")
8079
8080 (define_peephole
8081 [(set (match_operand:SF 0 "memory_operand" "")
8082 (match_operand:SF 1 "register_operand" "fr"))
8083 (set (match_operand:SF 2 "memory_operand" "")
8084 (match_operand:SF 3 "register_operand" "fr"))]
8085 "registers_ok_for_ldd_peep (operands[1], operands[3])
8086 && ! MEM_VOLATILE_P (operands[0])
8087 && ! MEM_VOLATILE_P (operands[2])
8088 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8089 "std\\t%1, %0")
8090
8091 (define_peephole
8092 [(set (match_operand:SI 0 "register_operand" "=rf")
8093 (match_operand:SI 1 "memory_operand" ""))
8094 (set (match_operand:SI 2 "register_operand" "=rf")
8095 (match_operand:SI 3 "memory_operand" ""))]
8096 "registers_ok_for_ldd_peep (operands[2], operands[0])
8097 && ! MEM_VOLATILE_P (operands[3])
8098 && ! MEM_VOLATILE_P (operands[1])
8099 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8100 "ldd\\t%3, %2")
8101
8102 (define_peephole
8103 [(set (match_operand:SI 0 "memory_operand" "")
8104 (match_operand:SI 1 "register_operand" "rf"))
8105 (set (match_operand:SI 2 "memory_operand" "")
8106 (match_operand:SI 3 "register_operand" "rf"))]
8107 "registers_ok_for_ldd_peep (operands[3], operands[1])
8108 && ! MEM_VOLATILE_P (operands[2])
8109 && ! MEM_VOLATILE_P (operands[0])
8110 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8111 "std\\t%3, %2")
8112
8113 (define_peephole
8114 [(set (match_operand:SF 0 "register_operand" "=fr")
8115 (match_operand:SF 1 "memory_operand" ""))
8116 (set (match_operand:SF 2 "register_operand" "=fr")
8117 (match_operand:SF 3 "memory_operand" ""))]
8118 "registers_ok_for_ldd_peep (operands[2], operands[0])
8119 && ! MEM_VOLATILE_P (operands[3])
8120 && ! MEM_VOLATILE_P (operands[1])
8121 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8122 "ldd\\t%3, %2")
8123
8124 (define_peephole
8125 [(set (match_operand:SF 0 "memory_operand" "")
8126 (match_operand:SF 1 "register_operand" "fr"))
8127 (set (match_operand:SF 2 "memory_operand" "")
8128 (match_operand:SF 3 "register_operand" "fr"))]
8129 "registers_ok_for_ldd_peep (operands[3], operands[1])
8130 && ! MEM_VOLATILE_P (operands[2])
8131 && ! MEM_VOLATILE_P (operands[0])
8132 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8133 "std\\t%3, %2")
8134
8135 ;; Optimize the case of following a reg-reg move with a test
8136 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8137 ;; This can result from a float to fix conversion.
8138
8139 (define_peephole
8140 [(set (match_operand:SI 0 "register_operand" "=r")
8141 (match_operand:SI 1 "register_operand" "r"))
8142 (set (reg:CC 100)
8143 (compare:CC (match_operand:SI 2 "register_operand" "r")
8144 (const_int 0)))]
8145 "(rtx_equal_p (operands[2], operands[0])
8146 || rtx_equal_p (operands[2], operands[1]))
8147 && ! FP_REG_P (operands[0])
8148 && ! FP_REG_P (operands[1])"
8149 "orcc\\t%1, 0, %0")
8150
8151 (define_peephole
8152 [(set (match_operand:DI 0 "register_operand" "=r")
8153 (match_operand:DI 1 "register_operand" "r"))
8154 (set (reg:CCX 100)
8155 (compare:CCX (match_operand:DI 2 "register_operand" "r")
8156 (const_int 0)))]
8157 "TARGET_ARCH64
8158 && (rtx_equal_p (operands[2], operands[0])
8159 || rtx_equal_p (operands[2], operands[1]))
8160 && ! FP_REG_P (operands[0])
8161 && ! FP_REG_P (operands[1])"
8162 "orcc\\t%1, 0, %0")
8163
8164 ;; Return peepholes. First the "normal" ones.
8165 ;; These are necessary to catch insns ending up in the epilogue delay list.
8166
8167 (define_insn "*return_qi"
8168 [(set (match_operand:QI 0 "restore_operand" "")
8169 (match_operand:QI 1 "arith_operand" "rI"))
8170 (return)]
8171 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8172 "*
8173 {
8174 if (! TARGET_ARCH64 && current_function_returns_struct)
8175 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8176 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8177 || IN_OR_GLOBAL_P (operands[1])))
8178 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8179 else
8180 return \"ret\\n\\trestore %%g0, %1, %Y0\";
8181 }"
8182 [(set_attr "type" "multi")])
8183
8184 (define_insn "*return_hi"
8185 [(set (match_operand:HI 0 "restore_operand" "")
8186 (match_operand:HI 1 "arith_operand" "rI"))
8187 (return)]
8188 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8189 "*
8190 {
8191 if (! TARGET_ARCH64 && current_function_returns_struct)
8192 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8193 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8194 || IN_OR_GLOBAL_P (operands[1])))
8195 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8196 else
8197 return \"ret\;restore %%g0, %1, %Y0\";
8198 }"
8199 [(set_attr "type" "multi")])
8200
8201 (define_insn "*return_si"
8202 [(set (match_operand:SI 0 "restore_operand" "")
8203 (match_operand:SI 1 "arith_operand" "rI"))
8204 (return)]
8205 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8206 "*
8207 {
8208 if (! TARGET_ARCH64 && current_function_returns_struct)
8209 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8210 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8211 || IN_OR_GLOBAL_P (operands[1])))
8212 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8213 else
8214 return \"ret\;restore %%g0, %1, %Y0\";
8215 }"
8216 [(set_attr "type" "multi")])
8217
8218 ;; The following pattern is only generated by delayed-branch scheduling,
8219 ;; when the insn winds up in the epilogue. This can happen not only when
8220 ;; ! TARGET_FPU because we move complex types around by parts using
8221 ;; SF mode SUBREGs.
8222 (define_insn "*return_sf_no_fpu"
8223 [(set (match_operand:SF 0 "restore_operand" "=r")
8224 (match_operand:SF 1 "register_operand" "r"))
8225 (return)]
8226 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8227 "*
8228 {
8229 if (! TARGET_ARCH64 && current_function_returns_struct)
8230 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8231 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8232 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8233 else
8234 return \"ret\;restore %%g0, %1, %Y0\";
8235 }"
8236 [(set_attr "type" "multi")])
8237
8238 (define_insn "*return_addsi"
8239 [(set (match_operand:SI 0 "restore_operand" "")
8240 (plus:SI (match_operand:SI 1 "register_operand" "r")
8241 (match_operand:SI 2 "arith_operand" "rI")))
8242 (return)]
8243 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8244 "*
8245 {
8246 if (! TARGET_ARCH64 && current_function_returns_struct)
8247 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
8248 /* If operands are global or in registers, can use return */
8249 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8250 && (GET_CODE (operands[2]) == CONST_INT
8251 || IN_OR_GLOBAL_P (operands[2])))
8252 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
8253 else
8254 return \"ret\;restore %r1, %2, %Y0\";
8255 }"
8256 [(set_attr "type" "multi")])
8257
8258 (define_insn "*return_losum_si"
8259 [(set (match_operand:SI 0 "restore_operand" "")
8260 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8261 (match_operand:SI 2 "immediate_operand" "in")))
8262 (return)]
8263 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0 && ! TARGET_CM_MEDMID"
8264 "*
8265 {
8266 if (! TARGET_ARCH64 && current_function_returns_struct)
8267 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
8268 /* If operands are global or in registers, can use return */
8269 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8270 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
8271 else
8272 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
8273 }"
8274 [(set_attr "type" "multi")])
8275
8276 (define_insn "*return_di"
8277 [(set (match_operand:DI 0 "restore_operand" "")
8278 (match_operand:DI 1 "arith_double_operand" "rHI"))
8279 (return)]
8280 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
8281 "ret\;restore %%g0, %1, %Y0"
8282 [(set_attr "type" "multi")])
8283
8284 (define_insn "*return_adddi"
8285 [(set (match_operand:DI 0 "restore_operand" "")
8286 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8287 (match_operand:DI 2 "arith_double_operand" "rHI")))
8288 (return)]
8289 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
8290 "ret\;restore %r1, %2, %Y0"
8291 [(set_attr "type" "multi")])
8292
8293 (define_insn "*return_losum_di"
8294 [(set (match_operand:DI 0 "restore_operand" "")
8295 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8296 (match_operand:DI 2 "immediate_operand" "in")))
8297 (return)]
8298 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
8299 "ret\;restore %r1, %%lo(%a2), %Y0"
8300 [(set_attr "type" "multi")])
8301
8302 ;; The following pattern is only generated by delayed-branch scheduling,
8303 ;; when the insn winds up in the epilogue.
8304 (define_insn "*return_sf"
8305 [(set (reg:SF 32)
8306 (match_operand:SF 0 "register_operand" "f"))
8307 (return)]
8308 "! TARGET_EPILOGUE"
8309 "ret\;fmovs\\t%0, %%f0"
8310 [(set_attr "type" "multi")])
8311
8312 ;; Now peepholes to do a call followed by a jump.
8313
8314 (define_peephole
8315 [(parallel [(set (match_operand 0 "" "")
8316 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8317 (match_operand 2 "" "")))
8318 (clobber (reg:SI 15))])
8319 (set (pc) (label_ref (match_operand 3 "" "")))]
8320 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8321 && in_same_eh_region (insn, operands[3])
8322 && in_same_eh_region (insn, ins1)"
8323 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8324
8325 (define_peephole
8326 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8327 (match_operand 1 "" ""))
8328 (clobber (reg:SI 15))])
8329 (set (pc) (label_ref (match_operand 2 "" "")))]
8330 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8331 && in_same_eh_region (insn, operands[2])
8332 && in_same_eh_region (insn, ins1)"
8333 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8334
8335 (define_peephole
8336 [(parallel [(set (match_operand 0 "" "")
8337 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
8338 (match_operand 2 "" "")))
8339 (clobber (reg:DI 15))])
8340 (set (pc) (label_ref (match_operand 3 "" "")))]
8341 "TARGET_ARCH64
8342 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8343 && in_same_eh_region (insn, operands[3])
8344 && in_same_eh_region (insn, ins1)"
8345 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8346
8347 (define_peephole
8348 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
8349 (match_operand 1 "" ""))
8350 (clobber (reg:DI 15))])
8351 (set (pc) (label_ref (match_operand 2 "" "")))]
8352 "TARGET_ARCH64
8353 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8354 && in_same_eh_region (insn, operands[2])
8355 && in_same_eh_region (insn, ins1)"
8356 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8357
8358 ;; After a nonlocal goto, we need to restore the PIC register, but only
8359 ;; if we need it. So do nothing much here, but we'll check for this in
8360 ;; finalize_pic.
8361
8362 ;; Make sure this unspec_volatile number agrees with finalize_pic.
8363 (define_insn "nonlocal_goto_receiver"
8364 [(unspec_volatile [(const_int 0)] 5)]
8365 "flag_pic"
8366 ""
8367 [(set_attr "length" "0")])
8368 \f
8369 (define_insn "trap"
8370 [(trap_if (const_int 1) (const_int 5))]
8371 ""
8372 "ta\\t5"
8373 [(set_attr "type" "misc")
8374 (set_attr "length" "1")])
8375
8376 (define_expand "conditional_trap"
8377 [(trap_if (match_operator 0 "noov_compare_op"
8378 [(match_dup 2) (match_dup 3)])
8379 (match_operand:SI 1 "arith_operand" ""))]
8380 ""
8381 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8382 sparc_compare_op0, sparc_compare_op1);
8383 operands[3] = const0_rtx;")
8384
8385 (define_insn ""
8386 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8387 (match_operand:SI 1 "arith_operand" "rM"))]
8388 ""
8389 "t%C0\\t%1"
8390 [(set_attr "type" "misc")
8391 (set_attr "length" "1")])
8392
8393 (define_insn ""
8394 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8395 (match_operand:SI 1 "arith_operand" "rM"))]
8396 "TARGET_V9"
8397 "t%C0\\t%%xcc, %1"
8398 [(set_attr "type" "misc")
8399 (set_attr "length" "1")])