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