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