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