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