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