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