re PR target/80846 (auto-vectorized AVX2 horizontal sum should narrow to 128b right...
[gcc.git] / gcc / config / sparc / sparc.md
1 ;; Machine description for SPARC.
2 ;; Copyright (C) 1987-2017 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
5 ;; at Cygnus Support.
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
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
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 (define_c_enum "unspec" [
24 UNSPEC_MOVE_PIC
25 UNSPEC_UPDATE_RETURN
26 UNSPEC_LOAD_PCREL_SYM
27 UNSPEC_FRAME_BLOCKAGE
28 UNSPEC_MOVE_PIC_LABEL
29 UNSPEC_SETH44
30 UNSPEC_SETM44
31 UNSPEC_SETHH
32 UNSPEC_SETLM
33 UNSPEC_EMB_HISUM
34 UNSPEC_EMB_TEXTUHI
35 UNSPEC_EMB_TEXTHI
36 UNSPEC_EMB_TEXTULO
37 UNSPEC_EMB_SETHM
38 UNSPEC_MOVE_GOTDATA
39
40 UNSPEC_MEMBAR
41 UNSPEC_ATOMIC
42
43 UNSPEC_TLSGD
44 UNSPEC_TLSLDM
45 UNSPEC_TLSLDO
46 UNSPEC_TLSIE
47 UNSPEC_TLSLE
48 UNSPEC_TLSLD_BASE
49
50 UNSPEC_FPACK16
51 UNSPEC_FPACK32
52 UNSPEC_FPACKFIX
53 UNSPEC_FEXPAND
54 UNSPEC_MUL16AU
55 UNSPEC_MUL16AL
56 UNSPEC_MUL8UL
57 UNSPEC_MULDUL
58 UNSPEC_ALIGNDATA
59 UNSPEC_FCMP
60 UNSPEC_PDIST
61 UNSPEC_EDGE8
62 UNSPEC_EDGE8L
63 UNSPEC_EDGE16
64 UNSPEC_EDGE16L
65 UNSPEC_EDGE32
66 UNSPEC_EDGE32L
67 UNSPEC_ARRAY8
68 UNSPEC_ARRAY16
69 UNSPEC_ARRAY32
70
71 UNSPEC_SP_SET
72 UNSPEC_SP_TEST
73
74 UNSPEC_EDGE8N
75 UNSPEC_EDGE8LN
76 UNSPEC_EDGE16N
77 UNSPEC_EDGE16LN
78 UNSPEC_EDGE32N
79 UNSPEC_EDGE32LN
80 UNSPEC_BSHUFFLE
81 UNSPEC_CMASK8
82 UNSPEC_CMASK16
83 UNSPEC_CMASK32
84 UNSPEC_FCHKSM16
85 UNSPEC_PDISTN
86 UNSPEC_FUCMP
87 UNSPEC_FHADD
88 UNSPEC_FHSUB
89 UNSPEC_XMUL
90 UNSPEC_MUL8
91 UNSPEC_MUL8SU
92 UNSPEC_MULDSU
93
94 UNSPEC_ADDV
95 UNSPEC_SUBV
96 UNSPEC_NEGV
97
98 UNSPEC_DICTUNPACK
99 UNSPEC_FPCMPSHL
100 UNSPEC_FPUCMPSHL
101 UNSPEC_FPCMPDESHL
102 UNSPEC_FPCMPURSHL
103 ])
104
105 (define_c_enum "unspecv" [
106 UNSPECV_BLOCKAGE
107 UNSPECV_PROBE_STACK_RANGE
108
109 UNSPECV_FLUSHW
110 UNSPECV_SAVEW
111
112 UNSPECV_FLUSH
113
114 UNSPECV_LDSTUB
115 UNSPECV_SWAP
116 UNSPECV_CAS
117
118 UNSPECV_LDFSR
119 UNSPECV_STFSR
120 ])
121
122 (define_constants
123 [(G0_REG 0)
124 (G1_REG 1)
125 (G2_REG 2)
126 (G3_REG 3)
127 (G4_REG 4)
128 (G5_REG 5)
129 (G6_REG 6)
130 (G7_REG 7)
131 (O0_REG 8)
132 (O1_REG 9)
133 (O2_REG 10)
134 (O3_REG 11)
135 (O4_REG 12)
136 (O5_REG 13)
137 (O6_REG 14)
138 (O7_REG 15)
139 (L0_REG 16)
140 (L1_REG 17)
141 (L2_REG 18)
142 (L3_REG 19)
143 (L4_REG 20)
144 (L5_REG 21)
145 (L6_REG 22)
146 (L7_REG 23)
147 (I0_REG 24)
148 (I1_REG 25)
149 (I2_REG 26)
150 (I3_REG 27)
151 (I4_REG 28)
152 (I5_REG 29)
153 (I6_REG 30)
154 (I7_REG 31)
155 (F0_REG 32)
156 (F1_REG 33)
157 (F2_REG 34)
158 (F3_REG 35)
159 (F4_REG 36)
160 (F5_REG 37)
161 (F6_REG 38)
162 (F7_REG 39)
163 (F8_REG 40)
164 (F9_REG 41)
165 (F10_REG 42)
166 (F11_REG 43)
167 (F12_REG 44)
168 (F13_REG 45)
169 (F14_REG 46)
170 (F15_REG 47)
171 (F16_REG 48)
172 (F17_REG 49)
173 (F18_REG 50)
174 (F19_REG 51)
175 (F20_REG 52)
176 (F21_REG 53)
177 (F22_REG 54)
178 (F23_REG 55)
179 (F24_REG 56)
180 (F25_REG 57)
181 (F26_REG 58)
182 (F27_REG 59)
183 (F28_REG 60)
184 (F29_REG 61)
185 (F30_REG 62)
186 (F31_REG 63)
187 (F32_REG 64)
188 (F34_REG 66)
189 (F36_REG 68)
190 (F38_REG 70)
191 (F40_REG 72)
192 (F42_REG 74)
193 (F44_REG 76)
194 (F46_REG 78)
195 (F48_REG 80)
196 (F50_REG 82)
197 (F52_REG 84)
198 (F54_REG 86)
199 (F56_REG 88)
200 (F58_REG 90)
201 (F60_REG 92)
202 (F62_REG 94)
203 (FCC0_REG 96)
204 (FCC1_REG 97)
205 (FCC2_REG 98)
206 (FCC3_REG 99)
207 (CC_REG 100)
208 (SFP_REG 101)
209 (GSR_REG 102)
210 ])
211
212 (define_mode_iterator I [QI HI SI DI])
213 (define_mode_iterator P [(SI "TARGET_ARCH32") (DI "TARGET_ARCH64")])
214 (define_mode_iterator W [SI (DI "TARGET_ARCH64")])
215 (define_mode_iterator F [SF DF TF])
216
217 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
218 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
219 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
220 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
221 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
222
223 ;; Attribute for cpu type.
224 ;; These must match the values of the enum processor_type in sparc-opts.h.
225 (define_attr "cpu"
226 "v7,
227 cypress,
228 v8,
229 supersparc,
230 hypersparc,
231 leon,
232 leon3,
233 leon3v7,
234 sparclite,
235 f930,
236 f934,
237 sparclite86x,
238 sparclet,
239 tsc701,
240 v9,
241 ultrasparc,
242 ultrasparc3,
243 niagara,
244 niagara2,
245 niagara3,
246 niagara4,
247 niagara7,
248 m8"
249 (const (symbol_ref "sparc_cpu_attr")))
250
251 ;; Attribute for the instruction set.
252 ;; At present we only need to distinguish v9/!v9, but for clarity we
253 ;; test TARGET_V8 too.
254 (define_attr "isa" "v7,v8,v9,sparclet"
255 (const
256 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
257 (symbol_ref "TARGET_V8") (const_string "v8")
258 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
259 (const_string "v7"))))
260
261 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3,vis4,vis4b"
262 (const_string "none"))
263
264 (define_attr "lra" "disabled,enabled"
265 (const_string "enabled"))
266
267 (define_attr "enabled" ""
268 (cond [(eq_attr "cpu_feature" "none")
269 (cond [(eq_attr "lra" "disabled") (symbol_ref "!TARGET_LRA")] (const_int 1))
270 (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
271 (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && !TARGET_V9")
272 (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
273 (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
274 (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")
275 (eq_attr "cpu_feature" "vis4") (symbol_ref "TARGET_VIS4")
276 (eq_attr "cpu_feature" "vis4b") (symbol_ref "TARGET_VIS4B")]
277 (const_int 0)))
278
279 ;; The SPARC instructions used by the backend are organized into a
280 ;; hierarchy using the insn attributes "type" and "subtype".
281 ;;
282 ;; The mnemonics used in the list below are the architectural names
283 ;; used in the Oracle SPARC Architecture specs. A / character
284 ;; separates the type from the subtype where appropriate. For
285 ;; brevity, text enclosed in {} denotes alternatives, while text
286 ;; enclosed in [] is optional.
287 ;;
288 ;; Please keep this list updated. It is of great help for keeping the
289 ;; correctness and coherence of the DFA schedulers.
290 ;;
291 ;; ialu: <empty>
292 ;; ialuX: ADD[X]C SUB[X]C
293 ;; shift: SLL[X] SRL[X] SRA[X]
294 ;; cmove: MOV{A,N,NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS}
295 ;; MOVF{A,N,U,G,UG,L,UL,LG,NE,E,UE,GE,UGE,LE,ULE,O}
296 ;; MOVR{Z,LEZ,LZ,NZ,GZ,GEZ}
297 ;; compare: ADDcc ADDCcc ANDcc ORcc SUBcc SUBCcc XORcc XNORcc
298 ;; imul: MULX SMUL[cc] UMUL UMULXHI XMULX XMULXHI
299 ;; idiv: UDIVX SDIVX
300 ;; flush: FLUSH
301 ;; load/regular: LD{UB,UH,UW} LDFSR
302 ;; load/prefetch: PREFETCH
303 ;; fpload: LDF LDDF LDQF
304 ;; sload: LD{SB,SH,SW}
305 ;; store: ST{B,H,W,X} STFSR
306 ;; fpstore: STF STDF STQF
307 ;; cbcond: CWB{NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS}
308 ;; CXB{NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS}
309 ;; uncond_branch: BA BPA JMPL
310 ;; branch: B{NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS}
311 ;; BP{NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS}
312 ;; FB{U,G,UG,L,UL,LG,NE,BE,UE,GE,UGE,LE,ULE,O}
313 ;; call: CALL
314 ;; return: RESTORE RETURN
315 ;; fpmove: FABS{s,d,q} FMOV{s,d,q} FNEG{s,d,q}
316 ;; fpcmove: FMOV{S,D,Q}{icc,xcc,fcc}
317 ;; fpcrmove: FMOVR{s,d,q}{Z,LEZ,LZ,NZ,GZ,GEZ}
318 ;; fp: FADD{s,d,q} FSUB{s,d,q} FHSUB{s,d} FNHADD{s,d} FNADD{s,d}
319 ;; FiTO{s,d,q} FsTO{i,x,d,q} FdTO{i,x,s,q} FxTO{d,s,q} FqTO{i,x,s,d}
320 ;; fpcmp: FCMP{s,d,q} FCMPE{s,d,q}
321 ;; fpmul: FMADD{s,d} FMSUB{s,d} FMUL{s,d,q} FNMADD{s,d}
322 ;; FNMSUB{s,d} FNMUL{s,d} FNsMULd FsMULd
323 ;; FdMULq
324 ;; array: ARRAY{8,16,32}
325 ;; bmask: BMASK
326 ;; edge: EDGE{8,16,32}[L]cc
327 ;; edgen: EDGE{8,16,32}[L]n
328 ;; fpdivs: FDIV{s,q}
329 ;; fpsqrts: FSQRT{s,q}
330 ;; fpdivd: FDIVd
331 ;; fpsqrtd: FSQRTd
332 ;; lzd: LZCNT
333 ;; fga/addsub64: FP{ADD,SUB}64
334 ;; fga/fpu: FCHKSM16 FEXPANd FMEAN16 FPMERGE
335 ;; FS{LL,RA,RL}{16,32}
336 ;; fga/maxmin: FP{MAX,MIN}[U]{8,16,32}
337 ;; fga/cmask: CMASK{8,16,32}
338 ;; fga/other: BSHUFFLE FALIGNDATAg FP{ADD,SUB}[S]{8,16,32}
339 ;; FP{ADD,SUB}US{8,16} DICTUNPACK
340 ;; gsr/reg: RDGSR WRGSR
341 ;; gsr/alignaddr: ALIGNADDRESS[_LITTLE]
342 ;; vismv/double: FSRC2d
343 ;; vismv/single: MOVwTOs FSRC2s
344 ;; vismv/movstouw: MOVsTOuw
345 ;; vismv/movxtod: MOVxTOd
346 ;; vismv/movdtox: MOVdTOx
347 ;; visl/single: F{AND,NAND,NOR,OR,NOT1}s
348 ;; F{AND,OR}NOT{1,2}s
349 ;; FONEs F{ZERO,XNOR,XOR}s FNOT2s
350 ;; visl/double: FONEd FZEROd FNOT1d F{OR,AND,XOR}d F{NOR,NAND,XNOR}d
351 ;; F{OR,AND}NOT1d F{OR,AND}NOT2d
352 ;; viscmp: FPCMP{LE,GT,NE,EQ}{8,16,32} FPCMPU{LE,GT,NE,EQ}{8,16,32}
353 ;; FPCMP{LE,GT,EQ,NE}{8,16,32}SHL FPCMPU{LE,GT,EQ,NE}{8,16,32}SHL
354 ;; FPCMPDE{8,16,32}SHL FPCMPUR{8,16,32}SHL
355 ;; fgm_pack: FPACKFIX FPACK{8,16,32}
356 ;; fgm_mul: FMUL8SUx16 FMUL8ULx16 FMUL8x16 FMUL8x16AL
357 ;; FMUL8x16AU FMULD8SUx16 FMULD8ULx16
358 ;; pdist: PDIST
359 ;; pdistn: PDISTN
360
361 (define_attr "type"
362 "ialu,compare,shift,
363 load,sload,store,
364 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
365 cbcond,uncond_cbcond,
366 imul,idiv,
367 fpload,fpstore,
368 fp,fpmove,
369 fpcmove,fpcrmove,
370 fpcmp,
371 fpmul,fpdivs,fpdivd,
372 fpsqrts,fpsqrtd,
373 fga,visl,vismv,viscmp,
374 fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array,bmask,
375 cmove,
376 ialuX,
377 multi,savew,flushw,iflush,trap,lzd"
378 (const_string "ialu"))
379
380 (define_attr "subtype"
381 "single,double,movstouw,movxtod,movdtox,
382 addsub64,cmask,fpu,maxmin,other,
383 reg,alignaddr,
384 prefetch,regular"
385 (const_string "single"))
386
387 ;; True if branch/call has empty delay slot and will emit a nop in it
388 (define_attr "empty_delay_slot" "false,true"
389 (symbol_ref "(empty_delay_slot (insn)
390 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
391
392 ;; True if we are making use of compare-and-branch instructions.
393 ;; True if we should emit a nop after a cbcond instruction
394 (define_attr "emit_cbcond_nop" "false,true"
395 (symbol_ref "(emit_cbcond_nop (insn)
396 ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)"))
397
398 (define_attr "branch_type" "none,icc,fcc,reg"
399 (const_string "none"))
400
401 (define_attr "pic" "false,true"
402 (symbol_ref "(flag_pic != 0
403 ? PIC_TRUE : PIC_FALSE)"))
404
405 (define_attr "calls_alloca" "false,true"
406 (symbol_ref "(cfun->calls_alloca != 0
407 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
408
409 (define_attr "calls_eh_return" "false,true"
410 (symbol_ref "(crtl->calls_eh_return != 0
411 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
412
413 (define_attr "leaf_function" "false,true"
414 (symbol_ref "(crtl->uses_only_leaf_regs != 0
415 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
416
417 (define_attr "delayed_branch" "false,true"
418 (symbol_ref "(flag_delayed_branch != 0
419 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
420
421 (define_attr "flat" "false,true"
422 (symbol_ref "(TARGET_FLAT != 0
423 ? FLAT_TRUE : FLAT_FALSE)"))
424
425 (define_attr "fix_ut699" "false,true"
426 (symbol_ref "(sparc_fix_ut699 != 0
427 ? FIX_UT699_TRUE : FIX_UT699_FALSE)"))
428
429 (define_attr "fix_b2bst" "false,true"
430 (symbol_ref "(sparc_fix_b2bst != 0
431 ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)"))
432
433 ;; Length (in # of insns).
434 ;; Beware that setting a length greater or equal to 3 for conditional branches
435 ;; has a side-effect (see output_cbranch and output_v9branch).
436 (define_attr "length" ""
437 (cond [(eq_attr "type" "uncond_branch,call")
438 (if_then_else (eq_attr "empty_delay_slot" "true")
439 (const_int 2)
440 (const_int 1))
441 (eq_attr "type" "sibcall")
442 (if_then_else (ior (eq_attr "leaf_function" "true")
443 (eq_attr "flat" "true"))
444 (if_then_else (eq_attr "empty_delay_slot" "true")
445 (const_int 3)
446 (const_int 2))
447 (if_then_else (eq_attr "empty_delay_slot" "true")
448 (const_int 2)
449 (const_int 1)))
450 (eq_attr "branch_type" "icc")
451 (if_then_else (match_operand 0 "v9_comparison_operator" "")
452 (if_then_else (lt (pc) (match_dup 1))
453 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
454 (if_then_else (eq_attr "empty_delay_slot" "true")
455 (const_int 2)
456 (const_int 1))
457 (if_then_else (eq_attr "empty_delay_slot" "true")
458 (const_int 4)
459 (const_int 3)))
460 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
461 (if_then_else (eq_attr "empty_delay_slot" "true")
462 (const_int 2)
463 (const_int 1))
464 (if_then_else (eq_attr "empty_delay_slot" "true")
465 (const_int 4)
466 (const_int 3))))
467 (if_then_else (eq_attr "empty_delay_slot" "true")
468 (const_int 2)
469 (const_int 1)))
470 (eq_attr "branch_type" "fcc")
471 (if_then_else (match_operand 0 "fcc0_register_operand" "")
472 (if_then_else (eq_attr "empty_delay_slot" "true")
473 (if_then_else (not (match_test "TARGET_V9"))
474 (const_int 3)
475 (const_int 2))
476 (if_then_else (not (match_test "TARGET_V9"))
477 (const_int 2)
478 (const_int 1)))
479 (if_then_else (lt (pc) (match_dup 2))
480 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
481 (if_then_else (eq_attr "empty_delay_slot" "true")
482 (const_int 2)
483 (const_int 1))
484 (if_then_else (eq_attr "empty_delay_slot" "true")
485 (const_int 4)
486 (const_int 3)))
487 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
488 (if_then_else (eq_attr "empty_delay_slot" "true")
489 (const_int 2)
490 (const_int 1))
491 (if_then_else (eq_attr "empty_delay_slot" "true")
492 (const_int 4)
493 (const_int 3)))))
494 (eq_attr "branch_type" "reg")
495 (if_then_else (lt (pc) (match_dup 2))
496 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
497 (if_then_else (eq_attr "empty_delay_slot" "true")
498 (const_int 2)
499 (const_int 1))
500 (if_then_else (eq_attr "empty_delay_slot" "true")
501 (const_int 4)
502 (const_int 3)))
503 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
504 (if_then_else (eq_attr "empty_delay_slot" "true")
505 (const_int 2)
506 (const_int 1))
507 (if_then_else (eq_attr "empty_delay_slot" "true")
508 (const_int 4)
509 (const_int 3))))
510 (eq_attr "type" "cbcond")
511 (if_then_else (lt (pc) (match_dup 3))
512 (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500))
513 (if_then_else (eq_attr "emit_cbcond_nop" "true")
514 (const_int 2)
515 (const_int 1))
516 (const_int 4))
517 (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500))
518 (if_then_else (eq_attr "emit_cbcond_nop" "true")
519 (const_int 2)
520 (const_int 1))
521 (const_int 4)))
522 (eq_attr "type" "uncond_cbcond")
523 (if_then_else (lt (pc) (match_dup 0))
524 (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500))
525 (if_then_else (eq_attr "emit_cbcond_nop" "true")
526 (const_int 2)
527 (const_int 1))
528 (const_int 1))
529 (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500))
530 (if_then_else (eq_attr "emit_cbcond_nop" "true")
531 (const_int 2)
532 (const_int 1))
533 (const_int 1)))
534 ] (const_int 1)))
535
536 ;; FP precision.
537 (define_attr "fptype" "single,double"
538 (const_string "single"))
539
540 ;; FP precision specific to the UT699.
541 (define_attr "fptype_ut699" "none,single"
542 (const_string "none"))
543
544 ;; UltraSPARC-III integer load type.
545 (define_attr "us3load_type" "2cycle,3cycle"
546 (const_string "2cycle"))
547
548 (define_asm_attributes
549 [(set_attr "length" "2")
550 (set_attr "type" "multi")])
551
552 ;; Attributes for branch scheduling
553 (define_attr "in_call_delay" "false,true"
554 (symbol_ref "(eligible_for_call_delay (insn)
555 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
556
557 (define_attr "in_sibcall_delay" "false,true"
558 (symbol_ref "(eligible_for_sibcall_delay (insn)
559 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
560
561 (define_attr "in_return_delay" "false,true"
562 (symbol_ref "(eligible_for_return_delay (insn)
563 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
564
565 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
566 ;; branches. This would allow us to remove the nop always inserted before
567 ;; a floating point branch.
568
569 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
570 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
571 ;; This is because doing so will add several pipeline stalls to the path
572 ;; that the load/store did not come from. Unfortunately, there is no way
573 ;; to prevent fill_eager_delay_slots from using load/store without completely
574 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
575 ;; because it prevents us from moving back the final store of inner loops.
576
577 (define_attr "in_branch_delay" "false,true"
578 (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
579 (const_string "false")
580 (and (eq_attr "fix_b2bst" "true") (eq_attr "type" "store,fpstore"))
581 (const_string "false")
582 (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
583 (const_string "false")
584 (and (eq_attr "fix_ut699" "true")
585 (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
586 (ior (eq_attr "fptype" "single")
587 (eq_attr "fptype_ut699" "single"))))
588 (const_string "false")
589 (eq_attr "length" "1")
590 (const_string "true")
591 ] (const_string "false")))
592
593 (define_delay (eq_attr "type" "call")
594 [(eq_attr "in_call_delay" "true") (nil) (nil)])
595
596 (define_delay (eq_attr "type" "sibcall")
597 [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
598
599 (define_delay (eq_attr "type" "return")
600 [(eq_attr "in_return_delay" "true") (nil) (nil)])
601
602 (define_delay (eq_attr "type" "branch")
603 [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
604
605 (define_delay (eq_attr "type" "uncond_branch")
606 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
607
608
609 ;; Include SPARC DFA schedulers
610
611 (include "cypress.md")
612 (include "supersparc.md")
613 (include "hypersparc.md")
614 (include "leon.md")
615 (include "sparclet.md")
616 (include "ultra1_2.md")
617 (include "ultra3.md")
618 (include "niagara.md")
619 (include "niagara2.md")
620 (include "niagara4.md")
621 (include "niagara7.md")
622 (include "m8.md")
623
624
625 ;; Operand and operator predicates and constraints
626
627 (include "predicates.md")
628 (include "constraints.md")
629
630
631 ;; Compare instructions.
632
633 ;; These are just the DEFINE_INSNs to match the patterns and the
634 ;; DEFINE_SPLITs for some of the scc insns that actually require
635 ;; more than one machine instruction. DEFINE_EXPANDs are further down.
636
637 (define_insn "*cmpsi_insn"
638 [(set (reg:CC CC_REG)
639 (compare:CC (match_operand:SI 0 "register_operand" "r")
640 (match_operand:SI 1 "arith_operand" "rI")))]
641 ""
642 "cmp\t%0, %1"
643 [(set_attr "type" "compare")])
644
645 (define_insn "*cmpdi_sp64"
646 [(set (reg:CCX CC_REG)
647 (compare:CCX (match_operand:DI 0 "register_operand" "r")
648 (match_operand:DI 1 "arith_operand" "rI")))]
649 "TARGET_ARCH64"
650 "cmp\t%0, %1"
651 [(set_attr "type" "compare")])
652
653 (define_insn "*cmpsi_sne"
654 [(set (reg:CCC CC_REG)
655 (compare:CCC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
656 (const_int -1)))]
657 ""
658 "cmp\t%%g0, %0"
659 [(set_attr "type" "compare")])
660
661 (define_insn "*cmpdi_sne"
662 [(set (reg:CCXC CC_REG)
663 (compare:CCXC (not:DI (match_operand:DI 0 "arith_operand" "rI"))
664 (const_int -1)))]
665 "TARGET_ARCH64"
666 "cmp\t%%g0, %0"
667 [(set_attr "type" "compare")])
668
669 (define_insn "*cmpsf_fpe"
670 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
671 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
672 (match_operand:SF 2 "register_operand" "f")))]
673 "TARGET_FPU"
674 {
675 if (TARGET_V9)
676 return "fcmpes\t%0, %1, %2";
677 return "fcmpes\t%1, %2";
678 }
679 [(set_attr "type" "fpcmp")])
680
681 (define_insn "*cmpdf_fpe"
682 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
683 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
684 (match_operand:DF 2 "register_operand" "e")))]
685 "TARGET_FPU"
686 {
687 if (TARGET_V9)
688 return "fcmped\t%0, %1, %2";
689 return "fcmped\t%1, %2";
690 }
691 [(set_attr "type" "fpcmp")
692 (set_attr "fptype" "double")])
693
694 (define_insn "*cmptf_fpe"
695 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
696 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
697 (match_operand:TF 2 "register_operand" "e")))]
698 "TARGET_FPU && TARGET_HARD_QUAD"
699 {
700 if (TARGET_V9)
701 return "fcmpeq\t%0, %1, %2";
702 return "fcmpeq\t%1, %2";
703 }
704 [(set_attr "type" "fpcmp")])
705
706 (define_insn "*cmpsf_fp"
707 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
708 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
709 (match_operand:SF 2 "register_operand" "f")))]
710 "TARGET_FPU"
711 {
712 if (TARGET_V9)
713 return "fcmps\t%0, %1, %2";
714 return "fcmps\t%1, %2";
715 }
716 [(set_attr "type" "fpcmp")])
717
718 (define_insn "*cmpdf_fp"
719 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
720 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
721 (match_operand:DF 2 "register_operand" "e")))]
722 "TARGET_FPU"
723 {
724 if (TARGET_V9)
725 return "fcmpd\t%0, %1, %2";
726 return "fcmpd\t%1, %2";
727 }
728 [(set_attr "type" "fpcmp")
729 (set_attr "fptype" "double")])
730
731 (define_insn "*cmptf_fp"
732 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
733 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
734 (match_operand:TF 2 "register_operand" "e")))]
735 "TARGET_FPU && TARGET_HARD_QUAD"
736 {
737 if (TARGET_V9)
738 return "fcmpq\t%0, %1, %2";
739 return "fcmpq\t%1, %2";
740 }
741 [(set_attr "type" "fpcmp")])
742
743 ;; Next come the scc insns.
744
745 ;; Note that the boolean result (operand 0) takes on DImode
746 ;; (not SImode) when TARGET_ARCH64.
747
748 (define_expand "cstoresi4"
749 [(use (match_operator 1 "comparison_operator"
750 [(match_operand:SI 2 "compare_operand" "")
751 (match_operand:SI 3 "arith_operand" "")]))
752 (clobber (match_operand:SI 0 "cstore_result_operand"))]
753 ""
754 {
755 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
756 operands[2] = force_reg (SImode, operands[2]);
757 if (emit_scc_insn (operands)) DONE; else FAIL;
758 })
759
760 (define_expand "cstoredi4"
761 [(use (match_operator 1 "comparison_operator"
762 [(match_operand:DI 2 "compare_operand" "")
763 (match_operand:DI 3 "arith_operand" "")]))
764 (clobber (match_operand:SI 0 "cstore_result_operand"))]
765 "TARGET_ARCH64"
766 {
767 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
768 operands[2] = force_reg (DImode, operands[2]);
769 if (emit_scc_insn (operands)) DONE; else FAIL;
770 })
771
772 (define_expand "cstore<F:mode>4"
773 [(use (match_operator 1 "comparison_operator"
774 [(match_operand:F 2 "register_operand" "")
775 (match_operand:F 3 "register_operand" "")]))
776 (clobber (match_operand:SI 0 "cstore_result_operand"))]
777 "TARGET_FPU"
778 {
779 if (emit_scc_insn (operands)) DONE; else FAIL;
780 })
781
782 ;; The SNE and SEQ patterns are special because they can be done
783 ;; without any branching and do not involve a COMPARE.
784
785 (define_insn_and_split "*snesi<W:mode>_zero"
786 [(set (match_operand:W 0 "register_operand" "=r")
787 (ne:W (match_operand:SI 1 "register_operand" "r")
788 (const_int 0)))
789 (clobber (reg:CC CC_REG))]
790 ""
791 "#"
792 ""
793 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
794 (set (match_dup 0) (ltu:W (reg:CCC CC_REG) (const_int 0)))]
795 ""
796 [(set_attr "length" "2")])
797
798 (define_insn_and_split "*neg_snesi<W:mode>_zero"
799 [(set (match_operand:W 0 "register_operand" "=r")
800 (neg:W (ne:W (match_operand:SI 1 "register_operand" "r")
801 (const_int 0))))
802 (clobber (reg:CC CC_REG))]
803 ""
804 "#"
805 ""
806 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
807 (set (match_dup 0) (neg:W (ltu:W (reg:CCC CC_REG) (const_int 0))))]
808 ""
809 [(set_attr "length" "2")])
810
811 (define_insn_and_split "*snedi<W:mode>_zero"
812 [(set (match_operand:W 0 "register_operand" "=&r")
813 (ne:W (match_operand:DI 1 "register_operand" "r")
814 (const_int 0)))]
815 "TARGET_ARCH64 && !TARGET_VIS3"
816 "#"
817 "&& !reg_overlap_mentioned_p (operands[1], operands[0])"
818 [(set (match_dup 0) (const_int 0))
819 (set (match_dup 0) (if_then_else:W (ne:DI (match_dup 1) (const_int 0))
820 (const_int 1)
821 (match_dup 0)))]
822 ""
823 [(set_attr "length" "2")])
824
825 (define_insn_and_split "*snedi<W:mode>_zero_vis3"
826 [(set (match_operand:W 0 "register_operand" "=r")
827 (ne:W (match_operand:DI 1 "register_operand" "r")
828 (const_int 0)))
829 (clobber (reg:CCX CC_REG))]
830 "TARGET_ARCH64 && TARGET_VIS3"
831 "#"
832 ""
833 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
834 (set (match_dup 0) (ltu:W (reg:CCXC CC_REG) (const_int 0)))]
835 ""
836 [(set_attr "length" "2")])
837
838 (define_insn_and_split "*neg_snedi<W:mode>_zero"
839 [(set (match_operand:W 0 "register_operand" "=&r")
840 (neg:W (ne:W (match_operand:DI 1 "register_operand" "r")
841 (const_int 0))))]
842 "TARGET_ARCH64 && !TARGET_SUBXC"
843 "#"
844 "&& !reg_overlap_mentioned_p (operands[1], operands[0])"
845 [(set (match_dup 0) (const_int 0))
846 (set (match_dup 0) (if_then_else:W (ne:DI (match_dup 1) (const_int 0))
847 (const_int -1)
848 (match_dup 0)))]
849 ""
850 [(set_attr "length" "2")])
851
852 (define_insn_and_split "*neg_snedi<W:mode>_zero_subxc"
853 [(set (match_operand:W 0 "register_operand" "=&r")
854 (neg:W (ne:W (match_operand:DI 1 "register_operand" "r")
855 (const_int 0))))
856 (clobber (reg:CCX CC_REG))]
857 "TARGET_ARCH64 && TARGET_SUBXC"
858 "#"
859 ""
860 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
861 (set (match_dup 0) (neg:W (ltu:W (reg:CCXC CC_REG) (const_int 0))))]
862 ""
863 [(set_attr "length" "2")])
864
865 (define_insn_and_split "*seqsi<W:mode>_zero"
866 [(set (match_operand:W 0 "register_operand" "=r")
867 (eq:W (match_operand:SI 1 "register_operand" "r")
868 (const_int 0)))
869 (clobber (reg:CC CC_REG))]
870 ""
871 "#"
872 ""
873 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
874 (set (match_dup 0) (geu:W (reg:CCC CC_REG) (const_int 0)))]
875 ""
876 [(set_attr "length" "2")])
877
878 (define_insn_and_split "*neg_seqsi<W:mode>_zero"
879 [(set (match_operand:W 0 "register_operand" "=r")
880 (neg:W (eq:W (match_operand:SI 1 "register_operand" "r")
881 (const_int 0))))
882 (clobber (reg:CC CC_REG))]
883 ""
884 "#"
885 ""
886 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
887 (set (match_dup 0) (neg:W (geu:W (reg:CCC CC_REG) (const_int 0))))]
888 ""
889 [(set_attr "length" "2")])
890
891 (define_insn_and_split "*seqdi<W:mode>_zero"
892 [(set (match_operand:W 0 "register_operand" "=&r")
893 (eq:W (match_operand:DI 1 "register_operand" "r")
894 (const_int 0)))]
895 "TARGET_ARCH64"
896 "#"
897 "&& !reg_overlap_mentioned_p (operands[1], operands[0])"
898 [(set (match_dup 0) (const_int 0))
899 (set (match_dup 0) (if_then_else:W (eq:DI (match_dup 1) (const_int 0))
900 (const_int 1)
901 (match_dup 0)))]
902 ""
903 [(set_attr "length" "2")])
904
905 (define_insn_and_split "*neg_seqdi<W:mode>_zero"
906 [(set (match_operand:W 0 "register_operand" "=&r")
907 (neg:W (eq:W (match_operand:DI 1 "register_operand" "r")
908 (const_int 0))))]
909 "TARGET_ARCH64"
910 "#"
911 "&& !reg_overlap_mentioned_p (operands[1], operands[0])"
912 [(set (match_dup 0) (const_int 0))
913 (set (match_dup 0) (if_then_else:W (eq:DI (match_dup 1) (const_int 0))
914 (const_int -1)
915 (match_dup 0)))]
916 ""
917 [(set_attr "length" "2")])
918
919 ;; We can also do (x + (i == 0)) and related, so put them in.
920
921 (define_insn_and_split "*plus_snesi<W:mode>_zero"
922 [(set (match_operand:W 0 "register_operand" "=r")
923 (plus:W (ne:W (match_operand:SI 1 "register_operand" "r")
924 (const_int 0))
925 (match_operand:W 2 "register_operand" "r")))
926 (clobber (reg:CC CC_REG))]
927 ""
928 "#"
929 ""
930 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
931 (set (match_dup 0) (plus:W (ltu:W (reg:CCC CC_REG) (const_int 0))
932 (match_dup 2)))]
933 ""
934 [(set_attr "length" "2")])
935
936 (define_insn_and_split "*plus_plus_snesi<W:mode>_zero"
937 [(set (match_operand:W 0 "register_operand" "=r")
938 (plus:W (plus:W (ne:W (match_operand:SI 1 "register_operand" "r")
939 (const_int 0))
940 (match_operand:W 2 "register_operand" "r"))
941 (match_operand:W 3 "register_operand" "r")))
942 (clobber (reg:CC CC_REG))]
943 ""
944 "#"
945 ""
946 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
947 (set (match_dup 0) (plus:W (plus:W (ltu:W (reg:CCC CC_REG) (const_int 0))
948 (match_dup 2))
949 (match_dup 3)))]
950 ""
951 [(set_attr "length" "2")])
952
953 (define_insn_and_split "*plus_snedi<W:mode>_zero"
954 [(set (match_operand:W 0 "register_operand" "=r")
955 (plus:W (ne:W (match_operand:DI 1 "register_operand" "r")
956 (const_int 0))
957 (match_operand:W 2 "register_operand" "r")))
958 (clobber (reg:CCX CC_REG))]
959 "TARGET_ARCH64 && TARGET_VIS3"
960 "#"
961 ""
962 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
963 (set (match_dup 0) (plus:W (ltu:W (reg:CCXC CC_REG) (const_int 0))
964 (match_dup 2)))]
965 ""
966 [(set_attr "length" "2")])
967
968 (define_insn_and_split "*plus_plus_snedi<W:mode>_zero"
969 [(set (match_operand:W 0 "register_operand" "=r")
970 (plus:W (plus:W (ne:W (match_operand:DI 1 "register_operand" "r")
971 (const_int 0))
972 (match_operand:W 2 "register_operand" "r"))
973 (match_operand:W 3 "register_operand" "r")))
974 (clobber (reg:CCX CC_REG))]
975 "TARGET_ARCH64 && TARGET_VIS3"
976 "#"
977 ""
978 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
979 (set (match_dup 0) (plus:W (plus:W (ltu:W (reg:CCXC CC_REG) (const_int 0))
980 (match_dup 2))
981 (match_dup 3)))]
982 ""
983 [(set_attr "length" "2")])
984
985 (define_insn_and_split "*minus_snesi<W:mode>_zero"
986 [(set (match_operand:W 0 "register_operand" "=r")
987 (minus:W (match_operand:W 2 "register_operand" "r")
988 (ne:W (match_operand:SI 1 "register_operand" "r")
989 (const_int 0))))
990 (clobber (reg:CC CC_REG))]
991 ""
992 "#"
993 ""
994 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
995 (set (match_dup 0) (minus:W (match_dup 2)
996 (ltu:W (reg:CCC CC_REG) (const_int 0))))]
997 ""
998 [(set_attr "length" "2")])
999
1000 (define_insn_and_split "*minus_minus_snesi<W:mode>_zero"
1001 [(set (match_operand:W 0 "register_operand" "=r")
1002 (minus:W (minus:W (match_operand:W 2 "register_operand" "r")
1003 (ne:W (match_operand:SI 1 "register_operand" "r")
1004 (const_int 0)))
1005 (match_operand:W 3 "register_operand" "r")))
1006 (clobber (reg:CC CC_REG))]
1007 ""
1008 "#"
1009 ""
1010 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
1011 (set (match_dup 0) (minus:W (minus:W (match_dup 2)
1012 (ltu:W (reg:CCC CC_REG) (const_int 0)))
1013 (match_dup 3)))]
1014 ""
1015 [(set_attr "length" "2")])
1016
1017 (define_insn_and_split "*minus_snedi<W:mode>_zero"
1018 [(set (match_operand:W 0 "register_operand" "=r")
1019 (minus:W (match_operand:W 2 "register_operand" "r")
1020 (ne:W (match_operand:DI 1 "register_operand" "r")
1021 (const_int 0))))
1022 (clobber (reg:CCX CC_REG))]
1023 "TARGET_ARCH64 && TARGET_SUBXC"
1024 "#"
1025 ""
1026 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
1027 (set (match_dup 0) (minus:W (match_dup 2)
1028 (ltu:W (reg:CCXC CC_REG) (const_int 0))))]
1029 ""
1030 [(set_attr "length" "2")])
1031
1032 (define_insn_and_split "*minus_minus_snedi<W:mode>_zero"
1033 [(set (match_operand:W 0 "register_operand" "=r")
1034 (minus:W (minus:W (match_operand:W 2 "register_operand" "r")
1035 (ne:W (match_operand:DI 1 "register_operand" "r")
1036 (const_int 0)))
1037 (match_operand:W 3 "register_operand" "r")))
1038 (clobber (reg:CCX CC_REG))]
1039 "TARGET_ARCH64 && TARGET_SUBXC"
1040 "#"
1041 ""
1042 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
1043 (set (match_dup 0) (minus:W (minus:W (match_dup 2)
1044 (ltu:W (reg:CCXC CC_REG) (const_int 0)))
1045 (match_dup 3)))]
1046 ""
1047 [(set_attr "length" "2")])
1048
1049 (define_insn_and_split "*plus_seqsi<W:mode>_zero"
1050 [(set (match_operand:W 0 "register_operand" "=r")
1051 (plus:W (eq:W (match_operand:SI 1 "register_operand" "r")
1052 (const_int 0))
1053 (match_operand:W 2 "register_operand" "r")))
1054 (clobber (reg:CC CC_REG))]
1055 ""
1056 "#"
1057 ""
1058 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
1059 (set (match_dup 0) (plus:W (geu:W (reg:CCC CC_REG) (const_int 0))
1060 (match_dup 2)))]
1061 ""
1062 [(set_attr "length" "2")])
1063
1064 (define_insn_and_split "*minus_seqsi<W:mode>_zero"
1065 [(set (match_operand:W 0 "register_operand" "=r")
1066 (minus:W (match_operand:W 2 "register_operand" "r")
1067 (eq:W (match_operand:SI 1 "register_operand" "r")
1068 (const_int 0))))
1069 (clobber (reg:CC CC_REG))]
1070 ""
1071 "#"
1072 ""
1073 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
1074 (set (match_dup 0) (minus:W (match_dup 2)
1075 (geu:W (reg:CCC CC_REG) (const_int 0))))]
1076 ""
1077 [(set_attr "length" "2")])
1078
1079 ;; We can also do GEU and LTU directly, but these operate after a compare.
1080
1081 (define_insn "*sltu<W:mode>_insn"
1082 [(set (match_operand:W 0 "register_operand" "=r")
1083 (ltu:W (match_operand 1 "icc_register_operand" "X") (const_int 0)))]
1084 "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode"
1085 "addx\t%%g0, 0, %0"
1086 [(set_attr "type" "ialuX")])
1087
1088 (define_insn "*plus_sltu<W:mode>"
1089 [(set (match_operand:W 0 "register_operand" "=r")
1090 (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1091 (const_int 0))
1092 (match_operand:W 1 "arith_operand" "rI")))]
1093 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1094 "addx\t%%g0, %1, %0"
1095 [(set_attr "type" "ialuX")])
1096
1097 (define_insn "*plus_plus_sltu<W:mode>"
1098 [(set (match_operand:W 0 "register_operand" "=r")
1099 (plus:W (plus:W (ltu:W (match_operand 3 "icc_register_operand" "X")
1100 (const_int 0))
1101 (match_operand:W 1 "register_operand" "%r"))
1102 (match_operand:W 2 "arith_operand" "rI")))]
1103 "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode"
1104 "addx\t%1, %2, %0"
1105 [(set_attr "type" "ialuX")])
1106
1107 (define_insn "*neg_sgeu<W:mode>"
1108 [(set (match_operand:W 0 "register_operand" "=r")
1109 (neg:W (geu:W (match_operand 1 "icc_register_operand" "X")
1110 (const_int 0))))]
1111 "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode"
1112 "addx\t%%g0, -1, %0"
1113 [(set_attr "type" "ialuX")])
1114
1115 (define_insn "*neg_sgeusidi"
1116 [(set (match_operand:DI 0 "register_operand" "=r")
1117 (sign_extend:DI (neg:SI (geu:SI (match_operand 1 "icc_register_operand" "X")
1118 (const_int 0)))))]
1119 "TARGET_ARCH64
1120 && (GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode)"
1121 "addx\t%%g0, -1, %0"
1122 [(set_attr "type" "ialuX")])
1123
1124 (define_insn "*minus_sgeu<W:mode>"
1125 [(set (match_operand:W 0 "register_operand" "=r")
1126 (minus:W (match_operand:W 1 "register_operand" "r")
1127 (geu:W (match_operand 2 "icc_register_operand" "X")
1128 (const_int 0))))]
1129 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1130 "addx\t%1, -1, %0"
1131 [(set_attr "type" "ialuX")])
1132
1133 (define_insn "*addx<W:mode>"
1134 [(set (match_operand:W 0 "register_operand" "=r")
1135 (plus:W (plus:W (match_operand:W 1 "register_operand" "%r")
1136 (match_operand:W 2 "arith_operand" "rI"))
1137 (ltu:W (match_operand 3 "icc_register_operand" "X")
1138 (const_int 0))))]
1139 "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode"
1140 "addx\t%1, %2, %0"
1141 [(set_attr "type" "ialuX")])
1142
1143 (define_insn "*sltu<W:mode>_insn_vis3"
1144 [(set (match_operand:W 0 "register_operand" "=r")
1145 (ltu:W (match_operand 1 "icc_register_operand" "X") (const_int 0)))]
1146 "TARGET_ARCH64 && TARGET_VIS3
1147 && (GET_MODE (operands[1]) == CCXmode || GET_MODE (operands[1]) == CCXCmode)"
1148 "addxc\t%%g0, %%g0, %0"
1149 [(set_attr "type" "ialuX")])
1150
1151 (define_insn "*plus_sltu<W:mode>_vis3"
1152 [(set (match_operand:W 0 "register_operand" "=r")
1153 (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1154 (const_int 0))
1155 (match_operand:W 1 "register_operand" "r")))]
1156 "TARGET_ARCH64 && TARGET_VIS3
1157 && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)"
1158 "addxc\t%%g0, %1, %0"
1159 [(set_attr "type" "ialuX")])
1160
1161 (define_insn "*plus_plus_sltu<W:mode>_vis3"
1162 [(set (match_operand:W 0 "register_operand" "=r")
1163 (plus:W (plus:W (ltu:W (match_operand 3 "icc_register_operand" "X")
1164 (const_int 0))
1165 (match_operand:W 1 "register_operand" "%r"))
1166 (match_operand:W 2 "register_operand" "r")))]
1167 "TARGET_ARCH64 && TARGET_VIS3
1168 && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)"
1169 "addxc\t%1, %2, %0"
1170 [(set_attr "type" "ialuX")])
1171
1172 (define_insn "*addxc<W:mode>"
1173 [(set (match_operand:W 0 "register_operand" "=r")
1174 (plus:W (plus:W (match_operand:W 1 "register_operand" "%r")
1175 (match_operand:W 2 "register_operand" "r"))
1176 (ltu:W (match_operand 3 "icc_register_operand" "X")
1177 (const_int 0))))]
1178 "TARGET_ARCH64 && TARGET_VIS3
1179 && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)"
1180 "addxc\t%1, %2, %0"
1181 [(set_attr "type" "ialuX")])
1182
1183 (define_insn "*neg_sltu<W:mode>"
1184 [(set (match_operand:W 0 "register_operand" "=r")
1185 (neg:W (ltu:W (match_operand 1 "icc_register_operand" "X")
1186 (const_int 0))))]
1187 "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode"
1188 "subx\t%%g0, 0, %0"
1189 [(set_attr "type" "ialuX")])
1190
1191 (define_insn "*neg_sltusidi"
1192 [(set (match_operand:DI 0 "register_operand" "=r")
1193 (sign_extend:DI (neg:SI (ltu:SI (match_operand 1 "icc_register_operand" "X")
1194 (const_int 0)))))]
1195 "TARGET_ARCH64
1196 && (GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode)"
1197 "subx\t%%g0, 0, %0"
1198 [(set_attr "type" "ialuX")])
1199
1200 (define_insn "*minus_neg_sltu<W:mode>"
1201 [(set (match_operand:W 0 "register_operand" "=r")
1202 (minus:W (neg:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1203 (const_int 0)))
1204 (match_operand:W 1 "arith_operand" "rI")))]
1205 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1206 "subx\t%%g0, %1, %0"
1207 [(set_attr "type" "ialuX")])
1208
1209 (define_insn "*neg_plus_sltu<W:mode>"
1210 [(set (match_operand:W 0 "register_operand" "=r")
1211 (neg:W (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1212 (const_int 0))
1213 (match_operand:W 1 "arith_operand" "rI"))))]
1214 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1215 "subx\t%%g0, %1, %0"
1216 [(set_attr "type" "ialuX")])
1217
1218 (define_insn "*minus_sltu<W:mode>"
1219 [(set (match_operand:W 0 "register_operand" "=r")
1220 (minus:W (match_operand:W 1 "register_operand" "r")
1221 (ltu:W (match_operand 2 "icc_register_operand" "X")
1222 (const_int 0))))]
1223 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1224 "subx\t%1, 0, %0"
1225 [(set_attr "type" "ialuX")])
1226
1227 (define_insn "*minus_minus_sltu<W:mode>"
1228 [(set (match_operand:W 0 "register_operand" "=r")
1229 (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ")
1230 (ltu:W (match_operand 3 "icc_register_operand" "X")
1231 (const_int 0)))
1232 (match_operand:W 2 "arith_operand" "rI")))]
1233 "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode"
1234 "subx\t%r1, %2, %0"
1235 [(set_attr "type" "ialuX")])
1236
1237 (define_insn "*sgeu<W:mode>_insn"
1238 [(set (match_operand:W 0 "register_operand" "=r")
1239 (geu:W (match_operand 1 "icc_register_operand" "X") (const_int 0)))]
1240 "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode"
1241 "subx\t%%g0, -1, %0"
1242 [(set_attr "type" "ialuX")])
1243
1244 (define_insn "*plus_sgeu<W:mode>"
1245 [(set (match_operand:W 0 "register_operand" "=r")
1246 (plus:W (geu:W (match_operand 2 "icc_register_operand" "X")
1247 (const_int 0))
1248 (match_operand:W 1 "register_operand" "r")))]
1249 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1250 "subx\t%1, -1, %0"
1251 [(set_attr "type" "ialuX")])
1252
1253 (define_insn "*subx<W:mode>"
1254 [(set (match_operand:W 0 "register_operand" "=r")
1255 (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ")
1256 (match_operand:W 2 "arith_operand" "rI"))
1257 (ltu:W (match_operand 3 "icc_register_operand" "X")
1258 (const_int 0))))]
1259 "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode"
1260 "subx\t%r1, %2, %0"
1261 [(set_attr "type" "ialuX")])
1262
1263 (define_insn "*neg_sltu<W:mode>_subxc"
1264 [(set (match_operand:W 0 "register_operand" "=r")
1265 (neg:W (ltu:W (match_operand 1 "icc_register_operand" "X")
1266 (const_int 0))))]
1267 "TARGET_ARCH64 && TARGET_SUBXC
1268 && (GET_MODE (operands[1]) == CCXmode || GET_MODE (operands[1]) == CCXCmode)"
1269 "subxc\t%%g0, %%g0, %0"
1270 [(set_attr "type" "ialuX")])
1271
1272 (define_insn "*minus_neg_sltu<W:mode>_subxc"
1273 [(set (match_operand:W 0 "register_operand" "=r")
1274 (minus:W (neg:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1275 (const_int 0)))
1276 (match_operand:W 1 "register_operand" "r")))]
1277 "TARGET_ARCH64 && TARGET_SUBXC
1278 && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)"
1279 "subxc\t%%g0, %1, %0"
1280 [(set_attr "type" "ialuX")])
1281
1282 (define_insn "*neg_plus_sltu<W:mode>_subxc"
1283 [(set (match_operand:W 0 "register_operand" "=r")
1284 (neg:W (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1285 (const_int 0))
1286 (match_operand:W 1 "register_operand" "r"))))]
1287 "TARGET_ARCH64 && TARGET_SUBXC
1288 && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)"
1289 "subxc\t%%g0, %1, %0"
1290 [(set_attr "type" "ialuX")])
1291
1292 (define_insn "*minus_sltu<W:mode>_subxc"
1293 [(set (match_operand:W 0 "register_operand" "=r")
1294 (minus:W (match_operand:W 1 "register_operand" "r")
1295 (ltu:W (match_operand 2 "icc_register_operand" "X")
1296 (const_int 0))))]
1297 "TARGET_ARCH64 && TARGET_SUBXC
1298 && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)"
1299 "subxc\t%1, %%g0, %0"
1300 [(set_attr "type" "ialuX")])
1301
1302 (define_insn "*minus_minus_sltu<W:mode>_subxc"
1303 [(set (match_operand:W 0 "register_operand" "=r")
1304 (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ")
1305 (ltu:W (match_operand 3 "icc_register_operand" "X")
1306 (const_int 0)))
1307 (match_operand:W 2 "register_operand" "r")))]
1308 "TARGET_ARCH64 && TARGET_SUBXC
1309 && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)"
1310 "subxc\t%r1, %2, %0"
1311 [(set_attr "type" "ialuX")])
1312
1313 (define_insn "*subxc<W:mode>"
1314 [(set (match_operand:W 0 "register_operand" "=r")
1315 (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ")
1316 (match_operand:W 2 "register_operand" "r"))
1317 (ltu:W (match_operand 3 "icc_register_operand" "X")
1318 (const_int 0))))]
1319 "TARGET_ARCH64 && TARGET_SUBXC
1320 && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)"
1321 "subxc\t%r1, %2, %0"
1322 [(set_attr "type" "ialuX")])
1323
1324 (define_split
1325 [(set (match_operand:W 0 "register_operand" "")
1326 (match_operator:W 1 "icc_comparison_operator"
1327 [(match_operand 2 "icc_register_operand" "") (const_int 0)]))]
1328 "TARGET_V9
1329 /* 64-bit LTU is better implemented using addxc with VIS3. */
1330 && !(GET_CODE (operands[1]) == LTU
1331 && (GET_MODE (operands[2]) == CCXmode
1332 || GET_MODE (operands[2]) == CCXCmode)
1333 && TARGET_VIS3)
1334 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1335 && !((GET_CODE (operands[1]) == LTU || GET_CODE (operands[1]) == GEU)
1336 && (GET_MODE (operands[2]) == CCmode
1337 || GET_MODE (operands[2]) == CCCmode))"
1338 [(set (match_dup 0) (const_int 0))
1339 (set (match_dup 0)
1340 (if_then_else:SI (match_op_dup:W 1 [(match_dup 2) (const_int 0)])
1341 (const_int 1)
1342 (match_dup 0)))]
1343 "")
1344
1345 ;; These control RTL generation for conditional jump insns
1346
1347 (define_expand "cbranchcc4"
1348 [(set (pc)
1349 (if_then_else (match_operator 0 "comparison_operator"
1350 [(match_operand 1 "compare_operand" "")
1351 (match_operand 2 "const_zero_operand" "")])
1352 (label_ref (match_operand 3 "" ""))
1353 (pc)))]
1354 ""
1355 "")
1356
1357 (define_expand "cbranchsi4"
1358 [(use (match_operator 0 "comparison_operator"
1359 [(match_operand:SI 1 "compare_operand" "")
1360 (match_operand:SI 2 "arith_operand" "")]))
1361 (use (match_operand 3 ""))]
1362 ""
1363 {
1364 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1365 operands[1] = force_reg (SImode, operands[1]);
1366 emit_conditional_branch_insn (operands);
1367 DONE;
1368 })
1369
1370 (define_expand "cbranchdi4"
1371 [(use (match_operator 0 "comparison_operator"
1372 [(match_operand:DI 1 "compare_operand" "")
1373 (match_operand:DI 2 "arith_operand" "")]))
1374 (use (match_operand 3 ""))]
1375 "TARGET_ARCH64"
1376 {
1377 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1378 operands[1] = force_reg (DImode, operands[1]);
1379 emit_conditional_branch_insn (operands);
1380 DONE;
1381 })
1382
1383 (define_expand "cbranch<F:mode>4"
1384 [(use (match_operator 0 "comparison_operator"
1385 [(match_operand:F 1 "register_operand" "")
1386 (match_operand:F 2 "register_operand" "")]))
1387 (use (match_operand 3 ""))]
1388 "TARGET_FPU"
1389 {
1390 emit_conditional_branch_insn (operands);
1391 DONE;
1392 })
1393
1394
1395 ;; Now match both normal and inverted jump.
1396
1397 ;; XXX fpcmp nop braindamage
1398 (define_insn "*normal_branch"
1399 [(set (pc)
1400 (if_then_else (match_operator 0 "icc_comparison_operator"
1401 [(reg CC_REG) (const_int 0)])
1402 (label_ref (match_operand 1 "" ""))
1403 (pc)))]
1404 ""
1405 {
1406 return output_cbranch (operands[0], operands[1], 1, 0,
1407 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1408 insn);
1409 }
1410 [(set_attr "type" "branch")
1411 (set_attr "branch_type" "icc")])
1412
1413 ;; XXX fpcmp nop braindamage
1414 (define_insn "*inverted_branch"
1415 [(set (pc)
1416 (if_then_else (match_operator 0 "icc_comparison_operator"
1417 [(reg CC_REG) (const_int 0)])
1418 (pc)
1419 (label_ref (match_operand 1 "" ""))))]
1420 ""
1421 {
1422 return output_cbranch (operands[0], operands[1], 1, 1,
1423 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1424 insn);
1425 }
1426 [(set_attr "type" "branch")
1427 (set_attr "branch_type" "icc")])
1428
1429 ;; XXX fpcmp nop braindamage
1430 (define_insn "*normal_fp_branch"
1431 [(set (pc)
1432 (if_then_else (match_operator 1 "comparison_operator"
1433 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1434 (const_int 0)])
1435 (label_ref (match_operand 2 "" ""))
1436 (pc)))]
1437 ""
1438 {
1439 return output_cbranch (operands[1], operands[2], 2, 0,
1440 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1441 insn);
1442 }
1443 [(set_attr "type" "branch")
1444 (set_attr "branch_type" "fcc")])
1445
1446 ;; XXX fpcmp nop braindamage
1447 (define_insn "*inverted_fp_branch"
1448 [(set (pc)
1449 (if_then_else (match_operator 1 "comparison_operator"
1450 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1451 (const_int 0)])
1452 (pc)
1453 (label_ref (match_operand 2 "" ""))))]
1454 ""
1455 {
1456 return output_cbranch (operands[1], operands[2], 2, 1,
1457 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1458 insn);
1459 }
1460 [(set_attr "type" "branch")
1461 (set_attr "branch_type" "fcc")])
1462
1463 ;; XXX fpcmp nop braindamage
1464 (define_insn "*normal_fpe_branch"
1465 [(set (pc)
1466 (if_then_else (match_operator 1 "comparison_operator"
1467 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1468 (const_int 0)])
1469 (label_ref (match_operand 2 "" ""))
1470 (pc)))]
1471 ""
1472 {
1473 return output_cbranch (operands[1], operands[2], 2, 0,
1474 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1475 insn);
1476 }
1477 [(set_attr "type" "branch")
1478 (set_attr "branch_type" "fcc")])
1479
1480 ;; XXX fpcmp nop braindamage
1481 (define_insn "*inverted_fpe_branch"
1482 [(set (pc)
1483 (if_then_else (match_operator 1 "comparison_operator"
1484 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1485 (const_int 0)])
1486 (pc)
1487 (label_ref (match_operand 2 "" ""))))]
1488 ""
1489 {
1490 return output_cbranch (operands[1], operands[2], 2, 1,
1491 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1492 insn);
1493 }
1494 [(set_attr "type" "branch")
1495 (set_attr "branch_type" "fcc")])
1496
1497 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1498 ;; in the architecture.
1499
1500 (define_insn "*cbcond_sp32"
1501 [(set (pc)
1502 (if_then_else (match_operator 0 "comparison_operator"
1503 [(match_operand:SI 1 "register_operand" "r")
1504 (match_operand:SI 2 "arith5_operand" "rA")])
1505 (label_ref (match_operand 3 "" ""))
1506 (pc)))]
1507 "TARGET_CBCOND"
1508 {
1509 return output_cbcond (operands[0], operands[3], insn);
1510 }
1511 [(set_attr "type" "cbcond")])
1512
1513 (define_insn "*cbcond_sp64"
1514 [(set (pc)
1515 (if_then_else (match_operator 0 "comparison_operator"
1516 [(match_operand:DI 1 "register_operand" "r")
1517 (match_operand:DI 2 "arith5_operand" "rA")])
1518 (label_ref (match_operand 3 "" ""))
1519 (pc)))]
1520 "TARGET_ARCH64 && TARGET_CBCOND"
1521 {
1522 return output_cbcond (operands[0], operands[3], insn);
1523 }
1524 [(set_attr "type" "cbcond")])
1525
1526 ;; There are no 32-bit brreg insns.
1527
1528 (define_insn "*normal_int_branch_sp64"
1529 [(set (pc)
1530 (if_then_else (match_operator 0 "v9_register_comparison_operator"
1531 [(match_operand:DI 1 "register_operand" "r")
1532 (const_int 0)])
1533 (label_ref (match_operand 2 "" ""))
1534 (pc)))]
1535 "TARGET_ARCH64"
1536 {
1537 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1538 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1539 insn);
1540 }
1541 [(set_attr "type" "branch")
1542 (set_attr "branch_type" "reg")])
1543
1544 (define_insn "*inverted_int_branch_sp64"
1545 [(set (pc)
1546 (if_then_else (match_operator 0 "v9_register_comparison_operator"
1547 [(match_operand:DI 1 "register_operand" "r")
1548 (const_int 0)])
1549 (pc)
1550 (label_ref (match_operand 2 "" ""))))]
1551 "TARGET_ARCH64"
1552 {
1553 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1554 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1555 insn);
1556 }
1557 [(set_attr "type" "branch")
1558 (set_attr "branch_type" "reg")])
1559
1560
1561 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1562 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1563 ;; that adds the PC value at the call point to register #(operand 3).
1564 ;;
1565 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1566 ;; because the RDPC instruction is extremely expensive and incurs a complete
1567 ;; instruction pipeline flush.
1568
1569 (define_insn "load_pcrel_sym<P:mode>"
1570 [(set (match_operand:P 0 "register_operand" "=r")
1571 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1572 (match_operand:P 2 "call_address_operand" "")
1573 (match_operand:P 3 "const_int_operand" "")]
1574 UNSPEC_LOAD_PCREL_SYM))
1575 (clobber (reg:P O7_REG))]
1576 "REGNO (operands[0]) == INTVAL (operands[3])"
1577 {
1578 if (flag_delayed_branch)
1579 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1580 else
1581 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1582 }
1583 [(set (attr "type") (const_string "multi"))
1584 (set (attr "length")
1585 (if_then_else (eq_attr "delayed_branch" "true")
1586 (const_int 3)
1587 (const_int 4)))])
1588
1589
1590 ;; Integer move instructions
1591
1592 (define_expand "movqi"
1593 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1594 (match_operand:QI 1 "general_operand" ""))]
1595 ""
1596 {
1597 if (sparc_expand_move (QImode, operands))
1598 DONE;
1599 })
1600
1601 (define_insn "*movqi_insn"
1602 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1603 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1604 "(register_operand (operands[0], QImode)
1605 || register_or_zero_operand (operands[1], QImode))"
1606 "@
1607 mov\t%1, %0
1608 ldub\t%1, %0
1609 stb\t%r1, %0"
1610 [(set_attr "type" "*,load,store")
1611 (set_attr "subtype" "*,regular,*")
1612 (set_attr "us3load_type" "*,3cycle,*")])
1613
1614 (define_expand "movhi"
1615 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1616 (match_operand:HI 1 "general_operand" ""))]
1617 ""
1618 {
1619 if (sparc_expand_move (HImode, operands))
1620 DONE;
1621 })
1622
1623 (define_insn "*movhi_insn"
1624 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1625 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1626 "(register_operand (operands[0], HImode)
1627 || register_or_zero_operand (operands[1], HImode))"
1628 "@
1629 mov\t%1, %0
1630 sethi\t%%hi(%a1), %0
1631 lduh\t%1, %0
1632 sth\t%r1, %0"
1633 [(set_attr "type" "*,*,load,store")
1634 (set_attr "subtype" "*,*,regular,*")
1635 (set_attr "us3load_type" "*,*,3cycle,*")])
1636
1637 ;; We always work with constants here.
1638 (define_insn "*movhi_lo_sum"
1639 [(set (match_operand:HI 0 "register_operand" "=r")
1640 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1641 (match_operand:HI 2 "small_int_operand" "I")))]
1642 ""
1643 "or\t%1, %2, %0")
1644
1645 (define_expand "movsi"
1646 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1647 (match_operand:SI 1 "general_operand" ""))]
1648 ""
1649 {
1650 if (sparc_expand_move (SImode, operands))
1651 DONE;
1652 })
1653
1654 (define_insn "*movsi_insn"
1655 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1656 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1657 "register_operand (operands[0], SImode)
1658 || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1659 "@
1660 mov\t%1, %0
1661 sethi\t%%hi(%a1), %0
1662 ld\t%1, %0
1663 st\t%r1, %0
1664 movstouw\t%1, %0
1665 movwtos\t%1, %0
1666 fmovs\t%1, %0
1667 ld\t%1, %0
1668 st\t%1, %0
1669 fzeros\t%0
1670 fones\t%0"
1671 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1672 (set_attr "subtype" "*,*,regular,*,movstouw,single,*,*,*,single,single")
1673 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1674
1675 (define_insn "*movsi_lo_sum"
1676 [(set (match_operand:SI 0 "register_operand" "=r")
1677 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1678 (match_operand:SI 2 "immediate_operand" "in")))]
1679 "!flag_pic"
1680 "or\t%1, %%lo(%a2), %0")
1681
1682 (define_insn "*movsi_high"
1683 [(set (match_operand:SI 0 "register_operand" "=r")
1684 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1685 "!flag_pic"
1686 "sethi\t%%hi(%a1), %0")
1687
1688 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1689 ;; so that CSE won't optimize the address computation away.
1690 (define_insn "movsi_lo_sum_pic"
1691 [(set (match_operand:SI 0 "register_operand" "=r")
1692 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1693 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")]
1694 UNSPEC_MOVE_PIC)))]
1695 "flag_pic"
1696 {
1697 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1698 return "xor\t%1, %%gdop_lox10(%a2), %0";
1699 #else
1700 return "or\t%1, %%lo(%a2), %0";
1701 #endif
1702 })
1703
1704 (define_insn "movsi_high_pic"
1705 [(set (match_operand:SI 0 "register_operand" "=r")
1706 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1707 "flag_pic && check_pic (1)"
1708 {
1709 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1710 return "sethi\t%%gdop_hix22(%a1), %0";
1711 #else
1712 return "sethi\t%%hi(%a1), %0";
1713 #endif
1714 })
1715
1716 (define_insn "movsi_pic_gotdata_op"
1717 [(set (match_operand:SI 0 "register_operand" "=r")
1718 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1719 (match_operand:SI 2 "register_operand" "r")
1720 (match_operand 3 "symbolic_operand" "")]
1721 UNSPEC_MOVE_GOTDATA))]
1722 "flag_pic && check_pic (1)"
1723 {
1724 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1725 return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1726 #else
1727 return "ld\t[%1 + %2], %0";
1728 #endif
1729 }
1730 [(set_attr "type" "load")
1731 (set_attr "subtype" "regular")])
1732
1733 (define_expand "movsi_pic_label_ref"
1734 [(set (match_dup 3) (high:SI
1735 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1736 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1737 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1738 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1739 (set (match_operand:SI 0 "register_operand" "=r")
1740 (minus:SI (match_dup 5) (match_dup 4)))]
1741 "flag_pic"
1742 {
1743 crtl->uses_pic_offset_table = 1;
1744 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1745 if (!can_create_pseudo_p ())
1746 {
1747 operands[3] = operands[0];
1748 operands[4] = operands[0];
1749 }
1750 else
1751 {
1752 operands[3] = gen_reg_rtx (SImode);
1753 operands[4] = gen_reg_rtx (SImode);
1754 }
1755 operands[5] = pic_offset_table_rtx;
1756 })
1757
1758 (define_insn "*movsi_high_pic_label_ref"
1759 [(set (match_operand:SI 0 "register_operand" "=r")
1760 (high:SI
1761 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1762 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1763 "flag_pic"
1764 "sethi\t%%hi(%a2-(%a1-.)), %0")
1765
1766 (define_insn "*movsi_lo_sum_pic_label_ref"
1767 [(set (match_operand:SI 0 "register_operand" "=r")
1768 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1769 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1770 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1771 "flag_pic"
1772 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1773
1774 ;; Set up the PIC register for VxWorks.
1775
1776 (define_expand "vxworks_load_got"
1777 [(set (match_dup 0)
1778 (high:SI (match_dup 1)))
1779 (set (match_dup 0)
1780 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1781 (set (match_dup 0)
1782 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1783 "TARGET_VXWORKS_RTP"
1784 {
1785 operands[0] = pic_offset_table_rtx;
1786 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1787 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1788 })
1789
1790 (define_expand "movdi"
1791 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1792 (match_operand:DI 1 "general_operand" ""))]
1793 ""
1794 {
1795 if (sparc_expand_move (DImode, operands))
1796 DONE;
1797 })
1798
1799 ;; Be careful, fmovd does not exist when !v9.
1800 ;; We match MEM moves directly when we have correct even
1801 ;; numbered registers, but fall into splits otherwise.
1802 ;; The constraint ordering here is really important to
1803 ;; avoid insane problems in reload, especially for patterns
1804 ;; of the form:
1805 ;;
1806 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1807 ;; (const_int -5016)))
1808 ;; (reg:DI 2 %g2))
1809 ;;
1810
1811 (define_insn "*movdi_insn_sp32"
1812 [(set (match_operand:DI 0 "nonimmediate_operand"
1813 "=T,o,U,T,r,o,r,r,?*f,?T,?*f,?o,?*e,?*e, r,?*f,?*e,?T,*b,*b")
1814 (match_operand:DI 1 "input_operand"
1815 " J,J,T,U,o,r,i,r, T,*f, o,*f, *e, *e,?*f, r, T,*e, J, P"))]
1816 "TARGET_ARCH32
1817 && (register_operand (operands[0], DImode)
1818 || register_or_zero_operand (operands[1], DImode))"
1819 "@
1820 stx\t%r1, %0
1821 #
1822 ldd\t%1, %0
1823 std\t%1, %0
1824 ldd\t%1, %0
1825 std\t%1, %0
1826 #
1827 #
1828 ldd\t%1, %0
1829 std\t%1, %0
1830 #
1831 #
1832 fmovd\t%1, %0
1833 #
1834 #
1835 #
1836 ldd\t%1, %0
1837 std\t%1, %0
1838 fzero\t%0
1839 fone\t%0"
1840 [(set_attr "type" "store,*,load,store,load,store,*,*,fpload,fpstore,*,*,fpmove,*,*,*,fpload,fpstore,visl,
1841 visl")
1842 (set_attr "subtype" "*,*,regular,*,regular,*,*,*,*,*,*,*,*,*,*,*,*,*,double,double")
1843 (set_attr "length" "*,2,*,*,*,*,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1844 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1845 (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")
1846 (set_attr "lra" "*,*,disabled,disabled,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
1847
1848 (define_insn "*movdi_insn_sp64"
1849 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1850 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))]
1851 "TARGET_ARCH64
1852 && (register_operand (operands[0], DImode)
1853 || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1854 "@
1855 mov\t%1, %0
1856 sethi\t%%hi(%a1), %0
1857 ldx\t%1, %0
1858 stx\t%r1, %0
1859 movdtox\t%1, %0
1860 movxtod\t%1, %0
1861 fmovd\t%1, %0
1862 ldd\t%1, %0
1863 std\t%1, %0
1864 fzero\t%0
1865 fone\t%0"
1866 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1867 (set_attr "subtype" "*,*,regular,*,movdtox,movxtod,*,*,*,double,double")
1868 (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1869 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1870
1871 (define_expand "movdi_pic_label_ref"
1872 [(set (match_dup 3) (high:DI
1873 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1874 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1875 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1876 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1877 (set (match_operand:DI 0 "register_operand" "=r")
1878 (minus:DI (match_dup 5) (match_dup 4)))]
1879 "TARGET_ARCH64 && flag_pic"
1880 {
1881 crtl->uses_pic_offset_table = 1;
1882 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1883 if (!can_create_pseudo_p ())
1884 {
1885 operands[3] = operands[0];
1886 operands[4] = operands[0];
1887 }
1888 else
1889 {
1890 operands[3] = gen_reg_rtx (DImode);
1891 operands[4] = gen_reg_rtx (DImode);
1892 }
1893 operands[5] = pic_offset_table_rtx;
1894 })
1895
1896 (define_insn "*movdi_high_pic_label_ref"
1897 [(set (match_operand:DI 0 "register_operand" "=r")
1898 (high:DI
1899 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1900 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1901 "TARGET_ARCH64 && flag_pic"
1902 "sethi\t%%hi(%a2-(%a1-.)), %0")
1903
1904 (define_insn "*movdi_lo_sum_pic_label_ref"
1905 [(set (match_operand:DI 0 "register_operand" "=r")
1906 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1907 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1908 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1909 "TARGET_ARCH64 && flag_pic"
1910 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1911
1912 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
1913 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1914
1915 (define_insn "movdi_lo_sum_pic"
1916 [(set (match_operand:DI 0 "register_operand" "=r")
1917 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1918 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")]
1919 UNSPEC_MOVE_PIC)))]
1920 "TARGET_ARCH64 && flag_pic"
1921 {
1922 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1923 return "xor\t%1, %%gdop_lox10(%a2), %0";
1924 #else
1925 return "or\t%1, %%lo(%a2), %0";
1926 #endif
1927 })
1928
1929 (define_insn "movdi_high_pic"
1930 [(set (match_operand:DI 0 "register_operand" "=r")
1931 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1932 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1933 {
1934 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1935 return "sethi\t%%gdop_hix22(%a1), %0";
1936 #else
1937 return "sethi\t%%hi(%a1), %0";
1938 #endif
1939 })
1940
1941 (define_insn "movdi_pic_gotdata_op"
1942 [(set (match_operand:DI 0 "register_operand" "=r")
1943 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1944 (match_operand:DI 2 "register_operand" "r")
1945 (match_operand 3 "symbolic_operand" "")]
1946 UNSPEC_MOVE_GOTDATA))]
1947 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1948 {
1949 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1950 return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1951 #else
1952 return "ldx\t[%1 + %2], %0";
1953 #endif
1954 }
1955 [(set_attr "type" "load")
1956 (set_attr "subtype" "regular")])
1957
1958 (define_insn "*sethi_di_medlow_embmedany_pic"
1959 [(set (match_operand:DI 0 "register_operand" "=r")
1960 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1961 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && flag_pic && check_pic (1)"
1962 "sethi\t%%hi(%a1), %0")
1963
1964 (define_insn "*sethi_di_medlow"
1965 [(set (match_operand:DI 0 "register_operand" "=r")
1966 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1967 "TARGET_CM_MEDLOW && !flag_pic"
1968 "sethi\t%%hi(%a1), %0")
1969
1970 (define_insn "*losum_di_medlow"
1971 [(set (match_operand:DI 0 "register_operand" "=r")
1972 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1973 (match_operand:DI 2 "symbolic_operand" "")))]
1974 "TARGET_CM_MEDLOW && !flag_pic"
1975 "or\t%1, %%lo(%a2), %0")
1976
1977 (define_insn "seth44"
1978 [(set (match_operand:DI 0 "register_operand" "=r")
1979 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
1980 UNSPEC_SETH44)))]
1981 "TARGET_CM_MEDMID && !flag_pic"
1982 "sethi\t%%h44(%a1), %0")
1983
1984 (define_insn "setm44"
1985 [(set (match_operand:DI 0 "register_operand" "=r")
1986 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1987 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
1988 UNSPEC_SETM44)))]
1989 "TARGET_CM_MEDMID && !flag_pic"
1990 "or\t%1, %%m44(%a2), %0")
1991
1992 (define_insn "setl44"
1993 [(set (match_operand:DI 0 "register_operand" "=r")
1994 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1995 (match_operand:DI 2 "symbolic_operand" "")))]
1996 "TARGET_CM_MEDMID && !flag_pic"
1997 "or\t%1, %%l44(%a2), %0")
1998
1999 (define_insn "sethh"
2000 [(set (match_operand:DI 0 "register_operand" "=r")
2001 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2002 UNSPEC_SETHH)))]
2003 "TARGET_CM_MEDANY && !flag_pic"
2004 "sethi\t%%hh(%a1), %0")
2005
2006 (define_insn "setlm"
2007 [(set (match_operand:DI 0 "register_operand" "=r")
2008 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2009 UNSPEC_SETLM)))]
2010 "TARGET_CM_MEDANY && !flag_pic"
2011 "sethi\t%%lm(%a1), %0")
2012
2013 (define_insn "sethm"
2014 [(set (match_operand:DI 0 "register_operand" "=r")
2015 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2016 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
2017 UNSPEC_EMB_SETHM)))]
2018 "TARGET_CM_MEDANY && !flag_pic"
2019 "or\t%1, %%hm(%a2), %0")
2020
2021 (define_insn "setlo"
2022 [(set (match_operand:DI 0 "register_operand" "=r")
2023 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2024 (match_operand:DI 2 "symbolic_operand" "")))]
2025 "TARGET_CM_MEDANY && !flag_pic"
2026 "or\t%1, %%lo(%a2), %0")
2027
2028 (define_insn "embmedany_sethi"
2029 [(set (match_operand:DI 0 "register_operand" "=r")
2030 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")]
2031 UNSPEC_EMB_HISUM)))]
2032 "TARGET_CM_EMBMEDANY && !flag_pic"
2033 "sethi\t%%hi(%a1), %0")
2034
2035 (define_insn "embmedany_losum"
2036 [(set (match_operand:DI 0 "register_operand" "=r")
2037 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2038 (match_operand:DI 2 "data_segment_operand" "")))]
2039 "TARGET_CM_EMBMEDANY && !flag_pic"
2040 "add\t%1, %%lo(%a2), %0")
2041
2042 (define_insn "embmedany_brsum"
2043 [(set (match_operand:DI 0 "register_operand" "=r")
2044 (unspec:DI [(match_operand:DI 1 "register_operand" "r")]
2045 UNSPEC_EMB_HISUM))]
2046 "TARGET_CM_EMBMEDANY && !flag_pic"
2047 "add\t%1, %_, %0")
2048
2049 (define_insn "embmedany_textuhi"
2050 [(set (match_operand:DI 0 "register_operand" "=r")
2051 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")]
2052 UNSPEC_EMB_TEXTUHI)))]
2053 "TARGET_CM_EMBMEDANY && !flag_pic"
2054 "sethi\t%%uhi(%a1), %0")
2055
2056 (define_insn "embmedany_texthi"
2057 [(set (match_operand:DI 0 "register_operand" "=r")
2058 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")]
2059 UNSPEC_EMB_TEXTHI)))]
2060 "TARGET_CM_EMBMEDANY && !flag_pic"
2061 "sethi\t%%hi(%a1), %0")
2062
2063 (define_insn "embmedany_textulo"
2064 [(set (match_operand:DI 0 "register_operand" "=r")
2065 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2066 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")]
2067 UNSPEC_EMB_TEXTULO)))]
2068 "TARGET_CM_EMBMEDANY && !flag_pic"
2069 "or\t%1, %%ulo(%a2), %0")
2070
2071 (define_insn "embmedany_textlo"
2072 [(set (match_operand:DI 0 "register_operand" "=r")
2073 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2074 (match_operand:DI 2 "text_segment_operand" "")))]
2075 "TARGET_CM_EMBMEDANY && !flag_pic"
2076 "or\t%1, %%lo(%a2), %0")
2077
2078 ;; Now some patterns to help reload out a bit.
2079 (define_expand "reload_indi"
2080 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2081 (match_operand:DI 1 "immediate_operand" "")
2082 (match_operand:TI 2 "register_operand" "=&r")])]
2083 "(TARGET_CM_MEDANY || TARGET_CM_EMBMEDANY) && !flag_pic"
2084 {
2085 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2086 DONE;
2087 })
2088
2089 (define_expand "reload_outdi"
2090 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2091 (match_operand:DI 1 "immediate_operand" "")
2092 (match_operand:TI 2 "register_operand" "=&r")])]
2093 "(TARGET_CM_MEDANY || TARGET_CM_EMBMEDANY) && !flag_pic"
2094 {
2095 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2096 DONE;
2097 })
2098
2099 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2100 (define_split
2101 [(set (match_operand:DI 0 "register_operand" "")
2102 (match_operand:DI 1 "const_int_operand" ""))]
2103 "reload_completed
2104 && TARGET_ARCH32
2105 && ((GET_CODE (operands[0]) == REG
2106 && SPARC_INT_REG_P (REGNO (operands[0])))
2107 || (GET_CODE (operands[0]) == SUBREG
2108 && GET_CODE (SUBREG_REG (operands[0])) == REG
2109 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2110 [(clobber (const_int 0))]
2111 {
2112 HOST_WIDE_INT low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2113 HOST_WIDE_INT high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2114 rtx high_part = gen_highpart (SImode, operands[0]);
2115 rtx low_part = gen_lowpart (SImode, operands[0]);
2116
2117 emit_move_insn_1 (high_part, GEN_INT (high));
2118
2119 /* Slick... but this loses if the constant can be done in one insn. */
2120 if (low == high && !SPARC_SETHI32_P (high) && !SPARC_SIMM13_P (high))
2121 emit_move_insn_1 (low_part, high_part);
2122 else
2123 emit_move_insn_1 (low_part, GEN_INT (low));
2124
2125 DONE;
2126 })
2127
2128 (define_split
2129 [(set (match_operand:DI 0 "register_operand" "")
2130 (match_operand:DI 1 "register_operand" ""))]
2131 "reload_completed
2132 && (!TARGET_V9
2133 || (TARGET_ARCH32
2134 && sparc_split_reg_reg_legitimate (operands[0], operands[1])))"
2135 [(clobber (const_int 0))]
2136 {
2137 sparc_split_reg_reg (operands[0], operands[1], SImode);
2138 DONE;
2139 })
2140
2141 ;; Now handle the cases of memory moves from/to non-even
2142 ;; DI mode register pairs.
2143 (define_split
2144 [(set (match_operand:DI 0 "register_operand" "")
2145 (match_operand:DI 1 "memory_operand" ""))]
2146 "reload_completed
2147 && TARGET_ARCH32
2148 && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
2149 [(clobber (const_int 0))]
2150 {
2151 sparc_split_reg_mem (operands[0], operands[1], SImode);
2152 DONE;
2153 })
2154
2155 (define_split
2156 [(set (match_operand:DI 0 "memory_operand" "")
2157 (match_operand:DI 1 "register_operand" ""))]
2158 "reload_completed
2159 && TARGET_ARCH32
2160 && sparc_split_reg_mem_legitimate (operands[1], operands[0])"
2161 [(clobber (const_int 0))]
2162 {
2163 sparc_split_mem_reg (operands[0], operands[1], SImode);
2164 DONE;
2165 })
2166
2167 (define_split
2168 [(set (match_operand:DI 0 "memory_operand" "")
2169 (match_operand:DI 1 "const_zero_operand" ""))]
2170 "reload_completed
2171 && (!TARGET_V9
2172 || (TARGET_ARCH32
2173 && !mem_min_alignment (operands[0], 8)))
2174 && offsettable_memref_p (operands[0])"
2175 [(clobber (const_int 0))]
2176 {
2177 emit_move_insn_1 (adjust_address (operands[0], SImode, 0), const0_rtx);
2178 emit_move_insn_1 (adjust_address (operands[0], SImode, 4), const0_rtx);
2179 DONE;
2180 })
2181
2182 (define_expand "movti"
2183 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2184 (match_operand:TI 1 "general_operand" ""))]
2185 "TARGET_ARCH64"
2186 {
2187 if (sparc_expand_move (TImode, operands))
2188 DONE;
2189 })
2190
2191 ;; We need to prevent reload from splitting TImode moves, because it
2192 ;; might decide to overwrite a pointer with the value it points to.
2193 ;; In that case we have to do the loads in the appropriate order so
2194 ;; that the pointer is not destroyed too early.
2195
2196 (define_insn "*movti_insn_sp64"
2197 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2198 (match_operand:TI 1 "input_operand" "roJ,rJ, eo, e,J"))]
2199 "TARGET_ARCH64
2200 && !TARGET_HARD_QUAD
2201 && (register_operand (operands[0], TImode)
2202 || register_or_zero_operand (operands[1], TImode))"
2203 "#"
2204 [(set_attr "length" "2,2,2,2,2")
2205 (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2206
2207 (define_insn "*movti_insn_sp64_hq"
2208 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2209 (match_operand:TI 1 "input_operand" "roJ,rJ, e, m, e,J"))]
2210 "TARGET_ARCH64
2211 && TARGET_HARD_QUAD
2212 && (register_operand (operands[0], TImode)
2213 || register_or_zero_operand (operands[1], TImode))"
2214 "@
2215 #
2216 #
2217 fmovq\t%1, %0
2218 ldq\t%1, %0
2219 stq\t%1, %0
2220 #"
2221 [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2222 (set_attr "length" "2,2,*,*,*,2")])
2223
2224 ;; Now all the splits to handle multi-insn TI mode moves.
2225 (define_split
2226 [(set (match_operand:TI 0 "register_operand" "")
2227 (match_operand:TI 1 "register_operand" ""))]
2228 "reload_completed
2229 && ((TARGET_FPU
2230 && !TARGET_HARD_QUAD)
2231 || (!fp_register_operand (operands[0], TImode)
2232 && !fp_register_operand (operands[1], TImode)))"
2233 [(clobber (const_int 0))]
2234 {
2235 rtx set_dest = operands[0];
2236 rtx set_src = operands[1];
2237 rtx dest1, dest2;
2238 rtx src1, src2;
2239
2240 dest1 = gen_highpart (DImode, set_dest);
2241 dest2 = gen_lowpart (DImode, set_dest);
2242 src1 = gen_highpart (DImode, set_src);
2243 src2 = gen_lowpart (DImode, set_src);
2244
2245 /* Now emit using the real source and destination we found, swapping
2246 the order if we detect overlap. */
2247 if (reg_overlap_mentioned_p (dest1, src2))
2248 {
2249 emit_insn (gen_movdi (dest2, src2));
2250 emit_insn (gen_movdi (dest1, src1));
2251 }
2252 else
2253 {
2254 emit_insn (gen_movdi (dest1, src1));
2255 emit_insn (gen_movdi (dest2, src2));
2256 }
2257 DONE;
2258 })
2259
2260 (define_split
2261 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2262 (match_operand:TI 1 "const_zero_operand" ""))]
2263 "reload_completed"
2264 [(clobber (const_int 0))]
2265 {
2266 rtx set_dest = operands[0];
2267 rtx dest1, dest2;
2268
2269 switch (GET_CODE (set_dest))
2270 {
2271 case REG:
2272 dest1 = gen_highpart (DImode, set_dest);
2273 dest2 = gen_lowpart (DImode, set_dest);
2274 break;
2275 case MEM:
2276 dest1 = adjust_address (set_dest, DImode, 0);
2277 dest2 = adjust_address (set_dest, DImode, 8);
2278 break;
2279 default:
2280 gcc_unreachable ();
2281 }
2282
2283 emit_insn (gen_movdi (dest1, const0_rtx));
2284 emit_insn (gen_movdi (dest2, const0_rtx));
2285 DONE;
2286 })
2287
2288 (define_split
2289 [(set (match_operand:TI 0 "register_operand" "")
2290 (match_operand:TI 1 "memory_operand" ""))]
2291 "reload_completed
2292 && offsettable_memref_p (operands[1])
2293 && (!TARGET_HARD_QUAD
2294 || !fp_register_operand (operands[0], TImode))"
2295 [(clobber (const_int 0))]
2296 {
2297 rtx word0 = adjust_address (operands[1], DImode, 0);
2298 rtx word1 = adjust_address (operands[1], DImode, 8);
2299 rtx set_dest, dest1, dest2;
2300
2301 set_dest = operands[0];
2302
2303 dest1 = gen_highpart (DImode, set_dest);
2304 dest2 = gen_lowpart (DImode, set_dest);
2305
2306 /* Now output, ordering such that we don't clobber any registers
2307 mentioned in the address. */
2308 if (reg_overlap_mentioned_p (dest1, word1))
2309
2310 {
2311 emit_insn (gen_movdi (dest2, word1));
2312 emit_insn (gen_movdi (dest1, word0));
2313 }
2314 else
2315 {
2316 emit_insn (gen_movdi (dest1, word0));
2317 emit_insn (gen_movdi (dest2, word1));
2318 }
2319 DONE;
2320 })
2321
2322 (define_split
2323 [(set (match_operand:TI 0 "memory_operand" "")
2324 (match_operand:TI 1 "register_operand" ""))]
2325 "reload_completed
2326 && offsettable_memref_p (operands[0])
2327 && (!TARGET_HARD_QUAD
2328 || !fp_register_operand (operands[1], TImode))"
2329 [(clobber (const_int 0))]
2330 {
2331 rtx set_src = operands[1];
2332
2333 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2334 gen_highpart (DImode, set_src)));
2335 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2336 gen_lowpart (DImode, set_src)));
2337 DONE;
2338 })
2339
2340
2341 ;; Floating point move instructions
2342
2343 (define_expand "movsf"
2344 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2345 (match_operand:SF 1 "general_operand" ""))]
2346 ""
2347 {
2348 if (sparc_expand_move (SFmode, operands))
2349 DONE;
2350 })
2351
2352 (define_insn "*movsf_insn"
2353 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m")
2354 (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2355 "(register_operand (operands[0], SFmode)
2356 || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2357 {
2358 if (GET_CODE (operands[1]) == CONST_DOUBLE
2359 && (which_alternative == 3
2360 || which_alternative == 4
2361 || which_alternative == 5))
2362 {
2363 long i;
2364
2365 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i);
2366 operands[1] = GEN_INT (i);
2367 }
2368
2369 switch (which_alternative)
2370 {
2371 case 0:
2372 return "fzeros\t%0";
2373 case 1:
2374 return "fones\t%0";
2375 case 2:
2376 return "fmovs\t%1, %0";
2377 case 3:
2378 return "mov\t%1, %0";
2379 case 4:
2380 return "sethi\t%%hi(%a1), %0";
2381 case 5:
2382 return "#";
2383 case 6:
2384 return "movstouw\t%1, %0";
2385 case 7:
2386 return "movwtos\t%1, %0";
2387 case 8:
2388 case 9:
2389 return "ld\t%1, %0";
2390 case 10:
2391 case 11:
2392 return "st\t%r1, %0";
2393 default:
2394 gcc_unreachable ();
2395 }
2396 }
2397 [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2398 (set_attr "subtype" "single,single,*,*,*,*,movstouw,single,*,regular,*,*")
2399 (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2400
2401 ;; The following 3 patterns build SFmode constants in integer registers.
2402
2403 (define_insn "*movsf_lo_sum"
2404 [(set (match_operand:SF 0 "register_operand" "=r")
2405 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2406 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2407 ""
2408 {
2409 long i;
2410
2411 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[2]), i);
2412 operands[2] = GEN_INT (i);
2413 return "or\t%1, %%lo(%a2), %0";
2414 })
2415
2416 (define_insn "*movsf_high"
2417 [(set (match_operand:SF 0 "register_operand" "=r")
2418 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2419 ""
2420 {
2421 long i;
2422
2423 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i);
2424 operands[1] = GEN_INT (i);
2425 return "sethi\t%%hi(%1), %0";
2426 })
2427
2428 (define_split
2429 [(set (match_operand:SF 0 "register_operand" "")
2430 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2431 "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2432 [(set (match_dup 0) (high:SF (match_dup 1)))
2433 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2434
2435 (define_expand "movdf"
2436 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2437 (match_operand:DF 1 "general_operand" ""))]
2438 ""
2439 {
2440 if (sparc_expand_move (DFmode, operands))
2441 DONE;
2442 })
2443
2444 (define_insn "*movdf_insn_sp32"
2445 [(set (match_operand:DF 0 "nonimmediate_operand"
2446 "=T,o,b,b,e,e,*r, f, e,T,U,T, f,o, *r,*r, o")
2447 (match_operand:DF 1 "input_operand"
2448 " G,G,G,C,e,e, f,*r,T#F,e,T,U,o#F,f,*rF, o,*r"))]
2449 "TARGET_ARCH32
2450 && (register_operand (operands[0], DFmode)
2451 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2452 "@
2453 stx\t%r1, %0
2454 #
2455 fzero\t%0
2456 fone\t%0
2457 fmovd\t%1, %0
2458 #
2459 #
2460 #
2461 ldd\t%1, %0
2462 std\t%1, %0
2463 ldd\t%1, %0
2464 std\t%1, %0
2465 #
2466 #
2467 #
2468 ldd\t%1, %0
2469 std\t%1, %0"
2470 [(set_attr "type" "store,*,visl,visl,fpmove,*,*,*,fpload,fpstore,load,store,*,*,*,load,store")
2471 (set_attr "subtype" "*,*,double,double,*,*,*,*,*,*,regular,*,*,*,*,regular,*")
2472 (set_attr "length" "*,2,*,*,*,2,2,2,*,*,*,*,2,2,2,*,*")
2473 (set_attr "fptype" "*,*,double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2474 (set_attr "cpu_feature" "v9,*,vis,vis,v9,fpunotv9,vis3,vis3,fpu,fpu,*,*,fpu,fpu,*,*,*")
2475 (set_attr "lra" "*,*,*,*,*,*,*,*,*,*,disabled,disabled,*,*,*,*,*")])
2476
2477 (define_insn "*movdf_insn_sp64"
2478 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r")
2479 (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2480 "TARGET_ARCH64
2481 && (register_operand (operands[0], DFmode)
2482 || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2483 "@
2484 fzero\t%0
2485 fone\t%0
2486 fmovd\t%1, %0
2487 movdtox\t%1, %0
2488 movxtod\t%1, %0
2489 ldd\t%1, %0
2490 std\t%1, %0
2491 mov\t%r1, %0
2492 ldx\t%1, %0
2493 stx\t%r1, %0
2494 #"
2495 [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2496 (set_attr "subtype" "double,double,*,movdtox,movxtod,regular,*,*,regular,*,*")
2497 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2498 (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2499 (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2500
2501 ;; This pattern builds DFmode constants in integer registers.
2502 (define_split
2503 [(set (match_operand:DF 0 "register_operand" "")
2504 (match_operand:DF 1 "const_double_operand" ""))]
2505 "reload_completed
2506 && REG_P (operands[0])
2507 && SPARC_INT_REG_P (REGNO (operands[0]))
2508 && !const_zero_operand (operands[1], GET_MODE (operands[0]))"
2509 [(clobber (const_int 0))]
2510 {
2511 operands[0] = gen_raw_REG (DImode, REGNO (operands[0]));
2512
2513 if (TARGET_ARCH64)
2514 {
2515 rtx tem = simplify_subreg (DImode, operands[1], DFmode, 0);
2516 emit_insn (gen_movdi (operands[0], tem));
2517 }
2518 else
2519 {
2520 rtx hi = simplify_subreg (SImode, operands[1], DFmode, 0);
2521 rtx lo = simplify_subreg (SImode, operands[1], DFmode, 4);
2522 rtx high_part = gen_highpart (SImode, operands[0]);
2523 rtx low_part = gen_lowpart (SImode, operands[0]);
2524
2525 gcc_assert (GET_CODE (hi) == CONST_INT);
2526 gcc_assert (GET_CODE (lo) == CONST_INT);
2527
2528 emit_move_insn_1 (high_part, hi);
2529
2530 /* Slick... but this loses if the constant can be done in one insn. */
2531 if (lo == hi
2532 && !SPARC_SETHI32_P (INTVAL (hi))
2533 && !SPARC_SIMM13_P (INTVAL (hi)))
2534 emit_move_insn_1 (low_part, high_part);
2535 else
2536 emit_move_insn_1 (low_part, lo);
2537 }
2538 DONE;
2539 })
2540
2541 ;; Ok, now the splits to handle all the multi insn and
2542 ;; mis-aligned memory address cases.
2543 ;; In these splits please take note that we must be
2544 ;; careful when V9 but not ARCH64 because the integer
2545 ;; register DFmode cases must be handled.
2546 (define_split
2547 [(set (match_operand:DF 0 "register_operand" "")
2548 (match_operand:DF 1 "const_zero_operand" ""))]
2549 "reload_completed
2550 && TARGET_ARCH32
2551 && ((GET_CODE (operands[0]) == REG
2552 && SPARC_INT_REG_P (REGNO (operands[0])))
2553 || (GET_CODE (operands[0]) == SUBREG
2554 && GET_CODE (SUBREG_REG (operands[0])) == REG
2555 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2556 [(clobber (const_int 0))]
2557 {
2558 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), CONST0_RTX (SFmode));
2559 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), CONST0_RTX (SFmode));
2560 DONE;
2561 })
2562
2563 (define_split
2564 [(set (match_operand:DF 0 "register_operand" "")
2565 (match_operand:DF 1 "register_operand" ""))]
2566 "reload_completed
2567 && (!TARGET_V9
2568 || (TARGET_ARCH32
2569 && sparc_split_reg_reg_legitimate (operands[0], operands[1])))"
2570 [(clobber (const_int 0))]
2571 {
2572 sparc_split_reg_reg (operands[0], operands[1], SFmode);
2573 DONE;
2574 })
2575
2576 (define_split
2577 [(set (match_operand:DF 0 "register_operand" "")
2578 (match_operand:DF 1 "memory_operand" ""))]
2579 "reload_completed
2580 && TARGET_ARCH32
2581 && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
2582 [(clobber (const_int 0))]
2583 {
2584 sparc_split_reg_mem (operands[0], operands[1], SFmode);
2585 DONE;
2586 })
2587
2588 (define_split
2589 [(set (match_operand:DF 0 "memory_operand" "")
2590 (match_operand:DF 1 "register_operand" ""))]
2591 "reload_completed
2592 && TARGET_ARCH32
2593 && sparc_split_reg_mem_legitimate (operands[1], operands[0])"
2594 [(clobber (const_int 0))]
2595 {
2596 sparc_split_mem_reg (operands[0], operands[1], SFmode);
2597 DONE;
2598 })
2599
2600 (define_split
2601 [(set (match_operand:DF 0 "memory_operand" "")
2602 (match_operand:DF 1 "const_zero_operand" ""))]
2603 "reload_completed
2604 && (!TARGET_V9
2605 || (TARGET_ARCH32
2606 && !mem_min_alignment (operands[0], 8)))
2607 && offsettable_memref_p (operands[0])"
2608 [(clobber (const_int 0))]
2609 {
2610 emit_move_insn_1 (adjust_address (operands[0], SFmode, 0), CONST0_RTX (SFmode));
2611 emit_move_insn_1 (adjust_address (operands[0], SFmode, 4), CONST0_RTX (SFmode));
2612 DONE;
2613 })
2614
2615 (define_expand "movtf"
2616 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2617 (match_operand:TF 1 "general_operand" ""))]
2618 ""
2619 {
2620 if (sparc_expand_move (TFmode, operands))
2621 DONE;
2622 })
2623
2624 (define_insn "*movtf_insn_sp32"
2625 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r")
2626 (match_operand:TF 1 "input_operand" " G,oe,e,rG,roG"))]
2627 "TARGET_ARCH32
2628 && (register_operand (operands[0], TFmode)
2629 || register_or_zero_operand (operands[1], TFmode))"
2630 "#"
2631 [(set_attr "length" "4,4,4,4,4")
2632 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2633
2634 (define_insn "*movtf_insn_sp64"
2635 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r")
2636 (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))]
2637 "TARGET_ARCH64
2638 && !TARGET_HARD_QUAD
2639 && (register_operand (operands[0], TFmode)
2640 || register_or_zero_operand (operands[1], TFmode))"
2641 "#"
2642 [(set_attr "length" "2,2,2,2,2")
2643 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2644
2645 (define_insn "*movtf_insn_sp64_hq"
2646 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r")
2647 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2648 "TARGET_ARCH64
2649 && TARGET_HARD_QUAD
2650 && (register_operand (operands[0], TFmode)
2651 || register_or_zero_operand (operands[1], TFmode))"
2652 "@
2653 #
2654 fmovq\t%1, %0
2655 ldq\t%1, %0
2656 stq\t%1, %0
2657 #
2658 #"
2659 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2660 (set_attr "length" "2,*,*,*,2,2")])
2661
2662 ;; Now all the splits to handle multi-insn TF mode moves.
2663 (define_split
2664 [(set (match_operand:TF 0 "register_operand" "")
2665 (match_operand:TF 1 "register_operand" ""))]
2666 "reload_completed
2667 && (TARGET_ARCH32
2668 || (TARGET_FPU
2669 && !TARGET_HARD_QUAD)
2670 || (!fp_register_operand (operands[0], TFmode)
2671 && !fp_register_operand (operands[1], TFmode)))"
2672 [(clobber (const_int 0))]
2673 {
2674 rtx set_dest = operands[0];
2675 rtx set_src = operands[1];
2676 rtx dest1, dest2;
2677 rtx src1, src2;
2678
2679 dest1 = gen_df_reg (set_dest, 0);
2680 dest2 = gen_df_reg (set_dest, 1);
2681 src1 = gen_df_reg (set_src, 0);
2682 src2 = gen_df_reg (set_src, 1);
2683
2684 /* Now emit using the real source and destination we found, swapping
2685 the order if we detect overlap. */
2686 if (reg_overlap_mentioned_p (dest1, src2))
2687 {
2688 emit_insn (gen_movdf (dest2, src2));
2689 emit_insn (gen_movdf (dest1, src1));
2690 }
2691 else
2692 {
2693 emit_insn (gen_movdf (dest1, src1));
2694 emit_insn (gen_movdf (dest2, src2));
2695 }
2696 DONE;
2697 })
2698
2699 (define_split
2700 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2701 (match_operand:TF 1 "const_zero_operand" ""))]
2702 "reload_completed"
2703 [(clobber (const_int 0))]
2704 {
2705 rtx set_dest = operands[0];
2706 rtx dest1, dest2;
2707
2708 switch (GET_CODE (set_dest))
2709 {
2710 case REG:
2711 dest1 = gen_df_reg (set_dest, 0);
2712 dest2 = gen_df_reg (set_dest, 1);
2713 break;
2714 case MEM:
2715 dest1 = adjust_address (set_dest, DFmode, 0);
2716 dest2 = adjust_address (set_dest, DFmode, 8);
2717 break;
2718 default:
2719 gcc_unreachable ();
2720 }
2721
2722 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2723 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2724 DONE;
2725 })
2726
2727 (define_split
2728 [(set (match_operand:TF 0 "register_operand" "")
2729 (match_operand:TF 1 "memory_operand" ""))]
2730 "(reload_completed
2731 && offsettable_memref_p (operands[1])
2732 && (TARGET_ARCH32
2733 || !TARGET_HARD_QUAD
2734 || !fp_register_operand (operands[0], TFmode)))"
2735 [(clobber (const_int 0))]
2736 {
2737 rtx word0 = adjust_address (operands[1], DFmode, 0);
2738 rtx word1 = adjust_address (operands[1], DFmode, 8);
2739 rtx set_dest, dest1, dest2;
2740
2741 set_dest = operands[0];
2742
2743 dest1 = gen_df_reg (set_dest, 0);
2744 dest2 = gen_df_reg (set_dest, 1);
2745
2746 /* Now output, ordering such that we don't clobber any registers
2747 mentioned in the address. */
2748 if (reg_overlap_mentioned_p (dest1, word1))
2749
2750 {
2751 emit_insn (gen_movdf (dest2, word1));
2752 emit_insn (gen_movdf (dest1, word0));
2753 }
2754 else
2755 {
2756 emit_insn (gen_movdf (dest1, word0));
2757 emit_insn (gen_movdf (dest2, word1));
2758 }
2759 DONE;
2760 })
2761
2762 (define_split
2763 [(set (match_operand:TF 0 "memory_operand" "")
2764 (match_operand:TF 1 "register_operand" ""))]
2765 "(reload_completed
2766 && offsettable_memref_p (operands[0])
2767 && (TARGET_ARCH32
2768 || !TARGET_HARD_QUAD
2769 || !fp_register_operand (operands[1], TFmode)))"
2770 [(clobber (const_int 0))]
2771 {
2772 rtx set_src = operands[1];
2773
2774 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2775 gen_df_reg (set_src, 0)));
2776 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2777 gen_df_reg (set_src, 1)));
2778 DONE;
2779 })
2780
2781
2782 ;; SPARC-V9 conditional move instructions
2783
2784 ;; We can handle larger constants here for some flavors, but for now we keep
2785 ;; it simple and only allow those constants supported by all flavors.
2786 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2787 ;; 3 contains the constant if one is present, but we handle either for
2788 ;; generality (sparc.c puts a constant in operand 2).
2789 ;;
2790 ;; Our instruction patterns, on the other hand, canonicalize such that
2791 ;; operand 3 must be the set destination.
2792
2793 (define_expand "mov<I:mode>cc"
2794 [(set (match_operand:I 0 "register_operand" "")
2795 (if_then_else:I (match_operand 1 "comparison_operator" "")
2796 (match_operand:I 2 "arith10_operand" "")
2797 (match_operand:I 3 "arith10_operand" "")))]
2798 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2799 {
2800 if (!sparc_expand_conditional_move (<I:MODE>mode, operands))
2801 FAIL;
2802 DONE;
2803 })
2804
2805 (define_expand "mov<F:mode>cc"
2806 [(set (match_operand:F 0 "register_operand" "")
2807 (if_then_else:F (match_operand 1 "comparison_operator" "")
2808 (match_operand:F 2 "register_operand" "")
2809 (match_operand:F 3 "register_operand" "")))]
2810 "TARGET_V9 && TARGET_FPU"
2811 {
2812 if (!sparc_expand_conditional_move (<F:MODE>mode, operands))
2813 FAIL;
2814 DONE;
2815 })
2816
2817 (define_insn "*mov<I:mode>_cc_v9"
2818 [(set (match_operand:I 0 "register_operand" "=r")
2819 (if_then_else:I (match_operator 1 "icc_or_fcc_comparison_operator"
2820 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2821 (const_int 0)])
2822 (match_operand:I 3 "arith11_operand" "rL")
2823 (match_operand:I 4 "register_operand" "0")))]
2824 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2825 "mov%C1\t%x2, %3, %0"
2826 [(set_attr "type" "cmove")])
2827
2828 (define_insn "*mov<I:mode>_cc_reg_sp64"
2829 [(set (match_operand:I 0 "register_operand" "=r")
2830 (if_then_else:I (match_operator 1 "v9_register_comparison_operator"
2831 [(match_operand:DI 2 "register_operand" "r")
2832 (const_int 0)])
2833 (match_operand:I 3 "arith10_operand" "rM")
2834 (match_operand:I 4 "register_operand" "0")))]
2835 "TARGET_ARCH64"
2836 "movr%D1\t%2, %r3, %0"
2837 [(set_attr "type" "cmove")])
2838
2839 (define_insn "*movsf_cc_v9"
2840 [(set (match_operand:SF 0 "register_operand" "=f")
2841 (if_then_else:SF (match_operator 1 "icc_or_fcc_comparison_operator"
2842 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2843 (const_int 0)])
2844 (match_operand:SF 3 "register_operand" "f")
2845 (match_operand:SF 4 "register_operand" "0")))]
2846 "TARGET_V9 && TARGET_FPU"
2847 "fmovs%C1\t%x2, %3, %0"
2848 [(set_attr "type" "fpcmove")])
2849
2850 (define_insn "*movsf_cc_reg_sp64"
2851 [(set (match_operand:SF 0 "register_operand" "=f")
2852 (if_then_else:SF (match_operator 1 "v9_register_comparison_operator"
2853 [(match_operand:DI 2 "register_operand" "r")
2854 (const_int 0)])
2855 (match_operand:SF 3 "register_operand" "f")
2856 (match_operand:SF 4 "register_operand" "0")))]
2857 "TARGET_ARCH64 && TARGET_FPU"
2858 "fmovrs%D1\t%2, %3, %0"
2859 [(set_attr "type" "fpcrmove")])
2860
2861 ;; Named because invoked by movtf_cc_v9
2862 (define_insn "movdf_cc_v9"
2863 [(set (match_operand:DF 0 "register_operand" "=e")
2864 (if_then_else:DF (match_operator 1 "icc_or_fcc_comparison_operator"
2865 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2866 (const_int 0)])
2867 (match_operand:DF 3 "register_operand" "e")
2868 (match_operand:DF 4 "register_operand" "0")))]
2869 "TARGET_V9 && TARGET_FPU"
2870 "fmovd%C1\t%x2, %3, %0"
2871 [(set_attr "type" "fpcmove")
2872 (set_attr "fptype" "double")])
2873
2874 ;; Named because invoked by movtf_cc_reg_sp64
2875 (define_insn "movdf_cc_reg_sp64"
2876 [(set (match_operand:DF 0 "register_operand" "=e")
2877 (if_then_else:DF (match_operator 1 "v9_register_comparison_operator"
2878 [(match_operand:DI 2 "register_operand" "r")
2879 (const_int 0)])
2880 (match_operand:DF 3 "register_operand" "e")
2881 (match_operand:DF 4 "register_operand" "0")))]
2882 "TARGET_ARCH64 && TARGET_FPU"
2883 "fmovrd%D1\t%2, %3, %0"
2884 [(set_attr "type" "fpcrmove")
2885 (set_attr "fptype" "double")])
2886
2887 (define_insn "*movtf_cc_hq_v9"
2888 [(set (match_operand:TF 0 "register_operand" "=e")
2889 (if_then_else:TF (match_operator 1 "icc_or_fcc_comparison_operator"
2890 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2891 (const_int 0)])
2892 (match_operand:TF 3 "register_operand" "e")
2893 (match_operand:TF 4 "register_operand" "0")))]
2894 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2895 "fmovq%C1\t%x2, %3, %0"
2896 [(set_attr "type" "fpcmove")])
2897
2898 (define_insn "*movtf_cc_reg_hq_sp64"
2899 [(set (match_operand:TF 0 "register_operand" "=e")
2900 (if_then_else:TF (match_operator 1 "v9_register_comparison_operator"
2901 [(match_operand:DI 2 "register_operand" "r")
2902 (const_int 0)])
2903 (match_operand:TF 3 "register_operand" "e")
2904 (match_operand:TF 4 "register_operand" "0")))]
2905 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2906 "fmovrq%D1\t%2, %3, %0"
2907 [(set_attr "type" "fpcrmove")])
2908
2909 (define_insn_and_split "*movtf_cc_v9"
2910 [(set (match_operand:TF 0 "register_operand" "=e")
2911 (if_then_else:TF (match_operator 1 "icc_or_fcc_comparison_operator"
2912 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2913 (const_int 0)])
2914 (match_operand:TF 3 "register_operand" "e")
2915 (match_operand:TF 4 "register_operand" "0")))]
2916 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2917 "#"
2918 "&& reload_completed"
2919 [(clobber (const_int 0))]
2920 {
2921 rtx set_dest = operands[0];
2922 rtx set_srca = operands[3];
2923 rtx dest1, dest2;
2924 rtx srca1, srca2;
2925
2926 dest1 = gen_df_reg (set_dest, 0);
2927 dest2 = gen_df_reg (set_dest, 1);
2928 srca1 = gen_df_reg (set_srca, 0);
2929 srca2 = gen_df_reg (set_srca, 1);
2930
2931 if (reg_overlap_mentioned_p (dest1, srca2))
2932 {
2933 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2],
2934 srca2, dest2));
2935 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2],
2936 srca1, dest1));
2937 }
2938 else
2939 {
2940 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2],
2941 srca1, dest1));
2942 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2],
2943 srca2, dest2));
2944 }
2945 DONE;
2946 }
2947 [(set_attr "length" "2")])
2948
2949 (define_insn_and_split "*movtf_cc_reg_sp64"
2950 [(set (match_operand:TF 0 "register_operand" "=e")
2951 (if_then_else:TF (match_operator 1 "v9_register_comparison_operator"
2952 [(match_operand:DI 2 "register_operand" "r")
2953 (const_int 0)])
2954 (match_operand:TF 3 "register_operand" "e")
2955 (match_operand:TF 4 "register_operand" "0")))]
2956 "TARGET_ARCH64 && TARGET_FPU && !TARGET_HARD_QUAD"
2957 "#"
2958 "&& reload_completed"
2959 [(clobber (const_int 0))]
2960 {
2961 rtx set_dest = operands[0];
2962 rtx set_srca = operands[3];
2963 rtx dest1, dest2;
2964 rtx srca1, srca2;
2965
2966 dest1 = gen_df_reg (set_dest, 0);
2967 dest2 = gen_df_reg (set_dest, 1);
2968 srca1 = gen_df_reg (set_srca, 0);
2969 srca2 = gen_df_reg (set_srca, 1);
2970
2971 if (reg_overlap_mentioned_p (dest1, srca2))
2972 {
2973 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2],
2974 srca2, dest2));
2975 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2],
2976 srca1, dest1));
2977 }
2978 else
2979 {
2980 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2],
2981 srca1, dest1));
2982 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2],
2983 srca2, dest2));
2984 }
2985 DONE;
2986 }
2987 [(set_attr "length" "2")])
2988
2989
2990 ;; Zero-extension instructions
2991
2992 ;; These patterns originally accepted general_operands, however, slightly
2993 ;; better code is generated by only accepting register_operands, and then
2994 ;; letting combine generate the ldu[hb] insns.
2995
2996 (define_expand "zero_extendhisi2"
2997 [(set (match_operand:SI 0 "register_operand" "")
2998 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2999 ""
3000 {
3001 rtx temp = gen_reg_rtx (SImode);
3002 rtx shift_16 = GEN_INT (16);
3003 int op1_subbyte = 0;
3004
3005 if (GET_CODE (operand1) == SUBREG)
3006 {
3007 op1_subbyte = SUBREG_BYTE (operand1);
3008 op1_subbyte /= GET_MODE_SIZE (SImode);
3009 op1_subbyte *= GET_MODE_SIZE (SImode);
3010 operand1 = XEXP (operand1, 0);
3011 }
3012
3013 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3014 shift_16));
3015 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3016 DONE;
3017 })
3018
3019 (define_insn "*zero_extendhisi2_insn"
3020 [(set (match_operand:SI 0 "register_operand" "=r")
3021 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3022 ""
3023 "lduh\t%1, %0"
3024 [(set_attr "type" "load")
3025 (set_attr "subtype" "regular")
3026 (set_attr "us3load_type" "3cycle")])
3027
3028 (define_expand "zero_extendqihi2"
3029 [(set (match_operand:HI 0 "register_operand" "")
3030 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3031 ""
3032 "")
3033
3034 (define_insn "*zero_extendqihi2_insn"
3035 [(set (match_operand:HI 0 "register_operand" "=r,r")
3036 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3037 "GET_CODE (operands[1]) != CONST_INT"
3038 "@
3039 and\t%1, 0xff, %0
3040 ldub\t%1, %0"
3041 [(set_attr "type" "*,load")
3042 (set_attr "subtype" "*,regular")
3043 (set_attr "us3load_type" "*,3cycle")])
3044
3045 (define_expand "zero_extendqisi2"
3046 [(set (match_operand:SI 0 "register_operand" "")
3047 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3048 ""
3049 "")
3050
3051 (define_insn "*zero_extendqisi2_insn"
3052 [(set (match_operand:SI 0 "register_operand" "=r,r")
3053 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3054 "GET_CODE (operands[1]) != CONST_INT"
3055 "@
3056 and\t%1, 0xff, %0
3057 ldub\t%1, %0"
3058 [(set_attr "type" "*,load")
3059 (set_attr "subtype" "*,regular")
3060 (set_attr "us3load_type" "*,3cycle")])
3061
3062 (define_expand "zero_extendqidi2"
3063 [(set (match_operand:DI 0 "register_operand" "")
3064 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3065 "TARGET_ARCH64"
3066 "")
3067
3068 (define_insn "*zero_extendqidi2_insn"
3069 [(set (match_operand:DI 0 "register_operand" "=r,r")
3070 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3071 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3072 "@
3073 and\t%1, 0xff, %0
3074 ldub\t%1, %0"
3075 [(set_attr "type" "*,load")
3076 (set_attr "subtype" "*,regular")
3077 (set_attr "us3load_type" "*,3cycle")])
3078
3079 (define_expand "zero_extendhidi2"
3080 [(set (match_operand:DI 0 "register_operand" "")
3081 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3082 "TARGET_ARCH64"
3083 {
3084 rtx temp = gen_reg_rtx (DImode);
3085 rtx shift_48 = GEN_INT (48);
3086 int op1_subbyte = 0;
3087
3088 if (GET_CODE (operand1) == SUBREG)
3089 {
3090 op1_subbyte = SUBREG_BYTE (operand1);
3091 op1_subbyte /= GET_MODE_SIZE (DImode);
3092 op1_subbyte *= GET_MODE_SIZE (DImode);
3093 operand1 = XEXP (operand1, 0);
3094 }
3095
3096 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3097 shift_48));
3098 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3099 DONE;
3100 })
3101
3102 (define_insn "*zero_extendhidi2_insn"
3103 [(set (match_operand:DI 0 "register_operand" "=r")
3104 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3105 "TARGET_ARCH64"
3106 "lduh\t%1, %0"
3107 [(set_attr "type" "load")
3108 (set_attr "subtype" "regular")
3109 (set_attr "us3load_type" "3cycle")])
3110
3111 ;; ??? Write truncdisi pattern using sra?
3112
3113 (define_expand "zero_extendsidi2"
3114 [(set (match_operand:DI 0 "register_operand" "")
3115 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3116 ""
3117 "")
3118
3119 (define_insn "*zero_extendsidi2_insn_sp64"
3120 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3121 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3122 "TARGET_ARCH64
3123 && GET_CODE (operands[1]) != CONST_INT"
3124 "@
3125 srl\t%1, 0, %0
3126 lduw\t%1, %0
3127 movstouw\t%1, %0"
3128 [(set_attr "type" "shift,load,vismv")
3129 (set_attr "subtype" "*,regular,movstouw")
3130 (set_attr "cpu_feature" "*,*,vis3")])
3131
3132 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3133 [(set (match_operand:DI 0 "register_operand" "=r")
3134 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3135 "TARGET_ARCH32"
3136 "#"
3137 "&& reload_completed"
3138 [(set (match_dup 2) (match_dup 1))
3139 (set (match_dup 3) (const_int 0))]
3140 "operands[2] = gen_lowpart (SImode, operands[0]);
3141 operands[3] = gen_highpart (SImode, operands[0]);"
3142 [(set_attr "length" "2")])
3143
3144 ;; Simplify comparisons of extended values.
3145
3146 (define_insn "*cmp_zero_extendqisi2"
3147 [(set (reg:CC CC_REG)
3148 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3149 (const_int 0)))]
3150 ""
3151 "andcc\t%0, 0xff, %%g0"
3152 [(set_attr "type" "compare")])
3153
3154 (define_insn "*cmp_zero_qi"
3155 [(set (reg:CC CC_REG)
3156 (compare:CC (match_operand:QI 0 "register_operand" "r")
3157 (const_int 0)))]
3158 ""
3159 "andcc\t%0, 0xff, %%g0"
3160 [(set_attr "type" "compare")])
3161
3162 (define_insn "*cmp_zero_extendqisi2_set"
3163 [(set (reg:CC CC_REG)
3164 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3165 (const_int 0)))
3166 (set (match_operand:SI 0 "register_operand" "=r")
3167 (zero_extend:SI (match_dup 1)))]
3168 ""
3169 "andcc\t%1, 0xff, %0"
3170 [(set_attr "type" "compare")])
3171
3172 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3173 [(set (reg:CC CC_REG)
3174 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3175 (const_int 255))
3176 (const_int 0)))
3177 (set (match_operand:SI 0 "register_operand" "=r")
3178 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3179 ""
3180 "andcc\t%1, 0xff, %0"
3181 [(set_attr "type" "compare")])
3182
3183 (define_insn "*cmp_zero_extendqidi2"
3184 [(set (reg:CCX CC_REG)
3185 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3186 (const_int 0)))]
3187 "TARGET_ARCH64"
3188 "andcc\t%0, 0xff, %%g0"
3189 [(set_attr "type" "compare")])
3190
3191 (define_insn "*cmp_zero_qi_sp64"
3192 [(set (reg:CCX CC_REG)
3193 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3194 (const_int 0)))]
3195 "TARGET_ARCH64"
3196 "andcc\t%0, 0xff, %%g0"
3197 [(set_attr "type" "compare")])
3198
3199 (define_insn "*cmp_zero_extendqidi2_set"
3200 [(set (reg:CCX CC_REG)
3201 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3202 (const_int 0)))
3203 (set (match_operand:DI 0 "register_operand" "=r")
3204 (zero_extend:DI (match_dup 1)))]
3205 "TARGET_ARCH64"
3206 "andcc\t%1, 0xff, %0"
3207 [(set_attr "type" "compare")])
3208
3209 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3210 [(set (reg:CCX CC_REG)
3211 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3212 (const_int 255))
3213 (const_int 0)))
3214 (set (match_operand:DI 0 "register_operand" "=r")
3215 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3216 "TARGET_ARCH64"
3217 "andcc\t%1, 0xff, %0"
3218 [(set_attr "type" "compare")])
3219
3220 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3221
3222 (define_insn "*cmp_siqi_trunc"
3223 [(set (reg:CC CC_REG)
3224 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3225 (const_int 0)))]
3226 ""
3227 "andcc\t%0, 0xff, %%g0"
3228 [(set_attr "type" "compare")])
3229
3230 (define_insn "*cmp_siqi_trunc_set"
3231 [(set (reg:CC CC_REG)
3232 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3233 (const_int 0)))
3234 (set (match_operand:QI 0 "register_operand" "=r")
3235 (subreg:QI (match_dup 1) 3))]
3236 ""
3237 "andcc\t%1, 0xff, %0"
3238 [(set_attr "type" "compare")])
3239
3240 (define_insn "*cmp_diqi_trunc"
3241 [(set (reg:CC CC_REG)
3242 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3243 (const_int 0)))]
3244 "TARGET_ARCH64"
3245 "andcc\t%0, 0xff, %%g0"
3246 [(set_attr "type" "compare")])
3247
3248 (define_insn "*cmp_diqi_trunc_set"
3249 [(set (reg:CC CC_REG)
3250 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3251 (const_int 0)))
3252 (set (match_operand:QI 0 "register_operand" "=r")
3253 (subreg:QI (match_dup 1) 7))]
3254 "TARGET_ARCH64"
3255 "andcc\t%1, 0xff, %0"
3256 [(set_attr "type" "compare")])
3257 \f
3258
3259 ;; Sign-extension instructions
3260
3261 ;; These patterns originally accepted general_operands, however, slightly
3262 ;; better code is generated by only accepting register_operands, and then
3263 ;; letting combine generate the lds[hb] insns.
3264
3265 (define_expand "extendhisi2"
3266 [(set (match_operand:SI 0 "register_operand" "")
3267 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3268 ""
3269 {
3270 rtx temp = gen_reg_rtx (SImode);
3271 rtx shift_16 = GEN_INT (16);
3272 int op1_subbyte = 0;
3273
3274 if (GET_CODE (operand1) == SUBREG)
3275 {
3276 op1_subbyte = SUBREG_BYTE (operand1);
3277 op1_subbyte /= GET_MODE_SIZE (SImode);
3278 op1_subbyte *= GET_MODE_SIZE (SImode);
3279 operand1 = XEXP (operand1, 0);
3280 }
3281
3282 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3283 shift_16));
3284 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3285 DONE;
3286 })
3287
3288 (define_insn "*sign_extendhisi2_insn"
3289 [(set (match_operand:SI 0 "register_operand" "=r")
3290 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3291 ""
3292 "ldsh\t%1, %0"
3293 [(set_attr "type" "sload")
3294 (set_attr "us3load_type" "3cycle")])
3295
3296 (define_expand "extendqihi2"
3297 [(set (match_operand:HI 0 "register_operand" "")
3298 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3299 ""
3300 {
3301 rtx temp = gen_reg_rtx (SImode);
3302 rtx shift_24 = GEN_INT (24);
3303 int op1_subbyte = 0;
3304 int op0_subbyte = 0;
3305
3306 if (GET_CODE (operand1) == SUBREG)
3307 {
3308 op1_subbyte = SUBREG_BYTE (operand1);
3309 op1_subbyte /= GET_MODE_SIZE (SImode);
3310 op1_subbyte *= GET_MODE_SIZE (SImode);
3311 operand1 = XEXP (operand1, 0);
3312 }
3313 if (GET_CODE (operand0) == SUBREG)
3314 {
3315 op0_subbyte = SUBREG_BYTE (operand0);
3316 op0_subbyte /= GET_MODE_SIZE (SImode);
3317 op0_subbyte *= GET_MODE_SIZE (SImode);
3318 operand0 = XEXP (operand0, 0);
3319 }
3320 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3321 shift_24));
3322 if (GET_MODE (operand0) != SImode)
3323 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3324 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3325 DONE;
3326 })
3327
3328 (define_insn "*sign_extendqihi2_insn"
3329 [(set (match_operand:HI 0 "register_operand" "=r")
3330 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3331 ""
3332 "ldsb\t%1, %0"
3333 [(set_attr "type" "sload")
3334 (set_attr "us3load_type" "3cycle")])
3335
3336 (define_expand "extendqisi2"
3337 [(set (match_operand:SI 0 "register_operand" "")
3338 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3339 ""
3340 {
3341 rtx temp = gen_reg_rtx (SImode);
3342 rtx shift_24 = GEN_INT (24);
3343 int op1_subbyte = 0;
3344
3345 if (GET_CODE (operand1) == SUBREG)
3346 {
3347 op1_subbyte = SUBREG_BYTE (operand1);
3348 op1_subbyte /= GET_MODE_SIZE (SImode);
3349 op1_subbyte *= GET_MODE_SIZE (SImode);
3350 operand1 = XEXP (operand1, 0);
3351 }
3352
3353 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3354 shift_24));
3355 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3356 DONE;
3357 })
3358
3359 (define_insn "*sign_extendqisi2_insn"
3360 [(set (match_operand:SI 0 "register_operand" "=r")
3361 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3362 ""
3363 "ldsb\t%1, %0"
3364 [(set_attr "type" "sload")
3365 (set_attr "us3load_type" "3cycle")])
3366
3367 (define_expand "extendqidi2"
3368 [(set (match_operand:DI 0 "register_operand" "")
3369 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3370 "TARGET_ARCH64"
3371 {
3372 rtx temp = gen_reg_rtx (DImode);
3373 rtx shift_56 = GEN_INT (56);
3374 int op1_subbyte = 0;
3375
3376 if (GET_CODE (operand1) == SUBREG)
3377 {
3378 op1_subbyte = SUBREG_BYTE (operand1);
3379 op1_subbyte /= GET_MODE_SIZE (DImode);
3380 op1_subbyte *= GET_MODE_SIZE (DImode);
3381 operand1 = XEXP (operand1, 0);
3382 }
3383
3384 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3385 shift_56));
3386 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3387 DONE;
3388 })
3389
3390 (define_insn "*sign_extendqidi2_insn"
3391 [(set (match_operand:DI 0 "register_operand" "=r")
3392 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3393 "TARGET_ARCH64"
3394 "ldsb\t%1, %0"
3395 [(set_attr "type" "sload")
3396 (set_attr "us3load_type" "3cycle")])
3397
3398 (define_expand "extendhidi2"
3399 [(set (match_operand:DI 0 "register_operand" "")
3400 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3401 "TARGET_ARCH64"
3402 {
3403 rtx temp = gen_reg_rtx (DImode);
3404 rtx shift_48 = GEN_INT (48);
3405 int op1_subbyte = 0;
3406
3407 if (GET_CODE (operand1) == SUBREG)
3408 {
3409 op1_subbyte = SUBREG_BYTE (operand1);
3410 op1_subbyte /= GET_MODE_SIZE (DImode);
3411 op1_subbyte *= GET_MODE_SIZE (DImode);
3412 operand1 = XEXP (operand1, 0);
3413 }
3414
3415 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3416 shift_48));
3417 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3418 DONE;
3419 })
3420
3421 (define_insn "*sign_extendhidi2_insn"
3422 [(set (match_operand:DI 0 "register_operand" "=r")
3423 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3424 "TARGET_ARCH64"
3425 "ldsh\t%1, %0"
3426 [(set_attr "type" "sload")
3427 (set_attr "us3load_type" "3cycle")])
3428
3429 (define_expand "extendsidi2"
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3432 "TARGET_ARCH64"
3433 "")
3434
3435 (define_insn "*sign_extendsidi2_insn"
3436 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3437 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3438 "TARGET_ARCH64"
3439 "@
3440 sra\t%1, 0, %0
3441 ldsw\t%1, %0
3442 movstosw\t%1, %0"
3443 [(set_attr "type" "shift,sload,vismv")
3444 (set_attr "us3load_type" "*,3cycle,*")
3445 (set_attr "cpu_feature" "*,*,vis3")])
3446
3447
3448 ;; Special pattern for optimizing bit-field compares. This is needed
3449 ;; because combine uses this as a canonical form.
3450
3451 (define_insn "*cmp_zero_extract"
3452 [(set (reg:CC CC_REG)
3453 (compare:CC
3454 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3455 (match_operand:SI 1 "small_int_operand" "I")
3456 (match_operand:SI 2 "small_int_operand" "I"))
3457 (const_int 0)))]
3458 "INTVAL (operands[2]) > 19"
3459 {
3460 int len = INTVAL (operands[1]);
3461 int pos = 32 - INTVAL (operands[2]) - len;
3462 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3463 operands[1] = GEN_INT (mask);
3464 return "andcc\t%0, %1, %%g0";
3465 }
3466 [(set_attr "type" "compare")])
3467
3468 (define_insn "*cmp_zero_extract_sp64"
3469 [(set (reg:CCX CC_REG)
3470 (compare:CCX
3471 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3472 (match_operand:SI 1 "small_int_operand" "I")
3473 (match_operand:SI 2 "small_int_operand" "I"))
3474 (const_int 0)))]
3475 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3476 {
3477 int len = INTVAL (operands[1]);
3478 int pos = 64 - INTVAL (operands[2]) - len;
3479 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3480 operands[1] = GEN_INT (mask);
3481 return "andcc\t%0, %1, %%g0";
3482 }
3483 [(set_attr "type" "compare")])
3484
3485
3486 ;; Conversions between float, double and long double.
3487
3488 (define_insn "extendsfdf2"
3489 [(set (match_operand:DF 0 "register_operand" "=e")
3490 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3491 "TARGET_FPU"
3492 "fstod\t%1, %0"
3493 [(set_attr "type" "fp")
3494 (set_attr "fptype" "double")])
3495
3496 (define_expand "extendsftf2"
3497 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3498 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3499 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3500 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3501
3502 (define_insn "*extendsftf2_hq"
3503 [(set (match_operand:TF 0 "register_operand" "=e")
3504 (float_extend:TF (match_operand:SF 1 "register_operand" "f")))]
3505 "TARGET_FPU && TARGET_HARD_QUAD"
3506 "fstoq\t%1, %0"
3507 [(set_attr "type" "fp")])
3508
3509 (define_expand "extenddftf2"
3510 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3511 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
3512 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3513 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3514
3515 (define_insn "*extenddftf2_hq"
3516 [(set (match_operand:TF 0 "register_operand" "=e")
3517 (float_extend:TF (match_operand:DF 1 "register_operand" "e")))]
3518 "TARGET_FPU && TARGET_HARD_QUAD"
3519 "fdtoq\t%1, %0"
3520 [(set_attr "type" "fp")])
3521
3522 (define_insn "truncdfsf2"
3523 [(set (match_operand:SF 0 "register_operand" "=f")
3524 (float_truncate:SF (match_operand:DF 1 "register_operand" "e")))]
3525 "TARGET_FPU"
3526 "fdtos\t%1, %0"
3527 [(set_attr "type" "fp")
3528 (set_attr "fptype" "double")
3529 (set_attr "fptype_ut699" "single")])
3530
3531 (define_expand "trunctfsf2"
3532 [(set (match_operand:SF 0 "register_operand" "")
3533 (float_truncate:SF (match_operand:TF 1 "general_operand" "")))]
3534 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3535 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3536
3537 (define_insn "*trunctfsf2_hq"
3538 [(set (match_operand:SF 0 "register_operand" "=f")
3539 (float_truncate:SF (match_operand:TF 1 "register_operand" "e")))]
3540 "TARGET_FPU && TARGET_HARD_QUAD"
3541 "fqtos\t%1, %0"
3542 [(set_attr "type" "fp")])
3543
3544 (define_expand "trunctfdf2"
3545 [(set (match_operand:DF 0 "register_operand" "")
3546 (float_truncate:DF (match_operand:TF 1 "general_operand" "")))]
3547 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3548 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3549
3550 (define_insn "*trunctfdf2_hq"
3551 [(set (match_operand:DF 0 "register_operand" "=e")
3552 (float_truncate:DF (match_operand:TF 1 "register_operand" "e")))]
3553 "TARGET_FPU && TARGET_HARD_QUAD"
3554 "fqtod\t%1, %0"
3555 [(set_attr "type" "fp")])
3556
3557
3558 ;; Conversion between fixed point and floating point.
3559
3560 (define_insn "floatsisf2"
3561 [(set (match_operand:SF 0 "register_operand" "=f")
3562 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3563 "TARGET_FPU"
3564 "fitos\t%1, %0"
3565 [(set_attr "type" "fp")
3566 (set_attr "fptype" "single")])
3567
3568 (define_insn "floatsidf2"
3569 [(set (match_operand:DF 0 "register_operand" "=e")
3570 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3571 "TARGET_FPU"
3572 "fitod\t%1, %0"
3573 [(set_attr "type" "fp")
3574 (set_attr "fptype" "double")])
3575
3576 (define_expand "floatsitf2"
3577 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3578 (float:TF (match_operand:SI 1 "register_operand" "")))]
3579 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3580 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3581
3582 (define_insn "*floatsitf2_hq"
3583 [(set (match_operand:TF 0 "register_operand" "=e")
3584 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3585 "TARGET_FPU && TARGET_HARD_QUAD"
3586 "fitoq\t%1, %0"
3587 [(set_attr "type" "fp")])
3588
3589 (define_expand "floatunssitf2"
3590 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3591 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3592 "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD"
3593 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3594
3595 ;; Now the same for 64 bit sources.
3596
3597 (define_insn "floatdisf2"
3598 [(set (match_operand:SF 0 "register_operand" "=f")
3599 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3600 "TARGET_V9 && TARGET_FPU"
3601 "fxtos\t%1, %0"
3602 [(set_attr "type" "fp")
3603 (set_attr "fptype" "double")])
3604
3605 (define_expand "floatunsdisf2"
3606 [(use (match_operand:SF 0 "register_operand" ""))
3607 (use (match_operand:DI 1 "general_operand" ""))]
3608 "TARGET_ARCH64 && TARGET_FPU"
3609 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3610
3611 (define_insn "floatdidf2"
3612 [(set (match_operand:DF 0 "register_operand" "=e")
3613 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3614 "TARGET_V9 && TARGET_FPU"
3615 "fxtod\t%1, %0"
3616 [(set_attr "type" "fp")
3617 (set_attr "fptype" "double")])
3618
3619 (define_expand "floatunsdidf2"
3620 [(use (match_operand:DF 0 "register_operand" ""))
3621 (use (match_operand:DI 1 "general_operand" ""))]
3622 "TARGET_ARCH64 && TARGET_FPU"
3623 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3624
3625 (define_expand "floatditf2"
3626 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3627 (float:TF (match_operand:DI 1 "register_operand" "")))]
3628 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3629 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3630
3631 (define_insn "*floatditf2_hq"
3632 [(set (match_operand:TF 0 "register_operand" "=e")
3633 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3634 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3635 "fxtoq\t%1, %0"
3636 [(set_attr "type" "fp")])
3637
3638 (define_expand "floatunsditf2"
3639 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3640 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3641 "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD"
3642 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3643
3644 ;; Convert a float to an actual integer.
3645 ;; Truncation is performed as part of the conversion.
3646
3647 (define_insn "fix_truncsfsi2"
3648 [(set (match_operand:SI 0 "register_operand" "=f")
3649 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3650 "TARGET_FPU"
3651 "fstoi\t%1, %0"
3652 [(set_attr "type" "fp")
3653 (set_attr "fptype" "single")])
3654
3655 (define_insn "fix_truncdfsi2"
3656 [(set (match_operand:SI 0 "register_operand" "=f")
3657 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3658 "TARGET_FPU"
3659 "fdtoi\t%1, %0"
3660 [(set_attr "type" "fp")
3661 (set_attr "fptype" "double")
3662 (set_attr "fptype_ut699" "single")])
3663
3664 (define_expand "fix_trunctfsi2"
3665 [(set (match_operand:SI 0 "register_operand" "")
3666 (fix:SI (match_operand:TF 1 "general_operand" "")))]
3667 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3668 "emit_tfmode_cvt (FIX, operands); DONE;")
3669
3670 (define_insn "*fix_trunctfsi2_hq"
3671 [(set (match_operand:SI 0 "register_operand" "=f")
3672 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3673 "TARGET_FPU && TARGET_HARD_QUAD"
3674 "fqtoi\t%1, %0"
3675 [(set_attr "type" "fp")])
3676
3677 (define_expand "fixuns_trunctfsi2"
3678 [(set (match_operand:SI 0 "register_operand" "")
3679 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3680 "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD"
3681 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3682
3683 ;; Now the same, for V9 targets
3684
3685 (define_insn "fix_truncsfdi2"
3686 [(set (match_operand:DI 0 "register_operand" "=e")
3687 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3688 "TARGET_V9 && TARGET_FPU"
3689 "fstox\t%1, %0"
3690 [(set_attr "type" "fp")
3691 (set_attr "fptype" "double")])
3692
3693 (define_expand "fixuns_truncsfdi2"
3694 [(use (match_operand:DI 0 "register_operand" ""))
3695 (use (match_operand:SF 1 "general_operand" ""))]
3696 "TARGET_ARCH64 && TARGET_FPU"
3697 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3698
3699 (define_insn "fix_truncdfdi2"
3700 [(set (match_operand:DI 0 "register_operand" "=e")
3701 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3702 "TARGET_V9 && TARGET_FPU"
3703 "fdtox\t%1, %0"
3704 [(set_attr "type" "fp")
3705 (set_attr "fptype" "double")])
3706
3707 (define_expand "fixuns_truncdfdi2"
3708 [(use (match_operand:DI 0 "register_operand" ""))
3709 (use (match_operand:DF 1 "general_operand" ""))]
3710 "TARGET_ARCH64 && TARGET_FPU"
3711 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3712
3713 (define_expand "fix_trunctfdi2"
3714 [(set (match_operand:DI 0 "register_operand" "")
3715 (fix:DI (match_operand:TF 1 "general_operand" "")))]
3716 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3717 "emit_tfmode_cvt (FIX, operands); DONE;")
3718
3719 (define_insn "*fix_trunctfdi2_hq"
3720 [(set (match_operand:DI 0 "register_operand" "=e")
3721 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3722 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3723 "fqtox\t%1, %0"
3724 [(set_attr "type" "fp")])
3725
3726 (define_expand "fixuns_trunctfdi2"
3727 [(set (match_operand:DI 0 "register_operand" "")
3728 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3729 "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD"
3730 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3731
3732
3733 ;; Integer addition/subtraction instructions.
3734
3735 (define_expand "adddi3"
3736 [(set (match_operand:DI 0 "register_operand" "")
3737 (plus:DI (match_operand:DI 1 "register_operand" "")
3738 (match_operand:DI 2 "arith_double_add_operand" "")))]
3739 ""
3740 {
3741 if (TARGET_ARCH32)
3742 {
3743 emit_insn (gen_adddi3_sp32 (operands[0], operands[1], operands[2]));
3744 DONE;
3745 }
3746 })
3747
3748 (define_expand "uaddvdi4"
3749 [(parallel [(set (reg:CCXC CC_REG)
3750 (compare:CCXC (plus:DI (match_operand:DI 1 "register_operand")
3751 (match_operand:DI 2 "arith_add_operand"))
3752 (match_dup 1)))
3753 (set (match_operand:DI 0 "register_operand")
3754 (plus:DI (match_dup 1) (match_dup 2)))])
3755 (set (pc) (if_then_else (ltu (reg:CCXC CC_REG) (const_int 0))
3756 (label_ref (match_operand 3))
3757 (pc)))]
3758 ""
3759 {
3760 if (TARGET_ARCH32)
3761 {
3762 emit_insn (gen_uaddvdi4_sp32 (operands[0], operands[1], operands[2]));
3763 rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
3764 const0_rtx);
3765 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
3766 DONE;
3767 }
3768 })
3769
3770 (define_expand "addvdi4"
3771 [(parallel [(set (reg:CCXV CC_REG)
3772 (compare:CCXV (plus:DI (match_operand:DI 1 "register_operand")
3773 (match_operand:DI 2 "arith_add_operand"))
3774 (unspec:DI [(match_dup 1) (match_dup 2)]
3775 UNSPEC_ADDV)))
3776 (set (match_operand:DI 0 "register_operand")
3777 (plus:DI (match_dup 1) (match_dup 2)))])
3778 (set (pc) (if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
3779 (label_ref (match_operand 3))
3780 (pc)))]
3781 ""
3782 {
3783 if (TARGET_ARCH32)
3784 {
3785 emit_insn (gen_addvdi4_sp32 (operands[0], operands[1], operands[2]));
3786 rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
3787 const0_rtx);
3788 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
3789 DONE;
3790 }
3791 })
3792
3793 (define_insn_and_split "adddi3_sp32"
3794 [(set (match_operand:DI 0 "register_operand" "=&r")
3795 (plus:DI (match_operand:DI 1 "register_operand" "%r")
3796 (match_operand:DI 2 "arith_double_operand" "rHI")))
3797 (clobber (reg:CC CC_REG))]
3798 "TARGET_ARCH32"
3799 "#"
3800 "&& reload_completed"
3801 [(parallel [(set (reg:CCC CC_REG)
3802 (compare:CCC (plus:SI (match_dup 4) (match_dup 5))
3803 (match_dup 4)))
3804 (set (match_dup 3)
3805 (plus:SI (match_dup 4) (match_dup 5)))])
3806 (set (match_dup 6)
3807 (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3808 (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
3809 {
3810 operands[3] = gen_lowpart (SImode, operands[0]);
3811 operands[4] = gen_lowpart (SImode, operands[1]);
3812 operands[5] = gen_lowpart (SImode, operands[2]);
3813 operands[6] = gen_highpart (SImode, operands[0]);
3814 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3815 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3816 }
3817 [(set_attr "length" "2")])
3818
3819 (define_insn_and_split "uaddvdi4_sp32"
3820 [(set (reg:CCC CC_REG)
3821 (compare:CCC (plus:DI (match_operand:DI 1 "register_operand" "%r")
3822 (match_operand:DI 2 "arith_double_operand" "rHI"))
3823 (match_dup 1)))
3824 (set (match_operand:DI 0 "register_operand" "=&r")
3825 (plus:DI (match_dup 1) (match_dup 2)))]
3826 "TARGET_ARCH32"
3827 "#"
3828 "&& reload_completed"
3829 [(parallel [(set (reg:CCC CC_REG)
3830 (compare:CCC (plus:SI (match_dup 4) (match_dup 5))
3831 (match_dup 4)))
3832 (set (match_dup 3)
3833 (plus:SI (match_dup 4) (match_dup 5)))])
3834 (parallel [(set (reg:CCC CC_REG)
3835 (compare:CCC (zero_extend:DI
3836 (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3837 (ltu:SI (reg:CCC CC_REG)
3838 (const_int 0))))
3839 (plus:DI (plus:DI (zero_extend:DI (match_dup 7))
3840 (zero_extend:DI (match_dup 8)))
3841 (ltu:DI (reg:CCC CC_REG)
3842 (const_int 0)))))
3843 (set (match_dup 6)
3844 (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3845 (ltu:SI (reg:CCC CC_REG)
3846 (const_int 0))))])]
3847 {
3848 operands[3] = gen_lowpart (SImode, operands[0]);
3849 operands[4] = gen_lowpart (SImode, operands[1]);
3850 operands[5] = gen_lowpart (SImode, operands[2]);
3851 operands[6] = gen_highpart (SImode, operands[0]);
3852 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3853 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3854 }
3855 [(set_attr "length" "2")])
3856
3857 (define_insn_and_split "addvdi4_sp32"
3858 [(set (reg:CCV CC_REG)
3859 (compare:CCV (plus:DI (match_operand:DI 1 "register_operand" "%r")
3860 (match_operand:DI 2 "arith_double_operand" "rHI"))
3861 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
3862 (set (match_operand:DI 0 "register_operand" "=&r")
3863 (plus:DI (match_dup 1) (match_dup 2)))]
3864 "TARGET_ARCH32"
3865 "#"
3866 "&& reload_completed"
3867 [(parallel [(set (reg:CCC CC_REG)
3868 (compare:CCC (plus:SI (match_dup 4) (match_dup 5))
3869 (match_dup 4)))
3870 (set (match_dup 3)
3871 (plus:SI (match_dup 4) (match_dup 5)))])
3872 (parallel [(set (reg:CCV CC_REG)
3873 (compare:CCV (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3874 (ltu:SI (reg:CCC CC_REG)
3875 (const_int 0)))
3876 (unspec:SI [(plus:SI (match_dup 7) (match_dup 8))
3877 (ltu:SI (reg:CCC CC_REG)
3878 (const_int 0))]
3879 UNSPEC_ADDV)))
3880 (set (match_dup 6)
3881 (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3882 (ltu:SI (reg:CCC CC_REG) (const_int 0))))])]
3883 {
3884 operands[3] = gen_lowpart (SImode, operands[0]);
3885 operands[4] = gen_lowpart (SImode, operands[1]);
3886 operands[5] = gen_lowpart (SImode, operands[2]);
3887 operands[6] = gen_highpart (SImode, operands[0]);
3888 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3889 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3890 }
3891 [(set_attr "length" "2")])
3892
3893 (define_insn_and_split "*addx_extend_sp32"
3894 [(set (match_operand:DI 0 "register_operand" "=r")
3895 (zero_extend:DI (plus:SI (plus:SI
3896 (match_operand:SI 1 "register_operand" "%r")
3897 (match_operand:SI 2 "arith_operand" "rI"))
3898 (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
3899 "TARGET_ARCH32"
3900 "#"
3901 "&& reload_completed"
3902 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3903 (ltu:SI (reg:CCC CC_REG) (const_int 0))))
3904 (set (match_dup 4) (const_int 0))]
3905 "operands[3] = gen_lowpart (SImode, operands[0]);
3906 operands[4] = gen_highpart (SImode, operands[0]);"
3907 [(set_attr "length" "2")])
3908
3909 (define_insn_and_split "*adddi3_extend_sp32"
3910 [(set (match_operand:DI 0 "register_operand" "=&r")
3911 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3912 (match_operand:DI 2 "register_operand" "r")))
3913 (clobber (reg:CC CC_REG))]
3914 "TARGET_ARCH32"
3915 "#"
3916 "&& reload_completed"
3917 [(parallel [(set (reg:CCC CC_REG)
3918 (compare:CCC (plus:SI (match_dup 3) (match_dup 1))
3919 (match_dup 3)))
3920 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3921 (set (match_dup 6)
3922 (plus:SI (plus:SI (match_dup 4) (const_int 0))
3923 (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
3924 "operands[3] = gen_lowpart (SImode, operands[2]);
3925 operands[4] = gen_highpart (SImode, operands[2]);
3926 operands[5] = gen_lowpart (SImode, operands[0]);
3927 operands[6] = gen_highpart (SImode, operands[0]);"
3928 [(set_attr "length" "2")])
3929
3930 (define_insn "*adddi3_sp64"
3931 [(set (match_operand:DI 0 "register_operand" "=r,r")
3932 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3933 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3934 "TARGET_ARCH64"
3935 "@
3936 add\t%1, %2, %0
3937 sub\t%1, -%2, %0")
3938
3939 (define_insn "addsi3"
3940 [(set (match_operand:SI 0 "register_operand" "=r,r")
3941 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3942 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3943 ""
3944 "@
3945 add\t%1, %2, %0
3946 sub\t%1, -%2, %0"
3947 [(set_attr "type" "*,*")
3948 (set_attr "fptype" "*,*")])
3949
3950 (define_expand "uaddvsi4"
3951 [(parallel [(set (reg:CCC CC_REG)
3952 (compare:CCC (plus:SI (match_operand:SI 1 "register_operand")
3953 (match_operand:SI 2 "arith_operand"))
3954 (match_dup 1)))
3955 (set (match_operand:SI 0 "register_operand")
3956 (plus:SI (match_dup 1) (match_dup 2)))])
3957 (set (pc) (if_then_else (ltu (reg:CCC CC_REG) (const_int 0))
3958 (label_ref (match_operand 3))
3959 (pc)))]
3960 "")
3961
3962 (define_expand "addvsi4"
3963 [(parallel [(set (reg:CCV CC_REG)
3964 (compare:CCV (plus:SI (match_operand:SI 1 "register_operand")
3965 (match_operand:SI 2 "arith_operand"))
3966 (unspec:SI [(match_dup 1) (match_dup 2)]
3967 UNSPEC_ADDV)))
3968 (set (match_operand:SI 0 "register_operand")
3969 (plus:SI (match_dup 1) (match_dup 2)))])
3970 (set (pc) (if_then_else (ne (reg:CCV CC_REG) (const_int 0))
3971 (label_ref (match_operand 3))
3972 (pc)))]
3973 "")
3974
3975 (define_insn "*cmp_ccnz_plus"
3976 [(set (reg:CCNZ CC_REG)
3977 (compare:CCNZ (plus:SI (match_operand:SI 0 "register_operand" "%r")
3978 (match_operand:SI 1 "arith_operand" "rI"))
3979 (const_int 0)))]
3980 ""
3981 "addcc\t%0, %1, %%g0"
3982 [(set_attr "type" "compare")])
3983
3984 (define_insn "*cmp_ccxnz_plus"
3985 [(set (reg:CCXNZ CC_REG)
3986 (compare:CCXNZ (plus:DI (match_operand:DI 0 "register_operand" "%r")
3987 (match_operand:DI 1 "arith_operand" "rI"))
3988 (const_int 0)))]
3989 "TARGET_ARCH64"
3990 "addcc\t%0, %1, %%g0"
3991 [(set_attr "type" "compare")])
3992
3993 (define_insn "*cmp_ccnz_plus_set"
3994 [(set (reg:CCNZ CC_REG)
3995 (compare:CCNZ (plus:SI (match_operand:SI 1 "register_operand" "%r")
3996 (match_operand:SI 2 "arith_operand" "rI"))
3997 (const_int 0)))
3998 (set (match_operand:SI 0 "register_operand" "=r")
3999 (plus:SI (match_dup 1) (match_dup 2)))]
4000 ""
4001 "addcc\t%1, %2, %0"
4002 [(set_attr "type" "compare")])
4003
4004 (define_insn "*cmp_ccxnz_plus_set"
4005 [(set (reg:CCXNZ CC_REG)
4006 (compare:CCXNZ (plus:DI (match_operand:DI 1 "register_operand" "%r")
4007 (match_operand:DI 2 "arith_operand" "rI"))
4008 (const_int 0)))
4009 (set (match_operand:DI 0 "register_operand" "=r")
4010 (plus:DI (match_dup 1) (match_dup 2)))]
4011 "TARGET_ARCH64"
4012 "addcc\t%1, %2, %0"
4013 [(set_attr "type" "compare")])
4014
4015 (define_insn "*cmp_ccc_plus"
4016 [(set (reg:CCC CC_REG)
4017 (compare:CCC (plus:SI (match_operand:SI 0 "register_operand" "%r")
4018 (match_operand:SI 1 "arith_operand" "rI"))
4019 (match_dup 0)))]
4020 ""
4021 "addcc\t%0, %1, %%g0"
4022 [(set_attr "type" "compare")])
4023
4024 (define_insn "*cmp_ccxc_plus"
4025 [(set (reg:CCXC CC_REG)
4026 (compare:CCXC (plus:DI (match_operand:DI 0 "register_operand" "%r")
4027 (match_operand:DI 1 "arith_operand" "rI"))
4028 (match_dup 0)))]
4029 "TARGET_ARCH64"
4030 "addcc\t%0, %1, %%g0"
4031 [(set_attr "type" "compare")])
4032
4033 (define_insn "*cmp_ccc_plus_set"
4034 [(set (reg:CCC CC_REG)
4035 (compare:CCC (plus:SI (match_operand:SI 1 "register_operand" "%r")
4036 (match_operand:SI 2 "arith_operand" "rI"))
4037 (match_dup 1)))
4038 (set (match_operand:SI 0 "register_operand" "=r")
4039 (plus:SI (match_dup 1) (match_dup 2)))]
4040 ""
4041 "addcc\t%1, %2, %0"
4042 [(set_attr "type" "compare")])
4043
4044 (define_insn "*cmp_ccxc_plus_set"
4045 [(set (reg:CCXC CC_REG)
4046 (compare:CCXC (plus:DI (match_operand:DI 1 "register_operand" "%r")
4047 (match_operand:DI 2 "arith_operand" "rI"))
4048 (match_dup 1)))
4049 (set (match_operand:DI 0 "register_operand" "=r")
4050 (plus:DI (match_dup 1) (match_dup 2)))]
4051 "TARGET_ARCH64"
4052 "addcc\t%1, %2, %0"
4053 [(set_attr "type" "compare")])
4054
4055 (define_insn "*cmp_ccc_plus_sltu_set"
4056 [(set (reg:CCC CC_REG)
4057 (compare:CCC (zero_extend:DI
4058 (plus:SI
4059 (plus:SI (match_operand:SI 1 "register_operand" "%r")
4060 (match_operand:SI 2 "arith_operand" "rI"))
4061 (ltu:SI (reg:CCC CC_REG) (const_int 0))))
4062 (plus:DI (plus:DI (zero_extend:DI (match_dup 1))
4063 (zero_extend:DI (match_dup 2)))
4064 (ltu:DI (reg:CCC CC_REG) (const_int 0)))))
4065 (set (match_operand:SI 0 "register_operand" "=r")
4066 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4067 (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
4068 ""
4069 "addxcc\t%1, %2, %0"
4070 [(set_attr "type" "compare")])
4071
4072 (define_insn "*cmp_ccv_plus"
4073 [(set (reg:CCV CC_REG)
4074 (compare:CCV (plus:SI (match_operand:SI 0 "register_operand" "%r")
4075 (match_operand:SI 1 "arith_operand" "rI"))
4076 (unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))]
4077 ""
4078 "addcc\t%0, %1, %%g0"
4079 [(set_attr "type" "compare")])
4080
4081 (define_insn "*cmp_ccxv_plus"
4082 [(set (reg:CCXV CC_REG)
4083 (compare:CCXV (plus:DI (match_operand:DI 0 "register_operand" "%r")
4084 (match_operand:DI 1 "arith_operand" "rI"))
4085 (unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))]
4086 "TARGET_ARCH64"
4087 "addcc\t%0, %1, %%g0"
4088 [(set_attr "type" "compare")])
4089
4090 (define_insn "*cmp_ccv_plus_set"
4091 [(set (reg:CCV CC_REG)
4092 (compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r")
4093 (match_operand:SI 2 "arith_operand" "rI"))
4094 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
4095 (set (match_operand:SI 0 "register_operand" "=r")
4096 (plus:SI (match_dup 1) (match_dup 2)))]
4097 ""
4098 "addcc\t%1, %2, %0"
4099 [(set_attr "type" "compare")])
4100
4101 (define_insn "*cmp_ccxv_plus_set"
4102 [(set (reg:CCXV CC_REG)
4103 (compare:CCXV (plus:DI (match_operand:DI 1 "register_operand" "%r")
4104 (match_operand:DI 2 "arith_operand" "rI"))
4105 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
4106 (set (match_operand:DI 0 "register_operand" "=r")
4107 (plus:DI (match_dup 1) (match_dup 2)))]
4108 "TARGET_ARCH64"
4109 "addcc\t%1, %2, %0"
4110 [(set_attr "type" "compare")])
4111
4112 (define_insn "*cmp_ccv_plus_sltu_set"
4113 [(set (reg:CCV CC_REG)
4114 (compare:CCV (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "%r")
4115 (match_operand:SI 2 "arith_operand" "rI"))
4116 (ltu:SI (reg:CCC CC_REG) (const_int 0)))
4117 (unspec:SI [(plus:SI (match_dup 1) (match_dup 2))
4118 (ltu:SI (reg:CCC CC_REG) (const_int 0))]
4119 UNSPEC_ADDV)))
4120 (set (match_operand:SI 0 "register_operand" "=r")
4121 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4122 (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
4123 ""
4124 "addxcc\t%1, %2, %0"
4125 [(set_attr "type" "compare")])
4126
4127
4128 (define_expand "subdi3"
4129 [(set (match_operand:DI 0 "register_operand" "")
4130 (minus:DI (match_operand:DI 1 "register_operand" "")
4131 (match_operand:DI 2 "arith_double_add_operand" "")))]
4132 ""
4133 {
4134 if (TARGET_ARCH32)
4135 {
4136 emit_insn (gen_subdi3_sp32 (operands[0], operands[1], operands[2]));
4137 DONE;
4138 }
4139 })
4140
4141 (define_expand "usubvdi4"
4142 [(parallel [(set (reg:CCX CC_REG)
4143 (compare:CCX (match_operand:DI 1 "register_or_zero_operand")
4144 (match_operand:DI 2 "arith_add_operand")))
4145 (set (match_operand:DI 0 "register_operand")
4146 (minus:DI (match_dup 1) (match_dup 2)))])
4147 (set (pc) (if_then_else (ltu (reg:CCX CC_REG) (const_int 0))
4148 (label_ref (match_operand 3))
4149 (pc)))]
4150 ""
4151 {
4152 if (operands[1] == const0_rtx)
4153 {
4154 emit_insn (gen_unegvdi3 (operands[0], operands[2], operands[3]));
4155 DONE;
4156 }
4157
4158 if (TARGET_ARCH32)
4159 {
4160 emit_insn (gen_usubvdi4_sp32 (operands[0], operands[1], operands[2]));
4161 rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
4162 const0_rtx);
4163 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
4164 DONE;
4165 }
4166 })
4167
4168 (define_expand "subvdi4"
4169 [(parallel [(set (reg:CCXV CC_REG)
4170 (compare:CCXV (minus:DI (match_operand:DI 1 "register_operand")
4171 (match_operand:DI 2 "arith_add_operand"))
4172 (unspec:DI [(match_dup 1) (match_dup 2)]
4173 UNSPEC_SUBV)))
4174 (set (match_operand:DI 0 "register_operand")
4175 (minus:DI (match_dup 1) (match_dup 2)))])
4176 (set (pc) (if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
4177 (label_ref (match_operand 3))
4178 (pc)))]
4179 ""
4180 {
4181 if (TARGET_ARCH32)
4182 {
4183 emit_insn (gen_subvdi4_sp32 (operands[0], operands[1], operands[2]));
4184 rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
4185 const0_rtx);
4186 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
4187 DONE;
4188 }
4189 })
4190
4191 (define_insn_and_split "subdi3_sp32"
4192 [(set (match_operand:DI 0 "register_operand" "=&r")
4193 (minus:DI (match_operand:DI 1 "register_operand" "r")
4194 (match_operand:DI 2 "arith_double_operand" "rHI")))
4195 (clobber (reg:CC CC_REG))]
4196 "TARGET_ARCH32"
4197 "#"
4198 "&& reload_completed"
4199 [(parallel [(set (reg:CC CC_REG)
4200 (compare:CC (match_dup 4) (match_dup 5)))
4201 (set (match_dup 3)
4202 (minus:SI (match_dup 4) (match_dup 5)))])
4203 (set (match_dup 6)
4204 (minus:SI (minus:SI (match_dup 7) (match_dup 8))
4205 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
4206 {
4207 operands[3] = gen_lowpart (SImode, operands[0]);
4208 operands[4] = gen_lowpart (SImode, operands[1]);
4209 operands[5] = gen_lowpart (SImode, operands[2]);
4210 operands[6] = gen_highpart (SImode, operands[0]);
4211 operands[7] = gen_highpart (SImode, operands[1]);
4212 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4213 }
4214 [(set_attr "length" "2")])
4215
4216 (define_insn_and_split "usubvdi4_sp32"
4217 [(set (reg:CCC CC_REG)
4218 (compare:CCC (match_operand:DI 1 "register_operand" "r")
4219 (match_operand:DI 2 "arith_double_operand" "rHI")))
4220 (set (match_operand:DI 0 "register_operand" "=&r")
4221 (minus:DI (match_dup 1) (match_dup 2)))]
4222 "TARGET_ARCH32"
4223 "#"
4224 "&& reload_completed"
4225 [(parallel [(set (reg:CC CC_REG)
4226 (compare:CC (match_dup 4) (match_dup 5)))
4227 (set (match_dup 3)
4228 (minus:SI (match_dup 4) (match_dup 5)))])
4229 (parallel [(set (reg:CCC CC_REG)
4230 (compare:CCC (zero_extend:DI
4231 (minus:SI (minus:SI (match_dup 7)
4232 (ltu:SI (reg:CC CC_REG)
4233 (const_int 0)))
4234 (match_dup 8)))
4235 (minus:DI
4236 (minus:DI (zero_extend:DI (match_dup 7))
4237 (ltu:DI (reg:CC CC_REG)
4238 (const_int 0)))
4239 (zero_extend:DI (match_dup 8)))))
4240 (set (match_dup 6)
4241 (minus:SI (minus:SI (match_dup 7)
4242 (ltu:SI (reg:CC CC_REG)
4243 (const_int 0)))
4244 (match_dup 8)))])]
4245 {
4246 operands[3] = gen_lowpart (SImode, operands[0]);
4247 operands[4] = gen_lowpart (SImode, operands[1]);
4248 operands[5] = gen_lowpart (SImode, operands[2]);
4249 operands[6] = gen_highpart (SImode, operands[0]);
4250 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4251 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4252 }
4253 [(set_attr "length" "2")])
4254
4255 (define_insn_and_split "subvdi4_sp32"
4256 [(set (reg:CCV CC_REG)
4257 (compare:CCV (minus:DI (match_operand:DI 1 "register_operand" "%r")
4258 (match_operand:DI 2 "arith_double_operand" "rHI"))
4259 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
4260 (set (match_operand:DI 0 "register_operand" "=&r")
4261 (minus:DI (match_dup 1) (match_dup 2)))]
4262 "TARGET_ARCH32"
4263 "#"
4264 "&& reload_completed"
4265 [(parallel [(set (reg:CC CC_REG)
4266 (compare:CC (match_dup 4) (match_dup 5)))
4267 (set (match_dup 3)
4268 (minus:SI (match_dup 4) (match_dup 5)))])
4269 (parallel [(set (reg:CCV CC_REG)
4270 (compare:CCV (minus:SI (minus:SI (match_dup 7) (match_dup 8))
4271 (ltu:SI (reg:CC CC_REG)
4272 (const_int 0)))
4273 (unspec:SI [(minus:SI (match_dup 7) (match_dup 8))
4274 (ltu:SI (reg:CC CC_REG)
4275 (const_int 0))]
4276 UNSPEC_SUBV)))
4277 (set (match_dup 6)
4278 (minus:SI (minus:SI (match_dup 7) (match_dup 8))
4279 (ltu:SI (reg:CC CC_REG) (const_int 0))))])]
4280 {
4281 operands[3] = gen_lowpart (SImode, operands[0]);
4282 operands[4] = gen_lowpart (SImode, operands[1]);
4283 operands[5] = gen_lowpart (SImode, operands[2]);
4284 operands[6] = gen_highpart (SImode, operands[0]);
4285 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4286 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4287 }
4288 [(set_attr "length" "2")])
4289
4290 (define_insn_and_split "*subx_extend_sp32"
4291 [(set (match_operand:DI 0 "register_operand" "=r")
4292 (zero_extend:DI (minus:SI (minus:SI
4293 (match_operand:SI 1 "register_or_zero_operand" "rJ")
4294 (match_operand:SI 2 "arith_operand" "rI"))
4295 (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
4296 "TARGET_ARCH32"
4297 "#"
4298 "&& reload_completed"
4299 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4300 (ltu:SI (reg:CCC CC_REG) (const_int 0))))
4301 (set (match_dup 4) (const_int 0))]
4302 "operands[3] = gen_lowpart (SImode, operands[0]);
4303 operands[4] = gen_highpart (SImode, operands[0]);"
4304 [(set_attr "length" "2")])
4305
4306 (define_insn_and_split "*subdi3_extend_sp32"
4307 [(set (match_operand:DI 0 "register_operand" "=&r")
4308 (minus:DI (match_operand:DI 1 "register_operand" "r")
4309 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4310 (clobber (reg:CC CC_REG))]
4311 "TARGET_ARCH32"
4312 "#"
4313 "&& reload_completed"
4314 [(parallel [(set (reg:CC CC_REG)
4315 (compare:CC (match_dup 3) (match_dup 2)))
4316 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4317 (set (match_dup 6)
4318 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4319 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
4320 "operands[3] = gen_lowpart (SImode, operands[1]);
4321 operands[4] = gen_highpart (SImode, operands[1]);
4322 operands[5] = gen_lowpart (SImode, operands[0]);
4323 operands[6] = gen_highpart (SImode, operands[0]);"
4324 [(set_attr "length" "2")])
4325
4326 (define_insn "*subdi3_sp64"
4327 [(set (match_operand:DI 0 "register_operand" "=r,r")
4328 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4329 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4330 "TARGET_ARCH64"
4331 "@
4332 sub\t%1, %2, %0
4333 add\t%1, -%2, %0")
4334
4335 (define_insn "subsi3"
4336 [(set (match_operand:SI 0 "register_operand" "=r,r")
4337 (minus:SI (match_operand:SI 1 "register_operand" "r,r")
4338 (match_operand:SI 2 "arith_add_operand" "rI,O")))]
4339 ""
4340 "@
4341 sub\t%1, %2, %0
4342 add\t%1, -%2, %0"
4343 [(set_attr "type" "*,*")
4344 (set_attr "fptype" "*,*")])
4345
4346 (define_expand "usubvsi4"
4347 [(parallel [(set (reg:CC CC_REG)
4348 (compare:CC (match_operand:SI 1 "register_or_zero_operand")
4349 (match_operand:SI 2 "arith_operand")))
4350 (set (match_operand:SI 0 "register_operand")
4351 (minus:SI (match_dup 1) (match_dup 2)))])
4352 (set (pc) (if_then_else (ltu (reg:CC CC_REG) (const_int 0))
4353 (label_ref (match_operand 3))
4354 (pc)))]
4355 ""
4356 {
4357 if (operands[1] == const0_rtx)
4358 {
4359 emit_insn (gen_unegvsi3 (operands[0], operands[2], operands[3]));
4360 DONE;
4361 }
4362 })
4363
4364 (define_expand "subvsi4"
4365 [(parallel [(set (reg:CCV CC_REG)
4366 (compare:CCV (minus:SI (match_operand:SI 1 "register_operand")
4367 (match_operand:SI 2 "arith_operand"))
4368 (unspec:SI [(match_dup 1) (match_dup 2)]
4369 UNSPEC_SUBV)))
4370 (set (match_operand:SI 0 "register_operand")
4371 (minus:SI (match_dup 1) (match_dup 2)))])
4372 (set (pc) (if_then_else (ne (reg:CCV CC_REG) (const_int 0))
4373 (label_ref (match_operand 3))
4374 (pc)))]
4375 "")
4376
4377 (define_insn "*cmp_ccnz_minus"
4378 [(set (reg:CCNZ CC_REG)
4379 (compare:CCNZ (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4380 (match_operand:SI 1 "arith_operand" "rI"))
4381 (const_int 0)))]
4382 ""
4383 "subcc\t%r0, %1, %%g0"
4384 [(set_attr "type" "compare")])
4385
4386 (define_insn "*cmp_ccxnz_minus"
4387 [(set (reg:CCXNZ CC_REG)
4388 (compare:CCXNZ (minus:DI (match_operand:DI 0 "register_or_zero_operand" "rJ")
4389 (match_operand:DI 1 "arith_operand" "rI"))
4390 (const_int 0)))]
4391 "TARGET_ARCH64"
4392 "subcc\t%r0, %1, %%g0"
4393 [(set_attr "type" "compare")])
4394
4395 (define_insn "*cmp_ccnz_minus_set"
4396 [(set (reg:CCNZ CC_REG)
4397 (compare:CCNZ (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4398 (match_operand:SI 2 "arith_operand" "rI"))
4399 (const_int 0)))
4400 (set (match_operand:SI 0 "register_operand" "=r")
4401 (minus:SI (match_dup 1) (match_dup 2)))]
4402 ""
4403 "subcc\t%r1, %2, %0"
4404 [(set_attr "type" "compare")])
4405
4406 (define_insn "*cmp_ccxnz_minus_set"
4407 [(set (reg:CCXNZ CC_REG)
4408 (compare:CCXNZ (minus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4409 (match_operand:DI 2 "arith_operand" "rI"))
4410 (const_int 0)))
4411 (set (match_operand:DI 0 "register_operand" "=r")
4412 (minus:DI (match_dup 1) (match_dup 2)))]
4413 "TARGET_ARCH64"
4414 "subcc\t%r1, %2, %0"
4415 [(set_attr "type" "compare")])
4416
4417 (define_insn "*cmpsi_set"
4418 [(set (reg:CC CC_REG)
4419 (compare:CC (match_operand:SI 1 "register_or_zero_operand" "rJ")
4420 (match_operand:SI 2 "arith_operand" "rI")))
4421 (set (match_operand:SI 0 "register_operand" "=r")
4422 (minus:SI (match_dup 1) (match_dup 2)))]
4423 ""
4424 "subcc\t%r1, %2, %0"
4425 [(set_attr "type" "compare")])
4426
4427 (define_insn "*cmpdi_set"
4428 [(set (reg:CCX CC_REG)
4429 (compare:CCX (match_operand:DI 1 "register_or_zero_operand" "rJ")
4430 (match_operand:DI 2 "arith_operand" "rI")))
4431 (set (match_operand:DI 0 "register_operand" "=r")
4432 (minus:DI (match_dup 1) (match_dup 2)))]
4433 "TARGET_ARCH64"
4434 "subcc\t%r1, %2, %0"
4435 [(set_attr "type" "compare")])
4436
4437 (define_insn "*cmp_ccc_minus_sltu_set"
4438 [(set (reg:CCC CC_REG)
4439 (compare:CCC (zero_extend:DI
4440 (minus:SI
4441 (minus:SI
4442 (match_operand:SI 1 "register_or_zero_operand" "rJ")
4443 (ltu:SI (reg:CC CC_REG) (const_int 0)))
4444 (match_operand:SI 2 "arith_operand" "rI")))
4445 (minus:DI
4446 (minus:DI
4447 (zero_extend:DI (match_dup 1))
4448 (ltu:DI (reg:CC CC_REG) (const_int 0)))
4449 (zero_extend:DI (match_dup 2)))))
4450 (set (match_operand:SI 0 "register_operand" "=r")
4451 (minus:SI (minus:SI (match_dup 1)
4452 (ltu:SI (reg:CC CC_REG) (const_int 0)))
4453 (match_dup 2)))]
4454 ""
4455 "subxcc\t%r1, %2, %0"
4456 [(set_attr "type" "compare")])
4457
4458 (define_insn "*cmp_ccv_minus"
4459 [(set (reg:CCV CC_REG)
4460 (compare:CCV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4461 (match_operand:SI 1 "arith_operand" "rI"))
4462 (unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))]
4463 ""
4464 "subcc\t%r0, %1, %%g0"
4465 [(set_attr "type" "compare")])
4466
4467 (define_insn "*cmp_ccxv_minus"
4468 [(set (reg:CCXV CC_REG)
4469 (compare:CCXV (minus:DI (match_operand:DI 0 "register_or_zero_operand" "rJ")
4470 (match_operand:DI 1 "arith_operand" "rI"))
4471 (unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))]
4472 "TARGET_ARCH64"
4473 "subcc\t%r0, %1, %%g0"
4474 [(set_attr "type" "compare")])
4475
4476 (define_insn "*cmp_ccv_minus_set"
4477 [(set (reg:CCV CC_REG)
4478 (compare:CCV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4479 (match_operand:SI 2 "arith_operand" "rI"))
4480 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
4481 (set (match_operand:SI 0 "register_operand" "=r")
4482 (minus:SI (match_dup 1) (match_dup 2)))]
4483 ""
4484 "subcc\t%r1, %2, %0"
4485 [(set_attr "type" "compare")])
4486
4487 (define_insn "*cmp_ccxv_minus_set"
4488 [(set (reg:CCXV CC_REG)
4489 (compare:CCXV (minus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4490 (match_operand:DI 2 "arith_operand" "rI"))
4491 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
4492 (set (match_operand:DI 0 "register_operand" "=r")
4493 (minus:DI (match_dup 1) (match_dup 2)))]
4494 "TARGET_ARCH64"
4495 "subcc\t%r1, %2, %0"
4496 [(set_attr "type" "compare")])
4497
4498 (define_insn "*cmp_ccv_minus_sltu_set"
4499 [(set (reg:CCV CC_REG)
4500 (compare:CCV
4501 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4502 (match_operand:SI 2 "arith_operand" "rI"))
4503 (ltu:SI (reg:CC CC_REG) (const_int 0)))
4504 (unspec:SI [(minus:SI (match_dup 1) (match_dup 2))
4505 (ltu:SI (reg:CC CC_REG) (const_int 0))]
4506 UNSPEC_SUBV)))
4507 (set (match_operand:SI 0 "register_operand" "=r")
4508 (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4509 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
4510 ""
4511 "subxcc\t%1, %2, %0"
4512 [(set_attr "type" "compare")])
4513
4514
4515 ;; Integer multiply/divide instructions.
4516
4517 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4518 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4519
4520 (define_insn "mulsi3"
4521 [(set (match_operand:SI 0 "register_operand" "=r")
4522 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4523 (match_operand:SI 2 "arith_operand" "rI")))]
4524 "TARGET_HARD_MUL"
4525 "smul\t%1, %2, %0"
4526 [(set_attr "type" "imul")])
4527
4528 (define_expand "muldi3"
4529 [(set (match_operand:DI 0 "register_operand" "")
4530 (mult:DI (match_operand:DI 1 "arith_operand" "")
4531 (match_operand:DI 2 "arith_operand" "")))]
4532 "TARGET_ARCH64 || TARGET_V8PLUS"
4533 {
4534 if (TARGET_V8PLUS)
4535 {
4536 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4537 DONE;
4538 }
4539 })
4540
4541 (define_insn "*muldi3_sp64"
4542 [(set (match_operand:DI 0 "register_operand" "=r")
4543 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4544 (match_operand:DI 2 "arith_operand" "rI")))]
4545 "TARGET_ARCH64"
4546 "mulx\t%1, %2, %0"
4547 [(set_attr "type" "imul")])
4548
4549 ;; V8plus wide multiply.
4550 (define_insn "muldi3_v8plus"
4551 [(set (match_operand:DI 0 "register_operand" "=r,h")
4552 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4553 (match_operand:DI 2 "arith_operand" "rI,rI")))
4554 (clobber (match_scratch:SI 3 "=&h,X"))
4555 (clobber (match_scratch:SI 4 "=&h,X"))]
4556 "TARGET_V8PLUS"
4557 {
4558 return output_v8plus_mult (insn, operands, \"mulx\");
4559 }
4560 [(set_attr "type" "multi")
4561 (set_attr "length" "9,8")])
4562
4563 (define_insn "*cmp_mul_set"
4564 [(set (reg:CC CC_REG)
4565 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4566 (match_operand:SI 2 "arith_operand" "rI"))
4567 (const_int 0)))
4568 (set (match_operand:SI 0 "register_operand" "=r")
4569 (mult:SI (match_dup 1) (match_dup 2)))]
4570 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4571 "smulcc\t%1, %2, %0"
4572 [(set_attr "type" "imul")])
4573
4574 (define_expand "mulsidi3"
4575 [(set (match_operand:DI 0 "register_operand" "")
4576 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4577 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4578 "TARGET_HARD_MUL"
4579 {
4580 if (CONSTANT_P (operands[2]))
4581 {
4582 if (TARGET_V8PLUS)
4583 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4584 operands[2]));
4585 else if (TARGET_ARCH32)
4586 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4587 operands[2]));
4588 else
4589 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4590 operands[2]));
4591 DONE;
4592 }
4593 if (TARGET_V8PLUS)
4594 {
4595 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4596 DONE;
4597 }
4598 })
4599
4600 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4601 ;; registers can hold 64-bit values in the V8plus environment.
4602 (define_insn "mulsidi3_v8plus"
4603 [(set (match_operand:DI 0 "register_operand" "=h,r")
4604 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4605 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4606 (clobber (match_scratch:SI 3 "=X,&h"))]
4607 "TARGET_V8PLUS"
4608 "@
4609 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4610 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4611 [(set_attr "type" "multi")
4612 (set_attr "length" "2,3")])
4613
4614 (define_insn "const_mulsidi3_v8plus"
4615 [(set (match_operand:DI 0 "register_operand" "=h,r")
4616 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4617 (match_operand:DI 2 "small_int_operand" "I,I")))
4618 (clobber (match_scratch:SI 3 "=X,&h"))]
4619 "TARGET_V8PLUS"
4620 "@
4621 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4622 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4623 [(set_attr "type" "multi")
4624 (set_attr "length" "2,3")])
4625
4626 (define_insn "*mulsidi3_sp32"
4627 [(set (match_operand:DI 0 "register_operand" "=r")
4628 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4629 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4630 "TARGET_HARD_MUL32"
4631 {
4632 return TARGET_SPARCLET
4633 ? "smuld\t%1, %2, %L0"
4634 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4635 }
4636 [(set (attr "type")
4637 (if_then_else (eq_attr "isa" "sparclet")
4638 (const_string "imul") (const_string "multi")))
4639 (set (attr "length")
4640 (if_then_else (eq_attr "isa" "sparclet")
4641 (const_int 1) (const_int 2)))])
4642
4643 (define_insn "*mulsidi3_sp64"
4644 [(set (match_operand:DI 0 "register_operand" "=r")
4645 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4646 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4647 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4648 "smul\t%1, %2, %0"
4649 [(set_attr "type" "imul")])
4650
4651 ;; Extra pattern, because sign_extend of a constant isn't valid.
4652
4653 (define_insn "const_mulsidi3_sp32"
4654 [(set (match_operand:DI 0 "register_operand" "=r")
4655 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4656 (match_operand:DI 2 "small_int_operand" "I")))]
4657 "TARGET_HARD_MUL32"
4658 {
4659 return TARGET_SPARCLET
4660 ? "smuld\t%1, %2, %L0"
4661 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4662 }
4663 [(set (attr "type")
4664 (if_then_else (eq_attr "isa" "sparclet")
4665 (const_string "imul") (const_string "multi")))
4666 (set (attr "length")
4667 (if_then_else (eq_attr "isa" "sparclet")
4668 (const_int 1) (const_int 2)))])
4669
4670 (define_insn "const_mulsidi3_sp64"
4671 [(set (match_operand:DI 0 "register_operand" "=r")
4672 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4673 (match_operand:DI 2 "small_int_operand" "I")))]
4674 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4675 "smul\t%1, %2, %0"
4676 [(set_attr "type" "imul")])
4677
4678 (define_expand "smulsi3_highpart"
4679 [(set (match_operand:SI 0 "register_operand" "")
4680 (truncate:SI
4681 (lshiftrt:DI
4682 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4683 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4684 (const_int 32))))]
4685 "TARGET_HARD_MUL && TARGET_ARCH32"
4686 {
4687 if (CONSTANT_P (operands[2]))
4688 {
4689 if (TARGET_V8PLUS)
4690 {
4691 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4692 operands[1],
4693 operands[2],
4694 GEN_INT (32)));
4695 DONE;
4696 }
4697 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4698 DONE;
4699 }
4700 if (TARGET_V8PLUS)
4701 {
4702 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4703 operands[2], GEN_INT (32)));
4704 DONE;
4705 }
4706 })
4707
4708 (define_insn "smulsi3_highpart_v8plus"
4709 [(set (match_operand:SI 0 "register_operand" "=h,r")
4710 (truncate:SI
4711 (lshiftrt:DI
4712 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4713 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4714 (match_operand:SI 3 "small_int_operand" "I,I"))))
4715 (clobber (match_scratch:SI 4 "=X,&h"))]
4716 "TARGET_V8PLUS"
4717 "@
4718 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4719 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4720 [(set_attr "type" "multi")
4721 (set_attr "length" "2")])
4722
4723 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4724 (define_insn ""
4725 [(set (match_operand:SI 0 "register_operand" "=h,r")
4726 (subreg:SI
4727 (lshiftrt:DI
4728 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4729 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4730 (match_operand:SI 3 "small_int_operand" "I,I")) 4))
4731 (clobber (match_scratch:SI 4 "=X,&h"))]
4732 "TARGET_V8PLUS"
4733 "@
4734 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4735 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4736 [(set_attr "type" "multi")
4737 (set_attr "length" "2")])
4738
4739 (define_insn "const_smulsi3_highpart_v8plus"
4740 [(set (match_operand:SI 0 "register_operand" "=h,r")
4741 (truncate:SI
4742 (lshiftrt:DI
4743 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4744 (match_operand:DI 2 "small_int_operand" "I,I"))
4745 (match_operand:SI 3 "small_int_operand" "I,I"))))
4746 (clobber (match_scratch:SI 4 "=X,&h"))]
4747 "TARGET_V8PLUS"
4748 "@
4749 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4750 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4751 [(set_attr "type" "multi")
4752 (set_attr "length" "2")])
4753
4754 (define_insn "*smulsi3_highpart_sp32"
4755 [(set (match_operand:SI 0 "register_operand" "=r")
4756 (truncate:SI
4757 (lshiftrt:DI
4758 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4759 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4760 (const_int 32))))]
4761 "TARGET_HARD_MUL32"
4762 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4763 [(set_attr "type" "multi")
4764 (set_attr "length" "2")])
4765
4766 (define_insn "const_smulsi3_highpart"
4767 [(set (match_operand:SI 0 "register_operand" "=r")
4768 (truncate:SI
4769 (lshiftrt:DI
4770 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4771 (match_operand:DI 2 "small_int_operand" "i"))
4772 (const_int 32))))]
4773 "TARGET_HARD_MUL32"
4774 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4775 [(set_attr "type" "multi")
4776 (set_attr "length" "2")])
4777
4778 (define_expand "umulsidi3"
4779 [(set (match_operand:DI 0 "register_operand" "")
4780 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4781 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4782 "TARGET_HARD_MUL"
4783 {
4784 if (CONSTANT_P (operands[2]))
4785 {
4786 if (TARGET_V8PLUS)
4787 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4788 operands[2]));
4789 else if (TARGET_ARCH32)
4790 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4791 operands[2]));
4792 else
4793 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4794 operands[2]));
4795 DONE;
4796 }
4797 if (TARGET_V8PLUS)
4798 {
4799 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4800 DONE;
4801 }
4802 })
4803
4804 (define_insn "umulsidi3_v8plus"
4805 [(set (match_operand:DI 0 "register_operand" "=h,r")
4806 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4807 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4808 (clobber (match_scratch:SI 3 "=X,&h"))]
4809 "TARGET_V8PLUS"
4810 "@
4811 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4812 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4813 [(set_attr "type" "multi")
4814 (set_attr "length" "2,3")])
4815
4816 (define_insn "*umulsidi3_sp32"
4817 [(set (match_operand:DI 0 "register_operand" "=r")
4818 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4819 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4820 "TARGET_HARD_MUL32"
4821 {
4822 return TARGET_SPARCLET
4823 ? "umuld\t%1, %2, %L0"
4824 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4825 }
4826 [(set (attr "type")
4827 (if_then_else (eq_attr "isa" "sparclet")
4828 (const_string "imul") (const_string "multi")))
4829 (set (attr "length")
4830 (if_then_else (eq_attr "isa" "sparclet")
4831 (const_int 1) (const_int 2)))])
4832
4833 (define_insn "*umulsidi3_sp64"
4834 [(set (match_operand:DI 0 "register_operand" "=r")
4835 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4836 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4837 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4838 "umul\t%1, %2, %0"
4839 [(set_attr "type" "imul")])
4840
4841 ;; Extra pattern, because sign_extend of a constant isn't valid.
4842
4843 (define_insn "const_umulsidi3_sp32"
4844 [(set (match_operand:DI 0 "register_operand" "=r")
4845 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4846 (match_operand:DI 2 "uns_small_int_operand" "")))]
4847 "TARGET_HARD_MUL32"
4848 {
4849 return TARGET_SPARCLET
4850 ? "umuld\t%1, %s2, %L0"
4851 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4852 }
4853 [(set (attr "type")
4854 (if_then_else (eq_attr "isa" "sparclet")
4855 (const_string "imul") (const_string "multi")))
4856 (set (attr "length")
4857 (if_then_else (eq_attr "isa" "sparclet")
4858 (const_int 1) (const_int 2)))])
4859
4860 (define_insn "const_umulsidi3_sp64"
4861 [(set (match_operand:DI 0 "register_operand" "=r")
4862 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4863 (match_operand:DI 2 "uns_small_int_operand" "")))]
4864 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4865 "umul\t%1, %s2, %0"
4866 [(set_attr "type" "imul")])
4867
4868 (define_insn "const_umulsidi3_v8plus"
4869 [(set (match_operand:DI 0 "register_operand" "=h,r")
4870 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4871 (match_operand:DI 2 "uns_small_int_operand" "")))
4872 (clobber (match_scratch:SI 3 "=X,h"))]
4873 "TARGET_V8PLUS"
4874 "@
4875 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4876 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4877 [(set_attr "type" "multi")
4878 (set_attr "length" "2,3")])
4879
4880 (define_expand "umulsi3_highpart"
4881 [(set (match_operand:SI 0 "register_operand" "")
4882 (truncate:SI
4883 (lshiftrt:DI
4884 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4885 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4886 (const_int 32))))]
4887 "TARGET_HARD_MUL && TARGET_ARCH32"
4888 {
4889 if (CONSTANT_P (operands[2]))
4890 {
4891 if (TARGET_V8PLUS)
4892 {
4893 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4894 operands[1],
4895 operands[2],
4896 GEN_INT (32)));
4897 DONE;
4898 }
4899 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4900 DONE;
4901 }
4902 if (TARGET_V8PLUS)
4903 {
4904 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4905 operands[2], GEN_INT (32)));
4906 DONE;
4907 }
4908 })
4909
4910 (define_insn "umulsi3_highpart_v8plus"
4911 [(set (match_operand:SI 0 "register_operand" "=h,r")
4912 (truncate:SI
4913 (lshiftrt:DI
4914 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4915 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4916 (match_operand:SI 3 "small_int_operand" "I,I"))))
4917 (clobber (match_scratch:SI 4 "=X,h"))]
4918 "TARGET_V8PLUS"
4919 "@
4920 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4921 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4922 [(set_attr "type" "multi")
4923 (set_attr "length" "2")])
4924
4925 (define_insn "const_umulsi3_highpart_v8plus"
4926 [(set (match_operand:SI 0 "register_operand" "=h,r")
4927 (truncate:SI
4928 (lshiftrt:DI
4929 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4930 (match_operand:DI 2 "uns_small_int_operand" ""))
4931 (match_operand:SI 3 "small_int_operand" "I,I"))))
4932 (clobber (match_scratch:SI 4 "=X,h"))]
4933 "TARGET_V8PLUS"
4934 "@
4935 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4936 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4937 [(set_attr "type" "multi")
4938 (set_attr "length" "2")])
4939
4940 (define_insn "*umulsi3_highpart_sp32"
4941 [(set (match_operand:SI 0 "register_operand" "=r")
4942 (truncate:SI
4943 (lshiftrt:DI
4944 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4945 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4946 (const_int 32))))]
4947 "TARGET_HARD_MUL32"
4948 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4949 [(set_attr "type" "multi")
4950 (set_attr "length" "2")])
4951
4952 (define_insn "const_umulsi3_highpart"
4953 [(set (match_operand:SI 0 "register_operand" "=r")
4954 (truncate:SI
4955 (lshiftrt:DI
4956 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4957 (match_operand:DI 2 "uns_small_int_operand" ""))
4958 (const_int 32))))]
4959 "TARGET_HARD_MUL32"
4960 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4961 [(set_attr "type" "multi")
4962 (set_attr "length" "2")])
4963
4964
4965 (define_expand "umulxhi_vis"
4966 [(set (match_operand:DI 0 "register_operand" "")
4967 (truncate:DI
4968 (lshiftrt:TI
4969 (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" ""))
4970 (zero_extend:TI (match_operand:DI 2 "arith_operand" "")))
4971 (const_int 64))))]
4972 "TARGET_VIS3"
4973 {
4974 if (TARGET_ARCH32)
4975 {
4976 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
4977 DONE;
4978 }
4979 })
4980
4981 (define_insn "*umulxhi_sp64"
4982 [(set (match_operand:DI 0 "register_operand" "=r")
4983 (truncate:DI
4984 (lshiftrt:TI
4985 (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" "%r"))
4986 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI")))
4987 (const_int 64))))]
4988 "TARGET_VIS3 && TARGET_ARCH64"
4989 "umulxhi\t%1, %2, %0"
4990 [(set_attr "type" "imul")])
4991
4992 (define_insn "umulxhi_v8plus"
4993 [(set (match_operand:DI 0 "register_operand" "=r,h")
4994 (truncate:DI
4995 (lshiftrt:TI
4996 (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0"))
4997 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI")))
4998 (const_int 64))))
4999 (clobber (match_scratch:SI 3 "=&h,X"))
5000 (clobber (match_scratch:SI 4 "=&h,X"))]
5001 "TARGET_VIS3 && TARGET_ARCH32"
5002 {
5003 return output_v8plus_mult (insn, operands, \"umulxhi\");
5004 }
5005 [(set_attr "type" "imul")
5006 (set_attr "length" "9,8")])
5007
5008 (define_expand "xmulx_vis"
5009 [(set (match_operand:DI 0 "register_operand" "")
5010 (truncate:DI
5011 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" ""))
5012 (zero_extend:TI (match_operand:DI 2 "arith_operand" ""))]
5013 UNSPEC_XMUL)))]
5014 "TARGET_VIS3"
5015 {
5016 if (TARGET_ARCH32)
5017 {
5018 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
5019 DONE;
5020 }
5021 })
5022
5023 (define_insn "*xmulx_sp64"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (truncate:DI
5026 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r"))
5027 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI"))]
5028 UNSPEC_XMUL)))]
5029 "TARGET_VIS3 && TARGET_ARCH64"
5030 "xmulx\t%1, %2, %0"
5031 [(set_attr "type" "imul")])
5032
5033 (define_insn "xmulx_v8plus"
5034 [(set (match_operand:DI 0 "register_operand" "=r,h")
5035 (truncate:DI
5036 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0"))
5037 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI"))]
5038 UNSPEC_XMUL)))
5039 (clobber (match_scratch:SI 3 "=&h,X"))
5040 (clobber (match_scratch:SI 4 "=&h,X"))]
5041 "TARGET_VIS3 && TARGET_ARCH32"
5042 {
5043 return output_v8plus_mult (insn, operands, \"xmulx\");
5044 }
5045 [(set_attr "type" "imul")
5046 (set_attr "length" "9,8")])
5047
5048 (define_expand "xmulxhi_vis"
5049 [(set (match_operand:DI 0 "register_operand" "")
5050 (truncate:DI
5051 (lshiftrt:TI
5052 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" ""))
5053 (zero_extend:TI (match_operand:DI 2 "arith_operand" ""))]
5054 UNSPEC_XMUL)
5055 (const_int 64))))]
5056 "TARGET_VIS3"
5057 {
5058 if (TARGET_ARCH32)
5059 {
5060 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
5061 DONE;
5062 }
5063 })
5064
5065 (define_insn "*xmulxhi_sp64"
5066 [(set (match_operand:DI 0 "register_operand" "=r")
5067 (truncate:DI
5068 (lshiftrt:TI
5069 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r"))
5070 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI"))]
5071 UNSPEC_XMUL)
5072 (const_int 64))))]
5073 "TARGET_VIS3 && TARGET_ARCH64"
5074 "xmulxhi\t%1, %2, %0"
5075 [(set_attr "type" "imul")])
5076
5077 (define_insn "xmulxhi_v8plus"
5078 [(set (match_operand:DI 0 "register_operand" "=r,h")
5079 (truncate:DI
5080 (lshiftrt:TI
5081 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0"))
5082 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI"))]
5083 UNSPEC_XMUL)
5084 (const_int 64))))
5085 (clobber (match_scratch:SI 3 "=&h,X"))
5086 (clobber (match_scratch:SI 4 "=&h,X"))]
5087 "TARGET_VIS3 && TARGET_ARCH32"
5088 {
5089 return output_v8plus_mult (insn, operands, \"xmulxhi\");
5090 }
5091 [(set_attr "type" "imul")
5092 (set_attr "length" "9,8")])
5093
5094 (define_expand "divsi3"
5095 [(parallel [(set (match_operand:SI 0 "register_operand" "")
5096 (div:SI (match_operand:SI 1 "register_operand" "")
5097 (match_operand:SI 2 "input_operand" "")))
5098 (clobber (match_scratch:SI 3 ""))])]
5099 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5100 {
5101 if (TARGET_ARCH64)
5102 {
5103 operands[3] = gen_reg_rtx(SImode);
5104 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5105 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5106 operands[3]));
5107 DONE;
5108 }
5109 })
5110
5111 ;; The V8 architecture specifies that there must be at least 3 instructions
5112 ;; between a write to the Y register and a use of it for correct results.
5113 ;; We try to fill one of them with a simple constant or a memory load.
5114
5115 (define_insn "divsi3_sp32"
5116 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
5117 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
5118 (match_operand:SI 2 "input_operand" "rI,K,m")))
5119 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
5120 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
5121 {
5122 output_asm_insn ("sra\t%1, 31, %3", operands);
5123 output_asm_insn ("wr\t%3, 0, %%y", operands);
5124
5125 switch (which_alternative)
5126 {
5127 case 0:
5128 if (TARGET_V9)
5129 return "sdiv\t%1, %2, %0";
5130 else
5131 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5132 case 1:
5133 if (TARGET_V9)
5134 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
5135 else
5136 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5137 case 2:
5138 if (TARGET_V9)
5139 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
5140 else
5141 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5142 default:
5143 gcc_unreachable ();
5144 }
5145 }
5146 [(set_attr "type" "multi")
5147 (set (attr "length")
5148 (if_then_else (eq_attr "isa" "v9")
5149 (const_int 4) (const_int 6)))])
5150
5151 (define_insn "divsi3_sp64"
5152 [(set (match_operand:SI 0 "register_operand" "=r")
5153 (div:SI (match_operand:SI 1 "register_operand" "r")
5154 (match_operand:SI 2 "input_operand" "rI")))
5155 (use (match_operand:SI 3 "register_operand" "r"))]
5156 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5157 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5158 [(set_attr "type" "multi")
5159 (set_attr "length" "2")])
5160
5161 (define_insn "divdi3"
5162 [(set (match_operand:DI 0 "register_operand" "=r")
5163 (div:DI (match_operand:DI 1 "register_operand" "r")
5164 (match_operand:DI 2 "arith_operand" "rI")))]
5165 "TARGET_ARCH64"
5166 "sdivx\t%1, %2, %0"
5167 [(set_attr "type" "idiv")])
5168
5169 (define_insn "*cmp_sdiv_cc_set"
5170 [(set (reg:CC CC_REG)
5171 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5172 (match_operand:SI 2 "arith_operand" "rI"))
5173 (const_int 0)))
5174 (set (match_operand:SI 0 "register_operand" "=r")
5175 (div:SI (match_dup 1) (match_dup 2)))
5176 (clobber (match_scratch:SI 3 "=&r"))]
5177 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5178 {
5179 output_asm_insn ("sra\t%1, 31, %3", operands);
5180 output_asm_insn ("wr\t%3, 0, %%y", operands);
5181
5182 if (TARGET_V9)
5183 return "sdivcc\t%1, %2, %0";
5184 else
5185 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5186 }
5187 [(set_attr "type" "multi")
5188 (set (attr "length")
5189 (if_then_else (eq_attr "isa" "v9")
5190 (const_int 3) (const_int 6)))])
5191
5192 (define_expand "udivsi3"
5193 [(set (match_operand:SI 0 "register_operand" "")
5194 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5195 (match_operand:SI 2 "input_operand" "")))]
5196 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5197 "")
5198
5199 ;; The V8 architecture specifies that there must be at least 3 instructions
5200 ;; between a write to the Y register and a use of it for correct results.
5201 ;; We try to fill one of them with a simple constant or a memory load.
5202
5203 (define_insn "udivsi3_sp32"
5204 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
5205 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
5206 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
5207 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
5208 {
5209 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5210
5211 switch (which_alternative)
5212 {
5213 case 0:
5214 if (TARGET_V9)
5215 return "udiv\t%1, %2, %0";
5216 else
5217 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5218 case 1:
5219 if (TARGET_V9)
5220 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
5221 else
5222 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5223 case 2:
5224 if (TARGET_V9)
5225 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
5226 else
5227 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5228 case 3:
5229 if (TARGET_V9)
5230 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
5231 else
5232 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5233 default:
5234 gcc_unreachable ();
5235 }
5236 }
5237 [(set_attr "type" "multi")
5238 (set (attr "length")
5239 (if_then_else (eq_attr "isa" "v9")
5240 (const_int 3) (const_int 5)))])
5241
5242 (define_insn "udivsi3_sp64"
5243 [(set (match_operand:SI 0 "register_operand" "=r")
5244 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5245 (match_operand:SI 2 "input_operand" "rI")))]
5246 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5247 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5248 [(set_attr "type" "multi")
5249 (set_attr "length" "2")])
5250
5251 (define_insn "udivdi3"
5252 [(set (match_operand:DI 0 "register_operand" "=r")
5253 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5254 (match_operand:DI 2 "arith_operand" "rI")))]
5255 "TARGET_ARCH64"
5256 "udivx\t%1, %2, %0"
5257 [(set_attr "type" "idiv")])
5258
5259 (define_insn "*cmp_udiv_cc_set"
5260 [(set (reg:CC CC_REG)
5261 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5262 (match_operand:SI 2 "arith_operand" "rI"))
5263 (const_int 0)))
5264 (set (match_operand:SI 0 "register_operand" "=r")
5265 (udiv:SI (match_dup 1) (match_dup 2)))]
5266 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5267 {
5268 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5269
5270 if (TARGET_V9)
5271 return "udivcc\t%1, %2, %0";
5272 else
5273 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5274 }
5275 [(set_attr "type" "multi")
5276 (set (attr "length")
5277 (if_then_else (eq_attr "isa" "v9")
5278 (const_int 2) (const_int 5)))])
5279
5280
5281 ;; SPARClet multiply/accumulate insns
5282
5283 (define_insn "*smacsi"
5284 [(set (match_operand:SI 0 "register_operand" "=r")
5285 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5286 (match_operand:SI 2 "arith_operand" "rI"))
5287 (match_operand:SI 3 "register_operand" "0")))]
5288 "TARGET_SPARCLET"
5289 "smac\t%1, %2, %0"
5290 [(set_attr "type" "imul")])
5291
5292 (define_insn "*smacdi"
5293 [(set (match_operand:DI 0 "register_operand" "=r")
5294 (plus:DI (mult:DI (sign_extend:DI
5295 (match_operand:SI 1 "register_operand" "%r"))
5296 (sign_extend:DI
5297 (match_operand:SI 2 "register_operand" "r")))
5298 (match_operand:DI 3 "register_operand" "0")))]
5299 "TARGET_SPARCLET"
5300 "smacd\t%1, %2, %L0"
5301 [(set_attr "type" "imul")])
5302
5303 (define_insn "*umacdi"
5304 [(set (match_operand:DI 0 "register_operand" "=r")
5305 (plus:DI (mult:DI (zero_extend:DI
5306 (match_operand:SI 1 "register_operand" "%r"))
5307 (zero_extend:DI
5308 (match_operand:SI 2 "register_operand" "r")))
5309 (match_operand:DI 3 "register_operand" "0")))]
5310 "TARGET_SPARCLET"
5311 "umacd\t%1, %2, %L0"
5312 [(set_attr "type" "imul")])
5313
5314
5315 ;; Boolean instructions.
5316
5317 (define_insn "anddi3"
5318 [(set (match_operand:DI 0 "register_operand" "=r")
5319 (and:DI (match_operand:DI 1 "arith_operand" "%r")
5320 (match_operand:DI 2 "arith_operand" "rI")))]
5321 "TARGET_ARCH64"
5322 "and\t%1, %2, %0")
5323
5324 (define_insn "andsi3"
5325 [(set (match_operand:SI 0 "register_operand" "=r")
5326 (and:SI (match_operand:SI 1 "arith_operand" "%r")
5327 (match_operand:SI 2 "arith_operand" "rI")))]
5328 ""
5329 "and\t%1, %2, %0")
5330
5331 (define_split
5332 [(set (match_operand:SI 0 "register_operand" "")
5333 (and:SI (match_operand:SI 1 "register_operand" "")
5334 (match_operand:SI 2 "const_compl_high_operand" "")))
5335 (clobber (match_operand:SI 3 "register_operand" ""))]
5336 ""
5337 [(set (match_dup 3) (match_dup 4))
5338 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5339 {
5340 operands[4] = GEN_INT (~INTVAL (operands[2]));
5341 })
5342
5343 (define_insn "*and_not_di_sp64"
5344 [(set (match_operand:DI 0 "register_operand" "=r")
5345 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
5346 (match_operand:DI 2 "register_operand" "r")))]
5347 "TARGET_ARCH64"
5348 "andn\t%2, %1, %0")
5349
5350 (define_insn "*and_not_si"
5351 [(set (match_operand:SI 0 "register_operand" "=r")
5352 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
5353 (match_operand:SI 2 "register_operand" "r")))]
5354 ""
5355 "andn\t%2, %1, %0")
5356
5357 (define_insn "iordi3"
5358 [(set (match_operand:DI 0 "register_operand" "=r")
5359 (ior:DI (match_operand:DI 1 "arith_operand" "%r")
5360 (match_operand:DI 2 "arith_operand" "rI")))]
5361 "TARGET_ARCH64"
5362 "or\t%1, %2, %0")
5363
5364 (define_insn "iorsi3"
5365 [(set (match_operand:SI 0 "register_operand" "=r")
5366 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
5367 (match_operand:SI 2 "arith_operand" "rI")))]
5368 ""
5369 "or\t%1, %2, %0")
5370
5371 (define_split
5372 [(set (match_operand:SI 0 "register_operand" "")
5373 (ior:SI (match_operand:SI 1 "register_operand" "")
5374 (match_operand:SI 2 "const_compl_high_operand" "")))
5375 (clobber (match_operand:SI 3 "register_operand" ""))]
5376 ""
5377 [(set (match_dup 3) (match_dup 4))
5378 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5379 {
5380 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
5381 })
5382
5383 (define_insn "*or_not_di_sp64"
5384 [(set (match_operand:DI 0 "register_operand" "=r")
5385 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5386 (match_operand:DI 2 "register_operand" "r")))]
5387 "TARGET_ARCH64"
5388 "orn\t%2, %1, %0")
5389
5390 (define_insn "*or_not_si"
5391 [(set (match_operand:SI 0 "register_operand" "=r")
5392 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5393 (match_operand:SI 2 "register_operand" "r")))]
5394 ""
5395 "orn\t%2, %1, %0")
5396
5397 (define_insn "xordi3"
5398 [(set (match_operand:DI 0 "register_operand" "=r")
5399 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
5400 (match_operand:DI 2 "arith_operand" "rI")))]
5401 "TARGET_ARCH64"
5402 "xor\t%r1, %2, %0")
5403
5404 (define_insn "xorsi3"
5405 [(set (match_operand:SI 0 "register_operand" "=r")
5406 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
5407 (match_operand:SI 2 "arith_operand" "rI")))]
5408 ""
5409 "xor\t%r1, %2, %0")
5410
5411 (define_split
5412 [(set (match_operand:SI 0 "register_operand" "")
5413 (xor:SI (match_operand:SI 1 "register_operand" "")
5414 (match_operand:SI 2 "const_compl_high_operand" "")))
5415 (clobber (match_operand:SI 3 "register_operand" ""))]
5416 ""
5417 [(set (match_dup 3) (match_dup 4))
5418 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5419 {
5420 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
5421 })
5422
5423 (define_split
5424 [(set (match_operand:SI 0 "register_operand" "")
5425 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5426 (match_operand:SI 2 "const_compl_high_operand" ""))))
5427 (clobber (match_operand:SI 3 "register_operand" ""))]
5428 ""
5429 [(set (match_dup 3) (match_dup 4))
5430 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5431 {
5432 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
5433 })
5434
5435 (define_insn "*xor_not_di_sp64"
5436 [(set (match_operand:DI 0 "register_operand" "=r")
5437 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
5438 (match_operand:DI 2 "arith_operand" "rI"))))]
5439 "TARGET_ARCH64"
5440 "xnor\t%r1, %2, %0")
5441
5442 (define_insn "*xor_not_si"
5443 [(set (match_operand:SI 0 "register_operand" "=r")
5444 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
5445 (match_operand:SI 2 "arith_operand" "rI"))))]
5446 ""
5447 "xnor\t%r1, %2, %0")
5448
5449 ;; These correspond to the above in the case where we also (or only)
5450 ;; want to set the condition code.
5451
5452 (define_insn "*cmp_cc_arith_op"
5453 [(set (reg:CC CC_REG)
5454 (compare:CC (match_operator:SI 2 "cc_arith_operator"
5455 [(match_operand:SI 0 "arith_operand" "%r")
5456 (match_operand:SI 1 "arith_operand" "rI")])
5457 (const_int 0)))]
5458 ""
5459 "%A2cc\t%0, %1, %%g0"
5460 [(set_attr "type" "compare")])
5461
5462 (define_insn "*cmp_ccx_arith_op"
5463 [(set (reg:CCX CC_REG)
5464 (compare:CCX (match_operator:DI 2 "cc_arith_operator"
5465 [(match_operand:DI 0 "arith_operand" "%r")
5466 (match_operand:DI 1 "arith_operand" "rI")])
5467 (const_int 0)))]
5468 "TARGET_ARCH64"
5469 "%A2cc\t%0, %1, %%g0"
5470 [(set_attr "type" "compare")])
5471
5472 (define_insn "*cmp_cc_arith_op_set"
5473 [(set (reg:CC CC_REG)
5474 (compare:CC (match_operator:SI 3 "cc_arith_operator"
5475 [(match_operand:SI 1 "arith_operand" "%r")
5476 (match_operand:SI 2 "arith_operand" "rI")])
5477 (const_int 0)))
5478 (set (match_operand:SI 0 "register_operand" "=r")
5479 (match_operator:SI 4 "cc_arith_operator"
5480 [(match_dup 1) (match_dup 2)]))]
5481 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5482 "%A3cc\t%1, %2, %0"
5483 [(set_attr "type" "compare")])
5484
5485 (define_insn "*cmp_ccx_arith_op_set"
5486 [(set (reg:CCX CC_REG)
5487 (compare:CCX (match_operator:DI 3 "cc_arith_operator"
5488 [(match_operand:DI 1 "arith_operand" "%r")
5489 (match_operand:DI 2 "arith_operand" "rI")])
5490 (const_int 0)))
5491 (set (match_operand:DI 0 "register_operand" "=r")
5492 (match_operator:DI 4 "cc_arith_operator"
5493 [(match_dup 1) (match_dup 2)]))]
5494 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5495 "%A3cc\t%1, %2, %0"
5496 [(set_attr "type" "compare")])
5497
5498 (define_insn "*cmp_cc_xor_not"
5499 [(set (reg:CC CC_REG)
5500 (compare:CC
5501 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5502 (match_operand:SI 1 "arith_operand" "rI")))
5503 (const_int 0)))]
5504 ""
5505 "xnorcc\t%r0, %1, %%g0"
5506 [(set_attr "type" "compare")])
5507
5508 (define_insn "*cmp_ccx_xor_not"
5509 [(set (reg:CCX CC_REG)
5510 (compare:CCX
5511 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5512 (match_operand:DI 1 "arith_operand" "rI")))
5513 (const_int 0)))]
5514 "TARGET_ARCH64"
5515 "xnorcc\t%r0, %1, %%g0"
5516 [(set_attr "type" "compare")])
5517
5518 (define_insn "*cmp_cc_xor_not_set"
5519 [(set (reg:CC CC_REG)
5520 (compare:CC
5521 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5522 (match_operand:SI 2 "arith_operand" "rI")))
5523 (const_int 0)))
5524 (set (match_operand:SI 0 "register_operand" "=r")
5525 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5526 ""
5527 "xnorcc\t%r1, %2, %0"
5528 [(set_attr "type" "compare")])
5529
5530 (define_insn "*cmp_ccx_xor_not_set"
5531 [(set (reg:CCX CC_REG)
5532 (compare:CCX
5533 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5534 (match_operand:DI 2 "arith_operand" "rI")))
5535 (const_int 0)))
5536 (set (match_operand:DI 0 "register_operand" "=r")
5537 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5538 "TARGET_ARCH64"
5539 "xnorcc\t%r1, %2, %0"
5540 [(set_attr "type" "compare")])
5541
5542 (define_insn "*cmp_cc_arith_op_not"
5543 [(set (reg:CC CC_REG)
5544 (compare:CC (match_operator:SI 2 "cc_arith_not_operator"
5545 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5546 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5547 (const_int 0)))]
5548 ""
5549 "%B2cc\t%r1, %0, %%g0"
5550 [(set_attr "type" "compare")])
5551
5552 (define_insn "*cmp_ccx_arith_op_not"
5553 [(set (reg:CCX CC_REG)
5554 (compare:CCX (match_operator:DI 2 "cc_arith_not_operator"
5555 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5556 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5557 (const_int 0)))]
5558 "TARGET_ARCH64"
5559 "%B2cc\t%r1, %0, %%g0"
5560 [(set_attr "type" "compare")])
5561
5562 (define_insn "*cmp_cc_arith_op_not_set"
5563 [(set (reg:CC CC_REG)
5564 (compare:CC (match_operator:SI 3 "cc_arith_not_operator"
5565 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5566 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5567 (const_int 0)))
5568 (set (match_operand:SI 0 "register_operand" "=r")
5569 (match_operator:SI 4 "cc_arith_not_operator"
5570 [(not:SI (match_dup 1)) (match_dup 2)]))]
5571 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5572 "%B3cc\t%r2, %1, %0"
5573 [(set_attr "type" "compare")])
5574
5575 (define_insn "*cmp_ccx_arith_op_not_set"
5576 [(set (reg:CCX CC_REG)
5577 (compare:CCX (match_operator:DI 3 "cc_arith_not_operator"
5578 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5579 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5580 (const_int 0)))
5581 (set (match_operand:DI 0 "register_operand" "=r")
5582 (match_operator:DI 4 "cc_arith_not_operator"
5583 [(not:DI (match_dup 1)) (match_dup 2)]))]
5584 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5585 "%B3cc\t%r2, %1, %0"
5586 [(set_attr "type" "compare")])
5587
5588 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5589 ;; does not know how to make it work for constants.
5590
5591 (define_expand "negdi2"
5592 [(set (match_operand:DI 0 "register_operand" "=r")
5593 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5594 ""
5595 {
5596 if (TARGET_ARCH32)
5597 {
5598 emit_insn (gen_negdi2_sp32 (operands[0], operands[1]));
5599 DONE;
5600 }
5601 })
5602
5603 (define_expand "unegvdi3"
5604 [(parallel [(set (reg:CCXC CC_REG)
5605 (compare:CCXC (not:DI (match_operand:DI 1 "register_operand" ""))
5606 (const_int -1)))
5607 (set (match_operand:DI 0 "register_operand" "")
5608 (neg:DI (match_dup 1)))])
5609 (set (pc)
5610 (if_then_else (ltu (reg:CCXC CC_REG) (const_int 0))
5611 (label_ref (match_operand 2 ""))
5612 (pc)))]
5613 ""
5614 {
5615 if (TARGET_ARCH32)
5616 {
5617 emit_insn (gen_unegvdi3_sp32 (operands[0], operands[1]));
5618 rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
5619 const0_rtx);
5620 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2]));
5621 DONE;
5622 }
5623 })
5624
5625 (define_expand "negvdi3"
5626 [(parallel [(set (reg:CCXV CC_REG)
5627 (compare:CCXV (neg:DI (match_operand:DI 1 "register_operand" ""))
5628 (unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
5629 (set (match_operand:DI 0 "register_operand" "")
5630 (neg:DI (match_dup 1)))])
5631 (set (pc)
5632 (if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
5633 (label_ref (match_operand 2 ""))
5634 (pc)))]
5635 ""
5636 {
5637 if (TARGET_ARCH32)
5638 {
5639 emit_insn (gen_negvdi3_sp32 (operands[0], operands[1]));
5640 rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
5641 const0_rtx);
5642 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2]));
5643 DONE;
5644 }
5645 })
5646
5647 (define_insn_and_split "negdi2_sp32"
5648 [(set (match_operand:DI 0 "register_operand" "=&r")
5649 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5650 (clobber (reg:CC CC_REG))]
5651 "TARGET_ARCH32"
5652 "#"
5653 "&& reload_completed"
5654 [(parallel [(set (reg:CCC CC_REG)
5655 (compare:CCC (not:SI (match_dup 5)) (const_int -1)))
5656 (set (match_dup 4) (neg:SI (match_dup 5)))])
5657 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5658 (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
5659 "operands[2] = gen_highpart (SImode, operands[0]);
5660 operands[3] = gen_highpart (SImode, operands[1]);
5661 operands[4] = gen_lowpart (SImode, operands[0]);
5662 operands[5] = gen_lowpart (SImode, operands[1]);"
5663 [(set_attr "length" "2")])
5664
5665 (define_insn_and_split "unegvdi3_sp32"
5666 [(set (reg:CCC CC_REG)
5667 (compare:CCC (not:DI (match_operand:DI 1 "register_operand" "r"))
5668 (const_int -1)))
5669 (set (match_operand:DI 0 "register_operand" "=&r")
5670 (neg:DI (match_dup 1)))]
5671 "TARGET_ARCH32"
5672 "#"
5673 "&& reload_completed"
5674 [(parallel [(set (reg:CCC CC_REG)
5675 (compare:CCC (not:SI (match_dup 5)) (const_int -1)))
5676 (set (match_dup 4) (neg:SI (match_dup 5)))])
5677 (parallel [(set (reg:CCC CC_REG)
5678 (compare:CCC (zero_extend:DI
5679 (neg:SI (plus:SI (match_dup 3)
5680 (ltu:SI (reg:CCC CC_REG)
5681 (const_int 0)))))
5682 (neg:DI (plus:DI (zero_extend:DI (match_dup 3))
5683 (ltu:DI (reg:CCC CC_REG)
5684 (const_int 0))))))
5685 (set (match_dup 2) (neg:SI (plus:SI (match_dup 3)
5686 (ltu:SI (reg:CCC CC_REG)
5687 (const_int 0)))))])]
5688 "operands[2] = gen_highpart (SImode, operands[0]);
5689 operands[3] = gen_highpart (SImode, operands[1]);
5690 operands[4] = gen_lowpart (SImode, operands[0]);
5691 operands[5] = gen_lowpart (SImode, operands[1]);"
5692 [(set_attr "length" "2")])
5693
5694 (define_insn_and_split "negvdi3_sp32"
5695 [(set (reg:CCV CC_REG)
5696 (compare:CCV (neg:DI (match_operand:DI 1 "register_operand" "r"))
5697 (unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
5698 (set (match_operand:DI 0 "register_operand" "=&r")
5699 (neg:DI (match_dup 1)))]
5700 "TARGET_ARCH32"
5701 "#"
5702 "&& reload_completed"
5703 [(parallel [(set (reg:CCC CC_REG)
5704 (compare:CCC (not:SI (match_dup 5)) (const_int -1)))
5705 (set (match_dup 4) (neg:SI (match_dup 5)))])
5706 (parallel [(set (reg:CCV CC_REG)
5707 (compare:CCV (neg:SI (plus:SI (match_dup 3)
5708 (ltu:SI (reg:CCC CC_REG)
5709 (const_int 0))))
5710 (unspec:SI [(plus:SI (match_dup 3)
5711 (ltu:SI (reg:CCC CC_REG)
5712 (const_int 0)))]
5713 UNSPEC_NEGV)))
5714 (set (match_dup 2) (neg:SI (plus:SI (match_dup 3)
5715 (ltu:SI (reg:CCC CC_REG)
5716 (const_int 0)))))])]
5717 "operands[2] = gen_highpart (SImode, operands[0]);
5718 operands[3] = gen_highpart (SImode, operands[1]);
5719 operands[4] = gen_lowpart (SImode, operands[0]);
5720 operands[5] = gen_lowpart (SImode, operands[1]);"
5721 [(set_attr "length" "2")])
5722
5723 (define_insn "*negdi2_sp64"
5724 [(set (match_operand:DI 0 "register_operand" "=r")
5725 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5726 "TARGET_ARCH64"
5727 "sub\t%%g0, %1, %0")
5728
5729 (define_insn "negsi2"
5730 [(set (match_operand:SI 0 "register_operand" "=r")
5731 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5732 ""
5733 "sub\t%%g0, %1, %0")
5734
5735 (define_expand "unegvsi3"
5736 [(parallel [(set (reg:CCC CC_REG)
5737 (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" ""))
5738 (const_int -1)))
5739 (set (match_operand:SI 0 "register_operand" "")
5740 (neg:SI (match_dup 1)))])
5741 (set (pc)
5742 (if_then_else (ltu (reg:CCC CC_REG) (const_int 0))
5743 (label_ref (match_operand 2 ""))
5744 (pc)))]
5745 "")
5746
5747 (define_expand "negvsi3"
5748 [(parallel [(set (reg:CCV CC_REG)
5749 (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" ""))
5750 (unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
5751 (set (match_operand:SI 0 "register_operand" "")
5752 (neg:SI (match_dup 1)))])
5753 (set (pc)
5754 (if_then_else (ne (reg:CCV CC_REG) (const_int 0))
5755 (label_ref (match_operand 2 ""))
5756 (pc)))]
5757 "")
5758
5759 (define_insn "*cmp_ccnz_neg"
5760 [(set (reg:CCNZ CC_REG)
5761 (compare:CCNZ (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5762 (const_int 0)))]
5763 ""
5764 "subcc\t%%g0, %0, %%g0"
5765 [(set_attr "type" "compare")])
5766
5767 (define_insn "*cmp_ccxnz_neg"
5768 [(set (reg:CCXNZ CC_REG)
5769 (compare:CCXNZ (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5770 (const_int 0)))]
5771 "TARGET_ARCH64"
5772 "subcc\t%%g0, %0, %%g0"
5773 [(set_attr "type" "compare")])
5774
5775 (define_insn "*cmp_ccnz_neg_set"
5776 [(set (reg:CCNZ CC_REG)
5777 (compare:CCNZ (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5778 (const_int 0)))
5779 (set (match_operand:SI 0 "register_operand" "=r")
5780 (neg:SI (match_dup 1)))]
5781 ""
5782 "subcc\t%%g0, %1, %0"
5783 [(set_attr "type" "compare")])
5784
5785 (define_insn "*cmp_ccxnz_neg_set"
5786 [(set (reg:CCXNZ CC_REG)
5787 (compare:CCXNZ (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5788 (const_int 0)))
5789 (set (match_operand:DI 0 "register_operand" "=r")
5790 (neg:DI (match_dup 1)))]
5791 "TARGET_ARCH64"
5792 "subcc\t%%g0, %1, %0"
5793 [(set_attr "type" "compare")])
5794
5795 (define_insn "*cmp_ccc_neg_set"
5796 [(set (reg:CCC CC_REG)
5797 (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5798 (const_int -1)))
5799 (set (match_operand:SI 0 "register_operand" "=r")
5800 (neg:SI (match_dup 1)))]
5801 ""
5802 "subcc\t%%g0, %1, %0"
5803 [(set_attr "type" "compare")])
5804
5805 (define_insn "*cmp_ccxc_neg_set"
5806 [(set (reg:CCXC CC_REG)
5807 (compare:CCXC (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5808 (const_int -1)))
5809 (set (match_operand:DI 0 "register_operand" "=r")
5810 (neg:DI (match_dup 1)))]
5811 "TARGET_ARCH64"
5812 "subcc\t%%g0, %1, %0"
5813 [(set_attr "type" "compare")])
5814
5815 (define_insn "*cmp_ccc_neg_sltu_set"
5816 [(set (reg:CCC CC_REG)
5817 (compare:CCC (zero_extend:DI
5818 (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
5819 (ltu:SI (reg:CCC CC_REG)
5820 (const_int 0)))))
5821 (neg:DI (plus:DI (zero_extend:DI (match_dup 1))
5822 (ltu:DI (reg:CCC CC_REG)
5823 (const_int 0))))))
5824 (set (match_operand:SI 0 "register_operand" "=r")
5825 (neg:SI (plus:SI (match_dup 1)
5826 (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
5827 ""
5828 "subxcc\t%%g0, %1, %0"
5829 [(set_attr "type" "compare")])
5830
5831 (define_insn "*cmp_ccv_neg"
5832 [(set (reg:CCV CC_REG)
5833 (compare:CCV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5834 (unspec:SI [(match_dup 0)] UNSPEC_NEGV)))]
5835 ""
5836 "subcc\t%%g0, %0, %%g0"
5837 [(set_attr "type" "compare")])
5838
5839 (define_insn "*cmp_ccxv_neg"
5840 [(set (reg:CCXV CC_REG)
5841 (compare:CCXV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5842 (unspec:DI [(match_dup 0)] UNSPEC_NEGV)))]
5843 "TARGET_ARCH64"
5844 "subcc\t%%g0, %0, %%g0"
5845 [(set_attr "type" "compare")])
5846
5847 (define_insn "*cmp_ccv_neg_set"
5848 [(set (reg:CCV CC_REG)
5849 (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5850 (unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
5851 (set (match_operand:SI 0 "register_operand" "=r")
5852 (neg:SI (match_dup 1)))]
5853 ""
5854 "subcc\t%%g0, %1, %0"
5855 [(set_attr "type" "compare")])
5856
5857 (define_insn "*cmp_ccxv_neg_set"
5858 [(set (reg:CCXV CC_REG)
5859 (compare:CCXV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5860 (unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
5861 (set (match_operand:DI 0 "register_operand" "=r")
5862 (neg:DI (match_dup 1)))]
5863 "TARGET_ARCH64"
5864 "subcc\t%%g0, %1, %0"
5865 [(set_attr "type" "compare")])
5866
5867 (define_insn "*cmp_ccv_neg_sltu_set"
5868 [(set (reg:CCV CC_REG)
5869 (compare:CCV (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
5870 (ltu:SI (reg:CCC CC_REG) (const_int 0))))
5871 (unspec:SI [(plus:SI (match_dup 1)
5872 (ltu:SI (reg:CCC CC_REG)
5873 (const_int 0)))]
5874 UNSPEC_NEGV)))
5875 (set (match_operand:SI 0 "register_operand" "=r")
5876 (neg:SI (plus:SI (match_dup 1)
5877 (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
5878 ""
5879 "subxcc\t%%g0, %1, %0"
5880 [(set_attr "type" "compare")])
5881
5882
5883 (define_insn "one_cmpldi2"
5884 [(set (match_operand:DI 0 "register_operand" "=r")
5885 (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5886 "TARGET_ARCH64"
5887 "xnor\t%%g0, %1, %0")
5888
5889 (define_insn "one_cmplsi2"
5890 [(set (match_operand:SI 0 "register_operand" "=r")
5891 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5892 ""
5893 "xnor\t%%g0, %1, %0")
5894
5895 (define_insn "*cmp_cc_not"
5896 [(set (reg:CC CC_REG)
5897 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5898 (const_int 0)))]
5899 ""
5900 "xnorcc\t%%g0, %0, %%g0"
5901 [(set_attr "type" "compare")])
5902
5903 (define_insn "*cmp_ccx_not"
5904 [(set (reg:CCX CC_REG)
5905 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5906 (const_int 0)))]
5907 "TARGET_ARCH64"
5908 "xnorcc\t%%g0, %0, %%g0"
5909 [(set_attr "type" "compare")])
5910
5911 (define_insn "*cmp_cc_set_not"
5912 [(set (reg:CC CC_REG)
5913 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5914 (const_int 0)))
5915 (set (match_operand:SI 0 "register_operand" "=r")
5916 (not:SI (match_dup 1)))]
5917 ""
5918 "xnorcc\t%%g0, %1, %0"
5919 [(set_attr "type" "compare")])
5920
5921 (define_insn "*cmp_ccx_set_not"
5922 [(set (reg:CCX CC_REG)
5923 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5924 (const_int 0)))
5925 (set (match_operand:DI 0 "register_operand" "=r")
5926 (not:DI (match_dup 1)))]
5927 "TARGET_ARCH64"
5928 "xnorcc\t%%g0, %1, %0"
5929 [(set_attr "type" "compare")])
5930
5931 (define_insn "*cmp_cc_set"
5932 [(set (match_operand:SI 0 "register_operand" "=r")
5933 (match_operand:SI 1 "register_operand" "r"))
5934 (set (reg:CC CC_REG)
5935 (compare:CC (match_dup 1) (const_int 0)))]
5936 ""
5937 "orcc\t%1, 0, %0"
5938 [(set_attr "type" "compare")])
5939
5940 (define_insn "*cmp_ccx_set64"
5941 [(set (match_operand:DI 0 "register_operand" "=r")
5942 (match_operand:DI 1 "register_operand" "r"))
5943 (set (reg:CCX CC_REG)
5944 (compare:CCX (match_dup 1) (const_int 0)))]
5945 "TARGET_ARCH64"
5946 "orcc\t%1, 0, %0"
5947 [(set_attr "type" "compare")])
5948
5949
5950 ;; Floating point arithmetic instructions.
5951
5952 (define_expand "addtf3"
5953 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5954 (plus:TF (match_operand:TF 1 "general_operand" "")
5955 (match_operand:TF 2 "general_operand" "")))]
5956 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5957 "emit_tfmode_binop (PLUS, operands); DONE;")
5958
5959 (define_insn "*addtf3_hq"
5960 [(set (match_operand:TF 0 "register_operand" "=e")
5961 (plus:TF (match_operand:TF 1 "register_operand" "e")
5962 (match_operand:TF 2 "register_operand" "e")))]
5963 "TARGET_FPU && TARGET_HARD_QUAD"
5964 "faddq\t%1, %2, %0"
5965 [(set_attr "type" "fp")])
5966
5967 (define_insn "adddf3"
5968 [(set (match_operand:DF 0 "register_operand" "=e")
5969 (plus:DF (match_operand:DF 1 "register_operand" "e")
5970 (match_operand:DF 2 "register_operand" "e")))]
5971 "TARGET_FPU"
5972 "faddd\t%1, %2, %0"
5973 [(set_attr "type" "fp")
5974 (set_attr "fptype" "double")])
5975
5976 (define_insn "addsf3"
5977 [(set (match_operand:SF 0 "register_operand" "=f")
5978 (plus:SF (match_operand:SF 1 "register_operand" "f")
5979 (match_operand:SF 2 "register_operand" "f")))]
5980 "TARGET_FPU"
5981 "fadds\t%1, %2, %0"
5982 [(set_attr "type" "fp")])
5983
5984 (define_expand "subtf3"
5985 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5986 (minus:TF (match_operand:TF 1 "general_operand" "")
5987 (match_operand:TF 2 "general_operand" "")))]
5988 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5989 "emit_tfmode_binop (MINUS, operands); DONE;")
5990
5991 (define_insn "*subtf3_hq"
5992 [(set (match_operand:TF 0 "register_operand" "=e")
5993 (minus:TF (match_operand:TF 1 "register_operand" "e")
5994 (match_operand:TF 2 "register_operand" "e")))]
5995 "TARGET_FPU && TARGET_HARD_QUAD"
5996 "fsubq\t%1, %2, %0"
5997 [(set_attr "type" "fp")])
5998
5999 (define_insn "subdf3"
6000 [(set (match_operand:DF 0 "register_operand" "=e")
6001 (minus:DF (match_operand:DF 1 "register_operand" "e")
6002 (match_operand:DF 2 "register_operand" "e")))]
6003 "TARGET_FPU"
6004 "fsubd\t%1, %2, %0"
6005 [(set_attr "type" "fp")
6006 (set_attr "fptype" "double")])
6007
6008 (define_insn "subsf3"
6009 [(set (match_operand:SF 0 "register_operand" "=f")
6010 (minus:SF (match_operand:SF 1 "register_operand" "f")
6011 (match_operand:SF 2 "register_operand" "f")))]
6012 "TARGET_FPU"
6013 "fsubs\t%1, %2, %0"
6014 [(set_attr "type" "fp")])
6015
6016 (define_expand "multf3"
6017 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6018 (mult:TF (match_operand:TF 1 "general_operand" "")
6019 (match_operand:TF 2 "general_operand" "")))]
6020 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6021 "emit_tfmode_binop (MULT, operands); DONE;")
6022
6023 (define_insn "*multf3_hq"
6024 [(set (match_operand:TF 0 "register_operand" "=e")
6025 (mult:TF (match_operand:TF 1 "register_operand" "e")
6026 (match_operand:TF 2 "register_operand" "e")))]
6027 "TARGET_FPU && TARGET_HARD_QUAD"
6028 "fmulq\t%1, %2, %0"
6029 [(set_attr "type" "fpmul")])
6030
6031 (define_insn "muldf3"
6032 [(set (match_operand:DF 0 "register_operand" "=e")
6033 (mult:DF (match_operand:DF 1 "register_operand" "e")
6034 (match_operand:DF 2 "register_operand" "e")))]
6035 "TARGET_FPU"
6036 "fmuld\t%1, %2, %0"
6037 [(set_attr "type" "fpmul")
6038 (set_attr "fptype" "double")])
6039
6040 (define_insn "mulsf3"
6041 [(set (match_operand:SF 0 "register_operand" "=f")
6042 (mult:SF (match_operand:SF 1 "register_operand" "f")
6043 (match_operand:SF 2 "register_operand" "f")))]
6044 "TARGET_FPU"
6045 "fmuls\t%1, %2, %0"
6046 [(set_attr "type" "fpmul")])
6047
6048 (define_insn "fmadf4"
6049 [(set (match_operand:DF 0 "register_operand" "=e")
6050 (fma:DF (match_operand:DF 1 "register_operand" "e")
6051 (match_operand:DF 2 "register_operand" "e")
6052 (match_operand:DF 3 "register_operand" "e")))]
6053 "TARGET_FMAF"
6054 "fmaddd\t%1, %2, %3, %0"
6055 [(set_attr "type" "fpmul")])
6056
6057 (define_insn "fmsdf4"
6058 [(set (match_operand:DF 0 "register_operand" "=e")
6059 (fma:DF (match_operand:DF 1 "register_operand" "e")
6060 (match_operand:DF 2 "register_operand" "e")
6061 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
6062 "TARGET_FMAF"
6063 "fmsubd\t%1, %2, %3, %0"
6064 [(set_attr "type" "fpmul")])
6065
6066 (define_insn "*nfmadf4"
6067 [(set (match_operand:DF 0 "register_operand" "=e")
6068 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
6069 (match_operand:DF 2 "register_operand" "e")
6070 (match_operand:DF 3 "register_operand" "e"))))]
6071 "TARGET_FMAF"
6072 "fnmaddd\t%1, %2, %3, %0"
6073 [(set_attr "type" "fpmul")])
6074
6075 (define_insn "*nfmsdf4"
6076 [(set (match_operand:DF 0 "register_operand" "=e")
6077 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
6078 (match_operand:DF 2 "register_operand" "e")
6079 (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
6080 "TARGET_FMAF"
6081 "fnmsubd\t%1, %2, %3, %0"
6082 [(set_attr "type" "fpmul")])
6083
6084 (define_insn "fmasf4"
6085 [(set (match_operand:SF 0 "register_operand" "=f")
6086 (fma:SF (match_operand:SF 1 "register_operand" "f")
6087 (match_operand:SF 2 "register_operand" "f")
6088 (match_operand:SF 3 "register_operand" "f")))]
6089 "TARGET_FMAF"
6090 "fmadds\t%1, %2, %3, %0"
6091 [(set_attr "type" "fpmul")])
6092
6093 (define_insn "fmssf4"
6094 [(set (match_operand:SF 0 "register_operand" "=f")
6095 (fma:SF (match_operand:SF 1 "register_operand" "f")
6096 (match_operand:SF 2 "register_operand" "f")
6097 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
6098 "TARGET_FMAF"
6099 "fmsubs\t%1, %2, %3, %0"
6100 [(set_attr "type" "fpmul")])
6101
6102 (define_insn "*nfmasf4"
6103 [(set (match_operand:SF 0 "register_operand" "=f")
6104 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
6105 (match_operand:SF 2 "register_operand" "f")
6106 (match_operand:SF 3 "register_operand" "f"))))]
6107 "TARGET_FMAF"
6108 "fnmadds\t%1, %2, %3, %0"
6109 [(set_attr "type" "fpmul")])
6110
6111 (define_insn "*nfmssf4"
6112 [(set (match_operand:SF 0 "register_operand" "=f")
6113 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
6114 (match_operand:SF 2 "register_operand" "f")
6115 (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
6116 "TARGET_FMAF"
6117 "fnmsubs\t%1, %2, %3, %0"
6118 [(set_attr "type" "fpmul")])
6119
6120 (define_insn "*muldf3_extend"
6121 [(set (match_operand:DF 0 "register_operand" "=e")
6122 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6123 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6124 "TARGET_FSMULD"
6125 "fsmuld\t%1, %2, %0"
6126 [(set_attr "type" "fpmul")
6127 (set_attr "fptype" "double")])
6128
6129 (define_insn "*multf3_extend"
6130 [(set (match_operand:TF 0 "register_operand" "=e")
6131 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6132 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6133 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6134 "fdmulq\t%1, %2, %0"
6135 [(set_attr "type" "fpmul")])
6136
6137 (define_expand "divtf3"
6138 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6139 (div:TF (match_operand:TF 1 "general_operand" "")
6140 (match_operand:TF 2 "general_operand" "")))]
6141 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6142 "emit_tfmode_binop (DIV, operands); DONE;")
6143
6144 ;; don't have timing for quad-prec. divide.
6145 (define_insn "*divtf3_hq"
6146 [(set (match_operand:TF 0 "register_operand" "=e")
6147 (div:TF (match_operand:TF 1 "register_operand" "e")
6148 (match_operand:TF 2 "register_operand" "e")))]
6149 "TARGET_FPU && TARGET_HARD_QUAD"
6150 "fdivq\t%1, %2, %0"
6151 [(set_attr "type" "fpdivs")])
6152
6153 (define_expand "divdf3"
6154 [(set (match_operand:DF 0 "register_operand" "=e")
6155 (div:DF (match_operand:DF 1 "register_operand" "e")
6156 (match_operand:DF 2 "register_operand" "e")))]
6157 "TARGET_FPU"
6158 "")
6159
6160 (define_insn "*divdf3_nofix"
6161 [(set (match_operand:DF 0 "register_operand" "=e")
6162 (div:DF (match_operand:DF 1 "register_operand" "e")
6163 (match_operand:DF 2 "register_operand" "e")))]
6164 "TARGET_FPU && !sparc_fix_ut699"
6165 "fdivd\t%1, %2, %0"
6166 [(set_attr "type" "fpdivd")
6167 (set_attr "fptype" "double")])
6168
6169 (define_insn "*divdf3_fix"
6170 [(set (match_operand:DF 0 "register_operand" "=e")
6171 (div:DF (match_operand:DF 1 "register_operand" "e")
6172 (match_operand:DF 2 "register_operand" "e")))]
6173 "TARGET_FPU && sparc_fix_ut699"
6174 "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
6175 [(set_attr "type" "fpdivd")
6176 (set_attr "fptype" "double")
6177 (set_attr "length" "3")])
6178
6179 (define_insn "divsf3"
6180 [(set (match_operand:SF 0 "register_operand" "=f")
6181 (div:SF (match_operand:SF 1 "register_operand" "f")
6182 (match_operand:SF 2 "register_operand" "f")))]
6183 "TARGET_FPU && !sparc_fix_ut699"
6184 "fdivs\t%1, %2, %0"
6185 [(set_attr "type" "fpdivs")])
6186
6187 (define_expand "negtf2"
6188 [(set (match_operand:TF 0 "register_operand" "")
6189 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6190 "TARGET_FPU"
6191 "")
6192
6193 (define_insn "*negtf2_hq"
6194 [(set (match_operand:TF 0 "register_operand" "=e")
6195 (neg:TF (match_operand:TF 1 "register_operand" "e")))]
6196 "TARGET_FPU && TARGET_HARD_QUAD"
6197 "fnegq\t%1, %0"
6198 [(set_attr "type" "fpmove")])
6199
6200 (define_insn_and_split "*negtf2"
6201 [(set (match_operand:TF 0 "register_operand" "=e")
6202 (neg:TF (match_operand:TF 1 "register_operand" "e")))]
6203 "TARGET_FPU && !TARGET_HARD_QUAD"
6204 "#"
6205 "&& reload_completed"
6206 [(clobber (const_int 0))]
6207 {
6208 rtx set_dest = operands[0];
6209 rtx set_src = operands[1];
6210 rtx dest1, dest2;
6211 rtx src1, src2;
6212
6213 dest1 = gen_df_reg (set_dest, 0);
6214 dest2 = gen_df_reg (set_dest, 1);
6215 src1 = gen_df_reg (set_src, 0);
6216 src2 = gen_df_reg (set_src, 1);
6217
6218 /* Now emit using the real source and destination we found, swapping
6219 the order if we detect overlap. */
6220 if (reg_overlap_mentioned_p (dest1, src2))
6221 {
6222 emit_insn (gen_movdf (dest2, src2));
6223 emit_insn (gen_negdf2 (dest1, src1));
6224 }
6225 else
6226 {
6227 emit_insn (gen_negdf2 (dest1, src1));
6228 if (REGNO (dest2) != REGNO (src2))
6229 emit_insn (gen_movdf (dest2, src2));
6230 }
6231 DONE;
6232 }
6233 [(set_attr "length" "2")])
6234
6235 (define_expand "negdf2"
6236 [(set (match_operand:DF 0 "register_operand" "")
6237 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6238 "TARGET_FPU"
6239 "")
6240
6241 (define_insn_and_split "*negdf2_notv9"
6242 [(set (match_operand:DF 0 "register_operand" "=e")
6243 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6244 "TARGET_FPU && !TARGET_V9"
6245 "#"
6246 "&& reload_completed"
6247 [(clobber (const_int 0))]
6248 {
6249 rtx set_dest = operands[0];
6250 rtx set_src = operands[1];
6251 rtx dest1, dest2;
6252 rtx src1, src2;
6253
6254 dest1 = gen_highpart (SFmode, set_dest);
6255 dest2 = gen_lowpart (SFmode, set_dest);
6256 src1 = gen_highpart (SFmode, set_src);
6257 src2 = gen_lowpart (SFmode, set_src);
6258
6259 /* Now emit using the real source and destination we found, swapping
6260 the order if we detect overlap. */
6261 if (reg_overlap_mentioned_p (dest1, src2))
6262 {
6263 emit_insn (gen_movsf (dest2, src2));
6264 emit_insn (gen_negsf2 (dest1, src1));
6265 }
6266 else
6267 {
6268 emit_insn (gen_negsf2 (dest1, src1));
6269 if (REGNO (dest2) != REGNO (src2))
6270 emit_insn (gen_movsf (dest2, src2));
6271 }
6272 DONE;
6273 }
6274 [(set_attr "length" "2")])
6275
6276 (define_insn "*negdf2_v9"
6277 [(set (match_operand:DF 0 "register_operand" "=e")
6278 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6279 "TARGET_FPU && TARGET_V9"
6280 "fnegd\t%1, %0"
6281 [(set_attr "type" "fpmove")
6282 (set_attr "fptype" "double")])
6283
6284 (define_insn "negsf2"
6285 [(set (match_operand:SF 0 "register_operand" "=f")
6286 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6287 "TARGET_FPU"
6288 "fnegs\t%1, %0"
6289 [(set_attr "type" "fpmove")])
6290
6291 (define_expand "abstf2"
6292 [(set (match_operand:TF 0 "register_operand" "")
6293 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6294 "TARGET_FPU"
6295 "")
6296
6297 (define_insn "*abstf2_hq"
6298 [(set (match_operand:TF 0 "register_operand" "=e")
6299 (abs:TF (match_operand:TF 1 "register_operand" "e")))]
6300 "TARGET_FPU && TARGET_HARD_QUAD"
6301 "fabsq\t%1, %0"
6302 [(set_attr "type" "fpmove")])
6303
6304 (define_insn_and_split "*abstf2"
6305 [(set (match_operand:TF 0 "register_operand" "=e")
6306 (abs:TF (match_operand:TF 1 "register_operand" "e")))]
6307 "TARGET_FPU && !TARGET_HARD_QUAD"
6308 "#"
6309 "&& reload_completed"
6310 [(clobber (const_int 0))]
6311 {
6312 rtx set_dest = operands[0];
6313 rtx set_src = operands[1];
6314 rtx dest1, dest2;
6315 rtx src1, src2;
6316
6317 dest1 = gen_df_reg (set_dest, 0);
6318 dest2 = gen_df_reg (set_dest, 1);
6319 src1 = gen_df_reg (set_src, 0);
6320 src2 = gen_df_reg (set_src, 1);
6321
6322 /* Now emit using the real source and destination we found, swapping
6323 the order if we detect overlap. */
6324 if (reg_overlap_mentioned_p (dest1, src2))
6325 {
6326 emit_insn (gen_movdf (dest2, src2));
6327 emit_insn (gen_absdf2 (dest1, src1));
6328 }
6329 else
6330 {
6331 emit_insn (gen_absdf2 (dest1, src1));
6332 if (REGNO (dest2) != REGNO (src2))
6333 emit_insn (gen_movdf (dest2, src2));
6334 }
6335 DONE;
6336 }
6337 [(set_attr "length" "2")])
6338
6339 (define_expand "absdf2"
6340 [(set (match_operand:DF 0 "register_operand" "")
6341 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6342 "TARGET_FPU"
6343 "")
6344
6345 (define_insn_and_split "*absdf2_notv9"
6346 [(set (match_operand:DF 0 "register_operand" "=e")
6347 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6348 "TARGET_FPU && !TARGET_V9"
6349 "#"
6350 "&& reload_completed"
6351 [(clobber (const_int 0))]
6352 {
6353 rtx set_dest = operands[0];
6354 rtx set_src = operands[1];
6355 rtx dest1, dest2;
6356 rtx src1, src2;
6357
6358 dest1 = gen_highpart (SFmode, set_dest);
6359 dest2 = gen_lowpart (SFmode, set_dest);
6360 src1 = gen_highpart (SFmode, set_src);
6361 src2 = gen_lowpart (SFmode, set_src);
6362
6363 /* Now emit using the real source and destination we found, swapping
6364 the order if we detect overlap. */
6365 if (reg_overlap_mentioned_p (dest1, src2))
6366 {
6367 emit_insn (gen_movsf (dest2, src2));
6368 emit_insn (gen_abssf2 (dest1, src1));
6369 }
6370 else
6371 {
6372 emit_insn (gen_abssf2 (dest1, src1));
6373 if (REGNO (dest2) != REGNO (src2))
6374 emit_insn (gen_movsf (dest2, src2));
6375 }
6376 DONE;
6377 }
6378 [(set_attr "length" "2")])
6379
6380 (define_insn "*absdf2_v9"
6381 [(set (match_operand:DF 0 "register_operand" "=e")
6382 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6383 "TARGET_FPU && TARGET_V9"
6384 "fabsd\t%1, %0"
6385 [(set_attr "type" "fpmove")
6386 (set_attr "fptype" "double")])
6387
6388 (define_insn "abssf2"
6389 [(set (match_operand:SF 0 "register_operand" "=f")
6390 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6391 "TARGET_FPU"
6392 "fabss\t%1, %0"
6393 [(set_attr "type" "fpmove")])
6394
6395 (define_expand "sqrttf2"
6396 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6397 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6398 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6399 "emit_tfmode_unop (SQRT, operands); DONE;")
6400
6401 (define_insn "*sqrttf2_hq"
6402 [(set (match_operand:TF 0 "register_operand" "=e")
6403 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6404 "TARGET_FPU && TARGET_HARD_QUAD"
6405 "fsqrtq\t%1, %0"
6406 [(set_attr "type" "fpsqrts")])
6407
6408 (define_expand "sqrtdf2"
6409 [(set (match_operand:DF 0 "register_operand" "=e")
6410 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6411 "TARGET_FPU"
6412 "")
6413
6414 (define_insn "*sqrtdf2_nofix"
6415 [(set (match_operand:DF 0 "register_operand" "=e")
6416 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6417 "TARGET_FPU && !sparc_fix_ut699"
6418 "fsqrtd\t%1, %0"
6419 [(set_attr "type" "fpsqrtd")
6420 (set_attr "fptype" "double")])
6421
6422 (define_insn "*sqrtdf2_fix"
6423 [(set (match_operand:DF 0 "register_operand" "=e")
6424 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6425 "TARGET_FPU && sparc_fix_ut699"
6426 "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
6427 [(set_attr "type" "fpsqrtd")
6428 (set_attr "fptype" "double")
6429 (set_attr "length" "3")])
6430
6431 (define_insn "sqrtsf2"
6432 [(set (match_operand:SF 0 "register_operand" "=f")
6433 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6434 "TARGET_FPU && !sparc_fix_ut699"
6435 "fsqrts\t%1, %0"
6436 [(set_attr "type" "fpsqrts")])
6437
6438
6439 ;; Arithmetic shift instructions.
6440
6441 (define_insn "ashlsi3"
6442 [(set (match_operand:SI 0 "register_operand" "=r")
6443 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6444 (match_operand:SI 2 "arith_operand" "rI")))]
6445 ""
6446 {
6447 if (GET_CODE (operands[2]) == CONST_INT)
6448 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6449 return "sll\t%1, %2, %0";
6450 }
6451 [(set_attr "type" "shift")])
6452
6453 (define_expand "ashldi3"
6454 [(set (match_operand:DI 0 "register_operand" "=r")
6455 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6456 (match_operand:SI 2 "arith_operand" "rI")))]
6457 "TARGET_ARCH64 || TARGET_V8PLUS"
6458 {
6459 if (TARGET_ARCH32)
6460 {
6461 if (GET_CODE (operands[2]) == CONST_INT)
6462 FAIL;
6463 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6464 DONE;
6465 }
6466 })
6467
6468 (define_insn "*ashldi3_sp64"
6469 [(set (match_operand:DI 0 "register_operand" "=r")
6470 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6471 (match_operand:SI 2 "arith_operand" "rI")))]
6472 "TARGET_ARCH64"
6473 {
6474 if (GET_CODE (operands[2]) == CONST_INT)
6475 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6476 return "sllx\t%1, %2, %0";
6477 }
6478 [(set_attr "type" "shift")])
6479
6480 (define_insn "ashldi3_v8plus"
6481 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6482 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6483 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6484 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6485 "TARGET_V8PLUS"
6486 {
6487 return output_v8plus_shift (insn ,operands, \"sllx\");
6488 }
6489 [(set_attr "type" "multi")
6490 (set_attr "length" "5,5,6")])
6491
6492 (define_insn "*cmp_ccnz_ashift_1"
6493 [(set (reg:CCNZ CC_REG)
6494 (compare:CCNZ (ashift:SI (match_operand:SI 0 "register_operand" "r")
6495 (const_int 1))
6496 (const_int 0)))]
6497 ""
6498 "addcc\t%0, %0, %%g0"
6499 [(set_attr "type" "compare")])
6500
6501 (define_insn "*cmp_ccnz_set_ashift_1"
6502 [(set (reg:CCNZ CC_REG)
6503 (compare:CCNZ (ashift:SI (match_operand:SI 1 "register_operand" "r")
6504 (const_int 1))
6505 (const_int 0)))
6506 (set (match_operand:SI 0 "register_operand" "=r")
6507 (ashift:SI (match_dup 1) (const_int 1)))]
6508 ""
6509 "addcc\t%1, %1, %0"
6510 [(set_attr "type" "compare")])
6511
6512 (define_insn "ashrsi3"
6513 [(set (match_operand:SI 0 "register_operand" "=r")
6514 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6515 (match_operand:SI 2 "arith_operand" "rI")))]
6516 ""
6517 {
6518 if (GET_CODE (operands[2]) == CONST_INT)
6519 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6520 return "sra\t%1, %2, %0";
6521 }
6522 [(set_attr "type" "shift")])
6523
6524 (define_insn "*ashrsi3_extend0"
6525 [(set (match_operand:DI 0 "register_operand" "=r")
6526 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6527 (match_operand:SI 2 "arith_operand" "rI"))))]
6528 "TARGET_ARCH64"
6529 {
6530 if (GET_CODE (operands[2]) == CONST_INT)
6531 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6532 return "sra\t%1, %2, %0";
6533 }
6534 [(set_attr "type" "shift")])
6535
6536 ;; This handles the case where
6537 ;; (sign_extend:DI (ashiftrt:SI (match_operand:SI) (match_operand:SI)))
6538 ;; but combiner "simplifies" it for us.
6539 (define_insn "*ashrsi3_extend1"
6540 [(set (match_operand:DI 0 "register_operand" "=r")
6541 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6542 (const_int 32))
6543 (match_operand:SI 2 "small_int_operand" "I")))]
6544 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6545 {
6546 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6547 return "sra\t%1, %2, %0";
6548 }
6549 [(set_attr "type" "shift")])
6550
6551 ;; This handles the case where
6552 ;; (ashiftrt:DI (sign_extend:DI (match_operand:SI)) (const_int))
6553 ;; but combiner "simplifies" it for us.
6554 (define_insn "*ashrsi3_extend2"
6555 [(set (match_operand:DI 0 "register_operand" "=r")
6556 (sign_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6557 (match_operand 2 "small_int_operand" "I")
6558 (const_int 32)))]
6559 "TARGET_ARCH64 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 32"
6560 {
6561 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6562 return "sra\t%1, %2, %0";
6563 }
6564 [(set_attr "type" "shift")])
6565
6566 (define_expand "ashrdi3"
6567 [(set (match_operand:DI 0 "register_operand" "=r")
6568 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6569 (match_operand:SI 2 "arith_operand" "rI")))]
6570 "TARGET_ARCH64 || TARGET_V8PLUS"
6571 {
6572 if (TARGET_ARCH32)
6573 {
6574 if (GET_CODE (operands[2]) == CONST_INT)
6575 FAIL; /* prefer generic code in this case */
6576 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6577 DONE;
6578 }
6579 })
6580
6581 (define_insn "*ashrdi3_sp64"
6582 [(set (match_operand:DI 0 "register_operand" "=r")
6583 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6584 (match_operand:SI 2 "arith_operand" "rI")))]
6585 "TARGET_ARCH64"
6586 {
6587 if (GET_CODE (operands[2]) == CONST_INT)
6588 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6589 return "srax\t%1, %2, %0";
6590 }
6591 [(set_attr "type" "shift")])
6592
6593 (define_insn "ashrdi3_v8plus"
6594 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6595 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6596 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6597 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6598 "TARGET_V8PLUS"
6599 {
6600 return output_v8plus_shift (insn, operands, \"srax\");
6601 }
6602 [(set_attr "type" "multi")
6603 (set_attr "length" "5,5,6")])
6604
6605 (define_insn "lshrsi3"
6606 [(set (match_operand:SI 0 "register_operand" "=r")
6607 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6608 (match_operand:SI 2 "arith_operand" "rI")))]
6609 ""
6610 {
6611 if (GET_CODE (operands[2]) == CONST_INT)
6612 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6613 return "srl\t%1, %2, %0";
6614 }
6615 [(set_attr "type" "shift")])
6616
6617 (define_insn "*lshrsi3_extend0"
6618 [(set (match_operand:DI 0 "register_operand" "=r")
6619 (zero_extend:DI
6620 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6621 (match_operand:SI 2 "arith_operand" "rI"))))]
6622 "TARGET_ARCH64"
6623 {
6624 if (GET_CODE (operands[2]) == CONST_INT)
6625 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6626 return "srl\t%1, %2, %0";
6627 }
6628 [(set_attr "type" "shift")])
6629
6630 ;; This handles the case where
6631 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI)))
6632 ;; but combiner "simplifies" it for us.
6633 (define_insn "*lshrsi3_extend1"
6634 [(set (match_operand:DI 0 "register_operand" "=r")
6635 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6636 (match_operand:SI 2 "arith_operand" "rI")) 0)
6637 (match_operand 3 "const_int_operand" "")))]
6638 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6639 {
6640 if (GET_CODE (operands[2]) == CONST_INT)
6641 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6642 return "srl\t%1, %2, %0";
6643 }
6644 [(set_attr "type" "shift")])
6645
6646 ;; This handles the case where
6647 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int))
6648 ;; but combiner "simplifies" it for us.
6649 (define_insn "*lshrsi3_extend2"
6650 [(set (match_operand:DI 0 "register_operand" "=r")
6651 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6652 (match_operand 2 "small_int_operand" "I")
6653 (const_int 32)))]
6654 "TARGET_ARCH64 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 32"
6655 {
6656 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6657 return "srl\t%1, %2, %0";
6658 }
6659 [(set_attr "type" "shift")])
6660
6661 (define_expand "lshrdi3"
6662 [(set (match_operand:DI 0 "register_operand" "=r")
6663 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6664 (match_operand:SI 2 "arith_operand" "rI")))]
6665 "TARGET_ARCH64 || TARGET_V8PLUS"
6666 {
6667 if (TARGET_ARCH32)
6668 {
6669 if (GET_CODE (operands[2]) == CONST_INT)
6670 FAIL;
6671 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6672 DONE;
6673 }
6674 })
6675
6676 (define_insn "*lshrdi3_sp64"
6677 [(set (match_operand:DI 0 "register_operand" "=r")
6678 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6679 (match_operand:SI 2 "arith_operand" "rI")))]
6680 "TARGET_ARCH64"
6681 {
6682 if (GET_CODE (operands[2]) == CONST_INT)
6683 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6684 return "srlx\t%1, %2, %0";
6685 }
6686 [(set_attr "type" "shift")])
6687
6688 (define_insn "lshrdi3_v8plus"
6689 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6690 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6691 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6692 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6693 "TARGET_V8PLUS"
6694 {
6695 return output_v8plus_shift (insn, operands, \"srlx\");
6696 }
6697 [(set_attr "type" "multi")
6698 (set_attr "length" "5,5,6")])
6699
6700 (define_insn ""
6701 [(set (match_operand:SI 0 "register_operand" "=r")
6702 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6703 (const_int 32)) 4)
6704 (match_operand:SI 2 "small_int_operand" "I")))]
6705 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6706 {
6707 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6708 return "srax\t%1, %2, %0";
6709 }
6710 [(set_attr "type" "shift")])
6711
6712 (define_insn ""
6713 [(set (match_operand:SI 0 "register_operand" "=r")
6714 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6715 (const_int 32)) 4)
6716 (match_operand:SI 2 "small_int_operand" "I")))]
6717 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6718 {
6719 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6720 return "srlx\t%1, %2, %0";
6721 }
6722 [(set_attr "type" "shift")])
6723
6724 (define_insn ""
6725 [(set (match_operand:SI 0 "register_operand" "=r")
6726 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6727 (match_operand:SI 2 "small_int_operand" "I")) 4)
6728 (match_operand:SI 3 "small_int_operand" "I")))]
6729 "TARGET_ARCH64
6730 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6731 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6732 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6733 {
6734 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6735
6736 return "srax\t%1, %2, %0";
6737 }
6738 [(set_attr "type" "shift")])
6739
6740 (define_insn ""
6741 [(set (match_operand:SI 0 "register_operand" "=r")
6742 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6743 (match_operand:SI 2 "small_int_operand" "I")) 4)
6744 (match_operand:SI 3 "small_int_operand" "I")))]
6745 "TARGET_ARCH64
6746 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6747 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6748 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6749 {
6750 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6751
6752 return "srlx\t%1, %2, %0";
6753 }
6754 [(set_attr "type" "shift")])
6755
6756
6757 ;; Unconditional and other jump instructions.
6758
6759 (define_expand "jump"
6760 [(set (pc) (label_ref (match_operand 0 "" "")))]
6761 "")
6762
6763 (define_insn "*jump_ubranch"
6764 [(set (pc) (label_ref (match_operand 0 "" "")))]
6765 "!TARGET_CBCOND"
6766 {
6767 return output_ubranch (operands[0], insn);
6768 }
6769 [(set_attr "type" "uncond_branch")])
6770
6771 (define_insn "*jump_cbcond"
6772 [(set (pc) (label_ref (match_operand 0 "" "")))]
6773 "TARGET_CBCOND"
6774 {
6775 return output_ubranch (operands[0], insn);
6776 }
6777 [(set_attr "type" "uncond_cbcond")])
6778
6779 (define_expand "tablejump"
6780 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6781 (use (label_ref (match_operand 1 "" "")))])]
6782 ""
6783 {
6784 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6785
6786 /* In pic mode, our address differences are against the base of the
6787 table. Add that base value back in; CSE ought to be able to combine
6788 the two address loads. */
6789 if (flag_pic)
6790 {
6791 rtx tmp, tmp2;
6792 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6793 tmp2 = operands[0];
6794 if (CASE_VECTOR_MODE != Pmode)
6795 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6796 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6797 operands[0] = memory_address (Pmode, tmp);
6798 }
6799 })
6800
6801 (define_insn "*tablejump_sp32"
6802 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6803 (use (label_ref (match_operand 1 "" "")))]
6804 "TARGET_ARCH32"
6805 "jmp\t%a0%#"
6806 [(set_attr "type" "uncond_branch")])
6807
6808 (define_insn "*tablejump_sp64"
6809 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6810 (use (label_ref (match_operand 1 "" "")))]
6811 "TARGET_ARCH64"
6812 "jmp\t%a0%#"
6813 [(set_attr "type" "uncond_branch")])
6814
6815
6816 ;; Jump to subroutine instructions.
6817
6818 (define_expand "call"
6819 ;; Note that this expression is not used for generating RTL.
6820 ;; All the RTL is generated explicitly below.
6821 [(call (match_operand 0 "call_operand" "")
6822 (match_operand 3 "" "i"))]
6823 ;; operands[2] is next_arg_register
6824 ;; operands[3] is struct_value_size_rtx.
6825 ""
6826 {
6827 rtx fn_rtx;
6828
6829 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6830
6831 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6832
6833 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6834 {
6835 /* This is really a PIC sequence. We want to represent
6836 it as a funny jump so its delay slots can be filled.
6837
6838 ??? But if this really *is* a CALL, will not it clobber the
6839 call-clobbered registers? We lose this if it is a JUMP_INSN.
6840 Why cannot we have delay slots filled if it were a CALL? */
6841
6842 /* We accept negative sizes for untyped calls. */
6843 if (TARGET_ARCH32 && INTVAL (operands[3]) != 0)
6844 emit_jump_insn
6845 (gen_rtx_PARALLEL
6846 (VOIDmode,
6847 gen_rtvec (3,
6848 gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6849 operands[3],
6850 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6851 else
6852 emit_jump_insn
6853 (gen_rtx_PARALLEL
6854 (VOIDmode,
6855 gen_rtvec (2,
6856 gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6857 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6858 goto finish_call;
6859 }
6860
6861 fn_rtx = operands[0];
6862
6863 /* We accept negative sizes for untyped calls. */
6864 if (TARGET_ARCH32 && INTVAL (operands[3]) != 0)
6865 sparc_emit_call_insn
6866 (gen_rtx_PARALLEL
6867 (VOIDmode,
6868 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6869 operands[3],
6870 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6871 XEXP (fn_rtx, 0));
6872 else
6873 sparc_emit_call_insn
6874 (gen_rtx_PARALLEL
6875 (VOIDmode,
6876 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6877 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6878 XEXP (fn_rtx, 0));
6879
6880 finish_call:
6881
6882 DONE;
6883 })
6884
6885 ;; We can't use the same pattern for these two insns, because then registers
6886 ;; in the address may not be properly reloaded.
6887
6888 (define_insn "*call_address_sp32"
6889 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6890 (match_operand 1 "" ""))
6891 (clobber (reg:SI O7_REG))]
6892 ;;- Do not use operand 1 for most machines.
6893 "TARGET_ARCH32"
6894 "call\t%a0, %1%#"
6895 [(set_attr "type" "call")])
6896
6897 (define_insn "*call_symbolic_sp32"
6898 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6899 (match_operand 1 "" ""))
6900 (clobber (reg:SI O7_REG))]
6901 ;;- Do not use operand 1 for most machines.
6902 "TARGET_ARCH32"
6903 "call\t%a0, %1%#"
6904 [(set_attr "type" "call")])
6905
6906 (define_insn "*call_address_sp64"
6907 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6908 (match_operand 1 "" ""))
6909 (clobber (reg:DI O7_REG))]
6910 ;;- Do not use operand 1 for most machines.
6911 "TARGET_ARCH64"
6912 "call\t%a0, %1%#"
6913 [(set_attr "type" "call")])
6914
6915 (define_insn "*call_symbolic_sp64"
6916 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6917 (match_operand 1 "" ""))
6918 (clobber (reg:DI O7_REG))]
6919 ;;- Do not use operand 1 for most machines.
6920 "TARGET_ARCH64"
6921 "call\t%a0, %1%#"
6922 [(set_attr "type" "call")])
6923
6924 ;; This is a call that wants a structure value.
6925 ;; There is no such critter for v9 (??? we may need one anyway).
6926 (define_insn "*call_address_struct_value_sp32"
6927 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6928 (match_operand 1 "" ""))
6929 (match_operand 2 "immediate_operand" "")
6930 (clobber (reg:SI O7_REG))]
6931 ;;- Do not use operand 1 for most machines.
6932 "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6933 {
6934 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6935 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6936 }
6937 [(set_attr "type" "call_no_delay_slot")
6938 (set_attr "length" "3")])
6939
6940 ;; This is a call that wants a structure value.
6941 ;; There is no such critter for v9 (??? we may need one anyway).
6942 (define_insn "*call_symbolic_struct_value_sp32"
6943 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6944 (match_operand 1 "" ""))
6945 (match_operand 2 "immediate_operand" "")
6946 (clobber (reg:SI O7_REG))]
6947 ;;- Do not use operand 1 for most machines.
6948 "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6949 {
6950 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6951 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6952 }
6953 [(set_attr "type" "call_no_delay_slot")
6954 (set_attr "length" "3")])
6955
6956 ;; This is a call that may want a structure value. This is used for
6957 ;; untyped_calls.
6958 (define_insn "*call_address_untyped_struct_value_sp32"
6959 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6960 (match_operand 1 "" ""))
6961 (match_operand 2 "immediate_operand" "")
6962 (clobber (reg:SI O7_REG))]
6963 ;;- Do not use operand 1 for most machines.
6964 "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6965 "call\t%a0, %1\n\t nop\n\tnop"
6966 [(set_attr "type" "call_no_delay_slot")
6967 (set_attr "length" "3")])
6968
6969 ;; This is a call that may want a structure value. This is used for
6970 ;; untyped_calls.
6971 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6972 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6973 (match_operand 1 "" ""))
6974 (match_operand 2 "immediate_operand" "")
6975 (clobber (reg:SI O7_REG))]
6976 ;;- Do not use operand 1 for most machines.
6977 "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6978 "call\t%a0, %1\n\t nop\n\tnop"
6979 [(set_attr "type" "call_no_delay_slot")
6980 (set_attr "length" "3")])
6981
6982 (define_expand "call_value"
6983 ;; Note that this expression is not used for generating RTL.
6984 ;; All the RTL is generated explicitly below.
6985 [(set (match_operand 0 "register_operand" "=rf")
6986 (call (match_operand 1 "" "")
6987 (match_operand 4 "" "")))]
6988 ;; operand 2 is stack_size_rtx
6989 ;; operand 3 is next_arg_register
6990 ""
6991 {
6992 rtx fn_rtx;
6993 rtvec vec;
6994
6995 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6996
6997 fn_rtx = operands[1];
6998
6999 vec = gen_rtvec (2,
7000 gen_rtx_SET (operands[0],
7001 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7002 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7003
7004 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
7005
7006 DONE;
7007 })
7008
7009 (define_insn "*call_value_address_sp32"
7010 [(set (match_operand 0 "" "=rf")
7011 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7012 (match_operand 2 "" "")))
7013 (clobber (reg:SI O7_REG))]
7014 ;;- Do not use operand 2 for most machines.
7015 "TARGET_ARCH32"
7016 "call\t%a1, %2%#"
7017 [(set_attr "type" "call")])
7018
7019 (define_insn "*call_value_symbolic_sp32"
7020 [(set (match_operand 0 "" "=rf")
7021 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7022 (match_operand 2 "" "")))
7023 (clobber (reg:SI O7_REG))]
7024 ;;- Do not use operand 2 for most machines.
7025 "TARGET_ARCH32"
7026 "call\t%a1, %2%#"
7027 [(set_attr "type" "call")])
7028
7029 (define_insn "*call_value_address_sp64"
7030 [(set (match_operand 0 "" "")
7031 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7032 (match_operand 2 "" "")))
7033 (clobber (reg:DI O7_REG))]
7034 ;;- Do not use operand 2 for most machines.
7035 "TARGET_ARCH64"
7036 "call\t%a1, %2%#"
7037 [(set_attr "type" "call")])
7038
7039 (define_insn "*call_value_symbolic_sp64"
7040 [(set (match_operand 0 "" "")
7041 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7042 (match_operand 2 "" "")))
7043 (clobber (reg:DI O7_REG))]
7044 ;;- Do not use operand 2 for most machines.
7045 "TARGET_ARCH64"
7046 "call\t%a1, %2%#"
7047 [(set_attr "type" "call")])
7048
7049 (define_expand "untyped_call"
7050 [(parallel [(call (match_operand 0 "" "")
7051 (const_int 0))
7052 (match_operand:BLK 1 "memory_operand" "")
7053 (match_operand 2 "" "")])]
7054 ""
7055 {
7056 rtx valreg1 = gen_rtx_REG (DImode, 8);
7057 rtx result = operands[1];
7058
7059 /* Pass constm1 to indicate that it may expect a structure value, but
7060 we don't know what size it is. */
7061 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
7062
7063 /* Save the function value registers. */
7064 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
7065 if (TARGET_FPU)
7066 {
7067 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7068 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
7069 valreg2);
7070 }
7071
7072 /* The optimizer does not know that the call sets the function value
7073 registers we stored in the result block. We avoid problems by
7074 claiming that all hard registers are used and clobbered at this
7075 point. */
7076 emit_insn (gen_blockage ());
7077
7078 DONE;
7079 })
7080
7081
7082 ;; Tail call instructions.
7083
7084 (define_expand "sibcall"
7085 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7086 (return)])]
7087 ""
7088 "")
7089
7090 (define_insn "*sibcall_symbolic_sp32"
7091 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7092 (match_operand 1 "" ""))
7093 (return)]
7094 "TARGET_ARCH32"
7095 {
7096 return output_sibcall(insn, operands[0]);
7097 }
7098 [(set_attr "type" "sibcall")])
7099
7100 (define_insn "*sibcall_symbolic_sp64"
7101 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7102 (match_operand 1 "" ""))
7103 (return)]
7104 "TARGET_ARCH64"
7105 {
7106 return output_sibcall(insn, operands[0]);
7107 }
7108 [(set_attr "type" "sibcall")])
7109
7110 (define_expand "sibcall_value"
7111 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7112 (call (match_operand 1 "" "") (const_int 0)))
7113 (return)])]
7114 ""
7115 "")
7116
7117 (define_insn "*sibcall_value_symbolic_sp32"
7118 [(set (match_operand 0 "" "=rf")
7119 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7120 (match_operand 2 "" "")))
7121 (return)]
7122 "TARGET_ARCH32"
7123 {
7124 return output_sibcall(insn, operands[1]);
7125 }
7126 [(set_attr "type" "sibcall")])
7127
7128 (define_insn "*sibcall_value_symbolic_sp64"
7129 [(set (match_operand 0 "" "")
7130 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7131 (match_operand 2 "" "")))
7132 (return)]
7133 "TARGET_ARCH64"
7134 {
7135 return output_sibcall(insn, operands[1]);
7136 }
7137 [(set_attr "type" "sibcall")])
7138
7139
7140 ;; Special instructions.
7141
7142 (define_expand "prologue"
7143 [(const_int 0)]
7144 ""
7145 {
7146 if (TARGET_FLAT)
7147 sparc_flat_expand_prologue ();
7148 else
7149 sparc_expand_prologue ();
7150 DONE;
7151 })
7152
7153 ;; The "register window save" insn is modelled as follows. The dwarf2
7154 ;; information is manually added in emit_window_save.
7155
7156 (define_insn "window_save"
7157 [(unspec_volatile
7158 [(match_operand 0 "arith_operand" "rI")]
7159 UNSPECV_SAVEW)]
7160 "!TARGET_FLAT"
7161 "save\t%%sp, %0, %%sp"
7162 [(set_attr "type" "savew")])
7163
7164 (define_expand "epilogue"
7165 [(return)]
7166 ""
7167 {
7168 if (TARGET_FLAT)
7169 sparc_flat_expand_epilogue (false);
7170 else
7171 sparc_expand_epilogue (false);
7172 })
7173
7174 (define_expand "sibcall_epilogue"
7175 [(return)]
7176 ""
7177 {
7178 if (TARGET_FLAT)
7179 sparc_flat_expand_epilogue (false);
7180 else
7181 sparc_expand_epilogue (false);
7182 DONE;
7183 })
7184
7185 (define_expand "eh_return"
7186 [(use (match_operand 0 "general_operand" ""))]
7187 ""
7188 {
7189 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
7190 emit_jump_insn (gen_eh_return_internal ());
7191 emit_barrier ();
7192 DONE;
7193 })
7194
7195 (define_insn_and_split "eh_return_internal"
7196 [(eh_return)]
7197 ""
7198 "#"
7199 "epilogue_completed"
7200 [(return)]
7201 {
7202 if (TARGET_FLAT)
7203 sparc_flat_expand_epilogue (true);
7204 else
7205 sparc_expand_epilogue (true);
7206 })
7207
7208 (define_expand "return"
7209 [(return)]
7210 "sparc_can_use_return_insn_p ()"
7211 {
7212 if (cfun->calls_alloca)
7213 emit_insn (gen_frame_blockage ());
7214 })
7215
7216 (define_insn "*return_internal"
7217 [(return)]
7218 ""
7219 {
7220 return output_return (insn);
7221 }
7222 [(set_attr "type" "return")
7223 (set (attr "length")
7224 (cond [(eq_attr "calls_eh_return" "true")
7225 (if_then_else (eq_attr "delayed_branch" "true")
7226 (if_then_else (ior (eq_attr "isa" "v9")
7227 (eq_attr "flat" "true"))
7228 (const_int 2)
7229 (const_int 3))
7230 (if_then_else (eq_attr "flat" "true")
7231 (const_int 3)
7232 (const_int 4)))
7233 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
7234 (if_then_else (eq_attr "empty_delay_slot" "true")
7235 (const_int 2)
7236 (const_int 1))
7237 (eq_attr "empty_delay_slot" "true")
7238 (if_then_else (eq_attr "delayed_branch" "true")
7239 (const_int 2)
7240 (const_int 3))
7241 ] (const_int 1)))])
7242
7243 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7244 ;; all of memory. This blocks insns from being moved across this point.
7245
7246 (define_insn "blockage"
7247 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7248 ""
7249 ""
7250 [(set_attr "length" "0")])
7251
7252 ;; Do not schedule instructions accessing memory before this point.
7253
7254 (define_expand "frame_blockage"
7255 [(set (match_dup 0)
7256 (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
7257 ""
7258 {
7259 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7260 MEM_VOLATILE_P (operands[0]) = 1;
7261 operands[1] = stack_pointer_rtx;
7262 })
7263
7264 (define_insn "*frame_blockage<P:mode>"
7265 [(set (match_operand:BLK 0 "" "")
7266 (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
7267 ""
7268 ""
7269 [(set_attr "length" "0")])
7270
7271 (define_expand "probe_stack"
7272 [(set (match_operand 0 "memory_operand" "") (const_int 0))]
7273 ""
7274 {
7275 operands[0]
7276 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
7277 })
7278
7279 (define_insn "probe_stack_range<P:mode>"
7280 [(set (match_operand:P 0 "register_operand" "=r")
7281 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
7282 (match_operand:P 2 "register_operand" "r")]
7283 UNSPECV_PROBE_STACK_RANGE))]
7284 ""
7285 {
7286 return output_probe_stack_range (operands[0], operands[2]);
7287 }
7288 [(set_attr "type" "multi")])
7289
7290 ;; Prepare to return any type including a structure value.
7291
7292 (define_expand "untyped_return"
7293 [(match_operand:BLK 0 "memory_operand" "")
7294 (match_operand 1 "" "")]
7295 ""
7296 {
7297 rtx valreg1 = gen_rtx_REG (DImode, 24);
7298 rtx result = operands[0];
7299
7300 if (TARGET_ARCH32)
7301 {
7302 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
7303 rtx value = gen_reg_rtx (SImode);
7304
7305 /* Fetch the instruction where we will return to and see if it's an unimp
7306 instruction (the most significant 10 bits will be zero). If so,
7307 update the return address to skip the unimp instruction. */
7308 emit_move_insn (value,
7309 gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
7310 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7311 emit_insn (gen_update_return (rtnreg, value));
7312 }
7313
7314 /* Reload the function value registers.
7315 Put USE insns before the return. */
7316 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7317 emit_use (valreg1);
7318
7319 if (TARGET_FPU)
7320 {
7321 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7322 emit_move_insn (valreg2,
7323 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7324 emit_use (valreg2);
7325 }
7326
7327 /* Construct the return. */
7328 expand_naked_return ();
7329
7330 DONE;
7331 })
7332
7333 ;; Adjust the return address conditionally. If the value of op1 is equal
7334 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
7335 ;; This is technically *half* the check required by the 32-bit SPARC
7336 ;; psABI. This check only ensures that an "unimp" insn was written by
7337 ;; the caller, but doesn't check to see if the expected size matches
7338 ;; (this is encoded in the 12 lower bits). This check is obsolete and
7339 ;; only used by the above code "untyped_return".
7340
7341 (define_insn "update_return"
7342 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7343 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7344 "TARGET_ARCH32"
7345 {
7346 if (flag_delayed_branch)
7347 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7348 else
7349 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7350 }
7351 [(set (attr "type") (const_string "multi"))
7352 (set (attr "length")
7353 (if_then_else (eq_attr "delayed_branch" "true")
7354 (const_int 3)
7355 (const_int 4)))])
7356 \f
7357 (define_insn "nop"
7358 [(const_int 0)]
7359 ""
7360 "nop")
7361
7362 (define_expand "indirect_jump"
7363 [(set (pc) (match_operand 0 "address_operand" "p"))]
7364 ""
7365 "")
7366
7367 (define_insn "*branch_sp32"
7368 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7369 "TARGET_ARCH32"
7370 "jmp\t%a0%#"
7371 [(set_attr "type" "uncond_branch")])
7372
7373 (define_insn "*branch_sp64"
7374 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7375 "TARGET_ARCH64"
7376 "jmp\t%a0%#"
7377 [(set_attr "type" "uncond_branch")])
7378
7379 (define_expand "save_stack_nonlocal"
7380 [(set (match_operand 0 "memory_operand" "")
7381 (match_operand 1 "register_operand" ""))
7382 (set (match_dup 2) (match_dup 3))]
7383 ""
7384 {
7385 operands[0] = adjust_address (operands[0], Pmode, 0);
7386 operands[2] = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
7387 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
7388 })
7389
7390 (define_expand "restore_stack_nonlocal"
7391 [(set (match_operand 0 "register_operand" "")
7392 (match_operand 1 "memory_operand" ""))]
7393 ""
7394 {
7395 operands[1] = adjust_address (operands[1], Pmode, 0);
7396 })
7397
7398 (define_expand "nonlocal_goto"
7399 [(match_operand 0 "general_operand" "")
7400 (match_operand 1 "general_operand" "")
7401 (match_operand 2 "memory_operand" "")
7402 (match_operand 3 "memory_operand" "")]
7403 ""
7404 {
7405 rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
7406 rtx r_label = copy_to_reg (operands[1]);
7407 rtx r_sp = adjust_address (operands[2], Pmode, 0);
7408 rtx r_fp = operands[3];
7409 rtx r_i7 = adjust_address (operands[2], Pmode, GET_MODE_SIZE (Pmode));
7410
7411 /* We need to flush all the register windows so that their contents will
7412 be re-synchronized by the restore insn of the target function. */
7413 if (!TARGET_FLAT)
7414 emit_insn (gen_flush_register_windows ());
7415
7416 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7417 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7418
7419 /* Restore frame pointer for containing function. */
7420 emit_move_insn (hard_frame_pointer_rtx, r_fp);
7421 emit_stack_restore (SAVE_NONLOCAL, r_sp);
7422 emit_move_insn (i7, r_i7);
7423
7424 /* USE of hard_frame_pointer_rtx added for consistency;
7425 not clear if really needed. */
7426 emit_use (hard_frame_pointer_rtx);
7427 emit_use (stack_pointer_rtx);
7428 emit_use (i7);
7429
7430 emit_jump_insn (gen_indirect_jump (r_label));
7431 emit_barrier ();
7432 DONE;
7433 })
7434
7435 (define_expand "builtin_setjmp_receiver"
7436 [(label_ref (match_operand 0 "" ""))]
7437 "flag_pic"
7438 {
7439 load_got_register ();
7440 DONE;
7441 })
7442
7443 ;; Special insn to flush register windows.
7444
7445 (define_insn "flush_register_windows"
7446 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7447 ""
7448 {
7449 return TARGET_V9 ? "flushw" : "ta\t3";
7450 }
7451 [(set_attr "type" "flushw")])
7452
7453 ;; Special pattern for the FLUSH instruction.
7454
7455 (define_insn "flush<P:mode>"
7456 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7457 ""
7458 {
7459 return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0";
7460 }
7461 [(set_attr "type" "iflush")])
7462
7463 ;; Special insns to load and store the 32-bit FP Status Register.
7464
7465 (define_insn "ldfsr"
7466 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
7467 "TARGET_FPU"
7468 "ld\t%0, %%fsr"
7469 [(set_attr "type" "load")
7470 (set_attr "subtype" "regular")])
7471
7472 (define_insn "stfsr"
7473 [(set (match_operand:SI 0 "memory_operand" "=m")
7474 (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
7475 "TARGET_FPU"
7476 "st\t%%fsr, %0"
7477 [(set_attr "type" "store")])
7478
7479
7480 ;; Find first set instructions.
7481
7482 (define_expand "popcountdi2"
7483 [(set (match_operand:DI 0 "register_operand" "")
7484 (popcount:DI (match_operand:DI 1 "register_operand" "")))]
7485 "TARGET_POPC"
7486 {
7487 if (TARGET_ARCH32)
7488 {
7489 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
7490 DONE;
7491 }
7492 })
7493
7494 (define_insn "*popcountdi_sp64"
7495 [(set (match_operand:DI 0 "register_operand" "=r")
7496 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
7497 "TARGET_POPC && TARGET_ARCH64"
7498 "popc\t%1, %0")
7499
7500 (define_insn "popcountdi_v8plus"
7501 [(set (match_operand:DI 0 "register_operand" "=r")
7502 (popcount:DI (match_operand:DI 1 "register_operand" "r")))
7503 (clobber (match_scratch:SI 2 "=&h"))]
7504 "TARGET_POPC && TARGET_ARCH32"
7505 {
7506 if (sparc_check_64 (operands[1], insn) <= 0)
7507 output_asm_insn ("srl\t%L1, 0, %L1", operands);
7508 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
7509 }
7510 [(set_attr "type" "multi")
7511 (set_attr "length" "5")])
7512
7513 (define_expand "popcountsi2"
7514 [(set (match_dup 2)
7515 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
7516 (set (match_operand:SI 0 "register_operand" "")
7517 (truncate:SI (popcount:DI (match_dup 2))))]
7518 "TARGET_POPC"
7519 {
7520 if (TARGET_ARCH32)
7521 {
7522 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
7523 DONE;
7524 }
7525 else
7526 operands[2] = gen_reg_rtx (DImode);
7527 })
7528
7529 (define_insn "*popcountsi_sp64"
7530 [(set (match_operand:SI 0 "register_operand" "=r")
7531 (truncate:SI
7532 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
7533 "TARGET_POPC && TARGET_ARCH64"
7534 "popc\t%1, %0")
7535
7536 (define_insn "popcountsi_v8plus"
7537 [(set (match_operand:SI 0 "register_operand" "=r")
7538 (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
7539 "TARGET_POPC && TARGET_ARCH32"
7540 {
7541 if (sparc_check_64 (operands[1], insn) <= 0)
7542 output_asm_insn ("srl\t%1, 0, %1", operands);
7543 return "popc\t%1, %0";
7544 }
7545 [(set_attr "type" "multi")
7546 (set_attr "length" "2")])
7547
7548 (define_expand "clzdi2"
7549 [(set (match_operand:DI 0 "register_operand" "")
7550 (clz:DI (match_operand:DI 1 "register_operand" "")))]
7551 "TARGET_VIS3"
7552 {
7553 if (TARGET_ARCH32)
7554 {
7555 emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
7556 DONE;
7557 }
7558 })
7559
7560 (define_insn "*clzdi_sp64"
7561 [(set (match_operand:DI 0 "register_operand" "=r")
7562 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
7563 "TARGET_VIS3 && TARGET_ARCH64"
7564 "lzd\t%1, %0"
7565 [(set_attr "type" "lzd")])
7566
7567 (define_insn "clzdi_v8plus"
7568 [(set (match_operand:DI 0 "register_operand" "=r")
7569 (clz:DI (match_operand:DI 1 "register_operand" "r")))
7570 (clobber (match_scratch:SI 2 "=&h"))]
7571 "TARGET_VIS3 && TARGET_ARCH32"
7572 {
7573 if (sparc_check_64 (operands[1], insn) <= 0)
7574 output_asm_insn ("srl\t%L1, 0, %L1", operands);
7575 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
7576 }
7577 [(set_attr "type" "multi")
7578 (set_attr "length" "5")])
7579
7580 (define_expand "clzsi2"
7581 [(set (match_dup 2)
7582 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
7583 (set (match_dup 3)
7584 (truncate:SI (clz:DI (match_dup 2))))
7585 (set (match_operand:SI 0 "register_operand" "")
7586 (minus:SI (match_dup 3) (const_int 32)))]
7587 "TARGET_VIS3"
7588 {
7589 if (TARGET_ARCH32)
7590 {
7591 emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
7592 DONE;
7593 }
7594 else
7595 {
7596 operands[2] = gen_reg_rtx (DImode);
7597 operands[3] = gen_reg_rtx (SImode);
7598 }
7599 })
7600
7601 (define_insn "*clzsi_sp64"
7602 [(set (match_operand:SI 0 "register_operand" "=r")
7603 (truncate:SI
7604 (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
7605 "TARGET_VIS3 && TARGET_ARCH64"
7606 "lzd\t%1, %0"
7607 [(set_attr "type" "lzd")])
7608
7609 (define_insn "clzsi_v8plus"
7610 [(set (match_operand:SI 0 "register_operand" "=r")
7611 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
7612 "TARGET_VIS3 && TARGET_ARCH32"
7613 {
7614 if (sparc_check_64 (operands[1], insn) <= 0)
7615 output_asm_insn ("srl\t%1, 0, %1", operands);
7616 return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
7617 }
7618 [(set_attr "type" "multi")
7619 (set_attr "length" "3")])
7620
7621 \f
7622 ;; Peepholes go at the end.
7623
7624 ;; Optimize consecutive loads or stores into ldd and std when possible.
7625 ;; The conditions in which we do this are very restricted and are
7626 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7627
7628 (define_peephole2
7629 [(set (match_operand:SI 0 "memory_operand" "")
7630 (const_int 0))
7631 (set (match_operand:SI 1 "memory_operand" "")
7632 (const_int 0))]
7633 "TARGET_V9
7634 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7635 [(set (match_dup 0) (const_int 0))]
7636 {
7637 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
7638 })
7639
7640 (define_peephole2
7641 [(set (match_operand:SI 0 "memory_operand" "")
7642 (const_int 0))
7643 (set (match_operand:SI 1 "memory_operand" "")
7644 (const_int 0))]
7645 "TARGET_V9
7646 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7647 [(set (match_dup 1) (const_int 0))]
7648 {
7649 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
7650 })
7651
7652 (define_peephole2
7653 [(set (match_operand:SI 0 "register_operand" "")
7654 (match_operand:SI 1 "memory_operand" ""))
7655 (set (match_operand:SI 2 "register_operand" "")
7656 (match_operand:SI 3 "memory_operand" ""))]
7657 "registers_ok_for_ldd_peep (operands[0], operands[2])
7658 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7659 [(set (match_dup 0) (match_dup 1))]
7660 {
7661 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
7662 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
7663 })
7664
7665 (define_peephole2
7666 [(set (match_operand:SI 0 "memory_operand" "")
7667 (match_operand:SI 1 "register_operand" ""))
7668 (set (match_operand:SI 2 "memory_operand" "")
7669 (match_operand:SI 3 "register_operand" ""))]
7670 "registers_ok_for_ldd_peep (operands[1], operands[3])
7671 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7672 [(set (match_dup 0) (match_dup 1))]
7673 {
7674 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
7675 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
7676 })
7677
7678 (define_peephole2
7679 [(set (match_operand:SF 0 "register_operand" "")
7680 (match_operand:SF 1 "memory_operand" ""))
7681 (set (match_operand:SF 2 "register_operand" "")
7682 (match_operand:SF 3 "memory_operand" ""))]
7683 "registers_ok_for_ldd_peep (operands[0], operands[2])
7684 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7685 [(set (match_dup 0) (match_dup 1))]
7686 {
7687 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7688 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7689 })
7690
7691 (define_peephole2
7692 [(set (match_operand:SF 0 "memory_operand" "")
7693 (match_operand:SF 1 "register_operand" ""))
7694 (set (match_operand:SF 2 "memory_operand" "")
7695 (match_operand:SF 3 "register_operand" ""))]
7696 "registers_ok_for_ldd_peep (operands[1], operands[3])
7697 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7698 [(set (match_dup 0) (match_dup 1))]
7699 {
7700 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7701 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7702 })
7703
7704 (define_peephole2
7705 [(set (match_operand:SI 0 "register_operand" "")
7706 (match_operand:SI 1 "memory_operand" ""))
7707 (set (match_operand:SI 2 "register_operand" "")
7708 (match_operand:SI 3 "memory_operand" ""))]
7709 "registers_ok_for_ldd_peep (operands[2], operands[0])
7710 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7711 [(set (match_dup 2) (match_dup 3))]
7712 {
7713 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7714 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7715 })
7716
7717 (define_peephole2
7718 [(set (match_operand:SI 0 "memory_operand" "")
7719 (match_operand:SI 1 "register_operand" ""))
7720 (set (match_operand:SI 2 "memory_operand" "")
7721 (match_operand:SI 3 "register_operand" ""))]
7722 "registers_ok_for_ldd_peep (operands[3], operands[1])
7723 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7724 [(set (match_dup 2) (match_dup 3))]
7725 {
7726 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DImode);
7727 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7728 })
7729
7730 (define_peephole2
7731 [(set (match_operand:SF 0 "register_operand" "")
7732 (match_operand:SF 1 "memory_operand" ""))
7733 (set (match_operand:SF 2 "register_operand" "")
7734 (match_operand:SF 3 "memory_operand" ""))]
7735 "registers_ok_for_ldd_peep (operands[2], operands[0])
7736 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7737 [(set (match_dup 2) (match_dup 3))]
7738 {
7739 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7740 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7741 })
7742
7743 (define_peephole2
7744 [(set (match_operand:SF 0 "memory_operand" "")
7745 (match_operand:SF 1 "register_operand" ""))
7746 (set (match_operand:SF 2 "memory_operand" "")
7747 (match_operand:SF 3 "register_operand" ""))]
7748 "registers_ok_for_ldd_peep (operands[3], operands[1])
7749 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7750 [(set (match_dup 2) (match_dup 3))]
7751 {
7752 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7753 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7754 })
7755
7756 ;; Optimize the case of following a reg-reg move with a test
7757 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7758 ;; This can result from a float to fix conversion.
7759
7760 (define_peephole2
7761 [(set (match_operand:SI 0 "register_operand" "")
7762 (match_operand:SI 1 "register_operand" ""))
7763 (set (reg:CC CC_REG)
7764 (compare:CC (match_operand:SI 2 "register_operand" "")
7765 (const_int 0)))]
7766 "(rtx_equal_p (operands[2], operands[0])
7767 || rtx_equal_p (operands[2], operands[1]))
7768 && !SPARC_FP_REG_P (REGNO (operands[0]))
7769 && !SPARC_FP_REG_P (REGNO (operands[1]))"
7770 [(parallel [(set (match_dup 0) (match_dup 1))
7771 (set (reg:CC CC_REG)
7772 (compare:CC (match_dup 1) (const_int 0)))])]
7773 "")
7774
7775 (define_peephole2
7776 [(set (match_operand:DI 0 "register_operand" "")
7777 (match_operand:DI 1 "register_operand" ""))
7778 (set (reg:CCX CC_REG)
7779 (compare:CCX (match_operand:DI 2 "register_operand" "")
7780 (const_int 0)))]
7781 "TARGET_ARCH64
7782 && (rtx_equal_p (operands[2], operands[0])
7783 || rtx_equal_p (operands[2], operands[1]))
7784 && !SPARC_FP_REG_P (REGNO (operands[0]))
7785 && !SPARC_FP_REG_P (REGNO (operands[1]))"
7786 [(parallel [(set (match_dup 0) (match_dup 1))
7787 (set (reg:CCX CC_REG)
7788 (compare:CCX (match_dup 1) (const_int 0)))])]
7789 "")
7790
7791
7792 ;; Prefetch instructions.
7793
7794 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point
7795 ;; register file, if it hits the prefetch cache, has a chance to dual-issue
7796 ;; with other memory operations. With DFA we might be able to model this,
7797 ;; but it requires a lot of state.
7798 (define_expand "prefetch"
7799 [(match_operand 0 "address_operand" "")
7800 (match_operand 1 "const_int_operand" "")
7801 (match_operand 2 "const_int_operand" "")]
7802 "TARGET_V9"
7803 {
7804 if (TARGET_ARCH64)
7805 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7806 else
7807 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7808 DONE;
7809 })
7810
7811 (define_insn "prefetch_64"
7812 [(prefetch (match_operand:DI 0 "address_operand" "p")
7813 (match_operand:DI 1 "const_int_operand" "n")
7814 (match_operand:DI 2 "const_int_operand" "n"))]
7815 ""
7816 {
7817 static const char * const prefetch_instr[2][2] = {
7818 {
7819 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7820 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7821 },
7822 {
7823 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7824 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7825 }
7826 };
7827 int read_or_write = INTVAL (operands[1]);
7828 int locality = INTVAL (operands[2]);
7829
7830 gcc_assert (read_or_write == 0 || read_or_write == 1);
7831 gcc_assert (locality >= 0 && locality < 4);
7832 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7833 }
7834 [(set_attr "type" "load")
7835 (set_attr "subtype" "prefetch")])
7836
7837 (define_insn "prefetch_32"
7838 [(prefetch (match_operand:SI 0 "address_operand" "p")
7839 (match_operand:SI 1 "const_int_operand" "n")
7840 (match_operand:SI 2 "const_int_operand" "n"))]
7841 ""
7842 {
7843 static const char * const prefetch_instr[2][2] = {
7844 {
7845 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7846 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7847 },
7848 {
7849 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7850 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7851 }
7852 };
7853 int read_or_write = INTVAL (operands[1]);
7854 int locality = INTVAL (operands[2]);
7855
7856 gcc_assert (read_or_write == 0 || read_or_write == 1);
7857 gcc_assert (locality >= 0 && locality < 4);
7858 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7859 }
7860 [(set_attr "type" "load")
7861 (set_attr "subtype" "prefetch")])
7862
7863
7864 ;; Trap instructions.
7865
7866 (define_insn "trap"
7867 [(trap_if (const_int 1) (const_int 5))]
7868 ""
7869 "ta\t5"
7870 [(set_attr "type" "trap")])
7871
7872 (define_expand "ctrapsi4"
7873 [(trap_if (match_operator 0 "comparison_operator"
7874 [(match_operand:SI 1 "compare_operand" "")
7875 (match_operand:SI 2 "arith_operand" "")])
7876 (match_operand 3 "arith_operand"))]
7877 ""
7878 {
7879 operands[1] = gen_compare_reg (operands[0]);
7880 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7881 FAIL;
7882 operands[2] = const0_rtx;
7883 })
7884
7885 (define_expand "ctrapdi4"
7886 [(trap_if (match_operator 0 "comparison_operator"
7887 [(match_operand:DI 1 "compare_operand" "")
7888 (match_operand:DI 2 "arith_operand" "")])
7889 (match_operand 3 "arith_operand"))]
7890 "TARGET_ARCH64"
7891 {
7892 operands[1] = gen_compare_reg (operands[0]);
7893 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7894 FAIL;
7895 operands[2] = const0_rtx;
7896 })
7897
7898 (define_insn "*trapsi_insn"
7899 [(trap_if (match_operator 0 "icc_comparison_operator"
7900 [(reg:CC CC_REG) (const_int 0)])
7901 (match_operand:SI 1 "arith_operand" "rM"))]
7902 ""
7903 {
7904 if (TARGET_V9)
7905 return "t%C0\t%%icc, %1";
7906 else
7907 return "t%C0\t%1";
7908 }
7909 [(set_attr "type" "trap")])
7910
7911 (define_insn "*trapdi_insn"
7912 [(trap_if (match_operator 0 "icc_comparison_operator"
7913 [(reg:CCX CC_REG) (const_int 0)])
7914 (match_operand:SI 1 "arith_operand" "rM"))]
7915 "TARGET_V9"
7916 "t%C0\t%%xcc, %1"
7917 [(set_attr "type" "trap")])
7918
7919
7920 ;; TLS support instructions.
7921
7922 (define_insn "tgd_hi22"
7923 [(set (match_operand:SI 0 "register_operand" "=r")
7924 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7925 UNSPEC_TLSGD)))]
7926 "TARGET_TLS"
7927 "sethi\\t%%tgd_hi22(%a1), %0")
7928
7929 (define_insn "tgd_lo10"
7930 [(set (match_operand:SI 0 "register_operand" "=r")
7931 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7932 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7933 UNSPEC_TLSGD)))]
7934 "TARGET_TLS"
7935 "add\\t%1, %%tgd_lo10(%a2), %0")
7936
7937 (define_insn "tgd_add32"
7938 [(set (match_operand:SI 0 "register_operand" "=r")
7939 (plus:SI (match_operand:SI 1 "register_operand" "r")
7940 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7941 (match_operand 3 "tgd_symbolic_operand" "")]
7942 UNSPEC_TLSGD)))]
7943 "TARGET_TLS && TARGET_ARCH32"
7944 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7945
7946 (define_insn "tgd_add64"
7947 [(set (match_operand:DI 0 "register_operand" "=r")
7948 (plus:DI (match_operand:DI 1 "register_operand" "r")
7949 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7950 (match_operand 3 "tgd_symbolic_operand" "")]
7951 UNSPEC_TLSGD)))]
7952 "TARGET_TLS && TARGET_ARCH64"
7953 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7954
7955 (define_insn "tgd_call32"
7956 [(set (match_operand 0 "register_operand" "=r")
7957 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7958 (match_operand 2 "tgd_symbolic_operand" "")]
7959 UNSPEC_TLSGD))
7960 (match_operand 3 "" "")))
7961 (clobber (reg:SI O7_REG))]
7962 "TARGET_TLS && TARGET_ARCH32"
7963 "call\t%a1, %%tgd_call(%a2)%#"
7964 [(set_attr "type" "call")])
7965
7966 (define_insn "tgd_call64"
7967 [(set (match_operand 0 "register_operand" "=r")
7968 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7969 (match_operand 2 "tgd_symbolic_operand" "")]
7970 UNSPEC_TLSGD))
7971 (match_operand 3 "" "")))
7972 (clobber (reg:DI O7_REG))]
7973 "TARGET_TLS && TARGET_ARCH64"
7974 "call\t%a1, %%tgd_call(%a2)%#"
7975 [(set_attr "type" "call")])
7976
7977 (define_insn "tldm_hi22"
7978 [(set (match_operand:SI 0 "register_operand" "=r")
7979 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7980 "TARGET_TLS"
7981 "sethi\\t%%tldm_hi22(%&), %0")
7982
7983 (define_insn "tldm_lo10"
7984 [(set (match_operand:SI 0 "register_operand" "=r")
7985 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7986 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7987 "TARGET_TLS"
7988 "add\\t%1, %%tldm_lo10(%&), %0")
7989
7990 (define_insn "tldm_add32"
7991 [(set (match_operand:SI 0 "register_operand" "=r")
7992 (plus:SI (match_operand:SI 1 "register_operand" "r")
7993 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7994 UNSPEC_TLSLDM)))]
7995 "TARGET_TLS && TARGET_ARCH32"
7996 "add\\t%1, %2, %0, %%tldm_add(%&)")
7997
7998 (define_insn "tldm_add64"
7999 [(set (match_operand:DI 0 "register_operand" "=r")
8000 (plus:DI (match_operand:DI 1 "register_operand" "r")
8001 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8002 UNSPEC_TLSLDM)))]
8003 "TARGET_TLS && TARGET_ARCH64"
8004 "add\\t%1, %2, %0, %%tldm_add(%&)")
8005
8006 (define_insn "tldm_call32"
8007 [(set (match_operand 0 "register_operand" "=r")
8008 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8009 UNSPEC_TLSLDM))
8010 (match_operand 2 "" "")))
8011 (clobber (reg:SI O7_REG))]
8012 "TARGET_TLS && TARGET_ARCH32"
8013 "call\t%a1, %%tldm_call(%&)%#"
8014 [(set_attr "type" "call")])
8015
8016 (define_insn "tldm_call64"
8017 [(set (match_operand 0 "register_operand" "=r")
8018 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8019 UNSPEC_TLSLDM))
8020 (match_operand 2 "" "")))
8021 (clobber (reg:DI O7_REG))]
8022 "TARGET_TLS && TARGET_ARCH64"
8023 "call\t%a1, %%tldm_call(%&)%#"
8024 [(set_attr "type" "call")])
8025
8026 (define_insn "tldo_hix22"
8027 [(set (match_operand:SI 0 "register_operand" "=r")
8028 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8029 UNSPEC_TLSLDO)))]
8030 "TARGET_TLS"
8031 "sethi\\t%%tldo_hix22(%a1), %0")
8032
8033 (define_insn "tldo_lox10"
8034 [(set (match_operand:SI 0 "register_operand" "=r")
8035 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8036 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8037 UNSPEC_TLSLDO)))]
8038 "TARGET_TLS"
8039 "xor\\t%1, %%tldo_lox10(%a2), %0")
8040
8041 (define_insn "tldo_add32"
8042 [(set (match_operand:SI 0 "register_operand" "=r")
8043 (plus:SI (match_operand:SI 1 "register_operand" "r")
8044 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8045 (match_operand 3 "tld_symbolic_operand" "")]
8046 UNSPEC_TLSLDO)))]
8047 "TARGET_TLS && TARGET_ARCH32"
8048 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8049
8050 (define_insn "tldo_add64"
8051 [(set (match_operand:DI 0 "register_operand" "=r")
8052 (plus:DI (match_operand:DI 1 "register_operand" "r")
8053 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8054 (match_operand 3 "tld_symbolic_operand" "")]
8055 UNSPEC_TLSLDO)))]
8056 "TARGET_TLS && TARGET_ARCH64"
8057 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8058
8059 (define_insn "tie_hi22"
8060 [(set (match_operand:SI 0 "register_operand" "=r")
8061 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8062 UNSPEC_TLSIE)))]
8063 "TARGET_TLS"
8064 "sethi\\t%%tie_hi22(%a1), %0")
8065
8066 (define_insn "tie_lo10"
8067 [(set (match_operand:SI 0 "register_operand" "=r")
8068 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8069 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8070 UNSPEC_TLSIE)))]
8071 "TARGET_TLS"
8072 "add\\t%1, %%tie_lo10(%a2), %0")
8073
8074 (define_insn "tie_ld32"
8075 [(set (match_operand:SI 0 "register_operand" "=r")
8076 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8077 (match_operand:SI 2 "register_operand" "r")
8078 (match_operand 3 "tie_symbolic_operand" "")]
8079 UNSPEC_TLSIE))]
8080 "TARGET_TLS && TARGET_ARCH32"
8081 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8082 [(set_attr "type" "load")
8083 (set_attr "subtype" "regular")])
8084
8085 (define_insn "tie_ld64"
8086 [(set (match_operand:DI 0 "register_operand" "=r")
8087 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8088 (match_operand:SI 2 "register_operand" "r")
8089 (match_operand 3 "tie_symbolic_operand" "")]
8090 UNSPEC_TLSIE))]
8091 "TARGET_TLS && TARGET_ARCH64"
8092 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8093 [(set_attr "type" "load")
8094 (set_attr "subtype" "regular")])
8095
8096 (define_insn "tie_add32"
8097 [(set (match_operand:SI 0 "register_operand" "=r")
8098 (plus:SI (match_operand:SI 1 "register_operand" "r")
8099 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8100 (match_operand 3 "tie_symbolic_operand" "")]
8101 UNSPEC_TLSIE)))]
8102 "TARGET_SUN_TLS && TARGET_ARCH32"
8103 "add\\t%1, %2, %0, %%tie_add(%a3)")
8104
8105 (define_insn "tie_add64"
8106 [(set (match_operand:DI 0 "register_operand" "=r")
8107 (plus:DI (match_operand:DI 1 "register_operand" "r")
8108 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8109 (match_operand 3 "tie_symbolic_operand" "")]
8110 UNSPEC_TLSIE)))]
8111 "TARGET_SUN_TLS && TARGET_ARCH64"
8112 "add\\t%1, %2, %0, %%tie_add(%a3)")
8113
8114 (define_insn "tle_hix22_sp32"
8115 [(set (match_operand:SI 0 "register_operand" "=r")
8116 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8117 UNSPEC_TLSLE)))]
8118 "TARGET_TLS && TARGET_ARCH32"
8119 "sethi\\t%%tle_hix22(%a1), %0")
8120
8121 (define_insn "tle_lox10_sp32"
8122 [(set (match_operand:SI 0 "register_operand" "=r")
8123 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8124 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8125 UNSPEC_TLSLE)))]
8126 "TARGET_TLS && TARGET_ARCH32"
8127 "xor\\t%1, %%tle_lox10(%a2), %0")
8128
8129 (define_insn "tle_hix22_sp64"
8130 [(set (match_operand:DI 0 "register_operand" "=r")
8131 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8132 UNSPEC_TLSLE)))]
8133 "TARGET_TLS && TARGET_ARCH64"
8134 "sethi\\t%%tle_hix22(%a1), %0")
8135
8136 (define_insn "tle_lox10_sp64"
8137 [(set (match_operand:DI 0 "register_operand" "=r")
8138 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8139 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8140 UNSPEC_TLSLE)))]
8141 "TARGET_TLS && TARGET_ARCH64"
8142 "xor\\t%1, %%tle_lox10(%a2), %0")
8143
8144 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8145 (define_insn "*tldo_ldub_sp32"
8146 [(set (match_operand:QI 0 "register_operand" "=r")
8147 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8148 (match_operand 3 "tld_symbolic_operand" "")]
8149 UNSPEC_TLSLDO)
8150 (match_operand:SI 1 "register_operand" "r"))))]
8151 "TARGET_TLS && TARGET_ARCH32"
8152 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8153 [(set_attr "type" "load")
8154 (set_attr "subtype" "regular")
8155 (set_attr "us3load_type" "3cycle")])
8156
8157 (define_insn "*tldo_ldub1_sp32"
8158 [(set (match_operand:HI 0 "register_operand" "=r")
8159 (zero_extend:HI
8160 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8161 (match_operand 3 "tld_symbolic_operand" "")]
8162 UNSPEC_TLSLDO)
8163 (match_operand:SI 1 "register_operand" "r")))))]
8164 "TARGET_TLS && TARGET_ARCH32"
8165 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8166 [(set_attr "type" "load")
8167 (set_attr "subtype" "regular")
8168 (set_attr "us3load_type" "3cycle")])
8169
8170 (define_insn "*tldo_ldub2_sp32"
8171 [(set (match_operand:SI 0 "register_operand" "=r")
8172 (zero_extend:SI
8173 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8174 (match_operand 3 "tld_symbolic_operand" "")]
8175 UNSPEC_TLSLDO)
8176 (match_operand:SI 1 "register_operand" "r")))))]
8177 "TARGET_TLS && TARGET_ARCH32"
8178 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8179 [(set_attr "type" "load")
8180 (set_attr "subtype" "regular")
8181 (set_attr "us3load_type" "3cycle")])
8182
8183 (define_insn "*tldo_ldsb1_sp32"
8184 [(set (match_operand:HI 0 "register_operand" "=r")
8185 (sign_extend:HI
8186 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8187 (match_operand 3 "tld_symbolic_operand" "")]
8188 UNSPEC_TLSLDO)
8189 (match_operand:SI 1 "register_operand" "r")))))]
8190 "TARGET_TLS && TARGET_ARCH32"
8191 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8192 [(set_attr "type" "sload")
8193 (set_attr "us3load_type" "3cycle")])
8194
8195 (define_insn "*tldo_ldsb2_sp32"
8196 [(set (match_operand:SI 0 "register_operand" "=r")
8197 (sign_extend:SI
8198 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8199 (match_operand 3 "tld_symbolic_operand" "")]
8200 UNSPEC_TLSLDO)
8201 (match_operand:SI 1 "register_operand" "r")))))]
8202 "TARGET_TLS && TARGET_ARCH32"
8203 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8204 [(set_attr "type" "sload")
8205 (set_attr "us3load_type" "3cycle")])
8206
8207 (define_insn "*tldo_ldub_sp64"
8208 [(set (match_operand:QI 0 "register_operand" "=r")
8209 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8210 (match_operand 3 "tld_symbolic_operand" "")]
8211 UNSPEC_TLSLDO)
8212 (match_operand:DI 1 "register_operand" "r"))))]
8213 "TARGET_TLS && TARGET_ARCH64"
8214 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8215 [(set_attr "type" "load")
8216 (set_attr "subtype" "regular")
8217 (set_attr "us3load_type" "3cycle")])
8218
8219 (define_insn "*tldo_ldub1_sp64"
8220 [(set (match_operand:HI 0 "register_operand" "=r")
8221 (zero_extend:HI
8222 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8223 (match_operand 3 "tld_symbolic_operand" "")]
8224 UNSPEC_TLSLDO)
8225 (match_operand:DI 1 "register_operand" "r")))))]
8226 "TARGET_TLS && TARGET_ARCH64"
8227 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8228 [(set_attr "type" "load")
8229 (set_attr "subtype" "regular")
8230 (set_attr "us3load_type" "3cycle")])
8231
8232 (define_insn "*tldo_ldub2_sp64"
8233 [(set (match_operand:SI 0 "register_operand" "=r")
8234 (zero_extend:SI
8235 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8236 (match_operand 3 "tld_symbolic_operand" "")]
8237 UNSPEC_TLSLDO)
8238 (match_operand:DI 1 "register_operand" "r")))))]
8239 "TARGET_TLS && TARGET_ARCH64"
8240 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8241 [(set_attr "type" "load")
8242 (set_attr "subtype" "regular")
8243 (set_attr "us3load_type" "3cycle")])
8244
8245 (define_insn "*tldo_ldub3_sp64"
8246 [(set (match_operand:DI 0 "register_operand" "=r")
8247 (zero_extend:DI
8248 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8249 (match_operand 3 "tld_symbolic_operand" "")]
8250 UNSPEC_TLSLDO)
8251 (match_operand:DI 1 "register_operand" "r")))))]
8252 "TARGET_TLS && TARGET_ARCH64"
8253 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8254 [(set_attr "type" "load")
8255 (set_attr "subtype" "regular")
8256 (set_attr "us3load_type" "3cycle")])
8257
8258 (define_insn "*tldo_ldsb1_sp64"
8259 [(set (match_operand:HI 0 "register_operand" "=r")
8260 (sign_extend:HI
8261 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8262 (match_operand 3 "tld_symbolic_operand" "")]
8263 UNSPEC_TLSLDO)
8264 (match_operand:DI 1 "register_operand" "r")))))]
8265 "TARGET_TLS && TARGET_ARCH64"
8266 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8267 [(set_attr "type" "sload")
8268 (set_attr "us3load_type" "3cycle")])
8269
8270 (define_insn "*tldo_ldsb2_sp64"
8271 [(set (match_operand:SI 0 "register_operand" "=r")
8272 (sign_extend:SI
8273 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8274 (match_operand 3 "tld_symbolic_operand" "")]
8275 UNSPEC_TLSLDO)
8276 (match_operand:DI 1 "register_operand" "r")))))]
8277 "TARGET_TLS && TARGET_ARCH64"
8278 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8279 [(set_attr "type" "sload")
8280 (set_attr "us3load_type" "3cycle")])
8281
8282 (define_insn "*tldo_ldsb3_sp64"
8283 [(set (match_operand:DI 0 "register_operand" "=r")
8284 (sign_extend:DI
8285 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8286 (match_operand 3 "tld_symbolic_operand" "")]
8287 UNSPEC_TLSLDO)
8288 (match_operand:DI 1 "register_operand" "r")))))]
8289 "TARGET_TLS && TARGET_ARCH64"
8290 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8291 [(set_attr "type" "sload")
8292 (set_attr "us3load_type" "3cycle")])
8293
8294 (define_insn "*tldo_lduh_sp32"
8295 [(set (match_operand:HI 0 "register_operand" "=r")
8296 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8297 (match_operand 3 "tld_symbolic_operand" "")]
8298 UNSPEC_TLSLDO)
8299 (match_operand:SI 1 "register_operand" "r"))))]
8300 "TARGET_TLS && TARGET_ARCH32"
8301 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8302 [(set_attr "type" "load")
8303 (set_attr "subtype" "regular")
8304 (set_attr "us3load_type" "3cycle")])
8305
8306 (define_insn "*tldo_lduh1_sp32"
8307 [(set (match_operand:SI 0 "register_operand" "=r")
8308 (zero_extend:SI
8309 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8310 (match_operand 3 "tld_symbolic_operand" "")]
8311 UNSPEC_TLSLDO)
8312 (match_operand:SI 1 "register_operand" "r")))))]
8313 "TARGET_TLS && TARGET_ARCH32"
8314 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8315 [(set_attr "type" "load")
8316 (set_attr "subtype" "regular")
8317 (set_attr "us3load_type" "3cycle")])
8318
8319 (define_insn "*tldo_ldsh1_sp32"
8320 [(set (match_operand:SI 0 "register_operand" "=r")
8321 (sign_extend:SI
8322 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8323 (match_operand 3 "tld_symbolic_operand" "")]
8324 UNSPEC_TLSLDO)
8325 (match_operand:SI 1 "register_operand" "r")))))]
8326 "TARGET_TLS && TARGET_ARCH32"
8327 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8328 [(set_attr "type" "sload")
8329 (set_attr "us3load_type" "3cycle")])
8330
8331 (define_insn "*tldo_lduh_sp64"
8332 [(set (match_operand:HI 0 "register_operand" "=r")
8333 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8334 (match_operand 3 "tld_symbolic_operand" "")]
8335 UNSPEC_TLSLDO)
8336 (match_operand:DI 1 "register_operand" "r"))))]
8337 "TARGET_TLS && TARGET_ARCH64"
8338 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8339 [(set_attr "type" "load")
8340 (set_attr "subtype" "regular")
8341 (set_attr "us3load_type" "3cycle")])
8342
8343 (define_insn "*tldo_lduh1_sp64"
8344 [(set (match_operand:SI 0 "register_operand" "=r")
8345 (zero_extend:SI
8346 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8347 (match_operand 3 "tld_symbolic_operand" "")]
8348 UNSPEC_TLSLDO)
8349 (match_operand:DI 1 "register_operand" "r")))))]
8350 "TARGET_TLS && TARGET_ARCH64"
8351 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8352 [(set_attr "type" "load")
8353 (set_attr "subtype" "regular")
8354 (set_attr "us3load_type" "3cycle")])
8355
8356 (define_insn "*tldo_lduh2_sp64"
8357 [(set (match_operand:DI 0 "register_operand" "=r")
8358 (zero_extend:DI
8359 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8360 (match_operand 3 "tld_symbolic_operand" "")]
8361 UNSPEC_TLSLDO)
8362 (match_operand:DI 1 "register_operand" "r")))))]
8363 "TARGET_TLS && TARGET_ARCH64"
8364 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8365 [(set_attr "type" "load")
8366 (set_attr "subtype" "regular")
8367 (set_attr "us3load_type" "3cycle")])
8368
8369 (define_insn "*tldo_ldsh1_sp64"
8370 [(set (match_operand:SI 0 "register_operand" "=r")
8371 (sign_extend:SI
8372 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8373 (match_operand 3 "tld_symbolic_operand" "")]
8374 UNSPEC_TLSLDO)
8375 (match_operand:DI 1 "register_operand" "r")))))]
8376 "TARGET_TLS && TARGET_ARCH64"
8377 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8378 [(set_attr "type" "sload")
8379 (set_attr "us3load_type" "3cycle")])
8380
8381 (define_insn "*tldo_ldsh2_sp64"
8382 [(set (match_operand:DI 0 "register_operand" "=r")
8383 (sign_extend:DI
8384 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8385 (match_operand 3 "tld_symbolic_operand" "")]
8386 UNSPEC_TLSLDO)
8387 (match_operand:DI 1 "register_operand" "r")))))]
8388 "TARGET_TLS && TARGET_ARCH64"
8389 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8390 [(set_attr "type" "sload")
8391 (set_attr "us3load_type" "3cycle")])
8392
8393 (define_insn "*tldo_lduw_sp32"
8394 [(set (match_operand:SI 0 "register_operand" "=r")
8395 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8396 (match_operand 3 "tld_symbolic_operand" "")]
8397 UNSPEC_TLSLDO)
8398 (match_operand:SI 1 "register_operand" "r"))))]
8399 "TARGET_TLS && TARGET_ARCH32"
8400 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8401 [(set_attr "type" "load")
8402 (set_attr "subtype" "regular")])
8403
8404 (define_insn "*tldo_lduw_sp64"
8405 [(set (match_operand:SI 0 "register_operand" "=r")
8406 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8407 (match_operand 3 "tld_symbolic_operand" "")]
8408 UNSPEC_TLSLDO)
8409 (match_operand:DI 1 "register_operand" "r"))))]
8410 "TARGET_TLS && TARGET_ARCH64"
8411 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8412 [(set_attr "type" "load")
8413 (set_attr "subtype" "regular")])
8414
8415 (define_insn "*tldo_lduw1_sp64"
8416 [(set (match_operand:DI 0 "register_operand" "=r")
8417 (zero_extend:DI
8418 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8419 (match_operand 3 "tld_symbolic_operand" "")]
8420 UNSPEC_TLSLDO)
8421 (match_operand:DI 1 "register_operand" "r")))))]
8422 "TARGET_TLS && TARGET_ARCH64"
8423 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8424 [(set_attr "type" "load")
8425 (set_attr "subtype" "regular")])
8426
8427 (define_insn "*tldo_ldsw1_sp64"
8428 [(set (match_operand:DI 0 "register_operand" "=r")
8429 (sign_extend:DI
8430 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8431 (match_operand 3 "tld_symbolic_operand" "")]
8432 UNSPEC_TLSLDO)
8433 (match_operand:DI 1 "register_operand" "r")))))]
8434 "TARGET_TLS && TARGET_ARCH64"
8435 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8436 [(set_attr "type" "sload")
8437 (set_attr "us3load_type" "3cycle")])
8438
8439 (define_insn "*tldo_ldx_sp64"
8440 [(set (match_operand:DI 0 "register_operand" "=r")
8441 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8442 (match_operand 3 "tld_symbolic_operand" "")]
8443 UNSPEC_TLSLDO)
8444 (match_operand:DI 1 "register_operand" "r"))))]
8445 "TARGET_TLS && TARGET_ARCH64"
8446 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8447 [(set_attr "type" "load")
8448 (set_attr "subtype" "regular")])
8449
8450 (define_insn "*tldo_stb_sp32"
8451 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8452 (match_operand 3 "tld_symbolic_operand" "")]
8453 UNSPEC_TLSLDO)
8454 (match_operand:SI 1 "register_operand" "r")))
8455 (match_operand:QI 0 "register_operand" "r"))]
8456 "TARGET_TLS && TARGET_ARCH32"
8457 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8458 [(set_attr "type" "store")])
8459
8460 (define_insn "*tldo_stb_sp64"
8461 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8462 (match_operand 3 "tld_symbolic_operand" "")]
8463 UNSPEC_TLSLDO)
8464 (match_operand:DI 1 "register_operand" "r")))
8465 (match_operand:QI 0 "register_operand" "r"))]
8466 "TARGET_TLS && TARGET_ARCH64"
8467 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8468 [(set_attr "type" "store")])
8469
8470 (define_insn "*tldo_sth_sp32"
8471 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8472 (match_operand 3 "tld_symbolic_operand" "")]
8473 UNSPEC_TLSLDO)
8474 (match_operand:SI 1 "register_operand" "r")))
8475 (match_operand:HI 0 "register_operand" "r"))]
8476 "TARGET_TLS && TARGET_ARCH32"
8477 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8478 [(set_attr "type" "store")])
8479
8480 (define_insn "*tldo_sth_sp64"
8481 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8482 (match_operand 3 "tld_symbolic_operand" "")]
8483 UNSPEC_TLSLDO)
8484 (match_operand:DI 1 "register_operand" "r")))
8485 (match_operand:HI 0 "register_operand" "r"))]
8486 "TARGET_TLS && TARGET_ARCH64"
8487 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8488 [(set_attr "type" "store")])
8489
8490 (define_insn "*tldo_stw_sp32"
8491 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8492 (match_operand 3 "tld_symbolic_operand" "")]
8493 UNSPEC_TLSLDO)
8494 (match_operand:SI 1 "register_operand" "r")))
8495 (match_operand:SI 0 "register_operand" "r"))]
8496 "TARGET_TLS && TARGET_ARCH32"
8497 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8498 [(set_attr "type" "store")])
8499
8500 (define_insn "*tldo_stw_sp64"
8501 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8502 (match_operand 3 "tld_symbolic_operand" "")]
8503 UNSPEC_TLSLDO)
8504 (match_operand:DI 1 "register_operand" "r")))
8505 (match_operand:SI 0 "register_operand" "r"))]
8506 "TARGET_TLS && TARGET_ARCH64"
8507 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8508 [(set_attr "type" "store")])
8509
8510 (define_insn "*tldo_stx_sp64"
8511 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8512 (match_operand 3 "tld_symbolic_operand" "")]
8513 UNSPEC_TLSLDO)
8514 (match_operand:DI 1 "register_operand" "r")))
8515 (match_operand:DI 0 "register_operand" "r"))]
8516 "TARGET_TLS && TARGET_ARCH64"
8517 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8518 [(set_attr "type" "store")])
8519
8520
8521 ;; Stack protector instructions.
8522
8523 (define_expand "stack_protect_set"
8524 [(match_operand 0 "memory_operand" "")
8525 (match_operand 1 "memory_operand" "")]
8526 ""
8527 {
8528 #ifdef TARGET_THREAD_SSP_OFFSET
8529 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8530 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8531 operands[1] = gen_rtx_MEM (Pmode, addr);
8532 #endif
8533 if (TARGET_ARCH64)
8534 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8535 else
8536 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8537 DONE;
8538 })
8539
8540 (define_insn "stack_protect_setsi"
8541 [(set (match_operand:SI 0 "memory_operand" "=m")
8542 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8543 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8544 "TARGET_ARCH32"
8545 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8546 [(set_attr "type" "multi")
8547 (set_attr "length" "3")])
8548
8549 (define_insn "stack_protect_setdi"
8550 [(set (match_operand:DI 0 "memory_operand" "=m")
8551 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8552 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8553 "TARGET_ARCH64"
8554 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8555 [(set_attr "type" "multi")
8556 (set_attr "length" "3")])
8557
8558 (define_expand "stack_protect_test"
8559 [(match_operand 0 "memory_operand" "")
8560 (match_operand 1 "memory_operand" "")
8561 (match_operand 2 "" "")]
8562 ""
8563 {
8564 rtx result, test;
8565 #ifdef TARGET_THREAD_SSP_OFFSET
8566 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8567 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8568 operands[1] = gen_rtx_MEM (Pmode, addr);
8569 #endif
8570 if (TARGET_ARCH64)
8571 {
8572 result = gen_reg_rtx (Pmode);
8573 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
8574 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
8575 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
8576 }
8577 else
8578 {
8579 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8580 result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8581 test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
8582 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
8583 }
8584 DONE;
8585 })
8586
8587 (define_insn "stack_protect_testsi"
8588 [(set (reg:CC CC_REG)
8589 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8590 (match_operand:SI 1 "memory_operand" "m")]
8591 UNSPEC_SP_TEST))
8592 (set (match_scratch:SI 3 "=r") (const_int 0))
8593 (clobber (match_scratch:SI 2 "=&r"))]
8594 "TARGET_ARCH32"
8595 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8596 [(set_attr "type" "multi")
8597 (set_attr "length" "4")])
8598
8599 (define_insn "stack_protect_testdi"
8600 [(set (match_operand:DI 0 "register_operand" "=&r")
8601 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8602 (match_operand:DI 2 "memory_operand" "m")]
8603 UNSPEC_SP_TEST))
8604 (set (match_scratch:DI 3 "=r") (const_int 0))]
8605 "TARGET_ARCH64"
8606 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8607 [(set_attr "type" "multi")
8608 (set_attr "length" "4")])
8609
8610
8611 ;; Vector instructions.
8612
8613 (define_mode_iterator VM32 [V1SI V2HI V4QI])
8614 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
8615 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8616
8617 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")
8618 (V8QI "8")])
8619 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
8620 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
8621 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
8622 (V1DI "double") (V2SI "double") (V4HI "double")
8623 (V8QI "double")])
8624 (define_mode_attr veltmode [(V1SI "si") (V2HI "hi") (V4QI "qi") (V1DI "di")
8625 (V2SI "si") (V4HI "hi") (V8QI "qi")])
8626
8627 (define_expand "mov<VMALL:mode>"
8628 [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
8629 (match_operand:VMALL 1 "general_operand" ""))]
8630 "TARGET_VIS"
8631 {
8632 if (sparc_expand_move (<VMALL:MODE>mode, operands))
8633 DONE;
8634 })
8635
8636 (define_insn "*mov<VM32:mode>_insn"
8637 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
8638 (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
8639 "TARGET_VIS
8640 && (register_operand (operands[0], <VM32:MODE>mode)
8641 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
8642 "@
8643 fzeros\t%0
8644 fones\t%0
8645 fsrc2s\t%1, %0
8646 ld\t%1, %0
8647 st\t%1, %0
8648 st\t%r1, %0
8649 ld\t%1, %0
8650 st\t%1, %0
8651 mov\t%1, %0
8652 movstouw\t%1, %0
8653 movwtos\t%1, %0"
8654 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
8655 (set_attr "subtype" "single,single,single,*,*,*,regular,*,*,movstouw,single")
8656 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
8657
8658 (define_insn "*mov<VM64:mode>_insn_sp64"
8659 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,W,m,*r, m,*r, e,*r")
8660 (match_operand:VM64 1 "input_operand" "Y,Z,e,W,e,Y, m,*r, e,*r,*r"))]
8661 "TARGET_VIS
8662 && TARGET_ARCH64
8663 && (register_operand (operands[0], <VM64:MODE>mode)
8664 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
8665 "@
8666 fzero\t%0
8667 fone\t%0
8668 fsrc2\t%1, %0
8669 ldd\t%1, %0
8670 std\t%1, %0
8671 stx\t%r1, %0
8672 ldx\t%1, %0
8673 stx\t%1, %0
8674 movdtox\t%1, %0
8675 movxtod\t%1, %0
8676 mov\t%1, %0"
8677 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
8678 (set_attr "subtype" "double,double,double,*,*,*,regular,*,movdtox,movxtod,*")
8679 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
8680
8681 (define_insn "*mov<VM64:mode>_insn_sp32"
8682 [(set (match_operand:VM64 0 "nonimmediate_operand"
8683 "=T,o,e,e,e,*r, f,e,T,U,T,f,o,*r,*r, o")
8684 (match_operand:VM64 1 "input_operand"
8685 " Y,Y,Y,Z,e, f,*r,T,e,T,U,o,f,*r, o,*r"))]
8686 "TARGET_VIS
8687 && TARGET_ARCH32
8688 && (register_operand (operands[0], <VM64:MODE>mode)
8689 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
8690 "@
8691 stx\t%r1, %0
8692 #
8693 fzero\t%0
8694 fone\t%0
8695 fsrc2\t%1, %0
8696 #
8697 #
8698 ldd\t%1, %0
8699 std\t%1, %0
8700 ldd\t%1, %0
8701 std\t%1, %0
8702 #
8703 #
8704 #
8705 ldd\t%1, %0
8706 std\t%1, %0"
8707 [(set_attr "type" "store,*,visl,visl,vismv,*,*,fpload,fpstore,load,store,*,*,*,load,store")
8708 (set_attr "subtype" "*,*,double,double,double,*,*,*,*,regular,*,*,*,*,regular,*")
8709 (set_attr "length" "*,2,*,*,*,2,2,*,*,*,*,2,2,2,*,*")
8710 (set_attr "cpu_feature" "*,*,vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*,*,*")
8711 (set_attr "lra" "*,*,*,*,*,*,*,*,*,disabled,disabled,*,*,*,*,*")])
8712
8713 (define_split
8714 [(set (match_operand:VM64 0 "register_operand" "")
8715 (match_operand:VM64 1 "register_operand" ""))]
8716 "reload_completed
8717 && TARGET_VIS
8718 && TARGET_ARCH32
8719 && sparc_split_reg_reg_legitimate (operands[0], operands[1])"
8720 [(clobber (const_int 0))]
8721 {
8722 sparc_split_reg_reg (operands[0], operands[1], SImode);
8723 DONE;
8724 })
8725
8726 (define_split
8727 [(set (match_operand:VM64 0 "register_operand" "")
8728 (match_operand:VM64 1 "memory_operand" ""))]
8729 "reload_completed
8730 && TARGET_VIS
8731 && TARGET_ARCH32
8732 && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
8733 [(clobber (const_int 0))]
8734 {
8735 sparc_split_reg_mem (operands[0], operands[1], SImode);
8736 DONE;
8737 })
8738
8739 (define_split
8740 [(set (match_operand:VM64 0 "memory_operand" "")
8741 (match_operand:VM64 1 "register_operand" ""))]
8742 "reload_completed
8743 && TARGET_VIS
8744 && TARGET_ARCH32
8745 && sparc_split_reg_mem_legitimate (operands[1], operands[0])"
8746 [(clobber (const_int 0))]
8747 {
8748 sparc_split_mem_reg (operands[0], operands[1], SImode);
8749 DONE;
8750 })
8751
8752 (define_split
8753 [(set (match_operand:VM64 0 "memory_operand" "")
8754 (match_operand:VM64 1 "const_zero_operand" ""))]
8755 "reload_completed
8756 && TARGET_VIS
8757 && TARGET_ARCH32
8758 && !mem_min_alignment (operands[0], 8)
8759 && offsettable_memref_p (operands[0])"
8760 [(clobber (const_int 0))]
8761 {
8762 emit_move_insn_1 (adjust_address (operands[0], SImode, 0), const0_rtx);
8763 emit_move_insn_1 (adjust_address (operands[0], SImode, 4), const0_rtx);
8764 DONE;
8765 })
8766
8767 (define_expand "vec_init<VMALL:mode><VMALL:veltmode>"
8768 [(match_operand:VMALL 0 "register_operand" "")
8769 (match_operand:VMALL 1 "" "")]
8770 "TARGET_VIS"
8771 {
8772 sparc_expand_vector_init (operands[0], operands[1]);
8773 DONE;
8774 })
8775
8776 (define_code_iterator plusminus [plus minus])
8777 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8778
8779 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8780
8781 (define_insn "<plusminus_insn><VADDSUB:mode>3"
8782 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8783 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8784 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8785 "TARGET_VIS"
8786 "fp<plusminus_insn><vbits>\t%1, %2, %0"
8787 [(set_attr "type" "fga")
8788 (set_attr "subtype" "other")
8789 (set_attr "fptype" "<vfptype>")])
8790
8791 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8792 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8793 (V1DI "") (V2SI "") (V4HI "") (V8QI "")])
8794 (define_code_iterator vlop [ior and xor])
8795 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8796 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8797
8798 (define_insn "<vlop:code><VL:mode>3"
8799 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8800 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8801 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8802 "TARGET_VIS"
8803 "f<vlinsn><vlsuf>\t%1, %2, %0"
8804 [(set_attr "type" "visl")
8805 (set_attr "fptype" "<vfptype>")])
8806
8807 (define_insn "*not_<vlop:code><VL:mode>3"
8808 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8809 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8810 (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8811 "TARGET_VIS"
8812 "f<vlninsn><vlsuf>\t%1, %2, %0"
8813 [(set_attr "type" "visl")
8814 (set_attr "fptype" "<vfptype>")])
8815
8816 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8817 (define_insn "*nand<VL:mode>_vis"
8818 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8819 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8820 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8821 "TARGET_VIS"
8822 "fnand<vlsuf>\t%1, %2, %0"
8823 [(set_attr "type" "visl")
8824 (set_attr "fptype" "<vfptype>")])
8825
8826 (define_code_iterator vlnotop [ior and])
8827
8828 (define_insn "*<vlnotop:code>_not1<VL:mode>_vis"
8829 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8830 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8831 (match_operand:VL 2 "register_operand" "<vconstr>")))]
8832 "TARGET_VIS"
8833 "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8834 [(set_attr "type" "visl")
8835 (set_attr "fptype" "<vfptype>")])
8836
8837 (define_insn "*<vlnotop:code>_not2<VL:mode>_vis"
8838 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8839 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8840 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8841 "TARGET_VIS"
8842 "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8843 [(set_attr "type" "visl")
8844 (set_attr "fptype" "<vfptype>")])
8845
8846 (define_insn "one_cmpl<VL:mode>2"
8847 [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8848 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8849 "TARGET_VIS"
8850 "fnot1<vlsuf>\t%1, %0"
8851 [(set_attr "type" "visl")
8852 (set_attr "fptype" "<vfptype>")])
8853
8854 ;; Hard to generate VIS instructions. We have builtins for these.
8855
8856 (define_insn "fpack16_vis"
8857 [(set (match_operand:V4QI 0 "register_operand" "=f")
8858 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8859 (reg:DI GSR_REG)]
8860 UNSPEC_FPACK16))]
8861 "TARGET_VIS"
8862 "fpack16\t%1, %0"
8863 [(set_attr "type" "fgm_pack")
8864 (set_attr "fptype" "double")])
8865
8866 (define_insn "fpackfix_vis"
8867 [(set (match_operand:V2HI 0 "register_operand" "=f")
8868 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8869 (reg:DI GSR_REG)]
8870 UNSPEC_FPACKFIX))]
8871 "TARGET_VIS"
8872 "fpackfix\t%1, %0"
8873 [(set_attr "type" "fgm_pack")
8874 (set_attr "fptype" "double")])
8875
8876 (define_insn "fpack32_vis"
8877 [(set (match_operand:V8QI 0 "register_operand" "=e")
8878 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8879 (match_operand:V8QI 2 "register_operand" "e")
8880 (reg:DI GSR_REG)]
8881 UNSPEC_FPACK32))]
8882 "TARGET_VIS"
8883 "fpack32\t%1, %2, %0"
8884 [(set_attr "type" "fgm_pack")
8885 (set_attr "fptype" "double")])
8886
8887 (define_insn "fexpand_vis"
8888 [(set (match_operand:V4HI 0 "register_operand" "=e")
8889 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8890 UNSPEC_FEXPAND))]
8891 "TARGET_VIS"
8892 "fexpand\t%1, %0"
8893 [(set_attr "type" "fga")
8894 (set_attr "subtype" "fpu")
8895 (set_attr "fptype" "double")])
8896
8897 (define_insn "fpmerge_vis"
8898 [(set (match_operand:V8QI 0 "register_operand" "=e")
8899 (vec_select:V8QI
8900 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8901 (match_operand:V4QI 2 "register_operand" "f"))
8902 (parallel [(const_int 0) (const_int 4)
8903 (const_int 1) (const_int 5)
8904 (const_int 2) (const_int 6)
8905 (const_int 3) (const_int 7)])))]
8906 "TARGET_VIS"
8907 "fpmerge\t%1, %2, %0"
8908 [(set_attr "type" "fga")
8909 (set_attr "subtype" "fpu")
8910 (set_attr "fptype" "double")])
8911
8912 ;; Partitioned multiply instructions
8913 (define_insn "fmul8x16_vis"
8914 [(set (match_operand:V4HI 0 "register_operand" "=e")
8915 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8916 (match_operand:V4HI 2 "register_operand" "e")]
8917 UNSPEC_MUL8))]
8918 "TARGET_VIS"
8919 "fmul8x16\t%1, %2, %0"
8920 [(set_attr "type" "fgm_mul")
8921 (set_attr "fptype" "double")])
8922
8923 (define_insn "fmul8x16au_vis"
8924 [(set (match_operand:V4HI 0 "register_operand" "=e")
8925 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8926 (match_operand:V2HI 2 "register_operand" "f")]
8927 UNSPEC_MUL16AU))]
8928 "TARGET_VIS"
8929 "fmul8x16au\t%1, %2, %0"
8930 [(set_attr "type" "fgm_mul")
8931 (set_attr "fptype" "double")])
8932
8933 (define_insn "fmul8x16al_vis"
8934 [(set (match_operand:V4HI 0 "register_operand" "=e")
8935 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8936 (match_operand:V2HI 2 "register_operand" "f")]
8937 UNSPEC_MUL16AL))]
8938 "TARGET_VIS"
8939 "fmul8x16al\t%1, %2, %0"
8940 [(set_attr "type" "fgm_mul")
8941 (set_attr "fptype" "double")])
8942
8943 (define_insn "fmul8sux16_vis"
8944 [(set (match_operand:V4HI 0 "register_operand" "=e")
8945 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8946 (match_operand:V4HI 2 "register_operand" "e")]
8947 UNSPEC_MUL8SU))]
8948 "TARGET_VIS"
8949 "fmul8sux16\t%1, %2, %0"
8950 [(set_attr "type" "fgm_mul")
8951 (set_attr "fptype" "double")])
8952
8953 (define_insn "fmul8ulx16_vis"
8954 [(set (match_operand:V4HI 0 "register_operand" "=e")
8955 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8956 (match_operand:V4HI 2 "register_operand" "e")]
8957 UNSPEC_MUL8UL))]
8958 "TARGET_VIS"
8959 "fmul8ulx16\t%1, %2, %0"
8960 [(set_attr "type" "fgm_mul")
8961 (set_attr "fptype" "double")])
8962
8963 (define_insn "fmuld8sux16_vis"
8964 [(set (match_operand:V2SI 0 "register_operand" "=e")
8965 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8966 (match_operand:V2HI 2 "register_operand" "f")]
8967 UNSPEC_MULDSU))]
8968 "TARGET_VIS"
8969 "fmuld8sux16\t%1, %2, %0"
8970 [(set_attr "type" "fgm_mul")
8971 (set_attr "fptype" "double")])
8972
8973 (define_insn "fmuld8ulx16_vis"
8974 [(set (match_operand:V2SI 0 "register_operand" "=e")
8975 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8976 (match_operand:V2HI 2 "register_operand" "f")]
8977 UNSPEC_MULDUL))]
8978 "TARGET_VIS"
8979 "fmuld8ulx16\t%1, %2, %0"
8980 [(set_attr "type" "fgm_mul")
8981 (set_attr "fptype" "double")])
8982
8983 (define_expand "wrgsr_vis"
8984 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8985 "TARGET_VIS"
8986 {
8987 if (TARGET_ARCH32)
8988 {
8989 emit_insn (gen_wrgsr_v8plus (operands[0]));
8990 DONE;
8991 }
8992 })
8993
8994 (define_insn "*wrgsr_sp64"
8995 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8996 "TARGET_VIS && TARGET_ARCH64"
8997 "wr\t%%g0, %0, %%gsr"
8998 [(set_attr "type" "gsr")
8999 (set_attr "subtype" "reg")])
9000
9001 (define_insn "wrgsr_v8plus"
9002 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
9003 (clobber (match_scratch:SI 1 "=X,&h"))]
9004 "TARGET_VIS && TARGET_ARCH32"
9005 {
9006 if (GET_CODE (operands[0]) == CONST_INT
9007 || sparc_check_64 (operands[0], insn))
9008 return "wr\t%%g0, %0, %%gsr";
9009
9010 output_asm_insn("srl\t%L0, 0, %L0", operands);
9011 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
9012 }
9013 [(set_attr "type" "multi")])
9014
9015 (define_expand "rdgsr_vis"
9016 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
9017 "TARGET_VIS"
9018 {
9019 if (TARGET_ARCH32)
9020 {
9021 emit_insn (gen_rdgsr_v8plus (operands[0]));
9022 DONE;
9023 }
9024 })
9025
9026 (define_insn "*rdgsr_sp64"
9027 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
9028 "TARGET_VIS && TARGET_ARCH64"
9029 "rd\t%%gsr, %0"
9030 [(set_attr "type" "gsr")
9031 (set_attr "subtype" "reg")])
9032
9033 (define_insn "rdgsr_v8plus"
9034 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
9035 (clobber (match_scratch:SI 1 "=&h"))]
9036 "TARGET_VIS && TARGET_ARCH32"
9037 {
9038 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
9039 }
9040 [(set_attr "type" "multi")])
9041
9042 ;; Using faligndata only makes sense after an alignaddr since the choice of
9043 ;; bytes to take out of each operand is dependent on the results of the last
9044 ;; alignaddr.
9045 (define_insn "faligndata<VM64:mode>_vis"
9046 [(set (match_operand:VM64 0 "register_operand" "=e")
9047 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
9048 (match_operand:VM64 2 "register_operand" "e")
9049 (reg:DI GSR_REG)]
9050 UNSPEC_ALIGNDATA))]
9051 "TARGET_VIS"
9052 "faligndata\t%1, %2, %0"
9053 [(set_attr "type" "fga")
9054 (set_attr "subtype" "other")
9055 (set_attr "fptype" "double")])
9056
9057 (define_insn "alignaddrsi_vis"
9058 [(set (match_operand:SI 0 "register_operand" "=r")
9059 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9060 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9061 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9062 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9063 "TARGET_VIS"
9064 "alignaddr\t%r1, %r2, %0"
9065 [(set_attr "type" "gsr")
9066 (set_attr "subtype" "alignaddr")])
9067
9068 (define_insn "alignaddrdi_vis"
9069 [(set (match_operand:DI 0 "register_operand" "=r")
9070 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9071 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9072 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9073 (plus:DI (match_dup 1) (match_dup 2)))]
9074 "TARGET_VIS"
9075 "alignaddr\t%r1, %r2, %0"
9076 [(set_attr "type" "gsr")
9077 (set_attr "subtype" "alignaddr")])
9078
9079 (define_insn "alignaddrlsi_vis"
9080 [(set (match_operand:SI 0 "register_operand" "=r")
9081 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9082 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9083 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9084 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
9085 (const_int 7)))]
9086 "TARGET_VIS"
9087 "alignaddrl\t%r1, %r2, %0"
9088 [(set_attr "type" "gsr")
9089 (set_attr "subtype" "alignaddr")])
9090
9091 (define_insn "alignaddrldi_vis"
9092 [(set (match_operand:DI 0 "register_operand" "=r")
9093 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9094 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9095 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9096 (xor:DI (plus:DI (match_dup 1) (match_dup 2))
9097 (const_int 7)))]
9098 "TARGET_VIS"
9099 "alignaddrl\t%r1, %r2, %0"
9100 [(set_attr "type" "gsr")
9101 (set_attr "subtype" "alignaddr")])
9102
9103 (define_insn "pdist_vis"
9104 [(set (match_operand:DI 0 "register_operand" "=e")
9105 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
9106 (match_operand:V8QI 2 "register_operand" "e")
9107 (match_operand:DI 3 "register_operand" "0")]
9108 UNSPEC_PDIST))]
9109 "TARGET_VIS"
9110 "pdist\t%1, %2, %0"
9111 [(set_attr "type" "pdist")
9112 (set_attr "fptype" "double")])
9113
9114 ;; Edge instructions produce condition codes equivalent to a 'subcc'
9115 ;; with the same operands.
9116 (define_insn "edge8<P:mode>_vis"
9117 [(set (reg:CCNZ CC_REG)
9118 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9119 (match_operand:P 2 "register_or_zero_operand" "rJ"))
9120 (const_int 0)))
9121 (set (match_operand:P 0 "register_operand" "=r")
9122 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
9123 "TARGET_VIS"
9124 "edge8\t%r1, %r2, %0"
9125 [(set_attr "type" "edge")])
9126
9127 (define_insn "edge8l<P:mode>_vis"
9128 [(set (reg:CCNZ CC_REG)
9129 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9130 (match_operand:P 2 "register_or_zero_operand" "rJ"))
9131 (const_int 0)))
9132 (set (match_operand:P 0 "register_operand" "=r")
9133 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
9134 "TARGET_VIS"
9135 "edge8l\t%r1, %r2, %0"
9136 [(set_attr "type" "edge")])
9137
9138 (define_insn "edge16<P:mode>_vis"
9139 [(set (reg:CCNZ CC_REG)
9140 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9141 (match_operand:P 2 "register_or_zero_operand" "rJ"))
9142 (const_int 0)))
9143 (set (match_operand:P 0 "register_operand" "=r")
9144 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
9145 "TARGET_VIS"
9146 "edge16\t%r1, %r2, %0"
9147 [(set_attr "type" "edge")])
9148
9149 (define_insn "edge16l<P:mode>_vis"
9150 [(set (reg:CCNZ CC_REG)
9151 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9152 (match_operand:P 2 "register_or_zero_operand" "rJ"))
9153 (const_int 0)))
9154 (set (match_operand:P 0 "register_operand" "=r")
9155 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
9156 "TARGET_VIS"
9157 "edge16l\t%r1, %r2, %0"
9158 [(set_attr "type" "edge")])
9159
9160 (define_insn "edge32<P:mode>_vis"
9161 [(set (reg:CCNZ CC_REG)
9162 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9163 (match_operand:P 2 "register_or_zero_operand" "rJ"))
9164 (const_int 0)))
9165 (set (match_operand:P 0 "register_operand" "=r")
9166 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
9167 "TARGET_VIS"
9168 "edge32\t%r1, %r2, %0"
9169 [(set_attr "type" "edge")])
9170
9171 (define_insn "edge32l<P:mode>_vis"
9172 [(set (reg:CCNZ CC_REG)
9173 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9174 (match_operand:P 2 "register_or_zero_operand" "rJ"))
9175 (const_int 0)))
9176 (set (match_operand:P 0 "register_operand" "=r")
9177 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
9178 "TARGET_VIS"
9179 "edge32l\t%r1, %r2, %0"
9180 [(set_attr "type" "edge")])
9181
9182 (define_code_iterator gcond [le ne gt eq])
9183 (define_mode_iterator GCM [V4HI V2SI])
9184 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
9185
9186 (define_insn "fcmp<gcond:code><GCM:gcm_name><P:mode>_vis"
9187 [(set (match_operand:P 0 "register_operand" "=r")
9188 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
9189 (match_operand:GCM 2 "register_operand" "e"))]
9190 UNSPEC_FCMP))]
9191 "TARGET_VIS"
9192 "fcmp<gcond:code><GCM:gcm_name>\t%1, %2, %0"
9193 [(set_attr "type" "viscmp")])
9194
9195 (define_insn "fpcmp<gcond:code>8<P:mode>_vis"
9196 [(set (match_operand:P 0 "register_operand" "=r")
9197 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
9198 (match_operand:V8QI 2 "register_operand" "e"))]
9199 UNSPEC_FCMP))]
9200 "TARGET_VIS4"
9201 "fpcmp<gcond:code>8\t%1, %2, %0"
9202 [(set_attr "type" "viscmp")])
9203
9204 (define_expand "vcond<GCM:mode><GCM:mode>"
9205 [(match_operand:GCM 0 "register_operand" "")
9206 (match_operand:GCM 1 "register_operand" "")
9207 (match_operand:GCM 2 "register_operand" "")
9208 (match_operator 3 ""
9209 [(match_operand:GCM 4 "register_operand" "")
9210 (match_operand:GCM 5 "register_operand" "")])]
9211 "TARGET_VIS3"
9212 {
9213 sparc_expand_vcond (<MODE>mode, operands, UNSPEC_CMASK<gcm_name>, UNSPEC_FCMP);
9214 DONE;
9215 })
9216
9217 (define_expand "vconduv8qiv8qi"
9218 [(match_operand:V8QI 0 "register_operand" "")
9219 (match_operand:V8QI 1 "register_operand" "")
9220 (match_operand:V8QI 2 "register_operand" "")
9221 (match_operator 3 ""
9222 [(match_operand:V8QI 4 "register_operand" "")
9223 (match_operand:V8QI 5 "register_operand" "")])]
9224 "TARGET_VIS3"
9225 {
9226 sparc_expand_vcond (V8QImode, operands, UNSPEC_CMASK8, UNSPEC_FUCMP);
9227 DONE;
9228 })
9229
9230 (define_insn "array8<P:mode>_vis"
9231 [(set (match_operand:P 0 "register_operand" "=r")
9232 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9233 (match_operand:P 2 "register_or_zero_operand" "rJ")]
9234 UNSPEC_ARRAY8))]
9235 "TARGET_VIS"
9236 "array8\t%r1, %r2, %0"
9237 [(set_attr "type" "array")])
9238
9239 (define_insn "array16<P:mode>_vis"
9240 [(set (match_operand:P 0 "register_operand" "=r")
9241 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9242 (match_operand:P 2 "register_or_zero_operand" "rJ")]
9243 UNSPEC_ARRAY16))]
9244 "TARGET_VIS"
9245 "array16\t%r1, %r2, %0"
9246 [(set_attr "type" "array")])
9247
9248 (define_insn "array32<P:mode>_vis"
9249 [(set (match_operand:P 0 "register_operand" "=r")
9250 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9251 (match_operand:P 2 "register_or_zero_operand" "rJ")]
9252 UNSPEC_ARRAY32))]
9253 "TARGET_VIS"
9254 "array32\t%r1, %r2, %0"
9255 [(set_attr "type" "array")])
9256
9257 (define_insn "bmaskdi_vis"
9258 [(set (match_operand:DI 0 "register_operand" "=r")
9259 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9260 (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9261 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
9262 (plus:DI (match_dup 1) (match_dup 2)))]
9263 "TARGET_VIS2 && TARGET_ARCH64"
9264 "bmask\t%r1, %r2, %0"
9265 [(set_attr "type" "bmask")])
9266
9267 (define_insn "bmasksi_vis"
9268 [(set (match_operand:SI 0 "register_operand" "=r")
9269 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9270 (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9271 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
9272 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9273 "TARGET_VIS2"
9274 "bmask\t%r1, %r2, %0"
9275 [(set_attr "type" "bmask")])
9276
9277 (define_insn "bshuffle<VM64:mode>_vis"
9278 [(set (match_operand:VM64 0 "register_operand" "=e")
9279 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
9280 (match_operand:VM64 2 "register_operand" "e")
9281 (reg:DI GSR_REG)]
9282 UNSPEC_BSHUFFLE))]
9283 "TARGET_VIS2"
9284 "bshuffle\t%1, %2, %0"
9285 [(set_attr "type" "fga")
9286 (set_attr "subtype" "other")
9287 (set_attr "fptype" "double")])
9288
9289 ;; The rtl expanders will happily convert constant permutations on other
9290 ;; modes down to V8QI. Rely on this to avoid the complexity of the byte
9291 ;; order of the permutation.
9292 (define_expand "vec_perm_constv8qi"
9293 [(match_operand:V8QI 0 "register_operand" "")
9294 (match_operand:V8QI 1 "register_operand" "")
9295 (match_operand:V8QI 2 "register_operand" "")
9296 (match_operand:V8QI 3 "" "")]
9297 "TARGET_VIS2"
9298 {
9299 unsigned int i, mask;
9300 rtx sel = operands[3];
9301
9302 for (i = mask = 0; i < 8; ++i)
9303 mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
9304 sel = force_reg (SImode, gen_int_mode (mask, SImode));
9305
9306 emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
9307 emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
9308 DONE;
9309 })
9310
9311 ;; Unlike constant permutation, we can vastly simplify the compression of
9312 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
9313 ;; width of the input is.
9314 (define_expand "vec_perm<VM64:mode>"
9315 [(match_operand:VM64 0 "register_operand" "")
9316 (match_operand:VM64 1 "register_operand" "")
9317 (match_operand:VM64 2 "register_operand" "")
9318 (match_operand:VM64 3 "register_operand" "")]
9319 "TARGET_VIS2"
9320 {
9321 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
9322 emit_insn (gen_bshuffle<VM64:mode>_vis (operands[0], operands[1], operands[2]));
9323 DONE;
9324 })
9325
9326 ;; VIS 2.0 adds edge variants which do not set the condition codes
9327 (define_insn "edge8n<P:mode>_vis"
9328 [(set (match_operand:P 0 "register_operand" "=r")
9329 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9330 (match_operand:P 2 "register_or_zero_operand" "rJ")]
9331 UNSPEC_EDGE8N))]
9332 "TARGET_VIS2"
9333 "edge8n\t%r1, %r2, %0"
9334 [(set_attr "type" "edgen")])
9335
9336 (define_insn "edge8ln<P:mode>_vis"
9337 [(set (match_operand:P 0 "register_operand" "=r")
9338 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9339 (match_operand:P 2 "register_or_zero_operand" "rJ")]
9340 UNSPEC_EDGE8LN))]
9341 "TARGET_VIS2"
9342 "edge8ln\t%r1, %r2, %0"
9343 [(set_attr "type" "edgen")])
9344
9345 (define_insn "edge16n<P:mode>_vis"
9346 [(set (match_operand:P 0 "register_operand" "=r")
9347 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9348 (match_operand:P 2 "register_or_zero_operand" "rJ")]
9349 UNSPEC_EDGE16N))]
9350 "TARGET_VIS2"
9351 "edge16n\t%r1, %r2, %0"
9352 [(set_attr "type" "edgen")])
9353
9354 (define_insn "edge16ln<P:mode>_vis"
9355 [(set (match_operand:P 0 "register_operand" "=r")
9356 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9357 (match_operand:P 2 "register_or_zero_operand" "rJ")]
9358 UNSPEC_EDGE16LN))]
9359 "TARGET_VIS2"
9360 "edge16ln\t%r1, %r2, %0"
9361 [(set_attr "type" "edgen")])
9362
9363 (define_insn "edge32n<P:mode>_vis"
9364 [(set (match_operand:P 0 "register_operand" "=r")
9365 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9366 (match_operand:P 2 "register_or_zero_operand" "rJ")]
9367 UNSPEC_EDGE32N))]
9368 "TARGET_VIS2"
9369 "edge32n\t%r1, %r2, %0"
9370 [(set_attr "type" "edgen")])
9371
9372 (define_insn "edge32ln<P:mode>_vis"
9373 [(set (match_operand:P 0 "register_operand" "=r")
9374 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9375 (match_operand:P 2 "register_or_zero_operand" "rJ")]
9376 UNSPEC_EDGE32LN))]
9377 "TARGET_VIS2"
9378 "edge32ln\t%r1, %r2, %0"
9379 [(set_attr "type" "edge")])
9380
9381 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
9382 (define_insn "cmask8<P:mode>_vis"
9383 [(set (reg:DI GSR_REG)
9384 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9385 (reg:DI GSR_REG)]
9386 UNSPEC_CMASK8))]
9387 "TARGET_VIS3"
9388 "cmask8\t%r0"
9389 [(set_attr "type" "fga")
9390 (set_attr "subtype" "cmask")])
9391
9392 (define_insn "cmask16<P:mode>_vis"
9393 [(set (reg:DI GSR_REG)
9394 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9395 (reg:DI GSR_REG)]
9396 UNSPEC_CMASK16))]
9397 "TARGET_VIS3"
9398 "cmask16\t%r0"
9399 [(set_attr "type" "fga")
9400 (set_attr "subtype" "cmask")])
9401
9402 (define_insn "cmask32<P:mode>_vis"
9403 [(set (reg:DI GSR_REG)
9404 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9405 (reg:DI GSR_REG)]
9406 UNSPEC_CMASK32))]
9407 "TARGET_VIS3"
9408 "cmask32\t%r0"
9409 [(set_attr "type" "fga")
9410 (set_attr "subtype" "cmask")])
9411
9412 (define_insn "fchksm16_vis"
9413 [(set (match_operand:V4HI 0 "register_operand" "=e")
9414 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
9415 (match_operand:V4HI 2 "register_operand" "e")]
9416 UNSPEC_FCHKSM16))]
9417 "TARGET_VIS3"
9418 "fchksm16\t%1, %2, %0"
9419 [(set_attr "type" "fga")
9420 (set_attr "subtype" "fpu")])
9421
9422 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
9423 (define_code_attr vis3_shift_insn
9424 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
9425 (define_code_attr vis3_shift_patname
9426 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
9427
9428 (define_insn "v<vis3_shift_patname><GCM:mode>3"
9429 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
9430 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
9431 (match_operand:GCM 2 "register_operand" "<vconstr>")))]
9432 "TARGET_VIS3"
9433 "<vis3_shift_insn><vbits>\t%1, %2, %0"
9434 [(set_attr "type" "fga")
9435 (set_attr "subtype" "fpu")])
9436
9437 (define_insn "pdistn<P:mode>_vis"
9438 [(set (match_operand:P 0 "register_operand" "=r")
9439 (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
9440 (match_operand:V8QI 2 "register_operand" "e")]
9441 UNSPEC_PDISTN))]
9442 "TARGET_VIS3"
9443 "pdistn\t%1, %2, %0"
9444 [(set_attr "type" "pdistn")
9445 (set_attr "fptype" "double")])
9446
9447 (define_insn "fmean16_vis"
9448 [(set (match_operand:V4HI 0 "register_operand" "=e")
9449 (truncate:V4HI
9450 (lshiftrt:V4SI
9451 (plus:V4SI
9452 (plus:V4SI
9453 (zero_extend:V4SI
9454 (match_operand:V4HI 1 "register_operand" "e"))
9455 (zero_extend:V4SI
9456 (match_operand:V4HI 2 "register_operand" "e")))
9457 (const_vector:V4SI [(const_int 1) (const_int 1)
9458 (const_int 1) (const_int 1)]))
9459 (const_int 1))))]
9460 "TARGET_VIS3"
9461 "fmean16\t%1, %2, %0"
9462 [(set_attr "type" "fga")
9463 (set_attr "subtype" "fpu")])
9464
9465 (define_insn "fp<plusminus_insn>64_vis"
9466 [(set (match_operand:V1DI 0 "register_operand" "=e")
9467 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
9468 (match_operand:V1DI 2 "register_operand" "e")))]
9469 "TARGET_VIS3"
9470 "fp<plusminus_insn>64\t%1, %2, %0"
9471 [(set_attr "type" "fga")
9472 (set_attr "subtype" "addsub64")])
9473
9474 (define_insn "<plusminus_insn>v8qi3"
9475 [(set (match_operand:V8QI 0 "register_operand" "=e")
9476 (plusminus:V8QI (match_operand:V8QI 1 "register_operand" "e")
9477 (match_operand:V8QI 2 "register_operand" "e")))]
9478 "TARGET_VIS4"
9479 "fp<plusminus_insn>8\t%1, %2, %0"
9480 [(set_attr "type" "fga")
9481 (set_attr "subtype" "other")])
9482
9483 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
9484 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
9485 (define_code_attr vis3_addsub_ss_insn
9486 [(ss_plus "fpadds") (ss_minus "fpsubs")])
9487 (define_code_attr vis3_addsub_ss_patname
9488 [(ss_plus "ssadd") (ss_minus "sssub")])
9489
9490 (define_insn "<vis3_addsub_ss_patname><VASS:mode>3"
9491 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
9492 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
9493 (match_operand:VASS 2 "register_operand" "<vconstr>")))]
9494 "TARGET_VIS3"
9495 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
9496 [(set_attr "type" "fga")
9497 (set_attr "subtype" "other")])
9498
9499 (define_mode_iterator VMMAX [V8QI V4HI V2SI])
9500 (define_code_iterator vis4_minmax [smin smax])
9501 (define_code_attr vis4_minmax_insn
9502 [(smin "fpmin") (smax "fpmax")])
9503 (define_code_attr vis4_minmax_patname
9504 [(smin "min") (smax "max")])
9505
9506 (define_insn "<vis4_minmax_patname><VMMAX:mode>3"
9507 [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
9508 (vis4_minmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
9509 (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
9510 "TARGET_VIS4"
9511 "<vis4_minmax_insn><vbits>\t%1, %2, %0"
9512 [(set_attr "type" "fga")
9513 (set_attr "subtype" "maxmin")])
9514
9515 (define_code_iterator vis4_uminmax [umin umax])
9516 (define_code_attr vis4_uminmax_insn
9517 [(umin "fpminu") (umax "fpmaxu")])
9518 (define_code_attr vis4_uminmax_patname
9519 [(umin "minu") (umax "maxu")])
9520
9521 (define_insn "<vis4_uminmax_patname><VMMAX:mode>3"
9522 [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
9523 (vis4_uminmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
9524 (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
9525 "TARGET_VIS4"
9526 "<vis4_uminmax_insn><vbits>\t%1, %2, %0"
9527 [(set_attr "type" "fga")
9528 (set_attr "subtype" "maxmin")])
9529
9530 ;; The use of vis3_addsub_ss_patname in the VIS4 instruction below is
9531 ;; intended.
9532 (define_insn "<vis3_addsub_ss_patname>v8qi3"
9533 [(set (match_operand:V8QI 0 "register_operand" "=e")
9534 (vis3_addsub_ss:V8QI (match_operand:V8QI 1 "register_operand" "e")
9535 (match_operand:V8QI 2 "register_operand" "e")))]
9536 "TARGET_VIS4"
9537 "<vis3_addsub_ss_insn>8\t%1, %2, %0"
9538 [(set_attr "type" "fga")
9539 (set_attr "subtype" "other")])
9540
9541 (define_mode_iterator VAUS [V4HI V8QI])
9542 (define_code_iterator vis4_addsub_us [us_plus us_minus])
9543 (define_code_attr vis4_addsub_us_insn
9544 [(us_plus "fpaddus") (us_minus "fpsubus")])
9545 (define_code_attr vis4_addsub_us_patname
9546 [(us_plus "usadd") (us_minus "ussub")])
9547
9548 (define_insn "<vis4_addsub_us_patname><VAUS:mode>3"
9549 [(set (match_operand:VAUS 0 "register_operand" "=<vconstr>")
9550 (vis4_addsub_us:VAUS (match_operand:VAUS 1 "register_operand" "<vconstr>")
9551 (match_operand:VAUS 2 "register_operand" "<vconstr>")))]
9552 "TARGET_VIS4"
9553 "<vis4_addsub_us_insn><vbits>\t%1, %2, %0"
9554 [(set_attr "type" "fga")
9555 (set_attr "subtype" "other")])
9556
9557 (define_insn "fucmp<gcond:code>8<P:mode>_vis"
9558 [(set (match_operand:P 0 "register_operand" "=r")
9559 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
9560 (match_operand:V8QI 2 "register_operand" "e"))]
9561 UNSPEC_FUCMP))]
9562 "TARGET_VIS3"
9563 "fucmp<gcond:code>8\t%1, %2, %0"
9564 [(set_attr "type" "viscmp")])
9565
9566 (define_insn "fpcmpu<gcond:code><GCM:gcm_name><P:mode>_vis"
9567 [(set (match_operand:P 0 "register_operand" "=r")
9568 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
9569 (match_operand:GCM 2 "register_operand" "e"))]
9570 UNSPEC_FUCMP))]
9571 "TARGET_VIS4"
9572 "fpcmpu<gcond:code><GCM:gcm_name>\t%1, %2, %0"
9573 [(set_attr "type" "viscmp")])
9574
9575 (define_insn "*naddsf3"
9576 [(set (match_operand:SF 0 "register_operand" "=f")
9577 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
9578 (match_operand:SF 2 "register_operand" "f"))))]
9579 "TARGET_VIS3"
9580 "fnadds\t%1, %2, %0"
9581 [(set_attr "type" "fp")])
9582
9583 (define_insn "*nadddf3"
9584 [(set (match_operand:DF 0 "register_operand" "=e")
9585 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
9586 (match_operand:DF 2 "register_operand" "e"))))]
9587 "TARGET_VIS3"
9588 "fnaddd\t%1, %2, %0"
9589 [(set_attr "type" "fp")
9590 (set_attr "fptype" "double")])
9591
9592 (define_insn "*nmulsf3"
9593 [(set (match_operand:SF 0 "register_operand" "=f")
9594 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
9595 (match_operand:SF 2 "register_operand" "f")))]
9596 "TARGET_VIS3"
9597 "fnmuls\t%1, %2, %0"
9598 [(set_attr "type" "fpmul")])
9599
9600 (define_insn "*nmuldf3"
9601 [(set (match_operand:DF 0 "register_operand" "=e")
9602 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
9603 (match_operand:DF 2 "register_operand" "e")))]
9604 "TARGET_VIS3"
9605 "fnmuld\t%1, %2, %0"
9606 [(set_attr "type" "fpmul")
9607 (set_attr "fptype" "double")])
9608
9609 (define_insn "*nmuldf3_extend"
9610 [(set (match_operand:DF 0 "register_operand" "=e")
9611 (mult:DF (neg:DF (float_extend:DF
9612 (match_operand:SF 1 "register_operand" "f")))
9613 (float_extend:DF
9614 (match_operand:SF 2 "register_operand" "f"))))]
9615 "TARGET_VIS3"
9616 "fnsmuld\t%1, %2, %0"
9617 [(set_attr "type" "fpmul")
9618 (set_attr "fptype" "double")])
9619
9620 (define_insn "fhaddsf_vis"
9621 [(set (match_operand:SF 0 "register_operand" "=f")
9622 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9623 (match_operand:SF 2 "register_operand" "f")]
9624 UNSPEC_FHADD))]
9625 "TARGET_VIS3"
9626 "fhadds\t%1, %2, %0"
9627 [(set_attr "type" "fp")])
9628
9629 (define_insn "fhadddf_vis"
9630 [(set (match_operand:DF 0 "register_operand" "=f")
9631 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9632 (match_operand:DF 2 "register_operand" "f")]
9633 UNSPEC_FHADD))]
9634 "TARGET_VIS3"
9635 "fhaddd\t%1, %2, %0"
9636 [(set_attr "type" "fp")
9637 (set_attr "fptype" "double")])
9638
9639 (define_insn "fhsubsf_vis"
9640 [(set (match_operand:SF 0 "register_operand" "=f")
9641 (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9642 (match_operand:SF 2 "register_operand" "f")]
9643 UNSPEC_FHSUB))]
9644 "TARGET_VIS3"
9645 "fhsubs\t%1, %2, %0"
9646 [(set_attr "type" "fp")])
9647
9648 (define_insn "fhsubdf_vis"
9649 [(set (match_operand:DF 0 "register_operand" "=f")
9650 (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9651 (match_operand:DF 2 "register_operand" "f")]
9652 UNSPEC_FHSUB))]
9653 "TARGET_VIS3"
9654 "fhsubd\t%1, %2, %0"
9655 [(set_attr "type" "fp")
9656 (set_attr "fptype" "double")])
9657
9658 (define_insn "fnhaddsf_vis"
9659 [(set (match_operand:SF 0 "register_operand" "=f")
9660 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9661 (match_operand:SF 2 "register_operand" "f")]
9662 UNSPEC_FHADD)))]
9663 "TARGET_VIS3"
9664 "fnhadds\t%1, %2, %0"
9665 [(set_attr "type" "fp")])
9666
9667 (define_insn "fnhadddf_vis"
9668 [(set (match_operand:DF 0 "register_operand" "=f")
9669 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9670 (match_operand:DF 2 "register_operand" "f")]
9671 UNSPEC_FHADD)))]
9672 "TARGET_VIS3"
9673 "fnhaddd\t%1, %2, %0"
9674 [(set_attr "type" "fp")
9675 (set_attr "fptype" "double")])
9676
9677 ;; VIS4B instructions.
9678
9679 (define_mode_iterator DUMODE [V2SI V4HI V8QI])
9680
9681 (define_insn "dictunpack<DUMODE:vbits>"
9682 [(set (match_operand:DUMODE 0 "register_operand" "=e")
9683 (unspec:DUMODE [(match_operand:DF 1 "register_operand" "e")
9684 (match_operand:SI 2 "imm5_operand_dictunpack<DUMODE:vbits>" "t")]
9685 UNSPEC_DICTUNPACK))]
9686 "TARGET_VIS4B"
9687 "dictunpack\t%1, %2, %0"
9688 [(set_attr "type" "fga")
9689 (set_attr "subtype" "other")])
9690
9691 (define_mode_iterator FPCSMODE [V2SI V4HI V8QI])
9692 (define_code_iterator fpcscond [le gt eq ne])
9693 (define_code_iterator fpcsucond [le gt])
9694
9695 (define_insn "fpcmp<fpcscond:code><FPCSMODE:vbits><P:mode>shl"
9696 [(set (match_operand:P 0 "register_operand" "=r")
9697 (unspec:P [(fpcscond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
9698 (match_operand:FPCSMODE 2 "register_operand" "e"))
9699 (match_operand:SI 3 "imm2_operand" "q")]
9700 UNSPEC_FPCMPSHL))]
9701 "TARGET_VIS4B"
9702 "fpcmp<fpcscond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9703 [(set_attr "type" "viscmp")])
9704
9705 (define_insn "fpcmpu<fpcsucond:code><FPCSMODE:vbits><P:mode>shl"
9706 [(set (match_operand:P 0 "register_operand" "=r")
9707 (unspec:P [(fpcsucond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
9708 (match_operand:FPCSMODE 2 "register_operand" "e"))
9709 (match_operand:SI 3 "imm2_operand" "q")]
9710 UNSPEC_FPUCMPSHL))]
9711 "TARGET_VIS4B"
9712 "fpcmpu<fpcsucond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9713 [(set_attr "type" "viscmp")])
9714
9715 (define_insn "fpcmpde<FPCSMODE:vbits><P:mode>shl"
9716 [(set (match_operand:P 0 "register_operand" "=r")
9717 (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
9718 (match_operand:FPCSMODE 2 "register_operand" "e")
9719 (match_operand:SI 3 "imm2_operand" "q")]
9720 UNSPEC_FPCMPDESHL))]
9721 "TARGET_VIS4B"
9722 "fpcmpde<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9723 [(set_attr "type" "viscmp")])
9724
9725 (define_insn "fpcmpur<FPCSMODE:vbits><P:mode>shl"
9726 [(set (match_operand:P 0 "register_operand" "=r")
9727 (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
9728 (match_operand:FPCSMODE 2 "register_operand" "e")
9729 (match_operand:SI 3 "imm2_operand" "q")]
9730 UNSPEC_FPCMPURSHL))]
9731 "TARGET_VIS4B"
9732 "fpcmpur<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9733 [(set_attr "type" "viscmp")])
9734
9735 (include "sync.md")