sparc.c (const64_high_operand): Zero-extend operands of SPARC_SETHI_P.
[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], 1, 0,
1897 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1898 ! final_sequence, insn);
1899 }"
1900 [(set_attr "type" "branch")])
1901
1902 ;; XXX fpcmp nop braindamage
1903 (define_insn "*inverted_branch"
1904 [(set (pc)
1905 (if_then_else (match_operator 0 "noov_compare_op"
1906 [(reg 100) (const_int 0)])
1907 (pc)
1908 (label_ref (match_operand 1 "" ""))))]
1909 ""
1910 "*
1911 {
1912 return output_cbranch (operands[0], 1, 1,
1913 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1914 ! final_sequence, insn);
1915 }"
1916 [(set_attr "type" "branch")])
1917
1918 ;; XXX fpcmp nop braindamage
1919 (define_insn "*normal_fp_branch"
1920 [(set (pc)
1921 (if_then_else (match_operator 1 "comparison_operator"
1922 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1923 (const_int 0)])
1924 (label_ref (match_operand 2 "" ""))
1925 (pc)))]
1926 ""
1927 "*
1928 {
1929 return output_cbranch (operands[1], 2, 0,
1930 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1931 ! final_sequence, insn);
1932 }"
1933 [(set_attr "type" "branch")])
1934
1935 ;; XXX fpcmp nop braindamage
1936 (define_insn "*inverted_fp_branch"
1937 [(set (pc)
1938 (if_then_else (match_operator 1 "comparison_operator"
1939 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1940 (const_int 0)])
1941 (pc)
1942 (label_ref (match_operand 2 "" ""))))]
1943 ""
1944 "*
1945 {
1946 return output_cbranch (operands[1], 2, 1,
1947 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1948 ! final_sequence, insn);
1949 }"
1950 [(set_attr "type" "branch")])
1951
1952 ;; XXX fpcmp nop braindamage
1953 (define_insn "*normal_fpe_branch"
1954 [(set (pc)
1955 (if_then_else (match_operator 1 "comparison_operator"
1956 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1957 (const_int 0)])
1958 (label_ref (match_operand 2 "" ""))
1959 (pc)))]
1960 ""
1961 "*
1962 {
1963 return output_cbranch (operands[1], 2, 0,
1964 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1965 ! final_sequence, insn);
1966 }"
1967 [(set_attr "type" "branch")])
1968
1969 ;; XXX fpcmp nop braindamage
1970 (define_insn "*inverted_fpe_branch"
1971 [(set (pc)
1972 (if_then_else (match_operator 1 "comparison_operator"
1973 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1974 (const_int 0)])
1975 (pc)
1976 (label_ref (match_operand 2 "" ""))))]
1977 ""
1978 "*
1979 {
1980 return output_cbranch (operands[1], 2, 1,
1981 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1982 ! final_sequence, insn);
1983 }"
1984 [(set_attr "type" "branch")])
1985
1986 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1987 ;; in the architecture.
1988
1989 ;; There are no 32 bit brreg insns.
1990
1991 ;; XXX
1992 (define_insn "*normal_int_branch_sp64"
1993 [(set (pc)
1994 (if_then_else (match_operator 0 "v9_regcmp_op"
1995 [(match_operand:DI 1 "register_operand" "r")
1996 (const_int 0)])
1997 (label_ref (match_operand 2 "" ""))
1998 (pc)))]
1999 "TARGET_ARCH64"
2000 "*
2001 {
2002 return output_v9branch (operands[0], 1, 2, 0,
2003 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2004 ! final_sequence, insn);
2005 }"
2006 [(set_attr "type" "branch")])
2007
2008 ;; XXX
2009 (define_insn "*inverted_int_branch_sp64"
2010 [(set (pc)
2011 (if_then_else (match_operator 0 "v9_regcmp_op"
2012 [(match_operand:DI 1 "register_operand" "r")
2013 (const_int 0)])
2014 (pc)
2015 (label_ref (match_operand 2 "" ""))))]
2016 "TARGET_ARCH64"
2017 "*
2018 {
2019 return output_v9branch (operands[0], 1, 2, 1,
2020 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2021 ! final_sequence, insn);
2022 }"
2023 [(set_attr "type" "branch")])
2024 \f
2025 ;; Load program counter insns.
2026
2027 (define_insn "get_pc"
2028 [(clobber (reg:SI 15))
2029 (set (match_operand 0 "register_operand" "=r")
2030 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2031 "flag_pic && REGNO (operands[0]) == 23"
2032 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2033 [(set_attr "type" "multi")
2034 (set_attr "length" "3")])
2035
2036 ;; Currently unused...
2037 ;; (define_insn "get_pc_via_rdpc"
2038 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2039 ;; "TARGET_V9"
2040 ;; "rd\\t%%pc, %0"
2041 ;; [(set_attr "type" "misc")])
2042
2043 \f
2044 ;; Move instructions
2045
2046 (define_expand "movqi"
2047 [(set (match_operand:QI 0 "general_operand" "")
2048 (match_operand:QI 1 "general_operand" ""))]
2049 ""
2050 "
2051 {
2052 /* Working with CONST_INTs is easier, so convert
2053 a double if needed. */
2054 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2055 {
2056 operands[1] = GEN_INT (trunc_int_for_mode
2057 (CONST_DOUBLE_LOW (operands[1]), QImode));
2058 }
2059
2060 /* Handle sets of MEM first. */
2061 if (GET_CODE (operands[0]) == MEM)
2062 {
2063 if (reg_or_0_operand (operands[1], QImode))
2064 goto movqi_is_ok;
2065
2066 if (! reload_in_progress)
2067 {
2068 operands[0] = validize_mem (operands[0]);
2069 operands[1] = force_reg (QImode, operands[1]);
2070 }
2071 }
2072
2073 /* Fixup PIC cases. */
2074 if (flag_pic)
2075 {
2076 if (CONSTANT_P (operands[1])
2077 && pic_address_needs_scratch (operands[1]))
2078 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2079
2080 if (symbolic_operand (operands[1], QImode))
2081 {
2082 operands[1] = legitimize_pic_address (operands[1],
2083 QImode,
2084 (reload_in_progress ?
2085 operands[0] :
2086 NULL_RTX));
2087 goto movqi_is_ok;
2088 }
2089 }
2090
2091 /* All QI constants require only one insn, so proceed. */
2092
2093 movqi_is_ok:
2094 ;
2095 }")
2096
2097 (define_insn "*movqi_insn"
2098 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2099 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2100 "(register_operand (operands[0], QImode)
2101 || reg_or_0_operand (operands[1], QImode))"
2102 "@
2103 mov\\t%1, %0
2104 ldub\\t%1, %0
2105 stb\\t%r1, %0"
2106 [(set_attr "type" "*,load,store")])
2107
2108 (define_expand "movhi"
2109 [(set (match_operand:HI 0 "general_operand" "")
2110 (match_operand:HI 1 "general_operand" ""))]
2111 ""
2112 "
2113 {
2114 /* Working with CONST_INTs is easier, so convert
2115 a double if needed. */
2116 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2117 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2118
2119 /* Handle sets of MEM first. */
2120 if (GET_CODE (operands[0]) == MEM)
2121 {
2122 if (reg_or_0_operand (operands[1], HImode))
2123 goto movhi_is_ok;
2124
2125 if (! reload_in_progress)
2126 {
2127 operands[0] = validize_mem (operands[0]);
2128 operands[1] = force_reg (HImode, operands[1]);
2129 }
2130 }
2131
2132 /* Fixup PIC cases. */
2133 if (flag_pic)
2134 {
2135 if (CONSTANT_P (operands[1])
2136 && pic_address_needs_scratch (operands[1]))
2137 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2138
2139 if (symbolic_operand (operands[1], HImode))
2140 {
2141 operands[1] = legitimize_pic_address (operands[1],
2142 HImode,
2143 (reload_in_progress ?
2144 operands[0] :
2145 NULL_RTX));
2146 goto movhi_is_ok;
2147 }
2148 }
2149
2150 /* This makes sure we will not get rematched due to splittage. */
2151 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2152 ;
2153 else if (CONSTANT_P (operands[1])
2154 && GET_CODE (operands[1]) != HIGH
2155 && GET_CODE (operands[1]) != LO_SUM)
2156 {
2157 sparc_emit_set_const32 (operands[0], operands[1]);
2158 DONE;
2159 }
2160 movhi_is_ok:
2161 ;
2162 }")
2163
2164 (define_insn "*movhi_const64_special"
2165 [(set (match_operand:HI 0 "register_operand" "=r")
2166 (match_operand:HI 1 "const64_high_operand" ""))]
2167 "TARGET_ARCH64"
2168 "sethi\\t%%hi(%a1), %0")
2169
2170 (define_insn "*movhi_insn"
2171 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2172 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2173 "(register_operand (operands[0], HImode)
2174 || reg_or_0_operand (operands[1], HImode))"
2175 "@
2176 mov\\t%1, %0
2177 sethi\\t%%hi(%a1), %0
2178 lduh\\t%1, %0
2179 sth\\t%r1, %0"
2180 [(set_attr "type" "*,*,load,store")])
2181
2182 ;; We always work with constants here.
2183 (define_insn "*movhi_lo_sum"
2184 [(set (match_operand:HI 0 "register_operand" "=r")
2185 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2186 (match_operand:HI 2 "arith_operand" "I")))]
2187 ""
2188 "or\\t%1, %2, %0")
2189
2190 (define_expand "movsi"
2191 [(set (match_operand:SI 0 "general_operand" "")
2192 (match_operand:SI 1 "general_operand" ""))]
2193 ""
2194 "
2195 {
2196 /* Working with CONST_INTs is easier, so convert
2197 a double if needed. */
2198 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2199 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2200
2201 /* Handle sets of MEM first. */
2202 if (GET_CODE (operands[0]) == MEM)
2203 {
2204 if (reg_or_0_operand (operands[1], SImode))
2205 goto movsi_is_ok;
2206
2207 if (! reload_in_progress)
2208 {
2209 operands[0] = validize_mem (operands[0]);
2210 operands[1] = force_reg (SImode, operands[1]);
2211 }
2212 }
2213
2214 /* Fixup PIC cases. */
2215 if (flag_pic)
2216 {
2217 if (CONSTANT_P (operands[1])
2218 && pic_address_needs_scratch (operands[1]))
2219 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2220
2221 if (GET_CODE (operands[1]) == LABEL_REF)
2222 {
2223 /* shit */
2224 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2225 DONE;
2226 }
2227
2228 if (symbolic_operand (operands[1], SImode))
2229 {
2230 operands[1] = legitimize_pic_address (operands[1],
2231 SImode,
2232 (reload_in_progress ?
2233 operands[0] :
2234 NULL_RTX));
2235 goto movsi_is_ok;
2236 }
2237 }
2238
2239 /* If we are trying to toss an integer constant into the
2240 FPU registers, force it into memory. */
2241 if (GET_CODE (operands[0]) == REG
2242 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2243 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2244 && CONSTANT_P (operands[1]))
2245 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2246 operands[1]));
2247
2248 /* This makes sure we will not get rematched due to splittage. */
2249 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2250 ;
2251 else if (CONSTANT_P (operands[1])
2252 && GET_CODE (operands[1]) != HIGH
2253 && GET_CODE (operands[1]) != LO_SUM)
2254 {
2255 sparc_emit_set_const32 (operands[0], operands[1]);
2256 DONE;
2257 }
2258 movsi_is_ok:
2259 ;
2260 }")
2261
2262 ;; This is needed to show CSE exactly which bits are set
2263 ;; in a 64-bit register by sethi instructions.
2264 (define_insn "*movsi_const64_special"
2265 [(set (match_operand:SI 0 "register_operand" "=r")
2266 (match_operand:SI 1 "const64_high_operand" ""))]
2267 "TARGET_ARCH64"
2268 "sethi\\t%%hi(%a1), %0")
2269
2270 (define_insn "*movsi_insn"
2271 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2272 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2273 "(register_operand (operands[0], SImode)
2274 || reg_or_0_operand (operands[1], SImode))"
2275 "@
2276 mov\\t%1, %0
2277 fmovs\\t%1, %0
2278 sethi\\t%%hi(%a1), %0
2279 clr\\t%0
2280 ld\\t%1, %0
2281 ld\\t%1, %0
2282 st\\t%r1, %0
2283 st\\t%1, %0
2284 fzeros\\t%0"
2285 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2286
2287 (define_insn "*movsi_lo_sum"
2288 [(set (match_operand:SI 0 "register_operand" "=r")
2289 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2290 (match_operand:SI 2 "immediate_operand" "in")))]
2291 ""
2292 "or\\t%1, %%lo(%a2), %0")
2293
2294 (define_insn "*movsi_high"
2295 [(set (match_operand:SI 0 "register_operand" "=r")
2296 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2297 ""
2298 "sethi\\t%%hi(%a1), %0")
2299
2300 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2301 ;; so that CSE won't optimize the address computation away.
2302 (define_insn "movsi_lo_sum_pic"
2303 [(set (match_operand:SI 0 "register_operand" "=r")
2304 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2305 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2306 "flag_pic"
2307 "or\\t%1, %%lo(%a2), %0")
2308
2309 (define_insn "movsi_high_pic"
2310 [(set (match_operand:SI 0 "register_operand" "=r")
2311 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2312 "flag_pic && check_pic (1)"
2313 "sethi\\t%%hi(%a1), %0")
2314
2315 (define_expand "movsi_pic_label_ref"
2316 [(set (match_dup 3) (high:SI
2317 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2318 (match_dup 2)] 5)))
2319 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2320 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2321 (set (match_operand:SI 0 "register_operand" "=r")
2322 (minus:SI (match_dup 5) (match_dup 4)))]
2323 "flag_pic"
2324 "
2325 {
2326 current_function_uses_pic_offset_table = 1;
2327 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2328 if (no_new_pseudos)
2329 {
2330 operands[3] = operands[0];
2331 operands[4] = operands[0];
2332 }
2333 else
2334 {
2335 operands[3] = gen_reg_rtx (SImode);
2336 operands[4] = gen_reg_rtx (SImode);
2337 }
2338 operands[5] = pic_offset_table_rtx;
2339 }")
2340
2341 (define_insn "*movsi_high_pic_label_ref"
2342 [(set (match_operand:SI 0 "register_operand" "=r")
2343 (high:SI
2344 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2345 (match_operand:SI 2 "" "")] 5)))]
2346 "flag_pic"
2347 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2348
2349 (define_insn "*movsi_lo_sum_pic_label_ref"
2350 [(set (match_operand:SI 0 "register_operand" "=r")
2351 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2352 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2353 (match_operand:SI 3 "" "")] 5)))]
2354 "flag_pic"
2355 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2356
2357 (define_expand "movdi"
2358 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2359 (match_operand:DI 1 "general_operand" ""))]
2360 ""
2361 "
2362 {
2363 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2364 if (GET_CODE (operands[1]) == CONST_DOUBLE
2365 #if HOST_BITS_PER_WIDE_INT == 32
2366 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2367 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2368 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2369 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2370 #endif
2371 )
2372 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2373
2374 /* Handle MEM cases first. */
2375 if (GET_CODE (operands[0]) == MEM)
2376 {
2377 /* If it's a REG, we can always do it.
2378 The const zero case is more complex, on v9
2379 we can always perform it. */
2380 if (register_operand (operands[1], DImode)
2381 || (TARGET_V9
2382 && (operands[1] == const0_rtx)))
2383 goto movdi_is_ok;
2384
2385 if (! reload_in_progress)
2386 {
2387 operands[0] = validize_mem (operands[0]);
2388 operands[1] = force_reg (DImode, operands[1]);
2389 }
2390 }
2391
2392 if (flag_pic)
2393 {
2394 if (CONSTANT_P (operands[1])
2395 && pic_address_needs_scratch (operands[1]))
2396 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2397
2398 if (GET_CODE (operands[1]) == LABEL_REF)
2399 {
2400 if (! TARGET_ARCH64)
2401 abort ();
2402 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2403 DONE;
2404 }
2405
2406 if (symbolic_operand (operands[1], DImode))
2407 {
2408 operands[1] = legitimize_pic_address (operands[1],
2409 DImode,
2410 (reload_in_progress ?
2411 operands[0] :
2412 NULL_RTX));
2413 goto movdi_is_ok;
2414 }
2415 }
2416
2417 /* If we are trying to toss an integer constant into the
2418 FPU registers, force it into memory. */
2419 if (GET_CODE (operands[0]) == REG
2420 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2421 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2422 && CONSTANT_P (operands[1]))
2423 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2424 operands[1]));
2425
2426 /* This makes sure we will not get rematched due to splittage. */
2427 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2428 ;
2429 else if (TARGET_ARCH64
2430 && CONSTANT_P (operands[1])
2431 && GET_CODE (operands[1]) != HIGH
2432 && GET_CODE (operands[1]) != LO_SUM)
2433 {
2434 sparc_emit_set_const64 (operands[0], operands[1]);
2435 DONE;
2436 }
2437
2438 movdi_is_ok:
2439 ;
2440 }")
2441
2442 ;; Be careful, fmovd does not exist when !arch64.
2443 ;; We match MEM moves directly when we have correct even
2444 ;; numbered registers, but fall into splits otherwise.
2445 ;; The constraint ordering here is really important to
2446 ;; avoid insane problems in reload, especially for patterns
2447 ;; of the form:
2448 ;;
2449 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2450 ;; (const_int -5016)))
2451 ;; (reg:DI 2 %g2))
2452 ;;
2453
2454 (define_insn "*movdi_insn_sp32_v9"
2455 [(set (match_operand:DI 0 "nonimmediate_operand"
2456 "=m,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2457 (match_operand:DI 1 "input_operand"
2458 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2459 "! TARGET_ARCH64 && TARGET_V9
2460 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2461 "@
2462 stx\\t%%g0, %0
2463 std\\t%1, %0
2464 ldd\\t%1, %0
2465 #
2466 #
2467 #
2468 #
2469 std\\t%1, %0
2470 ldd\\t%1, %0
2471 #
2472 #
2473 #"
2474 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2475 (set_attr "length" "*,*,*,2,2,2,2,*,*,2,2,2")])
2476
2477 (define_insn "*movdi_insn_sp32"
2478 [(set (match_operand:DI 0 "nonimmediate_operand"
2479 "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2480 (match_operand:DI 1 "input_operand"
2481 " U,T,r,o,i,r, f, T, o, f, f"))]
2482 "! TARGET_ARCH64
2483 && (register_operand (operands[0], DImode)
2484 || register_operand (operands[1], DImode))"
2485 "@
2486 std\\t%1, %0
2487 ldd\\t%1, %0
2488 #
2489 #
2490 #
2491 #
2492 std\\t%1, %0
2493 ldd\\t%1, %0
2494 #
2495 #
2496 #"
2497 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2498 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2499
2500 ;; The following are generated by sparc_emit_set_const64
2501 (define_insn "*movdi_sp64_dbl"
2502 [(set (match_operand:DI 0 "register_operand" "=r")
2503 (match_operand:DI 1 "const64_operand" ""))]
2504 "(TARGET_ARCH64
2505 && HOST_BITS_PER_WIDE_INT != 64)"
2506 "mov\\t%1, %0")
2507
2508 ;; This is needed to show CSE exactly which bits are set
2509 ;; in a 64-bit register by sethi instructions.
2510 (define_insn "*movdi_const64_special"
2511 [(set (match_operand:DI 0 "register_operand" "=r")
2512 (match_operand:DI 1 "const64_high_operand" ""))]
2513 "TARGET_ARCH64"
2514 "sethi\\t%%hi(%a1), %0")
2515
2516 (define_insn "*movdi_insn_sp64_novis"
2517 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2518 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,m,e"))]
2519 "TARGET_ARCH64 && ! TARGET_VIS
2520 && (register_operand (operands[0], DImode)
2521 || reg_or_0_operand (operands[1], DImode))"
2522 "@
2523 mov\\t%1, %0
2524 sethi\\t%%hi(%a1), %0
2525 clr\\t%0
2526 ldx\\t%1, %0
2527 stx\\t%r1, %0
2528 fmovd\\t%1, %0
2529 ldd\\t%1, %0
2530 std\\t%1, %0"
2531 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2532 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2533
2534 (define_insn "*movdi_insn_sp64_vis"
2535 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2536 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,m,e,J"))]
2537 "TARGET_ARCH64 && TARGET_VIS &&
2538 (register_operand (operands[0], DImode)
2539 || reg_or_0_operand (operands[1], DImode))"
2540 "@
2541 mov\\t%1, %0
2542 sethi\\t%%hi(%a1), %0
2543 clr\\t%0
2544 ldx\\t%1, %0
2545 stx\\t%r1, %0
2546 fmovd\\t%1, %0
2547 ldd\\t%1, %0
2548 std\\t%1, %0
2549 fzero\\t%0"
2550 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2551 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2552
2553 (define_expand "movdi_pic_label_ref"
2554 [(set (match_dup 3) (high:DI
2555 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2556 (match_dup 2)] 5)))
2557 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2558 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2559 (set (match_operand:DI 0 "register_operand" "=r")
2560 (minus:DI (match_dup 5) (match_dup 4)))]
2561 "TARGET_ARCH64 && flag_pic"
2562 "
2563 {
2564 current_function_uses_pic_offset_table = 1;
2565 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2566 if (no_new_pseudos)
2567 {
2568 operands[3] = operands[0];
2569 operands[4] = operands[0];
2570 }
2571 else
2572 {
2573 operands[3] = gen_reg_rtx (DImode);
2574 operands[4] = gen_reg_rtx (DImode);
2575 }
2576 operands[5] = pic_offset_table_rtx;
2577 }")
2578
2579 (define_insn "*movdi_high_pic_label_ref"
2580 [(set (match_operand:DI 0 "register_operand" "=r")
2581 (high:DI
2582 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2583 (match_operand:DI 2 "" "")] 5)))]
2584 "TARGET_ARCH64 && flag_pic"
2585 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2586
2587 (define_insn "*movdi_lo_sum_pic_label_ref"
2588 [(set (match_operand:DI 0 "register_operand" "=r")
2589 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2590 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2591 (match_operand:DI 3 "" "")] 5)))]
2592 "TARGET_ARCH64 && flag_pic"
2593 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2594
2595 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2596 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2597
2598 (define_insn "movdi_lo_sum_pic"
2599 [(set (match_operand:DI 0 "register_operand" "=r")
2600 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2601 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2602 "TARGET_ARCH64 && flag_pic"
2603 "or\\t%1, %%lo(%a2), %0")
2604
2605 (define_insn "movdi_high_pic"
2606 [(set (match_operand:DI 0 "register_operand" "=r")
2607 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2608 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2609 "sethi\\t%%hi(%a1), %0")
2610
2611 (define_insn "*sethi_di_medlow_embmedany_pic"
2612 [(set (match_operand:DI 0 "register_operand" "=r")
2613 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2614 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2615 "sethi\\t%%hi(%a1), %0")
2616
2617 (define_insn "*sethi_di_medlow"
2618 [(set (match_operand:DI 0 "register_operand" "=r")
2619 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2620 "TARGET_CM_MEDLOW && check_pic (1)"
2621 "sethi\\t%%hi(%a1), %0")
2622
2623 (define_insn "*losum_di_medlow"
2624 [(set (match_operand:DI 0 "register_operand" "=r")
2625 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2626 (match_operand:DI 2 "symbolic_operand" "")))]
2627 "TARGET_CM_MEDLOW"
2628 "or\\t%1, %%lo(%a2), %0")
2629
2630 (define_insn "seth44"
2631 [(set (match_operand:DI 0 "register_operand" "=r")
2632 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2633 "TARGET_CM_MEDMID"
2634 "sethi\\t%%h44(%a1), %0")
2635
2636 (define_insn "setm44"
2637 [(set (match_operand:DI 0 "register_operand" "=r")
2638 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2639 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2640 "TARGET_CM_MEDMID"
2641 "or\\t%1, %%m44(%a2), %0")
2642
2643 (define_insn "setl44"
2644 [(set (match_operand:DI 0 "register_operand" "=r")
2645 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2646 (match_operand:DI 2 "symbolic_operand" "")))]
2647 "TARGET_CM_MEDMID"
2648 "or\\t%1, %%l44(%a2), %0")
2649
2650 (define_insn "sethh"
2651 [(set (match_operand:DI 0 "register_operand" "=r")
2652 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2653 "TARGET_CM_MEDANY"
2654 "sethi\\t%%hh(%a1), %0")
2655
2656 (define_insn "setlm"
2657 [(set (match_operand:DI 0 "register_operand" "=r")
2658 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2659 "TARGET_CM_MEDANY"
2660 "sethi\\t%%lm(%a1), %0")
2661
2662 (define_insn "sethm"
2663 [(set (match_operand:DI 0 "register_operand" "=r")
2664 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2665 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2666 "TARGET_CM_MEDANY"
2667 "or\\t%1, %%hm(%a2), %0")
2668
2669 (define_insn "setlo"
2670 [(set (match_operand:DI 0 "register_operand" "=r")
2671 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2672 (match_operand:DI 2 "symbolic_operand" "")))]
2673 "TARGET_CM_MEDANY"
2674 "or\\t%1, %%lo(%a2), %0")
2675
2676 (define_insn "embmedany_sethi"
2677 [(set (match_operand:DI 0 "register_operand" "=r")
2678 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2679 "TARGET_CM_EMBMEDANY && check_pic (1)"
2680 "sethi\\t%%hi(%a1), %0")
2681
2682 (define_insn "embmedany_losum"
2683 [(set (match_operand:DI 0 "register_operand" "=r")
2684 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2685 (match_operand:DI 2 "data_segment_operand" "")))]
2686 "TARGET_CM_EMBMEDANY"
2687 "add\\t%1, %%lo(%a2), %0")
2688
2689 (define_insn "embmedany_brsum"
2690 [(set (match_operand:DI 0 "register_operand" "=r")
2691 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2692 "TARGET_CM_EMBMEDANY"
2693 "add\\t%1, %_, %0")
2694
2695 (define_insn "embmedany_textuhi"
2696 [(set (match_operand:DI 0 "register_operand" "=r")
2697 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2698 "TARGET_CM_EMBMEDANY && check_pic (1)"
2699 "sethi\\t%%uhi(%a1), %0")
2700
2701 (define_insn "embmedany_texthi"
2702 [(set (match_operand:DI 0 "register_operand" "=r")
2703 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2704 "TARGET_CM_EMBMEDANY && check_pic (1)"
2705 "sethi\\t%%hi(%a1), %0")
2706
2707 (define_insn "embmedany_textulo"
2708 [(set (match_operand:DI 0 "register_operand" "=r")
2709 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2710 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2711 "TARGET_CM_EMBMEDANY"
2712 "or\\t%1, %%ulo(%a2), %0")
2713
2714 (define_insn "embmedany_textlo"
2715 [(set (match_operand:DI 0 "register_operand" "=r")
2716 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2717 (match_operand:DI 2 "text_segment_operand" "")))]
2718 "TARGET_CM_EMBMEDANY"
2719 "or\\t%1, %%lo(%a2), %0")
2720
2721 ;; Now some patterns to help reload out a bit.
2722 (define_expand "reload_indi"
2723 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2724 (match_operand:DI 1 "immediate_operand" "")
2725 (match_operand:TI 2 "register_operand" "=&r")])]
2726 "(TARGET_CM_MEDANY
2727 || TARGET_CM_EMBMEDANY)
2728 && ! flag_pic"
2729 "
2730 {
2731 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2732 DONE;
2733 }")
2734
2735 (define_expand "reload_outdi"
2736 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2737 (match_operand:DI 1 "immediate_operand" "")
2738 (match_operand:TI 2 "register_operand" "=&r")])]
2739 "(TARGET_CM_MEDANY
2740 || TARGET_CM_EMBMEDANY)
2741 && ! flag_pic"
2742 "
2743 {
2744 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2745 DONE;
2746 }")
2747
2748 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2749 (define_split
2750 [(set (match_operand:DI 0 "register_operand" "")
2751 (match_operand:DI 1 "const_int_operand" ""))]
2752 "! TARGET_ARCH64 && reload_completed"
2753 [(clobber (const_int 0))]
2754 "
2755 {
2756 #if HOST_BITS_PER_WIDE_INT == 32
2757 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2758 (INTVAL (operands[1]) < 0) ?
2759 constm1_rtx :
2760 const0_rtx));
2761 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2762 operands[1]));
2763 #else
2764 unsigned int low, high;
2765
2766 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2767 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2768 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2769
2770 /* Slick... but this trick loses if this subreg constant part
2771 can be done in one insn. */
2772 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2773 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2774 gen_highpart (SImode, operands[0])));
2775 else
2776 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2777 #endif
2778 DONE;
2779 }")
2780
2781 (define_split
2782 [(set (match_operand:DI 0 "register_operand" "")
2783 (match_operand:DI 1 "const_double_operand" ""))]
2784 "! TARGET_ARCH64 && reload_completed"
2785 [(clobber (const_int 0))]
2786 "
2787 {
2788 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2789 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2790
2791 /* Slick... but this trick loses if this subreg constant part
2792 can be done in one insn. */
2793 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2794 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2795 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2796 {
2797 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2798 gen_highpart (SImode, operands[0])));
2799 }
2800 else
2801 {
2802 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2803 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2804 }
2805 DONE;
2806 }")
2807
2808 (define_split
2809 [(set (match_operand:DI 0 "register_operand" "")
2810 (match_operand:DI 1 "register_operand" ""))]
2811 "! TARGET_ARCH64 && reload_completed"
2812 [(clobber (const_int 0))]
2813 "
2814 {
2815 rtx set_dest = operands[0];
2816 rtx set_src = operands[1];
2817 rtx dest1, dest2;
2818 rtx src1, src2;
2819
2820 dest1 = gen_highpart (SImode, set_dest);
2821 dest2 = gen_lowpart (SImode, set_dest);
2822 src1 = gen_highpart (SImode, set_src);
2823 src2 = gen_lowpart (SImode, set_src);
2824
2825 /* Now emit using the real source and destination we found, swapping
2826 the order if we detect overlap. */
2827 if (reg_overlap_mentioned_p (dest1, src2))
2828 {
2829 emit_insn (gen_movsi (dest2, src2));
2830 emit_insn (gen_movsi (dest1, src1));
2831 }
2832 else
2833 {
2834 emit_insn (gen_movsi (dest1, src1));
2835 emit_insn (gen_movsi (dest2, src2));
2836 }
2837 DONE;
2838 }")
2839
2840 ;; Now handle the cases of memory moves from/to non-even
2841 ;; DI mode register pairs.
2842 (define_split
2843 [(set (match_operand:DI 0 "register_operand" "")
2844 (match_operand:DI 1 "memory_operand" ""))]
2845 "(! TARGET_ARCH64
2846 && reload_completed
2847 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2848 [(clobber (const_int 0))]
2849 "
2850 {
2851 rtx word0 = adjust_address (operands[1], SImode, 0);
2852 rtx word1 = adjust_address (operands[1], SImode, 4);
2853 rtx high_part = gen_highpart (SImode, operands[0]);
2854 rtx low_part = gen_lowpart (SImode, operands[0]);
2855
2856 if (reg_overlap_mentioned_p (high_part, word1))
2857 {
2858 emit_insn (gen_movsi (low_part, word1));
2859 emit_insn (gen_movsi (high_part, word0));
2860 }
2861 else
2862 {
2863 emit_insn (gen_movsi (high_part, word0));
2864 emit_insn (gen_movsi (low_part, word1));
2865 }
2866 DONE;
2867 }")
2868
2869 (define_split
2870 [(set (match_operand:DI 0 "memory_operand" "")
2871 (match_operand:DI 1 "register_operand" ""))]
2872 "(! TARGET_ARCH64
2873 && reload_completed
2874 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2875 [(clobber (const_int 0))]
2876 "
2877 {
2878 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2879 gen_highpart (SImode, operands[1])));
2880 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2881 gen_lowpart (SImode, operands[1])));
2882 DONE;
2883 }")
2884
2885 \f
2886 ;; Floating point move insns
2887
2888 (define_insn "*movsf_insn_novis"
2889 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2890 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2891 "(TARGET_FPU && ! TARGET_VIS)
2892 && (register_operand (operands[0], SFmode)
2893 || register_operand (operands[1], SFmode)
2894 || fp_zero_operand (operands[1], SFmode))"
2895 "*
2896 {
2897 if (GET_CODE (operands[1]) == CONST_DOUBLE
2898 && (which_alternative == 2
2899 || which_alternative == 3
2900 || which_alternative == 4))
2901 {
2902 REAL_VALUE_TYPE r;
2903 long i;
2904
2905 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2906 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2907 operands[1] = GEN_INT (i);
2908 }
2909
2910 switch (which_alternative)
2911 {
2912 case 0:
2913 return \"fmovs\\t%1, %0\";
2914 case 1:
2915 return \"clr\\t%0\";
2916 case 2:
2917 return \"sethi\\t%%hi(%a1), %0\";
2918 case 3:
2919 return \"mov\\t%1, %0\";
2920 case 4:
2921 return \"#\";
2922 case 5:
2923 case 6:
2924 return \"ld\\t%1, %0\";
2925 case 7:
2926 case 8:
2927 return \"st\\t%r1, %0\";
2928 default:
2929 abort();
2930 }
2931 }"
2932 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2933
2934 (define_insn "*movsf_insn_vis"
2935 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2936 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2937 "(TARGET_FPU && TARGET_VIS)
2938 && (register_operand (operands[0], SFmode)
2939 || register_operand (operands[1], SFmode)
2940 || fp_zero_operand (operands[1], SFmode))"
2941 "*
2942 {
2943 if (GET_CODE (operands[1]) == CONST_DOUBLE
2944 && (which_alternative == 3
2945 || which_alternative == 4
2946 || which_alternative == 5))
2947 {
2948 REAL_VALUE_TYPE r;
2949 long i;
2950
2951 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2952 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2953 operands[1] = GEN_INT (i);
2954 }
2955
2956 switch (which_alternative)
2957 {
2958 case 0:
2959 return \"fmovs\\t%1, %0\";
2960 case 1:
2961 return \"fzeros\\t%0\";
2962 case 2:
2963 return \"clr\\t%0\";
2964 case 3:
2965 return \"sethi\\t%%hi(%a1), %0\";
2966 case 4:
2967 return \"mov\\t%1, %0\";
2968 case 5:
2969 return \"#\";
2970 case 6:
2971 case 7:
2972 return \"ld\\t%1, %0\";
2973 case 8:
2974 case 9:
2975 return \"st\\t%r1, %0\";
2976 default:
2977 abort();
2978 }
2979 }"
2980 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2981
2982 ;; Exactly the same as above, except that all `f' cases are deleted.
2983 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2984 ;; when -mno-fpu.
2985
2986 (define_insn "*movsf_no_f_insn"
2987 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2988 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2989 "! TARGET_FPU
2990 && (register_operand (operands[0], SFmode)
2991 || register_operand (operands[1], SFmode)
2992 || fp_zero_operand (operands[1], SFmode))"
2993 "*
2994 {
2995 if (GET_CODE (operands[1]) == CONST_DOUBLE
2996 && (which_alternative == 1
2997 || which_alternative == 2
2998 || which_alternative == 3))
2999 {
3000 REAL_VALUE_TYPE r;
3001 long i;
3002
3003 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3004 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3005 operands[1] = GEN_INT (i);
3006 }
3007
3008 switch (which_alternative)
3009 {
3010 case 0:
3011 return \"clr\\t%0\";
3012 case 1:
3013 return \"sethi\\t%%hi(%a1), %0\";
3014 case 2:
3015 return \"mov\\t%1, %0\";
3016 case 3:
3017 return \"#\";
3018 case 4:
3019 return \"ld\\t%1, %0\";
3020 case 5:
3021 return \"st\\t%r1, %0\";
3022 default:
3023 abort();
3024 }
3025 }"
3026 [(set_attr "type" "*,*,*,*,load,store")])
3027
3028 (define_insn "*movsf_lo_sum"
3029 [(set (match_operand:SF 0 "register_operand" "=r")
3030 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3031 (match_operand:SF 2 "const_double_operand" "S")))]
3032 "fp_high_losum_p (operands[2])"
3033 "*
3034 {
3035 REAL_VALUE_TYPE r;
3036 long i;
3037
3038 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3039 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3040 operands[2] = GEN_INT (i);
3041 return \"or\\t%1, %%lo(%a2), %0\";
3042 }")
3043
3044 (define_insn "*movsf_high"
3045 [(set (match_operand:SF 0 "register_operand" "=r")
3046 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3047 "fp_high_losum_p (operands[1])"
3048 "*
3049 {
3050 REAL_VALUE_TYPE r;
3051 long i;
3052
3053 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3054 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3055 operands[1] = GEN_INT (i);
3056 return \"sethi\\t%%hi(%1), %0\";
3057 }")
3058
3059 (define_split
3060 [(set (match_operand:SF 0 "register_operand" "")
3061 (match_operand:SF 1 "const_double_operand" ""))]
3062 "fp_high_losum_p (operands[1])
3063 && (GET_CODE (operands[0]) == REG
3064 && REGNO (operands[0]) < 32)"
3065 [(set (match_dup 0) (high:SF (match_dup 1)))
3066 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3067
3068 (define_expand "movsf"
3069 [(set (match_operand:SF 0 "general_operand" "")
3070 (match_operand:SF 1 "general_operand" ""))]
3071 ""
3072 "
3073 {
3074 /* Force SFmode constants into memory. */
3075 if (GET_CODE (operands[0]) == REG
3076 && CONSTANT_P (operands[1]))
3077 {
3078 /* emit_group_store will send such bogosity to us when it is
3079 not storing directly into memory. So fix this up to avoid
3080 crashes in output_constant_pool. */
3081 if (operands [1] == const0_rtx)
3082 operands[1] = CONST0_RTX (SFmode);
3083
3084 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3085 goto movsf_is_ok;
3086
3087 /* We are able to build any SF constant in integer registers
3088 with at most 2 instructions. */
3089 if (REGNO (operands[0]) < 32)
3090 goto movsf_is_ok;
3091
3092 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3093 operands[1]));
3094 }
3095
3096 /* Handle sets of MEM first. */
3097 if (GET_CODE (operands[0]) == MEM)
3098 {
3099 if (register_operand (operands[1], SFmode)
3100 || fp_zero_operand (operands[1], SFmode))
3101 goto movsf_is_ok;
3102
3103 if (! reload_in_progress)
3104 {
3105 operands[0] = validize_mem (operands[0]);
3106 operands[1] = force_reg (SFmode, operands[1]);
3107 }
3108 }
3109
3110 /* Fixup PIC cases. */
3111 if (flag_pic)
3112 {
3113 if (CONSTANT_P (operands[1])
3114 && pic_address_needs_scratch (operands[1]))
3115 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3116
3117 if (symbolic_operand (operands[1], SFmode))
3118 {
3119 operands[1] = legitimize_pic_address (operands[1],
3120 SFmode,
3121 (reload_in_progress ?
3122 operands[0] :
3123 NULL_RTX));
3124 }
3125 }
3126
3127 movsf_is_ok:
3128 ;
3129 }")
3130
3131 (define_expand "movdf"
3132 [(set (match_operand:DF 0 "general_operand" "")
3133 (match_operand:DF 1 "general_operand" ""))]
3134 ""
3135 "
3136 {
3137 /* Force DFmode constants into memory. */
3138 if (GET_CODE (operands[0]) == REG
3139 && CONSTANT_P (operands[1]))
3140 {
3141 /* emit_group_store will send such bogosity to us when it is
3142 not storing directly into memory. So fix this up to avoid
3143 crashes in output_constant_pool. */
3144 if (operands [1] == const0_rtx)
3145 operands[1] = CONST0_RTX (DFmode);
3146
3147 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3148 && fp_zero_operand (operands[1], DFmode))
3149 goto movdf_is_ok;
3150
3151 /* We are able to build any DF constant in integer registers. */
3152 if (REGNO (operands[0]) < 32
3153 && (reload_completed || reload_in_progress))
3154 goto movdf_is_ok;
3155
3156 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3157 operands[1]));
3158 }
3159
3160 /* Handle MEM cases first. */
3161 if (GET_CODE (operands[0]) == MEM)
3162 {
3163 if (register_operand (operands[1], DFmode)
3164 || fp_zero_operand (operands[1], DFmode))
3165 goto movdf_is_ok;
3166
3167 if (! reload_in_progress)
3168 {
3169 operands[0] = validize_mem (operands[0]);
3170 operands[1] = force_reg (DFmode, operands[1]);
3171 }
3172 }
3173
3174 /* Fixup PIC cases. */
3175 if (flag_pic)
3176 {
3177 if (CONSTANT_P (operands[1])
3178 && pic_address_needs_scratch (operands[1]))
3179 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3180
3181 if (symbolic_operand (operands[1], DFmode))
3182 {
3183 operands[1] = legitimize_pic_address (operands[1],
3184 DFmode,
3185 (reload_in_progress ?
3186 operands[0] :
3187 NULL_RTX));
3188 }
3189 }
3190
3191 movdf_is_ok:
3192 ;
3193 }")
3194
3195 ;; Be careful, fmovd does not exist when !v9.
3196 (define_insn "*movdf_insn_sp32"
3197 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3198 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3199 "TARGET_FPU
3200 && ! TARGET_V9
3201 && (register_operand (operands[0], DFmode)
3202 || register_operand (operands[1], DFmode)
3203 || fp_zero_operand (operands[1], DFmode))"
3204 "@
3205 ldd\\t%1, %0
3206 std\\t%1, %0
3207 ldd\\t%1, %0
3208 std\\t%1, %0
3209 #
3210 #
3211 #
3212 #
3213 #
3214 #"
3215 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3216 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3217
3218 (define_insn "*movdf_no_e_insn_sp32"
3219 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3220 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3221 "! TARGET_FPU
3222 && ! TARGET_V9
3223 && ! TARGET_ARCH64
3224 && (register_operand (operands[0], DFmode)
3225 || register_operand (operands[1], DFmode)
3226 || fp_zero_operand (operands[1], DFmode))"
3227 "@
3228 ldd\\t%1, %0
3229 std\\t%1, %0
3230 #
3231 #
3232 #"
3233 [(set_attr "type" "load,store,*,*,*")
3234 (set_attr "length" "*,*,2,2,2")])
3235
3236 (define_insn "*movdf_no_e_insn_v9_sp32"
3237 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3238 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3239 "! TARGET_FPU
3240 && TARGET_V9
3241 && ! TARGET_ARCH64
3242 && (register_operand (operands[0], DFmode)
3243 || register_operand (operands[1], DFmode)
3244 || fp_zero_operand (operands[1], DFmode))"
3245 "@
3246 ldd\\t%1, %0
3247 std\\t%1, %0
3248 stx\\t%r1, %0
3249 #
3250 #"
3251 [(set_attr "type" "load,store,store,*,*")
3252 (set_attr "length" "*,*,*,2,2")])
3253
3254 ;; We have available v9 double floats but not 64-bit
3255 ;; integer registers and no VIS.
3256 (define_insn "*movdf_insn_v9only_novis"
3257 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3258 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3259 "TARGET_FPU
3260 && TARGET_V9
3261 && ! TARGET_VIS
3262 && ! TARGET_ARCH64
3263 && (register_operand (operands[0], DFmode)
3264 || register_operand (operands[1], DFmode)
3265 || fp_zero_operand (operands[1], DFmode))"
3266 "@
3267 fmovd\\t%1, %0
3268 ldd\\t%1, %0
3269 stx\\t%r1, %0
3270 std\\t%1, %0
3271 ldd\\t%1, %0
3272 std\\t%1, %0
3273 #
3274 #
3275 #"
3276 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3277 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3278 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3279
3280 ;; We have available v9 double floats but not 64-bit
3281 ;; integer registers but we have VIS.
3282 (define_insn "*movdf_insn_v9only_vis"
3283 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3284 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3285 "TARGET_FPU
3286 && TARGET_VIS
3287 && ! TARGET_ARCH64
3288 && (register_operand (operands[0], DFmode)
3289 || register_operand (operands[1], DFmode)
3290 || fp_zero_operand (operands[1], DFmode))"
3291 "@
3292 fzero\\t%0
3293 fmovd\\t%1, %0
3294 ldd\\t%1, %0
3295 stx\\t%r1, %0
3296 std\\t%1, %0
3297 ldd\\t%1, %0
3298 std\\t%1, %0
3299 #
3300 #
3301 #"
3302 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3303 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3304 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3305
3306 ;; We have available both v9 double floats and 64-bit
3307 ;; integer registers. No VIS though.
3308 (define_insn "*movdf_insn_sp64_novis"
3309 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3310 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3311 "TARGET_FPU
3312 && ! TARGET_VIS
3313 && TARGET_ARCH64
3314 && (register_operand (operands[0], DFmode)
3315 || register_operand (operands[1], DFmode)
3316 || fp_zero_operand (operands[1], DFmode))"
3317 "@
3318 fmovd\\t%1, %0
3319 ldd\\t%1, %0
3320 std\\t%1, %0
3321 mov\\t%r1, %0
3322 ldx\\t%1, %0
3323 stx\\t%r1, %0
3324 #"
3325 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3326 (set_attr "length" "*,*,*,*,*,*,2")
3327 (set_attr "fptype" "double,*,*,*,*,*,*")])
3328
3329 ;; We have available both v9 double floats and 64-bit
3330 ;; integer registers. And we have VIS.
3331 (define_insn "*movdf_insn_sp64_vis"
3332 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3333 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3334 "TARGET_FPU
3335 && TARGET_VIS
3336 && TARGET_ARCH64
3337 && (register_operand (operands[0], DFmode)
3338 || register_operand (operands[1], DFmode)
3339 || fp_zero_operand (operands[1], DFmode))"
3340 "@
3341 fzero\\t%0
3342 fmovd\\t%1, %0
3343 ldd\\t%1, %0
3344 std\\t%1, %0
3345 mov\\t%r1, %0
3346 ldx\\t%1, %0
3347 stx\\t%r1, %0
3348 #"
3349 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3350 (set_attr "length" "*,*,*,*,*,*,*,2")
3351 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3352
3353 (define_insn "*movdf_no_e_insn_sp64"
3354 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3355 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3356 "! TARGET_FPU
3357 && TARGET_ARCH64
3358 && (register_operand (operands[0], DFmode)
3359 || register_operand (operands[1], DFmode)
3360 || fp_zero_operand (operands[1], DFmode))"
3361 "@
3362 mov\\t%1, %0
3363 ldx\\t%1, %0
3364 stx\\t%r1, %0"
3365 [(set_attr "type" "*,load,store")])
3366
3367 (define_split
3368 [(set (match_operand:DF 0 "register_operand" "")
3369 (match_operand:DF 1 "const_double_operand" ""))]
3370 "TARGET_FPU
3371 && (GET_CODE (operands[0]) == REG
3372 && REGNO (operands[0]) < 32)
3373 && ! fp_zero_operand(operands[1], DFmode)
3374 && reload_completed"
3375 [(clobber (const_int 0))]
3376 "
3377 {
3378 REAL_VALUE_TYPE r;
3379 long l[2];
3380
3381 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3382 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3383 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3384
3385 if (TARGET_ARCH64)
3386 {
3387 #if HOST_BITS_PER_WIDE_INT == 64
3388 HOST_WIDE_INT val;
3389
3390 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3391 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3392 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3393 #else
3394 emit_insn (gen_movdi (operands[0],
3395 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3396 #endif
3397 }
3398 else
3399 {
3400 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3401 GEN_INT (l[0])));
3402
3403 /* Slick... but this trick loses if this subreg constant part
3404 can be done in one insn. */
3405 if (l[1] == l[0]
3406 && !(SPARC_SETHI32_P (l[0])
3407 || SPARC_SIMM13_P (l[0])))
3408 {
3409 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3410 gen_highpart (SImode, operands[0])));
3411 }
3412 else
3413 {
3414 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3415 GEN_INT (l[1])));
3416 }
3417 }
3418 DONE;
3419 }")
3420
3421 ;; Ok, now the splits to handle all the multi insn and
3422 ;; mis-aligned memory address cases.
3423 ;; In these splits please take note that we must be
3424 ;; careful when V9 but not ARCH64 because the integer
3425 ;; register DFmode cases must be handled.
3426 (define_split
3427 [(set (match_operand:DF 0 "register_operand" "")
3428 (match_operand:DF 1 "register_operand" ""))]
3429 "(! TARGET_V9
3430 || (! TARGET_ARCH64
3431 && ((GET_CODE (operands[0]) == REG
3432 && REGNO (operands[0]) < 32)
3433 || (GET_CODE (operands[0]) == SUBREG
3434 && GET_CODE (SUBREG_REG (operands[0])) == REG
3435 && REGNO (SUBREG_REG (operands[0])) < 32))))
3436 && reload_completed"
3437 [(clobber (const_int 0))]
3438 "
3439 {
3440 rtx set_dest = operands[0];
3441 rtx set_src = operands[1];
3442 rtx dest1, dest2;
3443 rtx src1, src2;
3444
3445 dest1 = gen_highpart (SFmode, set_dest);
3446 dest2 = gen_lowpart (SFmode, set_dest);
3447 src1 = gen_highpart (SFmode, set_src);
3448 src2 = gen_lowpart (SFmode, set_src);
3449
3450 /* Now emit using the real source and destination we found, swapping
3451 the order if we detect overlap. */
3452 if (reg_overlap_mentioned_p (dest1, src2))
3453 {
3454 emit_insn (gen_movsf (dest2, src2));
3455 emit_insn (gen_movsf (dest1, src1));
3456 }
3457 else
3458 {
3459 emit_insn (gen_movsf (dest1, src1));
3460 emit_insn (gen_movsf (dest2, src2));
3461 }
3462 DONE;
3463 }")
3464
3465 (define_split
3466 [(set (match_operand:DF 0 "register_operand" "")
3467 (match_operand:DF 1 "memory_operand" ""))]
3468 "reload_completed
3469 && ! TARGET_ARCH64
3470 && (((REGNO (operands[0]) % 2) != 0)
3471 || ! mem_min_alignment (operands[1], 8))
3472 && offsettable_memref_p (operands[1])"
3473 [(clobber (const_int 0))]
3474 "
3475 {
3476 rtx word0 = adjust_address (operands[1], SFmode, 0);
3477 rtx word1 = adjust_address (operands[1], SFmode, 4);
3478
3479 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3480 {
3481 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3482 word1));
3483 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3484 word0));
3485 }
3486 else
3487 {
3488 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3489 word0));
3490 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3491 word1));
3492 }
3493 DONE;
3494 }")
3495
3496 (define_split
3497 [(set (match_operand:DF 0 "memory_operand" "")
3498 (match_operand:DF 1 "register_operand" ""))]
3499 "reload_completed
3500 && ! TARGET_ARCH64
3501 && (((REGNO (operands[1]) % 2) != 0)
3502 || ! mem_min_alignment (operands[0], 8))
3503 && offsettable_memref_p (operands[0])"
3504 [(clobber (const_int 0))]
3505 "
3506 {
3507 rtx word0 = adjust_address (operands[0], SFmode, 0);
3508 rtx word1 = adjust_address (operands[0], SFmode, 4);
3509
3510 emit_insn (gen_movsf (word0,
3511 gen_highpart (SFmode, operands[1])));
3512 emit_insn (gen_movsf (word1,
3513 gen_lowpart (SFmode, operands[1])));
3514 DONE;
3515 }")
3516
3517 (define_split
3518 [(set (match_operand:DF 0 "memory_operand" "")
3519 (match_operand:DF 1 "fp_zero_operand" ""))]
3520 "reload_completed
3521 && (! TARGET_V9
3522 || (! TARGET_ARCH64
3523 && ! mem_min_alignment (operands[0], 8)))
3524 && offsettable_memref_p (operands[0])"
3525 [(clobber (const_int 0))]
3526 "
3527 {
3528 rtx dest1, dest2;
3529
3530 dest1 = adjust_address (operands[0], SFmode, 0);
3531 dest2 = adjust_address (operands[0], SFmode, 4);
3532
3533 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3534 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3535 DONE;
3536 }")
3537
3538 (define_split
3539 [(set (match_operand:DF 0 "register_operand" "")
3540 (match_operand:DF 1 "fp_zero_operand" ""))]
3541 "reload_completed
3542 && ! TARGET_ARCH64
3543 && ((GET_CODE (operands[0]) == REG
3544 && REGNO (operands[0]) < 32)
3545 || (GET_CODE (operands[0]) == SUBREG
3546 && GET_CODE (SUBREG_REG (operands[0])) == REG
3547 && REGNO (SUBREG_REG (operands[0])) < 32))"
3548 [(clobber (const_int 0))]
3549 "
3550 {
3551 rtx set_dest = operands[0];
3552 rtx dest1, dest2;
3553
3554 dest1 = gen_highpart (SFmode, set_dest);
3555 dest2 = gen_lowpart (SFmode, set_dest);
3556 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3557 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3558 DONE;
3559 }")
3560
3561 (define_expand "movtf"
3562 [(set (match_operand:TF 0 "general_operand" "")
3563 (match_operand:TF 1 "general_operand" ""))]
3564 ""
3565 "
3566 {
3567 /* Force TFmode constants into memory. */
3568 if (GET_CODE (operands[0]) == REG
3569 && CONSTANT_P (operands[1]))
3570 {
3571 /* emit_group_store will send such bogosity to us when it is
3572 not storing directly into memory. So fix this up to avoid
3573 crashes in output_constant_pool. */
3574 if (operands [1] == const0_rtx)
3575 operands[1] = CONST0_RTX (TFmode);
3576
3577 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3578 goto movtf_is_ok;
3579
3580 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3581 operands[1]));
3582 }
3583
3584 /* Handle MEM cases first, note that only v9 guarentees
3585 full 16-byte alignment for quads. */
3586 if (GET_CODE (operands[0]) == MEM)
3587 {
3588 if (register_operand (operands[1], TFmode)
3589 || fp_zero_operand (operands[1], TFmode))
3590 goto movtf_is_ok;
3591
3592 if (! reload_in_progress)
3593 {
3594 operands[0] = validize_mem (operands[0]);
3595 operands[1] = force_reg (TFmode, operands[1]);
3596 }
3597 }
3598
3599 /* Fixup PIC cases. */
3600 if (flag_pic)
3601 {
3602 if (CONSTANT_P (operands[1])
3603 && pic_address_needs_scratch (operands[1]))
3604 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3605
3606 if (symbolic_operand (operands[1], TFmode))
3607 {
3608 operands[1] = legitimize_pic_address (operands[1],
3609 TFmode,
3610 (reload_in_progress ?
3611 operands[0] :
3612 NULL_RTX));
3613 }
3614 }
3615
3616 movtf_is_ok:
3617 ;
3618 }")
3619
3620 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3621 ;; we must split them all. :-(
3622 (define_insn "*movtf_insn_sp32"
3623 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3624 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3625 "TARGET_FPU
3626 && ! TARGET_VIS
3627 && ! TARGET_ARCH64
3628 && (register_operand (operands[0], TFmode)
3629 || register_operand (operands[1], TFmode)
3630 || fp_zero_operand (operands[1], TFmode))"
3631 "#"
3632 [(set_attr "length" "4")])
3633
3634 (define_insn "*movtf_insn_vis_sp32"
3635 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3636 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3637 "TARGET_FPU
3638 && TARGET_VIS
3639 && ! TARGET_ARCH64
3640 && (register_operand (operands[0], TFmode)
3641 || register_operand (operands[1], TFmode)
3642 || fp_zero_operand (operands[1], TFmode))"
3643 "#"
3644 [(set_attr "length" "4")])
3645
3646 ;; Exactly the same as above, except that all `e' cases are deleted.
3647 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3648 ;; when -mno-fpu.
3649
3650 (define_insn "*movtf_no_e_insn_sp32"
3651 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3652 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3653 "! TARGET_FPU
3654 && ! TARGET_ARCH64
3655 && (register_operand (operands[0], TFmode)
3656 || register_operand (operands[1], TFmode)
3657 || fp_zero_operand (operands[1], TFmode))"
3658 "#"
3659 [(set_attr "length" "4")])
3660
3661 ;; Now handle the float reg cases directly when arch64,
3662 ;; hard_quad, and proper reg number alignment are all true.
3663 (define_insn "*movtf_insn_hq_sp64"
3664 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3665 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3666 "TARGET_FPU
3667 && ! TARGET_VIS
3668 && TARGET_ARCH64
3669 && TARGET_HARD_QUAD
3670 && (register_operand (operands[0], TFmode)
3671 || register_operand (operands[1], TFmode)
3672 || fp_zero_operand (operands[1], TFmode))"
3673 "@
3674 fmovq\\t%1, %0
3675 ldq\\t%1, %0
3676 stq\\t%1, %0
3677 #
3678 #"
3679 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3680 (set_attr "length" "*,*,*,2,2")])
3681
3682 (define_insn "*movtf_insn_hq_vis_sp64"
3683 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3684 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3685 "TARGET_FPU
3686 && TARGET_VIS
3687 && TARGET_ARCH64
3688 && TARGET_HARD_QUAD
3689 && (register_operand (operands[0], TFmode)
3690 || register_operand (operands[1], TFmode)
3691 || fp_zero_operand (operands[1], TFmode))"
3692 "@
3693 fmovq\\t%1, %0
3694 ldq\\t%1, %0
3695 stq\\t%1, %0
3696 #
3697 #
3698 #"
3699 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3700 (set_attr "length" "*,*,*,2,2,2")])
3701
3702 ;; Now we allow the integer register cases even when
3703 ;; only arch64 is true.
3704 (define_insn "*movtf_insn_sp64"
3705 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3706 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3707 "TARGET_FPU
3708 && ! TARGET_VIS
3709 && TARGET_ARCH64
3710 && ! TARGET_HARD_QUAD
3711 && (register_operand (operands[0], TFmode)
3712 || register_operand (operands[1], TFmode)
3713 || fp_zero_operand (operands[1], TFmode))"
3714 "#"
3715 [(set_attr "length" "2")])
3716
3717 (define_insn "*movtf_insn_vis_sp64"
3718 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3719 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3720 "TARGET_FPU
3721 && TARGET_VIS
3722 && TARGET_ARCH64
3723 && ! TARGET_HARD_QUAD
3724 && (register_operand (operands[0], TFmode)
3725 || register_operand (operands[1], TFmode)
3726 || fp_zero_operand (operands[1], TFmode))"
3727 "#"
3728 [(set_attr "length" "2")])
3729
3730 (define_insn "*movtf_no_e_insn_sp64"
3731 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3732 (match_operand:TF 1 "input_operand" "orG,rG"))]
3733 "! TARGET_FPU
3734 && TARGET_ARCH64
3735 && (register_operand (operands[0], TFmode)
3736 || register_operand (operands[1], TFmode)
3737 || fp_zero_operand (operands[1], TFmode))"
3738 "#"
3739 [(set_attr "length" "2")])
3740
3741 ;; Now all the splits to handle multi-insn TF mode moves.
3742 (define_split
3743 [(set (match_operand:TF 0 "register_operand" "")
3744 (match_operand:TF 1 "register_operand" ""))]
3745 "reload_completed
3746 && (! TARGET_ARCH64
3747 || (TARGET_FPU
3748 && ! TARGET_HARD_QUAD))"
3749 [(clobber (const_int 0))]
3750 "
3751 {
3752 rtx set_dest = operands[0];
3753 rtx set_src = operands[1];
3754 rtx dest1, dest2;
3755 rtx src1, src2;
3756
3757 dest1 = gen_df_reg (set_dest, 0);
3758 dest2 = gen_df_reg (set_dest, 1);
3759 src1 = gen_df_reg (set_src, 0);
3760 src2 = gen_df_reg (set_src, 1);
3761
3762 /* Now emit using the real source and destination we found, swapping
3763 the order if we detect overlap. */
3764 if (reg_overlap_mentioned_p (dest1, src2))
3765 {
3766 emit_insn (gen_movdf (dest2, src2));
3767 emit_insn (gen_movdf (dest1, src1));
3768 }
3769 else
3770 {
3771 emit_insn (gen_movdf (dest1, src1));
3772 emit_insn (gen_movdf (dest2, src2));
3773 }
3774 DONE;
3775 }")
3776
3777 (define_split
3778 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3779 (match_operand:TF 1 "fp_zero_operand" ""))]
3780 "reload_completed"
3781 [(clobber (const_int 0))]
3782 "
3783 {
3784 rtx set_dest = operands[0];
3785 rtx dest1, dest2;
3786
3787 switch (GET_CODE (set_dest))
3788 {
3789 case REG:
3790 dest1 = gen_df_reg (set_dest, 0);
3791 dest2 = gen_df_reg (set_dest, 1);
3792 break;
3793 case MEM:
3794 dest1 = adjust_address (set_dest, DFmode, 0);
3795 dest2 = adjust_address (set_dest, DFmode, 8);
3796 break;
3797 default:
3798 abort ();
3799 }
3800
3801 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3802 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3803 DONE;
3804 }")
3805
3806 (define_split
3807 [(set (match_operand:TF 0 "register_operand" "")
3808 (match_operand:TF 1 "memory_operand" ""))]
3809 "(reload_completed
3810 && offsettable_memref_p (operands[1]))"
3811 [(clobber (const_int 0))]
3812 "
3813 {
3814 rtx word0 = adjust_address (operands[1], DFmode, 0);
3815 rtx word1 = adjust_address (operands[1], DFmode, 8);
3816 rtx set_dest, dest1, dest2;
3817
3818 set_dest = operands[0];
3819
3820 dest1 = gen_df_reg (set_dest, 0);
3821 dest2 = gen_df_reg (set_dest, 1);
3822
3823 /* Now output, ordering such that we don't clobber any registers
3824 mentioned in the address. */
3825 if (reg_overlap_mentioned_p (dest1, word1))
3826
3827 {
3828 emit_insn (gen_movdf (dest2, word1));
3829 emit_insn (gen_movdf (dest1, word0));
3830 }
3831 else
3832 {
3833 emit_insn (gen_movdf (dest1, word0));
3834 emit_insn (gen_movdf (dest2, word1));
3835 }
3836 DONE;
3837 }")
3838
3839 (define_split
3840 [(set (match_operand:TF 0 "memory_operand" "")
3841 (match_operand:TF 1 "register_operand" ""))]
3842 "(reload_completed
3843 && offsettable_memref_p (operands[0]))"
3844 [(clobber (const_int 0))]
3845 "
3846 {
3847 rtx set_src = operands[1];
3848
3849 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3850 gen_df_reg (set_src, 0)));
3851 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3852 gen_df_reg (set_src, 1)));
3853 DONE;
3854 }")
3855 \f
3856 ;; Sparc V9 conditional move instructions.
3857
3858 ;; We can handle larger constants here for some flavors, but for now we keep
3859 ;; it simple and only allow those constants supported by all flavours.
3860 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3861 ;; 3 contains the constant if one is present, but we handle either for
3862 ;; generality (sparc.c puts a constant in operand 2).
3863
3864 (define_expand "movqicc"
3865 [(set (match_operand:QI 0 "register_operand" "")
3866 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3867 (match_operand:QI 2 "arith10_operand" "")
3868 (match_operand:QI 3 "arith10_operand" "")))]
3869 "TARGET_V9"
3870 "
3871 {
3872 enum rtx_code code = GET_CODE (operands[1]);
3873
3874 if (GET_MODE (sparc_compare_op0) == DImode
3875 && ! TARGET_ARCH64)
3876 FAIL;
3877
3878 if (sparc_compare_op1 == const0_rtx
3879 && GET_CODE (sparc_compare_op0) == REG
3880 && GET_MODE (sparc_compare_op0) == DImode
3881 && v9_regcmp_p (code))
3882 {
3883 operands[1] = gen_rtx_fmt_ee (code, DImode,
3884 sparc_compare_op0, sparc_compare_op1);
3885 }
3886 else
3887 {
3888 rtx cc_reg = gen_compare_reg (code,
3889 sparc_compare_op0, sparc_compare_op1);
3890 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3891 }
3892 }")
3893
3894 (define_expand "movhicc"
3895 [(set (match_operand:HI 0 "register_operand" "")
3896 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3897 (match_operand:HI 2 "arith10_operand" "")
3898 (match_operand:HI 3 "arith10_operand" "")))]
3899 "TARGET_V9"
3900 "
3901 {
3902 enum rtx_code code = GET_CODE (operands[1]);
3903
3904 if (GET_MODE (sparc_compare_op0) == DImode
3905 && ! TARGET_ARCH64)
3906 FAIL;
3907
3908 if (sparc_compare_op1 == const0_rtx
3909 && GET_CODE (sparc_compare_op0) == REG
3910 && GET_MODE (sparc_compare_op0) == DImode
3911 && v9_regcmp_p (code))
3912 {
3913 operands[1] = gen_rtx_fmt_ee (code, DImode,
3914 sparc_compare_op0, sparc_compare_op1);
3915 }
3916 else
3917 {
3918 rtx cc_reg = gen_compare_reg (code,
3919 sparc_compare_op0, sparc_compare_op1);
3920 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3921 }
3922 }")
3923
3924 (define_expand "movsicc"
3925 [(set (match_operand:SI 0 "register_operand" "")
3926 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3927 (match_operand:SI 2 "arith10_operand" "")
3928 (match_operand:SI 3 "arith10_operand" "")))]
3929 "TARGET_V9"
3930 "
3931 {
3932 enum rtx_code code = GET_CODE (operands[1]);
3933 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3934
3935 if (sparc_compare_op1 == const0_rtx
3936 && GET_CODE (sparc_compare_op0) == REG
3937 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3938 {
3939 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3940 sparc_compare_op0, sparc_compare_op1);
3941 }
3942 else
3943 {
3944 rtx cc_reg = gen_compare_reg (code,
3945 sparc_compare_op0, sparc_compare_op1);
3946 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3947 cc_reg, const0_rtx);
3948 }
3949 }")
3950
3951 (define_expand "movdicc"
3952 [(set (match_operand:DI 0 "register_operand" "")
3953 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3954 (match_operand:DI 2 "arith10_double_operand" "")
3955 (match_operand:DI 3 "arith10_double_operand" "")))]
3956 "TARGET_ARCH64"
3957 "
3958 {
3959 enum rtx_code code = GET_CODE (operands[1]);
3960
3961 if (sparc_compare_op1 == const0_rtx
3962 && GET_CODE (sparc_compare_op0) == REG
3963 && GET_MODE (sparc_compare_op0) == DImode
3964 && v9_regcmp_p (code))
3965 {
3966 operands[1] = gen_rtx_fmt_ee (code, DImode,
3967 sparc_compare_op0, sparc_compare_op1);
3968 }
3969 else
3970 {
3971 rtx cc_reg = gen_compare_reg (code,
3972 sparc_compare_op0, sparc_compare_op1);
3973 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3974 cc_reg, const0_rtx);
3975 }
3976 }")
3977
3978 (define_expand "movsfcc"
3979 [(set (match_operand:SF 0 "register_operand" "")
3980 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3981 (match_operand:SF 2 "register_operand" "")
3982 (match_operand:SF 3 "register_operand" "")))]
3983 "TARGET_V9 && TARGET_FPU"
3984 "
3985 {
3986 enum rtx_code code = GET_CODE (operands[1]);
3987
3988 if (GET_MODE (sparc_compare_op0) == DImode
3989 && ! TARGET_ARCH64)
3990 FAIL;
3991
3992 if (sparc_compare_op1 == const0_rtx
3993 && GET_CODE (sparc_compare_op0) == REG
3994 && GET_MODE (sparc_compare_op0) == DImode
3995 && v9_regcmp_p (code))
3996 {
3997 operands[1] = gen_rtx_fmt_ee (code, DImode,
3998 sparc_compare_op0, sparc_compare_op1);
3999 }
4000 else
4001 {
4002 rtx cc_reg = gen_compare_reg (code,
4003 sparc_compare_op0, sparc_compare_op1);
4004 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4005 }
4006 }")
4007
4008 (define_expand "movdfcc"
4009 [(set (match_operand:DF 0 "register_operand" "")
4010 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4011 (match_operand:DF 2 "register_operand" "")
4012 (match_operand:DF 3 "register_operand" "")))]
4013 "TARGET_V9 && TARGET_FPU"
4014 "
4015 {
4016 enum rtx_code code = GET_CODE (operands[1]);
4017
4018 if (GET_MODE (sparc_compare_op0) == DImode
4019 && ! TARGET_ARCH64)
4020 FAIL;
4021
4022 if (sparc_compare_op1 == const0_rtx
4023 && GET_CODE (sparc_compare_op0) == REG
4024 && GET_MODE (sparc_compare_op0) == DImode
4025 && v9_regcmp_p (code))
4026 {
4027 operands[1] = gen_rtx_fmt_ee (code, DImode,
4028 sparc_compare_op0, sparc_compare_op1);
4029 }
4030 else
4031 {
4032 rtx cc_reg = gen_compare_reg (code,
4033 sparc_compare_op0, sparc_compare_op1);
4034 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4035 }
4036 }")
4037
4038 (define_expand "movtfcc"
4039 [(set (match_operand:TF 0 "register_operand" "")
4040 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4041 (match_operand:TF 2 "register_operand" "")
4042 (match_operand:TF 3 "register_operand" "")))]
4043 "TARGET_V9 && TARGET_FPU"
4044 "
4045 {
4046 enum rtx_code code = GET_CODE (operands[1]);
4047
4048 if (GET_MODE (sparc_compare_op0) == DImode
4049 && ! TARGET_ARCH64)
4050 FAIL;
4051
4052 if (sparc_compare_op1 == const0_rtx
4053 && GET_CODE (sparc_compare_op0) == REG
4054 && GET_MODE (sparc_compare_op0) == DImode
4055 && v9_regcmp_p (code))
4056 {
4057 operands[1] = gen_rtx_fmt_ee (code, DImode,
4058 sparc_compare_op0, sparc_compare_op1);
4059 }
4060 else
4061 {
4062 rtx cc_reg = gen_compare_reg (code,
4063 sparc_compare_op0, sparc_compare_op1);
4064 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4065 }
4066 }")
4067
4068 ;; Conditional move define_insns.
4069
4070 (define_insn "*movqi_cc_sp64"
4071 [(set (match_operand:QI 0 "register_operand" "=r,r")
4072 (if_then_else:QI (match_operator 1 "comparison_operator"
4073 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4074 (const_int 0)])
4075 (match_operand:QI 3 "arith11_operand" "rL,0")
4076 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4077 "TARGET_V9"
4078 "@
4079 mov%C1\\t%x2, %3, %0
4080 mov%c1\\t%x2, %4, %0"
4081 [(set_attr "type" "cmove")])
4082
4083 (define_insn "*movhi_cc_sp64"
4084 [(set (match_operand:HI 0 "register_operand" "=r,r")
4085 (if_then_else:HI (match_operator 1 "comparison_operator"
4086 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4087 (const_int 0)])
4088 (match_operand:HI 3 "arith11_operand" "rL,0")
4089 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4090 "TARGET_V9"
4091 "@
4092 mov%C1\\t%x2, %3, %0
4093 mov%c1\\t%x2, %4, %0"
4094 [(set_attr "type" "cmove")])
4095
4096 (define_insn "*movsi_cc_sp64"
4097 [(set (match_operand:SI 0 "register_operand" "=r,r")
4098 (if_then_else:SI (match_operator 1 "comparison_operator"
4099 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4100 (const_int 0)])
4101 (match_operand:SI 3 "arith11_operand" "rL,0")
4102 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4103 "TARGET_V9"
4104 "@
4105 mov%C1\\t%x2, %3, %0
4106 mov%c1\\t%x2, %4, %0"
4107 [(set_attr "type" "cmove")])
4108
4109 ;; ??? The constraints of operands 3,4 need work.
4110 (define_insn "*movdi_cc_sp64"
4111 [(set (match_operand:DI 0 "register_operand" "=r,r")
4112 (if_then_else:DI (match_operator 1 "comparison_operator"
4113 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4114 (const_int 0)])
4115 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4116 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4117 "TARGET_ARCH64"
4118 "@
4119 mov%C1\\t%x2, %3, %0
4120 mov%c1\\t%x2, %4, %0"
4121 [(set_attr "type" "cmove")])
4122
4123 (define_insn "*movdi_cc_sp64_trunc"
4124 [(set (match_operand:SI 0 "register_operand" "=r,r")
4125 (if_then_else:SI (match_operator 1 "comparison_operator"
4126 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4127 (const_int 0)])
4128 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4129 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4130 "TARGET_ARCH64"
4131 "@
4132 mov%C1\\t%x2, %3, %0
4133 mov%c1\\t%x2, %4, %0"
4134 [(set_attr "type" "cmove")])
4135
4136 (define_insn "*movsf_cc_sp64"
4137 [(set (match_operand:SF 0 "register_operand" "=f,f")
4138 (if_then_else:SF (match_operator 1 "comparison_operator"
4139 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4140 (const_int 0)])
4141 (match_operand:SF 3 "register_operand" "f,0")
4142 (match_operand:SF 4 "register_operand" "0,f")))]
4143 "TARGET_V9 && TARGET_FPU"
4144 "@
4145 fmovs%C1\\t%x2, %3, %0
4146 fmovs%c1\\t%x2, %4, %0"
4147 [(set_attr "type" "fpcmove")])
4148
4149 (define_insn "movdf_cc_sp64"
4150 [(set (match_operand:DF 0 "register_operand" "=e,e")
4151 (if_then_else:DF (match_operator 1 "comparison_operator"
4152 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4153 (const_int 0)])
4154 (match_operand:DF 3 "register_operand" "e,0")
4155 (match_operand:DF 4 "register_operand" "0,e")))]
4156 "TARGET_V9 && TARGET_FPU"
4157 "@
4158 fmovd%C1\\t%x2, %3, %0
4159 fmovd%c1\\t%x2, %4, %0"
4160 [(set_attr "type" "fpcmove")
4161 (set_attr "fptype" "double")])
4162
4163 (define_insn "*movtf_cc_hq_sp64"
4164 [(set (match_operand:TF 0 "register_operand" "=e,e")
4165 (if_then_else:TF (match_operator 1 "comparison_operator"
4166 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4167 (const_int 0)])
4168 (match_operand:TF 3 "register_operand" "e,0")
4169 (match_operand:TF 4 "register_operand" "0,e")))]
4170 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4171 "@
4172 fmovq%C1\\t%x2, %3, %0
4173 fmovq%c1\\t%x2, %4, %0"
4174 [(set_attr "type" "fpcmove")])
4175
4176 (define_insn "*movtf_cc_sp64"
4177 [(set (match_operand:TF 0 "register_operand" "=e,e")
4178 (if_then_else:TF (match_operator 1 "comparison_operator"
4179 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4180 (const_int 0)])
4181 (match_operand:TF 3 "register_operand" "e,0")
4182 (match_operand:TF 4 "register_operand" "0,e")))]
4183 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4184 "#"
4185 [(set_attr "length" "2")])
4186
4187 (define_split
4188 [(set (match_operand:TF 0 "register_operand" "")
4189 (if_then_else:TF (match_operator 1 "comparison_operator"
4190 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4191 (const_int 0)])
4192 (match_operand:TF 3 "register_operand" "")
4193 (match_operand:TF 4 "register_operand" "")))]
4194 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4195 [(clobber (const_int 0))]
4196 "
4197 {
4198 rtx set_dest = operands[0];
4199 rtx set_srca = operands[3];
4200 rtx set_srcb = operands[4];
4201 int third = rtx_equal_p (set_dest, set_srca);
4202 rtx dest1, dest2;
4203 rtx srca1, srca2, srcb1, srcb2;
4204
4205 dest1 = gen_df_reg (set_dest, 0);
4206 dest2 = gen_df_reg (set_dest, 1);
4207 srca1 = gen_df_reg (set_srca, 0);
4208 srca2 = gen_df_reg (set_srca, 1);
4209 srcb1 = gen_df_reg (set_srcb, 0);
4210 srcb2 = gen_df_reg (set_srcb, 1);
4211
4212 /* Now emit using the real source and destination we found, swapping
4213 the order if we detect overlap. */
4214 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4215 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4216 {
4217 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4218 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4219 }
4220 else
4221 {
4222 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4223 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4224 }
4225 DONE;
4226 }")
4227
4228 (define_insn "*movqi_cc_reg_sp64"
4229 [(set (match_operand:QI 0 "register_operand" "=r,r")
4230 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4231 [(match_operand:DI 2 "register_operand" "r,r")
4232 (const_int 0)])
4233 (match_operand:QI 3 "arith10_operand" "rM,0")
4234 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4235 "TARGET_ARCH64"
4236 "@
4237 movr%D1\\t%2, %r3, %0
4238 movr%d1\\t%2, %r4, %0"
4239 [(set_attr "type" "cmove")])
4240
4241 (define_insn "*movhi_cc_reg_sp64"
4242 [(set (match_operand:HI 0 "register_operand" "=r,r")
4243 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4244 [(match_operand:DI 2 "register_operand" "r,r")
4245 (const_int 0)])
4246 (match_operand:HI 3 "arith10_operand" "rM,0")
4247 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4248 "TARGET_ARCH64"
4249 "@
4250 movr%D1\\t%2, %r3, %0
4251 movr%d1\\t%2, %r4, %0"
4252 [(set_attr "type" "cmove")])
4253
4254 (define_insn "*movsi_cc_reg_sp64"
4255 [(set (match_operand:SI 0 "register_operand" "=r,r")
4256 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4257 [(match_operand:DI 2 "register_operand" "r,r")
4258 (const_int 0)])
4259 (match_operand:SI 3 "arith10_operand" "rM,0")
4260 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4261 "TARGET_ARCH64"
4262 "@
4263 movr%D1\\t%2, %r3, %0
4264 movr%d1\\t%2, %r4, %0"
4265 [(set_attr "type" "cmove")])
4266
4267 ;; ??? The constraints of operands 3,4 need work.
4268 (define_insn "*movdi_cc_reg_sp64"
4269 [(set (match_operand:DI 0 "register_operand" "=r,r")
4270 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4271 [(match_operand:DI 2 "register_operand" "r,r")
4272 (const_int 0)])
4273 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4274 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4275 "TARGET_ARCH64"
4276 "@
4277 movr%D1\\t%2, %r3, %0
4278 movr%d1\\t%2, %r4, %0"
4279 [(set_attr "type" "cmove")])
4280
4281 (define_insn "*movdi_cc_reg_sp64_trunc"
4282 [(set (match_operand:SI 0 "register_operand" "=r,r")
4283 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4284 [(match_operand:DI 2 "register_operand" "r,r")
4285 (const_int 0)])
4286 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4287 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4288 "TARGET_ARCH64"
4289 "@
4290 movr%D1\\t%2, %r3, %0
4291 movr%d1\\t%2, %r4, %0"
4292 [(set_attr "type" "cmove")])
4293
4294 (define_insn "*movsf_cc_reg_sp64"
4295 [(set (match_operand:SF 0 "register_operand" "=f,f")
4296 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4297 [(match_operand:DI 2 "register_operand" "r,r")
4298 (const_int 0)])
4299 (match_operand:SF 3 "register_operand" "f,0")
4300 (match_operand:SF 4 "register_operand" "0,f")))]
4301 "TARGET_ARCH64 && TARGET_FPU"
4302 "@
4303 fmovrs%D1\\t%2, %3, %0
4304 fmovrs%d1\\t%2, %4, %0"
4305 [(set_attr "type" "fpcmove")])
4306
4307 (define_insn "movdf_cc_reg_sp64"
4308 [(set (match_operand:DF 0 "register_operand" "=e,e")
4309 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4310 [(match_operand:DI 2 "register_operand" "r,r")
4311 (const_int 0)])
4312 (match_operand:DF 3 "register_operand" "e,0")
4313 (match_operand:DF 4 "register_operand" "0,e")))]
4314 "TARGET_ARCH64 && TARGET_FPU"
4315 "@
4316 fmovrd%D1\\t%2, %3, %0
4317 fmovrd%d1\\t%2, %4, %0"
4318 [(set_attr "type" "fpcmove")
4319 (set_attr "fptype" "double")])
4320
4321 (define_insn "*movtf_cc_reg_hq_sp64"
4322 [(set (match_operand:TF 0 "register_operand" "=e,e")
4323 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4324 [(match_operand:DI 2 "register_operand" "r,r")
4325 (const_int 0)])
4326 (match_operand:TF 3 "register_operand" "e,0")
4327 (match_operand:TF 4 "register_operand" "0,e")))]
4328 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4329 "@
4330 fmovrq%D1\\t%2, %3, %0
4331 fmovrq%d1\\t%2, %4, %0"
4332 [(set_attr "type" "fpcmove")])
4333
4334 (define_insn "*movtf_cc_reg_sp64"
4335 [(set (match_operand:TF 0 "register_operand" "=e,e")
4336 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4337 [(match_operand:DI 2 "register_operand" "r,r")
4338 (const_int 0)])
4339 (match_operand:TF 3 "register_operand" "e,0")
4340 (match_operand:TF 4 "register_operand" "0,e")))]
4341 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4342 "#"
4343 [(set_attr "length" "2")])
4344
4345 (define_split
4346 [(set (match_operand:TF 0 "register_operand" "")
4347 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4348 [(match_operand:DI 2 "register_operand" "")
4349 (const_int 0)])
4350 (match_operand:TF 3 "register_operand" "")
4351 (match_operand:TF 4 "register_operand" "")))]
4352 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4353 [(clobber (const_int 0))]
4354 "
4355 {
4356 rtx set_dest = operands[0];
4357 rtx set_srca = operands[3];
4358 rtx set_srcb = operands[4];
4359 int third = rtx_equal_p (set_dest, set_srca);
4360 rtx dest1, dest2;
4361 rtx srca1, srca2, srcb1, srcb2;
4362
4363 dest1 = gen_df_reg (set_dest, 0);
4364 dest2 = gen_df_reg (set_dest, 1);
4365 srca1 = gen_df_reg (set_srca, 0);
4366 srca2 = gen_df_reg (set_srca, 1);
4367 srcb1 = gen_df_reg (set_srcb, 0);
4368 srcb2 = gen_df_reg (set_srcb, 1);
4369
4370 /* Now emit using the real source and destination we found, swapping
4371 the order if we detect overlap. */
4372 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4373 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4374 {
4375 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4376 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4377 }
4378 else
4379 {
4380 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4381 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4382 }
4383 DONE;
4384 }")
4385
4386 \f
4387 ;;- zero extension instructions
4388
4389 ;; These patterns originally accepted general_operands, however, slightly
4390 ;; better code is generated by only accepting register_operands, and then
4391 ;; letting combine generate the ldu[hb] insns.
4392
4393 (define_expand "zero_extendhisi2"
4394 [(set (match_operand:SI 0 "register_operand" "")
4395 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4396 ""
4397 "
4398 {
4399 rtx temp = gen_reg_rtx (SImode);
4400 rtx shift_16 = GEN_INT (16);
4401 int op1_subbyte = 0;
4402
4403 if (GET_CODE (operand1) == SUBREG)
4404 {
4405 op1_subbyte = SUBREG_BYTE (operand1);
4406 op1_subbyte /= GET_MODE_SIZE (SImode);
4407 op1_subbyte *= GET_MODE_SIZE (SImode);
4408 operand1 = XEXP (operand1, 0);
4409 }
4410
4411 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4412 shift_16));
4413 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4414 DONE;
4415 }")
4416
4417 (define_insn "*zero_extendhisi2_insn"
4418 [(set (match_operand:SI 0 "register_operand" "=r")
4419 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4420 ""
4421 "lduh\\t%1, %0"
4422 [(set_attr "type" "load")])
4423
4424 (define_expand "zero_extendqihi2"
4425 [(set (match_operand:HI 0 "register_operand" "")
4426 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4427 ""
4428 "")
4429
4430 (define_insn "*zero_extendqihi2_insn"
4431 [(set (match_operand:HI 0 "register_operand" "=r,r")
4432 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4433 "GET_CODE (operands[1]) != CONST_INT"
4434 "@
4435 and\\t%1, 0xff, %0
4436 ldub\\t%1, %0"
4437 [(set_attr "type" "*,load")])
4438
4439 (define_expand "zero_extendqisi2"
4440 [(set (match_operand:SI 0 "register_operand" "")
4441 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4442 ""
4443 "")
4444
4445 (define_insn "*zero_extendqisi2_insn"
4446 [(set (match_operand:SI 0 "register_operand" "=r,r")
4447 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4448 "GET_CODE (operands[1]) != CONST_INT"
4449 "@
4450 and\\t%1, 0xff, %0
4451 ldub\\t%1, %0"
4452 [(set_attr "type" "*,load")])
4453
4454 (define_expand "zero_extendqidi2"
4455 [(set (match_operand:DI 0 "register_operand" "")
4456 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4457 "TARGET_ARCH64"
4458 "")
4459
4460 (define_insn "*zero_extendqidi2_insn"
4461 [(set (match_operand:DI 0 "register_operand" "=r,r")
4462 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4463 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4464 "@
4465 and\\t%1, 0xff, %0
4466 ldub\\t%1, %0"
4467 [(set_attr "type" "*,load")])
4468
4469 (define_expand "zero_extendhidi2"
4470 [(set (match_operand:DI 0 "register_operand" "")
4471 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4472 "TARGET_ARCH64"
4473 "
4474 {
4475 rtx temp = gen_reg_rtx (DImode);
4476 rtx shift_48 = GEN_INT (48);
4477 int op1_subbyte = 0;
4478
4479 if (GET_CODE (operand1) == SUBREG)
4480 {
4481 op1_subbyte = SUBREG_BYTE (operand1);
4482 op1_subbyte /= GET_MODE_SIZE (DImode);
4483 op1_subbyte *= GET_MODE_SIZE (DImode);
4484 operand1 = XEXP (operand1, 0);
4485 }
4486
4487 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4488 shift_48));
4489 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4490 DONE;
4491 }")
4492
4493 (define_insn "*zero_extendhidi2_insn"
4494 [(set (match_operand:DI 0 "register_operand" "=r")
4495 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4496 "TARGET_ARCH64"
4497 "lduh\\t%1, %0"
4498 [(set_attr "type" "load")])
4499
4500
4501 ;; ??? Write truncdisi pattern using sra?
4502
4503 (define_expand "zero_extendsidi2"
4504 [(set (match_operand:DI 0 "register_operand" "")
4505 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4506 ""
4507 "")
4508
4509 (define_insn "*zero_extendsidi2_insn_sp64"
4510 [(set (match_operand:DI 0 "register_operand" "=r,r")
4511 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4512 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4513 "@
4514 srl\\t%1, 0, %0
4515 lduw\\t%1, %0"
4516 [(set_attr "type" "shift,load")])
4517
4518 (define_insn "*zero_extendsidi2_insn_sp32"
4519 [(set (match_operand:DI 0 "register_operand" "=r")
4520 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4521 "! TARGET_ARCH64"
4522 "#"
4523 [(set_attr "length" "2")])
4524
4525 (define_split
4526 [(set (match_operand:DI 0 "register_operand" "")
4527 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4528 "! TARGET_ARCH64 && reload_completed"
4529 [(set (match_dup 2) (match_dup 3))
4530 (set (match_dup 4) (match_dup 5))]
4531 "
4532 {
4533 rtx dest1, dest2;
4534
4535 dest1 = gen_highpart (SImode, operands[0]);
4536 dest2 = gen_lowpart (SImode, operands[0]);
4537
4538 /* Swap the order in case of overlap. */
4539 if (REGNO (dest1) == REGNO (operands[1]))
4540 {
4541 operands[2] = dest2;
4542 operands[3] = operands[1];
4543 operands[4] = dest1;
4544 operands[5] = const0_rtx;
4545 }
4546 else
4547 {
4548 operands[2] = dest1;
4549 operands[3] = const0_rtx;
4550 operands[4] = dest2;
4551 operands[5] = operands[1];
4552 }
4553 }")
4554
4555 ;; Simplify comparisons of extended values.
4556
4557 (define_insn "*cmp_zero_extendqisi2"
4558 [(set (reg:CC 100)
4559 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4560 (const_int 0)))]
4561 ""
4562 "andcc\\t%0, 0xff, %%g0"
4563 [(set_attr "type" "compare")])
4564
4565 (define_insn "*cmp_zero_qi"
4566 [(set (reg:CC 100)
4567 (compare:CC (match_operand:QI 0 "register_operand" "r")
4568 (const_int 0)))]
4569 ""
4570 "andcc\\t%0, 0xff, %%g0"
4571 [(set_attr "type" "compare")])
4572
4573 (define_insn "*cmp_zero_extendqisi2_set"
4574 [(set (reg:CC 100)
4575 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4576 (const_int 0)))
4577 (set (match_operand:SI 0 "register_operand" "=r")
4578 (zero_extend:SI (match_dup 1)))]
4579 ""
4580 "andcc\\t%1, 0xff, %0"
4581 [(set_attr "type" "compare")])
4582
4583 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4584 [(set (reg:CC 100)
4585 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4586 (const_int 255))
4587 (const_int 0)))
4588 (set (match_operand:SI 0 "register_operand" "=r")
4589 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4590 ""
4591 "andcc\\t%1, 0xff, %0"
4592 [(set_attr "type" "compare")])
4593
4594 (define_insn "*cmp_zero_extendqidi2"
4595 [(set (reg:CCX 100)
4596 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4597 (const_int 0)))]
4598 "TARGET_ARCH64"
4599 "andcc\\t%0, 0xff, %%g0"
4600 [(set_attr "type" "compare")])
4601
4602 (define_insn "*cmp_zero_qi_sp64"
4603 [(set (reg:CCX 100)
4604 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4605 (const_int 0)))]
4606 "TARGET_ARCH64"
4607 "andcc\\t%0, 0xff, %%g0"
4608 [(set_attr "type" "compare")])
4609
4610 (define_insn "*cmp_zero_extendqidi2_set"
4611 [(set (reg:CCX 100)
4612 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4613 (const_int 0)))
4614 (set (match_operand:DI 0 "register_operand" "=r")
4615 (zero_extend:DI (match_dup 1)))]
4616 "TARGET_ARCH64"
4617 "andcc\\t%1, 0xff, %0"
4618 [(set_attr "type" "compare")])
4619
4620 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4621 [(set (reg:CCX 100)
4622 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4623 (const_int 255))
4624 (const_int 0)))
4625 (set (match_operand:DI 0 "register_operand" "=r")
4626 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4627 "TARGET_ARCH64"
4628 "andcc\\t%1, 0xff, %0"
4629 [(set_attr "type" "compare")])
4630
4631 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4632
4633 (define_insn "*cmp_siqi_trunc"
4634 [(set (reg:CC 100)
4635 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4636 (const_int 0)))]
4637 ""
4638 "andcc\\t%0, 0xff, %%g0"
4639 [(set_attr "type" "compare")])
4640
4641 (define_insn "*cmp_siqi_trunc_set"
4642 [(set (reg:CC 100)
4643 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4644 (const_int 0)))
4645 (set (match_operand:QI 0 "register_operand" "=r")
4646 (subreg:QI (match_dup 1) 3))]
4647 ""
4648 "andcc\\t%1, 0xff, %0"
4649 [(set_attr "type" "compare")])
4650
4651 (define_insn "*cmp_diqi_trunc"
4652 [(set (reg:CC 100)
4653 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4654 (const_int 0)))]
4655 "TARGET_ARCH64"
4656 "andcc\\t%0, 0xff, %%g0"
4657 [(set_attr "type" "compare")])
4658
4659 (define_insn "*cmp_diqi_trunc_set"
4660 [(set (reg:CC 100)
4661 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4662 (const_int 0)))
4663 (set (match_operand:QI 0 "register_operand" "=r")
4664 (subreg:QI (match_dup 1) 7))]
4665 "TARGET_ARCH64"
4666 "andcc\\t%1, 0xff, %0"
4667 [(set_attr "type" "compare")])
4668 \f
4669 ;;- sign extension instructions
4670
4671 ;; These patterns originally accepted general_operands, however, slightly
4672 ;; better code is generated by only accepting register_operands, and then
4673 ;; letting combine generate the lds[hb] insns.
4674
4675 (define_expand "extendhisi2"
4676 [(set (match_operand:SI 0 "register_operand" "")
4677 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4678 ""
4679 "
4680 {
4681 rtx temp = gen_reg_rtx (SImode);
4682 rtx shift_16 = GEN_INT (16);
4683 int op1_subbyte = 0;
4684
4685 if (GET_CODE (operand1) == SUBREG)
4686 {
4687 op1_subbyte = SUBREG_BYTE (operand1);
4688 op1_subbyte /= GET_MODE_SIZE (SImode);
4689 op1_subbyte *= GET_MODE_SIZE (SImode);
4690 operand1 = XEXP (operand1, 0);
4691 }
4692
4693 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4694 shift_16));
4695 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4696 DONE;
4697 }")
4698
4699 (define_insn "*sign_extendhisi2_insn"
4700 [(set (match_operand:SI 0 "register_operand" "=r")
4701 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4702 ""
4703 "ldsh\\t%1, %0"
4704 [(set_attr "type" "sload")])
4705
4706 (define_expand "extendqihi2"
4707 [(set (match_operand:HI 0 "register_operand" "")
4708 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4709 ""
4710 "
4711 {
4712 rtx temp = gen_reg_rtx (SImode);
4713 rtx shift_24 = GEN_INT (24);
4714 int op1_subbyte = 0;
4715 int op0_subbyte = 0;
4716
4717 if (GET_CODE (operand1) == SUBREG)
4718 {
4719 op1_subbyte = SUBREG_BYTE (operand1);
4720 op1_subbyte /= GET_MODE_SIZE (SImode);
4721 op1_subbyte *= GET_MODE_SIZE (SImode);
4722 operand1 = XEXP (operand1, 0);
4723 }
4724 if (GET_CODE (operand0) == SUBREG)
4725 {
4726 op0_subbyte = SUBREG_BYTE (operand0);
4727 op0_subbyte /= GET_MODE_SIZE (SImode);
4728 op0_subbyte *= GET_MODE_SIZE (SImode);
4729 operand0 = XEXP (operand0, 0);
4730 }
4731 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4732 shift_24));
4733 if (GET_MODE (operand0) != SImode)
4734 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4735 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4736 DONE;
4737 }")
4738
4739 (define_insn "*sign_extendqihi2_insn"
4740 [(set (match_operand:HI 0 "register_operand" "=r")
4741 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4742 ""
4743 "ldsb\\t%1, %0"
4744 [(set_attr "type" "sload")])
4745
4746 (define_expand "extendqisi2"
4747 [(set (match_operand:SI 0 "register_operand" "")
4748 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4749 ""
4750 "
4751 {
4752 rtx temp = gen_reg_rtx (SImode);
4753 rtx shift_24 = GEN_INT (24);
4754 int op1_subbyte = 0;
4755
4756 if (GET_CODE (operand1) == SUBREG)
4757 {
4758 op1_subbyte = SUBREG_BYTE (operand1);
4759 op1_subbyte /= GET_MODE_SIZE (SImode);
4760 op1_subbyte *= GET_MODE_SIZE (SImode);
4761 operand1 = XEXP (operand1, 0);
4762 }
4763
4764 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4765 shift_24));
4766 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4767 DONE;
4768 }")
4769
4770 (define_insn "*sign_extendqisi2_insn"
4771 [(set (match_operand:SI 0 "register_operand" "=r")
4772 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4773 ""
4774 "ldsb\\t%1, %0"
4775 [(set_attr "type" "sload")])
4776
4777 (define_expand "extendqidi2"
4778 [(set (match_operand:DI 0 "register_operand" "")
4779 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4780 "TARGET_ARCH64"
4781 "
4782 {
4783 rtx temp = gen_reg_rtx (DImode);
4784 rtx shift_56 = GEN_INT (56);
4785 int op1_subbyte = 0;
4786
4787 if (GET_CODE (operand1) == SUBREG)
4788 {
4789 op1_subbyte = SUBREG_BYTE (operand1);
4790 op1_subbyte /= GET_MODE_SIZE (DImode);
4791 op1_subbyte *= GET_MODE_SIZE (DImode);
4792 operand1 = XEXP (operand1, 0);
4793 }
4794
4795 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4796 shift_56));
4797 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4798 DONE;
4799 }")
4800
4801 (define_insn "*sign_extendqidi2_insn"
4802 [(set (match_operand:DI 0 "register_operand" "=r")
4803 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4804 "TARGET_ARCH64"
4805 "ldsb\\t%1, %0"
4806 [(set_attr "type" "sload")])
4807
4808 (define_expand "extendhidi2"
4809 [(set (match_operand:DI 0 "register_operand" "")
4810 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4811 "TARGET_ARCH64"
4812 "
4813 {
4814 rtx temp = gen_reg_rtx (DImode);
4815 rtx shift_48 = GEN_INT (48);
4816 int op1_subbyte = 0;
4817
4818 if (GET_CODE (operand1) == SUBREG)
4819 {
4820 op1_subbyte = SUBREG_BYTE (operand1);
4821 op1_subbyte /= GET_MODE_SIZE (DImode);
4822 op1_subbyte *= GET_MODE_SIZE (DImode);
4823 operand1 = XEXP (operand1, 0);
4824 }
4825
4826 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4827 shift_48));
4828 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4829 DONE;
4830 }")
4831
4832 (define_insn "*sign_extendhidi2_insn"
4833 [(set (match_operand:DI 0 "register_operand" "=r")
4834 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4835 "TARGET_ARCH64"
4836 "ldsh\\t%1, %0"
4837 [(set_attr "type" "sload")])
4838
4839 (define_expand "extendsidi2"
4840 [(set (match_operand:DI 0 "register_operand" "")
4841 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4842 "TARGET_ARCH64"
4843 "")
4844
4845 (define_insn "*sign_extendsidi2_insn"
4846 [(set (match_operand:DI 0 "register_operand" "=r,r")
4847 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4848 "TARGET_ARCH64"
4849 "@
4850 sra\\t%1, 0, %0
4851 ldsw\\t%1, %0"
4852 [(set_attr "type" "shift,sload")])
4853 \f
4854 ;; Special pattern for optimizing bit-field compares. This is needed
4855 ;; because combine uses this as a canonical form.
4856
4857 (define_insn "*cmp_zero_extract"
4858 [(set (reg:CC 100)
4859 (compare:CC
4860 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4861 (match_operand:SI 1 "small_int_or_double" "n")
4862 (match_operand:SI 2 "small_int_or_double" "n"))
4863 (const_int 0)))]
4864 "(GET_CODE (operands[2]) == CONST_INT
4865 && INTVAL (operands[2]) > 19)
4866 || (GET_CODE (operands[2]) == CONST_DOUBLE
4867 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4868 "*
4869 {
4870 int len = (GET_CODE (operands[1]) == CONST_INT
4871 ? INTVAL (operands[1])
4872 : CONST_DOUBLE_LOW (operands[1]));
4873 int pos = 32 -
4874 (GET_CODE (operands[2]) == CONST_INT
4875 ? INTVAL (operands[2])
4876 : CONST_DOUBLE_LOW (operands[2])) - len;
4877 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4878
4879 operands[1] = GEN_INT (mask);
4880 return \"andcc\\t%0, %1, %%g0\";
4881 }"
4882 [(set_attr "type" "compare")])
4883
4884 (define_insn "*cmp_zero_extract_sp64"
4885 [(set (reg:CCX 100)
4886 (compare:CCX
4887 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4888 (match_operand:SI 1 "small_int_or_double" "n")
4889 (match_operand:SI 2 "small_int_or_double" "n"))
4890 (const_int 0)))]
4891 "TARGET_ARCH64
4892 && ((GET_CODE (operands[2]) == CONST_INT
4893 && INTVAL (operands[2]) > 51)
4894 || (GET_CODE (operands[2]) == CONST_DOUBLE
4895 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4896 "*
4897 {
4898 int len = (GET_CODE (operands[1]) == CONST_INT
4899 ? INTVAL (operands[1])
4900 : CONST_DOUBLE_LOW (operands[1]));
4901 int pos = 64 -
4902 (GET_CODE (operands[2]) == CONST_INT
4903 ? INTVAL (operands[2])
4904 : CONST_DOUBLE_LOW (operands[2])) - len;
4905 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4906
4907 operands[1] = GEN_INT (mask);
4908 return \"andcc\\t%0, %1, %%g0\";
4909 }"
4910 [(set_attr "type" "compare")])
4911 \f
4912 ;; Conversions between float, double and long double.
4913
4914 (define_insn "extendsfdf2"
4915 [(set (match_operand:DF 0 "register_operand" "=e")
4916 (float_extend:DF
4917 (match_operand:SF 1 "register_operand" "f")))]
4918 "TARGET_FPU"
4919 "fstod\\t%1, %0"
4920 [(set_attr "type" "fp")
4921 (set_attr "fptype" "double")])
4922
4923 (define_expand "extendsftf2"
4924 [(set (match_operand:TF 0 "register_operand" "=e")
4925 (float_extend:TF
4926 (match_operand:SF 1 "register_operand" "f")))]
4927 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4928 "
4929 {
4930 if (! TARGET_HARD_QUAD)
4931 {
4932 rtx slot0;
4933
4934 if (GET_CODE (operands[0]) != MEM)
4935 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4936 else
4937 slot0 = operands[0];
4938
4939 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4940 VOIDmode, 2,
4941 XEXP (slot0, 0), Pmode,
4942 operands[1], SFmode);
4943
4944 if (GET_CODE (operands[0]) != MEM)
4945 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4946 DONE;
4947 }
4948 }")
4949
4950 (define_insn "*extendsftf2_hq"
4951 [(set (match_operand:TF 0 "register_operand" "=e")
4952 (float_extend:TF
4953 (match_operand:SF 1 "register_operand" "f")))]
4954 "TARGET_FPU && TARGET_HARD_QUAD"
4955 "fstoq\\t%1, %0"
4956 [(set_attr "type" "fp")])
4957
4958 (define_expand "extenddftf2"
4959 [(set (match_operand:TF 0 "register_operand" "=e")
4960 (float_extend:TF
4961 (match_operand:DF 1 "register_operand" "e")))]
4962 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4963 "
4964 {
4965 if (! TARGET_HARD_QUAD)
4966 {
4967 rtx slot0;
4968
4969 if (GET_CODE (operands[0]) != MEM)
4970 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4971 else
4972 slot0 = operands[0];
4973
4974 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
4975 VOIDmode, 2,
4976 XEXP (slot0, 0), Pmode,
4977 operands[1], DFmode);
4978
4979 if (GET_CODE (operands[0]) != MEM)
4980 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4981 DONE;
4982 }
4983 }")
4984
4985 (define_insn "*extenddftf2_hq"
4986 [(set (match_operand:TF 0 "register_operand" "=e")
4987 (float_extend:TF
4988 (match_operand:DF 1 "register_operand" "e")))]
4989 "TARGET_FPU && TARGET_HARD_QUAD"
4990 "fdtoq\\t%1, %0"
4991 [(set_attr "type" "fp")])
4992
4993 (define_insn "truncdfsf2"
4994 [(set (match_operand:SF 0 "register_operand" "=f")
4995 (float_truncate:SF
4996 (match_operand:DF 1 "register_operand" "e")))]
4997 "TARGET_FPU"
4998 "fdtos\\t%1, %0"
4999 [(set_attr "type" "fp")
5000 (set_attr "fptype" "double")])
5001
5002 (define_expand "trunctfsf2"
5003 [(set (match_operand:SF 0 "register_operand" "=f")
5004 (float_truncate:SF
5005 (match_operand:TF 1 "register_operand" "e")))]
5006 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5007 "
5008 {
5009 if (! TARGET_HARD_QUAD)
5010 {
5011 rtx slot0;
5012
5013 if (GET_CODE (operands[1]) != MEM)
5014 {
5015 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5016 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5017 }
5018 else
5019 slot0 = operands[1];
5020
5021 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5022 operands[0], 0, SFmode, 1,
5023 XEXP (slot0, 0), Pmode);
5024 DONE;
5025 }
5026 }")
5027
5028 (define_insn "*trunctfsf2_hq"
5029 [(set (match_operand:SF 0 "register_operand" "=f")
5030 (float_truncate:SF
5031 (match_operand:TF 1 "register_operand" "e")))]
5032 "TARGET_FPU && TARGET_HARD_QUAD"
5033 "fqtos\\t%1, %0"
5034 [(set_attr "type" "fp")])
5035
5036 (define_expand "trunctfdf2"
5037 [(set (match_operand:DF 0 "register_operand" "=f")
5038 (float_truncate:DF
5039 (match_operand:TF 1 "register_operand" "e")))]
5040 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5041 "
5042 {
5043 if (! TARGET_HARD_QUAD)
5044 {
5045 rtx slot0;
5046
5047 if (GET_CODE (operands[1]) != MEM)
5048 {
5049 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5050 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5051 }
5052 else
5053 slot0 = operands[1];
5054
5055 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5056 operands[0], 0, DFmode, 1,
5057 XEXP (slot0, 0), Pmode);
5058 DONE;
5059 }
5060 }")
5061
5062 (define_insn "*trunctfdf2_hq"
5063 [(set (match_operand:DF 0 "register_operand" "=e")
5064 (float_truncate:DF
5065 (match_operand:TF 1 "register_operand" "e")))]
5066 "TARGET_FPU && TARGET_HARD_QUAD"
5067 "fqtod\\t%1, %0"
5068 [(set_attr "type" "fp")])
5069 \f
5070 ;; Conversion between fixed point and floating point.
5071
5072 (define_insn "floatsisf2"
5073 [(set (match_operand:SF 0 "register_operand" "=f")
5074 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5075 "TARGET_FPU"
5076 "fitos\\t%1, %0"
5077 [(set_attr "type" "fp")
5078 (set_attr "fptype" "double")])
5079
5080 (define_insn "floatsidf2"
5081 [(set (match_operand:DF 0 "register_operand" "=e")
5082 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5083 "TARGET_FPU"
5084 "fitod\\t%1, %0"
5085 [(set_attr "type" "fp")
5086 (set_attr "fptype" "double")])
5087
5088 (define_expand "floatsitf2"
5089 [(set (match_operand:TF 0 "register_operand" "=e")
5090 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5091 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5092 "
5093 {
5094 if (! TARGET_HARD_QUAD)
5095 {
5096 rtx slot0;
5097
5098 if (GET_CODE (operands[1]) != MEM)
5099 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5100 else
5101 slot0 = operands[1];
5102
5103 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5104 VOIDmode, 2,
5105 XEXP (slot0, 0), Pmode,
5106 operands[1], SImode);
5107
5108 if (GET_CODE (operands[0]) != MEM)
5109 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5110 DONE;
5111 }
5112 }")
5113
5114 (define_insn "*floatsitf2_hq"
5115 [(set (match_operand:TF 0 "register_operand" "=e")
5116 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5117 "TARGET_FPU && TARGET_HARD_QUAD"
5118 "fitoq\\t%1, %0"
5119 [(set_attr "type" "fp")])
5120
5121 (define_expand "floatunssitf2"
5122 [(set (match_operand:TF 0 "register_operand" "=e")
5123 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5124 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5125 "
5126 {
5127 rtx slot0;
5128
5129 if (GET_CODE (operands[1]) != MEM)
5130 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5131 else
5132 slot0 = operands[1];
5133
5134 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5135 VOIDmode, 2,
5136 XEXP (slot0, 0), Pmode,
5137 operands[1], SImode);
5138
5139 if (GET_CODE (operands[0]) != MEM)
5140 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5141 DONE;
5142 }")
5143
5144 ;; Now the same for 64 bit sources.
5145
5146 (define_insn "floatdisf2"
5147 [(set (match_operand:SF 0 "register_operand" "=f")
5148 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5149 "TARGET_V9 && TARGET_FPU"
5150 "fxtos\\t%1, %0"
5151 [(set_attr "type" "fp")
5152 (set_attr "fptype" "double")])
5153
5154 (define_insn "floatdidf2"
5155 [(set (match_operand:DF 0 "register_operand" "=e")
5156 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5157 "TARGET_V9 && TARGET_FPU"
5158 "fxtod\\t%1, %0"
5159 [(set_attr "type" "fp")
5160 (set_attr "fptype" "double")])
5161
5162 (define_expand "floatditf2"
5163 [(set (match_operand:TF 0 "register_operand" "=e")
5164 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5165 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5166 "
5167 {
5168 if (! TARGET_HARD_QUAD)
5169 {
5170 rtx slot0;
5171
5172 if (GET_CODE (operands[1]) != MEM)
5173 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5174 else
5175 slot0 = operands[1];
5176
5177 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5178 VOIDmode, 2,
5179 XEXP (slot0, 0), Pmode,
5180 operands[1], DImode);
5181
5182 if (GET_CODE (operands[0]) != MEM)
5183 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5184 DONE;
5185 }
5186 }")
5187
5188 (define_insn "*floatditf2_hq"
5189 [(set (match_operand:TF 0 "register_operand" "=e")
5190 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5191 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5192 "fxtoq\\t%1, %0"
5193 [(set_attr "type" "fp")])
5194
5195 (define_expand "floatunsditf2"
5196 [(set (match_operand:TF 0 "register_operand" "=e")
5197 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5198 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5199 "
5200 {
5201 rtx slot0;
5202
5203 if (GET_CODE (operands[1]) != MEM)
5204 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5205 else
5206 slot0 = operands[1];
5207
5208 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5209 VOIDmode, 2,
5210 XEXP (slot0, 0), Pmode,
5211 operands[1], DImode);
5212
5213 if (GET_CODE (operands[0]) != MEM)
5214 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5215 DONE;
5216 }")
5217
5218 ;; Convert a float to an actual integer.
5219 ;; Truncation is performed as part of the conversion.
5220
5221 (define_insn "fix_truncsfsi2"
5222 [(set (match_operand:SI 0 "register_operand" "=f")
5223 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5224 "TARGET_FPU"
5225 "fstoi\\t%1, %0"
5226 [(set_attr "type" "fp")
5227 (set_attr "fptype" "double")])
5228
5229 (define_insn "fix_truncdfsi2"
5230 [(set (match_operand:SI 0 "register_operand" "=f")
5231 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5232 "TARGET_FPU"
5233 "fdtoi\\t%1, %0"
5234 [(set_attr "type" "fp")
5235 (set_attr "fptype" "double")])
5236
5237 (define_expand "fix_trunctfsi2"
5238 [(set (match_operand:SI 0 "register_operand" "=f")
5239 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5240 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5241 "
5242 {
5243 if (! TARGET_HARD_QUAD)
5244 {
5245 rtx slot0;
5246
5247 if (GET_CODE (operands[1]) != MEM)
5248 {
5249 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5250 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5251 }
5252 else
5253 slot0 = operands[1];
5254
5255 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5256 operands[0], 0, SImode, 1,
5257 XEXP (slot0, 0), Pmode);
5258 DONE;
5259 }
5260 }")
5261
5262 (define_insn "*fix_trunctfsi2_hq"
5263 [(set (match_operand:SI 0 "register_operand" "=f")
5264 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5265 "TARGET_FPU && TARGET_HARD_QUAD"
5266 "fqtoi\\t%1, %0"
5267 [(set_attr "type" "fp")])
5268
5269 (define_expand "fixuns_trunctfsi2"
5270 [(set (match_operand:SI 0 "register_operand" "=f")
5271 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5272 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5273 "
5274 {
5275 rtx slot0;
5276
5277 if (GET_CODE (operands[1]) != MEM)
5278 {
5279 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5280 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5281 }
5282 else
5283 slot0 = operands[1];
5284
5285 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5286 operands[0], 0, SImode, 1,
5287 XEXP (slot0, 0), Pmode);
5288 DONE;
5289 }")
5290
5291 ;; Now the same, for V9 targets
5292
5293 (define_insn "fix_truncsfdi2"
5294 [(set (match_operand:DI 0 "register_operand" "=e")
5295 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5296 "TARGET_V9 && TARGET_FPU"
5297 "fstox\\t%1, %0"
5298 [(set_attr "type" "fp")
5299 (set_attr "fptype" "double")])
5300
5301 (define_insn "fix_truncdfdi2"
5302 [(set (match_operand:DI 0 "register_operand" "=e")
5303 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5304 "TARGET_V9 && TARGET_FPU"
5305 "fdtox\\t%1, %0"
5306 [(set_attr "type" "fp")
5307 (set_attr "fptype" "double")])
5308
5309 (define_expand "fix_trunctfdi2"
5310 [(set (match_operand:DI 0 "register_operand" "=e")
5311 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5312 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5313 "
5314 {
5315 if (! TARGET_HARD_QUAD)
5316 {
5317 rtx slot0;
5318
5319 if (GET_CODE (operands[1]) != MEM)
5320 {
5321 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5322 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5323 }
5324 else
5325 slot0 = operands[1];
5326
5327 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5328 operands[0], 0, DImode, 1,
5329 XEXP (slot0, 0), Pmode);
5330 DONE;
5331 }
5332 }")
5333
5334 (define_insn "*fix_trunctfdi2_hq"
5335 [(set (match_operand:DI 0 "register_operand" "=e")
5336 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5337 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5338 "fqtox\\t%1, %0"
5339 [(set_attr "type" "fp")])
5340
5341 (define_expand "fixuns_trunctfdi2"
5342 [(set (match_operand:DI 0 "register_operand" "=f")
5343 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5344 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5345 "
5346 {
5347 rtx slot0;
5348
5349 if (GET_CODE (operands[1]) != MEM)
5350 {
5351 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5352 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5353 }
5354 else
5355 slot0 = operands[1];
5356
5357 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5358 operands[0], 0, DImode, 1,
5359 XEXP (slot0, 0), Pmode);
5360 DONE;
5361 }")
5362
5363 \f
5364 ;;- arithmetic instructions
5365
5366 (define_expand "adddi3"
5367 [(set (match_operand:DI 0 "register_operand" "=r")
5368 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5369 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5370 ""
5371 "
5372 {
5373 HOST_WIDE_INT i;
5374
5375 if (! TARGET_ARCH64)
5376 {
5377 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5378 gen_rtx_SET (VOIDmode, operands[0],
5379 gen_rtx_PLUS (DImode, operands[1],
5380 operands[2])),
5381 gen_rtx_CLOBBER (VOIDmode,
5382 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5383 DONE;
5384 }
5385 if (arith_double_4096_operand(operands[2], DImode))
5386 {
5387 switch (GET_CODE (operands[1]))
5388 {
5389 case CONST_INT: i = INTVAL (operands[1]); break;
5390 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5391 default:
5392 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5393 gen_rtx_MINUS (DImode, operands[1],
5394 GEN_INT(-4096))));
5395 DONE;
5396 }
5397 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5398 DONE;
5399 }
5400 }")
5401
5402 (define_insn "adddi3_insn_sp32"
5403 [(set (match_operand:DI 0 "register_operand" "=r")
5404 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5405 (match_operand:DI 2 "arith_double_operand" "rHI")))
5406 (clobber (reg:CC 100))]
5407 "! TARGET_ARCH64"
5408 "#"
5409 [(set_attr "length" "2")])
5410
5411 (define_split
5412 [(set (match_operand:DI 0 "register_operand" "")
5413 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5414 (match_operand:DI 2 "arith_double_operand" "")))
5415 (clobber (reg:CC 100))]
5416 "! TARGET_ARCH64 && reload_completed"
5417 [(parallel [(set (reg:CC_NOOV 100)
5418 (compare:CC_NOOV (plus:SI (match_dup 4)
5419 (match_dup 5))
5420 (const_int 0)))
5421 (set (match_dup 3)
5422 (plus:SI (match_dup 4) (match_dup 5)))])
5423 (set (match_dup 6)
5424 (plus:SI (plus:SI (match_dup 7)
5425 (match_dup 8))
5426 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5427 "
5428 {
5429 operands[3] = gen_lowpart (SImode, operands[0]);
5430 operands[4] = gen_lowpart (SImode, operands[1]);
5431 operands[5] = gen_lowpart (SImode, operands[2]);
5432 operands[6] = gen_highpart (SImode, operands[0]);
5433 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5434 #if HOST_BITS_PER_WIDE_INT == 32
5435 if (GET_CODE (operands[2]) == CONST_INT)
5436 {
5437 if (INTVAL (operands[2]) < 0)
5438 operands[8] = constm1_rtx;
5439 else
5440 operands[8] = const0_rtx;
5441 }
5442 else
5443 #endif
5444 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5445 }")
5446
5447 (define_split
5448 [(set (match_operand:DI 0 "register_operand" "")
5449 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5450 (match_operand:DI 2 "arith_double_operand" "")))
5451 (clobber (reg:CC 100))]
5452 "! TARGET_ARCH64 && reload_completed"
5453 [(parallel [(set (reg:CC_NOOV 100)
5454 (compare:CC_NOOV (minus:SI (match_dup 4)
5455 (match_dup 5))
5456 (const_int 0)))
5457 (set (match_dup 3)
5458 (minus:SI (match_dup 4) (match_dup 5)))])
5459 (set (match_dup 6)
5460 (minus:SI (minus:SI (match_dup 7)
5461 (match_dup 8))
5462 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5463 "
5464 {
5465 operands[3] = gen_lowpart (SImode, operands[0]);
5466 operands[4] = gen_lowpart (SImode, operands[1]);
5467 operands[5] = gen_lowpart (SImode, operands[2]);
5468 operands[6] = gen_highpart (SImode, operands[0]);
5469 operands[7] = gen_highpart (SImode, operands[1]);
5470 #if HOST_BITS_PER_WIDE_INT == 32
5471 if (GET_CODE (operands[2]) == CONST_INT)
5472 {
5473 if (INTVAL (operands[2]) < 0)
5474 operands[8] = constm1_rtx;
5475 else
5476 operands[8] = const0_rtx;
5477 }
5478 else
5479 #endif
5480 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5481 }")
5482
5483 ;; LTU here means "carry set"
5484 (define_insn "addx"
5485 [(set (match_operand:SI 0 "register_operand" "=r")
5486 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5487 (match_operand:SI 2 "arith_operand" "rI"))
5488 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5489 ""
5490 "addx\\t%1, %2, %0"
5491 [(set_attr "type" "misc")])
5492
5493 (define_insn "*addx_extend_sp32"
5494 [(set (match_operand:DI 0 "register_operand" "=r")
5495 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5496 (match_operand:SI 2 "arith_operand" "rI"))
5497 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5498 "! TARGET_ARCH64"
5499 "#"
5500 [(set_attr "length" "2")])
5501
5502 (define_split
5503 [(set (match_operand:DI 0 "register_operand" "")
5504 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5505 (match_operand:SI 2 "arith_operand" ""))
5506 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5507 "! TARGET_ARCH64 && reload_completed"
5508 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5509 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5510 (set (match_dup 4) (const_int 0))]
5511 "operands[3] = gen_lowpart (SImode, operands[0]);
5512 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5513
5514 (define_insn "*addx_extend_sp64"
5515 [(set (match_operand:DI 0 "register_operand" "=r")
5516 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5517 (match_operand:SI 2 "arith_operand" "rI"))
5518 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5519 "TARGET_ARCH64"
5520 "addx\\t%r1, %2, %0"
5521 [(set_attr "type" "misc")])
5522
5523 (define_insn "subx"
5524 [(set (match_operand:SI 0 "register_operand" "=r")
5525 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5526 (match_operand:SI 2 "arith_operand" "rI"))
5527 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5528 ""
5529 "subx\\t%r1, %2, %0"
5530 [(set_attr "type" "misc")])
5531
5532 (define_insn "*subx_extend_sp64"
5533 [(set (match_operand:DI 0 "register_operand" "=r")
5534 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5535 (match_operand:SI 2 "arith_operand" "rI"))
5536 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5537 "TARGET_ARCH64"
5538 "subx\\t%r1, %2, %0"
5539 [(set_attr "type" "misc")])
5540
5541 (define_insn "*subx_extend"
5542 [(set (match_operand:DI 0 "register_operand" "=r")
5543 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5544 (match_operand:SI 2 "arith_operand" "rI"))
5545 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5546 "! TARGET_ARCH64"
5547 "#"
5548 [(set_attr "length" "2")])
5549
5550 (define_split
5551 [(set (match_operand:DI 0 "register_operand" "")
5552 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5553 (match_operand:SI 2 "arith_operand" ""))
5554 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5555 "! TARGET_ARCH64 && reload_completed"
5556 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5557 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5558 (set (match_dup 4) (const_int 0))]
5559 "operands[3] = gen_lowpart (SImode, operands[0]);
5560 operands[4] = gen_highpart (SImode, operands[0]);")
5561
5562 (define_insn ""
5563 [(set (match_operand:DI 0 "register_operand" "=r")
5564 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5565 (match_operand:DI 2 "register_operand" "r")))
5566 (clobber (reg:CC 100))]
5567 "! TARGET_ARCH64"
5568 "#"
5569 [(set_attr "length" "2")])
5570
5571 (define_split
5572 [(set (match_operand:DI 0 "register_operand" "")
5573 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5574 (match_operand:DI 2 "register_operand" "")))
5575 (clobber (reg:CC 100))]
5576 "! TARGET_ARCH64 && reload_completed"
5577 [(parallel [(set (reg:CC_NOOV 100)
5578 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5579 (const_int 0)))
5580 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5581 (set (match_dup 6)
5582 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5583 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5584 "operands[3] = gen_lowpart (SImode, operands[2]);
5585 operands[4] = gen_highpart (SImode, operands[2]);
5586 operands[5] = gen_lowpart (SImode, operands[0]);
5587 operands[6] = gen_highpart (SImode, operands[0]);")
5588
5589 (define_insn "*adddi3_sp64"
5590 [(set (match_operand:DI 0 "register_operand" "=r")
5591 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5592 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5593 "TARGET_ARCH64"
5594 "add\\t%1, %2, %0")
5595
5596 (define_expand "addsi3"
5597 [(set (match_operand:SI 0 "register_operand" "=r,d")
5598 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5599 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5600 ""
5601 "
5602 {
5603 if (arith_4096_operand(operands[2], SImode))
5604 {
5605 if (GET_CODE (operands[1]) == CONST_INT)
5606 emit_insn (gen_movsi (operands[0],
5607 GEN_INT (INTVAL (operands[1]) + 4096)));
5608 else
5609 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5610 gen_rtx_MINUS (SImode, operands[1],
5611 GEN_INT(-4096))));
5612 DONE;
5613 }
5614 }")
5615
5616 (define_insn "*addsi3"
5617 [(set (match_operand:SI 0 "register_operand" "=r,d")
5618 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5619 (match_operand:SI 2 "arith_operand" "rI,d")))]
5620 ""
5621 "@
5622 add\\t%1, %2, %0
5623 fpadd32s\\t%1, %2, %0"
5624 [(set_attr "type" "*,fp")])
5625
5626 (define_insn "*cmp_cc_plus"
5627 [(set (reg:CC_NOOV 100)
5628 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5629 (match_operand:SI 1 "arith_operand" "rI"))
5630 (const_int 0)))]
5631 ""
5632 "addcc\\t%0, %1, %%g0"
5633 [(set_attr "type" "compare")])
5634
5635 (define_insn "*cmp_ccx_plus"
5636 [(set (reg:CCX_NOOV 100)
5637 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5638 (match_operand:DI 1 "arith_double_operand" "rHI"))
5639 (const_int 0)))]
5640 "TARGET_ARCH64"
5641 "addcc\\t%0, %1, %%g0"
5642 [(set_attr "type" "compare")])
5643
5644 (define_insn "*cmp_cc_plus_set"
5645 [(set (reg:CC_NOOV 100)
5646 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5647 (match_operand:SI 2 "arith_operand" "rI"))
5648 (const_int 0)))
5649 (set (match_operand:SI 0 "register_operand" "=r")
5650 (plus:SI (match_dup 1) (match_dup 2)))]
5651 ""
5652 "addcc\\t%1, %2, %0"
5653 [(set_attr "type" "compare")])
5654
5655 (define_insn "*cmp_ccx_plus_set"
5656 [(set (reg:CCX_NOOV 100)
5657 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5658 (match_operand:DI 2 "arith_double_operand" "rHI"))
5659 (const_int 0)))
5660 (set (match_operand:DI 0 "register_operand" "=r")
5661 (plus:DI (match_dup 1) (match_dup 2)))]
5662 "TARGET_ARCH64"
5663 "addcc\\t%1, %2, %0"
5664 [(set_attr "type" "compare")])
5665
5666 (define_expand "subdi3"
5667 [(set (match_operand:DI 0 "register_operand" "=r")
5668 (minus:DI (match_operand:DI 1 "register_operand" "r")
5669 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5670 ""
5671 "
5672 {
5673 if (! TARGET_ARCH64)
5674 {
5675 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5676 gen_rtx_SET (VOIDmode, operands[0],
5677 gen_rtx_MINUS (DImode, operands[1],
5678 operands[2])),
5679 gen_rtx_CLOBBER (VOIDmode,
5680 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5681 DONE;
5682 }
5683 if (arith_double_4096_operand(operands[2], DImode))
5684 {
5685 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5686 gen_rtx_PLUS (DImode, operands[1],
5687 GEN_INT(-4096))));
5688 DONE;
5689 }
5690 }")
5691
5692 (define_insn "*subdi3_sp32"
5693 [(set (match_operand:DI 0 "register_operand" "=r")
5694 (minus:DI (match_operand:DI 1 "register_operand" "r")
5695 (match_operand:DI 2 "arith_double_operand" "rHI")))
5696 (clobber (reg:CC 100))]
5697 "! TARGET_ARCH64"
5698 "#"
5699 [(set_attr "length" "2")])
5700
5701 (define_split
5702 [(set (match_operand:DI 0 "register_operand" "")
5703 (minus:DI (match_operand:DI 1 "register_operand" "")
5704 (match_operand:DI 2 "arith_double_operand" "")))
5705 (clobber (reg:CC 100))]
5706 "! TARGET_ARCH64
5707 && reload_completed
5708 && (GET_CODE (operands[2]) == CONST_INT
5709 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5710 [(clobber (const_int 0))]
5711 "
5712 {
5713 rtx highp, lowp;
5714
5715 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5716 lowp = gen_lowpart (SImode, operands[2]);
5717 if ((lowp == const0_rtx)
5718 && (operands[0] == operands[1]))
5719 {
5720 emit_insn (gen_rtx_SET (VOIDmode,
5721 gen_highpart (SImode, operands[0]),
5722 gen_rtx_MINUS (SImode,
5723 gen_highpart_mode (SImode, DImode,
5724 operands[1]),
5725 highp)));
5726 }
5727 else
5728 {
5729 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5730 gen_lowpart (SImode, operands[1]),
5731 lowp));
5732 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5733 gen_highpart_mode (SImode, DImode, operands[1]),
5734 highp));
5735 }
5736 DONE;
5737 }")
5738
5739 (define_split
5740 [(set (match_operand:DI 0 "register_operand" "")
5741 (minus:DI (match_operand:DI 1 "register_operand" "")
5742 (match_operand:DI 2 "register_operand" "")))
5743 (clobber (reg:CC 100))]
5744 "! TARGET_ARCH64
5745 && reload_completed"
5746 [(clobber (const_int 0))]
5747 "
5748 {
5749 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5750 gen_lowpart (SImode, operands[1]),
5751 gen_lowpart (SImode, operands[2])));
5752 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5753 gen_highpart (SImode, operands[1]),
5754 gen_highpart (SImode, operands[2])));
5755 DONE;
5756 }")
5757
5758 (define_insn ""
5759 [(set (match_operand:DI 0 "register_operand" "=r")
5760 (minus:DI (match_operand:DI 1 "register_operand" "r")
5761 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5762 (clobber (reg:CC 100))]
5763 "! TARGET_ARCH64"
5764 "#"
5765 [(set_attr "length" "2")])
5766
5767 (define_split
5768 [(set (match_operand:DI 0 "register_operand" "")
5769 (minus:DI (match_operand:DI 1 "register_operand" "")
5770 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5771 (clobber (reg:CC 100))]
5772 "! TARGET_ARCH64 && reload_completed"
5773 [(parallel [(set (reg:CC_NOOV 100)
5774 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5775 (const_int 0)))
5776 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5777 (set (match_dup 6)
5778 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5779 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5780 "operands[3] = gen_lowpart (SImode, operands[1]);
5781 operands[4] = gen_highpart (SImode, operands[1]);
5782 operands[5] = gen_lowpart (SImode, operands[0]);
5783 operands[6] = gen_highpart (SImode, operands[0]);")
5784
5785 (define_insn "*subdi3_sp64"
5786 [(set (match_operand:DI 0 "register_operand" "=r")
5787 (minus:DI (match_operand:DI 1 "register_operand" "r")
5788 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5789 "TARGET_ARCH64"
5790 "sub\\t%1, %2, %0")
5791
5792 (define_expand "subsi3"
5793 [(set (match_operand:SI 0 "register_operand" "=r,d")
5794 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5795 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5796 ""
5797 "
5798 {
5799 if (arith_4096_operand(operands[2], SImode))
5800 {
5801 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5802 gen_rtx_PLUS (SImode, operands[1],
5803 GEN_INT(-4096))));
5804 DONE;
5805 }
5806 }")
5807
5808 (define_insn "*subsi3"
5809 [(set (match_operand:SI 0 "register_operand" "=r,d")
5810 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5811 (match_operand:SI 2 "arith_operand" "rI,d")))]
5812 ""
5813 "@
5814 sub\\t%1, %2, %0
5815 fpsub32s\\t%1, %2, %0"
5816 [(set_attr "type" "*,fp")])
5817
5818 (define_insn "*cmp_minus_cc"
5819 [(set (reg:CC_NOOV 100)
5820 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5821 (match_operand:SI 1 "arith_operand" "rI"))
5822 (const_int 0)))]
5823 ""
5824 "subcc\\t%r0, %1, %%g0"
5825 [(set_attr "type" "compare")])
5826
5827 (define_insn "*cmp_minus_ccx"
5828 [(set (reg:CCX_NOOV 100)
5829 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5830 (match_operand:DI 1 "arith_double_operand" "rHI"))
5831 (const_int 0)))]
5832 "TARGET_ARCH64"
5833 "subcc\\t%0, %1, %%g0"
5834 [(set_attr "type" "compare")])
5835
5836 (define_insn "cmp_minus_cc_set"
5837 [(set (reg:CC_NOOV 100)
5838 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5839 (match_operand:SI 2 "arith_operand" "rI"))
5840 (const_int 0)))
5841 (set (match_operand:SI 0 "register_operand" "=r")
5842 (minus:SI (match_dup 1) (match_dup 2)))]
5843 ""
5844 "subcc\\t%r1, %2, %0"
5845 [(set_attr "type" "compare")])
5846
5847 (define_insn "*cmp_minus_ccx_set"
5848 [(set (reg:CCX_NOOV 100)
5849 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5850 (match_operand:DI 2 "arith_double_operand" "rHI"))
5851 (const_int 0)))
5852 (set (match_operand:DI 0 "register_operand" "=r")
5853 (minus:DI (match_dup 1) (match_dup 2)))]
5854 "TARGET_ARCH64"
5855 "subcc\\t%1, %2, %0"
5856 [(set_attr "type" "compare")])
5857 \f
5858 ;; Integer Multiply/Divide.
5859
5860 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5861 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5862
5863 (define_insn "mulsi3"
5864 [(set (match_operand:SI 0 "register_operand" "=r")
5865 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5866 (match_operand:SI 2 "arith_operand" "rI")))]
5867 "TARGET_HARD_MUL"
5868 "smul\\t%1, %2, %0"
5869 [(set_attr "type" "imul")])
5870
5871 (define_expand "muldi3"
5872 [(set (match_operand:DI 0 "register_operand" "=r")
5873 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5874 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5875 "TARGET_ARCH64 || TARGET_V8PLUS"
5876 "
5877 {
5878 if (TARGET_V8PLUS)
5879 {
5880 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5881 DONE;
5882 }
5883 }")
5884
5885 (define_insn "*muldi3_sp64"
5886 [(set (match_operand:DI 0 "register_operand" "=r")
5887 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5888 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5889 "TARGET_ARCH64"
5890 "mulx\\t%1, %2, %0"
5891 [(set_attr "type" "imul")])
5892
5893 ;; V8plus wide multiply.
5894 ;; XXX
5895 (define_insn "muldi3_v8plus"
5896 [(set (match_operand:DI 0 "register_operand" "=r,h")
5897 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5898 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5899 (clobber (match_scratch:SI 3 "=&h,X"))
5900 (clobber (match_scratch:SI 4 "=&h,X"))]
5901 "TARGET_V8PLUS"
5902 "*
5903 {
5904 if (sparc_check_64 (operands[1], insn) <= 0)
5905 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5906 if (which_alternative == 1)
5907 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5908 if (GET_CODE (operands[2]) == CONST_INT)
5909 {
5910 if (which_alternative == 1)
5911 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5912 else
5913 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\";
5914 }
5915 if (sparc_check_64 (operands[2], insn) <= 0)
5916 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5917 if (which_alternative == 1)
5918 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\";
5919 else
5920 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\";
5921 }"
5922 [(set_attr "type" "multi")
5923 (set_attr "length" "9,8")])
5924
5925 (define_insn "*cmp_mul_set"
5926 [(set (reg:CC 100)
5927 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5928 (match_operand:SI 2 "arith_operand" "rI"))
5929 (const_int 0)))
5930 (set (match_operand:SI 0 "register_operand" "=r")
5931 (mult:SI (match_dup 1) (match_dup 2)))]
5932 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5933 "smulcc\\t%1, %2, %0"
5934 [(set_attr "type" "imul")])
5935
5936 (define_expand "mulsidi3"
5937 [(set (match_operand:DI 0 "register_operand" "")
5938 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5939 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5940 "TARGET_HARD_MUL"
5941 "
5942 {
5943 if (CONSTANT_P (operands[2]))
5944 {
5945 if (TARGET_V8PLUS)
5946 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5947 operands[2]));
5948 else
5949 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5950 operands[2]));
5951 DONE;
5952 }
5953 if (TARGET_V8PLUS)
5954 {
5955 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5956 DONE;
5957 }
5958 }")
5959
5960 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5961 ;; registers can hold 64 bit values in the V8plus environment.
5962 ;; XXX
5963 (define_insn "mulsidi3_v8plus"
5964 [(set (match_operand:DI 0 "register_operand" "=h,r")
5965 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5966 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5967 (clobber (match_scratch:SI 3 "=X,&h"))]
5968 "TARGET_V8PLUS"
5969 "@
5970 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5971 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5972 [(set_attr "type" "multi")
5973 (set_attr "length" "2,3")])
5974
5975 ;; XXX
5976 (define_insn "const_mulsidi3_v8plus"
5977 [(set (match_operand:DI 0 "register_operand" "=h,r")
5978 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5979 (match_operand:SI 2 "small_int" "I,I")))
5980 (clobber (match_scratch:SI 3 "=X,&h"))]
5981 "TARGET_V8PLUS"
5982 "@
5983 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5984 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5985 [(set_attr "type" "multi")
5986 (set_attr "length" "2,3")])
5987
5988 ;; XXX
5989 (define_insn "*mulsidi3_sp32"
5990 [(set (match_operand:DI 0 "register_operand" "=r")
5991 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5992 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5993 "TARGET_HARD_MUL32"
5994 "*
5995 {
5996 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5997 }"
5998 [(set (attr "type")
5999 (if_then_else (eq_attr "isa" "sparclet")
6000 (const_string "imul") (const_string "multi")))
6001 (set (attr "length")
6002 (if_then_else (eq_attr "isa" "sparclet")
6003 (const_int 1) (const_int 2)))])
6004
6005 (define_insn "*mulsidi3_sp64"
6006 [(set (match_operand:DI 0 "register_operand" "=r")
6007 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6008 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6009 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6010 "smul\\t%1, %2, %0"
6011 [(set_attr "type" "imul")])
6012
6013 ;; Extra pattern, because sign_extend of a constant isn't valid.
6014
6015 ;; XXX
6016 (define_insn "const_mulsidi3_sp32"
6017 [(set (match_operand:DI 0 "register_operand" "=r")
6018 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6019 (match_operand:SI 2 "small_int" "I")))]
6020 "TARGET_HARD_MUL32"
6021 "*
6022 {
6023 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6024 }"
6025 [(set (attr "type")
6026 (if_then_else (eq_attr "isa" "sparclet")
6027 (const_string "imul") (const_string "multi")))
6028 (set (attr "length")
6029 (if_then_else (eq_attr "isa" "sparclet")
6030 (const_int 1) (const_int 2)))])
6031
6032 (define_insn "const_mulsidi3_sp64"
6033 [(set (match_operand:DI 0 "register_operand" "=r")
6034 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6035 (match_operand:SI 2 "small_int" "I")))]
6036 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6037 "smul\\t%1, %2, %0"
6038 [(set_attr "type" "imul")])
6039
6040 (define_expand "smulsi3_highpart"
6041 [(set (match_operand:SI 0 "register_operand" "")
6042 (truncate:SI
6043 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6044 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6045 (const_int 32))))]
6046 "TARGET_HARD_MUL && TARGET_ARCH32"
6047 "
6048 {
6049 if (CONSTANT_P (operands[2]))
6050 {
6051 if (TARGET_V8PLUS)
6052 {
6053 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6054 operands[1],
6055 operands[2],
6056 GEN_INT (32)));
6057 DONE;
6058 }
6059 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6060 DONE;
6061 }
6062 if (TARGET_V8PLUS)
6063 {
6064 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6065 operands[2], GEN_INT (32)));
6066 DONE;
6067 }
6068 }")
6069
6070 ;; XXX
6071 (define_insn "smulsi3_highpart_v8plus"
6072 [(set (match_operand:SI 0 "register_operand" "=h,r")
6073 (truncate:SI
6074 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6075 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6076 (match_operand:SI 3 "const_int_operand" "i,i"))))
6077 (clobber (match_scratch:SI 4 "=X,&h"))]
6078 "TARGET_V8PLUS"
6079 "@
6080 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6081 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6082 [(set_attr "type" "multi")
6083 (set_attr "length" "2")])
6084
6085 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6086 ;; XXX
6087 (define_insn ""
6088 [(set (match_operand:SI 0 "register_operand" "=h,r")
6089 (subreg:SI
6090 (lshiftrt:DI
6091 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6092 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6093 (match_operand:SI 3 "const_int_operand" "i,i"))
6094 4))
6095 (clobber (match_scratch:SI 4 "=X,&h"))]
6096 "TARGET_V8PLUS"
6097 "@
6098 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6099 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6100 [(set_attr "type" "multi")
6101 (set_attr "length" "2")])
6102
6103 ;; XXX
6104 (define_insn "const_smulsi3_highpart_v8plus"
6105 [(set (match_operand:SI 0 "register_operand" "=h,r")
6106 (truncate:SI
6107 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6108 (match_operand 2 "small_int" "i,i"))
6109 (match_operand:SI 3 "const_int_operand" "i,i"))))
6110 (clobber (match_scratch:SI 4 "=X,&h"))]
6111 "TARGET_V8PLUS"
6112 "@
6113 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6114 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6115 [(set_attr "type" "multi")
6116 (set_attr "length" "2")])
6117
6118 ;; XXX
6119 (define_insn "*smulsi3_highpart_sp32"
6120 [(set (match_operand:SI 0 "register_operand" "=r")
6121 (truncate:SI
6122 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6123 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6124 (const_int 32))))]
6125 "TARGET_HARD_MUL32"
6126 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6127 [(set_attr "type" "multi")
6128 (set_attr "length" "2")])
6129
6130 ;; XXX
6131 (define_insn "const_smulsi3_highpart"
6132 [(set (match_operand:SI 0 "register_operand" "=r")
6133 (truncate:SI
6134 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6135 (match_operand:SI 2 "register_operand" "r"))
6136 (const_int 32))))]
6137 "TARGET_HARD_MUL32"
6138 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6139 [(set_attr "type" "multi")
6140 (set_attr "length" "2")])
6141
6142 (define_expand "umulsidi3"
6143 [(set (match_operand:DI 0 "register_operand" "")
6144 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6145 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6146 "TARGET_HARD_MUL"
6147 "
6148 {
6149 if (CONSTANT_P (operands[2]))
6150 {
6151 if (TARGET_V8PLUS)
6152 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6153 operands[2]));
6154 else
6155 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6156 operands[2]));
6157 DONE;
6158 }
6159 if (TARGET_V8PLUS)
6160 {
6161 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6162 DONE;
6163 }
6164 }")
6165
6166 ;; XXX
6167 (define_insn "umulsidi3_v8plus"
6168 [(set (match_operand:DI 0 "register_operand" "=h,r")
6169 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6170 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6171 (clobber (match_scratch:SI 3 "=X,&h"))]
6172 "TARGET_V8PLUS"
6173 "@
6174 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6175 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6176 [(set_attr "type" "multi")
6177 (set_attr "length" "2,3")])
6178
6179 ;; XXX
6180 (define_insn "*umulsidi3_sp32"
6181 [(set (match_operand:DI 0 "register_operand" "=r")
6182 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6183 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6184 "TARGET_HARD_MUL32"
6185 "*
6186 {
6187 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6188 }"
6189 [(set (attr "type")
6190 (if_then_else (eq_attr "isa" "sparclet")
6191 (const_string "imul") (const_string "multi")))
6192 (set (attr "length")
6193 (if_then_else (eq_attr "isa" "sparclet")
6194 (const_int 1) (const_int 2)))])
6195
6196 (define_insn "*umulsidi3_sp64"
6197 [(set (match_operand:DI 0 "register_operand" "=r")
6198 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6199 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6200 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6201 "umul\\t%1, %2, %0"
6202 [(set_attr "type" "imul")])
6203
6204 ;; Extra pattern, because sign_extend of a constant isn't valid.
6205
6206 ;; XXX
6207 (define_insn "const_umulsidi3_sp32"
6208 [(set (match_operand:DI 0 "register_operand" "=r")
6209 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6210 (match_operand:SI 2 "uns_small_int" "")))]
6211 "TARGET_HARD_MUL32"
6212 "*
6213 {
6214 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6215 }"
6216 [(set (attr "type")
6217 (if_then_else (eq_attr "isa" "sparclet")
6218 (const_string "imul") (const_string "multi")))
6219 (set (attr "length")
6220 (if_then_else (eq_attr "isa" "sparclet")
6221 (const_int 1) (const_int 2)))])
6222
6223 (define_insn "const_umulsidi3_sp64"
6224 [(set (match_operand:DI 0 "register_operand" "=r")
6225 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6226 (match_operand:SI 2 "uns_small_int" "")))]
6227 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6228 "umul\\t%1, %2, %0"
6229 [(set_attr "type" "imul")])
6230
6231 ;; XXX
6232 (define_insn "const_umulsidi3_v8plus"
6233 [(set (match_operand:DI 0 "register_operand" "=h,r")
6234 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6235 (match_operand:SI 2 "uns_small_int" "")))
6236 (clobber (match_scratch:SI 3 "=X,h"))]
6237 "TARGET_V8PLUS"
6238 "@
6239 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6240 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6241 [(set_attr "type" "multi")
6242 (set_attr "length" "2,3")])
6243
6244 (define_expand "umulsi3_highpart"
6245 [(set (match_operand:SI 0 "register_operand" "")
6246 (truncate:SI
6247 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6248 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6249 (const_int 32))))]
6250 "TARGET_HARD_MUL && TARGET_ARCH32"
6251 "
6252 {
6253 if (CONSTANT_P (operands[2]))
6254 {
6255 if (TARGET_V8PLUS)
6256 {
6257 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6258 operands[1],
6259 operands[2],
6260 GEN_INT (32)));
6261 DONE;
6262 }
6263 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6264 DONE;
6265 }
6266 if (TARGET_V8PLUS)
6267 {
6268 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6269 operands[2], GEN_INT (32)));
6270 DONE;
6271 }
6272 }")
6273
6274 ;; XXX
6275 (define_insn "umulsi3_highpart_v8plus"
6276 [(set (match_operand:SI 0 "register_operand" "=h,r")
6277 (truncate:SI
6278 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6279 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6280 (match_operand:SI 3 "const_int_operand" "i,i"))))
6281 (clobber (match_scratch:SI 4 "=X,h"))]
6282 "TARGET_V8PLUS"
6283 "@
6284 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6285 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6286 [(set_attr "type" "multi")
6287 (set_attr "length" "2")])
6288
6289 ;; XXX
6290 (define_insn "const_umulsi3_highpart_v8plus"
6291 [(set (match_operand:SI 0 "register_operand" "=h,r")
6292 (truncate:SI
6293 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6294 (match_operand:SI 2 "uns_small_int" ""))
6295 (match_operand:SI 3 "const_int_operand" "i,i"))))
6296 (clobber (match_scratch:SI 4 "=X,h"))]
6297 "TARGET_V8PLUS"
6298 "@
6299 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6300 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6301 [(set_attr "type" "multi")
6302 (set_attr "length" "2")])
6303
6304 ;; XXX
6305 (define_insn "*umulsi3_highpart_sp32"
6306 [(set (match_operand:SI 0 "register_operand" "=r")
6307 (truncate:SI
6308 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6309 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6310 (const_int 32))))]
6311 "TARGET_HARD_MUL32"
6312 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6313 [(set_attr "type" "multi")
6314 (set_attr "length" "2")])
6315
6316 ;; XXX
6317 (define_insn "const_umulsi3_highpart"
6318 [(set (match_operand:SI 0 "register_operand" "=r")
6319 (truncate:SI
6320 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6321 (match_operand:SI 2 "uns_small_int" ""))
6322 (const_int 32))))]
6323 "TARGET_HARD_MUL32"
6324 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6325 [(set_attr "type" "multi")
6326 (set_attr "length" "2")])
6327
6328 ;; The v8 architecture specifies that there must be 3 instructions between
6329 ;; a y register write and a use of it for correct results.
6330
6331 (define_expand "divsi3"
6332 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6333 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6334 (match_operand:SI 2 "input_operand" "rI,m")))
6335 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6336 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6337 "
6338 {
6339 if (TARGET_ARCH64)
6340 {
6341 operands[3] = gen_reg_rtx(SImode);
6342 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6343 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6344 operands[3]));
6345 DONE;
6346 }
6347 }")
6348
6349 (define_insn "divsi3_sp32"
6350 [(set (match_operand:SI 0 "register_operand" "=r,r")
6351 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6352 (match_operand:SI 2 "input_operand" "rI,m")))
6353 (clobber (match_scratch:SI 3 "=&r,&r"))]
6354 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6355 && TARGET_ARCH32"
6356 "*
6357 {
6358 if (which_alternative == 0)
6359 if (TARGET_V9)
6360 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6361 else
6362 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6363 else
6364 if (TARGET_V9)
6365 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6366 else
6367 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\";
6368 }"
6369 [(set_attr "type" "multi")
6370 (set (attr "length")
6371 (if_then_else (eq_attr "isa" "v9")
6372 (const_int 4) (const_int 7)))])
6373
6374 (define_insn "divsi3_sp64"
6375 [(set (match_operand:SI 0 "register_operand" "=r")
6376 (div:SI (match_operand:SI 1 "register_operand" "r")
6377 (match_operand:SI 2 "input_operand" "rI")))
6378 (use (match_operand:SI 3 "register_operand" "r"))]
6379 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6380 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6381 [(set_attr "type" "multi")
6382 (set_attr "length" "2")])
6383
6384 (define_insn "divdi3"
6385 [(set (match_operand:DI 0 "register_operand" "=r")
6386 (div:DI (match_operand:DI 1 "register_operand" "r")
6387 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6388 "TARGET_ARCH64"
6389 "sdivx\\t%1, %2, %0"
6390 [(set_attr "type" "idiv")])
6391
6392 (define_insn "*cmp_sdiv_cc_set"
6393 [(set (reg:CC 100)
6394 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6395 (match_operand:SI 2 "arith_operand" "rI"))
6396 (const_int 0)))
6397 (set (match_operand:SI 0 "register_operand" "=r")
6398 (div:SI (match_dup 1) (match_dup 2)))
6399 (clobber (match_scratch:SI 3 "=&r"))]
6400 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6401 "*
6402 {
6403 if (TARGET_V9)
6404 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6405 else
6406 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6407 }"
6408 [(set_attr "type" "multi")
6409 (set (attr "length")
6410 (if_then_else (eq_attr "isa" "v9")
6411 (const_int 3) (const_int 6)))])
6412
6413 ;; XXX
6414 (define_expand "udivsi3"
6415 [(set (match_operand:SI 0 "register_operand" "")
6416 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6417 (match_operand:SI 2 "input_operand" "")))]
6418 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6419 "")
6420
6421 (define_insn "udivsi3_sp32"
6422 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6423 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6424 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6425 "(TARGET_V8
6426 || TARGET_DEPRECATED_V8_INSNS)
6427 && TARGET_ARCH32"
6428 "*
6429 {
6430 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6431 switch (which_alternative)
6432 {
6433 default:
6434 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6435 case 1:
6436 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6437 case 2:
6438 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6439 }
6440 }"
6441 [(set_attr "type" "multi")
6442 (set_attr "length" "5")])
6443
6444 (define_insn "udivsi3_sp64"
6445 [(set (match_operand:SI 0 "register_operand" "=r")
6446 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6447 (match_operand:SI 2 "input_operand" "rI")))]
6448 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6449 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6450 [(set_attr "type" "multi")
6451 (set_attr "length" "2")])
6452
6453 (define_insn "udivdi3"
6454 [(set (match_operand:DI 0 "register_operand" "=r")
6455 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6456 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6457 "TARGET_ARCH64"
6458 "udivx\\t%1, %2, %0"
6459 [(set_attr "type" "idiv")])
6460
6461 (define_insn "*cmp_udiv_cc_set"
6462 [(set (reg:CC 100)
6463 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6464 (match_operand:SI 2 "arith_operand" "rI"))
6465 (const_int 0)))
6466 (set (match_operand:SI 0 "register_operand" "=r")
6467 (udiv:SI (match_dup 1) (match_dup 2)))]
6468 "TARGET_V8
6469 || TARGET_DEPRECATED_V8_INSNS"
6470 "*
6471 {
6472 if (TARGET_V9)
6473 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6474 else
6475 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6476 }"
6477 [(set_attr "type" "multi")
6478 (set (attr "length")
6479 (if_then_else (eq_attr "isa" "v9")
6480 (const_int 2) (const_int 5)))])
6481
6482 ; sparclet multiply/accumulate insns
6483
6484 (define_insn "*smacsi"
6485 [(set (match_operand:SI 0 "register_operand" "=r")
6486 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6487 (match_operand:SI 2 "arith_operand" "rI"))
6488 (match_operand:SI 3 "register_operand" "0")))]
6489 "TARGET_SPARCLET"
6490 "smac\\t%1, %2, %0"
6491 [(set_attr "type" "imul")])
6492
6493 (define_insn "*smacdi"
6494 [(set (match_operand:DI 0 "register_operand" "=r")
6495 (plus:DI (mult:DI (sign_extend:DI
6496 (match_operand:SI 1 "register_operand" "%r"))
6497 (sign_extend:DI
6498 (match_operand:SI 2 "register_operand" "r")))
6499 (match_operand:DI 3 "register_operand" "0")))]
6500 "TARGET_SPARCLET"
6501 "smacd\\t%1, %2, %L0"
6502 [(set_attr "type" "imul")])
6503
6504 (define_insn "*umacdi"
6505 [(set (match_operand:DI 0 "register_operand" "=r")
6506 (plus:DI (mult:DI (zero_extend:DI
6507 (match_operand:SI 1 "register_operand" "%r"))
6508 (zero_extend:DI
6509 (match_operand:SI 2 "register_operand" "r")))
6510 (match_operand:DI 3 "register_operand" "0")))]
6511 "TARGET_SPARCLET"
6512 "umacd\\t%1, %2, %L0"
6513 [(set_attr "type" "imul")])
6514 \f
6515 ;;- Boolean instructions
6516 ;; We define DImode `and' so with DImode `not' we can get
6517 ;; DImode `andn'. Other combinations are possible.
6518
6519 (define_expand "anddi3"
6520 [(set (match_operand:DI 0 "register_operand" "")
6521 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6522 (match_operand:DI 2 "arith_double_operand" "")))]
6523 ""
6524 "")
6525
6526 (define_insn "*anddi3_sp32"
6527 [(set (match_operand:DI 0 "register_operand" "=r,b")
6528 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6529 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6530 "! TARGET_ARCH64"
6531 "@
6532 #
6533 fand\\t%1, %2, %0"
6534 [(set_attr "type" "*,fp")
6535 (set_attr "length" "2,*")
6536 (set_attr "fptype" "double")])
6537
6538 (define_insn "*anddi3_sp64"
6539 [(set (match_operand:DI 0 "register_operand" "=r,b")
6540 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6541 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6542 "TARGET_ARCH64"
6543 "@
6544 and\\t%1, %2, %0
6545 fand\\t%1, %2, %0"
6546 [(set_attr "type" "*,fp")
6547 (set_attr "fptype" "double")])
6548
6549 (define_insn "andsi3"
6550 [(set (match_operand:SI 0 "register_operand" "=r,d")
6551 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6552 (match_operand:SI 2 "arith_operand" "rI,d")))]
6553 ""
6554 "@
6555 and\\t%1, %2, %0
6556 fands\\t%1, %2, %0"
6557 [(set_attr "type" "*,fp")])
6558
6559 (define_split
6560 [(set (match_operand:SI 0 "register_operand" "")
6561 (and:SI (match_operand:SI 1 "register_operand" "")
6562 (match_operand:SI 2 "" "")))
6563 (clobber (match_operand:SI 3 "register_operand" ""))]
6564 "GET_CODE (operands[2]) == CONST_INT
6565 && !SMALL_INT32 (operands[2])
6566 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6567 [(set (match_dup 3) (match_dup 4))
6568 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6569 "
6570 {
6571 operands[4] = GEN_INT (~INTVAL (operands[2]));
6572 }")
6573
6574 ;; Split DImode logical operations requiring two instructions.
6575 (define_split
6576 [(set (match_operand:DI 0 "register_operand" "")
6577 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6578 [(match_operand:DI 2 "register_operand" "")
6579 (match_operand:DI 3 "arith_double_operand" "")]))]
6580 "! TARGET_ARCH64
6581 && reload_completed
6582 && ((GET_CODE (operands[0]) == REG
6583 && REGNO (operands[0]) < 32)
6584 || (GET_CODE (operands[0]) == SUBREG
6585 && GET_CODE (SUBREG_REG (operands[0])) == REG
6586 && REGNO (SUBREG_REG (operands[0])) < 32))"
6587 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6588 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6589 "
6590 {
6591 operands[4] = gen_highpart (SImode, operands[0]);
6592 operands[5] = gen_lowpart (SImode, operands[0]);
6593 operands[6] = gen_highpart (SImode, operands[2]);
6594 operands[7] = gen_lowpart (SImode, operands[2]);
6595 #if HOST_BITS_PER_WIDE_INT == 32
6596 if (GET_CODE (operands[3]) == CONST_INT)
6597 {
6598 if (INTVAL (operands[3]) < 0)
6599 operands[8] = constm1_rtx;
6600 else
6601 operands[8] = const0_rtx;
6602 }
6603 else
6604 #endif
6605 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6606 operands[9] = gen_lowpart (SImode, operands[3]);
6607 }")
6608
6609 (define_insn "*and_not_di_sp32"
6610 [(set (match_operand:DI 0 "register_operand" "=r,b")
6611 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6612 (match_operand:DI 2 "register_operand" "r,b")))]
6613 "! TARGET_ARCH64"
6614 "@
6615 #
6616 fandnot1\\t%1, %2, %0"
6617 [(set_attr "type" "*,fp")
6618 (set_attr "length" "2,*")
6619 (set_attr "fptype" "double")])
6620
6621 (define_split
6622 [(set (match_operand:DI 0 "register_operand" "")
6623 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6624 (match_operand:DI 2 "register_operand" "")))]
6625 "! TARGET_ARCH64
6626 && reload_completed
6627 && ((GET_CODE (operands[0]) == REG
6628 && REGNO (operands[0]) < 32)
6629 || (GET_CODE (operands[0]) == SUBREG
6630 && GET_CODE (SUBREG_REG (operands[0])) == REG
6631 && REGNO (SUBREG_REG (operands[0])) < 32))"
6632 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6633 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6634 "operands[3] = gen_highpart (SImode, operands[0]);
6635 operands[4] = gen_highpart (SImode, operands[1]);
6636 operands[5] = gen_highpart (SImode, operands[2]);
6637 operands[6] = gen_lowpart (SImode, operands[0]);
6638 operands[7] = gen_lowpart (SImode, operands[1]);
6639 operands[8] = gen_lowpart (SImode, operands[2]);")
6640
6641 (define_insn "*and_not_di_sp64"
6642 [(set (match_operand:DI 0 "register_operand" "=r,b")
6643 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6644 (match_operand:DI 2 "register_operand" "r,b")))]
6645 "TARGET_ARCH64"
6646 "@
6647 andn\\t%2, %1, %0
6648 fandnot1\\t%1, %2, %0"
6649 [(set_attr "type" "*,fp")
6650 (set_attr "fptype" "double")])
6651
6652 (define_insn "*and_not_si"
6653 [(set (match_operand:SI 0 "register_operand" "=r,d")
6654 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6655 (match_operand:SI 2 "register_operand" "r,d")))]
6656 ""
6657 "@
6658 andn\\t%2, %1, %0
6659 fandnot1s\\t%1, %2, %0"
6660 [(set_attr "type" "*,fp")])
6661
6662 (define_expand "iordi3"
6663 [(set (match_operand:DI 0 "register_operand" "")
6664 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6665 (match_operand:DI 2 "arith_double_operand" "")))]
6666 ""
6667 "")
6668
6669 (define_insn "*iordi3_sp32"
6670 [(set (match_operand:DI 0 "register_operand" "=r,b")
6671 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6672 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6673 "! TARGET_ARCH64"
6674 "@
6675 #
6676 for\\t%1, %2, %0"
6677 [(set_attr "type" "*,fp")
6678 (set_attr "length" "2,*")
6679 (set_attr "fptype" "double")])
6680
6681 (define_insn "*iordi3_sp64"
6682 [(set (match_operand:DI 0 "register_operand" "=r,b")
6683 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6684 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6685 "TARGET_ARCH64"
6686 "@
6687 or\\t%1, %2, %0
6688 for\\t%1, %2, %0"
6689 [(set_attr "type" "*,fp")
6690 (set_attr "fptype" "double")])
6691
6692 (define_insn "iorsi3"
6693 [(set (match_operand:SI 0 "register_operand" "=r,d")
6694 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6695 (match_operand:SI 2 "arith_operand" "rI,d")))]
6696 ""
6697 "@
6698 or\\t%1, %2, %0
6699 fors\\t%1, %2, %0"
6700 [(set_attr "type" "*,fp")])
6701
6702 (define_split
6703 [(set (match_operand:SI 0 "register_operand" "")
6704 (ior:SI (match_operand:SI 1 "register_operand" "")
6705 (match_operand:SI 2 "" "")))
6706 (clobber (match_operand:SI 3 "register_operand" ""))]
6707 "GET_CODE (operands[2]) == CONST_INT
6708 && !SMALL_INT32 (operands[2])
6709 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6710 [(set (match_dup 3) (match_dup 4))
6711 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6712 "
6713 {
6714 operands[4] = GEN_INT (~INTVAL (operands[2]));
6715 }")
6716
6717 (define_insn "*or_not_di_sp32"
6718 [(set (match_operand:DI 0 "register_operand" "=r,b")
6719 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6720 (match_operand:DI 2 "register_operand" "r,b")))]
6721 "! TARGET_ARCH64"
6722 "@
6723 #
6724 fornot1\\t%1, %2, %0"
6725 [(set_attr "type" "*,fp")
6726 (set_attr "length" "2,*")
6727 (set_attr "fptype" "double")])
6728
6729 (define_split
6730 [(set (match_operand:DI 0 "register_operand" "")
6731 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6732 (match_operand:DI 2 "register_operand" "")))]
6733 "! TARGET_ARCH64
6734 && reload_completed
6735 && ((GET_CODE (operands[0]) == REG
6736 && REGNO (operands[0]) < 32)
6737 || (GET_CODE (operands[0]) == SUBREG
6738 && GET_CODE (SUBREG_REG (operands[0])) == REG
6739 && REGNO (SUBREG_REG (operands[0])) < 32))"
6740 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6741 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6742 "operands[3] = gen_highpart (SImode, operands[0]);
6743 operands[4] = gen_highpart (SImode, operands[1]);
6744 operands[5] = gen_highpart (SImode, operands[2]);
6745 operands[6] = gen_lowpart (SImode, operands[0]);
6746 operands[7] = gen_lowpart (SImode, operands[1]);
6747 operands[8] = gen_lowpart (SImode, operands[2]);")
6748
6749 (define_insn "*or_not_di_sp64"
6750 [(set (match_operand:DI 0 "register_operand" "=r,b")
6751 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6752 (match_operand:DI 2 "register_operand" "r,b")))]
6753 "TARGET_ARCH64"
6754 "@
6755 orn\\t%2, %1, %0
6756 fornot1\\t%1, %2, %0"
6757 [(set_attr "type" "*,fp")
6758 (set_attr "fptype" "double")])
6759
6760 (define_insn "*or_not_si"
6761 [(set (match_operand:SI 0 "register_operand" "=r,d")
6762 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6763 (match_operand:SI 2 "register_operand" "r,d")))]
6764 ""
6765 "@
6766 orn\\t%2, %1, %0
6767 fornot1s\\t%1, %2, %0"
6768 [(set_attr "type" "*,fp")])
6769
6770 (define_expand "xordi3"
6771 [(set (match_operand:DI 0 "register_operand" "")
6772 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6773 (match_operand:DI 2 "arith_double_operand" "")))]
6774 ""
6775 "")
6776
6777 (define_insn "*xordi3_sp32"
6778 [(set (match_operand:DI 0 "register_operand" "=r,b")
6779 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6780 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6781 "! TARGET_ARCH64"
6782 "@
6783 #
6784 fxor\\t%1, %2, %0"
6785 [(set_attr "type" "*,fp")
6786 (set_attr "length" "2,*")
6787 (set_attr "fptype" "double")])
6788
6789 (define_insn "*xordi3_sp64"
6790 [(set (match_operand:DI 0 "register_operand" "=r,b")
6791 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6792 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6793 "TARGET_ARCH64"
6794 "@
6795 xor\\t%r1, %2, %0
6796 fxor\\t%1, %2, %0"
6797 [(set_attr "type" "*,fp")
6798 (set_attr "fptype" "double")])
6799
6800 (define_insn "*xordi3_sp64_dbl"
6801 [(set (match_operand:DI 0 "register_operand" "=r")
6802 (xor:DI (match_operand:DI 1 "register_operand" "r")
6803 (match_operand:DI 2 "const64_operand" "")))]
6804 "(TARGET_ARCH64
6805 && HOST_BITS_PER_WIDE_INT != 64)"
6806 "xor\\t%1, %2, %0")
6807
6808 (define_insn "xorsi3"
6809 [(set (match_operand:SI 0 "register_operand" "=r,d")
6810 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6811 (match_operand:SI 2 "arith_operand" "rI,d")))]
6812 ""
6813 "@
6814 xor\\t%r1, %2, %0
6815 fxors\\t%1, %2, %0"
6816 [(set_attr "type" "*,fp")])
6817
6818 (define_split
6819 [(set (match_operand:SI 0 "register_operand" "")
6820 (xor:SI (match_operand:SI 1 "register_operand" "")
6821 (match_operand:SI 2 "" "")))
6822 (clobber (match_operand:SI 3 "register_operand" ""))]
6823 "GET_CODE (operands[2]) == CONST_INT
6824 && !SMALL_INT32 (operands[2])
6825 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6826 [(set (match_dup 3) (match_dup 4))
6827 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6828 "
6829 {
6830 operands[4] = GEN_INT (~INTVAL (operands[2]));
6831 }")
6832
6833 (define_split
6834 [(set (match_operand:SI 0 "register_operand" "")
6835 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6836 (match_operand:SI 2 "" ""))))
6837 (clobber (match_operand:SI 3 "register_operand" ""))]
6838 "GET_CODE (operands[2]) == CONST_INT
6839 && !SMALL_INT32 (operands[2])
6840 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6841 [(set (match_dup 3) (match_dup 4))
6842 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6843 "
6844 {
6845 operands[4] = GEN_INT (~INTVAL (operands[2]));
6846 }")
6847
6848 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6849 ;; Combine now canonicalizes to the rightmost expression.
6850 (define_insn "*xor_not_di_sp32"
6851 [(set (match_operand:DI 0 "register_operand" "=r,b")
6852 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6853 (match_operand:DI 2 "register_operand" "r,b"))))]
6854 "! TARGET_ARCH64"
6855 "@
6856 #
6857 fxnor\\t%1, %2, %0"
6858 [(set_attr "type" "*,fp")
6859 (set_attr "length" "2,*")
6860 (set_attr "fptype" "double")])
6861
6862 (define_split
6863 [(set (match_operand:DI 0 "register_operand" "")
6864 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6865 (match_operand:DI 2 "register_operand" ""))))]
6866 "! TARGET_ARCH64
6867 && reload_completed
6868 && ((GET_CODE (operands[0]) == REG
6869 && REGNO (operands[0]) < 32)
6870 || (GET_CODE (operands[0]) == SUBREG
6871 && GET_CODE (SUBREG_REG (operands[0])) == REG
6872 && REGNO (SUBREG_REG (operands[0])) < 32))"
6873 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6874 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6875 "operands[3] = gen_highpart (SImode, operands[0]);
6876 operands[4] = gen_highpart (SImode, operands[1]);
6877 operands[5] = gen_highpart (SImode, operands[2]);
6878 operands[6] = gen_lowpart (SImode, operands[0]);
6879 operands[7] = gen_lowpart (SImode, operands[1]);
6880 operands[8] = gen_lowpart (SImode, operands[2]);")
6881
6882 (define_insn "*xor_not_di_sp64"
6883 [(set (match_operand:DI 0 "register_operand" "=r,b")
6884 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6885 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6886 "TARGET_ARCH64"
6887 "@
6888 xnor\\t%r1, %2, %0
6889 fxnor\\t%1, %2, %0"
6890 [(set_attr "type" "*,fp")
6891 (set_attr "fptype" "double")])
6892
6893 (define_insn "*xor_not_si"
6894 [(set (match_operand:SI 0 "register_operand" "=r,d")
6895 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6896 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6897 ""
6898 "@
6899 xnor\\t%r1, %2, %0
6900 fxnors\\t%1, %2, %0"
6901 [(set_attr "type" "*,fp")])
6902
6903 ;; These correspond to the above in the case where we also (or only)
6904 ;; want to set the condition code.
6905
6906 (define_insn "*cmp_cc_arith_op"
6907 [(set (reg:CC 100)
6908 (compare:CC
6909 (match_operator:SI 2 "cc_arithop"
6910 [(match_operand:SI 0 "arith_operand" "%r")
6911 (match_operand:SI 1 "arith_operand" "rI")])
6912 (const_int 0)))]
6913 ""
6914 "%A2cc\\t%0, %1, %%g0"
6915 [(set_attr "type" "compare")])
6916
6917 (define_insn "*cmp_ccx_arith_op"
6918 [(set (reg:CCX 100)
6919 (compare:CCX
6920 (match_operator:DI 2 "cc_arithop"
6921 [(match_operand:DI 0 "arith_double_operand" "%r")
6922 (match_operand:DI 1 "arith_double_operand" "rHI")])
6923 (const_int 0)))]
6924 "TARGET_ARCH64"
6925 "%A2cc\\t%0, %1, %%g0"
6926 [(set_attr "type" "compare")])
6927
6928 (define_insn "*cmp_cc_arith_op_set"
6929 [(set (reg:CC 100)
6930 (compare:CC
6931 (match_operator:SI 3 "cc_arithop"
6932 [(match_operand:SI 1 "arith_operand" "%r")
6933 (match_operand:SI 2 "arith_operand" "rI")])
6934 (const_int 0)))
6935 (set (match_operand:SI 0 "register_operand" "=r")
6936 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6937 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6938 "%A3cc\\t%1, %2, %0"
6939 [(set_attr "type" "compare")])
6940
6941 (define_insn "*cmp_ccx_arith_op_set"
6942 [(set (reg:CCX 100)
6943 (compare:CCX
6944 (match_operator:DI 3 "cc_arithop"
6945 [(match_operand:DI 1 "arith_double_operand" "%r")
6946 (match_operand:DI 2 "arith_double_operand" "rHI")])
6947 (const_int 0)))
6948 (set (match_operand:DI 0 "register_operand" "=r")
6949 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6950 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6951 "%A3cc\\t%1, %2, %0"
6952 [(set_attr "type" "compare")])
6953
6954 (define_insn "*cmp_cc_xor_not"
6955 [(set (reg:CC 100)
6956 (compare:CC
6957 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6958 (match_operand:SI 1 "arith_operand" "rI")))
6959 (const_int 0)))]
6960 ""
6961 "xnorcc\\t%r0, %1, %%g0"
6962 [(set_attr "type" "compare")])
6963
6964 (define_insn "*cmp_ccx_xor_not"
6965 [(set (reg:CCX 100)
6966 (compare:CCX
6967 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6968 (match_operand:DI 1 "arith_double_operand" "rHI")))
6969 (const_int 0)))]
6970 "TARGET_ARCH64"
6971 "xnorcc\\t%r0, %1, %%g0"
6972 [(set_attr "type" "compare")])
6973
6974 (define_insn "*cmp_cc_xor_not_set"
6975 [(set (reg:CC 100)
6976 (compare:CC
6977 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6978 (match_operand:SI 2 "arith_operand" "rI")))
6979 (const_int 0)))
6980 (set (match_operand:SI 0 "register_operand" "=r")
6981 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6982 ""
6983 "xnorcc\\t%r1, %2, %0"
6984 [(set_attr "type" "compare")])
6985
6986 (define_insn "*cmp_ccx_xor_not_set"
6987 [(set (reg:CCX 100)
6988 (compare:CCX
6989 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6990 (match_operand:DI 2 "arith_double_operand" "rHI")))
6991 (const_int 0)))
6992 (set (match_operand:DI 0 "register_operand" "=r")
6993 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6994 "TARGET_ARCH64"
6995 "xnorcc\\t%r1, %2, %0"
6996 [(set_attr "type" "compare")])
6997
6998 (define_insn "*cmp_cc_arith_op_not"
6999 [(set (reg:CC 100)
7000 (compare:CC
7001 (match_operator:SI 2 "cc_arithopn"
7002 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7003 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7004 (const_int 0)))]
7005 ""
7006 "%B2cc\\t%r1, %0, %%g0"
7007 [(set_attr "type" "compare")])
7008
7009 (define_insn "*cmp_ccx_arith_op_not"
7010 [(set (reg:CCX 100)
7011 (compare:CCX
7012 (match_operator:DI 2 "cc_arithopn"
7013 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7014 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7015 (const_int 0)))]
7016 "TARGET_ARCH64"
7017 "%B2cc\\t%r1, %0, %%g0"
7018 [(set_attr "type" "compare")])
7019
7020 (define_insn "*cmp_cc_arith_op_not_set"
7021 [(set (reg:CC 100)
7022 (compare:CC
7023 (match_operator:SI 3 "cc_arithopn"
7024 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7025 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7026 (const_int 0)))
7027 (set (match_operand:SI 0 "register_operand" "=r")
7028 (match_operator:SI 4 "cc_arithopn"
7029 [(not:SI (match_dup 1)) (match_dup 2)]))]
7030 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7031 "%B3cc\\t%r2, %1, %0"
7032 [(set_attr "type" "compare")])
7033
7034 (define_insn "*cmp_ccx_arith_op_not_set"
7035 [(set (reg:CCX 100)
7036 (compare:CCX
7037 (match_operator:DI 3 "cc_arithopn"
7038 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7039 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7040 (const_int 0)))
7041 (set (match_operand:DI 0 "register_operand" "=r")
7042 (match_operator:DI 4 "cc_arithopn"
7043 [(not:DI (match_dup 1)) (match_dup 2)]))]
7044 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7045 "%B3cc\\t%r2, %1, %0"
7046 [(set_attr "type" "compare")])
7047
7048 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7049 ;; does not know how to make it work for constants.
7050
7051 (define_expand "negdi2"
7052 [(set (match_operand:DI 0 "register_operand" "=r")
7053 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7054 ""
7055 "
7056 {
7057 if (! TARGET_ARCH64)
7058 {
7059 emit_insn (gen_rtx_PARALLEL
7060 (VOIDmode,
7061 gen_rtvec (2,
7062 gen_rtx_SET (VOIDmode, operand0,
7063 gen_rtx_NEG (DImode, operand1)),
7064 gen_rtx_CLOBBER (VOIDmode,
7065 gen_rtx_REG (CCmode,
7066 SPARC_ICC_REG)))));
7067 DONE;
7068 }
7069 }")
7070
7071 (define_insn "*negdi2_sp32"
7072 [(set (match_operand:DI 0 "register_operand" "=r")
7073 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7074 (clobber (reg:CC 100))]
7075 "TARGET_ARCH32"
7076 "#"
7077 [(set_attr "length" "2")])
7078
7079 (define_split
7080 [(set (match_operand:DI 0 "register_operand" "")
7081 (neg:DI (match_operand:DI 1 "register_operand" "")))
7082 (clobber (reg:CC 100))]
7083 "TARGET_ARCH32
7084 && reload_completed"
7085 [(parallel [(set (reg:CC_NOOV 100)
7086 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7087 (const_int 0)))
7088 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7089 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7090 (ltu:SI (reg:CC 100) (const_int 0))))]
7091 "operands[2] = gen_highpart (SImode, operands[0]);
7092 operands[3] = gen_highpart (SImode, operands[1]);
7093 operands[4] = gen_lowpart (SImode, operands[0]);
7094 operands[5] = gen_lowpart (SImode, operands[1]);")
7095
7096 (define_insn "*negdi2_sp64"
7097 [(set (match_operand:DI 0 "register_operand" "=r")
7098 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7099 "TARGET_ARCH64"
7100 "sub\\t%%g0, %1, %0")
7101
7102 (define_insn "negsi2"
7103 [(set (match_operand:SI 0 "register_operand" "=r")
7104 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7105 ""
7106 "sub\\t%%g0, %1, %0")
7107
7108 (define_insn "*cmp_cc_neg"
7109 [(set (reg:CC_NOOV 100)
7110 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7111 (const_int 0)))]
7112 ""
7113 "subcc\\t%%g0, %0, %%g0"
7114 [(set_attr "type" "compare")])
7115
7116 (define_insn "*cmp_ccx_neg"
7117 [(set (reg:CCX_NOOV 100)
7118 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7119 (const_int 0)))]
7120 "TARGET_ARCH64"
7121 "subcc\\t%%g0, %0, %%g0"
7122 [(set_attr "type" "compare")])
7123
7124 (define_insn "*cmp_cc_set_neg"
7125 [(set (reg:CC_NOOV 100)
7126 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7127 (const_int 0)))
7128 (set (match_operand:SI 0 "register_operand" "=r")
7129 (neg:SI (match_dup 1)))]
7130 ""
7131 "subcc\\t%%g0, %1, %0"
7132 [(set_attr "type" "compare")])
7133
7134 (define_insn "*cmp_ccx_set_neg"
7135 [(set (reg:CCX_NOOV 100)
7136 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7137 (const_int 0)))
7138 (set (match_operand:DI 0 "register_operand" "=r")
7139 (neg:DI (match_dup 1)))]
7140 "TARGET_ARCH64"
7141 "subcc\\t%%g0, %1, %0"
7142 [(set_attr "type" "compare")])
7143
7144 ;; We cannot use the "not" pseudo insn because the Sun assembler
7145 ;; does not know how to make it work for constants.
7146 (define_expand "one_cmpldi2"
7147 [(set (match_operand:DI 0 "register_operand" "")
7148 (not:DI (match_operand:DI 1 "register_operand" "")))]
7149 ""
7150 "")
7151
7152 (define_insn "*one_cmpldi2_sp32"
7153 [(set (match_operand:DI 0 "register_operand" "=r,b")
7154 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7155 "! TARGET_ARCH64"
7156 "@
7157 #
7158 fnot1\\t%1, %0"
7159 [(set_attr "type" "*,fp")
7160 (set_attr "length" "2,*")
7161 (set_attr "fptype" "double")])
7162
7163 (define_split
7164 [(set (match_operand:DI 0 "register_operand" "")
7165 (not:DI (match_operand:DI 1 "register_operand" "")))]
7166 "! TARGET_ARCH64
7167 && reload_completed
7168 && ((GET_CODE (operands[0]) == REG
7169 && REGNO (operands[0]) < 32)
7170 || (GET_CODE (operands[0]) == SUBREG
7171 && GET_CODE (SUBREG_REG (operands[0])) == REG
7172 && REGNO (SUBREG_REG (operands[0])) < 32))"
7173 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7174 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7175 "operands[2] = gen_highpart (SImode, operands[0]);
7176 operands[3] = gen_highpart (SImode, operands[1]);
7177 operands[4] = gen_lowpart (SImode, operands[0]);
7178 operands[5] = gen_lowpart (SImode, operands[1]);")
7179
7180 (define_insn "*one_cmpldi2_sp64"
7181 [(set (match_operand:DI 0 "register_operand" "=r,b")
7182 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7183 "TARGET_ARCH64"
7184 "@
7185 xnor\\t%%g0, %1, %0
7186 fnot1\\t%1, %0"
7187 [(set_attr "type" "*,fp")
7188 (set_attr "fptype" "double")])
7189
7190 (define_insn "one_cmplsi2"
7191 [(set (match_operand:SI 0 "register_operand" "=r,d")
7192 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7193 ""
7194 "@
7195 xnor\\t%%g0, %1, %0
7196 fnot1s\\t%1, %0"
7197 [(set_attr "type" "*,fp")])
7198
7199 (define_insn "*cmp_cc_not"
7200 [(set (reg:CC 100)
7201 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7202 (const_int 0)))]
7203 ""
7204 "xnorcc\\t%%g0, %0, %%g0"
7205 [(set_attr "type" "compare")])
7206
7207 (define_insn "*cmp_ccx_not"
7208 [(set (reg:CCX 100)
7209 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7210 (const_int 0)))]
7211 "TARGET_ARCH64"
7212 "xnorcc\\t%%g0, %0, %%g0"
7213 [(set_attr "type" "compare")])
7214
7215 (define_insn "*cmp_cc_set_not"
7216 [(set (reg:CC 100)
7217 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7218 (const_int 0)))
7219 (set (match_operand:SI 0 "register_operand" "=r")
7220 (not:SI (match_dup 1)))]
7221 ""
7222 "xnorcc\\t%%g0, %1, %0"
7223 [(set_attr "type" "compare")])
7224
7225 (define_insn "*cmp_ccx_set_not"
7226 [(set (reg:CCX 100)
7227 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7228 (const_int 0)))
7229 (set (match_operand:DI 0 "register_operand" "=r")
7230 (not:DI (match_dup 1)))]
7231 "TARGET_ARCH64"
7232 "xnorcc\\t%%g0, %1, %0"
7233 [(set_attr "type" "compare")])
7234
7235 (define_insn "*cmp_cc_set"
7236 [(set (match_operand:SI 0 "register_operand" "=r")
7237 (match_operand:SI 1 "register_operand" "r"))
7238 (set (reg:CC 100)
7239 (compare:CC (match_dup 1)
7240 (const_int 0)))]
7241 ""
7242 "orcc\\t%1, 0, %0"
7243 [(set_attr "type" "compare")])
7244
7245 (define_insn "*cmp_ccx_set64"
7246 [(set (match_operand:DI 0 "register_operand" "=r")
7247 (match_operand:DI 1 "register_operand" "r"))
7248 (set (reg:CCX 100)
7249 (compare:CCX (match_dup 1)
7250 (const_int 0)))]
7251 "TARGET_ARCH64"
7252 "orcc\\t%1, 0, %0"
7253 [(set_attr "type" "compare")])
7254 \f
7255 ;; Floating point arithmetic instructions.
7256
7257 (define_expand "addtf3"
7258 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7259 (plus:TF (match_operand:TF 1 "general_operand" "")
7260 (match_operand:TF 2 "general_operand" "")))]
7261 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7262 "
7263 {
7264 if (! TARGET_HARD_QUAD)
7265 {
7266 rtx slot0, slot1, slot2;
7267
7268 if (GET_CODE (operands[0]) != MEM)
7269 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7270 else
7271 slot0 = operands[0];
7272 if (GET_CODE (operands[1]) != MEM)
7273 {
7274 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7275 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7276 }
7277 else
7278 slot1 = operands[1];
7279 if (GET_CODE (operands[2]) != MEM)
7280 {
7281 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7282 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7283 }
7284 else
7285 slot2 = operands[2];
7286
7287 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7288 VOIDmode, 3,
7289 XEXP (slot0, 0), Pmode,
7290 XEXP (slot1, 0), Pmode,
7291 XEXP (slot2, 0), Pmode);
7292
7293 if (GET_CODE (operands[0]) != MEM)
7294 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7295 DONE;
7296 }
7297 }")
7298
7299 (define_insn "*addtf3_hq"
7300 [(set (match_operand:TF 0 "register_operand" "=e")
7301 (plus:TF (match_operand:TF 1 "register_operand" "e")
7302 (match_operand:TF 2 "register_operand" "e")))]
7303 "TARGET_FPU && TARGET_HARD_QUAD"
7304 "faddq\\t%1, %2, %0"
7305 [(set_attr "type" "fp")])
7306
7307 (define_insn "adddf3"
7308 [(set (match_operand:DF 0 "register_operand" "=e")
7309 (plus:DF (match_operand:DF 1 "register_operand" "e")
7310 (match_operand:DF 2 "register_operand" "e")))]
7311 "TARGET_FPU"
7312 "faddd\\t%1, %2, %0"
7313 [(set_attr "type" "fp")
7314 (set_attr "fptype" "double")])
7315
7316 (define_insn "addsf3"
7317 [(set (match_operand:SF 0 "register_operand" "=f")
7318 (plus:SF (match_operand:SF 1 "register_operand" "f")
7319 (match_operand:SF 2 "register_operand" "f")))]
7320 "TARGET_FPU"
7321 "fadds\\t%1, %2, %0"
7322 [(set_attr "type" "fp")])
7323
7324 (define_expand "subtf3"
7325 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7326 (minus:TF (match_operand:TF 1 "general_operand" "")
7327 (match_operand:TF 2 "general_operand" "")))]
7328 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7329 "
7330 {
7331 if (! TARGET_HARD_QUAD)
7332 {
7333 rtx slot0, slot1, slot2;
7334
7335 if (GET_CODE (operands[0]) != MEM)
7336 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7337 else
7338 slot0 = operands[0];
7339 if (GET_CODE (operands[1]) != MEM)
7340 {
7341 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7342 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7343 }
7344 else
7345 slot1 = operands[1];
7346 if (GET_CODE (operands[2]) != MEM)
7347 {
7348 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7349 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7350 }
7351 else
7352 slot2 = operands[2];
7353
7354 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7355 VOIDmode, 3,
7356 XEXP (slot0, 0), Pmode,
7357 XEXP (slot1, 0), Pmode,
7358 XEXP (slot2, 0), Pmode);
7359
7360 if (GET_CODE (operands[0]) != MEM)
7361 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7362 DONE;
7363 }
7364 }")
7365
7366 (define_insn "*subtf3_hq"
7367 [(set (match_operand:TF 0 "register_operand" "=e")
7368 (minus:TF (match_operand:TF 1 "register_operand" "e")
7369 (match_operand:TF 2 "register_operand" "e")))]
7370 "TARGET_FPU && TARGET_HARD_QUAD"
7371 "fsubq\\t%1, %2, %0"
7372 [(set_attr "type" "fp")])
7373
7374 (define_insn "subdf3"
7375 [(set (match_operand:DF 0 "register_operand" "=e")
7376 (minus:DF (match_operand:DF 1 "register_operand" "e")
7377 (match_operand:DF 2 "register_operand" "e")))]
7378 "TARGET_FPU"
7379 "fsubd\\t%1, %2, %0"
7380 [(set_attr "type" "fp")
7381 (set_attr "fptype" "double")])
7382
7383 (define_insn "subsf3"
7384 [(set (match_operand:SF 0 "register_operand" "=f")
7385 (minus:SF (match_operand:SF 1 "register_operand" "f")
7386 (match_operand:SF 2 "register_operand" "f")))]
7387 "TARGET_FPU"
7388 "fsubs\\t%1, %2, %0"
7389 [(set_attr "type" "fp")])
7390
7391 (define_expand "multf3"
7392 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7393 (mult:TF (match_operand:TF 1 "general_operand" "")
7394 (match_operand:TF 2 "general_operand" "")))]
7395 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7396 "
7397 {
7398 if (! TARGET_HARD_QUAD)
7399 {
7400 rtx slot0, slot1, slot2;
7401
7402 if (GET_CODE (operands[0]) != MEM)
7403 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7404 else
7405 slot0 = operands[0];
7406 if (GET_CODE (operands[1]) != MEM)
7407 {
7408 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7409 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7410 }
7411 else
7412 slot1 = operands[1];
7413 if (GET_CODE (operands[2]) != MEM)
7414 {
7415 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7416 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7417 }
7418 else
7419 slot2 = operands[2];
7420
7421 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7422 VOIDmode, 3,
7423 XEXP (slot0, 0), Pmode,
7424 XEXP (slot1, 0), Pmode,
7425 XEXP (slot2, 0), Pmode);
7426
7427 if (GET_CODE (operands[0]) != MEM)
7428 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7429 DONE;
7430 }
7431 }")
7432
7433 (define_insn "*multf3_hq"
7434 [(set (match_operand:TF 0 "register_operand" "=e")
7435 (mult:TF (match_operand:TF 1 "register_operand" "e")
7436 (match_operand:TF 2 "register_operand" "e")))]
7437 "TARGET_FPU && TARGET_HARD_QUAD"
7438 "fmulq\\t%1, %2, %0"
7439 [(set_attr "type" "fpmul")])
7440
7441 (define_insn "muldf3"
7442 [(set (match_operand:DF 0 "register_operand" "=e")
7443 (mult:DF (match_operand:DF 1 "register_operand" "e")
7444 (match_operand:DF 2 "register_operand" "e")))]
7445 "TARGET_FPU"
7446 "fmuld\\t%1, %2, %0"
7447 [(set_attr "type" "fpmul")
7448 (set_attr "fptype" "double")])
7449
7450 (define_insn "mulsf3"
7451 [(set (match_operand:SF 0 "register_operand" "=f")
7452 (mult:SF (match_operand:SF 1 "register_operand" "f")
7453 (match_operand:SF 2 "register_operand" "f")))]
7454 "TARGET_FPU"
7455 "fmuls\\t%1, %2, %0"
7456 [(set_attr "type" "fpmul")])
7457
7458 (define_insn "*muldf3_extend"
7459 [(set (match_operand:DF 0 "register_operand" "=e")
7460 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7461 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7462 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7463 "fsmuld\\t%1, %2, %0"
7464 [(set_attr "type" "fpmul")
7465 (set_attr "fptype" "double")])
7466
7467 (define_insn "*multf3_extend"
7468 [(set (match_operand:TF 0 "register_operand" "=e")
7469 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7470 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7471 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7472 "fdmulq\\t%1, %2, %0"
7473 [(set_attr "type" "fpmul")])
7474
7475 (define_expand "divtf3"
7476 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7477 (div:TF (match_operand:TF 1 "general_operand" "")
7478 (match_operand:TF 2 "general_operand" "")))]
7479 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7480 "
7481 {
7482 if (! TARGET_HARD_QUAD)
7483 {
7484 rtx slot0, slot1, slot2;
7485
7486 if (GET_CODE (operands[0]) != MEM)
7487 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7488 else
7489 slot0 = operands[0];
7490 if (GET_CODE (operands[1]) != MEM)
7491 {
7492 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7493 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7494 }
7495 else
7496 slot1 = operands[1];
7497 if (GET_CODE (operands[2]) != MEM)
7498 {
7499 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7500 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7501 }
7502 else
7503 slot2 = operands[2];
7504
7505 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7506 VOIDmode, 3,
7507 XEXP (slot0, 0), Pmode,
7508 XEXP (slot1, 0), Pmode,
7509 XEXP (slot2, 0), Pmode);
7510
7511 if (GET_CODE (operands[0]) != MEM)
7512 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7513 DONE;
7514 }
7515 }")
7516
7517 ;; don't have timing for quad-prec. divide.
7518 (define_insn "*divtf3_hq"
7519 [(set (match_operand:TF 0 "register_operand" "=e")
7520 (div:TF (match_operand:TF 1 "register_operand" "e")
7521 (match_operand:TF 2 "register_operand" "e")))]
7522 "TARGET_FPU && TARGET_HARD_QUAD"
7523 "fdivq\\t%1, %2, %0"
7524 [(set_attr "type" "fpdivd")])
7525
7526 (define_insn "divdf3"
7527 [(set (match_operand:DF 0 "register_operand" "=e")
7528 (div:DF (match_operand:DF 1 "register_operand" "e")
7529 (match_operand:DF 2 "register_operand" "e")))]
7530 "TARGET_FPU"
7531 "fdivd\\t%1, %2, %0"
7532 [(set_attr "type" "fpdivd")
7533 (set_attr "fptype" "double")])
7534
7535 (define_insn "divsf3"
7536 [(set (match_operand:SF 0 "register_operand" "=f")
7537 (div:SF (match_operand:SF 1 "register_operand" "f")
7538 (match_operand:SF 2 "register_operand" "f")))]
7539 "TARGET_FPU"
7540 "fdivs\\t%1, %2, %0"
7541 [(set_attr "type" "fpdivs")])
7542
7543 (define_expand "negtf2"
7544 [(set (match_operand:TF 0 "register_operand" "=e,e")
7545 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7546 "TARGET_FPU"
7547 "")
7548
7549 (define_insn "*negtf2_notv9"
7550 [(set (match_operand:TF 0 "register_operand" "=e,e")
7551 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7552 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7553 "TARGET_FPU
7554 && ! TARGET_V9"
7555 "@
7556 fnegs\\t%0, %0
7557 #"
7558 [(set_attr "type" "fpmove,*")
7559 (set_attr "length" "*,2")])
7560
7561 (define_split
7562 [(set (match_operand:TF 0 "register_operand" "")
7563 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7564 "TARGET_FPU
7565 && ! TARGET_V9
7566 && reload_completed
7567 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7568 [(set (match_dup 2) (neg:SF (match_dup 3)))
7569 (set (match_dup 4) (match_dup 5))
7570 (set (match_dup 6) (match_dup 7))]
7571 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7572 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7573 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7574 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7575 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7576 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7577
7578 (define_insn "*negtf2_v9"
7579 [(set (match_operand:TF 0 "register_operand" "=e,e")
7580 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7581 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7582 "TARGET_FPU && TARGET_V9"
7583 "@
7584 fnegd\\t%0, %0
7585 #"
7586 [(set_attr "type" "fpmove,*")
7587 (set_attr "length" "*,2")
7588 (set_attr "fptype" "double")])
7589
7590 (define_split
7591 [(set (match_operand:TF 0 "register_operand" "")
7592 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7593 "TARGET_FPU
7594 && TARGET_V9
7595 && reload_completed
7596 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7597 [(set (match_dup 2) (neg:DF (match_dup 3)))
7598 (set (match_dup 4) (match_dup 5))]
7599 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7600 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7601 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7602 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7603
7604 (define_expand "negdf2"
7605 [(set (match_operand:DF 0 "register_operand" "")
7606 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7607 "TARGET_FPU"
7608 "")
7609
7610 (define_insn "*negdf2_notv9"
7611 [(set (match_operand:DF 0 "register_operand" "=e,e")
7612 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7613 "TARGET_FPU && ! TARGET_V9"
7614 "@
7615 fnegs\\t%0, %0
7616 #"
7617 [(set_attr "type" "fpmove,*")
7618 (set_attr "length" "*,2")])
7619
7620 (define_split
7621 [(set (match_operand:DF 0 "register_operand" "")
7622 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7623 "TARGET_FPU
7624 && ! TARGET_V9
7625 && reload_completed
7626 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7627 [(set (match_dup 2) (neg:SF (match_dup 3)))
7628 (set (match_dup 4) (match_dup 5))]
7629 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7630 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7631 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7632 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7633
7634 (define_insn "*negdf2_v9"
7635 [(set (match_operand:DF 0 "register_operand" "=e")
7636 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7637 "TARGET_FPU && TARGET_V9"
7638 "fnegd\\t%1, %0"
7639 [(set_attr "type" "fpmove")
7640 (set_attr "fptype" "double")])
7641
7642 (define_insn "negsf2"
7643 [(set (match_operand:SF 0 "register_operand" "=f")
7644 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7645 "TARGET_FPU"
7646 "fnegs\\t%1, %0"
7647 [(set_attr "type" "fpmove")])
7648
7649 (define_expand "abstf2"
7650 [(set (match_operand:TF 0 "register_operand" "")
7651 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7652 "TARGET_FPU"
7653 "")
7654
7655 (define_insn "*abstf2_notv9"
7656 [(set (match_operand:TF 0 "register_operand" "=e,e")
7657 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7658 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7659 "TARGET_FPU && ! TARGET_V9"
7660 "@
7661 fabss\\t%0, %0
7662 #"
7663 [(set_attr "type" "fpmove,*")
7664 (set_attr "length" "*,2")])
7665
7666 (define_split
7667 [(set (match_operand:TF 0 "register_operand" "")
7668 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7669 "TARGET_FPU
7670 && ! TARGET_V9
7671 && reload_completed
7672 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7673 [(set (match_dup 2) (abs:SF (match_dup 3)))
7674 (set (match_dup 4) (match_dup 5))
7675 (set (match_dup 6) (match_dup 7))]
7676 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7677 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7678 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7679 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7680 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7681 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7682
7683 (define_insn "*abstf2_hq_v9"
7684 [(set (match_operand:TF 0 "register_operand" "=e,e")
7685 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7686 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7687 "@
7688 fabsd\\t%0, %0
7689 fabsq\\t%1, %0"
7690 [(set_attr "type" "fpmove")
7691 (set_attr "fptype" "double,*")])
7692
7693 (define_insn "*abstf2_v9"
7694 [(set (match_operand:TF 0 "register_operand" "=e,e")
7695 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7696 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7697 "@
7698 fabsd\\t%0, %0
7699 #"
7700 [(set_attr "type" "fpmove,*")
7701 (set_attr "length" "*,2")
7702 (set_attr "fptype" "double,*")])
7703
7704 (define_split
7705 [(set (match_operand:TF 0 "register_operand" "")
7706 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7707 "TARGET_FPU
7708 && TARGET_V9
7709 && reload_completed
7710 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7711 [(set (match_dup 2) (abs:DF (match_dup 3)))
7712 (set (match_dup 4) (match_dup 5))]
7713 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7714 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7715 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7716 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7717
7718 (define_expand "absdf2"
7719 [(set (match_operand:DF 0 "register_operand" "")
7720 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7721 "TARGET_FPU"
7722 "")
7723
7724 (define_insn "*absdf2_notv9"
7725 [(set (match_operand:DF 0 "register_operand" "=e,e")
7726 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7727 "TARGET_FPU && ! TARGET_V9"
7728 "@
7729 fabss\\t%0, %0
7730 #"
7731 [(set_attr "type" "fpmove,*")
7732 (set_attr "length" "*,2")])
7733
7734 (define_split
7735 [(set (match_operand:DF 0 "register_operand" "")
7736 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7737 "TARGET_FPU
7738 && ! TARGET_V9
7739 && reload_completed
7740 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7741 [(set (match_dup 2) (abs:SF (match_dup 3)))
7742 (set (match_dup 4) (match_dup 5))]
7743 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7744 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7745 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7746 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7747
7748 (define_insn "*absdf2_v9"
7749 [(set (match_operand:DF 0 "register_operand" "=e")
7750 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7751 "TARGET_FPU && TARGET_V9"
7752 "fabsd\\t%1, %0"
7753 [(set_attr "type" "fpmove")
7754 (set_attr "fptype" "double")])
7755
7756 (define_insn "abssf2"
7757 [(set (match_operand:SF 0 "register_operand" "=f")
7758 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7759 "TARGET_FPU"
7760 "fabss\\t%1, %0"
7761 [(set_attr "type" "fpmove")])
7762
7763 (define_expand "sqrttf2"
7764 [(set (match_operand:TF 0 "register_operand" "=e")
7765 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7766 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7767 "
7768 {
7769 if (! TARGET_HARD_QUAD)
7770 {
7771 rtx slot0, slot1;
7772
7773 if (GET_CODE (operands[0]) != MEM)
7774 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7775 else
7776 slot0 = operands[0];
7777 if (GET_CODE (operands[1]) != MEM)
7778 {
7779 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7780 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7781 }
7782 else
7783 slot1 = operands[1];
7784
7785 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7786 VOIDmode, 2,
7787 XEXP (slot0, 0), Pmode,
7788 XEXP (slot1, 0), Pmode);
7789
7790 if (GET_CODE (operands[0]) != MEM)
7791 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7792 DONE;
7793 }
7794 }")
7795
7796 (define_insn "*sqrttf2_hq"
7797 [(set (match_operand:TF 0 "register_operand" "=e")
7798 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7799 "TARGET_FPU && TARGET_HARD_QUAD"
7800 "fsqrtq\\t%1, %0"
7801 [(set_attr "type" "fpsqrtd")])
7802
7803 (define_insn "sqrtdf2"
7804 [(set (match_operand:DF 0 "register_operand" "=e")
7805 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7806 "TARGET_FPU"
7807 "fsqrtd\\t%1, %0"
7808 [(set_attr "type" "fpsqrtd")
7809 (set_attr "fptype" "double")])
7810
7811 (define_insn "sqrtsf2"
7812 [(set (match_operand:SF 0 "register_operand" "=f")
7813 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7814 "TARGET_FPU"
7815 "fsqrts\\t%1, %0"
7816 [(set_attr "type" "fpsqrts")])
7817 \f
7818 ;;- arithmetic shift instructions
7819
7820 (define_insn "ashlsi3"
7821 [(set (match_operand:SI 0 "register_operand" "=r")
7822 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7823 (match_operand:SI 2 "arith_operand" "rI")))]
7824 ""
7825 "*
7826 {
7827 if (GET_CODE (operands[2]) == CONST_INT
7828 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7829 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7830
7831 return \"sll\\t%1, %2, %0\";
7832 }"
7833 [(set_attr "type" "shift")])
7834
7835 ;; We special case multiplication by two, as add can be done
7836 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7837 (define_insn "*ashlsi3_const1"
7838 [(set (match_operand:SI 0 "register_operand" "=r")
7839 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7840 (const_int 1)))]
7841 ""
7842 "add\\t%1, %1, %0")
7843
7844 (define_expand "ashldi3"
7845 [(set (match_operand:DI 0 "register_operand" "=r")
7846 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7847 (match_operand:SI 2 "arith_operand" "rI")))]
7848 "TARGET_ARCH64 || TARGET_V8PLUS"
7849 "
7850 {
7851 if (! TARGET_ARCH64)
7852 {
7853 if (GET_CODE (operands[2]) == CONST_INT)
7854 FAIL;
7855 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7856 DONE;
7857 }
7858 }")
7859
7860 ;; We special case multiplication by two, as add can be done
7861 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7862 (define_insn "*ashldi3_const1"
7863 [(set (match_operand:DI 0 "register_operand" "=r")
7864 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7865 (const_int 1)))]
7866 "TARGET_ARCH64"
7867 "add\\t%1, %1, %0")
7868
7869 (define_insn "*ashldi3_sp64"
7870 [(set (match_operand:DI 0 "register_operand" "=r")
7871 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7872 (match_operand:SI 2 "arith_operand" "rI")))]
7873 "TARGET_ARCH64"
7874 "*
7875 {
7876 if (GET_CODE (operands[2]) == CONST_INT
7877 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7878 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7879
7880 return \"sllx\\t%1, %2, %0\";
7881 }"
7882 [(set_attr "type" "shift")])
7883
7884 ;; XXX UGH!
7885 (define_insn "ashldi3_v8plus"
7886 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7887 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7888 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7889 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7890 "TARGET_V8PLUS"
7891 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7892 [(set_attr "type" "multi")
7893 (set_attr "length" "5,5,6")])
7894
7895 ;; Optimize (1LL<<x)-1
7896 ;; XXX this also needs to be fixed to handle equal subregs
7897 ;; XXX first before we could re-enable it.
7898 ;(define_insn ""
7899 ; [(set (match_operand:DI 0 "register_operand" "=h")
7900 ; (plus:DI (ashift:DI (const_int 1)
7901 ; (match_operand:SI 1 "arith_operand" "rI"))
7902 ; (const_int -1)))]
7903 ; "0 && TARGET_V8PLUS"
7904 ; "*
7905 ;{
7906 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7907 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7908 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7909 ;}"
7910 ; [(set_attr "type" "multi")
7911 ; (set_attr "length" "4")])
7912
7913 (define_insn "*cmp_cc_ashift_1"
7914 [(set (reg:CC_NOOV 100)
7915 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7916 (const_int 1))
7917 (const_int 0)))]
7918 ""
7919 "addcc\\t%0, %0, %%g0"
7920 [(set_attr "type" "compare")])
7921
7922 (define_insn "*cmp_cc_set_ashift_1"
7923 [(set (reg:CC_NOOV 100)
7924 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7925 (const_int 1))
7926 (const_int 0)))
7927 (set (match_operand:SI 0 "register_operand" "=r")
7928 (ashift:SI (match_dup 1) (const_int 1)))]
7929 ""
7930 "addcc\\t%1, %1, %0"
7931 [(set_attr "type" "compare")])
7932
7933 (define_insn "ashrsi3"
7934 [(set (match_operand:SI 0 "register_operand" "=r")
7935 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7936 (match_operand:SI 2 "arith_operand" "rI")))]
7937 ""
7938 "*
7939 {
7940 if (GET_CODE (operands[2]) == CONST_INT
7941 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7942 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7943
7944 return \"sra\\t%1, %2, %0\";
7945 }"
7946 [(set_attr "type" "shift")])
7947
7948 (define_insn "*ashrsi3_extend"
7949 [(set (match_operand:DI 0 "register_operand" "=r")
7950 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7951 (match_operand:SI 2 "arith_operand" "r"))))]
7952 "TARGET_ARCH64"
7953 "sra\\t%1, %2, %0"
7954 [(set_attr "type" "shift")])
7955
7956 ;; This handles the case as above, but with constant shift instead of
7957 ;; register. Combiner "simplifies" it for us a little bit though.
7958 (define_insn "*ashrsi3_extend2"
7959 [(set (match_operand:DI 0 "register_operand" "=r")
7960 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7961 (const_int 32))
7962 (match_operand:SI 2 "small_int_or_double" "n")))]
7963 "TARGET_ARCH64
7964 && ((GET_CODE (operands[2]) == CONST_INT
7965 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7966 || (GET_CODE (operands[2]) == CONST_DOUBLE
7967 && !CONST_DOUBLE_HIGH (operands[2])
7968 && CONST_DOUBLE_LOW (operands[2]) >= 32
7969 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7970 "*
7971 {
7972 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7973
7974 return \"sra\\t%1, %2, %0\";
7975 }"
7976 [(set_attr "type" "shift")])
7977
7978 (define_expand "ashrdi3"
7979 [(set (match_operand:DI 0 "register_operand" "=r")
7980 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7981 (match_operand:SI 2 "arith_operand" "rI")))]
7982 "TARGET_ARCH64 || TARGET_V8PLUS"
7983 "
7984 {
7985 if (! TARGET_ARCH64)
7986 {
7987 if (GET_CODE (operands[2]) == CONST_INT)
7988 FAIL; /* prefer generic code in this case */
7989 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7990 DONE;
7991 }
7992 }")
7993
7994 (define_insn ""
7995 [(set (match_operand:DI 0 "register_operand" "=r")
7996 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7997 (match_operand:SI 2 "arith_operand" "rI")))]
7998 "TARGET_ARCH64"
7999 "*
8000 {
8001 if (GET_CODE (operands[2]) == CONST_INT
8002 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8003 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8004
8005 return \"srax\\t%1, %2, %0\";
8006 }"
8007 [(set_attr "type" "shift")])
8008
8009 ;; XXX
8010 (define_insn "ashrdi3_v8plus"
8011 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8012 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8013 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8014 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8015 "TARGET_V8PLUS"
8016 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8017 [(set_attr "type" "multi")
8018 (set_attr "length" "5,5,6")])
8019
8020 (define_insn "lshrsi3"
8021 [(set (match_operand:SI 0 "register_operand" "=r")
8022 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8023 (match_operand:SI 2 "arith_operand" "rI")))]
8024 ""
8025 "*
8026 {
8027 if (GET_CODE (operands[2]) == CONST_INT
8028 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8029 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8030
8031 return \"srl\\t%1, %2, %0\";
8032 }"
8033 [(set_attr "type" "shift")])
8034
8035 ;; This handles the case where
8036 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8037 ;; but combiner "simplifies" it for us.
8038 (define_insn "*lshrsi3_extend"
8039 [(set (match_operand:DI 0 "register_operand" "=r")
8040 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8041 (match_operand:SI 2 "arith_operand" "r")) 0)
8042 (match_operand 3 "" "")))]
8043 "TARGET_ARCH64
8044 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8045 && CONST_DOUBLE_HIGH (operands[3]) == 0
8046 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8047 || (HOST_BITS_PER_WIDE_INT >= 64
8048 && GET_CODE (operands[3]) == CONST_INT
8049 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8050 "srl\\t%1, %2, %0"
8051 [(set_attr "type" "shift")])
8052
8053 ;; This handles the case where
8054 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8055 ;; but combiner "simplifies" it for us.
8056 (define_insn "*lshrsi3_extend2"
8057 [(set (match_operand:DI 0 "register_operand" "=r")
8058 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8059 (match_operand 2 "small_int_or_double" "n")
8060 (const_int 32)))]
8061 "TARGET_ARCH64
8062 && ((GET_CODE (operands[2]) == CONST_INT
8063 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8064 || (GET_CODE (operands[2]) == CONST_DOUBLE
8065 && CONST_DOUBLE_HIGH (operands[2]) == 0
8066 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8067 "*
8068 {
8069 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8070
8071 return \"srl\\t%1, %2, %0\";
8072 }"
8073 [(set_attr "type" "shift")])
8074
8075 (define_expand "lshrdi3"
8076 [(set (match_operand:DI 0 "register_operand" "=r")
8077 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8078 (match_operand:SI 2 "arith_operand" "rI")))]
8079 "TARGET_ARCH64 || TARGET_V8PLUS"
8080 "
8081 {
8082 if (! TARGET_ARCH64)
8083 {
8084 if (GET_CODE (operands[2]) == CONST_INT)
8085 FAIL;
8086 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8087 DONE;
8088 }
8089 }")
8090
8091 (define_insn ""
8092 [(set (match_operand:DI 0 "register_operand" "=r")
8093 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8094 (match_operand:SI 2 "arith_operand" "rI")))]
8095 "TARGET_ARCH64"
8096 "*
8097 {
8098 if (GET_CODE (operands[2]) == CONST_INT
8099 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8100 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8101
8102 return \"srlx\\t%1, %2, %0\";
8103 }"
8104 [(set_attr "type" "shift")])
8105
8106 ;; XXX
8107 (define_insn "lshrdi3_v8plus"
8108 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8109 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8110 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8111 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8112 "TARGET_V8PLUS"
8113 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8114 [(set_attr "type" "multi")
8115 (set_attr "length" "5,5,6")])
8116
8117 (define_insn ""
8118 [(set (match_operand:SI 0 "register_operand" "=r")
8119 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8120 (const_int 32)) 4)
8121 (match_operand:SI 2 "small_int_or_double" "n")))]
8122 "TARGET_ARCH64
8123 && ((GET_CODE (operands[2]) == CONST_INT
8124 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8125 || (GET_CODE (operands[2]) == CONST_DOUBLE
8126 && !CONST_DOUBLE_HIGH (operands[2])
8127 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8128 "*
8129 {
8130 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8131
8132 return \"srax\\t%1, %2, %0\";
8133 }"
8134 [(set_attr "type" "shift")])
8135
8136 (define_insn ""
8137 [(set (match_operand:SI 0 "register_operand" "=r")
8138 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8139 (const_int 32)) 4)
8140 (match_operand:SI 2 "small_int_or_double" "n")))]
8141 "TARGET_ARCH64
8142 && ((GET_CODE (operands[2]) == CONST_INT
8143 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8144 || (GET_CODE (operands[2]) == CONST_DOUBLE
8145 && !CONST_DOUBLE_HIGH (operands[2])
8146 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8147 "*
8148 {
8149 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8150
8151 return \"srlx\\t%1, %2, %0\";
8152 }"
8153 [(set_attr "type" "shift")])
8154
8155 (define_insn ""
8156 [(set (match_operand:SI 0 "register_operand" "=r")
8157 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8158 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8159 (match_operand:SI 3 "small_int_or_double" "n")))]
8160 "TARGET_ARCH64
8161 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8162 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8163 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8164 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8165 "*
8166 {
8167 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8168
8169 return \"srax\\t%1, %2, %0\";
8170 }"
8171 [(set_attr "type" "shift")])
8172
8173 (define_insn ""
8174 [(set (match_operand:SI 0 "register_operand" "=r")
8175 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8176 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8177 (match_operand:SI 3 "small_int_or_double" "n")))]
8178 "TARGET_ARCH64
8179 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8180 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8181 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8182 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8183 "*
8184 {
8185 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8186
8187 return \"srlx\\t%1, %2, %0\";
8188 }"
8189 [(set_attr "type" "shift")])
8190 \f
8191 ;; Unconditional and other jump instructions
8192 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8193 ;; following insn is never executed. This saves us a nop. Dbx does not
8194 ;; handle such branches though, so we only use them when optimizing.
8195 (define_insn "jump"
8196 [(set (pc) (label_ref (match_operand 0 "" "")))]
8197 ""
8198 "*
8199 {
8200 /* TurboSparc is reported to have problems with
8201 with
8202 foo: b,a foo
8203 i.e. an empty loop with the annul bit set. The workaround is to use
8204 foo: b foo; nop
8205 instead. */
8206
8207 if (! TARGET_V9 && flag_delayed_branch
8208 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8209 == INSN_ADDRESSES (INSN_UID (insn))))
8210 return \"b\\t%l0%#\";
8211 else
8212 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8213 }"
8214 [(set_attr "type" "uncond_branch")])
8215
8216 (define_expand "tablejump"
8217 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8218 (use (label_ref (match_operand 1 "" "")))])]
8219 ""
8220 "
8221 {
8222 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8223 abort ();
8224
8225 /* In pic mode, our address differences are against the base of the
8226 table. Add that base value back in; CSE ought to be able to combine
8227 the two address loads. */
8228 if (flag_pic)
8229 {
8230 rtx tmp, tmp2;
8231 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8232 tmp2 = operands[0];
8233 if (CASE_VECTOR_MODE != Pmode)
8234 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8235 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8236 operands[0] = memory_address (Pmode, tmp);
8237 }
8238 }")
8239
8240 (define_insn "*tablejump_sp32"
8241 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8242 (use (label_ref (match_operand 1 "" "")))]
8243 "! TARGET_ARCH64"
8244 "jmp\\t%a0%#"
8245 [(set_attr "type" "uncond_branch")])
8246
8247 (define_insn "*tablejump_sp64"
8248 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8249 (use (label_ref (match_operand 1 "" "")))]
8250 "TARGET_ARCH64"
8251 "jmp\\t%a0%#"
8252 [(set_attr "type" "uncond_branch")])
8253
8254 ;; This pattern recognizes the "instruction" that appears in
8255 ;; a function call that wants a structure value,
8256 ;; to inform the called function if compiled with Sun CC.
8257 ;(define_insn "*unimp_insn"
8258 ; [(match_operand:SI 0 "immediate_operand" "")]
8259 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8260 ; "unimp\\t%0"
8261 ; [(set_attr "type" "marker")])
8262
8263 ;;- jump to subroutine
8264 (define_expand "call"
8265 ;; Note that this expression is not used for generating RTL.
8266 ;; All the RTL is generated explicitly below.
8267 [(call (match_operand 0 "call_operand" "")
8268 (match_operand 3 "" "i"))]
8269 ;; operands[2] is next_arg_register
8270 ;; operands[3] is struct_value_size_rtx.
8271 ""
8272 "
8273 {
8274 rtx fn_rtx, nregs_rtx;
8275
8276 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8277 abort ();
8278
8279 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8280 {
8281 /* This is really a PIC sequence. We want to represent
8282 it as a funny jump so its delay slots can be filled.
8283
8284 ??? But if this really *is* a CALL, will not it clobber the
8285 call-clobbered registers? We lose this if it is a JUMP_INSN.
8286 Why cannot we have delay slots filled if it were a CALL? */
8287
8288 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8289 emit_jump_insn
8290 (gen_rtx_PARALLEL
8291 (VOIDmode,
8292 gen_rtvec (3,
8293 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8294 operands[3],
8295 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8296 else
8297 emit_jump_insn
8298 (gen_rtx_PARALLEL
8299 (VOIDmode,
8300 gen_rtvec (2,
8301 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8302 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8303 goto finish_call;
8304 }
8305
8306 fn_rtx = operands[0];
8307
8308 /* Count the number of parameter registers being used by this call.
8309 if that argument is NULL, it means we are using them all, which
8310 means 6 on the sparc. */
8311 #if 0
8312 if (operands[2])
8313 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8314 else
8315 nregs_rtx = GEN_INT (6);
8316 #else
8317 nregs_rtx = const0_rtx;
8318 #endif
8319
8320 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8321 emit_call_insn
8322 (gen_rtx_PARALLEL
8323 (VOIDmode,
8324 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8325 operands[3],
8326 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8327 else
8328 emit_call_insn
8329 (gen_rtx_PARALLEL
8330 (VOIDmode,
8331 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8332 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8333
8334 finish_call:
8335 #if 0
8336 /* If this call wants a structure value,
8337 emit an unimp insn to let the called function know about this. */
8338 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8339 {
8340 rtx insn = emit_insn (operands[3]);
8341 SCHED_GROUP_P (insn) = 1;
8342 }
8343 #endif
8344
8345 DONE;
8346 }")
8347
8348 ;; We can't use the same pattern for these two insns, because then registers
8349 ;; in the address may not be properly reloaded.
8350
8351 (define_insn "*call_address_sp32"
8352 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8353 (match_operand 1 "" ""))
8354 (clobber (reg:SI 15))]
8355 ;;- Do not use operand 1 for most machines.
8356 "! TARGET_ARCH64"
8357 "call\\t%a0, %1%#"
8358 [(set_attr "type" "call")])
8359
8360 (define_insn "*call_symbolic_sp32"
8361 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8362 (match_operand 1 "" ""))
8363 (clobber (reg:SI 15))]
8364 ;;- Do not use operand 1 for most machines.
8365 "! TARGET_ARCH64"
8366 "call\\t%a0, %1%#"
8367 [(set_attr "type" "call")])
8368
8369 (define_insn "*call_address_sp64"
8370 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8371 (match_operand 1 "" ""))
8372 (clobber (reg:DI 15))]
8373 ;;- Do not use operand 1 for most machines.
8374 "TARGET_ARCH64"
8375 "call\\t%a0, %1%#"
8376 [(set_attr "type" "call")])
8377
8378 (define_insn "*call_symbolic_sp64"
8379 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8380 (match_operand 1 "" ""))
8381 (clobber (reg:DI 15))]
8382 ;;- Do not use operand 1 for most machines.
8383 "TARGET_ARCH64"
8384 "call\\t%a0, %1%#"
8385 [(set_attr "type" "call")])
8386
8387 ;; This is a call that wants a structure value.
8388 ;; There is no such critter for v9 (??? we may need one anyway).
8389 (define_insn "*call_address_struct_value_sp32"
8390 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8391 (match_operand 1 "" ""))
8392 (match_operand 2 "immediate_operand" "")
8393 (clobber (reg:SI 15))]
8394 ;;- Do not use operand 1 for most machines.
8395 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8396 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8397 [(set_attr "type" "call_no_delay_slot")
8398 (set_attr "length" "2")])
8399
8400 ;; This is a call that wants a structure value.
8401 ;; There is no such critter for v9 (??? we may need one anyway).
8402 (define_insn "*call_symbolic_struct_value_sp32"
8403 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8404 (match_operand 1 "" ""))
8405 (match_operand 2 "immediate_operand" "")
8406 (clobber (reg:SI 15))]
8407 ;;- Do not use operand 1 for most machines.
8408 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8409 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8410 [(set_attr "type" "call_no_delay_slot")
8411 (set_attr "length" "2")])
8412
8413 ;; This is a call that may want a structure value. This is used for
8414 ;; untyped_calls.
8415 (define_insn "*call_address_untyped_struct_value_sp32"
8416 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8417 (match_operand 1 "" ""))
8418 (match_operand 2 "immediate_operand" "")
8419 (clobber (reg:SI 15))]
8420 ;;- Do not use operand 1 for most machines.
8421 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8422 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8423 [(set_attr "type" "call_no_delay_slot")
8424 (set_attr "length" "2")])
8425
8426 ;; This is a call that wants a structure value.
8427 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8428 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8429 (match_operand 1 "" ""))
8430 (match_operand 2 "immediate_operand" "")
8431 (clobber (reg:SI 15))]
8432 ;;- Do not use operand 1 for most machines.
8433 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8434 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8435 [(set_attr "type" "call_no_delay_slot")
8436 (set_attr "length" "2")])
8437
8438 (define_expand "call_value"
8439 ;; Note that this expression is not used for generating RTL.
8440 ;; All the RTL is generated explicitly below.
8441 [(set (match_operand 0 "register_operand" "=rf")
8442 (call (match_operand 1 "" "")
8443 (match_operand 4 "" "")))]
8444 ;; operand 2 is stack_size_rtx
8445 ;; operand 3 is next_arg_register
8446 ""
8447 "
8448 {
8449 rtx fn_rtx, nregs_rtx;
8450 rtvec vec;
8451
8452 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8453 abort ();
8454
8455 fn_rtx = operands[1];
8456
8457 #if 0
8458 if (operands[3])
8459 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8460 else
8461 nregs_rtx = GEN_INT (6);
8462 #else
8463 nregs_rtx = const0_rtx;
8464 #endif
8465
8466 vec = gen_rtvec (2,
8467 gen_rtx_SET (VOIDmode, operands[0],
8468 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8469 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8470
8471 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8472
8473 DONE;
8474 }")
8475
8476 (define_insn "*call_value_address_sp32"
8477 [(set (match_operand 0 "" "=rf")
8478 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8479 (match_operand 2 "" "")))
8480 (clobber (reg:SI 15))]
8481 ;;- Do not use operand 2 for most machines.
8482 "! TARGET_ARCH64"
8483 "call\\t%a1, %2%#"
8484 [(set_attr "type" "call")])
8485
8486 (define_insn "*call_value_symbolic_sp32"
8487 [(set (match_operand 0 "" "=rf")
8488 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8489 (match_operand 2 "" "")))
8490 (clobber (reg:SI 15))]
8491 ;;- Do not use operand 2 for most machines.
8492 "! TARGET_ARCH64"
8493 "call\\t%a1, %2%#"
8494 [(set_attr "type" "call")])
8495
8496 (define_insn "*call_value_address_sp64"
8497 [(set (match_operand 0 "" "")
8498 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8499 (match_operand 2 "" "")))
8500 (clobber (reg:DI 15))]
8501 ;;- Do not use operand 2 for most machines.
8502 "TARGET_ARCH64"
8503 "call\\t%a1, %2%#"
8504 [(set_attr "type" "call")])
8505
8506 (define_insn "*call_value_symbolic_sp64"
8507 [(set (match_operand 0 "" "")
8508 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8509 (match_operand 2 "" "")))
8510 (clobber (reg:DI 15))]
8511 ;;- Do not use operand 2 for most machines.
8512 "TARGET_ARCH64"
8513 "call\\t%a1, %2%#"
8514 [(set_attr "type" "call")])
8515
8516 (define_expand "untyped_call"
8517 [(parallel [(call (match_operand 0 "" "")
8518 (const_int 0))
8519 (match_operand 1 "" "")
8520 (match_operand 2 "" "")])]
8521 ""
8522 "
8523 {
8524 int i;
8525
8526 /* Pass constm1 to indicate that it may expect a structure value, but
8527 we don't know what size it is. */
8528 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8529
8530 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8531 {
8532 rtx set = XVECEXP (operands[2], 0, i);
8533 emit_move_insn (SET_DEST (set), SET_SRC (set));
8534 }
8535
8536 /* The optimizer does not know that the call sets the function value
8537 registers we stored in the result block. We avoid problems by
8538 claiming that all hard registers are used and clobbered at this
8539 point. */
8540 emit_insn (gen_blockage ());
8541
8542 DONE;
8543 }")
8544
8545 ;;- tail calls
8546 (define_expand "sibcall"
8547 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8548 (return)])]
8549 ""
8550 "")
8551
8552 (define_insn "*sibcall_symbolic_sp32"
8553 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8554 (match_operand 1 "" ""))
8555 (return)]
8556 "! TARGET_ARCH64"
8557 "* return output_sibcall(insn, operands[0]);"
8558 [(set_attr "type" "sibcall")])
8559
8560 (define_insn "*sibcall_symbolic_sp64"
8561 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8562 (match_operand 1 "" ""))
8563 (return)]
8564 "TARGET_ARCH64"
8565 "* return output_sibcall(insn, operands[0]);"
8566 [(set_attr "type" "sibcall")])
8567
8568 (define_expand "sibcall_value"
8569 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8570 (call (match_operand 1 "" "") (const_int 0)))
8571 (return)])]
8572 ""
8573 "")
8574
8575 (define_insn "*sibcall_value_symbolic_sp32"
8576 [(set (match_operand 0 "" "=rf")
8577 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8578 (match_operand 2 "" "")))
8579 (return)]
8580 "! TARGET_ARCH64"
8581 "* return output_sibcall(insn, operands[1]);"
8582 [(set_attr "type" "sibcall")])
8583
8584 (define_insn "*sibcall_value_symbolic_sp64"
8585 [(set (match_operand 0 "" "")
8586 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8587 (match_operand 2 "" "")))
8588 (return)]
8589 "TARGET_ARCH64"
8590 "* return output_sibcall(insn, operands[1]);"
8591 [(set_attr "type" "sibcall")])
8592
8593 (define_expand "sibcall_epilogue"
8594 [(const_int 0)]
8595 ""
8596 "DONE;")
8597
8598 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8599 ;; all of memory. This blocks insns from being moved across this point.
8600
8601 (define_insn "blockage"
8602 [(unspec_volatile [(const_int 0)] 0)]
8603 ""
8604 ""
8605 [(set_attr "length" "0")])
8606
8607 ;; Prepare to return any type including a structure value.
8608
8609 (define_expand "untyped_return"
8610 [(match_operand:BLK 0 "memory_operand" "")
8611 (match_operand 1 "" "")]
8612 ""
8613 "
8614 {
8615 rtx valreg1 = gen_rtx_REG (DImode, 24);
8616 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8617 rtx result = operands[0];
8618
8619 if (! TARGET_ARCH64)
8620 {
8621 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8622 ? 15 : 31));
8623 rtx value = gen_reg_rtx (SImode);
8624
8625 /* Fetch the instruction where we will return to and see if it's an unimp
8626 instruction (the most significant 10 bits will be zero). If so,
8627 update the return address to skip the unimp instruction. */
8628 emit_move_insn (value,
8629 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8630 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8631 emit_insn (gen_update_return (rtnreg, value));
8632 }
8633
8634 /* Reload the function value registers. */
8635 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8636 emit_move_insn (valreg2,
8637 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8638
8639 /* Put USE insns before the return. */
8640 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8641 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8642
8643 /* Construct the return. */
8644 expand_null_return ();
8645
8646 DONE;
8647 }")
8648
8649 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8650 ;; and parts of the compiler don't want to believe that the add is needed.
8651
8652 (define_insn "update_return"
8653 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8654 (match_operand:SI 1 "register_operand" "r")] 1)]
8655 "! TARGET_ARCH64"
8656 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8657 [(set_attr "type" "multi")
8658 (set_attr "length" "3")])
8659 \f
8660 (define_insn "return"
8661 [(return)
8662 (use (reg:SI 31))]
8663 "! TARGET_EPILOGUE"
8664 "* return output_return (operands);"
8665 [(set_attr "type" "return")])
8666
8667 (define_peephole
8668 [(set (match_operand:SI 0 "register_operand" "=r")
8669 (match_operand:SI 1 "arith_operand" "rI"))
8670 (parallel [(return)
8671 (use (reg:SI 31))])]
8672 "sparc_return_peephole_ok (operands[0], operands[1])"
8673 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8674
8675 (define_insn "nop"
8676 [(const_int 0)]
8677 ""
8678 "nop")
8679
8680 (define_expand "indirect_jump"
8681 [(set (pc) (match_operand 0 "address_operand" "p"))]
8682 ""
8683 "")
8684
8685 (define_insn "*branch_sp32"
8686 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8687 "! TARGET_ARCH64"
8688 "jmp\\t%a0%#"
8689 [(set_attr "type" "uncond_branch")])
8690
8691 (define_insn "*branch_sp64"
8692 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8693 "TARGET_ARCH64"
8694 "jmp\\t%a0%#"
8695 [(set_attr "type" "uncond_branch")])
8696
8697 ;; ??? Doesn't work with -mflat.
8698 (define_expand "nonlocal_goto"
8699 [(match_operand:SI 0 "general_operand" "")
8700 (match_operand:SI 1 "general_operand" "")
8701 (match_operand:SI 2 "general_operand" "")
8702 (match_operand:SI 3 "" "")]
8703 ""
8704 "
8705 {
8706 #if 0
8707 rtx chain = operands[0];
8708 #endif
8709 rtx lab = operands[1];
8710 rtx stack = operands[2];
8711 rtx fp = operands[3];
8712 rtx labreg;
8713
8714 /* Trap instruction to flush all the register windows. */
8715 emit_insn (gen_flush_register_windows ());
8716
8717 /* Load the fp value for the containing fn into %fp. This is needed
8718 because STACK refers to %fp. Note that virtual register instantiation
8719 fails if the virtual %fp isn't set from a register. */
8720 if (GET_CODE (fp) != REG)
8721 fp = force_reg (Pmode, fp);
8722 emit_move_insn (virtual_stack_vars_rtx, fp);
8723
8724 /* Find the containing function's current nonlocal goto handler,
8725 which will do any cleanups and then jump to the label. */
8726 labreg = gen_rtx_REG (Pmode, 8);
8727 emit_move_insn (labreg, lab);
8728
8729 /* Restore %fp from stack pointer value for containing function.
8730 The restore insn that follows will move this to %sp,
8731 and reload the appropriate value into %fp. */
8732 emit_move_insn (hard_frame_pointer_rtx, stack);
8733
8734 /* USE of frame_pointer_rtx added for consistency; not clear if
8735 really needed. */
8736 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8737 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8738
8739 #if 0
8740 /* Return, restoring reg window and jumping to goto handler. */
8741 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8742 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8743 {
8744 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8745 static_chain_rtx,
8746 chain));
8747 emit_barrier ();
8748 DONE;
8749 }
8750 /* Put in the static chain register the nonlocal label address. */
8751 emit_move_insn (static_chain_rtx, chain);
8752 #endif
8753
8754 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8755 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8756 emit_barrier ();
8757 DONE;
8758 }")
8759
8760 ;; Special trap insn to flush register windows.
8761 (define_insn "flush_register_windows"
8762 [(unspec_volatile [(const_int 0)] 1)]
8763 ""
8764 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8765 [(set_attr "type" "misc")])
8766
8767 (define_insn "goto_handler_and_restore"
8768 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8769 "GET_MODE (operands[0]) == Pmode"
8770 "jmp\\t%0+0\\n\\trestore"
8771 [(set_attr "type" "multi")
8772 (set_attr "length" "2")])
8773
8774 ;;(define_insn "goto_handler_and_restore_v9"
8775 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8776 ;; (match_operand:SI 1 "register_operand" "=r,r")
8777 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8778 ;; "TARGET_V9 && ! TARGET_ARCH64"
8779 ;; "@
8780 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8781 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8782 ;; [(set_attr "type" "multi")
8783 ;; (set_attr "length" "2,3")])
8784 ;;
8785 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8786 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8787 ;; (match_operand:DI 1 "register_operand" "=r,r")
8788 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8789 ;; "TARGET_V9 && TARGET_ARCH64"
8790 ;; "@
8791 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8792 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8793 ;; [(set_attr "type" "multi")
8794 ;; (set_attr "length" "2,3")])
8795
8796 ;; For __builtin_setjmp we need to flush register windows iff the function
8797 ;; calls alloca as well, because otherwise the register window might be
8798 ;; saved after %sp adjustement and thus setjmp would crash
8799 (define_expand "builtin_setjmp_setup"
8800 [(match_operand 0 "register_operand" "r")]
8801 ""
8802 "
8803 {
8804 emit_insn (gen_do_builtin_setjmp_setup ());
8805 DONE;
8806 }")
8807
8808 ;; ??? Should set length to zero when !current_function_calls_alloca,
8809 ;; ??? but there is no easy way to get at that definition. It would
8810 ;; ??? require including function.h into sparc-protos.h and that is
8811 ;; ??? likely not a good idea. -DaveM
8812 (define_insn "do_builtin_setjmp_setup"
8813 [(unspec_volatile [(const_int 0)] 5)]
8814 ""
8815 "*
8816 {
8817 if (!current_function_calls_alloca)
8818 return \"\";
8819 if (TARGET_V9)
8820 return \"flushw\";
8821 return \"ta\\t3\";
8822 }"
8823 [(set_attr "type" "misc")])
8824
8825 ;; Pattern for use after a setjmp to store FP and the return register
8826 ;; into the stack area.
8827
8828 (define_expand "setjmp"
8829 [(const_int 0)]
8830 ""
8831 "
8832 {
8833 if (TARGET_ARCH64)
8834 emit_insn (gen_setjmp_64 ());
8835 else
8836 emit_insn (gen_setjmp_32 ());
8837 DONE;
8838 }")
8839
8840 (define_expand "setjmp_32"
8841 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8842 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8843 ""
8844 "
8845 { operands[0] = frame_pointer_rtx; }")
8846
8847 (define_expand "setjmp_64"
8848 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8849 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8850 ""
8851 "
8852 { operands[0] = frame_pointer_rtx; }")
8853
8854 ;; Special pattern for the FLUSH instruction.
8855
8856 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8857 ; of the define_insn otherwise missing a mode. We make "flush", aka
8858 ; gen_flush, the default one since sparc_initialize_trampoline uses
8859 ; it on SImode mem values.
8860
8861 (define_insn "flush"
8862 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8863 ""
8864 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8865 [(set_attr "type" "misc")])
8866
8867 (define_insn "flushdi"
8868 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8869 ""
8870 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8871 [(set_attr "type" "misc")])
8872
8873 \f
8874 ;; find first set.
8875
8876 ;; The scan instruction searches from the most significant bit while ffs
8877 ;; searches from the least significant bit. The bit index and treatment of
8878 ;; zero also differ. It takes at least 7 instructions to get the proper
8879 ;; result. Here is an obvious 8 instruction sequence.
8880
8881 ;; XXX
8882 (define_insn "ffssi2"
8883 [(set (match_operand:SI 0 "register_operand" "=&r")
8884 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8885 (clobber (match_scratch:SI 2 "=&r"))]
8886 "TARGET_SPARCLITE || TARGET_SPARCLET"
8887 "*
8888 {
8889 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\";
8890 }"
8891 [(set_attr "type" "multi")
8892 (set_attr "length" "8")])
8893
8894 ;; ??? This should be a define expand, so that the extra instruction have
8895 ;; a chance of being optimized away.
8896
8897 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8898 ;; does, but no one uses that and we don't have a switch for it.
8899 ;
8900 ;(define_insn "ffsdi2"
8901 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8902 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8903 ; (clobber (match_scratch:DI 2 "=&r"))]
8904 ; "TARGET_ARCH64"
8905 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8906 ; [(set_attr "type" "multi")
8907 ; (set_attr "length" "4")])
8908
8909
8910 \f
8911 ;; Peepholes go at the end.
8912
8913 ;; Optimize consecutive loads or stores into ldd and std when possible.
8914 ;; The conditions in which we do this are very restricted and are
8915 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8916
8917 (define_peephole2
8918 [(set (match_operand:SI 0 "memory_operand" "")
8919 (const_int 0))
8920 (set (match_operand:SI 1 "memory_operand" "")
8921 (const_int 0))]
8922 "TARGET_V9
8923 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8924 [(set (match_dup 0)
8925 (const_int 0))]
8926 "operands[0] = change_address (operands[0], DImode, NULL);")
8927
8928 (define_peephole2
8929 [(set (match_operand:SI 0 "memory_operand" "")
8930 (const_int 0))
8931 (set (match_operand:SI 1 "memory_operand" "")
8932 (const_int 0))]
8933 "TARGET_V9
8934 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8935 [(set (match_dup 1)
8936 (const_int 0))]
8937 "operands[1] = change_address (operands[1], DImode, NULL);")
8938
8939 (define_peephole2
8940 [(set (match_operand:SI 0 "register_operand" "")
8941 (match_operand:SI 1 "memory_operand" ""))
8942 (set (match_operand:SI 2 "register_operand" "")
8943 (match_operand:SI 3 "memory_operand" ""))]
8944 "registers_ok_for_ldd_peep (operands[0], operands[2])
8945 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8946 [(set (match_dup 0)
8947 (match_dup 1))]
8948 "operands[1] = change_address (operands[1], DImode, NULL);
8949 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8950
8951 (define_peephole2
8952 [(set (match_operand:SI 0 "memory_operand" "")
8953 (match_operand:SI 1 "register_operand" ""))
8954 (set (match_operand:SI 2 "memory_operand" "")
8955 (match_operand:SI 3 "register_operand" ""))]
8956 "registers_ok_for_ldd_peep (operands[1], operands[3])
8957 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8958 [(set (match_dup 0)
8959 (match_dup 1))]
8960 "operands[0] = change_address (operands[0], DImode, NULL);
8961 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8962
8963 (define_peephole2
8964 [(set (match_operand:SF 0 "register_operand" "")
8965 (match_operand:SF 1 "memory_operand" ""))
8966 (set (match_operand:SF 2 "register_operand" "")
8967 (match_operand:SF 3 "memory_operand" ""))]
8968 "registers_ok_for_ldd_peep (operands[0], operands[2])
8969 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8970 [(set (match_dup 0)
8971 (match_dup 1))]
8972 "operands[1] = change_address (operands[1], DFmode, NULL);
8973 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8974
8975 (define_peephole2
8976 [(set (match_operand:SF 0 "memory_operand" "")
8977 (match_operand:SF 1 "register_operand" ""))
8978 (set (match_operand:SF 2 "memory_operand" "")
8979 (match_operand:SF 3 "register_operand" ""))]
8980 "registers_ok_for_ldd_peep (operands[1], operands[3])
8981 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8982 [(set (match_dup 0)
8983 (match_dup 1))]
8984 "operands[0] = change_address (operands[0], DFmode, NULL);
8985 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8986
8987 (define_peephole2
8988 [(set (match_operand:SI 0 "register_operand" "")
8989 (match_operand:SI 1 "memory_operand" ""))
8990 (set (match_operand:SI 2 "register_operand" "")
8991 (match_operand:SI 3 "memory_operand" ""))]
8992 "registers_ok_for_ldd_peep (operands[2], operands[0])
8993 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
8994 [(set (match_dup 2)
8995 (match_dup 3))]
8996 "operands[3] = change_address (operands[3], DImode, NULL);
8997 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8998
8999 (define_peephole2
9000 [(set (match_operand:SI 0 "memory_operand" "")
9001 (match_operand:SI 1 "register_operand" ""))
9002 (set (match_operand:SI 2 "memory_operand" "")
9003 (match_operand:SI 3 "register_operand" ""))]
9004 "registers_ok_for_ldd_peep (operands[3], operands[1])
9005 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9006 [(set (match_dup 2)
9007 (match_dup 3))]
9008 "operands[2] = change_address (operands[2], DImode, NULL);
9009 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9010 ")
9011
9012 (define_peephole2
9013 [(set (match_operand:SF 0 "register_operand" "")
9014 (match_operand:SF 1 "memory_operand" ""))
9015 (set (match_operand:SF 2 "register_operand" "")
9016 (match_operand:SF 3 "memory_operand" ""))]
9017 "registers_ok_for_ldd_peep (operands[2], operands[0])
9018 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9019 [(set (match_dup 2)
9020 (match_dup 3))]
9021 "operands[3] = change_address (operands[3], DFmode, NULL);
9022 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9023
9024 (define_peephole2
9025 [(set (match_operand:SF 0 "memory_operand" "")
9026 (match_operand:SF 1 "register_operand" ""))
9027 (set (match_operand:SF 2 "memory_operand" "")
9028 (match_operand:SF 3 "register_operand" ""))]
9029 "registers_ok_for_ldd_peep (operands[3], operands[1])
9030 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9031 [(set (match_dup 2)
9032 (match_dup 3))]
9033 "operands[2] = change_address (operands[2], DFmode, NULL);
9034 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9035
9036 ;; Optimize the case of following a reg-reg move with a test
9037 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9038 ;; This can result from a float to fix conversion.
9039
9040 (define_peephole2
9041 [(set (match_operand:SI 0 "register_operand" "")
9042 (match_operand:SI 1 "register_operand" ""))
9043 (set (reg:CC 100)
9044 (compare:CC (match_operand:SI 2 "register_operand" "")
9045 (const_int 0)))]
9046 "(rtx_equal_p (operands[2], operands[0])
9047 || rtx_equal_p (operands[2], operands[1]))
9048 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9049 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9050 [(parallel [(set (match_dup 0) (match_dup 1))
9051 (set (reg:CC 100)
9052 (compare:CC (match_dup 1) (const_int 0)))])]
9053 "")
9054
9055 (define_peephole2
9056 [(set (match_operand:DI 0 "register_operand" "")
9057 (match_operand:DI 1 "register_operand" ""))
9058 (set (reg:CCX 100)
9059 (compare:CCX (match_operand:DI 2 "register_operand" "")
9060 (const_int 0)))]
9061 "TARGET_ARCH64
9062 && (rtx_equal_p (operands[2], operands[0])
9063 || rtx_equal_p (operands[2], operands[1]))
9064 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9065 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9066 [(parallel [(set (match_dup 0) (match_dup 1))
9067 (set (reg:CCX 100)
9068 (compare:CC (match_dup 1) (const_int 0)))])]
9069 "")
9070
9071 ;; Return peepholes. First the "normal" ones.
9072 ;; These are necessary to catch insns ending up in the epilogue delay list.
9073
9074 (define_insn "*return_qi"
9075 [(set (match_operand:QI 0 "restore_operand" "")
9076 (match_operand:QI 1 "arith_operand" "rI"))
9077 (return)]
9078 "! TARGET_EPILOGUE"
9079 "*
9080 {
9081 if (! TARGET_ARCH64 && current_function_returns_struct)
9082 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9083 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9084 || IN_OR_GLOBAL_P (operands[1])))
9085 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9086 else
9087 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9088 }"
9089 [(set_attr "type" "multi")
9090 (set_attr "length" "2")])
9091
9092 (define_insn "*return_hi"
9093 [(set (match_operand:HI 0 "restore_operand" "")
9094 (match_operand:HI 1 "arith_operand" "rI"))
9095 (return)]
9096 "! TARGET_EPILOGUE"
9097 "*
9098 {
9099 if (! TARGET_ARCH64 && current_function_returns_struct)
9100 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9101 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9102 || IN_OR_GLOBAL_P (operands[1])))
9103 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9104 else
9105 return \"ret\;restore %%g0, %1, %Y0\";
9106 }"
9107 [(set_attr "type" "multi")
9108 (set_attr "length" "2")])
9109
9110 (define_insn "*return_si"
9111 [(set (match_operand:SI 0 "restore_operand" "")
9112 (match_operand:SI 1 "arith_operand" "rI"))
9113 (return)]
9114 "! TARGET_EPILOGUE"
9115 "*
9116 {
9117 if (! TARGET_ARCH64 && current_function_returns_struct)
9118 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9119 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9120 || IN_OR_GLOBAL_P (operands[1])))
9121 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9122 else
9123 return \"ret\;restore %%g0, %1, %Y0\";
9124 }"
9125 [(set_attr "type" "multi")
9126 (set_attr "length" "2")])
9127
9128 ;; The following pattern is only generated by delayed-branch scheduling,
9129 ;; when the insn winds up in the epilogue. This can happen not only when
9130 ;; ! TARGET_FPU because we move complex types around by parts using
9131 ;; SF mode SUBREGs.
9132 (define_insn "*return_sf_no_fpu"
9133 [(set (match_operand:SF 0 "restore_operand" "=r")
9134 (match_operand:SF 1 "register_operand" "r"))
9135 (return)]
9136 "! TARGET_EPILOGUE"
9137 "*
9138 {
9139 if (! TARGET_ARCH64 && current_function_returns_struct)
9140 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9141 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9142 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9143 else
9144 return \"ret\;restore %%g0, %1, %Y0\";
9145 }"
9146 [(set_attr "type" "multi")
9147 (set_attr "length" "2")])
9148
9149 (define_insn "*return_df_no_fpu"
9150 [(set (match_operand:DF 0 "restore_operand" "=r")
9151 (match_operand:DF 1 "register_operand" "r"))
9152 (return)]
9153 "! TARGET_EPILOGUE && TARGET_ARCH64"
9154 "*
9155 {
9156 if (IN_OR_GLOBAL_P (operands[1]))
9157 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9158 else
9159 return \"ret\;restore %%g0, %1, %Y0\";
9160 }"
9161 [(set_attr "type" "multi")
9162 (set_attr "length" "2")])
9163
9164 (define_insn "*return_addsi"
9165 [(set (match_operand:SI 0 "restore_operand" "")
9166 (plus:SI (match_operand:SI 1 "register_operand" "r")
9167 (match_operand:SI 2 "arith_operand" "rI")))
9168 (return)]
9169 "! TARGET_EPILOGUE"
9170 "*
9171 {
9172 if (! TARGET_ARCH64 && current_function_returns_struct)
9173 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9174 /* If operands are global or in registers, can use return */
9175 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9176 && (GET_CODE (operands[2]) == CONST_INT
9177 || IN_OR_GLOBAL_P (operands[2])))
9178 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9179 else
9180 return \"ret\;restore %r1, %2, %Y0\";
9181 }"
9182 [(set_attr "type" "multi")
9183 (set_attr "length" "2")])
9184
9185 (define_insn "*return_losum_si"
9186 [(set (match_operand:SI 0 "restore_operand" "")
9187 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9188 (match_operand:SI 2 "immediate_operand" "in")))
9189 (return)]
9190 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9191 "*
9192 {
9193 if (! TARGET_ARCH64 && current_function_returns_struct)
9194 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9195 /* If operands are global or in registers, can use return */
9196 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9197 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9198 else
9199 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9200 }"
9201 [(set_attr "type" "multi")
9202 (set_attr "length" "2")])
9203
9204 (define_insn "*return_di"
9205 [(set (match_operand:DI 0 "restore_operand" "")
9206 (match_operand:DI 1 "arith_double_operand" "rHI"))
9207 (return)]
9208 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9209 "ret\;restore %%g0, %1, %Y0"
9210 [(set_attr "type" "multi")
9211 (set_attr "length" "2")])
9212
9213 (define_insn "*return_adddi"
9214 [(set (match_operand:DI 0 "restore_operand" "")
9215 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9216 (match_operand:DI 2 "arith_double_operand" "rHI")))
9217 (return)]
9218 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9219 "ret\;restore %r1, %2, %Y0"
9220 [(set_attr "type" "multi")
9221 (set_attr "length" "2")])
9222
9223 (define_insn "*return_losum_di"
9224 [(set (match_operand:DI 0 "restore_operand" "")
9225 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9226 (match_operand:DI 2 "immediate_operand" "in")))
9227 (return)]
9228 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9229 "ret\;restore %r1, %%lo(%a2), %Y0"
9230 [(set_attr "type" "multi")
9231 (set_attr "length" "2")])
9232
9233 ;; The following pattern is only generated by delayed-branch scheduling,
9234 ;; when the insn winds up in the epilogue.
9235 (define_insn "*return_sf"
9236 [(set (reg:SF 32)
9237 (match_operand:SF 0 "register_operand" "f"))
9238 (return)]
9239 "! TARGET_EPILOGUE"
9240 "ret\;fmovs\\t%0, %%f0"
9241 [(set_attr "type" "multi")
9242 (set_attr "length" "2")])
9243
9244 ;; Now peepholes to do a call followed by a jump.
9245
9246 (define_peephole
9247 [(parallel [(set (match_operand 0 "" "")
9248 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9249 (match_operand 2 "" "")))
9250 (clobber (reg:SI 15))])
9251 (set (pc) (label_ref (match_operand 3 "" "")))]
9252 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9253 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9254 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9255
9256 (define_peephole
9257 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9258 (match_operand 1 "" ""))
9259 (clobber (reg:SI 15))])
9260 (set (pc) (label_ref (match_operand 2 "" "")))]
9261 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9262 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9263 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9264
9265 (define_peephole
9266 [(parallel [(set (match_operand 0 "" "")
9267 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9268 (match_operand 2 "" "")))
9269 (clobber (reg:DI 15))])
9270 (set (pc) (label_ref (match_operand 3 "" "")))]
9271 "TARGET_ARCH64
9272 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9273 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9274 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9275
9276 (define_peephole
9277 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9278 (match_operand 1 "" ""))
9279 (clobber (reg:DI 15))])
9280 (set (pc) (label_ref (match_operand 2 "" "")))]
9281 "TARGET_ARCH64
9282 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9283 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9284 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9285
9286 (define_insn "prefetch"
9287 [(prefetch (match_operand:DI 0 "address_operand" "p")
9288 (match_operand:DI 1 "const_int_operand" "n")
9289 (match_operand:DI 2 "const_int_operand" "n"))]
9290 "TARGET_V9"
9291 {
9292 static const char * const prefetch_instr[2][4] = {
9293 {
9294 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9295 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9296 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9297 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9298 },
9299 {
9300 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9301 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9302 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9303 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9304 }
9305 };
9306 int read_or_write = INTVAL (operands[1]);
9307 int locality = INTVAL (operands[2]);
9308
9309 if (read_or_write != 0 && read_or_write != 1)
9310 abort ();
9311 if (locality < 0 || locality > 3)
9312 abort ();
9313 return prefetch_instr [read_or_write][locality];
9314 }
9315 [(set_attr "type" "load")])
9316 \f
9317 (define_expand "prologue"
9318 [(const_int 1)]
9319 "flag_pic && current_function_uses_pic_offset_table"
9320 "
9321 {
9322 load_pic_register ();
9323 DONE;
9324 }")
9325
9326 ;; We need to reload %l7 for -mflat -fpic,
9327 ;; otherwise %l7 should be preserved simply
9328 ;; by loading the function's register window
9329 (define_expand "exception_receiver"
9330 [(const_int 0)]
9331 "TARGET_FLAT && flag_pic"
9332 "
9333 {
9334 load_pic_register ();
9335 DONE;
9336 }")
9337
9338 ;; Likewise
9339 (define_expand "builtin_setjmp_receiver"
9340 [(label_ref (match_operand 0 "" ""))]
9341 "TARGET_FLAT && flag_pic"
9342 "
9343 {
9344 load_pic_register ();
9345 DONE;
9346 }")
9347 \f
9348 (define_insn "trap"
9349 [(trap_if (const_int 1) (const_int 5))]
9350 ""
9351 "ta\\t5"
9352 [(set_attr "type" "misc")])
9353
9354 (define_expand "conditional_trap"
9355 [(trap_if (match_operator 0 "noov_compare_op"
9356 [(match_dup 2) (match_dup 3)])
9357 (match_operand:SI 1 "arith_operand" ""))]
9358 ""
9359 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9360 sparc_compare_op0, sparc_compare_op1);
9361 operands[3] = const0_rtx;")
9362
9363 (define_insn ""
9364 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9365 (match_operand:SI 1 "arith_operand" "rM"))]
9366 ""
9367 "t%C0\\t%1"
9368 [(set_attr "type" "misc")])
9369
9370 (define_insn ""
9371 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9372 (match_operand:SI 1 "arith_operand" "rM"))]
9373 "TARGET_V9"
9374 "t%C0\\t%%xcc, %1"
9375 [(set_attr "type" "misc")])