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