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