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