dc6c3a31645be1757ebf9ac8fdf632fb1969e2cb
[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 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
6 ;; at Cygnus Support.
7
8 ;; This file is part of GCC.
9
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
23
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25
26 (define_constants
27 [(UNSPEC_MOVE_PIC 0)
28 (UNSPEC_UPDATE_RETURN 1)
29 (UNSPEC_LOAD_PCREL_SYM 2)
30 (UNSPEC_MOVE_PIC_LABEL 5)
31 (UNSPEC_SETH44 6)
32 (UNSPEC_SETM44 7)
33 (UNSPEC_SETHH 9)
34 (UNSPEC_SETLM 10)
35 (UNSPEC_EMB_HISUM 11)
36 (UNSPEC_EMB_TEXTUHI 13)
37 (UNSPEC_EMB_TEXTHI 14)
38 (UNSPEC_EMB_TEXTULO 15)
39 (UNSPEC_EMB_SETHM 18)
40
41 (UNSPEC_TLSGD 30)
42 (UNSPEC_TLSLDM 31)
43 (UNSPEC_TLSLDO 32)
44 (UNSPEC_TLSIE 33)
45 (UNSPEC_TLSLE 34)
46 (UNSPEC_TLSLD_BASE 35)
47
48 (UNSPEC_FPACK16 40)
49 (UNSPEC_FPACK32 41)
50 (UNSPEC_FPACKFIX 42)
51 (UNSPEC_FEXPAND 43)
52 (UNSPEC_FPMERGE 44)
53 (UNSPEC_MUL16AL 45)
54 (UNSPEC_MUL8UL 46)
55 (UNSPEC_MULDUL 47)
56 (UNSPEC_ALIGNDATA 48)
57 (UNSPEC_ALIGNADDR 49)
58 (UNSPEC_PDIST 50)
59
60 (UNSPEC_SP_SET 60)
61 (UNSPEC_SP_TEST 61)
62 ])
63
64 (define_constants
65 [(UNSPECV_BLOCKAGE 0)
66 (UNSPECV_FLUSHW 1)
67 (UNSPECV_GOTO 2)
68 (UNSPECV_FLUSH 4)
69 (UNSPECV_SETJMP 5)
70 (UNSPECV_SAVEW 6)
71 (UNSPECV_MEMBAR 7)
72 (UNSPECV_CAS 8)
73 (UNSPECV_SWAP 9)
74 (UNSPECV_LDSTUB 10)
75 ])
76
77 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
78 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
79 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
80 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
81 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
82
83
84 ;; Attribute for cpu type.
85 ;; These must match the values for enum processor_type in sparc.h.
86 (define_attr "cpu"
87 "v7,
88 cypress,
89 v8,
90 supersparc,
91 sparclite,f930,f934,
92 hypersparc,sparclite86x,
93 sparclet,tsc701,
94 v9,
95 ultrasparc,
96 ultrasparc3,
97 niagara,
98 niagara2"
99 (const (symbol_ref "sparc_cpu_attr")))
100
101 ;; Attribute for the instruction set.
102 ;; At present we only need to distinguish v9/!v9, but for clarity we
103 ;; test TARGET_V8 too.
104 (define_attr "isa" "v7,v8,v9,sparclet"
105 (const
106 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
107 (symbol_ref "TARGET_V8") (const_string "v8")
108 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
109 (const_string "v7"))))
110
111 ;; Insn type.
112 (define_attr "type"
113 "ialu,compare,shift,
114 load,sload,store,
115 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
116 imul,idiv,
117 fpload,fpstore,
118 fp,fpmove,
119 fpcmove,fpcrmove,
120 fpcmp,
121 fpmul,fpdivs,fpdivd,
122 fpsqrts,fpsqrtd,
123 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
124 cmove,
125 ialuX,
126 multi,savew,flushw,iflush,trap"
127 (const_string "ialu"))
128
129 ;; True if branch/call has empty delay slot and will emit a nop in it
130 (define_attr "empty_delay_slot" "false,true"
131 (symbol_ref "empty_delay_slot (insn)"))
132
133 (define_attr "branch_type" "none,icc,fcc,reg"
134 (const_string "none"))
135
136 (define_attr "pic" "false,true"
137 (symbol_ref "flag_pic != 0"))
138
139 (define_attr "calls_alloca" "false,true"
140 (symbol_ref "cfun->calls_alloca != 0"))
141
142 (define_attr "calls_eh_return" "false,true"
143 (symbol_ref "crtl->calls_eh_return !=0 "))
144
145 (define_attr "leaf_function" "false,true"
146 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
147
148 (define_attr "delayed_branch" "false,true"
149 (symbol_ref "flag_delayed_branch != 0"))
150
151 ;; Length (in # of insns).
152 ;; Beware that setting a length greater or equal to 3 for conditional branches
153 ;; has a side-effect (see output_cbranch and output_v9branch).
154 (define_attr "length" ""
155 (cond [(eq_attr "type" "uncond_branch,call")
156 (if_then_else (eq_attr "empty_delay_slot" "true")
157 (const_int 2)
158 (const_int 1))
159 (eq_attr "type" "sibcall")
160 (if_then_else (eq_attr "leaf_function" "true")
161 (if_then_else (eq_attr "empty_delay_slot" "true")
162 (const_int 3)
163 (const_int 2))
164 (if_then_else (eq_attr "empty_delay_slot" "true")
165 (const_int 2)
166 (const_int 1)))
167 (eq_attr "branch_type" "icc")
168 (if_then_else (match_operand 0 "noov_compare64_operator" "")
169 (if_then_else (lt (pc) (match_dup 1))
170 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
171 (if_then_else (eq_attr "empty_delay_slot" "true")
172 (const_int 2)
173 (const_int 1))
174 (if_then_else (eq_attr "empty_delay_slot" "true")
175 (const_int 4)
176 (const_int 3)))
177 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
178 (if_then_else (eq_attr "empty_delay_slot" "true")
179 (const_int 2)
180 (const_int 1))
181 (if_then_else (eq_attr "empty_delay_slot" "true")
182 (const_int 4)
183 (const_int 3))))
184 (if_then_else (eq_attr "empty_delay_slot" "true")
185 (const_int 2)
186 (const_int 1)))
187 (eq_attr "branch_type" "fcc")
188 (if_then_else (match_operand 0 "fcc0_register_operand" "")
189 (if_then_else (eq_attr "empty_delay_slot" "true")
190 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
191 (const_int 3)
192 (const_int 2))
193 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
194 (const_int 2)
195 (const_int 1)))
196 (if_then_else (lt (pc) (match_dup 2))
197 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
198 (if_then_else (eq_attr "empty_delay_slot" "true")
199 (const_int 2)
200 (const_int 1))
201 (if_then_else (eq_attr "empty_delay_slot" "true")
202 (const_int 4)
203 (const_int 3)))
204 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
205 (if_then_else (eq_attr "empty_delay_slot" "true")
206 (const_int 2)
207 (const_int 1))
208 (if_then_else (eq_attr "empty_delay_slot" "true")
209 (const_int 4)
210 (const_int 3)))))
211 (eq_attr "branch_type" "reg")
212 (if_then_else (lt (pc) (match_dup 2))
213 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
214 (if_then_else (eq_attr "empty_delay_slot" "true")
215 (const_int 2)
216 (const_int 1))
217 (if_then_else (eq_attr "empty_delay_slot" "true")
218 (const_int 4)
219 (const_int 3)))
220 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
221 (if_then_else (eq_attr "empty_delay_slot" "true")
222 (const_int 2)
223 (const_int 1))
224 (if_then_else (eq_attr "empty_delay_slot" "true")
225 (const_int 4)
226 (const_int 3))))
227 ] (const_int 1)))
228
229 ;; FP precision.
230 (define_attr "fptype" "single,double"
231 (const_string "single"))
232
233 ;; UltraSPARC-III integer load type.
234 (define_attr "us3load_type" "2cycle,3cycle"
235 (const_string "2cycle"))
236
237 (define_asm_attributes
238 [(set_attr "length" "2")
239 (set_attr "type" "multi")])
240
241 ;; Attributes for instruction and branch scheduling
242 (define_attr "tls_call_delay" "false,true"
243 (symbol_ref "tls_call_delay (insn)"))
244
245 (define_attr "in_call_delay" "false,true"
246 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
247 (const_string "false")
248 (eq_attr "type" "load,fpload,store,fpstore")
249 (if_then_else (eq_attr "length" "1")
250 (const_string "true")
251 (const_string "false"))]
252 (if_then_else (and (eq_attr "length" "1")
253 (eq_attr "tls_call_delay" "true"))
254 (const_string "true")
255 (const_string "false"))))
256
257 (define_attr "eligible_for_sibcall_delay" "false,true"
258 (symbol_ref "eligible_for_sibcall_delay (insn)"))
259
260 (define_attr "eligible_for_return_delay" "false,true"
261 (symbol_ref "eligible_for_return_delay (insn)"))
262
263 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
264 ;; branches. This would allow us to remove the nop always inserted before
265 ;; a floating point branch.
266
267 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
268 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
269 ;; This is because doing so will add several pipeline stalls to the path
270 ;; that the load/store did not come from. Unfortunately, there is no way
271 ;; to prevent fill_eager_delay_slots from using load/store without completely
272 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
273 ;; because it prevents us from moving back the final store of inner loops.
274
275 (define_attr "in_branch_delay" "false,true"
276 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
277 (eq_attr "length" "1"))
278 (const_string "true")
279 (const_string "false")))
280
281 (define_attr "in_uncond_branch_delay" "false,true"
282 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
283 (eq_attr "length" "1"))
284 (const_string "true")
285 (const_string "false")))
286
287 (define_attr "in_annul_branch_delay" "false,true"
288 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
289 (eq_attr "length" "1"))
290 (const_string "true")
291 (const_string "false")))
292
293 (define_delay (eq_attr "type" "call")
294 [(eq_attr "in_call_delay" "true") (nil) (nil)])
295
296 (define_delay (eq_attr "type" "sibcall")
297 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
298
299 (define_delay (eq_attr "type" "branch")
300 [(eq_attr "in_branch_delay" "true")
301 (nil) (eq_attr "in_annul_branch_delay" "true")])
302
303 (define_delay (eq_attr "type" "uncond_branch")
304 [(eq_attr "in_uncond_branch_delay" "true")
305 (nil) (nil)])
306
307 (define_delay (eq_attr "type" "return")
308 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
309
310
311 ;; Include SPARC DFA schedulers
312
313 (include "cypress.md")
314 (include "supersparc.md")
315 (include "hypersparc.md")
316 (include "sparclet.md")
317 (include "ultra1_2.md")
318 (include "ultra3.md")
319 (include "niagara.md")
320 (include "niagara2.md")
321
322
323 ;; Operand and operator predicates and constraints
324
325 (include "predicates.md")
326 (include "constraints.md")
327
328
329 ;; Compare instructions.
330
331 ;; We generate RTL for comparisons and branches by having the cmpxx
332 ;; patterns store away the operands. Then, the scc and bcc patterns
333 ;; emit RTL for both the compare and the branch.
334 ;;
335 ;; We do this because we want to generate different code for an sne and
336 ;; seq insn. In those cases, if the second operand of the compare is not
337 ;; const0_rtx, we want to compute the xor of the two operands and test
338 ;; it against zero.
339 ;;
340 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
341 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
342 ;; insns that actually require more than one machine instruction.
343
344 (define_expand "cmpsi"
345 [(set (reg:CC 100)
346 (compare:CC (match_operand:SI 0 "compare_operand" "")
347 (match_operand:SI 1 "arith_operand" "")))]
348 ""
349 {
350 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
351 operands[0] = force_reg (SImode, operands[0]);
352
353 sparc_compare_op0 = operands[0];
354 sparc_compare_op1 = operands[1];
355 DONE;
356 })
357
358 (define_expand "cmpdi"
359 [(set (reg:CCX 100)
360 (compare:CCX (match_operand:DI 0 "compare_operand" "")
361 (match_operand:DI 1 "arith_operand" "")))]
362 "TARGET_ARCH64"
363 {
364 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
365 operands[0] = force_reg (DImode, operands[0]);
366
367 sparc_compare_op0 = operands[0];
368 sparc_compare_op1 = operands[1];
369 DONE;
370 })
371
372 (define_expand "cmpsf"
373 ;; The 96 here isn't ever used by anyone.
374 [(set (reg:CCFP 96)
375 (compare:CCFP (match_operand:SF 0 "register_operand" "")
376 (match_operand:SF 1 "register_operand" "")))]
377 "TARGET_FPU"
378 {
379 sparc_compare_op0 = operands[0];
380 sparc_compare_op1 = operands[1];
381 DONE;
382 })
383
384 (define_expand "cmpdf"
385 ;; The 96 here isn't ever used by anyone.
386 [(set (reg:CCFP 96)
387 (compare:CCFP (match_operand:DF 0 "register_operand" "")
388 (match_operand:DF 1 "register_operand" "")))]
389 "TARGET_FPU"
390 {
391 sparc_compare_op0 = operands[0];
392 sparc_compare_op1 = operands[1];
393 DONE;
394 })
395
396 (define_expand "cmptf"
397 ;; The 96 here isn't ever used by anyone.
398 [(set (reg:CCFP 96)
399 (compare:CCFP (match_operand:TF 0 "register_operand" "")
400 (match_operand:TF 1 "register_operand" "")))]
401 "TARGET_FPU"
402 {
403 sparc_compare_op0 = operands[0];
404 sparc_compare_op1 = operands[1];
405 DONE;
406 })
407
408 ;; Now the compare DEFINE_INSNs.
409
410 (define_insn "*cmpsi_insn"
411 [(set (reg:CC 100)
412 (compare:CC (match_operand:SI 0 "register_operand" "r")
413 (match_operand:SI 1 "arith_operand" "rI")))]
414 ""
415 "cmp\t%0, %1"
416 [(set_attr "type" "compare")])
417
418 (define_insn "*cmpdi_sp64"
419 [(set (reg:CCX 100)
420 (compare:CCX (match_operand:DI 0 "register_operand" "r")
421 (match_operand:DI 1 "arith_operand" "rI")))]
422 "TARGET_ARCH64"
423 "cmp\t%0, %1"
424 [(set_attr "type" "compare")])
425
426 (define_insn "*cmpsf_fpe"
427 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
428 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
429 (match_operand:SF 2 "register_operand" "f")))]
430 "TARGET_FPU"
431 {
432 if (TARGET_V9)
433 return "fcmpes\t%0, %1, %2";
434 return "fcmpes\t%1, %2";
435 }
436 [(set_attr "type" "fpcmp")])
437
438 (define_insn "*cmpdf_fpe"
439 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
440 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
441 (match_operand:DF 2 "register_operand" "e")))]
442 "TARGET_FPU"
443 {
444 if (TARGET_V9)
445 return "fcmped\t%0, %1, %2";
446 return "fcmped\t%1, %2";
447 }
448 [(set_attr "type" "fpcmp")
449 (set_attr "fptype" "double")])
450
451 (define_insn "*cmptf_fpe"
452 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
453 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
454 (match_operand:TF 2 "register_operand" "e")))]
455 "TARGET_FPU && TARGET_HARD_QUAD"
456 {
457 if (TARGET_V9)
458 return "fcmpeq\t%0, %1, %2";
459 return "fcmpeq\t%1, %2";
460 }
461 [(set_attr "type" "fpcmp")])
462
463 (define_insn "*cmpsf_fp"
464 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
465 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
466 (match_operand:SF 2 "register_operand" "f")))]
467 "TARGET_FPU"
468 {
469 if (TARGET_V9)
470 return "fcmps\t%0, %1, %2";
471 return "fcmps\t%1, %2";
472 }
473 [(set_attr "type" "fpcmp")])
474
475 (define_insn "*cmpdf_fp"
476 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
477 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
478 (match_operand:DF 2 "register_operand" "e")))]
479 "TARGET_FPU"
480 {
481 if (TARGET_V9)
482 return "fcmpd\t%0, %1, %2";
483 return "fcmpd\t%1, %2";
484 }
485 [(set_attr "type" "fpcmp")
486 (set_attr "fptype" "double")])
487
488 (define_insn "*cmptf_fp"
489 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
490 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
491 (match_operand:TF 2 "register_operand" "e")))]
492 "TARGET_FPU && TARGET_HARD_QUAD"
493 {
494 if (TARGET_V9)
495 return "fcmpq\t%0, %1, %2";
496 return "fcmpq\t%1, %2";
497 }
498 [(set_attr "type" "fpcmp")])
499 \f
500 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
501 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
502 ;; the same code as v8 (the addx/subx method has more applications). The
503 ;; exception to this is "reg != 0" which can be done in one instruction on v9
504 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
505 ;; branches.
506
507 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
508 ;; generate addcc/subcc instructions.
509
510 (define_expand "seqsi_special"
511 [(set (match_dup 3)
512 (xor:SI (match_operand:SI 1 "register_operand" "")
513 (match_operand:SI 2 "register_operand" "")))
514 (parallel [(set (match_operand:SI 0 "register_operand" "")
515 (eq:SI (match_dup 3) (const_int 0)))
516 (clobber (reg:CC 100))])]
517 ""
518 { operands[3] = gen_reg_rtx (SImode); })
519
520 (define_expand "seqdi_special"
521 [(set (match_dup 3)
522 (xor:DI (match_operand:DI 1 "register_operand" "")
523 (match_operand:DI 2 "register_operand" "")))
524 (set (match_operand:DI 0 "register_operand" "")
525 (eq:DI (match_dup 3) (const_int 0)))]
526 "TARGET_ARCH64"
527 { operands[3] = gen_reg_rtx (DImode); })
528
529 (define_expand "snesi_special"
530 [(set (match_dup 3)
531 (xor:SI (match_operand:SI 1 "register_operand" "")
532 (match_operand:SI 2 "register_operand" "")))
533 (parallel [(set (match_operand:SI 0 "register_operand" "")
534 (ne:SI (match_dup 3) (const_int 0)))
535 (clobber (reg:CC 100))])]
536 ""
537 { operands[3] = gen_reg_rtx (SImode); })
538
539 (define_expand "snedi_special"
540 [(set (match_dup 3)
541 (xor:DI (match_operand:DI 1 "register_operand" "")
542 (match_operand:DI 2 "register_operand" "")))
543 (set (match_operand:DI 0 "register_operand" "")
544 (ne:DI (match_dup 3) (const_int 0)))]
545 "TARGET_ARCH64"
546 { operands[3] = gen_reg_rtx (DImode); })
547
548 (define_expand "seqdi_special_trunc"
549 [(set (match_dup 3)
550 (xor:DI (match_operand:DI 1 "register_operand" "")
551 (match_operand:DI 2 "register_operand" "")))
552 (set (match_operand:SI 0 "register_operand" "")
553 (eq:SI (match_dup 3) (const_int 0)))]
554 "TARGET_ARCH64"
555 { operands[3] = gen_reg_rtx (DImode); })
556
557 (define_expand "snedi_special_trunc"
558 [(set (match_dup 3)
559 (xor:DI (match_operand:DI 1 "register_operand" "")
560 (match_operand:DI 2 "register_operand" "")))
561 (set (match_operand:SI 0 "register_operand" "")
562 (ne:SI (match_dup 3) (const_int 0)))]
563 "TARGET_ARCH64"
564 { operands[3] = gen_reg_rtx (DImode); })
565
566 (define_expand "seqsi_special_extend"
567 [(set (match_dup 3)
568 (xor:SI (match_operand:SI 1 "register_operand" "")
569 (match_operand:SI 2 "register_operand" "")))
570 (parallel [(set (match_operand:DI 0 "register_operand" "")
571 (eq:DI (match_dup 3) (const_int 0)))
572 (clobber (reg:CC 100))])]
573 "TARGET_ARCH64"
574 { operands[3] = gen_reg_rtx (SImode); })
575
576 (define_expand "snesi_special_extend"
577 [(set (match_dup 3)
578 (xor:SI (match_operand:SI 1 "register_operand" "")
579 (match_operand:SI 2 "register_operand" "")))
580 (parallel [(set (match_operand:DI 0 "register_operand" "")
581 (ne:DI (match_dup 3) (const_int 0)))
582 (clobber (reg:CC 100))])]
583 "TARGET_ARCH64"
584 { operands[3] = gen_reg_rtx (SImode); })
585
586 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
587 ;; However, the code handles both SImode and DImode.
588 (define_expand "seq"
589 [(set (match_operand:SI 0 "int_register_operand" "")
590 (eq:SI (match_dup 1) (const_int 0)))]
591 ""
592 {
593 if (GET_MODE (sparc_compare_op0) == SImode)
594 {
595 rtx pat;
596
597 if (GET_MODE (operands[0]) == SImode)
598 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
599 sparc_compare_op1);
600 else if (! TARGET_ARCH64)
601 FAIL;
602 else
603 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
604 sparc_compare_op1);
605 emit_insn (pat);
606 DONE;
607 }
608 else if (GET_MODE (sparc_compare_op0) == DImode)
609 {
610 rtx pat;
611
612 if (! TARGET_ARCH64)
613 FAIL;
614 else if (GET_MODE (operands[0]) == SImode)
615 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
616 sparc_compare_op1);
617 else
618 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
619 sparc_compare_op1);
620 emit_insn (pat);
621 DONE;
622 }
623 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
624 {
625 enum rtx_code code
626 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
627 gcc_assert (code == NE);
628 emit_insn (gen_sne (operands[0]));
629 DONE;
630 }
631 else if (TARGET_V9)
632 {
633 if (gen_v9_scc (EQ, operands))
634 DONE;
635 /* fall through */
636 }
637 FAIL;
638 })
639
640 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
641 ;; However, the code handles both SImode and DImode.
642 (define_expand "sne"
643 [(set (match_operand:SI 0 "int_register_operand" "")
644 (ne:SI (match_dup 1) (const_int 0)))]
645 ""
646 {
647 if (GET_MODE (sparc_compare_op0) == SImode)
648 {
649 rtx pat;
650
651 if (GET_MODE (operands[0]) == SImode)
652 pat = gen_snesi_special (operands[0], sparc_compare_op0,
653 sparc_compare_op1);
654 else if (! TARGET_ARCH64)
655 FAIL;
656 else
657 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
658 sparc_compare_op1);
659 emit_insn (pat);
660 DONE;
661 }
662 else if (GET_MODE (sparc_compare_op0) == DImode)
663 {
664 rtx pat;
665
666 if (! TARGET_ARCH64)
667 FAIL;
668 else if (GET_MODE (operands[0]) == SImode)
669 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
670 sparc_compare_op1);
671 else
672 pat = gen_snedi_special (operands[0], sparc_compare_op0,
673 sparc_compare_op1);
674 emit_insn (pat);
675 DONE;
676 }
677 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
678 {
679 enum rtx_code code
680 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
681 gcc_assert (code == NE);
682 emit_insn (gen_sne (operands[0]));
683 DONE;
684 }
685 else if (TARGET_V9)
686 {
687 if (gen_v9_scc (NE, operands))
688 DONE;
689 /* fall through */
690 }
691 FAIL;
692 })
693
694 (define_expand "sgt"
695 [(set (match_operand:SI 0 "int_register_operand" "")
696 (gt:SI (match_dup 1) (const_int 0)))]
697 ""
698 {
699 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
700 {
701 enum rtx_code code
702 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
703 gcc_assert (code == NE);
704 emit_insn (gen_sne (operands[0]));
705 DONE;
706 }
707 else if (TARGET_V9)
708 {
709 if (gen_v9_scc (GT, operands))
710 DONE;
711 /* fall through */
712 }
713 FAIL;
714 })
715
716 (define_expand "slt"
717 [(set (match_operand:SI 0 "int_register_operand" "")
718 (lt:SI (match_dup 1) (const_int 0)))]
719 ""
720 {
721 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
722 {
723 enum rtx_code code
724 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
725 gcc_assert (code == NE);
726 emit_insn (gen_sne (operands[0]));
727 DONE;
728 }
729 else if (TARGET_V9)
730 {
731 if (gen_v9_scc (LT, operands))
732 DONE;
733 /* fall through */
734 }
735 FAIL;
736 })
737
738 (define_expand "sge"
739 [(set (match_operand:SI 0 "int_register_operand" "")
740 (ge:SI (match_dup 1) (const_int 0)))]
741 ""
742 {
743 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
744 {
745 enum rtx_code code
746 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
747 gcc_assert (code == NE);
748 emit_insn (gen_sne (operands[0]));
749 DONE;
750 }
751 else if (TARGET_V9)
752 {
753 if (gen_v9_scc (GE, operands))
754 DONE;
755 /* fall through */
756 }
757 FAIL;
758 })
759
760 (define_expand "sle"
761 [(set (match_operand:SI 0 "int_register_operand" "")
762 (le:SI (match_dup 1) (const_int 0)))]
763 ""
764 {
765 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
766 {
767 enum rtx_code code
768 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
769 gcc_assert (code == NE);
770 emit_insn (gen_sne (operands[0]));
771 DONE;
772 }
773 else if (TARGET_V9)
774 {
775 if (gen_v9_scc (LE, operands))
776 DONE;
777 /* fall through */
778 }
779 FAIL;
780 })
781
782 (define_expand "sgtu"
783 [(set (match_operand:SI 0 "int_register_operand" "")
784 (gtu:SI (match_dup 1) (const_int 0)))]
785 ""
786 {
787 if (! TARGET_V9)
788 {
789 rtx tem, pat;
790
791 /* We can do ltu easily, so if both operands are registers, swap them and
792 do a LTU. */
793 if ((GET_CODE (sparc_compare_op0) == REG
794 || GET_CODE (sparc_compare_op0) == SUBREG)
795 && (GET_CODE (sparc_compare_op1) == REG
796 || GET_CODE (sparc_compare_op1) == SUBREG))
797 {
798 tem = sparc_compare_op0;
799 sparc_compare_op0 = sparc_compare_op1;
800 sparc_compare_op1 = tem;
801 pat = gen_sltu (operands[0]);
802 if (pat == NULL_RTX)
803 FAIL;
804 emit_insn (pat);
805 DONE;
806 }
807 }
808 else
809 {
810 if (gen_v9_scc (GTU, operands))
811 DONE;
812 }
813 FAIL;
814 })
815
816 (define_expand "sltu"
817 [(set (match_operand:SI 0 "int_register_operand" "")
818 (ltu:SI (match_dup 1) (const_int 0)))]
819 ""
820 {
821 if (TARGET_V9)
822 {
823 if (gen_v9_scc (LTU, operands))
824 DONE;
825 }
826 operands[1] = gen_compare_reg (LTU);
827 })
828
829 (define_expand "sgeu"
830 [(set (match_operand:SI 0 "int_register_operand" "")
831 (geu:SI (match_dup 1) (const_int 0)))]
832 ""
833 {
834 if (TARGET_V9)
835 {
836 if (gen_v9_scc (GEU, operands))
837 DONE;
838 }
839 operands[1] = gen_compare_reg (GEU);
840 })
841
842 (define_expand "sleu"
843 [(set (match_operand:SI 0 "int_register_operand" "")
844 (leu:SI (match_dup 1) (const_int 0)))]
845 ""
846 {
847 if (! TARGET_V9)
848 {
849 rtx tem, pat;
850
851 /* We can do geu easily, so if both operands are registers, swap them and
852 do a GEU. */
853 if ((GET_CODE (sparc_compare_op0) == REG
854 || GET_CODE (sparc_compare_op0) == SUBREG)
855 && (GET_CODE (sparc_compare_op1) == REG
856 || GET_CODE (sparc_compare_op1) == SUBREG))
857 {
858 tem = sparc_compare_op0;
859 sparc_compare_op0 = sparc_compare_op1;
860 sparc_compare_op1 = tem;
861 pat = gen_sgeu (operands[0]);
862 if (pat == NULL_RTX)
863 FAIL;
864 emit_insn (pat);
865 DONE;
866 }
867 }
868 else
869 {
870 if (gen_v9_scc (LEU, operands))
871 DONE;
872 }
873 FAIL;
874 })
875
876 ;; Now the DEFINE_INSNs for the scc cases.
877
878 ;; The SEQ and SNE patterns are special because they can be done
879 ;; without any branching and do not involve a COMPARE. We want
880 ;; them to always use the splits below so the results can be
881 ;; scheduled.
882
883 (define_insn_and_split "*snesi_zero"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (ne:SI (match_operand:SI 1 "register_operand" "r")
886 (const_int 0)))
887 (clobber (reg:CC 100))]
888 ""
889 "#"
890 ""
891 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
892 (const_int 0)))
893 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
894 ""
895 [(set_attr "length" "2")])
896
897 (define_insn_and_split "*neg_snesi_zero"
898 [(set (match_operand:SI 0 "register_operand" "=r")
899 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
900 (const_int 0))))
901 (clobber (reg:CC 100))]
902 ""
903 "#"
904 ""
905 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
906 (const_int 0)))
907 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
908 ""
909 [(set_attr "length" "2")])
910
911 (define_insn_and_split "*snesi_zero_extend"
912 [(set (match_operand:DI 0 "register_operand" "=r")
913 (ne:DI (match_operand:SI 1 "register_operand" "r")
914 (const_int 0)))
915 (clobber (reg:CC 100))]
916 "TARGET_ARCH64"
917 "#"
918 "&& 1"
919 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
920 (match_dup 1))
921 (const_int 0)))
922 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
923 (const_int 0))
924 (ltu:SI (reg:CC_NOOV 100)
925 (const_int 0)))))]
926 ""
927 [(set_attr "length" "2")])
928
929 (define_insn_and_split "*snedi_zero"
930 [(set (match_operand:DI 0 "register_operand" "=&r")
931 (ne:DI (match_operand:DI 1 "register_operand" "r")
932 (const_int 0)))]
933 "TARGET_ARCH64"
934 "#"
935 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
936 [(set (match_dup 0) (const_int 0))
937 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
938 (const_int 0))
939 (const_int 1)
940 (match_dup 0)))]
941 ""
942 [(set_attr "length" "2")])
943
944 (define_insn_and_split "*neg_snedi_zero"
945 [(set (match_operand:DI 0 "register_operand" "=&r")
946 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
947 (const_int 0))))]
948 "TARGET_ARCH64"
949 "#"
950 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
951 [(set (match_dup 0) (const_int 0))
952 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
953 (const_int 0))
954 (const_int -1)
955 (match_dup 0)))]
956 ""
957 [(set_attr "length" "2")])
958
959 (define_insn_and_split "*snedi_zero_trunc"
960 [(set (match_operand:SI 0 "register_operand" "=&r")
961 (ne:SI (match_operand:DI 1 "register_operand" "r")
962 (const_int 0)))]
963 "TARGET_ARCH64"
964 "#"
965 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
966 [(set (match_dup 0) (const_int 0))
967 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
968 (const_int 0))
969 (const_int 1)
970 (match_dup 0)))]
971 ""
972 [(set_attr "length" "2")])
973
974 (define_insn_and_split "*seqsi_zero"
975 [(set (match_operand:SI 0 "register_operand" "=r")
976 (eq:SI (match_operand:SI 1 "register_operand" "r")
977 (const_int 0)))
978 (clobber (reg:CC 100))]
979 ""
980 "#"
981 ""
982 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
983 (const_int 0)))
984 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
985 ""
986 [(set_attr "length" "2")])
987
988 (define_insn_and_split "*neg_seqsi_zero"
989 [(set (match_operand:SI 0 "register_operand" "=r")
990 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
991 (const_int 0))))
992 (clobber (reg:CC 100))]
993 ""
994 "#"
995 ""
996 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
997 (const_int 0)))
998 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
999 ""
1000 [(set_attr "length" "2")])
1001
1002 (define_insn_and_split "*seqsi_zero_extend"
1003 [(set (match_operand:DI 0 "register_operand" "=r")
1004 (eq:DI (match_operand:SI 1 "register_operand" "r")
1005 (const_int 0)))
1006 (clobber (reg:CC 100))]
1007 "TARGET_ARCH64"
1008 "#"
1009 "&& 1"
1010 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
1011 (match_dup 1))
1012 (const_int 0)))
1013 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1014 (const_int -1))
1015 (ltu:SI (reg:CC_NOOV 100)
1016 (const_int 0)))))]
1017 ""
1018 [(set_attr "length" "2")])
1019
1020 (define_insn_and_split "*seqdi_zero"
1021 [(set (match_operand:DI 0 "register_operand" "=&r")
1022 (eq:DI (match_operand:DI 1 "register_operand" "r")
1023 (const_int 0)))]
1024 "TARGET_ARCH64"
1025 "#"
1026 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1027 [(set (match_dup 0) (const_int 0))
1028 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1029 (const_int 0))
1030 (const_int 1)
1031 (match_dup 0)))]
1032 ""
1033 [(set_attr "length" "2")])
1034
1035 (define_insn_and_split "*neg_seqdi_zero"
1036 [(set (match_operand:DI 0 "register_operand" "=&r")
1037 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1038 (const_int 0))))]
1039 "TARGET_ARCH64"
1040 "#"
1041 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1042 [(set (match_dup 0) (const_int 0))
1043 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1044 (const_int 0))
1045 (const_int -1)
1046 (match_dup 0)))]
1047 ""
1048 [(set_attr "length" "2")])
1049
1050 (define_insn_and_split "*seqdi_zero_trunc"
1051 [(set (match_operand:SI 0 "register_operand" "=&r")
1052 (eq:SI (match_operand:DI 1 "register_operand" "r")
1053 (const_int 0)))]
1054 "TARGET_ARCH64"
1055 "#"
1056 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1057 [(set (match_dup 0) (const_int 0))
1058 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1059 (const_int 0))
1060 (const_int 1)
1061 (match_dup 0)))]
1062 ""
1063 [(set_attr "length" "2")])
1064
1065 ;; We can also do (x + (i == 0)) and related, so put them in.
1066 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1067 ;; versions for v9.
1068
1069 (define_insn_and_split "*x_plus_i_ne_0"
1070 [(set (match_operand:SI 0 "register_operand" "=r")
1071 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1072 (const_int 0))
1073 (match_operand:SI 2 "register_operand" "r")))
1074 (clobber (reg:CC 100))]
1075 ""
1076 "#"
1077 ""
1078 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1079 (const_int 0)))
1080 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1081 (match_dup 2)))]
1082 ""
1083 [(set_attr "length" "2")])
1084
1085 (define_insn_and_split "*x_minus_i_ne_0"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1087 (minus:SI (match_operand:SI 2 "register_operand" "r")
1088 (ne:SI (match_operand:SI 1 "register_operand" "r")
1089 (const_int 0))))
1090 (clobber (reg:CC 100))]
1091 ""
1092 "#"
1093 ""
1094 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1095 (const_int 0)))
1096 (set (match_dup 0) (minus:SI (match_dup 2)
1097 (ltu:SI (reg:CC 100) (const_int 0))))]
1098 ""
1099 [(set_attr "length" "2")])
1100
1101 (define_insn_and_split "*x_plus_i_eq_0"
1102 [(set (match_operand:SI 0 "register_operand" "=r")
1103 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1104 (const_int 0))
1105 (match_operand:SI 2 "register_operand" "r")))
1106 (clobber (reg:CC 100))]
1107 ""
1108 "#"
1109 ""
1110 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1111 (const_int 0)))
1112 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1113 (match_dup 2)))]
1114 ""
1115 [(set_attr "length" "2")])
1116
1117 (define_insn_and_split "*x_minus_i_eq_0"
1118 [(set (match_operand:SI 0 "register_operand" "=r")
1119 (minus:SI (match_operand:SI 2 "register_operand" "r")
1120 (eq:SI (match_operand:SI 1 "register_operand" "r")
1121 (const_int 0))))
1122 (clobber (reg:CC 100))]
1123 ""
1124 "#"
1125 ""
1126 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1127 (const_int 0)))
1128 (set (match_dup 0) (minus:SI (match_dup 2)
1129 (geu:SI (reg:CC 100) (const_int 0))))]
1130 ""
1131 [(set_attr "length" "2")])
1132
1133 ;; We can also do GEU and LTU directly, but these operate after a compare.
1134 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1135 ;; versions for v9.
1136
1137 (define_insn "*sltu_insn"
1138 [(set (match_operand:SI 0 "register_operand" "=r")
1139 (ltu:SI (reg:CC 100) (const_int 0)))]
1140 ""
1141 "addx\t%%g0, 0, %0"
1142 [(set_attr "type" "ialuX")])
1143
1144 (define_insn "*neg_sltu_insn"
1145 [(set (match_operand:SI 0 "register_operand" "=r")
1146 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1147 ""
1148 "subx\t%%g0, 0, %0"
1149 [(set_attr "type" "ialuX")])
1150
1151 ;; ??? Combine should canonicalize these next two to the same pattern.
1152 (define_insn "*neg_sltu_minus_x"
1153 [(set (match_operand:SI 0 "register_operand" "=r")
1154 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1155 (match_operand:SI 1 "arith_operand" "rI")))]
1156 ""
1157 "subx\t%%g0, %1, %0"
1158 [(set_attr "type" "ialuX")])
1159
1160 (define_insn "*neg_sltu_plus_x"
1161 [(set (match_operand:SI 0 "register_operand" "=r")
1162 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1163 (match_operand:SI 1 "arith_operand" "rI"))))]
1164 ""
1165 "subx\t%%g0, %1, %0"
1166 [(set_attr "type" "ialuX")])
1167
1168 (define_insn "*sgeu_insn"
1169 [(set (match_operand:SI 0 "register_operand" "=r")
1170 (geu:SI (reg:CC 100) (const_int 0)))]
1171 ""
1172 "subx\t%%g0, -1, %0"
1173 [(set_attr "type" "ialuX")])
1174
1175 (define_insn "*neg_sgeu_insn"
1176 [(set (match_operand:SI 0 "register_operand" "=r")
1177 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1178 ""
1179 "addx\t%%g0, -1, %0"
1180 [(set_attr "type" "ialuX")])
1181
1182 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1183 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1184 ;; versions for v9.
1185
1186 (define_insn "*sltu_plus_x"
1187 [(set (match_operand:SI 0 "register_operand" "=r")
1188 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1189 (match_operand:SI 1 "arith_operand" "rI")))]
1190 ""
1191 "addx\t%%g0, %1, %0"
1192 [(set_attr "type" "ialuX")])
1193
1194 (define_insn "*sltu_plus_x_plus_y"
1195 [(set (match_operand:SI 0 "register_operand" "=r")
1196 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1197 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1198 (match_operand:SI 2 "arith_operand" "rI"))))]
1199 ""
1200 "addx\t%1, %2, %0"
1201 [(set_attr "type" "ialuX")])
1202
1203 (define_insn "*x_minus_sltu"
1204 [(set (match_operand:SI 0 "register_operand" "=r")
1205 (minus:SI (match_operand:SI 1 "register_operand" "r")
1206 (ltu:SI (reg:CC 100) (const_int 0))))]
1207 ""
1208 "subx\t%1, 0, %0"
1209 [(set_attr "type" "ialuX")])
1210
1211 ;; ??? Combine should canonicalize these next two to the same pattern.
1212 (define_insn "*x_minus_y_minus_sltu"
1213 [(set (match_operand:SI 0 "register_operand" "=r")
1214 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1215 (match_operand:SI 2 "arith_operand" "rI"))
1216 (ltu:SI (reg:CC 100) (const_int 0))))]
1217 ""
1218 "subx\t%r1, %2, %0"
1219 [(set_attr "type" "ialuX")])
1220
1221 (define_insn "*x_minus_sltu_plus_y"
1222 [(set (match_operand:SI 0 "register_operand" "=r")
1223 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1224 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1225 (match_operand:SI 2 "arith_operand" "rI"))))]
1226 ""
1227 "subx\t%r1, %2, %0"
1228 [(set_attr "type" "ialuX")])
1229
1230 (define_insn "*sgeu_plus_x"
1231 [(set (match_operand:SI 0 "register_operand" "=r")
1232 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1233 (match_operand:SI 1 "register_operand" "r")))]
1234 ""
1235 "subx\t%1, -1, %0"
1236 [(set_attr "type" "ialuX")])
1237
1238 (define_insn "*x_minus_sgeu"
1239 [(set (match_operand:SI 0 "register_operand" "=r")
1240 (minus:SI (match_operand:SI 1 "register_operand" "r")
1241 (geu:SI (reg:CC 100) (const_int 0))))]
1242 ""
1243 "addx\t%1, -1, %0"
1244 [(set_attr "type" "ialuX")])
1245
1246 (define_split
1247 [(set (match_operand:SI 0 "register_operand" "")
1248 (match_operator:SI 2 "noov_compare_operator"
1249 [(match_operand 1 "icc_or_fcc_register_operand" "")
1250 (const_int 0)]))]
1251 "TARGET_V9
1252 && REGNO (operands[1]) == SPARC_ICC_REG
1253 && (GET_MODE (operands[1]) == CCXmode
1254 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1255 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1256 [(set (match_dup 0) (const_int 0))
1257 (set (match_dup 0)
1258 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1259 (const_int 1)
1260 (match_dup 0)))]
1261 "")
1262
1263 \f
1264 ;; These control RTL generation for conditional jump insns
1265
1266 ;; The quad-word fp compare library routines all return nonzero to indicate
1267 ;; true, which is different from the equivalent libgcc routines, so we must
1268 ;; handle them specially here.
1269
1270 (define_expand "beq"
1271 [(set (pc)
1272 (if_then_else (eq (match_dup 1) (const_int 0))
1273 (label_ref (match_operand 0 "" ""))
1274 (pc)))]
1275 ""
1276 {
1277 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1278 && GET_CODE (sparc_compare_op0) == REG
1279 && GET_MODE (sparc_compare_op0) == DImode)
1280 {
1281 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1282 DONE;
1283 }
1284 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1285 {
1286 enum rtx_code code
1287 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1288 gcc_assert (code == NE);
1289 emit_jump_insn (gen_bne (operands[0]));
1290 DONE;
1291 }
1292 operands[1] = gen_compare_reg (EQ);
1293 })
1294
1295 (define_expand "bne"
1296 [(set (pc)
1297 (if_then_else (ne (match_dup 1) (const_int 0))
1298 (label_ref (match_operand 0 "" ""))
1299 (pc)))]
1300 ""
1301 {
1302 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1303 && GET_CODE (sparc_compare_op0) == REG
1304 && GET_MODE (sparc_compare_op0) == DImode)
1305 {
1306 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1307 DONE;
1308 }
1309 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1310 {
1311 enum rtx_code code
1312 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1313 gcc_assert (code == NE);
1314 emit_jump_insn (gen_bne (operands[0]));
1315 DONE;
1316 }
1317 operands[1] = gen_compare_reg (NE);
1318 })
1319
1320 (define_expand "bgt"
1321 [(set (pc)
1322 (if_then_else (gt (match_dup 1) (const_int 0))
1323 (label_ref (match_operand 0 "" ""))
1324 (pc)))]
1325 ""
1326 {
1327 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1328 && GET_CODE (sparc_compare_op0) == REG
1329 && GET_MODE (sparc_compare_op0) == DImode)
1330 {
1331 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1332 DONE;
1333 }
1334 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1335 {
1336 enum rtx_code code
1337 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1338 gcc_assert (code == NE);
1339 emit_jump_insn (gen_bne (operands[0]));
1340 DONE;
1341 }
1342 operands[1] = gen_compare_reg (GT);
1343 })
1344
1345 (define_expand "bgtu"
1346 [(set (pc)
1347 (if_then_else (gtu (match_dup 1) (const_int 0))
1348 (label_ref (match_operand 0 "" ""))
1349 (pc)))]
1350 ""
1351 {
1352 operands[1] = gen_compare_reg (GTU);
1353 })
1354
1355 (define_expand "blt"
1356 [(set (pc)
1357 (if_then_else (lt (match_dup 1) (const_int 0))
1358 (label_ref (match_operand 0 "" ""))
1359 (pc)))]
1360 ""
1361 {
1362 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1363 && GET_CODE (sparc_compare_op0) == REG
1364 && GET_MODE (sparc_compare_op0) == DImode)
1365 {
1366 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1367 DONE;
1368 }
1369 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1370 {
1371 enum rtx_code code
1372 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1373 gcc_assert (code == NE);
1374 emit_jump_insn (gen_bne (operands[0]));
1375 DONE;
1376 }
1377 operands[1] = gen_compare_reg (LT);
1378 })
1379
1380 (define_expand "bltu"
1381 [(set (pc)
1382 (if_then_else (ltu (match_dup 1) (const_int 0))
1383 (label_ref (match_operand 0 "" ""))
1384 (pc)))]
1385 ""
1386 {
1387 operands[1] = gen_compare_reg (LTU);
1388 })
1389
1390 (define_expand "bge"
1391 [(set (pc)
1392 (if_then_else (ge (match_dup 1) (const_int 0))
1393 (label_ref (match_operand 0 "" ""))
1394 (pc)))]
1395 ""
1396 {
1397 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1398 && GET_CODE (sparc_compare_op0) == REG
1399 && GET_MODE (sparc_compare_op0) == DImode)
1400 {
1401 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1402 DONE;
1403 }
1404 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1405 {
1406 enum rtx_code code
1407 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1408 gcc_assert (code == NE);
1409 emit_jump_insn (gen_bne (operands[0]));
1410 DONE;
1411 }
1412 operands[1] = gen_compare_reg (GE);
1413 })
1414
1415 (define_expand "bgeu"
1416 [(set (pc)
1417 (if_then_else (geu (match_dup 1) (const_int 0))
1418 (label_ref (match_operand 0 "" ""))
1419 (pc)))]
1420 ""
1421 {
1422 operands[1] = gen_compare_reg (GEU);
1423 })
1424
1425 (define_expand "ble"
1426 [(set (pc)
1427 (if_then_else (le (match_dup 1) (const_int 0))
1428 (label_ref (match_operand 0 "" ""))
1429 (pc)))]
1430 ""
1431 {
1432 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1433 && GET_CODE (sparc_compare_op0) == REG
1434 && GET_MODE (sparc_compare_op0) == DImode)
1435 {
1436 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1437 DONE;
1438 }
1439 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1440 {
1441 enum rtx_code code
1442 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1443 gcc_assert (code == NE);
1444 emit_jump_insn (gen_bne (operands[0]));
1445 DONE;
1446 }
1447 operands[1] = gen_compare_reg (LE);
1448 })
1449
1450 (define_expand "bleu"
1451 [(set (pc)
1452 (if_then_else (leu (match_dup 1) (const_int 0))
1453 (label_ref (match_operand 0 "" ""))
1454 (pc)))]
1455 ""
1456 {
1457 operands[1] = gen_compare_reg (LEU);
1458 })
1459
1460 (define_expand "bunordered"
1461 [(set (pc)
1462 (if_then_else (unordered (match_dup 1) (const_int 0))
1463 (label_ref (match_operand 0 "" ""))
1464 (pc)))]
1465 ""
1466 {
1467 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1468 {
1469 enum rtx_code code
1470 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED);
1471 gcc_assert (code == EQ);
1472 emit_jump_insn (gen_beq (operands[0]));
1473 DONE;
1474 }
1475 operands[1] = gen_compare_reg (UNORDERED);
1476 })
1477
1478 (define_expand "bordered"
1479 [(set (pc)
1480 (if_then_else (ordered (match_dup 1) (const_int 0))
1481 (label_ref (match_operand 0 "" ""))
1482 (pc)))]
1483 ""
1484 {
1485 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1486 {
1487 enum rtx_code code
1488 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1489 gcc_assert (code == NE);
1490 emit_jump_insn (gen_bne (operands[0]));
1491 DONE;
1492 }
1493 operands[1] = gen_compare_reg (ORDERED);
1494 })
1495
1496 (define_expand "bungt"
1497 [(set (pc)
1498 (if_then_else (ungt (match_dup 1) (const_int 0))
1499 (label_ref (match_operand 0 "" ""))
1500 (pc)))]
1501 ""
1502 {
1503 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1504 {
1505 enum rtx_code code
1506 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1507 gcc_assert (code == GT);
1508 emit_jump_insn (gen_bgt (operands[0]));
1509 DONE;
1510 }
1511 operands[1] = gen_compare_reg (UNGT);
1512 })
1513
1514 (define_expand "bunlt"
1515 [(set (pc)
1516 (if_then_else (unlt (match_dup 1) (const_int 0))
1517 (label_ref (match_operand 0 "" ""))
1518 (pc)))]
1519 ""
1520 {
1521 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1522 {
1523 enum rtx_code code
1524 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1525 gcc_assert (code == NE);
1526 emit_jump_insn (gen_bne (operands[0]));
1527 DONE;
1528 }
1529 operands[1] = gen_compare_reg (UNLT);
1530 })
1531
1532 (define_expand "buneq"
1533 [(set (pc)
1534 (if_then_else (uneq (match_dup 1) (const_int 0))
1535 (label_ref (match_operand 0 "" ""))
1536 (pc)))]
1537 ""
1538 {
1539 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1540 {
1541 enum rtx_code code
1542 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1543 gcc_assert (code == EQ);
1544 emit_jump_insn (gen_beq (operands[0]));
1545 DONE;
1546 }
1547 operands[1] = gen_compare_reg (UNEQ);
1548 })
1549
1550 (define_expand "bunge"
1551 [(set (pc)
1552 (if_then_else (unge (match_dup 1) (const_int 0))
1553 (label_ref (match_operand 0 "" ""))
1554 (pc)))]
1555 ""
1556 {
1557 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1558 {
1559 enum rtx_code code
1560 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1561 gcc_assert (code == NE);
1562 emit_jump_insn (gen_bne (operands[0]));
1563 DONE;
1564 }
1565 operands[1] = gen_compare_reg (UNGE);
1566 })
1567
1568 (define_expand "bunle"
1569 [(set (pc)
1570 (if_then_else (unle (match_dup 1) (const_int 0))
1571 (label_ref (match_operand 0 "" ""))
1572 (pc)))]
1573 ""
1574 {
1575 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1576 {
1577 enum rtx_code code
1578 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1579 gcc_assert (code == NE);
1580 emit_jump_insn (gen_bne (operands[0]));
1581 DONE;
1582 }
1583 operands[1] = gen_compare_reg (UNLE);
1584 })
1585
1586 (define_expand "bltgt"
1587 [(set (pc)
1588 (if_then_else (ltgt (match_dup 1) (const_int 0))
1589 (label_ref (match_operand 0 "" ""))
1590 (pc)))]
1591 ""
1592 {
1593 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1594 {
1595 enum rtx_code code
1596 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1597 gcc_assert (code == NE);
1598 emit_jump_insn (gen_bne (operands[0]));
1599 DONE;
1600 }
1601 operands[1] = gen_compare_reg (LTGT);
1602 })
1603 \f
1604 ;; Now match both normal and inverted jump.
1605
1606 ;; XXX fpcmp nop braindamage
1607 (define_insn "*normal_branch"
1608 [(set (pc)
1609 (if_then_else (match_operator 0 "noov_compare_operator"
1610 [(reg 100) (const_int 0)])
1611 (label_ref (match_operand 1 "" ""))
1612 (pc)))]
1613 ""
1614 {
1615 return output_cbranch (operands[0], operands[1], 1, 0,
1616 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1617 insn);
1618 }
1619 [(set_attr "type" "branch")
1620 (set_attr "branch_type" "icc")])
1621
1622 ;; XXX fpcmp nop braindamage
1623 (define_insn "*inverted_branch"
1624 [(set (pc)
1625 (if_then_else (match_operator 0 "noov_compare_operator"
1626 [(reg 100) (const_int 0)])
1627 (pc)
1628 (label_ref (match_operand 1 "" ""))))]
1629 ""
1630 {
1631 return output_cbranch (operands[0], operands[1], 1, 1,
1632 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1633 insn);
1634 }
1635 [(set_attr "type" "branch")
1636 (set_attr "branch_type" "icc")])
1637
1638 ;; XXX fpcmp nop braindamage
1639 (define_insn "*normal_fp_branch"
1640 [(set (pc)
1641 (if_then_else (match_operator 1 "comparison_operator"
1642 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1643 (const_int 0)])
1644 (label_ref (match_operand 2 "" ""))
1645 (pc)))]
1646 ""
1647 {
1648 return output_cbranch (operands[1], operands[2], 2, 0,
1649 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1650 insn);
1651 }
1652 [(set_attr "type" "branch")
1653 (set_attr "branch_type" "fcc")])
1654
1655 ;; XXX fpcmp nop braindamage
1656 (define_insn "*inverted_fp_branch"
1657 [(set (pc)
1658 (if_then_else (match_operator 1 "comparison_operator"
1659 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1660 (const_int 0)])
1661 (pc)
1662 (label_ref (match_operand 2 "" ""))))]
1663 ""
1664 {
1665 return output_cbranch (operands[1], operands[2], 2, 1,
1666 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1667 insn);
1668 }
1669 [(set_attr "type" "branch")
1670 (set_attr "branch_type" "fcc")])
1671
1672 ;; XXX fpcmp nop braindamage
1673 (define_insn "*normal_fpe_branch"
1674 [(set (pc)
1675 (if_then_else (match_operator 1 "comparison_operator"
1676 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1677 (const_int 0)])
1678 (label_ref (match_operand 2 "" ""))
1679 (pc)))]
1680 ""
1681 {
1682 return output_cbranch (operands[1], operands[2], 2, 0,
1683 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1684 insn);
1685 }
1686 [(set_attr "type" "branch")
1687 (set_attr "branch_type" "fcc")])
1688
1689 ;; XXX fpcmp nop braindamage
1690 (define_insn "*inverted_fpe_branch"
1691 [(set (pc)
1692 (if_then_else (match_operator 1 "comparison_operator"
1693 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1694 (const_int 0)])
1695 (pc)
1696 (label_ref (match_operand 2 "" ""))))]
1697 ""
1698 {
1699 return output_cbranch (operands[1], operands[2], 2, 1,
1700 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1701 insn);
1702 }
1703 [(set_attr "type" "branch")
1704 (set_attr "branch_type" "fcc")])
1705
1706 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1707 ;; in the architecture.
1708
1709 ;; There are no 32 bit brreg insns.
1710
1711 ;; XXX
1712 (define_insn "*normal_int_branch_sp64"
1713 [(set (pc)
1714 (if_then_else (match_operator 0 "v9_register_compare_operator"
1715 [(match_operand:DI 1 "register_operand" "r")
1716 (const_int 0)])
1717 (label_ref (match_operand 2 "" ""))
1718 (pc)))]
1719 "TARGET_ARCH64"
1720 {
1721 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1722 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1723 insn);
1724 }
1725 [(set_attr "type" "branch")
1726 (set_attr "branch_type" "reg")])
1727
1728 ;; XXX
1729 (define_insn "*inverted_int_branch_sp64"
1730 [(set (pc)
1731 (if_then_else (match_operator 0 "v9_register_compare_operator"
1732 [(match_operand:DI 1 "register_operand" "r")
1733 (const_int 0)])
1734 (pc)
1735 (label_ref (match_operand 2 "" ""))))]
1736 "TARGET_ARCH64"
1737 {
1738 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1739 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1740 insn);
1741 }
1742 [(set_attr "type" "branch")
1743 (set_attr "branch_type" "reg")])
1744
1745
1746 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1747
1748 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1749 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1750 ;; that adds the PC value at the call point to operand 0.
1751
1752 (define_insn "load_pcrel_sym<P:mode>"
1753 [(set (match_operand:P 0 "register_operand" "=r")
1754 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1755 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1756 (clobber (reg:P 15))]
1757 ""
1758 {
1759 if (flag_delayed_branch)
1760 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1761 else
1762 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1763 }
1764 [(set (attr "type") (const_string "multi"))
1765 (set (attr "length")
1766 (if_then_else (eq_attr "delayed_branch" "true")
1767 (const_int 3)
1768 (const_int 4)))])
1769
1770
1771 ;; Integer move instructions
1772
1773 (define_expand "movqi"
1774 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1775 (match_operand:QI 1 "general_operand" ""))]
1776 ""
1777 {
1778 if (sparc_expand_move (QImode, operands))
1779 DONE;
1780 })
1781
1782 (define_insn "*movqi_insn"
1783 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1784 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1785 "(register_operand (operands[0], QImode)
1786 || register_or_zero_operand (operands[1], QImode))"
1787 "@
1788 mov\t%1, %0
1789 ldub\t%1, %0
1790 stb\t%r1, %0"
1791 [(set_attr "type" "*,load,store")
1792 (set_attr "us3load_type" "*,3cycle,*")])
1793
1794 (define_expand "movhi"
1795 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1796 (match_operand:HI 1 "general_operand" ""))]
1797 ""
1798 {
1799 if (sparc_expand_move (HImode, operands))
1800 DONE;
1801 })
1802
1803 (define_insn "*movhi_insn"
1804 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1805 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1806 "(register_operand (operands[0], HImode)
1807 || register_or_zero_operand (operands[1], HImode))"
1808 "@
1809 mov\t%1, %0
1810 sethi\t%%hi(%a1), %0
1811 lduh\t%1, %0
1812 sth\t%r1, %0"
1813 [(set_attr "type" "*,*,load,store")
1814 (set_attr "us3load_type" "*,*,3cycle,*")])
1815
1816 ;; We always work with constants here.
1817 (define_insn "*movhi_lo_sum"
1818 [(set (match_operand:HI 0 "register_operand" "=r")
1819 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1820 (match_operand:HI 2 "small_int_operand" "I")))]
1821 ""
1822 "or\t%1, %2, %0")
1823
1824 (define_expand "movsi"
1825 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1826 (match_operand:SI 1 "general_operand" ""))]
1827 ""
1828 {
1829 if (sparc_expand_move (SImode, operands))
1830 DONE;
1831 })
1832
1833 (define_insn "*movsi_insn"
1834 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1835 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1836 "(register_operand (operands[0], SImode)
1837 || register_or_zero_operand (operands[1], SImode))"
1838 "@
1839 mov\t%1, %0
1840 sethi\t%%hi(%a1), %0
1841 ld\t%1, %0
1842 st\t%r1, %0
1843 fmovs\t%1, %0
1844 ld\t%1, %0
1845 st\t%1, %0
1846 fzeros\t%0"
1847 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1848
1849 (define_insn "*movsi_lo_sum"
1850 [(set (match_operand:SI 0 "register_operand" "=r")
1851 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1852 (match_operand:SI 2 "immediate_operand" "in")))]
1853 ""
1854 "or\t%1, %%lo(%a2), %0")
1855
1856 (define_insn "*movsi_high"
1857 [(set (match_operand:SI 0 "register_operand" "=r")
1858 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1859 ""
1860 "sethi\t%%hi(%a1), %0")
1861
1862 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1863 ;; so that CSE won't optimize the address computation away.
1864 (define_insn "movsi_lo_sum_pic"
1865 [(set (match_operand:SI 0 "register_operand" "=r")
1866 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1867 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1868 "flag_pic"
1869 "or\t%1, %%lo(%a2), %0")
1870
1871 (define_insn "movsi_high_pic"
1872 [(set (match_operand:SI 0 "register_operand" "=r")
1873 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1874 "flag_pic && check_pic (1)"
1875 "sethi\t%%hi(%a1), %0")
1876
1877 (define_expand "movsi_pic_label_ref"
1878 [(set (match_dup 3) (high:SI
1879 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1880 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1881 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1882 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1883 (set (match_operand:SI 0 "register_operand" "=r")
1884 (minus:SI (match_dup 5) (match_dup 4)))]
1885 "flag_pic"
1886 {
1887 crtl->uses_pic_offset_table = 1;
1888 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1889 if (!can_create_pseudo_p ())
1890 {
1891 operands[3] = operands[0];
1892 operands[4] = operands[0];
1893 }
1894 else
1895 {
1896 operands[3] = gen_reg_rtx (SImode);
1897 operands[4] = gen_reg_rtx (SImode);
1898 }
1899 operands[5] = pic_offset_table_rtx;
1900 })
1901
1902 (define_insn "*movsi_high_pic_label_ref"
1903 [(set (match_operand:SI 0 "register_operand" "=r")
1904 (high:SI
1905 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1906 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1907 "flag_pic"
1908 "sethi\t%%hi(%a2-(%a1-.)), %0")
1909
1910 (define_insn "*movsi_lo_sum_pic_label_ref"
1911 [(set (match_operand:SI 0 "register_operand" "=r")
1912 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1913 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1914 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1915 "flag_pic"
1916 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1917
1918 ;; Set up the PIC register for VxWorks.
1919
1920 (define_expand "vxworks_load_got"
1921 [(set (match_dup 0)
1922 (high:SI (match_dup 1)))
1923 (set (match_dup 0)
1924 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1925 (set (match_dup 0)
1926 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1927 "TARGET_VXWORKS_RTP"
1928 {
1929 operands[0] = pic_offset_table_rtx;
1930 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1931 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1932 })
1933
1934 (define_expand "movdi"
1935 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1936 (match_operand:DI 1 "general_operand" ""))]
1937 ""
1938 {
1939 if (sparc_expand_move (DImode, operands))
1940 DONE;
1941 })
1942
1943 ;; Be careful, fmovd does not exist when !v9.
1944 ;; We match MEM moves directly when we have correct even
1945 ;; numbered registers, but fall into splits otherwise.
1946 ;; The constraint ordering here is really important to
1947 ;; avoid insane problems in reload, especially for patterns
1948 ;; of the form:
1949 ;;
1950 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1951 ;; (const_int -5016)))
1952 ;; (reg:DI 2 %g2))
1953 ;;
1954
1955 (define_insn "*movdi_insn_sp32"
1956 [(set (match_operand:DI 0 "nonimmediate_operand"
1957 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1958 (match_operand:DI 1 "input_operand"
1959 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1960 "! TARGET_V9
1961 && (register_operand (operands[0], DImode)
1962 || register_or_zero_operand (operands[1], DImode))"
1963 "@
1964 #
1965 std\t%1, %0
1966 ldd\t%1, %0
1967 #
1968 #
1969 #
1970 #
1971 std\t%1, %0
1972 ldd\t%1, %0
1973 #
1974 #
1975 #"
1976 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1977 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1978
1979 (define_insn "*movdi_insn_sp32_v9"
1980 [(set (match_operand:DI 0 "nonimmediate_operand"
1981 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1982 (match_operand:DI 1 "input_operand"
1983 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1984 "! TARGET_ARCH64
1985 && TARGET_V9
1986 && (register_operand (operands[0], DImode)
1987 || register_or_zero_operand (operands[1], DImode))"
1988 "@
1989 stx\t%%g0, %0
1990 #
1991 std\t%1, %0
1992 ldd\t%1, %0
1993 #
1994 #
1995 #
1996 #
1997 std\t%1, %0
1998 ldd\t%1, %0
1999 #
2000 #
2001 fmovd\\t%1, %0
2002 ldd\\t%1, %0
2003 std\\t%1, %0"
2004 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2005 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2006 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2007
2008 (define_insn "*movdi_insn_sp64"
2009 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
2010 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
2011 "TARGET_ARCH64
2012 && (register_operand (operands[0], DImode)
2013 || register_or_zero_operand (operands[1], DImode))"
2014 "@
2015 mov\t%1, %0
2016 sethi\t%%hi(%a1), %0
2017 ldx\t%1, %0
2018 stx\t%r1, %0
2019 fmovd\t%1, %0
2020 ldd\t%1, %0
2021 std\t%1, %0
2022 fzero\t%0"
2023 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
2024 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
2025
2026 (define_expand "movdi_pic_label_ref"
2027 [(set (match_dup 3) (high:DI
2028 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2029 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2030 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2031 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2032 (set (match_operand:DI 0 "register_operand" "=r")
2033 (minus:DI (match_dup 5) (match_dup 4)))]
2034 "TARGET_ARCH64 && flag_pic"
2035 {
2036 crtl->uses_pic_offset_table = 1;
2037 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2038 if (!can_create_pseudo_p ())
2039 {
2040 operands[3] = operands[0];
2041 operands[4] = operands[0];
2042 }
2043 else
2044 {
2045 operands[3] = gen_reg_rtx (DImode);
2046 operands[4] = gen_reg_rtx (DImode);
2047 }
2048 operands[5] = pic_offset_table_rtx;
2049 })
2050
2051 (define_insn "*movdi_high_pic_label_ref"
2052 [(set (match_operand:DI 0 "register_operand" "=r")
2053 (high:DI
2054 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2055 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2056 "TARGET_ARCH64 && flag_pic"
2057 "sethi\t%%hi(%a2-(%a1-.)), %0")
2058
2059 (define_insn "*movdi_lo_sum_pic_label_ref"
2060 [(set (match_operand:DI 0 "register_operand" "=r")
2061 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2062 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2063 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2064 "TARGET_ARCH64 && flag_pic"
2065 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2066
2067 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2068 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2069
2070 (define_insn "movdi_lo_sum_pic"
2071 [(set (match_operand:DI 0 "register_operand" "=r")
2072 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2073 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2074 "TARGET_ARCH64 && flag_pic"
2075 "or\t%1, %%lo(%a2), %0")
2076
2077 (define_insn "movdi_high_pic"
2078 [(set (match_operand:DI 0 "register_operand" "=r")
2079 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2080 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2081 "sethi\t%%hi(%a1), %0")
2082
2083 (define_insn "*sethi_di_medlow_embmedany_pic"
2084 [(set (match_operand:DI 0 "register_operand" "=r")
2085 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2086 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2087 "sethi\t%%hi(%a1), %0")
2088
2089 (define_insn "*sethi_di_medlow"
2090 [(set (match_operand:DI 0 "register_operand" "=r")
2091 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2092 "TARGET_CM_MEDLOW && check_pic (1)"
2093 "sethi\t%%hi(%a1), %0")
2094
2095 (define_insn "*losum_di_medlow"
2096 [(set (match_operand:DI 0 "register_operand" "=r")
2097 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2098 (match_operand:DI 2 "symbolic_operand" "")))]
2099 "TARGET_CM_MEDLOW"
2100 "or\t%1, %%lo(%a2), %0")
2101
2102 (define_insn "seth44"
2103 [(set (match_operand:DI 0 "register_operand" "=r")
2104 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2105 "TARGET_CM_MEDMID"
2106 "sethi\t%%h44(%a1), %0")
2107
2108 (define_insn "setm44"
2109 [(set (match_operand:DI 0 "register_operand" "=r")
2110 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2111 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2112 "TARGET_CM_MEDMID"
2113 "or\t%1, %%m44(%a2), %0")
2114
2115 (define_insn "setl44"
2116 [(set (match_operand:DI 0 "register_operand" "=r")
2117 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2118 (match_operand:DI 2 "symbolic_operand" "")))]
2119 "TARGET_CM_MEDMID"
2120 "or\t%1, %%l44(%a2), %0")
2121
2122 (define_insn "sethh"
2123 [(set (match_operand:DI 0 "register_operand" "=r")
2124 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2125 "TARGET_CM_MEDANY"
2126 "sethi\t%%hh(%a1), %0")
2127
2128 (define_insn "setlm"
2129 [(set (match_operand:DI 0 "register_operand" "=r")
2130 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2131 "TARGET_CM_MEDANY"
2132 "sethi\t%%lm(%a1), %0")
2133
2134 (define_insn "sethm"
2135 [(set (match_operand:DI 0 "register_operand" "=r")
2136 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2137 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2138 "TARGET_CM_MEDANY"
2139 "or\t%1, %%hm(%a2), %0")
2140
2141 (define_insn "setlo"
2142 [(set (match_operand:DI 0 "register_operand" "=r")
2143 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2144 (match_operand:DI 2 "symbolic_operand" "")))]
2145 "TARGET_CM_MEDANY"
2146 "or\t%1, %%lo(%a2), %0")
2147
2148 (define_insn "embmedany_sethi"
2149 [(set (match_operand:DI 0 "register_operand" "=r")
2150 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2151 "TARGET_CM_EMBMEDANY && check_pic (1)"
2152 "sethi\t%%hi(%a1), %0")
2153
2154 (define_insn "embmedany_losum"
2155 [(set (match_operand:DI 0 "register_operand" "=r")
2156 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2157 (match_operand:DI 2 "data_segment_operand" "")))]
2158 "TARGET_CM_EMBMEDANY"
2159 "add\t%1, %%lo(%a2), %0")
2160
2161 (define_insn "embmedany_brsum"
2162 [(set (match_operand:DI 0 "register_operand" "=r")
2163 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2164 "TARGET_CM_EMBMEDANY"
2165 "add\t%1, %_, %0")
2166
2167 (define_insn "embmedany_textuhi"
2168 [(set (match_operand:DI 0 "register_operand" "=r")
2169 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2170 "TARGET_CM_EMBMEDANY && check_pic (1)"
2171 "sethi\t%%uhi(%a1), %0")
2172
2173 (define_insn "embmedany_texthi"
2174 [(set (match_operand:DI 0 "register_operand" "=r")
2175 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2176 "TARGET_CM_EMBMEDANY && check_pic (1)"
2177 "sethi\t%%hi(%a1), %0")
2178
2179 (define_insn "embmedany_textulo"
2180 [(set (match_operand:DI 0 "register_operand" "=r")
2181 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2182 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2183 "TARGET_CM_EMBMEDANY"
2184 "or\t%1, %%ulo(%a2), %0")
2185
2186 (define_insn "embmedany_textlo"
2187 [(set (match_operand:DI 0 "register_operand" "=r")
2188 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2189 (match_operand:DI 2 "text_segment_operand" "")))]
2190 "TARGET_CM_EMBMEDANY"
2191 "or\t%1, %%lo(%a2), %0")
2192
2193 ;; Now some patterns to help reload out a bit.
2194 (define_expand "reload_indi"
2195 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2196 (match_operand:DI 1 "immediate_operand" "")
2197 (match_operand:TI 2 "register_operand" "=&r")])]
2198 "(TARGET_CM_MEDANY
2199 || TARGET_CM_EMBMEDANY)
2200 && ! flag_pic"
2201 {
2202 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2203 DONE;
2204 })
2205
2206 (define_expand "reload_outdi"
2207 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2208 (match_operand:DI 1 "immediate_operand" "")
2209 (match_operand:TI 2 "register_operand" "=&r")])]
2210 "(TARGET_CM_MEDANY
2211 || TARGET_CM_EMBMEDANY)
2212 && ! flag_pic"
2213 {
2214 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2215 DONE;
2216 })
2217
2218 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2219 (define_split
2220 [(set (match_operand:DI 0 "register_operand" "")
2221 (match_operand:DI 1 "const_int_operand" ""))]
2222 "! TARGET_ARCH64 && reload_completed"
2223 [(clobber (const_int 0))]
2224 {
2225 #if HOST_BITS_PER_WIDE_INT == 32
2226 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2227 (INTVAL (operands[1]) < 0) ?
2228 constm1_rtx :
2229 const0_rtx));
2230 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2231 operands[1]));
2232 #else
2233 unsigned int low, high;
2234
2235 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2236 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2237 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2238
2239 /* Slick... but this trick loses if this subreg constant part
2240 can be done in one insn. */
2241 if (low == high
2242 && ! SPARC_SETHI32_P (high)
2243 && ! SPARC_SIMM13_P (high))
2244 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2245 gen_highpart (SImode, operands[0])));
2246 else
2247 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2248 #endif
2249 DONE;
2250 })
2251
2252 (define_split
2253 [(set (match_operand:DI 0 "register_operand" "")
2254 (match_operand:DI 1 "const_double_operand" ""))]
2255 "reload_completed
2256 && (! TARGET_V9
2257 || (! TARGET_ARCH64
2258 && ((GET_CODE (operands[0]) == REG
2259 && REGNO (operands[0]) < 32)
2260 || (GET_CODE (operands[0]) == SUBREG
2261 && GET_CODE (SUBREG_REG (operands[0])) == REG
2262 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2263 [(clobber (const_int 0))]
2264 {
2265 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2266 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2267
2268 /* Slick... but this trick loses if this subreg constant part
2269 can be done in one insn. */
2270 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2271 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2272 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2273 {
2274 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2275 gen_highpart (SImode, operands[0])));
2276 }
2277 else
2278 {
2279 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2280 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2281 }
2282 DONE;
2283 })
2284
2285 (define_split
2286 [(set (match_operand:DI 0 "register_operand" "")
2287 (match_operand:DI 1 "register_operand" ""))]
2288 "reload_completed
2289 && (! TARGET_V9
2290 || (! TARGET_ARCH64
2291 && ((GET_CODE (operands[0]) == REG
2292 && REGNO (operands[0]) < 32)
2293 || (GET_CODE (operands[0]) == SUBREG
2294 && GET_CODE (SUBREG_REG (operands[0])) == REG
2295 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2296 [(clobber (const_int 0))]
2297 {
2298 rtx set_dest = operands[0];
2299 rtx set_src = operands[1];
2300 rtx dest1, dest2;
2301 rtx src1, src2;
2302
2303 dest1 = gen_highpart (SImode, set_dest);
2304 dest2 = gen_lowpart (SImode, set_dest);
2305 src1 = gen_highpart (SImode, set_src);
2306 src2 = gen_lowpart (SImode, set_src);
2307
2308 /* Now emit using the real source and destination we found, swapping
2309 the order if we detect overlap. */
2310 if (reg_overlap_mentioned_p (dest1, src2))
2311 {
2312 emit_insn (gen_movsi (dest2, src2));
2313 emit_insn (gen_movsi (dest1, src1));
2314 }
2315 else
2316 {
2317 emit_insn (gen_movsi (dest1, src1));
2318 emit_insn (gen_movsi (dest2, src2));
2319 }
2320 DONE;
2321 })
2322
2323 ;; Now handle the cases of memory moves from/to non-even
2324 ;; DI mode register pairs.
2325 (define_split
2326 [(set (match_operand:DI 0 "register_operand" "")
2327 (match_operand:DI 1 "memory_operand" ""))]
2328 "(! TARGET_ARCH64
2329 && reload_completed
2330 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2331 [(clobber (const_int 0))]
2332 {
2333 rtx word0 = adjust_address (operands[1], SImode, 0);
2334 rtx word1 = adjust_address (operands[1], SImode, 4);
2335 rtx high_part = gen_highpart (SImode, operands[0]);
2336 rtx low_part = gen_lowpart (SImode, operands[0]);
2337
2338 if (reg_overlap_mentioned_p (high_part, word1))
2339 {
2340 emit_insn (gen_movsi (low_part, word1));
2341 emit_insn (gen_movsi (high_part, word0));
2342 }
2343 else
2344 {
2345 emit_insn (gen_movsi (high_part, word0));
2346 emit_insn (gen_movsi (low_part, word1));
2347 }
2348 DONE;
2349 })
2350
2351 (define_split
2352 [(set (match_operand:DI 0 "memory_operand" "")
2353 (match_operand:DI 1 "register_operand" ""))]
2354 "(! TARGET_ARCH64
2355 && reload_completed
2356 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2357 [(clobber (const_int 0))]
2358 {
2359 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2360 gen_highpart (SImode, operands[1])));
2361 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2362 gen_lowpart (SImode, operands[1])));
2363 DONE;
2364 })
2365
2366 (define_split
2367 [(set (match_operand:DI 0 "memory_operand" "")
2368 (match_operand:DI 1 "const_zero_operand" ""))]
2369 "reload_completed
2370 && (! TARGET_V9
2371 || (! TARGET_ARCH64
2372 && ! mem_min_alignment (operands[0], 8)))
2373 && offsettable_memref_p (operands[0])"
2374 [(clobber (const_int 0))]
2375 {
2376 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2377 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2378 DONE;
2379 })
2380
2381
2382 ;; Floating point and vector move instructions
2383
2384 ;; We don't define V1SI because SI should work just fine.
2385 (define_mode_iterator V32 [SF V2HI V4QI])
2386
2387 ;; Yes, you guessed it right, the former movsf expander.
2388 (define_expand "mov<V32:mode>"
2389 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2390 (match_operand:V32 1 "general_operand" ""))]
2391 "<V32:MODE>mode == SFmode || TARGET_VIS"
2392 {
2393 if (sparc_expand_move (<V32:MODE>mode, operands))
2394 DONE;
2395 })
2396
2397 (define_insn "*movsf_insn"
2398 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2399 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2400 "TARGET_FPU
2401 && (register_operand (operands[0], <V32:MODE>mode)
2402 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2403 {
2404 if (GET_CODE (operands[1]) == CONST_DOUBLE
2405 && (which_alternative == 2
2406 || which_alternative == 3
2407 || which_alternative == 4))
2408 {
2409 REAL_VALUE_TYPE r;
2410 long i;
2411
2412 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2413 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2414 operands[1] = GEN_INT (i);
2415 }
2416
2417 switch (which_alternative)
2418 {
2419 case 0:
2420 return "fzeros\t%0";
2421 case 1:
2422 return "fmovs\t%1, %0";
2423 case 2:
2424 return "mov\t%1, %0";
2425 case 3:
2426 return "sethi\t%%hi(%a1), %0";
2427 case 4:
2428 return "#";
2429 case 5:
2430 case 6:
2431 return "ld\t%1, %0";
2432 case 7:
2433 case 8:
2434 return "st\t%r1, %0";
2435 default:
2436 gcc_unreachable ();
2437 }
2438 }
2439 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2440
2441 ;; Exactly the same as above, except that all `f' cases are deleted.
2442 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2443 ;; when -mno-fpu.
2444
2445 (define_insn "*movsf_insn_no_fpu"
2446 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2447 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2448 "! TARGET_FPU
2449 && (register_operand (operands[0], SFmode)
2450 || register_or_zero_operand (operands[1], SFmode))"
2451 {
2452 if (GET_CODE (operands[1]) == CONST_DOUBLE
2453 && (which_alternative == 0
2454 || which_alternative == 1
2455 || which_alternative == 2))
2456 {
2457 REAL_VALUE_TYPE r;
2458 long i;
2459
2460 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2461 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2462 operands[1] = GEN_INT (i);
2463 }
2464
2465 switch (which_alternative)
2466 {
2467 case 0:
2468 return "mov\t%1, %0";
2469 case 1:
2470 return "sethi\t%%hi(%a1), %0";
2471 case 2:
2472 return "#";
2473 case 3:
2474 return "ld\t%1, %0";
2475 case 4:
2476 return "st\t%r1, %0";
2477 default:
2478 gcc_unreachable ();
2479 }
2480 }
2481 [(set_attr "type" "*,*,*,load,store")])
2482
2483 ;; The following 3 patterns build SFmode constants in integer registers.
2484
2485 (define_insn "*movsf_lo_sum"
2486 [(set (match_operand:SF 0 "register_operand" "=r")
2487 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2488 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2489 ""
2490 {
2491 REAL_VALUE_TYPE r;
2492 long i;
2493
2494 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2495 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2496 operands[2] = GEN_INT (i);
2497 return "or\t%1, %%lo(%a2), %0";
2498 })
2499
2500 (define_insn "*movsf_high"
2501 [(set (match_operand:SF 0 "register_operand" "=r")
2502 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2503 ""
2504 {
2505 REAL_VALUE_TYPE r;
2506 long i;
2507
2508 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2509 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2510 operands[1] = GEN_INT (i);
2511 return "sethi\t%%hi(%1), %0";
2512 })
2513
2514 (define_split
2515 [(set (match_operand:SF 0 "register_operand" "")
2516 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2517 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2518 [(set (match_dup 0) (high:SF (match_dup 1)))
2519 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2520
2521 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
2522
2523 ;; Yes, you again guessed it right, the former movdf expander.
2524 (define_expand "mov<V64:mode>"
2525 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2526 (match_operand:V64 1 "general_operand" ""))]
2527 "<V64:MODE>mode == DFmode || TARGET_VIS"
2528 {
2529 if (sparc_expand_move (<V64:MODE>mode, operands))
2530 DONE;
2531 })
2532
2533 ;; Be careful, fmovd does not exist when !v9.
2534 (define_insn "*movdf_insn_sp32"
2535 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2536 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2537 "TARGET_FPU
2538 && ! TARGET_V9
2539 && (register_operand (operands[0], DFmode)
2540 || register_or_zero_operand (operands[1], DFmode))"
2541 "@
2542 ldd\t%1, %0
2543 std\t%1, %0
2544 ldd\t%1, %0
2545 std\t%1, %0
2546 #
2547 #
2548 #
2549 #
2550 #
2551 #"
2552 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2553 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2554
2555 (define_insn "*movdf_insn_sp32_no_fpu"
2556 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2557 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2558 "! TARGET_FPU
2559 && ! TARGET_V9
2560 && (register_operand (operands[0], DFmode)
2561 || register_or_zero_operand (operands[1], DFmode))"
2562 "@
2563 ldd\t%1, %0
2564 std\t%1, %0
2565 #
2566 #
2567 #"
2568 [(set_attr "type" "load,store,*,*,*")
2569 (set_attr "length" "*,*,2,2,2")])
2570
2571 ;; We have available v9 double floats but not 64-bit integer registers.
2572 (define_insn "*movdf_insn_sp32_v9"
2573 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2574 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2575 "TARGET_FPU
2576 && TARGET_V9
2577 && ! TARGET_ARCH64
2578 && (register_operand (operands[0], <V64:MODE>mode)
2579 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2580 "@
2581 fzero\t%0
2582 fmovd\t%1, %0
2583 ldd\t%1, %0
2584 stx\t%r1, %0
2585 std\t%1, %0
2586 ldd\t%1, %0
2587 std\t%1, %0
2588 #
2589 #
2590 #"
2591 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2592 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2593 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2594
2595 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2596 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2597 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2598 "! TARGET_FPU
2599 && TARGET_V9
2600 && ! TARGET_ARCH64
2601 && (register_operand (operands[0], DFmode)
2602 || register_or_zero_operand (operands[1], DFmode))"
2603 "@
2604 ldd\t%1, %0
2605 std\t%1, %0
2606 stx\t%r1, %0
2607 #
2608 #"
2609 [(set_attr "type" "load,store,store,*,*")
2610 (set_attr "length" "*,*,*,2,2")])
2611
2612 ;; We have available both v9 double floats and 64-bit integer registers.
2613 (define_insn "*movdf_insn_sp64"
2614 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2615 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2616 "TARGET_FPU
2617 && TARGET_ARCH64
2618 && (register_operand (operands[0], <V64:MODE>mode)
2619 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2620 "@
2621 fzero\t%0
2622 fmovd\t%1, %0
2623 ldd\t%1, %0
2624 std\t%1, %0
2625 mov\t%r1, %0
2626 ldx\t%1, %0
2627 stx\t%r1, %0
2628 #"
2629 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2630 (set_attr "length" "*,*,*,*,*,*,*,2")
2631 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2632
2633 (define_insn "*movdf_insn_sp64_no_fpu"
2634 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2635 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2636 "! TARGET_FPU
2637 && TARGET_ARCH64
2638 && (register_operand (operands[0], DFmode)
2639 || register_or_zero_operand (operands[1], DFmode))"
2640 "@
2641 mov\t%1, %0
2642 ldx\t%1, %0
2643 stx\t%r1, %0"
2644 [(set_attr "type" "*,load,store")])
2645
2646 ;; This pattern build DFmode constants in integer registers.
2647 (define_split
2648 [(set (match_operand:DF 0 "register_operand" "")
2649 (match_operand:DF 1 "const_double_operand" ""))]
2650 "TARGET_FPU
2651 && (GET_CODE (operands[0]) == REG
2652 && REGNO (operands[0]) < 32)
2653 && ! const_zero_operand(operands[1], DFmode)
2654 && reload_completed"
2655 [(clobber (const_int 0))]
2656 {
2657 REAL_VALUE_TYPE r;
2658 long l[2];
2659
2660 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2661 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2662 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2663
2664 if (TARGET_ARCH64)
2665 {
2666 #if HOST_BITS_PER_WIDE_INT == 32
2667 gcc_unreachable ();
2668 #else
2669 HOST_WIDE_INT val;
2670
2671 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2672 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2673 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2674 #endif
2675 }
2676 else
2677 {
2678 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2679 gen_int_mode (l[0], SImode)));
2680
2681 /* Slick... but this trick loses if this subreg constant part
2682 can be done in one insn. */
2683 if (l[1] == l[0]
2684 && ! SPARC_SETHI32_P (l[0])
2685 && ! SPARC_SIMM13_P (l[0]))
2686 {
2687 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2688 gen_highpart (SImode, operands[0])));
2689 }
2690 else
2691 {
2692 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2693 gen_int_mode (l[1], SImode)));
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 ;; The V8 architecture specifies that there must be 3 instructions between
4901 ;; a Y register write and a use of it for correct results.
4902
4903 (define_expand "divsi3"
4904 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
4905 (div:SI (match_operand:SI 1 "register_operand" "r,r")
4906 (match_operand:SI 2 "input_operand" "rI,m")))
4907 (clobber (match_scratch:SI 3 "=&r,&r"))])]
4908 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4909 {
4910 if (TARGET_ARCH64)
4911 {
4912 operands[3] = gen_reg_rtx(SImode);
4913 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4914 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4915 operands[3]));
4916 DONE;
4917 }
4918 })
4919
4920 (define_insn "divsi3_sp32"
4921 [(set (match_operand:SI 0 "register_operand" "=r,r")
4922 (div:SI (match_operand:SI 1 "register_operand" "r,r")
4923 (match_operand:SI 2 "input_operand" "rI,m")))
4924 (clobber (match_scratch:SI 3 "=&r,&r"))]
4925 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
4926 && TARGET_ARCH32"
4927 {
4928 if (which_alternative == 0)
4929 if (TARGET_V9)
4930 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
4931 else
4932 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4933 else
4934 if (TARGET_V9)
4935 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
4936 else
4937 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4938 }
4939 [(set_attr "type" "multi")
4940 (set (attr "length")
4941 (if_then_else (eq_attr "isa" "v9")
4942 (const_int 4) (const_int 6)))])
4943
4944 (define_insn "divsi3_sp64"
4945 [(set (match_operand:SI 0 "register_operand" "=r")
4946 (div:SI (match_operand:SI 1 "register_operand" "r")
4947 (match_operand:SI 2 "input_operand" "rI")))
4948 (use (match_operand:SI 3 "register_operand" "r"))]
4949 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4950 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4951 [(set_attr "type" "multi")
4952 (set_attr "length" "2")])
4953
4954 (define_insn "divdi3"
4955 [(set (match_operand:DI 0 "register_operand" "=r")
4956 (div:DI (match_operand:DI 1 "register_operand" "r")
4957 (match_operand:DI 2 "arith_operand" "rI")))]
4958 "TARGET_ARCH64"
4959 "sdivx\t%1, %2, %0"
4960 [(set_attr "type" "idiv")])
4961
4962 (define_insn "*cmp_sdiv_cc_set"
4963 [(set (reg:CC 100)
4964 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4965 (match_operand:SI 2 "arith_operand" "rI"))
4966 (const_int 0)))
4967 (set (match_operand:SI 0 "register_operand" "=r")
4968 (div:SI (match_dup 1) (match_dup 2)))
4969 (clobber (match_scratch:SI 3 "=&r"))]
4970 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4971 {
4972 if (TARGET_V9)
4973 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
4974 else
4975 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4976 }
4977 [(set_attr "type" "multi")
4978 (set (attr "length")
4979 (if_then_else (eq_attr "isa" "v9")
4980 (const_int 3) (const_int 6)))])
4981
4982 ;; XXX
4983 (define_expand "udivsi3"
4984 [(set (match_operand:SI 0 "register_operand" "")
4985 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4986 (match_operand:SI 2 "input_operand" "")))]
4987 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4988 "")
4989
4990 ;; The V8 architecture specifies that there must be 3 instructions between
4991 ;; a Y register write and a use of it for correct results.
4992
4993 (define_insn "udivsi3_sp32"
4994 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
4995 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
4996 (match_operand:SI 2 "input_operand" "rI,m,r")))]
4997 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
4998 && TARGET_ARCH32"
4999 {
5000 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5001 switch (which_alternative)
5002 {
5003 default:
5004 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5005 case 1:
5006 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5007 case 2:
5008 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5009 }
5010 }
5011 [(set_attr "type" "multi")
5012 (set_attr "length" "5")])
5013
5014 (define_insn "udivsi3_sp64"
5015 [(set (match_operand:SI 0 "register_operand" "=r")
5016 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5017 (match_operand:SI 2 "input_operand" "rI")))]
5018 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5019 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5020 [(set_attr "type" "multi")
5021 (set_attr "length" "2")])
5022
5023 (define_insn "udivdi3"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5026 (match_operand:DI 2 "arith_operand" "rI")))]
5027 "TARGET_ARCH64"
5028 "udivx\t%1, %2, %0"
5029 [(set_attr "type" "idiv")])
5030
5031 (define_insn "*cmp_udiv_cc_set"
5032 [(set (reg:CC 100)
5033 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5034 (match_operand:SI 2 "arith_operand" "rI"))
5035 (const_int 0)))
5036 (set (match_operand:SI 0 "register_operand" "=r")
5037 (udiv:SI (match_dup 1) (match_dup 2)))]
5038 "TARGET_V8
5039 || TARGET_DEPRECATED_V8_INSNS"
5040 {
5041 if (TARGET_V9)
5042 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5043 else
5044 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5045 }
5046 [(set_attr "type" "multi")
5047 (set (attr "length")
5048 (if_then_else (eq_attr "isa" "v9")
5049 (const_int 2) (const_int 5)))])
5050
5051 ; sparclet multiply/accumulate insns
5052
5053 (define_insn "*smacsi"
5054 [(set (match_operand:SI 0 "register_operand" "=r")
5055 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5056 (match_operand:SI 2 "arith_operand" "rI"))
5057 (match_operand:SI 3 "register_operand" "0")))]
5058 "TARGET_SPARCLET"
5059 "smac\t%1, %2, %0"
5060 [(set_attr "type" "imul")])
5061
5062 (define_insn "*smacdi"
5063 [(set (match_operand:DI 0 "register_operand" "=r")
5064 (plus:DI (mult:DI (sign_extend:DI
5065 (match_operand:SI 1 "register_operand" "%r"))
5066 (sign_extend:DI
5067 (match_operand:SI 2 "register_operand" "r")))
5068 (match_operand:DI 3 "register_operand" "0")))]
5069 "TARGET_SPARCLET"
5070 "smacd\t%1, %2, %L0"
5071 [(set_attr "type" "imul")])
5072
5073 (define_insn "*umacdi"
5074 [(set (match_operand:DI 0 "register_operand" "=r")
5075 (plus:DI (mult:DI (zero_extend:DI
5076 (match_operand:SI 1 "register_operand" "%r"))
5077 (zero_extend:DI
5078 (match_operand:SI 2 "register_operand" "r")))
5079 (match_operand:DI 3 "register_operand" "0")))]
5080 "TARGET_SPARCLET"
5081 "umacd\t%1, %2, %L0"
5082 [(set_attr "type" "imul")])
5083
5084
5085 ;; Boolean instructions.
5086
5087 ;; We define DImode `and' so with DImode `not' we can get
5088 ;; DImode `andn'. Other combinations are possible.
5089
5090 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
5091 (define_mode_iterator V32I [SI V2HI V4QI])
5092
5093 (define_expand "and<V64I:mode>3"
5094 [(set (match_operand:V64I 0 "register_operand" "")
5095 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5096 (match_operand:V64I 2 "arith_double_operand" "")))]
5097 ""
5098 "")
5099
5100 (define_insn "*and<V64I:mode>3_sp32"
5101 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5102 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5103 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5104 "! TARGET_ARCH64"
5105 "@
5106 #
5107 fand\t%1, %2, %0"
5108 [(set_attr "type" "*,fga")
5109 (set_attr "length" "2,*")
5110 (set_attr "fptype" "*,double")])
5111
5112 (define_insn "*and<V64I:mode>3_sp64"
5113 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5114 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5115 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5116 "TARGET_ARCH64"
5117 "@
5118 and\t%1, %2, %0
5119 fand\t%1, %2, %0"
5120 [(set_attr "type" "*,fga")
5121 (set_attr "fptype" "*,double")])
5122
5123 (define_insn "and<V32I:mode>3"
5124 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5125 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5126 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5127 ""
5128 "@
5129 and\t%1, %2, %0
5130 fands\t%1, %2, %0"
5131 [(set_attr "type" "*,fga")
5132 (set_attr "fptype" "*,single")])
5133
5134 (define_split
5135 [(set (match_operand:SI 0 "register_operand" "")
5136 (and:SI (match_operand:SI 1 "register_operand" "")
5137 (match_operand:SI 2 "const_compl_high_operand" "")))
5138 (clobber (match_operand:SI 3 "register_operand" ""))]
5139 ""
5140 [(set (match_dup 3) (match_dup 4))
5141 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5142 {
5143 operands[4] = GEN_INT (~INTVAL (operands[2]));
5144 })
5145
5146 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5147 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5148 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5149 (match_operand:V64I 2 "register_operand" "r,b")))]
5150 "! TARGET_ARCH64"
5151 "@
5152 #
5153 fandnot1\t%1, %2, %0"
5154 "&& reload_completed
5155 && ((GET_CODE (operands[0]) == REG
5156 && REGNO (operands[0]) < 32)
5157 || (GET_CODE (operands[0]) == SUBREG
5158 && GET_CODE (SUBREG_REG (operands[0])) == REG
5159 && REGNO (SUBREG_REG (operands[0])) < 32))"
5160 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5161 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5162 "operands[3] = gen_highpart (SImode, operands[0]);
5163 operands[4] = gen_highpart (SImode, operands[1]);
5164 operands[5] = gen_highpart (SImode, operands[2]);
5165 operands[6] = gen_lowpart (SImode, operands[0]);
5166 operands[7] = gen_lowpart (SImode, operands[1]);
5167 operands[8] = gen_lowpart (SImode, operands[2]);"
5168 [(set_attr "type" "*,fga")
5169 (set_attr "length" "2,*")
5170 (set_attr "fptype" "*,double")])
5171
5172 (define_insn "*and_not_<V64I:mode>_sp64"
5173 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5174 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5175 (match_operand:V64I 2 "register_operand" "r,b")))]
5176 "TARGET_ARCH64"
5177 "@
5178 andn\t%2, %1, %0
5179 fandnot1\t%1, %2, %0"
5180 [(set_attr "type" "*,fga")
5181 (set_attr "fptype" "*,double")])
5182
5183 (define_insn "*and_not_<V32I:mode>"
5184 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5185 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5186 (match_operand:V32I 2 "register_operand" "r,d")))]
5187 ""
5188 "@
5189 andn\t%2, %1, %0
5190 fandnot1s\t%1, %2, %0"
5191 [(set_attr "type" "*,fga")
5192 (set_attr "fptype" "*,single")])
5193
5194 (define_expand "ior<V64I:mode>3"
5195 [(set (match_operand:V64I 0 "register_operand" "")
5196 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5197 (match_operand:V64I 2 "arith_double_operand" "")))]
5198 ""
5199 "")
5200
5201 (define_insn "*ior<V64I:mode>3_sp32"
5202 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5203 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5204 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5205 "! TARGET_ARCH64"
5206 "@
5207 #
5208 for\t%1, %2, %0"
5209 [(set_attr "type" "*,fga")
5210 (set_attr "length" "2,*")
5211 (set_attr "fptype" "*,double")])
5212
5213 (define_insn "*ior<V64I:mode>3_sp64"
5214 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5215 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5216 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5217 "TARGET_ARCH64"
5218 "@
5219 or\t%1, %2, %0
5220 for\t%1, %2, %0"
5221 [(set_attr "type" "*,fga")
5222 (set_attr "fptype" "*,double")])
5223
5224 (define_insn "ior<V32I:mode>3"
5225 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5226 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5227 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5228 ""
5229 "@
5230 or\t%1, %2, %0
5231 fors\t%1, %2, %0"
5232 [(set_attr "type" "*,fga")
5233 (set_attr "fptype" "*,single")])
5234
5235 (define_split
5236 [(set (match_operand:SI 0 "register_operand" "")
5237 (ior:SI (match_operand:SI 1 "register_operand" "")
5238 (match_operand:SI 2 "const_compl_high_operand" "")))
5239 (clobber (match_operand:SI 3 "register_operand" ""))]
5240 ""
5241 [(set (match_dup 3) (match_dup 4))
5242 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5243 {
5244 operands[4] = GEN_INT (~INTVAL (operands[2]));
5245 })
5246
5247 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5248 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5249 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5250 (match_operand:V64I 2 "register_operand" "r,b")))]
5251 "! TARGET_ARCH64"
5252 "@
5253 #
5254 fornot1\t%1, %2, %0"
5255 "&& reload_completed
5256 && ((GET_CODE (operands[0]) == REG
5257 && REGNO (operands[0]) < 32)
5258 || (GET_CODE (operands[0]) == SUBREG
5259 && GET_CODE (SUBREG_REG (operands[0])) == REG
5260 && REGNO (SUBREG_REG (operands[0])) < 32))"
5261 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5262 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5263 "operands[3] = gen_highpart (SImode, operands[0]);
5264 operands[4] = gen_highpart (SImode, operands[1]);
5265 operands[5] = gen_highpart (SImode, operands[2]);
5266 operands[6] = gen_lowpart (SImode, operands[0]);
5267 operands[7] = gen_lowpart (SImode, operands[1]);
5268 operands[8] = gen_lowpart (SImode, operands[2]);"
5269 [(set_attr "type" "*,fga")
5270 (set_attr "length" "2,*")
5271 (set_attr "fptype" "*,double")])
5272
5273 (define_insn "*or_not_<V64I:mode>_sp64"
5274 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5275 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5276 (match_operand:V64I 2 "register_operand" "r,b")))]
5277 "TARGET_ARCH64"
5278 "@
5279 orn\t%2, %1, %0
5280 fornot1\t%1, %2, %0"
5281 [(set_attr "type" "*,fga")
5282 (set_attr "fptype" "*,double")])
5283
5284 (define_insn "*or_not_<V32I:mode>"
5285 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5286 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5287 (match_operand:V32I 2 "register_operand" "r,d")))]
5288 ""
5289 "@
5290 orn\t%2, %1, %0
5291 fornot1s\t%1, %2, %0"
5292 [(set_attr "type" "*,fga")
5293 (set_attr "fptype" "*,single")])
5294
5295 (define_expand "xor<V64I:mode>3"
5296 [(set (match_operand:V64I 0 "register_operand" "")
5297 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5298 (match_operand:V64I 2 "arith_double_operand" "")))]
5299 ""
5300 "")
5301
5302 (define_insn "*xor<V64I:mode>3_sp32"
5303 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5304 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5305 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5306 "! TARGET_ARCH64"
5307 "@
5308 #
5309 fxor\t%1, %2, %0"
5310 [(set_attr "type" "*,fga")
5311 (set_attr "length" "2,*")
5312 (set_attr "fptype" "*,double")])
5313
5314 (define_insn "*xor<V64I:mode>3_sp64"
5315 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5316 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5317 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5318 "TARGET_ARCH64"
5319 "@
5320 xor\t%r1, %2, %0
5321 fxor\t%1, %2, %0"
5322 [(set_attr "type" "*,fga")
5323 (set_attr "fptype" "*,double")])
5324
5325 (define_insn "xor<V32I:mode>3"
5326 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5327 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5328 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5329 ""
5330 "@
5331 xor\t%r1, %2, %0
5332 fxors\t%1, %2, %0"
5333 [(set_attr "type" "*,fga")
5334 (set_attr "fptype" "*,single")])
5335
5336 (define_split
5337 [(set (match_operand:SI 0 "register_operand" "")
5338 (xor:SI (match_operand:SI 1 "register_operand" "")
5339 (match_operand:SI 2 "const_compl_high_operand" "")))
5340 (clobber (match_operand:SI 3 "register_operand" ""))]
5341 ""
5342 [(set (match_dup 3) (match_dup 4))
5343 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5344 {
5345 operands[4] = GEN_INT (~INTVAL (operands[2]));
5346 })
5347
5348 (define_split
5349 [(set (match_operand:SI 0 "register_operand" "")
5350 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5351 (match_operand:SI 2 "const_compl_high_operand" ""))))
5352 (clobber (match_operand:SI 3 "register_operand" ""))]
5353 ""
5354 [(set (match_dup 3) (match_dup 4))
5355 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5356 {
5357 operands[4] = GEN_INT (~INTVAL (operands[2]));
5358 })
5359
5360 ;; Split DImode logical operations requiring two instructions.
5361 (define_split
5362 [(set (match_operand:V64I 0 "register_operand" "")
5363 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5364 [(match_operand:V64I 2 "register_operand" "")
5365 (match_operand:V64I 3 "arith_double_operand" "")]))]
5366 "! TARGET_ARCH64
5367 && reload_completed
5368 && ((GET_CODE (operands[0]) == REG
5369 && REGNO (operands[0]) < 32)
5370 || (GET_CODE (operands[0]) == SUBREG
5371 && GET_CODE (SUBREG_REG (operands[0])) == REG
5372 && REGNO (SUBREG_REG (operands[0])) < 32))"
5373 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5374 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5375 {
5376 operands[4] = gen_highpart (SImode, operands[0]);
5377 operands[5] = gen_lowpart (SImode, operands[0]);
5378 operands[6] = gen_highpart (SImode, operands[2]);
5379 operands[7] = gen_lowpart (SImode, operands[2]);
5380 #if HOST_BITS_PER_WIDE_INT == 32
5381 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5382 {
5383 if (INTVAL (operands[3]) < 0)
5384 operands[8] = constm1_rtx;
5385 else
5386 operands[8] = const0_rtx;
5387 }
5388 else
5389 #endif
5390 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5391 operands[9] = gen_lowpart (SImode, operands[3]);
5392 })
5393
5394 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5395 ;; Combine now canonicalizes to the rightmost expression.
5396 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5397 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5398 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5399 (match_operand:V64I 2 "register_operand" "r,b"))))]
5400 "! TARGET_ARCH64"
5401 "@
5402 #
5403 fxnor\t%1, %2, %0"
5404 "&& reload_completed
5405 && ((GET_CODE (operands[0]) == REG
5406 && REGNO (operands[0]) < 32)
5407 || (GET_CODE (operands[0]) == SUBREG
5408 && GET_CODE (SUBREG_REG (operands[0])) == REG
5409 && REGNO (SUBREG_REG (operands[0])) < 32))"
5410 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5411 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5412 "operands[3] = gen_highpart (SImode, operands[0]);
5413 operands[4] = gen_highpart (SImode, operands[1]);
5414 operands[5] = gen_highpart (SImode, operands[2]);
5415 operands[6] = gen_lowpart (SImode, operands[0]);
5416 operands[7] = gen_lowpart (SImode, operands[1]);
5417 operands[8] = gen_lowpart (SImode, operands[2]);"
5418 [(set_attr "type" "*,fga")
5419 (set_attr "length" "2,*")
5420 (set_attr "fptype" "*,double")])
5421
5422 (define_insn "*xor_not_<V64I:mode>_sp64"
5423 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5424 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5425 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5426 "TARGET_ARCH64"
5427 "@
5428 xnor\t%r1, %2, %0
5429 fxnor\t%1, %2, %0"
5430 [(set_attr "type" "*,fga")
5431 (set_attr "fptype" "*,double")])
5432
5433 (define_insn "*xor_not_<V32I:mode>"
5434 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5435 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5436 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5437 ""
5438 "@
5439 xnor\t%r1, %2, %0
5440 fxnors\t%1, %2, %0"
5441 [(set_attr "type" "*,fga")
5442 (set_attr "fptype" "*,single")])
5443
5444 ;; These correspond to the above in the case where we also (or only)
5445 ;; want to set the condition code.
5446
5447 (define_insn "*cmp_cc_arith_op"
5448 [(set (reg:CC 100)
5449 (compare:CC
5450 (match_operator:SI 2 "cc_arith_operator"
5451 [(match_operand:SI 0 "arith_operand" "%r")
5452 (match_operand:SI 1 "arith_operand" "rI")])
5453 (const_int 0)))]
5454 ""
5455 "%A2cc\t%0, %1, %%g0"
5456 [(set_attr "type" "compare")])
5457
5458 (define_insn "*cmp_ccx_arith_op"
5459 [(set (reg:CCX 100)
5460 (compare:CCX
5461 (match_operator:DI 2 "cc_arith_operator"
5462 [(match_operand:DI 0 "arith_operand" "%r")
5463 (match_operand:DI 1 "arith_operand" "rI")])
5464 (const_int 0)))]
5465 "TARGET_ARCH64"
5466 "%A2cc\t%0, %1, %%g0"
5467 [(set_attr "type" "compare")])
5468
5469 (define_insn "*cmp_cc_arith_op_set"
5470 [(set (reg:CC 100)
5471 (compare:CC
5472 (match_operator:SI 3 "cc_arith_operator"
5473 [(match_operand:SI 1 "arith_operand" "%r")
5474 (match_operand:SI 2 "arith_operand" "rI")])
5475 (const_int 0)))
5476 (set (match_operand:SI 0 "register_operand" "=r")
5477 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5478 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5479 "%A3cc\t%1, %2, %0"
5480 [(set_attr "type" "compare")])
5481
5482 (define_insn "*cmp_ccx_arith_op_set"
5483 [(set (reg:CCX 100)
5484 (compare:CCX
5485 (match_operator:DI 3 "cc_arith_operator"
5486 [(match_operand:DI 1 "arith_operand" "%r")
5487 (match_operand:DI 2 "arith_operand" "rI")])
5488 (const_int 0)))
5489 (set (match_operand:DI 0 "register_operand" "=r")
5490 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5491 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5492 "%A3cc\t%1, %2, %0"
5493 [(set_attr "type" "compare")])
5494
5495 (define_insn "*cmp_cc_xor_not"
5496 [(set (reg:CC 100)
5497 (compare:CC
5498 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5499 (match_operand:SI 1 "arith_operand" "rI")))
5500 (const_int 0)))]
5501 ""
5502 "xnorcc\t%r0, %1, %%g0"
5503 [(set_attr "type" "compare")])
5504
5505 (define_insn "*cmp_ccx_xor_not"
5506 [(set (reg:CCX 100)
5507 (compare:CCX
5508 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5509 (match_operand:DI 1 "arith_operand" "rI")))
5510 (const_int 0)))]
5511 "TARGET_ARCH64"
5512 "xnorcc\t%r0, %1, %%g0"
5513 [(set_attr "type" "compare")])
5514
5515 (define_insn "*cmp_cc_xor_not_set"
5516 [(set (reg:CC 100)
5517 (compare:CC
5518 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5519 (match_operand:SI 2 "arith_operand" "rI")))
5520 (const_int 0)))
5521 (set (match_operand:SI 0 "register_operand" "=r")
5522 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5523 ""
5524 "xnorcc\t%r1, %2, %0"
5525 [(set_attr "type" "compare")])
5526
5527 (define_insn "*cmp_ccx_xor_not_set"
5528 [(set (reg:CCX 100)
5529 (compare:CCX
5530 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5531 (match_operand:DI 2 "arith_operand" "rI")))
5532 (const_int 0)))
5533 (set (match_operand:DI 0 "register_operand" "=r")
5534 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5535 "TARGET_ARCH64"
5536 "xnorcc\t%r1, %2, %0"
5537 [(set_attr "type" "compare")])
5538
5539 (define_insn "*cmp_cc_arith_op_not"
5540 [(set (reg:CC 100)
5541 (compare:CC
5542 (match_operator:SI 2 "cc_arith_not_operator"
5543 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5544 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5545 (const_int 0)))]
5546 ""
5547 "%B2cc\t%r1, %0, %%g0"
5548 [(set_attr "type" "compare")])
5549
5550 (define_insn "*cmp_ccx_arith_op_not"
5551 [(set (reg:CCX 100)
5552 (compare:CCX
5553 (match_operator:DI 2 "cc_arith_not_operator"
5554 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5555 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5556 (const_int 0)))]
5557 "TARGET_ARCH64"
5558 "%B2cc\t%r1, %0, %%g0"
5559 [(set_attr "type" "compare")])
5560
5561 (define_insn "*cmp_cc_arith_op_not_set"
5562 [(set (reg:CC 100)
5563 (compare:CC
5564 (match_operator:SI 3 "cc_arith_not_operator"
5565 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5566 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5567 (const_int 0)))
5568 (set (match_operand:SI 0 "register_operand" "=r")
5569 (match_operator:SI 4 "cc_arith_not_operator"
5570 [(not:SI (match_dup 1)) (match_dup 2)]))]
5571 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5572 "%B3cc\t%r2, %1, %0"
5573 [(set_attr "type" "compare")])
5574
5575 (define_insn "*cmp_ccx_arith_op_not_set"
5576 [(set (reg:CCX 100)
5577 (compare:CCX
5578 (match_operator:DI 3 "cc_arith_not_operator"
5579 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5580 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5581 (const_int 0)))
5582 (set (match_operand:DI 0 "register_operand" "=r")
5583 (match_operator:DI 4 "cc_arith_not_operator"
5584 [(not:DI (match_dup 1)) (match_dup 2)]))]
5585 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5586 "%B3cc\t%r2, %1, %0"
5587 [(set_attr "type" "compare")])
5588
5589 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5590 ;; does not know how to make it work for constants.
5591
5592 (define_expand "negdi2"
5593 [(set (match_operand:DI 0 "register_operand" "=r")
5594 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5595 ""
5596 {
5597 if (! TARGET_ARCH64)
5598 {
5599 emit_insn (gen_rtx_PARALLEL
5600 (VOIDmode,
5601 gen_rtvec (2,
5602 gen_rtx_SET (VOIDmode, operand0,
5603 gen_rtx_NEG (DImode, operand1)),
5604 gen_rtx_CLOBBER (VOIDmode,
5605 gen_rtx_REG (CCmode,
5606 SPARC_ICC_REG)))));
5607 DONE;
5608 }
5609 })
5610
5611 (define_insn_and_split "*negdi2_sp32"
5612 [(set (match_operand:DI 0 "register_operand" "=r")
5613 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5614 (clobber (reg:CC 100))]
5615 "TARGET_ARCH32"
5616 "#"
5617 "&& reload_completed"
5618 [(parallel [(set (reg:CC_NOOV 100)
5619 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5620 (const_int 0)))
5621 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5622 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5623 (ltu:SI (reg:CC 100) (const_int 0))))]
5624 "operands[2] = gen_highpart (SImode, operands[0]);
5625 operands[3] = gen_highpart (SImode, operands[1]);
5626 operands[4] = gen_lowpart (SImode, operands[0]);
5627 operands[5] = gen_lowpart (SImode, operands[1]);"
5628 [(set_attr "length" "2")])
5629
5630 (define_insn "*negdi2_sp64"
5631 [(set (match_operand:DI 0 "register_operand" "=r")
5632 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5633 "TARGET_ARCH64"
5634 "sub\t%%g0, %1, %0")
5635
5636 (define_insn "negsi2"
5637 [(set (match_operand:SI 0 "register_operand" "=r")
5638 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5639 ""
5640 "sub\t%%g0, %1, %0")
5641
5642 (define_insn "*cmp_cc_neg"
5643 [(set (reg:CC_NOOV 100)
5644 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5645 (const_int 0)))]
5646 ""
5647 "subcc\t%%g0, %0, %%g0"
5648 [(set_attr "type" "compare")])
5649
5650 (define_insn "*cmp_ccx_neg"
5651 [(set (reg:CCX_NOOV 100)
5652 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5653 (const_int 0)))]
5654 "TARGET_ARCH64"
5655 "subcc\t%%g0, %0, %%g0"
5656 [(set_attr "type" "compare")])
5657
5658 (define_insn "*cmp_cc_set_neg"
5659 [(set (reg:CC_NOOV 100)
5660 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5661 (const_int 0)))
5662 (set (match_operand:SI 0 "register_operand" "=r")
5663 (neg:SI (match_dup 1)))]
5664 ""
5665 "subcc\t%%g0, %1, %0"
5666 [(set_attr "type" "compare")])
5667
5668 (define_insn "*cmp_ccx_set_neg"
5669 [(set (reg:CCX_NOOV 100)
5670 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5671 (const_int 0)))
5672 (set (match_operand:DI 0 "register_operand" "=r")
5673 (neg:DI (match_dup 1)))]
5674 "TARGET_ARCH64"
5675 "subcc\t%%g0, %1, %0"
5676 [(set_attr "type" "compare")])
5677
5678 ;; We cannot use the "not" pseudo insn because the Sun assembler
5679 ;; does not know how to make it work for constants.
5680 (define_expand "one_cmpl<V64I:mode>2"
5681 [(set (match_operand:V64I 0 "register_operand" "")
5682 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5683 ""
5684 "")
5685
5686 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5687 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5688 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5689 "! TARGET_ARCH64"
5690 "@
5691 #
5692 fnot1\t%1, %0"
5693 "&& reload_completed
5694 && ((GET_CODE (operands[0]) == REG
5695 && REGNO (operands[0]) < 32)
5696 || (GET_CODE (operands[0]) == SUBREG
5697 && GET_CODE (SUBREG_REG (operands[0])) == REG
5698 && REGNO (SUBREG_REG (operands[0])) < 32))"
5699 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5700 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5701 "operands[2] = gen_highpart (SImode, operands[0]);
5702 operands[3] = gen_highpart (SImode, operands[1]);
5703 operands[4] = gen_lowpart (SImode, operands[0]);
5704 operands[5] = gen_lowpart (SImode, operands[1]);"
5705 [(set_attr "type" "*,fga")
5706 (set_attr "length" "2,*")
5707 (set_attr "fptype" "*,double")])
5708
5709 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5710 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5711 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5712 "TARGET_ARCH64"
5713 "@
5714 xnor\t%%g0, %1, %0
5715 fnot1\t%1, %0"
5716 [(set_attr "type" "*,fga")
5717 (set_attr "fptype" "*,double")])
5718
5719 (define_insn "one_cmpl<V32I:mode>2"
5720 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5721 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5722 ""
5723 "@
5724 xnor\t%%g0, %1, %0
5725 fnot1s\t%1, %0"
5726 [(set_attr "type" "*,fga")
5727 (set_attr "fptype" "*,single")])
5728
5729 (define_insn "*cmp_cc_not"
5730 [(set (reg:CC 100)
5731 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5732 (const_int 0)))]
5733 ""
5734 "xnorcc\t%%g0, %0, %%g0"
5735 [(set_attr "type" "compare")])
5736
5737 (define_insn "*cmp_ccx_not"
5738 [(set (reg:CCX 100)
5739 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5740 (const_int 0)))]
5741 "TARGET_ARCH64"
5742 "xnorcc\t%%g0, %0, %%g0"
5743 [(set_attr "type" "compare")])
5744
5745 (define_insn "*cmp_cc_set_not"
5746 [(set (reg:CC 100)
5747 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5748 (const_int 0)))
5749 (set (match_operand:SI 0 "register_operand" "=r")
5750 (not:SI (match_dup 1)))]
5751 ""
5752 "xnorcc\t%%g0, %1, %0"
5753 [(set_attr "type" "compare")])
5754
5755 (define_insn "*cmp_ccx_set_not"
5756 [(set (reg:CCX 100)
5757 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5758 (const_int 0)))
5759 (set (match_operand:DI 0 "register_operand" "=r")
5760 (not:DI (match_dup 1)))]
5761 "TARGET_ARCH64"
5762 "xnorcc\t%%g0, %1, %0"
5763 [(set_attr "type" "compare")])
5764
5765 (define_insn "*cmp_cc_set"
5766 [(set (match_operand:SI 0 "register_operand" "=r")
5767 (match_operand:SI 1 "register_operand" "r"))
5768 (set (reg:CC 100)
5769 (compare:CC (match_dup 1)
5770 (const_int 0)))]
5771 ""
5772 "orcc\t%1, 0, %0"
5773 [(set_attr "type" "compare")])
5774
5775 (define_insn "*cmp_ccx_set64"
5776 [(set (match_operand:DI 0 "register_operand" "=r")
5777 (match_operand:DI 1 "register_operand" "r"))
5778 (set (reg:CCX 100)
5779 (compare:CCX (match_dup 1)
5780 (const_int 0)))]
5781 "TARGET_ARCH64"
5782 "orcc\t%1, 0, %0"
5783 [(set_attr "type" "compare")])
5784
5785
5786 ;; Floating point arithmetic instructions.
5787
5788 (define_expand "addtf3"
5789 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5790 (plus:TF (match_operand:TF 1 "general_operand" "")
5791 (match_operand:TF 2 "general_operand" "")))]
5792 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5793 "emit_tfmode_binop (PLUS, operands); DONE;")
5794
5795 (define_insn "*addtf3_hq"
5796 [(set (match_operand:TF 0 "register_operand" "=e")
5797 (plus:TF (match_operand:TF 1 "register_operand" "e")
5798 (match_operand:TF 2 "register_operand" "e")))]
5799 "TARGET_FPU && TARGET_HARD_QUAD"
5800 "faddq\t%1, %2, %0"
5801 [(set_attr "type" "fp")])
5802
5803 (define_insn "adddf3"
5804 [(set (match_operand:DF 0 "register_operand" "=e")
5805 (plus:DF (match_operand:DF 1 "register_operand" "e")
5806 (match_operand:DF 2 "register_operand" "e")))]
5807 "TARGET_FPU"
5808 "faddd\t%1, %2, %0"
5809 [(set_attr "type" "fp")
5810 (set_attr "fptype" "double")])
5811
5812 (define_insn "addsf3"
5813 [(set (match_operand:SF 0 "register_operand" "=f")
5814 (plus:SF (match_operand:SF 1 "register_operand" "f")
5815 (match_operand:SF 2 "register_operand" "f")))]
5816 "TARGET_FPU"
5817 "fadds\t%1, %2, %0"
5818 [(set_attr "type" "fp")])
5819
5820 (define_expand "subtf3"
5821 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5822 (minus:TF (match_operand:TF 1 "general_operand" "")
5823 (match_operand:TF 2 "general_operand" "")))]
5824 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5825 "emit_tfmode_binop (MINUS, operands); DONE;")
5826
5827 (define_insn "*subtf3_hq"
5828 [(set (match_operand:TF 0 "register_operand" "=e")
5829 (minus:TF (match_operand:TF 1 "register_operand" "e")
5830 (match_operand:TF 2 "register_operand" "e")))]
5831 "TARGET_FPU && TARGET_HARD_QUAD"
5832 "fsubq\t%1, %2, %0"
5833 [(set_attr "type" "fp")])
5834
5835 (define_insn "subdf3"
5836 [(set (match_operand:DF 0 "register_operand" "=e")
5837 (minus:DF (match_operand:DF 1 "register_operand" "e")
5838 (match_operand:DF 2 "register_operand" "e")))]
5839 "TARGET_FPU"
5840 "fsubd\t%1, %2, %0"
5841 [(set_attr "type" "fp")
5842 (set_attr "fptype" "double")])
5843
5844 (define_insn "subsf3"
5845 [(set (match_operand:SF 0 "register_operand" "=f")
5846 (minus:SF (match_operand:SF 1 "register_operand" "f")
5847 (match_operand:SF 2 "register_operand" "f")))]
5848 "TARGET_FPU"
5849 "fsubs\t%1, %2, %0"
5850 [(set_attr "type" "fp")])
5851
5852 (define_expand "multf3"
5853 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5854 (mult:TF (match_operand:TF 1 "general_operand" "")
5855 (match_operand:TF 2 "general_operand" "")))]
5856 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5857 "emit_tfmode_binop (MULT, operands); DONE;")
5858
5859 (define_insn "*multf3_hq"
5860 [(set (match_operand:TF 0 "register_operand" "=e")
5861 (mult:TF (match_operand:TF 1 "register_operand" "e")
5862 (match_operand:TF 2 "register_operand" "e")))]
5863 "TARGET_FPU && TARGET_HARD_QUAD"
5864 "fmulq\t%1, %2, %0"
5865 [(set_attr "type" "fpmul")])
5866
5867 (define_insn "muldf3"
5868 [(set (match_operand:DF 0 "register_operand" "=e")
5869 (mult:DF (match_operand:DF 1 "register_operand" "e")
5870 (match_operand:DF 2 "register_operand" "e")))]
5871 "TARGET_FPU"
5872 "fmuld\t%1, %2, %0"
5873 [(set_attr "type" "fpmul")
5874 (set_attr "fptype" "double")])
5875
5876 (define_insn "mulsf3"
5877 [(set (match_operand:SF 0 "register_operand" "=f")
5878 (mult:SF (match_operand:SF 1 "register_operand" "f")
5879 (match_operand:SF 2 "register_operand" "f")))]
5880 "TARGET_FPU"
5881 "fmuls\t%1, %2, %0"
5882 [(set_attr "type" "fpmul")])
5883
5884 (define_insn "*muldf3_extend"
5885 [(set (match_operand:DF 0 "register_operand" "=e")
5886 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5887 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5888 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5889 "fsmuld\t%1, %2, %0"
5890 [(set_attr "type" "fpmul")
5891 (set_attr "fptype" "double")])
5892
5893 (define_insn "*multf3_extend"
5894 [(set (match_operand:TF 0 "register_operand" "=e")
5895 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5896 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5897 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5898 "fdmulq\t%1, %2, %0"
5899 [(set_attr "type" "fpmul")])
5900
5901 (define_expand "divtf3"
5902 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5903 (div:TF (match_operand:TF 1 "general_operand" "")
5904 (match_operand:TF 2 "general_operand" "")))]
5905 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5906 "emit_tfmode_binop (DIV, operands); DONE;")
5907
5908 ;; don't have timing for quad-prec. divide.
5909 (define_insn "*divtf3_hq"
5910 [(set (match_operand:TF 0 "register_operand" "=e")
5911 (div:TF (match_operand:TF 1 "register_operand" "e")
5912 (match_operand:TF 2 "register_operand" "e")))]
5913 "TARGET_FPU && TARGET_HARD_QUAD"
5914 "fdivq\t%1, %2, %0"
5915 [(set_attr "type" "fpdivd")])
5916
5917 (define_insn "divdf3"
5918 [(set (match_operand:DF 0 "register_operand" "=e")
5919 (div:DF (match_operand:DF 1 "register_operand" "e")
5920 (match_operand:DF 2 "register_operand" "e")))]
5921 "TARGET_FPU"
5922 "fdivd\t%1, %2, %0"
5923 [(set_attr "type" "fpdivd")
5924 (set_attr "fptype" "double")])
5925
5926 (define_insn "divsf3"
5927 [(set (match_operand:SF 0 "register_operand" "=f")
5928 (div:SF (match_operand:SF 1 "register_operand" "f")
5929 (match_operand:SF 2 "register_operand" "f")))]
5930 "TARGET_FPU"
5931 "fdivs\t%1, %2, %0"
5932 [(set_attr "type" "fpdivs")])
5933
5934 (define_expand "negtf2"
5935 [(set (match_operand:TF 0 "register_operand" "=e,e")
5936 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5937 "TARGET_FPU"
5938 "")
5939
5940 (define_insn_and_split "*negtf2_notv9"
5941 [(set (match_operand:TF 0 "register_operand" "=e,e")
5942 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5943 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5944 "TARGET_FPU
5945 && ! TARGET_V9"
5946 "@
5947 fnegs\t%0, %0
5948 #"
5949 "&& reload_completed
5950 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5951 [(set (match_dup 2) (neg:SF (match_dup 3)))
5952 (set (match_dup 4) (match_dup 5))
5953 (set (match_dup 6) (match_dup 7))]
5954 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5955 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5956 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5957 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5958 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5959 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5960 [(set_attr "type" "fpmove,*")
5961 (set_attr "length" "*,2")])
5962
5963 (define_insn_and_split "*negtf2_v9"
5964 [(set (match_operand:TF 0 "register_operand" "=e,e")
5965 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5966 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5967 "TARGET_FPU && TARGET_V9"
5968 "@
5969 fnegd\t%0, %0
5970 #"
5971 "&& reload_completed
5972 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5973 [(set (match_dup 2) (neg:DF (match_dup 3)))
5974 (set (match_dup 4) (match_dup 5))]
5975 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5976 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5977 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5978 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5979 [(set_attr "type" "fpmove,*")
5980 (set_attr "length" "*,2")
5981 (set_attr "fptype" "double")])
5982
5983 (define_expand "negdf2"
5984 [(set (match_operand:DF 0 "register_operand" "")
5985 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5986 "TARGET_FPU"
5987 "")
5988
5989 (define_insn_and_split "*negdf2_notv9"
5990 [(set (match_operand:DF 0 "register_operand" "=e,e")
5991 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5992 "TARGET_FPU && ! TARGET_V9"
5993 "@
5994 fnegs\t%0, %0
5995 #"
5996 "&& reload_completed
5997 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5998 [(set (match_dup 2) (neg:SF (match_dup 3)))
5999 (set (match_dup 4) (match_dup 5))]
6000 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6001 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6002 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6003 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6004 [(set_attr "type" "fpmove,*")
6005 (set_attr "length" "*,2")])
6006
6007 (define_insn "*negdf2_v9"
6008 [(set (match_operand:DF 0 "register_operand" "=e")
6009 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6010 "TARGET_FPU && TARGET_V9"
6011 "fnegd\t%1, %0"
6012 [(set_attr "type" "fpmove")
6013 (set_attr "fptype" "double")])
6014
6015 (define_insn "negsf2"
6016 [(set (match_operand:SF 0 "register_operand" "=f")
6017 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6018 "TARGET_FPU"
6019 "fnegs\t%1, %0"
6020 [(set_attr "type" "fpmove")])
6021
6022 (define_expand "abstf2"
6023 [(set (match_operand:TF 0 "register_operand" "")
6024 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6025 "TARGET_FPU"
6026 "")
6027
6028 (define_insn_and_split "*abstf2_notv9"
6029 [(set (match_operand:TF 0 "register_operand" "=e,e")
6030 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6031 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6032 "TARGET_FPU && ! TARGET_V9"
6033 "@
6034 fabss\t%0, %0
6035 #"
6036 "&& reload_completed
6037 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6038 [(set (match_dup 2) (abs:SF (match_dup 3)))
6039 (set (match_dup 4) (match_dup 5))
6040 (set (match_dup 6) (match_dup 7))]
6041 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6042 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6043 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6044 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6045 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6046 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6047 [(set_attr "type" "fpmove,*")
6048 (set_attr "length" "*,2")])
6049
6050 (define_insn "*abstf2_hq_v9"
6051 [(set (match_operand:TF 0 "register_operand" "=e,e")
6052 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6053 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6054 "@
6055 fabsd\t%0, %0
6056 fabsq\t%1, %0"
6057 [(set_attr "type" "fpmove")
6058 (set_attr "fptype" "double,*")])
6059
6060 (define_insn_and_split "*abstf2_v9"
6061 [(set (match_operand:TF 0 "register_operand" "=e,e")
6062 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6063 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6064 "@
6065 fabsd\t%0, %0
6066 #"
6067 "&& reload_completed
6068 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6069 [(set (match_dup 2) (abs:DF (match_dup 3)))
6070 (set (match_dup 4) (match_dup 5))]
6071 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6072 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6073 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6074 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6075 [(set_attr "type" "fpmove,*")
6076 (set_attr "length" "*,2")
6077 (set_attr "fptype" "double,*")])
6078
6079 (define_expand "absdf2"
6080 [(set (match_operand:DF 0 "register_operand" "")
6081 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6082 "TARGET_FPU"
6083 "")
6084
6085 (define_insn_and_split "*absdf2_notv9"
6086 [(set (match_operand:DF 0 "register_operand" "=e,e")
6087 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6088 "TARGET_FPU && ! TARGET_V9"
6089 "@
6090 fabss\t%0, %0
6091 #"
6092 "&& reload_completed
6093 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6094 [(set (match_dup 2) (abs:SF (match_dup 3)))
6095 (set (match_dup 4) (match_dup 5))]
6096 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6097 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6098 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6099 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6100 [(set_attr "type" "fpmove,*")
6101 (set_attr "length" "*,2")])
6102
6103 (define_insn "*absdf2_v9"
6104 [(set (match_operand:DF 0 "register_operand" "=e")
6105 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6106 "TARGET_FPU && TARGET_V9"
6107 "fabsd\t%1, %0"
6108 [(set_attr "type" "fpmove")
6109 (set_attr "fptype" "double")])
6110
6111 (define_insn "abssf2"
6112 [(set (match_operand:SF 0 "register_operand" "=f")
6113 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6114 "TARGET_FPU"
6115 "fabss\t%1, %0"
6116 [(set_attr "type" "fpmove")])
6117
6118 (define_expand "sqrttf2"
6119 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6120 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6121 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6122 "emit_tfmode_unop (SQRT, operands); DONE;")
6123
6124 (define_insn "*sqrttf2_hq"
6125 [(set (match_operand:TF 0 "register_operand" "=e")
6126 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6127 "TARGET_FPU && TARGET_HARD_QUAD"
6128 "fsqrtq\t%1, %0"
6129 [(set_attr "type" "fpsqrtd")])
6130
6131 (define_insn "sqrtdf2"
6132 [(set (match_operand:DF 0 "register_operand" "=e")
6133 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6134 "TARGET_FPU"
6135 "fsqrtd\t%1, %0"
6136 [(set_attr "type" "fpsqrtd")
6137 (set_attr "fptype" "double")])
6138
6139 (define_insn "sqrtsf2"
6140 [(set (match_operand:SF 0 "register_operand" "=f")
6141 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6142 "TARGET_FPU"
6143 "fsqrts\t%1, %0"
6144 [(set_attr "type" "fpsqrts")])
6145
6146
6147 ;; Arithmetic shift instructions.
6148
6149 (define_insn "ashlsi3"
6150 [(set (match_operand:SI 0 "register_operand" "=r")
6151 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6152 (match_operand:SI 2 "arith_operand" "rI")))]
6153 ""
6154 {
6155 if (GET_CODE (operands[2]) == CONST_INT)
6156 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6157 return "sll\t%1, %2, %0";
6158 }
6159 [(set (attr "type")
6160 (if_then_else (match_operand 2 "const_one_operand" "")
6161 (const_string "ialu") (const_string "shift")))])
6162
6163 (define_expand "ashldi3"
6164 [(set (match_operand:DI 0 "register_operand" "=r")
6165 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6166 (match_operand:SI 2 "arith_operand" "rI")))]
6167 "TARGET_ARCH64 || TARGET_V8PLUS"
6168 {
6169 if (! TARGET_ARCH64)
6170 {
6171 if (GET_CODE (operands[2]) == CONST_INT)
6172 FAIL;
6173 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6174 DONE;
6175 }
6176 })
6177
6178 (define_insn "*ashldi3_sp64"
6179 [(set (match_operand:DI 0 "register_operand" "=r")
6180 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6181 (match_operand:SI 2 "arith_operand" "rI")))]
6182 "TARGET_ARCH64"
6183 {
6184 if (GET_CODE (operands[2]) == CONST_INT)
6185 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6186 return "sllx\t%1, %2, %0";
6187 }
6188 [(set (attr "type")
6189 (if_then_else (match_operand 2 "const_one_operand" "")
6190 (const_string "ialu") (const_string "shift")))])
6191
6192 ;; XXX UGH!
6193 (define_insn "ashldi3_v8plus"
6194 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6195 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6196 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6197 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6198 "TARGET_V8PLUS"
6199 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6200 [(set_attr "type" "multi")
6201 (set_attr "length" "5,5,6")])
6202
6203 ;; Optimize (1LL<<x)-1
6204 ;; XXX this also needs to be fixed to handle equal subregs
6205 ;; XXX first before we could re-enable it.
6206 ;(define_insn ""
6207 ; [(set (match_operand:DI 0 "register_operand" "=h")
6208 ; (plus:DI (ashift:DI (const_int 1)
6209 ; (match_operand:SI 1 "arith_operand" "rI"))
6210 ; (const_int -1)))]
6211 ; "0 && TARGET_V8PLUS"
6212 ;{
6213 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6214 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6215 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6216 ;}
6217 ; [(set_attr "type" "multi")
6218 ; (set_attr "length" "4")])
6219
6220 (define_insn "*cmp_cc_ashift_1"
6221 [(set (reg:CC_NOOV 100)
6222 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6223 (const_int 1))
6224 (const_int 0)))]
6225 ""
6226 "addcc\t%0, %0, %%g0"
6227 [(set_attr "type" "compare")])
6228
6229 (define_insn "*cmp_cc_set_ashift_1"
6230 [(set (reg:CC_NOOV 100)
6231 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6232 (const_int 1))
6233 (const_int 0)))
6234 (set (match_operand:SI 0 "register_operand" "=r")
6235 (ashift:SI (match_dup 1) (const_int 1)))]
6236 ""
6237 "addcc\t%1, %1, %0"
6238 [(set_attr "type" "compare")])
6239
6240 (define_insn "ashrsi3"
6241 [(set (match_operand:SI 0 "register_operand" "=r")
6242 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6243 (match_operand:SI 2 "arith_operand" "rI")))]
6244 ""
6245 {
6246 if (GET_CODE (operands[2]) == CONST_INT)
6247 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6248 return "sra\t%1, %2, %0";
6249 }
6250 [(set_attr "type" "shift")])
6251
6252 (define_insn "*ashrsi3_extend"
6253 [(set (match_operand:DI 0 "register_operand" "=r")
6254 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6255 (match_operand:SI 2 "arith_operand" "r"))))]
6256 "TARGET_ARCH64"
6257 "sra\t%1, %2, %0"
6258 [(set_attr "type" "shift")])
6259
6260 ;; This handles the case as above, but with constant shift instead of
6261 ;; register. Combiner "simplifies" it for us a little bit though.
6262 (define_insn "*ashrsi3_extend2"
6263 [(set (match_operand:DI 0 "register_operand" "=r")
6264 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6265 (const_int 32))
6266 (match_operand:SI 2 "small_int_operand" "I")))]
6267 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6268 {
6269 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6270 return "sra\t%1, %2, %0";
6271 }
6272 [(set_attr "type" "shift")])
6273
6274 (define_expand "ashrdi3"
6275 [(set (match_operand:DI 0 "register_operand" "=r")
6276 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6277 (match_operand:SI 2 "arith_operand" "rI")))]
6278 "TARGET_ARCH64 || TARGET_V8PLUS"
6279 {
6280 if (! TARGET_ARCH64)
6281 {
6282 if (GET_CODE (operands[2]) == CONST_INT)
6283 FAIL; /* prefer generic code in this case */
6284 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6285 DONE;
6286 }
6287 })
6288
6289 (define_insn "*ashrdi3_sp64"
6290 [(set (match_operand:DI 0 "register_operand" "=r")
6291 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6292 (match_operand:SI 2 "arith_operand" "rI")))]
6293 "TARGET_ARCH64"
6294
6295 {
6296 if (GET_CODE (operands[2]) == CONST_INT)
6297 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6298 return "srax\t%1, %2, %0";
6299 }
6300 [(set_attr "type" "shift")])
6301
6302 ;; XXX
6303 (define_insn "ashrdi3_v8plus"
6304 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6305 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6306 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6307 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6308 "TARGET_V8PLUS"
6309 "* return output_v8plus_shift (operands, insn, \"srax\");"
6310 [(set_attr "type" "multi")
6311 (set_attr "length" "5,5,6")])
6312
6313 (define_insn "lshrsi3"
6314 [(set (match_operand:SI 0 "register_operand" "=r")
6315 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6316 (match_operand:SI 2 "arith_operand" "rI")))]
6317 ""
6318 {
6319 if (GET_CODE (operands[2]) == CONST_INT)
6320 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6321 return "srl\t%1, %2, %0";
6322 }
6323 [(set_attr "type" "shift")])
6324
6325 ;; This handles the case where
6326 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6327 ;; but combiner "simplifies" it for us.
6328 (define_insn "*lshrsi3_extend"
6329 [(set (match_operand:DI 0 "register_operand" "=r")
6330 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6331 (match_operand:SI 2 "arith_operand" "r")) 0)
6332 (match_operand 3 "const_int_operand" "")))]
6333 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6334 "srl\t%1, %2, %0"
6335 [(set_attr "type" "shift")])
6336
6337 ;; This handles the case where
6338 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6339 ;; but combiner "simplifies" it for us.
6340 (define_insn "*lshrsi3_extend2"
6341 [(set (match_operand:DI 0 "register_operand" "=r")
6342 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6343 (match_operand 2 "small_int_operand" "I")
6344 (const_int 32)))]
6345 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6346 {
6347 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6348 return "srl\t%1, %2, %0";
6349 }
6350 [(set_attr "type" "shift")])
6351
6352 (define_expand "lshrdi3"
6353 [(set (match_operand:DI 0 "register_operand" "=r")
6354 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6355 (match_operand:SI 2 "arith_operand" "rI")))]
6356 "TARGET_ARCH64 || TARGET_V8PLUS"
6357 {
6358 if (! TARGET_ARCH64)
6359 {
6360 if (GET_CODE (operands[2]) == CONST_INT)
6361 FAIL;
6362 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6363 DONE;
6364 }
6365 })
6366
6367 (define_insn "*lshrdi3_sp64"
6368 [(set (match_operand:DI 0 "register_operand" "=r")
6369 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6370 (match_operand:SI 2 "arith_operand" "rI")))]
6371 "TARGET_ARCH64"
6372 {
6373 if (GET_CODE (operands[2]) == CONST_INT)
6374 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6375 return "srlx\t%1, %2, %0";
6376 }
6377 [(set_attr "type" "shift")])
6378
6379 ;; XXX
6380 (define_insn "lshrdi3_v8plus"
6381 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6382 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6383 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6384 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6385 "TARGET_V8PLUS"
6386 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6387 [(set_attr "type" "multi")
6388 (set_attr "length" "5,5,6")])
6389
6390 (define_insn ""
6391 [(set (match_operand:SI 0 "register_operand" "=r")
6392 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6393 (const_int 32)) 4)
6394 (match_operand:SI 2 "small_int_operand" "I")))]
6395 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6396 {
6397 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6398 return "srax\t%1, %2, %0";
6399 }
6400 [(set_attr "type" "shift")])
6401
6402 (define_insn ""
6403 [(set (match_operand:SI 0 "register_operand" "=r")
6404 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6405 (const_int 32)) 4)
6406 (match_operand:SI 2 "small_int_operand" "I")))]
6407 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6408 {
6409 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6410 return "srlx\t%1, %2, %0";
6411 }
6412 [(set_attr "type" "shift")])
6413
6414 (define_insn ""
6415 [(set (match_operand:SI 0 "register_operand" "=r")
6416 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6417 (match_operand:SI 2 "small_int_operand" "I")) 4)
6418 (match_operand:SI 3 "small_int_operand" "I")))]
6419 "TARGET_ARCH64
6420 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6421 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6422 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6423 {
6424 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6425
6426 return "srax\t%1, %2, %0";
6427 }
6428 [(set_attr "type" "shift")])
6429
6430 (define_insn ""
6431 [(set (match_operand:SI 0 "register_operand" "=r")
6432 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6433 (match_operand:SI 2 "small_int_operand" "I")) 4)
6434 (match_operand:SI 3 "small_int_operand" "I")))]
6435 "TARGET_ARCH64
6436 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6437 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6438 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6439 {
6440 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6441
6442 return "srlx\t%1, %2, %0";
6443 }
6444 [(set_attr "type" "shift")])
6445
6446
6447 ;; Unconditional and other jump instructions.
6448
6449 (define_insn "jump"
6450 [(set (pc) (label_ref (match_operand 0 "" "")))]
6451 ""
6452 "* return output_ubranch (operands[0], 0, insn);"
6453 [(set_attr "type" "uncond_branch")])
6454
6455 (define_expand "tablejump"
6456 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6457 (use (label_ref (match_operand 1 "" "")))])]
6458 ""
6459 {
6460 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6461
6462 /* In pic mode, our address differences are against the base of the
6463 table. Add that base value back in; CSE ought to be able to combine
6464 the two address loads. */
6465 if (flag_pic)
6466 {
6467 rtx tmp, tmp2;
6468 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6469 tmp2 = operands[0];
6470 if (CASE_VECTOR_MODE != Pmode)
6471 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6472 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6473 operands[0] = memory_address (Pmode, tmp);
6474 }
6475 })
6476
6477 (define_insn "*tablejump_sp32"
6478 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6479 (use (label_ref (match_operand 1 "" "")))]
6480 "! TARGET_ARCH64"
6481 "jmp\t%a0%#"
6482 [(set_attr "type" "uncond_branch")])
6483
6484 (define_insn "*tablejump_sp64"
6485 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6486 (use (label_ref (match_operand 1 "" "")))]
6487 "TARGET_ARCH64"
6488 "jmp\t%a0%#"
6489 [(set_attr "type" "uncond_branch")])
6490
6491
6492 ;; Jump to subroutine instructions.
6493
6494 (define_expand "call"
6495 ;; Note that this expression is not used for generating RTL.
6496 ;; All the RTL is generated explicitly below.
6497 [(call (match_operand 0 "call_operand" "")
6498 (match_operand 3 "" "i"))]
6499 ;; operands[2] is next_arg_register
6500 ;; operands[3] is struct_value_size_rtx.
6501 ""
6502 {
6503 rtx fn_rtx;
6504
6505 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6506
6507 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6508
6509 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6510 {
6511 /* This is really a PIC sequence. We want to represent
6512 it as a funny jump so its delay slots can be filled.
6513
6514 ??? But if this really *is* a CALL, will not it clobber the
6515 call-clobbered registers? We lose this if it is a JUMP_INSN.
6516 Why cannot we have delay slots filled if it were a CALL? */
6517
6518 /* We accept negative sizes for untyped calls. */
6519 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6520 emit_jump_insn
6521 (gen_rtx_PARALLEL
6522 (VOIDmode,
6523 gen_rtvec (3,
6524 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6525 operands[3],
6526 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6527 else
6528 emit_jump_insn
6529 (gen_rtx_PARALLEL
6530 (VOIDmode,
6531 gen_rtvec (2,
6532 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6533 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6534 goto finish_call;
6535 }
6536
6537 fn_rtx = operands[0];
6538
6539 /* We accept negative sizes for untyped calls. */
6540 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6541 sparc_emit_call_insn
6542 (gen_rtx_PARALLEL
6543 (VOIDmode,
6544 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6545 operands[3],
6546 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6547 XEXP (fn_rtx, 0));
6548 else
6549 sparc_emit_call_insn
6550 (gen_rtx_PARALLEL
6551 (VOIDmode,
6552 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6553 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6554 XEXP (fn_rtx, 0));
6555
6556 finish_call:
6557
6558 DONE;
6559 })
6560
6561 ;; We can't use the same pattern for these two insns, because then registers
6562 ;; in the address may not be properly reloaded.
6563
6564 (define_insn "*call_address_sp32"
6565 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6566 (match_operand 1 "" ""))
6567 (clobber (reg:SI 15))]
6568 ;;- Do not use operand 1 for most machines.
6569 "! TARGET_ARCH64"
6570 "call\t%a0, %1%#"
6571 [(set_attr "type" "call")])
6572
6573 (define_insn "*call_symbolic_sp32"
6574 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6575 (match_operand 1 "" ""))
6576 (clobber (reg:SI 15))]
6577 ;;- Do not use operand 1 for most machines.
6578 "! TARGET_ARCH64"
6579 "call\t%a0, %1%#"
6580 [(set_attr "type" "call")])
6581
6582 (define_insn "*call_address_sp64"
6583 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6584 (match_operand 1 "" ""))
6585 (clobber (reg:DI 15))]
6586 ;;- Do not use operand 1 for most machines.
6587 "TARGET_ARCH64"
6588 "call\t%a0, %1%#"
6589 [(set_attr "type" "call")])
6590
6591 (define_insn "*call_symbolic_sp64"
6592 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6593 (match_operand 1 "" ""))
6594 (clobber (reg:DI 15))]
6595 ;;- Do not use operand 1 for most machines.
6596 "TARGET_ARCH64"
6597 "call\t%a0, %1%#"
6598 [(set_attr "type" "call")])
6599
6600 ;; This is a call that wants a structure value.
6601 ;; There is no such critter for v9 (??? we may need one anyway).
6602 (define_insn "*call_address_struct_value_sp32"
6603 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6604 (match_operand 1 "" ""))
6605 (match_operand 2 "immediate_operand" "")
6606 (clobber (reg:SI 15))]
6607 ;;- Do not use operand 1 for most machines.
6608 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6609 {
6610 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6611 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6612 }
6613 [(set_attr "type" "call_no_delay_slot")
6614 (set_attr "length" "3")])
6615
6616 ;; This is a call that wants a structure value.
6617 ;; There is no such critter for v9 (??? we may need one anyway).
6618 (define_insn "*call_symbolic_struct_value_sp32"
6619 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6620 (match_operand 1 "" ""))
6621 (match_operand 2 "immediate_operand" "")
6622 (clobber (reg:SI 15))]
6623 ;;- Do not use operand 1 for most machines.
6624 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6625 {
6626 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6627 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6628 }
6629 [(set_attr "type" "call_no_delay_slot")
6630 (set_attr "length" "3")])
6631
6632 ;; This is a call that may want a structure value. This is used for
6633 ;; untyped_calls.
6634 (define_insn "*call_address_untyped_struct_value_sp32"
6635 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6636 (match_operand 1 "" ""))
6637 (match_operand 2 "immediate_operand" "")
6638 (clobber (reg:SI 15))]
6639 ;;- Do not use operand 1 for most machines.
6640 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6641 "call\t%a0, %1\n\t nop\n\tnop"
6642 [(set_attr "type" "call_no_delay_slot")
6643 (set_attr "length" "3")])
6644
6645 ;; This is a call that may want a structure value. This is used for
6646 ;; untyped_calls.
6647 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6648 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6649 (match_operand 1 "" ""))
6650 (match_operand 2 "immediate_operand" "")
6651 (clobber (reg:SI 15))]
6652 ;;- Do not use operand 1 for most machines.
6653 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6654 "call\t%a0, %1\n\t nop\n\tnop"
6655 [(set_attr "type" "call_no_delay_slot")
6656 (set_attr "length" "3")])
6657
6658 (define_expand "call_value"
6659 ;; Note that this expression is not used for generating RTL.
6660 ;; All the RTL is generated explicitly below.
6661 [(set (match_operand 0 "register_operand" "=rf")
6662 (call (match_operand 1 "" "")
6663 (match_operand 4 "" "")))]
6664 ;; operand 2 is stack_size_rtx
6665 ;; operand 3 is next_arg_register
6666 ""
6667 {
6668 rtx fn_rtx;
6669 rtvec vec;
6670
6671 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6672
6673 fn_rtx = operands[1];
6674
6675 vec = gen_rtvec (2,
6676 gen_rtx_SET (VOIDmode, operands[0],
6677 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6678 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6679
6680 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6681
6682 DONE;
6683 })
6684
6685 (define_insn "*call_value_address_sp32"
6686 [(set (match_operand 0 "" "=rf")
6687 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6688 (match_operand 2 "" "")))
6689 (clobber (reg:SI 15))]
6690 ;;- Do not use operand 2 for most machines.
6691 "! TARGET_ARCH64"
6692 "call\t%a1, %2%#"
6693 [(set_attr "type" "call")])
6694
6695 (define_insn "*call_value_symbolic_sp32"
6696 [(set (match_operand 0 "" "=rf")
6697 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6698 (match_operand 2 "" "")))
6699 (clobber (reg:SI 15))]
6700 ;;- Do not use operand 2 for most machines.
6701 "! TARGET_ARCH64"
6702 "call\t%a1, %2%#"
6703 [(set_attr "type" "call")])
6704
6705 (define_insn "*call_value_address_sp64"
6706 [(set (match_operand 0 "" "")
6707 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6708 (match_operand 2 "" "")))
6709 (clobber (reg:DI 15))]
6710 ;;- Do not use operand 2 for most machines.
6711 "TARGET_ARCH64"
6712 "call\t%a1, %2%#"
6713 [(set_attr "type" "call")])
6714
6715 (define_insn "*call_value_symbolic_sp64"
6716 [(set (match_operand 0 "" "")
6717 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6718 (match_operand 2 "" "")))
6719 (clobber (reg:DI 15))]
6720 ;;- Do not use operand 2 for most machines.
6721 "TARGET_ARCH64"
6722 "call\t%a1, %2%#"
6723 [(set_attr "type" "call")])
6724
6725 (define_expand "untyped_call"
6726 [(parallel [(call (match_operand 0 "" "")
6727 (const_int 0))
6728 (match_operand:BLK 1 "memory_operand" "")
6729 (match_operand 2 "" "")])]
6730 ""
6731 {
6732 rtx valreg1 = gen_rtx_REG (DImode, 8);
6733 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6734 rtx result = operands[1];
6735
6736 /* Pass constm1 to indicate that it may expect a structure value, but
6737 we don't know what size it is. */
6738 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6739
6740 /* Save the function value registers. */
6741 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6742 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6743 valreg2);
6744
6745 /* The optimizer does not know that the call sets the function value
6746 registers we stored in the result block. We avoid problems by
6747 claiming that all hard registers are used and clobbered at this
6748 point. */
6749 emit_insn (gen_blockage ());
6750
6751 DONE;
6752 })
6753
6754 ;; Tail call instructions.
6755
6756 (define_expand "sibcall"
6757 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6758 (return)])]
6759 ""
6760 "")
6761
6762 (define_insn "*sibcall_symbolic_sp32"
6763 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6764 (match_operand 1 "" ""))
6765 (return)]
6766 "! TARGET_ARCH64"
6767 "* return output_sibcall(insn, operands[0]);"
6768 [(set_attr "type" "sibcall")])
6769
6770 (define_insn "*sibcall_symbolic_sp64"
6771 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6772 (match_operand 1 "" ""))
6773 (return)]
6774 "TARGET_ARCH64"
6775 "* return output_sibcall(insn, operands[0]);"
6776 [(set_attr "type" "sibcall")])
6777
6778 (define_expand "sibcall_value"
6779 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6780 (call (match_operand 1 "" "") (const_int 0)))
6781 (return)])]
6782 ""
6783 "")
6784
6785 (define_insn "*sibcall_value_symbolic_sp32"
6786 [(set (match_operand 0 "" "=rf")
6787 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6788 (match_operand 2 "" "")))
6789 (return)]
6790 "! TARGET_ARCH64"
6791 "* return output_sibcall(insn, operands[1]);"
6792 [(set_attr "type" "sibcall")])
6793
6794 (define_insn "*sibcall_value_symbolic_sp64"
6795 [(set (match_operand 0 "" "")
6796 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6797 (match_operand 2 "" "")))
6798 (return)]
6799 "TARGET_ARCH64"
6800 "* return output_sibcall(insn, operands[1]);"
6801 [(set_attr "type" "sibcall")])
6802
6803
6804 ;; Special instructions.
6805
6806 (define_expand "prologue"
6807 [(const_int 0)]
6808 ""
6809 {
6810 sparc_expand_prologue ();
6811 DONE;
6812 })
6813
6814 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6815 ;; backend automatically emits the required call frame debugging information
6816 ;; while it is parsing it. Therefore, the pattern should not be modified
6817 ;; without first studying the impact of the changes on the debug info.
6818 ;; [(set (%fp) (%sp))
6819 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6820 ;; (set (%i7) (%o7))]
6821
6822 (define_insn "save_register_window<P:mode>"
6823 [(set (reg:P 30) (reg:P 14))
6824 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6825 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6826 (set (reg:P 31) (reg:P 15))]
6827 ""
6828 "save\t%%sp, %0, %%sp"
6829 [(set_attr "type" "savew")])
6830
6831 (define_expand "epilogue"
6832 [(return)]
6833 ""
6834 {
6835 sparc_expand_epilogue ();
6836 })
6837
6838 (define_expand "sibcall_epilogue"
6839 [(return)]
6840 ""
6841 {
6842 sparc_expand_epilogue ();
6843 DONE;
6844 })
6845
6846 (define_expand "return"
6847 [(return)]
6848 "sparc_can_use_return_insn_p ()"
6849 "")
6850
6851 (define_insn "*return_internal"
6852 [(return)]
6853 ""
6854 "* return output_return (insn);"
6855 [(set_attr "type" "return")
6856 (set (attr "length")
6857 (cond [(eq_attr "leaf_function" "true")
6858 (if_then_else (eq_attr "empty_delay_slot" "true")
6859 (const_int 2)
6860 (const_int 1))
6861 (eq_attr "calls_eh_return" "true")
6862 (if_then_else (eq_attr "delayed_branch" "true")
6863 (if_then_else (eq_attr "isa" "v9")
6864 (const_int 2)
6865 (const_int 3))
6866 (if_then_else (eq_attr "isa" "v9")
6867 (const_int 3)
6868 (const_int 4)))
6869 (eq_attr "empty_delay_slot" "true")
6870 (if_then_else (eq_attr "delayed_branch" "true")
6871 (const_int 2)
6872 (const_int 3))
6873 ] (const_int 1)))])
6874
6875 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6876 ;; all of memory. This blocks insns from being moved across this point.
6877
6878 (define_insn "blockage"
6879 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6880 ""
6881 ""
6882 [(set_attr "length" "0")])
6883
6884 ;; Prepare to return any type including a structure value.
6885
6886 (define_expand "untyped_return"
6887 [(match_operand:BLK 0 "memory_operand" "")
6888 (match_operand 1 "" "")]
6889 ""
6890 {
6891 rtx valreg1 = gen_rtx_REG (DImode, 24);
6892 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6893 rtx result = operands[0];
6894
6895 if (! TARGET_ARCH64)
6896 {
6897 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6898 ? 15 : 31));
6899 rtx value = gen_reg_rtx (SImode);
6900
6901 /* Fetch the instruction where we will return to and see if it's an unimp
6902 instruction (the most significant 10 bits will be zero). If so,
6903 update the return address to skip the unimp instruction. */
6904 emit_move_insn (value,
6905 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6906 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6907 emit_insn (gen_update_return (rtnreg, value));
6908 }
6909
6910 /* Reload the function value registers. */
6911 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6912 emit_move_insn (valreg2,
6913 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6914
6915 /* Put USE insns before the return. */
6916 emit_use (valreg1);
6917 emit_use (valreg2);
6918
6919 /* Construct the return. */
6920 expand_naked_return ();
6921
6922 DONE;
6923 })
6924
6925 ;; Adjust the return address conditionally. If the value of op1 is equal
6926 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6927 ;; This is technically *half* the check required by the 32-bit SPARC
6928 ;; psABI. This check only ensures that an "unimp" insn was written by
6929 ;; the caller, but doesn't check to see if the expected size matches
6930 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6931 ;; only used by the above code "untyped_return".
6932
6933 (define_insn "update_return"
6934 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6935 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6936 "! TARGET_ARCH64"
6937 {
6938 if (flag_delayed_branch)
6939 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6940 else
6941 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6942 }
6943 [(set (attr "type") (const_string "multi"))
6944 (set (attr "length")
6945 (if_then_else (eq_attr "delayed_branch" "true")
6946 (const_int 3)
6947 (const_int 4)))])
6948 \f
6949 (define_insn "nop"
6950 [(const_int 0)]
6951 ""
6952 "nop")
6953
6954 (define_expand "indirect_jump"
6955 [(set (pc) (match_operand 0 "address_operand" "p"))]
6956 ""
6957 "")
6958
6959 (define_insn "*branch_sp32"
6960 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6961 "! TARGET_ARCH64"
6962 "jmp\t%a0%#"
6963 [(set_attr "type" "uncond_branch")])
6964
6965 (define_insn "*branch_sp64"
6966 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6967 "TARGET_ARCH64"
6968 "jmp\t%a0%#"
6969 [(set_attr "type" "uncond_branch")])
6970
6971 (define_expand "nonlocal_goto"
6972 [(match_operand:SI 0 "general_operand" "")
6973 (match_operand:SI 1 "general_operand" "")
6974 (match_operand:SI 2 "general_operand" "")
6975 (match_operand:SI 3 "" "")]
6976 ""
6977 {
6978 rtx lab = operands[1];
6979 rtx stack = operands[2];
6980 rtx fp = operands[3];
6981 rtx labreg;
6982
6983 /* Trap instruction to flush all the register windows. */
6984 emit_insn (gen_flush_register_windows ());
6985
6986 /* Load the fp value for the containing fn into %fp. This is needed
6987 because STACK refers to %fp. Note that virtual register instantiation
6988 fails if the virtual %fp isn't set from a register. */
6989 if (GET_CODE (fp) != REG)
6990 fp = force_reg (Pmode, fp);
6991 emit_move_insn (virtual_stack_vars_rtx, fp);
6992
6993 /* Find the containing function's current nonlocal goto handler,
6994 which will do any cleanups and then jump to the label. */
6995 labreg = gen_rtx_REG (Pmode, 8);
6996 emit_move_insn (labreg, lab);
6997
6998 /* Restore %fp from stack pointer value for containing function.
6999 The restore insn that follows will move this to %sp,
7000 and reload the appropriate value into %fp. */
7001 emit_move_insn (hard_frame_pointer_rtx, stack);
7002
7003 emit_use (stack_pointer_rtx);
7004 emit_use (static_chain_rtx);
7005
7006 /* ??? The V9-specific version was disabled in rev 1.65. */
7007 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7008 emit_barrier ();
7009 DONE;
7010 })
7011
7012 ;; Special trap insn to flush register windows.
7013 (define_insn "flush_register_windows"
7014 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7015 ""
7016 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7017 [(set_attr "type" "flushw")])
7018
7019 (define_insn "goto_handler_and_restore"
7020 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7021 "GET_MODE (operands[0]) == Pmode"
7022 {
7023 if (flag_delayed_branch)
7024 return "jmp\t%0\n\t restore";
7025 else
7026 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7027 }
7028 [(set (attr "type") (const_string "multi"))
7029 (set (attr "length")
7030 (if_then_else (eq_attr "delayed_branch" "true")
7031 (const_int 2)
7032 (const_int 4)))])
7033
7034 ;; For __builtin_setjmp we need to flush register windows iff the function
7035 ;; calls alloca as well, because otherwise the register window might be
7036 ;; saved after %sp adjustment and thus setjmp would crash
7037 (define_expand "builtin_setjmp_setup"
7038 [(match_operand 0 "register_operand" "r")]
7039 ""
7040 {
7041 emit_insn (gen_do_builtin_setjmp_setup ());
7042 DONE;
7043 })
7044
7045 (define_insn "do_builtin_setjmp_setup"
7046 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7047 ""
7048 {
7049 if (! cfun->calls_alloca)
7050 return "";
7051 if (! TARGET_V9)
7052 return "\tta\t3\n";
7053 fputs ("\tflushw\n", asm_out_file);
7054 if (flag_pic)
7055 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7056 TARGET_ARCH64 ? 'x' : 'w',
7057 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7058 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7059 TARGET_ARCH64 ? 'x' : 'w',
7060 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7061 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7062 TARGET_ARCH64 ? 'x' : 'w',
7063 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7064 return "";
7065 }
7066 [(set_attr "type" "multi")
7067 (set (attr "length")
7068 (cond [(eq_attr "calls_alloca" "false")
7069 (const_int 0)
7070 (eq_attr "isa" "!v9")
7071 (const_int 1)
7072 (eq_attr "pic" "true")
7073 (const_int 4)] (const_int 3)))])
7074
7075 ;; Pattern for use after a setjmp to store FP and the return register
7076 ;; into the stack area.
7077
7078 (define_expand "setjmp"
7079 [(const_int 0)]
7080 ""
7081 {
7082 rtx mem;
7083
7084 mem = gen_rtx_MEM (Pmode,
7085 plus_constant (stack_pointer_rtx,
7086 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7087 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7088
7089 mem = gen_rtx_MEM (Pmode,
7090 plus_constant (stack_pointer_rtx,
7091 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7092 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7093 DONE;
7094 })
7095
7096 ;; Special pattern for the FLUSH instruction.
7097
7098 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7099 ; of the define_insn otherwise missing a mode. We make "flush", aka
7100 ; gen_flush, the default one since sparc_initialize_trampoline uses
7101 ; it on SImode mem values.
7102
7103 (define_insn "flush"
7104 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7105 ""
7106 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7107 [(set_attr "type" "iflush")])
7108
7109 (define_insn "flushdi"
7110 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7111 ""
7112 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7113 [(set_attr "type" "iflush")])
7114
7115
7116 ;; Find first set instructions.
7117
7118 ;; The scan instruction searches from the most significant bit while ffs
7119 ;; searches from the least significant bit. The bit index and treatment of
7120 ;; zero also differ. It takes at least 7 instructions to get the proper
7121 ;; result. Here is an obvious 8 instruction sequence.
7122
7123 ;; XXX
7124 (define_insn "ffssi2"
7125 [(set (match_operand:SI 0 "register_operand" "=&r")
7126 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7127 (clobber (match_scratch:SI 2 "=&r"))]
7128 "TARGET_SPARCLITE || TARGET_SPARCLET"
7129 {
7130 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";
7131 }
7132 [(set_attr "type" "multi")
7133 (set_attr "length" "8")])
7134
7135 ;; ??? This should be a define expand, so that the extra instruction have
7136 ;; a chance of being optimized away.
7137
7138 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7139 ;; does, but no one uses that and we don't have a switch for it.
7140 ;
7141 ;(define_insn "ffsdi2"
7142 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7143 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7144 ; (clobber (match_scratch:DI 2 "=&r"))]
7145 ; "TARGET_ARCH64"
7146 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7147 ; [(set_attr "type" "multi")
7148 ; (set_attr "length" "4")])
7149
7150
7151 \f
7152 ;; Peepholes go at the end.
7153
7154 ;; Optimize consecutive loads or stores into ldd and std when possible.
7155 ;; The conditions in which we do this are very restricted and are
7156 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7157
7158 (define_peephole2
7159 [(set (match_operand:SI 0 "memory_operand" "")
7160 (const_int 0))
7161 (set (match_operand:SI 1 "memory_operand" "")
7162 (const_int 0))]
7163 "TARGET_V9
7164 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7165 [(set (match_dup 0)
7166 (const_int 0))]
7167 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7168
7169 (define_peephole2
7170 [(set (match_operand:SI 0 "memory_operand" "")
7171 (const_int 0))
7172 (set (match_operand:SI 1 "memory_operand" "")
7173 (const_int 0))]
7174 "TARGET_V9
7175 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7176 [(set (match_dup 1)
7177 (const_int 0))]
7178 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7179
7180 (define_peephole2
7181 [(set (match_operand:SI 0 "register_operand" "")
7182 (match_operand:SI 1 "memory_operand" ""))
7183 (set (match_operand:SI 2 "register_operand" "")
7184 (match_operand:SI 3 "memory_operand" ""))]
7185 "registers_ok_for_ldd_peep (operands[0], operands[2])
7186 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7187 [(set (match_dup 0)
7188 (match_dup 1))]
7189 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7190 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7191
7192 (define_peephole2
7193 [(set (match_operand:SI 0 "memory_operand" "")
7194 (match_operand:SI 1 "register_operand" ""))
7195 (set (match_operand:SI 2 "memory_operand" "")
7196 (match_operand:SI 3 "register_operand" ""))]
7197 "registers_ok_for_ldd_peep (operands[1], operands[3])
7198 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7199 [(set (match_dup 0)
7200 (match_dup 1))]
7201 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7202 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7203
7204 (define_peephole2
7205 [(set (match_operand:SF 0 "register_operand" "")
7206 (match_operand:SF 1 "memory_operand" ""))
7207 (set (match_operand:SF 2 "register_operand" "")
7208 (match_operand:SF 3 "memory_operand" ""))]
7209 "registers_ok_for_ldd_peep (operands[0], operands[2])
7210 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7211 [(set (match_dup 0)
7212 (match_dup 1))]
7213 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7214 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7215
7216 (define_peephole2
7217 [(set (match_operand:SF 0 "memory_operand" "")
7218 (match_operand:SF 1 "register_operand" ""))
7219 (set (match_operand:SF 2 "memory_operand" "")
7220 (match_operand:SF 3 "register_operand" ""))]
7221 "registers_ok_for_ldd_peep (operands[1], operands[3])
7222 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7223 [(set (match_dup 0)
7224 (match_dup 1))]
7225 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7226 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7227
7228 (define_peephole2
7229 [(set (match_operand:SI 0 "register_operand" "")
7230 (match_operand:SI 1 "memory_operand" ""))
7231 (set (match_operand:SI 2 "register_operand" "")
7232 (match_operand:SI 3 "memory_operand" ""))]
7233 "registers_ok_for_ldd_peep (operands[2], operands[0])
7234 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7235 [(set (match_dup 2)
7236 (match_dup 3))]
7237 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7238 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7239
7240 (define_peephole2
7241 [(set (match_operand:SI 0 "memory_operand" "")
7242 (match_operand:SI 1 "register_operand" ""))
7243 (set (match_operand:SI 2 "memory_operand" "")
7244 (match_operand:SI 3 "register_operand" ""))]
7245 "registers_ok_for_ldd_peep (operands[3], operands[1])
7246 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7247 [(set (match_dup 2)
7248 (match_dup 3))]
7249 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7250 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7251 ")
7252
7253 (define_peephole2
7254 [(set (match_operand:SF 0 "register_operand" "")
7255 (match_operand:SF 1 "memory_operand" ""))
7256 (set (match_operand:SF 2 "register_operand" "")
7257 (match_operand:SF 3 "memory_operand" ""))]
7258 "registers_ok_for_ldd_peep (operands[2], operands[0])
7259 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7260 [(set (match_dup 2)
7261 (match_dup 3))]
7262 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7263 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7264
7265 (define_peephole2
7266 [(set (match_operand:SF 0 "memory_operand" "")
7267 (match_operand:SF 1 "register_operand" ""))
7268 (set (match_operand:SF 2 "memory_operand" "")
7269 (match_operand:SF 3 "register_operand" ""))]
7270 "registers_ok_for_ldd_peep (operands[3], operands[1])
7271 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7272 [(set (match_dup 2)
7273 (match_dup 3))]
7274 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7275 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7276
7277 ;; Optimize the case of following a reg-reg move with a test
7278 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7279 ;; This can result from a float to fix conversion.
7280
7281 (define_peephole2
7282 [(set (match_operand:SI 0 "register_operand" "")
7283 (match_operand:SI 1 "register_operand" ""))
7284 (set (reg:CC 100)
7285 (compare:CC (match_operand:SI 2 "register_operand" "")
7286 (const_int 0)))]
7287 "(rtx_equal_p (operands[2], operands[0])
7288 || rtx_equal_p (operands[2], operands[1]))
7289 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7290 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7291 [(parallel [(set (match_dup 0) (match_dup 1))
7292 (set (reg:CC 100)
7293 (compare:CC (match_dup 1) (const_int 0)))])]
7294 "")
7295
7296 (define_peephole2
7297 [(set (match_operand:DI 0 "register_operand" "")
7298 (match_operand:DI 1 "register_operand" ""))
7299 (set (reg:CCX 100)
7300 (compare:CCX (match_operand:DI 2 "register_operand" "")
7301 (const_int 0)))]
7302 "TARGET_ARCH64
7303 && (rtx_equal_p (operands[2], operands[0])
7304 || rtx_equal_p (operands[2], operands[1]))
7305 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7306 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7307 [(parallel [(set (match_dup 0) (match_dup 1))
7308 (set (reg:CCX 100)
7309 (compare:CCX (match_dup 1) (const_int 0)))])]
7310 "")
7311
7312
7313 ;; Prefetch instructions.
7314
7315 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7316 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7317 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7318 ;; ??? state.
7319 (define_expand "prefetch"
7320 [(match_operand 0 "address_operand" "")
7321 (match_operand 1 "const_int_operand" "")
7322 (match_operand 2 "const_int_operand" "")]
7323 "TARGET_V9"
7324 {
7325 if (TARGET_ARCH64)
7326 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7327 else
7328 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7329 DONE;
7330 })
7331
7332 (define_insn "prefetch_64"
7333 [(prefetch (match_operand:DI 0 "address_operand" "p")
7334 (match_operand:DI 1 "const_int_operand" "n")
7335 (match_operand:DI 2 "const_int_operand" "n"))]
7336 ""
7337 {
7338 static const char * const prefetch_instr[2][2] = {
7339 {
7340 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7341 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7342 },
7343 {
7344 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7345 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7346 }
7347 };
7348 int read_or_write = INTVAL (operands[1]);
7349 int locality = INTVAL (operands[2]);
7350
7351 gcc_assert (read_or_write == 0 || read_or_write == 1);
7352 gcc_assert (locality >= 0 && locality < 4);
7353 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7354 }
7355 [(set_attr "type" "load")])
7356
7357 (define_insn "prefetch_32"
7358 [(prefetch (match_operand:SI 0 "address_operand" "p")
7359 (match_operand:SI 1 "const_int_operand" "n")
7360 (match_operand:SI 2 "const_int_operand" "n"))]
7361 ""
7362 {
7363 static const char * const prefetch_instr[2][2] = {
7364 {
7365 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7366 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7367 },
7368 {
7369 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7370 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7371 }
7372 };
7373 int read_or_write = INTVAL (operands[1]);
7374 int locality = INTVAL (operands[2]);
7375
7376 gcc_assert (read_or_write == 0 || read_or_write == 1);
7377 gcc_assert (locality >= 0 && locality < 4);
7378 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7379 }
7380 [(set_attr "type" "load")])
7381
7382
7383 ;; Trap instructions.
7384
7385 (define_insn "trap"
7386 [(trap_if (const_int 1) (const_int 5))]
7387 ""
7388 "ta\t5"
7389 [(set_attr "type" "trap")])
7390
7391 (define_expand "conditional_trap"
7392 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7393 (match_operand:SI 1 "arith_operand" ""))]
7394 ""
7395 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7396 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7397 FAIL;
7398 operands[3] = const0_rtx;")
7399
7400 (define_insn ""
7401 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7402 (match_operand:SI 1 "arith_operand" "rM"))]
7403 ""
7404 {
7405 if (TARGET_V9)
7406 return "t%C0\t%%icc, %1";
7407 else
7408 return "t%C0\t%1";
7409 }
7410 [(set_attr "type" "trap")])
7411
7412 (define_insn ""
7413 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7414 (match_operand:SI 1 "arith_operand" "rM"))]
7415 "TARGET_V9"
7416 "t%C0\t%%xcc, %1"
7417 [(set_attr "type" "trap")])
7418
7419
7420 ;; TLS support instructions.
7421
7422 (define_insn "tgd_hi22"
7423 [(set (match_operand:SI 0 "register_operand" "=r")
7424 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7425 UNSPEC_TLSGD)))]
7426 "TARGET_TLS"
7427 "sethi\\t%%tgd_hi22(%a1), %0")
7428
7429 (define_insn "tgd_lo10"
7430 [(set (match_operand:SI 0 "register_operand" "=r")
7431 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7432 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7433 UNSPEC_TLSGD)))]
7434 "TARGET_TLS"
7435 "add\\t%1, %%tgd_lo10(%a2), %0")
7436
7437 (define_insn "tgd_add32"
7438 [(set (match_operand:SI 0 "register_operand" "=r")
7439 (plus:SI (match_operand:SI 1 "register_operand" "r")
7440 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7441 (match_operand 3 "tgd_symbolic_operand" "")]
7442 UNSPEC_TLSGD)))]
7443 "TARGET_TLS && TARGET_ARCH32"
7444 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7445
7446 (define_insn "tgd_add64"
7447 [(set (match_operand:DI 0 "register_operand" "=r")
7448 (plus:DI (match_operand:DI 1 "register_operand" "r")
7449 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7450 (match_operand 3 "tgd_symbolic_operand" "")]
7451 UNSPEC_TLSGD)))]
7452 "TARGET_TLS && TARGET_ARCH64"
7453 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7454
7455 (define_insn "tgd_call32"
7456 [(set (match_operand 0 "register_operand" "=r")
7457 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7458 (match_operand 2 "tgd_symbolic_operand" "")]
7459 UNSPEC_TLSGD))
7460 (match_operand 3 "" "")))
7461 (clobber (reg:SI 15))]
7462 "TARGET_TLS && TARGET_ARCH32"
7463 "call\t%a1, %%tgd_call(%a2)%#"
7464 [(set_attr "type" "call")])
7465
7466 (define_insn "tgd_call64"
7467 [(set (match_operand 0 "register_operand" "=r")
7468 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7469 (match_operand 2 "tgd_symbolic_operand" "")]
7470 UNSPEC_TLSGD))
7471 (match_operand 3 "" "")))
7472 (clobber (reg:DI 15))]
7473 "TARGET_TLS && TARGET_ARCH64"
7474 "call\t%a1, %%tgd_call(%a2)%#"
7475 [(set_attr "type" "call")])
7476
7477 (define_insn "tldm_hi22"
7478 [(set (match_operand:SI 0 "register_operand" "=r")
7479 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7480 "TARGET_TLS"
7481 "sethi\\t%%tldm_hi22(%&), %0")
7482
7483 (define_insn "tldm_lo10"
7484 [(set (match_operand:SI 0 "register_operand" "=r")
7485 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7486 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7487 "TARGET_TLS"
7488 "add\\t%1, %%tldm_lo10(%&), %0")
7489
7490 (define_insn "tldm_add32"
7491 [(set (match_operand:SI 0 "register_operand" "=r")
7492 (plus:SI (match_operand:SI 1 "register_operand" "r")
7493 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7494 UNSPEC_TLSLDM)))]
7495 "TARGET_TLS && TARGET_ARCH32"
7496 "add\\t%1, %2, %0, %%tldm_add(%&)")
7497
7498 (define_insn "tldm_add64"
7499 [(set (match_operand:DI 0 "register_operand" "=r")
7500 (plus:DI (match_operand:DI 1 "register_operand" "r")
7501 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7502 UNSPEC_TLSLDM)))]
7503 "TARGET_TLS && TARGET_ARCH64"
7504 "add\\t%1, %2, %0, %%tldm_add(%&)")
7505
7506 (define_insn "tldm_call32"
7507 [(set (match_operand 0 "register_operand" "=r")
7508 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7509 UNSPEC_TLSLDM))
7510 (match_operand 2 "" "")))
7511 (clobber (reg:SI 15))]
7512 "TARGET_TLS && TARGET_ARCH32"
7513 "call\t%a1, %%tldm_call(%&)%#"
7514 [(set_attr "type" "call")])
7515
7516 (define_insn "tldm_call64"
7517 [(set (match_operand 0 "register_operand" "=r")
7518 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7519 UNSPEC_TLSLDM))
7520 (match_operand 2 "" "")))
7521 (clobber (reg:DI 15))]
7522 "TARGET_TLS && TARGET_ARCH64"
7523 "call\t%a1, %%tldm_call(%&)%#"
7524 [(set_attr "type" "call")])
7525
7526 (define_insn "tldo_hix22"
7527 [(set (match_operand:SI 0 "register_operand" "=r")
7528 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7529 UNSPEC_TLSLDO)))]
7530 "TARGET_TLS"
7531 "sethi\\t%%tldo_hix22(%a1), %0")
7532
7533 (define_insn "tldo_lox10"
7534 [(set (match_operand:SI 0 "register_operand" "=r")
7535 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7536 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7537 UNSPEC_TLSLDO)))]
7538 "TARGET_TLS"
7539 "xor\\t%1, %%tldo_lox10(%a2), %0")
7540
7541 (define_insn "tldo_add32"
7542 [(set (match_operand:SI 0 "register_operand" "=r")
7543 (plus:SI (match_operand:SI 1 "register_operand" "r")
7544 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7545 (match_operand 3 "tld_symbolic_operand" "")]
7546 UNSPEC_TLSLDO)))]
7547 "TARGET_TLS && TARGET_ARCH32"
7548 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7549
7550 (define_insn "tldo_add64"
7551 [(set (match_operand:DI 0 "register_operand" "=r")
7552 (plus:DI (match_operand:DI 1 "register_operand" "r")
7553 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7554 (match_operand 3 "tld_symbolic_operand" "")]
7555 UNSPEC_TLSLDO)))]
7556 "TARGET_TLS && TARGET_ARCH64"
7557 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7558
7559 (define_insn "tie_hi22"
7560 [(set (match_operand:SI 0 "register_operand" "=r")
7561 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7562 UNSPEC_TLSIE)))]
7563 "TARGET_TLS"
7564 "sethi\\t%%tie_hi22(%a1), %0")
7565
7566 (define_insn "tie_lo10"
7567 [(set (match_operand:SI 0 "register_operand" "=r")
7568 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7569 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7570 UNSPEC_TLSIE)))]
7571 "TARGET_TLS"
7572 "add\\t%1, %%tie_lo10(%a2), %0")
7573
7574 (define_insn "tie_ld32"
7575 [(set (match_operand:SI 0 "register_operand" "=r")
7576 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7577 (match_operand:SI 2 "register_operand" "r")
7578 (match_operand 3 "tie_symbolic_operand" "")]
7579 UNSPEC_TLSIE))]
7580 "TARGET_TLS && TARGET_ARCH32"
7581 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7582 [(set_attr "type" "load")])
7583
7584 (define_insn "tie_ld64"
7585 [(set (match_operand:DI 0 "register_operand" "=r")
7586 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7587 (match_operand:SI 2 "register_operand" "r")
7588 (match_operand 3 "tie_symbolic_operand" "")]
7589 UNSPEC_TLSIE))]
7590 "TARGET_TLS && TARGET_ARCH64"
7591 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7592 [(set_attr "type" "load")])
7593
7594 (define_insn "tie_add32"
7595 [(set (match_operand:SI 0 "register_operand" "=r")
7596 (plus:SI (match_operand:SI 1 "register_operand" "r")
7597 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7598 (match_operand 3 "tie_symbolic_operand" "")]
7599 UNSPEC_TLSIE)))]
7600 "TARGET_SUN_TLS && TARGET_ARCH32"
7601 "add\\t%1, %2, %0, %%tie_add(%a3)")
7602
7603 (define_insn "tie_add64"
7604 [(set (match_operand:DI 0 "register_operand" "=r")
7605 (plus:DI (match_operand:DI 1 "register_operand" "r")
7606 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7607 (match_operand 3 "tie_symbolic_operand" "")]
7608 UNSPEC_TLSIE)))]
7609 "TARGET_SUN_TLS && TARGET_ARCH64"
7610 "add\\t%1, %2, %0, %%tie_add(%a3)")
7611
7612 (define_insn "tle_hix22_sp32"
7613 [(set (match_operand:SI 0 "register_operand" "=r")
7614 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7615 UNSPEC_TLSLE)))]
7616 "TARGET_TLS && TARGET_ARCH32"
7617 "sethi\\t%%tle_hix22(%a1), %0")
7618
7619 (define_insn "tle_lox10_sp32"
7620 [(set (match_operand:SI 0 "register_operand" "=r")
7621 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7622 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7623 UNSPEC_TLSLE)))]
7624 "TARGET_TLS && TARGET_ARCH32"
7625 "xor\\t%1, %%tle_lox10(%a2), %0")
7626
7627 (define_insn "tle_hix22_sp64"
7628 [(set (match_operand:DI 0 "register_operand" "=r")
7629 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7630 UNSPEC_TLSLE)))]
7631 "TARGET_TLS && TARGET_ARCH64"
7632 "sethi\\t%%tle_hix22(%a1), %0")
7633
7634 (define_insn "tle_lox10_sp64"
7635 [(set (match_operand:DI 0 "register_operand" "=r")
7636 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7637 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7638 UNSPEC_TLSLE)))]
7639 "TARGET_TLS && TARGET_ARCH64"
7640 "xor\\t%1, %%tle_lox10(%a2), %0")
7641
7642 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7643 (define_insn "*tldo_ldub_sp32"
7644 [(set (match_operand:QI 0 "register_operand" "=r")
7645 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7646 (match_operand 3 "tld_symbolic_operand" "")]
7647 UNSPEC_TLSLDO)
7648 (match_operand:SI 1 "register_operand" "r"))))]
7649 "TARGET_TLS && TARGET_ARCH32"
7650 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7651 [(set_attr "type" "load")
7652 (set_attr "us3load_type" "3cycle")])
7653
7654 (define_insn "*tldo_ldub1_sp32"
7655 [(set (match_operand:HI 0 "register_operand" "=r")
7656 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7657 (match_operand 3 "tld_symbolic_operand" "")]
7658 UNSPEC_TLSLDO)
7659 (match_operand:SI 1 "register_operand" "r")))))]
7660 "TARGET_TLS && TARGET_ARCH32"
7661 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7662 [(set_attr "type" "load")
7663 (set_attr "us3load_type" "3cycle")])
7664
7665 (define_insn "*tldo_ldub2_sp32"
7666 [(set (match_operand:SI 0 "register_operand" "=r")
7667 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7668 (match_operand 3 "tld_symbolic_operand" "")]
7669 UNSPEC_TLSLDO)
7670 (match_operand:SI 1 "register_operand" "r")))))]
7671 "TARGET_TLS && TARGET_ARCH32"
7672 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7673 [(set_attr "type" "load")
7674 (set_attr "us3load_type" "3cycle")])
7675
7676 (define_insn "*tldo_ldsb1_sp32"
7677 [(set (match_operand:HI 0 "register_operand" "=r")
7678 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7679 (match_operand 3 "tld_symbolic_operand" "")]
7680 UNSPEC_TLSLDO)
7681 (match_operand:SI 1 "register_operand" "r")))))]
7682 "TARGET_TLS && TARGET_ARCH32"
7683 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7684 [(set_attr "type" "sload")
7685 (set_attr "us3load_type" "3cycle")])
7686
7687 (define_insn "*tldo_ldsb2_sp32"
7688 [(set (match_operand:SI 0 "register_operand" "=r")
7689 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7690 (match_operand 3 "tld_symbolic_operand" "")]
7691 UNSPEC_TLSLDO)
7692 (match_operand:SI 1 "register_operand" "r")))))]
7693 "TARGET_TLS && TARGET_ARCH32"
7694 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7695 [(set_attr "type" "sload")
7696 (set_attr "us3load_type" "3cycle")])
7697
7698 (define_insn "*tldo_ldub_sp64"
7699 [(set (match_operand:QI 0 "register_operand" "=r")
7700 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7701 (match_operand 3 "tld_symbolic_operand" "")]
7702 UNSPEC_TLSLDO)
7703 (match_operand:DI 1 "register_operand" "r"))))]
7704 "TARGET_TLS && TARGET_ARCH64"
7705 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7706 [(set_attr "type" "load")
7707 (set_attr "us3load_type" "3cycle")])
7708
7709 (define_insn "*tldo_ldub1_sp64"
7710 [(set (match_operand:HI 0 "register_operand" "=r")
7711 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7712 (match_operand 3 "tld_symbolic_operand" "")]
7713 UNSPEC_TLSLDO)
7714 (match_operand:DI 1 "register_operand" "r")))))]
7715 "TARGET_TLS && TARGET_ARCH64"
7716 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7717 [(set_attr "type" "load")
7718 (set_attr "us3load_type" "3cycle")])
7719
7720 (define_insn "*tldo_ldub2_sp64"
7721 [(set (match_operand:SI 0 "register_operand" "=r")
7722 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7723 (match_operand 3 "tld_symbolic_operand" "")]
7724 UNSPEC_TLSLDO)
7725 (match_operand:DI 1 "register_operand" "r")))))]
7726 "TARGET_TLS && TARGET_ARCH64"
7727 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7728 [(set_attr "type" "load")
7729 (set_attr "us3load_type" "3cycle")])
7730
7731 (define_insn "*tldo_ldub3_sp64"
7732 [(set (match_operand:DI 0 "register_operand" "=r")
7733 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7734 (match_operand 3 "tld_symbolic_operand" "")]
7735 UNSPEC_TLSLDO)
7736 (match_operand:DI 1 "register_operand" "r")))))]
7737 "TARGET_TLS && TARGET_ARCH64"
7738 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7739 [(set_attr "type" "load")
7740 (set_attr "us3load_type" "3cycle")])
7741
7742 (define_insn "*tldo_ldsb1_sp64"
7743 [(set (match_operand:HI 0 "register_operand" "=r")
7744 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7745 (match_operand 3 "tld_symbolic_operand" "")]
7746 UNSPEC_TLSLDO)
7747 (match_operand:DI 1 "register_operand" "r")))))]
7748 "TARGET_TLS && TARGET_ARCH64"
7749 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7750 [(set_attr "type" "sload")
7751 (set_attr "us3load_type" "3cycle")])
7752
7753 (define_insn "*tldo_ldsb2_sp64"
7754 [(set (match_operand:SI 0 "register_operand" "=r")
7755 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7756 (match_operand 3 "tld_symbolic_operand" "")]
7757 UNSPEC_TLSLDO)
7758 (match_operand:DI 1 "register_operand" "r")))))]
7759 "TARGET_TLS && TARGET_ARCH64"
7760 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7761 [(set_attr "type" "sload")
7762 (set_attr "us3load_type" "3cycle")])
7763
7764 (define_insn "*tldo_ldsb3_sp64"
7765 [(set (match_operand:DI 0 "register_operand" "=r")
7766 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7767 (match_operand 3 "tld_symbolic_operand" "")]
7768 UNSPEC_TLSLDO)
7769 (match_operand:DI 1 "register_operand" "r")))))]
7770 "TARGET_TLS && TARGET_ARCH64"
7771 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7772 [(set_attr "type" "sload")
7773 (set_attr "us3load_type" "3cycle")])
7774
7775 (define_insn "*tldo_lduh_sp32"
7776 [(set (match_operand:HI 0 "register_operand" "=r")
7777 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7778 (match_operand 3 "tld_symbolic_operand" "")]
7779 UNSPEC_TLSLDO)
7780 (match_operand:SI 1 "register_operand" "r"))))]
7781 "TARGET_TLS && TARGET_ARCH32"
7782 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7783 [(set_attr "type" "load")
7784 (set_attr "us3load_type" "3cycle")])
7785
7786 (define_insn "*tldo_lduh1_sp32"
7787 [(set (match_operand:SI 0 "register_operand" "=r")
7788 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7789 (match_operand 3 "tld_symbolic_operand" "")]
7790 UNSPEC_TLSLDO)
7791 (match_operand:SI 1 "register_operand" "r")))))]
7792 "TARGET_TLS && TARGET_ARCH32"
7793 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7794 [(set_attr "type" "load")
7795 (set_attr "us3load_type" "3cycle")])
7796
7797 (define_insn "*tldo_ldsh1_sp32"
7798 [(set (match_operand:SI 0 "register_operand" "=r")
7799 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7800 (match_operand 3 "tld_symbolic_operand" "")]
7801 UNSPEC_TLSLDO)
7802 (match_operand:SI 1 "register_operand" "r")))))]
7803 "TARGET_TLS && TARGET_ARCH32"
7804 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7805 [(set_attr "type" "sload")
7806 (set_attr "us3load_type" "3cycle")])
7807
7808 (define_insn "*tldo_lduh_sp64"
7809 [(set (match_operand:HI 0 "register_operand" "=r")
7810 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7811 (match_operand 3 "tld_symbolic_operand" "")]
7812 UNSPEC_TLSLDO)
7813 (match_operand:DI 1 "register_operand" "r"))))]
7814 "TARGET_TLS && TARGET_ARCH64"
7815 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7816 [(set_attr "type" "load")
7817 (set_attr "us3load_type" "3cycle")])
7818
7819 (define_insn "*tldo_lduh1_sp64"
7820 [(set (match_operand:SI 0 "register_operand" "=r")
7821 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7822 (match_operand 3 "tld_symbolic_operand" "")]
7823 UNSPEC_TLSLDO)
7824 (match_operand:DI 1 "register_operand" "r")))))]
7825 "TARGET_TLS && TARGET_ARCH64"
7826 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7827 [(set_attr "type" "load")
7828 (set_attr "us3load_type" "3cycle")])
7829
7830 (define_insn "*tldo_lduh2_sp64"
7831 [(set (match_operand:DI 0 "register_operand" "=r")
7832 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7833 (match_operand 3 "tld_symbolic_operand" "")]
7834 UNSPEC_TLSLDO)
7835 (match_operand:DI 1 "register_operand" "r")))))]
7836 "TARGET_TLS && TARGET_ARCH64"
7837 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7838 [(set_attr "type" "load")
7839 (set_attr "us3load_type" "3cycle")])
7840
7841 (define_insn "*tldo_ldsh1_sp64"
7842 [(set (match_operand:SI 0 "register_operand" "=r")
7843 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7844 (match_operand 3 "tld_symbolic_operand" "")]
7845 UNSPEC_TLSLDO)
7846 (match_operand:DI 1 "register_operand" "r")))))]
7847 "TARGET_TLS && TARGET_ARCH64"
7848 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7849 [(set_attr "type" "sload")
7850 (set_attr "us3load_type" "3cycle")])
7851
7852 (define_insn "*tldo_ldsh2_sp64"
7853 [(set (match_operand:DI 0 "register_operand" "=r")
7854 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7855 (match_operand 3 "tld_symbolic_operand" "")]
7856 UNSPEC_TLSLDO)
7857 (match_operand:DI 1 "register_operand" "r")))))]
7858 "TARGET_TLS && TARGET_ARCH64"
7859 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7860 [(set_attr "type" "sload")
7861 (set_attr "us3load_type" "3cycle")])
7862
7863 (define_insn "*tldo_lduw_sp32"
7864 [(set (match_operand:SI 0 "register_operand" "=r")
7865 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7866 (match_operand 3 "tld_symbolic_operand" "")]
7867 UNSPEC_TLSLDO)
7868 (match_operand:SI 1 "register_operand" "r"))))]
7869 "TARGET_TLS && TARGET_ARCH32"
7870 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7871 [(set_attr "type" "load")])
7872
7873 (define_insn "*tldo_lduw_sp64"
7874 [(set (match_operand:SI 0 "register_operand" "=r")
7875 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7876 (match_operand 3 "tld_symbolic_operand" "")]
7877 UNSPEC_TLSLDO)
7878 (match_operand:DI 1 "register_operand" "r"))))]
7879 "TARGET_TLS && TARGET_ARCH64"
7880 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7881 [(set_attr "type" "load")])
7882
7883 (define_insn "*tldo_lduw1_sp64"
7884 [(set (match_operand:DI 0 "register_operand" "=r")
7885 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7886 (match_operand 3 "tld_symbolic_operand" "")]
7887 UNSPEC_TLSLDO)
7888 (match_operand:DI 1 "register_operand" "r")))))]
7889 "TARGET_TLS && TARGET_ARCH64"
7890 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7891 [(set_attr "type" "load")])
7892
7893 (define_insn "*tldo_ldsw1_sp64"
7894 [(set (match_operand:DI 0 "register_operand" "=r")
7895 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7896 (match_operand 3 "tld_symbolic_operand" "")]
7897 UNSPEC_TLSLDO)
7898 (match_operand:DI 1 "register_operand" "r")))))]
7899 "TARGET_TLS && TARGET_ARCH64"
7900 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7901 [(set_attr "type" "sload")
7902 (set_attr "us3load_type" "3cycle")])
7903
7904 (define_insn "*tldo_ldx_sp64"
7905 [(set (match_operand:DI 0 "register_operand" "=r")
7906 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7907 (match_operand 3 "tld_symbolic_operand" "")]
7908 UNSPEC_TLSLDO)
7909 (match_operand:DI 1 "register_operand" "r"))))]
7910 "TARGET_TLS && TARGET_ARCH64"
7911 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7912 [(set_attr "type" "load")])
7913
7914 (define_insn "*tldo_stb_sp32"
7915 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7916 (match_operand 3 "tld_symbolic_operand" "")]
7917 UNSPEC_TLSLDO)
7918 (match_operand:SI 1 "register_operand" "r")))
7919 (match_operand:QI 0 "register_operand" "=r"))]
7920 "TARGET_TLS && TARGET_ARCH32"
7921 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7922 [(set_attr "type" "store")])
7923
7924 (define_insn "*tldo_stb_sp64"
7925 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7926 (match_operand 3 "tld_symbolic_operand" "")]
7927 UNSPEC_TLSLDO)
7928 (match_operand:DI 1 "register_operand" "r")))
7929 (match_operand:QI 0 "register_operand" "=r"))]
7930 "TARGET_TLS && TARGET_ARCH64"
7931 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7932 [(set_attr "type" "store")])
7933
7934 (define_insn "*tldo_sth_sp32"
7935 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7936 (match_operand 3 "tld_symbolic_operand" "")]
7937 UNSPEC_TLSLDO)
7938 (match_operand:SI 1 "register_operand" "r")))
7939 (match_operand:HI 0 "register_operand" "=r"))]
7940 "TARGET_TLS && TARGET_ARCH32"
7941 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7942 [(set_attr "type" "store")])
7943
7944 (define_insn "*tldo_sth_sp64"
7945 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7946 (match_operand 3 "tld_symbolic_operand" "")]
7947 UNSPEC_TLSLDO)
7948 (match_operand:DI 1 "register_operand" "r")))
7949 (match_operand:HI 0 "register_operand" "=r"))]
7950 "TARGET_TLS && TARGET_ARCH64"
7951 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7952 [(set_attr "type" "store")])
7953
7954 (define_insn "*tldo_stw_sp32"
7955 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7956 (match_operand 3 "tld_symbolic_operand" "")]
7957 UNSPEC_TLSLDO)
7958 (match_operand:SI 1 "register_operand" "r")))
7959 (match_operand:SI 0 "register_operand" "=r"))]
7960 "TARGET_TLS && TARGET_ARCH32"
7961 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7962 [(set_attr "type" "store")])
7963
7964 (define_insn "*tldo_stw_sp64"
7965 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7966 (match_operand 3 "tld_symbolic_operand" "")]
7967 UNSPEC_TLSLDO)
7968 (match_operand:DI 1 "register_operand" "r")))
7969 (match_operand:SI 0 "register_operand" "=r"))]
7970 "TARGET_TLS && TARGET_ARCH64"
7971 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7972 [(set_attr "type" "store")])
7973
7974 (define_insn "*tldo_stx_sp64"
7975 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7976 (match_operand 3 "tld_symbolic_operand" "")]
7977 UNSPEC_TLSLDO)
7978 (match_operand:DI 1 "register_operand" "r")))
7979 (match_operand:DI 0 "register_operand" "=r"))]
7980 "TARGET_TLS && TARGET_ARCH64"
7981 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7982 [(set_attr "type" "store")])
7983
7984
7985 ;; Stack protector instructions.
7986
7987 (define_expand "stack_protect_set"
7988 [(match_operand 0 "memory_operand" "")
7989 (match_operand 1 "memory_operand" "")]
7990 ""
7991 {
7992 #ifdef TARGET_THREAD_SSP_OFFSET
7993 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7994 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7995 operands[1] = gen_rtx_MEM (Pmode, addr);
7996 #endif
7997 if (TARGET_ARCH64)
7998 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7999 else
8000 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8001 DONE;
8002 })
8003
8004 (define_insn "stack_protect_setsi"
8005 [(set (match_operand:SI 0 "memory_operand" "=m")
8006 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8007 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8008 "TARGET_ARCH32"
8009 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8010 [(set_attr "type" "multi")
8011 (set_attr "length" "3")])
8012
8013 (define_insn "stack_protect_setdi"
8014 [(set (match_operand:DI 0 "memory_operand" "=m")
8015 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8016 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8017 "TARGET_ARCH64"
8018 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8019 [(set_attr "type" "multi")
8020 (set_attr "length" "3")])
8021
8022 (define_expand "stack_protect_test"
8023 [(match_operand 0 "memory_operand" "")
8024 (match_operand 1 "memory_operand" "")
8025 (match_operand 2 "" "")]
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 {
8035 rtx temp = gen_reg_rtx (Pmode);
8036 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8037 sparc_compare_op0 = temp;
8038 sparc_compare_op1 = const0_rtx;
8039 }
8040 else
8041 {
8042 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8043 sparc_compare_op0 = operands[0];
8044 sparc_compare_op1 = operands[1];
8045 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8046 }
8047 emit_jump_insn (gen_beq (operands[2]));
8048 DONE;
8049 })
8050
8051 (define_insn "stack_protect_testsi"
8052 [(set (reg:CC 100)
8053 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8054 (match_operand:SI 1 "memory_operand" "m")]
8055 UNSPEC_SP_TEST))
8056 (set (match_scratch:SI 3 "=r") (const_int 0))
8057 (clobber (match_scratch:SI 2 "=&r"))]
8058 "TARGET_ARCH32"
8059 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8060 [(set_attr "type" "multi")
8061 (set_attr "length" "4")])
8062
8063 (define_insn "stack_protect_testdi"
8064 [(set (match_operand:DI 0 "register_operand" "=&r")
8065 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8066 (match_operand:DI 2 "memory_operand" "m")]
8067 UNSPEC_SP_TEST))
8068 (set (match_scratch:DI 3 "=r") (const_int 0))]
8069 "TARGET_ARCH64"
8070 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8071 [(set_attr "type" "multi")
8072 (set_attr "length" "4")])
8073
8074
8075 ;; Vector instructions.
8076
8077 (define_insn "addv2si3"
8078 [(set (match_operand:V2SI 0 "register_operand" "=e")
8079 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8080 (match_operand:V2SI 2 "register_operand" "e")))]
8081 "TARGET_VIS"
8082 "fpadd32\t%1, %2, %0"
8083 [(set_attr "type" "fga")
8084 (set_attr "fptype" "double")])
8085
8086 (define_insn "addv4hi3"
8087 [(set (match_operand:V4HI 0 "register_operand" "=e")
8088 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8089 (match_operand:V4HI 2 "register_operand" "e")))]
8090 "TARGET_VIS"
8091 "fpadd16\t%1, %2, %0"
8092 [(set_attr "type" "fga")
8093 (set_attr "fptype" "double")])
8094
8095 ;; fpadd32s is emitted by the addsi3 pattern.
8096
8097 (define_insn "addv2hi3"
8098 [(set (match_operand:V2HI 0 "register_operand" "=f")
8099 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8100 (match_operand:V2HI 2 "register_operand" "f")))]
8101 "TARGET_VIS"
8102 "fpadd16s\t%1, %2, %0"
8103 [(set_attr "type" "fga")
8104 (set_attr "fptype" "single")])
8105
8106 (define_insn "subv2si3"
8107 [(set (match_operand:V2SI 0 "register_operand" "=e")
8108 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8109 (match_operand:V2SI 2 "register_operand" "e")))]
8110 "TARGET_VIS"
8111 "fpsub32\t%1, %2, %0"
8112 [(set_attr "type" "fga")
8113 (set_attr "fptype" "double")])
8114
8115 (define_insn "subv4hi3"
8116 [(set (match_operand:V4HI 0 "register_operand" "=e")
8117 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8118 (match_operand:V4HI 2 "register_operand" "e")))]
8119 "TARGET_VIS"
8120 "fpsub16\t%1, %2, %0"
8121 [(set_attr "type" "fga")
8122 (set_attr "fptype" "double")])
8123
8124 ;; fpsub32s is emitted by the subsi3 pattern.
8125
8126 (define_insn "subv2hi3"
8127 [(set (match_operand:V2HI 0 "register_operand" "=f")
8128 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8129 (match_operand:V2HI 2 "register_operand" "f")))]
8130 "TARGET_VIS"
8131 "fpsub16s\t%1, %2, %0"
8132 [(set_attr "type" "fga")
8133 (set_attr "fptype" "single")])
8134
8135 ;; All other logical instructions have integer equivalents so they
8136 ;; are defined together.
8137
8138 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8139
8140 (define_insn "*nand<V64mode>_vis"
8141 [(set (match_operand:V64 0 "register_operand" "=e")
8142 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8143 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8144 "TARGET_VIS"
8145 "fnand\t%1, %2, %0"
8146 [(set_attr "type" "fga")
8147 (set_attr "fptype" "double")])
8148
8149 (define_insn "*nand<V32mode>_vis"
8150 [(set (match_operand:V32 0 "register_operand" "=f")
8151 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8152 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8153 "TARGET_VIS"
8154 "fnands\t%1, %2, %0"
8155 [(set_attr "type" "fga")
8156 (set_attr "fptype" "single")])
8157
8158 ;; Hard to generate VIS instructions. We have builtins for these.
8159
8160 (define_insn "fpack16_vis"
8161 [(set (match_operand:V4QI 0 "register_operand" "=f")
8162 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8163 UNSPEC_FPACK16))]
8164 "TARGET_VIS"
8165 "fpack16\t%1, %0"
8166 [(set_attr "type" "fga")
8167 (set_attr "fptype" "double")])
8168
8169 (define_insn "fpackfix_vis"
8170 [(set (match_operand:V2HI 0 "register_operand" "=f")
8171 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8172 UNSPEC_FPACKFIX))]
8173 "TARGET_VIS"
8174 "fpackfix\t%1, %0"
8175 [(set_attr "type" "fga")
8176 (set_attr "fptype" "double")])
8177
8178 (define_insn "fpack32_vis"
8179 [(set (match_operand:V8QI 0 "register_operand" "=e")
8180 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8181 (match_operand:V8QI 2 "register_operand" "e")]
8182 UNSPEC_FPACK32))]
8183 "TARGET_VIS"
8184 "fpack32\t%1, %2, %0"
8185 [(set_attr "type" "fga")
8186 (set_attr "fptype" "double")])
8187
8188 (define_insn "fexpand_vis"
8189 [(set (match_operand:V4HI 0 "register_operand" "=e")
8190 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8191 UNSPEC_FEXPAND))]
8192 "TARGET_VIS"
8193 "fexpand\t%1, %0"
8194 [(set_attr "type" "fga")
8195 (set_attr "fptype" "double")])
8196
8197 ;; It may be possible to describe this operation as (1 indexed):
8198 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8199 ;; 1,5,10,14,19,23,28,32)
8200 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8201 ;; because vec_merge expects all the operands to be of the same type.
8202 (define_insn "fpmerge_vis"
8203 [(set (match_operand:V8QI 0 "register_operand" "=e")
8204 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8205 (match_operand:V4QI 2 "register_operand" "f")]
8206 UNSPEC_FPMERGE))]
8207 "TARGET_VIS"
8208 "fpmerge\t%1, %2, %0"
8209 [(set_attr "type" "fga")
8210 (set_attr "fptype" "double")])
8211
8212 ;; Partitioned multiply instructions
8213 (define_insn "fmul8x16_vis"
8214 [(set (match_operand:V4HI 0 "register_operand" "=e")
8215 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8216 (match_operand:V4HI 2 "register_operand" "e")))]
8217 "TARGET_VIS"
8218 "fmul8x16\t%1, %2, %0"
8219 [(set_attr "type" "fpmul")
8220 (set_attr "fptype" "double")])
8221
8222 ;; Only one of the following two insns can be a multiply.
8223 (define_insn "fmul8x16au_vis"
8224 [(set (match_operand:V4HI 0 "register_operand" "=e")
8225 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8226 (match_operand:V2HI 2 "register_operand" "f")))]
8227 "TARGET_VIS"
8228 "fmul8x16au\t%1, %2, %0"
8229 [(set_attr "type" "fpmul")
8230 (set_attr "fptype" "double")])
8231
8232 (define_insn "fmul8x16al_vis"
8233 [(set (match_operand:V4HI 0 "register_operand" "=e")
8234 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8235 (match_operand:V2HI 2 "register_operand" "f")]
8236 UNSPEC_MUL16AL))]
8237 "TARGET_VIS"
8238 "fmul8x16al\t%1, %2, %0"
8239 [(set_attr "type" "fpmul")
8240 (set_attr "fptype" "double")])
8241
8242 ;; Only one of the following two insns can be a multiply.
8243 (define_insn "fmul8sux16_vis"
8244 [(set (match_operand:V4HI 0 "register_operand" "=e")
8245 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8246 (match_operand:V4HI 2 "register_operand" "e")))]
8247 "TARGET_VIS"
8248 "fmul8sux16\t%1, %2, %0"
8249 [(set_attr "type" "fpmul")
8250 (set_attr "fptype" "double")])
8251
8252 (define_insn "fmul8ulx16_vis"
8253 [(set (match_operand:V4HI 0 "register_operand" "=e")
8254 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8255 (match_operand:V4HI 2 "register_operand" "e")]
8256 UNSPEC_MUL8UL))]
8257 "TARGET_VIS"
8258 "fmul8ulx16\t%1, %2, %0"
8259 [(set_attr "type" "fpmul")
8260 (set_attr "fptype" "double")])
8261
8262 ;; Only one of the following two insns can be a multiply.
8263 (define_insn "fmuld8sux16_vis"
8264 [(set (match_operand:V2SI 0 "register_operand" "=e")
8265 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8266 (match_operand:V2HI 2 "register_operand" "f")))]
8267 "TARGET_VIS"
8268 "fmuld8sux16\t%1, %2, %0"
8269 [(set_attr "type" "fpmul")
8270 (set_attr "fptype" "double")])
8271
8272 (define_insn "fmuld8ulx16_vis"
8273 [(set (match_operand:V2SI 0 "register_operand" "=e")
8274 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8275 (match_operand:V2HI 2 "register_operand" "f")]
8276 UNSPEC_MULDUL))]
8277 "TARGET_VIS"
8278 "fmuld8ulx16\t%1, %2, %0"
8279 [(set_attr "type" "fpmul")
8280 (set_attr "fptype" "double")])
8281
8282 ;; Using faligndata only makes sense after an alignaddr since the choice of
8283 ;; bytes to take out of each operand is dependent on the results of the last
8284 ;; alignaddr.
8285 (define_insn "faligndata<V64I:mode>_vis"
8286 [(set (match_operand:V64I 0 "register_operand" "=e")
8287 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8288 (match_operand:V64I 2 "register_operand" "e")]
8289 UNSPEC_ALIGNDATA))]
8290 "TARGET_VIS"
8291 "faligndata\t%1, %2, %0"
8292 [(set_attr "type" "fga")
8293 (set_attr "fptype" "double")])
8294
8295 (define_insn "alignaddr<P:mode>_vis"
8296 [(set (match_operand:P 0 "register_operand" "=r")
8297 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8298 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8299 UNSPEC_ALIGNADDR))]
8300 "TARGET_VIS"
8301 "alignaddr\t%r1, %r2, %0")
8302
8303 (define_insn "pdist_vis"
8304 [(set (match_operand:DI 0 "register_operand" "=e")
8305 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8306 (match_operand:V8QI 2 "register_operand" "e")
8307 (match_operand:DI 3 "register_operand" "0")]
8308 UNSPEC_PDIST))]
8309 "TARGET_VIS"
8310 "pdist\t%1, %2, %0"
8311 [(set_attr "type" "fga")
8312 (set_attr "fptype" "double")])
8313
8314 (include "sync.md")