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