OSDN Git Service

2004-07-12 David S. Miller <davem@nuts.davemloft.net>
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.md
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004 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 GCC.
9
10 ;; GCC 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 ;; GCC 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 GCC; 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 (define_constants
28   [(UNSPEC_MOVE_PIC             0)
29    (UNSPEC_UPDATE_RETURN        1)
30    (UNSPEC_LOAD_PCREL_SYM       2)
31    (UNSPEC_MOVE_PIC_LABEL       5)
32    (UNSPEC_SETH44               6)
33    (UNSPEC_SETM44               7)
34    (UNSPEC_SETHH                9)
35    (UNSPEC_SETLM                10)
36    (UNSPEC_EMB_HISUM            11)
37    (UNSPEC_EMB_TEXTUHI          13)
38    (UNSPEC_EMB_TEXTHI           14)
39    (UNSPEC_EMB_TEXTULO          15)
40    (UNSPEC_EMB_SETHM            18)
41
42    (UNSPEC_TLSGD                30)
43    (UNSPEC_TLSLDM               31)
44    (UNSPEC_TLSLDO               32)
45    (UNSPEC_TLSIE                33)
46    (UNSPEC_TLSLE                34)
47    (UNSPEC_TLSLD_BASE           35)
48   ])
49
50 (define_constants
51   [(UNSPECV_BLOCKAGE            0)
52    (UNSPECV_FLUSHW              1)
53    (UNSPECV_GOTO                2)
54    (UNSPECV_FLUSH               4)
55    (UNSPECV_SETJMP              5)
56    (UNSPECV_SAVEW               6)
57   ])
58
59 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
60 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
61 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
62 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
63 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
64
65 ;; Attribute for cpu type.
66 ;; These must match the values for enum processor_type in sparc.h.
67 (define_attr "cpu"
68   "v7,
69    cypress,
70    v8,
71    supersparc,
72    sparclite,f930,f934,
73    hypersparc,sparclite86x,
74    sparclet,tsc701,
75    v9,
76    ultrasparc,
77    ultrasparc3"
78   (const (symbol_ref "sparc_cpu_attr")))
79
80 ;; Attribute for the instruction set.
81 ;; At present we only need to distinguish v9/!v9, but for clarity we
82 ;; test TARGET_V8 too.
83 (define_attr "isa" "v7,v8,v9,sparclet"
84  (const
85   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
86          (symbol_ref "TARGET_V8") (const_string "v8")
87          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
88         (const_string "v7"))))
89
90 ;; Insn type.
91 (define_attr "type"
92   "ialu,compare,shift,
93    load,sload,store,
94    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
95    imul,idiv,
96    fpload,fpstore,
97    fp,fpmove,
98    fpcmove,fpcrmove,
99    fpcmp,
100    fpmul,fpdivs,fpdivd,
101    fpsqrts,fpsqrtd,
102    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
103    cmove,
104    ialuX,
105    multi,savew,flushw,iflush,trap"
106   (const_string "ialu"))
107
108 ;; True if branch/call has empty delay slot and will emit a nop in it
109 (define_attr "empty_delay_slot" "false,true"
110   (symbol_ref "empty_delay_slot (insn)"))
111
112 (define_attr "branch_type" "none,icc,fcc,reg"
113   (const_string "none"))
114
115 (define_attr "pic" "false,true"
116   (symbol_ref "flag_pic != 0"))
117
118 (define_attr "calls_alloca" "false,true"
119   (symbol_ref "current_function_calls_alloca != 0"))
120
121 (define_attr "calls_eh_return" "false,true"
122    (symbol_ref "current_function_calls_eh_return !=0 "))
123    
124 (define_attr "leaf_function" "false,true"
125   (symbol_ref "current_function_uses_only_leaf_regs != 0"))
126
127 (define_attr "delayed_branch" "false,true"
128   (symbol_ref "flag_delayed_branch != 0"))
129
130 ;; Length (in # of insns).
131 (define_attr "length" ""
132   (cond [(eq_attr "type" "uncond_branch,call")
133            (if_then_else (eq_attr "empty_delay_slot" "true")
134              (const_int 2)
135              (const_int 1))
136          (eq_attr "type" "sibcall")
137            (if_then_else (eq_attr "leaf_function" "true")
138              (if_then_else (eq_attr "empty_delay_slot" "true")
139                (const_int 3)
140                (const_int 2))
141              (if_then_else (eq_attr "empty_delay_slot" "true")
142                (const_int 2)
143                (const_int 1)))
144          (eq_attr "branch_type" "icc")
145            (if_then_else (match_operand 0 "noov_compare64_op" "")
146              (if_then_else (lt (pc) (match_dup 1))
147                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
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 1)) (const_int 260000))
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              (if_then_else (eq_attr "empty_delay_slot" "true")
162                (const_int 2)
163                (const_int 1)))
164          (eq_attr "branch_type" "fcc")
165            (if_then_else (match_operand 0 "fcc0_reg_operand" "")
166              (if_then_else (eq_attr "empty_delay_slot" "true")
167                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
168                  (const_int 3)
169                  (const_int 2))
170                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
171                  (const_int 2)
172                  (const_int 1)))
173              (if_then_else (lt (pc) (match_dup 2))
174                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
175                  (if_then_else (eq_attr "empty_delay_slot" "true")
176                    (const_int 2)
177                    (const_int 1))
178                  (if_then_else (eq_attr "empty_delay_slot" "true")
179                    (const_int 4)
180                    (const_int 3)))
181                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
182                  (if_then_else (eq_attr "empty_delay_slot" "true")
183                    (const_int 2)
184                    (const_int 1))
185                  (if_then_else (eq_attr "empty_delay_slot" "true")
186                    (const_int 4)
187                    (const_int 3)))))
188          (eq_attr "branch_type" "reg")
189            (if_then_else (lt (pc) (match_dup 2))
190              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
191                (if_then_else (eq_attr "empty_delay_slot" "true")
192                  (const_int 2)
193                  (const_int 1))
194                (if_then_else (eq_attr "empty_delay_slot" "true")
195                  (const_int 4)
196                  (const_int 3)))
197              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
198                (if_then_else (eq_attr "empty_delay_slot" "true")
199                  (const_int 2)
200                  (const_int 1))
201                (if_then_else (eq_attr "empty_delay_slot" "true")
202                  (const_int 4)
203                  (const_int 3))))
204          ] (const_int 1)))
205
206 ;; FP precision.
207 (define_attr "fptype" "single,double"
208   (const_string "single"))
209
210 ;; UltraSPARC-III integer load type.
211 (define_attr "us3load_type" "2cycle,3cycle"
212   (const_string "2cycle"))
213
214 (define_asm_attributes
215   [(set_attr "length" "2")
216    (set_attr "type" "multi")])
217
218 ;; Attributes for instruction and branch scheduling
219 (define_attr "tls_call_delay" "false,true"
220   (symbol_ref "tls_call_delay (insn)"))
221
222 (define_attr "in_call_delay" "false,true"
223   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
224                 (const_string "false")
225          (eq_attr "type" "load,fpload,store,fpstore")
226                 (if_then_else (eq_attr "length" "1")
227                               (const_string "true")
228                               (const_string "false"))]
229         (if_then_else (and (eq_attr "length" "1")
230                            (eq_attr "tls_call_delay" "true"))
231                       (const_string "true")
232                       (const_string "false"))))
233
234 (define_attr "eligible_for_sibcall_delay" "false,true"
235   (symbol_ref "eligible_for_sibcall_delay (insn)"))
236
237 (define_attr "eligible_for_return_delay" "false,true"
238   (symbol_ref "eligible_for_return_delay (insn)"))
239
240 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
241 ;; branches.  This would allow us to remove the nop always inserted before
242 ;; a floating point branch.
243
244 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
245 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
246 ;; This is because doing so will add several pipeline stalls to the path
247 ;; that the load/store did not come from.  Unfortunately, there is no way
248 ;; to prevent fill_eager_delay_slots from using load/store without completely
249 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
250 ;; because it prevents us from moving back the final store of inner loops.
251
252 (define_attr "in_branch_delay" "false,true"
253   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
254                      (eq_attr "length" "1"))
255                 (const_string "true")
256                 (const_string "false")))
257
258 (define_attr "in_uncond_branch_delay" "false,true"
259   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
260                      (eq_attr "length" "1"))
261                 (const_string "true")
262                 (const_string "false")))
263
264 (define_attr "in_annul_branch_delay" "false,true"
265   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
266                      (eq_attr "length" "1"))
267                 (const_string "true")
268                 (const_string "false")))
269
270 (define_delay (eq_attr "type" "call")
271   [(eq_attr "in_call_delay" "true") (nil) (nil)])
272
273 (define_delay (eq_attr "type" "sibcall")
274   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
275
276 (define_delay (eq_attr "type" "branch")
277   [(eq_attr "in_branch_delay" "true")
278    (nil) (eq_attr "in_annul_branch_delay" "true")])
279
280 (define_delay (eq_attr "type" "uncond_branch")
281   [(eq_attr "in_uncond_branch_delay" "true")
282    (nil) (nil)])
283
284 (define_delay (eq_attr "type" "return")
285   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
286
287 ;; Include SPARC DFA schedulers
288
289 (include "cypress.md")
290 (include "supersparc.md")
291 (include "hypersparc.md")
292 (include "sparclet.md")
293 (include "ultra1_2.md")
294 (include "ultra3.md")
295
296 \f
297 ;; Compare instructions.
298 ;; This controls RTL generation and register allocation.
299
300 ;; We generate RTL for comparisons and branches by having the cmpxx 
301 ;; patterns store away the operands.  Then, the scc and bcc patterns
302 ;; emit RTL for both the compare and the branch.
303 ;;
304 ;; We do this because we want to generate different code for an sne and
305 ;; seq insn.  In those cases, if the second operand of the compare is not
306 ;; const0_rtx, we want to compute the xor of the two operands and test
307 ;; it against zero.
308 ;;
309 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
310 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
311 ;; insns that actually require more than one machine instruction.
312
313 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
314
315 (define_expand "cmpsi"
316   [(set (reg:CC 100)
317         (compare:CC (match_operand:SI 0 "compare_operand" "")
318                     (match_operand:SI 1 "arith_operand" "")))]
319   ""
320 {
321   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
322     operands[0] = force_reg (SImode, operands[0]);
323
324   sparc_compare_op0 = operands[0];
325   sparc_compare_op1 = operands[1];
326   DONE;
327 })
328
329 (define_expand "cmpdi"
330   [(set (reg:CCX 100)
331         (compare:CCX (match_operand:DI 0 "compare_operand" "")
332                      (match_operand:DI 1 "arith_double_operand" "")))]
333   "TARGET_ARCH64"
334 {
335   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
336     operands[0] = force_reg (DImode, operands[0]);
337
338   sparc_compare_op0 = operands[0];
339   sparc_compare_op1 = operands[1];
340   DONE;
341 })
342
343 (define_expand "cmpsf"
344   ;; The 96 here isn't ever used by anyone.
345   [(set (reg:CCFP 96)
346         (compare:CCFP (match_operand:SF 0 "register_operand" "")
347                       (match_operand:SF 1 "register_operand" "")))]
348   "TARGET_FPU"
349 {
350   sparc_compare_op0 = operands[0];
351   sparc_compare_op1 = operands[1];
352   DONE;
353 })
354
355 (define_expand "cmpdf"
356   ;; The 96 here isn't ever used by anyone.
357   [(set (reg:CCFP 96)
358         (compare:CCFP (match_operand:DF 0 "register_operand" "")
359                       (match_operand:DF 1 "register_operand" "")))]
360   "TARGET_FPU"
361 {
362   sparc_compare_op0 = operands[0];
363   sparc_compare_op1 = operands[1];
364   DONE;
365 })
366
367 (define_expand "cmptf"
368   ;; The 96 here isn't ever used by anyone.
369   [(set (reg:CCFP 96)
370         (compare:CCFP (match_operand:TF 0 "register_operand" "")
371                       (match_operand:TF 1 "register_operand" "")))]
372   "TARGET_FPU"
373 {
374   sparc_compare_op0 = operands[0];
375   sparc_compare_op1 = operands[1];
376   DONE;
377 })
378
379 ;; Now the compare DEFINE_INSNs.
380
381 (define_insn "*cmpsi_insn"
382   [(set (reg:CC 100)
383         (compare:CC (match_operand:SI 0 "register_operand" "r")
384                     (match_operand:SI 1 "arith_operand" "rI")))]
385   ""
386   "cmp\t%0, %1"
387   [(set_attr "type" "compare")])
388
389 (define_insn "*cmpdi_sp64"
390   [(set (reg:CCX 100)
391         (compare:CCX (match_operand:DI 0 "register_operand" "r")
392                      (match_operand:DI 1 "arith_double_operand" "rHI")))]
393   "TARGET_ARCH64"
394   "cmp\t%0, %1"
395   [(set_attr "type" "compare")])
396
397 (define_insn "*cmpsf_fpe"
398   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
399         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
400                        (match_operand:SF 2 "register_operand" "f")))]
401   "TARGET_FPU"
402 {
403   if (TARGET_V9)
404     return "fcmpes\t%0, %1, %2";
405   return "fcmpes\t%1, %2";
406 }
407   [(set_attr "type" "fpcmp")])
408
409 (define_insn "*cmpdf_fpe"
410   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
411         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
412                        (match_operand:DF 2 "register_operand" "e")))]
413   "TARGET_FPU"
414 {
415   if (TARGET_V9)
416     return "fcmped\t%0, %1, %2";
417   return "fcmped\t%1, %2";
418 }
419   [(set_attr "type" "fpcmp")
420    (set_attr "fptype" "double")])
421
422 (define_insn "*cmptf_fpe"
423   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
424         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
425                        (match_operand:TF 2 "register_operand" "e")))]
426   "TARGET_FPU && TARGET_HARD_QUAD"
427 {
428   if (TARGET_V9)
429     return "fcmpeq\t%0, %1, %2";
430   return "fcmpeq\t%1, %2";
431 }
432   [(set_attr "type" "fpcmp")])
433
434 (define_insn "*cmpsf_fp"
435   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
436         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
437                       (match_operand:SF 2 "register_operand" "f")))]
438   "TARGET_FPU"
439 {
440   if (TARGET_V9)
441     return "fcmps\t%0, %1, %2";
442   return "fcmps\t%1, %2";
443 }
444   [(set_attr "type" "fpcmp")])
445
446 (define_insn "*cmpdf_fp"
447   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
448         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
449                       (match_operand:DF 2 "register_operand" "e")))]
450   "TARGET_FPU"
451 {
452   if (TARGET_V9)
453     return "fcmpd\t%0, %1, %2";
454   return "fcmpd\t%1, %2";
455 }
456   [(set_attr "type" "fpcmp")
457    (set_attr "fptype" "double")])
458
459 (define_insn "*cmptf_fp"
460   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
461         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
462                       (match_operand:TF 2 "register_operand" "e")))]
463   "TARGET_FPU && TARGET_HARD_QUAD"
464 {
465   if (TARGET_V9)
466     return "fcmpq\t%0, %1, %2";
467   return "fcmpq\t%1, %2";
468 }
469   [(set_attr "type" "fpcmp")])
470 \f
471 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
472 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
473 ;; the same code as v8 (the addx/subx method has more applications).  The
474 ;; exception to this is "reg != 0" which can be done in one instruction on v9
475 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
476 ;; branches.
477
478 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
479 ;; generate addcc/subcc instructions.
480
481 (define_expand "seqsi_special"
482   [(set (match_dup 3)
483         (xor:SI (match_operand:SI 1 "register_operand" "")
484                 (match_operand:SI 2 "register_operand" "")))
485    (parallel [(set (match_operand:SI 0 "register_operand" "")
486                    (eq:SI (match_dup 3) (const_int 0)))
487               (clobber (reg:CC 100))])]
488   ""
489   { operands[3] = gen_reg_rtx (SImode); })
490
491 (define_expand "seqdi_special"
492   [(set (match_dup 3)
493         (xor:DI (match_operand:DI 1 "register_operand" "")
494                 (match_operand:DI 2 "register_operand" "")))
495    (set (match_operand:DI 0 "register_operand" "")
496         (eq:DI (match_dup 3) (const_int 0)))]
497   "TARGET_ARCH64"
498   { operands[3] = gen_reg_rtx (DImode); })
499
500 (define_expand "snesi_special"
501   [(set (match_dup 3)
502         (xor:SI (match_operand:SI 1 "register_operand" "")
503                 (match_operand:SI 2 "register_operand" "")))
504    (parallel [(set (match_operand:SI 0 "register_operand" "")
505                    (ne:SI (match_dup 3) (const_int 0)))
506               (clobber (reg:CC 100))])]
507   ""
508   { operands[3] = gen_reg_rtx (SImode); })
509
510 (define_expand "snedi_special"
511   [(set (match_dup 3)
512         (xor:DI (match_operand:DI 1 "register_operand" "")
513                 (match_operand:DI 2 "register_operand" "")))
514    (set (match_operand:DI 0 "register_operand" "")
515         (ne:DI (match_dup 3) (const_int 0)))]
516   "TARGET_ARCH64"
517   { operands[3] = gen_reg_rtx (DImode); })
518
519 (define_expand "seqdi_special_trunc"
520   [(set (match_dup 3)
521         (xor:DI (match_operand:DI 1 "register_operand" "")
522                 (match_operand:DI 2 "register_operand" "")))
523    (set (match_operand:SI 0 "register_operand" "")
524         (eq:SI (match_dup 3) (const_int 0)))]
525   "TARGET_ARCH64"
526   { operands[3] = gen_reg_rtx (DImode); })
527
528 (define_expand "snedi_special_trunc"
529   [(set (match_dup 3)
530         (xor:DI (match_operand:DI 1 "register_operand" "")
531                 (match_operand:DI 2 "register_operand" "")))
532    (set (match_operand:SI 0 "register_operand" "")
533         (ne:SI (match_dup 3) (const_int 0)))]
534   "TARGET_ARCH64"
535   { operands[3] = gen_reg_rtx (DImode); })
536
537 (define_expand "seqsi_special_extend"
538   [(set (match_dup 3)
539         (xor:SI (match_operand:SI 1 "register_operand" "")
540                 (match_operand:SI 2 "register_operand" "")))
541    (parallel [(set (match_operand:DI 0 "register_operand" "")
542                    (eq:DI (match_dup 3) (const_int 0)))
543               (clobber (reg:CC 100))])]
544   "TARGET_ARCH64"
545   { operands[3] = gen_reg_rtx (SImode); })
546
547 (define_expand "snesi_special_extend"
548   [(set (match_dup 3)
549         (xor:SI (match_operand:SI 1 "register_operand" "")
550                 (match_operand:SI 2 "register_operand" "")))
551    (parallel [(set (match_operand:DI 0 "register_operand" "")
552                    (ne:DI (match_dup 3) (const_int 0)))
553               (clobber (reg:CC 100))])]
554   "TARGET_ARCH64"
555   { operands[3] = gen_reg_rtx (SImode); })
556
557 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
558 ;; However, the code handles both SImode and DImode.
559 (define_expand "seq"
560   [(set (match_operand:SI 0 "intreg_operand" "")
561         (eq:SI (match_dup 1) (const_int 0)))]
562   ""
563 {
564   if (GET_MODE (sparc_compare_op0) == SImode)
565     {
566       rtx pat;
567
568       if (GET_MODE (operands[0]) == SImode)
569         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
570                                  sparc_compare_op1);
571       else if (! TARGET_ARCH64)
572         FAIL;
573       else
574         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
575                                         sparc_compare_op1);
576       emit_insn (pat);
577       DONE;
578     }
579   else if (GET_MODE (sparc_compare_op0) == DImode)
580     {
581       rtx pat;
582
583       if (! TARGET_ARCH64)
584         FAIL;
585       else if (GET_MODE (operands[0]) == SImode)
586         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
587                                        sparc_compare_op1);
588       else
589         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
590                                  sparc_compare_op1);
591       emit_insn (pat);
592       DONE;
593     }
594   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
595     {
596       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
597       emit_jump_insn (gen_sne (operands[0]));
598       DONE;
599     }
600   else if (TARGET_V9)
601     {
602       if (gen_v9_scc (EQ, operands))
603         DONE;
604       /* fall through */
605     }
606   FAIL;
607 })
608
609 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
610 ;; However, the code handles both SImode and DImode.
611 (define_expand "sne"
612   [(set (match_operand:SI 0 "intreg_operand" "")
613         (ne:SI (match_dup 1) (const_int 0)))]
614   ""
615 {
616   if (GET_MODE (sparc_compare_op0) == SImode)
617     {
618       rtx pat;
619
620       if (GET_MODE (operands[0]) == SImode)
621         pat = gen_snesi_special (operands[0], sparc_compare_op0,
622                                  sparc_compare_op1);
623       else if (! TARGET_ARCH64)
624         FAIL;
625       else
626         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
627                                         sparc_compare_op1);
628       emit_insn (pat);
629       DONE;
630     }
631   else if (GET_MODE (sparc_compare_op0) == DImode)
632     {
633       rtx pat;
634
635       if (! TARGET_ARCH64)
636         FAIL;
637       else if (GET_MODE (operands[0]) == SImode)
638         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
639                                        sparc_compare_op1);
640       else
641         pat = gen_snedi_special (operands[0], sparc_compare_op0,
642                                  sparc_compare_op1);
643       emit_insn (pat);
644       DONE;
645     }
646   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
647     {
648       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
649       emit_jump_insn (gen_sne (operands[0]));
650       DONE;
651     }
652   else if (TARGET_V9)
653     {
654       if (gen_v9_scc (NE, operands))
655         DONE;
656       /* fall through */
657     }
658   FAIL;
659 })
660
661 (define_expand "sgt"
662   [(set (match_operand:SI 0 "intreg_operand" "")
663         (gt:SI (match_dup 1) (const_int 0)))]
664   ""
665 {
666   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
667     {
668       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
669       emit_jump_insn (gen_sne (operands[0]));
670       DONE;
671     }
672   else if (TARGET_V9)
673     {
674       if (gen_v9_scc (GT, operands))
675         DONE;
676       /* fall through */
677     }
678   FAIL;
679 })
680
681 (define_expand "slt"
682   [(set (match_operand:SI 0 "intreg_operand" "")
683         (lt:SI (match_dup 1) (const_int 0)))]
684   ""
685 {
686   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
687     {
688       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
689       emit_jump_insn (gen_sne (operands[0]));
690       DONE;
691     }
692   else if (TARGET_V9)
693     {
694       if (gen_v9_scc (LT, operands))
695         DONE;
696       /* fall through */
697     }
698   FAIL;
699 })
700
701 (define_expand "sge"
702   [(set (match_operand:SI 0 "intreg_operand" "")
703         (ge:SI (match_dup 1) (const_int 0)))]
704   ""
705 {
706   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
707     {
708       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
709       emit_jump_insn (gen_sne (operands[0]));
710       DONE;
711     }
712   else if (TARGET_V9)
713     {
714       if (gen_v9_scc (GE, operands))
715         DONE;
716       /* fall through */
717     }
718   FAIL;
719 })
720
721 (define_expand "sle"
722   [(set (match_operand:SI 0 "intreg_operand" "")
723         (le:SI (match_dup 1) (const_int 0)))]
724   ""
725 {
726   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
727     {
728       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
729       emit_jump_insn (gen_sne (operands[0]));
730       DONE;
731     }
732   else if (TARGET_V9)
733     {
734       if (gen_v9_scc (LE, operands))
735         DONE;
736       /* fall through */
737     }
738   FAIL;
739 })
740
741 (define_expand "sgtu"
742   [(set (match_operand:SI 0 "intreg_operand" "")
743         (gtu:SI (match_dup 1) (const_int 0)))]
744   ""
745 {
746   if (! TARGET_V9)
747     {
748       rtx tem, pat;
749
750       /* We can do ltu easily, so if both operands are registers, swap them and
751          do a LTU.  */
752       if ((GET_CODE (sparc_compare_op0) == REG
753            || GET_CODE (sparc_compare_op0) == SUBREG)
754           && (GET_CODE (sparc_compare_op1) == REG
755               || GET_CODE (sparc_compare_op1) == SUBREG))
756         {
757           tem = sparc_compare_op0;
758           sparc_compare_op0 = sparc_compare_op1;
759           sparc_compare_op1 = tem;
760           pat = gen_sltu (operands[0]);
761           if (pat == NULL_RTX)
762             FAIL;
763           emit_insn (pat);
764           DONE;
765         }
766     }
767   else
768     {
769       if (gen_v9_scc (GTU, operands))
770         DONE;
771     }
772   FAIL;
773 })
774
775 (define_expand "sltu"
776   [(set (match_operand:SI 0 "intreg_operand" "")
777         (ltu:SI (match_dup 1) (const_int 0)))]
778   ""
779 {
780   if (TARGET_V9)
781     {
782       if (gen_v9_scc (LTU, operands))
783         DONE;
784     }
785   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
786 })
787
788 (define_expand "sgeu"
789   [(set (match_operand:SI 0 "intreg_operand" "")
790         (geu:SI (match_dup 1) (const_int 0)))]
791   ""
792 {
793   if (TARGET_V9)
794     {
795       if (gen_v9_scc (GEU, operands))
796         DONE;
797     }
798   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
799 })
800
801 (define_expand "sleu"
802   [(set (match_operand:SI 0 "intreg_operand" "")
803         (leu:SI (match_dup 1) (const_int 0)))]
804   ""
805 {
806   if (! TARGET_V9)
807     {
808       rtx tem, pat;
809
810       /* We can do geu easily, so if both operands are registers, swap them and
811          do a GEU.  */
812       if ((GET_CODE (sparc_compare_op0) == REG
813            || GET_CODE (sparc_compare_op0) == SUBREG)
814           && (GET_CODE (sparc_compare_op1) == REG
815               || GET_CODE (sparc_compare_op1) == SUBREG))
816         {
817           tem = sparc_compare_op0;
818           sparc_compare_op0 = sparc_compare_op1;
819           sparc_compare_op1 = tem;
820           pat = gen_sgeu (operands[0]);
821           if (pat == NULL_RTX)
822             FAIL;
823           emit_insn (pat);
824           DONE;
825         }
826     }
827   else
828     {
829       if (gen_v9_scc (LEU, operands))
830         DONE;
831     }
832   FAIL;
833 })
834
835 ;; Now the DEFINE_INSNs for the scc cases.
836
837 ;; The SEQ and SNE patterns are special because they can be done
838 ;; without any branching and do not involve a COMPARE.  We want
839 ;; them to always use the splitz below so the results can be
840 ;; scheduled.
841
842 (define_insn_and_split "*snesi_zero"
843   [(set (match_operand:SI 0 "register_operand" "=r")
844         (ne:SI (match_operand:SI 1 "register_operand" "r")
845                (const_int 0)))
846    (clobber (reg:CC 100))]
847   ""
848   "#"
849   ""
850   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
851                                            (const_int 0)))
852    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
853   ""
854   [(set_attr "length" "2")])
855
856 (define_insn_and_split "*neg_snesi_zero"
857   [(set (match_operand:SI 0 "register_operand" "=r")
858         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
859                        (const_int 0))))
860    (clobber (reg:CC 100))]
861   ""
862   "#"
863   ""
864   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
865                                            (const_int 0)))
866    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
867   ""
868   [(set_attr "length" "2")])
869
870 (define_insn_and_split "*snesi_zero_extend"
871   [(set (match_operand:DI 0 "register_operand" "=r")
872         (ne:DI (match_operand:SI 1 "register_operand" "r")
873                (const_int 0)))
874    (clobber (reg:CC 100))]
875   "TARGET_ARCH64"
876   "#"
877   "&& 1"
878   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
879                                                      (match_dup 1))
880                                            (const_int 0)))
881    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
882                                                         (const_int 0))
883                                                (ltu:SI (reg:CC_NOOV 100)
884                                                        (const_int 0)))))]
885   ""
886   [(set_attr "length" "2")])
887
888 (define_insn_and_split "*snedi_zero"
889   [(set (match_operand:DI 0 "register_operand" "=&r")
890         (ne:DI (match_operand:DI 1 "register_operand" "r")
891                (const_int 0)))]
892   "TARGET_ARCH64"
893   "#"
894   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
895   [(set (match_dup 0) (const_int 0))
896    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
897                                               (const_int 0))
898                                        (const_int 1)
899                                        (match_dup 0)))]
900   ""
901   [(set_attr "length" "2")])
902
903 (define_insn_and_split "*neg_snedi_zero"
904   [(set (match_operand:DI 0 "register_operand" "=&r")
905         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
906                        (const_int 0))))]
907   "TARGET_ARCH64"
908   "#"
909   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
910   [(set (match_dup 0) (const_int 0))
911    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
912                                               (const_int 0))
913                                        (const_int -1)
914                                        (match_dup 0)))]
915   ""
916   [(set_attr "length" "2")])
917
918 (define_insn_and_split "*snedi_zero_trunc"
919   [(set (match_operand:SI 0 "register_operand" "=&r")
920         (ne:SI (match_operand:DI 1 "register_operand" "r")
921                (const_int 0)))]
922   "TARGET_ARCH64"
923   "#"
924   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
925   [(set (match_dup 0) (const_int 0))
926    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
927                                               (const_int 0))
928                                        (const_int 1)
929                                        (match_dup 0)))]
930   ""
931   [(set_attr "length" "2")])
932
933 (define_insn_and_split "*seqsi_zero"
934   [(set (match_operand:SI 0 "register_operand" "=r")
935         (eq:SI (match_operand:SI 1 "register_operand" "r")
936                (const_int 0)))
937    (clobber (reg:CC 100))]
938   ""
939   "#"
940   ""
941   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
942                                            (const_int 0)))
943    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
944   ""
945   [(set_attr "length" "2")])
946
947 (define_insn_and_split "*neg_seqsi_zero"
948   [(set (match_operand:SI 0 "register_operand" "=r")
949         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
950                        (const_int 0))))
951    (clobber (reg:CC 100))]
952   ""
953   "#"
954   ""
955   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
956                                            (const_int 0)))
957    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
958   ""
959   [(set_attr "length" "2")])
960
961 (define_insn_and_split "*seqsi_zero_extend"
962   [(set (match_operand:DI 0 "register_operand" "=r")
963         (eq:DI (match_operand:SI 1 "register_operand" "r")
964                (const_int 0)))
965    (clobber (reg:CC 100))]
966   "TARGET_ARCH64"
967   "#"
968   "&& 1"
969   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
970                                                      (match_dup 1))
971                                            (const_int 0)))
972    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
973                                                           (const_int -1))
974                                                 (ltu:SI (reg:CC_NOOV 100)
975                                                         (const_int 0)))))]
976   ""
977   [(set_attr "length" "2")])
978
979 (define_insn_and_split "*seqdi_zero"
980   [(set (match_operand:DI 0 "register_operand" "=&r")
981         (eq:DI (match_operand:DI 1 "register_operand" "r")
982                (const_int 0)))]
983   "TARGET_ARCH64"
984   "#"
985   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
986   [(set (match_dup 0) (const_int 0))
987    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
988                                               (const_int 0))
989                                        (const_int 1)
990                                        (match_dup 0)))]
991   ""
992   [(set_attr "length" "2")])
993
994 (define_insn_and_split "*neg_seqdi_zero"
995   [(set (match_operand:DI 0 "register_operand" "=&r")
996         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
997                        (const_int 0))))]
998   "TARGET_ARCH64"
999   "#"
1000   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1001   [(set (match_dup 0) (const_int 0))
1002    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1003                                               (const_int 0))
1004                                        (const_int -1)
1005                                        (match_dup 0)))]
1006   ""
1007   [(set_attr "length" "2")]) 
1008
1009 (define_insn_and_split "*seqdi_zero_trunc"
1010   [(set (match_operand:SI 0 "register_operand" "=&r")
1011         (eq:SI (match_operand:DI 1 "register_operand" "r")
1012                (const_int 0)))]
1013   "TARGET_ARCH64"
1014   "#"
1015   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1016   [(set (match_dup 0) (const_int 0))
1017    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1018                                               (const_int 0))
1019                                        (const_int 1)
1020                                        (match_dup 0)))]
1021   ""
1022   [(set_attr "length" "2")])
1023
1024 ;; We can also do (x + (i == 0)) and related, so put them in.
1025 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1026 ;; versions for v9.
1027
1028 (define_insn_and_split "*x_plus_i_ne_0"
1029   [(set (match_operand:SI 0 "register_operand" "=r")
1030         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1031                         (const_int 0))
1032                  (match_operand:SI 2 "register_operand" "r")))
1033    (clobber (reg:CC 100))]
1034   ""
1035   "#"
1036   ""
1037   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1038                                            (const_int 0)))
1039    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1040                                (match_dup 2)))]
1041   ""
1042   [(set_attr "length" "2")])
1043
1044 (define_insn_and_split "*x_minus_i_ne_0"
1045   [(set (match_operand:SI 0 "register_operand" "=r")
1046         (minus:SI (match_operand:SI 2 "register_operand" "r")
1047                   (ne:SI (match_operand:SI 1 "register_operand" "r")
1048                          (const_int 0))))
1049    (clobber (reg:CC 100))]
1050   ""
1051   "#"
1052   ""
1053   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1054                                            (const_int 0)))
1055    (set (match_dup 0) (minus:SI (match_dup 2)
1056                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1057   ""
1058   [(set_attr "length" "2")])
1059
1060 (define_insn_and_split "*x_plus_i_eq_0"
1061   [(set (match_operand:SI 0 "register_operand" "=r")
1062         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1063                         (const_int 0))
1064                  (match_operand:SI 2 "register_operand" "r")))
1065    (clobber (reg:CC 100))]
1066   ""
1067   "#"
1068   ""
1069   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1070                                            (const_int 0)))
1071    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1072                                (match_dup 2)))]
1073   ""
1074   [(set_attr "length" "2")])
1075
1076 (define_insn_and_split "*x_minus_i_eq_0"
1077   [(set (match_operand:SI 0 "register_operand" "=r")
1078         (minus:SI (match_operand:SI 2 "register_operand" "r")
1079                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1080                          (const_int 0))))
1081    (clobber (reg:CC 100))]
1082   ""
1083   "#"
1084   ""
1085   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1086                                            (const_int 0)))
1087    (set (match_dup 0) (minus:SI (match_dup 2)
1088                                 (geu:SI (reg:CC 100) (const_int 0))))]
1089   ""
1090   [(set_attr "length" "2")])
1091
1092 ;; We can also do GEU and LTU directly, but these operate after a compare.
1093 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1094 ;; versions for v9.
1095
1096 (define_insn "*sltu_insn"
1097   [(set (match_operand:SI 0 "register_operand" "=r")
1098         (ltu:SI (reg:CC 100) (const_int 0)))]
1099   ""
1100   "addx\t%%g0, 0, %0"
1101   [(set_attr "type" "ialuX")])
1102
1103 (define_insn "*neg_sltu_insn"
1104   [(set (match_operand:SI 0 "register_operand" "=r")
1105         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1106   ""
1107   "subx\t%%g0, 0, %0"
1108   [(set_attr "type" "ialuX")])
1109
1110 ;; ??? Combine should canonicalize these next two to the same pattern.
1111 (define_insn "*neg_sltu_minus_x"
1112   [(set (match_operand:SI 0 "register_operand" "=r")
1113         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1114                   (match_operand:SI 1 "arith_operand" "rI")))]
1115   ""
1116   "subx\t%%g0, %1, %0"
1117   [(set_attr "type" "ialuX")])
1118
1119 (define_insn "*neg_sltu_plus_x"
1120   [(set (match_operand:SI 0 "register_operand" "=r")
1121         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1122                          (match_operand:SI 1 "arith_operand" "rI"))))]
1123   ""
1124   "subx\t%%g0, %1, %0"
1125   [(set_attr "type" "ialuX")])
1126
1127 (define_insn "*sgeu_insn"
1128   [(set (match_operand:SI 0 "register_operand" "=r")
1129         (geu:SI (reg:CC 100) (const_int 0)))]
1130   ""
1131   "subx\t%%g0, -1, %0"
1132   [(set_attr "type" "ialuX")])
1133
1134 (define_insn "*neg_sgeu_insn"
1135   [(set (match_operand:SI 0 "register_operand" "=r")
1136         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1137   ""
1138   "addx\t%%g0, -1, %0"
1139   [(set_attr "type" "ialuX")])
1140
1141 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1142 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1143 ;; versions for v9.
1144
1145 (define_insn "*sltu_plus_x"
1146   [(set (match_operand:SI 0 "register_operand" "=r")
1147         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1148                  (match_operand:SI 1 "arith_operand" "rI")))]
1149   ""
1150   "addx\t%%g0, %1, %0"
1151   [(set_attr "type" "ialuX")])
1152
1153 (define_insn "*sltu_plus_x_plus_y"
1154   [(set (match_operand:SI 0 "register_operand" "=r")
1155         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1156                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1157                           (match_operand:SI 2 "arith_operand" "rI"))))]
1158   ""
1159   "addx\t%1, %2, %0"
1160   [(set_attr "type" "ialuX")])
1161
1162 (define_insn "*x_minus_sltu"
1163   [(set (match_operand:SI 0 "register_operand" "=r")
1164         (minus:SI (match_operand:SI 1 "register_operand" "r")
1165                   (ltu:SI (reg:CC 100) (const_int 0))))]
1166   ""
1167   "subx\t%1, 0, %0"
1168   [(set_attr "type" "ialuX")])
1169
1170 ;; ??? Combine should canonicalize these next two to the same pattern.
1171 (define_insn "*x_minus_y_minus_sltu"
1172   [(set (match_operand:SI 0 "register_operand" "=r")
1173         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1174                             (match_operand:SI 2 "arith_operand" "rI"))
1175                   (ltu:SI (reg:CC 100) (const_int 0))))]
1176   ""
1177   "subx\t%r1, %2, %0"
1178   [(set_attr "type" "ialuX")])
1179
1180 (define_insn "*x_minus_sltu_plus_y"
1181   [(set (match_operand:SI 0 "register_operand" "=r")
1182         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1183                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1184                            (match_operand:SI 2 "arith_operand" "rI"))))]
1185   ""
1186   "subx\t%r1, %2, %0"
1187   [(set_attr "type" "ialuX")])
1188
1189 (define_insn "*sgeu_plus_x"
1190   [(set (match_operand:SI 0 "register_operand" "=r")
1191         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1192                  (match_operand:SI 1 "register_operand" "r")))]
1193   ""
1194   "subx\t%1, -1, %0"
1195   [(set_attr "type" "ialuX")])
1196
1197 (define_insn "*x_minus_sgeu"
1198   [(set (match_operand:SI 0 "register_operand" "=r")
1199         (minus:SI (match_operand:SI 1 "register_operand" "r")
1200                   (geu:SI (reg:CC 100) (const_int 0))))]
1201   ""
1202   "addx\t%1, -1, %0"
1203   [(set_attr "type" "ialuX")])
1204
1205 (define_split
1206   [(set (match_operand:SI 0 "register_operand" "")
1207         (match_operator:SI 2 "noov_compare_op"
1208                            [(match_operand 1 "icc_or_fcc_reg_operand" "")
1209                             (const_int 0)]))]
1210   ;; 32 bit LTU/GEU are better implemented using addx/subx
1211   "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1212    && (GET_MODE (operands[1]) == CCXmode
1213        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1214   [(set (match_dup 0) (const_int 0))
1215    (set (match_dup 0)
1216         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1217                          (const_int 1)
1218                          (match_dup 0)))]
1219   "")
1220
1221 \f
1222 ;; These control RTL generation for conditional jump insns
1223
1224 ;; The quad-word fp compare library routines all return nonzero to indicate
1225 ;; true, which is different from the equivalent libgcc routines, so we must
1226 ;; handle them specially here.
1227
1228 (define_expand "beq"
1229   [(set (pc)
1230         (if_then_else (eq (match_dup 1) (const_int 0))
1231                       (label_ref (match_operand 0 "" ""))
1232                       (pc)))]
1233   ""
1234 {
1235   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1236       && GET_CODE (sparc_compare_op0) == REG
1237       && GET_MODE (sparc_compare_op0) == DImode)
1238     {
1239       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1240       DONE;
1241     }
1242   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1243     {
1244       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1245       emit_jump_insn (gen_bne (operands[0]));
1246       DONE;
1247     }
1248   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1249 })
1250
1251 (define_expand "bne"
1252   [(set (pc)
1253         (if_then_else (ne (match_dup 1) (const_int 0))
1254                       (label_ref (match_operand 0 "" ""))
1255                       (pc)))]
1256   ""
1257 {
1258   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1259       && GET_CODE (sparc_compare_op0) == REG
1260       && GET_MODE (sparc_compare_op0) == DImode)
1261     {
1262       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1263       DONE;
1264     }
1265   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1266     {
1267       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1268       emit_jump_insn (gen_bne (operands[0]));
1269       DONE;
1270     }
1271   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1272 })
1273
1274 (define_expand "bgt"
1275   [(set (pc)
1276         (if_then_else (gt (match_dup 1) (const_int 0))
1277                       (label_ref (match_operand 0 "" ""))
1278                       (pc)))]
1279   ""
1280 {
1281   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1282       && GET_CODE (sparc_compare_op0) == REG
1283       && GET_MODE (sparc_compare_op0) == DImode)
1284     {
1285       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1286       DONE;
1287     }
1288   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1289     {
1290       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1291       emit_jump_insn (gen_bne (operands[0]));
1292       DONE;
1293     }
1294   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1295 })
1296
1297 (define_expand "bgtu"
1298   [(set (pc)
1299         (if_then_else (gtu (match_dup 1) (const_int 0))
1300                       (label_ref (match_operand 0 "" ""))
1301                       (pc)))]
1302   ""
1303 {
1304   operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1305 })
1306
1307 (define_expand "blt"
1308   [(set (pc)
1309         (if_then_else (lt (match_dup 1) (const_int 0))
1310                       (label_ref (match_operand 0 "" ""))
1311                       (pc)))]
1312   ""
1313 {
1314   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1315       && GET_CODE (sparc_compare_op0) == REG
1316       && GET_MODE (sparc_compare_op0) == DImode)
1317     {
1318       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1319       DONE;
1320     }
1321   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1322     {
1323       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1324       emit_jump_insn (gen_bne (operands[0]));
1325       DONE;
1326     }
1327   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1328 })
1329
1330 (define_expand "bltu"
1331   [(set (pc)
1332         (if_then_else (ltu (match_dup 1) (const_int 0))
1333                       (label_ref (match_operand 0 "" ""))
1334                       (pc)))]
1335   ""
1336 {
1337   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1338 })
1339
1340 (define_expand "bge"
1341   [(set (pc)
1342         (if_then_else (ge (match_dup 1) (const_int 0))
1343                       (label_ref (match_operand 0 "" ""))
1344                       (pc)))]
1345   ""
1346 {
1347   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1348       && GET_CODE (sparc_compare_op0) == REG
1349       && GET_MODE (sparc_compare_op0) == DImode)
1350     {
1351       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1352       DONE;
1353     }
1354   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1355     {
1356       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1357       emit_jump_insn (gen_bne (operands[0]));
1358       DONE;
1359     }
1360   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1361 })
1362
1363 (define_expand "bgeu"
1364   [(set (pc)
1365         (if_then_else (geu (match_dup 1) (const_int 0))
1366                       (label_ref (match_operand 0 "" ""))
1367                       (pc)))]
1368   ""
1369 {
1370   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1371 })
1372
1373 (define_expand "ble"
1374   [(set (pc)
1375         (if_then_else (le (match_dup 1) (const_int 0))
1376                       (label_ref (match_operand 0 "" ""))
1377                       (pc)))]
1378   ""
1379 {
1380   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1381       && GET_CODE (sparc_compare_op0) == REG
1382       && GET_MODE (sparc_compare_op0) == DImode)
1383     {
1384       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1385       DONE;
1386     }
1387   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1388     {
1389       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1390       emit_jump_insn (gen_bne (operands[0]));
1391       DONE;
1392     }
1393   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1394 })
1395
1396 (define_expand "bleu"
1397   [(set (pc)
1398         (if_then_else (leu (match_dup 1) (const_int 0))
1399                       (label_ref (match_operand 0 "" ""))
1400                       (pc)))]
1401   ""
1402 {
1403   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1404 })
1405
1406 (define_expand "bunordered"
1407   [(set (pc)
1408         (if_then_else (unordered (match_dup 1) (const_int 0))
1409                       (label_ref (match_operand 0 "" ""))
1410                       (pc)))]
1411   ""
1412 {
1413   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1414     {
1415       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1416                                 UNORDERED);
1417       emit_jump_insn (gen_beq (operands[0]));
1418       DONE;
1419     }
1420   operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1421                                  sparc_compare_op1);
1422 })
1423
1424 (define_expand "bordered"
1425   [(set (pc)
1426         (if_then_else (ordered (match_dup 1) (const_int 0))
1427                       (label_ref (match_operand 0 "" ""))
1428                       (pc)))]
1429   ""
1430 {
1431   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1432     {
1433       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1434       emit_jump_insn (gen_bne (operands[0]));
1435       DONE;
1436     }
1437   operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1438                                  sparc_compare_op1);
1439 })
1440
1441 (define_expand "bungt"
1442   [(set (pc)
1443         (if_then_else (ungt (match_dup 1) (const_int 0))
1444                       (label_ref (match_operand 0 "" ""))
1445                       (pc)))]
1446   ""
1447 {
1448   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1449     {
1450       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1451       emit_jump_insn (gen_bgt (operands[0]));
1452       DONE;
1453     }
1454   operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1455 })
1456
1457 (define_expand "bunlt"
1458   [(set (pc)
1459         (if_then_else (unlt (match_dup 1) (const_int 0))
1460                       (label_ref (match_operand 0 "" ""))
1461                       (pc)))]
1462   ""
1463 {
1464   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1465     {
1466       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1467       emit_jump_insn (gen_bne (operands[0]));
1468       DONE;
1469     }
1470   operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1471 })
1472
1473 (define_expand "buneq"
1474   [(set (pc)
1475         (if_then_else (uneq (match_dup 1) (const_int 0))
1476                       (label_ref (match_operand 0 "" ""))
1477                       (pc)))]
1478   ""
1479 {
1480   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1481     {
1482       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1483       emit_jump_insn (gen_beq (operands[0]));
1484       DONE;
1485     }
1486   operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1487 })
1488
1489 (define_expand "bunge"
1490   [(set (pc)
1491         (if_then_else (unge (match_dup 1) (const_int 0))
1492                       (label_ref (match_operand 0 "" ""))
1493                       (pc)))]
1494   ""
1495 {
1496   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1497     {
1498       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1499       emit_jump_insn (gen_bne (operands[0]));
1500       DONE;
1501     }
1502   operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1503 })
1504
1505 (define_expand "bunle"
1506   [(set (pc)
1507         (if_then_else (unle (match_dup 1) (const_int 0))
1508                       (label_ref (match_operand 0 "" ""))
1509                       (pc)))]
1510   ""
1511 {
1512   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1513     {
1514       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1515       emit_jump_insn (gen_bne (operands[0]));
1516       DONE;
1517     }
1518   operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1519 })
1520
1521 (define_expand "bltgt"
1522   [(set (pc)
1523         (if_then_else (ltgt (match_dup 1) (const_int 0))
1524                       (label_ref (match_operand 0 "" ""))
1525                       (pc)))]
1526   ""
1527 {
1528   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1529     {
1530       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1531       emit_jump_insn (gen_bne (operands[0]));
1532       DONE;
1533     }
1534   operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1535 })
1536 \f
1537 ;; Now match both normal and inverted jump.
1538
1539 ;; XXX fpcmp nop braindamage
1540 (define_insn "*normal_branch"
1541   [(set (pc)
1542         (if_then_else (match_operator 0 "noov_compare_op"
1543                                       [(reg 100) (const_int 0)])
1544                       (label_ref (match_operand 1 "" ""))
1545                       (pc)))]
1546   ""
1547 {
1548   return output_cbranch (operands[0], operands[1], 1, 0,
1549                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1550                          ! final_sequence, insn);
1551 }
1552   [(set_attr "type" "branch")
1553    (set_attr "branch_type" "icc")])
1554
1555 ;; XXX fpcmp nop braindamage
1556 (define_insn "*inverted_branch"
1557   [(set (pc)
1558         (if_then_else (match_operator 0 "noov_compare_op"
1559                                       [(reg 100) (const_int 0)])
1560                       (pc)
1561                       (label_ref (match_operand 1 "" ""))))]
1562   ""
1563 {
1564   return output_cbranch (operands[0], operands[1], 1, 1,
1565                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1566                          ! final_sequence, insn);
1567 }
1568   [(set_attr "type" "branch")
1569    (set_attr "branch_type" "icc")])
1570
1571 ;; XXX fpcmp nop braindamage
1572 (define_insn "*normal_fp_branch"
1573   [(set (pc)
1574         (if_then_else (match_operator 1 "comparison_operator"
1575                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1576                                        (const_int 0)])
1577                       (label_ref (match_operand 2 "" ""))
1578                       (pc)))]
1579   ""
1580 {
1581   return output_cbranch (operands[1], operands[2], 2, 0,
1582                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1583                          ! final_sequence, insn);
1584 }
1585   [(set_attr "type" "branch")
1586    (set_attr "branch_type" "fcc")])
1587
1588 ;; XXX fpcmp nop braindamage
1589 (define_insn "*inverted_fp_branch"
1590   [(set (pc)
1591         (if_then_else (match_operator 1 "comparison_operator"
1592                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1593                                        (const_int 0)])
1594                       (pc)
1595                       (label_ref (match_operand 2 "" ""))))]
1596   ""
1597 {
1598   return output_cbranch (operands[1], operands[2], 2, 1,
1599                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1600                          ! final_sequence, insn);
1601 }
1602   [(set_attr "type" "branch")
1603    (set_attr "branch_type" "fcc")])
1604
1605 ;; XXX fpcmp nop braindamage
1606 (define_insn "*normal_fpe_branch"
1607   [(set (pc)
1608         (if_then_else (match_operator 1 "comparison_operator"
1609                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1610                                        (const_int 0)])
1611                       (label_ref (match_operand 2 "" ""))
1612                       (pc)))]
1613   ""
1614 {
1615   return output_cbranch (operands[1], operands[2], 2, 0,
1616                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1617                          ! final_sequence, insn);
1618 }
1619   [(set_attr "type" "branch")
1620    (set_attr "branch_type" "fcc")])
1621
1622 ;; XXX fpcmp nop braindamage
1623 (define_insn "*inverted_fpe_branch"
1624   [(set (pc)
1625         (if_then_else (match_operator 1 "comparison_operator"
1626                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1627                                        (const_int 0)])
1628                       (pc)
1629                       (label_ref (match_operand 2 "" ""))))]
1630   ""
1631 {
1632   return output_cbranch (operands[1], operands[2], 2, 1,
1633                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1634                          ! final_sequence, insn);
1635 }
1636   [(set_attr "type" "branch")
1637    (set_attr "branch_type" "fcc")])
1638
1639 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1640 ;; in the architecture.
1641
1642 ;; There are no 32 bit brreg insns.
1643
1644 ;; XXX
1645 (define_insn "*normal_int_branch_sp64"
1646   [(set (pc)
1647         (if_then_else (match_operator 0 "v9_regcmp_op"
1648                                       [(match_operand:DI 1 "register_operand" "r")
1649                                        (const_int 0)])
1650                       (label_ref (match_operand 2 "" ""))
1651                       (pc)))]
1652   "TARGET_ARCH64"
1653 {
1654   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1655                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1656                           ! final_sequence, insn);
1657 }
1658   [(set_attr "type" "branch")
1659    (set_attr "branch_type" "reg")])
1660
1661 ;; XXX
1662 (define_insn "*inverted_int_branch_sp64"
1663   [(set (pc)
1664         (if_then_else (match_operator 0 "v9_regcmp_op"
1665                                       [(match_operand:DI 1 "register_operand" "r")
1666                                        (const_int 0)])
1667                       (pc)
1668                       (label_ref (match_operand 2 "" ""))))]
1669   "TARGET_ARCH64"
1670 {
1671   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1672                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1673                           ! final_sequence, insn);
1674 }
1675   [(set_attr "type" "branch")
1676    (set_attr "branch_type" "reg")])
1677 \f
1678 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1679 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1680 ;; that adds the PC value at the call point to operand 0.
1681
1682 (define_insn "load_pcrel_sym"
1683   [(set (match_operand 0 "register_operand" "=r")
1684         (unspec [(match_operand 1 "symbolic_operand" "")
1685                  (match_operand 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1686    (clobber (reg:SI 15))]
1687   ""
1688 {
1689   if (flag_delayed_branch)
1690     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1691   else
1692     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1693 }
1694   [(set (attr "type") (const_string "multi"))
1695    (set (attr "length")
1696         (if_then_else (eq_attr "delayed_branch" "true")
1697                       (const_int 3)
1698                       (const_int 4)))])
1699 \f
1700 ;; Move instructions
1701
1702 (define_expand "movqi"
1703   [(set (match_operand:QI 0 "general_operand" "")
1704         (match_operand:QI 1 "general_operand" ""))]
1705   ""
1706 {
1707   /* Working with CONST_INTs is easier, so convert
1708      a double if needed.  */
1709   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1710     {
1711       operands[1] = GEN_INT (trunc_int_for_mode
1712                              (CONST_DOUBLE_LOW (operands[1]), QImode));
1713     }
1714
1715   /* Handle sets of MEM first.  */
1716   if (GET_CODE (operands[0]) == MEM)
1717     {
1718       if (reg_or_0_operand (operands[1], QImode))
1719         goto movqi_is_ok;
1720
1721       if (! reload_in_progress)
1722         {
1723           operands[0] = validize_mem (operands[0]);
1724           operands[1] = force_reg (QImode, operands[1]);
1725         }
1726     }
1727
1728   /* Fixup TLS cases.  */
1729   if (tls_symbolic_operand (operands [1]))
1730     operands[1] = legitimize_tls_address (operands[1]);
1731
1732   /* Fixup PIC cases.  */
1733   if (flag_pic)
1734     {
1735       if (CONSTANT_P (operands[1])
1736           && pic_address_needs_scratch (operands[1]))
1737         operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1738
1739       if (symbolic_operand (operands[1], QImode))
1740         {
1741           operands[1] = legitimize_pic_address (operands[1],
1742                                                 QImode,
1743                                                 (reload_in_progress ?
1744                                                  operands[0] :
1745                                                  NULL_RTX));
1746           goto movqi_is_ok;
1747         }
1748     }
1749
1750   /* All QI constants require only one insn, so proceed.  */
1751
1752  movqi_is_ok:
1753   ;
1754 })
1755
1756 (define_insn "*movqi_insn"
1757   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1758         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1759   "(register_operand (operands[0], QImode)
1760     || reg_or_0_operand (operands[1], QImode))"
1761   "@
1762    mov\t%1, %0
1763    ldub\t%1, %0
1764    stb\t%r1, %0"
1765   [(set_attr "type" "*,load,store")
1766    (set_attr "us3load_type" "*,3cycle,*")])
1767
1768 (define_expand "movhi"
1769   [(set (match_operand:HI 0 "general_operand" "")
1770         (match_operand:HI 1 "general_operand" ""))]
1771   ""
1772 {
1773   /* Working with CONST_INTs is easier, so convert
1774      a double if needed.  */
1775   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1776     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1777
1778   /* Handle sets of MEM first.  */
1779   if (GET_CODE (operands[0]) == MEM)
1780     {
1781       if (reg_or_0_operand (operands[1], HImode))
1782         goto movhi_is_ok;
1783
1784       if (! reload_in_progress)
1785         {
1786           operands[0] = validize_mem (operands[0]);
1787           operands[1] = force_reg (HImode, operands[1]);
1788         }
1789     }
1790
1791   /* Fixup TLS cases.  */
1792   if (tls_symbolic_operand (operands [1]))
1793     operands[1] = legitimize_tls_address (operands[1]);
1794
1795   /* Fixup PIC cases.  */
1796   if (flag_pic)
1797     {
1798       if (CONSTANT_P (operands[1])
1799           && pic_address_needs_scratch (operands[1]))
1800         operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1801
1802       if (symbolic_operand (operands[1], HImode))
1803         {
1804           operands[1] = legitimize_pic_address (operands[1],
1805                                                 HImode,
1806                                                 (reload_in_progress ?
1807                                                  operands[0] :
1808                                                  NULL_RTX));
1809           goto movhi_is_ok;
1810         }
1811     }
1812
1813   /* This makes sure we will not get rematched due to splittage.  */
1814   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1815     ;
1816   else if (CONSTANT_P (operands[1])
1817            && GET_CODE (operands[1]) != HIGH
1818            && GET_CODE (operands[1]) != LO_SUM)
1819     {
1820       sparc_emit_set_const32 (operands[0], operands[1]);
1821       DONE;
1822     }
1823  movhi_is_ok:
1824   ;
1825 })
1826
1827 (define_insn "*movhi_const64_special"
1828   [(set (match_operand:HI 0 "register_operand" "=r")
1829         (match_operand:HI 1 "const64_high_operand" ""))]
1830   "TARGET_ARCH64"
1831   "sethi\t%%hi(%a1), %0")
1832
1833 (define_insn "*movhi_insn"
1834   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1835         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1836   "(register_operand (operands[0], HImode)
1837     || reg_or_0_operand (operands[1], HImode))"
1838   "@
1839    mov\t%1, %0
1840    sethi\t%%hi(%a1), %0
1841    lduh\t%1, %0
1842    sth\t%r1, %0"
1843   [(set_attr "type" "*,*,load,store")
1844    (set_attr "us3load_type" "*,*,3cycle,*")])
1845
1846 ;; We always work with constants here.
1847 (define_insn "*movhi_lo_sum"
1848   [(set (match_operand:HI 0 "register_operand" "=r")
1849         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1850                 (match_operand:HI 2 "small_int" "I")))]
1851   ""
1852   "or\t%1, %2, %0")
1853
1854 (define_expand "movsi"
1855   [(set (match_operand:SI 0 "general_operand" "")
1856         (match_operand:SI 1 "general_operand" ""))]
1857   ""
1858 {
1859   /* Working with CONST_INTs is easier, so convert
1860      a double if needed.  */
1861   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1862     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1863
1864   /* Handle sets of MEM first.  */
1865   if (GET_CODE (operands[0]) == MEM)
1866     {
1867       if (reg_or_0_operand (operands[1], SImode))
1868         goto movsi_is_ok;
1869
1870       if (! reload_in_progress)
1871         {
1872           operands[0] = validize_mem (operands[0]);
1873           operands[1] = force_reg (SImode, operands[1]);
1874         }
1875     }
1876
1877   /* Fixup TLS cases.  */
1878   if (tls_symbolic_operand (operands [1]))
1879     operands[1] = legitimize_tls_address (operands[1]);
1880
1881   /* Fixup PIC cases.  */
1882   if (flag_pic)
1883     {
1884       if (CONSTANT_P (operands[1])
1885           && pic_address_needs_scratch (operands[1]))
1886         operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1887
1888       if (GET_CODE (operands[1]) == LABEL_REF)
1889         {
1890           /* shit */
1891           emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1892           DONE;
1893         }
1894
1895       if (symbolic_operand (operands[1], SImode))
1896         {
1897           operands[1] = legitimize_pic_address (operands[1],
1898                                                 SImode,
1899                                                 (reload_in_progress ?
1900                                                  operands[0] :
1901                                                  NULL_RTX));
1902           goto movsi_is_ok;
1903         }
1904     }
1905
1906   /* If we are trying to toss an integer constant into the
1907      FPU registers, force it into memory.  */
1908   if (GET_CODE (operands[0]) == REG
1909       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1910       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1911       && CONSTANT_P (operands[1]))
1912     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1913                                                  operands[1]));
1914
1915   /* This makes sure we will not get rematched due to splittage.  */
1916   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1917     ;
1918   else if (CONSTANT_P (operands[1])
1919            && GET_CODE (operands[1]) != HIGH
1920            && GET_CODE (operands[1]) != LO_SUM)
1921     {
1922       sparc_emit_set_const32 (operands[0], operands[1]);
1923       DONE;
1924     }
1925  movsi_is_ok:
1926   ;
1927 })
1928
1929 ;; This is needed to show CSE exactly which bits are set
1930 ;; in a 64-bit register by sethi instructions.
1931 (define_insn "*movsi_const64_special"
1932   [(set (match_operand:SI 0 "register_operand" "=r")
1933         (match_operand:SI 1 "const64_high_operand" ""))]
1934   "TARGET_ARCH64"
1935   "sethi\t%%hi(%a1), %0")
1936
1937 (define_insn "*movsi_insn"
1938   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1939         (match_operand:SI 1 "input_operand"   "rI,!f,K,J,m,!m,rJ,!f,J"))]
1940   "(register_operand (operands[0], SImode)
1941     || reg_or_0_operand (operands[1], SImode))"
1942   "@
1943    mov\t%1, %0
1944    fmovs\t%1, %0
1945    sethi\t%%hi(%a1), %0
1946    clr\t%0
1947    ld\t%1, %0
1948    ld\t%1, %0
1949    st\t%r1, %0
1950    st\t%1, %0
1951    fzeros\t%0"
1952   [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1953
1954 (define_insn "*movsi_lo_sum"
1955   [(set (match_operand:SI 0 "register_operand" "=r")
1956         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1957                    (match_operand:SI 2 "immediate_operand" "in")))]
1958   ""
1959   "or\t%1, %%lo(%a2), %0")
1960
1961 (define_insn "*movsi_high"
1962   [(set (match_operand:SI 0 "register_operand" "=r")
1963         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1964   ""
1965   "sethi\t%%hi(%a1), %0")
1966
1967 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1968 ;; so that CSE won't optimize the address computation away.
1969 (define_insn "movsi_lo_sum_pic"
1970   [(set (match_operand:SI 0 "register_operand" "=r")
1971         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1972                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1973   "flag_pic"
1974   "or\t%1, %%lo(%a2), %0")
1975
1976 (define_insn "movsi_high_pic"
1977   [(set (match_operand:SI 0 "register_operand" "=r")
1978         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1979   "flag_pic && check_pic (1)"
1980   "sethi\t%%hi(%a1), %0")
1981
1982 (define_expand "movsi_pic_label_ref"
1983   [(set (match_dup 3) (high:SI
1984      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1985                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1986    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1987      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1988    (set (match_operand:SI 0 "register_operand" "=r")
1989         (minus:SI (match_dup 5) (match_dup 4)))]
1990   "flag_pic"
1991 {
1992   current_function_uses_pic_offset_table = 1;
1993   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1994   if (no_new_pseudos)
1995     {
1996       operands[3] = operands[0];
1997       operands[4] = operands[0];
1998     }
1999   else
2000     {
2001       operands[3] = gen_reg_rtx (SImode);
2002       operands[4] = gen_reg_rtx (SImode);
2003     }
2004   operands[5] = pic_offset_table_rtx;
2005 })
2006
2007 (define_insn "*movsi_high_pic_label_ref"
2008   [(set (match_operand:SI 0 "register_operand" "=r")
2009       (high:SI
2010         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2011                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2012   "flag_pic"
2013   "sethi\t%%hi(%a2-(%a1-.)), %0")
2014
2015 (define_insn "*movsi_lo_sum_pic_label_ref"
2016   [(set (match_operand:SI 0 "register_operand" "=r")
2017       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2018         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2019                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2020   "flag_pic"
2021   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2022
2023 (define_expand "movdi"
2024   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2025         (match_operand:DI 1 "general_operand" ""))]
2026   ""
2027 {
2028   /* Where possible, convert CONST_DOUBLE into a CONST_INT.  */
2029   if (GET_CODE (operands[1]) == CONST_DOUBLE
2030 #if HOST_BITS_PER_WIDE_INT == 32
2031       && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2032            && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2033           || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2034               && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2035 #endif
2036       )
2037     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2038
2039   /* Handle MEM cases first.  */
2040   if (GET_CODE (operands[0]) == MEM)
2041     {
2042       /* If it's a REG, we can always do it.
2043          The const zero case is more complex, on v9
2044          we can always perform it.  */
2045       if (register_operand (operands[1], DImode)
2046           || (TARGET_V9
2047               && (operands[1] == const0_rtx)))
2048         goto movdi_is_ok;
2049
2050       if (! reload_in_progress)
2051         {
2052           operands[0] = validize_mem (operands[0]);
2053           operands[1] = force_reg (DImode, operands[1]);
2054         }
2055     }
2056
2057   /* Fixup TLS cases.  */
2058   if (tls_symbolic_operand (operands [1]))
2059     operands[1] = legitimize_tls_address (operands[1]);
2060
2061   if (flag_pic)
2062     {
2063       if (CONSTANT_P (operands[1])
2064           && pic_address_needs_scratch (operands[1]))
2065         operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2066
2067       if (GET_CODE (operands[1]) == LABEL_REF)
2068         {
2069           if (! TARGET_ARCH64)
2070             abort ();
2071           emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2072           DONE;
2073         }
2074
2075       if (symbolic_operand (operands[1], DImode))
2076         {
2077           operands[1] = legitimize_pic_address (operands[1],
2078                                                 DImode,
2079                                                 (reload_in_progress ?
2080                                                  operands[0] :
2081                                                  NULL_RTX));
2082           goto movdi_is_ok;
2083         }
2084     }
2085
2086   /* If we are trying to toss an integer constant into the
2087      FPU registers, force it into memory.  */
2088   if (GET_CODE (operands[0]) == REG
2089       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2090       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2091       && CONSTANT_P (operands[1]))
2092     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2093                                                  operands[1]));
2094
2095   /* This makes sure we will not get rematched due to splittage.  */
2096   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2097     ;
2098   else if (TARGET_ARCH64
2099            && CONSTANT_P (operands[1])
2100            && GET_CODE (operands[1]) != HIGH
2101            && GET_CODE (operands[1]) != LO_SUM)
2102     {
2103       sparc_emit_set_const64 (operands[0], operands[1]);
2104       DONE;
2105     }
2106
2107  movdi_is_ok:
2108   ;
2109 })
2110
2111 ;; Be careful, fmovd does not exist when !v9.
2112 ;; We match MEM moves directly when we have correct even
2113 ;; numbered registers, but fall into splits otherwise.
2114 ;; The constraint ordering here is really important to
2115 ;; avoid insane problems in reload, especially for patterns
2116 ;; of the form:
2117 ;;
2118 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2119 ;;                       (const_int -5016)))
2120 ;;      (reg:DI 2 %g2))
2121 ;;
2122
2123 (define_insn "*movdi_insn_sp32_v9"
2124   [(set (match_operand:DI 0 "nonimmediate_operand"
2125                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2126         (match_operand:DI 1 "input_operand"
2127                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2128   "! TARGET_ARCH64 && TARGET_V9
2129    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2130   "@
2131    stx\t%%g0, %0
2132    #
2133    std\t%1, %0
2134    ldd\t%1, %0
2135    #
2136    #
2137    #
2138    #
2139    std\t%1, %0
2140    ldd\t%1, %0
2141    #
2142    #
2143    fmovd\\t%1, %0
2144    ldd\\t%1, %0
2145    std\\t%1, %0"
2146   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2147    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2148    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2149
2150 (define_insn "*movdi_insn_sp32"
2151   [(set (match_operand:DI 0 "nonimmediate_operand"
2152                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2153         (match_operand:DI 1 "input_operand"
2154                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2155   "! TARGET_ARCH64
2156    && (register_operand (operands[0], DImode)
2157        || register_operand (operands[1], DImode))"
2158   "@
2159    #
2160    std\t%1, %0
2161    ldd\t%1, %0
2162    #
2163    #
2164    #
2165    #
2166    std\t%1, %0
2167    ldd\t%1, %0
2168    #
2169    #
2170    #"
2171   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2172    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2173
2174 ;; The following are generated by sparc_emit_set_const64
2175 (define_insn "*movdi_sp64_dbl"
2176   [(set (match_operand:DI 0 "register_operand" "=r")
2177         (match_operand:DI 1 "const64_operand" ""))]
2178   "(TARGET_ARCH64
2179     && HOST_BITS_PER_WIDE_INT != 64)"
2180   "mov\t%1, %0")
2181
2182 ;; This is needed to show CSE exactly which bits are set
2183 ;; in a 64-bit register by sethi instructions.
2184 (define_insn "*movdi_const64_special"
2185   [(set (match_operand:DI 0 "register_operand" "=r")
2186         (match_operand:DI 1 "const64_high_operand" ""))]
2187   "TARGET_ARCH64"
2188   "sethi\t%%hi(%a1), %0")
2189
2190 (define_insn "*movdi_insn_sp64_novis"
2191   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2192         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e"))]
2193   "TARGET_ARCH64 && ! TARGET_VIS
2194    && (register_operand (operands[0], DImode)
2195        || reg_or_0_operand (operands[1], DImode))"
2196   "@
2197    mov\t%1, %0
2198    sethi\t%%hi(%a1), %0
2199    clr\t%0
2200    ldx\t%1, %0
2201    stx\t%r1, %0
2202    fmovd\t%1, %0
2203    ldd\t%1, %0
2204    std\t%1, %0"
2205   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2206    (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2207
2208 (define_insn "*movdi_insn_sp64_vis"
2209   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2210         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e,J"))]
2211   "TARGET_ARCH64 && TARGET_VIS &&
2212    (register_operand (operands[0], DImode)
2213     || reg_or_0_operand (operands[1], DImode))"
2214   "@
2215    mov\t%1, %0
2216    sethi\t%%hi(%a1), %0
2217    clr\t%0
2218    ldx\t%1, %0
2219    stx\t%r1, %0
2220    fmovd\t%1, %0
2221    ldd\t%1, %0
2222    std\t%1, %0
2223    fzero\t%0"
2224   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2225    (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2226
2227 (define_expand "movdi_pic_label_ref"
2228   [(set (match_dup 3) (high:DI
2229      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2230                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2231    (set (match_dup 4) (lo_sum:DI (match_dup 3)
2232      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2233    (set (match_operand:DI 0 "register_operand" "=r")
2234         (minus:DI (match_dup 5) (match_dup 4)))]
2235   "TARGET_ARCH64 && flag_pic"
2236 {
2237   current_function_uses_pic_offset_table = 1;
2238   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2239   if (no_new_pseudos)
2240     {
2241       operands[3] = operands[0];
2242       operands[4] = operands[0];
2243     }
2244   else
2245     {
2246       operands[3] = gen_reg_rtx (DImode);
2247       operands[4] = gen_reg_rtx (DImode);
2248     }
2249   operands[5] = pic_offset_table_rtx;
2250 })
2251
2252 (define_insn "*movdi_high_pic_label_ref"
2253   [(set (match_operand:DI 0 "register_operand" "=r")
2254         (high:DI
2255           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2256                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2257   "TARGET_ARCH64 && flag_pic"
2258   "sethi\t%%hi(%a2-(%a1-.)), %0")
2259
2260 (define_insn "*movdi_lo_sum_pic_label_ref"
2261   [(set (match_operand:DI 0 "register_operand" "=r")
2262       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2263         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2264                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2265   "TARGET_ARCH64 && flag_pic"
2266   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2267
2268 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2269 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2270
2271 (define_insn "movdi_lo_sum_pic"
2272   [(set (match_operand:DI 0 "register_operand" "=r")
2273         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2274                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2275   "TARGET_ARCH64 && flag_pic"
2276   "or\t%1, %%lo(%a2), %0")
2277
2278 (define_insn "movdi_high_pic"
2279   [(set (match_operand:DI 0 "register_operand" "=r")
2280         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2281   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2282   "sethi\t%%hi(%a1), %0")
2283
2284 (define_insn "*sethi_di_medlow_embmedany_pic"
2285   [(set (match_operand:DI 0 "register_operand" "=r")
2286         (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2287   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2288   "sethi\t%%hi(%a1), %0")
2289
2290 (define_insn "*sethi_di_medlow"
2291   [(set (match_operand:DI 0 "register_operand" "=r")
2292         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2293   "TARGET_CM_MEDLOW && check_pic (1)"
2294   "sethi\t%%hi(%a1), %0")
2295
2296 (define_insn "*losum_di_medlow"
2297   [(set (match_operand:DI 0 "register_operand" "=r")
2298         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2299                    (match_operand:DI 2 "symbolic_operand" "")))]
2300   "TARGET_CM_MEDLOW"
2301   "or\t%1, %%lo(%a2), %0")
2302
2303 (define_insn "seth44"
2304   [(set (match_operand:DI 0 "register_operand" "=r")
2305         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2306   "TARGET_CM_MEDMID"
2307   "sethi\t%%h44(%a1), %0")
2308
2309 (define_insn "setm44"
2310   [(set (match_operand:DI 0 "register_operand" "=r")
2311         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2312                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2313   "TARGET_CM_MEDMID"
2314   "or\t%1, %%m44(%a2), %0")
2315
2316 (define_insn "setl44"
2317   [(set (match_operand:DI 0 "register_operand" "=r")
2318         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2319                    (match_operand:DI 2 "symbolic_operand" "")))]
2320   "TARGET_CM_MEDMID"
2321   "or\t%1, %%l44(%a2), %0")
2322
2323 (define_insn "sethh"
2324   [(set (match_operand:DI 0 "register_operand" "=r")
2325         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2326   "TARGET_CM_MEDANY"
2327   "sethi\t%%hh(%a1), %0")
2328
2329 (define_insn "setlm"
2330   [(set (match_operand:DI 0 "register_operand" "=r")
2331         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2332   "TARGET_CM_MEDANY"
2333   "sethi\t%%lm(%a1), %0")
2334
2335 (define_insn "sethm"
2336   [(set (match_operand:DI 0 "register_operand" "=r")
2337         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2338                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2339   "TARGET_CM_MEDANY"
2340   "or\t%1, %%hm(%a2), %0")
2341
2342 (define_insn "setlo"
2343   [(set (match_operand:DI 0 "register_operand" "=r")
2344         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2345                    (match_operand:DI 2 "symbolic_operand" "")))]
2346   "TARGET_CM_MEDANY"
2347   "or\t%1, %%lo(%a2), %0")
2348
2349 (define_insn "embmedany_sethi"
2350   [(set (match_operand:DI 0 "register_operand" "=r")
2351         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2352   "TARGET_CM_EMBMEDANY && check_pic (1)"
2353   "sethi\t%%hi(%a1), %0")
2354
2355 (define_insn "embmedany_losum"
2356   [(set (match_operand:DI 0 "register_operand" "=r")
2357         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2358                    (match_operand:DI 2 "data_segment_operand" "")))]
2359   "TARGET_CM_EMBMEDANY"
2360   "add\t%1, %%lo(%a2), %0")
2361
2362 (define_insn "embmedany_brsum"
2363   [(set (match_operand:DI 0 "register_operand" "=r")
2364         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2365   "TARGET_CM_EMBMEDANY"
2366   "add\t%1, %_, %0")
2367
2368 (define_insn "embmedany_textuhi"
2369   [(set (match_operand:DI 0 "register_operand" "=r")
2370         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2371   "TARGET_CM_EMBMEDANY && check_pic (1)"
2372   "sethi\t%%uhi(%a1), %0")
2373
2374 (define_insn "embmedany_texthi"
2375   [(set (match_operand:DI 0 "register_operand" "=r")
2376         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2377   "TARGET_CM_EMBMEDANY && check_pic (1)"
2378   "sethi\t%%hi(%a1), %0")
2379
2380 (define_insn "embmedany_textulo"
2381   [(set (match_operand:DI 0 "register_operand" "=r")
2382         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2383                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2384   "TARGET_CM_EMBMEDANY"
2385   "or\t%1, %%ulo(%a2), %0")
2386
2387 (define_insn "embmedany_textlo"
2388   [(set (match_operand:DI 0 "register_operand" "=r")
2389         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2390                    (match_operand:DI 2 "text_segment_operand" "")))]
2391   "TARGET_CM_EMBMEDANY"
2392   "or\t%1, %%lo(%a2), %0")
2393
2394 ;; Now some patterns to help reload out a bit.
2395 (define_expand "reload_indi"
2396   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2397               (match_operand:DI 1 "immediate_operand" "")
2398               (match_operand:TI 2 "register_operand" "=&r")])]
2399   "(TARGET_CM_MEDANY
2400     || TARGET_CM_EMBMEDANY)
2401    && ! flag_pic"
2402 {
2403   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2404   DONE;
2405 })
2406
2407 (define_expand "reload_outdi"
2408   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2409               (match_operand:DI 1 "immediate_operand" "")
2410               (match_operand:TI 2 "register_operand" "=&r")])]
2411   "(TARGET_CM_MEDANY
2412     || TARGET_CM_EMBMEDANY)
2413    && ! flag_pic"
2414 {
2415   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2416   DONE;
2417 })
2418
2419 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2420 (define_split
2421   [(set (match_operand:DI 0 "register_operand" "")
2422         (match_operand:DI 1 "const_int_operand" ""))]
2423   "! TARGET_ARCH64 && reload_completed"
2424   [(clobber (const_int 0))]
2425 {
2426 #if HOST_BITS_PER_WIDE_INT == 32
2427   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2428                         (INTVAL (operands[1]) < 0) ?
2429                         constm1_rtx :
2430                         const0_rtx));
2431   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2432                         operands[1]));
2433 #else
2434   unsigned int low, high;
2435
2436   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2437   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2438   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2439
2440   /* Slick... but this trick loses if this subreg constant part
2441      can be done in one insn.  */
2442   if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2443     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2444                           gen_highpart (SImode, operands[0])));
2445   else
2446     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2447 #endif
2448   DONE;
2449 })
2450
2451 (define_split
2452   [(set (match_operand:DI 0 "register_operand" "")
2453         (match_operand:DI 1 "const_double_operand" ""))]
2454   "reload_completed
2455    && (! TARGET_V9
2456        || (! TARGET_ARCH64
2457            && ((GET_CODE (operands[0]) == REG
2458                 && REGNO (operands[0]) < 32)
2459                || (GET_CODE (operands[0]) == SUBREG
2460                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2461                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2462   [(clobber (const_int 0))]
2463 {
2464   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2465                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2466
2467   /* Slick... but this trick loses if this subreg constant part
2468      can be done in one insn.  */
2469   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2470       && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2471            || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2472     {
2473       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2474                             gen_highpart (SImode, operands[0])));
2475     }
2476   else
2477     {
2478       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2479                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2480     }
2481   DONE;
2482 })
2483
2484 (define_split
2485   [(set (match_operand:DI 0 "register_operand" "")
2486         (match_operand:DI 1 "register_operand" ""))]
2487   "reload_completed
2488    && (! TARGET_V9
2489        || (! TARGET_ARCH64
2490            && ((GET_CODE (operands[0]) == REG
2491                 && REGNO (operands[0]) < 32)
2492                || (GET_CODE (operands[0]) == SUBREG
2493                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2494                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2495   [(clobber (const_int 0))]
2496 {
2497   rtx set_dest = operands[0];
2498   rtx set_src = operands[1];
2499   rtx dest1, dest2;
2500   rtx src1, src2;
2501
2502   dest1 = gen_highpart (SImode, set_dest);
2503   dest2 = gen_lowpart (SImode, set_dest);
2504   src1 = gen_highpart (SImode, set_src);
2505   src2 = gen_lowpart (SImode, set_src);
2506
2507   /* Now emit using the real source and destination we found, swapping
2508      the order if we detect overlap.  */
2509   if (reg_overlap_mentioned_p (dest1, src2))
2510     {
2511       emit_insn (gen_movsi (dest2, src2));
2512       emit_insn (gen_movsi (dest1, src1));
2513     }
2514   else
2515     {
2516       emit_insn (gen_movsi (dest1, src1));
2517       emit_insn (gen_movsi (dest2, src2));
2518     }
2519   DONE;
2520 })
2521
2522 ;; Now handle the cases of memory moves from/to non-even
2523 ;; DI mode register pairs.
2524 (define_split
2525   [(set (match_operand:DI 0 "register_operand" "")
2526         (match_operand:DI 1 "memory_operand" ""))]
2527   "(! TARGET_ARCH64
2528     && reload_completed
2529     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2530   [(clobber (const_int 0))]
2531 {
2532   rtx word0 = adjust_address (operands[1], SImode, 0);
2533   rtx word1 = adjust_address (operands[1], SImode, 4);
2534   rtx high_part = gen_highpart (SImode, operands[0]);
2535   rtx low_part = gen_lowpart (SImode, operands[0]);
2536
2537   if (reg_overlap_mentioned_p (high_part, word1))
2538     {
2539       emit_insn (gen_movsi (low_part, word1));
2540       emit_insn (gen_movsi (high_part, word0));
2541     }
2542   else
2543     {
2544       emit_insn (gen_movsi (high_part, word0));
2545       emit_insn (gen_movsi (low_part, word1));
2546     }
2547   DONE;
2548 })
2549
2550 (define_split
2551   [(set (match_operand:DI 0 "memory_operand" "")
2552         (match_operand:DI 1 "register_operand" ""))]
2553   "(! TARGET_ARCH64
2554     && reload_completed
2555     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2556   [(clobber (const_int 0))]
2557 {
2558   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2559                         gen_highpart (SImode, operands[1])));
2560   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2561                         gen_lowpart (SImode, operands[1])));
2562   DONE;
2563 })
2564
2565 (define_split
2566   [(set (match_operand:DI 0 "memory_operand" "")
2567         (const_int 0))]
2568   "reload_completed
2569    && (! TARGET_V9
2570        || (! TARGET_ARCH64
2571            && ! mem_min_alignment (operands[0], 8)))
2572    && offsettable_memref_p (operands[0])"
2573   [(clobber (const_int 0))]
2574 {
2575   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2576   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2577   DONE;
2578 })
2579 \f
2580 ;; Floating point move insns
2581
2582 (define_insn "*movsf_insn_novis"
2583   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2584         (match_operand:SF 1 "input_operand"         "f,G,Q,*rR,S,m,m,f,*rG"))]
2585   "(TARGET_FPU && ! TARGET_VIS)
2586    && (register_operand (operands[0], SFmode)
2587        || register_operand (operands[1], SFmode)
2588        || fp_zero_operand (operands[1], SFmode))"
2589 {
2590   if (GET_CODE (operands[1]) == CONST_DOUBLE
2591       && (which_alternative == 2
2592           || which_alternative == 3
2593           || which_alternative == 4))
2594     {
2595       REAL_VALUE_TYPE r;
2596       long i;
2597
2598       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2599       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2600       operands[1] = GEN_INT (i);
2601     }
2602
2603   switch (which_alternative)
2604     {
2605     case 0:
2606       return "fmovs\t%1, %0";
2607     case 1:
2608       return "clr\t%0";
2609     case 2:
2610       return "sethi\t%%hi(%a1), %0";
2611     case 3:
2612       return "mov\t%1, %0";
2613     case 4:
2614       return "#";
2615     case 5:
2616     case 6:
2617       return "ld\t%1, %0";
2618     case 7:
2619     case 8:
2620       return "st\t%r1, %0";
2621     default:
2622       abort();
2623     }
2624 }
2625   [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2626
2627 (define_insn "*movsf_insn_vis"
2628   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2629         (match_operand:SF 1 "input_operand"         "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2630   "(TARGET_FPU && TARGET_VIS)
2631    && (register_operand (operands[0], SFmode)
2632        || register_operand (operands[1], SFmode)
2633        || fp_zero_operand (operands[1], SFmode))"
2634 {
2635   if (GET_CODE (operands[1]) == CONST_DOUBLE
2636       && (which_alternative == 3
2637           || which_alternative == 4
2638           || which_alternative == 5))
2639     {
2640       REAL_VALUE_TYPE r;
2641       long i;
2642
2643       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2644       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2645       operands[1] = GEN_INT (i);
2646     }
2647
2648   switch (which_alternative)
2649     {
2650     case 0:
2651       return "fmovs\t%1, %0";
2652     case 1:
2653       return "fzeros\t%0";
2654     case 2:
2655       return "clr\t%0";
2656     case 3:
2657       return "sethi\t%%hi(%a1), %0";
2658     case 4:
2659       return "mov\t%1, %0";
2660     case 5:
2661       return "#";
2662     case 6:
2663     case 7:
2664       return "ld\t%1, %0";
2665     case 8:
2666     case 9:
2667       return "st\t%r1, %0";
2668     default:
2669       abort();
2670     }
2671 }
2672   [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2673
2674 ;; Exactly the same as above, except that all `f' cases are deleted.
2675 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2676 ;; when -mno-fpu.
2677
2678 (define_insn "*movsf_no_f_insn"
2679   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2680         (match_operand:SF 1 "input_operand"    "G,Q,rR,S,m,rG"))]
2681   "! TARGET_FPU
2682    && (register_operand (operands[0], SFmode)
2683        || register_operand (operands[1], SFmode)
2684        || fp_zero_operand (operands[1], SFmode))"
2685 {
2686   if (GET_CODE (operands[1]) == CONST_DOUBLE
2687       && (which_alternative == 1
2688           || which_alternative == 2
2689           || which_alternative == 3))
2690     {
2691       REAL_VALUE_TYPE r;
2692       long i;
2693
2694       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2695       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2696       operands[1] = GEN_INT (i);
2697     }
2698
2699   switch (which_alternative)
2700     {
2701     case 0:
2702       return "clr\t%0";
2703     case 1:
2704       return "sethi\t%%hi(%a1), %0";
2705     case 2:
2706       return "mov\t%1, %0";
2707     case 3:
2708       return "#";
2709     case 4:
2710       return "ld\t%1, %0";
2711     case 5:
2712       return "st\t%r1, %0";
2713     default:
2714       abort();
2715     }
2716 }
2717   [(set_attr "type" "*,*,*,*,load,store")])
2718
2719 (define_insn "*movsf_lo_sum"
2720   [(set (match_operand:SF 0 "register_operand" "=r")
2721         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2722                    (match_operand:SF 2 "const_double_operand" "S")))]
2723   "fp_high_losum_p (operands[2])"
2724 {
2725   REAL_VALUE_TYPE r;
2726   long i;
2727
2728   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2729   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2730   operands[2] = GEN_INT (i);
2731   return "or\t%1, %%lo(%a2), %0";
2732 })
2733
2734 (define_insn "*movsf_high"
2735   [(set (match_operand:SF 0 "register_operand" "=r")
2736         (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2737   "fp_high_losum_p (operands[1])"
2738 {
2739   REAL_VALUE_TYPE r;
2740   long i;
2741
2742   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2743   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2744   operands[1] = GEN_INT (i);
2745   return "sethi\t%%hi(%1), %0";
2746 })
2747
2748 (define_split
2749   [(set (match_operand:SF 0 "register_operand" "")
2750         (match_operand:SF 1 "const_double_operand" ""))]
2751   "fp_high_losum_p (operands[1])
2752    && (GET_CODE (operands[0]) == REG
2753        && REGNO (operands[0]) < 32)"
2754   [(set (match_dup 0) (high:SF (match_dup 1)))
2755    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2756
2757 (define_expand "movsf"
2758   [(set (match_operand:SF 0 "general_operand" "")
2759         (match_operand:SF 1 "general_operand" ""))]
2760   ""
2761 {
2762   /* Force SFmode constants into memory.  */
2763   if (GET_CODE (operands[0]) == REG
2764       && CONSTANT_P (operands[1]))
2765     {
2766       /* emit_group_store will send such bogosity to us when it is
2767          not storing directly into memory.  So fix this up to avoid
2768          crashes in output_constant_pool.  */
2769       if (operands [1] == const0_rtx)
2770         operands[1] = CONST0_RTX (SFmode);
2771
2772       if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2773         goto movsf_is_ok;
2774
2775       /* We are able to build any SF constant in integer registers
2776          with at most 2 instructions.  */
2777       if (REGNO (operands[0]) < 32)
2778         goto movsf_is_ok;
2779
2780       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2781                                                    operands[1]));
2782     }
2783
2784   /* Handle sets of MEM first.  */
2785   if (GET_CODE (operands[0]) == MEM)
2786     {
2787       if (register_operand (operands[1], SFmode)
2788           || fp_zero_operand (operands[1], SFmode))
2789         goto movsf_is_ok;
2790
2791       if (! reload_in_progress)
2792         {
2793           operands[0] = validize_mem (operands[0]);
2794           operands[1] = force_reg (SFmode, operands[1]);
2795         }
2796     }
2797
2798   /* Fixup PIC cases.  */
2799   if (flag_pic)
2800     {
2801       if (CONSTANT_P (operands[1])
2802           && pic_address_needs_scratch (operands[1]))
2803         operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2804
2805       if (symbolic_operand (operands[1], SFmode))
2806         {
2807           operands[1] = legitimize_pic_address (operands[1],
2808                                                 SFmode,
2809                                                 (reload_in_progress ?
2810                                                  operands[0] :
2811                                                  NULL_RTX));
2812         }
2813     }
2814
2815  movsf_is_ok:
2816   ;
2817 })
2818
2819 (define_expand "movdf"
2820   [(set (match_operand:DF 0 "general_operand" "")
2821         (match_operand:DF 1 "general_operand" ""))]
2822   ""
2823 {
2824   /* Force DFmode constants into memory.  */
2825   if (GET_CODE (operands[0]) == REG
2826       && CONSTANT_P (operands[1]))
2827     {
2828       /* emit_group_store will send such bogosity to us when it is
2829          not storing directly into memory.  So fix this up to avoid
2830          crashes in output_constant_pool.  */
2831       if (operands [1] == const0_rtx)
2832         operands[1] = CONST0_RTX (DFmode);
2833
2834       if ((TARGET_VIS || REGNO (operands[0]) < 32)
2835           && fp_zero_operand (operands[1], DFmode))
2836         goto movdf_is_ok;
2837
2838       /* We are able to build any DF constant in integer registers.  */
2839       if (REGNO (operands[0]) < 32
2840           && (reload_completed || reload_in_progress))
2841         goto movdf_is_ok;
2842
2843       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2844                                                    operands[1]));
2845     }
2846
2847   /* Handle MEM cases first.  */
2848   if (GET_CODE (operands[0]) == MEM)
2849     {
2850       if (register_operand (operands[1], DFmode)
2851           || fp_zero_operand (operands[1], DFmode))
2852         goto movdf_is_ok;
2853
2854       if (! reload_in_progress)
2855         {
2856           operands[0] = validize_mem (operands[0]);
2857           operands[1] = force_reg (DFmode, operands[1]);
2858         }
2859     }
2860
2861   /* Fixup PIC cases.  */
2862   if (flag_pic)
2863     {
2864       if (CONSTANT_P (operands[1])
2865           && pic_address_needs_scratch (operands[1]))
2866         operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2867
2868       if (symbolic_operand (operands[1], DFmode))
2869         {
2870           operands[1] = legitimize_pic_address (operands[1],
2871                                                 DFmode,
2872                                                 (reload_in_progress ?
2873                                                  operands[0] :
2874                                                  NULL_RTX));
2875         }
2876     }
2877
2878  movdf_is_ok:
2879   ;
2880 })
2881
2882 ;; Be careful, fmovd does not exist when !v9.
2883 (define_insn "*movdf_insn_sp32"
2884   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2885         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2886   "TARGET_FPU
2887    && ! TARGET_V9
2888    && (register_operand (operands[0], DFmode)
2889        || register_operand (operands[1], DFmode)
2890        || fp_zero_operand (operands[1], DFmode))"
2891   "@
2892   ldd\t%1, %0
2893   std\t%1, %0
2894   ldd\t%1, %0
2895   std\t%1, %0
2896   #
2897   #
2898   #
2899   #
2900   #
2901   #"
2902  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2903   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2904
2905 (define_insn "*movdf_no_e_insn_sp32"
2906   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2907         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2908   "! TARGET_FPU
2909    && ! TARGET_V9
2910    && ! TARGET_ARCH64
2911    && (register_operand (operands[0], DFmode)
2912        || register_operand (operands[1], DFmode)
2913        || fp_zero_operand (operands[1], DFmode))"
2914   "@
2915   ldd\t%1, %0
2916   std\t%1, %0
2917   #
2918   #
2919   #"
2920   [(set_attr "type" "load,store,*,*,*")
2921    (set_attr "length" "*,*,2,2,2")])
2922
2923 (define_insn "*movdf_no_e_insn_v9_sp32"
2924   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2925         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2926   "! TARGET_FPU
2927    && TARGET_V9
2928    && ! TARGET_ARCH64
2929    && (register_operand (operands[0], DFmode)
2930        || register_operand (operands[1], DFmode)
2931        || fp_zero_operand (operands[1], DFmode))"
2932   "@
2933   ldd\t%1, %0
2934   std\t%1, %0
2935   stx\t%r1, %0
2936   #
2937   #"
2938   [(set_attr "type" "load,store,store,*,*")
2939    (set_attr "length" "*,*,*,2,2")])
2940
2941 ;; We have available v9 double floats but not 64-bit
2942 ;; integer registers and no VIS.
2943 (define_insn "*movdf_insn_v9only_novis"
2944   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2945         (match_operand:DF 1 "input_operand"    "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2946   "TARGET_FPU
2947    && TARGET_V9
2948    && ! TARGET_VIS
2949    && ! TARGET_ARCH64
2950    && (register_operand (operands[0], DFmode)
2951        || register_operand (operands[1], DFmode)
2952        || fp_zero_operand (operands[1], DFmode))"
2953   "@
2954   fmovd\t%1, %0
2955   ldd\t%1, %0
2956   stx\t%r1, %0
2957   std\t%1, %0
2958   ldd\t%1, %0
2959   std\t%1, %0
2960   #
2961   #
2962   #"
2963   [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2964    (set_attr "length" "*,*,*,*,*,*,2,2,2")
2965    (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2966
2967 ;; We have available v9 double floats but not 64-bit
2968 ;; integer registers but we have VIS.
2969 (define_insn "*movdf_insn_v9only_vis"
2970   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2971         (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2972   "TARGET_FPU
2973    && TARGET_VIS
2974    && ! TARGET_ARCH64
2975    && (register_operand (operands[0], DFmode)
2976        || register_operand (operands[1], DFmode)
2977        || fp_zero_operand (operands[1], DFmode))"
2978   "@
2979   fzero\t%0
2980   fmovd\t%1, %0
2981   ldd\t%1, %0
2982   stx\t%r1, %0
2983   std\t%1, %0
2984   ldd\t%1, %0
2985   std\t%1, %0
2986   #
2987   #
2988   #"
2989   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2990    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2991    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2992
2993 ;; We have available both v9 double floats and 64-bit
2994 ;; integer registers. No VIS though.
2995 (define_insn "*movdf_insn_sp64_novis"
2996   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2997         (match_operand:DF 1 "input_operand"    "e,W#F,e,*rG,m,*rG,F"))]
2998   "TARGET_FPU
2999    && ! TARGET_VIS
3000    && TARGET_ARCH64
3001    && (register_operand (operands[0], DFmode)
3002        || register_operand (operands[1], DFmode)
3003        || fp_zero_operand (operands[1], DFmode))"
3004   "@
3005   fmovd\t%1, %0
3006   ldd\t%1, %0
3007   std\t%1, %0
3008   mov\t%r1, %0
3009   ldx\t%1, %0
3010   stx\t%r1, %0
3011   #"
3012   [(set_attr "type" "fpmove,load,store,*,load,store,*")
3013    (set_attr "length" "*,*,*,*,*,*,2")
3014    (set_attr "fptype" "double,*,*,*,*,*,*")])
3015
3016 ;; We have available both v9 double floats and 64-bit
3017 ;; integer registers. And we have VIS.
3018 (define_insn "*movdf_insn_sp64_vis"
3019   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3020         (match_operand:DF 1 "input_operand"    "G,e,W#F,e,*rG,m,*rG,F"))]
3021   "TARGET_FPU
3022    && TARGET_VIS
3023    && TARGET_ARCH64
3024    && (register_operand (operands[0], DFmode)
3025        || register_operand (operands[1], DFmode)
3026        || fp_zero_operand (operands[1], DFmode))"
3027   "@
3028   fzero\t%0
3029   fmovd\t%1, %0
3030   ldd\t%1, %0
3031   std\t%1, %0
3032   mov\t%r1, %0
3033   ldx\t%1, %0
3034   stx\t%r1, %0
3035   #"
3036   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3037    (set_attr "length" "*,*,*,*,*,*,*,2")
3038    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3039
3040 (define_insn "*movdf_no_e_insn_sp64"
3041   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3042         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
3043   "! TARGET_FPU
3044    && TARGET_ARCH64
3045    && (register_operand (operands[0], DFmode)
3046        || register_operand (operands[1], DFmode)
3047        || fp_zero_operand (operands[1], DFmode))"
3048   "@
3049   mov\t%1, %0
3050   ldx\t%1, %0
3051   stx\t%r1, %0"
3052   [(set_attr "type" "*,load,store")])
3053
3054 (define_split
3055   [(set (match_operand:DF 0 "register_operand" "")
3056         (match_operand:DF 1 "const_double_operand" ""))]
3057   "TARGET_FPU
3058    && (GET_CODE (operands[0]) == REG
3059        && REGNO (operands[0]) < 32)
3060    && ! fp_zero_operand(operands[1], DFmode)
3061    && reload_completed"
3062   [(clobber (const_int 0))]
3063 {
3064   REAL_VALUE_TYPE r;
3065   long l[2];
3066
3067   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3068   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3069   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3070
3071   if (TARGET_ARCH64)
3072     {
3073 #if HOST_BITS_PER_WIDE_INT == 64
3074       HOST_WIDE_INT val;
3075
3076       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3077              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3078       emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3079 #else
3080       emit_insn (gen_movdi (operands[0],
3081                             immed_double_const (l[1], l[0], DImode)));
3082 #endif
3083     }
3084   else
3085     {
3086       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3087                             GEN_INT (l[0])));
3088
3089       /* Slick... but this trick loses if this subreg constant part
3090          can be done in one insn.  */
3091       if (l[1] == l[0]
3092           && !(SPARC_SETHI32_P (l[0])
3093                || SPARC_SIMM13_P (l[0])))
3094         {
3095           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3096                                 gen_highpart (SImode, operands[0])));
3097         }
3098       else
3099         {
3100           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3101                                 GEN_INT (l[1])));
3102         }
3103     }
3104   DONE;
3105 })
3106
3107 ;; Ok, now the splits to handle all the multi insn and
3108 ;; mis-aligned memory address cases.
3109 ;; In these splits please take note that we must be
3110 ;; careful when V9 but not ARCH64 because the integer
3111 ;; register DFmode cases must be handled.
3112 (define_split
3113   [(set (match_operand:DF 0 "register_operand" "")
3114         (match_operand:DF 1 "register_operand" ""))]
3115   "(! TARGET_V9
3116     || (! TARGET_ARCH64
3117         && ((GET_CODE (operands[0]) == REG
3118              && REGNO (operands[0]) < 32)
3119             || (GET_CODE (operands[0]) == SUBREG
3120                 && GET_CODE (SUBREG_REG (operands[0])) == REG
3121                 && REGNO (SUBREG_REG (operands[0])) < 32))))
3122    && reload_completed"
3123   [(clobber (const_int 0))]
3124 {
3125   rtx set_dest = operands[0];
3126   rtx set_src = operands[1];
3127   rtx dest1, dest2;
3128   rtx src1, src2;
3129
3130   dest1 = gen_highpart (SFmode, set_dest);
3131   dest2 = gen_lowpart (SFmode, set_dest);
3132   src1 = gen_highpart (SFmode, set_src);
3133   src2 = gen_lowpart (SFmode, set_src);
3134
3135   /* Now emit using the real source and destination we found, swapping
3136      the order if we detect overlap.  */
3137   if (reg_overlap_mentioned_p (dest1, src2))
3138     {
3139       emit_insn (gen_movsf (dest2, src2));
3140       emit_insn (gen_movsf (dest1, src1));
3141     }
3142   else
3143     {
3144       emit_insn (gen_movsf (dest1, src1));
3145       emit_insn (gen_movsf (dest2, src2));
3146     }
3147   DONE;
3148 })
3149
3150 (define_split
3151   [(set (match_operand:DF 0 "register_operand" "")
3152         (match_operand:DF 1 "memory_operand" ""))]
3153   "reload_completed
3154    && ! TARGET_ARCH64
3155    && (((REGNO (operands[0]) % 2) != 0)
3156        || ! mem_min_alignment (operands[1], 8))
3157    && offsettable_memref_p (operands[1])"
3158   [(clobber (const_int 0))]
3159 {
3160   rtx word0 = adjust_address (operands[1], SFmode, 0);
3161   rtx word1 = adjust_address (operands[1], SFmode, 4);
3162
3163   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3164     {
3165       emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3166                             word1));
3167       emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3168                             word0));
3169     }
3170   else
3171     {
3172       emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3173                             word0));
3174       emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3175                             word1));
3176     }
3177   DONE;
3178 })
3179
3180 (define_split
3181   [(set (match_operand:DF 0 "memory_operand" "")
3182         (match_operand:DF 1 "register_operand" ""))]
3183   "reload_completed
3184    && ! TARGET_ARCH64
3185    && (((REGNO (operands[1]) % 2) != 0)
3186        || ! mem_min_alignment (operands[0], 8))
3187    && offsettable_memref_p (operands[0])"
3188   [(clobber (const_int 0))]
3189 {
3190   rtx word0 = adjust_address (operands[0], SFmode, 0);
3191   rtx word1 = adjust_address (operands[0], SFmode, 4);
3192
3193   emit_insn (gen_movsf (word0,
3194                         gen_highpart (SFmode, operands[1])));
3195   emit_insn (gen_movsf (word1,
3196                         gen_lowpart (SFmode, operands[1])));
3197   DONE;
3198 })
3199
3200 (define_split
3201   [(set (match_operand:DF 0 "memory_operand" "")
3202         (match_operand:DF 1 "fp_zero_operand" ""))]
3203   "reload_completed
3204    && (! TARGET_V9
3205        || (! TARGET_ARCH64
3206            && ! mem_min_alignment (operands[0], 8)))
3207    && offsettable_memref_p (operands[0])"
3208   [(clobber (const_int 0))]
3209 {
3210   rtx dest1, dest2;
3211
3212   dest1 = adjust_address (operands[0], SFmode, 0);
3213   dest2 = adjust_address (operands[0], SFmode, 4);
3214
3215   emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3216   emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3217   DONE;
3218 })
3219
3220 (define_split
3221   [(set (match_operand:DF 0 "register_operand" "")
3222         (match_operand:DF 1 "fp_zero_operand" ""))]
3223   "reload_completed
3224    && ! TARGET_ARCH64
3225    && ((GET_CODE (operands[0]) == REG
3226         && REGNO (operands[0]) < 32)
3227        || (GET_CODE (operands[0]) == SUBREG
3228            && GET_CODE (SUBREG_REG (operands[0])) == REG
3229            && REGNO (SUBREG_REG (operands[0])) < 32))"
3230   [(clobber (const_int 0))]
3231 {
3232   rtx set_dest = operands[0];
3233   rtx dest1, dest2;
3234
3235   dest1 = gen_highpart (SFmode, set_dest);
3236   dest2 = gen_lowpart (SFmode, set_dest);
3237   emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3238   emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3239   DONE;
3240 })
3241
3242 (define_expand "movtf"
3243   [(set (match_operand:TF 0 "general_operand" "")
3244         (match_operand:TF 1 "general_operand" ""))]
3245   ""
3246 {
3247   /* Force TFmode constants into memory.  */
3248   if (GET_CODE (operands[0]) == REG
3249       && CONSTANT_P (operands[1]))
3250     {
3251       /* emit_group_store will send such bogosity to us when it is
3252          not storing directly into memory.  So fix this up to avoid
3253          crashes in output_constant_pool.  */
3254       if (operands [1] == const0_rtx)
3255         operands[1] = CONST0_RTX (TFmode);
3256
3257       if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3258         goto movtf_is_ok;
3259
3260       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3261                                                    operands[1]));
3262     }
3263
3264   /* Handle MEM cases first, note that only v9 guarantees
3265      full 16-byte alignment for quads.  */
3266   if (GET_CODE (operands[0]) == MEM)
3267     {
3268       if (register_operand (operands[1], TFmode)
3269           || fp_zero_operand (operands[1], TFmode))
3270         goto movtf_is_ok;
3271
3272       if (! reload_in_progress)
3273         {
3274           operands[0] = validize_mem (operands[0]);
3275           operands[1] = force_reg (TFmode, operands[1]);
3276         }
3277     }
3278
3279   /* Fixup PIC cases.  */
3280   if (flag_pic)
3281     {
3282       if (CONSTANT_P (operands[1])
3283           && pic_address_needs_scratch (operands[1]))
3284         operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3285
3286       if (symbolic_operand (operands[1], TFmode))
3287         {
3288           operands[1] = legitimize_pic_address (operands[1],
3289                                                 TFmode,
3290                                                 (reload_in_progress ?
3291                                                  operands[0] :
3292                                                  NULL_RTX));
3293         }
3294     }
3295
3296  movtf_is_ok:
3297   ;
3298 })
3299
3300 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3301 ;; we must split them all.  :-(
3302 (define_insn "*movtf_insn_sp32"
3303   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3304         (match_operand:TF 1 "input_operand"    "oe,GeUr,o,roG"))]
3305   "TARGET_FPU
3306    && ! TARGET_VIS
3307    && ! TARGET_ARCH64
3308    && (register_operand (operands[0], TFmode)
3309        || register_operand (operands[1], TFmode)
3310        || fp_zero_operand (operands[1], TFmode))"
3311   "#"
3312   [(set_attr "length" "4")])
3313
3314 (define_insn "*movtf_insn_vis_sp32"
3315   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3316         (match_operand:TF 1 "input_operand"    "Goe,GeUr,o,roG"))]
3317   "TARGET_FPU
3318    && TARGET_VIS
3319    && ! TARGET_ARCH64
3320    && (register_operand (operands[0], TFmode)
3321        || register_operand (operands[1], TFmode)
3322        || fp_zero_operand (operands[1], TFmode))"
3323   "#"
3324   [(set_attr "length" "4")])
3325
3326 ;; Exactly the same as above, except that all `e' cases are deleted.
3327 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3328 ;; when -mno-fpu.
3329
3330 (define_insn "*movtf_no_e_insn_sp32"
3331   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3332         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
3333   "! TARGET_FPU
3334    && ! TARGET_ARCH64
3335    && (register_operand (operands[0], TFmode)
3336        || register_operand (operands[1], TFmode)
3337        || fp_zero_operand (operands[1], TFmode))"
3338   "#"
3339   [(set_attr "length" "4")])
3340
3341 ;; Now handle the float reg cases directly when arch64,
3342 ;; hard_quad, and proper reg number alignment are all true.
3343 (define_insn "*movtf_insn_hq_sp64"
3344   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3345         (match_operand:TF 1 "input_operand"    "e,m,e,Gr,roG"))]
3346   "TARGET_FPU
3347    && ! TARGET_VIS
3348    && TARGET_ARCH64
3349    && TARGET_HARD_QUAD
3350    && (register_operand (operands[0], TFmode)
3351        || register_operand (operands[1], TFmode)
3352        || fp_zero_operand (operands[1], TFmode))"
3353   "@
3354   fmovq\t%1, %0
3355   ldq\t%1, %0
3356   stq\t%1, %0
3357   #
3358   #"
3359   [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3360    (set_attr "length" "*,*,*,2,2")])
3361
3362 (define_insn "*movtf_insn_hq_vis_sp64"
3363   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3364         (match_operand:TF 1 "input_operand"    "e,m,e,G,roG,r"))]
3365   "TARGET_FPU
3366    && TARGET_VIS
3367    && TARGET_ARCH64
3368    && TARGET_HARD_QUAD
3369    && (register_operand (operands[0], TFmode)
3370        || register_operand (operands[1], TFmode)
3371        || fp_zero_operand (operands[1], TFmode))"
3372   "@
3373   fmovq\t%1, %0
3374   ldq\t%1, %0
3375   stq\t%1, %0
3376   #
3377   #
3378   #"
3379   [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3380    (set_attr "length" "*,*,*,2,2,2")])
3381
3382 ;; Now we allow the integer register cases even when
3383 ;; only arch64 is true.
3384 (define_insn "*movtf_insn_sp64"
3385   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3386         (match_operand:TF 1 "input_operand"    "oe,Ger,orG"))]
3387   "TARGET_FPU
3388    && ! TARGET_VIS
3389    && TARGET_ARCH64
3390    && ! TARGET_HARD_QUAD
3391    && (register_operand (operands[0], TFmode)
3392        || register_operand (operands[1], TFmode)
3393        || fp_zero_operand (operands[1], TFmode))"
3394   "#"
3395   [(set_attr "length" "2")])
3396
3397 (define_insn "*movtf_insn_vis_sp64"
3398   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3399         (match_operand:TF 1 "input_operand"    "Goe,Ger,orG"))]
3400   "TARGET_FPU
3401    && TARGET_VIS
3402    && TARGET_ARCH64
3403    && ! TARGET_HARD_QUAD
3404    && (register_operand (operands[0], TFmode)
3405        || register_operand (operands[1], TFmode)
3406        || fp_zero_operand (operands[1], TFmode))"
3407   "#"
3408   [(set_attr "length" "2")])