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