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