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