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