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