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