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