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