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
49 ;; UNSPEC_VOLATILE: 0 blockage
50 ;; 1 flush_register_windows
51 ;; 2 goto_handler_and_restore
52 ;; 3 goto_handler_and_restore_v9*
54 ;; 5 do_builtin_setjmp_setup
57 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
58 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
59 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
60 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
61 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
63 ;; Attribute for cpu type.
64 ;; These must match the values for enum processor_type in sparc.h.
65 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc,ultrasparc3"
66 (const (symbol_ref "sparc_cpu_attr")))
68 ;; Attribute for the instruction set.
69 ;; At present we only need to distinguish v9/!v9, but for clarity we
70 ;; test TARGET_V8 too.
71 (define_attr "isa" "v6,v8,v9,sparclet"
73 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
74 (symbol_ref "TARGET_V8") (const_string "v8")
75 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
76 (const_string "v6"))))
79 (define_attr "arch" "arch32bit,arch64bit"
81 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
82 (const_string "arch32bit"))))
87 "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"
88 (const_string "ialu"))
90 ;; true if branch/call has empty delay slot and will emit a nop in it
91 (define_attr "empty_delay_slot" "false,true"
92 (symbol_ref "empty_delay_slot (insn)"))
94 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
96 (define_attr "pic" "false,true"
97 (symbol_ref "flag_pic != 0"))
99 ;; Length (in # of insns).
100 (define_attr "length" ""
101 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
102 (if_then_else (eq_attr "empty_delay_slot" "true")
105 (eq_attr "branch_type" "icc")
106 (if_then_else (match_operand 0 "noov_compare64_op" "")
107 (if_then_else (lt (pc) (match_dup 1))
108 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
109 (if_then_else (eq_attr "empty_delay_slot" "true")
112 (if_then_else (eq_attr "empty_delay_slot" "true")
115 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
116 (if_then_else (eq_attr "empty_delay_slot" "true")
119 (if_then_else (eq_attr "empty_delay_slot" "true")
122 (if_then_else (eq_attr "empty_delay_slot" "true")
125 (eq_attr "branch_type" "fcc")
126 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
127 (if_then_else (eq_attr "empty_delay_slot" "true")
130 (if_then_else (lt (pc) (match_dup 2))
131 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
132 (if_then_else (eq_attr "empty_delay_slot" "true")
135 (if_then_else (eq_attr "empty_delay_slot" "true")
138 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
139 (if_then_else (eq_attr "empty_delay_slot" "true")
142 (if_then_else (eq_attr "empty_delay_slot" "true")
145 (eq_attr "branch_type" "reg")
146 (if_then_else (lt (pc) (match_dup 2))
147 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
148 (if_then_else (eq_attr "empty_delay_slot" "true")
151 (if_then_else (eq_attr "empty_delay_slot" "true")
154 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
155 (if_then_else (eq_attr "empty_delay_slot" "true")
158 (if_then_else (eq_attr "empty_delay_slot" "true")
164 (define_attr "fptype" "single,double" (const_string "single"))
166 ;; UltraSPARC-III integer load type.
167 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
169 (define_asm_attributes
170 [(set_attr "length" "2")
171 (set_attr "type" "multi")])
173 ;; Attributes for instruction and branch scheduling
175 (define_attr "in_call_delay" "false,true"
176 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
177 (const_string "false")
178 (eq_attr "type" "load,fpload,store,fpstore")
179 (if_then_else (eq_attr "length" "1")
180 (const_string "true")
181 (const_string "false"))]
182 (if_then_else (eq_attr "length" "1")
183 (const_string "true")
184 (const_string "false"))))
186 (define_delay (eq_attr "type" "call")
187 [(eq_attr "in_call_delay" "true") (nil) (nil)])
189 (define_attr "eligible_for_sibcall_delay" "false,true"
190 (symbol_ref "eligible_for_sibcall_delay (insn)"))
192 (define_delay (eq_attr "type" "sibcall")
193 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
195 (define_attr "leaf_function" "false,true"
196 (const (symbol_ref "current_function_uses_only_leaf_regs")))
198 (define_attr "eligible_for_return_delay" "false,true"
199 (symbol_ref "eligible_for_return_delay (insn)"))
201 (define_attr "in_return_delay" "false,true"
202 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
203 (eq_attr "length" "1"))
204 (eq_attr "leaf_function" "false"))
205 (eq_attr "eligible_for_return_delay" "false"))
206 (const_string "true")
207 (const_string "false")))
209 (define_delay (and (eq_attr "type" "return")
210 (eq_attr "isa" "v9"))
211 [(eq_attr "in_return_delay" "true") (nil) (nil)])
213 ;; ??? Should implement the notion of predelay slots for floating point
214 ;; branches. This would allow us to remove the nop always inserted before
215 ;; a floating point branch.
217 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
218 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
219 ;; This is because doing so will add several pipeline stalls to the path
220 ;; that the load/store did not come from. Unfortunately, there is no way
221 ;; to prevent fill_eager_delay_slots from using load/store without completely
222 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
223 ;; because it prevents us from moving back the final store of inner loops.
225 (define_attr "in_branch_delay" "false,true"
226 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
227 (eq_attr "length" "1"))
228 (const_string "true")
229 (const_string "false")))
231 (define_attr "in_uncond_branch_delay" "false,true"
232 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
233 (eq_attr "length" "1"))
234 (const_string "true")
235 (const_string "false")))
237 (define_attr "in_annul_branch_delay" "false,true"
238 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
239 (eq_attr "length" "1"))
240 (const_string "true")
241 (const_string "false")))
243 (define_delay (eq_attr "type" "branch")
244 [(eq_attr "in_branch_delay" "true")
245 (nil) (eq_attr "in_annul_branch_delay" "true")])
247 (define_delay (eq_attr "type" "uncond_branch")
248 [(eq_attr "in_uncond_branch_delay" "true")
251 ;; DFA scheduling on the SPARC
253 (define_automaton "cypress_0,cypress_1,supersparc_0,supersparc_1,hypersparc_0,hypersparc_1,sparclet,ultrasparc_0,ultrasparc_1,ultrasparc3_0,ultrasparc3_1")
255 ;; Cypress scheduling
257 (define_cpu_unit "cyp_memory, cyp_fpalu" "cypress_0")
258 (define_cpu_unit "cyp_fpmds" "cypress_1")
260 (define_insn_reservation "cyp_load" 2
261 (and (eq_attr "cpu" "cypress")
262 (eq_attr "type" "load,sload,fpload"))
263 "cyp_memory, nothing")
265 (define_insn_reservation "cyp_fp_alu" 5
266 (and (eq_attr "cpu" "cypress")
267 (eq_attr "type" "fp,fpmove"))
268 "cyp_fpalu, nothing*3")
270 (define_insn_reservation "cyp_fp_mult" 7
271 (and (eq_attr "cpu" "cypress")
272 (eq_attr "type" "fpmul"))
273 "cyp_fpmds, nothing*5")
275 (define_insn_reservation "cyp_fp_div" 37
276 (and (eq_attr "cpu" "cypress")
277 (eq_attr "type" "fpdivs,fpdivd"))
278 "cyp_fpmds, nothing*35")
280 (define_insn_reservation "cyp_fp_sqrt" 63
281 (and (eq_attr "cpu" "cypress")
282 (eq_attr "type" "fpsqrts,fpsqrtd"))
283 "cyp_fpmds, nothing*61")
285 ;; SuperSPARC scheduling
287 (define_cpu_unit "ss_memory, ss_shift, ss_iwport0, ss_iwport1" "supersparc_0")
288 (define_cpu_unit "ss_fpalu" "supersparc_0")
289 (define_cpu_unit "ss_fpmds" "supersparc_1")
291 (define_reservation "ss_iwport" "(ss_iwport0 | ss_iwport1)")
293 (define_insn_reservation "ss_iuload" 1
294 (and (eq_attr "cpu" "supersparc")
295 (eq_attr "type" "load,sload"))
298 ;; Ok, fpu loads deliver the result in zero cycles. But we
299 ;; have to show the ss_memory reservation somehow, thus...
300 (define_insn_reservation "ss_fpload" 0
301 (and (eq_attr "cpu" "supersparc")
302 (eq_attr "type" "fpload"))
305 (define_bypass 0 "ss_fpload" "ss_fp_alu,ss_fp_mult,ss_fp_divs,ss_fp_divd,ss_fp_sqrt")
307 (define_insn_reservation "ss_store" 1
308 (and (eq_attr "cpu" "supersparc")
309 (eq_attr "type" "store,fpstore"))
312 (define_insn_reservation "ss_ialu_shift" 1
313 (and (eq_attr "cpu" "supersparc")
314 (eq_attr "type" "shift"))
315 "ss_shift + ss_iwport")
317 (define_insn_reservation "ss_ialu_any" 1
318 (and (eq_attr "cpu" "supersparc")
319 (eq_attr "type" "load,sload,store,shift,ialu"))
322 (define_insn_reservation "ss_fp_alu" 3
323 (and (eq_attr "cpu" "supersparc")
324 (eq_attr "type" "fp,fpmove,fpcmp"))
325 "ss_fpalu, nothing*2")
327 (define_insn_reservation "ss_fp_mult" 3
328 (and (eq_attr "cpu" "supersparc")
329 (eq_attr "type" "fpmul"))
330 "ss_fpmds, nothing*2")
332 (define_insn_reservation "ss_fp_divs" 6
333 (and (eq_attr "cpu" "supersparc")
334 (eq_attr "type" "fpdivs"))
335 "ss_fpmds*4, nothing*2")
337 (define_insn_reservation "ss_fp_divd" 9
338 (and (eq_attr "cpu" "supersparc")
339 (eq_attr "type" "fpdivd"))
340 "ss_fpmds*7, nothing*2")
342 (define_insn_reservation "ss_fp_sqrt" 12
343 (and (eq_attr "cpu" "supersparc")
344 (eq_attr "type" "fpsqrts,fpsqrtd"))
345 "ss_fpmds*10, nothing*2")
347 (define_insn_reservation "ss_imul" 4
348 (and (eq_attr "cpu" "supersparc")
349 (eq_attr "type" "imul"))
352 ;; HyperSPARC/sparclite86x scheduling
354 (define_cpu_unit "hs_memory,hs_branch,hs_shift,hs_fpalu" "hypersparc_0")
355 (define_cpu_unit "hs_fpmds" "hypersparc_1")
357 (define_insn_reservation "hs_load" 1
358 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
359 (eq_attr "type" "load,sload,fpload"))
362 (define_insn_reservation "hs_store" 2
363 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
364 (eq_attr "type" "store,fpstore"))
365 "hs_memory, nothing")
367 (define_insn_reservation "hs_slbranch" 1
368 (and (eq_attr "cpu" "sparclite86x")
369 (eq_attr "type" "branch"))
372 (define_insn_reservation "hs_slshift" 1
373 (and (eq_attr "cpu" "sparclite86x")
374 (eq_attr "type" "shift"))
377 (define_insn_reservation "hs_fp_alu" 1
378 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
379 (eq_attr "type" "fp,fpmove,fpcmp"))
382 (define_insn_reservation "hs_fp_mult" 1
383 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
384 (eq_attr "type" "fpmul"))
387 (define_insn_reservation "hs_fp_divs" 8
388 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
389 (eq_attr "type" "fpdivs"))
390 "hs_fpmds*6, nothing*2")
392 (define_insn_reservation "hs_fp_divd" 12
393 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
394 (eq_attr "type" "fpdivd"))
395 "hs_fpmds*10, nothing*2")
397 (define_insn_reservation "hs_fp_sqrt" 17
398 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
399 (eq_attr "type" "fpsqrts,fpsqrtd"))
400 "hs_fpmds*15, nothing*2")
402 (define_insn_reservation "hs_imul" 17
403 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
404 (eq_attr "type" "imul"))
405 "hs_fpmds*15, nothing*2")
407 ;; Sparclet tsc701 scheduling
409 (define_cpu_unit "sl_load0,sl_load1,sl_load2,sl_load3" "sparclet")
410 (define_cpu_unit "sl_store,sl_imul" "sparclet")
412 (define_reservation "sl_load_any" "(sl_load0 | sl_load1 | sl_load2 | sl_load3)")
413 (define_reservation "sl_load_all" "(sl_load0 + sl_load1 + sl_load2 + sl_load3)")
415 (define_insn_reservation "sl_ld" 3
416 (and (eq_attr "cpu" "tsc701")
417 (eq_attr "type" "load,sload"))
418 "sl_load_any, sl_load_any, sl_load_any")
420 (define_insn_reservation "sl_st" 3
421 (and (eq_attr "cpu" "tsc701")
422 (eq_attr "type" "store"))
423 "(sl_store+sl_load_all)*3")
425 (define_insn_reservation "sl_imul" 5
426 (and (eq_attr "cpu" "tsc701")
427 (eq_attr "type" "imul"))
430 ;; UltraSPARC-I/II scheduling
432 (define_cpu_unit "us1_fdivider,us1_fpm" "ultrasparc_0");
433 (define_cpu_unit "us1_fpa,us1_load_writeback" "ultrasparc_1")
434 (define_cpu_unit "us1_fps_0,us1_fps_1,us1_fpd_0,us1_fpd_1" "ultrasparc_1")
435 (define_cpu_unit "us1_slot0,us1_slot1,us1_slot2,us1_slot3" "ultrasparc_1")
436 (define_cpu_unit "us1_ieu0,us1_ieu1,us1_cti,us1_lsu" "ultrasparc_1")
438 (define_reservation "us1_slot012" "(us1_slot0 | us1_slot1 | us1_slot2)")
439 (define_reservation "us1_slotany" "(us1_slot0 | us1_slot1 | us1_slot2 | us1_slot3)")
440 (define_reservation "us1_single_issue" "us1_slot0 + us1_slot1 + us1_slot2 + us1_slot3")
442 (define_reservation "us1_fp_single" "(us1_fps_0 | us1_fps_1)")
443 (define_reservation "us1_fp_double" "(us1_fpd_0 | us1_fpd_1)")
444 ;; This is a simplified representation of the issue at hand.
445 ;; For most cases, going from one FP precision type insn to another
446 ;; just breaks up the insn group. However for some cases, such
447 ;; a situation causes the second insn to stall 2 more cycles.
448 (exclusion_set "us1_fps_0,us1_fps_1" "us1_fpd_0,us1_fpd_1")
450 ;; If we have to schedule an ieu1 specific instruction and we want
451 ;; to reserve the ieu0 unit as well, we must reserve it first. So for
452 ;; example we could not schedule this sequence:
455 ;; but we could schedule them together like this:
458 ;; This basically requires that ieu0 is reserved before ieu1 when
459 ;; it is required that both be reserved.
460 (absence_set "us1_ieu0" "us1_ieu1")
462 ;; This defines the slotting order. Most IEU instructions can only
463 ;; execute in the first three slots, FPU and branches can go into
464 ;; any slot. We represent instructions which "break the group"
465 ;; as requiring reservation of us1_slot0.
466 (absence_set "us1_slot0" "us1_slot1,us1_slot2,us1_slot3")
467 (absence_set "us1_slot1" "us1_slot2,us1_slot3")
468 (absence_set "us1_slot2" "us1_slot3")
470 (define_insn_reservation "us1_simple_ieuN" 1
471 (and (eq_attr "cpu" "ultrasparc")
472 (eq_attr "type" "ialu"))
473 "(us1_ieu0 | us1_ieu1) + us1_slot012")
475 (define_insn_reservation "us1_simple_ieu0" 1
476 (and (eq_attr "cpu" "ultrasparc")
477 (eq_attr "type" "shift"))
478 "us1_ieu0 + us1_slot012")
480 (define_insn_reservation "us1_simple_ieu1" 1
481 (and (eq_attr "cpu" "ultrasparc")
482 (eq_attr "type" "compare"))
483 "us1_ieu1 + us1_slot012")
485 (define_insn_reservation "us1_cmove" 2
486 (and (eq_attr "cpu" "ultrasparc")
487 (eq_attr "type" "cmove"))
488 "us1_single_issue, nothing")
490 (define_insn_reservation "us1_imul" 1
491 (and (eq_attr "cpu" "ultrasparc")
492 (eq_attr "type" "imul"))
495 (define_insn_reservation "us1_idiv" 1
496 (and (eq_attr "cpu" "ultrasparc")
497 (eq_attr "type" "idiv"))
500 ;; For loads, the "delayed return mode" behavior of the chip
501 ;; is represented using the us1_load_writeback resource.
502 (define_insn_reservation "us1_load" 2
503 (and (eq_attr "cpu" "ultrasparc")
504 (eq_attr "type" "load,fpload"))
505 "us1_lsu + us1_slot012, us1_load_writeback")
507 (define_insn_reservation "us1_load_signed" 3
508 (and (eq_attr "cpu" "ultrasparc")
509 (eq_attr "type" "sload"))
510 "us1_lsu + us1_slot012, nothing, us1_load_writeback")
512 (define_insn_reservation "us1_store" 1
513 (and (eq_attr "cpu" "ultrasparc")
514 (eq_attr "type" "store,fpstore"))
515 "us1_lsu + us1_slot012")
517 (define_insn_reservation "us1_branch" 1
518 (and (eq_attr "cpu" "ultrasparc")
519 (eq_attr "type" "branch"))
520 "us1_cti + us1_slotany")
522 (define_insn_reservation "us1_call_jmpl" 1
523 (and (eq_attr "cpu" "ultrasparc")
524 (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch"))
525 "us1_cti + us1_ieu1 + us1_slot0")
527 (define_insn_reservation "us1_fmov_single" 1
528 (and (and (eq_attr "cpu" "ultrasparc")
529 (eq_attr "type" "fpmove"))
530 (eq_attr "fptype" "single"))
531 "us1_fpa + us1_fp_single + us1_slotany")
533 (define_insn_reservation "us1_fmov_double" 1
534 (and (and (eq_attr "cpu" "ultrasparc")
535 (eq_attr "type" "fpmove"))
536 (eq_attr "fptype" "double"))
537 "us1_fpa + us1_fp_double + us1_slotany")
539 (define_insn_reservation "us1_fcmov_single" 2
540 (and (and (eq_attr "cpu" "ultrasparc")
541 (eq_attr "type" "fpcmove,fpcrmove"))
542 (eq_attr "fptype" "single"))
543 "us1_fpa + us1_fp_single + us1_slotany, nothing")
545 (define_insn_reservation "us1_fcmov_double" 2
546 (and (and (eq_attr "cpu" "ultrasparc")
547 (eq_attr "type" "fpcmove,fpcrmove"))
548 (eq_attr "fptype" "double"))
549 "us1_fpa + us1_fp_double + us1_slotany, nothing")
551 (define_insn_reservation "us1_faddsub_single" 4
552 (and (and (eq_attr "cpu" "ultrasparc")
553 (eq_attr "type" "fp"))
554 (eq_attr "fptype" "single"))
555 "us1_fpa + us1_fp_single + us1_slotany, nothing*3")
557 (define_insn_reservation "us1_faddsub_double" 4
558 (and (and (eq_attr "cpu" "ultrasparc")
559 (eq_attr "type" "fp"))
560 (eq_attr "fptype" "double"))
561 "us1_fpa + us1_fp_double + us1_slotany, nothing*3")
563 (define_insn_reservation "us1_fpcmp_single" 1
564 (and (and (eq_attr "cpu" "ultrasparc")
565 (eq_attr "type" "fpcmp"))
566 (eq_attr "fptype" "single"))
567 "us1_fpa + us1_fp_single + us1_slotany")
569 (define_insn_reservation "us1_fpcmp_double" 1
570 (and (and (eq_attr "cpu" "ultrasparc")
571 (eq_attr "type" "fpcmp"))
572 (eq_attr "fptype" "double"))
573 "us1_fpa + us1_fp_double + us1_slotany")
575 (define_insn_reservation "us1_fmult_single" 4
576 (and (and (eq_attr "cpu" "ultrasparc")
577 (eq_attr "type" "fpmul"))
578 (eq_attr "fptype" "single"))
579 "us1_fpm + us1_fp_single + us1_slotany, nothing*3")
581 (define_insn_reservation "us1_fmult_double" 4
582 (and (and (eq_attr "cpu" "ultrasparc")
583 (eq_attr "type" "fpmul"))
584 (eq_attr "fptype" "double"))
585 "us1_fpm + us1_fp_double + us1_slotany, nothing*3")
587 ;; This is actually in theory dangerous, because it is possible
588 ;; for the chip to prematurely dispatch the dependant instruction
589 ;; in the G stage, resulting in a 9 cycle stall. However I have never
590 ;; been able to trigger this case myself even with hand written code,
591 ;; so it must require some rare complicated pipeline state.
593 "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double"
594 "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
596 ;; Floating point divide and square root use the multiplier unit
597 ;; for final rounding 3 cycles before the divide/sqrt is complete.
599 (define_insn_reservation "us1_fdivs"
601 (and (eq_attr "cpu" "ultrasparc")
602 (eq_attr "type" "fpdivs,fpsqrts"))
603 "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*8, (us1_fpm + us1_fdivider), us1_fdivider*2"
609 "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
611 (define_insn_reservation "us1_fdivd"
613 (and (eq_attr "cpu" "ultrasparc")
614 (eq_attr "type" "fpdivd,fpsqrtd"))
615 "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*18, (us1_fpm + us1_fdivider), us1_fdivider*2"
620 "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
622 ;; Any store may multi issue with the insn creating the source
623 ;; data as long as that creating insn is not an FPU div/sqrt.
624 ;; We need a special guard function because this bypass does
625 ;; not apply to the address inputs of the store.
626 (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"
627 "ultrasparc_store_bypass_p")
629 ;; An integer branch may execute in the same cycle as the compare
630 ;; creating the condition codes.
631 (define_bypass 0 "us1_simple_ieu1" "us1_branch")
633 ;; UltraSPARC-III scheduling
635 ;; A much simpler beast, no silly slotting rules and both
636 ;; integer units are fully symmetric. It does still have
637 ;; single-issue instructions though.
639 (define_cpu_unit "us3_a0,us3_a1,us3_ms,us3_br,us3_fpm" "ultrasparc3_0")
640 (define_cpu_unit "us3_slot0,us3_slot1,us3_slot2,us3_slot3,us3_fpa" "ultrasparc3_1")
641 (define_cpu_unit "us3_load_writeback" "ultrasparc3_1")
643 (define_reservation "us3_slotany" "(us3_slot0 | us3_slot1 | us3_slot2 | us3_slot3)")
644 (define_reservation "us3_single_issue" "us3_slot0 + us3_slot1 + us3_slot2 + us3_slot3")
645 (define_reservation "us3_ax" "(us3_a0 | us3_a1)")
647 (define_insn_reservation "us3_integer" 1
648 (and (eq_attr "cpu" "ultrasparc3")
649 (eq_attr "type" "ialu,shift,compare"))
650 "us3_ax + us3_slotany")
652 (define_insn_reservation "us3_cmove" 2
653 (and (eq_attr "cpu" "ultrasparc3")
654 (eq_attr "type" "cmove"))
655 "us3_ms + us3_br + us3_slotany, nothing")
657 ;; ??? Not entirely accurate.
658 ;; ??? It can run from 6 to 9 cycles. The first cycle the MS pipe
659 ;; ??? is needed, and the instruction group is broken right after
660 ;; ??? the imul. Then 'helper' instructions are generated to perform
661 ;; ??? each further stage of the multiplication, each such 'helper' is
662 ;; ??? single group. So, the reservation aspect is represented accurately
663 ;; ??? here, but the variable cycles are not.
664 ;; ??? Currently I have no idea how to determine the variability, but once
665 ;; ??? known we can simply add a define_bypass or similar to model it.
666 (define_insn_reservation "us3_imul" 6
667 (and (eq_attr "cpu" "ultrasparc3")
668 (eq_attr "type" "imul"))
669 "us3_ms + us3_slotany, us3_single_issue*5")
671 (define_insn_reservation "us3_idiv" 71
672 (and (eq_attr "cpu" "ultrasparc3")
673 (eq_attr "type" "idiv"))
674 "us3_ms + us3_slotany, us3_single_issue*70")
676 ;; UltraSPARC-III has a similar load delay as UltraSPARC-I/II except
677 ;; that all loads except 32-bit/64-bit unsigned loads take the extra
678 ;; delay for sign/zero extension.
679 (define_insn_reservation "us3_2cycle_load" 2
680 (and (eq_attr "cpu" "ultrasparc3")
681 (and (eq_attr "type" "load,fpload")
682 (eq_attr "us3load_type" "2cycle")))
683 "us3_ms + us3_slotany, us3_load_writeback")
685 (define_insn_reservation "us3_load_delayed" 3
686 (and (eq_attr "cpu" "ultrasparc3")
687 (and (eq_attr "type" "load,sload")
688 (eq_attr "us3load_type" "3cycle")))
689 "us3_ms + us3_slotany, nothing, us3_load_writeback")
691 (define_insn_reservation "us3_store" 1
692 (and (eq_attr "cpu" "ultrasparc3")
693 (eq_attr "type" "store,fpstore"))
694 "us3_ms + us3_slotany")
696 (define_insn_reservation "us3_branch" 1
697 (and (eq_attr "cpu" "ultrasparc3")
698 (eq_attr "type" "branch"))
699 "us3_br + us3_slotany")
701 (define_insn_reservation "us3_call_jmpl" 1
702 (and (eq_attr "cpu" "ultrasparc3")
703 (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch"))
704 "us3_br + us3_ms + us3_slotany")
706 (define_insn_reservation "us3_fmov" 3
707 (and (eq_attr "cpu" "ultrasparc3")
708 (eq_attr "type" "fpmove"))
709 "us3_fpa + us3_slotany, nothing*2")
711 (define_insn_reservation "us3_fcmov" 3
712 (and (eq_attr "cpu" "ultrasparc3")
713 (eq_attr "type" "fpcmove"))
714 "us3_fpa + us3_br + us3_slotany, nothing*2")
716 (define_insn_reservation "us3_fcrmov" 3
717 (and (eq_attr "cpu" "ultrasparc3")
718 (eq_attr "type" "fpcrmove"))
719 "us3_fpa + us3_ms + us3_slotany, nothing*2")
721 (define_insn_reservation "us3_faddsub" 4
722 (and (eq_attr "cpu" "ultrasparc3")
723 (eq_attr "type" "fp"))
724 "us3_fpa + us3_slotany, nothing*3")
726 (define_insn_reservation "us3_fpcmp" 5
727 (and (eq_attr "cpu" "ultrasparc3")
728 (eq_attr "type" "fpcmp"))
729 "us3_fpa + us3_slotany, nothing*4")
731 (define_insn_reservation "us3_fmult" 4
732 (and (eq_attr "cpu" "ultrasparc3")
733 (eq_attr "type" "fpmul"))
734 "us3_fpm + us3_slotany, nothing*3")
736 (define_insn_reservation "us3_fdivs" 17
737 (and (eq_attr "cpu" "ultrasparc3")
738 (eq_attr "type" "fpdivs"))
739 "(us3_fpm + us3_slotany), us3_fpm*14, nothing*2")
741 (define_insn_reservation "us3_fsqrts" 20
742 (and (eq_attr "cpu" "ultrasparc3")
743 (eq_attr "type" "fpsqrts"))
744 "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2")
746 (define_insn_reservation "us3_fdivd" 20
747 (and (eq_attr "cpu" "ultrasparc3")
748 (eq_attr "type" "fpdivd"))
749 "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2")
751 (define_insn_reservation "us3_fsqrtd" 29
752 (and (eq_attr "cpu" "ultrasparc3")
753 (eq_attr "type" "fpsqrtd"))
754 "(us3_fpm + us3_slotany), us3_fpm*26, nothing*2")
756 ;; Any store may multi issue with the insn creating the source
757 ;; data as long as that creating insn is not an FPU div/sqrt.
758 ;; We need a special guard function because this bypass does
759 ;; not apply to the address inputs of the store.
760 (define_bypass 0 "us3_integer,us3_faddsub,us3_fmov,us3_fcmov,us3_fmult" "us3_store"
761 "ultrasparc_store_bypass_p")
763 ;; An integer branch may execute in the same cycle as the compare
764 ;; creating the condition codes.
765 (define_bypass 0 "us3_integer" "us3_branch")
767 ;; If FMOVfcc is user of FPCMP, latency is only 1 cycle.
768 (define_bypass 1 "us3_fpcmp" "us3_fcmov")
771 ;; Compare instructions.
772 ;; This controls RTL generation and register allocation.
774 ;; We generate RTL for comparisons and branches by having the cmpxx
775 ;; patterns store away the operands. Then, the scc and bcc patterns
776 ;; emit RTL for both the compare and the branch.
778 ;; We do this because we want to generate different code for an sne and
779 ;; seq insn. In those cases, if the second operand of the compare is not
780 ;; const0_rtx, we want to compute the xor of the two operands and test
783 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
784 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
785 ;; insns that actually require more than one machine instruction.
787 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
789 (define_expand "cmpsi"
791 (compare:CC (match_operand:SI 0 "register_operand" "")
792 (match_operand:SI 1 "arith_operand" "")))]
796 sparc_compare_op0 = operands[0];
797 sparc_compare_op1 = operands[1];
801 (define_expand "cmpdi"
803 (compare:CCX (match_operand:DI 0 "register_operand" "")
804 (match_operand:DI 1 "arith_double_operand" "")))]
808 sparc_compare_op0 = operands[0];
809 sparc_compare_op1 = operands[1];
813 (define_expand "cmpsf"
814 ;; The 96 here isn't ever used by anyone.
816 (compare:CCFP (match_operand:SF 0 "register_operand" "")
817 (match_operand:SF 1 "register_operand" "")))]
821 sparc_compare_op0 = operands[0];
822 sparc_compare_op1 = operands[1];
826 (define_expand "cmpdf"
827 ;; The 96 here isn't ever used by anyone.
829 (compare:CCFP (match_operand:DF 0 "register_operand" "")
830 (match_operand:DF 1 "register_operand" "")))]
834 sparc_compare_op0 = operands[0];
835 sparc_compare_op1 = operands[1];
839 (define_expand "cmptf"
840 ;; The 96 here isn't ever used by anyone.
842 (compare:CCFP (match_operand:TF 0 "register_operand" "")
843 (match_operand:TF 1 "register_operand" "")))]
847 sparc_compare_op0 = operands[0];
848 sparc_compare_op1 = operands[1];
852 ;; Now the compare DEFINE_INSNs.
854 (define_insn "*cmpsi_insn"
856 (compare:CC (match_operand:SI 0 "register_operand" "r")
857 (match_operand:SI 1 "arith_operand" "rI")))]
860 [(set_attr "type" "compare")])
862 (define_insn "*cmpdi_sp64"
864 (compare:CCX (match_operand:DI 0 "register_operand" "r")
865 (match_operand:DI 1 "arith_double_operand" "rHI")))]
868 [(set_attr "type" "compare")])
870 (define_insn "*cmpsf_fpe"
871 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
872 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
873 (match_operand:SF 2 "register_operand" "f")))]
878 return \"fcmpes\\t%0, %1, %2\";
879 return \"fcmpes\\t%1, %2\";
881 [(set_attr "type" "fpcmp")])
883 (define_insn "*cmpdf_fpe"
884 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
885 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
886 (match_operand:DF 2 "register_operand" "e")))]
891 return \"fcmped\\t%0, %1, %2\";
892 return \"fcmped\\t%1, %2\";
894 [(set_attr "type" "fpcmp")
895 (set_attr "fptype" "double")])
897 (define_insn "*cmptf_fpe"
898 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
899 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
900 (match_operand:TF 2 "register_operand" "e")))]
901 "TARGET_FPU && TARGET_HARD_QUAD"
905 return \"fcmpeq\\t%0, %1, %2\";
906 return \"fcmpeq\\t%1, %2\";
908 [(set_attr "type" "fpcmp")])
910 (define_insn "*cmpsf_fp"
911 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
912 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
913 (match_operand:SF 2 "register_operand" "f")))]
918 return \"fcmps\\t%0, %1, %2\";
919 return \"fcmps\\t%1, %2\";
921 [(set_attr "type" "fpcmp")])
923 (define_insn "*cmpdf_fp"
924 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
925 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
926 (match_operand:DF 2 "register_operand" "e")))]
931 return \"fcmpd\\t%0, %1, %2\";
932 return \"fcmpd\\t%1, %2\";
934 [(set_attr "type" "fpcmp")
935 (set_attr "fptype" "double")])
937 (define_insn "*cmptf_fp"
938 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
939 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
940 (match_operand:TF 2 "register_operand" "e")))]
941 "TARGET_FPU && TARGET_HARD_QUAD"
945 return \"fcmpq\\t%0, %1, %2\";
946 return \"fcmpq\\t%1, %2\";
948 [(set_attr "type" "fpcmp")])
950 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
951 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
952 ;; the same code as v8 (the addx/subx method has more applications). The
953 ;; exception to this is "reg != 0" which can be done in one instruction on v9
954 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
957 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
958 ;; generate addcc/subcc instructions.
960 (define_expand "seqsi_special"
962 (xor:SI (match_operand:SI 1 "register_operand" "")
963 (match_operand:SI 2 "register_operand" "")))
964 (parallel [(set (match_operand:SI 0 "register_operand" "")
965 (eq:SI (match_dup 3) (const_int 0)))
966 (clobber (reg:CC 100))])]
968 "{ operands[3] = gen_reg_rtx (SImode); }")
970 (define_expand "seqdi_special"
972 (xor:DI (match_operand:DI 1 "register_operand" "")
973 (match_operand:DI 2 "register_operand" "")))
974 (set (match_operand:DI 0 "register_operand" "")
975 (eq:DI (match_dup 3) (const_int 0)))]
977 "{ operands[3] = gen_reg_rtx (DImode); }")
979 (define_expand "snesi_special"
981 (xor:SI (match_operand:SI 1 "register_operand" "")
982 (match_operand:SI 2 "register_operand" "")))
983 (parallel [(set (match_operand:SI 0 "register_operand" "")
984 (ne:SI (match_dup 3) (const_int 0)))
985 (clobber (reg:CC 100))])]
987 "{ operands[3] = gen_reg_rtx (SImode); }")
989 (define_expand "snedi_special"
991 (xor:DI (match_operand:DI 1 "register_operand" "")
992 (match_operand:DI 2 "register_operand" "")))
993 (set (match_operand:DI 0 "register_operand" "")
994 (ne:DI (match_dup 3) (const_int 0)))]
996 "{ operands[3] = gen_reg_rtx (DImode); }")
998 (define_expand "seqdi_special_trunc"
1000 (xor:DI (match_operand:DI 1 "register_operand" "")
1001 (match_operand:DI 2 "register_operand" "")))
1002 (set (match_operand:SI 0 "register_operand" "")
1003 (eq:SI (match_dup 3) (const_int 0)))]
1005 "{ operands[3] = gen_reg_rtx (DImode); }")
1007 (define_expand "snedi_special_trunc"
1009 (xor:DI (match_operand:DI 1 "register_operand" "")
1010 (match_operand:DI 2 "register_operand" "")))
1011 (set (match_operand:SI 0 "register_operand" "")
1012 (ne:SI (match_dup 3) (const_int 0)))]
1014 "{ operands[3] = gen_reg_rtx (DImode); }")
1016 (define_expand "seqsi_special_extend"
1018 (xor:SI (match_operand:SI 1 "register_operand" "")
1019 (match_operand:SI 2 "register_operand" "")))
1020 (parallel [(set (match_operand:DI 0 "register_operand" "")
1021 (eq:DI (match_dup 3) (const_int 0)))
1022 (clobber (reg:CC 100))])]
1024 "{ operands[3] = gen_reg_rtx (SImode); }")
1026 (define_expand "snesi_special_extend"
1028 (xor:SI (match_operand:SI 1 "register_operand" "")
1029 (match_operand:SI 2 "register_operand" "")))
1030 (parallel [(set (match_operand:DI 0 "register_operand" "")
1031 (ne:DI (match_dup 3) (const_int 0)))
1032 (clobber (reg:CC 100))])]
1034 "{ operands[3] = gen_reg_rtx (SImode); }")
1036 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
1037 ;; However, the code handles both SImode and DImode.
1038 (define_expand "seq"
1039 [(set (match_operand:SI 0 "intreg_operand" "")
1040 (eq:SI (match_dup 1) (const_int 0)))]
1044 if (GET_MODE (sparc_compare_op0) == SImode)
1048 if (GET_MODE (operands[0]) == SImode)
1049 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
1051 else if (! TARGET_ARCH64)
1054 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
1059 else if (GET_MODE (sparc_compare_op0) == DImode)
1063 if (! TARGET_ARCH64)
1065 else if (GET_MODE (operands[0]) == SImode)
1066 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
1069 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
1074 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1076 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1077 emit_jump_insn (gen_sne (operands[0]));
1082 if (gen_v9_scc (EQ, operands))
1089 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
1090 ;; However, the code handles both SImode and DImode.
1091 (define_expand "sne"
1092 [(set (match_operand:SI 0 "intreg_operand" "")
1093 (ne:SI (match_dup 1) (const_int 0)))]
1097 if (GET_MODE (sparc_compare_op0) == SImode)
1101 if (GET_MODE (operands[0]) == SImode)
1102 pat = gen_snesi_special (operands[0], sparc_compare_op0,
1104 else if (! TARGET_ARCH64)
1107 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
1112 else if (GET_MODE (sparc_compare_op0) == DImode)
1116 if (! TARGET_ARCH64)
1118 else if (GET_MODE (operands[0]) == SImode)
1119 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
1122 pat = gen_snedi_special (operands[0], sparc_compare_op0,
1127 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1129 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1130 emit_jump_insn (gen_sne (operands[0]));
1135 if (gen_v9_scc (NE, operands))
1142 (define_expand "sgt"
1143 [(set (match_operand:SI 0 "intreg_operand" "")
1144 (gt:SI (match_dup 1) (const_int 0)))]
1148 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1150 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1151 emit_jump_insn (gen_sne (operands[0]));
1156 if (gen_v9_scc (GT, operands))
1163 (define_expand "slt"
1164 [(set (match_operand:SI 0 "intreg_operand" "")
1165 (lt:SI (match_dup 1) (const_int 0)))]
1169 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1171 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1172 emit_jump_insn (gen_sne (operands[0]));
1177 if (gen_v9_scc (LT, operands))
1184 (define_expand "sge"
1185 [(set (match_operand:SI 0 "intreg_operand" "")
1186 (ge:SI (match_dup 1) (const_int 0)))]
1190 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1192 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1193 emit_jump_insn (gen_sne (operands[0]));
1198 if (gen_v9_scc (GE, operands))
1205 (define_expand "sle"
1206 [(set (match_operand:SI 0 "intreg_operand" "")
1207 (le:SI (match_dup 1) (const_int 0)))]
1211 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1213 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1214 emit_jump_insn (gen_sne (operands[0]));
1219 if (gen_v9_scc (LE, operands))
1226 (define_expand "sgtu"
1227 [(set (match_operand:SI 0 "intreg_operand" "")
1228 (gtu:SI (match_dup 1) (const_int 0)))]
1236 /* We can do ltu easily, so if both operands are registers, swap them and
1238 if ((GET_CODE (sparc_compare_op0) == REG
1239 || GET_CODE (sparc_compare_op0) == SUBREG)
1240 && (GET_CODE (sparc_compare_op1) == REG
1241 || GET_CODE (sparc_compare_op1) == SUBREG))
1243 tem = sparc_compare_op0;
1244 sparc_compare_op0 = sparc_compare_op1;
1245 sparc_compare_op1 = tem;
1246 pat = gen_sltu (operands[0]);
1247 if (pat == NULL_RTX)
1255 if (gen_v9_scc (GTU, operands))
1261 (define_expand "sltu"
1262 [(set (match_operand:SI 0 "intreg_operand" "")
1263 (ltu:SI (match_dup 1) (const_int 0)))]
1269 if (gen_v9_scc (LTU, operands))
1272 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1275 (define_expand "sgeu"
1276 [(set (match_operand:SI 0 "intreg_operand" "")
1277 (geu:SI (match_dup 1) (const_int 0)))]
1283 if (gen_v9_scc (GEU, operands))
1286 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1289 (define_expand "sleu"
1290 [(set (match_operand:SI 0 "intreg_operand" "")
1291 (leu:SI (match_dup 1) (const_int 0)))]
1299 /* We can do geu easily, so if both operands are registers, swap them and
1301 if ((GET_CODE (sparc_compare_op0) == REG
1302 || GET_CODE (sparc_compare_op0) == SUBREG)
1303 && (GET_CODE (sparc_compare_op1) == REG
1304 || GET_CODE (sparc_compare_op1) == SUBREG))
1306 tem = sparc_compare_op0;
1307 sparc_compare_op0 = sparc_compare_op1;
1308 sparc_compare_op1 = tem;
1309 pat = gen_sgeu (operands[0]);
1310 if (pat == NULL_RTX)
1318 if (gen_v9_scc (LEU, operands))
1324 ;; Now the DEFINE_INSNs for the scc cases.
1326 ;; The SEQ and SNE patterns are special because they can be done
1327 ;; without any branching and do not involve a COMPARE. We want
1328 ;; them to always use the splitz below so the results can be
1331 (define_insn "*snesi_zero"
1332 [(set (match_operand:SI 0 "register_operand" "=r")
1333 (ne:SI (match_operand:SI 1 "register_operand" "r")
1335 (clobber (reg:CC 100))]
1338 [(set_attr "length" "2")])
1341 [(set (match_operand:SI 0 "register_operand" "")
1342 (ne:SI (match_operand:SI 1 "register_operand" "")
1344 (clobber (reg:CC 100))]
1346 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1348 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1351 (define_insn "*neg_snesi_zero"
1352 [(set (match_operand:SI 0 "register_operand" "=r")
1353 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1355 (clobber (reg:CC 100))]
1358 [(set_attr "length" "2")])
1361 [(set (match_operand:SI 0 "register_operand" "")
1362 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1364 (clobber (reg:CC 100))]
1366 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1368 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1371 (define_insn "*snesi_zero_extend"
1372 [(set (match_operand:DI 0 "register_operand" "=r")
1373 (ne:DI (match_operand:SI 1 "register_operand" "r")
1375 (clobber (reg:CC 100))]
1378 [(set_attr "length" "2")])
1381 [(set (match_operand:DI 0 "register_operand" "")
1382 (ne:DI (match_operand:SI 1 "register_operand" "")
1384 (clobber (reg:CC 100))]
1386 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1388 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1390 (ltu:SI (reg:CC_NOOV 100)
1394 (define_insn "*snedi_zero"
1395 [(set (match_operand:DI 0 "register_operand" "=&r")
1396 (ne:DI (match_operand:DI 1 "register_operand" "r")
1400 [(set_attr "length" "2")])
1403 [(set (match_operand:DI 0 "register_operand" "")
1404 (ne:DI (match_operand:DI 1 "register_operand" "")
1407 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1408 [(set (match_dup 0) (const_int 0))
1409 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1415 (define_insn "*neg_snedi_zero"
1416 [(set (match_operand:DI 0 "register_operand" "=&r")
1417 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1421 [(set_attr "length" "2")])
1424 [(set (match_operand:DI 0 "register_operand" "")
1425 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1428 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1429 [(set (match_dup 0) (const_int 0))
1430 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1436 (define_insn "*snedi_zero_trunc"
1437 [(set (match_operand:SI 0 "register_operand" "=&r")
1438 (ne:SI (match_operand:DI 1 "register_operand" "r")
1442 [(set_attr "length" "2")])
1445 [(set (match_operand:SI 0 "register_operand" "")
1446 (ne:SI (match_operand:DI 1 "register_operand" "")
1449 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1450 [(set (match_dup 0) (const_int 0))
1451 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1457 (define_insn "*seqsi_zero"
1458 [(set (match_operand:SI 0 "register_operand" "=r")
1459 (eq:SI (match_operand:SI 1 "register_operand" "r")
1461 (clobber (reg:CC 100))]
1464 [(set_attr "length" "2")])
1467 [(set (match_operand:SI 0 "register_operand" "")
1468 (eq:SI (match_operand:SI 1 "register_operand" "")
1470 (clobber (reg:CC 100))]
1472 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1474 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1477 (define_insn "*neg_seqsi_zero"
1478 [(set (match_operand:SI 0 "register_operand" "=r")
1479 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1481 (clobber (reg:CC 100))]
1484 [(set_attr "length" "2")])
1487 [(set (match_operand:SI 0 "register_operand" "")
1488 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1490 (clobber (reg:CC 100))]
1492 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1494 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1497 (define_insn "*seqsi_zero_extend"
1498 [(set (match_operand:DI 0 "register_operand" "=r")
1499 (eq:DI (match_operand:SI 1 "register_operand" "r")
1501 (clobber (reg:CC 100))]
1504 [(set_attr "length" "2")])
1507 [(set (match_operand:DI 0 "register_operand" "")
1508 (eq:DI (match_operand:SI 1 "register_operand" "")
1510 (clobber (reg:CC 100))]
1512 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1514 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1516 (ltu:SI (reg:CC_NOOV 100)
1520 (define_insn "*seqdi_zero"
1521 [(set (match_operand:DI 0 "register_operand" "=&r")
1522 (eq:DI (match_operand:DI 1 "register_operand" "r")
1526 [(set_attr "length" "2")])
1529 [(set (match_operand:DI 0 "register_operand" "")
1530 (eq:DI (match_operand:DI 1 "register_operand" "")
1533 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1534 [(set (match_dup 0) (const_int 0))
1535 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1541 (define_insn "*neg_seqdi_zero"
1542 [(set (match_operand:DI 0 "register_operand" "=&r")
1543 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1547 [(set_attr "length" "2")])
1550 [(set (match_operand:DI 0 "register_operand" "")
1551 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1554 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1555 [(set (match_dup 0) (const_int 0))
1556 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1562 (define_insn "*seqdi_zero_trunc"
1563 [(set (match_operand:SI 0 "register_operand" "=&r")
1564 (eq:SI (match_operand:DI 1 "register_operand" "r")
1568 [(set_attr "length" "2")])
1571 [(set (match_operand:SI 0 "register_operand" "")
1572 (eq:SI (match_operand:DI 1 "register_operand" "")
1575 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1576 [(set (match_dup 0) (const_int 0))
1577 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1583 ;; We can also do (x + (i == 0)) and related, so put them in.
1584 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1587 (define_insn "*x_plus_i_ne_0"
1588 [(set (match_operand:SI 0 "register_operand" "=r")
1589 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1591 (match_operand:SI 2 "register_operand" "r")))
1592 (clobber (reg:CC 100))]
1595 [(set_attr "length" "2")])
1598 [(set (match_operand:SI 0 "register_operand" "")
1599 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1601 (match_operand:SI 2 "register_operand" "")))
1602 (clobber (reg:CC 100))]
1604 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1606 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1610 (define_insn "*x_minus_i_ne_0"
1611 [(set (match_operand:SI 0 "register_operand" "=r")
1612 (minus:SI (match_operand:SI 2 "register_operand" "r")
1613 (ne:SI (match_operand:SI 1 "register_operand" "r")
1615 (clobber (reg:CC 100))]
1618 [(set_attr "length" "2")])
1621 [(set (match_operand:SI 0 "register_operand" "")
1622 (minus:SI (match_operand:SI 2 "register_operand" "")
1623 (ne:SI (match_operand:SI 1 "register_operand" "")
1625 (clobber (reg:CC 100))]
1627 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1629 (set (match_dup 0) (minus:SI (match_dup 2)
1630 (ltu:SI (reg:CC 100) (const_int 0))))]
1633 (define_insn "*x_plus_i_eq_0"
1634 [(set (match_operand:SI 0 "register_operand" "=r")
1635 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1637 (match_operand:SI 2 "register_operand" "r")))
1638 (clobber (reg:CC 100))]
1641 [(set_attr "length" "2")])
1644 [(set (match_operand:SI 0 "register_operand" "")
1645 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1647 (match_operand:SI 2 "register_operand" "")))
1648 (clobber (reg:CC 100))]
1650 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1652 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1656 (define_insn "*x_minus_i_eq_0"
1657 [(set (match_operand:SI 0 "register_operand" "=r")
1658 (minus:SI (match_operand:SI 2 "register_operand" "r")
1659 (eq:SI (match_operand:SI 1 "register_operand" "r")
1661 (clobber (reg:CC 100))]
1664 [(set_attr "length" "2")])
1667 [(set (match_operand:SI 0 "register_operand" "")
1668 (minus:SI (match_operand:SI 2 "register_operand" "")
1669 (eq:SI (match_operand:SI 1 "register_operand" "")
1671 (clobber (reg:CC 100))]
1673 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1675 (set (match_dup 0) (minus:SI (match_dup 2)
1676 (geu:SI (reg:CC 100) (const_int 0))))]
1679 ;; We can also do GEU and LTU directly, but these operate after a compare.
1680 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1683 (define_insn "*sltu_insn"
1684 [(set (match_operand:SI 0 "register_operand" "=r")
1685 (ltu:SI (reg:CC 100) (const_int 0)))]
1687 "addx\\t%%g0, 0, %0"
1688 [(set_attr "type" "misc")])
1690 (define_insn "*neg_sltu_insn"
1691 [(set (match_operand:SI 0 "register_operand" "=r")
1692 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1694 "subx\\t%%g0, 0, %0"
1695 [(set_attr "type" "misc")])
1697 ;; ??? Combine should canonicalize these next two to the same pattern.
1698 (define_insn "*neg_sltu_minus_x"
1699 [(set (match_operand:SI 0 "register_operand" "=r")
1700 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1701 (match_operand:SI 1 "arith_operand" "rI")))]
1703 "subx\\t%%g0, %1, %0"
1704 [(set_attr "type" "misc")])
1706 (define_insn "*neg_sltu_plus_x"
1707 [(set (match_operand:SI 0 "register_operand" "=r")
1708 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1709 (match_operand:SI 1 "arith_operand" "rI"))))]
1711 "subx\\t%%g0, %1, %0"
1712 [(set_attr "type" "misc")])
1714 (define_insn "*sgeu_insn"
1715 [(set (match_operand:SI 0 "register_operand" "=r")
1716 (geu:SI (reg:CC 100) (const_int 0)))]
1718 "subx\\t%%g0, -1, %0"
1719 [(set_attr "type" "misc")])
1721 (define_insn "*neg_sgeu_insn"
1722 [(set (match_operand:SI 0 "register_operand" "=r")
1723 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1725 "addx\\t%%g0, -1, %0"
1726 [(set_attr "type" "misc")])
1728 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1729 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1732 (define_insn "*sltu_plus_x"
1733 [(set (match_operand:SI 0 "register_operand" "=r")
1734 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1735 (match_operand:SI 1 "arith_operand" "rI")))]
1737 "addx\\t%%g0, %1, %0"
1738 [(set_attr "type" "misc")])
1740 (define_insn "*sltu_plus_x_plus_y"
1741 [(set (match_operand:SI 0 "register_operand" "=r")
1742 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1743 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1744 (match_operand:SI 2 "arith_operand" "rI"))))]
1747 [(set_attr "type" "misc")])
1749 (define_insn "*x_minus_sltu"
1750 [(set (match_operand:SI 0 "register_operand" "=r")
1751 (minus:SI (match_operand:SI 1 "register_operand" "r")
1752 (ltu:SI (reg:CC 100) (const_int 0))))]
1755 [(set_attr "type" "misc")])
1757 ;; ??? Combine should canonicalize these next two to the same pattern.
1758 (define_insn "*x_minus_y_minus_sltu"
1759 [(set (match_operand:SI 0 "register_operand" "=r")
1760 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1761 (match_operand:SI 2 "arith_operand" "rI"))
1762 (ltu:SI (reg:CC 100) (const_int 0))))]
1764 "subx\\t%r1, %2, %0"
1765 [(set_attr "type" "misc")])
1767 (define_insn "*x_minus_sltu_plus_y"
1768 [(set (match_operand:SI 0 "register_operand" "=r")
1769 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1770 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1771 (match_operand:SI 2 "arith_operand" "rI"))))]
1773 "subx\\t%r1, %2, %0"
1774 [(set_attr "type" "misc")])
1776 (define_insn "*sgeu_plus_x"
1777 [(set (match_operand:SI 0 "register_operand" "=r")
1778 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1779 (match_operand:SI 1 "register_operand" "r")))]
1782 [(set_attr "type" "misc")])
1784 (define_insn "*x_minus_sgeu"
1785 [(set (match_operand:SI 0 "register_operand" "=r")
1786 (minus:SI (match_operand:SI 1 "register_operand" "r")
1787 (geu:SI (reg:CC 100) (const_int 0))))]
1790 [(set_attr "type" "misc")])
1793 [(set (match_operand:SI 0 "register_operand" "")
1794 (match_operator:SI 2 "noov_compare_op"
1795 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1797 ;; 32 bit LTU/GEU are better implemented using addx/subx
1798 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1799 && (GET_MODE (operands[1]) == CCXmode
1800 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1801 [(set (match_dup 0) (const_int 0))
1803 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1809 ;; These control RTL generation for conditional jump insns
1811 ;; The quad-word fp compare library routines all return nonzero to indicate
1812 ;; true, which is different from the equivalent libgcc routines, so we must
1813 ;; handle them specially here.
1815 (define_expand "beq"
1817 (if_then_else (eq (match_dup 1) (const_int 0))
1818 (label_ref (match_operand 0 "" ""))
1823 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1824 && GET_CODE (sparc_compare_op0) == REG
1825 && GET_MODE (sparc_compare_op0) == DImode)
1827 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1830 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1832 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1833 emit_jump_insn (gen_bne (operands[0]));
1836 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1839 (define_expand "bne"
1841 (if_then_else (ne (match_dup 1) (const_int 0))
1842 (label_ref (match_operand 0 "" ""))
1847 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1848 && GET_CODE (sparc_compare_op0) == REG
1849 && GET_MODE (sparc_compare_op0) == DImode)
1851 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1854 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1856 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1857 emit_jump_insn (gen_bne (operands[0]));
1860 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1863 (define_expand "bgt"
1865 (if_then_else (gt (match_dup 1) (const_int 0))
1866 (label_ref (match_operand 0 "" ""))
1871 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1872 && GET_CODE (sparc_compare_op0) == REG
1873 && GET_MODE (sparc_compare_op0) == DImode)
1875 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1878 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1880 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1881 emit_jump_insn (gen_bne (operands[0]));
1884 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1887 (define_expand "bgtu"
1889 (if_then_else (gtu (match_dup 1) (const_int 0))
1890 (label_ref (match_operand 0 "" ""))
1894 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1897 (define_expand "blt"
1899 (if_then_else (lt (match_dup 1) (const_int 0))
1900 (label_ref (match_operand 0 "" ""))
1905 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1906 && GET_CODE (sparc_compare_op0) == REG
1907 && GET_MODE (sparc_compare_op0) == DImode)
1909 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1912 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1914 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1915 emit_jump_insn (gen_bne (operands[0]));
1918 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1921 (define_expand "bltu"
1923 (if_then_else (ltu (match_dup 1) (const_int 0))
1924 (label_ref (match_operand 0 "" ""))
1928 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1931 (define_expand "bge"
1933 (if_then_else (ge (match_dup 1) (const_int 0))
1934 (label_ref (match_operand 0 "" ""))
1939 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1940 && GET_CODE (sparc_compare_op0) == REG
1941 && GET_MODE (sparc_compare_op0) == DImode)
1943 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1946 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1948 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1949 emit_jump_insn (gen_bne (operands[0]));
1952 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1955 (define_expand "bgeu"
1957 (if_then_else (geu (match_dup 1) (const_int 0))
1958 (label_ref (match_operand 0 "" ""))
1962 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1965 (define_expand "ble"
1967 (if_then_else (le (match_dup 1) (const_int 0))
1968 (label_ref (match_operand 0 "" ""))
1973 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1974 && GET_CODE (sparc_compare_op0) == REG
1975 && GET_MODE (sparc_compare_op0) == DImode)
1977 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1980 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1982 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1983 emit_jump_insn (gen_bne (operands[0]));
1986 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1989 (define_expand "bleu"
1991 (if_then_else (leu (match_dup 1) (const_int 0))
1992 (label_ref (match_operand 0 "" ""))
1996 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1999 (define_expand "bunordered"
2001 (if_then_else (unordered (match_dup 1) (const_int 0))
2002 (label_ref (match_operand 0 "" ""))
2007 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2009 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
2011 emit_jump_insn (gen_beq (operands[0]));
2014 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
2018 (define_expand "bordered"
2020 (if_then_else (ordered (match_dup 1) (const_int 0))
2021 (label_ref (match_operand 0 "" ""))
2026 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2028 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
2029 emit_jump_insn (gen_bne (operands[0]));
2032 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
2036 (define_expand "bungt"
2038 (if_then_else (ungt (match_dup 1) (const_int 0))
2039 (label_ref (match_operand 0 "" ""))
2044 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2046 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
2047 emit_jump_insn (gen_bgt (operands[0]));
2050 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
2053 (define_expand "bunlt"
2055 (if_then_else (unlt (match_dup 1) (const_int 0))
2056 (label_ref (match_operand 0 "" ""))
2061 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2063 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
2064 emit_jump_insn (gen_bne (operands[0]));
2067 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
2070 (define_expand "buneq"
2072 (if_then_else (uneq (match_dup 1) (const_int 0))
2073 (label_ref (match_operand 0 "" ""))
2078 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2080 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
2081 emit_jump_insn (gen_beq (operands[0]));
2084 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
2087 (define_expand "bunge"
2089 (if_then_else (unge (match_dup 1) (const_int 0))
2090 (label_ref (match_operand 0 "" ""))
2095 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2097 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
2098 emit_jump_insn (gen_bne (operands[0]));
2101 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
2104 (define_expand "bunle"
2106 (if_then_else (unle (match_dup 1) (const_int 0))
2107 (label_ref (match_operand 0 "" ""))
2112 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2114 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
2115 emit_jump_insn (gen_bne (operands[0]));
2118 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
2121 (define_expand "bltgt"
2123 (if_then_else (ltgt (match_dup 1) (const_int 0))
2124 (label_ref (match_operand 0 "" ""))
2129 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2131 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
2132 emit_jump_insn (gen_bne (operands[0]));
2135 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
2138 ;; Now match both normal and inverted jump.
2140 ;; XXX fpcmp nop braindamage
2141 (define_insn "*normal_branch"
2143 (if_then_else (match_operator 0 "noov_compare_op"
2144 [(reg 100) (const_int 0)])
2145 (label_ref (match_operand 1 "" ""))
2150 return output_cbranch (operands[0], operands[1], 1, 0,
2151 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2152 ! final_sequence, insn);
2154 [(set_attr "type" "branch")
2155 (set_attr "branch_type" "icc")])
2157 ;; XXX fpcmp nop braindamage
2158 (define_insn "*inverted_branch"
2160 (if_then_else (match_operator 0 "noov_compare_op"
2161 [(reg 100) (const_int 0)])
2163 (label_ref (match_operand 1 "" ""))))]
2167 return output_cbranch (operands[0], operands[1], 1, 1,
2168 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2169 ! final_sequence, insn);
2171 [(set_attr "type" "branch")
2172 (set_attr "branch_type" "icc")])
2174 ;; XXX fpcmp nop braindamage
2175 (define_insn "*normal_fp_branch"
2177 (if_then_else (match_operator 1 "comparison_operator"
2178 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2180 (label_ref (match_operand 2 "" ""))
2185 return output_cbranch (operands[1], operands[2], 2, 0,
2186 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2187 ! final_sequence, insn);
2189 [(set_attr "type" "branch")
2190 (set_attr "branch_type" "fcc")])
2192 ;; XXX fpcmp nop braindamage
2193 (define_insn "*inverted_fp_branch"
2195 (if_then_else (match_operator 1 "comparison_operator"
2196 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2199 (label_ref (match_operand 2 "" ""))))]
2203 return output_cbranch (operands[1], operands[2], 2, 1,
2204 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2205 ! final_sequence, insn);
2207 [(set_attr "type" "branch")
2208 (set_attr "branch_type" "fcc")])
2210 ;; XXX fpcmp nop braindamage
2211 (define_insn "*normal_fpe_branch"
2213 (if_then_else (match_operator 1 "comparison_operator"
2214 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2216 (label_ref (match_operand 2 "" ""))
2221 return output_cbranch (operands[1], operands[2], 2, 0,
2222 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2223 ! final_sequence, insn);
2225 [(set_attr "type" "branch")
2226 (set_attr "branch_type" "fcc")])
2228 ;; XXX fpcmp nop braindamage
2229 (define_insn "*inverted_fpe_branch"
2231 (if_then_else (match_operator 1 "comparison_operator"
2232 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2235 (label_ref (match_operand 2 "" ""))))]
2239 return output_cbranch (operands[1], operands[2], 2, 1,
2240 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2241 ! final_sequence, insn);
2243 [(set_attr "type" "branch")
2244 (set_attr "branch_type" "fcc")])
2246 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2247 ;; in the architecture.
2249 ;; There are no 32 bit brreg insns.
2252 (define_insn "*normal_int_branch_sp64"
2254 (if_then_else (match_operator 0 "v9_regcmp_op"
2255 [(match_operand:DI 1 "register_operand" "r")
2257 (label_ref (match_operand 2 "" ""))
2262 return output_v9branch (operands[0], operands[2], 1, 2, 0,
2263 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2264 ! final_sequence, insn);
2266 [(set_attr "type" "branch")
2267 (set_attr "branch_type" "reg")])
2270 (define_insn "*inverted_int_branch_sp64"
2272 (if_then_else (match_operator 0 "v9_regcmp_op"
2273 [(match_operand:DI 1 "register_operand" "r")
2276 (label_ref (match_operand 2 "" ""))))]
2280 return output_v9branch (operands[0], operands[2], 1, 2, 1,
2281 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2282 ! final_sequence, insn);
2284 [(set_attr "type" "branch")
2285 (set_attr "branch_type" "reg")])
2287 ;; Load program counter insns.
2289 (define_insn "get_pc"
2290 [(clobber (reg:SI 15))
2291 (set (match_operand 0 "register_operand" "=r")
2292 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2293 "flag_pic && REGNO (operands[0]) == 23"
2294 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2295 [(set_attr "type" "multi")
2296 (set_attr "length" "3")])
2298 ;; Currently unused...
2299 ;; (define_insn "get_pc_via_rdpc"
2300 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2303 ;; [(set_attr "type" "misc")])
2306 ;; Move instructions
2308 (define_expand "movqi"
2309 [(set (match_operand:QI 0 "general_operand" "")
2310 (match_operand:QI 1 "general_operand" ""))]
2314 /* Working with CONST_INTs is easier, so convert
2315 a double if needed. */
2316 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2318 operands[1] = GEN_INT (trunc_int_for_mode
2319 (CONST_DOUBLE_LOW (operands[1]), QImode));
2322 /* Handle sets of MEM first. */
2323 if (GET_CODE (operands[0]) == MEM)
2325 if (reg_or_0_operand (operands[1], QImode))
2328 if (! reload_in_progress)
2330 operands[0] = validize_mem (operands[0]);
2331 operands[1] = force_reg (QImode, operands[1]);
2335 /* Fixup PIC cases. */
2338 if (CONSTANT_P (operands[1])
2339 && pic_address_needs_scratch (operands[1]))
2340 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2342 if (symbolic_operand (operands[1], QImode))
2344 operands[1] = legitimize_pic_address (operands[1],
2346 (reload_in_progress ?
2353 /* All QI constants require only one insn, so proceed. */
2359 (define_insn "*movqi_insn"
2360 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2361 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2362 "(register_operand (operands[0], QImode)
2363 || reg_or_0_operand (operands[1], QImode))"
2368 [(set_attr "type" "*,load,store")
2369 (set_attr "us3load_type" "*,3cycle,*")])
2371 (define_expand "movhi"
2372 [(set (match_operand:HI 0 "general_operand" "")
2373 (match_operand:HI 1 "general_operand" ""))]
2377 /* Working with CONST_INTs is easier, so convert
2378 a double if needed. */
2379 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2380 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2382 /* Handle sets of MEM first. */
2383 if (GET_CODE (operands[0]) == MEM)
2385 if (reg_or_0_operand (operands[1], HImode))
2388 if (! reload_in_progress)
2390 operands[0] = validize_mem (operands[0]);
2391 operands[1] = force_reg (HImode, operands[1]);
2395 /* Fixup PIC cases. */
2398 if (CONSTANT_P (operands[1])
2399 && pic_address_needs_scratch (operands[1]))
2400 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2402 if (symbolic_operand (operands[1], HImode))
2404 operands[1] = legitimize_pic_address (operands[1],
2406 (reload_in_progress ?
2413 /* This makes sure we will not get rematched due to splittage. */
2414 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2416 else if (CONSTANT_P (operands[1])
2417 && GET_CODE (operands[1]) != HIGH
2418 && GET_CODE (operands[1]) != LO_SUM)
2420 sparc_emit_set_const32 (operands[0], operands[1]);
2427 (define_insn "*movhi_const64_special"
2428 [(set (match_operand:HI 0 "register_operand" "=r")
2429 (match_operand:HI 1 "const64_high_operand" ""))]
2431 "sethi\\t%%hi(%a1), %0")
2433 (define_insn "*movhi_insn"
2434 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2435 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2436 "(register_operand (operands[0], HImode)
2437 || reg_or_0_operand (operands[1], HImode))"
2440 sethi\\t%%hi(%a1), %0
2443 [(set_attr "type" "*,*,load,store")
2444 (set_attr "us3load_type" "*,*,3cycle,*")])
2446 ;; We always work with constants here.
2447 (define_insn "*movhi_lo_sum"
2448 [(set (match_operand:HI 0 "register_operand" "=r")
2449 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2450 (match_operand:HI 2 "arith_operand" "I")))]
2454 (define_expand "movsi"
2455 [(set (match_operand:SI 0 "general_operand" "")
2456 (match_operand:SI 1 "general_operand" ""))]
2460 /* Working with CONST_INTs is easier, so convert
2461 a double if needed. */
2462 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2463 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2465 /* Handle sets of MEM first. */
2466 if (GET_CODE (operands[0]) == MEM)
2468 if (reg_or_0_operand (operands[1], SImode))
2471 if (! reload_in_progress)
2473 operands[0] = validize_mem (operands[0]);
2474 operands[1] = force_reg (SImode, operands[1]);
2478 /* Fixup PIC cases. */
2481 if (CONSTANT_P (operands[1])
2482 && pic_address_needs_scratch (operands[1]))
2483 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2485 if (GET_CODE (operands[1]) == LABEL_REF)
2488 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2492 if (symbolic_operand (operands[1], SImode))
2494 operands[1] = legitimize_pic_address (operands[1],
2496 (reload_in_progress ?
2503 /* If we are trying to toss an integer constant into the
2504 FPU registers, force it into memory. */
2505 if (GET_CODE (operands[0]) == REG
2506 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2507 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2508 && CONSTANT_P (operands[1]))
2509 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2512 /* This makes sure we will not get rematched due to splittage. */
2513 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2515 else if (CONSTANT_P (operands[1])
2516 && GET_CODE (operands[1]) != HIGH
2517 && GET_CODE (operands[1]) != LO_SUM)
2519 sparc_emit_set_const32 (operands[0], operands[1]);
2526 ;; This is needed to show CSE exactly which bits are set
2527 ;; in a 64-bit register by sethi instructions.
2528 (define_insn "*movsi_const64_special"
2529 [(set (match_operand:SI 0 "register_operand" "=r")
2530 (match_operand:SI 1 "const64_high_operand" ""))]
2532 "sethi\\t%%hi(%a1), %0")
2534 (define_insn "*movsi_insn"
2535 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2536 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2537 "(register_operand (operands[0], SImode)
2538 || reg_or_0_operand (operands[1], SImode))"
2542 sethi\\t%%hi(%a1), %0
2549 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2551 (define_insn "*movsi_lo_sum"
2552 [(set (match_operand:SI 0 "register_operand" "=r")
2553 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2554 (match_operand:SI 2 "immediate_operand" "in")))]
2556 "or\\t%1, %%lo(%a2), %0")
2558 (define_insn "*movsi_high"
2559 [(set (match_operand:SI 0 "register_operand" "=r")
2560 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2562 "sethi\\t%%hi(%a1), %0")
2564 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2565 ;; so that CSE won't optimize the address computation away.
2566 (define_insn "movsi_lo_sum_pic"
2567 [(set (match_operand:SI 0 "register_operand" "=r")
2568 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2569 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2571 "or\\t%1, %%lo(%a2), %0")
2573 (define_insn "movsi_high_pic"
2574 [(set (match_operand:SI 0 "register_operand" "=r")
2575 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2576 "flag_pic && check_pic (1)"
2577 "sethi\\t%%hi(%a1), %0")
2579 (define_expand "movsi_pic_label_ref"
2580 [(set (match_dup 3) (high:SI
2581 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2583 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2584 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2585 (set (match_operand:SI 0 "register_operand" "=r")
2586 (minus:SI (match_dup 5) (match_dup 4)))]
2590 current_function_uses_pic_offset_table = 1;
2591 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2594 operands[3] = operands[0];
2595 operands[4] = operands[0];
2599 operands[3] = gen_reg_rtx (SImode);
2600 operands[4] = gen_reg_rtx (SImode);
2602 operands[5] = pic_offset_table_rtx;
2605 (define_insn "*movsi_high_pic_label_ref"
2606 [(set (match_operand:SI 0 "register_operand" "=r")
2608 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2609 (match_operand:SI 2 "" "")] 5)))]
2611 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2613 (define_insn "*movsi_lo_sum_pic_label_ref"
2614 [(set (match_operand:SI 0 "register_operand" "=r")
2615 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2616 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2617 (match_operand:SI 3 "" "")] 5)))]
2619 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2621 (define_expand "movdi"
2622 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2623 (match_operand:DI 1 "general_operand" ""))]
2627 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2628 if (GET_CODE (operands[1]) == CONST_DOUBLE
2629 #if HOST_BITS_PER_WIDE_INT == 32
2630 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2631 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2632 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2633 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2636 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2638 /* Handle MEM cases first. */
2639 if (GET_CODE (operands[0]) == MEM)
2641 /* If it's a REG, we can always do it.
2642 The const zero case is more complex, on v9
2643 we can always perform it. */
2644 if (register_operand (operands[1], DImode)
2646 && (operands[1] == const0_rtx)))
2649 if (! reload_in_progress)
2651 operands[0] = validize_mem (operands[0]);
2652 operands[1] = force_reg (DImode, operands[1]);
2658 if (CONSTANT_P (operands[1])
2659 && pic_address_needs_scratch (operands[1]))
2660 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2662 if (GET_CODE (operands[1]) == LABEL_REF)
2664 if (! TARGET_ARCH64)
2666 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2670 if (symbolic_operand (operands[1], DImode))
2672 operands[1] = legitimize_pic_address (operands[1],
2674 (reload_in_progress ?
2681 /* If we are trying to toss an integer constant into the
2682 FPU registers, force it into memory. */
2683 if (GET_CODE (operands[0]) == REG
2684 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2685 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2686 && CONSTANT_P (operands[1]))
2687 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2690 /* This makes sure we will not get rematched due to splittage. */
2691 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2693 else if (TARGET_ARCH64
2694 && CONSTANT_P (operands[1])
2695 && GET_CODE (operands[1]) != HIGH
2696 && GET_CODE (operands[1]) != LO_SUM)
2698 sparc_emit_set_const64 (operands[0], operands[1]);
2706 ;; Be careful, fmovd does not exist when !arch64.
2707 ;; We match MEM moves directly when we have correct even
2708 ;; numbered registers, but fall into splits otherwise.
2709 ;; The constraint ordering here is really important to
2710 ;; avoid insane problems in reload, especially for patterns
2713 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2714 ;; (const_int -5016)))
2718 (define_insn "*movdi_insn_sp32_v9"
2719 [(set (match_operand:DI 0 "nonimmediate_operand"
2720 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2721 (match_operand:DI 1 "input_operand"
2722 " J,J,U,T,r,o,i,r, f, T, o, f, f"))]
2723 "! TARGET_ARCH64 && TARGET_V9
2724 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2739 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2740 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2742 (define_insn "*movdi_insn_sp32"
2743 [(set (match_operand:DI 0 "nonimmediate_operand"
2744 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2745 (match_operand:DI 1 "input_operand"
2746 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2748 && (register_operand (operands[0], DImode)
2749 || register_operand (operands[1], DImode))"
2763 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2764 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2766 ;; The following are generated by sparc_emit_set_const64
2767 (define_insn "*movdi_sp64_dbl"
2768 [(set (match_operand:DI 0 "register_operand" "=r")
2769 (match_operand:DI 1 "const64_operand" ""))]
2771 && HOST_BITS_PER_WIDE_INT != 64)"
2774 ;; This is needed to show CSE exactly which bits are set
2775 ;; in a 64-bit register by sethi instructions.
2776 (define_insn "*movdi_const64_special"
2777 [(set (match_operand:DI 0 "register_operand" "=r")
2778 (match_operand:DI 1 "const64_high_operand" ""))]
2780 "sethi\\t%%hi(%a1), %0")
2782 (define_insn "*movdi_insn_sp64_novis"
2783 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2784 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2785 "TARGET_ARCH64 && ! TARGET_VIS
2786 && (register_operand (operands[0], DImode)
2787 || reg_or_0_operand (operands[1], DImode))"
2790 sethi\\t%%hi(%a1), %0
2797 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2798 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2800 (define_insn "*movdi_insn_sp64_vis"
2801 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2802 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2803 "TARGET_ARCH64 && TARGET_VIS &&
2804 (register_operand (operands[0], DImode)
2805 || reg_or_0_operand (operands[1], DImode))"
2808 sethi\\t%%hi(%a1), %0
2816 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2817 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2819 (define_expand "movdi_pic_label_ref"
2820 [(set (match_dup 3) (high:DI
2821 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2823 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2824 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2825 (set (match_operand:DI 0 "register_operand" "=r")
2826 (minus:DI (match_dup 5) (match_dup 4)))]
2827 "TARGET_ARCH64 && flag_pic"
2830 current_function_uses_pic_offset_table = 1;
2831 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2834 operands[3] = operands[0];
2835 operands[4] = operands[0];
2839 operands[3] = gen_reg_rtx (DImode);
2840 operands[4] = gen_reg_rtx (DImode);
2842 operands[5] = pic_offset_table_rtx;
2845 (define_insn "*movdi_high_pic_label_ref"
2846 [(set (match_operand:DI 0 "register_operand" "=r")
2848 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2849 (match_operand:DI 2 "" "")] 5)))]
2850 "TARGET_ARCH64 && flag_pic"
2851 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2853 (define_insn "*movdi_lo_sum_pic_label_ref"
2854 [(set (match_operand:DI 0 "register_operand" "=r")
2855 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2856 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2857 (match_operand:DI 3 "" "")] 5)))]
2858 "TARGET_ARCH64 && flag_pic"
2859 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2861 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2862 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2864 (define_insn "movdi_lo_sum_pic"
2865 [(set (match_operand:DI 0 "register_operand" "=r")
2866 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2867 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2868 "TARGET_ARCH64 && flag_pic"
2869 "or\\t%1, %%lo(%a2), %0")
2871 (define_insn "movdi_high_pic"
2872 [(set (match_operand:DI 0 "register_operand" "=r")
2873 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2874 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2875 "sethi\\t%%hi(%a1), %0")
2877 (define_insn "*sethi_di_medlow_embmedany_pic"
2878 [(set (match_operand:DI 0 "register_operand" "=r")
2879 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2880 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2881 "sethi\\t%%hi(%a1), %0")
2883 (define_insn "*sethi_di_medlow"
2884 [(set (match_operand:DI 0 "register_operand" "=r")
2885 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2886 "TARGET_CM_MEDLOW && check_pic (1)"
2887 "sethi\\t%%hi(%a1), %0")
2889 (define_insn "*losum_di_medlow"
2890 [(set (match_operand:DI 0 "register_operand" "=r")
2891 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2892 (match_operand:DI 2 "symbolic_operand" "")))]
2894 "or\\t%1, %%lo(%a2), %0")
2896 (define_insn "seth44"
2897 [(set (match_operand:DI 0 "register_operand" "=r")
2898 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2900 "sethi\\t%%h44(%a1), %0")
2902 (define_insn "setm44"
2903 [(set (match_operand:DI 0 "register_operand" "=r")
2904 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2905 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2907 "or\\t%1, %%m44(%a2), %0")
2909 (define_insn "setl44"
2910 [(set (match_operand:DI 0 "register_operand" "=r")
2911 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2912 (match_operand:DI 2 "symbolic_operand" "")))]
2914 "or\\t%1, %%l44(%a2), %0")
2916 (define_insn "sethh"
2917 [(set (match_operand:DI 0 "register_operand" "=r")
2918 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2920 "sethi\\t%%hh(%a1), %0")
2922 (define_insn "setlm"
2923 [(set (match_operand:DI 0 "register_operand" "=r")
2924 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2926 "sethi\\t%%lm(%a1), %0")
2928 (define_insn "sethm"
2929 [(set (match_operand:DI 0 "register_operand" "=r")
2930 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2931 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2933 "or\\t%1, %%hm(%a2), %0")
2935 (define_insn "setlo"
2936 [(set (match_operand:DI 0 "register_operand" "=r")
2937 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2938 (match_operand:DI 2 "symbolic_operand" "")))]
2940 "or\\t%1, %%lo(%a2), %0")
2942 (define_insn "embmedany_sethi"
2943 [(set (match_operand:DI 0 "register_operand" "=r")
2944 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2945 "TARGET_CM_EMBMEDANY && check_pic (1)"
2946 "sethi\\t%%hi(%a1), %0")
2948 (define_insn "embmedany_losum"
2949 [(set (match_operand:DI 0 "register_operand" "=r")
2950 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2951 (match_operand:DI 2 "data_segment_operand" "")))]
2952 "TARGET_CM_EMBMEDANY"
2953 "add\\t%1, %%lo(%a2), %0")
2955 (define_insn "embmedany_brsum"
2956 [(set (match_operand:DI 0 "register_operand" "=r")
2957 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2958 "TARGET_CM_EMBMEDANY"
2961 (define_insn "embmedany_textuhi"
2962 [(set (match_operand:DI 0 "register_operand" "=r")
2963 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2964 "TARGET_CM_EMBMEDANY && check_pic (1)"
2965 "sethi\\t%%uhi(%a1), %0")
2967 (define_insn "embmedany_texthi"
2968 [(set (match_operand:DI 0 "register_operand" "=r")
2969 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2970 "TARGET_CM_EMBMEDANY && check_pic (1)"
2971 "sethi\\t%%hi(%a1), %0")
2973 (define_insn "embmedany_textulo"
2974 [(set (match_operand:DI 0 "register_operand" "=r")
2975 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2976 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2977 "TARGET_CM_EMBMEDANY"
2978 "or\\t%1, %%ulo(%a2), %0")
2980 (define_insn "embmedany_textlo"
2981 [(set (match_operand:DI 0 "register_operand" "=r")
2982 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2983 (match_operand:DI 2 "text_segment_operand" "")))]
2984 "TARGET_CM_EMBMEDANY"
2985 "or\\t%1, %%lo(%a2), %0")
2987 ;; Now some patterns to help reload out a bit.
2988 (define_expand "reload_indi"
2989 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2990 (match_operand:DI 1 "immediate_operand" "")
2991 (match_operand:TI 2 "register_operand" "=&r")])]
2993 || TARGET_CM_EMBMEDANY)
2997 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
3001 (define_expand "reload_outdi"
3002 [(parallel [(match_operand:DI 0 "register_operand" "=r")
3003 (match_operand:DI 1 "immediate_operand" "")
3004 (match_operand:TI 2 "register_operand" "=&r")])]
3006 || TARGET_CM_EMBMEDANY)
3010 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
3014 ;; Split up putting CONSTs and REGs into DI regs when !arch64
3016 [(set (match_operand:DI 0 "register_operand" "")
3017 (match_operand:DI 1 "const_int_operand" ""))]
3018 "! TARGET_ARCH64 && reload_completed"
3019 [(clobber (const_int 0))]
3022 #if HOST_BITS_PER_WIDE_INT == 32
3023 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3024 (INTVAL (operands[1]) < 0) ?
3027 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3030 unsigned int low, high;
3032 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
3033 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
3034 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
3036 /* Slick... but this trick loses if this subreg constant part
3037 can be done in one insn. */
3038 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
3039 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3040 gen_highpart (SImode, operands[0])));
3042 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
3048 [(set (match_operand:DI 0 "register_operand" "")
3049 (match_operand:DI 1 "const_double_operand" ""))]
3050 "! TARGET_ARCH64 && reload_completed"
3051 [(clobber (const_int 0))]
3054 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3055 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
3057 /* Slick... but this trick loses if this subreg constant part
3058 can be done in one insn. */
3059 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
3060 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
3061 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
3063 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3064 gen_highpart (SImode, operands[0])));
3068 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3069 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
3075 [(set (match_operand:DI 0 "register_operand" "")
3076 (match_operand:DI 1 "register_operand" ""))]
3077 "! TARGET_ARCH64 && reload_completed"
3078 [(clobber (const_int 0))]
3081 rtx set_dest = operands[0];
3082 rtx set_src = operands[1];
3086 dest1 = gen_highpart (SImode, set_dest);
3087 dest2 = gen_lowpart (SImode, set_dest);
3088 src1 = gen_highpart (SImode, set_src);
3089 src2 = gen_lowpart (SImode, set_src);
3091 /* Now emit using the real source and destination we found, swapping
3092 the order if we detect overlap. */
3093 if (reg_overlap_mentioned_p (dest1, src2))
3095 emit_insn (gen_movsi (dest2, src2));
3096 emit_insn (gen_movsi (dest1, src1));
3100 emit_insn (gen_movsi (dest1, src1));
3101 emit_insn (gen_movsi (dest2, src2));
3106 ;; Now handle the cases of memory moves from/to non-even
3107 ;; DI mode register pairs.
3109 [(set (match_operand:DI 0 "register_operand" "")
3110 (match_operand:DI 1 "memory_operand" ""))]
3113 && sparc_splitdi_legitimate (operands[0], operands[1]))"
3114 [(clobber (const_int 0))]
3117 rtx word0 = adjust_address (operands[1], SImode, 0);
3118 rtx word1 = adjust_address (operands[1], SImode, 4);
3119 rtx high_part = gen_highpart (SImode, operands[0]);
3120 rtx low_part = gen_lowpart (SImode, operands[0]);
3122 if (reg_overlap_mentioned_p (high_part, word1))
3124 emit_insn (gen_movsi (low_part, word1));
3125 emit_insn (gen_movsi (high_part, word0));
3129 emit_insn (gen_movsi (high_part, word0));
3130 emit_insn (gen_movsi (low_part, word1));
3136 [(set (match_operand:DI 0 "memory_operand" "")
3137 (match_operand:DI 1 "register_operand" ""))]
3140 && sparc_splitdi_legitimate (operands[1], operands[0]))"
3141 [(clobber (const_int 0))]
3144 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
3145 gen_highpart (SImode, operands[1])));
3146 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
3147 gen_lowpart (SImode, operands[1])));
3152 [(set (match_operand:DI 0 "memory_operand" "")
3157 && ! mem_min_alignment (operands[0], 8)))
3158 && offsettable_memref_p (operands[0])"
3159 [(clobber (const_int 0))]
3162 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
3163 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
3167 ;; Floating point move insns
3169 (define_insn "*movsf_insn_novis"
3170 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
3171 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
3172 "(TARGET_FPU && ! TARGET_VIS)
3173 && (register_operand (operands[0], SFmode)
3174 || register_operand (operands[1], SFmode)
3175 || fp_zero_operand (operands[1], SFmode))"
3178 if (GET_CODE (operands[1]) == CONST_DOUBLE
3179 && (which_alternative == 2
3180 || which_alternative == 3
3181 || which_alternative == 4))
3186 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3187 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3188 operands[1] = GEN_INT (i);
3191 switch (which_alternative)
3194 return \"fmovs\\t%1, %0\";
3196 return \"clr\\t%0\";
3198 return \"sethi\\t%%hi(%a1), %0\";
3200 return \"mov\\t%1, %0\";
3205 return \"ld\\t%1, %0\";
3208 return \"st\\t%r1, %0\";
3213 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
3215 (define_insn "*movsf_insn_vis"
3216 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3217 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3218 "(TARGET_FPU && TARGET_VIS)
3219 && (register_operand (operands[0], SFmode)
3220 || register_operand (operands[1], SFmode)
3221 || fp_zero_operand (operands[1], SFmode))"
3224 if (GET_CODE (operands[1]) == CONST_DOUBLE
3225 && (which_alternative == 3
3226 || which_alternative == 4
3227 || which_alternative == 5))
3232 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3233 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3234 operands[1] = GEN_INT (i);
3237 switch (which_alternative)
3240 return \"fmovs\\t%1, %0\";
3242 return \"fzeros\\t%0\";
3244 return \"clr\\t%0\";
3246 return \"sethi\\t%%hi(%a1), %0\";
3248 return \"mov\\t%1, %0\";
3253 return \"ld\\t%1, %0\";
3256 return \"st\\t%r1, %0\";
3261 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
3263 ;; Exactly the same as above, except that all `f' cases are deleted.
3264 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3267 (define_insn "*movsf_no_f_insn"
3268 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
3269 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
3271 && (register_operand (operands[0], SFmode)
3272 || register_operand (operands[1], SFmode)
3273 || fp_zero_operand (operands[1], SFmode))"
3276 if (GET_CODE (operands[1]) == CONST_DOUBLE
3277 && (which_alternative == 1
3278 || which_alternative == 2
3279 || which_alternative == 3))
3284 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3285 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3286 operands[1] = GEN_INT (i);
3289 switch (which_alternative)
3292 return \"clr\\t%0\";
3294 return \"sethi\\t%%hi(%a1), %0\";
3296 return \"mov\\t%1, %0\";
3300 return \"ld\\t%1, %0\";
3302 return \"st\\t%r1, %0\";
3307 [(set_attr "type" "*,*,*,*,load,store")])
3309 (define_insn "*movsf_lo_sum"
3310 [(set (match_operand:SF 0 "register_operand" "=r")
3311 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3312 (match_operand:SF 2 "const_double_operand" "S")))]
3313 "fp_high_losum_p (operands[2])"
3319 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3320 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3321 operands[2] = GEN_INT (i);
3322 return \"or\\t%1, %%lo(%a2), %0\";
3325 (define_insn "*movsf_high"
3326 [(set (match_operand:SF 0 "register_operand" "=r")
3327 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3328 "fp_high_losum_p (operands[1])"
3334 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3335 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3336 operands[1] = GEN_INT (i);
3337 return \"sethi\\t%%hi(%1), %0\";
3341 [(set (match_operand:SF 0 "register_operand" "")
3342 (match_operand:SF 1 "const_double_operand" ""))]
3343 "fp_high_losum_p (operands[1])
3344 && (GET_CODE (operands[0]) == REG
3345 && REGNO (operands[0]) < 32)"
3346 [(set (match_dup 0) (high:SF (match_dup 1)))
3347 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3349 (define_expand "movsf"
3350 [(set (match_operand:SF 0 "general_operand" "")
3351 (match_operand:SF 1 "general_operand" ""))]
3355 /* Force SFmode constants into memory. */
3356 if (GET_CODE (operands[0]) == REG
3357 && CONSTANT_P (operands[1]))
3359 /* emit_group_store will send such bogosity to us when it is
3360 not storing directly into memory. So fix this up to avoid
3361 crashes in output_constant_pool. */
3362 if (operands [1] == const0_rtx)
3363 operands[1] = CONST0_RTX (SFmode);
3365 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3368 /* We are able to build any SF constant in integer registers
3369 with at most 2 instructions. */
3370 if (REGNO (operands[0]) < 32)
3373 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3377 /* Handle sets of MEM first. */
3378 if (GET_CODE (operands[0]) == MEM)
3380 if (register_operand (operands[1], SFmode)
3381 || fp_zero_operand (operands[1], SFmode))
3384 if (! reload_in_progress)
3386 operands[0] = validize_mem (operands[0]);
3387 operands[1] = force_reg (SFmode, operands[1]);
3391 /* Fixup PIC cases. */
3394 if (CONSTANT_P (operands[1])
3395 && pic_address_needs_scratch (operands[1]))
3396 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3398 if (symbolic_operand (operands[1], SFmode))
3400 operands[1] = legitimize_pic_address (operands[1],
3402 (reload_in_progress ?
3412 (define_expand "movdf"
3413 [(set (match_operand:DF 0 "general_operand" "")
3414 (match_operand:DF 1 "general_operand" ""))]
3418 /* Force DFmode constants into memory. */
3419 if (GET_CODE (operands[0]) == REG
3420 && CONSTANT_P (operands[1]))
3422 /* emit_group_store will send such bogosity to us when it is
3423 not storing directly into memory. So fix this up to avoid
3424 crashes in output_constant_pool. */
3425 if (operands [1] == const0_rtx)
3426 operands[1] = CONST0_RTX (DFmode);
3428 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3429 && fp_zero_operand (operands[1], DFmode))
3432 /* We are able to build any DF constant in integer registers. */
3433 if (REGNO (operands[0]) < 32
3434 && (reload_completed || reload_in_progress))
3437 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3441 /* Handle MEM cases first. */
3442 if (GET_CODE (operands[0]) == MEM)
3444 if (register_operand (operands[1], DFmode)
3445 || fp_zero_operand (operands[1], DFmode))
3448 if (! reload_in_progress)
3450 operands[0] = validize_mem (operands[0]);
3451 operands[1] = force_reg (DFmode, operands[1]);
3455 /* Fixup PIC cases. */
3458 if (CONSTANT_P (operands[1])
3459 && pic_address_needs_scratch (operands[1]))
3460 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3462 if (symbolic_operand (operands[1], DFmode))
3464 operands[1] = legitimize_pic_address (operands[1],
3466 (reload_in_progress ?
3476 ;; Be careful, fmovd does not exist when !v9.
3477 (define_insn "*movdf_insn_sp32"
3478 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
3479 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3482 && (register_operand (operands[0], DFmode)
3483 || register_operand (operands[1], DFmode)
3484 || fp_zero_operand (operands[1], DFmode))"
3496 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3497 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3499 (define_insn "*movdf_no_e_insn_sp32"
3500 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3501 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3505 && (register_operand (operands[0], DFmode)
3506 || register_operand (operands[1], DFmode)
3507 || fp_zero_operand (operands[1], DFmode))"
3514 [(set_attr "type" "load,store,*,*,*")
3515 (set_attr "length" "*,*,2,2,2")])
3517 (define_insn "*movdf_no_e_insn_v9_sp32"
3518 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3519 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3523 && (register_operand (operands[0], DFmode)
3524 || register_operand (operands[1], DFmode)
3525 || fp_zero_operand (operands[1], DFmode))"
3532 [(set_attr "type" "load,store,store,*,*")
3533 (set_attr "length" "*,*,*,2,2")])
3535 ;; We have available v9 double floats but not 64-bit
3536 ;; integer registers and no VIS.
3537 (define_insn "*movdf_insn_v9only_novis"
3538 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,e,*r,o")
3539 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGe"))]
3544 && (register_operand (operands[0], DFmode)
3545 || register_operand (operands[1], DFmode)
3546 || fp_zero_operand (operands[1], DFmode))"
3557 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3558 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3559 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3561 ;; We have available v9 double floats but not 64-bit
3562 ;; integer registers but we have VIS.
3563 (define_insn "*movdf_insn_v9only_vis"
3564 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,e,*r,o")
3565 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGe"))]
3569 && (register_operand (operands[0], DFmode)
3570 || register_operand (operands[1], DFmode)
3571 || fp_zero_operand (operands[1], DFmode))"
3583 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3584 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3585 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3587 ;; We have available both v9 double floats and 64-bit
3588 ;; integer registers. No VIS though.
3589 (define_insn "*movdf_insn_sp64_novis"
3590 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3591 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3595 && (register_operand (operands[0], DFmode)
3596 || register_operand (operands[1], DFmode)
3597 || fp_zero_operand (operands[1], DFmode))"
3606 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3607 (set_attr "length" "*,*,*,*,*,*,2")
3608 (set_attr "fptype" "double,*,*,*,*,*,*")])
3610 ;; We have available both v9 double floats and 64-bit
3611 ;; integer registers. And we have VIS.
3612 (define_insn "*movdf_insn_sp64_vis"
3613 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3614 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3618 && (register_operand (operands[0], DFmode)
3619 || register_operand (operands[1], DFmode)
3620 || fp_zero_operand (operands[1], DFmode))"
3630 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3631 (set_attr "length" "*,*,*,*,*,*,*,2")
3632 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3634 (define_insn "*movdf_no_e_insn_sp64"
3635 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3636 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3639 && (register_operand (operands[0], DFmode)
3640 || register_operand (operands[1], DFmode)
3641 || fp_zero_operand (operands[1], DFmode))"
3646 [(set_attr "type" "*,load,store")])
3649 [(set (match_operand:DF 0 "register_operand" "")
3650 (match_operand:DF 1 "const_double_operand" ""))]
3652 && (GET_CODE (operands[0]) == REG
3653 && REGNO (operands[0]) < 32)
3654 && ! fp_zero_operand(operands[1], DFmode)
3655 && reload_completed"
3656 [(clobber (const_int 0))]
3662 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3663 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3664 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3668 #if HOST_BITS_PER_WIDE_INT == 64
3671 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3672 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3673 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3675 emit_insn (gen_movdi (operands[0],
3676 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3681 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3684 /* Slick... but this trick loses if this subreg constant part
3685 can be done in one insn. */
3687 && !(SPARC_SETHI32_P (l[0])
3688 || SPARC_SIMM13_P (l[0])))
3690 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3691 gen_highpart (SImode, operands[0])));
3695 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3702 ;; Ok, now the splits to handle all the multi insn and
3703 ;; mis-aligned memory address cases.
3704 ;; In these splits please take note that we must be
3705 ;; careful when V9 but not ARCH64 because the integer
3706 ;; register DFmode cases must be handled.
3708 [(set (match_operand:DF 0 "register_operand" "")
3709 (match_operand:DF 1 "register_operand" ""))]
3712 && ((GET_CODE (operands[0]) == REG
3713 && REGNO (operands[0]) < 32)
3714 || (GET_CODE (operands[0]) == SUBREG
3715 && GET_CODE (SUBREG_REG (operands[0])) == REG
3716 && REGNO (SUBREG_REG (operands[0])) < 32))))
3717 && reload_completed"
3718 [(clobber (const_int 0))]
3721 rtx set_dest = operands[0];
3722 rtx set_src = operands[1];
3726 dest1 = gen_highpart (SFmode, set_dest);
3727 dest2 = gen_lowpart (SFmode, set_dest);
3728 src1 = gen_highpart (SFmode, set_src);
3729 src2 = gen_lowpart (SFmode, set_src);
3731 /* Now emit using the real source and destination we found, swapping
3732 the order if we detect overlap. */
3733 if (reg_overlap_mentioned_p (dest1, src2))
3735 emit_insn (gen_movsf (dest2, src2));
3736 emit_insn (gen_movsf (dest1, src1));
3740 emit_insn (gen_movsf (dest1, src1));
3741 emit_insn (gen_movsf (dest2, src2));
3747 [(set (match_operand:DF 0 "register_operand" "")
3748 (match_operand:DF 1 "memory_operand" ""))]
3751 && (((REGNO (operands[0]) % 2) != 0)
3752 || ! mem_min_alignment (operands[1], 8))
3753 && offsettable_memref_p (operands[1])"
3754 [(clobber (const_int 0))]
3757 rtx word0 = adjust_address (operands[1], SFmode, 0);
3758 rtx word1 = adjust_address (operands[1], SFmode, 4);
3760 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3762 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3764 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3769 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3771 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3778 [(set (match_operand:DF 0 "memory_operand" "")
3779 (match_operand:DF 1 "register_operand" ""))]
3782 && (((REGNO (operands[1]) % 2) != 0)
3783 || ! mem_min_alignment (operands[0], 8))
3784 && offsettable_memref_p (operands[0])"
3785 [(clobber (const_int 0))]
3788 rtx word0 = adjust_address (operands[0], SFmode, 0);
3789 rtx word1 = adjust_address (operands[0], SFmode, 4);
3791 emit_insn (gen_movsf (word0,
3792 gen_highpart (SFmode, operands[1])));
3793 emit_insn (gen_movsf (word1,
3794 gen_lowpart (SFmode, operands[1])));
3799 [(set (match_operand:DF 0 "memory_operand" "")
3800 (match_operand:DF 1 "fp_zero_operand" ""))]
3804 && ! mem_min_alignment (operands[0], 8)))
3805 && offsettable_memref_p (operands[0])"
3806 [(clobber (const_int 0))]
3811 dest1 = adjust_address (operands[0], SFmode, 0);
3812 dest2 = adjust_address (operands[0], SFmode, 4);
3814 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3815 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3820 [(set (match_operand:DF 0 "register_operand" "")
3821 (match_operand:DF 1 "fp_zero_operand" ""))]
3824 && ((GET_CODE (operands[0]) == REG
3825 && REGNO (operands[0]) < 32)
3826 || (GET_CODE (operands[0]) == SUBREG
3827 && GET_CODE (SUBREG_REG (operands[0])) == REG
3828 && REGNO (SUBREG_REG (operands[0])) < 32))"
3829 [(clobber (const_int 0))]
3832 rtx set_dest = operands[0];
3835 dest1 = gen_highpart (SFmode, set_dest);
3836 dest2 = gen_lowpart (SFmode, set_dest);
3837 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3838 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3842 (define_expand "movtf"
3843 [(set (match_operand:TF 0 "general_operand" "")
3844 (match_operand:TF 1 "general_operand" ""))]
3848 /* Force TFmode constants into memory. */
3849 if (GET_CODE (operands[0]) == REG
3850 && CONSTANT_P (operands[1]))
3852 /* emit_group_store will send such bogosity to us when it is
3853 not storing directly into memory. So fix this up to avoid
3854 crashes in output_constant_pool. */
3855 if (operands [1] == const0_rtx)
3856 operands[1] = CONST0_RTX (TFmode);
3858 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3861 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3865 /* Handle MEM cases first, note that only v9 guarentees
3866 full 16-byte alignment for quads. */
3867 if (GET_CODE (operands[0]) == MEM)
3869 if (register_operand (operands[1], TFmode)
3870 || fp_zero_operand (operands[1], TFmode))
3873 if (! reload_in_progress)
3875 operands[0] = validize_mem (operands[0]);
3876 operands[1] = force_reg (TFmode, operands[1]);
3880 /* Fixup PIC cases. */
3883 if (CONSTANT_P (operands[1])
3884 && pic_address_needs_scratch (operands[1]))
3885 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3887 if (symbolic_operand (operands[1], TFmode))
3889 operands[1] = legitimize_pic_address (operands[1],
3891 (reload_in_progress ?
3901 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3902 ;; we must split them all. :-(
3903 (define_insn "*movtf_insn_sp32"
3904 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3905 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3909 && (register_operand (operands[0], TFmode)
3910 || register_operand (operands[1], TFmode)
3911 || fp_zero_operand (operands[1], TFmode))"
3913 [(set_attr "length" "4")])
3915 (define_insn "*movtf_insn_vis_sp32"
3916 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3917 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3921 && (register_operand (operands[0], TFmode)
3922 || register_operand (operands[1], TFmode)
3923 || fp_zero_operand (operands[1], TFmode))"
3925 [(set_attr "length" "4")])
3927 ;; Exactly the same as above, except that all `e' cases are deleted.
3928 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3931 (define_insn "*movtf_no_e_insn_sp32"
3932 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3933 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3936 && (register_operand (operands[0], TFmode)
3937 || register_operand (operands[1], TFmode)
3938 || fp_zero_operand (operands[1], TFmode))"
3940 [(set_attr "length" "4")])
3942 ;; Now handle the float reg cases directly when arch64,
3943 ;; hard_quad, and proper reg number alignment are all true.
3944 (define_insn "*movtf_insn_hq_sp64"
3945 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3946 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3951 && (register_operand (operands[0], TFmode)
3952 || register_operand (operands[1], TFmode)
3953 || fp_zero_operand (operands[1], TFmode))"
3960 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3961 (set_attr "length" "*,*,*,2,2")])
3963 (define_insn "*movtf_insn_hq_vis_sp64"
3964 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3965 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3970 && (register_operand (operands[0], TFmode)
3971 || register_operand (operands[1], TFmode)
3972 || fp_zero_operand (operands[1], TFmode))"
3980 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3981 (set_attr "length" "*,*,*,2,2,2")])
3983 ;; Now we allow the integer register cases even when
3984 ;; only arch64 is true.
3985 (define_insn "*movtf_insn_sp64"
3986 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3987 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3991 && ! TARGET_HARD_QUAD
3992 && (register_operand (operands[0], TFmode)
3993 || register_operand (operands[1], TFmode)
3994 || fp_zero_operand (operands[1], TFmode))"
3996 [(set_attr "length" "2")])
3998 (define_insn "*movtf_insn_vis_sp64"
3999 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
4000 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
4004 && ! TARGET_HARD_QUAD
4005 && (register_operand (operands[0], TFmode)
4006 || register_operand (operands[1], TFmode)
4007 || fp_zero_operand (operands[1], TFmode))"
4009 [(set_attr "length" "2")])
4011 (define_insn "*movtf_no_e_insn_sp64"
4012 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
4013 (match_operand:TF 1 "input_operand" "orG,rG"))]
4016 && (register_operand (operands[0], TFmode)
4017 || register_operand (operands[1], TFmode)
4018 || fp_zero_operand (operands[1], TFmode))"
4020 [(set_attr "length" "2")])
4022 ;; Now all the splits to handle multi-insn TF mode moves.
4024 [(set (match_operand:TF 0 "register_operand" "")
4025 (match_operand:TF 1 "register_operand" ""))]
4029 && ! TARGET_HARD_QUAD)
4030 || ! fp_register_operand (operands[0], TFmode))"
4031 [(clobber (const_int 0))]
4034 rtx set_dest = operands[0];
4035 rtx set_src = operands[1];
4039 dest1 = gen_df_reg (set_dest, 0);
4040 dest2 = gen_df_reg (set_dest, 1);
4041 src1 = gen_df_reg (set_src, 0);
4042 src2 = gen_df_reg (set_src, 1);
4044 /* Now emit using the real source and destination we found, swapping
4045 the order if we detect overlap. */
4046 if (reg_overlap_mentioned_p (dest1, src2))
4048 emit_insn (gen_movdf (dest2, src2));
4049 emit_insn (gen_movdf (dest1, src1));
4053 emit_insn (gen_movdf (dest1, src1));
4054 emit_insn (gen_movdf (dest2, src2));
4060 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4061 (match_operand:TF 1 "fp_zero_operand" ""))]
4063 [(clobber (const_int 0))]
4066 rtx set_dest = operands[0];
4069 switch (GET_CODE (set_dest))
4072 dest1 = gen_df_reg (set_dest, 0);
4073 dest2 = gen_df_reg (set_dest, 1);
4076 dest1 = adjust_address (set_dest, DFmode, 0);
4077 dest2 = adjust_address (set_dest, DFmode, 8);
4083 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
4084 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
4089 [(set (match_operand:TF 0 "register_operand" "")
4090 (match_operand:TF 1 "memory_operand" ""))]
4092 && offsettable_memref_p (operands[1])
4094 || ! TARGET_HARD_QUAD
4095 || ! fp_register_operand (operands[0], TFmode)))"
4096 [(clobber (const_int 0))]
4099 rtx word0 = adjust_address (operands[1], DFmode, 0);
4100 rtx word1 = adjust_address (operands[1], DFmode, 8);
4101 rtx set_dest, dest1, dest2;
4103 set_dest = operands[0];
4105 dest1 = gen_df_reg (set_dest, 0);
4106 dest2 = gen_df_reg (set_dest, 1);
4108 /* Now output, ordering such that we don't clobber any registers
4109 mentioned in the address. */
4110 if (reg_overlap_mentioned_p (dest1, word1))
4113 emit_insn (gen_movdf (dest2, word1));
4114 emit_insn (gen_movdf (dest1, word0));
4118 emit_insn (gen_movdf (dest1, word0));
4119 emit_insn (gen_movdf (dest2, word1));
4125 [(set (match_operand:TF 0 "memory_operand" "")
4126 (match_operand:TF 1 "register_operand" ""))]
4128 && offsettable_memref_p (operands[0])
4130 || ! TARGET_HARD_QUAD
4131 || ! fp_register_operand (operands[1], TFmode)))"
4132 [(clobber (const_int 0))]
4135 rtx set_src = operands[1];
4137 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
4138 gen_df_reg (set_src, 0)));
4139 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
4140 gen_df_reg (set_src, 1)));
4144 ;; Sparc V9 conditional move instructions.
4146 ;; We can handle larger constants here for some flavors, but for now we keep
4147 ;; it simple and only allow those constants supported by all flavours.
4148 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
4149 ;; 3 contains the constant if one is present, but we handle either for
4150 ;; generality (sparc.c puts a constant in operand 2).
4152 (define_expand "movqicc"
4153 [(set (match_operand:QI 0 "register_operand" "")
4154 (if_then_else:QI (match_operand 1 "comparison_operator" "")
4155 (match_operand:QI 2 "arith10_operand" "")
4156 (match_operand:QI 3 "arith10_operand" "")))]
4160 enum rtx_code code = GET_CODE (operands[1]);
4162 if (GET_MODE (sparc_compare_op0) == DImode
4166 if (sparc_compare_op1 == const0_rtx
4167 && GET_CODE (sparc_compare_op0) == REG
4168 && GET_MODE (sparc_compare_op0) == DImode
4169 && v9_regcmp_p (code))
4171 operands[1] = gen_rtx_fmt_ee (code, DImode,
4172 sparc_compare_op0, sparc_compare_op1);
4176 rtx cc_reg = gen_compare_reg (code,
4177 sparc_compare_op0, sparc_compare_op1);
4178 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4182 (define_expand "movhicc"
4183 [(set (match_operand:HI 0 "register_operand" "")
4184 (if_then_else:HI (match_operand 1 "comparison_operator" "")
4185 (match_operand:HI 2 "arith10_operand" "")
4186 (match_operand:HI 3 "arith10_operand" "")))]
4190 enum rtx_code code = GET_CODE (operands[1]);
4192 if (GET_MODE (sparc_compare_op0) == DImode
4196 if (sparc_compare_op1 == const0_rtx
4197 && GET_CODE (sparc_compare_op0) == REG
4198 && GET_MODE (sparc_compare_op0) == DImode
4199 && v9_regcmp_p (code))
4201 operands[1] = gen_rtx_fmt_ee (code, DImode,
4202 sparc_compare_op0, sparc_compare_op1);
4206 rtx cc_reg = gen_compare_reg (code,
4207 sparc_compare_op0, sparc_compare_op1);
4208 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4212 (define_expand "movsicc"
4213 [(set (match_operand:SI 0 "register_operand" "")
4214 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4215 (match_operand:SI 2 "arith10_operand" "")
4216 (match_operand:SI 3 "arith10_operand" "")))]
4220 enum rtx_code code = GET_CODE (operands[1]);
4221 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4223 if (sparc_compare_op1 == const0_rtx
4224 && GET_CODE (sparc_compare_op0) == REG
4225 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4227 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4228 sparc_compare_op0, sparc_compare_op1);
4232 rtx cc_reg = gen_compare_reg (code,
4233 sparc_compare_op0, sparc_compare_op1);
4234 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4235 cc_reg, const0_rtx);
4239 (define_expand "movdicc"
4240 [(set (match_operand:DI 0 "register_operand" "")
4241 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4242 (match_operand:DI 2 "arith10_double_operand" "")
4243 (match_operand:DI 3 "arith10_double_operand" "")))]
4247 enum rtx_code code = GET_CODE (operands[1]);
4249 if (sparc_compare_op1 == const0_rtx
4250 && GET_CODE (sparc_compare_op0) == REG
4251 && GET_MODE (sparc_compare_op0) == DImode
4252 && v9_regcmp_p (code))
4254 operands[1] = gen_rtx_fmt_ee (code, DImode,
4255 sparc_compare_op0, sparc_compare_op1);
4259 rtx cc_reg = gen_compare_reg (code,
4260 sparc_compare_op0, sparc_compare_op1);
4261 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4262 cc_reg, const0_rtx);
4266 (define_expand "movsfcc"
4267 [(set (match_operand:SF 0 "register_operand" "")
4268 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4269 (match_operand:SF 2 "register_operand" "")
4270 (match_operand:SF 3 "register_operand" "")))]
4271 "TARGET_V9 && TARGET_FPU"
4274 enum rtx_code code = GET_CODE (operands[1]);
4276 if (GET_MODE (sparc_compare_op0) == DImode
4280 if (sparc_compare_op1 == const0_rtx
4281 && GET_CODE (sparc_compare_op0) == REG
4282 && GET_MODE (sparc_compare_op0) == DImode
4283 && v9_regcmp_p (code))
4285 operands[1] = gen_rtx_fmt_ee (code, DImode,
4286 sparc_compare_op0, sparc_compare_op1);
4290 rtx cc_reg = gen_compare_reg (code,
4291 sparc_compare_op0, sparc_compare_op1);
4292 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4296 (define_expand "movdfcc"
4297 [(set (match_operand:DF 0 "register_operand" "")
4298 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4299 (match_operand:DF 2 "register_operand" "")
4300 (match_operand:DF 3 "register_operand" "")))]
4301 "TARGET_V9 && TARGET_FPU"
4304 enum rtx_code code = GET_CODE (operands[1]);
4306 if (GET_MODE (sparc_compare_op0) == DImode
4310 if (sparc_compare_op1 == const0_rtx
4311 && GET_CODE (sparc_compare_op0) == REG
4312 && GET_MODE (sparc_compare_op0) == DImode
4313 && v9_regcmp_p (code))
4315 operands[1] = gen_rtx_fmt_ee (code, DImode,
4316 sparc_compare_op0, sparc_compare_op1);
4320 rtx cc_reg = gen_compare_reg (code,
4321 sparc_compare_op0, sparc_compare_op1);
4322 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4326 (define_expand "movtfcc"
4327 [(set (match_operand:TF 0 "register_operand" "")
4328 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4329 (match_operand:TF 2 "register_operand" "")
4330 (match_operand:TF 3 "register_operand" "")))]
4331 "TARGET_V9 && TARGET_FPU"
4334 enum rtx_code code = GET_CODE (operands[1]);
4336 if (GET_MODE (sparc_compare_op0) == DImode
4340 if (sparc_compare_op1 == const0_rtx
4341 && GET_CODE (sparc_compare_op0) == REG
4342 && GET_MODE (sparc_compare_op0) == DImode
4343 && v9_regcmp_p (code))
4345 operands[1] = gen_rtx_fmt_ee (code, DImode,
4346 sparc_compare_op0, sparc_compare_op1);
4350 rtx cc_reg = gen_compare_reg (code,
4351 sparc_compare_op0, sparc_compare_op1);
4352 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4356 ;; Conditional move define_insns.
4358 (define_insn "*movqi_cc_sp64"
4359 [(set (match_operand:QI 0 "register_operand" "=r,r")
4360 (if_then_else:QI (match_operator 1 "comparison_operator"
4361 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4363 (match_operand:QI 3 "arith11_operand" "rL,0")
4364 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4367 mov%C1\\t%x2, %3, %0
4368 mov%c1\\t%x2, %4, %0"
4369 [(set_attr "type" "cmove")])
4371 (define_insn "*movhi_cc_sp64"
4372 [(set (match_operand:HI 0 "register_operand" "=r,r")
4373 (if_then_else:HI (match_operator 1 "comparison_operator"
4374 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4376 (match_operand:HI 3 "arith11_operand" "rL,0")
4377 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4380 mov%C1\\t%x2, %3, %0
4381 mov%c1\\t%x2, %4, %0"
4382 [(set_attr "type" "cmove")])
4384 (define_insn "*movsi_cc_sp64"
4385 [(set (match_operand:SI 0 "register_operand" "=r,r")
4386 (if_then_else:SI (match_operator 1 "comparison_operator"
4387 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4389 (match_operand:SI 3 "arith11_operand" "rL,0")
4390 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4393 mov%C1\\t%x2, %3, %0
4394 mov%c1\\t%x2, %4, %0"
4395 [(set_attr "type" "cmove")])
4397 ;; ??? The constraints of operands 3,4 need work.
4398 (define_insn "*movdi_cc_sp64"
4399 [(set (match_operand:DI 0 "register_operand" "=r,r")
4400 (if_then_else:DI (match_operator 1 "comparison_operator"
4401 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4403 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4404 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4407 mov%C1\\t%x2, %3, %0
4408 mov%c1\\t%x2, %4, %0"
4409 [(set_attr "type" "cmove")])
4411 (define_insn "*movdi_cc_sp64_trunc"
4412 [(set (match_operand:SI 0 "register_operand" "=r,r")
4413 (if_then_else:SI (match_operator 1 "comparison_operator"
4414 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4416 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4417 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4420 mov%C1\\t%x2, %3, %0
4421 mov%c1\\t%x2, %4, %0"
4422 [(set_attr "type" "cmove")])
4424 (define_insn "*movsf_cc_sp64"
4425 [(set (match_operand:SF 0 "register_operand" "=f,f")
4426 (if_then_else:SF (match_operator 1 "comparison_operator"
4427 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4429 (match_operand:SF 3 "register_operand" "f,0")
4430 (match_operand:SF 4 "register_operand" "0,f")))]
4431 "TARGET_V9 && TARGET_FPU"
4433 fmovs%C1\\t%x2, %3, %0
4434 fmovs%c1\\t%x2, %4, %0"
4435 [(set_attr "type" "fpcmove")])
4437 (define_insn "movdf_cc_sp64"
4438 [(set (match_operand:DF 0 "register_operand" "=e,e")
4439 (if_then_else:DF (match_operator 1 "comparison_operator"
4440 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4442 (match_operand:DF 3 "register_operand" "e,0")
4443 (match_operand:DF 4 "register_operand" "0,e")))]
4444 "TARGET_V9 && TARGET_FPU"
4446 fmovd%C1\\t%x2, %3, %0
4447 fmovd%c1\\t%x2, %4, %0"
4448 [(set_attr "type" "fpcmove")
4449 (set_attr "fptype" "double")])
4451 (define_insn "*movtf_cc_hq_sp64"
4452 [(set (match_operand:TF 0 "register_operand" "=e,e")
4453 (if_then_else:TF (match_operator 1 "comparison_operator"
4454 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4456 (match_operand:TF 3 "register_operand" "e,0")
4457 (match_operand:TF 4 "register_operand" "0,e")))]
4458 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4460 fmovq%C1\\t%x2, %3, %0
4461 fmovq%c1\\t%x2, %4, %0"
4462 [(set_attr "type" "fpcmove")])
4464 (define_insn "*movtf_cc_sp64"
4465 [(set (match_operand:TF 0 "register_operand" "=e,e")
4466 (if_then_else:TF (match_operator 1 "comparison_operator"
4467 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4469 (match_operand:TF 3 "register_operand" "e,0")
4470 (match_operand:TF 4 "register_operand" "0,e")))]
4471 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4473 [(set_attr "length" "2")])
4476 [(set (match_operand:TF 0 "register_operand" "")
4477 (if_then_else:TF (match_operator 1 "comparison_operator"
4478 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4480 (match_operand:TF 3 "register_operand" "")
4481 (match_operand:TF 4 "register_operand" "")))]
4482 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4483 [(clobber (const_int 0))]
4486 rtx set_dest = operands[0];
4487 rtx set_srca = operands[3];
4488 rtx set_srcb = operands[4];
4489 int third = rtx_equal_p (set_dest, set_srca);
4491 rtx srca1, srca2, srcb1, srcb2;
4493 dest1 = gen_df_reg (set_dest, 0);
4494 dest2 = gen_df_reg (set_dest, 1);
4495 srca1 = gen_df_reg (set_srca, 0);
4496 srca2 = gen_df_reg (set_srca, 1);
4497 srcb1 = gen_df_reg (set_srcb, 0);
4498 srcb2 = gen_df_reg (set_srcb, 1);
4500 /* Now emit using the real source and destination we found, swapping
4501 the order if we detect overlap. */
4502 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4503 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4505 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4506 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4510 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4511 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4516 (define_insn "*movqi_cc_reg_sp64"
4517 [(set (match_operand:QI 0 "register_operand" "=r,r")
4518 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4519 [(match_operand:DI 2 "register_operand" "r,r")
4521 (match_operand:QI 3 "arith10_operand" "rM,0")
4522 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4525 movr%D1\\t%2, %r3, %0
4526 movr%d1\\t%2, %r4, %0"
4527 [(set_attr "type" "cmove")])
4529 (define_insn "*movhi_cc_reg_sp64"
4530 [(set (match_operand:HI 0 "register_operand" "=r,r")
4531 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4532 [(match_operand:DI 2 "register_operand" "r,r")
4534 (match_operand:HI 3 "arith10_operand" "rM,0")
4535 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4538 movr%D1\\t%2, %r3, %0
4539 movr%d1\\t%2, %r4, %0"
4540 [(set_attr "type" "cmove")])
4542 (define_insn "*movsi_cc_reg_sp64"
4543 [(set (match_operand:SI 0 "register_operand" "=r,r")
4544 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4545 [(match_operand:DI 2 "register_operand" "r,r")
4547 (match_operand:SI 3 "arith10_operand" "rM,0")
4548 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4551 movr%D1\\t%2, %r3, %0
4552 movr%d1\\t%2, %r4, %0"
4553 [(set_attr "type" "cmove")])
4555 ;; ??? The constraints of operands 3,4 need work.
4556 (define_insn "*movdi_cc_reg_sp64"
4557 [(set (match_operand:DI 0 "register_operand" "=r,r")
4558 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4559 [(match_operand:DI 2 "register_operand" "r,r")
4561 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4562 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4565 movr%D1\\t%2, %r3, %0
4566 movr%d1\\t%2, %r4, %0"
4567 [(set_attr "type" "cmove")])
4569 (define_insn "*movdi_cc_reg_sp64_trunc"
4570 [(set (match_operand:SI 0 "register_operand" "=r,r")
4571 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4572 [(match_operand:DI 2 "register_operand" "r,r")
4574 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4575 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4578 movr%D1\\t%2, %r3, %0
4579 movr%d1\\t%2, %r4, %0"
4580 [(set_attr "type" "cmove")])
4582 (define_insn "*movsf_cc_reg_sp64"
4583 [(set (match_operand:SF 0 "register_operand" "=f,f")
4584 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4585 [(match_operand:DI 2 "register_operand" "r,r")
4587 (match_operand:SF 3 "register_operand" "f,0")
4588 (match_operand:SF 4 "register_operand" "0,f")))]
4589 "TARGET_ARCH64 && TARGET_FPU"
4591 fmovrs%D1\\t%2, %3, %0
4592 fmovrs%d1\\t%2, %4, %0"
4593 [(set_attr "type" "fpcrmove")])
4595 (define_insn "movdf_cc_reg_sp64"
4596 [(set (match_operand:DF 0 "register_operand" "=e,e")
4597 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4598 [(match_operand:DI 2 "register_operand" "r,r")
4600 (match_operand:DF 3 "register_operand" "e,0")
4601 (match_operand:DF 4 "register_operand" "0,e")))]
4602 "TARGET_ARCH64 && TARGET_FPU"
4604 fmovrd%D1\\t%2, %3, %0
4605 fmovrd%d1\\t%2, %4, %0"
4606 [(set_attr "type" "fpcrmove")
4607 (set_attr "fptype" "double")])
4609 (define_insn "*movtf_cc_reg_hq_sp64"
4610 [(set (match_operand:TF 0 "register_operand" "=e,e")
4611 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4612 [(match_operand:DI 2 "register_operand" "r,r")
4614 (match_operand:TF 3 "register_operand" "e,0")
4615 (match_operand:TF 4 "register_operand" "0,e")))]
4616 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4618 fmovrq%D1\\t%2, %3, %0
4619 fmovrq%d1\\t%2, %4, %0"
4620 [(set_attr "type" "fpcrmove")])
4622 (define_insn "*movtf_cc_reg_sp64"
4623 [(set (match_operand:TF 0 "register_operand" "=e,e")
4624 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4625 [(match_operand:DI 2 "register_operand" "r,r")
4627 (match_operand:TF 3 "register_operand" "e,0")
4628 (match_operand:TF 4 "register_operand" "0,e")))]
4629 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4631 [(set_attr "length" "2")])
4634 [(set (match_operand:TF 0 "register_operand" "")
4635 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4636 [(match_operand:DI 2 "register_operand" "")
4638 (match_operand:TF 3 "register_operand" "")
4639 (match_operand:TF 4 "register_operand" "")))]
4640 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4641 [(clobber (const_int 0))]
4644 rtx set_dest = operands[0];
4645 rtx set_srca = operands[3];
4646 rtx set_srcb = operands[4];
4647 int third = rtx_equal_p (set_dest, set_srca);
4649 rtx srca1, srca2, srcb1, srcb2;
4651 dest1 = gen_df_reg (set_dest, 0);
4652 dest2 = gen_df_reg (set_dest, 1);
4653 srca1 = gen_df_reg (set_srca, 0);
4654 srca2 = gen_df_reg (set_srca, 1);
4655 srcb1 = gen_df_reg (set_srcb, 0);
4656 srcb2 = gen_df_reg (set_srcb, 1);
4658 /* Now emit using the real source and destination we found, swapping
4659 the order if we detect overlap. */
4660 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4661 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4663 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4664 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4668 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4669 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4675 ;;- zero extension instructions
4677 ;; These patterns originally accepted general_operands, however, slightly
4678 ;; better code is generated by only accepting register_operands, and then
4679 ;; letting combine generate the ldu[hb] insns.
4681 (define_expand "zero_extendhisi2"
4682 [(set (match_operand:SI 0 "register_operand" "")
4683 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4687 rtx temp = gen_reg_rtx (SImode);
4688 rtx shift_16 = GEN_INT (16);
4689 int op1_subbyte = 0;
4691 if (GET_CODE (operand1) == SUBREG)
4693 op1_subbyte = SUBREG_BYTE (operand1);
4694 op1_subbyte /= GET_MODE_SIZE (SImode);
4695 op1_subbyte *= GET_MODE_SIZE (SImode);
4696 operand1 = XEXP (operand1, 0);
4699 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4701 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4705 (define_insn "*zero_extendhisi2_insn"
4706 [(set (match_operand:SI 0 "register_operand" "=r")
4707 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4710 [(set_attr "type" "load")
4711 (set_attr "us3load_type" "3cycle")])
4713 (define_expand "zero_extendqihi2"
4714 [(set (match_operand:HI 0 "register_operand" "")
4715 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4719 (define_insn "*zero_extendqihi2_insn"
4720 [(set (match_operand:HI 0 "register_operand" "=r,r")
4721 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4722 "GET_CODE (operands[1]) != CONST_INT"
4726 [(set_attr "type" "*,load")
4727 (set_attr "us3load_type" "*,3cycle")])
4729 (define_expand "zero_extendqisi2"
4730 [(set (match_operand:SI 0 "register_operand" "")
4731 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4735 (define_insn "*zero_extendqisi2_insn"
4736 [(set (match_operand:SI 0 "register_operand" "=r,r")
4737 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4738 "GET_CODE (operands[1]) != CONST_INT"
4742 [(set_attr "type" "*,load")
4743 (set_attr "us3load_type" "*,3cycle")])
4745 (define_expand "zero_extendqidi2"
4746 [(set (match_operand:DI 0 "register_operand" "")
4747 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4751 (define_insn "*zero_extendqidi2_insn"
4752 [(set (match_operand:DI 0 "register_operand" "=r,r")
4753 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4754 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4758 [(set_attr "type" "*,load")
4759 (set_attr "us3load_type" "*,3cycle")])
4761 (define_expand "zero_extendhidi2"
4762 [(set (match_operand:DI 0 "register_operand" "")
4763 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4767 rtx temp = gen_reg_rtx (DImode);
4768 rtx shift_48 = GEN_INT (48);
4769 int op1_subbyte = 0;
4771 if (GET_CODE (operand1) == SUBREG)
4773 op1_subbyte = SUBREG_BYTE (operand1);
4774 op1_subbyte /= GET_MODE_SIZE (DImode);
4775 op1_subbyte *= GET_MODE_SIZE (DImode);
4776 operand1 = XEXP (operand1, 0);
4779 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4781 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4785 (define_insn "*zero_extendhidi2_insn"
4786 [(set (match_operand:DI 0 "register_operand" "=r")
4787 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4790 [(set_attr "type" "load")
4791 (set_attr "us3load_type" "3cycle")])
4794 ;; ??? Write truncdisi pattern using sra?
4796 (define_expand "zero_extendsidi2"
4797 [(set (match_operand:DI 0 "register_operand" "")
4798 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4802 (define_insn "*zero_extendsidi2_insn_sp64"
4803 [(set (match_operand:DI 0 "register_operand" "=r,r")
4804 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4805 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4809 [(set_attr "type" "shift,load")])
4811 (define_insn "*zero_extendsidi2_insn_sp32"
4812 [(set (match_operand:DI 0 "register_operand" "=r")
4813 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4816 [(set_attr "length" "2")])
4819 [(set (match_operand:DI 0 "register_operand" "")
4820 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4821 "! TARGET_ARCH64 && reload_completed"
4822 [(set (match_dup 2) (match_dup 3))
4823 (set (match_dup 4) (match_dup 5))]
4828 dest1 = gen_highpart (SImode, operands[0]);
4829 dest2 = gen_lowpart (SImode, operands[0]);
4831 /* Swap the order in case of overlap. */
4832 if (REGNO (dest1) == REGNO (operands[1]))
4834 operands[2] = dest2;
4835 operands[3] = operands[1];
4836 operands[4] = dest1;
4837 operands[5] = const0_rtx;
4841 operands[2] = dest1;
4842 operands[3] = const0_rtx;
4843 operands[4] = dest2;
4844 operands[5] = operands[1];
4848 ;; Simplify comparisons of extended values.
4850 (define_insn "*cmp_zero_extendqisi2"
4852 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4855 "andcc\\t%0, 0xff, %%g0"
4856 [(set_attr "type" "compare")])
4858 (define_insn "*cmp_zero_qi"
4860 (compare:CC (match_operand:QI 0 "register_operand" "r")
4863 "andcc\\t%0, 0xff, %%g0"
4864 [(set_attr "type" "compare")])
4866 (define_insn "*cmp_zero_extendqisi2_set"
4868 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4870 (set (match_operand:SI 0 "register_operand" "=r")
4871 (zero_extend:SI (match_dup 1)))]
4873 "andcc\\t%1, 0xff, %0"
4874 [(set_attr "type" "compare")])
4876 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4878 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4881 (set (match_operand:SI 0 "register_operand" "=r")
4882 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4884 "andcc\\t%1, 0xff, %0"
4885 [(set_attr "type" "compare")])
4887 (define_insn "*cmp_zero_extendqidi2"
4889 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4892 "andcc\\t%0, 0xff, %%g0"
4893 [(set_attr "type" "compare")])
4895 (define_insn "*cmp_zero_qi_sp64"
4897 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4900 "andcc\\t%0, 0xff, %%g0"
4901 [(set_attr "type" "compare")])
4903 (define_insn "*cmp_zero_extendqidi2_set"
4905 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4907 (set (match_operand:DI 0 "register_operand" "=r")
4908 (zero_extend:DI (match_dup 1)))]
4910 "andcc\\t%1, 0xff, %0"
4911 [(set_attr "type" "compare")])
4913 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4915 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4918 (set (match_operand:DI 0 "register_operand" "=r")
4919 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4921 "andcc\\t%1, 0xff, %0"
4922 [(set_attr "type" "compare")])
4924 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4926 (define_insn "*cmp_siqi_trunc"
4928 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4931 "andcc\\t%0, 0xff, %%g0"
4932 [(set_attr "type" "compare")])
4934 (define_insn "*cmp_siqi_trunc_set"
4936 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4938 (set (match_operand:QI 0 "register_operand" "=r")
4939 (subreg:QI (match_dup 1) 3))]
4941 "andcc\\t%1, 0xff, %0"
4942 [(set_attr "type" "compare")])
4944 (define_insn "*cmp_diqi_trunc"
4946 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4949 "andcc\\t%0, 0xff, %%g0"
4950 [(set_attr "type" "compare")])
4952 (define_insn "*cmp_diqi_trunc_set"
4954 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4956 (set (match_operand:QI 0 "register_operand" "=r")
4957 (subreg:QI (match_dup 1) 7))]
4959 "andcc\\t%1, 0xff, %0"
4960 [(set_attr "type" "compare")])
4962 ;;- sign extension instructions
4964 ;; These patterns originally accepted general_operands, however, slightly
4965 ;; better code is generated by only accepting register_operands, and then
4966 ;; letting combine generate the lds[hb] insns.
4968 (define_expand "extendhisi2"
4969 [(set (match_operand:SI 0 "register_operand" "")
4970 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4974 rtx temp = gen_reg_rtx (SImode);
4975 rtx shift_16 = GEN_INT (16);
4976 int op1_subbyte = 0;
4978 if (GET_CODE (operand1) == SUBREG)
4980 op1_subbyte = SUBREG_BYTE (operand1);
4981 op1_subbyte /= GET_MODE_SIZE (SImode);
4982 op1_subbyte *= GET_MODE_SIZE (SImode);
4983 operand1 = XEXP (operand1, 0);
4986 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4988 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4992 (define_insn "*sign_extendhisi2_insn"
4993 [(set (match_operand:SI 0 "register_operand" "=r")
4994 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4997 [(set_attr "type" "sload")
4998 (set_attr "us3load_type" "3cycle")])
5000 (define_expand "extendqihi2"
5001 [(set (match_operand:HI 0 "register_operand" "")
5002 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
5006 rtx temp = gen_reg_rtx (SImode);
5007 rtx shift_24 = GEN_INT (24);
5008 int op1_subbyte = 0;
5009 int op0_subbyte = 0;
5011 if (GET_CODE (operand1) == SUBREG)
5013 op1_subbyte = SUBREG_BYTE (operand1);
5014 op1_subbyte /= GET_MODE_SIZE (SImode);
5015 op1_subbyte *= GET_MODE_SIZE (SImode);
5016 operand1 = XEXP (operand1, 0);
5018 if (GET_CODE (operand0) == SUBREG)
5020 op0_subbyte = SUBREG_BYTE (operand0);
5021 op0_subbyte /= GET_MODE_SIZE (SImode);
5022 op0_subbyte *= GET_MODE_SIZE (SImode);
5023 operand0 = XEXP (operand0, 0);
5025 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
5027 if (GET_MODE (operand0) != SImode)
5028 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
5029 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
5033 (define_insn "*sign_extendqihi2_insn"
5034 [(set (match_operand:HI 0 "register_operand" "=r")
5035 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
5038 [(set_attr "type" "sload")
5039 (set_attr "us3load_type" "3cycle")])
5041 (define_expand "extendqisi2"
5042 [(set (match_operand:SI 0 "register_operand" "")
5043 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5047 rtx temp = gen_reg_rtx (SImode);
5048 rtx shift_24 = GEN_INT (24);
5049 int op1_subbyte = 0;
5051 if (GET_CODE (operand1) == SUBREG)
5053 op1_subbyte = SUBREG_BYTE (operand1);
5054 op1_subbyte /= GET_MODE_SIZE (SImode);
5055 op1_subbyte *= GET_MODE_SIZE (SImode);
5056 operand1 = XEXP (operand1, 0);
5059 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
5061 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
5065 (define_insn "*sign_extendqisi2_insn"
5066 [(set (match_operand:SI 0 "register_operand" "=r")
5067 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
5070 [(set_attr "type" "sload")
5071 (set_attr "us3load_type" "3cycle")])
5073 (define_expand "extendqidi2"
5074 [(set (match_operand:DI 0 "register_operand" "")
5075 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
5079 rtx temp = gen_reg_rtx (DImode);
5080 rtx shift_56 = GEN_INT (56);
5081 int op1_subbyte = 0;
5083 if (GET_CODE (operand1) == SUBREG)
5085 op1_subbyte = SUBREG_BYTE (operand1);
5086 op1_subbyte /= GET_MODE_SIZE (DImode);
5087 op1_subbyte *= GET_MODE_SIZE (DImode);
5088 operand1 = XEXP (operand1, 0);
5091 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
5093 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
5097 (define_insn "*sign_extendqidi2_insn"
5098 [(set (match_operand:DI 0 "register_operand" "=r")
5099 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
5102 [(set_attr "type" "sload")
5103 (set_attr "us3load_type" "3cycle")])
5105 (define_expand "extendhidi2"
5106 [(set (match_operand:DI 0 "register_operand" "")
5107 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
5111 rtx temp = gen_reg_rtx (DImode);
5112 rtx shift_48 = GEN_INT (48);
5113 int op1_subbyte = 0;
5115 if (GET_CODE (operand1) == SUBREG)
5117 op1_subbyte = SUBREG_BYTE (operand1);
5118 op1_subbyte /= GET_MODE_SIZE (DImode);
5119 op1_subbyte *= GET_MODE_SIZE (DImode);
5120 operand1 = XEXP (operand1, 0);
5123 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
5125 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
5129 (define_insn "*sign_extendhidi2_insn"
5130 [(set (match_operand:DI 0 "register_operand" "=r")
5131 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
5134 [(set_attr "type" "sload")
5135 (set_attr "us3load_type" "3cycle")])
5137 (define_expand "extendsidi2"
5138 [(set (match_operand:DI 0 "register_operand" "")
5139 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
5143 (define_insn "*sign_extendsidi2_insn"
5144 [(set (match_operand:DI 0 "register_operand" "=r,r")
5145 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
5150 [(set_attr "type" "shift,sload")
5151 (set_attr "us3load_type" "*,3cycle")])
5153 ;; Special pattern for optimizing bit-field compares. This is needed
5154 ;; because combine uses this as a canonical form.
5156 (define_insn "*cmp_zero_extract"
5159 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
5160 (match_operand:SI 1 "small_int_or_double" "n")
5161 (match_operand:SI 2 "small_int_or_double" "n"))
5163 "(GET_CODE (operands[2]) == CONST_INT
5164 && INTVAL (operands[2]) > 19)
5165 || (GET_CODE (operands[2]) == CONST_DOUBLE
5166 && CONST_DOUBLE_LOW (operands[2]) > 19)"
5169 int len = (GET_CODE (operands[1]) == CONST_INT
5170 ? INTVAL (operands[1])
5171 : CONST_DOUBLE_LOW (operands[1]));
5173 (GET_CODE (operands[2]) == CONST_INT
5174 ? INTVAL (operands[2])
5175 : CONST_DOUBLE_LOW (operands[2])) - len;
5176 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
5178 operands[1] = GEN_INT (mask);
5179 return \"andcc\\t%0, %1, %%g0\";
5181 [(set_attr "type" "compare")])
5183 (define_insn "*cmp_zero_extract_sp64"
5186 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
5187 (match_operand:SI 1 "small_int_or_double" "n")
5188 (match_operand:SI 2 "small_int_or_double" "n"))
5191 && ((GET_CODE (operands[2]) == CONST_INT
5192 && INTVAL (operands[2]) > 51)
5193 || (GET_CODE (operands[2]) == CONST_DOUBLE
5194 && CONST_DOUBLE_LOW (operands[2]) > 51))"
5197 int len = (GET_CODE (operands[1]) == CONST_INT
5198 ? INTVAL (operands[1])
5199 : CONST_DOUBLE_LOW (operands[1]));
5201 (GET_CODE (operands[2]) == CONST_INT
5202 ? INTVAL (operands[2])
5203 : CONST_DOUBLE_LOW (operands[2])) - len;
5204 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5206 operands[1] = GEN_INT (mask);
5207 return \"andcc\\t%0, %1, %%g0\";
5209 [(set_attr "type" "compare")])
5211 ;; Conversions between float, double and long double.
5213 (define_insn "extendsfdf2"
5214 [(set (match_operand:DF 0 "register_operand" "=e")
5216 (match_operand:SF 1 "register_operand" "f")))]
5219 [(set_attr "type" "fp")
5220 (set_attr "fptype" "double")])
5222 (define_expand "extendsftf2"
5223 [(set (match_operand:TF 0 "register_operand" "=e")
5225 (match_operand:SF 1 "register_operand" "f")))]
5226 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5229 if (! TARGET_HARD_QUAD)
5233 if (GET_CODE (operands[0]) != MEM)
5234 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5236 slot0 = operands[0];
5238 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), LCT_NORMAL,
5240 XEXP (slot0, 0), Pmode,
5241 operands[1], SFmode);
5243 if (GET_CODE (operands[0]) != MEM)
5244 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5249 (define_insn "*extendsftf2_hq"
5250 [(set (match_operand:TF 0 "register_operand" "=e")
5252 (match_operand:SF 1 "register_operand" "f")))]
5253 "TARGET_FPU && TARGET_HARD_QUAD"
5255 [(set_attr "type" "fp")])
5257 (define_expand "extenddftf2"
5258 [(set (match_operand:TF 0 "register_operand" "=e")
5260 (match_operand:DF 1 "register_operand" "e")))]
5261 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5264 if (! TARGET_HARD_QUAD)
5268 if (GET_CODE (operands[0]) != MEM)
5269 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5271 slot0 = operands[0];
5273 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), LCT_NORMAL,
5275 XEXP (slot0, 0), Pmode,
5276 operands[1], DFmode);
5278 if (GET_CODE (operands[0]) != MEM)
5279 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5284 (define_insn "*extenddftf2_hq"
5285 [(set (match_operand:TF 0 "register_operand" "=e")
5287 (match_operand:DF 1 "register_operand" "e")))]
5288 "TARGET_FPU && TARGET_HARD_QUAD"
5290 [(set_attr "type" "fp")])
5292 (define_insn "truncdfsf2"
5293 [(set (match_operand:SF 0 "register_operand" "=f")
5295 (match_operand:DF 1 "register_operand" "e")))]
5298 [(set_attr "type" "fp")
5299 (set_attr "fptype" "double")])
5301 (define_expand "trunctfsf2"
5302 [(set (match_operand:SF 0 "register_operand" "=f")
5304 (match_operand:TF 1 "register_operand" "e")))]
5305 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5308 if (! TARGET_HARD_QUAD)
5312 if (GET_CODE (operands[1]) != MEM)
5314 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5315 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5318 slot0 = operands[1];
5320 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5321 operands[0], LCT_NORMAL, SFmode, 1,
5322 XEXP (slot0, 0), Pmode);
5327 (define_insn "*trunctfsf2_hq"
5328 [(set (match_operand:SF 0 "register_operand" "=f")
5330 (match_operand:TF 1 "register_operand" "e")))]
5331 "TARGET_FPU && TARGET_HARD_QUAD"
5333 [(set_attr "type" "fp")])
5335 (define_expand "trunctfdf2"
5336 [(set (match_operand:DF 0 "register_operand" "=f")
5338 (match_operand:TF 1 "register_operand" "e")))]
5339 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5342 if (! TARGET_HARD_QUAD)
5346 if (GET_CODE (operands[1]) != MEM)
5348 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5349 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5352 slot0 = operands[1];
5354 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5355 operands[0], LCT_NORMAL, DFmode, 1,
5356 XEXP (slot0, 0), Pmode);
5361 (define_insn "*trunctfdf2_hq"
5362 [(set (match_operand:DF 0 "register_operand" "=e")
5364 (match_operand:TF 1 "register_operand" "e")))]
5365 "TARGET_FPU && TARGET_HARD_QUAD"
5367 [(set_attr "type" "fp")])
5369 ;; Conversion between fixed point and floating point.
5371 (define_insn "floatsisf2"
5372 [(set (match_operand:SF 0 "register_operand" "=f")
5373 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5376 [(set_attr "type" "fp")
5377 (set_attr "fptype" "double")])
5379 (define_insn "floatsidf2"
5380 [(set (match_operand:DF 0 "register_operand" "=e")
5381 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5384 [(set_attr "type" "fp")
5385 (set_attr "fptype" "double")])
5387 (define_expand "floatsitf2"
5388 [(set (match_operand:TF 0 "register_operand" "=e")
5389 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5390 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5393 if (! TARGET_HARD_QUAD)
5397 if (GET_CODE (operands[1]) != MEM)
5398 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5400 slot0 = operands[1];
5402 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5404 XEXP (slot0, 0), Pmode,
5405 operands[1], SImode);
5407 if (GET_CODE (operands[0]) != MEM)
5408 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5413 (define_insn "*floatsitf2_hq"
5414 [(set (match_operand:TF 0 "register_operand" "=e")
5415 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5416 "TARGET_FPU && TARGET_HARD_QUAD"
5418 [(set_attr "type" "fp")])
5420 (define_expand "floatunssitf2"
5421 [(set (match_operand:TF 0 "register_operand" "=e")
5422 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5423 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5428 if (GET_CODE (operands[1]) != MEM)
5429 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5431 slot0 = operands[1];
5433 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5435 XEXP (slot0, 0), Pmode,
5436 operands[1], SImode);
5438 if (GET_CODE (operands[0]) != MEM)
5439 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5443 ;; Now the same for 64 bit sources.
5445 (define_insn "floatdisf2"
5446 [(set (match_operand:SF 0 "register_operand" "=f")
5447 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5448 "TARGET_V9 && TARGET_FPU"
5450 [(set_attr "type" "fp")
5451 (set_attr "fptype" "double")])
5453 (define_expand "floatunsdisf2"
5454 [(use (match_operand:SF 0 "register_operand" ""))
5455 (use (match_operand:DI 1 "register_operand" ""))]
5456 "TARGET_ARCH64 && TARGET_FPU"
5457 "sparc_emit_floatunsdi (operands); DONE;")
5459 (define_insn "floatdidf2"
5460 [(set (match_operand:DF 0 "register_operand" "=e")
5461 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5462 "TARGET_V9 && TARGET_FPU"
5464 [(set_attr "type" "fp")
5465 (set_attr "fptype" "double")])
5467 (define_expand "floatunsdidf2"
5468 [(use (match_operand:DF 0 "register_operand" ""))
5469 (use (match_operand:DI 1 "register_operand" ""))]
5470 "TARGET_ARCH64 && TARGET_FPU"
5471 "sparc_emit_floatunsdi (operands); DONE;")
5473 (define_expand "floatditf2"
5474 [(set (match_operand:TF 0 "register_operand" "=e")
5475 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5476 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5479 if (! TARGET_HARD_QUAD)
5483 if (GET_CODE (operands[1]) != MEM)
5484 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5486 slot0 = operands[1];
5488 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5490 XEXP (slot0, 0), Pmode,
5491 operands[1], DImode);
5493 if (GET_CODE (operands[0]) != MEM)
5494 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5499 (define_insn "*floatditf2_hq"
5500 [(set (match_operand:TF 0 "register_operand" "=e")
5501 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5502 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5504 [(set_attr "type" "fp")])
5506 (define_expand "floatunsditf2"
5507 [(set (match_operand:TF 0 "register_operand" "=e")
5508 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5509 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5514 if (GET_CODE (operands[1]) != MEM)
5515 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5517 slot0 = operands[1];
5519 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5521 XEXP (slot0, 0), Pmode,
5522 operands[1], DImode);
5524 if (GET_CODE (operands[0]) != MEM)
5525 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5529 ;; Convert a float to an actual integer.
5530 ;; Truncation is performed as part of the conversion.
5532 (define_insn "fix_truncsfsi2"
5533 [(set (match_operand:SI 0 "register_operand" "=f")
5534 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5537 [(set_attr "type" "fp")
5538 (set_attr "fptype" "double")])
5540 (define_insn "fix_truncdfsi2"
5541 [(set (match_operand:SI 0 "register_operand" "=f")
5542 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5545 [(set_attr "type" "fp")
5546 (set_attr "fptype" "double")])
5548 (define_expand "fix_trunctfsi2"
5549 [(set (match_operand:SI 0 "register_operand" "=f")
5550 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5551 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5554 if (! TARGET_HARD_QUAD)
5558 if (GET_CODE (operands[1]) != MEM)
5560 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5561 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5564 slot0 = operands[1];
5566 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5567 operands[0], LCT_NORMAL, SImode, 1,
5568 XEXP (slot0, 0), Pmode);
5573 (define_insn "*fix_trunctfsi2_hq"
5574 [(set (match_operand:SI 0 "register_operand" "=f")
5575 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5576 "TARGET_FPU && TARGET_HARD_QUAD"
5578 [(set_attr "type" "fp")])
5580 (define_expand "fixuns_trunctfsi2"
5581 [(set (match_operand:SI 0 "register_operand" "=f")
5582 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5583 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5588 if (GET_CODE (operands[1]) != MEM)
5590 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5591 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5594 slot0 = operands[1];
5596 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5597 operands[0], LCT_NORMAL, SImode, 1,
5598 XEXP (slot0, 0), Pmode);
5602 ;; Now the same, for V9 targets
5604 (define_insn "fix_truncsfdi2"
5605 [(set (match_operand:DI 0 "register_operand" "=e")
5606 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5607 "TARGET_V9 && TARGET_FPU"
5609 [(set_attr "type" "fp")
5610 (set_attr "fptype" "double")])
5612 (define_insn "fix_truncdfdi2"
5613 [(set (match_operand:DI 0 "register_operand" "=e")
5614 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5615 "TARGET_V9 && TARGET_FPU"
5617 [(set_attr "type" "fp")
5618 (set_attr "fptype" "double")])
5620 (define_expand "fix_trunctfdi2"
5621 [(set (match_operand:DI 0 "register_operand" "=e")
5622 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5623 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5626 if (! TARGET_HARD_QUAD)
5630 if (GET_CODE (operands[1]) != MEM)
5632 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5633 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5636 slot0 = operands[1];
5638 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5639 operands[0], LCT_NORMAL, DImode, 1,
5640 XEXP (slot0, 0), Pmode);
5645 (define_insn "*fix_trunctfdi2_hq"
5646 [(set (match_operand:DI 0 "register_operand" "=e")
5647 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5648 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5650 [(set_attr "type" "fp")])
5652 (define_expand "fixuns_trunctfdi2"
5653 [(set (match_operand:DI 0 "register_operand" "=f")
5654 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5655 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5660 if (GET_CODE (operands[1]) != MEM)
5662 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5663 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5666 slot0 = operands[1];
5668 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5669 operands[0], LCT_NORMAL, DImode, 1,
5670 XEXP (slot0, 0), Pmode);
5675 ;;- arithmetic instructions
5677 (define_expand "adddi3"
5678 [(set (match_operand:DI 0 "register_operand" "=r")
5679 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5680 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5686 if (! TARGET_ARCH64)
5688 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5689 gen_rtx_SET (VOIDmode, operands[0],
5690 gen_rtx_PLUS (DImode, operands[1],
5692 gen_rtx_CLOBBER (VOIDmode,
5693 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5696 if (arith_double_4096_operand(operands[2], DImode))
5698 switch (GET_CODE (operands[1]))
5700 case CONST_INT: i = INTVAL (operands[1]); break;
5701 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5703 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5704 gen_rtx_MINUS (DImode, operands[1],
5708 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5713 (define_insn "adddi3_insn_sp32"
5714 [(set (match_operand:DI 0 "register_operand" "=r")
5715 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5716 (match_operand:DI 2 "arith_double_operand" "rHI")))
5717 (clobber (reg:CC 100))]
5720 [(set_attr "length" "2")])
5723 [(set (match_operand:DI 0 "register_operand" "")
5724 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5725 (match_operand:DI 2 "arith_double_operand" "")))
5726 (clobber (reg:CC 100))]
5727 "! TARGET_ARCH64 && reload_completed"
5728 [(parallel [(set (reg:CC_NOOV 100)
5729 (compare:CC_NOOV (plus:SI (match_dup 4)
5733 (plus:SI (match_dup 4) (match_dup 5)))])
5735 (plus:SI (plus:SI (match_dup 7)
5737 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5740 operands[3] = gen_lowpart (SImode, operands[0]);
5741 operands[4] = gen_lowpart (SImode, operands[1]);
5742 operands[5] = gen_lowpart (SImode, operands[2]);
5743 operands[6] = gen_highpart (SImode, operands[0]);
5744 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5745 #if HOST_BITS_PER_WIDE_INT == 32
5746 if (GET_CODE (operands[2]) == CONST_INT)
5748 if (INTVAL (operands[2]) < 0)
5749 operands[8] = constm1_rtx;
5751 operands[8] = const0_rtx;
5755 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5759 [(set (match_operand:DI 0 "register_operand" "")
5760 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5761 (match_operand:DI 2 "arith_double_operand" "")))
5762 (clobber (reg:CC 100))]
5763 "! TARGET_ARCH64 && reload_completed"
5764 [(parallel [(set (reg:CC_NOOV 100)
5765 (compare:CC_NOOV (minus:SI (match_dup 4)
5769 (minus:SI (match_dup 4) (match_dup 5)))])
5771 (minus:SI (minus:SI (match_dup 7)
5773 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5776 operands[3] = gen_lowpart (SImode, operands[0]);
5777 operands[4] = gen_lowpart (SImode, operands[1]);
5778 operands[5] = gen_lowpart (SImode, operands[2]);
5779 operands[6] = gen_highpart (SImode, operands[0]);
5780 operands[7] = gen_highpart (SImode, operands[1]);
5781 #if HOST_BITS_PER_WIDE_INT == 32
5782 if (GET_CODE (operands[2]) == CONST_INT)
5784 if (INTVAL (operands[2]) < 0)
5785 operands[8] = constm1_rtx;
5787 operands[8] = const0_rtx;
5791 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5794 ;; LTU here means "carry set"
5796 [(set (match_operand:SI 0 "register_operand" "=r")
5797 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5798 (match_operand:SI 2 "arith_operand" "rI"))
5799 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5802 [(set_attr "type" "misc")])
5804 (define_insn "*addx_extend_sp32"
5805 [(set (match_operand:DI 0 "register_operand" "=r")
5806 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5807 (match_operand:SI 2 "arith_operand" "rI"))
5808 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5811 [(set_attr "length" "2")])
5814 [(set (match_operand:DI 0 "register_operand" "")
5815 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5816 (match_operand:SI 2 "arith_operand" ""))
5817 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5818 "! TARGET_ARCH64 && reload_completed"
5819 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5820 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5821 (set (match_dup 4) (const_int 0))]
5822 "operands[3] = gen_lowpart (SImode, operands[0]);
5823 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5825 (define_insn "*addx_extend_sp64"
5826 [(set (match_operand:DI 0 "register_operand" "=r")
5827 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5828 (match_operand:SI 2 "arith_operand" "rI"))
5829 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5831 "addx\\t%r1, %2, %0"
5832 [(set_attr "type" "misc")])
5835 [(set (match_operand:SI 0 "register_operand" "=r")
5836 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5837 (match_operand:SI 2 "arith_operand" "rI"))
5838 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5840 "subx\\t%r1, %2, %0"
5841 [(set_attr "type" "misc")])
5843 (define_insn "*subx_extend_sp64"
5844 [(set (match_operand:DI 0 "register_operand" "=r")
5845 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5846 (match_operand:SI 2 "arith_operand" "rI"))
5847 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5849 "subx\\t%r1, %2, %0"
5850 [(set_attr "type" "misc")])
5852 (define_insn "*subx_extend"
5853 [(set (match_operand:DI 0 "register_operand" "=r")
5854 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5855 (match_operand:SI 2 "arith_operand" "rI"))
5856 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5859 [(set_attr "length" "2")])
5862 [(set (match_operand:DI 0 "register_operand" "")
5863 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5864 (match_operand:SI 2 "arith_operand" ""))
5865 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5866 "! TARGET_ARCH64 && reload_completed"
5867 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5868 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5869 (set (match_dup 4) (const_int 0))]
5870 "operands[3] = gen_lowpart (SImode, operands[0]);
5871 operands[4] = gen_highpart (SImode, operands[0]);")
5874 [(set (match_operand:DI 0 "register_operand" "=r")
5875 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5876 (match_operand:DI 2 "register_operand" "r")))
5877 (clobber (reg:CC 100))]
5880 [(set_attr "length" "2")])
5883 [(set (match_operand:DI 0 "register_operand" "")
5884 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5885 (match_operand:DI 2 "register_operand" "")))
5886 (clobber (reg:CC 100))]
5887 "! TARGET_ARCH64 && reload_completed"
5888 [(parallel [(set (reg:CC_NOOV 100)
5889 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5891 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5893 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5894 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5895 "operands[3] = gen_lowpart (SImode, operands[2]);
5896 operands[4] = gen_highpart (SImode, operands[2]);
5897 operands[5] = gen_lowpart (SImode, operands[0]);
5898 operands[6] = gen_highpart (SImode, operands[0]);")
5900 (define_insn "*adddi3_sp64"
5901 [(set (match_operand:DI 0 "register_operand" "=r")
5902 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5903 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5907 (define_expand "addsi3"
5908 [(set (match_operand:SI 0 "register_operand" "=r,d")
5909 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5910 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5914 if (arith_4096_operand(operands[2], SImode))
5916 if (GET_CODE (operands[1]) == CONST_INT)
5917 emit_insn (gen_movsi (operands[0],
5918 GEN_INT (INTVAL (operands[1]) + 4096)));
5920 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5921 gen_rtx_MINUS (SImode, operands[1],
5927 (define_insn "*addsi3"
5928 [(set (match_operand:SI 0 "register_operand" "=r,d")
5929 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5930 (match_operand:SI 2 "arith_operand" "rI,d")))]
5934 fpadd32s\\t%1, %2, %0"
5935 [(set_attr "type" "*,fp")])
5937 (define_insn "*cmp_cc_plus"
5938 [(set (reg:CC_NOOV 100)
5939 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5940 (match_operand:SI 1 "arith_operand" "rI"))
5943 "addcc\\t%0, %1, %%g0"
5944 [(set_attr "type" "compare")])
5946 (define_insn "*cmp_ccx_plus"
5947 [(set (reg:CCX_NOOV 100)
5948 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5949 (match_operand:DI 1 "arith_double_operand" "rHI"))
5952 "addcc\\t%0, %1, %%g0"
5953 [(set_attr "type" "compare")])
5955 (define_insn "*cmp_cc_plus_set"
5956 [(set (reg:CC_NOOV 100)
5957 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5958 (match_operand:SI 2 "arith_operand" "rI"))
5960 (set (match_operand:SI 0 "register_operand" "=r")
5961 (plus:SI (match_dup 1) (match_dup 2)))]
5963 "addcc\\t%1, %2, %0"
5964 [(set_attr "type" "compare")])
5966 (define_insn "*cmp_ccx_plus_set"
5967 [(set (reg:CCX_NOOV 100)
5968 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5969 (match_operand:DI 2 "arith_double_operand" "rHI"))
5971 (set (match_operand:DI 0 "register_operand" "=r")
5972 (plus:DI (match_dup 1) (match_dup 2)))]
5974 "addcc\\t%1, %2, %0"
5975 [(set_attr "type" "compare")])
5977 (define_expand "subdi3"
5978 [(set (match_operand:DI 0 "register_operand" "=r")
5979 (minus:DI (match_operand:DI 1 "register_operand" "r")
5980 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5984 if (! TARGET_ARCH64)
5986 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5987 gen_rtx_SET (VOIDmode, operands[0],
5988 gen_rtx_MINUS (DImode, operands[1],
5990 gen_rtx_CLOBBER (VOIDmode,
5991 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5994 if (arith_double_4096_operand(operands[2], DImode))
5996 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5997 gen_rtx_PLUS (DImode, operands[1],
6003 (define_insn "*subdi3_sp32"
6004 [(set (match_operand:DI 0 "register_operand" "=r")
6005 (minus:DI (match_operand:DI 1 "register_operand" "r")
6006 (match_operand:DI 2 "arith_double_operand" "rHI")))
6007 (clobber (reg:CC 100))]
6010 [(set_attr "length" "2")])
6013 [(set (match_operand:DI 0 "register_operand" "")
6014 (minus:DI (match_operand:DI 1 "register_operand" "")
6015 (match_operand:DI 2 "arith_double_operand" "")))
6016 (clobber (reg:CC 100))]
6019 && (GET_CODE (operands[2]) == CONST_INT
6020 || GET_CODE (operands[2]) == CONST_DOUBLE)"
6021 [(clobber (const_int 0))]
6026 highp = gen_highpart_mode (SImode, DImode, operands[2]);
6027 lowp = gen_lowpart (SImode, operands[2]);
6028 if ((lowp == const0_rtx)
6029 && (operands[0] == operands[1]))
6031 emit_insn (gen_rtx_SET (VOIDmode,
6032 gen_highpart (SImode, operands[0]),
6033 gen_rtx_MINUS (SImode,
6034 gen_highpart_mode (SImode, DImode,
6040 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
6041 gen_lowpart (SImode, operands[1]),
6043 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
6044 gen_highpart_mode (SImode, DImode, operands[1]),
6051 [(set (match_operand:DI 0 "register_operand" "")
6052 (minus:DI (match_operand:DI 1 "register_operand" "")
6053 (match_operand:DI 2 "register_operand" "")))
6054 (clobber (reg:CC 100))]
6056 && reload_completed"
6057 [(clobber (const_int 0))]
6060 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
6061 gen_lowpart (SImode, operands[1]),
6062 gen_lowpart (SImode, operands[2])));
6063 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
6064 gen_highpart (SImode, operands[1]),
6065 gen_highpart (SImode, operands[2])));
6070 [(set (match_operand:DI 0 "register_operand" "=r")
6071 (minus:DI (match_operand:DI 1 "register_operand" "r")
6072 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
6073 (clobber (reg:CC 100))]
6076 [(set_attr "length" "2")])
6079 [(set (match_operand:DI 0 "register_operand" "")
6080 (minus:DI (match_operand:DI 1 "register_operand" "")
6081 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
6082 (clobber (reg:CC 100))]
6083 "! TARGET_ARCH64 && reload_completed"
6084 [(parallel [(set (reg:CC_NOOV 100)
6085 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
6087 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
6089 (minus:SI (minus:SI (match_dup 4) (const_int 0))
6090 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
6091 "operands[3] = gen_lowpart (SImode, operands[1]);
6092 operands[4] = gen_highpart (SImode, operands[1]);
6093 operands[5] = gen_lowpart (SImode, operands[0]);
6094 operands[6] = gen_highpart (SImode, operands[0]);")
6096 (define_insn "*subdi3_sp64"
6097 [(set (match_operand:DI 0 "register_operand" "=r")
6098 (minus:DI (match_operand:DI 1 "register_operand" "r")
6099 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6103 (define_expand "subsi3"
6104 [(set (match_operand:SI 0 "register_operand" "=r,d")
6105 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
6106 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
6110 if (arith_4096_operand(operands[2], SImode))
6112 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6113 gen_rtx_PLUS (SImode, operands[1],
6119 (define_insn "*subsi3"
6120 [(set (match_operand:SI 0 "register_operand" "=r,d")
6121 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
6122 (match_operand:SI 2 "arith_operand" "rI,d")))]
6126 fpsub32s\\t%1, %2, %0"
6127 [(set_attr "type" "*,fp")])
6129 (define_insn "*cmp_minus_cc"
6130 [(set (reg:CC_NOOV 100)
6131 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
6132 (match_operand:SI 1 "arith_operand" "rI"))
6135 "subcc\\t%r0, %1, %%g0"
6136 [(set_attr "type" "compare")])
6138 (define_insn "*cmp_minus_ccx"
6139 [(set (reg:CCX_NOOV 100)
6140 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
6141 (match_operand:DI 1 "arith_double_operand" "rHI"))
6144 "subcc\\t%0, %1, %%g0"
6145 [(set_attr "type" "compare")])
6147 (define_insn "cmp_minus_cc_set"
6148 [(set (reg:CC_NOOV 100)
6149 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
6150 (match_operand:SI 2 "arith_operand" "rI"))
6152 (set (match_operand:SI 0 "register_operand" "=r")
6153 (minus:SI (match_dup 1) (match_dup 2)))]
6155 "subcc\\t%r1, %2, %0"
6156 [(set_attr "type" "compare")])
6158 (define_insn "*cmp_minus_ccx_set"
6159 [(set (reg:CCX_NOOV 100)
6160 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
6161 (match_operand:DI 2 "arith_double_operand" "rHI"))
6163 (set (match_operand:DI 0 "register_operand" "=r")
6164 (minus:DI (match_dup 1) (match_dup 2)))]
6166 "subcc\\t%1, %2, %0"
6167 [(set_attr "type" "compare")])
6169 ;; Integer Multiply/Divide.
6171 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
6172 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
6174 (define_insn "mulsi3"
6175 [(set (match_operand:SI 0 "register_operand" "=r")
6176 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6177 (match_operand:SI 2 "arith_operand" "rI")))]
6180 [(set_attr "type" "imul")])
6182 (define_expand "muldi3"
6183 [(set (match_operand:DI 0 "register_operand" "=r")
6184 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6185 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6186 "TARGET_ARCH64 || TARGET_V8PLUS"
6191 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
6196 (define_insn "*muldi3_sp64"
6197 [(set (match_operand:DI 0 "register_operand" "=r")
6198 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6199 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6202 [(set_attr "type" "imul")])
6204 ;; V8plus wide multiply.
6206 (define_insn "muldi3_v8plus"
6207 [(set (match_operand:DI 0 "register_operand" "=r,h")
6208 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6209 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
6210 (clobber (match_scratch:SI 3 "=&h,X"))
6211 (clobber (match_scratch:SI 4 "=&h,X"))]
6215 if (sparc_check_64 (operands[1], insn) <= 0)
6216 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6217 if (which_alternative == 1)
6218 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6219 if (GET_CODE (operands[2]) == CONST_INT)
6221 if (which_alternative == 1)
6222 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6224 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\";
6226 if (sparc_check_64 (operands[2], insn) <= 0)
6227 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6228 if (which_alternative == 1)
6229 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\";
6231 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\";
6233 [(set_attr "type" "multi")
6234 (set_attr "length" "9,8")])
6236 (define_insn "*cmp_mul_set"
6238 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6239 (match_operand:SI 2 "arith_operand" "rI"))
6241 (set (match_operand:SI 0 "register_operand" "=r")
6242 (mult:SI (match_dup 1) (match_dup 2)))]
6243 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6244 "smulcc\\t%1, %2, %0"
6245 [(set_attr "type" "imul")])
6247 (define_expand "mulsidi3"
6248 [(set (match_operand:DI 0 "register_operand" "")
6249 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6250 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6254 if (CONSTANT_P (operands[2]))
6257 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6260 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6266 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6271 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6272 ;; registers can hold 64 bit values in the V8plus environment.
6274 (define_insn "mulsidi3_v8plus"
6275 [(set (match_operand:DI 0 "register_operand" "=h,r")
6276 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6277 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6278 (clobber (match_scratch:SI 3 "=X,&h"))]
6281 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6282 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6283 [(set_attr "type" "multi")
6284 (set_attr "length" "2,3")])
6287 (define_insn "const_mulsidi3_v8plus"
6288 [(set (match_operand:DI 0 "register_operand" "=h,r")
6289 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6290 (match_operand:SI 2 "small_int" "I,I")))
6291 (clobber (match_scratch:SI 3 "=X,&h"))]
6294 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6295 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6296 [(set_attr "type" "multi")
6297 (set_attr "length" "2,3")])
6300 (define_insn "*mulsidi3_sp32"
6301 [(set (match_operand:DI 0 "register_operand" "=r")
6302 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6303 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6307 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6310 (if_then_else (eq_attr "isa" "sparclet")
6311 (const_string "imul") (const_string "multi")))
6312 (set (attr "length")
6313 (if_then_else (eq_attr "isa" "sparclet")
6314 (const_int 1) (const_int 2)))])
6316 (define_insn "*mulsidi3_sp64"
6317 [(set (match_operand:DI 0 "register_operand" "=r")
6318 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6319 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6320 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6322 [(set_attr "type" "imul")])
6324 ;; Extra pattern, because sign_extend of a constant isn't valid.
6327 (define_insn "const_mulsidi3_sp32"
6328 [(set (match_operand:DI 0 "register_operand" "=r")
6329 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6330 (match_operand:SI 2 "small_int" "I")))]
6334 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6337 (if_then_else (eq_attr "isa" "sparclet")
6338 (const_string "imul") (const_string "multi")))
6339 (set (attr "length")
6340 (if_then_else (eq_attr "isa" "sparclet")
6341 (const_int 1) (const_int 2)))])
6343 (define_insn "const_mulsidi3_sp64"
6344 [(set (match_operand:DI 0 "register_operand" "=r")
6345 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6346 (match_operand:SI 2 "small_int" "I")))]
6347 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6349 [(set_attr "type" "imul")])
6351 (define_expand "smulsi3_highpart"
6352 [(set (match_operand:SI 0 "register_operand" "")
6354 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6355 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6357 "TARGET_HARD_MUL && TARGET_ARCH32"
6360 if (CONSTANT_P (operands[2]))
6364 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6370 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6375 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6376 operands[2], GEN_INT (32)));
6382 (define_insn "smulsi3_highpart_v8plus"
6383 [(set (match_operand:SI 0 "register_operand" "=h,r")
6385 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6386 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6387 (match_operand:SI 3 "const_int_operand" "i,i"))))
6388 (clobber (match_scratch:SI 4 "=X,&h"))]
6391 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6392 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6393 [(set_attr "type" "multi")
6394 (set_attr "length" "2")])
6396 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6399 [(set (match_operand:SI 0 "register_operand" "=h,r")
6402 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6403 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6404 (match_operand:SI 3 "const_int_operand" "i,i"))
6406 (clobber (match_scratch:SI 4 "=X,&h"))]
6409 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6410 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6411 [(set_attr "type" "multi")
6412 (set_attr "length" "2")])
6415 (define_insn "const_smulsi3_highpart_v8plus"
6416 [(set (match_operand:SI 0 "register_operand" "=h,r")
6418 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6419 (match_operand 2 "small_int" "i,i"))
6420 (match_operand:SI 3 "const_int_operand" "i,i"))))
6421 (clobber (match_scratch:SI 4 "=X,&h"))]
6424 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6425 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6426 [(set_attr "type" "multi")
6427 (set_attr "length" "2")])
6430 (define_insn "*smulsi3_highpart_sp32"
6431 [(set (match_operand:SI 0 "register_operand" "=r")
6433 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6434 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6437 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6438 [(set_attr "type" "multi")
6439 (set_attr "length" "2")])
6442 (define_insn "const_smulsi3_highpart"
6443 [(set (match_operand:SI 0 "register_operand" "=r")
6445 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6446 (match_operand:SI 2 "register_operand" "r"))
6449 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6450 [(set_attr "type" "multi")
6451 (set_attr "length" "2")])
6453 (define_expand "umulsidi3"
6454 [(set (match_operand:DI 0 "register_operand" "")
6455 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6456 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6460 if (CONSTANT_P (operands[2]))
6463 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6466 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6472 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6478 (define_insn "umulsidi3_v8plus"
6479 [(set (match_operand:DI 0 "register_operand" "=h,r")
6480 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6481 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6482 (clobber (match_scratch:SI 3 "=X,&h"))]
6485 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6486 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6487 [(set_attr "type" "multi")
6488 (set_attr "length" "2,3")])
6491 (define_insn "*umulsidi3_sp32"
6492 [(set (match_operand:DI 0 "register_operand" "=r")
6493 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6494 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6498 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6501 (if_then_else (eq_attr "isa" "sparclet")
6502 (const_string "imul") (const_string "multi")))
6503 (set (attr "length")
6504 (if_then_else (eq_attr "isa" "sparclet")
6505 (const_int 1) (const_int 2)))])
6507 (define_insn "*umulsidi3_sp64"
6508 [(set (match_operand:DI 0 "register_operand" "=r")
6509 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6510 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6511 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6513 [(set_attr "type" "imul")])
6515 ;; Extra pattern, because sign_extend of a constant isn't valid.
6518 (define_insn "const_umulsidi3_sp32"
6519 [(set (match_operand:DI 0 "register_operand" "=r")
6520 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6521 (match_operand:SI 2 "uns_small_int" "")))]
6525 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6528 (if_then_else (eq_attr "isa" "sparclet")
6529 (const_string "imul") (const_string "multi")))
6530 (set (attr "length")
6531 (if_then_else (eq_attr "isa" "sparclet")
6532 (const_int 1) (const_int 2)))])
6534 (define_insn "const_umulsidi3_sp64"
6535 [(set (match_operand:DI 0 "register_operand" "=r")
6536 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6537 (match_operand:SI 2 "uns_small_int" "")))]
6538 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6540 [(set_attr "type" "imul")])
6543 (define_insn "const_umulsidi3_v8plus"
6544 [(set (match_operand:DI 0 "register_operand" "=h,r")
6545 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6546 (match_operand:SI 2 "uns_small_int" "")))
6547 (clobber (match_scratch:SI 3 "=X,h"))]
6550 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6551 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6552 [(set_attr "type" "multi")
6553 (set_attr "length" "2,3")])
6555 (define_expand "umulsi3_highpart"
6556 [(set (match_operand:SI 0 "register_operand" "")
6558 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6559 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6561 "TARGET_HARD_MUL && TARGET_ARCH32"
6564 if (CONSTANT_P (operands[2]))
6568 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6574 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6579 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6580 operands[2], GEN_INT (32)));
6586 (define_insn "umulsi3_highpart_v8plus"
6587 [(set (match_operand:SI 0 "register_operand" "=h,r")
6589 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6590 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6591 (match_operand:SI 3 "const_int_operand" "i,i"))))
6592 (clobber (match_scratch:SI 4 "=X,h"))]
6595 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6596 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6597 [(set_attr "type" "multi")
6598 (set_attr "length" "2")])
6601 (define_insn "const_umulsi3_highpart_v8plus"
6602 [(set (match_operand:SI 0 "register_operand" "=h,r")
6604 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6605 (match_operand:SI 2 "uns_small_int" ""))
6606 (match_operand:SI 3 "const_int_operand" "i,i"))))
6607 (clobber (match_scratch:SI 4 "=X,h"))]
6610 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6611 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6612 [(set_attr "type" "multi")
6613 (set_attr "length" "2")])
6616 (define_insn "*umulsi3_highpart_sp32"
6617 [(set (match_operand:SI 0 "register_operand" "=r")
6619 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6620 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6623 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6624 [(set_attr "type" "multi")
6625 (set_attr "length" "2")])
6628 (define_insn "const_umulsi3_highpart"
6629 [(set (match_operand:SI 0 "register_operand" "=r")
6631 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6632 (match_operand:SI 2 "uns_small_int" ""))
6635 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6636 [(set_attr "type" "multi")
6637 (set_attr "length" "2")])
6639 ;; The v8 architecture specifies that there must be 3 instructions between
6640 ;; a y register write and a use of it for correct results.
6642 (define_expand "divsi3"
6643 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6644 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6645 (match_operand:SI 2 "input_operand" "rI,m")))
6646 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6647 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6652 operands[3] = gen_reg_rtx(SImode);
6653 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6654 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6660 (define_insn "divsi3_sp32"
6661 [(set (match_operand:SI 0 "register_operand" "=r,r")
6662 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6663 (match_operand:SI 2 "input_operand" "rI,m")))
6664 (clobber (match_scratch:SI 3 "=&r,&r"))]
6665 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6669 if (which_alternative == 0)
6671 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6673 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6676 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6678 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\";
6680 [(set_attr "type" "multi")
6681 (set (attr "length")
6682 (if_then_else (eq_attr "isa" "v9")
6683 (const_int 4) (const_int 6)))])
6685 (define_insn "divsi3_sp64"
6686 [(set (match_operand:SI 0 "register_operand" "=r")
6687 (div:SI (match_operand:SI 1 "register_operand" "r")
6688 (match_operand:SI 2 "input_operand" "rI")))
6689 (use (match_operand:SI 3 "register_operand" "r"))]
6690 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6691 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6692 [(set_attr "type" "multi")
6693 (set_attr "length" "2")])
6695 (define_insn "divdi3"
6696 [(set (match_operand:DI 0 "register_operand" "=r")
6697 (div:DI (match_operand:DI 1 "register_operand" "r")
6698 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6700 "sdivx\\t%1, %2, %0"
6701 [(set_attr "type" "idiv")])
6703 (define_insn "*cmp_sdiv_cc_set"
6705 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6706 (match_operand:SI 2 "arith_operand" "rI"))
6708 (set (match_operand:SI 0 "register_operand" "=r")
6709 (div:SI (match_dup 1) (match_dup 2)))
6710 (clobber (match_scratch:SI 3 "=&r"))]
6711 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6715 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6717 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6719 [(set_attr "type" "multi")
6720 (set (attr "length")
6721 (if_then_else (eq_attr "isa" "v9")
6722 (const_int 3) (const_int 6)))])
6725 (define_expand "udivsi3"
6726 [(set (match_operand:SI 0 "register_operand" "")
6727 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6728 (match_operand:SI 2 "input_operand" "")))]
6729 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6732 (define_insn "udivsi3_sp32"
6733 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6734 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6735 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6737 || TARGET_DEPRECATED_V8_INSNS)
6741 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6742 switch (which_alternative)
6745 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6747 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6749 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6752 [(set_attr "type" "multi")
6753 (set_attr "length" "5")])
6755 (define_insn "udivsi3_sp64"
6756 [(set (match_operand:SI 0 "register_operand" "=r")
6757 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6758 (match_operand:SI 2 "input_operand" "rI")))]
6759 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6760 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6761 [(set_attr "type" "multi")
6762 (set_attr "length" "2")])
6764 (define_insn "udivdi3"
6765 [(set (match_operand:DI 0 "register_operand" "=r")
6766 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6767 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6769 "udivx\\t%1, %2, %0"
6770 [(set_attr "type" "idiv")])
6772 (define_insn "*cmp_udiv_cc_set"
6774 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6775 (match_operand:SI 2 "arith_operand" "rI"))
6777 (set (match_operand:SI 0 "register_operand" "=r")
6778 (udiv:SI (match_dup 1) (match_dup 2)))]
6780 || TARGET_DEPRECATED_V8_INSNS"
6784 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6786 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6788 [(set_attr "type" "multi")
6789 (set (attr "length")
6790 (if_then_else (eq_attr "isa" "v9")
6791 (const_int 2) (const_int 5)))])
6793 ; sparclet multiply/accumulate insns
6795 (define_insn "*smacsi"
6796 [(set (match_operand:SI 0 "register_operand" "=r")
6797 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6798 (match_operand:SI 2 "arith_operand" "rI"))
6799 (match_operand:SI 3 "register_operand" "0")))]
6802 [(set_attr "type" "imul")])
6804 (define_insn "*smacdi"
6805 [(set (match_operand:DI 0 "register_operand" "=r")
6806 (plus:DI (mult:DI (sign_extend:DI
6807 (match_operand:SI 1 "register_operand" "%r"))
6809 (match_operand:SI 2 "register_operand" "r")))
6810 (match_operand:DI 3 "register_operand" "0")))]
6812 "smacd\\t%1, %2, %L0"
6813 [(set_attr "type" "imul")])
6815 (define_insn "*umacdi"
6816 [(set (match_operand:DI 0 "register_operand" "=r")
6817 (plus:DI (mult:DI (zero_extend:DI
6818 (match_operand:SI 1 "register_operand" "%r"))
6820 (match_operand:SI 2 "register_operand" "r")))
6821 (match_operand:DI 3 "register_operand" "0")))]
6823 "umacd\\t%1, %2, %L0"
6824 [(set_attr "type" "imul")])
6826 ;;- Boolean instructions
6827 ;; We define DImode `and' so with DImode `not' we can get
6828 ;; DImode `andn'. Other combinations are possible.
6830 (define_expand "anddi3"
6831 [(set (match_operand:DI 0 "register_operand" "")
6832 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6833 (match_operand:DI 2 "arith_double_operand" "")))]
6837 (define_insn "*anddi3_sp32"
6838 [(set (match_operand:DI 0 "register_operand" "=r,b")
6839 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6840 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6845 [(set_attr "type" "*,fp")
6846 (set_attr "length" "2,*")
6847 (set_attr "fptype" "double")])
6849 (define_insn "*anddi3_sp64"
6850 [(set (match_operand:DI 0 "register_operand" "=r,b")
6851 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6852 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6857 [(set_attr "type" "*,fp")
6858 (set_attr "fptype" "double")])
6860 (define_insn "andsi3"
6861 [(set (match_operand:SI 0 "register_operand" "=r,d")
6862 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6863 (match_operand:SI 2 "arith_operand" "rI,d")))]
6868 [(set_attr "type" "*,fp")])
6871 [(set (match_operand:SI 0 "register_operand" "")
6872 (and:SI (match_operand:SI 1 "register_operand" "")
6873 (match_operand:SI 2 "" "")))
6874 (clobber (match_operand:SI 3 "register_operand" ""))]
6875 "GET_CODE (operands[2]) == CONST_INT
6876 && !SMALL_INT32 (operands[2])
6877 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6878 [(set (match_dup 3) (match_dup 4))
6879 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6882 operands[4] = GEN_INT (~INTVAL (operands[2]));
6885 ;; Split DImode logical operations requiring two instructions.
6887 [(set (match_operand:DI 0 "register_operand" "")
6888 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6889 [(match_operand:DI 2 "register_operand" "")
6890 (match_operand:DI 3 "arith_double_operand" "")]))]
6893 && ((GET_CODE (operands[0]) == REG
6894 && REGNO (operands[0]) < 32)
6895 || (GET_CODE (operands[0]) == SUBREG
6896 && GET_CODE (SUBREG_REG (operands[0])) == REG
6897 && REGNO (SUBREG_REG (operands[0])) < 32))"
6898 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6899 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6902 operands[4] = gen_highpart (SImode, operands[0]);
6903 operands[5] = gen_lowpart (SImode, operands[0]);
6904 operands[6] = gen_highpart (SImode, operands[2]);
6905 operands[7] = gen_lowpart (SImode, operands[2]);
6906 #if HOST_BITS_PER_WIDE_INT == 32
6907 if (GET_CODE (operands[3]) == CONST_INT)
6909 if (INTVAL (operands[3]) < 0)
6910 operands[8] = constm1_rtx;
6912 operands[8] = const0_rtx;
6916 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6917 operands[9] = gen_lowpart (SImode, operands[3]);
6920 (define_insn "*and_not_di_sp32"
6921 [(set (match_operand:DI 0 "register_operand" "=r,b")
6922 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6923 (match_operand:DI 2 "register_operand" "r,b")))]
6927 fandnot1\\t%1, %2, %0"
6928 [(set_attr "type" "*,fp")
6929 (set_attr "length" "2,*")
6930 (set_attr "fptype" "double")])
6933 [(set (match_operand:DI 0 "register_operand" "")
6934 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6935 (match_operand:DI 2 "register_operand" "")))]
6938 && ((GET_CODE (operands[0]) == REG
6939 && REGNO (operands[0]) < 32)
6940 || (GET_CODE (operands[0]) == SUBREG
6941 && GET_CODE (SUBREG_REG (operands[0])) == REG
6942 && REGNO (SUBREG_REG (operands[0])) < 32))"
6943 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6944 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6945 "operands[3] = gen_highpart (SImode, operands[0]);
6946 operands[4] = gen_highpart (SImode, operands[1]);
6947 operands[5] = gen_highpart (SImode, operands[2]);
6948 operands[6] = gen_lowpart (SImode, operands[0]);
6949 operands[7] = gen_lowpart (SImode, operands[1]);
6950 operands[8] = gen_lowpart (SImode, operands[2]);")
6952 (define_insn "*and_not_di_sp64"
6953 [(set (match_operand:DI 0 "register_operand" "=r,b")
6954 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6955 (match_operand:DI 2 "register_operand" "r,b")))]
6959 fandnot1\\t%1, %2, %0"
6960 [(set_attr "type" "*,fp")
6961 (set_attr "fptype" "double")])
6963 (define_insn "*and_not_si"
6964 [(set (match_operand:SI 0 "register_operand" "=r,d")
6965 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6966 (match_operand:SI 2 "register_operand" "r,d")))]
6970 fandnot1s\\t%1, %2, %0"
6971 [(set_attr "type" "*,fp")])
6973 (define_expand "iordi3"
6974 [(set (match_operand:DI 0 "register_operand" "")
6975 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6976 (match_operand:DI 2 "arith_double_operand" "")))]
6980 (define_insn "*iordi3_sp32"
6981 [(set (match_operand:DI 0 "register_operand" "=r,b")
6982 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6983 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6988 [(set_attr "type" "*,fp")
6989 (set_attr "length" "2,*")
6990 (set_attr "fptype" "double")])
6992 (define_insn "*iordi3_sp64"
6993 [(set (match_operand:DI 0 "register_operand" "=r,b")
6994 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6995 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
7000 [(set_attr "type" "*,fp")
7001 (set_attr "fptype" "double")])
7003 (define_insn "iorsi3"
7004 [(set (match_operand:SI 0 "register_operand" "=r,d")
7005 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
7006 (match_operand:SI 2 "arith_operand" "rI,d")))]
7011 [(set_attr "type" "*,fp")])
7014 [(set (match_operand:SI 0 "register_operand" "")
7015 (ior:SI (match_operand:SI 1 "register_operand" "")
7016 (match_operand:SI 2 "" "")))
7017 (clobber (match_operand:SI 3 "register_operand" ""))]
7018 "GET_CODE (operands[2]) == CONST_INT
7019 && !SMALL_INT32 (operands[2])
7020 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7021 [(set (match_dup 3) (match_dup 4))
7022 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
7025 operands[4] = GEN_INT (~INTVAL (operands[2]));
7028 (define_insn "*or_not_di_sp32"
7029 [(set (match_operand:DI 0 "register_operand" "=r,b")
7030 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
7031 (match_operand:DI 2 "register_operand" "r,b")))]
7035 fornot1\\t%1, %2, %0"
7036 [(set_attr "type" "*,fp")
7037 (set_attr "length" "2,*")
7038 (set_attr "fptype" "double")])
7041 [(set (match_operand:DI 0 "register_operand" "")
7042 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
7043 (match_operand:DI 2 "register_operand" "")))]
7046 && ((GET_CODE (operands[0]) == REG
7047 && REGNO (operands[0]) < 32)
7048 || (GET_CODE (operands[0]) == SUBREG
7049 && GET_CODE (SUBREG_REG (operands[0])) == REG
7050 && REGNO (SUBREG_REG (operands[0])) < 32))"
7051 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
7052 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
7053 "operands[3] = gen_highpart (SImode, operands[0]);
7054 operands[4] = gen_highpart (SImode, operands[1]);
7055 operands[5] = gen_highpart (SImode, operands[2]);
7056 operands[6] = gen_lowpart (SImode, operands[0]);
7057 operands[7] = gen_lowpart (SImode, operands[1]);
7058 operands[8] = gen_lowpart (SImode, operands[2]);")
7060 (define_insn "*or_not_di_sp64"
7061 [(set (match_operand:DI 0 "register_operand" "=r,b")
7062 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
7063 (match_operand:DI 2 "register_operand" "r,b")))]
7067 fornot1\\t%1, %2, %0"
7068 [(set_attr "type" "*,fp")
7069 (set_attr "fptype" "double")])
7071 (define_insn "*or_not_si"
7072 [(set (match_operand:SI 0 "register_operand" "=r,d")
7073 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
7074 (match_operand:SI 2 "register_operand" "r,d")))]
7078 fornot1s\\t%1, %2, %0"
7079 [(set_attr "type" "*,fp")])
7081 (define_expand "xordi3"
7082 [(set (match_operand:DI 0 "register_operand" "")
7083 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
7084 (match_operand:DI 2 "arith_double_operand" "")))]
7088 (define_insn "*xordi3_sp32"
7089 [(set (match_operand:DI 0 "register_operand" "=r,b")
7090 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
7091 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
7096 [(set_attr "type" "*,fp")
7097 (set_attr "length" "2,*")
7098 (set_attr "fptype" "double")])
7100 (define_insn "*xordi3_sp64"
7101 [(set (match_operand:DI 0 "register_operand" "=r,b")
7102 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
7103 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
7108 [(set_attr "type" "*,fp")
7109 (set_attr "fptype" "double")])
7111 (define_insn "*xordi3_sp64_dbl"
7112 [(set (match_operand:DI 0 "register_operand" "=r")
7113 (xor:DI (match_operand:DI 1 "register_operand" "r")
7114 (match_operand:DI 2 "const64_operand" "")))]
7116 && HOST_BITS_PER_WIDE_INT != 64)"
7119 (define_insn "xorsi3"
7120 [(set (match_operand:SI 0 "register_operand" "=r,d")
7121 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
7122 (match_operand:SI 2 "arith_operand" "rI,d")))]
7127 [(set_attr "type" "*,fp")])
7130 [(set (match_operand:SI 0 "register_operand" "")
7131 (xor:SI (match_operand:SI 1 "register_operand" "")
7132 (match_operand:SI 2 "" "")))
7133 (clobber (match_operand:SI 3 "register_operand" ""))]
7134 "GET_CODE (operands[2]) == CONST_INT
7135 && !SMALL_INT32 (operands[2])
7136 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7137 [(set (match_dup 3) (match_dup 4))
7138 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
7141 operands[4] = GEN_INT (~INTVAL (operands[2]));
7145 [(set (match_operand:SI 0 "register_operand" "")
7146 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
7147 (match_operand:SI 2 "" ""))))
7148 (clobber (match_operand:SI 3 "register_operand" ""))]
7149 "GET_CODE (operands[2]) == CONST_INT
7150 && !SMALL_INT32 (operands[2])
7151 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7152 [(set (match_dup 3) (match_dup 4))
7153 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
7156 operands[4] = GEN_INT (~INTVAL (operands[2]));
7159 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
7160 ;; Combine now canonicalizes to the rightmost expression.
7161 (define_insn "*xor_not_di_sp32"
7162 [(set (match_operand:DI 0 "register_operand" "=r,b")
7163 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
7164 (match_operand:DI 2 "register_operand" "r,b"))))]
7169 [(set_attr "type" "*,fp")
7170 (set_attr "length" "2,*")
7171 (set_attr "fptype" "double")])
7174 [(set (match_operand:DI 0 "register_operand" "")
7175 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
7176 (match_operand:DI 2 "register_operand" ""))))]
7179 && ((GET_CODE (operands[0]) == REG
7180 && REGNO (operands[0]) < 32)
7181 || (GET_CODE (operands[0]) == SUBREG
7182 && GET_CODE (SUBREG_REG (operands[0])) == REG
7183 && REGNO (SUBREG_REG (operands[0])) < 32))"
7184 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
7185 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
7186 "operands[3] = gen_highpart (SImode, operands[0]);
7187 operands[4] = gen_highpart (SImode, operands[1]);
7188 operands[5] = gen_highpart (SImode, operands[2]);
7189 operands[6] = gen_lowpart (SImode, operands[0]);
7190 operands[7] = gen_lowpart (SImode, operands[1]);
7191 operands[8] = gen_lowpart (SImode, operands[2]);")
7193 (define_insn "*xor_not_di_sp64"
7194 [(set (match_operand:DI 0 "register_operand" "=r,b")
7195 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
7196 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
7201 [(set_attr "type" "*,fp")
7202 (set_attr "fptype" "double")])
7204 (define_insn "*xor_not_si"
7205 [(set (match_operand:SI 0 "register_operand" "=r,d")
7206 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7207 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7211 fxnors\\t%1, %2, %0"
7212 [(set_attr "type" "*,fp")])
7214 ;; These correspond to the above in the case where we also (or only)
7215 ;; want to set the condition code.
7217 (define_insn "*cmp_cc_arith_op"
7220 (match_operator:SI 2 "cc_arithop"
7221 [(match_operand:SI 0 "arith_operand" "%r")
7222 (match_operand:SI 1 "arith_operand" "rI")])
7225 "%A2cc\\t%0, %1, %%g0"
7226 [(set_attr "type" "compare")])
7228 (define_insn "*cmp_ccx_arith_op"
7231 (match_operator:DI 2 "cc_arithop"
7232 [(match_operand:DI 0 "arith_double_operand" "%r")
7233 (match_operand:DI 1 "arith_double_operand" "rHI")])
7236 "%A2cc\\t%0, %1, %%g0"
7237 [(set_attr "type" "compare")])
7239 (define_insn "*cmp_cc_arith_op_set"
7242 (match_operator:SI 3 "cc_arithop"
7243 [(match_operand:SI 1 "arith_operand" "%r")
7244 (match_operand:SI 2 "arith_operand" "rI")])
7246 (set (match_operand:SI 0 "register_operand" "=r")
7247 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7248 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7249 "%A3cc\\t%1, %2, %0"
7250 [(set_attr "type" "compare")])
7252 (define_insn "*cmp_ccx_arith_op_set"
7255 (match_operator:DI 3 "cc_arithop"
7256 [(match_operand:DI 1 "arith_double_operand" "%r")
7257 (match_operand:DI 2 "arith_double_operand" "rHI")])
7259 (set (match_operand:DI 0 "register_operand" "=r")
7260 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7261 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7262 "%A3cc\\t%1, %2, %0"
7263 [(set_attr "type" "compare")])
7265 (define_insn "*cmp_cc_xor_not"
7268 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7269 (match_operand:SI 1 "arith_operand" "rI")))
7272 "xnorcc\\t%r0, %1, %%g0"
7273 [(set_attr "type" "compare")])
7275 (define_insn "*cmp_ccx_xor_not"
7278 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7279 (match_operand:DI 1 "arith_double_operand" "rHI")))
7282 "xnorcc\\t%r0, %1, %%g0"
7283 [(set_attr "type" "compare")])
7285 (define_insn "*cmp_cc_xor_not_set"
7288 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7289 (match_operand:SI 2 "arith_operand" "rI")))
7291 (set (match_operand:SI 0 "register_operand" "=r")
7292 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7294 "xnorcc\\t%r1, %2, %0"
7295 [(set_attr "type" "compare")])
7297 (define_insn "*cmp_ccx_xor_not_set"
7300 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7301 (match_operand:DI 2 "arith_double_operand" "rHI")))
7303 (set (match_operand:DI 0 "register_operand" "=r")
7304 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7306 "xnorcc\\t%r1, %2, %0"
7307 [(set_attr "type" "compare")])
7309 (define_insn "*cmp_cc_arith_op_not"
7312 (match_operator:SI 2 "cc_arithopn"
7313 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7314 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7317 "%B2cc\\t%r1, %0, %%g0"
7318 [(set_attr "type" "compare")])
7320 (define_insn "*cmp_ccx_arith_op_not"
7323 (match_operator:DI 2 "cc_arithopn"
7324 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7325 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7328 "%B2cc\\t%r1, %0, %%g0"
7329 [(set_attr "type" "compare")])
7331 (define_insn "*cmp_cc_arith_op_not_set"
7334 (match_operator:SI 3 "cc_arithopn"
7335 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7336 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7338 (set (match_operand:SI 0 "register_operand" "=r")
7339 (match_operator:SI 4 "cc_arithopn"
7340 [(not:SI (match_dup 1)) (match_dup 2)]))]
7341 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7342 "%B3cc\\t%r2, %1, %0"
7343 [(set_attr "type" "compare")])
7345 (define_insn "*cmp_ccx_arith_op_not_set"
7348 (match_operator:DI 3 "cc_arithopn"
7349 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7350 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7352 (set (match_operand:DI 0 "register_operand" "=r")
7353 (match_operator:DI 4 "cc_arithopn"
7354 [(not:DI (match_dup 1)) (match_dup 2)]))]
7355 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7356 "%B3cc\\t%r2, %1, %0"
7357 [(set_attr "type" "compare")])
7359 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7360 ;; does not know how to make it work for constants.
7362 (define_expand "negdi2"
7363 [(set (match_operand:DI 0 "register_operand" "=r")
7364 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7368 if (! TARGET_ARCH64)
7370 emit_insn (gen_rtx_PARALLEL
7373 gen_rtx_SET (VOIDmode, operand0,
7374 gen_rtx_NEG (DImode, operand1)),
7375 gen_rtx_CLOBBER (VOIDmode,
7376 gen_rtx_REG (CCmode,
7382 (define_insn "*negdi2_sp32"
7383 [(set (match_operand:DI 0 "register_operand" "=r")
7384 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7385 (clobber (reg:CC 100))]
7388 [(set_attr "length" "2")])
7391 [(set (match_operand:DI 0 "register_operand" "")
7392 (neg:DI (match_operand:DI 1 "register_operand" "")))
7393 (clobber (reg:CC 100))]
7395 && reload_completed"
7396 [(parallel [(set (reg:CC_NOOV 100)
7397 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7399 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7400 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7401 (ltu:SI (reg:CC 100) (const_int 0))))]
7402 "operands[2] = gen_highpart (SImode, operands[0]);
7403 operands[3] = gen_highpart (SImode, operands[1]);
7404 operands[4] = gen_lowpart (SImode, operands[0]);
7405 operands[5] = gen_lowpart (SImode, operands[1]);")
7407 (define_insn "*negdi2_sp64"
7408 [(set (match_operand:DI 0 "register_operand" "=r")
7409 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7411 "sub\\t%%g0, %1, %0")
7413 (define_insn "negsi2"
7414 [(set (match_operand:SI 0 "register_operand" "=r")
7415 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7417 "sub\\t%%g0, %1, %0")
7419 (define_insn "*cmp_cc_neg"
7420 [(set (reg:CC_NOOV 100)
7421 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7424 "subcc\\t%%g0, %0, %%g0"
7425 [(set_attr "type" "compare")])
7427 (define_insn "*cmp_ccx_neg"
7428 [(set (reg:CCX_NOOV 100)
7429 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7432 "subcc\\t%%g0, %0, %%g0"
7433 [(set_attr "type" "compare")])
7435 (define_insn "*cmp_cc_set_neg"
7436 [(set (reg:CC_NOOV 100)
7437 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7439 (set (match_operand:SI 0 "register_operand" "=r")
7440 (neg:SI (match_dup 1)))]
7442 "subcc\\t%%g0, %1, %0"
7443 [(set_attr "type" "compare")])
7445 (define_insn "*cmp_ccx_set_neg"
7446 [(set (reg:CCX_NOOV 100)
7447 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7449 (set (match_operand:DI 0 "register_operand" "=r")
7450 (neg:DI (match_dup 1)))]
7452 "subcc\\t%%g0, %1, %0"
7453 [(set_attr "type" "compare")])
7455 ;; We cannot use the "not" pseudo insn because the Sun assembler
7456 ;; does not know how to make it work for constants.
7457 (define_expand "one_cmpldi2"
7458 [(set (match_operand:DI 0 "register_operand" "")
7459 (not:DI (match_operand:DI 1 "register_operand" "")))]
7463 (define_insn "*one_cmpldi2_sp32"
7464 [(set (match_operand:DI 0 "register_operand" "=r,b")
7465 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7470 [(set_attr "type" "*,fp")
7471 (set_attr "length" "2,*")
7472 (set_attr "fptype" "double")])
7475 [(set (match_operand:DI 0 "register_operand" "")
7476 (not:DI (match_operand:DI 1 "register_operand" "")))]
7479 && ((GET_CODE (operands[0]) == REG
7480 && REGNO (operands[0]) < 32)
7481 || (GET_CODE (operands[0]) == SUBREG
7482 && GET_CODE (SUBREG_REG (operands[0])) == REG
7483 && REGNO (SUBREG_REG (operands[0])) < 32))"
7484 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7485 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7486 "operands[2] = gen_highpart (SImode, operands[0]);
7487 operands[3] = gen_highpart (SImode, operands[1]);
7488 operands[4] = gen_lowpart (SImode, operands[0]);
7489 operands[5] = gen_lowpart (SImode, operands[1]);")
7491 (define_insn "*one_cmpldi2_sp64"
7492 [(set (match_operand:DI 0 "register_operand" "=r,b")
7493 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7498 [(set_attr "type" "*,fp")
7499 (set_attr "fptype" "double")])
7501 (define_insn "one_cmplsi2"
7502 [(set (match_operand:SI 0 "register_operand" "=r,d")
7503 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7508 [(set_attr "type" "*,fp")])
7510 (define_insn "*cmp_cc_not"
7512 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7515 "xnorcc\\t%%g0, %0, %%g0"
7516 [(set_attr "type" "compare")])
7518 (define_insn "*cmp_ccx_not"
7520 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7523 "xnorcc\\t%%g0, %0, %%g0"
7524 [(set_attr "type" "compare")])
7526 (define_insn "*cmp_cc_set_not"
7528 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7530 (set (match_operand:SI 0 "register_operand" "=r")
7531 (not:SI (match_dup 1)))]
7533 "xnorcc\\t%%g0, %1, %0"
7534 [(set_attr "type" "compare")])
7536 (define_insn "*cmp_ccx_set_not"
7538 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7540 (set (match_operand:DI 0 "register_operand" "=r")
7541 (not:DI (match_dup 1)))]
7543 "xnorcc\\t%%g0, %1, %0"
7544 [(set_attr "type" "compare")])
7546 (define_insn "*cmp_cc_set"
7547 [(set (match_operand:SI 0 "register_operand" "=r")
7548 (match_operand:SI 1 "register_operand" "r"))
7550 (compare:CC (match_dup 1)
7554 [(set_attr "type" "compare")])
7556 (define_insn "*cmp_ccx_set64"
7557 [(set (match_operand:DI 0 "register_operand" "=r")
7558 (match_operand:DI 1 "register_operand" "r"))
7560 (compare:CCX (match_dup 1)
7564 [(set_attr "type" "compare")])
7566 ;; Floating point arithmetic instructions.
7568 (define_expand "addtf3"
7569 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7570 (plus:TF (match_operand:TF 1 "general_operand" "")
7571 (match_operand:TF 2 "general_operand" "")))]
7572 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7575 if (! TARGET_HARD_QUAD)
7577 rtx slot0, slot1, slot2;
7579 if (GET_CODE (operands[0]) != MEM)
7580 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7582 slot0 = operands[0];
7583 if (GET_CODE (operands[1]) != MEM)
7585 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7586 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7589 slot1 = operands[1];
7590 if (GET_CODE (operands[2]) != MEM)
7592 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7593 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7596 slot2 = operands[2];
7598 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7600 XEXP (slot0, 0), Pmode,
7601 XEXP (slot1, 0), Pmode,
7602 XEXP (slot2, 0), Pmode);
7604 if (GET_CODE (operands[0]) != MEM)
7605 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7610 (define_insn "*addtf3_hq"
7611 [(set (match_operand:TF 0 "register_operand" "=e")
7612 (plus:TF (match_operand:TF 1 "register_operand" "e")
7613 (match_operand:TF 2 "register_operand" "e")))]
7614 "TARGET_FPU && TARGET_HARD_QUAD"
7615 "faddq\\t%1, %2, %0"
7616 [(set_attr "type" "fp")])
7618 (define_insn "adddf3"
7619 [(set (match_operand:DF 0 "register_operand" "=e")
7620 (plus:DF (match_operand:DF 1 "register_operand" "e")
7621 (match_operand:DF 2 "register_operand" "e")))]
7623 "faddd\\t%1, %2, %0"
7624 [(set_attr "type" "fp")
7625 (set_attr "fptype" "double")])
7627 (define_insn "addsf3"
7628 [(set (match_operand:SF 0 "register_operand" "=f")
7629 (plus:SF (match_operand:SF 1 "register_operand" "f")
7630 (match_operand:SF 2 "register_operand" "f")))]
7632 "fadds\\t%1, %2, %0"
7633 [(set_attr "type" "fp")])
7635 (define_expand "subtf3"
7636 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7637 (minus:TF (match_operand:TF 1 "general_operand" "")
7638 (match_operand:TF 2 "general_operand" "")))]
7639 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7642 if (! TARGET_HARD_QUAD)
7644 rtx slot0, slot1, slot2;
7646 if (GET_CODE (operands[0]) != MEM)
7647 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7649 slot0 = operands[0];
7650 if (GET_CODE (operands[1]) != MEM)
7652 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7653 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7656 slot1 = operands[1];
7657 if (GET_CODE (operands[2]) != MEM)
7659 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7660 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7663 slot2 = operands[2];
7665 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7667 XEXP (slot0, 0), Pmode,
7668 XEXP (slot1, 0), Pmode,
7669 XEXP (slot2, 0), Pmode);
7671 if (GET_CODE (operands[0]) != MEM)
7672 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7677 (define_insn "*subtf3_hq"
7678 [(set (match_operand:TF 0 "register_operand" "=e")
7679 (minus:TF (match_operand:TF 1 "register_operand" "e")
7680 (match_operand:TF 2 "register_operand" "e")))]
7681 "TARGET_FPU && TARGET_HARD_QUAD"
7682 "fsubq\\t%1, %2, %0"
7683 [(set_attr "type" "fp")])
7685 (define_insn "subdf3"
7686 [(set (match_operand:DF 0 "register_operand" "=e")
7687 (minus:DF (match_operand:DF 1 "register_operand" "e")
7688 (match_operand:DF 2 "register_operand" "e")))]
7690 "fsubd\\t%1, %2, %0"
7691 [(set_attr "type" "fp")
7692 (set_attr "fptype" "double")])
7694 (define_insn "subsf3"
7695 [(set (match_operand:SF 0 "register_operand" "=f")
7696 (minus:SF (match_operand:SF 1 "register_operand" "f")
7697 (match_operand:SF 2 "register_operand" "f")))]
7699 "fsubs\\t%1, %2, %0"
7700 [(set_attr "type" "fp")])
7702 (define_expand "multf3"
7703 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7704 (mult:TF (match_operand:TF 1 "general_operand" "")
7705 (match_operand:TF 2 "general_operand" "")))]
7706 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7709 if (! TARGET_HARD_QUAD)
7711 rtx slot0, slot1, slot2;
7713 if (GET_CODE (operands[0]) != MEM)
7714 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7716 slot0 = operands[0];
7717 if (GET_CODE (operands[1]) != MEM)
7719 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7720 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7723 slot1 = operands[1];
7724 if (GET_CODE (operands[2]) != MEM)
7726 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7727 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7730 slot2 = operands[2];
7732 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7734 XEXP (slot0, 0), Pmode,
7735 XEXP (slot1, 0), Pmode,
7736 XEXP (slot2, 0), Pmode);
7738 if (GET_CODE (operands[0]) != MEM)
7739 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7744 (define_insn "*multf3_hq"
7745 [(set (match_operand:TF 0 "register_operand" "=e")
7746 (mult:TF (match_operand:TF 1 "register_operand" "e")
7747 (match_operand:TF 2 "register_operand" "e")))]
7748 "TARGET_FPU && TARGET_HARD_QUAD"
7749 "fmulq\\t%1, %2, %0"
7750 [(set_attr "type" "fpmul")])
7752 (define_insn "muldf3"
7753 [(set (match_operand:DF 0 "register_operand" "=e")
7754 (mult:DF (match_operand:DF 1 "register_operand" "e")
7755 (match_operand:DF 2 "register_operand" "e")))]
7757 "fmuld\\t%1, %2, %0"
7758 [(set_attr "type" "fpmul")
7759 (set_attr "fptype" "double")])
7761 (define_insn "mulsf3"
7762 [(set (match_operand:SF 0 "register_operand" "=f")
7763 (mult:SF (match_operand:SF 1 "register_operand" "f")
7764 (match_operand:SF 2 "register_operand" "f")))]
7766 "fmuls\\t%1, %2, %0"
7767 [(set_attr "type" "fpmul")])
7769 (define_insn "*muldf3_extend"
7770 [(set (match_operand:DF 0 "register_operand" "=e")
7771 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7772 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7773 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7774 "fsmuld\\t%1, %2, %0"
7775 [(set_attr "type" "fpmul")
7776 (set_attr "fptype" "double")])
7778 (define_insn "*multf3_extend"
7779 [(set (match_operand:TF 0 "register_operand" "=e")
7780 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7781 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7782 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7783 "fdmulq\\t%1, %2, %0"
7784 [(set_attr "type" "fpmul")])
7786 (define_expand "divtf3"
7787 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7788 (div:TF (match_operand:TF 1 "general_operand" "")
7789 (match_operand:TF 2 "general_operand" "")))]
7790 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7793 if (! TARGET_HARD_QUAD)
7795 rtx slot0, slot1, slot2;
7797 if (GET_CODE (operands[0]) != MEM)
7798 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7800 slot0 = operands[0];
7801 if (GET_CODE (operands[1]) != MEM)
7803 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7804 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7807 slot1 = operands[1];
7808 if (GET_CODE (operands[2]) != MEM)
7810 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7811 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7814 slot2 = operands[2];
7816 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7818 XEXP (slot0, 0), Pmode,
7819 XEXP (slot1, 0), Pmode,
7820 XEXP (slot2, 0), Pmode);
7822 if (GET_CODE (operands[0]) != MEM)
7823 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7828 ;; don't have timing for quad-prec. divide.
7829 (define_insn "*divtf3_hq"
7830 [(set (match_operand:TF 0 "register_operand" "=e")
7831 (div:TF (match_operand:TF 1 "register_operand" "e")
7832 (match_operand:TF 2 "register_operand" "e")))]
7833 "TARGET_FPU && TARGET_HARD_QUAD"
7834 "fdivq\\t%1, %2, %0"
7835 [(set_attr "type" "fpdivd")])
7837 (define_insn "divdf3"
7838 [(set (match_operand:DF 0 "register_operand" "=e")
7839 (div:DF (match_operand:DF 1 "register_operand" "e")
7840 (match_operand:DF 2 "register_operand" "e")))]
7842 "fdivd\\t%1, %2, %0"
7843 [(set_attr "type" "fpdivd")
7844 (set_attr "fptype" "double")])
7846 (define_insn "divsf3"
7847 [(set (match_operand:SF 0 "register_operand" "=f")
7848 (div:SF (match_operand:SF 1 "register_operand" "f")
7849 (match_operand:SF 2 "register_operand" "f")))]
7851 "fdivs\\t%1, %2, %0"
7852 [(set_attr "type" "fpdivs")])
7854 (define_expand "negtf2"
7855 [(set (match_operand:TF 0 "register_operand" "=e,e")
7856 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7860 (define_insn "*negtf2_notv9"
7861 [(set (match_operand:TF 0 "register_operand" "=e,e")
7862 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7863 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7869 [(set_attr "type" "fpmove,*")
7870 (set_attr "length" "*,2")])
7873 [(set (match_operand:TF 0 "register_operand" "")
7874 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7878 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7879 [(set (match_dup 2) (neg:SF (match_dup 3)))
7880 (set (match_dup 4) (match_dup 5))
7881 (set (match_dup 6) (match_dup 7))]
7882 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7883 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7884 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7885 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7886 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7887 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7889 (define_insn "*negtf2_v9"
7890 [(set (match_operand:TF 0 "register_operand" "=e,e")
7891 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7892 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7893 "TARGET_FPU && TARGET_V9"
7897 [(set_attr "type" "fpmove,*")
7898 (set_attr "length" "*,2")
7899 (set_attr "fptype" "double")])
7902 [(set (match_operand:TF 0 "register_operand" "")
7903 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7907 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7908 [(set (match_dup 2) (neg:DF (match_dup 3)))
7909 (set (match_dup 4) (match_dup 5))]
7910 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7911 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7912 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7913 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7915 (define_expand "negdf2"
7916 [(set (match_operand:DF 0 "register_operand" "")
7917 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7921 (define_insn "*negdf2_notv9"
7922 [(set (match_operand:DF 0 "register_operand" "=e,e")
7923 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7924 "TARGET_FPU && ! TARGET_V9"
7928 [(set_attr "type" "fpmove,*")
7929 (set_attr "length" "*,2")])
7932 [(set (match_operand:DF 0 "register_operand" "")
7933 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7937 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7938 [(set (match_dup 2) (neg:SF (match_dup 3)))
7939 (set (match_dup 4) (match_dup 5))]
7940 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7941 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7942 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7943 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7945 (define_insn "*negdf2_v9"
7946 [(set (match_operand:DF 0 "register_operand" "=e")
7947 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7948 "TARGET_FPU && TARGET_V9"
7950 [(set_attr "type" "fpmove")
7951 (set_attr "fptype" "double")])
7953 (define_insn "negsf2"
7954 [(set (match_operand:SF 0 "register_operand" "=f")
7955 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7958 [(set_attr "type" "fpmove")])
7960 (define_expand "abstf2"
7961 [(set (match_operand:TF 0 "register_operand" "")
7962 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7966 (define_insn "*abstf2_notv9"
7967 [(set (match_operand:TF 0 "register_operand" "=e,e")
7968 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7969 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7970 "TARGET_FPU && ! TARGET_V9"
7974 [(set_attr "type" "fpmove,*")
7975 (set_attr "length" "*,2")])
7978 [(set (match_operand:TF 0 "register_operand" "")
7979 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7983 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7984 [(set (match_dup 2) (abs:SF (match_dup 3)))
7985 (set (match_dup 4) (match_dup 5))
7986 (set (match_dup 6) (match_dup 7))]
7987 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7988 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7989 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7990 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7991 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7992 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7994 (define_insn "*abstf2_hq_v9"
7995 [(set (match_operand:TF 0 "register_operand" "=e,e")
7996 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7997 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
8001 [(set_attr "type" "fpmove")
8002 (set_attr "fptype" "double,*")])
8004 (define_insn "*abstf2_v9"
8005 [(set (match_operand:TF 0 "register_operand" "=e,e")
8006 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
8007 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
8011 [(set_attr "type" "fpmove,*")
8012 (set_attr "length" "*,2")
8013 (set_attr "fptype" "double,*")])
8016 [(set (match_operand:TF 0 "register_operand" "")
8017 (abs:TF (match_operand:TF 1 "register_operand" "")))]
8021 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
8022 [(set (match_dup 2) (abs:DF (match_dup 3)))
8023 (set (match_dup 4) (match_dup 5))]
8024 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
8025 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
8026 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
8027 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
8029 (define_expand "absdf2"
8030 [(set (match_operand:DF 0 "register_operand" "")
8031 (abs:DF (match_operand:DF 1 "register_operand" "")))]
8035 (define_insn "*absdf2_notv9"
8036 [(set (match_operand:DF 0 "register_operand" "=e,e")
8037 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
8038 "TARGET_FPU && ! TARGET_V9"
8042 [(set_attr "type" "fpmove,*")
8043 (set_attr "length" "*,2")])
8046 [(set (match_operand:DF 0 "register_operand" "")
8047 (abs:DF (match_operand:DF 1 "register_operand" "")))]
8051 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
8052 [(set (match_dup 2) (abs:SF (match_dup 3)))
8053 (set (match_dup 4) (match_dup 5))]
8054 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
8055 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
8056 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
8057 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
8059 (define_insn "*absdf2_v9"
8060 [(set (match_operand:DF 0 "register_operand" "=e")
8061 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
8062 "TARGET_FPU && TARGET_V9"
8064 [(set_attr "type" "fpmove")
8065 (set_attr "fptype" "double")])
8067 (define_insn "abssf2"
8068 [(set (match_operand:SF 0 "register_operand" "=f")
8069 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
8072 [(set_attr "type" "fpmove")])
8074 (define_expand "sqrttf2"
8075 [(set (match_operand:TF 0 "register_operand" "=e")
8076 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
8077 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
8080 if (! TARGET_HARD_QUAD)
8084 if (GET_CODE (operands[0]) != MEM)
8085 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
8087 slot0 = operands[0];
8088 if (GET_CODE (operands[1]) != MEM)
8090 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
8091 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
8094 slot1 = operands[1];
8096 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
8098 XEXP (slot0, 0), Pmode,
8099 XEXP (slot1, 0), Pmode);
8101 if (GET_CODE (operands[0]) != MEM)
8102 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
8107 (define_insn "*sqrttf2_hq"
8108 [(set (match_operand:TF 0 "register_operand" "=e")
8109 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
8110 "TARGET_FPU && TARGET_HARD_QUAD"
8112 [(set_attr "type" "fpsqrtd")])
8114 (define_insn "sqrtdf2"
8115 [(set (match_operand:DF 0 "register_operand" "=e")
8116 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
8119 [(set_attr "type" "fpsqrtd")
8120 (set_attr "fptype" "double")])
8122 (define_insn "sqrtsf2"
8123 [(set (match_operand:SF 0 "register_operand" "=f")
8124 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
8127 [(set_attr "type" "fpsqrts")])
8129 ;;- arithmetic shift instructions
8131 (define_insn "ashlsi3"
8132 [(set (match_operand:SI 0 "register_operand" "=r")
8133 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8134 (match_operand:SI 2 "arith_operand" "rI")))]
8138 if (GET_CODE (operands[2]) == CONST_INT
8139 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8140 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8142 return \"sll\\t%1, %2, %0\";
8144 [(set_attr "type" "shift")])
8146 ;; We special case multiplication by two, as add can be done
8147 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8148 (define_insn "*ashlsi3_const1"
8149 [(set (match_operand:SI 0 "register_operand" "=r")
8150 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8155 (define_expand "ashldi3"
8156 [(set (match_operand:DI 0 "register_operand" "=r")
8157 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8158 (match_operand:SI 2 "arith_operand" "rI")))]
8159 "TARGET_ARCH64 || TARGET_V8PLUS"
8162 if (! TARGET_ARCH64)
8164 if (GET_CODE (operands[2]) == CONST_INT)
8166 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
8171 ;; We special case multiplication by two, as add can be done
8172 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8173 (define_insn "*ashldi3_const1"
8174 [(set (match_operand:DI 0 "register_operand" "=r")
8175 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8180 (define_insn "*ashldi3_sp64"
8181 [(set (match_operand:DI 0 "register_operand" "=r")
8182 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8183 (match_operand:SI 2 "arith_operand" "rI")))]
8187 if (GET_CODE (operands[2]) == CONST_INT
8188 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8189 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8191 return \"sllx\\t%1, %2, %0\";
8193 [(set_attr "type" "shift")])
8196 (define_insn "ashldi3_v8plus"
8197 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8198 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8199 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8200 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8202 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8203 [(set_attr "type" "multi")
8204 (set_attr "length" "5,5,6")])
8206 ;; Optimize (1LL<<x)-1
8207 ;; XXX this also needs to be fixed to handle equal subregs
8208 ;; XXX first before we could re-enable it.
8210 ; [(set (match_operand:DI 0 "register_operand" "=h")
8211 ; (plus:DI (ashift:DI (const_int 1)
8212 ; (match_operand:SI 1 "arith_operand" "rI"))
8214 ; "0 && TARGET_V8PLUS"
8217 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
8218 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8219 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8221 ; [(set_attr "type" "multi")
8222 ; (set_attr "length" "4")])
8224 (define_insn "*cmp_cc_ashift_1"
8225 [(set (reg:CC_NOOV 100)
8226 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8230 "addcc\\t%0, %0, %%g0"
8231 [(set_attr "type" "compare")])
8233 (define_insn "*cmp_cc_set_ashift_1"
8234 [(set (reg:CC_NOOV 100)
8235 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8238 (set (match_operand:SI 0 "register_operand" "=r")
8239 (ashift:SI (match_dup 1) (const_int 1)))]
8241 "addcc\\t%1, %1, %0"
8242 [(set_attr "type" "compare")])
8244 (define_insn "ashrsi3"
8245 [(set (match_operand:SI 0 "register_operand" "=r")
8246 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8247 (match_operand:SI 2 "arith_operand" "rI")))]
8251 if (GET_CODE (operands[2]) == CONST_INT
8252 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8253 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8255 return \"sra\\t%1, %2, %0\";
8257 [(set_attr "type" "shift")])
8259 (define_insn "*ashrsi3_extend"
8260 [(set (match_operand:DI 0 "register_operand" "=r")
8261 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8262 (match_operand:SI 2 "arith_operand" "r"))))]
8265 [(set_attr "type" "shift")])
8267 ;; This handles the case as above, but with constant shift instead of
8268 ;; register. Combiner "simplifies" it for us a little bit though.
8269 (define_insn "*ashrsi3_extend2"
8270 [(set (match_operand:DI 0 "register_operand" "=r")
8271 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8273 (match_operand:SI 2 "small_int_or_double" "n")))]
8275 && ((GET_CODE (operands[2]) == CONST_INT
8276 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8277 || (GET_CODE (operands[2]) == CONST_DOUBLE
8278 && !CONST_DOUBLE_HIGH (operands[2])
8279 && CONST_DOUBLE_LOW (operands[2]) >= 32
8280 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8283 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8285 return \"sra\\t%1, %2, %0\";
8287 [(set_attr "type" "shift")])
8289 (define_expand "ashrdi3"
8290 [(set (match_operand:DI 0 "register_operand" "=r")
8291 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8292 (match_operand:SI 2 "arith_operand" "rI")))]
8293 "TARGET_ARCH64 || TARGET_V8PLUS"
8296 if (! TARGET_ARCH64)
8298 if (GET_CODE (operands[2]) == CONST_INT)
8299 FAIL; /* prefer generic code in this case */
8300 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8306 [(set (match_operand:DI 0 "register_operand" "=r")
8307 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8308 (match_operand:SI 2 "arith_operand" "rI")))]
8312 if (GET_CODE (operands[2]) == CONST_INT
8313 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8314 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8316 return \"srax\\t%1, %2, %0\";
8318 [(set_attr "type" "shift")])
8321 (define_insn "ashrdi3_v8plus"
8322 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8323 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8324 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8325 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8327 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8328 [(set_attr "type" "multi")
8329 (set_attr "length" "5,5,6")])
8331 (define_insn "lshrsi3"
8332 [(set (match_operand:SI 0 "register_operand" "=r")
8333 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8334 (match_operand:SI 2 "arith_operand" "rI")))]
8338 if (GET_CODE (operands[2]) == CONST_INT
8339 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8340 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8342 return \"srl\\t%1, %2, %0\";
8344 [(set_attr "type" "shift")])
8346 ;; This handles the case where
8347 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8348 ;; but combiner "simplifies" it for us.
8349 (define_insn "*lshrsi3_extend"
8350 [(set (match_operand:DI 0 "register_operand" "=r")
8351 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8352 (match_operand:SI 2 "arith_operand" "r")) 0)
8353 (match_operand 3 "" "")))]
8355 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8356 && CONST_DOUBLE_HIGH (operands[3]) == 0
8357 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8358 || (HOST_BITS_PER_WIDE_INT >= 64
8359 && GET_CODE (operands[3]) == CONST_INT
8360 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8362 [(set_attr "type" "shift")])
8364 ;; This handles the case where
8365 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8366 ;; but combiner "simplifies" it for us.
8367 (define_insn "*lshrsi3_extend2"
8368 [(set (match_operand:DI 0 "register_operand" "=r")
8369 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8370 (match_operand 2 "small_int_or_double" "n")
8373 && ((GET_CODE (operands[2]) == CONST_INT
8374 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8375 || (GET_CODE (operands[2]) == CONST_DOUBLE
8376 && CONST_DOUBLE_HIGH (operands[2]) == 0
8377 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8380 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8382 return \"srl\\t%1, %2, %0\";
8384 [(set_attr "type" "shift")])
8386 (define_expand "lshrdi3"
8387 [(set (match_operand:DI 0 "register_operand" "=r")
8388 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8389 (match_operand:SI 2 "arith_operand" "rI")))]
8390 "TARGET_ARCH64 || TARGET_V8PLUS"
8393 if (! TARGET_ARCH64)
8395 if (GET_CODE (operands[2]) == CONST_INT)
8397 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8403 [(set (match_operand:DI 0 "register_operand" "=r")
8404 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8405 (match_operand:SI 2 "arith_operand" "rI")))]
8409 if (GET_CODE (operands[2]) == CONST_INT
8410 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8411 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8413 return \"srlx\\t%1, %2, %0\";
8415 [(set_attr "type" "shift")])
8418 (define_insn "lshrdi3_v8plus"
8419 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8420 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8421 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8422 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8424 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8425 [(set_attr "type" "multi")
8426 (set_attr "length" "5,5,6")])
8429 [(set (match_operand:SI 0 "register_operand" "=r")
8430 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8432 (match_operand:SI 2 "small_int_or_double" "n")))]
8434 && ((GET_CODE (operands[2]) == CONST_INT
8435 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8436 || (GET_CODE (operands[2]) == CONST_DOUBLE
8437 && !CONST_DOUBLE_HIGH (operands[2])
8438 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8441 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8443 return \"srax\\t%1, %2, %0\";
8445 [(set_attr "type" "shift")])
8448 [(set (match_operand:SI 0 "register_operand" "=r")
8449 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8451 (match_operand:SI 2 "small_int_or_double" "n")))]
8453 && ((GET_CODE (operands[2]) == CONST_INT
8454 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8455 || (GET_CODE (operands[2]) == CONST_DOUBLE
8456 && !CONST_DOUBLE_HIGH (operands[2])
8457 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8460 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8462 return \"srlx\\t%1, %2, %0\";
8464 [(set_attr "type" "shift")])
8467 [(set (match_operand:SI 0 "register_operand" "=r")
8468 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8469 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8470 (match_operand:SI 3 "small_int_or_double" "n")))]
8472 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8473 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8474 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8475 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8478 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8480 return \"srax\\t%1, %2, %0\";
8482 [(set_attr "type" "shift")])
8485 [(set (match_operand:SI 0 "register_operand" "=r")
8486 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8487 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8488 (match_operand:SI 3 "small_int_or_double" "n")))]
8490 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8491 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8492 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8493 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8496 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8498 return \"srlx\\t%1, %2, %0\";
8500 [(set_attr "type" "shift")])
8502 ;; Unconditional and other jump instructions
8503 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8504 ;; following insn is never executed. This saves us a nop. Dbx does not
8505 ;; handle such branches though, so we only use them when optimizing.
8507 [(set (pc) (label_ref (match_operand 0 "" "")))]
8511 /* TurboSparc is reported to have problems with
8514 i.e. an empty loop with the annul bit set. The workaround is to use
8518 if (! TARGET_V9 && flag_delayed_branch
8519 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8520 == INSN_ADDRESSES (INSN_UID (insn))))
8521 return \"b\\t%l0%#\";
8523 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8525 [(set_attr "type" "uncond_branch")])
8527 (define_expand "tablejump"
8528 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8529 (use (label_ref (match_operand 1 "" "")))])]
8533 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8536 /* In pic mode, our address differences are against the base of the
8537 table. Add that base value back in; CSE ought to be able to combine
8538 the two address loads. */
8542 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8544 if (CASE_VECTOR_MODE != Pmode)
8545 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8546 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8547 operands[0] = memory_address (Pmode, tmp);
8551 (define_insn "*tablejump_sp32"
8552 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8553 (use (label_ref (match_operand 1 "" "")))]
8556 [(set_attr "type" "uncond_branch")])
8558 (define_insn "*tablejump_sp64"
8559 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8560 (use (label_ref (match_operand 1 "" "")))]
8563 [(set_attr "type" "uncond_branch")])
8565 ;; This pattern recognizes the "instruction" that appears in
8566 ;; a function call that wants a structure value,
8567 ;; to inform the called function if compiled with Sun CC.
8568 ;(define_insn "*unimp_insn"
8569 ; [(match_operand:SI 0 "immediate_operand" "")]
8570 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8572 ; [(set_attr "type" "marker")])
8574 ;;- jump to subroutine
8575 (define_expand "call"
8576 ;; Note that this expression is not used for generating RTL.
8577 ;; All the RTL is generated explicitly below.
8578 [(call (match_operand 0 "call_operand" "")
8579 (match_operand 3 "" "i"))]
8580 ;; operands[2] is next_arg_register
8581 ;; operands[3] is struct_value_size_rtx.
8585 rtx fn_rtx, nregs_rtx;
8587 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8590 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8592 /* This is really a PIC sequence. We want to represent
8593 it as a funny jump so its delay slots can be filled.
8595 ??? But if this really *is* a CALL, will not it clobber the
8596 call-clobbered registers? We lose this if it is a JUMP_INSN.
8597 Why cannot we have delay slots filled if it were a CALL? */
8599 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8604 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8606 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8612 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8613 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8617 fn_rtx = operands[0];
8619 /* Count the number of parameter registers being used by this call.
8620 if that argument is NULL, it means we are using them all, which
8621 means 6 on the sparc. */
8624 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8626 nregs_rtx = GEN_INT (6);
8628 nregs_rtx = const0_rtx;
8631 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8635 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8637 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8642 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8643 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8647 /* If this call wants a structure value,
8648 emit an unimp insn to let the called function know about this. */
8649 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8651 rtx insn = emit_insn (operands[3]);
8652 SCHED_GROUP_P (insn) = 1;
8659 ;; We can't use the same pattern for these two insns, because then registers
8660 ;; in the address may not be properly reloaded.
8662 (define_insn "*call_address_sp32"
8663 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8664 (match_operand 1 "" ""))
8665 (clobber (reg:SI 15))]
8666 ;;- Do not use operand 1 for most machines.
8669 [(set_attr "type" "call")])
8671 (define_insn "*call_symbolic_sp32"
8672 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8673 (match_operand 1 "" ""))
8674 (clobber (reg:SI 15))]
8675 ;;- Do not use operand 1 for most machines.
8678 [(set_attr "type" "call")])
8680 (define_insn "*call_address_sp64"
8681 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8682 (match_operand 1 "" ""))
8683 (clobber (reg:DI 15))]
8684 ;;- Do not use operand 1 for most machines.
8687 [(set_attr "type" "call")])
8689 (define_insn "*call_symbolic_sp64"
8690 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8691 (match_operand 1 "" ""))
8692 (clobber (reg:DI 15))]
8693 ;;- Do not use operand 1 for most machines.
8696 [(set_attr "type" "call")])
8698 ;; This is a call that wants a structure value.
8699 ;; There is no such critter for v9 (??? we may need one anyway).
8700 (define_insn "*call_address_struct_value_sp32"
8701 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8702 (match_operand 1 "" ""))
8703 (match_operand 2 "immediate_operand" "")
8704 (clobber (reg:SI 15))]
8705 ;;- Do not use operand 1 for most machines.
8706 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8707 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8708 [(set_attr "type" "call_no_delay_slot")
8709 (set_attr "length" "3")])
8711 ;; This is a call that wants a structure value.
8712 ;; There is no such critter for v9 (??? we may need one anyway).
8713 (define_insn "*call_symbolic_struct_value_sp32"
8714 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8715 (match_operand 1 "" ""))
8716 (match_operand 2 "immediate_operand" "")
8717 (clobber (reg:SI 15))]
8718 ;;- Do not use operand 1 for most machines.
8719 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8720 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8721 [(set_attr "type" "call_no_delay_slot")
8722 (set_attr "length" "3")])
8724 ;; This is a call that may want a structure value. This is used for
8726 (define_insn "*call_address_untyped_struct_value_sp32"
8727 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8728 (match_operand 1 "" ""))
8729 (match_operand 2 "immediate_operand" "")
8730 (clobber (reg:SI 15))]
8731 ;;- Do not use operand 1 for most machines.
8732 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8733 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8734 [(set_attr "type" "call_no_delay_slot")
8735 (set_attr "length" "3")])
8737 ;; This is a call that wants a structure value.
8738 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8739 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8740 (match_operand 1 "" ""))
8741 (match_operand 2 "immediate_operand" "")
8742 (clobber (reg:SI 15))]
8743 ;;- Do not use operand 1 for most machines.
8744 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8745 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8746 [(set_attr "type" "call_no_delay_slot")
8747 (set_attr "length" "3")])
8749 (define_expand "call_value"
8750 ;; Note that this expression is not used for generating RTL.
8751 ;; All the RTL is generated explicitly below.
8752 [(set (match_operand 0 "register_operand" "=rf")
8753 (call (match_operand 1 "" "")
8754 (match_operand 4 "" "")))]
8755 ;; operand 2 is stack_size_rtx
8756 ;; operand 3 is next_arg_register
8760 rtx fn_rtx, nregs_rtx;
8763 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8766 fn_rtx = operands[1];
8770 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8772 nregs_rtx = GEN_INT (6);
8774 nregs_rtx = const0_rtx;
8778 gen_rtx_SET (VOIDmode, operands[0],
8779 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8780 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8782 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8787 (define_insn "*call_value_address_sp32"
8788 [(set (match_operand 0 "" "=rf")
8789 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8790 (match_operand 2 "" "")))
8791 (clobber (reg:SI 15))]
8792 ;;- Do not use operand 2 for most machines.
8795 [(set_attr "type" "call")])
8797 (define_insn "*call_value_symbolic_sp32"
8798 [(set (match_operand 0 "" "=rf")
8799 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8800 (match_operand 2 "" "")))
8801 (clobber (reg:SI 15))]
8802 ;;- Do not use operand 2 for most machines.
8805 [(set_attr "type" "call")])
8807 (define_insn "*call_value_address_sp64"
8808 [(set (match_operand 0 "" "")
8809 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8810 (match_operand 2 "" "")))
8811 (clobber (reg:DI 15))]
8812 ;;- Do not use operand 2 for most machines.
8815 [(set_attr "type" "call")])
8817 (define_insn "*call_value_symbolic_sp64"
8818 [(set (match_operand 0 "" "")
8819 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8820 (match_operand 2 "" "")))
8821 (clobber (reg:DI 15))]
8822 ;;- Do not use operand 2 for most machines.
8825 [(set_attr "type" "call")])
8827 (define_expand "untyped_call"
8828 [(parallel [(call (match_operand 0 "" "")
8830 (match_operand 1 "" "")
8831 (match_operand 2 "" "")])]
8837 /* Pass constm1 to indicate that it may expect a structure value, but
8838 we don't know what size it is. */
8839 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8841 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8843 rtx set = XVECEXP (operands[2], 0, i);
8844 emit_move_insn (SET_DEST (set), SET_SRC (set));
8847 /* The optimizer does not know that the call sets the function value
8848 registers we stored in the result block. We avoid problems by
8849 claiming that all hard registers are used and clobbered at this
8851 emit_insn (gen_blockage ());
8857 (define_expand "sibcall"
8858 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8863 (define_insn "*sibcall_symbolic_sp32"
8864 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8865 (match_operand 1 "" ""))
8868 "* return output_sibcall(insn, operands[0]);"
8869 [(set_attr "type" "sibcall")])
8871 (define_insn "*sibcall_symbolic_sp64"
8872 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8873 (match_operand 1 "" ""))
8876 "* return output_sibcall(insn, operands[0]);"
8877 [(set_attr "type" "sibcall")])
8879 (define_expand "sibcall_value"
8880 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8881 (call (match_operand 1 "" "") (const_int 0)))
8886 (define_insn "*sibcall_value_symbolic_sp32"
8887 [(set (match_operand 0 "" "=rf")
8888 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8889 (match_operand 2 "" "")))
8892 "* return output_sibcall(insn, operands[1]);"
8893 [(set_attr "type" "sibcall")])
8895 (define_insn "*sibcall_value_symbolic_sp64"
8896 [(set (match_operand 0 "" "")
8897 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8898 (match_operand 2 "" "")))
8901 "* return output_sibcall(insn, operands[1]);"
8902 [(set_attr "type" "sibcall")])
8904 (define_expand "sibcall_epilogue"
8909 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8910 ;; all of memory. This blocks insns from being moved across this point.
8912 (define_insn "blockage"
8913 [(unspec_volatile [(const_int 0)] 0)]
8916 [(set_attr "length" "0")])
8918 ;; Prepare to return any type including a structure value.
8920 (define_expand "untyped_return"
8921 [(match_operand:BLK 0 "memory_operand" "")
8922 (match_operand 1 "" "")]
8926 rtx valreg1 = gen_rtx_REG (DImode, 24);
8927 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8928 rtx result = operands[0];
8930 if (! TARGET_ARCH64)
8932 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8934 rtx value = gen_reg_rtx (SImode);
8936 /* Fetch the instruction where we will return to and see if it's an unimp
8937 instruction (the most significant 10 bits will be zero). If so,
8938 update the return address to skip the unimp instruction. */
8939 emit_move_insn (value,
8940 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8941 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8942 emit_insn (gen_update_return (rtnreg, value));
8945 /* Reload the function value registers. */
8946 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8947 emit_move_insn (valreg2,
8948 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8950 /* Put USE insns before the return. */
8951 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8952 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8954 /* Construct the return. */
8955 expand_null_return ();
8960 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8961 ;; and parts of the compiler don't want to believe that the add is needed.
8963 (define_insn "update_return"
8964 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8965 (match_operand:SI 1 "register_operand" "r")] 1)]
8967 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8968 [(set_attr "type" "multi")
8969 (set_attr "length" "3")])
8976 (define_expand "indirect_jump"
8977 [(set (pc) (match_operand 0 "address_operand" "p"))]
8981 (define_insn "*branch_sp32"
8982 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8985 [(set_attr "type" "uncond_branch")])
8987 (define_insn "*branch_sp64"
8988 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8991 [(set_attr "type" "uncond_branch")])
8993 ;; ??? Doesn't work with -mflat.
8994 (define_expand "nonlocal_goto"
8995 [(match_operand:SI 0 "general_operand" "")
8996 (match_operand:SI 1 "general_operand" "")
8997 (match_operand:SI 2 "general_operand" "")
8998 (match_operand:SI 3 "" "")]
9003 rtx chain = operands[0];
9005 rtx lab = operands[1];
9006 rtx stack = operands[2];
9007 rtx fp = operands[3];
9010 /* Trap instruction to flush all the register windows. */
9011 emit_insn (gen_flush_register_windows ());
9013 /* Load the fp value for the containing fn into %fp. This is needed
9014 because STACK refers to %fp. Note that virtual register instantiation
9015 fails if the virtual %fp isn't set from a register. */
9016 if (GET_CODE (fp) != REG)
9017 fp = force_reg (Pmode, fp);
9018 emit_move_insn (virtual_stack_vars_rtx, fp);
9020 /* Find the containing function's current nonlocal goto handler,
9021 which will do any cleanups and then jump to the label. */
9022 labreg = gen_rtx_REG (Pmode, 8);
9023 emit_move_insn (labreg, lab);
9025 /* Restore %fp from stack pointer value for containing function.
9026 The restore insn that follows will move this to %sp,
9027 and reload the appropriate value into %fp. */
9028 emit_move_insn (hard_frame_pointer_rtx, stack);
9030 /* USE of frame_pointer_rtx added for consistency; not clear if
9032 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
9033 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9036 /* Return, restoring reg window and jumping to goto handler. */
9037 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
9038 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
9040 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
9046 /* Put in the static chain register the nonlocal label address. */
9047 emit_move_insn (static_chain_rtx, chain);
9050 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
9051 emit_jump_insn (gen_goto_handler_and_restore (labreg));
9056 ;; Special trap insn to flush register windows.
9057 (define_insn "flush_register_windows"
9058 [(unspec_volatile [(const_int 0)] 1)]
9060 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
9061 [(set_attr "type" "misc")])
9063 (define_insn "goto_handler_and_restore"
9064 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
9065 "GET_MODE (operands[0]) == Pmode"
9066 "jmp\\t%0+0\\n\\trestore"
9067 [(set_attr "type" "multi")
9068 (set_attr "length" "2")])
9070 ;;(define_insn "goto_handler_and_restore_v9"
9071 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
9072 ;; (match_operand:SI 1 "register_operand" "=r,r")
9073 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9074 ;; "TARGET_V9 && ! TARGET_ARCH64"
9076 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9077 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9078 ;; [(set_attr "type" "multi")
9079 ;; (set_attr "length" "2,3")])
9081 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
9082 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
9083 ;; (match_operand:DI 1 "register_operand" "=r,r")
9084 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9085 ;; "TARGET_V9 && TARGET_ARCH64"
9087 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9088 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9089 ;; [(set_attr "type" "multi")
9090 ;; (set_attr "length" "2,3")])
9092 ;; For __builtin_setjmp we need to flush register windows iff the function
9093 ;; calls alloca as well, because otherwise the register window might be
9094 ;; saved after %sp adjustement and thus setjmp would crash
9095 (define_expand "builtin_setjmp_setup"
9096 [(match_operand 0 "register_operand" "r")]
9100 emit_insn (gen_do_builtin_setjmp_setup ());
9104 (define_insn "do_builtin_setjmp_setup"
9105 [(unspec_volatile [(const_int 0)] 5)]
9109 if (! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT)
9111 fputs (\"\tflushw\n\", asm_out_file);
9113 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
9114 TARGET_ARCH64 ? 'x' : 'w',
9115 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
9116 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
9117 TARGET_ARCH64 ? 'x' : 'w',
9118 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
9119 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
9120 TARGET_ARCH64 ? 'x' : 'w',
9121 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
9124 [(set_attr "type" "misc")
9125 (set (attr "length") (if_then_else (eq_attr "pic" "true")
9130 [(unspec_volatile [(const_int 0)] 5)]
9131 "! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT"
9135 if (current_function_calls_alloca)
9136 emit_insn (gen_flush_register_windows ());
9140 ;; Pattern for use after a setjmp to store FP and the return register
9141 ;; into the stack area.
9143 (define_expand "setjmp"
9149 emit_insn (gen_setjmp_64 ());
9151 emit_insn (gen_setjmp_32 ());
9155 (define_expand "setjmp_32"
9156 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
9157 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
9160 { operands[0] = frame_pointer_rtx; }")
9162 (define_expand "setjmp_64"
9163 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
9164 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
9167 { operands[0] = frame_pointer_rtx; }")
9169 ;; Special pattern for the FLUSH instruction.
9171 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
9172 ; of the define_insn otherwise missing a mode. We make "flush", aka
9173 ; gen_flush, the default one since sparc_initialize_trampoline uses
9174 ; it on SImode mem values.
9176 (define_insn "flush"
9177 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
9179 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9180 [(set_attr "type" "misc")])
9182 (define_insn "flushdi"
9183 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
9185 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9186 [(set_attr "type" "misc")])
9191 ;; The scan instruction searches from the most significant bit while ffs
9192 ;; searches from the least significant bit. The bit index and treatment of
9193 ;; zero also differ. It takes at least 7 instructions to get the proper
9194 ;; result. Here is an obvious 8 instruction sequence.
9197 (define_insn "ffssi2"
9198 [(set (match_operand:SI 0 "register_operand" "=&r")
9199 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
9200 (clobber (match_scratch:SI 2 "=&r"))]
9201 "TARGET_SPARCLITE || TARGET_SPARCLET"
9204 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\";
9206 [(set_attr "type" "multi")
9207 (set_attr "length" "8")])
9209 ;; ??? This should be a define expand, so that the extra instruction have
9210 ;; a chance of being optimized away.
9212 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9213 ;; does, but no one uses that and we don't have a switch for it.
9215 ;(define_insn "ffsdi2"
9216 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9217 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9218 ; (clobber (match_scratch:DI 2 "=&r"))]
9220 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9221 ; [(set_attr "type" "multi")
9222 ; (set_attr "length" "4")])
9226 ;; Peepholes go at the end.
9228 ;; Optimize consecutive loads or stores into ldd and std when possible.
9229 ;; The conditions in which we do this are very restricted and are
9230 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9233 [(set (match_operand:SI 0 "memory_operand" "")
9235 (set (match_operand:SI 1 "memory_operand" "")
9238 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
9241 "operands[0] = change_address (operands[0], DImode, NULL);")
9244 [(set (match_operand:SI 0 "memory_operand" "")
9246 (set (match_operand:SI 1 "memory_operand" "")
9249 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
9252 "operands[1] = change_address (operands[1], DImode, NULL);")
9255 [(set (match_operand:SI 0 "register_operand" "")
9256 (match_operand:SI 1 "memory_operand" ""))
9257 (set (match_operand:SI 2 "register_operand" "")
9258 (match_operand:SI 3 "memory_operand" ""))]
9259 "registers_ok_for_ldd_peep (operands[0], operands[2])
9260 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9263 "operands[1] = change_address (operands[1], DImode, NULL);
9264 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
9267 [(set (match_operand:SI 0 "memory_operand" "")
9268 (match_operand:SI 1 "register_operand" ""))
9269 (set (match_operand:SI 2 "memory_operand" "")
9270 (match_operand:SI 3 "register_operand" ""))]
9271 "registers_ok_for_ldd_peep (operands[1], operands[3])
9272 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9275 "operands[0] = change_address (operands[0], DImode, NULL);
9276 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
9279 [(set (match_operand:SF 0 "register_operand" "")
9280 (match_operand:SF 1 "memory_operand" ""))
9281 (set (match_operand:SF 2 "register_operand" "")
9282 (match_operand:SF 3 "memory_operand" ""))]
9283 "registers_ok_for_ldd_peep (operands[0], operands[2])
9284 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9287 "operands[1] = change_address (operands[1], DFmode, NULL);
9288 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
9291 [(set (match_operand:SF 0 "memory_operand" "")
9292 (match_operand:SF 1 "register_operand" ""))
9293 (set (match_operand:SF 2 "memory_operand" "")
9294 (match_operand:SF 3 "register_operand" ""))]
9295 "registers_ok_for_ldd_peep (operands[1], operands[3])
9296 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9299 "operands[0] = change_address (operands[0], DFmode, NULL);
9300 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
9303 [(set (match_operand:SI 0 "register_operand" "")
9304 (match_operand:SI 1 "memory_operand" ""))
9305 (set (match_operand:SI 2 "register_operand" "")
9306 (match_operand:SI 3 "memory_operand" ""))]
9307 "registers_ok_for_ldd_peep (operands[2], operands[0])
9308 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9311 "operands[3] = change_address (operands[3], DImode, NULL);
9312 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9315 [(set (match_operand:SI 0 "memory_operand" "")
9316 (match_operand:SI 1 "register_operand" ""))
9317 (set (match_operand:SI 2 "memory_operand" "")
9318 (match_operand:SI 3 "register_operand" ""))]
9319 "registers_ok_for_ldd_peep (operands[3], operands[1])
9320 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9323 "operands[2] = change_address (operands[2], DImode, NULL);
9324 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9328 [(set (match_operand:SF 0 "register_operand" "")
9329 (match_operand:SF 1 "memory_operand" ""))
9330 (set (match_operand:SF 2 "register_operand" "")
9331 (match_operand:SF 3 "memory_operand" ""))]
9332 "registers_ok_for_ldd_peep (operands[2], operands[0])
9333 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9336 "operands[3] = change_address (operands[3], DFmode, NULL);
9337 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9340 [(set (match_operand:SF 0 "memory_operand" "")
9341 (match_operand:SF 1 "register_operand" ""))
9342 (set (match_operand:SF 2 "memory_operand" "")
9343 (match_operand:SF 3 "register_operand" ""))]
9344 "registers_ok_for_ldd_peep (operands[3], operands[1])
9345 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9348 "operands[2] = change_address (operands[2], DFmode, NULL);
9349 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9351 ;; Optimize the case of following a reg-reg move with a test
9352 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9353 ;; This can result from a float to fix conversion.
9356 [(set (match_operand:SI 0 "register_operand" "")
9357 (match_operand:SI 1 "register_operand" ""))
9359 (compare:CC (match_operand:SI 2 "register_operand" "")
9361 "(rtx_equal_p (operands[2], operands[0])
9362 || rtx_equal_p (operands[2], operands[1]))
9363 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9364 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9365 [(parallel [(set (match_dup 0) (match_dup 1))
9367 (compare:CC (match_dup 1) (const_int 0)))])]
9371 [(set (match_operand:DI 0 "register_operand" "")
9372 (match_operand:DI 1 "register_operand" ""))
9374 (compare:CCX (match_operand:DI 2 "register_operand" "")
9377 && (rtx_equal_p (operands[2], operands[0])
9378 || rtx_equal_p (operands[2], operands[1]))
9379 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9380 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9381 [(parallel [(set (match_dup 0) (match_dup 1))
9383 (compare:CCX (match_dup 1) (const_int 0)))])]
9386 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
9387 ;; who then immediately calls final_scan_insn.
9389 (define_insn "*return_qi"
9390 [(set (match_operand:QI 0 "restore_operand" "")
9391 (match_operand:QI 1 "arith_operand" "rI"))
9393 "sparc_emitting_epilogue"
9396 if (! TARGET_ARCH64 && current_function_returns_struct)
9397 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9398 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9399 || IN_OR_GLOBAL_P (operands[1])))
9400 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9402 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9404 [(set_attr "type" "multi")
9405 (set_attr "length" "2")])
9407 (define_insn "*return_hi"
9408 [(set (match_operand:HI 0 "restore_operand" "")
9409 (match_operand:HI 1 "arith_operand" "rI"))
9411 "sparc_emitting_epilogue"
9414 if (! TARGET_ARCH64 && current_function_returns_struct)
9415 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9416 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9417 || IN_OR_GLOBAL_P (operands[1])))
9418 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9420 return \"ret\;restore %%g0, %1, %Y0\";
9422 [(set_attr "type" "multi")
9423 (set_attr "length" "2")])
9425 (define_insn "*return_si"
9426 [(set (match_operand:SI 0 "restore_operand" "")
9427 (match_operand:SI 1 "arith_operand" "rI"))
9429 "sparc_emitting_epilogue"
9432 if (! TARGET_ARCH64 && current_function_returns_struct)
9433 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9434 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9435 || IN_OR_GLOBAL_P (operands[1])))
9436 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9438 return \"ret\;restore %%g0, %1, %Y0\";
9440 [(set_attr "type" "multi")
9441 (set_attr "length" "2")])
9443 (define_insn "*return_sf_no_fpu"
9444 [(set (match_operand:SF 0 "restore_operand" "=r")
9445 (match_operand:SF 1 "register_operand" "r"))
9447 "sparc_emitting_epilogue"
9450 if (! TARGET_ARCH64 && current_function_returns_struct)
9451 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9452 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9453 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9455 return \"ret\;restore %%g0, %1, %Y0\";
9457 [(set_attr "type" "multi")
9458 (set_attr "length" "2")])
9460 (define_insn "*return_df_no_fpu"
9461 [(set (match_operand:DF 0 "restore_operand" "=r")
9462 (match_operand:DF 1 "register_operand" "r"))
9464 "sparc_emitting_epilogue && TARGET_ARCH64"
9467 if (IN_OR_GLOBAL_P (operands[1]))
9468 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9470 return \"ret\;restore %%g0, %1, %Y0\";
9472 [(set_attr "type" "multi")
9473 (set_attr "length" "2")])
9475 (define_insn "*return_addsi"
9476 [(set (match_operand:SI 0 "restore_operand" "")
9477 (plus:SI (match_operand:SI 1 "register_operand" "r")
9478 (match_operand:SI 2 "arith_operand" "rI")))
9480 "sparc_emitting_epilogue"
9483 if (! TARGET_ARCH64 && current_function_returns_struct)
9484 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9485 /* If operands are global or in registers, can use return */
9486 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9487 && (GET_CODE (operands[2]) == CONST_INT
9488 || IN_OR_GLOBAL_P (operands[2])))
9489 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9491 return \"ret\;restore %r1, %2, %Y0\";
9493 [(set_attr "type" "multi")
9494 (set_attr "length" "2")])
9496 (define_insn "*return_losum_si"
9497 [(set (match_operand:SI 0 "restore_operand" "")
9498 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9499 (match_operand:SI 2 "immediate_operand" "in")))
9501 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
9504 if (! TARGET_ARCH64 && current_function_returns_struct)
9505 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9506 /* If operands are global or in registers, can use return */
9507 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9508 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9510 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9512 [(set_attr "type" "multi")
9513 (set_attr "length" "2")])
9515 (define_insn "*return_di"
9516 [(set (match_operand:DI 0 "restore_operand" "")
9517 (match_operand:DI 1 "arith_double_operand" "rHI"))
9519 "sparc_emitting_epilogue && TARGET_ARCH64"
9520 "ret\;restore %%g0, %1, %Y0"
9521 [(set_attr "type" "multi")
9522 (set_attr "length" "2")])
9524 (define_insn "*return_adddi"
9525 [(set (match_operand:DI 0 "restore_operand" "")
9526 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9527 (match_operand:DI 2 "arith_double_operand" "rHI")))
9529 "sparc_emitting_epilogue && TARGET_ARCH64"
9530 "ret\;restore %r1, %2, %Y0"
9531 [(set_attr "type" "multi")
9532 (set_attr "length" "2")])
9534 (define_insn "*return_losum_di"
9535 [(set (match_operand:DI 0 "restore_operand" "")
9536 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9537 (match_operand:DI 2 "immediate_operand" "in")))
9539 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
9540 "ret\;restore %r1, %%lo(%a2), %Y0"
9541 [(set_attr "type" "multi")
9542 (set_attr "length" "2")])
9544 (define_insn "*return_sf"
9546 (match_operand:SF 0 "register_operand" "f"))
9548 "sparc_emitting_epilogue"
9549 "ret\;fmovs\\t%0, %%f0"
9550 [(set_attr "type" "multi")
9551 (set_attr "length" "2")])
9553 ;; Now peepholes to do a call followed by a jump.
9556 [(parallel [(set (match_operand 0 "" "")
9557 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9558 (match_operand 2 "" "")))
9559 (clobber (reg:SI 15))])
9560 (set (pc) (label_ref (match_operand 3 "" "")))]
9561 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9562 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
9563 && sparc_cpu != PROCESSOR_ULTRASPARC"
9564 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9567 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9568 (match_operand 1 "" ""))
9569 (clobber (reg:SI 15))])
9570 (set (pc) (label_ref (match_operand 2 "" "")))]
9571 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9572 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
9573 && sparc_cpu != PROCESSOR_ULTRASPARC"
9574 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9576 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
9577 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
9578 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
9580 (define_expand "prefetch"
9581 [(match_operand 0 "address_operand" "")
9582 (match_operand 1 "const_int_operand" "")
9583 (match_operand 2 "const_int_operand" "")]
9588 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
9590 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
9594 (define_insn "prefetch_64"
9595 [(prefetch (match_operand:DI 0 "address_operand" "p")
9596 (match_operand:DI 1 "const_int_operand" "n")
9597 (match_operand:DI 2 "const_int_operand" "n"))]
9600 static const char * const prefetch_instr[2][2] = {
9602 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9603 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
9606 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9607 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
9610 int read_or_write = INTVAL (operands[1]);
9611 int locality = INTVAL (operands[2]);
9613 if (read_or_write != 0 && read_or_write != 1)
9615 if (locality < 0 || locality > 3)
9617 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
9619 [(set_attr "type" "load")])
9621 (define_insn "prefetch_32"
9622 [(prefetch (match_operand:SI 0 "address_operand" "p")
9623 (match_operand:SI 1 "const_int_operand" "n")
9624 (match_operand:SI 2 "const_int_operand" "n"))]
9627 static const char * const prefetch_instr[2][2] = {
9629 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9630 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
9633 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9634 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
9637 int read_or_write = INTVAL (operands[1]);
9638 int locality = INTVAL (operands[2]);
9640 if (read_or_write != 0 && read_or_write != 1)
9642 if (locality < 0 || locality > 3)
9644 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
9646 [(set_attr "type" "load")])
9648 (define_expand "prologue"
9650 "flag_pic && current_function_uses_pic_offset_table"
9653 load_pic_register ();
9657 ;; We need to reload %l7 for -mflat -fpic,
9658 ;; otherwise %l7 should be preserved simply
9659 ;; by loading the function's register window
9660 (define_expand "exception_receiver"
9662 "TARGET_FLAT && flag_pic"
9665 load_pic_register ();
9670 (define_expand "builtin_setjmp_receiver"
9671 [(label_ref (match_operand 0 "" ""))]
9672 "TARGET_FLAT && flag_pic"
9675 load_pic_register ();
9680 [(trap_if (const_int 1) (const_int 5))]
9683 [(set_attr "type" "misc")])
9685 (define_expand "conditional_trap"
9686 [(trap_if (match_operator 0 "noov_compare_op"
9687 [(match_dup 2) (match_dup 3)])
9688 (match_operand:SI 1 "arith_operand" ""))]
9690 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9691 sparc_compare_op0, sparc_compare_op1);
9692 operands[3] = const0_rtx;")
9695 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9696 (match_operand:SI 1 "arith_operand" "rM"))]
9699 [(set_attr "type" "misc")])
9702 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9703 (match_operand:SI 1 "arith_operand" "rM"))]
9706 [(set_attr "type" "misc")])
9708 (define_insn "cycle_display"
9709 [(unspec [(match_operand 0 "const_int_operand" "")] 20)]
9712 [(set_attr "length" "0")])