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