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