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