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