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