OSDN Git Service

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