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