sparc.md (DFA schedulers): Split out...
[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 if (sparc_check_64 (operands[2], insn) <= 0)
5493 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5494 if (which_alternative == 1)
5495 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\";
5496 else
5497 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\";
5498 }"
5499 [(set_attr "type" "multi")
5500 (set_attr "length" "9,8")])
5501
5502 (define_insn "*cmp_mul_set"
5503 [(set (reg:CC 100)
5504 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5505 (match_operand:SI 2 "arith_operand" "rI"))
5506 (const_int 0)))
5507 (set (match_operand:SI 0 "register_operand" "=r")
5508 (mult:SI (match_dup 1) (match_dup 2)))]
5509 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5510 "smulcc\\t%1, %2, %0"
5511 [(set_attr "type" "imul")])
5512
5513 (define_expand "mulsidi3"
5514 [(set (match_operand:DI 0 "register_operand" "")
5515 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5516 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5517 "TARGET_HARD_MUL"
5518 "
5519 {
5520 if (CONSTANT_P (operands[2]))
5521 {
5522 if (TARGET_V8PLUS)
5523 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5524 operands[2]));
5525 else
5526 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5527 operands[2]));
5528 DONE;
5529 }
5530 if (TARGET_V8PLUS)
5531 {
5532 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5533 DONE;
5534 }
5535 }")
5536
5537 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5538 ;; registers can hold 64 bit values in the V8plus environment.
5539 ;; XXX
5540 (define_insn "mulsidi3_v8plus"
5541 [(set (match_operand:DI 0 "register_operand" "=h,r")
5542 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5543 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5544 (clobber (match_scratch:SI 3 "=X,&h"))]
5545 "TARGET_V8PLUS"
5546 "@
5547 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5548 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5549 [(set_attr "type" "multi")
5550 (set_attr "length" "2,3")])
5551
5552 ;; XXX
5553 (define_insn "const_mulsidi3_v8plus"
5554 [(set (match_operand:DI 0 "register_operand" "=h,r")
5555 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5556 (match_operand:SI 2 "small_int" "I,I")))
5557 (clobber (match_scratch:SI 3 "=X,&h"))]
5558 "TARGET_V8PLUS"
5559 "@
5560 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5561 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5562 [(set_attr "type" "multi")
5563 (set_attr "length" "2,3")])
5564
5565 ;; XXX
5566 (define_insn "*mulsidi3_sp32"
5567 [(set (match_operand:DI 0 "register_operand" "=r")
5568 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5569 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5570 "TARGET_HARD_MUL32"
5571 "*
5572 {
5573 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5574 }"
5575 [(set (attr "type")
5576 (if_then_else (eq_attr "isa" "sparclet")
5577 (const_string "imul") (const_string "multi")))
5578 (set (attr "length")
5579 (if_then_else (eq_attr "isa" "sparclet")
5580 (const_int 1) (const_int 2)))])
5581
5582 (define_insn "*mulsidi3_sp64"
5583 [(set (match_operand:DI 0 "register_operand" "=r")
5584 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5585 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5586 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5587 "smul\\t%1, %2, %0"
5588 [(set_attr "type" "imul")])
5589
5590 ;; Extra pattern, because sign_extend of a constant isn't valid.
5591
5592 ;; XXX
5593 (define_insn "const_mulsidi3_sp32"
5594 [(set (match_operand:DI 0 "register_operand" "=r")
5595 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5596 (match_operand:SI 2 "small_int" "I")))]
5597 "TARGET_HARD_MUL32"
5598 "*
5599 {
5600 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5601 }"
5602 [(set (attr "type")
5603 (if_then_else (eq_attr "isa" "sparclet")
5604 (const_string "imul") (const_string "multi")))
5605 (set (attr "length")
5606 (if_then_else (eq_attr "isa" "sparclet")
5607 (const_int 1) (const_int 2)))])
5608
5609 (define_insn "const_mulsidi3_sp64"
5610 [(set (match_operand:DI 0 "register_operand" "=r")
5611 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5612 (match_operand:SI 2 "small_int" "I")))]
5613 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5614 "smul\\t%1, %2, %0"
5615 [(set_attr "type" "imul")])
5616
5617 (define_expand "smulsi3_highpart"
5618 [(set (match_operand:SI 0 "register_operand" "")
5619 (truncate:SI
5620 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5621 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5622 (const_int 32))))]
5623 "TARGET_HARD_MUL && TARGET_ARCH32"
5624 "
5625 {
5626 if (CONSTANT_P (operands[2]))
5627 {
5628 if (TARGET_V8PLUS)
5629 {
5630 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5631 operands[1],
5632 operands[2],
5633 GEN_INT (32)));
5634 DONE;
5635 }
5636 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5637 DONE;
5638 }
5639 if (TARGET_V8PLUS)
5640 {
5641 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5642 operands[2], GEN_INT (32)));
5643 DONE;
5644 }
5645 }")
5646
5647 ;; XXX
5648 (define_insn "smulsi3_highpart_v8plus"
5649 [(set (match_operand:SI 0 "register_operand" "=h,r")
5650 (truncate:SI
5651 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5652 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5653 (match_operand:SI 3 "const_int_operand" "i,i"))))
5654 (clobber (match_scratch:SI 4 "=X,&h"))]
5655 "TARGET_V8PLUS"
5656 "@
5657 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
5658 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
5659 [(set_attr "type" "multi")
5660 (set_attr "length" "2")])
5661
5662 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5663 ;; XXX
5664 (define_insn ""
5665 [(set (match_operand:SI 0 "register_operand" "=h,r")
5666 (subreg:SI
5667 (lshiftrt:DI
5668 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5669 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5670 (match_operand:SI 3 "const_int_operand" "i,i"))
5671 4))
5672 (clobber (match_scratch:SI 4 "=X,&h"))]
5673 "TARGET_V8PLUS"
5674 "@
5675 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5676 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5677 [(set_attr "type" "multi")
5678 (set_attr "length" "2")])
5679
5680 ;; XXX
5681 (define_insn "const_smulsi3_highpart_v8plus"
5682 [(set (match_operand:SI 0 "register_operand" "=h,r")
5683 (truncate:SI
5684 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5685 (match_operand 2 "small_int" "i,i"))
5686 (match_operand:SI 3 "const_int_operand" "i,i"))))
5687 (clobber (match_scratch:SI 4 "=X,&h"))]
5688 "TARGET_V8PLUS"
5689 "@
5690 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5691 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5692 [(set_attr "type" "multi")
5693 (set_attr "length" "2")])
5694
5695 ;; XXX
5696 (define_insn "*smulsi3_highpart_sp32"
5697 [(set (match_operand:SI 0 "register_operand" "=r")
5698 (truncate:SI
5699 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5700 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5701 (const_int 32))))]
5702 "TARGET_HARD_MUL32"
5703 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5704 [(set_attr "type" "multi")
5705 (set_attr "length" "2")])
5706
5707 ;; XXX
5708 (define_insn "const_smulsi3_highpart"
5709 [(set (match_operand:SI 0 "register_operand" "=r")
5710 (truncate:SI
5711 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5712 (match_operand:SI 2 "register_operand" "r"))
5713 (const_int 32))))]
5714 "TARGET_HARD_MUL32"
5715 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5716 [(set_attr "type" "multi")
5717 (set_attr "length" "2")])
5718
5719 (define_expand "umulsidi3"
5720 [(set (match_operand:DI 0 "register_operand" "")
5721 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5722 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5723 "TARGET_HARD_MUL"
5724 "
5725 {
5726 if (CONSTANT_P (operands[2]))
5727 {
5728 if (TARGET_V8PLUS)
5729 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5730 operands[2]));
5731 else
5732 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5733 operands[2]));
5734 DONE;
5735 }
5736 if (TARGET_V8PLUS)
5737 {
5738 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5739 DONE;
5740 }
5741 }")
5742
5743 ;; XXX
5744 (define_insn "umulsidi3_v8plus"
5745 [(set (match_operand:DI 0 "register_operand" "=h,r")
5746 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5747 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5748 (clobber (match_scratch:SI 3 "=X,&h"))]
5749 "TARGET_V8PLUS"
5750 "@
5751 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5752 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5753 [(set_attr "type" "multi")
5754 (set_attr "length" "2,3")])
5755
5756 ;; XXX
5757 (define_insn "*umulsidi3_sp32"
5758 [(set (match_operand:DI 0 "register_operand" "=r")
5759 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5760 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5761 "TARGET_HARD_MUL32"
5762 "*
5763 {
5764 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5765 }"
5766 [(set (attr "type")
5767 (if_then_else (eq_attr "isa" "sparclet")
5768 (const_string "imul") (const_string "multi")))
5769 (set (attr "length")
5770 (if_then_else (eq_attr "isa" "sparclet")
5771 (const_int 1) (const_int 2)))])
5772
5773 (define_insn "*umulsidi3_sp64"
5774 [(set (match_operand:DI 0 "register_operand" "=r")
5775 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5776 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5777 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5778 "umul\\t%1, %2, %0"
5779 [(set_attr "type" "imul")])
5780
5781 ;; Extra pattern, because sign_extend of a constant isn't valid.
5782
5783 ;; XXX
5784 (define_insn "const_umulsidi3_sp32"
5785 [(set (match_operand:DI 0 "register_operand" "=r")
5786 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5787 (match_operand:SI 2 "uns_small_int" "")))]
5788 "TARGET_HARD_MUL32"
5789 "*
5790 {
5791 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5792 }"
5793 [(set (attr "type")
5794 (if_then_else (eq_attr "isa" "sparclet")
5795 (const_string "imul") (const_string "multi")))
5796 (set (attr "length")
5797 (if_then_else (eq_attr "isa" "sparclet")
5798 (const_int 1) (const_int 2)))])
5799
5800 (define_insn "const_umulsidi3_sp64"
5801 [(set (match_operand:DI 0 "register_operand" "=r")
5802 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5803 (match_operand:SI 2 "uns_small_int" "")))]
5804 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5805 "umul\\t%1, %2, %0"
5806 [(set_attr "type" "imul")])
5807
5808 ;; XXX
5809 (define_insn "const_umulsidi3_v8plus"
5810 [(set (match_operand:DI 0 "register_operand" "=h,r")
5811 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5812 (match_operand:SI 2 "uns_small_int" "")))
5813 (clobber (match_scratch:SI 3 "=X,h"))]
5814 "TARGET_V8PLUS"
5815 "@
5816 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5817 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5818 [(set_attr "type" "multi")
5819 (set_attr "length" "2,3")])
5820
5821 (define_expand "umulsi3_highpart"
5822 [(set (match_operand:SI 0 "register_operand" "")
5823 (truncate:SI
5824 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5825 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5826 (const_int 32))))]
5827 "TARGET_HARD_MUL && TARGET_ARCH32"
5828 "
5829 {
5830 if (CONSTANT_P (operands[2]))
5831 {
5832 if (TARGET_V8PLUS)
5833 {
5834 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5835 operands[1],
5836 operands[2],
5837 GEN_INT (32)));
5838 DONE;
5839 }
5840 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5841 DONE;
5842 }
5843 if (TARGET_V8PLUS)
5844 {
5845 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5846 operands[2], GEN_INT (32)));
5847 DONE;
5848 }
5849 }")
5850
5851 ;; XXX
5852 (define_insn "umulsi3_highpart_v8plus"
5853 [(set (match_operand:SI 0 "register_operand" "=h,r")
5854 (truncate:SI
5855 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5856 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5857 (match_operand:SI 3 "const_int_operand" "i,i"))))
5858 (clobber (match_scratch:SI 4 "=X,h"))]
5859 "TARGET_V8PLUS"
5860 "@
5861 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5862 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5863 [(set_attr "type" "multi")
5864 (set_attr "length" "2")])
5865
5866 ;; XXX
5867 (define_insn "const_umulsi3_highpart_v8plus"
5868 [(set (match_operand:SI 0 "register_operand" "=h,r")
5869 (truncate:SI
5870 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5871 (match_operand:SI 2 "uns_small_int" ""))
5872 (match_operand:SI 3 "const_int_operand" "i,i"))))
5873 (clobber (match_scratch:SI 4 "=X,h"))]
5874 "TARGET_V8PLUS"
5875 "@
5876 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5877 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5878 [(set_attr "type" "multi")
5879 (set_attr "length" "2")])
5880
5881 ;; XXX
5882 (define_insn "*umulsi3_highpart_sp32"
5883 [(set (match_operand:SI 0 "register_operand" "=r")
5884 (truncate:SI
5885 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5886 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5887 (const_int 32))))]
5888 "TARGET_HARD_MUL32"
5889 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5890 [(set_attr "type" "multi")
5891 (set_attr "length" "2")])
5892
5893 ;; XXX
5894 (define_insn "const_umulsi3_highpart"
5895 [(set (match_operand:SI 0 "register_operand" "=r")
5896 (truncate:SI
5897 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5898 (match_operand:SI 2 "uns_small_int" ""))
5899 (const_int 32))))]
5900 "TARGET_HARD_MUL32"
5901 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5902 [(set_attr "type" "multi")
5903 (set_attr "length" "2")])
5904
5905 ;; The v8 architecture specifies that there must be 3 instructions between
5906 ;; a y register write and a use of it for correct results.
5907
5908 (define_expand "divsi3"
5909 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5910 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5911 (match_operand:SI 2 "input_operand" "rI,m")))
5912 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5913 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5914 "
5915 {
5916 if (TARGET_ARCH64)
5917 {
5918 operands[3] = gen_reg_rtx(SImode);
5919 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5920 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5921 operands[3]));
5922 DONE;
5923 }
5924 }")
5925
5926 (define_insn "divsi3_sp32"
5927 [(set (match_operand:SI 0 "register_operand" "=r,r")
5928 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5929 (match_operand:SI 2 "input_operand" "rI,m")))
5930 (clobber (match_scratch:SI 3 "=&r,&r"))]
5931 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5932 && TARGET_ARCH32"
5933 "*
5934 {
5935 if (which_alternative == 0)
5936 if (TARGET_V9)
5937 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
5938 else
5939 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5940 else
5941 if (TARGET_V9)
5942 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5943 else
5944 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\";
5945 }"
5946 [(set_attr "type" "multi")
5947 (set (attr "length")
5948 (if_then_else (eq_attr "isa" "v9")
5949 (const_int 4) (const_int 6)))])
5950
5951 (define_insn "divsi3_sp64"
5952 [(set (match_operand:SI 0 "register_operand" "=r")
5953 (div:SI (match_operand:SI 1 "register_operand" "r")
5954 (match_operand:SI 2 "input_operand" "rI")))
5955 (use (match_operand:SI 3 "register_operand" "r"))]
5956 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5957 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
5958 [(set_attr "type" "multi")
5959 (set_attr "length" "2")])
5960
5961 (define_insn "divdi3"
5962 [(set (match_operand:DI 0 "register_operand" "=r")
5963 (div:DI (match_operand:DI 1 "register_operand" "r")
5964 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5965 "TARGET_ARCH64"
5966 "sdivx\\t%1, %2, %0"
5967 [(set_attr "type" "idiv")])
5968
5969 (define_insn "*cmp_sdiv_cc_set"
5970 [(set (reg:CC 100)
5971 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5972 (match_operand:SI 2 "arith_operand" "rI"))
5973 (const_int 0)))
5974 (set (match_operand:SI 0 "register_operand" "=r")
5975 (div:SI (match_dup 1) (match_dup 2)))
5976 (clobber (match_scratch:SI 3 "=&r"))]
5977 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5978 "*
5979 {
5980 if (TARGET_V9)
5981 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5982 else
5983 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5984 }"
5985 [(set_attr "type" "multi")
5986 (set (attr "length")
5987 (if_then_else (eq_attr "isa" "v9")
5988 (const_int 3) (const_int 6)))])
5989
5990 ;; XXX
5991 (define_expand "udivsi3"
5992 [(set (match_operand:SI 0 "register_operand" "")
5993 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5994 (match_operand:SI 2 "input_operand" "")))]
5995 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5996 "")
5997
5998 (define_insn "udivsi3_sp32"
5999 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6000 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6001 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6002 "(TARGET_V8
6003 || TARGET_DEPRECATED_V8_INSNS)
6004 && TARGET_ARCH32"
6005 "*
6006 {
6007 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6008 switch (which_alternative)
6009 {
6010 default:
6011 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6012 case 1:
6013 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6014 case 2:
6015 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6016 }
6017 }"
6018 [(set_attr "type" "multi")
6019 (set_attr "length" "5")])
6020
6021 (define_insn "udivsi3_sp64"
6022 [(set (match_operand:SI 0 "register_operand" "=r")
6023 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6024 (match_operand:SI 2 "input_operand" "rI")))]
6025 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6026 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6027 [(set_attr "type" "multi")
6028 (set_attr "length" "2")])
6029
6030 (define_insn "udivdi3"
6031 [(set (match_operand:DI 0 "register_operand" "=r")
6032 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6033 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6034 "TARGET_ARCH64"
6035 "udivx\\t%1, %2, %0"
6036 [(set_attr "type" "idiv")])
6037
6038 (define_insn "*cmp_udiv_cc_set"
6039 [(set (reg:CC 100)
6040 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6041 (match_operand:SI 2 "arith_operand" "rI"))
6042 (const_int 0)))
6043 (set (match_operand:SI 0 "register_operand" "=r")
6044 (udiv:SI (match_dup 1) (match_dup 2)))]
6045 "TARGET_V8
6046 || TARGET_DEPRECATED_V8_INSNS"
6047 "*
6048 {
6049 if (TARGET_V9)
6050 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6051 else
6052 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6053 }"
6054 [(set_attr "type" "multi")
6055 (set (attr "length")
6056 (if_then_else (eq_attr "isa" "v9")
6057 (const_int 2) (const_int 5)))])
6058
6059 ; sparclet multiply/accumulate insns
6060
6061 (define_insn "*smacsi"
6062 [(set (match_operand:SI 0 "register_operand" "=r")
6063 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6064 (match_operand:SI 2 "arith_operand" "rI"))
6065 (match_operand:SI 3 "register_operand" "0")))]
6066 "TARGET_SPARCLET"
6067 "smac\\t%1, %2, %0"
6068 [(set_attr "type" "imul")])
6069
6070 (define_insn "*smacdi"
6071 [(set (match_operand:DI 0 "register_operand" "=r")
6072 (plus:DI (mult:DI (sign_extend:DI
6073 (match_operand:SI 1 "register_operand" "%r"))
6074 (sign_extend:DI
6075 (match_operand:SI 2 "register_operand" "r")))
6076 (match_operand:DI 3 "register_operand" "0")))]
6077 "TARGET_SPARCLET"
6078 "smacd\\t%1, %2, %L0"
6079 [(set_attr "type" "imul")])
6080
6081 (define_insn "*umacdi"
6082 [(set (match_operand:DI 0 "register_operand" "=r")
6083 (plus:DI (mult:DI (zero_extend:DI
6084 (match_operand:SI 1 "register_operand" "%r"))
6085 (zero_extend:DI
6086 (match_operand:SI 2 "register_operand" "r")))
6087 (match_operand:DI 3 "register_operand" "0")))]
6088 "TARGET_SPARCLET"
6089 "umacd\\t%1, %2, %L0"
6090 [(set_attr "type" "imul")])
6091 \f
6092 ;;- Boolean instructions
6093 ;; We define DImode `and' so with DImode `not' we can get
6094 ;; DImode `andn'. Other combinations are possible.
6095
6096 (define_expand "anddi3"
6097 [(set (match_operand:DI 0 "register_operand" "")
6098 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6099 (match_operand:DI 2 "arith_double_operand" "")))]
6100 ""
6101 "")
6102
6103 (define_insn "*anddi3_sp32"
6104 [(set (match_operand:DI 0 "register_operand" "=r,b")
6105 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6106 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6107 "! TARGET_ARCH64"
6108 "@
6109 #
6110 fand\\t%1, %2, %0"
6111 [(set_attr "type" "*,fp")
6112 (set_attr "length" "2,*")
6113 (set_attr "fptype" "double")])
6114
6115 (define_insn "*anddi3_sp64"
6116 [(set (match_operand:DI 0 "register_operand" "=r,b")
6117 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6118 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6119 "TARGET_ARCH64"
6120 "@
6121 and\\t%1, %2, %0
6122 fand\\t%1, %2, %0"
6123 [(set_attr "type" "*,fp")
6124 (set_attr "fptype" "double")])
6125
6126 (define_insn "andsi3"
6127 [(set (match_operand:SI 0 "register_operand" "=r,d")
6128 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6129 (match_operand:SI 2 "arith_operand" "rI,d")))]
6130 ""
6131 "@
6132 and\\t%1, %2, %0
6133 fands\\t%1, %2, %0"
6134 [(set_attr "type" "*,fp")])
6135
6136 (define_split
6137 [(set (match_operand:SI 0 "register_operand" "")
6138 (and:SI (match_operand:SI 1 "register_operand" "")
6139 (match_operand:SI 2 "" "")))
6140 (clobber (match_operand:SI 3 "register_operand" ""))]
6141 "GET_CODE (operands[2]) == CONST_INT
6142 && !SMALL_INT32 (operands[2])
6143 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6144 [(set (match_dup 3) (match_dup 4))
6145 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6146 "
6147 {
6148 operands[4] = GEN_INT (~INTVAL (operands[2]));
6149 }")
6150
6151 ;; Split DImode logical operations requiring two instructions.
6152 (define_split
6153 [(set (match_operand:DI 0 "register_operand" "")
6154 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6155 [(match_operand:DI 2 "register_operand" "")
6156 (match_operand:DI 3 "arith_double_operand" "")]))]
6157 "! TARGET_ARCH64
6158 && reload_completed
6159 && ((GET_CODE (operands[0]) == REG
6160 && REGNO (operands[0]) < 32)
6161 || (GET_CODE (operands[0]) == SUBREG
6162 && GET_CODE (SUBREG_REG (operands[0])) == REG
6163 && REGNO (SUBREG_REG (operands[0])) < 32))"
6164 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6165 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6166 "
6167 {
6168 operands[4] = gen_highpart (SImode, operands[0]);
6169 operands[5] = gen_lowpart (SImode, operands[0]);
6170 operands[6] = gen_highpart (SImode, operands[2]);
6171 operands[7] = gen_lowpart (SImode, operands[2]);
6172 #if HOST_BITS_PER_WIDE_INT == 32
6173 if (GET_CODE (operands[3]) == CONST_INT)
6174 {
6175 if (INTVAL (operands[3]) < 0)
6176 operands[8] = constm1_rtx;
6177 else
6178 operands[8] = const0_rtx;
6179 }
6180 else
6181 #endif
6182 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6183 operands[9] = gen_lowpart (SImode, operands[3]);
6184 }")
6185
6186 (define_insn "*and_not_di_sp32"
6187 [(set (match_operand:DI 0 "register_operand" "=r,b")
6188 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6189 (match_operand:DI 2 "register_operand" "r,b")))]
6190 "! TARGET_ARCH64"
6191 "@
6192 #
6193 fandnot1\\t%1, %2, %0"
6194 [(set_attr "type" "*,fp")
6195 (set_attr "length" "2,*")
6196 (set_attr "fptype" "double")])
6197
6198 (define_split
6199 [(set (match_operand:DI 0 "register_operand" "")
6200 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6201 (match_operand:DI 2 "register_operand" "")))]
6202 "! TARGET_ARCH64
6203 && reload_completed
6204 && ((GET_CODE (operands[0]) == REG
6205 && REGNO (operands[0]) < 32)
6206 || (GET_CODE (operands[0]) == SUBREG
6207 && GET_CODE (SUBREG_REG (operands[0])) == REG
6208 && REGNO (SUBREG_REG (operands[0])) < 32))"
6209 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6210 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6211 "operands[3] = gen_highpart (SImode, operands[0]);
6212 operands[4] = gen_highpart (SImode, operands[1]);
6213 operands[5] = gen_highpart (SImode, operands[2]);
6214 operands[6] = gen_lowpart (SImode, operands[0]);
6215 operands[7] = gen_lowpart (SImode, operands[1]);
6216 operands[8] = gen_lowpart (SImode, operands[2]);")
6217
6218 (define_insn "*and_not_di_sp64"
6219 [(set (match_operand:DI 0 "register_operand" "=r,b")
6220 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6221 (match_operand:DI 2 "register_operand" "r,b")))]
6222 "TARGET_ARCH64"
6223 "@
6224 andn\\t%2, %1, %0
6225 fandnot1\\t%1, %2, %0"
6226 [(set_attr "type" "*,fp")
6227 (set_attr "fptype" "double")])
6228
6229 (define_insn "*and_not_si"
6230 [(set (match_operand:SI 0 "register_operand" "=r,d")
6231 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6232 (match_operand:SI 2 "register_operand" "r,d")))]
6233 ""
6234 "@
6235 andn\\t%2, %1, %0
6236 fandnot1s\\t%1, %2, %0"
6237 [(set_attr "type" "*,fp")])
6238
6239 (define_expand "iordi3"
6240 [(set (match_operand:DI 0 "register_operand" "")
6241 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6242 (match_operand:DI 2 "arith_double_operand" "")))]
6243 ""
6244 "")
6245
6246 (define_insn "*iordi3_sp32"
6247 [(set (match_operand:DI 0 "register_operand" "=r,b")
6248 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6249 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6250 "! TARGET_ARCH64"
6251 "@
6252 #
6253 for\\t%1, %2, %0"
6254 [(set_attr "type" "*,fp")
6255 (set_attr "length" "2,*")
6256 (set_attr "fptype" "double")])
6257
6258 (define_insn "*iordi3_sp64"
6259 [(set (match_operand:DI 0 "register_operand" "=r,b")
6260 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6261 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6262 "TARGET_ARCH64"
6263 "@
6264 or\\t%1, %2, %0
6265 for\\t%1, %2, %0"
6266 [(set_attr "type" "*,fp")
6267 (set_attr "fptype" "double")])
6268
6269 (define_insn "iorsi3"
6270 [(set (match_operand:SI 0 "register_operand" "=r,d")
6271 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6272 (match_operand:SI 2 "arith_operand" "rI,d")))]
6273 ""
6274 "@
6275 or\\t%1, %2, %0
6276 fors\\t%1, %2, %0"
6277 [(set_attr "type" "*,fp")])
6278
6279 (define_split
6280 [(set (match_operand:SI 0 "register_operand" "")
6281 (ior:SI (match_operand:SI 1 "register_operand" "")
6282 (match_operand:SI 2 "" "")))
6283 (clobber (match_operand:SI 3 "register_operand" ""))]
6284 "GET_CODE (operands[2]) == CONST_INT
6285 && !SMALL_INT32 (operands[2])
6286 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6287 [(set (match_dup 3) (match_dup 4))
6288 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6289 "
6290 {
6291 operands[4] = GEN_INT (~INTVAL (operands[2]));
6292 }")
6293
6294 (define_insn "*or_not_di_sp32"
6295 [(set (match_operand:DI 0 "register_operand" "=r,b")
6296 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6297 (match_operand:DI 2 "register_operand" "r,b")))]
6298 "! TARGET_ARCH64"
6299 "@
6300 #
6301 fornot1\\t%1, %2, %0"
6302 [(set_attr "type" "*,fp")
6303 (set_attr "length" "2,*")
6304 (set_attr "fptype" "double")])
6305
6306 (define_split
6307 [(set (match_operand:DI 0 "register_operand" "")
6308 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6309 (match_operand:DI 2 "register_operand" "")))]
6310 "! TARGET_ARCH64
6311 && reload_completed
6312 && ((GET_CODE (operands[0]) == REG
6313 && REGNO (operands[0]) < 32)
6314 || (GET_CODE (operands[0]) == SUBREG
6315 && GET_CODE (SUBREG_REG (operands[0])) == REG
6316 && REGNO (SUBREG_REG (operands[0])) < 32))"
6317 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6318 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6319 "operands[3] = gen_highpart (SImode, operands[0]);
6320 operands[4] = gen_highpart (SImode, operands[1]);
6321 operands[5] = gen_highpart (SImode, operands[2]);
6322 operands[6] = gen_lowpart (SImode, operands[0]);
6323 operands[7] = gen_lowpart (SImode, operands[1]);
6324 operands[8] = gen_lowpart (SImode, operands[2]);")
6325
6326 (define_insn "*or_not_di_sp64"
6327 [(set (match_operand:DI 0 "register_operand" "=r,b")
6328 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6329 (match_operand:DI 2 "register_operand" "r,b")))]
6330 "TARGET_ARCH64"
6331 "@
6332 orn\\t%2, %1, %0
6333 fornot1\\t%1, %2, %0"
6334 [(set_attr "type" "*,fp")
6335 (set_attr "fptype" "double")])
6336
6337 (define_insn "*or_not_si"
6338 [(set (match_operand:SI 0 "register_operand" "=r,d")
6339 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6340 (match_operand:SI 2 "register_operand" "r,d")))]
6341 ""
6342 "@
6343 orn\\t%2, %1, %0
6344 fornot1s\\t%1, %2, %0"
6345 [(set_attr "type" "*,fp")])
6346
6347 (define_expand "xordi3"
6348 [(set (match_operand:DI 0 "register_operand" "")
6349 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6350 (match_operand:DI 2 "arith_double_operand" "")))]
6351 ""
6352 "")
6353
6354 (define_insn "*xordi3_sp32"
6355 [(set (match_operand:DI 0 "register_operand" "=r,b")
6356 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6357 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6358 "! TARGET_ARCH64"
6359 "@
6360 #
6361 fxor\\t%1, %2, %0"
6362 [(set_attr "type" "*,fp")
6363 (set_attr "length" "2,*")
6364 (set_attr "fptype" "double")])
6365
6366 (define_insn "*xordi3_sp64"
6367 [(set (match_operand:DI 0 "register_operand" "=r,b")
6368 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6369 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6370 "TARGET_ARCH64"
6371 "@
6372 xor\\t%r1, %2, %0
6373 fxor\\t%1, %2, %0"
6374 [(set_attr "type" "*,fp")
6375 (set_attr "fptype" "double")])
6376
6377 (define_insn "*xordi3_sp64_dbl"
6378 [(set (match_operand:DI 0 "register_operand" "=r")
6379 (xor:DI (match_operand:DI 1 "register_operand" "r")
6380 (match_operand:DI 2 "const64_operand" "")))]
6381 "(TARGET_ARCH64
6382 && HOST_BITS_PER_WIDE_INT != 64)"
6383 "xor\\t%1, %2, %0")
6384
6385 (define_insn "xorsi3"
6386 [(set (match_operand:SI 0 "register_operand" "=r,d")
6387 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6388 (match_operand:SI 2 "arith_operand" "rI,d")))]
6389 ""
6390 "@
6391 xor\\t%r1, %2, %0
6392 fxors\\t%1, %2, %0"
6393 [(set_attr "type" "*,fp")])
6394
6395 (define_split
6396 [(set (match_operand:SI 0 "register_operand" "")
6397 (xor:SI (match_operand:SI 1 "register_operand" "")
6398 (match_operand:SI 2 "" "")))
6399 (clobber (match_operand:SI 3 "register_operand" ""))]
6400 "GET_CODE (operands[2]) == CONST_INT
6401 && !SMALL_INT32 (operands[2])
6402 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6403 [(set (match_dup 3) (match_dup 4))
6404 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6405 "
6406 {
6407 operands[4] = GEN_INT (~INTVAL (operands[2]));
6408 }")
6409
6410 (define_split
6411 [(set (match_operand:SI 0 "register_operand" "")
6412 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6413 (match_operand:SI 2 "" ""))))
6414 (clobber (match_operand:SI 3 "register_operand" ""))]
6415 "GET_CODE (operands[2]) == CONST_INT
6416 && !SMALL_INT32 (operands[2])
6417 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6418 [(set (match_dup 3) (match_dup 4))
6419 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6420 "
6421 {
6422 operands[4] = GEN_INT (~INTVAL (operands[2]));
6423 }")
6424
6425 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6426 ;; Combine now canonicalizes to the rightmost expression.
6427 (define_insn "*xor_not_di_sp32"
6428 [(set (match_operand:DI 0 "register_operand" "=r,b")
6429 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6430 (match_operand:DI 2 "register_operand" "r,b"))))]
6431 "! TARGET_ARCH64"
6432 "@
6433 #
6434 fxnor\\t%1, %2, %0"
6435 [(set_attr "type" "*,fp")
6436 (set_attr "length" "2,*")
6437 (set_attr "fptype" "double")])
6438
6439 (define_split
6440 [(set (match_operand:DI 0 "register_operand" "")
6441 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6442 (match_operand:DI 2 "register_operand" ""))))]
6443 "! TARGET_ARCH64
6444 && reload_completed
6445 && ((GET_CODE (operands[0]) == REG
6446 && REGNO (operands[0]) < 32)
6447 || (GET_CODE (operands[0]) == SUBREG
6448 && GET_CODE (SUBREG_REG (operands[0])) == REG
6449 && REGNO (SUBREG_REG (operands[0])) < 32))"
6450 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6451 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6452 "operands[3] = gen_highpart (SImode, operands[0]);
6453 operands[4] = gen_highpart (SImode, operands[1]);
6454 operands[5] = gen_highpart (SImode, operands[2]);
6455 operands[6] = gen_lowpart (SImode, operands[0]);
6456 operands[7] = gen_lowpart (SImode, operands[1]);
6457 operands[8] = gen_lowpart (SImode, operands[2]);")
6458
6459 (define_insn "*xor_not_di_sp64"
6460 [(set (match_operand:DI 0 "register_operand" "=r,b")
6461 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6462 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6463 "TARGET_ARCH64"
6464 "@
6465 xnor\\t%r1, %2, %0
6466 fxnor\\t%1, %2, %0"
6467 [(set_attr "type" "*,fp")
6468 (set_attr "fptype" "double")])
6469
6470 (define_insn "*xor_not_si"
6471 [(set (match_operand:SI 0 "register_operand" "=r,d")
6472 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6473 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6474 ""
6475 "@
6476 xnor\\t%r1, %2, %0
6477 fxnors\\t%1, %2, %0"
6478 [(set_attr "type" "*,fp")])
6479
6480 ;; These correspond to the above in the case where we also (or only)
6481 ;; want to set the condition code.
6482
6483 (define_insn "*cmp_cc_arith_op"
6484 [(set (reg:CC 100)
6485 (compare:CC
6486 (match_operator:SI 2 "cc_arithop"
6487 [(match_operand:SI 0 "arith_operand" "%r")
6488 (match_operand:SI 1 "arith_operand" "rI")])
6489 (const_int 0)))]
6490 ""
6491 "%A2cc\\t%0, %1, %%g0"
6492 [(set_attr "type" "compare")])
6493
6494 (define_insn "*cmp_ccx_arith_op"
6495 [(set (reg:CCX 100)
6496 (compare:CCX
6497 (match_operator:DI 2 "cc_arithop"
6498 [(match_operand:DI 0 "arith_double_operand" "%r")
6499 (match_operand:DI 1 "arith_double_operand" "rHI")])
6500 (const_int 0)))]
6501 "TARGET_ARCH64"
6502 "%A2cc\\t%0, %1, %%g0"
6503 [(set_attr "type" "compare")])
6504
6505 (define_insn "*cmp_cc_arith_op_set"
6506 [(set (reg:CC 100)
6507 (compare:CC
6508 (match_operator:SI 3 "cc_arithop"
6509 [(match_operand:SI 1 "arith_operand" "%r")
6510 (match_operand:SI 2 "arith_operand" "rI")])
6511 (const_int 0)))
6512 (set (match_operand:SI 0 "register_operand" "=r")
6513 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6514 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6515 "%A3cc\\t%1, %2, %0"
6516 [(set_attr "type" "compare")])
6517
6518 (define_insn "*cmp_ccx_arith_op_set"
6519 [(set (reg:CCX 100)
6520 (compare:CCX
6521 (match_operator:DI 3 "cc_arithop"
6522 [(match_operand:DI 1 "arith_double_operand" "%r")
6523 (match_operand:DI 2 "arith_double_operand" "rHI")])
6524 (const_int 0)))
6525 (set (match_operand:DI 0 "register_operand" "=r")
6526 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6527 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6528 "%A3cc\\t%1, %2, %0"
6529 [(set_attr "type" "compare")])
6530
6531 (define_insn "*cmp_cc_xor_not"
6532 [(set (reg:CC 100)
6533 (compare:CC
6534 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6535 (match_operand:SI 1 "arith_operand" "rI")))
6536 (const_int 0)))]
6537 ""
6538 "xnorcc\\t%r0, %1, %%g0"
6539 [(set_attr "type" "compare")])
6540
6541 (define_insn "*cmp_ccx_xor_not"
6542 [(set (reg:CCX 100)
6543 (compare:CCX
6544 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6545 (match_operand:DI 1 "arith_double_operand" "rHI")))
6546 (const_int 0)))]
6547 "TARGET_ARCH64"
6548 "xnorcc\\t%r0, %1, %%g0"
6549 [(set_attr "type" "compare")])
6550
6551 (define_insn "*cmp_cc_xor_not_set"
6552 [(set (reg:CC 100)
6553 (compare:CC
6554 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6555 (match_operand:SI 2 "arith_operand" "rI")))
6556 (const_int 0)))
6557 (set (match_operand:SI 0 "register_operand" "=r")
6558 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6559 ""
6560 "xnorcc\\t%r1, %2, %0"
6561 [(set_attr "type" "compare")])
6562
6563 (define_insn "*cmp_ccx_xor_not_set"
6564 [(set (reg:CCX 100)
6565 (compare:CCX
6566 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6567 (match_operand:DI 2 "arith_double_operand" "rHI")))
6568 (const_int 0)))
6569 (set (match_operand:DI 0 "register_operand" "=r")
6570 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6571 "TARGET_ARCH64"
6572 "xnorcc\\t%r1, %2, %0"
6573 [(set_attr "type" "compare")])
6574
6575 (define_insn "*cmp_cc_arith_op_not"
6576 [(set (reg:CC 100)
6577 (compare:CC
6578 (match_operator:SI 2 "cc_arithopn"
6579 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6580 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6581 (const_int 0)))]
6582 ""
6583 "%B2cc\\t%r1, %0, %%g0"
6584 [(set_attr "type" "compare")])
6585
6586 (define_insn "*cmp_ccx_arith_op_not"
6587 [(set (reg:CCX 100)
6588 (compare:CCX
6589 (match_operator:DI 2 "cc_arithopn"
6590 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6591 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6592 (const_int 0)))]
6593 "TARGET_ARCH64"
6594 "%B2cc\\t%r1, %0, %%g0"
6595 [(set_attr "type" "compare")])
6596
6597 (define_insn "*cmp_cc_arith_op_not_set"
6598 [(set (reg:CC 100)
6599 (compare:CC
6600 (match_operator:SI 3 "cc_arithopn"
6601 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6602 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6603 (const_int 0)))
6604 (set (match_operand:SI 0 "register_operand" "=r")
6605 (match_operator:SI 4 "cc_arithopn"
6606 [(not:SI (match_dup 1)) (match_dup 2)]))]
6607 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6608 "%B3cc\\t%r2, %1, %0"
6609 [(set_attr "type" "compare")])
6610
6611 (define_insn "*cmp_ccx_arith_op_not_set"
6612 [(set (reg:CCX 100)
6613 (compare:CCX
6614 (match_operator:DI 3 "cc_arithopn"
6615 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6616 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6617 (const_int 0)))
6618 (set (match_operand:DI 0 "register_operand" "=r")
6619 (match_operator:DI 4 "cc_arithopn"
6620 [(not:DI (match_dup 1)) (match_dup 2)]))]
6621 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6622 "%B3cc\\t%r2, %1, %0"
6623 [(set_attr "type" "compare")])
6624
6625 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6626 ;; does not know how to make it work for constants.
6627
6628 (define_expand "negdi2"
6629 [(set (match_operand:DI 0 "register_operand" "=r")
6630 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6631 ""
6632 "
6633 {
6634 if (! TARGET_ARCH64)
6635 {
6636 emit_insn (gen_rtx_PARALLEL
6637 (VOIDmode,
6638 gen_rtvec (2,
6639 gen_rtx_SET (VOIDmode, operand0,
6640 gen_rtx_NEG (DImode, operand1)),
6641 gen_rtx_CLOBBER (VOIDmode,
6642 gen_rtx_REG (CCmode,
6643 SPARC_ICC_REG)))));
6644 DONE;
6645 }
6646 }")
6647
6648 (define_insn "*negdi2_sp32"
6649 [(set (match_operand:DI 0 "register_operand" "=r")
6650 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6651 (clobber (reg:CC 100))]
6652 "TARGET_ARCH32"
6653 "#"
6654 [(set_attr "length" "2")])
6655
6656 (define_split
6657 [(set (match_operand:DI 0 "register_operand" "")
6658 (neg:DI (match_operand:DI 1 "register_operand" "")))
6659 (clobber (reg:CC 100))]
6660 "TARGET_ARCH32
6661 && reload_completed"
6662 [(parallel [(set (reg:CC_NOOV 100)
6663 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6664 (const_int 0)))
6665 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6666 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6667 (ltu:SI (reg:CC 100) (const_int 0))))]
6668 "operands[2] = gen_highpart (SImode, operands[0]);
6669 operands[3] = gen_highpart (SImode, operands[1]);
6670 operands[4] = gen_lowpart (SImode, operands[0]);
6671 operands[5] = gen_lowpart (SImode, operands[1]);")
6672
6673 (define_insn "*negdi2_sp64"
6674 [(set (match_operand:DI 0 "register_operand" "=r")
6675 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6676 "TARGET_ARCH64"
6677 "sub\\t%%g0, %1, %0")
6678
6679 (define_insn "negsi2"
6680 [(set (match_operand:SI 0 "register_operand" "=r")
6681 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6682 ""
6683 "sub\\t%%g0, %1, %0")
6684
6685 (define_insn "*cmp_cc_neg"
6686 [(set (reg:CC_NOOV 100)
6687 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6688 (const_int 0)))]
6689 ""
6690 "subcc\\t%%g0, %0, %%g0"
6691 [(set_attr "type" "compare")])
6692
6693 (define_insn "*cmp_ccx_neg"
6694 [(set (reg:CCX_NOOV 100)
6695 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6696 (const_int 0)))]
6697 "TARGET_ARCH64"
6698 "subcc\\t%%g0, %0, %%g0"
6699 [(set_attr "type" "compare")])
6700
6701 (define_insn "*cmp_cc_set_neg"
6702 [(set (reg:CC_NOOV 100)
6703 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6704 (const_int 0)))
6705 (set (match_operand:SI 0 "register_operand" "=r")
6706 (neg:SI (match_dup 1)))]
6707 ""
6708 "subcc\\t%%g0, %1, %0"
6709 [(set_attr "type" "compare")])
6710
6711 (define_insn "*cmp_ccx_set_neg"
6712 [(set (reg:CCX_NOOV 100)
6713 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6714 (const_int 0)))
6715 (set (match_operand:DI 0 "register_operand" "=r")
6716 (neg:DI (match_dup 1)))]
6717 "TARGET_ARCH64"
6718 "subcc\\t%%g0, %1, %0"
6719 [(set_attr "type" "compare")])
6720
6721 ;; We cannot use the "not" pseudo insn because the Sun assembler
6722 ;; does not know how to make it work for constants.
6723 (define_expand "one_cmpldi2"
6724 [(set (match_operand:DI 0 "register_operand" "")
6725 (not:DI (match_operand:DI 1 "register_operand" "")))]
6726 ""
6727 "")
6728
6729 (define_insn "*one_cmpldi2_sp32"
6730 [(set (match_operand:DI 0 "register_operand" "=r,b")
6731 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6732 "! TARGET_ARCH64"
6733 "@
6734 #
6735 fnot1\\t%1, %0"
6736 [(set_attr "type" "*,fp")
6737 (set_attr "length" "2,*")
6738 (set_attr "fptype" "double")])
6739
6740 (define_split
6741 [(set (match_operand:DI 0 "register_operand" "")
6742 (not:DI (match_operand:DI 1 "register_operand" "")))]
6743 "! TARGET_ARCH64
6744 && reload_completed
6745 && ((GET_CODE (operands[0]) == REG
6746 && REGNO (operands[0]) < 32)
6747 || (GET_CODE (operands[0]) == SUBREG
6748 && GET_CODE (SUBREG_REG (operands[0])) == REG
6749 && REGNO (SUBREG_REG (operands[0])) < 32))"
6750 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6751 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6752 "operands[2] = gen_highpart (SImode, operands[0]);
6753 operands[3] = gen_highpart (SImode, operands[1]);
6754 operands[4] = gen_lowpart (SImode, operands[0]);
6755 operands[5] = gen_lowpart (SImode, operands[1]);")
6756
6757 (define_insn "*one_cmpldi2_sp64"
6758 [(set (match_operand:DI 0 "register_operand" "=r,b")
6759 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6760 "TARGET_ARCH64"
6761 "@
6762 xnor\\t%%g0, %1, %0
6763 fnot1\\t%1, %0"
6764 [(set_attr "type" "*,fp")
6765 (set_attr "fptype" "double")])
6766
6767 (define_insn "one_cmplsi2"
6768 [(set (match_operand:SI 0 "register_operand" "=r,d")
6769 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6770 ""
6771 "@
6772 xnor\\t%%g0, %1, %0
6773 fnot1s\\t%1, %0"
6774 [(set_attr "type" "*,fp")])
6775
6776 (define_insn "*cmp_cc_not"
6777 [(set (reg:CC 100)
6778 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6779 (const_int 0)))]
6780 ""
6781 "xnorcc\\t%%g0, %0, %%g0"
6782 [(set_attr "type" "compare")])
6783
6784 (define_insn "*cmp_ccx_not"
6785 [(set (reg:CCX 100)
6786 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6787 (const_int 0)))]
6788 "TARGET_ARCH64"
6789 "xnorcc\\t%%g0, %0, %%g0"
6790 [(set_attr "type" "compare")])
6791
6792 (define_insn "*cmp_cc_set_not"
6793 [(set (reg:CC 100)
6794 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6795 (const_int 0)))
6796 (set (match_operand:SI 0 "register_operand" "=r")
6797 (not:SI (match_dup 1)))]
6798 ""
6799 "xnorcc\\t%%g0, %1, %0"
6800 [(set_attr "type" "compare")])
6801
6802 (define_insn "*cmp_ccx_set_not"
6803 [(set (reg:CCX 100)
6804 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6805 (const_int 0)))
6806 (set (match_operand:DI 0 "register_operand" "=r")
6807 (not:DI (match_dup 1)))]
6808 "TARGET_ARCH64"
6809 "xnorcc\\t%%g0, %1, %0"
6810 [(set_attr "type" "compare")])
6811
6812 (define_insn "*cmp_cc_set"
6813 [(set (match_operand:SI 0 "register_operand" "=r")
6814 (match_operand:SI 1 "register_operand" "r"))
6815 (set (reg:CC 100)
6816 (compare:CC (match_dup 1)
6817 (const_int 0)))]
6818 ""
6819 "orcc\\t%1, 0, %0"
6820 [(set_attr "type" "compare")])
6821
6822 (define_insn "*cmp_ccx_set64"
6823 [(set (match_operand:DI 0 "register_operand" "=r")
6824 (match_operand:DI 1 "register_operand" "r"))
6825 (set (reg:CCX 100)
6826 (compare:CCX (match_dup 1)
6827 (const_int 0)))]
6828 "TARGET_ARCH64"
6829 "orcc\\t%1, 0, %0"
6830 [(set_attr "type" "compare")])
6831 \f
6832 ;; Floating point arithmetic instructions.
6833
6834 (define_expand "addtf3"
6835 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6836 (plus:TF (match_operand:TF 1 "general_operand" "")
6837 (match_operand:TF 2 "general_operand" "")))]
6838 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6839 "emit_tfmode_binop (PLUS, operands); DONE;")
6840
6841 (define_insn "*addtf3_hq"
6842 [(set (match_operand:TF 0 "register_operand" "=e")
6843 (plus:TF (match_operand:TF 1 "register_operand" "e")
6844 (match_operand:TF 2 "register_operand" "e")))]
6845 "TARGET_FPU && TARGET_HARD_QUAD"
6846 "faddq\\t%1, %2, %0"
6847 [(set_attr "type" "fp")])
6848
6849 (define_insn "adddf3"
6850 [(set (match_operand:DF 0 "register_operand" "=e")
6851 (plus:DF (match_operand:DF 1 "register_operand" "e")
6852 (match_operand:DF 2 "register_operand" "e")))]
6853 "TARGET_FPU"
6854 "faddd\\t%1, %2, %0"
6855 [(set_attr "type" "fp")
6856 (set_attr "fptype" "double")])
6857
6858 (define_insn "addsf3"
6859 [(set (match_operand:SF 0 "register_operand" "=f")
6860 (plus:SF (match_operand:SF 1 "register_operand" "f")
6861 (match_operand:SF 2 "register_operand" "f")))]
6862 "TARGET_FPU"
6863 "fadds\\t%1, %2, %0"
6864 [(set_attr "type" "fp")])
6865
6866 (define_expand "subtf3"
6867 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6868 (minus:TF (match_operand:TF 1 "general_operand" "")
6869 (match_operand:TF 2 "general_operand" "")))]
6870 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6871 "emit_tfmode_binop (MINUS, operands); DONE;")
6872
6873 (define_insn "*subtf3_hq"
6874 [(set (match_operand:TF 0 "register_operand" "=e")
6875 (minus:TF (match_operand:TF 1 "register_operand" "e")
6876 (match_operand:TF 2 "register_operand" "e")))]
6877 "TARGET_FPU && TARGET_HARD_QUAD"
6878 "fsubq\\t%1, %2, %0"
6879 [(set_attr "type" "fp")])
6880
6881 (define_insn "subdf3"
6882 [(set (match_operand:DF 0 "register_operand" "=e")
6883 (minus:DF (match_operand:DF 1 "register_operand" "e")
6884 (match_operand:DF 2 "register_operand" "e")))]
6885 "TARGET_FPU"
6886 "fsubd\\t%1, %2, %0"
6887 [(set_attr "type" "fp")
6888 (set_attr "fptype" "double")])
6889
6890 (define_insn "subsf3"
6891 [(set (match_operand:SF 0 "register_operand" "=f")
6892 (minus:SF (match_operand:SF 1 "register_operand" "f")
6893 (match_operand:SF 2 "register_operand" "f")))]
6894 "TARGET_FPU"
6895 "fsubs\\t%1, %2, %0"
6896 [(set_attr "type" "fp")])
6897
6898 (define_expand "multf3"
6899 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6900 (mult:TF (match_operand:TF 1 "general_operand" "")
6901 (match_operand:TF 2 "general_operand" "")))]
6902 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6903 "emit_tfmode_binop (MULT, operands); DONE;")
6904
6905 (define_insn "*multf3_hq"
6906 [(set (match_operand:TF 0 "register_operand" "=e")
6907 (mult:TF (match_operand:TF 1 "register_operand" "e")
6908 (match_operand:TF 2 "register_operand" "e")))]
6909 "TARGET_FPU && TARGET_HARD_QUAD"
6910 "fmulq\\t%1, %2, %0"
6911 [(set_attr "type" "fpmul")])
6912
6913 (define_insn "muldf3"
6914 [(set (match_operand:DF 0 "register_operand" "=e")
6915 (mult:DF (match_operand:DF 1 "register_operand" "e")
6916 (match_operand:DF 2 "register_operand" "e")))]
6917 "TARGET_FPU"
6918 "fmuld\\t%1, %2, %0"
6919 [(set_attr "type" "fpmul")
6920 (set_attr "fptype" "double")])
6921
6922 (define_insn "mulsf3"
6923 [(set (match_operand:SF 0 "register_operand" "=f")
6924 (mult:SF (match_operand:SF 1 "register_operand" "f")
6925 (match_operand:SF 2 "register_operand" "f")))]
6926 "TARGET_FPU"
6927 "fmuls\\t%1, %2, %0"
6928 [(set_attr "type" "fpmul")])
6929
6930 (define_insn "*muldf3_extend"
6931 [(set (match_operand:DF 0 "register_operand" "=e")
6932 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6933 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6934 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6935 "fsmuld\\t%1, %2, %0"
6936 [(set_attr "type" "fpmul")
6937 (set_attr "fptype" "double")])
6938
6939 (define_insn "*multf3_extend"
6940 [(set (match_operand:TF 0 "register_operand" "=e")
6941 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6942 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6943 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6944 "fdmulq\\t%1, %2, %0"
6945 [(set_attr "type" "fpmul")])
6946
6947 (define_expand "divtf3"
6948 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6949 (div:TF (match_operand:TF 1 "general_operand" "")
6950 (match_operand:TF 2 "general_operand" "")))]
6951 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6952 "emit_tfmode_binop (DIV, operands); DONE;")
6953
6954 ;; don't have timing for quad-prec. divide.
6955 (define_insn "*divtf3_hq"
6956 [(set (match_operand:TF 0 "register_operand" "=e")
6957 (div:TF (match_operand:TF 1 "register_operand" "e")
6958 (match_operand:TF 2 "register_operand" "e")))]
6959 "TARGET_FPU && TARGET_HARD_QUAD"
6960 "fdivq\\t%1, %2, %0"
6961 [(set_attr "type" "fpdivd")])
6962
6963 (define_insn "divdf3"
6964 [(set (match_operand:DF 0 "register_operand" "=e")
6965 (div:DF (match_operand:DF 1 "register_operand" "e")
6966 (match_operand:DF 2 "register_operand" "e")))]
6967 "TARGET_FPU"
6968 "fdivd\\t%1, %2, %0"
6969 [(set_attr "type" "fpdivd")
6970 (set_attr "fptype" "double")])
6971
6972 (define_insn "divsf3"
6973 [(set (match_operand:SF 0 "register_operand" "=f")
6974 (div:SF (match_operand:SF 1 "register_operand" "f")
6975 (match_operand:SF 2 "register_operand" "f")))]
6976 "TARGET_FPU"
6977 "fdivs\\t%1, %2, %0"
6978 [(set_attr "type" "fpdivs")])
6979
6980 (define_expand "negtf2"
6981 [(set (match_operand:TF 0 "register_operand" "=e,e")
6982 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6983 "TARGET_FPU"
6984 "")
6985
6986 (define_insn "*negtf2_notv9"
6987 [(set (match_operand:TF 0 "register_operand" "=e,e")
6988 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6989 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6990 "TARGET_FPU
6991 && ! TARGET_V9"
6992 "@
6993 fnegs\\t%0, %0
6994 #"
6995 [(set_attr "type" "fpmove,*")
6996 (set_attr "length" "*,2")])
6997
6998 (define_split
6999 [(set (match_operand:TF 0 "register_operand" "")
7000 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7001 "TARGET_FPU
7002 && ! TARGET_V9
7003 && reload_completed
7004 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7005 [(set (match_dup 2) (neg:SF (match_dup 3)))
7006 (set (match_dup 4) (match_dup 5))
7007 (set (match_dup 6) (match_dup 7))]
7008 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7009 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7010 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7011 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7012 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7013 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7014
7015 (define_insn "*negtf2_v9"
7016 [(set (match_operand:TF 0 "register_operand" "=e,e")
7017 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7018 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7019 "TARGET_FPU && TARGET_V9"
7020 "@
7021 fnegd\\t%0, %0
7022 #"
7023 [(set_attr "type" "fpmove,*")
7024 (set_attr "length" "*,2")
7025 (set_attr "fptype" "double")])
7026
7027 (define_split
7028 [(set (match_operand:TF 0 "register_operand" "")
7029 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7030 "TARGET_FPU
7031 && TARGET_V9
7032 && reload_completed
7033 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7034 [(set (match_dup 2) (neg:DF (match_dup 3)))
7035 (set (match_dup 4) (match_dup 5))]
7036 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7037 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7038 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7039 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7040
7041 (define_expand "negdf2"
7042 [(set (match_operand:DF 0 "register_operand" "")
7043 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7044 "TARGET_FPU"
7045 "")
7046
7047 (define_insn "*negdf2_notv9"
7048 [(set (match_operand:DF 0 "register_operand" "=e,e")
7049 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7050 "TARGET_FPU && ! TARGET_V9"
7051 "@
7052 fnegs\\t%0, %0
7053 #"
7054 [(set_attr "type" "fpmove,*")
7055 (set_attr "length" "*,2")])
7056
7057 (define_split
7058 [(set (match_operand:DF 0 "register_operand" "")
7059 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7060 "TARGET_FPU
7061 && ! TARGET_V9
7062 && reload_completed
7063 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7064 [(set (match_dup 2) (neg:SF (match_dup 3)))
7065 (set (match_dup 4) (match_dup 5))]
7066 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7067 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7068 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7069 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7070
7071 (define_insn "*negdf2_v9"
7072 [(set (match_operand:DF 0 "register_operand" "=e")
7073 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7074 "TARGET_FPU && TARGET_V9"
7075 "fnegd\\t%1, %0"
7076 [(set_attr "type" "fpmove")
7077 (set_attr "fptype" "double")])
7078
7079 (define_insn "negsf2"
7080 [(set (match_operand:SF 0 "register_operand" "=f")
7081 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7082 "TARGET_FPU"
7083 "fnegs\\t%1, %0"
7084 [(set_attr "type" "fpmove")])
7085
7086 (define_expand "abstf2"
7087 [(set (match_operand:TF 0 "register_operand" "")
7088 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7089 "TARGET_FPU"
7090 "")
7091
7092 (define_insn "*abstf2_notv9"
7093 [(set (match_operand:TF 0 "register_operand" "=e,e")
7094 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7095 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7096 "TARGET_FPU && ! TARGET_V9"
7097 "@
7098 fabss\\t%0, %0
7099 #"
7100 [(set_attr "type" "fpmove,*")
7101 (set_attr "length" "*,2")])
7102
7103 (define_split
7104 [(set (match_operand:TF 0 "register_operand" "")
7105 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7106 "TARGET_FPU
7107 && ! TARGET_V9
7108 && reload_completed
7109 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7110 [(set (match_dup 2) (abs:SF (match_dup 3)))
7111 (set (match_dup 4) (match_dup 5))
7112 (set (match_dup 6) (match_dup 7))]
7113 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7114 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7115 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7116 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7117 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7118 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7119
7120 (define_insn "*abstf2_hq_v9"
7121 [(set (match_operand:TF 0 "register_operand" "=e,e")
7122 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7123 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7124 "@
7125 fabsd\\t%0, %0
7126 fabsq\\t%1, %0"
7127 [(set_attr "type" "fpmove")
7128 (set_attr "fptype" "double,*")])
7129
7130 (define_insn "*abstf2_v9"
7131 [(set (match_operand:TF 0 "register_operand" "=e,e")
7132 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7133 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7134 "@
7135 fabsd\\t%0, %0
7136 #"
7137 [(set_attr "type" "fpmove,*")
7138 (set_attr "length" "*,2")
7139 (set_attr "fptype" "double,*")])
7140
7141 (define_split
7142 [(set (match_operand:TF 0 "register_operand" "")
7143 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7144 "TARGET_FPU
7145 && TARGET_V9
7146 && reload_completed
7147 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7148 [(set (match_dup 2) (abs:DF (match_dup 3)))
7149 (set (match_dup 4) (match_dup 5))]
7150 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7151 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7152 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7153 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7154
7155 (define_expand "absdf2"
7156 [(set (match_operand:DF 0 "register_operand" "")
7157 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7158 "TARGET_FPU"
7159 "")
7160
7161 (define_insn "*absdf2_notv9"
7162 [(set (match_operand:DF 0 "register_operand" "=e,e")
7163 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7164 "TARGET_FPU && ! TARGET_V9"
7165 "@
7166 fabss\\t%0, %0
7167 #"
7168 [(set_attr "type" "fpmove,*")
7169 (set_attr "length" "*,2")])
7170
7171 (define_split
7172 [(set (match_operand:DF 0 "register_operand" "")
7173 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7174 "TARGET_FPU
7175 && ! TARGET_V9
7176 && reload_completed
7177 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7178 [(set (match_dup 2) (abs:SF (match_dup 3)))
7179 (set (match_dup 4) (match_dup 5))]
7180 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7181 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7182 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7183 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7184
7185 (define_insn "*absdf2_v9"
7186 [(set (match_operand:DF 0 "register_operand" "=e")
7187 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7188 "TARGET_FPU && TARGET_V9"
7189 "fabsd\\t%1, %0"
7190 [(set_attr "type" "fpmove")
7191 (set_attr "fptype" "double")])
7192
7193 (define_insn "abssf2"
7194 [(set (match_operand:SF 0 "register_operand" "=f")
7195 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7196 "TARGET_FPU"
7197 "fabss\\t%1, %0"
7198 [(set_attr "type" "fpmove")])
7199
7200 (define_expand "sqrttf2"
7201 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7202 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
7203 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7204 "emit_tfmode_unop (SQRT, operands); DONE;")
7205
7206 (define_insn "*sqrttf2_hq"
7207 [(set (match_operand:TF 0 "register_operand" "=e")
7208 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7209 "TARGET_FPU && TARGET_HARD_QUAD"
7210 "fsqrtq\\t%1, %0"
7211 [(set_attr "type" "fpsqrtd")])
7212
7213 (define_insn "sqrtdf2"
7214 [(set (match_operand:DF 0 "register_operand" "=e")
7215 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7216 "TARGET_FPU"
7217 "fsqrtd\\t%1, %0"
7218 [(set_attr "type" "fpsqrtd")
7219 (set_attr "fptype" "double")])
7220
7221 (define_insn "sqrtsf2"
7222 [(set (match_operand:SF 0 "register_operand" "=f")
7223 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7224 "TARGET_FPU"
7225 "fsqrts\\t%1, %0"
7226 [(set_attr "type" "fpsqrts")])
7227 \f
7228 ;;- arithmetic shift instructions
7229
7230 (define_insn "ashlsi3"
7231 [(set (match_operand:SI 0 "register_operand" "=r")
7232 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7233 (match_operand:SI 2 "arith_operand" "rI")))]
7234 ""
7235 "*
7236 {
7237 if (GET_CODE (operands[2]) == CONST_INT
7238 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7239 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7240
7241 return \"sll\\t%1, %2, %0\";
7242 }"
7243 [(set_attr "type" "shift")])
7244
7245 ;; We special case multiplication by two, as add can be done
7246 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7247 (define_insn "*ashlsi3_const1"
7248 [(set (match_operand:SI 0 "register_operand" "=r")
7249 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7250 (const_int 1)))]
7251 ""
7252 "add\\t%1, %1, %0")
7253
7254 (define_expand "ashldi3"
7255 [(set (match_operand:DI 0 "register_operand" "=r")
7256 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7257 (match_operand:SI 2 "arith_operand" "rI")))]
7258 "TARGET_ARCH64 || TARGET_V8PLUS"
7259 "
7260 {
7261 if (! TARGET_ARCH64)
7262 {
7263 if (GET_CODE (operands[2]) == CONST_INT)
7264 FAIL;
7265 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7266 DONE;
7267 }
7268 }")
7269
7270 ;; We special case multiplication by two, as add can be done
7271 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7272 (define_insn "*ashldi3_const1"
7273 [(set (match_operand:DI 0 "register_operand" "=r")
7274 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7275 (const_int 1)))]
7276 "TARGET_ARCH64"
7277 "add\\t%1, %1, %0")
7278
7279 (define_insn "*ashldi3_sp64"
7280 [(set (match_operand:DI 0 "register_operand" "=r")
7281 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7282 (match_operand:SI 2 "arith_operand" "rI")))]
7283 "TARGET_ARCH64"
7284 "*
7285 {
7286 if (GET_CODE (operands[2]) == CONST_INT
7287 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7288 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7289
7290 return \"sllx\\t%1, %2, %0\";
7291 }"
7292 [(set_attr "type" "shift")])
7293
7294 ;; XXX UGH!
7295 (define_insn "ashldi3_v8plus"
7296 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7297 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7298 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7299 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7300 "TARGET_V8PLUS"
7301 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7302 [(set_attr "type" "multi")
7303 (set_attr "length" "5,5,6")])
7304
7305 ;; Optimize (1LL<<x)-1
7306 ;; XXX this also needs to be fixed to handle equal subregs
7307 ;; XXX first before we could re-enable it.
7308 ;(define_insn ""
7309 ; [(set (match_operand:DI 0 "register_operand" "=h")
7310 ; (plus:DI (ashift:DI (const_int 1)
7311 ; (match_operand:SI 1 "arith_operand" "rI"))
7312 ; (const_int -1)))]
7313 ; "0 && TARGET_V8PLUS"
7314 ; "*
7315 ;{
7316 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7317 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7318 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7319 ;}"
7320 ; [(set_attr "type" "multi")
7321 ; (set_attr "length" "4")])
7322
7323 (define_insn "*cmp_cc_ashift_1"
7324 [(set (reg:CC_NOOV 100)
7325 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7326 (const_int 1))
7327 (const_int 0)))]
7328 ""
7329 "addcc\\t%0, %0, %%g0"
7330 [(set_attr "type" "compare")])
7331
7332 (define_insn "*cmp_cc_set_ashift_1"
7333 [(set (reg:CC_NOOV 100)
7334 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7335 (const_int 1))
7336 (const_int 0)))
7337 (set (match_operand:SI 0 "register_operand" "=r")
7338 (ashift:SI (match_dup 1) (const_int 1)))]
7339 ""
7340 "addcc\\t%1, %1, %0"
7341 [(set_attr "type" "compare")])
7342
7343 (define_insn "ashrsi3"
7344 [(set (match_operand:SI 0 "register_operand" "=r")
7345 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7346 (match_operand:SI 2 "arith_operand" "rI")))]
7347 ""
7348 "*
7349 {
7350 if (GET_CODE (operands[2]) == CONST_INT
7351 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7352 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7353
7354 return \"sra\\t%1, %2, %0\";
7355 }"
7356 [(set_attr "type" "shift")])
7357
7358 (define_insn "*ashrsi3_extend"
7359 [(set (match_operand:DI 0 "register_operand" "=r")
7360 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7361 (match_operand:SI 2 "arith_operand" "r"))))]
7362 "TARGET_ARCH64"
7363 "sra\\t%1, %2, %0"
7364 [(set_attr "type" "shift")])
7365
7366 ;; This handles the case as above, but with constant shift instead of
7367 ;; register. Combiner "simplifies" it for us a little bit though.
7368 (define_insn "*ashrsi3_extend2"
7369 [(set (match_operand:DI 0 "register_operand" "=r")
7370 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7371 (const_int 32))
7372 (match_operand:SI 2 "small_int_or_double" "n")))]
7373 "TARGET_ARCH64
7374 && ((GET_CODE (operands[2]) == CONST_INT
7375 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7376 || (GET_CODE (operands[2]) == CONST_DOUBLE
7377 && !CONST_DOUBLE_HIGH (operands[2])
7378 && CONST_DOUBLE_LOW (operands[2]) >= 32
7379 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7380 "*
7381 {
7382 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7383
7384 return \"sra\\t%1, %2, %0\";
7385 }"
7386 [(set_attr "type" "shift")])
7387
7388 (define_expand "ashrdi3"
7389 [(set (match_operand:DI 0 "register_operand" "=r")
7390 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7391 (match_operand:SI 2 "arith_operand" "rI")))]
7392 "TARGET_ARCH64 || TARGET_V8PLUS"
7393 "
7394 {
7395 if (! TARGET_ARCH64)
7396 {
7397 if (GET_CODE (operands[2]) == CONST_INT)
7398 FAIL; /* prefer generic code in this case */
7399 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7400 DONE;
7401 }
7402 }")
7403
7404 (define_insn ""
7405 [(set (match_operand:DI 0 "register_operand" "=r")
7406 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7407 (match_operand:SI 2 "arith_operand" "rI")))]
7408 "TARGET_ARCH64"
7409 "*
7410 {
7411 if (GET_CODE (operands[2]) == CONST_INT
7412 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7413 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7414
7415 return \"srax\\t%1, %2, %0\";
7416 }"
7417 [(set_attr "type" "shift")])
7418
7419 ;; XXX
7420 (define_insn "ashrdi3_v8plus"
7421 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7422 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7423 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7424 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7425 "TARGET_V8PLUS"
7426 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7427 [(set_attr "type" "multi")
7428 (set_attr "length" "5,5,6")])
7429
7430 (define_insn "lshrsi3"
7431 [(set (match_operand:SI 0 "register_operand" "=r")
7432 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7433 (match_operand:SI 2 "arith_operand" "rI")))]
7434 ""
7435 "*
7436 {
7437 if (GET_CODE (operands[2]) == CONST_INT
7438 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7439 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7440
7441 return \"srl\\t%1, %2, %0\";
7442 }"
7443 [(set_attr "type" "shift")])
7444
7445 ;; This handles the case where
7446 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7447 ;; but combiner "simplifies" it for us.
7448 (define_insn "*lshrsi3_extend"
7449 [(set (match_operand:DI 0 "register_operand" "=r")
7450 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7451 (match_operand:SI 2 "arith_operand" "r")) 0)
7452 (match_operand 3 "" "")))]
7453 "TARGET_ARCH64
7454 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7455 && CONST_DOUBLE_HIGH (operands[3]) == 0
7456 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7457 || (HOST_BITS_PER_WIDE_INT >= 64
7458 && GET_CODE (operands[3]) == CONST_INT
7459 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7460 "srl\\t%1, %2, %0"
7461 [(set_attr "type" "shift")])
7462
7463 ;; This handles the case where
7464 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7465 ;; but combiner "simplifies" it for us.
7466 (define_insn "*lshrsi3_extend2"
7467 [(set (match_operand:DI 0 "register_operand" "=r")
7468 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7469 (match_operand 2 "small_int_or_double" "n")
7470 (const_int 32)))]
7471 "TARGET_ARCH64
7472 && ((GET_CODE (operands[2]) == CONST_INT
7473 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7474 || (GET_CODE (operands[2]) == CONST_DOUBLE
7475 && CONST_DOUBLE_HIGH (operands[2]) == 0
7476 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7477 "*
7478 {
7479 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7480
7481 return \"srl\\t%1, %2, %0\";
7482 }"
7483 [(set_attr "type" "shift")])
7484
7485 (define_expand "lshrdi3"
7486 [(set (match_operand:DI 0 "register_operand" "=r")
7487 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7488 (match_operand:SI 2 "arith_operand" "rI")))]
7489 "TARGET_ARCH64 || TARGET_V8PLUS"
7490 "
7491 {
7492 if (! TARGET_ARCH64)
7493 {
7494 if (GET_CODE (operands[2]) == CONST_INT)
7495 FAIL;
7496 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7497 DONE;
7498 }
7499 }")
7500
7501 (define_insn ""
7502 [(set (match_operand:DI 0 "register_operand" "=r")
7503 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7504 (match_operand:SI 2 "arith_operand" "rI")))]
7505 "TARGET_ARCH64"
7506 "*
7507 {
7508 if (GET_CODE (operands[2]) == CONST_INT
7509 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7510 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7511
7512 return \"srlx\\t%1, %2, %0\";
7513 }"
7514 [(set_attr "type" "shift")])
7515
7516 ;; XXX
7517 (define_insn "lshrdi3_v8plus"
7518 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7519 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7520 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7521 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7522 "TARGET_V8PLUS"
7523 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7524 [(set_attr "type" "multi")
7525 (set_attr "length" "5,5,6")])
7526
7527 (define_insn ""
7528 [(set (match_operand:SI 0 "register_operand" "=r")
7529 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7530 (const_int 32)) 4)
7531 (match_operand:SI 2 "small_int_or_double" "n")))]
7532 "TARGET_ARCH64
7533 && ((GET_CODE (operands[2]) == CONST_INT
7534 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7535 || (GET_CODE (operands[2]) == CONST_DOUBLE
7536 && !CONST_DOUBLE_HIGH (operands[2])
7537 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7538 "*
7539 {
7540 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7541
7542 return \"srax\\t%1, %2, %0\";
7543 }"
7544 [(set_attr "type" "shift")])
7545
7546 (define_insn ""
7547 [(set (match_operand:SI 0 "register_operand" "=r")
7548 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7549 (const_int 32)) 4)
7550 (match_operand:SI 2 "small_int_or_double" "n")))]
7551 "TARGET_ARCH64
7552 && ((GET_CODE (operands[2]) == CONST_INT
7553 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7554 || (GET_CODE (operands[2]) == CONST_DOUBLE
7555 && !CONST_DOUBLE_HIGH (operands[2])
7556 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7557 "*
7558 {
7559 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7560
7561 return \"srlx\\t%1, %2, %0\";
7562 }"
7563 [(set_attr "type" "shift")])
7564
7565 (define_insn ""
7566 [(set (match_operand:SI 0 "register_operand" "=r")
7567 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7568 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7569 (match_operand:SI 3 "small_int_or_double" "n")))]
7570 "TARGET_ARCH64
7571 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7572 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7573 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7574 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7575 "*
7576 {
7577 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7578
7579 return \"srax\\t%1, %2, %0\";
7580 }"
7581 [(set_attr "type" "shift")])
7582
7583 (define_insn ""
7584 [(set (match_operand:SI 0 "register_operand" "=r")
7585 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7586 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7587 (match_operand:SI 3 "small_int_or_double" "n")))]
7588 "TARGET_ARCH64
7589 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7590 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7591 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7592 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7593 "*
7594 {
7595 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7596
7597 return \"srlx\\t%1, %2, %0\";
7598 }"
7599 [(set_attr "type" "shift")])
7600 \f
7601 ;; Unconditional and other jump instructions
7602 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7603 ;; following insn is never executed. This saves us a nop. Dbx does not
7604 ;; handle such branches though, so we only use them when optimizing.
7605 (define_insn "jump"
7606 [(set (pc) (label_ref (match_operand 0 "" "")))]
7607 ""
7608 "*
7609 {
7610 /* TurboSparc is reported to have problems with
7611 with
7612 foo: b,a foo
7613 i.e. an empty loop with the annul bit set. The workaround is to use
7614 foo: b foo; nop
7615 instead. */
7616
7617 if (! TARGET_V9 && flag_delayed_branch
7618 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7619 == INSN_ADDRESSES (INSN_UID (insn))))
7620 return \"b\\t%l0%#\";
7621 else
7622 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7623 }"
7624 [(set_attr "type" "uncond_branch")])
7625
7626 (define_expand "tablejump"
7627 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7628 (use (label_ref (match_operand 1 "" "")))])]
7629 ""
7630 "
7631 {
7632 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7633 abort ();
7634
7635 /* In pic mode, our address differences are against the base of the
7636 table. Add that base value back in; CSE ought to be able to combine
7637 the two address loads. */
7638 if (flag_pic)
7639 {
7640 rtx tmp, tmp2;
7641 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7642 tmp2 = operands[0];
7643 if (CASE_VECTOR_MODE != Pmode)
7644 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7645 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7646 operands[0] = memory_address (Pmode, tmp);
7647 }
7648 }")
7649
7650 (define_insn "*tablejump_sp32"
7651 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7652 (use (label_ref (match_operand 1 "" "")))]
7653 "! TARGET_ARCH64"
7654 "jmp\\t%a0%#"
7655 [(set_attr "type" "uncond_branch")])
7656
7657 (define_insn "*tablejump_sp64"
7658 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7659 (use (label_ref (match_operand 1 "" "")))]
7660 "TARGET_ARCH64"
7661 "jmp\\t%a0%#"
7662 [(set_attr "type" "uncond_branch")])
7663
7664 ;; This pattern recognizes the "instruction" that appears in
7665 ;; a function call that wants a structure value,
7666 ;; to inform the called function if compiled with Sun CC.
7667 ;(define_insn "*unimp_insn"
7668 ; [(match_operand:SI 0 "immediate_operand" "")]
7669 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7670 ; "unimp\\t%0"
7671 ; [(set_attr "type" "marker")])
7672
7673 ;;- jump to subroutine
7674 (define_expand "call"
7675 ;; Note that this expression is not used for generating RTL.
7676 ;; All the RTL is generated explicitly below.
7677 [(call (match_operand 0 "call_operand" "")
7678 (match_operand 3 "" "i"))]
7679 ;; operands[2] is next_arg_register
7680 ;; operands[3] is struct_value_size_rtx.
7681 ""
7682 "
7683 {
7684 rtx fn_rtx, nregs_rtx;
7685
7686 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7687 abort ();
7688
7689 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7690 {
7691 /* This is really a PIC sequence. We want to represent
7692 it as a funny jump so its delay slots can be filled.
7693
7694 ??? But if this really *is* a CALL, will not it clobber the
7695 call-clobbered registers? We lose this if it is a JUMP_INSN.
7696 Why cannot we have delay slots filled if it were a CALL? */
7697
7698 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7699 emit_jump_insn
7700 (gen_rtx_PARALLEL
7701 (VOIDmode,
7702 gen_rtvec (3,
7703 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7704 operands[3],
7705 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7706 else
7707 emit_jump_insn
7708 (gen_rtx_PARALLEL
7709 (VOIDmode,
7710 gen_rtvec (2,
7711 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7712 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7713 goto finish_call;
7714 }
7715
7716 fn_rtx = operands[0];
7717
7718 /* Count the number of parameter registers being used by this call.
7719 if that argument is NULL, it means we are using them all, which
7720 means 6 on the sparc. */
7721 #if 0
7722 if (operands[2])
7723 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7724 else
7725 nregs_rtx = GEN_INT (6);
7726 #else
7727 nregs_rtx = const0_rtx;
7728 #endif
7729
7730 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7731 emit_call_insn
7732 (gen_rtx_PARALLEL
7733 (VOIDmode,
7734 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7735 operands[3],
7736 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7737 else
7738 emit_call_insn
7739 (gen_rtx_PARALLEL
7740 (VOIDmode,
7741 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7742 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7743
7744 finish_call:
7745 #if 0
7746 /* If this call wants a structure value,
7747 emit an unimp insn to let the called function know about this. */
7748 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7749 {
7750 rtx insn = emit_insn (operands[3]);
7751 SCHED_GROUP_P (insn) = 1;
7752 }
7753 #endif
7754
7755 DONE;
7756 }")
7757
7758 ;; We can't use the same pattern for these two insns, because then registers
7759 ;; in the address may not be properly reloaded.
7760
7761 (define_insn "*call_address_sp32"
7762 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7763 (match_operand 1 "" ""))
7764 (clobber (reg:SI 15))]
7765 ;;- Do not use operand 1 for most machines.
7766 "! TARGET_ARCH64"
7767 "call\\t%a0, %1%#"
7768 [(set_attr "type" "call")])
7769
7770 (define_insn "*call_symbolic_sp32"
7771 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7772 (match_operand 1 "" ""))
7773 (clobber (reg:SI 15))]
7774 ;;- Do not use operand 1 for most machines.
7775 "! TARGET_ARCH64"
7776 "call\\t%a0, %1%#"
7777 [(set_attr "type" "call")])
7778
7779 (define_insn "*call_address_sp64"
7780 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7781 (match_operand 1 "" ""))
7782 (clobber (reg:DI 15))]
7783 ;;- Do not use operand 1 for most machines.
7784 "TARGET_ARCH64"
7785 "call\\t%a0, %1%#"
7786 [(set_attr "type" "call")])
7787
7788 (define_insn "*call_symbolic_sp64"
7789 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7790 (match_operand 1 "" ""))
7791 (clobber (reg:DI 15))]
7792 ;;- Do not use operand 1 for most machines.
7793 "TARGET_ARCH64"
7794 "call\\t%a0, %1%#"
7795 [(set_attr "type" "call")])
7796
7797 ;; This is a call that wants a structure value.
7798 ;; There is no such critter for v9 (??? we may need one anyway).
7799 (define_insn "*call_address_struct_value_sp32"
7800 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7801 (match_operand 1 "" ""))
7802 (match_operand 2 "immediate_operand" "")
7803 (clobber (reg:SI 15))]
7804 ;;- Do not use operand 1 for most machines.
7805 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7806 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7807 [(set_attr "type" "call_no_delay_slot")
7808 (set_attr "length" "3")])
7809
7810 ;; This is a call that wants a structure value.
7811 ;; There is no such critter for v9 (??? we may need one anyway).
7812 (define_insn "*call_symbolic_struct_value_sp32"
7813 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7814 (match_operand 1 "" ""))
7815 (match_operand 2 "immediate_operand" "")
7816 (clobber (reg:SI 15))]
7817 ;;- Do not use operand 1 for most machines.
7818 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7819 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7820 [(set_attr "type" "call_no_delay_slot")
7821 (set_attr "length" "3")])
7822
7823 ;; This is a call that may want a structure value. This is used for
7824 ;; untyped_calls.
7825 (define_insn "*call_address_untyped_struct_value_sp32"
7826 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7827 (match_operand 1 "" ""))
7828 (match_operand 2 "immediate_operand" "")
7829 (clobber (reg:SI 15))]
7830 ;;- Do not use operand 1 for most machines.
7831 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7832 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7833 [(set_attr "type" "call_no_delay_slot")
7834 (set_attr "length" "3")])
7835
7836 ;; This is a call that wants a structure value.
7837 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7838 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7839 (match_operand 1 "" ""))
7840 (match_operand 2 "immediate_operand" "")
7841 (clobber (reg:SI 15))]
7842 ;;- Do not use operand 1 for most machines.
7843 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7844 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7845 [(set_attr "type" "call_no_delay_slot")
7846 (set_attr "length" "3")])
7847
7848 (define_expand "call_value"
7849 ;; Note that this expression is not used for generating RTL.
7850 ;; All the RTL is generated explicitly below.
7851 [(set (match_operand 0 "register_operand" "=rf")
7852 (call (match_operand 1 "" "")
7853 (match_operand 4 "" "")))]
7854 ;; operand 2 is stack_size_rtx
7855 ;; operand 3 is next_arg_register
7856 ""
7857 "
7858 {
7859 rtx fn_rtx, nregs_rtx;
7860 rtvec vec;
7861
7862 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7863 abort ();
7864
7865 fn_rtx = operands[1];
7866
7867 #if 0
7868 if (operands[3])
7869 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7870 else
7871 nregs_rtx = GEN_INT (6);
7872 #else
7873 nregs_rtx = const0_rtx;
7874 #endif
7875
7876 vec = gen_rtvec (2,
7877 gen_rtx_SET (VOIDmode, operands[0],
7878 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7879 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7880
7881 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7882
7883 DONE;
7884 }")
7885
7886 (define_insn "*call_value_address_sp32"
7887 [(set (match_operand 0 "" "=rf")
7888 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7889 (match_operand 2 "" "")))
7890 (clobber (reg:SI 15))]
7891 ;;- Do not use operand 2 for most machines.
7892 "! TARGET_ARCH64"
7893 "call\\t%a1, %2%#"
7894 [(set_attr "type" "call")])
7895
7896 (define_insn "*call_value_symbolic_sp32"
7897 [(set (match_operand 0 "" "=rf")
7898 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7899 (match_operand 2 "" "")))
7900 (clobber (reg:SI 15))]
7901 ;;- Do not use operand 2 for most machines.
7902 "! TARGET_ARCH64"
7903 "call\\t%a1, %2%#"
7904 [(set_attr "type" "call")])
7905
7906 (define_insn "*call_value_address_sp64"
7907 [(set (match_operand 0 "" "")
7908 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7909 (match_operand 2 "" "")))
7910 (clobber (reg:DI 15))]
7911 ;;- Do not use operand 2 for most machines.
7912 "TARGET_ARCH64"
7913 "call\\t%a1, %2%#"
7914 [(set_attr "type" "call")])
7915
7916 (define_insn "*call_value_symbolic_sp64"
7917 [(set (match_operand 0 "" "")
7918 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7919 (match_operand 2 "" "")))
7920 (clobber (reg:DI 15))]
7921 ;;- Do not use operand 2 for most machines.
7922 "TARGET_ARCH64"
7923 "call\\t%a1, %2%#"
7924 [(set_attr "type" "call")])
7925
7926 (define_expand "untyped_call"
7927 [(parallel [(call (match_operand 0 "" "")
7928 (const_int 0))
7929 (match_operand 1 "" "")
7930 (match_operand 2 "" "")])]
7931 ""
7932 "
7933 {
7934 int i;
7935
7936 /* Pass constm1 to indicate that it may expect a structure value, but
7937 we don't know what size it is. */
7938 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7939
7940 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7941 {
7942 rtx set = XVECEXP (operands[2], 0, i);
7943 emit_move_insn (SET_DEST (set), SET_SRC (set));
7944 }
7945
7946 /* The optimizer does not know that the call sets the function value
7947 registers we stored in the result block. We avoid problems by
7948 claiming that all hard registers are used and clobbered at this
7949 point. */
7950 emit_insn (gen_blockage ());
7951
7952 DONE;
7953 }")
7954
7955 ;;- tail calls
7956 (define_expand "sibcall"
7957 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7958 (return)])]
7959 ""
7960 "")
7961
7962 (define_insn "*sibcall_symbolic_sp32"
7963 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7964 (match_operand 1 "" ""))
7965 (return)]
7966 "! TARGET_ARCH64"
7967 "* return output_sibcall(insn, operands[0]);"
7968 [(set_attr "type" "sibcall")])
7969
7970 (define_insn "*sibcall_symbolic_sp64"
7971 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7972 (match_operand 1 "" ""))
7973 (return)]
7974 "TARGET_ARCH64"
7975 "* return output_sibcall(insn, operands[0]);"
7976 [(set_attr "type" "sibcall")])
7977
7978 (define_expand "sibcall_value"
7979 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7980 (call (match_operand 1 "" "") (const_int 0)))
7981 (return)])]
7982 ""
7983 "")
7984
7985 (define_insn "*sibcall_value_symbolic_sp32"
7986 [(set (match_operand 0 "" "=rf")
7987 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7988 (match_operand 2 "" "")))
7989 (return)]
7990 "! TARGET_ARCH64"
7991 "* return output_sibcall(insn, operands[1]);"
7992 [(set_attr "type" "sibcall")])
7993
7994 (define_insn "*sibcall_value_symbolic_sp64"
7995 [(set (match_operand 0 "" "")
7996 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7997 (match_operand 2 "" "")))
7998 (return)]
7999 "TARGET_ARCH64"
8000 "* return output_sibcall(insn, operands[1]);"
8001 [(set_attr "type" "sibcall")])
8002
8003 (define_expand "sibcall_epilogue"
8004 [(const_int 0)]
8005 ""
8006 "DONE;")
8007
8008 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8009 ;; all of memory. This blocks insns from being moved across this point.
8010
8011 (define_insn "blockage"
8012 [(unspec_volatile [(const_int 0)] 0)]
8013 ""
8014 ""
8015 [(set_attr "length" "0")])
8016
8017 ;; Prepare to return any type including a structure value.
8018
8019 (define_expand "untyped_return"
8020 [(match_operand:BLK 0 "memory_operand" "")
8021 (match_operand 1 "" "")]
8022 ""
8023 "
8024 {
8025 rtx valreg1 = gen_rtx_REG (DImode, 24);
8026 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8027 rtx result = operands[0];
8028
8029 if (! TARGET_ARCH64)
8030 {
8031 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8032 ? 15 : 31));
8033 rtx value = gen_reg_rtx (SImode);
8034
8035 /* Fetch the instruction where we will return to and see if it's an unimp
8036 instruction (the most significant 10 bits will be zero). If so,
8037 update the return address to skip the unimp instruction. */
8038 emit_move_insn (value,
8039 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8040 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8041 emit_insn (gen_update_return (rtnreg, value));
8042 }
8043
8044 /* Reload the function value registers. */
8045 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8046 emit_move_insn (valreg2,
8047 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8048
8049 /* Put USE insns before the return. */
8050 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8051 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8052
8053 /* Construct the return. */
8054 expand_null_return ();
8055
8056 DONE;
8057 }")
8058
8059 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8060 ;; and parts of the compiler don't want to believe that the add is needed.
8061
8062 (define_insn "update_return"
8063 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8064 (match_operand:SI 1 "register_operand" "r")] 1)]
8065 "! TARGET_ARCH64"
8066 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8067 [(set_attr "type" "multi")
8068 (set_attr "length" "3")])
8069 \f
8070 (define_insn "nop"
8071 [(const_int 0)]
8072 ""
8073 "nop")
8074
8075 (define_expand "indirect_jump"
8076 [(set (pc) (match_operand 0 "address_operand" "p"))]
8077 ""
8078 "")
8079
8080 (define_insn "*branch_sp32"
8081 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8082 "! TARGET_ARCH64"
8083 "jmp\\t%a0%#"
8084 [(set_attr "type" "uncond_branch")])
8085
8086 (define_insn "*branch_sp64"
8087 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8088 "TARGET_ARCH64"
8089 "jmp\\t%a0%#"
8090 [(set_attr "type" "uncond_branch")])
8091
8092 ;; ??? Doesn't work with -mflat.
8093 (define_expand "nonlocal_goto"
8094 [(match_operand:SI 0 "general_operand" "")
8095 (match_operand:SI 1 "general_operand" "")
8096 (match_operand:SI 2 "general_operand" "")
8097 (match_operand:SI 3 "" "")]
8098 ""
8099 "
8100 {
8101 #if 0
8102 rtx chain = operands[0];
8103 #endif
8104 rtx lab = operands[1];
8105 rtx stack = operands[2];
8106 rtx fp = operands[3];
8107 rtx labreg;
8108
8109 /* Trap instruction to flush all the register windows. */
8110 emit_insn (gen_flush_register_windows ());
8111
8112 /* Load the fp value for the containing fn into %fp. This is needed
8113 because STACK refers to %fp. Note that virtual register instantiation
8114 fails if the virtual %fp isn't set from a register. */
8115 if (GET_CODE (fp) != REG)
8116 fp = force_reg (Pmode, fp);
8117 emit_move_insn (virtual_stack_vars_rtx, fp);
8118
8119 /* Find the containing function's current nonlocal goto handler,
8120 which will do any cleanups and then jump to the label. */
8121 labreg = gen_rtx_REG (Pmode, 8);
8122 emit_move_insn (labreg, lab);
8123
8124 /* Restore %fp from stack pointer value for containing function.
8125 The restore insn that follows will move this to %sp,
8126 and reload the appropriate value into %fp. */
8127 emit_move_insn (hard_frame_pointer_rtx, stack);
8128
8129 /* USE of frame_pointer_rtx added for consistency; not clear if
8130 really needed. */
8131 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8132 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8133
8134 #if 0
8135 /* Return, restoring reg window and jumping to goto handler. */
8136 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8137 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8138 {
8139 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8140 static_chain_rtx,
8141 chain));
8142 emit_barrier ();
8143 DONE;
8144 }
8145 /* Put in the static chain register the nonlocal label address. */
8146 emit_move_insn (static_chain_rtx, chain);
8147 #endif
8148
8149 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8150 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8151 emit_barrier ();
8152 DONE;
8153 }")
8154
8155 ;; Special trap insn to flush register windows.
8156 (define_insn "flush_register_windows"
8157 [(unspec_volatile [(const_int 0)] 1)]
8158 ""
8159 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8160 [(set_attr "type" "misc")])
8161
8162 (define_insn "goto_handler_and_restore"
8163 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8164 "GET_MODE (operands[0]) == Pmode"
8165 "jmp\\t%0+0\\n\\trestore"
8166 [(set_attr "type" "multi")
8167 (set_attr "length" "2")])
8168
8169 ;;(define_insn "goto_handler_and_restore_v9"
8170 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8171 ;; (match_operand:SI 1 "register_operand" "=r,r")
8172 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8173 ;; "TARGET_V9 && ! TARGET_ARCH64"
8174 ;; "@
8175 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8176 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8177 ;; [(set_attr "type" "multi")
8178 ;; (set_attr "length" "2,3")])
8179 ;;
8180 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8181 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8182 ;; (match_operand:DI 1 "register_operand" "=r,r")
8183 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8184 ;; "TARGET_V9 && TARGET_ARCH64"
8185 ;; "@
8186 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8187 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8188 ;; [(set_attr "type" "multi")
8189 ;; (set_attr "length" "2,3")])
8190
8191 ;; For __builtin_setjmp we need to flush register windows iff the function
8192 ;; calls alloca as well, because otherwise the register window might be
8193 ;; saved after %sp adjustement and thus setjmp would crash
8194 (define_expand "builtin_setjmp_setup"
8195 [(match_operand 0 "register_operand" "r")]
8196 ""
8197 "
8198 {
8199 emit_insn (gen_do_builtin_setjmp_setup ());
8200 DONE;
8201 }")
8202
8203 (define_insn "do_builtin_setjmp_setup"
8204 [(unspec_volatile [(const_int 0)] 5)]
8205 ""
8206 "*
8207 {
8208 if (! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT)
8209 return \"#\";
8210 fputs (\"\tflushw\n\", asm_out_file);
8211 if (flag_pic)
8212 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
8213 TARGET_ARCH64 ? 'x' : 'w',
8214 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
8215 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
8216 TARGET_ARCH64 ? 'x' : 'w',
8217 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
8218 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
8219 TARGET_ARCH64 ? 'x' : 'w',
8220 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
8221 return \"\";
8222 }"
8223 [(set_attr "type" "misc")
8224 (set (attr "length") (if_then_else (eq_attr "pic" "true")
8225 (const_int 4)
8226 (const_int 3)))])
8227
8228 (define_split
8229 [(unspec_volatile [(const_int 0)] 5)]
8230 "! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT"
8231 [(const_int 0)]
8232 "
8233 {
8234 if (current_function_calls_alloca)
8235 emit_insn (gen_flush_register_windows ());
8236 DONE;
8237 }")
8238
8239 ;; Pattern for use after a setjmp to store FP and the return register
8240 ;; into the stack area.
8241
8242 (define_expand "setjmp"
8243 [(const_int 0)]
8244 ""
8245 "
8246 {
8247 if (TARGET_ARCH64)
8248 emit_insn (gen_setjmp_64 ());
8249 else
8250 emit_insn (gen_setjmp_32 ());
8251 DONE;
8252 }")
8253
8254 (define_expand "setjmp_32"
8255 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8256 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8257 ""
8258 "
8259 { operands[0] = frame_pointer_rtx; }")
8260
8261 (define_expand "setjmp_64"
8262 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8263 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8264 ""
8265 "
8266 { operands[0] = frame_pointer_rtx; }")
8267
8268 ;; Special pattern for the FLUSH instruction.
8269
8270 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8271 ; of the define_insn otherwise missing a mode. We make "flush", aka
8272 ; gen_flush, the default one since sparc_initialize_trampoline uses
8273 ; it on SImode mem values.
8274
8275 (define_insn "flush"
8276 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8277 ""
8278 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8279 [(set_attr "type" "misc")])
8280
8281 (define_insn "flushdi"
8282 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8283 ""
8284 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8285 [(set_attr "type" "misc")])
8286
8287 \f
8288 ;; find first set.
8289
8290 ;; The scan instruction searches from the most significant bit while ffs
8291 ;; searches from the least significant bit. The bit index and treatment of
8292 ;; zero also differ. It takes at least 7 instructions to get the proper
8293 ;; result. Here is an obvious 8 instruction sequence.
8294
8295 ;; XXX
8296 (define_insn "ffssi2"
8297 [(set (match_operand:SI 0 "register_operand" "=&r")
8298 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8299 (clobber (match_scratch:SI 2 "=&r"))]
8300 "TARGET_SPARCLITE || TARGET_SPARCLET"
8301 "*
8302 {
8303 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\";
8304 }"
8305 [(set_attr "type" "multi")
8306 (set_attr "length" "8")])
8307
8308 ;; ??? This should be a define expand, so that the extra instruction have
8309 ;; a chance of being optimized away.
8310
8311 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8312 ;; does, but no one uses that and we don't have a switch for it.
8313 ;
8314 ;(define_insn "ffsdi2"
8315 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8316 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8317 ; (clobber (match_scratch:DI 2 "=&r"))]
8318 ; "TARGET_ARCH64"
8319 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8320 ; [(set_attr "type" "multi")
8321 ; (set_attr "length" "4")])
8322
8323
8324 \f
8325 ;; Peepholes go at the end.
8326
8327 ;; Optimize consecutive loads or stores into ldd and std when possible.
8328 ;; The conditions in which we do this are very restricted and are
8329 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8330
8331 (define_peephole2
8332 [(set (match_operand:SI 0 "memory_operand" "")
8333 (const_int 0))
8334 (set (match_operand:SI 1 "memory_operand" "")
8335 (const_int 0))]
8336 "TARGET_V9
8337 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8338 [(set (match_dup 0)
8339 (const_int 0))]
8340 "operands[0] = change_address (operands[0], DImode, NULL);")
8341
8342 (define_peephole2
8343 [(set (match_operand:SI 0 "memory_operand" "")
8344 (const_int 0))
8345 (set (match_operand:SI 1 "memory_operand" "")
8346 (const_int 0))]
8347 "TARGET_V9
8348 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8349 [(set (match_dup 1)
8350 (const_int 0))]
8351 "operands[1] = change_address (operands[1], DImode, NULL);")
8352
8353 (define_peephole2
8354 [(set (match_operand:SI 0 "register_operand" "")
8355 (match_operand:SI 1 "memory_operand" ""))
8356 (set (match_operand:SI 2 "register_operand" "")
8357 (match_operand:SI 3 "memory_operand" ""))]
8358 "registers_ok_for_ldd_peep (operands[0], operands[2])
8359 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8360 [(set (match_dup 0)
8361 (match_dup 1))]
8362 "operands[1] = change_address (operands[1], DImode, NULL);
8363 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8364
8365 (define_peephole2
8366 [(set (match_operand:SI 0 "memory_operand" "")
8367 (match_operand:SI 1 "register_operand" ""))
8368 (set (match_operand:SI 2 "memory_operand" "")
8369 (match_operand:SI 3 "register_operand" ""))]
8370 "registers_ok_for_ldd_peep (operands[1], operands[3])
8371 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8372 [(set (match_dup 0)
8373 (match_dup 1))]
8374 "operands[0] = change_address (operands[0], DImode, NULL);
8375 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8376
8377 (define_peephole2
8378 [(set (match_operand:SF 0 "register_operand" "")
8379 (match_operand:SF 1 "memory_operand" ""))
8380 (set (match_operand:SF 2 "register_operand" "")
8381 (match_operand:SF 3 "memory_operand" ""))]
8382 "registers_ok_for_ldd_peep (operands[0], operands[2])
8383 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8384 [(set (match_dup 0)
8385 (match_dup 1))]
8386 "operands[1] = change_address (operands[1], DFmode, NULL);
8387 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8388
8389 (define_peephole2
8390 [(set (match_operand:SF 0 "memory_operand" "")
8391 (match_operand:SF 1 "register_operand" ""))
8392 (set (match_operand:SF 2 "memory_operand" "")
8393 (match_operand:SF 3 "register_operand" ""))]
8394 "registers_ok_for_ldd_peep (operands[1], operands[3])
8395 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8396 [(set (match_dup 0)
8397 (match_dup 1))]
8398 "operands[0] = change_address (operands[0], DFmode, NULL);
8399 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8400
8401 (define_peephole2
8402 [(set (match_operand:SI 0 "register_operand" "")
8403 (match_operand:SI 1 "memory_operand" ""))
8404 (set (match_operand:SI 2 "register_operand" "")
8405 (match_operand:SI 3 "memory_operand" ""))]
8406 "registers_ok_for_ldd_peep (operands[2], operands[0])
8407 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8408 [(set (match_dup 2)
8409 (match_dup 3))]
8410 "operands[3] = change_address (operands[3], DImode, NULL);
8411 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8412
8413 (define_peephole2
8414 [(set (match_operand:SI 0 "memory_operand" "")
8415 (match_operand:SI 1 "register_operand" ""))
8416 (set (match_operand:SI 2 "memory_operand" "")
8417 (match_operand:SI 3 "register_operand" ""))]
8418 "registers_ok_for_ldd_peep (operands[3], operands[1])
8419 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8420 [(set (match_dup 2)
8421 (match_dup 3))]
8422 "operands[2] = change_address (operands[2], DImode, NULL);
8423 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8424 ")
8425
8426 (define_peephole2
8427 [(set (match_operand:SF 0 "register_operand" "")
8428 (match_operand:SF 1 "memory_operand" ""))
8429 (set (match_operand:SF 2 "register_operand" "")
8430 (match_operand:SF 3 "memory_operand" ""))]
8431 "registers_ok_for_ldd_peep (operands[2], operands[0])
8432 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8433 [(set (match_dup 2)
8434 (match_dup 3))]
8435 "operands[3] = change_address (operands[3], DFmode, NULL);
8436 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8437
8438 (define_peephole2
8439 [(set (match_operand:SF 0 "memory_operand" "")
8440 (match_operand:SF 1 "register_operand" ""))
8441 (set (match_operand:SF 2 "memory_operand" "")
8442 (match_operand:SF 3 "register_operand" ""))]
8443 "registers_ok_for_ldd_peep (operands[3], operands[1])
8444 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8445 [(set (match_dup 2)
8446 (match_dup 3))]
8447 "operands[2] = change_address (operands[2], DFmode, NULL);
8448 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8449
8450 ;; Optimize the case of following a reg-reg move with a test
8451 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8452 ;; This can result from a float to fix conversion.
8453
8454 (define_peephole2
8455 [(set (match_operand:SI 0 "register_operand" "")
8456 (match_operand:SI 1 "register_operand" ""))
8457 (set (reg:CC 100)
8458 (compare:CC (match_operand:SI 2 "register_operand" "")
8459 (const_int 0)))]
8460 "(rtx_equal_p (operands[2], operands[0])
8461 || rtx_equal_p (operands[2], operands[1]))
8462 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8463 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8464 [(parallel [(set (match_dup 0) (match_dup 1))
8465 (set (reg:CC 100)
8466 (compare:CC (match_dup 1) (const_int 0)))])]
8467 "")
8468
8469 (define_peephole2
8470 [(set (match_operand:DI 0 "register_operand" "")
8471 (match_operand:DI 1 "register_operand" ""))
8472 (set (reg:CCX 100)
8473 (compare:CCX (match_operand:DI 2 "register_operand" "")
8474 (const_int 0)))]
8475 "TARGET_ARCH64
8476 && (rtx_equal_p (operands[2], operands[0])
8477 || rtx_equal_p (operands[2], operands[1]))
8478 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8479 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8480 [(parallel [(set (match_dup 0) (match_dup 1))
8481 (set (reg:CCX 100)
8482 (compare:CCX (match_dup 1) (const_int 0)))])]
8483 "")
8484
8485 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8486 ;; who then immediately calls final_scan_insn.
8487
8488 (define_insn "*return_qi"
8489 [(set (match_operand:QI 0 "restore_operand" "")
8490 (match_operand:QI 1 "arith_operand" "rI"))
8491 (return)]
8492 "sparc_emitting_epilogue"
8493 "*
8494 {
8495 if (! TARGET_ARCH64 && current_function_returns_struct)
8496 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8497 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8498 || IN_OR_GLOBAL_P (operands[1])))
8499 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8500 else
8501 return \"ret\\n\\trestore %%g0, %1, %Y0\";
8502 }"
8503 [(set_attr "type" "multi")
8504 (set_attr "length" "2")])
8505
8506 (define_insn "*return_hi"
8507 [(set (match_operand:HI 0 "restore_operand" "")
8508 (match_operand:HI 1 "arith_operand" "rI"))
8509 (return)]
8510 "sparc_emitting_epilogue"
8511 "*
8512 {
8513 if (! TARGET_ARCH64 && current_function_returns_struct)
8514 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8515 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8516 || IN_OR_GLOBAL_P (operands[1])))
8517 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8518 else
8519 return \"ret\;restore %%g0, %1, %Y0\";
8520 }"
8521 [(set_attr "type" "multi")
8522 (set_attr "length" "2")])
8523
8524 (define_insn "*return_si"
8525 [(set (match_operand:SI 0 "restore_operand" "")
8526 (match_operand:SI 1 "arith_operand" "rI"))
8527 (return)]
8528 "sparc_emitting_epilogue"
8529 "*
8530 {
8531 if (! TARGET_ARCH64 && current_function_returns_struct)
8532 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8533 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8534 || IN_OR_GLOBAL_P (operands[1])))
8535 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8536 else
8537 return \"ret\;restore %%g0, %1, %Y0\";
8538 }"
8539 [(set_attr "type" "multi")
8540 (set_attr "length" "2")])
8541
8542 (define_insn "*return_sf_no_fpu"
8543 [(set (match_operand:SF 0 "restore_operand" "=r")
8544 (match_operand:SF 1 "register_operand" "r"))
8545 (return)]
8546 "sparc_emitting_epilogue"
8547 "*
8548 {
8549 if (! TARGET_ARCH64 && current_function_returns_struct)
8550 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8551 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8552 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8553 else
8554 return \"ret\;restore %%g0, %1, %Y0\";
8555 }"
8556 [(set_attr "type" "multi")
8557 (set_attr "length" "2")])
8558
8559 (define_insn "*return_df_no_fpu"
8560 [(set (match_operand:DF 0 "restore_operand" "=r")
8561 (match_operand:DF 1 "register_operand" "r"))
8562 (return)]
8563 "sparc_emitting_epilogue && TARGET_ARCH64"
8564 "*
8565 {
8566 if (IN_OR_GLOBAL_P (operands[1]))
8567 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8568 else
8569 return \"ret\;restore %%g0, %1, %Y0\";
8570 }"
8571 [(set_attr "type" "multi")
8572 (set_attr "length" "2")])
8573
8574 (define_insn "*return_addsi"
8575 [(set (match_operand:SI 0 "restore_operand" "")
8576 (plus:SI (match_operand:SI 1 "register_operand" "r")
8577 (match_operand:SI 2 "arith_operand" "rI")))
8578 (return)]
8579 "sparc_emitting_epilogue"
8580 "*
8581 {
8582 if (! TARGET_ARCH64 && current_function_returns_struct)
8583 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
8584 /* If operands are global or in registers, can use return */
8585 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8586 && (GET_CODE (operands[2]) == CONST_INT
8587 || IN_OR_GLOBAL_P (operands[2])))
8588 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
8589 else
8590 return \"ret\;restore %r1, %2, %Y0\";
8591 }"
8592 [(set_attr "type" "multi")
8593 (set_attr "length" "2")])
8594
8595 (define_insn "*return_losum_si"
8596 [(set (match_operand:SI 0 "restore_operand" "")
8597 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8598 (match_operand:SI 2 "immediate_operand" "in")))
8599 (return)]
8600 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8601 "*
8602 {
8603 if (! TARGET_ARCH64 && current_function_returns_struct)
8604 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
8605 /* If operands are global or in registers, can use return */
8606 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8607 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
8608 else
8609 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
8610 }"
8611 [(set_attr "type" "multi")
8612 (set_attr "length" "2")])
8613
8614 (define_insn "*return_di"
8615 [(set (match_operand:DI 0 "restore_operand" "")
8616 (match_operand:DI 1 "arith_double_operand" "rHI"))
8617 (return)]
8618 "sparc_emitting_epilogue && TARGET_ARCH64"
8619 "ret\;restore %%g0, %1, %Y0"
8620 [(set_attr "type" "multi")
8621 (set_attr "length" "2")])
8622
8623 (define_insn "*return_adddi"
8624 [(set (match_operand:DI 0 "restore_operand" "")
8625 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8626 (match_operand:DI 2 "arith_double_operand" "rHI")))
8627 (return)]
8628 "sparc_emitting_epilogue && TARGET_ARCH64"
8629 "ret\;restore %r1, %2, %Y0"
8630 [(set_attr "type" "multi")
8631 (set_attr "length" "2")])
8632
8633 (define_insn "*return_losum_di"
8634 [(set (match_operand:DI 0 "restore_operand" "")
8635 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8636 (match_operand:DI 2 "immediate_operand" "in")))
8637 (return)]
8638 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8639 "ret\;restore %r1, %%lo(%a2), %Y0"
8640 [(set_attr "type" "multi")
8641 (set_attr "length" "2")])
8642
8643 (define_insn "*return_sf"
8644 [(set (reg:SF 32)
8645 (match_operand:SF 0 "register_operand" "f"))
8646 (return)]
8647 "sparc_emitting_epilogue"
8648 "ret\;fmovs\\t%0, %%f0"
8649 [(set_attr "type" "multi")
8650 (set_attr "length" "2")])
8651
8652 ;; Now peepholes to do a call followed by a jump.
8653
8654 (define_peephole
8655 [(parallel [(set (match_operand 0 "" "")
8656 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8657 (match_operand 2 "" "")))
8658 (clobber (reg:SI 15))])
8659 (set (pc) (label_ref (match_operand 3 "" "")))]
8660 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8661 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8662 && sparc_cpu != PROCESSOR_ULTRASPARC
8663 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8664 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8665
8666 (define_peephole
8667 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8668 (match_operand 1 "" ""))
8669 (clobber (reg:SI 15))])
8670 (set (pc) (label_ref (match_operand 2 "" "")))]
8671 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8672 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8673 && sparc_cpu != PROCESSOR_ULTRASPARC
8674 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8675 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8676
8677 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8678 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8679 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8680 ;; ??? state.
8681 (define_expand "prefetch"
8682 [(match_operand 0 "address_operand" "")
8683 (match_operand 1 "const_int_operand" "")
8684 (match_operand 2 "const_int_operand" "")]
8685 "TARGET_V9"
8686 "
8687 {
8688 if (TARGET_ARCH64)
8689 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8690 else
8691 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8692 DONE;
8693 }")
8694
8695 (define_insn "prefetch_64"
8696 [(prefetch (match_operand:DI 0 "address_operand" "p")
8697 (match_operand:DI 1 "const_int_operand" "n")
8698 (match_operand:DI 2 "const_int_operand" "n"))]
8699 ""
8700 {
8701 static const char * const prefetch_instr[2][2] = {
8702 {
8703 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8704 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8705 },
8706 {
8707 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8708 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8709 }
8710 };
8711 int read_or_write = INTVAL (operands[1]);
8712 int locality = INTVAL (operands[2]);
8713
8714 if (read_or_write != 0 && read_or_write != 1)
8715 abort ();
8716 if (locality < 0 || locality > 3)
8717 abort ();
8718 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8719 }
8720 [(set_attr "type" "load")])
8721
8722 (define_insn "prefetch_32"
8723 [(prefetch (match_operand:SI 0 "address_operand" "p")
8724 (match_operand:SI 1 "const_int_operand" "n")
8725 (match_operand:SI 2 "const_int_operand" "n"))]
8726 ""
8727 {
8728 static const char * const prefetch_instr[2][2] = {
8729 {
8730 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8731 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8732 },
8733 {
8734 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8735 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8736 }
8737 };
8738 int read_or_write = INTVAL (operands[1]);
8739 int locality = INTVAL (operands[2]);
8740
8741 if (read_or_write != 0 && read_or_write != 1)
8742 abort ();
8743 if (locality < 0 || locality > 3)
8744 abort ();
8745 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8746 }
8747 [(set_attr "type" "load")])
8748 \f
8749 (define_expand "prologue"
8750 [(const_int 1)]
8751 "flag_pic && current_function_uses_pic_offset_table"
8752 "
8753 {
8754 load_pic_register ();
8755 DONE;
8756 }")
8757
8758 ;; We need to reload %l7 for -mflat -fpic,
8759 ;; otherwise %l7 should be preserved simply
8760 ;; by loading the function's register window
8761 (define_expand "exception_receiver"
8762 [(const_int 0)]
8763 "TARGET_FLAT && flag_pic"
8764 "
8765 {
8766 load_pic_register ();
8767 DONE;
8768 }")
8769
8770 ;; Likewise
8771 (define_expand "builtin_setjmp_receiver"
8772 [(label_ref (match_operand 0 "" ""))]
8773 "TARGET_FLAT && flag_pic"
8774 "
8775 {
8776 load_pic_register ();
8777 DONE;
8778 }")
8779 \f
8780 (define_insn "trap"
8781 [(trap_if (const_int 1) (const_int 5))]
8782 ""
8783 "ta\\t5"
8784 [(set_attr "type" "misc")])
8785
8786 (define_expand "conditional_trap"
8787 [(trap_if (match_operator 0 "noov_compare_op"
8788 [(match_dup 2) (match_dup 3)])
8789 (match_operand:SI 1 "arith_operand" ""))]
8790 ""
8791 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8792 sparc_compare_op0, sparc_compare_op1);
8793 operands[3] = const0_rtx;")
8794
8795 (define_insn ""
8796 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8797 (match_operand:SI 1 "arith_operand" "rM"))]
8798 ""
8799 "t%C0\\t%1"
8800 [(set_attr "type" "misc")])
8801
8802 (define_insn ""
8803 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8804 (match_operand:SI 1 "arith_operand" "rM"))]
8805 "TARGET_V9"
8806 "t%C0\\t%%xcc, %1"
8807 [(set_attr "type" "misc")])