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