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