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