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