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