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