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