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