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