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