OSDN Git Service

PR target/6512, PR target/5628
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.md
1 ;; Machine description for SPARC chip for GNU C compiler
2 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 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,
6 ;;  at Cygnus Support.
7
8 ;; This file is part of GNU CC.
9
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
28 ;;
29 ;; UNSPEC:              0       movsi_{lo_sum,high}_pic
30 ;;                              pic_lo_sum_di
31 ;;                              pic_sethi_di
32 ;;                      1       update_return
33 ;;                      2       get_pc
34 ;;                      5       movsi_{,lo_sum_,high_}pic_label_ref
35 ;;                      6       seth44
36 ;;                      7       setm44
37 ;;                      8       setl44
38 ;;                      9       sethh
39 ;;                      10      setlm
40 ;;                      11      embmedany_sethi, embmedany_brsum
41 ;;                      13      embmedany_textuhi
42 ;;                      14      embmedany_texthi
43 ;;                      15      embmedany_textulo
44 ;;                      16      embmedany_textlo
45 ;;                      18      sethm
46 ;;                      19      setlo
47 ;;                      20      cycle_display
48 ;;
49 ;; UNSPEC_VOLATILE:     0       blockage
50 ;;                      1       flush_register_windows
51 ;;                      2       goto_handler_and_restore
52 ;;                      3       goto_handler_and_restore_v9*
53 ;;                      4       flush
54 ;;                      5       do_builtin_setjmp_setup
55 ;;
56
57 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
58 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
59 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
60 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
61 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
62
63 ;; 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")))
67
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"
72  (const
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"))))
77
78 ;; Architecture size.
79 (define_attr "arch" "arch32bit,arch64bit"
80  (const
81   (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
82         (const_string "arch32bit"))))
83
84 ;; Insn type.
85
86 (define_attr "type"
87   "ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,idiv,fpload,fpstore,fp,fpmove,fpcmove,fpcrmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
88   (const_string "ialu"))
89
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)"))
93
94 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
95
96 (define_attr "pic" "false,true"
97   (symbol_ref "flag_pic != 0"))
98
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")
103              (const_int 2)
104              (const_int 1))
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")
110                    (const_int 2)
111                    (const_int 1))
112                  (if_then_else (eq_attr "empty_delay_slot" "true")
113                    (const_int 4)
114                    (const_int 3)))
115                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
116                  (if_then_else (eq_attr "empty_delay_slot" "true")
117                    (const_int 2)
118                    (const_int 1))
119                  (if_then_else (eq_attr "empty_delay_slot" "true")
120                    (const_int 4)
121                    (const_int 3))))
122              (if_then_else (eq_attr "empty_delay_slot" "true")
123                (const_int 2)
124                (const_int 1)))
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")
128                (const_int 2)
129                (const_int 1))
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")
133                    (const_int 2)
134                    (const_int 1))
135                  (if_then_else (eq_attr "empty_delay_slot" "true")
136                    (const_int 4)
137                    (const_int 3)))
138                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
139                  (if_then_else (eq_attr "empty_delay_slot" "true")
140                    (const_int 2)
141                    (const_int 1))
142                  (if_then_else (eq_attr "empty_delay_slot" "true")
143                    (const_int 4)
144                    (const_int 3)))))
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")
149                  (const_int 2)
150                  (const_int 1))
151                (if_then_else (eq_attr "empty_delay_slot" "true")
152                  (const_int 4)
153                  (const_int 3)))
154              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
155                (if_then_else (eq_attr "empty_delay_slot" "true")
156                  (const_int 2)
157                  (const_int 1))
158                (if_then_else (eq_attr "empty_delay_slot" "true")
159                  (const_int 4)
160                  (const_int 3))))
161          ] (const_int 1)))
162
163 ;; FP precision.
164 (define_attr "fptype" "single,double" (const_string "single"))
165
166 ;; UltraSPARC-III integer load type.
167 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
168
169 (define_asm_attributes
170   [(set_attr "length" "2")
171    (set_attr "type" "multi")])
172
173 ;; Attributes for instruction and branch scheduling
174
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"))))
185
186 (define_delay (eq_attr "type" "call")
187   [(eq_attr "in_call_delay" "true") (nil) (nil)])
188
189 (define_attr "eligible_for_sibcall_delay" "false,true"
190   (symbol_ref "eligible_for_sibcall_delay (insn)"))
191
192 (define_delay (eq_attr "type" "sibcall")
193   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
194
195 (define_attr "leaf_function" "false,true"
196   (const (symbol_ref "current_function_uses_only_leaf_regs")))
197
198 (define_attr "eligible_for_return_delay" "false,true"
199   (symbol_ref "eligible_for_return_delay (insn)"))
200
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")))
208
209 (define_delay (and (eq_attr "type" "return")
210                    (eq_attr "isa" "v9"))
211   [(eq_attr "in_return_delay" "true") (nil) (nil)])
212
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.
216
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.
224
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")))
230
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")))
236
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")))
242
243 (define_delay (eq_attr "type" "branch")
244   [(eq_attr "in_branch_delay" "true")
245    (nil) (eq_attr "in_annul_branch_delay" "true")])
246
247 (define_delay (eq_attr "type" "uncond_branch")
248   [(eq_attr "in_uncond_branch_delay" "true")
249    (nil) (nil)])
250    
251 ;; DFA scheduling on the SPARC
252
253 (define_automaton "cypress_0,cypress_1,supersparc_0,supersparc_1,hypersparc_0,hypersparc_1,sparclet,ultrasparc_0,ultrasparc_1,ultrasparc3_0,ultrasparc3_1")
254
255 ;; Cypress scheduling
256
257 (define_cpu_unit "cyp_memory, cyp_fpalu" "cypress_0")
258 (define_cpu_unit "cyp_fpmds" "cypress_1")
259
260 (define_insn_reservation "cyp_load" 2
261   (and (eq_attr "cpu" "cypress")
262     (eq_attr "type" "load,sload,fpload"))
263   "cyp_memory, nothing")
264
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")
269
270 (define_insn_reservation "cyp_fp_mult" 7
271   (and (eq_attr "cpu" "cypress")
272     (eq_attr "type" "fpmul"))
273   "cyp_fpmds, nothing*5")
274
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")
279
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")
284
285 ;; SuperSPARC scheduling
286
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")
290
291 (define_reservation "ss_iwport" "(ss_iwport0 | ss_iwport1)")
292
293 (define_insn_reservation "ss_iuload" 1
294   (and (eq_attr "cpu" "supersparc")
295     (eq_attr "type" "load,sload"))
296   "ss_memory")
297
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"))
303   "ss_memory")
304
305 (define_bypass 0 "ss_fpload" "ss_fp_alu,ss_fp_mult,ss_fp_divs,ss_fp_divd,ss_fp_sqrt")
306
307 (define_insn_reservation "ss_store" 1
308   (and (eq_attr "cpu" "supersparc")
309     (eq_attr "type" "store,fpstore"))
310   "ss_memory")
311
312 (define_insn_reservation "ss_ialu_shift" 1
313   (and (eq_attr "cpu" "supersparc")
314     (eq_attr "type" "shift"))
315   "ss_shift + ss_iwport")
316
317 (define_insn_reservation "ss_ialu_any" 1
318   (and (eq_attr "cpu" "supersparc")
319     (eq_attr "type" "load,sload,store,shift,ialu"))
320   "ss_iwport")
321
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")
326
327 (define_insn_reservation "ss_fp_mult" 3
328   (and (eq_attr "cpu" "supersparc")
329     (eq_attr "type" "fpmul"))
330   "ss_fpmds, nothing*2")
331
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")
336
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")
341
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")
346
347 (define_insn_reservation "ss_imul" 4
348   (and (eq_attr "cpu" "supersparc")
349     (eq_attr "type" "imul"))
350   "ss_fpmds*4")
351
352 ;; HyperSPARC/sparclite86x scheduling
353
354 (define_cpu_unit "hs_memory,hs_branch,hs_shift,hs_fpalu" "hypersparc_0")
355 (define_cpu_unit "hs_fpmds" "hypersparc_1")
356
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"))
360   "hs_memory")
361
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")
366
367 (define_insn_reservation "hs_slbranch" 1
368   (and (eq_attr "cpu" "sparclite86x")
369     (eq_attr "type" "branch"))
370   "hs_branch")
371
372 (define_insn_reservation "hs_slshift" 1
373   (and (eq_attr "cpu" "sparclite86x")
374     (eq_attr "type" "shift"))
375   "hs_shift")
376
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"))
380   "hs_fpalu")
381
382 (define_insn_reservation "hs_fp_mult" 1
383   (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
384     (eq_attr "type" "fpmul"))
385   "hs_fpmds")
386
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")
391
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")
396
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")
401
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")
406
407 ;; Sparclet tsc701 scheduling
408
409 (define_cpu_unit "sl_load0,sl_load1,sl_load2,sl_load3" "sparclet")
410 (define_cpu_unit "sl_store,sl_imul" "sparclet")
411
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)")
414
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")
419
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")
424
425 (define_insn_reservation "sl_imul" 5
426   (and (eq_attr "cpu" "tsc701")
427     (eq_attr "type" "imul"))
428   "sl_imul*5")
429
430 ;; UltraSPARC-I/II scheduling
431
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")
437
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")
441
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")
449
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:
453 ;;      COMPARE         IEU1
454 ;;      IALU            IEU0
455 ;; but we could schedule them together like this:
456 ;;      IALU            IEU0
457 ;;      COMPARE         IEU1
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")
461
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")
469
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")
474
475 (define_insn_reservation "us1_simple_ieu0" 1
476   (and (eq_attr "cpu" "ultrasparc")
477     (eq_attr "type" "shift"))
478   "us1_ieu0 + us1_slot012")
479
480 (define_insn_reservation "us1_simple_ieu1" 1
481   (and (eq_attr "cpu" "ultrasparc")
482     (eq_attr "type" "compare"))
483   "us1_ieu1 + us1_slot012")
484
485 (define_insn_reservation "us1_cmove" 2
486   (and (eq_attr "cpu" "ultrasparc")
487     (eq_attr "type" "cmove"))
488   "us1_single_issue, nothing")
489
490 (define_insn_reservation "us1_imul" 1
491   (and (eq_attr "cpu" "ultrasparc")
492     (eq_attr "type" "imul"))
493   "us1_single_issue")
494
495 (define_insn_reservation "us1_idiv" 1
496   (and (eq_attr "cpu" "ultrasparc")
497     (eq_attr "type" "idiv"))
498   "us1_single_issue")
499
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")
506
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")
511
512 (define_insn_reservation "us1_store" 1
513   (and (eq_attr "cpu" "ultrasparc")
514     (eq_attr "type" "store,fpstore"))
515   "us1_lsu + us1_slot012")
516
517 (define_insn_reservation "us1_branch" 1
518   (and (eq_attr "cpu" "ultrasparc")
519     (eq_attr "type" "branch"))
520   "us1_cti + us1_slotany")
521
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")
526
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")
532
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")
538
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")
544
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")
550
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")
556
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")
562
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")
568
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")
574
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")
580
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")
586
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.
592 (define_bypass 3
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")
595
596 ;; Floating point divide and square root use the multiplier unit
597 ;; for final rounding 3 cycles before the divide/sqrt is complete.
598
599 (define_insn_reservation "us1_fdivs"
600   13
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"
604   )
605
606 (define_bypass
607   12
608   "us1_fdivs"
609   "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
610
611 (define_insn_reservation "us1_fdivd"
612   23
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"
616   )
617 (define_bypass
618   22
619   "us1_fdivd"
620   "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
621
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")
628
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")
632
633 ;; UltraSPARC-III scheduling
634 ;;
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.
638
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")
642
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)")
646
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")
651
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")
656
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")
670
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")
675
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")
684
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")
690
691 (define_insn_reservation "us3_store" 1
692   (and (eq_attr "cpu" "ultrasparc3")
693     (eq_attr "type" "store,fpstore"))
694   "us3_ms + us3_slotany")
695
696 (define_insn_reservation "us3_branch" 1
697   (and (eq_attr "cpu" "ultrasparc3")
698     (eq_attr "type" "branch"))
699   "us3_br + us3_slotany")
700
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")
705
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")
710
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")
715
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")
720
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")
725
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")
730
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")
735
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")
740
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")
745
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")
750
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")
755
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")
762
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")
766
767 ;; If FMOVfcc is user of FPCMP, latency is only 1 cycle.
768 (define_bypass 1 "us3_fpcmp" "us3_fcmov")
769
770 \f
771 ;; Compare instructions.
772 ;; This controls RTL generation and register allocation.
773
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.
777 ;;
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
781 ;; it against zero.
782 ;;
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.
786
787 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
788
789 (define_expand "cmpsi"
790   [(set (reg:CC 100)
791         (compare:CC (match_operand:SI 0 "register_operand" "")
792                     (match_operand:SI 1 "arith_operand" "")))]
793   ""
794   "
795 {
796   sparc_compare_op0 = operands[0];
797   sparc_compare_op1 = operands[1];
798   DONE;
799 }")
800
801 (define_expand "cmpdi"
802   [(set (reg:CCX 100)
803         (compare:CCX (match_operand:DI 0 "register_operand" "")
804                      (match_operand:DI 1 "arith_double_operand" "")))]
805   "TARGET_ARCH64"
806   "
807 {
808   sparc_compare_op0 = operands[0];
809   sparc_compare_op1 = operands[1];
810   DONE;
811 }")
812
813 (define_expand "cmpsf"
814   ;; The 96 here isn't ever used by anyone.
815   [(set (reg:CCFP 96)
816         (compare:CCFP (match_operand:SF 0 "register_operand" "")
817                       (match_operand:SF 1 "register_operand" "")))]
818   "TARGET_FPU"
819   "
820 {
821   sparc_compare_op0 = operands[0];
822   sparc_compare_op1 = operands[1];
823   DONE;
824 }")
825
826 (define_expand "cmpdf"
827   ;; The 96 here isn't ever used by anyone.
828   [(set (reg:CCFP 96)
829         (compare:CCFP (match_operand:DF 0 "register_operand" "")
830                       (match_operand:DF 1 "register_operand" "")))]
831   "TARGET_FPU"
832   "
833 {
834   sparc_compare_op0 = operands[0];
835   sparc_compare_op1 = operands[1];
836   DONE;
837 }")
838
839 (define_expand "cmptf"
840   ;; The 96 here isn't ever used by anyone.
841   [(set (reg:CCFP 96)
842         (compare:CCFP (match_operand:TF 0 "register_operand" "")
843                       (match_operand:TF 1 "register_operand" "")))]
844   "TARGET_FPU"
845   "
846 {
847   sparc_compare_op0 = operands[0];
848   sparc_compare_op1 = operands[1];
849   DONE;
850 }")
851
852 ;; Now the compare DEFINE_INSNs.
853
854 (define_insn "*cmpsi_insn"
855   [(set (reg:CC 100)
856         (compare:CC (match_operand:SI 0 "register_operand" "r")
857                     (match_operand:SI 1 "arith_operand" "rI")))]
858   ""
859   "cmp\\t%0, %1"
860   [(set_attr "type" "compare")])
861
862 (define_insn "*cmpdi_sp64"
863   [(set (reg:CCX 100)
864         (compare:CCX (match_operand:DI 0 "register_operand" "r")
865                      (match_operand:DI 1 "arith_double_operand" "rHI")))]
866   "TARGET_ARCH64"
867   "cmp\\t%0, %1"
868   [(set_attr "type" "compare")])
869
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")))]
874   "TARGET_FPU"
875   "*
876 {
877   if (TARGET_V9)
878     return \"fcmpes\\t%0, %1, %2\";
879   return \"fcmpes\\t%1, %2\";
880 }"
881   [(set_attr "type" "fpcmp")])
882
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")))]
887   "TARGET_FPU"
888   "*
889 {
890   if (TARGET_V9)
891     return \"fcmped\\t%0, %1, %2\";
892   return \"fcmped\\t%1, %2\";
893 }"
894   [(set_attr "type" "fpcmp")
895    (set_attr "fptype" "double")])
896
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"
902   "*
903 {
904   if (TARGET_V9)
905     return \"fcmpeq\\t%0, %1, %2\";
906   return \"fcmpeq\\t%1, %2\";
907 }"
908   [(set_attr "type" "fpcmp")])
909
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")))]
914   "TARGET_FPU"
915   "*
916 {
917   if (TARGET_V9)
918     return \"fcmps\\t%0, %1, %2\";
919   return \"fcmps\\t%1, %2\";
920 }"
921   [(set_attr "type" "fpcmp")])
922
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")))]
927   "TARGET_FPU"
928   "*
929 {
930   if (TARGET_V9)
931     return \"fcmpd\\t%0, %1, %2\";
932   return \"fcmpd\\t%1, %2\";
933 }"
934   [(set_attr "type" "fpcmp")
935    (set_attr "fptype" "double")])
936
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"
942   "*
943 {
944   if (TARGET_V9)
945     return \"fcmpq\\t%0, %1, %2\";
946   return \"fcmpq\\t%1, %2\";
947 }"
948   [(set_attr "type" "fpcmp")])
949 \f
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
955 ;; branches.
956
957 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
958 ;; generate addcc/subcc instructions.
959
960 (define_expand "seqsi_special"
961   [(set (match_dup 3)
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))])]
967   ""
968   "{ operands[3] = gen_reg_rtx (SImode); }")
969
970 (define_expand "seqdi_special"
971   [(set (match_dup 3)
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)))]
976   "TARGET_ARCH64"
977   "{ operands[3] = gen_reg_rtx (DImode); }")
978
979 (define_expand "snesi_special"
980   [(set (match_dup 3)
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))])]
986   ""
987   "{ operands[3] = gen_reg_rtx (SImode); }")
988
989 (define_expand "snedi_special"
990   [(set (match_dup 3)
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)))]
995   "TARGET_ARCH64"
996   "{ operands[3] = gen_reg_rtx (DImode); }")
997
998 (define_expand "seqdi_special_trunc"
999   [(set (match_dup 3)
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)))]
1004   "TARGET_ARCH64"
1005   "{ operands[3] = gen_reg_rtx (DImode); }")
1006
1007 (define_expand "snedi_special_trunc"
1008   [(set (match_dup 3)
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)))]
1013   "TARGET_ARCH64"
1014   "{ operands[3] = gen_reg_rtx (DImode); }")
1015
1016 (define_expand "seqsi_special_extend"
1017   [(set (match_dup 3)
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))])]
1023   "TARGET_ARCH64"
1024   "{ operands[3] = gen_reg_rtx (SImode); }")
1025
1026 (define_expand "snesi_special_extend"
1027   [(set (match_dup 3)
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))])]
1033   "TARGET_ARCH64"
1034   "{ operands[3] = gen_reg_rtx (SImode); }")
1035
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)))]
1041   ""
1042   "
1043 {
1044   if (GET_MODE (sparc_compare_op0) == SImode)
1045     {
1046       rtx pat;
1047
1048       if (GET_MODE (operands[0]) == SImode)
1049         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
1050                                  sparc_compare_op1);
1051       else if (! TARGET_ARCH64)
1052         FAIL;
1053       else
1054         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
1055                                         sparc_compare_op1);
1056       emit_insn (pat);
1057       DONE;
1058     }
1059   else if (GET_MODE (sparc_compare_op0) == DImode)
1060     {
1061       rtx pat;
1062
1063       if (! TARGET_ARCH64)
1064         FAIL;
1065       else if (GET_MODE (operands[0]) == SImode)
1066         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
1067                                        sparc_compare_op1);
1068       else
1069         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
1070                                  sparc_compare_op1);
1071       emit_insn (pat);
1072       DONE;
1073     }
1074   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1075     {
1076       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1077       emit_jump_insn (gen_sne (operands[0]));
1078       DONE;
1079     }
1080   else if (TARGET_V9)
1081     {
1082       if (gen_v9_scc (EQ, operands))
1083         DONE;
1084       /* fall through */
1085     }
1086   FAIL;
1087 }")
1088
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)))]
1094   ""
1095   "
1096 {
1097   if (GET_MODE (sparc_compare_op0) == SImode)
1098     {
1099       rtx pat;
1100
1101       if (GET_MODE (operands[0]) == SImode)
1102         pat = gen_snesi_special (operands[0], sparc_compare_op0,
1103                                  sparc_compare_op1);
1104       else if (! TARGET_ARCH64)
1105         FAIL;
1106       else
1107         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
1108                                         sparc_compare_op1);
1109       emit_insn (pat);
1110       DONE;
1111     }
1112   else if (GET_MODE (sparc_compare_op0) == DImode)
1113     {
1114       rtx pat;
1115
1116       if (! TARGET_ARCH64)
1117         FAIL;
1118       else if (GET_MODE (operands[0]) == SImode)
1119         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
1120                                        sparc_compare_op1);
1121       else
1122         pat = gen_snedi_special (operands[0], sparc_compare_op0,
1123                                  sparc_compare_op1);
1124       emit_insn (pat);
1125       DONE;
1126     }
1127   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1128     {
1129       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1130       emit_jump_insn (gen_sne (operands[0]));
1131       DONE;
1132     }
1133   else if (TARGET_V9)
1134     {
1135       if (gen_v9_scc (NE, operands))
1136         DONE;
1137       /* fall through */
1138     }
1139   FAIL;
1140 }")
1141
1142 (define_expand "sgt"
1143   [(set (match_operand:SI 0 "intreg_operand" "")
1144         (gt:SI (match_dup 1) (const_int 0)))]
1145   ""
1146   "
1147 {
1148   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1149     {
1150       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1151       emit_jump_insn (gen_sne (operands[0]));
1152       DONE;
1153     }
1154   else if (TARGET_V9)
1155     {
1156       if (gen_v9_scc (GT, operands))
1157         DONE;
1158       /* fall through */
1159     }
1160   FAIL;
1161 }")
1162
1163 (define_expand "slt"
1164   [(set (match_operand:SI 0 "intreg_operand" "")
1165         (lt:SI (match_dup 1) (const_int 0)))]
1166   ""
1167   "
1168 {
1169   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1170     {
1171       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1172       emit_jump_insn (gen_sne (operands[0]));
1173       DONE;
1174     }
1175   else if (TARGET_V9)
1176     {
1177       if (gen_v9_scc (LT, operands))
1178         DONE;
1179       /* fall through */
1180     }
1181   FAIL;
1182 }")
1183
1184 (define_expand "sge"
1185   [(set (match_operand:SI 0 "intreg_operand" "")
1186         (ge:SI (match_dup 1) (const_int 0)))]
1187   ""
1188   "
1189 {
1190   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1191     {
1192       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1193       emit_jump_insn (gen_sne (operands[0]));
1194       DONE;
1195     }
1196   else if (TARGET_V9)
1197     {
1198       if (gen_v9_scc (GE, operands))
1199         DONE;
1200       /* fall through */
1201     }
1202   FAIL;
1203 }")
1204
1205 (define_expand "sle"
1206   [(set (match_operand:SI 0 "intreg_operand" "")
1207         (le:SI (match_dup 1) (const_int 0)))]
1208   ""
1209   "
1210 {
1211   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1212     {
1213       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1214       emit_jump_insn (gen_sne (operands[0]));
1215       DONE;
1216     }
1217   else if (TARGET_V9)
1218     {
1219       if (gen_v9_scc (LE, operands))
1220         DONE;
1221       /* fall through */
1222     }
1223   FAIL;
1224 }")
1225
1226 (define_expand "sgtu"
1227   [(set (match_operand:SI 0 "intreg_operand" "")
1228         (gtu:SI (match_dup 1) (const_int 0)))]
1229   ""
1230   "
1231 {
1232   if (! TARGET_V9)
1233     {
1234       rtx tem, pat;
1235
1236       /* We can do ltu easily, so if both operands are registers, swap them and
1237          do a LTU.  */
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))
1242         {
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)
1248             FAIL;
1249           emit_insn (pat);
1250           DONE;
1251         }
1252     }
1253   else
1254     {
1255       if (gen_v9_scc (GTU, operands))
1256         DONE;
1257     }
1258   FAIL;
1259 }")
1260
1261 (define_expand "sltu"
1262   [(set (match_operand:SI 0 "intreg_operand" "")
1263         (ltu:SI (match_dup 1) (const_int 0)))]
1264   ""
1265   "
1266 {
1267   if (TARGET_V9)
1268     {
1269       if (gen_v9_scc (LTU, operands))
1270         DONE;
1271     }
1272   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1273 }")
1274
1275 (define_expand "sgeu"
1276   [(set (match_operand:SI 0 "intreg_operand" "")
1277         (geu:SI (match_dup 1) (const_int 0)))]
1278   ""
1279   "
1280 {
1281   if (TARGET_V9)
1282     {
1283       if (gen_v9_scc (GEU, operands))
1284         DONE;
1285     }
1286   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1287 }")
1288
1289 (define_expand "sleu"
1290   [(set (match_operand:SI 0 "intreg_operand" "")
1291         (leu:SI (match_dup 1) (const_int 0)))]
1292   ""
1293   "
1294 {
1295   if (! TARGET_V9)
1296     {
1297       rtx tem, pat;
1298
1299       /* We can do geu easily, so if both operands are registers, swap them and
1300          do a GEU.  */
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))
1305         {
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)
1311             FAIL;
1312           emit_insn (pat);
1313           DONE;
1314         }
1315     }
1316   else
1317     {
1318       if (gen_v9_scc (LEU, operands))
1319         DONE;
1320     }
1321   FAIL;
1322 }")
1323
1324 ;; Now the DEFINE_INSNs for the scc cases.
1325
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
1329 ;; scheduled.
1330
1331 (define_insn "*snesi_zero"
1332   [(set (match_operand:SI 0 "register_operand" "=r")
1333         (ne:SI (match_operand:SI 1 "register_operand" "r")
1334                (const_int 0)))
1335    (clobber (reg:CC 100))]
1336   ""
1337   "#"
1338   [(set_attr "length" "2")])
1339
1340 (define_split
1341   [(set (match_operand:SI 0 "register_operand" "")
1342         (ne:SI (match_operand:SI 1 "register_operand" "")
1343                (const_int 0)))
1344    (clobber (reg:CC 100))]
1345   ""
1346   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1347                                            (const_int 0)))
1348    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1349   "")
1350
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")
1354                        (const_int 0))))
1355    (clobber (reg:CC 100))]
1356   ""
1357   "#"
1358   [(set_attr "length" "2")])
1359
1360 (define_split
1361   [(set (match_operand:SI 0 "register_operand" "")
1362         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1363                        (const_int 0))))
1364    (clobber (reg:CC 100))]
1365   ""
1366   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1367                                            (const_int 0)))
1368    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1369   "")
1370
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")
1374                (const_int 0)))
1375    (clobber (reg:CC 100))]
1376   "TARGET_ARCH64"
1377   "#"
1378   [(set_attr "length" "2")])
1379
1380 (define_split
1381   [(set (match_operand:DI 0 "register_operand" "")
1382         (ne:DI (match_operand:SI 1 "register_operand" "")
1383                (const_int 0)))
1384    (clobber (reg:CC 100))]
1385   "TARGET_ARCH64"
1386   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1387                                            (const_int 0)))
1388    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1389                                                         (const_int 0))
1390                                                (ltu:SI (reg:CC_NOOV 100)
1391                                                        (const_int 0)))))]
1392   "")
1393
1394 (define_insn "*snedi_zero"
1395   [(set (match_operand:DI 0 "register_operand" "=&r")
1396         (ne:DI (match_operand:DI 1 "register_operand" "r")
1397                (const_int 0)))]
1398   "TARGET_ARCH64"
1399   "#"
1400   [(set_attr "length" "2")])
1401
1402 (define_split
1403   [(set (match_operand:DI 0 "register_operand" "")
1404         (ne:DI (match_operand:DI 1 "register_operand" "")
1405                (const_int 0)))]
1406   "TARGET_ARCH64
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)
1410                                               (const_int 0))
1411                                        (const_int 1)
1412                                        (match_dup 0)))]
1413   "")
1414
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")
1418                        (const_int 0))))]
1419   "TARGET_ARCH64"
1420   "#"
1421   [(set_attr "length" "2")])
1422
1423 (define_split
1424   [(set (match_operand:DI 0 "register_operand" "")
1425         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1426                        (const_int 0))))]
1427   "TARGET_ARCH64
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)
1431                                               (const_int 0))
1432                                        (const_int -1)
1433                                        (match_dup 0)))]
1434   "")
1435
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")
1439                (const_int 0)))]
1440   "TARGET_ARCH64"
1441   "#"
1442   [(set_attr "length" "2")])
1443
1444 (define_split
1445   [(set (match_operand:SI 0 "register_operand" "")
1446         (ne:SI (match_operand:DI 1 "register_operand" "")
1447                (const_int 0)))]
1448   "TARGET_ARCH64
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)
1452                                               (const_int 0))
1453                                        (const_int 1)
1454                                        (match_dup 0)))]
1455   "")
1456
1457 (define_insn "*seqsi_zero"
1458   [(set (match_operand:SI 0 "register_operand" "=r")
1459         (eq:SI (match_operand:SI 1 "register_operand" "r")
1460                (const_int 0)))
1461    (clobber (reg:CC 100))]
1462   ""
1463   "#"
1464   [(set_attr "length" "2")])
1465
1466 (define_split
1467   [(set (match_operand:SI 0 "register_operand" "")
1468         (eq:SI (match_operand:SI 1 "register_operand" "")
1469                (const_int 0)))
1470    (clobber (reg:CC 100))]
1471   ""
1472   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1473                                            (const_int 0)))
1474    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1475   "")
1476
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")
1480                        (const_int 0))))
1481    (clobber (reg:CC 100))]
1482   ""
1483   "#"
1484   [(set_attr "length" "2")])
1485
1486 (define_split
1487   [(set (match_operand:SI 0 "register_operand" "")
1488         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1489                        (const_int 0))))
1490    (clobber (reg:CC 100))]
1491   ""
1492   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1493                                            (const_int 0)))
1494    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1495   "")
1496
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")
1500                (const_int 0)))
1501    (clobber (reg:CC 100))]
1502   "TARGET_ARCH64"
1503   "#"
1504   [(set_attr "length" "2")])
1505
1506 (define_split
1507   [(set (match_operand:DI 0 "register_operand" "")
1508         (eq:DI (match_operand:SI 1 "register_operand" "")
1509                (const_int 0)))
1510    (clobber (reg:CC 100))]
1511   "TARGET_ARCH64"
1512   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1513                                            (const_int 0)))
1514    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1515                                                           (const_int -1))
1516                                                 (ltu:SI (reg:CC_NOOV 100)
1517                                                         (const_int 0)))))]
1518   "")
1519
1520 (define_insn "*seqdi_zero"
1521   [(set (match_operand:DI 0 "register_operand" "=&r")
1522         (eq:DI (match_operand:DI 1 "register_operand" "r")
1523                (const_int 0)))]
1524   "TARGET_ARCH64"
1525   "#"
1526   [(set_attr "length" "2")])
1527
1528 (define_split
1529   [(set (match_operand:DI 0 "register_operand" "")
1530         (eq:DI (match_operand:DI 1 "register_operand" "")
1531                (const_int 0)))]
1532   "TARGET_ARCH64
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)
1536                                               (const_int 0))
1537                                        (const_int 1)
1538                                        (match_dup 0)))]
1539   "")
1540
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")
1544                        (const_int 0))))]
1545   "TARGET_ARCH64"
1546   "#"
1547   [(set_attr "length" "2")]) 
1548
1549 (define_split
1550   [(set (match_operand:DI 0 "register_operand" "")
1551         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1552                        (const_int 0))))]
1553   "TARGET_ARCH64
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)
1557                                               (const_int 0))
1558                                        (const_int -1)
1559                                        (match_dup 0)))]
1560   "")
1561
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")
1565                (const_int 0)))]
1566   "TARGET_ARCH64"
1567   "#"
1568   [(set_attr "length" "2")])
1569
1570 (define_split
1571   [(set (match_operand:SI 0 "register_operand" "")
1572         (eq:SI (match_operand:DI 1 "register_operand" "")
1573                (const_int 0)))]
1574   "TARGET_ARCH64
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)
1578                                               (const_int 0))
1579                                        (const_int 1)
1580                                        (match_dup 0)))]
1581   "")
1582
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
1585 ;; versions for v9.
1586
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")
1590                         (const_int 0))
1591                  (match_operand:SI 2 "register_operand" "r")))
1592    (clobber (reg:CC 100))]
1593   ""
1594   "#"
1595   [(set_attr "length" "2")])
1596
1597 (define_split
1598   [(set (match_operand:SI 0 "register_operand" "")
1599         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1600                         (const_int 0))
1601                  (match_operand:SI 2 "register_operand" "")))
1602    (clobber (reg:CC 100))]
1603   ""
1604   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1605                                            (const_int 0)))
1606    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1607                                (match_dup 2)))]
1608   "")
1609
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")
1614                          (const_int 0))))
1615    (clobber (reg:CC 100))]
1616   ""
1617   "#"
1618   [(set_attr "length" "2")])
1619
1620 (define_split
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" "")
1624                          (const_int 0))))
1625    (clobber (reg:CC 100))]
1626   ""
1627   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1628                                            (const_int 0)))
1629    (set (match_dup 0) (minus:SI (match_dup 2)
1630                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1631   "")
1632
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")
1636                         (const_int 0))
1637                  (match_operand:SI 2 "register_operand" "r")))
1638    (clobber (reg:CC 100))]
1639   ""
1640   "#"
1641   [(set_attr "length" "2")])
1642
1643 (define_split
1644   [(set (match_operand:SI 0 "register_operand" "")
1645         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1646                         (const_int 0))
1647                  (match_operand:SI 2 "register_operand" "")))
1648    (clobber (reg:CC 100))]
1649   ""
1650   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1651                                            (const_int 0)))
1652    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1653                                (match_dup 2)))]
1654   "")
1655
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")
1660                          (const_int 0))))
1661    (clobber (reg:CC 100))]
1662   ""
1663   "#"
1664   [(set_attr "length" "2")])
1665
1666 (define_split
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" "")
1670                          (const_int 0))))
1671    (clobber (reg:CC 100))]
1672   ""
1673   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1674                                            (const_int 0)))
1675    (set (match_dup 0) (minus:SI (match_dup 2)
1676                                 (geu:SI (reg:CC 100) (const_int 0))))]
1677   "")
1678
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
1681 ;; versions for v9.
1682
1683 (define_insn "*sltu_insn"
1684   [(set (match_operand:SI 0 "register_operand" "=r")
1685         (ltu:SI (reg:CC 100) (const_int 0)))]
1686   ""
1687   "addx\\t%%g0, 0, %0"
1688   [(set_attr "type" "misc")])
1689
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))))]
1693   ""
1694   "subx\\t%%g0, 0, %0"
1695   [(set_attr "type" "misc")])
1696
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")))]
1702   ""
1703   "subx\\t%%g0, %1, %0"
1704   [(set_attr "type" "misc")])
1705
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"))))]
1710   ""
1711   "subx\\t%%g0, %1, %0"
1712   [(set_attr "type" "misc")])
1713
1714 (define_insn "*sgeu_insn"
1715   [(set (match_operand:SI 0 "register_operand" "=r")
1716         (geu:SI (reg:CC 100) (const_int 0)))]
1717   ""
1718   "subx\\t%%g0, -1, %0"
1719   [(set_attr "type" "misc")])
1720
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))))]
1724   ""
1725   "addx\\t%%g0, -1, %0"
1726   [(set_attr "type" "misc")])
1727
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
1730 ;; versions for v9.
1731
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")))]
1736   ""
1737   "addx\\t%%g0, %1, %0"
1738   [(set_attr "type" "misc")])
1739
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"))))]
1745   ""
1746   "addx\\t%1, %2, %0"
1747   [(set_attr "type" "misc")])
1748
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))))]
1753   ""
1754   "subx\\t%1, 0, %0"
1755   [(set_attr "type" "misc")])
1756
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))))]
1763   ""
1764   "subx\\t%r1, %2, %0"
1765   [(set_attr "type" "misc")])
1766
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"))))]
1772   ""
1773   "subx\\t%r1, %2, %0"
1774   [(set_attr "type" "misc")])
1775
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")))]
1780   ""
1781   "subx\\t%1, -1, %0"
1782   [(set_attr "type" "misc")])
1783
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))))]
1788   ""
1789   "addx\\t%1, -1, %0"
1790   [(set_attr "type" "misc")])
1791
1792 (define_split
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" "")
1796                             (const_int 0)]))]
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))
1802    (set (match_dup 0)
1803         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1804                          (const_int 1)
1805                          (match_dup 0)))]
1806   "")
1807
1808 \f
1809 ;; These control RTL generation for conditional jump insns
1810
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.
1814
1815 (define_expand "beq"
1816   [(set (pc)
1817         (if_then_else (eq (match_dup 1) (const_int 0))
1818                       (label_ref (match_operand 0 "" ""))
1819                       (pc)))]
1820   ""
1821   "
1822 {
1823   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1824       && GET_CODE (sparc_compare_op0) == REG
1825       && GET_MODE (sparc_compare_op0) == DImode)
1826     {
1827       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1828       DONE;
1829     }
1830   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1831     {
1832       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1833       emit_jump_insn (gen_bne (operands[0]));
1834       DONE;
1835     }
1836   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1837 }")
1838
1839 (define_expand "bne"
1840   [(set (pc)
1841         (if_then_else (ne (match_dup 1) (const_int 0))
1842                       (label_ref (match_operand 0 "" ""))
1843                       (pc)))]
1844   ""
1845   "
1846 {
1847   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1848       && GET_CODE (sparc_compare_op0) == REG
1849       && GET_MODE (sparc_compare_op0) == DImode)
1850     {
1851       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1852       DONE;
1853     }
1854   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1855     {
1856       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1857       emit_jump_insn (gen_bne (operands[0]));
1858       DONE;
1859     }
1860   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1861 }")
1862
1863 (define_expand "bgt"
1864   [(set (pc)
1865         (if_then_else (gt (match_dup 1) (const_int 0))
1866                       (label_ref (match_operand 0 "" ""))
1867                       (pc)))]
1868   ""
1869   "
1870 {
1871   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1872       && GET_CODE (sparc_compare_op0) == REG
1873       && GET_MODE (sparc_compare_op0) == DImode)
1874     {
1875       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1876       DONE;
1877     }
1878   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1879     {
1880       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1881       emit_jump_insn (gen_bne (operands[0]));
1882       DONE;
1883     }
1884   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1885 }")
1886
1887 (define_expand "bgtu"
1888   [(set (pc)
1889         (if_then_else (gtu (match_dup 1) (const_int 0))
1890                       (label_ref (match_operand 0 "" ""))
1891                       (pc)))]
1892   ""
1893   "
1894 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1895 }")
1896
1897 (define_expand "blt"
1898   [(set (pc)
1899         (if_then_else (lt (match_dup 1) (const_int 0))
1900                       (label_ref (match_operand 0 "" ""))
1901                       (pc)))]
1902   ""
1903   "
1904 {
1905   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1906       && GET_CODE (sparc_compare_op0) == REG
1907       && GET_MODE (sparc_compare_op0) == DImode)
1908     {
1909       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1910       DONE;
1911     }
1912   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1913     {
1914       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1915       emit_jump_insn (gen_bne (operands[0]));
1916       DONE;
1917     }
1918   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1919 }")
1920
1921 (define_expand "bltu"
1922   [(set (pc)
1923         (if_then_else (ltu (match_dup 1) (const_int 0))
1924                       (label_ref (match_operand 0 "" ""))
1925                       (pc)))]
1926   ""
1927   "
1928 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1929 }")
1930
1931 (define_expand "bge"
1932   [(set (pc)
1933         (if_then_else (ge (match_dup 1) (const_int 0))
1934                       (label_ref (match_operand 0 "" ""))
1935                       (pc)))]
1936   ""
1937   "
1938 {
1939   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1940       && GET_CODE (sparc_compare_op0) == REG
1941       && GET_MODE (sparc_compare_op0) == DImode)
1942     {
1943       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1944       DONE;
1945     }
1946   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1947     {
1948       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1949       emit_jump_insn (gen_bne (operands[0]));
1950       DONE;
1951     }
1952   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1953 }")
1954
1955 (define_expand "bgeu"
1956   [(set (pc)
1957         (if_then_else (geu (match_dup 1) (const_int 0))
1958                       (label_ref (match_operand 0 "" ""))
1959                       (pc)))]
1960   ""
1961   "
1962 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1963 }")
1964
1965 (define_expand "ble"
1966   [(set (pc)
1967         (if_then_else (le (match_dup 1) (const_int 0))
1968                       (label_ref (match_operand 0 "" ""))
1969                       (pc)))]
1970   ""
1971   "
1972 {
1973   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1974       && GET_CODE (sparc_compare_op0) == REG
1975       && GET_MODE (sparc_compare_op0) == DImode)
1976     {
1977       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1978       DONE;
1979     }
1980   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1981     {
1982       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1983       emit_jump_insn (gen_bne (operands[0]));
1984       DONE;
1985     }
1986   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1987 }")
1988
1989 (define_expand "bleu"
1990   [(set (pc)
1991         (if_then_else (leu (match_dup 1) (const_int 0))
1992                       (label_ref (match_operand 0 "" ""))
1993                       (pc)))]
1994   ""
1995   "
1996 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1997 }")
1998
1999 (define_expand "bunordered"
2000   [(set (pc)
2001         (if_then_else (unordered (match_dup 1) (const_int 0))
2002                       (label_ref (match_operand 0 "" ""))
2003                       (pc)))]
2004   ""
2005   "
2006 {
2007   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2008     {
2009       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
2010                                 UNORDERED);
2011       emit_jump_insn (gen_beq (operands[0]));
2012       DONE;
2013     }
2014   operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
2015                                  sparc_compare_op1);
2016 }")
2017
2018 (define_expand "bordered"
2019   [(set (pc)
2020         (if_then_else (ordered (match_dup 1) (const_int 0))
2021                       (label_ref (match_operand 0 "" ""))
2022                       (pc)))]
2023   ""
2024   "
2025 {
2026   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2027     {
2028       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
2029       emit_jump_insn (gen_bne (operands[0]));
2030       DONE;
2031     }
2032   operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
2033                                  sparc_compare_op1);
2034 }")
2035
2036 (define_expand "bungt"
2037   [(set (pc)
2038         (if_then_else (ungt (match_dup 1) (const_int 0))
2039                       (label_ref (match_operand 0 "" ""))
2040                       (pc)))]
2041   ""
2042   "
2043 {
2044   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2045     {
2046       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
2047       emit_jump_insn (gen_bgt (operands[0]));
2048       DONE;
2049     }
2050   operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
2051 }")
2052
2053 (define_expand "bunlt"
2054   [(set (pc)
2055         (if_then_else (unlt (match_dup 1) (const_int 0))
2056                       (label_ref (match_operand 0 "" ""))
2057                       (pc)))]
2058   ""
2059   "
2060 {
2061   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2062     {
2063       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
2064       emit_jump_insn (gen_bne (operands[0]));
2065       DONE;
2066     }
2067   operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
2068 }")
2069
2070 (define_expand "buneq"
2071   [(set (pc)
2072         (if_then_else (uneq (match_dup 1) (const_int 0))
2073                       (label_ref (match_operand 0 "" ""))
2074                       (pc)))]
2075   ""
2076   "
2077 {
2078   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2079     {
2080       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
2081       emit_jump_insn (gen_beq (operands[0]));
2082       DONE;
2083     }
2084   operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
2085 }")
2086
2087 (define_expand "bunge"
2088   [(set (pc)
2089         (if_then_else (unge (match_dup 1) (const_int 0))
2090                       (label_ref (match_operand 0 "" ""))
2091                       (pc)))]
2092   ""
2093   "
2094 {
2095   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2096     {
2097       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
2098       emit_jump_insn (gen_bne (operands[0]));
2099       DONE;
2100     }
2101   operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
2102 }")
2103
2104 (define_expand "bunle"
2105   [(set (pc)
2106         (if_then_else (unle (match_dup 1) (const_int 0))
2107                       (label_ref (match_operand 0 "" ""))
2108                       (pc)))]
2109   ""
2110   "
2111 {
2112   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2113     {
2114       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
2115       emit_jump_insn (gen_bne (operands[0]));
2116       DONE;
2117     }
2118   operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
2119 }")
2120
2121 (define_expand "bltgt"
2122   [(set (pc)
2123         (if_then_else (ltgt (match_dup 1) (const_int 0))
2124                       (label_ref (match_operand 0 "" ""))
2125                       (pc)))]
2126   ""
2127   "
2128 {
2129   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2130     {
2131       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
2132       emit_jump_insn (gen_bne (operands[0]));
2133       DONE;
2134     }
2135   operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
2136 }")
2137 \f
2138 ;; Now match both normal and inverted jump.
2139
2140 ;; XXX fpcmp nop braindamage
2141 (define_insn "*normal_branch"
2142   [(set (pc)
2143         (if_then_else (match_operator 0 "noov_compare_op"
2144                                       [(reg 100) (const_int 0)])
2145                       (label_ref (match_operand 1 "" ""))
2146                       (pc)))]
2147   ""
2148   "*
2149 {
2150   return output_cbranch (operands[0], operands[1], 1, 0,
2151                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2152                          ! final_sequence, insn);
2153 }"
2154   [(set_attr "type" "branch")
2155    (set_attr "branch_type" "icc")])
2156
2157 ;; XXX fpcmp nop braindamage
2158 (define_insn "*inverted_branch"
2159   [(set (pc)
2160         (if_then_else (match_operator 0 "noov_compare_op"
2161                                       [(reg 100) (const_int 0)])
2162                       (pc)
2163                       (label_ref (match_operand 1 "" ""))))]
2164   ""
2165   "*
2166 {
2167   return output_cbranch (operands[0], operands[1], 1, 1,
2168                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2169                          ! final_sequence, insn);
2170 }"
2171   [(set_attr "type" "branch")
2172    (set_attr "branch_type" "icc")])
2173
2174 ;; XXX fpcmp nop braindamage
2175 (define_insn "*normal_fp_branch"
2176   [(set (pc)
2177         (if_then_else (match_operator 1 "comparison_operator"
2178                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2179                                        (const_int 0)])
2180                       (label_ref (match_operand 2 "" ""))
2181                       (pc)))]
2182   ""
2183   "*
2184 {
2185   return output_cbranch (operands[1], operands[2], 2, 0,
2186                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2187                          ! final_sequence, insn);
2188 }"
2189   [(set_attr "type" "branch")
2190    (set_attr "branch_type" "fcc")])
2191
2192 ;; XXX fpcmp nop braindamage
2193 (define_insn "*inverted_fp_branch"
2194   [(set (pc)
2195         (if_then_else (match_operator 1 "comparison_operator"
2196                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2197                                        (const_int 0)])
2198                       (pc)
2199                       (label_ref (match_operand 2 "" ""))))]
2200   ""
2201   "*
2202 {
2203   return output_cbranch (operands[1], operands[2], 2, 1,
2204                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2205                          ! final_sequence, insn);
2206 }"
2207   [(set_attr "type" "branch")
2208    (set_attr "branch_type" "fcc")])
2209
2210 ;; XXX fpcmp nop braindamage
2211 (define_insn "*normal_fpe_branch"
2212   [(set (pc)
2213         (if_then_else (match_operator 1 "comparison_operator"
2214                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2215                                        (const_int 0)])
2216                       (label_ref (match_operand 2 "" ""))
2217                       (pc)))]
2218   ""
2219   "*
2220 {
2221   return output_cbranch (operands[1], operands[2], 2, 0,
2222                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2223                          ! final_sequence, insn);
2224 }"
2225   [(set_attr "type" "branch")
2226    (set_attr "branch_type" "fcc")])
2227
2228 ;; XXX fpcmp nop braindamage
2229 (define_insn "*inverted_fpe_branch"
2230   [(set (pc)
2231         (if_then_else (match_operator 1 "comparison_operator"
2232                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2233                                        (const_int 0)])
2234                       (pc)
2235                       (label_ref (match_operand 2 "" ""))))]
2236   ""
2237   "*
2238 {
2239   return output_cbranch (operands[1], operands[2], 2, 1,
2240                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2241                          ! final_sequence, insn);
2242 }"
2243   [(set_attr "type" "branch")
2244    (set_attr "branch_type" "fcc")])
2245
2246 ;; Sparc V9-specific jump insns.  None of these are guaranteed to be
2247 ;; in the architecture.
2248
2249 ;; There are no 32 bit brreg insns.
2250
2251 ;; XXX
2252 (define_insn "*normal_int_branch_sp64"
2253   [(set (pc)
2254         (if_then_else (match_operator 0 "v9_regcmp_op"
2255                                       [(match_operand:DI 1 "register_operand" "r")
2256                                        (const_int 0)])
2257                       (label_ref (match_operand 2 "" ""))
2258                       (pc)))]
2259   "TARGET_ARCH64"
2260   "*
2261 {
2262   return output_v9branch (operands[0], operands[2], 1, 2, 0,
2263                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2264                           ! final_sequence, insn);
2265 }"
2266   [(set_attr "type" "branch")
2267    (set_attr "branch_type" "reg")])
2268
2269 ;; XXX
2270 (define_insn "*inverted_int_branch_sp64"
2271   [(set (pc)
2272         (if_then_else (match_operator 0 "v9_regcmp_op"
2273                                       [(match_operand:DI 1 "register_operand" "r")
2274                                        (const_int 0)])
2275                       (pc)
2276                       (label_ref (match_operand 2 "" ""))))]
2277   "TARGET_ARCH64"
2278   "*
2279 {
2280   return output_v9branch (operands[0], operands[2], 1, 2, 1,
2281                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2282                           ! final_sequence, insn);
2283 }"
2284   [(set_attr "type" "branch")
2285    (set_attr "branch_type" "reg")])
2286 \f
2287 ;; Load program counter insns.
2288
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")])
2297
2298 ;; Currently unused...
2299 ;; (define_insn "get_pc_via_rdpc"
2300 ;;   [(set (match_operand 0 "register_operand" "=r") (pc))]
2301 ;;   "TARGET_V9"
2302 ;;   "rd\\t%%pc, %0"
2303 ;;   [(set_attr "type" "misc")])
2304
2305 \f
2306 ;; Move instructions
2307
2308 (define_expand "movqi"
2309   [(set (match_operand:QI 0 "general_operand" "")
2310         (match_operand:QI 1 "general_operand" ""))]
2311   ""
2312   "
2313 {
2314   /* Working with CONST_INTs is easier, so convert
2315      a double if needed.  */
2316   if (GET_CODE (operands[1]) == CONST_DOUBLE)
2317     {
2318       operands[1] = GEN_INT (trunc_int_for_mode
2319                              (CONST_DOUBLE_LOW (operands[1]), QImode));
2320     }
2321
2322   /* Handle sets of MEM first.  */
2323   if (GET_CODE (operands[0]) == MEM)
2324     {
2325       if (reg_or_0_operand (operands[1], QImode))
2326         goto movqi_is_ok;
2327
2328       if (! reload_in_progress)
2329         {
2330           operands[0] = validize_mem (operands[0]);
2331           operands[1] = force_reg (QImode, operands[1]);
2332         }
2333     }
2334
2335   /* Fixup PIC cases.  */
2336   if (flag_pic)
2337     {
2338       if (CONSTANT_P (operands[1])
2339           && pic_address_needs_scratch (operands[1]))
2340         operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2341
2342       if (symbolic_operand (operands[1], QImode))
2343         {
2344           operands[1] = legitimize_pic_address (operands[1],
2345                                                 QImode,
2346                                                 (reload_in_progress ?
2347                                                  operands[0] :
2348                                                  NULL_RTX));
2349           goto movqi_is_ok;
2350         }
2351     }
2352
2353   /* All QI constants require only one insn, so proceed.  */
2354
2355  movqi_is_ok:
2356   ;
2357 }")
2358
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))"
2364   "@
2365    mov\\t%1, %0
2366    ldub\\t%1, %0
2367    stb\\t%r1, %0"
2368   [(set_attr "type" "*,load,store")
2369    (set_attr "us3load_type" "*,3cycle,*")])
2370
2371 (define_expand "movhi"
2372   [(set (match_operand:HI 0 "general_operand" "")
2373         (match_operand:HI 1 "general_operand" ""))]
2374   ""
2375   "
2376 {
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]));
2381
2382   /* Handle sets of MEM first.  */
2383   if (GET_CODE (operands[0]) == MEM)
2384     {
2385       if (reg_or_0_operand (operands[1], HImode))
2386         goto movhi_is_ok;
2387
2388       if (! reload_in_progress)
2389         {
2390           operands[0] = validize_mem (operands[0]);
2391           operands[1] = force_reg (HImode, operands[1]);
2392         }
2393     }
2394
2395   /* Fixup PIC cases.  */
2396   if (flag_pic)
2397     {
2398       if (CONSTANT_P (operands[1])
2399           && pic_address_needs_scratch (operands[1]))
2400         operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2401
2402       if (symbolic_operand (operands[1], HImode))
2403         {
2404           operands[1] = legitimize_pic_address (operands[1],
2405                                                 HImode,
2406                                                 (reload_in_progress ?
2407                                                  operands[0] :
2408                                                  NULL_RTX));
2409           goto movhi_is_ok;
2410         }
2411     }
2412
2413   /* This makes sure we will not get rematched due to splittage.  */
2414   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2415     ;
2416   else if (CONSTANT_P (operands[1])
2417            && GET_CODE (operands[1]) != HIGH
2418            && GET_CODE (operands[1]) != LO_SUM)
2419     {
2420       sparc_emit_set_const32 (operands[0], operands[1]);
2421       DONE;
2422     }
2423  movhi_is_ok:
2424   ;
2425 }")
2426
2427 (define_insn "*movhi_const64_special"
2428   [(set (match_operand:HI 0 "register_operand" "=r")
2429         (match_operand:HI 1 "const64_high_operand" ""))]
2430   "TARGET_ARCH64"
2431   "sethi\\t%%hi(%a1), %0")
2432
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))"
2438   "@
2439    mov\\t%1, %0
2440    sethi\\t%%hi(%a1), %0
2441    lduh\\t%1, %0
2442    sth\\t%r1, %0"
2443   [(set_attr "type" "*,*,load,store")
2444    (set_attr "us3load_type" "*,*,3cycle,*")])
2445
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")))]
2451   ""
2452   "or\\t%1, %2, %0")
2453
2454 (define_expand "movsi"
2455   [(set (match_operand:SI 0 "general_operand" "")
2456         (match_operand:SI 1 "general_operand" ""))]
2457   ""
2458   "
2459 {
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]));
2464
2465   /* Handle sets of MEM first.  */
2466   if (GET_CODE (operands[0]) == MEM)
2467     {
2468       if (reg_or_0_operand (operands[1], SImode))
2469         goto movsi_is_ok;
2470
2471       if (! reload_in_progress)
2472         {
2473           operands[0] = validize_mem (operands[0]);
2474           operands[1] = force_reg (SImode, operands[1]);
2475         }
2476     }
2477
2478   /* Fixup PIC cases.  */
2479   if (flag_pic)
2480     {
2481       if (CONSTANT_P (operands[1])
2482           && pic_address_needs_scratch (operands[1]))
2483         operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2484
2485       if (GET_CODE (operands[1]) == LABEL_REF)
2486         {
2487           /* shit */
2488           emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2489           DONE;
2490         }
2491
2492       if (symbolic_operand (operands[1], SImode))
2493         {
2494           operands[1] = legitimize_pic_address (operands[1],
2495                                                 SImode,
2496                                                 (reload_in_progress ?
2497                                                  operands[0] :
2498                                                  NULL_RTX));
2499           goto movsi_is_ok;
2500         }
2501     }
2502
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]),
2510                                                  operands[1]));
2511
2512   /* This makes sure we will not get rematched due to splittage.  */
2513   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2514     ;
2515   else if (CONSTANT_P (operands[1])
2516            && GET_CODE (operands[1]) != HIGH
2517            && GET_CODE (operands[1]) != LO_SUM)
2518     {
2519       sparc_emit_set_const32 (operands[0], operands[1]);
2520       DONE;
2521     }
2522  movsi_is_ok:
2523   ;
2524 }")
2525
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" ""))]
2531   "TARGET_ARCH64"
2532   "sethi\\t%%hi(%a1), %0")
2533
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))"
2539   "@
2540    mov\\t%1, %0
2541    fmovs\\t%1, %0
2542    sethi\\t%%hi(%a1), %0
2543    clr\\t%0
2544    ld\\t%1, %0
2545    ld\\t%1, %0
2546    st\\t%r1, %0
2547    st\\t%1, %0
2548    fzeros\\t%0"
2549   [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2550
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")))]
2555   ""
2556   "or\\t%1, %%lo(%a2), %0")
2557
2558 (define_insn "*movsi_high"
2559   [(set (match_operand:SI 0 "register_operand" "=r")
2560         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2561   ""
2562   "sethi\\t%%hi(%a1), %0")
2563
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)))]
2570   "flag_pic"
2571   "or\\t%1, %%lo(%a2), %0")
2572
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")
2578
2579 (define_expand "movsi_pic_label_ref"
2580   [(set (match_dup 3) (high:SI
2581      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2582                  (match_dup 2)] 5)))
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)))]
2587   "flag_pic"
2588   "
2589 {
2590   current_function_uses_pic_offset_table = 1;
2591   operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2592   if (no_new_pseudos)
2593     {
2594       operands[3] = operands[0];
2595       operands[4] = operands[0];
2596     }
2597   else
2598     {
2599       operands[3] = gen_reg_rtx (SImode);
2600       operands[4] = gen_reg_rtx (SImode);
2601     }
2602   operands[5] = pic_offset_table_rtx;
2603 }")
2604
2605 (define_insn "*movsi_high_pic_label_ref"
2606   [(set (match_operand:SI 0 "register_operand" "=r")
2607       (high:SI
2608         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2609                     (match_operand:SI 2 "" "")] 5)))]
2610   "flag_pic"
2611   "sethi\\t%%hi(%a2-(%a1-.)), %0")
2612
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)))]
2618   "flag_pic"
2619   "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2620
2621 (define_expand "movdi"
2622   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2623         (match_operand:DI 1 "general_operand" ""))]
2624   ""
2625   "
2626 {
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))
2634 #endif
2635       )
2636     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2637
2638   /* Handle MEM cases first.  */
2639   if (GET_CODE (operands[0]) == MEM)
2640     {
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)
2645           || (TARGET_V9
2646               && (operands[1] == const0_rtx)))
2647         goto movdi_is_ok;
2648
2649       if (! reload_in_progress)
2650         {
2651           operands[0] = validize_mem (operands[0]);
2652           operands[1] = force_reg (DImode, operands[1]);
2653         }
2654     }
2655
2656   if (flag_pic)
2657     {
2658       if (CONSTANT_P (operands[1])
2659           && pic_address_needs_scratch (operands[1]))
2660         operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2661
2662       if (GET_CODE (operands[1]) == LABEL_REF)
2663         {
2664           if (! TARGET_ARCH64)
2665             abort ();
2666           emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2667           DONE;
2668         }
2669
2670       if (symbolic_operand (operands[1], DImode))
2671         {
2672           operands[1] = legitimize_pic_address (operands[1],
2673                                                 DImode,
2674                                                 (reload_in_progress ?
2675                                                  operands[0] :
2676                                                  NULL_RTX));
2677           goto movdi_is_ok;
2678         }
2679     }
2680
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]),
2688                                                  operands[1]));
2689
2690   /* This makes sure we will not get rematched due to splittage.  */
2691   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2692     ;
2693   else if (TARGET_ARCH64
2694            && CONSTANT_P (operands[1])
2695            && GET_CODE (operands[1]) != HIGH
2696            && GET_CODE (operands[1]) != LO_SUM)
2697     {
2698       sparc_emit_set_const64 (operands[0], operands[1]);
2699       DONE;
2700     }
2701
2702  movdi_is_ok:
2703   ;
2704 }")
2705
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
2711 ;; of the form:
2712 ;;
2713 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2714 ;;                       (const_int -5016)))
2715 ;;      (reg:DI 2 %g2))
2716 ;;
2717
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)"
2725   "@
2726    stx\\t%%g0, %0
2727    #
2728    std\\t%1, %0
2729    ldd\\t%1, %0
2730    #
2731    #
2732    #
2733    #
2734    std\\t%1, %0
2735    ldd\\t%1, %0
2736    #
2737    #
2738    #"
2739   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2740    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2741
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"))]
2747   "! TARGET_ARCH64
2748    && (register_operand (operands[0], DImode)
2749        || register_operand (operands[1], DImode))"
2750   "@
2751    #
2752    std\\t%1, %0
2753    ldd\\t%1, %0
2754    #
2755    #
2756    #
2757    #
2758    std\\t%1, %0
2759    ldd\\t%1, %0
2760    #
2761    #
2762    #"
2763   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2764    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2765
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" ""))]
2770   "(TARGET_ARCH64
2771     && HOST_BITS_PER_WIDE_INT != 64)"
2772   "mov\\t%1, %0")
2773
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" ""))]
2779   "TARGET_ARCH64"
2780   "sethi\\t%%hi(%a1), %0")
2781
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))"
2788   "@
2789    mov\\t%1, %0
2790    sethi\\t%%hi(%a1), %0
2791    clr\\t%0
2792    ldx\\t%1, %0
2793    stx\\t%r1, %0
2794    fmovd\\t%1, %0
2795    ldd\\t%1, %0
2796    std\\t%1, %0"
2797   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2798    (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2799
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))"
2806   "@
2807    mov\\t%1, %0
2808    sethi\\t%%hi(%a1), %0
2809    clr\\t%0
2810    ldx\\t%1, %0
2811    stx\\t%r1, %0
2812    fmovd\\t%1, %0
2813    ldd\\t%1, %0
2814    std\\t%1, %0
2815    fzero\\t%0"
2816   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2817    (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2818
2819 (define_expand "movdi_pic_label_ref"
2820   [(set (match_dup 3) (high:DI
2821      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2822                  (match_dup 2)] 5)))
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"
2828   "
2829 {
2830   current_function_uses_pic_offset_table = 1;
2831   operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2832   if (no_new_pseudos)
2833     {
2834       operands[3] = operands[0];
2835       operands[4] = operands[0];
2836     }
2837   else
2838     {
2839       operands[3] = gen_reg_rtx (DImode);
2840       operands[4] = gen_reg_rtx (DImode);
2841     }
2842   operands[5] = pic_offset_table_rtx;
2843 }")
2844
2845 (define_insn "*movdi_high_pic_label_ref"
2846   [(set (match_operand:DI 0 "register_operand" "=r")
2847         (high:DI
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")
2852
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")
2860
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.
2863
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")
2870
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")
2876
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")
2882
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")
2888
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" "")))]
2893   "TARGET_CM_MEDLOW"
2894   "or\\t%1, %%lo(%a2), %0")
2895
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)))]
2899   "TARGET_CM_MEDMID"
2900   "sethi\\t%%h44(%a1), %0")
2901
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)))]
2906   "TARGET_CM_MEDMID"
2907   "or\\t%1, %%m44(%a2), %0")
2908
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" "")))]
2913   "TARGET_CM_MEDMID"
2914   "or\\t%1, %%l44(%a2), %0")
2915
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)))]
2919   "TARGET_CM_MEDANY"
2920   "sethi\\t%%hh(%a1), %0")
2921
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)))]
2925   "TARGET_CM_MEDANY"
2926   "sethi\\t%%lm(%a1), %0")
2927
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)))]
2932   "TARGET_CM_MEDANY"
2933   "or\\t%1, %%hm(%a2), %0")
2934
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" "")))]
2939   "TARGET_CM_MEDANY"
2940   "or\\t%1, %%lo(%a2), %0")
2941
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")
2947
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")
2954
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"
2959   "add\\t%1, %_, %0")
2960
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")
2966
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")
2972
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")
2979
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")
2986
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")])]
2992   "(TARGET_CM_MEDANY
2993     || TARGET_CM_EMBMEDANY)
2994    && ! flag_pic"
2995   "
2996 {
2997   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2998   DONE;
2999 }")
3000
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")])]
3005   "(TARGET_CM_MEDANY
3006     || TARGET_CM_EMBMEDANY)
3007    && ! flag_pic"
3008   "
3009 {
3010   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
3011   DONE;
3012 }")
3013
3014 ;; Split up putting CONSTs and REGs into DI regs when !arch64
3015 (define_split
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))]
3020   "
3021 {
3022 #if HOST_BITS_PER_WIDE_INT == 32
3023   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3024                         (INTVAL (operands[1]) < 0) ?
3025                         constm1_rtx :
3026                         const0_rtx));
3027   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3028                         operands[1]));
3029 #else
3030   unsigned int low, high;
3031
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)));
3035
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])));
3041   else
3042     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
3043 #endif
3044   DONE;
3045 }")
3046
3047 (define_split
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))]
3052   "
3053 {
3054   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3055                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
3056
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]))))
3062     {
3063       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3064                             gen_highpart (SImode, operands[0])));
3065     }
3066   else
3067     {
3068       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3069                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
3070     }
3071   DONE;
3072 }")
3073
3074 (define_split
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))]
3079   "
3080 {
3081   rtx set_dest = operands[0];
3082   rtx set_src = operands[1];
3083   rtx dest1, dest2;
3084   rtx src1, src2;
3085
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);
3090
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))
3094     {
3095       emit_insn (gen_movsi (dest2, src2));
3096       emit_insn (gen_movsi (dest1, src1));
3097     }
3098   else
3099     {
3100       emit_insn (gen_movsi (dest1, src1));
3101       emit_insn (gen_movsi (dest2, src2));
3102     }
3103   DONE;
3104 }")
3105
3106 ;; Now handle the cases of memory moves from/to non-even
3107 ;; DI mode register pairs.
3108 (define_split
3109   [(set (match_operand:DI 0 "register_operand" "")
3110         (match_operand:DI 1 "memory_operand" ""))]
3111   "(! TARGET_ARCH64
3112     && reload_completed
3113     && sparc_splitdi_legitimate (operands[0], operands[1]))"
3114   [(clobber (const_int 0))]
3115   "
3116 {
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]);
3121
3122   if (reg_overlap_mentioned_p (high_part, word1))
3123     {
3124       emit_insn (gen_movsi (low_part, word1));
3125       emit_insn (gen_movsi (high_part, word0));
3126     }
3127   else
3128     {
3129       emit_insn (gen_movsi (high_part, word0));
3130       emit_insn (gen_movsi (low_part, word1));
3131     }
3132   DONE;
3133 }")
3134
3135 (define_split
3136   [(set (match_operand:DI 0 "memory_operand" "")
3137         (match_operand:DI 1 "register_operand" ""))]
3138   "(! TARGET_ARCH64
3139     && reload_completed
3140     && sparc_splitdi_legitimate (operands[1], operands[0]))"
3141   [(clobber (const_int 0))]
3142   "
3143 {
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])));
3148   DONE;
3149 }")
3150
3151 (define_split
3152   [(set (match_operand:DI 0 "memory_operand" "")
3153         (const_int 0))]
3154   "reload_completed
3155    && (! TARGET_V9
3156        || (! TARGET_ARCH64
3157            && ! mem_min_alignment (operands[0], 8)))
3158    && offsettable_memref_p (operands[0])"
3159   [(clobber (const_int 0))]
3160   "
3161 {
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));
3164   DONE;
3165 }")
3166 \f
3167 ;; Floating point move insns
3168
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))"
3176   "*
3177 {
3178   if (GET_CODE (operands[1]) == CONST_DOUBLE
3179       && (which_alternative == 2
3180           || which_alternative == 3
3181           || which_alternative == 4))
3182     {
3183       REAL_VALUE_TYPE r;
3184       long i;
3185
3186       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3187       REAL_VALUE_TO_TARGET_SINGLE (r, i);
3188       operands[1] = GEN_INT (i);
3189     }
3190
3191   switch (which_alternative)
3192     {
3193     case 0:
3194       return \"fmovs\\t%1, %0\";
3195     case 1:
3196       return \"clr\\t%0\";
3197     case 2:
3198       return \"sethi\\t%%hi(%a1), %0\";
3199     case 3:
3200       return \"mov\\t%1, %0\";
3201     case 4:
3202       return \"#\";
3203     case 5:
3204     case 6:
3205       return \"ld\\t%1, %0\";
3206     case 7:
3207     case 8:
3208       return \"st\\t%r1, %0\";
3209     default:
3210       abort();
3211     }
3212 }"
3213   [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
3214
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))"
3222   "*
3223 {
3224   if (GET_CODE (operands[1]) == CONST_DOUBLE
3225       && (which_alternative == 3
3226           || which_alternative == 4
3227           || which_alternative == 5))
3228     {
3229       REAL_VALUE_TYPE r;
3230       long i;
3231
3232       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3233       REAL_VALUE_TO_TARGET_SINGLE (r, i);
3234       operands[1] = GEN_INT (i);
3235     }
3236
3237   switch (which_alternative)
3238     {
3239     case 0:
3240       return \"fmovs\\t%1, %0\";
3241     case 1:
3242       return \"fzeros\\t%0\";
3243     case 2:
3244       return \"clr\\t%0\";
3245     case 3:
3246       return \"sethi\\t%%hi(%a1), %0\";
3247     case 4:
3248       return \"mov\\t%1, %0\";
3249     case 5:
3250       return \"#\";
3251     case 6:
3252     case 7:
3253       return \"ld\\t%1, %0\";
3254     case 8:
3255     case 9:
3256       return \"st\\t%r1, %0\";
3257     default:
3258       abort();
3259     }
3260 }"
3261   [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
3262
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
3265 ;; when -mno-fpu.
3266
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"))]
3270   "! TARGET_FPU
3271    && (register_operand (operands[0], SFmode)
3272        || register_operand (operands[1], SFmode)
3273        || fp_zero_operand (operands[1], SFmode))"
3274   "*
3275 {
3276   if (GET_CODE (operands[1]) == CONST_DOUBLE
3277       && (which_alternative == 1
3278           || which_alternative == 2
3279           || which_alternative == 3))
3280     {
3281       REAL_VALUE_TYPE r;
3282       long i;
3283
3284       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3285       REAL_VALUE_TO_TARGET_SINGLE (r, i);
3286       operands[1] = GEN_INT (i);
3287     }
3288
3289   switch (which_alternative)
3290     {
3291     case 0:
3292       return \"clr\\t%0\";
3293     case 1:
3294       return \"sethi\\t%%hi(%a1), %0\";
3295     case 2:
3296       return \"mov\\t%1, %0\";
3297     case 3:
3298       return \"#\";
3299     case 4:
3300       return \"ld\\t%1, %0\";
3301     case 5:
3302       return \"st\\t%r1, %0\";
3303     default:
3304       abort();
3305     }
3306 }"
3307   [(set_attr "type" "*,*,*,*,load,store")])
3308
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])"
3314   "*
3315 {
3316   REAL_VALUE_TYPE r;
3317   long i;
3318
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\";
3323 }")
3324
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])"
3329   "*
3330 {
3331   REAL_VALUE_TYPE r;
3332   long i;
3333
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\";
3338 }")
3339
3340 (define_split
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)))])
3348
3349 (define_expand "movsf"
3350   [(set (match_operand:SF 0 "general_operand" "")
3351         (match_operand:SF 1 "general_operand" ""))]
3352   ""
3353   "
3354 {
3355   /* Force SFmode constants into memory.  */
3356   if (GET_CODE (operands[0]) == REG
3357       && CONSTANT_P (operands[1]))
3358     {
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);
3364
3365       if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3366         goto movsf_is_ok;
3367
3368       /* We are able to build any SF constant in integer registers
3369          with at most 2 instructions.  */
3370       if (REGNO (operands[0]) < 32)
3371         goto movsf_is_ok;
3372
3373       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3374                                                    operands[1]));
3375     }
3376
3377   /* Handle sets of MEM first.  */
3378   if (GET_CODE (operands[0]) == MEM)
3379     {
3380       if (register_operand (operands[1], SFmode)
3381           || fp_zero_operand (operands[1], SFmode))
3382         goto movsf_is_ok;
3383
3384       if (! reload_in_progress)
3385         {
3386           operands[0] = validize_mem (operands[0]);
3387           operands[1] = force_reg (SFmode, operands[1]);
3388         }
3389     }
3390
3391   /* Fixup PIC cases.  */
3392   if (flag_pic)
3393     {
3394       if (CONSTANT_P (operands[1])
3395           && pic_address_needs_scratch (operands[1]))
3396         operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3397
3398       if (symbolic_operand (operands[1], SFmode))
3399         {
3400           operands[1] = legitimize_pic_address (operands[1],
3401                                                 SFmode,
3402                                                 (reload_in_progress ?
3403                                                  operands[0] :
3404                                                  NULL_RTX));
3405         }
3406     }
3407
3408  movsf_is_ok:
3409   ;
3410 }")
3411