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