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