OSDN Git Service

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