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