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