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