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