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