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