1 ;; Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GNU CC.
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
29 ;; UNSPEC: 0 movsi_{lo_sum,high}_pic
34 ;; 5 movsi_{,lo_sum_,high_}pic_label_ref
40 ;; 11 embmedany_sethi, embmedany_brsum
41 ;; 13 embmedany_textuhi
42 ;; 14 embmedany_texthi
43 ;; 15 embmedany_textulo
44 ;; 16 embmedany_textlo
48 ;; UNSPEC_VOLATILE: 0 blockage
49 ;; 1 flush_register_windows
50 ;; 2 goto_handler_and_restore
51 ;; 3 goto_handler_and_restore_v9*
53 ;; 5 do_builtin_setjmp_setup
56 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
57 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
58 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
59 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
60 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
62 ;; Attribute for cpu type.
63 ;; These must match the values for enum processor_type in sparc.h.
64 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc,ultrasparc3"
65 (const (symbol_ref "sparc_cpu_attr")))
67 ;; Attribute for the instruction set.
68 ;; At present we only need to distinguish v9/!v9, but for clarity we
69 ;; test TARGET_V8 too.
70 (define_attr "isa" "v6,v8,v9,sparclet"
72 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
73 (symbol_ref "TARGET_V8") (const_string "v8")
74 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
75 (const_string "v6"))))
78 (define_attr "arch" "arch32bit,arch64bit"
80 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
81 (const_string "arch32bit"))))
86 "ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,idiv,fpload,fpstore,fp,fpmove,fpcmove,fpcrmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
87 (const_string "ialu"))
89 ;; true if branch/call has empty delay slot and will emit a nop in it
90 (define_attr "empty_delay_slot" "false,true"
91 (symbol_ref "empty_delay_slot (insn)"))
93 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
95 (define_attr "pic" "false,true"
96 (symbol_ref "flag_pic != 0"))
98 ;; Length (in # of insns).
99 (define_attr "length" ""
100 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
101 (if_then_else (eq_attr "empty_delay_slot" "true")
104 (eq_attr "branch_type" "icc")
105 (if_then_else (match_operand 0 "noov_compare64_op" "")
106 (if_then_else (lt (pc) (match_dup 1))
107 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
108 (if_then_else (eq_attr "empty_delay_slot" "true")
111 (if_then_else (eq_attr "empty_delay_slot" "true")
114 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
115 (if_then_else (eq_attr "empty_delay_slot" "true")
118 (if_then_else (eq_attr "empty_delay_slot" "true")
121 (if_then_else (eq_attr "empty_delay_slot" "true")
124 (eq_attr "branch_type" "fcc")
125 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
126 (if_then_else (eq_attr "empty_delay_slot" "true")
129 (if_then_else (lt (pc) (match_dup 2))
130 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
131 (if_then_else (eq_attr "empty_delay_slot" "true")
134 (if_then_else (eq_attr "empty_delay_slot" "true")
137 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
138 (if_then_else (eq_attr "empty_delay_slot" "true")
141 (if_then_else (eq_attr "empty_delay_slot" "true")
144 (eq_attr "branch_type" "reg")
145 (if_then_else (lt (pc) (match_dup 2))
146 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
147 (if_then_else (eq_attr "empty_delay_slot" "true")
150 (if_then_else (eq_attr "empty_delay_slot" "true")
153 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
154 (if_then_else (eq_attr "empty_delay_slot" "true")
157 (if_then_else (eq_attr "empty_delay_slot" "true")
163 (define_attr "fptype" "single,double" (const_string "single"))
165 ;; UltraSPARC-III integer load type.
166 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
168 (define_asm_attributes
169 [(set_attr "length" "2")
170 (set_attr "type" "multi")])
172 ;; Attributes for instruction and branch scheduling
174 (define_attr "in_call_delay" "false,true"
175 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
176 (const_string "false")
177 (eq_attr "type" "load,fpload,store,fpstore")
178 (if_then_else (eq_attr "length" "1")
179 (const_string "true")
180 (const_string "false"))]
181 (if_then_else (eq_attr "length" "1")
182 (const_string "true")
183 (const_string "false"))))
185 (define_delay (eq_attr "type" "call")
186 [(eq_attr "in_call_delay" "true") (nil) (nil)])
188 (define_attr "eligible_for_sibcall_delay" "false,true"
189 (symbol_ref "eligible_for_sibcall_delay (insn)"))
191 (define_delay (eq_attr "type" "sibcall")
192 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
194 (define_attr "leaf_function" "false,true"
195 (const (symbol_ref "current_function_uses_only_leaf_regs")))
197 (define_attr "eligible_for_return_delay" "false,true"
198 (symbol_ref "eligible_for_return_delay (insn)"))
200 (define_attr "in_return_delay" "false,true"
201 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
202 (eq_attr "length" "1"))
203 (eq_attr "leaf_function" "false"))
204 (eq_attr "eligible_for_return_delay" "false"))
205 (const_string "true")
206 (const_string "false")))
208 (define_delay (and (eq_attr "type" "return")
209 (eq_attr "isa" "v9"))
210 [(eq_attr "in_return_delay" "true") (nil) (nil)])
212 ;; ??? Should implement the notion of predelay slots for floating point
213 ;; branches. This would allow us to remove the nop always inserted before
214 ;; a floating point branch.
216 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
217 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
218 ;; This is because doing so will add several pipeline stalls to the path
219 ;; that the load/store did not come from. Unfortunately, there is no way
220 ;; to prevent fill_eager_delay_slots from using load/store without completely
221 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
222 ;; because it prevents us from moving back the final store of inner loops.
224 (define_attr "in_branch_delay" "false,true"
225 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
226 (eq_attr "length" "1"))
227 (const_string "true")
228 (const_string "false")))
230 (define_attr "in_uncond_branch_delay" "false,true"
231 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
232 (eq_attr "length" "1"))
233 (const_string "true")
234 (const_string "false")))
236 (define_attr "in_annul_branch_delay" "false,true"
237 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
238 (eq_attr "length" "1"))
239 (const_string "true")
240 (const_string "false")))
242 (define_delay (eq_attr "type" "branch")
243 [(eq_attr "in_branch_delay" "true")
244 (nil) (eq_attr "in_annul_branch_delay" "true")])
246 (define_delay (eq_attr "type" "uncond_branch")
247 [(eq_attr "in_uncond_branch_delay" "true")
250 ;; DFA scheduling on the SPARC
252 (define_automaton "cypress_0,cypress_1,supersparc_0,supersparc_1,hypersparc_0,hypersparc_1,sparclet,ultrasparc_0,ultrasparc_1,ultrasparc3_0,ultrasparc3_1")
254 ;; Cypress scheduling
256 (define_cpu_unit "cyp_memory, cyp_fpalu" "cypress_0")
257 (define_cpu_unit "cyp_fpmds" "cypress_1")
259 (define_insn_reservation "cyp_load" 2
260 (and (eq_attr "cpu" "cypress")
261 (eq_attr "type" "load,sload,fpload"))
262 "cyp_memory, nothing")
264 (define_insn_reservation "cyp_fp_alu" 5
265 (and (eq_attr "cpu" "cypress")
266 (eq_attr "type" "fp,fpmove"))
267 "cyp_fpalu, nothing*3")
269 (define_insn_reservation "cyp_fp_mult" 7
270 (and (eq_attr "cpu" "cypress")
271 (eq_attr "type" "fpmul"))
272 "cyp_fpmds, nothing*5")
274 (define_insn_reservation "cyp_fp_div" 37
275 (and (eq_attr "cpu" "cypress")
276 (eq_attr "type" "fpdivs,fpdivd"))
277 "cyp_fpmds, nothing*35")
279 (define_insn_reservation "cyp_fp_sqrt" 63
280 (and (eq_attr "cpu" "cypress")
281 (eq_attr "type" "fpsqrts,fpsqrtd"))
282 "cyp_fpmds, nothing*61")
284 ;; SuperSPARC scheduling
286 (define_cpu_unit "ss_memory, ss_shift, ss_iwport0, ss_iwport1" "supersparc_0")
287 (define_cpu_unit "ss_fpalu" "supersparc_0")
288 (define_cpu_unit "ss_fpmds" "supersparc_1")
290 (define_reservation "ss_iwport" "(ss_iwport0 | ss_iwport1)")
292 (define_insn_reservation "ss_iuload" 1
293 (and (eq_attr "cpu" "supersparc")
294 (eq_attr "type" "load,sload"))
297 ;; Ok, fpu loads deliver the result in zero cycles. But we
298 ;; have to show the ss_memory reservation somehow, thus...
299 (define_insn_reservation "ss_fpload" 0
300 (and (eq_attr "cpu" "supersparc")
301 (eq_attr "type" "fpload"))
304 (define_bypass 0 "ss_fpload" "ss_fp_alu,ss_fp_mult,ss_fp_divs,ss_fp_divd,ss_fp_sqrt")
306 (define_insn_reservation "ss_store" 1
307 (and (eq_attr "cpu" "supersparc")
308 (eq_attr "type" "store,fpstore"))
311 (define_insn_reservation "ss_ialu_shift" 1
312 (and (eq_attr "cpu" "supersparc")
313 (eq_attr "type" "shift"))
314 "ss_shift + ss_iwport")
316 (define_insn_reservation "ss_ialu_any" 1
317 (and (eq_attr "cpu" "supersparc")
318 (eq_attr "type" "load,sload,store,shift,ialu"))
321 (define_insn_reservation "ss_fp_alu" 3
322 (and (eq_attr "cpu" "supersparc")
323 (eq_attr "type" "fp,fpmove,fpcmp"))
324 "ss_fpalu, nothing*2")
326 (define_insn_reservation "ss_fp_mult" 3
327 (and (eq_attr "cpu" "supersparc")
328 (eq_attr "type" "fpmul"))
329 "ss_fpmds, nothing*2")
331 (define_insn_reservation "ss_fp_divs" 6
332 (and (eq_attr "cpu" "supersparc")
333 (eq_attr "type" "fpdivs"))
334 "ss_fpmds*4, nothing*2")
336 (define_insn_reservation "ss_fp_divd" 9
337 (and (eq_attr "cpu" "supersparc")
338 (eq_attr "type" "fpdivd"))
339 "ss_fpmds*7, nothing*2")
341 (define_insn_reservation "ss_fp_sqrt" 12
342 (and (eq_attr "cpu" "supersparc")
343 (eq_attr "type" "fpsqrts,fpsqrtd"))
344 "ss_fpmds*10, nothing*2")
346 (define_insn_reservation "ss_imul" 4
347 (and (eq_attr "cpu" "supersparc")
348 (eq_attr "type" "imul"))
351 ;; HyperSPARC/sparclite86x scheduling
353 (define_cpu_unit "hs_memory,hs_branch,hs_shift,hs_fpalu" "hypersparc_0")
354 (define_cpu_unit "hs_fpmds" "hypersparc_1")
356 (define_insn_reservation "hs_load" 1
357 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
358 (eq_attr "type" "load,sload,fpload"))
361 (define_insn_reservation "hs_store" 2
362 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
363 (eq_attr "type" "store,fpstore"))
364 "hs_memory, nothing")
366 (define_insn_reservation "hs_slbranch" 1
367 (and (eq_attr "cpu" "sparclite86x")
368 (eq_attr "type" "branch"))
371 (define_insn_reservation "hs_slshift" 1
372 (and (eq_attr "cpu" "sparclite86x")
373 (eq_attr "type" "shift"))
376 (define_insn_reservation "hs_fp_alu" 1
377 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
378 (eq_attr "type" "fp,fpmove,fpcmp"))
381 (define_insn_reservation "hs_fp_mult" 1
382 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
383 (eq_attr "type" "fpmul"))
386 (define_insn_reservation "hs_fp_divs" 8
387 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
388 (eq_attr "type" "fpdivs"))
389 "hs_fpmds*6, nothing*2")
391 (define_insn_reservation "hs_fp_divd" 12
392 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
393 (eq_attr "type" "fpdivd"))
394 "hs_fpmds*10, nothing*2")
396 (define_insn_reservation "hs_fp_sqrt" 17
397 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
398 (eq_attr "type" "fpsqrts,fpsqrtd"))
399 "hs_fpmds*15, nothing*2")
401 (define_insn_reservation "hs_imul" 17
402 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
403 (eq_attr "type" "imul"))
404 "hs_fpmds*15, nothing*2")
406 ;; Sparclet tsc701 scheduling
408 (define_cpu_unit "sl_load0,sl_load1,sl_load2,sl_load3" "sparclet")
409 (define_cpu_unit "sl_store,sl_imul" "sparclet")
411 (define_reservation "sl_load_any" "(sl_load0 | sl_load1 | sl_load2 | sl_load3)")
412 (define_reservation "sl_load_all" "(sl_load0 + sl_load1 + sl_load2 + sl_load3)")
414 (define_insn_reservation "sl_ld" 3
415 (and (eq_attr "cpu" "tsc701")
416 (eq_attr "type" "load,sload"))
417 "sl_load_any, sl_load_any, sl_load_any")
419 (define_insn_reservation "sl_st" 3
420 (and (eq_attr "cpu" "tsc701")
421 (eq_attr "type" "store"))
422 "(sl_store+sl_load_all)*3")
424 (define_insn_reservation "sl_imul" 5
425 (and (eq_attr "cpu" "tsc701")
426 (eq_attr "type" "imul"))
429 ;; UltraSPARC-I/II scheduling
431 (define_cpu_unit "us1_fdivider,us1_fpm" "ultrasparc_0");
432 (define_cpu_unit "us1_fpa,us1_load_writeback" "ultrasparc_1")
433 (define_cpu_unit "us1_fps_0,us1_fps_1,us1_fpd_0,us1_fpd_1" "ultrasparc_1")
434 (define_cpu_unit "us1_slot0,us1_slot1,us1_slot2,us1_slot3" "ultrasparc_1")
435 (define_cpu_unit "us1_ieu0,us1_ieu1,us1_cti,us1_lsu" "ultrasparc_1")
437 (define_reservation "us1_slot012" "(us1_slot0 | us1_slot1 | us1_slot2)")
438 (define_reservation "us1_slotany" "(us1_slot0 | us1_slot1 | us1_slot2 | us1_slot3)")
439 (define_reservation "us1_single_issue" "us1_slot0 + us1_slot1 + us1_slot2 + us1_slot3")
441 (define_reservation "us1_fp_single" "(us1_fps_0 | us1_fps_1)")
442 (define_reservation "us1_fp_double" "(us1_fpd_0 | us1_fpd_1)")
443 ;; This is a simplified representation of the issue at hand.
444 ;; For most cases, going from one FP precision type insn to another
445 ;; just breaks up the insn group. However for some cases, such
446 ;; a situation causes the second insn to stall 2 more cycles.
447 (exclusion_set "us1_fps_0,us1_fps_1" "us1_fpd_0,us1_fpd_1")
449 ;; If we have to schedule an ieu1 specific instruction and we want
450 ;; to reserve the ieu0 unit as well, we must reserve it first. So for
451 ;; example we could not schedule this sequence:
454 ;; but we could schedule them together like this:
457 ;; This basically requires that ieu0 is reserved before ieu1 when
458 ;; it is required that both be reserved.
459 (absence_set "us1_ieu0" "us1_ieu1")
461 ;; This defines the slotting order. Most IEU instructions can only
462 ;; execute in the first three slots, FPU and branches can go into
463 ;; any slot. We represent instructions which "break the group"
464 ;; as requiring reservation of us1_slot0.
465 (absence_set "us1_slot0" "us1_slot1,us1_slot2,us1_slot3")
466 (absence_set "us1_slot1" "us1_slot2,us1_slot3")
467 (absence_set "us1_slot2" "us1_slot3")
469 (define_insn_reservation "us1_simple_ieuN" 1
470 (and (eq_attr "cpu" "ultrasparc")
471 (eq_attr "type" "ialu"))
472 "(us1_ieu0 | us1_ieu1) + us1_slot012")
474 (define_insn_reservation "us1_simple_ieu0" 1
475 (and (eq_attr "cpu" "ultrasparc")
476 (eq_attr "type" "shift"))
477 "us1_ieu0 + us1_slot012")
479 (define_insn_reservation "us1_simple_ieu1" 1
480 (and (eq_attr "cpu" "ultrasparc")
481 (eq_attr "type" "compare"))
482 "us1_ieu1 + us1_slot012")
484 (define_insn_reservation "us1_cmove" 2
485 (and (eq_attr "cpu" "ultrasparc")
486 (eq_attr "type" "cmove"))
487 "us1_single_issue, nothing")
489 (define_insn_reservation "us1_imul" 1
490 (and (eq_attr "cpu" "ultrasparc")
491 (eq_attr "type" "imul"))
494 (define_insn_reservation "us1_idiv" 1
495 (and (eq_attr "cpu" "ultrasparc")
496 (eq_attr "type" "idiv"))
499 ;; For loads, the "delayed return mode" behavior of the chip
500 ;; is represented using the us1_load_writeback resource.
501 (define_insn_reservation "us1_load" 2
502 (and (eq_attr "cpu" "ultrasparc")
503 (eq_attr "type" "load,fpload"))
504 "us1_lsu + us1_slot012, us1_load_writeback")
506 (define_insn_reservation "us1_load_signed" 3
507 (and (eq_attr "cpu" "ultrasparc")
508 (eq_attr "type" "sload"))
509 "us1_lsu + us1_slot012, nothing, us1_load_writeback")
511 (define_insn_reservation "us1_store" 1
512 (and (eq_attr "cpu" "ultrasparc")
513 (eq_attr "type" "store,fpstore"))
514 "us1_lsu + us1_slot012")
516 (define_insn_reservation "us1_branch" 1
517 (and (eq_attr "cpu" "ultrasparc")
518 (eq_attr "type" "branch"))
519 "us1_cti + us1_slotany")
521 (define_insn_reservation "us1_call_jmpl" 1
522 (and (eq_attr "cpu" "ultrasparc")
523 (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch"))
524 "us1_cti + us1_ieu1 + us1_slot0")
526 (define_insn_reservation "us1_fmov_single" 1
527 (and (and (eq_attr "cpu" "ultrasparc")
528 (eq_attr "type" "fpmove"))
529 (eq_attr "fptype" "single"))
530 "us1_fpa + us1_fp_single + us1_slotany")
532 (define_insn_reservation "us1_fmov_double" 1
533 (and (and (eq_attr "cpu" "ultrasparc")
534 (eq_attr "type" "fpmove"))
535 (eq_attr "fptype" "double"))
536 "us1_fpa + us1_fp_double + us1_slotany")
538 (define_insn_reservation "us1_fcmov_single" 2
539 (and (and (eq_attr "cpu" "ultrasparc")
540 (eq_attr "type" "fpcmove,fpcrmove"))
541 (eq_attr "fptype" "single"))
542 "us1_fpa + us1_fp_single + us1_slotany, nothing")
544 (define_insn_reservation "us1_fcmov_double" 2
545 (and (and (eq_attr "cpu" "ultrasparc")
546 (eq_attr "type" "fpcmove,fpcrmove"))
547 (eq_attr "fptype" "double"))
548 "us1_fpa + us1_fp_double + us1_slotany, nothing")
550 (define_insn_reservation "us1_faddsub_single" 4
551 (and (and (eq_attr "cpu" "ultrasparc")
552 (eq_attr "type" "fp"))
553 (eq_attr "fptype" "single"))
554 "us1_fpa + us1_fp_single + us1_slotany, nothing*3")
556 (define_insn_reservation "us1_faddsub_double" 4
557 (and (and (eq_attr "cpu" "ultrasparc")
558 (eq_attr "type" "fp"))
559 (eq_attr "fptype" "double"))
560 "us1_fpa + us1_fp_double + us1_slotany, nothing*3")
562 (define_insn_reservation "us1_fpcmp_single" 1
563 (and (and (eq_attr "cpu" "ultrasparc")
564 (eq_attr "type" "fpcmp"))
565 (eq_attr "fptype" "single"))
566 "us1_fpa + us1_fp_single + us1_slotany")
568 (define_insn_reservation "us1_fpcmp_double" 1
569 (and (and (eq_attr "cpu" "ultrasparc")
570 (eq_attr "type" "fpcmp"))
571 (eq_attr "fptype" "double"))
572 "us1_fpa + us1_fp_double + us1_slotany")
574 (define_insn_reservation "us1_fmult_single" 4
575 (and (and (eq_attr "cpu" "ultrasparc")
576 (eq_attr "type" "fpmul"))
577 (eq_attr "fptype" "single"))
578 "us1_fpm + us1_fp_single + us1_slotany, nothing*3")
580 (define_insn_reservation "us1_fmult_double" 4
581 (and (and (eq_attr "cpu" "ultrasparc")
582 (eq_attr "type" "fpmul"))
583 (eq_attr "fptype" "double"))
584 "us1_fpm + us1_fp_double + us1_slotany, nothing*3")
586 ;; This is actually in theory dangerous, because it is possible
587 ;; for the chip to prematurely dispatch the dependant instruction
588 ;; in the G stage, resulting in a 9 cycle stall. However I have never
589 ;; been able to trigger this case myself even with hand written code,
590 ;; so it must require some rare complicated pipeline state.
592 "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double"
593 "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
595 ;; Floating point divide and square root use the multiplier unit
596 ;; for final rounding 3 cycles before the divide/sqrt is complete.
598 (define_insn_reservation "us1_fdivs"
600 (and (eq_attr "cpu" "ultrasparc")
601 (eq_attr "type" "fpdivs,fpsqrts"))
602 "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*8, (us1_fpm + us1_fdivider), us1_fdivider*2"
608 "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
610 (define_insn_reservation "us1_fdivd"
612 (and (eq_attr "cpu" "ultrasparc")
613 (eq_attr "type" "fpdivd,fpsqrtd"))
614 "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*18, (us1_fpm + us1_fdivider), us1_fdivider*2"
619 "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
621 ;; Any store may multi issue with the insn creating the source
622 ;; data as long as that creating insn is not an FPU div/sqrt.
623 ;; We need a special guard function because this bypass does
624 ;; not apply to the address inputs of the store.
625 (define_bypass 0 "us1_simple_ieuN,us1_simple_ieu1,us1_simple_ieu0,us1_faddsub_single,us1_faddsub_double,us1_fmov_single,us1_fmov_double,us1_fcmov_single,us1_fcmov_double,us1_fmult_single,us1_fmult_double" "us1_store"
626 "store_data_bypass_p")
628 ;; An integer branch may execute in the same cycle as the compare
629 ;; creating the condition codes.
630 (define_bypass 0 "us1_simple_ieu1" "us1_branch")
632 ;; UltraSPARC-III scheduling
634 ;; A much simpler beast, no silly slotting rules and both
635 ;; integer units are fully symmetric. It does still have
636 ;; single-issue instructions though.
638 (define_cpu_unit "us3_a0,us3_a1,us3_ms,us3_br,us3_fpm" "ultrasparc3_0")
639 (define_cpu_unit "us3_slot0,us3_slot1,us3_slot2,us3_slot3,us3_fpa" "ultrasparc3_1")
640 (define_cpu_unit "us3_load_writeback" "ultrasparc3_1")
642 (define_reservation "us3_slotany" "(us3_slot0 | us3_slot1 | us3_slot2 | us3_slot3)")
643 (define_reservation "us3_single_issue" "us3_slot0 + us3_slot1 + us3_slot2 + us3_slot3")
644 (define_reservation "us3_ax" "(us3_a0 | us3_a1)")
646 (define_insn_reservation "us3_integer" 1
647 (and (eq_attr "cpu" "ultrasparc3")
648 (eq_attr "type" "ialu,shift,compare"))
649 "us3_ax + us3_slotany")
651 (define_insn_reservation "us3_cmove" 2
652 (and (eq_attr "cpu" "ultrasparc3")
653 (eq_attr "type" "cmove"))
654 "us3_ms + us3_br + us3_slotany, nothing")
656 ;; ??? Not entirely accurate.
657 ;; ??? It can run from 6 to 9 cycles. The first cycle the MS pipe
658 ;; ??? is needed, and the instruction group is broken right after
659 ;; ??? the imul. Then 'helper' instructions are generated to perform
660 ;; ??? each further stage of the multiplication, each such 'helper' is
661 ;; ??? single group. So, the reservation aspect is represented accurately
662 ;; ??? here, but the variable cycles are not.
663 ;; ??? Currently I have no idea how to determine the variability, but once
664 ;; ??? known we can simply add a define_bypass or similar to model it.
665 (define_insn_reservation "us3_imul" 6
666 (and (eq_attr "cpu" "ultrasparc3")
667 (eq_attr "type" "imul"))
668 "us3_ms + us3_slotany, us3_single_issue*5")
670 (define_insn_reservation "us3_idiv" 71
671 (and (eq_attr "cpu" "ultrasparc3")
672 (eq_attr "type" "idiv"))
673 "us3_ms + us3_slotany, us3_single_issue*70")
675 ;; UltraSPARC-III has a similar load delay as UltraSPARC-I/II except
676 ;; that all loads except 32-bit/64-bit unsigned loads take the extra
677 ;; delay for sign/zero extension.
678 (define_insn_reservation "us3_2cycle_load" 2
679 (and (eq_attr "cpu" "ultrasparc3")
680 (and (eq_attr "type" "load,fpload")
681 (eq_attr "us3load_type" "2cycle")))
682 "us3_ms + us3_slotany, us3_load_writeback")
684 (define_insn_reservation "us3_load_delayed" 3
685 (and (eq_attr "cpu" "ultrasparc3")
686 (and (eq_attr "type" "load,sload")
687 (eq_attr "us3load_type" "3cycle")))
688 "us3_ms + us3_slotany, nothing, us3_load_writeback")
690 (define_insn_reservation "us3_store" 1
691 (and (eq_attr "cpu" "ultrasparc3")
692 (eq_attr "type" "store,fpstore"))
693 "us3_ms + us3_slotany")
695 (define_insn_reservation "us3_branch" 1
696 (and (eq_attr "cpu" "ultrasparc3")
697 (eq_attr "type" "branch"))
698 "us3_br + us3_slotany")
700 (define_insn_reservation "us3_call_jmpl" 1
701 (and (eq_attr "cpu" "ultrasparc3")
702 (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch"))
703 "us3_br + us3_ms + us3_slotany")
705 (define_insn_reservation "us3_fmov" 3
706 (and (eq_attr "cpu" "ultrasparc3")
707 (eq_attr "type" "fpmove"))
708 "us3_fpa + us3_slotany, nothing*2")
710 (define_insn_reservation "us3_fcmov" 3
711 (and (eq_attr "cpu" "ultrasparc3")
712 (eq_attr "type" "fpcmove"))
713 "us3_fpa + us3_br + us3_slotany, nothing*2")
715 (define_insn_reservation "us3_fcrmov" 3
716 (and (eq_attr "cpu" "ultrasparc3")
717 (eq_attr "type" "fpcrmove"))
718 "us3_fpa + us3_ms + us3_slotany, nothing*2")
720 (define_insn_reservation "us3_faddsub" 4
721 (and (eq_attr "cpu" "ultrasparc3")
722 (eq_attr "type" "fp"))
723 "us3_fpa + us3_slotany, nothing*3")
725 (define_insn_reservation "us3_fpcmp" 5
726 (and (eq_attr "cpu" "ultrasparc3")
727 (eq_attr "type" "fpcmp"))
728 "us3_fpa + us3_slotany, nothing*4")
730 (define_insn_reservation "us3_fmult" 4
731 (and (eq_attr "cpu" "ultrasparc3")
732 (eq_attr "type" "fpmul"))
733 "us3_fpm + us3_slotany, nothing*3")
735 (define_insn_reservation "us3_fdivs" 17
736 (and (eq_attr "cpu" "ultrasparc3")
737 (eq_attr "type" "fpdivs"))
738 "(us3_fpm + us3_slotany), us3_fpm*14, nothing*2")
740 (define_insn_reservation "us3_fsqrts" 20
741 (and (eq_attr "cpu" "ultrasparc3")
742 (eq_attr "type" "fpsqrts"))
743 "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2")
745 (define_insn_reservation "us3_fdivd" 20
746 (and (eq_attr "cpu" "ultrasparc3")
747 (eq_attr "type" "fpdivd"))
748 "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2")
750 (define_insn_reservation "us3_fsqrtd" 29
751 (and (eq_attr "cpu" "ultrasparc3")
752 (eq_attr "type" "fpsqrtd"))
753 "(us3_fpm + us3_slotany), us3_fpm*26, nothing*2")
755 ;; Any store may multi issue with the insn creating the source
756 ;; data as long as that creating insn is not an FPU div/sqrt.
757 ;; We need a special guard function because this bypass does
758 ;; not apply to the address inputs of the store.
759 (define_bypass 0 "us3_integer,us3_faddsub,us3_fmov,us3_fcmov,us3_fmult" "us3_store"
760 "store_data_bypass_p")
762 ;; An integer branch may execute in the same cycle as the compare
763 ;; creating the condition codes.
764 (define_bypass 0 "us3_integer" "us3_branch")
766 ;; If FMOVfcc is user of FPCMP, latency is only 1 cycle.
767 (define_bypass 1 "us3_fpcmp" "us3_fcmov")
770 ;; Compare instructions.
771 ;; This controls RTL generation and register allocation.
773 ;; We generate RTL for comparisons and branches by having the cmpxx
774 ;; patterns store away the operands. Then, the scc and bcc patterns
775 ;; emit RTL for both the compare and the branch.
777 ;; We do this because we want to generate different code for an sne and
778 ;; seq insn. In those cases, if the second operand of the compare is not
779 ;; const0_rtx, we want to compute the xor of the two operands and test
782 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
783 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
784 ;; insns that actually require more than one machine instruction.
786 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
788 (define_expand "cmpsi"
790 (compare:CC (match_operand:SI 0 "register_operand" "")
791 (match_operand:SI 1 "arith_operand" "")))]
795 sparc_compare_op0 = operands[0];
796 sparc_compare_op1 = operands[1];
800 (define_expand "cmpdi"
802 (compare:CCX (match_operand:DI 0 "register_operand" "")
803 (match_operand:DI 1 "arith_double_operand" "")))]
807 sparc_compare_op0 = operands[0];
808 sparc_compare_op1 = operands[1];
812 (define_expand "cmpsf"
813 ;; The 96 here isn't ever used by anyone.
815 (compare:CCFP (match_operand:SF 0 "register_operand" "")
816 (match_operand:SF 1 "register_operand" "")))]
820 sparc_compare_op0 = operands[0];
821 sparc_compare_op1 = operands[1];
825 (define_expand "cmpdf"
826 ;; The 96 here isn't ever used by anyone.
828 (compare:CCFP (match_operand:DF 0 "register_operand" "")
829 (match_operand:DF 1 "register_operand" "")))]
833 sparc_compare_op0 = operands[0];
834 sparc_compare_op1 = operands[1];
838 (define_expand "cmptf"
839 ;; The 96 here isn't ever used by anyone.
841 (compare:CCFP (match_operand:TF 0 "register_operand" "")
842 (match_operand:TF 1 "register_operand" "")))]
846 sparc_compare_op0 = operands[0];
847 sparc_compare_op1 = operands[1];
851 ;; Now the compare DEFINE_INSNs.
853 (define_insn "*cmpsi_insn"
855 (compare:CC (match_operand:SI 0 "register_operand" "r")
856 (match_operand:SI 1 "arith_operand" "rI")))]
859 [(set_attr "type" "compare")])
861 (define_insn "*cmpdi_sp64"
863 (compare:CCX (match_operand:DI 0 "register_operand" "r")
864 (match_operand:DI 1 "arith_double_operand" "rHI")))]
867 [(set_attr "type" "compare")])
869 (define_insn "*cmpsf_fpe"
870 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
871 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
872 (match_operand:SF 2 "register_operand" "f")))]
877 return \"fcmpes\\t%0, %1, %2\";
878 return \"fcmpes\\t%1, %2\";
880 [(set_attr "type" "fpcmp")])
882 (define_insn "*cmpdf_fpe"
883 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
884 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
885 (match_operand:DF 2 "register_operand" "e")))]
890 return \"fcmped\\t%0, %1, %2\";
891 return \"fcmped\\t%1, %2\";
893 [(set_attr "type" "fpcmp")
894 (set_attr "fptype" "double")])
896 (define_insn "*cmptf_fpe"
897 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
898 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
899 (match_operand:TF 2 "register_operand" "e")))]
900 "TARGET_FPU && TARGET_HARD_QUAD"
904 return \"fcmpeq\\t%0, %1, %2\";
905 return \"fcmpeq\\t%1, %2\";
907 [(set_attr "type" "fpcmp")])
909 (define_insn "*cmpsf_fp"
910 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
911 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
912 (match_operand:SF 2 "register_operand" "f")))]
917 return \"fcmps\\t%0, %1, %2\";
918 return \"fcmps\\t%1, %2\";
920 [(set_attr "type" "fpcmp")])
922 (define_insn "*cmpdf_fp"
923 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
924 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
925 (match_operand:DF 2 "register_operand" "e")))]
930 return \"fcmpd\\t%0, %1, %2\";
931 return \"fcmpd\\t%1, %2\";
933 [(set_attr "type" "fpcmp")
934 (set_attr "fptype" "double")])
936 (define_insn "*cmptf_fp"
937 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
938 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
939 (match_operand:TF 2 "register_operand" "e")))]
940 "TARGET_FPU && TARGET_HARD_QUAD"
944 return \"fcmpq\\t%0, %1, %2\";
945 return \"fcmpq\\t%1, %2\";
947 [(set_attr "type" "fpcmp")])
949 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
950 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
951 ;; the same code as v8 (the addx/subx method has more applications). The
952 ;; exception to this is "reg != 0" which can be done in one instruction on v9
953 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
956 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
957 ;; generate addcc/subcc instructions.
959 (define_expand "seqsi_special"
961 (xor:SI (match_operand:SI 1 "register_operand" "")
962 (match_operand:SI 2 "register_operand" "")))
963 (parallel [(set (match_operand:SI 0 "register_operand" "")
964 (eq:SI (match_dup 3) (const_int 0)))
965 (clobber (reg:CC 100))])]
967 "{ operands[3] = gen_reg_rtx (SImode); }")
969 (define_expand "seqdi_special"
971 (xor:DI (match_operand:DI 1 "register_operand" "")
972 (match_operand:DI 2 "register_operand" "")))
973 (set (match_operand:DI 0 "register_operand" "")
974 (eq:DI (match_dup 3) (const_int 0)))]
976 "{ operands[3] = gen_reg_rtx (DImode); }")
978 (define_expand "snesi_special"
980 (xor:SI (match_operand:SI 1 "register_operand" "")
981 (match_operand:SI 2 "register_operand" "")))
982 (parallel [(set (match_operand:SI 0 "register_operand" "")
983 (ne:SI (match_dup 3) (const_int 0)))
984 (clobber (reg:CC 100))])]
986 "{ operands[3] = gen_reg_rtx (SImode); }")
988 (define_expand "snedi_special"
990 (xor:DI (match_operand:DI 1 "register_operand" "")
991 (match_operand:DI 2 "register_operand" "")))
992 (set (match_operand:DI 0 "register_operand" "")
993 (ne:DI (match_dup 3) (const_int 0)))]
995 "{ operands[3] = gen_reg_rtx (DImode); }")
997 (define_expand "seqdi_special_trunc"
999 (xor:DI (match_operand:DI 1 "register_operand" "")
1000 (match_operand:DI 2 "register_operand" "")))
1001 (set (match_operand:SI 0 "register_operand" "")
1002 (eq:SI (match_dup 3) (const_int 0)))]
1004 "{ operands[3] = gen_reg_rtx (DImode); }")
1006 (define_expand "snedi_special_trunc"
1008 (xor:DI (match_operand:DI 1 "register_operand" "")
1009 (match_operand:DI 2 "register_operand" "")))
1010 (set (match_operand:SI 0 "register_operand" "")
1011 (ne:SI (match_dup 3) (const_int 0)))]
1013 "{ operands[3] = gen_reg_rtx (DImode); }")
1015 (define_expand "seqsi_special_extend"
1017 (xor:SI (match_operand:SI 1 "register_operand" "")
1018 (match_operand:SI 2 "register_operand" "")))
1019 (parallel [(set (match_operand:DI 0 "register_operand" "")
1020 (eq:DI (match_dup 3) (const_int 0)))
1021 (clobber (reg:CC 100))])]
1023 "{ operands[3] = gen_reg_rtx (SImode); }")
1025 (define_expand "snesi_special_extend"
1027 (xor:SI (match_operand:SI 1 "register_operand" "")
1028 (match_operand:SI 2 "register_operand" "")))
1029 (parallel [(set (match_operand:DI 0 "register_operand" "")
1030 (ne:DI (match_dup 3) (const_int 0)))
1031 (clobber (reg:CC 100))])]
1033 "{ operands[3] = gen_reg_rtx (SImode); }")
1035 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
1036 ;; However, the code handles both SImode and DImode.
1037 (define_expand "seq"
1038 [(set (match_operand:SI 0 "intreg_operand" "")
1039 (eq:SI (match_dup 1) (const_int 0)))]
1043 if (GET_MODE (sparc_compare_op0) == SImode)
1047 if (GET_MODE (operands[0]) == SImode)
1048 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
1050 else if (! TARGET_ARCH64)
1053 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
1058 else if (GET_MODE (sparc_compare_op0) == DImode)
1062 if (! TARGET_ARCH64)
1064 else if (GET_MODE (operands[0]) == SImode)
1065 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
1068 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
1073 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1075 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1076 emit_jump_insn (gen_sne (operands[0]));
1081 if (gen_v9_scc (EQ, operands))
1088 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
1089 ;; However, the code handles both SImode and DImode.
1090 (define_expand "sne"
1091 [(set (match_operand:SI 0 "intreg_operand" "")
1092 (ne:SI (match_dup 1) (const_int 0)))]
1096 if (GET_MODE (sparc_compare_op0) == SImode)
1100 if (GET_MODE (operands[0]) == SImode)
1101 pat = gen_snesi_special (operands[0], sparc_compare_op0,
1103 else if (! TARGET_ARCH64)
1106 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
1111 else if (GET_MODE (sparc_compare_op0) == DImode)
1115 if (! TARGET_ARCH64)
1117 else if (GET_MODE (operands[0]) == SImode)
1118 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
1121 pat = gen_snedi_special (operands[0], sparc_compare_op0,
1126 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1128 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1129 emit_jump_insn (gen_sne (operands[0]));
1134 if (gen_v9_scc (NE, operands))
1141 (define_expand "sgt"
1142 [(set (match_operand:SI 0 "intreg_operand" "")
1143 (gt:SI (match_dup 1) (const_int 0)))]
1147 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1149 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1150 emit_jump_insn (gen_sne (operands[0]));
1155 if (gen_v9_scc (GT, operands))
1162 (define_expand "slt"
1163 [(set (match_operand:SI 0 "intreg_operand" "")
1164 (lt:SI (match_dup 1) (const_int 0)))]
1168 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1170 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1171 emit_jump_insn (gen_sne (operands[0]));
1176 if (gen_v9_scc (LT, operands))
1183 (define_expand "sge"
1184 [(set (match_operand:SI 0 "intreg_operand" "")
1185 (ge:SI (match_dup 1) (const_int 0)))]
1189 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1191 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1192 emit_jump_insn (gen_sne (operands[0]));
1197 if (gen_v9_scc (GE, operands))
1204 (define_expand "sle"
1205 [(set (match_operand:SI 0 "intreg_operand" "")
1206 (le:SI (match_dup 1) (const_int 0)))]
1210 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1212 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1213 emit_jump_insn (gen_sne (operands[0]));
1218 if (gen_v9_scc (LE, operands))
1225 (define_expand "sgtu"
1226 [(set (match_operand:SI 0 "intreg_operand" "")
1227 (gtu:SI (match_dup 1) (const_int 0)))]
1235 /* We can do ltu easily, so if both operands are registers, swap them and
1237 if ((GET_CODE (sparc_compare_op0) == REG
1238 || GET_CODE (sparc_compare_op0) == SUBREG)
1239 && (GET_CODE (sparc_compare_op1) == REG
1240 || GET_CODE (sparc_compare_op1) == SUBREG))
1242 tem = sparc_compare_op0;
1243 sparc_compare_op0 = sparc_compare_op1;
1244 sparc_compare_op1 = tem;
1245 pat = gen_sltu (operands[0]);
1246 if (pat == NULL_RTX)
1254 if (gen_v9_scc (GTU, operands))
1260 (define_expand "sltu"
1261 [(set (match_operand:SI 0 "intreg_operand" "")
1262 (ltu:SI (match_dup 1) (const_int 0)))]
1268 if (gen_v9_scc (LTU, operands))
1271 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1274 (define_expand "sgeu"
1275 [(set (match_operand:SI 0 "intreg_operand" "")
1276 (geu:SI (match_dup 1) (const_int 0)))]
1282 if (gen_v9_scc (GEU, operands))
1285 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1288 (define_expand "sleu"
1289 [(set (match_operand:SI 0 "intreg_operand" "")
1290 (leu:SI (match_dup 1) (const_int 0)))]
1298 /* We can do geu easily, so if both operands are registers, swap them and
1300 if ((GET_CODE (sparc_compare_op0) == REG
1301 || GET_CODE (sparc_compare_op0) == SUBREG)
1302 && (GET_CODE (sparc_compare_op1) == REG
1303 || GET_CODE (sparc_compare_op1) == SUBREG))
1305 tem = sparc_compare_op0;
1306 sparc_compare_op0 = sparc_compare_op1;
1307 sparc_compare_op1 = tem;
1308 pat = gen_sgeu (operands[0]);
1309 if (pat == NULL_RTX)
1317 if (gen_v9_scc (LEU, operands))
1323 ;; Now the DEFINE_INSNs for the scc cases.
1325 ;; The SEQ and SNE patterns are special because they can be done
1326 ;; without any branching and do not involve a COMPARE. We want
1327 ;; them to always use the splitz below so the results can be
1330 (define_insn "*snesi_zero"
1331 [(set (match_operand:SI 0 "register_operand" "=r")
1332 (ne:SI (match_operand:SI 1 "register_operand" "r")
1334 (clobber (reg:CC 100))]
1337 [(set_attr "length" "2")])
1340 [(set (match_operand:SI 0 "register_operand" "")
1341 (ne:SI (match_operand:SI 1 "register_operand" "")
1343 (clobber (reg:CC 100))]
1345 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1347 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1350 (define_insn "*neg_snesi_zero"
1351 [(set (match_operand:SI 0 "register_operand" "=r")
1352 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1354 (clobber (reg:CC 100))]
1357 [(set_attr "length" "2")])
1360 [(set (match_operand:SI 0 "register_operand" "")
1361 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1363 (clobber (reg:CC 100))]
1365 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1367 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1370 (define_insn "*snesi_zero_extend"
1371 [(set (match_operand:DI 0 "register_operand" "=r")
1372 (ne:DI (match_operand:SI 1 "register_operand" "r")
1374 (clobber (reg:CC 100))]
1377 [(set_attr "length" "2")])
1380 [(set (match_operand:DI 0 "register_operand" "")
1381 (ne:DI (match_operand:SI 1 "register_operand" "")
1383 (clobber (reg:CC 100))]
1385 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1387 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1389 (ltu:SI (reg:CC_NOOV 100)
1393 (define_insn "*snedi_zero"
1394 [(set (match_operand:DI 0 "register_operand" "=&r")
1395 (ne:DI (match_operand:DI 1 "register_operand" "r")
1399 [(set_attr "length" "2")])
1402 [(set (match_operand:DI 0 "register_operand" "")
1403 (ne:DI (match_operand:DI 1 "register_operand" "")
1406 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1407 [(set (match_dup 0) (const_int 0))
1408 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1414 (define_insn "*neg_snedi_zero"
1415 [(set (match_operand:DI 0 "register_operand" "=&r")
1416 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1420 [(set_attr "length" "2")])
1423 [(set (match_operand:DI 0 "register_operand" "")
1424 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1427 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1428 [(set (match_dup 0) (const_int 0))
1429 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1435 (define_insn "*snedi_zero_trunc"
1436 [(set (match_operand:SI 0 "register_operand" "=&r")
1437 (ne:SI (match_operand:DI 1 "register_operand" "r")
1441 [(set_attr "length" "2")])
1444 [(set (match_operand:SI 0 "register_operand" "")
1445 (ne:SI (match_operand:DI 1 "register_operand" "")
1448 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1449 [(set (match_dup 0) (const_int 0))
1450 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1456 (define_insn "*seqsi_zero"
1457 [(set (match_operand:SI 0 "register_operand" "=r")
1458 (eq:SI (match_operand:SI 1 "register_operand" "r")
1460 (clobber (reg:CC 100))]
1463 [(set_attr "length" "2")])
1466 [(set (match_operand:SI 0 "register_operand" "")
1467 (eq:SI (match_operand:SI 1 "register_operand" "")
1469 (clobber (reg:CC 100))]
1471 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1473 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1476 (define_insn "*neg_seqsi_zero"
1477 [(set (match_operand:SI 0 "register_operand" "=r")
1478 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1480 (clobber (reg:CC 100))]
1483 [(set_attr "length" "2")])
1486 [(set (match_operand:SI 0 "register_operand" "")
1487 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1489 (clobber (reg:CC 100))]
1491 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1493 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1496 (define_insn "*seqsi_zero_extend"
1497 [(set (match_operand:DI 0 "register_operand" "=r")
1498 (eq:DI (match_operand:SI 1 "register_operand" "r")
1500 (clobber (reg:CC 100))]
1503 [(set_attr "length" "2")])
1506 [(set (match_operand:DI 0 "register_operand" "")
1507 (eq:DI (match_operand:SI 1 "register_operand" "")
1509 (clobber (reg:CC 100))]
1511 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1513 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1515 (ltu:SI (reg:CC_NOOV 100)
1519 (define_insn "*seqdi_zero"
1520 [(set (match_operand:DI 0 "register_operand" "=&r")
1521 (eq:DI (match_operand:DI 1 "register_operand" "r")
1525 [(set_attr "length" "2")])
1528 [(set (match_operand:DI 0 "register_operand" "")
1529 (eq:DI (match_operand:DI 1 "register_operand" "")
1532 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1533 [(set (match_dup 0) (const_int 0))
1534 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1540 (define_insn "*neg_seqdi_zero"
1541 [(set (match_operand:DI 0 "register_operand" "=&r")
1542 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1546 [(set_attr "length" "2")])
1549 [(set (match_operand:DI 0 "register_operand" "")
1550 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1553 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1554 [(set (match_dup 0) (const_int 0))
1555 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1561 (define_insn "*seqdi_zero_trunc"
1562 [(set (match_operand:SI 0 "register_operand" "=&r")
1563 (eq:SI (match_operand:DI 1 "register_operand" "r")
1567 [(set_attr "length" "2")])
1570 [(set (match_operand:SI 0 "register_operand" "")
1571 (eq:SI (match_operand:DI 1 "register_operand" "")
1574 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1575 [(set (match_dup 0) (const_int 0))
1576 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1582 ;; We can also do (x + (i == 0)) and related, so put them in.
1583 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1586 (define_insn "*x_plus_i_ne_0"
1587 [(set (match_operand:SI 0 "register_operand" "=r")
1588 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1590 (match_operand:SI 2 "register_operand" "r")))
1591 (clobber (reg:CC 100))]
1594 [(set_attr "length" "2")])
1597 [(set (match_operand:SI 0 "register_operand" "")
1598 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1600 (match_operand:SI 2 "register_operand" "")))
1601 (clobber (reg:CC 100))]
1603 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1605 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1609 (define_insn "*x_minus_i_ne_0"
1610 [(set (match_operand:SI 0 "register_operand" "=r")
1611 (minus:SI (match_operand:SI 2 "register_operand" "r")
1612 (ne:SI (match_operand:SI 1 "register_operand" "r")
1614 (clobber (reg:CC 100))]
1617 [(set_attr "length" "2")])
1620 [(set (match_operand:SI 0 "register_operand" "")
1621 (minus:SI (match_operand:SI 2 "register_operand" "")
1622 (ne:SI (match_operand:SI 1 "register_operand" "")
1624 (clobber (reg:CC 100))]
1626 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1628 (set (match_dup 0) (minus:SI (match_dup 2)
1629 (ltu:SI (reg:CC 100) (const_int 0))))]
1632 (define_insn "*x_plus_i_eq_0"
1633 [(set (match_operand:SI 0 "register_operand" "=r")
1634 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1636 (match_operand:SI 2 "register_operand" "r")))
1637 (clobber (reg:CC 100))]
1640 [(set_attr "length" "2")])
1643 [(set (match_operand:SI 0 "register_operand" "")
1644 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1646 (match_operand:SI 2 "register_operand" "")))
1647 (clobber (reg:CC 100))]
1649 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1651 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1655 (define_insn "*x_minus_i_eq_0"
1656 [(set (match_operand:SI 0 "register_operand" "=r")
1657 (minus:SI (match_operand:SI 2 "register_operand" "r")
1658 (eq:SI (match_operand:SI 1 "register_operand" "r")
1660 (clobber (reg:CC 100))]
1663 [(set_attr "length" "2")])
1666 [(set (match_operand:SI 0 "register_operand" "")
1667 (minus:SI (match_operand:SI 2 "register_operand" "")
1668 (eq:SI (match_operand:SI 1 "register_operand" "")
1670 (clobber (reg:CC 100))]
1672 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1674 (set (match_dup 0) (minus:SI (match_dup 2)
1675 (geu:SI (reg:CC 100) (const_int 0))))]
1678 ;; We can also do GEU and LTU directly, but these operate after a compare.
1679 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1682 (define_insn "*sltu_insn"
1683 [(set (match_operand:SI 0 "register_operand" "=r")
1684 (ltu:SI (reg:CC 100) (const_int 0)))]
1686 "addx\\t%%g0, 0, %0"
1687 [(set_attr "type" "misc")])
1689 (define_insn "*neg_sltu_insn"
1690 [(set (match_operand:SI 0 "register_operand" "=r")
1691 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1693 "subx\\t%%g0, 0, %0"
1694 [(set_attr "type" "misc")])
1696 ;; ??? Combine should canonicalize these next two to the same pattern.
1697 (define_insn "*neg_sltu_minus_x"
1698 [(set (match_operand:SI 0 "register_operand" "=r")
1699 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1700 (match_operand:SI 1 "arith_operand" "rI")))]
1702 "subx\\t%%g0, %1, %0"
1703 [(set_attr "type" "misc")])
1705 (define_insn "*neg_sltu_plus_x"
1706 [(set (match_operand:SI 0 "register_operand" "=r")
1707 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1708 (match_operand:SI 1 "arith_operand" "rI"))))]
1710 "subx\\t%%g0, %1, %0"
1711 [(set_attr "type" "misc")])
1713 (define_insn "*sgeu_insn"
1714 [(set (match_operand:SI 0 "register_operand" "=r")
1715 (geu:SI (reg:CC 100) (const_int 0)))]
1717 "subx\\t%%g0, -1, %0"
1718 [(set_attr "type" "misc")])
1720 (define_insn "*neg_sgeu_insn"
1721 [(set (match_operand:SI 0 "register_operand" "=r")
1722 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1724 "addx\\t%%g0, -1, %0"
1725 [(set_attr "type" "misc")])
1727 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1728 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1731 (define_insn "*sltu_plus_x"
1732 [(set (match_operand:SI 0 "register_operand" "=r")
1733 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1734 (match_operand:SI 1 "arith_operand" "rI")))]
1736 "addx\\t%%g0, %1, %0"
1737 [(set_attr "type" "misc")])
1739 (define_insn "*sltu_plus_x_plus_y"
1740 [(set (match_operand:SI 0 "register_operand" "=r")
1741 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1742 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1743 (match_operand:SI 2 "arith_operand" "rI"))))]
1746 [(set_attr "type" "misc")])
1748 (define_insn "*x_minus_sltu"
1749 [(set (match_operand:SI 0 "register_operand" "=r")
1750 (minus:SI (match_operand:SI 1 "register_operand" "r")
1751 (ltu:SI (reg:CC 100) (const_int 0))))]
1754 [(set_attr "type" "misc")])
1756 ;; ??? Combine should canonicalize these next two to the same pattern.
1757 (define_insn "*x_minus_y_minus_sltu"
1758 [(set (match_operand:SI 0 "register_operand" "=r")
1759 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1760 (match_operand:SI 2 "arith_operand" "rI"))
1761 (ltu:SI (reg:CC 100) (const_int 0))))]
1763 "subx\\t%r1, %2, %0"
1764 [(set_attr "type" "misc")])
1766 (define_insn "*x_minus_sltu_plus_y"
1767 [(set (match_operand:SI 0 "register_operand" "=r")
1768 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1769 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1770 (match_operand:SI 2 "arith_operand" "rI"))))]
1772 "subx\\t%r1, %2, %0"
1773 [(set_attr "type" "misc")])
1775 (define_insn "*sgeu_plus_x"
1776 [(set (match_operand:SI 0 "register_operand" "=r")
1777 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1778 (match_operand:SI 1 "register_operand" "r")))]
1781 [(set_attr "type" "misc")])
1783 (define_insn "*x_minus_sgeu"
1784 [(set (match_operand:SI 0 "register_operand" "=r")
1785 (minus:SI (match_operand:SI 1 "register_operand" "r")
1786 (geu:SI (reg:CC 100) (const_int 0))))]
1789 [(set_attr "type" "misc")])
1792 [(set (match_operand:SI 0 "register_operand" "")
1793 (match_operator:SI 2 "noov_compare_op"
1794 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1796 ;; 32 bit LTU/GEU are better implemented using addx/subx
1797 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1798 && (GET_MODE (operands[1]) == CCXmode
1799 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1800 [(set (match_dup 0) (const_int 0))
1802 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1808 ;; These control RTL generation for conditional jump insns
1810 ;; The quad-word fp compare library routines all return nonzero to indicate
1811 ;; true, which is different from the equivalent libgcc routines, so we must
1812 ;; handle them specially here.
1814 (define_expand "beq"
1816 (if_then_else (eq (match_dup 1) (const_int 0))
1817 (label_ref (match_operand 0 "" ""))
1822 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1823 && GET_CODE (sparc_compare_op0) == REG
1824 && GET_MODE (sparc_compare_op0) == DImode)
1826 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1829 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1831 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1832 emit_jump_insn (gen_bne (operands[0]));
1835 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1838 (define_expand "bne"
1840 (if_then_else (ne (match_dup 1) (const_int 0))
1841 (label_ref (match_operand 0 "" ""))
1846 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1847 && GET_CODE (sparc_compare_op0) == REG
1848 && GET_MODE (sparc_compare_op0) == DImode)
1850 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1853 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1855 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1856 emit_jump_insn (gen_bne (operands[0]));
1859 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1862 (define_expand "bgt"
1864 (if_then_else (gt (match_dup 1) (const_int 0))
1865 (label_ref (match_operand 0 "" ""))
1870 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1871 && GET_CODE (sparc_compare_op0) == REG
1872 && GET_MODE (sparc_compare_op0) == DImode)
1874 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1877 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1879 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1880 emit_jump_insn (gen_bne (operands[0]));
1883 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1886 (define_expand "bgtu"
1888 (if_then_else (gtu (match_dup 1) (const_int 0))
1889 (label_ref (match_operand 0 "" ""))
1893 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1896 (define_expand "blt"
1898 (if_then_else (lt (match_dup 1) (const_int 0))
1899 (label_ref (match_operand 0 "" ""))
1904 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1905 && GET_CODE (sparc_compare_op0) == REG
1906 && GET_MODE (sparc_compare_op0) == DImode)
1908 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1911 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1913 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1914 emit_jump_insn (gen_bne (operands[0]));
1917 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1920 (define_expand "bltu"
1922 (if_then_else (ltu (match_dup 1) (const_int 0))
1923 (label_ref (match_operand 0 "" ""))
1927 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1930 (define_expand "bge"
1932 (if_then_else (ge (match_dup 1) (const_int 0))
1933 (label_ref (match_operand 0 "" ""))
1938 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1939 && GET_CODE (sparc_compare_op0) == REG
1940 && GET_MODE (sparc_compare_op0) == DImode)
1942 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1945 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1947 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1948 emit_jump_insn (gen_bne (operands[0]));
1951 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1954 (define_expand "bgeu"
1956 (if_then_else (geu (match_dup 1) (const_int 0))
1957 (label_ref (match_operand 0 "" ""))
1961 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1964 (define_expand "ble"
1966 (if_then_else (le (match_dup 1) (const_int 0))
1967 (label_ref (match_operand 0 "" ""))
1972 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1973 && GET_CODE (sparc_compare_op0) == REG
1974 && GET_MODE (sparc_compare_op0) == DImode)
1976 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1979 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1981 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1982 emit_jump_insn (gen_bne (operands[0]));
1985 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1988 (define_expand "bleu"
1990 (if_then_else (leu (match_dup 1) (const_int 0))
1991 (label_ref (match_operand 0 "" ""))
1995 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1998 (define_expand "bunordered"
2000 (if_then_else (unordered (match_dup 1) (const_int 0))
2001 (label_ref (match_operand 0 "" ""))
2006 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2008 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
2010 emit_jump_insn (gen_beq (operands[0]));
2013 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
2017 (define_expand "bordered"
2019 (if_then_else (ordered (match_dup 1) (const_int 0))
2020 (label_ref (match_operand 0 "" ""))
2025 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2027 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
2028 emit_jump_insn (gen_bne (operands[0]));
2031 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
2035 (define_expand "bungt"
2037 (if_then_else (ungt (match_dup 1) (const_int 0))
2038 (label_ref (match_operand 0 "" ""))
2043 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2045 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
2046 emit_jump_insn (gen_bgt (operands[0]));
2049 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
2052 (define_expand "bunlt"
2054 (if_then_else (unlt (match_dup 1) (const_int 0))
2055 (label_ref (match_operand 0 "" ""))
2060 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2062 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
2063 emit_jump_insn (gen_bne (operands[0]));
2066 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
2069 (define_expand "buneq"
2071 (if_then_else (uneq (match_dup 1) (const_int 0))
2072 (label_ref (match_operand 0 "" ""))
2077 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2079 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
2080 emit_jump_insn (gen_beq (operands[0]));
2083 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
2086 (define_expand "bunge"
2088 (if_then_else (unge (match_dup 1) (const_int 0))
2089 (label_ref (match_operand 0 "" ""))
2094 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2096 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
2097 emit_jump_insn (gen_bne (operands[0]));
2100 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
2103 (define_expand "bunle"
2105 (if_then_else (unle (match_dup 1) (const_int 0))
2106 (label_ref (match_operand 0 "" ""))
2111 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2113 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
2114 emit_jump_insn (gen_bne (operands[0]));
2117 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
2120 (define_expand "bltgt"
2122 (if_then_else (ltgt (match_dup 1) (const_int 0))
2123 (label_ref (match_operand 0 "" ""))
2128 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2130 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
2131 emit_jump_insn (gen_bne (operands[0]));
2134 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
2137 ;; Now match both normal and inverted jump.
2139 ;; XXX fpcmp nop braindamage
2140 (define_insn "*normal_branch"
2142 (if_then_else (match_operator 0 "noov_compare_op"
2143 [(reg 100) (const_int 0)])
2144 (label_ref (match_operand 1 "" ""))
2149 return output_cbranch (operands[0], operands[1], 1, 0,
2150 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2151 ! final_sequence, insn);
2153 [(set_attr "type" "branch")
2154 (set_attr "branch_type" "icc")])
2156 ;; XXX fpcmp nop braindamage
2157 (define_insn "*inverted_branch"
2159 (if_then_else (match_operator 0 "noov_compare_op"
2160 [(reg 100) (const_int 0)])
2162 (label_ref (match_operand 1 "" ""))))]
2166 return output_cbranch (operands[0], operands[1], 1, 1,
2167 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2168 ! final_sequence, insn);
2170 [(set_attr "type" "branch")
2171 (set_attr "branch_type" "icc")])
2173 ;; XXX fpcmp nop braindamage
2174 (define_insn "*normal_fp_branch"
2176 (if_then_else (match_operator 1 "comparison_operator"
2177 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2179 (label_ref (match_operand 2 "" ""))
2184 return output_cbranch (operands[1], operands[2], 2, 0,
2185 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2186 ! final_sequence, insn);
2188 [(set_attr "type" "branch")
2189 (set_attr "branch_type" "fcc")])
2191 ;; XXX fpcmp nop braindamage
2192 (define_insn "*inverted_fp_branch"
2194 (if_then_else (match_operator 1 "comparison_operator"
2195 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2198 (label_ref (match_operand 2 "" ""))))]
2202 return output_cbranch (operands[1], operands[2], 2, 1,
2203 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2204 ! final_sequence, insn);
2206 [(set_attr "type" "branch")
2207 (set_attr "branch_type" "fcc")])
2209 ;; XXX fpcmp nop braindamage
2210 (define_insn "*normal_fpe_branch"
2212 (if_then_else (match_operator 1 "comparison_operator"
2213 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2215 (label_ref (match_operand 2 "" ""))
2220 return output_cbranch (operands[1], operands[2], 2, 0,
2221 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2222 ! final_sequence, insn);
2224 [(set_attr "type" "branch")
2225 (set_attr "branch_type" "fcc")])
2227 ;; XXX fpcmp nop braindamage
2228 (define_insn "*inverted_fpe_branch"
2230 (if_then_else (match_operator 1 "comparison_operator"
2231 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2234 (label_ref (match_operand 2 "" ""))))]
2238 return output_cbranch (operands[1], operands[2], 2, 1,
2239 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2240 ! final_sequence, insn);
2242 [(set_attr "type" "branch")
2243 (set_attr "branch_type" "fcc")])
2245 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2246 ;; in the architecture.
2248 ;; There are no 32 bit brreg insns.
2251 (define_insn "*normal_int_branch_sp64"
2253 (if_then_else (match_operator 0 "v9_regcmp_op"
2254 [(match_operand:DI 1 "register_operand" "r")
2256 (label_ref (match_operand 2 "" ""))
2261 return output_v9branch (operands[0], operands[2], 1, 2, 0,
2262 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2263 ! final_sequence, insn);
2265 [(set_attr "type" "branch")
2266 (set_attr "branch_type" "reg")])
2269 (define_insn "*inverted_int_branch_sp64"
2271 (if_then_else (match_operator 0 "v9_regcmp_op"
2272 [(match_operand:DI 1 "register_operand" "r")
2275 (label_ref (match_operand 2 "" ""))))]
2279 return output_v9branch (operands[0], operands[2], 1, 2, 1,
2280 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2281 ! final_sequence, insn);
2283 [(set_attr "type" "branch")
2284 (set_attr "branch_type" "reg")])
2286 ;; Load program counter insns.
2288 (define_insn "get_pc"
2289 [(clobber (reg:SI 15))
2290 (set (match_operand 0 "register_operand" "=r")
2291 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2292 "flag_pic && REGNO (operands[0]) == 23"
2293 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2294 [(set_attr "type" "multi")
2295 (set_attr "length" "3")])
2297 ;; Currently unused...
2298 ;; (define_insn "get_pc_via_rdpc"
2299 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2302 ;; [(set_attr "type" "misc")])
2305 ;; Move instructions
2307 (define_expand "movqi"
2308 [(set (match_operand:QI 0 "general_operand" "")
2309 (match_operand:QI 1 "general_operand" ""))]
2313 /* Working with CONST_INTs is easier, so convert
2314 a double if needed. */
2315 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2317 operands[1] = GEN_INT (trunc_int_for_mode
2318 (CONST_DOUBLE_LOW (operands[1]), QImode));
2321 /* Handle sets of MEM first. */
2322 if (GET_CODE (operands[0]) == MEM)
2324 if (reg_or_0_operand (operands[1], QImode))
2327 if (! reload_in_progress)
2329 operands[0] = validize_mem (operands[0]);
2330 operands[1] = force_reg (QImode, operands[1]);
2334 /* Fixup PIC cases. */
2337 if (CONSTANT_P (operands[1])
2338 && pic_address_needs_scratch (operands[1]))
2339 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2341 if (symbolic_operand (operands[1], QImode))
2343 operands[1] = legitimize_pic_address (operands[1],
2345 (reload_in_progress ?
2352 /* All QI constants require only one insn, so proceed. */
2358 (define_insn "*movqi_insn"
2359 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2360 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2361 "(register_operand (operands[0], QImode)
2362 || reg_or_0_operand (operands[1], QImode))"
2367 [(set_attr "type" "*,load,store")
2368 (set_attr "us3load_type" "*,3cycle,*")])
2370 (define_expand "movhi"
2371 [(set (match_operand:HI 0 "general_operand" "")
2372 (match_operand:HI 1 "general_operand" ""))]
2376 /* Working with CONST_INTs is easier, so convert
2377 a double if needed. */
2378 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2379 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2381 /* Handle sets of MEM first. */
2382 if (GET_CODE (operands[0]) == MEM)
2384 if (reg_or_0_operand (operands[1], HImode))
2387 if (! reload_in_progress)
2389 operands[0] = validize_mem (operands[0]);
2390 operands[1] = force_reg (HImode, operands[1]);
2394 /* Fixup PIC cases. */
2397 if (CONSTANT_P (operands[1])
2398 && pic_address_needs_scratch (operands[1]))
2399 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2401 if (symbolic_operand (operands[1], HImode))
2403 operands[1] = legitimize_pic_address (operands[1],
2405 (reload_in_progress ?
2412 /* This makes sure we will not get rematched due to splittage. */
2413 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2415 else if (CONSTANT_P (operands[1])
2416 && GET_CODE (operands[1]) != HIGH
2417 && GET_CODE (operands[1]) != LO_SUM)
2419 sparc_emit_set_const32 (operands[0], operands[1]);
2426 (define_insn "*movhi_const64_special"
2427 [(set (match_operand:HI 0 "register_operand" "=r")
2428 (match_operand:HI 1 "const64_high_operand" ""))]
2430 "sethi\\t%%hi(%a1), %0")
2432 (define_insn "*movhi_insn"
2433 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2434 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2435 "(register_operand (operands[0], HImode)
2436 || reg_or_0_operand (operands[1], HImode))"
2439 sethi\\t%%hi(%a1), %0
2442 [(set_attr "type" "*,*,load,store")
2443 (set_attr "us3load_type" "*,*,3cycle,*")])
2445 ;; We always work with constants here.
2446 (define_insn "*movhi_lo_sum"
2447 [(set (match_operand:HI 0 "register_operand" "=r")
2448 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2449 (match_operand:HI 2 "arith_operand" "I")))]
2453 (define_expand "movsi"
2454 [(set (match_operand:SI 0 "general_operand" "")
2455 (match_operand:SI 1 "general_operand" ""))]
2459 /* Working with CONST_INTs is easier, so convert
2460 a double if needed. */
2461 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2462 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2464 /* Handle sets of MEM first. */
2465 if (GET_CODE (operands[0]) == MEM)
2467 if (reg_or_0_operand (operands[1], SImode))
2470 if (! reload_in_progress)
2472 operands[0] = validize_mem (operands[0]);
2473 operands[1] = force_reg (SImode, operands[1]);
2477 /* Fixup PIC cases. */
2480 if (CONSTANT_P (operands[1])
2481 && pic_address_needs_scratch (operands[1]))
2482 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2484 if (GET_CODE (operands[1]) == LABEL_REF)
2487 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2491 if (symbolic_operand (operands[1], SImode))
2493 operands[1] = legitimize_pic_address (operands[1],
2495 (reload_in_progress ?
2502 /* If we are trying to toss an integer constant into the
2503 FPU registers, force it into memory. */
2504 if (GET_CODE (operands[0]) == REG
2505 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2506 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2507 && CONSTANT_P (operands[1]))
2508 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2511 /* This makes sure we will not get rematched due to splittage. */
2512 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2514 else if (CONSTANT_P (operands[1])
2515 && GET_CODE (operands[1]) != HIGH
2516 && GET_CODE (operands[1]) != LO_SUM)
2518 sparc_emit_set_const32 (operands[0], operands[1]);
2525 ;; This is needed to show CSE exactly which bits are set
2526 ;; in a 64-bit register by sethi instructions.
2527 (define_insn "*movsi_const64_special"
2528 [(set (match_operand:SI 0 "register_operand" "=r")
2529 (match_operand:SI 1 "const64_high_operand" ""))]
2531 "sethi\\t%%hi(%a1), %0")
2533 (define_insn "*movsi_insn"
2534 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2535 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2536 "(register_operand (operands[0], SImode)
2537 || reg_or_0_operand (operands[1], SImode))"
2541 sethi\\t%%hi(%a1), %0
2548 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2550 (define_insn "*movsi_lo_sum"
2551 [(set (match_operand:SI 0 "register_operand" "=r")
2552 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2553 (match_operand:SI 2 "immediate_operand" "in")))]
2555 "or\\t%1, %%lo(%a2), %0")
2557 (define_insn "*movsi_high"
2558 [(set (match_operand:SI 0 "register_operand" "=r")
2559 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2561 "sethi\\t%%hi(%a1), %0")
2563 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2564 ;; so that CSE won't optimize the address computation away.
2565 (define_insn "movsi_lo_sum_pic"
2566 [(set (match_operand:SI 0 "register_operand" "=r")
2567 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2568 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2570 "or\\t%1, %%lo(%a2), %0")
2572 (define_insn "movsi_high_pic"
2573 [(set (match_operand:SI 0 "register_operand" "=r")
2574 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2575 "flag_pic && check_pic (1)"
2576 "sethi\\t%%hi(%a1), %0")
2578 (define_expand "movsi_pic_label_ref"
2579 [(set (match_dup 3) (high:SI
2580 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2582 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2583 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2584 (set (match_operand:SI 0 "register_operand" "=r")
2585 (minus:SI (match_dup 5) (match_dup 4)))]
2589 current_function_uses_pic_offset_table = 1;
2590 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2593 operands[3] = operands[0];
2594 operands[4] = operands[0];
2598 operands[3] = gen_reg_rtx (SImode);
2599 operands[4] = gen_reg_rtx (SImode);
2601 operands[5] = pic_offset_table_rtx;
2604 (define_insn "*movsi_high_pic_label_ref"
2605 [(set (match_operand:SI 0 "register_operand" "=r")
2607 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2608 (match_operand:SI 2 "" "")] 5)))]
2610 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2612 (define_insn "*movsi_lo_sum_pic_label_ref"
2613 [(set (match_operand:SI 0 "register_operand" "=r")
2614 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2615 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2616 (match_operand:SI 3 "" "")] 5)))]
2618 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2620 (define_expand "movdi"
2621 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2622 (match_operand:DI 1 "general_operand" ""))]
2626 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2627 if (GET_CODE (operands[1]) == CONST_DOUBLE
2628 #if HOST_BITS_PER_WIDE_INT == 32
2629 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2630 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2631 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2632 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2635 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2637 /* Handle MEM cases first. */
2638 if (GET_CODE (operands[0]) == MEM)
2640 /* If it's a REG, we can always do it.
2641 The const zero case is more complex, on v9
2642 we can always perform it. */
2643 if (register_operand (operands[1], DImode)
2645 && (operands[1] == const0_rtx)))
2648 if (! reload_in_progress)
2650 operands[0] = validize_mem (operands[0]);
2651 operands[1] = force_reg (DImode, operands[1]);
2657 if (CONSTANT_P (operands[1])
2658 && pic_address_needs_scratch (operands[1]))
2659 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2661 if (GET_CODE (operands[1]) == LABEL_REF)
2663 if (! TARGET_ARCH64)
2665 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2669 if (symbolic_operand (operands[1], DImode))
2671 operands[1] = legitimize_pic_address (operands[1],
2673 (reload_in_progress ?
2680 /* If we are trying to toss an integer constant into the
2681 FPU registers, force it into memory. */
2682 if (GET_CODE (operands[0]) == REG
2683 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2684 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2685 && CONSTANT_P (operands[1]))
2686 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2689 /* This makes sure we will not get rematched due to splittage. */
2690 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2692 else if (TARGET_ARCH64
2693 && CONSTANT_P (operands[1])
2694 && GET_CODE (operands[1]) != HIGH
2695 && GET_CODE (operands[1]) != LO_SUM)
2697 sparc_emit_set_const64 (operands[0], operands[1]);
2705 ;; Be careful, fmovd does not exist when !arch64.
2706 ;; We match MEM moves directly when we have correct even
2707 ;; numbered registers, but fall into splits otherwise.
2708 ;; The constraint ordering here is really important to
2709 ;; avoid insane problems in reload, especially for patterns
2712 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2713 ;; (const_int -5016)))
2717 (define_insn "*movdi_insn_sp32_v9"
2718 [(set (match_operand:DI 0 "nonimmediate_operand"
2719 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2720 (match_operand:DI 1 "input_operand"
2721 " J,J,U,T,r,o,i,r, f, T, o, f, f"))]
2722 "! TARGET_ARCH64 && TARGET_V9
2723 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2738 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2739 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2741 (define_insn "*movdi_insn_sp32"
2742 [(set (match_operand:DI 0 "nonimmediate_operand"
2743 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2744 (match_operand:DI 1 "input_operand"
2745 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2747 && (register_operand (operands[0], DImode)
2748 || register_operand (operands[1], DImode))"
2762 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2763 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2765 ;; The following are generated by sparc_emit_set_const64
2766 (define_insn "*movdi_sp64_dbl"
2767 [(set (match_operand:DI 0 "register_operand" "=r")
2768 (match_operand:DI 1 "const64_operand" ""))]
2770 && HOST_BITS_PER_WIDE_INT != 64)"
2773 ;; This is needed to show CSE exactly which bits are set
2774 ;; in a 64-bit register by sethi instructions.
2775 (define_insn "*movdi_const64_special"
2776 [(set (match_operand:DI 0 "register_operand" "=r")
2777 (match_operand:DI 1 "const64_high_operand" ""))]
2779 "sethi\\t%%hi(%a1), %0")
2781 (define_insn "*movdi_insn_sp64_novis"
2782 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2783 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2784 "TARGET_ARCH64 && ! TARGET_VIS
2785 && (register_operand (operands[0], DImode)
2786 || reg_or_0_operand (operands[1], DImode))"
2789 sethi\\t%%hi(%a1), %0
2796 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2797 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2799 (define_insn "*movdi_insn_sp64_vis"
2800 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2801 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2802 "TARGET_ARCH64 && TARGET_VIS &&
2803 (register_operand (operands[0], DImode)
2804 || reg_or_0_operand (operands[1], DImode))"
2807 sethi\\t%%hi(%a1), %0
2815 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2816 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2818 (define_expand "movdi_pic_label_ref"
2819 [(set (match_dup 3) (high:DI
2820 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2822 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2823 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2824 (set (match_operand:DI 0 "register_operand" "=r")
2825 (minus:DI (match_dup 5) (match_dup 4)))]
2826 "TARGET_ARCH64 && flag_pic"
2829 current_function_uses_pic_offset_table = 1;
2830 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2833 operands[3] = operands[0];
2834 operands[4] = operands[0];
2838 operands[3] = gen_reg_rtx (DImode);
2839 operands[4] = gen_reg_rtx (DImode);
2841 operands[5] = pic_offset_table_rtx;
2844 (define_insn "*movdi_high_pic_label_ref"
2845 [(set (match_operand:DI 0 "register_operand" "=r")
2847 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2848 (match_operand:DI 2 "" "")] 5)))]
2849 "TARGET_ARCH64 && flag_pic"
2850 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2852 (define_insn "*movdi_lo_sum_pic_label_ref"
2853 [(set (match_operand:DI 0 "register_operand" "=r")
2854 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2855 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2856 (match_operand:DI 3 "" "")] 5)))]
2857 "TARGET_ARCH64 && flag_pic"
2858 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2860 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2861 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2863 (define_insn "movdi_lo_sum_pic"
2864 [(set (match_operand:DI 0 "register_operand" "=r")
2865 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2866 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2867 "TARGET_ARCH64 && flag_pic"
2868 "or\\t%1, %%lo(%a2), %0")
2870 (define_insn "movdi_high_pic"
2871 [(set (match_operand:DI 0 "register_operand" "=r")
2872 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2873 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2874 "sethi\\t%%hi(%a1), %0")
2876 (define_insn "*sethi_di_medlow_embmedany_pic"
2877 [(set (match_operand:DI 0 "register_operand" "=r")
2878 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2879 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2880 "sethi\\t%%hi(%a1), %0")
2882 (define_insn "*sethi_di_medlow"
2883 [(set (match_operand:DI 0 "register_operand" "=r")
2884 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2885 "TARGET_CM_MEDLOW && check_pic (1)"
2886 "sethi\\t%%hi(%a1), %0")
2888 (define_insn "*losum_di_medlow"
2889 [(set (match_operand:DI 0 "register_operand" "=r")
2890 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2891 (match_operand:DI 2 "symbolic_operand" "")))]
2893 "or\\t%1, %%lo(%a2), %0")
2895 (define_insn "seth44"
2896 [(set (match_operand:DI 0 "register_operand" "=r")
2897 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2899 "sethi\\t%%h44(%a1), %0")
2901 (define_insn "setm44"
2902 [(set (match_operand:DI 0 "register_operand" "=r")
2903 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2904 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2906 "or\\t%1, %%m44(%a2), %0")
2908 (define_insn "setl44"
2909 [(set (match_operand:DI 0 "register_operand" "=r")
2910 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2911 (match_operand:DI 2 "symbolic_operand" "")))]
2913 "or\\t%1, %%l44(%a2), %0")
2915 (define_insn "sethh"
2916 [(set (match_operand:DI 0 "register_operand" "=r")
2917 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2919 "sethi\\t%%hh(%a1), %0")
2921 (define_insn "setlm"
2922 [(set (match_operand:DI 0 "register_operand" "=r")
2923 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2925 "sethi\\t%%lm(%a1), %0")
2927 (define_insn "sethm"
2928 [(set (match_operand:DI 0 "register_operand" "=r")
2929 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2930 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2932 "or\\t%1, %%hm(%a2), %0")
2934 (define_insn "setlo"
2935 [(set (match_operand:DI 0 "register_operand" "=r")
2936 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2937 (match_operand:DI 2 "symbolic_operand" "")))]
2939 "or\\t%1, %%lo(%a2), %0")
2941 (define_insn "embmedany_sethi"
2942 [(set (match_operand:DI 0 "register_operand" "=r")
2943 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2944 "TARGET_CM_EMBMEDANY && check_pic (1)"
2945 "sethi\\t%%hi(%a1), %0")
2947 (define_insn "embmedany_losum"
2948 [(set (match_operand:DI 0 "register_operand" "=r")
2949 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2950 (match_operand:DI 2 "data_segment_operand" "")))]
2951 "TARGET_CM_EMBMEDANY"
2952 "add\\t%1, %%lo(%a2), %0")
2954 (define_insn "embmedany_brsum"
2955 [(set (match_operand:DI 0 "register_operand" "=r")
2956 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2957 "TARGET_CM_EMBMEDANY"
2960 (define_insn "embmedany_textuhi"
2961 [(set (match_operand:DI 0 "register_operand" "=r")
2962 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2963 "TARGET_CM_EMBMEDANY && check_pic (1)"
2964 "sethi\\t%%uhi(%a1), %0")
2966 (define_insn "embmedany_texthi"
2967 [(set (match_operand:DI 0 "register_operand" "=r")
2968 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2969 "TARGET_CM_EMBMEDANY && check_pic (1)"
2970 "sethi\\t%%hi(%a1), %0")
2972 (define_insn "embmedany_textulo"
2973 [(set (match_operand:DI 0 "register_operand" "=r")
2974 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2975 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2976 "TARGET_CM_EMBMEDANY"
2977 "or\\t%1, %%ulo(%a2), %0")
2979 (define_insn "embmedany_textlo"
2980 [(set (match_operand:DI 0 "register_operand" "=r")
2981 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2982 (match_operand:DI 2 "text_segment_operand" "")))]
2983 "TARGET_CM_EMBMEDANY"
2984 "or\\t%1, %%lo(%a2), %0")
2986 ;; Now some patterns to help reload out a bit.
2987 (define_expand "reload_indi"
2988 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2989 (match_operand:DI 1 "immediate_operand" "")
2990 (match_operand:TI 2 "register_operand" "=&r")])]
2992 || TARGET_CM_EMBMEDANY)
2996 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
3000 (define_expand "reload_outdi"
3001 [(parallel [(match_operand:DI 0 "register_operand" "=r")
3002 (match_operand:DI 1 "immediate_operand" "")
3003 (match_operand:TI 2 "register_operand" "=&r")])]
3005 || TARGET_CM_EMBMEDANY)
3009 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
3013 ;; Split up putting CONSTs and REGs into DI regs when !arch64
3015 [(set (match_operand:DI 0 "register_operand" "")
3016 (match_operand:DI 1 "const_int_operand" ""))]
3017 "! TARGET_ARCH64 && reload_completed"
3018 [(clobber (const_int 0))]
3021 #if HOST_BITS_PER_WIDE_INT == 32
3022 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3023 (INTVAL (operands[1]) < 0) ?
3026 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3029 unsigned int low, high;
3031 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
3032 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
3033 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
3035 /* Slick... but this trick loses if this subreg constant part
3036 can be done in one insn. */
3037 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
3038 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3039 gen_highpart (SImode, operands[0])));
3041 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
3047 [(set (match_operand:DI 0 "register_operand" "")
3048 (match_operand:DI 1 "const_double_operand" ""))]
3049 "! TARGET_ARCH64 && reload_completed"
3050 [(clobber (const_int 0))]
3053 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3054 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
3056 /* Slick... but this trick loses if this subreg constant part
3057 can be done in one insn. */
3058 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
3059 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
3060 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
3062 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3063 gen_highpart (SImode, operands[0])));
3067 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3068 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
3074 [(set (match_operand:DI 0 "register_operand" "")
3075 (match_operand:DI 1 "register_operand" ""))]
3076 "! TARGET_ARCH64 && reload_completed"
3077 [(clobber (const_int 0))]
3080 rtx set_dest = operands[0];
3081 rtx set_src = operands[1];
3085 dest1 = gen_highpart (SImode, set_dest);
3086 dest2 = gen_lowpart (SImode, set_dest);
3087 src1 = gen_highpart (SImode, set_src);
3088 src2 = gen_lowpart (SImode, set_src);
3090 /* Now emit using the real source and destination we found, swapping
3091 the order if we detect overlap. */
3092 if (reg_overlap_mentioned_p (dest1, src2))
3094 emit_insn (gen_movsi (dest2, src2));
3095 emit_insn (gen_movsi (dest1, src1));
3099 emit_insn (gen_movsi (dest1, src1));
3100 emit_insn (gen_movsi (dest2, src2));
3105 ;; Now handle the cases of memory moves from/to non-even
3106 ;; DI mode register pairs.
3108 [(set (match_operand:DI 0 "register_operand" "")
3109 (match_operand:DI 1 "memory_operand" ""))]
3112 && sparc_splitdi_legitimate (operands[0], operands[1]))"
3113 [(clobber (const_int 0))]
3116 rtx word0 = adjust_address (operands[1], SImode, 0);
3117 rtx word1 = adjust_address (operands[1], SImode, 4);
3118 rtx high_part = gen_highpart (SImode, operands[0]);
3119 rtx low_part = gen_lowpart (SImode, operands[0]);
3121 if (reg_overlap_mentioned_p (high_part, word1))
3123 emit_insn (gen_movsi (low_part, word1));
3124 emit_insn (gen_movsi (high_part, word0));
3128 emit_insn (gen_movsi (high_part, word0));
3129 emit_insn (gen_movsi (low_part, word1));
3135 [(set (match_operand:DI 0 "memory_operand" "")
3136 (match_operand:DI 1 "register_operand" ""))]
3139 && sparc_splitdi_legitimate (operands[1], operands[0]))"
3140 [(clobber (const_int 0))]
3143 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
3144 gen_highpart (SImode, operands[1])));
3145 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
3146 gen_lowpart (SImode, operands[1])));
3151 [(set (match_operand:DI 0 "memory_operand" "")
3156 && ! mem_min_alignment (operands[0], 8)))
3157 && offsettable_memref_p (operands[0])"
3158 [(clobber (const_int 0))]
3161 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
3162 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
3166 ;; Floating point move insns
3168 (define_insn "*movsf_insn_novis"
3169 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
3170 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
3171 "(TARGET_FPU && ! TARGET_VIS)
3172 && (register_operand (operands[0], SFmode)
3173 || register_operand (operands[1], SFmode)
3174 || fp_zero_operand (operands[1], SFmode))"
3177 if (GET_CODE (operands[1]) == CONST_DOUBLE
3178 && (which_alternative == 2
3179 || which_alternative == 3
3180 || which_alternative == 4))
3185 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3186 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3187 operands[1] = GEN_INT (i);
3190 switch (which_alternative)
3193 return \"fmovs\\t%1, %0\";
3195 return \"clr\\t%0\";
3197 return \"sethi\\t%%hi(%a1), %0\";
3199 return \"mov\\t%1, %0\";
3204 return \"ld\\t%1, %0\";
3207 return \"st\\t%r1, %0\";
3212 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
3214 (define_insn "*movsf_insn_vis"
3215 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3216 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3217 "(TARGET_FPU && TARGET_VIS)
3218 && (register_operand (operands[0], SFmode)
3219 || register_operand (operands[1], SFmode)
3220 || fp_zero_operand (operands[1], SFmode))"
3223 if (GET_CODE (operands[1]) == CONST_DOUBLE
3224 && (which_alternative == 3
3225 || which_alternative == 4
3226 || which_alternative == 5))
3231 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3232 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3233 operands[1] = GEN_INT (i);
3236 switch (which_alternative)
3239 return \"fmovs\\t%1, %0\";
3241 return \"fzeros\\t%0\";
3243 return \"clr\\t%0\";
3245 return \"sethi\\t%%hi(%a1), %0\";
3247 return \"mov\\t%1, %0\";
3252 return \"ld\\t%1, %0\";
3255 return \"st\\t%r1, %0\";
3260 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
3262 ;; Exactly the same as above, except that all `f' cases are deleted.
3263 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3266 (define_insn "*movsf_no_f_insn"
3267 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
3268 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
3270 && (register_operand (operands[0], SFmode)
3271 || register_operand (operands[1], SFmode)
3272 || fp_zero_operand (operands[1], SFmode))"
3275 if (GET_CODE (operands[1]) == CONST_DOUBLE
3276 && (which_alternative == 1
3277 || which_alternative == 2
3278 || which_alternative == 3))
3283 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3284 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3285 operands[1] = GEN_INT (i);
3288 switch (which_alternative)
3291 return \"clr\\t%0\";
3293 return \"sethi\\t%%hi(%a1), %0\";
3295 return \"mov\\t%1, %0\";
3299 return \"ld\\t%1, %0\";
3301 return \"st\\t%r1, %0\";
3306 [(set_attr "type" "*,*,*,*,load,store")])
3308 (define_insn "*movsf_lo_sum"
3309 [(set (match_operand:SF 0 "register_operand" "=r")
3310 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3311 (match_operand:SF 2 "const_double_operand" "S")))]
3312 "fp_high_losum_p (operands[2])"
3318 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3319 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3320 operands[2] = GEN_INT (i);
3321 return \"or\\t%1, %%lo(%a2), %0\";
3324 (define_insn "*movsf_high"
3325 [(set (match_operand:SF 0 "register_operand" "=r")
3326 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3327 "fp_high_losum_p (operands[1])"
3333 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3334 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3335 operands[1] = GEN_INT (i);
3336 return \"sethi\\t%%hi(%1), %0\";
3340 [(set (match_operand:SF 0 "register_operand" "")
3341 (match_operand:SF 1 "const_double_operand" ""))]
3342 "fp_high_losum_p (operands[1])
3343 && (GET_CODE (operands[0]) == REG
3344 && REGNO (operands[0]) < 32)"
3345 [(set (match_dup 0) (high:SF (match_dup 1)))
3346 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3348 (define_expand "movsf"
3349 [(set (match_operand:SF 0 "general_operand" "")
3350 (match_operand:SF 1 "general_operand" ""))]
3354 /* Force SFmode constants into memory. */
3355 if (GET_CODE (operands[0]) == REG
3356 && CONSTANT_P (operands[1]))
3358 /* emit_group_store will send such bogosity to us when it is
3359 not storing directly into memory. So fix this up to avoid
3360 crashes in output_constant_pool. */
3361 if (operands [1] == const0_rtx)
3362 operands[1] = CONST0_RTX (SFmode);
3364 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3367 /* We are able to build any SF constant in integer registers
3368 with at most 2 instructions. */
3369 if (REGNO (operands[0]) < 32)
3372 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3376 /* Handle sets of MEM first. */
3377 if (GET_CODE (operands[0]) == MEM)
3379 if (register_operand (operands[1], SFmode)
3380 || fp_zero_operand (operands[1], SFmode))
3383 if (! reload_in_progress)
3385 operands[0] = validize_mem (operands[0]);
3386 operands[1] = force_reg (SFmode, operands[1]);
3390 /* Fixup PIC cases. */
3393 if (CONSTANT_P (operands[1])
3394 && pic_address_needs_scratch (operands[1]))
3395 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3397 if (symbolic_operand (operands[1], SFmode))
3399 operands[1] = legitimize_pic_address (operands[1],
3401 (reload_in_progress ?
3411 (define_expand "movdf"
3412 [(set (match_operand:DF 0 "general_operand" "")
3413 (match_operand:DF 1 "general_operand" ""))]
3417 /* Force DFmode constants into memory. */
3418 if (GET_CODE (operands[0]) == REG
3419 && CONSTANT_P (operands[1]))
3421 /* emit_group_store will send such bogosity to us when it is
3422 not storing directly into memory. So fix this up to avoid
3423 crashes in output_constant_pool. */
3424 if (operands [1] == const0_rtx)
3425 operands[1] = CONST0_RTX (DFmode);
3427 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3428 && fp_zero_operand (operands[1], DFmode))
3431 /* We are able to build any DF constant in integer registers. */
3432 if (REGNO (operands[0]) < 32
3433 && (reload_completed || reload_in_progress))
3436 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3440 /* Handle MEM cases first. */
3441 if (GET_CODE (operands[0]) == MEM)
3443 if (register_operand (operands[1], DFmode)
3444 || fp_zero_operand (operands[1], DFmode))
3447 if (! reload_in_progress)
3449 operands[0] = validize_mem (operands[0]);
3450 operands[1] = force_reg (DFmode, operands[1]);
3454 /* Fixup PIC cases. */
3457 if (CONSTANT_P (operands[1])
3458 && pic_address_needs_scratch (operands[1]))
3459 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3461 if (symbolic_operand (operands[1], DFmode))
3463 operands[1] = legitimize_pic_address (operands[1],
3465 (reload_in_progress ?
3475 ;; Be careful, fmovd does not exist when !v9.
3476 (define_insn "*movdf_insn_sp32"
3477 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
3478 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3481 && (register_operand (operands[0], DFmode)
3482 || register_operand (operands[1], DFmode)
3483 || fp_zero_operand (operands[1], DFmode))"
3495 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3496 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3498 (define_insn "*movdf_no_e_insn_sp32"
3499 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3500 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3504 && (register_operand (operands[0], DFmode)
3505 || register_operand (operands[1], DFmode)
3506 || fp_zero_operand (operands[1], DFmode))"
3513 [(set_attr "type" "load,store,*,*,*")
3514 (set_attr "length" "*,*,2,2,2")])
3516 (define_insn "*movdf_no_e_insn_v9_sp32"
3517 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3518 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3522 && (register_operand (operands[0], DFmode)
3523 || register_operand (operands[1], DFmode)
3524 || fp_zero_operand (operands[1], DFmode))"
3531 [(set_attr "type" "load,store,store,*,*")
3532 (set_attr "length" "*,*,*,2,2")])
3534 ;; We have available v9 double floats but not 64-bit
3535 ;; integer registers and no VIS.
3536 (define_insn "*movdf_insn_v9only_novis"
3537 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
3538 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
3543 && (register_operand (operands[0], DFmode)
3544 || register_operand (operands[1], DFmode)
3545 || fp_zero_operand (operands[1], DFmode))"
3556 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3557 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3558 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3560 ;; We have available v9 double floats but not 64-bit
3561 ;; integer registers but we have VIS.
3562 (define_insn "*movdf_insn_v9only_vis"
3563 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
3564 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
3568 && (register_operand (operands[0], DFmode)
3569 || register_operand (operands[1], DFmode)
3570 || fp_zero_operand (operands[1], DFmode))"
3582 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3583 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3584 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3586 ;; We have available both v9 double floats and 64-bit
3587 ;; integer registers. No VIS though.
3588 (define_insn "*movdf_insn_sp64_novis"
3589 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3590 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3594 && (register_operand (operands[0], DFmode)
3595 || register_operand (operands[1], DFmode)
3596 || fp_zero_operand (operands[1], DFmode))"
3605 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3606 (set_attr "length" "*,*,*,*,*,*,2")
3607 (set_attr "fptype" "double,*,*,*,*,*,*")])
3609 ;; We have available both v9 double floats and 64-bit
3610 ;; integer registers. And we have VIS.
3611 (define_insn "*movdf_insn_sp64_vis"
3612 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3613 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3617 && (register_operand (operands[0], DFmode)
3618 || register_operand (operands[1], DFmode)
3619 || fp_zero_operand (operands[1], DFmode))"
3629 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3630 (set_attr "length" "*,*,*,*,*,*,*,2")
3631 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3633 (define_insn "*movdf_no_e_insn_sp64"
3634 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3635 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3638 && (register_operand (operands[0], DFmode)
3639 || register_operand (operands[1], DFmode)
3640 || fp_zero_operand (operands[1], DFmode))"
3645 [(set_attr "type" "*,load,store")])
3648 [(set (match_operand:DF 0 "register_operand" "")
3649 (match_operand:DF 1 "const_double_operand" ""))]
3651 && (GET_CODE (operands[0]) == REG
3652 && REGNO (operands[0]) < 32)
3653 && ! fp_zero_operand(operands[1], DFmode)
3654 && reload_completed"
3655 [(clobber (const_int 0))]
3661 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3662 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3663 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3667 #if HOST_BITS_PER_WIDE_INT == 64
3670 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3671 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3672 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3674 emit_insn (gen_movdi (operands[0],
3675 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3680 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3683 /* Slick... but this trick loses if this subreg constant part
3684 can be done in one insn. */
3686 && !(SPARC_SETHI32_P (l[0])
3687 || SPARC_SIMM13_P (l[0])))
3689 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3690 gen_highpart (SImode, operands[0])));
3694 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3701 ;; Ok, now the splits to handle all the multi insn and
3702 ;; mis-aligned memory address cases.
3703 ;; In these splits please take note that we must be
3704 ;; careful when V9 but not ARCH64 because the integer
3705 ;; register DFmode cases must be handled.
3707 [(set (match_operand:DF 0 "register_operand" "")
3708 (match_operand:DF 1 "register_operand" ""))]
3711 && ((GET_CODE (operands[0]) == REG
3712 && REGNO (operands[0]) < 32)
3713 || (GET_CODE (operands[0]) == SUBREG
3714 && GET_CODE (SUBREG_REG (operands[0])) == REG
3715 && REGNO (SUBREG_REG (operands[0])) < 32))))
3716 && reload_completed"
3717 [(clobber (const_int 0))]
3720 rtx set_dest = operands[0];
3721 rtx set_src = operands[1];
3725 dest1 = gen_highpart (SFmode, set_dest);
3726 dest2 = gen_lowpart (SFmode, set_dest);
3727 src1 = gen_highpart (SFmode, set_src);
3728 src2 = gen_lowpart (SFmode, set_src);
3730 /* Now emit using the real source and destination we found, swapping
3731 the order if we detect overlap. */
3732 if (reg_overlap_mentioned_p (dest1, src2))
3734 emit_insn (gen_movsf (dest2, src2));
3735 emit_insn (gen_movsf (dest1, src1));
3739 emit_insn (gen_movsf (dest1, src1));
3740 emit_insn (gen_movsf (dest2, src2));
3746 [(set (match_operand:DF 0 "register_operand" "")
3747 (match_operand:DF 1 "memory_operand" ""))]
3750 && (((REGNO (operands[0]) % 2) != 0)
3751 || ! mem_min_alignment (operands[1], 8))
3752 && offsettable_memref_p (operands[1])"
3753 [(clobber (const_int 0))]
3756 rtx word0 = adjust_address (operands[1], SFmode, 0);
3757 rtx word1 = adjust_address (operands[1], SFmode, 4);
3759 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3761 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3763 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3768 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3770 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3777 [(set (match_operand:DF 0 "memory_operand" "")
3778 (match_operand:DF 1 "register_operand" ""))]
3781 && (((REGNO (operands[1]) % 2) != 0)
3782 || ! mem_min_alignment (operands[0], 8))
3783 && offsettable_memref_p (operands[0])"
3784 [(clobber (const_int 0))]
3787 rtx word0 = adjust_address (operands[0], SFmode, 0);
3788 rtx word1 = adjust_address (operands[0], SFmode, 4);
3790 emit_insn (gen_movsf (word0,
3791 gen_highpart (SFmode, operands[1])));
3792 emit_insn (gen_movsf (word1,
3793 gen_lowpart (SFmode, operands[1])));
3798 [(set (match_operand:DF 0 "memory_operand" "")
3799 (match_operand:DF 1 "fp_zero_operand" ""))]
3803 && ! mem_min_alignment (operands[0], 8)))
3804 && offsettable_memref_p (operands[0])"
3805 [(clobber (const_int 0))]
3810 dest1 = adjust_address (operands[0], SFmode, 0);
3811 dest2 = adjust_address (operands[0], SFmode, 4);
3813 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3814 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3819 [(set (match_operand:DF 0 "register_operand" "")
3820 (match_operand:DF 1 "fp_zero_operand" ""))]
3823 && ((GET_CODE (operands[0]) == REG
3824 && REGNO (operands[0]) < 32)
3825 || (GET_CODE (operands[0]) == SUBREG
3826 && GET_CODE (SUBREG_REG (operands[0])) == REG
3827 && REGNO (SUBREG_REG (operands[0])) < 32))"
3828 [(clobber (const_int 0))]
3831 rtx set_dest = operands[0];
3834 dest1 = gen_highpart (SFmode, set_dest);
3835 dest2 = gen_lowpart (SFmode, set_dest);
3836 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3837 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3841 (define_expand "movtf"
3842 [(set (match_operand:TF 0 "general_operand" "")
3843 (match_operand:TF 1 "general_operand" ""))]
3847 /* Force TFmode constants into memory. */
3848 if (GET_CODE (operands[0]) == REG
3849 && CONSTANT_P (operands[1]))
3851 /* emit_group_store will send such bogosity to us when it is
3852 not storing directly into memory. So fix this up to avoid
3853 crashes in output_constant_pool. */
3854 if (operands [1] == const0_rtx)
3855 operands[1] = CONST0_RTX (TFmode);
3857 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3860 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3864 /* Handle MEM cases first, note that only v9 guarentees
3865 full 16-byte alignment for quads. */
3866 if (GET_CODE (operands[0]) == MEM)
3868 if (register_operand (operands[1], TFmode)
3869 || fp_zero_operand (operands[1], TFmode))
3872 if (! reload_in_progress)
3874 operands[0] = validize_mem (operands[0]);
3875 operands[1] = force_reg (TFmode, operands[1]);
3879 /* Fixup PIC cases. */
3882 if (CONSTANT_P (operands[1])
3883 && pic_address_needs_scratch (operands[1]))
3884 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3886 if (symbolic_operand (operands[1], TFmode))
3888 operands[1] = legitimize_pic_address (operands[1],
3890 (reload_in_progress ?
3900 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3901 ;; we must split them all. :-(
3902 (define_insn "*movtf_insn_sp32"
3903 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3904 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3908 && (register_operand (operands[0], TFmode)
3909 || register_operand (operands[1], TFmode)
3910 || fp_zero_operand (operands[1], TFmode))"
3912 [(set_attr "length" "4")])
3914 (define_insn "*movtf_insn_vis_sp32"
3915 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3916 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3920 && (register_operand (operands[0], TFmode)
3921 || register_operand (operands[1], TFmode)
3922 || fp_zero_operand (operands[1], TFmode))"
3924 [(set_attr "length" "4")])
3926 ;; Exactly the same as above, except that all `e' cases are deleted.
3927 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3930 (define_insn "*movtf_no_e_insn_sp32"
3931 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3932 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3935 && (register_operand (operands[0], TFmode)
3936 || register_operand (operands[1], TFmode)
3937 || fp_zero_operand (operands[1], TFmode))"
3939 [(set_attr "length" "4")])
3941 ;; Now handle the float reg cases directly when arch64,
3942 ;; hard_quad, and proper reg number alignment are all true.
3943 (define_insn "*movtf_insn_hq_sp64"
3944 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3945 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3950 && (register_operand (operands[0], TFmode)
3951 || register_operand (operands[1], TFmode)
3952 || fp_zero_operand (operands[1], TFmode))"
3959 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3960 (set_attr "length" "*,*,*,2,2")])
3962 (define_insn "*movtf_insn_hq_vis_sp64"
3963 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3964 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3969 && (register_operand (operands[0], TFmode)
3970 || register_operand (operands[1], TFmode)
3971 || fp_zero_operand (operands[1], TFmode))"
3979 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3980 (set_attr "length" "*,*,*,2,2,2")])
3982 ;; Now we allow the integer register cases even when
3983 ;; only arch64 is true.
3984 (define_insn "*movtf_insn_sp64"
3985 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3986 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3990 && ! TARGET_HARD_QUAD
3991 && (register_operand (operands[0], TFmode)
3992 || register_operand (operands[1], TFmode)
3993 || fp_zero_operand (operands[1], TFmode))"
3995 [(set_attr "length" "2")])
3997 (define_insn "*movtf_insn_vis_sp64"
3998 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3999 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
4003 && ! TARGET_HARD_QUAD
4004 && (register_operand (operands[0], TFmode)
4005 || register_operand (operands[1], TFmode)
4006 || fp_zero_operand (operands[1], TFmode))"
4008 [(set_attr "length" "2")])
4010 (define_insn "*movtf_no_e_insn_sp64"
4011 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
4012 (match_operand:TF 1 "input_operand" "orG,rG"))]
4015 && (register_operand (operands[0], TFmode)
4016 || register_operand (operands[1], TFmode)
4017 || fp_zero_operand (operands[1], TFmode))"
4019 [(set_attr "length" "2")])
4021 ;; Now all the splits to handle multi-insn TF mode moves.
4023 [(set (match_operand:TF 0 "register_operand" "")
4024 (match_operand:TF 1 "register_operand" ""))]
4028 && ! TARGET_HARD_QUAD)
4029 || ! fp_register_operand (operands[0], TFmode))"
4030 [(clobber (const_int 0))]
4033 rtx set_dest = operands[0];
4034 rtx set_src = operands[1];
4038 dest1 = gen_df_reg (set_dest, 0);
4039 dest2 = gen_df_reg (set_dest, 1);
4040 src1 = gen_df_reg (set_src, 0);
4041 src2 = gen_df_reg (set_src, 1);
4043 /* Now emit using the real source and destination we found, swapping
4044 the order if we detect overlap. */
4045 if (reg_overlap_mentioned_p (dest1, src2))
4047 emit_insn (gen_movdf (dest2, src2));
4048 emit_insn (gen_movdf (dest1, src1));
4052 emit_insn (gen_movdf (dest1, src1));
4053 emit_insn (gen_movdf (dest2, src2));
4059 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4060 (match_operand:TF 1 "fp_zero_operand" ""))]
4062 [(clobber (const_int 0))]
4065 rtx set_dest = operands[0];
4068 switch (GET_CODE (set_dest))
4071 dest1 = gen_df_reg (set_dest, 0);
4072 dest2 = gen_df_reg (set_dest, 1);
4075 dest1 = adjust_address (set_dest, DFmode, 0);
4076 dest2 = adjust_address (set_dest, DFmode, 8);
4082 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
4083 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
4088 [(set (match_operand:TF 0 "register_operand" "")
4089 (match_operand:TF 1 "memory_operand" ""))]
4091 && offsettable_memref_p (operands[1])
4093 || ! TARGET_HARD_QUAD
4094 || ! fp_register_operand (operands[0], TFmode)))"
4095 [(clobber (const_int 0))]
4098 rtx word0 = adjust_address (operands[1], DFmode, 0);
4099 rtx word1 = adjust_address (operands[1], DFmode, 8);
4100 rtx set_dest, dest1, dest2;
4102 set_dest = operands[0];
4104 dest1 = gen_df_reg (set_dest, 0);
4105 dest2 = gen_df_reg (set_dest, 1);
4107 /* Now output, ordering such that we don't clobber any registers
4108 mentioned in the address. */
4109 if (reg_overlap_mentioned_p (dest1, word1))
4112 emit_insn (gen_movdf (dest2, word1));
4113 emit_insn (gen_movdf (dest1, word0));
4117 emit_insn (gen_movdf (dest1, word0));
4118 emit_insn (gen_movdf (dest2, word1));
4124 [(set (match_operand:TF 0 "memory_operand" "")
4125 (match_operand:TF 1 "register_operand" ""))]
4127 && offsettable_memref_p (operands[0])
4129 || ! TARGET_HARD_QUAD
4130 || ! fp_register_operand (operands[1], TFmode)))"
4131 [(clobber (const_int 0))]
4134 rtx set_src = operands[1];
4136 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
4137 gen_df_reg (set_src, 0)));
4138 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
4139 gen_df_reg (set_src, 1)));
4143 ;; Sparc V9 conditional move instructions.
4145 ;; We can handle larger constants here for some flavors, but for now we keep
4146 ;; it simple and only allow those constants supported by all flavours.
4147 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
4148 ;; 3 contains the constant if one is present, but we handle either for
4149 ;; generality (sparc.c puts a constant in operand 2).
4151 (define_expand "movqicc"
4152 [(set (match_operand:QI 0 "register_operand" "")
4153 (if_then_else:QI (match_operand 1 "comparison_operator" "")
4154 (match_operand:QI 2 "arith10_operand" "")
4155 (match_operand:QI 3 "arith10_operand" "")))]
4159 enum rtx_code code = GET_CODE (operands[1]);
4161 if (GET_MODE (sparc_compare_op0) == DImode
4165 if (sparc_compare_op1 == const0_rtx
4166 && GET_CODE (sparc_compare_op0) == REG
4167 && GET_MODE (sparc_compare_op0) == DImode
4168 && v9_regcmp_p (code))
4170 operands[1] = gen_rtx_fmt_ee (code, DImode,
4171 sparc_compare_op0, sparc_compare_op1);
4175 rtx cc_reg = gen_compare_reg (code,
4176 sparc_compare_op0, sparc_compare_op1);
4177 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4181 (define_expand "movhicc"
4182 [(set (match_operand:HI 0 "register_operand" "")
4183 (if_then_else:HI (match_operand 1 "comparison_operator" "")
4184 (match_operand:HI 2 "arith10_operand" "")
4185 (match_operand:HI 3 "arith10_operand" "")))]
4189 enum rtx_code code = GET_CODE (operands[1]);
4191 if (GET_MODE (sparc_compare_op0) == DImode
4195 if (sparc_compare_op1 == const0_rtx
4196 && GET_CODE (sparc_compare_op0) == REG
4197 && GET_MODE (sparc_compare_op0) == DImode
4198 && v9_regcmp_p (code))
4200 operands[1] = gen_rtx_fmt_ee (code, DImode,
4201 sparc_compare_op0, sparc_compare_op1);
4205 rtx cc_reg = gen_compare_reg (code,
4206 sparc_compare_op0, sparc_compare_op1);
4207 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4211 (define_expand "movsicc"
4212 [(set (match_operand:SI 0 "register_operand" "")
4213 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4214 (match_operand:SI 2 "arith10_operand" "")
4215 (match_operand:SI 3 "arith10_operand" "")))]
4219 enum rtx_code code = GET_CODE (operands[1]);
4220 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4222 if (sparc_compare_op1 == const0_rtx
4223 && GET_CODE (sparc_compare_op0) == REG
4224 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4226 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4227 sparc_compare_op0, sparc_compare_op1);
4231 rtx cc_reg = gen_compare_reg (code,
4232 sparc_compare_op0, sparc_compare_op1);
4233 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4234 cc_reg, const0_rtx);
4238 (define_expand "movdicc"
4239 [(set (match_operand:DI 0 "register_operand" "")
4240 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4241 (match_operand:DI 2 "arith10_double_operand" "")
4242 (match_operand:DI 3 "arith10_double_operand" "")))]
4246 enum rtx_code code = GET_CODE (operands[1]);
4248 if (sparc_compare_op1 == const0_rtx
4249 && GET_CODE (sparc_compare_op0) == REG
4250 && GET_MODE (sparc_compare_op0) == DImode
4251 && v9_regcmp_p (code))
4253 operands[1] = gen_rtx_fmt_ee (code, DImode,
4254 sparc_compare_op0, sparc_compare_op1);
4258 rtx cc_reg = gen_compare_reg (code,
4259 sparc_compare_op0, sparc_compare_op1);
4260 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4261 cc_reg, const0_rtx);
4265 (define_expand "movsfcc"
4266 [(set (match_operand:SF 0 "register_operand" "")
4267 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4268 (match_operand:SF 2 "register_operand" "")
4269 (match_operand:SF 3 "register_operand" "")))]
4270 "TARGET_V9 && TARGET_FPU"
4273 enum rtx_code code = GET_CODE (operands[1]);
4275 if (GET_MODE (sparc_compare_op0) == DImode
4279 if (sparc_compare_op1 == const0_rtx
4280 && GET_CODE (sparc_compare_op0) == REG
4281 && GET_MODE (sparc_compare_op0) == DImode
4282 && v9_regcmp_p (code))
4284 operands[1] = gen_rtx_fmt_ee (code, DImode,
4285 sparc_compare_op0, sparc_compare_op1);
4289 rtx cc_reg = gen_compare_reg (code,
4290 sparc_compare_op0, sparc_compare_op1);
4291 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4295 (define_expand "movdfcc"
4296 [(set (match_operand:DF 0 "register_operand" "")
4297 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4298 (match_operand:DF 2 "register_operand" "")
4299 (match_operand:DF 3 "register_operand" "")))]
4300 "TARGET_V9 && TARGET_FPU"
4303 enum rtx_code code = GET_CODE (operands[1]);
4305 if (GET_MODE (sparc_compare_op0) == DImode
4309 if (sparc_compare_op1 == const0_rtx
4310 && GET_CODE (sparc_compare_op0) == REG
4311 && GET_MODE (sparc_compare_op0) == DImode
4312 && v9_regcmp_p (code))
4314 operands[1] = gen_rtx_fmt_ee (code, DImode,
4315 sparc_compare_op0, sparc_compare_op1);
4319 rtx cc_reg = gen_compare_reg (code,
4320 sparc_compare_op0, sparc_compare_op1);
4321 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4325 (define_expand "movtfcc"
4326 [(set (match_operand:TF 0 "register_operand" "")
4327 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4328 (match_operand:TF 2 "register_operand" "")
4329 (match_operand:TF 3 "register_operand" "")))]
4330 "TARGET_V9 && TARGET_FPU"
4333 enum rtx_code code = GET_CODE (operands[1]);
4335 if (GET_MODE (sparc_compare_op0) == DImode
4339 if (sparc_compare_op1 == const0_rtx
4340 && GET_CODE (sparc_compare_op0) == REG
4341 && GET_MODE (sparc_compare_op0) == DImode
4342 && v9_regcmp_p (code))
4344 operands[1] = gen_rtx_fmt_ee (code, DImode,
4345 sparc_compare_op0, sparc_compare_op1);
4349 rtx cc_reg = gen_compare_reg (code,
4350 sparc_compare_op0, sparc_compare_op1);
4351 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4355 ;; Conditional move define_insns.
4357 (define_insn "*movqi_cc_sp64"
4358 [(set (match_operand:QI 0 "register_operand" "=r,r")
4359 (if_then_else:QI (match_operator 1 "comparison_operator"
4360 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4362 (match_operand:QI 3 "arith11_operand" "rL,0")
4363 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4366 mov%C1\\t%x2, %3, %0
4367 mov%c1\\t%x2, %4, %0"
4368 [(set_attr "type" "cmove")])
4370 (define_insn "*movhi_cc_sp64"
4371 [(set (match_operand:HI 0 "register_operand" "=r,r")
4372 (if_then_else:HI (match_operator 1 "comparison_operator"
4373 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4375 (match_operand:HI 3 "arith11_operand" "rL,0")
4376 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4379 mov%C1\\t%x2, %3, %0
4380 mov%c1\\t%x2, %4, %0"
4381 [(set_attr "type" "cmove")])
4383 (define_insn "*movsi_cc_sp64"
4384 [(set (match_operand:SI 0 "register_operand" "=r,r")
4385 (if_then_else:SI (match_operator 1 "comparison_operator"
4386 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4388 (match_operand:SI 3 "arith11_operand" "rL,0")
4389 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4392 mov%C1\\t%x2, %3, %0
4393 mov%c1\\t%x2, %4, %0"
4394 [(set_attr "type" "cmove")])
4396 ;; ??? The constraints of operands 3,4 need work.
4397 (define_insn "*movdi_cc_sp64"
4398 [(set (match_operand:DI 0 "register_operand" "=r,r")
4399 (if_then_else:DI (match_operator 1 "comparison_operator"
4400 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4402 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4403 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4406 mov%C1\\t%x2, %3, %0
4407 mov%c1\\t%x2, %4, %0"
4408 [(set_attr "type" "cmove")])
4410 (define_insn "*movdi_cc_sp64_trunc"
4411 [(set (match_operand:SI 0 "register_operand" "=r,r")
4412 (if_then_else:SI (match_operator 1 "comparison_operator"
4413 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4415 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4416 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4419 mov%C1\\t%x2, %3, %0
4420 mov%c1\\t%x2, %4, %0"
4421 [(set_attr "type" "cmove")])
4423 (define_insn "*movsf_cc_sp64"
4424 [(set (match_operand:SF 0 "register_operand" "=f,f")
4425 (if_then_else:SF (match_operator 1 "comparison_operator"
4426 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4428 (match_operand:SF 3 "register_operand" "f,0")
4429 (match_operand:SF 4 "register_operand" "0,f")))]
4430 "TARGET_V9 && TARGET_FPU"
4432 fmovs%C1\\t%x2, %3, %0
4433 fmovs%c1\\t%x2, %4, %0"
4434 [(set_attr "type" "fpcmove")])
4436 (define_insn "movdf_cc_sp64"
4437 [(set (match_operand:DF 0 "register_operand" "=e,e")
4438 (if_then_else:DF (match_operator 1 "comparison_operator"
4439 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4441 (match_operand:DF 3 "register_operand" "e,0")
4442 (match_operand:DF 4 "register_operand" "0,e")))]
4443 "TARGET_V9 && TARGET_FPU"
4445 fmovd%C1\\t%x2, %3, %0
4446 fmovd%c1\\t%x2, %4, %0"
4447 [(set_attr "type" "fpcmove")
4448 (set_attr "fptype" "double")])
4450 (define_insn "*movtf_cc_hq_sp64"
4451 [(set (match_operand:TF 0 "register_operand" "=e,e")
4452 (if_then_else:TF (match_operator 1 "comparison_operator"
4453 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4455 (match_operand:TF 3 "register_operand" "e,0")
4456 (match_operand:TF 4 "register_operand" "0,e")))]
4457 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4459 fmovq%C1\\t%x2, %3, %0
4460 fmovq%c1\\t%x2, %4, %0"
4461 [(set_attr "type" "fpcmove")])
4463 (define_insn "*movtf_cc_sp64"
4464 [(set (match_operand:TF 0 "register_operand" "=e,e")
4465 (if_then_else:TF (match_operator 1 "comparison_operator"
4466 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4468 (match_operand:TF 3 "register_operand" "e,0")
4469 (match_operand:TF 4 "register_operand" "0,e")))]
4470 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4472 [(set_attr "length" "2")])
4475 [(set (match_operand:TF 0 "register_operand" "")
4476 (if_then_else:TF (match_operator 1 "comparison_operator"
4477 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4479 (match_operand:TF 3 "register_operand" "")
4480 (match_operand:TF 4 "register_operand" "")))]
4481 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4482 [(clobber (const_int 0))]
4485 rtx set_dest = operands[0];
4486 rtx set_srca = operands[3];
4487 rtx set_srcb = operands[4];
4488 int third = rtx_equal_p (set_dest, set_srca);
4490 rtx srca1, srca2, srcb1, srcb2;
4492 dest1 = gen_df_reg (set_dest, 0);
4493 dest2 = gen_df_reg (set_dest, 1);
4494 srca1 = gen_df_reg (set_srca, 0);
4495 srca2 = gen_df_reg (set_srca, 1);
4496 srcb1 = gen_df_reg (set_srcb, 0);
4497 srcb2 = gen_df_reg (set_srcb, 1);
4499 /* Now emit using the real source and destination we found, swapping
4500 the order if we detect overlap. */
4501 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4502 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4504 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4505 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4509 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4510 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4515 (define_insn "*movqi_cc_reg_sp64"
4516 [(set (match_operand:QI 0 "register_operand" "=r,r")
4517 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4518 [(match_operand:DI 2 "register_operand" "r,r")
4520 (match_operand:QI 3 "arith10_operand" "rM,0")
4521 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4524 movr%D1\\t%2, %r3, %0
4525 movr%d1\\t%2, %r4, %0"
4526 [(set_attr "type" "cmove")])
4528 (define_insn "*movhi_cc_reg_sp64"
4529 [(set (match_operand:HI 0 "register_operand" "=r,r")
4530 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4531 [(match_operand:DI 2 "register_operand" "r,r")
4533 (match_operand:HI 3 "arith10_operand" "rM,0")
4534 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4537 movr%D1\\t%2, %r3, %0
4538 movr%d1\\t%2, %r4, %0"
4539 [(set_attr "type" "cmove")])
4541 (define_insn "*movsi_cc_reg_sp64"
4542 [(set (match_operand:SI 0 "register_operand" "=r,r")
4543 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4544 [(match_operand:DI 2 "register_operand" "r,r")
4546 (match_operand:SI 3 "arith10_operand" "rM,0")
4547 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4550 movr%D1\\t%2, %r3, %0
4551 movr%d1\\t%2, %r4, %0"
4552 [(set_attr "type" "cmove")])
4554 ;; ??? The constraints of operands 3,4 need work.
4555 (define_insn "*movdi_cc_reg_sp64"
4556 [(set (match_operand:DI 0 "register_operand" "=r,r")
4557 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4558 [(match_operand:DI 2 "register_operand" "r,r")
4560 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4561 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4564 movr%D1\\t%2, %r3, %0
4565 movr%d1\\t%2, %r4, %0"
4566 [(set_attr "type" "cmove")])
4568 (define_insn "*movdi_cc_reg_sp64_trunc"
4569 [(set (match_operand:SI 0 "register_operand" "=r,r")
4570 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4571 [(match_operand:DI 2 "register_operand" "r,r")
4573 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4574 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4577 movr%D1\\t%2, %r3, %0
4578 movr%d1\\t%2, %r4, %0"
4579 [(set_attr "type" "cmove")])
4581 (define_insn "*movsf_cc_reg_sp64"
4582 [(set (match_operand:SF 0 "register_operand" "=f,f")
4583 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4584 [(match_operand:DI 2 "register_operand" "r,r")
4586 (match_operand:SF 3 "register_operand" "f,0")
4587 (match_operand:SF 4 "register_operand" "0,f")))]
4588 "TARGET_ARCH64 && TARGET_FPU"
4590 fmovrs%D1\\t%2, %3, %0
4591 fmovrs%d1\\t%2, %4, %0"
4592 [(set_attr "type" "fpcrmove")])
4594 (define_insn "movdf_cc_reg_sp64"
4595 [(set (match_operand:DF 0 "register_operand" "=e,e")
4596 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4597 [(match_operand:DI 2 "register_operand" "r,r")
4599 (match_operand:DF 3 "register_operand" "e,0")
4600 (match_operand:DF 4 "register_operand" "0,e")))]
4601 "TARGET_ARCH64 && TARGET_FPU"
4603 fmovrd%D1\\t%2, %3, %0
4604 fmovrd%d1\\t%2, %4, %0"
4605 [(set_attr "type" "fpcrmove")
4606 (set_attr "fptype" "double")])
4608 (define_insn "*movtf_cc_reg_hq_sp64"
4609 [(set (match_operand:TF 0 "register_operand" "=e,e")
4610 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4611 [(match_operand:DI 2 "register_operand" "r,r")
4613 (match_operand:TF 3 "register_operand" "e,0")
4614 (match_operand:TF 4 "register_operand" "0,e")))]
4615 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4617 fmovrq%D1\\t%2, %3, %0
4618 fmovrq%d1\\t%2, %4, %0"
4619 [(set_attr "type" "fpcrmove")])
4621 (define_insn "*movtf_cc_reg_sp64"
4622 [(set (match_operand:TF 0 "register_operand" "=e,e")
4623 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4624 [(match_operand:DI 2 "register_operand" "r,r")
4626 (match_operand:TF 3 "register_operand" "e,0")
4627 (match_operand:TF 4 "register_operand" "0,e")))]
4628 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4630 [(set_attr "length" "2")])
4633 [(set (match_operand:TF 0 "register_operand" "")
4634 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4635 [(match_operand:DI 2 "register_operand" "")
4637 (match_operand:TF 3 "register_operand" "")
4638 (match_operand:TF 4 "register_operand" "")))]
4639 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4640 [(clobber (const_int 0))]
4643 rtx set_dest = operands[0];
4644 rtx set_srca = operands[3];
4645 rtx set_srcb = operands[4];
4646 int third = rtx_equal_p (set_dest, set_srca);
4648 rtx srca1, srca2, srcb1, srcb2;
4650 dest1 = gen_df_reg (set_dest, 0);
4651 dest2 = gen_df_reg (set_dest, 1);
4652 srca1 = gen_df_reg (set_srca, 0);
4653 srca2 = gen_df_reg (set_srca, 1);
4654 srcb1 = gen_df_reg (set_srcb, 0);
4655 srcb2 = gen_df_reg (set_srcb, 1);
4657 /* Now emit using the real source and destination we found, swapping
4658 the order if we detect overlap. */
4659 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4660 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4662 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4663 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4667 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4668 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4674 ;;- zero extension instructions
4676 ;; These patterns originally accepted general_operands, however, slightly
4677 ;; better code is generated by only accepting register_operands, and then
4678 ;; letting combine generate the ldu[hb] insns.
4680 (define_expand "zero_extendhisi2"
4681 [(set (match_operand:SI 0 "register_operand" "")
4682 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4686 rtx temp = gen_reg_rtx (SImode);
4687 rtx shift_16 = GEN_INT (16);
4688 int op1_subbyte = 0;
4690 if (GET_CODE (operand1) == SUBREG)
4692 op1_subbyte = SUBREG_BYTE (operand1);
4693 op1_subbyte /= GET_MODE_SIZE (SImode);
4694 op1_subbyte *= GET_MODE_SIZE (SImode);
4695 operand1 = XEXP (operand1, 0);
4698 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4700 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4704 (define_insn "*zero_extendhisi2_insn"
4705 [(set (match_operand:SI 0 "register_operand" "=r")
4706 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4709 [(set_attr "type" "load")
4710 (set_attr "us3load_type" "3cycle")])
4712 (define_expand "zero_extendqihi2"
4713 [(set (match_operand:HI 0 "register_operand" "")
4714 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4718 (define_insn "*zero_extendqihi2_insn"
4719 [(set (match_operand:HI 0 "register_operand" "=r,r")
4720 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4721 "GET_CODE (operands[1]) != CONST_INT"
4725 [(set_attr "type" "*,load")
4726 (set_attr "us3load_type" "*,3cycle")])
4728 (define_expand "zero_extendqisi2"
4729 [(set (match_operand:SI 0 "register_operand" "")
4730 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4734 (define_insn "*zero_extendqisi2_insn"
4735 [(set (match_operand:SI 0 "register_operand" "=r,r")
4736 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4737 "GET_CODE (operands[1]) != CONST_INT"
4741 [(set_attr "type" "*,load")
4742 (set_attr "us3load_type" "*,3cycle")])
4744 (define_expand "zero_extendqidi2"
4745 [(set (match_operand:DI 0 "register_operand" "")
4746 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4750 (define_insn "*zero_extendqidi2_insn"
4751 [(set (match_operand:DI 0 "register_operand" "=r,r")
4752 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4753 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4757 [(set_attr "type" "*,load")
4758 (set_attr "us3load_type" "*,3cycle")])
4760 (define_expand "zero_extendhidi2"
4761 [(set (match_operand:DI 0 "register_operand" "")
4762 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4766 rtx temp = gen_reg_rtx (DImode);
4767 rtx shift_48 = GEN_INT (48);
4768 int op1_subbyte = 0;
4770 if (GET_CODE (operand1) == SUBREG)
4772 op1_subbyte = SUBREG_BYTE (operand1);
4773 op1_subbyte /= GET_MODE_SIZE (DImode);
4774 op1_subbyte *= GET_MODE_SIZE (DImode);
4775 operand1 = XEXP (operand1, 0);
4778 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4780 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4784 (define_insn "*zero_extendhidi2_insn"
4785 [(set (match_operand:DI 0 "register_operand" "=r")
4786 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4789 [(set_attr "type" "load")
4790 (set_attr "us3load_type" "3cycle")])
4793 ;; ??? Write truncdisi pattern using sra?
4795 (define_expand "zero_extendsidi2"
4796 [(set (match_operand:DI 0 "register_operand" "")
4797 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4801 (define_insn "*zero_extendsidi2_insn_sp64"
4802 [(set (match_operand:DI 0 "register_operand" "=r,r")
4803 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4804 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4808 [(set_attr "type" "shift,load")])
4810 (define_insn "*zero_extendsidi2_insn_sp32"
4811 [(set (match_operand:DI 0 "register_operand" "=r")
4812 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4815 [(set_attr "length" "2")])
4818 [(set (match_operand:DI 0 "register_operand" "")
4819 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4820 "! TARGET_ARCH64 && reload_completed"
4821 [(set (match_dup 2) (match_dup 3))
4822 (set (match_dup 4) (match_dup 5))]
4827 dest1 = gen_highpart (SImode, operands[0]);
4828 dest2 = gen_lowpart (SImode, operands[0]);
4830 /* Swap the order in case of overlap. */
4831 if (REGNO (dest1) == REGNO (operands[1]))
4833 operands[2] = dest2;
4834 operands[3] = operands[1];
4835 operands[4] = dest1;
4836 operands[5] = const0_rtx;
4840 operands[2] = dest1;
4841 operands[3] = const0_rtx;
4842 operands[4] = dest2;
4843 operands[5] = operands[1];
4847 ;; Simplify comparisons of extended values.
4849 (define_insn "*cmp_zero_extendqisi2"
4851 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4854 "andcc\\t%0, 0xff, %%g0"
4855 [(set_attr "type" "compare")])
4857 (define_insn "*cmp_zero_qi"
4859 (compare:CC (match_operand:QI 0 "register_operand" "r")
4862 "andcc\\t%0, 0xff, %%g0"
4863 [(set_attr "type" "compare")])
4865 (define_insn "*cmp_zero_extendqisi2_set"
4867 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4869 (set (match_operand:SI 0 "register_operand" "=r")
4870 (zero_extend:SI (match_dup 1)))]
4872 "andcc\\t%1, 0xff, %0"
4873 [(set_attr "type" "compare")])
4875 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4877 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4880 (set (match_operand:SI 0 "register_operand" "=r")
4881 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4883 "andcc\\t%1, 0xff, %0"
4884 [(set_attr "type" "compare")])
4886 (define_insn "*cmp_zero_extendqidi2"
4888 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4891 "andcc\\t%0, 0xff, %%g0"
4892 [(set_attr "type" "compare")])
4894 (define_insn "*cmp_zero_qi_sp64"
4896 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4899 "andcc\\t%0, 0xff, %%g0"
4900 [(set_attr "type" "compare")])
4902 (define_insn "*cmp_zero_extendqidi2_set"
4904 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4906 (set (match_operand:DI 0 "register_operand" "=r")
4907 (zero_extend:DI (match_dup 1)))]
4909 "andcc\\t%1, 0xff, %0"
4910 [(set_attr "type" "compare")])
4912 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4914 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4917 (set (match_operand:DI 0 "register_operand" "=r")
4918 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4920 "andcc\\t%1, 0xff, %0"
4921 [(set_attr "type" "compare")])
4923 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4925 (define_insn "*cmp_siqi_trunc"
4927 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4930 "andcc\\t%0, 0xff, %%g0"
4931 [(set_attr "type" "compare")])
4933 (define_insn "*cmp_siqi_trunc_set"
4935 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4937 (set (match_operand:QI 0 "register_operand" "=r")
4938 (subreg:QI (match_dup 1) 3))]
4940 "andcc\\t%1, 0xff, %0"
4941 [(set_attr "type" "compare")])
4943 (define_insn "*cmp_diqi_trunc"
4945 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4948 "andcc\\t%0, 0xff, %%g0"
4949 [(set_attr "type" "compare")])
4951 (define_insn "*cmp_diqi_trunc_set"
4953 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4955 (set (match_operand:QI 0 "register_operand" "=r")
4956 (subreg:QI (match_dup 1) 7))]
4958 "andcc\\t%1, 0xff, %0"
4959 [(set_attr "type" "compare")])
4961 ;;- sign extension instructions
4963 ;; These patterns originally accepted general_operands, however, slightly
4964 ;; better code is generated by only accepting register_operands, and then
4965 ;; letting combine generate the lds[hb] insns.
4967 (define_expand "extendhisi2"
4968 [(set (match_operand:SI 0 "register_operand" "")
4969 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4973 rtx temp = gen_reg_rtx (SImode);
4974 rtx shift_16 = GEN_INT (16);
4975 int op1_subbyte = 0;
4977 if (GET_CODE (operand1) == SUBREG)
4979 op1_subbyte = SUBREG_BYTE (operand1);
4980 op1_subbyte /= GET_MODE_SIZE (SImode);
4981 op1_subbyte *= GET_MODE_SIZE (SImode);
4982 operand1 = XEXP (operand1, 0);
4985 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4987 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4991 (define_insn "*sign_extendhisi2_insn"
4992 [(set (match_operand:SI 0 "register_operand" "=r")
4993 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4996 [(set_attr "type" "sload")
4997 (set_attr "us3load_type" "3cycle")])
4999 (define_expand "extendqihi2"
5000 [(set (match_operand:HI 0 "register_operand" "")
5001 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
5005 rtx temp = gen_reg_rtx (SImode);
5006 rtx shift_24 = GEN_INT (24);
5007 int op1_subbyte = 0;
5008 int op0_subbyte = 0;
5010 if (GET_CODE (operand1) == SUBREG)
5012 op1_subbyte = SUBREG_BYTE (operand1);
5013 op1_subbyte /= GET_MODE_SIZE (SImode);
5014 op1_subbyte *= GET_MODE_SIZE (SImode);
5015 operand1 = XEXP (operand1, 0);
5017 if (GET_CODE (operand0) == SUBREG)
5019 op0_subbyte = SUBREG_BYTE (operand0);
5020 op0_subbyte /= GET_MODE_SIZE (SImode);
5021 op0_subbyte *= GET_MODE_SIZE (SImode);
5022 operand0 = XEXP (operand0, 0);
5024 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
5026 if (GET_MODE (operand0) != SImode)
5027 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
5028 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
5032 (define_insn "*sign_extendqihi2_insn"
5033 [(set (match_operand:HI 0 "register_operand" "=r")
5034 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
5037 [(set_attr "type" "sload")
5038 (set_attr "us3load_type" "3cycle")])
5040 (define_expand "extendqisi2"
5041 [(set (match_operand:SI 0 "register_operand" "")
5042 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5046 rtx temp = gen_reg_rtx (SImode);
5047 rtx shift_24 = GEN_INT (24);
5048 int op1_subbyte = 0;
5050 if (GET_CODE (operand1) == SUBREG)
5052 op1_subbyte = SUBREG_BYTE (operand1);
5053 op1_subbyte /= GET_MODE_SIZE (SImode);
5054 op1_subbyte *= GET_MODE_SIZE (SImode);
5055 operand1 = XEXP (operand1, 0);
5058 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
5060 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
5064 (define_insn "*sign_extendqisi2_insn"
5065 [(set (match_operand:SI 0 "register_operand" "=r")
5066 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
5069 [(set_attr "type" "sload")
5070 (set_attr "us3load_type" "3cycle")])
5072 (define_expand "extendqidi2"
5073 [(set (match_operand:DI 0 "register_operand" "")
5074 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
5078 rtx temp = gen_reg_rtx (DImode);
5079 rtx shift_56 = GEN_INT (56);
5080 int op1_subbyte = 0;
5082 if (GET_CODE (operand1) == SUBREG)
5084 op1_subbyte = SUBREG_BYTE (operand1);
5085 op1_subbyte /= GET_MODE_SIZE (DImode);
5086 op1_subbyte *= GET_MODE_SIZE (DImode);
5087 operand1 = XEXP (operand1, 0);
5090 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
5092 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
5096 (define_insn "*sign_extendqidi2_insn"
5097 [(set (match_operand:DI 0 "register_operand" "=r")
5098 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
5101 [(set_attr "type" "sload")
5102 (set_attr "us3load_type" "3cycle")])
5104 (define_expand "extendhidi2"
5105 [(set (match_operand:DI 0 "register_operand" "")
5106 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
5110 rtx temp = gen_reg_rtx (DImode);
5111 rtx shift_48 = GEN_INT (48);
5112 int op1_subbyte = 0;
5114 if (GET_CODE (operand1) == SUBREG)
5116 op1_subbyte = SUBREG_BYTE (operand1);
5117 op1_subbyte /= GET_MODE_SIZE (DImode);
5118 op1_subbyte *= GET_MODE_SIZE (DImode);
5119 operand1 = XEXP (operand1, 0);
5122 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
5124 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
5128 (define_insn "*sign_extendhidi2_insn"
5129 [(set (match_operand:DI 0 "register_operand" "=r")
5130 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
5133 [(set_attr "type" "sload")
5134 (set_attr "us3load_type" "3cycle")])
5136 (define_expand "extendsidi2"
5137 [(set (match_operand:DI 0 "register_operand" "")
5138 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
5142 (define_insn "*sign_extendsidi2_insn"
5143 [(set (match_operand:DI 0 "register_operand" "=r,r")
5144 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
5149 [(set_attr "type" "shift,sload")
5150 (set_attr "us3load_type" "*,3cycle")])
5152 ;; Special pattern for optimizing bit-field compares. This is needed
5153 ;; because combine uses this as a canonical form.
5155 (define_insn "*cmp_zero_extract"
5158 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
5159 (match_operand:SI 1 "small_int_or_double" "n")
5160 (match_operand:SI 2 "small_int_or_double" "n"))
5162 "(GET_CODE (operands[2]) == CONST_INT
5163 && INTVAL (operands[2]) > 19)
5164 || (GET_CODE (operands[2]) == CONST_DOUBLE
5165 && CONST_DOUBLE_LOW (operands[2]) > 19)"
5168 int len = (GET_CODE (operands[1]) == CONST_INT
5169 ? INTVAL (operands[1])
5170 : CONST_DOUBLE_LOW (operands[1]));
5172 (GET_CODE (operands[2]) == CONST_INT
5173 ? INTVAL (operands[2])
5174 : CONST_DOUBLE_LOW (operands[2])) - len;
5175 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
5177 operands[1] = GEN_INT (mask);
5178 return \"andcc\\t%0, %1, %%g0\";
5180 [(set_attr "type" "compare")])
5182 (define_insn "*cmp_zero_extract_sp64"
5185 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
5186 (match_operand:SI 1 "small_int_or_double" "n")
5187 (match_operand:SI 2 "small_int_or_double" "n"))
5190 && ((GET_CODE (operands[2]) == CONST_INT
5191 && INTVAL (operands[2]) > 51)
5192 || (GET_CODE (operands[2]) == CONST_DOUBLE
5193 && CONST_DOUBLE_LOW (operands[2]) > 51))"
5196 int len = (GET_CODE (operands[1]) == CONST_INT
5197 ? INTVAL (operands[1])
5198 : CONST_DOUBLE_LOW (operands[1]));
5200 (GET_CODE (operands[2]) == CONST_INT
5201 ? INTVAL (operands[2])
5202 : CONST_DOUBLE_LOW (operands[2])) - len;
5203 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5205 operands[1] = GEN_INT (mask);
5206 return \"andcc\\t%0, %1, %%g0\";
5208 [(set_attr "type" "compare")])
5210 ;; Conversions between float, double and long double.
5212 (define_insn "extendsfdf2"
5213 [(set (match_operand:DF 0 "register_operand" "=e")
5215 (match_operand:SF 1 "register_operand" "f")))]
5218 [(set_attr "type" "fp")
5219 (set_attr "fptype" "double")])
5221 (define_expand "extendsftf2"
5222 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5224 (match_operand:SF 1 "register_operand" "")))]
5225 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5226 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
5228 (define_insn "*extendsftf2_hq"
5229 [(set (match_operand:TF 0 "register_operand" "=e")
5231 (match_operand:SF 1 "register_operand" "f")))]
5232 "TARGET_FPU && TARGET_HARD_QUAD"
5234 [(set_attr "type" "fp")])
5236 (define_expand "extenddftf2"
5237 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5239 (match_operand:DF 1 "register_operand" "")))]
5240 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5241 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
5243 (define_insn "*extenddftf2_hq"
5244 [(set (match_operand:TF 0 "register_operand" "=e")
5246 (match_operand:DF 1 "register_operand" "e")))]
5247 "TARGET_FPU && TARGET_HARD_QUAD"
5249 [(set_attr "type" "fp")])
5251 (define_insn "truncdfsf2"
5252 [(set (match_operand:SF 0 "register_operand" "=f")
5254 (match_operand:DF 1 "register_operand" "e")))]
5257 [(set_attr "type" "fp")
5258 (set_attr "fptype" "double")])
5260 (define_expand "trunctfsf2"
5261 [(set (match_operand:SF 0 "register_operand" "")
5263 (match_operand:TF 1 "general_operand" "")))]
5264 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5265 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
5267 (define_insn "*trunctfsf2_hq"
5268 [(set (match_operand:SF 0 "register_operand" "=f")
5270 (match_operand:TF 1 "register_operand" "e")))]
5271 "TARGET_FPU && TARGET_HARD_QUAD"
5273 [(set_attr "type" "fp")])
5275 (define_expand "trunctfdf2"
5276 [(set (match_operand:DF 0 "register_operand" "")
5278 (match_operand:TF 1 "general_operand" "")))]
5279 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5280 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
5282 (define_insn "*trunctfdf2_hq"
5283 [(set (match_operand:DF 0 "register_operand" "=e")
5285 (match_operand:TF 1 "register_operand" "e")))]
5286 "TARGET_FPU && TARGET_HARD_QUAD"
5288 [(set_attr "type" "fp")])
5290 ;; Conversion between fixed point and floating point.
5292 (define_insn "floatsisf2"
5293 [(set (match_operand:SF 0 "register_operand" "=f")
5294 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5297 [(set_attr "type" "fp")
5298 (set_attr "fptype" "double")])
5300 (define_insn "floatsidf2"
5301 [(set (match_operand:DF 0 "register_operand" "=e")
5302 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5305 [(set_attr "type" "fp")
5306 (set_attr "fptype" "double")])
5308 (define_expand "floatsitf2"
5309 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5310 (float:TF (match_operand:SI 1 "register_operand" "")))]
5311 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5312 "emit_tfmode_cvt (FLOAT, operands); DONE;")
5314 (define_insn "*floatsitf2_hq"
5315 [(set (match_operand:TF 0 "register_operand" "=e")
5316 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5317 "TARGET_FPU && TARGET_HARD_QUAD"
5319 [(set_attr "type" "fp")])
5321 (define_expand "floatunssitf2"
5322 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5323 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
5324 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5325 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
5327 ;; Now the same for 64 bit sources.
5329 (define_insn "floatdisf2"
5330 [(set (match_operand:SF 0 "register_operand" "=f")
5331 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5332 "TARGET_V9 && TARGET_FPU"
5334 [(set_attr "type" "fp")
5335 (set_attr "fptype" "double")])
5337 (define_expand "floatunsdisf2"
5338 [(use (match_operand:SF 0 "register_operand" ""))
5339 (use (match_operand:DI 1 "register_operand" ""))]
5340 "TARGET_ARCH64 && TARGET_FPU"
5341 "sparc_emit_floatunsdi (operands); DONE;")
5343 (define_insn "floatdidf2"
5344 [(set (match_operand:DF 0 "register_operand" "=e")
5345 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5346 "TARGET_V9 && TARGET_FPU"
5348 [(set_attr "type" "fp")
5349 (set_attr "fptype" "double")])
5351 (define_expand "floatunsdidf2"
5352 [(use (match_operand:DF 0 "register_operand" ""))
5353 (use (match_operand:DI 1 "register_operand" ""))]
5354 "TARGET_ARCH64 && TARGET_FPU"
5355 "sparc_emit_floatunsdi (operands); DONE;")
5357 (define_expand "floatditf2"
5358 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5359 (float:TF (match_operand:DI 1 "register_operand" "")))]
5360 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5361 "emit_tfmode_cvt (FLOAT, operands); DONE;")
5363 (define_insn "*floatditf2_hq"
5364 [(set (match_operand:TF 0 "register_operand" "=e")
5365 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5366 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5368 [(set_attr "type" "fp")])
5370 (define_expand "floatunsditf2"
5371 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5372 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
5373 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5374 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
5376 ;; Convert a float to an actual integer.
5377 ;; Truncation is performed as part of the conversion.
5379 (define_insn "fix_truncsfsi2"
5380 [(set (match_operand:SI 0 "register_operand" "=f")
5381 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5384 [(set_attr "type" "fp")
5385 (set_attr "fptype" "double")])
5387 (define_insn "fix_truncdfsi2"
5388 [(set (match_operand:SI 0 "register_operand" "=f")
5389 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5392 [(set_attr "type" "fp")
5393 (set_attr "fptype" "double")])
5395 (define_expand "fix_trunctfsi2"
5396 [(set (match_operand:SI 0 "register_operand" "")
5397 (fix:SI (match_operand:TF 1 "general_operand" "")))]
5398 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5399 "emit_tfmode_cvt (FIX, operands); DONE;")
5401 (define_insn "*fix_trunctfsi2_hq"
5402 [(set (match_operand:SI 0 "register_operand" "=f")
5403 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
5404 "TARGET_FPU && TARGET_HARD_QUAD"
5406 [(set_attr "type" "fp")])
5408 (define_expand "fixuns_trunctfsi2"
5409 [(set (match_operand:SI 0 "register_operand" "")
5410 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
5411 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5412 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
5414 ;; Now the same, for V9 targets
5416 (define_insn "fix_truncsfdi2"
5417 [(set (match_operand:DI 0 "register_operand" "=e")
5418 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5419 "TARGET_V9 && TARGET_FPU"
5421 [(set_attr "type" "fp")
5422 (set_attr "fptype" "double")])
5424 (define_insn "fix_truncdfdi2"
5425 [(set (match_operand:DI 0 "register_operand" "=e")
5426 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5427 "TARGET_V9 && TARGET_FPU"
5429 [(set_attr "type" "fp")
5430 (set_attr "fptype" "double")])
5432 (define_expand "fix_trunctfdi2"
5433 [(set (match_operand:DI 0 "register_operand" "")
5434 (fix:DI (match_operand:TF 1 "general_operand" "")))]
5435 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5436 "emit_tfmode_cvt (FIX, operands); DONE;")
5438 (define_insn "*fix_trunctfdi2_hq"
5439 [(set (match_operand:DI 0 "register_operand" "=e")
5440 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
5441 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5443 [(set_attr "type" "fp")])
5445 (define_expand "fixuns_trunctfdi2"
5446 [(set (match_operand:DI 0 "register_operand" "")
5447 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
5448 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5449 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
5451 ;;- arithmetic instructions
5453 (define_expand "adddi3"
5454 [(set (match_operand:DI 0 "register_operand" "=r")
5455 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5456 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5462 if (! TARGET_ARCH64)
5464 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5465 gen_rtx_SET (VOIDmode, operands[0],
5466 gen_rtx_PLUS (DImode, operands[1],
5468 gen_rtx_CLOBBER (VOIDmode,
5469 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5472 if (arith_double_4096_operand(operands[2], DImode))
5474 switch (GET_CODE (operands[1]))
5476 case CONST_INT: i = INTVAL (operands[1]); break;
5477 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5479 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5480 gen_rtx_MINUS (DImode, operands[1],
5484 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5489 (define_insn "adddi3_insn_sp32"
5490 [(set (match_operand:DI 0 "register_operand" "=r")
5491 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5492 (match_operand:DI 2 "arith_double_operand" "rHI")))
5493 (clobber (reg:CC 100))]
5496 [(set_attr "length" "2")])
5499 [(set (match_operand:DI 0 "register_operand" "")
5500 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5501 (match_operand:DI 2 "arith_double_operand" "")))
5502 (clobber (reg:CC 100))]
5503 "! TARGET_ARCH64 && reload_completed"
5504 [(parallel [(set (reg:CC_NOOV 100)
5505 (compare:CC_NOOV (plus:SI (match_dup 4)
5509 (plus:SI (match_dup 4) (match_dup 5)))])
5511 (plus:SI (plus:SI (match_dup 7)
5513 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5516 operands[3] = gen_lowpart (SImode, operands[0]);
5517 operands[4] = gen_lowpart (SImode, operands[1]);
5518 operands[5] = gen_lowpart (SImode, operands[2]);
5519 operands[6] = gen_highpart (SImode, operands[0]);
5520 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5521 #if HOST_BITS_PER_WIDE_INT == 32
5522 if (GET_CODE (operands[2]) == CONST_INT)
5524 if (INTVAL (operands[2]) < 0)
5525 operands[8] = constm1_rtx;
5527 operands[8] = const0_rtx;
5531 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5535 [(set (match_operand:DI 0 "register_operand" "")
5536 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5537 (match_operand:DI 2 "arith_double_operand" "")))
5538 (clobber (reg:CC 100))]
5539 "! TARGET_ARCH64 && reload_completed"
5540 [(parallel [(set (reg:CC_NOOV 100)
5541 (compare:CC_NOOV (minus:SI (match_dup 4)
5545 (minus:SI (match_dup 4) (match_dup 5)))])
5547 (minus:SI (minus:SI (match_dup 7)
5549 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5552 operands[3] = gen_lowpart (SImode, operands[0]);
5553 operands[4] = gen_lowpart (SImode, operands[1]);
5554 operands[5] = gen_lowpart (SImode, operands[2]);
5555 operands[6] = gen_highpart (SImode, operands[0]);
5556 operands[7] = gen_highpart (SImode, operands[1]);
5557 #if HOST_BITS_PER_WIDE_INT == 32
5558 if (GET_CODE (operands[2]) == CONST_INT)
5560 if (INTVAL (operands[2]) < 0)
5561 operands[8] = constm1_rtx;
5563 operands[8] = const0_rtx;
5567 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5570 ;; LTU here means "carry set"
5572 [(set (match_operand:SI 0 "register_operand" "=r")
5573 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5574 (match_operand:SI 2 "arith_operand" "rI"))
5575 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5578 [(set_attr "type" "misc")])
5580 (define_insn "*addx_extend_sp32"
5581 [(set (match_operand:DI 0 "register_operand" "=r")
5582 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5583 (match_operand:SI 2 "arith_operand" "rI"))
5584 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5587 [(set_attr "length" "2")])
5590 [(set (match_operand:DI 0 "register_operand" "")
5591 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5592 (match_operand:SI 2 "arith_operand" ""))
5593 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5594 "! TARGET_ARCH64 && reload_completed"
5595 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5596 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5597 (set (match_dup 4) (const_int 0))]
5598 "operands[3] = gen_lowpart (SImode, operands[0]);
5599 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5601 (define_insn "*addx_extend_sp64"
5602 [(set (match_operand:DI 0 "register_operand" "=r")
5603 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5604 (match_operand:SI 2 "arith_operand" "rI"))
5605 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5607 "addx\\t%r1, %2, %0"
5608 [(set_attr "type" "misc")])
5611 [(set (match_operand:SI 0 "register_operand" "=r")
5612 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5613 (match_operand:SI 2 "arith_operand" "rI"))
5614 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5616 "subx\\t%r1, %2, %0"
5617 [(set_attr "type" "misc")])
5619 (define_insn "*subx_extend_sp64"
5620 [(set (match_operand:DI 0 "register_operand" "=r")
5621 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5622 (match_operand:SI 2 "arith_operand" "rI"))
5623 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5625 "subx\\t%r1, %2, %0"
5626 [(set_attr "type" "misc")])
5628 (define_insn "*subx_extend"
5629 [(set (match_operand:DI 0 "register_operand" "=r")
5630 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5631 (match_operand:SI 2 "arith_operand" "rI"))
5632 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5635 [(set_attr "length" "2")])
5638 [(set (match_operand:DI 0 "register_operand" "")
5639 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5640 (match_operand:SI 2 "arith_operand" ""))
5641 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5642 "! TARGET_ARCH64 && reload_completed"
5643 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5644 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5645 (set (match_dup 4) (const_int 0))]
5646 "operands[3] = gen_lowpart (SImode, operands[0]);
5647 operands[4] = gen_highpart (SImode, operands[0]);")
5650 [(set (match_operand:DI 0 "register_operand" "=r")
5651 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5652 (match_operand:DI 2 "register_operand" "r")))
5653 (clobber (reg:CC 100))]
5656 [(set_attr "length" "2")])
5659 [(set (match_operand:DI 0 "register_operand" "")
5660 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5661 (match_operand:DI 2 "register_operand" "")))
5662 (clobber (reg:CC 100))]
5663 "! TARGET_ARCH64 && reload_completed"
5664 [(parallel [(set (reg:CC_NOOV 100)
5665 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5667 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5669 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5670 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5671 "operands[3] = gen_lowpart (SImode, operands[2]);
5672 operands[4] = gen_highpart (SImode, operands[2]);
5673 operands[5] = gen_lowpart (SImode, operands[0]);
5674 operands[6] = gen_highpart (SImode, operands[0]);")
5676 (define_insn "*adddi3_sp64"
5677 [(set (match_operand:DI 0 "register_operand" "=r")
5678 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5679 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5683 (define_expand "addsi3"
5684 [(set (match_operand:SI 0 "register_operand" "=r,d")
5685 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5686 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5690 if (arith_4096_operand(operands[2], SImode))
5692 if (GET_CODE (operands[1]) == CONST_INT)
5693 emit_insn (gen_movsi (operands[0],
5694 GEN_INT (INTVAL (operands[1]) + 4096)));
5696 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5697 gen_rtx_MINUS (SImode, operands[1],
5703 (define_insn "*addsi3"
5704 [(set (match_operand:SI 0 "register_operand" "=r,d")
5705 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5706 (match_operand:SI 2 "arith_operand" "rI,d")))]
5710 fpadd32s\\t%1, %2, %0"
5711 [(set_attr "type" "*,fp")])
5713 (define_insn "*cmp_cc_plus"
5714 [(set (reg:CC_NOOV 100)
5715 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5716 (match_operand:SI 1 "arith_operand" "rI"))
5719 "addcc\\t%0, %1, %%g0"
5720 [(set_attr "type" "compare")])
5722 (define_insn "*cmp_ccx_plus"
5723 [(set (reg:CCX_NOOV 100)
5724 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5725 (match_operand:DI 1 "arith_double_operand" "rHI"))
5728 "addcc\\t%0, %1, %%g0"
5729 [(set_attr "type" "compare")])
5731 (define_insn "*cmp_cc_plus_set"
5732 [(set (reg:CC_NOOV 100)
5733 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5734 (match_operand:SI 2 "arith_operand" "rI"))
5736 (set (match_operand:SI 0 "register_operand" "=r")
5737 (plus:SI (match_dup 1) (match_dup 2)))]
5739 "addcc\\t%1, %2, %0"
5740 [(set_attr "type" "compare")])
5742 (define_insn "*cmp_ccx_plus_set"
5743 [(set (reg:CCX_NOOV 100)
5744 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5745 (match_operand:DI 2 "arith_double_operand" "rHI"))
5747 (set (match_operand:DI 0 "register_operand" "=r")
5748 (plus:DI (match_dup 1) (match_dup 2)))]
5750 "addcc\\t%1, %2, %0"
5751 [(set_attr "type" "compare")])
5753 (define_expand "subdi3"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5755 (minus:DI (match_operand:DI 1 "register_operand" "r")
5756 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5760 if (! TARGET_ARCH64)
5762 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5763 gen_rtx_SET (VOIDmode, operands[0],
5764 gen_rtx_MINUS (DImode, operands[1],
5766 gen_rtx_CLOBBER (VOIDmode,
5767 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5770 if (arith_double_4096_operand(operands[2], DImode))
5772 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5773 gen_rtx_PLUS (DImode, operands[1],
5779 (define_insn "*subdi3_sp32"
5780 [(set (match_operand:DI 0 "register_operand" "=r")
5781 (minus:DI (match_operand:DI 1 "register_operand" "r")
5782 (match_operand:DI 2 "arith_double_operand" "rHI")))
5783 (clobber (reg:CC 100))]
5786 [(set_attr "length" "2")])
5789 [(set (match_operand:DI 0 "register_operand" "")
5790 (minus:DI (match_operand:DI 1 "register_operand" "")
5791 (match_operand:DI 2 "arith_double_operand" "")))
5792 (clobber (reg:CC 100))]
5795 && (GET_CODE (operands[2]) == CONST_INT
5796 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5797 [(clobber (const_int 0))]
5802 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5803 lowp = gen_lowpart (SImode, operands[2]);
5804 if ((lowp == const0_rtx)
5805 && (operands[0] == operands[1]))
5807 emit_insn (gen_rtx_SET (VOIDmode,
5808 gen_highpart (SImode, operands[0]),
5809 gen_rtx_MINUS (SImode,
5810 gen_highpart_mode (SImode, DImode,
5816 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5817 gen_lowpart (SImode, operands[1]),
5819 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5820 gen_highpart_mode (SImode, DImode, operands[1]),
5827 [(set (match_operand:DI 0 "register_operand" "")
5828 (minus:DI (match_operand:DI 1 "register_operand" "")
5829 (match_operand:DI 2 "register_operand" "")))
5830 (clobber (reg:CC 100))]
5832 && reload_completed"
5833 [(clobber (const_int 0))]
5836 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5837 gen_lowpart (SImode, operands[1]),
5838 gen_lowpart (SImode, operands[2])));
5839 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5840 gen_highpart (SImode, operands[1]),
5841 gen_highpart (SImode, operands[2])));
5846 [(set (match_operand:DI 0 "register_operand" "=r")
5847 (minus:DI (match_operand:DI 1 "register_operand" "r")
5848 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5849 (clobber (reg:CC 100))]
5852 [(set_attr "length" "2")])
5855 [(set (match_operand:DI 0 "register_operand" "")
5856 (minus:DI (match_operand:DI 1 "register_operand" "")
5857 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5858 (clobber (reg:CC 100))]
5859 "! TARGET_ARCH64 && reload_completed"
5860 [(parallel [(set (reg:CC_NOOV 100)
5861 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5863 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5865 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5866 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5867 "operands[3] = gen_lowpart (SImode, operands[1]);
5868 operands[4] = gen_highpart (SImode, operands[1]);
5869 operands[5] = gen_lowpart (SImode, operands[0]);
5870 operands[6] = gen_highpart (SImode, operands[0]);")
5872 (define_insn "*subdi3_sp64"
5873 [(set (match_operand:DI 0 "register_operand" "=r")
5874 (minus:DI (match_operand:DI 1 "register_operand" "r")
5875 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5879 (define_expand "subsi3"
5880 [(set (match_operand:SI 0 "register_operand" "=r,d")
5881 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5882 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5886 if (arith_4096_operand(operands[2], SImode))
5888 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5889 gen_rtx_PLUS (SImode, operands[1],
5895 (define_insn "*subsi3"
5896 [(set (match_operand:SI 0 "register_operand" "=r,d")
5897 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5898 (match_operand:SI 2 "arith_operand" "rI,d")))]
5902 fpsub32s\\t%1, %2, %0"
5903 [(set_attr "type" "*,fp")])
5905 (define_insn "*cmp_minus_cc"
5906 [(set (reg:CC_NOOV 100)
5907 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5908 (match_operand:SI 1 "arith_operand" "rI"))
5911 "subcc\\t%r0, %1, %%g0"
5912 [(set_attr "type" "compare")])
5914 (define_insn "*cmp_minus_ccx"
5915 [(set (reg:CCX_NOOV 100)
5916 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5917 (match_operand:DI 1 "arith_double_operand" "rHI"))
5920 "subcc\\t%0, %1, %%g0"
5921 [(set_attr "type" "compare")])
5923 (define_insn "cmp_minus_cc_set"
5924 [(set (reg:CC_NOOV 100)
5925 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5926 (match_operand:SI 2 "arith_operand" "rI"))
5928 (set (match_operand:SI 0 "register_operand" "=r")
5929 (minus:SI (match_dup 1) (match_dup 2)))]
5931 "subcc\\t%r1, %2, %0"
5932 [(set_attr "type" "compare")])
5934 (define_insn "*cmp_minus_ccx_set"
5935 [(set (reg:CCX_NOOV 100)
5936 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5937 (match_operand:DI 2 "arith_double_operand" "rHI"))
5939 (set (match_operand:DI 0 "register_operand" "=r")
5940 (minus:DI (match_dup 1) (match_dup 2)))]
5942 "subcc\\t%1, %2, %0"
5943 [(set_attr "type" "compare")])
5945 ;; Integer Multiply/Divide.
5947 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5948 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5950 (define_insn "mulsi3"
5951 [(set (match_operand:SI 0 "register_operand" "=r")
5952 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5953 (match_operand:SI 2 "arith_operand" "rI")))]
5956 [(set_attr "type" "imul")])
5958 (define_expand "muldi3"
5959 [(set (match_operand:DI 0 "register_operand" "=r")
5960 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5961 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5962 "TARGET_ARCH64 || TARGET_V8PLUS"
5967 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5972 (define_insn "*muldi3_sp64"
5973 [(set (match_operand:DI 0 "register_operand" "=r")
5974 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5975 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5978 [(set_attr "type" "imul")])
5980 ;; V8plus wide multiply.
5982 (define_insn "muldi3_v8plus"
5983 [(set (match_operand:DI 0 "register_operand" "=r,h")
5984 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5985 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5986 (clobber (match_scratch:SI 3 "=&h,X"))
5987 (clobber (match_scratch:SI 4 "=&h,X"))]
5991 if (sparc_check_64 (operands[1], insn) <= 0)
5992 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5993 if (which_alternative == 1)
5994 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5995 if (GET_CODE (operands[2]) == CONST_INT)
5997 if (which_alternative == 1)
5998 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6000 return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
6002 if (sparc_check_64 (operands[2], insn) <= 0)
6003 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6004 if (which_alternative == 1)
6005 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\";
6007 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\";
6009 [(set_attr "type" "multi")
6010 (set_attr "length" "9,8")])
6012 (define_insn "*cmp_mul_set"
6014 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6015 (match_operand:SI 2 "arith_operand" "rI"))
6017 (set (match_operand:SI 0 "register_operand" "=r")
6018 (mult:SI (match_dup 1) (match_dup 2)))]
6019 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6020 "smulcc\\t%1, %2, %0"
6021 [(set_attr "type" "imul")])
6023 (define_expand "mulsidi3"
6024 [(set (match_operand:DI 0 "register_operand" "")
6025 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6026 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6030 if (CONSTANT_P (operands[2]))
6033 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6036 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6042 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6047 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6048 ;; registers can hold 64 bit values in the V8plus environment.
6050 (define_insn "mulsidi3_v8plus"
6051 [(set (match_operand:DI 0 "register_operand" "=h,r")
6052 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6053 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6054 (clobber (match_scratch:SI 3 "=X,&h"))]
6057 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6058 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6059 [(set_attr "type" "multi")
6060 (set_attr "length" "2,3")])
6063 (define_insn "const_mulsidi3_v8plus"
6064 [(set (match_operand:DI 0 "register_operand" "=h,r")
6065 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6066 (match_operand:SI 2 "small_int" "I,I")))
6067 (clobber (match_scratch:SI 3 "=X,&h"))]
6070 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6071 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6072 [(set_attr "type" "multi")
6073 (set_attr "length" "2,3")])
6076 (define_insn "*mulsidi3_sp32"
6077 [(set (match_operand:DI 0 "register_operand" "=r")
6078 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6079 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6083 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6086 (if_then_else (eq_attr "isa" "sparclet")
6087 (const_string "imul") (const_string "multi")))
6088 (set (attr "length")
6089 (if_then_else (eq_attr "isa" "sparclet")
6090 (const_int 1) (const_int 2)))])
6092 (define_insn "*mulsidi3_sp64"
6093 [(set (match_operand:DI 0 "register_operand" "=r")
6094 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6095 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6096 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6098 [(set_attr "type" "imul")])
6100 ;; Extra pattern, because sign_extend of a constant isn't valid.
6103 (define_insn "const_mulsidi3_sp32"
6104 [(set (match_operand:DI 0 "register_operand" "=r")
6105 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6106 (match_operand:SI 2 "small_int" "I")))]
6110 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6113 (if_then_else (eq_attr "isa" "sparclet")
6114 (const_string "imul") (const_string "multi")))
6115 (set (attr "length")
6116 (if_then_else (eq_attr "isa" "sparclet")
6117 (const_int 1) (const_int 2)))])
6119 (define_insn "const_mulsidi3_sp64"
6120 [(set (match_operand:DI 0 "register_operand" "=r")
6121 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6122 (match_operand:SI 2 "small_int" "I")))]
6123 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6125 [(set_attr "type" "imul")])
6127 (define_expand "smulsi3_highpart"
6128 [(set (match_operand:SI 0 "register_operand" "")
6130 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6131 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6133 "TARGET_HARD_MUL && TARGET_ARCH32"
6136 if (CONSTANT_P (operands[2]))
6140 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6146 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6151 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6152 operands[2], GEN_INT (32)));
6158 (define_insn "smulsi3_highpart_v8plus"
6159 [(set (match_operand:SI 0 "register_operand" "=h,r")
6161 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6162 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6163 (match_operand:SI 3 "const_int_operand" "i,i"))))
6164 (clobber (match_scratch:SI 4 "=X,&h"))]
6167 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6168 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6169 [(set_attr "type" "multi")
6170 (set_attr "length" "2")])
6172 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6175 [(set (match_operand:SI 0 "register_operand" "=h,r")
6178 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6179 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6180 (match_operand:SI 3 "const_int_operand" "i,i"))
6182 (clobber (match_scratch:SI 4 "=X,&h"))]
6185 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6186 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6187 [(set_attr "type" "multi")
6188 (set_attr "length" "2")])
6191 (define_insn "const_smulsi3_highpart_v8plus"
6192 [(set (match_operand:SI 0 "register_operand" "=h,r")
6194 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6195 (match_operand 2 "small_int" "i,i"))
6196 (match_operand:SI 3 "const_int_operand" "i,i"))))
6197 (clobber (match_scratch:SI 4 "=X,&h"))]
6200 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6201 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6202 [(set_attr "type" "multi")
6203 (set_attr "length" "2")])
6206 (define_insn "*smulsi3_highpart_sp32"
6207 [(set (match_operand:SI 0 "register_operand" "=r")
6209 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6210 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6213 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6214 [(set_attr "type" "multi")
6215 (set_attr "length" "2")])
6218 (define_insn "const_smulsi3_highpart"
6219 [(set (match_operand:SI 0 "register_operand" "=r")
6221 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6222 (match_operand:SI 2 "register_operand" "r"))
6225 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6226 [(set_attr "type" "multi")
6227 (set_attr "length" "2")])
6229 (define_expand "umulsidi3"
6230 [(set (match_operand:DI 0 "register_operand" "")
6231 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6232 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6236 if (CONSTANT_P (operands[2]))
6239 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6242 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6248 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6254 (define_insn "umulsidi3_v8plus"
6255 [(set (match_operand:DI 0 "register_operand" "=h,r")
6256 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6257 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6258 (clobber (match_scratch:SI 3 "=X,&h"))]
6261 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6262 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6263 [(set_attr "type" "multi")
6264 (set_attr "length" "2,3")])
6267 (define_insn "*umulsidi3_sp32"
6268 [(set (match_operand:DI 0 "register_operand" "=r")
6269 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6270 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6274 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6277 (if_then_else (eq_attr "isa" "sparclet")
6278 (const_string "imul") (const_string "multi")))
6279 (set (attr "length")
6280 (if_then_else (eq_attr "isa" "sparclet")
6281 (const_int 1) (const_int 2)))])
6283 (define_insn "*umulsidi3_sp64"
6284 [(set (match_operand:DI 0 "register_operand" "=r")
6285 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6286 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6287 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6289 [(set_attr "type" "imul")])
6291 ;; Extra pattern, because sign_extend of a constant isn't valid.
6294 (define_insn "const_umulsidi3_sp32"
6295 [(set (match_operand:DI 0 "register_operand" "=r")
6296 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6297 (match_operand:SI 2 "uns_small_int" "")))]
6301 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6304 (if_then_else (eq_attr "isa" "sparclet")
6305 (const_string "imul") (const_string "multi")))
6306 (set (attr "length")
6307 (if_then_else (eq_attr "isa" "sparclet")
6308 (const_int 1) (const_int 2)))])
6310 (define_insn "const_umulsidi3_sp64"
6311 [(set (match_operand:DI 0 "register_operand" "=r")
6312 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6313 (match_operand:SI 2 "uns_small_int" "")))]
6314 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6316 [(set_attr "type" "imul")])
6319 (define_insn "const_umulsidi3_v8plus"
6320 [(set (match_operand:DI 0 "register_operand" "=h,r")
6321 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6322 (match_operand:SI 2 "uns_small_int" "")))
6323 (clobber (match_scratch:SI 3 "=X,h"))]
6326 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6327 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6328 [(set_attr "type" "multi")
6329 (set_attr "length" "2,3")])
6331 (define_expand "umulsi3_highpart"
6332 [(set (match_operand:SI 0 "register_operand" "")
6334 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6335 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6337 "TARGET_HARD_MUL && TARGET_ARCH32"
6340 if (CONSTANT_P (operands[2]))
6344 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6350 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6355 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6356 operands[2], GEN_INT (32)));
6362 (define_insn "umulsi3_highpart_v8plus"
6363 [(set (match_operand:SI 0 "register_operand" "=h,r")
6365 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6366 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6367 (match_operand:SI 3 "const_int_operand" "i,i"))))
6368 (clobber (match_scratch:SI 4 "=X,h"))]
6371 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6372 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6373 [(set_attr "type" "multi")
6374 (set_attr "length" "2")])
6377 (define_insn "const_umulsi3_highpart_v8plus"
6378 [(set (match_operand:SI 0 "register_operand" "=h,r")
6380 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6381 (match_operand:SI 2 "uns_small_int" ""))
6382 (match_operand:SI 3 "const_int_operand" "i,i"))))
6383 (clobber (match_scratch:SI 4 "=X,h"))]
6386 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6387 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6388 [(set_attr "type" "multi")
6389 (set_attr "length" "2")])
6392 (define_insn "*umulsi3_highpart_sp32"
6393 [(set (match_operand:SI 0 "register_operand" "=r")
6395 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6396 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6399 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6400 [(set_attr "type" "multi")
6401 (set_attr "length" "2")])
6404 (define_insn "const_umulsi3_highpart"
6405 [(set (match_operand:SI 0 "register_operand" "=r")
6407 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6408 (match_operand:SI 2 "uns_small_int" ""))
6411 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6412 [(set_attr "type" "multi")
6413 (set_attr "length" "2")])
6415 ;; The v8 architecture specifies that there must be 3 instructions between
6416 ;; a y register write and a use of it for correct results.
6418 (define_expand "divsi3"
6419 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6420 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6421 (match_operand:SI 2 "input_operand" "rI,m")))
6422 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6423 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6428 operands[3] = gen_reg_rtx(SImode);
6429 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6430 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6436 (define_insn "divsi3_sp32"
6437 [(set (match_operand:SI 0 "register_operand" "=r,r")
6438 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6439 (match_operand:SI 2 "input_operand" "rI,m")))
6440 (clobber (match_scratch:SI 3 "=&r,&r"))]
6441 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6445 if (which_alternative == 0)
6447 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6449 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6452 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6454 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
6456 [(set_attr "type" "multi")
6457 (set (attr "length")
6458 (if_then_else (eq_attr "isa" "v9")
6459 (const_int 4) (const_int 6)))])
6461 (define_insn "divsi3_sp64"
6462 [(set (match_operand:SI 0 "register_operand" "=r")
6463 (div:SI (match_operand:SI 1 "register_operand" "r")
6464 (match_operand:SI 2 "input_operand" "rI")))
6465 (use (match_operand:SI 3 "register_operand" "r"))]
6466 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6467 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6468 [(set_attr "type" "multi")
6469 (set_attr "length" "2")])
6471 (define_insn "divdi3"
6472 [(set (match_operand:DI 0 "register_operand" "=r")
6473 (div:DI (match_operand:DI 1 "register_operand" "r")
6474 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6476 "sdivx\\t%1, %2, %0"
6477 [(set_attr "type" "idiv")])
6479 (define_insn "*cmp_sdiv_cc_set"
6481 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6482 (match_operand:SI 2 "arith_operand" "rI"))
6484 (set (match_operand:SI 0 "register_operand" "=r")
6485 (div:SI (match_dup 1) (match_dup 2)))
6486 (clobber (match_scratch:SI 3 "=&r"))]
6487 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6491 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6493 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6495 [(set_attr "type" "multi")
6496 (set (attr "length")
6497 (if_then_else (eq_attr "isa" "v9")
6498 (const_int 3) (const_int 6)))])
6501 (define_expand "udivsi3"
6502 [(set (match_operand:SI 0 "register_operand" "")
6503 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6504 (match_operand:SI 2 "input_operand" "")))]
6505 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6508 (define_insn "udivsi3_sp32"
6509 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6510 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6511 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6513 || TARGET_DEPRECATED_V8_INSNS)
6517 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6518 switch (which_alternative)
6521 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6523 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6525 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6528 [(set_attr "type" "multi")
6529 (set_attr "length" "5")])
6531 (define_insn "udivsi3_sp64"
6532 [(set (match_operand:SI 0 "register_operand" "=r")
6533 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6534 (match_operand:SI 2 "input_operand" "rI")))]
6535 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6536 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6537 [(set_attr "type" "multi")
6538 (set_attr "length" "2")])
6540 (define_insn "udivdi3"
6541 [(set (match_operand:DI 0 "register_operand" "=r")
6542 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6543 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6545 "udivx\\t%1, %2, %0"
6546 [(set_attr "type" "idiv")])
6548 (define_insn "*cmp_udiv_cc_set"
6550 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6551 (match_operand:SI 2 "arith_operand" "rI"))
6553 (set (match_operand:SI 0 "register_operand" "=r")
6554 (udiv:SI (match_dup 1) (match_dup 2)))]
6556 || TARGET_DEPRECATED_V8_INSNS"
6560 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6562 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6564 [(set_attr "type" "multi")
6565 (set (attr "length")
6566 (if_then_else (eq_attr "isa" "v9")
6567 (const_int 2) (const_int 5)))])
6569 ; sparclet multiply/accumulate insns
6571 (define_insn "*smacsi"
6572 [(set (match_operand:SI 0 "register_operand" "=r")
6573 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6574 (match_operand:SI 2 "arith_operand" "rI"))
6575 (match_operand:SI 3 "register_operand" "0")))]
6578 [(set_attr "type" "imul")])
6580 (define_insn "*smacdi"
6581 [(set (match_operand:DI 0 "register_operand" "=r")
6582 (plus:DI (mult:DI (sign_extend:DI
6583 (match_operand:SI 1 "register_operand" "%r"))
6585 (match_operand:SI 2 "register_operand" "r")))
6586 (match_operand:DI 3 "register_operand" "0")))]
6588 "smacd\\t%1, %2, %L0"
6589 [(set_attr "type" "imul")])
6591 (define_insn "*umacdi"
6592 [(set (match_operand:DI 0 "register_operand" "=r")
6593 (plus:DI (mult:DI (zero_extend:DI
6594 (match_operand:SI 1 "register_operand" "%r"))
6596 (match_operand:SI 2 "register_operand" "r")))
6597 (match_operand:DI 3 "register_operand" "0")))]
6599 "umacd\\t%1, %2, %L0"
6600 [(set_attr "type" "imul")])
6602 ;;- Boolean instructions
6603 ;; We define DImode `and' so with DImode `not' we can get
6604 ;; DImode `andn'. Other combinations are possible.
6606 (define_expand "anddi3"
6607 [(set (match_operand:DI 0 "register_operand" "")
6608 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6609 (match_operand:DI 2 "arith_double_operand" "")))]
6613 (define_insn "*anddi3_sp32"
6614 [(set (match_operand:DI 0 "register_operand" "=r,b")
6615 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6616 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6621 [(set_attr "type" "*,fp")
6622 (set_attr "length" "2,*")
6623 (set_attr "fptype" "double")])
6625 (define_insn "*anddi3_sp64"
6626 [(set (match_operand:DI 0 "register_operand" "=r,b")
6627 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6628 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6633 [(set_attr "type" "*,fp")
6634 (set_attr "fptype" "double")])
6636 (define_insn "andsi3"
6637 [(set (match_operand:SI 0 "register_operand" "=r,d")
6638 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6639 (match_operand:SI 2 "arith_operand" "rI,d")))]
6644 [(set_attr "type" "*,fp")])
6647 [(set (match_operand:SI 0 "register_operand" "")
6648 (and:SI (match_operand:SI 1 "register_operand" "")
6649 (match_operand:SI 2 "" "")))
6650 (clobber (match_operand:SI 3 "register_operand" ""))]
6651 "GET_CODE (operands[2]) == CONST_INT
6652 && !SMALL_INT32 (operands[2])
6653 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6654 [(set (match_dup 3) (match_dup 4))
6655 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6658 operands[4] = GEN_INT (~INTVAL (operands[2]));
6661 ;; Split DImode logical operations requiring two instructions.
6663 [(set (match_operand:DI 0 "register_operand" "")
6664 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6665 [(match_operand:DI 2 "register_operand" "")
6666 (match_operand:DI 3 "arith_double_operand" "")]))]
6669 && ((GET_CODE (operands[0]) == REG
6670 && REGNO (operands[0]) < 32)
6671 || (GET_CODE (operands[0]) == SUBREG
6672 && GET_CODE (SUBREG_REG (operands[0])) == REG
6673 && REGNO (SUBREG_REG (operands[0])) < 32))"
6674 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6675 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6678 operands[4] = gen_highpart (SImode, operands[0]);
6679 operands[5] = gen_lowpart (SImode, operands[0]);
6680 operands[6] = gen_highpart (SImode, operands[2]);
6681 operands[7] = gen_lowpart (SImode, operands[2]);
6682 #if HOST_BITS_PER_WIDE_INT == 32
6683 if (GET_CODE (operands[3]) == CONST_INT)
6685 if (INTVAL (operands[3]) < 0)
6686 operands[8] = constm1_rtx;
6688 operands[8] = const0_rtx;
6692 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6693 operands[9] = gen_lowpart (SImode, operands[3]);
6696 (define_insn "*and_not_di_sp32"
6697 [(set (match_operand:DI 0 "register_operand" "=r,b")
6698 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6699 (match_operand:DI 2 "register_operand" "r,b")))]
6703 fandnot1\\t%1, %2, %0"
6704 [(set_attr "type" "*,fp")
6705 (set_attr "length" "2,*")
6706 (set_attr "fptype" "double")])
6709 [(set (match_operand:DI 0 "register_operand" "")
6710 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6711 (match_operand:DI 2 "register_operand" "")))]
6714 && ((GET_CODE (operands[0]) == REG
6715 && REGNO (operands[0]) < 32)
6716 || (GET_CODE (operands[0]) == SUBREG
6717 && GET_CODE (SUBREG_REG (operands[0])) == REG
6718 && REGNO (SUBREG_REG (operands[0])) < 32))"
6719 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6720 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6721 "operands[3] = gen_highpart (SImode, operands[0]);
6722 operands[4] = gen_highpart (SImode, operands[1]);
6723 operands[5] = gen_highpart (SImode, operands[2]);
6724 operands[6] = gen_lowpart (SImode, operands[0]);
6725 operands[7] = gen_lowpart (SImode, operands[1]);
6726 operands[8] = gen_lowpart (SImode, operands[2]);")
6728 (define_insn "*and_not_di_sp64"
6729 [(set (match_operand:DI 0 "register_operand" "=r,b")
6730 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6731 (match_operand:DI 2 "register_operand" "r,b")))]
6735 fandnot1\\t%1, %2, %0"
6736 [(set_attr "type" "*,fp")
6737 (set_attr "fptype" "double")])
6739 (define_insn "*and_not_si"
6740 [(set (match_operand:SI 0 "register_operand" "=r,d")
6741 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6742 (match_operand:SI 2 "register_operand" "r,d")))]
6746 fandnot1s\\t%1, %2, %0"
6747 [(set_attr "type" "*,fp")])
6749 (define_expand "iordi3"
6750 [(set (match_operand:DI 0 "register_operand" "")
6751 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6752 (match_operand:DI 2 "arith_double_operand" "")))]
6756 (define_insn "*iordi3_sp32"
6757 [(set (match_operand:DI 0 "register_operand" "=r,b")
6758 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6759 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6764 [(set_attr "type" "*,fp")
6765 (set_attr "length" "2,*")
6766 (set_attr "fptype" "double")])
6768 (define_insn "*iordi3_sp64"
6769 [(set (match_operand:DI 0 "register_operand" "=r,b")
6770 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6771 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6776 [(set_attr "type" "*,fp")
6777 (set_attr "fptype" "double")])
6779 (define_insn "iorsi3"
6780 [(set (match_operand:SI 0 "register_operand" "=r,d")
6781 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6782 (match_operand:SI 2 "arith_operand" "rI,d")))]
6787 [(set_attr "type" "*,fp")])
6790 [(set (match_operand:SI 0 "register_operand" "")
6791 (ior:SI (match_operand:SI 1 "register_operand" "")
6792 (match_operand:SI 2 "" "")))
6793 (clobber (match_operand:SI 3 "register_operand" ""))]
6794 "GET_CODE (operands[2]) == CONST_INT
6795 && !SMALL_INT32 (operands[2])
6796 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6797 [(set (match_dup 3) (match_dup 4))
6798 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6801 operands[4] = GEN_INT (~INTVAL (operands[2]));
6804 (define_insn "*or_not_di_sp32"
6805 [(set (match_operand:DI 0 "register_operand" "=r,b")
6806 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6807 (match_operand:DI 2 "register_operand" "r,b")))]
6811 fornot1\\t%1, %2, %0"
6812 [(set_attr "type" "*,fp")
6813 (set_attr "length" "2,*")
6814 (set_attr "fptype" "double")])
6817 [(set (match_operand:DI 0 "register_operand" "")
6818 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6819 (match_operand:DI 2 "register_operand" "")))]
6822 && ((GET_CODE (operands[0]) == REG
6823 && REGNO (operands[0]) < 32)
6824 || (GET_CODE (operands[0]) == SUBREG
6825 && GET_CODE (SUBREG_REG (operands[0])) == REG
6826 && REGNO (SUBREG_REG (operands[0])) < 32))"
6827 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6828 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6829 "operands[3] = gen_highpart (SImode, operands[0]);
6830 operands[4] = gen_highpart (SImode, operands[1]);
6831 operands[5] = gen_highpart (SImode, operands[2]);
6832 operands[6] = gen_lowpart (SImode, operands[0]);
6833 operands[7] = gen_lowpart (SImode, operands[1]);
6834 operands[8] = gen_lowpart (SImode, operands[2]);")
6836 (define_insn "*or_not_di_sp64"
6837 [(set (match_operand:DI 0 "register_operand" "=r,b")
6838 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6839 (match_operand:DI 2 "register_operand" "r,b")))]
6843 fornot1\\t%1, %2, %0"
6844 [(set_attr "type" "*,fp")
6845 (set_attr "fptype" "double")])
6847 (define_insn "*or_not_si"
6848 [(set (match_operand:SI 0 "register_operand" "=r,d")
6849 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6850 (match_operand:SI 2 "register_operand" "r,d")))]
6854 fornot1s\\t%1, %2, %0"
6855 [(set_attr "type" "*,fp")])
6857 (define_expand "xordi3"
6858 [(set (match_operand:DI 0 "register_operand" "")
6859 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6860 (match_operand:DI 2 "arith_double_operand" "")))]
6864 (define_insn "*xordi3_sp32"
6865 [(set (match_operand:DI 0 "register_operand" "=r,b")
6866 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6867 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6872 [(set_attr "type" "*,fp")
6873 (set_attr "length" "2,*")
6874 (set_attr "fptype" "double")])
6876 (define_insn "*xordi3_sp64"
6877 [(set (match_operand:DI 0 "register_operand" "=r,b")
6878 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6879 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6884 [(set_attr "type" "*,fp")
6885 (set_attr "fptype" "double")])
6887 (define_insn "*xordi3_sp64_dbl"
6888 [(set (match_operand:DI 0 "register_operand" "=r")
6889 (xor:DI (match_operand:DI 1 "register_operand" "r")
6890 (match_operand:DI 2 "const64_operand" "")))]
6892 && HOST_BITS_PER_WIDE_INT != 64)"
6895 (define_insn "xorsi3"
6896 [(set (match_operand:SI 0 "register_operand" "=r,d")
6897 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6898 (match_operand:SI 2 "arith_operand" "rI,d")))]
6903 [(set_attr "type" "*,fp")])
6906 [(set (match_operand:SI 0 "register_operand" "")
6907 (xor:SI (match_operand:SI 1 "register_operand" "")
6908 (match_operand:SI 2 "" "")))
6909 (clobber (match_operand:SI 3 "register_operand" ""))]
6910 "GET_CODE (operands[2]) == CONST_INT
6911 && !SMALL_INT32 (operands[2])
6912 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6913 [(set (match_dup 3) (match_dup 4))
6914 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6917 operands[4] = GEN_INT (~INTVAL (operands[2]));
6921 [(set (match_operand:SI 0 "register_operand" "")
6922 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6923 (match_operand:SI 2 "" ""))))
6924 (clobber (match_operand:SI 3 "register_operand" ""))]
6925 "GET_CODE (operands[2]) == CONST_INT
6926 && !SMALL_INT32 (operands[2])
6927 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6928 [(set (match_dup 3) (match_dup 4))
6929 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6932 operands[4] = GEN_INT (~INTVAL (operands[2]));
6935 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6936 ;; Combine now canonicalizes to the rightmost expression.
6937 (define_insn "*xor_not_di_sp32"
6938 [(set (match_operand:DI 0 "register_operand" "=r,b")
6939 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6940 (match_operand:DI 2 "register_operand" "r,b"))))]
6945 [(set_attr "type" "*,fp")
6946 (set_attr "length" "2,*")
6947 (set_attr "fptype" "double")])
6950 [(set (match_operand:DI 0 "register_operand" "")
6951 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6952 (match_operand:DI 2 "register_operand" ""))))]
6955 && ((GET_CODE (operands[0]) == REG
6956 && REGNO (operands[0]) < 32)
6957 || (GET_CODE (operands[0]) == SUBREG
6958 && GET_CODE (SUBREG_REG (operands[0])) == REG
6959 && REGNO (SUBREG_REG (operands[0])) < 32))"
6960 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6961 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6962 "operands[3] = gen_highpart (SImode, operands[0]);
6963 operands[4] = gen_highpart (SImode, operands[1]);
6964 operands[5] = gen_highpart (SImode, operands[2]);
6965 operands[6] = gen_lowpart (SImode, operands[0]);
6966 operands[7] = gen_lowpart (SImode, operands[1]);
6967 operands[8] = gen_lowpart (SImode, operands[2]);")
6969 (define_insn "*xor_not_di_sp64"
6970 [(set (match_operand:DI 0 "register_operand" "=r,b")
6971 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6972 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6977 [(set_attr "type" "*,fp")
6978 (set_attr "fptype" "double")])
6980 (define_insn "*xor_not_si"
6981 [(set (match_operand:SI 0 "register_operand" "=r,d")
6982 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6983 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6987 fxnors\\t%1, %2, %0"
6988 [(set_attr "type" "*,fp")])
6990 ;; These correspond to the above in the case where we also (or only)
6991 ;; want to set the condition code.
6993 (define_insn "*cmp_cc_arith_op"
6996 (match_operator:SI 2 "cc_arithop"
6997 [(match_operand:SI 0 "arith_operand" "%r")
6998 (match_operand:SI 1 "arith_operand" "rI")])
7001 "%A2cc\\t%0, %1, %%g0"
7002 [(set_attr "type" "compare")])
7004 (define_insn "*cmp_ccx_arith_op"
7007 (match_operator:DI 2 "cc_arithop"
7008 [(match_operand:DI 0 "arith_double_operand" "%r")
7009 (match_operand:DI 1 "arith_double_operand" "rHI")])
7012 "%A2cc\\t%0, %1, %%g0"
7013 [(set_attr "type" "compare")])
7015 (define_insn "*cmp_cc_arith_op_set"
7018 (match_operator:SI 3 "cc_arithop"
7019 [(match_operand:SI 1 "arith_operand" "%r")
7020 (match_operand:SI 2 "arith_operand" "rI")])
7022 (set (match_operand:SI 0 "register_operand" "=r")
7023 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7024 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7025 "%A3cc\\t%1, %2, %0"
7026 [(set_attr "type" "compare")])
7028 (define_insn "*cmp_ccx_arith_op_set"
7031 (match_operator:DI 3 "cc_arithop"
7032 [(match_operand:DI 1 "arith_double_operand" "%r")
7033 (match_operand:DI 2 "arith_double_operand" "rHI")])
7035 (set (match_operand:DI 0 "register_operand" "=r")
7036 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7037 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7038 "%A3cc\\t%1, %2, %0"
7039 [(set_attr "type" "compare")])
7041 (define_insn "*cmp_cc_xor_not"
7044 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7045 (match_operand:SI 1 "arith_operand" "rI")))
7048 "xnorcc\\t%r0, %1, %%g0"
7049 [(set_attr "type" "compare")])
7051 (define_insn "*cmp_ccx_xor_not"
7054 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7055 (match_operand:DI 1 "arith_double_operand" "rHI")))
7058 "xnorcc\\t%r0, %1, %%g0"
7059 [(set_attr "type" "compare")])
7061 (define_insn "*cmp_cc_xor_not_set"
7064 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7065 (match_operand:SI 2 "arith_operand" "rI")))
7067 (set (match_operand:SI 0 "register_operand" "=r")
7068 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7070 "xnorcc\\t%r1, %2, %0"
7071 [(set_attr "type" "compare")])
7073 (define_insn "*cmp_ccx_xor_not_set"
7076 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7077 (match_operand:DI 2 "arith_double_operand" "rHI")))
7079 (set (match_operand:DI 0 "register_operand" "=r")
7080 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7082 "xnorcc\\t%r1, %2, %0"
7083 [(set_attr "type" "compare")])
7085 (define_insn "*cmp_cc_arith_op_not"
7088 (match_operator:SI 2 "cc_arithopn"
7089 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7090 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7093 "%B2cc\\t%r1, %0, %%g0"
7094 [(set_attr "type" "compare")])
7096 (define_insn "*cmp_ccx_arith_op_not"
7099 (match_operator:DI 2 "cc_arithopn"
7100 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7101 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7104 "%B2cc\\t%r1, %0, %%g0"
7105 [(set_attr "type" "compare")])
7107 (define_insn "*cmp_cc_arith_op_not_set"
7110 (match_operator:SI 3 "cc_arithopn"
7111 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7112 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7114 (set (match_operand:SI 0 "register_operand" "=r")
7115 (match_operator:SI 4 "cc_arithopn"
7116 [(not:SI (match_dup 1)) (match_dup 2)]))]
7117 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7118 "%B3cc\\t%r2, %1, %0"
7119 [(set_attr "type" "compare")])
7121 (define_insn "*cmp_ccx_arith_op_not_set"
7124 (match_operator:DI 3 "cc_arithopn"
7125 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7126 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7128 (set (match_operand:DI 0 "register_operand" "=r")
7129 (match_operator:DI 4 "cc_arithopn"
7130 [(not:DI (match_dup 1)) (match_dup 2)]))]
7131 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7132 "%B3cc\\t%r2, %1, %0"
7133 [(set_attr "type" "compare")])
7135 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7136 ;; does not know how to make it work for constants.
7138 (define_expand "negdi2"
7139 [(set (match_operand:DI 0 "register_operand" "=r")
7140 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7144 if (! TARGET_ARCH64)
7146 emit_insn (gen_rtx_PARALLEL
7149 gen_rtx_SET (VOIDmode, operand0,
7150 gen_rtx_NEG (DImode, operand1)),
7151 gen_rtx_CLOBBER (VOIDmode,
7152 gen_rtx_REG (CCmode,
7158 (define_insn "*negdi2_sp32"
7159 [(set (match_operand:DI 0 "register_operand" "=r")
7160 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7161 (clobber (reg:CC 100))]
7164 [(set_attr "length" "2")])
7167 [(set (match_operand:DI 0 "register_operand" "")
7168 (neg:DI (match_operand:DI 1 "register_operand" "")))
7169 (clobber (reg:CC 100))]
7171 && reload_completed"
7172 [(parallel [(set (reg:CC_NOOV 100)
7173 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7175 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7176 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7177 (ltu:SI (reg:CC 100) (const_int 0))))]
7178 "operands[2] = gen_highpart (SImode, operands[0]);
7179 operands[3] = gen_highpart (SImode, operands[1]);
7180 operands[4] = gen_lowpart (SImode, operands[0]);
7181 operands[5] = gen_lowpart (SImode, operands[1]);")
7183 (define_insn "*negdi2_sp64"
7184 [(set (match_operand:DI 0 "register_operand" "=r")
7185 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7187 "sub\\t%%g0, %1, %0")
7189 (define_insn "negsi2"
7190 [(set (match_operand:SI 0 "register_operand" "=r")
7191 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7193 "sub\\t%%g0, %1, %0")
7195 (define_insn "*cmp_cc_neg"
7196 [(set (reg:CC_NOOV 100)
7197 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7200 "subcc\\t%%g0, %0, %%g0"
7201 [(set_attr "type" "compare")])
7203 (define_insn "*cmp_ccx_neg"
7204 [(set (reg:CCX_NOOV 100)
7205 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7208 "subcc\\t%%g0, %0, %%g0"
7209 [(set_attr "type" "compare")])
7211 (define_insn "*cmp_cc_set_neg"
7212 [(set (reg:CC_NOOV 100)
7213 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7215 (set (match_operand:SI 0 "register_operand" "=r")
7216 (neg:SI (match_dup 1)))]
7218 "subcc\\t%%g0, %1, %0"
7219 [(set_attr "type" "compare")])
7221 (define_insn "*cmp_ccx_set_neg"
7222 [(set (reg:CCX_NOOV 100)
7223 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7225 (set (match_operand:DI 0 "register_operand" "=r")
7226 (neg:DI (match_dup 1)))]
7228 "subcc\\t%%g0, %1, %0"
7229 [(set_attr "type" "compare")])
7231 ;; We cannot use the "not" pseudo insn because the Sun assembler
7232 ;; does not know how to make it work for constants.
7233 (define_expand "one_cmpldi2"
7234 [(set (match_operand:DI 0 "register_operand" "")
7235 (not:DI (match_operand:DI 1 "register_operand" "")))]
7239 (define_insn "*one_cmpldi2_sp32"
7240 [(set (match_operand:DI 0 "register_operand" "=r,b")
7241 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7246 [(set_attr "type" "*,fp")
7247 (set_attr "length" "2,*")
7248 (set_attr "fptype" "double")])
7251 [(set (match_operand:DI 0 "register_operand" "")
7252 (not:DI (match_operand:DI 1 "register_operand" "")))]
7255 && ((GET_CODE (operands[0]) == REG
7256 && REGNO (operands[0]) < 32)
7257 || (GET_CODE (operands[0]) == SUBREG
7258 && GET_CODE (SUBREG_REG (operands[0])) == REG
7259 && REGNO (SUBREG_REG (operands[0])) < 32))"
7260 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7261 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7262 "operands[2] = gen_highpart (SImode, operands[0]);
7263 operands[3] = gen_highpart (SImode, operands[1]);
7264 operands[4] = gen_lowpart (SImode, operands[0]);
7265 operands[5] = gen_lowpart (SImode, operands[1]);")
7267 (define_insn "*one_cmpldi2_sp64"
7268 [(set (match_operand:DI 0 "register_operand" "=r,b")
7269 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7274 [(set_attr "type" "*,fp")
7275 (set_attr "fptype" "double")])
7277 (define_insn "one_cmplsi2"
7278 [(set (match_operand:SI 0 "register_operand" "=r,d")
7279 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7284 [(set_attr "type" "*,fp")])
7286 (define_insn "*cmp_cc_not"
7288 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7291 "xnorcc\\t%%g0, %0, %%g0"
7292 [(set_attr "type" "compare")])
7294 (define_insn "*cmp_ccx_not"
7296 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7299 "xnorcc\\t%%g0, %0, %%g0"
7300 [(set_attr "type" "compare")])
7302 (define_insn "*cmp_cc_set_not"
7304 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7306 (set (match_operand:SI 0 "register_operand" "=r")
7307 (not:SI (match_dup 1)))]
7309 "xnorcc\\t%%g0, %1, %0"
7310 [(set_attr "type" "compare")])
7312 (define_insn "*cmp_ccx_set_not"
7314 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7316 (set (match_operand:DI 0 "register_operand" "=r")
7317 (not:DI (match_dup 1)))]
7319 "xnorcc\\t%%g0, %1, %0"
7320 [(set_attr "type" "compare")])
7322 (define_insn "*cmp_cc_set"
7323 [(set (match_operand:SI 0 "register_operand" "=r")
7324 (match_operand:SI 1 "register_operand" "r"))
7326 (compare:CC (match_dup 1)
7330 [(set_attr "type" "compare")])
7332 (define_insn "*cmp_ccx_set64"
7333 [(set (match_operand:DI 0 "register_operand" "=r")
7334 (match_operand:DI 1 "register_operand" "r"))
7336 (compare:CCX (match_dup 1)
7340 [(set_attr "type" "compare")])
7342 ;; Floating point arithmetic instructions.
7344 (define_expand "addtf3"
7345 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7346 (plus:TF (match_operand:TF 1 "general_operand" "")
7347 (match_operand:TF 2 "general_operand" "")))]
7348 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7349 "emit_tfmode_binop (PLUS, operands); DONE;")
7351 (define_insn "*addtf3_hq"
7352 [(set (match_operand:TF 0 "register_operand" "=e")
7353 (plus:TF (match_operand:TF 1 "register_operand" "e")
7354 (match_operand:TF 2 "register_operand" "e")))]
7355 "TARGET_FPU && TARGET_HARD_QUAD"
7356 "faddq\\t%1, %2, %0"
7357 [(set_attr "type" "fp")])
7359 (define_insn "adddf3"
7360 [(set (match_operand:DF 0 "register_operand" "=e")
7361 (plus:DF (match_operand:DF 1 "register_operand" "e")
7362 (match_operand:DF 2 "register_operand" "e")))]
7364 "faddd\\t%1, %2, %0"
7365 [(set_attr "type" "fp")
7366 (set_attr "fptype" "double")])
7368 (define_insn "addsf3"
7369 [(set (match_operand:SF 0 "register_operand" "=f")
7370 (plus:SF (match_operand:SF 1 "register_operand" "f")
7371 (match_operand:SF 2 "register_operand" "f")))]
7373 "fadds\\t%1, %2, %0"
7374 [(set_attr "type" "fp")])
7376 (define_expand "subtf3"
7377 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7378 (minus:TF (match_operand:TF 1 "general_operand" "")
7379 (match_operand:TF 2 "general_operand" "")))]
7380 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7381 "emit_tfmode_binop (MINUS, operands); DONE;")
7383 (define_insn "*subtf3_hq"
7384 [(set (match_operand:TF 0 "register_operand" "=e")
7385 (minus:TF (match_operand:TF 1 "register_operand" "e")
7386 (match_operand:TF 2 "register_operand" "e")))]
7387 "TARGET_FPU && TARGET_HARD_QUAD"
7388 "fsubq\\t%1, %2, %0"
7389 [(set_attr "type" "fp")])
7391 (define_insn "subdf3"
7392 [(set (match_operand:DF 0 "register_operand" "=e")
7393 (minus:DF (match_operand:DF 1 "register_operand" "e")
7394 (match_operand:DF 2 "register_operand" "e")))]
7396 "fsubd\\t%1, %2, %0"
7397 [(set_attr "type" "fp")
7398 (set_attr "fptype" "double")])
7400 (define_insn "subsf3"
7401 [(set (match_operand:SF 0 "register_operand" "=f")
7402 (minus:SF (match_operand:SF 1 "register_operand" "f")
7403 (match_operand:SF 2 "register_operand" "f")))]
7405 "fsubs\\t%1, %2, %0"
7406 [(set_attr "type" "fp")])
7408 (define_expand "multf3"
7409 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7410 (mult:TF (match_operand:TF 1 "general_operand" "")
7411 (match_operand:TF 2 "general_operand" "")))]
7412 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7413 "emit_tfmode_binop (MULT, operands); DONE;")
7415 (define_insn "*multf3_hq"
7416 [(set (match_operand:TF 0 "register_operand" "=e")
7417 (mult:TF (match_operand:TF 1 "register_operand" "e")
7418 (match_operand:TF 2 "register_operand" "e")))]
7419 "TARGET_FPU && TARGET_HARD_QUAD"
7420 "fmulq\\t%1, %2, %0"
7421 [(set_attr "type" "fpmul")])
7423 (define_insn "muldf3"
7424 [(set (match_operand:DF 0 "register_operand" "=e")
7425 (mult:DF (match_operand:DF 1 "register_operand" "e")
7426 (match_operand:DF 2 "register_operand" "e")))]
7428 "fmuld\\t%1, %2, %0"
7429 [(set_attr "type" "fpmul")
7430 (set_attr "fptype" "double")])
7432 (define_insn "mulsf3"
7433 [(set (match_operand:SF 0 "register_operand" "=f")
7434 (mult:SF (match_operand:SF 1 "register_operand" "f")
7435 (match_operand:SF 2 "register_operand" "f")))]
7437 "fmuls\\t%1, %2, %0"
7438 [(set_attr "type" "fpmul")])
7440 (define_insn "*muldf3_extend"
7441 [(set (match_operand:DF 0 "register_operand" "=e")
7442 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7443 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7444 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7445 "fsmuld\\t%1, %2, %0"
7446 [(set_attr "type" "fpmul")
7447 (set_attr "fptype" "double")])
7449 (define_insn "*multf3_extend"
7450 [(set (match_operand:TF 0 "register_operand" "=e")
7451 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7452 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7453 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7454 "fdmulq\\t%1, %2, %0"
7455 [(set_attr "type" "fpmul")])
7457 (define_expand "divtf3"
7458 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7459 (div:TF (match_operand:TF 1 "general_operand" "")
7460 (match_operand:TF 2 "general_operand" "")))]
7461 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7462 "emit_tfmode_binop (DIV, operands); DONE;")
7464 ;; don't have timing for quad-prec. divide.
7465 (define_insn "*divtf3_hq"
7466 [(set (match_operand:TF 0 "register_operand" "=e")
7467 (div:TF (match_operand:TF 1 "register_operand" "e")
7468 (match_operand:TF 2 "register_operand" "e")))]
7469 "TARGET_FPU && TARGET_HARD_QUAD"
7470 "fdivq\\t%1, %2, %0"
7471 [(set_attr "type" "fpdivd")])
7473 (define_insn "divdf3"
7474 [(set (match_operand:DF 0 "register_operand" "=e")
7475 (div:DF (match_operand:DF 1 "register_operand" "e")
7476 (match_operand:DF 2 "register_operand" "e")))]
7478 "fdivd\\t%1, %2, %0"
7479 [(set_attr "type" "fpdivd")
7480 (set_attr "fptype" "double")])
7482 (define_insn "divsf3"
7483 [(set (match_operand:SF 0 "register_operand" "=f")
7484 (div:SF (match_operand:SF 1 "register_operand" "f")
7485 (match_operand:SF 2 "register_operand" "f")))]
7487 "fdivs\\t%1, %2, %0"
7488 [(set_attr "type" "fpdivs")])
7490 (define_expand "negtf2"
7491 [(set (match_operand:TF 0 "register_operand" "=e,e")
7492 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7496 (define_insn "*negtf2_notv9"
7497 [(set (match_operand:TF 0 "register_operand" "=e,e")
7498 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7499 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7505 [(set_attr "type" "fpmove,*")
7506 (set_attr "length" "*,2")])
7509 [(set (match_operand:TF 0 "register_operand" "")
7510 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7514 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7515 [(set (match_dup 2) (neg:SF (match_dup 3)))
7516 (set (match_dup 4) (match_dup 5))
7517 (set (match_dup 6) (match_dup 7))]
7518 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7519 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7520 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7521 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7522 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7523 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7525 (define_insn "*negtf2_v9"
7526 [(set (match_operand:TF 0 "register_operand" "=e,e")
7527 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7528 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7529 "TARGET_FPU && TARGET_V9"
7533 [(set_attr "type" "fpmove,*")
7534 (set_attr "length" "*,2")
7535 (set_attr "fptype" "double")])
7538 [(set (match_operand:TF 0 "register_operand" "")
7539 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7543 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7544 [(set (match_dup 2) (neg:DF (match_dup 3)))
7545 (set (match_dup 4) (match_dup 5))]
7546 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7547 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7548 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7549 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7551 (define_expand "negdf2"
7552 [(set (match_operand:DF 0 "register_operand" "")
7553 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7557 (define_insn "*negdf2_notv9"
7558 [(set (match_operand:DF 0 "register_operand" "=e,e")
7559 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7560 "TARGET_FPU && ! TARGET_V9"
7564 [(set_attr "type" "fpmove,*")
7565 (set_attr "length" "*,2")])
7568 [(set (match_operand:DF 0 "register_operand" "")
7569 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7573 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7574 [(set (match_dup 2) (neg:SF (match_dup 3)))
7575 (set (match_dup 4) (match_dup 5))]
7576 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7577 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7578 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7579 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7581 (define_insn "*negdf2_v9"
7582 [(set (match_operand:DF 0 "register_operand" "=e")
7583 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7584 "TARGET_FPU && TARGET_V9"
7586 [(set_attr "type" "fpmove")
7587 (set_attr "fptype" "double")])
7589 (define_insn "negsf2"
7590 [(set (match_operand:SF 0 "register_operand" "=f")
7591 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7594 [(set_attr "type" "fpmove")])
7596 (define_expand "abstf2"
7597 [(set (match_operand:TF 0 "register_operand" "")
7598 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7602 (define_insn "*abstf2_notv9"
7603 [(set (match_operand:TF 0 "register_operand" "=e,e")
7604 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7605 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7606 "TARGET_FPU && ! TARGET_V9"
7610 [(set_attr "type" "fpmove,*")
7611 (set_attr "length" "*,2")])
7614 [(set (match_operand:TF 0 "register_operand" "")
7615 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7619 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7620 [(set (match_dup 2) (abs:SF (match_dup 3)))
7621 (set (match_dup 4) (match_dup 5))
7622 (set (match_dup 6) (match_dup 7))]
7623 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7624 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7625 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7626 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7627 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7628 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7630 (define_insn "*abstf2_hq_v9"
7631 [(set (match_operand:TF 0 "register_operand" "=e,e")
7632 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7633 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7637 [(set_attr "type" "fpmove")
7638 (set_attr "fptype" "double,*")])
7640 (define_insn "*abstf2_v9"
7641 [(set (match_operand:TF 0 "register_operand" "=e,e")
7642 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7643 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7647 [(set_attr "type" "fpmove,*")
7648 (set_attr "length" "*,2")
7649 (set_attr "fptype" "double,*")])
7652 [(set (match_operand:TF 0 "register_operand" "")
7653 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7657 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7658 [(set (match_dup 2) (abs:DF (match_dup 3)))
7659 (set (match_dup 4) (match_dup 5))]
7660 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7661 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7662 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7663 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7665 (define_expand "absdf2"
7666 [(set (match_operand:DF 0 "register_operand" "")
7667 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7671 (define_insn "*absdf2_notv9"
7672 [(set (match_operand:DF 0 "register_operand" "=e,e")
7673 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7674 "TARGET_FPU && ! TARGET_V9"
7678 [(set_attr "type" "fpmove,*")
7679 (set_attr "length" "*,2")])
7682 [(set (match_operand:DF 0 "register_operand" "")
7683 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7687 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7688 [(set (match_dup 2) (abs:SF (match_dup 3)))
7689 (set (match_dup 4) (match_dup 5))]
7690 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7691 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7692 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7693 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7695 (define_insn "*absdf2_v9"
7696 [(set (match_operand:DF 0 "register_operand" "=e")
7697 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7698 "TARGET_FPU && TARGET_V9"
7700 [(set_attr "type" "fpmove")
7701 (set_attr "fptype" "double")])
7703 (define_insn "abssf2"
7704 [(set (match_operand:SF 0 "register_operand" "=f")
7705 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7708 [(set_attr "type" "fpmove")])
7710 (define_expand "sqrttf2"
7711 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7712 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
7713 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7714 "emit_tfmode_unop (SQRT, operands); DONE;")
7716 (define_insn "*sqrttf2_hq"
7717 [(set (match_operand:TF 0 "register_operand" "=e")
7718 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7719 "TARGET_FPU && TARGET_HARD_QUAD"
7721 [(set_attr "type" "fpsqrtd")])
7723 (define_insn "sqrtdf2"
7724 [(set (match_operand:DF 0 "register_operand" "=e")
7725 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7728 [(set_attr "type" "fpsqrtd")
7729 (set_attr "fptype" "double")])
7731 (define_insn "sqrtsf2"
7732 [(set (match_operand:SF 0 "register_operand" "=f")
7733 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7736 [(set_attr "type" "fpsqrts")])
7738 ;;- arithmetic shift instructions
7740 (define_insn "ashlsi3"
7741 [(set (match_operand:SI 0 "register_operand" "=r")
7742 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7743 (match_operand:SI 2 "arith_operand" "rI")))]
7747 if (GET_CODE (operands[2]) == CONST_INT
7748 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7749 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7751 return \"sll\\t%1, %2, %0\";
7753 [(set_attr "type" "shift")])
7755 ;; We special case multiplication by two, as add can be done
7756 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7757 (define_insn "*ashlsi3_const1"
7758 [(set (match_operand:SI 0 "register_operand" "=r")
7759 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7764 (define_expand "ashldi3"
7765 [(set (match_operand:DI 0 "register_operand" "=r")
7766 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7767 (match_operand:SI 2 "arith_operand" "rI")))]
7768 "TARGET_ARCH64 || TARGET_V8PLUS"
7771 if (! TARGET_ARCH64)
7773 if (GET_CODE (operands[2]) == CONST_INT)
7775 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7780 ;; We special case multiplication by two, as add can be done
7781 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7782 (define_insn "*ashldi3_const1"
7783 [(set (match_operand:DI 0 "register_operand" "=r")
7784 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7789 (define_insn "*ashldi3_sp64"
7790 [(set (match_operand:DI 0 "register_operand" "=r")
7791 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7792 (match_operand:SI 2 "arith_operand" "rI")))]
7796 if (GET_CODE (operands[2]) == CONST_INT
7797 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7798 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7800 return \"sllx\\t%1, %2, %0\";
7802 [(set_attr "type" "shift")])
7805 (define_insn "ashldi3_v8plus"
7806 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7807 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7808 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7809 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7811 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7812 [(set_attr "type" "multi")
7813 (set_attr "length" "5,5,6")])
7815 ;; Optimize (1LL<<x)-1
7816 ;; XXX this also needs to be fixed to handle equal subregs
7817 ;; XXX first before we could re-enable it.
7819 ; [(set (match_operand:DI 0 "register_operand" "=h")
7820 ; (plus:DI (ashift:DI (const_int 1)
7821 ; (match_operand:SI 1 "arith_operand" "rI"))
7823 ; "0 && TARGET_V8PLUS"
7826 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7827 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7828 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7830 ; [(set_attr "type" "multi")
7831 ; (set_attr "length" "4")])
7833 (define_insn "*cmp_cc_ashift_1"
7834 [(set (reg:CC_NOOV 100)
7835 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7839 "addcc\\t%0, %0, %%g0"
7840 [(set_attr "type" "compare")])
7842 (define_insn "*cmp_cc_set_ashift_1"
7843 [(set (reg:CC_NOOV 100)
7844 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7847 (set (match_operand:SI 0 "register_operand" "=r")
7848 (ashift:SI (match_dup 1) (const_int 1)))]
7850 "addcc\\t%1, %1, %0"
7851 [(set_attr "type" "compare")])
7853 (define_insn "ashrsi3"
7854 [(set (match_operand:SI 0 "register_operand" "=r")
7855 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7856 (match_operand:SI 2 "arith_operand" "rI")))]
7860 if (GET_CODE (operands[2]) == CONST_INT
7861 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7862 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7864 return \"sra\\t%1, %2, %0\";
7866 [(set_attr "type" "shift")])
7868 (define_insn "*ashrsi3_extend"
7869 [(set (match_operand:DI 0 "register_operand" "=r")
7870 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7871 (match_operand:SI 2 "arith_operand" "r"))))]
7874 [(set_attr "type" "shift")])
7876 ;; This handles the case as above, but with constant shift instead of
7877 ;; register. Combiner "simplifies" it for us a little bit though.
7878 (define_insn "*ashrsi3_extend2"
7879 [(set (match_operand:DI 0 "register_operand" "=r")
7880 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7882 (match_operand:SI 2 "small_int_or_double" "n")))]
7884 && ((GET_CODE (operands[2]) == CONST_INT
7885 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7886 || (GET_CODE (operands[2]) == CONST_DOUBLE
7887 && !CONST_DOUBLE_HIGH (operands[2])
7888 && CONST_DOUBLE_LOW (operands[2]) >= 32
7889 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7892 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7894 return \"sra\\t%1, %2, %0\";
7896 [(set_attr "type" "shift")])
7898 (define_expand "ashrdi3"
7899 [(set (match_operand:DI 0 "register_operand" "=r")
7900 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7901 (match_operand:SI 2 "arith_operand" "rI")))]
7902 "TARGET_ARCH64 || TARGET_V8PLUS"
7905 if (! TARGET_ARCH64)
7907 if (GET_CODE (operands[2]) == CONST_INT)
7908 FAIL; /* prefer generic code in this case */
7909 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7915 [(set (match_operand:DI 0 "register_operand" "=r")
7916 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7917 (match_operand:SI 2 "arith_operand" "rI")))]
7921 if (GET_CODE (operands[2]) == CONST_INT
7922 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7923 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7925 return \"srax\\t%1, %2, %0\";
7927 [(set_attr "type" "shift")])
7930 (define_insn "ashrdi3_v8plus"
7931 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7932 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7933 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7934 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7936 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7937 [(set_attr "type" "multi")
7938 (set_attr "length" "5,5,6")])
7940 (define_insn "lshrsi3"
7941 [(set (match_operand:SI 0 "register_operand" "=r")
7942 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7943 (match_operand:SI 2 "arith_operand" "rI")))]
7947 if (GET_CODE (operands[2]) == CONST_INT
7948 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7949 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7951 return \"srl\\t%1, %2, %0\";
7953 [(set_attr "type" "shift")])
7955 ;; This handles the case where
7956 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7957 ;; but combiner "simplifies" it for us.
7958 (define_insn "*lshrsi3_extend"
7959 [(set (match_operand:DI 0 "register_operand" "=r")
7960 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7961 (match_operand:SI 2 "arith_operand" "r")) 0)
7962 (match_operand 3 "" "")))]
7964 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7965 && CONST_DOUBLE_HIGH (operands[3]) == 0
7966 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7967 || (HOST_BITS_PER_WIDE_INT >= 64
7968 && GET_CODE (operands[3]) == CONST_INT
7969 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7971 [(set_attr "type" "shift")])
7973 ;; This handles the case where
7974 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7975 ;; but combiner "simplifies" it for us.
7976 (define_insn "*lshrsi3_extend2"
7977 [(set (match_operand:DI 0 "register_operand" "=r")
7978 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7979 (match_operand 2 "small_int_or_double" "n")
7982 && ((GET_CODE (operands[2]) == CONST_INT
7983 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7984 || (GET_CODE (operands[2]) == CONST_DOUBLE
7985 && CONST_DOUBLE_HIGH (operands[2]) == 0
7986 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7989 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7991 return \"srl\\t%1, %2, %0\";
7993 [(set_attr "type" "shift")])
7995 (define_expand "lshrdi3"
7996 [(set (match_operand:DI 0 "register_operand" "=r")
7997 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7998 (match_operand:SI 2 "arith_operand" "rI")))]
7999 "TARGET_ARCH64 || TARGET_V8PLUS"
8002 if (! TARGET_ARCH64)
8004 if (GET_CODE (operands[2]) == CONST_INT)
8006 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8012 [(set (match_operand:DI 0 "register_operand" "=r")
8013 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8014 (match_operand:SI 2 "arith_operand" "rI")))]
8018 if (GET_CODE (operands[2]) == CONST_INT
8019 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8020 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8022 return \"srlx\\t%1, %2, %0\";
8024 [(set_attr "type" "shift")])
8027 (define_insn "lshrdi3_v8plus"
8028 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8029 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8030 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8031 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8033 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8034 [(set_attr "type" "multi")
8035 (set_attr "length" "5,5,6")])
8038 [(set (match_operand:SI 0 "register_operand" "=r")
8039 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8041 (match_operand:SI 2 "small_int_or_double" "n")))]
8043 && ((GET_CODE (operands[2]) == CONST_INT
8044 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8045 || (GET_CODE (operands[2]) == CONST_DOUBLE
8046 && !CONST_DOUBLE_HIGH (operands[2])
8047 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8050 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8052 return \"srax\\t%1, %2, %0\";
8054 [(set_attr "type" "shift")])
8057 [(set (match_operand:SI 0 "register_operand" "=r")
8058 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8060 (match_operand:SI 2 "small_int_or_double" "n")))]
8062 && ((GET_CODE (operands[2]) == CONST_INT
8063 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8064 || (GET_CODE (operands[2]) == CONST_DOUBLE
8065 && !CONST_DOUBLE_HIGH (operands[2])
8066 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8069 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8071 return \"srlx\\t%1, %2, %0\";
8073 [(set_attr "type" "shift")])
8076 [(set (match_operand:SI 0 "register_operand" "=r")
8077 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8078 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8079 (match_operand:SI 3 "small_int_or_double" "n")))]
8081 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8082 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8083 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8084 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8087 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8089 return \"srax\\t%1, %2, %0\";
8091 [(set_attr "type" "shift")])
8094 [(set (match_operand:SI 0 "register_operand" "=r")
8095 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8096 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8097 (match_operand:SI 3 "small_int_or_double" "n")))]
8099 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8100 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8101 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8102 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8105 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8107 return \"srlx\\t%1, %2, %0\";
8109 [(set_attr "type" "shift")])
8111 ;; Unconditional and other jump instructions
8112 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8113 ;; following insn is never executed. This saves us a nop. Dbx does not
8114 ;; handle such branches though, so we only use them when optimizing.
8116 [(set (pc) (label_ref (match_operand 0 "" "")))]
8120 /* TurboSparc is reported to have problems with
8123 i.e. an empty loop with the annul bit set. The workaround is to use
8127 if (! TARGET_V9 && flag_delayed_branch
8128 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8129 == INSN_ADDRESSES (INSN_UID (insn))))
8130 return \"b\\t%l0%#\";
8132 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8134 [(set_attr "type" "uncond_branch")])
8136 (define_expand "tablejump"
8137 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8138 (use (label_ref (match_operand 1 "" "")))])]
8142 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8145 /* In pic mode, our address differences are against the base of the
8146 table. Add that base value back in; CSE ought to be able to combine
8147 the two address loads. */
8151 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8153 if (CASE_VECTOR_MODE != Pmode)
8154 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8155 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8156 operands[0] = memory_address (Pmode, tmp);
8160 (define_insn "*tablejump_sp32"
8161 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8162 (use (label_ref (match_operand 1 "" "")))]
8165 [(set_attr "type" "uncond_branch")])
8167 (define_insn "*tablejump_sp64"
8168 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8169 (use (label_ref (match_operand 1 "" "")))]
8172 [(set_attr "type" "uncond_branch")])
8174 ;; This pattern recognizes the "instruction" that appears in
8175 ;; a function call that wants a structure value,
8176 ;; to inform the called function if compiled with Sun CC.
8177 ;(define_insn "*unimp_insn"
8178 ; [(match_operand:SI 0 "immediate_operand" "")]
8179 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8181 ; [(set_attr "type" "marker")])
8183 ;;- jump to subroutine
8184 (define_expand "call"
8185 ;; Note that this expression is not used for generating RTL.
8186 ;; All the RTL is generated explicitly below.
8187 [(call (match_operand 0 "call_operand" "")
8188 (match_operand 3 "" "i"))]
8189 ;; operands[2] is next_arg_register
8190 ;; operands[3] is struct_value_size_rtx.
8194 rtx fn_rtx, nregs_rtx;
8196 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8199 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8201 /* This is really a PIC sequence. We want to represent
8202 it as a funny jump so its delay slots can be filled.
8204 ??? But if this really *is* a CALL, will not it clobber the
8205 call-clobbered registers? We lose this if it is a JUMP_INSN.
8206 Why cannot we have delay slots filled if it were a CALL? */
8208 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8213 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8215 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8221 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8222 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8226 fn_rtx = operands[0];
8228 /* Count the number of parameter registers being used by this call.
8229 if that argument is NULL, it means we are using them all, which
8230 means 6 on the sparc. */
8233 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8235 nregs_rtx = GEN_INT (6);
8237 nregs_rtx = const0_rtx;
8240 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8244 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8246 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8251 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8252 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8256 /* If this call wants a structure value,
8257 emit an unimp insn to let the called function know about this. */
8258 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8260 rtx insn = emit_insn (operands[3]);
8261 SCHED_GROUP_P (insn) = 1;
8268 ;; We can't use the same pattern for these two insns, because then registers
8269 ;; in the address may not be properly reloaded.
8271 (define_insn "*call_address_sp32"
8272 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8273 (match_operand 1 "" ""))
8274 (clobber (reg:SI 15))]
8275 ;;- Do not use operand 1 for most machines.
8278 [(set_attr "type" "call")])
8280 (define_insn "*call_symbolic_sp32"
8281 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8282 (match_operand 1 "" ""))
8283 (clobber (reg:SI 15))]
8284 ;;- Do not use operand 1 for most machines.
8287 [(set_attr "type" "call")])
8289 (define_insn "*call_address_sp64"
8290 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8291 (match_operand 1 "" ""))
8292 (clobber (reg:DI 15))]
8293 ;;- Do not use operand 1 for most machines.
8296 [(set_attr "type" "call")])
8298 (define_insn "*call_symbolic_sp64"
8299 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8300 (match_operand 1 "" ""))
8301 (clobber (reg:DI 15))]
8302 ;;- Do not use operand 1 for most machines.
8305 [(set_attr "type" "call")])
8307 ;; This is a call that wants a structure value.
8308 ;; There is no such critter for v9 (??? we may need one anyway).
8309 (define_insn "*call_address_struct_value_sp32"
8310 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8311 (match_operand 1 "" ""))
8312 (match_operand 2 "immediate_operand" "")
8313 (clobber (reg:SI 15))]
8314 ;;- Do not use operand 1 for most machines.
8315 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8316 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8317 [(set_attr "type" "call_no_delay_slot")
8318 (set_attr "length" "3")])
8320 ;; This is a call that wants a structure value.
8321 ;; There is no such critter for v9 (??? we may need one anyway).
8322 (define_insn "*call_symbolic_struct_value_sp32"
8323 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8324 (match_operand 1 "" ""))
8325 (match_operand 2 "immediate_operand" "")
8326 (clobber (reg:SI 15))]
8327 ;;- Do not use operand 1 for most machines.
8328 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8329 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8330 [(set_attr "type" "call_no_delay_slot")
8331 (set_attr "length" "3")])
8333 ;; This is a call that may want a structure value. This is used for
8335 (define_insn "*call_address_untyped_struct_value_sp32"
8336 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8337 (match_operand 1 "" ""))
8338 (match_operand 2 "immediate_operand" "")
8339 (clobber (reg:SI 15))]
8340 ;;- Do not use operand 1 for most machines.
8341 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8342 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8343 [(set_attr "type" "call_no_delay_slot")
8344 (set_attr "length" "3")])
8346 ;; This is a call that wants a structure value.
8347 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8348 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8349 (match_operand 1 "" ""))
8350 (match_operand 2 "immediate_operand" "")
8351 (clobber (reg:SI 15))]
8352 ;;- Do not use operand 1 for most machines.
8353 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8354 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8355 [(set_attr "type" "call_no_delay_slot")
8356 (set_attr "length" "3")])
8358 (define_expand "call_value"
8359 ;; Note that this expression is not used for generating RTL.
8360 ;; All the RTL is generated explicitly below.
8361 [(set (match_operand 0 "register_operand" "=rf")
8362 (call (match_operand 1 "" "")
8363 (match_operand 4 "" "")))]
8364 ;; operand 2 is stack_size_rtx
8365 ;; operand 3 is next_arg_register
8369 rtx fn_rtx, nregs_rtx;
8372 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8375 fn_rtx = operands[1];
8379 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8381 nregs_rtx = GEN_INT (6);
8383 nregs_rtx = const0_rtx;
8387 gen_rtx_SET (VOIDmode, operands[0],
8388 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8389 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8391 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8396 (define_insn "*call_value_address_sp32"
8397 [(set (match_operand 0 "" "=rf")
8398 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8399 (match_operand 2 "" "")))
8400 (clobber (reg:SI 15))]
8401 ;;- Do not use operand 2 for most machines.
8404 [(set_attr "type" "call")])
8406 (define_insn "*call_value_symbolic_sp32"
8407 [(set (match_operand 0 "" "=rf")
8408 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8409 (match_operand 2 "" "")))
8410 (clobber (reg:SI 15))]
8411 ;;- Do not use operand 2 for most machines.
8414 [(set_attr "type" "call")])
8416 (define_insn "*call_value_address_sp64"
8417 [(set (match_operand 0 "" "")
8418 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8419 (match_operand 2 "" "")))
8420 (clobber (reg:DI 15))]
8421 ;;- Do not use operand 2 for most machines.
8424 [(set_attr "type" "call")])
8426 (define_insn "*call_value_symbolic_sp64"
8427 [(set (match_operand 0 "" "")
8428 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8429 (match_operand 2 "" "")))
8430 (clobber (reg:DI 15))]
8431 ;;- Do not use operand 2 for most machines.
8434 [(set_attr "type" "call")])
8436 (define_expand "untyped_call"
8437 [(parallel [(call (match_operand 0 "" "")
8439 (match_operand 1 "" "")
8440 (match_operand 2 "" "")])]
8446 /* Pass constm1 to indicate that it may expect a structure value, but
8447 we don't know what size it is. */
8448 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8450 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8452 rtx set = XVECEXP (operands[2], 0, i);
8453 emit_move_insn (SET_DEST (set), SET_SRC (set));
8456 /* The optimizer does not know that the call sets the function value
8457 registers we stored in the result block. We avoid problems by
8458 claiming that all hard registers are used and clobbered at this
8460 emit_insn (gen_blockage ());
8466 (define_expand "sibcall"
8467 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8472 (define_insn "*sibcall_symbolic_sp32"
8473 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8474 (match_operand 1 "" ""))
8477 "* return output_sibcall(insn, operands[0]);"
8478 [(set_attr "type" "sibcall")])
8480 (define_insn "*sibcall_symbolic_sp64"
8481 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8482 (match_operand 1 "" ""))
8485 "* return output_sibcall(insn, operands[0]);"
8486 [(set_attr "type" "sibcall")])
8488 (define_expand "sibcall_value"
8489 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8490 (call (match_operand 1 "" "") (const_int 0)))
8495 (define_insn "*sibcall_value_symbolic_sp32"
8496 [(set (match_operand 0 "" "=rf")
8497 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8498 (match_operand 2 "" "")))
8501 "* return output_sibcall(insn, operands[1]);"
8502 [(set_attr "type" "sibcall")])
8504 (define_insn "*sibcall_value_symbolic_sp64"
8505 [(set (match_operand 0 "" "")
8506 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8507 (match_operand 2 "" "")))
8510 "* return output_sibcall(insn, operands[1]);"
8511 [(set_attr "type" "sibcall")])
8513 (define_expand "sibcall_epilogue"
8518 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8519 ;; all of memory. This blocks insns from being moved across this point.
8521 (define_insn "blockage"
8522 [(unspec_volatile [(const_int 0)] 0)]
8525 [(set_attr "length" "0")])
8527 ;; Prepare to return any type including a structure value.
8529 (define_expand "untyped_return"
8530 [(match_operand:BLK 0 "memory_operand" "")
8531 (match_operand 1 "" "")]
8535 rtx valreg1 = gen_rtx_REG (DImode, 24);
8536 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8537 rtx result = operands[0];
8539 if (! TARGET_ARCH64)
8541 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8543 rtx value = gen_reg_rtx (SImode);
8545 /* Fetch the instruction where we will return to and see if it's an unimp
8546 instruction (the most significant 10 bits will be zero). If so,
8547 update the return address to skip the unimp instruction. */
8548 emit_move_insn (value,
8549 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8550 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8551 emit_insn (gen_update_return (rtnreg, value));
8554 /* Reload the function value registers. */
8555 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8556 emit_move_insn (valreg2,
8557 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8559 /* Put USE insns before the return. */
8560 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8561 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8563 /* Construct the return. */
8564 expand_null_return ();
8569 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8570 ;; and parts of the compiler don't want to believe that the add is needed.
8572 (define_insn "update_return"
8573 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8574 (match_operand:SI 1 "register_operand" "r")] 1)]
8576 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8577 [(set_attr "type" "multi")
8578 (set_attr "length" "3")])
8585 (define_expand "indirect_jump"
8586 [(set (pc) (match_operand 0 "address_operand" "p"))]
8590 (define_insn "*branch_sp32"
8591 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8594 [(set_attr "type" "uncond_branch")])
8596 (define_insn "*branch_sp64"
8597 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8600 [(set_attr "type" "uncond_branch")])
8602 ;; ??? Doesn't work with -mflat.
8603 (define_expand "nonlocal_goto"
8604 [(match_operand:SI 0 "general_operand" "")
8605 (match_operand:SI 1 "general_operand" "")
8606 (match_operand:SI 2 "general_operand" "")
8607 (match_operand:SI 3 "" "")]
8612 rtx chain = operands[0];
8614 rtx lab = operands[1];
8615 rtx stack = operands[2];
8616 rtx fp = operands[3];
8619 /* Trap instruction to flush all the register windows. */
8620 emit_insn (gen_flush_register_windows ());
8622 /* Load the fp value for the containing fn into %fp. This is needed
8623 because STACK refers to %fp. Note that virtual register instantiation
8624 fails if the virtual %fp isn't set from a register. */
8625 if (GET_CODE (fp) != REG)
8626 fp = force_reg (Pmode, fp);
8627 emit_move_insn (virtual_stack_vars_rtx, fp);
8629 /* Find the containing function's current nonlocal goto handler,
8630 which will do any cleanups and then jump to the label. */
8631 labreg = gen_rtx_REG (Pmode, 8);
8632 emit_move_insn (labreg, lab);
8634 /* Restore %fp from stack pointer value for containing function.
8635 The restore insn that follows will move this to %sp,
8636 and reload the appropriate value into %fp. */
8637 emit_move_insn (hard_frame_pointer_rtx, stack);
8639 /* USE of frame_pointer_rtx added for consistency; not clear if
8641 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8642 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8645 /* Return, restoring reg window and jumping to goto handler. */
8646 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8647 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8649 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8655 /* Put in the static chain register the nonlocal label address. */
8656 emit_move_insn (static_chain_rtx, chain);
8659 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8660 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8665 ;; Special trap insn to flush register windows.
8666 (define_insn "flush_register_windows"
8667 [(unspec_volatile [(const_int 0)] 1)]
8669 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8670 [(set_attr "type" "misc")])
8672 (define_insn "goto_handler_and_restore"
8673 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8674 "GET_MODE (operands[0]) == Pmode"
8675 "jmp\\t%0+0\\n\\trestore"
8676 [(set_attr "type" "multi")
8677 (set_attr "length" "2")])
8679 ;;(define_insn "goto_handler_and_restore_v9"
8680 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8681 ;; (match_operand:SI 1 "register_operand" "=r,r")
8682 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8683 ;; "TARGET_V9 && ! TARGET_ARCH64"
8685 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8686 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8687 ;; [(set_attr "type" "multi")
8688 ;; (set_attr "length" "2,3")])
8690 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8691 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8692 ;; (match_operand:DI 1 "register_operand" "=r,r")
8693 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8694 ;; "TARGET_V9 && TARGET_ARCH64"
8696 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8697 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8698 ;; [(set_attr "type" "multi")
8699 ;; (set_attr "length" "2,3")])
8701 ;; For __builtin_setjmp we need to flush register windows iff the function
8702 ;; calls alloca as well, because otherwise the register window might be
8703 ;; saved after %sp adjustement and thus setjmp would crash
8704 (define_expand "builtin_setjmp_setup"
8705 [(match_operand 0 "register_operand" "r")]
8709 emit_insn (gen_do_builtin_setjmp_setup ());
8713 (define_insn "do_builtin_setjmp_setup"
8714 [(unspec_volatile [(const_int 0)] 5)]
8718 if (! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT)
8720 fputs (\"\tflushw\n\", asm_out_file);
8722 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
8723 TARGET_ARCH64 ? 'x' : 'w',
8724 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
8725 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
8726 TARGET_ARCH64 ? 'x' : 'w',
8727 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
8728 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
8729 TARGET_ARCH64 ? 'x' : 'w',
8730 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
8733 [(set_attr "type" "misc")
8734 (set (attr "length") (if_then_else (eq_attr "pic" "true")
8739 [(unspec_volatile [(const_int 0)] 5)]
8740 "! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT"
8744 if (current_function_calls_alloca)
8745 emit_insn (gen_flush_register_windows ());
8749 ;; Pattern for use after a setjmp to store FP and the return register
8750 ;; into the stack area.
8752 (define_expand "setjmp"
8758 emit_insn (gen_setjmp_64 ());
8760 emit_insn (gen_setjmp_32 ());
8764 (define_expand "setjmp_32"
8765 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8766 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8769 { operands[0] = frame_pointer_rtx; }")
8771 (define_expand "setjmp_64"
8772 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8773 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8776 { operands[0] = frame_pointer_rtx; }")
8778 ;; Special pattern for the FLUSH instruction.
8780 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8781 ; of the define_insn otherwise missing a mode. We make "flush", aka
8782 ; gen_flush, the default one since sparc_initialize_trampoline uses
8783 ; it on SImode mem values.
8785 (define_insn "flush"
8786 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8788 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8789 [(set_attr "type" "misc")])
8791 (define_insn "flushdi"
8792 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8794 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8795 [(set_attr "type" "misc")])
8800 ;; The scan instruction searches from the most significant bit while ffs
8801 ;; searches from the least significant bit. The bit index and treatment of
8802 ;; zero also differ. It takes at least 7 instructions to get the proper
8803 ;; result. Here is an obvious 8 instruction sequence.
8806 (define_insn "ffssi2"
8807 [(set (match_operand:SI 0 "register_operand" "=&r")
8808 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8809 (clobber (match_scratch:SI 2 "=&r"))]
8810 "TARGET_SPARCLITE || TARGET_SPARCLET"
8813 return \"sub\\t%%g0, %1, %0\;and\\t%0, %1, %0\;scan\\t%0, 0, %0\;mov\\t32, %2\;sub\\t%2, %0, %0\;sra\\t%0, 31, %2\;and\\t%2, 31, %2\;add\\t%2, %0, %0\";
8815 [(set_attr "type" "multi")
8816 (set_attr "length" "8")])
8818 ;; ??? This should be a define expand, so that the extra instruction have
8819 ;; a chance of being optimized away.
8821 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8822 ;; does, but no one uses that and we don't have a switch for it.
8824 ;(define_insn "ffsdi2"
8825 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8826 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8827 ; (clobber (match_scratch:DI 2 "=&r"))]
8829 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8830 ; [(set_attr "type" "multi")
8831 ; (set_attr "length" "4")])
8835 ;; Peepholes go at the end.
8837 ;; Optimize consecutive loads or stores into ldd and std when possible.
8838 ;; The conditions in which we do this are very restricted and are
8839 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8842 [(set (match_operand:SI 0 "memory_operand" "")
8844 (set (match_operand:SI 1 "memory_operand" "")
8847 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8850 "operands[0] = change_address (operands[0], DImode, NULL);")
8853 [(set (match_operand:SI 0 "memory_operand" "")
8855 (set (match_operand:SI 1 "memory_operand" "")
8858 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8861 "operands[1] = change_address (operands[1], DImode, NULL);")
8864 [(set (match_operand:SI 0 "register_operand" "")
8865 (match_operand:SI 1 "memory_operand" ""))
8866 (set (match_operand:SI 2 "register_operand" "")
8867 (match_operand:SI 3 "memory_operand" ""))]
8868 "registers_ok_for_ldd_peep (operands[0], operands[2])
8869 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8872 "operands[1] = change_address (operands[1], DImode, NULL);
8873 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8876 [(set (match_operand:SI 0 "memory_operand" "")
8877 (match_operand:SI 1 "register_operand" ""))
8878 (set (match_operand:SI 2 "memory_operand" "")
8879 (match_operand:SI 3 "register_operand" ""))]
8880 "registers_ok_for_ldd_peep (operands[1], operands[3])
8881 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8884 "operands[0] = change_address (operands[0], DImode, NULL);
8885 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8888 [(set (match_operand:SF 0 "register_operand" "")
8889 (match_operand:SF 1 "memory_operand" ""))
8890 (set (match_operand:SF 2 "register_operand" "")
8891 (match_operand:SF 3 "memory_operand" ""))]
8892 "registers_ok_for_ldd_peep (operands[0], operands[2])
8893 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8896 "operands[1] = change_address (operands[1], DFmode, NULL);
8897 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8900 [(set (match_operand:SF 0 "memory_operand" "")
8901 (match_operand:SF 1 "register_operand" ""))
8902 (set (match_operand:SF 2 "memory_operand" "")
8903 (match_operand:SF 3 "register_operand" ""))]
8904 "registers_ok_for_ldd_peep (operands[1], operands[3])
8905 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8908 "operands[0] = change_address (operands[0], DFmode, NULL);
8909 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8912 [(set (match_operand:SI 0 "register_operand" "")
8913 (match_operand:SI 1 "memory_operand" ""))
8914 (set (match_operand:SI 2 "register_operand" "")
8915 (match_operand:SI 3 "memory_operand" ""))]
8916 "registers_ok_for_ldd_peep (operands[2], operands[0])
8917 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8920 "operands[3] = change_address (operands[3], DImode, NULL);
8921 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8924 [(set (match_operand:SI 0 "memory_operand" "")
8925 (match_operand:SI 1 "register_operand" ""))
8926 (set (match_operand:SI 2 "memory_operand" "")
8927 (match_operand:SI 3 "register_operand" ""))]
8928 "registers_ok_for_ldd_peep (operands[3], operands[1])
8929 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8932 "operands[2] = change_address (operands[2], DImode, NULL);
8933 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8937 [(set (match_operand:SF 0 "register_operand" "")
8938 (match_operand:SF 1 "memory_operand" ""))
8939 (set (match_operand:SF 2 "register_operand" "")
8940 (match_operand:SF 3 "memory_operand" ""))]
8941 "registers_ok_for_ldd_peep (operands[2], operands[0])
8942 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8945 "operands[3] = change_address (operands[3], DFmode, NULL);
8946 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8949 [(set (match_operand:SF 0 "memory_operand" "")
8950 (match_operand:SF 1 "register_operand" ""))
8951 (set (match_operand:SF 2 "memory_operand" "")
8952 (match_operand:SF 3 "register_operand" ""))]
8953 "registers_ok_for_ldd_peep (operands[3], operands[1])
8954 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8957 "operands[2] = change_address (operands[2], DFmode, NULL);
8958 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8960 ;; Optimize the case of following a reg-reg move with a test
8961 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8962 ;; This can result from a float to fix conversion.
8965 [(set (match_operand:SI 0 "register_operand" "")
8966 (match_operand:SI 1 "register_operand" ""))
8968 (compare:CC (match_operand:SI 2 "register_operand" "")
8970 "(rtx_equal_p (operands[2], operands[0])
8971 || rtx_equal_p (operands[2], operands[1]))
8972 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8973 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8974 [(parallel [(set (match_dup 0) (match_dup 1))
8976 (compare:CC (match_dup 1) (const_int 0)))])]
8980 [(set (match_operand:DI 0 "register_operand" "")
8981 (match_operand:DI 1 "register_operand" ""))
8983 (compare:CCX (match_operand:DI 2 "register_operand" "")
8986 && (rtx_equal_p (operands[2], operands[0])
8987 || rtx_equal_p (operands[2], operands[1]))
8988 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8989 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8990 [(parallel [(set (match_dup 0) (match_dup 1))
8992 (compare:CCX (match_dup 1) (const_int 0)))])]
8995 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8996 ;; who then immediately calls final_scan_insn.
8998 (define_insn "*return_qi"
8999 [(set (match_operand:QI 0 "restore_operand" "")
9000 (match_operand:QI 1 "arith_operand" "rI"))
9002 "sparc_emitting_epilogue"
9005 if (! TARGET_ARCH64 && current_function_returns_struct)
9006 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9007 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9008 || IN_OR_GLOBAL_P (operands[1])))
9009 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9011 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9013 [(set_attr "type" "multi")
9014 (set_attr "length" "2")])
9016 (define_insn "*return_hi"
9017 [(set (match_operand:HI 0 "restore_operand" "")
9018 (match_operand:HI 1 "arith_operand" "rI"))
9020 "sparc_emitting_epilogue"
9023 if (! TARGET_ARCH64 && current_function_returns_struct)
9024 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9025 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9026 || IN_OR_GLOBAL_P (operands[1])))
9027 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9029 return \"ret\;restore %%g0, %1, %Y0\";
9031 [(set_attr "type" "multi")
9032 (set_attr "length" "2")])
9034 (define_insn "*return_si"
9035 [(set (match_operand:SI 0 "restore_operand" "")
9036 (match_operand:SI 1 "arith_operand" "rI"))
9038 "sparc_emitting_epilogue"
9041 if (! TARGET_ARCH64 && current_function_returns_struct)
9042 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9043 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9044 || IN_OR_GLOBAL_P (operands[1])))
9045 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9047 return \"ret\;restore %%g0, %1, %Y0\";
9049 [(set_attr "type" "multi")
9050 (set_attr "length" "2")])
9052 (define_insn "*return_sf_no_fpu"
9053 [(set (match_operand:SF 0 "restore_operand" "=r")
9054 (match_operand:SF 1 "register_operand" "r"))
9056 "sparc_emitting_epilogue"
9059 if (! TARGET_ARCH64 && current_function_returns_struct)
9060 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9061 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9062 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9064 return \"ret\;restore %%g0, %1, %Y0\";
9066 [(set_attr "type" "multi")
9067 (set_attr "length" "2")])
9069 (define_insn "*return_df_no_fpu"
9070 [(set (match_operand:DF 0 "restore_operand" "=r")
9071 (match_operand:DF 1 "register_operand" "r"))
9073 "sparc_emitting_epilogue && TARGET_ARCH64"
9076 if (IN_OR_GLOBAL_P (operands[1]))
9077 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9079 return \"ret\;restore %%g0, %1, %Y0\";
9081 [(set_attr "type" "multi")
9082 (set_attr "length" "2")])
9084 (define_insn "*return_addsi"
9085 [(set (match_operand:SI 0 "restore_operand" "")
9086 (plus:SI (match_operand:SI 1 "register_operand" "r")
9087 (match_operand:SI 2 "arith_operand" "rI")))
9089 "sparc_emitting_epilogue"
9092 if (! TARGET_ARCH64 && current_function_returns_struct)
9093 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9094 /* If operands are global or in registers, can use return */
9095 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9096 && (GET_CODE (operands[2]) == CONST_INT
9097 || IN_OR_GLOBAL_P (operands[2])))
9098 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9100 return \"ret\;restore %r1, %2, %Y0\";
9102 [(set_attr "type" "multi")
9103 (set_attr "length" "2")])
9105 (define_insn "*return_losum_si"
9106 [(set (match_operand:SI 0 "restore_operand" "")
9107 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9108 (match_operand:SI 2 "immediate_operand" "in")))
9110 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
9113 if (! TARGET_ARCH64 && current_function_returns_struct)
9114 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9115 /* If operands are global or in registers, can use return */
9116 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9117 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9119 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9121 [(set_attr "type" "multi")
9122 (set_attr "length" "2")])
9124 (define_insn "*return_di"
9125 [(set (match_operand:DI 0 "restore_operand" "")
9126 (match_operand:DI 1 "arith_double_operand" "rHI"))
9128 "sparc_emitting_epilogue && TARGET_ARCH64"
9129 "ret\;restore %%g0, %1, %Y0"
9130 [(set_attr "type" "multi")
9131 (set_attr "length" "2")])
9133 (define_insn "*return_adddi"
9134 [(set (match_operand:DI 0 "restore_operand" "")
9135 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9136 (match_operand:DI 2 "arith_double_operand" "rHI")))
9138 "sparc_emitting_epilogue && TARGET_ARCH64"
9139 "ret\;restore %r1, %2, %Y0"
9140 [(set_attr "type" "multi")
9141 (set_attr "length" "2")])
9143 (define_insn "*return_losum_di"
9144 [(set (match_operand:DI 0 "restore_operand" "")
9145 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9146 (match_operand:DI 2 "immediate_operand" "in")))
9148 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
9149 "ret\;restore %r1, %%lo(%a2), %Y0"
9150 [(set_attr "type" "multi")
9151 (set_attr "length" "2")])
9153 (define_insn "*return_sf"
9155 (match_operand:SF 0 "register_operand" "f"))
9157 "sparc_emitting_epilogue"
9158 "ret\;fmovs\\t%0, %%f0"
9159 [(set_attr "type" "multi")
9160 (set_attr "length" "2")])
9162 ;; Now peepholes to do a call followed by a jump.
9165 [(parallel [(set (match_operand 0 "" "")
9166 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9167 (match_operand 2 "" "")))
9168 (clobber (reg:SI 15))])
9169 (set (pc) (label_ref (match_operand 3 "" "")))]
9170 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9171 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
9172 && sparc_cpu != PROCESSOR_ULTRASPARC
9173 && sparc_cpu != PROCESSOR_ULTRASPARC3"
9174 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9177 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9178 (match_operand 1 "" ""))
9179 (clobber (reg:SI 15))])
9180 (set (pc) (label_ref (match_operand 2 "" "")))]
9181 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9182 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
9183 && sparc_cpu != PROCESSOR_ULTRASPARC
9184 && sparc_cpu != PROCESSOR_ULTRASPARC3"
9185 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9187 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
9188 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
9189 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
9191 (define_expand "prefetch"
9192 [(match_operand 0 "address_operand" "")
9193 (match_operand 1 "const_int_operand" "")
9194 (match_operand 2 "const_int_operand" "")]
9199 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
9201 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
9205 (define_insn "prefetch_64"
9206 [(prefetch (match_operand:DI 0 "address_operand" "p")
9207 (match_operand:DI 1 "const_int_operand" "n")
9208 (match_operand:DI 2 "const_int_operand" "n"))]
9211 static const char * const prefetch_instr[2][2] = {
9213 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9214 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
9217 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9218 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
9221 int read_or_write = INTVAL (operands[1]);
9222 int locality = INTVAL (operands[2]);
9224 if (read_or_write != 0 && read_or_write != 1)
9226 if (locality < 0 || locality > 3)
9228 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
9230 [(set_attr "type" "load")])
9232 (define_insn "prefetch_32"
9233 [(prefetch (match_operand:SI 0 "address_operand" "p")
9234 (match_operand:SI 1 "const_int_operand" "n")
9235 (match_operand:SI 2 "const_int_operand" "n"))]
9238 static const char * const prefetch_instr[2][2] = {
9240 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9241 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
9244 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9245 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
9248 int read_or_write = INTVAL (operands[1]);
9249 int locality = INTVAL (operands[2]);
9251 if (read_or_write != 0 && read_or_write != 1)
9253 if (locality < 0 || locality > 3)
9255 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
9257 [(set_attr "type" "load")])
9259 (define_expand "prologue"
9261 "flag_pic && current_function_uses_pic_offset_table"
9264 load_pic_register ();
9268 ;; We need to reload %l7 for -mflat -fpic,
9269 ;; otherwise %l7 should be preserved simply
9270 ;; by loading the function's register window
9271 (define_expand "exception_receiver"
9273 "TARGET_FLAT && flag_pic"
9276 load_pic_register ();
9281 (define_expand "builtin_setjmp_receiver"
9282 [(label_ref (match_operand 0 "" ""))]
9283 "TARGET_FLAT && flag_pic"
9286 load_pic_register ();
9291 [(trap_if (const_int 1) (const_int 5))]
9294 [(set_attr "type" "misc")])
9296 (define_expand "conditional_trap"
9297 [(trap_if (match_operator 0 "noov_compare_op"
9298 [(match_dup 2) (match_dup 3)])
9299 (match_operand:SI 1 "arith_operand" ""))]
9301 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9302 sparc_compare_op0, sparc_compare_op1);
9303 operands[3] = const0_rtx;")
9306 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9307 (match_operand:SI 1 "arith_operand" "rM"))]
9310 [(set_attr "type" "misc")])
9313 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9314 (match_operand:SI 1 "arith_operand" "rM"))]
9317 [(set_attr "type" "misc")])