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