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