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