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