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