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