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