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