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