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