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