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