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