OSDN Git Service

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