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