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