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