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