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