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