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