invoke.texi (SPARC options): Remove -mflat and all -mxxx (xxx:chip) options.
[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 "register_operand" ""))]
4666 "TARGET_ARCH64 && TARGET_FPU"
4667 "sparc_emit_floatunsdi (operands); 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 "register_operand" ""))]
4680 "TARGET_ARCH64 && TARGET_FPU"
4681 "sparc_emit_floatunsdi (operands); 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_insn "fix_truncdfdi2"
4751 [(set (match_operand:DI 0 "register_operand" "=e")
4752 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4753 "TARGET_V9 && TARGET_FPU"
4754 "fdtox\t%1, %0"
4755 [(set_attr "type" "fp")
4756 (set_attr "fptype" "double")])
4757
4758 (define_expand "fix_trunctfdi2"
4759 [(set (match_operand:DI 0 "register_operand" "")
4760 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4761 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4762 "emit_tfmode_cvt (FIX, operands); DONE;")
4763
4764 (define_insn "*fix_trunctfdi2_hq"
4765 [(set (match_operand:DI 0 "register_operand" "=e")
4766 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4767 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4768 "fqtox\t%1, %0"
4769 [(set_attr "type" "fp")])
4770
4771 (define_expand "fixuns_trunctfdi2"
4772 [(set (match_operand:DI 0 "register_operand" "")
4773 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4774 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4775 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4776 \f
4777 ;;- arithmetic instructions
4778
4779 (define_expand "adddi3"
4780 [(set (match_operand:DI 0 "register_operand" "")
4781 (plus:DI (match_operand:DI 1 "register_operand" "")
4782 (match_operand:DI 2 "arith_double_add_operand" "")))]
4783 ""
4784 {
4785 if (! TARGET_ARCH64)
4786 {
4787 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4788 gen_rtx_SET (VOIDmode, operands[0],
4789 gen_rtx_PLUS (DImode, operands[1],
4790 operands[2])),
4791 gen_rtx_CLOBBER (VOIDmode,
4792 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4793 DONE;
4794 }
4795 })
4796
4797 (define_insn_and_split "adddi3_insn_sp32"
4798 [(set (match_operand:DI 0 "register_operand" "=r")
4799 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4800 (match_operand:DI 2 "arith_double_operand" "rHI")))
4801 (clobber (reg:CC 100))]
4802 "! TARGET_ARCH64"
4803 "#"
4804 "&& reload_completed"
4805 [(parallel [(set (reg:CC_NOOV 100)
4806 (compare:CC_NOOV (plus:SI (match_dup 4)
4807 (match_dup 5))
4808 (const_int 0)))
4809 (set (match_dup 3)
4810 (plus:SI (match_dup 4) (match_dup 5)))])
4811 (set (match_dup 6)
4812 (plus:SI (plus:SI (match_dup 7)
4813 (match_dup 8))
4814 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4815 {
4816 operands[3] = gen_lowpart (SImode, operands[0]);
4817 operands[4] = gen_lowpart (SImode, operands[1]);
4818 operands[5] = gen_lowpart (SImode, operands[2]);
4819 operands[6] = gen_highpart (SImode, operands[0]);
4820 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4821 #if HOST_BITS_PER_WIDE_INT == 32
4822 if (GET_CODE (operands[2]) == CONST_INT)
4823 {
4824 if (INTVAL (operands[2]) < 0)
4825 operands[8] = constm1_rtx;
4826 else
4827 operands[8] = const0_rtx;
4828 }
4829 else
4830 #endif
4831 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4832 }
4833 [(set_attr "length" "2")])
4834
4835 (define_split
4836 [(set (match_operand:DI 0 "register_operand" "")
4837 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4838 (match_operand:DI 2 "arith_double_operand" "")))
4839 (clobber (reg:CC 100))]
4840 "! TARGET_ARCH64 && reload_completed"
4841 [(parallel [(set (reg:CC_NOOV 100)
4842 (compare:CC_NOOV (minus:SI (match_dup 4)
4843 (match_dup 5))
4844 (const_int 0)))
4845 (set (match_dup 3)
4846 (minus:SI (match_dup 4) (match_dup 5)))])
4847 (set (match_dup 6)
4848 (minus:SI (minus:SI (match_dup 7)
4849 (match_dup 8))
4850 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4851 {
4852 operands[3] = gen_lowpart (SImode, operands[0]);
4853 operands[4] = gen_lowpart (SImode, operands[1]);
4854 operands[5] = gen_lowpart (SImode, operands[2]);
4855 operands[6] = gen_highpart (SImode, operands[0]);
4856 operands[7] = gen_highpart (SImode, operands[1]);
4857 #if HOST_BITS_PER_WIDE_INT == 32
4858 if (GET_CODE (operands[2]) == CONST_INT)
4859 {
4860 if (INTVAL (operands[2]) < 0)
4861 operands[8] = constm1_rtx;
4862 else
4863 operands[8] = const0_rtx;
4864 }
4865 else
4866 #endif
4867 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4868 })
4869
4870 ;; LTU here means "carry set"
4871 (define_insn "addx"
4872 [(set (match_operand:SI 0 "register_operand" "=r")
4873 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4874 (match_operand:SI 2 "arith_operand" "rI"))
4875 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4876 ""
4877 "addx\t%1, %2, %0"
4878 [(set_attr "type" "ialuX")])
4879
4880 (define_insn_and_split "*addx_extend_sp32"
4881 [(set (match_operand:DI 0 "register_operand" "=r")
4882 (zero_extend:DI (plus:SI (plus:SI
4883 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4884 (match_operand:SI 2 "arith_operand" "rI"))
4885 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4886 "! TARGET_ARCH64"
4887 "#"
4888 "&& reload_completed"
4889 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4890 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4891 (set (match_dup 4) (const_int 0))]
4892 "operands[3] = gen_lowpart (SImode, operands[0]);
4893 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4894 [(set_attr "length" "2")])
4895
4896 (define_insn "*addx_extend_sp64"
4897 [(set (match_operand:DI 0 "register_operand" "=r")
4898 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4899 (match_operand:SI 2 "arith_operand" "rI"))
4900 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4901 "TARGET_ARCH64"
4902 "addx\t%r1, %2, %0"
4903 [(set_attr "type" "ialuX")])
4904
4905 (define_insn "subx"
4906 [(set (match_operand:SI 0 "register_operand" "=r")
4907 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4908 (match_operand:SI 2 "arith_operand" "rI"))
4909 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4910 ""
4911 "subx\t%r1, %2, %0"
4912 [(set_attr "type" "ialuX")])
4913
4914 (define_insn "*subx_extend_sp64"
4915 [(set (match_operand:DI 0 "register_operand" "=r")
4916 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4917 (match_operand:SI 2 "arith_operand" "rI"))
4918 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4919 "TARGET_ARCH64"
4920 "subx\t%r1, %2, %0"
4921 [(set_attr "type" "ialuX")])
4922
4923 (define_insn_and_split "*subx_extend"
4924 [(set (match_operand:DI 0 "register_operand" "=r")
4925 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4926 (match_operand:SI 2 "arith_operand" "rI"))
4927 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4928 "! TARGET_ARCH64"
4929 "#"
4930 "&& reload_completed"
4931 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4932 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4933 (set (match_dup 4) (const_int 0))]
4934 "operands[3] = gen_lowpart (SImode, operands[0]);
4935 operands[4] = gen_highpart (SImode, operands[0]);"
4936 [(set_attr "length" "2")])
4937
4938 (define_insn_and_split ""
4939 [(set (match_operand:DI 0 "register_operand" "=r")
4940 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4941 (match_operand:DI 2 "register_operand" "r")))
4942 (clobber (reg:CC 100))]
4943 "! TARGET_ARCH64"
4944 "#"
4945 "&& reload_completed"
4946 [(parallel [(set (reg:CC_NOOV 100)
4947 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4948 (const_int 0)))
4949 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4950 (set (match_dup 6)
4951 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4952 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4953 "operands[3] = gen_lowpart (SImode, operands[2]);
4954 operands[4] = gen_highpart (SImode, operands[2]);
4955 operands[5] = gen_lowpart (SImode, operands[0]);
4956 operands[6] = gen_highpart (SImode, operands[0]);"
4957 [(set_attr "length" "2")])
4958
4959 (define_insn "*adddi3_sp64"
4960 [(set (match_operand:DI 0 "register_operand" "=r,r")
4961 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4962 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
4963 "TARGET_ARCH64"
4964 "@
4965 add\t%1, %2, %0
4966 sub\t%1, -%2, %0")
4967
4968 (define_insn "addsi3"
4969 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4970 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4971 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4972 ""
4973 "@
4974 add\t%1, %2, %0
4975 sub\t%1, -%2, %0
4976 fpadd32s\t%1, %2, %0"
4977 [(set_attr "type" "*,*,fga")])
4978
4979 (define_insn "*cmp_cc_plus"
4980 [(set (reg:CC_NOOV 100)
4981 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4982 (match_operand:SI 1 "arith_operand" "rI"))
4983 (const_int 0)))]
4984 ""
4985 "addcc\t%0, %1, %%g0"
4986 [(set_attr "type" "compare")])
4987
4988 (define_insn "*cmp_ccx_plus"
4989 [(set (reg:CCX_NOOV 100)
4990 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4991 (match_operand:DI 1 "arith_double_operand" "rHI"))
4992 (const_int 0)))]
4993 "TARGET_ARCH64"
4994 "addcc\t%0, %1, %%g0"
4995 [(set_attr "type" "compare")])
4996
4997 (define_insn "*cmp_cc_plus_set"
4998 [(set (reg:CC_NOOV 100)
4999 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5000 (match_operand:SI 2 "arith_operand" "rI"))
5001 (const_int 0)))
5002 (set (match_operand:SI 0 "register_operand" "=r")
5003 (plus:SI (match_dup 1) (match_dup 2)))]
5004 ""
5005 "addcc\t%1, %2, %0"
5006 [(set_attr "type" "compare")])
5007
5008 (define_insn "*cmp_ccx_plus_set"
5009 [(set (reg:CCX_NOOV 100)
5010 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5011 (match_operand:DI 2 "arith_double_operand" "rHI"))
5012 (const_int 0)))
5013 (set (match_operand:DI 0 "register_operand" "=r")
5014 (plus:DI (match_dup 1) (match_dup 2)))]
5015 "TARGET_ARCH64"
5016 "addcc\t%1, %2, %0"
5017 [(set_attr "type" "compare")])
5018
5019 (define_expand "subdi3"
5020 [(set (match_operand:DI 0 "register_operand" "")
5021 (minus:DI (match_operand:DI 1 "register_operand" "")
5022 (match_operand:DI 2 "arith_double_add_operand" "")))]
5023 ""
5024 {
5025 if (! TARGET_ARCH64)
5026 {
5027 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5028 gen_rtx_SET (VOIDmode, operands[0],
5029 gen_rtx_MINUS (DImode, operands[1],
5030 operands[2])),
5031 gen_rtx_CLOBBER (VOIDmode,
5032 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5033 DONE;
5034 }
5035 })
5036
5037 (define_insn_and_split "*subdi3_sp32"
5038 [(set (match_operand:DI 0 "register_operand" "=r")
5039 (minus:DI (match_operand:DI 1 "register_operand" "r")
5040 (match_operand:DI 2 "arith_double_operand" "rHI")))
5041 (clobber (reg:CC 100))]
5042 "! TARGET_ARCH64"
5043 "#"
5044 "&& reload_completed
5045 && (GET_CODE (operands[2]) == CONST_INT
5046 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5047 [(clobber (const_int 0))]
5048 {
5049 rtx highp, lowp;
5050
5051 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5052 lowp = gen_lowpart (SImode, operands[2]);
5053 if ((lowp == const0_rtx)
5054 && (operands[0] == operands[1]))
5055 {
5056 emit_insn (gen_rtx_SET (VOIDmode,
5057 gen_highpart (SImode, operands[0]),
5058 gen_rtx_MINUS (SImode,
5059 gen_highpart_mode (SImode, DImode,
5060 operands[1]),
5061 highp)));
5062 }
5063 else
5064 {
5065 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5066 gen_lowpart (SImode, operands[1]),
5067 lowp));
5068 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5069 gen_highpart_mode (SImode, DImode, operands[1]),
5070 highp));
5071 }
5072 DONE;
5073 }
5074 [(set_attr "length" "2")])
5075
5076 (define_split
5077 [(set (match_operand:DI 0 "register_operand" "")
5078 (minus:DI (match_operand:DI 1 "register_operand" "")
5079 (match_operand:DI 2 "register_operand" "")))
5080 (clobber (reg:CC 100))]
5081 "! TARGET_ARCH64
5082 && reload_completed"
5083 [(clobber (const_int 0))]
5084 {
5085 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5086 gen_lowpart (SImode, operands[1]),
5087 gen_lowpart (SImode, operands[2])));
5088 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5089 gen_highpart (SImode, operands[1]),
5090 gen_highpart (SImode, operands[2])));
5091 DONE;
5092 })
5093
5094 (define_insn_and_split ""
5095 [(set (match_operand:DI 0 "register_operand" "=r")
5096 (minus:DI (match_operand:DI 1 "register_operand" "r")
5097 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5098 (clobber (reg:CC 100))]
5099 "! TARGET_ARCH64"
5100 "#"
5101 "&& reload_completed"
5102 [(parallel [(set (reg:CC_NOOV 100)
5103 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5104 (const_int 0)))
5105 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5106 (set (match_dup 6)
5107 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5108 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5109 "operands[3] = gen_lowpart (SImode, operands[1]);
5110 operands[4] = gen_highpart (SImode, operands[1]);
5111 operands[5] = gen_lowpart (SImode, operands[0]);
5112 operands[6] = gen_highpart (SImode, operands[0]);"
5113 [(set_attr "length" "2")])
5114
5115 (define_insn "*subdi3_sp64"
5116 [(set (match_operand:DI 0 "register_operand" "=r,r")
5117 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5118 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5119 "TARGET_ARCH64"
5120 "@
5121 sub\t%1, %2, %0
5122 add\t%1, -%2, %0")
5123
5124 (define_insn "subsi3"
5125 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5126 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5127 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5128 ""
5129 "@
5130 sub\t%1, %2, %0
5131 add\t%1, -%2, %0
5132 fpsub32s\t%1, %2, %0"
5133 [(set_attr "type" "*,*,fga")])
5134
5135 (define_insn "*cmp_minus_cc"
5136 [(set (reg:CC_NOOV 100)
5137 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5138 (match_operand:SI 1 "arith_operand" "rI"))
5139 (const_int 0)))]
5140 ""
5141 "subcc\t%r0, %1, %%g0"
5142 [(set_attr "type" "compare")])
5143
5144 (define_insn "*cmp_minus_ccx"
5145 [(set (reg:CCX_NOOV 100)
5146 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5147 (match_operand:DI 1 "arith_double_operand" "rHI"))
5148 (const_int 0)))]
5149 "TARGET_ARCH64"
5150 "subcc\t%0, %1, %%g0"
5151 [(set_attr "type" "compare")])
5152
5153 (define_insn "cmp_minus_cc_set"
5154 [(set (reg:CC_NOOV 100)
5155 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5156 (match_operand:SI 2 "arith_operand" "rI"))
5157 (const_int 0)))
5158 (set (match_operand:SI 0 "register_operand" "=r")
5159 (minus:SI (match_dup 1) (match_dup 2)))]
5160 ""
5161 "subcc\t%r1, %2, %0"
5162 [(set_attr "type" "compare")])
5163
5164 (define_insn "*cmp_minus_ccx_set"
5165 [(set (reg:CCX_NOOV 100)
5166 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5167 (match_operand:DI 2 "arith_double_operand" "rHI"))
5168 (const_int 0)))
5169 (set (match_operand:DI 0 "register_operand" "=r")
5170 (minus:DI (match_dup 1) (match_dup 2)))]
5171 "TARGET_ARCH64"
5172 "subcc\t%1, %2, %0"
5173 [(set_attr "type" "compare")])
5174 \f
5175 ;; Integer Multiply/Divide.
5176
5177 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5178 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5179
5180 (define_insn "mulsi3"
5181 [(set (match_operand:SI 0 "register_operand" "=r")
5182 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5183 (match_operand:SI 2 "arith_operand" "rI")))]
5184 "TARGET_HARD_MUL"
5185 "smul\t%1, %2, %0"
5186 [(set_attr "type" "imul")])
5187
5188 (define_expand "muldi3"
5189 [(set (match_operand:DI 0 "register_operand" "=r")
5190 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5191 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5192 "TARGET_ARCH64 || TARGET_V8PLUS"
5193 {
5194 if (TARGET_V8PLUS)
5195 {
5196 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5197 DONE;
5198 }
5199 })
5200
5201 (define_insn "*muldi3_sp64"
5202 [(set (match_operand:DI 0 "register_operand" "=r")
5203 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5204 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5205 "TARGET_ARCH64"
5206 "mulx\t%1, %2, %0"
5207 [(set_attr "type" "imul")])
5208
5209 ;; V8plus wide multiply.
5210 ;; XXX
5211 (define_insn "muldi3_v8plus"
5212 [(set (match_operand:DI 0 "register_operand" "=r,h")
5213 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5214 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5215 (clobber (match_scratch:SI 3 "=&h,X"))
5216 (clobber (match_scratch:SI 4 "=&h,X"))]
5217 "TARGET_V8PLUS"
5218 {
5219 if (sparc_check_64 (operands[1], insn) <= 0)
5220 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5221 if (which_alternative == 1)
5222 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5223 if (GET_CODE (operands[2]) == CONST_INT)
5224 {
5225 if (which_alternative == 1)
5226 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5227 else
5228 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";
5229 }
5230 else if (rtx_equal_p (operands[1], operands[2]))
5231 {
5232 if (which_alternative == 1)
5233 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5234 else
5235 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";
5236 }
5237 if (sparc_check_64 (operands[2], insn) <= 0)
5238 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5239 if (which_alternative == 1)
5240 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";
5241 else
5242 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";
5243 }
5244 [(set_attr "type" "multi")
5245 (set_attr "length" "9,8")])
5246
5247 (define_insn "*cmp_mul_set"
5248 [(set (reg:CC 100)
5249 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5250 (match_operand:SI 2 "arith_operand" "rI"))
5251 (const_int 0)))
5252 (set (match_operand:SI 0 "register_operand" "=r")
5253 (mult:SI (match_dup 1) (match_dup 2)))]
5254 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5255 "smulcc\t%1, %2, %0"
5256 [(set_attr "type" "imul")])
5257
5258 (define_expand "mulsidi3"
5259 [(set (match_operand:DI 0 "register_operand" "")
5260 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5261 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5262 "TARGET_HARD_MUL"
5263 {
5264 if (CONSTANT_P (operands[2]))
5265 {
5266 if (TARGET_V8PLUS)
5267 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5268 operands[2]));
5269 else if (TARGET_ARCH32)
5270 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5271 operands[2]));
5272 else
5273 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5274 operands[2]));
5275 DONE;
5276 }
5277 if (TARGET_V8PLUS)
5278 {
5279 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5280 DONE;
5281 }
5282 })
5283
5284 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5285 ;; registers can hold 64 bit values in the V8plus environment.
5286 ;; XXX
5287 (define_insn "mulsidi3_v8plus"
5288 [(set (match_operand:DI 0 "register_operand" "=h,r")
5289 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5290 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5291 (clobber (match_scratch:SI 3 "=X,&h"))]
5292 "TARGET_V8PLUS"
5293 "@
5294 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5295 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5296 [(set_attr "type" "multi")
5297 (set_attr "length" "2,3")])
5298
5299 ;; XXX
5300 (define_insn "const_mulsidi3_v8plus"
5301 [(set (match_operand:DI 0 "register_operand" "=h,r")
5302 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5303 (match_operand:DI 2 "small_int" "I,I")))
5304 (clobber (match_scratch:SI 3 "=X,&h"))]
5305 "TARGET_V8PLUS"
5306 "@
5307 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5308 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5309 [(set_attr "type" "multi")
5310 (set_attr "length" "2,3")])
5311
5312 ;; XXX
5313 (define_insn "*mulsidi3_sp32"
5314 [(set (match_operand:DI 0 "register_operand" "=r")
5315 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5316 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5317 "TARGET_HARD_MUL32"
5318 {
5319 return TARGET_SPARCLET
5320 ? "smuld\t%1, %2, %L0"
5321 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5322 }
5323 [(set (attr "type")
5324 (if_then_else (eq_attr "isa" "sparclet")
5325 (const_string "imul") (const_string "multi")))
5326 (set (attr "length")
5327 (if_then_else (eq_attr "isa" "sparclet")
5328 (const_int 1) (const_int 2)))])
5329
5330 (define_insn "*mulsidi3_sp64"
5331 [(set (match_operand:DI 0 "register_operand" "=r")
5332 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5333 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5334 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5335 "smul\t%1, %2, %0"
5336 [(set_attr "type" "imul")])
5337
5338 ;; Extra pattern, because sign_extend of a constant isn't valid.
5339
5340 ;; XXX
5341 (define_insn "const_mulsidi3_sp32"
5342 [(set (match_operand:DI 0 "register_operand" "=r")
5343 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5344 (match_operand:DI 2 "small_int" "I")))]
5345 "TARGET_HARD_MUL32"
5346 {
5347 return TARGET_SPARCLET
5348 ? "smuld\t%1, %2, %L0"
5349 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5350 }
5351 [(set (attr "type")
5352 (if_then_else (eq_attr "isa" "sparclet")
5353 (const_string "imul") (const_string "multi")))
5354 (set (attr "length")
5355 (if_then_else (eq_attr "isa" "sparclet")
5356 (const_int 1) (const_int 2)))])
5357
5358 (define_insn "const_mulsidi3_sp64"
5359 [(set (match_operand:DI 0 "register_operand" "=r")
5360 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5361 (match_operand:DI 2 "small_int" "I")))]
5362 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5363 "smul\t%1, %2, %0"
5364 [(set_attr "type" "imul")])
5365
5366 (define_expand "smulsi3_highpart"
5367 [(set (match_operand:SI 0 "register_operand" "")
5368 (truncate:SI
5369 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5370 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5371 (const_int 32))))]
5372 "TARGET_HARD_MUL && TARGET_ARCH32"
5373 {
5374 if (CONSTANT_P (operands[2]))
5375 {
5376 if (TARGET_V8PLUS)
5377 {
5378 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5379 operands[1],
5380 operands[2],
5381 GEN_INT (32)));
5382 DONE;
5383 }
5384 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5385 DONE;
5386 }
5387 if (TARGET_V8PLUS)
5388 {
5389 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5390 operands[2], GEN_INT (32)));
5391 DONE;
5392 }
5393 })
5394
5395 ;; XXX
5396 (define_insn "smulsi3_highpart_v8plus"
5397 [(set (match_operand:SI 0 "register_operand" "=h,r")
5398 (truncate:SI
5399 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5400 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5401 (match_operand:SI 3 "const_int_operand" "i,i"))))
5402 (clobber (match_scratch:SI 4 "=X,&h"))]
5403 "TARGET_V8PLUS"
5404 "@
5405 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5406 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5407 [(set_attr "type" "multi")
5408 (set_attr "length" "2")])
5409
5410 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5411 ;; XXX
5412 (define_insn ""
5413 [(set (match_operand:SI 0 "register_operand" "=h,r")
5414 (subreg:SI
5415 (lshiftrt:DI
5416 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5417 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5418 (match_operand:SI 3 "const_int_operand" "i,i"))
5419 4))
5420 (clobber (match_scratch:SI 4 "=X,&h"))]
5421 "TARGET_V8PLUS"
5422 "@
5423 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5424 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5425 [(set_attr "type" "multi")
5426 (set_attr "length" "2")])
5427
5428 ;; XXX
5429 (define_insn "const_smulsi3_highpart_v8plus"
5430 [(set (match_operand:SI 0 "register_operand" "=h,r")
5431 (truncate:SI
5432 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5433 (match_operand:DI 2 "small_int" "i,i"))
5434 (match_operand:SI 3 "const_int_operand" "i,i"))))
5435 (clobber (match_scratch:SI 4 "=X,&h"))]
5436 "TARGET_V8PLUS"
5437 "@
5438 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5439 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5440 [(set_attr "type" "multi")
5441 (set_attr "length" "2")])
5442
5443 ;; XXX
5444 (define_insn "*smulsi3_highpart_sp32"
5445 [(set (match_operand:SI 0 "register_operand" "=r")
5446 (truncate:SI
5447 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5448 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5449 (const_int 32))))]
5450 "TARGET_HARD_MUL32"
5451 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5452 [(set_attr "type" "multi")
5453 (set_attr "length" "2")])
5454
5455 ;; XXX
5456 (define_insn "const_smulsi3_highpart"
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 (match_operand:DI 2 "small_int" "i"))
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 (define_expand "umulsidi3"
5468 [(set (match_operand:DI 0 "register_operand" "")
5469 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5470 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5471 "TARGET_HARD_MUL"
5472 {
5473 if (CONSTANT_P (operands[2]))
5474 {
5475 if (TARGET_V8PLUS)
5476 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5477 operands[2]));
5478 else if (TARGET_ARCH32)
5479 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5480 operands[2]));
5481 else
5482 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5483 operands[2]));
5484 DONE;
5485 }
5486 if (TARGET_V8PLUS)
5487 {
5488 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5489 DONE;
5490 }
5491 })
5492
5493 ;; XXX
5494 (define_insn "umulsidi3_v8plus"
5495 [(set (match_operand:DI 0 "register_operand" "=h,r")
5496 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5497 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5498 (clobber (match_scratch:SI 3 "=X,&h"))]
5499 "TARGET_V8PLUS"
5500 "@
5501 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5502 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5503 [(set_attr "type" "multi")
5504 (set_attr "length" "2,3")])
5505
5506 ;; XXX
5507 (define_insn "*umulsidi3_sp32"
5508 [(set (match_operand:DI 0 "register_operand" "=r")
5509 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5510 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5511 "TARGET_HARD_MUL32"
5512 {
5513 return TARGET_SPARCLET
5514 ? "umuld\t%1, %2, %L0"
5515 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5516 }
5517 [(set (attr "type")
5518 (if_then_else (eq_attr "isa" "sparclet")
5519 (const_string "imul") (const_string "multi")))
5520 (set (attr "length")
5521 (if_then_else (eq_attr "isa" "sparclet")
5522 (const_int 1) (const_int 2)))])
5523
5524 (define_insn "*umulsidi3_sp64"
5525 [(set (match_operand:DI 0 "register_operand" "=r")
5526 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5527 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5528 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5529 "umul\t%1, %2, %0"
5530 [(set_attr "type" "imul")])
5531
5532 ;; Extra pattern, because sign_extend of a constant isn't valid.
5533
5534 ;; XXX
5535 (define_insn "const_umulsidi3_sp32"
5536 [(set (match_operand:DI 0 "register_operand" "=r")
5537 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5538 (match_operand:DI 2 "uns_small_int" "")))]
5539 "TARGET_HARD_MUL32"
5540 {
5541 return TARGET_SPARCLET
5542 ? "umuld\t%1, %s2, %L0"
5543 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5544 }
5545 [(set (attr "type")
5546 (if_then_else (eq_attr "isa" "sparclet")
5547 (const_string "imul") (const_string "multi")))
5548 (set (attr "length")
5549 (if_then_else (eq_attr "isa" "sparclet")
5550 (const_int 1) (const_int 2)))])
5551
5552 (define_insn "const_umulsidi3_sp64"
5553 [(set (match_operand:DI 0 "register_operand" "=r")
5554 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5555 (match_operand:DI 2 "uns_small_int" "")))]
5556 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5557 "umul\t%1, %s2, %0"
5558 [(set_attr "type" "imul")])
5559
5560 ;; XXX
5561 (define_insn "const_umulsidi3_v8plus"
5562 [(set (match_operand:DI 0 "register_operand" "=h,r")
5563 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5564 (match_operand:DI 2 "uns_small_int" "")))
5565 (clobber (match_scratch:SI 3 "=X,h"))]
5566 "TARGET_V8PLUS"
5567 "@
5568 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5569 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5570 [(set_attr "type" "multi")
5571 (set_attr "length" "2,3")])
5572
5573 (define_expand "umulsi3_highpart"
5574 [(set (match_operand:SI 0 "register_operand" "")
5575 (truncate:SI
5576 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5577 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5578 (const_int 32))))]
5579 "TARGET_HARD_MUL && TARGET_ARCH32"
5580 {
5581 if (CONSTANT_P (operands[2]))
5582 {
5583 if (TARGET_V8PLUS)
5584 {
5585 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5586 operands[1],
5587 operands[2],
5588 GEN_INT (32)));
5589 DONE;
5590 }
5591 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5592 DONE;
5593 }
5594 if (TARGET_V8PLUS)
5595 {
5596 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5597 operands[2], GEN_INT (32)));
5598 DONE;
5599 }
5600 })
5601
5602 ;; XXX
5603 (define_insn "umulsi3_highpart_v8plus"
5604 [(set (match_operand:SI 0 "register_operand" "=h,r")
5605 (truncate:SI
5606 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5607 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5608 (match_operand:SI 3 "const_int_operand" "i,i"))))
5609 (clobber (match_scratch:SI 4 "=X,h"))]
5610 "TARGET_V8PLUS"
5611 "@
5612 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5613 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5614 [(set_attr "type" "multi")
5615 (set_attr "length" "2")])
5616
5617 ;; XXX
5618 (define_insn "const_umulsi3_highpart_v8plus"
5619 [(set (match_operand:SI 0 "register_operand" "=h,r")
5620 (truncate:SI
5621 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5622 (match_operand:DI 2 "uns_small_int" ""))
5623 (match_operand:SI 3 "const_int_operand" "i,i"))))
5624 (clobber (match_scratch:SI 4 "=X,h"))]
5625 "TARGET_V8PLUS"
5626 "@
5627 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5628 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5629 [(set_attr "type" "multi")
5630 (set_attr "length" "2")])
5631
5632 ;; XXX
5633 (define_insn "*umulsi3_highpart_sp32"
5634 [(set (match_operand:SI 0 "register_operand" "=r")
5635 (truncate:SI
5636 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5637 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5638 (const_int 32))))]
5639 "TARGET_HARD_MUL32"
5640 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5641 [(set_attr "type" "multi")
5642 (set_attr "length" "2")])
5643
5644 ;; XXX
5645 (define_insn "const_umulsi3_highpart"
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 (match_operand:DI 2 "uns_small_int" ""))
5650 (const_int 32))))]
5651 "TARGET_HARD_MUL32"
5652 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5653 [(set_attr "type" "multi")
5654 (set_attr "length" "2")])
5655
5656 ;; The v8 architecture specifies that there must be 3 instructions between
5657 ;; a y register write and a use of it for correct results.
5658
5659 (define_expand "divsi3"
5660 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5661 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5662 (match_operand:SI 2 "input_operand" "rI,m")))
5663 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5664 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5665 {
5666 if (TARGET_ARCH64)
5667 {
5668 operands[3] = gen_reg_rtx(SImode);
5669 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5670 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5671 operands[3]));
5672 DONE;
5673 }
5674 })
5675
5676 (define_insn "divsi3_sp32"
5677 [(set (match_operand:SI 0 "register_operand" "=r,r")
5678 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5679 (match_operand:SI 2 "input_operand" "rI,m")))
5680 (clobber (match_scratch:SI 3 "=&r,&r"))]
5681 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5682 && TARGET_ARCH32"
5683 {
5684 if (which_alternative == 0)
5685 if (TARGET_V9)
5686 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5687 else
5688 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5689 else
5690 if (TARGET_V9)
5691 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5692 else
5693 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";
5694 }
5695 [(set_attr "type" "multi")
5696 (set (attr "length")
5697 (if_then_else (eq_attr "isa" "v9")
5698 (const_int 4) (const_int 6)))])
5699
5700 (define_insn "divsi3_sp64"
5701 [(set (match_operand:SI 0 "register_operand" "=r")
5702 (div:SI (match_operand:SI 1 "register_operand" "r")
5703 (match_operand:SI 2 "input_operand" "rI")))
5704 (use (match_operand:SI 3 "register_operand" "r"))]
5705 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5706 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5707 [(set_attr "type" "multi")
5708 (set_attr "length" "2")])
5709
5710 (define_insn "divdi3"
5711 [(set (match_operand:DI 0 "register_operand" "=r")
5712 (div:DI (match_operand:DI 1 "register_operand" "r")
5713 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5714 "TARGET_ARCH64"
5715 "sdivx\t%1, %2, %0"
5716 [(set_attr "type" "idiv")])
5717
5718 (define_insn "*cmp_sdiv_cc_set"
5719 [(set (reg:CC 100)
5720 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5721 (match_operand:SI 2 "arith_operand" "rI"))
5722 (const_int 0)))
5723 (set (match_operand:SI 0 "register_operand" "=r")
5724 (div:SI (match_dup 1) (match_dup 2)))
5725 (clobber (match_scratch:SI 3 "=&r"))]
5726 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5727 {
5728 if (TARGET_V9)
5729 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5730 else
5731 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5732 }
5733 [(set_attr "type" "multi")
5734 (set (attr "length")
5735 (if_then_else (eq_attr "isa" "v9")
5736 (const_int 3) (const_int 6)))])
5737
5738 ;; XXX
5739 (define_expand "udivsi3"
5740 [(set (match_operand:SI 0 "register_operand" "")
5741 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5742 (match_operand:SI 2 "input_operand" "")))]
5743 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5744 "")
5745
5746 (define_insn "udivsi3_sp32"
5747 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5748 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5749 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5750 "(TARGET_V8
5751 || TARGET_DEPRECATED_V8_INSNS)
5752 && TARGET_ARCH32"
5753 {
5754 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5755 switch (which_alternative)
5756 {
5757 default:
5758 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5759 case 1:
5760 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5761 case 2:
5762 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5763 }
5764 }
5765 [(set_attr "type" "multi")
5766 (set_attr "length" "5")])
5767
5768 (define_insn "udivsi3_sp64"
5769 [(set (match_operand:SI 0 "register_operand" "=r")
5770 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5771 (match_operand:SI 2 "input_operand" "rI")))]
5772 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5773 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5774 [(set_attr "type" "multi")
5775 (set_attr "length" "2")])
5776
5777 (define_insn "udivdi3"
5778 [(set (match_operand:DI 0 "register_operand" "=r")
5779 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5780 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5781 "TARGET_ARCH64"
5782 "udivx\t%1, %2, %0"
5783 [(set_attr "type" "idiv")])
5784
5785 (define_insn "*cmp_udiv_cc_set"
5786 [(set (reg:CC 100)
5787 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5788 (match_operand:SI 2 "arith_operand" "rI"))
5789 (const_int 0)))
5790 (set (match_operand:SI 0 "register_operand" "=r")
5791 (udiv:SI (match_dup 1) (match_dup 2)))]
5792 "TARGET_V8
5793 || TARGET_DEPRECATED_V8_INSNS"
5794 {
5795 if (TARGET_V9)
5796 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5797 else
5798 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5799 }
5800 [(set_attr "type" "multi")
5801 (set (attr "length")
5802 (if_then_else (eq_attr "isa" "v9")
5803 (const_int 2) (const_int 5)))])
5804
5805 ; sparclet multiply/accumulate insns
5806
5807 (define_insn "*smacsi"
5808 [(set (match_operand:SI 0 "register_operand" "=r")
5809 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5810 (match_operand:SI 2 "arith_operand" "rI"))
5811 (match_operand:SI 3 "register_operand" "0")))]
5812 "TARGET_SPARCLET"
5813 "smac\t%1, %2, %0"
5814 [(set_attr "type" "imul")])
5815
5816 (define_insn "*smacdi"
5817 [(set (match_operand:DI 0 "register_operand" "=r")
5818 (plus:DI (mult:DI (sign_extend:DI
5819 (match_operand:SI 1 "register_operand" "%r"))
5820 (sign_extend:DI
5821 (match_operand:SI 2 "register_operand" "r")))
5822 (match_operand:DI 3 "register_operand" "0")))]
5823 "TARGET_SPARCLET"
5824 "smacd\t%1, %2, %L0"
5825 [(set_attr "type" "imul")])
5826
5827 (define_insn "*umacdi"
5828 [(set (match_operand:DI 0 "register_operand" "=r")
5829 (plus:DI (mult:DI (zero_extend:DI
5830 (match_operand:SI 1 "register_operand" "%r"))
5831 (zero_extend:DI
5832 (match_operand:SI 2 "register_operand" "r")))
5833 (match_operand:DI 3 "register_operand" "0")))]
5834 "TARGET_SPARCLET"
5835 "umacd\t%1, %2, %L0"
5836 [(set_attr "type" "imul")])
5837 \f
5838 ;;- Boolean instructions
5839 ;; We define DImode `and' so with DImode `not' we can get
5840 ;; DImode `andn'. Other combinations are possible.
5841
5842 (define_expand "anddi3"
5843 [(set (match_operand:DI 0 "register_operand" "")
5844 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5845 (match_operand:DI 2 "arith_double_operand" "")))]
5846 ""
5847 "")
5848
5849 (define_insn "*anddi3_sp32"
5850 [(set (match_operand:DI 0 "register_operand" "=r,b")
5851 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5852 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5853 "! TARGET_ARCH64"
5854 "@
5855 #
5856 fand\t%1, %2, %0"
5857 [(set_attr "type" "*,fga")
5858 (set_attr "length" "2,*")
5859 (set_attr "fptype" "double")])
5860
5861 (define_insn "*anddi3_sp64"
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 and\t%1, %2, %0
5868 fand\t%1, %2, %0"
5869 [(set_attr "type" "*,fga")
5870 (set_attr "fptype" "double")])
5871
5872 (define_insn "andsi3"
5873 [(set (match_operand:SI 0 "register_operand" "=r,d")
5874 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5875 (match_operand:SI 2 "arith_operand" "rI,d")))]
5876 ""
5877 "@
5878 and\t%1, %2, %0
5879 fands\t%1, %2, %0"
5880 [(set_attr "type" "*,fga")])
5881
5882 (define_split
5883 [(set (match_operand:SI 0 "register_operand" "")
5884 (and:SI (match_operand:SI 1 "register_operand" "")
5885 (match_operand:SI 2 "" "")))
5886 (clobber (match_operand:SI 3 "register_operand" ""))]
5887 "GET_CODE (operands[2]) == CONST_INT
5888 && !SMALL_INT32 (operands[2])
5889 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5890 [(set (match_dup 3) (match_dup 4))
5891 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5892 {
5893 operands[4] = GEN_INT (~INTVAL (operands[2]));
5894 })
5895
5896 ;; Split DImode logical operations requiring two instructions.
5897 (define_split
5898 [(set (match_operand:DI 0 "register_operand" "")
5899 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5900 [(match_operand:DI 2 "register_operand" "")
5901 (match_operand:DI 3 "arith_double_operand" "")]))]
5902 "! TARGET_ARCH64
5903 && reload_completed
5904 && ((GET_CODE (operands[0]) == REG
5905 && REGNO (operands[0]) < 32)
5906 || (GET_CODE (operands[0]) == SUBREG
5907 && GET_CODE (SUBREG_REG (operands[0])) == REG
5908 && REGNO (SUBREG_REG (operands[0])) < 32))"
5909 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5910 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5911 {
5912 operands[4] = gen_highpart (SImode, operands[0]);
5913 operands[5] = gen_lowpart (SImode, operands[0]);
5914 operands[6] = gen_highpart (SImode, operands[2]);
5915 operands[7] = gen_lowpart (SImode, operands[2]);
5916 #if HOST_BITS_PER_WIDE_INT == 32
5917 if (GET_CODE (operands[3]) == CONST_INT)
5918 {
5919 if (INTVAL (operands[3]) < 0)
5920 operands[8] = constm1_rtx;
5921 else
5922 operands[8] = const0_rtx;
5923 }
5924 else
5925 #endif
5926 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5927 operands[9] = gen_lowpart (SImode, operands[3]);
5928 })
5929
5930 (define_insn_and_split "*and_not_di_sp32"
5931 [(set (match_operand:DI 0 "register_operand" "=r,b")
5932 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5933 (match_operand:DI 2 "register_operand" "r,b")))]
5934 "! TARGET_ARCH64"
5935 "@
5936 #
5937 fandnot1\t%1, %2, %0"
5938 "&& reload_completed
5939 && ((GET_CODE (operands[0]) == REG
5940 && REGNO (operands[0]) < 32)
5941 || (GET_CODE (operands[0]) == SUBREG
5942 && GET_CODE (SUBREG_REG (operands[0])) == REG
5943 && REGNO (SUBREG_REG (operands[0])) < 32))"
5944 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5945 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5946 "operands[3] = gen_highpart (SImode, operands[0]);
5947 operands[4] = gen_highpart (SImode, operands[1]);
5948 operands[5] = gen_highpart (SImode, operands[2]);
5949 operands[6] = gen_lowpart (SImode, operands[0]);
5950 operands[7] = gen_lowpart (SImode, operands[1]);
5951 operands[8] = gen_lowpart (SImode, operands[2]);"
5952 [(set_attr "type" "*,fga")
5953 (set_attr "length" "2,*")
5954 (set_attr "fptype" "double")])
5955
5956 (define_insn "*and_not_di_sp64"
5957 [(set (match_operand:DI 0 "register_operand" "=r,b")
5958 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5959 (match_operand:DI 2 "register_operand" "r,b")))]
5960 "TARGET_ARCH64"
5961 "@
5962 andn\t%2, %1, %0
5963 fandnot1\t%1, %2, %0"
5964 [(set_attr "type" "*,fga")
5965 (set_attr "fptype" "double")])
5966
5967 (define_insn "*and_not_si"
5968 [(set (match_operand:SI 0 "register_operand" "=r,d")
5969 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5970 (match_operand:SI 2 "register_operand" "r,d")))]
5971 ""
5972 "@
5973 andn\t%2, %1, %0
5974 fandnot1s\t%1, %2, %0"
5975 [(set_attr "type" "*,fga")])
5976
5977 (define_expand "iordi3"
5978 [(set (match_operand:DI 0 "register_operand" "")
5979 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5980 (match_operand:DI 2 "arith_double_operand" "")))]
5981 ""
5982 "")
5983
5984 (define_insn "*iordi3_sp32"
5985 [(set (match_operand:DI 0 "register_operand" "=r,b")
5986 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5987 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5988 "! TARGET_ARCH64"
5989 "@
5990 #
5991 for\t%1, %2, %0"
5992 [(set_attr "type" "*,fga")
5993 (set_attr "length" "2,*")
5994 (set_attr "fptype" "double")])
5995
5996 (define_insn "*iordi3_sp64"
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 or\t%1, %2, %0
6003 for\t%1, %2, %0"
6004 [(set_attr "type" "*,fga")
6005 (set_attr "fptype" "double")])
6006
6007 (define_insn "iorsi3"
6008 [(set (match_operand:SI 0 "register_operand" "=r,d")
6009 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6010 (match_operand:SI 2 "arith_operand" "rI,d")))]
6011 ""
6012 "@
6013 or\t%1, %2, %0
6014 fors\t%1, %2, %0"
6015 [(set_attr "type" "*,fga")])
6016
6017 (define_split
6018 [(set (match_operand:SI 0 "register_operand" "")
6019 (ior:SI (match_operand:SI 1 "register_operand" "")
6020 (match_operand:SI 2 "" "")))
6021 (clobber (match_operand:SI 3 "register_operand" ""))]
6022 "GET_CODE (operands[2]) == CONST_INT
6023 && !SMALL_INT32 (operands[2])
6024 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6025 [(set (match_dup 3) (match_dup 4))
6026 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6027 {
6028 operands[4] = GEN_INT (~INTVAL (operands[2]));
6029 })
6030
6031 (define_insn_and_split "*or_not_di_sp32"
6032 [(set (match_operand:DI 0 "register_operand" "=r,b")
6033 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6034 (match_operand:DI 2 "register_operand" "r,b")))]
6035 "! TARGET_ARCH64"
6036 "@
6037 #
6038 fornot1\t%1, %2, %0"
6039 "&& reload_completed
6040 && ((GET_CODE (operands[0]) == REG
6041 && REGNO (operands[0]) < 32)
6042 || (GET_CODE (operands[0]) == SUBREG
6043 && GET_CODE (SUBREG_REG (operands[0])) == REG
6044 && REGNO (SUBREG_REG (operands[0])) < 32))"
6045 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6046 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6047 "operands[3] = gen_highpart (SImode, operands[0]);
6048 operands[4] = gen_highpart (SImode, operands[1]);
6049 operands[5] = gen_highpart (SImode, operands[2]);
6050 operands[6] = gen_lowpart (SImode, operands[0]);
6051 operands[7] = gen_lowpart (SImode, operands[1]);
6052 operands[8] = gen_lowpart (SImode, operands[2]);"
6053 [(set_attr "type" "*,fga")
6054 (set_attr "length" "2,*")
6055 (set_attr "fptype" "double")])
6056
6057 (define_insn "*or_not_di_sp64"
6058 [(set (match_operand:DI 0 "register_operand" "=r,b")
6059 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6060 (match_operand:DI 2 "register_operand" "r,b")))]
6061 "TARGET_ARCH64"
6062 "@
6063 orn\t%2, %1, %0
6064 fornot1\t%1, %2, %0"
6065 [(set_attr "type" "*,fga")
6066 (set_attr "fptype" "double")])
6067
6068 (define_insn "*or_not_si"
6069 [(set (match_operand:SI 0 "register_operand" "=r,d")
6070 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6071 (match_operand:SI 2 "register_operand" "r,d")))]
6072 ""
6073 "@
6074 orn\t%2, %1, %0
6075 fornot1s\t%1, %2, %0"
6076 [(set_attr "type" "*,fga")])
6077
6078 (define_expand "xordi3"
6079 [(set (match_operand:DI 0 "register_operand" "")
6080 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6081 (match_operand:DI 2 "arith_double_operand" "")))]
6082 ""
6083 "")
6084
6085 (define_insn "*xordi3_sp32"
6086 [(set (match_operand:DI 0 "register_operand" "=r,b")
6087 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6088 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6089 "! TARGET_ARCH64"
6090 "@
6091 #
6092 fxor\t%1, %2, %0"
6093 [(set_attr "type" "*,fga")
6094 (set_attr "length" "2,*")
6095 (set_attr "fptype" "double")])
6096
6097 (define_insn "*xordi3_sp64"
6098 [(set (match_operand:DI 0 "register_operand" "=r,b")
6099 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6100 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6101 "TARGET_ARCH64"
6102 "@
6103 xor\t%r1, %2, %0
6104 fxor\t%1, %2, %0"
6105 [(set_attr "type" "*,fga")
6106 (set_attr "fptype" "double")])
6107
6108 (define_insn "*xordi3_sp64_dbl"
6109 [(set (match_operand:DI 0 "register_operand" "=r")
6110 (xor:DI (match_operand:DI 1 "register_operand" "r")
6111 (match_operand:DI 2 "const64_operand" "")))]
6112 "(TARGET_ARCH64
6113 && HOST_BITS_PER_WIDE_INT != 64)"
6114 "xor\t%1, %2, %0")
6115
6116 (define_insn "xorsi3"
6117 [(set (match_operand:SI 0 "register_operand" "=r,d")
6118 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6119 (match_operand:SI 2 "arith_operand" "rI,d")))]
6120 ""
6121 "@
6122 xor\t%r1, %2, %0
6123 fxors\t%1, %2, %0"
6124 [(set_attr "type" "*,fga")])
6125
6126 (define_split
6127 [(set (match_operand:SI 0 "register_operand" "")
6128 (xor:SI (match_operand:SI 1 "register_operand" "")
6129 (match_operand:SI 2 "" "")))
6130 (clobber (match_operand:SI 3 "register_operand" ""))]
6131 "GET_CODE (operands[2]) == CONST_INT
6132 && !SMALL_INT32 (operands[2])
6133 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6134 [(set (match_dup 3) (match_dup 4))
6135 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6136 {
6137 operands[4] = GEN_INT (~INTVAL (operands[2]));
6138 })
6139
6140 (define_split
6141 [(set (match_operand:SI 0 "register_operand" "")
6142 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6143 (match_operand:SI 2 "" ""))))
6144 (clobber (match_operand:SI 3 "register_operand" ""))]
6145 "GET_CODE (operands[2]) == CONST_INT
6146 && !SMALL_INT32 (operands[2])
6147 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6148 [(set (match_dup 3) (match_dup 4))
6149 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6150 {
6151 operands[4] = GEN_INT (~INTVAL (operands[2]));
6152 })
6153
6154 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6155 ;; Combine now canonicalizes to the rightmost expression.
6156 (define_insn_and_split "*xor_not_di_sp32"
6157 [(set (match_operand:DI 0 "register_operand" "=r,b")
6158 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6159 (match_operand:DI 2 "register_operand" "r,b"))))]
6160 "! TARGET_ARCH64"
6161 "@
6162 #
6163 fxnor\t%1, %2, %0"
6164 "&& reload_completed
6165 && ((GET_CODE (operands[0]) == REG
6166 && REGNO (operands[0]) < 32)
6167 || (GET_CODE (operands[0]) == SUBREG
6168 && GET_CODE (SUBREG_REG (operands[0])) == REG
6169 && REGNO (SUBREG_REG (operands[0])) < 32))"
6170 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6171 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6172 "operands[3] = gen_highpart (SImode, operands[0]);
6173 operands[4] = gen_highpart (SImode, operands[1]);
6174 operands[5] = gen_highpart (SImode, operands[2]);
6175 operands[6] = gen_lowpart (SImode, operands[0]);
6176 operands[7] = gen_lowpart (SImode, operands[1]);
6177 operands[8] = gen_lowpart (SImode, operands[2]);"
6178 [(set_attr "type" "*,fga")
6179 (set_attr "length" "2,*")
6180 (set_attr "fptype" "double")])
6181
6182 (define_insn "*xor_not_di_sp64"
6183 [(set (match_operand:DI 0 "register_operand" "=r,b")
6184 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6185 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6186 "TARGET_ARCH64"
6187 "@
6188 xnor\t%r1, %2, %0
6189 fxnor\t%1, %2, %0"
6190 [(set_attr "type" "*,fga")
6191 (set_attr "fptype" "double")])
6192
6193 (define_insn "*xor_not_si"
6194 [(set (match_operand:SI 0 "register_operand" "=r,d")
6195 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6196 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6197 ""
6198 "@
6199 xnor\t%r1, %2, %0
6200 fxnors\t%1, %2, %0"
6201 [(set_attr "type" "*,fga")])
6202
6203 ;; These correspond to the above in the case where we also (or only)
6204 ;; want to set the condition code.
6205
6206 (define_insn "*cmp_cc_arith_op"
6207 [(set (reg:CC 100)
6208 (compare:CC
6209 (match_operator:SI 2 "cc_arithop"
6210 [(match_operand:SI 0 "arith_operand" "%r")
6211 (match_operand:SI 1 "arith_operand" "rI")])
6212 (const_int 0)))]
6213 ""
6214 "%A2cc\t%0, %1, %%g0"
6215 [(set_attr "type" "compare")])
6216
6217 (define_insn "*cmp_ccx_arith_op"
6218 [(set (reg:CCX 100)
6219 (compare:CCX
6220 (match_operator:DI 2 "cc_arithop"
6221 [(match_operand:DI 0 "arith_double_operand" "%r")
6222 (match_operand:DI 1 "arith_double_operand" "rHI")])
6223 (const_int 0)))]
6224 "TARGET_ARCH64"
6225 "%A2cc\t%0, %1, %%g0"
6226 [(set_attr "type" "compare")])
6227
6228 (define_insn "*cmp_cc_arith_op_set"
6229 [(set (reg:CC 100)
6230 (compare:CC
6231 (match_operator:SI 3 "cc_arithop"
6232 [(match_operand:SI 1 "arith_operand" "%r")
6233 (match_operand:SI 2 "arith_operand" "rI")])
6234 (const_int 0)))
6235 (set (match_operand:SI 0 "register_operand" "=r")
6236 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6237 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6238 "%A3cc\t%1, %2, %0"
6239 [(set_attr "type" "compare")])
6240
6241 (define_insn "*cmp_ccx_arith_op_set"
6242 [(set (reg:CCX 100)
6243 (compare:CCX
6244 (match_operator:DI 3 "cc_arithop"
6245 [(match_operand:DI 1 "arith_double_operand" "%r")
6246 (match_operand:DI 2 "arith_double_operand" "rHI")])
6247 (const_int 0)))
6248 (set (match_operand:DI 0 "register_operand" "=r")
6249 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6250 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6251 "%A3cc\t%1, %2, %0"
6252 [(set_attr "type" "compare")])
6253
6254 (define_insn "*cmp_cc_xor_not"
6255 [(set (reg:CC 100)
6256 (compare:CC
6257 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6258 (match_operand:SI 1 "arith_operand" "rI")))
6259 (const_int 0)))]
6260 ""
6261 "xnorcc\t%r0, %1, %%g0"
6262 [(set_attr "type" "compare")])
6263
6264 (define_insn "*cmp_ccx_xor_not"
6265 [(set (reg:CCX 100)
6266 (compare:CCX
6267 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6268 (match_operand:DI 1 "arith_double_operand" "rHI")))
6269 (const_int 0)))]
6270 "TARGET_ARCH64"
6271 "xnorcc\t%r0, %1, %%g0"
6272 [(set_attr "type" "compare")])
6273
6274 (define_insn "*cmp_cc_xor_not_set"
6275 [(set (reg:CC 100)
6276 (compare:CC
6277 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6278 (match_operand:SI 2 "arith_operand" "rI")))
6279 (const_int 0)))
6280 (set (match_operand:SI 0 "register_operand" "=r")
6281 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6282 ""
6283 "xnorcc\t%r1, %2, %0"
6284 [(set_attr "type" "compare")])
6285
6286 (define_insn "*cmp_ccx_xor_not_set"
6287 [(set (reg:CCX 100)
6288 (compare:CCX
6289 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6290 (match_operand:DI 2 "arith_double_operand" "rHI")))
6291 (const_int 0)))
6292 (set (match_operand:DI 0 "register_operand" "=r")
6293 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6294 "TARGET_ARCH64"
6295 "xnorcc\t%r1, %2, %0"
6296 [(set_attr "type" "compare")])
6297
6298 (define_insn "*cmp_cc_arith_op_not"
6299 [(set (reg:CC 100)
6300 (compare:CC
6301 (match_operator:SI 2 "cc_arithopn"
6302 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6303 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6304 (const_int 0)))]
6305 ""
6306 "%B2cc\t%r1, %0, %%g0"
6307 [(set_attr "type" "compare")])
6308
6309 (define_insn "*cmp_ccx_arith_op_not"
6310 [(set (reg:CCX 100)
6311 (compare:CCX
6312 (match_operator:DI 2 "cc_arithopn"
6313 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6314 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6315 (const_int 0)))]
6316 "TARGET_ARCH64"
6317 "%B2cc\t%r1, %0, %%g0"
6318 [(set_attr "type" "compare")])
6319
6320 (define_insn "*cmp_cc_arith_op_not_set"
6321 [(set (reg:CC 100)
6322 (compare:CC
6323 (match_operator:SI 3 "cc_arithopn"
6324 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6325 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6326 (const_int 0)))
6327 (set (match_operand:SI 0 "register_operand" "=r")
6328 (match_operator:SI 4 "cc_arithopn"
6329 [(not:SI (match_dup 1)) (match_dup 2)]))]
6330 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6331 "%B3cc\t%r2, %1, %0"
6332 [(set_attr "type" "compare")])
6333
6334 (define_insn "*cmp_ccx_arith_op_not_set"
6335 [(set (reg:CCX 100)
6336 (compare:CCX
6337 (match_operator:DI 3 "cc_arithopn"
6338 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6339 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6340 (const_int 0)))
6341 (set (match_operand:DI 0 "register_operand" "=r")
6342 (match_operator:DI 4 "cc_arithopn"
6343 [(not:DI (match_dup 1)) (match_dup 2)]))]
6344 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6345 "%B3cc\t%r2, %1, %0"
6346 [(set_attr "type" "compare")])
6347
6348 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6349 ;; does not know how to make it work for constants.
6350
6351 (define_expand "negdi2"
6352 [(set (match_operand:DI 0 "register_operand" "=r")
6353 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6354 ""
6355 {
6356 if (! TARGET_ARCH64)
6357 {
6358 emit_insn (gen_rtx_PARALLEL
6359 (VOIDmode,
6360 gen_rtvec (2,
6361 gen_rtx_SET (VOIDmode, operand0,
6362 gen_rtx_NEG (DImode, operand1)),
6363 gen_rtx_CLOBBER (VOIDmode,
6364 gen_rtx_REG (CCmode,
6365 SPARC_ICC_REG)))));
6366 DONE;
6367 }
6368 })
6369
6370 (define_insn_and_split "*negdi2_sp32"
6371 [(set (match_operand:DI 0 "register_operand" "=r")
6372 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6373 (clobber (reg:CC 100))]
6374 "TARGET_ARCH32"
6375 "#"
6376 "&& reload_completed"
6377 [(parallel [(set (reg:CC_NOOV 100)
6378 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6379 (const_int 0)))
6380 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6381 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6382 (ltu:SI (reg:CC 100) (const_int 0))))]
6383 "operands[2] = gen_highpart (SImode, operands[0]);
6384 operands[3] = gen_highpart (SImode, operands[1]);
6385 operands[4] = gen_lowpart (SImode, operands[0]);
6386 operands[5] = gen_lowpart (SImode, operands[1]);"
6387 [(set_attr "length" "2")])
6388
6389 (define_insn "*negdi2_sp64"
6390 [(set (match_operand:DI 0 "register_operand" "=r")
6391 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6392 "TARGET_ARCH64"
6393 "sub\t%%g0, %1, %0")
6394
6395 (define_insn "negsi2"
6396 [(set (match_operand:SI 0 "register_operand" "=r")
6397 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6398 ""
6399 "sub\t%%g0, %1, %0")
6400
6401 (define_insn "*cmp_cc_neg"
6402 [(set (reg:CC_NOOV 100)
6403 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6404 (const_int 0)))]
6405 ""
6406 "subcc\t%%g0, %0, %%g0"
6407 [(set_attr "type" "compare")])
6408
6409 (define_insn "*cmp_ccx_neg"
6410 [(set (reg:CCX_NOOV 100)
6411 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6412 (const_int 0)))]
6413 "TARGET_ARCH64"
6414 "subcc\t%%g0, %0, %%g0"
6415 [(set_attr "type" "compare")])
6416
6417 (define_insn "*cmp_cc_set_neg"
6418 [(set (reg:CC_NOOV 100)
6419 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6420 (const_int 0)))
6421 (set (match_operand:SI 0 "register_operand" "=r")
6422 (neg:SI (match_dup 1)))]
6423 ""
6424 "subcc\t%%g0, %1, %0"
6425 [(set_attr "type" "compare")])
6426
6427 (define_insn "*cmp_ccx_set_neg"
6428 [(set (reg:CCX_NOOV 100)
6429 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6430 (const_int 0)))
6431 (set (match_operand:DI 0 "register_operand" "=r")
6432 (neg:DI (match_dup 1)))]
6433 "TARGET_ARCH64"
6434 "subcc\t%%g0, %1, %0"
6435 [(set_attr "type" "compare")])
6436
6437 ;; We cannot use the "not" pseudo insn because the Sun assembler
6438 ;; does not know how to make it work for constants.
6439 (define_expand "one_cmpldi2"
6440 [(set (match_operand:DI 0 "register_operand" "")
6441 (not:DI (match_operand:DI 1 "register_operand" "")))]
6442 ""
6443 "")
6444
6445 (define_insn_and_split "*one_cmpldi2_sp32"
6446 [(set (match_operand:DI 0 "register_operand" "=r,b")
6447 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6448 "! TARGET_ARCH64"
6449 "@
6450 #
6451 fnot1\t%1, %0"
6452 "&& reload_completed
6453 && ((GET_CODE (operands[0]) == REG
6454 && REGNO (operands[0]) < 32)
6455 || (GET_CODE (operands[0]) == SUBREG
6456 && GET_CODE (SUBREG_REG (operands[0])) == REG
6457 && REGNO (SUBREG_REG (operands[0])) < 32))"
6458 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6459 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6460 "operands[2] = gen_highpart (SImode, operands[0]);
6461 operands[3] = gen_highpart (SImode, operands[1]);
6462 operands[4] = gen_lowpart (SImode, operands[0]);
6463 operands[5] = gen_lowpart (SImode, operands[1]);"
6464 [(set_attr "type" "*,fga")
6465 (set_attr "length" "2,*")
6466 (set_attr "fptype" "double")])
6467
6468 (define_insn "*one_cmpldi2_sp64"
6469 [(set (match_operand:DI 0 "register_operand" "=r,b")
6470 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6471 "TARGET_ARCH64"
6472 "@
6473 xnor\t%%g0, %1, %0
6474 fnot1\t%1, %0"
6475 [(set_attr "type" "*,fga")
6476 (set_attr "fptype" "double")])
6477
6478 (define_insn "one_cmplsi2"
6479 [(set (match_operand:SI 0 "register_operand" "=r,d")
6480 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6481 ""
6482 "@
6483 xnor\t%%g0, %1, %0
6484 fnot1s\t%1, %0"
6485 [(set_attr "type" "*,fga")])
6486
6487 (define_insn "*cmp_cc_not"
6488 [(set (reg:CC 100)
6489 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6490 (const_int 0)))]
6491 ""
6492 "xnorcc\t%%g0, %0, %%g0"
6493 [(set_attr "type" "compare")])
6494
6495 (define_insn "*cmp_ccx_not"
6496 [(set (reg:CCX 100)
6497 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6498 (const_int 0)))]
6499 "TARGET_ARCH64"
6500 "xnorcc\t%%g0, %0, %%g0"
6501 [(set_attr "type" "compare")])
6502
6503 (define_insn "*cmp_cc_set_not"
6504 [(set (reg:CC 100)
6505 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6506 (const_int 0)))
6507 (set (match_operand:SI 0 "register_operand" "=r")
6508 (not:SI (match_dup 1)))]
6509 ""
6510 "xnorcc\t%%g0, %1, %0"
6511 [(set_attr "type" "compare")])
6512
6513 (define_insn "*cmp_ccx_set_not"
6514 [(set (reg:CCX 100)
6515 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6516 (const_int 0)))
6517 (set (match_operand:DI 0 "register_operand" "=r")
6518 (not:DI (match_dup 1)))]
6519 "TARGET_ARCH64"
6520 "xnorcc\t%%g0, %1, %0"
6521 [(set_attr "type" "compare")])
6522
6523 (define_insn "*cmp_cc_set"
6524 [(set (match_operand:SI 0 "register_operand" "=r")
6525 (match_operand:SI 1 "register_operand" "r"))
6526 (set (reg:CC 100)
6527 (compare:CC (match_dup 1)
6528 (const_int 0)))]
6529 ""
6530 "orcc\t%1, 0, %0"
6531 [(set_attr "type" "compare")])
6532
6533 (define_insn "*cmp_ccx_set64"
6534 [(set (match_operand:DI 0 "register_operand" "=r")
6535 (match_operand:DI 1 "register_operand" "r"))
6536 (set (reg:CCX 100)
6537 (compare:CCX (match_dup 1)
6538 (const_int 0)))]
6539 "TARGET_ARCH64"
6540 "orcc\t%1, 0, %0"
6541 [(set_attr "type" "compare")])
6542 \f
6543 ;; Floating point arithmetic instructions.
6544
6545 (define_expand "addtf3"
6546 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6547 (plus:TF (match_operand:TF 1 "general_operand" "")
6548 (match_operand:TF 2 "general_operand" "")))]
6549 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6550 "emit_tfmode_binop (PLUS, operands); DONE;")
6551
6552 (define_insn "*addtf3_hq"
6553 [(set (match_operand:TF 0 "register_operand" "=e")
6554 (plus:TF (match_operand:TF 1 "register_operand" "e")
6555 (match_operand:TF 2 "register_operand" "e")))]
6556 "TARGET_FPU && TARGET_HARD_QUAD"
6557 "faddq\t%1, %2, %0"
6558 [(set_attr "type" "fp")])
6559
6560 (define_insn "adddf3"
6561 [(set (match_operand:DF 0 "register_operand" "=e")
6562 (plus:DF (match_operand:DF 1 "register_operand" "e")
6563 (match_operand:DF 2 "register_operand" "e")))]
6564 "TARGET_FPU"
6565 "faddd\t%1, %2, %0"
6566 [(set_attr "type" "fp")
6567 (set_attr "fptype" "double")])
6568
6569 (define_insn "addsf3"
6570 [(set (match_operand:SF 0 "register_operand" "=f")
6571 (plus:SF (match_operand:SF 1 "register_operand" "f")
6572 (match_operand:SF 2 "register_operand" "f")))]
6573 "TARGET_FPU"
6574 "fadds\t%1, %2, %0"
6575 [(set_attr "type" "fp")])
6576
6577 (define_expand "subtf3"
6578 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6579 (minus:TF (match_operand:TF 1 "general_operand" "")
6580 (match_operand:TF 2 "general_operand" "")))]
6581 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6582 "emit_tfmode_binop (MINUS, operands); DONE;")
6583
6584 (define_insn "*subtf3_hq"
6585 [(set (match_operand:TF 0 "register_operand" "=e")
6586 (minus:TF (match_operand:TF 1 "register_operand" "e")
6587 (match_operand:TF 2 "register_operand" "e")))]
6588 "TARGET_FPU && TARGET_HARD_QUAD"
6589 "fsubq\t%1, %2, %0"
6590 [(set_attr "type" "fp")])
6591
6592 (define_insn "subdf3"
6593 [(set (match_operand:DF 0 "register_operand" "=e")
6594 (minus:DF (match_operand:DF 1 "register_operand" "e")
6595 (match_operand:DF 2 "register_operand" "e")))]
6596 "TARGET_FPU"
6597 "fsubd\t%1, %2, %0"
6598 [(set_attr "type" "fp")
6599 (set_attr "fptype" "double")])
6600
6601 (define_insn "subsf3"
6602 [(set (match_operand:SF 0 "register_operand" "=f")
6603 (minus:SF (match_operand:SF 1 "register_operand" "f")
6604 (match_operand:SF 2 "register_operand" "f")))]
6605 "TARGET_FPU"
6606 "fsubs\t%1, %2, %0"
6607 [(set_attr "type" "fp")])
6608
6609 (define_expand "multf3"
6610 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6611 (mult:TF (match_operand:TF 1 "general_operand" "")
6612 (match_operand:TF 2 "general_operand" "")))]
6613 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6614 "emit_tfmode_binop (MULT, operands); DONE;")
6615
6616 (define_insn "*multf3_hq"
6617 [(set (match_operand:TF 0 "register_operand" "=e")
6618 (mult:TF (match_operand:TF 1 "register_operand" "e")
6619 (match_operand:TF 2 "register_operand" "e")))]
6620 "TARGET_FPU && TARGET_HARD_QUAD"
6621 "fmulq\t%1, %2, %0"
6622 [(set_attr "type" "fpmul")])
6623
6624 (define_insn "muldf3"
6625 [(set (match_operand:DF 0 "register_operand" "=e")
6626 (mult:DF (match_operand:DF 1 "register_operand" "e")
6627 (match_operand:DF 2 "register_operand" "e")))]
6628 "TARGET_FPU"
6629 "fmuld\t%1, %2, %0"
6630 [(set_attr "type" "fpmul")
6631 (set_attr "fptype" "double")])
6632
6633 (define_insn "mulsf3"
6634 [(set (match_operand:SF 0 "register_operand" "=f")
6635 (mult:SF (match_operand:SF 1 "register_operand" "f")
6636 (match_operand:SF 2 "register_operand" "f")))]
6637 "TARGET_FPU"
6638 "fmuls\t%1, %2, %0"
6639 [(set_attr "type" "fpmul")])
6640
6641 (define_insn "*muldf3_extend"
6642 [(set (match_operand:DF 0 "register_operand" "=e")
6643 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6644 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6645 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6646 "fsmuld\t%1, %2, %0"
6647 [(set_attr "type" "fpmul")
6648 (set_attr "fptype" "double")])
6649
6650 (define_insn "*multf3_extend"
6651 [(set (match_operand:TF 0 "register_operand" "=e")
6652 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6653 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6654 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6655 "fdmulq\t%1, %2, %0"
6656 [(set_attr "type" "fpmul")])
6657
6658 (define_expand "divtf3"
6659 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6660 (div:TF (match_operand:TF 1 "general_operand" "")
6661 (match_operand:TF 2 "general_operand" "")))]
6662 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6663 "emit_tfmode_binop (DIV, operands); DONE;")
6664
6665 ;; don't have timing for quad-prec. divide.
6666 (define_insn "*divtf3_hq"
6667 [(set (match_operand:TF 0 "register_operand" "=e")
6668 (div:TF (match_operand:TF 1 "register_operand" "e")
6669 (match_operand:TF 2 "register_operand" "e")))]
6670 "TARGET_FPU && TARGET_HARD_QUAD"
6671 "fdivq\t%1, %2, %0"
6672 [(set_attr "type" "fpdivd")])
6673
6674 (define_insn "divdf3"
6675 [(set (match_operand:DF 0 "register_operand" "=e")
6676 (div:DF (match_operand:DF 1 "register_operand" "e")
6677 (match_operand:DF 2 "register_operand" "e")))]
6678 "TARGET_FPU"
6679 "fdivd\t%1, %2, %0"
6680 [(set_attr "type" "fpdivd")
6681 (set_attr "fptype" "double")])
6682
6683 (define_insn "divsf3"
6684 [(set (match_operand:SF 0 "register_operand" "=f")
6685 (div:SF (match_operand:SF 1 "register_operand" "f")
6686 (match_operand:SF 2 "register_operand" "f")))]
6687 "TARGET_FPU"
6688 "fdivs\t%1, %2, %0"
6689 [(set_attr "type" "fpdivs")])
6690
6691 (define_expand "negtf2"
6692 [(set (match_operand:TF 0 "register_operand" "=e,e")
6693 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6694 "TARGET_FPU"
6695 "")
6696
6697 (define_insn_and_split "*negtf2_notv9"
6698 [(set (match_operand:TF 0 "register_operand" "=e,e")
6699 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6700 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6701 "TARGET_FPU
6702 && ! TARGET_V9"
6703 "@
6704 fnegs\t%0, %0
6705 #"
6706 "&& reload_completed
6707 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6708 [(set (match_dup 2) (neg:SF (match_dup 3)))
6709 (set (match_dup 4) (match_dup 5))
6710 (set (match_dup 6) (match_dup 7))]
6711 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6712 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6713 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6714 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6715 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6716 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6717 [(set_attr "type" "fpmove,*")
6718 (set_attr "length" "*,2")])
6719
6720 (define_insn_and_split "*negtf2_v9"
6721 [(set (match_operand:TF 0 "register_operand" "=e,e")
6722 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6723 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6724 "TARGET_FPU && TARGET_V9"
6725 "@
6726 fnegd\t%0, %0
6727 #"
6728 "&& reload_completed
6729 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6730 [(set (match_dup 2) (neg:DF (match_dup 3)))
6731 (set (match_dup 4) (match_dup 5))]
6732 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6733 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6734 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6735 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6736 [(set_attr "type" "fpmove,*")
6737 (set_attr "length" "*,2")
6738 (set_attr "fptype" "double")])
6739
6740 (define_expand "negdf2"
6741 [(set (match_operand:DF 0 "register_operand" "")
6742 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6743 "TARGET_FPU"
6744 "")
6745
6746 (define_insn_and_split "*negdf2_notv9"
6747 [(set (match_operand:DF 0 "register_operand" "=e,e")
6748 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6749 "TARGET_FPU && ! TARGET_V9"
6750 "@
6751 fnegs\t%0, %0
6752 #"
6753 "&& reload_completed
6754 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6755 [(set (match_dup 2) (neg:SF (match_dup 3)))
6756 (set (match_dup 4) (match_dup 5))]
6757 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6758 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6759 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6760 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6761 [(set_attr "type" "fpmove,*")
6762 (set_attr "length" "*,2")])
6763
6764 (define_insn "*negdf2_v9"
6765 [(set (match_operand:DF 0 "register_operand" "=e")
6766 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6767 "TARGET_FPU && TARGET_V9"
6768 "fnegd\t%1, %0"
6769 [(set_attr "type" "fpmove")
6770 (set_attr "fptype" "double")])
6771
6772 (define_insn "negsf2"
6773 [(set (match_operand:SF 0 "register_operand" "=f")
6774 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6775 "TARGET_FPU"
6776 "fnegs\t%1, %0"
6777 [(set_attr "type" "fpmove")])
6778
6779 (define_expand "abstf2"
6780 [(set (match_operand:TF 0 "register_operand" "")
6781 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6782 "TARGET_FPU"
6783 "")
6784
6785 (define_insn_and_split "*abstf2_notv9"
6786 [(set (match_operand:TF 0 "register_operand" "=e,e")
6787 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6788 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6789 "TARGET_FPU && ! TARGET_V9"
6790 "@
6791 fabss\t%0, %0
6792 #"
6793 "&& reload_completed
6794 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6795 [(set (match_dup 2) (abs:SF (match_dup 3)))
6796 (set (match_dup 4) (match_dup 5))
6797 (set (match_dup 6) (match_dup 7))]
6798 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6799 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6800 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6801 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6802 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6803 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6804 [(set_attr "type" "fpmove,*")
6805 (set_attr "length" "*,2")])
6806
6807 (define_insn "*abstf2_hq_v9"
6808 [(set (match_operand:TF 0 "register_operand" "=e,e")
6809 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6810 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6811 "@
6812 fabsd\t%0, %0
6813 fabsq\t%1, %0"
6814 [(set_attr "type" "fpmove")
6815 (set_attr "fptype" "double,*")])
6816
6817 (define_insn_and_split "*abstf2_v9"
6818 [(set (match_operand:TF 0 "register_operand" "=e,e")
6819 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6820 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6821 "@
6822 fabsd\t%0, %0
6823 #"
6824 "&& reload_completed
6825 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6826 [(set (match_dup 2) (abs:DF (match_dup 3)))
6827 (set (match_dup 4) (match_dup 5))]
6828 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6829 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6830 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6831 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6832 [(set_attr "type" "fpmove,*")
6833 (set_attr "length" "*,2")
6834 (set_attr "fptype" "double,*")])
6835
6836 (define_expand "absdf2"
6837 [(set (match_operand:DF 0 "register_operand" "")
6838 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6839 "TARGET_FPU"
6840 "")
6841
6842 (define_insn_and_split "*absdf2_notv9"
6843 [(set (match_operand:DF 0 "register_operand" "=e,e")
6844 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6845 "TARGET_FPU && ! TARGET_V9"
6846 "@
6847 fabss\t%0, %0
6848 #"
6849 "&& reload_completed
6850 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6851 [(set (match_dup 2) (abs:SF (match_dup 3)))
6852 (set (match_dup 4) (match_dup 5))]
6853 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6854 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6855 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6856 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6857 [(set_attr "type" "fpmove,*")
6858 (set_attr "length" "*,2")])
6859
6860 (define_insn "*absdf2_v9"
6861 [(set (match_operand:DF 0 "register_operand" "=e")
6862 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6863 "TARGET_FPU && TARGET_V9"
6864 "fabsd\t%1, %0"
6865 [(set_attr "type" "fpmove")
6866 (set_attr "fptype" "double")])
6867
6868 (define_insn "abssf2"
6869 [(set (match_operand:SF 0 "register_operand" "=f")
6870 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6871 "TARGET_FPU"
6872 "fabss\t%1, %0"
6873 [(set_attr "type" "fpmove")])
6874
6875 (define_expand "sqrttf2"
6876 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6877 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6878 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6879 "emit_tfmode_unop (SQRT, operands); DONE;")
6880
6881 (define_insn "*sqrttf2_hq"
6882 [(set (match_operand:TF 0 "register_operand" "=e")
6883 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6884 "TARGET_FPU && TARGET_HARD_QUAD"
6885 "fsqrtq\t%1, %0"
6886 [(set_attr "type" "fpsqrtd")])
6887
6888 (define_insn "sqrtdf2"
6889 [(set (match_operand:DF 0 "register_operand" "=e")
6890 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6891 "TARGET_FPU"
6892 "fsqrtd\t%1, %0"
6893 [(set_attr "type" "fpsqrtd")
6894 (set_attr "fptype" "double")])
6895
6896 (define_insn "sqrtsf2"
6897 [(set (match_operand:SF 0 "register_operand" "=f")
6898 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6899 "TARGET_FPU"
6900 "fsqrts\t%1, %0"
6901 [(set_attr "type" "fpsqrts")])
6902 \f
6903 ;;- arithmetic shift instructions
6904
6905 (define_insn "ashlsi3"
6906 [(set (match_operand:SI 0 "register_operand" "=r")
6907 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6908 (match_operand:SI 2 "arith_operand" "rI")))]
6909 ""
6910 {
6911 if (operands[2] == const1_rtx)
6912 return "add\t%1, %1, %0";
6913 if (GET_CODE (operands[2]) == CONST_INT)
6914 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6915 return "sll\t%1, %2, %0";
6916 }
6917 [(set (attr "type")
6918 (if_then_else (match_operand 2 "const1_operand" "")
6919 (const_string "ialu") (const_string "shift")))])
6920
6921 (define_expand "ashldi3"
6922 [(set (match_operand:DI 0 "register_operand" "=r")
6923 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6924 (match_operand:SI 2 "arith_operand" "rI")))]
6925 "TARGET_ARCH64 || TARGET_V8PLUS"
6926 {
6927 if (! TARGET_ARCH64)
6928 {
6929 if (GET_CODE (operands[2]) == CONST_INT)
6930 FAIL;
6931 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6932 DONE;
6933 }
6934 })
6935
6936 (define_insn "*ashldi3_sp64"
6937 [(set (match_operand:DI 0 "register_operand" "=r")
6938 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6939 (match_operand:SI 2 "arith_operand" "rI")))]
6940 "TARGET_ARCH64"
6941 {
6942 if (operands[2] == const1_rtx)
6943 return "add\t%1, %1, %0";
6944 if (GET_CODE (operands[2]) == CONST_INT)
6945 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6946 return "sllx\t%1, %2, %0";
6947 }
6948 [(set (attr "type")
6949 (if_then_else (match_operand 2 "const1_operand" "")
6950 (const_string "ialu") (const_string "shift")))])
6951
6952 ;; XXX UGH!
6953 (define_insn "ashldi3_v8plus"
6954 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6955 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6956 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6957 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6958 "TARGET_V8PLUS"
6959 { return sparc_v8plus_shift (operands, insn, "sllx"); }
6960 [(set_attr "type" "multi")
6961 (set_attr "length" "5,5,6")])
6962
6963 ;; Optimize (1LL<<x)-1
6964 ;; XXX this also needs to be fixed to handle equal subregs
6965 ;; XXX first before we could re-enable it.
6966 ;(define_insn ""
6967 ; [(set (match_operand:DI 0 "register_operand" "=h")
6968 ; (plus:DI (ashift:DI (const_int 1)
6969 ; (match_operand:SI 1 "arith_operand" "rI"))
6970 ; (const_int -1)))]
6971 ; "0 && TARGET_V8PLUS"
6972 ;{
6973 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6974 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6975 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6976 ;}
6977 ; [(set_attr "type" "multi")
6978 ; (set_attr "length" "4")])
6979
6980 (define_insn "*cmp_cc_ashift_1"
6981 [(set (reg:CC_NOOV 100)
6982 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6983 (const_int 1))
6984 (const_int 0)))]
6985 ""
6986 "addcc\t%0, %0, %%g0"
6987 [(set_attr "type" "compare")])
6988
6989 (define_insn "*cmp_cc_set_ashift_1"
6990 [(set (reg:CC_NOOV 100)
6991 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6992 (const_int 1))
6993 (const_int 0)))
6994 (set (match_operand:SI 0 "register_operand" "=r")
6995 (ashift:SI (match_dup 1) (const_int 1)))]
6996 ""
6997 "addcc\t%1, %1, %0"
6998 [(set_attr "type" "compare")])
6999
7000 (define_insn "ashrsi3"
7001 [(set (match_operand:SI 0 "register_operand" "=r")
7002 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7003 (match_operand:SI 2 "arith_operand" "rI")))]
7004 ""
7005 {
7006 if (GET_CODE (operands[2]) == CONST_INT)
7007 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7008 return "sra\t%1, %2, %0";
7009 }
7010 [(set_attr "type" "shift")])
7011
7012 (define_insn "*ashrsi3_extend"
7013 [(set (match_operand:DI 0 "register_operand" "=r")
7014 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7015 (match_operand:SI 2 "arith_operand" "r"))))]
7016 "TARGET_ARCH64"
7017 "sra\t%1, %2, %0"
7018 [(set_attr "type" "shift")])
7019
7020 ;; This handles the case as above, but with constant shift instead of
7021 ;; register. Combiner "simplifies" it for us a little bit though.
7022 (define_insn "*ashrsi3_extend2"
7023 [(set (match_operand:DI 0 "register_operand" "=r")
7024 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7025 (const_int 32))
7026 (match_operand:SI 2 "small_int_or_double" "n")))]
7027 "TARGET_ARCH64
7028 && ((GET_CODE (operands[2]) == CONST_INT
7029 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7030 || (GET_CODE (operands[2]) == CONST_DOUBLE
7031 && !CONST_DOUBLE_HIGH (operands[2])
7032 && CONST_DOUBLE_LOW (operands[2]) >= 32
7033 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7034 {
7035 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7036
7037 return "sra\t%1, %2, %0";
7038 }
7039 [(set_attr "type" "shift")])
7040
7041 (define_expand "ashrdi3"
7042 [(set (match_operand:DI 0 "register_operand" "=r")
7043 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7044 (match_operand:SI 2 "arith_operand" "rI")))]
7045 "TARGET_ARCH64 || TARGET_V8PLUS"
7046 {
7047 if (! TARGET_ARCH64)
7048 {
7049 if (GET_CODE (operands[2]) == CONST_INT)
7050 FAIL; /* prefer generic code in this case */
7051 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7052 DONE;
7053 }
7054 })
7055
7056 (define_insn "*ashrdi3_sp64"
7057 [(set (match_operand:DI 0 "register_operand" "=r")
7058 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7059 (match_operand:SI 2 "arith_operand" "rI")))]
7060 "TARGET_ARCH64"
7061
7062 {
7063 if (GET_CODE (operands[2]) == CONST_INT)
7064 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7065 return "srax\t%1, %2, %0";
7066 }
7067 [(set_attr "type" "shift")])
7068
7069 ;; XXX
7070 (define_insn "ashrdi3_v8plus"
7071 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7072 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7073 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7074 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7075 "TARGET_V8PLUS"
7076 { return sparc_v8plus_shift (operands, insn, "srax"); }
7077 [(set_attr "type" "multi")
7078 (set_attr "length" "5,5,6")])
7079
7080 (define_insn "lshrsi3"
7081 [(set (match_operand:SI 0 "register_operand" "=r")
7082 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7083 (match_operand:SI 2 "arith_operand" "rI")))]
7084 ""
7085 {
7086 if (GET_CODE (operands[2]) == CONST_INT)
7087 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7088 return "srl\t%1, %2, %0";
7089 }
7090 [(set_attr "type" "shift")])
7091
7092 ;; This handles the case where
7093 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7094 ;; but combiner "simplifies" it for us.
7095 (define_insn "*lshrsi3_extend"
7096 [(set (match_operand:DI 0 "register_operand" "=r")
7097 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7098 (match_operand:SI 2 "arith_operand" "r")) 0)
7099 (match_operand 3 "" "")))]
7100 "TARGET_ARCH64
7101 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7102 && CONST_DOUBLE_HIGH (operands[3]) == 0
7103 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7104 || (HOST_BITS_PER_WIDE_INT >= 64
7105 && GET_CODE (operands[3]) == CONST_INT
7106 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7107 "srl\t%1, %2, %0"
7108 [(set_attr "type" "shift")])
7109
7110 ;; This handles the case where
7111 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7112 ;; but combiner "simplifies" it for us.
7113 (define_insn "*lshrsi3_extend2"
7114 [(set (match_operand:DI 0 "register_operand" "=r")
7115 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7116 (match_operand 2 "small_int_or_double" "n")
7117 (const_int 32)))]
7118 "TARGET_ARCH64
7119 && ((GET_CODE (operands[2]) == CONST_INT
7120 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7121 || (GET_CODE (operands[2]) == CONST_DOUBLE
7122 && CONST_DOUBLE_HIGH (operands[2]) == 0
7123 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7124 {
7125 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7126
7127 return "srl\t%1, %2, %0";
7128 }
7129 [(set_attr "type" "shift")])
7130
7131 (define_expand "lshrdi3"
7132 [(set (match_operand:DI 0 "register_operand" "=r")
7133 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7134 (match_operand:SI 2 "arith_operand" "rI")))]
7135 "TARGET_ARCH64 || TARGET_V8PLUS"
7136 {
7137 if (! TARGET_ARCH64)
7138 {
7139 if (GET_CODE (operands[2]) == CONST_INT)
7140 FAIL;
7141 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7142 DONE;
7143 }
7144 })
7145
7146 (define_insn "*lshrdi3_sp64"
7147 [(set (match_operand:DI 0 "register_operand" "=r")
7148 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7149 (match_operand:SI 2 "arith_operand" "rI")))]
7150 "TARGET_ARCH64"
7151 {
7152 if (GET_CODE (operands[2]) == CONST_INT)
7153 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7154 return "srlx\t%1, %2, %0";
7155 }
7156 [(set_attr "type" "shift")])
7157
7158 ;; XXX
7159 (define_insn "lshrdi3_v8plus"
7160 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7161 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7162 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7163 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7164 "TARGET_V8PLUS"
7165 { return sparc_v8plus_shift (operands, insn, "srlx"); }
7166 [(set_attr "type" "multi")
7167 (set_attr "length" "5,5,6")])
7168
7169 (define_insn ""
7170 [(set (match_operand:SI 0 "register_operand" "=r")
7171 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7172 (const_int 32)) 4)
7173 (match_operand:SI 2 "small_int_or_double" "n")))]
7174 "TARGET_ARCH64
7175 && ((GET_CODE (operands[2]) == CONST_INT
7176 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7177 || (GET_CODE (operands[2]) == CONST_DOUBLE
7178 && !CONST_DOUBLE_HIGH (operands[2])
7179 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7180 {
7181 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7182
7183 return "srax\t%1, %2, %0";
7184 }
7185 [(set_attr "type" "shift")])
7186
7187 (define_insn ""
7188 [(set (match_operand:SI 0 "register_operand" "=r")
7189 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7190 (const_int 32)) 4)
7191 (match_operand:SI 2 "small_int_or_double" "n")))]
7192 "TARGET_ARCH64
7193 && ((GET_CODE (operands[2]) == CONST_INT
7194 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7195 || (GET_CODE (operands[2]) == CONST_DOUBLE
7196 && !CONST_DOUBLE_HIGH (operands[2])
7197 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7198 {
7199 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7200
7201 return "srlx\t%1, %2, %0";
7202 }
7203 [(set_attr "type" "shift")])
7204
7205 (define_insn ""
7206 [(set (match_operand:SI 0 "register_operand" "=r")
7207 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7208 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7209 (match_operand:SI 3 "small_int_or_double" "n")))]
7210 "TARGET_ARCH64
7211 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7212 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7213 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7214 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7215 {
7216 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7217
7218 return "srax\t%1, %2, %0";
7219 }
7220 [(set_attr "type" "shift")])
7221
7222 (define_insn ""
7223 [(set (match_operand:SI 0 "register_operand" "=r")
7224 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7225 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7226 (match_operand:SI 3 "small_int_or_double" "n")))]
7227 "TARGET_ARCH64
7228 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7229 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7230 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7231 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7232 {
7233 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7234
7235 return "srlx\t%1, %2, %0";
7236 }
7237 [(set_attr "type" "shift")])
7238 \f
7239 ;; Unconditional and other jump instructions
7240 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7241 ;; following insn is never executed. This saves us a nop. Dbx does not
7242 ;; handle such branches though, so we only use them when optimizing.
7243 (define_insn "jump"
7244 [(set (pc) (label_ref (match_operand 0 "" "")))]
7245 ""
7246 {
7247 /* TurboSPARC is reported to have problems with
7248 with
7249 foo: b,a foo
7250 i.e. an empty loop with the annul bit set. The workaround is to use
7251 foo: b foo; nop
7252 instead. */
7253
7254 if (! TARGET_V9 && flag_delayed_branch
7255 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7256 == INSN_ADDRESSES (INSN_UID (insn))))
7257 return "b\t%l0%#";
7258 else
7259 return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7260 }
7261 [(set_attr "type" "uncond_branch")])
7262
7263 (define_expand "tablejump"
7264 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7265 (use (label_ref (match_operand 1 "" "")))])]
7266 ""
7267 {
7268 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7269 abort ();
7270
7271 /* In pic mode, our address differences are against the base of the
7272 table. Add that base value back in; CSE ought to be able to combine
7273 the two address loads. */
7274 if (flag_pic)
7275 {
7276 rtx tmp, tmp2;
7277 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7278 tmp2 = operands[0];
7279 if (CASE_VECTOR_MODE != Pmode)
7280 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7281 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7282 operands[0] = memory_address (Pmode, tmp);
7283 }
7284 })
7285
7286 (define_insn "*tablejump_sp32"
7287 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7288 (use (label_ref (match_operand 1 "" "")))]
7289 "! TARGET_ARCH64"
7290 "jmp\t%a0%#"
7291 [(set_attr "type" "uncond_branch")])
7292
7293 (define_insn "*tablejump_sp64"
7294 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7295 (use (label_ref (match_operand 1 "" "")))]
7296 "TARGET_ARCH64"
7297 "jmp\t%a0%#"
7298 [(set_attr "type" "uncond_branch")])
7299
7300 ;; This pattern recognizes the "instruction" that appears in
7301 ;; a function call that wants a structure value,
7302 ;; to inform the called function if compiled with Sun CC.
7303 ;(define_insn "*unimp_insn"
7304 ; [(match_operand:SI 0 "immediate_operand" "")]
7305 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7306 ; "unimp\t%0"
7307 ; [(set_attr "type" "marker")])
7308
7309 ;;- jump to subroutine
7310 (define_expand "call"
7311 ;; Note that this expression is not used for generating RTL.
7312 ;; All the RTL is generated explicitly below.
7313 [(call (match_operand 0 "call_operand" "")
7314 (match_operand 3 "" "i"))]
7315 ;; operands[2] is next_arg_register
7316 ;; operands[3] is struct_value_size_rtx.
7317 ""
7318 {
7319 rtx fn_rtx, nregs_rtx;
7320
7321 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7322 abort ();
7323
7324 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7325 {
7326 /* This is really a PIC sequence. We want to represent
7327 it as a funny jump so its delay slots can be filled.
7328
7329 ??? But if this really *is* a CALL, will not it clobber the
7330 call-clobbered registers? We lose this if it is a JUMP_INSN.
7331 Why cannot we have delay slots filled if it were a CALL? */
7332
7333 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7334 emit_jump_insn
7335 (gen_rtx_PARALLEL
7336 (VOIDmode,
7337 gen_rtvec (3,
7338 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7339 operands[3],
7340 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7341 else
7342 emit_jump_insn
7343 (gen_rtx_PARALLEL
7344 (VOIDmode,
7345 gen_rtvec (2,
7346 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7347 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7348 goto finish_call;
7349 }
7350
7351 fn_rtx = operands[0];
7352
7353 /* Count the number of parameter registers being used by this call.
7354 if that argument is NULL, it means we are using them all, which
7355 means 6 on the sparc. */
7356 #if 0
7357 if (operands[2])
7358 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7359 else
7360 nregs_rtx = GEN_INT (6);
7361 #else
7362 nregs_rtx = const0_rtx;
7363 #endif
7364
7365 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7366 emit_call_insn
7367 (gen_rtx_PARALLEL
7368 (VOIDmode,
7369 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7370 operands[3],
7371 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7372 else
7373 emit_call_insn
7374 (gen_rtx_PARALLEL
7375 (VOIDmode,
7376 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7377 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7378
7379 finish_call:
7380 #if 0
7381 /* If this call wants a structure value,
7382 emit an unimp insn to let the called function know about this. */
7383 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7384 {
7385 rtx insn = emit_insn (operands[3]);
7386 SCHED_GROUP_P (insn) = 1;
7387 }
7388 #endif
7389
7390 DONE;
7391 })
7392
7393 ;; We can't use the same pattern for these two insns, because then registers
7394 ;; in the address may not be properly reloaded.
7395
7396 (define_insn "*call_address_sp32"
7397 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7398 (match_operand 1 "" ""))
7399 (clobber (reg:SI 15))]
7400 ;;- Do not use operand 1 for most machines.
7401 "! TARGET_ARCH64"
7402 "call\t%a0, %1%#"
7403 [(set_attr "type" "call")])
7404
7405 (define_insn "*call_symbolic_sp32"
7406 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7407 (match_operand 1 "" ""))
7408 (clobber (reg:SI 15))]
7409 ;;- Do not use operand 1 for most machines.
7410 "! TARGET_ARCH64"
7411 "call\t%a0, %1%#"
7412 [(set_attr "type" "call")])
7413
7414 (define_insn "*call_address_sp64"
7415 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7416 (match_operand 1 "" ""))
7417 (clobber (reg:DI 15))]
7418 ;;- Do not use operand 1 for most machines.
7419 "TARGET_ARCH64"
7420 "call\t%a0, %1%#"
7421 [(set_attr "type" "call")])
7422
7423 (define_insn "*call_symbolic_sp64"
7424 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7425 (match_operand 1 "" ""))
7426 (clobber (reg:DI 15))]
7427 ;;- Do not use operand 1 for most machines.
7428 "TARGET_ARCH64"
7429 "call\t%a0, %1%#"
7430 [(set_attr "type" "call")])
7431
7432 ;; This is a call that wants a structure value.
7433 ;; There is no such critter for v9 (??? we may need one anyway).
7434 (define_insn "*call_address_struct_value_sp32"
7435 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7436 (match_operand 1 "" ""))
7437 (match_operand 2 "immediate_operand" "")
7438 (clobber (reg:SI 15))]
7439 ;;- Do not use operand 1 for most machines.
7440 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7441 "call\t%a0, %1\n\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 wants a structure value.
7446 ;; There is no such critter for v9 (??? we may need one anyway).
7447 (define_insn "*call_symbolic_struct_value_sp32"
7448 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7449 (match_operand 1 "" ""))
7450 (match_operand 2 "immediate_operand" "")
7451 (clobber (reg:SI 15))]
7452 ;;- Do not use operand 1 for most machines.
7453 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7454 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7455 [(set_attr "type" "call_no_delay_slot")
7456 (set_attr "length" "3")])
7457
7458 ;; This is a call that may want a structure value. This is used for
7459 ;; untyped_calls.
7460 (define_insn "*call_address_untyped_struct_value_sp32"
7461 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7462 (match_operand 1 "" ""))
7463 (match_operand 2 "immediate_operand" "")
7464 (clobber (reg:SI 15))]
7465 ;;- Do not use operand 1 for most machines.
7466 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7467 "call\t%a0, %1\n\tnop\n\tnop"
7468 [(set_attr "type" "call_no_delay_slot")
7469 (set_attr "length" "3")])
7470
7471 ;; This is a call that wants a structure value.
7472 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7473 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7474 (match_operand 1 "" ""))
7475 (match_operand 2 "immediate_operand" "")
7476 (clobber (reg:SI 15))]
7477 ;;- Do not use operand 1 for most machines.
7478 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7479 "call\t%a0, %1\n\tnop\n\tnop"
7480 [(set_attr "type" "call_no_delay_slot")
7481 (set_attr "length" "3")])
7482
7483 (define_expand "call_value"
7484 ;; Note that this expression is not used for generating RTL.
7485 ;; All the RTL is generated explicitly below.
7486 [(set (match_operand 0 "register_operand" "=rf")
7487 (call (match_operand 1 "" "")
7488 (match_operand 4 "" "")))]
7489 ;; operand 2 is stack_size_rtx
7490 ;; operand 3 is next_arg_register
7491 ""
7492 {
7493 rtx fn_rtx, nregs_rtx;
7494 rtvec vec;
7495
7496 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7497 abort ();
7498
7499 fn_rtx = operands[1];
7500
7501 #if 0
7502 if (operands[3])
7503 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7504 else
7505 nregs_rtx = GEN_INT (6);
7506 #else
7507 nregs_rtx = const0_rtx;
7508 #endif
7509
7510 vec = gen_rtvec (2,
7511 gen_rtx_SET (VOIDmode, operands[0],
7512 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7513 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7514
7515 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7516
7517 DONE;
7518 })
7519
7520 (define_insn "*call_value_address_sp32"
7521 [(set (match_operand 0 "" "=rf")
7522 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7523 (match_operand 2 "" "")))
7524 (clobber (reg:SI 15))]
7525 ;;- Do not use operand 2 for most machines.
7526 "! TARGET_ARCH64"
7527 "call\t%a1, %2%#"
7528 [(set_attr "type" "call")])
7529
7530 (define_insn "*call_value_symbolic_sp32"
7531 [(set (match_operand 0 "" "=rf")
7532 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7533 (match_operand 2 "" "")))
7534 (clobber (reg:SI 15))]
7535 ;;- Do not use operand 2 for most machines.
7536 "! TARGET_ARCH64"
7537 "call\t%a1, %2%#"
7538 [(set_attr "type" "call")])
7539
7540 (define_insn "*call_value_address_sp64"
7541 [(set (match_operand 0 "" "")
7542 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7543 (match_operand 2 "" "")))
7544 (clobber (reg:DI 15))]
7545 ;;- Do not use operand 2 for most machines.
7546 "TARGET_ARCH64"
7547 "call\t%a1, %2%#"
7548 [(set_attr "type" "call")])
7549
7550 (define_insn "*call_value_symbolic_sp64"
7551 [(set (match_operand 0 "" "")
7552 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7553 (match_operand 2 "" "")))
7554 (clobber (reg:DI 15))]
7555 ;;- Do not use operand 2 for most machines.
7556 "TARGET_ARCH64"
7557 "call\t%a1, %2%#"
7558 [(set_attr "type" "call")])
7559
7560 (define_expand "untyped_call"
7561 [(parallel [(call (match_operand 0 "" "")
7562 (const_int 0))
7563 (match_operand 1 "" "")
7564 (match_operand 2 "" "")])]
7565 ""
7566 {
7567 int i;
7568
7569 /* Pass constm1 to indicate that it may expect a structure value, but
7570 we don't know what size it is. */
7571 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7572
7573 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7574 {
7575 rtx set = XVECEXP (operands[2], 0, i);
7576 emit_move_insn (SET_DEST (set), SET_SRC (set));
7577 }
7578
7579 /* The optimizer does not know that the call sets the function value
7580 registers we stored in the result block. We avoid problems by
7581 claiming that all hard registers are used and clobbered at this
7582 point. */
7583 emit_insn (gen_blockage ());
7584
7585 DONE;
7586 })
7587
7588 ;;- tail calls
7589 (define_expand "sibcall"
7590 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7591 (return)])]
7592 ""
7593 "")
7594
7595 (define_insn "*sibcall_symbolic_sp32"
7596 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7597 (match_operand 1 "" ""))
7598 (return)]
7599 "! TARGET_ARCH64"
7600 "* return output_sibcall(insn, operands[0]);"
7601 [(set_attr "type" "sibcall")])
7602
7603 (define_insn "*sibcall_symbolic_sp64"
7604 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7605 (match_operand 1 "" ""))
7606 (return)]
7607 "TARGET_ARCH64"
7608 "* return output_sibcall(insn, operands[0]);"
7609 [(set_attr "type" "sibcall")])
7610
7611 (define_expand "sibcall_value"
7612 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7613 (call (match_operand 1 "" "") (const_int 0)))
7614 (return)])]
7615 ""
7616 "")
7617
7618 (define_insn "*sibcall_value_symbolic_sp32"
7619 [(set (match_operand 0 "" "=rf")
7620 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7621 (match_operand 2 "" "")))
7622 (return)]
7623 "! TARGET_ARCH64"
7624 "* return output_sibcall(insn, operands[1]);"
7625 [(set_attr "type" "sibcall")])
7626
7627 (define_insn "*sibcall_value_symbolic_sp64"
7628 [(set (match_operand 0 "" "")
7629 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7630 (match_operand 2 "" "")))
7631 (return)]
7632 "TARGET_ARCH64"
7633 "* return output_sibcall(insn, operands[1]);"
7634 [(set_attr "type" "sibcall")])
7635
7636 (define_expand "sibcall_epilogue"
7637 [(const_int 0)]
7638 ""
7639 "DONE;")
7640
7641 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7642 ;; all of memory. This blocks insns from being moved across this point.
7643
7644 (define_insn "blockage"
7645 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7646 ""
7647 ""
7648 [(set_attr "length" "0")])
7649
7650 ;; Prepare to return any type including a structure value.
7651
7652 (define_expand "untyped_return"
7653 [(match_operand:BLK 0 "memory_operand" "")
7654 (match_operand 1 "" "")]
7655 ""
7656 {
7657 rtx valreg1 = gen_rtx_REG (DImode, 24);
7658 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7659 rtx result = operands[0];
7660
7661 if (! TARGET_ARCH64)
7662 {
7663 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7664 ? 15 : 31));
7665 rtx value = gen_reg_rtx (SImode);
7666
7667 /* Fetch the instruction where we will return to and see if it's an unimp
7668 instruction (the most significant 10 bits will be zero). If so,
7669 update the return address to skip the unimp instruction. */
7670 emit_move_insn (value,
7671 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7672 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7673 emit_insn (gen_update_return (rtnreg, value));
7674 }
7675
7676 /* Reload the function value registers. */
7677 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7678 emit_move_insn (valreg2,
7679 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7680
7681 /* Put USE insns before the return. */
7682 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7683 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7684
7685 /* Construct the return. */
7686 expand_naked_return ();
7687
7688 DONE;
7689 })
7690
7691 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7692 ;; and parts of the compiler don't want to believe that the add is needed.
7693
7694 (define_insn "update_return"
7695 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7696 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7697 "! TARGET_ARCH64"
7698 "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7699 [(set_attr "type" "multi")
7700 (set_attr "length" "3")])
7701 \f
7702 (define_insn "nop"
7703 [(const_int 0)]
7704 ""
7705 "nop")
7706
7707 (define_expand "indirect_jump"
7708 [(set (pc) (match_operand 0 "address_operand" "p"))]
7709 ""
7710 "")
7711
7712 (define_insn "*branch_sp32"
7713 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7714 "! TARGET_ARCH64"
7715 "jmp\t%a0%#"
7716 [(set_attr "type" "uncond_branch")])
7717
7718 (define_insn "*branch_sp64"
7719 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7720 "TARGET_ARCH64"
7721 "jmp\t%a0%#"
7722 [(set_attr "type" "uncond_branch")])
7723
7724 (define_expand "nonlocal_goto"
7725 [(match_operand:SI 0 "general_operand" "")
7726 (match_operand:SI 1 "general_operand" "")
7727 (match_operand:SI 2 "general_operand" "")
7728 (match_operand:SI 3 "" "")]
7729 ""
7730 {
7731 #if 0
7732 rtx chain = operands[0];
7733 #endif
7734 rtx lab = operands[1];
7735 rtx stack = operands[2];
7736 rtx fp = operands[3];
7737 rtx labreg;
7738
7739 /* Trap instruction to flush all the register windows. */
7740 emit_insn (gen_flush_register_windows ());
7741
7742 /* Load the fp value for the containing fn into %fp. This is needed
7743 because STACK refers to %fp. Note that virtual register instantiation
7744 fails if the virtual %fp isn't set from a register. */
7745 if (GET_CODE (fp) != REG)
7746 fp = force_reg (Pmode, fp);
7747 emit_move_insn (virtual_stack_vars_rtx, fp);
7748
7749 /* Find the containing function's current nonlocal goto handler,
7750 which will do any cleanups and then jump to the label. */
7751 labreg = gen_rtx_REG (Pmode, 8);
7752 emit_move_insn (labreg, lab);
7753
7754 /* Restore %fp from stack pointer value for containing function.
7755 The restore insn that follows will move this to %sp,
7756 and reload the appropriate value into %fp. */
7757 emit_move_insn (hard_frame_pointer_rtx, stack);
7758
7759 /* USE of frame_pointer_rtx added for consistency; not clear if
7760 really needed. */
7761 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7762 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7763
7764 #if 0
7765 /* Return, restoring reg window and jumping to goto handler. */
7766 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7767 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7768 {
7769 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7770 static_chain_rtx,
7771 chain));
7772 emit_barrier ();
7773 DONE;
7774 }
7775 /* Put in the static chain register the nonlocal label address. */
7776 emit_move_insn (static_chain_rtx, chain);
7777 #endif
7778
7779 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7780 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7781 emit_barrier ();
7782 DONE;
7783 })
7784
7785 ;; Special trap insn to flush register windows.
7786 (define_insn "flush_register_windows"
7787 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7788 ""
7789 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7790 [(set_attr "type" "flushw")])
7791
7792 (define_insn "goto_handler_and_restore"
7793 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7794 "GET_MODE (operands[0]) == Pmode"
7795 "jmp\t%0+0\n\trestore"
7796 [(set_attr "type" "multi")
7797 (set_attr "length" "2")])
7798
7799 ;;(define_insn "goto_handler_and_restore_v9"
7800 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7801 ;; (match_operand:SI 1 "register_operand" "=r,r")
7802 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7803 ;; "TARGET_V9 && ! TARGET_ARCH64"
7804 ;; "@
7805 ;; return\t%0+0\n\tmov\t%2, %Y1
7806 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7807 ;; [(set_attr "type" "multi")
7808 ;; (set_attr "length" "2,3")])
7809 ;;
7810 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7811 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7812 ;; (match_operand:DI 1 "register_operand" "=r,r")
7813 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7814 ;; "TARGET_V9 && TARGET_ARCH64"
7815 ;; "@
7816 ;; return\t%0+0\n\tmov\t%2, %Y1
7817 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7818 ;; [(set_attr "type" "multi")
7819 ;; (set_attr "length" "2,3")])
7820
7821 ;; For __builtin_setjmp we need to flush register windows iff the function
7822 ;; calls alloca as well, because otherwise the register window might be
7823 ;; saved after %sp adjustment and thus setjmp would crash
7824 (define_expand "builtin_setjmp_setup"
7825 [(match_operand 0 "register_operand" "r")]
7826 ""
7827 {
7828 emit_insn (gen_do_builtin_setjmp_setup ());
7829 DONE;
7830 })
7831
7832 (define_insn "do_builtin_setjmp_setup"
7833 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7834 ""
7835 {
7836 if (! current_function_calls_alloca)
7837 return "";
7838 if (! TARGET_V9)
7839 return "\tta\t3\n";
7840 fputs ("\tflushw\n", asm_out_file);
7841 if (flag_pic)
7842 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7843 TARGET_ARCH64 ? 'x' : 'w',
7844 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7845 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7846 TARGET_ARCH64 ? 'x' : 'w',
7847 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7848 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7849 TARGET_ARCH64 ? 'x' : 'w',
7850 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7851 return "";
7852 }
7853 [(set_attr "type" "multi")
7854 (set (attr "length")
7855 (cond [(eq_attr "current_function_calls_alloca" "false")
7856 (const_int 0)
7857 (eq_attr "isa" "!v9")
7858 (const_int 1)
7859 (eq_attr "pic" "true")
7860 (const_int 4)] (const_int 3)))])
7861
7862 ;; Pattern for use after a setjmp to store FP and the return register
7863 ;; into the stack area.
7864
7865 (define_expand "setjmp"
7866 [(const_int 0)]
7867 ""
7868 {
7869 if (TARGET_ARCH64)
7870 emit_insn (gen_setjmp_64 ());
7871 else
7872 emit_insn (gen_setjmp_32 ());
7873 DONE;
7874 })
7875
7876 (define_expand "setjmp_32"
7877 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7878 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7879 ""
7880 { operands[0] = frame_pointer_rtx; })
7881
7882 (define_expand "setjmp_64"
7883 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7884 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7885 ""
7886 { operands[0] = frame_pointer_rtx; })
7887
7888 ;; Special pattern for the FLUSH instruction.
7889
7890 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7891 ; of the define_insn otherwise missing a mode. We make "flush", aka
7892 ; gen_flush, the default one since sparc_initialize_trampoline uses
7893 ; it on SImode mem values.
7894
7895 (define_insn "flush"
7896 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7897 ""
7898 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7899 [(set_attr "type" "iflush")])
7900
7901 (define_insn "flushdi"
7902 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7903 ""
7904 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7905 [(set_attr "type" "iflush")])
7906
7907 \f
7908 ;; find first set.
7909
7910 ;; The scan instruction searches from the most significant bit while ffs
7911 ;; searches from the least significant bit. The bit index and treatment of
7912 ;; zero also differ. It takes at least 7 instructions to get the proper
7913 ;; result. Here is an obvious 8 instruction sequence.
7914
7915 ;; XXX
7916 (define_insn "ffssi2"
7917 [(set (match_operand:SI 0 "register_operand" "=&r")
7918 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7919 (clobber (match_scratch:SI 2 "=&r"))]
7920 "TARGET_SPARCLITE || TARGET_SPARCLET"
7921 {
7922 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";
7923 }
7924 [(set_attr "type" "multi")
7925 (set_attr "length" "8")])
7926
7927 ;; ??? This should be a define expand, so that the extra instruction have
7928 ;; a chance of being optimized away.
7929
7930 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7931 ;; does, but no one uses that and we don't have a switch for it.
7932 ;
7933 ;(define_insn "ffsdi2"
7934 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7935 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7936 ; (clobber (match_scratch:DI 2 "=&r"))]
7937 ; "TARGET_ARCH64"
7938 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7939 ; [(set_attr "type" "multi")
7940 ; (set_attr "length" "4")])
7941
7942
7943 \f
7944 ;; Peepholes go at the end.
7945
7946 ;; Optimize consecutive loads or stores into ldd and std when possible.
7947 ;; The conditions in which we do this are very restricted and are
7948 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7949
7950 (define_peephole2
7951 [(set (match_operand:SI 0 "memory_operand" "")
7952 (const_int 0))
7953 (set (match_operand:SI 1 "memory_operand" "")
7954 (const_int 0))]
7955 "TARGET_V9
7956 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7957 [(set (match_dup 0)
7958 (const_int 0))]
7959 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7960
7961 (define_peephole2
7962 [(set (match_operand:SI 0 "memory_operand" "")
7963 (const_int 0))
7964 (set (match_operand:SI 1 "memory_operand" "")
7965 (const_int 0))]
7966 "TARGET_V9
7967 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7968 [(set (match_dup 1)
7969 (const_int 0))]
7970 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7971
7972 (define_peephole2
7973 [(set (match_operand:SI 0 "register_operand" "")
7974 (match_operand:SI 1 "memory_operand" ""))
7975 (set (match_operand:SI 2 "register_operand" "")
7976 (match_operand:SI 3 "memory_operand" ""))]
7977 "registers_ok_for_ldd_peep (operands[0], operands[2])
7978 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7979 [(set (match_dup 0)
7980 (match_dup 1))]
7981 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7982 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7983
7984 (define_peephole2
7985 [(set (match_operand:SI 0 "memory_operand" "")
7986 (match_operand:SI 1 "register_operand" ""))
7987 (set (match_operand:SI 2 "memory_operand" "")
7988 (match_operand:SI 3 "register_operand" ""))]
7989 "registers_ok_for_ldd_peep (operands[1], operands[3])
7990 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7991 [(set (match_dup 0)
7992 (match_dup 1))]
7993 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7994 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7995
7996 (define_peephole2
7997 [(set (match_operand:SF 0 "register_operand" "")
7998 (match_operand:SF 1 "memory_operand" ""))
7999 (set (match_operand:SF 2 "register_operand" "")
8000 (match_operand:SF 3 "memory_operand" ""))]
8001 "registers_ok_for_ldd_peep (operands[0], operands[2])
8002 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8003 [(set (match_dup 0)
8004 (match_dup 1))]
8005 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8006 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8007
8008 (define_peephole2
8009 [(set (match_operand:SF 0 "memory_operand" "")
8010 (match_operand:SF 1 "register_operand" ""))
8011 (set (match_operand:SF 2 "memory_operand" "")
8012 (match_operand:SF 3 "register_operand" ""))]
8013 "registers_ok_for_ldd_peep (operands[1], operands[3])
8014 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8015 [(set (match_dup 0)
8016 (match_dup 1))]
8017 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8018 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8019
8020 (define_peephole2
8021 [(set (match_operand:SI 0 "register_operand" "")
8022 (match_operand:SI 1 "memory_operand" ""))
8023 (set (match_operand:SI 2 "register_operand" "")
8024 (match_operand:SI 3 "memory_operand" ""))]
8025 "registers_ok_for_ldd_peep (operands[2], operands[0])
8026 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8027 [(set (match_dup 2)
8028 (match_dup 3))]
8029 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8030 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8031
8032 (define_peephole2
8033 [(set (match_operand:SI 0 "memory_operand" "")
8034 (match_operand:SI 1 "register_operand" ""))
8035 (set (match_operand:SI 2 "memory_operand" "")
8036 (match_operand:SI 3 "register_operand" ""))]
8037 "registers_ok_for_ldd_peep (operands[3], operands[1])
8038 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8039 [(set (match_dup 2)
8040 (match_dup 3))]
8041 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8042 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8043 ")
8044
8045 (define_peephole2
8046 [(set (match_operand:SF 0 "register_operand" "")
8047 (match_operand:SF 1 "memory_operand" ""))
8048 (set (match_operand:SF 2 "register_operand" "")
8049 (match_operand:SF 3 "memory_operand" ""))]
8050 "registers_ok_for_ldd_peep (operands[2], operands[0])
8051 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8052 [(set (match_dup 2)
8053 (match_dup 3))]
8054 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8055 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8056
8057 (define_peephole2
8058 [(set (match_operand:SF 0 "memory_operand" "")
8059 (match_operand:SF 1 "register_operand" ""))
8060 (set (match_operand:SF 2 "memory_operand" "")
8061 (match_operand:SF 3 "register_operand" ""))]
8062 "registers_ok_for_ldd_peep (operands[3], operands[1])
8063 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8064 [(set (match_dup 2)
8065 (match_dup 3))]
8066 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8067 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8068
8069 ;; Optimize the case of following a reg-reg move with a test
8070 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8071 ;; This can result from a float to fix conversion.
8072
8073 (define_peephole2
8074 [(set (match_operand:SI 0 "register_operand" "")
8075 (match_operand:SI 1 "register_operand" ""))
8076 (set (reg:CC 100)
8077 (compare:CC (match_operand:SI 2 "register_operand" "")
8078 (const_int 0)))]
8079 "(rtx_equal_p (operands[2], operands[0])
8080 || rtx_equal_p (operands[2], operands[1]))
8081 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8082 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8083 [(parallel [(set (match_dup 0) (match_dup 1))
8084 (set (reg:CC 100)
8085 (compare:CC (match_dup 1) (const_int 0)))])]
8086 "")
8087
8088 (define_peephole2
8089 [(set (match_operand:DI 0 "register_operand" "")
8090 (match_operand:DI 1 "register_operand" ""))
8091 (set (reg:CCX 100)
8092 (compare:CCX (match_operand:DI 2 "register_operand" "")
8093 (const_int 0)))]
8094 "TARGET_ARCH64
8095 && (rtx_equal_p (operands[2], operands[0])
8096 || rtx_equal_p (operands[2], operands[1]))
8097 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8098 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8099 [(parallel [(set (match_dup 0) (match_dup 1))
8100 (set (reg:CCX 100)
8101 (compare:CCX (match_dup 1) (const_int 0)))])]
8102 "")
8103
8104 ;; Return peepholes. These are generated by sparc_function_epilogue
8105 ;; who then immediately calls final_scan_insn.
8106
8107 (define_insn "*return_qi"
8108 [(set (match_operand:QI 0 "restore_operand" "")
8109 (match_operand:QI 1 "arith_operand" "rI"))
8110 (return)]
8111 "sparc_emitting_epilogue"
8112 {
8113 if (! TARGET_ARCH64 && current_function_returns_struct)
8114 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8115 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8116 || IN_OR_GLOBAL_P (operands[1])))
8117 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8118 else
8119 return "ret\n\trestore %%g0, %1, %Y0";
8120 }
8121 [(set_attr "type" "multi")
8122 (set_attr "length" "2")])
8123
8124 (define_insn "*return_hi"
8125 [(set (match_operand:HI 0 "restore_operand" "")
8126 (match_operand:HI 1 "arith_operand" "rI"))
8127 (return)]
8128 "sparc_emitting_epilogue"
8129 {
8130 if (! TARGET_ARCH64 && current_function_returns_struct)
8131 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8132 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8133 || IN_OR_GLOBAL_P (operands[1])))
8134 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8135 else
8136 return "ret\;restore %%g0, %1, %Y0";
8137 }
8138 [(set_attr "type" "multi")
8139 (set_attr "length" "2")])
8140
8141 (define_insn "*return_si"
8142 [(set (match_operand:SI 0 "restore_operand" "")
8143 (match_operand:SI 1 "arith_operand" "rI"))
8144 (return)]
8145 "sparc_emitting_epilogue"
8146 {
8147 if (! TARGET_ARCH64 && current_function_returns_struct)
8148 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8149 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8150 || IN_OR_GLOBAL_P (operands[1])))
8151 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8152 else
8153 return "ret\;restore %%g0, %1, %Y0";
8154 }
8155 [(set_attr "type" "multi")
8156 (set_attr "length" "2")])
8157
8158 (define_insn "*return_sf_no_fpu"
8159 [(set (match_operand:SF 0 "restore_operand" "=r")
8160 (match_operand:SF 1 "register_operand" "r"))
8161 (return)]
8162 "sparc_emitting_epilogue"
8163 {
8164 if (! TARGET_ARCH64 && current_function_returns_struct)
8165 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8166 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8167 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8168 else
8169 return "ret\;restore %%g0, %1, %Y0";
8170 }
8171 [(set_attr "type" "multi")
8172 (set_attr "length" "2")])
8173
8174 (define_insn "*return_df_no_fpu"
8175 [(set (match_operand:DF 0 "restore_operand" "=r")
8176 (match_operand:DF 1 "register_operand" "r"))
8177 (return)]
8178 "sparc_emitting_epilogue && TARGET_ARCH64"
8179 {
8180 if (IN_OR_GLOBAL_P (operands[1]))
8181 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8182 else
8183 return "ret\;restore %%g0, %1, %Y0";
8184 }
8185 [(set_attr "type" "multi")
8186 (set_attr "length" "2")])
8187
8188 (define_insn "*return_addsi"
8189 [(set (match_operand:SI 0 "restore_operand" "")
8190 (plus:SI (match_operand:SI 1 "register_operand" "r")
8191 (match_operand:SI 2 "arith_operand" "rI")))
8192 (return)]
8193 "sparc_emitting_epilogue"
8194 {
8195 if (! TARGET_ARCH64 && current_function_returns_struct)
8196 return "jmp\t%%i7+12\n\trestore %r1, %2, %Y0";
8197 /* If operands are global or in registers, can use return */
8198 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8199 && (GET_CODE (operands[2]) == CONST_INT
8200 || IN_OR_GLOBAL_P (operands[2])))
8201 return "return\t%%i7+8\n\tadd\t%Y1, %Y2, %Y0";
8202 else
8203 return "ret\;restore %r1, %2, %Y0";
8204 }
8205 [(set_attr "type" "multi")
8206 (set_attr "length" "2")])
8207
8208 (define_insn "*return_losum_si"
8209 [(set (match_operand:SI 0 "restore_operand" "")
8210 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8211 (match_operand:SI 2 "immediate_operand" "in")))
8212 (return)]
8213 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8214 {
8215 if (! TARGET_ARCH64 && current_function_returns_struct)
8216 return "jmp\t%%i7+12\n\trestore %r1, %%lo(%a2), %Y0";
8217 /* If operands are global or in registers, can use return */
8218 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8219 return "return\t%%i7+8\n\tor\t%Y1, %%lo(%a2), %Y0";
8220 else
8221 return "ret\;restore %r1, %%lo(%a2), %Y0";
8222 }
8223 [(set_attr "type" "multi")
8224 (set_attr "length" "2")])
8225
8226 (define_insn "*return_di"
8227 [(set (match_operand:DI 0 "restore_operand" "")
8228 (match_operand:DI 1 "arith_double_operand" "rHI"))
8229 (return)]
8230 "sparc_emitting_epilogue && TARGET_ARCH64"
8231 "ret\;restore %%g0, %1, %Y0"
8232 [(set_attr "type" "multi")
8233 (set_attr "length" "2")])
8234
8235 (define_insn "*return_adddi"
8236 [(set (match_operand:DI 0 "restore_operand" "")
8237 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8238 (match_operand:DI 2 "arith_double_operand" "rHI")))
8239 (return)]
8240 "sparc_emitting_epilogue && TARGET_ARCH64"
8241 "ret\;restore %r1, %2, %Y0"
8242 [(set_attr "type" "multi")
8243 (set_attr "length" "2")])
8244
8245 (define_insn "*return_losum_di"
8246 [(set (match_operand:DI 0 "restore_operand" "")
8247 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8248 (match_operand:DI 2 "immediate_operand" "in")))
8249 (return)]
8250 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8251 "ret\;restore %r1, %%lo(%a2), %Y0"
8252 [(set_attr "type" "multi")
8253 (set_attr "length" "2")])
8254
8255 (define_insn "*return_sf"
8256 [(set (reg:SF 32)
8257 (match_operand:SF 0 "register_operand" "f"))
8258 (return)]
8259 "sparc_emitting_epilogue"
8260 "ret\;fmovs\t%0, %%f0"
8261 [(set_attr "type" "multi")
8262 (set_attr "length" "2")])
8263
8264 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8265 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8266 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8267 ;; ??? state.
8268 (define_expand "prefetch"
8269 [(match_operand 0 "address_operand" "")
8270 (match_operand 1 "const_int_operand" "")
8271 (match_operand 2 "const_int_operand" "")]
8272 "TARGET_V9"
8273 {
8274 if (TARGET_ARCH64)
8275 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8276 else
8277 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8278 DONE;
8279 })
8280
8281 (define_insn "prefetch_64"
8282 [(prefetch (match_operand:DI 0 "address_operand" "p")
8283 (match_operand:DI 1 "const_int_operand" "n")
8284 (match_operand:DI 2 "const_int_operand" "n"))]
8285 ""
8286 {
8287 static const char * const prefetch_instr[2][2] = {
8288 {
8289 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8290 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8291 },
8292 {
8293 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8294 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8295 }
8296 };
8297 int read_or_write = INTVAL (operands[1]);
8298 int locality = INTVAL (operands[2]);
8299
8300 if (read_or_write != 0 && read_or_write != 1)
8301 abort ();
8302 if (locality < 0 || locality > 3)
8303 abort ();
8304 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8305 }
8306 [(set_attr "type" "load")])
8307
8308 (define_insn "prefetch_32"
8309 [(prefetch (match_operand:SI 0 "address_operand" "p")
8310 (match_operand:SI 1 "const_int_operand" "n")
8311 (match_operand:SI 2 "const_int_operand" "n"))]
8312 ""
8313 {
8314 static const char * const prefetch_instr[2][2] = {
8315 {
8316 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8317 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8318 },
8319 {
8320 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8321 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8322 }
8323 };
8324 int read_or_write = INTVAL (operands[1]);
8325 int locality = INTVAL (operands[2]);
8326
8327 if (read_or_write != 0 && read_or_write != 1)
8328 abort ();
8329 if (locality < 0 || locality > 3)
8330 abort ();
8331 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8332 }
8333 [(set_attr "type" "load")])
8334 \f
8335 (define_expand "prologue"
8336 [(const_int 1)]
8337 "flag_pic && current_function_uses_pic_offset_table"
8338 {
8339 load_pic_register ();
8340 DONE;
8341 })
8342 \f
8343 (define_insn "trap"
8344 [(trap_if (const_int 1) (const_int 5))]
8345 ""
8346 "ta\t5"
8347 [(set_attr "type" "trap")])
8348
8349 (define_expand "conditional_trap"
8350 [(trap_if (match_operator 0 "noov_compare_op"
8351 [(match_dup 2) (match_dup 3)])
8352 (match_operand:SI 1 "arith_operand" ""))]
8353 ""
8354 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8355 sparc_compare_op0, sparc_compare_op1);
8356 operands[3] = const0_rtx;")
8357
8358 (define_insn ""
8359 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8360 (match_operand:SI 1 "arith_operand" "rM"))]
8361 ""
8362 "t%C0\t%1"
8363 [(set_attr "type" "trap")])
8364
8365 (define_insn ""
8366 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8367 (match_operand:SI 1 "arith_operand" "rM"))]
8368 "TARGET_V9"
8369 "t%C0\t%%xcc, %1"
8370 [(set_attr "type" "trap")])
8371
8372 ;; TLS support
8373 (define_insn "tgd_hi22"
8374 [(set (match_operand:SI 0 "register_operand" "=r")
8375 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8376 UNSPEC_TLSGD)))]
8377 "TARGET_TLS"
8378 "sethi\\t%%tgd_hi22(%a1), %0")
8379
8380 (define_insn "tgd_lo10"
8381 [(set (match_operand:SI 0 "register_operand" "=r")
8382 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8383 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8384 UNSPEC_TLSGD)))]
8385 "TARGET_TLS"
8386 "add\\t%1, %%tgd_lo10(%a2), %0")
8387
8388 (define_insn "tgd_add32"
8389 [(set (match_operand:SI 0 "register_operand" "=r")
8390 (plus:SI (match_operand:SI 1 "register_operand" "r")
8391 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8392 (match_operand 3 "tgd_symbolic_operand" "")]
8393 UNSPEC_TLSGD)))]
8394 "TARGET_TLS && TARGET_ARCH32"
8395 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8396
8397 (define_insn "tgd_add64"
8398 [(set (match_operand:DI 0 "register_operand" "=r")
8399 (plus:DI (match_operand:DI 1 "register_operand" "r")
8400 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8401 (match_operand 3 "tgd_symbolic_operand" "")]
8402 UNSPEC_TLSGD)))]
8403 "TARGET_TLS && TARGET_ARCH64"
8404 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8405
8406 (define_insn "tgd_call32"
8407 [(set (match_operand 0 "register_operand" "=r")
8408 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8409 (match_operand 2 "tgd_symbolic_operand" "")]
8410 UNSPEC_TLSGD))
8411 (match_operand 3 "" "")))
8412 (clobber (reg:SI 15))]
8413 "TARGET_TLS && TARGET_ARCH32"
8414 "call\t%a1, %%tgd_call(%a2)%#"
8415 [(set_attr "type" "call")])
8416
8417 (define_insn "tgd_call64"
8418 [(set (match_operand 0 "register_operand" "=r")
8419 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8420 (match_operand 2 "tgd_symbolic_operand" "")]
8421 UNSPEC_TLSGD))
8422 (match_operand 3 "" "")))
8423 (clobber (reg:DI 15))]
8424 "TARGET_TLS && TARGET_ARCH64"
8425 "call\t%a1, %%tgd_call(%a2)%#"
8426 [(set_attr "type" "call")])
8427
8428 (define_insn "tldm_hi22"
8429 [(set (match_operand:SI 0 "register_operand" "=r")
8430 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8431 "TARGET_TLS"
8432 "sethi\\t%%tldm_hi22(%&), %0")
8433
8434 (define_insn "tldm_lo10"
8435 [(set (match_operand:SI 0 "register_operand" "=r")
8436 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8437 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8438 "TARGET_TLS"
8439 "add\\t%1, %%tldm_lo10(%&), %0")
8440
8441 (define_insn "tldm_add32"
8442 [(set (match_operand:SI 0 "register_operand" "=r")
8443 (plus:SI (match_operand:SI 1 "register_operand" "r")
8444 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8445 UNSPEC_TLSLDM)))]
8446 "TARGET_TLS && TARGET_ARCH32"
8447 "add\\t%1, %2, %0, %%tldm_add(%&)")
8448
8449 (define_insn "tldm_add64"
8450 [(set (match_operand:DI 0 "register_operand" "=r")
8451 (plus:DI (match_operand:DI 1 "register_operand" "r")
8452 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8453 UNSPEC_TLSLDM)))]
8454 "TARGET_TLS && TARGET_ARCH64"
8455 "add\\t%1, %2, %0, %%tldm_add(%&)")
8456
8457 (define_insn "tldm_call32"
8458 [(set (match_operand 0 "register_operand" "=r")
8459 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8460 UNSPEC_TLSLDM))
8461 (match_operand 2 "" "")))
8462 (clobber (reg:SI 15))]
8463 "TARGET_TLS && TARGET_ARCH32"
8464 "call\t%a1, %%tldm_call(%&)%#"
8465 [(set_attr "type" "call")])
8466
8467 (define_insn "tldm_call64"
8468 [(set (match_operand 0 "register_operand" "=r")
8469 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8470 UNSPEC_TLSLDM))
8471 (match_operand 2 "" "")))
8472 (clobber (reg:DI 15))]
8473 "TARGET_TLS && TARGET_ARCH64"
8474 "call\t%a1, %%tldm_call(%&)%#"
8475 [(set_attr "type" "call")])
8476
8477 (define_insn "tldo_hix22"
8478 [(set (match_operand:SI 0 "register_operand" "=r")
8479 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8480 UNSPEC_TLSLDO)))]
8481 "TARGET_TLS"
8482 "sethi\\t%%tldo_hix22(%a1), %0")
8483
8484 (define_insn "tldo_lox10"
8485 [(set (match_operand:SI 0 "register_operand" "=r")
8486 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8487 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8488 UNSPEC_TLSLDO)))]
8489 "TARGET_TLS"
8490 "xor\\t%1, %%tldo_lox10(%a2), %0")
8491
8492 (define_insn "tldo_add32"
8493 [(set (match_operand:SI 0 "register_operand" "=r")
8494 (plus:SI (match_operand:SI 1 "register_operand" "r")
8495 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8496 (match_operand 3 "tld_symbolic_operand" "")]
8497 UNSPEC_TLSLDO)))]
8498 "TARGET_TLS && TARGET_ARCH32"
8499 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8500
8501 (define_insn "tldo_add64"
8502 [(set (match_operand:DI 0 "register_operand" "=r")
8503 (plus:DI (match_operand:DI 1 "register_operand" "r")
8504 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8505 (match_operand 3 "tld_symbolic_operand" "")]
8506 UNSPEC_TLSLDO)))]
8507 "TARGET_TLS && TARGET_ARCH64"
8508 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8509
8510 (define_insn "tie_hi22"
8511 [(set (match_operand:SI 0 "register_operand" "=r")
8512 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8513 UNSPEC_TLSIE)))]
8514 "TARGET_TLS"
8515 "sethi\\t%%tie_hi22(%a1), %0")
8516
8517 (define_insn "tie_lo10"
8518 [(set (match_operand:SI 0 "register_operand" "=r")
8519 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8520 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8521 UNSPEC_TLSIE)))]
8522 "TARGET_TLS"
8523 "add\\t%1, %%tie_lo10(%a2), %0")
8524
8525 (define_insn "tie_ld32"
8526 [(set (match_operand:SI 0 "register_operand" "=r")
8527 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8528 (match_operand:SI 2 "register_operand" "r")
8529 (match_operand 3 "tie_symbolic_operand" "")]
8530 UNSPEC_TLSIE))]
8531 "TARGET_TLS && TARGET_ARCH32"
8532 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8533 [(set_attr "type" "load")])
8534
8535 (define_insn "tie_ld64"
8536 [(set (match_operand:DI 0 "register_operand" "=r")
8537 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8538 (match_operand:SI 2 "register_operand" "r")
8539 (match_operand 3 "tie_symbolic_operand" "")]
8540 UNSPEC_TLSIE))]
8541 "TARGET_TLS && TARGET_ARCH64"
8542 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8543 [(set_attr "type" "load")])
8544
8545 (define_insn "tie_add32"
8546 [(set (match_operand:SI 0 "register_operand" "=r")
8547 (plus:SI (match_operand:SI 1 "register_operand" "r")
8548 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8549 (match_operand 3 "tie_symbolic_operand" "")]
8550 UNSPEC_TLSIE)))]
8551 "TARGET_SUN_TLS && TARGET_ARCH32"
8552 "add\\t%1, %2, %0, %%tie_add(%a3)")
8553
8554 (define_insn "tie_add64"
8555 [(set (match_operand:DI 0 "register_operand" "=r")
8556 (plus:DI (match_operand:DI 1 "register_operand" "r")
8557 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8558 (match_operand 3 "tie_symbolic_operand" "")]
8559 UNSPEC_TLSIE)))]
8560 "TARGET_SUN_TLS && TARGET_ARCH64"
8561 "add\\t%1, %2, %0, %%tie_add(%a3)")
8562
8563 (define_insn "tle_hix22_sp32"
8564 [(set (match_operand:SI 0 "register_operand" "=r")
8565 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8566 UNSPEC_TLSLE)))]
8567 "TARGET_TLS && TARGET_ARCH32"
8568 "sethi\\t%%tle_hix22(%a1), %0")
8569
8570 (define_insn "tle_lox10_sp32"
8571 [(set (match_operand:SI 0 "register_operand" "=r")
8572 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8573 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8574 UNSPEC_TLSLE)))]
8575 "TARGET_TLS && TARGET_ARCH32"
8576 "xor\\t%1, %%tle_lox10(%a2), %0")
8577
8578 (define_insn "tle_hix22_sp64"
8579 [(set (match_operand:DI 0 "register_operand" "=r")
8580 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8581 UNSPEC_TLSLE)))]
8582 "TARGET_TLS && TARGET_ARCH64"
8583 "sethi\\t%%tle_hix22(%a1), %0")
8584
8585 (define_insn "tle_lox10_sp64"
8586 [(set (match_operand:DI 0 "register_operand" "=r")
8587 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8588 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8589 UNSPEC_TLSLE)))]
8590 "TARGET_TLS && TARGET_ARCH64"
8591 "xor\\t%1, %%tle_lox10(%a2), %0")
8592
8593 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8594 (define_insn "*tldo_ldub_sp32"
8595 [(set (match_operand:QI 0 "register_operand" "=r")
8596 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8597 (match_operand 3 "tld_symbolic_operand" "")]
8598 UNSPEC_TLSLDO)
8599 (match_operand:SI 1 "register_operand" "r"))))]
8600 "TARGET_TLS && TARGET_ARCH32"
8601 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8602 [(set_attr "type" "load")
8603 (set_attr "us3load_type" "3cycle")])
8604
8605 (define_insn "*tldo_ldub1_sp32"
8606 [(set (match_operand:HI 0 "register_operand" "=r")
8607 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8608 (match_operand 3 "tld_symbolic_operand" "")]
8609 UNSPEC_TLSLDO)
8610 (match_operand:SI 1 "register_operand" "r")))))]
8611 "TARGET_TLS && TARGET_ARCH32"
8612 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8613 [(set_attr "type" "load")
8614 (set_attr "us3load_type" "3cycle")])
8615
8616 (define_insn "*tldo_ldub2_sp32"
8617 [(set (match_operand:SI 0 "register_operand" "=r")
8618 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8619 (match_operand 3 "tld_symbolic_operand" "")]
8620 UNSPEC_TLSLDO)
8621 (match_operand:SI 1 "register_operand" "r")))))]
8622 "TARGET_TLS && TARGET_ARCH32"
8623 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8624 [(set_attr "type" "load")
8625 (set_attr "us3load_type" "3cycle")])
8626
8627 (define_insn "*tldo_ldsb1_sp32"
8628 [(set (match_operand:HI 0 "register_operand" "=r")
8629 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8630 (match_operand 3 "tld_symbolic_operand" "")]
8631 UNSPEC_TLSLDO)
8632 (match_operand:SI 1 "register_operand" "r")))))]
8633 "TARGET_TLS && TARGET_ARCH32"
8634 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8635 [(set_attr "type" "sload")
8636 (set_attr "us3load_type" "3cycle")])
8637
8638 (define_insn "*tldo_ldsb2_sp32"
8639 [(set (match_operand:SI 0 "register_operand" "=r")
8640 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8641 (match_operand 3 "tld_symbolic_operand" "")]
8642 UNSPEC_TLSLDO)
8643 (match_operand:SI 1 "register_operand" "r")))))]
8644 "TARGET_TLS && TARGET_ARCH32"
8645 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8646 [(set_attr "type" "sload")
8647 (set_attr "us3load_type" "3cycle")])
8648
8649 (define_insn "*tldo_ldub_sp64"
8650 [(set (match_operand:QI 0 "register_operand" "=r")
8651 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8652 (match_operand 3 "tld_symbolic_operand" "")]
8653 UNSPEC_TLSLDO)
8654 (match_operand:DI 1 "register_operand" "r"))))]
8655 "TARGET_TLS && TARGET_ARCH64"
8656 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8657 [(set_attr "type" "load")
8658 (set_attr "us3load_type" "3cycle")])
8659
8660 (define_insn "*tldo_ldub1_sp64"
8661 [(set (match_operand:HI 0 "register_operand" "=r")
8662 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8663 (match_operand 3 "tld_symbolic_operand" "")]
8664 UNSPEC_TLSLDO)
8665 (match_operand:DI 1 "register_operand" "r")))))]
8666 "TARGET_TLS && TARGET_ARCH64"
8667 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8668 [(set_attr "type" "load")
8669 (set_attr "us3load_type" "3cycle")])
8670
8671 (define_insn "*tldo_ldub2_sp64"
8672 [(set (match_operand:SI 0 "register_operand" "=r")
8673 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8674 (match_operand 3 "tld_symbolic_operand" "")]
8675 UNSPEC_TLSLDO)
8676 (match_operand:DI 1 "register_operand" "r")))))]
8677 "TARGET_TLS && TARGET_ARCH64"
8678 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8679 [(set_attr "type" "load")
8680 (set_attr "us3load_type" "3cycle")])
8681
8682 (define_insn "*tldo_ldub3_sp64"
8683 [(set (match_operand:DI 0 "register_operand" "=r")
8684 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8685 (match_operand 3 "tld_symbolic_operand" "")]
8686 UNSPEC_TLSLDO)
8687 (match_operand:DI 1 "register_operand" "r")))))]
8688 "TARGET_TLS && TARGET_ARCH64"
8689 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8690 [(set_attr "type" "load")
8691 (set_attr "us3load_type" "3cycle")])
8692
8693 (define_insn "*tldo_ldsb1_sp64"
8694 [(set (match_operand:HI 0 "register_operand" "=r")
8695 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8696 (match_operand 3 "tld_symbolic_operand" "")]
8697 UNSPEC_TLSLDO)
8698 (match_operand:DI 1 "register_operand" "r")))))]
8699 "TARGET_TLS && TARGET_ARCH64"
8700 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8701 [(set_attr "type" "sload")
8702 (set_attr "us3load_type" "3cycle")])
8703
8704 (define_insn "*tldo_ldsb2_sp64"
8705 [(set (match_operand:SI 0 "register_operand" "=r")
8706 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8707 (match_operand 3 "tld_symbolic_operand" "")]
8708 UNSPEC_TLSLDO)
8709 (match_operand:DI 1 "register_operand" "r")))))]
8710 "TARGET_TLS && TARGET_ARCH64"
8711 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8712 [(set_attr "type" "sload")
8713 (set_attr "us3load_type" "3cycle")])
8714
8715 (define_insn "*tldo_ldsb3_sp64"
8716 [(set (match_operand:DI 0 "register_operand" "=r")
8717 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8718 (match_operand 3 "tld_symbolic_operand" "")]
8719 UNSPEC_TLSLDO)
8720 (match_operand:DI 1 "register_operand" "r")))))]
8721 "TARGET_TLS && TARGET_ARCH64"
8722 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8723 [(set_attr "type" "sload")
8724 (set_attr "us3load_type" "3cycle")])
8725
8726 (define_insn "*tldo_lduh_sp32"
8727 [(set (match_operand:HI 0 "register_operand" "=r")
8728 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8729 (match_operand 3 "tld_symbolic_operand" "")]
8730 UNSPEC_TLSLDO)
8731 (match_operand:SI 1 "register_operand" "r"))))]
8732 "TARGET_TLS && TARGET_ARCH32"
8733 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8734 [(set_attr "type" "load")
8735 (set_attr "us3load_type" "3cycle")])
8736
8737 (define_insn "*tldo_lduh1_sp32"
8738 [(set (match_operand:SI 0 "register_operand" "=r")
8739 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8740 (match_operand 3 "tld_symbolic_operand" "")]
8741 UNSPEC_TLSLDO)
8742 (match_operand:SI 1 "register_operand" "r")))))]
8743 "TARGET_TLS && TARGET_ARCH32"
8744 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8745 [(set_attr "type" "load")
8746 (set_attr "us3load_type" "3cycle")])
8747
8748 (define_insn "*tldo_ldsh1_sp32"
8749 [(set (match_operand:SI 0 "register_operand" "=r")
8750 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8751 (match_operand 3 "tld_symbolic_operand" "")]
8752 UNSPEC_TLSLDO)
8753 (match_operand:SI 1 "register_operand" "r")))))]
8754 "TARGET_TLS && TARGET_ARCH32"
8755 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8756 [(set_attr "type" "sload")
8757 (set_attr "us3load_type" "3cycle")])
8758
8759 (define_insn "*tldo_lduh_sp64"
8760 [(set (match_operand:HI 0 "register_operand" "=r")
8761 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8762 (match_operand 3 "tld_symbolic_operand" "")]
8763 UNSPEC_TLSLDO)
8764 (match_operand:DI 1 "register_operand" "r"))))]
8765 "TARGET_TLS && TARGET_ARCH64"
8766 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8767 [(set_attr "type" "load")
8768 (set_attr "us3load_type" "3cycle")])
8769
8770 (define_insn "*tldo_lduh1_sp64"
8771 [(set (match_operand:SI 0 "register_operand" "=r")
8772 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8773 (match_operand 3 "tld_symbolic_operand" "")]
8774 UNSPEC_TLSLDO)
8775 (match_operand:DI 1 "register_operand" "r")))))]
8776 "TARGET_TLS && TARGET_ARCH64"
8777 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8778 [(set_attr "type" "load")
8779 (set_attr "us3load_type" "3cycle")])
8780
8781 (define_insn "*tldo_lduh2_sp64"
8782 [(set (match_operand:DI 0 "register_operand" "=r")
8783 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8784 (match_operand 3 "tld_symbolic_operand" "")]
8785 UNSPEC_TLSLDO)
8786 (match_operand:DI 1 "register_operand" "r")))))]
8787 "TARGET_TLS && TARGET_ARCH64"
8788 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8789 [(set_attr "type" "load")
8790 (set_attr "us3load_type" "3cycle")])
8791
8792 (define_insn "*tldo_ldsh1_sp64"
8793 [(set (match_operand:SI 0 "register_operand" "=r")
8794 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8795 (match_operand 3 "tld_symbolic_operand" "")]
8796 UNSPEC_TLSLDO)
8797 (match_operand:DI 1 "register_operand" "r")))))]
8798 "TARGET_TLS && TARGET_ARCH64"
8799 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8800 [(set_attr "type" "sload")
8801 (set_attr "us3load_type" "3cycle")])
8802
8803 (define_insn "*tldo_ldsh2_sp64"
8804 [(set (match_operand:DI 0 "register_operand" "=r")
8805 (sign_extend:DI (mem:HI (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 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8811 [(set_attr "type" "sload")
8812 (set_attr "us3load_type" "3cycle")])
8813
8814 (define_insn "*tldo_lduw_sp32"
8815 [(set (match_operand:SI 0 "register_operand" "=r")
8816 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8817 (match_operand 3 "tld_symbolic_operand" "")]
8818 UNSPEC_TLSLDO)
8819 (match_operand:SI 1 "register_operand" "r"))))]
8820 "TARGET_TLS && TARGET_ARCH32"
8821 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8822 [(set_attr "type" "load")])
8823
8824 (define_insn "*tldo_lduw_sp64"
8825 [(set (match_operand:SI 0 "register_operand" "=r")
8826 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8827 (match_operand 3 "tld_symbolic_operand" "")]
8828 UNSPEC_TLSLDO)
8829 (match_operand:DI 1 "register_operand" "r"))))]
8830 "TARGET_TLS && TARGET_ARCH64"
8831 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8832 [(set_attr "type" "load")])
8833
8834 (define_insn "*tldo_lduw1_sp64"
8835 [(set (match_operand:DI 0 "register_operand" "=r")
8836 (zero_extend:DI (mem:SI (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 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8842 [(set_attr "type" "load")])
8843
8844 (define_insn "*tldo_ldsw1_sp64"
8845 [(set (match_operand:DI 0 "register_operand" "=r")
8846 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8847 (match_operand 3 "tld_symbolic_operand" "")]
8848 UNSPEC_TLSLDO)
8849 (match_operand:DI 1 "register_operand" "r")))))]
8850 "TARGET_TLS && TARGET_ARCH64"
8851 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8852 [(set_attr "type" "sload")
8853 (set_attr "us3load_type" "3cycle")])
8854
8855 (define_insn "*tldo_ldx_sp64"
8856 [(set (match_operand:DI 0 "register_operand" "=r")
8857 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8858 (match_operand 3 "tld_symbolic_operand" "")]
8859 UNSPEC_TLSLDO)
8860 (match_operand:DI 1 "register_operand" "r"))))]
8861 "TARGET_TLS && TARGET_ARCH64"
8862 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8863 [(set_attr "type" "load")])
8864
8865 (define_insn "*tldo_stb_sp32"
8866 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8867 (match_operand 3 "tld_symbolic_operand" "")]
8868 UNSPEC_TLSLDO)
8869 (match_operand:SI 1 "register_operand" "r")))
8870 (match_operand:QI 0 "register_operand" "=r"))]
8871 "TARGET_TLS && TARGET_ARCH32"
8872 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8873 [(set_attr "type" "store")])
8874
8875 (define_insn "*tldo_stb_sp64"
8876 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8877 (match_operand 3 "tld_symbolic_operand" "")]
8878 UNSPEC_TLSLDO)
8879 (match_operand:DI 1 "register_operand" "r")))
8880 (match_operand:QI 0 "register_operand" "=r"))]
8881 "TARGET_TLS && TARGET_ARCH64"
8882 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8883 [(set_attr "type" "store")])
8884
8885 (define_insn "*tldo_sth_sp32"
8886 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8887 (match_operand 3 "tld_symbolic_operand" "")]
8888 UNSPEC_TLSLDO)
8889 (match_operand:SI 1 "register_operand" "r")))
8890 (match_operand:HI 0 "register_operand" "=r"))]
8891 "TARGET_TLS && TARGET_ARCH32"
8892 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8893 [(set_attr "type" "store")])
8894
8895 (define_insn "*tldo_sth_sp64"
8896 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8897 (match_operand 3 "tld_symbolic_operand" "")]
8898 UNSPEC_TLSLDO)
8899 (match_operand:DI 1 "register_operand" "r")))
8900 (match_operand:HI 0 "register_operand" "=r"))]
8901 "TARGET_TLS && TARGET_ARCH64"
8902 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8903 [(set_attr "type" "store")])
8904
8905 (define_insn "*tldo_stw_sp32"
8906 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8907 (match_operand 3 "tld_symbolic_operand" "")]
8908 UNSPEC_TLSLDO)
8909 (match_operand:SI 1 "register_operand" "r")))
8910 (match_operand:SI 0 "register_operand" "=r"))]
8911 "TARGET_TLS && TARGET_ARCH32"
8912 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8913 [(set_attr "type" "store")])
8914
8915 (define_insn "*tldo_stw_sp64"
8916 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8917 (match_operand 3 "tld_symbolic_operand" "")]
8918 UNSPEC_TLSLDO)
8919 (match_operand:DI 1 "register_operand" "r")))
8920 (match_operand:SI 0 "register_operand" "=r"))]
8921 "TARGET_TLS && TARGET_ARCH64"
8922 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8923 [(set_attr "type" "store")])
8924
8925 (define_insn "*tldo_stx_sp64"
8926 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8927 (match_operand 3 "tld_symbolic_operand" "")]
8928 UNSPEC_TLSLDO)
8929 (match_operand:DI 1 "register_operand" "r")))
8930 (match_operand:DI 0 "register_operand" "=r"))]
8931 "TARGET_TLS && TARGET_ARCH64"
8932 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8933 [(set_attr "type" "store")])