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